The Great Blink mv for source files, part 2.

Move and rename files.

NOAUTOREVERT=true
NOPRESUBMIT=true
NOTREECHECKS=true
Bug: 768828
TBR=darin@chromium.org
NOTRY=true

Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28
Reviewed-on: https://chromium-review.googlesource.com/1001153
Reviewed-by: Blink Reformat <blink-reformat@chromium.org>
Commit-Queue: Blink Reformat <blink-reformat@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#549061}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index ea647be..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,8 +0,0 @@
----
-BasedOnStyle: Chromium
-Language: JavaScript
-ColumnLimit: 120
-CommentPragmas: .*\@.*
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: None
-ReflowComments: false
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 86b0332..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,14 +0,0 @@
-// Do not use glob pattern, this file is used by PRESUBMIT.py
-// to ignore these same files/folders for clang-format
-front_end/.eslintrc.js
-front_end/audits2_worker/lighthouse/
-front_end/audits2/lighthouse/
-front_end/cm/
-front_end/cm_headless/
-front_end/cm_modes/
-front_end/cm_web_modes/
-front_end/diff/diff_match_patch.js
-front_end/formatter_worker/acorn/
-front_end/terminal/xterm.js/
-front_end/protocol_externs.js
-scripts/
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index cca6724..0000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,130 +0,0 @@
-module.exports = {
-    "root": true,
-
-    "env": {
-        "browser": true,
-        "es6": true
-    },
-
-    "parserOptions": {
-        "ecmaVersion": 8
-    },
-
-    /**
-     * ESLint rules
-     *
-     * All available rules: http://eslint.org/docs/rules/
-     *
-     * Rules take the following form:
-     *   "rule-name", [severity, { opts }]
-     * Severity: 2 == error, 1 == warning, 0 == off.
-     */
-    "rules": {
-        /**
-         * Enforced rules
-         */
-
-
-        // syntax preferences
-        "quotes": [2, "single", {
-            "avoidEscape": true,
-            "allowTemplateLiterals": true
-        }],
-        "semi": 2,
-        "no-extra-semi": 2,
-        "comma-style": [2, "last"],
-        "wrap-iife": [2, "inside"],
-        "spaced-comment": [2, "always", {
-            "markers": ["*"]
-        }],
-        "eqeqeq": [2],
-        "accessor-pairs": [2, {
-            "getWithoutSet": false,
-            "setWithoutGet": false
-        }],
-        "curly": [2, "multi-or-nest", "consistent"],
-        "new-parens": 2,
-        "func-call-spacing": 2,
-        "arrow-parens": [2, "as-needed"],
-
-        // anti-patterns
-        "no-with": 2,
-        "no-multi-str": 2,
-        "no-caller": 2,
-        "no-implied-eval": 2,
-        "no-labels": 2,
-        "no-new-object": 2,
-        "no-octal-escape": 2,
-        "no-self-compare": 2,
-        "no-shadow-restricted-names": 2,
-        "no-cond-assign": 2,
-        "no-debugger": 2,
-        "no-console": [2, { "allow": ["assert", "context", "error", "timeStamp", "time", "timeEnd", "warn"] }],
-        "no-dupe-keys": 2,
-        "no-duplicate-case": 2,
-        "no-empty-character-class": 2,
-        "no-unreachable": 2,
-        "no-unsafe-negation": 2,
-        "radix": 2,
-        "valid-typeof": 2,
-        "no-var": 2,
-        "prefer-const": 2,
-        "no-unused-vars": [2, { "args": "none", "vars": "local" }],
-
-        // es2015 features
-        "require-yield": 2,
-        "template-curly-spacing": [2, "never"],
-
-        // spacing details
-        "space-infix-ops": 2,
-        "space-in-parens": [2, "never"],
-        "space-before-function-paren": [2, {
-            "anonymous": "never",
-            "named": "never",
-            "asyncArrow": "always"
-        }],
-        "no-whitespace-before-property": 2,
-        "keyword-spacing": [2, {
-            "overrides": {
-                "if": {"after": true},
-                "else": {"after": true},
-                "for": {"after": true},
-                "while": {"after": true},
-                "do": {"after": true},
-                "switch": {"after": true},
-                "return": {"after": true}
-            }
-        }],
-        "arrow-spacing": [2, {
-            "after": true,
-            "before": true
-        }],
-
-        // file whitespace
-        "no-multiple-empty-lines": [2, {"max": 2}],
-        "no-mixed-spaces-and-tabs": 2,
-        "no-trailing-spaces": 2,
-        "linebreak-style": [ 2, "unix" ],
-
-        /**
-         * Disabled, aspirational rules
-         */
-
-        "indent": [0, 2, { "SwitchCase": 1, "CallExpression": {"arguments": 2}, "MemberExpression": 2 }],
-
-        // brace-style is disabled, as eslint cannot enforce 1tbs as default, but allman for functions
-        "brace-style": [0, "allman", { "allowSingleLine": true }],
-
-        // key-spacing is disabled, as some objects use value-aligned spacing, some not.
-        "key-spacing": [0, {
-            "beforeColon": false,
-            "afterColon": true,
-            "align": "value"
-        }],
-        // quote-props is diabled, as property quoting styles are too varied to enforce.
-        "quote-props": [0, "as-needed"],
-
-        // no-implicit-globals will prevent accidental globals
-        "no-implicit-globals": [0]
-    }
-};
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 89db6be..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,19 +0,0 @@
-*.Makefile
-*.mk
-*.pyc
-*.rules
-*.sln
-*.tmp
-*.vcproj*
-*.vcxproj*
-*.xcodeproj*
-node_modules
-config.gypi
-npm-debug.log
-/.dev_profile
-/.test_cache
-/release
-/scripts/local_node/runtimes
-/scripts/visualize_deps/out
-/front_end/protocol_externs.js
-package-lock.json
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index df4d355..0000000
--- a/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-devtools.gyp
-devtools.gypi
-BUILD.gn
-PRESUBMIT.py
-OWNERS
\ No newline at end of file
diff --git a/.style.yapf b/.style.yapf
deleted file mode 100644
index e78094a..0000000
--- a/.style.yapf
+++ /dev/null
@@ -1,5 +0,0 @@
-[style]
-based_on_style = chromium
-indent_width = 4
-column_limit = 132
-
diff --git a/BUILD.gn b/BUILD.gn
deleted file mode 100644
index 347f0fe..0000000
--- a/BUILD.gn
+++ /dev/null
@@ -1,1304 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/features.gni")
-import("//third_party/blink/public/public_features.gni")
-import("//third_party/blink/renderer/core/core.gni")
-
-all_devtools_files = [
-  "front_end/accessibility/AccessibilityModel.js",
-  "front_end/accessibility/accessibilityNode.css",
-  "front_end/accessibility/AccessibilityNodeView.js",
-  "front_end/accessibility/accessibilityProperties.css",
-  "front_end/accessibility/AccessibilitySidebarView.js",
-  "front_end/accessibility/AccessibilityStrings.js",
-  "front_end/accessibility/ARIAAttributesView.js",
-  "front_end/accessibility/ARIAConfig.js",
-  "front_end/accessibility/ARIAMetadata.js",
-  "front_end/accessibility/axBreadcrumbs.css",
-  "front_end/accessibility/AXBreadcrumbsPane.js",
-  "front_end/accessibility/module.json",
-  "front_end/accessibility_test_runner/AccessibilityPaneTestRunner.js",
-  "front_end/accessibility_test_runner/module.json",
-  "front_end/animation/AnimationGroupPreviewUI.js",
-  "front_end/animation/AnimationModel.js",
-  "front_end/animation/animationScreenshotPopover.css",
-  "front_end/animation/AnimationScreenshotPopover.js",
-  "front_end/animation/animationTimeline.css",
-  "front_end/animation/AnimationTimeline.js",
-  "front_end/animation/AnimationUI.js",
-  "front_end/animation/module.json",
-  "front_end/application_test_runner/AppcacheTestRunner.js",
-  "front_end/application_test_runner/CacheStorageTestRunner.js",
-  "front_end/application_test_runner/IndexedDBTestRunner.js",
-  "front_end/application_test_runner/module.json",
-  "front_end/application_test_runner/ResourcesTestRunner.js",
-  "front_end/application_test_runner/ResourceTreeTestRunner.js",
-  "front_end/application_test_runner/ServiceWorkersTestRunner.js",
-  "front_end/audits2_worker.js",
-  "front_end/audits2_worker.json",
-  "front_end/audits2_worker/Audits2Service.js",
-  "front_end/audits2_worker/lighthouse/lighthouse-background.js",
-  "front_end/audits2_worker/module.json",
-  "front_end/audits2/Audits2Panel.js",
-  "front_end/audits2/Audits2Dialog.js",
-  "front_end/audits2/Audits2ProtocolService.js",
-  "front_end/audits2/Audits2StatusView.js",
-  "front_end/audits2/audits2Dialog.css",
-  "front_end/audits2/audits2Panel.css",
-  "front_end/audits2/lighthouse/renderer/dom.js",
-  "front_end/audits2/lighthouse/renderer/details-renderer.js",
-  "front_end/audits2/lighthouse/renderer/category-renderer.js",
-  "front_end/audits2/lighthouse/renderer/crc-details-renderer.js",
-  "front_end/audits2/lighthouse/renderer/report-renderer.js",
-  "front_end/audits2/lighthouse/renderer/util.js",
-  "front_end/audits2/lighthouse/report-styles.css",
-  "front_end/audits2/lighthouse/templates.html",
-  "front_end/audits2/module.json",
-  "front_end/audits2_test_runner/Audits2TestRunner.js",
-  "front_end/audits2_test_runner/module.json",
-  "front_end/bindings/BlackboxManager.js",
-  "front_end/bindings/BreakpointManager.js",
-  "front_end/bindings/CompilerScriptMapping.js",
-  "front_end/bindings/ContentProviderBasedProject.js",
-  "front_end/bindings/CSSWorkspaceBinding.js",
-  "front_end/bindings/DebuggerWorkspaceBinding.js",
-  "front_end/bindings/DefaultScriptMapping.js",
-  "front_end/bindings/FileUtils.js",
-  "front_end/bindings/LiveLocation.js",
-  "front_end/bindings/module.json",
-  "front_end/bindings/NetworkProject.js",
-  "front_end/bindings/PresentationConsoleMessageHelper.js",
-  "front_end/bindings/ResourceMapping.js",
-  "front_end/bindings/ResourceScriptMapping.js",
-  "front_end/bindings/ResourceUtils.js",
-  "front_end/bindings/SASSSourceMapping.js",
-  "front_end/bindings/StylesSourceMapping.js",
-  "front_end/bindings/TempFile.js",
-  "front_end/bindings_test_runner/AutomappingTestRunner.js",
-  "front_end/bindings_test_runner/BindingsTestRunner.js",
-  "front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js",
-  "front_end/bindings_test_runner/module.json",
-  "front_end/bindings_test_runner/PersistenceTestRunner.js",
-  "front_end/bindings_test_runner/OverridesTestRunner.js",
-  "front_end/browser_components/ImagePreview.js",
-  "front_end/browser_components/imagePreview.css",
-  "front_end/browser_console/BrowserConsole.js",
-  "front_end/browser_console/module.json",
-  "front_end/browser_debugger/DOMBreakpointsSidebarPane.js",
-  "front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js",
-  "front_end/browser_debugger/ObjectEventListenersSidebarPane.js",
-  "front_end/browser_debugger/XHRBreakpointsSidebarPane.js",
-  "front_end/browser_debugger/domBreakpointsSidebarPane.css",
-  "front_end/browser_debugger/eventListenerBreakpoints.css",
-  "front_end/browser_debugger/module.json",
-  "front_end/browser_debugger/xhrBreakpointsSidebarPane.css",
-  "front_end/browser_sdk/HAREntry.js",
-  "front_end/browser_sdk/LogManager.js",
-  "front_end/browser_sdk/NetworkLog.js",
-  "front_end/browser_sdk/module.json",
-  "front_end/changes/ChangesHighlighter.js",
-  "front_end/changes/changesView.css",
-  "front_end/changes/ChangesView.js",
-  "front_end/changes/changesSidebar.css",
-  "front_end/changes/ChangesSidebar.js",
-  "front_end/changes/module.json",
-  "front_end/cm/activeline.js",
-  "front_end/cm/closebrackets.js",
-  "front_end/cm/codemirror.css",
-  "front_end/cm/codemirror.js",
-  "front_end/cm/comment.js",
-  "front_end/cm/markselection.js",
-  "front_end/cm/matchbrackets.js",
-  "front_end/cm/module.json",
-  "front_end/cm/multiplex.js",
-  "front_end/cm/overlay.js",
-  "front_end/cm_headless/headlesscodemirror.js",
-  "front_end/cm_headless/module.json",
-  "front_end/cm_modes/clike.js",
-  "front_end/cm_modes/clojure.js",
-  "front_end/cm_modes/coffeescript.js",
-  "front_end/cm_modes/DefaultCodeMirrorMimeMode.js",
-  "front_end/cm_modes/jsx.js",
-  "front_end/cm_modes/livescript.js",
-  "front_end/cm_modes/markdown.js",
-  "front_end/cm_modes/module.json",
-  "front_end/cm_modes/php.js",
-  "front_end/cm_modes/python.js",
-  "front_end/cm_modes/shell.js",
-  "front_end/cm_modes/stylus.js",
-  "front_end/cm_web_modes/css.js",
-  "front_end/cm_web_modes/htmlembedded.js",
-  "front_end/cm_web_modes/htmlmixed.js",
-  "front_end/cm_web_modes/javascript.js",
-  "front_end/cm_web_modes/xml.js",
-  "front_end/color_picker/ContrastDetails.js",
-  "front_end/color_picker/ContrastInfo.js",
-  "front_end/color_picker/ContrastOverlay.js",
-  "front_end/color_picker/module.json",
-  "front_end/color_picker/spectrum.css",
-  "front_end/color_picker/Spectrum.js",
-  "front_end/common/CharacterIdMap.js",
-  "front_end/common/Color.js",
-  "front_end/common/Console.js",
-  "front_end/common/ContentProvider.js",
-  "front_end/common/module.json",
-  "front_end/common/ModuleExtensionInterfaces.js",
-  "front_end/common/Object.js",
-  "front_end/common/OutputStream.js",
-  "front_end/common/ParsedURL.js",
-  "front_end/common/Progress.js",
-  "front_end/common/ResourceType.js",
-  "front_end/common/SegmentedRange.js",
-  "front_end/common/Settings.js",
-  "front_end/common/StaticContentProvider.js",
-  "front_end/common/TextDictionary.js",
-  "front_end/common/Throttler.js",
-  "front_end/common/Trie.js",
-  "front_end/common/UIString.js",
-  "front_end/common/Worker.js",
-  "front_end/components/DockController.js",
-  "front_end/components/JSPresentationUtils.js",
-  "front_end/components/Linkifier.js",
-  "front_end/components/TargetDetachedDialog.js",
-  "front_end/components/Reload.js",
-  "front_end/components/jsUtils.css",
-  "front_end/components/module.json",
-  "front_end/console/ConsoleContextSelector.js",
-  "front_end/console/ConsoleFilter.js",
-  "front_end/console/ConsoleSidebar.js",
-  "front_end/console/ConsolePanel.js",
-  "front_end/console/ConsolePrompt.js",
-  "front_end/console/consoleView.css",
-  "front_end/console/consoleContextSelector.css",
-  "front_end/console/consoleSidebar.css",
-  "front_end/console/ConsoleView.js",
-  "front_end/console/ConsoleViewMessage.js",
-  "front_end/console/ConsoleViewport.js",
-  "front_end/console/module.json",
-  "front_end/console_counters/errorWarningCounter.css",
-  "front_end/console_counters/module.json",
-  "front_end/console_counters/WarningErrorCounter.js",
-  "front_end/console_test_runner/ConsoleTestRunner.js",
-  "front_end/console_test_runner/module.json",
-  "front_end/cookie_table/CookiesTable.js",
-  "front_end/cookie_table/module.json",
-  "front_end/coverage/coverageListView.css",
-  "front_end/coverage/CoverageDecorationManager.js",
-  "front_end/coverage/CoverageListView.js",
-  "front_end/coverage/CoverageModel.js",
-  "front_end/coverage/coverageView.css",
-  "front_end/coverage/CoverageView.js",
-  "front_end/coverage/module.json",
-  "front_end/coverage_test_runner/CoverageTestRunner.js",
-  "front_end/coverage_test_runner/module.json",
-  "front_end/cpu_profiler_test_runner/module.json",
-  "front_end/cpu_profiler_test_runner/ProfilerTestRunner.js",
-  "front_end/data_grid/dataGrid.css",
-  "front_end/data_grid/DataGrid.js",
-  "front_end/data_grid/module.json",
-  "front_end/data_grid/ShowMoreDataGridNode.js",
-  "front_end/data_grid/SortableDataGrid.js",
-  "front_end/data_grid/ViewportDataGrid.js",
-  "front_end/data_grid_test_runner/DataGridTestRunner.js",
-  "front_end/data_grid_test_runner/module.json",
-  "front_end/device_mode_test_runner/DeviceModeTestRunner.js",
-  "front_end/device_mode_test_runner/module.json",
-  "front_end/devices/DevicesView.js",
-  "front_end/devices/devicesView.css",
-  "front_end/devices/module.json",
-  "front_end/diff/diff_match_patch.js",
-  "front_end/diff/Diff.js",
-  "front_end/diff/module.json",
-  "front_end/dom_extension/DOMExtension.js",
-  "front_end/dom_extension/module.json",
-  "front_end/elements/breadcrumbs.css",
-  "front_end/elements/classesPaneWidget.css",
-  "front_end/elements/ClassesPaneWidget.js",
-  "front_end/elements/ColorSwatchPopoverIcon.js",
-  "front_end/elements/ComputedStyleModel.js",
-  "front_end/elements/computedStyleSidebarPane.css",
-  "front_end/elements/computedStyleWidgetTree.css",
-  "front_end/elements/ComputedStyleWidget.js",
-  "front_end/elements/DOMLinkifier.js",
-  "front_end/elements/domLinkifier.css",
-  "front_end/elements/DOMPath.js",
-  "front_end/elements/ElementsBreadcrumbs.js",
-  "front_end/elements/elementsPanel.css",
-  "front_end/elements/ElementsPanel.js",
-  "front_end/elements/ElementsSidebarPane.js",
-  "front_end/elements/elementStatePaneWidget.css",
-  "front_end/elements/ElementStatePaneWidget.js",
-  "front_end/elements/ElementsTreeElement.js",
-  "front_end/elements/ElementsTreeElementHighlighter.js",
-  "front_end/elements/elementsTreeOutline.css",
-  "front_end/elements/ElementsTreeOutline.js",
-  "front_end/elements/EventListenersWidget.js",
-  "front_end/elements/InspectElementModeController.js",
-  "front_end/elements/MarkerDecorator.js",
-  "front_end/elements/metricsSidebarPane.css",
-  "front_end/elements/MetricsSidebarPane.js",
-  "front_end/elements/module.json",
-  "front_end/elements/platformFontsWidget.css",
-  "front_end/elements/PlatformFontsWidget.js",
-  "front_end/elements/propertiesWidget.css",
-  "front_end/elements/PropertiesWidget.js",
-  "front_end/elements/StylePropertyHighlighter.js",
-  "front_end/elements/stylesSectionTree.css",
-  "front_end/elements/stylesSidebarPane.css",
-  "front_end/elements/StylesSidebarPane.js",
-  "front_end/elements/StylePropertyTreeElement.js",
-  "front_end/elements_test_runner/EditDOMTestRunner.js",
-  "front_end/elements_test_runner/ElementsPanelShadowSelectionOnRefreshTestRunner.js",
-  "front_end/elements_test_runner/ElementsTestRunner.js",
-  "front_end/elements_test_runner/SetOuterHTMLTestRunner.js",
-  "front_end/elements_test_runner/StylesUpdateLinksTestRunner.js",
-  "front_end/emulated_devices/module.json",
-  "front_end/emulation/AdvancedApp.js",
-  "front_end/emulation/DeviceModeModel.js",
-  "front_end/emulation/deviceModeToolbar.css",
-  "front_end/emulation/DeviceModeToolbar.js",
-  "front_end/emulation/deviceModeView.css",
-  "front_end/emulation/DeviceModeView.js",
-  "front_end/emulation/DeviceModeWrapper.js",
-  "front_end/emulation/devicesSettingsTab.css",
-  "front_end/emulation/DevicesSettingsTab.js",
-  "front_end/emulation/EmulatedDevices.js",
-  "front_end/emulation/inspectedPagePlaceholder.css",
-  "front_end/emulation/InspectedPagePlaceholder.js",
-  "front_end/emulation/mediaQueryInspector.css",
-  "front_end/emulation/MediaQueryInspector.js",
-  "front_end/emulation/module.json",
-  "front_end/emulation/sensors.css",
-  "front_end/emulation/SensorsView.js",
-  "front_end/event_listeners/EventListenersUtils.js",
-  "front_end/event_listeners/eventListenersView.css",
-  "front_end/event_listeners/EventListenersView.js",
-  "front_end/event_listeners/module.json",
-  "front_end/extensions/ExtensionAPI.js",
-  "front_end/extensions/ExtensionPanel.js",
-  "front_end/extensions/ExtensionRegistryStub.js",
-  "front_end/extensions/ExtensionServer.js",
-  "front_end/extensions/ExtensionTraceProvider.js",
-  "front_end/extensions/ExtensionView.js",
-  "front_end/extensions/module.json",
-  "front_end/extensions_test_runner/ExtensionsNetworkTestRunner.js",
-  "front_end/extensions_test_runner/ExtensionsTestRunner.js",
-  "front_end/extensions_test_runner/module.json",
-  "front_end/formatter/FormatterWorkerPool.js",
-  "front_end/formatter/module.json",
-  "front_end/formatter/ScriptFormatter.js",
-  "front_end/formatter_worker.js",
-  "front_end/formatter_worker.json",
-  "front_end/formatter_worker/AcornTokenizer.js",
-  "front_end/formatter_worker/CSSFormatter.js",
-  "front_end/formatter_worker/CSSRuleParser.js",
-  "front_end/formatter_worker/ESTreeWalker.js",
-  "front_end/formatter_worker/FormattedContentBuilder.js",
-  "front_end/formatter_worker/FormatterWorker.js",
-  "front_end/formatter_worker/HTMLFormatter.js",
-  "front_end/formatter_worker/IdentityFormatter.js",
-  "front_end/formatter_worker/JavaScriptFormatter.js",
-  "front_end/formatter_worker/JavaScriptOutline.js",
-  "front_end/formatter_worker/RelaxedJSONParser.js",
-  "front_end/formatter_worker/acorn/acorn.js",
-  "front_end/formatter_worker/acorn/acorn_loose.js",
-  "front_end/formatter_worker/module.json",
-  "front_end/har_importer/HARFormat.js",
-  "front_end/har_importer/HARImporter.js",
-  "front_end/har_importer/module.json",
-  "front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js",
-  "front_end/heap_profiler_test_runner/module.json",
-  "front_end/heap_snapshot_model/HeapSnapshotModel.js",
-  "front_end/heap_snapshot_model/module.json",
-  "front_end/heap_snapshot_worker.js",
-  "front_end/heap_snapshot_worker.json",
-  "front_end/heap_snapshot_worker/AllocationProfile.js",
-  "front_end/heap_snapshot_worker/HeapSnapshot.js",
-  "front_end/heap_snapshot_worker/HeapSnapshotLoader.js",
-  "front_end/heap_snapshot_worker/HeapSnapshotWorker.js",
-  "front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js",
-  "front_end/heap_snapshot_worker/module.json",
-  "front_end/help/Help.js",
-  "front_end/help/module.json",
-  "front_end/help/releaseNote.css",
-  "front_end/help/ReleaseNoteText.js",
-  "front_end/help/ReleaseNoteView.js",
-  "front_end/host/InspectorFrontendHost.js",
-  "front_end/host/InspectorFrontendHostAPI.js",
-  "front_end/host/module.json",
-  "front_end/host/Platform.js",
-  "front_end/host/ResourceLoader.js",
-  "front_end/host/UserMetrics.js",
-  "front_end/inline_editor/bezierEditor.css",
-  "front_end/inline_editor/BezierEditor.js",
-  "front_end/inline_editor/bezierSwatch.css",
-  "front_end/inline_editor/BezierUI.js",
-  "front_end/inline_editor/colorSwatch.css",
-  "front_end/inline_editor/ColorSwatch.js",
-  "front_end/inline_editor/cssShadowEditor.css",
-  "front_end/inline_editor/CSSShadowEditor.js",
-  "front_end/inline_editor/CSSShadowModel.js",
-  "front_end/inline_editor/cssShadowSwatch.css",
-  "front_end/inline_editor/module.json",
-  "front_end/inline_editor/swatchPopover.css",
-  "front_end/inline_editor/SwatchPopoverHelper.js",
-  "front_end/inspector.js",
-  "front_end/inspector.json",
-  "front_end/inspector_main/InspectorMain.js",
-  "front_end/inspector_main/module.json",
-  "front_end/inspector_main/nodeIcon.css",
-  "front_end/inspector_main/renderingOptions.css",
-  "front_end/inspector_main/RenderingOptions.js",
-  "front_end/inspector_main/RequestAppBannerActionDelegate.js",
-  "front_end/integration_test_runner.js",
-  "front_end/integration_test_runner.json",
-  "front_end/js_main/JsMain.js",
-  "front_end/js_main/module.json",
-  "front_end/js_profiler/module.json",
-  "front_end/layer_viewer/layerDetailsView.css",
-  "front_end/layer_viewer/LayerDetailsView.js",
-  "front_end/layer_viewer/layers3DView.css",
-  "front_end/layer_viewer/Layers3DView.js",
-  "front_end/layer_viewer/LayerTreeOutline.js",
-  "front_end/layer_viewer/LayerViewHost.js",
-  "front_end/layer_viewer/module.json",
-  "front_end/layer_viewer/paintProfiler.css",
-  "front_end/layer_viewer/PaintProfilerView.js",
-  "front_end/layer_viewer/TransformController.js",
-  "front_end/layers/LayerPaintProfilerView.js",
-  "front_end/layers/LayersPanel.js",
-  "front_end/layers/LayerTreeModel.js",
-  "front_end/layers/module.json",
-  "front_end/layers_test_runner/LayersTestRunner.js",
-  "front_end/layers_test_runner/module.json",
-  "front_end/main/ExecutionContextSelector.js",
-  "front_end/main/Main.js",
-  "front_end/main/module.json",
-  "front_end/main/SimpleApp.js",
-  "front_end/protocol_monitor/ProtocolMonitor.js",
-  "front_end/protocol_monitor/protocolMonitor.css",
-  "front_end/protocol_monitor/module.json",
-  "front_end/mobile_throttling/MobileThrottlingSelector.js",
-  "front_end/mobile_throttling/module.json",
-  "front_end/mobile_throttling/NetworkPanelIndicator.js",
-  "front_end/mobile_throttling/NetworkThrottlingSelector.js",
-  "front_end/mobile_throttling/ThrottlingManager.js",
-  "front_end/mobile_throttling/ThrottlingPresets.js",
-  "front_end/mobile_throttling/throttlingSettingsTab.css",
-  "front_end/mobile_throttling/ThrottlingSettingsTab.js",
-  "front_end/ndb_app.json",
-  "front_end/network/blockedURLsPane.css",
-  "front_end/network/BlockedURLsPane.js",
-  "front_end/network/eventSourceMessagesView.css",
-  "front_end/network/EventSourceMessagesView.js",
-  "front_end/network/HARWriter.js",
-  "front_end/network/module.json",
-  "front_end/network/networkConfigView.css",
-  "front_end/network/NetworkConfigView.js",
-  "front_end/network/NetworkDataGridNode.js",
-  "front_end/network/NetworkItemView.js",
-  "front_end/network/networkLogView.css",
-  "front_end/network/NetworkLogView.js",
-  "front_end/network/NetworkLogViewColumns.js",
-  "front_end/network/NetworkFrameGrouper.js",
-  "front_end/network/networkManageCustomHeadersView.css",
-  "front_end/network/NetworkManageCustomHeadersView.js",
-  "front_end/network/NetworkOverview.js",
-  "front_end/network/networkPanel.css",
-  "front_end/network/NetworkPanel.js",
-  "front_end/network/NetworkSearchScope.js",
-  "front_end/network/NetworkTimeCalculator.js",
-  "front_end/network/networkTimingTable.css",
-  "front_end/network/networkWaterfallColumn.css",
-  "front_end/network/NetworkWaterfallColumn.js",
-  "front_end/network/requestCookiesView.css",
-  "front_end/network/RequestCookiesView.js",
-  "front_end/network/requestHeadersTree.css",
-  "front_end/network/requestHeadersView.css",
-  "front_end/network/RequestHeadersView.js",
-  "front_end/network/requestHTMLView.css",
-  "front_end/network/RequestHTMLView.js",
-  "front_end/network/RequestPreviewView.js",
-  "front_end/network/RequestResponseView.js",
-  "front_end/network/RequestTimingView.js",
-  "front_end/network/ResourceWebSocketFrameView.js",
-  "front_end/network/webSocketFrameView.css",
-  "front_end/network_test_runner/module.json",
-  "front_end/network_test_runner/NetworkTestRunner.js",
-  "front_end/network_test_runner/ProductRegistryTestRunner.js",
-  "front_end/node_debugger/module.json",
-  "front_end/node_main/NodeConnectionsPanel.js",
-  "front_end/node_main/nodeConnectionsPanel.css",
-  "front_end/node_main/NodeMain.js",
-  "front_end/node_main/module.json",
-  "front_end/object_ui/customPreviewComponent.css",
-  "front_end/object_ui/CustomPreviewComponent.js",
-  "front_end/object_ui/JavaScriptAutocomplete.js",
-  "front_end/object_ui/module.json",
-  "front_end/object_ui/objectPopover.css",
-  "front_end/object_ui/ObjectPopoverHelper.js",
-  "front_end/object_ui/objectPropertiesSection.css",
-  "front_end/object_ui/ObjectPropertiesSection.js",
-  "front_end/object_ui/objectValue.css",
-  "front_end/object_ui/RemoteObjectPreviewFormatter.js",
-  "front_end/perf_ui/ChartViewport.js",
-  "front_end/perf_ui/FilmStripView.js",
-  "front_end/perf_ui/FlameChart.js",
-  "front_end/perf_ui/GCActionDelegate.js",
-  "front_end/perf_ui/LineLevelProfile.js",
-  "front_end/perf_ui/NetworkPriorities.js",
-  "front_end/perf_ui/OverviewGrid.js",
-  "front_end/perf_ui/PieChart.js",
-  "front_end/perf_ui/TimelineGrid.js",
-  "front_end/perf_ui/TimelineOverviewPane.js",
-  "front_end/perf_ui/chartViewport.css",
-  "front_end/perf_ui/filmStripView.css",
-  "front_end/perf_ui/flameChart.css",
-  "front_end/perf_ui/module.json",
-  "front_end/perf_ui/overviewGrid.css",
-  "front_end/perf_ui/pieChart.css",
-  "front_end/perf_ui/timelineGrid.css",
-  "front_end/perf_ui/timelineOverviewInfo.css",
-  "front_end/performance_monitor/PerformanceMonitor.js",
-  "front_end/performance_monitor/performanceMonitor.css",
-  "front_end/performance_monitor/module.json",
-  "front_end/performance_test_runner/module.json",
-  "front_end/performance_test_runner/TimelineDataTestRunner.js",
-  "front_end/performance_test_runner/TimelineTestRunner.js",
-  "front_end/persistence/Automapping.js",
-  "front_end/persistence/editFileSystemView.css",
-  "front_end/persistence/EditFileSystemView.js",
-  "front_end/persistence/FileSystemWorkspaceBinding.js",
-  "front_end/persistence/IsolatedFileSystem.js",
-  "front_end/persistence/IsolatedFileSystemManager.js",
-  "front_end/persistence/NetworkPersistenceManager.js",
-  "front_end/persistence/Persistence.js",
-  "front_end/persistence/PersistenceActions.js",
-  "front_end/persistence/PersistenceUtils.js",
-  "front_end/persistence/workspaceSettingsTab.css",
-  "front_end/persistence/WorkspaceSettingsTab.js",
-  "front_end/platform/module.json",
-  "front_end/platform/utilities.js",
-  "front_end/product_registry/BadgePool.js",
-  "front_end/product_registry/ProductRegistry.js",
-  "front_end/product_registry/badge.css",
-  "front_end/product_registry/module.json",
-  "front_end/product_registry/popup.css",
-  "front_end/product_registry_impl/module.json",
-  "front_end/product_registry_impl/ProductRegistryImpl.js",
-  "front_end/product_registry_impl/ProductRegistryData.js",
-  "front_end/product_registry_impl/sha1/sha1.js",
-  "front_end/profiler/BottomUpProfileDataGrid.js",
-  "front_end/profiler/CPUProfileFlameChart.js",
-  "front_end/profiler/CPUProfileView.js",
-  "front_end/profiler/heapProfiler.css",
-  "front_end/profiler/HeapProfileView.js",
-  "front_end/profiler/HeapSnapshotDataGrids.js",
-  "front_end/profiler/HeapSnapshotGridNodes.js",
-  "front_end/profiler/HeapSnapshotProxy.js",
-  "front_end/profiler/HeapSnapshotView.js",
-  "front_end/profiler/HeapProfilerPanel.js",
-  "front_end/profiler/IsolateSelector.js",
-  "front_end/profiler/module.json",
-  "front_end/profiler/ProfileDataGrid.js",
-  "front_end/profiler/ProfileHeader.js",
-  "front_end/profiler/profileLauncherView.css",
-  "front_end/profiler/ProfileLauncherView.js",
-  "front_end/profiler/ProfileType.js",
-  "front_end/profiler/profilesPanel.css",
-  "front_end/profiler/ProfilesPanel.js",
-  "front_end/profiler/profilesSidebarTree.css",
-  "front_end/profiler/ProfileTypeRegistry.js",
-  "front_end/profiler/ProfileView.js",
-  "front_end/profiler/TopDownProfileDataGrid.js",
-  "front_end/protocol/InspectorBackend.js",
-  "front_end/protocol/module.json",
-  "front_end/quick_open/CommandMenu.js",
-  "front_end/quick_open/filteredListWidget.css",
-  "front_end/quick_open/FilteredListWidget.js",
-  "front_end/quick_open/HelpQuickOpen.js",
-  "front_end/quick_open/QuickOpen.js",
-  "front_end/quick_open/module.json",
-  "front_end/resources/ApplicationCacheModel.js",
-  "front_end/resources/ApplicationCacheItemsView.js",
-  "front_end/resources/ApplicationPanelSidebar.js",
-  "front_end/resources/appManifestView.css",
-  "front_end/resources/AppManifestView.js",
-  "front_end/resources/clearStorageView.css",
-  "front_end/resources/ClearStorageView.js",
-  "front_end/resources/CookieItemsView.js",
-  "front_end/resources/DatabaseModel.js",
-  "front_end/resources/DatabaseQueryView.js",
-  "front_end/resources/DatabaseTableView.js",
-  "front_end/resources/DOMStorageItemsView.js",
-  "front_end/resources/DOMStorageModel.js",
-  "front_end/resources/IndexedDBModel.js",
-  "front_end/resources/indexedDBViews.css",
-  "front_end/resources/IndexedDBViews.js",
-  "front_end/resources/module.json",
-  "front_end/resources/resourcesPanel.css",
-  "front_end/resources/ResourcesPanel.js",
-  "front_end/resources/ResourcesSection.js",
-  "front_end/resources/resourcesSidebar.css",
-  "front_end/resources/serviceWorkerCacheViews.css",
-  "front_end/resources/ServiceWorkerCacheViews.js",
-  "front_end/resources/serviceWorkersView.css",
-  "front_end/resources/ServiceWorkersView.js",
-  "front_end/resources/StorageItemsView.js",
-  "front_end/Runtime.js",
-  "front_end/shell.json",
-  "front_end/screencast/InputModel.js",
-  "front_end/screencast/module.json",
-  "front_end/screencast/ScreencastApp.js",
-  "front_end/screencast/screencastView.css",
-  "front_end/screencast/ScreencastView.js",
-  "front_end/sdk/ChildTargetManager.js",
-  "front_end/sdk/Connections.js",
-  "front_end/sdk/ConsoleModel.js",
-  "front_end/sdk/ContentProviders.js",
-  "front_end/sdk/CookieModel.js",
-  "front_end/sdk/CookieParser.js",
-  "front_end/sdk/CPUProfileDataModel.js",
-  "front_end/sdk/CPUProfilerModel.js",
-  "front_end/sdk/CSSMatchedStyles.js",
-  "front_end/sdk/CSSMedia.js",
-  "front_end/sdk/CSSMetadata.js",
-  "front_end/sdk/CSSModel.js",
-  "front_end/sdk/CSSProperty.js",
-  "front_end/sdk/CSSRule.js",
-  "front_end/sdk/CSSStyleDeclaration.js",
-  "front_end/sdk/CSSStyleSheetHeader.js",
-  "front_end/sdk/DOMDebuggerModel.js",
-  "front_end/sdk/DebuggerModel.js",
-  "front_end/sdk/DOMModel.js",
-  "front_end/sdk/EmulationModel.js",
-  "front_end/sdk/FilmStripModel.js",
-  "front_end/sdk/HeapProfilerModel.js",
-  "front_end/sdk/LayerTreeBase.js",
-  "front_end/sdk/LogModel.js",
-  "front_end/sdk/module.json",
-  "front_end/sdk/NetworkManager.js",
-  "front_end/sdk/NetworkRequest.js",
-  "front_end/sdk/OverlayModel.js",
-  "front_end/sdk/PaintProfiler.js",
-  "front_end/sdk/PerformanceMetricsModel.js",
-  "front_end/sdk/ProfileTreeModel.js",
-  "front_end/sdk/RemoteObject.js",
-  "front_end/sdk/Resource.js",
-  "front_end/sdk/ResourceTreeModel.js",
-  "front_end/sdk/RuntimeModel.js",
-  "front_end/sdk/ScreenCaptureModel.js",
-  "front_end/sdk/Script.js",
-  "front_end/sdk/SecurityOriginManager.js",
-  "front_end/sdk/ServerTiming.js",
-  "front_end/sdk/ServiceWorkerCacheModel.js",
-  "front_end/sdk/ServiceWorkerManager.js",
-  "front_end/sdk/SourceMap.js",
-  "front_end/sdk/SourceMapManager.js",
-  "front_end/sdk/Target.js",
-  "front_end/sdk/TargetManager.js",
-  "front_end/sdk/TracingManager.js",
-  "front_end/sdk/TracingModel.js",
-  "front_end/sdk_test_runner/module.json",
-  "front_end/sdk_test_runner/PageMockTestRunner.js",
-  "front_end/search/SearchConfig.js",
-  "front_end/search/searchResultsPane.css",
-  "front_end/search/SearchResultsPane.js",
-  "front_end/search/searchView.css",
-  "front_end/search/SearchView.js",
-  "front_end/security/lockIcon.css",
-  "front_end/security/mainView.css",
-  "front_end/security/module.json",
-  "front_end/security/originView.css",
-  "front_end/security/SecurityModel.js",
-  "front_end/security/SecurityPanel.js",
-  "front_end/security/sidebar.css",
-  "front_end/security_test_runner/module.json",
-  "front_end/security_test_runner/SecurityTestRunner.js",
-  "front_end/services/ServiceManager.js",
-  "front_end/settings/frameworkBlackboxSettingsTab.css",
-  "front_end/settings/FrameworkBlackboxSettingsTab.js",
-  "front_end/settings/module.json",
-  "front_end/settings/settingsScreen.css",
-  "front_end/settings/SettingsScreen.js",
-  "front_end/snippets/module.json",
-  "front_end/snippets/ScriptSnippetModel.js",
-  "front_end/snippets/SnippetsQuickOpen.js",
-  "front_end/snippets/SnippetStorage.js",
-  "front_end/source_frame/fontView.css",
-  "front_end/source_frame/FontView.js",
-  "front_end/source_frame/imageView.css",
-  "front_end/source_frame/jsonView.css",
-  "front_end/source_frame/JSONView.js",
-  "front_end/source_frame/ImageView.js",
-  "front_end/source_frame/messagesPopover.css",
-  "front_end/source_frame/module.json",
-  "front_end/source_frame/PreviewFactory.js",
-  "front_end/source_frame/resourceSourceFrame.css",
-  "front_end/source_frame/ResourceSourceFrame.js",
-  "front_end/source_frame/SourceCodeDiff.js",
-  "front_end/source_frame/SourceFrame.js",
-  "front_end/source_frame/SourcesTextEditor.js",
-  "front_end/source_frame/xmlTree.css",
-  "front_end/source_frame/xmlView.css",
-  "front_end/source_frame/XMLView.js",
-  "front_end/sources/AddSourceMapURLDialog.js",
-  "front_end/sources/callStackSidebarPane.css",
-  "front_end/sources/CallStackSidebarPane.js",
-  "front_end/sources/CSSPlugin.js",
-  "front_end/sources/dialog.css",
-  "front_end/sources/debuggerPausedMessage.css",
-  "front_end/sources/DebuggerPausedMessage.js",
-  "front_end/sources/EditingLocationHistoryManager.js",
-  "front_end/sources/FilePathScoreFunction.js",
-  "front_end/sources/FilteredUISourceCodeListProvider.js",
-  "front_end/sources/GoToLineQuickOpen.js",
-  "front_end/sources/InplaceFormatterEditorAction.js",
-  "front_end/sources/javaScriptBreakpointsSidebarPane.css",
-  "front_end/sources/JavaScriptBreakpointsSidebarPane.js",
-  "front_end/sources/JavaScriptCompilerPlugin.js",
-  "front_end/sources/JavaScriptSourceFrame.js",
-  "front_end/sources/module.json",
-  "front_end/sources/navigatorTree.css",
-  "front_end/sources/navigatorView.css",
-  "front_end/sources/NavigatorView.js",
-  "front_end/sources/OpenFileQuickOpen.js",
-  "front_end/sources/OutlineQuickOpen.js",
-  "front_end/sources/revisionHistory.css",
-  "front_end/sources/scopeChainSidebarPane.css",
-  "front_end/sources/ScopeChainSidebarPane.js",
-  "front_end/sources/ScriptFormatterEditorAction.js",
-  "front_end/sources/SearchSourcesView.js",
-  "front_end/sources/serviceWorkersSidebar.css",
-  "front_end/sources/SimpleHistoryManager.js",
-  "front_end/sources/SnippetsPlugin.js",
-  "front_end/sources/SourceFormatter.js",
-  "front_end/sources/SourceMapNamesResolver.js",
-  "front_end/sources/SourcesNavigator.js",
-  "front_end/sources/sourcesPanel.css",
-  "front_end/sources/SourcesPanel.js",
-  "front_end/sources/SourcesSearchScope.js",
-  "front_end/sources/sourcesView.css",
-  "front_end/sources/SourcesView.js",
-  "front_end/sources/UISourceCodeFrame.js",
-  "front_end/sources/TabbedEditorContainer.js",
-  "front_end/sources/threadsSidebarPane.css",
-  "front_end/sources/ThreadsSidebarPane.js",
-  "front_end/sources/watchExpressionsSidebarPane.css",
-  "front_end/sources/WatchExpressionsSidebarPane.js",
-  "front_end/sources_test_runner/AutocompleteTestRunner.js",
-  "front_end/sources_test_runner/DebuggerTestRunner.js",
-  "front_end/sources_test_runner/EditorTestRunner.js",
-  "front_end/sources_test_runner/LiveEditTestRunner.js",
-  "front_end/sources_test_runner/SearchTestRunner.js",
-  "front_end/sources_test_runner/SourcesTestRunner.js",
-  "front_end/sources_test_runner/module.json",
-  "front_end/terminal/terminal.css",
-  "front_end/terminal/TerminalWidget.js",
-  "front_end/terminal/xterm.js/addons/fit/fit.js",
-  "front_end/terminal/xterm.js/build/xterm.css",
-  "front_end/terminal/xterm.js/build/xterm.js",
-  "front_end/test_runner/module.json",
-  "front_end/test_runner/TestRunner.js",
-  "front_end/text_editor/cmdevtools.css",
-  "front_end/text_editor/CodeMirrorTextEditor.js",
-  "front_end/text_editor/CodeMirrorUtils.js",
-  "front_end/text_editor/module.json",
-  "front_end/text_editor/TextEditorAutocompleteController.js",
-  "front_end/text_utils/module.json",
-  "front_end/text_utils/Text.js",
-  "front_end/text_utils/TextRange.js",
-  "front_end/text_utils/TextUtils.js",
-  "front_end/timeline_model/module.json",
-  "front_end/timeline_model/TimelineFrameModel.js",
-  "front_end/timeline_model/TimelineIRModel.js",
-  "front_end/timeline_model/TimelineJSProfile.js",
-  "front_end/timeline_model/TimelineModel.js",
-  "front_end/timeline_model/TimelineModelFilter.js",
-  "front_end/timeline_model/TimelineProfileTree.js",
-  "front_end/timeline_model/TracingLayerTree.js",
-  "front_end/timeline/CountersGraph.js",
-  "front_end/timeline/EventsTimelineTreeView.js",
-  "front_end/timeline/ExtensionTracingSession.js",
-  "front_end/timeline/historyToolbarButton.css",
-  "front_end/timeline/invalidationsTree.css",
-  "front_end/timeline/module.json",
-  "front_end/timeline/PerformanceModel.js",
-  "front_end/timeline/TimelineController.js",
-  "front_end/timeline/TimelineDetailsView.js",
-  "front_end/timeline/TimelineEventOverview.js",
-  "front_end/timeline/TimelineFilters.js",
-  "front_end/timeline/TimelineFlameChartDataProvider.js",
-  "front_end/timeline/TimelineFlameChartNetworkDataProvider.js",
-  "front_end/timeline/timelineFlamechartPopover.css",
-  "front_end/timeline/TimelineFlameChartView.js",
-  "front_end/timeline/timelineHistoryManager.css",
-  "front_end/timeline/TimelineHistoryManager.js",
-  "front_end/timeline/TimelineLayersView.js",
-  "front_end/timeline/TimelineLoader.js",
-  "front_end/timeline/timelinePaintProfiler.css",
-  "front_end/timeline/TimelinePaintProfilerView.js",
-  "front_end/timeline/timelinePanel.css",
-  "front_end/timeline/TimelinePanel.js",
-  "front_end/timeline/timelineStatusDialog.css",
-  "front_end/timeline/TimelineTreeView.js",
-  "front_end/timeline/TimelineUIUtils.js",
-  "front_end/toolbox_bootstrap/module.json",
-  "front_end/toolbox_bootstrap/Toolbox.js",
-  "front_end/toolbox.js",
-  "front_end/toolbox.json",
-  "front_end/ui/ActionRegistry.js",
-  "front_end/ui/ARIAUtils.js",
-  "front_end/ui/checkboxTextLabel.css",
-  "front_end/ui/closeButton.css",
-  "front_end/ui/confirmDialog.css",
-  "front_end/ui/Context.js",
-  "front_end/ui/ContextMenu.js",
-  "front_end/ui/dialog.css",
-  "front_end/ui/Dialog.js",
-  "front_end/ui/SyntaxHighlighter.js",
-  "front_end/ui/dropTarget.css",
-  "front_end/ui/DropTarget.js",
-  "front_end/ui/emptyWidget.css",
-  "front_end/ui/EmptyWidget.js",
-  "front_end/ui/filter.css",
-  "front_end/ui/FilterBar.js",
-  "front_end/ui/FilterSuggestionBuilder.js",
-  "front_end/ui/ForwardedInputEventHandler.js",
-  "front_end/ui/Fragment.js",
-  "front_end/ui/Geometry.js",
-  "front_end/ui/glassPane.css",
-  "front_end/ui/GlassPane.js",
-  "front_end/ui/HistoryInput.js",
-  "front_end/ui/Icon.js",
-  "front_end/ui/infobar.css",
-  "front_end/ui/Infobar.js",
-  "front_end/ui/inlineButton.css",
-  "front_end/ui/InplaceEditor.js",
-  "front_end/ui/inspectorCommon.css",
-  "front_end/ui/inspectorStyle.css",
-  "front_end/ui/inspectorSyntaxHighlight.css",
-  "front_end/ui/inspectorSyntaxHighlightDark.css",
-  "front_end/ui/InspectorView.js",
-  "front_end/ui/inspectorViewTabbedPane.css",
-  "front_end/ui/KeyboardShortcut.js",
-  "front_end/ui/ListControl.js",
-  "front_end/ui/ListModel.js",
-  "front_end/ui/listWidget.css",
-  "front_end/ui/ListWidget.js",
-  "front_end/ui/module.json",
-  "front_end/ui/Panel.js",
-  "front_end/ui/popover.css",
-  "front_end/ui/Popover.js",
-  "front_end/ui/progressIndicator.css",
-  "front_end/ui/ProgressIndicator.js",
-  "front_end/ui/radioButton.css",
-  "front_end/ui/reportView.css",
-  "front_end/ui/ReportView.js",
-  "front_end/ui/ResizerWidget.js",
-  "front_end/ui/RemoteDebuggingTerminatedScreen.js",
-  "front_end/ui/remoteDebuggingTerminatedScreen.css",
-  "front_end/ui/rootView.css",
-  "front_end/ui/RootView.js",
-  "front_end/ui/searchableView.css",
-  "front_end/ui/SearchableView.js",
-  "front_end/ui/segmentedButton.css",
-  "front_end/ui/SegmentedButton.js",
-  "front_end/ui/SettingsUI.js",
-  "front_end/ui/ShortcutRegistry.js",
-  "front_end/ui/ShortcutsScreen.js",
-  "front_end/ui/slider.css",
-  "front_end/ui/smallBubble.css",
-  "front_end/ui/softContextMenu.css",
-  "front_end/ui/SoftContextMenu.js",
-  "front_end/ui/SoftDropDown.js",
-  "front_end/ui/softDropDown.css",
-  "front_end/ui/softDropDownButton.css",
-  "front_end/ui/splitWidget.css",
-  "front_end/ui/SplitWidget.js",
-  "front_end/ui/suggestBox.css",
-  "front_end/ui/SuggestBox.js",
-  "front_end/ui/tabbedPane.css",
-  "front_end/ui/TabbedPane.js",
-  "front_end/ui/TargetCrashedScreen.js",
-  "front_end/ui/targetCrashedScreen.css",
-  "front_end/ui/textButton.css",
-  "front_end/ui/TextEditor.js",
-  "front_end/ui/textPrompt.css",
-  "front_end/ui/TextPrompt.js",
-  "front_end/ui/ThrottledWidget.js",
-  "front_end/ui/toolbar.css",
-  "front_end/ui/Toolbar.js",
-  "front_end/ui/tooltip.css",
-  "front_end/ui/Tooltip.js",
-  "front_end/ui/treeoutline.css",
-  "front_end/ui/treeoutline.js",
-  "front_end/ui/UIUtils.js",
-  "front_end/ui/View.js",
-  "front_end/ui/viewContainers.css",
-  "front_end/ui/Widget.js",
-  "front_end/ui/XElement.js",
-  "front_end/ui/XLink.js",
-  "front_end/ui/XWidget.js",
-  "front_end/ui/ZoomManager.js",
-  "front_end/worker_main/WorkerMain.js",
-  "front_end/worker_main/module.json",
-  "front_end/worker_service/ServiceDispatcher.js",
-  "front_end/workspace/FileManager.js",
-  "front_end/workspace/module.json",
-  "front_end/workspace/UISourceCode.js",
-  "front_end/workspace/Workspace.js",
-  "front_end/workspace_diff/WorkspaceDiff.js",
-  "front_end/workspace_diff/module.json",
-]
-
-devtools_embedder_scripts = [
-  "front_end/devtools_compatibility.js",
-  "front_end/Tests.js",
-]
-
-devtools_emulated_devices_images = [
-  "front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png",
-  "front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png",
-  "front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png",
-  "front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png",
-  "front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png",
-  "front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png",
-  "front_end/emulated_devices/google-nexus-5-vertical-default-1x.png",
-  "front_end/emulated_devices/google-nexus-5-vertical-default-2x.png",
-  "front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png",
-  "front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png",
-  "front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png",
-  "front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png",
-  "front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png",
-  "front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png",
-  "front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png",
-  "front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png",
-  "front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png",
-  "front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png",
-  "front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png",
-  "front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png",
-  "front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png",
-  "front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png",
-  "front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png",
-  "front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png",
-  "front_end/emulated_devices/iPad-landscape.svg",
-  "front_end/emulated_devices/iPad-portrait.svg",
-  "front_end/emulated_devices/iPhone5-landscape.svg",
-  "front_end/emulated_devices/iPhone5-portrait.svg",
-  "front_end/emulated_devices/iPhone6-landscape.svg",
-  "front_end/emulated_devices/iPhone6-portrait.svg",
-  "front_end/emulated_devices/iPhone6Plus-landscape.svg",
-  "front_end/emulated_devices/iPhone6Plus-portrait.svg",
-  "front_end/emulated_devices/Nexus5X-landscape.svg",
-  "front_end/emulated_devices/Nexus5X-portrait.svg",
-  "front_end/emulated_devices/Nexus6P-landscape.svg",
-  "front_end/emulated_devices/Nexus6P-portrait.svg",
-]
-
-devtools_image_files = [
-  "front_end/Images/accelerometer-back.png",
-  "front_end/Images/accelerometer-bottom.png",
-  "front_end/Images/accelerometer-front.png",
-  "front_end/Images/accelerometer-left.png",
-  "front_end/Images/accelerometer-right.png",
-  "front_end/Images/accelerometer-top.png",
-  "front_end/Images/audits_logo.svg",
-  "front_end/Images/breakpoint.png",
-  "front_end/Images/breakpoint_2x.png",
-  "front_end/Images/breakpointConditional.png",
-  "front_end/Images/breakpointConditional_2x.png",
-  "front_end/Images/checker.png",
-  "front_end/Images/chromeDisabledSelect.png",
-  "front_end/Images/chromeDisabledSelect_2x.png",
-  "front_end/Images/chromeLeft.png",
-  "front_end/Images/chromeMiddle.png",
-  "front_end/Images/chromeRight.png",
-  "front_end/Images/chromeSelect.png",
-  "front_end/Images/chromeSelect_2x.png",
-  "front_end/Images/deleteIcon.png",
-  "front_end/Images/errorWave.png",
-  "front_end/Images/errorWave_2x.png",
-  "front_end/Images/ic_info_black_18dp.svg",
-  "front_end/Images/ic_warning_black_18dp.svg",
-  "front_end/Images/navigationControls.png",
-  "front_end/Images/navigationControls_2x.png",
-  "front_end/Images/nodeIcon.png",
-  "front_end/Images/popoverArrows.png",
-  "front_end/Images/profileGroupIcon.png",
-  "front_end/Images/profileIcon.png",
-  "front_end/Images/profileSmallIcon.png",
-  "front_end/Images/radioDot.png",
-  "front_end/Images/resizeDiagonal.png",
-  "front_end/Images/resizeDiagonal_2x.png",
-  "front_end/Images/resizeHorizontal.png",
-  "front_end/Images/resizeHorizontal_2x.png",
-  "front_end/Images/resizeVertical.png",
-  "front_end/Images/resizeVertical_2x.png",
-  "front_end/Images/resourceCSSIcon.png",
-  "front_end/Images/resourceDocumentIcon.png",
-  "front_end/Images/resourceDocumentIconSmall.png",
-  "front_end/Images/mediumIcons.png",
-  "front_end/Images/mediumIcons_2x.png",
-  "front_end/Images/resourceJSIcon.png",
-  "front_end/Images/resourcePlainIcon.png",
-  "front_end/Images/resourcePlainIconSmall.png",
-  "front_end/Images/resourcesTimeGraphIcon.png",
-  "front_end/Images/searchNext.png",
-  "front_end/Images/searchPrev.png",
-  "front_end/Images/securityIcons_2x.png",
-  "front_end/Images/securityIcons.png",
-  "front_end/Images/smallIcons.png",
-  "front_end/Images/smallIcons_2x.png",
-  "front_end/Images/speech.png",
-  "front_end/Images/treeoutlineTriangles.png",
-  "front_end/Images/treeoutlineTriangles_2x.png",
-  "front_end/Images/largeIcons.png",
-  "front_end/Images/largeIcons_2x.png",
-  "front_end/Images/toolbarResizerVertical.png",
-  "front_end/Images/touchCursor.png",
-  "front_end/Images/touchCursor_2x.png",
-  "front_end/Images/whatsnew.png",
-]
-
-resources_out_dir = "$root_out_dir/resources/inspector"
-
-generated_scripts = [
-  "$resources_out_dir/InspectorBackendCommands.js",
-  "$resources_out_dir/SupportedCSSProperties.js",
-]
-
-application_templates = [
-  "front_end/devtools_app.html",
-  "front_end/inspector.html",
-  "front_end/integration_test_runner.html",
-  "front_end/js_app.html",
-  "front_end/ndb_app.html",
-  "front_end/node_app.html",
-  "front_end/toolbox.html",
-  "front_end/worker_app.html",
-]
-
-generated_applications = [
-  "$resources_out_dir/audits2_worker.js",
-  "$resources_out_dir/devtools_app.html",
-  "$resources_out_dir/devtools_app.js",
-  "$resources_out_dir/formatter_worker.js",
-  "$resources_out_dir/heap_snapshot_worker.js",
-  "$resources_out_dir/inspector.html",
-  "$resources_out_dir/inspector.js",
-  "$resources_out_dir/js_app.html",
-  "$resources_out_dir/js_app.js",
-  "$resources_out_dir/node_app.html",
-  "$resources_out_dir/node_app.js",
-  "$resources_out_dir/shell.js",
-  "$resources_out_dir/toolbox.html",
-  "$resources_out_dir/toolbox.js",
-  "$resources_out_dir/worker_app.html",
-  "$resources_out_dir/worker_app.js",
-]
-
-generated_non_autostart_non_remote_modules = [
-  "$resources_out_dir/animation/animation_module.js",
-  "$resources_out_dir/audits2/audits2_module.js",
-  "$resources_out_dir/browser_console/browser_console_module.js",
-  "$resources_out_dir/browser_debugger/browser_debugger_module.js",
-  "$resources_out_dir/changes/changes_module.js",
-  "$resources_out_dir/protocol_monitor/protocol_monitor_module.js",
-  "$resources_out_dir/cm/cm_module.js",
-  "$resources_out_dir/color_picker/color_picker_module.js",
-  "$resources_out_dir/console/console_module.js",
-  "$resources_out_dir/cookie_table/cookie_table_module.js",
-  "$resources_out_dir/coverage/coverage_module.js",
-  "$resources_out_dir/data_grid/data_grid_module.js",
-  "$resources_out_dir/devices/devices_module.js",
-  "$resources_out_dir/diff/diff_module.js",
-  "$resources_out_dir/elements/elements_module.js",
-  "$resources_out_dir/event_listeners/event_listeners_module.js",
-  "$resources_out_dir/formatter/formatter_module.js",
-  "$resources_out_dir/har_importer/har_importer_module.js",
-  "$resources_out_dir/heap_snapshot_model/heap_snapshot_model_module.js",
-  "$resources_out_dir/help/help_module.js",
-  "$resources_out_dir/inline_editor/inline_editor_module.js",
-  "$resources_out_dir/js_profiler/js_profiler_module.js",
-  "$resources_out_dir/layer_viewer/layer_viewer_module.js",
-  "$resources_out_dir/layers/layers_module.js",
-  "$resources_out_dir/network/network_module.js",
-  "$resources_out_dir/node_debugger/node_debugger_module.js",
-  "$resources_out_dir/object_ui/object_ui_module.js",
-  "$resources_out_dir/perf_ui/perf_ui_module.js",
-  "$resources_out_dir/performance_monitor/performance_monitor_module.js",
-  "$resources_out_dir/profiler/profiler_module.js",
-  "$resources_out_dir/quick_open/quick_open_module.js",
-  "$resources_out_dir/resources/resources_module.js",
-  "$resources_out_dir/search/search_module.js",
-  "$resources_out_dir/security/security_module.js",
-  "$resources_out_dir/settings/settings_module.js",
-  "$resources_out_dir/snippets/snippets_module.js",
-  "$resources_out_dir/source_frame/source_frame_module.js",
-  "$resources_out_dir/sources/sources_module.js",
-  "$resources_out_dir/text_editor/text_editor_module.js",
-  "$resources_out_dir/timeline_model/timeline_model_module.js",
-  "$resources_out_dir/timeline/timeline_module.js",
-  "$resources_out_dir/workspace_diff/workspace_diff_module.js",
-]
-
-generated_remote_modules = [
-  "$resources_out_dir/accessibility/accessibility_module.js",
-  "$resources_out_dir/audits2_worker/audits2_worker_module.js",
-  "$resources_out_dir/cm_modes/cm_modes_module.js",
-  "$resources_out_dir/emulated_devices/emulated_devices_module.js",
-  "$resources_out_dir/product_registry_impl/product_registry_impl_module.js",
-]
-
-devtools_applications = [
-  "audits2_worker",
-  "devtools_app",
-  "formatter_worker",
-  "heap_snapshot_worker",
-  "inspector",
-  "integration_test_runner",
-  "js_app",
-  "ndb_app",
-  "node_app",
-  "shell",
-  "toolbox",
-  "worker_app",
-]
-
-#-------------------------------------------------------------------------------
-
-visibility = [ "//third_party/blink/*" ]
-
-group("devtools_all_files") {
-  data = all_devtools_files
-}
-
-group("devtools_frontend_resources") {
-  public_deps = [
-    ":build_release_devtools",
-    ":copy_embedder_scripts",
-    ":copy_emulated_devices_images",
-    ":copy_inspector_images",
-    ":devtools_extension_api",
-    ":frontend_protocol_sources",
-    ":supported_css_properties",
-  ]
-  if (debug_devtools) {
-    public_deps += [ ":build_debug_devtools" ]
-  }
-}
-
-copy("copy_embedder_scripts") {
-  sources = devtools_embedder_scripts
-  outputs = [
-    "$resources_out_dir/{{source_file_part}}",
-  ]
-}
-
-copy("copy_inspector_images") {
-  sources = devtools_image_files
-  outputs = [
-    "$resources_out_dir/Images/{{source_file_part}}",
-  ]
-}
-
-copy("copy_emulated_devices_images") {
-  sources = devtools_emulated_devices_images
-  outputs = [
-    "$resources_out_dir/emulated_devices/{{source_file_part}}",
-  ]
-}
-
-action("generate_devtools_grd") {
-  script = "scripts/build/generate_devtools_grd.py"
-
-  deps = [
-    ":devtools_frontend_resources",
-  ]
-
-  grd_files =
-      generated_applications + generated_non_autostart_non_remote_modules +
-      devtools_embedder_scripts +
-      [ "$resources_out_dir/devtools_extension_api.js" ]
-
-  # Bundle remote modules in ChromeOS.
-  if (is_chromeos) {
-    grd_files += generated_remote_modules
-  }
-
-  inputs = grd_files + devtools_image_files
-  outfile = "$root_gen_dir/devtools/devtools_resources.grd"
-  outputs = [
-    outfile,
-  ]
-
-  relative_path_dirs = [
-    resources_out_dir,
-    "front_end",
-  ]
-
-  args = rebase_path(grd_files, root_build_dir) + [ "--relative_path_dirs" ] +
-         rebase_path(relative_path_dirs, root_build_dir) +
-         [
-           "--images",
-           rebase_path("front_end/Images", root_build_dir),
-           "--output",
-           rebase_path(outfile, root_build_dir),
-         ]
-}
-
-action("devtools_extension_api") {
-  script = "scripts/build/generate_devtools_extension_api.py"
-
-  devtools_extension_api_files = [ "front_end/extensions/ExtensionAPI.js" ]
-  inputs = devtools_extension_api_files
-  outputs = [
-    "$resources_out_dir/devtools_extension_api.js",
-  ]
-
-  args = rebase_path(outputs, root_build_dir) +
-         rebase_path(devtools_extension_api_files, root_build_dir)
-}
-
-action("supported_css_properties") {
-  script = "scripts/build/generate_supported_css.py"
-
-  inputs = [
-    "../core/css/CSSProperties.json5",
-  ]
-
-  outputs = [
-    "$resources_out_dir/SupportedCSSProperties.js",
-  ]
-
-  args =
-      rebase_path(inputs, root_build_dir) + rebase_path(outputs, root_build_dir)
-}
-
-action("frontend_protocol_sources") {
-  script = "scripts/build/code_generator_frontend.py"
-  deps = [
-    "../core/inspector:protocol_version",
-  ]
-  inputs = [
-    "$blink_core_output_dir/inspector/protocol.json",
-  ]
-  outputs = [
-    "$resources_out_dir/InspectorBackendCommands.js",
-  ]
-
-  args = rebase_path(inputs, root_build_dir) + [
-           "--output_js_dir",
-           rebase_path(resources_out_dir, root_build_dir),
-         ]
-}
-
-action("build_release_devtools") {
-  script = "scripts/build/build_release_applications.py"
-
-  deps = [
-    ":frontend_protocol_sources",
-    ":supported_css_properties",
-  ]
-
-  helper_scripts = [
-    "scripts/build/modular_build.py",
-    "scripts/build/rjsmin.py",
-  ]
-
-  inputs = helper_scripts + all_devtools_files + generated_scripts +
-           application_templates
-  outputs =
-      generated_applications + generated_non_autostart_non_remote_modules +
-      generated_remote_modules
-
-  args = devtools_applications + [
-           "--input_path",
-           rebase_path("front_end", root_build_dir),
-           "--output_path",
-           rebase_path(resources_out_dir, root_build_dir),
-         ]
-}
-
-if (debug_devtools) {
-  resources_out_debug_dir = "$root_out_dir/resources/inspector/debug"
-
-  action("build_debug_devtools") {
-    script = "scripts/build/build_debug_applications.py"
-
-    deps = [
-      ":copy_generated_scripts",
-    ]
-
-    inputs = all_devtools_files + application_templates
-    outputs = [
-      "$resources_out_debug_dir/devtools_app.html",
-      "$resources_out_debug_dir/inspector.html",
-      "$resources_out_debug_dir/integration_test_runner.html",
-      "$resources_out_debug_dir/js_app.html",
-      "$resources_out_debug_dir/ndb_app.html",
-      "$resources_out_debug_dir/node_app.html",
-      "$resources_out_debug_dir/toolbox.html",
-      "$resources_out_debug_dir/worker_app.html",
-    ]
-
-    args = devtools_applications + [
-             "--input_path",
-             rebase_path("front_end", root_build_dir),
-             "--output_path",
-             rebase_path(resources_out_debug_dir, root_build_dir),
-           ]
-  }
-
-  copy("copy_generated_scripts") {
-    deps = [
-      ":frontend_protocol_sources",
-      ":supported_css_properties",
-    ]
-    sources = generated_scripts
-    outputs = [
-      "$resources_out_debug_dir/{{source_file_part}}",
-    ]
-  }
-}
-
-group("devtools_closure_compile") {
-  data = [
-    # Needed for isolate script to execute.
-    "front_end/",
-    "scripts/build/",
-    "scripts/closure/",
-    "scripts/compile_frontend.py",
-    "scripts/dependency_preprocessor.py",
-    "scripts/jsdoc_validator/",
-    "scripts/special_case_namespaces.json",
-    "scripts/utils.py",
-    "//testing/scripts/common.py",
-    "//testing/scripts/run_devtools_check.py",
-    "//testing/xvfb.py",
-    "//third_party/blink/renderer/core/inspector/browser_protocol.json",
-    "//v8/src/inspector/js_protocol.json",
-  ]
-}
-
-if (is_linux && !is_chromeos) {
-  group("devtools_eslint") {
-    data = [
-      # Needed for isolate script to execute.
-      ".eslintignore",
-      ".eslintrc.js",
-      "front_end/",
-      "scripts/lint_javascript.py",
-      "scripts/local_node.py",
-      "//testing/scripts/common.py",
-      "//testing/scripts/run_devtools_check.py",
-      "//testing/xvfb.py",
-      "//third_party/devtools-node-modules/",
-      "//third_party/node/node.py",
-      "//third_party/node/linux/node-linux-x64/",
-    ]
-  }
-}
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 972bb2e..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/OWNERS b/OWNERS
deleted file mode 100644
index 090886e..0000000
--- a/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-dgozman@chromium.org
-pfeldman@chromium.org
-lushnikov@chromium.org
-per-file devtools.gyp*=*
-per-file BUILD.gn=*
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
deleted file mode 100644
index f19f443..0000000
--- a/PRESUBMIT.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# Copyright (C) 2014 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""DevTools JSDoc validator presubmit script
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into gcl.
-"""
-
-import sys
-
-
-def _CheckBuildGN(input_api, output_api):
-    script_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "check_gn.js")
-    return _checkWithNodeScript(input_api, output_api, script_path)
-
-
-def _CheckFormat(input_api, output_api):
-
-    def popen(args):
-        return input_api.subprocess.Popen(args=args, stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT)
-
-    affected_files = _getAffectedJSFiles(input_api)
-    if len(affected_files) == 0:
-        return []
-    original_sys_path = sys.path
-    try:
-        sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts")]
-        import local_node
-    finally:
-        sys.path = original_sys_path
-
-    ignore_files = []
-    eslint_ignore_path = input_api.os_path.join(input_api.PresubmitLocalPath(), '.eslintignore')
-    with open(eslint_ignore_path, 'r') as ignore_manifest:
-        for line in ignore_manifest:
-            ignore_files.append(line.strip())
-    formattable_files = [affected_file for affected_file in affected_files
-                         if all(ignore_file not in affected_file for ignore_file in ignore_files)]
-    if len(formattable_files) == 0:
-        return []
-
-    check_formatting_process = popen(['git', 'cl', 'format', '--js', '--dry-run'] + formattable_files)
-    check_formatting_process.communicate()
-    if check_formatting_process.returncode == 0:
-        return []
-
-    format_args = ['git', 'cl', 'format', '--js'] + formattable_files
-    format_process = popen(format_args)
-    format_out, _ = format_process.communicate()
-    if format_process.returncode != 0:
-        return [output_api.PresubmitError(format_out)]
-
-    # Use eslint to autofix the braces.
-    # Also fix semicolon to avoid confusing clang-format.
-    eslint_process = popen([
-        local_node.node_path(), local_node.eslint_path(),
-        '--no-eslintrc', '--fix', '--env=es6', '--rule={"curly": [2, "multi-or-nest", "consistent"], "semi": 2}'
-    ] + affected_files)
-    eslint_process.communicate()
-
-    # Need to run clang-format again to align the braces
-    popen(format_args).communicate()
-
-    return [
-        output_api.PresubmitError("ERROR: Found formatting violations in third_party/WebKit/Source/devtools.\n"
-                                  "Ran clang-format on diff\n"
-                                  "Use git status to check the formatting changes"),
-        output_api.PresubmitError(format_out),
-    ]
-
-
-def _CheckDevtoolsStyle(input_api, output_api):
-    affected_front_end_files = _getAffectedFrontEndFiles(input_api)
-    if len(affected_front_end_files) > 0:
-        lint_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "lint_javascript.py")
-        process = input_api.subprocess.Popen(
-            [input_api.python_executable, lint_path] + affected_front_end_files,
-            stdout=input_api.subprocess.PIPE,
-            stderr=input_api.subprocess.STDOUT)
-        out, _ = process.communicate()
-        if process.returncode != 0:
-            return [output_api.PresubmitError(out)]
-        return [output_api.PresubmitNotifyResult(out)]
-    return []
-
-
-def _CompileDevtoolsFrontend(input_api, output_api):
-    compile_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "compile_frontend.py")
-    out, _ = input_api.subprocess.Popen(
-        [input_api.python_executable, compile_path], stdout=input_api.subprocess.PIPE,
-        stderr=input_api.subprocess.STDOUT).communicate()
-    if "ERROR" in out or "WARNING" in out:
-        return [output_api.PresubmitError(out)]
-    if "NOTE" in out:
-        return [output_api.PresubmitPromptWarning(out)]
-    return []
-
-
-def _CheckConvertSVGToPNGHashes(input_api, output_api):
-    if not input_api.platform.startswith('linux'):
-        return []
-
-    original_sys_path = sys.path
-    try:
-        sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), 'scripts', 'build')]
-        import devtools_file_hashes
-    finally:
-        sys.path = original_sys_path
-
-    absolute_local_paths = [af.AbsoluteLocalPath() for af in input_api.AffectedFiles(include_deletes=False)]
-    images_src_path = input_api.os_path.join("devtools", "front_end", "Images", "src")
-    image_source_file_paths = [path for path in absolute_local_paths if images_src_path in path and path.endswith(".svg")]
-    image_sources_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "front_end", "Images", "src")
-    hashes_file_name = "svg2png.hashes"
-    hashes_file_path = input_api.os_path.join(image_sources_path, hashes_file_name)
-    invalid_hash_file_paths = devtools_file_hashes.files_with_invalid_hashes(hashes_file_path, image_source_file_paths)
-    if len(invalid_hash_file_paths) == 0:
-        return []
-    invalid_hash_file_names = [input_api.os_path.basename(file_path) for file_path in invalid_hash_file_paths]
-    file_paths_str = ", ".join(invalid_hash_file_names)
-    error_message = "The following SVG files should be converted to PNG using convert_svg_images_png.py script before uploading: \n  - %s" % file_paths_str
-    return [output_api.PresubmitError(error_message)]
-
-
-def _CheckOptimizePNGHashes(input_api, output_api):
-    if not input_api.platform.startswith('linux'):
-        return []
-
-    original_sys_path = sys.path
-    try:
-        sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), 'scripts', 'build')]
-        import devtools_file_hashes
-    finally:
-        sys.path = original_sys_path
-
-    absolute_local_paths = [af.AbsoluteLocalPath() for af in input_api.AffectedFiles(include_deletes=False)]
-    images_src_path = input_api.os_path.join("devtools", "front_end", "Images", "src")
-    image_source_file_paths = [path for path in absolute_local_paths if images_src_path in path and path.endswith(".svg")]
-    image_sources_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "front_end", "Images", "src")
-    hashes_file_name = "optimize_png.hashes"
-    hashes_file_path = input_api.os_path.join(image_sources_path, hashes_file_name)
-    invalid_hash_file_paths = devtools_file_hashes.files_with_invalid_hashes(hashes_file_path, image_source_file_paths)
-    if len(invalid_hash_file_paths) == 0:
-        return []
-    invalid_hash_file_names = [input_api.os_path.basename(file_path) for file_path in invalid_hash_file_paths]
-    file_paths_str = ", ".join(invalid_hash_file_names)
-    error_message = "The following PNG files should be optimized using optimize_png_images.py script before uploading: \n  - %s" % file_paths_str
-    return [output_api.PresubmitError(error_message)]
-
-
-def _CheckCSSViolations(input_api, output_api):
-    results = []
-    for f in input_api.AffectedFiles(include_deletes=False):
-        if not f.LocalPath().endswith(".css"):
-            continue
-        for line_number, line in f.ChangedContents():
-            if "/deep/" in line:
-                results.append(output_api.PresubmitError(("%s:%d uses /deep/ selector") % (f.LocalPath(), line_number)))
-            if "::shadow" in line:
-                results.append(output_api.PresubmitError(("%s:%d uses ::shadow selector") % (f.LocalPath(), line_number)))
-    return results
-
-
-def CheckChangeOnUpload(input_api, output_api):
-    results = []
-    results.extend(_CheckBuildGN(input_api, output_api))
-    results.extend(_CheckFormat(input_api, output_api))
-    results.extend(_CheckDevtoolsStyle(input_api, output_api))
-    results.extend(_CompileDevtoolsFrontend(input_api, output_api))
-    results.extend(_CheckConvertSVGToPNGHashes(input_api, output_api))
-    results.extend(_CheckOptimizePNGHashes(input_api, output_api))
-    results.extend(_CheckCSSViolations(input_api, output_api))
-    return results
-
-
-def CheckChangeOnCommit(input_api, output_api):
-    return []
-
-
-def _getAffectedFrontEndFiles(input_api):
-    local_paths = [f.AbsoluteLocalPath() for f in input_api.AffectedFiles() if f.Action() != "D"]
-    devtools_root = input_api.PresubmitLocalPath()
-    devtools_front_end = input_api.os_path.join(devtools_root, "front_end")
-    affected_front_end_files = [
-        file_name for file_name in local_paths if devtools_front_end in file_name and file_name.endswith(".js")
-    ]
-    return [input_api.os_path.relpath(file_name, devtools_root) for file_name in affected_front_end_files]
-
-
-def _getAffectedJSFiles(input_api):
-    local_paths = [f.AbsoluteLocalPath() for f in input_api.AffectedFiles() if f.Action() != "D"]
-    devtools_root = input_api.PresubmitLocalPath()
-    devtools_front_end = input_api.os_path.join(devtools_root, "front_end")
-    devtools_scripts = input_api.os_path.join(devtools_root, "scripts")
-    affected_js_files = [
-        file_name for file_name in local_paths
-        if (devtools_front_end in file_name or devtools_scripts in file_name) and file_name.endswith(".js")
-    ]
-    return [input_api.os_path.relpath(file_name, devtools_root) for file_name in affected_js_files]
-
-
-def _checkWithNodeScript(input_api, output_api, script_path):
-    original_sys_path = sys.path
-    try:
-        sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts")]
-        import local_node
-    finally:
-        sys.path = original_sys_path
-
-    node_path = local_node.node_path()
-
-    process = input_api.subprocess.Popen(
-        [node_path, script_path], stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT)
-    out, _ = process.communicate()
-
-    if process.returncode != 0:
-        return [output_api.PresubmitError(out)]
-    return [output_api.PresubmitNotifyResult(out)]
diff --git a/front_end/.editorconfig b/front_end/.editorconfig
deleted file mode 100644
index c6c8b36..0000000
--- a/front_end/.editorconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
diff --git a/front_end/Images/accelerometer-back.png b/front_end/Images/accelerometer-back.png
deleted file mode 100644
index e300cb9..0000000
--- a/front_end/Images/accelerometer-back.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/accelerometer-bottom.png b/front_end/Images/accelerometer-bottom.png
deleted file mode 100644
index 0978673..0000000
--- a/front_end/Images/accelerometer-bottom.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/accelerometer-front.png b/front_end/Images/accelerometer-front.png
deleted file mode 100644
index e78de3e..0000000
--- a/front_end/Images/accelerometer-front.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/accelerometer-left.png b/front_end/Images/accelerometer-left.png
deleted file mode 100644
index acb9823..0000000
--- a/front_end/Images/accelerometer-left.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/accelerometer-right.png b/front_end/Images/accelerometer-right.png
deleted file mode 100644
index 5504e7c..0000000
--- a/front_end/Images/accelerometer-right.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/accelerometer-top.png b/front_end/Images/accelerometer-top.png
deleted file mode 100644
index f3c047f..0000000
--- a/front_end/Images/accelerometer-top.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/audits_logo.svg b/front_end/Images/audits_logo.svg
deleted file mode 100644
index bd2e7d0..0000000
--- a/front_end/Images/audits_logo.svg
+++ /dev/null
@@ -1,354 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   id="Layer_1"
-   data-name="Layer 1"
-   viewBox="0 0 750 750"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="PWA_Illustration_Lighthouse_05_Lighthouse.svg"
-   inkscape:export-filename="/Users/ericbidelman/Desktop/lh_logo_icon.png"
-   inkscape:export-xdpi="180"
-   inkscape:export-ydpi="180"
-   width="750"
-   height="750">
-  <metadata
-     id="metadata85">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title>PWA_Illustration_Lighthouse</dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1143"
-     inkscape:window-height="714"
-     id="namedview83"
-     showgrid="false"
-     borderlayer="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="50"
-     fit-margin-bottom="0"
-     inkscape:zoom="0.49370068"
-     inkscape:cx="330.80744"
-     inkscape:cy="423.36785"
-     inkscape:window-x="44"
-     inkscape:window-y="42"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="layer6" />
-  <defs
-     id="defs3">
-    <style
-       id="style5">.cls-1,.cls-10{fill:#304ffe;}.cls-2{fill:#ffe082;}.cls-10,.cls-2{opacity:0.5;}.cls-3{fill:#2979ff;}.cls-4{fill:#ffd54f;}.cls-5{fill:#fff176;}.cls-6{fill:#f4511e;}.cls-7{fill:#e64a19;}.cls-8{fill:#c5cae9;}.cls-9{fill:#ff7043;}.cls-11{fill:#fdd835;}.cls-12{fill:#fff9c4;}.cls-13{fill:#448aff;}.cls-14{fill:#00c853;}.cls-15{fill:#64dd17;}</style>
-  </defs>
-  <title
-     id="title7">PWA_Illustration_Lighthouse</title>
-  <path
-     class="cls-1"
-     d="m 92.427653,571.02434 c 52.319997,0 52.319997,-33.94 104.639997,-33.94 52.32,0 52.31,33.94 104.63,33.94 52.32,0 52.32,-33.94 104.63,-33.94 52.31,0 52.32,33.94 104.64,33.94 52.32,0 52.32,-33.94 104.64,-33.94 49.48,0 52.17,30.34 96.56,33.64 a 326.73,326.73 0 0 0 8.09,-72.39 c 0,-179.87 -145.82,-325.69 -325.69,-325.69 -179.87,0 -325.699998,145.82 -325.699998,325.69 a 326.75,326.75 0 0 0 7.9,71.51 98.88,98.88 0 0 0 15.660001,1.18 z"
-     id="path9"
-     inkscape:connector-curvature="0"
-     style="fill:#304ffe" />
-  <path
-     class="cls-3"
-     d="M 345.99765,377.16434"
-     id="path13"
-     inkscape:connector-curvature="0"
-     style="fill:#2979ff" />
-  <rect
-     class="cls-4"
-     x="362.97766"
-     y="213.56435"
-     width="84.839996"
-     height="78.489998"
-     id="rect15"
-     style="fill:#ffd54f" />
-  <rect
-     class="cls-5"
-     x="362.97766"
-     y="213.56435"
-     width="29.950001"
-     height="78.489998"
-     id="rect17"
-     style="fill:#fff176" />
-  <ellipse
-     class="cls-5"
-     cx="392.29767"
-     cy="233.21434"
-     rx="19.84"
-     ry="24.889999"
-     id="ellipse19"
-     style="fill:#fff176" />
-  <path
-     class="cls-6"
-     d="m 360.89765,204.70434 a 43.835,43.835 0 1 1 87.67,0"
-     id="path21"
-     inkscape:connector-curvature="0"
-     style="fill:#f4511e" />
-  <path
-     class="cls-7"
-     d="m 405.10765,160.87434 a 43.51,43.51 0 0 1 43.46,43.83 l -43.46,0 0,-43.83 z"
-     id="path23"
-     inkscape:connector-curvature="0"
-     style="fill:#e64a19" />
-  <rect
-     class="cls-6"
-     x="352.41766"
-     y="203.29433"
-     width="104.64"
-     height="11.31"
-     rx="5.6599998"
-     ry="5.6599998"
-     id="rect25"
-     style="fill:#f4511e" />
-  <polygon
-     class="cls-8"
-     points="393,416 405.23,173.5 490.07,173.5 501,404 501,404 "
-     id="polygon27"
-     style="fill:#c5cae9"
-     transform="translate(-42.202351,118.02434)" />
-  <line
-     class="cls-9"
-     x1="449.03766"
-     y1="310.25433"
-     x2="452.29767"
-     y2="374.42432"
-     id="line29"
-     style="fill:#ff7043" />
-  <polygon
-     class="cls-9"
-     points="402.05,233.8 398.63,301.09 494.5,256.4 491.24,192.23 491.24,192.23 "
-     id="polygon31"
-     style="fill:#ff7043"
-     transform="translate(-42.202351,118.02434)" />
-  <line
-     class="cls-9"
-     x1="455.51767"
-     y1="437.66437"
-     x2="458.78766"
-     y2="501.8443"
-     id="line33"
-     style="fill:#ff7043" />
-  <polygon
-     class="cls-9"
-     points="395.25,367.4 391.83,434.7 500.99,383.82 497.72,319.64 497.72,319.64 "
-     id="polygon35"
-     style="fill:#ff7043"
-     transform="translate(-42.202351,118.02434)" />
-  <rect
-     class="cls-7"
-     x="349.98767"
-     y="255.90434"
-     width="109.49"
-     height="35.82"
-     id="rect39"
-     style="fill:#e64a19" />
-  <rect
-     class="cls-6"
-     x="349.98767"
-     y="255.90434"
-     width="71.779999"
-     height="35.82"
-     id="rect41"
-     style="fill:#f4511e" />
-  <path
-     class="cls-2"
-     d="m 403.97765,255.90434 c 0,13 -12.1,23.5 -27,23.5 -14.9,0 -27,-10.52 -27,-23.5"
-     id="path43"
-     inkscape:connector-curvature="0"
-     style="opacity:0.5;fill:#ffe082" />
-  <g
-     inkscape:groupmode="layer"
-     id="layer1"
-     inkscape:label="clouds"
-     style="display:inline"
-     transform="translate(-111.06999,296.26999)">
-    <path
-       style="fill:#2979ff"
-       class="cls-3"
-       d="m 653.72764,-50.455653 a 19.59,19.59 0 0 1 8.32,1.84 34.49,34.49 0 0 1 66.7,-9 l 0.12,0 a 23.25,23.25 0 0 1 0,46.5 l -75.14,0 a 19.67,19.67 0 1 1 0,-39.34 z"
-       id="path71"
-       inkscape:connector-curvature="0" />
-    <path
-       style="fill:#448aff"
-       class="cls-13"
-       d="m 430.72764,137.02435 a 16.6,16.6 0 0 1 7,1.56 29.23,29.23 0 0 1 56.53,-7.63 l 0.1,0 a 19.71,19.71 0 1 1 0,39.41 l -63.63,0 a 16.67,16.67 0 1 1 0,-33.34 z"
-       id="path77"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer2"
-     inkscape:label="stars"
-     style="display:inline"
-     transform="translate(-111.06999,296.26999)">
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="593.86761"
-       cy="-88.77565"
-       r="3.53"
-       id="circle45" />
-    <circle
-       style="fill:#fff9c4"
-       class="cls-12"
-       cx="624.86761"
-       cy="109.62434"
-       r="6.1300001"
-       id="circle47" />
-    <circle
-       style="fill:#fff9c4"
-       class="cls-12"
-       cx="253.46765"
-       cy="53.594345"
-       r="6.1300001"
-       id="circle49" />
-    <circle
-       style="fill:#fff9c4"
-       class="cls-12"
-       cx="353.41763"
-       cy="160.21434"
-       r="6.1300001"
-       id="circle51" />
-    <circle
-       style="fill:#fff9c4"
-       class="cls-12"
-       cx="598.4776"
-       cy="11.644347"
-       r="6.1300001"
-       id="circle53" />
-    <circle
-       style="fill:#fff9c4"
-       class="cls-12"
-       cx="727.62762"
-       cy="169.54436"
-       r="6.1300001"
-       id="circle55" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="240.26764"
-       cy="192.40434"
-       r="3.53"
-       id="circle57" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="272.82764"
-       cy="121.09435"
-       r="3.53"
-       id="circle59" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="294.73764"
-       cy="102.71434"
-       r="3.53"
-       id="circle61" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="387.34766"
-       cy="20.004347"
-       r="3.53"
-       id="circle63" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="679.86761"
-       cy="30.224348"
-       r="3.53"
-       id="circle65" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="818.5976"
-       cy="177.65434"
-       r="3.53"
-       id="circle67" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="328.67764"
-       cy="9.3943472"
-       r="3.53"
-       id="circle69" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="640.89764"
-       cy="179.20436"
-       r="3.53"
-       id="circle73" />
-    <circle
-       style="fill:#fdd835"
-       class="cls-11"
-       cx="747.86761"
-       cy="90.754349"
-       r="3.53"
-       id="circle75" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer3"
-     inkscape:label="light"
-     style="display:inline"
-     transform="translate(-111.06999,296.26999)">
-    <path
-       style="opacity:0.5;fill:#ffe082"
-       class="cls-2"
-       d="m 475.48764,-83.895653 -334.62,-47.789997 a 3.65,3.65 0 0 0 -1,-0.14 c -8.67,0 -16,31.889997 -16,71.149997 0,39.26 7.33,71.07 16,71.07 a 3.66,3.66 0 0 0 0.93,-0.13 l 334.64,-47.88 0,-46.28 z"
-       id="path11"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer6"
-     inkscape:label="shade"
-     style="display:inline">
-    <polygon
-       class="cls-10"
-       points="493.27,173.5 450.37,173.5 450.37,393 502,416 493.27,173.5 "
-       id="polygon37"
-       style="opacity:0.5;fill:#304ffe"
-       transform="translate(-42.202351,118.02434)" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer5"
-     inkscape:label="GRASS"
-     transform="translate(-111.06999,296.26999)"
-     style="display:inline">
-    <path
-       style="fill:#00c853"
-       class="cls-14"
-       d="m 413.76764,275.48435 c 52.32,0 52.32,-33.94 104.63,-33.94 52.31,0 52.32,33.94 104.63,33.94 44.42,0 51.13,-24.46 84.16,-31.84 -45.13,-24.66 -112.53,-40.33 -187.84,-40.33 -75.63,0 -143.28,15.79 -188.41,40.64 31.93,7.73 39.02,31.53 82.83,31.53 z"
-       id="path79"
-       inkscape:connector-curvature="0" />
-    <path
-       style="fill:#64dd17"
-       class="cls-15"
-       d="m 413.86764,275.01435 c 52.32,0 52.32,-33.94 104.63,-33.94 l 1.1,0 -0.58,-37.32 c -74.89,0 -142,15.49 -187.08,39.91 31.16,7.98 38.55,31.35 81.93,31.35 z"
-       id="path81"
-       inkscape:connector-curvature="0" />
-  </g>
-</svg>
diff --git a/front_end/Images/breakpoint.png b/front_end/Images/breakpoint.png
deleted file mode 100644
index ce145b3..0000000
--- a/front_end/Images/breakpoint.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/breakpointConditional.png b/front_end/Images/breakpointConditional.png
deleted file mode 100644
index 5f7c9a3..0000000
--- a/front_end/Images/breakpointConditional.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/breakpointConditional_2x.png b/front_end/Images/breakpointConditional_2x.png
deleted file mode 100644
index 45af335..0000000
--- a/front_end/Images/breakpointConditional_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/breakpoint_2x.png b/front_end/Images/breakpoint_2x.png
deleted file mode 100644
index 10a35a5..0000000
--- a/front_end/Images/breakpoint_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/checkboxCheckmark.png b/front_end/Images/checkboxCheckmark.png
deleted file mode 100644
index a054fa9..0000000
--- a/front_end/Images/checkboxCheckmark.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/checkboxCheckmark_2x.png b/front_end/Images/checkboxCheckmark_2x.png
deleted file mode 100644
index 15641b3..0000000
--- a/front_end/Images/checkboxCheckmark_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/checker.png b/front_end/Images/checker.png
deleted file mode 100644
index 816a4ec..0000000
--- a/front_end/Images/checker.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chevrons.png b/front_end/Images/chevrons.png
deleted file mode 100644
index aea9e1b..0000000
--- a/front_end/Images/chevrons.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chevrons_2x.png b/front_end/Images/chevrons_2x.png
deleted file mode 100644
index 024ddb9..0000000
--- a/front_end/Images/chevrons_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeDisabledSelect.png b/front_end/Images/chromeDisabledSelect.png
deleted file mode 100644
index 0aa2000..0000000
--- a/front_end/Images/chromeDisabledSelect.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeDisabledSelect_2x.png b/front_end/Images/chromeDisabledSelect_2x.png
deleted file mode 100644
index 36404ed..0000000
--- a/front_end/Images/chromeDisabledSelect_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeLeft.png b/front_end/Images/chromeLeft.png
deleted file mode 100644
index 63f1feb..0000000
--- a/front_end/Images/chromeLeft.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeMiddle.png b/front_end/Images/chromeMiddle.png
deleted file mode 100644
index 6d645ec..0000000
--- a/front_end/Images/chromeMiddle.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeRight.png b/front_end/Images/chromeRight.png
deleted file mode 100644
index 30e1833..0000000
--- a/front_end/Images/chromeRight.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeSelect.png b/front_end/Images/chromeSelect.png
deleted file mode 100644
index 2af6f67..0000000
--- a/front_end/Images/chromeSelect.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/chromeSelect_2x.png b/front_end/Images/chromeSelect_2x.png
deleted file mode 100644
index 642bf46..0000000
--- a/front_end/Images/chromeSelect_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/deleteIcon.png b/front_end/Images/deleteIcon.png
deleted file mode 100644
index f0dd0db..0000000
--- a/front_end/Images/deleteIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/errorWave.png b/front_end/Images/errorWave.png
deleted file mode 100644
index 4ae395a..0000000
--- a/front_end/Images/errorWave.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/errorWave_2x.png b/front_end/Images/errorWave_2x.png
deleted file mode 100644
index c1633dc..0000000
--- a/front_end/Images/errorWave_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/ic_info_black_18dp.svg b/front_end/Images/ic_info_black_18dp.svg
deleted file mode 100644
index b953ab6..0000000
--- a/front_end/Images/ic_info_black_18dp.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 48 48" fill="#000000">
-    <path d="M0 0h48v48H0z" fill="none"/>
-    <path d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z"/>
-</svg>
diff --git a/front_end/Images/ic_warning_black_18dp.svg b/front_end/Images/ic_warning_black_18dp.svg
deleted file mode 100644
index d9b6ad4..0000000
--- a/front_end/Images/ic_warning_black_18dp.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 18 18" fill="#000000">
-    <path d="M0 0h18v18H0z" fill="none"/>
-    <path d="M.5 16h17L9 1 .5 16zm9.5-2H8v-2h2v2zm0-3H8V7h2v4z"/>
-</svg>
diff --git a/front_end/Images/largeIcons.png b/front_end/Images/largeIcons.png
deleted file mode 100644
index 5d9ea50..0000000
--- a/front_end/Images/largeIcons.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/largeIcons_2x.png b/front_end/Images/largeIcons_2x.png
deleted file mode 100644
index f6b7df7..0000000
--- a/front_end/Images/largeIcons_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/mediumIcons.png b/front_end/Images/mediumIcons.png
deleted file mode 100644
index 187f2c3..0000000
--- a/front_end/Images/mediumIcons.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/mediumIcons_2x.png b/front_end/Images/mediumIcons_2x.png
deleted file mode 100644
index 310edf2..0000000
--- a/front_end/Images/mediumIcons_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/navigationControls.png b/front_end/Images/navigationControls.png
deleted file mode 100644
index c314171..0000000
--- a/front_end/Images/navigationControls.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/navigationControls_2x.png b/front_end/Images/navigationControls_2x.png
deleted file mode 100644
index ae3f51f..0000000
--- a/front_end/Images/navigationControls_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/nodeIcon.png b/front_end/Images/nodeIcon.png
deleted file mode 100644
index a7929a9..0000000
--- a/front_end/Images/nodeIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/popoverArrows.png b/front_end/Images/popoverArrows.png
deleted file mode 100644
index b897b6e..0000000
--- a/front_end/Images/popoverArrows.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/profileGroupIcon.png b/front_end/Images/profileGroupIcon.png
deleted file mode 100644
index ff78cb4..0000000
--- a/front_end/Images/profileGroupIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/profileIcon.png b/front_end/Images/profileIcon.png
deleted file mode 100644
index c0c4600..0000000
--- a/front_end/Images/profileIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/profileSmallIcon.png b/front_end/Images/profileSmallIcon.png
deleted file mode 100644
index e5c4ad5..0000000
--- a/front_end/Images/profileSmallIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/radioDot.png b/front_end/Images/radioDot.png
deleted file mode 100644
index 5d50890..0000000
--- a/front_end/Images/radioDot.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/readme.md b/front_end/Images/readme.md
deleted file mode 100644
index 1e0503b..0000000
--- a/front_end/Images/readme.md
+++ /dev/null
@@ -1,18 +0,0 @@
-## Adding new icons
-
-1. Use Inkscape 0.92 or newer.
-1. Choose an existing spritesheet, like `largeIcons.svg` to add the icon to
-1. Open that file with Inkscape and import the new SVG into the document
-1. Place in an open spot, and use guides to scale the icon to a good size, relative to other icons
-1. Any straight lines should be snapped to the closest pixel value.
-   - Use the `Edit paths by nodes` tool (F2) to edit the path directly.
-   - Tweak the X, Y values at the top to be integers.
-1. Generate PNGs from the SVGs:
-   - `./scripts/convert_svg_images_to_png.py`
-1. Optimize PNGs:
-   - `./scripts/optimize_png_images.py`
-1. In `ui/Icon.js` add an entry in `UI.Icon.Descriptors`.
-   - Look at the spritesheet's axes to identify the correct grid position.
-1. You may want to regenerate devtools resources:
-   - `ninja -C ~/chromium/src/out/Release/ devtools_frontend_resources`
-
diff --git a/front_end/Images/resizeDiagonal.png b/front_end/Images/resizeDiagonal.png
deleted file mode 100644
index cd28ff3..0000000
--- a/front_end/Images/resizeDiagonal.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resizeDiagonal_2x.png b/front_end/Images/resizeDiagonal_2x.png
deleted file mode 100644
index dade5f3..0000000
--- a/front_end/Images/resizeDiagonal_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resizeHorizontal.png b/front_end/Images/resizeHorizontal.png
deleted file mode 100644
index a3dda7b..0000000
--- a/front_end/Images/resizeHorizontal.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resizeHorizontal_2x.png b/front_end/Images/resizeHorizontal_2x.png
deleted file mode 100644
index 3fdb98f..0000000
--- a/front_end/Images/resizeHorizontal_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resizeVertical.png b/front_end/Images/resizeVertical.png
deleted file mode 100644
index d4de02c..0000000
--- a/front_end/Images/resizeVertical.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resizeVertical_2x.png b/front_end/Images/resizeVertical_2x.png
deleted file mode 100644
index f8db81b..0000000
--- a/front_end/Images/resizeVertical_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourceCSSIcon.png b/front_end/Images/resourceCSSIcon.png
deleted file mode 100644
index 18828d0..0000000
--- a/front_end/Images/resourceCSSIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourceDocumentIcon.png b/front_end/Images/resourceDocumentIcon.png
deleted file mode 100644
index fdc10e4..0000000
--- a/front_end/Images/resourceDocumentIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourceDocumentIconSmall.png b/front_end/Images/resourceDocumentIconSmall.png
deleted file mode 100644
index 64d9735..0000000
--- a/front_end/Images/resourceDocumentIconSmall.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourceJSIcon.png b/front_end/Images/resourceJSIcon.png
deleted file mode 100644
index c1b7218..0000000
--- a/front_end/Images/resourceJSIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourcePlainIcon.png b/front_end/Images/resourcePlainIcon.png
deleted file mode 100644
index 8c82a4c..0000000
--- a/front_end/Images/resourcePlainIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourcePlainIconSmall.png b/front_end/Images/resourcePlainIconSmall.png
deleted file mode 100644
index 0349c0d..0000000
--- a/front_end/Images/resourcePlainIconSmall.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/resourcesTimeGraphIcon.png b/front_end/Images/resourcesTimeGraphIcon.png
deleted file mode 100644
index 87de550..0000000
--- a/front_end/Images/resourcesTimeGraphIcon.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/searchNext.png b/front_end/Images/searchNext.png
deleted file mode 100644
index 69e519e..0000000
--- a/front_end/Images/searchNext.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/searchPrev.png b/front_end/Images/searchPrev.png
deleted file mode 100644
index 733d40b..0000000
--- a/front_end/Images/searchPrev.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/securityIcons.png b/front_end/Images/securityIcons.png
deleted file mode 100644
index 63b3b60..0000000
--- a/front_end/Images/securityIcons.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/securityIcons_2x.png b/front_end/Images/securityIcons_2x.png
deleted file mode 100644
index 49ef2be..0000000
--- a/front_end/Images/securityIcons_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/smallIcons.png b/front_end/Images/smallIcons.png
deleted file mode 100644
index 657cb13..0000000
--- a/front_end/Images/smallIcons.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/smallIcons_2x.png b/front_end/Images/smallIcons_2x.png
deleted file mode 100644
index d505749..0000000
--- a/front_end/Images/smallIcons_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/speech.png b/front_end/Images/speech.png
deleted file mode 100644
index 5de84ab..0000000
--- a/front_end/Images/speech.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/src/breakpoint.svg b/front_end/Images/src/breakpoint.svg
deleted file mode 100644
index 4b5f707..0000000
--- a/front_end/Images/src/breakpoint.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><svg height="11" version="1.1" width="26" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-><defs
-/><sodipodi:namedview showgrid="true"
-><inkscape:grid empspacing="5" enabled="true" id="grid2985" snapvisiblegridlinesonly="true" type="xygrid" visible="true"/></sodipodi:namedview
-><path d="m22.8 0.5 2.7 5-2.7 5-22.3 0 0-10z" fill="#698cfe" stroke="#4073f4"/></svg
->
\ No newline at end of file
diff --git a/front_end/Images/src/breakpointConditional.svg b/front_end/Images/src/breakpointConditional.svg
deleted file mode 100644
index 97b9913..0000000
--- a/front_end/Images/src/breakpointConditional.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><svg height="11" version="1.1" width="26" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-><defs
-/><sodipodi:namedview showgrid="true"
-><inkscape:grid empspacing="5" enabled="true" id="grid2985" snapvisiblegridlinesonly="true" type="xygrid" visible="true"/></sodipodi:namedview
-><path d="m22.8 0.5 2.7 5-2.7 5-22.3 0 0-10z" fill="#ef9d0d" stroke="#a36c01"/></svg
->
\ No newline at end of file
diff --git a/front_end/Images/src/checkboxCheckmark.svg b/front_end/Images/src/checkboxCheckmark.svg
deleted file mode 100644
index b54a738..0000000
--- a/front_end/Images/src/checkboxCheckmark.svg
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="11"
-   height="11"
-   id="svg3283"
-   version="1.1"
-   inkscape:version="0.48.4 r9939"
-   sodipodi:docname="New document 4">
-  <defs
-     id="defs3285" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="15.839192"
-     inkscape:cx="1.4668053"
-     inkscape:cy="9.4825906"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:window-width="1280"
-     inkscape:window-height="747"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata3288">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(0,-1041.3622)">
-    <path
-       d="m 3.65,1048.5722 -1.44,-2.03 -1.21,1.21 2.55,3.61 6.45,-7.67 -1.12,-1.33 z"
-       id="path3689"
-       inkscape:connector-curvature="0" />
-  </g>
-</svg>
diff --git a/front_end/Images/src/chevrons.svg b/front_end/Images/src/chevrons.svg
deleted file mode 100644
index 59e5ae1..0000000
--- a/front_end/Images/src/chevrons.svg
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="30"
-   height="10"
-   id="svg3232"
-   version="1.1"
-   inkscape:version="0.48.4 r9939"
-   sodipodi:docname="chevrons.svg">
-  <defs
-     id="defs3234" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="2"
-     inkscape:cx="375"
-     inkscape:cy="-51.428571"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:window-width="1640"
-     inkscape:window-height="844"
-     inkscape:window-x="516"
-     inkscape:window-y="280"
-     inkscape:window-maximized="0" />
-  <metadata
-     id="metadata3237">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:groupmode="layer"
-     id="layer1">
-    <path
-       inkscape:connector-curvature="0"
-       d="M 0,2.75005 0.96529,1.78476 5.07291,5.89238 0.96529,10 0,9.03471 3.13549,5.89238 z"
-       id="path4-7" />
-    <path
-       inkscape:connector-curvature="0"
-       d="M 27.24995,2.92708 28.21524,3.89238 24.10762,8 20,3.89238 l 0.96529,-0.9653 3.14233,3.13549 z"
-       id="path4-7-5" />
-  </g>
-</svg>
diff --git a/front_end/Images/src/errorWave.svg b/front_end/Images/src/errorWave.svg
deleted file mode 100644
index 6733960..0000000
--- a/front_end/Images/src/errorWave.svg
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="6"
-   height="4"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.48.3.1 r9886"
-   inkscape:export-xdpi="97.627121"
-   inkscape:export-ydpi="97.627121"
-   sodipodi:docname="errorWave.svg">
-  <defs
-     id="defs4" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="90.509668"
-     inkscape:cx="3.4293179"
-     inkscape:cy="3.1283329"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="2154"
-     inkscape:window-height="1195"
-     inkscape:window-x="399"
-     inkscape:window-y="129"
-     inkscape:window-maximized="0">
-    <inkscape:grid
-       type="xygrid"
-       id="grid2985"
-       empspacing="5"
-       visible="true"
-       enabled="true"
-       snapvisiblegridlinesonly="true" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(0,-1048.3622)">
-    <path
-       style="fill:none;stroke:#ff0000;stroke-width:0.656;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
-       d="m -0.24596307,1048.8938 3.25701167,2.7917 3.2570116,-2.7917"
-       id="path3850"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccc" />
-  </g>
-</svg>
diff --git a/front_end/Images/src/largeIcons.svg b/front_end/Images/src/largeIcons.svg
deleted file mode 100644
index 7ddbae1..0000000
--- a/front_end/Images/src/largeIcons.svg
+++ /dev/null
@@ -1,1466 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="224"
-   height="216"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.48.4 r9939"
-   sodipodi:docname="largeIcons.svg">
-  <metadata
-     id="metadata606">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs604" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1946"
-     inkscape:window-height="1546"
-     id="namedview602"
-     showgrid="true"
-     inkscape:zoom="4.3703705"
-     inkscape:cx="90.664772"
-     inkscape:cy="118.13064"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg2"
-     inkscape:snap-grids="true"
-     showguides="true"
-     inkscape:guide-bbox="true">
-    <inkscape:grid
-       type="xygrid"
-       id="grid3583"
-       empspacing="5"
-       visible="true"
-       enabled="true"
-       snapvisiblegridlinesonly="true"
-       spacingx="28px"
-       spacingy="24px" />
-  </sodipodi:namedview>
-  <g
-     id="g4">
-    <g
-       transform="translate(-322,-72)"
-       id="g8">
-      <circle
-         transform="translate(326,74)"
-         cx="15"
-         cy="17"
-         r="3"
-         id="circle10"
-         d="m 18,17 c 0,1.656854 -1.343146,3 -3,3 -1.656854,0 -3,-1.343146 -3,-3 0,-1.656854 1.343146,-3 3,-3 1.656854,0 3,1.343146 3,3 z"
-         sodipodi:cx="15"
-         sodipodi:cy="17"
-         sodipodi:rx="3"
-         sodipodi:ry="3"
-         style="fill:#009802" />
-      <path
-         d="m 329,77 h 18 v 18 h -18 z"
-         id="path12"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-      <path
-         d="m 327.25,75.25 h 20 v 20 h -20 z"
-         id="path14"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-      <path
-         d="m 325.12,73.125 h 20 v 20 h -20 z"
-         id="path16"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-    </g>
-  </g>
-  <g
-     transform="translate(26,0)"
-     id="g18">
-    <path
-       transform="translate(-32,0)"
-       d="M 57,12 53.5,8 H 39 v 8 h 14.5"
-       id="path22"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(-2.003,24)"
-     id="g24">
-    <path
-       transform="translate(-224,-120)"
-       d="m 240.77,127 h -1.534 v 4.233 h -4.233 v 1.534 h 4.233 V 137 h 1.534 v -4.233 h 4.233 v -1.534 H 240.77 V 127 z"
-       id="path28"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(26,24)"
-     id="g30">
-    <path
-       transform="translate(-96,-145)"
-       d="m 103,148 h 18 v 18 h -18 z"
-       id="path34"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-96,-145)"
-       d="m 115.42,154.7 -6.705,-6.705 -1.0575,1.0575 1.785,1.785 -3.8625,3.8625 c -0.4425,0.4425 -0.4425,1.155 0,1.59 l 4.125,4.125 c 0.2175,0.2175 0.51,0.33 0.795,0.33 0.285,0 0.5775,-0.1125 0.795,-0.33 l 4.125,-4.125 c 0.4425,-0.435 0.4425,-1.1475 0,-1.59 z m -8.5125,0.795 3.5925,-3.5925 3.5925,3.5925 h -7.185 z m 10.342,1.125 c 0,0 -1.5,1.6275 -1.5,2.625 0,0.825 0.675,1.5 1.5,1.5 0.825,0 1.5,-0.675 1.5,-1.5 0,-0.9975 -1.5,-2.625 -1.5,-2.625 z"
-       id="path36"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-96,-145)"
-       d="m 103,163 h 18 v 3 h -18 z"
-       id="path38"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.36000001" />
-  </g>
-  <g
-     transform="translate(0,48)"
-     id="g40">
-    <path
-       transform="translate(7,3)"
-       d="M 0,0 H 18 V 18 H 0 z"
-       id="path44"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(7,3)"
-       d="m 13,5 h 1.4936 C 15.32558,5 16,5.67154 16,6.5064 v 7.9871 c 0,0.83198 -0.67154,1.5064 -1.5064,1.5064 H 6.5065 c -0.83198,0 -1.5064,-0.67154 -1.5064,-1.5064 v -1.4936 h 6.4936 c 0.8349,0 1.5064,-0.67446 1.5064,-1.5064 V 4.9999 z"
-       id="path46"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.36000001" />
-    <path
-       transform="translate(7,3)"
-       d="M 3.5,2 C 2.669,2 2,2.669 2,3.5 v 8 C 2,12.331 2.669,13 3.5,13 h 8 c 0.831,0 1.5,-0.669 1.5,-1.5 v -8 C 13,2.669 12.331,2 11.5,2 h -8 z m 0,1.5 h 8 v 8 h -8 v -8 z"
-       id="path48"
-       inkscape:connector-curvature="0"
-       style="fill:#212121" />
-  </g>
-  <g
-     transform="translate(26,48)"
-     id="g50">
-    <path
-       transform="translate(-96,-24)"
-       d="m 107,33 h 8 v 6 h -8 z"
-       stroke-miterlimit="4.2"
-       id="path54"
-       inkscape:connector-curvature="0"
-       style="stroke:#000000;stroke-width:2;stroke-miterlimit:4.19999981" />
-    <path
-       transform="translate(-96,-24)"
-       d="m 115,36 4,-4 v 8"
-       id="path56"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(54,0)"
-     id="g58">
-    <g
-       id="g62"
-       style="stroke:#000000">
-      <path
-         transform="matrix(0.36,0,0,0.36,-2.5,7.46)"
-         d="m 53,14 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
-         id="path64"
-         inkscape:connector-curvature="0"
-         style="fill-rule:evenodd;stroke-width:2.77800012" />
-      <path
-         transform="translate(-128,-120)"
-         d="m 143.48,129.5 2.5403,-2 h -1.5242 v -2 h -2 l -0.0161,2 h -1.5403 z"
-         id="path66"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="translate(-128,-120)"
-         d="m 146.5,132.5 2,2.5 v -1.4998 l 2,-1e-4 v -2.0002 l -2,1e-4 V 130 z"
-         id="path68"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="translate(-128,-120)"
-         d="m 143.5,135.5 -2.5,2 h 1.5 v 2 h 2 v -2 h 1.5 z"
-         id="path70"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="translate(-128,-120)"
-         d="m 140.5,132.5 -2,-2.5 v 1.4999 h -2 v 2.0002 l 2,-3e-4 V 135 z"
-         id="path72"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(56,24)"
-     id="g74">
-    <g
-       id="g78"
-       style="fill-rule:evenodd">
-      <path
-         transform="matrix(0.9018,0,0,0.9018,4.308,4.525)"
-         d="M 0,0 H 18 V 18 H 0 z"
-         id="path80"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-      <path
-         transform="matrix(0.9018,0,0,0.9018,4.308,4.525)"
-         d="M 4.174,8.343 2.76,9.757 7.003,13.999 15.488,5.514 14.074,4.1 7.003,11.171 z"
-         id="path82"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(57,47)"
-     id="g84">
-    <path
-       transform="translate(-68,-143)"
-       d="M 76.94,152 76,152.94 79.0533,156 76,159.06 l 0.94,0.94 4,-4 z"
-       id="path88"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-68,-143)"
-       d="M 80.94,152 80,152.94 83.0533,156 80,159.06 l 0.94,0.94 4,-4 z"
-       id="path90"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(-2,72)"
-     id="g92">
-    <path
-       transform="translate(-64,0)"
-       d="m 80.44,16.94 c -2.48,0 -4.5,-2.02 -4.5,-4.5 0,-0.88 0.26,-1.7 0.69,-2.39 l 6.2,6.2 c -0.69,0.44 -1.51,0.69 -2.39,0.69 m 4.5,-4.5 c 0,0.88 -0.26,1.7 -0.69,2.39 l -6.2,-6.2 c 0.69,-0.44 1.51,-0.69 2.39,-0.69 2.48,0 4.5,2.02 4.5,4.5 M 80.5,6 C 76.91,6 74,8.91 74,12.5 74,16.09 76.91,19 80.5,19 84.09,19 87,16.09 87,12.5 87,8.91 84.09,6 80.5,6"
-       id="path96"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(28,72)"
-     id="g98">
-    <g
-       id="g102"
-       style="fill-rule:evenodd">
-      <path
-         transform="matrix(0.87153,0,0,0.87153,4.071,4.568)"
-         d="M 0,0 H 18 V 18 H 0 z"
-         id="path104"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-      <path
-         transform="matrix(0.87153,0,0,0.87153,4.071,4.568)"
-         d="M 12,3.5 A 1.505,1.505 0 0 0 10.494,2 H 4.506 C 3.676,2 3,2.674 3,3.506 v 7.988 C 3,12.326 3.671,12.997 4.5,13 V 3.5 H 12 z M 6,6.506 C 6,5.674 6.676,5 7.506,5 h 5.988 C 14.326,5 15,5.672 15,6.506 v 7.988 C 15,15.326 14.324,16 13.494,16 H 7.506 A 1.505,1.505 0 0 1 6,14.494 V 6.506 z M 7.5,6.5 h 6 v 8 h -6 v -8 z"
-         id="path106"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(54,72)"
-     id="g108">
-    <path
-       transform="translate(0,-24)"
-       d="M 25,36 21.36,32 H 19.57 L 14,40 h 7.36 L 25,36 z"
-       id="path112"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-24)"
-       d="m 7,32 v 8 H 9.05 L 14,32 H 7 z"
-       id="path114"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-24)"
-       d="M 9.67,44.55 8.08,43.23 18.84,27.45 20.43,28.77 9.67,44.55 z"
-       id="path116"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-24)"
-       d="M 0,24 H 24 V 48 H 0 z"
-       id="path118"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(0,-24)"
-       d="M 0,24 H 24 V 48 H 0 z m 0,0 H 24 V 48 H 0 z m 0,0 H 24 V 48 H 0 z m 0,0 H 24 V 48 H 0 z"
-       id="path120"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(0,-24)"
-       d="M 0,24 H 24 V 48 H 0 z"
-       id="path122"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(0,-24)"
-       d="M 0,24 H 24 V 48 H 0 z"
-       id="path124"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(0,-24)"
-       d="M 0,24 H 24 V 48 H 0 z"
-       id="path126"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-  <g
-     transform="translate(82,0)"
-     id="g128">
-    <path
-       transform="translate(-128,0)"
-       d="M 149,8.33 147.67,7 144,10.67 140.33,7 139,8.33 142.67,12 139,15.67 140.33,17 144,13.33 147.67,17 149,15.67 145.33,12 149,8.33 z"
-       id="path132"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82,24)"
-     id="g134">
-    <path
-       transform="translate(-32,-24)"
-       d="M 53,37 H 43 v -5 h 10 v 5 z M 41,42 H 55 V 30 H 41 v 12 z"
-       id="path138"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82,48)"
-     id="g140">
-    <path
-       transform="translate(-224,-48)"
-       d="m 238,64 h 7 v -8 h -7 z m 9,2 H 233 V 54 h 14 z"
-       id="path144"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82,72)"
-     id="g146">
-    <path
-       transform="translate(-256,-48)"
-       d="m 274,64 h -7 v -8 h 7 v 8 z m -9,2 h 14 V 54 h -14 v 12 z"
-       id="path150"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(-2,96)"
-     id="g152">
-    <path
-       transform="translate(-160,0)"
-       d="m 169,16.089 v 2.9105 h 2.9105 L 180.1944,10.7156 177.2838,7.8051 169,16.089 z m 13.769,-7.9387 c 0.30785,-0.30785 0.30785,-0.79294 0,-1.1008 l -1.8191,-1.8191 c -0.30785,-0.30784 -0.79295,-0.30784 -1.1008,0 l -1.5206,1.5299 2.9105,2.9105 1.5299,-1.5206 z"
-       id="path156"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(26,96)"
-     id="g158">
-    <path
-       transform="translate(-288,-120)"
-       d="m 310.77,127.04 -1.816,-1.8164 c -0.30331,-0.30338 -0.79716,-0.30338 -1.1005,0 l -2.4304,2.4309 -1.4894,-1.4935 -1.1005,1.1007 1.1044,1.1046 -6.9373,6.9348 v 3.695 h 3.6942 l 6.9373,-6.9387 1.1005,1.1046 1.1005,-1.1007 -1.4932,-1.4935 2.4304,-2.4309 c 0.3072,-0.30338 0.3072,-0.79345 0,-1.0968 z m -10.721,10.4 -1.4932,-1.4935 6.2724,-6.2736 1.4932,1.4935 -6.2723,6.2736 z"
-       id="path162"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(54,96)"
-     id="g164">
-    <path
-       transform="translate(-32,-48)"
-       d="m 44,59 2,3 v 4 h 4 v -4 l 2,-3 z"
-       id="path168"
-       inkscape:connector-curvature="0"
-       style="opacity:0.5;fill:#424242" />
-    <path
-       transform="translate(-32,-48)"
-       d="m 46.5,65.23 c 0.32,0.13 0.84,0.24 1.47,0.24 0.59,0 1.14,-0.1 1.53,-0.26 v -3.93 l 4,-4.57 v -0.19 h -11 v 0.22 l 4,4.57 v 3.93 z M 47.97,67 C 46.81,66.91 45.82,66.71 45,66.01 V 61.89 L 41,57.32 V 55 h 14 v 2.35 l -4,4.57 v 4.13 c -0.92,0.67 -2.1,0.94 -3.03,0.95"
-       id="path170"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82.001,96)"
-     id="g172">
-    <path
-       transform="matrix(0.75,0,0,0.75,-74.421,-143.43)"
-       d="m 108.56,195.24 h 24 v 24 h -24 z"
-       id="path176"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="matrix(0.75,0,0,0.75,-74.421,-143.43)"
-       d="m 108.56,215.24 h 24 v 4 h -24 z"
-       id="path178"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.36000001" />
-    <path
-       transform="matrix(0.75,0,0,0.75,-74.421,-143.43)"
-       d="m 119.56,198.24 -5.5,14 h 2.25 l 1.12,-3 h 6.25 l 1.12,3 h 2.25 l -5.49,-14 h -2 z m -1.38,9 2.38,-6.33 2.38,6.33 h -4.76 z"
-       id="path180"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(106,1)"
-     id="g182">
-    <path
-       transform="matrix(0,-1,1,0,-112,-260)"
-       d="m -278.5,126.5 h 14 v 12 h -14 z"
-       id="path186"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="matrix(0,1,1,0,-112,-260)"
-       d="m 272,132.5 -5,-3.25 v 6.5"
-       id="path188"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(0,-1,1,0,-112,-260)"
-       d="m -275,126 h 1 v 13 h -1 z"
-       id="path190"
-       inkscape:connector-curvature="0" />
-  </g>
-  <path
-     style="fill:none;stroke:#000000"
-     inkscape:connector-curvature="0"
-     id="path196"
-     d="m 119.5,30.5 h 14 v 12 h -14 z" />
-  <path
-     inkscape:connector-curvature="0"
-     id="path198"
-     d="m 126,36.5 5,-3.25 v 6.5" />
-  <path
-     inkscape:connector-curvature="0"
-     id="path200"
-     d="m 123,30 h 1 v 13 h -1 z" />
-  <g
-     transform="translate(111,48)"
-     id="g202">
-    <path
-       transform="matrix(-1,0,0,1,-192,-120)"
-       d="m -214.5,126.5 h 14 v 12 h -14 z"
-       id="path206"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="translate(-192,-120)"
-       d="m 208,132.5 -5,-3.25 v 6.5"
-       id="path208"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(-1,0,0,1,-192,-120)"
-       d="m -211,126 h 1 v 13 h -1 z"
-       id="path210"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(106,73)"
-     id="g212">
-    <path
-       transform="matrix(0,1,1,0,-88,283)"
-       d="m -278.5,102.5 h 14 v 12 h -14 z"
-       id="path216"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="matrix(0,-1,1,0,-88,283)"
-       d="m 272,108.5 -5,-3.25 v 6.5"
-       id="path218"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(0,1,1,0,-88,283)"
-       d="m -275,102 h 1 v 13 h -1 z"
-       id="path220"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(110,96)"
-     id="g222">
-    <path
-       transform="translate(-224,0)"
-       d="m 237,11 h -4 V 7 h 4 v 4 z"
-       id="path226"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-224,0)"
-       d="m 247,9 h -9 V 7 h 9 v 2 z"
-       id="path228"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-224,0)"
-       d="m 247,11 h -9 v -1 h 9 v 1 z"
-       id="path230"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-224,0)"
-       d="m 247,15 h -9 v -2 h 9 v 2 z"
-       id="path232"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-224,0)"
-       d="m 237,17 h -4 v -4 h 4 v 4 z"
-       id="path234"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-224,0)"
-       d="m 247,17 h -9 v -1 h 9 v 1 z"
-       id="path236"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(-2,120)"
-     id="g238">
-    <path
-       transform="translate(0,-144)"
-       d="m 23,157 h -2 v 2 h 2 z"
-       id="path242"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 23,161 h -2 v 2 c 1,0 2,-1 2,-2 z"
-       id="path244"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 23,153 h -2 v 2 h 2 z"
-       id="path246"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 21,149 v 2 h 2 c 0,-1 -1,-2 -2,-2 z"
-       id="path248"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 11,163 h 4 v -6 H 9 v 4 c 0,1.1 0.9,2 2,2 z"
-       id="path250"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="M 11,153 H 9 v 2 h 2 z"
-       id="path252"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 19,149 h -2 v 2 h 2 z"
-       id="path254"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 19,161 h -2 v 2 h 2 z"
-       id="path256"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 11,149 c -1,0 -2,1 -2,2 h 2 z"
-       id="path258"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-144)"
-       d="m 15,149 h -2 v 2 h 2 z"
-       id="path260"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(26,120)"
-     id="g262">
-    <path
-       transform="translate(-290,-46)"
-       d="m 317,69 v -5 l -5,5 h 5 z"
-       id="path266"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(54,120)"
-     id="g268">
-    <g
-       id="g272"
-       style="fill-rule:evenodd">
-      <path
-         transform="matrix(1.4142,0,0,1.4142,-278.88,-36.772)"
-         d="m 209.92,31.305 a 1.0607,1.0607 0 1 1 -2.1213,0 1.0607,1.0607 0 1 1 2.1213,0 z"
-         id="path274"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="matrix(1.4142,0,0,1.4142,-278.88,-31.772)"
-         d="m 209.92,31.305 a 1.0607,1.0607 0 1 1 -2.1213,0 1.0607,1.0607 0 1 1 2.1213,0 z"
-         id="path276"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="matrix(1.4142,0,0,1.4142,-278.88,-26.772)"
-         d="m 209.92,31.305 a 1.0607,1.0607 0 1 1 -2.1213,0 1.0607,1.0607 0 1 1 2.1213,0 z"
-         id="path278"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(84,120)"
-     id="g280">
-    <path
-       transform="translate(-162,-144)"
-       d="m 166,147 h 18 v 18 h -18 z"
-       id="path284"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-162,-144)"
-       d="m 181.52,154.53 c -0.51,-2.58 -2.7862,-4.5262 -5.5162,-4.5262 -2.1675,0 -4.0462,1.23 -4.9875,3.0262 -2.2538,0.24375 -4.0125,2.1525 -4.0125,4.4738 0,2.4862 2.0138,4.5 4.5,4.5 h 9.75 c 2.07,0 3.75,-1.68 3.75,-3.75 0,-1.98 -1.5412,-3.585 -3.4838,-3.7238 z m -0.26625,5.9738 h -9.75 c -1.6575,0 -3,-1.3425 -3,-3 0,-1.6575 1.3425,-3 3,-3 h 0.5325 c 0.49125,-1.7288 2.0775,-3 3.9675,-3 2.28,0 4.125,1.845 4.125,4.125 v 0.375 h 1.125 c 1.2412,0 2.25,1.0088 2.25,2.25 0,1.2412 -1.0088,2.25 -2.25,2.25 z"
-       id="path286"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(112,120)"
-     id="g288">
-    <path
-       transform="translate(-226,-72)"
-       d="m 235,76 c -0.55,0 -0.99,0.45 -0.99,1 L 234,91 c 0,0.55 0.44,1 1,1 h 10 c 0.55,0 1,-0.45 1,-1 V 81 l -5,-5 h -6 z m 6,5 v -4 l 4,4 h -4 z"
-       id="path292"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-226,-72)"
-       d="m 231,75 h 18 v 18 h -18 z"
-       id="path294"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-  <g
-     transform="translate(140,0)"
-     id="g296">
-    <path
-       transform="translate(-162,-24)"
-       d="m 169,29 h 18 v 18 h -18 z"
-       id="path300"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-162,-24)"
-       d="m 167.25,27.25 h 20 v 20 h -20 z"
-       id="path302"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-162,-24)"
-       d="m 165.12,25.125 h 20 v 20 h -20 z"
-       id="path304"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-162,-24)"
-       d="m 171,28 c -0.55,0 -1,0.45 -1,1 v 14 c 0,0.55 0.44,1 1,1 h 5.0938 c -0.0656,-0.32311 -0.0937,-0.65753 -0.0937,-1 0,-2.7614 2.2386,-5 5,-5 0.34247,0 0.67689,0.02816 1,0.09375 v -5.0938 l -5,-5 h -6 z m 6,1 4,4 h -4 v -4 z"
-       id="path306"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(140,24)"
-     id="g308">
-    <path
-       transform="translate(-66,-120)"
-       d="m 71,124 h 18 v 18 H 71 z"
-       id="path312"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-66,-120)"
-       d="m 82,129 -2,-2 h -5 c -0.55,0 -1,0.45 -1,1 v 10 c 0,0.55 0.45,1 1,1 h 12 c 0.55,0 1,-0.45 1,-1 v -8 c 0,-0.55 -0.45,-1 -1,-1 h -5 z"
-       id="path314"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(140,48)"
-     id="g316">
-    <path
-       transform="translate(-258,-144)"
-       d="m 278,150 h -10.5 c -0.8325,0 -1.5,0.675 -1.5,1.5 v 9 c 0,0.825 0.6675,1.5 1.5,1.5 H 278 c 0.825,0 1.5,-0.675 1.5,-1.5 v -9 c 0,-0.825 -0.6675,-1.5 -1.5,-1.5 z m 0,10.5 H 267.5 V 153 H 278 v 7.5 z"
-       id="path320"
-       inkscape:connector-curvature="0"
-       style="fill:#010101" />
-    <path
-       transform="translate(-258,-144)"
-       d="m 262.97,147.07 h 18 v 18 h -18 z"
-       id="path322"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-  <g
-     transform="translate(140,72)"
-     id="g324">
-    <path
-       transform="translate(6,3.9)"
-       d="M 9,1 H 3.9954 C 3.45567,1 3,1.45078 3,2.0068 v 11.986 c 0,0.5569 0.44565,1.0068 0.9954,1.0068 h 8.0092 C 12.54433,14.9996 13,14.54882 13,13.9928 V 4.9996 l -4,-4 z m 3,4 H 9 V 2 l 3,3 z M 6,7 11,9.5 6,12 V 7 z"
-       id="path328"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(140,96)"
-     id="g330">
-    <g
-       id="g334"
-       style="stroke:#000000">
-      <path
-         transform="matrix(0.72907,0,0,0.72907,5.617,4.598)"
-         d="M 7.854,6.963 6.877,7.279 6.857,8.617 6.889,8.705 7.398,9.699 6.188,10.578 5.398,9.787 5.326,9.73 4.047,9.336 3.443,10.166 4.213,11.26 4.291,11.313 5.287,11.817 4.824,13.241 3.72,13.065 3.628,13.061 2.362,13.493 v 1.027 l 1.266,0.434 0.092,-0.004 1.104,-0.178 0.463,1.424 -0.996,0.506 -0.078,0.051 -0.77,1.094 0.604,0.83 1.279,-0.393 0.072,-0.059 0.789,-0.791 1.211,0.879 -0.51,0.996 -0.031,0.086 0.02,1.338 0.977,0.316 0.803,-1.068 0.025,-0.09 0.172,-1.104 h 1.498 l 0.172,1.104 0.025,0.09 0.803,1.068 0.977,-0.316 0.02,-1.338 -0.031,-0.086 -0.51,-0.996 1.211,-0.879 0.789,0.791 0.072,0.059 1.279,0.393 0.604,-0.83 -0.771,-1.094 -0.076,-0.051 -0.996,-0.506 0.461,-1.424 1.105,0.178 0.092,0.004 1.266,-0.434 v -1.027 l -1.266,-0.432 -0.092,0.004 -1.105,0.176 -0.461,-1.424 0.996,-0.504 0.076,-0.053 0.771,-1.094 L 15.159,9.336 13.88,9.731 13.808,9.788 13.019,10.579 11.808,9.7 12.318,8.706 12.349,8.618 12.329,7.28 11.352,6.964 10.549,8.034 10.524,8.122 10.352,9.227 H 8.854 L 8.682,8.121 8.656,8.03 7.854,6.963 m 1.748,3.398 a 3.621,3.645 0 0 1 3.621,3.645 3.621,3.645 0 0 1 -3.621,3.646 3.621,3.645 0 0 1 -3.619,-3.646 3.621,3.645 0 0 1 3.619,-3.645 z"
-         id="path336"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="matrix(0.72907,0,0,0.72907,5.227,3.617)"
-         d="M 14.885,1.563 14.178,1.957 14.365,3.24 14.396,3.279 15.14,4.04 14.553,5.03 13.529,4.736 13.479,4.729 12.262,5.172 12.25,5.98 13.455,6.459 13.506,6.453 14.537,6.189 15.1,7.191 14.332,7.932 14.301,7.971 14.08,9.248 14.771,9.662 15.787,8.859 15.807,8.811 16.1,7.787 17.242,7.803 17.502,8.834 17.52,8.883 18.514,9.715 19.219,9.32 19.03,8.04 19,7.998 18.258,7.234 18.844,6.25 19.869,6.541 19.92,6.551 21.14,6.105 21.15,5.297 19.943,4.818 19.893,4.824 18.861,5.088 18.301,4.086 19.07,3.346 19.1,3.307 19.322,2.029 18.627,1.615 17.609,2.418 17.59,2.467 17.303,3.49 16.16,3.475 15.896,2.443 15.879,2.395 14.885,1.563 z m 1.814,2.138 a 1.938,1.938 0 0 1 1.938,1.938 1.938,1.938 0 0 1 -1.938,1.937 1.938,1.938 0 0 1 -1.937,-1.937 1.938,1.938 0 0 1 1.937,-1.938 z"
-         id="path338"
-         inkscape:connector-curvature="0"
-         style="stroke-width:0.89899999" />
-    </g>
-  </g>
-  <g
-     transform="translate(138,120)"
-     id="g340">
-    <g
-       id="g344"
-       style="fill:none">
-      <path
-         transform="translate(8,4)"
-         d="M 0,0 H 16 V 16 H 0 V 0 z"
-         id="path346"
-         inkscape:connector-curvature="0"
-         style="opacity:0.5" />
-      <path
-         transform="translate(8,4)"
-         d="M 6,14 H 3.5 C 2.5,14 2,13.5 2,12.5 v -9 C 2,2.5 2.5,2 3.5,2 h 9 C 14,2 14,3.4678 14,3.5 V 6 H 13 V 3 H 3 v 10 h 3 v 1 z m 9,-5 -3,2 3,3 -1,1 -3,-3 -2,3 -2,-8 8,2 z"
-         id="path348"
-         inkscape:connector-curvature="0"
-         style="fill:#000000" />
-    </g>
-  </g>
-  <g
-     transform="translate(0,144)"
-     id="g350">
-    <path
-       transform="translate(-98,-120)"
-       d="m 110.5,127.5 h -1 l 2,-2 2,2 h -1 c 0,0 -0.0345,4.6379 -0.0345,4.0345 l 4.0345,-0.034 v -1 l 2,2 -2,2 v -1 l -4.0345,-0.034 0.0345,4.0346 h 1 l -2,2 -2,-2 h 1 l 0.0345,-4.0346 -4.0345,0.034 v 1 l -2,-2 2,-2 v 1 l 4.0345,0.034 z"
-       id="path354"
-       inkscape:connector-curvature="0"
-       style="stroke:#000000" />
-  </g>
-  <g
-     transform="translate(26,144)"
-     id="g356">
-    <path
-       transform="translate(-320,0)"
-       d="m 333.6,15.2 h 1.6 V 8.8 h -1.6 v 6.4 z M 336,4 c -4.42,0 -8,3.58 -8,8 0,4.42 3.58,8 8,8 4.42,0 8,-3.58 8,-8 0,-4.42 -3.58,-8 -8,-8 z m 0,14.4 c -3.528,0 -6.4,-2.872 -6.4,-6.4 0,-3.528 2.872,-6.4 6.4,-6.4 3.528,0 6.4,2.872 6.4,6.4 0,3.528 -2.872,6.4 -6.4,6.4 z m 0.8,-3.2 h 1.6 V 8.8 h -1.6 v 6.4 z"
-       id="path360"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(54,144)"
-     id="g362">
-    <path
-       transform="translate(-32,-72)"
-       d="m 47,88 h -3 v -8 h 3 v 8 z"
-       id="path366"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-32,-72)"
-       d="m 53,88 h -3 v -8 h 3 v 8 z"
-       id="path368"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82,144)"
-     id="g370">
-    <path
-       transform="translate(-256,0)"
-       d="m 275,15 h -2 V 9 h 2 z m -4,0 h -2 V 9 h 2 z m 4,-10 h -6 l -4,4 v 6 l 4,4 h 6 l 4,-4.12 V 9 z"
-       id="path374"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(110,144)"
-     id="g376">
-    <g
-       font-weight="400"
-       id="g380"
-       style="font-weight:400;font-family:Sans">
-      <path
-         transform="translate(-289,-96)"
-         d="m 300,101 v 4.0001 1.0001 l 3.3434,0.53115 -0.0156,8.0468 -1.3278,0.42183 c 0.006,0.59278 0.43931,1.0114 1,1 h 8 c 0.57896,0.002 0.98177,-0.42708 1,-1 v -14 c -0.0102,-0.53477 -0.48177,-0.99739 -1,-1 h -10 c -0.53297,0.008 -0.99716,0.45677 -1,1 z m 1,0 h 10 v 14 h -8 l 0.71845,-0.42179 0.0937,-8.4218 -2.8122,-0.1561 v -0.99993 z"
-         overflow="visible"
-         style="text-indent:0;line-height:normal;text-transform:none;block-progression:tb;overflow:visible"
-         id="path382"
-         inkscape:connector-curvature="0" />
-      <path
-         transform="translate(-289,-96)"
-         d="m 297,106 v 9 c 0.006,0.59278 0.43931,1.0114 1,1 h 5 c 0.57896,0.002 0.98177,-0.42708 1,-1 v -9 c -0.0102,-0.53477 -0.48177,-0.99739 -1,-1 h -5 c -0.53297,0.008 -0.99716,0.45677 -1,1 z m 1,1.0002 h 5 v 7 h -5 z"
-         overflow="visible"
-         style="text-indent:0;line-height:normal;text-transform:none;block-progression:tb;overflow:visible"
-         id="path384"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(138,144)"
-     id="g386">
-    <path
-       transform="translate(-320,-48)"
-       d="m 328,60 c 0,4.42 3.58,8 8,8 4.42,0 8,-3.58 8,-8 0,-4.42 -3.58,-8 -8,-8 -4.42,0 -8,3.58 -8,8 z m 8,6.4 c -3.528,0 -6.4,-2.872 -6.4,-6.4 0,-3.528 2.872,-6.4 6.4,-6.4 3.528,0 6.4,2.872 6.4,6.4 0,3.528 -2.872,6.4 -6.4,6.4 z M 334.5067,63.4286 339.0781,60 334.5067,56.5714 v 6.8571 z"
-       id="path390"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(-2,168)"
-     id="g392">
-    <path
-       transform="translate(-96,-48)"
-       d="m 108,60 10,-5 v 10"
-       id="path396"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(26,168)"
-     id="g398">
-    <path
-       transform="translate(-64,-48)"
-       d="M 86,60 76,55 v 10"
-       id="path402"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(54,168)"
-     id="g404">
-    <path
-       transform="translate(-256,-24)"
-       d="m 268.01,35.99 c 0.61,0.28 1.07,0.9 1.07,1.58 0.11,0.85 -0.05,1.72 0.12,2.57 0.27,0.54 1,0.28 1.43,0.55 0.49,0.24 0.48,1.01 -0.06,1.18 -0.56,0.22 -1.18,0.08 -1.74,-0.05 -0.71,-0.2 -1.41,-0.72 -1.5,-1.5 -0.18,-0.89 0.01,-1.8 -0.16,-2.68 -0.22,-0.64 -0.94,-0.9 -1.57,-0.93 -0.58,-0.1 -0.83,-0.94 -0.35,-1.3 0.51,-0.35 1.26,-0.14 1.69,-0.66 0.44,-0.48 0.29,-1.18 0.32,-1.78 0,-0.81 -0.02,-1.77 0.65,-2.34 0.66,-0.54 1.58,-0.71 2.41,-0.63 0.63,0 0.98,0.87 0.4,1.22 -0.44,0.37 -1.2,0.06 -1.51,0.65 -0.14,0.56 -0.05,1.15 -0.07,1.73 -0.01,0.75 -0.05,1.64 -0.72,2.13 -0.12,0.1 -0.26,0.19 -0.4,0.26"
-       id="path408"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-256,-24)"
-       d="m 276.98,35.99 c -0.67,-0.3 -1.08,-1.02 -1.08,-1.75 -0.07,-0.76 0.03,-1.52 -0.06,-2.28 -0.24,-0.58 -0.98,-0.4 -1.46,-0.59 -0.59,-0.24 -0.48,-1.18 0.14,-1.31 0.73,-0.15 1.52,-0.01 2.18,0.32 0.56,0.28 0.95,0.86 0.99,1.48 0.13,0.83 -0.03,1.68 0.13,2.5 0.2,0.68 0.94,0.83 1.54,0.9 0.56,0.07 0.86,0.8 0.46,1.21 -0.44,0.46 -1.2,0.2 -1.65,0.66 -0.51,0.46 -0.4,1.21 -0.4,1.83 -0.03,0.78 0.06,1.69 -0.52,2.3 -0.74,0.65 -1.8,0.86 -2.75,0.68 -0.52,-0.16 -0.69,-1.01 -0.15,-1.25 0.44,-0.23 1.02,-0.08 1.41,-0.45 0.26,-0.45 0.09,-0.98 0.14,-1.47 0.01,-0.76 -0.07,-1.63 0.43,-2.26 0.18,-0.21 0.42,-0.37 0.66,-0.51"
-       id="path410"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82,168)"
-     id="g412">
-    <g
-       id="g416">
-      <path
-         d="M 0,0 H 24 V 24 H 0 z"
-         id="path418"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-      <path
-         d="m 16,6 c -3.31,0 -6,2.69 -6,6 0,3.31 2.69,6 6,6 3.31,0 6,-2.69 6,-6 h -2 c 0,2.2091 -1.7909,4 -4,4 -2.2091,0 -4,-1.7909 -4,-4 0,-2.2091 1.7909,-4 4,-4 1.2756,0 2.3926,0.60127 3.125,1.5312 h 2.3438 C 20.52659,7.4496 18.4308,6 16,6 z"
-         id="path420"
-         inkscape:connector-curvature="0" />
-      <path
-         d="M 21.091,6.88 V 9.9718 H 17.9992 z"
-         id="path422"
-         inkscape:connector-curvature="0"
-         style="stroke:#000000;stroke-width:1.06799996" />
-    </g>
-  </g>
-  <g
-     transform="translate(110,168)"
-     id="g424">
-    <path
-       transform="translate(8,4)"
-       d="M 2.5858,13.891 C 0.9959,12.4291 0,10.3315 0,8.0002 c 0,-4.42 3.58,-8 8,-8 4.42,0 8,3.58 8,8 0,4.42 -3.58,8 -8,8 v -1.6 c 3.528,0 6.4,-2.872 6.4,-6.4 0,-3.528 -2.872,-6.4 -6.4,-6.4 -3.528,0 -6.4,2.872 -6.4,6.4 0,1.9357 0.86461,3.674 2.2278,4.8487 l 1.6925,-1.4201 0.015145,4.463 -4.3925,-0.7899 1.443,-1.2108 z M 6.5066,11.4287 11.078,8.0001 6.5066,4.5715 v 6.8571 z"
-       id="path428"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(138,168)"
-     id="g430">
-    <path
-       transform="translate(0,-72)"
-       d="M 23,84 15,79 V 89"
-       id="path434"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-72)"
-       d="M 13,89 H 10 V 79 h 3 v 10 z"
-       id="path436"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(166,0)"
-     id="g438">
-    <path
-       transform="translate(-160,-120)"
-       d="m 169.2,130.15 c 0.0551,-0.1128 0.15339,-0.22 0.2313,-0.3064 0.54584,-0.6074 1.3889,-1.1974 3.0053,-1.5702 v -2.1715 c -1.2931,0.2523 -2.3146,0.6686 -3.304,1.5597 -0.33248,0.3832 -0.50543,0.6247 -0.514,1.1665 -0.007,0.443 0.17732,0.8863 0.58141,1.3219 z m 6.6309,3.1292 c -1.6164,-0.024 -3.1091,-0.2558 -4.6228,-0.764 -2.6938,-0.9037 -3.0286,-2.1697 -3.1703,-2.5931 -0.0958,1.6897 0.028,2.9573 0.0346,3.0648 0.092,1.5004 1.2918,2.6742 2.1575,3.1151 1.7796,0.9067 3.6614,1.3756 5.601,1.4151 v 2.4842 l 3.251,-4.6483 -3.251,-4.6486 v 2.5748 z m -0.32327,-5.2959 c 1.6164,0.01 3.4529,0.3384 5.2454,1.1131 0.73528,0.3177 1.3275,0.7904 1.8082,1.3048 0.33152,-0.1523 0.80672,-0.7308 0.74126,-1.2923 -0.16163,-1.3879 -1.6264,-2.1912 -1.8801,-2.3045 -1.7704,-0.7908 -3.9751,-1.0356 -5.9147,-1.0589 v -1.7442 l -2.0132,2.8787 2.0132,2.8783 v -1.775 z m 8.4236,1.8658 c -0.0824,0.6478 -0.82676,2.0349 -3.8978,2.9138 v 4.5247 c 1.1314,-0.3677 2.465,-1.2956 3.1787,-2.1988 0.2911,-0.3677 0.46906,-0.875 0.57736,-1.242 0.33216,-1.1229 0.18604,-3.3136 0.14175,-3.9977 z"
-       id="path442"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(166,24)"
-     id="g444">
-    <path
-       transform="translate(8,4)"
-       d="m 10.624,2.47 c 1.9155,0.90417 3.2862,2.7533 3.4971,4.9467 h 0.87866 C 14.70102,3.8234 11.68426,1 7.99976,1 L 7.61315,1.0175 9.84495,3.24 10.62403,2.47 z M 6.9629,2.02083 c -0.34561,-0.34417 -0.90209,-0.34417 -1.2418,0 l -3.7255,3.71 c -0.34561,0.34417 -0.34561,0.89833 0,1.2367 l 7.041,7.0117 c 0.34561,0.34417 0.90209,0.34417 1.2418,0 l 3.7255,-3.71 c 0.34561,-0.34417 0.34561,-0.89833 0,-1.2367 l -7.041,-7.0117 z m 2.6946,11.34 -7.041,-7.0117 3.7255,-3.71 7.041,7.0117 -3.7255,3.71 z M 5.3755,13.53 C 3.46,12.63167 2.0893,10.7767 1.8784,8.5833 H 0.99974 C 1.29848,12.1766 4.31524,15 7.99974,15 L 8.38635,14.9825 6.15455,12.76 5.37547,13.53 z"
-       id="path448"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(166,48)"
-     id="g450">
-    <path
-       transform="translate(-288,-72)"
-       d="m 293.96,74.013 h 20 v 20 h -20 z"
-       id="path454"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-288,-72)"
-       d="m 297,77 h 18 v 18 h -18 z"
-       id="path456"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-288,-72)"
-       d="m 295.25,75.25 h 20 v 20 h -20 z"
-       id="path458"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-288,-72)"
-       d="m 293.12,73.125 h 20 v 20 h -20 z"
-       id="path460"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-288,-72)"
-       d="m 288,72 h 24 v 24 h -24 z"
-       id="path462"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-288,-72)"
-       d="m 309.35,84.686 c 0.0288,-0.224 0.0504,-0.448 0.0504,-0.686 0,-0.238 -0.0216,-0.462 -0.0504,-0.686 l 1.5184,-1.155 c 0.13673,-0.105 0.17272,-0.294 0.0863,-0.448 l -1.4393,-2.422 c -0.0863,-0.154 -0.28065,-0.21 -0.43897,-0.154 l -1.7919,0.7 c -0.37422,-0.28 -0.77722,-0.511 -1.2162,-0.686 l -0.27341,-1.855 C 305.77334,77.126 305.62223,77 305.44232,77 h -2.8785 c -0.17992,0 -0.33104,0.126 -0.35263,0.294 l -0.27346,1.855 c -0.43898,0.175 -0.84198,0.413 -1.2162,0.686 l -1.7919,-0.7 c -0.16551,-0.063 -0.35262,0 -0.43898,0.154 l -1.4393,2.422 c -0.0935,0.154 -0.0504,0.343 0.0863,0.448 l 1.5184,1.155 c -0.0287,0.224 -0.0504,0.455 -0.0504,0.686 0,0.231 0.0216,0.462 0.0504,0.686 l -1.5184,1.155 c -0.13673,0.105 -0.17271,0.294 -0.0863,0.448 l 1.4393,2.422 c 0.0863,0.154 0.28067,0.21 0.43898,0.154 l 1.7919,-0.7 c 0.37421,0.28 0.77721,0.511 1.2162,0.686 l 0.27346,1.855 c 0.0216,0.168 0.17271,0.294 0.35263,0.294 h 2.8785 c 0.17991,0 0.33103,-0.126 0.35263,-0.294 l 0.27345,-1.855 c 0.43898,-0.175 0.84198,-0.413 1.2162,-0.686 l 1.7919,0.7 c 0.16552,0.063 0.35263,0 0.43898,-0.154 l 1.4393,-2.422 c 0.0863,-0.154 0.0504,-0.343 -0.0863,-0.448 l -1.5184,-1.155 z m -5.3469,1.764 c -1.3889,0 -2.5187,-1.099 -2.5187,-2.45 0,-1.351 1.1298,-2.45 2.5187,-2.45 1.3889,0 2.5187,1.099 2.5187,2.45 0,1.351 -1.1298,2.45 -2.5187,2.45 z"
-       id="path464"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(162,73)"
-     id="g466">
-    <path
-       transform="matrix(0,-1,1,0,-136,251)"
-       d="m 232.5,150.5 h 14 v 12 h -14 z"
-       id="path470"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="matrix(0,-1,1,0,-136,251)"
-       d="m 244,156.5 -5,-3.25 v 6.5"
-       id="path472"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(0,-1,1,0,-136,251)"
-       d="m 236,150 h 1 v 13 h -1 z"
-       id="path474"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(166,96)"
-     id="g476">
-    <path
-       transform="translate(-160,-72)"
-       d="m 168.5,78.5 h 14 v 12 h -14 z"
-       id="path480"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="translate(-160,-72)"
-       d="m 180,84.5 -5,-3.25 v 6.5"
-       id="path482"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-160,-72)"
-       d="m 172,78 h 1 v 13 h -1 z"
-       id="path484"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(166,120)"
-     id="g486">
-    <path
-       transform="matrix(-1,0,0,1,-192,-96)"
-       d="m -214.5,102.5 h 14 v 12 h -14 z"
-       id="path490"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="translate(-192,-96)"
-       d="m 203,108.5 5,-3.25 v 6.5"
-       id="path492"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(-1,0,0,1,-192,-96)"
-       d="m -211,102 h 1 v 13 h -1 z"
-       id="path494"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(162,145)"
-     id="g496">
-    <path
-       transform="matrix(0,1,1,0,-88,219)"
-       d="m -214.5,102.5 h 14 v 12 h -14 z"
-       id="path500"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000" />
-    <path
-       transform="matrix(0,-1,1,0,-88,219)"
-       d="m 203,108.5 5,-3.25 v 6.5"
-       id="path502"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(0,1,1,0,-88,219)"
-       d="m -211,102 h 1 v 13 h -1 z"
-       id="path504"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(166,168)"
-     id="g506">
-    <path
-       transform="translate(-288,0)"
-       d="m 298,12 c 0,3.31 2.69,6 6,6 3.31,0 6,-2.69 6,-6 0,-3.31 -2.69,-6 -6,-6 -3.31,0 -6,2.69 -6,6"
-       id="path510"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(-2,192)"
-     id="g512">
-    <path
-       transform="translate(-64,-72)"
-       d="m 78.5,89 c 0,1.1 0.9,2 2,2 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 -1.1,0 -2,0.9 -2,2"
-       id="path516"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-64,-72)"
-       d="m 79,78 v 4 h -3 l 4.5,4 4.5,-4 h -3 v -4 h -3 z"
-       id="path518"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(26,192)"
-     id="g520">
-    <path
-       transform="translate(-96,-72)"
-       d="m 110.5,89 c 0,1.1 0.9,2 2,2 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 -1.1,0 -2,0.9 -2,2"
-       id="path524"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-96,-72)"
-       d="m 112.5,78 -4.5,4 h 3 v 4 h 3 v -4 h 3 l -4.5,-4 z"
-       id="path526"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(54,192)"
-     id="g528">
-    <path
-       transform="translate(-128,-72)"
-       d="m 142,86.5 c 0,1.1 0.9,2 2,2 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 -1.1,0 -2,0.9 -2,2"
-       id="path532"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-128,-72)"
-       d="m 137.25,87.03 c 2.55,-8.43 11.4,-8.73 13.94,0"
-       id="path534"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#000000;stroke-width:2.5" />
-    <path
-       transform="translate(-128,-72)"
-       d="m 151.68,89 -4.54,-2.76 6.68,-2.1"
-       id="path536"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(82,192)"
-     id="g538">
-    <path
-       transform="translate(-288,-24)"
-       d="m 295,36 c 0,4.97 4.03,9 9,9 4.97,0 9,-4.03 9,-9 0,-4.97 -4.03,-9 -9,-9 -4.97,0 -9,4.03 -9,9"
-       id="path542"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite60_a)" />
-    <path
-       transform="translate(-288,-24)"
-       d="m 298,36 c 0,3.31 2.69,6 6,6 3.31,0 6,-2.69 6,-6 0,-3.31 -2.69,-6 -6,-6 -3.31,0 -6,2.69 -6,6"
-       id="path544"
-       inkscape:connector-curvature="0" />
-    <defs
-       id="defs546">
-      <radialGradient
-         id="sprite60_b"
-         cx="0"
-         cy="0"
-         r="1"
-         gradientTransform="matrix(18,0,0,-18,680,341)"
-         gradientUnits="userSpaceOnUse">
-        <stop
-           offset="0"
-           id="stop549" />
-        <stop
-           stop-opacity="0"
-           offset="1"
-           id="stop551" />
-      </radialGradient>
-      <radialGradient
-         id="sprite60_a"
-         cx="0"
-         cy="0"
-         r="1"
-         gradientTransform="matrix(9,0,0,9,304,36)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite60_b" />
-    </defs>
-  </g>
-  <g
-     transform="translate(110,192)"
-     id="g554">
-    <g
-       id="g558">
-      <path
-         transform="translate(7,3)"
-         d="M 0,0 H 18 V 18 H 0 z"
-         id="path560"
-         inkscape:connector-curvature="0"
-         style="fill:none" />
-      <path
-         transform="translate(7,3)"
-         d="M 15.25,8 H 16 V 6.125 5 H 5 V 6.125 8 h 0.75 c 0,-0.82843 0.67157,-1.5 1.5,-1.5 h 2.5 v 7.25 c 0,0.82843 -0.67157,1.5 -1.5,1.5 V 16 h 1.875 0.75 1.875 v -0.75 c -0.82843,0 -1.5,-0.67157 -1.5,-1.5 V 6.5 h 2.5 c 0.82843,0 1.5,0.67157 1.5,1.5 z"
-         id="path562"
-         inkscape:connector-curvature="0"
-         style="fill-opacity:0.36000001" />
-      <path
-         transform="translate(7,3)"
-         d="M 12.25,5 H 13 V 3.125 2 H 2 V 3.125 5 h 0.75 c 0,-0.82843 0.67157,-1.5 1.5,-1.5 h 2.5 v 7.25 c 0,0.82843 -0.67157,1.5 -1.5,1.5 V 13 h 1.875 0.75 1.875 v -0.75 c -0.82843,0 -1.5,-0.67157 -1.5,-1.5 V 3.5 h 2.5 c 0.82843,0 1.5,0.67157 1.5,1.5 z"
-         id="path564"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(138,192)"
-     id="g566">
-    <path
-       transform="translate(-128,-24)"
-       d="m 139.5,33 h 9 L 147,43 h -6"
-       id="path570"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-128,-24)"
-       d="m 147.5,30 h -2 v -1 h -3 v 1 h -2 c -0.55,0 -1,0.48 -1,1 v 1 h 1 7 1 v -1 c 0,-0.52 -0.45,-1 -1,-1"
-       id="path572"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(168,192)"
-     id="g574">
-    <path
-       transform="translate(0,-48)"
-       d="M 10,57 H 8 v 9 h 11 v -2 h -9 z"
-       id="path578"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(0,-48)"
-       d="m 13,56 h 7 v 5 h -7 z m -2,-2 v 9 h 11 v -9 z"
-       id="path580"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(194,0)"
-     id="g582">
-    <path
-       transform="translate(-96,0)"
-       d="m 112,6.6909 c -3.6364,0 -6.7418,2.2618 -8,5.4545 1.2582,3.1927 4.3636,5.4545 8,5.4545 3.6364,0 6.7418,-2.2618 8,-5.4545 -1.2582,-3.1927 -4.3636,-5.4545 -8,-5.4545 z m 0,9.0909 c -2.0073,0 -3.6364,-1.6291 -3.6364,-3.6364 0,-2.0073 1.6291,-3.6364 3.6364,-3.6364 2.0073,0 3.6364,1.6291 3.6364,3.6364 0,2.0073 -1.6291,3.6364 -3.6364,3.6364 z m 0,-5.8182 c -1.2073,0 -2.1818,0.97455 -2.1818,2.1818 0,1.2073 0.97455,2.1818 2.1818,2.1818 1.2073,0 2.1818,-0.97455 2.1818,-2.1818 0,-1.2073 -0.97455,-2.1818 -2.1818,-2.1818 z"
-       id="path586"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(194,24)"
-     id="g588">
-    <path
-       transform="translate(-128,-48)"
-       d="m 153,57 h -11 v -2 h 11 v 2 z"
-       id="path592"
-       inkscape:connector-curvature="0"
-       style="opacity:0.2" />
-    <path
-       transform="translate(-128,-48)"
-       d="m 142,57 h -6 v -2 h 6 v 2 z"
-       id="path594"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-128,-48)"
-       d="m 145,60 h -6 v -2 h 6 v 2 z"
-       id="path596"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-128,-48)"
-       d="m 150,63 h -6 v -2 h 6 v 2 z"
-       id="path598"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="translate(-128,-48)"
-       d="m 152,66 h -6 v -2 h 6 v 2 z"
-       id="path600"
-       inkscape:connector-curvature="0" />
-  </g>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="12.355932"
-     y="231.55931"
-     id="text4355"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357"
-       x="12.355932"
-       y="231.55931">a</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="40.355934"
-     y="231.55931"
-     id="text4355-3"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-6"
-       x="40.355934"
-       y="231.55931">b</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="68.355934"
-     y="231.55931"
-     id="text4355-7"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-5"
-       x="68.355934"
-       y="231.55931">c</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="96.355934"
-     y="231.55931"
-     id="text4355-35"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-62"
-       x="96.355934"
-       y="231.55931">d</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="124.35593"
-     y="231.55931"
-     id="text4355-9"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-1"
-       x="124.35593"
-       y="231.55931">e</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="152.35593"
-     y="231.55931"
-     id="text4355-2"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-7"
-       x="152.35593"
-       y="231.55931">f</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="180.35593"
-     y="231.55931"
-     id="text4355-0"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-9"
-       x="180.35593"
-       y="231.55931">g</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="208.35593"
-     y="231.55931"
-     id="text4355-36"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-0"
-       x="208.35593"
-       y="231.55931">h</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="207.55931"
-     id="text4355-6"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-2"
-       x="-15.644068"
-       y="207.55931">1</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="183.55931"
-     id="text4355-61"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-8"
-       x="-15.644068"
-       y="183.55931">2</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="159.55931"
-     id="text4355-79"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-20"
-       x="-15.644068"
-       y="159.55931">3</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="135.55931"
-     id="text4355-23"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-75"
-       x="-15.644068"
-       y="135.55931">4</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="111.55931"
-     id="text4355-92"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-28"
-       x="-15.644068"
-       y="111.55931">5</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="87.559311"
-     id="text4355-97"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-3"
-       x="-15.644068"
-       y="87.559311">6</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="63.559311"
-     id="text4355-612"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-93"
-       x="-15.644068"
-       y="63.559311">7</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="39.559311"
-     id="text4355-1"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-94"
-       x="-15.644068"
-       y="39.559311">8</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-15.644068"
-     y="15.559311"
-     id="text4355-78"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-4"
-       x="-15.644068"
-       y="15.559311">9</tspan></text>
-  <g
-     id="Page-1-6"
-     style="fill:none;stroke:none"
-     transform="translate(200,50)">
-    <g
-       id="undo">
-      <rect
-         height="20"
-         width="20"
-         y="0"
-         x="0"
-         id="bounds"
-         style="fill:#ffffff;fill-opacity:0" />
-      <path
-         id="shape"
-         d="M 4.3431457,9.3431458 C 5.790861,7.8954305 7.790861,7 10,7 c 3.555275,0 6.568879,2.3191676 7.610506,5.527197 L 16.155367,13 15.658589,13 C 14.834916,10.669615 12.612438,9 10,9 8.3431458,9 6.8431457,9.6715729 5.7573593,10.757359 L 8,13 2,13 2,7 l 2.3431457,2.3431458 0,0 z"
-         inkscape:connector-curvature="0"
-         style="fill:#000000" />
-    </g>
-  </g>
-  <path
-     style="fill:#000000"
-     sodipodi:nodetypes="ccccccccccccc"
-     inkscape:connector-curvature="0"
-     d="m 215,82 -3,0 0,-4 -4,0 0,4 -3,0 5,6 z m -10,7 0,1 10,0 0,-1 z"
-     id="path4295" />
-  <path
-     style="fill:none"
-     inkscape:connector-curvature="0"
-     d="m 196,72 h 24 v 24 h -24 z"
-     id="path4297" />
-  <path
-     style="fill:#000000"
-     d="m 210,102 -5,6 3,0 0,4 4,0 0,-4 3,0 z m -5,11 0,1 10,0 0,-1 z"
-     id="path4295-3"
-     inkscape:connector-curvature="0"
-     sodipodi:nodetypes="ccccccccccccc" />
-  <g
-     transform="matrix(0,-1,1,0,196.13559,219.83898)"
-     id="g512-3">
-    <path
-       d="m 15,8 v 6.487608 h -3 l 4.5,6.487607 4.5,-6.487607 H 18 V 8 h -3 z"
-       id="path518-7"
-       inkscape:connector-curvature="0" />
-  </g>
-  <rect
-     style="fill:#000000;"
-     id="square-icon"
-     width="8"
-     height="8"
-     x="206"
-     y="176" />
-  <g
-     style="fill:#000000"
-     id="g4456"
-     transform="matrix(0.78548728,0,0,0.78548728,200.6822,123.63151)">
-    <path
-       id="path4442"
-       d="M 15.5,14 H 14.71 L 14.43,13.73 C 15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3 5.91,3 3,5.91 3,9.5 3,13.09 5.91,16 9.5,16 c 1.61,0 3.09,-0.59 4.23,-1.57 L 14,14.71 v 0.79 l 5,4.99 1.49,-1.49 z m -6,0 C 7.01,14 5,11.99 5,9.5 5,7.01 7.01,5 9.5,5 11.99,5 14,7.01 14,9.5 14,11.99 11.99,14 9.5,14 Z"
-       inkscape:connector-curvature="0" />
-    <path
-       id="path4444"
-       d="M 0,0 H 24 V 24 H 0 Z"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-</svg>
diff --git a/front_end/Images/src/mediumIcons.svg b/front_end/Images/src/mediumIcons.svg
deleted file mode 100644
index 861d177..0000000
--- a/front_end/Images/src/mediumIcons.svg
+++ /dev/null
@@ -1,764 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="80"
-   height="80"
-   id="svg4775"
-   version="1.1"
-   inkscape:version="0.48.4 r9939"
-   sodipodi:docname="mediumIcons.svg"
-   inkscape:export-filename="/Users/pfeldman/code/chromium/src/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons.png"
-   inkscape:export-xdpi="90"
-   inkscape:export-ydpi="90">
-  <metadata
-     id="metadata4917">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs4915">
-    <linearGradient
-       id="sprite6_b-6">
-      <stop
-         id="stop4236-2"
-         offset="0"
-         stop-color="#d7687d" />
-      <stop
-         id="stop4238-6"
-         offset="1"
-         stop-color="#b21402" />
-    </linearGradient>
-    <linearGradient
-       xlink:href="#sprite6_b-6"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)"
-       x2="24"
-       id="sprite6_a-0" />
-    <linearGradient
-       id="sprite9_d-9">
-      <stop
-         id="stop4292-1"
-         offset="0"
-         stop-color="#606eda" />
-      <stop
-         id="stop4294-2"
-         offset="1"
-         stop-color="#021db2" />
-    </linearGradient>
-    <linearGradient
-       xlink:href="#sprite9_d-9"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)"
-       y2="104"
-       y1="104"
-       x2="127"
-       x1="113"
-       id="sprite9_a-2" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#sprite6_b-6"
-       id="linearGradient5055"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)"
-       x2="24" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#sprite9_d-9"
-       id="linearGradient5057"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)"
-       x1="113"
-       y1="104"
-       x2="127"
-       y2="104" />
-  </defs>
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1278"
-     inkscape:window-height="746"
-     id="namedview4913"
-     showgrid="true"
-     inkscape:zoom="5.2149126"
-     inkscape:cx="-5.9228807"
-     inkscape:cy="72.509528"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg4775">
-    <inkscape:grid
-       type="xygrid"
-       id="grid4919"
-       empspacing="5"
-       visible="true"
-       enabled="true"
-       snapvisiblegridlinesonly="true"
-       spacingx="16px"
-       spacingy="16px" />
-  </sodipodi:namedview>
-  <g
-     id="g4777"
-     transform="translate(0,16)">
-    <path
-       d="m 3,4 h 10 v 9.008 C 13,14.1082 12.11257,15 11.0004,15 H 4.9996 C 3.8952,15 3,14.09982 3,13.008 V 4 z M 2,2 H 14 V 3 H 2 V 2 z M 5,1 h 6 V 2 H 5 V 1 z"
-       id="path4781"
-       inkscape:connector-curvature="0"
-       style="fill:#212121" />
-  </g>
-  <g
-     transform="translate(16,16)"
-     id="g4783">
-    <path
-       d="M 13.526,6.25 H 12.0523 V 5.5 c 0,-0.414 -0.33011,-0.75 -0.73684,-0.75 H 9.84176 V 4 c 0,-0.414 -0.33011,-0.75 -0.73684,-0.75 H 8.36808 V 1.75 C 8.36808,1.423 8.16029,1.153 7.87366,1.0495 7.81987,1.021 7.74913,1 7.63124,1 c -3.6628,0 -6.6316,3.0218 -6.6316,6.75 0,3.7275 2.9687,6.75 6.6316,6.75 3.6629,0 6.6316,-3.0225 6.6316,-6.75 V 7 c 0,-0.414 -0.3301,-0.75 -0.73684,-0.75 z M 3.5786,8.5 C 2.96784,8.5 2.4733,7.99667 2.4733,7.375 2.4733,6.75333 2.9678,6.25 3.5786,6.25 4.1894,6.25 4.6839,6.75333 4.6839,7.375 4.6839,7.99667 4.1894,8.5 3.5786,8.5 z M 4.6839,4.375 c 0,-0.62175 0.49516,-1.125 1.1053,-1.125 0.61084,0 1.1053,0.50325 1.1053,1.125 C 6.8945,4.996 6.40008,5.5 5.7892,5.5 5.17909,5.5 4.6839,4.996 4.6839,4.375 z M 6.8944,13 c -0.61059,0 -1.1053,-0.50334 -1.1053,-1.1246 0,-0.62129 0.49467,-1.1254 1.1053,-1.1254 0.61063,0 1.1053,0.50409 1.1053,1.1254 C 7.9997,12.49668 7.50503,13 6.8944,13 z M 7.26282,9.25 C 6.65271,9.25 6.15752,8.746 6.15752,8.125 6.15752,7.504 6.65268,7 7.26282,7 c 0.61014,0 1.1053,0.504 1.1053,1.125 0,0.621 -0.49516,1.125 -1.1053,1.125 z m 3.6842,1.5 c -0.6101,0 -1.1053,-0.504 -1.1053,-1.125 0,-0.621 0.49516,-1.125 1.1053,-1.125 0.61011,0 1.1053,0.504 1.1053,1.125 0,0.621 -0.49516,1.125 -1.1053,1.125 z"
-       id="path4787"
-       inkscape:connector-curvature="0"
-       style="fill:#212121" />
-  </g>
-  <g
-     transform="translate(32,16)"
-     id="g4789">
-    <path
-       d="M 8,6 C 11.3137,6 14,5.10457 14,4 14,2.89543 11.3137,2 8,2 4.6863,2 2,2.89543 2,4 2,5.10457 4.6863,6 8,6 z m -6,7 c 0,1.1046 2.6863,2 6,2 3.3137,0 6,-0.89543 6,-2 v -2 c 0,1.1046 -2.6863,2 -6,2 -3.3137,0 -6,-0.89543 -6,-2 v 2 z m 0,-3 c 0,1.1046 2.6863,2 6,2 3.3137,0 6,-0.89543 6,-2 V 8 C 14,9.1046 11.3137,10 8,10 4.6863,10 2,9.10457 2,8 v 2 z M 2,7 c 0,1.1046 2.6863,2 6,2 3.3137,0 6,-0.89543 6,-2 V 5 C 14,6.1046 11.3137,7 8,7 4.6863,7 2,6.10457 2,5 v 2 z"
-       id="path4793"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(48,16)"
-     id="g4795">
-    <g
-       id="g4799">
-      <g
-         id="g4801"
-         style="fill:none">
-        <path
-           d="M 0,0 H 16 V 16 H 0 z"
-           id="path4803"
-           inkscape:connector-curvature="0" />
-        <path
-           transform="translate(3,1)"
-           d="M 6,0 H 0.9954 C 0.45567,0 0,0.45078 0,1.0068 v 11.986 c 0,0.5569 0.44565,1.0068 0.9954,1.0068 H 9.0046 C 9.54433,13.9996 10,13.54882 10,12.9928 V 3.9996 l -4,-4 z M 9.29,4 H 6 V 0.71 L 9.29,4 z"
-           id="path4805"
-           inkscape:connector-curvature="0"
-           style="fill:#000000" />
-      </g>
-    </g>
-  </g>
-  <g
-     transform="translate(0,32)"
-     id="g4807">
-    <path
-       d="M 6.5,3.2289 V 1 h 3 v 2.2289 c 0.70763,0.22225 1.3475,0.59759 1.8807,1.0872 l 1.9315,-1.1151 1.5,2.5981 -1.9305,1.1146 c 0.07749,0.34976 0.11835,0.71329 0.11835,1.0864 0,0.37311 -0.04086,0.73661 -0.11835,1.0864 l 1.9305,1.1146 -1.5,2.5981 -1.9315,-1.1151 C 10.84746,12.17371 10.2076,12.54904 9.5,12.7713 v 2.2289 h -3 V 12.7713 C 5.79237,12.54905 5.1525,12.17371 4.6193,11.6841 l -1.9315,1.1151 -1.5,-2.5981 1.9305,-1.1146 C 3.04081,8.73674 2.99995,8.37321 2.99995,8.0001 2.99995,7.62699 3.04081,7.26349 3.1183,6.9137 L 1.1878,5.7991 2.6878,3.201 4.6193,4.3161 C 5.15253,3.82649 5.7924,3.45116 6.5,3.2289 z M 8,10.5 C 9.3807,10.5 10.5,9.3807 10.5,8 10.5,6.6193 9.3807,5.5 8,5.5 6.6193,5.5 5.5,6.6193 5.5,8 c 0,1.3807 1.1193,2.5 2.5,2.5 z"
-       id="path4811"
-       inkscape:connector-curvature="0"
-       style="fill:#212121" />
-  </g>
-  <g
-     transform="translate(16,32)"
-     id="g4813">
-    <path
-       d="M 2,3.999 C 2,3.44729 2.45098,3.00004 2.99078,3.00004 h 5.0092 v 3 h -6 v -2.001 z M 2,11 h 6 v 3 H 2.9908 C 2.44361,14 2.00002,13.55734 2.00002,13.00104 v -2.001 z M 2,7 h 6 v 3 H 2 V 7 z M 9,3 h 5.0092 c 0.54719,0 0.99078,0.44266 0.99078,0.99896 v 2.001 h -6 v -3 z m 0,8 h 6 v 2.001 c 0,0.55171 -0.45098,0.99896 -0.99078,0.99896 h -5.0092 v -3 z M 9,7 h 6 v 3 H 9 V 7 z"
-       id="path4817"
-       inkscape:connector-curvature="0"
-       style="fill:#212121" />
-  </g>
-  <g
-     transform="translate(34,34)"
-     id="g4819">
-    <path
-       transform="matrix(1.1,0,0,1.1,-3.3,-3.3)"
-       d="m 8,13 c 2.7614,0 5,-2.2386 5,-5 C 13,5.2386 10.7614,3 8,3 5.2386,3 3,5.2386 3,8 c 0,2.7614 2.2386,5 5,5 z M 8,11 V 9 H 5 V 7 H 8 V 5 l 3,3 -3,3 z"
-       id="path4823"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(50,33)"
-     id="g4825">
-    <g
-       transform="translate(-76,-24)"
-       id="g4829">
-      <circle
-         transform="matrix(1.2,0,0,1.2,72.4,21.2)"
-         cx="10.5"
-         cy="11.5"
-         r="2.5"
-         id="circle4831"
-         d="M 13,11.5 C 13,12.880712 11.880712,14 10.5,14 9.1192881,14 8,12.880712 8,11.5 8,10.119288 9.1192881,9 10.5,9 11.880712,9 13,10.119288 13,11.5 z"
-         sodipodi:cx="10.5"
-         sodipodi:cy="11.5"
-         sodipodi:rx="2.5"
-         sodipodi:ry="2.5"
-         style="fill:#009802" />
-      <path
-         d="m 78,25 c -0.54399,0 -1,0.45026 -1,1 v 8 c 0,0.53973 0.44936,1 1,1 h 3.0312 c -0.02335,-0.1633 -0.03125,-0.33024 -0.03125,-0.5 0,-0.16976 0.0079,-0.3367 0.03125,-0.5 H 78 v -8 h 3 v 3 h 3 v 1.5 c 0.1633,-0.02335 0.33024,0 0.5,0 0.16976,0 0.3367,-0.02335 0.5,0 V 28 l -3,-3 z m 4,1 2,2 h -2 z"
-         id="path4833"
-         inkscape:connector-curvature="0" />
-    </g>
-  </g>
-  <g
-     transform="translate(2,49)"
-     id="g4835">
-    <path
-       transform="translate(-65.625,-24.5)"
-       d="m 71.625,25.5 h -4.003 c -0.54399,0 -0.99703,0.44566 -0.99703,0.9954 v 8.0092 c 0,0.53973 0.44639,0.9954 0.99703,0.9954 h 6.0059 c 0.54399,0 0.99703,-0.44566 0.99703,-0.9954 V 28.5 l -3,-3 z m 0,1 2,2 h -2 v -2 z m -4,0 h 3 v 3 h 3 v 5 h -6 v -8 z"
-       id="path4839"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(17,49)"
-     id="g4841">
-    <path
-       transform="translate(-160,-96)"
-       d="m 160,102.5 c 0,3.59 2.91,6.5 6.5,6.5 3.59,0 6.5,-2.91 6.5,-6.5 0,-3.59 -2.91,-6.5 -6.5,-6.5 -3.59,0 -6.5,2.91 -6.5,6.5"
-       id="path4845"
-       inkscape:connector-curvature="0"
-       style="fill:#9f9f9f" />
-    <path
-       transform="translate(-160,-96)"
-       d="m 170,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4847"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.36000001" />
-    <path
-       transform="translate(-160,-96)"
-       d="M 170,99.93 169.07,99 166.5,101.57 163.93,99 163,99.93 l 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4849"
-       inkscape:connector-curvature="0"
-       style="fill:#ffffff" />
-  </g>
-  <g
-     transform="translate(33,49)"
-     id="g4851">
-    <path
-       transform="translate(-143,-96)"
-       d="m 143,102.5 c 0,3.59 2.91,6.5 6.5,6.5 3.59,0 6.5,-2.91 6.5,-6.5 0,-3.59 -2.91,-6.5 -6.5,-6.5 -3.59,0 -6.5,2.91 -6.5,6.5"
-       id="path4855"
-       inkscape:connector-curvature="0"
-       style="fill:#bebebe" />
-    <path
-       transform="translate(-143,-96)"
-       d="m 153,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4857"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.37000002" />
-    <path
-       transform="translate(-143,-96)"
-       d="M 153,99.93 152.07,99 149.5,101.57 146.93,99 146,99.93 l 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4859"
-       inkscape:connector-curvature="0"
-       style="fill:#ffffff" />
-  </g>
-  <g
-     transform="translate(49,49)"
-     id="g4861">
-    <path
-       transform="translate(-111,-96)"
-       d="m 118,96 c -3.87,0 -7,3.13 -7,7 0,3.87 3.13,7 7,7 3.87,0 7,-3.13 7,-7 0,-3.87 -3.13,-7 -7,-7"
-       id="path4865"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite12_a)" />
-    <path
-       transform="translate(-111,-96)"
-       d="m 111.5,103 c 0,3.59 2.91,6.5 6.5,6.5 3.59,0 6.5,-2.91 6.5,-6.5 0,-3.59 -2.91,-6.5 -6.5,-6.5 -3.59,0 -6.5,2.91 -6.5,6.5"
-       id="path4867"
-       inkscape:connector-curvature="0"
-       style="fill:#f27d82" />
-    <path
-       transform="translate(-111,-96)"
-       d="m 121.5,100.93 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4869"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.36000001" />
-    <path
-       transform="translate(-111,-96)"
-       d="m 121.5,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4871"
-       inkscape:connector-curvature="0"
-       style="fill:#ffffff" />
-    <defs
-       id="defs4873">
-      <linearGradient
-         id="sprite12_r">
-        <stop
-           stop-color="#d7687d"
-           offset="0"
-           id="stop4876" />
-        <stop
-           stop-color="#b21402"
-           offset="1"
-           id="stop4878" />
-      </linearGradient>
-      <linearGradient
-         id="sprite12_a"
-         x2="24"
-         gradientTransform="matrix(0,-0.58333,-0.58333,0,118,110)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite12_r" />
-    </defs>
-  </g>
-  <g
-     transform="translate(1,65)"
-     id="g4881">
-    <path
-       transform="translate(-96,-96)"
-       d="m 103,110 c 3.87,0 7,-3.13 7,-7 0,-3.87 -3.13,-7 -7,-7 -3.87,0 -7,3.13 -7,7 0,3.87 3.13,7 7,7"
-       id="path4885"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite13_a)" />
-    <path
-       transform="translate(-96,-96)"
-       d="m 103,96.5 c -3.59,0 -6.5,2.91 -6.5,6.5 0,3.59 2.91,6.5 6.5,6.5 3.59,0 6.5,-2.91 6.5,-6.5 0,-3.59 -2.91,-6.5 -6.5,-6.5"
-       id="path4887"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite13_b)" />
-    <path
-       transform="translate(-96,-96)"
-       d="m 106.5,100.93 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4889"
-       inkscape:connector-curvature="0"
-       style="fill:#993c35" />
-    <path
-       transform="translate(-96,-96)"
-       d="m 106.5,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4891"
-       inkscape:connector-curvature="0"
-       style="fill:#ffffff" />
-    <defs
-       id="defs4893">
-      <linearGradient
-         id="sprite13_b"
-         x1="96.5"
-         x2="109.5"
-         y1="103"
-         y2="103"
-         gradientTransform="matrix(0,1,-1,0,206,0)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite13_q" />
-      <linearGradient
-         id="sprite13_q">
-        <stop
-           stop-color="#e59290"
-           offset="0"
-           id="stop4897" />
-        <stop
-           stop-color="#e99890"
-           offset="1"
-           id="stop4899" />
-      </linearGradient>
-      <linearGradient
-         id="sprite13_a"
-         x1="113"
-         x2="127"
-         y1="104"
-         y2="104"
-         gradientTransform="matrix(0,1,-1,0,207,-17)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite13_r" />
-      <linearGradient
-         id="sprite13_r">
-        <stop
-           stop-color="#c0544f"
-           offset="0"
-           id="stop4903" />
-        <stop
-           stop-color="#d08481"
-           offset="1"
-           id="stop4905" />
-      </linearGradient>
-    </defs>
-  </g>
-  <g
-     transform="translate(18,66)"
-     id="g4907">
-    <path
-       transform="translate(-234,-30)"
-       d="m 242.27,38.92 c -0.75073,0.56132 -1.6826,0.89372 -2.6921,0.89372 -2.4853,0 -4.5,-2.0147 -4.5,-4.5 0,-2.4853 2.0147,-4.5 4.5,-4.5 2.4853,0 4.5,2.0147 4.5,4.5 0,1.1154 -0.40579,2.136 -1.0778,2.9222 l 2.3456,2.3456 -0.70711,0.70711 z m -2.6921,-0.10628 c 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 z"
-       id="path4911"
-       inkscape:connector-curvature="0"
-       style="fill:#5b5b5b" />
-  </g>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-11.403088"
-     y="75.207672"
-     id="text4355"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357"
-       x="-11.403088"
-       y="75.207672">1</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-11.144299"
-     y="59.675297"
-     id="text4355-8"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-8"
-       x="-11.144299"
-       y="59.675297">2</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-11.066174"
-     y="44.142918"
-     id="text4355-4"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-3"
-       x="-11.066174"
-       y="44.142918">3</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="-11.266369"
-     y="28.610538"
-     id="text4355-1"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-4"
-       x="-11.266369"
-       y="28.610538">4</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="5.9353299"
-     y="92.082359"
-     id="text4355-9"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-2"
-       x="5.9353299"
-       y="92.082359">a</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="21.659466"
-     y="92.082359"
-     id="text4355-0"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-6"
-       x="21.659466"
-       y="92.082359">b</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="37.383606"
-     y="92.082359"
-     id="text4355-89"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-26"
-       x="37.383606"
-       y="92.082359">c</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#b3b3b3;fill-opacity:1;stroke:none;font-family:Sans"
-     x="53.107742"
-     y="92.082359"
-     id="text4355-6"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan4357-49"
-       x="53.107742"
-       y="92.082359">d</tspan></text>
-  <g
-     style="fill:none;stroke:none"
-     id="g6346"
-     transform="translate(32,64)">
-    <polygon
-       points="0,0 16,0 16,16 0,16 "
-       id="polygon6348" />
-    <path
-       style="fill:#000000"
-       inkscape:connector-curvature="0"
-       id="path6350"
-       d="M 8,1 C 4.136,1 1,4.136 1,8 c 0,3.864 3.136,7 7,7 3.864,0 7,-3.136 7,-7 C 15,4.136 11.864,1 8,1 L 8,1 z M 2.5,8 C 2.5,4.968125 4.968125,2.5 8,2.5 c 3.031875,0 5.5,2.468125 5.5,5.5 0,3.031875 -2.468125,5.5 -5.5,5.5 C 4.968125,13.5 2.5,11.031875 2.5,8 z M 9,12 9,7 7,7 7,12 9,12 z M 7,6 9,6 9,4 7,4 7,6 7,6 z" />
-  </g>
-  <g
-     id="g4443-7"
-     transform="matrix(1.3997356,0,0,1.3934295,65.053843,65.020556)"
-     mask="url(#path4453-6-mask)">
-    <path
-       transform="translate(-60,0)"
-       d="m 61,9 4,-8 4,8 z"
-       id="path4447-5"
-       inkscape:connector-curvature="0"
-       style="stroke:#c19600;stroke-width:2;stroke-linejoin:round" />
-    <path
-       transform="translate(-60,0)"
-       d="m 61,9 4,-8 4,8 z"
-       id="path4449-3"
-       inkscape:connector-curvature="0"
-       style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round" />
-    <path
-       transform="translate(-60,0)"
-       d="m 63.75,2.75 h 2.5 v 2.5 L 65.75,7 h -1.5 l -0.5,-1.75 v -2.5 m 0,5.25 h 2.5 v 1.25 h -2.5"
-       id="path4451-5"
-       inkscape:connector-curvature="0"
-       style="fill:#ad8601" />
-    <mask
-       id="path4453-6-mask">
-      <path
-         transform="translate(-60,0)"
-         d="m 64,3 h 2 V 5.25 L 65.5,7 h -1 L 64,5.25 V 3 m 0,5 h 2 v 1 h -2"
-         id="path4453-6"
-         inkscape:connector-curvature="0"
-         style="fill:#000000" />
-      <rect
-         width="10"
-         height="10"
-         style="fill:#ffffff"
-         id="rect8990"
-         x="0"
-         y="0" />
-    </mask>
-  </g>
-  <g
-     id="g4279-7"
-     transform="matrix(1.36,0,0,1.34,65.3,49.5)"
-     mask="url(#path4287-3-mask)">
-    <path
-       transform="translate(-80,0)"
-       d="m 85,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 90,2.2399995 87.76,-4.7795e-7 85,-4.7795e-7"
-       id="path4283-0"
-       inkscape:connector-curvature="0"
-       style="fill:url(#linearGradient5057)" />
-    <path
-       transform="translate(-80,0)"
-       d="m 80.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64"
-       id="path4285-9"
-       inkscape:connector-curvature="0"
-       style="fill:#2a53cd" />
-    <mask
-       id="path4287-3-mask">
-      <path
-         transform="translate(-80,0)"
-         d="m 83.93,2.14 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 C 84.09,2.71 83.93,2.43 83.93,2.14 z m 1.7,5.46 H 86.3 V 8.13 H 83.41 V 7.6 h 0.66 V 3.99 H 83.41 V 3.46 h 2.22 V 7.6 z"
-         id="path4287-3"
-         inkscape:connector-curvature="0"
-         style="fill:#000000" />
-      <rect
-         width="10"
-         height="10"
-         style="fill:#ffffff"
-         id="rect8997"
-         x="0"
-         y="0" />
-    </mask>
-    <defs
-       id="defs4289-6">
-      <linearGradient
-         id="linearGradient3198">
-        <stop
-           stop-color="#606eda"
-           offset="0"
-           id="stop3200" />
-        <stop
-           stop-color="#021db2"
-           offset="1"
-           id="stop3202" />
-      </linearGradient>
-      <linearGradient
-         id="linearGradient3204"
-         x1="113"
-         x2="127"
-         y1="104"
-         y2="104"
-         gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite9_d-9" />
-    </defs>
-  </g>
-  <g
-     id="g4221-1"
-     transform="matrix(1.37,0,0,1.36,65.2,33.3)"
-     mask="url(#path4229-9-path4231-2-mask)">
-    <path
-       transform="translate(-20,0)"
-       d="m 25,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 30,2.2399995 27.76,-4.7795e-7 25,-4.7795e-7"
-       id="path4225-8"
-       inkscape:connector-curvature="0"
-       style="fill:url(#linearGradient5055)" />
-    <path
-       transform="translate(-20,0)"
-       d="m 20.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64"
-       id="path4227-7"
-       inkscape:connector-curvature="0"
-       style="fill:#eb3941" />
-    <mask
-       id="path4229-9-path4231-2-mask">
-      <path
-         transform="translate(-20,0)"
-         d="m 23,3 4,4"
-         id="path4229-9"
-         inkscape:connector-curvature="0"
-         style="stroke:#000000" />
-      <path
-         transform="translate(-20,0)"
-         d="M 27,3 23,7"
-         id="path4231-2"
-         inkscape:connector-curvature="0"
-         style="stroke:#000000" />
-      <rect
-         width="10"
-         height="10"
-         style="fill:#ffffff"
-         id="rect9010"
-         x="0"
-         y="0" />
-    </mask>
-    <defs
-       id="defs4233-0">
-      <linearGradient
-         id="linearGradient3257">
-        <stop
-           stop-color="#d7687d"
-           offset="0"
-           id="stop3259" />
-        <stop
-           stop-color="#b21402"
-           offset="1"
-           id="stop3261" />
-      </linearGradient>
-      <linearGradient
-         id="linearGradient3263"
-         x2="24"
-         gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite6_b-6" />
-    </defs>
-  </g>
-  <g
-     style="fill:#000000"
-     id="g9271"
-     transform="matrix(0.66666667,0,0,0.66666667,64,16)">
-    <path
-       id="path9261"
-       d="M 12,2 C 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22 17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 z m 0,3 c 1.66,0 3,1.34 3,3 0,1.66 -1.34,3 -3,3 C 10.34,11 9,9.66 9,8 9,6.34 10.34,5 12,5 z m 0,14.2 c -2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22 z"
-       inkscape:connector-curvature="0" />
-    <path
-       id="path9263"
-       d="M 0,0 H 24 V 24 H 0 z"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.37333333;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
-     x="-10.738436"
-     y="12.11775"
-     id="text5090"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan5092"
-       x="-10.738436"
-       y="12.11775">5</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.35111114;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
-     x="68.649277"
-     y="91.69722"
-     id="text5862"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan5864"
-       x="68.649277"
-       y="91.69722">e</tspan></text>
-  <g
-     style="fill:#000000"
-     id="g5994"
-     transform="matrix(0.75,0,0,0.75,63,-1)">
-    <path
-       id="path5984"
-       d="M 3,13 H 5 V 11 H 3 v 2 z m 0,4 H 5 V 15 H 3 v 2 z M 3,9 H 5 V 7 H 3 v 2 z m 4,4 H 21 V 11 H 7 v 2 z m 0,4 H 21 V 15 H 7 v 2 z M 7,7 V 9 H 21 V 7 H 7 z"
-       inkscape:connector-curvature="0" />
-    <path
-       id="path5986"
-       d="M 0,0 H 24 V 24 H 0 z"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-  <g
-     style="fill:#000000"
-     id="g6079"
-     transform="matrix(0.75,0,0,0.75,47,63)">
-    <path
-       id="path6069"
-       d="M 0,0 H 24 V 24 H 0 z"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       id="path6071"
-       d="M 20,8 H 17.19 C 16.74,7.22 16.12,6.55 15.37,6.04 L 17,4.41 15.59,3 13.42,5.17 C 12.96,5.06 12.49,5 12,5 11.51,5 11.04,5.06 10.59,5.17 L 8.41,3 7,4.41 8.62,6.04 C 7.88,6.55 7.26,7.22 6.81,8 H 4 v 2 H 6.09 C 6.04,10.33 6,10.66 6,11 v 1 H 4 v 2 h 2 v 1 c 0,0.34 0.04,0.67 0.09,1 H 4 v 2 h 2.81 c 1.04,1.79 2.97,3 5.19,3 2.22,0 4.15,-1.21 5.19,-3 H 20 V 16 H 17.91 C 17.96,15.67 18,15.34 18,15 v -1 h 2 v -2 h -2 v -1 c 0,-0.34 -0.04,-0.67 -0.09,-1 H 20 V 8 z m -6,8 h -4 v -2 h 4 v 2 z m 0,-4 h -4 v -2 h 4 v 2 z"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     style="fill:none;stroke:none"
-     id="g6340"
-     transform="translate(48,0)">
-    <rect
-       style="opacity:0.2"
-       height="16"
-       width="16"
-       y="0"
-       x="0"
-       id="rect6342" />
-    <path
-       style="fill:#000000"
-       inkscape:connector-curvature="0"
-       id="path6344"
-       d="m 0.5,14 15,0 L 8,1 0.5,14 l 0,0 z m 8.5,-2 -2,0 0,-2 2,0 0,2 0,0 z M 9,9 7,9 7,6 9,6 9,9 9,9 z" />
-  </g>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
-     x="32.469646"
-     y="7.902472"
-     id="text3111"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan3113"
-       x="32.469646"
-       y="7.902472"
-       style="font-size:10px;font-weight:bold">A</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
-     x="40.362782"
-     y="15.525424"
-     id="text3115"
-     sodipodi:linespacing="125%"><tspan
-       sodipodi:role="line"
-       id="tspan3117"
-       x="40.362782"
-       y="15.525424"
-       style="font-size:10px;font-weight:bold">B</tspan></text>
-  <path
-     d="m 37.955041,13.088794 c -1.914609,-0.291809 -2.119489,-0.899233 -2.237,-4.129445 l -1.219783,0 c 0.04662,3.855641 0.06137,5.297137 5.735435,5.257508 l 0.316769,-0.01434 -2.595652,-2.995518 c -0.01446,0.611794 -0.01486,1.270551 2.31e-4,1.881795 z"
-     id="path448"
-     inkscape:connector-curvature="0"
-     sodipodi:nodetypes="ccccccc" />
-</svg>
diff --git a/front_end/Images/src/optimize_png.hashes b/front_end/Images/src/optimize_png.hashes
deleted file mode 100644
index 6d0214a..0000000
--- a/front_end/Images/src/optimize_png.hashes
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "securityIcons.svg": "27676f7c1f1542659c7c49a8052259dc",
-    "largeIcons.svg": "6c7e87328ee5186a34782daf56700758",
-    "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
-    "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a",
-    "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
-    "smallIcons.svg": "40aefe4606ebba939725954ff9f908ef",
-    "mediumIcons.svg": "5305adcb3fa224710ef2efeec01667a8",
-    "breakpoint.svg": "69cd92d807259c022791112809b97799",
-    "treeoutlineTriangles.svg": "2d26ab85d919f83d5021f2f385dffd0b",
-    "chevrons.svg": "79b4b527771e30b6388ce664077b3409"
-}
\ No newline at end of file
diff --git a/front_end/Images/src/securityIcons.svg b/front_end/Images/src/securityIcons.svg
deleted file mode 100644
index 0b8f777..0000000
--- a/front_end/Images/src/securityIcons.svg
+++ /dev/null
@@ -1,278 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="80"
-   height="32"
-   viewBox="0 0 80 32"
-   version="1.1"
-   id="svg6301"
-   inkscape:version="0.48.4 r9939"
-   sodipodi:docname="securityIcons.svg">
-  <metadata
-     id="metadata6418">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1525"
-     inkscape:window-height="1092"
-     id="namedview6416"
-     showgrid="false"
-     inkscape:zoom="17.55"
-     inkscape:cx="77.609293"
-     inkscape:cy="-1.8798347"
-     inkscape:window-x="615"
-     inkscape:window-y="171"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Page"
-     showborder="true" />
-  <!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
-  <title
-     id="title6303">Non-Touch-Summary-Icons</title>
-  <desc
-     id="desc6305">Created with Sketch.</desc>
-  <defs
-     id="defs6307" />
-  <g
-     id="Page"
-     style="fill:none;stroke:none"
-     transform="translate(0,-64)">
-    <g
-       style="fill:#000000"
-       transform="translate(48,80)"
-       id="Info-Grey">
-      <path
-         inkscape:connector-curvature="0"
-         id="Icon"
-         d="M 2,3.7320873 C 2,2.7754819 2.7742777,2 3.7262996,2 L 13.2737,2 C 14.227109,2 15,2.7689087 15,3.7320873 l 0,8.5358257 C 15,13.224518 14.225722,14 13.2737,14 L 3.7262996,14 C 2.7728907,14 2,13.231091 2,12.267913 L 2,3.7320873 z M 8,6 9,6 9,5 8,5 8,6 8,6 z m 0,5 1,0 0,-4 -1,0 0,4 0,0 z" />
-    </g>
-    <g
-       id="Icon-HTTP"
-       transform="translate(64,80)">
-      <polygon
-         id="Layout"
-         points="0,16 0,0 16,0 16,16 " />
-    </g>
-    <g
-       id="ic_help_black_24dp"
-       transform="translate(66,82)"
-       style="fill:#000000">
-      <g
-         id="Group">
-        <path
-           d="M 67.71875 18 C 66.766728 18 66 18.762145 66 19.71875 L 66 28.28125 C 66 29.244428 66.765341 30 67.71875 30 L 77.28125 30 C 78.233272 30 79 29.237855 79 28.28125 L 79 19.71875 C 79 18.755571 78.234659 18 77.28125 18 L 67.71875 18 z M 72.5 20 C 73.605 20 74.5 20.895 74.5 22 C 74.5 22.44 74.31625 22.84 74.03125 23.125 L 73.59375 23.59375 C 73.23375 23.95875 73 24.25 73 25 L 72.6875 25 L 72.3125 25 L 72 25 L 72 24.75 C 72 24.2 72.23375 23.70875 72.59375 23.34375 L 73.21875 22.71875 C 73.40375 22.53875 73.5 22.275 73.5 22 C 73.5 21.45 73.05 21 72.5 21 C 71.95 21 71.5 21.45 71.5 22 L 70.5 22 C 70.5 20.895 71.395 20 72.5 20 z M 72 26 L 73 26 L 73 27 L 72 27 L 72 26 z "
-           transform="translate(-66,-18)"
-           id="path3614" />
-      </g>
-    </g>
-    <g
-       transform="translate(0,80)"
-       id="g6319">
-      <g
-         id="Security-Icon-Green-Simple">
-        <rect
-           style="opacity:0.2"
-           height="16"
-           width="16"
-           y="0"
-           x="0"
-           id="rect6322" />
-        <rect
-           style="fill:#000000"
-           rx="1"
-           height="8"
-           width="8"
-           y="4"
-           x="4"
-           id="Green" />
-      </g>
-    </g>
-    <g
-       transform="translate(16,80)"
-       id="g6325">
-      <g
-         id="g6327">
-        <rect
-           style="opacity:0.2"
-           height="16"
-           width="16"
-           y="0"
-           x="0"
-           id="rect6329" />
-        <rect
-           style="fill:#000000"
-           rx="4"
-           height="8"
-           width="8"
-           y="4"
-           x="4"
-           id="rect6331" />
-      </g>
-    </g>
-    <g
-       transform="translate(32,80)"
-       id="g6333">
-      <g
-         id="g6335">
-        <rect
-           style="opacity:0.2"
-           height="16"
-           width="16"
-           y="0"
-           x="0"
-           id="rect6337" />
-        <polygon
-           style="fill:#000000"
-           points="3,12 8,3 13,12 "
-           id="Red" />
-      </g>
-    </g>
-    <g
-       transform="translate(32,64)"
-       id="g6340">
-      <rect
-         style="opacity:0.2"
-         height="16"
-         width="16"
-         y="0"
-         x="0"
-         id="rect6342" />
-      <path
-         style="fill:#000000"
-         inkscape:connector-curvature="0"
-         id="path6344"
-         d="m 0.5,14 15,0 L 8,1 0.5,14 l 0,0 z m 8.5,-2 -2,0 0,-2 2,0 0,2 0,0 z M 9,9 7,9 7,6 9,6 9,9 9,9 z" />
-    </g>
-    <g
-       transform="translate(16,64)"
-       id="g6346">
-      <polygon
-         points="16,0 16,16 0,16 0,0 "
-         id="polygon6348" />
-      <path
-         style="fill:#000000"
-         inkscape:connector-curvature="0"
-         id="path6350"
-         d="M 8,1 C 4.136,1 1,4.136 1,8 c 0,3.864 3.136,7 7,7 3.864,0 7,-3.136 7,-7 C 15,4.136 11.864,1 8,1 L 8,1 z M 2.5,8 C 2.5,4.968125 4.968125,2.5 8,2.5 c 3.031875,0 5.5,2.468125 5.5,5.5 0,3.031875 -2.468125,5.5 -5.5,5.5 C 4.968125,13.5 2.5,11.031875 2.5,8 z M 9,12 9,7 7,7 7,12 9,12 z M 7,6 9,6 9,4 7,4 7,6 7,6 z" />
-    </g>
-    <g
-       transform="translate(0,64)"
-       id="g6352">
-      <polygon
-         points="16,0 16,16 0,16 0,0 "
-         id="polygon6354" />
-      <path
-         style="fill:#000000"
-         inkscape:connector-curvature="0"
-         id="path6356"
-         d="m 10.5,6.4999999 0,-1 C 10.5,4.1199951 9.3800049,3 8,3 6.6199951,3.0101721 5.5,4.1199951 5.5,5.4999999 l 0,1 c 0,0 0.050003,1e-7 -0.5,0 -0.5500031,-10e-8 -1,0.4501534 -1,0.9963379 L 4,12.5 c 0,0.550003 0.4500122,1 1,1 0.5499878,0 5.450012,0 6,0 0.549988,0 1,-0.449997 1,-1 0,-0.550003 0,-4.4499969 0,-5 0,-0.5277289 -0.449997,-1 -1,-1.0000001 -0.550003,1e-7 -0.5,0 -0.5,0 z M 6.5,6.5101141 6.5,5.5 C 6.5,4.6699982 7.1699982,4 8,4 8.8300018,4 9.5,4.6699982 9.5,5.5 l 0,1.0101141 -3,0 z" />
-    </g>
-    <g
-       style="fill:#000000"
-       transform="translate(99,35)"
-       id="g6358" />
-    <g
-       transform="translate(128,32)"
-       id="g6362">
-      <g
-         id="g6364">
-        <polygon
-           points="32,0 32,32 0,32 0,0 "
-           id="polygon6366" />
-      </g>
-      <g
-         style="fill:#000000"
-         transform="translate(3,3)"
-         id="g6368">
-        <g
-           id="g6370" />
-      </g>
-    </g>
-    <g
-       transform="translate(0,32)"
-       id="g6374">
-      <g
-         id="g6376">
-        <rect
-           style="opacity:0.2"
-           height="32"
-           width="32"
-           y="0"
-           x="0"
-           id="rect6378" />
-      </g>
-    </g>
-    <g
-       transform="translate(32,32)"
-       id="g6382">
-      <g
-         id="g6384">
-        <rect
-           style="opacity:0.2"
-           height="32"
-           width="32"
-           y="0"
-           x="0"
-           id="rect6386" />
-      </g>
-    </g>
-    <g
-       transform="translate(64,32)"
-       id="g6390">
-      <g
-         id="g6392">
-        <rect
-           style="opacity:0.2"
-           height="32"
-           width="32"
-           y="0"
-           x="0"
-           id="rect6394" />
-      </g>
-    </g>
-    <g
-       transform="translate(64,0)"
-       id="g6398">
-      <rect
-         style="opacity:0.2"
-         height="32"
-         width="32"
-         y="0"
-         x="0"
-         id="rect6400" />
-    </g>
-    <g
-       transform="translate(32,0)"
-       id="g6404">
-      <polygon
-         points="32,0 32,32 0,32 0,0 "
-         id="polygon6406" />
-    </g>
-    <g
-       id="g6410">
-      <polygon
-         points="32,0 32,32 0,32 0,0 "
-         id="polygon6412" />
-    </g>
-  </g>
-</svg>
diff --git a/front_end/Images/src/smallIcons.svg b/front_end/Images/src/smallIcons.svg
deleted file mode 100644
index 6b36da9..0000000
--- a/front_end/Images/src/smallIcons.svg
+++ /dev/null
@@ -1,1049 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="110"
-   height="110"
-   id="svg4185"
-   version="1.1"
-   inkscape:version="0.92.2pre0 (973e216, 2017-07-25)"
-   sodipodi:docname="smallIcons.svg"
-   inkscape:export-filename="/Users/pfeldman/code/chromium/src/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png"
-   inkscape:export-xdpi="180"
-   inkscape:export-ydpi="180">
-  <metadata
-     id="metadata4459">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs4457">
-    <linearGradient
-       id="sprite9_a-2"
-       x1="113"
-       x2="127"
-       y1="104"
-       y2="104"
-       gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)"
-       gradientUnits="userSpaceOnUse"
-       xlink:href="#sprite9_d-9" />
-    <linearGradient
-       id="sprite9_d-9">
-      <stop
-         stop-color="#606eda"
-         offset="0"
-         id="stop4292-1" />
-      <stop
-         stop-color="#021db2"
-         offset="1"
-         id="stop4294-2" />
-    </linearGradient>
-    <linearGradient
-       id="sprite6_a-0"
-       x2="24"
-       gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)"
-       gradientUnits="userSpaceOnUse"
-       xlink:href="#sprite6_b-6" />
-    <linearGradient
-       id="sprite6_b-6">
-      <stop
-         stop-color="#d7687d"
-         offset="0"
-         id="stop4236-2" />
-      <stop
-         stop-color="#b21402"
-         offset="1"
-         id="stop4238-6" />
-    </linearGradient>
-  </defs>
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1272"
-     inkscape:window-height="1006"
-     id="namedview4455"
-     showgrid="true"
-     inkscape:zoom="7.4167646"
-     inkscape:cx="72.154899"
-     inkscape:cy="32.871453"
-     inkscape:window-x="768"
-     inkscape:window-y="0"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg4185">
-    <inkscape:grid
-       type="xygrid"
-       id="grid4461"
-       empspacing="5"
-       visible="true"
-       enabled="true"
-       snapvisiblegridlinesonly="true"
-       spacingx="10"
-       spacingy="10"
-       originx="0"
-       originy="0" />
-  </sodipodi:namedview>
-  <g
-     id="g4187"
-     transform="translate(0,20)">
-    <path
-       transform="translate(-80,-20)"
-       d="m 80,20.995 c 0,-0.54974 0.45566,-0.9954 0.9954,-0.9954 h 8.0092 c 0.54974,0 0.9954,0.45566 0.9954,0.9954 v 8.0092 c 0,0.54974 -0.45566,0.9954 -0.9954,0.9954 H 80.9954 C 80.44566,29.9996 80,29.54394 80,29.0042 z m 5.1233,4.7444 c 2.5673,-0.42788 3.6267,-1.193 3.6267,-3.7398 h -1.5 c 0,1.6199 -0.44058,1.9381 -2.3733,2.2602 -2.5673,0.42788 -3.6267,1.193 -3.6267,3.7398 h 1.5 c 0,-1.6199 0.44058,-1.9381 2.3733,-2.2602 z"
-       id="path4191"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(20,20)"
-     id="g4193">
-    <path
-       transform="translate(-128,-109)"
-       d="m 131.65,116.21 -1.44,-2.03 -1.21,1.21 2.55,3.61 6.45,-7.67 -1.12,-1.33 z"
-       id="path4197"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(0,40)"
-     id="g4199">
-    <path
-       transform="translate(-40,-19)"
-       d="m 46.5,25 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1"
-       id="path4203"
-       inkscape:connector-curvature="0"
-       style="fill:#bababa" />
-    <path
-       transform="translate(-40,-19)"
-       d="m 45.75,21.75 -3.5,3.25 3.5,3.25"
-       id="path4205"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#bababa;stroke-width:1.5" />
-  </g>
-  <g
-     transform="translate(20,40)"
-     id="g4207">
-    <path
-       transform="translate(-177,-98)"
-       d="m 184.5,100.43 -0.93,-0.93 -2.57,2.57 -2.57,-2.57 -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4211"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.23999999" />
-    <path
-       transform="translate(-177,-98)"
-       d="M 184.5,99.93 183.57,99 181,101.57 178.43,99 l -0.93,0.93 2.57,2.57 -2.57,2.57 0.93,0.93 2.57,-2.57 2.57,2.57 0.93,-0.93 -2.57,-2.57 2.57,-2.57 z"
-       id="path4213"
-       inkscape:connector-curvature="0"
-       style="fill:#676767" />
-  </g>
-  <g
-     transform="translate(40,20)"
-     id="g4215">
-    <path
-       transform="translate(-100,0)"
-       d="m 103.25,-4.7795e-7 c -0.7,0 -1.25,0.49999999795 -1.25,1.24999997795 v 7.5 c 0,0.7 0.5,1.25 1.25,1.25 h 3.5 c 0.7,0 1.25,-0.5 1.25,-1.25 v -7.5 C 108,0.54999952 107.5,-4.7795e-7 106.75,-4.7795e-7 z M 103,0.99999952 h 4 V 7.9999995 h -4 z m 2,7.24999998 c 0.4,0 0.75,0.3 0.75,0.75 0,0.4 -0.3,0.75 -0.75,0.75 -0.4,0 -0.75,-0.3 -0.75,-0.75 0,-0.4 0.3,-0.75 0.75,-0.75 z"
-       id="path4219"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(40,40)"
-     id="g4221">
-    <path
-       transform="translate(-20,0)"
-       d="m 25,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 30,2.2399995 27.76,-4.7795e-7 25,-4.7795e-7"
-       id="path4225"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite6_a)" />
-    <path
-       transform="translate(-20,0)"
-       d="m 20.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64"
-       id="path4227"
-       inkscape:connector-curvature="0"
-       style="fill:#eb3941" />
-    <path
-       transform="translate(-20,0)"
-       d="m 23,3 4,4"
-       id="path4229"
-       inkscape:connector-curvature="0"
-       style="stroke:#ffffff" />
-    <path
-       transform="translate(-20,0)"
-       d="M 27,3 23,7"
-       id="path4231"
-       inkscape:connector-curvature="0"
-       style="stroke:#ffffff" />
-    <defs
-       id="defs4233">
-      <linearGradient
-         id="sprite6_b">
-        <stop
-           stop-color="#d7687d"
-           offset="0"
-           id="stop4236" />
-        <stop
-           stop-color="#b21402"
-           offset="1"
-           id="stop4238" />
-      </linearGradient>
-      <linearGradient
-         id="sprite6_a"
-         x2="24"
-         gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite6_b" />
-    </defs>
-  </g>
-  <path
-     style="fill:#adf2ad;stroke:#007200;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
-     inkscape:connector-curvature="0"
-     id="path4245"
-     d="M 4.4998214,61.3 8.5,65.00025 4.4998214,68.7 l 0,-1.2 -3.0748614,0 0.07504,-5 3.0001787,0 z"
-     sodipodi:nodetypes="cccccccc" />
-  <g
-     transform="translate(20,60)"
-     id="g4247">
-    <path
-       transform="translate(-140,0)"
-       d="m 144.95,9.9997 c -2.7598,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.2899,-4.9797 5.0497,-4.9497 2.7598,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.2899,4.9797 -5.0497,4.9497 z"
-       id="path4251"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite8_a)" />
-    <path
-       transform="translate(-140,0)"
-       d="m 149.5,5.05 c -0.03,2.4898 -2.0599,4.4797 -4.5497,4.4497 -2.4898,-0.03 -4.4797,-2.0598 -4.4497,-4.5497 0.03,-2.4898 2.0599,-4.4797 4.5497,-4.4497 2.4898,0.03 4.4797,2.0598 4.4497,4.5497 z"
-       id="path4253"
-       inkscape:connector-curvature="0"
-       style="fill:#00be00" />
-    <path
-       transform="translate(-140,0)"
-       d="m 145.08,0.5303 c 1.9699,0.02 3.5498,1.0599 3.5398,2.3198 -0.01,1.26 -1.6199,2.2599 -3.5898,2.2399 -1.9699,-0.02 -3.5498,-1.0599 -3.5398,-2.3199 0.01,-1.2599 1.6199,-2.2598 3.5898,-2.2398 z"
-       id="path4255"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite8_b)" />
-    <path
-       transform="translate(-140,0)"
-       d="m 144.98,9.4097 c 1.6599,0.02 3.0098,-0.6799 3.0198,-1.5599 0.01,-0.8799 -1.3299,-1.6099 -2.9798,-1.6299 -1.6599,-0.02 -3.0098,0.68 -3.0198,1.5599 -0.01,0.88 1.3299,1.6099 2.9798,1.6299 z"
-       id="path4257"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite8_c)" />
-    <defs
-       id="defs4259">
-      <linearGradient
-         id="sprite8_j">
-        <stop
-           stop-color="#00d600"
-           stop-opacity="0"
-           offset="0"
-           id="stop4262" />
-        <stop
-           stop-color="#d8fc7b"
-           stop-opacity=".81"
-           offset="1"
-           id="stop4264" />
-      </linearGradient>
-      <linearGradient
-         id="sprite8_k">
-        <stop
-           stop-color="#00ba00"
-           offset="0"
-           id="stop4267" />
-        <stop
-           stop-color="#fff"
-           stop-opacity=".91"
-           offset="1"
-           id="stop4269" />
-      </linearGradient>
-      <linearGradient
-         id="sprite8_l">
-        <stop
-           stop-color="#00a104"
-           offset="0"
-           id="stop4272" />
-        <stop
-           stop-color="#00c605"
-           offset="1"
-           id="stop4274" />
-      </linearGradient>
-      <linearGradient
-         id="sprite8_c"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(-0.0048,0.4396,0.78038,0.00853,65.608,-94.834)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite8_j" />
-      <linearGradient
-         id="sprite8_b"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(0.00687,-0.62923,0.9267,0.01012,47.871,147.44)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite8_k" />
-      <linearGradient
-         id="sprite8_a"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(-0.01507,1.3791,-1.3006,-0.0142,282.66,-312.8)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite8_l" />
-    </defs>
-  </g>
-  <g
-     transform="translate(40,60)"
-     id="g4279">
-    <path
-       transform="translate(-80,0)"
-       d="m 85,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 90,2.2399995 87.76,-4.7795e-7 85,-4.7795e-7"
-       id="path4283"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite9_a)" />
-    <path
-       transform="translate(-80,0)"
-       d="m 80.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64"
-       id="path4285"
-       inkscape:connector-curvature="0"
-       style="fill:#2a53cd" />
-    <path
-       transform="translate(-80,0)"
-       d="m 83.93,2.14 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 C 84.09,2.71 83.93,2.43 83.93,2.14 z m 1.7,5.46 H 86.3 V 8.13 H 83.41 V 7.6 h 0.66 V 3.99 H 83.41 V 3.46 h 2.22 V 7.6 z"
-       id="path4287"
-       inkscape:connector-curvature="0"
-       style="fill:#ffffff" />
-    <defs
-       id="defs4289">
-      <linearGradient
-         id="sprite9_d">
-        <stop
-           stop-color="#606eda"
-           offset="0"
-           id="stop4292" />
-        <stop
-           stop-color="#021db2"
-           offset="1"
-           id="stop4294" />
-      </linearGradient>
-      <linearGradient
-         id="sprite9_a"
-         x1="113"
-         x2="127"
-         y1="104"
-         y2="104"
-         gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite9_d" />
-    </defs>
-  </g>
-  <g
-     transform="translate(60,20)"
-     id="g4297">
-    <path
-       transform="translate(-160,-20)"
-       d="m 160.45,20.467 v 9.079 h 5.373 l 3.5821,-4.5398 -3.5821,-4.5392 z"
-       id="path4301"
-       inkscape:connector-curvature="0"
-       style="fill:#698cfe;stroke:#4073f4;stroke-width:0.90799999" />
-  </g>
-  <g
-     transform="translate(60,40)"
-     id="g4303">
-    <path
-       transform="translate(-140,-20)"
-       d="m 140.45,20.467 v 9.0791 h 5.3718 l 3.5813,-4.54 -3.5813,-4.5391 z"
-       id="path4307"
-       inkscape:connector-curvature="0"
-       style="fill:#ef9d0d;stroke:#a36c01;stroke-width:0.90799999" />
-  </g>
-  <g
-     transform="translate(60,60)"
-     id="g4309">
-    <path
-       transform="translate(-160,0)"
-       d="m 165,10 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z"
-       id="path4313"
-       inkscape:connector-curvature="0"
-       style="fill:#e5a600" />
-    <path
-       transform="translate(-160,0)"
-       d="m 169.5,5 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z"
-       id="path4315"
-       inkscape:connector-curvature="0"
-       style="fill:#ffbd00" />
-    <path
-       transform="translate(-160,0)"
-       d="m 165.03,0.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z"
-       id="path4317"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite12_a)" />
-    <path
-       transform="translate(-160,0)"
-       d="m 164.99,9.42 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z"
-       id="path4319"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite12_b)" />
-    <defs
-       id="defs4321">
-      <linearGradient
-         id="sprite12_l">
-        <stop
-           stop-color="#ffa801"
-           stop-opacity="0"
-           offset="0"
-           id="stop4324" />
-        <stop
-           stop-color="#f0fb3d"
-           offset="1"
-           id="stop4326" />
-      </linearGradient>
-      <linearGradient
-         id="sprite12_m">
-        <stop
-           stop-color="#ffbd00"
-           stop-opacity=".65"
-           offset="0"
-           id="stop4329" />
-        <stop
-           stop-color="#fff"
-           stop-opacity=".91"
-           offset="1"
-           id="stop4331" />
-      </linearGradient>
-      <linearGradient
-         id="sprite12_b"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(0,0.43966,0.78049,0,84.444,-93.924)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite12_l" />
-      <linearGradient
-         id="sprite12_a"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(0,-0.62931,0.92683,0,69.47,148.53)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite12_m" />
-    </defs>
-  </g>
-  <g
-     transform="translate(0,80)"
-     id="g4335">
-    <path
-       transform="translate(-120,0)"
-       d="m 125,10 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z"
-       id="path4339"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite13_a)" />
-    <path
-       transform="translate(-120,0)"
-       d="m 129.5,5 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z"
-       id="path4341"
-       inkscape:connector-curvature="0"
-       style="fill:#dd0000" />
-    <path
-       transform="translate(-120,0)"
-       d="m 125.03,0.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z"
-       id="path4343"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite13_b)" />
-    <path
-       transform="translate(-120,0)"
-       d="m 125.03,9.47 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z"
-       id="path4345"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite13_c)" />
-    <defs
-       id="defs4347">
-      <linearGradient
-         id="sprite13_g">
-        <stop
-           stop-color="red"
-           stop-opacity="0"
-           offset="0"
-           id="stop4350" />
-        <stop
-           stop-color="#f0cb68"
-           stop-opacity=".71"
-           offset="1"
-           id="stop4352" />
-      </linearGradient>
-      <linearGradient
-         id="sprite13_h">
-        <stop
-           stop-color="#e60000"
-           stop-opacity=".65"
-           offset="0"
-           id="stop4355" />
-        <stop
-           stop-color="#fff"
-           stop-opacity=".91"
-           offset="1"
-           id="stop4357" />
-      </linearGradient>
-      <linearGradient
-         id="sprite13_i">
-        <stop
-           stop-color="#a10000"
-           offset="0"
-           id="stop4360" />
-        <stop
-           stop-color="#c60000"
-           offset="1"
-           id="stop4362" />
-      </linearGradient>
-      <linearGradient
-         id="sprite13_c"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(0,0.43966,0.78049,0,44.488,-93.88)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite13_g" />
-      <linearGradient
-         id="sprite13_b"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(0,-0.62931,0.92683,0,29.47,148.53)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite13_h" />
-      <linearGradient
-         id="sprite13_a"
-         x1="227.88"
-         x2="235.12"
-         y1="103.16"
-         y2="103.16"
-         gradientTransform="matrix(0,1.3793,-1.3008,0,259.08,-314.35)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite13_i" />
-    </defs>
-  </g>
-  <g
-     transform="translate(20,80)"
-     id="g4367">
-    <path
-       transform="translate(-60,-20)"
-       d="M 60,20 H 70 V 30 H 60 z"
-       id="path4371"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-    <path
-       transform="translate(-60,-20)"
-       d="M 67.5,22.5 V 20 H 60 v 7.5 h 2.5 V 30 H 70 V 22.5 z M 61,21 h 5.5 v 5.5 H 61 z m 2.5,6.5 h 4 v -4 H 69 V 29 h -5.5 z"
-       id="path4373"
-       inkscape:connector-curvature="0" />
-    <path
-       d="m 3.5,7.5 h 4 v -4 H 9 V 9 H 3.5 z"
-       id="path4375"
-       inkscape:connector-curvature="0"
-       style="fill-opacity:0.25" />
-  </g>
-  <g
-     id="g4383"
-     style="fill:#acf2ae;stroke:#007200;stroke-width:2.5769999"
-     transform="translate(40,80)">
-    <path
-       transform="matrix(0.29356,0,0,0.2909,-37.35,6.864)"
-       d="m 144.95,9.9997 c -2.7598,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.2899,-4.9797 5.0497,-4.9497 2.7598,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.2899,4.9797 -5.0497,4.9497 z"
-       id="path4385"
-       inkscape:connector-curvature="0" />
-    <path
-       transform="matrix(0.29356,0,0,0.2909,-37.35,6.864)"
-       d="m 149.5,5.05 c -0.03,2.4898 -2.0599,4.4797 -4.5497,4.4497 -2.4898,-0.03 -4.4797,-2.0598 -4.4497,-4.5497 0.03,-2.4898 2.0599,-4.4797 4.5497,-4.4497 2.4898,0.03 4.4797,2.0598 4.4497,4.5497 z"
-       id="path4387"
-       inkscape:connector-curvature="0" />
-  </g>
-  <path
-     d="M 48.3126,82.499864 45.21075,86 42.1089,82.499864 l 1.24074,0 0,-1.919464 3.72222,0 0,1.919735 z"
-     id="path4389"
-     inkscape:connector-curvature="0"
-     style="fill:#adf2ad;stroke:#007200;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
-     sodipodi:nodetypes="cccccccc" />
-  <path
-     d="m 66.5375,88.5145 c -0.0088,0.72431 -0.6047,1.3032 -1.3356,1.2945 -0.73092,-0.0087 -1.3151,-0.59922 -1.3063,-1.3236 0.0088,-0.7243 0.6047,-1.3032 1.3356,-1.2945 0.73092,0.0087 1.3151,0.59922 1.3063,1.3235 z"
-     id="path4397"
-     inkscape:connector-curvature="0"
-     style="fill:#acf2ae;stroke:#007200;stroke-width:0.75300002" />
-  <path
-     d="m 62.1084,83.500135 3.10185,-2.981685 3.10185,2.981685 -1.24074,0 0,1.999865 -3.72222,0 0,-2.000136 z"
-     id="path4399"
-     inkscape:connector-curvature="0"
-     style="fill:#adf2ad;stroke:#007200;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
-     sodipodi:nodetypes="cccccccc" />
-  <g
-     transform="translate(80,20)"
-     id="g4401">
-    <path
-       transform="translate(-20,-20)"
-       d="m 23.25,21.75 3.5,3.25 -3.5,3.25"
-       id="path4405"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#367cf1;stroke-width:1.5" />
-  </g>
-  <g
-     transform="translate(80,40)"
-     id="g4407">
-    <path
-       transform="translate(-180,-20)"
-       d="m 186,20 -5,5 5,5 v -2 h 3 v -6 h -3 z"
-       id="path4411"
-       inkscape:connector-curvature="0"
-       style="fill:#4688f1" />
-  </g>
-  <g
-     transform="translate(80,60)"
-     id="g4413">
-    <path
-       transform="matrix(-1,0,0,1,190,-19.955)"
-       d="m 186,19.955 -5,5 5,5.0225 0,-2.045 3,0.0225 0,-6 -3,0 z"
-       id="path4417"
-       inkscape:connector-curvature="0"
-       style="fill:#4688f1"
-       sodipodi:nodetypes="cccccccc" />
-  </g>
-  <g
-     transform="matrix(0.85714286,0,0,0.85714286,80.142857,80.142857)"
-     id="g4419">
-    <path
-       transform="translate(-20,-98)"
-       d="m 25.083333,107.16667 4.083334,-7 H 21"
-       id="path4423"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccc" />
-  </g>
-  <g
-     transform="matrix(0.71428571,0,0,0.875,1.2857143,101)"
-     id="g4425">
-    <path
-       transform="translate(-4,-98)"
-       d="M 12,102 5,98 v 8"
-       id="path4429"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(20,100)"
-     id="g4431">
-    <path
-       transform="translate(-4,-111)"
-       d="m 8,111 4,7 H 4"
-       id="path4435"
-       inkscape:connector-curvature="0" />
-  </g>
-  <g
-     transform="translate(40,100)"
-     id="g4437">
-    <path
-       transform="translate(0,-19)"
-       d="m 3.2503,21.75 3.5,3.25 -3.5,3.25"
-       id="path4441"
-       inkscape:connector-curvature="0"
-       style="fill:none;stroke:#939393;stroke-width:1.5" />
-  </g>
-  <g
-     transform="translate(60,100)"
-     id="g4443">
-    <path
-       transform="translate(-60,0)"
-       d="m 61,9 4,-8 4,8 z"
-       id="path4447"
-       inkscape:connector-curvature="0"
-       style="stroke:#c19600;stroke-width:2;stroke-linejoin:round" />
-    <path
-       transform="translate(-60,0)"
-       d="m 61,9 4,-8 4,8 z"
-       id="path4449"
-       inkscape:connector-curvature="0"
-       style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round" />
-    <path
-       transform="translate(-60,0)"
-       d="m 63.75,2.75 h 2.5 v 2.5 L 65.75,7 h -1.5 l -0.5,-1.75 v -2.5 m 0,5.25 h 2.5 v 1.25 h -2.5"
-       id="path4451"
-       inkscape:connector-curvature="0"
-       style="fill:#ad8601" />
-    <path
-       transform="translate(-60,0)"
-       d="m 64,3 h 2 V 5.25 L 65.5,7 h -1 L 64,5.25 V 3 m 0,5 h 2 v 1 h -2"
-       id="path4453"
-       inkscape:connector-curvature="0"
-       style="fill:#ffffff" />
-  </g>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="3.0508475"
-     y="118.38672"
-     id="text5191"><tspan
-       sodipodi:role="line"
-       id="tspan5193"
-       x="3.0508475"
-       y="118.38672"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">a</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="23.050848"
-     y="118.38672"
-     id="text5191-1"><tspan
-       sodipodi:role="line"
-       id="tspan5193-7"
-       x="23.050848"
-       y="118.38672"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">b</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="43.050846"
-     y="118.38672"
-     id="text5191-7"><tspan
-       sodipodi:role="line"
-       id="tspan5193-1"
-       x="43.050846"
-       y="118.38672"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">c</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="63.050854"
-     y="118.38672"
-     id="text5191-15"><tspan
-       sodipodi:role="line"
-       id="tspan5193-9"
-       x="63.050854"
-       y="118.38672"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">d</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="83.05085"
-     y="118.38672"
-     id="text5191-77"><tspan
-       sodipodi:role="line"
-       id="tspan5193-6"
-       x="83.05085"
-       y="118.38672"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">e</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="-7.0260201"
-     y="107.81779"
-     id="text5191-73"><tspan
-       sodipodi:role="line"
-       id="tspan5193-65"
-       x="-7.0260201"
-       y="107.81779"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">1</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="-6.8189888"
-     y="87.880318"
-     id="text5191-6"><tspan
-       sodipodi:role="line"
-       id="tspan5193-3"
-       x="-6.8189888"
-       y="87.880318"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">2</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="-6.7564888"
-     y="67.991669"
-     id="text5191-9"><tspan
-       sodipodi:role="line"
-       id="tspan5193-4"
-       x="-6.7564888"
-       y="67.991669"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">3</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="-6.9166451"
-     y="47.993652"
-     id="text5191-8"><tspan
-       sodipodi:role="line"
-       id="tspan5193-12"
-       x="-6.9166451"
-       y="47.993652"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">4</tspan></text>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="-7.1080513"
-     y="28.056175"
-     id="text5191-93"><tspan
-       sodipodi:role="line"
-       id="tspan5193-90"
-       x="-7.1080513"
-       y="28.056175"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">5</tspan></text>
-  <g
-     transform="matrix(1.1320755,0,0,1.1320754,81.603774,102.60377)"
-     style="fill:#00bcd4;stroke:#000000;stroke-width:0.30000001"
-     id="g3669">
-    <circle
-       sodipodi:ry="2.5"
-       sodipodi:rx="2.5"
-       sodipodi:cy="3"
-       sodipodi:cx="3"
-       cx="3"
-       cy="3"
-       r="2.5"
-       id="circle3671" />
-  </g>
-  <path
-     inkscape:connector-curvature="0"
-     style="fill:#000000;fill-opacity:1;stroke-width:0;stroke-miterlimit:4"
-     d="m 5,-3e-7 c -2.761423,0 -5,2.238577 -5,5 C 0,7.7614237 2.238577,10 5,10 7.761423,10 9.9999997,7.7614237 9.9999997,4.9999997 c 0,-2.761423 -2.2385767,-5 -4.9999997,-5 z m 0.04808,0.721154 c 1.082746,1e-6 2.1787,0.399853 3.004808,1.225961 1.6522148,1.652217 1.6522148,4.333359 0,5.985577 L 5.04808,4.9519227 2.067311,1.9471147 C 2.893418,1.1210057 3.965334,0.7211527 5.04808,0.7211537 z"
-     id="path3255" />
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="-6.6795936"
-     y="8"
-     id="text5191-93-3"><tspan
-       sodipodi:role="line"
-       id="tspan5193-90-6"
-       x="-6.6795936"
-       y="8"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">6</tspan></text>
-  <g
-     transform="translate(13.293,-7.4383945)"
-     id="g74">
-    <path
-       style="fill:none"
-       inkscape:connector-curvature="0"
-       id="path80"
-       d="M 4.308,4.525 H 20.5404 V 20.7574 H 4.308 z" />
-    <path
-       style="fill-rule:evenodd"
-       inkscape:connector-curvature="0"
-       id="path82"
-       d="M 7.8179366,12.994649 6.707,14.105586 10.040596,17.438394 16.707,10.77199 15.596064,9.6610525 10.040596,15.216521 z" />
-    <g
-       transform="matrix(0.76923077,0,0,0.76923077,19.014692,2.8283064)"
-       id="g92">
-      <path
-         transform="translate(-64,0)"
-         d="m 80.44,16.94 c -2.48,0 -4.5,-2.02 -4.5,-4.5 0,-0.88 0.26,-1.7 0.69,-2.39 l 6.2,6.2 c -0.69,0.44 -1.51,0.69 -2.39,0.69 m 4.5,-4.5 c 0,0.88 -0.26,1.7 -0.69,2.39 l -6.2,-6.2 c 0.69,-0.44 1.51,-0.69 2.39,-0.69 2.48,0 4.5,2.02 4.5,4.5 M 80.5,6 C 76.91,6 74,8.91 74,12.5 74,16.09 76.91,19 80.5,19 84.09,19 87,16.09 87,12.5 87,8.91 84.09,6 80.5,6"
-         id="path96"
-         inkscape:connector-curvature="0" />
-    </g>
-    <path
-       style="fill-rule:evenodd"
-       d="m 55.582,9.6571445 -5.53125,5.5625005 -0.40625,-0.40625 -1.09375,1.125 1.5,1.499999 6.65625,-6.656249 -1.125,-1.1250005 z"
-       id="path3185" />
-  </g>
-  <text
-     xml:space="preserve"
-     style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1;stroke:none"
-     x="103.73887"
-     y="118.48206"
-     id="text5191-77-3"><tspan
-       sodipodi:role="line"
-       id="tspan5193-6-6"
-       x="103.73887"
-       y="118.48206"
-       style="font-size:8px;line-height:1.25;font-family:sans-serif">f</tspan></text>
-  <g
-     id="g4443-7"
-     transform="translate(100,100)"
-     mask="url(#path4453-6-mask)">
-    <path
-       transform="translate(-60,0)"
-       d="m 61,9 4,-8 4,8 z"
-       id="path4447-5"
-       inkscape:connector-curvature="0"
-       style="stroke:#c19600;stroke-width:2;stroke-linejoin:round" />
-    <path
-       transform="translate(-60,0)"
-       d="m 61,9 4,-8 4,8 z"
-       id="path4449-3"
-       inkscape:connector-curvature="0"
-       style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round" />
-    <path
-       transform="translate(-60,0)"
-       d="m 63.75,2.75 h 2.5 v 2.5 L 65.75,7 h -1.5 l -0.5,-1.75 v -2.5 m 0,5.25 h 2.5 v 1.25 h -2.5"
-       id="path4451-5"
-       inkscape:connector-curvature="0"
-       style="fill:#ad8601" />
-    <mask
-       id="path4453-6-mask">
-      <path
-         transform="translate(-60,0)"
-         d="m 64,3 h 2 V 5.25 L 65.5,7 h -1 L 64,5.25 V 3 m 0,5 h 2 v 1 h -2"
-         id="path4453-6"
-         inkscape:connector-curvature="0"
-         style="fill:#000000" />
-      <rect
-         width="10"
-         height="10"
-         style="fill:#ffffff"
-         id="rect8990" />
-    </mask>
-  </g>
-  <g
-     id="g4279-7"
-     transform="translate(100,80)"
-     mask="url(#path4287-3-mask)">
-    <path
-       transform="translate(-80,0)"
-       d="m 85,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 90,2.2399995 87.76,-4.7795e-7 85,-4.7795e-7"
-       id="path4283-0"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite9_a-2)" />
-    <path
-       transform="translate(-80,0)"
-       d="m 80.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64"
-       id="path4285-9"
-       inkscape:connector-curvature="0"
-       style="fill:#2a53cd" />
-    <mask
-       id="path4287-3-mask">
-      <path
-         transform="translate(-80,0)"
-         d="m 83.93,2.14 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 C 84.09,2.71 83.93,2.43 83.93,2.14 z m 1.7,5.46 H 86.3 V 8.13 H 83.41 V 7.6 h 0.66 V 3.99 H 83.41 V 3.46 h 2.22 V 7.6 z"
-         id="path4287-3"
-         inkscape:connector-curvature="0"
-         style="fill:#000000" />
-      <rect
-         width="10"
-         height="10"
-         style="fill:#ffffff"
-         id="rect8997" />
-    </mask>
-    <defs
-       id="defs4289-6">
-      <linearGradient
-         id="linearGradient3198">
-        <stop
-           stop-color="#606eda"
-           offset="0"
-           id="stop3200" />
-        <stop
-           stop-color="#021db2"
-           offset="1"
-           id="stop3202" />
-      </linearGradient>
-      <linearGradient
-         id="linearGradient3204"
-         x1="113"
-         x2="127"
-         y1="104"
-         y2="104"
-         gradientTransform="matrix(0.71429,0,0,0.71429,-0.714,-69.286)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite9_d-9" />
-    </defs>
-  </g>
-  <g
-     id="g4221-1"
-     transform="translate(100,60)"
-     mask="url(#path4229-9-path4231-2-mask)">
-    <path
-       transform="translate(-20,0)"
-       d="m 25,-4.7795e-7 c -2.76,0 -5,2.23999997795 -5,4.99999997795 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 C 30,2.2399995 27.76,-4.7795e-7 25,-4.7795e-7"
-       id="path4225-8"
-       inkscape:connector-curvature="0"
-       style="fill:url(#sprite6_a-0)" />
-    <path
-       transform="translate(-20,0)"
-       d="m 20.36,5 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64"
-       id="path4227-7"
-       inkscape:connector-curvature="0"
-       style="fill:#eb3941" />
-    <mask
-       id="path4229-9-path4231-2-mask">
-      <path
-         transform="translate(-20,0)"
-         d="m 23,3 4,4"
-         id="path4229-9"
-         inkscape:connector-curvature="0"
-         style="stroke:#000000" />
-      <path
-         transform="translate(-20,0)"
-         d="M 27,3 23,7"
-         id="path4231-2"
-         inkscape:connector-curvature="0"
-         style="stroke:#000000" />
-      <rect
-         width="10"
-         height="10"
-         style="fill:#ffffff"
-         id="rect9010" />
-    </mask>
-    <defs
-       id="defs4233-0">
-      <linearGradient
-         id="linearGradient3257">
-        <stop
-           stop-color="#d7687d"
-           offset="0"
-           id="stop3259" />
-        <stop
-           stop-color="#b21402"
-           offset="1"
-           id="stop3261" />
-      </linearGradient>
-      <linearGradient
-         id="linearGradient3263"
-         x2="24"
-         gradientTransform="matrix(0,-0.41667,-0.41667,0,25,10)"
-         gradientUnits="userSpaceOnUse"
-         xlink:href="#sprite6_b-6" />
-    </defs>
-  </g>
-  <g
-     style="fill:#000000"
-     id="g9271"
-     transform="matrix(0.48333333,0,0,0.48333333,99.3,39.3)">
-    <path
-       id="path9261"
-       d="M 12,2 C 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22 17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 z m 0,3 c 1.66,0 3,1.34 3,3 0,1.66 -1.34,3 -3,3 C 10.34,11 9,9.66 9,8 9,6.34 10.34,5 12,5 z m 0,14.2 c -2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22 z"
-       inkscape:connector-curvature="0" />
-    <path
-       id="path9263"
-       d="M 0,0 H 24 V 24 H 0 z"
-       inkscape:connector-curvature="0"
-       style="fill:none" />
-  </g>
-  <path
-     style="fill:#000000"
-     inkscape:connector-curvature="0"
-     d="M 105,22.528009 101,26.958771 101.94,28 105,24.617852 108.06,28 109,26.958771 z"
-     id="path3942" />
-  <path
-     style="fill:none"
-     inkscape:connector-curvature="0"
-     d="M 76.448271,14.990123 H 93.976446 V 34.405914 H 76.448271 z"
-     id="path3944" />
-  <path
-     style="fill:#000000"
-     inkscape:connector-curvature="0"
-     d="M 88.06,3.059999 85,6.113332 81.94,3.059999 l -0.94,0.94 4,4 4,-4 z"
-     id="path3974" />
-</svg>
diff --git a/front_end/Images/src/svg2png.hashes b/front_end/Images/src/svg2png.hashes
deleted file mode 100644
index 6d0214a..0000000
--- a/front_end/Images/src/svg2png.hashes
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "securityIcons.svg": "27676f7c1f1542659c7c49a8052259dc",
-    "largeIcons.svg": "6c7e87328ee5186a34782daf56700758",
-    "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
-    "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a",
-    "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
-    "smallIcons.svg": "40aefe4606ebba939725954ff9f908ef",
-    "mediumIcons.svg": "5305adcb3fa224710ef2efeec01667a8",
-    "breakpoint.svg": "69cd92d807259c022791112809b97799",
-    "treeoutlineTriangles.svg": "2d26ab85d919f83d5021f2f385dffd0b",
-    "chevrons.svg": "79b4b527771e30b6388ce664077b3409"
-}
\ No newline at end of file
diff --git a/front_end/Images/src/treeoutlineTriangles.svg b/front_end/Images/src/treeoutlineTriangles.svg
deleted file mode 100644
index 600f244..0000000
--- a/front_end/Images/src/treeoutlineTriangles.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="32"
-   height="24"
-   id="svg3620"
-   version="1.1"
-   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
-   sodipodi:docname="treeoutlineTriangles.svg"
-   inkscape:export-filename="/Users/pfeldman/code/chromium/src/third_party/WebKit/Source/devtools/front_end/Images/treeoutlineTriangles_2x.png"
-   inkscape:export-xdpi="192"
-   inkscape:export-ydpi="192">
-  <defs
-     id="defs3622" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="15.999999"
-     inkscape:cx="5.8968306"
-     inkscape:cy="33.634397"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:window-width="1680"
-     inkscape:window-height="1005"
-     inkscape:window-x="0"
-     inkscape:window-y="1"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata3625">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(0,-1028.3622)">
-    <path
-       d="m 7.5,1034.3622 -5.5,-3.75 v 7.5"
-       id="path3619"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccc" />
-    <path
-       d="m 20.5,1037.8622 3.75,-5.5 h -7.5"
-       id="path3621"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="ccc" />
-  </g>
-</svg>
diff --git a/front_end/Images/toolbarResizerVertical.png b/front_end/Images/toolbarResizerVertical.png
deleted file mode 100644
index bf84d1e..0000000
--- a/front_end/Images/toolbarResizerVertical.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/touchCursor.png b/front_end/Images/touchCursor.png
deleted file mode 100644
index a6e0e80..0000000
--- a/front_end/Images/touchCursor.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/touchCursor_2x.png b/front_end/Images/touchCursor_2x.png
deleted file mode 100644
index f769f12..0000000
--- a/front_end/Images/touchCursor_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/treeoutlineTriangles.png b/front_end/Images/treeoutlineTriangles.png
deleted file mode 100644
index 3ae162f..0000000
--- a/front_end/Images/treeoutlineTriangles.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/treeoutlineTriangles_2x.png b/front_end/Images/treeoutlineTriangles_2x.png
deleted file mode 100644
index fc7e0ac..0000000
--- a/front_end/Images/treeoutlineTriangles_2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/Images/whatsnew.png b/front_end/Images/whatsnew.png
deleted file mode 100644
index 9e34d4e..0000000
--- a/front_end/Images/whatsnew.png
+++ /dev/null
Binary files differ
diff --git a/front_end/OWNERS b/front_end/OWNERS
deleted file mode 100644
index 12637c5..0000000
--- a/front_end/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-alph@chromium.org
-caseq@chromium.org
-dgozman@chromium.org
-lushnikov@chromium.org
-pfeldman@chromium.org
diff --git a/front_end/Runtime.js b/front_end/Runtime.js
deleted file mode 100644
index 56fbb23..0000000
--- a/front_end/Runtime.js
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// This gets all concatenated module descriptors in the release mode.
-const allDescriptors = [];
-let applicationDescriptor;
-const _loadedScripts = {};
-
-// FIXME: This is a workaround to force Closure compiler provide
-// the standard ES6 runtime for all modules. This should be removed
-// once Closure provides standard externs for Map et al.
-for (const k of []) {  // eslint-disable-line
-}
-
-(function() {
-const baseUrl = self.location ? self.location.origin + self.location.pathname : '';
-self._importScriptPathPrefix = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1);
-})();
-
-/**
- * @unrestricted
- */
-var Runtime = class {  // eslint-disable-line
-  /**
-   * @param {!Array.<!Runtime.ModuleDescriptor>} descriptors
-   */
-  constructor(descriptors) {
-    /** @type {!Array<!Runtime.Module>} */
-    this._modules = [];
-    /** @type {!Object<string, !Runtime.Module>} */
-    this._modulesMap = {};
-    /** @type {!Array<!Runtime.Extension>} */
-    this._extensions = [];
-    /** @type {!Object<string, !function(new:Object)>} */
-    this._cachedTypeClasses = {};
-    /** @type {!Object<string, !Runtime.ModuleDescriptor>} */
-    this._descriptorsMap = {};
-
-    for (let i = 0; i < descriptors.length; ++i)
-      this._registerModule(descriptors[i]);
-
-    Runtime._runtimeReadyPromiseCallback();
-  }
-
-  /**
-   * @param {string} url
-   * @return {!Promise.<string>}
-   */
-  static loadResourcePromise(url) {
-    return new Promise(load);
-
-    /**
-     * @param {function(?)} fulfill
-     * @param {function(*)} reject
-     */
-    function load(fulfill, reject) {
-      const xhr = new XMLHttpRequest();
-      xhr.open('GET', url, true);
-      xhr.onreadystatechange = onreadystatechange;
-
-      /**
-       * @param {Event} e
-       */
-      function onreadystatechange(e) {
-        if (xhr.readyState !== XMLHttpRequest.DONE)
-          return;
-
-        if ([0, 200, 304].indexOf(xhr.status) === -1)  // Testing harness file:/// results in 0.
-          reject(new Error('While loading from url ' + url + ' server responded with a status of ' + xhr.status));
-        else
-          fulfill(e.target.response);
-      }
-      xhr.send(null);
-    }
-  }
-
-  /**
-   * http://tools.ietf.org/html/rfc3986#section-5.2.4
-   * @param {string} path
-   * @return {string}
-   */
-  static normalizePath(path) {
-    if (path.indexOf('..') === -1 && path.indexOf('.') === -1)
-      return path;
-
-    const normalizedSegments = [];
-    const segments = path.split('/');
-    for (let i = 0; i < segments.length; i++) {
-      const segment = segments[i];
-      if (segment === '.')
-        continue;
-      else if (segment === '..')
-        normalizedSegments.pop();
-      else if (segment)
-        normalizedSegments.push(segment);
-    }
-    let normalizedPath = normalizedSegments.join('/');
-    if (normalizedPath[normalizedPath.length - 1] === '/')
-      return normalizedPath;
-    if (path[0] === '/' && normalizedPath)
-      normalizedPath = '/' + normalizedPath;
-    if ((path[path.length - 1] === '/') || (segments[segments.length - 1] === '.') ||
-        (segments[segments.length - 1] === '..'))
-      normalizedPath = normalizedPath + '/';
-
-    return normalizedPath;
-  }
-
-  /**
-   * @param {!Array.<string>} scriptNames
-   * @param {string=} base
-   * @return {!Promise.<undefined>}
-   */
-  static _loadScriptsPromise(scriptNames, base) {
-    /** @type {!Array<!Promise<undefined>>} */
-    const promises = [];
-    /** @type {!Array<string>} */
-    const urls = [];
-    const sources = new Array(scriptNames.length);
-    let scriptToEval = 0;
-    for (let i = 0; i < scriptNames.length; ++i) {
-      const scriptName = scriptNames[i];
-      let sourceURL = (base || self._importScriptPathPrefix) + scriptName;
-
-      const schemaIndex = sourceURL.indexOf('://') + 3;
-      let pathIndex = sourceURL.indexOf('/', schemaIndex);
-      if (pathIndex === -1)
-        pathIndex = sourceURL.length;
-      sourceURL = sourceURL.substring(0, pathIndex) + Runtime.normalizePath(sourceURL.substring(pathIndex));
-
-      if (_loadedScripts[sourceURL])
-        continue;
-      urls.push(sourceURL);
-      promises.push(Runtime.loadResourcePromise(sourceURL).then(
-          scriptSourceLoaded.bind(null, i), scriptSourceLoaded.bind(null, i, undefined)));
-    }
-    return Promise.all(promises).then(undefined);
-
-    /**
-     * @param {number} scriptNumber
-     * @param {string=} scriptSource
-     */
-    function scriptSourceLoaded(scriptNumber, scriptSource) {
-      sources[scriptNumber] = scriptSource || '';
-      // Eval scripts as fast as possible.
-      while (typeof sources[scriptToEval] !== 'undefined') {
-        evaluateScript(urls[scriptToEval], sources[scriptToEval]);
-        ++scriptToEval;
-      }
-    }
-
-    /**
-     * @param {string} sourceURL
-     * @param {string=} scriptSource
-     */
-    function evaluateScript(sourceURL, scriptSource) {
-      _loadedScripts[sourceURL] = true;
-      if (!scriptSource) {
-        // Do not reject, as this is normal in the hosted mode.
-        console.error('Empty response arrived for script \'' + sourceURL + '\'');
-        return;
-      }
-      self.eval(scriptSource + '\n//# sourceURL=' + sourceURL);
-    }
-  }
-
-  /**
-   * @param {string} url
-   * @param {boolean} appendSourceURL
-   * @return {!Promise<undefined>}
-   */
-  static _loadResourceIntoCache(url, appendSourceURL) {
-    return Runtime.loadResourcePromise(url).then(
-        cacheResource.bind(this, url), cacheResource.bind(this, url, undefined));
-
-    /**
-     * @param {string} path
-     * @param {string=} content
-     */
-    function cacheResource(path, content) {
-      if (!content) {
-        console.error('Failed to load resource: ' + path);
-        return;
-      }
-      const sourceURL = appendSourceURL ? Runtime.resolveSourceURL(path) : '';
-      Runtime.cachedResources[path] = content + sourceURL;
-    }
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  static async runtimeReady() {
-    return Runtime._runtimeReadyPromise;
-  }
-
-  /**
-   * @param {string} appName
-   * @return {!Promise.<undefined>}
-   */
-  static async startApplication(appName) {
-    console.timeStamp('Runtime.startApplication');
-
-    const allDescriptorsByName = {};
-    for (let i = 0; i < allDescriptors.length; ++i) {
-      const d = allDescriptors[i];
-      allDescriptorsByName[d['name']] = d;
-    }
-
-    if (!applicationDescriptor) {
-      let data = await Runtime.loadResourcePromise(appName + '.json');
-      applicationDescriptor = JSON.parse(data);
-      let descriptor = applicationDescriptor;
-      while (descriptor.extends) {
-        data = await Runtime.loadResourcePromise(descriptor.extends + '.json');
-        descriptor = JSON.parse(data);
-        applicationDescriptor.modules = descriptor.modules.concat(applicationDescriptor.modules);
-      }
-    }
-
-    const configuration = applicationDescriptor.modules;
-    const moduleJSONPromises = [];
-    const coreModuleNames = [];
-    for (let i = 0; i < configuration.length; ++i) {
-      const descriptor = configuration[i];
-      const name = descriptor['name'];
-      const moduleJSON = allDescriptorsByName[name];
-      if (moduleJSON)
-        moduleJSONPromises.push(Promise.resolve(moduleJSON));
-      else
-        moduleJSONPromises.push(Runtime.loadResourcePromise(name + '/module.json').then(JSON.parse.bind(JSON)));
-      if (descriptor['type'] === 'autostart')
-        coreModuleNames.push(name);
-    }
-
-    const moduleDescriptors = await Promise.all(moduleJSONPromises);
-
-    for (let i = 0; i < moduleDescriptors.length; ++i) {
-      moduleDescriptors[i].name = configuration[i]['name'];
-      moduleDescriptors[i].condition = configuration[i]['condition'];
-      moduleDescriptors[i].remote = configuration[i]['type'] === 'remote';
-    }
-    self.runtime = new Runtime(moduleDescriptors);
-    if (coreModuleNames)
-      return /** @type {!Promise<undefined>} */ (self.runtime._loadAutoStartModules(coreModuleNames));
-  }
-
-  /**
-   * @param {string} appName
-   * @return {!Promise.<undefined>}
-   */
-  static startWorker(appName) {
-    return Runtime.startApplication(appName).then(sendWorkerReady);
-
-    function sendWorkerReady() {
-      self.postMessage('workerReady');
-    }
-  }
-
-  /**
-   * @param {string} name
-   * @return {?string}
-   */
-  static queryParam(name) {
-    return Runtime._queryParamsObject[name] || null;
-  }
-
-  /**
-   * @return {string}
-   */
-  static queryParamsString() {
-    return location.search;
-  }
-
-  /**
-   * @return {!Object}
-   */
-  static _experimentsSetting() {
-    try {
-      return /** @type {!Object} */ (
-          JSON.parse(self.localStorage && self.localStorage['experiments'] ? self.localStorage['experiments'] : '{}'));
-    } catch (e) {
-      console.error('Failed to parse localStorage[\'experiments\']');
-      return {};
-    }
-  }
-
-  static _assert(value, message) {
-    if (value)
-      return;
-    Runtime._originalAssert.call(Runtime._console, value, message + ' ' + new Error().stack);
-  }
-
-  /**
-   * @param {string} platform
-   */
-  static setPlatform(platform) {
-    Runtime._platform = platform;
-  }
-
-  /**
-   * @param {!Object} descriptor
-   * @return {boolean}
-   */
-  static _isDescriptorEnabled(descriptor) {
-    const activatorExperiment = descriptor['experiment'];
-    if (activatorExperiment === '*')
-      return Runtime.experiments.supportEnabled();
-    if (activatorExperiment && activatorExperiment.startsWith('!') &&
-        Runtime.experiments.isEnabled(activatorExperiment.substring(1)))
-      return false;
-    if (activatorExperiment && !activatorExperiment.startsWith('!') &&
-        !Runtime.experiments.isEnabled(activatorExperiment))
-      return false;
-    const condition = descriptor['condition'];
-    if (condition && !condition.startsWith('!') && !Runtime.queryParam(condition))
-      return false;
-    if (condition && condition.startsWith('!') && Runtime.queryParam(condition.substring(1)))
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {string} path
-   * @return {string}
-   */
-  static resolveSourceURL(path) {
-    let sourceURL = self.location.href;
-    if (self.location.search)
-      sourceURL = sourceURL.replace(self.location.search, '');
-    sourceURL = sourceURL.substring(0, sourceURL.lastIndexOf('/') + 1) + path;
-    return '\n/*# sourceURL=' + sourceURL + ' */';
-  }
-
-  useTestBase() {
-    Runtime._remoteBase = 'http://localhost:8000/inspector-sources/';
-    if (Runtime.queryParam('debugFrontend'))
-      Runtime._remoteBase += 'debug/';
-  }
-
-  /**
-   * @param {!Runtime.ModuleDescriptor} descriptor
-   */
-  _registerModule(descriptor) {
-    const module = new Runtime.Module(this, descriptor);
-    this._modules.push(module);
-    this._modulesMap[descriptor['name']] = module;
-  }
-
-  /**
-   * @param {string} moduleName
-   * @return {!Promise.<undefined>}
-   */
-  loadModulePromise(moduleName) {
-    return this._modulesMap[moduleName]._loadPromise();
-  }
-
-  /**
-   * @param {!Array.<string>} moduleNames
-   * @return {!Promise.<!Array.<*>>}
-   */
-  _loadAutoStartModules(moduleNames) {
-    const promises = [];
-    for (let i = 0; i < moduleNames.length; ++i)
-      promises.push(this.loadModulePromise(moduleNames[i]));
-    return Promise.all(promises);
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @param {?function(function(new:Object)):boolean} predicate
-   * @return {boolean}
-   */
-  _checkExtensionApplicability(extension, predicate) {
-    if (!predicate)
-      return false;
-    const contextTypes = extension.descriptor().contextTypes;
-    if (!contextTypes)
-      return true;
-    for (let i = 0; i < contextTypes.length; ++i) {
-      const contextType = this._resolve(contextTypes[i]);
-      const isMatching = !!contextType && predicate(contextType);
-      if (isMatching)
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @param {?Object} context
-   * @return {boolean}
-   */
-  isExtensionApplicableToContext(extension, context) {
-    if (!context)
-      return true;
-    return this._checkExtensionApplicability(extension, isInstanceOf);
-
-    /**
-     * @param {!Function} targetType
-     * @return {boolean}
-     */
-    function isInstanceOf(targetType) {
-      return context instanceof targetType;
-    }
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @param {!Set.<!Function>=} currentContextTypes
-   * @return {boolean}
-   */
-  isExtensionApplicableToContextTypes(extension, currentContextTypes) {
-    if (!extension.descriptor().contextTypes)
-      return true;
-
-    return this._checkExtensionApplicability(extension, currentContextTypes ? isContextTypeKnown : null);
-
-    /**
-     * @param {!Function} targetType
-     * @return {boolean}
-     */
-    function isContextTypeKnown(targetType) {
-      return currentContextTypes.has(targetType);
-    }
-  }
-
-  /**
-   * @param {*} type
-   * @param {?Object=} context
-   * @param {boolean=} sortByTitle
-   * @return {!Array.<!Runtime.Extension>}
-   */
-  extensions(type, context, sortByTitle) {
-    return this._extensions.filter(filter).sort(sortByTitle ? titleComparator : orderComparator);
-
-    /**
-     * @param {!Runtime.Extension} extension
-     * @return {boolean}
-     */
-    function filter(extension) {
-      if (extension._type !== type && extension._typeClass() !== type)
-        return false;
-      if (!extension.enabled())
-        return false;
-      return !context || extension.isApplicable(context);
-    }
-
-    /**
-     * @param {!Runtime.Extension} extension1
-     * @param {!Runtime.Extension} extension2
-     * @return {number}
-     */
-    function orderComparator(extension1, extension2) {
-      const order1 = extension1.descriptor()['order'] || 0;
-      const order2 = extension2.descriptor()['order'] || 0;
-      return order1 - order2;
-    }
-
-    /**
-     * @param {!Runtime.Extension} extension1
-     * @param {!Runtime.Extension} extension2
-     * @return {number}
-     */
-    function titleComparator(extension1, extension2) {
-      const title1 = extension1.title() || '';
-      const title2 = extension2.title() || '';
-      return title1.localeCompare(title2);
-    }
-  }
-
-  /**
-   * @param {*} type
-   * @param {?Object=} context
-   * @return {?Runtime.Extension}
-   */
-  extension(type, context) {
-    return this.extensions(type, context)[0] || null;
-  }
-
-  /**
-   * @param {*} type
-   * @param {?Object=} context
-   * @return {!Promise.<!Array.<!Object>>}
-   */
-  allInstances(type, context) {
-    return Promise.all(this.extensions(type, context).map(extension => extension.instance()));
-  }
-
-  /**
-   * @return {?function(new:Object)}
-   */
-  _resolve(typeName) {
-    if (!this._cachedTypeClasses[typeName]) {
-      const path = typeName.split('.');
-      let object = self;
-      for (let i = 0; object && (i < path.length); ++i)
-        object = object[path[i]];
-      if (object)
-        this._cachedTypeClasses[typeName] = /** @type function(new:Object) */ (object);
-    }
-    return this._cachedTypeClasses[typeName] || null;
-  }
-
-  /**
-   * @param {!Function} constructorFunction
-   * @return {!Object}
-   */
-  sharedInstance(constructorFunction) {
-    if (Runtime._instanceSymbol in constructorFunction &&
-        Object.getOwnPropertySymbols(constructorFunction).includes(Runtime._instanceSymbol))
-      return constructorFunction[Runtime._instanceSymbol];
-
-    const instance = new constructorFunction();
-    constructorFunction[Runtime._instanceSymbol] = instance;
-    return instance;
-  }
-};
-
-/**
- * @type {!Object.<string, string>}
- */
-Runtime._queryParamsObject = {
-  __proto__: null
-};
-
-Runtime._instanceSymbol = Symbol('instance');
-
-/**
- * @type {!Object.<string, string>}
- */
-Runtime.cachedResources = {
-  __proto__: null
-};
-
-
-Runtime._console = console;
-Runtime._originalAssert = console.assert;
-
-
-Runtime._platform = '';
-
-
-/**
- * @unrestricted
- */
-Runtime.ModuleDescriptor = class {
-  constructor() {
-    /**
-     * @type {string}
-     */
-    this.name;
-
-    /**
-     * @type {!Array.<!Runtime.ExtensionDescriptor>}
-     */
-    this.extensions;
-
-    /**
-     * @type {!Array.<string>|undefined}
-     */
-    this.dependencies;
-
-    /**
-     * @type {!Array.<string>}
-     */
-    this.scripts;
-
-    /**
-     * @type {string|undefined}
-     */
-    this.condition;
-
-    /**
-     * @type {boolean|undefined}
-     */
-    this.remote;
-  }
-};
-
-/**
- * @unrestricted
- */
-Runtime.ExtensionDescriptor = class {
-  constructor() {
-    /**
-     * @type {string}
-     */
-    this.type;
-
-    /**
-     * @type {string|undefined}
-     */
-    this.className;
-
-    /**
-     * @type {string|undefined}
-     */
-    this.factoryName;
-
-    /**
-     * @type {!Array.<string>|undefined}
-     */
-    this.contextTypes;
-  }
-};
-
-/**
- * @unrestricted
- */
-Runtime.Module = class {
-  /**
-   * @param {!Runtime} manager
-   * @param {!Runtime.ModuleDescriptor} descriptor
-   */
-  constructor(manager, descriptor) {
-    this._manager = manager;
-    this._descriptor = descriptor;
-    this._name = descriptor.name;
-    /** @type {!Array<!Runtime.Extension>} */
-    this._extensions = [];
-
-    /** @type {!Map<string, !Array<!Runtime.Extension>>} */
-    this._extensionsByClassName = new Map();
-    const extensions = /** @type {?Array.<!Runtime.ExtensionDescriptor>} */ (descriptor.extensions);
-    for (let i = 0; extensions && i < extensions.length; ++i) {
-      const extension = new Runtime.Extension(this, extensions[i]);
-      this._manager._extensions.push(extension);
-      this._extensions.push(extension);
-    }
-    this._loadedForTest = false;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._name;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  enabled() {
-    return Runtime._isDescriptorEnabled(this._descriptor);
-  }
-
-  /**
-   * @param {string} name
-   * @return {string}
-   */
-  resource(name) {
-    const fullName = this._name + '/' + name;
-    const content = Runtime.cachedResources[fullName];
-    if (!content)
-      throw new Error(fullName + ' not preloaded. Check module.json');
-    return content;
-  }
-
-  /**
-   * @return {!Promise.<undefined>}
-   */
-  _loadPromise() {
-    if (!this.enabled())
-      return Promise.reject(new Error('Module ' + this._name + ' is not enabled'));
-
-    if (this._pendingLoadPromise)
-      return this._pendingLoadPromise;
-
-    const dependencies = this._descriptor.dependencies;
-    const dependencyPromises = [];
-    for (let i = 0; dependencies && i < dependencies.length; ++i)
-      dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._loadPromise());
-
-    this._pendingLoadPromise = Promise.all(dependencyPromises)
-                                   .then(this._loadResources.bind(this))
-                                   .then(this._loadScripts.bind(this))
-                                   .then(() => this._loadedForTest = true);
-
-    return this._pendingLoadPromise;
-  }
-
-  /**
-   * @return {!Promise.<undefined>}
-   * @this {Runtime.Module}
-   */
-  _loadResources() {
-    const resources = this._descriptor['resources'];
-    if (!resources || !resources.length)
-      return Promise.resolve();
-    const promises = [];
-    for (let i = 0; i < resources.length; ++i) {
-      const url = this._modularizeURL(resources[i]);
-      promises.push(Runtime._loadResourceIntoCache(url, true));
-    }
-    return Promise.all(promises).then(undefined);
-  }
-
-  /**
-   * @return {!Promise.<undefined>}
-   */
-  _loadScripts() {
-    if (!this._descriptor.scripts || !this._descriptor.scripts.length)
-      return Promise.resolve();
-
-    // Module namespaces.
-    // NOTE: Update scripts/special_case_namespaces.json if you add a special cased namespace.
-    // The namespace keyword confuses clang-format.
-    // clang-format off
-    const specialCases = {
-      'sdk': 'SDK',
-      'js_sdk': 'JSSDK',
-      'browser_sdk': 'BrowserSDK',
-      'ui': 'UI',
-      'object_ui': 'ObjectUI',
-      'perf_ui': 'PerfUI',
-      'har_importer': 'HARImporter',
-      'sdk_test_runner': 'SDKTestRunner',
-      'cpu_profiler_test_runner': 'CPUProfilerTestRunner'
-    };
-    const namespace = specialCases[this._name] || this._name.split('_').map(a => a.substring(0, 1).toUpperCase() + a.substring(1)).join('');
-    self[namespace] = self[namespace] || {};
-    // clang-format on
-    return Runtime._loadScriptsPromise(this._descriptor.scripts.map(this._modularizeURL, this), this._remoteBase());
-  }
-
-  /**
-   * @param {string} resourceName
-   */
-  _modularizeURL(resourceName) {
-    return Runtime.normalizePath(this._name + '/' + resourceName);
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  _remoteBase() {
-    return !Runtime.queryParam('debugFrontend') && this._descriptor.remote && Runtime._remoteBase || undefined;
-  }
-
-  /**
-   * @param {string} value
-   * @return {string}
-   */
-  substituteURL(value) {
-    const base = this._remoteBase() || '';
-    return value.replace(/@url\(([^\)]*?)\)/g, convertURL.bind(this));
-
-    function convertURL(match, url) {
-      return base + this._modularizeURL(url);
-    }
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Runtime.Extension = class {
-  /**
-   * @param {!Runtime.Module} module
-   * @param {!Runtime.ExtensionDescriptor} descriptor
-   */
-  constructor(module, descriptor) {
-    this._module = module;
-    this._descriptor = descriptor;
-
-    this._type = descriptor.type;
-    this._hasTypeClass = this._type.charAt(0) === '@';
-
-    /**
-     * @type {?string}
-     */
-    this._className = descriptor.className || null;
-    this._factoryName = descriptor.factoryName || null;
-  }
-
-  /**
-   * @return {!Object}
-   */
-  descriptor() {
-    return this._descriptor;
-  }
-
-  /**
-   * @return {!Runtime.Module}
-   */
-  module() {
-    return this._module;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  enabled() {
-    return this._module.enabled() && Runtime._isDescriptorEnabled(this.descriptor());
-  }
-
-  /**
-   * @return {?function(new:Object)}
-   */
-  _typeClass() {
-    if (!this._hasTypeClass)
-      return null;
-    return this._module._manager._resolve(this._type.substring(1));
-  }
-
-  /**
-   * @param {?Object} context
-   * @return {boolean}
-   */
-  isApplicable(context) {
-    return this._module._manager.isExtensionApplicableToContext(this, context);
-  }
-
-  /**
-   * @return {!Promise.<!Object>}
-   */
-  instance() {
-    return this._module._loadPromise().then(this._createInstance.bind(this));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canInstantiate() {
-    return !!(this._className || this._factoryName);
-  }
-
-  /**
-   * @return {!Object}
-   */
-  _createInstance() {
-    const className = this._className || this._factoryName;
-    if (!className)
-      throw new Error('Could not instantiate extension with no class');
-    const constructorFunction = self.eval(/** @type {string} */ (className));
-    if (!(constructorFunction instanceof Function))
-      throw new Error('Could not instantiate: ' + className);
-    if (this._className)
-      return this._module._manager.sharedInstance(constructorFunction);
-    return new constructorFunction(this);
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    // FIXME: should be Common.UIString() but runtime is not l10n aware yet.
-    return this._descriptor['title-' + Runtime._platform] || this._descriptor['title'];
-  }
-
-  /**
-   * @param {function(new:Object)} contextType
-   * @return {boolean}
-   */
-  hasContextType(contextType) {
-    const contextTypes = this.descriptor().contextTypes;
-    if (!contextTypes)
-      return false;
-    for (let i = 0; i < contextTypes.length; ++i) {
-      if (contextType === this._module._manager._resolve(contextTypes[i]))
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Runtime.ExperimentsSupport = class {
-  constructor() {
-    this._supportEnabled = Runtime.queryParam('experiments') !== null;
-    this._experiments = [];
-    this._experimentNames = {};
-    this._enabledTransiently = {};
-  }
-
-  /**
-   * @return {!Array.<!Runtime.Experiment>}
-   */
-  allConfigurableExperiments() {
-    const result = [];
-    for (let i = 0; i < this._experiments.length; i++) {
-      const experiment = this._experiments[i];
-      if (!this._enabledTransiently[experiment.name])
-        result.push(experiment);
-    }
-    return result;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  supportEnabled() {
-    return this._supportEnabled;
-  }
-
-  /**
-   * @param {!Object} value
-   */
-  _setExperimentsSetting(value) {
-    if (!self.localStorage)
-      return;
-    self.localStorage['experiments'] = JSON.stringify(value);
-  }
-
-  /**
-   * @param {string} experimentName
-   * @param {string} experimentTitle
-   * @param {boolean=} hidden
-   */
-  register(experimentName, experimentTitle, hidden) {
-    Runtime._assert(!this._experimentNames[experimentName], 'Duplicate registration of experiment ' + experimentName);
-    this._experimentNames[experimentName] = true;
-    this._experiments.push(new Runtime.Experiment(this, experimentName, experimentTitle, !!hidden));
-  }
-
-  /**
-   * @param {string} experimentName
-   * @return {boolean}
-   */
-  isEnabled(experimentName) {
-    this._checkExperiment(experimentName);
-
-    if (this._enabledTransiently[experimentName])
-      return true;
-    if (!this.supportEnabled())
-      return false;
-
-    return !!Runtime._experimentsSetting()[experimentName];
-  }
-
-  /**
-   * @param {string} experimentName
-   * @param {boolean} enabled
-   */
-  setEnabled(experimentName, enabled) {
-    this._checkExperiment(experimentName);
-    const experimentsSetting = Runtime._experimentsSetting();
-    experimentsSetting[experimentName] = enabled;
-    this._setExperimentsSetting(experimentsSetting);
-  }
-
-  /**
-   * @param {!Array.<string>} experimentNames
-   */
-  setDefaultExperiments(experimentNames) {
-    for (let i = 0; i < experimentNames.length; ++i) {
-      this._checkExperiment(experimentNames[i]);
-      this._enabledTransiently[experimentNames[i]] = true;
-    }
-  }
-
-  /**
-   * @param {string} experimentName
-   */
-  enableForTest(experimentName) {
-    this._checkExperiment(experimentName);
-    this._enabledTransiently[experimentName] = true;
-  }
-
-  clearForTest() {
-    this._experiments = [];
-    this._experimentNames = {};
-    this._enabledTransiently = {};
-  }
-
-  cleanUpStaleExperiments() {
-    const experimentsSetting = Runtime._experimentsSetting();
-    const cleanedUpExperimentSetting = {};
-    for (let i = 0; i < this._experiments.length; ++i) {
-      const experimentName = this._experiments[i].name;
-      if (experimentsSetting[experimentName])
-        cleanedUpExperimentSetting[experimentName] = true;
-    }
-    this._setExperimentsSetting(cleanedUpExperimentSetting);
-  }
-
-  /**
-   * @param {string} experimentName
-   */
-  _checkExperiment(experimentName) {
-    Runtime._assert(this._experimentNames[experimentName], 'Unknown experiment ' + experimentName);
-  }
-};
-
-/**
- * @unrestricted
- */
-Runtime.Experiment = class {
-  /**
-   * @param {!Runtime.ExperimentsSupport} experiments
-   * @param {string} name
-   * @param {string} title
-   * @param {boolean} hidden
-   */
-  constructor(experiments, name, title, hidden) {
-    this.name = name;
-    this.title = title;
-    this.hidden = hidden;
-    this._experiments = experiments;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEnabled() {
-    return this._experiments.isEnabled(this.name);
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._experiments.setEnabled(this.name, enabled);
-  }
-};
-
-{
-  (function parseQueryParameters() {
-    const queryParams = Runtime.queryParamsString();
-    if (!queryParams)
-      return;
-    const params = queryParams.substring(1).split('&');
-    for (let i = 0; i < params.length; ++i) {
-      const pair = params[i].split('=');
-      const name = pair.shift();
-      Runtime._queryParamsObject[name] = pair.join('=');
-    }
-  })();
-}
-
-// This must be constructed after the query parameters have been parsed.
-Runtime.experiments = new Runtime.ExperimentsSupport();
-
-/** @type {Function} */
-Runtime._runtimeReadyPromiseCallback;
-Runtime._runtimeReadyPromise = new Promise(fulfil => Runtime._runtimeReadyPromiseCallback = fulfil);
-/**
- * @type {?string}
- */
-Runtime._remoteBase;
-(function validateRemoteBase() {
-  if (location.href.startsWith('chrome-devtools://devtools/bundled/') && Runtime.queryParam('remoteBase')) {
-    const versionMatch = /\/serve_file\/(@[0-9a-zA-Z]+)\/?$/.exec(Runtime.queryParam('remoteBase'));
-    if (versionMatch)
-      Runtime._remoteBase = `${location.origin}/remote/serve_file/${versionMatch[1]}/`;
-  }
-})();
-
-
-/**
- * @interface
- */
-function ServicePort() {
-}
-
-ServicePort.prototype = {
-  /**
-   * @param {function(string)} messageHandler
-   * @param {function(string)} closeHandler
-   */
-  setHandlers(messageHandler, closeHandler) {},
-
-  /**
-   * @param {string} message
-   * @return {!Promise<boolean>}
-   */
-  send(message) {},
-
-  /**
-   * @return {!Promise<boolean>}
-   */
-  close() {}
-};
-
-/** @type {!Runtime} */
-var runtime;  // eslint-disable-line
diff --git a/front_end/Tests.js b/front_end/Tests.js
deleted file mode 100644
index d66f75a..0000000
--- a/front_end/Tests.js
+++ /dev/null
@@ -1,1334 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/* eslint-disable indent */
-
-/**
- * @fileoverview This file contains small testing framework along with the
- * test suite for the frontend. These tests are a part of the continues build
- * and are executed by the devtools_sanity_unittest.cc as a part of the
- * Interactive UI Test suite.
- * FIXME: change field naming style to use trailing underscore.
- */
-
-(function createTestSuite(window) {
-
-  /**
-   * @unrestricted
-   */
-  const TestSuite = class {
-    /**
-     * Test suite for interactive UI tests.
-     * @param {Object} domAutomationController DomAutomationController instance.
-     */
-    constructor(domAutomationController) {
-      this.domAutomationController_ = domAutomationController;
-      this.controlTaken_ = false;
-      this.timerId_ = -1;
-      this._asyncInvocationId = 0;
-    }
-
-    /**
-     * Key event with given key identifier.
-     */
-    static createKeyEvent(key) {
-      return new KeyboardEvent('keydown', {bubbles: true, cancelable: true, key: key});
-    }
-  };
-
-  /**
-   * Reports test failure.
-   * @param {string} message Failure description.
-   */
-  TestSuite.prototype.fail = function(message) {
-    if (this.controlTaken_)
-      this.reportFailure_(message);
-    else
-      throw message;
-  };
-
-  /**
-   * Equals assertion tests that expected === actual.
-   * @param {!Object|boolean} expected Expected object.
-   * @param {!Object|boolean} actual Actual object.
-   * @param {string} opt_message User message to print if the test fails.
-   */
-  TestSuite.prototype.assertEquals = function(expected, actual, opt_message) {
-    if (expected !== actual) {
-      let message = 'Expected: \'' + expected + '\', but was \'' + actual + '\'';
-      if (opt_message)
-        message = opt_message + '(' + message + ')';
-      this.fail(message);
-    }
-  };
-
-  /**
-   * True assertion tests that value == true.
-   * @param {!Object} value Actual object.
-   * @param {string} opt_message User message to print if the test fails.
-   */
-  TestSuite.prototype.assertTrue = function(value, opt_message) {
-    this.assertEquals(true, !!value, opt_message);
-  };
-
-  /**
-   * Takes control over execution.
-   */
-  TestSuite.prototype.takeControl = function() {
-    this.controlTaken_ = true;
-    // Set up guard timer.
-    const self = this;
-    this.timerId_ = setTimeout(function() {
-      self.reportFailure_('Timeout exceeded: 20 sec');
-    }, 20000);
-  };
-
-  /**
-   * Releases control over execution.
-   */
-  TestSuite.prototype.releaseControl = function() {
-    if (this.timerId_ !== -1) {
-      clearTimeout(this.timerId_);
-      this.timerId_ = -1;
-    }
-    this.controlTaken_ = false;
-    this.reportOk_();
-  };
-
-  /**
-   * Async tests use this one to report that they are completed.
-   */
-  TestSuite.prototype.reportOk_ = function() {
-    this.domAutomationController_.send('[OK]');
-  };
-
-  /**
-   * Async tests use this one to report failures.
-   */
-  TestSuite.prototype.reportFailure_ = function(error) {
-    if (this.timerId_ !== -1) {
-      clearTimeout(this.timerId_);
-      this.timerId_ = -1;
-    }
-    this.domAutomationController_.send('[FAILED] ' + error);
-  };
-
-  /**
-   * Run specified test on a fresh instance of the test suite.
-   * @param {Array<string>} args method name followed by its parameters.
-   */
-  TestSuite.prototype.dispatchOnTestSuite = function(args) {
-    const methodName = args.shift();
-    try {
-      this[methodName].apply(this, args);
-      if (!this.controlTaken_)
-        this.reportOk_();
-    } catch (e) {
-      this.reportFailure_(e);
-    }
-  };
-
-  /**
-   * Wrap an async method with TestSuite.{takeControl(), releaseControl()}
-   * and invoke TestSuite.reportOk_ upon completion.
-   * @param {Array<string>} args method name followed by its parameters.
-   */
-  TestSuite.prototype.waitForAsync = function(var_args) {
-    const args = Array.prototype.slice.call(arguments);
-    this.takeControl();
-    args.push(this.releaseControl.bind(this));
-    this.dispatchOnTestSuite(args);
-  };
-
-  /**
-   * Overrides the method with specified name until it's called first time.
-   * @param {!Object} receiver An object whose method to override.
-   * @param {string} methodName Name of the method to override.
-   * @param {!Function} override A function that should be called right after the
-   *     overridden method returns.
-   * @param {?boolean} opt_sticky Whether restore original method after first run
-   *     or not.
-   */
-  TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky) {
-    const orig = receiver[methodName];
-    if (typeof orig !== 'function')
-      this.fail('Cannot find method to override: ' + methodName);
-    const test = this;
-    receiver[methodName] = function(var_args) {
-      let result;
-      try {
-        result = orig.apply(this, arguments);
-      } finally {
-        if (!opt_sticky)
-          receiver[methodName] = orig;
-      }
-      // In case of exception the override won't be called.
-      try {
-        override.apply(this, arguments);
-      } catch (e) {
-        test.fail('Exception in overriden method \'' + methodName + '\': ' + e);
-      }
-      return result;
-    };
-  };
-
-  /**
-   * Waits for current throttler invocations, if any.
-   * @param {!Common.Throttler} throttler
-   * @param {function()} callback
-   */
-  TestSuite.prototype.waitForThrottler = function(throttler, callback) {
-    const test = this;
-    let scheduleShouldFail = true;
-    test.addSniffer(throttler, 'schedule', onSchedule);
-
-    function hasSomethingScheduled() {
-      return throttler._isRunningProcess || throttler._process;
-    }
-
-    function checkState() {
-      if (!hasSomethingScheduled()) {
-        scheduleShouldFail = false;
-        callback();
-        return;
-      }
-
-      test.addSniffer(throttler, '_processCompletedForTests', checkState);
-    }
-
-    function onSchedule() {
-      if (scheduleShouldFail)
-        test.fail('Unexpected Throttler.schedule');
-    }
-
-    checkState();
-  };
-
-  /**
-   * @param {string} panelName Name of the panel to show.
-   */
-  TestSuite.prototype.showPanel = function(panelName) {
-    return UI.inspectorView.showPanel(panelName);
-  };
-
-  // UI Tests
-
-  /**
-   * Tests that scripts tab can be open and populated with inspected scripts.
-   */
-  TestSuite.prototype.testShowScriptsTab = function() {
-    const test = this;
-    this.showPanel('sources').then(function() {
-      // There should be at least main page script.
-      this._waitUntilScriptsAreParsed(['debugger_test_page.html'], function() {
-        test.releaseControl();
-      });
-    }.bind(this));
-    // Wait until all scripts are added to the debugger.
-    this.takeControl();
-  };
-
-  /**
-   * Tests that scripts tab is populated with inspected scripts even if it
-   * hadn't been shown by the moment inspected paged refreshed.
-   * @see http://crbug.com/26312
-   */
-  TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function() {
-    const test = this;
-    const debuggerModel = SDK.targetManager.mainTarget().model(SDK.DebuggerModel);
-    debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, waitUntilScriptIsParsed);
-
-    this.showPanel('elements').then(function() {
-      // Reload inspected page. It will reset the debugger agent.
-      test.evaluateInConsole_('window.location.reload(true);', function(resultText) {});
-    });
-
-    function waitUntilScriptIsParsed() {
-      debuggerModel.removeEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, waitUntilScriptIsParsed);
-      test.showPanel('sources').then(function() {
-        test._waitUntilScriptsAreParsed(['debugger_test_page.html'], function() {
-          test.releaseControl();
-        });
-      });
-    }
-
-    // Wait until all scripts are added to the debugger.
-    this.takeControl();
-  };
-
-  /**
-   * Tests that scripts list contains content scripts.
-   */
-  TestSuite.prototype.testContentScriptIsPresent = function() {
-    const test = this;
-    this.showPanel('sources').then(function() {
-      test._waitUntilScriptsAreParsed(['page_with_content_script.html', 'simple_content_script.js'], function() {
-        test.releaseControl();
-      });
-    });
-
-    // Wait until all scripts are added to the debugger.
-    this.takeControl();
-  };
-
-  /**
-   * Tests that scripts are not duplicaed on Scripts tab switch.
-   */
-  TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() {
-    const test = this;
-
-    function switchToElementsTab() {
-      test.showPanel('elements').then(function() {
-        setTimeout(switchToScriptsTab, 0);
-      });
-    }
-
-    function switchToScriptsTab() {
-      test.showPanel('sources').then(function() {
-        setTimeout(checkScriptsPanel, 0);
-      });
-    }
-
-    function checkScriptsPanel() {
-      test.assertTrue(test._scriptsAreParsed(['debugger_test_page.html']), 'Some scripts are missing.');
-      checkNoDuplicates();
-      test.releaseControl();
-    }
-
-    function checkNoDuplicates() {
-      const uiSourceCodes = test.nonAnonymousUISourceCodes_();
-      for (let i = 0; i < uiSourceCodes.length; i++) {
-        for (let j = i + 1; j < uiSourceCodes.length; j++) {
-          test.assertTrue(
-              uiSourceCodes[i].url() !== uiSourceCodes[j].url(),
-              'Found script duplicates: ' + test.uiSourceCodesToString_(uiSourceCodes));
-        }
-      }
-    }
-
-    this.showPanel('sources').then(function() {
-      test._waitUntilScriptsAreParsed(['debugger_test_page.html'], function() {
-        checkNoDuplicates();
-        setTimeout(switchToElementsTab, 0);
-      });
-    });
-
-    // Wait until all scripts are added to the debugger.
-    this.takeControl();
-  };
-
-  // Tests that debugger works correctly if pause event occurs when DevTools
-  // frontend is being loaded.
-  TestSuite.prototype.testPauseWhenLoadingDevTools = function() {
-    const debuggerModel = SDK.targetManager.mainTarget().model(SDK.DebuggerModel);
-    if (debuggerModel.debuggerPausedDetails)
-      return;
-
-    this.showPanel('sources').then(function() {
-      // Script execution can already be paused.
-
-      this._waitForScriptPause(this.releaseControl.bind(this));
-    }.bind(this));
-
-    this.takeControl();
-  };
-
-  // Tests that pressing "Pause" will pause script execution if the script
-  // is already running.
-  TestSuite.prototype.testPauseWhenScriptIsRunning = function() {
-    this.showPanel('sources').then(function() {
-      this.evaluateInConsole_('setTimeout("handleClick()", 0)', didEvaluateInConsole.bind(this));
-    }.bind(this));
-
-    function didEvaluateInConsole(resultText) {
-      this.assertTrue(!isNaN(resultText), 'Failed to get timer id: ' + resultText);
-      // Wait for some time to make sure that inspected page is running the
-      // infinite loop.
-      setTimeout(testScriptPause.bind(this), 300);
-    }
-
-    function testScriptPause() {
-      // The script should be in infinite loop. Click "Pause" button to
-      // pause it and wait for the result.
-      UI.panels.sources._togglePause();
-
-      this._waitForScriptPause(this.releaseControl.bind(this));
-    }
-
-    this.takeControl();
-  };
-
-  /**
-   * Tests network size.
-   */
-  TestSuite.prototype.testNetworkSize = function() {
-    const test = this;
-
-    function finishRequest(request, finishTime) {
-      test.assertEquals(25, request.resourceSize, 'Incorrect total data length');
-      test.releaseControl();
-    }
-
-    this.addSniffer(SDK.NetworkDispatcher.prototype, '_finishNetworkRequest', finishRequest);
-
-    // Reload inspected page to sniff network events
-    test.evaluateInConsole_('window.location.reload(true);', function(resultText) {});
-
-    this.takeControl();
-  };
-
-  /**
-   * Tests network sync size.
-   */
-  TestSuite.prototype.testNetworkSyncSize = function() {
-    const test = this;
-
-    function finishRequest(request, finishTime) {
-      test.assertEquals(25, request.resourceSize, 'Incorrect total data length');
-      test.releaseControl();
-    }
-
-    this.addSniffer(SDK.NetworkDispatcher.prototype, '_finishNetworkRequest', finishRequest);
-
-    // Send synchronous XHR to sniff network events
-    test.evaluateInConsole_(
-        'let xhr = new XMLHttpRequest(); xhr.open("GET", "chunked", false); xhr.send(null);', function() {});
-
-    this.takeControl();
-  };
-
-  /**
-   * Tests network raw headers text.
-   */
-  TestSuite.prototype.testNetworkRawHeadersText = function() {
-    const test = this;
-
-    function finishRequest(request, finishTime) {
-      if (!request.responseHeadersText)
-        test.fail('Failure: resource does not have response headers text');
-      const index = request.responseHeadersText.indexOf('Date:');
-      test.assertEquals(
-          112, request.responseHeadersText.substring(index).length, 'Incorrect response headers text length');
-      test.releaseControl();
-    }
-
-    this.addSniffer(SDK.NetworkDispatcher.prototype, '_finishNetworkRequest', finishRequest);
-
-    // Reload inspected page to sniff network events
-    test.evaluateInConsole_('window.location.reload(true);', function(resultText) {});
-
-    this.takeControl();
-  };
-
-  /**
-   * Tests network timing.
-   */
-  TestSuite.prototype.testNetworkTiming = function() {
-    const test = this;
-
-    function finishRequest(request, finishTime) {
-      // Setting relaxed expectations to reduce flakiness.
-      // Server sends headers after 100ms, then sends data during another 100ms.
-      // We expect these times to be measured at least as 70ms.
-      test.assertTrue(
-          request.timing.receiveHeadersEnd - request.timing.connectStart >= 70,
-          'Time between receiveHeadersEnd and connectStart should be >=70ms, but was ' +
-              'receiveHeadersEnd=' + request.timing.receiveHeadersEnd + ', connectStart=' +
-              request.timing.connectStart + '.');
-      test.assertTrue(
-          request.responseReceivedTime - request.startTime >= 0.07,
-          'Time between responseReceivedTime and startTime should be >=0.07s, but was ' +
-              'responseReceivedTime=' + request.responseReceivedTime + ', startTime=' + request.startTime + '.');
-      test.assertTrue(
-          request.endTime - request.startTime >= 0.14,
-          'Time between endTime and startTime should be >=0.14s, but was ' +
-              'endtime=' + request.endTime + ', startTime=' + request.startTime + '.');
-
-      test.releaseControl();
-    }
-
-    this.addSniffer(SDK.NetworkDispatcher.prototype, '_finishNetworkRequest', finishRequest);
-
-    // Reload inspected page to sniff network events
-    test.evaluateInConsole_('window.location.reload(true);', function(resultText) {});
-
-    this.takeControl();
-  };
-
-  TestSuite.prototype.testPushTimes = function(url) {
-    const test = this;
-    let pendingRequestCount = 2;
-
-    function finishRequest(request, finishTime) {
-      test.assertTrue(
-          typeof request.timing.pushStart === 'number' && request.timing.pushStart > 0,
-          `pushStart is invalid: ${request.timing.pushStart}`);
-      test.assertTrue(typeof request.timing.pushEnd === 'number', `pushEnd is invalid: ${request.timing.pushEnd}`);
-      test.assertTrue(request.timing.pushStart < request.startTime, 'pushStart should be before startTime');
-      if (request.url().endsWith('?pushUseNullEndTime')) {
-        test.assertTrue(request.timing.pushEnd === 0, `pushEnd should be 0 but is ${request.timing.pushEnd}`);
-      } else {
-        test.assertTrue(
-            request.timing.pushStart < request.timing.pushEnd,
-            `pushStart should be before pushEnd (${request.timing.pushStart} >= ${request.timing.pushEnd})`);
-        // The below assertion is just due to the way we generate times in the moch URLRequestJob and is not generally an invariant.
-        test.assertTrue(request.timing.pushEnd < request.endTime, 'pushEnd should be before endTime');
-        test.assertTrue(request.startTime < request.timing.pushEnd, 'pushEnd should be after startTime');
-      }
-      if (!--pendingRequestCount)
-        test.releaseControl();
-    }
-
-    this.addSniffer(SDK.NetworkDispatcher.prototype, '_finishNetworkRequest', finishRequest, true);
-
-    test.evaluateInConsole_('addImage(\'' + url + '\')', function(resultText) {});
-    test.evaluateInConsole_('addImage(\'' + url + '?pushUseNullEndTime\')', function(resultText) {});
-    this.takeControl();
-  };
-
-  TestSuite.prototype.testConsoleOnNavigateBack = function() {
-
-    function filteredMessages() {
-      return SDK.consoleModel.messages().filter(a => a.source !== SDK.ConsoleMessage.MessageSource.Violation);
-    }
-
-    if (filteredMessages().length === 1)
-      firstConsoleMessageReceived.call(this, null);
-    else
-      SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this);
-
-
-    function firstConsoleMessageReceived(event) {
-      if (event && event.data.source === SDK.ConsoleMessage.MessageSource.Violation)
-        return;
-      SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this);
-      this.evaluateInConsole_('clickLink();', didClickLink.bind(this));
-    }
-
-    function didClickLink() {
-      // Check that there are no new messages(command is not a message).
-      this.assertEquals(3, filteredMessages().length);
-      this.evaluateInConsole_('history.back();', didNavigateBack.bind(this));
-    }
-
-    function didNavigateBack() {
-      // Make sure navigation completed and possible console messages were pushed.
-      this.evaluateInConsole_('void 0;', didCompleteNavigation.bind(this));
-    }
-
-    function didCompleteNavigation() {
-      this.assertEquals(7, filteredMessages().length);
-      this.releaseControl();
-    }
-
-    this.takeControl();
-  };
-
-  TestSuite.prototype.testSharedWorker = function() {
-    function didEvaluateInConsole(resultText) {
-      this.assertEquals('2011', resultText);
-      this.releaseControl();
-    }
-    this.evaluateInConsole_('globalVar', didEvaluateInConsole.bind(this));
-    this.takeControl();
-  };
-
-  TestSuite.prototype.testPauseInSharedWorkerInitialization1 = function() {
-    // Make sure the worker is loaded.
-    this.takeControl();
-    this._waitForTargets(2, callback.bind(this));
-
-    function callback() {
-      Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches(this.releaseControl.bind(this));
-    }
-  };
-
-  TestSuite.prototype.testPauseInSharedWorkerInitialization2 = function() {
-    this.takeControl();
-    this._waitForTargets(2, callback.bind(this));
-
-    function callback() {
-      const debuggerModel = SDK.targetManager.models(SDK.DebuggerModel)[0];
-      if (debuggerModel.isPaused()) {
-        this.releaseControl();
-        return;
-      }
-      this._waitForScriptPause(this.releaseControl.bind(this));
-    }
-  };
-
-  TestSuite.prototype.enableTouchEmulation = function() {
-    const deviceModeModel = new Emulation.DeviceModeModel(function() {});
-    deviceModeModel._target = SDK.targetManager.mainTarget();
-    deviceModeModel._applyTouch(true, true);
-  };
-
-  TestSuite.prototype.waitForDebuggerPaused = function() {
-    const debuggerModel = SDK.targetManager.mainTarget().model(SDK.DebuggerModel);
-    if (debuggerModel.debuggerPausedDetails)
-      return;
-
-    this.takeControl();
-    this._waitForScriptPause(this.releaseControl.bind(this));
-  };
-
-  TestSuite.prototype.switchToPanel = function(panelName) {
-    this.showPanel(panelName).then(this.releaseControl.bind(this));
-    this.takeControl();
-  };
-
-  // Regression test for crbug.com/370035.
-  TestSuite.prototype.testDeviceMetricsOverrides = function() {
-    function dumpPageMetrics() {
-      return JSON.stringify(
-          {width: window.innerWidth, height: window.innerHeight, deviceScaleFactor: window.devicePixelRatio});
-    }
-
-    const test = this;
-
-    async function testOverrides(params, metrics, callback) {
-      await SDK.targetManager.mainTarget().emulationAgent().invoke_setDeviceMetricsOverride(params);
-      test.evaluateInConsole_('(' + dumpPageMetrics.toString() + ')()', checkMetrics);
-
-      function checkMetrics(consoleResult) {
-        test.assertEquals(
-            '"' + JSON.stringify(metrics) + '"', consoleResult, 'Wrong metrics for params: ' + JSON.stringify(params));
-        callback();
-      }
-    }
-
-    function step1() {
-      testOverrides(
-          {width: 1200, height: 1000, deviceScaleFactor: 1, mobile: false, fitWindow: true},
-          {width: 1200, height: 1000, deviceScaleFactor: 1}, step2);
-    }
-
-    function step2() {
-      testOverrides(
-          {width: 1200, height: 1000, deviceScaleFactor: 1, mobile: false, fitWindow: false},
-          {width: 1200, height: 1000, deviceScaleFactor: 1}, step3);
-    }
-
-    function step3() {
-      testOverrides(
-          {width: 1200, height: 1000, deviceScaleFactor: 3, mobile: false, fitWindow: true},
-          {width: 1200, height: 1000, deviceScaleFactor: 3}, step4);
-    }
-
-    function step4() {
-      testOverrides(
-          {width: 1200, height: 1000, deviceScaleFactor: 3, mobile: false, fitWindow: false},
-          {width: 1200, height: 1000, deviceScaleFactor: 3}, finish);
-    }
-
-    function finish() {
-      test.releaseControl();
-    }
-
-    test.takeControl();
-    step1();
-  };
-
-  TestSuite.prototype.testDispatchKeyEventShowsAutoFill = function() {
-    const test = this;
-    let receivedReady = false;
-
-    function signalToShowAutofill() {
-      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-          {type: 'rawKeyDown', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
-      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-          {type: 'keyUp', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
-    }
-
-    function selectTopAutoFill() {
-      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-          {type: 'rawKeyDown', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
-      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-          {type: 'keyUp', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
-      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-          {type: 'rawKeyDown', key: 'Enter', windowsVirtualKeyCode: 13, nativeVirtualKeyCode: 13});
-      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-          {type: 'keyUp', key: 'Enter', windowsVirtualKeyCode: 13, nativeVirtualKeyCode: 13});
-
-      test.evaluateInConsole_('document.getElementById("name").value', onResultOfInput);
-    }
-
-    function onResultOfInput(value) {
-      // Console adds "" around the response.
-      test.assertEquals('"Abbf"', value);
-      test.releaseControl();
-    }
-
-    function onConsoleMessage(event) {
-      const message = event.data.messageText;
-      if (message === 'ready' && !receivedReady) {
-        receivedReady = true;
-        signalToShowAutofill();
-      }
-      // This log comes from the browser unittest code.
-      if (message === 'didShowSuggestions')
-        selectTopAutoFill();
-    }
-
-    this.takeControl();
-
-    // It is possible for the ready console messagage to be already received but not handled
-    // or received later. This ensures we can catch both cases.
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
-
-    const messages = SDK.consoleModel.messages();
-    if (messages.length) {
-      const text = messages[0].messageText;
-      this.assertEquals('ready', text);
-      signalToShowAutofill();
-    }
-  };
-
-  TestSuite.prototype.testDispatchKeyEventDoesNotCrash = function() {
-    SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-        {type: 'rawKeyDown', windowsVirtualKeyCode: 0x23, key: 'End'});
-    SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
-        {type: 'keyUp', windowsVirtualKeyCode: 0x23, key: 'End'});
-  };
-
-  // Simple sanity check to make sure network throttling is wired up
-  // See crbug.com/747724
-  TestSuite.prototype.testOfflineNetworkConditions = async function() {
-    const test = this;
-    SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.OfflineConditions);
-
-    function finishRequest(request) {
-      test.assertEquals(
-          'net::ERR_INTERNET_DISCONNECTED', request.localizedFailDescription, 'Request should have failed');
-      test.releaseControl();
-    }
-
-    this.addSniffer(SDK.NetworkDispatcher.prototype, '_finishNetworkRequest', finishRequest);
-
-    test.takeControl();
-    test.evaluateInConsole_('window.location.reload(true);', function(resultText) {});
-  };
-
-  TestSuite.prototype.testEmulateNetworkConditions = function() {
-    const test = this;
-
-    function testPreset(preset, messages, next) {
-      function onConsoleMessage(event) {
-        const index = messages.indexOf(event.data.messageText);
-        if (index === -1) {
-          test.fail('Unexpected message: ' + event.data.messageText);
-          return;
-        }
-
-        messages.splice(index, 1);
-        if (!messages.length) {
-          SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
-          next();
-        }
-      }
-
-      SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
-      SDK.multitargetNetworkManager.setNetworkConditions(preset);
-    }
-
-    test.takeControl();
-    step1();
-
-    function step1() {
-      testPreset(
-          MobileThrottling.networkPresets[2],
-          [
-            'offline event: online = false', 'connection change event: type = none; downlinkMax = 0; effectiveType = 4g'
-          ],
-          step2);
-    }
-
-    function step2() {
-      testPreset(
-          MobileThrottling.networkPresets[1],
-          [
-            'online event: online = true',
-            'connection change event: type = cellular; downlinkMax = 0.390625; effectiveType = 2g'
-          ],
-          step3);
-    }
-
-    function step3() {
-      testPreset(
-          MobileThrottling.networkPresets[0],
-          ['connection change event: type = cellular; downlinkMax = 1.4400000000000002; effectiveType = 3g'],
-          test.releaseControl.bind(test));
-    }
-  };
-
-  TestSuite.prototype.testScreenshotRecording = function() {
-    const test = this;
-
-    function performActionsInPage(callback) {
-      let count = 0;
-      const div = document.createElement('div');
-      div.setAttribute('style', 'left: 0px; top: 0px; width: 100px; height: 100px; position: absolute;');
-      document.body.appendChild(div);
-      requestAnimationFrame(frame);
-      function frame() {
-        const color = [0, 0, 0];
-        color[count % 3] = 255;
-        div.style.backgroundColor = 'rgb(' + color.join(',') + ')';
-        if (++count > 10)
-          requestAnimationFrame(callback);
-        else
-          requestAnimationFrame(frame);
-      }
-    }
-
-    const captureFilmStripSetting = Common.settings.createSetting('timelineCaptureFilmStrip', false);
-    captureFilmStripSetting.set(true);
-    test.evaluateInConsole_(performActionsInPage.toString(), function() {});
-    test.invokeAsyncWithTimeline_('performActionsInPage', onTimelineDone);
-
-    function onTimelineDone() {
-      captureFilmStripSetting.set(false);
-      const filmStripModel = UI.panels.timeline._performanceModel.filmStripModel();
-      const frames = filmStripModel.frames();
-      test.assertTrue(frames.length > 4 && typeof frames.length === 'number');
-      loadFrameImages(frames);
-    }
-
-    function loadFrameImages(frames) {
-      const readyImages = [];
-      for (const frame of frames)
-        frame.imageDataPromise().then(onGotImageData);
-
-      function onGotImageData(data) {
-        const image = new Image();
-        test.assertTrue(!!data, 'No image data for frame');
-        image.addEventListener('load', onLoad);
-        image.src = 'data:image/jpg;base64,' + data;
-      }
-
-      function onLoad(event) {
-        readyImages.push(event.target);
-        if (readyImages.length === frames.length)
-          validateImagesAndCompleteTest(readyImages);
-      }
-    }
-
-    function validateImagesAndCompleteTest(images) {
-      let redCount = 0;
-      let greenCount = 0;
-      let blueCount = 0;
-
-      const canvas = document.createElement('canvas');
-      const ctx = canvas.getContext('2d');
-      for (const image of images) {
-        test.assertTrue(image.naturalWidth > 10);
-        test.assertTrue(image.naturalHeight > 10);
-        canvas.width = image.naturalWidth;
-        canvas.height = image.naturalHeight;
-        ctx.drawImage(image, 0, 0);
-        const data = ctx.getImageData(0, 0, 1, 1);
-        const color = Array.prototype.join.call(data.data, ',');
-        if (data.data[0] > 200)
-          redCount++;
-        else if (data.data[1] > 200)
-          greenCount++;
-        else if (data.data[2] > 200)
-          blueCount++;
-        else
-          test.fail('Unexpected color: ' + color);
-      }
-      test.assertTrue(redCount && greenCount && blueCount, 'Color sanity check failed');
-      test.releaseControl();
-    }
-
-    test.takeControl();
-  };
-
-  TestSuite.prototype.testSettings = function() {
-    const test = this;
-
-    createSettings();
-    test.takeControl();
-    setTimeout(reset, 0);
-
-    function createSettings() {
-      const localSetting = Common.settings.createLocalSetting('local', undefined);
-      localSetting.set({s: 'local', n: 1});
-      const globalSetting = Common.settings.createSetting('global', undefined);
-      globalSetting.set({s: 'global', n: 2});
-    }
-
-    function reset() {
-      Runtime.experiments.clearForTest();
-      InspectorFrontendHost.getPreferences(gotPreferences);
-    }
-
-    function gotPreferences(prefs) {
-      Main.Main._instanceForTest._createSettings(prefs);
-
-      const localSetting = Common.settings.createLocalSetting('local', undefined);
-      test.assertEquals('object', typeof localSetting.get());
-      test.assertEquals('local', localSetting.get().s);
-      test.assertEquals(1, localSetting.get().n);
-      const globalSetting = Common.settings.createSetting('global', undefined);
-      test.assertEquals('object', typeof globalSetting.get());
-      test.assertEquals('global', globalSetting.get().s);
-      test.assertEquals(2, globalSetting.get().n);
-      test.releaseControl();
-    }
-  };
-
-  TestSuite.prototype.testWindowInitializedOnNavigateBack = function() {
-    const test = this;
-    test.takeControl();
-    const messages = SDK.consoleModel.messages();
-    if (messages.length === 1)
-      checkMessages();
-    else
-      SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, checkMessages.bind(this), this);
-
-    function checkMessages() {
-      const messages = SDK.consoleModel.messages();
-      test.assertEquals(1, messages.length);
-      test.assertTrue(messages[0].messageText.indexOf('Uncaught') === -1);
-      test.releaseControl();
-    }
-  };
-
-  TestSuite.prototype.testConsoleContextNames = function() {
-    const test = this;
-    test.takeControl();
-    this.showPanel('console').then(() => this._waitForExecutionContexts(2, onExecutionContexts.bind(this)));
-
-    function onExecutionContexts() {
-      const consoleView = Console.ConsoleView.instance();
-      const selector = consoleView._consoleContextSelector;
-      const values = [];
-      for (const item of selector._items)
-        values.push(selector.titleFor(item));
-      test.assertEquals('top', values[0]);
-      test.assertEquals('Simple content script', values[1]);
-      test.releaseControl();
-    }
-  };
-
-  TestSuite.prototype.testRawHeadersWithHSTS = function(url) {
-    const test = this;
-    test.takeControl();
-    SDK.targetManager.addModelListener(
-        SDK.NetworkManager, SDK.NetworkManager.Events.ResponseReceived, onResponseReceived);
-
-    this.evaluateInConsole_(`
-      let img = document.createElement('img');
-      img.src = "${url}";
-      document.body.appendChild(img);
-    `, () => {});
-
-    let count = 0;
-    function onResponseReceived(event) {
-      const networkRequest = event.data;
-      if (!networkRequest.url().startsWith('http'))
-        return;
-      switch (++count) {
-        case 1:  // Original redirect
-          test.assertEquals(301, networkRequest.statusCode);
-          test.assertEquals('Moved Permanently', networkRequest.statusText);
-          test.assertTrue(url.endsWith(networkRequest.responseHeaderValue('Location')));
-          break;
-
-        case 2:  // HSTS internal redirect
-          test.assertTrue(networkRequest.url().startsWith('http://'));
-          test.assertEquals(undefined, networkRequest.requestHeadersText());
-          test.assertEquals(307, networkRequest.statusCode);
-          test.assertEquals('Internal Redirect', networkRequest.statusText);
-          test.assertEquals('HSTS', networkRequest.responseHeaderValue('Non-Authoritative-Reason'));
-          test.assertTrue(networkRequest.responseHeaderValue('Location').startsWith('https://'));
-          break;
-
-        case 3:  // Final response
-          test.assertTrue(networkRequest.url().startsWith('https://'));
-          test.assertTrue(networkRequest.requestHeaderValue('Referer').startsWith('http://127.0.0.1'));
-          test.assertEquals(200, networkRequest.statusCode);
-          test.assertEquals('OK', networkRequest.statusText);
-          test.assertEquals('132', networkRequest.responseHeaderValue('Content-Length'));
-          test.releaseControl();
-      }
-    }
-  };
-
-  TestSuite.prototype.testDOMWarnings = function() {
-    const messages = SDK.consoleModel.messages();
-    this.assertEquals(1, messages.length);
-    const expectedPrefix = '[DOM] Found 2 elements with non-unique id #dup:';
-    this.assertTrue(messages[0].messageText.startsWith(expectedPrefix));
-  };
-
-  TestSuite.prototype.waitForTestResultsInConsole = function() {
-    const messages = SDK.consoleModel.messages();
-    for (let i = 0; i < messages.length; ++i) {
-      const text = messages[i].messageText;
-      if (text === 'PASS')
-        return;
-      else if (/^FAIL/.test(text))
-        this.fail(text);  // This will throw.
-    }
-    // Neither PASS nor FAIL, so wait for more messages.
-    function onConsoleMessage(event) {
-      const text = event.data.messageText;
-      if (text === 'PASS')
-        this.releaseControl();
-      else if (/^FAIL/.test(text))
-        this.fail(text);
-    }
-
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
-    this.takeControl();
-  };
-
-  TestSuite.prototype._overrideMethod = function(receiver, methodName, override) {
-    const original = receiver[methodName];
-    if (typeof original !== 'function') {
-      this.fail(`TestSuite._overrideMethod: $[methodName] is not a function`);
-      return;
-    }
-    receiver[methodName] = function() {
-      let value;
-      try {
-        value = original.apply(receiver, arguments);
-      } finally {
-        receiver[methodName] = original;
-      }
-      override.apply(original, arguments);
-      return value;
-    };
-  };
-
-  TestSuite.prototype.startTimeline = function(callback) {
-    const test = this;
-    this.showPanel('timeline').then(function() {
-      const timeline = UI.panels.timeline;
-      test._overrideMethod(timeline, '_recordingStarted', callback);
-      timeline._toggleRecording();
-    });
-  };
-
-  TestSuite.prototype.stopTimeline = function(callback) {
-    const timeline = UI.panels.timeline;
-    this._overrideMethod(timeline, 'loadingComplete', callback);
-    timeline._toggleRecording();
-  };
-
-  TestSuite.prototype.invokePageFunctionAsync = function(functionName, opt_args, callback_is_always_last) {
-    const callback = arguments[arguments.length - 1];
-    const doneMessage = `DONE: ${functionName}.${++this._asyncInvocationId}`;
-    const argsString = arguments.length < 3 ?
-        '' :
-        Array.prototype.slice.call(arguments, 1, -1).map(arg => JSON.stringify(arg)).join(',') + ',';
-    this.evaluateInConsole_(
-        `${functionName}(${argsString} function() { console.log('${doneMessage}'); });`, function() {});
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage);
-
-    function onConsoleMessage(event) {
-      const text = event.data.messageText;
-      if (text === doneMessage) {
-        SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, onConsoleMessage);
-        callback();
-      }
-    }
-  };
-
-  TestSuite.prototype.invokeAsyncWithTimeline_ = function(functionName, callback) {
-    const test = this;
-
-    this.startTimeline(onRecordingStarted);
-
-    function onRecordingStarted() {
-      test.invokePageFunctionAsync(functionName, pageActionsDone);
-    }
-
-    function pageActionsDone() {
-      test.stopTimeline(callback);
-    }
-  };
-
-  TestSuite.prototype.enableExperiment = function(name) {
-    Runtime.experiments.enableForTest(name);
-  };
-
-  TestSuite.prototype.checkInputEventsPresent = function() {
-    const expectedEvents = new Set(arguments);
-    const model = UI.panels.timeline._performanceModel.timelineModel();
-    const asyncEvents = model.virtualThreads().find(thread => thread.isMainFrame).asyncEventsByGroup;
-    const input = asyncEvents.get(TimelineModel.TimelineModel.AsyncEventGroup.input) || [];
-    const prefix = 'InputLatency::';
-    for (const e of input) {
-      if (!e.name.startsWith(prefix))
-        continue;
-      if (e.steps.length < 2)
-        continue;
-      if (e.name.startsWith(prefix + 'Mouse') &&
-          typeof TimelineModel.TimelineData.forEvent(e.steps[0]).timeWaitingForMainThread !== 'number')
-        throw `Missing timeWaitingForMainThread on ${e.name}`;
-      expectedEvents.delete(e.name.substr(prefix.length));
-    }
-    if (expectedEvents.size)
-      throw 'Some expected events are not found: ' + Array.from(expectedEvents.keys()).join(',');
-  };
-
-  TestSuite.prototype.testInspectedElementIs = async function(nodeName) {
-    this.takeControl();
-    await self.runtime.loadModulePromise('elements');
-    if (!Elements.ElementsPanel._firstInspectElementNodeNameForTest)
-      await new Promise(f => this.addSniffer(Elements.ElementsPanel, '_firstInspectElementCompletedForTest', f));
-    this.assertEquals(nodeName, Elements.ElementsPanel._firstInspectElementNodeNameForTest);
-    this.releaseControl();
-  };
-
-  TestSuite.prototype.testInputDispatchEventsToOOPIF = async function() {
-    this.takeControl();
-
-    await new Promise(callback => this._waitForTargets(2, callback));
-
-    async function takeLogs(target) {
-      const code = `
-        (function() {
-          var result = window.logs.join(' ');
-          window.logs = [];
-          return result;
-        })()
-      `;
-      return (await target.runtimeAgent().invoke_evaluate({expression: code})).result.value;
-    }
-
-    let parentFrameOutput;
-    let childFrameOutput;
-
-    const inputAgent = SDK.targetManager.mainTarget().inputAgent();
-    const runtimeAgent = SDK.targetManager.mainTarget().runtimeAgent();
-    await inputAgent.invoke_dispatchMouseEvent({type: 'mousePressed', button: 'left', clickCount: 1, x: 10, y: 10});
-    await inputAgent.invoke_dispatchMouseEvent({type: 'mouseMoved', button: 'left', clickCount: 1, x: 10, y: 20});
-    await inputAgent.invoke_dispatchMouseEvent({type: 'mouseReleased', button: 'left', clickCount: 1, x: 10, y: 20});
-    await inputAgent.invoke_dispatchMouseEvent({type: 'mousePressed', button: 'left', clickCount: 1, x: 230, y: 140});
-    await inputAgent.invoke_dispatchMouseEvent({type: 'mouseMoved', button: 'left', clickCount: 1, x: 230, y: 150});
-    await inputAgent.invoke_dispatchMouseEvent({type: 'mouseReleased', button: 'left', clickCount: 1, x: 230, y: 150});
-    parentFrameOutput = 'Event type: mousedown button: 0 x: 10 y: 10 Event type: mouseup button: 0 x: 10 y: 20';
-    this.assertEquals(parentFrameOutput, await takeLogs(SDK.targetManager.targets()[0]));
-    childFrameOutput = 'Event type: mousedown button: 0 x: 30 y: 40 Event type: mouseup button: 0 x: 30 y: 50';
-    this.assertEquals(childFrameOutput, await takeLogs(SDK.targetManager.targets()[1]));
-
-
-    await inputAgent.invoke_dispatchKeyEvent({type: 'keyDown', key: 'a'});
-    await runtimeAgent.invoke_evaluate({expression: `document.querySelector('iframe').focus()`});
-    await inputAgent.invoke_dispatchKeyEvent({type: 'keyDown', key: 'a'});
-    parentFrameOutput = 'Event type: keydown';
-    this.assertEquals(parentFrameOutput, await takeLogs(SDK.targetManager.targets()[0]));
-    childFrameOutput = 'Event type: keydown';
-    this.assertEquals(childFrameOutput, await takeLogs(SDK.targetManager.targets()[1]));
-
-    await inputAgent.invoke_dispatchTouchEvent({type: 'touchStart', touchPoints: [{x: 10, y: 10}]});
-    await inputAgent.invoke_dispatchTouchEvent({type: 'touchEnd', touchPoints: []});
-    await inputAgent.invoke_dispatchTouchEvent({type: 'touchStart', touchPoints: [{x: 230, y: 140}]});
-    await inputAgent.invoke_dispatchTouchEvent({type: 'touchEnd', touchPoints: []});
-    parentFrameOutput = 'Event type: touchstart touch x: 10 touch y: 10';
-    this.assertEquals(parentFrameOutput, await takeLogs(SDK.targetManager.targets()[0]));
-    childFrameOutput = 'Event type: touchstart touch x: 30 touch y: 40';
-    this.assertEquals(childFrameOutput, await takeLogs(SDK.targetManager.targets()[1]));
-
-    this.releaseControl();
-  };
-
-  TestSuite.prototype.testLoadResourceForFrontend = async function(baseURL) {
-    const test = this;
-    const loggedHeaders = new Set(['cache-control', 'pragma']);
-    function testCase(url, headers, expectedStatus, expectedHeaders, expectedContent) {
-      return new Promise(fulfill => {
-        Host.ResourceLoader.load(url, headers, callback);
-
-        function callback(statusCode, headers, content) {
-          test.assertEquals(expectedStatus, statusCode);
-
-          const headersArray = [];
-          for (const name in headers) {
-            const nameLower = name.toLowerCase();
-            if (loggedHeaders.has(nameLower))
-              headersArray.push(nameLower);
-          }
-          headersArray.sort();
-          test.assertEquals(expectedHeaders.join(', '), headersArray.join(', '));
-          test.assertEquals(expectedContent, content);
-          fulfill();
-        }
-      });
-    }
-
-    this.takeControl();
-    await testCase(baseURL + 'non-existent.html', undefined, 404, [], '');
-    await testCase(baseURL + 'hello.html', undefined, 200, [], '<!doctype html>\n<p>hello</p>\n');
-    await testCase(baseURL + 'echoheader?x-devtools-test', {'x-devtools-test': 'Foo'}, 200, ['cache-control'], 'Foo');
-    await testCase(baseURL + 'set-header?pragma:%20no-cache', undefined, 200, ['pragma'], 'pragma: no-cache');
-
-    await SDK.targetManager.mainTarget().runtimeAgent().invoke_evaluate({
-      expression: `fetch("/set-cookie?devtools-test-cookie=Bar",
-                         {credentials: 'include'})`,
-      awaitPromise: true
-    });
-    await testCase(baseURL + 'echoheader?Cookie', undefined, 200, ['cache-control'], 'devtools-test-cookie=Bar');
-
-    this.releaseControl();
-  };
-
-  /**
-   * Serializes array of uiSourceCodes to string.
-   * @param {!Array.<!Workspace.UISourceCode>} uiSourceCodes
-   * @return {string}
-   */
-  TestSuite.prototype.uiSourceCodesToString_ = function(uiSourceCodes) {
-    const names = [];
-    for (let i = 0; i < uiSourceCodes.length; i++)
-      names.push('"' + uiSourceCodes[i].url() + '"');
-    return names.join(',');
-  };
-
-  /**
-   * Returns all loaded non anonymous uiSourceCodes.
-   * @return {!Array.<!Workspace.UISourceCode>}
-   */
-  TestSuite.prototype.nonAnonymousUISourceCodes_ = function() {
-    /**
-     * @param {!Workspace.UISourceCode} uiSourceCode
-     */
-    function filterOutService(uiSourceCode) {
-      return !uiSourceCode.project().isServiceProject();
-    }
-
-    const uiSourceCodes = Workspace.workspace.uiSourceCodes();
-    return uiSourceCodes.filter(filterOutService);
-  };
-
-  /*
- * Evaluates the code in the console as if user typed it manually and invokes
- * the callback when the result message is received and added to the console.
- * @param {string} code
- * @param {function(string)} callback
- */
-  TestSuite.prototype.evaluateInConsole_ = function(code, callback) {
-    function innerEvaluate() {
-      UI.context.removeFlavorChangeListener(SDK.ExecutionContext, showConsoleAndEvaluate, this);
-      const consoleView = Console.ConsoleView.instance();
-      consoleView._prompt._appendCommand(code);
-
-      this.addSniffer(Console.ConsoleView.prototype, '_consoleMessageAddedForTest', function(viewMessage) {
-        callback(viewMessage.toMessageElement().deepTextContent());
-      }.bind(this));
-    }
-
-    function showConsoleAndEvaluate() {
-      Common.console.showPromise().then(innerEvaluate.bind(this));
-    }
-
-    if (!UI.context.flavor(SDK.ExecutionContext)) {
-      UI.context.addFlavorChangeListener(SDK.ExecutionContext, showConsoleAndEvaluate, this);
-      return;
-    }
-    showConsoleAndEvaluate.call(this);
-  };
-
-  /**
-   * Checks that all expected scripts are present in the scripts list
-   * in the Scripts panel.
-   * @param {!Array.<string>} expected Regular expressions describing
-   *     expected script names.
-   * @return {boolean} Whether all the scripts are in "scripts-files" select
-   *     box
-   */
-  TestSuite.prototype._scriptsAreParsed = function(expected) {
-    const uiSourceCodes = this.nonAnonymousUISourceCodes_();
-    // Check that at least all the expected scripts are present.
-    const missing = expected.slice(0);
-    for (let i = 0; i < uiSourceCodes.length; ++i) {
-      for (let j = 0; j < missing.length; ++j) {
-        if (uiSourceCodes[i].name().search(missing[j]) !== -1) {
-          missing.splice(j, 1);
-          break;
-        }
-      }
-    }
-    return missing.length === 0;
-  };
-
-  /**
-   * Waits for script pause, checks expectations, and invokes the callback.
-   * @param {function():void} callback
-   */
-  TestSuite.prototype._waitForScriptPause = function(callback) {
-    this.addSniffer(SDK.DebuggerModel.prototype, '_pausedScript', callback);
-  };
-
-  /**
-   * Waits until all the scripts are parsed and invokes the callback.
-   */
-  TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callback) {
-    const test = this;
-
-    function waitForAllScripts() {
-      if (test._scriptsAreParsed(expectedScripts))
-        callback();
-      else
-        test.addSniffer(UI.panels.sources.sourcesView(), '_addUISourceCode', waitForAllScripts);
-    }
-
-    waitForAllScripts();
-  };
-
-  TestSuite.prototype._waitForTargets = function(n, callback) {
-    checkTargets.call(this);
-
-    function checkTargets() {
-      if (SDK.targetManager.targets().length >= n)
-        callback.call(null);
-      else
-        this.addSniffer(SDK.TargetManager.prototype, 'createTarget', checkTargets.bind(this));
-    }
-  };
-
-  TestSuite.prototype._waitForExecutionContexts = function(n, callback) {
-    const runtimeModel = SDK.targetManager.mainTarget().model(SDK.RuntimeModel);
-    checkForExecutionContexts.call(this);
-
-    function checkForExecutionContexts() {
-      if (runtimeModel.executionContexts().length >= n)
-        callback.call(null);
-      else
-        this.addSniffer(SDK.RuntimeModel.prototype, '_executionContextCreated', checkForExecutionContexts.bind(this));
-    }
-  };
-
-
-  window.uiTests = new TestSuite(window.domAutomationController);
-})(window);
diff --git a/front_end/accessibility/ARIAAttributesView.js b/front_end/accessibility/ARIAAttributesView.js
deleted file mode 100644
index 434cefe..0000000
--- a/front_end/accessibility/ARIAAttributesView.js
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Accessibility.ARIAAttributesPane = class extends Accessibility.AccessibilitySubPane {
-  constructor() {
-    super(ls`ARIA Attributes`);
-
-    this._noPropertiesInfo = this.createInfo(ls`No ARIA attributes`);
-    this._treeOutline = this.createTreeOutline();
-  }
-
-  /**
-   * @override
-   * @param {?SDK.DOMNode} node
-   */
-  setNode(node) {
-    super.setNode(node);
-    this._treeOutline.removeChildren();
-    if (!this.node())
-      return;
-    const target = this.node().domModel().target();
-    const attributes = node.attributes();
-    for (let i = 0; i < attributes.length; ++i) {
-      const attribute = attributes[i];
-      if (Accessibility.ARIAAttributesPane._attributes.indexOf(attribute.name) < 0)
-        continue;
-      this._treeOutline.appendChild(new Accessibility.ARIAAttributesTreeElement(this, attribute, target));
-    }
-
-    const foundAttributes = (this._treeOutline.rootElement().childCount() !== 0);
-    this._noPropertiesInfo.classList.toggle('hidden', foundAttributes);
-    this._treeOutline.element.classList.toggle('hidden', !foundAttributes);
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.ARIAAttributesTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Accessibility.ARIAAttributesPane} parentPane
-   * @param {!SDK.DOMNode.Attribute} attribute
-   * @param {!SDK.Target} target
-   */
-  constructor(parentPane, attribute, target) {
-    super('');
-
-    this._parentPane = parentPane;
-    this._attribute = attribute;
-
-    this.selectable = false;
-  }
-
-  /**
-   * @param {string} value
-   * @return {!Element}
-   */
-  static createARIAValueElement(value) {
-    const valueElement = createElementWithClass('span', 'monospace');
-    // TODO(aboxhall): quotation marks?
-    valueElement.setTextContentTruncatedIfNeeded(value || '');
-    return valueElement;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this._populateListItem();
-    this.listItemElement.addEventListener('click', this._mouseClick.bind(this));
-  }
-
-  _populateListItem() {
-    this.listItemElement.removeChildren();
-    this.appendNameElement(this._attribute.name);
-    this.listItemElement.createChild('span', 'separator').textContent = ':\u00A0';
-    this.appendAttributeValueElement(this._attribute.value);
-  }
-
-  /**
-   * @param {string} name
-   */
-  appendNameElement(name) {
-    this._nameElement = createElement('span');
-    this._nameElement.textContent = name;
-    this._nameElement.classList.add('ax-name');
-    this._nameElement.classList.add('monospace');
-    this.listItemElement.appendChild(this._nameElement);
-  }
-
-  /**
-   * @param {string} value
-   */
-  appendAttributeValueElement(value) {
-    this._valueElement = Accessibility.ARIAAttributesTreeElement.createARIAValueElement(value);
-    this.listItemElement.appendChild(this._valueElement);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseClick(event) {
-    if (event.target === this.listItemElement)
-      return;
-
-    event.consume(true);
-
-    this._startEditing();
-  }
-
-  _startEditing() {
-    const valueElement = this._valueElement;
-
-    if (UI.isBeingEdited(valueElement))
-      return;
-
-    const previousContent = valueElement.textContent;
-
-    /**
-     * @param {string} previousContent
-     * @param {!Event} event
-     * @this {Accessibility.ARIAAttributesTreeElement}
-     */
-    function blurListener(previousContent, event) {
-      const text = event.target.textContent;
-      this._editingCommitted(text, previousContent);
-    }
-
-    this._prompt = new Accessibility.ARIAAttributesPane.ARIAAttributePrompt(
-        Accessibility.ariaMetadata().valuesForProperty(this._nameElement.textContent), this);
-    this._prompt.setAutocompletionTimeout(0);
-    const proxyElement = this._prompt.attachAndStartEditing(valueElement, blurListener.bind(this, previousContent));
-
-    proxyElement.addEventListener('keydown', this._editingValueKeyDown.bind(this, previousContent), false);
-
-    valueElement.getComponentSelection().selectAllChildren(valueElement);
-  }
-
-  _removePrompt() {
-    if (!this._prompt)
-      return;
-    this._prompt.detach();
-    delete this._prompt;
-  }
-
-  /**
-   * @param {string} userInput
-   * @param {string} previousContent
-   */
-  _editingCommitted(userInput, previousContent) {
-    this._removePrompt();
-
-    // Make the changes to the attribute
-    if (userInput !== previousContent)
-      this._parentPane.node().setAttributeValue(this._attribute.name, userInput);
-  }
-
-  _editingCancelled() {
-    this._removePrompt();
-    this._populateListItem();
-  }
-
-  /**
-   * @param {string} previousContent
-   * @param {!Event} event
-   */
-  _editingValueKeyDown(previousContent, event) {
-    if (event.handled)
-      return;
-
-    if (isEnterKey(event)) {
-      this._editingCommitted(event.target.textContent, previousContent);
-      event.consume();
-      return;
-    }
-
-    if (event.keyCode === UI.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === 'U+001B') {
-      this._editingCancelled();
-      event.consume();
-      return;
-    }
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Accessibility.ARIAAttributesPane.ARIAAttributePrompt = class extends UI.TextPrompt {
-  /**
-   * @param {!Array<string>} ariaCompletions
-   * @param {!Accessibility.ARIAAttributesTreeElement} treeElement
-   */
-  constructor(ariaCompletions, treeElement) {
-    super();
-    this.initialize(this._buildPropertyCompletions.bind(this));
-
-    this._ariaCompletions = ariaCompletions;
-    this._treeElement = treeElement;
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} prefix
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  _buildPropertyCompletions(expression, prefix, force) {
-    prefix = prefix.toLowerCase();
-    if (!prefix && !force && (this._isEditingName || expression))
-      return Promise.resolve([]);
-    return Promise.resolve(this._ariaCompletions.filter(value => value.startsWith(prefix)).map(c => ({text: c})));
-  }
-};
-
-Accessibility.ARIAAttributesPane._attributes = [
-  'role',
-  'aria-busy',
-  'aria-checked',
-  'aria-disabled',
-  'aria-expanded',
-  'aria-grabbed',
-  'aria-hidden',
-  'aria-invalid',
-  'aria-pressed',
-  'aria-selected',
-  'aria-activedescendant',
-  'aria-atomic',
-  'aria-autocomplete',
-  'aria-controls',
-  'aria-describedby',
-  'aria-dropeffect',
-  'aria-flowto',
-  'aria-haspopup',
-  'aria-label',
-  'aria-labelledby',
-  'aria-level',
-  'aria-live',
-  'aria-multiline',
-  'aria-multiselectable',
-  'aria-orientation',
-  'aria-owns',
-  'aria-posinset',
-  'aria-readonly',
-  'aria-relevant',
-  'aria-required',
-  'aria-setsize',
-  'aria-sort',
-  'aria-valuemax',
-  'aria-valuemin',
-  'aria-valuenow',
-  'aria-valuetext',
-];
diff --git a/front_end/accessibility/ARIAConfig.js b/front_end/accessibility/ARIAConfig.js
deleted file mode 100644
index 909b013..0000000
--- a/front_end/accessibility/ARIAConfig.js
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Accessibility.ARIAMetadata._config = {
-  'attributes': {
-    'aria-activedescendant': {'type': 'IDREF'},
-    'aria-atomic': {'default': 'false', 'type': 'boolean'},
-    'aria-autocomplete': {'default': 'none', 'enum': ['inline', 'list', 'both', 'none'], 'type': 'token'},
-    'aria-busy': {'default': 'false', 'type': 'boolean'},
-    'aria-checked': {'default': 'undefined', 'enum': ['true', 'false', 'mixed', 'undefined'], 'type': 'token'},
-    'aria-colcount': {'type': 'integer'},
-    'aria-colindex': {'type': 'integer'},
-    'aria-colspan': {'type': 'integer'},
-    'aria-controls': {'type': 'IDREF_list'},
-    'aria-current':
-        {'default': 'false', 'enum': ['page', 'step', 'location', 'date', 'time', 'true', 'false'], 'type': 'token'},
-    'aria-describedby': {'type': 'IDREF_list'},
-    'aria-details': {'type': 'IDREF'},
-    'aria-disabled': {'default': 'false', 'type': 'boolean'},
-    'aria-dropeffect':
-        {'default': 'none', 'enum': ['copy', 'move', 'link', 'execute', 'popup', 'none'], 'type': 'token_list'},
-    'aria-errormessage': {'type': 'IDREF'},
-    'aria-expanded': {'default': 'undefined', 'enum': ['true', 'false', 'undefined'], 'type': 'token'},
-    'aria-flowto': {'type': 'IDREF_list'},
-    'aria-grabbed': {'default': 'undefined', 'enum': ['true', 'false', 'undefined'], 'type': 'token'},
-    'aria-haspopup':
-        {'default': 'false', 'enum': ['false', 'true', 'menu', 'listbox', 'tree', 'grid', 'dialog'], 'type': 'token'},
-    'aria-hidden': {'default': 'undefined', 'enum': ['true', 'false', 'undefined'], 'type': 'token'},
-    'aria-invalid': {'default': 'false', 'enum': ['grammar', 'false', 'spelling', 'true'], 'type': 'token'},
-    'aria-keyshortcuts': {'type': 'string'},
-    'aria-label': {'type': 'string'},
-    'aria-labelledby': {'type': 'IDREF_list'},
-    'aria-level': {'type': 'integer'},
-    'aria-live': {'default': 'off', 'enum': ['off', 'polite', 'assertive'], 'type': 'token'},
-    'aria-modal': {'default': 'false', 'type': 'boolean'},
-    'aria-multiline': {'default': 'false', 'type': 'boolean'},
-    'aria-multiselectable': {'default': 'false', 'type': 'boolean'},
-    'aria-orientation': {'default': 'undefined', 'enum': ['horizontal', 'undefined', 'vertical'], 'type': 'token'},
-    'aria-owns': {'type': 'IDREF_list'},
-    'aria-placeholder': {'type': 'string'},
-    'aria-posinset': {'type': 'integer'},
-    'aria-pressed': {'default': 'undefined', 'enum': ['true', 'false', 'mixed', 'undefined'], 'type': 'token'},
-    'aria-readonly': {'default': 'false', 'type': 'boolean'},
-    'aria-relevant':
-        {'default': 'additions text', 'enum': ['additions', 'removals', 'text', 'all'], 'type': 'token_list'},
-    'aria-required': {'default': 'false', 'type': 'boolean'},
-    'aria-roledescription': {'type': 'string'},
-    'aria-rowcount': {'type': 'integer'},
-    'aria-rowindex': {'type': 'integer'},
-    'aria-rowspan': {'type': 'integer'},
-    'aria-selected': {'default': 'undefined', 'enum': ['true', 'false', 'undefined'], 'type': 'token'},
-    'aria-setsize': {'type': 'integer'},
-    'aria-sort': {'default': 'none', 'enum': ['ascending', 'descending', 'none', 'other'], 'type': 'token'},
-    'aria-valuemax': {'type': 'decimal'},
-    'aria-valuemin': {'type': 'decimal'},
-    'aria-valuenow': {'type': 'decimal'},
-    'aria-valuetext': {'type': 'string'},
-    'tabindex': {'type': 'integer'}
-  },
-  'roles': {
-    'alert': {
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      'implicitValues': {'aria-live': 'assertive', 'aria-atomic': 'true'}
-    },
-    'alertdialog': {'nameFrom': ['author'], 'superclasses': ['alert', 'dialog'], 'nameRequired': true},
-    'application': {'nameFrom': ['author'], 'superclasses': ['structure'], 'nameRequired': true},
-    'article': {
-      'nameFrom': ['author'],
-      'superclasses': ['document'],
-      'supportedAttributes': ['aria-posinset', 'aria-setsize']
-    },
-    'banner': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'button': {
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['command'],
-      'supportedAttributes': ['aria-expanded', 'aria-pressed'],
-      'nameRequired': true,
-      'childrenPresentational': true
-    },
-    'cell': {
-      'namefrom': ['contents', 'author'],
-      'scope': 'row',
-      'superclasses': ['section'],
-      'supportedAttributes': ['aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan']
-    },
-    'checkbox': {
-      'nameFrom': ['contents', 'author'],
-      'requiredAttributes': ['aria-checked'],
-      'superclasses': ['input'],
-      'supportedAttributes': ['aria-readonly'],
-      'nameRequired': true,
-      'implicitValues': {'aria-checked': false}
-    },
-    'columnheader': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['row'],
-      'superclasses': ['gridcell', 'sectionhead', 'widget'],
-      'supportedAttributes': ['aria-sort'],
-      'nameRequired': true
-    },
-    'combobox': {
-      // TODO(aboxhall): Follow up with Nektarios and Aaron regarding role on textbox
-      'mustContain': ['textbox'],
-      'nameFrom': ['author'],
-      'requiredAttributes': ['aria-controls', 'aria-expanded'],
-      'superclasses': ['select'],
-      'supportedAttributes': ['aria-autocomplete', 'aria-readonly', 'aria-required'],
-      'nameRequired': true,
-      'implicitValues': {'aria-expanded': 'false', 'aria-haspopup': 'listbox'}
-    },
-    'command': {'abstract': true, 'nameFrom': ['author'], 'superclasses': ['widget']},
-    'complementary': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'composite': {
-      'abstract': true,
-      'nameFrom': ['author'],
-      'superclasses': ['widget'],
-      'supportedAttributes': ['aria-activedescendant'],
-    },
-    'contentinfo': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'definition': {'nameFrom': ['author'], 'superclasses': ['section']},
-    'dialog': {'nameFrom': ['author'], 'superclasses': ['window'], 'nameRequired': true},
-    'directory': {'nameFrom': ['author'], 'superclasses': ['list']},
-    'document': {
-      'nameFrom': ['author'],
-      'superclasses': ['structure'],
-      'supportedAttributes': ['aria-expanded'],
-      'nameRequired': false
-    },
-    'feed': {'nameFrom': ['author'], 'superclasses': ['list'], 'mustContain': ['article'], 'nameRequired': false},
-    'figure': {'namefrom': ['author'], 'superclasses': ['section'], 'nameRequired': false},
-    'form': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'grid': {
-      'nameFrom': ['author'],
-      'superclasses': ['composite', 'table'],
-      // TODO(aboxhall): Figure out how to express "rowgroup --> row" here.
-      'mustContain': ['row'],
-      'supportedAttributes': ['aria-level', 'aria-multiselectable', 'aria-readonly'],
-      'nameRequired': true
-    },
-    'gridcell': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['row'],
-      'superclasses': ['cell', 'widget'],
-      'supportedAttributes': ['aria-readonly', 'aria-required', 'aria-selected'],
-      'nameRequired': true
-    },
-    'group': {'nameFrom': ['author'], 'superclasses': ['section'], 'supportedAttributes': ['aria-activedescendant']},
-    'heading': {
-      'namefrom': ['contents', 'author'],
-      'superclasses': ['sectionhead'],
-      'supportedAttributes': ['aria-level'],
-      'nameRequired': true,
-      'implicitValues': {'aria-level': '2'}
-    },
-    'img': {'nameFrom': ['author'], 'superclasses': ['section'], 'nameRequired': true, 'childrenPresentational': true},
-    'input': {'abstract': true, 'nameFrom': ['author'], 'superclasses': ['widget']},
-    'landmark': {'abstract': true, 'nameFrom': ['author'], 'superclasses': ['section'], 'nameRequired': false},
-    'link': {
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['command'],
-      'supportedAttributes': ['aria-expanded'],
-      'nameRequired': true
-    },
-    'list': {
-      // TODO(aboxhall): Figure out how to express "group --> listitem"
-      'mustContain': ['listitem'],
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      'implicitValues': {'aria-orientation': 'vertical'}
-    },
-    'listbox': {
-      'nameFrom': ['author'],
-      'superclasses': ['select'],
-      'mustContain': ['option'],
-      'supportedAttributes': ['aria-multiselectable', 'aria-readonly', 'aria-required'],
-      'nameRequired': true,
-      'implicitValues': {'aria-orientation': 'vertical'},
-    },
-    'listitem': {
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      'scope': ['group', 'list'],
-      'supportedAttributes': ['aria-level', 'aria-posinset', 'aria-setsize']
-    },
-    'log': {
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      'nameRequired': true,
-      'implicitValues': {'aria-live': 'polite'}
-    },
-    'main': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'marquee': {'nameFrom': ['author'], 'superclasses': ['section'], 'nameRequired': true},
-    'math': {
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      'nameRequired': true,
-      // TODO(aboxhall/aleventhal): this is what the spec says, but seems wrong.
-      childrenPresentational: true
-    },
-    'menu': {
-      'mustContain': ['group', 'menuitemradio', 'menuitem', 'menuitemcheckbox', 'menuitemradio'],
-      'nameFrom': ['author'],
-      'superclasses': ['select'],
-      'implicitValues': {'aria-orientation': 'vertical'}
-    },
-    'menubar': {
-      'nameFrom': ['author'],
-      'superclasses': ['menu'],
-      // TODO(aboxhall): figure out how to express "group --> {menuitem, menuitemradio, menuitemcheckbox}"
-      'mustContain': ['menuitem', 'menuitemradio', 'menuitemcheckbox'],
-      'implicitValues': {'aria-orientation': 'horizontal'}
-    },
-    'menuitem': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['group', 'menu', 'menubar'],
-      'superclasses': ['command'],
-      'nameRequired': true
-    },
-    'menuitemcheckbox': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['menu', 'menubar'],
-      'superclasses': ['checkbox', 'menuitem'],
-      'nameRequired': true,
-      'childrenPresentational': true,
-      'implicitValues': {'aria-checked': false}
-    },
-    'menuitemradio': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['menu', 'menubar', 'group'],
-      'superclasses': ['menuitemcheckbox', 'radio'],
-      'nameRequired': true,
-      'childrenPresentational': true,
-      'implicitValues': {'aria-checked': false}
-    },
-    'navigation': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'none': {'superclasses': ['structure']},
-    'note': {'nameFrom': ['author'], 'superclasses': ['section']},
-    'option': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['listbox'],
-      'superclasses': ['input'],
-      'requiredAttributes': ['aria-selected'],
-      'supportedAttributes': ['aria-checked', 'aria-posinset', 'aria-setsize'],
-      'nameRequired': true,
-      'childrenPresentational': true,
-      'implicitValues': {'aria-selected': 'false'}
-    },
-    'presentation': {'superclasses': ['structure']},
-    'progressbar':
-        {'nameFrom': ['author'], 'superclasses': ['range'], 'nameRequired': true, 'childrenPresentational': true},
-    'radio': {
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['input'],
-      'requiredAttributes': ['aria-checked'],
-      'supportedAttributes': ['aria-posinset', 'aria-setsize'],
-      'nameRequired': true,
-      'childrenPresentational': true,
-      'implicitValues': {'aria-checked': 'false'}
-    },
-    'radiogroup': {
-      'nameFrom': ['author'],
-      'superclasses': ['select'],
-      'mustContain': ['radio'],
-      'supportedAttributes': ['aria-readonly', 'aria-required'],
-      'nameRequired': true
-    },
-    'range': {
-      'abstract': true,
-      'nameFrom': ['author'],
-      'superclasses': ['widget'],
-      'supportedAttributes': ['aria-valuemax', 'aria-valuemin', 'aria-valuenow', 'aria-valuetext']
-    },
-    'region': {'nameFrom': ['author'], 'superclasses': ['landmark'], 'nameRequired': true},
-    'roletype': {
-      'abstract': true,
-      'supportedAttributes': [
-        'aria-atomic',   'aria-busy',       'aria-controls',       'aria-current', 'aria-describedby', 'aria-details',
-        'aria-disabled', 'aria-dropeffect', 'aria-errormessage',   'aria-flowto',  'aria-grabbed',     'aria-haspopup',
-        'aria-hidden',   'aria-invalid',    'aria-keyshortcuts',   'aria-label',   'aria-labelledby',  'aria-live',
-        'aria-owns',     'aria-relevant',   'aria-roledescription'
-      ]
-    },
-    'row': {
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['group', 'widget'],
-      'mustContain': ['cell', 'columnheader', 'gridcell', 'rowheader'],
-      'scope': ['grid', 'rowgroup', 'table', 'treegrid'],
-      // TODO(aboxhall/aleventhal): This is not in the spec yet, but
-      // setsize and posinset are included here for treegrid
-      // purposes. Issue already filed on spec. Remove this comment
-      // when spec updated.
-      'supportedAttributes':
-          ['aria-colindex', 'aria-level', 'aria-rowindex', 'aria-selected', 'aria-setsize', 'aria-posinset']
-    },
-    'rowgroup': {
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['structure'],
-      'mustContain': ['row'],
-      'scope': ['grid', 'table', 'treegrid'],
-    },
-    'rowheader': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['row'],
-      'superclasses': ['cell', 'gridcell', 'sectionhead'],
-      'supportedAttributes': ['aria-sort'],
-      'nameRequired': true
-    },
-    'scrollbar': {
-      'nameFrom': ['author'],
-      'requiredAttributes': ['aria-controls', 'aria-orientation', 'aria-valuemax', 'aria-valuemin', 'aria-valuenow'],
-      'superclasses': ['range'],
-      'nameRequired': false,
-      'childrenPresentational': true,
-      'implicitValues': {'aria-orientation': 'vertical', 'aria-valuemin': '0', 'aria-valuemax': '100'}
-    },
-    'search': {'nameFrom': ['author'], 'superclasses': ['landmark']},
-    'searchbox': {'nameFrom': ['author'], 'superclasses': ['textbox'], 'nameRequired': true},
-    'section': {'abstract': true, 'superclasses': ['structure'], 'supportedAttributes': ['aria-expanded']},
-    'sectionhead': {
-      'abstract': true,
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['structure'],
-      'supportedAttributes': ['aria-expanded']
-    },
-    'select': {'abstract': true, 'nameFrom': ['author'], 'superclasses': ['composite', 'group']},
-    'separator': {
-      'nameFrom': ['author'],
-      // TODO(aboxhall): superclass depends on focusability, but
-      // doesn't affect required/supported attributes
-      'superclasses': ['structure'],
-      // TODO(aboxhall): required attributes depend on focusability
-      'supportedAttributes': ['aria-orientation', 'aria-valuemin', 'aria-valuemax', 'aria-valuenow', 'aria-valuetext']
-    },
-    'slider': {
-      'nameFrom': ['author'],
-      'requiredAttributes': ['aria-valuemax', 'aria-valuemin', 'aria-valuenow'],
-      'superclasses': ['input', 'range'],
-      'supportedAttributes': ['aria-orientation'],
-      'nameRequired': true,
-      'childrenPresentational': true,
-      // TODO(aboxhall): aria-valuenow default is halfway between
-      // aria-valuemin and aria-valuemax
-      'implicitValues': {'aria-orientation': 'horizontal', 'aria-valuemin': '0', 'aria-valuemax': '100'}
-    },
-    'spinbutton': {
-      'nameFrom': ['author'],
-      'requiredAttributes': ['aria-valuemax', 'aria-valuemin', 'aria-valuenow'],
-      'superclasses': ['composite', 'input', 'range'],
-      'supportedAttributes': ['aria-required', 'aria-readonly'],
-      'nameRequired': true,
-      'implicitValues': {'aria-valuenow': '0'}
-    },
-    'status': {
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      'implicitValues': {'aria-live': 'polite', 'aria-atomic': 'true'}
-    },
-    'structure': {'abstract': true, 'superclasses': ['roletype']},
-    'switch': {
-      'nameFrom': ['contents', 'author'],
-      'superclasses': ['checkbox'],
-      'requiredAttributes': ['aria-checked'],
-      'nameRequired': true,
-      'childrenPresentational': true,
-      'implicitValues': {'aria-checked': 'false'}
-    },
-    'tab': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['tablist'],
-      'superclasses': ['sectionhead', 'widget'],
-      'supportedAttributes': ['aria-selected'],
-      'childrenPresentational': true,
-      'implicitValues': {'aria-selected': 'false'}
-    },
-    'table': {
-      'nameFrom': ['author'],
-      'superclasses': ['section'],
-      // TODO(aboxhall): Figure out how to express "rowgroup --> row"
-      'mustContain': ['row'],
-      'supportedAttributes': ['aria-colcount', 'aria-rowcount'],
-      'nameRequired': true
-    },
-    'tablist': {
-      'nameFrom': ['author'],
-      'superclasses': ['composite'],
-      'mustContain': ['tab'],
-      'supportedAttributes': ['aria-level', 'aria-multiselectable', 'aria-orientation'],
-      'implicitValues': {'aria-orientation': 'horizontal'}
-    },
-    'tabpanel': {'nameFrom': ['author'], 'superclasses': ['section'], 'nameRequired': true},
-    'term': {'nameFrom': ['author'], 'superclasses': ['section']},
-    'textbox': {
-      'nameFrom': ['author'],
-      'superclasses': ['input'],
-      'supportedAttributes': [
-        'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-placeholder', 'aria-readonly',
-        'aria-required'
-      ],
-      'nameRequired': true
-    },
-    'timer': {'nameFrom': ['author'], 'superclasses': ['status']},
-    'toolbar': {
-      'nameFrom': ['author'],
-      'superclasses': ['group'],
-      'supportedAttributes': ['aria-orientation'],
-      'implicitValues': {'aria-orientation': 'horizontal'}
-    },
-    'tooltip': {'nameFrom': ['contents', 'author'], 'superclasses': ['section'], 'nameRequired': true},
-    'tree': {
-      'nameFrom': ['author'],
-      'mustContain': ['group', 'treeitem'],
-      'superclasses': ['select'],
-      'supportedAttributes': ['aria-multiselectable', 'aria-required'],
-      'nameRequired': true,
-      'implicitValues': {'aria-orientation': 'vertical'}
-    },
-    'treegrid': {
-      // TODO(aboxhall): Figure out how to express "rowgroup --> row"
-      'mustContain': ['row'],
-      'nameFrom': ['author'],
-      'superclasses': ['grid', 'tree'],
-      'nameRequired': true
-    },
-    'treeitem': {
-      'nameFrom': ['contents', 'author'],
-      'scope': ['group', 'tree'],
-      'superclasses': ['listitem', 'option'],
-      'nameRequired': true
-    },
-    'widget': {'abstract': true, 'superclasses': ['roletype']},
-    'window': {
-      'abstract': true,
-      'nameFrom': ['author'],
-      'superclasses': ['roletype'],
-      'supportedAttributes': ['aria-expanded', 'aria-modal']
-    }
-  }
-};
diff --git a/front_end/accessibility/ARIAMetadata.js b/front_end/accessibility/ARIAMetadata.js
deleted file mode 100644
index 5fbf0cd..0000000
--- a/front_end/accessibility/ARIAMetadata.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Accessibility.ARIAMetadata = class {
-  /**
-   * @param {?Object} config
-   */
-  constructor(config) {
-    /** @type {!Map<string, !Accessibility.ARIAMetadata.Attribute>} */
-    this._attributes = new Map();
-
-    if (config)
-      this._initialize(config);
-  }
-
-  /**
-   * @param {!Object} config
-   */
-  _initialize(config) {
-    const attributes = config['attributes'];
-
-    const booleanEnum = ['true', 'false'];
-    for (const name in attributes) {
-      const attributeConfig = attributes[name];
-      if (attributeConfig.type === 'boolean')
-        attributeConfig.enum = booleanEnum;
-      this._attributes.set(name, new Accessibility.ARIAMetadata.Attribute(attributeConfig));
-    }
-
-    /** @type {!Array<string>} */
-    this._roleNames = Object.keys(config['roles']);
-  }
-
-  /**
-   * @param {string} property
-   * @return {!Array<string>}
-   */
-  valuesForProperty(property) {
-    if (this._attributes.has(property))
-      return this._attributes.get(property).getEnum();
-
-    if (property === 'role')
-      return this._roleNames;
-
-    return [];
-  }
-};
-
-/**
- * @return {!Accessibility.ARIAMetadata}
- */
-Accessibility.ariaMetadata = function() {
-  if (!Accessibility.ARIAMetadata._instance)
-    Accessibility.ARIAMetadata._instance = new Accessibility.ARIAMetadata(Accessibility.ARIAMetadata._config || null);
-  return Accessibility.ARIAMetadata._instance;
-};
-
-/**
- * @unrestricted
- */
-Accessibility.ARIAMetadata.Attribute = class {
-  /**
-   * @param {!Object} config
-   */
-  constructor(config) {
-    /** @type {!Array<string>} */
-    this._enum = [];
-
-    if ('enum' in config)
-      this._enum = config.enum;
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  getEnum() {
-    return this._enum;
-  }
-};
diff --git a/front_end/accessibility/AXBreadcrumbsPane.js b/front_end/accessibility/AXBreadcrumbsPane.js
deleted file mode 100644
index 34708e0..0000000
--- a/front_end/accessibility/AXBreadcrumbsPane.js
+++ /dev/null
@@ -1,498 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Accessibility.AXBreadcrumbsPane = class extends Accessibility.AccessibilitySubPane {
-  /**
-   * @param {!Accessibility.AccessibilitySidebarView} axSidebarView
-   */
-  constructor(axSidebarView) {
-    super(ls`Accessibility Tree`);
-
-    this.element.classList.add('ax-subpane');
-    UI.ARIAUtils.markAsTree(this.element);
-    this.element.tabIndex = -1;
-
-    this._axSidebarView = axSidebarView;
-
-    /** @type {?Accessibility.AXBreadcrumb} */
-    this._preselectedBreadcrumb = null;
-    /** @type {?Accessibility.AXBreadcrumb} */
-    this._inspectedNodeBreadcrumb = null;
-
-    this._hoveredBreadcrumb = null;
-    this._rootElement = this.element.createChild('div', 'ax-breadcrumbs');
-
-    this._rootElement.addEventListener('keydown', this._onKeyDown.bind(this), true);
-    this._rootElement.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    this._rootElement.addEventListener('mouseleave', this._onMouseLeave.bind(this), false);
-    this._rootElement.addEventListener('click', this._onClick.bind(this), false);
-    this._rootElement.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), false);
-    this._rootElement.addEventListener('focusout', this._onFocusOut.bind(this), false);
-    this.registerRequiredCSS('accessibility/axBreadcrumbs.css');
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (this._inspectedNodeBreadcrumb)
-      this._inspectedNodeBreadcrumb.nodeElement().focus();
-    else
-      this.element.focus();
-  }
-
-  /**
-   * @param {?Accessibility.AccessibilityNode} axNode
-   * @override
-   */
-  setAXNode(axNode) {
-    const hadFocus = this.element.hasFocus();
-    super.setAXNode(axNode);
-
-    this._rootElement.removeChildren();
-
-    if (!axNode)
-      return;
-
-    const ancestorChain = [];
-    let ancestor = axNode;
-    while (ancestor) {
-      ancestorChain.push(ancestor);
-      ancestor = ancestor.parentNode();
-    }
-    ancestorChain.reverse();
-
-    let depth = 0;
-    let breadcrumb = null;
-    let parent = null;
-    for (ancestor of ancestorChain) {
-      breadcrumb = new Accessibility.AXBreadcrumb(ancestor, depth, (ancestor === axNode));
-      if (parent)
-        parent.appendChild(breadcrumb);
-      else
-        this._rootElement.appendChild(breadcrumb.element());
-      parent = breadcrumb;
-      depth++;
-    }
-
-    this._inspectedNodeBreadcrumb = breadcrumb;
-    this._inspectedNodeBreadcrumb.setPreselected(true, hadFocus);
-
-    this._setPreselectedBreadcrumb(this._inspectedNodeBreadcrumb);
-
-    /**
-     * @param {!Accessibility.AXBreadcrumb} parentBreadcrumb
-     * @param {!Accessibility.AccessibilityNode} axNode
-     * @param {number} localDepth
-     */
-    function append(parentBreadcrumb, axNode, localDepth) {
-      const childBreadcrumb = new Accessibility.AXBreadcrumb(axNode, localDepth, false);
-      parentBreadcrumb.appendChild(childBreadcrumb);
-
-      // In most cases there will be no children here, but there are some special cases.
-      for (const child of axNode.children())
-        append(childBreadcrumb, child, localDepth + 1);
-    }
-
-    for (const child of axNode.children())
-      append(this._inspectedNodeBreadcrumb, child, depth);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._setPreselectedBreadcrumb(null);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (!this._preselectedBreadcrumb)
-      return;
-    if (!event.path.some(element => element === this._preselectedBreadcrumb.element()))
-      return;
-    if (event.shiftKey || event.metaKey || event.ctrlKey)
-      return;
-
-    let handled = false;
-    if ((event.key === 'ArrowUp' || event.key === 'ArrowLeft') && !event.altKey)
-      handled = this._preselectPrevious();
-    else if ((event.key === 'ArrowDown' || event.key === 'ArrowRight') && !event.altKey)
-      handled = this._preselectNext();
-    else if (isEnterKey(event))
-      handled = this._inspectDOMNode(this._preselectedBreadcrumb.axNode());
-
-    if (handled)
-      event.consume(true);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _preselectPrevious() {
-    const previousBreadcrumb = this._preselectedBreadcrumb.previousBreadcrumb();
-    if (!previousBreadcrumb)
-      return false;
-    this._setPreselectedBreadcrumb(previousBreadcrumb);
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _preselectNext() {
-    const nextBreadcrumb = this._preselectedBreadcrumb.nextBreadcrumb();
-    if (!nextBreadcrumb)
-      return false;
-    this._setPreselectedBreadcrumb(nextBreadcrumb);
-    return true;
-  }
-
-  /**
-   * @param {?Accessibility.AXBreadcrumb} breadcrumb
-   */
-  _setPreselectedBreadcrumb(breadcrumb) {
-    if (breadcrumb === this._preselectedBreadcrumb)
-      return;
-    const hadFocus = this.element.hasFocus();
-    if (this._preselectedBreadcrumb)
-      this._preselectedBreadcrumb.setPreselected(false, hadFocus);
-
-    if (breadcrumb)
-      this._preselectedBreadcrumb = breadcrumb;
-    else
-      this._preselectedBreadcrumb = this._inspectedNodeBreadcrumb;
-    this._preselectedBreadcrumb.setPreselected(true, hadFocus);
-    if (!breadcrumb && hadFocus)
-      SDK.OverlayModel.hideDOMNodeHighlight();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseLeave(event) {
-    this._setHoveredBreadcrumb(null);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    const breadcrumbElement = event.target.enclosingNodeOrSelfWithClass('ax-breadcrumb');
-    if (!breadcrumbElement) {
-      this._setHoveredBreadcrumb(null);
-      return;
-    }
-    const breadcrumb = breadcrumbElement.breadcrumb;
-    if (!breadcrumb.isDOMNode())
-      return;
-    this._setHoveredBreadcrumb(breadcrumb);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onFocusOut(event) {
-    if (!this._preselectedBreadcrumb || event.target !== this._preselectedBreadcrumb.nodeElement())
-      return;
-    this._setPreselectedBreadcrumb(null);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    const breadcrumbElement = event.target.enclosingNodeOrSelfWithClass('ax-breadcrumb');
-    if (!breadcrumbElement) {
-      this._setHoveredBreadcrumb(null);
-      return;
-    }
-    const breadcrumb = breadcrumbElement.breadcrumb;
-    if (breadcrumb.inspected()) {
-      // If the user is clicking the inspected breadcrumb, they probably want to
-      // focus it.
-      breadcrumb.nodeElement().focus();
-      return;
-    }
-    if (!breadcrumb.isDOMNode())
-      return;
-    this._inspectDOMNode(breadcrumb.axNode());
-  }
-
-  /**
-   * @param {?Accessibility.AXBreadcrumb} breadcrumb
-   */
-  _setHoveredBreadcrumb(breadcrumb) {
-    if (breadcrumb === this._hoveredBreadcrumb)
-      return;
-
-    if (this._hoveredBreadcrumb)
-      this._hoveredBreadcrumb.setHovered(false);
-
-    if (breadcrumb) {
-      breadcrumb.setHovered(true);
-    } else if (this.node()) {
-      // Highlight and scroll into view the currently inspected node.
-      this.node().domModel().overlayModel().nodeHighlightRequested(this.node().id);
-    }
-
-    this._hoveredBreadcrumb = breadcrumb;
-  }
-
-  /**
-   * @param {!Accessibility.AccessibilityNode} axNode
-   * @return {boolean}
-   */
-  _inspectDOMNode(axNode) {
-    if (!axNode.isDOMNode())
-      return false;
-
-    axNode.deferredDOMNode().resolve(domNode => {
-      this._axSidebarView.setNode(domNode, true /* fromAXTree */);
-      Common.Revealer.reveal(domNode, true /* omitFocus */);
-    });
-
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _contextMenuEventFired(event) {
-    const breadcrumbElement = event.target.enclosingNodeOrSelfWithClass('ax-breadcrumb');
-    if (!breadcrumbElement)
-      return;
-
-    const axNode = breadcrumbElement.breadcrumb.axNode();
-    if (!axNode.isDOMNode() || !axNode.deferredDOMNode())
-      return;
-
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.viewSection().appendItem(ls`Scroll into view`, () => {
-      axNode.deferredDOMNode().resolvePromise().then(domNode => {
-        if (!domNode)
-          return;
-        domNode.scrollIntoView();
-      });
-    });
-
-    contextMenu.appendApplicableItems(axNode.deferredDOMNode());
-    contextMenu.show();
-  }
-};
-
-Accessibility.AXBreadcrumb = class {
-  /**
-   * @param {!Accessibility.AccessibilityNode} axNode
-   * @param {number} depth
-   * @param {boolean} inspected
-   */
-  constructor(axNode, depth, inspected) {
-    /** @type {!Accessibility.AccessibilityNode} */
-    this._axNode = axNode;
-
-    this._element = createElementWithClass('div', 'ax-breadcrumb');
-    this._element.breadcrumb = this;
-
-    this._nodeElement = createElementWithClass('div', 'ax-node');
-    UI.ARIAUtils.markAsTreeitem(this._nodeElement);
-    this._nodeElement.tabIndex = -1;
-    this._element.appendChild(this._nodeElement);
-    this._nodeWrapper = createElementWithClass('div', 'wrapper');
-    this._nodeElement.appendChild(this._nodeWrapper);
-
-    this._selectionElement = createElementWithClass('div', 'selection fill');
-    this._nodeElement.appendChild(this._selectionElement);
-
-    this._childrenGroupElement = createElementWithClass('div', 'children');
-    UI.ARIAUtils.markAsGroup(this._childrenGroupElement);
-    this._element.appendChild(this._childrenGroupElement);
-
-    /** @type !Array<!Accessibility.AXBreadcrumb> */
-    this._children = [];
-    this._hovered = false;
-    this._preselected = false;
-    this._parent = null;
-
-    this._inspected = inspected;
-    this._nodeElement.classList.toggle('inspected', inspected);
-
-    this._nodeElement.style.paddingLeft = (16 * depth + 4) + 'px';
-
-    if (this._axNode.ignored()) {
-      this._appendIgnoredNodeElement();
-    } else {
-      this._appendRoleElement(this._axNode.role());
-      if (this._axNode.name() && this._axNode.name().value) {
-        this._nodeWrapper.createChild('span', 'separator').textContent = '\u00A0';
-        this._appendNameElement(/** @type {string} */ (this._axNode.name().value));
-      }
-    }
-
-    if (this._axNode.hasOnlyUnloadedChildren())
-      this._nodeElement.classList.add('children-unloaded');
-
-    if (!this._axNode.isDOMNode())
-      this._nodeElement.classList.add('no-dom-node');
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  nodeElement() {
-    return this._nodeElement;
-  }
-
-  /**
-   * @param {!Accessibility.AXBreadcrumb} breadcrumb
-   */
-  appendChild(breadcrumb) {
-    this._children.push(breadcrumb);
-    breadcrumb.setParent(this);
-    this._nodeElement.classList.add('parent');
-    UI.ARIAUtils.setExpanded(this._nodeElement, true);
-    this._childrenGroupElement.appendChild(breadcrumb.element());
-  }
-
-  /**
-   * @param {!Accessibility.AXBreadcrumb} breadcrumb
-   */
-  setParent(breadcrumb) {
-    this._parent = breadcrumb;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  preselected() {
-    return this._preselected;
-  }
-
-  /**
-   * @param {boolean} preselected
-   * @param {boolean} selectedByUser
-   */
-  setPreselected(preselected, selectedByUser) {
-    if (this._preselected === preselected)
-      return;
-    this._preselected = preselected;
-    this._nodeElement.classList.toggle('preselected', preselected);
-    if (preselected)
-      this._nodeElement.setAttribute('tabIndex', 0);
-    else
-      this._nodeElement.setAttribute('tabIndex', -1);
-    if (this._preselected) {
-      if (selectedByUser)
-        this._nodeElement.focus();
-      if (!this._inspected)
-        this._axNode.highlightDOMNode();
-      else
-        SDK.OverlayModel.hideDOMNodeHighlight();
-    }
-  }
-
-  /**
-   * @param {boolean} hovered
-   */
-  setHovered(hovered) {
-    if (this._hovered === hovered)
-      return;
-    this._hovered = hovered;
-    this._nodeElement.classList.toggle('hovered', hovered);
-    if (this._hovered) {
-      this._nodeElement.classList.toggle('hovered', true);
-      this._axNode.highlightDOMNode();
-    }
-  }
-
-  /**
-   * @return {!Accessibility.AccessibilityNode}
-   */
-  axNode() {
-    return this._axNode;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  inspected() {
-    return this._inspected;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDOMNode() {
-    return this._axNode.isDOMNode();
-  }
-
-  /**
-   * @return {?Accessibility.AXBreadcrumb}
-   */
-  nextBreadcrumb() {
-    if (this._children.length)
-      return this._children[0];
-    const nextSibling = this.element().nextSibling;
-    if (nextSibling)
-      return nextSibling.breadcrumb;
-    return null;
-  }
-
-  /**
-   * @return {?Accessibility.AXBreadcrumb}
-   */
-  previousBreadcrumb() {
-    const previousSibling = this.element().previousSibling;
-    if (previousSibling)
-      return previousSibling.breadcrumb;
-
-    return this._parent;
-  }
-
-  /**
-   * @param {string} name
-   */
-  _appendNameElement(name) {
-    const nameElement = createElement('span');
-    nameElement.textContent = '"' + name + '"';
-    nameElement.classList.add('ax-readable-string');
-    this._nodeWrapper.appendChild(nameElement);
-  }
-
-  /**
-   * @param {?Protocol.Accessibility.AXValue} role
-   */
-  _appendRoleElement(role) {
-    if (!role)
-      return;
-
-    const roleElement = createElementWithClass('span', 'monospace');
-    roleElement.classList.add(Accessibility.AXBreadcrumb.RoleStyles[role.type]);
-    roleElement.setTextContentTruncatedIfNeeded(role.value || '');
-
-    this._nodeWrapper.appendChild(roleElement);
-  }
-
-  _appendIgnoredNodeElement() {
-    const ignoredNodeElement = createElementWithClass('span', 'monospace');
-    ignoredNodeElement.textContent = ls`Ignored`;
-    ignoredNodeElement.classList.add('ax-breadcrumbs-ignored-node');
-    this._nodeWrapper.appendChild(ignoredNodeElement);
-  }
-};
-
-/** @type {!Object<string, string>} */
-Accessibility.AXBreadcrumb.RoleStyles = {
-  internalRole: 'ax-internal-role',
-  role: 'ax-role',
-};
diff --git a/front_end/accessibility/AccessibilityModel.js b/front_end/accessibility/AccessibilityModel.js
deleted file mode 100644
index 6dd0923..0000000
--- a/front_end/accessibility/AccessibilityModel.js
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Accessibility.AccessibilityNode = class {
-  /**
-   * @param {!Accessibility.AccessibilityModel} accessibilityModel
-   * @param {!Protocol.Accessibility.AXNode} payload
-   */
-  constructor(accessibilityModel, payload) {
-    this._accessibilityModel = accessibilityModel;
-    this._agent = accessibilityModel._agent;
-
-    this._id = payload.nodeId;
-    accessibilityModel._setAXNodeForAXId(this._id, this);
-    if (payload.backendDOMNodeId) {
-      accessibilityModel._setAXNodeForBackendDOMNodeId(payload.backendDOMNodeId, this);
-      this._backendDOMNodeId = payload.backendDOMNodeId;
-      this._deferredDOMNode = new SDK.DeferredDOMNode(accessibilityModel.target(), payload.backendDOMNodeId);
-    } else {
-      this._backendDOMNodeId = null;
-      this._deferredDOMNode = null;
-    }
-    this._ignored = payload.ignored;
-    if (this._ignored && 'ignoredReasons' in payload)
-      this._ignoredReasons = payload.ignoredReasons;
-
-    this._role = payload.role || null;
-    this._name = payload.name || null;
-    this._description = payload.description || null;
-    this._value = payload.value || null;
-    this._properties = payload.properties || null;
-    this._childIds = payload.childIds || null;
-    this._parentNode = null;
-  }
-
-  /**
-   * @return {!Accessibility.AccessibilityModel}
-   */
-  accessibilityModel() {
-    return this._accessibilityModel;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  ignored() {
-    return this._ignored;
-  }
-
-  /**
-   * @return {?Array<!Protocol.Accessibility.AXProperty>}
-   */
-  ignoredReasons() {
-    return this._ignoredReasons || null;
-  }
-
-  /**
-   * @return {?Protocol.Accessibility.AXValue}
-   */
-  role() {
-    return this._role || null;
-  }
-
-  /**
-   * @return {!Array<!Protocol.Accessibility.AXProperty>}
-   */
-  coreProperties() {
-    const properties = [];
-
-    if (this._name)
-      properties.push(/** @type {!Protocol.Accessibility.AXProperty} */ ({name: 'name', value: this._name}));
-    if (this._description) {
-      properties.push(
-          /** @type {!Protocol.Accessibility.AXProperty} */ ({name: 'description', value: this._description}));
-    }
-    if (this._value)
-      properties.push(/** @type {!Protocol.Accessibility.AXProperty} */ ({name: 'value', value: this._value}));
-
-    return properties;
-  }
-
-  /**
-   * @return {?Protocol.Accessibility.AXValue}
-   */
-  name() {
-    return this._name || null;
-  }
-
-  /**
-   * @return {?Protocol.Accessibility.AXValue}
-   */
-  description() {
-    return this._description || null;
-  }
-
-  /**
-   * @return {?Protocol.Accessibility.AXValue}
-   */
-  value() {
-    return this._value || null;
-  }
-
-  /**
-   * @return {?Array<!Protocol.Accessibility.AXProperty>}
-   */
-  properties() {
-    return this._properties || null;
-  }
-
-  /**
-   * @return {?Accessibility.AccessibilityNode}
-   */
-  parentNode() {
-    return this._parentNode;
-  }
-
-  /**
-   * @param {?Accessibility.AccessibilityNode} parentNode
-   */
-  _setParentNode(parentNode) {
-    this._parentNode = parentNode;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDOMNode() {
-    return !!this._backendDOMNodeId;
-  }
-
-  /**
-   * @return {?number}
-   */
-  backendDOMNodeId() {
-    return this._backendDOMNodeId;
-  }
-
-  /**
-   * @return {?SDK.DeferredDOMNode}
-   */
-  deferredDOMNode() {
-    return this._deferredDOMNode;
-  }
-
-  highlightDOMNode() {
-    if (!this.deferredDOMNode())
-      return;
-
-    // Highlight node in page.
-    this.deferredDOMNode().highlight();
-
-    // Highlight node in Elements tree.
-    this.deferredDOMNode().resolvePromise().then(node => {
-      if (!node)
-        return;
-      node.domModel().overlayModel().nodeHighlightRequested(node.id);
-    });
-  }
-
-  /**
-   * @return {!Array<!Accessibility.AccessibilityNode>}
-   */
-  children() {
-    const children = [];
-    if (!this._childIds)
-      return children;
-
-    for (const childId of this._childIds) {
-      const child = this._accessibilityModel.axNodeForId(childId);
-      if (child)
-        children.push(child);
-    }
-
-    return children;
-  }
-
-  /**
-   * @return {number}
-   */
-  numChildren() {
-    if (!this._childIds)
-      return 0;
-    return this._childIds.length;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasOnlyUnloadedChildren() {
-    if (!this._childIds || !this._childIds.length)
-      return false;
-
-    return !this._childIds.some(id => this._accessibilityModel.axNodeForId(id) !== undefined);
-  }
-
-  /**
-   * TODO(aboxhall): Remove once protocol is stable.
-   * @param {!Accessibility.AccessibilityNode} inspectedNode
-   * @param {string=} leadingSpace
-   * @return {string}
-   */
-  printSelfAndChildren(inspectedNode, leadingSpace) {
-    let string = leadingSpace || '';
-    if (this._role)
-      string += this._role.value;
-    else
-      string += '<no role>';
-    string += (this._name ? ' ' + this._name.value : '');
-    string += ' ' + this._id;
-    if (this._domNode)
-      string += ' (' + this._domNode.nodeName() + ')';
-    if (this === inspectedNode)
-      string += ' *';
-    for (const child of this.children())
-      string += '\n' + child.printSelfAndChildren(inspectedNode, (leadingSpace || '') + '  ');
-    return string;
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AccessibilityModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._agent = target.accessibilityAgent();
-
-    /** @type {!Map<string, !Accessibility.AccessibilityNode>} */
-    this._axIdToAXNode = new Map();
-    this._backendDOMNodeIdToAXNode = new Map();
-  }
-
-  clear() {
-    this._axIdToAXNode.clear();
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise}
-   */
-  async requestPartialAXTree(node) {
-    const payloads = await this._agent.getPartialAXTree(node.id, undefined, undefined, true);
-    if (!payloads)
-      return;
-
-    for (const payload of payloads)
-      new Accessibility.AccessibilityNode(this, payload);
-
-    for (const axNode of this._axIdToAXNode.values()) {
-      for (const axChild of axNode.children())
-        axChild._setParentNode(axNode);
-    }
-  }
-
-  /**
-   * @param {string} axId
-   * @return {?Accessibility.AccessibilityNode}
-   */
-  axNodeForId(axId) {
-    return this._axIdToAXNode.get(axId);
-  }
-
-  /**
-   * @param {string} axId
-   * @param {!Accessibility.AccessibilityNode} axNode
-   */
-  _setAXNodeForAXId(axId, axNode) {
-    this._axIdToAXNode.set(axId, axNode);
-  }
-
-  /**
-   * @param {?SDK.DOMNode} domNode
-   * @return {?Accessibility.AccessibilityNode}
-   */
-  axNodeForDOMNode(domNode) {
-    if (!domNode)
-      return null;
-    return this._backendDOMNodeIdToAXNode.get(domNode.backendNodeId());
-  }
-
-  /**
-   * @param {number} backendDOMNodeId
-   * @param {!Accessibility.AccessibilityNode} axNode
-   */
-  _setAXNodeForBackendDOMNodeId(backendDOMNodeId, axNode) {
-    this._backendDOMNodeIdToAXNode.set(backendDOMNodeId, axNode);
-  }
-
-  // TODO(aboxhall): Remove once protocol is stable.
-  /**
-   * @param {!SDK.DOMNode} inspectedNode
-   */
-  logTree(inspectedNode) {
-    let rootNode = inspectedNode;
-    while (rootNode.parentNode())
-      rootNode = rootNode.parentNode();
-    console.log(rootNode.printSelfAndChildren(inspectedNode));  // eslint-disable-line no-console
-  }
-};
-
-SDK.SDKModel.register(Accessibility.AccessibilityModel, SDK.Target.Capability.DOM, false);
diff --git a/front_end/accessibility/AccessibilityNodeView.js b/front_end/accessibility/AccessibilityNodeView.js
deleted file mode 100644
index f0c0a2e..0000000
--- a/front_end/accessibility/AccessibilityNodeView.js
+++ /dev/null
@@ -1,624 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Accessibility.AXNodeSubPane = class extends Accessibility.AccessibilitySubPane {
-  constructor() {
-    super(ls`Computed Properties`);
-
-    this.contentElement.classList.add('ax-subpane');
-
-    this._noNodeInfo = this.createInfo(ls`No accessibility node`);
-    this._ignoredInfo = this.createInfo(ls`Accessibility node not exposed`, 'ax-ignored-info hidden');
-
-    this._treeOutline = this.createTreeOutline();
-    this._ignoredReasonsTree = this.createTreeOutline();
-
-    this.element.classList.add('accessibility-computed');
-    this.registerRequiredCSS('accessibility/accessibilityNode.css');
-  }
-
-  /**
-   * @param {?Accessibility.AccessibilityNode} axNode
-   * @override
-   */
-  setAXNode(axNode) {
-    if (this._axNode === axNode)
-      return;
-    this._axNode = axNode;
-
-    const treeOutline = this._treeOutline;
-    treeOutline.removeChildren();
-    const ignoredReasons = this._ignoredReasonsTree;
-    ignoredReasons.removeChildren();
-
-    if (!axNode) {
-      treeOutline.element.classList.add('hidden');
-      this._ignoredInfo.classList.add('hidden');
-      ignoredReasons.element.classList.add('hidden');
-
-      this._noNodeInfo.classList.remove('hidden');
-      this.element.classList.add('ax-ignored-node-pane');
-
-      return;
-    }
-
-    if (axNode.ignored()) {
-      this._noNodeInfo.classList.add('hidden');
-      treeOutline.element.classList.add('hidden');
-      this.element.classList.add('ax-ignored-node-pane');
-
-      this._ignoredInfo.classList.remove('hidden');
-      ignoredReasons.element.classList.remove('hidden');
-      /**
-       * @param {!Protocol.Accessibility.AXProperty} property
-       */
-      function addIgnoredReason(property) {
-        ignoredReasons.appendChild(new Accessibility.AXNodeIgnoredReasonTreeElement(
-            property, /** @type {!Accessibility.AccessibilityNode} */ (axNode)));
-      }
-      const ignoredReasonsArray = /** @type {!Array<!Protocol.Accessibility.AXProperty>} */ (axNode.ignoredReasons());
-      for (const reason of ignoredReasonsArray)
-        addIgnoredReason(reason);
-      if (!ignoredReasons.firstChild())
-        ignoredReasons.element.classList.add('hidden');
-      return;
-    }
-    this.element.classList.remove('ax-ignored-node-pane');
-
-    this._ignoredInfo.classList.add('hidden');
-    ignoredReasons.element.classList.add('hidden');
-    this._noNodeInfo.classList.add('hidden');
-
-    treeOutline.element.classList.remove('hidden');
-
-    /**
-     * @param {!Protocol.Accessibility.AXProperty} property
-     */
-    function addProperty(property) {
-      treeOutline.appendChild(new Accessibility.AXNodePropertyTreePropertyElement(
-          property, /** @type {!Accessibility.AccessibilityNode} */ (axNode)));
-    }
-
-    for (const property of axNode.coreProperties())
-      addProperty(property);
-
-    const roleProperty = /** @type {!Protocol.Accessibility.AXProperty} */ ({name: 'role', value: axNode.role()});
-    addProperty(roleProperty);
-    for (const property of /** @type {!Array.<!Protocol.Accessibility.AXProperty>} */ (axNode.properties()))
-      addProperty(property);
-  }
-
-  /**
-   * @override
-   * @param {?SDK.DOMNode} node
-   */
-  setNode(node) {
-    super.setNode(node);
-    this._axNode = null;
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AXNodePropertyTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Accessibility.AccessibilityNode} axNode
-   */
-  constructor(axNode) {
-    // Pass an empty title, the title gets made later in onattach.
-    super('');
-    this._axNode = axNode;
-  }
-
-  /**
-   * @param {?Protocol.Accessibility.AXValueType} type
-   * @param {string} value
-   * @return {!Element}
-   */
-  static createSimpleValueElement(type, value) {
-    let valueElement;
-    const AXValueType = Protocol.Accessibility.AXValueType;
-    if (!type || type === AXValueType.ValueUndefined || type === AXValueType.ComputedString)
-      valueElement = createElement('span');
-    else
-      valueElement = createElementWithClass('span', 'monospace');
-    let valueText;
-    const isStringProperty = type && Accessibility.AXNodePropertyTreeElement.StringProperties.has(type);
-    if (isStringProperty) {
-      // Render \n as a nice unicode cr symbol.
-      valueText = '"' + value.replace(/\n/g, '\u21B5') + '"';
-      valueElement._originalTextContent = value;
-    } else {
-      valueText = String(value);
-    }
-
-    if (type && type in Accessibility.AXNodePropertyTreeElement.TypeStyles)
-      valueElement.classList.add(Accessibility.AXNodePropertyTreeElement.TypeStyles[type]);
-
-    valueElement.setTextContentTruncatedIfNeeded(valueText || '');
-
-    valueElement.title = String(value) || '';
-
-    return valueElement;
-  }
-
-  /**
-   * @param {string} tooltip
-   * @return {!Element}
-   */
-  static createExclamationMark(tooltip) {
-    const exclamationElement = createElement('label', 'dt-icon-label');
-    exclamationElement.type = 'smallicon-warning';
-    exclamationElement.title = tooltip;
-    return exclamationElement;
-  }
-
-  /**
-   * @param {string} name
-   */
-  appendNameElement(name) {
-    const nameElement = createElement('span');
-    const AXAttributes = Accessibility.AccessibilityStrings.AXAttributes;
-    if (name in AXAttributes) {
-      nameElement.textContent = ls(AXAttributes[name].name);
-      nameElement.title = AXAttributes[name].description;
-      nameElement.classList.add('ax-readable-name');
-    } else {
-      nameElement.textContent = name;
-      nameElement.classList.add('ax-name');
-      nameElement.classList.add('monospace');
-    }
-    this.listItemElement.appendChild(nameElement);
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXValue} value
-   */
-  appendValueElement(value) {
-    const AXValueType = Protocol.Accessibility.AXValueType;
-    if (value.type === AXValueType.Idref || value.type === AXValueType.Node || value.type === AXValueType.IdrefList ||
-        value.type === AXValueType.NodeList) {
-      this.appendRelatedNodeListValueElement(value);
-      return;
-    } else if (value.sources) {
-      const sources = value.sources;
-      for (let i = 0; i < sources.length; i++) {
-        const source = sources[i];
-        const child = new Accessibility.AXValueSourceTreeElement(source, this._axNode);
-        this.appendChild(child);
-      }
-      this.expand();
-    }
-    const element = Accessibility.AXNodePropertyTreeElement.createSimpleValueElement(value.type, String(value.value));
-    this.listItemElement.appendChild(element);
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXRelatedNode} relatedNode
-   * @param {number} index
-   */
-  appendRelatedNode(relatedNode, index) {
-    const deferredNode =
-        new SDK.DeferredDOMNode(this._axNode.accessibilityModel().target(), relatedNode.backendDOMNodeId);
-    const nodeTreeElement = new Accessibility.AXRelatedNodeSourceTreeElement({deferredNode: deferredNode}, relatedNode);
-    this.appendChild(nodeTreeElement);
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXRelatedNode} relatedNode
-   */
-  appendRelatedNodeInline(relatedNode) {
-    const deferredNode =
-        new SDK.DeferredDOMNode(this._axNode.accessibilityModel().target(), relatedNode.backendDOMNodeId);
-    const linkedNode = new Accessibility.AXRelatedNodeElement({deferredNode: deferredNode}, relatedNode);
-    this.listItemElement.appendChild(linkedNode.render());
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXValue} value
-   */
-  appendRelatedNodeListValueElement(value) {
-    if (value.relatedNodes.length === 1 && !value.value) {
-      this.appendRelatedNodeInline(value.relatedNodes[0]);
-      return;
-    }
-
-    value.relatedNodes.forEach(this.appendRelatedNode, this);
-    if (value.relatedNodes.length <= 3)
-      this.expand();
-    else
-      this.collapse();
-  }
-};
-
-
-/** @type {!Object<string, string>} */
-Accessibility.AXNodePropertyTreeElement.TypeStyles = {
-  attribute: 'ax-value-string',
-  boolean: 'object-value-boolean',
-  booleanOrUndefined: 'object-value-boolean',
-  computedString: 'ax-readable-string',
-  idref: 'ax-value-string',
-  idrefList: 'ax-value-string',
-  integer: 'object-value-number',
-  internalRole: 'ax-internal-role',
-  number: 'ax-value-number',
-  role: 'ax-role',
-  string: 'ax-value-string',
-  tristate: 'object-value-boolean',
-  valueUndefined: 'ax-value-undefined'
-};
-
-/** @type {!Set.<!Protocol.Accessibility.AXValueType>} */
-Accessibility.AXNodePropertyTreeElement.StringProperties = new Set([
-  Protocol.Accessibility.AXValueType.String, Protocol.Accessibility.AXValueType.ComputedString,
-  Protocol.Accessibility.AXValueType.IdrefList, Protocol.Accessibility.AXValueType.Idref
-]);
-
-/**
- * @unrestricted
- */
-Accessibility.AXNodePropertyTreePropertyElement = class extends Accessibility.AXNodePropertyTreeElement {
-  /**
-   * @param {!Protocol.Accessibility.AXProperty} property
-   * @param {!Accessibility.AccessibilityNode} axNode
-   */
-  constructor(property, axNode) {
-    super(axNode);
-
-    this._property = property;
-    this.toggleOnClick = true;
-    this.selectable = false;
-
-    this.listItemElement.classList.add('property');
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this._update();
-  }
-
-  _update() {
-    this.listItemElement.removeChildren();
-
-    this.appendNameElement(this._property.name);
-
-    this.listItemElement.createChild('span', 'separator').textContent = ':\u00A0';
-
-    this.appendValueElement(this._property.value);
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AXValueSourceTreeElement = class extends Accessibility.AXNodePropertyTreeElement {
-  /**
-   * @param {!Protocol.Accessibility.AXValueSource} source
-   * @param {!Accessibility.AccessibilityNode} axNode
-   */
-  constructor(source, axNode) {
-    super(axNode);
-    this._source = source;
-    this.selectable = false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this._update();
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXRelatedNode} relatedNode
-   * @param {number} index
-   * @param {string} idref
-   */
-  appendRelatedNodeWithIdref(relatedNode, index, idref) {
-    const deferredNode =
-        new SDK.DeferredDOMNode(this._axNode.accessibilityModel().target(), relatedNode.backendDOMNodeId);
-    const nodeTreeElement =
-        new Accessibility.AXRelatedNodeSourceTreeElement({deferredNode: deferredNode, idref: idref}, relatedNode);
-    this.appendChild(nodeTreeElement);
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXValue} value
-   */
-  appendIDRefValueElement(value) {
-    const relatedNodes = value.relatedNodes;
-
-    const idrefs = value.value.trim().split(/\s+/);
-    if (idrefs.length === 1) {
-      const idref = idrefs[0];
-      const matchingNode = relatedNodes.find(node => node.idref === idref);
-      if (matchingNode)
-        this.appendRelatedNodeWithIdref(matchingNode, 0, idref);
-      else
-        this.listItemElement.appendChild(new Accessibility.AXRelatedNodeElement({idref: idref}).render());
-
-    } else {
-      // TODO(aboxhall): exclamation mark if not idreflist type
-      for (let i = 0; i < idrefs.length; ++i) {
-        const idref = idrefs[i];
-        const matchingNode = relatedNodes.find(node => node.idref === idref);
-        if (matchingNode)
-          this.appendRelatedNodeWithIdref(matchingNode, i, idref);
-        else
-          this.appendChild(new Accessibility.AXRelatedNodeSourceTreeElement({idref: idref}));
-      }
-    }
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXValue} value
-   * @override
-   */
-  appendRelatedNodeListValueElement(value) {
-    const relatedNodes = value.relatedNodes;
-    const numNodes = relatedNodes.length;
-
-    if (value.type === Protocol.Accessibility.AXValueType.IdrefList ||
-        value.type === Protocol.Accessibility.AXValueType.Idref)
-      this.appendIDRefValueElement(value);
-    else
-      super.appendRelatedNodeListValueElement(value);
-
-
-    if (numNodes <= 3)
-      this.expand();
-    else
-      this.collapse();
-  }
-
-  /**
-   * @param {!Protocol.Accessibility.AXValueSource} source
-   */
-  appendSourceNameElement(source) {
-    const nameElement = createElement('span');
-    const AXValueSourceType = Protocol.Accessibility.AXValueSourceType;
-    const type = source.type;
-    switch (type) {
-      case AXValueSourceType.Attribute:
-      case AXValueSourceType.Placeholder:
-      case AXValueSourceType.RelatedElement:
-        if (source.nativeSource) {
-          const AXNativeSourceTypes = Accessibility.AccessibilityStrings.AXNativeSourceTypes;
-          const nativeSource = source.nativeSource;
-          nameElement.textContent = ls(AXNativeSourceTypes[nativeSource].name);
-          nameElement.title = ls(AXNativeSourceTypes[nativeSource].description);
-          nameElement.classList.add('ax-readable-name');
-          break;
-        }
-        nameElement.textContent = source.attribute;
-        nameElement.classList.add('ax-name');
-        nameElement.classList.add('monospace');
-        break;
-      default:
-        const AXSourceTypes = Accessibility.AccessibilityStrings.AXSourceTypes;
-        if (type in AXSourceTypes) {
-          nameElement.textContent = ls(AXSourceTypes[type].name);
-          nameElement.title = ls(AXSourceTypes[type].description);
-          nameElement.classList.add('ax-readable-name');
-        } else {
-          console.warn(type, 'not in AXSourceTypes');
-          nameElement.textContent = ls(type);
-        }
-    }
-    this.listItemElement.appendChild(nameElement);
-  }
-
-  _update() {
-    this.listItemElement.removeChildren();
-
-    if (this._source.invalid) {
-      const exclamationMark = Accessibility.AXNodePropertyTreeElement.createExclamationMark(ls`Invalid source.`);
-      this.listItemElement.appendChild(exclamationMark);
-      this.listItemElement.classList.add('ax-value-source-invalid');
-    } else if (this._source.superseded) {
-      this.listItemElement.classList.add('ax-value-source-unused');
-    }
-
-    this.appendSourceNameElement(this._source);
-
-    this.listItemElement.createChild('span', 'separator').textContent = ':\u00a0';
-
-    if (this._source.attributeValue) {
-      this.appendValueElement(this._source.attributeValue);
-      this.listItemElement.createTextChild('\u00a0');
-    } else if (this._source.nativeSourceValue) {
-      this.appendValueElement(this._source.nativeSourceValue);
-      this.listItemElement.createTextChild('\u00a0');
-      if (this._source.value)
-        this.appendValueElement(this._source.value);
-    } else if (this._source.value) {
-      this.appendValueElement(this._source.value);
-    } else {
-      const valueElement = Accessibility.AXNodePropertyTreeElement.createSimpleValueElement(
-          Protocol.Accessibility.AXValueType.ValueUndefined, ls`Not specified`);
-      this.listItemElement.appendChild(valueElement);
-      this.listItemElement.classList.add('ax-value-source-unused');
-    }
-
-    if (this._source.value && this._source.superseded)
-      this.listItemElement.classList.add('ax-value-source-superseded');
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AXRelatedNodeSourceTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {{deferredNode: (!SDK.DeferredDOMNode|undefined), idref: (string|undefined)}} node
-   * @param {!Protocol.Accessibility.AXRelatedNode=} value
-   */
-  constructor(node, value) {
-    super('');
-
-    this._value = value;
-    this._axRelatedNodeElement = new Accessibility.AXRelatedNodeElement(node, value);
-    this.selectable = false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.appendChild(this._axRelatedNodeElement.render());
-    if (!this._value)
-      return;
-
-    if (this._value.text) {
-      this.listItemElement.appendChild(Accessibility.AXNodePropertyTreeElement.createSimpleValueElement(
-          Protocol.Accessibility.AXValueType.ComputedString, this._value.text));
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AXRelatedNodeElement = class {
-  /**
-   * @param {{deferredNode: (!SDK.DeferredDOMNode|undefined), idref: (string|undefined)}} node
-   * @param {!Protocol.Accessibility.AXRelatedNode=} value
-   */
-  constructor(node, value) {
-    this._deferredNode = node.deferredNode;
-    this._idref = node.idref;
-    this._value = value;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  render() {
-    const element = createElement('span');
-    let valueElement;
-
-    if (this._deferredNode) {
-      valueElement = createElement('span');
-      element.appendChild(valueElement);
-      Common.Linkifier.linkify(this._deferredNode).then(linkfied => valueElement.appendChild(linkfied));
-    } else if (this._idref) {
-      element.classList.add('invalid');
-      valueElement = Accessibility.AXNodePropertyTreeElement.createExclamationMark(ls`No node with this ID.`);
-      valueElement.createTextChild(this._idref);
-      element.appendChild(valueElement);
-    }
-
-    return element;
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AXNodeIgnoredReasonTreeElement = class extends Accessibility.AXNodePropertyTreeElement {
-  /**
-   * @param {!Protocol.Accessibility.AXProperty} property
-   * @param {!Accessibility.AccessibilityNode} axNode
-   */
-  constructor(property, axNode) {
-    super(axNode);
-    this._property = property;
-    this._axNode = axNode;
-    this.toggleOnClick = true;
-    this.selectable = false;
-  }
-
-  /**
-   * @param {?string} reason
-   * @param {?Accessibility.AccessibilityNode} axNode
-   * @return {?Element}
-   */
-  static createReasonElement(reason, axNode) {
-    let reasonElement = null;
-    switch (reason) {
-      case 'activeModalDialog':
-        reasonElement = UI.formatLocalized('Element is hidden by active modal dialog:\u00a0', []);
-        break;
-      case 'ancestorIsLeafNode':
-        reasonElement = UI.formatLocalized('Ancestor\'s children are all presentational:\u00a0', []);
-        break;
-      case 'ariaHiddenElement': {
-        const ariaHiddenSpan = createElement('span', 'source-code').textContent = 'aria-hidden';
-        reasonElement = UI.formatLocalized('Element is %s.', [ariaHiddenSpan]);
-        break;
-      }
-      case 'ariaHiddenSubtree': {
-        const ariaHiddenSpan = createElement('span', 'source-code').textContent = 'aria-hidden';
-        const trueSpan = createElement('span', 'source-code').textContent = 'true';
-        reasonElement = UI.formatLocalized('%s is %s on ancestor:\u00a0', [ariaHiddenSpan, trueSpan]);
-        break;
-      }
-      case 'emptyAlt':
-        reasonElement = UI.formatLocalized('Element has empty alt text.', []);
-        break;
-      case 'emptyText':
-        reasonElement = UI.formatLocalized('No text content.', []);
-        break;
-      case 'inertElement':
-        reasonElement = UI.formatLocalized('Element is inert.', []);
-        break;
-      case 'inertSubtree':
-        reasonElement = UI.formatLocalized('Element is in an inert subtree from\u00a0', []);
-        break;
-      case 'inheritsPresentation':
-        reasonElement = UI.formatLocalized('Element inherits presentational role from\u00a0', []);
-        break;
-      case 'labelContainer':
-        reasonElement = UI.formatLocalized('Part of label element:\u00a0', []);
-        break;
-      case 'labelFor':
-        reasonElement = UI.formatLocalized('Label for\u00a0', []);
-        break;
-      case 'notRendered':
-        reasonElement = UI.formatLocalized('Element is not rendered.', []);
-        break;
-      case 'notVisible':
-        reasonElement = UI.formatLocalized('Element is not visible.', []);
-        break;
-      case 'presentationalRole': {
-        const rolePresentationSpan = createElement('span', 'source-code').textContent = 'role=' + axNode.role().value;
-        reasonElement = UI.formatLocalized('Element has %s.', [rolePresentationSpan]);
-        break;
-      }
-      case 'probablyPresentational':
-        reasonElement = UI.formatLocalized('Element is presentational.', []);
-        break;
-      case 'staticTextUsedAsNameFor':
-        reasonElement = UI.formatLocalized('Static text node is used as name for\u00a0', []);
-        break;
-      case 'uninteresting':
-        reasonElement = UI.formatLocalized('Element not interesting for accessibility.', []);
-        break;
-    }
-    if (reasonElement)
-      reasonElement.classList.add('ax-reason');
-    return reasonElement;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.removeChildren();
-
-    this._reasonElement =
-        Accessibility.AXNodeIgnoredReasonTreeElement.createReasonElement(this._property.name, this._axNode);
-    this.listItemElement.appendChild(this._reasonElement);
-
-    const value = this._property.value;
-    if (value.type === Protocol.Accessibility.AXValueType.Idref)
-      this.appendRelatedNodeListValueElement(value);
-  }
-};
diff --git a/front_end/accessibility/AccessibilitySidebarView.js b/front_end/accessibility/AccessibilitySidebarView.js
deleted file mode 100644
index 21da831..0000000
--- a/front_end/accessibility/AccessibilitySidebarView.js
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Accessibility.AccessibilitySidebarView = class extends UI.ThrottledWidget {
-  constructor() {
-    super();
-    this._node = null;
-    this._axNode = null;
-    this._skipNextPullNode = false;
-    this._sidebarPaneStack = UI.viewManager.createStackLocation();
-    this._breadcrumbsSubPane = new Accessibility.AXBreadcrumbsPane(this);
-    this._sidebarPaneStack.showView(this._breadcrumbsSubPane);
-    this._ariaSubPane = new Accessibility.ARIAAttributesPane();
-    this._sidebarPaneStack.showView(this._ariaSubPane);
-    this._axNodeSubPane = new Accessibility.AXNodeSubPane();
-    this._sidebarPaneStack.showView(this._axNodeSubPane);
-    this._sidebarPaneStack.widget().show(this.element);
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this._pullNode, this);
-    this._pullNode();
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @return {?Accessibility.AccessibilityNode}
-   */
-  axNode() {
-    return this._axNode;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   * @param {boolean=} fromAXTree
-   */
-  setNode(node, fromAXTree) {
-    this._skipNextPullNode = !!fromAXTree;
-    this._node = node;
-    this.update();
-  }
-
-  /**
-   * @param {?Accessibility.AccessibilityNode} axNode
-   */
-  accessibilityNodeCallback(axNode) {
-    if (!axNode)
-      return;
-
-    this._axNode = axNode;
-
-    if (axNode.isDOMNode())
-      this._sidebarPaneStack.showView(this._ariaSubPane, this._axNodeSubPane);
-    else
-      this._sidebarPaneStack.removeView(this._ariaSubPane);
-
-    if (this._axNodeSubPane)
-      this._axNodeSubPane.setAXNode(axNode);
-    if (this._breadcrumbsSubPane)
-      this._breadcrumbsSubPane.setAXNode(axNode);
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    const node = this.node();
-    this._axNodeSubPane.setNode(node);
-    this._ariaSubPane.setNode(node);
-    this._breadcrumbsSubPane.setNode(node);
-    if (!node)
-      return Promise.resolve();
-    const accessibilityModel = node.domModel().target().model(Accessibility.AccessibilityModel);
-    accessibilityModel.clear();
-    return accessibilityModel.requestPartialAXTree(node).then(() => {
-      this.accessibilityNodeCallback(accessibilityModel.axNodeForDOMNode(node));
-    });
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-
-    this._breadcrumbsSubPane.setNode(this.node());
-    this._breadcrumbsSubPane.setAXNode(this.axNode());
-    this._axNodeSubPane.setNode(this.node());
-    this._axNodeSubPane.setAXNode(this.axNode());
-    this._ariaSubPane.setNode(this.node());
-
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrModified, this._onAttrChange, this);
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrRemoved, this._onAttrChange, this);
-    SDK.targetManager.addModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
-    SDK.targetManager.addModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.ChildNodeCountUpdated, this._onNodeChange, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    SDK.targetManager.removeModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrModified, this._onAttrChange, this);
-    SDK.targetManager.removeModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrRemoved, this._onAttrChange, this);
-    SDK.targetManager.removeModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
-    SDK.targetManager.removeModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.ChildNodeCountUpdated, this._onNodeChange, this);
-  }
-
-  _pullNode() {
-    if (this._skipNextPullNode) {
-      this._skipNextPullNode = false;
-      return;
-    }
-    this.setNode(UI.context.flavor(SDK.DOMNode));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onAttrChange(event) {
-    if (!this.node())
-      return;
-    const node = event.data.node;
-    if (this.node() !== node)
-      return;
-    this.update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onNodeChange(event) {
-    if (!this.node())
-      return;
-    const node = event.data;
-    if (this.node() !== node)
-      return;
-    this.update();
-  }
-};
-
-/**
- * @unrestricted
- */
-Accessibility.AccessibilitySubPane = class extends UI.SimpleView {
-  /**
-   * @param {string} name
-   */
-  constructor(name) {
-    super(name);
-
-    this._axNode = null;
-    this.registerRequiredCSS('accessibility/accessibilityProperties.css');
-  }
-
-  /**
-   * @param {?Accessibility.AccessibilityNode} axNode
-   * @protected
-   */
-  setAXNode(axNode) {
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  setNode(node) {
-    this._node = node;
-  }
-
-  /**
-   * @param {string} textContent
-   * @param {string=} className
-   * @return {!Element}
-   */
-  createInfo(textContent, className) {
-    const classNameOrDefault = className || 'gray-info-message';
-    const info = this.element.createChild('div', classNameOrDefault);
-    info.textContent = textContent;
-    return info;
-  }
-
-  /**
-   * @return {!UI.TreeOutline}
-   */
-  createTreeOutline() {
-    const treeOutline = new UI.TreeOutlineInShadow();
-    treeOutline.registerRequiredCSS('accessibility/accessibilityNode.css');
-    treeOutline.registerRequiredCSS('accessibility/accessibilityProperties.css');
-    treeOutline.registerRequiredCSS('object_ui/objectValue.css');
-
-    treeOutline.element.classList.add('hidden');
-    treeOutline.hideOverflow();
-    this.element.appendChild(treeOutline.element);
-    return treeOutline;
-  }
-};
diff --git a/front_end/accessibility/AccessibilityStrings.js b/front_end/accessibility/AccessibilityStrings.js
deleted file mode 100644
index 50d31b2..0000000
--- a/front_end/accessibility/AccessibilityStrings.js
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Accessibility.AccessibilityStrings = {};
-
-Accessibility.AccessibilityStrings.AXAttributes = {
-  'disabled': {
-    name: 'Disabled',
-    description: 'If true, this element currently cannot be interacted with.',
-    group: 'AXGlobalStates'
-  },
-  'invalid': {
-    name: 'Invalid user entry',
-    description: 'If true, this element\'s user-entered value does not conform to validation requirement.',
-    group: 'AXGlobalStates'
-  },
-  'live': {
-    name: 'Live region',
-    description: 'Whether and what priority of live updates may be expected for this element.',
-    group: 'AXLiveRegionAttributes'
-  },
-  'atomic': {
-    name: 'Atomic (live regions)',
-    description:
-        'If this element may receive live updates, whether the entire live region should be presented to the user on changes, or only changed nodes.',
-    group: 'AXLiveRegionAttributes'
-  },
-  'relevant': {
-    name: 'Relevant (live regions)',
-    description: 'If this element may receive live updates, what type of updates should trigger a notification.',
-    group: 'AXLiveRegionAttributes'
-  },
-  'busy': {
-    name: 'Busy (live regions)',
-    description:
-        'Whether this element or its subtree are currently being updated (and thus may be in an inconsistent state).',
-    group: 'AXLiveRegionAttributes'
-  },
-  'root': {
-    name: 'Live region root',
-    description: 'If this element may receive live updates, the root element of the containing live region.',
-    group: 'AXLiveRegionAttributes'
-  },
-  'autocomplete': {
-    name: 'Has autocomplete',
-    description: 'Whether and what type of autocomplete suggestions are currently provided by this element.',
-    group: 'AXWidgetAttributes'
-  },
-  'haspopup': {
-    name: 'Has popup',
-    description: 'Whether this element has caused some kind of pop-up (such as a menu) to appear.',
-    group: 'AXWidgetAttributes'
-  },
-  'level': {name: 'Level', description: 'The hierarchical level of this element.', group: 'AXWidgetAttributes'},
-  'multiselectable': {
-    name: 'Multi-selectable',
-    description: 'Whether a user may select more than one option from this widget.',
-    group: 'AXWidgetAttributes'
-  },
-  'orientation': {
-    name: 'Orientation',
-    description: 'Whether this linear element\'s orientation is horizontal or vertical.',
-    group: 'AXWidgetAttributes'
-  },
-  'multiline': {
-    name: 'Multi-line',
-    description: 'Whether this textbox may have more than one line.',
-    group: 'AXWidgetAttributes'
-  },
-  'readonly': {
-    name: 'Read-only',
-    description: 'If true, this element may be interacted with, but its value cannot be changed.',
-    group: 'AXWidgetAttributes'
-  },
-  'required': {
-    name: 'Required',
-    description: 'Whether this element is a required field in a form.',
-    group: 'AXWidgetAttributes'
-  },
-  'valuemin': {
-    name: 'Minimum value',
-    description: 'For a range widget, the minimum allowed value.',
-    group: 'AXWidgetAttributes'
-  },
-  'valuemax': {
-    name: 'Maximum value',
-    description: 'For a range widget, the maximum allowed value.',
-    group: 'AXWidgetAttributes'
-  },
-  'valuetext': {
-    name: 'Value description',
-    description: 'A human-readable version of the value of a range widget (where necessary).',
-    group: 'AXWidgetAttributes'
-  },
-  'checked': {
-    name: 'Checked',
-    description:
-        'Whether this checkbox, radio button or tree item is checked, unchecked, or mixed (e.g. has both checked and un-checked children).',
-    group: 'AXWidgetStates'
-  },
-  'expanded': {
-    name: 'Expanded',
-    description: 'Whether this element, or another grouping element it controls, is expanded.',
-    group: 'AXWidgetStates'
-  },
-  'pressed': {
-    name: 'Pressed',
-    description: 'Whether this toggle button is currently in a pressed state.',
-    group: 'AXWidgetStates'
-  },
-  'selected': {
-    name: 'Selected',
-    description: 'Whether the option represented by this element is currently selected.',
-    group: 'AXWidgetStates'
-  },
-  'activedescendant': {
-    name: 'Active descendant',
-    description: 'The descendant of this element which is active; i.e. the element to which focus should be delegated.',
-    group: 'AXRelationshipAttributes'
-  },
-  'flowto': {
-    name: 'Flows to',
-    description:
-        'Element to which the user may choose to navigate after this one, instead of the next element in the DOM order.',
-    group: 'AXRelationshipAttributes'
-  },
-  'controls': {
-    name: 'Controls',
-    description: 'Element or elements whose content or presence is/are controlled by this widget.',
-    group: 'AXRelationshipAttributes'
-  },
-  'describedby': {
-    name: 'Described by',
-    description: 'Element or elements which form the description of this element.',
-    group: 'AXRelationshipAttributes'
-  },
-  'labelledby': {
-    name: 'Labeled by',
-    description: 'Element or elements which may form the name of this element.',
-    group: 'AXRelationshipAttributes'
-  },
-  'owns': {
-    name: 'Owns',
-    description:
-        'Element or elements which should be considered descendants of this element, despite not being descendants in the DOM.',
-    group: 'AXRelationshipAttributes'
-  },
-  'name': {name: 'Name', description: 'The computed name of this element.', group: 'Default'},
-  'role': {
-    name: 'Role',
-    description:
-        'Indicates the purpose of this element, such as a user interface idiom for a widget, or structural role within a document.',
-    group: 'Default'
-  },
-  'value': {
-    name: 'Value',
-    description:
-        'The value of this element; this may be user-provided or developer-provided, depending on the element.',
-    group: 'Default'
-  },
-  'help': {name: 'Help', description: 'The computed help text for this element.', group: 'Default'},
-  'description': {name: 'Description', description: 'The accessible description for this element.', group: 'Default'}
-};
-
-Accessibility.AccessibilityStrings.AXSourceTypes = {
-  'attribute': {name: 'From attribute', description: 'Value from attribute.'},
-  'implicit': {
-    name: 'Implicit',
-    description: 'Implicit value.',
-  },
-  'style': {name: 'From style', description: 'Value from style.'},
-  'contents': {name: 'Contents', description: 'Value from element contents.'},
-  'placeholder': {name: 'From placeholder attribute', description: 'Value from placeholder attribute.'},
-  'relatedElement': {name: 'Related element', description: 'Value from related element.'}
-};
-
-Accessibility.AccessibilityStrings.AXNativeSourceTypes = {
-  'figcaption': {name: 'From caption', description: 'Value from figcaption element.'},
-  'label': {name: 'From label', description: 'Value from label element.'},
-  'labelfor': {name: 'From label (for)', description: 'Value from label element with for= attribute.'},
-  'labelwrapped': {name: 'From label (wrapped)', description: 'Value from label element wrapped.'},
-  'tablecaption': {name: 'From caption', description: 'Value from table caption.'},
-  'title': {'name': 'From title', 'description': 'Value from title attribute.'},
-  'other': {name: 'From native HTML', description: 'Value from native HTML (unknown source).'},
-
-};
diff --git a/front_end/accessibility/accessibilityNode.css b/front_end/accessibility/accessibilityNode.css
deleted file mode 100644
index a6e59ca..0000000
--- a/front_end/accessibility/accessibilityNode.css
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.sidebar-pane.accessibility-computed {
-    background-color: rgba(0, 0, 0, 0.03);
-}
-
-.widget.ax-subpane {
-    overflow-x: hidden;
-    -webkit-user-select: text;
-}
-
-div.ax-text-alternatives {
-    margin-bottom: 3px;
-    border-bottom: 1px solid #BFBFBF;
-}
-
-.ax-ignored-info {
-    padding: 6px;
-}
-
-.ax-ignored-node-pane {
-    flex: none;
-}
-
-.invalid {
-    text-decoration: line-through;
-}
-
-span.ax-value-undefined {
-    font-style: italic;
-}
-
-.ax-value-source-unused {
-    opacity: 0.7;
-}
-
-.ax-value-source-superseded,
-.ax-value-source-invalid {
-    text-decoration: line-through;
-}
-
-.sidebar-pane-stack .sidebar-pane {
-    padding-left: 4px;
-}
-
-.tree-outline label[is=dt-icon-label] {
-    position: relative;
-    left: -11px;
-}
-
-.tree-outline li {
-    display: block;
-    overflow-x: hidden;
-    padding-left: 1px;
-    align-items: baseline;
-}
-
-.tree-outline li::before {
-    content: "";
-    width: 14px;
-    display: inline-block;
-}
-
-.tree-outline li.property {
-    color: rgb(33, 33, 33);
-}
-
-.tree-outline li.invalid {
-    position: relative;
-    left: -2px;
-}
-
-.tree-outline label[is=dt-icon-label] + .ax-name {
-    margin-left: -11px;
-}
-
-.tree-outline li span {
-    flex-shrink: 0;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}
diff --git a/front_end/accessibility/accessibilityProperties.css b/front_end/accessibility/accessibilityProperties.css
deleted file mode 100644
index c193898..0000000
--- a/front_end/accessibility/accessibilityProperties.css
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.ax-name {
-    color: rgb(153, 69, 0);
-    flex-shrink: 0;
-}
-
-.ax-readable-name {
-    flex-shrink: 0;
-    padding-left: 2px;
-}
-
-.ax-readable-string {
-    font-style: italic;
-}
-
-.ax-value-string {
-    color: rgb(200, 0, 0);
-}
-
-span.ax-internal-role {
-    font-style: italic;
-}
diff --git a/front_end/accessibility/axBreadcrumbs.css b/front_end/accessibility/axBreadcrumbs.css
deleted file mode 100644
index 70c8f49..0000000
--- a/front_end/accessibility/axBreadcrumbs.css
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.ax-breadcrumbs-ignored-node {
-    font-style: italic;
-    opacity: 0.7;
-}
-
-.ax-breadcrumbs {
-    padding-top: 1px;
-    margin: 0;
-    position: relative;
-}
-
-.ax-breadcrumbs .ax-node {
-    align-items: center;
-    margin-top: 1px;
-    min-height: 16px;
-    overflow-x: hidden;
-    padding-left: 4px;
-    padding-right: 4px;
-    padding-top: 1px;
-    position: relative;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}
-
-.ax-breadcrumbs .ax-node span {
-    flex-shrink: 0;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}
-
-.ax-breadcrumbs .ax-node .wrapper {
-    padding-left: 12px;
-    overflow-x: hidden;
-}
-
-.ax-breadcrumbs .ax-node::before {
-    -webkit-mask-image: url(Images/chevrons.png);
-    -webkit-mask-position: 0 0;
-    -webkit-mask-size: 30px 10px;
-    -webkit-mask-repeat: no-repeat;
-    background-color: rgb(48, 57, 66);
-    content: "";
-    text-shadow: none;
-    margin-right: -2px;
-    height: 12px;
-    width: 14px;
-    position: absolute;
-    display: inline-block;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-    .ax-breadcrumbs .ax-node::before {
-        -webkit-mask-image: url(Images/chevrons_2x.png);
-    }
-} /* media */
-
-.ax-breadcrumbs .ax-node:not(.parent):not(.children-unloaded)::before {
-    background-color: transparent;
-}
-
-.ax-breadcrumbs .ax-node.parent::before {
-    -webkit-mask-position: -20px 1px;
-}
-
-.ax-breadcrumbs .ax-node.children-unloaded::before {
-    -webkit-mask-position: 0px 1px;
-    width: 13px;
-}
-
-.ax-breadcrumbs .ax-node.no-dom-node {
-    opacity: 0.7;
-}
-
-.ax-breadcrumbs .ax-node.children-unloaded::before {
-    opacity: 0.4;
-}
-
-.ax-breadcrumbs .ax-node.preselected:not(.inspected) .selection,
-.ax-breadcrumbs .ax-node.hovered:not(.inspected) .selection {
-    display: block;
-    left: 2px;
-    right: 2px;
-    background-color: rgba(56, 121, 217, 0.1);
-    border-radius: 5px;
-}
-
-.ax-breadcrumbs .ax-node.preselected:not(.inspected):focus .selection {
-    border: 1px solid rgba(56, 121, 217, 0.4);
-}
-
-.ax-breadcrumbs .ax-node .selection {
-    display: none;
-    z-index: -1;
-}
-
-.ax-breadcrumbs .ax-node.inspected .selection {
-    display: block;
-    background-color: #ddd;
-}
-
-.ax-breadcrumbs .ax-node.inspected:focus .selection {
-    background-color: var(--selection-bg-color);
-}
-
-.ax-breadcrumbs .ax-node.parent.inspected:focus::before {
-    background-color: white;
-}
-
-.ax-breadcrumbs .ax-node.inspected:focus {
-    color: white;
-}
-
-.ax-breadcrumbs .ax-node.inspected:focus * {
-    color: inherit;
-}
diff --git a/front_end/accessibility/module.json b/front_end/accessibility/module.json
deleted file mode 100644
index f0e42b3..0000000
--- a/front_end/accessibility/module.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "elements-sidebar",
-            "id": "accessibility.view",
-            "title": "Accessibility",
-            "order": 10,
-            "persistence": "permanent",
-            "className": "Accessibility.AccessibilitySidebarView"
-        }
-    ],
-    "dependencies": ["elements"],
-    "scripts": [
-        "AccessibilityModel.js",
-        "AccessibilitySidebarView.js",
-        "AccessibilityNodeView.js",
-        "AccessibilityStrings.js",
-        "ARIAAttributesView.js",
-        "ARIAMetadata.js",
-        "ARIAConfig.js",
-        "AXBreadcrumbsPane.js"
-    ],
-    "skip_compilation": [
-        "ARIAConfig.js"
-    ],
-    "resources": [
-        "accessibilityNode.css",
-        "accessibilityProperties.css",
-        "axBreadcrumbs.css"
-    ]
-}
diff --git a/front_end/accessibility_test_runner/AccessibilityPaneTestRunner.js b/front_end/accessibility_test_runner/AccessibilityPaneTestRunner.js
deleted file mode 100644
index 6da6959..0000000
--- a/front_end/accessibility_test_runner/AccessibilityPaneTestRunner.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-AccessibilityTestRunner.accessibilitySidebarPane = function() {
-  return self.runtime.sharedInstance(Accessibility.AccessibilitySidebarView);
-};
-
-AccessibilityTestRunner.selectNodeAndWaitForAccessibility = function(idValue) {
-  return new Promise(resolve => {
-    ElementsTestRunner.selectNodeWithId(idValue, function() {
-      self.runtime.sharedInstance(Accessibility.AccessibilitySidebarView).doUpdate().then(resolve);
-    });
-  });
-};
-
-AccessibilityTestRunner.dumpSelectedElementAccessibilityNode = function() {
-  const sidebarPane = AccessibilityTestRunner.accessibilitySidebarPane();
-
-  if (!sidebarPane) {
-    TestRunner.addResult('No sidebarPane in dumpSelectedElementAccessibilityNode');
-    TestRunner.completeTest();
-    return;
-  }
-
-  AccessibilityTestRunner.dumpAccessibilityNode(sidebarPane._axNodeSubPane._axNode);
-};
-
-AccessibilityTestRunner.dumpAccessibilityNode = function(accessibilityNode) {
-  if (!accessibilityNode) {
-    TestRunner.addResult('<null>');
-    TestRunner.completeTest();
-    return;
-  }
-
-  const builder = [];
-  builder.push(accessibilityNode.role().value);
-  builder.push((accessibilityNode.name() ? '"' + accessibilityNode.name().value + '"' : '<undefined>'));
-
-  if (accessibilityNode.properties()) {
-    for (const property of accessibilityNode.properties()) {
-      if ('value' in property)
-        builder.push(property.name + '="' + property.value.value + '"');
-    }
-  }
-
-  TestRunner.addResult(builder.join(' '));
-};
-
-AccessibilityTestRunner.findARIAAttributeTreeElement = function(attribute) {
-  const sidebarPane = AccessibilityTestRunner.accessibilitySidebarPane();
-
-  if (!sidebarPane) {
-    TestRunner.addResult('Could not get Accessibility sidebar pane.');
-    TestRunner.completeTest();
-    return;
-  }
-
-  const ariaSubPane = sidebarPane._ariaSubPane;
-  const treeOutline = ariaSubPane._treeOutline;
-  const childNodes = treeOutline._rootElement._children;
-
-  for (const treeElement of childNodes) {
-    if (treeElement._attribute.name === attribute)
-      return treeElement;
-  }
-
-  return null;
-};
diff --git a/front_end/accessibility_test_runner/module.json b/front_end/accessibility_test_runner/module.json
deleted file mode 100644
index f841d02..0000000
--- a/front_end/accessibility_test_runner/module.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "accessibility",
-    "elements_test_runner"
-  ],
-  "scripts": [
-    "AccessibilityPaneTestRunner.js"
-  ],
-  "skip_compilation": [
-    "AccessibilityPaneTestRunner.js"
-  ]
-}
diff --git a/front_end/animation/AnimationGroupPreviewUI.js b/front_end/animation/AnimationGroupPreviewUI.js
deleted file mode 100644
index 3ec7be4..0000000
--- a/front_end/animation/AnimationGroupPreviewUI.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Animation.AnimationGroupPreviewUI = class {
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} model
-   */
-  constructor(model) {
-    this._model = model;
-    this.element = createElementWithClass('div', 'animation-buffer-preview');
-    this.element.createChild('div', 'animation-paused fill');
-    this._removeButton = this.element.createChild('div', 'animation-remove-button');
-    this._removeButton.textContent = '\u2715';
-    this._replayOverlayElement = this.element.createChild('div', 'animation-buffer-preview-animation');
-    this._svg = this.element.createSVGChild('svg');
-    this._svg.setAttribute('width', '100%');
-    this._svg.setAttribute('preserveAspectRatio', 'none');
-    this._svg.setAttribute('height', '100%');
-    this._viewBoxHeight = 32;
-    this._svg.setAttribute('viewBox', '0 0 100 ' + this._viewBoxHeight);
-    this._svg.setAttribute('shape-rendering', 'crispEdges');
-    this._render();
-  }
-
-  /**
-   * @return {number}
-   */
-  _groupDuration() {
-    let duration = 0;
-    for (const anim of this._model.animations()) {
-      const animDuration = anim.source().delay() + anim.source().duration();
-      if (animDuration > duration)
-        duration = animDuration;
-    }
-    return duration;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  removeButton() {
-    return this._removeButton;
-  }
-
-  replay() {
-    this._replayOverlayElement.animate(
-        [
-          {offset: 0, width: '0%', opacity: 1}, {offset: 0.9, width: '100%', opacity: 1},
-          {offset: 1, width: '100%', opacity: 0}
-        ],
-        {duration: 200, easing: 'cubic-bezier(0, 0, 0.2, 1)'});
-  }
-
-  _render() {
-    this._svg.removeChildren();
-    const maxToShow = 10;
-    const numberOfAnimations = Math.min(this._model.animations().length, maxToShow);
-    const timeToPixelRatio = 100 / Math.max(this._groupDuration(), 750);
-    for (let i = 0; i < numberOfAnimations; i++) {
-      const effect = this._model.animations()[i].source();
-      const line = this._svg.createSVGChild('line');
-      line.setAttribute('x1', effect.delay() * timeToPixelRatio);
-      line.setAttribute('x2', (effect.delay() + effect.duration()) * timeToPixelRatio);
-      const y = Math.floor(this._viewBoxHeight / Math.max(6, numberOfAnimations) * i + 1);
-      line.setAttribute('y1', y);
-      line.setAttribute('y2', y);
-      line.style.stroke = Animation.AnimationUI.Color(this._model.animations()[i]);
-    }
-  }
-};
diff --git a/front_end/animation/AnimationModel.js b/front_end/animation/AnimationModel.js
deleted file mode 100644
index 0d4001c..0000000
--- a/front_end/animation/AnimationModel.js
+++ /dev/null
@@ -1,811 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
-    this._agent = target.animationAgent();
-    target.registerAnimationDispatcher(new Animation.AnimationDispatcher(this));
-    /** @type {!Map.<string, !Animation.AnimationModel.Animation>} */
-    this._animationsById = new Map();
-    /** @type {!Map.<string, !Animation.AnimationModel.AnimationGroup>} */
-    this._animationGroups = new Map();
-    /** @type {!Array.<string>} */
-    this._pendingAnimations = [];
-    this._playbackRate = 1;
-    const resourceTreeModel = /** @type {!SDK.ResourceTreeModel} */ (target.model(SDK.ResourceTreeModel));
-    resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated, this._reset, this);
-    const screenCaptureModel = target.model(SDK.ScreenCaptureModel);
-    if (screenCaptureModel)
-      this._screenshotCapture = new Animation.AnimationModel.ScreenshotCapture(this, screenCaptureModel);
-  }
-
-  _reset() {
-    this._animationsById.clear();
-    this._animationGroups.clear();
-    this._pendingAnimations = [];
-    this.dispatchEventToListeners(Animation.AnimationModel.Events.ModelReset);
-  }
-
-  /**
-   * @param {string} id
-   */
-  animationCreated(id) {
-    this._pendingAnimations.push(id);
-  }
-
-  /**
-   * @param {string} id
-   */
-  _animationCanceled(id) {
-    this._pendingAnimations.remove(id);
-    this._flushPendingAnimationsIfNeeded();
-  }
-
-  /**
-   * @param {!Protocol.Animation.Animation} payload
-   */
-  animationStarted(payload) {
-    // We are not interested in animations without effect or target.
-    if (!payload.source || !payload.source.backendNodeId)
-      return;
-
-    const animation = Animation.AnimationModel.Animation.parsePayload(this, payload);
-
-    // Ignore Web Animations custom effects & groups.
-    if (animation.type() === 'WebAnimation' && animation.source().keyframesRule().keyframes().length === 0) {
-      this._pendingAnimations.remove(animation.id());
-    } else {
-      this._animationsById.set(animation.id(), animation);
-      if (this._pendingAnimations.indexOf(animation.id()) === -1)
-        this._pendingAnimations.push(animation.id());
-    }
-
-    this._flushPendingAnimationsIfNeeded();
-  }
-
-  _flushPendingAnimationsIfNeeded() {
-    for (const id of this._pendingAnimations) {
-      if (!this._animationsById.get(id))
-        return;
-    }
-
-    while (this._pendingAnimations.length)
-      this._matchExistingGroups(this._createGroupFromPendingAnimations());
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} incomingGroup
-   * @return {boolean}
-   */
-  _matchExistingGroups(incomingGroup) {
-    let matchedGroup = null;
-    for (const group of this._animationGroups.values()) {
-      if (group._matches(incomingGroup)) {
-        matchedGroup = group;
-        group._update(incomingGroup);
-        break;
-      }
-    }
-
-    if (!matchedGroup) {
-      this._animationGroups.set(incomingGroup.id(), incomingGroup);
-      if (this._screenshotCapture)
-        this._screenshotCapture.captureScreenshots(incomingGroup.finiteDuration(), incomingGroup._screenshots);
-    }
-    this.dispatchEventToListeners(Animation.AnimationModel.Events.AnimationGroupStarted, matchedGroup || incomingGroup);
-    return !!matchedGroup;
-  }
-
-  /**
-   * @return {!Animation.AnimationModel.AnimationGroup}
-   */
-  _createGroupFromPendingAnimations() {
-    console.assert(this._pendingAnimations.length);
-    const groupedAnimations = [this._animationsById.get(this._pendingAnimations.shift())];
-    const remainingAnimations = [];
-    for (const id of this._pendingAnimations) {
-      const anim = this._animationsById.get(id);
-      if (anim.startTime() === groupedAnimations[0].startTime())
-        groupedAnimations.push(anim);
-      else
-        remainingAnimations.push(id);
-    }
-    this._pendingAnimations = remainingAnimations;
-    return new Animation.AnimationModel.AnimationGroup(this, groupedAnimations[0].id(), groupedAnimations);
-  }
-
-  /**
-   * @param {number} playbackRate
-   */
-  setPlaybackRate(playbackRate) {
-    this._playbackRate = playbackRate;
-    this._agent.setPlaybackRate(playbackRate);
-  }
-
-  /**
-   * @param {!Array.<string>} animations
-   */
-  _releaseAnimations(animations) {
-    this._agent.releaseAnimations(animations);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  suspendModel() {
-    this._reset();
-    return this._agent.disable();
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  resumeModel() {
-    if (!this._enabled)
-      return Promise.resolve();
-    return this._agent.enable();
-  }
-
-  ensureEnabled() {
-    if (this._enabled)
-      return;
-    this._agent.enable();
-    this._enabled = true;
-  }
-};
-
-SDK.SDKModel.register(Animation.AnimationModel, SDK.Target.Capability.DOM, false);
-
-/** @enum {symbol} */
-Animation.AnimationModel.Events = {
-  AnimationGroupStarted: Symbol('AnimationGroupStarted'),
-  ModelReset: Symbol('ModelReset')
-};
-
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel.Animation = class {
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   * @param {!Protocol.Animation.Animation} payload
-   */
-  constructor(animationModel, payload) {
-    this._animationModel = animationModel;
-    this._payload = payload;
-    this._source = new Animation.AnimationModel.AnimationEffect(
-        animationModel, /** @type {!Protocol.Animation.AnimationEffect} */ (this._payload.source));
-  }
-
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   * @param {!Protocol.Animation.Animation} payload
-   * @return {!Animation.AnimationModel.Animation}
-   */
-  static parsePayload(animationModel, payload) {
-    return new Animation.AnimationModel.Animation(animationModel, payload);
-  }
-
-  /**
-   * @return {!Protocol.Animation.Animation}
-   */
-  payload() {
-    return this._payload;
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this._payload.id;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._payload.name;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  paused() {
-    return this._payload.pausedState;
-  }
-
-  /**
-   * @return {string}
-   */
-  playState() {
-    return this._playState || this._payload.playState;
-  }
-
-  /**
-   * @param {string} playState
-   */
-  setPlayState(playState) {
-    this._playState = playState;
-  }
-
-  /**
-   * @return {number}
-   */
-  playbackRate() {
-    return this._payload.playbackRate;
-  }
-
-  /**
-   * @return {number}
-   */
-  startTime() {
-    return this._payload.startTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  endTime() {
-    if (!this.source().iterations)
-      return Infinity;
-    return this.startTime() + this.source().delay() + this.source().duration() * this.source().iterations() +
-        this.source().endDelay();
-  }
-
-  /**
-   * @return {number}
-   */
-  _finiteDuration() {
-    const iterations = Math.min(this.source().iterations(), 3);
-    return this.source().delay() + this.source().duration() * iterations;
-  }
-
-  /**
-   * @return {number}
-   */
-  currentTime() {
-    return this._payload.currentTime;
-  }
-
-  /**
-   * @return {!Animation.AnimationModel.AnimationEffect}
-   */
-  source() {
-    return this._source;
-  }
-
-  /**
-   * @return {!Animation.AnimationModel.Animation.Type}
-   */
-  type() {
-    return /** @type {!Animation.AnimationModel.Animation.Type} */ (this._payload.type);
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.Animation} animation
-   * @return {boolean}
-   */
-  overlaps(animation) {
-    // Infinite animations
-    if (!this.source().iterations() || !animation.source().iterations())
-      return true;
-
-    const firstAnimation = this.startTime() < animation.startTime() ? this : animation;
-    const secondAnimation = firstAnimation === this ? animation : this;
-    return firstAnimation.endTime() >= secondAnimation.startTime();
-  }
-
-  /**
-   * @param {number} duration
-   * @param {number} delay
-   */
-  setTiming(duration, delay) {
-    this._source.node().then(this._updateNodeStyle.bind(this, duration, delay));
-    this._source._duration = duration;
-    this._source._delay = delay;
-    this._animationModel._agent.setTiming(this.id(), duration, delay);
-  }
-
-  /**
-   * @param {number} duration
-   * @param {number} delay
-   * @param {!SDK.DOMNode} node
-   */
-  _updateNodeStyle(duration, delay, node) {
-    let animationPrefix;
-    if (this.type() === Animation.AnimationModel.Animation.Type.CSSTransition)
-      animationPrefix = 'transition-';
-    else if (this.type() === Animation.AnimationModel.Animation.Type.CSSAnimation)
-      animationPrefix = 'animation-';
-    else
-      return;
-
-    const cssModel = node.domModel().cssModel();
-    cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + 'duration', duration + 'ms');
-    cssModel.setEffectivePropertyValueForNode(node.id, animationPrefix + 'delay', delay + 'ms');
-  }
-
-  /**
-   * @return {!Promise<?SDK.RemoteObject>}
-   */
-  remoteObjectPromise() {
-    return this._animationModel._agent.resolveAnimation(this.id()).then(
-        payload => payload && this._animationModel._runtimeModel.createRemoteObject(payload));
-  }
-
-  /**
-   * @return {string}
-   */
-  _cssId() {
-    return this._payload.cssId || '';
-  }
-};
-
-
-/** @enum {string} */
-Animation.AnimationModel.Animation.Type = {
-  CSSTransition: 'CSSTransition',
-  CSSAnimation: 'CSSAnimation',
-  WebAnimation: 'WebAnimation'
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel.AnimationEffect = class {
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   * @param {!Protocol.Animation.AnimationEffect} payload
-   */
-  constructor(animationModel, payload) {
-    this._animationModel = animationModel;
-    this._payload = payload;
-    if (payload.keyframesRule)
-      this._keyframesRule = new Animation.AnimationModel.KeyframesRule(payload.keyframesRule);
-    this._delay = this._payload.delay;
-    this._duration = this._payload.duration;
-  }
-
-  /**
-   * @return {number}
-   */
-  delay() {
-    return this._delay;
-  }
-
-  /**
-   * @return {number}
-   */
-  endDelay() {
-    return this._payload.endDelay;
-  }
-
-  /**
-   * @return {number}
-   */
-  iterationStart() {
-    return this._payload.iterationStart;
-  }
-
-  /**
-   * @return {number}
-   */
-  iterations() {
-    // Animations with zero duration, zero delays and infinite iterations can't be shown.
-    if (!this.delay() && !this.endDelay() && !this.duration())
-      return 0;
-    return this._payload.iterations || Infinity;
-  }
-
-  /**
-   * @return {number}
-   */
-  duration() {
-    return this._duration;
-  }
-
-  /**
-   * @return {string}
-   */
-  direction() {
-    return this._payload.direction;
-  }
-
-  /**
-   * @return {string}
-   */
-  fill() {
-    return this._payload.fill;
-  }
-
-  /**
-   * @return {!Promise.<!SDK.DOMNode>}
-   */
-  node() {
-    if (!this._deferredNode)
-      this._deferredNode = new SDK.DeferredDOMNode(this._animationModel.target(), this.backendNodeId());
-    return this._deferredNode.resolvePromise();
-  }
-
-  /**
-   * @return {!SDK.DeferredDOMNode}
-   */
-  deferredNode() {
-    return new SDK.DeferredDOMNode(this._animationModel.target(), this.backendNodeId());
-  }
-
-  /**
-   * @return {number}
-   */
-  backendNodeId() {
-    return /** @type {number} */ (this._payload.backendNodeId);
-  }
-
-  /**
-   * @return {?Animation.AnimationModel.KeyframesRule}
-   */
-  keyframesRule() {
-    return this._keyframesRule;
-  }
-
-  /**
-   * @return {string}
-   */
-  easing() {
-    return this._payload.easing;
-  }
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel.KeyframesRule = class {
-  /**
-   * @param {!Protocol.Animation.KeyframesRule} payload
-   */
-  constructor(payload) {
-    this._payload = payload;
-    this._keyframes = this._payload.keyframes.map(function(keyframeStyle) {
-      return new Animation.AnimationModel.KeyframeStyle(keyframeStyle);
-    });
-  }
-
-  /**
-   * @param {!Array.<!Protocol.Animation.KeyframeStyle>} payload
-   */
-  _setKeyframesPayload(payload) {
-    this._keyframes = payload.map(function(keyframeStyle) {
-      return new Animation.AnimationModel.KeyframeStyle(keyframeStyle);
-    });
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  name() {
-    return this._payload.name;
-  }
-
-  /**
-   * @return {!Array.<!Animation.AnimationModel.KeyframeStyle>}
-   */
-  keyframes() {
-    return this._keyframes;
-  }
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel.KeyframeStyle = class {
-  /**
-   * @param {!Protocol.Animation.KeyframeStyle} payload
-   */
-  constructor(payload) {
-    this._payload = payload;
-    this._offset = this._payload.offset;
-  }
-
-  /**
-   * @return {string}
-   */
-  offset() {
-    return this._offset;
-  }
-
-  /**
-   * @param {number} offset
-   */
-  setOffset(offset) {
-    this._offset = offset * 100 + '%';
-  }
-
-  /**
-   * @return {number}
-   */
-  offsetAsNumber() {
-    return parseFloat(this._offset) / 100;
-  }
-
-  /**
-   * @return {string}
-   */
-  easing() {
-    return this._payload.easing;
-  }
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel.AnimationGroup = class {
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   * @param {string} id
-   * @param {!Array.<!Animation.AnimationModel.Animation>} animations
-   */
-  constructor(animationModel, id, animations) {
-    this._animationModel = animationModel;
-    this._id = id;
-    this._animations = animations;
-    this._paused = false;
-    this._screenshots = [];
-    this._screenshotImages = [];
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @return {!Array.<!Animation.AnimationModel.Animation>}
-   */
-  animations() {
-    return this._animations;
-  }
-
-  release() {
-    this._animationModel._animationGroups.remove(this.id());
-    this._animationModel._releaseAnimations(this._animationIds());
-  }
-
-  /**
-   * @return {!Array.<string>}
-   */
-  _animationIds() {
-    /**
-     * @param {!Animation.AnimationModel.Animation} animation
-     * @return {string}
-     */
-    function extractId(animation) {
-      return animation.id();
-    }
-
-    return this._animations.map(extractId);
-  }
-
-  /**
-   * @return {number}
-   */
-  startTime() {
-    return this._animations[0].startTime();
-  }
-
-  /**
-   * @return {number}
-   */
-  finiteDuration() {
-    let maxDuration = 0;
-    for (let i = 0; i < this._animations.length; ++i)
-      maxDuration = Math.max(maxDuration, this._animations[i]._finiteDuration());
-    return maxDuration;
-  }
-
-  /**
-   * @param {number} currentTime
-   */
-  seekTo(currentTime) {
-    this._animationModel._agent.seekAnimations(this._animationIds(), currentTime);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  paused() {
-    return this._paused;
-  }
-
-  /**
-   * @param {boolean} paused
-   */
-  togglePause(paused) {
-    if (paused === this._paused)
-      return;
-    this._paused = paused;
-    this._animationModel._agent.setPaused(this._animationIds(), paused);
-  }
-
-  /**
-   * @return {!Promise<number>}
-   */
-  currentTimePromise() {
-    let longestAnim = null;
-    for (const anim of this._animations) {
-      if (!longestAnim || anim.endTime() > longestAnim.endTime())
-        longestAnim = anim;
-    }
-    return this._animationModel._agent.getCurrentTime(longestAnim.id()).then(currentTime => currentTime || 0);
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} group
-   * @return {boolean}
-   */
-  _matches(group) {
-    /**
-     * @param {!Animation.AnimationModel.Animation} anim
-     * @return {string}
-     */
-    function extractId(anim) {
-      if (anim.type() === Animation.AnimationModel.Animation.Type.WebAnimation)
-        return anim.type() + anim.id();
-      else
-        return anim._cssId();
-    }
-
-    if (this._animations.length !== group._animations.length)
-      return false;
-    const left = this._animations.map(extractId).sort();
-    const right = group._animations.map(extractId).sort();
-    for (let i = 0; i < left.length; i++) {
-      if (left[i] !== right[i])
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} group
-   */
-  _update(group) {
-    this._animationModel._releaseAnimations(this._animationIds());
-    this._animations = group._animations;
-  }
-
-  /**
-   * @return {!Array.<!Image>}
-   */
-  screenshots() {
-    for (let i = 0; i < this._screenshots.length; ++i) {
-      const image = new Image();
-      image.src = 'data:image/jpeg;base64,' + this._screenshots[i];
-      this._screenshotImages.push(image);
-    }
-    this._screenshots = [];
-    return this._screenshotImages;
-  }
-};
-
-/**
- * @implements {Protocol.AnimationDispatcher}
- * @unrestricted
- */
-Animation.AnimationDispatcher = class {
-  constructor(animationModel) {
-    this._animationModel = animationModel;
-  }
-
-  /**
-   * @override
-   * @param {string} id
-   */
-  animationCreated(id) {
-    this._animationModel.animationCreated(id);
-  }
-
-  /**
-   * @override
-   * @param {string} id
-   */
-  animationCanceled(id) {
-    this._animationModel._animationCanceled(id);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Animation.Animation} payload
-   */
-  animationStarted(payload) {
-    this._animationModel.animationStarted(payload);
-  }
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationModel.ScreenshotCapture = class {
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   * @param {!SDK.ScreenCaptureModel} screenCaptureModel
-   */
-  constructor(animationModel, screenCaptureModel) {
-    /** @type {!Array<!Animation.AnimationModel.ScreenshotCapture.Request>} */
-    this._requests = [];
-    this._screenCaptureModel = screenCaptureModel;
-    this._animationModel = animationModel;
-    this._animationModel.addEventListener(Animation.AnimationModel.Events.ModelReset, this._stopScreencast, this);
-  }
-
-  /**
-   * @param {number} duration
-   * @param {!Array<string>} screenshots
-   */
-  captureScreenshots(duration, screenshots) {
-    const screencastDuration = Math.min(duration / this._animationModel._playbackRate, 3000);
-    const endTime = screencastDuration + window.performance.now();
-    this._requests.push({endTime: endTime, screenshots: screenshots});
-
-    if (!this._endTime || endTime > this._endTime) {
-      clearTimeout(this._stopTimer);
-      this._stopTimer = setTimeout(this._stopScreencast.bind(this), screencastDuration);
-      this._endTime = endTime;
-    }
-
-    if (this._capturing)
-      return;
-    this._capturing = true;
-    this._screenCaptureModel.startScreencast(
-        'jpeg', 80, undefined, 300, 2, this._screencastFrame.bind(this), visible => {});
-  }
-
-  /**
-   * @param {string} base64Data
-   * @param {!Protocol.Page.ScreencastFrameMetadata} metadata
-   */
-  _screencastFrame(base64Data, metadata) {
-    /**
-     * @param {!Animation.AnimationModel.ScreenshotCapture.Request} request
-     * @return {boolean}
-     */
-    function isAnimating(request) {
-      return request.endTime >= now;
-    }
-
-    if (!this._capturing)
-      return;
-
-    const now = window.performance.now();
-    this._requests = this._requests.filter(isAnimating);
-    for (const request of this._requests)
-      request.screenshots.push(base64Data);
-  }
-
-  _stopScreencast() {
-    if (!this._capturing)
-      return;
-
-    delete this._stopTimer;
-    delete this._endTime;
-    this._requests = [];
-    this._capturing = false;
-    this._screenCaptureModel.stopScreencast();
-  }
-};
-
-/** @typedef {{ endTime: number, screenshots: !Array.<string>}} */
-Animation.AnimationModel.ScreenshotCapture.Request;
diff --git a/front_end/animation/AnimationScreenshotPopover.js b/front_end/animation/AnimationScreenshotPopover.js
deleted file mode 100644
index a889421..0000000
--- a/front_end/animation/AnimationScreenshotPopover.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Animation.AnimationScreenshotPopover = class extends UI.VBox {
-  /**
-   * @param {!Array.<!Image>} images
-   */
-  constructor(images) {
-    super(true);
-    console.assert(images.length);
-    this.registerRequiredCSS('animation/animationScreenshotPopover.css');
-    this.contentElement.classList.add('animation-screenshot-popover');
-    this._frames = images;
-    for (const image of images) {
-      this.contentElement.appendChild(image);
-      image.style.display = 'none';
-    }
-    this._currentFrame = 0;
-    this._frames[0].style.display = 'block';
-    this._progressBar = this.contentElement.createChild('div', 'animation-progress');
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._rafId = this.contentElement.window().requestAnimationFrame(this._changeFrame.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this.contentElement.window().cancelAnimationFrame(this._rafId);
-    delete this._endDelay;
-  }
-
-  _changeFrame() {
-    this._rafId = this.contentElement.window().requestAnimationFrame(this._changeFrame.bind(this));
-
-    if (this._endDelay) {
-      this._endDelay--;
-      return;
-    }
-    this._showFrame = !this._showFrame;
-    if (!this._showFrame)
-      return;
-
-    const numFrames = this._frames.length;
-    this._frames[this._currentFrame % numFrames].style.display = 'none';
-    this._currentFrame++;
-    this._frames[(this._currentFrame) % numFrames].style.display = 'block';
-    if (this._currentFrame % numFrames === numFrames - 1)
-      this._endDelay = 50;
-    this._progressBar.style.width = (this._currentFrame % numFrames + 1) / numFrames * 100 + '%';
-  }
-};
diff --git a/front_end/animation/AnimationTimeline.js b/front_end/animation/AnimationTimeline.js
deleted file mode 100644
index a21cb84..0000000
--- a/front_end/animation/AnimationTimeline.js
+++ /dev/null
@@ -1,737 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!Animation.AnimationModel>}
- * @unrestricted
- */
-Animation.AnimationTimeline = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('animation/animationTimeline.css');
-    this.element.classList.add('animations-timeline');
-
-    this._grid = this.contentElement.createSVGChild('svg', 'animation-timeline-grid');
-
-    this._playbackRate = 1;
-    this._allPaused = false;
-    this._createHeader();
-    this._animationsContainer = this.contentElement.createChild('div', 'animation-timeline-rows');
-    const timelineHint = this.contentElement.createChild('div', 'animation-timeline-rows-hint');
-    timelineHint.textContent = ls`Select an effect above to inspect and modify.`;
-
-    /** @const */ this._defaultDuration = 100;
-    this._duration = this._defaultDuration;
-    /** @const */ this._timelineControlsWidth = 150;
-    /** @type {!Map.<!Protocol.DOM.BackendNodeId, !Animation.AnimationTimeline.NodeUI>} */
-    this._nodesMap = new Map();
-    this._uiAnimations = [];
-    this._groupBuffer = [];
-    /** @type {!Map.<!Animation.AnimationModel.AnimationGroup, !Animation.AnimationGroupPreviewUI>} */
-    this._previewMap = new Map();
-    this._symbol = Symbol('animationTimeline');
-    /** @type {!Map.<string, !Animation.AnimationModel.Animation>} */
-    this._animationsMap = new Map();
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
-    SDK.targetManager.observeModels(Animation.AnimationModel, this);
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this._nodeChanged, this);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    for (const animationModel of SDK.targetManager.models(Animation.AnimationModel))
-      this._addEventListeners(animationModel);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    for (const animationModel of SDK.targetManager.models(Animation.AnimationModel))
-      this._removeEventListeners(animationModel);
-    this._popoverHelper.hidePopover();
-  }
-
-  /**
-   * @override
-   * @param {!Animation.AnimationModel} animationModel
-   */
-  modelAdded(animationModel) {
-    if (this.isShowing())
-      this._addEventListeners(animationModel);
-  }
-
-  /**
-   * @override
-   * @param {!Animation.AnimationModel} animationModel
-   */
-  modelRemoved(animationModel) {
-    this._removeEventListeners(animationModel);
-  }
-
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   */
-  _addEventListeners(animationModel) {
-    animationModel.ensureEnabled();
-    animationModel.addEventListener(
-        Animation.AnimationModel.Events.AnimationGroupStarted, this._animationGroupStarted, this);
-    animationModel.addEventListener(Animation.AnimationModel.Events.ModelReset, this._reset, this);
-  }
-
-  /**
-   * @param {!Animation.AnimationModel} animationModel
-   */
-  _removeEventListeners(animationModel) {
-    animationModel.removeEventListener(
-        Animation.AnimationModel.Events.AnimationGroupStarted, this._animationGroupStarted, this);
-    animationModel.removeEventListener(Animation.AnimationModel.Events.ModelReset, this._reset, this);
-  }
-
-  _nodeChanged() {
-    for (const nodeUI of this._nodesMap.values())
-      nodeUI._nodeChanged();
-  }
-
-  /**
-   * @return {!Element} element
-   */
-  _createScrubber() {
-    this._timelineScrubber = createElementWithClass('div', 'animation-scrubber hidden');
-    this._timelineScrubberLine = this._timelineScrubber.createChild('div', 'animation-scrubber-line');
-    this._timelineScrubberLine.createChild('div', 'animation-scrubber-head');
-    this._timelineScrubber.createChild('div', 'animation-time-overlay');
-    return this._timelineScrubber;
-  }
-
-  _createHeader() {
-    const toolbarContainer = this.contentElement.createChild('div', 'animation-timeline-toolbar-container');
-    const topToolbar = new UI.Toolbar('animation-timeline-toolbar', toolbarContainer);
-    const clearButton = new UI.ToolbarButton(ls`Clear all`, 'largeicon-clear');
-    clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset.bind(this));
-    topToolbar.appendToolbarItem(clearButton);
-    topToolbar.appendSeparator();
-
-    this._pauseButton = new UI.ToolbarToggle(ls`Pause all`, 'largeicon-pause', 'largeicon-resume');
-    this._pauseButton.addEventListener(UI.ToolbarButton.Events.Click, this._togglePauseAll.bind(this));
-    topToolbar.appendToolbarItem(this._pauseButton);
-
-    const playbackRateControl = toolbarContainer.createChild('div', 'animation-playback-rate-control');
-    this._playbackRateButtons = [];
-    for (const playbackRate of Animation.AnimationTimeline.GlobalPlaybackRates) {
-      const button = playbackRateControl.createChild('div', 'animation-playback-rate-button');
-      button.textContent = playbackRate ? ls`${playbackRate * 100}%` : ls`Pause`;
-      button.playbackRate = playbackRate;
-      button.addEventListener('click', this._setPlaybackRate.bind(this, playbackRate));
-      button.title = ls`Set speed to ${button.textContent}`;
-      this._playbackRateButtons.push(button);
-    }
-    this._updatePlaybackControls();
-
-    this._previewContainer = this.contentElement.createChild('div', 'animation-timeline-buffer');
-    this._popoverHelper = new UI.PopoverHelper(this._previewContainer, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setDisableOnClick(true);
-    this._popoverHelper.setTimeout(0);
-    const emptyBufferHint = this.contentElement.createChild('div', 'animation-timeline-buffer-hint');
-    emptyBufferHint.textContent = ls`Listening for animations...`;
-    const container = this.contentElement.createChild('div', 'animation-timeline-header');
-    const controls = container.createChild('div', 'animation-controls');
-    this._currentTime = controls.createChild('div', 'animation-timeline-current-time monospace');
-
-    const toolbar = new UI.Toolbar('animation-controls-toolbar', controls);
-    this._controlButton = new UI.ToolbarToggle(ls`Replay timeline`, 'largeicon-replay-animation');
-    this._controlState = Animation.AnimationTimeline._ControlState.Replay;
-    this._controlButton.setToggled(true);
-    this._controlButton.addEventListener(UI.ToolbarButton.Events.Click, this._controlButtonToggle.bind(this));
-    toolbar.appendToolbarItem(this._controlButton);
-
-    const gridHeader = container.createChild('div', 'animation-grid-header');
-    UI.installDragHandle(
-        gridHeader, this._repositionScrubber.bind(this), this._scrubberDragMove.bind(this),
-        this._scrubberDragEnd.bind(this), 'text');
-    container.appendChild(this._createScrubber());
-    UI.installDragHandle(
-        this._timelineScrubberLine, this._scrubberDragStart.bind(this), this._scrubberDragMove.bind(this),
-        this._scrubberDragEnd.bind(this), 'col-resize');
-    this._currentTime.textContent = '';
-
-    return container;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    const element = event.target;
-    if (!element.isDescendant(this._previewContainer))
-      return null;
-
-    return {
-      box: event.target.boxInWindow(),
-      show: popover => {
-        let animGroup;
-        for (const group of this._previewMap.keysArray()) {
-          if (this._previewMap.get(group).element === element.parentElement)
-            animGroup = group;
-        }
-        console.assert(animGroup);
-        const screenshots = animGroup.screenshots();
-        if (!screenshots.length)
-          return Promise.resolve(false);
-
-        let fulfill;
-        const promise = new Promise(x => fulfill = x);
-        if (!screenshots[0].complete)
-          screenshots[0].onload = onFirstScreenshotLoaded.bind(null, screenshots);
-        else
-          onFirstScreenshotLoaded(screenshots);
-        return promise;
-
-        /**
-         * @param  {!Array.<!Image>} screenshots
-         */
-        function onFirstScreenshotLoaded(screenshots) {
-          new Animation.AnimationScreenshotPopover(screenshots).show(popover.contentElement);
-          fulfill(true);
-        }
-      }
-    };
-  }
-
-  _togglePauseAll() {
-    this._allPaused = !this._allPaused;
-    this._pauseButton.setToggled(this._allPaused);
-    this._setPlaybackRate(this._playbackRate);
-    this._pauseButton.setTitle(this._allPaused ? ls`Resume all` : ls`Pause all`);
-  }
-
-  /**
-   * @param {number} playbackRate
-   */
-  _setPlaybackRate(playbackRate) {
-    this._playbackRate = playbackRate;
-    for (const animationModel of SDK.targetManager.models(Animation.AnimationModel))
-      animationModel.setPlaybackRate(this._allPaused ? 0 : this._playbackRate);
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.AnimationsPlaybackRateChanged);
-    if (this._scrubberPlayer)
-      this._scrubberPlayer.playbackRate = this._effectivePlaybackRate();
-
-    this._updatePlaybackControls();
-  }
-
-  _updatePlaybackControls() {
-    for (const button of this._playbackRateButtons) {
-      const selected = this._playbackRate === button.playbackRate;
-      button.classList.toggle('selected', selected);
-    }
-  }
-
-  _controlButtonToggle() {
-    if (this._controlState === Animation.AnimationTimeline._ControlState.Play)
-      this._togglePause(false);
-    else if (this._controlState === Animation.AnimationTimeline._ControlState.Replay)
-      this._replay();
-    else
-      this._togglePause(true);
-  }
-
-  _updateControlButton() {
-    this._controlButton.setEnabled(!!this._selectedGroup);
-    if (this._selectedGroup && this._selectedGroup.paused()) {
-      this._controlState = Animation.AnimationTimeline._ControlState.Play;
-      this._controlButton.setToggled(true);
-      this._controlButton.setTitle(ls`Play timeline`);
-      this._controlButton.setGlyph('largeicon-play-animation');
-    } else if (!this._scrubberPlayer || this._scrubberPlayer.currentTime >= this.duration()) {
-      this._controlState = Animation.AnimationTimeline._ControlState.Replay;
-      this._controlButton.setToggled(true);
-      this._controlButton.setTitle(ls`Replay timeline`);
-      this._controlButton.setGlyph('largeicon-replay-animation');
-    } else {
-      this._controlState = Animation.AnimationTimeline._ControlState.Pause;
-      this._controlButton.setToggled(false);
-      this._controlButton.setTitle(ls`Pause timeline`);
-      this._controlButton.setGlyph('largeicon-pause-animation');
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  _effectivePlaybackRate() {
-    return (this._allPaused || (this._selectedGroup && this._selectedGroup.paused())) ? 0 : this._playbackRate;
-  }
-
-  /**
-   * @param {boolean} pause
-   */
-  _togglePause(pause) {
-    this._selectedGroup.togglePause(pause);
-    if (this._scrubberPlayer)
-      this._scrubberPlayer.playbackRate = this._effectivePlaybackRate();
-    this._previewMap.get(this._selectedGroup).element.classList.toggle('paused', pause);
-    this._updateControlButton();
-  }
-
-  _replay() {
-    if (!this._selectedGroup)
-      return;
-    this._selectedGroup.seekTo(0);
-    this._animateTime(0);
-    this._updateControlButton();
-  }
-
-  /**
-   * @return {number}
-   */
-  duration() {
-    return this._duration;
-  }
-
-  /**
-   * @param {number} duration
-   */
-  setDuration(duration) {
-    this._duration = duration;
-    this.scheduleRedraw();
-  }
-
-  _clearTimeline() {
-    this._uiAnimations = [];
-    this._nodesMap.clear();
-    this._animationsMap.clear();
-    this._animationsContainer.removeChildren();
-    this._duration = this._defaultDuration;
-    this._timelineScrubber.classList.add('hidden');
-    delete this._selectedGroup;
-    if (this._scrubberPlayer)
-      this._scrubberPlayer.cancel();
-    delete this._scrubberPlayer;
-    this._currentTime.textContent = '';
-    this._updateControlButton();
-  }
-
-  _reset() {
-    this._clearTimeline();
-    if (this._allPaused)
-      this._togglePauseAll();
-    else
-      this._setPlaybackRate(this._playbackRate);
-
-    for (const group of this._groupBuffer)
-      group.release();
-    this._groupBuffer = [];
-    this._previewMap.clear();
-    this._previewContainer.removeChildren();
-    this._popoverHelper.hidePopover();
-    this._renderGrid();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _animationGroupStarted(event) {
-    this._addAnimationGroup(/** @type {!Animation.AnimationModel.AnimationGroup} */ (event.data));
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} group
-   */
-  _addAnimationGroup(group) {
-    /**
-     * @param {!Animation.AnimationModel.AnimationGroup} left
-     * @param {!Animation.AnimationModel.AnimationGroup} right
-     */
-    function startTimeComparator(left, right) {
-      return left.startTime() > right.startTime();
-    }
-
-    if (this._previewMap.get(group)) {
-      if (this._selectedGroup === group)
-        this._syncScrubber();
-      else
-        this._previewMap.get(group).replay();
-      return;
-    }
-    this._groupBuffer.sort(startTimeComparator);
-    // Discard oldest groups from buffer if necessary
-    const groupsToDiscard = [];
-    const bufferSize = this.width() / 50;
-    while (this._groupBuffer.length > bufferSize) {
-      const toDiscard = this._groupBuffer.splice(this._groupBuffer[0] === this._selectedGroup ? 1 : 0, 1);
-      groupsToDiscard.push(toDiscard[0]);
-    }
-    for (const g of groupsToDiscard) {
-      this._previewMap.get(g).element.remove();
-      this._previewMap.delete(g);
-      g.release();
-    }
-    // Generate preview
-    const preview = new Animation.AnimationGroupPreviewUI(group);
-    this._groupBuffer.push(group);
-    this._previewMap.set(group, preview);
-    this._previewContainer.appendChild(preview.element);
-    preview.removeButton().addEventListener('click', this._removeAnimationGroup.bind(this, group));
-    preview.element.addEventListener('click', this._selectAnimationGroup.bind(this, group));
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} group
-   * @param {!Event} event
-   */
-  _removeAnimationGroup(group, event) {
-    this._groupBuffer.remove(group);
-    this._previewMap.get(group).element.remove();
-    this._previewMap.delete(group);
-    group.release();
-    event.consume(true);
-
-    if (this._selectedGroup === group) {
-      this._clearTimeline();
-      this._renderGrid();
-    }
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.AnimationGroup} group
-   */
-  _selectAnimationGroup(group) {
-    /**
-     * @param {!Animation.AnimationGroupPreviewUI} ui
-     * @param {!Animation.AnimationModel.AnimationGroup} group
-     * @this {!Animation.AnimationTimeline}
-     */
-    function applySelectionClass(ui, group) {
-      ui.element.classList.toggle('selected', this._selectedGroup === group);
-    }
-
-    if (this._selectedGroup === group) {
-      this._togglePause(false);
-      this._replay();
-      return;
-    }
-    this._clearTimeline();
-    this._selectedGroup = group;
-    this._previewMap.forEach(applySelectionClass, this);
-    this.setDuration(Math.max(500, group.finiteDuration() + 100));
-    for (const anim of group.animations())
-      this._addAnimation(anim);
-    this.scheduleRedraw();
-    this._timelineScrubber.classList.remove('hidden');
-    this._togglePause(false);
-    this._replay();
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.Animation} animation
-   */
-  _addAnimation(animation) {
-    /**
-     * @param {?SDK.DOMNode} node
-     * @this {Animation.AnimationTimeline}
-     */
-    function nodeResolved(node) {
-      nodeUI.nodeResolved(node);
-      uiAnimation.setNode(node);
-      if (node)
-        node[this._symbol] = nodeUI;
-    }
-
-    let nodeUI = this._nodesMap.get(animation.source().backendNodeId());
-    if (!nodeUI) {
-      nodeUI = new Animation.AnimationTimeline.NodeUI(animation.source());
-      this._animationsContainer.appendChild(nodeUI.element);
-      this._nodesMap.set(animation.source().backendNodeId(), nodeUI);
-    }
-    const nodeRow = nodeUI.createNewRow();
-    const uiAnimation = new Animation.AnimationUI(animation, this, nodeRow);
-    animation.source().deferredNode().resolve(nodeResolved.bind(this));
-    this._uiAnimations.push(uiAnimation);
-    this._animationsMap.set(animation.id(), animation);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _nodeRemoved(event) {
-    const node = event.data.node;
-    if (node[this._symbol])
-      node[this._symbol].nodeRemoved();
-  }
-
-  _renderGrid() {
-    /** @const */ const gridSize = 250;
-    this._grid.setAttribute('width', this.width() + 10);
-    this._grid.setAttribute('height', this._cachedTimelineHeight + 30);
-    this._grid.setAttribute('shape-rendering', 'crispEdges');
-    this._grid.removeChildren();
-    let lastDraw = undefined;
-    for (let time = 0; time < this.duration(); time += gridSize) {
-      const line = this._grid.createSVGChild('rect', 'animation-timeline-grid-line');
-      line.setAttribute('x', time * this.pixelMsRatio() + 10);
-      line.setAttribute('y', 23);
-      line.setAttribute('height', '100%');
-      line.setAttribute('width', 1);
-    }
-    for (let time = 0; time < this.duration(); time += gridSize) {
-      const gridWidth = time * this.pixelMsRatio();
-      if (lastDraw === undefined || gridWidth - lastDraw > 50) {
-        lastDraw = gridWidth;
-        const label = this._grid.createSVGChild('text', 'animation-timeline-grid-label');
-        label.textContent = Number.millisToString(time);
-        label.setAttribute('x', gridWidth + 10);
-        label.setAttribute('y', 16);
-      }
-    }
-  }
-
-  scheduleRedraw() {
-    this._renderQueue = [];
-    for (const ui of this._uiAnimations)
-      this._renderQueue.push(ui);
-    if (this._redrawing)
-      return;
-    this._redrawing = true;
-    this._renderGrid();
-    this._animationsContainer.window().requestAnimationFrame(this._render.bind(this));
-  }
-
-  /**
-   * @param {number=} timestamp
-   */
-  _render(timestamp) {
-    while (this._renderQueue.length && (!timestamp || window.performance.now() - timestamp < 50))
-      this._renderQueue.shift().redraw();
-    if (this._renderQueue.length)
-      this._animationsContainer.window().requestAnimationFrame(this._render.bind(this));
-    else
-      delete this._redrawing;
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._cachedTimelineWidth = Math.max(0, this._animationsContainer.offsetWidth - this._timelineControlsWidth) || 0;
-    this._cachedTimelineHeight = this._animationsContainer.offsetHeight;
-    this.scheduleRedraw();
-    if (this._scrubberPlayer)
-      this._syncScrubber();
-    delete this._gridOffsetLeft;
-  }
-
-  /**
-   * @return {number}
-   */
-  width() {
-    return this._cachedTimelineWidth || 0;
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.Animation} animation
-   * @return {boolean}
-   */
-  _resizeWindow(animation) {
-    let resized = false;
-
-    // This shows at most 3 iterations
-    const duration = animation.source().duration() * Math.min(2, animation.source().iterations());
-    const requiredDuration = animation.source().delay() + duration + animation.source().endDelay();
-    if (requiredDuration > this._duration) {
-      resized = true;
-      this._duration = requiredDuration + 200;
-    }
-    return resized;
-  }
-
-  _syncScrubber() {
-    if (!this._selectedGroup)
-      return;
-    this._selectedGroup.currentTimePromise()
-        .then(this._animateTime.bind(this))
-        .then(this._updateControlButton.bind(this));
-  }
-
-  /**
-   * @param {number} currentTime
-   */
-  _animateTime(currentTime) {
-    if (this._scrubberPlayer)
-      this._scrubberPlayer.cancel();
-
-    this._scrubberPlayer = this._timelineScrubber.animate(
-        [{transform: 'translateX(0px)'}, {transform: 'translateX(' + this.width() + 'px)'}],
-        {duration: this.duration(), fill: 'forwards'});
-    this._scrubberPlayer.playbackRate = this._effectivePlaybackRate();
-    this._scrubberPlayer.onfinish = this._updateControlButton.bind(this);
-    this._scrubberPlayer.currentTime = currentTime;
-    this.element.window().requestAnimationFrame(this._updateScrubber.bind(this));
-  }
-
-  /**
-   * @return {number}
-   */
-  pixelMsRatio() {
-    return this.width() / this.duration() || 0;
-  }
-
-  /**
-   * @param {number} timestamp
-   */
-  _updateScrubber(timestamp) {
-    if (!this._scrubberPlayer)
-      return;
-    this._currentTime.textContent = Number.millisToString(this._scrubberPlayer.currentTime);
-    if (this._scrubberPlayer.playState === 'pending' || this._scrubberPlayer.playState === 'running')
-      this.element.window().requestAnimationFrame(this._updateScrubber.bind(this));
-    else if (this._scrubberPlayer.playState === 'finished')
-      this._currentTime.textContent = '';
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _repositionScrubber(event) {
-    if (!this._selectedGroup)
-      return false;
-
-    // Seek to current mouse position.
-    if (!this._gridOffsetLeft)
-      this._gridOffsetLeft = this._grid.totalOffsetLeft() + 10;
-    const seekTime = Math.max(0, event.x - this._gridOffsetLeft) / this.pixelMsRatio();
-    this._selectedGroup.seekTo(seekTime);
-    this._togglePause(true);
-    this._animateTime(seekTime);
-
-    // Interface with scrubber drag.
-    this._originalScrubberTime = seekTime;
-    this._originalMousePosition = event.x;
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _scrubberDragStart(event) {
-    if (!this._scrubberPlayer || !this._selectedGroup)
-      return false;
-
-    this._originalScrubberTime = this._scrubberPlayer.currentTime;
-    this._timelineScrubber.classList.remove('animation-timeline-end');
-    this._scrubberPlayer.pause();
-    this._originalMousePosition = event.x;
-
-    this._togglePause(true);
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _scrubberDragMove(event) {
-    const delta = event.x - this._originalMousePosition;
-    const currentTime =
-        Math.max(0, Math.min(this._originalScrubberTime + delta / this.pixelMsRatio(), this.duration()));
-    this._scrubberPlayer.currentTime = currentTime;
-    this._currentTime.textContent = Number.millisToString(Math.round(currentTime));
-    this._selectedGroup.seekTo(currentTime);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _scrubberDragEnd(event) {
-    const currentTime = Math.max(0, this._scrubberPlayer.currentTime);
-    this._scrubberPlayer.play();
-    this._scrubberPlayer.currentTime = currentTime;
-    this._currentTime.window().requestAnimationFrame(this._updateScrubber.bind(this));
-  }
-};
-
-Animation.AnimationTimeline.GlobalPlaybackRates = [1, 0.25, 0.1];
-
-/** @enum {string} */
-Animation.AnimationTimeline._ControlState = {
-  Play: 'play-outline',
-  Replay: 'replay-outline',
-  Pause: 'pause-outline'
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationTimeline.NodeUI = class {
-  /**
-   * @param {!Animation.AnimationModel.AnimationEffect} animationEffect
-   */
-  constructor(animationEffect) {
-    this.element = createElementWithClass('div', 'animation-node-row');
-    this._description = this.element.createChild('div', 'animation-node-description');
-    this._timelineElement = this.element.createChild('div', 'animation-node-timeline');
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  async nodeResolved(node) {
-    if (!node) {
-      this._description.createTextChild('<node>');
-      return;
-    }
-    this._node = node;
-    this._nodeChanged();
-    Common.Linkifier.linkify(node).then(link => this._description.appendChild(link));
-    if (!node.ownerDocument)
-      this.nodeRemoved();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  createNewRow() {
-    return this._timelineElement.createChild('div', 'animation-timeline-row');
-  }
-
-  nodeRemoved() {
-    this.element.classList.add('animation-node-removed');
-    this._node = null;
-  }
-
-  _nodeChanged() {
-    this.element.classList.toggle(
-        'animation-node-selected', this._node && this._node === UI.context.flavor(SDK.DOMNode));
-  }
-};
-
-/**
- * @unrestricted
- */
-Animation.AnimationTimeline.StepTimingFunction = class {
-  /**
-   * @param {number} steps
-   * @param {string} stepAtPosition
-   */
-  constructor(steps, stepAtPosition) {
-    this.steps = steps;
-    this.stepAtPosition = stepAtPosition;
-  }
-
-  /**
-   * @param {string} text
-   * @return {?Animation.AnimationTimeline.StepTimingFunction}
-   */
-  static parse(text) {
-    let match = text.match(/^steps\((\d+), (start|middle)\)$/);
-    if (match)
-      return new Animation.AnimationTimeline.StepTimingFunction(parseInt(match[1], 10), match[2]);
-    match = text.match(/^steps\((\d+)\)$/);
-    if (match)
-      return new Animation.AnimationTimeline.StepTimingFunction(parseInt(match[1], 10), 'end');
-    return null;
-  }
-};
diff --git a/front_end/animation/AnimationUI.js b/front_end/animation/AnimationUI.js
deleted file mode 100644
index 8c6ebc4..0000000
--- a/front_end/animation/AnimationUI.js
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Animation.AnimationUI = class {
-  /**
-   * @param {!Animation.AnimationModel.Animation} animation
-   * @param {!Animation.AnimationTimeline} timeline
-   * @param {!Element} parentElement
-   */
-  constructor(animation, timeline, parentElement) {
-    this._animation = animation;
-    this._timeline = timeline;
-    this._parentElement = parentElement;
-
-    if (this._animation.source().keyframesRule())
-      this._keyframes = this._animation.source().keyframesRule().keyframes();
-
-    this._nameElement = parentElement.createChild('div', 'animation-name');
-    this._nameElement.textContent = this._animation.name();
-
-    this._svg = parentElement.createSVGChild('svg', 'animation-ui');
-    this._svg.setAttribute('height', Animation.AnimationUI.Options.AnimationSVGHeight);
-    this._svg.style.marginLeft = '-' + Animation.AnimationUI.Options.AnimationMargin + 'px';
-    this._svg.addEventListener('contextmenu', this._onContextMenu.bind(this));
-    this._activeIntervalGroup = this._svg.createSVGChild('g');
-    UI.installDragHandle(
-        this._activeIntervalGroup, this._mouseDown.bind(this, Animation.AnimationUI.MouseEvents.AnimationDrag, null),
-        this._mouseMove.bind(this), this._mouseUp.bind(this), '-webkit-grabbing', '-webkit-grab');
-
-    /** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints: !Object.<number, !Element>, keyframeRender: !Object.<number, !Element>}>} */
-    this._cachedElements = [];
-
-    this._movementInMs = 0;
-    this._color = Animation.AnimationUI.Color(this._animation);
-  }
-
-  /**
-   * @param {!Animation.AnimationModel.Animation} animation
-   * @return {string}
-   */
-  static Color(animation) {
-    const names = Object.keys(Animation.AnimationUI.Colors);
-    const color =
-        Animation.AnimationUI.Colors[names[String.hashCode(animation.name() || animation.id()) % names.length]];
-    return color.asString(Common.Color.Format.RGB);
-  }
-
-  /**
-   * @return {!Animation.AnimationModel.Animation}
-   */
-  animation() {
-    return this._animation;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  setNode(node) {
-    this._node = node;
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {string} className
-   */
-  _createLine(parentElement, className) {
-    const line = parentElement.createSVGChild('line', className);
-    line.setAttribute('x1', Animation.AnimationUI.Options.AnimationMargin);
-    line.setAttribute('y1', Animation.AnimationUI.Options.AnimationHeight);
-    line.setAttribute('y2', Animation.AnimationUI.Options.AnimationHeight);
-    line.style.stroke = this._color;
-    return line;
-  }
-
-  /**
-   * @param {number} iteration
-   * @param {!Element} parentElement
-   */
-  _drawAnimationLine(iteration, parentElement) {
-    const cache = this._cachedElements[iteration];
-    if (!cache.animationLine)
-      cache.animationLine = this._createLine(parentElement, 'animation-line');
-    cache.animationLine.setAttribute(
-        'x2',
-        (this._duration() * this._timeline.pixelMsRatio() + Animation.AnimationUI.Options.AnimationMargin).toFixed(2));
-  }
-
-  /**
-   * @param {!Element} parentElement
-   */
-  _drawDelayLine(parentElement) {
-    if (!this._delayLine) {
-      this._delayLine = this._createLine(parentElement, 'animation-delay-line');
-      this._endDelayLine = this._createLine(parentElement, 'animation-delay-line');
-    }
-    const fill = this._animation.source().fill();
-    this._delayLine.classList.toggle('animation-fill', fill === 'backwards' || fill === 'both');
-    const margin = Animation.AnimationUI.Options.AnimationMargin;
-    this._delayLine.setAttribute('x1', margin);
-    this._delayLine.setAttribute('x2', (this._delay() * this._timeline.pixelMsRatio() + margin).toFixed(2));
-    const forwardsFill = fill === 'forwards' || fill === 'both';
-    this._endDelayLine.classList.toggle('animation-fill', forwardsFill);
-    const leftMargin = Math.min(
-        this._timeline.width(),
-        (this._delay() + this._duration() * this._animation.source().iterations()) * this._timeline.pixelMsRatio());
-    this._endDelayLine.style.transform = 'translateX(' + leftMargin.toFixed(2) + 'px)';
-    this._endDelayLine.setAttribute('x1', margin);
-    this._endDelayLine.setAttribute(
-        'x2', forwardsFill ? (this._timeline.width() - leftMargin + margin).toFixed(2) :
-                             (this._animation.source().endDelay() * this._timeline.pixelMsRatio() + margin).toFixed(2));
-  }
-
-  /**
-   * @param {number} iteration
-   * @param {!Element} parentElement
-   * @param {number} x
-   * @param {number} keyframeIndex
-   * @param {boolean} attachEvents
-   */
-  _drawPoint(iteration, parentElement, x, keyframeIndex, attachEvents) {
-    if (this._cachedElements[iteration].keyframePoints[keyframeIndex]) {
-      this._cachedElements[iteration].keyframePoints[keyframeIndex].setAttribute('cx', x.toFixed(2));
-      return;
-    }
-
-    const circle =
-        parentElement.createSVGChild('circle', keyframeIndex <= 0 ? 'animation-endpoint' : 'animation-keyframe-point');
-    circle.setAttribute('cx', x.toFixed(2));
-    circle.setAttribute('cy', Animation.AnimationUI.Options.AnimationHeight);
-    circle.style.stroke = this._color;
-    circle.setAttribute('r', Animation.AnimationUI.Options.AnimationMargin / 2);
-
-    if (keyframeIndex <= 0)
-      circle.style.fill = this._color;
-
-    this._cachedElements[iteration].keyframePoints[keyframeIndex] = circle;
-
-    if (!attachEvents)
-      return;
-
-    let eventType;
-    if (keyframeIndex === 0)
-      eventType = Animation.AnimationUI.MouseEvents.StartEndpointMove;
-    else if (keyframeIndex === -1)
-      eventType = Animation.AnimationUI.MouseEvents.FinishEndpointMove;
-    else
-      eventType = Animation.AnimationUI.MouseEvents.KeyframeMove;
-    UI.installDragHandle(
-        circle, this._mouseDown.bind(this, eventType, keyframeIndex), this._mouseMove.bind(this),
-        this._mouseUp.bind(this), 'ew-resize');
-  }
-
-  /**
-   * @param {number} iteration
-   * @param {number} keyframeIndex
-   * @param {!Element} parentElement
-   * @param {number} leftDistance
-   * @param {number} width
-   * @param {string} easing
-   */
-  _renderKeyframe(iteration, keyframeIndex, parentElement, leftDistance, width, easing) {
-    /**
-     * @param {!Element} parentElement
-     * @param {number} x
-     * @param {string} strokeColor
-     */
-    function createStepLine(parentElement, x, strokeColor) {
-      const line = parentElement.createSVGChild('line');
-      line.setAttribute('x1', x);
-      line.setAttribute('x2', x);
-      line.setAttribute('y1', Animation.AnimationUI.Options.AnimationMargin);
-      line.setAttribute('y2', Animation.AnimationUI.Options.AnimationHeight);
-      line.style.stroke = strokeColor;
-    }
-
-    const bezier = UI.Geometry.CubicBezier.parse(easing);
-    const cache = this._cachedElements[iteration].keyframeRender;
-    if (!cache[keyframeIndex]) {
-      cache[keyframeIndex] = bezier ? parentElement.createSVGChild('path', 'animation-keyframe') :
-                                      parentElement.createSVGChild('g', 'animation-keyframe-step');
-    }
-    const group = cache[keyframeIndex];
-    group.style.transform = 'translateX(' + leftDistance.toFixed(2) + 'px)';
-
-    if (easing === 'linear') {
-      group.style.fill = this._color;
-      const height = InlineEditor.BezierUI.Height;
-      group.setAttribute(
-          'd', ['M', 0, height, 'L', 0, 5, 'L', width.toFixed(2), 5, 'L', width.toFixed(2), height, 'Z'].join(' '));
-    } else if (bezier) {
-      group.style.fill = this._color;
-      InlineEditor.BezierUI.drawVelocityChart(bezier, group, width);
-    } else {
-      const stepFunction = Animation.AnimationTimeline.StepTimingFunction.parse(easing);
-      group.removeChildren();
-      /** @const */ const offsetMap = {'start': 0, 'middle': 0.5, 'end': 1};
-      /** @const */ const offsetWeight = offsetMap[stepFunction.stepAtPosition];
-      for (let i = 0; i < stepFunction.steps; i++)
-        createStepLine(group, (i + offsetWeight) * width / stepFunction.steps, this._color);
-    }
-  }
-
-  redraw() {
-    const maxWidth = this._timeline.width() - Animation.AnimationUI.Options.AnimationMargin;
-
-    this._svg.setAttribute('width', (maxWidth + 2 * Animation.AnimationUI.Options.AnimationMargin).toFixed(2));
-    this._activeIntervalGroup.style.transform =
-        'translateX(' + (this._delay() * this._timeline.pixelMsRatio()).toFixed(2) + 'px)';
-
-    this._nameElement.style.transform = 'translateX(' +
-        (this._delay() * this._timeline.pixelMsRatio() + Animation.AnimationUI.Options.AnimationMargin).toFixed(2) +
-        'px)';
-    this._nameElement.style.width = (this._duration() * this._timeline.pixelMsRatio()).toFixed(2) + 'px';
-    this._drawDelayLine(this._svg);
-
-    if (this._animation.type() === 'CSSTransition') {
-      this._renderTransition();
-      return;
-    }
-
-    this._renderIteration(this._activeIntervalGroup, 0);
-    if (!this._tailGroup)
-      this._tailGroup = this._activeIntervalGroup.createSVGChild('g', 'animation-tail-iterations');
-    const iterationWidth = this._duration() * this._timeline.pixelMsRatio();
-    let iteration;
-    for (iteration = 1;
-         iteration < this._animation.source().iterations() && iterationWidth * (iteration - 1) < this._timeline.width();
-         iteration++)
-      this._renderIteration(this._tailGroup, iteration);
-    while (iteration < this._cachedElements.length)
-      this._cachedElements.pop().group.remove();
-  }
-
-  _renderTransition() {
-    if (!this._cachedElements[0])
-      this._cachedElements[0] = {animationLine: null, keyframePoints: {}, keyframeRender: {}, group: null};
-    this._drawAnimationLine(0, this._activeIntervalGroup);
-    this._renderKeyframe(
-        0, 0, this._activeIntervalGroup, Animation.AnimationUI.Options.AnimationMargin,
-        this._duration() * this._timeline.pixelMsRatio(), this._animation.source().easing());
-    this._drawPoint(0, this._activeIntervalGroup, Animation.AnimationUI.Options.AnimationMargin, 0, true);
-    this._drawPoint(
-        0, this._activeIntervalGroup,
-        this._duration() * this._timeline.pixelMsRatio() + Animation.AnimationUI.Options.AnimationMargin, -1, true);
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {number} iteration
-   */
-  _renderIteration(parentElement, iteration) {
-    if (!this._cachedElements[iteration]) {
-      this._cachedElements[iteration] =
-          {animationLine: null, keyframePoints: {}, keyframeRender: {}, group: parentElement.createSVGChild('g')};
-    }
-    const group = this._cachedElements[iteration].group;
-    group.style.transform =
-        'translateX(' + (iteration * this._duration() * this._timeline.pixelMsRatio()).toFixed(2) + 'px)';
-    this._drawAnimationLine(iteration, group);
-    console.assert(this._keyframes.length > 1);
-    for (let i = 0; i < this._keyframes.length - 1; i++) {
-      const leftDistance = this._offset(i) * this._duration() * this._timeline.pixelMsRatio() +
-          Animation.AnimationUI.Options.AnimationMargin;
-      const width = this._duration() * (this._offset(i + 1) - this._offset(i)) * this._timeline.pixelMsRatio();
-      this._renderKeyframe(iteration, i, group, leftDistance, width, this._keyframes[i].easing());
-      if (i || (!i && iteration === 0))
-        this._drawPoint(iteration, group, leftDistance, i, iteration === 0);
-    }
-    this._drawPoint(
-        iteration, group,
-        this._duration() * this._timeline.pixelMsRatio() + Animation.AnimationUI.Options.AnimationMargin, -1,
-        iteration === 0);
-  }
-
-  /**
-   * @return {number}
-   */
-  _delay() {
-    let delay = this._animation.source().delay();
-    if (this._mouseEventType === Animation.AnimationUI.MouseEvents.AnimationDrag ||
-        this._mouseEventType === Animation.AnimationUI.MouseEvents.StartEndpointMove)
-      delay += this._movementInMs;
-    // FIXME: add support for negative start delay
-    return Math.max(0, delay);
-  }
-
-  /**
-   * @return {number}
-   */
-  _duration() {
-    let duration = this._animation.source().duration();
-    if (this._mouseEventType === Animation.AnimationUI.MouseEvents.FinishEndpointMove)
-      duration += this._movementInMs;
-    else if (this._mouseEventType === Animation.AnimationUI.MouseEvents.StartEndpointMove)
-      duration -= Math.max(this._movementInMs, -this._animation.source().delay());  // Cannot have negative delay
-    return Math.max(0, duration);
-  }
-
-  /**
-   * @param {number} i
-   * @return {number} offset
-   */
-  _offset(i) {
-    let offset = this._keyframes[i].offsetAsNumber();
-    if (this._mouseEventType === Animation.AnimationUI.MouseEvents.KeyframeMove && i === this._keyframeMoved) {
-      console.assert(i > 0 && i < this._keyframes.length - 1, 'First and last keyframe cannot be moved');
-      offset += this._movementInMs / this._animation.source().duration();
-      offset = Math.max(offset, this._keyframes[i - 1].offsetAsNumber());
-      offset = Math.min(offset, this._keyframes[i + 1].offsetAsNumber());
-    }
-    return offset;
-  }
-
-  /**
-   * @param {!Animation.AnimationUI.MouseEvents} mouseEventType
-   * @param {?number} keyframeIndex
-   * @param {!Event} event
-   */
-  _mouseDown(mouseEventType, keyframeIndex, event) {
-    if (event.buttons === 2)
-      return false;
-    if (this._svg.enclosingNodeOrSelfWithClass('animation-node-removed'))
-      return false;
-    this._mouseEventType = mouseEventType;
-    this._keyframeMoved = keyframeIndex;
-    this._downMouseX = event.clientX;
-    event.consume(true);
-    if (this._node)
-      Common.Revealer.reveal(this._node);
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseMove(event) {
-    this._movementInMs = (event.clientX - this._downMouseX) / this._timeline.pixelMsRatio();
-    if (this._delay() + this._duration() > this._timeline.duration() * 0.8)
-      this._timeline.setDuration(this._timeline.duration() * 1.2);
-    this.redraw();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseUp(event) {
-    this._movementInMs = (event.clientX - this._downMouseX) / this._timeline.pixelMsRatio();
-
-    // Commit changes
-    if (this._mouseEventType === Animation.AnimationUI.MouseEvents.KeyframeMove)
-      this._keyframes[this._keyframeMoved].setOffset(this._offset(this._keyframeMoved));
-    else
-      this._animation.setTiming(this._duration(), this._delay());
-
-    this._movementInMs = 0;
-    this.redraw();
-
-    delete this._mouseEventType;
-    delete this._downMouseX;
-    delete this._keyframeMoved;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onContextMenu(event) {
-    /**
-     * @param {?SDK.RemoteObject} remoteObject
-     */
-    function showContextMenu(remoteObject) {
-      if (!remoteObject)
-        return;
-      const contextMenu = new UI.ContextMenu(event);
-      contextMenu.appendApplicableItems(remoteObject);
-      contextMenu.show();
-    }
-
-    this._animation.remoteObjectPromise().then(showContextMenu);
-    event.consume(true);
-  }
-};
-
-/**
- * @enum {string}
- */
-Animation.AnimationUI.MouseEvents = {
-  AnimationDrag: 'AnimationDrag',
-  KeyframeMove: 'KeyframeMove',
-  StartEndpointMove: 'StartEndpointMove',
-  FinishEndpointMove: 'FinishEndpointMove'
-};
-
-Animation.AnimationUI.Options = {
-  AnimationHeight: 26,
-  AnimationSVGHeight: 50,
-  AnimationMargin: 7,
-  EndpointsClickRegionSize: 10,
-  GridCanvasHeight: 40
-};
-
-Animation.AnimationUI.Colors = {
-  'Purple': Common.Color.parse('#9C27B0'),
-  'Light Blue': Common.Color.parse('#03A9F4'),
-  'Deep Orange': Common.Color.parse('#FF5722'),
-  'Blue': Common.Color.parse('#5677FC'),
-  'Lime': Common.Color.parse('#CDDC39'),
-  'Blue Grey': Common.Color.parse('#607D8B'),
-  'Pink': Common.Color.parse('#E91E63'),
-  'Green': Common.Color.parse('#0F9D58'),
-  'Brown': Common.Color.parse('#795548'),
-  'Cyan': Common.Color.parse('#00BCD4')
-};
diff --git a/front_end/animation/animationScreenshotPopover.css b/front_end/animation/animationScreenshotPopover.css
deleted file mode 100644
index f769794..0000000
--- a/front_end/animation/animationScreenshotPopover.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-img {
-    max-height: 300px;
-    border-radius: 2px;
-}
-
-.animation-progress {
-    position: absolute;
-    height: 2px;
-    bottom: 0;
-    left: 0;
-    background: var(--selection-bg-color);
-}
diff --git a/front_end/animation/animationTimeline.css b/front_end/animation/animationTimeline.css
deleted file mode 100644
index 703fb86..0000000
--- a/front_end/animation/animationTimeline.css
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    overflow: hidden;
-}
-
-.animation-node-row {
-    width: 100%;
-    display: flex;
-    border-bottom: 1px dashed hsla(0,0%,94%,1);
-}
-
-.animation-node-description {
-    width: 150px;
-    padding-left: 8px;
-    overflow: hidden;
-    position: relative;
-    transform-style: preserve-3d;
-    border-bottom: 1px solid hsl(0, 0%, 90%);
-    margin-bottom: -1px;
-    background-color: hsl(0, 0%, 98%);
-    display: flex;
-    align-items: center;
-    flex: 0 0 150px;
-}
-
-.animation-node-description > * {
-    flex: 0 0 auto;
-}
-
-.animation-timeline-row {
-    height: 32px;
-    position: relative;
-}
-
-path.animation-keyframe {
-    fill-opacity: 0.2;
-}
-
-svg.animation-ui g:first-child:hover path.animation-keyframe {
-    fill-opacity: 0.4;
-}
-
-.animation-node-selected path.animation-keyframe {
-    fill-opacity: 0.4;
-}
-
-line.animation-line {
-    stroke-width: 2px;
-    stroke-linecap: round;
-    fill: none;
-}
-
-line.animation-delay-line {
-    stroke-width: 2px;
-    stroke-dasharray: 6, 4;
-}
-
-line.animation-delay-line.animation-fill {
-    stroke-dasharray: none;
-}
-
-circle.animation-endpoint, circle.animation-keyframe-point {
-    stroke-width: 2px;
-    transition: transform 100ms cubic-bezier(0, 0, 0.2, 1);
-    transform: scale(1);
-    transform-box: fill-box;
-    transform-origin: 50% 50%;
-}
-
-.animation-ui circle.animation-endpoint:hover, .animation-ui circle.animation-keyframe-point:hover {
-    transform: scale(1.2);
-}
-
-circle.animation-endpoint:active, circle.animation-keyframe-point:active {
-    transform: scale(1);
-}
-
-circle.animation-keyframe-point {
-    fill: white;
-}
-
-.animation-name {
-    position: absolute;
-    top: 8px;
-    color: #333;
-    text-align: center;
-    margin-left: -8px;
-    white-space: nowrap;
-}
-
-.animation-timeline-toolbar-container {
-    display: flex;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-    flex: 0 0;
-}
-
-.animation-timeline-toolbar {
-    display: inline-block;
-}
-
-.animation-timeline-header {
-    height: 28px;
-    border-bottom: 1px solid #ccc;
-    flex-shrink: 0;
-    display: flex;
-}
-
-.animation-timeline-header:after {
-    content: "";
-    height: calc(100% - 48px - 28px);
-    position: absolute;
-    width: 150px;
-    left: 0;
-    margin-top: 28px;
-    background-color: hsl(0, 0%, 98%);
-    z-index: 0;
-    border-right: 1px solid hsl(0, 0%, 90%);
-}
-
-.animation-controls {
-    flex: 0 0 150px;
-    position: relative;
-    display: flex;
-    justify-content: flex-end;
-    padding-right: 8px;
-}
-
-.animation-timeline-current-time {flex: 0 0 auto;line-height: 28px;margin-right: 5px;}
-.animation-grid-header {
-    flex: 1 0 auto;
-    z-index: 1;
-    cursor: text;
-}
-
-.animation-timeline-buffer, .animation-timeline-buffer-hint {
-    height: 48px;
-    flex: 0 0 auto;
-    border-bottom: 1px solid #ccc;
-    display: flex;
-    padding: 0 2px;
-}
-
-.animation-timeline-buffer:empty, .animation-timeline-buffer-hint {
-    display: none;
-}
-
-.animation-timeline-buffer:empty ~ .animation-timeline-buffer-hint {
-    align-items: center;
-    justify-content: center;
-    font-size: 14px;
-    z-index: 101;
-    display: flex;
-}
-
-.animation-time-overlay {
-    background-color: black;
-    opacity: 0.05;
-    position: absolute;
-    height: 100%;
-    width: 100%;
-    z-index: -1;
-}
-
-.animation-timeline-end > .animation-time-overlay {
-    visibility: hidden;
-}
-
-.animation-scrubber {
-    opacity: 1;
-    position: absolute;
-    left: 150px;
-    height: calc(100% - 103px);
-    width: calc(100% - 150px);
-    top: 103px;
-    border-left: 1px solid hsla(4,90%,58%,1);
-    z-index: 1;
-}
-
-.animation-scrubber-line {
-    width: 11px;
-    background: linear-gradient(to right, transparent 5px, hsla(4,90%,58%,1) 5px, hsla(4,90%,58%,1) 6px, transparent 6px);
-    position: absolute;
-    top: -28px;
-    height: 28px;
-    left: -6px;
-    padding: 0 5px;
-    z-index: 2;
-}
-
-.animation-scrubber-head {
-    width: 7px;
-    height: 7px;
-    transform: rotate(45deg);
-    background: red;
-    position: absolute;
-    left: 2px;
-    top: 1px;
-}
-
-svg.animation-timeline-grid {
-    position: absolute;
-    left: 140px;
-    top: 76px;
-    z-index: 0;
-}
-
-rect.animation-timeline-grid-line {
-    fill: hsla(0,0%,93%,1);
-}
-
-.animation-timeline-row > svg.animation-ui {
-    position: absolute;
-}
-
-.animation-node-timeline {
-    flex-grow: 1;
-}
-
-.animation-node-description > div {
-    position: absolute;
-    top: 50%;
-    transform: translateY(-50%);
-    max-height: 100%;
-}
-
-.animation-node-removed {
-    -webkit-filter: saturate(0);
-    cursor: not-allowed;
-}
-
-svg.animation-ui g:first-child {
-    opacity: 1;
-}
-
-.animation-tail-iterations {
-    opacity: 0.5;
-}
-
-.animation-keyframe-step line {
-    stroke-width: 2;
-    stroke-opacity: 0.3;
-}
-
-text.animation-timeline-grid-label {
-    font-size: 10px;
-    fill: #5a5a5a;
-    text-anchor: middle;
-}
-
-.animation-timeline-rows, .animation-timeline-rows-hint {
-    flex-grow: 1;
-    overflow-y: auto;
-    z-index: 1;
-    overflow-x: hidden;
-}
-
-.animation-timeline-rows-hint {
-    display: none;
-}
-
-.animation-timeline-buffer:not(:empty) ~ .animation-timeline-rows:empty {
-    flex-grow: 0;
-}
-
-.animation-timeline-buffer:not(:empty) ~ .animation-timeline-rows:empty ~ .animation-timeline-rows-hint {
-    font-size: 14px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin-left: 150px;
-    padding: 10px;
-}
-
-.toolbar.animation-controls-toolbar {
-    flex: 0 0 auto;
-}
-
-.animation-node-row.animation-node-selected {
-    background-color: hsla(216, 71%, 53%, 0.08);
-}
-
-.animation-node-selected > .animation-node-description {
-    background-color: #EFF4FD;
-}
-
-.animation-timeline-empty-message {
-    padding-left: 230px;
-    padding-right: 30px;
-    text-align: center;
-    position: absolute;
-    font-size: 20px;
-    line-height: 32px;
-    align-items: center;   justify-content: center;
-    width: 100%;
-    height: calc(100% - 44px);
-    display: flex;
-}
-
-.animation-buffer-preview {
-    height: 40px;
-    margin: 4px 2px;
-    background-color: var(--toolbar-bg-color);
-    border-radius: 2px;
-    flex: 1 1;
-    padding: 4px;
-    max-width: 100px;
-    animation: newGroupAnim 200ms;
-    position: relative;
-}
-
-.animation-buffer-preview-animation {
-    width: 100%;
-    height: 100%;
-    border-radius: 2px 0 0 2px;
-    position: absolute;
-    top: 0;
-    left: 0;
-    background: hsla(219, 100%, 66%, 0.27);
-    opacity: 0;
-    border-right: 1px solid #A7A7A7;
-    cursor: pointer;
-}
-
-.animation-buffer-preview:not(.selected):hover {
-    background-color: hsla(217,90%,92%,1);
-}
-
-.animation-buffer-preview.selected {
-    background-color: var(--selection-bg-color);
-}
-
-.animation-paused {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    background-color: hsla(0,0%,70%,0.5);
-    display: none;
-}
-
-.animation-paused:before, .animation-paused:after {
-    content: "";
-    background: hsl(0, 100%, 100%);
-    width: 7px;
-    height: 20px;
-    border-radius: 2px;
-    margin: 2px;
-    border: 1px solid #ccc;
-}
-
-.animation-buffer-preview.paused .animation-paused {
-    display: flex;
-}
-
-.animation-buffer-preview.selected > svg > line {
-    stroke: white !important;
-}
-
-.animation-buffer-preview > svg > line {
-    stroke-width: 1px;
-}
-
-@keyframes newGroupAnim {
-    from {
-        -webkit-clip-path: polygon(0% 0%, 0% 100%, 0% 100%, 0% 0%);
-    }
-    to {
-        -webkit-clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0%);
-    }
-}
-
-.animation-playback-rate-control {
-    margin: 4px 0 4px 2px;
-    display: flex;
-    width: 120px;
-}
-
-.animation-playback-rate-button:first-child {
-    border-radius: 4px 0 0 4px;
-}
-
-.animation-playback-rate-button:last-child {
-    border-radius: 0 4px 4px 0;
-}
-
-.animation-playback-rate-button {
-    border: 1px solid #ccc;
-    display: inline-block;
-    margin-right: -1px;
-    padding: 1px 4px;
-    background: white;
-    flex: 1 0 auto;
-    text-align: center;
-    cursor: pointer;
-}
-
-.animation-playback-rate-button:not(.selected):hover {
-    background: hsl(211, 100%, 95%);
-}
-
-.animation-playback-rate-button.selected {
-    color: hsl(0, 100%, 100%);
-    background-color: var(--selection-bg-color);
-    border-color: var(--selection-bg-color);
-    z-index: 1;
-}
-
-.animation-playback-rate-button.selected:first-child {
-    color: var(--selection-bg-color);
-    background-color: hsl(217, 89%, 100%);
-}
-
-.animation-remove-button, -theme-preserve {
-    position: absolute;
-    top: -3px;
-    right: -3px;
-    background: #7B7B7B;
-    border-radius: 12px;
-    height: 16px;
-    width: 16px;
-    align-items: center;
-    font-size: 10px;
-    justify-content: center;
-    box-shadow: 0 1px 4px 0 rgb(185, 185, 185);
-    z-index: 100;
-    display: none;
-    cursor: pointer;
-    font-weight: 700;
-    color: white;
-}
-
-.animation-remove-button:hover {
-    background: #585858;
-}
-
-.animation-buffer-preview:hover .animation-remove-button {
-    display: flex;
-}
diff --git a/front_end/animation/module.json b/front_end/animation/module.json
deleted file mode 100644
index 57e238c..0000000
--- a/front_end/animation/module.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "animations",
-            "title": "Animations",
-            "persistence": "closeable",
-            "order": 0,
-            "className": "Animation.AnimationTimeline"
-        }
-    ],
-    "dependencies": [
-        "elements"
-    ],
-    "scripts": [
-        "AnimationModel.js",
-        "AnimationGroupPreviewUI.js",
-        "AnimationScreenshotPopover.js",
-        "AnimationTimeline.js",
-        "AnimationUI.js"
-    ],
-    "resources": [
-        "animationScreenshotPopover.css",
-        "animationTimeline.css"
-    ]
-}
diff --git a/front_end/application_test_runner/AppcacheTestRunner.js b/front_end/application_test_runner/AppcacheTestRunner.js
deleted file mode 100644
index 14b4089..0000000
--- a/front_end/application_test_runner/AppcacheTestRunner.js
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ApplicationTestRunner.createAndNavigateIFrame = function(url, callback) {
-  TestRunner.addSniffer(SDK.ResourceTreeModel.prototype, '_frameNavigated', frameNavigated);
-  TestRunner.evaluateInPageAnonymously('createAndNavigateIFrame(unescape(\'' + escape(url) + '\'))');
-
-  function frameNavigated(frame) {
-    callback(frame.id);
-  }
-};
-
-ApplicationTestRunner.navigateIFrame = function(frameId, url, callback) {
-  const frame = TestRunner.resourceTreeModel.frameForId(frameId);
-  TestRunner.evaluateInPageAnonymously(
-      'navigateIFrame(unescape(\'' + escape(frame.name) + '\'), unescape(\'' + escape(url) + '\'))');
-  TestRunner.addSniffer(SDK.ResourceTreeModel.prototype, '_frameNavigated', frameNavigated);
-
-  function frameNavigated(frame) {
-    callback(frame.id);
-  }
-};
-
-ApplicationTestRunner.removeIFrame = function(frameId, callback) {
-  const frame = TestRunner.resourceTreeModel.frameForId(frameId);
-  TestRunner.evaluateInPageAnonymously('removeIFrame(unescape(\'' + escape(frame.name) + '\'))');
-  TestRunner.addSniffer(SDK.ResourceTreeModel.prototype, '_frameDetached', frameDetached);
-
-  function frameDetached(frame) {
-    callback(frame.id);
-  }
-};
-
-ApplicationTestRunner.swapFrameCache = function(frameId) {
-  const frame = TestRunner.resourceTreeModel.frameForId(frameId);
-  TestRunner.evaluateInPageAnonymously('swapFrameCache(unescape(\'' + escape(frame.name) + '\'))');
-};
-
-ApplicationTestRunner.dumpApplicationCache = function() {
-  ApplicationTestRunner.dumpApplicationCacheTree();
-  ApplicationTestRunner.dumpApplicationCacheModel();
-  TestRunner.addResult('');
-};
-
-ApplicationTestRunner.dumpApplicationCacheTree = function() {
-  TestRunner.addResult('Dumping application cache tree:');
-  const applicationCacheTreeElement = UI.panels.resources._sidebar.applicationCacheListTreeElement;
-
-  if (!applicationCacheTreeElement.childCount()) {
-    TestRunner.addResult('    (empty)');
-    return;
-  }
-
-  for (let i = 0; i < applicationCacheTreeElement.childCount(); ++i) {
-    const manifestTreeElement = applicationCacheTreeElement.childAt(i);
-    TestRunner.addResult('    Manifest URL: ' + manifestTreeElement.manifestURL);
-
-    if (!manifestTreeElement.childCount()) {
-      TestRunner.addResult('    (no frames)');
-      continue;
-    }
-
-    for (let j = 0; j < manifestTreeElement.childCount(); ++j) {
-      const frameTreeElement = manifestTreeElement.childAt(j);
-      TestRunner.addResult('        Frame: ' + frameTreeElement.title);
-    }
-  }
-};
-
-ApplicationTestRunner.frameIdToString = function(frameId) {
-  if (!ApplicationTestRunner.framesByFrameId)
-    ApplicationTestRunner.framesByFrameId = {};
-
-  let frame = TestRunner.resourceTreeModel.frameForId(frameId);
-
-  if (!frame)
-    frame = ApplicationTestRunner.framesByFrameId[frameId];
-
-  ApplicationTestRunner.framesByFrameId[frameId] = frame;
-  return frame.name;
-};
-
-ApplicationTestRunner.applicationCacheStatusToString = function(status) {
-  const statusInformation = {};
-  statusInformation[applicationCache.UNCACHED] = 'UNCACHED';
-  statusInformation[applicationCache.IDLE] = 'IDLE';
-  statusInformation[applicationCache.CHECKING] = 'CHECKING';
-  statusInformation[applicationCache.DOWNLOADING] = 'DOWNLOADING';
-  statusInformation[applicationCache.UPDATEREADY] = 'UPDATEREADY';
-  statusInformation[applicationCache.OBSOLETE] = 'OBSOLETE';
-  return statusInformation[status] || statusInformation[applicationCache.UNCACHED];
-};
-
-ApplicationTestRunner.dumpApplicationCacheModel = function() {
-  TestRunner.addResult('Dumping application cache model:');
-  const model = UI.panels.resources._sidebar._applicationCacheModel;
-  const frameIds = [];
-
-  for (const frameId in model._manifestURLsByFrame)
-    frameIds.push(frameId);
-
-  function compareFunc(a, b) {
-    return ApplicationTestRunner.frameIdToString(a).localeCompare(ApplicationTestRunner.frameIdToString(b));
-  }
-
-  frameIds.sort(compareFunc);
-
-  if (!frameIds.length) {
-    TestRunner.addResult('    (empty)');
-    return;
-  }
-
-  for (let i = 0; i < frameIds.length; ++i) {
-    const frameId = frameIds[i];
-    const manifestURL = model.frameManifestURL(frameId);
-    const status = model.frameManifestStatus(frameId);
-    TestRunner.addResult('    Frame: ' + ApplicationTestRunner.frameIdToString(frameId));
-    TestRunner.addResult('        manifest url: ' + manifestURL);
-    TestRunner.addResult('        status:       ' + ApplicationTestRunner.applicationCacheStatusToString(status));
-  }
-};
-
-ApplicationTestRunner.waitForFrameManifestURLAndStatus = function(frameId, manifestURL, status, callback) {
-  const frameManifestStatus = UI.panels.resources._sidebar._applicationCacheModel.frameManifestStatus(frameId);
-  const frameManifestURL = UI.panels.resources._sidebar._applicationCacheModel.frameManifestURL(frameId);
-
-  if (frameManifestStatus === status && frameManifestURL.indexOf(manifestURL) !== -1) {
-    callback();
-    return;
-  }
-
-  const handler =
-      ApplicationTestRunner.waitForFrameManifestURLAndStatus.bind(this, frameId, manifestURL, status, callback);
-  TestRunner.addSniffer(Resources.ApplicationCacheModel.prototype, '_frameManifestUpdated', handler);
-};
-
-ApplicationTestRunner.startApplicationCacheStatusesRecording = function() {
-  if (ApplicationTestRunner.applicationCacheStatusesRecords) {
-    ApplicationTestRunner.applicationCacheStatusesRecords = {};
-    return;
-  }
-
-  ApplicationTestRunner.applicationCacheStatusesRecords = {};
-
-  function addRecord(frameId, manifestURL, status) {
-    const record = {};
-    record.manifestURL = manifestURL;
-    record.status = status;
-
-    if (!ApplicationTestRunner.applicationCacheStatusesRecords[frameId])
-      ApplicationTestRunner.applicationCacheStatusesRecords[frameId] = [];
-
-    ApplicationTestRunner.applicationCacheStatusesRecords[frameId].push(record);
-
-    if (ApplicationTestRunner.awaitedFrameStatusEventsCount &&
-        ApplicationTestRunner.awaitedFrameStatusEventsCount[frameId]) {
-      ApplicationTestRunner.awaitedFrameStatusEventsCount[frameId].count--;
-
-      if (!ApplicationTestRunner.awaitedFrameStatusEventsCount[frameId].count)
-        ApplicationTestRunner.awaitedFrameStatusEventsCount[frameId].callback();
-    }
-  }
-
-  TestRunner.addSniffer(Resources.ApplicationCacheModel.prototype, '_frameManifestUpdated', addRecord, true);
-};
-
-ApplicationTestRunner.ensureFrameStatusEventsReceived = function(frameId, count, callback) {
-  const records = ApplicationTestRunner.applicationCacheStatusesRecords[frameId] || [];
-  const eventsLeft = count - records.length;
-
-  if (!eventsLeft) {
-    callback();
-    return;
-  }
-
-  if (!ApplicationTestRunner.awaitedFrameStatusEventsCount)
-    ApplicationTestRunner.awaitedFrameStatusEventsCount = {};
-
-  ApplicationTestRunner.awaitedFrameStatusEventsCount[frameId] = {count: eventsLeft, callback: callback};
-};
-
-TestRunner.deprecatedInitAsync(`
-  let framesCount = 0;
-
-  function createAndNavigateIFrame(url) {
-    let iframe = document.createElement('iframe');
-    iframe.src = url;
-    iframe.name = 'frame' + ++framesCount;
-    iframe.id = iframe.name;
-    document.body.appendChild(iframe);
-  }
-
-  function removeIFrame(name) {
-    let iframe = document.querySelector('#' + name);
-    iframe.parentElement.removeChild(iframe);
-  }
-
-  function navigateIFrame(name, url) {
-    let iframe = document.querySelector('#' + name);
-    iframe.src = url;
-  }
-
-  function swapFrameCache(name) {
-    let iframe = document.querySelector('#' + name);
-    iframe.contentWindow.applicationCache.swapCache();
-  }
-`);
diff --git a/front_end/application_test_runner/CacheStorageTestRunner.js b/front_end/application_test_runner/CacheStorageTestRunner.js
deleted file mode 100644
index 29d10cc..0000000
--- a/front_end/application_test_runner/CacheStorageTestRunner.js
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ApplicationTestRunner.dumpCacheTree = async function() {
-  UI.panels.resources._sidebar.cacheStorageListTreeElement.expand();
-  const promise = TestRunner.addSnifferPromise(SDK.ServiceWorkerCacheModel.prototype, '_updateCacheNames');
-  UI.panels.resources._sidebar.cacheStorageListTreeElement._refreshCaches();
-  await promise;
-  await ApplicationTestRunner.dumpCacheTreeNoRefresh();
-};
-
-ApplicationTestRunner.dumpCacheTreeNoRefresh = async function() {
-  UI.panels.resources._sidebar.cacheStorageListTreeElement.expand();
-  TestRunner.addResult('Dumping CacheStorage tree:');
-  const cachesTreeElement = UI.panels.resources._sidebar.cacheStorageListTreeElement;
-
-  if (!cachesTreeElement.childCount()) {
-    TestRunner.addResult('    (empty)');
-    return;
-  }
-
-  for (let i = 0; i < cachesTreeElement.childCount(); ++i) {
-    const cacheTreeElement = cachesTreeElement.childAt(i);
-    TestRunner.addResult('    cache: ' + cacheTreeElement.title);
-    let view = cacheTreeElement._view;
-    promise = TestRunner.addSnifferPromise(Resources.ServiceWorkerCacheView.prototype, '_updateDataCallback');
-
-    if (!view)
-      cacheTreeElement.onselect(false);
-    else
-      view._updateData(true);
-
-    view = cacheTreeElement._view;
-    await promise;
-
-    if (view._entriesForTest.length === 0) {
-      TestRunner.addResult('        (cache empty)');
-      continue;
-    }
-
-    const dataGrid = view._dataGrid;
-
-    for (const node of dataGrid.rootNode().children) {
-      const children = Array.from(node.element().children).filter(function(element) {
-        return !element.classList.contains('responseTime-column');
-      });
-
-      const entries = Array.from(children, td => td.textContent).filter(text => text);
-      TestRunner.addResult('        ' + entries.join(', '));
-    }
-  }
-};
-
-ApplicationTestRunner.deleteCacheFromInspector = async function(cacheName, optionalEntry) {
-  UI.panels.resources._sidebar.cacheStorageListTreeElement.expand();
-
-  if (optionalEntry)
-    TestRunner.addResult('Deleting CacheStorage entry ' + optionalEntry + ' in cache ' + cacheName);
-  else
-    TestRunner.addResult('Deleting CacheStorage cache ' + cacheName);
-
-  const cachesTreeElement = UI.panels.resources._sidebar.cacheStorageListTreeElement;
-  let promise = TestRunner.addSnifferPromise(SDK.ServiceWorkerCacheModel.prototype, '_updateCacheNames');
-  UI.panels.resources._sidebar.cacheStorageListTreeElement._refreshCaches();
-  await promise;
-
-  if (!cachesTreeElement.childCount())
-    throw 'Error: Could not find CacheStorage cache ' + cacheName;
-
-
-  for (let i = 0; i < cachesTreeElement.childCount(); i++) {
-    const cacheTreeElement = cachesTreeElement.childAt(i);
-    const title = cacheTreeElement.title;
-    const elementCacheName = title.substring(0, title.lastIndexOf(' - '));
-
-    if (elementCacheName !== cacheName)
-      continue;
-
-    if (!optionalEntry) {
-      promise = TestRunner.addSnifferPromise(SDK.ServiceWorkerCacheModel.prototype, '_cacheRemoved');
-      cacheTreeElement._clearCache();
-      await promise;
-      return;
-    }
-
-    promise = TestRunner.addSnifferPromise(Resources.ServiceWorkerCacheView.prototype, '_updateDataCallback');
-    let view = cacheTreeElement._view;
-
-    if (!view)
-      cacheTreeElement.onselect(false);
-    else
-      view._updateData(true);
-
-    view = cacheTreeElement._view;
-    await promise;
-    const entry = view._entriesForTest.find(entry => entry.requestURL === optionalEntry);
-
-    if (!entry)
-      throw 'Error: Could not find cache entry to delete: ' + optionalEntry;
-
-    await view._model.deleteCacheEntry(view._cache, entry.requestURL);
-    return;
-  }
-
-  throw 'Error: Could not find CacheStorage cache ' + cacheName;
-};
-
-ApplicationTestRunner.waitForCacheRefresh = function(callback) {
-  TestRunner.addSniffer(SDK.ServiceWorkerCacheModel.prototype, '_updateCacheNames', callback, false);
-};
-
-ApplicationTestRunner.createCache = function(cacheName) {
-  return TestRunner.callFunctionInPageAsync('createCache', [cacheName]);
-};
-
-ApplicationTestRunner.addCacheEntry = function(cacheName, requestUrl, responseText) {
-  return TestRunner.callFunctionInPageAsync('addCacheEntry', [cacheName, requestUrl, responseText]);
-};
-
-ApplicationTestRunner.deleteCache = function(cacheName) {
-  return TestRunner.callFunctionInPageAsync('deleteCache', [cacheName]);
-};
-
-ApplicationTestRunner.deleteCacheEntry = function(cacheName, requestUrl) {
-  return TestRunner.callFunctionInPageAsync('deleteCacheEntry', [cacheName, requestUrl]);
-};
-
-ApplicationTestRunner.clearAllCaches = function() {
-  return TestRunner.callFunctionInPageAsync('clearAllCaches');
-};
-
-TestRunner.deprecatedInitAsync(`
-  function onCacheStorageError(e) {
-    console.error('CacheStorage error: ' + e);
-  }
-
-  function createCache(cacheName) {
-    return caches.open(cacheName).catch(onCacheStorageError);
-  }
-
-  function addCacheEntry(cacheName, requestUrl, responseText) {
-    return caches.open(cacheName).then(function(cache) {
-      let request = new Request(requestUrl);
-      let myBlob = new Blob();
-
-      let init = {
-        'status': 200,
-        'statusText': responseText
-      };
-
-      let response = new Response(myBlob, init);
-      return cache.put(request, response);
-    }).catch(onCacheStorageError);
-  }
-
-  function deleteCache(cacheName) {
-    return caches.delete(cacheName).then(function(success) {
-      if (!success)
-        onCacheStorageError('Could not find cache ' + cacheName);
-    }).catch(onCacheStorageError);
-  }
-
-  function deleteCacheEntry(cacheName, requestUrl) {
-    return caches.open(cacheName).then(cache => cache.delete(new Request(requestUrl))).catch(onCacheStorageError);
-  }
-
-  function clearAllCaches() {
-    return caches.keys().then(keys => Promise.all(keys.map(key => caches.delete(key)))).catch(onCacheStorageError.bind(this, undefined));
-  }
-`);
diff --git a/front_end/application_test_runner/IndexedDBTestRunner.js b/front_end/application_test_runner/IndexedDBTestRunner.js
deleted file mode 100644
index 0ab404b..0000000
--- a/front_end/application_test_runner/IndexedDBTestRunner.js
+++ /dev/null
@@ -1,457 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ApplicationTestRunner.dumpIndexedDBTree = function() {
-  TestRunner.addResult('Dumping IndexedDB tree:');
-  const indexedDBTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement;
-
-  if (!indexedDBTreeElement.childCount()) {
-    TestRunner.addResult('    (empty)');
-    return;
-  }
-
-  for (let i = 0; i < indexedDBTreeElement.childCount(); ++i) {
-    const databaseTreeElement = indexedDBTreeElement.childAt(i);
-    TestRunner.addResult('    database: ' + databaseTreeElement.title);
-
-    if (!databaseTreeElement.childCount()) {
-      TestRunner.addResult('        (no object stores)');
-      continue;
-    }
-
-    for (let j = 0; j < databaseTreeElement.childCount(); ++j) {
-      const objectStoreTreeElement = databaseTreeElement.childAt(j);
-      TestRunner.addResult('        Object store: ' + objectStoreTreeElement.title);
-
-      if (!objectStoreTreeElement.childCount()) {
-        TestRunner.addResult('            (no indexes)');
-        continue;
-      }
-
-      for (let k = 0; k < objectStoreTreeElement.childCount(); ++k) {
-        const indexTreeElement = objectStoreTreeElement.childAt(k);
-        TestRunner.addResult('            Index: ' + indexTreeElement.title);
-      }
-    }
-  }
-};
-
-ApplicationTestRunner.dumpObjectStores = function() {
-  TestRunner.addResult('Dumping ObjectStore data:');
-  const idbDatabaseTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement._idbDatabaseTreeElements[0];
-  for (let i = 0; i < idbDatabaseTreeElement.childCount(); ++i) {
-    const objectStoreTreeElement = idbDatabaseTreeElement.childAt(i);
-    objectStoreTreeElement.onselect(false);
-    TestRunner.addResult('    Object store: ' + objectStoreTreeElement.title);
-    const entries = objectStoreTreeElement._view._entries;
-    TestRunner.addResult('            Number of entries: ' + entries.length);
-    for (let j = 0; j < entries.length; ++j)
-      TestRunner.addResult('            Key = ' + entries[j].key._value + ', value = ' + entries[j].value);
-
-    for (let k = 0; k < objectStoreTreeElement.childCount(); ++k) {
-      const indexTreeElement = objectStoreTreeElement.childAt(k);
-      TestRunner.addResult('            Index: ' + indexTreeElement.title);
-      indexTreeElement.onselect(false);
-      const entries = indexTreeElement._view._entries;
-      TestRunner.addResult('                Number of entries: ' + entries.length);
-      for (let j = 0; j < entries.length; ++j)
-        TestRunner.addResult('                Key = ' + entries[j].primaryKey._value + ', value = ' + entries[j].value);
-    }
-  }
-};
-
-let lastCallbackId = 0;
-const callbacks = {};
-const callbackIdPrefix = 'InspectorTest.IndexedDB_callback';
-
-ApplicationTestRunner.evaluateWithCallback = function(frameId, methodName, parameters, callback) {
-  ApplicationTestRunner._installIndexedDBSniffer();
-  const callbackId = ++lastCallbackId;
-  callbacks[callbackId] = callback;
-  let parametersString = 'dispatchCallback.bind(this, "' + callbackIdPrefix + callbackId + '")';
-
-  for (let i = 0; i < parameters.length; ++i)
-    parametersString += ', ' + JSON.stringify(parameters[i]);
-
-  const requestString = methodName + '(' + parametersString + ')';
-  TestRunner.evaluateInPageAnonymously(requestString);
-};
-
-ApplicationTestRunner._installIndexedDBSniffer = function() {
-  ConsoleTestRunner.addConsoleSniffer(consoleMessageOverride, false);
-
-  function consoleMessageOverride(msg) {
-    const text = msg.messageText;
-
-    if (!text.startsWith(callbackIdPrefix)) {
-      ConsoleTestRunner.addConsoleSniffer(consoleMessageOverride, false);
-      return;
-    }
-
-    const callbackId = text.substring(callbackIdPrefix.length);
-    callbacks[callbackId].call();
-    delete callbacks[callbackId];
-  }
-};
-
-ApplicationTestRunner.createDatabase = function(frameId, databaseName, callback) {
-  ApplicationTestRunner.evaluateWithCallback(frameId, 'createDatabase', [databaseName], callback);
-};
-
-ApplicationTestRunner.deleteDatabase = function(frameId, databaseName, callback) {
-  ApplicationTestRunner.evaluateWithCallback(frameId, 'deleteDatabase', [databaseName], callback);
-};
-
-ApplicationTestRunner.createObjectStore = function(
-    frameId, databaseName, objectStoreName, keyPath, autoIncrement, callback) {
-  ApplicationTestRunner.evaluateWithCallback(
-      frameId, 'createObjectStore', [databaseName, objectStoreName, keyPath, autoIncrement], callback);
-};
-
-ApplicationTestRunner.deleteObjectStore = function(frameId, databaseName, objectStoreName, callback) {
-  ApplicationTestRunner.evaluateWithCallback(frameId, 'deleteObjectStore', [databaseName, objectStoreName], callback);
-};
-
-ApplicationTestRunner.createObjectStoreIndex = function(
-    frameId, databaseName, objectStoreName, objectStoreIndexName, keyPath, unique, multiEntry, callback) {
-  ApplicationTestRunner.evaluateWithCallback(
-      frameId, 'createObjectStoreIndex',
-      [databaseName, objectStoreName, objectStoreIndexName, keyPath, unique, multiEntry], callback);
-};
-
-ApplicationTestRunner.deleteObjectStoreIndex = function(
-    frameId, databaseName, objectStoreName, objectStoreIndexName, callback) {
-  ApplicationTestRunner.evaluateWithCallback(
-      frameId, 'deleteObjectStoreIndex', [databaseName, objectStoreName, objectStoreIndexName], callback);
-};
-
-ApplicationTestRunner.addIDBValue = function(frameId, databaseName, objectStoreName, value, key, callback) {
-  ApplicationTestRunner.evaluateWithCallback(
-      frameId, 'addIDBValue', [databaseName, objectStoreName, value, key], callback);
-};
-
-ApplicationTestRunner.createIndexedDBModel = function() {
-  const indexedDBModel = new Resources.IndexedDBModel(SDK.targetManager.mainTarget(), TestRunner.securityOriginManager);
-  indexedDBModel.enable();
-  return indexedDBModel;
-};
-
-ApplicationTestRunner.createDatabaseAsync = function(databaseName) {
-  return TestRunner.evaluateInPageAsync('createDatabaseAsync(\'' + databaseName + '\')');
-};
-
-ApplicationTestRunner.deleteDatabaseAsync = function(databaseName) {
-  return TestRunner.evaluateInPageAsync('deleteDatabaseAsync(\'' + databaseName + '\')');
-};
-
-ApplicationTestRunner.createObjectStoreAsync = function(databaseName, objectStoreName, indexName) {
-  return TestRunner.evaluateInPageAsync(
-      'createObjectStoreAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + indexName + '\')');
-};
-
-ApplicationTestRunner.deleteObjectStoreAsync = function(databaseName, objectStoreName) {
-  return TestRunner.evaluateInPageAsync(
-      'deleteObjectStoreAsync(\'' + databaseName + '\', \'' + objectStoreName + '\')');
-};
-
-ApplicationTestRunner.createObjectStoreIndexAsync = function(databaseName, objectStoreName, indexName) {
-  return TestRunner.evaluateInPageAsync(
-      'createObjectStoreIndexAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + indexName + '\')');
-};
-
-ApplicationTestRunner.deleteObjectStoreIndexAsync = function(databaseName, objectStoreName, indexName) {
-  return TestRunner.evaluateInPageAsync(
-      'deleteObjectStoreIndexAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + indexName + '\')');
-};
-
-ApplicationTestRunner.addIDBValueAsync = function(databaseName, objectStoreName, key, value) {
-  return TestRunner.evaluateInPageAsync(
-      'addIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\', \'' + value + '\')');
-};
-
-ApplicationTestRunner.deleteIDBValueAsync = function(databaseName, objectStoreName, key) {
-  return TestRunner.evaluateInPageAsync(
-      'deleteIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\')');
-};
-
-const __indexedDBHelpers = `
-  function dispatchCallback(callbackId) {
-    console.log(callbackId);
-  }
-
-  function onIndexedDBError(e) {
-    console.error('IndexedDB error: ' + e);
-  }
-
-  function onIndexedDBBlocked(e) {
-    console.error('IndexedDB blocked: ' + e);
-  }
-
-  function doWithDatabase(databaseName, callback) {
-    function innerCallback() {
-      let db = request.result;
-      callback(db);
-    }
-
-    let request = indexedDB.open(databaseName);
-    request.onblocked = onIndexedDBBlocked;
-    request.onerror = onIndexedDBError;
-    request.onsuccess = innerCallback;
-  }
-
-  function doWithVersionTransaction(databaseName, callback, commitCallback) {
-    doWithDatabase(databaseName, step2);
-
-    function step2(db) {
-      let version = db.version;
-      db.close();
-      request = indexedDB.open(databaseName, version + 1);
-      request.onerror = onIndexedDBError;
-      request.onupgradeneeded = onUpgradeNeeded;
-      request.onsuccess = onOpened;
-
-      function onUpgradeNeeded(e) {
-        let db = e.target.result;
-        let trans = e.target.transaction;
-        callback(db, trans);
-      }
-
-      function onOpened(e) {
-        let db = e.target.result;
-        db.close();
-        commitCallback();
-      }
-    }
-  }
-
-  function doWithReadWriteTransaction(databaseName, objectStoreName, callback, commitCallback) {
-    doWithDatabase(databaseName, step2);
-
-    function step2(db) {
-      let transaction = db.transaction([objectStoreName], 'readwrite');
-      let objectStore = transaction.objectStore(objectStoreName);
-      callback(objectStore, innerCommitCallback);
-
-      function innerCommitCallback() {
-        db.close();
-        commitCallback();
-      }
-    }
-  }
-
-  function createDatabase(callback, databaseName) {
-    let request = indexedDB.open(databaseName);
-    request.onerror = onIndexedDBError;
-    request.onsuccess = closeDatabase;
-
-    function closeDatabase() {
-      request.result.close();
-      callback();
-    }
-  }
-
-  function deleteDatabase(callback, databaseName) {
-    let request = indexedDB.deleteDatabase(databaseName);
-    request.onerror = onIndexedDBError;
-    request.onsuccess = callback;
-  }
-
-  function createObjectStore(callback, databaseName, objectStoreName, keyPath, autoIncrement) {
-    doWithVersionTransaction(databaseName, withTransactionCallback, callback);
-
-    function withTransactionCallback(db, transaction) {
-      let store = db.createObjectStore(objectStoreName, {
-        keyPath: keyPath,
-        autoIncrement: autoIncrement
-      });
-    }
-  }
-
-  function deleteObjectStore(callback, databaseName, objectStoreName) {
-    doWithVersionTransaction(databaseName, withTransactionCallback, callback);
-
-    function withTransactionCallback(db, transaction) {
-      let store = db.deleteObjectStore(objectStoreName);
-    }
-  }
-
-  function createObjectStoreIndex(callback, databaseName, objectStoreName, objectStoreIndexName, keyPath, unique, multiEntry) {
-    doWithVersionTransaction(databaseName, withTransactionCallback, callback);
-
-    function withTransactionCallback(db, transaction) {
-      let objectStore = transaction.objectStore(objectStoreName);
-
-      objectStore.createIndex(objectStoreIndexName, keyPath, {
-        unique: unique,
-        multiEntry: multiEntry
-      });
-    }
-  }
-
-  function deleteObjectStoreIndex(callback, databaseName, objectStoreName, objectStoreIndexName) {
-    doWithVersionTransaction(databaseName, withTransactionCallback, callback);
-
-    function withTransactionCallback(db, transaction) {
-      let objectStore = transaction.objectStore(objectStoreName);
-      objectStore.deleteIndex(objectStoreIndexName);
-    }
-  }
-
-  function addIDBValue(callback, databaseName, objectStoreName, value, key) {
-    doWithReadWriteTransaction(databaseName, objectStoreName, withTransactionCallback, callback);
-
-    function withTransactionCallback(objectStore, commitCallback) {
-      let request;
-
-      if (key)
-        request = objectStore.add(value, key);
-      else
-        request = objectStore.add(value);
-
-      request.onerror = onIndexedDBError;
-      request.onsuccess = commitCallback;
-    }
-  }
-
-  function createDatabaseAsync(databaseName) {
-    return new Promise((resolve) => {
-      createDatabase(resolve, databaseName);
-    });
-  }
-
-  function upgradeRequestAsync(databaseName, onUpgradeNeeded, callback) {
-    let request = indexedDB.open(databaseName);
-    request.onerror = onIndexedDBError;
-    request.onsuccess = function(event) {
-      let db = request.result;
-      let version = db.version;
-      db.close();
-
-      let upgradeRequest = indexedDB.open(databaseName, version + 1);
-      upgradeRequest.onerror = onIndexedDBError;
-      upgradeRequest.onupgradeneeded = function(e) {
-        onUpgradeNeeded(e.target.result, e.target.transaction, callback);
-      }
-      upgradeRequest.onsuccess = function(e) {
-        let upgradeDb = e.target.result;
-        upgradeDb.close();
-        callback();
-      }
-    }
-  }
-
-  function deleteDatabaseAsync(databaseName) {
-    let callback;
-    let promise = new Promise((fulfill) => callback = fulfill);
-    let request = indexedDB.deleteDatabase(databaseName);
-    request.onerror = onIndexedDBError;
-    request.onsuccess = callback;
-    return promise;
-  }
-
-  function createObjectStoreAsync(databaseName, objectStoreName, indexName) {
-    let callback;
-    let promise = new Promise((fulfill) => callback = fulfill);
-    let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
-      let store = upgradeDb.createObjectStore(objectStoreName, { keyPath: "test", autoIncrement: false });
-      store.createIndex(indexName, "test", { unique: false, multiEntry: false });
-      callback();
-    }
-    upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
-    return promise;
-  }
-
-  function deleteObjectStoreAsync(databaseName, objectStoreName) {
-    let callback;
-    let promise = new Promise((fulfill) => callback = fulfill);
-    let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
-      upgradeDb.deleteObjectStore(objectStoreName);
-      callback();
-    }
-    upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
-    return promise;
-  }
-
-  function createObjectStoreIndexAsync(databaseName, objectStoreName, indexName) {
-    let callback;
-    let promise = new Promise((fulfill) => callback = fulfill);
-    let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
-      let store = transaction.objectStore(objectStoreName);
-      store.createIndex(indexName, "test", { unique: false, multiEntry: false });
-      callback();
-    }
-    upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
-    return promise;
-  }
-
-  function deleteObjectStoreIndexAsync(databaseName, objectStoreName, indexName) {
-    let callback;
-    let promise = new Promise((fulfill) => callback = fulfill);
-    let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
-      let store = transaction.objectStore(objectStoreName);
-      store.deleteIndex(indexName);
-      callback();
-    }
-    upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
-    return promise;
-  }
-
-  function addIDBValueAsync(databaseName, objectStoreName, key, value) {
-    let callback;
-    let promise = new Promise(fulfill => callback = fulfill);
-    let request = indexedDB.open(databaseName);
-    request.onerror = onIndexedDBError;
-
-    request.onsuccess = function(event) {
-      let db = request.result;
-      let transaction = db.transaction(objectStoreName, 'readwrite');
-      let store = transaction.objectStore(objectStoreName);
-
-      store.put({
-        test: key,
-        testValue: value
-      });
-
-      transaction.onerror = onIndexedDBError;
-
-      transaction.oncomplete = function() {
-        db.close();
-        callback();
-      };
-    };
-
-    return promise;
-  }
-
-  function deleteIDBValueAsync(databaseName, objectStoreName, key) {
-    let callback;
-    let promise = new Promise((fulfill) => callback = fulfill);
-    let request = indexedDB.open(databaseName);
-    request.onerror = onIndexedDBError;
-    request.onsuccess = function(event) {
-      let db = request.result;
-      let transaction = db.transaction(objectStoreName, "readwrite");
-      let store = transaction.objectStore(objectStoreName);
-      store.delete(key);
-
-      transaction.onerror = onIndexedDBError;
-      transaction.oncomplete = function() {
-        db.close();
-        callback();
-      };
-    }
-    return promise;
-  }
-`;
-
-ApplicationTestRunner.setupIndexedDBHelpers = function() {
-  return TestRunner.evaluateInPagePromise(__indexedDBHelpers);
-};
-
-TestRunner.deprecatedInitAsync(__indexedDBHelpers);
diff --git a/front_end/application_test_runner/ResourceTreeTestRunner.js b/front_end/application_test_runner/ResourceTreeTestRunner.js
deleted file mode 100644
index 9a13b23..0000000
--- a/front_end/application_test_runner/ResourceTreeTestRunner.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ApplicationTestRunner.dumpResources = function(formatter) {
-  const results = [];
-
-  function formatterWrapper(resource) {
-    if (formatter)
-      results.push({resource: resource, text: formatter(resource)});
-    else
-      results.push({resource: resource, text: resource.url});
-  }
-
-  TestRunner.resourceTreeModel.forAllResources(formatterWrapper);
-
-  function comparator(result1, result2) {
-    return result1.resource.url.localeCompare(result2.resource.url);
-  }
-
-  results.sort(comparator);
-
-  for (let i = 0; i < results.length; ++i)
-    TestRunner.addResult(results[i].text);
-};
-
-ApplicationTestRunner.dumpResourcesURLMap = function() {
-  const results = [];
-  TestRunner.resourceTreeModel.forAllResources(collect);
-
-  function collect(resource) {
-    results.push({url: resource.url, resource: TestRunner.resourceTreeModel.resourceForURL(resource.url)});
-  }
-
-  function comparator(result1, result2) {
-    if (result1.url > result2.url)
-      return 1;
-
-    if (result2.url > result1.url)
-      return -1;
-
-    return 0;
-  }
-
-  results.sort(comparator);
-
-  for (let i = 0; i < results.length; ++i)
-    TestRunner.addResult(results[i].url + ' == ' + results[i].resource.url);
-};
-
-ApplicationTestRunner.dumpResourcesTree = function() {
-  function dump(treeItem, prefix) {
-    if (typeof treeItem._resetBubble === 'function')
-      treeItem._resetBubble();
-
-    TestRunner.addResult(prefix + treeItem.listItemElement.textContent);
-    treeItem.expand();
-    const children = treeItem.children();
-
-    for (let i = 0; children && i < children.length; ++i)
-      dump(children[i], prefix + '    ');
-  }
-
-  dump(UI.panels.resources._sidebar._resourcesSection._treeElement, '');
-
-  if (!ApplicationTestRunner._testSourceNavigator) {
-    ApplicationTestRunner._testSourceNavigator = new Sources.NetworkNavigatorView();
-    ApplicationTestRunner._testSourceNavigator.show(UI.inspectorView.element);
-  }
-
-  SourcesTestRunner.dumpNavigatorViewInAllModes(ApplicationTestRunner._testSourceNavigator);
-};
-
-ApplicationTestRunner.dumpResourceTreeEverything = function() {
-  function format(resource) {
-    return resource.resourceType().name() + ' ' + resource.url;
-  }
-
-  TestRunner.addResult('Resources:');
-  ApplicationTestRunner.dumpResources(format);
-  TestRunner.addResult('');
-  TestRunner.addResult('Resources URL Map:');
-  ApplicationTestRunner.dumpResourcesURLMap();
-  TestRunner.addResult('');
-  TestRunner.addResult('Resources Tree:');
-  ApplicationTestRunner.dumpResourcesTree();
-};
diff --git a/front_end/application_test_runner/ResourcesTestRunner.js b/front_end/application_test_runner/ResourcesTestRunner.js
deleted file mode 100644
index 1d58e18..0000000
--- a/front_end/application_test_runner/ResourcesTestRunner.js
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-/**
- * Many application panel tests are flaky because storage state (e.g. IndexedDB)
- * doesn't get reset between tests.
- */
-ApplicationTestRunner.resetState = async function() {
-  const securityOrigin = new Common.ParsedURL(TestRunner.url()).securityOrigin();
-  const storageTypes =
-      ['appcache', 'cache_storage', 'cookies', 'indexeddb', 'local_storage', 'service_workers', 'websql'];
-  await TestRunner.mainTarget.storageAgent().clearDataForOrigin(securityOrigin, storageTypes.join(','));
-};
-
-ApplicationTestRunner.createWebSQLDatabase = function(name) {
-  return TestRunner.evaluateInPageAsync(`_openWebSQLDatabase("${name}")`);
-};
-
-ApplicationTestRunner.requestURLComparer = function(r1, r2) {
-  return r1.request.url.localeCompare(r2.request.url);
-};
-
-ApplicationTestRunner.runAfterCachedResourcesProcessed = function(callback) {
-  if (!TestRunner.resourceTreeModel._cachedResourcesProcessed)
-    TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, callback);
-  else
-    callback();
-};
-
-ApplicationTestRunner.runAfterResourcesAreFinished = function(resourceURLs, callback) {
-  const resourceURLsMap = new Set(resourceURLs);
-
-  function checkResources() {
-    for (const url of resourceURLsMap) {
-      const resource = ApplicationTestRunner.resourceMatchingURL(url);
-
-      if (resource)
-        resourceURLsMap.delete(url);
-    }
-
-    if (!resourceURLsMap.size) {
-      TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.ResourceAdded, checkResources);
-      callback();
-    }
-  }
-
-  checkResources();
-
-  if (resourceURLsMap.size)
-    TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.ResourceAdded, checkResources);
-};
-
-ApplicationTestRunner.showResource = function(resourceURL, callback) {
-  let reported = false;
-
-  function callbackWrapper(sourceFrame) {
-    if (reported)
-      return;
-
-    callback(sourceFrame);
-    reported = true;
-  }
-
-  function showResourceCallback() {
-    const resource = ApplicationTestRunner.resourceMatchingURL(resourceURL);
-
-    if (!resource)
-      return;
-
-    UI.panels.resources.showResource(resource, 1);
-    const sourceFrame = UI.panels.resources._resourceViewForResource(resource);
-
-    if (sourceFrame.loaded)
-      callbackWrapper(sourceFrame);
-    else
-      TestRunner.addSniffer(sourceFrame, 'onTextEditorContentSet', callbackWrapper.bind(null, sourceFrame));
-  }
-
-  ApplicationTestRunner.runAfterResourcesAreFinished([resourceURL], showResourceCallback);
-};
-
-ApplicationTestRunner.resourceMatchingURL = function(resourceURL) {
-  let result = null;
-  TestRunner.resourceTreeModel.forAllResources(visit);
-
-  function visit(resource) {
-    if (resource.url.indexOf(resourceURL) !== -1) {
-      result = resource;
-      return true;
-    }
-  }
-
-  return result;
-};
-
-ApplicationTestRunner.waitForCookies = function() {
-  return new Promise(resolve => {
-    TestRunner.addSniffer(CookieTable.CookiesTable.prototype, '_rebuildTable', resolve);
-  });
-};
-
-ApplicationTestRunner.dumpCookieDomains = function() {
-  const cookieListChildren = UI.panels.resources._sidebar.cookieListTreeElement.children();
-  TestRunner.addResult('Available cookie domains:');
-  for (const child of cookieListChildren)
-    TestRunner.addResult(child._cookieDomain);
-};
-
-ApplicationTestRunner.dumpCookies = function() {
-  if (!UI.panels.resources._cookieView || !UI.panels.resources._cookieView.isShowing()) {
-    TestRunner.addResult('No cookies visible');
-    return;
-  }
-
-  TestRunner.addResult('Visible cookies');
-  for (const item of UI.panels.resources._cookieView._cookiesTable._data) {
-    const cookies = item.cookies || [];
-    for (const cookie of cookies)
-      TestRunner.addResult(`${cookie.name()}=${cookie.value()}`);
-  }
-};
-
-ApplicationTestRunner.databaseModel = function() {
-  return TestRunner.mainTarget.model(Resources.DatabaseModel);
-};
-
-ApplicationTestRunner.domStorageModel = function() {
-  return TestRunner.mainTarget.model(Resources.DOMStorageModel);
-};
-
-ApplicationTestRunner.indexedDBModel = function() {
-  return TestRunner.mainTarget.model(Resources.IndexedDBModel);
-};
-
-TestRunner.deprecatedInitAsync(`
-  function _openWebSQLDatabase(name) {
-    return new Promise(resolve => openDatabase(name, '1.0', '', 1024 * 1024, resolve));
-  }
-`);
diff --git a/front_end/application_test_runner/ServiceWorkersTestRunner.js b/front_end/application_test_runner/ServiceWorkersTestRunner.js
deleted file mode 100644
index b7f4d2f..0000000
--- a/front_end/application_test_runner/ServiceWorkersTestRunner.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ApplicationTestRunner.registerServiceWorker = function(script, scope) {
-  return TestRunner.callFunctionInPageAsync('registerServiceWorker', [script, scope]);
-};
-
-ApplicationTestRunner.waitForActivated = function(scope) {
-  return TestRunner.callFunctionInPageAsync('waitForActivated', [scope]);
-};
-
-ApplicationTestRunner.unregisterServiceWorker = function(scope) {
-  return TestRunner.callFunctionInPageAsync('unregisterServiceWorker', [scope]);
-};
-
-ApplicationTestRunner.postToServiceWorker = function(scope, message) {
-  return TestRunner.evaluateInPageAnonymously('postToServiceWorker("' + scope + '","' + message + '")');
-};
-
-ApplicationTestRunner.waitForServiceWorker = function(callback) {
-  function isRightTarget(target) {
-    return TestRunner.isDedicatedWorker(target) && TestRunner.isServiceWorker(target.parentTarget());
-  }
-
-  SDK.targetManager.observeTargets({
-    targetAdded: function(target) {
-      if (isRightTarget(target) && callback) {
-        setTimeout(callback.bind(null, target), 0);
-        callback = null;
-      }
-    },
-
-    targetRemoved: function(target) {}
-  });
-};
-
-ApplicationTestRunner.dumpServiceWorkersView = function() {
-  const swView = UI.panels.resources.visibleView;
-
-  return swView._currentWorkersView._sectionList.childTextNodes()
-      .concat(swView._otherWorkersView._sectionList.childTextNodes())
-      .map(function(node) {
-        return node.textContent.replace(/Received.*/, 'Received').replace(/#\d+/, '#N');
-      })
-      .join('\n');
-};
-
-ApplicationTestRunner.deleteServiceWorkerRegistration = function(scope) {
-  TestRunner.serviceWorkerManager.registrations().valuesArray().map(function(registration) {
-    if (registration.scopeURL === scope)
-      TestRunner.serviceWorkerManager.deleteRegistration(registration.id);
-  });
-};
-
-ApplicationTestRunner.makeFetchInServiceWorker = function(scope, url, requestInitializer, callback) {
-  TestRunner.callFunctionInPageAsync('makeFetchInServiceWorker', [scope, url, requestInitializer]).then(callback);
-};
-
-TestRunner.deprecatedInitAsync(`
-  let registrations = {};
-
-  function registerServiceWorker(script, scope) {
-    return navigator.serviceWorker.register(script, {
-      scope: scope
-    })
-    .then(reg => registrations[scope] = reg)
-    .catch(err => {
-      return Promise.reject(new Error('Service Worker registration error: ' +
-                                      err.toString()));
-    });
-  }
-
-  function waitForActivated(scope) {
-    let reg = registrations[scope];
-    if (!reg)
-      return Promise.reject(new Error('The registration'));
-    let worker = reg.installing || reg.waiting || reg.active;
-    if (worker.state === 'activated')
-      return Promise.resolve();
-    if (worker.state === 'redundant')
-      return Promise.reject(new Error('The worker is redundant'));
-    return new Promise(resolve => {
-        worker.addEventListener('statechange', () => {
-            if (worker.state === 'activated')
-              resolve();
-          });
-      });
-  }
-
-  function postToServiceWorker(scope, message) {
-    registrations[scope].active.postMessage(message);
-  }
-
-  function unregisterServiceWorker(scope) {
-    let registration = registrations[scope];
-
-    if (!registration)
-      return Promise.reject('ServiceWorker for ' + scope + ' is not registered');
-
-    return registration.unregister().then(() => delete registrations[scope]);
-  }
-
-  function makeFetchInServiceWorker(scope, url, requestInitializer) {
-    let script = 'resources/network-fetch-worker.js';
-
-    return navigator.serviceWorker.register(script, {
-      scope: scope
-    }).then(registration => {
-      let worker = registration.installing;
-
-      return new Promise(resolve => {
-        navigator.serviceWorker.onmessage = e => {
-          resolve(e.data);
-        };
-
-        worker.postMessage({
-          url: url,
-          init: requestInitializer
-        });
-      });
-    });
-  }
-`);
diff --git a/front_end/application_test_runner/module.json b/front_end/application_test_runner/module.json
deleted file mode 100644
index fffab05..0000000
--- a/front_end/application_test_runner/module.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "resources",
-    "console_test_runner",
-    "sources",
-    "sources_test_runner"
-  ],
-  "scripts": [
-    "AppcacheTestRunner.js",
-    "CacheStorageTestRunner.js",
-    "IndexedDBTestRunner.js",
-    "ResourceTreeTestRunner.js",
-    "ResourcesTestRunner.js",
-    "ServiceWorkersTestRunner.js"
-  ],
-  "skip_compilation": [
-    "AppcacheTestRunner.js",
-    "CacheStorageTestRunner.js",
-    "IndexedDBTestRunner.js",
-    "ResourceTreeTestRunner.js",
-    "ResourcesTestRunner.js",
-    "ServiceWorkersTestRunner.js"
-  ]
-}
diff --git a/front_end/audits2/Audits2Dialog.js b/front_end/audits2/Audits2Dialog.js
deleted file mode 100644
index ecee4da..0000000
--- a/front_end/audits2/Audits2Dialog.js
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Audits2.Audits2Dialog = class {
-  constructor(onAuditComplete, protocolService) {
-    this._onAuditComplete = onAuditComplete;
-    this._protocolService = protocolService;
-    this._protocolService.registerStatusCallback(msg => this._updateStatus(Common.UIString(msg)));
-  }
-
-  /**
-   * @param {!Element} dialogRenderElement
-   */
-  render(dialogRenderElement) {
-    this._dialog = new UI.Dialog();
-    this._dialog.setOutsideClickCallback(event => event.consume(true));
-    const root = UI.createShadowRootWithCoreStyles(this._dialog.contentElement, 'audits2/audits2Dialog.css');
-    const auditsViewElement = root.createChild('div', 'audits2-view vbox');
-
-    const closeButton = auditsViewElement.createChild('div', 'dialog-close-button', 'dt-close-button');
-    closeButton.addEventListener('click', () => this._cancelAndClose());
-
-    const uiElement = auditsViewElement.createChild('div', 'vbox launcher-container');
-    const headerElement = uiElement.createChild('header');
-    this._headerTitleElement = headerElement.createChild('p');
-    this._headerTitleElement.textContent = Common.UIString('Audits to perform');
-    uiElement.appendChild(headerElement);
-
-    this._auditSelectorForm = uiElement.createChild('form', 'audits2-form');
-
-    for (const preset of Audits2.Audits2Panel.Presets) {
-      preset.setting.setTitle(preset.title);
-      const checkbox = new UI.ToolbarSettingCheckbox(preset.setting);
-      const row = this._auditSelectorForm.createChild('div', 'vbox audits2-launcher-row');
-      row.appendChild(checkbox.element);
-      row.createChild('span', 'audits2-launcher-description dimmed').textContent = preset.description;
-    }
-
-    this._statusView = new Audits2.Audits2StatusView();
-    this._statusView.render(uiElement);
-    this._dialogHelpText = uiElement.createChild('div', 'audits2-dialog-help-text');
-
-    const buttonsRow = uiElement.createChild('div', 'audits2-dialog-buttons hbox');
-    this._startButton =
-        UI.createTextButton(Common.UIString('Run audit'), this._start.bind(this), '', true /* primary */);
-    buttonsRow.appendChild(this._startButton);
-    this._cancelButton = UI.createTextButton(Common.UIString('Cancel'), this._cancel.bind(this));
-    buttonsRow.appendChild(this._cancelButton);
-
-    auditsViewElement.tabIndex = 0;
-    this._dialog.setDefaultFocusedElement(this._startButton);
-    this._dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.SetExactWidthMaxHeight);
-    this._dialog.setMaxContentSize(new UI.Size(500, 400));
-    this._dialog.show(dialogRenderElement);
-  }
-
-  hide() {
-    if (!this._dialog)
-      return;
-
-    this._dialog.hide();
-
-    delete this._dialog;
-    delete this._statusView;
-    delete this._startButton;
-    delete this._cancelButton;
-    delete this._auditSelectorForm;
-    delete this._headerTitleElement;
-    delete this._emulationEnabledBefore;
-    delete this._emulationOutlineEnabledBefore;
-  }
-
-  /**
-   * @param {boolean} isEnabled
-   */
-  setStartEnabled(isEnabled) {
-    if (this._dialogHelpText)
-      this._dialogHelpText.classList.toggle('hidden', isEnabled);
-
-    if (this._startButton)
-      this._startButton.disabled = !isEnabled;
-  }
-
-  /**
-   * @param {string} text
-   */
-  setHelpText(text) {
-    if (this._dialogHelpText)
-      this._dialogHelpText.textContent = text;
-  }
-
-  /**
-   * @param {string} message
-   */
-  _updateStatus(message) {
-    if (!this._statusView)
-      return;
-    this._statusView.updateStatus(message);
-  }
-
-  _cancelAndClose() {
-    this._cancel();
-    this.hide();
-  }
-
-  async _cancel() {
-    if (this._auditRunning) {
-      this._updateStatus(Common.UIString('Cancelling\u2026'));
-      await this._stopAndReattach();
-
-      if (this._statusView)
-        this._statusView.reset();
-    } else {
-      this.hide();
-    }
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  _getInspectedURL() {
-    const mainTarget = SDK.targetManager.mainTarget();
-    const runtimeModel = mainTarget.model(SDK.RuntimeModel);
-    const executionContext = runtimeModel && runtimeModel.defaultExecutionContext();
-    let inspectedURL = mainTarget.inspectedURL();
-    if (!executionContext)
-      return Promise.resolve(inspectedURL);
-
-    // Evaluate location.href for a more specific URL than inspectedURL provides so that SPA hash navigation routes
-    // will be respected and audited.
-    return executionContext
-        .evaluate(
-            {
-              expression: 'window.location.href',
-              objectGroup: 'audits',
-              includeCommandLineAPI: false,
-              silent: false,
-              returnByValue: true,
-              generatePreview: false
-            },
-            /* userGesture */ false, /* awaitPromise */ false)
-        .then(result => {
-          if (!result.exceptionDetails && result.object) {
-            inspectedURL = result.object.value;
-            result.object.release();
-          }
-
-          return inspectedURL;
-        });
-  }
-
-  /**
-   * @return {!Object}
-   */
-  _getFlags() {
-    const flags = {};
-    for (const runtimeSetting of Audits2.Audits2Panel.RuntimeSettings)
-      runtimeSetting.setFlags(flags, runtimeSetting.setting.get());
-    return flags;
-  }
-
-  async _start() {
-    const flags = this._getFlags();
-
-    const emulationModel = self.singleton(Emulation.DeviceModeModel);
-    this._emulationEnabledBefore = emulationModel.enabledSetting().get();
-    this._emulationOutlineEnabledBefore = emulationModel.deviceOutlineSetting().get();
-    emulationModel.toolbarControlsEnabledSetting().set(false);
-
-    if (flags.disableDeviceEmulation) {
-      emulationModel.enabledSetting().set(false);
-      emulationModel.deviceOutlineSetting().set(false);
-      emulationModel.emulate(Emulation.DeviceModeModel.Type.None, null, null);
-    } else {
-      emulationModel.enabledSetting().set(true);
-      emulationModel.deviceOutlineSetting().set(true);
-
-      for (const device of Emulation.EmulatedDevicesList.instance().standard()) {
-        if (device.title === 'Nexus 5X')
-          emulationModel.emulate(Emulation.DeviceModeModel.Type.Device, device, device.modes[0], 1);
-      }
-    }
-
-    this._dialog.setCloseOnEscape(false);
-
-    const categoryIDs = [];
-    for (const preset of Audits2.Audits2Panel.Presets) {
-      if (preset.setting.get())
-        categoryIDs.push(preset.configID);
-    }
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.Audits2Started);
-
-    try {
-      this._auditURL = await this._getInspectedURL();
-      await this._protocolService.attach();
-
-      this._auditRunning = true;
-      this._updateButton(this._auditURL);
-      this._updateStatus(Common.UIString('Loading\u2026'));
-
-      const lighthouseResult = await this._protocolService.startLighthouse(this._auditURL, categoryIDs, flags);
-      if (lighthouseResult && lighthouseResult.fatal) {
-        const error = new Error(lighthouseResult.message);
-        error.stack = lighthouseResult.stack;
-        throw error;
-      }
-
-      if (!lighthouseResult)
-        throw new Error('Auditing failed to produce a result');
-
-      await this._stopAndReattach();
-      await this._onAuditComplete(lighthouseResult);
-    } catch (err) {
-      if (err instanceof Error)
-        this._statusView.renderBugReport(err, this._auditURL);
-    }
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  async _stopAndReattach() {
-    await this._protocolService.detach();
-
-    const emulationModel = self.singleton(Emulation.DeviceModeModel);
-    emulationModel.enabledSetting().set(this._emulationEnabledBefore);
-    emulationModel.deviceOutlineSetting().set(this._emulationOutlineEnabledBefore);
-    emulationModel.toolbarControlsEnabledSetting().set(true);
-    Emulation.InspectedPagePlaceholder.instance().update(true);
-
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.Audits2Finished);
-    const resourceTreeModel = SDK.targetManager.mainTarget().model(SDK.ResourceTreeModel);
-    // reload to reset the page state
-    await resourceTreeModel.navigate(this._auditURL);
-    this._auditRunning = false;
-    this._updateButton(this._auditURL);
-  }
-
-  /**
-   * @param {string} auditURL
-   */
-  _updateButton(auditURL) {
-    if (!this._dialog)
-      return;
-    this._startButton.classList.toggle('hidden', this._auditRunning);
-    this._startButton.disabled = this._auditRunning;
-    this._statusView.setVisible(this._auditRunning);
-    this._auditSelectorForm.classList.toggle('hidden', this._auditRunning);
-    if (this._auditRunning) {
-      const parsedURL = (auditURL || '').asParsedURL();
-      const pageHost = parsedURL && parsedURL.host;
-      this._headerTitleElement.textContent =
-          pageHost ? ls`Auditing ${pageHost}\u2026` : ls`Auditing your web page\u2026`;
-    } else {
-      this._headerTitleElement.textContent = Common.UIString('Audits to perform');
-    }
-  }
-};
diff --git a/front_end/audits2/Audits2Panel.js b/front_end/audits2/Audits2Panel.js
deleted file mode 100644
index 7aea16d..0000000
--- a/front_end/audits2/Audits2Panel.js
+++ /dev/null
@@ -1,638 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.ServiceWorkerManager>}
- * @unrestricted
- */
-Audits2.Audits2Panel = class extends UI.Panel {
-  constructor() {
-    super('audits2');
-    this.registerRequiredCSS('audits2/lighthouse/report-styles.css');
-    this.registerRequiredCSS('audits2/audits2Panel.css');
-
-    this._protocolService = new Audits2.ProtocolService();
-
-    this._renderToolbar();
-
-    this._auditResultsElement = this.contentElement.createChild('div', 'audits2-results-container');
-    this._dropTarget = new UI.DropTarget(
-        this.contentElement, [UI.DropTarget.Type.File], Common.UIString('Drop audit file here'),
-        this._handleDrop.bind(this));
-
-    for (const preset of Audits2.Audits2Panel.Presets)
-      preset.setting.addChangeListener(this._refreshDialogUI.bind(this));
-
-    this._showLandingPage();
-    SDK.targetManager.observeModels(SDK.ServiceWorkerManager, this);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._refreshDialogUI, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ServiceWorkerManager} serviceWorkerManager
-   */
-  modelAdded(serviceWorkerManager) {
-    if (this._manager)
-      return;
-
-    this._manager = serviceWorkerManager;
-    this._serviceWorkerListeners = [
-      this._manager.addEventListener(SDK.ServiceWorkerManager.Events.RegistrationUpdated, this._refreshDialogUI, this),
-      this._manager.addEventListener(SDK.ServiceWorkerManager.Events.RegistrationDeleted, this._refreshDialogUI, this),
-    ];
-
-    this._refreshDialogUI();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ServiceWorkerManager} serviceWorkerManager
-   */
-  modelRemoved(serviceWorkerManager) {
-    if (!this._manager || this._manager !== serviceWorkerManager)
-      return;
-
-    Common.EventTarget.removeEventListeners(this._serviceWorkerListeners);
-    this._manager = null;
-    this._serviceWorkerListeners = null;
-    this._refreshDialogUI();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _hasActiveServiceWorker() {
-    if (!this._manager)
-      return false;
-
-    const mainTarget = SDK.targetManager.mainTarget();
-    if (!mainTarget)
-      return false;
-
-    const inspectedURL = mainTarget.inspectedURL().asParsedURL();
-    const inspectedOrigin = inspectedURL && inspectedURL.securityOrigin();
-    for (const registration of this._manager.registrations().values()) {
-      if (registration.securityOrigin !== inspectedOrigin)
-        continue;
-
-      for (const version of registration.versions.values()) {
-        if (version.controlledClients.length > 1)
-          return true;
-      }
-    }
-
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _hasAtLeastOneCategory() {
-    return Audits2.Audits2Panel.Presets.some(preset => preset.setting.get());
-  }
-
-  /**
-   * @return {?string}
-   */
-  _unauditablePageMessage() {
-    if (!this._manager)
-      return null;
-
-    const mainTarget = SDK.targetManager.mainTarget();
-    const inspectedURL = mainTarget && mainTarget.inspectedURL();
-    if (inspectedURL && !/^(http|chrome-extension)/.test(inspectedURL)) {
-      return Common.UIString(
-          'Can only audit HTTP/HTTPS pages and Chrome extensions. ' +
-          'Navigate to a different page to start an audit.');
-    }
-
-    // Audits don't work on most undockable targets (extension popup pages, remote debugging, etc).
-    // However, the tests run in a content shell which is not dockable yet audits just fine,
-    // so disable this check when under test.
-    if (!Host.isUnderTest() && !Runtime.queryParam('can_dock'))
-      return Common.UIString('Can only audit tabs. Navigate to this page in a separate tab to start an audit.');
-
-    return null;
-  }
-
-  _refreshDialogUI() {
-    if (!this._dialog)
-      return;
-
-    const hasActiveServiceWorker = this._hasActiveServiceWorker();
-    const hasAtLeastOneCategory = this._hasAtLeastOneCategory();
-    const unauditablePageMessage = this._unauditablePageMessage();
-    const isDisabled = hasActiveServiceWorker || !hasAtLeastOneCategory || !!unauditablePageMessage;
-
-    let helpText = '';
-    if (hasActiveServiceWorker) {
-      helpText = Common.UIString(
-          'Multiple tabs are being controlled by the same service worker. ' +
-          'Close your other tabs on the same origin to audit this page.');
-    } else if (!hasAtLeastOneCategory) {
-      helpText = Common.UIString('At least one category must be selected.');
-    } else if (unauditablePageMessage) {
-      helpText = unauditablePageMessage;
-    }
-
-    this._dialog.setHelpText(helpText);
-    this._dialog.setStartEnabled(!isDisabled);
-  }
-
-  _refreshToolbarUI() {
-    this._downloadButton.setEnabled(this._reportSelector.hasCurrentSelection());
-    this._clearButton.setEnabled(this._reportSelector.hasItems());
-  }
-
-  _clearAll() {
-    this._reportSelector.clearAll();
-    this._showLandingPage();
-    this._refreshToolbarUI();
-  }
-
-  _downloadSelected() {
-    this._reportSelector.downloadSelected();
-  }
-
-  _renderToolbar() {
-    const toolbar = new UI.Toolbar('', this.element);
-
-    this._newButton = new UI.ToolbarButton(Common.UIString('Perform an audit\u2026'), 'largeicon-add');
-    toolbar.appendToolbarItem(this._newButton);
-    this._newButton.addEventListener(UI.ToolbarButton.Events.Click, this._showDialog.bind(this));
-
-    this._downloadButton = new UI.ToolbarButton(Common.UIString('Download report'), 'largeicon-download');
-    toolbar.appendToolbarItem(this._downloadButton);
-    this._downloadButton.addEventListener(UI.ToolbarButton.Events.Click, this._downloadSelected.bind(this));
-
-    toolbar.appendSeparator();
-
-    this._reportSelector = new Audits2.ReportSelector();
-    toolbar.appendToolbarItem(this._reportSelector.comboBox());
-
-    this._clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largeicon-clear');
-    toolbar.appendToolbarItem(this._clearButton);
-    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearAll.bind(this));
-
-    toolbar.appendSeparator();
-
-    toolbar.appendText(ls`Emulation: `);
-    for (const runtimeSetting of Audits2.Audits2Panel.RuntimeSettings) {
-      const control = new UI.ToolbarSettingComboBox(runtimeSetting.options, runtimeSetting.setting);
-      control.element.title = runtimeSetting.description;
-      toolbar.appendToolbarItem(control);
-    }
-
-    this._refreshToolbarUI();
-  }
-
-  _showLandingPage() {
-    if (this._reportSelector.hasCurrentSelection())
-      return;
-
-    this._auditResultsElement.removeChildren();
-    const landingPage = this._auditResultsElement.createChild('div', 'vbox audits2-landing-page');
-    const landingCenter = landingPage.createChild('div', 'vbox audits2-landing-center');
-    landingCenter.createChild('div', 'audits2-logo');
-    const text = landingCenter.createChild('div', 'audits2-landing-text');
-    text.createChild('span', 'audits2-landing-bold-text').textContent = Common.UIString('Audits');
-    text.createChild('span').textContent = Common.UIString(
-        ' help you identify and fix common problems that affect' +
-        ' your site\'s performance, accessibility, and user experience. ');
-    const link = text.createChild('span', 'link');
-    link.textContent = Common.UIString('Learn more');
-    link.addEventListener(
-        'click', () => InspectorFrontendHost.openInNewTab('https://developers.google.com/web/tools/lighthouse/'));
-
-    const newButton = UI.createTextButton(
-        Common.UIString('Perform an audit\u2026'), this._showDialog.bind(this), '', true /* primary */);
-    landingCenter.appendChild(newButton);
-    this.setDefaultFocusedElement(newButton);
-    this._refreshToolbarUI();
-  }
-
-  _showDialog() {
-    this._dialog = new Audits2.Audits2Dialog(result => this._buildReportUI(result), this._protocolService);
-    this._dialog.render(this._auditResultsElement);
-    this._refreshDialogUI();
-  }
-
-  _hideDialog() {
-    if (!this._dialog)
-      return;
-
-    this._dialog.hide();
-    delete this._dialog;
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} lighthouseResult
-   */
-  _buildReportUI(lighthouseResult) {
-    if (lighthouseResult === null)
-      return;
-
-    const optionElement =
-        new Audits2.ReportSelector.Item(lighthouseResult, this._auditResultsElement, this._showLandingPage.bind(this));
-    this._reportSelector.prepend(optionElement);
-    this._hideDialog();
-    this._refreshToolbarUI();
-  }
-
-  /**
-   * @param {!DataTransfer} dataTransfer
-   */
-  _handleDrop(dataTransfer) {
-    const items = dataTransfer.items;
-    if (!items.length)
-      return;
-    const item = items[0];
-    if (item.kind === 'file') {
-      const entry = items[0].webkitGetAsEntry();
-      if (!entry.isFile)
-        return;
-      entry.file(file => {
-        const reader = new FileReader();
-        reader.onload = () => this._loadedFromFile(/** @type {string} */ (reader.result));
-        reader.readAsText(file);
-      });
-    }
-  }
-
-  /**
-   * @param {string} profile
-   */
-  _loadedFromFile(profile) {
-    const data = JSON.parse(profile);
-    if (!data['lighthouseVersion'])
-      return;
-    this._buildReportUI(/** @type {!ReportRenderer.ReportJSON} */ (data));
-  }
-};
-
-/**
- * @override
- */
-Audits2.Audits2Panel.ReportRenderer = class extends ReportRenderer {
-  /**
-   * Provides empty element for left nav
-   * @override
-   * @returns {!DocumentFragment}
-   */
-  _renderReportNav() {
-    return createDocumentFragment();
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   * @override
-   * @return {!DocumentFragment}
-   */
-  _renderReportHeader(report) {
-    return createDocumentFragment();
-  }
-};
-
-class ReportUIFeatures {
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   */
-  initFeatures(report) {
-  }
-}
-
-/** @typedef {{type: string, setting: !Common.Setting, configID: string, title: string, description: string}} */
-Audits2.Audits2Panel.Preset;
-
-/** @type {!Array.<!Audits2.Audits2Panel.Preset>} */
-Audits2.Audits2Panel.Presets = [
-  // configID maps to Lighthouse's Object.keys(config.categories)[0] value
-  {
-    setting: Common.settings.createSetting('audits2.cat_perf', true),
-    configID: 'performance',
-    title: 'Performance',
-    description: 'How long does this app take to show content and become usable'
-  },
-  {
-    setting: Common.settings.createSetting('audits2.cat_pwa', true),
-    configID: 'pwa',
-    title: 'Progressive Web App',
-    description: 'Does this page meet the standard of a Progressive Web App'
-  },
-  {
-    setting: Common.settings.createSetting('audits2.cat_best_practices', true),
-    configID: 'best-practices',
-    title: 'Best practices',
-    description: 'Does this page follow best practices for modern web development'
-  },
-  {
-    setting: Common.settings.createSetting('audits2.cat_a11y', true),
-    configID: 'accessibility',
-    title: 'Accessibility',
-    description: 'Is this page usable by people with disabilities or impairments'
-  },
-  {
-    setting: Common.settings.createSetting('audits2.cat_seo', true),
-    configID: 'seo',
-    title: 'SEO',
-    description: 'Is this page optimized for search engine results ranking'
-  },
-];
-
-/** @typedef {{setting: !Common.Setting, description: string, setFlags: function(!Object, string), options: !Array}} */
-Audits2.Audits2Panel.RuntimeSetting;
-
-/** @type {!Array.<!Audits2.Audits2Panel.RuntimeSetting>} */
-Audits2.Audits2Panel.RuntimeSettings = [
-  {
-    setting: Common.settings.createSetting('audits2.device_type', 'mobile'),
-    description: Common.UIString('Apply mobile emulation during auditing'),
-    setFlags: (flags, value) => {
-      flags.disableDeviceEmulation = value === 'desktop';
-    },
-    options: [
-      {label: Common.UIString('Mobile'), value: 'mobile'},
-      {label: Common.UIString('Desktop'), value: 'desktop'},
-    ],
-  },
-  {
-    setting: Common.settings.createSetting('audits2.throttling', 'default'),
-    description: Common.UIString('Apply network and CPU throttling during performance auditing'),
-    setFlags: (flags, value) => {
-      flags.disableNetworkThrottling = value === 'off';
-      flags.disableCpuThrottling = value === 'off';
-    },
-    options: [
-      {label: Common.UIString('3G w/ CPU slowdown'), value: 'default'},
-      {label: Common.UIString('No throttling'), value: 'off'},
-    ],
-  },
-  {
-    setting: Common.settings.createSetting('audits2.storage_reset', 'on'),
-    description: Common.UIString('Reset storage (localStorage, IndexedDB, etc) to a clean baseline before auditing'),
-    setFlags: (flags, value) => {
-      flags.disableStorageReset = value === 'off';
-    },
-    options: [
-      {label: Common.UIString('Clear storage'), value: 'on'},
-      {label: Common.UIString('Preserve storage'), value: 'off'},
-    ],
-  },
-];
-
-Audits2.ReportSelector = class {
-  constructor() {
-    this._emptyItem = null;
-    this._comboBox = new UI.ToolbarComboBox(this._handleChange.bind(this), 'audits2-report');
-    this._comboBox.setMaxWidth(180);
-    this._comboBox.setMinWidth(140);
-    this._itemByOptionElement = new Map();
-    this._setPlaceholderState();
-  }
-
-  _setPlaceholderState() {
-    this._comboBox.setEnabled(false);
-    this._emptyItem = createElement('option');
-    this._emptyItem.label = Common.UIString('(no reports)');
-    this._comboBox.selectElement().appendChild(this._emptyItem);
-    this._comboBox.select(this._emptyItem);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleChange(event) {
-    const item = this._selectedItem();
-    if (item)
-      item.select();
-  }
-
-  /**
-   * @return {!Audits2.ReportSelector.Item}
-   */
-  _selectedItem() {
-    const option = this._comboBox.selectedOption();
-    return this._itemByOptionElement.get(option);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasCurrentSelection() {
-    return !!this._selectedItem();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasItems() {
-    return this._itemByOptionElement.size > 0;
-  }
-
-  /**
-   * @return {!UI.ToolbarComboBox}
-   */
-  comboBox() {
-    return this._comboBox;
-  }
-
-  /**
-   * @param {!Audits2.ReportSelector.Item} item
-   */
-  prepend(item) {
-    if (this._emptyItem) {
-      this._emptyItem.remove();
-      delete this._emptyItem;
-    }
-
-    const optionEl = item.optionElement();
-    const selectEl = this._comboBox.selectElement();
-
-    this._itemByOptionElement.set(optionEl, item);
-    selectEl.insertBefore(optionEl, selectEl.firstElementChild);
-    this._comboBox.setEnabled(true);
-    this._comboBox.select(optionEl);
-    item.select();
-  }
-
-  clearAll() {
-    for (const elem of this._comboBox.options()) {
-      this._itemByOptionElement.get(elem).delete();
-      this._itemByOptionElement.delete(elem);
-    }
-
-    this._setPlaceholderState();
-  }
-
-  downloadSelected() {
-    const item = this._selectedItem();
-    item.download();
-  }
-};
-
-Audits2.ReportSelector.Item = class {
-  /**
-   * @param {!ReportRenderer.ReportJSON} lighthouseResult
-   * @param {!Element} resultsView
-   * @param {function()} showLandingCallback
-   */
-  constructor(lighthouseResult, resultsView, showLandingCallback) {
-    this._lighthouseResult = lighthouseResult;
-    this._resultsView = resultsView;
-    this._showLandingCallback = showLandingCallback;
-    /** @type {?Element} */
-    this._reportContainer = null;
-
-
-    const url = new Common.ParsedURL(lighthouseResult.url);
-    const timestamp = lighthouseResult.generatedTime;
-    this._element = createElement('option');
-    this._element.label = `${new Date(timestamp).toLocaleTimeString()} - ${url.domain()}`;
-  }
-
-  select() {
-    this._renderReport();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  optionElement() {
-    return this._element;
-  }
-
-  delete() {
-    if (this._element)
-      this._element.remove();
-    this._showLandingCallback();
-  }
-
-  download() {
-    const url = new Common.ParsedURL(this._lighthouseResult.url).domain();
-    const timestamp = this._lighthouseResult.generatedTime;
-    const fileName = `${url}-${new Date(timestamp).toISO8601Compact()}.json`;
-    Workspace.fileManager.save(fileName, JSON.stringify(this._lighthouseResult), true);
-  }
-
-  _renderReport() {
-    this._resultsView.removeChildren();
-    if (this._reportContainer) {
-      this._resultsView.appendChild(this._reportContainer);
-      return;
-    }
-
-    this._reportContainer = this._resultsView.createChild('div', 'lh-vars lh-root lh-devtools');
-
-    const dom = new DOM(/** @type {!Document} */ (this._resultsView.ownerDocument));
-    const detailsRenderer = new Audits2.DetailsRenderer(dom);
-    const categoryRenderer = new Audits2.CategoryRenderer(dom, detailsRenderer);
-    categoryRenderer.setTraceArtifact(this._lighthouseResult);
-    const renderer = new Audits2.Audits2Panel.ReportRenderer(dom, categoryRenderer);
-
-    const templatesHTML = Runtime.cachedResources['audits2/lighthouse/templates.html'];
-    const templatesDOM = new DOMParser().parseFromString(templatesHTML, 'text/html');
-    if (!templatesDOM)
-      return;
-
-    renderer.setTemplateContext(templatesDOM);
-    renderer.renderReport(this._lighthouseResult, this._reportContainer);
-  }
-};
-
-Audits2.CategoryRenderer = class extends CategoryRenderer {
-  /**
-   * @override
-   * @param {!DOM} dom
-   * @param {!DetailsRenderer} detailsRenderer
-   */
-  constructor(dom, detailsRenderer) {
-    super(dom, detailsRenderer);
-    this._defaultPassTrace = null;
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} lhr
-   */
-  setTraceArtifact(lhr) {
-    if (!lhr.artifacts || !lhr.artifacts.traces || !lhr.artifacts.traces.defaultPass)
-      return;
-    this._defaultPassTrace = lhr.artifacts.traces.defaultPass;
-  }
-
-  /**
-   * @override
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @param {!Object<string, !ReportRenderer.GroupJSON>} groups
-   * @return {!Element}
-   */
-  renderPerformanceCategory(category, groups) {
-    const defaultPassTrace = this._defaultPassTrace;
-    const element = super.renderPerformanceCategory(category, groups);
-    if (!defaultPassTrace)
-      return element;
-
-    const timelineButton = UI.createTextButton(Common.UIString('View Trace'), onViewTraceClick, 'view-trace');
-    element.querySelector('.lh-audit-group').prepend(timelineButton);
-    return element;
-
-    async function onViewTraceClick() {
-      await UI.inspectorView.showPanel('timeline');
-      Timeline.TimelinePanel.instance().loadFromEvents(defaultPassTrace.traceEvents);
-    }
-  }
-};
-
-Audits2.DetailsRenderer = class extends DetailsRenderer {
-  /**
-   * @param {!DOM} dom
-   */
-  constructor(dom) {
-    super(dom);
-    this._onMainFrameNavigatedPromise = null;
-  }
-
-  /**
-   * @override
-   * @param {!DetailsRenderer.NodeDetailsJSON} item
-   * @return {!Element}
-   */
-  renderNode(item) {
-    const element = super.renderNode(item);
-    this._replaceWithDeferredNodeBlock(element, item);
-    return element;
-  }
-
-  /**
-   * @param {!Element} origElement
-   * @param {!DetailsRenderer.NodeDetailsJSON} detailsItem
-   */
-  async _replaceWithDeferredNodeBlock(origElement, detailsItem) {
-    const mainTarget = SDK.targetManager.mainTarget();
-    if (!this._onMainFrameNavigatedPromise) {
-      const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel);
-      this._onMainFrameNavigatedPromise = resourceTreeModel.once(SDK.ResourceTreeModel.Events.MainFrameNavigated);
-    }
-
-    await this._onMainFrameNavigatedPromise;
-
-    const domModel = mainTarget.model(SDK.DOMModel);
-    if (!detailsItem.path)
-      return;
-
-    const nodeId = await domModel.pushNodeByPathToFrontend(detailsItem.path);
-
-    if (!nodeId)
-      return;
-    const node = domModel.nodeForId(nodeId);
-    if (!node)
-      return;
-
-    const element =
-        await Common.Linkifier.linkify(node, /** @type {!Common.Linkifier.Options} */ ({title: detailsItem.snippet}));
-    origElement.title = '';
-    origElement.textContent = '';
-    origElement.appendChild(element);
-  }
-};
diff --git a/front_end/audits2/Audits2ProtocolService.js b/front_end/audits2/Audits2ProtocolService.js
deleted file mode 100644
index 4c68a1f..0000000
--- a/front_end/audits2/Audits2ProtocolService.js
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Audits2.ProtocolService = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {?Protocol.InspectorBackend.Connection} */
-    this._rawConnection = null;
-    /** @type {?Services.ServiceManager.Service} */
-    this._backend = null;
-    /** @type {?Promise} */
-    this._backendPromise = null;
-    /** @type {?function(string)} */
-    this._status = null;
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  attach() {
-    return InspectorMain.interceptMainConnection(this._dispatchProtocolMessage.bind(this)).then(rawConnection => {
-      this._rawConnection = rawConnection;
-    });
-  }
-
-  /**
-   * @param {string} auditURL
-   * @param {!Array<string>} categoryIDs
-   * @param {!Object} flags
-   * @return {!Promise<!ReportRenderer.ReportJSON>}
-   */
-  startLighthouse(auditURL, categoryIDs, flags) {
-    return this._send('start', {url: auditURL, categoryIDs, flags});
-  }
-
-  /**
-   * @return {!Promise<!Object|undefined>}
-   */
-  detach() {
-    return Promise.resolve().then(() => this._send('stop')).then(() => this._backend.dispose()).then(() => {
-      delete this._backend;
-      delete this._backendPromise;
-      return this._rawConnection.disconnect();
-    });
-  }
-
-  /**
-   *  @param {function (string): undefined} callback
-   */
-  registerStatusCallback(callback) {
-    this._status = callback;
-  }
-
-  /**
-   * @param {string} message
-   */
-  _dispatchProtocolMessage(message) {
-    this._send('dispatchProtocolMessage', {message: message});
-  }
-
-  _initWorker() {
-    this._backendPromise =
-        Services.serviceManager.createAppService('audits2_worker', 'Audits2Service').then(backend => {
-          if (this._backend)
-            return;
-          this._backend = backend;
-          this._backend.on('statusUpdate', result => this._status(result.message));
-          this._backend.on('sendProtocolMessage', result => this._sendProtocolMessage(result.message));
-        });
-  }
-
-  /**
-   * @param {string} message
-   */
-  _sendProtocolMessage(message) {
-    this._rawConnection.sendMessage(message);
-  }
-
-  /**
-   * @param {string} method
-   * @param {!Object=} params
-   * @return {!Promise<!ReportRenderer.ReportJSON>}
-   */
-  _send(method, params) {
-    if (!this._backendPromise)
-      this._initWorker();
-
-    return this._backendPromise.then(_ => this._backend.send(method, params));
-  }
-};
diff --git a/front_end/audits2/Audits2StatusView.js b/front_end/audits2/Audits2StatusView.js
deleted file mode 100644
index 64e2e0d..0000000
--- a/front_end/audits2/Audits2StatusView.js
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Audits2.Audits2StatusView = class {
-  constructor() {
-    this._statusView = null;
-    this._progressWrapper = null;
-    this._progressBar = null;
-    this._statusText = null;
-
-    this._textChangedAt = 0;
-    this._fastFactsQueued = Audits2.Audits2StatusView.FastFacts.slice();
-    this._currentPhase = null;
-    this._scheduledTextChangeTimeout = null;
-    this._scheduledFastFactTimeout = null;
-  }
-
-  /**
-   * @param {!Element} parentElement
-   */
-  render(parentElement) {
-    this.reset();
-
-    this._statusView = parentElement.createChild('div', 'audits2-status vbox hidden');
-    this._progressWrapper = this._statusView.createChild('div', 'audits2-progress-wrapper');
-    this._progressBar = this._progressWrapper.createChild('div', 'audits2-progress-bar');
-    this._statusText = this._statusView.createChild('div', 'audits2-status-text');
-
-    this.updateStatus(Common.UIString('Loading...'));
-  }
-
-  reset() {
-    this._resetProgressBarClasses();
-    clearTimeout(this._scheduledFastFactTimeout);
-
-    this._textChangedAt = 0;
-    this._fastFactsQueued = Audits2.Audits2StatusView.FastFacts.slice();
-    this._currentPhase = null;
-    this._scheduledTextChangeTimeout = null;
-    this._scheduledFastFactTimeout = null;
-  }
-
-  /**
-   * @param {boolean} isVisible
-   */
-  setVisible(isVisible) {
-    this._statusView.classList.toggle('hidden', !isVisible);
-
-    if (!isVisible)
-      clearTimeout(this._scheduledFastFactTimeout);
-  }
-
-  /**
-   * @param {?string} message
-   */
-  updateStatus(message) {
-    if (!message || !this._statusText)
-      return;
-
-    if (message.startsWith('Cancel')) {
-      this._commitTextChange(Common.UIString('Cancelling\u2026'));
-      clearTimeout(this._scheduledFastFactTimeout);
-      return;
-    }
-
-    const nextPhase = this._getPhaseForMessage(message);
-    if (!nextPhase && !this._currentPhase) {
-      this._commitTextChange(Common.UIString('Lighthouse is warming up\u2026'));
-      clearTimeout(this._scheduledFastFactTimeout);
-    } else if (nextPhase && (!this._currentPhase || this._currentPhase.order < nextPhase.order)) {
-      this._currentPhase = nextPhase;
-      this._scheduleTextChange(this._getMessageForPhase(nextPhase));
-      this._scheduleFastFactCheck();
-      this._resetProgressBarClasses();
-      this._progressBar.classList.add(nextPhase.progressBarClass);
-    }
-  }
-
-  /**
-   * @param {!Audits2.Audits2StatusView.StatusPhases} phase
-   * @return {string}
-   */
-  _getMessageForPhase(phase) {
-    if (phase.message)
-      return Common.UIString(phase.message);
-
-    const deviceType =
-        Audits2.Audits2Panel.RuntimeSettings.find(item => item.setting.name === 'audits2.device_type').setting.get();
-    const throttling =
-        Audits2.Audits2Panel.RuntimeSettings.find(item => item.setting.name === 'audits2.throttling').setting.get();
-    const match = Audits2.Audits2StatusView.LoadingMessages.find(item => {
-      return item.deviceType === deviceType && item.throttling === throttling;
-    });
-
-    return match ? ls`${match.message}` : ls`Lighthouse is loading your page`;
-  }
-
-  /**
-   * @param {string} message
-   * @return {?Audits2.Audits2StatusView.StatusPhases}
-   */
-  _getPhaseForMessage(message) {
-    return Audits2.Audits2StatusView.StatusPhases.find(phase => message.startsWith(phase.statusMessagePrefix));
-  }
-
-  _resetProgressBarClasses() {
-    if (!this._progressBar)
-      return;
-
-    this._progressBar.className = 'audits2-progress-bar';
-  }
-
-  _scheduleFastFactCheck() {
-    if (!this._currentPhase || this._scheduledFastFactTimeout)
-      return;
-
-    this._scheduledFastFactTimeout = setTimeout(() => {
-      this._updateFastFactIfNecessary();
-      this._scheduledFastFactTimeout = null;
-
-      this._scheduleFastFactCheck();
-    }, 100);
-  }
-
-  _updateFastFactIfNecessary() {
-    const now = performance.now();
-    if (now - this._textChangedAt < Audits2.Audits2StatusView.fastFactRotationInterval)
-      return;
-    if (!this._fastFactsQueued.length)
-      return;
-
-    const fastFactIndex = Math.floor(Math.random() * this._fastFactsQueued.length);
-    this._scheduleTextChange(ls`\ud83d\udca1 ${this._fastFactsQueued[fastFactIndex]}`);
-    this._fastFactsQueued.splice(fastFactIndex, 1);
-  }
-
-  /**
-   * @param {string} text
-   */
-  _commitTextChange(text) {
-    if (!this._statusText)
-      return;
-    this._textChangedAt = performance.now();
-    this._statusText.textContent = text;
-  }
-
-  /**
-   * @param {string} text
-   */
-  _scheduleTextChange(text) {
-    if (this._scheduledTextChangeTimeout)
-      clearTimeout(this._scheduledTextChangeTimeout);
-
-    const msSinceLastChange = performance.now() - this._textChangedAt;
-    const msToTextChange = Audits2.Audits2StatusView.minimumTextVisibilityDuration - msSinceLastChange;
-
-    this._scheduledTextChangeTimeout = setTimeout(() => {
-      this._commitTextChange(text);
-    }, Math.max(msToTextChange, 0));
-  }
-
-  /**
-   * @param {!Error} err
-   * @param {string} auditURL
-   */
-  renderBugReport(err, auditURL) {
-    console.error(err);
-    clearTimeout(this._scheduledFastFactTimeout);
-    clearTimeout(this._scheduledTextChangeTimeout);
-    this._resetProgressBarClasses();
-    this._progressBar.classList.add('errored');
-
-    this._commitTextChange('');
-    this._statusText.createTextChild(Common.UIString('Ah, sorry! We ran into an error: '));
-    this._statusText.createChild('em').createTextChild(err.message);
-    if (Audits2.Audits2StatusView.KnownBugPatterns.some(pattern => pattern.test(err.message))) {
-      const message = Common.UIString(
-          'Try to navigate to the URL in a fresh Chrome profile without any other tabs or ' +
-          'extensions open and try again.');
-      this._statusText.createChild('p').createTextChild(message);
-    } else {
-      this._renderBugReportLink(err, auditURL);
-    }
-  }
-
-  /**
-   * @param {!Error} err
-   * @param {string} auditURL
-   */
-  _renderBugReportLink(err, auditURL) {
-    const baseURI = 'https://github.com/GoogleChrome/lighthouse/issues/new?';
-    const title = encodeURI('title=DevTools Error: ' + err.message.substring(0, 60));
-
-    const issueBody = `
-**Initial URL**: ${auditURL}
-**Chrome Version**: ${navigator.userAgent.match(/Chrome\/(\S+)/)[1]}
-**Error Message**: ${err.message}
-**Stack Trace**:
-\`\`\`
-${err.stack}
-\`\`\`
-    `;
-    const body = '&body=' + encodeURIComponent(issueBody.trim());
-    const reportErrorEl = UI.XLink.create(
-        baseURI + title + body, Common.UIString('Report this bug'), 'audits2-link audits2-report-error');
-    this._statusText.appendChild(reportErrorEl);
-  }
-};
-
-
-/** @type {!Array.<!RegExp>} */
-Audits2.Audits2StatusView.KnownBugPatterns = [
-  /PARSING_PROBLEM/,
-  /DOCUMENT_REQUEST/,
-  /READ_FAILED/,
-  /TRACING_ALREADY_STARTED/,
-  /^You must provide a url to the runner/,
-  /^You probably have multiple tabs open/,
-];
-
-/** @typedef {{message: string, progressBarClass: string, order: number}} */
-Audits2.Audits2StatusView.StatusPhases = [
-  {
-    id: 'loading',
-    progressBarClass: 'loading',
-    statusMessagePrefix: 'Loading page',
-    order: 10,
-  },
-  {
-    id: 'gathering',
-    progressBarClass: 'gathering',
-    message: 'Lighthouse is gathering information about the page to compute your score.',
-    statusMessagePrefix: 'Retrieving',
-    order: 20,
-  },
-  {
-    id: 'auditing',
-    progressBarClass: 'auditing',
-    message: 'Almost there! Lighthouse is now generating your own special pretty report!',
-    statusMessagePrefix: 'Evaluating',
-    order: 30,
-  }
-];
-
-/** @typedef {{message: string, deviceType: string, throttling: string}} */
-Audits2.Audits2StatusView.LoadingMessages = [
-  {
-    deviceType: 'mobile',
-    throttling: 'on',
-    message: 'Lighthouse is loading your page with throttling to measure performance on a mobile device on 3G.',
-  },
-  {
-    deviceType: 'desktop',
-    throttling: 'on',
-    message: 'Lighthouse is loading your page with throttling to measure performance on a slow desktop on 3G.',
-  },
-  {
-    deviceType: 'mobile',
-    throttling: 'off',
-    message: 'Lighthouse is loading your page with mobile emulation.',
-  },
-  {
-    deviceType: 'desktop',
-    throttling: 'off',
-    message: 'Lighthouse is loading your page.',
-  },
-];
-
-Audits2.Audits2StatusView.FastFacts = [
-  '1MB takes a minimum of 5 seconds to download on a typical 3G connection [Source: WebPageTest and DevTools 3G definition].',
-  'Rebuilding Pinterest pages for performance increased conversion rates by 15% [Source: WPO Stats]',
-  'BBC has seen a loss of 10% of their users for every extra second of page load [Source: WPO Stats]',
-  'By reducing the response size of JSON needed for displaying comments, Instagram saw increased impressions [Source: WPO Stats]',
-  'Walmart saw a 1% increase in revenue for every 100ms improvement in page load [Source: WPO Stats]',
-  'If a site takes >1 second to become interactive, users lose attention, and their perception of completing the page task is broken [Source: Google Developers Blog]',
-  '75% of global mobile users in 2016 were on 2G or 3G [Source: GSMA Mobile]',
-  'The average user device costs less than 200 USD. [Source: International Data Corporation]',
-  '53% of all site visits are abandoned if page load takes more than 3 seconds [Source: Google DoubleClick blog]',
-  '19 seconds is the average time a mobile web page takes to load on a 3G connection [Source: Google DoubleClick blog]',
-  '14 seconds is the average time a mobile web page takes to load on a 4G connection [Source: Google DoubleClick blog]',
-  '70% of mobile pages take nearly 7 seconds for the visual content above the fold to display on the screen. [Source: Think with Google]',
-  'As page load time increases from one second to seven seconds, the probability of a mobile site visitor bouncing increases 113%. [Source: Think with Google]',
-  'As the number of elements on a page increases from 400 to 6,000, the probability of conversion drops 95%. [Source: Think with Google]',
-  '70% of mobile pages weigh over 1MB, 36% over 2MB, and 12% over 4MB. [Source: Think with Google]',
-  'Lighthouse only simulates mobile performance; to measure performance on a real device, try WebPageTest.org [Source: Lighthouse team]',
-];
-
-/** @const */
-Audits2.Audits2StatusView.fastFactRotationInterval = 6000;
-/** @const */
-Audits2.Audits2StatusView.minimumTextVisibilityDuration = 3000;
diff --git a/front_end/audits2/audits2Dialog.css b/front_end/audits2/audits2Dialog.css
deleted file mode 100644
index ae4b406..0000000
--- a/front_end/audits2/audits2Dialog.css
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.audits2-view {
-    --view-horizontal-margin: 20px;
-    margin: 7px var(--view-horizontal-margin);
-    flex: auto;
-    align-items: center;
-    width: 100%;
-    max-width: 500px;
-}
-
-.launcher-container {
-  width: 100%;
-}
-
-.audits2-view .dialog-close-button {
-    position: absolute;
-    top: 0px;
-    right: -14px;
-}
-
-header {
-    color: #666;
-    font-weight: bold;
-    font-size: 14px;
-    flex: none;
-}
-
-.audits2-form {
-  flex: auto;
-  overflow-y: auto;
-}
-
-.audits2-form label {
-    display: flex;
-}
-
-.audits2-form label div {
-    display: inline;
-}
-
-.audits2-status {
-    flex: auto;
-    align-items: center;
-    color: #666;
-}
-
-.audits2-status-text {
-    text-align: center;
-    height: 60px;
-    display: flex;
-    justify-content: center;
-    flex-direction: column;
-}
-
-.audits2-progress-wrapper {
-    width: calc(100% + 2 * var(--view-horizontal-margin));
-    height: 2px;
-    background-color: #E1F5FE;
-    position: relative;
-    margin: 10px;
-}
-
-.audits2-progress-bar {
-    width: 0%;
-    height: 100%;
-    background: #039BE5;
-    position: absolute;
-    transform-origin: left;
-    animation-fill-mode: forwards;
-    animation-timing-function: ease-out;
-    --progress-bar-loading-duration: 45s;
-    --progress-bar-gathering-duration: 12s;
-    --progress-bar-gathering-percent: 70%;
-    --progress-bar-auditing-duration: 5s;
-    --progress-bar-auditing-percent: 95%;
-}
-
-.audits2-progress-bar.errored {
-    width: 100%;
-    background: #E50303;
-}
-
-.audits2-progress-bar.loading {
-    animation-duration: var(--progress-bar-loading-duration);
-    animation-name: progressBarLoading;
-}
-
-@keyframes progressBarLoading {
-  0% { width: 0%; }
-  100% { width: var(--progress-bar-gathering-percent); }
-}
-
-.audits2-progress-bar.gathering {
-    animation-duration: var(--progress-bar-gathering-duration);
-    animation-name: progressBarGathering;
-}
-
-@keyframes progressBarGathering {
-  0% { width: var(--progress-bar-gathering-percent); }
-  100% { width: var(--progress-bar-auditing-percent); }
-}
-
-.audits2-progress-bar.auditing {
-    animation-duration: var(--progress-bar-auditing-duration);
-    animation-name: progressBarAuditing;
-}
-
-@keyframes progressBarAuditing {
-  0% { width: var(--progress-bar-auditing-percent); }
-  100% { width: 99%; }
-}
-
-.audits2-report-error {
-    display: block;
-    margin-top: 5px;
-}
-
-button {
-    margin: 15px 10px;
-}
-
-.audits2-launcher-row {
-    padding: 6px;
-}
-
-.audits2-launcher-description {
-    padding: 3px 0 0 22px;
-}
-
-.audits2-dialog-help-text {
-    color: red;
-    margin-top: 10px;
-}
-
-.audits2-dialog-buttons {
-    justify-content: center;
-    min-height: 40px;
-}
diff --git a/front_end/audits2/audits2Panel.css b/front_end/audits2/audits2Panel.css
deleted file mode 100644
index 22f9278..0000000
--- a/front_end/audits2/audits2Panel.css
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.audits2-logo {
-    width: 210px;
-    height: 200px;
-    flex-shrink: 0;
-    background-repeat: no-repeat;
-    background-size: contain;
-    margin-top: 10px;
-    background-image: url(Images/audits_logo.svg);
-}
-
-.audits2-landing-page {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    overflow: auto;
-}
-
-
-.audits2-landing-center {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    max-width: 400px;
-    margin: 50px;
-}
-
-.audits2-landing-center > * {
-    flex-shrink: 0;
-}
-
-.audits2-landing-text {
-    color: #666;
-}
-
-.audits2-landing-bold-text {
-    font-weight: bold;
-}
-
-.lh-root {
-  --report-menu-width: 0;
-  user-select: initial;
-  --lh-bg-color: #fff;
-  background-color: var(--lh-bg-color);
-}
-
-.-theme-with-dark-background .lh-root {
-  --lh-bg-color: hsl(0, 0%, 14%);
-  --secondary-text-color: hsl(0, 0%, 66%);
-  --report-secondary-border-color: hsl(0, 0%, 8%);
-}
-
-.-theme-with-dark-background .lh-root .lh-gauge {
-  --circle-background: hsl(0, 0%, 27%);
-  --inset-color: var(--lh-bg-color);
-}
-
-.lh-root .lh-container {
-  word-wrap: normal;
-}
-
-.lh-root pre {
-  word-wrap: break-word;
-}
-
-/* for View Trace button */
-.lh-audit-group {
-  position: relative;
-}
-button.view-trace {
-  position: absolute;
-  right: 0;
-}
-
-.audits2-landing-center button {
-    margin-top: 20px;
-}
-
-.audits2-results-container {
-    overflow-y: scroll;
-    position: relative;
-}
diff --git a/front_end/audits2/lighthouse/LICENSE b/front_end/audits2/lighthouse/LICENSE
deleted file mode 100644
index a4c5efd..0000000
--- a/front_end/audits2/lighthouse/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright 2014 Google Inc.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/front_end/audits2/lighthouse/README.chromium b/front_end/audits2/lighthouse/README.chromium
deleted file mode 100644
index 7619599..0000000
--- a/front_end/audits2/lighthouse/README.chromium
+++ /dev/null
@@ -1,8 +0,0 @@
-Name: Lighthouse is a performance auditing component written in JavaScript that works in the browser.
-Short Name: lighthouse
-URL: github.com/GoogleChrome/lighthouse
-License: Apache License 2.0
-Security Critical: no
-
-This directory contains Chromium's version of the lighthouse report assets, including renderer.
-
diff --git a/front_end/audits2/lighthouse/renderer/category-renderer.js b/front_end/audits2/lighthouse/renderer/category-renderer.js
deleted file mode 100644
index c361200..0000000
--- a/front_end/audits2/lighthouse/renderer/category-renderer.js
+++ /dev/null
@@ -1,566 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-'use strict';
-
-/* globals self, Util */
-
-class CategoryRenderer {
-  /**
-   * @param {!DOM} dom
-   * @param {!DetailsRenderer} detailsRenderer
-   */
-  constructor(dom, detailsRenderer) {
-    /** @private {!DOM} */
-    this._dom = dom;
-    /** @private {!DetailsRenderer} */
-    this._detailsRenderer = detailsRenderer;
-    /** @private {!Document|!Element} */
-    this._templateContext = this._dom.document();
-
-    this._detailsRenderer.setTemplateContext(this._templateContext);
-  }
-
-  /**
-   * @param {!ReportRenderer.AuditJSON} audit
-   * @return {!Element}
-   */
-  _renderAuditScore(audit) {
-    const tmpl = this._dom.cloneTemplate('#tmpl-lh-audit-score', this._templateContext);
-
-    const scoringMode = audit.result.scoringMode;
-    const description = audit.result.helpText;
-    let title = audit.result.description;
-
-    if (audit.result.displayValue) {
-      title += `:  ${audit.result.displayValue}`;
-    }
-
-    if (audit.result.debugString) {
-      const debugStrEl = tmpl.appendChild(this._dom.createElement('div', 'lh-debug'));
-      debugStrEl.textContent = audit.result.debugString;
-    }
-
-    // Append audit details to header section so the entire audit is within a <details>.
-    const header = /** @type {!HTMLDetailsElement} */ (this._dom.find('.lh-score__header', tmpl));
-    if (audit.result.details) {
-      header.appendChild(this._detailsRenderer.render(audit.result.details));
-    }
-
-    const scoreEl = this._dom.find('.lh-score', tmpl);
-    if (audit.result.informative) {
-      scoreEl.classList.add('lh-score--informative');
-    }
-    if (audit.result.manual) {
-      scoreEl.classList.add('lh-score--manual');
-    }
-
-    return this._populateScore(tmpl, audit.score, scoringMode, title, description);
-  }
-
-  /**
-   * @param {!DocumentFragment|!Element} element DOM node to populate with values.
-   * @param {number} score
-   * @param {string} scoringMode
-   * @param {string} title
-   * @param {string} description
-   * @return {!Element}
-   */
-  _populateScore(element, score, scoringMode, title, description) {
-    // Fill in the blanks.
-    const valueEl = this._dom.find('.lh-score__value', element);
-    valueEl.textContent = Util.formatNumber(score);
-    valueEl.classList.add(`lh-score__value--${Util.calculateRating(score)}`,
-        `lh-score__value--${scoringMode}`);
-
-    this._dom.find('.lh-score__title', element).appendChild(
-        this._dom.convertMarkdownCodeSnippets(title));
-    this._dom.find('.lh-score__description', element)
-        .appendChild(this._dom.convertMarkdownLinkSnippets(description));
-
-    return /** @type {!Element} **/ (element);
-  }
-
-  /**
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @return {!Element}
-   */
-  _renderCategoryScore(category) {
-    const tmpl = this._dom.cloneTemplate('#tmpl-lh-category-score', this._templateContext);
-    const score = Math.round(category.score);
-
-    const gaugeContainerEl = this._dom.find('.lh-score__gauge', tmpl);
-    const gaugeEl = this.renderScoreGauge(category);
-    gaugeContainerEl.appendChild(gaugeEl);
-
-    return this._populateScore(tmpl, score, 'numeric', category.name, category.description);
-  }
-
-  /**
-   * @param {!ReportRenderer.AuditJSON} audit
-   * @return {!Element}
-   */
-  _renderAudit(audit) {
-    const element = this._dom.createElement('div', 'lh-audit');
-    element.appendChild(this._renderAuditScore(audit));
-    return element;
-  }
-
-  /**
-   * @param {!ReportRenderer.AuditJSON} audit
-   * @param {number} scale
-   * @return {!Element}
-   */
-  _renderTimelineMetricAudit(audit, scale) {
-    const tmpl = this._dom.cloneTemplate('#tmpl-lh-timeline-metric', this._templateContext);
-    const element = this._dom.find('.lh-timeline-metric', tmpl);
-    element.classList.add(`lh-timeline-metric--${Util.calculateRating(audit.score)}`);
-
-    const titleEl = this._dom.find('.lh-timeline-metric__title', tmpl);
-    titleEl.textContent = audit.result.description;
-
-    const valueEl = this._dom.find('.lh-timeline-metric__value', tmpl);
-    valueEl.textContent = audit.result.displayValue;
-
-    const descriptionEl = this._dom.find('.lh-timeline-metric__description', tmpl);
-    descriptionEl.appendChild(this._dom.convertMarkdownLinkSnippets(audit.result.helpText));
-
-    if (typeof audit.result.rawValue !== 'number') {
-      const debugStrEl = this._dom.createChildOf(element, 'div', 'lh-debug');
-      debugStrEl.textContent = audit.result.debugString || 'Report error: no metric information';
-      return element;
-    }
-
-    const sparklineBarEl = this._dom.find('.lh-sparkline__bar', tmpl);
-    sparklineBarEl.style.width = `${audit.result.rawValue / scale * 100}%`;
-
-    return element;
-  }
-
-  /**
-   * @param {!ReportRenderer.AuditJSON} audit
-   * @param {number} scale
-   * @return {!Element}
-   */
-  _renderPerfHintAudit(audit, scale) {
-    const extendedInfo = /** @type {!CategoryRenderer.PerfHintExtendedInfo}
-        */ (audit.result.extendedInfo);
-    const tooltipAttrs = {title: audit.result.displayValue};
-
-    const element = this._dom.createElement('details', [
-      'lh-perf-hint',
-      `lh-perf-hint--${Util.calculateRating(audit.score)}`,
-      'lh-expandable-details',
-    ].join(' '));
-
-    const summary = this._dom.createChildOf(element, 'summary', 'lh-perf-hint__summary ' +
-        'lh-expandable-details__summary');
-    const titleEl = this._dom.createChildOf(summary, 'div', 'lh-perf-hint__title');
-    titleEl.textContent = audit.result.description;
-
-    this._dom.createChildOf(summary, 'div', 'lh-toggle-arrow', {title: 'See resources'});
-
-    if (!extendedInfo || typeof audit.result.rawValue !== 'number') {
-      const debugStrEl = this._dom.createChildOf(summary, 'div', 'lh-debug');
-      debugStrEl.textContent = audit.result.debugString || 'Report error: no extended information';
-      return element;
-    }
-
-    const sparklineContainerEl = this._dom.createChildOf(summary, 'div', 'lh-perf-hint__sparkline',
-        tooltipAttrs);
-    const sparklineEl = this._dom.createChildOf(sparklineContainerEl, 'div', 'lh-sparkline');
-    const sparklineBarEl = this._dom.createChildOf(sparklineEl, 'div', 'lh-sparkline__bar');
-    sparklineBarEl.style.width = audit.result.rawValue / scale * 100 + '%';
-
-    const statsEl = this._dom.createChildOf(summary, 'div', 'lh-perf-hint__stats', tooltipAttrs);
-    const statsMsEl = this._dom.createChildOf(statsEl, 'div', 'lh-perf-hint__primary-stat');
-    statsMsEl.textContent = Util.formatMilliseconds(audit.result.rawValue);
-
-    if (extendedInfo.value.wastedKb) {
-      const statsKbEl = this._dom.createChildOf(statsEl, 'div', 'lh-perf-hint__secondary-stat');
-      statsKbEl.textContent = Util.formatNumber(extendedInfo.value.wastedKb) + ' KB';
-    }
-
-    const descriptionEl = this._dom.createChildOf(element, 'div', 'lh-perf-hint__description');
-    descriptionEl.appendChild(this._dom.convertMarkdownLinkSnippets(audit.result.helpText));
-
-    if (audit.result.debugString) {
-      const debugStrEl = this._dom.createChildOf(summary, 'div', 'lh-debug');
-      debugStrEl.textContent = audit.result.debugString;
-    }
-
-    if (audit.result.details) {
-      element.appendChild(this._detailsRenderer.render(audit.result.details));
-    }
-
-    return element;
-  }
-
-  /**
-   * Renders the group container for a group of audits. Individual audit elements can be added
-   * directly to the returned element.
-   * @param {!ReportRenderer.GroupJSON} group
-   * @param {{expandable: boolean}} opts
-   * @return {!Element}
-   */
-  _renderAuditGroup(group, opts) {
-    const expandable = opts.expandable;
-    const element = this._dom.createElement(expandable ? 'details' : 'div', 'lh-audit-group');
-    const summmaryEl = this._dom.createChildOf(element, 'summary', 'lh-audit-group__summary');
-    const headerEl = this._dom.createChildOf(summmaryEl, 'div', 'lh-audit-group__header');
-    this._dom.createChildOf(summmaryEl, 'div',
-      `lh-toggle-arrow  ${expandable ? '' : ' lh-toggle-arrow-unexpandable'}`, {
-        title: 'See audits',
-      });
-
-    if (group.description) {
-      const auditGroupDescription = this._dom.createElement('div', 'lh-audit-group__description');
-      auditGroupDescription.appendChild(this._dom.convertMarkdownLinkSnippets(group.description));
-      element.appendChild(auditGroupDescription);
-    }
-    headerEl.textContent = group.title;
-
-    return element;
-  }
-
-  /**
-   * Find the total number of audits contained within a section.
-   * Accounts for nested subsections like Accessibility.
-   * @param {!Array<!Element>} elements
-   * @return {number}
-   */
-  _getTotalAuditsLength(elements) {
-    // Create a scratch element to append sections to so we can reuse querySelectorAll().
-    const scratch = this._dom.createElement('div');
-    elements.forEach(function(element) {
-      scratch.appendChild(element);
-    });
-    const subAudits = scratch.querySelectorAll('.lh-audit');
-    if (subAudits.length) {
-      return subAudits.length;
-    } else {
-      return elements.length;
-    }
-  }
-
-  /**
-   * @param {!Array<!Element>} elements
-   * @return {!Element}
-   */
-  _renderPassedAuditsSection(elements) {
-    const passedElem = this._renderAuditGroup({
-      title: `${this._getTotalAuditsLength(elements)} Passed Audits`,
-    }, {expandable: true});
-    passedElem.classList.add('lh-passed-audits');
-    elements.forEach(elem => passedElem.appendChild(elem));
-    return passedElem;
-  }
-
-  /**
-   * @param {!Array<!Element>} elements
-   * @return {!Element}
-   */
-  _renderNotApplicableAuditsSection(elements) {
-    const notApplicableElem = this._renderAuditGroup({
-      title: `${this._getTotalAuditsLength(elements)} Not Applicable Audits`,
-    }, {expandable: true});
-    notApplicableElem.classList.add('lh-audit-group--notapplicable');
-    elements.forEach(elem => notApplicableElem.appendChild(elem));
-    return notApplicableElem;
-  }
-
-  /**
-   * @param {!Array<!ReportRenderer.AuditJSON>} manualAudits
-   * @param {!Object<string, !ReportRenderer.GroupJSON>} groupDefinitions
-   * @param {!Element} element Parent container to add the manual audits to.
-   */
-  _renderManualAudits(manualAudits, groupDefinitions, element) {
-    const auditsGroupedByGroup = /** @type {!Object<string,
-        !Array<!ReportRenderer.AuditJSON>>} */ ({});
-    manualAudits.forEach(audit => {
-      const group = auditsGroupedByGroup[audit.group] || [];
-      group.push(audit);
-      auditsGroupedByGroup[audit.group] = group;
-    });
-
-    Object.keys(auditsGroupedByGroup).forEach(groupId => {
-      const group = groupDefinitions[groupId];
-      const auditGroupElem = this._renderAuditGroup(group, {expandable: true});
-      auditGroupElem.classList.add('lh-audit-group--manual');
-
-      auditsGroupedByGroup[groupId].forEach(audit => {
-        auditGroupElem.appendChild(this._renderAudit(audit));
-      });
-
-      element.appendChild(auditGroupElem);
-    });
-  }
-
-  /**
-   * @param {!Document|!Element} context
-   */
-  setTemplateContext(context) {
-    this._templateContext = context;
-    this._detailsRenderer.setTemplateContext(context);
-  }
-
-  /**
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @return {!DocumentFragment}
-   */
-  renderScoreGauge(category) {
-    const tmpl = this._dom.cloneTemplate('#tmpl-lh-gauge', this._templateContext);
-    this._dom.find('.lh-gauge__wrapper', tmpl).href = `#${category.id}`;
-    this._dom.find('.lh-gauge__label', tmpl).textContent = category.name;
-
-    const score = Math.round(category.score);
-    const fillRotation = Math.floor((score / 100) * 180);
-
-    const gauge = this._dom.find('.lh-gauge', tmpl);
-    gauge.setAttribute('data-progress', score); // .dataset not supported in jsdom.
-    gauge.classList.add(`lh-gauge--${Util.calculateRating(score)}`);
-
-    this._dom.findAll('.lh-gauge__fill', gauge).forEach(el => {
-      el.style.transform = `rotate(${fillRotation}deg)`;
-    });
-
-    this._dom.find('.lh-gauge__mask--full', gauge).style.transform =
-        `rotate(${fillRotation}deg)`;
-    this._dom.find('.lh-gauge__fill--fix', gauge).style.transform =
-        `rotate(${fillRotation * 2}deg)`;
-    this._dom.find('.lh-gauge__percentage', gauge).textContent = score;
-
-    return tmpl;
-  }
-
-  /**
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @param {!Object<string, !ReportRenderer.GroupJSON>} groups
-   * @return {!Element}
-   */
-  render(category, groups) {
-    switch (category.id) {
-      case 'performance':
-        return this.renderPerformanceCategory(category, groups);
-      case 'accessibility':
-        return this._renderAccessibilityCategory(category, groups);
-      default:
-        return this._renderDefaultCategory(category, groups);
-    }
-  }
-
-  /**
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @param {!Object<string, !ReportRenderer.GroupJSON>} groupDefinitions
-   * @return {!Element}
-   */
-  _renderDefaultCategory(category, groupDefinitions) {
-    const element = this._dom.createElement('div', 'lh-category');
-    this._createPermalinkSpan(element, category.id);
-    element.appendChild(this._renderCategoryScore(category));
-
-    const manualAudits = category.audits.filter(audit => audit.result.manual);
-    const nonManualAudits = category.audits.filter(audit => !manualAudits.includes(audit));
-    const passedAudits = nonManualAudits.filter(audit => audit.score === 100 &&
-        !audit.result.debugString);
-    const nonPassedAudits = nonManualAudits.filter(audit => !passedAudits.includes(audit));
-
-    const nonPassedElem = this._renderAuditGroup({
-      title: `${nonPassedAudits.length} Failed Audits`,
-    }, {expandable: false});
-    nonPassedElem.classList.add('lh-failed-audits');
-    nonPassedAudits.forEach(audit => nonPassedElem.appendChild(this._renderAudit(audit)));
-    element.appendChild(nonPassedElem);
-
-    // Create a passed section if there are passing audits.
-    if (passedAudits.length) {
-      const passedElem = this._renderPassedAuditsSection(
-        passedAudits.map(audit => this._renderAudit(audit))
-      );
-      element.appendChild(passedElem);
-    }
-
-    // Render manual audits after passing.
-    this._renderManualAudits(manualAudits, groupDefinitions, element);
-
-    return element;
-  }
-
-  /**
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @param {!Object<string, !ReportRenderer.GroupJSON>} groups
-   * @return {!Element}
-   */
-  renderPerformanceCategory(category, groups) {
-    const element = this._dom.createElement('div', 'lh-category');
-    this._createPermalinkSpan(element, category.id);
-    element.appendChild(this._renderCategoryScore(category));
-
-    const metricAudits = category.audits.filter(audit => audit.group === 'perf-metric');
-    const metricAuditsEl = this._renderAuditGroup(groups['perf-metric'], {expandable: false});
-    const timelineContainerEl = this._dom.createChildOf(metricAuditsEl, 'div',
-        'lh-timeline-container');
-    const timelineEl = this._dom.createChildOf(timelineContainerEl, 'div', 'lh-timeline');
-
-    let perfTimelineScale = 0;
-    metricAudits.forEach(audit => {
-      if (typeof audit.result.rawValue === 'number' && audit.result.rawValue) {
-        perfTimelineScale = Math.max(perfTimelineScale, audit.result.rawValue);
-      }
-    });
-
-    const thumbnailAudit = category.audits.find(audit => audit.id === 'screenshot-thumbnails');
-    const thumbnailResult = thumbnailAudit && thumbnailAudit.result;
-    if (thumbnailResult && thumbnailResult.details) {
-      const thumbnailDetails = /** @type {!DetailsRenderer.FilmstripDetails} */
-          (thumbnailResult.details);
-      perfTimelineScale = Math.max(perfTimelineScale, thumbnailDetails.scale);
-      const filmstripEl = this._detailsRenderer.render(thumbnailDetails);
-      timelineEl.appendChild(filmstripEl);
-    }
-
-    metricAudits.forEach(item => {
-      if (item.id === 'speed-index-metric' || item.id === 'estimated-input-latency') {
-        return metricAuditsEl.appendChild(this._renderAudit(item));
-      }
-
-      timelineEl.appendChild(this._renderTimelineMetricAudit(item, perfTimelineScale));
-    });
-
-    metricAuditsEl.open = true;
-    element.appendChild(metricAuditsEl);
-
-    const hintAudits = category.audits
-        .filter(audit => audit.group === 'perf-hint' && audit.score < 100)
-        .sort((auditA, auditB) => auditB.result.rawValue - auditA.result.rawValue);
-    if (hintAudits.length) {
-      const maxWaste = Math.max(...hintAudits.map(audit => audit.result.rawValue));
-      const scale = Math.ceil(maxWaste / 1000) * 1000;
-      const hintAuditsEl = this._renderAuditGroup(groups['perf-hint'], {expandable: false});
-      hintAudits.forEach(item => hintAuditsEl.appendChild(this._renderPerfHintAudit(item, scale)));
-      hintAuditsEl.open = true;
-      element.appendChild(hintAuditsEl);
-    }
-
-    const infoAudits = category.audits
-        .filter(audit => audit.group === 'perf-info' && audit.score < 100);
-    if (infoAudits.length) {
-      const infoAuditsEl = this._renderAuditGroup(groups['perf-info'], {expandable: false});
-      infoAudits.forEach(item => infoAuditsEl.appendChild(this._renderAudit(item)));
-      infoAuditsEl.open = true;
-      element.appendChild(infoAuditsEl);
-    }
-
-    const passedElements = category.audits
-        .filter(audit => (audit.group === 'perf-hint' || audit.group === 'perf-info') &&
-            audit.score === 100)
-        .map(audit => this._renderAudit(audit));
-
-    if (!passedElements.length) return element;
-
-    const passedElem = this._renderPassedAuditsSection(passedElements);
-    element.appendChild(passedElem);
-    return element;
-  }
-
-  /**
-   * @param {!ReportRenderer.CategoryJSON} category
-   * @param {!Object<string, !ReportRenderer.GroupJSON>} groupDefinitions
-   * @return {!Element}
-   */
-  _renderAccessibilityCategory(category, groupDefinitions) {
-    const element = this._dom.createElement('div', 'lh-category');
-    this._createPermalinkSpan(element, category.id);
-    element.appendChild(this._renderCategoryScore(category));
-
-    const manualAudits = category.audits.filter(audit => audit.result.manual);
-    const nonManualAudits = category.audits.filter(audit => !manualAudits.includes(audit));
-    const auditsGroupedByGroup = /** @type {!Object<string,
-        {passed: !Array<!ReportRenderer.AuditJSON>,
-        failed: !Array<!ReportRenderer.AuditJSON>,
-        notApplicable: !Array<!ReportRenderer.AuditJSON>}>} */ ({});
-    nonManualAudits.forEach(audit => {
-      const groupId = audit.group;
-      const groups = auditsGroupedByGroup[groupId] || {passed: [], failed: [], notApplicable: []};
-
-      if (audit.result.notApplicable) {
-        groups.notApplicable.push(audit);
-      } else if (audit.score === 100) {
-        groups.passed.push(audit);
-      } else {
-        groups.failed.push(audit);
-      }
-
-      auditsGroupedByGroup[groupId] = groups;
-    });
-
-    const passedElements = /** @type {!Array<!Element>} */ ([]);
-    const notApplicableElements = /** @type {!Array<!Element>} */ ([]);
-    Object.keys(auditsGroupedByGroup).forEach(groupId => {
-      const group = groupDefinitions[groupId];
-      const groups = auditsGroupedByGroup[groupId];
-      if (groups.failed.length) {
-        const auditGroupElem = this._renderAuditGroup(group, {expandable: false});
-        groups.failed.forEach(item => auditGroupElem.appendChild(this._renderAudit(item)));
-        auditGroupElem.open = true;
-        element.appendChild(auditGroupElem);
-      }
-
-      if (groups.passed.length) {
-        const auditGroupElem = this._renderAuditGroup(group, {expandable: true});
-        groups.passed.forEach(item => auditGroupElem.appendChild(this._renderAudit(item)));
-        passedElements.push(auditGroupElem);
-      }
-
-      if (groups.notApplicable.length) {
-        const auditGroupElem = this._renderAuditGroup(group, {expandable: true});
-        groups.notApplicable.forEach(item => auditGroupElem.appendChild(this._renderAudit(item)));
-        notApplicableElements.push(auditGroupElem);
-      }
-    });
-
-    if (passedElements.length) {
-      const passedElem = this._renderPassedAuditsSection(passedElements);
-      element.appendChild(passedElem);
-    }
-
-    if (notApplicableElements.length) {
-      const notApplicableElem = this._renderNotApplicableAuditsSection(notApplicableElements);
-      element.appendChild(notApplicableElem);
-    }
-
-    // Render manual audits after passing.
-    this._renderManualAudits(manualAudits, groupDefinitions, element);
-
-    return element;
-  }
-
-  /**
-   * Create a non-semantic span used for hash navigation of categories
-   * @param {!Element} element
-   * @param {string} id
-   */
-  _createPermalinkSpan(element, id) {
-    const permalinkEl = this._dom.createChildOf(element, 'span', 'lh-permalink');
-    permalinkEl.id = id;
-  }
-}
-
-if (typeof module !== 'undefined' && module.exports) {
-  module.exports = CategoryRenderer;
-} else {
-  self.CategoryRenderer = CategoryRenderer;
-}
-
-
-/**
- * @typedef {{
- *     value: {
- *       wastedMs: (number|undefined),
- *       wastedKb: (number|undefined),
- *     }
- * }}
- */
-CategoryRenderer.PerfHintExtendedInfo; // eslint-disable-line no-unused-expressions
diff --git a/front_end/audits2/lighthouse/renderer/crc-details-renderer.js b/front_end/audits2/lighthouse/renderer/crc-details-renderer.js
deleted file mode 100644
index 822b2f9..0000000
--- a/front_end/audits2/lighthouse/renderer/crc-details-renderer.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-'use strict';
-
-/**
- * @fileoverview This file contains helpers for constructing and rendering the
- * critical request chains network tree.
- */
-
-/* globals self Util */
-
-class CriticalRequestChainRenderer {
-  /**
-   * Create render context for critical-request-chain tree display.
-   * @param {!Object<string, !CriticalRequestChainRenderer.CRCNode>} tree
-   * @return {{tree: !Object<string, !CriticalRequestChainRenderer.CRCNode>, startTime: number, transferSize: number}}
-   */
-  static initTree(tree) {
-    let startTime = 0;
-    const rootNodes = Object.keys(tree);
-    if (rootNodes.length > 0) {
-      const node = tree[rootNodes[0]];
-      startTime = node.request.startTime;
-    }
-
-    return {tree, startTime, transferSize: 0};
-  }
-
-  /**
-   * Helper to create context for each critical-request-chain node based on its
-   * parent. Calculates if this node is the last child, whether it has any
-   * children itself and what the tree looks like all the way back up to the root,
-   * so the tree markers can be drawn correctly.
-   * @param {!Object<string, !CriticalRequestChainRenderer.CRCNode>} parent
-   * @param {string} id
-   * @param {number} startTime
-   * @param {number} transferSize
-   * @param {!Array<boolean>=} treeMarkers
-   * @param {boolean=} parentIsLastChild
-   * @return {!CriticalRequestChainRenderer.CRCSegment}
-   */
-  static createSegment(parent, id, startTime, transferSize, treeMarkers, parentIsLastChild) {
-    const node = parent[id];
-    const siblings = Object.keys(parent);
-    const isLastChild = siblings.indexOf(id) === (siblings.length - 1);
-    const hasChildren = Object.keys(node.children).length > 0;
-
-    // Copy the tree markers so that we don't change by reference.
-    const newTreeMarkers = Array.isArray(treeMarkers) ? treeMarkers.slice(0) : [];
-
-    // Add on the new entry.
-    if (typeof parentIsLastChild !== 'undefined') {
-      newTreeMarkers.push(!parentIsLastChild);
-    }
-
-    return {
-      node,
-      isLastChild,
-      hasChildren,
-      startTime,
-      transferSize: transferSize + node.request.transferSize,
-      treeMarkers: newTreeMarkers,
-    };
-  }
-
-  /**
-   * Creates the DOM for a tree segment.
-   * @param {!DOM} dom
-   * @param {!DocumentFragment} tmpl
-   * @param {!CriticalRequestChainRenderer.CRCSegment} segment
-   * @return {!Node}
-   */
-  static createChainNode(dom, tmpl, segment) {
-    const chainsEl = dom.cloneTemplate('#tmpl-lh-crc__chains', tmpl);
-
-    // Hovering over request shows full URL.
-    dom.find('.crc-node', chainsEl).setAttribute('title', segment.node.request.url);
-
-    const treeMarkeEl = dom.find('.crc-node__tree-marker', chainsEl);
-
-    // Construct lines and add spacers for sub requests.
-    segment.treeMarkers.forEach(separator => {
-      if (separator) {
-        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker vert'));
-        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker'));
-      } else {
-        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker'));
-        treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker'));
-      }
-    });
-
-    if (segment.isLastChild) {
-      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker up-right'));
-      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker right'));
-    } else {
-      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker vert-right'));
-      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker right'));
-    }
-
-    if (segment.hasChildren) {
-      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker horiz-down'));
-    } else {
-      treeMarkeEl.appendChild(dom.createElement('span', 'tree-marker right'));
-    }
-
-    // Fill in url, host, and request size information.
-    const {file, hostname} = Util.parseURL(segment.node.request.url);
-    const treevalEl = dom.find('.crc-node__tree-value', chainsEl);
-    dom.find('.crc-node__tree-file', treevalEl).textContent = `${file}`;
-    dom.find('.crc-node__tree-hostname', treevalEl).textContent = `(${hostname})`;
-
-    if (!segment.hasChildren) {
-      const span = dom.createElement('span', 'crc-node__chain-duration');
-      span.textContent = ' - ' + Util.chainDuration(
-          segment.node.request.startTime, segment.node.request.endTime) + 'ms, ';
-      const span2 = dom.createElement('span', 'crc-node__chain-duration');
-      span2.textContent = Util.formatBytesToKB(segment.node.request.transferSize);
-
-      treevalEl.appendChild(span);
-      treevalEl.appendChild(span2);
-    }
-
-    return chainsEl;
-  }
-
-  /**
-   * Recursively builds a tree from segments.
-   * @param {!DOM} dom
-   * @param {!DocumentFragment} tmpl
-   * @param {!CriticalRequestChainRenderer.CRCSegment} segment
-   * @param {!Element} detailsEl Parent details element.
-   * @param {!CriticalRequestChainRenderer.CRCDetailsJSON} details
-   */
-  static buildTree(dom, tmpl, segment, detailsEl, details) {
-    detailsEl.appendChild(CriticalRequestChainRenderer.createChainNode(dom, tmpl, segment));
-
-    for (const key of Object.keys(segment.node.children)) {
-      const childSegment = CriticalRequestChainRenderer.createSegment(segment.node.children, key,
-         segment.startTime, segment.transferSize, segment.treeMarkers, segment.isLastChild);
-      CriticalRequestChainRenderer.buildTree(dom, tmpl, childSegment, detailsEl, details);
-    }
-  }
-
-  /**
-   * @param {!DOM} dom
-   * @param {!Node} templateContext
-   * @param {!CriticalRequestChainRenderer.CRCDetailsJSON} details
-   * @return {!Node}
-   */
-  static render(dom, templateContext, details) {
-    const tmpl = dom.cloneTemplate('#tmpl-lh-crc', templateContext);
-
-    // Fill in top summary.
-    dom.find('.lh-crc__longest_duration', tmpl).textContent =
-        Util.formatNumber(details.longestChain.duration) + 'ms';
-    dom.find('.lh-crc__longest_length', tmpl).textContent = details.longestChain.length;
-    dom.find('.lh-crc__longest_transfersize', tmpl).textContent =
-        Util.formatBytesToKB(details.longestChain.transferSize);
-
-    const detailsEl = dom.find('.lh-details', tmpl);
-    detailsEl.open = true;
-
-    dom.find('.lh-details > summary', tmpl).textContent = details.header.text;
-
-    // Construct visual tree.
-    const root = CriticalRequestChainRenderer.initTree(details.chains);
-    for (const key of Object.keys(root.tree)) {
-      const segment = CriticalRequestChainRenderer.createSegment(root.tree, key,
-          root.startTime, root.transferSize);
-      CriticalRequestChainRenderer.buildTree(dom, tmpl, segment, detailsEl, details);
-    }
-
-    return tmpl;
-  }
-}
-
-// Allow Node require()'ing.
-if (typeof module !== 'undefined' && module.exports) {
-  module.exports = CriticalRequestChainRenderer;
-} else {
-  self.CriticalRequestChainRenderer = CriticalRequestChainRenderer;
-}
-
-/** @typedef {{
- *     type: string,
- *     header: {text: string},
- *     longestChain: {duration: number, length: number, transferSize: number},
- *     chains: !Object<string, !CriticalRequestChainRenderer.CRCNode>
- * }}
- */
-CriticalRequestChainRenderer.CRCDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     endTime: number,
- *     responseReceivedTime: number,
- *     startTime: number,
- *     transferSize: number,
- *     url: string
- * }}
- */
-CriticalRequestChainRenderer.CRCRequest; // eslint-disable-line no-unused-expressions
-
-/**
- * Record type so children can circularly have CRCNode values.
- * @struct
- * @record
- */
-CriticalRequestChainRenderer.CRCNode = function() {};
-
-/** @type {!Object<string, !CriticalRequestChainRenderer.CRCNode>} */
-CriticalRequestChainRenderer.CRCNode.prototype.children; // eslint-disable-line no-unused-expressions
-
-/** @type {!CriticalRequestChainRenderer.CRCRequest} */
-CriticalRequestChainRenderer.CRCNode.prototype.request; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     node: !CriticalRequestChainRenderer.CRCNode,
- *     isLastChild: boolean,
- *     hasChildren: boolean,
- *     startTime: number,
- *     transferSize: number,
- *     treeMarkers: !Array<boolean>
- * }}
- */
-CriticalRequestChainRenderer.CRCSegment; // eslint-disable-line no-unused-expressions
diff --git a/front_end/audits2/lighthouse/renderer/details-renderer.js b/front_end/audits2/lighthouse/renderer/details-renderer.js
deleted file mode 100644
index 21f31d3..0000000
--- a/front_end/audits2/lighthouse/renderer/details-renderer.js
+++ /dev/null
@@ -1,388 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-'use strict';
-
-/* globals self CriticalRequestChainRenderer Util URL */
-
-class DetailsRenderer {
-  /**
-   * @param {!DOM} dom
-   */
-  constructor(dom) {
-    /** @private {!DOM} */
-    this._dom = dom;
-    /** @private {!Document|!Element} */
-    this._templateContext; // eslint-disable-line no-unused-expressions
-  }
-
-  /**
-   * @param {!Document|!Element} context
-   */
-  setTemplateContext(context) {
-    this._templateContext = context;
-  }
-
-  /**
-   * @param {!DetailsRenderer.DetailsJSON} details
-   * @return {!Node}
-   */
-  render(details) {
-    switch (details.type) {
-      case 'text':
-        return this._renderText(details);
-      case 'url':
-        return this._renderTextURL(details);
-      case 'link':
-        return this._renderLink(/** @type {!DetailsRenderer.LinkDetailsJSON} */ (details));
-      case 'thumbnail':
-        return this._renderThumbnail(/** @type {!DetailsRenderer.ThumbnailDetails} */ (details));
-      case 'filmstrip':
-        return this._renderFilmstrip(/** @type {!DetailsRenderer.FilmstripDetails} */ (details));
-      case 'cards':
-        return this._renderCards(/** @type {!DetailsRenderer.CardsDetailsJSON} */ (details));
-      case 'table':
-        return this._renderTable(/** @type {!DetailsRenderer.TableDetailsJSON} */ (details));
-      case 'code':
-        return this._renderCode(details);
-      case 'node':
-        return this.renderNode(/** @type {!DetailsRenderer.NodeDetailsJSON} */(details));
-      case 'criticalrequestchain':
-        return CriticalRequestChainRenderer.render(this._dom, this._templateContext,
-          /** @type {!CriticalRequestChainRenderer.CRCDetailsJSON} */ (details));
-      case 'list':
-        return this._renderList(/** @type {!DetailsRenderer.ListDetailsJSON} */ (details));
-      default:
-        throw new Error(`Unknown type: ${details.type}`);
-    }
-  }
-
-  /**
-   * @param {!DetailsRenderer.DetailsJSON} text
-   * @return {!Element}
-   */
-  _renderTextURL(text) {
-    const url = text.text || '';
-
-    let displayedPath;
-    let displayedHost;
-    let title;
-    try {
-      const parsed = Util.parseURL(url);
-      displayedPath = parsed.file;
-      displayedHost = `(${parsed.hostname})`;
-      title = url;
-    } catch (/** @type {!Error} */ e) {
-      if (!(e instanceof TypeError)) {
-        throw e;
-      }
-      displayedPath = url;
-    }
-
-    const element = this._dom.createElement('div', 'lh-text__url');
-    element.appendChild(this._renderText({
-      text: displayedPath,
-      type: 'text',
-    }));
-
-    if (displayedHost) {
-      const hostElem = this._renderText({
-        text: displayedHost,
-        type: 'text',
-      });
-      hostElem.classList.add('lh-text__url-host');
-      element.appendChild(hostElem);
-    }
-
-    if (title) element.title = url;
-    return element;
-  }
-
-  /**
-   * @param {!DetailsRenderer.LinkDetailsJSON} details
-   * @return {!Element}
-   */
-  _renderLink(details) {
-    const allowedProtocols = ['https:', 'http:'];
-    const url = new URL(details.url);
-    if (!allowedProtocols.includes(url.protocol)) {
-      // Fall back to text if protocol not allowed.
-      return this._renderText(details);
-    }
-
-    const a = /** @type {!HTMLAnchorElement} */ (this._dom.createElement('a'));
-    a.rel = 'noopener';
-    a.target = '_blank';
-    a.textContent = details.text;
-    a.href = url.href;
-
-    return a;
-  }
-
-  /**
-   * @param {!DetailsRenderer.DetailsJSON} text
-   * @return {!Element}
-   */
-  _renderText(text) {
-    const element = this._dom.createElement('div', 'lh-text');
-    element.textContent = text.text;
-    return element;
-  }
-
-  /**
-   * Create small thumbnail with scaled down image asset.
-   * If the supplied details doesn't have an image/* mimeType, then an empty span is returned.
-   * @param {!DetailsRenderer.ThumbnailDetails} value
-   * @return {!Element}
-   */
-  _renderThumbnail(value) {
-    if (/^image/.test(value.mimeType) === false) {
-      return this._dom.createElement('span');
-    }
-
-    const element = this._dom.createElement('img', 'lh-thumbnail');
-    element.src = value.url;
-    element.alt = '';
-    element.title = value.url;
-    return element;
-  }
-
-  /**
-   * @param {!DetailsRenderer.ListDetailsJSON} list
-   * @return {!Element}
-   */
-  _renderList(list) {
-    if (!list.items.length) return this._dom.createElement('span');
-
-    const element = this._dom.createElement('details', 'lh-details');
-    element.open = true;
-    if (list.header) {
-      const summary = this._dom.createElement('summary', 'lh-list__header');
-      summary.textContent = list.header.text;
-      element.appendChild(summary);
-    }
-
-    const itemsElem = this._dom.createChildOf(element, 'div', 'lh-list__items');
-    for (const item of list.items) {
-      const itemElem = this._dom.createChildOf(itemsElem, 'span', 'lh-list__item');
-      itemElem.appendChild(this.render(item));
-    }
-    return element;
-  }
-
-  /**
-   * @param {!DetailsRenderer.TableDetailsJSON} details
-   * @return {!Element}
-   */
-  _renderTable(details) {
-    if (!details.items.length) return this._dom.createElement('span');
-
-    const element = this._dom.createElement('details', 'lh-details');
-    element.open = true;
-    if (details.header) {
-      element.appendChild(this._dom.createElement('summary')).textContent = details.header;
-    }
-
-    const tableElem = this._dom.createChildOf(element, 'table', 'lh-table');
-    const theadElem = this._dom.createChildOf(tableElem, 'thead');
-    const theadTrElem = this._dom.createChildOf(theadElem, 'tr');
-
-    for (const heading of details.itemHeaders) {
-      const itemType = heading.itemType || 'text';
-      const classes = `lh-table-column--${itemType}`;
-      this._dom.createChildOf(theadTrElem, 'th', classes).appendChild(this.render(heading));
-    }
-
-    const tbodyElem = this._dom.createChildOf(tableElem, 'tbody');
-    for (const row of details.items) {
-      const rowElem = this._dom.createChildOf(tbodyElem, 'tr');
-      for (const columnItem of row) {
-        const classes = `lh-table-column--${columnItem.type}`;
-        this._dom.createChildOf(rowElem, 'td', classes).appendChild(this.render(columnItem));
-      }
-    }
-    return element;
-  }
-
-  /**
-   * @param {!DetailsRenderer.NodeDetailsJSON} item
-   * @return {!Element}
-   * @protected
-   */
-  renderNode(item) {
-    const element = this._dom.createElement('span', 'lh-node');
-    element.textContent = item.snippet;
-    element.title = item.selector;
-    if (item.text) element.setAttribute('data-text', item.text);
-    if (item.path) element.setAttribute('data-path', item.path);
-    if (item.selector) element.setAttribute('data-selector', item.selector);
-    if (item.snippet) element.setAttribute('data-snippet', item.snippet);
-    return element;
-  }
-
-  /**
-   * @param {!DetailsRenderer.CardsDetailsJSON} details
-   * @return {!Element}
-   */
-  _renderCards(details) {
-    const element = this._dom.createElement('details', 'lh-details');
-    element.open = true;
-    if (details.header) {
-      element.appendChild(this._dom.createElement('summary')).textContent = details.header.text;
-    }
-
-    const cardsParent = this._dom.createElement('div', 'lh-scorecards');
-    for (const item of details.items) {
-      const card = cardsParent.appendChild(
-          this._dom.createElement('div', 'lh-scorecard', {title: item.snippet}));
-      const titleEl = this._dom.createElement('div', 'lh-scorecard__title');
-      const valueEl = this._dom.createElement('div', 'lh-scorecard__value');
-      const targetEl = this._dom.createElement('div', 'lh-scorecard__target');
-
-      card.appendChild(titleEl).textContent = item.title;
-      card.appendChild(valueEl).textContent = item.value;
-
-      if (item.target) {
-        card.appendChild(targetEl).textContent = `target: ${item.target}`;
-      }
-    }
-
-    element.appendChild(cardsParent);
-    return element;
-  }
-
-  /**
-   * @param {!DetailsRenderer.FilmstripDetails} details
-   * @return {!Element}
-   */
-  _renderFilmstrip(details) {
-    const filmstripEl = this._dom.createElement('div', 'lh-filmstrip');
-
-    for (const thumbnail of details.items) {
-      const frameEl = this._dom.createChildOf(filmstripEl, 'div', 'lh-filmstrip__frame');
-
-      let timing = Util.formatMilliseconds(thumbnail.timing, 1);
-      if (thumbnail.timing > 1000) {
-        timing = Util.formatNumber(thumbnail.timing / 1000) + ' s';
-      }
-
-      const timingEl = this._dom.createChildOf(frameEl, 'div', 'lh-filmstrip__timestamp');
-      timingEl.textContent = timing;
-
-      const base64data = thumbnail.data;
-      this._dom.createChildOf(frameEl, 'img', 'lh-filmstrip__thumbnail', {
-        src: `data:image/jpeg;base64,${base64data}`,
-        alt: `Screenshot at ${timing}`,
-      });
-    }
-
-    return filmstripEl;
-  }
-
-  /**
-   * @param {!DetailsRenderer.DetailsJSON} details
-   * @return {!Element}
-   */
-  _renderCode(details) {
-    const pre = this._dom.createElement('pre', 'lh-code');
-    pre.textContent = details.text;
-    return pre;
-  }
-}
-
-if (typeof module !== 'undefined' && module.exports) {
-  module.exports = DetailsRenderer;
-} else {
-  self.DetailsRenderer = DetailsRenderer;
-}
-
-/**
- * @typedef {{
- *     type: string,
- *     text: (string|undefined)
- * }}
- */
-DetailsRenderer.DetailsJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     type: string,
- *     header: ({text: string}|undefined),
- *     items: !Array<{type: string, text: (string|undefined)}>
- * }}
- */
-DetailsRenderer.ListDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     type: string,
- *     text: (string|undefined),
- *     path: (string|undefined),
- *     selector: (string|undefined),
- *     snippet:(string|undefined)
- * }}
- */
-DetailsRenderer.NodeDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     type: string,
- *     header: ({text: string}|undefined),
- *     items: !Array<{title: string, value: string, snippet: (string|undefined), target: string}>
- * }}
- */
-DetailsRenderer.CardsDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     type: string,
- *     itemType: (string|undefined),
- *     text: (string|undefined)
- * }}
- */
-DetailsRenderer.TableHeaderJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     type: string,
- *     text: (string|undefined),
- *     path: (string|undefined),
- *     selector: (string|undefined),
- *     snippet:(string|undefined)
- * }}
- */
-DetailsRenderer.NodeDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     type: string,
- *     header: ({text: string}|undefined),
- *     items: !Array<!Array<!DetailsRenderer.DetailsJSON>>,
- *     itemHeaders: !Array<!DetailsRenderer.TableHeaderJSON>
- * }}
- */
-DetailsRenderer.TableDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     type: string,
- *     url: ({text: string}|undefined),
- *     mimeType: ({text: string}|undefined)
- * }}
- */
-DetailsRenderer.ThumbnailDetails; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     type: string,
- *     url: string,
- *     text: string
- * }}
- */
-DetailsRenderer.LinkDetailsJSON; // eslint-disable-line no-unused-expressions
-
-/** @typedef {{
- *     type: string,
- *     scale: number,
- *     items: !Array<{timing: number, timestamp: number, data: string}>,
- * }}
- */
-DetailsRenderer.FilmstripDetails; // eslint-disable-line no-unused-expressions
diff --git a/front_end/audits2/lighthouse/renderer/dom.js b/front_end/audits2/lighthouse/renderer/dom.js
deleted file mode 100644
index a12f794..0000000
--- a/front_end/audits2/lighthouse/renderer/dom.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-'use strict';
-
-/* globals URL self */
-
-class DOM {
-  /**
-   * @param {!Document} document
-   */
-  constructor(document) {
-    /** @private {!Document} */
-    this._document = document;
-  }
-
-  /**
-   * @param {string} name
-   * @param {string=} className
-   * @param {!Object<string, (string|undefined)>=} attrs Attribute key/val pairs.
-   *     Note: if an attribute key has an undefined value, this method does not
-   *     set the attribute on the node.
-   * @return {!Element}
-   */
-  createElement(name, className, attrs = {}) {
-    const element = this._document.createElement(name);
-    if (className) {
-      element.className = className;
-    }
-    Object.keys(attrs).forEach(key => {
-      const value = attrs[key];
-      if (typeof value !== 'undefined') {
-        element.setAttribute(key, value);
-      }
-    });
-    return element;
-  }
-
-  /**
-   * @param {!Element} parentElem
-   * @param {string} elementName
-   * @param {string=} className
-   * @param {!Object<string, (string|undefined)>=} attrs Attribute key/val pairs.
-   *     Note: if an attribute key has an undefined value, this method does not
-   *     set the attribute on the node.
-   * @return {!Element}
-   */
-  createChildOf(parentElem, elementName, className, attrs) {
-    const element = this.createElement(elementName, className, attrs);
-    parentElem.appendChild(element);
-    return element;
-  }
-
-  /**
-   * @param {string} selector
-   * @param {!Node} context
-   * @return {!DocumentFragment} A clone of the template content.
-   * @throws {Error}
-   */
-  cloneTemplate(selector, context) {
-    const template = /** @type {?HTMLTemplateElement} */ (context.querySelector(selector));
-    if (!template) {
-      throw new Error(`Template not found: template${selector}`);
-    }
-
-    const clone = /** @type {!DocumentFragment} */ (this._document.importNode(
-        template.content, true));
-
-    // Prevent duplicate styles in the DOM. After a template has been stamped
-    // for the first time, remove the clone's styles so they're not re-added.
-    if (template.hasAttribute('data-stamped')) {
-      this.findAll('style', clone).forEach(style => style.remove());
-    }
-    template.setAttribute('data-stamped', true);
-
-    return clone;
-  }
-
-  /**
-   * Resets the "stamped" state of the templates.
-   */
-  resetTemplates() {
-    this.findAll('template[data-stamped]', this._document).forEach(t => {
-      t.removeAttribute('data-stamped');
-    });
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Element}
-   */
-  convertMarkdownLinkSnippets(text) {
-    const element = this.createElement('span');
-
-    // Split on markdown links (e.g. [some link](https://...)).
-    const parts = text.split(/\[([^\]]*?)\]\((https?:\/\/.*?)\)/g);
-
-    while (parts.length) {
-      // Pop off the same number of elements as there are capture groups.
-      const [preambleText, linkText, linkHref] = parts.splice(0, 3);
-      element.appendChild(this._document.createTextNode(preambleText));
-
-      // Append link if there are any.
-      if (linkText && linkHref) {
-        const a = /** @type {!HTMLAnchorElement} */ (this.createElement('a'));
-        a.rel = 'noopener';
-        a.target = '_blank';
-        a.textContent = linkText;
-        a.href = (new URL(linkHref)).href;
-        element.appendChild(a);
-      }
-    }
-
-    return element;
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Element}
-   */
-  convertMarkdownCodeSnippets(text) {
-    const element = this.createElement('span');
-
-    const parts = text.split(/`(.*?)`/g); // Split on markdown code slashes
-    while (parts.length) {
-      // Pop off the same number of elements as there are capture groups.
-      const [preambleText, codeText] = parts.splice(0, 2);
-      element.appendChild(this._document.createTextNode(preambleText));
-      if (codeText) {
-        const pre = /** @type {!HTMLPreElement} */ (this.createElement('code'));
-        pre.textContent = codeText;
-        element.appendChild(pre);
-      }
-    }
-
-    return element;
-  }
-
-  /**
-   * @return {!Document}
-   */
-  document() {
-    return this._document;
-  }
-
-  /**
-   * Guaranteed context.querySelector. Always returns an element or throws if
-   * nothing matches query.
-   * @param {string} query
-   * @param {!Node} context
-   * @return {!Element}
-   */
-  find(query, context) {
-    const result = context.querySelector(query);
-    if (result === null) {
-      throw new Error(`query ${query} not found`);
-    }
-    return result;
-  }
-
-  /**
-   * Helper for context.querySelectorAll. Returns an Array instead of a NodeList.
-   * @param {string} query
-   * @param {!Node} context
-   * @return {!Array<!Element>}
-   */
-  findAll(query, context) {
-    return Array.from(context.querySelectorAll(query));
-  }
-}
-
-if (typeof module !== 'undefined' && module.exports) {
-  module.exports = DOM;
-} else {
-  self.DOM = DOM;
-}
diff --git a/front_end/audits2/lighthouse/renderer/report-renderer.js b/front_end/audits2/lighthouse/renderer/report-renderer.js
deleted file mode 100644
index 92ca071..0000000
--- a/front_end/audits2/lighthouse/renderer/report-renderer.js
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-'use strict';
-
-/**
- * @fileoverview The entry point for rendering the Lighthouse report based on the JSON output.
- *    This file is injected into the report HTML along with the JSON report.
- *
- * Dummy text for ensuring report robustness: </script> pre$`post %%LIGHTHOUSE_JSON%%
- */
-
-/* globals self, Util */
-
-class ReportRenderer {
-  /**
-   * @param {!DOM} dom
-   * @param {!CategoryRenderer} categoryRenderer
-   */
-  constructor(dom, categoryRenderer) {
-    /** @private {!DOM} */
-    this._dom = dom;
-    /** @private {!CategoryRenderer} */
-    this._categoryRenderer = categoryRenderer;
-    /** @private {!Document|!Element} */
-    this._templateContext = this._dom.document();
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   * @param {!Element} container Parent element to render the report into.
-   */
-  renderReport(report, container) {
-    container.textContent = ''; // Remove previous report.
-    const element = container.appendChild(this._renderReport(report));
-
-    return /** @type {!Element} **/ (element);
-  }
-
-  /**
-   * Define a custom element for <templates> to be extracted from. For example:
-   *     this.setTemplateContext(new DOMParser().parseFromString(htmlStr, 'text/html'))
-   * @param {!Document|!Element} context
-   */
-  setTemplateContext(context) {
-    this._templateContext = context;
-    this._categoryRenderer.setTemplateContext(context);
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   * @return {!DocumentFragment}
-   */
-  _renderReportHeader(report) {
-    const header = this._dom.cloneTemplate('#tmpl-lh-heading', this._templateContext);
-    this._dom.find('.lh-config__timestamp', header).textContent =
-        Util.formatDateTime(report.generatedTime);
-    const url = this._dom.find('.lh-metadata__url', header);
-    url.href = report.url;
-    url.textContent = report.url;
-
-    this._dom.find('.lh-env__item__ua', header).textContent = report.userAgent;
-
-    const env = this._dom.find('.lh-env__items', header);
-    report.runtimeConfig.environment.forEach(runtime => {
-      const item = this._dom.cloneTemplate('#tmpl-lh-env__items', env);
-      this._dom.find('.lh-env__name', item).textContent = runtime.name;
-      this._dom.find('.lh-env__description', item).textContent = runtime.description;
-      this._dom.find('.lh-env__enabled', item).textContent =
-          runtime.enabled ? 'Enabled' : 'Disabled';
-      env.appendChild(item);
-    });
-
-    return header;
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   * @return {!DocumentFragment}
-   */
-  _renderReportFooter(report) {
-    const footer = this._dom.cloneTemplate('#tmpl-lh-footer', this._templateContext);
-    this._dom.find('.lh-footer__version', footer).textContent = report.lighthouseVersion;
-    this._dom.find('.lh-footer__timestamp', footer).textContent =
-        Util.formatDateTime(report.generatedTime);
-    return footer;
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   * @return {!DocumentFragment}
-   */
-  _renderReportNav(report) {
-    const leftNav = this._dom.cloneTemplate('#tmpl-lh-leftnav', this._templateContext);
-
-    this._dom.find('.leftnav__header__version', leftNav).textContent =
-        `Version: ${report.lighthouseVersion}`;
-
-    const nav = this._dom.find('.lh-leftnav', leftNav);
-    for (const category of report.reportCategories) {
-      const itemsTmpl = this._dom.cloneTemplate('#tmpl-lh-leftnav__items', leftNav);
-
-      const navItem = this._dom.find('.lh-leftnav__item', itemsTmpl);
-      navItem.href = `#${category.id}`;
-
-      this._dom.find('.leftnav-item__category', navItem).textContent = category.name;
-      const score = this._dom.find('.leftnav-item__score', navItem);
-      score.classList.add(`lh-score__value--${Util.calculateRating(category.score)}`);
-      score.textContent = Math.round(category.score);
-      nav.appendChild(navItem);
-    }
-    return leftNav;
-  }
-
-  /**
-   * Returns a div with a list of top-level warnings, or an empty div if no warnings.
-   * @param {!ReportRenderer.ReportJSON} report
-   * @return {!Node}
-   */
-  _renderReportWarnings(report) {
-    if (!report.runWarnings || report.runWarnings.length === 0) {
-      return this._dom.createElement('div');
-    }
-
-    const container = this._dom.cloneTemplate('#tmpl-lh-run-warnings', this._templateContext);
-    const warnings = this._dom.find('ul', container);
-    for (const warningString of report.runWarnings) {
-      const warning = warnings.appendChild(this._dom.createElement('li'));
-      warning.textContent = warningString;
-    }
-
-    return container;
-  }
-
-  /**
-   * @param {!ReportRenderer.ReportJSON} report
-   * @return {!Element}
-   */
-  _renderReport(report) {
-    const container = this._dom.createElement('div', 'lh-container');
-    container.appendChild(this._renderReportHeader(report)); // sticky header goes at the top.
-    container.appendChild(this._renderReportNav(report));
-    const reportSection = container.appendChild(this._dom.createElement('div', 'lh-report'));
-
-    reportSection.appendChild(this._renderReportWarnings(report));
-
-    let scoreHeader;
-    const isSoloCategory = report.reportCategories.length === 1;
-    if (!isSoloCategory) {
-      scoreHeader = reportSection.appendChild(this._dom.createElement('div', 'lh-scores-header'));
-    }
-
-    const categories = reportSection.appendChild(this._dom.createElement('div', 'lh-categories'));
-    for (const category of report.reportCategories) {
-      if (scoreHeader) {
-        scoreHeader.appendChild(this._categoryRenderer.renderScoreGauge(category));
-      }
-      categories.appendChild(this._categoryRenderer.render(category, report.reportGroups));
-    }
-
-    reportSection.appendChild(this._renderReportFooter(report));
-
-    return container;
-  }
-}
-
-if (typeof module !== 'undefined' && module.exports) {
-  module.exports = ReportRenderer;
-} else {
-  self.ReportRenderer = ReportRenderer;
-}
-
-/**
- * @typedef {{
- *     id: string,
- *     weight: number,
- *     score: number,
- *     group: string,
- *     result: {
- *       rawValue: (number|undefined),
- *       description: string,
- *       informative: boolean,
- *       manual: boolean,
- *       notApplicable: boolean,
- *       debugString: string,
- *       displayValue: string,
- *       helpText: string,
- *       score: (number|boolean),
- *       scoringMode: string,
- *       extendedInfo: Object,
- *       details: (!DetailsRenderer.DetailsJSON|undefined)
- *     }
- * }}
- */
-ReportRenderer.AuditJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     name: string,
- *     id: string,
- *     weight: number,
- *     score: number,
- *     description: string,
- *     audits: !Array<!ReportRenderer.AuditJSON>
- * }}
- */
-ReportRenderer.CategoryJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     title: string,
- *     description: (string|undefined),
- * }}
- */
-ReportRenderer.GroupJSON; // eslint-disable-line no-unused-expressions
-
-/**
- * @typedef {{
- *     lighthouseVersion: string,
- *     userAgent: string,
- *     generatedTime: string,
- *     timing: {total: number},
- *     initialUrl: string,
- *     url: string,
- *     runWarnings: (!Array<string>|undefined),
- *     artifacts: {traces: {defaultPass: {traceEvents: !Array}}},
- *     reportCategories: !Array<!ReportRenderer.CategoryJSON>,
- *     reportGroups: !Object<string, !ReportRenderer.GroupJSON>,
- *     runtimeConfig: {
- *       blockedUrlPatterns: !Array<string>,
- *       extraHeaders: !Object,
- *       environment: !Array<{description: string, enabled: boolean, name: string}>
- *     }
- * }}
- */
-ReportRenderer.ReportJSON; // eslint-disable-line no-unused-expressions
diff --git a/front_end/audits2/lighthouse/renderer/util.js b/front_end/audits2/lighthouse/renderer/util.js
deleted file mode 100644
index f979251..0000000
--- a/front_end/audits2/lighthouse/renderer/util.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-'use strict';
-
-/* globals self URL */
-
-const ELLIPSIS = '\u2026';
-const NBSP = '\xa0';
-
-const RATINGS = {
-  PASS: {label: 'pass', minScore: 75},
-  AVERAGE: {label: 'average', minScore: 45},
-  FAIL: {label: 'fail'},
-};
-
-class Util {
-  /**
-   * Convert a score to a rating label.
-   * @param {number} score
-   * @return {string}
-   */
-  static calculateRating(score) {
-    let rating = RATINGS.FAIL.label;
-    if (score >= RATINGS.PASS.minScore) {
-      rating = RATINGS.PASS.label;
-    } else if (score >= RATINGS.AVERAGE.minScore) {
-      rating = RATINGS.AVERAGE.label;
-    }
-    return rating;
-  }
-
-  /**
-   * Format number.
-   * @param {number} number
-   * @param {number=} decimalPlaces Number of decimal places to include. Defaults to 1.
-   * @return {string}
-   */
-  static formatNumber(number, decimalPlaces = 1) {
-    return number.toLocaleString(undefined, {maximumFractionDigits: decimalPlaces});
-  }
-
-  /**
-   * @param {number} size
-   * @param {number=} decimalPlaces Number of decimal places to include. Defaults to 2.
-   * @return {string}
-   */
-  static formatBytesToKB(size, decimalPlaces = 2) {
-    const kbs = (size / 1024).toLocaleString(undefined, {maximumFractionDigits: decimalPlaces});
-    return `${kbs}${NBSP}KB`;
-  }
-
-  /**
-   * @param {number} ms
-   * @param {number=} granularity Controls how coarse the displayed value is, defaults to 10
-   * @return {string}
-   */
-  static formatMilliseconds(ms, granularity = 10) {
-    const coarseTime = Math.round(ms / granularity) * granularity;
-    return `${coarseTime.toLocaleString()}${NBSP}ms`;
-  }
-
-  /**
-   * Format time.
-   * @param {string} date
-   * @return {string}
-   */
-  static formatDateTime(date) {
-    const options = {
-      month: 'short', day: 'numeric', year: 'numeric',
-      hour: 'numeric', minute: 'numeric', timeZoneName: 'short',
-    };
-    let formatter = new Intl.DateTimeFormat('en-US', options);
-
-    // Force UTC if runtime timezone could not be detected.
-    // See https://github.com/GoogleChrome/lighthouse/issues/1056
-    const tz = formatter.resolvedOptions().timeZone;
-    if (!tz || tz.toLowerCase() === 'etc/unknown') {
-      options.timeZone = 'UTC';
-      formatter = new Intl.DateTimeFormat('en-US', options);
-    }
-    return formatter.format(new Date(date));
-  }
-  /**
-   * Converts a time in seconds into a duration string, i.e. `1d 2h 13m 52s`
-   * @param {number} timeInSeconds
-   * @param {string=} zeroLabel
-   * @return {string}
-   */
-  static formatDuration(timeInSeconds, zeroLabel = 'None') {
-    if (timeInSeconds === 0) {
-      return zeroLabel;
-    }
-
-    /** @type {!Array<string>} */
-    const parts = [];
-    const unitLabels = /** @type {!Object<string, number>} */ ({
-      d: 60 * 60 * 24,
-      h: 60 * 60,
-      m: 60,
-      s: 1,
-    });
-
-    Object.keys(unitLabels).forEach(label => {
-      const unit = unitLabels[label];
-      const numberOfUnits = Math.floor(timeInSeconds / unit);
-      if (numberOfUnits > 0) {
-        timeInSeconds -= numberOfUnits * unit;
-        parts.push(`${numberOfUnits}\xa0${label}`);
-      }
-    });
-
-    return parts.join(' ');
-  }
-
-  /**
-   * @param {!URL} parsedUrl
-   * @param {{numPathParts: (number|undefined), preserveQuery: (boolean|undefined), preserveHost: (boolean|undefined)}=} options
-   * @return {string}
-   */
-  static getURLDisplayName(parsedUrl, options) {
-    options = options || {};
-    const numPathParts = options.numPathParts !== undefined ? options.numPathParts : 2;
-    const preserveQuery = options.preserveQuery !== undefined ? options.preserveQuery : true;
-    const preserveHost = options.preserveHost || false;
-
-    let name;
-
-    if (parsedUrl.protocol === 'about:' || parsedUrl.protocol === 'data:') {
-      // Handle 'about:*' and 'data:*' URLs specially since they have no path.
-      name = parsedUrl.href;
-    } else {
-      name = parsedUrl.pathname;
-      const parts = name.split('/').filter(part => part.length);
-      if (numPathParts && parts.length > numPathParts) {
-        name = ELLIPSIS + parts.slice(-1 * numPathParts).join('/');
-      }
-
-      if (preserveHost) {
-        name = `${parsedUrl.host}/${name.replace(/^\//, '')}`;
-      }
-      if (preserveQuery) {
-        name = `${name}${parsedUrl.search}`;
-      }
-    }
-
-    const MAX_LENGTH = 64;
-    // Always elide hexadecimal hash
-    name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
-    // Also elide other hash-like mixed-case strings
-    name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
-        `$1${ELLIPSIS}`);
-    // Also elide long number sequences
-    name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
-    // Merge any adjacent ellipses
-    name = name.replace(/\u2026+/g, ELLIPSIS);
-
-    // Elide query params first
-    if (name.length > MAX_LENGTH && name.includes('?')) {
-      // Try to leave the first query parameter intact
-      name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
-
-      // Remove it all if it's still too long
-      if (name.length > MAX_LENGTH) {
-        name = name.replace(/\?.*/, `?${ELLIPSIS}`);
-      }
-    }
-
-    // Elide too long names next
-    if (name.length > MAX_LENGTH) {
-      const dotIndex = name.lastIndexOf('.');
-      if (dotIndex >= 0) {
-        name = name.slice(0, MAX_LENGTH - 1 - (name.length - dotIndex)) +
-            // Show file extension
-            `${ELLIPSIS}${name.slice(dotIndex)}`;
-      } else {
-        name = name.slice(0, MAX_LENGTH - 1) + ELLIPSIS;
-      }
-    }
-
-    return name;
-  }
-
-  /**
-   * Split a URL into a file and hostname for easy display.
-   * @param {string} url
-   * @return {{file: string, hostname: string}}
-   */
-  static parseURL(url) {
-    const parsedUrl = new URL(url);
-    return {file: Util.getURLDisplayName(parsedUrl), hostname: parsedUrl.hostname};
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @return {string}
-   */
-  static chainDuration(startTime, endTime) {
-    return Util.formatNumber((endTime - startTime) * 1000);
-  }
-}
-
-if (typeof module !== 'undefined' && module.exports) {
-  module.exports = Util;
-} else {
-  // @ts-ignore
-  self.Util = Util;
-}
diff --git a/front_end/audits2/lighthouse/report-styles.css b/front_end/audits2/lighthouse/report-styles.css
deleted file mode 100644
index e56bc6e..0000000
--- a/front_end/audits2/lighthouse/report-styles.css
+++ /dev/null
@@ -1,968 +0,0 @@
-/**
- * @license Copyright 2017 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- */
-
-.lh-vars {
-  --text-font-family: Roboto, Helvetica, Arial, sans-serif;
-  --monospace-font-family: 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;
-  --body-font-size: 14px;
-  --body-line-height: 18px;
-  --subheader-font-size: 16px;
-  --subheader-line-height: 20px;
-  --header-font-size: 20px;
-  --header-line-height: 24px;
-  --title-font-size: 24px;
-  --title-line-height: 28px;
-  --caption-font-size: 12px;
-  --caption-line-height: 16px;
-  --default-padding: 12px;
-  --section-padding: 20px;
-  --section-indent: 16px;
-  --audit-group-indent: 16px;
-  --audit-indent: 16px;
-  --expandable-indent: 20px;
-  --secondary-text-color: #565656;
-  /*--accent-color: #3879d9;*/
-  --fail-color: #df332f;
-  --pass-color: #2b882f;
-  --informative-color: #0c50c7;
-  --manual-color: #757575;
-  --average-color: #ef6c00; /* md orange 800 */
-  --warning-color: #ffab00; /* md amber a700 */
-  --report-border-color: #ccc;
-  --report-secondary-border-color: #ebebeb;
-  --metric-timeline-rule-color: #b3b3b3;
-  --report-width: calc(60 * var(--body-font-size));
-  --report-menu-width: calc(20 * var(--body-font-size));
-  --report-content-width: calc(var(--report-width) + var(--report-menu-width));
-  --navitem-font-size: var(--body-font-size);
-  --navitem-line-height: var(--body-line-height);
-  --navitem-hpadding: var(--body-font-size);
-  --navitem-vpadding: calc(var(--navitem-line-height) / 2);
-  --lh-score-highlight-bg: hsla(0, 0%, 90%, 0.2);
-  --lh-score-icon-background-size: 24px;
-  --lh-score-margin: 12px;
-  --lh-table-header-bg: hsla(0, 0%, 50%, 0.4);
-  --lh-table-higlight-bg: hsla(0, 0%, 75%, 0.1);
-  --lh-sparkline-height: 5px;
-  --lh-sparkline-thin-height: 3px;
-  --lh-filmstrip-thumbnail-width: 60px;
-  --lh-audit-score-width: calc(5 * var(--body-font-size));
-  --lh-category-score-width: calc(5 * var(--body-font-size));
-  --lh-audit-vpadding: 8px;
-  --lh-audit-hgap: 12px;
-  --lh-audit-group-vpadding: 12px;
-  --lh-section-vpadding: 12px;
-  --pass-icon-url: url('data:image/svg+xml;utf8,<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path stroke="%23007F04" stroke-width="1.5" d="M1 5.75l3.5 3.5 6.5-6.5" fill="none" fill-rule="evenodd"/></svg>');
-  --fail-icon-url: url('data:image/svg+xml;utf8,<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><g stroke="%23EE1D0A" stroke-width="1.5" fill="none" fill-rule="evenodd"><path d="M2 10l8-8M10 10L2 2"/></g></svg>');
-  --collapsed-icon-url: url('data:image/svg+xml;utf8,<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="none" d="M0 0h12v12H0z"/><path fill="hsl(0, 0%, 60%)" d="M3 2l6 4-6 4z"/></g></svg>');
-  --expanded-icon-url: url('data:image/svg+xml;utf8,<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="none" d="M0 0h12v12H0z"/><path fill="hsl(0, 0%, 60%)" d="M10 3L6 9 2 3z"/></g></svg>');
-}
-
-.lh-vars.lh-devtools {
-  --text-font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;
-  --monospace-font-family: 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;
-  --body-font-size: 12px;
-  --body-line-height: 16px;
-  --subheader-font-size: 14px;
-  --subheader-line-height: 18px;
-  --header-font-size: 16px;
-  --header-line-height: 20px;
-  --title-font-size: 20px;
-  --title-line-height: 24px;
-  --caption-font-size: 11px;
-  --caption-line-height: 14px;
-  --default-padding: 12px;
-  --section-padding: 16px;
-  --section-indent: 16px;
-  --audit-group-indent: 16px;
-  --audit-indent: 16px;
-  --expandable-indent: 16px;
-
-  --lh-audit-vpadding: 4px;
-  --lh-audit-hgap: 12px;
-  --lh-audit-group-vpadding: 8px;
-  --lh-section-vpadding: 8px;
-}
-
-@keyframes fadeIn {
-  0% { opacity: 0;}
-  100% { opacity: 0.6;}
-}
-
-.lh-root * {
-  box-sizing: border-box;
-}
-
-.lh-root {
-  font-family: var(--text-font-family);
-  font-size: var(--body-font-size);
-  margin: 0;
-  line-height: var(--body-line-height);
-  background: #f5f5f5;
-  scroll-behavior: smooth;
-}
-
-.lh-root :focus {
-    outline: -webkit-focus-ring-color auto 3px;
-}
-
-.lh-root [hidden] {
-  display: none !important;
-}
-
-a {
-  color: #0c50c7;
-}
-
-summary {
-  cursor: pointer;
-}
-
-.lh-details {
-  font-size: var(--body-font-size);
-  margin-top: var(--default-padding);
-}
-
-.lh-details[open] summary {
-  margin-bottom: var(--default-padding);
-}
-
-.lh-details summary::-webkit-details-marker {
-  color: #9e9e9e;
-}
-
-.lh-details.flex .lh-code {
-  max-width: 70%;
-}
-
-/* Report header */
-
-.report-icon {
-  opacity: 0.7;
-}
-.report-icon:hover {
-  opacity: 1;
-}
-.report-icon[disabled] {
-  opacity: 0.3;
-  pointer-events: none;
-}
-
-.report-icon--share {
-  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></svg>');
-}
-.report-icon--print {
-  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/><path fill="none" d="M0 0h24v24H0z"/></svg>');
-}
-.report-icon--copy {
-  background-image: url('data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>');
-}
-.report-icon--open {
-  background-image: url('data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></svg>');
-}
-.report-icon--download {
-  background-image: url('data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
-}
-
-/* List */
-.lh-list {
-  font-size: smaller;
-  margin-top: var(--default-padding);
-}
-
-.lh-list__items {
-  padding-left: var(--default-padding);
-}
-
-.lh-list__item {
-  margin-bottom: 2px;
-}
-
-/* Node */
-.lh-node {
-  display: block;
-  font-family: var(--monospace-font-family);
-  word-break: break-word;
-  color: hsl(174, 100%, 27%);
-}
-span.lh-node:hover {
-    background: hsl(0, 0%, 98%);
-    border-radius: 2px;
-}
-
-/* Card */
-.lh-scorecards {
-  display: flex;
-  flex-wrap: wrap;
-}
-.lh-scorecard {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  flex: 0 0 calc(12 * var(--body-font-size));
-  flex-direction: column;
-  padding: var(--default-padding);
-  padding-top: calc(32px + var(--default-padding));
-  border-radius: 3px;
-  margin-right: var(--default-padding);
-  position: relative;
-  line-height: inherit;
-  border: 1px solid #ebebeb;
-}
-.lh-scorecard__title {
-  background-color: #eee;
-  position: absolute;
-  top: 0;
-  right: 0;
-  left: 0;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  padding: calc(var(--default-padding) / 2);
-}
-.lh-scorecard__value {
-  font-size: calc(1.6 * var(--body-font-size));
-}
-.lh-scorecard__target {
-  margin-top: calc(var(--default-padding) / 2);
-}
-
-/* Score */
-
-.lh-score {
-  display: flex;
-  align-items: flex-start;
-}
-
-.lh-score__value {
-  flex: none;
-  margin-left: var(--lh-score-margin);
-  width: calc(var(--lh-audit-score-width) - var(--lh-score-margin));
-  position: relative;
-  font-weight: bold;
-  top: 1px;
-  text-align: right;
-}
-
-.lh-score__value::after {
-  content: '';
-  position: absolute;
-  right: 0;
-  top: 0;
-  bottom: 0;
-  border-radius: inherit;
-  width: 16px;
-}
-
-.lh-score--informative .lh-score__value {
-  color: var(--informative-color);
-  border-radius: 50%;
-  top: 3px;
-}
-
-.lh-score--informative .lh-score__value::after {
-  display: none;
-  background: url('data:image/svg+xml;utf8,<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>info</title><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" fill="hsl(218, 89%, 41%)"/></svg>') no-repeat 50% 50%;
-  background-size: var(--lh-score-icon-background-size);
-}
-
-.lh-score--manual .lh-score__value::after {
-  background: url('data:image/svg+xml;utf8,<svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><title>manual</title><path d="M2 5h8v2H2z" fill="hsl(0, 0%, 100%)" fill-rule="evenodd"/></svg>') no-repeat 50% 50%;
-  background-size: 18px;
-  background-color: var(--manual-color);
-  width: 20px;
-  height:  20px;
-  position: relative;
-}
-
-.lh-score__value--binary {
-  color: transparent !important;
-}
-
-/* No icon for audits with number scores. */
-.lh-score__value:not(.lh-score__value--binary)::after {
-  content: none;
-}
-
-.lh-score__value--pass {
-  color: var(--pass-color);
-}
-
-.lh-score__value--pass::after {
-  background: var(--pass-icon-url) no-repeat center center / 12px 12px;
-}
-
-.lh-score__value--average {
-  color: var(--average-color);
-}
-
-.lh-score__value--average::after {
-  background: none;
-  content: '!';
-  color: var(--average-color);
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  font-weight: 500;
-  font-size: 15px;
-}
-
-.lh-score__value--fail {
-  color: var(--fail-color);
-}
-
-.lh-score__value--fail::after {
-  background: var(--fail-icon-url) no-repeat center center / 12px 12px;
-}
-
-.lh-score__description {
-  font-size: var(--body-font-size);
-  color: var(--secondary-text-color);
-  line-height: var(--body-line-height);
-}
-
-.lh-score__snippet {
-  align-items: center;
-  justify-content: space-between;
-  /*outline: none;*/
-}
-
-.lh-score__snippet::-moz-list-bullet {
-  display: none;
-}
-
-.lh-score__title {
-  flex: 1;
-}
-
-.lh-toggle-arrow {
-  background: var(--collapsed-icon-url) no-repeat center center / 12px 12px;
-  background-color: transparent;
-  width: 12px;
-  height: 12px;
-  flex: none;
-  transition: transform 150ms ease-in-out;
-  cursor: pointer;
-  border: none;
-  order: -1;
-  margin-right: calc(var(--expandable-indent) - 12px);
-  align-self: flex-start;
-}
-
-.lh-toggle-arrow-unexpandable {
-  visibility: hidden;
-}
-
-/* Expandable Details (Audit Groups, Audits) */
-
-.lh-score__header {
-  order: -1;
-  flex: 1;
-}
-
-.lh-expandable-details {
-  padding-left: var(--expandable-indent);
-}
-
-.lh-expandable-details__summary {
-  display: flex;
-  align-items: center;
-  cursor: pointer;
-  margin-left: calc(0px - var(--expandable-indent));
-}
-
-.lh-audit-group[open] > .lh-audit-group__summary > .lh-toggle-arrow,
-.lh-expandable-details[open] > .lh-expandable-details__summary > .lh-toggle-arrow {
-  background-image: var(--expanded-icon-url);
-}
-
-.lh-audit-group__summary::-webkit-details-marker,
-.lh-expandable-details__summary::-webkit-details-marker {
-  display: none;
-}
-
-.lh-score__snippet .lh-toggle-arrow {
-  margin-top: calc((var(--body-line-height) - 12px) / 2);
-}
-
-/* Perf Timeline */
-
-.lh-timeline-container {
-  overflow: hidden;
-  border-top: 1px solid var(--metric-timeline-rule-color);
-}
-
-.lh-timeline {
-  padding: 0;
-  padding-bottom: 0;
-  width: calc(var(--lh-filmstrip-thumbnail-width) * 10 + var(--default-padding) * 2);
-}
-
-.lh-narrow .lh-timeline-container {
-  width: calc(100vw - var(--section-padding) * 2);
-  overflow-x: scroll;
-}
-
-.lh-devtools .lh-timeline-container {
-  width: 100%;
-  overflow-x: scroll;
-}
-
-/* Perf Timeline Metric */
-
-.lh-timeline-metric {
-  position: relative;
-  margin-bottom: calc(2 * var(--lh-audit-vpadding));
-  padding-top: var(--lh-audit-vpadding);
-  border-top: 1px solid var(--report-secondary-border-color);
-}
-
-.lh-timeline-metric__header {
-  display: flex;
-}
-
-.lh-timeline-metric__details {
-  order: -1;
-}
-
-.lh-timeline-metric__title {
-  font-size: var(--body-font-size);
-  line-height: var(--body-line-height);
-  display: flex;
-}
-
-.lh-timeline-metric__name {
-  flex: 1;
-}
-
-.lh-timeline-metric__description {
-  color: var(--secondary-text-color);
-}
-
-.lh-timeline-metric__value {
-  width: var(--lh-audit-score-width);
-  text-align: right;
-}
-
-.lh-timeline-metric--pass .lh-timeline-metric__value {
-  color: var(--pass-color);
-}
-
-.lh-timeline-metric--average .lh-timeline-metric__value {
-  color: var(--average-color);
-}
-
-.lh-timeline-metric--fail .lh-timeline-metric__value {
-  color: var(--fail-color);
-}
-
-.lh-timeline-metric__sparkline {
-  position: absolute;
-  left: 0;
-  right: 0;
-  top: -1px;
-  height: 3px;
-  width: 100%;
-}
-
-.lh-timeline-metric__sparkline .lh-sparkline__bar {
-  float: none;
-}
-
-.lh-timeline-metric--pass .lh-sparkline__bar {
-  background: var(--pass-color);
-}
-
-.lh-timeline-metric--average .lh-sparkline__bar {
-  background: var(--average-color);
-}
-
-.lh-timeline-metric--fail .lh-sparkline__bar {
-  background: var(--fail-color);
-}
-
-.lh-timeline-metric .lh-debug {
-  margin-left: var(--expandable-indent);
-}
-
-/* Perf Hint */
-
-.lh-perf-hint {
-  padding-top: var(--lh-audit-vpadding);
-  padding-bottom: var(--lh-audit-vpadding);
-  border-top: 1px solid var(--report-secondary-border-color);
-}
-
-.lh-perf-hint:last-of-type {
-  border-bottom: none;
-}
-
-.lh-perf-hint__summary {
-  display: flex;
-  align-items: flex-start;
-  flex-wrap: wrap;
-  min-height: calc(var(--body-line-height) + var(--caption-line-height));
-}
-
-.lh-perf-hint__summary .lh-toggle-arrow {
-  margin-top: calc((var(--subheader-line-height) - 12px) / 2);
-}
-
-.lh-perf-hint__summary .lh-debug {
-  width: calc(100% - var(--expandable-indent));
-  margin: 0 var(--expandable-indent);
-}
-
-.lh-perf-hint__title {
-  font-size: var(--body-font-size);
-  flex: 10;
-}
-
-.lh-perf-hint__sparkline {
-  flex: 0 0 50%;
-  margin-top: calc((var(--body-line-height) - var(--lh-sparkline-height)) / 2);
-}
-
-.lh-perf-hint__sparkline .lh-sparkline {
-  width: 100%;
-  float: right;
-  margin: 0;
-}
-
-.lh-perf-hint__stats {
-  text-align: right;
-  flex: 0 0 var(--lh-audit-score-width);
-}
-
-.lh-perf-hint__primary-stat {
-  font-size: var(--body-font-size);
-  line-height: var(--body-line-height);
-}
-
-.lh-perf-hint__secondary-stat {
-  font-size: var(--caption-font-size);
-  line-height: var(--caption-line-height);
-}
-
-.lh-perf-hint__description {
-  color: var(--secondary-text-color);
-  margin-top: calc(var(--default-padding) / 2);
-}
-
-.lh-perf-hint--pass .lh-perf-hint__stats {
-  color: var(--pass-color);
-}
-
-.lh-perf-hint--pass .lh-sparkline__bar {
-  background: var(--pass-color);
-}
-
-.lh-perf-hint--average .lh-sparkline__bar {
-  background: var(--average-color);
-}
-
-.lh-perf-hint--average .lh-perf-hint__stats {
-  color: var(--average-color);
-}
-
-.lh-perf-hint--fail .lh-sparkline__bar {
-  background: var(--fail-color);
-}
-
-.lh-perf-hint--fail .lh-perf-hint__stats {
-  color: var(--fail-color);
-}
-
-/* Filmstrip */
-
-.lh-filmstrip {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-between;
-  padding-bottom: var(--default-padding);
-}
-
-.lh-filmstrip__frame {
-  text-align: right;
-  position: relative;
-}
-
-.lh-filmstrip__timestamp {
-  margin-bottom: calc(0.5 * var(--caption-line-height));
-  font-size: var(--caption-font-size);
-  line-height: var(--caption-line-height);
-  padding-top: 1px;
-  padding-right: 6px;
-}
-
-.lh-filmstrip__timestamp::before {
-  content: '';
-  height: 7px;
-  width: 2px;
-  background: var(--metric-timeline-rule-color);
-  position: absolute;
-  right: 0;
-  top: -2px;
-}
-
-.lh-filmstrip__thumbnail {
-  border: 1px solid var(--report-secondary-border-color);
-  max-height: 100px;
-  max-width: 60px;
-}
-
-/* Sparkline */
-
-.lh-sparkline {
-  margin: 5px;
-  height: var(--lh-sparkline-height);
-  width: 100%;
-}
-
-.lh-sparkline--thin {
-  height: calc(var(--lh-sparkline-height) / 2);
-}
-
-.lh-sparkline__bar {
-  background: var(--warning-color);
-  height: 100%;
-  float: right;
-  position: relative;
-}
-
-/* correlate metric end location with sparkline */
-.lh-timeline-metric:hover .lh-sparkline__bar::after {
-  content: '';
-  height: 100vh;
-  width: 2px;
-  background: inherit;
-  position: absolute;
-  right: 0;
-  bottom: 0;
-  opacity: 0;
-  animation: fadeIn 150ms;
-  animation-fill-mode: forwards;
-}
-
-/* Audit */
-
-.lh-audit {
-  margin-bottom: var(--lh-audit-vpadding);
-  padding-top: var(--lh-audit-vpadding);
-  border-top: 1px solid var(--report-secondary-border-color);
-}
-
-.lh-audit:last-of-type {
-  border-bottom: none;
-}
-
-.lh-audit > .lh-score {
-  font-size: var(--body-font-size);
-}
-
-.lh-audit .lh-debug {
-  margin-left: var(--expandable-indent);
-  margin-right: var(--lh-audit-score-width);
-}
-
-/* Audit Group */
-
-.lh-audit-group {
-  padding-top: var(--lh-audit-group-vpadding);
-  border-top: 1px solid var(--report-secondary-border-color);
-  padding-left: var(--expandable-indent);
-}
-
-.lh-audit-group__header {
-  font-size: var(--subheader-font-size);
-  line-height: var(--subheader-line-height);
-}
-
-.lh-audit-group__summary {
-  display: flex;
-  align-items: center;
-  margin-bottom: var(--lh-audit-group-vpadding);
-  margin-left: calc(0px - var(--expandable-indent));
-}
-
-.lh-audit-group__summary .lh-toggle-arrow {
-  margin-top: calc((var(--subheader-line-height) - 12px) / 2);
-}
-
-.lh-audit-group__description {
-  font-size: var(--body-font-size);
-  color: var(--secondary-text-color);
-  margin-top: calc(0px - var(--lh-audit-group-vpadding));
-  margin-bottom: var(--lh-audit-group-vpadding);
-  line-height: var(--body-line-height);
-}
-
-
-.lh-debug {
-  font-size: var(--caption-font-size);
-  line-height: var(--caption-line-height);
-  color: var(--fail-color);
-  margin-top: 3px;
-}
-
-.lh-debug::before {
-  display: none;
-  content: '';
-  background: url('data:image/svg+xml;utf8,<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>warn</title><path d="M0 0h24v24H0z" fill="none"/><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" fill="hsl(40, 100%, 50%)"/></svg>') no-repeat 50% 50%;
-  background-size: contain;
-  width: 20px;
-  height: 20px;
-  position: relative;
-  margin-right: calc(var(--default-padding) / 2);
-  top: 5px;
-}
-
-
-/* Report */
-
-.lh-container {
-  display: flex;
-  max-width: var(--report-content-width);
-  word-wrap: break-word;
-  margin: 0 auto;
-}
-
-.lh-report {
-  margin-left: var(--report-menu-width);
-  background-color: #fff;
-  padding-top: var(--report-header-height);
-}
-@media screen {
-  .lh-report {
-    width: var(--report-width);
-  }
-}
-
-.lh-exception {
-  font-size: large;
-}
-
-.lh-text {
-  white-space: nowrap;
-}
-
-.lh-code {
-  white-space: normal;
-  margin-top: 0;
-}
-
-.lh-run-warnings {
-  font-size: var(--body-font-size);
-  margin: var(--section-padding);
-  padding: var(--section-padding);
-  background-color: hsla(40, 100%, 91%, 1);
-  color: var(--secondary-text-color);
-}
-.lh-run-warnings li {
-  margin-bottom: calc(var(--header-line-height) / 2);
-}
-.lh-run-warnings::before {
-  display: inline-block;
-}
-
-.lh-scores-header {
-  display: flex;
-  justify-content: center;
-  overflow-x: hidden;
-  padding: var(--section-padding);
-  border-bottom: 1px solid var(--report-border-color);
-}
-.lh-scores-header__solo {
-  padding: 0;
-  border: 0;
-}
-
-.lh-categories {
-  width: 100%;
-  overflow: hidden;
-}
-
-.lh-category {
-  padding: var(--section-padding);
-  border-top: 1px solid var(--report-border-color);
-}
-
-/* section hash link jump should preserve fixed header
-   https://css-tricks.com/hash-tag-links-padding/
-*/
-.lh-category > .lh-permalink {
-  margin-top: calc((var(--report-header-height) + var(--default-padding)) * -1);
-  padding-bottom: calc(var(--report-header-height) + var(--default-padding));
-  display: block;
-  visibility: hidden;
-}
-
-.lh-category:first-of-type {
-  border: none;
-}
-
-.lh-category > .lh-score {
-  font-size: var(--header-font-size);
-  padding-bottom: var(--lh-section-vpadding);
-}
-
-.lh-category > .lh-score .lh-score__value,
-.lh-category > .lh-score .lh-score__gauge .lh-gauge__label {
-  display: none;
-}
-
-.lh-category .lh-score__gauge {
-  margin-left: var(--section-indent);
-  flex-basis: var(--circle-size);
-  flex-shrink: 0;
-}
-
-.lh-category .lh-score__gauge .lh-gauge {
-  --circle-size: calc(2.5 * var(--header-font-size));
-}
-
-/* Category snippet shouldnt have pointer cursor. */
-.lh-category > .lh-score .lh-score__snippet {
-  cursor: initial;
-}
-
-.lh-category > .lh-score .lh-score__title {
-  font-size: var(--header-font-size);
-  line-height: var(--header-line-height);
-}
-
-.lh-passed-audits[open] summary.lh-passed-audits-summary {
-  margin-bottom: calc(var(--default-padding) * 2);
-}
-
-summary.lh-passed-audits-summary {
-  margin: calc(var(--default-padding) * 2) var(--default-padding);
-  margin-left: var(--default-padding);
-  margin-bottom: 0;
-  font-size: 15px;
-  display: flex;
-  align-items: center;
-}
-
-#lh-log {
-  position: fixed;
-  background-color: #323232;
-  color: #fff;
-  min-height: 48px;
-  min-width: 288px;
-  padding: 16px 24px;
-  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
-  border-radius: 2px;
-  margin: 12px;
-  font-size: 14px;
-  cursor: default;
-  transition: transform 0.3s, opacity 0.3s;
-  transform: translateY(100px);
-  opacity: 0;
-  -webkit-font-smoothing: antialiased;
-  bottom: 0;
-  left: 0;
-  z-index: 3;
-}
-
-#lh-log.show {
-  opacity: 1;
-  transform: translateY(0);
-}
-
-/* 964 fits the min-width of the filmstrip */
-@media screen and (max-width: 964px) {
-  .lh-report {
-    margin-left: 0;
-    width: 100%;
-    min-width: 400px;
-  }
-}
-
-@media print {
-  body {
-    -webkit-print-color-adjust: exact; /* print background colors */
-  }
-  .lh-container {
-    display: block;
-  }
-  .lh-report {
-    margin-left: 0;
-    padding-top: 0;
-  }
-  .lh-categories {
-    margin-top: 0;
-  }
-}
-
-.lh-table {
-  --image-preview-size: 24px;
-  border: 1px solid var(--report-secondary-border-color);
-  border-collapse: collapse;
-  width: 100%;
-
-  --url-col-max-width: 450px;
-}
-
-.lh-table thead {
-  background: var(--lh-table-header-bg);
-}
-
-.lh-table tbody tr:nth-child(even) {
-  background-color: var(--lh-table-higlight-bg);
-}
-
-.lh-table th,
-.lh-table td {
-  padding: 8px 6px;
-}
-
-.lh-table-column--text {
-  text-align: right;
-}
-
-.lh-table-column--thumbnail {
-  width: calc(var(--image-preview-size) * 2);
-}
-
-.lh-table-column--url {
-  text-align: left;
-  min-width: 250px;
-  white-space: nowrap;
-  max-width: var(--url-col-max-width);
-}
-
-.lh-table-column--code {
-  max-width: var(--url-col-max-width);
-}
-
-.lh-text__url {
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.lh-text__url:hover {
-  text-decoration: underline dotted #999;
-  text-decoration-skip-ink: auto;
-}
-
-.lh-text__url > .lh-text, .lh-text__url-host {
-  display: inline;
-}
-
-.lh-text__url-host {
-  margin-left: calc(var(--body-font-size) / 2);
-  opacity: 0.6;
-  font-size: 90%
-}
-
-.lh-thumbnail {
-  height: var(--image-preview-size);
-  width: var(--image-preview-size);
-  object-fit: contain;
-}
-
-/*# sourceURL=report.styles.css */
diff --git a/front_end/audits2/lighthouse/templates.html b/front_end/audits2/lighthouse/templates.html
deleted file mode 100644
index 3a2bc90..0000000
--- a/front_end/audits2/lighthouse/templates.html
+++ /dev/null
@@ -1,559 +0,0 @@
-<!-- Lighthouse run warnings -->
-<template id="tmpl-lh-run-warnings">
-  <div class="lh-run-warnings lh-debug">
-    <strong>There were issues affecting this run of Lighthouse:</strong>
-    <ul></ul>
-  </div>
-</template>
-
-<!-- Lighthouse category score -->
-<template id="tmpl-lh-category-score">
-  <div class="lh-score">
-    <div class="lh-score__value"><!-- fill me --></div>
-    <div class="lh-score__gauge"></div>
-    <div class="lh-score__header">
-      <div class="lh-score__snippet">
-        <span class="lh-score__title"><!-- fill me --></span>
-      </div>
-      <div class="lh-score__description"><!-- fill me --></div>
-    </div>
-  </div>
-</template>
-
-<!-- Lighthouse audit score -->
-<template id="tmpl-lh-audit-score">
-  <div class="lh-score">
-    <div class="lh-score__value"><!-- fill me --></div>
-    <details class="lh-score__header lh-expandable-details">
-      <summary class="lh-score__snippet lh-expandable-details__summary">
-        <span class="lh-score__title"><!-- fill me --></span>
-        <div class="lh-toggle-arrow" title="See audits"></div>
-      </summary>
-      <div class="lh-score__description"><!-- fill me --></div>
-    </details>
-  </div>
-</template>
-
-<!-- Lighthouse timeline metric -->
-<template id="tmpl-lh-timeline-metric">
-  <div class="lh-timeline-metric">
-    <div class="lh-timeline-metric__sparkline">
-      <div class="lh-sparkline__bar"></div>
-    </div>
-    <div class="lh-timeline-metric__header">
-      <div class="lh-timeline-metric__value"><!-- fill me --></div>
-      <details class="lh-timeline-metric__details lh-expandable-details">
-        <summary class="lh-timeline-metric__summary lh-expandable-details__summary">
-          <span class="lh-timeline-metric__title"><!-- fill me --></span>
-          <div class="lh-toggle-arrow" title="See audits"></div>
-        </summary>
-        <div class="lh-timeline-metric__description"><!-- fill me --></div>
-      </details>
-    </div>
-  </div>
-</template>
-
-<!-- Lighthouse left nav -->
-<template id="tmpl-lh-leftnav">
-  <style>
-    .lh-leftnav {
-      width: var(--report-menu-width);
-      border-right: 1px solid var(--report-border-color);
-      position: fixed;
-      height: 100%;
-      background: #fff;
-      will-change: transform; /* prevent excessive paints */
-      z-index: 2;
-    }
-    .lh-leftnav__item {
-      padding: var(--navitem-vpadding) var(--navitem-hpadding);
-      color: var(--secondary-text-color);
-      font-size: var(--navitem-font-size);
-      line-height: var(--navitem-line-height);
-      display: flex;
-      justify-content: space-between;
-      text-decoration: none;
-      color: inherit;
-    }
-    .leftnav-item__score {
-      background: transparent;
-    }
-    .leftnav-item__score::after {
-      content: '';
-    }
-    .leftnav-item__score.lh-score__value--pass {
-      color: var(--pass-color);
-    }
-    .leftnav-item__score.lh-score__value--average {
-      color: var(--average-color);
-    }
-    .leftnav-item__score.lh-score__value--fail {
-      color: var(--fail-color);
-    }
-    .leftnav__header {
-      padding: 0 20px;
-      margin-bottom: var(--navitem-vpadding);
-      height: 115px;
-      font-size: 18px;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZoAAADeCAYAAAAEuMatAABPH0lEQVR4Ae3dBZyk1ZX38d+59z5PSfv0uMPg7iQB4oRkIbrZbGSz7Js368mbrLtE1903nuzGVuIGgQgxCBbIAAPjru1d8sg9b091fxhBMsN0T1V13+/ncz5VNRaFP+ee89zi8QRBEARBEARBEARBEARBIARB0BTZuru7Be0HOoFYlcirAqgIiaoMGKtbAaWNBYFkD9/JzAuC4H3/57KeZKB0Wb/jea9YVrowFbNC0KVAj4Cr50olzTACCKCy11j/QLG/tlmEb5bXp18GdtFmgkDSy3lS7qxzLKsWzSfVcWCMIAiOzxfvuIZV3S+lp/hSUk5DYSzzCIcIkORKJcsQDqOg3gBgUj8qyP8YlU8DnyEI2oTsfc4ynkjvm65eaJ9z8cuMdQvwmoCpgAwiOlH2AERDCONABZUxICUIgob6R7/ynOz7D/+yjlRuEE8BryAccixBczQBUXCj+Xc73difhcAJ2oFUn1PmcV19dnfxZ1/yM2CXkucJIEeWGsCD1IAKSBUvIyCDGD0AphFEUz9fb9QcEATZvetPSd/7uT/2ef56CpFgDIecYNBMUSOAYES+YJ37XeA+WlQQyN6Xr+bxzP+XX3upJEPPIPdVnpwB5LBXEBQa5UHGgFGQUXIzBDIETFakg6B1IGMWCILq337+NfnajX8lxcISjDBl2oPmcCIMl7fXfh/4R1pQEMjwhX0cLfq5a1eUXn3lGxgZtSCeE2MeLcEAOZABOaIJyDAwAAxh4iFERqaCaQzrhwGlxQWBfv3+qP4/t/xZVo9+RZxhykkJGgCNDEZ4rxV5C1ChtQSho1nO0fr/6NWvMPN6Lif3dWaGABzVCZmpSoAaUMdSRRgGBkEGcbof0RGgAlIBMoKgSe5ev6KcRoVC18Z1C0758Hve7p39SZwBOMlBc4hFPmeM3AgM0iKCwEmqHK7nRef1miXzz6JST5k5etir50gCFIAiOX3AUkBAIUUQqaIyBhMlOlGMAIMoQzg9gGUMJQFSQDlOQbB7sLsDm5f/4+tXdW7b1rM0sqxQdInAotTbRV+9/8z+pEp3LnQV8aU/tz+39PSC70kkotly9MWo/9SY6XtNWIVuFYFsePHZHG78rTc+/fxz6jdQI6U1CWAOKwV8o+RgSRUYRhhBGUAZQnQIzBCqw+BrIYACgA994+m9Y2OF00yUnXLHnlWrvn3XmhVdsEpFVwBLKnWzMMuwIkxSEIFyQfEiGFL+2Pw6L+E/qVFGEYCmdjQABWrcaZ73wG8W/uPm3fPjnRbdirLJCI+IMAgoJ1EQyIpfyJnCaZ25fOqtf/36nrR6FpiE9iOPE0QeSBBJUFJEx0GGEBkE9qN+GBgDxhEZAZRgVvnSHWeVXSlddd8jq9d89vbzzi0V9FxVOXvTvu4VWUqXCOWCgUIBlENElMejQBXhzfLX/LK8m+qhkGmJoBGUAhU+ZH6Pf+U36aChKjAK7BR4QIW1ueUhYKsxbAH2MUOCQC55hTKFC/vW9r3/Tz76C4wXSoBn9pAnKIOQg1SBg1UBHQUZRBgAOYD3gwg1aFRK0NLW7Z7fsXt/39L33HTVeXGUP21guPviezb2L7OWJc7SFztAaYic8lRUEJ4nX+Ov5KcxeDIcQMsEDYAhx+L5Q/cRviYvpIjyBKoi7B4fZHNW415V+a6HtcBuYIBpEASy6gplCl/9t387/7SF219LEtWZO44MHhAmKQ2SIkxtwukoMAIyBAwjcgCfDwFZo0664LaHTu/64t1nnke9+MzP337uBanlTIFzvacIYA0UI0WZHhlCHwO817yMNTxEjRJAywUNQEyNHXIab7Zf4YD0EaE8EWMBYQqKss5Y1lq4R+EbKfJDYATwBMFxcvNW8ah0xK5iIcrcolMFkPMYKih9QD9gaNAcyFFyRGogI8AwRgbI/QDCKDCKyBAwzrQJ/ufWS1099pd86juXPX3z7r6nZXn89OFxWWYNrqOoOB5LmT4Z8Fp5L2ewlgqdtLKEIqv0QV6tf8/fyR8R8cR8zuEEOMvnnJXCjwO5ovtR7rQi30G402V8BxgjCI6BXH6DAvCMNevkz3//Yz8fj8kKkJTgyQjA46xoWwBEEqAO1EArIMPAIEYOkPv9wDhQmXr1BE/qextWnvuhW64+f/POeS9Yv2PeVRksLxcoOwMIGFFOhgThNDbwPvNiuhgmwwG0bEcDYMmoSwe/aG9ho5xKAWUaeOPZauCutCZf3rOOO1S4H1CC4HHIolUKwOtf84P+v/iNj7+RkVInkBNM53Hc4T+mIBXQcZAxiMeBySCSxkzoAFADkkbNQVv29/R84JZrTt+8e97131q79PkYLoosncZA7JRmUIQa8LvyB/y0/DPjdAK0fNCA0MEwn7Rv4S/MuyijTBcVEEAMVRV+oMLtqvIZ4F5gkCCYIhf8uALwyivvOeMPbvyv11MpekCZSYE5VCqAAh5BQXJgMnxERlAdBIanPg+hfgDVFPDMIg9tX1z87D1nPfPOh8684f7Ni5/rvZwLUC4orSBBWM5OPmReSB8HyHBtEjQQkTDAYt4U3cxOlhChzLBHVLnVeG4e7JObgRGCOc2NlGm48fnfWUg9ioAaMy3wUwUIj1IABOgCelA1gAFyIJ0skyCMggwh/gCqEyUjj86FoEKb+M7Dqwp/d8fVz9r24MIbSAo/tmsgXl0uYouRAkoryYBnyK0sZCdVOmgnGRGL2cIl+nU2y2uImHGni3A6lp/vqOpWb/nynsXyhTp8ExgimHPcvnk0dEWVhSCeoNl0qjyHSKNUC0AR6AFdgWJABEhAqqBVvKsiZnJF2+T7yQr70KgC1BBt+rU9P9i+oPjNe8666LaHlr30we2LXpqmnB1FIAK9nUorUoQIz/Pkc4DQbhQhw/Ec/2m+Yn8SxSAoM02BOGEl8HOnbNSf8ykbxg9wi4p8TOD7wDhzQuCWfRdWnlkR63QB4AlakR56fVyCahnoQFIBBAAPmBRE6iBjiB/BuxGIRoAhxA+QR/ungigDUmbIr9/03FOHHu77iVsfWPby2HIlQCGCUlFpdSmwWrazhnVkRLSjjIg1ej+djDBML5aTQ4WGXIAiazpXsgb05wTuxvNFKcgnpcBawDNrBXL5jcrPveBrpTdee/P/Y7wYFgFmJzlsJmSYlCPkqOSIVEGGER3EuwF8NAwMoYxQYBio8xR8/BsXlbfumn/DR799/ktG6/bFkdJdLihKe6kgvEBu5m/lddQoAgLQNjMaAINHEd7t3sPNcgNFlJYg1FX4qop8PEr57Oyc5wTOD0BhWHuBCFBmo0CBfLKERykCWFS7QHtQVkNisIkH6igJSp2IKsgAogOo3U9eGAYqCOPAKEf59HfPP+O9X73iVQ9unPdTKGd2laA7VgCU9mOg8dyMJQOEduQxdDDKGl3LFxtB0yKUgijXC3q9wmbj+S9V+ShwL7NG4Mgh7ZBefAiaNjQDt2jLoQCCMjllMuYBy0EEvEGq+VTQVIARjB1Mk6jy/YdPWfr7n7/2RYPbup9jnfbP68ypp5YkAxHBCIiAESaJIrQ2RXDASjbgsbQzwVPWYQytyRtW55bfENU3E3MzVt6rwteAUYK25rIesOQ9gANSggB0qiYJRxOMdwhd1Wph2cM7F527bseiC/YNdS99zXn34s8Xxusx47UCo9UiY7WDFTNaKTJUKTFWLZB7g5+ozINXEMAYpoJIaSUGWC5byLG0s5SYFWygm4wEh0VpNaIAFKnzYtCJ4h6FD8WpfBTYR9CWXDQEL7/qni6qBfukQRMEAhifgeZDo539D25dcvEjuxZfPBEgfaA46/EIAnQV6/SUapj+IUDJvWlU5i311DbCZqRSYvhg8NQKVA4G00SNVYtU6hGqNCiThEPdkIgy01KEjEkCdDLMyaAzfHzWowcQlCpgESLAoTwV3gtJDtZAZJVpJTQIXHywfKS/Jrl8RHM+DKwjaCtyyQuV7/7du14ex/kVQJ2jBYGgGJ+j6IGhrkVrty29aP2uhReN1wpdzipGPD+KAIgCIAKCYmSyEEgyO1GOWhJRT10jfIbGywxO1ESQUU0d9SSi2vh5g+pU6BxeAJx4ECUI8xnkeXyOpbINUF4qH6OL4RntanJVMq/MFEPOKPO41byCGmU2s4Zv6I8xQgcRyvHIvFBwGacu2sS+4QXsHemd+VsbBIADAh8zKv8KrCVoC/K6X97p3vuWD766GKVnAylBcDibZ6joroG+ZfdvXnbl5j3zz03SqGBNjjHK9DgUPiL66PsGARTqWcR4bbLrqUzUwSAaHi9PVImRarERTlluSHNLltMgAuY4u6AEYTWb+DPzc5zH9/E4QKhRQhFmmjBzFMHgialiUIScb3Mtv+3/hSH6j7mz8SqU4grv+Mm38dwLb2HrvlX84cf/mLs2nk/BKSfJuCqfVZW/B75H0NLkNW/a2fH+t3zotUVXXwmSEwQA1mcounugZ8n9m5dfuWnPgguT1EXOekSUk01EMVMloiiC9wfL4FWoJlFjHjRSKTJaK07OhyZq4nPjOC7NLKrgG3XUUZxRBFCEFOWP5Dd5lfwb4/Qx23UwxN/r2/lnfQsllGNRqQsvvuwW/vINb4U8gtIoX/r2T/LWD7yTcgFAOYkyVfkE8A/A7QQtyWW5iVHKIEoAhIBBNN83ETD3bFz19C17+8+vp67gjCdyOc2iKuQHiyMJYIzSWazTXaqxfP5kGOVeGt1NmrmJspMdUKV0MHgar9WDnVESUZnqkNIccqBb6pxu7ieVInAokWYrT8xF8j1U38KxEgOj1S7II3AJoAxXulGawono64BXCHxCkb8FfkDQUuR3fmv9oj964yd/puDSMqDMTYFRj/Hp0Ejn/B9sXHHlwzsXX1JLXCma6mDakYgicMRxXONVlCw31NKoETjVg4GTxAxVyoyOxfxK9Te5OPkmtawAaQZpDl7BCFjDbNLBKJ/hdfym/wfKKMdCAVXPG5/3YW648lNs2H42f/6ZX2fX4AKcVZpsTOAjxjQC52GCliB619+eyryR14I65p5AVLF5MjZe7vnBppVXrtu2+NLxetzlrMeIMlsdCqBDCwkopMScyoM8N/8spl4nq+ZQT9BaSj5Sw+8agiwHYQYICDPKyKH/XWPqjNHFm/3HuIOnUUCPq8OsZ1CMlCQTjNAImRYyCLzHO/kbYDdNFYhu/aOLyM0NgGOOCQHj06QeFddtW3reDzYvv3pwrGOBszlGlLlL8Ahnyf2ca+6lJFUQQUUoZGP4u9eh1QREmHbqwecgwkwQYLxeppoUEFF2sZz/0F/kq/pCIkBQjpeqtHTHK45NQzvkr8cH+AAwTlMEolvecTXePwewzClhk2z9jkVn3b1h9bP2DXetEFGs8QQAQoajSIUCdRTwavixp9/N/Pm7IQcQpp/C4B6ojoIYppUo2Ix//tKNfPS7z6cjVoboY5QCRQCU2cpYEOFuQd4BfJrjpB30qNIjUGRSAowCBwiOiejmt12HckUImjkyhxGf7RvsWXz3+tXXbNi94CJVcNYTPJbHoAgAuTe86nnfY9GqPaAWVJl2YiCrw96tkCUgMu1B8+7/eTP/dut1dBXAABZlLokyPm28vAu4kyfgu+jP+rjCC9dV53GONSxVZZ4IJSbVUYaBnSiPqHKLV24DdhI8LgdSBhWC2UsAmyfVaqF8z4aVz3pg67Kn1ZKo7GyOGJ5AYPAcouA9ZB48M8SDRFDug4HdIExv0KhifUYMRChzURLxMtDnCfKP3vCXwABTagu4uL6AnykrL1FhNYA9+iraQxYBZwDPFvhZa9iP50uqfBC4leBxg4bZLTwPs2H74jPvePjU5+8f6Vwa2ZzI5bSiQKHcA2NDkNRAhGB68xboAv0d43mJyeV3h5awTubzK7HwUx05HQoIx0mZj/B6EV4twmeBdwL3EjQ4lCIgBLNx2J8MT6wr377u1Gdt2LXgYo+Y2GW0sEAVrJ0Mm6QKCDMgUMBzbjqPTxfnMaDQjwflhEUKP64511W28Bfe86dAEoJGNEYJZhPjM/XG3Ld+9ZV3r1/17PFa3OOsx4knaJOwKXXAqIN82rfQAgUMZIuFvB9B6UeZPgpi6Ow6g7chXK7KzwK753jQMMuCJnQxBwa7F333oTXXbtk7/xwjvh2PyULQRAVwMeRVgukPmXQZ+D4gZ8b4FARu8I7Pbt3OK4GtzFEOJAYlaP9ZjM+NTHQxT7vnkVXPHU/izsjmBG0sLkK9AgjBNBHIlgq+F8hPUq55Ll9R5n+yUW4A9jAHORQHCG0tPHg5ONzV/50HTnvBxj0LznPG0+4hEwi4AiggBNPBQ7ZEyOcBOSeNerC9XObm8T6ElwEZc4wDNQTtyfgcFX1w87KLvrduzbXj1UJvGPbPEgJYByjBNPDgeyCfD3hOOvWNul7ht4B3Mcc4wBC0H5cnlWqh4ztrz3jBup2LLjNomMXMNiKNOkGBAhFkiwQE8DSNgd/0yufn2g3TDhFBlaBNiHpsnm7dvXDNtx847cf2j3QueZIbloMgUMjmgZaAnKZS6Eb4A+CVzCFhPtNOrM99buWuB0951l0bVj0nz20cu5xgFlLA+xOd0QQKWgDfJ+BpCQIvF8MzgW8yRzi8KiC0tsBlyeh4ufub9591/cbd88+LrMfZnGAWy1NOTCAKebegMa0UNCaHX8wM95cMw4CfC0dnHlVDSwvPxmzbveDU2x444/qBkY4lc6GLCRTSOgjBU6WgFnwXLUUB4/mJ2PNMEWoC6wVuQ7kF+C6zkAP1tKbAaK6ov/fh1U+fuKfsusybeI4M/AP1kNQAIXjqNAZfAjytxgJLMwWFU4EXAG+zwje85W+AzzGLOIQcpQWFBzBr9Tj+9trTrntw29IrrPU445kDAjFQG4P8hL4qINCpkLGAp2UJjzJeeY5mPAflw1h+HdjHLOBAUtBwsWYribL64GD3gq/df9ZLdg70rpljXUwgQHUMcg/G8AQCzyHCIXroVUtCuxEA4adRzspyXgVsoc050DrQRcsI85ituxas+fp9Z71spFrqD0/4zzEikNahMgJGCB6HBwxoGXwn+JKgEQ2iQB1MVbEjoBHtS7kisnwmHeF6YAdtzKEkBK0RMqLZ2k0rLv3W2tNfnHsTz8WQCQRGDkCeghiCo3jwXZD3C74TMBxBATrAi5AnoAJ42pfhQp/wntoOXgYk7dzRJDRXYHyuKnz3gdOfc+/Glc8VVKzxzDGBMVAZhfFhQDhMoIBAtkjIFwAG8I16QuoApa1pDoWFvKi0hJ8F/ok25RBTQb0CQnDy2TxLkjj6+n1n3vDwzsWXOBOe8p+TxEBah6E9oAoiBEeFzFIhnwco4PnRlFlBc8hzfgvhk8C+dn1gswIoQTNCJh2vljq/es85r9i6r/+MyOUISvMEXs0T/7gIGAGEaSUCSQ0GdkKegDVMOwGMoGLIgRzhaAYQlJajU7cu9wM5c9UK8bwC+DfakEO0gtIE4VLM/YM9C2/9wdmv3DvUtaz5ty4HRjwFk/B4cjFInkEtA2+YPgK1MRjci9brIMcwVJCncDONKNiMOB2nm1E6UQ5RFKFGGY9tzVuX+wHPnKbCq9s3aKwbJ8sITiKX1Xbt61/51XvPeeVIpbSg+evLQeojTu3cwrVLv0nuHQACIAKAihDtSknv2AtpBiJMH0VrCdkdD0Oag/Ckqt6TAsLxe3n9d3mReRuS8ShLTpUyb7cf4CE5nwilZRjI5wtICBrgfIFlwI42DJp0hEyU4OSIstq2ifXlm+8991XVetzd3PvKAhFFAGs8TnIilxIhAKgCuQfvIVd8LYPUQy4gTB9jIFG0kkGW/8gQ0zTDe0U4fmWp0SEKemTQVOjAkaAt2M34MuAJoFuFs9oyaP7s6y8e+ZUrv5LHJo0AZeYELq9v3Lb43FvuO+fHk8yWQsic1AfgAMXIZIkoAGnuqGeWSlZmODHQMUYuRUgydKLIPZr7Q4EjAobpZQSt1EEVjAHhyRnhqfJYHkvIcShCSxHIOwED5AQQAYtpQ+62HSuSt6jUgRKgBDMWMg9tWX7xN+4/4yW5N4Vwncz0E0DMkUHiveD1YBnSzDFSLTI6UePVmNFakZFKkbFagX3VLq5KDvATV27Gz18GWU6DMEVAhBkhgg6NQZaDs0wJDGhJwDMlUKVIG3IlmyagM3p7X3jaP68/sGnFZd/44ZkvQ8WGZ2ROIEhEpwoE5VECWW4Yqxao1GOqScxItcBwpcToeInhaolqPSLNLVluJkoeveHFCFQF8B72DcHC5WCEk0IEkhS/fxiMcJhAAMdhAoE6bcgZpA4yDgjB9BIU45O1G1de/s0fnvFSBGueNGQCEQA9LFR4tEPJvVBPo4ly1DPXCJShgyEyXn60M6klEbXUkUxUmoMRkEPVIICzekTzYBAwAjsH0NU1pFQA75lx1uB3DaDDVTCGKYGCGlDhkCATwx7akJNIEzSvAIZgehmf3rd+1dO//eDpP4aoNaIcEkwFCOZgGcWrkOV2srw5GBqNIBmplBrHXaO1AuMTVanFjNdjkswggB7R8RyqQqTHP5Sv1sk37sadtwoEUGaOEbSekm/YxWMF4kEAJUBAc4aTAzxAG3J33r9UudZVcLkhmM7LMev3r1/59G89ePr1ImrmYMgc6kamCkBVUAWvQiWJGKsWGas3AmSi4smjrkZ3UqSWOLwKuRe8BwWMHOpSIqtMO2PwW/fh+7swy/ohzZkxIuTrd6JDFXCGwwQCKJADjkBAPWtdDztoQ871wKc3Xjj66gtvU5ICJygQYGom860HTn+xiIoRneUzE4DJV+HQ5zS3jNViKvVCIzTGapMzk6GxcmMoX6nHjV+TZpYkE1TBmENBIgCiWHOwTmI6eiX/4VYoxpj+rukPGxFwQr5xD37THp7gP1zgQaqgRUDDkXJ9Fx+nTbn6Ltj5YHGIyzUlOeFONbB5/cGpwT+CGNFZtBoMcth6cJabRkjUs4gks42OZGi8fLAaQVKtxxMVUUliaqnF50fNSmSqgNgpLcPI5AOUd2/AXXQKZn4P5B5UOWFTKZpv2E3+4DYahODxKJhRxfdJyFzYVjX8D23KVQ2YNX6ElAxwIWhO7AvL1m1efuFEyLwUsEa0PWcmRhEUr2bq2MqQedvoQEarxcbcZOJ1alZSaAziD75muQCgOlkcdszljIKhfdjJeU1253rsmcuxKxeAtZDnPCUiYA1aT/HrtpNv2QcCiPAEAgN2DPIaaBHwzFmJ5y86lrOXNuU6lkOn+CGYCpqnLDzxv2nH4rO+PhEyCq4FQ+bILS4UAAUEIVeoJVEjMMarxcaR13C12JiXTA3jSb0hb6wGG3IPHD4zMYo1yqxiDGQ5+Q83o/uGsWuWIH2dYAAPqAfliclhSZvl+O37G52MDo+BtRyDIAV3QEmXC3ORCkSGr3QY3kMbc/McfHn9paOvPueu8c64WsIbguPksmT77vmn3nLv2a/Mc1O0xrfMarCgGFEUoZ5Z6knUCJTqRI1MBcnkcVeJetZYC278fJo/9u+VwiTTCBXmBpFG+d2D+P0jmAU9mGXzkJ4OpBhDZEAB1aN+D5Bk6HiC7h/B7ziAHxoD5XhCJrBgBsB2QN4H5MwdBiTlIfH8dAI12phLKvBIpS9PE7ePAguBnOMSrvrfvb9/2c33nPeqehp1nKxrZUSOnJmAkuWWqQcSG6ExVi0wWikx2JiZFKgmcWNuMvm8iUUfM9g/9HrUzCSwBrzH7xpolJQLSFcJKRehFCOxo0EVradotY6OTdRoBerpVGIbMARPgdulqBN8F5Az+1mQcYh2aJlElgF7aWNO1tNQNPk+wAIpwTGHzPBoZ9/BTqZSj3uczWfkKXgjCnJoNVhVSHLbWAkeO1jVIsOVIqPVwkQVD1YjVLyXRuUKqiACZqqcVYKnMmcRALSaoON1GgwgQoMCKPjD/gt3lhMQCJBBtFVJlwq+F9BGzT4GUDAD4HYrkrIS0f8GuRbY2L5B42lYu/b0PZc9424lNxyDwPqsXi8Uv3rv2T8+0TEsjI4zZARAjlwJFhQEBMi8aWxs1dJoagg/GSgjjWF8ufF5qoMhzQzZYU/BGwMCMDXYNwTTbSqxn3hNzxBMJwFyiLYr+biQ94MWOURpX8IkDzIG9gDYEaXBAHCqop/0yHXAAdqQy4WG/3rw9AOXPev2cepRDHieWGDU+8zYiZB5xc6B3tWxy580TI5+eNFMXaeSZo4ks40aqxcad3KN1A52JxOv40VqU9etVBtPwYPIVHHke2OUgiEIZjehwR5Q7DD4TvBdgi8CBlRAaDMeJAVTBRnVxiseMBxB4FKDfsyovAyo0GacUxpKqe73uR01sOBJgiYQnYD/+v1n3rBx98JzYpcBIKJHBIki5I3trIMlVJP40WtURiuNMGmsB1eSyZlJNXGgNCgcCieOuE4lCAID5GCGwAwrCKgFDO1FQXLAA8ok06jHJXCtyfWfXcYbAE8bcXFdAfjy7efVX3vdyr1nrN6+iCTiMQJB1OCy2n0Pn3rV+p2LrywXEqZQSx3j1UIjOMZrcePZkpFqibHGVfSFxtPxuZep4AFVMHLYMb5RjlEQBDJVUySjPcmhOhaZ48aJ2gC8gzbiakUeFTu/Gbhgzv9fVxFQAcyhH9c6pfruu3549iWfvf3C68brMaNTYTI8PvnAYpJaktyRpIbcHxkkIjSIKJGlBQUGD9SJKfB4shxUAWFGGQEB9InHgxOlyFN+KJcjWHIyHIKnbQlzgtDwNlFZD3yMNuGMClP4yNev2PIHr/9Uwuy+NFWYZB4twQAZUAcSIptgzSjKAdBBusoH6JAD7/i7Z57xpW+f87bhasEAiDz+avDUFfRBGxGgoh3s4HQqdPAYCj09OZEDVWaMAEkqZDlPqFY2pIBwfERgvOao1CKMKFMw5NQoUaMDIWgDoqLvSXLZCnybNiDn3KBM4fzVO6OP/+E/vpGx4nKElPZ2eJAI4B8tLznoGCoDGB0hZQjPCDCI6DAdpWEg5TB37Ty9+6ff+fJbNOOyMC+ZvQTlaKqQ5cJvvWGQs9ck1BNhpkRWueehIht2uCdZQReeCmeVBzYWeHBDTOR4HErQVjYoPBvYTotzh1+1/tC2JemB8d4t/XZ8Jd7S4g4dbSkCCJMEUESqwDDoOCmjwADIAIYBhnSIROuIJkDO0QarHO7OTSvNL3zs+vdIzmVxCJlZzWM4mgLWgnUCGBBhxhgFDNooZVoJGAMKqADa5qdPwRoR3q/Ii4E6LcwhwuE+e9OlP/yZF996pdStAErzCMBRQWIapQCSAOOI1ihQRWQYZB/4ARIGQSvAOGiVCE+D0tDPcfm/7/6pt2d59Kq5+7R86GjiWImsoqqgzBxVQJGpmk6C4owigKgSzALKtaL6V8CbaGFOvHK4j9125fb/88LbtiF6CirpSR7EW8CACkKGkjZeY6kBQygDCIP06jCiYyhDGB0FasyQt7//xT8+Xo1+p7usKHNRoAjOeVwjaGhbChijiBDMJsIvA3cD76dFOYQj7Bvt8A9tX37XWadsOYV6NF1dzZEdCQqgh90AmYKMgQ6BDONLI8DBGsDoAGUdATLAA5BwUrzjo88/7QP/e+k/9HaqUdpLkgkCRE45QYFC5MA52p41IKJMJ++FegJewVmIoxBmTfCXGLkXuJsW5DDC0f7iw1ev/dff3XxlZHQlXpLj3whXATFTr4KQA1NHWTKOxiMIA6gOYO0A3Z3DoAlQAzJawL++75LyP3/y0g8sXswSlLahCEkGK/r34L1lx8D8E3zYM1DAWW2UqtC2VLAWjIACwolLUqFYUC48c4zOzpRde4us21zGWbBGOTkCEfryTD+wa508Bxigxbgda3mMHWvPSn7r515w8xnLv/jTjJcdQgYIU47qTgyCAlNBIXXUjTVCRMwBvB8kYxiRCqpjwNgRWZLkUBmg1Xzq3vP+on8+V6NKO0kz5bVX/y8/+4J/w6vwL196E//zvRefwG3MgSrEUx2N0r4UsFYRAVVATjxkli+q80e/uJ5nXDIINmdsLOaTX1jKP3xsJV4FI8rMC1TBGC5Yfq7+A/A6Woxbfq7yeF79zms2/O/v3PXF1Wt2v4jUxkA+WeJBKogMgg7hoyHUjQIjiA6jdgCo8yhLu/n5v3rda9bt7PqleZ2KajuFjLC49wC/cO2/M3/eThDPm174L9x83/Op1EoYowTHTxUiB1Gbz2hQsAaMQK6cEK+Cs57ffeNGnnH5fsgsJI7Ocs4bfnIzewciPvDppZRLnFzBa9Nxvg38My3EpeM8oRf//ltv/9Nf+d+9jNpTERlD9AA+HkRdBUiBjFlmy76+0773yLK/6i0rqrQXgdw7kiwGkwNKksZ4b0A4AYFzOlG0PWMUkenoZuC8NVWedsEQeAteaMgEYuGFV+/nEzctIc/lZB+hhc4m5h1JVb4F3EeLcFkuPJlf/8sf3wRsYg5QT4zjX4pllghKu4mssm+kh7/5/Fv55Rf9UyNg/v6Lb2asVghHZyfc0SjOKr7dt86sRYQTHtKoh45yTqHgwXMUoaOUUyp4RsctJ1GgYCzzSt3670bluUCFFuA6ugim5J7fRvT5tLHYKV+4+3nc9tBVqAqj1UJTlwFUBQARbf+gcUo9EdqRGosKdGYDRMwjoYCgJ9DhwZZdRXbvK7B4aRUS4RDPI1vLDAxbirFy8gXqudKj7wbeSgtwXhUIRLka4bdpf41gqdSLyNT7Zq5YR/bQ+3buqiIH1tBmBDUWUOLxAboGNtAxvJWSXs8YBU5E5JSde2Pe8z/L+f1fegSJcyYpe3aXed//rsAaECFoEoU3Gy83AV+kyZx4Ya5TodOL/iNQYpawRpu+mPDMs2/nLTf8Lbka/v7zb+FbD13RnmEjUIg9SpsQwYtF1FMc20PngY2Uhndg8xqIwZkMPCesVFA+/uXFHBiOecXz9tDVnbJpa5kPf3YpD28pU4iVoKmMN/q3InInsJcmcmqZ88aL+q6OCheqMA0Cr0JXqcrvv/JdLFvyCAj89sv+gtf/wwcYrnTirNJOBCjGCtoOAeMwPqU8sp2u/esbQWN8hheLNxEGTyzptKw3i0DklC9/ex5fmag4gmodIkcImRahcHqk+hfAjU1eplHmMoe8IK/ySypMk0CByGV0FschiwDoKIwT2RSl/YhAIVaU1qQiYCwmS+gc3krnwEaKY3tBPdoIGAdTRJRIUqaLyGRnowqqQkdJCVqHACm83iBfAD5Jk7gcYa6q7qdHO/UvSiWmMW8DIzAw1sW/3/xGfunH/hFV4X23/h/2jvYRGdpSK/4TuopBxWKzKh0HNtF5YD1xdRDUo8aBGB5PbFJUpj+MRZSg9SgI6J/1WfkGsIcmcH2WOcsu5I9S5QJVgmm/JRg+/I3X8I0HngkKW/YvI7KKtHNHo7QEFYuKIUrG6BjcQsfAJqLa0KHhvxieiAAFk4ICAhB4FbwHY8CIMtsI4GH1/lz/FPg/NIHbnytz0f7N8rwFp+ibUGZAIALWwMa9yxAgsiAA7Ro0BW2JFWUQotownQObKQ9uJqqPosagxnFslILJmBTkXjAC/V1DDFV6yf3sfcBU4MahnfIZ4NOcZG54pzDXdPTTOREyfw5EzJhARCm42RGahQhQmmIqRIgrA435S3loKy6tomLwNuJ4CBwxowlLK2P81kv+mqed9W1uf/jp/PlnfoXhSs9sDRuZt1L/DOQbwCAnkZu3kjnH57wJ5RKC4JgoxYKiJ3uDzFhEtTHYn1xR3o7N6/ipAf9TFZGiBJU6/NTVn+cl13wU0iIvfuZ/sm7Hmfz7La+ho8Cs5DPOUOG3gd/iJHJ5ztxiOcegv6UEwY+mj3Y0Hj1J8xdvY0RzyiO76dr3CMWx3YetKDtOlCNlUhBFCQigFlAil6DKrCaqb/bCfwPf5yRxijJXjOzDdHbxp1KglyA4RgKNjgZlxqiZDJhiMkDf7g1UNhygo7bniBXl6aE4MiAoxfCZ79/AFWu+z0Vn3M4P7n0hn73reooRs5ooJYG/3LNIrgUSTgK3d6EwVxQjXhlV9cVKEBwjBZGZu8rH2wg1jrhygAWbv8Oy9V+gsm0F++rnoNaAGKaTAFYzILBGOTA6j//3gb+lv3sfB0bmU88cziqzmQoIPHPeADcC7zk5M5oB5oRinT4VfZtaguC4OAvOgSrTRPDWocZRHNnFwo3fYNGGWykObQeTomY1ahyQMt0UsJJjhGAqbNLcsvPAYowBZ5S5opDo74nwOWA3M8wVU2VOsLxVlbMIguOgCnGsWKOATEPARCDSeP5l4fpbWbDpNuLR3WAcuBhEmFmCJcOhKIKghAeMFWOZeyyr6qP8LvD/mGGuPs6sVx2Rs3qW6VtQguC4qApx5DEG9EQCxsWI+sb9Y4sfuZn5W76DrQyCdRCVOFkUsOKxeDIsc1egHlyZ/ytePgjczQxyUVGY7Uq9/F6W0kMQHCcF4miqo1GOi4ppBIzxGT277mPJRMDM2/Z9TG0EXAGiIiefYMmxkpOqRZjLAhHK4vhD4GXMICeO2U24Jkv11TwFQaAKhUgx5ngDpoBLK/RtuYOl675Ez64fIGl1KmBKNIsqOMlxkqEaEwSq+lLgBuDzzBCnqsxahkhy/hjBcYIUQEGEOSRQnepoLOixPAPjYqLaKAs33dY4Iuva8wD4DGzcCJhmUwRnPFY8KCAQBAp/LCq3AhVmgEOF2ao6yMvLffpcPE+ZKtQTwTmInFJPBfXh+zbm1tEZGDmWFeUB5j/y3YmA+Sod+x8B9eBiMI5W4iRvFEEwxSiX1or6U8C/MwNcvajMRuOdUuqp6++gJxYyWS68/Ln7eNWLdtE/r86mbR188H+X8937u8P3oc8FCoVDM5rHX1Ee3cPCTd9k0SO3UBzeCgjYCBBajQKWyaBRDgkCl/Mb1ZJ8Ehhimrk0FmajZQO8rlriIlWesloi3PiSXfzOLz5Cgworlla54txh/t+fns037+qlVFCC2b7e7LEWcn/kinJ5aBuL1t/C/E23URjZBcaBjQGhdQmWvFHKpCBQAZdyWlfK/wX+imnmukaYdayntyb66xiesjwXFs5L+ZmX7gAEEgNTip2TP37H/d14bzBGCWb31pkxkJoCeN+44LKxorz5W7jKAJipFeU2oIAjx5ATBIdTAUHfIiofAfYyjZww+9QtP2XhTE5AlsOKRTX6ulPIhSOosLLxczn7Bg3GEMxSquAKESZy9Gy9n4WPfJX5Ww+uKA+BmxrwtxXBkGPwIATBERRW5OjPA+9gGrkMZTYxnl5n+FUVTogxMDgSUU8MxY4ccg4RZWjMMV41GCGYzSwsGl3H2V/7AMUN9yFp5dCKctvyODIeTxAY4Ze95z3AbqaJQ5lVROQNKnoKJyhyyqadRb7y7QW86sXbwFjwAk4B4dO3LmJ4zFIuKsHspAhxDOft/SKlka+B6W0ETPsTXPg65ycWLDoYNsAfME2cEWYNL9Kj8ItME2fhbz6yEms91z9rH8VSxsBQzEc+s5z/umkxpQKzXTg2M9ARZ+BKoIbZIibjCQWB8EaQfwZ2MQ0cIswWBm4EPW36gkYZqzre9i+n8YFPL6e7K2XfQMyOPQWiSBEhmOWcKJ1RFVSYTSJJEeGJBMFihJ8F3j5NQcOs4A09NtdfUqaXs4pX2LSjiGoRYyCeEyETKOAkp2xq4IXZQoFIwtFZ8ORU9Y058i/APk6Qy5RZwRpepjlnMgOMTIbL3BNYySnNsqABIZYMEZ5QEAisMJbXAH/PCXLG0vb21Ijnj+mb4m5Qz7QIAgUMOUVqgDCbxCYlCJ6MKCj6i3sXynuBCifA7VlI2+sf4kVxlcvUM62CwOIpzLKgUaAgKUHwZFTA5py1bDs/AXyIE+CWbaetqSBi9Jc80y8IDDkFnX0dTWRShCD40bzTX1DkY0DCU+RyR3tTrhR4LtMsCBQQ9UR+tgWNEJERBMdEeRpWnw3cxFPkMEo7k1zeCDhmQBA4UqxPQZhVnKYEwbEynp8/oaAxnrY1ulNWdyzWV4ow7YJAgbJUEfGzbkZjJUNQguBYeOX6eUbOA37IU+B6RWhXbon+dAI9zIAgUKDLVTEos43B4yQnUxcCJ/iRBApDXt8A/CpPgRvySjvKPB3G8JPCzAgCVeiJK4goKLOCqEd8huCxeDKC4Ngo/DiedwCDHCennrZUynhuvcA5KDMiCBTojiogHlRmQcB48qhIre8UtsqZ1IcjBCUIjoUKKwuZ3AB8hOPk4kxoR2msbxRlxgSBBzpdFVBA2jZg0Jw87mS8dxXjfavJu/pIBgyqIEIQHBNRSGJ9AyL/ASjHwSUF2o7COaI8nxkUBKrQYaogSrsRnwNKVuhuhMvYvNVkhS5AcXlGJAYhIgiO09UevRL4HsfBeZR2EyfyijSmLMqMCoKSVAEPWFqfIt4DSlrqY2zeqYz3riCPO2BqNgOgBqwFhDYQqAoAIkqzCTjNedVxB43mtBeRUhbrT4oyo4JAgRLtcHSmiM9BDPWO+Yz1r6HSs4w8KjV+XHzG0Ywo1kDuQQhaVT0VjAHvQUSInTZ/Nd7wciPydmCIY+QiK7QTD89COY8ZFgQKFLUK+JYOGDWOWtcSRvtPo9azhNzEiOaYPOWJiIA1Sp4LCEELSjLhGWfexY3P+RC1pMQ/f+UXeGTXKURWaSphdZZyHfAJjpHLUtqKi/Q1npMjCCKtAdqCA36PGkeldxVj/adS61yEGjsZMD7lR5gKGoIWleXCgu5B/vAn3snKFWtBlN7SCG/8139GVZp6jGYE6jV97XEFTVpT2kWlLIvmwbWcDEEgEOU1UG2ZgBHNyV2RavcyxuafRq3cD2IOHZEdCwURMEYBIWg9uUJXcZwlvbugVgaXsWrBFiKXk+YOoXm8h2I31xRgNbCZY+B6umkfRZ7rKywRZlYQKIIViKUOSEsETBZ1UOld2ehgklLfoeG/ZhwPBYwBawkrzi0qsrDtwGL+5/ZX8MqrPkFWL/CRb76OauKIndJs6unLM7kO+DeOgcsToV10JPqaNAKUGRUECsQCJUlApWkryoKSxl2Mz1vdWFNOit0IiviMEyEyFTQErciIknvHn336N7jl/udRSwrcu/k8Iqu0iiTSVx9z0CSR0g6sl9UKzxBlVlIVVMEYJWg+VShaT9nVOal0MkTMRKWlHsbnncJ43yqyyRXlxo9PB0GxRglalzWKqvCtBy9FBAqR0kpEuRzkHOABfgQnKrSDzPI84+mfrYO/3EMhUqqJUIxaYmc+bJzZlLKtA4YZpx7yFGze2CA7sPAK0r7FZIetKE8nY8AaQAVQgtYkohRjWlWH8bwQeGDWfE2AoC9VZp/MC/O7Bnnri/+O5Qs3cfNdN/Cxb78SmrpZEqhCbNLJjsYLM0chq4MrMLz0Qg6cex2bRq9idE8nkWSYPGUmiIAxoDx1QaBWX6xe/hbwPAnnhZZnhGUqXI3Oxm4GfuY5H+alz/wPyGIuXXUfa7efxZ3rz6cY00xhRmMyimaGgkZzyBKISgysega7z7iWoaUXYYoF/P3SCBixyoxQEAPWKKBND/R6ImQ5GAPFOBwftxNVnqY5pwPr2v5mAF/gOnL6mIVEYGnfLvAOkhKURpnXMYQSND1oJKUgCSBMG59BnuALPQyccs1EwLyA4YVn402EzevYtIpoETAz/MVnYG1zj85yL3gPF505xtLFNUZGHfc+1M14zVCIlLYQFK3R639k0LT6QDDOReqi1ymzlMLHv/NKLjr1Hnq7DvD9e6/jro0XEzmCJlIgIqUgdVABmY6ASck6+tm36ir2nH4tY/PXAGDyFJvVTvrZvzWK0hzeC3Hk+fUbN/Gya/dQLKXgLXf8oJc//MfT2La7SBzCpi0oXBfJkx+fOSdCK6sYXWAyns0sVYiU7667jBv/4QMs6dvND7eeS6VewFklaC5HRsQJdjR5CupJuhaz99RnsWfNsxvPwogqJksApVmMBRGaolqHN7x8F69+yXbILSQODFxx8QF+942GN/3J2WiYU7YHy9N3bNCVwGaegNuxSWll3QvlilKPLvQ5zOaw2bp/KZv2LCWOCCHTAhSwpIgmIBwnfTRgaj0r2HPac9k7ETAHr4kRzRvdSytwTZrR5F7o6fQ8/8r9gEAuNHggt1xx/jCnr6zwwMaOMKdsA6p09S3l6U8aNH1LaWmurNf7nFkvsjpRBM2ioHrYew9RWod8CLQAGBALGECefEUZqCw4g12nP58Dq55GvTz/0PFYi9AmdjSqUIg9pWIOCEdQKERKuehRpU0ErsSLgY/xBJwr0bKMl06vejUzJAjUAwomAhuDLYEpCJGF8bifz5Vfy7xsiFXZVvrzfZT8IGBAYkBoUIW8DjZmdMn57DrzOg6suIIs7sLkSWPA33JUcFYx0pwHEQ8MOR7e0sGpp44Chkc5z/adJbbsLIY5ZTtRno5IHzDI43AgtKrhbs7sGuEMhGkXhIARIOqCeL4Q94DrBAyI0DDEIv5KfwUBYvWsTjdxcf1erqp9k/OT+8HXwAu4AgMrn8aeM17A4NKLyKMSJjsYMJXWPhq0IAIKCCePCIiBf//vFVxwxihLl40DAihp3fHPn1jJnoGIclFpE4GwMk64CPgaj8PFCS2rXOFpCDFtJvdCmoM1tNLdRMHhx2LdUFoO8TzBRICC6mGvgAARk3IMD8VruH+iPtXxEi6r3cWra//N6kUR209/IQMLz8Xb+NEV5XbgDJMUkJM/l3xoU5mff/u5vO76XaxeMc7wcMz/3rKI2+7qDSHTbhSTW572hEGTW1qWy/Q6lfa7TqYUJ5yxZBv7Ruazf7SHglOUoNnUgzFQPkUoLwOJQD1ozo8kQKwQA5lEfKP8NO6YqCsXJTx3YY0uWyfNarQNBWMUEVClKQqxsmlHiT/8p1MpxlBPwQgUC0r7CbzRFwB/wuNw3mirzmfmqeEStL06md6OYd792j/kmnNuY/2u0/id/3wXD2w/vQWu9g4hYwvQebpQWACaN+opMUBJIQe+sTlm+5DwE+emLOrISHKhHRx+dNZMkdOJAq9CqaCI0KYChQuNyjJgR9tcqpkZvUyURbSRegrPPe+bXHPBVyEtcdqp9/CKKz/N2m2/gSIIStCkkClC95kQzQPNmBYWsBY2DkV8+Ae9vP6CIRZ3tk/YWAMitAQjStsLenOjzwD+i6O43CgtyculiDraiAiMVLtALbgEUMaqXShB0yiYCLrOEKI+0IxpV7Cwa8zysR/2cONFQ/QVPKmn5VmryPQNaIJAQC5/3KABoQWJiD6DNlOI4Btrr+bfv/RLvOiyL/DDTRfxn996Nc4QupkmUYXOU4S4HzRjxhQsbBtxfOahbl53/hBGwCstSxWcDUdV0ysQ1SuACEg5jBNVWo0aehQuF23Db8VTx99+8Rf4l5t+niQXjEBkFeVkCzSHwgIoLQbNmXGxhR/ujbljR4lrVlWoZ0IrsyFoplkgcImKLDx6TuMQodWo5yKDLqQNGVEKDlSF2CoAStAMxkF5pYAAnhkngBG4bUsH5y6s013w5J6WJQLGMG2CQKEL1UseGzSqtJoCPD0BEdqXiBI0j+ZQXCJEXaCek8YZ2Fsx3LO7yAvXjJHkglfwKqiC0jrksK8LFmG6BMHVwOc4jKMFiXARylMTBArGQmERIJx0kYE7dpQpO09sob+c0V/K6Yg8CmReaAUi4CzTKghUuIijOBVai5euOnq28NQFgSkz2c3kzVkbHqwa/vfBbkTACI2gOXN+nYsX11jenTbCxitNZ4yiTJ8gEOV0PPOB/UxxktNajC4BziAIjpVyiDB1xYyABTxNYQQQUCZr77hlx1iZ7+8ocdXKKs9ePUZktHndjYaOZsYEq3CsOiJocLQUUTlPVQsEwZNQD3gQe7AO/Zjmk+U6QQyop6nksC7HArVc+PL6MttHHK88e4SuQt6UsFFABKxTQABlmgSBQeVC4C6mOFRoJap6OcGTCQEjU7cu9wuuA0x02LclVyAZVGwBUFqOFbBucg069T381PlDlCJP7oVmsAZUmV5BoHoZ8P6W3ToT5QIVguAxNAfbAR0rIZ4vGMckZZLQUFoqAGhOyyo6WLc/4qYNnbz8rBF8E3JRRDDWoEy7ILigZbfOjJcONXoqjyMIIRP3Q9fpgi3/iEsxDaC0vNjC7TtKnLewxhn9yUm8I01QY1HxdMkoTroAwzQKghWozAMGWu7oLDe6WmApRwtCyPRBz9mCONCMJ6e0BSNQz+FbWztYMy89aQGDeopje+k58DDl8Tob7fOoaBGDMk2CYKEYPR24HcCJUVpFlLIyjehGaQgC1anr/U8TJALNmVUiA1uGI/aMWRZ15swIEVQs4jNKwzvpPLCB0uhOnE9ItA8RBWU6BUExyzn10aDJclqGWDkdVYLgUR6KS8B1gubMOiIwlghbhmOWd1fImT4qBhWL8QkdQzvoPPAIhfF9GJ/jjWuU9YrBo0yvIBAjpzHFiRFaRS6cI8qkIFAwMRQXCeqZlQTIFfZXLF4B4cSJwRuDTauNgOkY2Eihsh9UUWMbAQOgCE4yLDkoIEybIDCiZzHFGVFahnI2QTBFPcTdgikwq1mBSmLIvOCsnlAHgxhsUqFraAudBzYS14ZQpmYzwmM0gkY8yjQLAuVsFRyQOaU1uFzKip7qDUETeS8T1TpXyLvyoQcvZzPlqVNjUQxRbZjOwc10TJSrjwHgjeOJKIIjx+CZAUGw0ov0AvudF6EVpJaVRukmaAqvQq0GnWWlsytj/1CEVyjGStMoiAMM4Jm1vEIpUqwoelwbZAaAuDpE54FNlIe24NIKKgY1lmNhJMdJxgwIgk6Tc2ojaExOSxDR1UAHJ13gPYDyhpfv5seevZeuUsb23UXe898ruWNtV1PDRhVQZjUR6C9lWAM5P5oaB+opjO2j6+AG2fAObF5DZWr+cpxiSZgBQVCY+vv6HU5EaQUCKxQsJ11QT4W3vHYrv/j6zUwSVq8a44IzR/nld57LnQ80L2x8Cujs7mY6ImV5T0rmBTH6I1aUc0oju+gcmAwYyTMwBm8inqqCpCjTLwgUVgO0zowmlZVprIhyEgVpJpyytMZrfmw3qEBqmGTo7k14/Yt3cPeDZ+IVjHByGchGFc0FDKDMOpmH1X0Zyzszcg/OPP6KsvUppeFtdB1YT2FsL+Iz1FjUOk6UI2O6BYEA3rMSwKmnJWSOlaKcZEGWw8oldXq7MsiFI8nEz9Xo6coZHXcYq5xMYiAbm6yoB1SZVRQwwFUrKjirJLkcETDeTq4ol4d3NI7I4vEDgJ8MGOOYLpGkTLcgUMAalgM4a2gB4lR0GcpJFlihMfiv1gylTg+ewygDQxGVqsUITaE5VHcqUY/Mutvs6xlcuqTOuQvqpF4A8DZqlEvG6TmwlY7BLcTVAfTR4b9jmp3kZYBwglBPQBWcg2KsiDBrKSxFKDkVmk6ML5PLYk66IIqUdZvLfP3OebzouTvBOfCAU/DCp29dRK0ulIpKM4iB+j6o90NxMfiMWaGew4runOvPGEWA3MSoGLoHN7Fo407qG8YoZSMogjeOmeQkZ+YF1bpw5uoq11wySKGY8+AjnXzr3j6YepxgllqoaIdTlGarDkix2MVSMZxkgchkvfu9p5Dm8OwrB+gqerbvjPnwp5bzpW/Np1hQmkYAhdENiikIUR9oDihtySskOazqyXj1+SN0dTqSXOjcv55F629h4ZavMbLvPHZkF854wAAIEEnGzApqdeG6Zwzwx7+0nr7+KgA+t/zXF5bwp+87FVUQYTZaVEil7Aqp0Gx5Kn0q2iMEzeCsMjQS8bt/dwanrajS1ZGxY0+BHftiSoUWaO0FfAIjDygda4TiQsCAekBpeQqoQuohtvC0FXWuOzOh23lKOx5iybovMW/7nZjaCDgldzGaGyBnmoX15ibIcmHZooTf/7kN9PXXIHEAGKf85Et2sHZjF5/48kLKRWUWKuYq/S5XodmiBSxTxRA0jXOKKjy8pYRXcJaW+j++GPAJjD6kJAegtERw3YCACCBMqyQFryCcGCOTVYqU8+alXLLSc3b3CL0772X+uluYt+MuSKtgY4hKIAknWyQpCDMkSFK49OxhFiyoQ2p5VCYQw9UXD/DpWxfgVTCizDZZzDKXxTSdKIsImk4ECrHSsgwNtT1Q36+4TiZKMDGIZVqoghG48oIaXR0e709s0aJgPf2dwpI+Yb4ZZuHOO5l3+0307F4LeQKu0AiYZookm8FLNQNVsJYnZI1iBJTZyaALnUFpNoWFBMExEgsopCOQDiso00YVIgfXvniMJfMzslxO6A6y3BZw4weYt/l7LHz4Zsr714PPwcbgirSCiJRg5hRiuOehLoYGY3r765AYGqwCyvfu76Val7Y9OvMqpBkgEFsQUQ6nqgucqtJsgixUjkMQCIgw7VTBRAoGqpkhzzluOvVdL8WRvSzcfBuLHrmF0uBmwICNwDlahU51NJEoiiBo697Fl4AIFCMQ0baagW7eUeQvPria3/+FDZQ6EiYJX7x1CZ+6ZRHFuH1DxpmcS864jyQp8sPtZ4OCCIeRBQ4kdDRBMAWFOAJrAeW4eBujYhoPWC7a8DUWTlQ8uhtEwBVpRYpgG0GTkmhMK8q9UIrrXHfhbVSTIt966Kq2m2cUC8r/3rKQrbtKPPfKA8RFz9p1nXzl2wtIMmmEUbtRBMj5rZf9Ba+6+uNkueNvPverfOjrr8VZEJQpCwwtwAvzaAFBoEAhVkSUYyIG7woTVaRzYCNrbn8PF375d1l+z38Sj+8DVwAb08ocOZFkKK3He8GahD985bv48zf8Cn//c2/iTS/8F9KMtlOMlbse6OLd71nN2/7xVP7nqwvJPW0ZMgB5Dsv79/LyKz4DanBRwque/t/0livknkkCqvQ6VZpOlE6EpgsCVaEQ+R89nBUhtwWMz+je+wBLHvoK87bdga0NgW0M+NvmP6+TqaBRQGgpaQ5nLNrNtRfcArlDTMZLLv8c//7V/0s9LSCibTav0YmaHbsXIjBaLbN/tJ8lS9aDydk1uIRa6jBMUUAoO4QmE2PQDqX5gkAV4lgx5skDxmZ1+rd9n8WP3Dy5opxUplaUy7QbQ44lR2k91sC+kXls3HsKZ53+PQAe2nEmlSTGGaVdCe3PGmVgrIff/eg7ef1zPkStXubfbv55amlMZJXDFB1NJlBSKNMigiCOwIg+ZoPM2xiXjLNg27dY/PBN9O66D/LkUAfTpiweR9a6DxOPd/JHn/wDXnfNR6kmZT74tRtRFUBpriCyyh3rL+LeTRfhFTIPBacohwiUndBcAkWFDlpAEKhCIVKMARTUOHIbE9cGGwP+JetuomP/w+CzyYBxRdqZIhjxWPEorSl2yg+3nslvfPhtKFBwEFtFCVrlfx+vgsjke+UxSo4mU7QAlFrlvFoEQAnmcNDECs6R2YjC6B7mb/oWi9Z/jfLABkDAxuAcs4WhETQt/zezyAkCQKuFTGBEeRKFVgiaSJC4Fb5l0hqmtkAEZxQlmItBExUs5epeFjz8NRZMBExhZCeIAVdkNjIohpxWJyhtKYgdTScRUKCJ0ly45uzvc8MVn2HX/uV88OuvZ6xWxhqCOSazcNaBW7ngy/+AHRoEE4ErMnsJIh5BUYJgRkSOJhOIgJgmSTJhzaJt/PXP/Bod3XvBZhSiOn/26bdgjRLMLWpgyeiDWLsbXC+znQIGj8UTBDMkNjRbk4Mm97Codw8dPXvx1R5IC5y9/CGMIZhjFCESiF0GJmKuEJTIJAhBMCMiQ/NZwNEkkYWHdpzO/euejimNkGcFPvv9G8g9wRwUCZRNDRDmCgVKUiMIZog1NJmCaf6efg9vfv/f8Jvv/1ve+I8f4LN3Xk/BKcEcXAQwSperg86loBFKUscQBDPCOppMwLTCQ2EHRnv57B3XYQRiByIEc4wCkcnocFVQw9whlEwVEYJgJhhH85lWeQLZWYK5HjSS02Frc6yjgYIkCMz0VwUEIWjCtT9B4CSnaOqQC8dFOUQf53OD8BjKkUQopoZC6ojE84QElEkqAPrYzwIKqChPToglQVAUYZoFgTiCIGhQwJFRliqoHBkEhz4fWQgIYISalamC1CmpUfKp8gdLFDUKoiQGcgEz9T4VsCi5y/lObZBNtW3E3gNgVbC5AcB4wXmDUcH6g2UO/djUZ+uFKDdEmcUdfM0doqACioKAF300hIxRSmSIF1QABESZLkHgaD5PEDSjiVYQBXJQD5qDoYDzOVVxJNaS2cmQGImVfSXYV1b2d+SMFXOqsSePcnKXkUQ5SexJo4xarNScklgltZ7MKrmdChvjwSgCgGJQhElGPE48t4449td3gXiekBfIDW6qotzi/KHPcWYppG6ibKNKqaNUjykljnI9oqtaaFR3NaazbqknVTSuQx4juWASAQU1gAGVqfcCoByHIPBy0Us9TXY5cAfTLQhUjggSD6iZLBHAebLOAbRnN653F65zP/0927h26acYLtXY36GMFjOSQoZzKc5mWJtOdSegoqiAoFgFg2JRppoWBBAVBEBpECbpobA7QiQ5Xxw+n021hSA5T0oO/0OPei+H/7wCwmFnaeAFUcGoNDqfqNJFPj4fV+0iGu8hGp2HrXQTjfcRjfbhKj1EI/3YpAAK4gEFODqIlCA4StoKQXMpcCdB8BSJCuoBD6qThUIeQVauYnp2E3Xtw3bvxS7YSLz0IQp92ykVR+gojBAVhzGFCiauYiQn80UiBTNVqIAeHg7CTIkl40vD57GpthgkY8Yc3ZmIB+NB/KH3KpAWkaSAyQrYtIAb7yUeWExxcDHx4BKikXlElV5cpQs31odNQAVo1KH3agCUYE6qt0LQXAzczY8UBALKZOVANvVSBDqHiUpDaP827Mr7KC9eR0fXHsqd+3A9uxvdSsHVKOIxKqgaUEER8FPvMYcCpUkKJuNLQ+excSpomk50KnwA/NRnPRRGWYSt9GCrnUQHQ2hwEcV9KylNVGFwSePHG1W3iIJaUAMqc+gYLqi2QtBcANwFOILgKOIFMvAecgsaK6Y4Sr70YeIV99HZu43SvK24JQ9T7N1BVzxKwSYgHgGMN6h34C2qgkdoYY2g+crQuayvLQHJaHmHh47kIBw6R0sj4pEFFBrdz2KK+1dQ2rOK4oEVuGoHkllMBmqYCiAlmJVGWyFozgLuJHz5WaACGaiCB0Qg7R6Fxesp9m+iOBEm8cp76Vn4CD3lfdjiGNYmRCqQOdQ7vBoUoV0VJOOmkXN4pLoEJKetiYLJD1UeIUkRk5Qp7l9KefepFPespjiwbOLzcqKxTlAmayp8VJS2Fww4mk1JEeohaOYgL6Cg+WRlRWDRdgrzdhCvvpPO075Lb/8GCr27iMqDlCTD5g4/FShkEaQxGS0pfO+KCuSuUQ2iqE3Jy0OMrz7A+Jp7AEEqXVPHbkvo2H4GHdvOojjxPh5eiK2aqW4HkDbteoKkFTqalcD3gCUEs5yABzLIPeRlj+3eg5x6Nx2n3E7vwocpLn2Acu8OOkyCqIC3jdKJ8gizXUEybhk5i4eqy0By5gSTH7aIoKBgR+dT3L+M0t5T6Nx6Dh07zsCN9+CqEQqoa6MFg2Cro9lEE1TqBLOTCqTgFdSBdowhp9xF54r76FjzXbpW3k1v+QDW1bCAZDE+dXgi5iIFDMqc4m2jDpeXhxk/ZT/jp/6A/Zd/HlProLTnFDq3nUV55xl0bD+LaLQbyQUEvANEaUlB6mg2lQSoE8wScsQDkHkBdPWDlFffQ/ncm5i/9Id09OxqrBTH3qBZAX/wtd5BTgAg4W+YR4WP4uMq46fcx/iauyEpNVapO3aeRtfGi+nYfnqj87F1QQ2TZQGUlhDUHU0nVdBx2legAgpkkCn4vmGi+ZspnPtV+k+/je5l99PRtZeCF/zUBpjWOsgQfrQQNIGACqQxEIN4su79DPfuYfi8b2LGeynuW9E4Yut+5DJKe1cRjXaCCGpb4IgtqDiaTJWawChCOwoBk0BmQDoqmDV3MO/8r9B12rfoXfQwHa6KKJDF+EawBNNwnXmgBvKD5QAa3U5l5QNUVq1l7zM+RXEiaDq2nU3PI5fSsfVcXKWMeEGjJm2xBVVHk4moIlRQ2kAgXvAZKJCX69izv0fvWd+k57yvMH/eBuLiKDaL8AfDJS8TnNyts3DMBrVFm6ktXc+BS25q3GLQs/5SujZdSOeW83DjRZCT+dxOIFBxQvPFhtFaDkLQumuqoBkkJcWdeg+dl36KBWd+na4F6ykXRjBpgdw7tNZJRvDUCQYFlOApyqLJEiXp38m+ieDZd8XnKexfTvdE6PSuu7KxUOCqFu9m+o62wAvjcuHLPE2n/JvAz9F6QsDUIY3ALNxG8cIv0H/el+k75Xa641HwDs0ivFqmRxBLzu3jp3DX2GoQzzQJxIPNwWaQxo2g6XnoSvoefAaFgcVIBj4KgTMTBD7ojNJ0CntoHUEm5DloZ43okptYfP5EuJzzVXo792BRNC2Q1ztpG+HoLFADmXm006mseIDKyrXsuep/6N54EX1rr6Z7/WW4aoQ3oE6ZHoHCPqe0At0DQhMFXtAMvIJfvIPOi77I/Cs+2lhHLkZVSErkB4tgJikgBDP/bFfh0UWCofO/ztDZ36G4dzXz7ns2vQ9dSXHfYhBQd+ILBIHucaA0ncouhGYJAZNAVlSiM+6m7+kfZdE5N9HTvwmXOfI8Jq91cvIERjwnSaAGkhKIUlu8kZ3L1rH3Gf9L9yNX0H/v8+ncdiYmOaGNtUDNbocamk2F3YJyEgVe8An4jhR74VdZds0HWXjm1+hwFchj/Jwb6oejs3Cha9SorGOYgUu/yMAFtza21frveR49D18xeawWh8A5XiLsdSI0XVHYU1e8giGYWbngM8g7a5Se/jn6n/FhFq2+nZKtomk5zF5C0AS5myxRRs+4g9E1dzeuvOm/+zp6H3wG0VgBHx3renSQ5exxWU7TeWHYGPYDCwlmjgc/byelSz7L4qf/J/1L7ydWJc+K5HkHrSEwBK3zQHIRUMZXPNCovU/7DP33PJ++tc/AjfeBEDy5cTE6+P8BW01E00mieO8AAAAASUVORK5CYII=) no-repeat 150% 100%;
-      background-color: #2238b3;
-      background-size: 205px;
-      background-blend-mode: luminosity;
-    }
-    .leftnav__header__title {
-      font-family: var(--text-font-family);
-      font-size: var(--title-font-size);
-      line-height: var(--title-line-height);
-      font-weight: 300;
-      color: #fff;
-      margin: 0;
-      padding: 0;
-    }
-    .leftnav__header__version {
-      color: #aab3ed;
-      font-family: var(--text-font-family);
-      font-size: var(--body-font-size);
-      line-height: var(--body-line-height);
-    }
-    @media screen and (max-width: 964px) {
-      .lh-leftnav {
-        display: none;
-      }
-    }
-    @media print {
-      .lh-leftnav {
-        display: none;
-      }
-    }
-  </style>
-  <nav class="lh-leftnav">
-    <div class="leftnav__header">
-      <h1 class="leftnav__header__title">Lighthouse</h1>
-      <div class="leftnav__header__version"><!-- fill me --></div>
-    </div>
-    <template id="tmpl-lh-leftnav__items">
-      <a href="#" class="lh-leftnav__item">
-        <span class="leftnav-item__category"><!-- fill me --></span>
-        <span class="leftnav-item__score"><!-- fill me --></span>
-      </a>
-    </template>
-  </nav>
-</template>
-
-<!-- Lighthouse header -->
-<template id="tmpl-lh-heading">
-  <style>
-    :root {
-      --report-header-height: 58px;
-      --report-header-bg-color: #fafafa;
-    }
-    .lh-header {
-      display: flex;
-      height: var(--report-header-height);
-      left: 0;
-      right: 0;
-      max-width: 100%; /* support text-overflow on url */
-      border-bottom: 1px solid var(--report-secondary-border-color);
-      position: fixed;
-      z-index: 1;
-      will-change: transform;
-      background-color: var(--report-header-bg-color);
-      margin-left: var(--report-menu-width);
-      align-items: center;
-      padding: 0 calc(var(--default-padding) * 2);
-    }
-    .lh-metadata {
-      flex: 1 1 0;
-      padding-right: calc(var(--default-padding) / 2);
-      line-height: 20px;
-      color: var(--secondary-text-color);
-      overflow-x: hidden;
-    }
-    .lh-metadata__results {
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-    .lh-metadata__url {
-      color: currentColor;
-    }
-    .lh-export {
-      position: relative;
-    }
-    .lh-export__button {
-      background-color: #fff;
-      border: 1px solid var(--report-border-color);
-      border-radius: 3px;
-      cursor: pointer;
-      outline: none;
-      height: 32px;
-      width: 48px;
-      background-repeat: no-repeat;
-      background-size: 20px;
-      background-position: 50% 50%;
-    }
-    .lh-export__button:focus,
-    .lh-export__button.active {
-      box-shadow: 1px 1px 3px #ccc;
-    }
-    .lh-export__button.active + .lh-export__dropdown {
-      opacity: 1;
-      clip: rect(0, 164px, 200px, 0);
-    }
-    .lh-export__dropdown {
-      position: absolute;
-      background-color: #fff;
-      border: 1px solid var(--report-border-color);
-      border-radius: 3px;
-      padding: calc(var(--default-padding) / 2) 0;
-      cursor: pointer;
-      top: 36px;
-      right: 0;
-      box-shadow: 1px 1px 3px #ccc;
-      min-width: 125px;
-      clip: rect(0, 164px, 0, 0);
-      opacity: 0;
-      transition: all 200ms cubic-bezier(0,0,0.2,1);
-    }
-    .lh-export__dropdown a {
-      display: block;
-      color: currentColor;
-      text-decoration: none;
-      white-space: nowrap;
-      padding: 0 12px;
-      line-height: 2;
-    }
-    .lh-export__dropdown a:hover,
-    .lh-export__dropdown a:focus {
-      background-color: #efefef;
-      outline: none;
-    }
-    .lh-export__dropdown .report-icon {
-      cursor: pointer;
-      background-repeat: no-repeat;
-      background-position: 8px 50%;
-      background-size: 18px;
-      background-color: transparent;
-      text-indent: 18px;
-    }
-    /* copy icon needs slight adjustments to look great */
-    .lh-export__dropdown .report-icon--copy {
-      background-size: 16px;
-      background-position: 9px 50%;
-    }
-    /* save-as-gist option hidden in report */
-    .lh-export__dropdown .lh-export--gist {
-      display: none;
-    }
-    .lh-config {
-      display: flex;
-    }
-    .lh-env {
-      padding: var(--default-padding) 0 var(--default-padding) calc(var(--default-padding) * 2);
-      left: 0;
-      top: 100%;
-      position: absolute;
-      width: 100%;
-      background-color: var(--report-header-bg-color);
-      border-top: 1px solid var(--report-secondary-border-color);
-      border-bottom: 1px solid var(--report-secondary-border-color);
-    }
-    .lh-env__title {
-      font-size: var(--header-font-size);
-    }
-    .lh-env__items {
-      margin: var(--default-padding) 0 0 0;
-    }
-    .lh-config__timestamp {
-      margin-right: 6px;
-    }
-    .lh-config__settings-toggle {
-      margin-left: 6px;
-    }
-    .lh-config__timestamp,
-    .lh-config__settings-toggle summary {
-      color: var(--secondary-text-color);
-    }
-    .lh-config__settings-toggle summary {
-      display: flex;
-      align-items: center;
-    }
-    .lh-config__settings-toggle .lh-toggle-arrow {
-      width: 16px;
-      height: 16px;
-      margin-left: 2px;
-    }
-    .lh-config__settings-toggle[open] .lh-toggle-arrow {
-      transform: rotateZ(90deg);
-    }
-    .lh-config__settings-toggle summary::-moz-list-bullet {
-      display: none;
-    }
-    .lh-config__settings-toggle summary::-webkit-details-marker {
-      display: none;
-    }
-    @media screen and (min-width: 965px) {
-      .lh-header {
-        width: var(--report-width);
-        right: initial;
-        left: initial;
-      }
-    }
-    @media screen and (max-width: 964px) {
-      .lh-export__dropdown {
-        right: 0;
-        left: initial;
-      }
-      .lh-header {
-        padding: 0 var(--default-padding);
-        margin-left: 0;
-      }
-    }
-    @media print {
-      .lh-header {
-        position: static;
-        margin-left: 0;
-      }
-    }
-  </style>
-  <div class="lh-header">
-    <div class="lh-metadata">
-      <div class="lh-metadata__results">Results for: <a href="" class="lh-metadata__url" target="_blank" rel="noopener"><!-- fill me --></a></div>
-      <div class="lh-config">
-        <span class="lh-config__timestamp"><!-- fill me --></span> &bullet;
-        <details class="lh-config__settings-toggle">
-          <summary>
-            <span>Runtime settings</span>
-            <span class="lh-toggle-arrow" title="See report's runtime settings"></span>
-          </summary>
-          <div class="lh-env">
-            <div class="lh-env__title">Runtime environment</div>
-            <ul class="lh-env__items">
-              <li class="lh-env__item">
-                <span class="lh-env__name">User agent:</span>
-                <b class="lh-env__item__ua"><!-- fill me --></b>
-              </li>
-              <template id="tmpl-lh-env__items">
-                <li class="lh-env__item">
-                  <span class="lh-env__name"><!-- fill me --></span>
-                  <span class="lh-env__description"><!-- fill me --></span>:
-                  <b class="lh-env__enabled"><!-- fill me --></b>
-                </li>
-              </template>
-            </ul>
-          </div>
-        </details>
-      </div>
-    </div>
-    <div class="lh-export">
-      <button class="report-icon report-icon--share lh-export__button" title="Export report"></button>
-      <div class="lh-export__dropdown">
-        <a href="#" class="report-icon report-icon--print" data-action="print-summary">Print Summary</a>
-        <a href="#" class="report-icon report-icon--print" data-action="print-expanded">Print Expanded</a>
-        <a href="#" class="report-icon report-icon--copy" data-action="copy">Copy JSON</a>
-        <a href="#" class="report-icon report-icon--download" data-action="save-html">Save as HTML</a>
-        <a href="#" class="report-icon report-icon--download" data-action="save-json">Save as JSON</a>
-        <a href="#" class="report-icon report-icon--open lh-export--viewer" data-action="open-viewer">Open in Viewer</a>
-        <a href="#" class="report-icon report-icon--open lh-export--gist" data-action="save-gist">Save as Gist</a>
-      </div>
-    </div>
-  </div>
-</template>
-
-<!-- Lighthouse footer -->
-<template id="tmpl-lh-footer">
-  <style>
-    .lh-footer {
-      min-height: 90px;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background-color: var(--report-header-bg-color);
-      border-top: 1px solid var(--report-secondary-border-color);
-    }
-
-    .lh-footer span {
-      text-align: center;
-    }
-  </style>
-  <footer class="lh-footer">
-    <span>
-      Generated by <b>Lighthouse</b> <span class="lh-footer__version"><!-- fill me --></span> on
-      <span class="lh-footer__timestamp"><!-- fill me --></span> |
-      <a href="https://github.com/GoogleChrome/Lighthouse/issues" target="_blank" rel="noopener">File an issue</a>
-    </span>
-  </footer>
-</template>
-
-<!-- Lighthouse score gauge -->
-<template id="tmpl-lh-gauge">
-  <style>
-    .lh-gauge {
-      --circle-size: calc(2.5 * var(--header-font-size));
-      --circle-size-half: calc(var(--circle-size) / 2);
-      --circle-background: #ccc;
-      --circle-border-width: 2px;
-      --inset-size: calc(var(--circle-size) - 2 * var(--circle-border-width));
-      --inset-color: #fff;
-      --transition-length: 1s;
-      width: var(--circle-size);
-      height: var(--circle-size);
-      background-color: var(--circle-background);
-      border-radius: 50%;
-    }
-    .lh-gauge--pass {
-      --circle-color: var(--pass-color);
-      color: var(--circle-color);
-    }
-    .lh-gauge--average {
-      --circle-color: var(--average-color);
-      color: var(--circle-color);
-    }
-    .lh-gauge--fail {
-      --circle-color: var(--fail-color);
-      color: var(--circle-color);
-    }
-    .lh-gauge__mask,
-    .lh-gauge__fill {
-      width: var(--circle-size);
-      height: var(--circle-size);
-      position: absolute;
-      transition: transform var(--transition-length);
-      border-radius: 50%;
-    }
-    .lh-gauge__mask {
-      clip: rect(0px, var(--circle-size), var(--circle-size), var(--circle-size-half));
-    }
-    .lh-gauge__mask .lh-gauge__fill {
-      clip: rect(0px, var(--circle-size-half), var(--circle-size), 0px);
-      background-color: var(--circle-color);
-      backface-visibility: hidden;
-    }
-    .lh-gauge__percentage {
-      --spacer: calc((var(--circle-size) - var(--inset-size)) / 2);
-      width: var(--inset-size);
-      height: var(--inset-size);
-      position: absolute;
-      margin-left: var(--spacer);
-      margin-top: var(--spacer);
-      background-color: var(--inset-color);
-      border-radius: inherit;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      font-size: var(--header-font-size);
-    }
-    .lh-gauge__wrapper {
-      display: inline-flex;
-      align-items: center;
-      flex-direction: column;
-      text-decoration: none;
-      color: inherit;
-      flex: 1;
-      min-width: auto;
-      position: relative;
-    }
-    .lh-scores-header .lh-gauge__wrapper {
-      width: calc(10.5 * var(--body-font-size));
-    }
-    .lh-gauge__label {
-      font-size: var(--body-font-size);
-      line-height: var(--body-line-height);
-      margin-top: calc(0.5 * var(--body-line-height));
-      text-align: center;
-    }
-  </style>
-  <a href="#" class="lh-gauge__wrapper">
-    <div class="lh-gauge" data-progress="0">
-      <div class="lh-gauge__circle">
-        <div class="lh-gauge__mask lh-gauge__mask--full">
-          <div class="lh-gauge__fill"></div>
-        </div>
-        <div class="lh-gauge__mask lh-gauge__mask--half">
-          <div class="lh-gauge__fill"></div>
-          <div class="lh-gauge__fill lh-gauge__fill--fix"></div>
-        </div>
-      </div>
-      <div class="lh-gauge__percentage"></div>
-    </div>
-    <div class="lh-gauge__label"><!-- fill me --></div>
-  </a>
-</template>
-
-<!-- Lighthouse crtiical request chains component -->
-<template id="tmpl-lh-crc">
-  <style>
-    .lh-crc .tree-marker {
-      width: 12px;
-      height: 26px;
-      display: block;
-      float: left;
-      background-position: top left;
-    }
-    .lh-crc .horiz-down {
-      background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><g fill="%23D8D8D8" fill-rule="evenodd"><path d="M16 12v2H-2v-2z"/><path d="M9 12v14H7V12z"/></g></svg>');
-    }
-    .lh-crc .right {
-      background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M16 12v2H0v-2z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
-    }
-    .lh-crc .up-right {
-      background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v14H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
-    }
-    .lh-crc .vert-right {
-      background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v27H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
-    }
-    .lh-crc .vert {
-      background: url('data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v26H7z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>');
-    }
-    .lh-crc .crc-tree {
-      font-size: 14px;
-      width: 100%;
-      overflow-x: auto;
-    }
-    .lh-crc .crc-node {
-      height: 26px;
-      line-height: 26px;
-      white-space: nowrap;
-    }
-    .lh-crc .crc-node__tree-value {
-      margin-left: 10px;
-    }
-    .lh-crc .crc-node__chain-duration {
-      font-weight: 700;
-    }
-    .lh-crc .crc-node__tree-hostname {
-      color: #595959;
-    }
-    .lh-crc .crc-initial-nav {
-      color: #595959;
-      font-style: italic;
-    }
-  </style>
-  <div class="lh-score__description">
-    Longest chain: <b class="lh-crc__longest_duration"><!-- fill me: longestChain.duration --></b>
-    over <b class="lh-crc__longest_length"><!-- fill me: longestChain.length --></b> requests, totalling
-    <b class="lh-crc__longest_transfersize"><!-- fill me: longestChain.length --></b>
-  </div>
-  <div class="lh-crc">
-    <details class="lh-details">
-      <summary><!-- fill me --></summary>
-      <div class="crc-initial-nav">Initial Navigation</div>
-      <!-- stamp for each chain -->
-      <template id="tmpl-lh-crc__chains">
-        <div class="crc-node">
-          <span class="crc-node__tree-marker">
-            <!-- fill me -->
-          </span>
-          <span class="crc-node__tree-value">
-            <span class="crc-node__tree-file"><!-- fill me: node.request.url.file --></span>
-            <span class="crc-node__tree-hostname">(<!-- fill me: node.request.url.host -->)</span>
-            <!-- fill me -->
-          </span>
-        </div>
-      </template>
-    </details>
-  </div>
-</template>
diff --git a/front_end/audits2/module.json b/front_end/audits2/module.json
deleted file mode 100644
index 2ec939f..0000000
--- a/front_end/audits2/module.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "audits2",
-            "title": "Audits",
-            "order": 90,
-            "className": "Audits2.Audits2Panel"
-        }
-    ],
-    "dependencies": [
-        "components",
-        "emulation",
-        "timeline",
-        "inspector_main",
-        "sdk",
-        "services",
-        "ui"
-    ],
-    "scripts": [
-        "lighthouse/renderer/util.js",
-        "lighthouse/renderer/dom.js",
-        "lighthouse/renderer/category-renderer.js",
-        "lighthouse/renderer/details-renderer.js",
-        "lighthouse/renderer/crc-details-renderer.js",
-        "lighthouse/renderer/report-renderer.js",
-        "Audits2Panel.js",
-        "Audits2Dialog.js",
-        "Audits2StatusView.js",
-        "Audits2ProtocolService.js"
-    ],
-    "resources": [
-        "audits2Dialog.css",
-        "audits2Panel.css",
-        "lighthouse/report-styles.css",
-        "lighthouse/templates.html"
-    ]
-}
diff --git a/front_end/audits2_test_runner/Audits2TestRunner.js b/front_end/audits2_test_runner/Audits2TestRunner.js
deleted file mode 100644
index 4d0261b..0000000
--- a/front_end/audits2_test_runner/Audits2TestRunner.js
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-/**
- * @return {!Audits2.Audits2Panel}
- */
-Audits2TestRunner._panel = function() {
-  return /** @type {!Object} **/ (UI.panels).audits2;
-};
-
-/**
- * @return {?Element}
- */
-Audits2TestRunner.getResultsElement = function() {
-  return Audits2TestRunner._panel()._auditResultsElement;
-};
-
-/**
- * @return {?Element}
- */
-Audits2TestRunner.getDialogElement = function() {
-  return Audits2TestRunner._panel()._dialog._dialog.contentElement.shadowRoot.querySelector('.audits2-view');
-};
-
-/**
- * @return {?Element}
- */
-Audits2TestRunner.getRunButton = function() {
-  const dialog = Audits2TestRunner.getDialogElement();
-  return dialog && dialog.querySelectorAll('button')[0];
-};
-
-/**
- * @return {?Element}
- */
-Audits2TestRunner.getCancelButton = function() {
-  const dialog = Audits2TestRunner.getDialogElement();
-  return dialog && dialog.querySelectorAll('button')[1];
-};
-
-Audits2TestRunner.openDialog = function() {
-  const resultsElement = Audits2TestRunner.getResultsElement();
-  resultsElement.querySelector('button').click();
-};
-
-/**
- * @param {function(string)} onMessage
- */
-Audits2TestRunner.addStatusListener = function(onMessage) {
-  TestRunner.addSniffer(Audits2.Audits2Dialog.prototype, '_updateStatus', onMessage, true);
-};
-
-/**
- * @return {!Promise<!Object>}
- */
-Audits2TestRunner.waitForResults = function() {
-  return new Promise(resolve => {
-    TestRunner.addSniffer(Audits2.Audits2Panel.prototype, '_buildReportUI', resolve);
-  });
-};
-
-/**
- * @param {?Element} checkboxContainer
- * @return {string}
- */
-Audits2TestRunner._checkboxStateLabel = function(checkboxContainer) {
-  if (!checkboxContainer)
-    return 'missing';
-
-  const label = checkboxContainer.textElement.textContent;
-  const checkedLabel = checkboxContainer.checkboxElement.checked ? 'x' : ' ';
-  return `[${checkedLabel}] ${label}`;
-};
-
-/**
- * @param {?Element} button
- * @return {string}
- */
-Audits2TestRunner._buttonStateLabel = function(button) {
-  if (!button)
-    return 'missing';
-
-  const enabledLabel = button.disabled ? 'disabled' : 'enabled';
-  const hiddenLabel = window.getComputedStyle(button).getPropertyValue('visibility');
-  return `${button.textContent}: ${enabledLabel} ${hiddenLabel}`;
-};
-
-Audits2TestRunner.dumpDialogState = function() {
-  TestRunner.addResult('\n========== Audits2 Dialog State ==========');
-  const dialog = Audits2TestRunner._panel()._dialog && Audits2TestRunner._panel()._dialog._dialog;
-  TestRunner.addResult(dialog ? 'Dialog is visible\n' : 'No dialog');
-  if (!dialog)
-    return;
-
-  const dialogElement = Audits2TestRunner.getDialogElement();
-  const checkboxes = [...dialogElement.querySelectorAll('.checkbox')];
-  checkboxes.forEach(element => {
-    TestRunner.addResult(Audits2TestRunner._checkboxStateLabel(element));
-  });
-
-  const helpText = dialogElement.querySelector('.audits2-dialog-help-text');
-  if (!helpText.classList.contains('hidden'))
-    TestRunner.addResult(`Help text: ${helpText.textContent}`);
-
-  TestRunner.addResult(Audits2TestRunner._buttonStateLabel(Audits2TestRunner.getRunButton()));
-  TestRunner.addResult(Audits2TestRunner._buttonStateLabel(Audits2TestRunner.getCancelButton()) + '\n');
-};
\ No newline at end of file
diff --git a/front_end/audits2_test_runner/module.json b/front_end/audits2_test_runner/module.json
deleted file mode 100644
index 7c12c77..0000000
--- a/front_end/audits2_test_runner/module.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "audits2"
-  ],
-  "scripts": [
-    "Audits2TestRunner.js"
-  ]
-}
\ No newline at end of file
diff --git a/front_end/audits2_worker.js b/front_end/audits2_worker.js
deleted file mode 100644
index f299a02..0000000
--- a/front_end/audits2_worker.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// Release build has Runtime.js bundled.
-if (!self.Runtime)
-  self.importScripts('Runtime.js');
-Runtime.startWorker('audits2_worker');
diff --git a/front_end/audits2_worker.json b/front_end/audits2_worker.json
deleted file mode 100644
index 7da746e..0000000
--- a/front_end/audits2_worker.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "modules": [
-        { "name": "worker_service", "type": "autostart" },
-        { "name": "audits2_worker", "type": "remote" }
-    ]
-}
diff --git a/front_end/audits2_worker/Audits2Service.js b/front_end/audits2_worker/Audits2Service.js
deleted file mode 100644
index f19bee6..0000000
--- a/front_end/audits2_worker/Audits2Service.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @interface
- */
-class LighthousePort {
-  /**
-   * @param {!string} eventName, 'message', 'close'
-   * @param {function(string|undefined)} cb
-   */
-  on(eventName, cb) {
-  }
-
-  /**
-   * @param {string} message
-   */
-  send(message) {
-  }
-
-  close() {
-  }
-}
-
-/**
- * @implements {LighthousePort}
- * @implements {Service}
- * @unrestricted
- */
-var Audits2Service = class {  // eslint-disable-line
-  /**
-   * @override
-   * @param {function(string)}
-   */
-  setNotify(notify) {
-    this._notify = notify;
-  }
-
-  /**
-   * @return {!Promise<!ReportRenderer.ReportJSON>}
-   */
-  start(params) {
-    if (Runtime.queryParam('isUnderTest'))
-      this._disableLoggingForTest();
-
-    self.listenForStatus(message => {
-      this.statusUpdate(message[1]);
-    });
-
-    return Promise.resolve()
-        .then(_ => self.runLighthouseInWorker(this, params.url, {flags: params.flags}, params.categoryIDs))
-        .then(/** @type {!ReportRenderer.ReportJSON} */ result => {
-          // Keep all artifacts on the result, no trimming
-          return result;
-        })
-        .catch(err => ({
-                 fatal: true,
-                 message: err.message,
-                 stack: err.stack,
-               }));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  stop() {
-    this.close();
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {!Object=} params
-   * @return {!Promise}
-   */
-  dispatchProtocolMessage(params) {
-    this._onMessage(params['message']);
-    return Promise.resolve();
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  dispose() {
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {string} message
-   */
-  statusUpdate(message) {
-    this._notify('statusUpdate', {message: message});
-  }
-
-  /**
-   * @param {string} message
-   */
-  send(message) {
-    this._notify('sendProtocolMessage', {message: message});
-  }
-
-  close() {
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {function(string|undefined)} cb
-   */
-  on(eventName, cb) {
-    if (eventName === 'message')
-      this._onMessage = cb;
-    if (eventName === 'close')
-      this._onClose = cb;
-  }
-
-  _disableLoggingForTest() {
-    console.log = () => undefined;  // eslint-disable-line no-console
-  }
-};
-
-// Make lighthouse and traceviewer happy.
-global = self;
-global.isVinn = true;
-global.document = {};
-global.document.documentElement = {};
-global.document.documentElement.style = {
-  WebkitAppearance: 'WebkitAppearance'
-};
diff --git a/front_end/audits2_worker/lighthouse/LICENSE b/front_end/audits2_worker/lighthouse/LICENSE
deleted file mode 100644
index a4c5efd..0000000
--- a/front_end/audits2_worker/lighthouse/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright 2014 Google Inc.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/front_end/audits2_worker/lighthouse/README.chromium b/front_end/audits2_worker/lighthouse/README.chromium
deleted file mode 100644
index 1b58f4c..0000000
--- a/front_end/audits2_worker/lighthouse/README.chromium
+++ /dev/null
@@ -1,8 +0,0 @@
-Name: Lighthouse is a performance auditing component written in JavaScript that works in the browser.
-Short Name: lighthouse
-URL: github.com/GoogleChrome/lighthouse
-License: Apache License 2.0
-Security Critical: no
-
-This directory contains Chromium's version of lighthouse with tests, demo and sources removed.
-
diff --git a/front_end/audits2_worker/lighthouse/lighthouse-background.js b/front_end/audits2_worker/lighthouse/lighthouse-background.js
deleted file mode 100644
index c7b59ac..0000000
--- a/front_end/audits2_worker/lighthouse/lighthouse-background.js
+++ /dev/null
@@ -1,73942 +0,0 @@
-// lighthouse, browserified. 2.9.1 (f9171e0133fa0bffd8cd419ac3ec91861d5d5713)
-require=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 a(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;}({"../audits/accessibility/accesskeys":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class Accesskeys extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'accesskeys',
-description:'`[accesskey]` values are unique',
-failureDescription:'`[accesskey]` values are not unique',
-helpText:'Access keys let users quickly focus a part of the page. For proper '+
-'navigation, each access key must be unique. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/accesskeys?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=Accesskeys;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-allowed-attr":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ARIAAllowedAttr extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-allowed-attr',
-description:'`[aria-*]` attributes match their roles',
-failureDescription:'`[aria-*]` attributes do not match their roles',
-helpText:'Each ARIA `role` supports a specific subset of `aria-*` attributes. '+
-'Mismatching these invalidates the `aria-*` attributes. [Learn '+
-'more](https://dequeuniversity.com/rules/axe/2.2/aria-allowed-attr?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ARIAAllowedAttr;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-required-attr":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ARIARequiredAttr extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-required-attr',
-description:'`[role]`s have all required `[aria-*]` attributes',
-failureDescription:'`[role]`s do not have all required `[aria-*]` attributes',
-helpText:'Some ARIA roles have required attributes that describe the state '+
-'of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-attr?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ARIARequiredAttr;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-required-children":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class AriaRequiredChildren extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-required-children',
-description:'Elements with `[role]` that require specific children `[role]`s, are present',
-failureDescription:'Elements with `[role]` that require specific children `[role]`s, '+
-'are missing.',
-helpText:'Some ARIA parent roles must contain specific child roles to perform '+
-'their intended accessibility functions. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-children?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=AriaRequiredChildren;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-required-parent":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class AriaRequiredParent extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-required-parent',
-description:'`[role]`s are contained by their required parent element',
-failureDescription:'`[role]`s are not contained by their required parent element',
-helpText:'Some ARIA child roles must be contained by specific parent roles to '+
-'properly perform their intended accessibility functions. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-parent?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=AriaRequiredParent;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-roles":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class AriaRoles extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-roles',
-description:'`[role]` values are valid',
-failureDescription:'`[role]` values are not valid',
-helpText:'ARIA roles must have valid values in order to perform their '+
-'intended accessibility functions. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-roles?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=AriaRoles;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-valid-attr-value":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ARIAValidAttr extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-valid-attr-value',
-description:'`[aria-*]` attributes have valid values',
-failureDescription:'`[aria-*]` attributes do not have valid values',
-helpText:'Assistive technologies, like screen readers, can\'t interpret ARIA '+
-'attributes with invalid values. [Learn '+
-'more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr-value?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ARIAValidAttr;
-
-},{"./axe-audit":1}],"../audits/accessibility/aria-valid-attr":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ARIAValidAttr extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'aria-valid-attr',
-description:'`[aria-*]` attributes are valid and not misspelled',
-failureDescription:'`[aria-*]` attributes are not valid or misspelled',
-helpText:'Assistive technologies, like screen readers, can\'t interpret ARIA '+
-'attributes with invalid names. [Learn '+
-'more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ARIAValidAttr;
-
-},{"./axe-audit":1}],"../audits/accessibility/audio-caption":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class AudioCaption extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'audio-caption',
-description:'`<audio>` elements contain a `<track>` element with `[kind="captions"]`',
-failureDescription:'`<audio>` elements are missing a `<track>` element with '+
-'`[kind="captions"]`.',
-helpText:'Captions make audio elements usable for deaf or hearing-impaired users, '+
-'providing critical information such as who is talking, what they\'re saying, '+
-'and other non-speech information. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/audio-caption?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=AudioCaption;
-
-},{"./axe-audit":1}],"../audits/accessibility/button-name":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ButtonName extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'button-name',
-description:'Buttons have an accessible name',
-failureDescription:'Buttons do not have an accessible name',
-helpText:'When a button doesn\'t have an accessible name, screen readers announce it as '+
-'"button", making it unusable for users who rely on screen readers. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/button-name?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ButtonName;
-
-},{"./axe-audit":1}],"../audits/accessibility/bypass":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class Bypass extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'bypass',
-description:'The page contains a heading, skip link, or landmark region',
-failureDescription:'The page does not contain a heading, skip link, or landmark region',
-helpText:'Adding ways to bypass repetitive content lets keyboard users navigate the page '+
-'more efficiently. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/bypass?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=Bypass;
-
-},{"./axe-audit":1}],"../audits/accessibility/color-contrast":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ColorContrast extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'color-contrast',
-description:'Background and foreground colors have a sufficient contrast ratio',
-failureDescription:'Background and foreground colors do not have a '+
-'sufficient contrast ratio.',
-helpText:'Low-contrast text is difficult or impossible for many users to read. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/color-contrast?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ColorContrast;
-
-},{"./axe-audit":1}],"../audits/accessibility/definition-list":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class DefinitionList extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'definition-list',
-description:'`<dl>`\'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` '+
-'or `<template>` elements.',
-failureDescription:'`<dl>`\'s do not contain only properly-ordered `<dt>` and `<dd>` '+
-'groups, `<script>` or `<template>` elements.',
-helpText:'When definition lists are not properly marked up, screen readers may produce '+
-'confusing or inaccurate output. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/definition-list?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=DefinitionList;
-
-},{"./axe-audit":1}],"../audits/accessibility/dlitem":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class DLItem extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'dlitem',
-description:'Definition list items are wrapped in `<dl>` elements',
-failureDescription:'Definition list items are not wrapped in `<dl>` elements',
-helpText:'Definition list items (`<dt>` and `<dd>`) must be wrapped in a '+
-'parent `<dl>` element to ensure that screen readers can properly announce them. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/dlitem?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=DLItem;
-
-},{"./axe-audit":1}],"../audits/accessibility/document-title":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class DocumentTitle extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'document-title',
-description:'Document has a `<title>` element',
-failureDescription:'Document does not have a `<title>` element',
-helpText:'Screen reader users use page titles to get an overview of the contents of '+
-'the page. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/document-title?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=DocumentTitle;
-
-},{"./axe-audit":1}],"../audits/accessibility/duplicate-id":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class DuplicateId extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'duplicate-id',
-description:'`[id]` attributes on the page are unique',
-failureDescription:'`[id]` attributes on the page are not unique',
-helpText:'The value of an id attribute must be unique to prevent '+
-'other instances from being overlooked by assistive technologies. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/duplicate-id?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=DuplicateId;
-
-},{"./axe-audit":1}],"../audits/accessibility/frame-title":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class FrameTitle extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'frame-title',
-description:'`<frame>` or `<iframe>` elements have a title',
-failureDescription:'`<frame>` or `<iframe>` elements do not have a title',
-helpText:'Screen reader users rely on frame titles to describe the contents of frames. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/frame-title?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=FrameTitle;
-
-},{"./axe-audit":1}],"../audits/accessibility/html-has-lang":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class HTMLHasLang extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'html-has-lang',
-description:'`<html>` element has a `[lang]` attribute',
-failureDescription:'`<html>` element does not have a `[lang]` attribute',
-helpText:'If a page doesn\'t specify a lang attribute, a screen reader assumes '+
-'that the page is in the default language that the user chose when setting up the '+
-'screen reader. If the page isn\'t actually in the default language, then the screen '+
-'reader might not announce the page\'s text correctly. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/html-lang?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=HTMLHasLang;
-
-},{"./axe-audit":1}],"../audits/accessibility/html-lang-valid":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class HTMLLangValid extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'html-lang-valid',
-description:'`<html>` element has a valid value for its `[lang]` attribute',
-failureDescription:'`<html>` element does not have a valid value for '+
-'its `[lang]` attribute.',
-helpText:'Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) '+
-'helps screen readers announce text properly. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=HTMLLangValid;
-
-},{"./axe-audit":1}],"../audits/accessibility/image-alt":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ImageAlt extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'image-alt',
-description:'Image elements have `[alt]` attributes',
-failureDescription:'Image elements do not have `[alt]` attributes',
-helpText:'Informative elements should aim for short, descriptive alternate text. '+
-'Decorative elements can be ignored with an empty alt attribute.'+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/image-alt?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ImageAlt;
-
-},{"./axe-audit":1}],"../audits/accessibility/input-image-alt":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class InputImageAlt extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'input-image-alt',
-description:'`<input type="image">` elements have `[alt]` text',
-failureDescription:'`<input type="image">` elements do not have `[alt]` text',
-helpText:'When an image is being used as an `<input>` button, providing alternative text '+
-'can help screen reader users understand the purpose of the button. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/input-image-alt?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=InputImageAlt;
-
-},{"./axe-audit":1}],"../audits/accessibility/label":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class Label extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'label',
-description:'Form elements have associated labels',
-failureDescription:'Form elements do not have associated labels',
-helpText:'Labels ensure that form controls are announced properly by assistive '+
-'technologies, like screen readers. [Learn '+
-'more](https://dequeuniversity.com/rules/axe/2.2/label?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=Label;
-
-},{"./axe-audit":1}],"../audits/accessibility/layout-table":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class LayoutTable extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'layout-table',
-description:'Presentational `<table>` elements avoid using `<th>`, `<caption>` or the '+
-'`[summary]` attribute.',
-failureDescription:'Presentational `<table>` elements do not avoid using `<th>`, '+
-'`<caption>` or the `[summary]` attribute.',
-helpText:'A table being used for layout purposes should not include data elements, '+
-'such as the th or caption elements or the summary attribute, because this can '+
-'create a confusing experience for screen reader users. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/layout-table?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=LayoutTable;
-
-},{"./axe-audit":1}],"../audits/accessibility/link-name":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class LinkName extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'link-name',
-description:'Links have a discernible name',
-failureDescription:'Links do not have a discernible name',
-helpText:'Link text (and alternate text for images, when used as links) that is '+
-'discernible, unique, and focusable improves the navigation experience for '+
-'screen reader users. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/link-name?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=LinkName;
-
-},{"./axe-audit":1}],"../audits/accessibility/listitem":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ListItem extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'listitem',
-description:'List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements',
-failureDescription:'List items (`<li>`) are not contained within `<ul>` '+
-'or `<ol>` parent elements.',
-helpText:'Screen readers require list items (`<li>`) to be contained within a '+
-'parent `<ul>` or `<ol>` to be announced properly. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/listitem?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ListItem;
-
-},{"./axe-audit":1}],"../audits/accessibility/list":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class List extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'list',
-description:'Lists contain only `<li>` elements and script supporting elements '+
-'(`<script>` and `<template>`).',
-failureDescription:'Lists do not contain only `<li>` elements and script '+
-'supporting elements (`<script>` and `<template>`).',
-helpText:'Screen readers have a specific way of announcing lists. Ensuring proper list '+
-'structure aids screen reader output. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/list?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=List;
-
-},{"./axe-audit":1}],"../audits/accessibility/manual/custom-controls-labels":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class CustomControlsLabels extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'custom-controls-labels',
-helpText:'Custom interactive controls have associated labels, provided by aria-label or aria-labelledby. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).',
-description:'Custom controls have associated labels'},
-super.meta);
-}}
-
-
-module.exports=CustomControlsLabels;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/custom-controls-roles":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class CustomControlsRoles extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'custom-controls-roles',
-helpText:'Custom interactive controls have appropriate ARIA roles. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).',
-description:'Custom controls have ARIA roles'},
-super.meta);
-}}
-
-
-module.exports=CustomControlsRoles;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/focus-traps":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class FocusTraps extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'focus-traps',
-helpText:'A user can tab into and out of any control or region without accidentally trapping their focus. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).',
-description:'User focus is not accidentally trapped in a region'},
-super.meta);
-}}
-
-
-module.exports=FocusTraps;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/focusable-controls":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class FocusableControls extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'focusable-controls',
-helpText:'Custom interactive controls are keyboard focusable and display a focus indicator. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).',
-description:'Interactive controls are keyboard focusable'},
-super.meta);
-}}
-
-
-module.exports=FocusableControls;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/heading-levels":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class HeadingLevels extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'heading-levels',
-helpText:'Headings are used to create an outline for the page and heading levels are not skipped. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#take_advantage_of_headings_and_landmarks).',
-description:'Headings don\'t skip levels'},
-super.meta);
-}}
-
-
-module.exports=HeadingLevels;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/logical-tab-order":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class LogicalTabOrder extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'logical-tab-order',
-helpText:'Tabbing through the page follows the visual layout. Users cannot focus elements that are offscreen. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).',
-description:'The page has a logical tab order'},
-super.meta);
-}}
-
-
-module.exports=LogicalTabOrder;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/managed-focus":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class ManagedFocus extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'managed-focus',
-helpText:'If new content, such as a dialog, is added to the page, the user\'s focus is directed to it. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).',
-description:'The user\'s focus is directed to new content added to the page'},
-super.meta);
-}}
-
-
-module.exports=ManagedFocus;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/offscreen-content-hidden":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-
-class OffscreenContentHidden extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'offscreen-content-hidden',
-helpText:'Offscreen content is hidden with display: none or aria-hidden=true. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).',
-description:'Offscreen content is hidden from assistive technology'},
-super.meta);
-}}
-
-
-module.exports=OffscreenContentHidden;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/use-landmarks":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class UseLandmarks extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'use-landmarks',
-helpText:'Landmark elements (<main>, <nav>, etc.) are used to improve the keyboard navigation of the page for assistive technology. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#take_advantage_of_headings_and_landmarks).',
-description:'HTML5 landmark elements are used to improve navigation'},
-super.meta);
-}}
-
-
-module.exports=UseLandmarks;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/manual/visual-order-follows-dom":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class VisualOrderFollowsDOM extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'visual-order-follows-dom',
-helpText:'DOM order matches the visual order, improving navigation for assistive technology. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).',
-description:'Visual order on the page follows DOM order'},
-super.meta);
-}}
-
-
-module.exports=VisualOrderFollowsDOM;
-
-},{"../../manual/manual-audit":4}],"../audits/accessibility/meta-refresh":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class MetaRefresh extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'meta-refresh',
-description:'The document does not use `<meta http-equiv="refresh">`',
-failureDescription:'The document uses `<meta http-equiv="refresh">`',
-helpText:'Users do not expect a page to refresh automatically, and doing so will move '+
-'focus back to the top of the page. This may create a frustrating or '+
-'confusing experience. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/meta-refresh?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=MetaRefresh;
-
-},{"./axe-audit":1}],"../audits/accessibility/meta-viewport":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class MetaViewport extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'meta-viewport',
-description:'`[user-scalable="no"]` is not used in the `<meta name="viewport">` '+
-'element and the `[maximum-scale]` attribute is not less than 5.',
-failureDescription:'`[user-scalable="no"]` is used in the `<meta name="viewport">` '+
-'element or the `[maximum-scale]` attribute is less than 5.',
-helpText:'Disabling zooming is problematic for users with low vision who rely on screen '+
-'magnification to properly see the contents of a web page. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/meta-viewport?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=MetaViewport;
-
-},{"./axe-audit":1}],"../audits/accessibility/object-alt":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ObjectAlt extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'object-alt',
-description:'`<object>` elements have `[alt]` text',
-failureDescription:'`<object>` elements do not have `[alt]` text',
-helpText:'Screen readers cannot translate non-text content. Adding alt text to `<object>` '+
-'elements helps screen readers convey meaning to users. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/object-alt?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ObjectAlt;
-
-},{"./axe-audit":1}],"../audits/accessibility/tabindex":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class TabIndex extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'tabindex',
-description:'No element has a `[tabindex]` value greater than 0',
-failureDescription:'Some elements have a `[tabindex]` value greater than 0',
-helpText:'A value greater than 0 implies an explicit navigation ordering. '+
-'Although technically valid, this often creates frustrating experiences '+
-'for users who rely on assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/2.2/tabindex?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=TabIndex;
-
-},{"./axe-audit":1}],"../audits/accessibility/td-headers-attr":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class TDHeadersAttr extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'td-headers-attr',
-description:'Cells in a `<table>` element that use the `[headers]` attribute only refer '+
-'to other cells of that same table.',
-failureDescription:'Cells in a `<table>` element that use the `[headers]` '+
-'attribute refers to other cells of that same table.',
-helpText:'Screen readers have features to make navigating tables easier. Ensuring `<td>` '+
-'cells using the `[headers]` attribute only refer to other cells in the same table may '+
-'improve the experience for screen reader users. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/td-headers-attr?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=TDHeadersAttr;
-
-},{"./axe-audit":1}],"../audits/accessibility/th-has-data-cells":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class THHasDataCells extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'th-has-data-cells',
-description:'`<th>` elements and elements with `[role="columnheader"/"rowheader"]` have '+
-'data cells they describe.',
-failureDescription:'`<th>` elements and elements with '+
-'`[role="columnheader"/"rowheader"]` do not have data cells they describe.',
-helpText:'Screen readers have features to make navigating tables easier. Ensuring table '+
-'headers always refer to some set of cells may improve the experience for screen '+
-'reader users. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/th-has-data-cells?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=THHasDataCells;
-
-},{"./axe-audit":1}],"../audits/accessibility/valid-lang":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class ValidLang extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'valid-lang',
-description:'`[lang]` attributes have a valid value',
-failureDescription:'`[lang]` attributes do not have a valid value',
-helpText:'Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) '+
-'on elements helps ensure that text is pronounced correctly by a screen reader. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=ValidLang;
-
-},{"./axe-audit":1}],"../audits/accessibility/video-caption":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class VideoCaption extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'video-caption',
-description:'`<video>` elements contain a `<track>` element with `[kind="captions"]`',
-failureDescription:'`<video>` elements do not contain a `<track>` element '+
-'with `[kind="captions"]`.',
-helpText:'When a video provides a caption it is easier for deaf and hearing impaired '+
-'users to access its information. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/video-caption?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=VideoCaption;
-
-},{"./axe-audit":1}],"../audits/accessibility/video-description":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const AxeAudit=require('./axe-audit');
-
-class VideoDescription extends AxeAudit{
-
-
-
-static get meta(){
-return{
-name:'video-description',
-description:'`<video>` elements contain a `<track>` element with `[kind="description"]`',
-failureDescription:'`<video>` elements do not contain a `<track>` element with '+
-'`[kind="description"]`.',
-helpText:'Audio descriptions provide relevant information for videos that dialogue '+
-'cannot, such as facial expressions and scenes. '+
-'[Learn more](https://dequeuniversity.com/rules/axe/2.2/video-description?application=lighthouse).',
-requiredArtifacts:['Accessibility']};
-
-}}
-
-
-module.exports=VideoDescription;
-
-},{"./axe-audit":1}],"../audits/bootup-time":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const WebInspector=require('../lib/web-inspector');
-const Util=require('../report/v2/renderer/util');
-const{groupIdToName,taskToGroup}=require('../lib/task-groups');
-const THRESHOLD_IN_MS=10;
-
-class BootupTime extends Audit{
-
-
-
-static get meta(){
-return{
-category:'Performance',
-name:'bootup-time',
-description:'JavaScript boot-up time',
-failureDescription:'JavaScript boot-up time is too high',
-helpText:'Consider reducing the time spent parsing, compiling and executing JS. '+
-'You may find delivering smaller JS payloads helps with this.',
-requiredArtifacts:['traces']};
-
-}
-
-
-
-
-
-static getExecutionTimingsByURL(timelineModel){
-const bottomUpByURL=timelineModel.bottomUpGroupBy('URL');
-const result=new Map();
-
-bottomUpByURL.children.forEach((perUrlNode,url)=>{
-
-if(!url||url==='about:blank'){
-return;
-}
-
-const taskGroups={};
-perUrlNode.children.forEach(perTaskPerUrlNode=>{
-
-const task=WebInspector.TimelineUIUtils.eventStyle(perTaskPerUrlNode.event);
-
-const groupName=taskToGroup[task.title]||groupIdToName.other;
-const groupTotal=taskGroups[groupName]||0;
-taskGroups[groupName]=groupTotal+(perTaskPerUrlNode.selfTime||0);
-});
-result.set(url,taskGroups);
-});
-
-return result;
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[BootupTime.DEFAULT_PASS];
-return artifacts.requestDevtoolsTimelineModel(trace).then(devtoolsTimelineModel=>{
-const executionTimings=BootupTime.getExecutionTimingsByURL(devtoolsTimelineModel);
-let totalBootupTime=0;
-const extendedInfo={};
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'scripting',itemType:'text',text:groupIdToName.scripting},
-{key:'scriptParseCompile',itemType:'text',text:groupIdToName.scriptParseCompile}];
-
-
-
-const results=Array.from(executionTimings).
-map(([url,groups])=>{
-
-totalBootupTime+=Object.keys(groups).reduce((sum,name)=>sum+=groups[name],0);
-extendedInfo[url]=groups;
-
-const scriptingTotal=groups[groupIdToName.scripting]||0;
-const parseCompileTotal=groups[groupIdToName.scriptParseCompile]||0;
-return{
-url:url,
-sum:scriptingTotal+parseCompileTotal,
-
-
-scripting:Util.formatMilliseconds(scriptingTotal,1),
-scriptParseCompile:Util.formatMilliseconds(parseCompileTotal,1)};
-
-}).
-filter(result=>result.sum>=THRESHOLD_IN_MS).
-sort((a,b)=>b.sum-a.sum);
-
-const tableDetails=BootupTime.makeTableDetails(headings,results);
-
-return{
-score:totalBootupTime<2000,
-rawValue:totalBootupTime,
-displayValue:Util.formatMilliseconds(totalBootupTime),
-details:tableDetails,
-extendedInfo:{
-value:extendedInfo}};
-
-
-});
-}}
-
-
-module.exports=BootupTime;
-
-},{"../lib/task-groups":36,"../lib/web-inspector":42,"../report/v2/renderer/util":43,"./audit":2}],"../audits/byte-efficiency/offscreen-images":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const Sentry=require('../../lib/sentry');
-const URL=require('../../lib/url-shim');
-
-const ALLOWABLE_OFFSCREEN_X=100;
-const ALLOWABLE_OFFSCREEN_Y=200;
-
-const IGNORE_THRESHOLD_IN_BYTES=2048;
-const IGNORE_THRESHOLD_IN_PERCENT=75;
-
-class OffscreenImages extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'offscreen-images',
-description:'Offscreen images',
-informative:true,
-helpText:'Consider lazy-loading offscreen and hidden images to improve page load speed '+
-'and time to interactive. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images).',
-requiredArtifacts:['ImageUsage','ViewportDimensions','traces','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-static computeVisiblePixels(imageRect,viewportDimensions){
-const innerWidth=viewportDimensions.innerWidth;
-const innerHeight=viewportDimensions.innerHeight;
-
-const top=Math.max(imageRect.top,-1*ALLOWABLE_OFFSCREEN_Y);
-const right=Math.min(imageRect.right,innerWidth+ALLOWABLE_OFFSCREEN_X);
-const bottom=Math.min(imageRect.bottom,innerHeight+ALLOWABLE_OFFSCREEN_Y);
-const left=Math.max(imageRect.left,-1*ALLOWABLE_OFFSCREEN_X);
-
-return Math.max(right-left,0)*Math.max(bottom-top,0);
-}
-
-
-
-
-
-
-static computeWaste(image,viewportDimensions){
-const url=URL.elideDataURI(image.src);
-const totalPixels=image.clientWidth*image.clientHeight;
-const visiblePixels=this.computeVisiblePixels(image.clientRect,viewportDimensions);
-
-const wastedRatio=totalPixels===0?1:1-visiblePixels/totalPixels;
-const totalBytes=image.networkRecord.resourceSize;
-const wastedBytes=Math.round(totalBytes*wastedRatio);
-
-if(!Number.isFinite(wastedRatio)){
-return new Error(`Invalid image sizing information ${url}`);
-}
-
-return{
-url,
-preview:{
-type:'thumbnail',
-url:image.networkRecord.url,
-mimeType:image.networkRecord.mimeType},
-
-requestStartTime:image.networkRecord.startTime,
-totalBytes,
-wastedBytes,
-wastedPercent:100*wastedRatio};
-
-}
-
-
-
-
-
-static audit_(artifacts){
-const images=artifacts.ImageUsage;
-const viewportDimensions=artifacts.ViewportDimensions;
-const trace=artifacts.traces[ByteEfficiencyAudit.DEFAULT_PASS];
-
-let debugString;
-const resultsMap=images.reduce((results,image)=>{
-if(!image.networkRecord){
-return results;
-}
-
-const processed=OffscreenImages.computeWaste(image,viewportDimensions);
-if(processed instanceof Error){
-debugString=processed.message;
-Sentry.captureException(processed,{tags:{audit:this.meta.name},level:'warning'});
-return results;
-}
-
-
-const existing=results.get(processed.preview.url);
-if(!existing||existing.wastedBytes>processed.wastedBytes){
-results.set(processed.preview.url,processed);
-}
-
-return results;
-},new Map());
-
-return artifacts.requestFirstInteractive(trace).then(firstInteractive=>{
-const ttiTimestamp=firstInteractive.timestamp/1000000;
-const results=Array.from(resultsMap.values()).filter(item=>{
-const isWasteful=item.wastedBytes>IGNORE_THRESHOLD_IN_BYTES&&
-item.wastedPercent>IGNORE_THRESHOLD_IN_PERCENT;
-const loadedEarly=item.requestStartTime<ttiTimestamp;
-return isWasteful&&loadedEarly;
-});
-
-const headings=[
-{key:'preview',itemType:'thumbnail',text:''},
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}];
-
-
-return{
-debugString,
-results,
-headings};
-
-});
-}}
-
-
-module.exports=OffscreenImages;
-
-},{"../../lib/sentry":33,"../../lib/url-shim":41,"./byte-efficiency-audit":3}],"../audits/byte-efficiency/total-byte-weight":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=2500*1024;
-const SCORING_MEDIAN=4000*1024;
-
-class TotalByteWeight extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'total-byte-weight',
-description:'Avoids enormous network payloads',
-failureDescription:'Has enormous network payloads',
-helpText:
-'Large network payloads cost users real money and are highly correlated with '+
-'long load times. [Learn '+
-'more](https://developers.google.com/web/tools/lighthouse/audits/network-payloads).',
-scoringMode:ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['devtoolsLogs']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS];
-return Promise.all([
-artifacts.requestNetworkRecords(devtoolsLogs),
-artifacts.requestNetworkThroughput(devtoolsLogs)]).
-then(([networkRecords,networkThroughput])=>{
-let totalBytes=0;
-let results=[];
-networkRecords.forEach(record=>{
-
-
-if(record.scheme==='data'||!record.finished)return;
-
-const result={
-url:record.url,
-totalBytes:record.transferSize,
-totalKb:this.bytesToKbString(record.transferSize),
-totalMs:this.bytesToMsString(record.transferSize,networkThroughput)};
-
-
-totalBytes+=result.totalBytes;
-results.push(result);
-});
-const totalCompletedRequests=results.length;
-results=results.sort((itemA,itemB)=>itemB.totalBytes-itemA.totalBytes).slice(0,10);
-
-
-
-
-
-
-const score=ByteEfficiencyAudit.computeLogNormalScore(
-totalBytes,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Total Size'},
-{key:'totalMs',itemType:'text',text:'Transfer Time'}];
-
-
-const tableDetails=ByteEfficiencyAudit.makeTableDetails(headings,results);
-
-return{
-score,
-rawValue:totalBytes,
-displayValue:`Total size was ${ByteEfficiencyAudit.bytesToKbString(totalBytes)}`,
-extendedInfo:{
-value:{
-results,
-totalCompletedRequests}},
-
-
-details:tableDetails};
-
-});
-}}
-
-
-module.exports=TotalByteWeight;
-
-},{"./byte-efficiency-audit":3}],"../audits/byte-efficiency/unminified-css":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const UnusedCSSRules=require('./unused-css-rules');
-
-const IGNORE_THRESHOLD_IN_PERCENT=5;
-const IGNORE_THRESHOLD_IN_BYTES=2048;
-
-
-
-
-class UnminifiedCSS extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'unminified-css',
-description:'Minify CSS',
-informative:true,
-helpText:'Minifying CSS files can reduce network payload sizes.'+
-'[Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).',
-requiredArtifacts:['CSSUsage','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-
-static computeTokenLength(content){
-let totalTokenLength=0;
-let isInComment=false;
-let isInLicenseComment=false;
-let isInString=false;
-let stringOpenChar=null;
-
-for(let i=0;i<content.length;i++){
-const twoChars=content.substr(i,2);
-const char=twoChars.charAt(0);
-
-const isWhitespace=char===' '||char==='\n'||char==='\t';
-const isAStringOpenChar=char===`'`||char==='"';
-
-if(isInComment){
-if(isInLicenseComment)totalTokenLength++;
-
-if(twoChars==='*/'){
-if(isInLicenseComment)totalTokenLength++;
-isInComment=false;
-i++;
-}
-}else if(isInString){
-totalTokenLength++;
-if(char==='\\'){
-totalTokenLength++;
-i++;
-}else if(char===stringOpenChar){
-isInString=false;
-}
-}else{
-if(twoChars==='/*'){
-isInComment=true;
-isInLicenseComment=content.charAt(i+2)==='!';
-if(isInLicenseComment)totalTokenLength+=2;
-i++;
-}else if(isAStringOpenChar){
-isInString=true;
-stringOpenChar=char;
-totalTokenLength++;
-}else if(!isWhitespace){
-totalTokenLength++;
-}
-}
-}
-
-
-
-if(isInComment||isInString){
-return content.length;
-}
-
-return totalTokenLength;
-}
-
-
-
-
-
-
-
-static computeWaste(stylesheet,networkRecord,pageUrl){
-const content=stylesheet.content;
-const totalTokenLength=UnminifiedCSS.computeTokenLength(content);
-
-let url=stylesheet.header.sourceURL;
-if(!url||url===pageUrl){
-const contentPreview=UnusedCSSRules.determineContentPreview(stylesheet.content);
-url={type:'code',text:contentPreview};
-}
-
-const totalBytes=ByteEfficiencyAudit.estimateTransferSize(networkRecord,content.length,
-'stylesheet');
-const wastedRatio=1-totalTokenLength/content.length;
-const wastedBytes=Math.round(totalBytes*wastedRatio);
-
-return{
-url,
-totalBytes,
-wastedBytes,
-wastedPercent:100*wastedRatio};
-
-}
-
-
-
-
-
-static audit_(artifacts,networkRecords){
-const pageUrl=artifacts.URL.finalUrl;
-const results=[];
-for(const stylesheet of artifacts.CSSUsage.stylesheets){
-const networkRecord=networkRecords.
-find(record=>record.url===stylesheet.header.sourceURL);
-if(!stylesheet.content)continue;
-
-const result=UnminifiedCSS.computeWaste(stylesheet,networkRecord,pageUrl);
-
-
-
-if(result.wastedPercent<IGNORE_THRESHOLD_IN_PERCENT||
-result.wastedBytes<IGNORE_THRESHOLD_IN_BYTES)continue;
-results.push(result);
-}
-
-return{
-results,
-headings:[
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}]};
-
-
-}}
-
-
-module.exports=UnminifiedCSS;
-
-},{"./byte-efficiency-audit":3,"./unused-css-rules":"../audits/byte-efficiency/unused-css-rules"}],"../audits/byte-efficiency/unminified-javascript":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const esprima=require('esprima');
-
-const IGNORE_THRESHOLD_IN_PERCENT=10;
-const IGNORE_THRESHOLD_IN_BYTES=2048;
-
-
-
-
-
-
-
-
-
-
-
-class UnminifiedJavaScript extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'unminified-javascript',
-description:'Minify JavaScript',
-informative:true,
-helpText:'Minifying JavaScript files can reduce payload sizes and script parse time. '+
-'[Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).',
-requiredArtifacts:['Scripts','devtoolsLogs']};
-
-}
-
-
-
-
-
-static computeWaste(scriptContent,networkRecord){
-const contentLength=scriptContent.length;
-let totalTokenLength=0;
-
-const tokens=esprima.tokenize(scriptContent,{tolerant:true});
-if(!tokens.length&&tokens.errors&&tokens.errors.length){
-throw tokens.errors[0];
-}
-
-for(const token of tokens){
-totalTokenLength+=token.value.length;
-}
-
-const totalBytes=ByteEfficiencyAudit.estimateTransferSize(networkRecord,contentLength,
-'script');
-const wastedRatio=1-totalTokenLength/contentLength;
-const wastedBytes=Math.round(totalBytes*wastedRatio);
-
-return{
-url:networkRecord.url,
-totalBytes,
-wastedBytes,
-wastedPercent:100*wastedRatio};
-
-}
-
-
-
-
-
-static audit_(artifacts,networkRecords){
-const results=[];
-let debugString;
-for(const requestId of Object.keys(artifacts.Scripts)){
-const scriptContent=artifacts.Scripts[requestId];
-const networkRecord=networkRecords.find(record=>record.requestId===requestId);
-if(!networkRecord||!scriptContent)continue;
-
-try{
-const result=UnminifiedJavaScript.computeWaste(scriptContent,networkRecord);
-
-
-if(result.wastedPercent<IGNORE_THRESHOLD_IN_PERCENT||
-result.wastedBytes<IGNORE_THRESHOLD_IN_BYTES)continue;
-results.push(result);
-}catch(err){
-debugString=`Unable to process ${networkRecord._url}: ${err.message}`;
-}
-}
-
-return{
-results,
-debugString,
-headings:[
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}]};
-
-
-}}
-
-
-module.exports=UnminifiedJavaScript;
-
-},{"./byte-efficiency-audit":3,"esprima":130}],"../audits/byte-efficiency/unused-css-rules":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-
-const IGNORE_THRESHOLD_IN_BYTES=2048;
-const PREVIEW_LENGTH=100;
-
-class UnusedCSSRules extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'unused-css-rules',
-description:'Unused CSS rules',
-informative:true,
-helpText:'Remove unused rules from stylesheets to reduce unnecessary '+
-'bytes consumed by network activity. '+
-'[Learn more](https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery)',
-requiredArtifacts:['CSSUsage','URL','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-static indexStylesheetsById(styles,networkRecords){
-const indexedNetworkRecords=networkRecords.
-reduce((indexed,record)=>{
-indexed[record.url]=record;
-return indexed;
-},{});
-
-return styles.reduce((indexed,stylesheet)=>{
-indexed[stylesheet.header.styleSheetId]=Object.assign({
-usedRules:[],
-networkRecord:indexedNetworkRecords[stylesheet.header.sourceURL]},
-stylesheet);
-return indexed;
-},{});
-}
-
-
-
-
-
-
-static indexUsedRules(rules,indexedStylesheets){
-rules.forEach(rule=>{
-const stylesheetInfo=indexedStylesheets[rule.styleSheetId];
-
-if(!stylesheetInfo){
-return;
-}
-
-if(rule.used){
-stylesheetInfo.usedRules.push(rule);
-}
-});
-}
-
-
-
-
-
-static computeUsage(stylesheetInfo){
-let usedUncompressedBytes=0;
-const totalUncompressedBytes=stylesheetInfo.content.length;
-
-for(const usedRule of stylesheetInfo.usedRules){
-usedUncompressedBytes+=usedRule.endOffset-usedRule.startOffset;
-}
-
-const totalTransferredBytes=ByteEfficiencyAudit.estimateTransferSize(
-stylesheetInfo.networkRecord,totalUncompressedBytes,'stylesheet');
-const percentUnused=(totalUncompressedBytes-usedUncompressedBytes)/totalUncompressedBytes;
-const wastedBytes=Math.round(percentUnused*totalTransferredBytes);
-
-return{
-wastedBytes,
-wastedPercent:percentUnused*100,
-totalBytes:totalTransferredBytes};
-
-}
-
-
-
-
-
-
-static determineContentPreview(content){
-let preview=(content||'').
-slice(0,PREVIEW_LENGTH*5).
-replace(/( {2,}|\t)+/g,'  ').
-replace(/\n\s+}/g,'\n}').
-trim();
-
-if(preview.length>PREVIEW_LENGTH){
-const firstRuleStart=preview.indexOf('{');
-const firstRuleEnd=preview.indexOf('}');
-
-if(firstRuleStart===-1||firstRuleEnd===-1||
-firstRuleStart>firstRuleEnd||
-firstRuleStart>PREVIEW_LENGTH){
-
-preview=preview.slice(0,PREVIEW_LENGTH)+'...';
-}else if(firstRuleEnd<PREVIEW_LENGTH){
-
-preview=preview.slice(0,firstRuleEnd+1)+' ...';
-}else{
-
-const lastSemicolonIndex=preview.slice(0,PREVIEW_LENGTH).lastIndexOf(';');
-preview=lastSemicolonIndex<firstRuleStart?
-preview.slice(0,PREVIEW_LENGTH)+'... } ...':
-preview.slice(0,lastSemicolonIndex+1)+' ... } ...';
-}
-}
-
-return preview;
-}
-
-
-
-
-
-
-static mapSheetToResult(stylesheetInfo,pageUrl){
-if(stylesheetInfo.isDuplicate){
-return null;
-}
-
-let url=stylesheetInfo.header.sourceURL;
-if(!url||url===pageUrl){
-const contentPreview=UnusedCSSRules.determineContentPreview(stylesheetInfo.content);
-url={type:'code',text:contentPreview};
-}
-
-const usage=UnusedCSSRules.computeUsage(stylesheetInfo);
-return Object.assign({url},usage);
-}
-
-
-
-
-
-static audit_(artifacts){
-const styles=artifacts.CSSUsage.stylesheets;
-const usage=artifacts.CSSUsage.rules;
-const pageUrl=artifacts.URL.finalUrl;
-
-const devtoolsLogs=artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS];
-return artifacts.requestNetworkRecords(devtoolsLogs).then(networkRecords=>{
-const indexedSheets=UnusedCSSRules.indexStylesheetsById(styles,networkRecords);
-UnusedCSSRules.indexUsedRules(usage,indexedSheets);
-
-const results=Object.keys(indexedSheets).
-map(sheetId=>UnusedCSSRules.mapSheetToResult(indexedSheets[sheetId],pageUrl)).
-filter(sheet=>sheet&&sheet.wastedBytes>IGNORE_THRESHOLD_IN_BYTES);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}];
-
-
-return{
-results,
-headings};
-
-});
-}}
-
-
-module.exports=UnusedCSSRules;
-
-},{"./byte-efficiency-audit":3}],"../audits/byte-efficiency/unused-javascript":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-
-const IGNORE_THRESHOLD_IN_BYTES=2048;
-
-class UnusedJavaScript extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'unused-javascript',
-description:'Unused JavaScript',
-informative:true,
-helpText:'Remove unused JavaScript to reduce bytes consumed by network activity.',
-requiredArtifacts:['JsUsage','devtoolsLogs']};
-
-}
-
-
-
-
-
-static computeWaste(script){
-let maximumEndOffset=0;
-for(const func of script.functions){
-for(const range of func.ranges){
-maximumEndOffset=Math.max(maximumEndOffset,range.endOffset);
-}
-}
-
-
-
-const unusedByIndex=new Uint8Array(maximumEndOffset);
-for(const func of script.functions){
-for(const range of func.ranges){
-if(range.count===0){
-for(let i=range.startOffset;i<range.endOffset;i++){
-unusedByIndex[i]=1;
-}
-}
-}
-}
-
-let unused=0;
-for(const x of unusedByIndex){
-unused+=x;
-}
-
-return{
-unusedLength:unused,
-contentLength:maximumEndOffset};
-
-}
-
-
-
-
-
-
-static mergeWaste(wasteData,networkRecord){
-let unusedLength=0;
-let contentLength=0;
-for(const usage of wasteData){
-unusedLength+=usage.unusedLength;
-contentLength+=usage.contentLength;
-}
-
-const totalBytes=ByteEfficiencyAudit.estimateTransferSize(networkRecord,contentLength,
-'script');
-const wastedRatio=unusedLength/contentLength||0;
-const wastedBytes=Math.round(totalBytes*wastedRatio);
-
-return{
-url:networkRecord.url,
-totalBytes,
-wastedBytes,
-wastedPercent:100*wastedRatio};
-
-}
-
-
-
-
-
-static audit_(artifacts,networkRecords){
-const scriptsByUrl=new Map();
-for(const script of artifacts.JsUsage){
-const scripts=scriptsByUrl.get(script.url)||[];
-scripts.push(script);
-scriptsByUrl.set(script.url,scripts);
-}
-
-const results=[];
-for(const[url,scripts]of scriptsByUrl.entries()){
-const networkRecord=networkRecords.find(record=>record.url===url);
-if(!networkRecord)continue;
-const wasteData=scripts.map(UnusedJavaScript.computeWaste);
-const result=UnusedJavaScript.mergeWaste(wasteData,networkRecord);
-if(result.wastedBytes<=IGNORE_THRESHOLD_IN_BYTES)continue;
-results.push(result);
-}
-
-return{
-results,
-headings:[
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}]};
-
-
-}}
-
-
-module.exports=UnusedJavaScript;
-
-},{"./byte-efficiency-audit":3}],"../audits/byte-efficiency/uses-long-cache-ttl":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const assert=require('assert');
-const parseCacheControl=require('parse-cache-control');
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const formatDuration=require('../../report/v2/renderer/util.js').formatDuration;
-const WebInspector=require('../../lib/web-inspector');
-const URL=require('../../lib/url-shim');
-
-
-const IGNORE_THRESHOLD_IN_PERCENT=0.925;
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=4;
-const SCORING_MEDIAN=768;
-
-class CacheHeaders extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-category:'Caching',
-name:'uses-long-cache-ttl',
-description:'Uses efficient cache policy on static assets',
-failureDescription:'Uses inefficient cache policy on static assets',
-helpText:
-'A long cache lifetime can speed up repeat visits to your page. '+
-'[Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#cache-control).',
-scoringMode:ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['devtoolsLogs']};
-
-}
-
-
-
-
-
-
-
-
-
-
-static linearInterpolation(x0,y0,x1,y1,x){
-const slope=(y1-y0)/(x1-x0);
-return y0+(x-x0)*slope;
-}
-
-
-
-
-
-
-
-static getCacheHitProbability(maxAgeInSeconds){
-
-
-
-
-
-const RESOURCE_AGE_IN_HOURS_DECILES=[0,0.2,1,3,8,12,24,48,72,168,8760,Infinity];
-assert.ok(RESOURCE_AGE_IN_HOURS_DECILES.length===12,'deciles 0-10 and 1 for overflow');
-
-const maxAgeInHours=maxAgeInSeconds/3600;
-const upperDecileIndex=RESOURCE_AGE_IN_HOURS_DECILES.findIndex(
-decile=>decile>=maxAgeInHours);
-
-
-
-if(upperDecileIndex===RESOURCE_AGE_IN_HOURS_DECILES.length-1)return 1;
-if(upperDecileIndex===0)return 0;
-
-
-const upperDecileValue=RESOURCE_AGE_IN_HOURS_DECILES[upperDecileIndex];
-const lowerDecileValue=RESOURCE_AGE_IN_HOURS_DECILES[upperDecileIndex-1];
-const upperDecile=upperDecileIndex/10;
-const lowerDecile=(upperDecileIndex-1)/10;
-
-
-return CacheHeaders.linearInterpolation(
-lowerDecileValue,
-lowerDecile,
-upperDecileValue,
-upperDecile,
-maxAgeInHours);
-
-}
-
-
-
-
-
-
-
-
-
-static computeCacheLifetimeInSeconds(headers,cacheControl){
-if(cacheControl){
-
-if(cacheControl['no-cache']||cacheControl['no-store'])return 0;
-if(Number.isFinite(cacheControl['max-age']))return Math.max(cacheControl['max-age'],0);
-}else if((headers.get('pragma')||'').includes('no-cache')){
-
-return 0;
-}
-
-if(headers.has('expires')){
-const expires=new Date(headers.get('expires')).getTime();
-
-if(!expires)return 0;
-return Math.max(0,Math.ceil((expires-Date.now())/1000));
-}
-
-return null;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-static isCacheableAsset(record){
-const CACHEABLE_STATUS_CODES=new Set([200,203,206]);
-
-const STATIC_RESOURCE_TYPES=new Set([
-WebInspector.resourceTypes.Font,
-WebInspector.resourceTypes.Image,
-WebInspector.resourceTypes.Media,
-WebInspector.resourceTypes.Script,
-WebInspector.resourceTypes.Stylesheet]);
-
-
-const resourceUrl=record._url;
-return(
-CACHEABLE_STATUS_CODES.has(record.statusCode)&&
-STATIC_RESOURCE_TYPES.has(record._resourceType)&&
-!resourceUrl.includes('data:'));
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS];
-return artifacts.requestNetworkRecords(devtoolsLogs).then(records=>{
-const results=[];
-let queryStringCount=0;
-let totalWastedBytes=0;
-
-for(const record of records){
-if(!CacheHeaders.isCacheableAsset(record))continue;
-
-const headers=new Map();
-for(const header of record._responseHeaders){
-headers.set(header.name.toLowerCase(),header.value);
-}
-
-const cacheControl=parseCacheControl(headers.get('cache-control'));
-let cacheLifetimeInSeconds=CacheHeaders.computeCacheLifetimeInSeconds(
-headers,
-cacheControl);
-
-
-
-if(cacheLifetimeInSeconds===0)continue;
-cacheLifetimeInSeconds=cacheLifetimeInSeconds||0;
-
-const cacheHitProbability=CacheHeaders.getCacheHitProbability(cacheLifetimeInSeconds);
-if(cacheHitProbability>IGNORE_THRESHOLD_IN_PERCENT)continue;
-
-const url=URL.elideDataURI(record._url);
-const totalBytes=record._transferSize;
-const totalKb=ByteEfficiencyAudit.bytesToKbString(totalBytes);
-const wastedBytes=(1-cacheHitProbability)*totalBytes;
-const cacheLifetimeDisplay=formatDuration(cacheLifetimeInSeconds);
-
-totalWastedBytes+=wastedBytes;
-if(url.includes('?'))queryStringCount++;
-
-results.push({
-url,
-cacheControl,
-cacheLifetimeInSeconds,
-cacheLifetimeDisplay,
-cacheHitProbability,
-totalKb,
-totalBytes,
-wastedBytes});
-
-}
-
-results.sort(
-(a,b)=>a.cacheLifetimeInSeconds-b.cacheLifetimeInSeconds||b.totalBytes-a.totalBytes);
-
-
-
-
-
-
-const score=ByteEfficiencyAudit.computeLogNormalScore(
-totalWastedBytes/1024,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'cacheLifetimeDisplay',itemType:'text',text:'Cache TTL'},
-{key:'totalKb',itemType:'text',text:'Size (KB)'}];
-
-
-const tableDetails=ByteEfficiencyAudit.makeTableDetails(headings,results);
-
-return{
-score,
-rawValue:totalWastedBytes,
-displayValue:`${results.length} asset${results.length!==1?'s':''} found`,
-extendedInfo:{
-value:{
-results,
-queryStringCount}},
-
-
-details:tableDetails};
-
-});
-}}
-
-
-module.exports=CacheHeaders;
-
-},{"../../lib/url-shim":41,"../../lib/web-inspector":42,"../../report/v2/renderer/util.js":43,"./byte-efficiency-audit":3,"assert":47,"parse-cache-control":141}],"../audits/byte-efficiency/uses-optimized-images":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const URL=require('../../lib/url-shim');
-
-const IGNORE_THRESHOLD_IN_BYTES=4096;
-
-class UsesOptimizedImages extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'uses-optimized-images',
-description:'Optimize images',
-informative:true,
-helpText:'Optimized images load faster and consume less cellular data. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/optimize-images).',
-requiredArtifacts:['OptimizedImages','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-static computeSavings(image,type){
-const bytes=image.originalSize-image[type+'Size'];
-const percent=100*bytes/image.originalSize;
-return{bytes,percent};
-}
-
-
-
-
-
-static audit_(artifacts){
-const images=artifacts.OptimizedImages;
-
-const failedImages=[];
-const results=[];
-images.forEach(image=>{
-if(image.failed){
-failedImages.push(image);
-return;
-}else if(/(jpeg|bmp)/.test(image.mimeType)===false||
-image.originalSize<image.jpegSize+IGNORE_THRESHOLD_IN_BYTES){
-return;
-}
-
-const url=URL.elideDataURI(image.url);
-const jpegSavings=UsesOptimizedImages.computeSavings(image,'jpeg');
-
-results.push({
-url,
-fromProtocol:image.fromProtocol,
-isCrossOrigin:!image.isSameOrigin,
-preview:{url:image.url,mimeType:image.mimeType,type:'thumbnail'},
-totalBytes:image.originalSize,
-wastedBytes:jpegSavings.bytes});
-
-});
-
-let debugString;
-if(failedImages.length){
-const urls=failedImages.map(image=>URL.getURLDisplayName(image.url));
-debugString=`Lighthouse was unable to decode some of your images: ${urls.join(', ')}`;
-}
-
-const headings=[
-{key:'preview',itemType:'thumbnail',text:''},
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}];
-
-
-return{
-debugString,
-results,
-headings};
-
-}}
-
-
-module.exports=UsesOptimizedImages;
-
-},{"../../lib/url-shim":41,"./byte-efficiency-audit":3}],"../audits/byte-efficiency/uses-request-compression":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const URL=require('../../lib/url-shim');
-
-const IGNORE_THRESHOLD_IN_BYTES=1400;
-const IGNORE_THRESHOLD_IN_PERCENT=0.1;
-
-class ResponsesAreCompressed extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'uses-request-compression',
-informative:true,
-description:'Enable text compression',
-helpText:'Text-based responses should be served with compression (gzip, deflate or brotli)'+
-' to minimize total network bytes.'+
-' [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/optimize-encoding-and-transfer).',
-requiredArtifacts:['ResponseCompression','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-static audit_(artifacts){
-const uncompressedResponses=artifacts.ResponseCompression;
-
-const results=[];
-uncompressedResponses.forEach(record=>{
-const originalSize=record.resourceSize;
-const gzipSize=record.gzipSize;
-const gzipSavings=originalSize-gzipSize;
-
-
-
-if(1-gzipSize/originalSize<IGNORE_THRESHOLD_IN_PERCENT||
-gzipSavings<IGNORE_THRESHOLD_IN_BYTES||
-record.transferSize<gzipSize)
-{
-return;
-}
-
-
-const url=URL.elideDataURI(record.url);
-const isDuplicate=results.find(res=>res.url===url&&
-res.totalBytes===record.resourceSize);
-if(isDuplicate){
-return;
-}
-
-results.push({
-url,
-totalBytes:originalSize,
-wastedBytes:gzipSavings});
-
-});
-
-const headings=[
-{key:'url',itemType:'url',text:'Uncompressed resource URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'GZIP Savings'}];
-
-
-return{
-results,
-headings};
-
-}}
-
-
-module.exports=ResponsesAreCompressed;
-
-},{"../../lib/url-shim":41,"./byte-efficiency-audit":3}],"../audits/byte-efficiency/uses-responsive-images":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const Sentry=require('../../lib/sentry');
-const URL=require('../../lib/url-shim');
-
-const IGNORE_THRESHOLD_IN_BYTES=2048;
-const WASTEFUL_THRESHOLD_IN_BYTES=25*1024;
-
-class UsesResponsiveImages extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'uses-responsive-images',
-description:'Properly size images',
-informative:true,
-helpText:
-'Serve images that are appropriately-sized to save cellular data '+
-'and improve load time. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/oversized-images).',
-requiredArtifacts:['ImageUsage','ViewportDimensions','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-static computeWaste(image,DPR){
-const url=URL.elideDataURI(image.src);
-const actualPixels=image.naturalWidth*image.naturalHeight;
-const usedPixels=image.clientWidth*image.clientHeight*Math.pow(DPR,2);
-const wastedRatio=1-usedPixels/actualPixels;
-const totalBytes=image.networkRecord.resourceSize;
-const wastedBytes=Math.round(totalBytes*wastedRatio);
-
-
-
-if(!usedPixels){
-return null;
-}
-
-if(!Number.isFinite(wastedRatio)){
-return new Error(`Invalid image sizing information ${url}`);
-}
-
-return{
-url,
-preview:{
-type:'thumbnail',
-url:image.networkRecord.url,
-mimeType:image.networkRecord.mimeType},
-
-totalBytes,
-wastedBytes,
-wastedPercent:100*wastedRatio,
-isWasteful:wastedBytes>WASTEFUL_THRESHOLD_IN_BYTES};
-
-}
-
-
-
-
-
-static audit_(artifacts){
-const images=artifacts.ImageUsage;
-const DPR=artifacts.ViewportDimensions.devicePixelRatio;
-
-let debugString;
-const resultsMap=new Map();
-images.forEach(image=>{
-
-if(!image.networkRecord||image.networkRecord.mimeType==='image/svg+xml'){
-return;
-}
-
-const processed=UsesResponsiveImages.computeWaste(image,DPR);
-if(!processed)return;
-
-if(processed instanceof Error){
-debugString=processed.message;
-Sentry.captureException(processed,{tags:{audit:this.meta.name},level:'warning'});
-return;
-}
-
-
-const existing=resultsMap.get(processed.preview.url);
-if(!existing||existing.wastedBytes>processed.wastedBytes){
-resultsMap.set(processed.preview.url,processed);
-}
-});
-
-const results=Array.from(resultsMap.values()).
-filter(item=>item.wastedBytes>IGNORE_THRESHOLD_IN_BYTES);
-
-const headings=[
-{key:'preview',itemType:'thumbnail',text:''},
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}];
-
-
-return{
-debugString,
-results,
-headings};
-
-}}
-
-
-module.exports=UsesResponsiveImages;
-
-},{"../../lib/sentry":33,"../../lib/url-shim":41,"./byte-efficiency-audit":3}],"../audits/byte-efficiency/uses-webp-images":[function(require,module,exports){
-
-
-
-
-
-
-
-
-'use strict';
-
-const ByteEfficiencyAudit=require('./byte-efficiency-audit');
-const OptimizedImages=require('./uses-optimized-images');
-const URL=require('../../lib/url-shim');
-
-const IGNORE_THRESHOLD_IN_BYTES=8192;
-
-class UsesWebPImages extends ByteEfficiencyAudit{
-
-
-
-static get meta(){
-return{
-name:'uses-webp-images',
-description:'Serve images in next-gen formats',
-informative:true,
-helpText:'Image formats like JPEG 2000, JPEG XR, and WebP often provide better '+
-'compression than PNG or JPEG, which means faster downloads and less data consumption. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/webp).',
-requiredArtifacts:['OptimizedImages','devtoolsLogs']};
-
-}
-
-
-
-
-
-static audit_(artifacts){
-const images=artifacts.OptimizedImages;
-
-const failedImages=[];
-const results=[];
-images.forEach(image=>{
-if(image.failed){
-failedImages.push(image);
-return;
-}else if(image.originalSize<image.webpSize+IGNORE_THRESHOLD_IN_BYTES){
-return;
-}
-
-const url=URL.elideDataURI(image.url);
-const webpSavings=OptimizedImages.computeSavings(image,'webp');
-
-results.push({
-url,
-fromProtocol:image.fromProtocol,
-isCrossOrigin:!image.isSameOrigin,
-preview:{url:image.url,mimeType:image.mimeType,type:'thumbnail'},
-totalBytes:image.originalSize,
-wastedBytes:webpSavings.bytes});
-
-});
-
-let debugString;
-if(failedImages.length){
-const urls=failedImages.map(image=>URL.getURLDisplayName(image.url));
-debugString=`Lighthouse was unable to decode some of your images: ${urls.join(', ')}`;
-}
-
-const headings=[
-{key:'preview',itemType:'thumbnail',text:''},
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Original'},
-{key:'potentialSavings',itemType:'text',text:'Potential Savings'}];
-
-
-return{
-debugString,
-results,
-headings};
-
-}}
-
-
-module.exports=UsesWebPImages;
-
-},{"../../lib/url-shim":41,"./byte-efficiency-audit":3,"./uses-optimized-images":"../audits/byte-efficiency/uses-optimized-images"}],"../audits/cache-start-url":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-class CacheStartUrl extends Audit{
-
-
-
-static get meta(){
-return{
-name:'cache-start-url',
-description:'Cache contains start_url from manifest (alpha)',
-failureDescription:'Cache does not contain start_url from manifest (alpha)',
-requiredArtifacts:['CacheContents','Manifest','URL']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-if(!artifacts.Manifest||!artifacts.Manifest.value){
-
-return{
-rawValue:false};
-
-}
-
-const manifest=artifacts.Manifest.value;
-if(!(manifest.start_url&&manifest.start_url.value)){
-return{
-rawValue:false,
-debugString:'start_url not present in Manifest'};
-
-}
-
-
-const startURL=manifest.start_url.value;
-
-const altStartURL=startURL.
-replace(/\?utm_([^=]*)=([^&]|$)*/,'').
-replace(/\?$/,'');
-
-
-
-
-
-
-const cacheContents=artifacts.CacheContents;
-const cacheHasStartUrl=cacheContents.find(req=>{
-return startURL===req||altStartURL===req;
-});
-
-return{
-rawValue:cacheHasStartUrl!==undefined};
-
-}}
-
-
-module.exports=CacheStartUrl;
-
-},{"./audit":2}],"../audits/consistently-interactive":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const NetworkRecorder=require('../lib/network-recorder');
-const TracingProcessor=require('../lib/traces/tracing-processor');
-const LHError=require('../lib/errors');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=1700;
-const SCORING_MEDIAN=10000;
-
-const REQUIRED_QUIET_WINDOW=5000;
-const ALLOWED_CONCURRENT_REQUESTS=2;
-
-
-
-
-
-
-
-class ConsistentlyInteractiveMetric extends Audit{
-
-
-
-static get meta(){
-return{
-name:'consistently-interactive',
-description:'Consistently Interactive (beta)',
-helpText:'Consistently Interactive marks the time at which the page is '+
-'fully interactive. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive).',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['traces','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-
-
-static _findNetworkQuietPeriods(networkRecords,traceOfTab){
-const traceEndTsInMs=traceOfTab.timestamps.traceEnd/1000;
-return NetworkRecorder.findNetworkQuietPeriods(networkRecords,
-ALLOWED_CONCURRENT_REQUESTS,traceEndTsInMs);
-}
-
-
-
-
-
-
-
-static _findCPUQuietPeriods(longTasks,traceOfTab){
-const navStartTsInMs=traceOfTab.timestamps.navigationStart/1000;
-const traceEndTsInMs=traceOfTab.timestamps.traceEnd/1000;
-if(longTasks.length===0){
-return[{start:0,end:traceEndTsInMs}];
-}
-
-const quietPeriods=[];
-longTasks.forEach((task,index)=>{
-if(index===0){
-quietPeriods.push({
-start:0,
-end:task.start+navStartTsInMs});
-
-}
-
-if(index===longTasks.length-1){
-quietPeriods.push({
-start:task.end+navStartTsInMs,
-end:traceEndTsInMs});
-
-}else{
-quietPeriods.push({
-start:task.end+navStartTsInMs,
-end:longTasks[index+1].start+navStartTsInMs});
-
-}
-});
-
-return quietPeriods;
-}
-
-
-
-
-
-
-
-
-
-
-static findOverlappingQuietPeriods(longTasks,networkRecords,traceOfTab){
-const FMPTsInMs=traceOfTab.timestamps.firstMeaningfulPaint/1000;
-
-const isLongEnoughQuietPeriod=period=>
-period.end>FMPTsInMs+REQUIRED_QUIET_WINDOW&&
-period.end-period.start>=REQUIRED_QUIET_WINDOW;
-const networkQuietPeriods=this._findNetworkQuietPeriods(networkRecords,traceOfTab).
-filter(isLongEnoughQuietPeriod);
-const cpuQuietPeriods=this._findCPUQuietPeriods(longTasks,traceOfTab).
-filter(isLongEnoughQuietPeriod);
-
-const cpuQueue=cpuQuietPeriods.slice();
-const networkQueue=networkQuietPeriods.slice();
-
-
-let cpuCandidate=cpuQueue.shift();
-let networkCandidate=networkQueue.shift();
-while(cpuCandidate&&networkCandidate){
-if(cpuCandidate.start>=networkCandidate.start){
-
-if(networkCandidate.end>=cpuCandidate.start+REQUIRED_QUIET_WINDOW){
-return{
-cpuQuietPeriod:cpuCandidate,
-networkQuietPeriod:networkCandidate,
-cpuQuietPeriods,
-networkQuietPeriods};
-
-}else{
-networkCandidate=networkQueue.shift();
-}
-}else{
-
-if(cpuCandidate.end>=networkCandidate.start+REQUIRED_QUIET_WINDOW){
-return{
-cpuQuietPeriod:cpuCandidate,
-networkQuietPeriod:networkCandidate,
-cpuQuietPeriods,
-networkQuietPeriods};
-
-}else{
-cpuCandidate=cpuQueue.shift();
-}
-}
-}
-
-throw new LHError(
-cpuCandidate?
-LHError.errors.NO_TTI_NETWORK_IDLE_PERIOD:
-LHError.errors.NO_TTI_CPU_IDLE_PERIOD);
-
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-const devtoolsLog=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-const computedArtifacts=[
-artifacts.requestNetworkRecords(devtoolsLog),
-artifacts.requestTraceOfTab(trace)];
-
-
-return Promise.all(computedArtifacts).
-then(([networkRecords,traceOfTab])=>{
-if(!traceOfTab.timestamps.firstMeaningfulPaint){
-throw new LHError(LHError.errors.NO_FMP);
-}
-
-if(!traceOfTab.timestamps.domContentLoaded){
-throw new LHError(LHError.errors.NO_DCL);
-}
-
-const longTasks=TracingProcessor.getMainThreadTopLevelEvents(traceOfTab).
-filter(event=>event.duration>=50);
-const quietPeriodInfo=this.findOverlappingQuietPeriods(longTasks,networkRecords,
-traceOfTab);
-const cpuQuietPeriod=quietPeriodInfo.cpuQuietPeriod;
-
-const timestamp=Math.max(
-cpuQuietPeriod.start,
-traceOfTab.timestamps.firstMeaningfulPaint/1000,
-traceOfTab.timestamps.domContentLoaded/1000)*
-1000;
-const timeInMs=(timestamp-traceOfTab.timestamps.navigationStart)/1000;
-const extendedInfo=Object.assign(quietPeriodInfo,{timestamp,timeInMs});
-
-return{
-score:Audit.computeLogNormalScore(
-timeInMs,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN),
-
-rawValue:timeInMs,
-displayValue:Util.formatMilliseconds(timeInMs),
-extendedInfo:{
-value:extendedInfo}};
-
-
-});
-}}
-
-
-module.exports=ConsistentlyInteractiveMetric;
-
-
-
-
-
-
-
-let TimePeriod;
-
-},{"../lib/errors":28,"../lib/network-recorder":32,"../lib/traces/tracing-processor":40,"../report/v2/renderer/util":43,"./audit":2}],"../audits/content-width":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-class ContentWidth extends Audit{
-
-
-
-static get meta(){
-return{
-name:'content-width',
-description:'Content is sized correctly for the viewport',
-failureDescription:'Content is not sized correctly for the viewport',
-helpText:'If the width of your app\'s content doesn\'t match the width '+
-'of the viewport, your app might not be optimized for mobile screens. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/content-sized-correctly-for-viewport).',
-requiredArtifacts:['ViewportDimensions']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const viewportWidth=artifacts.ViewportDimensions.innerWidth;
-const windowWidth=artifacts.ViewportDimensions.outerWidth;
-const widthsMatch=viewportWidth===windowWidth;
-
-return{
-rawValue:widthsMatch,
-debugString:this.createDebugString(widthsMatch,artifacts.ViewportDimensions)};
-
-}
-
-static createDebugString(match,artifact){
-if(match){
-return'';
-}
-
-return'The viewport size is '+artifact.innerWidth+'px, '+
-'whereas the window size is '+artifact.outerWidth+'px.';
-}}
-
-
-module.exports=ContentWidth;
-
-},{"./audit":2}],"../audits/critical-request-chains":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-
-class CriticalRequestChains extends Audit{
-
-
-
-static get meta(){
-return{
-name:'critical-request-chains',
-description:'Critical Request Chains',
-informative:true,
-helpText:'The Critical Request Chains below show you what resources are '+
-'issued with a high priority. Consider reducing '+
-'the length of chains, reducing the download size of resources, or '+
-'deferring the download of unnecessary resources to improve page load. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains).',
-requiredArtifacts:['devtoolsLogs']};
-
-}
-
-static _traverse(tree,cb){
-function walk(node,depth,startTime,transferSize=0){
-const children=Object.keys(node);
-if(children.length===0){
-return;
-}
-children.forEach(id=>{
-const child=node[id];
-if(!startTime){
-startTime=child.request.startTime;
-}
-
-
-cb({
-depth,
-id,
-node:child,
-chainDuration:(child.request.endTime-startTime)*1000,
-chainTransferSize:transferSize+child.request.transferSize});
-
-
-
-walk(child.children,depth+1,startTime);
-},'');
-}
-
-walk(tree,0);
-}
-
-
-
-
-
-static _getLongestChain(tree){
-const longest={
-duration:0,
-length:0,
-transferSize:0};
-
-CriticalRequestChains._traverse(tree,opts=>{
-const duration=opts.chainDuration;
-if(duration>longest.duration){
-longest.duration=duration;
-longest.transferSize=opts.chainTransferSize;
-longest.length=opts.depth;
-}
-});
-
-longest.length++;
-return longest;
-}
-
-
-
-
-static flattenRequests(tree){
-const flattendChains={};
-const chainMap=new Map();
-CriticalRequestChains._traverse(tree,opts=>{
-let chain;
-if(chainMap.has(opts.id)){
-chain=chainMap.get(opts.id);
-}else{
-chain={};
-flattendChains[opts.id]=chain;
-}
-
-const request=opts.node.request;
-chain.request={
-url:request.url,
-startTime:request.startTime,
-endTime:request.endTime,
-responseReceivedTime:request.responseReceivedTime,
-transferSize:request.transferSize};
-
-chain.children={};
-Object.keys(opts.node.children).forEach(chainId=>{
-const childChain={};
-chainMap.set(chainId,childChain);
-chain.children[chainId]=childChain;
-});
-
-chainMap.set(opts.id,chain);
-});
-
-return flattendChains;
-}
-
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-return artifacts.requestCriticalRequestChains(devtoolsLogs).then(chains=>{
-let chainCount=0;
-function walk(node,depth){
-const children=Object.keys(node);
-
-
-
-if(children.length===0){
-chainCount++;
-}
-
-children.forEach(id=>{
-const child=node[id];
-walk(child.children,depth+1);
-},'');
-}
-
-const flattenedChains=CriticalRequestChains.flattenRequests(chains);
-
-
-const initialNavKey=Object.keys(flattenedChains)[0];
-const initialNavChildren=initialNavKey&&flattenedChains[initialNavKey].children;
-if(initialNavChildren&&Object.keys(initialNavChildren).length>0){
-walk(initialNavChildren,0);
-}
-
-const longestChain=CriticalRequestChains._getLongestChain(flattenedChains);
-
-return{
-rawValue:chainCount===0,
-displayValue:Util.formatNumber(chainCount),
-extendedInfo:{
-value:{
-chains:flattenedChains,
-longestChain}},
-
-
-details:{
-type:'criticalrequestchain',
-header:{type:'text',text:'View critical network waterfall:'},
-chains:flattenedChains,
-longestChain}};
-
-
-});
-}}
-
-
-module.exports=CriticalRequestChains;
-
-},{"../report/v2/renderer/util":43,"./audit":2}],"../audits/deprecations":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-
-class Deprecations extends Audit{
-
-
-
-static get meta(){
-return{
-name:'deprecations',
-description:'Avoids deprecated APIs',
-failureDescription:'Uses deprecated API\'s',
-helpText:'Deprecated APIs will eventually be removed from the browser. '+
-'[Learn more](https://www.chromestatus.com/features#deprecated).',
-requiredArtifacts:['ChromeConsoleMessages']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const entries=artifacts.ChromeConsoleMessages;
-
-const deprecations=entries.filter(log=>log.entry.source==='deprecation').map(log=>{
-return{
-type:'code',
-text:log.entry.text,
-url:log.entry.url,
-source:log.entry.source,
-lineNumber:log.entry.lineNumber};
-
-});
-
-const headings=[
-{key:'text',itemType:'code',text:'Deprecation / Warning'},
-{key:'url',itemType:'url',text:'URL'},
-{key:'lineNumber',itemType:'text',text:'Line'}];
-
-const details=Audit.makeTableDetails(headings,deprecations);
-
-let displayValue='';
-if(deprecations.length>1){
-displayValue=`${Util.formatNumber(deprecations.length)} warnings found`;
-}else if(deprecations.length===1){
-displayValue=`${deprecations.length} warning found`;
-}
-
-return{
-rawValue:deprecations.length===0,
-displayValue,
-extendedInfo:{
-value:deprecations},
-
-details};
-
-}}
-
-
-module.exports=Deprecations;
-
-},{"../report/v2/renderer/util":43,"./audit":2}],"../audits/dobetterweb/appcache-manifest":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-
-class AppCacheManifestAttr extends Audit{
-
-
-
-static get meta(){
-return{
-name:'appcache-manifest',
-description:'Avoids Application Cache',
-failureDescription:'Uses Application Cache',
-helpText:'Application Cache is deprecated. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/appcache).',
-requiredArtifacts:['AppCacheManifest']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const usingAppcache=artifacts.AppCacheManifest!==null;
-const debugString=usingAppcache?
-`Found <html manifest="${artifacts.AppCacheManifest}">.`:'';
-
-return{
-rawValue:!usingAppcache,
-debugString};
-
-}}
-
-
-module.exports=AppCacheManifestAttr;
-
-},{"../audit":2}],"../audits/dobetterweb/dom-size":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const Util=require('../../report/v2/renderer/util.js');
-
-const MAX_DOM_NODES=1500;
-const MAX_DOM_TREE_WIDTH=60;
-const MAX_DOM_TREE_DEPTH=32;
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=2400;
-const SCORING_MEDIAN=3000;
-
-class DOMSize extends Audit{
-static get MAX_DOM_NODES(){
-return MAX_DOM_NODES;
-}
-
-
-
-
-static get meta(){
-return{
-name:'dom-size',
-description:'Avoids an excessive DOM size',
-failureDescription:'Uses an excessive DOM size',
-helpText:'Browser engineers recommend pages contain fewer than '+
-`~${Util.formatNumber(DOMSize.MAX_DOM_NODES)} DOM nodes. The sweet spot is a tree `+
-`depth < ${MAX_DOM_TREE_DEPTH} elements and fewer than ${MAX_DOM_TREE_WIDTH} `+
-'children/parent element. A large DOM can increase memory usage, cause longer '+
-'[style calculations](https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations), '+
-'and produce costly [layout reflows](https://developers.google.com/speed/articles/reflow). [Learn more](https://developers.google.com/web/fundamentals/performance/rendering/).',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['DOMStats']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const stats=artifacts.DOMStats;
-
-
-
-
-
-
-
-const depthSnippet=stats.depth.pathToElement.reduce((str,curr,i)=>{
-return`${str}\n`+'  '.repeat(i)+`${curr} >`;
-},'').replace(/>$/g,'').trim();
-const widthSnippet='Element with most children:\n'+
-stats.width.pathToElement[stats.width.pathToElement.length-1];
-
-
-
-
-
-const score=Audit.computeLogNormalScore(
-stats.totalDOMNodes,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-const cards=[{
-title:'Total DOM Nodes',
-value:Util.formatNumber(stats.totalDOMNodes),
-target:`< ${Util.formatNumber(MAX_DOM_NODES)} nodes`},
-{
-title:'DOM Depth',
-value:Util.formatNumber(stats.depth.max),
-snippet:depthSnippet,
-target:`< ${Util.formatNumber(MAX_DOM_TREE_DEPTH)}`},
-{
-title:'Maximum Children',
-value:Util.formatNumber(stats.width.max),
-snippet:widthSnippet,
-target:`< ${Util.formatNumber(MAX_DOM_TREE_WIDTH)} nodes`}];
-
-
-return{
-score,
-rawValue:stats.totalDOMNodes,
-displayValue:`${Util.formatNumber(stats.totalDOMNodes)} nodes`,
-extendedInfo:{
-value:cards},
-
-details:{
-type:'cards',
-header:{type:'text',text:'View details'},
-items:cards}};
-
-
-}}
-
-
-module.exports=DOMSize;
-
-},{"../../report/v2/renderer/util.js":43,"../audit":2}],"../audits/dobetterweb/external-anchors-use-rel-noopener":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const URL=require('../../lib/url-shim');
-const Audit=require('../audit');
-
-class ExternalAnchorsUseRelNoopenerAudit extends Audit{
-
-
-
-static get meta(){
-return{
-name:'external-anchors-use-rel-noopener',
-description:'Opens external anchors using `rel="noopener"`',
-failureDescription:'Does not open external anchors using `rel="noopener"`',
-helpText:'Open new tabs using `rel="noopener"` to improve performance and '+
-'prevent security vulnerabilities. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/noopener).',
-requiredArtifacts:['URL','AnchorsWithNoRelNoopener']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-let debugString;
-const pageHost=new URL(artifacts.URL.finalUrl).host;
-
-
-
-
-const failingAnchors=artifacts.AnchorsWithNoRelNoopener.
-filter(anchor=>{
-try{
-return new URL(anchor.href).host!==pageHost;
-}catch(err){
-debugString='Lighthouse was unable to determine the destination '+
-'of some anchor tags. If they are not used as hyperlinks, '+
-'consider removing the _blank target.';
-return true;
-}
-}).
-filter(anchor=>{
-return!anchor.href||anchor.href.toLowerCase().startsWith('http');
-}).
-map(anchor=>{
-return{
-href:anchor.href||'Unknown',
-target:anchor.target||'',
-rel:anchor.rel||'',
-url:'<a'+(
-anchor.href?` href="${anchor.href}"`:'')+(
-anchor.target?` target="${anchor.target}"`:'')+(
-anchor.rel?` rel="${anchor.rel}"`:'')+'>'};
-
-});
-
-const headings=[
-{key:'href',itemType:'url',text:'URL'},
-{key:'target',itemType:'text',text:'Target'},
-{key:'rel',itemType:'text',text:'Rel'}];
-
-
-const details=Audit.makeTableDetails(headings,failingAnchors);
-
-return{
-rawValue:failingAnchors.length===0,
-extendedInfo:{
-value:failingAnchors},
-
-details,
-debugString};
-
-}}
-
-
-module.exports=ExternalAnchorsUseRelNoopenerAudit;
-
-},{"../../lib/url-shim":41,"../audit":2}],"../audits/dobetterweb/geolocation-on-start":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ViolationAudit=require('../violation-audit');
-
-class GeolocationOnStart extends ViolationAudit{
-
-
-
-static get meta(){
-return{
-name:'geolocation-on-start',
-description:'Avoids requesting the geolocation permission on page load',
-failureDescription:'Requests the geolocation permission on page load',
-helpText:'Users are mistrustful of or confused by sites that request their '+
-'location without context. Consider tying the request to user gestures instead. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/geolocation-on-load).',
-requiredArtifacts:['ChromeConsoleMessages']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-
-const results=ViolationAudit.getViolationResults(artifacts,/geolocation/);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'label',itemType:'text',text:'Location'}];
-
-const details=ViolationAudit.makeTableDetails(headings,results);
-
-return{
-rawValue:results.length===0,
-extendedInfo:{
-value:results},
-
-details};
-
-}}
-
-
-module.exports=GeolocationOnStart;
-
-},{"../violation-audit":6}],"../audits/dobetterweb/link-blocking-first-paint":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const Util=require('../../report/v2/renderer/util.js');
-const scoreForWastedMs=require('../byte-efficiency/byte-efficiency-audit').scoreForWastedMs;
-
-
-
-
-
-const LOAD_THRESHOLD_IN_MS=50;
-
-class LinkBlockingFirstPaintAudit extends Audit{
-
-
-
-static get meta(){
-return{
-name:'link-blocking-first-paint',
-description:'Reduce render-blocking stylesheets',
-informative:true,
-helpText:'External stylesheets are blocking the first paint of your page. Consider '+
-'delivering critical CSS via `<style>` tags and deferring non-critical '+
-'styles. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources).',
-requiredArtifacts:['TagsBlockingFirstPaint','traces']};
-
-}
-
-
-
-
-
-
-
-
-
-
-static computeAuditResultForTags(artifacts,tagFilter,endTimeMax=Infinity,
-loadDurationThreshold=0){
-const artifact=artifacts.TagsBlockingFirstPaint;
-
-const filtered=artifact.filter(item=>{
-return item.tag.tagName===tagFilter&&
-(item.endTime-item.startTime)*1000>=loadDurationThreshold&&
-item.endTime*1000<endTimeMax;
-});
-
-const startTime=filtered.length===0?0:
-filtered.reduce((t,item)=>Math.min(t,item.startTime),Number.MAX_VALUE);
-let endTime=0;
-
-const results=filtered.map(item=>{
-endTime=Math.max(item.endTime,endTime);
-
-return{
-url:item.tag.url,
-totalKb:Util.formatBytesToKB(item.transferSize),
-totalMs:Util.formatMilliseconds(Math.round((item.endTime-startTime)*1000),1)};
-
-});
-
-const rawDelayTime=Math.round((endTime-startTime)*1000);
-const delayTime=Util.formatMilliseconds(rawDelayTime,1);
-let displayValue='';
-if(results.length>1){
-displayValue=`${results.length} resources delayed first paint by ${delayTime}`;
-}else if(results.length===1){
-displayValue=`${results.length} resource delayed first paint by ${delayTime}`;
-}
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'totalKb',itemType:'text',text:'Size (KB)'},
-{key:'totalMs',itemType:'text',text:'Delayed Paint By (ms)'}];
-
-
-const tableDetails=Audit.makeTableDetails(headings,results);
-
-return{
-displayValue,
-score:scoreForWastedMs(rawDelayTime),
-rawValue:rawDelayTime,
-extendedInfo:{
-value:{
-wastedMs:delayTime,
-results}},
-
-
-details:tableDetails};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-return artifacts.requestTraceOfTab(trace).then(traceOfTab=>{
-const fcpTsInMs=traceOfTab.timestamps.firstContentfulPaint/1000;
-return this.computeAuditResultForTags(artifacts,'LINK',fcpTsInMs,LOAD_THRESHOLD_IN_MS);
-});
-}}
-
-
-module.exports=LinkBlockingFirstPaintAudit;
-
-},{"../../report/v2/renderer/util.js":43,"../audit":2,"../byte-efficiency/byte-efficiency-audit":3}],"../audits/dobetterweb/no-document-write":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ViolationAudit=require('../violation-audit');
-
-class NoDocWriteAudit extends ViolationAudit{
-
-
-
-static get meta(){
-return{
-name:'no-document-write',
-description:'Avoids `document.write()`',
-failureDescription:'Uses `document.write()`',
-helpText:'For users on slow connections, external scripts dynamically injected via '+
-'`document.write()` can delay page load by tens of seconds. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/document-write).',
-requiredArtifacts:['ChromeConsoleMessages']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const results=ViolationAudit.getViolationResults(artifacts,/document\.write/);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'label',itemType:'text',text:'Location'}];
-
-const details=ViolationAudit.makeTableDetails(headings,results);
-
-return{
-rawValue:results.length===0,
-extendedInfo:{
-value:results},
-
-details};
-
-}}
-
-
-module.exports=NoDocWriteAudit;
-
-},{"../violation-audit":6}],"../audits/dobetterweb/no-mutation-events":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const URL=require('../../lib/url-shim');
-const Audit=require('../audit');
-const EventHelpers=require('../../lib/event-helpers');
-
-class NoMutationEventsAudit extends Audit{
-static get MUTATION_EVENTS(){
-return[
-'DOMAttrModified',
-'DOMAttributeNameChanged',
-'DOMCharacterDataModified',
-'DOMElementNameChanged',
-'DOMNodeInserted',
-'DOMNodeInsertedIntoDocument',
-'DOMNodeRemoved',
-'DOMNodeRemovedFromDocument',
-'DOMSubtreeModified'];
-
-}
-
-
-
-
-static get meta(){
-return{
-name:'no-mutation-events',
-description:'Avoids Mutation Events in its own scripts',
-failureDescription:'Uses Mutation Events in its own scripts',
-helpText:'Mutation Events are deprecated and harm performance. Consider using Mutation '+
-'Observers instead. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/mutation-events).',
-requiredArtifacts:['URL','EventListeners']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-let debugString;
-const listeners=artifacts.EventListeners;
-
-const results=listeners.filter(loc=>{
-const isMutationEvent=this.MUTATION_EVENTS.includes(loc.type);
-let sameHost=URL.hostsMatch(artifacts.URL.finalUrl,loc.url);
-
-if(!URL.isValid(loc.url)&&isMutationEvent){
-sameHost=true;
-debugString=URL.INVALID_URL_DEBUG_STRING;
-}
-
-return sameHost&&isMutationEvent;
-}).map(EventHelpers.addFormattedCodeSnippet);
-
-const groupedResults=EventHelpers.groupCodeSnippetsByLocation(results);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'type',itemType:'code',text:'Event'},
-{key:'line',itemType:'text',text:'Line'},
-{key:'col',itemType:'text',text:'Col'},
-{key:'pre',itemType:'code',text:'Snippet'}];
-
-const details=NoMutationEventsAudit.makeTableDetails(headings,groupedResults);
-
-return{
-rawValue:groupedResults.length===0,
-extendedInfo:{
-value:{
-results:groupedResults}},
-
-
-details,
-debugString};
-
-}}
-
-
-module.exports=NoMutationEventsAudit;
-
-},{"../../lib/event-helpers":29,"../../lib/url-shim":41,"../audit":2}],"../audits/dobetterweb/no-vulnerable-libraries":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const Sentry=require('../../lib/sentry');
-const semver=require('semver');
-const snykDatabase=require('../../../third-party/snyk/snapshot.json');
-
-const SEMVER_REGEX=/^(\d+\.\d+\.\d+)[^-0-9]+/;
-
-class NoVulnerableLibrariesAudit extends Audit{
-
-
-
-static get meta(){
-return{
-name:'no-vulnerable-libraries',
-description:'Avoids front-end JavaScript libraries'+
-' with known security vulnerabilities',
-failureDescription:'Includes front-end JavaScript libraries'+
-' with known security vulnerabilities',
-helpText:'Some third-party scripts may contain known security vulnerabilities '+
-' that are easily identified and exploited by attackers.',
-requiredArtifacts:['JSLibraries']};
-
-}
-
-
-
-
-static get snykDB(){
-return snykDatabase;
-}
-
-
-
-
-static get severityMap(){
-return{
-high:3,
-medium:2,
-low:1};
-
-}
-
-
-
-
-
-
-static normalizeVersion(version){
-if(!version)return version;
-if(semver.valid(version))return version;
-
-
-if(/^\d+\.\d+$/.test(version))return`${version}.0`;
-
-if(SEMVER_REGEX.test(version))return version.match(SEMVER_REGEX)[1];
-
-return version;
-}
-
-
-
-
-
-
-static getVulns(lib,snykDB){
-const vulns=[];
-if(!snykDB.npm[lib.npmPkgName]){
-return vulns;
-}
-
-try{
-semver.satisfies(lib.version,'*');
-}catch(err){
-err.pkgName=lib.npmPkgName;
-
-Sentry.captureException(err,{level:'warning'});
-return vulns;
-}
-
-lib.pkgLink=`https://snyk.io/vuln/npm:${lib.npmPkgName}?lh@${lib.version}`;
-const snykInfo=snykDB.npm[lib.npmPkgName];
-snykInfo.forEach(vuln=>{
-if(semver.satisfies(lib.version,vuln.semver.vulnerable[0])){
-
-vulns.push({
-severity:vuln.severity,
-numericSeverity:this.severityMap[vuln.severity],
-library:`${lib.name}@${lib.version}`,
-url:'https://snyk.io/vuln/'+vuln.id});
-
-}
-});
-return vulns;
-}
-
-
-
-
-
-static highestSeverity(vulns){
-const sortedVulns=vulns.
-sort((a,b)=>b.numericSeverity-a.numericSeverity);
-return sortedVulns[0].severity;
-}
-
-
-
-
-
-static audit(artifacts){
-const libraries=artifacts.JSLibraries;
-if(!libraries.length){
-return{
-rawValue:true};
-
-}
-
-let totalVulns=0;
-const finalVulns=libraries.map(lib=>{
-lib.version=this.normalizeVersion(lib.version);
-lib.vulns=this.getVulns(lib,this.snykDB);
-if(lib.vulns.length>0){
-lib.vulnCount=lib.vulns.length;
-lib.highestSeverity=this.highestSeverity(lib.vulns).replace(/^\w/,l=>l.toUpperCase());
-totalVulns+=lib.vulnCount;
-lib.detectedLib={};
-lib.detectedLib.text=lib.name+'@'+lib.version;
-lib.detectedLib.url=lib.pkgLink;
-lib.detectedLib.type='link';
-}
-return lib;
-}).
-filter(obj=>{
-return obj.vulns.length>0;
-});
-
-let displayValue='';
-if(totalVulns>1){
-displayValue=`${totalVulns} vulnerabilities detected.`;
-}else if(totalVulns===1){
-displayValue=`${totalVulns} vulnerability was detected.`;
-}
-
-const headings=[
-{key:'detectedLib',itemType:'link',text:'Library Version'},
-{key:'vulnCount',itemType:'text',text:'Vulnerability Count'},
-{key:'highestSeverity',itemType:'text',text:'Highest Severity'}];
-
-const details=Audit.makeTableDetails(headings,finalVulns);
-
-return{
-rawValue:totalVulns===0,
-displayValue,
-extendedInfo:{
-jsLibs:libraries,
-vulnerabilities:finalVulns},
-
-details};
-
-}}
-
-
-module.exports=NoVulnerableLibrariesAudit;
-
-},{"../../../third-party/snyk/snapshot.json":147,"../../lib/sentry":33,"../audit":2,"semver":142}],"../audits/dobetterweb/no-websql":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-
-class NoWebSQLAudit extends Audit{
-
-
-
-static get meta(){
-return{
-name:'no-websql',
-description:'Avoids WebSQL DB',
-failureDescription:'Uses WebSQL DB',
-helpText:'Web SQL is deprecated. Consider using IndexedDB instead. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/web-sql).',
-requiredArtifacts:['WebSQL']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const db=artifacts.WebSQL;
-const debugString=db?
-`Found database "${db.name}", version: ${db.version}.`:'';
-
-return{
-rawValue:!db,
-debugString};
-
-}}
-
-
-module.exports=NoWebSQLAudit;
-
-},{"../audit":2}],"../audits/dobetterweb/notification-on-start":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ViolationAudit=require('../violation-audit');
-
-class NotificationOnStart extends ViolationAudit{
-
-
-
-static get meta(){
-return{
-name:'notification-on-start',
-description:'Avoids requesting the notification permission on page load',
-failureDescription:'Requests the notification permission on page load',
-helpText:'Users are mistrustful of or confused by sites that request to send '+
-'notifications without context. Consider tying the request to user gestures '+
-'instead. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/notifications-on-load).',
-requiredArtifacts:['ChromeConsoleMessages']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const results=ViolationAudit.getViolationResults(artifacts,/notification permission/);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'label',itemType:'text',text:'Location'}];
-
-const details=ViolationAudit.makeTableDetails(headings,results);
-
-return{
-rawValue:results.length===0,
-extendedInfo:{
-value:results},
-
-details};
-
-}}
-
-
-module.exports=NotificationOnStart;
-
-},{"../violation-audit":6}],"../audits/dobetterweb/password-inputs-can-be-pasted-into":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-
-class PasswordInputsCanBePastedIntoAudit extends Audit{
-
-
-
-static get meta(){
-return{
-name:'password-inputs-can-be-pasted-into',
-description:'Allows users to paste into password fields',
-failureDescription:'Prevents users to paste into password fields',
-helpText:'Preventing password pasting undermines good security policy. '+
-'[Learn more](https://www.ncsc.gov.uk/blog-post/let-them-paste-passwords)',
-requiredArtifacts:['PasswordInputsWithPreventedPaste']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const passwordInputsWithPreventedPaste=artifacts.PasswordInputsWithPreventedPaste;
-
-return{
-rawValue:passwordInputsWithPreventedPaste.length===0,
-extendedInfo:{
-value:passwordInputsWithPreventedPaste},
-
-details:{
-type:'list',
-header:{
-type:'text',
-text:'Password inputs that prevent pasting into'},
-
-items:passwordInputsWithPreventedPaste.map(input=>({
-type:'text',
-text:input.snippet}))}};
-
-
-
-}}
-
-
-module.exports=PasswordInputsCanBePastedIntoAudit;
-
-},{"../audit":2}],"../audits/dobetterweb/script-blocking-first-paint":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const LinkBlockingFirstPaintAudit=require('./link-blocking-first-paint');
-
-class ScriptBlockingFirstPaint extends Audit{
-
-
-
-static get meta(){
-return{
-name:'script-blocking-first-paint',
-description:'Reduce render-blocking scripts',
-informative:true,
-helpText:'Script elements are blocking the first paint of your page. Consider inlining '+
-'critical scripts and deferring non-critical ones. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources).',
-requiredArtifacts:['TagsBlockingFirstPaint','traces']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-return artifacts.requestTraceOfTab(trace).then(traceOfTab=>{
-const fcpTsInMs=traceOfTab.timestamps.firstContentfulPaint/1000;
-return LinkBlockingFirstPaintAudit.computeAuditResultForTags(artifacts,'SCRIPT',fcpTsInMs);
-});
-}}
-
-
-module.exports=ScriptBlockingFirstPaint;
-
-},{"../audit":2,"./link-blocking-first-paint":"../audits/dobetterweb/link-blocking-first-paint"}],"../audits/dobetterweb/uses-http2":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const URL=require('../../lib/url-shim');
-const Audit=require('../audit');
-const Util=require('../../report/v2/renderer/util.js');
-
-class UsesHTTP2Audit extends Audit{
-
-
-
-static get meta(){
-return{
-name:'uses-http2',
-description:'Uses HTTP/2 for its own resources',
-failureDescription:'Does not use HTTP/2 for all of its resources',
-helpText:'HTTP/2 offers many benefits over HTTP/1.1, including binary headers, '+
-'multiplexing, and server push. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/http2).',
-requiredArtifacts:['URL','devtoolsLogs']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-return artifacts.requestNetworkRecords(devtoolsLogs).then(networkRecords=>{
-const finalHost=new URL(artifacts.URL.finalUrl).host;
-
-
-const resources=networkRecords.filter(record=>{
-
-const isOldHttp=/HTTP\/[01][.\d]?/i.test(record.protocol);
-if(!isOldHttp)return false;
-const requestHost=new URL(record._url).host;
-return requestHost===finalHost;
-}).map(record=>{
-return{
-protocol:record.protocol,
-url:record.url};
-
-});
-
-let displayValue='';
-if(resources.length>1){
-displayValue=
-`${Util.formatNumber(resources.length)} requests were not handled over HTTP/2`;
-}else if(resources.length===1){
-displayValue=`${resources.length} request was not handled over HTTP/2`;
-}
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'protocol',itemType:'text',text:'Protocol'}];
-
-const details=Audit.makeTableDetails(headings,resources);
-
-return{
-rawValue:resources.length===0,
-displayValue:displayValue,
-extendedInfo:{
-value:{
-results:resources}},
-
-
-details};
-
-});
-}}
-
-
-module.exports=UsesHTTP2Audit;
-
-},{"../../lib/url-shim":41,"../../report/v2/renderer/util.js":43,"../audit":2}],"../audits/dobetterweb/uses-passive-event-listeners":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const ViolationAudit=require('../violation-audit');
-
-class PassiveEventsAudit extends ViolationAudit{
-
-
-
-static get meta(){
-return{
-name:'uses-passive-event-listeners',
-description:'Uses passive listeners to improve scrolling performance',
-failureDescription:'Does not use passive listeners to improve scrolling performance',
-helpText:'Consider marking your touch and wheel event listeners as `passive` '+
-'to improve your page\'s scroll performance. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/passive-event-listeners).',
-requiredArtifacts:['ChromeConsoleMessages']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const results=ViolationAudit.getViolationResults(artifacts,/passive event listener/);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'label',itemType:'text',text:'Location'}];
-
-const details=ViolationAudit.makeTableDetails(headings,results);
-
-return{
-rawValue:results.length===0,
-extendedInfo:{
-value:results},
-
-details};
-
-}}
-
-
-module.exports=PassiveEventsAudit;
-
-},{"../violation-audit":6}],"../audits/errors-in-console":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const Audit=require('./audit');
-
-class ErrorLogs extends Audit{
-
-
-
-static get meta(){
-return{
-name:'errors-in-console',
-description:'No browser errors logged to the console',
-helpText:'Errors logged to the console indicate unresolved problems. '+
-'They can come from network request failures and other browser concerns.',
-failureDescription:'Browser errors were logged to the console',
-requiredArtifacts:['ChromeConsoleMessages','RuntimeExceptions']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const consoleEntries=artifacts.ChromeConsoleMessages;
-const runtimeExceptions=artifacts.RuntimeExceptions;
-const consoleRows=
-consoleEntries.filter(log=>log.entry&&log.entry.level==='error').
-map(item=>{
-return{
-source:item.entry.source,
-description:item.entry.text,
-url:item.entry.url};
-
-});
-
-const runtimeExRows=
-runtimeExceptions.filter(entry=>entry.exceptionDetails!==undefined).
-map(entry=>{
-const description=entry.exceptionDetails.exception?
-entry.exceptionDetails.exception.description:entry.exceptionDetails.text;
-
-return{
-source:'Runtime.exception',
-description,
-url:entry.exceptionDetails.url};
-
-});
-
-const tableRows=consoleRows.concat(runtimeExRows);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'description',itemType:'code',text:'Description'}];
-
-
-const details=Audit.makeTableDetails(headings,tableRows);
-const numErrors=tableRows.length;
-
-return{
-score:numErrors===0,
-rawValue:numErrors,
-details};
-
-}}
-
-
-module.exports=ErrorLogs;
-
-},{"./audit":2}],"../audits/estimated-input-latency":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const TracingProcessor=require('../lib/traces/tracing-processor');
-const LHError=require('../lib/errors');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=50;
-const SCORING_MEDIAN=100;
-
-class EstimatedInputLatency extends Audit{
-
-
-
-static get meta(){
-return{
-name:'estimated-input-latency',
-description:'Estimated Input Latency',
-helpText:'The score above is an estimate of how long your app takes to respond to user '+
-'input, in milliseconds. There is a 90% probability that a user encounters this amount '+
-'of latency, or less. 10% of the time a user can expect additional latency. If your '+
-'latency is higher than 50 ms, users may perceive your app as laggy. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency).',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['traces']};
-
-}
-
-static calculate(tabTrace){
-const startTime=tabTrace.timings.firstMeaningfulPaint;
-if(!startTime){
-throw new LHError(LHError.errors.NO_FMP);
-}
-
-const latencyPercentiles=TracingProcessor.getRiskToResponsiveness(tabTrace,startTime);
-const ninetieth=latencyPercentiles.find(result=>result.percentile===0.9);
-const rawValue=parseFloat(ninetieth.time.toFixed(1));
-
-
-
-
-
-
-
-const score=Audit.computeLogNormalScore(
-ninetieth.time,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-return{
-score,
-rawValue,
-displayValue:Util.formatMilliseconds(rawValue,1),
-extendedInfo:{
-value:latencyPercentiles}};
-
-
-}
-
-
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[this.DEFAULT_PASS];
-
-return artifacts.requestTraceOfTab(trace).
-then(EstimatedInputLatency.calculate);
-}}
-
-
-module.exports=EstimatedInputLatency;
-
-},{"../lib/errors":28,"../lib/traces/tracing-processor":40,"../report/v2/renderer/util":43,"./audit":2}],"../audits/first-interactive":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util.js');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=1700;
-const SCORING_MEDIAN=10000;
-
-class FirstInteractiveMetric extends Audit{
-
-
-
-static get meta(){
-return{
-name:'first-interactive',
-description:'First Interactive (beta)',
-helpText:'First Interactive marks the time at which the page is '+
-'minimally interactive. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-interactive).',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['traces']};
-
-}
-
-
-
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-return artifacts.requestFirstInteractive(trace).
-then(firstInteractive=>{
-return{
-score:Audit.computeLogNormalScore(
-firstInteractive.timeInMs,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN),
-
-rawValue:firstInteractive.timeInMs,
-displayValue:Util.formatMilliseconds(firstInteractive.timeInMs),
-extendedInfo:{
-value:firstInteractive}};
-
-
-});
-}}
-
-
-module.exports=FirstInteractiveMetric;
-
-},{"../report/v2/renderer/util.js":43,"./audit":2}],"../audits/first-meaningful-paint":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const LHError=require('../lib/errors');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=1600;
-const SCORING_MEDIAN=4000;
-
-
-class FirstMeaningfulPaint extends Audit{
-
-
-
-static get meta(){
-return{
-name:'first-meaningful-paint',
-description:'First meaningful paint',
-helpText:'First meaningful paint measures when the primary content of a page is visible. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint).',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['traces']};
-
-}
-
-
-
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[this.DEFAULT_PASS];
-return artifacts.requestTraceOfTab(trace).then(tabTrace=>{
-if(!tabTrace.firstMeaningfulPaintEvt){
-throw new LHError(LHError.errors.NO_FMP);
-}
-
-
-
-if(!tabTrace.navigationStartEvt){
-throw new LHError(LHError.errors.NO_NAVSTART);
-}
-
-const result=this.calculateScore(tabTrace);
-
-return{
-score:result.score,
-rawValue:parseFloat(result.duration),
-displayValue:Util.formatMilliseconds(result.duration),
-debugString:result.debugString,
-extendedInfo:{
-value:result.extendedInfo}};
-
-
-});
-}
-
-static calculateScore(traceOfTab){
-
-const extendedInfo={
-timestamps:{
-navStart:traceOfTab.timestamps.navigationStart,
-fCP:traceOfTab.timestamps.firstContentfulPaint,
-fMP:traceOfTab.timestamps.firstMeaningfulPaint,
-onLoad:traceOfTab.timestamps.onLoad,
-endOfTrace:traceOfTab.timestamps.traceEnd},
-
-timings:{
-navStart:0,
-fCP:traceOfTab.timings.firstContentfulPaint,
-fMP:traceOfTab.timings.firstMeaningfulPaint,
-onLoad:traceOfTab.timings.onLoad,
-endOfTrace:traceOfTab.timings.traceEnd},
-
-fmpFellBack:traceOfTab.fmpFellBack};
-
-
-Object.keys(extendedInfo.timings).forEach(key=>{
-const val=extendedInfo.timings[key];
-if(typeof val!=='number'||Number.isNaN(val)){
-extendedInfo.timings[key]=undefined;
-extendedInfo.timestamps[key]=undefined;
-}else{
-extendedInfo.timings[key]=parseFloat(extendedInfo.timings[key].toFixed(3));
-}
-});
-
-
-
-
-
-const firstMeaningfulPaint=traceOfTab.timings.firstMeaningfulPaint;
-const score=Audit.computeLogNormalScore(
-firstMeaningfulPaint,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-return{
-score,
-duration:firstMeaningfulPaint.toFixed(1),
-rawValue:firstMeaningfulPaint,
-extendedInfo};
-
-}}
-
-
-module.exports=FirstMeaningfulPaint;
-
-},{"../lib/errors":28,"../report/v2/renderer/util":43,"./audit":2}],"../audits/font-display":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const WebInspector=require('../lib/web-inspector');
-const allowedFontFaceDisplays=['block','fallback','optional','swap'];
-
-class FontDisplay extends Audit{
-
-
-
-static get meta(){
-return{
-name:'font-display',
-description:'All text remains visible during webfont loads',
-failureDescription:'Avoid invisible text while webfonts are loading',
-helpText:'Leverage the font-display CSS feature to ensure text is user-visible while '+
-'webfonts are loading. '+
-'[Learn more](https://developers.google.com/web/updates/2016/02/font-display).',
-requiredArtifacts:['devtoolsLogs','Fonts']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[this.DEFAULT_PASS];
-const fontFaces=artifacts.Fonts;
-
-
-const fontsWithoutProperDisplay=fontFaces.filter(fontFace=>
-!fontFace.display||!allowedFontFaceDisplays.includes(fontFace.display));
-
-
-return artifacts.requestNetworkRecords(devtoolsLogs).then(networkRecords=>{
-const results=networkRecords.filter(record=>{
-const isFont=record._resourceType===WebInspector.resourceTypes.Font;
-
-return isFont;
-}).
-filter(fontRecord=>{
-
-return!!fontsWithoutProperDisplay.find(fontFace=>{
-return fontFace.src.find(src=>fontRecord.url===src);
-});
-}).
-
-map(record=>{
-
-
-const wastedTime=Math.min((record._endTime-record._startTime)*1000,3000);
-
-return{
-url:record.url,
-wastedTime:Util.formatMilliseconds(wastedTime,1)};
-
-});
-
-const headings=[
-{key:'url',itemType:'url',text:'Font URL'},
-{key:'wastedTime',itemType:'text',text:'Font download time'}];
-
-const details=Audit.makeTableDetails(headings,results);
-
-return{
-score:results.length===0,
-rawValue:results.length===0,
-details};
-
-});
-}}
-
-
-module.exports=FontDisplay;
-
-},{"../lib/web-inspector":42,"../report/v2/renderer/util":43,"./audit":2}],"../audits/image-aspect-ratio":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-const URL=require('../lib/url-shim');
-const THRESHOLD=0.05;
-
-class ImageAspectRatio extends Audit{
-
-
-
-static get meta(){
-return{
-name:'image-aspect-ratio',
-description:'Displays images with correct aspect ratio',
-failureDescription:'Displays images with incorrect aspect ratio',
-helpText:'Image display dimensions should match natural aspect ratio.',
-requiredArtifacts:['ImageUsage']};
-
-}
-
-
-
-
-
-static computeAspectRatios(image){
-const url=URL.elideDataURI(image.src);
-const actualAspectRatio=image.naturalWidth/image.naturalHeight;
-const displayedAspectRatio=image.width/image.height;
-const doRatiosMatch=Math.abs(actualAspectRatio-displayedAspectRatio)<THRESHOLD;
-
-if(!Number.isFinite(actualAspectRatio)||
-!Number.isFinite(displayedAspectRatio)){
-return new Error(`Invalid image sizing information ${url}`);
-}
-
-return{
-url,
-preview:{
-type:'thumbnail',
-url:image.networkRecord.url,
-mimeType:image.networkRecord.mimeType},
-
-displayedAspectRatio:`${image.width} x ${image.height}
-        (${displayedAspectRatio.toFixed(2)})`,
-actualAspectRatio:`${image.naturalWidth} x ${image.naturalHeight}
-        (${actualAspectRatio.toFixed(2)})`,
-doRatiosMatch};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const images=artifacts.ImageUsage;
-
-let debugString;
-const results=[];
-images.filter(image=>{
-
-
-
-return image.networkRecord&&
-image.networkRecord.mimeType!=='image/svg+xml'&&
-image.width&&
-image.height&&
-!image.usesObjectFit;
-}).forEach(image=>{
-const processed=ImageAspectRatio.computeAspectRatios(image);
-if(processed instanceof Error){
-debugString=processed.message;
-return;
-}
-
-if(!processed.doRatiosMatch)results.push(processed);
-});
-
-const headings=[
-{key:'preview',itemType:'thumbnail',text:''},
-{key:'url',itemType:'url',text:'URL'},
-{key:'displayedAspectRatio',itemType:'text',text:'Aspect Ratio (Displayed)'},
-{key:'actualAspectRatio',itemType:'text',text:'Aspect Ratio (Actual)'}];
-
-
-return{
-rawValue:results.length===0,
-debugString,
-details:Audit.makeTableDetails(headings,results)};
-
-}}
-
-
-module.exports=ImageAspectRatio;
-
-},{"../lib/url-shim":41,"./audit":2}],"../audits/is-on-https":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const URL=require('../lib/url-shim');
-const Util=require('../report/v2/renderer/util');
-
-const SECURE_SCHEMES=['data','https','wss','blob','chrome','chrome-extension'];
-const SECURE_DOMAINS=['localhost','127.0.0.1'];
-
-class HTTPS extends Audit{
-
-
-
-static get meta(){
-return{
-name:'is-on-https',
-description:'Uses HTTPS',
-failureDescription:'Does not use HTTPS',
-helpText:'All sites should be protected with HTTPS, even ones that don\'t handle '+
-'sensitive data. HTTPS prevents intruders from tampering with or passively listening '+
-'in on the communications between your app and your users, and is a prerequisite for '+
-'HTTP/2 and many new web platform APIs. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/https).',
-requiredArtifacts:['devtoolsLogs']};
-
-}
-
-
-
-
-
-static isSecureRecord(record){
-return SECURE_SCHEMES.includes(record.scheme)||
-SECURE_SCHEMES.includes(record.protocol)||
-SECURE_DOMAINS.includes(record.domain);
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-return artifacts.requestNetworkRecords(devtoolsLogs).then(networkRecords=>{
-const insecureRecords=networkRecords.
-filter(record=>!HTTPS.isSecureRecord(record)).
-map(record=>({url:URL.elideDataURI(record.url)}));
-
-let displayValue='';
-if(insecureRecords.length>1){
-displayValue=`${Util.formatNumber(insecureRecords.length)} insecure requests found`;
-}else if(insecureRecords.length===1){
-displayValue=`${insecureRecords.length} insecure request found`;
-}
-
-return{
-rawValue:insecureRecords.length===0,
-displayValue,
-extendedInfo:{
-value:insecureRecords},
-
-details:{
-type:'list',
-header:{type:'text',text:'Insecure URLs:'},
-items:insecureRecords.map(record=>({type:'url',text:record.url}))}};
-
-
-});
-}}
-
-
-module.exports=HTTPS;
-
-},{"../lib/url-shim":41,"../report/v2/renderer/util":43,"./audit":2}],"../audits/load-fast-enough-for-pwa":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const Audit=require('./audit');
-const URL=require('../lib/url-shim');
-const Emulation=require('../lib/emulation');
-const Sentry=require('../lib/sentry');
-const Util=require('../report/v2/renderer/util.js');
-
-
-
-const MAXIMUM_TTFI=10*1000;
-
-const WHITELISTED_STATUS_CODES=[307];
-
-class LoadFastEnough4Pwa extends Audit{
-
-
-
-static get meta(){
-return{
-name:'load-fast-enough-for-pwa',
-description:'Page load is fast enough on 3G',
-failureDescription:'Page load is not fast enough on 3G',
-helpText:'A fast page load over a 3G network ensures a good mobile user experience. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/fast-3g).',
-requiredArtifacts:['traces','devtoolsLogs']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-return artifacts.requestNetworkRecords(devtoolsLogs).then(networkRecords=>{
-const firstRequestLatenciesByOrigin=new Map();
-networkRecords.forEach(record=>{
-
-
-const fromCache=record._fromDiskCache||record._fromMemoryCache;
-const origin=URL.getOrigin(record._url);
-if(!origin||!record._timing||fromCache||
-WHITELISTED_STATUS_CODES.includes(record.statusCode)||!record.finished){
-return;
-}
-
-
-
-if(record._startTime<record._issueTime){
-return;
-}
-
-
-const latency=record._timing.receiveHeadersEnd-record._timing.sendEnd;
-const latencyInfo={
-url:record._url,
-startTime:record._startTime,
-origin,
-latency};
-
-
-
-
-const existing=firstRequestLatenciesByOrigin.get(origin);
-if(!existing||latencyInfo.startTime<existing.startTime){
-firstRequestLatenciesByOrigin.set(origin,latencyInfo);
-}
-});
-
-let firstRequestLatencies=Array.from(firstRequestLatenciesByOrigin.values());
-const latency3gMin=Emulation.settings.TYPICAL_MOBILE_THROTTLING_METRICS.targetLatency-10;
-const areLatenciesAll3G=firstRequestLatencies.every(val=>val.latency>latency3gMin);
-firstRequestLatencies=firstRequestLatencies.map(item=>({
-url:item.url,
-latency:Util.formatNumber(item.latency,2)}));
-
-
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-return artifacts.requestFirstInteractive(trace).then(firstInteractive=>{
-const timeToFirstInteractive=firstInteractive.timeInMs;
-const isFast=timeToFirstInteractive<MAXIMUM_TTFI;
-
-const extendedInfo={
-value:{areLatenciesAll3G,firstRequestLatencies,isFast,timeToFirstInteractive}};
-
-
-const details=Audit.makeTableDetails([
-{key:'url',itemType:'url',text:'URL'},
-{key:'latency',itemType:'text',text:'Latency (ms)'}],
-firstRequestLatencies);
-
-if(!isFast){
-return{
-rawValue:false,
-
-debugString:`First Interactive was at ${Util.formatMilliseconds(timeToFirstInteractive)}. More details in the "Performance" section.`,
-extendedInfo};
-
-}
-
-if(!areLatenciesAll3G){
-const sentryContext=Sentry.getContext();
-const hadThrottlingEnabled=sentryContext&&sentryContext.extra&&
-sentryContext.extra.networkThrottling;
-
-if(hadThrottlingEnabled){
-
-
-const violatingLatency=firstRequestLatencies.
-find(item=>Number(item.latency)<latency3gMin);
-Sentry.captureMessage('Network request latencies were not realistic',{
-tags:{audit:this.meta.name},
-extra:{violatingLatency},
-level:'warning'});
-
-}
-
-return{
-rawValue:true,
-
-debugString:`First Interactive was found at ${Util.formatMilliseconds(timeToFirstInteractive)}; however, the network request latencies were not sufficiently realistic, so the performance measurements cannot be trusted.`,
-extendedInfo,
-details};
-
-}
-
-return{
-rawValue:true,
-extendedInfo};
-
-});
-});
-}}
-
-
-module.exports=LoadFastEnough4Pwa;
-
-},{"../lib/emulation":27,"../lib/sentry":33,"../lib/url-shim":41,"../report/v2/renderer/util.js":43,"./audit":2}],"../audits/mainthread-work-breakdown":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-
-const{taskToGroup}=require('../lib/task-groups');
-
-class PageExecutionTimings extends Audit{
-
-
-
-static get meta(){
-return{
-category:'Performance',
-name:'mainthread-work-breakdown',
-description:'Main thread work breakdown',
-informative:true,
-helpText:'Consider reducing the time spent parsing, compiling and executing JS.'+
-'You may find delivering smaller JS payloads helps with this.',
-requiredArtifacts:['traces']};
-
-}
-
-
-
-
-
-static getExecutionTimingsByCategory(timelineModel){
-const bottomUpByName=timelineModel.bottomUpGroupBy('EventName');
-
-const result=new Map();
-bottomUpByName.children.forEach((event,eventName)=>
-result.set(eventName,event.selfTime));
-
-return result;
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[PageExecutionTimings.DEFAULT_PASS];
-
-return artifacts.requestDevtoolsTimelineModel(trace).
-then(devtoolsTimelineModel=>{
-const executionTimings=PageExecutionTimings.getExecutionTimingsByCategory(
-devtoolsTimelineModel);
-
-let totalExecutionTime=0;
-
-const extendedInfo={};
-const categoryTotals={};
-const results=Array.from(executionTimings).map(([eventName,duration])=>{
-totalExecutionTime+=duration;
-extendedInfo[eventName]=duration;
-const groupName=taskToGroup[eventName];
-
-const categoryTotal=categoryTotals[groupName]||0;
-categoryTotals[groupName]=categoryTotal+duration;
-
-return{
-category:eventName,
-group:groupName,
-duration:Util.formatMilliseconds(duration,1)};
-
-});
-
-const headings=[
-{key:'group',itemType:'text',text:'Category'},
-{key:'category',itemType:'text',text:'Work'},
-{key:'duration',itemType:'text',text:'Time spent'}];
-
-results.stableSort((a,b)=>categoryTotals[b.group]-categoryTotals[a.group]);
-const tableDetails=PageExecutionTimings.makeTableDetails(headings,results);
-
-return{
-score:totalExecutionTime<3000,
-rawValue:totalExecutionTime,
-displayValue:Util.formatMilliseconds(totalExecutionTime),
-details:tableDetails,
-extendedInfo:{
-value:extendedInfo}};
-
-
-});
-}}
-
-
-module.exports=PageExecutionTimings;
-
-},{"../lib/task-groups":36,"../report/v2/renderer/util":43,"./audit":2}],"../audits/manifest-short-name-length":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-class ManifestShortNameLength extends Audit{
-
-
-
-static get meta(){
-return{
-name:'manifest-short-name-length',
-description:'Manifest\'s `short_name` won\'t be truncated when displayed on homescreen',
-failureDescription:'Manifest\'s `short_name` will be truncated when displayed '+
-'on homescreen',
-helpText:'Make your app\'s `short_name` fewer than 12 characters to '+
-'ensure that it\'s not truncated on homescreens. [Learn '+
-'more](https://developers.google.com/web/tools/lighthouse/audits/manifest-short_name-is-not-truncated).',
-requiredArtifacts:['Manifest']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-return artifacts.requestManifestValues(artifacts.Manifest).then(manifestValues=>{
-if(manifestValues.isParseFailure){
-return{
-rawValue:false};
-
-}
-
-const hasShortName=manifestValues.allChecks.find(i=>i.id==='hasShortName').passing;
-if(!hasShortName){
-return{
-rawValue:false,
-debugString:'No short_name found in manifest.'};
-
-}
-
-const isShortEnough=manifestValues.allChecks.find(i=>i.id==='shortNameLength').passing;
-return{
-rawValue:isShortEnough};
-
-});
-}}
-
-
-module.exports=ManifestShortNameLength;
-
-},{"./audit":2}],"../audits/manual/pwa-cross-browser":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('./manual-audit');
-
-
-
-
-
-class PWACrossBrowser extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'pwa-cross-browser',
-helpText:'To reach the most number of users, sites should work across '+
-'every major browser. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser).',
-description:'Site works cross-browser'},
-super.meta);
-}}
-
-
-module.exports=PWACrossBrowser;
-
-},{"./manual-audit":4}],"../audits/manual/pwa-each-page-has-url":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('./manual-audit');
-
-
-
-
-
-class PWAEachPageHasURL extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'pwa-each-page-has-url',
-helpText:'Ensure individual pages are deep linkable via the URLs and that URLs are '+
-'unique for the purpose of shareability on social media. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url).',
-description:'Each page has a URL'},
-super.meta);
-}}
-
-
-module.exports=PWAEachPageHasURL;
-
-},{"./manual-audit":4}],"../audits/manual/pwa-page-transitions":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('./manual-audit');
-
-
-
-
-
-class PWAPageTransitions extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'pwa-page-transitions',
-helpText:'Transitions should feel snappy as you tap around, even on a slow network, a key '+
-'to perceived performance. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network).',
-description:'Page transitions don\'t feel like they block on the network'},
-super.meta);
-}}
-
-
-module.exports=PWAPageTransitions;
-
-},{"./manual-audit":4}],"../audits/mixed-content":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const URL=require('../lib/url-shim');
-const Util=require('../report/v2/renderer/util');
-
-
-
-
-
-
-
-class MixedContent extends Audit{
-
-
-
-static get meta(){
-return{
-category:'Mixed Content',
-name:'mixed-content',
-description:'All resources loaded are secure',
-informative:true,
-failureDescription:'Some insecure resources can be upgraded to HTTPS',
-helpText:`Mixed content warnings can prevent you from upgrading to HTTPS.
-      This audit shows which insecure resources this page uses that can be
-      upgraded to HTTPS. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/mixed-content)`,
-requiredArtifacts:['devtoolsLogs','MixedContent']};
-
-}
-
-
-
-
-
-
-
-
-
-static isSecureRecord(record){
-return record.securityState()==='secure'||record.protocol==='data';
-}
-
-
-
-
-
-
-
-static upgradeURL(url){
-const parsedURL=new URL(url);
-parsedURL.protocol='https:';
-return parsedURL.href;
-}
-
-
-
-
-
-
-
-static simplifyURL(url){
-const parsedURL=new URL(url);
-parsedURL.hash='';
-parsedURL.search='';
-return parsedURL.href;
-}
-
-
-
-
-
-
-
-static displayURL(url){
-const displayOptions={
-numPathParts:4,
-preserveQuery:false,
-preserveHost:true};
-
-return URL.getURLDisplayName(url,displayOptions);
-}
-
-
-
-
-
-static audit(artifacts){
-const defaultLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-const upgradeLogs=artifacts.devtoolsLogs['mixedContentPass'];
-const baseHostname=new URL(artifacts.MixedContent.url).host;
-
-const computedArtifacts=[
-artifacts.requestNetworkRecords(defaultLogs),
-artifacts.requestNetworkRecords(upgradeLogs)];
-
-
-return Promise.all(computedArtifacts).then(([defaultRecords,upgradedRecords])=>{
-const insecureRecords=defaultRecords.filter(
-record=>!MixedContent.isSecureRecord(record));
-const secureRecords=defaultRecords.filter(
-record=>MixedContent.isSecureRecord(record));
-
-const upgradePassHosts=new Set();
-const upgradePassSecureHosts=new Set();
-upgradedRecords.forEach(record=>{
-upgradePassHosts.add(new URL(record.url).hostname);
-if(MixedContent.isSecureRecord(record)&&record.finished&&!record.failed){
-upgradePassSecureHosts.add(new URL(record.url).hostname);
-}
-});
-
-
-
-
-const seen=new Set();
-const upgradeableResources=[];
-
-for(const record of insecureRecords){
-const simpleUrl=this.simplifyURL(record.url);
-if(seen.has(simpleUrl))continue;
-seen.add(simpleUrl);
-
-const resource={
-host:new URL(record.url).hostname,
-fullUrl:record.url,
-referrerDocUrl:this.displayURL(record._documentURL)};
-
-
-if(!upgradePassSecureHosts.has(resource.host))continue;
-
-if(!resource.referrerDocUrl.includes(baseHostname))continue;
-
-upgradeableResources.push(resource);
-}
-
-const displayValue=`${Util.formatNumber(upgradeableResources.length)}
-          ${upgradeableResources.length===1?'request':'requests'}`;
-
-const headings=[
-{key:'fullUrl',itemType:'url',text:'URL'}];
-
-const details=Audit.makeTableDetails(headings,upgradeableResources);
-
-const totalRecords=defaultRecords.length;
-const score=100*(
-secureRecords.length+0.5*upgradeableResources.length)/
-totalRecords;
-
-return{
-rawValue:score,
-displayValue:displayValue,
-details};
-
-});
-}}
-
-
-module.exports=MixedContent;
-
-},{"../lib/url-shim":41,"../report/v2/renderer/util":43,"./audit":2}],"../audits/predictive-perf":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util.js');
-const LoadSimulator=require('../lib/dependency-graph/simulator/simulator.js');
-const Node=require('../lib/dependency-graph/node.js');
-const WebInspector=require('../lib/web-inspector');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=1700;
-const SCORING_MEDIAN=10000;
-
-
-const CRITICAL_LONG_TASK_THRESHOLD=20;
-
-const COEFFICIENTS={
-FCP:{
-intercept:1440,
-optimistic:-1.75,
-pessimistic:2.73},
-
-FMP:{
-intercept:1532,
-optimistic:-.30,
-pessimistic:1.33},
-
-TTCI:{
-intercept:1582,
-optimistic:.97,
-pessimistic:.49}};
-
-
-
-class PredictivePerf extends Audit{
-
-
-
-static get meta(){
-return{
-name:'predictive-perf',
-description:'Predicted Performance (beta)',
-helpText:
-'Predicted performance evaluates how your site will perform under '+
-'a 3G connection on a mobile device.',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['traces','devtoolsLogs']};
-
-}
-
-
-
-
-
-
-static getScriptUrls(dependencyGraph,condition){
-const scriptUrls=new Set();
-
-dependencyGraph.traverse(node=>{
-if(node.type===Node.TYPES.CPU)return;
-if(node.record._resourceType!==WebInspector.resourceTypes.Script)return;
-if(condition&&!condition(node))return;
-scriptUrls.add(node.record.url);
-});
-
-return scriptUrls;
-}
-
-
-
-
-
-
-static getOptimisticFCPGraph(dependencyGraph,traceOfTab){
-const fcp=traceOfTab.timestamps.firstContentfulPaint;
-const blockingScriptUrls=PredictivePerf.getScriptUrls(dependencyGraph,node=>{
-return(
-node.endTime<=fcp&&node.hasRenderBlockingPriority()&&node.initiatorType!=='script');
-
-});
-
-return dependencyGraph.cloneWithRelationships(node=>{
-if(node.endTime>fcp)return false;
-
-if(node.type===Node.TYPES.CPU)return node.isEvaluateScriptFor(blockingScriptUrls);
-
-return node.hasRenderBlockingPriority()&&node.initiatorType!=='script';
-});
-}
-
-
-
-
-
-
-static getPessimisticFCPGraph(dependencyGraph,traceOfTab){
-const fcp=traceOfTab.timestamps.firstContentfulPaint;
-const blockingScriptUrls=PredictivePerf.getScriptUrls(dependencyGraph,node=>{
-return node.endTime<=fcp&&node.hasRenderBlockingPriority();
-});
-
-return dependencyGraph.cloneWithRelationships(node=>{
-if(node.endTime>fcp)return false;
-
-if(node.type===Node.TYPES.CPU)return node.isEvaluateScriptFor(blockingScriptUrls);
-
-return node.hasRenderBlockingPriority();
-});
-}
-
-
-
-
-
-
-static getOptimisticFMPGraph(dependencyGraph,traceOfTab){
-const fmp=traceOfTab.timestamps.firstMeaningfulPaint;
-const requiredScriptUrls=PredictivePerf.getScriptUrls(dependencyGraph,node=>{
-return(
-node.endTime<=fmp&&node.hasRenderBlockingPriority()&&node.initiatorType!=='script');
-
-});
-
-return dependencyGraph.cloneWithRelationships(node=>{
-if(node.endTime>fmp)return false;
-
-if(node.type===Node.TYPES.CPU)return node.isEvaluateScriptFor(requiredScriptUrls);
-
-return node.hasRenderBlockingPriority()&&node.initiatorType!=='script';
-});
-}
-
-
-
-
-
-
-static getPessimisticFMPGraph(dependencyGraph,traceOfTab){
-const fmp=traceOfTab.timestamps.firstMeaningfulPaint;
-const requiredScriptUrls=PredictivePerf.getScriptUrls(dependencyGraph,node=>{
-return node.endTime<=fmp&&node.hasRenderBlockingPriority();
-});
-
-return dependencyGraph.cloneWithRelationships(node=>{
-if(node.endTime>fmp)return false;
-
-
-if(node.type===Node.TYPES.CPU){
-return node.didPerformLayout()||node.isEvaluateScriptFor(requiredScriptUrls);
-}
-
-
-return node.hasRenderBlockingPriority();
-});
-}
-
-
-
-
-
-static getOptimisticTTCIGraph(dependencyGraph){
-
-const minimumCpuTaskDuration=CRITICAL_LONG_TASK_THRESHOLD*1000;
-
-return dependencyGraph.cloneWithRelationships(node=>{
-
-if(node.type===Node.TYPES.CPU)return node.event.dur>minimumCpuTaskDuration;
-
-const isImage=node.record._resourceType===WebInspector.resourceTypes.Image;
-const isScript=node.record._resourceType===WebInspector.resourceTypes.Script;
-return!isImage&&(isScript||
-node.record.priority()==='High'||
-node.record.priority()==='VeryHigh');
-});
-}
-
-
-
-
-
-static getPessimisticTTCIGraph(dependencyGraph){
-return dependencyGraph;
-}
-
-
-
-
-
-static getLastLongTaskEndTime(nodeTiming){
-return Array.from(nodeTiming.entries()).
-filter(([node,timing])=>node.type===Node.TYPES.CPU&&
-timing.endTime-timing.startTime>50).
-map(([_,timing])=>timing.endTime).
-reduce((max,x)=>Math.max(max,x),0);
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-return Promise.all([
-artifacts.requestPageDependencyGraph(trace,devtoolsLogs),
-artifacts.requestTraceOfTab(trace)]).
-then(([graph,traceOfTab])=>{
-const graphs={
-optimisticFCP:PredictivePerf.getOptimisticFCPGraph(graph,traceOfTab),
-pessimisticFCP:PredictivePerf.getPessimisticFCPGraph(graph,traceOfTab),
-optimisticFMP:PredictivePerf.getOptimisticFMPGraph(graph,traceOfTab),
-pessimisticFMP:PredictivePerf.getPessimisticFMPGraph(graph,traceOfTab),
-optimisticTTCI:PredictivePerf.getOptimisticTTCIGraph(graph,traceOfTab),
-pessimisticTTCI:PredictivePerf.getPessimisticTTCIGraph(graph,traceOfTab)};
-
-
-const values={};
-Object.keys(graphs).forEach(key=>{
-const estimate=new LoadSimulator(graphs[key]).simulate();
-const lastLongTaskEnd=PredictivePerf.getLastLongTaskEndTime(estimate.nodeTiming);
-
-switch(key){
-case'optimisticFCP':
-case'pessimisticFCP':
-case'optimisticFMP':
-case'pessimisticFMP':
-values[key]=estimate.timeInMs;
-break;
-case'optimisticTTCI':
-values[key]=Math.max(values.optimisticFMP,lastLongTaskEnd);
-break;
-case'pessimisticTTCI':
-values[key]=Math.max(values.pessimisticFMP,lastLongTaskEnd);
-break;}
-
-});
-
-values.roughEstimateOfFCP=COEFFICIENTS.FCP.intercept+
-COEFFICIENTS.FCP.optimistic*values.optimisticFCP+
-COEFFICIENTS.FCP.pessimistic*values.pessimisticFCP;
-values.roughEstimateOfFMP=COEFFICIENTS.FMP.intercept+
-COEFFICIENTS.FMP.optimistic*values.optimisticFMP+
-COEFFICIENTS.FMP.pessimistic*values.pessimisticFMP;
-values.roughEstimateOfTTCI=COEFFICIENTS.TTCI.intercept+
-COEFFICIENTS.TTCI.optimistic*values.optimisticTTCI+
-COEFFICIENTS.TTCI.pessimistic*values.pessimisticTTCI;
-
-
-
-values.roughEstimateOfFMP=Math.max(values.roughEstimateOfFCP,values.roughEstimateOfFMP);
-values.roughEstimateOfTTCI=Math.max(values.roughEstimateOfFMP,values.roughEstimateOfTTCI);
-
-const score=Audit.computeLogNormalScore(
-values.roughEstimateOfTTCI,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-return{
-score,
-rawValue:values.roughEstimateOfTTCI,
-displayValue:Util.formatMilliseconds(values.roughEstimateOfTTCI),
-extendedInfo:{value:values}};
-
-});
-}}
-
-
-module.exports=PredictivePerf;
-
-},{"../lib/dependency-graph/node.js":22,"../lib/dependency-graph/simulator/simulator.js":23,"../lib/web-inspector":42,"../report/v2/renderer/util.js":43,"./audit":2}],"../audits/redirects-http":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-class RedirectsHTTP extends Audit{
-
-
-
-static get meta(){
-return{
-name:'redirects-http',
-description:'Redirects HTTP traffic to HTTPS',
-failureDescription:'Does not redirect HTTP traffic to HTTPS',
-helpText:'If you\'ve already set up HTTPS, make sure that you redirect all HTTP traffic '+
-'to HTTPS. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https).',
-requiredArtifacts:['HTTPRedirect']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-return{
-rawValue:artifacts.HTTPRedirect.value,
-debugString:artifacts.HTTPRedirect.debugString};
-
-}}
-
-
-module.exports=RedirectsHTTP;
-
-},{"./audit":2}],"../audits/redirects":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const UnusedBytes=require('./byte-efficiency/byte-efficiency-audit');
-
-class Redirects extends Audit{
-
-
-
-static get meta(){
-return{
-name:'redirects',
-description:'Avoids page redirects',
-failureDescription:'Has multiple page redirects',
-helpText:'Redirects introduce additional delays before the page can be loaded. [Learn more](https://developers.google.com/speed/docs/insights/AvoidRedirects).',
-requiredArtifacts:['URL','devtoolsLogs']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-return artifacts.requestMainResource(artifacts.devtoolsLogs[Audit.DEFAULT_PASS]).
-then(mainResource=>{
-
-const redirectRequests=Array.from(mainResource.redirects||[]);
-
-
-redirectRequests.push(mainResource);
-
-let totalWastedMs=0;
-const pageRedirects=[];
-
-
-if(redirectRequests.length>1){
-pageRedirects.push({
-url:`(Initial: ${redirectRequests[0].url})`,
-wastedMs:'n/a'});
-
-}
-
-for(let i=1;i<redirectRequests.length;i++){
-const initialRequest=redirectRequests[i-1];
-const redirectedRequest=redirectRequests[i];
-
-const wastedMs=(redirectedRequest.startTime-initialRequest.startTime)*1000;
-totalWastedMs+=wastedMs;
-
-pageRedirects.push({
-url:redirectedRequest.url,
-wastedMs:Util.formatMilliseconds(wastedMs,1)});
-
-}
-
-const headings=[
-{key:'url',itemType:'text',text:'Redirected URL'},
-{key:'wastedMs',itemType:'text',text:'Time for Redirect'}];
-
-const details=Audit.makeTableDetails(headings,pageRedirects);
-
-return{
-
-score:redirectRequests.length<=2?100:UnusedBytes.scoreForWastedMs(totalWastedMs),
-rawValue:totalWastedMs,
-displayValue:Util.formatMilliseconds(totalWastedMs,1),
-extendedInfo:{
-value:{
-wastedMs:totalWastedMs}},
-
-
-details};
-
-});
-}}
-
-
-module.exports=Redirects;
-
-},{"../report/v2/renderer/util":43,"./audit":2,"./byte-efficiency/byte-efficiency-audit":3}],"../audits/screenshot-thumbnails":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const TTFI=require('./first-interactive');
-const TTCI=require('./consistently-interactive');
-const jpeg=require('jpeg-js');
-
-const NUMBER_OF_THUMBNAILS=10;
-const THUMBNAIL_WIDTH=120;
-
-class ScreenshotThumbnails extends Audit{
-
-
-
-static get meta(){
-return{
-name:'screenshot-thumbnails',
-informative:true,
-description:'Screenshot Thumbnails',
-helpText:'This is what the load of your site looked like.',
-requiredArtifacts:['traces']};
-
-}
-
-
-
-
-
-
-
-
-static scaleImageToThumbnail(imageData){
-const scaledWidth=THUMBNAIL_WIDTH;
-const scaleFactor=imageData.width/scaledWidth;
-const scaledHeight=Math.floor(imageData.height/scaleFactor);
-
-const outPixels=new Uint8Array(scaledWidth*scaledHeight*4);
-
-for(let i=0;i<scaledWidth;i++){
-for(let j=0;j<scaledHeight;j++){
-const origX=Math.floor(i*scaleFactor);
-const origY=Math.floor(j*scaleFactor);
-
-const origPos=(origY*imageData.width+origX)*4;
-const outPos=(j*scaledWidth+i)*4;
-
-outPixels[outPos]=imageData.data[origPos];
-outPixels[outPos+1]=imageData.data[origPos+1];
-outPixels[outPos+2]=imageData.data[origPos+2];
-outPixels[outPos+3]=imageData.data[origPos+3];
-}
-}
-
-return{
-width:scaledWidth,
-height:scaledHeight,
-data:outPixels};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-const cachedThumbnails=new Map();
-
-return Promise.all([
-artifacts.requestSpeedline(trace),
-TTFI.audit(artifacts).catch(()=>({rawValue:0})),
-TTCI.audit(artifacts).catch(()=>({rawValue:0}))]).
-then(([speedline,ttfi,ttci])=>{
-const thumbnails=[];
-const analyzedFrames=speedline.frames.filter(frame=>!frame.isProgressInterpolated());
-const maxFrameTime=
-speedline.complete||
-Math.max(...speedline.frames.map(frame=>frame.getTimeStamp()-speedline.beginning));
-
-
-const timelineEnd=Math.max(maxFrameTime,ttfi.rawValue,ttci.rawValue);
-
-for(let i=1;i<=NUMBER_OF_THUMBNAILS;i++){
-const targetTimestamp=speedline.beginning+timelineEnd*i/NUMBER_OF_THUMBNAILS;
-
-let frameForTimestamp=null;
-if(i===NUMBER_OF_THUMBNAILS){
-frameForTimestamp=analyzedFrames[analyzedFrames.length-1];
-}else{
-analyzedFrames.forEach(frame=>{
-if(frame.getTimeStamp()<=targetTimestamp){
-frameForTimestamp=frame;
-}
-});
-}
-
-const imageData=frameForTimestamp.getParsedImage();
-const thumbnailImageData=ScreenshotThumbnails.scaleImageToThumbnail(imageData);
-const base64Data=
-cachedThumbnails.get(frameForTimestamp)||
-jpeg.encode(thumbnailImageData,90).data.toString('base64');
-
-cachedThumbnails.set(frameForTimestamp,base64Data);
-thumbnails.push({
-timing:Math.round(targetTimestamp-speedline.beginning),
-timestamp:targetTimestamp*1000,
-data:base64Data});
-
-}
-
-return{
-score:100,
-rawValue:thumbnails.length>0,
-details:{
-type:'filmstrip',
-scale:timelineEnd,
-items:thumbnails}};
-
-
-});
-}}
-
-
-module.exports=ScreenshotThumbnails;
-
-},{"./audit":2,"./consistently-interactive":"../audits/consistently-interactive","./first-interactive":"../audits/first-interactive","jpeg-js":134}],"../audits/seo/canonical":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const LinkHeader=require('http-link-header');
-const URL=require('../../lib/url-shim');
-const LINK_HEADER='link';
-
-
-
-
-
-function getCanonicalLinksFromHeader(headerValue){
-const linkHeader=LinkHeader.parse(headerValue);
-
-return linkHeader.get('rel','canonical').map(c=>c.uri);
-}
-
-
-
-
-
-function getHreflangsFromHeader(headerValue){
-const linkHeader=LinkHeader.parse(headerValue);
-
-return linkHeader.get('rel','alternate').map(h=>h.uri);
-}
-
-
-
-
-
-
-function isValidRelativeOrAbsoluteURL(url){
-try{
-new URL(url,'https://example.com/');
-return true;
-}catch(e){
-return false;
-}
-}
-
-
-
-
-
-
-
-function getPrimaryDomain(url){
-return url.hostname.split('.').slice(-2).join('.');
-}
-
-class Canonical extends Audit{
-
-
-
-static get meta(){
-return{
-name:'canonical',
-description:'Document has a valid `rel=canonical`',
-failureDescription:'Document does not have a valid `rel=canonical`',
-helpText:'Canonical links suggest which URL to show in search results. '+
-'Read more in [Use canonical URLs]'+
-'(https://support.google.com/webmasters/answer/139066).',
-requiredArtifacts:['Canonical','Hreflang']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-
-return artifacts.requestMainResource(devtoolsLogs).
-then(mainResource=>{
-const baseURL=new URL(mainResource.url);
-let canonicals=[];
-let hreflangs=[];
-
-mainResource.responseHeaders.
-filter(h=>h.name.toLowerCase()===LINK_HEADER).
-forEach(h=>{
-canonicals=canonicals.concat(getCanonicalLinksFromHeader(h.value));
-hreflangs=hreflangs.concat(getHreflangsFromHeader(h.value));
-});
-
-canonicals=canonicals.concat(artifacts.Canonical);
-
-artifacts.Hreflang.forEach(({href})=>hreflangs.push(href));
-
-hreflangs=hreflangs.
-filter(href=>isValidRelativeOrAbsoluteURL(href)).
-map(href=>new URL(href,baseURL).href);
-
-if(canonicals.length===0){
-return{
-rawValue:true,
-notApplicable:true};
-
-}
-
-if(canonicals.length>1){
-return{
-rawValue:false,
-debugString:`Multiple URLs (${canonicals.join(', ')})`};
-
-}
-
-const canonical=canonicals[0];
-
-if(!isValidRelativeOrAbsoluteURL(canonical)){
-return{
-rawValue:false,
-debugString:`Invalid URL (${canonical})`};
-
-}
-
-if(!URL.isValid(canonical)){
-return{
-rawValue:false,
-debugString:`Relative URL (${canonical})`};
-
-}
-
-const canonicalURL=new URL(canonical);
-
-
-if(hreflangs.includes(baseURL.href)&&hreflangs.includes(canonicalURL.href)&&
-baseURL.href!==canonicalURL.href){
-return{
-rawValue:false,
-debugString:`Points to another hreflang location (${baseURL.href})`};
-
-}
-
-
-
-if(getPrimaryDomain(canonicalURL)!==getPrimaryDomain(baseURL)){
-return{
-rawValue:false,
-debugString:`Points to a different domain (${canonicalURL})`};
-
-}
-
-
-if(canonicalURL.origin===baseURL.origin&&
-canonicalURL.pathname==='/'&&baseURL.pathname!=='/'){
-return{
-rawValue:false,
-debugString:'Points to a root of the same origin'};
-
-}
-
-return{
-rawValue:true};
-
-});
-}}
-
-
-module.exports=Canonical;
-
-},{"../../lib/url-shim":41,"../audit":2,"http-link-header":131}],"../audits/seo/font-size":[function(require,module,exports){
-(function(global){
-
-
-
-
-
-'use strict';
-
-const URL=require('../../lib/url-shim');
-const Audit=require('../audit');
-const ViewportAudit=require('../viewport');
-const CSSStyleDeclaration=require('../../lib/web-inspector').CSSStyleDeclaration;
-const MINIMAL_PERCENTAGE_OF_LEGIBLE_TEXT=75;
-
-
-
-
-
-function getUniqueFailingRules(fontSizeArtifact){
-const failingRules=new Map();
-
-fontSizeArtifact.forEach(({cssRule,fontSize,textLength,node})=>{
-const artifactId=getFontArtifactId(cssRule,node);
-const failingRule=failingRules.get(artifactId);
-
-if(!failingRule){
-failingRules.set(artifactId,{
-node,
-cssRule,
-fontSize,
-textLength});
-
-}else{
-failingRule.textLength+=textLength;
-}
-});
-
-return failingRules.valuesArray();
-}
-
-
-
-
-
-function getAttributeMap(attributes){
-const map=new Map();
-
-for(let i=0;i<attributes.length;i+=2){
-const name=attributes[i].toLowerCase();
-const value=attributes[i+1].trim();
-
-if(value){
-map.set(name,value);
-}
-}
-
-return map;
-}
-
-
-
-
-
-
-function getSelector(node){
-const attributeMap=getAttributeMap(node.attributes);
-
-if(attributeMap.has('id')){
-return'#'+attributeMap.get('id');
-}else if(attributeMap.has('class')){
-return'.'+attributeMap.get('class').split(/\s+/).join('.');
-}
-
-return node.localName.toLowerCase();
-}
-
-
-
-
-
-function nodeToTableNode(node){
-const attributesString=node.attributes.map((value,idx)=>
-idx%2===0?` ${value}`:`="${value}"`).
-join('');
-
-return{
-type:'node',
-selector:node.parentNode?getSelector(node.parentNode):'',
-snippet:`<${node.localName}${attributesString}>`};
-
-}
-
-
-
-
-
-
-
-function findStyleRuleSource(baseURL,styleDeclaration,node){
-if(
-!styleDeclaration||
-styleDeclaration.type===CSSStyleDeclaration.Type.Attributes||
-styleDeclaration.type===CSSStyleDeclaration.Type.Inline)
-{
-return{
-source:baseURL,
-selector:nodeToTableNode(node)};
-
-}
-
-if(styleDeclaration.parentRule&&
-styleDeclaration.parentRule.origin===global.CSSAgent.StyleSheetOrigin.USER_AGENT){
-return{
-selector:styleDeclaration.parentRule.selectors.map(item=>item.text).join(', '),
-source:'User Agent Stylesheet'};
-
-}
-
-if(styleDeclaration.type===CSSStyleDeclaration.Type.Regular&&styleDeclaration.parentRule){
-const rule=styleDeclaration.parentRule;
-const stylesheet=styleDeclaration.stylesheet;
-
-if(stylesheet){
-let source;
-const selector=rule.selectors.map(item=>item.text).join(', ');
-
-if(stylesheet.sourceURL){
-const url=new URL(stylesheet.sourceURL,baseURL);
-const range=styleDeclaration.range;
-source=`${url.href}`;
-
-if(range){
-
-
-const absoluteStartLine=range.startLine+stylesheet.startLine+1;
-const absoluteStartColumn=range.startColumn+stylesheet.startColumn+1;
-
-source+=`:${absoluteStartLine}:${absoluteStartColumn}`;
-}
-}else{
-
-source='dynamic';
-}
-
-return{
-selector,
-source};
-
-}
-}
-
-return{
-source:'Unknown'};
-
-}
-
-
-
-
-
-
-function getFontArtifactId(styleDeclaration,node){
-if(styleDeclaration&&styleDeclaration.type===CSSStyleDeclaration.Type.Regular){
-const startLine=styleDeclaration.range?styleDeclaration.range.startLine:0;
-const startColumn=styleDeclaration.range?styleDeclaration.range.startColumn:0;
-return`${styleDeclaration.styleSheetId}@${startLine}:${startColumn}`;
-}else{
-return`node_${node.nodeId}`;
-}
-}
-
-class FontSize extends Audit{
-
-
-
-static get meta(){
-return{
-name:'font-size',
-description:'Document uses legible font sizes',
-failureDescription:'Document doesn\'t use legible font sizes',
-helpText:'Font sizes less than 16px are too small to be legible and require mobile '+
-'visitors to “pinch to zoom” in order to read. Strive to have >75% of page text ≥16px. '+
-'[Learn more](https://developers.google.com/speed/docs/insights/UseLegibleFontSizes).',
-requiredArtifacts:['FontSize','URL','Viewport']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const hasViewportSet=ViewportAudit.audit(artifacts).rawValue;
-if(!hasViewportSet){
-return{
-rawValue:false,
-debugString:'Text is illegible because of a missing viewport config'};
-
-}
-
-const{
-analyzedFailingNodesData,
-analyzedFailingTextLength,
-failingTextLength,
-visitedTextLength,
-totalTextLength}=
-artifacts.FontSize;
-
-if(totalTextLength===0){
-return{
-rawValue:true};
-
-}
-
-const failingRules=getUniqueFailingRules(analyzedFailingNodesData);
-const percentageOfPassingText=
-(visitedTextLength-failingTextLength)/visitedTextLength*100;
-const pageUrl=artifacts.URL.finalUrl;
-
-const headings=[
-{key:'source',itemType:'url',text:'Source'},
-{key:'selector',itemType:'code',text:'Selector'},
-{key:'coverage',itemType:'text',text:'% of Page Text'},
-{key:'fontSize',itemType:'text',text:'Font Size'}];
-
-
-const tableData=failingRules.sort((a,b)=>b.textLength-a.textLength).
-map(({cssRule,textLength,fontSize,node})=>{
-const percentageOfAffectedText=textLength/visitedTextLength*100;
-const origin=findStyleRuleSource(pageUrl,cssRule,node);
-
-return{
-source:origin.source,
-selector:origin.selector,
-coverage:`${percentageOfAffectedText.toFixed(2)}%`,
-fontSize:`${fontSize}px`};
-
-});
-
-
-if(analyzedFailingTextLength<failingTextLength){
-const percentageOfUnanalyzedFailingText=
-(failingTextLength-analyzedFailingTextLength)/visitedTextLength*100;
-
-tableData.push({
-source:'Add\'l illegible text',
-selector:null,
-coverage:`${percentageOfUnanalyzedFailingText.toFixed(2)}%`,
-fontSize:'< 16px'});
-
-}
-
-if(percentageOfPassingText>0){
-tableData.push({
-source:'Legible text',
-selector:null,
-coverage:`${percentageOfPassingText.toFixed(2)}%`,
-fontSize:'≥ 16px'});
-
-}
-
-const details=Audit.makeTableDetails(headings,tableData);
-const passed=percentageOfPassingText>=MINIMAL_PERCENTAGE_OF_LEGIBLE_TEXT;
-let debugString=null;
-
-if(!passed){
-const percentageOfFailingText=parseFloat((100-percentageOfPassingText).toFixed(2));
-let disclaimer='';
-
-
-if(visitedTextLength<totalTextLength){
-const percentageOfVisitedText=visitedTextLength/totalTextLength*100;
-disclaimer=` (based on ${percentageOfVisitedText.toFixed()}% sample)`;
-}
-
-debugString=`${percentageOfFailingText}% of text is too small${disclaimer}.`;
-}
-
-return{
-rawValue:passed,
-details,
-debugString};
-
-}}
-
-
-module.exports=FontSize;
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"../../lib/url-shim":41,"../../lib/web-inspector":42,"../audit":2,"../viewport":"../audits/viewport"}],"../audits/seo/hreflang":[function(require,module,exports){
-(function(global){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const LinkHeader=require('http-link-header');
-const VALID_LANGS=importValidLangs();
-const LINK_HEADER='link';
-const NO_LANGUAGE='x-default';
-
-
-
-
-
-
-function importValidLangs(){
-const axeCache=global.axe;
-global.axe={utils:{}};
-require('axe-core/lib/commons/utils/valid-langs.js');
-const validLangs=global.axe.utils.validLangs();
-global.axe=axeCache;
-
-return validLangs;
-}
-
-
-
-
-
-function isValidHreflang(hreflang){
-if(hreflang.toLowerCase()===NO_LANGUAGE){
-return true;
-}
-
-
-const[lang]=hreflang.split('-');
-return VALID_LANGS.includes(lang.toLowerCase());
-}
-
-
-
-
-
-function headerHasValidHreflangs(headerValue){
-const linkHeader=LinkHeader.parse(headerValue);
-
-return linkHeader.get('rel','alternate').
-every(link=>link.hreflang&&isValidHreflang(link.hreflang));
-}
-
-class Hreflang extends Audit{
-
-
-
-static get meta(){
-return{
-name:'hreflang',
-description:'Document has a valid `hreflang`',
-failureDescription:'Document doesn\'t have a valid `hreflang`',
-helpText:'hreflang allows crawlers to discover alternate translations of the '+
-'page content. [Learn more]'+
-'(https://support.google.com/webmasters/answer/189077).',
-requiredArtifacts:['Hreflang']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-
-return artifacts.requestMainResource(devtoolsLogs).
-then(mainResource=>{
-
-const invalidHreflangs=[];
-
-if(artifacts.Hreflang){
-artifacts.Hreflang.forEach(({href,hreflang})=>{
-if(!isValidHreflang(hreflang)){
-invalidHreflangs.push({
-source:{
-type:'node',
-snippet:`<link name="alternate" hreflang="${hreflang}" href="${href}" />`}});
-
-
-}
-});
-}
-
-mainResource.responseHeaders.
-filter(h=>h.name.toLowerCase()===LINK_HEADER&&!headerHasValidHreflangs(h.value)).
-forEach(h=>invalidHreflangs.push({source:`${h.name}: ${h.value}`}));
-
-const headings=[
-{key:'source',itemType:'code',text:'Source'}];
-
-const details=Audit.makeTableDetails(headings,invalidHreflangs);
-
-return{
-rawValue:invalidHreflangs.length===0,
-details};
-
-});
-}}
-
-
-module.exports=Hreflang;
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"../audit":2,"axe-core/lib/commons/utils/valid-langs.js":92,"http-link-header":131}],"../audits/seo/http-status-code":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const HTTP_UNSUCCESSFUL_CODE_LOW=400;
-const HTTP_UNSUCCESSFUL_CODE_HIGH=599;
-
-class HTTPStatusCode extends Audit{
-
-
-
-static get meta(){
-return{
-name:'http-status-code',
-description:'Page has successful HTTP status code',
-failureDescription:'Page has unsuccessful HTTP status code',
-helpText:'Pages with unsuccessful HTTP status codes may not be indexed properly. '+
-'[Learn more]'+
-'(https://developers.google.com/web/tools/lighthouse/audits/successful-http-code).',
-requiredArtifacts:['devtoolsLogs']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-
-return artifacts.requestMainResource(devtoolsLogs).
-then(mainResource=>{
-const statusCode=mainResource.statusCode;
-
-if(statusCode>=HTTP_UNSUCCESSFUL_CODE_LOW&&
-statusCode<=HTTP_UNSUCCESSFUL_CODE_HIGH){
-return{
-rawValue:false,
-displayValue:`${statusCode}`};
-
-}
-
-return{
-rawValue:true};
-
-});
-}}
-
-
-module.exports=HTTPStatusCode;
-
-},{"../audit":2}],"../audits/seo/is-crawlable":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const BLOCKLIST=new Set([
-'noindex',
-'none']);
-
-const ROBOTS_HEADER='x-robots-tag';
-const UNAVAILABLE_AFTER='unavailable_after';
-
-
-
-
-
-
-function isUnavailable(directive){
-const parts=directive.split(':');
-
-if(parts.length<=1||parts[0]!==UNAVAILABLE_AFTER){
-return false;
-}
-
-const date=Date.parse(parts.slice(1).join(':'));
-
-return!isNaN(date)&&date<Date.now();
-}
-
-
-
-
-
-
-function hasBlockingDirective(directives){
-return directives.split(',').
-map(d=>d.toLowerCase().trim()).
-some(d=>BLOCKLIST.has(d)||isUnavailable(d));
-}
-
-
-
-
-
-
-function hasUserAgent(directives){
-const parts=directives.match(/^([^,:]+):/);
-
-
-
-return!!parts&&parts[1].toLowerCase()!==UNAVAILABLE_AFTER;
-}
-
-class IsCrawlable extends Audit{
-
-
-
-static get meta(){
-return{
-name:'is-crawlable',
-description:'Page isn’t blocked from indexing',
-failureDescription:'Page is blocked from indexing',
-helpText:'The "Robots" directives tell crawlers how your content should be indexed. '+
-'[Learn more](https://developers.google.com/search/reference/robots_meta_tag).',
-requiredArtifacts:['MetaRobots']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-return artifacts.requestMainResource(artifacts.devtoolsLogs[Audit.DEFAULT_PASS]).
-then(mainResource=>{
-const blockingDirectives=[];
-
-if(artifacts.MetaRobots){
-const isBlocking=hasBlockingDirective(artifacts.MetaRobots);
-
-if(isBlocking){
-blockingDirectives.push({
-source:{
-type:'node',
-snippet:`<meta name="robots" content="${artifacts.MetaRobots}" />`}});
-
-
-}
-}
-
-mainResource.responseHeaders.
-filter(h=>h.name.toLowerCase()===ROBOTS_HEADER&&!hasUserAgent(h.value)&&
-hasBlockingDirective(h.value)).
-forEach(h=>blockingDirectives.push({source:`${h.name}: ${h.value}`}));
-
-const headings=[
-{key:'source',itemType:'code',text:'Source'}];
-
-const details=Audit.makeTableDetails(headings,blockingDirectives);
-
-return{
-rawValue:blockingDirectives.length===0,
-details};
-
-});
-}}
-
-
-module.exports=IsCrawlable;
-
-},{"../audit":2}],"../audits/seo/link-text":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const URL=require('../../lib/url-shim');
-const BLOCKLIST=new Set([
-'click here',
-'click this',
-'go',
-'here',
-'this',
-'start',
-'right here',
-'more',
-'learn more']);
-
-
-class LinkText extends Audit{
-
-
-
-static get meta(){
-return{
-category:'Content Best Practices',
-name:'link-text',
-description:'Links have descriptive text',
-failureDescription:'Links do not have descriptive text',
-helpText:'Descriptive link text helps search engines understand your content. '+
-'[Learn more](https://webmasters.googleblog.com/2008/10/importance-of-link-architecture.html).',
-requiredArtifacts:['URL','CrawlableLinks']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const failingLinks=artifacts.CrawlableLinks.
-filter(link=>{
-if(
-link.href.toLowerCase().startsWith('javascript:')||
-URL.equalWithExcludedFragments(link.href,artifacts.URL.finalUrl))
-{
-return false;
-}
-
-return BLOCKLIST.has(link.text.trim().toLowerCase());
-});
-
-const headings=[
-{key:'href',itemType:'url',text:'Link destination'},
-{key:'text',itemType:'text',text:'Link Text'}];
-
-
-const details=Audit.makeTableDetails(headings,failingLinks);
-let displayValue;
-
-if(failingLinks.length){
-displayValue=failingLinks.length>1?
-`${failingLinks.length} links found`:'1 link found';
-}
-
-return{
-rawValue:failingLinks.length===0,
-details,
-displayValue};
-
-}}
-
-
-module.exports=LinkText;
-
-},{"../../lib/url-shim":41,"../audit":2}],"../audits/seo/manual/mobile-friendly":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class MobileFriendly extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'mobile-friendly',
-helpText:'Take the [Mobile-Friendly Test](https://search.google.com/test/mobile-friendly) to check for audits not covered by Lighthouse, like sizing tap targets appropriately. [Learn more](https://developers.google.com/search/mobile-sites/).',
-description:'Page is mobile friendly'},
-super.meta);
-}}
-
-
-module.exports=MobileFriendly;
-
-},{"../../manual/manual-audit":4}],"../audits/seo/manual/structured-data":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ManualAudit=require('../../manual/manual-audit');
-
-
-
-
-
-class StructuredData extends ManualAudit{
-
-
-
-static get meta(){
-return Object.assign({
-name:'structured-data',
-helpText:'Run the [Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool/) and the [Structured Data Linter](http://linter.structured-data.org/) to validate structured data. [Learn more](https://developers.google.com/search/docs/guides/mark-up-content).',
-description:'Structured data is valid'},
-super.meta);
-}}
-
-
-module.exports=StructuredData;
-
-},{"../../manual/manual-audit":4}],"../audits/seo/meta-description":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-
-class Description extends Audit{
-
-
-
-static get meta(){
-return{
-name:'meta-description',
-description:'Document has a meta description',
-failureDescription:'Document does not have a meta description',
-helpText:'Meta descriptions may be included in search results to concisely summarize '+
-'page content. '+
-'[Learn more](https://support.google.com/webmasters/answer/35624?hl=en#1).',
-requiredArtifacts:['MetaDescription']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-if(artifacts.MetaDescription===null){
-return{
-rawValue:false};
-
-}
-
-if(artifacts.MetaDescription.trim().length===0){
-return{
-rawValue:false,
-debugString:'Description text is empty.'};
-
-}
-
-return{
-rawValue:true};
-
-}}
-
-
-module.exports=Description;
-
-},{"../audit":2}],"../audits/seo/plugins":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const URL=require('../../lib/url-shim');
-
-const JAVA_APPLET_TYPE='application/x-java-applet';
-const JAVA_BEAN_TYPE='application/x-java-bean';
-const TYPE_BLOCKLIST=new Set([
-'application/x-shockwave-flash',
-
-JAVA_APPLET_TYPE,
-JAVA_BEAN_TYPE,
-
-'application/x-silverlight',
-'application/x-silverlight-2']);
-
-const FILE_EXTENSION_BLOCKLIST=new Set([
-'swf',
-'flv',
-'class',
-'xap']);
-
-const SOURCE_PARAMS=new Set([
-'code',
-'movie',
-'source',
-'src']);
-
-
-
-
-
-
-function isPluginType(type){
-type=type.trim().toLowerCase();
-
-return TYPE_BLOCKLIST.has(type)||
-type.startsWith(JAVA_APPLET_TYPE)||
-type.startsWith(JAVA_BEAN_TYPE);
-}
-
-
-
-
-
-function isPluginURL(url){
-try{
-
-const filePath=new URL(url,'http://example.com').pathname;
-const parts=filePath.split('.');
-
-return parts.length>1&&FILE_EXTENSION_BLOCKLIST.has(parts.pop().trim().toLowerCase());
-}catch(e){
-return false;
-}
-}
-
-class Plugins extends Audit{
-
-
-
-static get meta(){
-return{
-name:'plugins',
-description:'Document avoids plugins',
-failureDescription:'Document uses plugins',
-helpText:'Most mobile devices do not support plugins, and many desktop browsers restrict '+
-'them.',
-requiredArtifacts:['EmbeddedContent']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const plugins=artifacts.EmbeddedContent.
-filter(item=>{
-if(item.tagName==='APPLET'){
-return true;
-}
-
-if(
-(item.tagName==='EMBED'||item.tagName==='OBJECT')&&
-item.type&&
-isPluginType(item.type))
-{
-return true;
-}
-
-const embedSrc=item.src||item.code;
-if(item.tagName==='EMBED'&&embedSrc&&isPluginURL(embedSrc)){
-return true;
-}
-
-if(item.tagName==='OBJECT'&&item.data&&isPluginURL(item.data)){
-return true;
-}
-
-const failingParams=item.params.filter(param=>
-SOURCE_PARAMS.has(param.name.trim().toLowerCase())&&isPluginURL(param.value));
-
-
-return failingParams.length>0;
-}).
-map(plugin=>{
-const tagName=plugin.tagName.toLowerCase();
-const attributes=['src','data','code','type'].
-reduce((result,attr)=>{
-if(plugin[attr]!==null){
-result+=` ${attr}="${plugin[attr]}"`;
-}
-return result;
-},'');
-const params=plugin.params.
-filter(param=>SOURCE_PARAMS.has(param.name.trim().toLowerCase())).
-map(param=>`<param ${param.name}="${param.value}" />`).
-join('');
-
-return{
-source:{
-type:'node',
-snippet:`<${tagName}${attributes}>${params}</${tagName}>`}};
-
-
-});
-
-const headings=[
-{key:'source',itemType:'code',text:'Element source'}];
-
-
-const details=Audit.makeTableDetails(headings,plugins);
-
-return{
-rawValue:plugins.length===0,
-details};
-
-}}
-
-
-module.exports=Plugins;
-
-},{"../../lib/url-shim":41,"../audit":2}],"../audits/service-worker":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const URL=require('../lib/url-shim');
-const Audit=require('./audit');
-
-class ServiceWorker extends Audit{
-
-
-
-static get meta(){
-return{
-name:'service-worker',
-description:'Registers a service worker',
-failureDescription:'Does not register a service worker',
-helpText:'The service worker is the technology that enables your app to use many '+
-'Progressive Web App features, such as offline, add to homescreen, and push '+
-'notifications. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker).',
-requiredArtifacts:['URL','ServiceWorker']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-
-
-const versions=artifacts.ServiceWorker.versions;
-const url=artifacts.URL.finalUrl;
-
-const origin=new URL(url).origin;
-const matchingSW=versions.filter(v=>v.status==='activated').
-find(v=>new URL(v.scriptURL).origin===origin);
-
-return{
-rawValue:!!matchingSW};
-
-}}
-
-
-module.exports=ServiceWorker;
-
-},{"../lib/url-shim":41,"./audit":2}],"../audits/speed-index-metric":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const LHError=require('../lib/errors');
-
-
-
-const SCORING_POINT_OF_DIMINISHING_RETURNS=1250;
-const SCORING_MEDIAN=5500;
-
-class SpeedIndexMetric extends Audit{
-
-
-
-static get meta(){
-return{
-name:'speed-index-metric',
-description:'Perceptual Speed Index',
-helpText:'Speed Index shows how quickly the contents of a page are visibly populated. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/speed-index).',
-scoringMode:Audit.SCORING_MODES.NUMERIC,
-requiredArtifacts:['traces']};
-
-}
-
-
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[this.DEFAULT_PASS];
-
-
-return artifacts.requestSpeedline(trace).then(speedline=>{
-if(speedline.frames.length===0){
-throw new LHError(LHError.errors.NO_SPEEDLINE_FRAMES);
-}
-
-if(speedline.perceptualSpeedIndex===0){
-throw new LHError(LHError.errors.SPEEDINDEX_OF_ZERO);
-}
-
-let visuallyReadyInMs=undefined;
-speedline.frames.forEach(frame=>{
-if(frame.getPerceptualProgress()>=85&&typeof visuallyReadyInMs==='undefined'){
-visuallyReadyInMs=frame.getTimeStamp()-speedline.beginning;
-}
-});
-
-
-
-
-
-
-
-const score=Audit.computeLogNormalScore(
-speedline.perceptualSpeedIndex,
-SCORING_POINT_OF_DIMINISHING_RETURNS,
-SCORING_MEDIAN);
-
-
-const extendedInfo={
-timings:{
-firstVisualChange:speedline.first,
-visuallyReady:visuallyReadyInMs,
-visuallyComplete:speedline.complete,
-perceptualSpeedIndex:speedline.perceptualSpeedIndex},
-
-timestamps:{
-firstVisualChange:(speedline.first+speedline.beginning)*1000,
-visuallyReady:(visuallyReadyInMs+speedline.beginning)*1000,
-visuallyComplete:(speedline.complete+speedline.beginning)*1000,
-perceptualSpeedIndex:(speedline.perceptualSpeedIndex+speedline.beginning)*1000},
-
-frames:speedline.frames.map(frame=>{
-return{
-timestamp:frame.getTimeStamp(),
-progress:frame.getPerceptualProgress()};
-
-})};
-
-
-const rawValue=Math.round(speedline.perceptualSpeedIndex);
-
-return{
-score,
-rawValue,
-displayValue:Util.formatNumber(rawValue),
-extendedInfo:{
-value:extendedInfo}};
-
-
-});
-}}
-
-
-module.exports=SpeedIndexMetric;
-
-},{"../lib/errors":28,"../report/v2/renderer/util":43,"./audit":2}],"../audits/splash-screen":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const MultiCheckAudit=require('./multi-check-audit');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class SplashScreen extends MultiCheckAudit{
-
-
-
-static get meta(){
-return{
-name:'splash-screen',
-description:'Configured for a custom splash screen',
-failureDescription:'Is not configured for a custom splash screen',
-helpText:'A themed splash screen ensures a high-quality experience when '+
-'users launch your app from their homescreens. [Learn '+
-'more](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen).',
-requiredArtifacts:['Manifest']};
-
-}
-
-static assessManifest(manifestValues,failures){
-if(manifestValues.isParseFailure){
-failures.push(manifestValues.parseFailureReason);
-return;
-}
-
-const splashScreenCheckIds=[
-'hasName',
-'hasBackgroundColor',
-'hasThemeColor',
-'hasIconsAtLeast512px'];
-
-
-manifestValues.allChecks.
-filter(item=>splashScreenCheckIds.includes(item.id)).
-forEach(item=>{
-if(!item.passing){
-failures.push(item.failureText);
-}
-});
-}
-
-
-static audit_(artifacts){
-const failures=[];
-
-return artifacts.requestManifestValues(artifacts.Manifest).then(manifestValues=>{
-SplashScreen.assessManifest(manifestValues,failures);
-
-return{
-failures,
-manifestValues};
-
-});
-}}
-
-
-module.exports=SplashScreen;
-
-},{"./multi-check-audit":5}],"../audits/themed-omnibox":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const MultiCheckAudit=require('./multi-check-audit');
-const validColor=require('../lib/web-inspector').Color.parse;
-
-
-
-
-
-
-
-
-
-
-
-class ThemedOmnibox extends MultiCheckAudit{
-
-
-
-static get meta(){
-return{
-name:'themed-omnibox',
-description:'Address bar matches brand colors',
-failureDescription:'Address bar does not match brand colors',
-helpText:'The browser address bar can be themed to match your site. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/address-bar).',
-requiredArtifacts:['Manifest','ThemeColor']};
-
-}
-
-static assessMetaThemecolor(themeColorMeta,failures){
-if(themeColorMeta===null){
-failures.push('No `<meta name="theme-color">` tag found');
-}else if(!validColor(themeColorMeta)){
-failures.push('The theme-color meta tag did not contain a valid CSS color');
-}
-}
-
-static assessManifest(manifestValues,failures){
-if(manifestValues.isParseFailure){
-failures.push(manifestValues.parseFailureReason);
-return;
-}
-
-const themeColorCheck=manifestValues.allChecks.find(i=>i.id==='hasThemeColor');
-if(!themeColorCheck.passing){
-failures.push(themeColorCheck.failureText);
-}
-}
-
-static audit_(artifacts){
-const failures=[];
-
-return artifacts.requestManifestValues(artifacts.Manifest).then(manifestValues=>{
-ThemedOmnibox.assessManifest(manifestValues,failures);
-ThemedOmnibox.assessMetaThemecolor(artifacts.ThemeColor,failures);
-
-return{
-failures,
-manifestValues,
-themeColor:artifacts.ThemeColor};
-
-});
-}}
-
-
-module.exports=ThemedOmnibox;
-
-},{"../lib/web-inspector":42,"./multi-check-audit":5}],"../audits/time-to-first-byte":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-
-const TTFB_THRESHOLD=600;
-
-class TTFBMetric extends Audit{
-
-
-
-static get meta(){
-return{
-name:'time-to-first-byte',
-description:'Keep server response times low (TTFB)',
-informative:true,
-helpText:'Time To First Byte identifies the time at which your server sends a response.'+
-' [Learn more](https://developers.google.com/web/tools/chrome-devtools/network-performance/issues).',
-requiredArtifacts:['devtoolsLogs','URL']};
-
-}
-
-static caclulateTTFB(record){
-const timing=record._timing;
-
-return timing.receiveHeadersEnd-timing.sendEnd;
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-
-return artifacts.requestNetworkRecords(devtoolsLogs).
-then(networkRecords=>{
-let debugString='';
-
-const finalUrl=artifacts.URL.finalUrl;
-const finalUrlRequest=networkRecords.find(record=>record._url===finalUrl);
-const ttfb=TTFBMetric.caclulateTTFB(finalUrlRequest);
-const passed=ttfb<TTFB_THRESHOLD;
-
-if(!passed){
-debugString=`Root document took ${Util.formatMilliseconds(ttfb,1)} `+
-'to get the first byte.';
-}
-
-return{
-rawValue:ttfb,
-score:passed,
-displayValue:Util.formatMilliseconds(ttfb),
-extendedInfo:{
-value:{
-wastedMs:ttfb-TTFB_THRESHOLD}},
-
-
-debugString};
-
-});
-}}
-
-
-module.exports=TTFBMetric;
-
-},{"../report/v2/renderer/util":43,"./audit":2}],"../audits/user-timings":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-
-class UserTimings extends Audit{
-
-
-
-static get meta(){
-return{
-name:'user-timings',
-description:'User Timing marks and measures',
-helpText:'Consider instrumenting your app with the User Timing API to create custom, '+
-'real-world measurements of key user experiences. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing).',
-requiredArtifacts:['traces'],
-informative:true};
-
-}
-
-
-
-
-
-static filterTrace(tabTrace){
-const userTimings=[];
-const measuresStartTimes={};
-
-
-
-
-
-tabTrace.processEvents.filter(evt=>{
-if(!evt.cat.includes('blink.user_timing')){
-return false;
-}
-
-
-
-return evt.name!=='requestStart'&&
-evt.name!=='navigationStart'&&
-evt.name!=='paintNonDefaultBackgroundColor'&&
-evt.args.frame===undefined;
-}).
-forEach(ut=>{
-
-if(ut.ph==='R'||ut.ph.toUpperCase()==='I'){
-userTimings.push({
-name:ut.name,
-isMark:true,
-args:ut.args,
-startTime:ut.ts});
-
-
-
-}else if(ut.ph.toLowerCase()==='b'){
-measuresStartTimes[ut.name]=ut.ts;
-
-
-}else if(ut.ph.toLowerCase()==='e'){
-userTimings.push({
-name:ut.name,
-isMark:false,
-args:ut.args,
-startTime:measuresStartTimes[ut.name],
-endTime:ut.ts});
-
-}
-});
-
-
-userTimings.forEach(ut=>{
-ut.startTime=(ut.startTime-tabTrace.navigationStartEvt.ts)/1000;
-if(!ut.isMark){
-ut.endTime=(ut.endTime-tabTrace.navigationStartEvt.ts)/1000;
-ut.duration=ut.endTime-ut.startTime;
-}
-});
-
-return userTimings;
-}
-
-
-
-
-static get blacklistedPrefixes(){
-return['goog_'];
-}
-
-
-
-
-
-
-static excludeBlacklisted(timing){
-return UserTimings.blacklistedPrefixes.every(prefix=>!timing.name.startsWith(prefix));
-}
-
-
-
-
-
-static audit(artifacts){
-const trace=artifacts.traces[Audit.DEFAULT_PASS];
-return artifacts.requestTraceOfTab(trace).then(tabTrace=>{
-const userTimings=this.filterTrace(tabTrace).filter(UserTimings.excludeBlacklisted);
-const tableRows=userTimings.map(item=>{
-const time=item.isMark?item.startTime:item.duration;
-return{
-name:item.name,
-timingType:item.isMark?'Mark':'Measure',
-time:Util.formatMilliseconds(time,0.001),
-timeAsNumber:time};
-
-}).sort((itemA,itemB)=>{
-if(itemA.timingType===itemB.timingType){
-
-return itemA.timeAsNumber-itemB.timeAsNumber;
-}else if(itemA.timingType==='Measure'){
-
-return-1;
-}else{
-return 1;
-}
-});
-
-const headings=[
-{key:'name',itemType:'text',text:'Name'},
-{key:'timingType',itemType:'text',text:'Type'},
-{key:'time',itemType:'text',text:'Time'}];
-
-
-const details=Audit.makeTableDetails(headings,tableRows);
-
-return{
-
-rawValue:userTimings.length===0,
-displayValue:userTimings.length,
-extendedInfo:{
-value:userTimings},
-
-details};
-
-});
-}}
-
-
-module.exports=UserTimings;
-
-},{"../report/v2/renderer/util":43,"./audit":2}],"../audits/uses-rel-preload":[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Util=require('../report/v2/renderer/util');
-const UnusedBytes=require('./byte-efficiency/byte-efficiency-audit');
-const THRESHOLD_IN_MS=100;
-
-class UsesRelPreloadAudit extends Audit{
-
-
-
-static get meta(){
-return{
-category:'Performance',
-name:'uses-rel-preload',
-description:'Preload key requests',
-informative:true,
-helpText:'Consider using <link rel=preload> to prioritize fetching late-discovered '+
-'resources sooner [Learn more](https://developers.google.com/web/updates/2016/03/link-rel-preload).',
-requiredArtifacts:['devtoolsLogs','traces'],
-scoringMode:Audit.SCORING_MODES.NUMERIC};
-
-}
-
-static _flattenRequests(chains,maxLevel,minLevel=0){
-const requests=[];
-const flatten=(chains,level)=>{
-Object.keys(chains).forEach(chain=>{
-if(chains[chain]){
-const currentChain=chains[chain];
-if(level>=minLevel){
-requests.push(currentChain.request);
-}
-
-if(level<maxLevel){
-flatten(currentChain.children,level+1);
-}
-}
-});
-};
-
-flatten(chains,0);
-
-return requests;
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLogs=artifacts.devtoolsLogs[UsesRelPreloadAudit.DEFAULT_PASS];
-
-return Promise.all([
-artifacts.requestCriticalRequestChains(devtoolsLogs),
-artifacts.requestMainResource(devtoolsLogs)]).
-then(([critChains,mainResource])=>{
-const results=[];
-let maxWasted=0;
-
-const mainResourceIndex=mainResource.redirects?mainResource.redirects.length:0;
-
-const criticalRequests=UsesRelPreloadAudit._flattenRequests(critChains,
-3+mainResourceIndex,2+mainResourceIndex);
-criticalRequests.forEach(request=>{
-const networkRecord=request;
-if(!networkRecord._isLinkPreload&&networkRecord.protocol!=='data'){
-
-const wastedMs=Math.min(request._startTime-mainResource._endTime,
-request._endTime-request._startTime)*1000;
-
-if(wastedMs>=THRESHOLD_IN_MS){
-maxWasted=Math.max(wastedMs,maxWasted);
-results.push({
-url:request.url,
-wastedMs:Util.formatMilliseconds(wastedMs)});
-
-}
-}
-});
-
-
-results.sort((a,b)=>b.wastedMs-a.wastedMs);
-
-const headings=[
-{key:'url',itemType:'url',text:'URL'},
-{key:'wastedMs',itemType:'text',text:'Potential Savings'}];
-
-const details=Audit.makeTableDetails(headings,results);
-
-return{
-score:UnusedBytes.scoreForWastedMs(maxWasted),
-rawValue:maxWasted,
-displayValue:Util.formatMilliseconds(maxWasted),
-extendedInfo:{
-value:results},
-
-details};
-
-});
-}}
-
-
-module.exports=UsesRelPreloadAudit;
-
-},{"../report/v2/renderer/util":43,"./audit":2,"./byte-efficiency/byte-efficiency-audit":3}],"../audits/viewport":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-const Parser=require('metaviewport-parser');
-
-class Viewport extends Audit{
-
-
-
-static get meta(){
-return{
-name:'viewport',
-description:'Has a `<meta name="viewport">` tag with `width` or `initial-scale`',
-failureDescription:'Does not have a `<meta name="viewport">` tag with `width` '+
-'or `initial-scale`',
-helpText:'Add a viewport meta tag to optimize your app for mobile screens. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/has-viewport-meta-tag).',
-requiredArtifacts:['Viewport']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-if(artifacts.Viewport===null){
-return{
-debugString:'No viewport meta tag found',
-rawValue:false};
-
-}
-
-let debugString='';
-const parsedProps=Parser.parseMetaViewPortContent(artifacts.Viewport);
-
-if(Object.keys(parsedProps.unknownProperties).length){
-debugString+=`Invalid properties found: ${JSON.stringify(parsedProps.unknownProperties)}. `;
-}
-if(Object.keys(parsedProps.invalidValues).length){
-debugString+=`Invalid values found: ${JSON.stringify(parsedProps.invalidValues)}. `;
-}
-debugString=debugString.trim();
-
-const viewportProps=parsedProps.validProperties;
-const hasMobileViewport=viewportProps.width||viewportProps['initial-scale'];
-
-return{
-rawValue:!!hasMobileViewport,
-debugString};
-
-}}
-
-
-module.exports=Viewport;
-
-},{"./audit":2,"metaviewport-parser":139}],"../audits/webapp-install-banner":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const MultiCheckAudit=require('./multi-check-audit');
-const SWAudit=require('./service-worker');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class WebappInstallBanner extends MultiCheckAudit{
-
-
-
-static get meta(){
-return{
-name:'webapp-install-banner',
-description:'User can be prompted to Install the Web App',
-failureDescription:'User will not be prompted to Install the Web App',
-helpText:'Browsers can proactively prompt users to add your app to their homescreen, '+
-'which can lead to higher engagement. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/install-prompt).',
-requiredArtifacts:['URL','ServiceWorker','Manifest','StartUrl']};
-
-}
-
-static assessManifest(artifacts,result){
-const{manifestValues,failures}=result;
-if(manifestValues.isParseFailure){
-failures.push(manifestValues.parseFailureReason);
-return;
-}
-
-const bannerCheckIds=[
-'hasName',
-'hasShortName',
-'hasStartUrl',
-'hasPWADisplayValue',
-'hasIconsAtLeast192px'];
-
-manifestValues.allChecks.
-filter(item=>bannerCheckIds.includes(item.id)).
-forEach(item=>{
-if(!item.passing){
-failures.push(item.failureText);
-}
-});
-}
-
-
-static assessServiceWorker(artifacts,result){
-const hasServiceWorker=SWAudit.audit(artifacts).rawValue;
-if(!hasServiceWorker){
-result.failures.push('Site does not register a service worker');
-}
-}
-
-static assessOfflineStartUrl(artifacts,result){
-const hasOfflineStartUrl=artifacts.StartUrl.statusCode===200;
-
-if(!hasOfflineStartUrl){
-result.failures.push('Service worker does not successfully serve the manifest\'s start_url');
-if(artifacts.StartUrl.debugString)result.failures.push(artifacts.StartUrl.debugString);
-}
-
-if(artifacts.StartUrl.debugString){
-result.warnings.push(artifacts.StartUrl.debugString);
-}
-}
-
-static audit_(artifacts){
-const failures=[];
-const warnings=[];
-
-return artifacts.requestManifestValues(artifacts.Manifest).then(manifestValues=>{
-const result={warnings,failures,manifestValues};
-WebappInstallBanner.assessManifest(artifacts,result);
-WebappInstallBanner.assessServiceWorker(artifacts,result);
-WebappInstallBanner.assessOfflineStartUrl(artifacts,result);
-
-return result;
-});
-}}
-
-
-module.exports=WebappInstallBanner;
-
-},{"./multi-check-audit":5,"./service-worker":"../audits/service-worker"}],"../audits/without-javascript":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-class WithoutJavaScript extends Audit{
-
-
-
-static get meta(){
-return{
-name:'without-javascript',
-description:'Contains some content when JavaScript is not available',
-failureDescription:'Does not provide fallback content when JavaScript is not available',
-helpText:'Your app should display some content when JavaScript is disabled, even if it\'s '+
-'just a warning to the user that JavaScript is required to use the app. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/no-js).',
-requiredArtifacts:['HTMLWithoutJavaScript']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-const artifact=artifacts.HTMLWithoutJavaScript;
-
-if(artifact.value.trim()===''){
-return{
-rawValue:false,
-debugString:'The page body should render some content if its scripts are not available.'};
-
-}
-
-return{
-rawValue:true};
-
-}}
-
-
-module.exports=WithoutJavaScript;
-
-},{"./audit":2}],"../audits/works-offline":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const URL=require('../lib/url-shim');
-const Audit=require('./audit');
-
-class WorksOffline extends Audit{
-
-
-
-static get meta(){
-return{
-name:'works-offline',
-description:'Responds with a 200 when offline',
-failureDescription:'Does not respond with a 200 when offline',
-helpText:'If you\'re building a Progressive Web App, consider using a service worker so '+
-'that your app can work offline. '+
-'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline).',
-requiredArtifacts:['Offline','URL']};
-
-}
-
-
-
-
-
-static audit(artifacts){
-let debugString;
-const passed=artifacts.Offline===200;
-if(!passed&&
-!URL.equalWithExcludedFragments(artifacts.URL.initialUrl,artifacts.URL.finalUrl)){
-debugString='WARNING: You may be failing this check because your test URL '+
-`(${artifacts.URL.initialUrl}) was redirected to "${artifacts.URL.finalUrl}". `+
-'Try testing the second URL directly.';
-}
-
-return{
-rawValue:passed,
-debugString};
-
-}}
-
-
-module.exports=WorksOffline;
-
-},{"../lib/url-shim":41,"./audit":2}],"./gather/computed/computed-artifact":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ArbitraryEqualityMap=require('../../lib/arbitrary-equality-map');
-
-class ComputedArtifact{
-
-
-
-constructor(allComputedArtifacts){
-
-this._cache=new ArbitraryEqualityMap();
-this._cache.setEqualityFn(ArbitraryEqualityMap.deepEquals);
-
-
-this._allComputedArtifacts=allComputedArtifacts;
-}
-
-get requiredNumberOfArtifacts(){
-return 1;
-}
-
-
-
-
-
-
-
-
-
-
-
-compute_(artifact,allComputedArtifacts){
-throw new Error('compute_() not implemented for computed artifact '+this.name);
-}
-
-
-
-
-
-_assertCorrectNumberOfArtifacts(artifacts){
-const actual=artifacts.length;
-const expected=this.requiredNumberOfArtifacts;
-if(actual!==expected){
-const className=this.constructor.name;
-throw new Error(`${className} requires ${expected} artifacts but ${actual} were given`);
-}
-}
-
-
-
-
-
-
-
-
-request(...artifacts){
-this._assertCorrectNumberOfArtifacts(artifacts);
-if(this._cache.has(artifacts)){
-return Promise.resolve(this._cache.get(artifacts));
-}
-
-const artifactPromise=Promise.resolve().
-then(_=>this.compute_(...artifacts,this._allComputedArtifacts));
-this._cache.set(artifacts,artifactPromise);
-
-return artifactPromise;
-}}
-
-
-module.exports=ComputedArtifact;
-
-},{"../../lib/arbitrary-equality-map":17}],"./gather/computed/critical-request-chains":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const WebInspector=require('../../lib/web-inspector');
-const assert=require('assert');
-
-class CriticalRequestChains extends ComputedArtifact{
-get name(){
-return'CriticalRequestChains';
-}
-
-
-
-
-
-
-
-
-static isCritical(request,mainResource){
-assert.ok(mainResource,'mainResource not provided');
-const resourceTypeCategory=request._resourceType&&request._resourceType._category;
-
-
-const isIframe=request._resourceType===WebInspector.resourceTypes.Document&&
-request.frameId!==mainResource.frameId;
-
-
-
-const nonCriticalResourceTypes=[
-WebInspector.resourceTypes.Image._category,
-WebInspector.resourceTypes.XHR._category];
-
-if(nonCriticalResourceTypes.includes(resourceTypeCategory)||
-isIframe||
-request.mimeType&&request.mimeType.startsWith('image/')){
-return false;
-}
-
-return['VeryHigh','High','Medium'].includes(request.priority());
-}
-
-static extractChain([networkRecords,mainResource]){
-networkRecords=networkRecords.filter(req=>req.finished);
-
-
-const requestIdToRequests=new Map();
-for(const request of networkRecords){
-requestIdToRequests.set(request.requestId,request);
-}
-
-
-
-const criticalRequests=networkRecords.filter(request=>
-CriticalRequestChains.isCritical(request,mainResource));
-
-
-const criticalRequestChains={};
-for(const request of criticalRequests){
-
-
-
-const ancestors=[];
-let ancestorRequest=request.initiatorRequest();
-let node=criticalRequestChains;
-while(ancestorRequest){
-const ancestorIsCritical=CriticalRequestChains.isCritical(ancestorRequest,mainResource);
-
-
-
-
-
-if(!ancestorIsCritical||ancestors.includes(ancestorRequest.requestId)){
-
-
-ancestors.length=0;
-node=undefined;
-break;
-}
-ancestors.push(ancestorRequest.requestId);
-ancestorRequest=ancestorRequest.initiatorRequest();
-}
-
-
-
-let ancestor=ancestors.pop();
-while(ancestor){
-const parentRequest=requestIdToRequests.get(ancestor);
-const parentRequestId=parentRequest.requestId;
-if(!node[parentRequestId]){
-node[parentRequestId]={
-request:parentRequest,
-children:{}};
-
-}
-
-
-ancestor=ancestors.pop();
-node=node[parentRequestId].children;
-}
-
-if(!node){
-continue;
-}
-
-
-if(node[request.requestId]){
-continue;
-}
-
-
-node[request.requestId]={
-request,
-children:{}};
-
-}
-
-return criticalRequestChains;
-}
-
-
-
-
-
-
-compute_(devtoolsLog,artifacts){
-return Promise.all([
-artifacts.requestNetworkRecords(devtoolsLog),
-artifacts.requestMainResource(devtoolsLog)]).
-
-then(CriticalRequestChains.extractChain);
-}}
-
-
-module.exports=CriticalRequestChains;
-
-},{"../../lib/web-inspector":42,"./computed-artifact":"./gather/computed/computed-artifact","assert":47}],"./gather/computed/dtm-model":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const DTM=require('../../lib/traces/devtools-timeline-model');
-
-class DevtoolsTimelineModel extends ComputedArtifact{
-get name(){
-return'DevtoolsTimelineModel';
-}
-
-
-
-
-
-compute_(trace){
-return Promise.resolve(new DTM(trace));
-}}
-
-
-module.exports=DevtoolsTimelineModel;
-
-},{"../../lib/traces/devtools-timeline-model":37,"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/first-interactive":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const TracingProcessor=require('../../lib/traces/tracing-processor');
-const LHError=require('../../lib/errors');
-
-const LONG_TASK_THRESHOLD=50;
-
-const MAX_TASK_CLUSTER_DURATION=250;
-const MIN_TASK_CLUSTER_PADDING=1000;
-const MIN_TASK_CLUSTER_FMP_DISTANCE=5000;
-
-const MAX_QUIET_WINDOW_SIZE=5000;
-
-
-const EXPONENTIATION_COEFFICIENT=-Math.log(3-1)/15;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class FirstInteractive extends ComputedArtifact{
-get name(){
-return'FirstInteractive';
-}
-
-
-
-
-
-static getRequiredWindowSizeInMs(t){
-const tInSeconds=t/1000;
-const exponentiationComponent=Math.exp(EXPONENTIATION_COEFFICIENT*tInSeconds);
-return(4*exponentiationComponent+1)*1000;
-}
-
-
-
-
-
-
-
-
-
-
-static getTaskClustersInWindow(tasks,startIndex,windowEnd){
-const clusters=[];
-
-let previousTaskEndTime=-Infinity;
-let currentCluster=null;
-
-
-
-
-
-const clusteringWindowEnd=windowEnd+MIN_TASK_CLUSTER_PADDING;
-const isInClusteringWindow=task=>task.start<clusteringWindowEnd;
-for(let i=startIndex;i<tasks.length;i++){
-if(!isInClusteringWindow(tasks[i])){
-break;
-}
-
-const task=tasks[i];
-
-
-if(task.start-previousTaskEndTime>MIN_TASK_CLUSTER_PADDING){
-currentCluster=[];
-clusters.push(currentCluster);
-}
-
-currentCluster.push(task);
-previousTaskEndTime=task.end;
-}
-
-return clusters.
-
-map(tasks=>{
-const start=tasks[0].start;
-const end=tasks[tasks.length-1].end;
-const duration=end-start;
-return{start,end,duration};
-}).
-
-filter(cluster=>cluster.start<windowEnd);
-}
-
-
-
-
-
-
-
-
-
-
-static findQuietWindow(FMP,traceEnd,longTasks){
-
-if(longTasks.length===0||
-longTasks[0].start>FMP+FirstInteractive.getRequiredWindowSizeInMs(0)){
-return FMP;
-}
-
-const isTooCloseToFMP=cluster=>cluster.start<FMP+MIN_TASK_CLUSTER_FMP_DISTANCE;
-const isTooLong=cluster=>cluster.duration>MAX_TASK_CLUSTER_DURATION;
-const isBadCluster=cluster=>isTooCloseToFMP(cluster)||isTooLong(cluster);
-
-
-
-for(let i=0;i<longTasks.length;i++){
-const windowStart=longTasks[i].end;
-const windowSize=FirstInteractive.getRequiredWindowSizeInMs(windowStart-FMP);
-const windowEnd=windowStart+windowSize;
-
-
-if(windowEnd>traceEnd){
-throw new LHError(LHError.errors.NO_FCPUI_IDLE_PERIOD);
-}
-
-
-if(i+1<longTasks.length&&
-longTasks[i+1].start-windowStart<=MIN_TASK_CLUSTER_PADDING){
-continue;
-}
-
-const taskClusters=FirstInteractive.getTaskClustersInWindow(longTasks,i+1,windowEnd);
-const hasBadTaskClusters=taskClusters.some(isBadCluster);
-
-if(!hasBadTaskClusters){
-return windowStart;
-}
-}
-
-throw new LHError(LHError.errors.NO_FCPUI_IDLE_PERIOD);
-}
-
-
-
-
-
-computeWithArtifacts(traceOfTab){
-const navStart=traceOfTab.timestamps.navigationStart;
-const FMP=traceOfTab.timings.firstMeaningfulPaint;
-const DCL=traceOfTab.timings.domContentLoaded;
-const traceEnd=traceOfTab.timings.traceEnd;
-
-if(traceEnd-FMP<MAX_QUIET_WINDOW_SIZE){
-throw new LHError(LHError.errors.FMP_TOO_LATE_FOR_FCPUI);
-}
-
-if(!FMP||!DCL){
-throw new LHError(FMP?LHError.errors.NO_DCL:LHError.errors.NO_FMP);
-}
-
-const longTasksAfterFMP=TracingProcessor.getMainThreadTopLevelEvents(traceOfTab,FMP).
-filter(evt=>evt.duration>=LONG_TASK_THRESHOLD);
-const firstInteractive=FirstInteractive.findQuietWindow(FMP,traceEnd,longTasksAfterFMP);
-
-const valueInMs=Math.max(firstInteractive,DCL);
-return{
-timeInMs:valueInMs,
-timestamp:valueInMs*1000+navStart};
-
-}
-
-
-
-
-
-
-compute_(trace,artifacts){
-return artifacts.requestTraceOfTab(trace).then(traceOfTab=>{
-return this.computeWithArtifacts(traceOfTab);
-});
-}}
-
-
-module.exports=FirstInteractive;
-
-},{"../../lib/errors":28,"../../lib/traces/tracing-processor":40,"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/main-resource":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const HTTP_REDIRECT_CODE_LOW=300;
-const HTTP_REDIRECT_CODE_HIGH=399;
-
-
-
-
-
-class MainResource extends ComputedArtifact{
-get name(){
-return'MainResource';
-}
-
-
-
-
-
-isMainResource(request){
-return request.statusCode<HTTP_REDIRECT_CODE_LOW||
-request.statusCode>HTTP_REDIRECT_CODE_HIGH;
-}
-
-
-
-
-
-
-compute_(devtoolsLog,artifacts){
-return artifacts.requestNetworkRecords(devtoolsLog).
-then(requests=>{
-const mainResource=requests.find(this.isMainResource);
-
-if(!mainResource){
-throw new Error('Unable to identify the main resource');
-}
-
-return mainResource;
-});
-}}
-
-
-module.exports=MainResource;
-
-},{"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/manifest-values":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const icons=require('../../lib/icons');
-
-const PWA_DISPLAY_VALUES=['minimal-ui','fullscreen','standalone'];
-
-
-
-const SUGGESTED_SHORTNAME_LENGTH=12;
-
-class ManifestValues extends ComputedArtifact{
-get name(){
-return'ManifestValues';
-}
-
-static get validityIds(){
-return['hasManifest','hasParseableManifest'];
-}
-
-static get manifestChecks(){
-return[
-{
-id:'hasStartUrl',
-failureText:'Manifest does not contain a `start_url`',
-validate:manifest=>!!manifest.value.start_url.value},
-
-{
-id:'hasIconsAtLeast192px',
-failureText:'Manifest does not have icons at least 192px',
-validate:manifest=>icons.doExist(manifest.value)&&
-icons.sizeAtLeast(192,manifest.value).length>0},
-
-{
-id:'hasIconsAtLeast512px',
-failureText:'Manifest does not have icons at least 512px',
-validate:manifest=>icons.doExist(manifest.value)&&
-icons.sizeAtLeast(512,manifest.value).length>0},
-
-{
-id:'hasPWADisplayValue',
-failureText:'Manifest\'s `display` value is not one of: '+PWA_DISPLAY_VALUES.join(' | '),
-validate:manifest=>PWA_DISPLAY_VALUES.includes(manifest.value.display.value)},
-
-{
-id:'hasBackgroundColor',
-failureText:'Manifest does not have `background_color`',
-validate:manifest=>!!manifest.value.background_color.value},
-
-{
-id:'hasThemeColor',
-failureText:'Manifest does not have `theme_color`',
-validate:manifest=>!!manifest.value.theme_color.value},
-
-{
-id:'hasShortName',
-failureText:'Manifest does not have `short_name`',
-validate:manifest=>!!manifest.value.short_name.value},
-
-{
-id:'shortNameLength',
-failureText:'Manifest `short_name` will be truncated when displayed on the homescreen',
-validate:manifest=>!!manifest.value.short_name.value&&
-manifest.value.short_name.value.length<=SUGGESTED_SHORTNAME_LENGTH},
-
-{
-id:'hasName',
-failureText:'Manifest does not have `name`',
-validate:manifest=>!!manifest.value.name.value}];
-
-
-}
-
-
-
-
-
-
-compute_(manifest){
-
-let parseFailureReason;
-
-if(manifest===null){
-parseFailureReason='No manifest was fetched';
-}
-if(manifest&&manifest.value===undefined){
-parseFailureReason='Manifest failed to parse as valid JSON';
-}
-if(parseFailureReason){
-return{
-isParseFailure:true,
-parseFailureReason,
-allChecks:[]};
-
-}
-
-
-const remainingChecks=ManifestValues.manifestChecks.map(item=>{
-item.passing=item.validate(manifest);
-return item;
-});
-
-return{
-isParseFailure:false,
-parseFailureReason,
-allChecks:remainingChecks};
-
-}}
-
-
-module.exports=ManifestValues;
-
-},{"../../lib/icons":30,"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/network-records":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const NetworkRecorder=require('../../lib/network-recorder');
-
-class NetworkRecords extends ComputedArtifact{
-get name(){
-return'NetworkRecords';
-}
-
-
-
-
-
-compute_(devtoolsLog){
-return NetworkRecorder.recordsFromLogs(devtoolsLog);
-}}
-
-
-module.exports=NetworkRecords;
-
-},{"../../lib/network-recorder":32,"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/network-throughput":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-
-class NetworkThroughput extends ComputedArtifact{
-get name(){
-return'NetworkThroughput';
-}
-
-
-
-
-
-
-
-
-
-static getThroughput(networkRecords){
-let totalBytes=0;
-const timeBoundaries=networkRecords.reduce((boundaries,record)=>{
-const scheme=record.parsedURL&&record.parsedURL.scheme;
-if(scheme==='data'||record.failed||!record.finished||
-record.statusCode>300||!record.transferSize){
-return boundaries;
-}
-
-totalBytes+=record.transferSize;
-boundaries.push({time:record.responseReceivedTime,isStart:true});
-boundaries.push({time:record.endTime,isStart:false});
-return boundaries;
-},[]).sort((a,b)=>a.time-b.time);
-
-if(!timeBoundaries.length){
-return Infinity;
-}
-
-let inflight=0;
-let currentStart=0;
-let totalDuration=0;
-timeBoundaries.forEach(boundary=>{
-if(boundary.isStart){
-if(inflight===0){
-currentStart=boundary.time;
-}
-inflight++;
-}else{
-inflight--;
-if(inflight===0){
-totalDuration+=boundary.time-currentStart;
-}
-}
-});
-
-return totalBytes/totalDuration;
-}
-
-
-
-
-
-
-compute_(devtoolsLog,artifacts){
-return artifacts.requestNetworkRecords(devtoolsLog).
-then(NetworkThroughput.getThroughput);
-}}
-
-
-module.exports=NetworkThroughput;
-
-},{"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/page-dependency-graph":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const NetworkNode=require('../../lib/dependency-graph/network-node');
-const CPUNode=require('../../lib/dependency-graph/cpu-node');
-const TracingProcessor=require('../../lib/traces/tracing-processor');
-const WebInspector=require('../../lib/web-inspector');
-
-
-const MINIMUM_TASK_DURATION_OF_INTEREST=10;
-
-
-const IGNORED_MIME_TYPES_REGEX=/^video/;
-
-class PageDependencyGraphArtifact extends ComputedArtifact{
-get name(){
-return'PageDependencyGraph';
-}
-
-get requiredNumberOfArtifacts(){
-return 2;
-}
-
-
-
-
-
-static getNetworkInitiators(record){
-if(!record._initiator)return[];
-if(record._initiator.url)return[record._initiator.url];
-if(record._initiator.type==='script'){
-const frames=record._initiator.stack.callFrames;
-return Array.from(new Set(frames.map(frame=>frame.url))).filter(Boolean);
-}
-
-return[];
-}
-
-
-
-
-
-static getNetworkNodeOutput(networkRecords){
-const nodes=[];
-const idToNodeMap=new Map();
-const urlToNodeMap=new Map();
-
-networkRecords.forEach(record=>{
-if(IGNORED_MIME_TYPES_REGEX.test(record.mimeType))return;
-const node=new NetworkNode(record);
-nodes.push(node);
-
-const list=urlToNodeMap.get(record.url)||[];
-list.push(node);
-
-idToNodeMap.set(record.requestId,node);
-urlToNodeMap.set(record.url,list);
-});
-
-return{nodes,idToNodeMap,urlToNodeMap};
-}
-
-
-
-
-
-static getCPUNodes(traceOfTab){
-const nodes=[];
-let i=0;
-
-const minimumEvtDur=MINIMUM_TASK_DURATION_OF_INTEREST*1000;
-while(i<traceOfTab.mainThreadEvents.length){
-const evt=traceOfTab.mainThreadEvents[i];
-
-
-if(
-!TracingProcessor.isScheduleableTask(evt)||
-!evt.dur||
-evt.dur<minimumEvtDur)
-{
-i++;
-continue;
-}
-
-
-const children=[];
-i++;
-for(
-const endTime=evt.ts+evt.dur;
-i<traceOfTab.mainThreadEvents.length&&traceOfTab.mainThreadEvents[i].ts<endTime;
-i++)
-{
-children.push(traceOfTab.mainThreadEvents[i]);
-}
-
-nodes.push(new CPUNode(evt,children));
-}
-
-return nodes;
-}
-
-
-
-
-
-static linkNetworkNodes(rootNode,networkNodeOutput){
-networkNodeOutput.nodes.forEach(node=>{
-const initiators=PageDependencyGraphArtifact.getNetworkInitiators(node.record);
-if(initiators.length){
-initiators.forEach(initiator=>{
-const parentCandidates=networkNodeOutput.urlToNodeMap.get(initiator)||[rootNode];
-
-const parent=parentCandidates.length===1?parentCandidates[0]:rootNode;
-node.addDependency(parent);
-});
-}else if(node!==rootNode){
-rootNode.addDependent(node);
-}
-
-const redirects=Array.from(node.record.redirects||[]);
-redirects.push(node.record);
-
-for(let i=1;i<redirects.length;i++){
-const redirectNode=networkNodeOutput.idToNodeMap.get(redirects[i-1].requestId);
-const actualNode=networkNodeOutput.idToNodeMap.get(redirects[i].requestId);
-actualNode.addDependency(redirectNode);
-}
-});
-}
-
-
-
-
-
-
-static linkCPUNodes(rootNode,networkNodeOutput,cpuNodes){
-function addDependentNetworkRequest(cpuNode,reqId){
-const networkNode=networkNodeOutput.idToNodeMap.get(reqId);
-if(!networkNode||
-networkNode.record._resourceType!==WebInspector.resourceTypes.XHR)return;
-cpuNode.addDependent(networkNode);
-}
-
-function addDependencyOnUrl(cpuNode,url){
-if(!url)return;
-const candidates=networkNodeOutput.urlToNodeMap.get(url)||[];
-
-let minCandidate=null;
-let minDistance=Infinity;
-
-candidates.forEach(candidate=>{
-const distance=cpuNode.startTime-candidate.endTime;
-if(distance>0&&distance<minDistance){
-minCandidate=candidate;
-minDistance=distance;
-}
-});
-
-if(!minCandidate)return;
-cpuNode.addDependency(minCandidate);
-}
-
-const timers=new Map();
-for(const node of cpuNodes){
-for(const evt of node.childEvents){
-if(!evt.args.data)continue;
-
-const url=evt.args.data.url;
-const stackTraceUrls=(evt.args.data.stackTrace||[]).map(l=>l.url).filter(Boolean);
-
-switch(evt.name){
-case'TimerInstall':
-timers.set(evt.args.data.timerId,node);
-stackTraceUrls.forEach(url=>addDependencyOnUrl(node,url));
-break;
-case'TimerFire':{
-const installer=timers.get(evt.args.data.timerId);
-if(!installer)break;
-installer.addDependent(node);
-break;
-}
-
-case'InvalidateLayout':
-case'ScheduleStyleRecalculation':
-stackTraceUrls.forEach(url=>addDependencyOnUrl(node,url));
-break;
-
-case'EvaluateScript':
-addDependencyOnUrl(node,url);
-stackTraceUrls.forEach(url=>addDependencyOnUrl(node,url));
-break;
-
-case'XHRReadyStateChange':
-
-if(evt.args.data.readyState!==4)break;
-
-addDependencyOnUrl(node,url);
-stackTraceUrls.forEach(url=>addDependencyOnUrl(node,url));
-break;
-
-case'FunctionCall':
-case'v8.compile':
-addDependencyOnUrl(node,url);
-break;
-
-case'ParseAuthorStyleSheet':
-addDependencyOnUrl(node,evt.args.data.styleSheetUrl);
-break;
-
-case'ResourceSendRequest':
-addDependentNetworkRequest(node,evt.args.data.requestId,evt);
-stackTraceUrls.forEach(url=>addDependencyOnUrl(node,url));
-break;}
-
-}
-
-if(node.getNumberOfDependencies()===0){
-node.addDependency(rootNode);
-}
-}
-}
-
-
-
-
-
-
-static createGraph(traceOfTab,networkRecords){
-const networkNodeOutput=PageDependencyGraphArtifact.getNetworkNodeOutput(networkRecords);
-const cpuNodes=PageDependencyGraphArtifact.getCPUNodes(traceOfTab);
-
-const rootRequest=networkRecords.reduce((min,r)=>min.startTime<r.startTime?min:r);
-const rootNode=networkNodeOutput.idToNodeMap.get(rootRequest.requestId);
-
-PageDependencyGraphArtifact.linkNetworkNodes(rootNode,networkNodeOutput,networkRecords);
-PageDependencyGraphArtifact.linkCPUNodes(rootNode,networkNodeOutput,cpuNodes);
-
-if(NetworkNode.hasCycle(rootNode)){
-throw new Error('Invalid dependency graph created, cycle detected');
-}
-
-return rootNode;
-}
-
-
-
-
-
-static printGraph(rootNode,widthInCharacters=100){
-function padRight(str,target,padChar=' '){
-return str+padChar.repeat(Math.max(target-str.length,0));
-}
-
-const nodes=[];
-rootNode.traverse(node=>nodes.push(node));
-nodes.sort((a,b)=>a.startTime-b.startTime);
-
-const min=nodes[0].startTime;
-const max=nodes.reduce((max,node)=>Math.max(max,node.endTime),0);
-
-const totalTime=max-min;
-const timePerCharacter=totalTime/widthInCharacters;
-nodes.forEach(node=>{
-const offset=Math.round((node.startTime-min)/timePerCharacter);
-const length=Math.ceil((node.endTime-node.startTime)/timePerCharacter);
-const bar=padRight('',offset)+padRight('',length,'=');
-
-const displayName=node.record?node.record._url:node.type;
-
-console.log(padRight(bar,widthInCharacters),`| ${displayName.slice(0,30)}`);
-});
-}
-
-
-
-
-
-
-
-compute_(trace,devtoolsLog,artifacts){
-const promises=[
-artifacts.requestTraceOfTab(trace),
-artifacts.requestNetworkRecords(devtoolsLog)];
-
-
-return Promise.all(promises).then(([traceOfTab,networkRecords])=>{
-return PageDependencyGraphArtifact.createGraph(traceOfTab,networkRecords);
-});
-}}
-
-
-module.exports=PageDependencyGraphArtifact;
-
-
-
-
-
-
-
-
-PageDependencyGraphArtifact.NetworkNodeOutput;
-
-},{"../../lib/dependency-graph/cpu-node":20,"../../lib/dependency-graph/network-node":21,"../../lib/traces/tracing-processor":40,"../../lib/web-inspector":42,"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/pushed-requests":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-
-class PushedRequests extends ComputedArtifact{
-get name(){
-return'PushedRequests';
-}
-
-
-
-
-
-
-
-compute_(devtoolsLog,artifacts){
-return artifacts.requestNetworkRecords(devtoolsLog).then(records=>{
-const pushedRecords=records.filter(r=>r._timing&&!!r._timing.pushStart);
-return pushedRecords;
-});
-}}
-
-
-module.exports=PushedRequests;
-
-},{"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/screenshots":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-
-class ScreenshotFilmstrip extends ComputedArtifact{
-get name(){
-return'Screenshots';
-}
-
-fetchScreenshot(frame){
-return frame.
-imageDataPromise().
-then(data=>'data:image/jpg;base64,'+data);
-}
-
-
-
-
-
-
-compute_(trace,artifacts){
-return artifacts.requestDevtoolsTimelineModel(trace).then(model=>{
-const filmStripFrames=model.filmStripModel().frames();
-const frameFetches=filmStripFrames.map(frame=>this.fetchScreenshot(frame));
-
-return Promise.all(frameFetches).then(images=>{
-const result=filmStripFrames.map((frame,i)=>({
-timestamp:frame.timestamp,
-datauri:images[i]}));
-
-return result;
-});
-});
-}}
-
-
-module.exports=ScreenshotFilmstrip;
-
-},{"./computed-artifact":"./gather/computed/computed-artifact"}],"./gather/computed/speedline":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const ComputedArtifact=require('./computed-artifact');
-const speedline=require('speedline');
-const LHError=require('../../lib/errors');
-
-class Speedline extends ComputedArtifact{
-get name(){
-return'Speedline';
-}
-
-
-
-
-compute_(trace,computedArtifacts){
-
-
-return computedArtifacts.requestTraceOfTab(trace).then(traceOfTab=>{
-
-
-const traceEvents=trace.traceEvents.slice();
-
-
-const navStart=traceOfTab.timestamps.navigationStart;
-return speedline(traceEvents,{
-timeOrigin:navStart,
-fastMode:true,
-include:'perceptualSpeedIndex'});
-
-}).catch(err=>{
-if(/No screenshots found in trace/.test(err.message)){
-throw new LHError(LHError.errors.NO_SCREENSHOTS);
-}
-
-throw err;
-});
-}}
-
-
-module.exports=Speedline;
-
-},{"../../lib/errors":28,"./computed-artifact":"./gather/computed/computed-artifact","speedline":144}],"./gather/computed/trace-of-tab":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-
-
-
-
-const ComputedArtifact=require('./computed-artifact');
-const log=require('lighthouse-logger');
-const LHError=require('../../lib/errors');
-const Sentry=require('../../lib/sentry');
-
-
-
-
-const WebInspector=require('../../lib/web-inspector');
-
-class TraceOfTab extends ComputedArtifact{
-get name(){
-return'TraceOfTab';
-}
-
-
-
-
-
-
-
-compute_(trace){
-
-
-const keyEvents=trace.traceEvents.
-filter(e=>{
-return e.cat.includes('blink.user_timing')||
-e.cat.includes('loading')||
-e.cat.includes('devtools.timeline')||
-e.name==='TracingStartedInPage';
-}).
-stableSort((event0,event1)=>event0.ts-event1.ts);
-
-
-
-const startedInPageEvt=keyEvents.find(e=>e.name==='TracingStartedInPage');
-if(!startedInPageEvt)throw new LHError(LHError.errors.NO_TRACING_STARTED);
-
-const frameEvents=keyEvents.filter(e=>e.args.frame===startedInPageEvt.args.data.page);
-
-
-const navigationStart=frameEvents.filter(e=>e.name==='navigationStart').pop();
-if(!navigationStart)throw new LHError(LHError.errors.NO_NAVSTART);
-
-
-const firstPaint=frameEvents.find(e=>e.name==='firstPaint'&&e.ts>navigationStart.ts);
-
-
-const firstContentfulPaint=frameEvents.find(
-e=>e.name==='firstContentfulPaint'&&e.ts>navigationStart.ts);
-
-
-
-let firstMeaningfulPaint=frameEvents.find(
-e=>e.name==='firstMeaningfulPaint'&&e.ts>navigationStart.ts);
-
-let fmpFellBack=false;
-
-
-
-
-
-if(!firstMeaningfulPaint){
-
-Sentry.captureMessage('No firstMeaningfulPaint found, using fallback',{level:'warning'});
-
-const fmpCand='firstMeaningfulPaintCandidate';
-fmpFellBack=true;
-log.verbose('trace-of-tab',`No firstMeaningfulPaint found, falling back to last ${fmpCand}`);
-const lastCandidate=frameEvents.filter(e=>e.name===fmpCand).pop();
-if(!lastCandidate){
-log.verbose('trace-of-tab','No `firstMeaningfulPaintCandidate` events found in trace');
-}
-firstMeaningfulPaint=lastCandidate;
-}
-
-const onLoad=frameEvents.find(e=>e.name==='loadEventEnd'&&e.ts>navigationStart.ts);
-const domContentLoaded=frameEvents.find(
-e=>e.name==='domContentLoadedEventEnd'&&e.ts>navigationStart.ts);
-
-
-
-
-const processEvents=trace.traceEvents.
-filter(e=>e.pid===startedInPageEvt.pid).
-stableSort((event0,event1)=>event0.ts-event1.ts);
-
-const mainThreadEvents=processEvents.
-filter(e=>e.tid===startedInPageEvt.tid);
-
-const traceEnd=trace.traceEvents.reduce((max,evt)=>{
-return max.ts>evt.ts?max:evt;
-});
-
-const metrics={
-navigationStart,
-firstPaint,
-firstContentfulPaint,
-firstMeaningfulPaint,
-traceEnd:{ts:traceEnd.ts+(traceEnd.dur||0)},
-onLoad,
-domContentLoaded};
-
-
-const timings={};
-const timestamps={};
-
-Object.keys(metrics).forEach(metric=>{
-timestamps[metric]=metrics[metric]&&metrics[metric].ts;
-timings[metric]=(timestamps[metric]-navigationStart.ts)/1000;
-});
-
-return{
-timings,
-timestamps,
-processEvents,
-mainThreadEvents,
-startedInPageEvt,
-navigationStartEvt:navigationStart,
-firstPaintEvt:firstPaint,
-firstContentfulPaintEvt:firstContentfulPaint,
-firstMeaningfulPaintEvt:firstMeaningfulPaint,
-onLoadEvt:onLoad,
-fmpFellBack};
-
-}}
-
-
-module.exports=TraceOfTab;
-
-},{"../../lib/errors":28,"../../lib/sentry":33,"../../lib/web-inspector":42,"./computed-artifact":"./gather/computed/computed-artifact","lighthouse-logger":137}],"./gatherers/accessibility":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-const Gatherer=require('./gatherer');
-
-const axeLibSource="/*! aXe v2.6.1\n * Copyright (c) 2017 Deque Systems, Inc.\n *\n * Your use of 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 * This entire copyright notice must appear in every copy of this file you\n * distribute or in any file that contains substantial portions of this source\n * code.\n */\n!function a(window){function b(a){this.name=\"SupportError\",this.cause=a.cause,this.message=\"`\"+a.cause+\"` - feature unsupported in your environment.\",a.ruleId&&(this.ruleId=a.ruleId,this.message+=\" Skipping \"+this.ruleId+\" rule.\"),this.stack=(new Error).stack}function c(a){\"use strict\";var b;return a?(b=axe.utils.clone(a),b.commons=a.commons):b={},b.reporter=b.reporter||null,b.rules=b.rules||[],b.checks=b.checks||[],b.data=Object.assign({checks:{},rules:{}},b.data),b}function d(a,b,c){\"use strict\";var d,e;for(d=0,e=a.length;d<e;d++)b[c](a[d])}function e(a){this.brand=\"axe\",this.application=\"axeAPI\",this.tagExclude=[\"experimental\"],this.defaultConfig=a,this._init()}function f(a,b,c){var d=a.brand,e=a.application;return axe.constants.helpUrlBase+d+\"/\"+(c||axe.version.substring(0,axe.version.lastIndexOf(\".\")))+\"/\"+b+\"?application=\"+e}function g(a){\"use strict\";this.id=a.id,this.data=null,this.relatedNodes=[],this.result=null}function h(a){\"use strict\";return\"string\"==typeof a?new Function(\"return \"+a+\";\")():a}function i(a){a&&(this.id=a.id,this.configure(a))}function j(a,b){\"use strict\";if(!axe.utils.isHidden(b)){axe.utils.findBy(a,\"node\",b)||a.push({node:b,include:[],exclude:[]})}}function k(a,b,c){\"use strict\";a.frames=a.frames||[];var d,e,f=document.querySelectorAll(c.shift());a:for(var g=0,h=f.length;g<h;g++){e=f[g];for(var i=0,j=a.frames.length;i<j;i++)if(a.frames[i].node===e){a.frames[i][b].push(c);break a}d={node:e,include:[],exclude:[]},c&&d[b].push(c),a.frames.push(d)}}function l(a){\"use strict\";if(a&&\"object\"===(void 0===a?\"undefined\":ha(a))||a instanceof NodeList){if(a instanceof Node)return{include:[a],exclude:[]};if(a.hasOwnProperty(\"include\")||a.hasOwnProperty(\"exclude\"))return{include:a.include&&+a.include.length?a.include:[document],exclude:a.exclude||[]};if(a.length===+a.length)return{include:a,exclude:[]}}return\"string\"==typeof a?{include:[a],exclude:[]}:{include:[document],exclude:[]}}function m(a,b){\"use strict\";for(var c,d=[],e=0,f=a[b].length;e<f;e++){if(\"string\"==typeof(c=a[b][e])){d=d.concat(axe.utils.toArray(document.querySelectorAll(c)));break}!c||!c.length||c instanceof Node?d.push(c):c.length>1?k(a,b,c):d=d.concat(axe.utils.toArray(document.querySelectorAll(c[0])))}return d.filter(function(a){return a})}function n(a){\"use strict\";if(0===a.include.length){if(0===a.frames.length){var b=axe.utils.respondable.isInFrame()?\"frame\":\"page\";return new Error(\"No elements found for include in \"+b+\" Context\")}a.frames.forEach(function(a,b){if(0===a.include.length)return new Error(\"No elements found for include in Context of frame \"+b)})}}function o(a){\"use strict\";var b=this;this.frames=[],this.initiator=!a||\"boolean\"!=typeof a.initiator||a.initiator,this.page=!1,a=l(a),this.exclude=a.exclude,this.include=a.include,this.include=m(this,\"include\"),this.exclude=m(this,\"exclude\"),axe.utils.select(\"frame, iframe\",this).forEach(function(a){fa(a,b)&&j(b.frames,a)}),1===this.include.length&&this.include[0]===document&&(this.page=!0);var c=n(this);if(c instanceof Error)throw c}function p(a){\"use strict\";this.id=a.id,this.result=axe.constants.NA,this.pageLevel=a.pageLevel,this.impact=null,this.nodes=[]}function q(a,b){\"use strict\";this._audit=b,this.id=a.id,this.selector=a.selector||\"*\",this.excludeHidden=\"boolean\"!=typeof a.excludeHidden||a.excludeHidden,this.enabled=\"boolean\"!=typeof a.enabled||a.enabled,this.pageLevel=\"boolean\"==typeof a.pageLevel&&a.pageLevel,this.any=a.any||[],this.all=a.all||[],this.none=a.none||[],this.tags=a.tags||[],a.matches&&(this.matches=h(a.matches))}function r(a){\"use strict\";return axe.utils.getAllChecks(a).map(function(b){var c=a._audit.checks[b.id||b];return c&&\"function\"==typeof c.after?c:null}).filter(Boolean)}function s(a,b){\"use strict\";var c=[];return a.forEach(function(a){axe.utils.getAllChecks(a).forEach(function(a){a.id===b&&c.push(a)})}),c}function t(a){\"use strict\";return a.filter(function(a){return!0!==a.filtered})}function u(a){\"use strict\";var b=[\"any\",\"all\",\"none\"],c=a.nodes.filter(function(a){var c=0;return b.forEach(function(b){a[b]=t(a[b]),c+=a[b].length}),c>0});return a.pageLevel&&c.length&&(c=[c.reduce(function(a,c){if(a)return b.forEach(function(b){a[b].push.apply(a[b],c[b])}),a})]),c}function v(a,b){\"use strict\";if(!axe._audit)throw new Error(\"No audit configured\");var c=axe.utils.queue(),d=[];Object.keys(axe.plugins).forEach(function(a){c.defer(function(b){var c=function(a){d.push(a),b()};try{axe.plugins[a].cleanup(b,c)}catch(a){c(a)}})}),axe.utils.toArray(document.querySelectorAll(\"frame, iframe\")).forEach(function(a){c.defer(function(b,c){return axe.utils.sendCommandToFrame(a,{command:\"cleanup-plugin\"},b,c)})}),c.then(function(c){0===d.length?a(c):b(d)}).catch(b)}function w(a){\"use strict\";var b;if(!(b=axe._audit))throw new Error(\"No audit configured\");a.reporter&&(\"function\"==typeof a.reporter||ka[a.reporter])&&(b.reporter=a.reporter),a.checks&&a.checks.forEach(function(a){b.addCheck(a)}),a.rules&&a.rules.forEach(function(a){b.addRule(a)}),void 0!==a.branding?b.setBranding(a.branding):b._constructHelpUrls(),a.tagExclude&&(b.tagExclude=a.tagExclude)}function x(a,b,c){\"use strict\";var d=c,e=function(a){a instanceof Error==!1&&(a=new Error(a)),c(a)},f=a&&a.context||{};f.hasOwnProperty(\"include\")&&!f.include.length&&(f.include=[document]);var g=a&&a.options||{};switch(a.command){case\"rules\":return A(f,g,d,e);case\"cleanup-plugin\":return v(d,e);default:if(axe._audit&&axe._audit.commands&&axe._audit.commands[a.command])return axe._audit.commands[a.command](a,c)}}function y(a){\"use strict\";this._run=a.run,this._collect=a.collect,this._registry={},a.commands.forEach(function(a){axe._audit.registerCommand(a)})}function z(){\"use strict\";var a=axe._audit;if(!a)throw new Error(\"No audit configured\");a.resetRulesAndChecks()}function A(a,b,c,d){\"use strict\";try{a=new o(a)}catch(a){return d(a)}var e=axe.utils.queue(),f=axe._audit;b.performanceTimer&&axe.utils.performanceTimer.auditStart(),a.frames.length&&!1!==b.iframes&&e.defer(function(c,d){axe.utils.collectResultsFromFrames(a,b,\"rules\",null,c,d)});var g=void 0;e.defer(function(c,d){b.restoreScroll&&(g=axe.utils.getScrollState()),f.run(a,b,c,d)}),e.then(function(e){try{g&&axe.utils.setScrollState(g),b.performanceTimer&&axe.utils.performanceTimer.auditEnd();var h=axe.utils.mergeResults(e.map(function(a){return{results:a}}));a.initiator&&(h=f.after(h,b),h.forEach(axe.utils.publishMetaData),h=h.map(axe.utils.finalizeRuleResult));try{c(h)}catch(a){axe.log(a)}}catch(a){d(a)}}).catch(d)}function B(a){\"use strict\";switch(!0){case\"string\"==typeof a:case Array.isArray(a):case Node&&a instanceof Node:case NodeList&&a instanceof NodeList:return!0;case\"object\"!==(void 0===a?\"undefined\":ha(a)):return!1;case void 0!==a.include:case void 0!==a.exclude:case\"number\"==typeof a.length:return!0;default:return!1}}function C(a,b,c){\"use strict\";var d=new TypeError(\"axe.run arguments are invalid\");if(!B(a)){if(void 0!==c)throw d;c=b,b=a,a=document}if(\"object\"!==(void 0===b?\"undefined\":ha(b))){if(void 0!==c)throw d;c=b,b={}}if(\"function\"!=typeof c&&void 0!==c)throw d;return{context:a,options:b,callback:c||la}}function D(a,b){\"use strict\";[\"any\",\"all\",\"none\"].forEach(function(c){Array.isArray(a[c])&&a[c].filter(function(a){return Array.isArray(a.relatedNodes)}).forEach(function(a){a.relatedNodes=a.relatedNodes.map(function(a){var c={html:a.source};return b.elementRef&&!a.fromFrame&&(c.element=a.element),(!1!==b.selectors||a.fromFrame)&&(c.target=a.selector),b.xpath&&(c.xpath=a.xpath),c})})})}function E(a,b){return ra.reduce(function(c,d){return c[d]=(a[d]||[]).map(function(a){return b(a,d)}),c},{})}function F(a,b,c){var d=Object.assign({},b);d.nodes=(d[c]||[]).concat(),axe.constants.resultGroups.forEach(function(a){delete d[a]}),a[c].push(d)}function G(a,b,c){\"use strict\";var d=window.getComputedStyle(a,null),e=!1;return!!d&&(b.forEach(function(a){d.getPropertyValue(a.property)===a.value&&(e=!0)}),!!e||!(a.nodeName.toUpperCase()===c.toUpperCase()||!a.parentNode)&&G(a.parentNode,b,c))}function H(a,b){\"use strict\";return new Error(a+\": \"+axe.utils.getSelector(b))}function I(a,b,c,d,e,f){\"use strict\";var g=axe.utils.queue();a.frames.forEach(function(e){var f={options:b,command:c,parameter:d,context:{initiator:!1,page:a.page,include:e.include||[],exclude:e.exclude||[]}};g.defer(function(a,b){var c=e.node;axe.utils.sendCommandToFrame(c,f,function(b){if(b)return a({results:b,frameElement:c,frame:axe.utils.getSelector(c)});a(null)},b)})}),g.then(function(a){e(axe.utils.mergeResults(a,b))}).catch(f)}function J(a,b){if(b=b||300,a.length>b){var c=a.indexOf(\">\");a=a.substring(0,c+1)}return a}function K(a){var b=a.outerHTML;return b||\"function\"!=typeof XMLSerializer||(b=(new XMLSerializer).serializeToString(a)),J(b||\"\")}function L(a,b,c){this._fromFrame=!!c,this.spec=c||{},b&&b.absolutePaths&&(this._options={toRoot:!0}),this.source=void 0!==this.spec.source?this.spec.source:K(a),this._element=a}function M(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:\"\";return 0!==a.length&&(a.match(/[0-9]/g)||\"\").length>=a.length/2}function N(a,b){return[a.substring(0,b),a.substring(b)]}function O(a){var b=a,c=\"\",d=\"\",e=\"\",f=\"\",g=\"\",h=\"\";if(a.includes(\"#\")){var i=N(a,a.indexOf(\"#\")),j=sa(i,2);a=j[0],h=j[1]}if(a.includes(\"?\")){var k=N(a,a.indexOf(\"?\")),l=sa(k,2);a=l[0],g=l[1]}if(a.includes(\"://\")){var m=a.split(\"://\"),n=sa(m,2);c=n[0],a=n[1];var o=N(a,a.indexOf(\"/\")),p=sa(o,2);d=p[0],a=p[1]}else if(\"//\"===a.substr(0,2)){a=a.substr(2);var q=N(a,a.indexOf(\"/\")),r=sa(q,2);d=r[0],a=r[1]}if(\"www.\"===d.substr(0,4)&&(d=d.substr(4)),d&&d.includes(\":\")){var s=N(d,d.indexOf(\":\")),t=sa(s,2);d=t[0],e=t[1]}return f=a,{original:b,protocol:c,domain:d,port:e,path:f,query:g,hash:h}}function P(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b<a.length;b++)c[b]=a[b];return c}return Array.from(a)}function Q(a){return![\"focus\",\"hover\",\"hidden\",\"visible\",\"dirty\",\"touched\",\"valid\",\"disable\",\"enable\",\"active\",\"col-\"].find(function(b){return a.includes(b)})}function R(a){return a.classList&&0!==a.classList.length?(a.parentNode&&Array.from(a.parentNode.children||\"\")||[]).reduce(function(b,c){return a===c?b:b.filter(function(a){return!c.classList.contains(a)})},Array.from(a.classList).filter(Q)):[]}function S(a,b){var c=a.parentNode&&Array.from(a.parentNode.children||\"\")||[];if(c.find(function(c){return c!==a&&axe.utils.matchesSelector(c,b)}))return\":nth-child(\"+(1+c.indexOf(a))+\")\";return\"\"}function T(a,b){void 0===ua&&(ua=axe.utils.isXHTML(document));var c=ta(ua?a.localName:a.nodeName.toLowerCase()),d=Array.from(a.classList)||[],e={nodeName:c,classList:d,isCustomElm:c.includes(\"-\"),isCommonElm:va.includes(c),distinctClassList:R(a)};return[wa.getCustomElm,wa.getElmRoleProp,wa.getUncommonElm,wa.getElmNameProp,wa.getDistinctClass,wa.getFileRefProp,wa.getCommonName].reduce(function(c,d){if(c.length===b)return c;var f=d(a,e);return f&&(f[0].match(/[a-z]/)?c.unshift(f):c.push(f)),c},[])}function U(a,b){var c,d;if(!a)return[];if(!b&&9===a.nodeType)return b=[{str:\"html\"}];if(b=b||[],a.parentNode&&a.parentNode!==a&&(b=U(a.parentNode,b)),a.previousSibling){d=1,c=a.previousSibling;do{1===c.nodeType&&c.nodeName===a.nodeName&&d++,c=c.previousSibling}while(c);1===d&&(d=null)}else if(a.nextSibling){c=a.nextSibling;do{1===c.nodeType&&c.nodeName===a.nodeName?(d=1,c=null):(d=null,c=c.previousSibling)}while(c)}if(1===a.nodeType){var e={};e.str=a.nodeName.toLowerCase();var f=a.getAttribute&&axe.utils.escapeSelector(a.getAttribute(\"id\"));f&&1===a.ownerDocument.querySelectorAll(\"#\"+f).length&&(e.id=a.getAttribute(\"id\")),d>1&&(e.count=d),b.push(e)}return b}function V(a){return a.reduce(function(a,b){return b.id?\"/\"+b.str+\"[@id='\"+b.id+\"']\":a+\"/\"+b.str+(b.count>0?\"[\"+b.count+\"]\":\"\")},\"\")}function W(a){\"use strict\";if(xa&&xa.parentNode)return void 0===xa.styleSheet?xa.appendChild(document.createTextNode(a)):xa.styleSheet.cssText+=a,xa;if(a){var b=document.head||document.getElementsByTagName(\"head\")[0];return xa=document.createElement(\"style\"),xa.type=\"text/css\",void 0===xa.styleSheet?xa.appendChild(document.createTextNode(a)):xa.styleSheet.cssText=a,b.appendChild(xa),xa}}function X(a,b,c,d){\"use strict\";var e=axe.utils.getXpath(c),f={element:c,selector:d,xpath:e};a.forEach(function(a){a.node=axe.utils.DqElement.fromFrame(a.node,b,f);var c=axe.utils.getAllChecks(a);c.length&&c.forEach(function(a){a.relatedNodes=a.relatedNodes.map(function(a){return axe.utils.DqElement.fromFrame(a,b,f)})})})}function Y(a,b){\"use strict\";for(var c,d,e=b[0].node,f=0,g=a.length;f<g;f++)if(d=a[f].node,(c=axe.utils.nodeSorter(d.element,e.element))>0||0===c&&e.selector.length<d.selector.length)return void a.splice.apply(a,[f,0].concat(b));a.push.apply(a,b)}function Z(a){\"use strict\";return a&&a.results?Array.isArray(a.results)?a.results.length?a.results:null:[a.results]:null}function $(a,b){function c(a){return a.incomplete&&a.incomplete.default?a.incomplete.default:ia.incompleteFallbackMessage()}if(!a||!a.missingData)return c(b);try{var d=b.incomplete[a.missingData[0].reason];if(!d)throw new Error;return d}catch(d){return\"string\"==typeof a.missingData?b.incomplete[a.missingData]:c(b)}}function _(a,b){\"use strict\";return function(c){var d=a[c.id]||{},e=d.messages||{},f=Object.assign({},d);delete f.messages,void 0===c.result?\"object\"===ha(e.incomplete)?f.message=function(){return $(c.data,e)}:f.message=e.incomplete:f.message=c.result===b?e.pass:e.fail,axe.utils.extendMetaData(c,f)}}function aa(a,b){\"use strict\";var c,d,e=axe._audit&&axe._audit.tagExclude?axe._audit.tagExclude:[];return b.hasOwnProperty(\"include\")||b.hasOwnProperty(\"exclude\")?(c=b.include||[],c=Array.isArray(c)?c:[c],d=b.exclude||[],d=Array.isArray(d)?d:[d],d=d.concat(e.filter(function(a){return-1===c.indexOf(a)}))):(c=Array.isArray(b)?b:[b],d=e.filter(function(a){return-1===c.indexOf(a)})),!!(c.some(function(b){return-1!==a.tags.indexOf(b)})||0===c.length&&!1!==a.enabled)&&d.every(function(b){return-1===a.tags.indexOf(b)})}function ba(a){var b=window.getComputedStyle(a),c=\"visible\"===b.getPropertyValue(\"overflow-y\"),d=\"visible\"===b.getPropertyValue(\"overflow-x\");if(!c&&a.scrollHeight>a.clientHeight||!d&&a.scrollWidth>a.clientWidth)return{elm:a,top:a.scrollTop,left:a.scrollLeft}}function ca(a,b,c){if(a===window)return a.scroll(b,c);a.scrollTop=b,a.scrollLeft=c}function da(a){return Array.from(a.children).reduce(function(a,b){var c=ba(b);return c&&a.push(c),a.concat(da(b))},[])}function ea(a){\"use strict\";return a.sort(function(a,b){return axe.utils.contains(a,b)?1:-1})[0]}function fa(a,b){\"use strict\";var c=b.include&&ea(b.include.filter(function(b){return axe.utils.contains(b,a)})),d=b.exclude&&ea(b.exclude.filter(function(b){return axe.utils.contains(b,a)}));return!!(!d&&c||d&&axe.utils.contains(d,c))}function ga(a,b,c){\"use strict\";for(var d=0,e=b.length;d<e;d++)-1===a.indexOf(b[d])&&fa(b[d],c)&&a.push(b[d])}var document=window.document,ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a},axe=axe||{};axe.version=\"2.6.1\",\"function\"==typeof define&&define.amd&&define([],function(){\"use strict\";return axe}),\"object\"===(\"undefined\"==typeof module?\"undefined\":ha(module))&&module.exports&&\"function\"==typeof a.toString&&(axe.source=\"(\"+a.toString()+')(typeof window === \"object\" ? window : this);',module.exports=axe),\"function\"==typeof window.getComputedStyle&&(window.axe=axe);var commons;b.prototype=Object.create(Error.prototype),b.prototype.constructor=b;var utils=axe.utils={},ia={},ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};e.prototype._init=function(){var a=c(this.defaultConfig);axe.commons=commons=a.commons,this.reporter=a.reporter,this.commands={},this.rules=[],this.checks={},d(a.rules,this,\"addRule\"),d(a.checks,this,\"addCheck\"),this.data={},this.data.checks=a.data&&a.data.checks||{},this.data.rules=a.data&&a.data.rules||{},this.data.failureSummaries=a.data&&a.data.failureSummaries||{},this.data.incompleteFallbackMessage=a.data&&a.data.incompleteFallbackMessage||\"\",this._constructHelpUrls()},e.prototype.registerCommand=function(a){\"use strict\";this.commands[a.id]=a.callback},e.prototype.addRule=function(a){\"use strict\";a.metadata&&(this.data.rules[a.id]=a.metadata);var b=this.getRule(a.id);b?b.configure(a):this.rules.push(new q(a,this))},e.prototype.addCheck=function(a){\"use strict\";var b=a.metadata;\"object\"===(void 0===b?\"undefined\":ha(b))&&(this.data.checks[a.id]=b,\"object\"===ha(b.messages)&&Object.keys(b.messages).filter(function(a){return b.messages.hasOwnProperty(a)&&\"string\"==typeof b.messages[a]}).forEach(function(a){0===b.messages[a].indexOf(\"function\")&&(b.messages[a]=new Function(\"return \"+b.messages[a]+\";\")())})),this.checks[a.id]?this.checks[a.id].configure(a):this.checks[a.id]=new i(a)},e.prototype.run=function(a,b,c,d){\"use strict\";this.validateOptions(b);var e=axe.utils.queue();this.rules.forEach(function(c){if(axe.utils.ruleShouldRun(c,a,b)){if(b.performanceTimer){var d=\"mark_rule_end_\"+c.id,f=\"mark_rule_start_\"+c.id;axe.utils.performanceTimer.mark(f)}e.defer(function(e,g){c.run(a,b,function(a){b.performanceTimer&&(axe.utils.performanceTimer.mark(d),axe.utils.performanceTimer.measure(\"rule_\"+c.id,f,d)),e(a)},function(a){if(b.debug)g(a);else{var d=Object.assign(new p(c),{result:axe.constants.CANTTELL,description:\"An error occured while running this rule\",message:a.message,stack:a.stack,error:a});e(d)}})})}}),e.then(function(a){c(a.filter(function(a){return!!a}))}).catch(d)},e.prototype.after=function(a,b){\"use strict\";var c=this.rules;return a.map(function(a){return axe.utils.findBy(c,\"id\",a.id).after(a,b)})},e.prototype.getRule=function(a){return this.rules.find(function(b){return b.id===a})},e.prototype.validateOptions=function(a){\"use strict\";var b=this;if(\"object\"===ha(a.runOnly)){var c=a.runOnly;if(\"rule\"===c.type&&Array.isArray(c.value))c.value.forEach(function(a){if(!b.getRule(a))throw new Error(\"unknown rule `\"+a+\"` in options.runOnly\")});else if(Array.isArray(c.value)&&c.value.length>0){var d=[].concat(c.value);if(b.rules.forEach(function(a){var b,c,e;if(d)for(c=0,e=a.tags.length;c<e;c++)-1!==(b=d.indexOf(a.tags[c]))&&d.splice(b,1)}),0!==d.length)throw new Error(\"could not find tags `\"+d.join(\"`, `\")+\"`\")}}return\"object\"===ha(a.rules)&&Object.keys(a.rules).forEach(function(a){if(!b.getRule(a))throw new Error(\"unknown rule `\"+a+\"` in options.rules\")}),a},e.prototype.setBranding=function(a){\"use strict\";var b={brand:this.brand,application:this.application};a&&a.hasOwnProperty(\"brand\")&&a.brand&&\"string\"==typeof a.brand&&(this.brand=a.brand),a&&a.hasOwnProperty(\"application\")&&a.application&&\"string\"==typeof a.application&&(this.application=a.application),this._constructHelpUrls(b)},e.prototype._constructHelpUrls=function(){var a=this,b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,c=(axe.version.match(/^[1-9][0-9]*\\.[0-9]+/)||[\"x.y\"])[0];this.rules.forEach(function(d){a.data.rules[d.id]||(a.data.rules[d.id]={});var e=a.data.rules[d.id];(\"string\"!=typeof e.helpUrl||b&&e.helpUrl===f(b,d.id,c))&&(e.helpUrl=f(a,d.id,c))})},e.prototype.resetRulesAndChecks=function(){\"use strict\";this._init()},i.prototype.enabled=!0,i.prototype.run=function(a,b,c,d){\"use strict\";b=b||{};var e=b.hasOwnProperty(\"enabled\")?b.enabled:this.enabled,f=b.options||this.options;if(e){var h,i=new g(this),j=axe.utils.checkHelper(i,b,c,d);try{h=this.evaluate.call(j,a,f)}catch(a){return void d(a)}j.isAsync||(i.result=h,setTimeout(function(){c(i)},0))}else c(null)},i.prototype.configure=function(a){var b=this;[\"options\",\"enabled\"].filter(function(b){return a.hasOwnProperty(b)}).forEach(function(c){return b[c]=a[c]}),[\"evaluate\",\"after\"].filter(function(b){return a.hasOwnProperty(b)}).forEach(function(c){return b[c]=h(a[c])})};var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};q.prototype.matches=function(){\"use strict\";return!0},q.prototype.gather=function(a){\"use strict\";var b=axe.utils.select(this.selector,a);return this.excludeHidden?b.filter(function(a){return!axe.utils.isHidden(a)}):b},q.prototype.runChecks=function(a,b,c,d,e){\"use strict\";var f=this,g=axe.utils.queue();this[a].forEach(function(a){var d=f._audit.checks[a.id||a],e=axe.utils.getCheckOption(d,f.id,c);g.defer(function(a,c){d.run(b,e,a,c)})}),g.then(function(b){b=b.filter(function(a){return a}),d({type:a,results:b})}).catch(e)},q.prototype.run=function(a,c,d,e){var f=this,g=axe.utils.queue(),h=new p(this),i=void 0;try{i=this.gather(a).filter(function(a){return f.matches(a)})}catch(a){return void e(new b({cause:a,ruleId:this.id}))}c.performanceTimer&&axe.log(\"gather (\",i.length,\"):\",axe.utils.performanceTimer.timeElapsed()+\"ms\"),i.forEach(function(a){g.defer(function(b,d){var e=axe.utils.queue();e.defer(function(b,d){f.runChecks(\"any\",a,c,b,d)}),e.defer(function(b,d){f.runChecks(\"all\",a,c,b,d)}),e.defer(function(b,d){f.runChecks(\"none\",a,c,b,d)}),e.then(function(d){if(d.length){var e=!1,f={};d.forEach(function(a){var b=a.results.filter(function(a){return a});f[a.type]=b,b.length&&(e=!0)}),e&&(f.node=new axe.utils.DqElement(a,c),h.nodes.push(f))}b()}).catch(function(a){return d(a)})})}),g.then(function(){return d(h)}).catch(function(a){return e(a)})},q.prototype.after=function(a,b){\"use strict\";var c=r(this),d=this.id;return c.forEach(function(c){var e=s(a.nodes,c.id),f=axe.utils.getCheckOption(c,d,b),g=c.after(e,f);e.forEach(function(a){-1===g.indexOf(a)&&(a.filtered=!0)})}),a.nodes=u(a),a},q.prototype.configure=function(a){\"use strict\";a.hasOwnProperty(\"selector\")&&(this.selector=a.selector),a.hasOwnProperty(\"excludeHidden\")&&(this.excludeHidden=\"boolean\"!=typeof a.excludeHidden||a.excludeHidden),a.hasOwnProperty(\"enabled\")&&(this.enabled=\"boolean\"!=typeof a.enabled||a.enabled),a.hasOwnProperty(\"pageLevel\")&&(this.pageLevel=\"boolean\"==typeof a.pageLevel&&a.pageLevel),a.hasOwnProperty(\"any\")&&(this.any=a.any),a.hasOwnProperty(\"all\")&&(this.all=a.all),a.hasOwnProperty(\"none\")&&(this.none=a.none),a.hasOwnProperty(\"tags\")&&(this.tags=a.tags),a.hasOwnProperty(\"matches\")&&(\"string\"==typeof a.matches?this.matches=new Function(\"return \"+a.matches+\";\")():this.matches=a.matches)},function(axe){var a=[{name:\"NA\",value:\"inapplicable\",priority:0,group:\"inapplicable\"},{name:\"PASS\",value:\"passed\",priority:1,group:\"passes\"},{name:\"CANTTELL\",value:\"cantTell\",priority:2,group:\"incomplete\"},{name:\"FAIL\",value:\"failed\",priority:3,group:\"violations\"}],b={helpUrlBase:\"https://dequeuniversity.com/rules/\",results:[],resultGroups:[],resultGroupMap:{},impact:Object.freeze([\"minor\",\"moderate\",\"serious\",\"critical\"])};a.forEach(function(a){var c=a.name,d=a.value,e=a.priority,f=a.group;b[c]=d,b[c+\"_PRIO\"]=e,b[c+\"_GROUP\"]=f,b.results[e]=d,b.resultGroups[e]=f,b.resultGroupMap[d]=f}),Object.freeze(b.results),Object.freeze(b.resultGroups),Object.freeze(b.resultGroupMap),Object.freeze(b),Object.defineProperty(axe,\"constants\",{value:b,enumerable:!0,configurable:!1,writable:!1})}(axe);var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};axe.log=function(){\"use strict\";\"object\"===(\"undefined\"==typeof console?\"undefined\":ha(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)};var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};axe.a11yCheck=function(a,b,c){\"use strict\";\"function\"==typeof b&&(c=b,b={}),b&&\"object\"===(void 0===b?\"undefined\":ha(b))||(b={});var d=axe._audit;if(!d)throw new Error(\"No audit configured\");b.reporter=b.reporter||d.reporter||\"v2\",b.performanceTimer&&axe.utils.performanceTimer.start();var e=axe.getReporter(b.reporter);axe._runRules(a,b,function(a){var d=e(a,b,c);void 0!==d&&(b.performanceTimer&&axe.utils.performanceTimer.end(),c(d))},axe.log)},axe.cleanup=v,axe.configure=w,axe.getRules=function(a){\"use strict\";a=a||[];var b=a.length?axe._audit.rules.filter(function(b){return!!a.filter(function(a){return-1!==b.tags.indexOf(a)}).length}):axe._audit.rules,c=axe._audit.data.rules||{};return b.map(function(a){var b=c[a.id]||{};return{ruleId:a.id,description:b.description,help:b.help,helpUrl:b.helpUrl,tags:a.tags}})},axe._load=function(a){\"use strict\";axe.utils.respondable.subscribe(\"axe.ping\",function(a,b,c){c({axe:!0})}),axe.utils.respondable.subscribe(\"axe.start\",x),axe._audit=new e(a)};var axe=axe||{};axe.plugins={},y.prototype.run=function(){\"use strict\";return this._run.apply(this,arguments)},y.prototype.collect=function(){\"use strict\";return this._collect.apply(this,arguments)},y.prototype.cleanup=function(a){\"use strict\";var b=axe.utils.queue(),c=this;Object.keys(this._registry).forEach(function(a){b.defer(function(b){c._registry[a].cleanup(b)})}),b.then(function(){a()})},y.prototype.add=function(a){\"use strict\";this._registry[a.id]=a},axe.registerPlugin=function(a){\"use strict\";axe.plugins[a.id]=new y(a)};var ja,ka={};axe.getReporter=function(a){\"use strict\";return\"string\"==typeof a&&ka[a]?ka[a]:\"function\"==typeof a?a:ja},axe.addReporter=function(a,b,c){\"use strict\";ka[a]=b,c&&(ja=b)},axe.reset=z,axe._runRules=A;var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a},la=function(){};axe.run=function(a,b,c){\"use strict\";if(!axe._audit)throw new Error(\"No audit configured\");var d=C(a,b,c);a=d.context,b=d.options,c=d.callback,b.reporter=b.reporter||axe._audit.reporter||\"v1\",b.performanceTimer&&axe.utils.performanceTimer.start();var e=void 0,f=la,g=la;return window.Promise&&c===la&&(e=new Promise(function(a,b){f=b,g=a})),axe._runRules(a,b,function(a){var d=function(a){try{c(null,a)}catch(a){axe.log(a)}g(a)};b.performanceTimer&&axe.utils.performanceTimer.end();try{var e=axe.getReporter(b.reporter),h=e(a,b,d);void 0!==h&&d(h)}catch(a){c(a),f(a)}},function(a){c(a),f(a)}),e},ia.failureSummary=function(a){\"use strict\";var b={};return b.none=a.none.concat(a.all),b.any=a.any,Object.keys(b).map(function(a){if(b[a].length){var c=axe._audit.data.failureSummaries[a];return c&&\"function\"==typeof c.failureMessage?c.failureMessage(b[a].map(function(a){return a.message||\"\"})):void 0}}).filter(function(a){return void 0!==a}).join(\"\\n\\n\")},ia.incompleteFallbackMessage=function(){\"use strict\";return axe._audit.data.incompleteFallbackMessage()};var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a},ma=axe.constants.resultGroups;ia.processAggregate=function(a,b){var c=axe.utils.aggregateResult(a);return c.timestamp=(new Date).toISOString(),c.url=window.location.href,ma.forEach(function(a){b.resultTypes&&!b.resultTypes.includes(a)&&(c[a]||[]).forEach(function(a){Array.isArray(a.nodes)&&a.nodes.length>0&&(a.nodes=[a.nodes[0]])}),c[a]=(c[a]||[]).map(function(a){return a=Object.assign({},a),Array.isArray(a.nodes)&&a.nodes.length>0&&(a.nodes=a.nodes.map(function(a){return\"object\"===ha(a.node)&&(a.html=a.node.source,b.elementRef&&!a.node.fromFrame&&(a.element=a.node.element),(!1!==b.selectors||a.node.fromFrame)&&(a.target=a.node.selector),b.xpath&&(a.xpath=a.node.xpath)),delete a.result,delete a.node,D(a,b),a})),ma.forEach(function(b){return delete a[b]}),delete a.pageLevel,delete a.result,a})}),c},axe.addReporter(\"na\",function(a,b,c){\"use strict\";\"function\"==typeof b&&(c=b,b={});var d=ia.processAggregate(a,b);c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})}),axe.addReporter(\"no-passes\",function(a,b,c){\"use strict\";\"function\"==typeof b&&(c=b,b={}),b.resultTypes=[\"violations\"];var d=ia.processAggregate(a,b);c({violations:d.violations,timestamp:d.timestamp,url:d.url})}),axe.addReporter(\"raw\",function(a,b,c){\"use strict\";\"function\"==typeof b&&(c=b,b={}),c(a)}),axe.addReporter(\"v1\",function(a,b,c){\"use strict\";\"function\"==typeof b&&(c=b,b={});var d=ia.processAggregate(a,b);d.violations.forEach(function(a){return a.nodes.forEach(function(a){a.failureSummary=ia.failureSummary(a)})}),c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})}),axe.addReporter(\"v2\",function(a,b,c){\"use strict\";\"function\"==typeof b&&(c=b,b={});var d=ia.processAggregate(a,b);c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})},!0),axe.utils.aggregate=function(a,b,c){b=b.slice(),c&&b.push(c);var d=b.map(function(b){return a.indexOf(b)}).sort();return a[d.pop()]};var na=axe.constants,oa=na.CANTTELL_PRIO,pa=na.FAIL_PRIO,qa=[];qa[axe.constants.PASS_PRIO]=!0,qa[axe.constants.CANTTELL_PRIO]=null,qa[axe.constants.FAIL_PRIO]=!1;var ra=[\"any\",\"all\",\"none\"];axe.utils.aggregateChecks=function(a){var b=Object.assign({},a);E(b,function(a,b){var c=qa.indexOf(a.result);a.priority=-1!==c?c:axe.constants.CANTTELL_PRIO,\"none\"===b&&(a.priority=4-a.priority)});var c={all:b.all.reduce(function(a,b){return Math.max(a,b.priority)},0),none:b.none.reduce(function(a,b){return Math.max(a,b.priority)},0),any:b.any.reduce(function(a,b){return Math.min(a,b.priority)},4)%4};b.priority=Math.max(c.all,c.none,c.any);var d=[];return ra.forEach(function(a){b[a]=b[a].filter(function(d){return d.priority===b.priority&&d.priority===c[a]}),b[a].forEach(function(a){return d.push(a.impact)})}),[oa,pa].includes(b.priority)?b.impact=axe.utils.aggregate(axe.constants.impact,d):b.impact=null,E(b,function(a){delete a.result,delete a.priority}),b.result=axe.constants.results[b.priority],delete b.priority,b},function(){axe.utils.aggregateNodeResults=function(a){var b={};if((a=a.map(function(a){if(a.any&&a.all&&a.none)return axe.utils.aggregateChecks(a);if(Array.isArray(a.node))return axe.utils.finalizeRuleResult(a);throw new TypeError(\"Invalid Result type\")}))&&a.length){var c=a.map(function(a){return a.result});b.result=axe.utils.aggregate(axe.constants.results,c,b.result)}else b.result=\"inapplicable\";axe.constants.resultGroups.forEach(function(a){return b[a]=[]}),a.forEach(function(a){var c=axe.constants.resultGroupMap[a.result];b[c].push(a)});var d=axe.constants.FAIL_GROUP;if(0===b[d].length&&(d=axe.constants.CANTTELL_GROUP),b[d].length>0){var e=b[d].map(function(a){return a.impact});b.impact=axe.utils.aggregate(axe.constants.impact,e)||null}else b.impact=null;return b}}(),axe.utils.aggregateResult=function(a){var b={};return axe.constants.resultGroups.forEach(function(a){return b[a]=[]}),a.forEach(function(a){a.error?F(b,a,axe.constants.CANTTELL_GROUP):a.result===axe.constants.NA?F(b,a,axe.constants.NA_GROUP):axe.constants.resultGroups.forEach(function(c){Array.isArray(a[c])&&a[c].length>0&&F(b,a,c)})}),b},axe.utils.areStylesSet=G,axe.utils.checkHelper=function(a,b,c,d){\"use strict\";return{isAsync:!1,async:function(){return this.isAsync=!0,function(b){b instanceof Error==!1?(a.result=b,c(a)):d(b)}},data:function(b){a.data=b},relatedNodes:function(c){c=c instanceof Node?[c]:axe.utils.toArray(c),a.relatedNodes=c.map(function(a){return new axe.utils.DqElement(a,b)})}}};var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};axe.utils.clone=function(a){\"use strict\";var b,c,d=a\n;if(null!==a&&\"object\"===(void 0===a?\"undefined\":ha(a)))if(Array.isArray(a))for(d=[],b=0,c=a.length;b<c;b++)d[b]=axe.utils.clone(a[b]);else{d={};for(b in a)d[b]=axe.utils.clone(a[b])}return d},axe.utils.sendCommandToFrame=function(a,b,c,d){\"use strict\";var e=a.contentWindow;if(!e)return axe.log(\"Frame does not have a content window\",a),void c(null);var f=setTimeout(function(){f=setTimeout(function(){var e=H(\"No response from frame\",a);b.debug?d(e):(axe.log(e),c(null))},0)},500);axe.utils.respondable(e,\"axe.ping\",null,void 0,function(){clearTimeout(f),f=setTimeout(function(){d(H(\"Axe in frame timed out\",a))},3e4),axe.utils.respondable(e,\"axe.start\",b,void 0,function(a){clearTimeout(f),a instanceof Error==!1?c(a):d(a)})})},axe.utils.collectResultsFromFrames=I,axe.utils.contains=function(a,b){\"use strict\";return\"function\"==typeof a.contains?a.contains(b):!!(16&a.compareDocumentPosition(b))},L.prototype={get selector(){return this.spec.selector||[axe.utils.getSelector(this.element,this._options)]},get xpath(){return this.spec.xpath||[axe.utils.getXpath(this.element)]},get element(){return this._element},get fromFrame(){return this._fromFrame},toJSON:function(){\"use strict\";return{selector:this.selector,source:this.source,xpath:this.xpath}}},L.fromFrame=function(a,b,c){return a.selector.unshift(c.selector),a.xpath.unshift(c.xpath),new axe.utils.DqElement(c.element,b,a)},axe.utils.DqElement=L,axe.utils.matchesSelector=function(){\"use strict\";function a(a){var b,c,d=a.Element.prototype,e=[\"matches\",\"matchesSelector\",\"mozMatchesSelector\",\"webkitMatchesSelector\",\"msMatchesSelector\"],f=e.length;for(b=0;b<f;b++)if(c=e[b],d[c])return c}var b;return function(c,d){return b&&c[b]||(b=a(c.ownerDocument.defaultView)),c[b](d)}}(),axe.utils.escapeSelector=function(a){\"use strict\";for(var b,c=String(a),d=c.length,e=-1,f=\"\",g=c.charCodeAt(0);++e<d;){if(0==(b=c.charCodeAt(e)))throw new Error(\"INVALID_CHARACTER_ERR\");b>=1&&b<=31||b>=127&&b<=159||0==e&&b>=48&&b<=57||1==e&&b>=48&&b<=57&&45==g?f+=\"\\\\\"+b.toString(16)+\" \":f+=(1!=e||45!=b||45!=g)&&(b>=128||45==b||95==b||b>=48&&b<=57||b>=65&&b<=90||b>=97&&b<=122)?c.charAt(e):\"\\\\\"+c.charAt(e)}return f},axe.utils.extendMetaData=function(a,b){Object.assign(a,b),Object.keys(b).filter(function(a){return\"function\"==typeof b[a]}).forEach(function(c){a[c]=null;try{a[c]=b[c](a)}catch(a){}})},axe.utils.finalizeRuleResult=function(a){return Object.assign(a,axe.utils.aggregateNodeResults(a.nodes)),delete a.nodes,a};var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};axe.utils.findBy=function(a,b,c){if(Array.isArray(a))return a.find(function(a){return\"object\"===(void 0===a?\"undefined\":ha(a))&&a[b]===c})},axe.utils.getAllChecks=function(a){\"use strict\";return[].concat(a.any||[]).concat(a.all||[]).concat(a.none||[])},axe.utils.getCheckOption=function(a,b,c){var d=((c.rules&&c.rules[b]||{}).checks||{})[a.id],e=(c.checks||{})[a.id],f=a.enabled,g=a.options;return e&&(e.hasOwnProperty(\"enabled\")&&(f=e.enabled),e.hasOwnProperty(\"options\")&&(g=e.options)),d&&(d.hasOwnProperty(\"enabled\")&&(f=d.enabled),d.hasOwnProperty(\"options\")&&(g=d.options)),{enabled:f,options:g,absolutePaths:c.absolutePaths}};var sa=function(){function a(a,b){var c=[],d=!0,e=!1,f=void 0;try{for(var g,h=a[Symbol.iterator]();!(d=(g=h.next()).done)&&(c.push(g.value),!b||c.length!==b);d=!0);}catch(a){e=!0,f=a}finally{try{!d&&h.return&&h.return()}finally{if(e)throw f}}return c}return function(b,c){if(Array.isArray(b))return b;if(Symbol.iterator in Object(b))return a(b,c);throw new TypeError(\"Invalid attempt to destructure non-iterable instance\")}}();axe.utils.getFriendlyUriEnd=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:\"\",b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!(a.length<=1||\"data:\"===a.substr(0,5)||\"javascript:\"===a.substr(0,11)||a.includes(\"?\"))){var c=b.currentDomain,d=b.maxLength,e=void 0===d?25:d,f=O(a),g=f.path,h=f.domain,i=f.hash,j=g.substr(g.substr(0,g.length-2).lastIndexOf(\"/\")+1);if(i)return j&&(j+i).length<=e?j+i:j.length<2&&i.length>2&&i.length<=e?i:void 0;if(h&&h.length<e&&g.length<=1)return h+g;if(g===\"/\"+j&&h&&c&&h!==c&&(h+g).length<=e)return h+g;var k=j.lastIndexOf(\".\");return(-1===k||k>1)&&(-1!==k||j.length>2)&&j.length<=e&&!j.match(/index(\\.[a-zA-Z]{2-4})?/)&&!M(j)?j:void 0}};var ta=axe.utils.escapeSelector,ua=void 0,va=[\"div\",\"span\",\"p\",\"b\",\"i\",\"u\",\"strong\",\"em\",\"h2\",\"h3\"],wa={getElmId:function(a){if(a.getAttribute(\"id\")){var b=\"#\"+ta(a.getAttribute(\"id\")||\"\");return b.match(/player_uid_/)||1!==document.querySelectorAll(b).length?void 0:b}},getCustomElm:function(a,b){var c=b.isCustomElm,d=b.nodeName;if(c)return d},getElmRoleProp:function(a){if(a.hasAttribute(\"role\"))return'[role=\"'+ta(a.getAttribute(\"role\"))+'\"]'},getUncommonElm:function(a,b){var c=b.isCommonElm,d=b.isCustomElm,e=b.nodeName;if(!c&&!d)return\"input\"===e&&a.hasAttribute(\"type\")&&(e+='[type=\"'+a.type+'\"]'),e},getElmNameProp:function(a){if(!a.hasAttribute(\"id\")&&a.name)return'[name=\"'+ta(a.name)+'\"]'},getDistinctClass:function(a,b){var c=b.distinctClassList;if(c.length>0&&c.length<3)return\".\"+c.map(ta).join(\".\")},getFileRefProp:function(a){var b=void 0;if(a.hasAttribute(\"href\"))b=\"href\";else{if(!a.hasAttribute(\"src\"))return;b=\"src\"}var c=axe.utils.getFriendlyUriEnd(a.getAttribute(b));if(c)return\"[\"+b+'$=\"'+encodeURI(c)+'\"]'},getCommonName:function(a,b){var c=b.nodeName;if(b.isCommonElm)return c}};axe.utils.getSelector=function a(b){var c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!b)return\"\";var d=void 0,e=void 0,f=c.isUnique,g=void 0!==f&&f,h=wa.getElmId(b),i=c.featureCount,j=void 0===i?2:i,k=c.minDepth,l=void 0===k?1:k,m=c.toRoot,n=void 0!==m&&m,o=c.childSelectors,p=void 0===o?[]:o;h?(d=h,g=!0):(d=T(b,j).join(\"\"),d+=S(b,d),g=c.isUnique||1===document.querySelectorAll(d).length,g||b!==document.documentElement||(d+=\":root\"),e=0!==l||!g);var q=[d].concat(P(p));return b.parentElement&&(n||e)?a(b.parentNode,{toRoot:n,isUnique:g,childSelectors:q,featureCount:1,minDepth:l-1}):q.join(\" > \")},axe.utils.getXpath=function(a){return V(U(a))};var xa;axe.utils.injectStyle=W,axe.utils.isHidden=function(a,b){\"use strict\";if(9===a.nodeType)return!1;var c=window.getComputedStyle(a,null);return!c||!a.parentNode||\"none\"===c.getPropertyValue(\"display\")||!b&&\"hidden\"===c.getPropertyValue(\"visibility\")||\"true\"===a.getAttribute(\"aria-hidden\")||axe.utils.isHidden(a.parentNode,!0)},axe.utils.isXHTML=function(a){\"use strict\";return!!a.createElement&&\"A\"===a.createElement(\"A\").localName},axe.utils.mergeResults=function(a,b){\"use strict\";var c=[];return a.forEach(function(a){var d=Z(a);d&&d.length&&d.forEach(function(d){d.nodes&&a.frame&&X(d.nodes,b,a.frameElement,a.frame);var e=axe.utils.findBy(c,\"id\",d.id);e?d.nodes.length&&Y(e.nodes,d.nodes):c.push(d)})}),c},axe.utils.nodeSorter=function(a,b){\"use strict\";return a===b?0:4&a.compareDocumentPosition(b)?-1:1},utils.performanceTimer=function(){\"use strict\";function a(){if(window.performance&&window.performance)return window.performance.now()}var b=null,c=a();return{start:function(){this.mark(\"mark_axe_start\")},end:function(){this.mark(\"mark_axe_end\"),this.measure(\"axe\",\"mark_axe_start\",\"mark_axe_end\"),this.logMeasures(\"axe\")},auditStart:function(){this.mark(\"mark_audit_start\")},auditEnd:function(){this.mark(\"mark_audit_end\"),this.measure(\"audit_start_to_end\",\"mark_audit_start\",\"mark_audit_end\"),this.logMeasures()},mark:function(a){window.performance&&void 0!==window.performance.mark&&window.performance.mark(a)},measure:function(a,b,c){window.performance&&void 0!==window.performance.measure&&window.performance.measure(a,b,c)},logMeasures:function(a){function b(a){axe.log(\"Measure \"+a.name+\" took \"+a.duration+\"ms\")}if(window.performance&&void 0!==window.performance.getEntriesByType)for(var c=window.performance.getEntriesByType(\"measure\"),d=0;d<c.length;++d){var e=c[d];if(e.name===a)return void b(e);b(e)}},timeElapsed:function(){return a()-c},reset:function(){b||(b=a()),c=a()}}}(),\"function\"!=typeof Object.assign&&function(){Object.assign=function(a){\"use strict\";if(void 0===a||null===a)throw new TypeError(\"Cannot convert undefined or null to object\");for(var b=Object(a),c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d)for(var e in d)d.hasOwnProperty(e)&&(b[e]=d[e])}return b}}(),Array.prototype.find||Object.defineProperty(Array.prototype,\"find\",{value:function(a){if(null===this)throw new TypeError(\"Array.prototype.find called on null or undefined\");if(\"function\"!=typeof a)throw new TypeError(\"predicate must be a function\");for(var b,c=Object(this),d=c.length>>>0,e=arguments[1],f=0;f<d;f++)if(b=c[f],a.call(e,b,f,c))return b}}),axe.utils.pollyfillElementsFromPoint=function(){if(document.elementsFromPoint)return document.elementsFromPoint;if(document.msElementsFromPoint)return document.msElementsFromPoint;var a=function(){var a=document.createElement(\"x\");return a.style.cssText=\"pointer-events:auto\",\"auto\"===a.style.pointerEvents}(),b=a?\"pointer-events\":\"visibility\",c=a?\"none\":\"hidden\",d=document.createElement(\"style\");return d.innerHTML=a?\"* { pointer-events: all }\":\"* { visibility: visible }\",function(a,e){var f,g,h,i=[],j=[];for(document.head.appendChild(d);(f=document.elementFromPoint(a,e))&&-1===i.indexOf(f);)i.push(f),j.push({value:f.style.getPropertyValue(b),priority:f.style.getPropertyPriority(b)}),f.style.setProperty(b,c,\"important\");for(g=j.length;h=j[--g];)i[g].style.setProperty(b,h.value?h.value:\"\",h.priority);return document.head.removeChild(d),i}},\"function\"==typeof window.addEventListener&&(document.elementsFromPoint=axe.utils.pollyfillElementsFromPoint()),Array.prototype.includes||Object.defineProperty(Array.prototype,\"includes\",{value:function(a){\"use strict\";var b=Object(this),c=parseInt(b.length,10)||0;if(0===c)return!1;var d,e=parseInt(arguments[1],10)||0;e>=0?d=e:(d=c+e)<0&&(d=0);for(var f;d<c;){if(f=b[d],a===f||a!==a&&f!==f)return!0;d++}return!1}}),Array.prototype.some||Object.defineProperty(Array.prototype,\"some\",{value:function(a){\"use strict\";if(null==this)throw new TypeError(\"Array.prototype.some called on null or undefined\");if(\"function\"!=typeof a)throw new TypeError;for(var b=Object(this),c=b.length>>>0,d=arguments.length>=2?arguments[1]:void 0,e=0;e<c;e++)if(e in b&&a.call(d,b[e],e,b))return!0;return!1}}),Array.from||Object.defineProperty(Array,\"from\",{value:function(){var a=Object.prototype.toString,b=function(b){return\"function\"==typeof b||\"[object Function]\"===a.call(b)},c=function(a){var b=Number(a);return isNaN(b)?0:0!==b&&isFinite(b)?(b>0?1:-1)*Math.floor(Math.abs(b)):b},d=Math.pow(2,53)-1,e=function(a){var b=c(a);return Math.min(Math.max(b,0),d)};return function(a){var c=this,d=Object(a);if(null==a)throw new TypeError(\"Array.from requires an array-like object - not null or undefined\");var f,g=arguments.length>1?arguments[1]:void 0;if(void 0!==g){if(!b(g))throw new TypeError(\"Array.from: when provided, the second argument must be a function\");arguments.length>2&&(f=arguments[2])}for(var h,i=e(d.length),j=b(c)?Object(new c(i)):new Array(i),k=0;k<i;)h=d[k],j[k]=g?void 0===f?g(h,k):g.call(f,h,k):h,k+=1;return j.length=i,j}}()}),String.prototype.includes||(String.prototype.includes=function(a,b){return\"number\"!=typeof b&&(b=0),!(b+a.length>this.length)&&-1!==this.indexOf(a,b)});var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};axe.utils.publishMetaData=function(a){\"use strict\";var b=axe._audit.data.checks||{},c=axe._audit.data.rules||{},d=axe.utils.findBy(axe._audit.rules,\"id\",a.id)||{};a.tags=axe.utils.clone(d.tags||[]);var e=_(b,!0),f=_(b,!1);a.nodes.forEach(function(a){a.any.forEach(e),a.all.forEach(e),a.none.forEach(f)}),axe.utils.extendMetaData(a,axe.utils.clone(c[a.id]||{}))};var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};!function(){\"use strict\";function a(){}function b(a){if(\"function\"!=typeof a)throw new TypeError(\"Queue methods require functions as arguments\")}function c(){function c(b){return function(c){g[b]=c,(i-=1)||j===a||(k=!0,j(g))}}function d(b){return j=a,m(b),g}function e(){for(var a=g.length;h<a;h++){var b=g[h];try{b.call(null,c(h),d)}catch(a){d(a)}}}var f,g=[],h=0,i=0,j=a,k=!1,l=function(a){f=a,setTimeout(function(){void 0!==f&&null!==f&&axe.log(\"Uncaught error (of queue)\",f)},1)},m=l,n={defer:function(a){if(\"object\"===(void 0===a?\"undefined\":ha(a))&&a.then&&a.catch){var c=a;a=function(a,b){c.then(a).catch(b)}}if(b(a),void 0===f){if(k)throw new Error(\"Queue already completed\");return g.push(a),++i,e(),n}},then:function(c){if(b(c),j!==a)throw new Error(\"queue `then` already set\");return f||(j=c,i||(k=!0,j(g))),n},catch:function(a){if(b(a),m!==l)throw new Error(\"queue `catch` already set\");return f?(a(f),f=null):m=a,n},abort:d};return n}axe.utils.queue=c}();var ha=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&\"function\"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?\"symbol\":typeof a};!function(a){\"use strict\";function b(){var a=\"axe\",b=\"\";return void 0!==axe&&axe._audit&&!axe._audit.application&&(a=axe._audit.application),void 0!==axe&&(b=axe.version),a+\".\"+b}function c(a){if(\"object\"===(void 0===a?\"undefined\":ha(a))&&\"string\"==typeof a.uuid&&!0===a._respondable){var c=b();return a._source===c||\"axe.x.y.z\"===a._source||\"axe.x.y.z\"===c}return!1}function d(a,c,d,e,f,g){var h;d instanceof Error&&(h={name:d.name,message:d.message,stack:d.stack},d=void 0);var i={uuid:e,topic:c,message:d,error:h,_respondable:!0,_source:b(),_keepalive:f};\"function\"==typeof g&&(j[e]=g),a.postMessage(JSON.stringify(i),\"*\")}function e(a,b,c,e,f){d(a,b,c,ya.v1(),e,f)}function f(a,b,c){return function(e,f,g){d(a,b,e,c,f,g)}}function g(a,b,c){var d=b.topic,e=k[d];if(e){var g=f(a,null,b.uuid);e(b.message,c,g)}}function h(a){var b=a.message||\"Unknown error occurred\",c=l.includes(a.name)?a.name:\"Error\",d=window[c]||Error;return a.stack&&(b+=\"\\n\"+a.stack.replace(a.message,\"\")),new d(b)}function i(a){var b;if(\"string\"==typeof a){try{b=JSON.parse(a)}catch(a){}if(c(b))return\"object\"===ha(b.error)?b.error=h(b.error):b.error=void 0,b}}var j={},k={},l=Object.freeze([\"EvalError\",\"RangeError\",\"ReferenceError\",\"SyntaxError\",\"TypeError\",\"URIError\"]);e.subscribe=function(a,b){k[a]=b},e.isInFrame=function(a){return a=a||window,!!a.frameElement},\"function\"==typeof window.addEventListener&&window.addEventListener(\"message\",function(a){var b=i(a.data);if(b){var c=b.uuid,e=b._keepalive,h=j[c];if(h){h(b.error||b.message,e,f(a.source,b.topic,c)),e||delete j[c]}if(!b.error)try{g(a.source,b,e)}catch(e){d(a.source,b.topic,e,c,!1)}}},!1),a.respondable=e}(utils),axe.utils.ruleShouldRun=function(a,b,c){\"use strict\";var d=c.runOnly||{},e=(c.rules||{})[a.id];return!(a.pageLevel&&!b.page)&&(\"rule\"===d.type?-1!==d.values.indexOf(a.id):e&&\"boolean\"==typeof e.enabled?e.enabled:\"tag\"===d.type&&d.values?aa(a,d.values):aa(a,[]))},axe.utils.getScrollState=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window,b=a.document.documentElement;return[void 0!==a.pageXOffset?{elm:a,top:a.pageYOffset,left:a.pageXOffset}:{elm:b,top:b.scrollTop,left:b.scrollLeft}].concat(da(document.body))},axe.utils.setScrollState=function(a){a.forEach(function(a){return ca(a.elm,a.top,a.left)})},axe.utils.select=function(a,b){\"use strict\";for(var c,d=[],e=0,f=b.include.length;e<f;e++)c=b.include[e],c.nodeType===c.ELEMENT_NODE&&axe.utils.matchesSelector(c,a)&&ga(d,[c],b),ga(d,c.querySelectorAll(a),b);return d.sort(axe.utils.nodeSorter)},axe.utils.toArray=function(a){\"use strict\";return Array.prototype.slice.call(a)};var ya;!function(a){function b(a,b,c){var d=b&&c||0,e=0;for(b=b||[],a.toLowerCase().replace(/[0-9a-f]{2}/g,function(a){e<16&&(b[d+e++]=l[a])});e<16;)b[d+e++]=0;return b}function c(a,b){var c=b||0,d=k;return d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+\"-\"+d[a[c++]]+d[a[c++]]+\"-\"+d[a[c++]]+d[a[c++]]+\"-\"+d[a[c++]]+d[a[c++]]+\"-\"+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]}function d(a,b,d){var e=b&&d||0,f=b||[];a=a||{};var g=null!=a.clockseq?a.clockseq:p,h=null!=a.msecs?a.msecs:(new Date).getTime(),i=null!=a.nsecs?a.nsecs:r+1,j=h-q+(i-r)/1e4;if(j<0&&null==a.clockseq&&(g=g+1&16383),(j<0||h>q)&&null==a.nsecs&&(i=0),i>=1e4)throw new Error(\"uuid.v1(): Can't create more than 10M uuids/sec\");q=h,r=i,p=g,h+=122192928e5;var k=(1e4*(268435455&h)+i)%4294967296;f[e++]=k>>>24&255,f[e++]=k>>>16&255,f[e++]=k>>>8&255,f[e++]=255&k;var l=h/4294967296*1e4&268435455;f[e++]=l>>>8&255,f[e++]=255&l,f[e++]=l>>>24&15|16,f[e++]=l>>>16&255,f[e++]=g>>>8|128,f[e++]=255&g;for(var m=a.node||o,n=0;n<6;n++)f[e+n]=m[n];return b||c(f)}function e(a,b,d){var e=b&&d||0;\"string\"==typeof a&&(b=\"binary\"==a?new j(16):null,a=null),a=a||{};var g=a.random||(a.rng||f)();if(g[6]=15&g[6]|64,g[8]=63&g[8]|128,b)for(var h=0;h<16;h++)b[e+h]=g[h];return b||c(g)}var f,g=a.crypto||a.msCrypto;if(!f&&g&&g.getRandomValues){var h=new Uint8Array(16);f=function(){return g.getRandomValues(h),h}}if(!f){var i=new Array(16);f=function(){for(var a,b=0;b<16;b++)0==(3&b)&&(a=4294967296*Math.random()),i[b]=a>>>((3&b)<<3)&255;return i}}for(var j=\"function\"==typeof a.Buffer?a.Buffer:Array,k=[],l={},m=0;m<256;m++)k[m]=(m+256).toString(16).substr(1),l[k[m]]=m;var n=f(),o=[1|n[0],n[1],n[2],n[3],n[4],n[5]],p=16383&(n[6]<<8|n[7]),q=0,r=0;ya=e,ya.v1=d,ya.v4=e,ya.parse=b,ya.unparse=c,ya.BufferClass=j}(window),axe._load({data:{rules:{accesskeys:{description:\"Ensures every accesskey attribute value is unique\",help:\"accesskey attribute value must be unique\"},\"area-alt\":{description:\"Ensures <area> elements of image maps have alternate text\",help:\"Active <area> elements must have alternate text\"},\"aria-allowed-attr\":{description:\"Ensures ARIA attributes are allowed for an element's role\",help:\"Elements must only use allowed ARIA attributes\"},\"aria-hidden-body\":{description:\"Ensures aria-hidden='true' is not present on the document body.\",help:\"aria-hidden='true' must not be present on the document body\"},\"aria-required-attr\":{description:\"Ensures elements with ARIA roles have all required ARIA attributes\",help:\"Required ARIA attributes must be provided\"},\"aria-required-children\":{description:\"Ensures elements with an ARIA role that require child roles contain them\",help:\"Certain ARIA roles must contain particular children\"},\"aria-required-parent\":{description:\"Ensures elements with an ARIA role that require parent roles are contained by them\",help:\"Certain ARIA roles must be contained by particular parents\"},\"aria-roles\":{description:\"Ensures all elements with a role attribute use a valid value\",help:\"ARIA roles used must conform to valid values\"},\"aria-valid-attr-value\":{description:\"Ensures all ARIA attributes have valid values\",help:\"ARIA attributes must conform to valid values\"},\"aria-valid-attr\":{description:\"Ensures attributes that begin with aria- are valid ARIA attributes\",help:\"ARIA attributes must conform to valid names\"},\"audio-caption\":{description:\"Ensures <audio> elements have captions\",help:\"<audio> elements must have a captions track\"},blink:{description:\"Ensures <blink> elements are not used\",help:\"<blink> elements are deprecated and must not be used\"},\"button-name\":{description:\"Ensures buttons have discernible text\",help:\"Buttons must have discernible text\"},bypass:{description:\"Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content\",help:\"Page must have means to bypass repeated blocks\"},checkboxgroup:{description:'Ensures related <input type=\"checkbox\"> elements have a group and that that group designation is consistent',help:\"Checkbox inputs with the same name attribute value must be part of a group\"},\"color-contrast\":{description:\"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds\",help:\"Elements must have sufficient color contrast\"},\"definition-list\":{description:\"Ensures <dl> elements are structured correctly\",help:\"<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements\"},dlitem:{description:\"Ensures <dt> and <dd> elements are contained by a <dl>\",help:\"<dt> and <dd> elements must be contained by a <dl>\"},\"document-title\":{description:\"Ensures each HTML document contains a non-empty <title> element\",help:\"Documents must have <title> element to aid in navigation\"},\"duplicate-id\":{description:\"Ensures every id attribute value is unique\",help:\"id attribute value must be unique\"},\"empty-heading\":{description:\"Ensures headings have discernible text\",help:\"Headings must not be empty\"},\"frame-title-unique\":{description:\"Ensures <iframe> and <frame> elements contain a unique title attribute\",help:\"Frames must have a unique title attribute\"},\"frame-title\":{description:\"Ensures <iframe> and <frame> elements contain a non-empty title attribute\",help:\"Frames must have title attribute\"},\"heading-order\":{description:\"Ensures the order of headings is semantically correct\",help:\"Heading levels should only increase by one\"},\"hidden-content\":{description:\"Informs users about hidden content.\",help:\"Hidden content on the page cannot be analyzed\"},\"href-no-hash\":{description:\"Ensures that href values are valid link references to promote only using anchors as links\",help:\"Anchors must only be used as links with valid URLs or URL fragments\"},\"html-has-lang\":{description:\"Ensures every HTML document has a lang attribute\",help:\"<html> element must have a lang attribute\"},\"html-lang-valid\":{description:\"Ensures the lang attribute of the <html> element has a valid value\",help:\"<html> element must have a valid value for the lang attribute\"},\"image-alt\":{description:\"Ensures <img> elements have alternate text or a role of none or presentation\",help:\"Images must have alternate text\"},\"image-redundant-alt\":{description:\"Ensure button and link text is not repeated as image alternative\",help:\"Text of buttons and links should not be repeated in the image alternative\"},\"input-image-alt\":{description:'Ensures <input type=\"image\"> elements have alternate text',help:\"Image buttons must have alternate text\"},\"label-title-only\":{description:\"Ensures that every form element is not solely labeled using the title or aria-describedby attributes\",help:\"Form elements should have a visible label\"},label:{description:\"Ensures every form element has a label\",help:\"Form elements must have labels\"},\"landmark-main-is-top-level\":{description:\"The main landmark should not be contained in another landmark\",help:\"Main landmark is not at top level\"},\"landmark-one-main\":{description:\"Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one.\",help:\"Page must contain one main landmark.\"},\"layout-table\":{description:\"Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute\",help:\"Layout tables must not use data table elements\"},\"link-in-text-block\":{description:\"Links can be distinguished without relying on color\",help:\"Links must be distinguished from surrounding text in a way that does not rely on color\"},\"link-name\":{description:\"Ensures links have discernible text\",help:\"Links must have discernible text\"},list:{description:\"Ensures that lists are structured correctly\",help:\"<ul> and <ol> must only directly contain <li>, <script> or <template> elements\"},listitem:{description:\"Ensures <li> elements are used semantically\",help:\"<li> elements must be contained in a <ul> or <ol>\"},marquee:{description:\"Ensures <marquee> elements are not used\",help:\"<marquee> elements are deprecated and must not be used\"},\"meta-refresh\":{description:'Ensures <meta http-equiv=\"refresh\"> is not used',help:\"Timed refresh must not exist\"},\"meta-viewport-large\":{description:'Ensures <meta name=\"viewport\"> can scale a significant amount',help:\"Users should be able to zoom and scale the text up to 500%\"},\"meta-viewport\":{description:'Ensures <meta name=\"viewport\"> does not disable text scaling and zooming',help:\"Zooming and scaling must not be disabled\"},\"object-alt\":{description:\"Ensures <object> elements have alternate text\",help:\"<object> elements must have alternate text\"},\"p-as-heading\":{description:\"Ensure p elements are not used to style headings\",help:\"Bold, italic text and font-size are not used to style p elements as a heading\"},radiogroup:{description:'Ensures related <input type=\"radio\"> elements have a group and that the group designation is consistent',help:\"Radio inputs with the same name attribute value must be part of a group\"},region:{description:\"Ensures all content is contained within a landmark region\",help:\"Content should be contained in a landmark region\"},\"scope-attr-valid\":{description:\"Ensures the scope attribute is used correctly on tables\",help:\"scope attribute should be used correctly\"},\"server-side-image-map\":{description:\"Ensures that server-side image maps are not used\",help:\"Server-side image maps must not be used\"},\"skip-link\":{description:\"Ensures the first link on the page is a skip link\",help:\"The page should have a skip link as its first link\"},tabindex:{description:\"Ensures tabindex attribute values are not greater than 0\",help:\"Elements should not have tabindex greater than zero\"},\"table-duplicate-name\":{description:\"Ensure that tables do not have the same summary and caption\",help:\"The <caption> element should not contain the same text as the summary attribute\"},\"table-fake-caption\":{description:\"Ensure that tables with a caption use the <caption> element.\",help:\"Data or header cells should not be used to give caption to a data table.\"},\"td-has-header\":{description:\"Ensure that each non-empty data cell in a large table has one or more table headers\",help:\"All non-empty td element in table larger than 3 by 3 must have an associated table header\"},\"td-headers-attr\":{description:\"Ensure that each cell in a table using the headers refers to another cell in that table\",help:\"All cells in a table element that use the headers attribute must only refer to other cells of that same table\"},\"th-has-data-cells\":{description:\"Ensure that each table header in a data table refers to data cells\",help:\"All th elements and elements with role=columnheader/rowheader must have data cells they describe\"},\"valid-lang\":{description:\"Ensures lang attributes have valid values\",help:\"lang attribute must have a valid value\"},\"video-caption\":{description:\"Ensures <video> elements have captions\",help:\"<video> elements must have captions\"},\"video-description\":{description:\"Ensures <video> elements have audio descriptions\",help:\"<video> elements must have an audio description track\"}},checks:{accesskeys:{impact:\"serious\",messages:{pass:function(a){return\"Accesskey attribute value is unique\"},fail:function(a){return\"Document has multiple elements with the same accesskey\"}}},\"non-empty-alt\":{impact:\"critical\",messages:{pass:function(a){return\"Element has a non-empty alt attribute\"},fail:function(a){return\"Element has no alt attribute or the alt attribute is empty\"}}},\"non-empty-title\":{impact:\"serious\",messages:{pass:function(a){return\"Element has a title attribute\"},fail:function(a){return\"Element has no title attribute or the title attribute is empty\"}}},\"aria-label\":{impact:\"serious\",messages:{pass:function(a){return\"aria-label attribute exists and is not empty\"},fail:function(a){return\"aria-label attribute does not exist or is empty\"}}},\"aria-labelledby\":{impact:\"serious\",messages:{pass:function(a){return\"aria-labelledby attribute exists and references elements that are visible to screen readers\"},fail:function(a){return\"aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible\"}}},\"aria-allowed-attr\":{impact:\"critical\",messages:{pass:function(a){return\"ARIA attributes are used correctly for the defined role\"},fail:function(a){var b=\"ARIA attribute\"+(a.data&&a.data.length>1?\"s are\":\" is\")+\" not allowed:\",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" \"+d;return b}}},\"aria-hidden-body\":{impact:\"critical\",messages:{pass:function(a){return\"No aria-hidden attribute is present on document body\"},fail:function(a){return\"aria-hidden=true should not be present on the document body\"}}},\"aria-required-attr\":{impact:\"critical\",messages:{pass:function(a){return\"All required ARIA attributes are present\"},fail:function(a){var b=\"Required ARIA attribute\"+(a.data&&a.data.length>1?\"s\":\"\")+\" not present:\",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" \"+d;return b}}},\"aria-required-children\":{impact:\"critical\",messages:{pass:function(a){return\"Required ARIA children are present\"},fail:function(a){var b=\"Required ARIA \"+(a.data&&a.data.length>1?\"children\":\"child\")+\" role not present:\",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" \"+d;return b}}},\"aria-required-parent\":{impact:\"critical\",messages:{pass:function(a){return\"Required ARIA parent role present\"},fail:function(a){var b=\"Required ARIA parent\"+(a.data&&a.data.length>1?\"s\":\"\")+\" role not present:\",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" \"+d;return b}}},invalidrole:{impact:\"critical\",messages:{pass:function(a){return\"ARIA role is valid\"},fail:function(a){return\"Role must be one of the valid ARIA roles\"}}},abstractrole:{impact:\"serious\",messages:{pass:function(a){return\"Abstract roles are not used\"},fail:function(a){return\"Abstract roles cannot be directly used\"}}},\"aria-valid-attr-value\":{impact:\"critical\",messages:{pass:function(a){return\"ARIA attribute values are valid\"},fail:function(a){var b=\"Invalid ARIA attribute value\"+(a.data&&a.data.length>1?\"s\":\"\")+\":\",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" \"+d;return b}}},\"aria-errormessage\":{impact:\"critical\",messages:{pass:function(a){return\"Uses a supported aria-errormessage technique\"},fail:function(a){var b=\"aria-errormessage value\"+(a.data&&a.data.length>1?\"s\":\"\")+\" \",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" `\"+d;return b+=\"` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)\"}}},\"aria-valid-attr\":{impact:\"critical\",messages:{pass:function(a){return\"ARIA attribute name\"+(a.data&&a.data.length>1?\"s\":\"\")+\" are valid\"},fail:function(a){var b=\"Invalid ARIA attribute name\"+(a.data&&a.data.length>1?\"s\":\"\")+\":\",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\" \"+d;return b}}},caption:{impact:\"critical\",messages:{pass:function(a){return\"The multimedia element has a captions track\"},fail:function(a){return\"The multimedia element does not have a captions track\"},incomplete:function(a){return\"A captions track for this element could not be found\"}}},\"is-on-screen\":{impact:\"serious\",messages:{pass:function(a){return\"Element is not visible\"},fail:function(a){return\"Element is visible\"}}},\"non-empty-if-present\":{impact:\"critical\",messages:{pass:function(a){var b=\"Element \";return a.data?b+=\"has a non-empty value attribute\":b+=\"does not have a value attribute\",b},fail:function(a){return\"Element has a value attribute and the value attribute is empty\"}}},\"non-empty-value\":{impact:\"critical\",messages:{pass:function(a){return\"Element has a non-empty value attribute\"},fail:function(a){return\"Element has no value attribute or the value attribute is empty\"}}},\"button-has-visible-text\":{impact:\"critical\",messages:{pass:function(a){return\"Element has inner text that is visible to screen readers\"},fail:function(a){return\"Element does not have inner text that is visible to screen readers\"}}},\n\"role-presentation\":{impact:\"minor\",messages:{pass:function(a){return'Element\\'s default semantics were overriden with role=\"presentation\"'},fail:function(a){return'Element\\'s default semantics were not overridden with role=\"presentation\"'}}},\"role-none\":{impact:\"minor\",messages:{pass:function(a){return'Element\\'s default semantics were overriden with role=\"none\"'},fail:function(a){return'Element\\'s default semantics were not overridden with role=\"none\"'}}},\"focusable-no-name\":{impact:\"serious\",messages:{pass:function(a){return\"Element is not in tab order or has accessible text\"},fail:function(a){return\"Element is in tab order and does not have accessible text\"}}},\"internal-link-present\":{impact:\"serious\",messages:{pass:function(a){return\"Valid skip link found\"},fail:function(a){return\"No valid skip link found\"}}},\"header-present\":{impact:\"serious\",messages:{pass:function(a){return\"Page has a header\"},fail:function(a){return\"Page does not have a header\"}}},landmark:{impact:\"serious\",messages:{pass:function(a){return\"Page has a landmark region\"},fail:function(a){return\"Page does not have a landmark region\"}}},\"group-labelledby\":{impact:\"critical\",messages:{pass:function(a){return'All elements with the name \"'+a.data.name+'\" reference the same element with aria-labelledby'},fail:function(a){return'All elements with the name \"'+a.data.name+'\" do not reference the same element with aria-labelledby'}}},fieldset:{impact:\"critical\",messages:{pass:function(a){return\"Element is contained in a fieldset\"},fail:function(a){var b=\"\",c=a.data&&a.data.failureCode;return b+=\"no-legend\"===c?\"Fieldset does not have a legend as its first child\":\"empty-legend\"===c?\"Legend does not have text that is visible to screen readers\":\"mixed-inputs\"===c?\"Fieldset contains unrelated inputs\":\"no-group-label\"===c?\"ARIA group does not have aria-label or aria-labelledby\":\"group-mixed-inputs\"===c?\"ARIA group contains unrelated inputs\":\"Element does not have a containing fieldset or ARIA group\"}}},\"color-contrast\":{impact:\"serious\",messages:{pass:function(a){return\"Element has sufficient color contrast of \"+a.data.contrastRatio},fail:function(a){return\"Element has insufficient color contrast of \"+a.data.contrastRatio+\" (foreground color: \"+a.data.fgColor+\", background color: \"+a.data.bgColor+\", font size: \"+a.data.fontSize+\", font weight: \"+a.data.fontWeight+\"). Expected contrast ratio of \"+a.data.expectedContrastRatio},incomplete:{bgImage:\"Element's background color could not be determined due to a background image\",bgGradient:\"Element's background color could not be determined due to a background gradient\",imgNode:\"Element's background color could not be determined because element contains an image node\",bgOverlap:\"Element's background color could not be determined because it is overlapped by another element\",fgAlpha:\"Element's foreground color could not be determined because of alpha transparency\",elmPartiallyObscured:\"Element's background color could not be determined because it's partially obscured by another element\",elmPartiallyObscuring:\"Element's background color could not be determined because it partially overlaps other elements\",outsideViewport:\"Element's background color could not be determined because it's outside the viewport\",equalRatio:\"Element has a 1:1 contrast ratio with the background\",default:\"Unable to determine contrast ratio\"}}},\"structured-dlitems\":{impact:\"serious\",messages:{pass:function(a){return\"When not empty, element has both <dt> and <dd> elements\"},fail:function(a){return\"When not empty, element does not have at least one <dt> element followed by at least one <dd> element\"}}},\"only-dlitems\":{impact:\"serious\",messages:{pass:function(a){return\"List element only has direct children that are allowed inside <dt> or <dd> elements\"},fail:function(a){return\"List element has direct children that are not allowed inside <dt> or <dd> elements\"}}},dlitem:{impact:\"serious\",messages:{pass:function(a){return\"Description list item has a <dl> parent element\"},fail:function(a){return\"Description list item does not have a <dl> parent element\"}}},\"doc-has-title\":{impact:\"serious\",messages:{pass:function(a){return\"Document has a non-empty <title> element\"},fail:function(a){return\"Document does not have a non-empty <title> element\"}}},\"duplicate-id\":{impact:\"moderate\",messages:{pass:function(a){return\"Document has no elements that share the same id attribute\"},fail:function(a){return\"Document has multiple elements with the same id attribute: \"+a.data}}},\"has-visible-text\":{impact:\"minor\",messages:{pass:function(a){return\"Element has text that is visible to screen readers\"},fail:function(a){return\"Element does not have text that is visible to screen readers\"}}},\"unique-frame-title\":{impact:\"serious\",messages:{pass:function(a){return\"Element's title attribute is unique\"},fail:function(a){return\"Element's title attribute is not unique\"}}},\"heading-order\":{impact:\"moderate\",messages:{pass:function(a){return\"Heading order valid\"},fail:function(a){return\"Heading order invalid\"}}},\"hidden-content\":{impact:\"minor\",messages:{pass:function(a){return\"All content on the page has been analyzed.\"},fail:function(a){return\"There were problems analyzing the content on this page.\"},incomplete:function(a){return\"There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it.\"}}},\"href-no-hash\":{impact:\"moderate\",messages:{pass:function(a){return\"Anchor does not have an href value of #\"},fail:function(a){return\"Anchor has an href value of #\"}}},\"has-lang\":{impact:\"serious\",messages:{pass:function(a){return\"The <html> element has a lang attribute\"},fail:function(a){return\"The <html> element does not have a lang attribute\"}}},\"valid-lang\":{impact:\"serious\",messages:{pass:function(a){return\"Value of lang attribute is included in the list of valid languages\"},fail:function(a){return\"Value of lang attribute not included in the list of valid languages\"}}},\"has-alt\":{impact:\"critical\",messages:{pass:function(a){return\"Element has an alt attribute\"},fail:function(a){return\"Element does not have an alt attribute\"}}},\"duplicate-img-label\":{impact:\"minor\",messages:{pass:function(a){return\"Element does not duplicate existing text in <img> alt text\"},fail:function(a){return\"Element contains <img> element with alt text that duplicates existing text\"}}},\"title-only\":{impact:\"serious\",messages:{pass:function(a){return\"Form element does not solely use title attribute for its label\"},fail:function(a){return\"Only title used to generate label for form element\"}}},\"implicit-label\":{impact:\"critical\",messages:{pass:function(a){return\"Form element has an implicit (wrapped) <label>\"},fail:function(a){return\"Form element does not have an implicit (wrapped) <label>\"}}},\"explicit-label\":{impact:\"critical\",messages:{pass:function(a){return\"Form element has an explicit <label>\"},fail:function(a){return\"Form element does not have an explicit <label>\"}}},\"help-same-as-label\":{impact:\"minor\",messages:{pass:function(a){return\"Help text (title or aria-describedby) does not duplicate label text\"},fail:function(a){return\"Help text (title or aria-describedby) text is the same as the label text\"}}},\"multiple-label\":{impact:\"serious\",messages:{pass:function(a){return\"Form element does not have multiple <label> elements\"},fail:function(a){return\"Form element has multiple <label> elements\"}}},\"main-is-top-level\":{impact:\"moderate\",messages:{pass:function(a){return\"The main landmark is at the top level.\"},fail:function(a){return\"The main landmark is contained in another landmark.\"}}},\"has-at-least-one-main\":{impact:\"moderate\",messages:{pass:function(a){return\"Document has at least one main landmark\"},fail:function(a){return\"Document has no main landmarks\"}}},\"has-no-more-than-one-main\":{impact:\"moderate\",messages:{pass:function(a){return\"Document has no more than one main landmark\"},fail:function(a){return\"Document has more than one main landmark\"}}},\"has-th\":{impact:\"serious\",messages:{pass:function(a){return\"Layout table does not use <th> elements\"},fail:function(a){return\"Layout table uses <th> elements\"}}},\"has-caption\":{impact:\"serious\",messages:{pass:function(a){return\"Layout table does not use <caption> element\"},fail:function(a){return\"Layout table uses <caption> element\"}}},\"has-summary\":{impact:\"serious\",messages:{pass:function(a){return\"Layout table does not use summary attribute\"},fail:function(a){return\"Layout table uses summary attribute\"}}},\"link-in-text-block\":{impact:\"serious\",messages:{pass:function(a){return\"Links can be distinguished from surrounding text in a way that does not rely on color\"},fail:function(a){return\"Links can not be distinguished from surrounding text in a way that does not rely on color\"},incomplete:{bgContrast:\"Element's contrast ratio could not be determined. Check for a distinct hover/focus style\",bgImage:\"Element's contrast ratio could not be determined due to a background image\",bgGradient:\"Element's contrast ratio could not be determined due to a background gradient\",imgNode:\"Element's contrast ratio could not be determined because element contains an image node\",bgOverlap:\"Element's contrast ratio could not be determined because of element overlap\",default:\"Unable to determine contrast ratio\"}}},\"only-listitems\":{impact:\"serious\",messages:{pass:function(a){return\"List element only has direct children that are allowed inside <li> elements\"},fail:function(a){return\"List element has direct children that are not allowed inside <li> elements\"}}},listitem:{impact:\"serious\",messages:{pass:function(a){return'List item has a <ul>, <ol> or role=\"list\" parent element'},fail:function(a){return'List item does not have a <ul>, <ol> or role=\"list\" parent element'}}},\"meta-refresh\":{impact:\"critical\",messages:{pass:function(a){return\"<meta> tag does not immediately refresh the page\"},fail:function(a){return\"<meta> tag forces timed refresh of page\"}}},\"meta-viewport-large\":{impact:\"minor\",messages:{pass:function(a){return\"<meta> tag does not prevent significant zooming on mobile devices\"},fail:function(a){return\"<meta> tag limits zooming on mobile devices\"}}},\"meta-viewport\":{impact:\"critical\",messages:{pass:function(a){return\"<meta> tag does not disable zooming on mobile devices\"},fail:function(a){return\"<meta> tag disables zooming on mobile devices\"}}},\"p-as-heading\":{impact:\"serious\",messages:{pass:function(a){return\"<p> elements are not styled as headings\"},fail:function(a){return\"Heading elements should be used instead of styled p elements\"}}},region:{impact:\"moderate\",messages:{pass:function(a){return\"Content contained by ARIA landmark\"},fail:function(a){return\"Content not contained by an ARIA landmark\"}}},\"html5-scope\":{impact:\"moderate\",messages:{pass:function(a){return\"Scope attribute is only used on table header elements (<th>)\"},fail:function(a){return\"In HTML 5, scope attributes may only be used on table header elements (<th>)\"}}},\"scope-value\":{impact:\"critical\",messages:{pass:function(a){return\"Scope attribute is used correctly\"},fail:function(a){return\"The value of the scope attribute may only be 'row' or 'col'\"}}},exists:{impact:\"minor\",messages:{pass:function(a){return\"Element does not exist\"},fail:function(a){return\"Element exists\"}}},\"skip-link\":{impact:\"moderate\",messages:{pass:function(a){return\"Valid skip link found\"},fail:function(a){return\"No valid skip link found\"}}},tabindex:{impact:\"serious\",messages:{pass:function(a){return\"Element does not have a tabindex greater than 0\"},fail:function(a){return\"Element has a tabindex greater than 0\"}}},\"same-caption-summary\":{impact:\"minor\",messages:{pass:function(a){return\"Content of summary attribute and <caption> are not duplicated\"},fail:function(a){return\"Content of summary attribute and <caption> element are identical\"}}},\"caption-faked\":{impact:\"serious\",messages:{pass:function(a){return\"The first row of a table is not used as a caption\"},fail:function(a){return\"The first row of the table should be a caption instead of a table cell\"}}},\"td-has-header\":{impact:\"critical\",messages:{pass:function(a){return\"All non-empty data cells have table headers\"},fail:function(a){return\"Some non-empty data cells do not have table headers\"}}},\"td-headers-attr\":{impact:\"serious\",messages:{pass:function(a){return\"The headers attribute is exclusively used to refer to other cells in the table\"},fail:function(a){return\"The headers attribute is not exclusively used to refer to other cells in the table\"}}},\"th-has-data-cells\":{impact:\"serious\",messages:{pass:function(a){return\"All table header cells refer to data cells\"},fail:function(a){return\"Not all table header cells refer to data cells\"},incomplete:function(a){return\"Table data cells are missing or empty\"}}},description:{impact:\"critical\",messages:{pass:function(a){return\"The multimedia element has an audio description track\"},fail:function(a){return\"The multimedia element does not have an audio description track\"},incomplete:function(a){return\"An audio description track for this element could not be found\"}}}},failureSummaries:{any:{failureMessage:function(a){var b=\"Fix any of the following:\",c=a;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\"\\n  \"+d.split(\"\\n\").join(\"\\n  \");return b}},none:{failureMessage:function(a){var b=\"Fix all of the following:\",c=a;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=\"\\n  \"+d.split(\"\\n\").join(\"\\n  \");return b}}},incompleteFallbackMessage:function(a){return\"aXe couldn't tell the reason. Time to break out the element inspector!\"}},rules:[{id:\"accesskeys\",selector:\"[accesskey]\",excludeHidden:!1,tags:[\"wcag2a\",\"wcag211\",\"cat.keyboard\"],all:[],any:[],none:[\"accesskeys\"]},{id:\"area-alt\",selector:\"map area[href]\",excludeHidden:!1,tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag111\",\"section508\",\"section508.22.a\"],all:[],any:[\"non-empty-alt\",\"non-empty-title\",\"aria-label\",\"aria-labelledby\"],none:[]},{id:\"aria-allowed-attr\",matches:function(a){var b=a.getAttribute(\"role\");b||(b=axe.commons.aria.implicitRole(a));var c=axe.commons.aria.allowedAttr(b);if(b&&c){var d=/^aria-/;if(a.hasAttributes())for(var e=a.attributes,f=0,g=e.length;f<g;f++)if(d.test(e[f].name))return!0}return!1},tags:[\"cat.aria\",\"wcag2a\",\"wcag411\",\"wcag412\"],all:[],any:[\"aria-allowed-attr\"],none:[]},{id:\"aria-hidden-body\",selector:\"body\",excludeHidden:!1,tags:[\"cat.aria\",\"wcag2a\",\"wcag412\"],all:[],any:[\"aria-hidden-body\"],none:[]},{id:\"aria-required-attr\",selector:\"[role]\",tags:[\"cat.aria\",\"wcag2a\",\"wcag411\",\"wcag412\"],all:[],any:[\"aria-required-attr\"],none:[]},{id:\"aria-required-children\",selector:\"[role]\",tags:[\"cat.aria\",\"wcag2a\",\"wcag131\"],all:[],any:[\"aria-required-children\"],none:[]},{id:\"aria-required-parent\",selector:\"[role]\",tags:[\"cat.aria\",\"wcag2a\",\"wcag131\"],all:[],any:[\"aria-required-parent\"],none:[]},{id:\"aria-roles\",selector:\"[role]\",tags:[\"cat.aria\",\"wcag2a\",\"wcag131\",\"wcag411\",\"wcag412\"],all:[],any:[],none:[\"invalidrole\",\"abstractrole\"]},{id:\"aria-valid-attr-value\",matches:function(a){var b=/^aria-/;if(a.hasAttributes())for(var c=a.attributes,d=0,e=c.length;d<e;d++)if(b.test(c[d].name))return!0;return!1},tags:[\"cat.aria\",\"wcag2a\",\"wcag131\",\"wcag411\",\"wcag412\"],all:[{options:[],id:\"aria-valid-attr-value\"},\"aria-errormessage\"],any:[],none:[]},{id:\"aria-valid-attr\",matches:function(a){var b=/^aria-/;if(a.hasAttributes())for(var c=a.attributes,d=0,e=c.length;d<e;d++)if(b.test(c[d].name))return!0;return!1},tags:[\"cat.aria\",\"wcag2a\",\"wcag411\"],all:[],any:[{options:[],id:\"aria-valid-attr\"}],none:[]},{id:\"audio-caption\",selector:\"audio\",excludeHidden:!1,tags:[\"cat.time-and-media\",\"wcag2a\",\"wcag122\",\"section508\",\"section508.22.a\"],all:[],any:[],none:[\"caption\"]},{id:\"blink\",selector:\"blink\",excludeHidden:!1,tags:[\"cat.time-and-media\",\"wcag2a\",\"wcag222\",\"section508\",\"section508.22.j\"],all:[],any:[],none:[\"is-on-screen\"]},{id:\"button-name\",selector:'button, [role=\"button\"], input[type=\"button\"], input[type=\"submit\"], input[type=\"reset\"]',tags:[\"cat.name-role-value\",\"wcag2a\",\"wcag412\",\"section508\",\"section508.22.a\"],all:[],any:[\"non-empty-if-present\",\"non-empty-value\",\"button-has-visible-text\",\"aria-label\",\"aria-labelledby\",\"role-presentation\",\"role-none\"],none:[\"focusable-no-name\"]},{id:\"bypass\",selector:\"html\",pageLevel:!0,matches:function(a){return!!a.querySelector(\"a[href]\")},tags:[\"cat.keyboard\",\"wcag2a\",\"wcag241\",\"section508\",\"section508.22.o\"],all:[],any:[\"internal-link-present\",\"header-present\",\"landmark\"],none:[]},{id:\"checkboxgroup\",selector:\"input[type=checkbox][name]\",tags:[\"cat.forms\",\"best-practice\"],all:[],any:[\"group-labelledby\",\"fieldset\"],none:[]},{id:\"color-contrast\",matches:function(a){var b=a.nodeName.toUpperCase(),c=a.type,d=document;if(\"true\"===a.getAttribute(\"aria-disabled\")||axe.commons.dom.findUp(a,'[aria-disabled=\"true\"]'))return!1;if(\"INPUT\"===b)return-1===[\"hidden\",\"range\",\"color\",\"checkbox\",\"radio\",\"image\"].indexOf(c)&&!a.disabled;if(\"SELECT\"===b)return!!a.options.length&&!a.disabled;if(\"TEXTAREA\"===b)return!a.disabled;if(\"OPTION\"===b)return!1;if(\"BUTTON\"===b&&a.disabled||axe.commons.dom.findUp(a,\"button[disabled]\"))return!1;if(\"FIELDSET\"===b&&a.disabled||axe.commons.dom.findUp(a,\"fieldset[disabled]\"))return!1;var e=axe.commons.dom.findUp(a,\"label\");if(\"LABEL\"===b||e){var f=a;e&&(f=e);var g=f.htmlFor&&d.getElementById(f.htmlFor);if(g&&g.disabled)return!1;var g=f.querySelector('input:not([type=\"hidden\"]):not([type=\"image\"]):not([type=\"button\"]):not([type=\"submit\"]):not([type=\"reset\"]), select, textarea');if(g&&g.disabled)return!1}if(a.getAttribute(\"id\")){var h=axe.commons.utils.escapeSelector(a.getAttribute(\"id\")),i=d.querySelector('[aria-labelledby~=\"'+h+'\"]');if(i&&i.hasAttribute(\"disabled\"))return!1}if(\"\"===axe.commons.text.visible(a,!1,!0))return!1;var j,k,l=document.createRange(),m=a.childNodes,n=m.length;for(k=0;k<n;k++)j=m[k],3===j.nodeType&&\"\"!==axe.commons.text.sanitize(j.nodeValue)&&l.selectNodeContents(j);var o=l.getClientRects();for(n=o.length,k=0;k<n;k++)if(axe.commons.dom.visuallyOverlaps(o[k],a))return!0;return!1},excludeHidden:!1,options:{noScroll:!1},tags:[\"cat.color\",\"wcag2aa\",\"wcag143\"],all:[],any:[\"color-contrast\"],none:[]},{id:\"definition-list\",selector:\"dl:not([role])\",tags:[\"cat.structure\",\"wcag2a\",\"wcag131\"],all:[],any:[],none:[\"structured-dlitems\",\"only-dlitems\"]},{id:\"dlitem\",selector:\"dd:not([role]), dt:not([role])\",tags:[\"cat.structure\",\"wcag2a\",\"wcag131\"],all:[],any:[\"dlitem\"],none:[]},{id:\"document-title\",selector:\"html\",matches:function(a){return a.ownerDocument.defaultView.self===a.ownerDocument.defaultView.top},tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag242\"],all:[],any:[\"doc-has-title\"],none:[]},{id:\"duplicate-id\",selector:\"[id]\",excludeHidden:!1,tags:[\"cat.parsing\",\"wcag2a\",\"wcag411\"],all:[],any:[\"duplicate-id\"],none:[]},{id:\"empty-heading\",selector:'h1, h2, h3, h4, h5, h6, [role=\"heading\"]',enabled:!0,tags:[\"cat.name-role-value\",\"best-practice\"],all:[],any:[\"has-visible-text\",\"role-presentation\",\"role-none\"],none:[]},{id:\"frame-title-unique\",selector:\"frame[title]:not([title='']), iframe[title]:not([title=''])\",matches:function(a){var b=a.getAttribute(\"title\");return!!(b?axe.commons.text.sanitize(b).trim():\"\")},tags:[\"cat.text-alternatives\",\"best-practice\"],all:[],any:[],none:[\"unique-frame-title\"]},{id:\"frame-title\",selector:\"frame, iframe\",tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag241\",\"section508\",\"section508.22.i\"],all:[],any:[\"aria-label\",\"aria-labelledby\",\"non-empty-title\",\"role-presentation\",\"role-none\"],none:[]},{id:\"heading-order\",selector:\"h1,h2,h3,h4,h5,h6,[role=heading]\",enabled:!1,tags:[\"cat.semantics\",\"best-practice\"],all:[],any:[\"heading-order\"],none:[]},{id:\"hidden-content\",selector:\"*\",excludeHidden:!1,tags:[\"experimental\",\"review-item\"],all:[],any:[\"hidden-content\"],none:[],enabled:!1},{id:\"href-no-hash\",selector:\"a[href]\",enabled:!1,tags:[\"cat.semantics\",\"best-practice\"],all:[],any:[\"href-no-hash\"],none:[]},{id:\"html-has-lang\",selector:\"html\",tags:[\"cat.language\",\"wcag2a\",\"wcag311\"],all:[],any:[\"has-lang\"],none:[]},{id:\"html-lang-valid\",selector:\"html[lang]\",tags:[\"cat.language\",\"wcag2a\",\"wcag311\"],all:[],any:[],none:[\"valid-lang\"]},{id:\"image-alt\",selector:\"img, [role='img']\",tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag111\",\"section508\",\"section508.22.a\"],all:[],any:[\"has-alt\",\"aria-label\",\"aria-labelledby\",\"non-empty-title\",\"role-presentation\",\"role-none\"],none:[]},{id:\"image-redundant-alt\",selector:'button, [role=\"button\"], a[href], p, li, td, th',tags:[\"cat.text-alternatives\",\"best-practice\"],all:[],any:[],none:[\"duplicate-img-label\"]},{id:\"input-image-alt\",selector:'input[type=\"image\"]',tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag111\",\"section508\",\"section508.22.a\"],all:[],any:[\"non-empty-alt\",\"aria-label\",\"aria-labelledby\",\"non-empty-title\"],none:[]},{id:\"label-title-only\",selector:\"input:not([type='hidden']):not([type='image']):not([type='button']):not([type='submit']):not([type='reset']), select, textarea\",enabled:!1,tags:[\"cat.forms\",\"best-practice\"],all:[],any:[],none:[\"title-only\"]},{id:\"label\",selector:\"input:not([type='hidden']):not([type='image']):not([type='button']):not([type='submit']):not([type='reset']), select, textarea\",tags:[\"cat.forms\",\"wcag2a\",\"wcag332\",\"wcag131\",\"section508\",\"section508.22.n\"],all:[],any:[\"aria-label\",\"aria-labelledby\",\"implicit-label\",\"explicit-label\",\"non-empty-title\"],none:[\"help-same-as-label\",\"multiple-label\"]},{id:\"landmark-main-is-top-level\",selector:\"main,[role=main]\",tags:[\"best-practice\"],all:[],any:[\"main-is-top-level\"],none:[]},{id:\"landmark-one-main\",selector:\"html\",tags:[\"best-practice\"],all:[\"has-at-least-one-main\",\"has-no-more-than-one-main\"],any:[],none:[]},{id:\"layout-table\",selector:\"table\",matches:function(a){return!axe.commons.table.isDataTable(a)},tags:[\"cat.semantics\",\"wcag2a\",\"wcag131\"],all:[],any:[],none:[\"has-th\",\"has-caption\",\"has-summary\"]},{id:\"link-in-text-block\",selector:\"a[href]:not([role]), *[role=link]\",matches:function(a){return!!axe.commons.text.sanitize(a.textContent)&&!!axe.commons.dom.isVisible(a,!1)&&axe.commons.dom.isInTextBlock(a)},excludeHidden:!1,tags:[\"cat.color\",\"experimental\",\"wcag2a\",\"wcag141\"],all:[\"link-in-text-block\"],any:[],none:[]},{id:\"link-name\",selector:'a[href]:not([role=\"button\"]), [role=link][href]',tags:[\"cat.name-role-value\",\"wcag2a\",\"wcag111\",\"wcag412\",\"wcag244\",\"section508\",\"section508.22.a\"],all:[],any:[\"has-visible-text\",\"aria-label\",\"aria-labelledby\",\"role-presentation\",\"role-none\"],none:[\"focusable-no-name\"]},{id:\"list\",selector:\"ul:not([role]), ol:not([role])\",tags:[\"cat.structure\",\"wcag2a\",\"wcag131\"],all:[],any:[],none:[\"only-listitems\"]},{id:\"listitem\",selector:\"li:not([role])\",tags:[\"cat.structure\",\"wcag2a\",\"wcag131\"],all:[],any:[\"listitem\"],none:[]},{id:\"marquee\",selector:\"marquee\",excludeHidden:!1,tags:[\"cat.parsing\",\"wcag2a\",\"wcag222\"],all:[],any:[],none:[\"is-on-screen\"]},{id:\"meta-refresh\",selector:'meta[http-equiv=\"refresh\"]',excludeHidden:!1,tags:[\"cat.time\",\"wcag2a\",\"wcag2aaa\",\"wcag221\",\"wcag224\",\"wcag325\"],all:[],any:[\"meta-refresh\"],none:[]},{id:\"meta-viewport-large\",selector:'meta[name=\"viewport\"]',excludeHidden:!1,tags:[\"cat.sensory-and-visual-cues\",\"best-practice\"],all:[],any:[{options:{scaleMinimum:5,lowerBound:2},id:\"meta-viewport-large\"}],none:[]},{id:\"meta-viewport\",selector:'meta[name=\"viewport\"]',excludeHidden:!1,tags:[\"cat.sensory-and-visual-cues\",\"wcag2aa\",\"wcag144\"],all:[],any:[{options:{scaleMinimum:2},id:\"meta-viewport\"}],none:[]},{id:\"object-alt\",selector:\"object\",tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag111\",\"section508\",\"section508.22.a\"],all:[],any:[\"has-visible-text\",\"aria-label\",\"aria-labelledby\",\"non-empty-title\"],none:[]},{id:\"p-as-heading\",selector:\"p\",matches:function(a){var b=Array.from(a.parentNode.childNodes),c=a.textContent.trim(),d=/[.!?:;](?![.!?:;])/g;return!(0===c.length||(c.match(d)||[]).length>=2)&&0!==b.slice(b.indexOf(a)+1).filter(function(a){return\"P\"===a.nodeName.toUpperCase()&&\"\"!==a.textContent.trim()}).length},tags:[\"cat.semantics\",\"wcag2a\",\"wcag131\",\"experimental\"],all:[{options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]},id:\"p-as-heading\"}],any:[],none:[]},{id:\"radiogroup\",selector:\"input[type=radio][name]\",tags:[\"cat.forms\",\"best-practice\"],all:[],any:[\"group-labelledby\",\"fieldset\"],none:[]},{id:\"region\",selector:\"html\",pageLevel:!0,enabled:!1,tags:[\"cat.keyboard\",\"best-practice\"],all:[],any:[\"region\"],none:[]},{id:\"scope-attr-valid\",selector:\"td[scope], th[scope]\",enabled:!0,tags:[\"cat.tables\",\"best-practice\"],all:[\"html5-scope\",\"scope-value\"],any:[],none:[]},{id:\"server-side-image-map\",selector:\"img[ismap]\",tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag211\",\"section508\",\"section508.22.f\"],all:[],any:[],none:[\"exists\"]},{id:\"skip-link\",selector:\"a[href]\",pageLevel:!0,enabled:!1,tags:[\"cat.keyboard\",\"best-practice\"],all:[],any:[\"skip-link\"],none:[]},{id:\"tabindex\",selector:\"[tabindex]\",tags:[\"cat.keyboard\",\"best-practice\"],all:[],any:[\"tabindex\"],none:[]},{id:\"table-duplicate-name\",selector:\"table\",tags:[\"cat.tables\",\"best-practice\"],all:[],any:[],none:[\"same-caption-summary\"]},{id:\"table-fake-caption\",selector:\"table\",matches:function(a){return axe.commons.table.isDataTable(a)},tags:[\"cat.tables\",\"experimental\",\"wcag2a\",\"wcag131\",\"section508\",\"section508.22.g\"],all:[\"caption-faked\"],any:[],none:[]},{id:\"td-has-header\",selector:\"table\",matches:function(a){if(axe.commons.table.isDataTable(a)){var b=axe.commons.table.toArray(a);return b.length>=3&&b[0].length>=3&&b[1].length>=3&&b[2].length>=3}return!1},tags:[\"cat.tables\",\"experimental\",\"wcag2a\",\"wcag131\",\"section508\",\"section508.22.g\"],all:[\"td-has-header\"],any:[],none:[]},{id:\"td-headers-attr\",selector:\"table\",tags:[\"cat.tables\",\"wcag2a\",\"wcag131\",\"section508\",\"section508.22.g\"],all:[\"td-headers-attr\"],any:[],none:[]},{id:\"th-has-data-cells\",selector:\"table\",matches:function(a){return axe.commons.table.isDataTable(a)},tags:[\"cat.tables\",\"wcag2a\",\"wcag131\",\"section508\",\"section508.22.g\"],all:[\"th-has-data-cells\"],any:[],none:[]},{id:\"valid-lang\",selector:\"[lang]:not(html), [xml\\\\:lang]:not(html)\",tags:[\"cat.language\",\"wcag2aa\",\"wcag312\"],all:[],any:[],none:[\"valid-lang\"]},{id:\"video-caption\",selector:\"video\",excludeHidden:!1,tags:[\"cat.text-alternatives\",\"wcag2a\",\"wcag122\",\"wcag123\",\"section508\",\"section508.22.a\"],all:[],any:[],none:[\"caption\"]},{id:\"video-description\",selector:\"video\",excludeHidden:!1,tags:[\"cat.text-alternatives\",\"wcag2aa\",\"wcag125\",\"section508\",\"section508.22.b\"],all:[],any:[],none:[\"description\"]}],checks:[{id:\"abstractrole\",evaluate:function(a,b){return\"abstract\"===axe.commons.aria.getRoleType(a.getAttribute(\"role\"))}},{id:\"aria-allowed-attr\",evaluate:function(a,b){var c,d,e,f=[],g=a.getAttribute(\"role\"),h=a.attributes;if(g||(g=axe.commons.aria.implicitRole(a)),e=axe.commons.aria.allowedAttr(g),g&&e)for(var i=0,j=h.length;i<j;i++)c=h[i],d=c.name,axe.commons.aria.validateAttr(d)&&-1===e.indexOf(d)&&f.push(d+'=\"'+c.nodeValue+'\"');return!f.length||(this.data(f),!1)}},{id:\"aria-hidden-body\",evaluate:function(a,b){return\"true\"!==a.getAttribute(\"aria-hidden\")}},{id:\"aria-errormessage\",evaluate:function(a,b){b=Array.isArray(b)?b:[];var c=a.getAttribute(\"aria-errormessage\"),d=a.hasAttribute(\"aria-errormessage\"),e=document;return!(-1===b.indexOf(c)&&d&&!function(){var b=c&&e.getElementById(c);if(b)return\"alert\"===b.getAttribute(\"role\")||\"assertive\"===b.getAttribute(\"aria-live\")||axe.utils.tokenList(a.getAttribute(\"aria-describedby\")||\"\").indexOf(c)>-1}())||(this.data(c),!1)}},{id:\"invalidrole\",evaluate:function(a,b){return!axe.commons.aria.isValidRole(a.getAttribute(\"role\"))}},{id:\"aria-required-attr\",evaluate:function(a,b){var c=[];if(a.hasAttributes()){var d,e=a.getAttribute(\"role\"),f=axe.commons.aria.requiredAttr(e);if(e&&f)for(var g=0,h=f.length;g<h;g++)d=f[g],a.getAttribute(d)||c.push(d)}return!c.length||(this.data(c),!1)}},{id:\"aria-required-children\",evaluate:function(a,b){function c(a,b,c){if(null===a)return!1;var d=f(b),e=['[role=\"'+b+'\"]'];return d&&(e=e.concat(d)),e=e.join(\",\"),c?g(a,e)||!!a.querySelector(e):!!a.querySelector(e)}function d(a,b){var d,e;for(d=0,e=a.length;d<e;d++)if(null!==a[d]&&c(a[d],b,!0))return!0;return!1}var e=axe.commons.aria.requiredOwned,f=axe.commons.aria.implicitNodes,g=axe.commons.utils.matchesSelector,h=axe.commons.dom.idrefs,i=a.getAttribute(\"role\"),j=e(i);if(!j)return!0;var k=!1,l=j.one;if(!l){var k=!0;l=j.all}var m=function(a,b,e,f){var g,i=b.length,j=[],k=h(a,\"aria-owns\");for(g=0;g<i;g++){var l=b[g];if(c(a,l)||d(k,l)){if(!e)return null}else e&&j.push(l)}if(\"combobox\"===f){var m=j.indexOf(\"textbox\"),n=[\"text\",\"search\",\"email\",\"url\",\"tel\"];m>=0&&\"INPUT\"===a.tagName&&n.includes(a.type)&&j.splice(m,1);var o=j.indexOf(\"listbox\"),p=a.getAttribute(\"aria-expanded\");o>=0&&(!p||\"false\"===p)&&j.splice(o,1)}return j.length?j:!e&&b.length?b:null}(a,l,k,i);return!m||(this.data(m),!1)}},{id:\"aria-required-parent\",evaluate:function(a,b){function c(a){return(axe.commons.aria.implicitNodes(a)||[]).concat('[role=\"'+a+'\"]').join(\",\")}function d(a,b,d){var e,f,g=a.getAttribute(\"role\"),h=[];if(b||(b=axe.commons.aria.requiredContext(g)),!b)return null;for(e=0,f=b.length;e<f;e++){if(d&&axe.utils.matchesSelector(a,c(b[e])))return null;if(axe.commons.dom.findUp(a,c(b[e])))return null;h.push(b[e])}return h}var e=d(a);if(!e)return!0;var f=function(a){for(var b=[],c=null;a;){if(a.getAttribute(\"id\")){var d=axe.commons.utils.escapeSelector(a.getAttribute(\"id\"));c=document.querySelector(\"[aria-owns~=\"+d+\"]\"),c&&b.push(c)}a=a.parentElement}return b.length?b:null}(a);if(f)for(var g=0,h=f.length;g<h;g++)if(!(e=d(f[g],e,!0)))return!0;return this.data(e),!1}},{id:\"aria-valid-attr-value\",evaluate:function(a,b){b=Array.isArray(b)?b:[];for(var c,d,e=[],f=/^aria-/,g=a.attributes,h=[\"aria-errormessage\"],i=0,j=g.length;i<j;i++)c=g[i],d=c.name,h.includes(d)||-1===b.indexOf(d)&&f.test(d)&&!axe.commons.aria.validateAttrValue(a,d)&&e.push(d+'=\"'+c.nodeValue+'\"');return!e.length||(this.data(e),!1)},options:[]},{id:\"aria-valid-attr\",evaluate:function(a,b){b=Array.isArray(b)?b:[];for(var c,d=[],e=/^aria-/,f=a.attributes,g=0,h=f.length;g<h;g++)c=f[g].name,-1===b.indexOf(c)&&e.test(c)&&!axe.commons.aria.validateAttr(c)&&d.push(c);return!d.length||(this.data(d),!1)},options:[]},{id:\"color-contrast\",evaluate:function(a,b){if(!axe.commons.dom.isVisible(a,!1))return!0;var c,d=!!(b||{}).noScroll,e=[],f=axe.commons.color.getBackgroundColor(a,e,d),g=axe.commons.color.getForegroundColor(a,d),h=window.getComputedStyle(a),i=parseFloat(h.getPropertyValue(\"font-size\")),j=h.getPropertyValue(\"font-weight\"),k=-1!==[\"bold\",\"bolder\",\"600\",\"700\",\"800\",\"900\"].indexOf(j),l=axe.commons.color.hasValidContrastRatio(f,g,i,k),m=Math.floor(100*l.contrastRatio)/100;null===f&&(c=axe.commons.color.incompleteData.get(\"bgColor\"));var n=!1;1===m&&(n=!0,c=axe.commons.color.incompleteData.set(\"bgColor\",\"equalRatio\"));var o={fgColor:g?g.toHexString():void 0,bgColor:f?f.toHexString():void 0,contrastRatio:l?m:void 0,fontSize:(72*i/96).toFixed(1)+\"pt\",fontWeight:k?\"bold\":\"normal\",missingData:c,expectedContrastRatio:l.expectedContrastRatio+\":1\"};return this.data(o),null===g||null===f||n?(c=null,axe.commons.color.incompleteData.clear(),void this.relatedNodes(e)):(l.isValid||this.relatedNodes(e),l.isValid)}},{id:\"link-in-text-block\",evaluate:function(a,b){function c(a,b){var c=a.getRelativeLuminance(),d=b.getRelativeLuminance();return(Math.max(c,d)+.05)/(Math.min(c,d)+.05)}function d(a){var b=window.getComputedStyle(a).getPropertyValue(\"display\");return-1!==f.indexOf(b)||\"table-\"===b.substr(0,6)}var e=axe.commons.color,f=[\"block\",\"list-item\",\"table\",\"flex\",\"grid\",\"inline-block\"];if(d(a))return!1;for(var g=a.parentNode;1===g.nodeType&&!d(g);)g=g.parentNode;if(this.relatedNodes([g]),e.elementIsDistinct(a,g))return!0;var h,i;if(h=e.getForegroundColor(a),i=e.getForegroundColor(g),h&&i){var j=c(h,i);if(1===j)return!0;if(j>=3)return axe.commons.color.incompleteData.set(\"fgColor\",\"bgContrast\"),this.data({\nmissingData:axe.commons.color.incompleteData.get(\"fgColor\")}),void axe.commons.color.incompleteData.clear();if(h=e.getBackgroundColor(a),i=e.getBackgroundColor(g),!h||!i||c(h,i)>=3){var k=void 0;return k=h&&i?\"bgContrast\":axe.commons.color.incompleteData.get(\"bgColor\"),axe.commons.color.incompleteData.set(\"fgColor\",k),this.data({missingData:axe.commons.color.incompleteData.get(\"fgColor\")}),void axe.commons.color.incompleteData.clear()}return!1}}},{id:\"fieldset\",evaluate:function(a,b){function c(a,b){return axe.commons.utils.toArray(a.querySelectorAll('select,textarea,button,input:not([name=\"'+b+'\"]):not([type=\"hidden\"])'))}function d(a,b){var d=a.firstElementChild;if(!d||\"LEGEND\"!==d.nodeName.toUpperCase())return h.relatedNodes([a]),g=\"no-legend\",!1;if(!axe.commons.text.accessibleText(d))return h.relatedNodes([d]),g=\"empty-legend\",!1;var e=c(a,b);return!e.length||(h.relatedNodes(e),g=\"mixed-inputs\",!1)}function e(a,b){var d=axe.commons.dom.idrefs(a,\"aria-labelledby\").some(function(a){return a&&axe.commons.text.accessibleText(a)}),e=a.getAttribute(\"aria-label\");if(!(d||e&&axe.commons.text.sanitize(e)))return h.relatedNodes(a),g=\"no-group-label\",!1;var f=c(a,b);return!f.length||(h.relatedNodes(f),g=\"group-mixed-inputs\",!1)}function f(a,b){return axe.commons.utils.toArray(a).filter(function(a){return a!==b})}var g,h=this,i={name:a.getAttribute(\"name\"),type:a.getAttribute(\"type\")},j=function(b){var c=axe.commons.utils.escapeSelector(a.name),i=document.querySelectorAll('input[type=\"'+axe.commons.utils.escapeSelector(a.type)+'\"][name=\"'+c+'\"]');if(i.length<2)return!0;var j=axe.commons.dom.findUp(b,\"fieldset\"),k=axe.commons.dom.findUp(b,'[role=\"group\"]'+(\"radio\"===a.type?',[role=\"radiogroup\"]':\"\"));return k||j?j?d(j,c):e(k,c):(g=\"no-group\",h.relatedNodes(f(i,b)),!1)}(a);return j||(i.failureCode=g),this.data(i),j},after:function(a,b){var c={};return a.filter(function(a){if(a.result)return!0;var b=a.data;if(b){if(c[b.type]=c[b.type]||{},!c[b.type][b.name])return c[b.type][b.name]=[b],!0;var d=c[b.type][b.name].some(function(a){return a.failureCode===b.failureCode});return d||c[b.type][b.name].push(b),!d}return!1})}},{id:\"group-labelledby\",evaluate:function(a,b){this.data({name:a.getAttribute(\"name\"),type:a.getAttribute(\"type\")});var c=document.querySelectorAll('input[type=\"'+axe.commons.utils.escapeSelector(a.type)+'\"][name=\"'+axe.commons.utils.escapeSelector(a.name)+'\"]');return c.length<=1||0!==[].map.call(c,function(a){var b=a.getAttribute(\"aria-labelledby\");return b?b.split(/\\s+/):[]}).reduce(function(a,b){return a.filter(function(a){return-1!==b.indexOf(a)})}).filter(function(a){var b=document.getElementById(a);return b&&axe.commons.text.accessibleText(b)}).length},after:function(a,b){var c={};return a.filter(function(a){var b=a.data;return!(!b||(c[b.type]=c[b.type]||{},c[b.type][b.name]))&&(c[b.type][b.name]=!0,!0)})}},{id:\"accesskeys\",evaluate:function(a,b){return axe.commons.dom.isVisible(a,!1)&&(this.data(a.getAttribute(\"accesskey\")),this.relatedNodes([a])),!0},after:function(a,b){var c={};return a.filter(function(a){if(!a.data)return!1;var b=a.data.toUpperCase();return c[b]?(c[b].relatedNodes.push(a.relatedNodes[0]),!1):(c[b]=a,a.relatedNodes=[],!0)}).map(function(a){return a.result=!!a.relatedNodes.length,a})}},{id:\"focusable-no-name\",evaluate:function(a,b){var c=a.getAttribute(\"tabindex\");return!!(axe.commons.dom.isFocusable(a)&&c>-1)&&!axe.commons.text.accessibleText(a)}},{id:\"has-at-least-one-main\",evaluate:function(a,b){var c=document.querySelectorAll(\"main,[role=main]\");return this.data(!!c[0]),!!c[0]},after:function(a,b){for(var c=!1,d=0;d<a.length&&!c;d++)c=a[d].data;for(var d=0;d<a.length;d++)a[d].result=c;return a}},{id:\"has-no-more-than-one-main\",evaluate:function(a,b){return document.querySelectorAll(\"main,[role=main]\").length<=1}},{id:\"main-is-top-level\",evaluate:function(a,b){for(var c=axe.commons.aria.getRolesByType(\"landmark\"),d=a.parentNode;d;){if(1===d.nodeType){var e=d.getAttribute(\"role\");if(e||\"form\"===d.tagName.toLowerCase()||(e=axe.commons.aria.implicitRole(d)),e&&c.includes(e))return!1}d=d.parentNode}return!0}},{id:\"tabindex\",evaluate:function(a,b){return a.tabIndex<=0}},{id:\"duplicate-img-label\",evaluate:function(a,b){var c=a.querySelectorAll(\"img\"),d=axe.commons.text.visible(a,!0).toLowerCase();if(\"\"===d)return!1;for(var e=0,f=c.length;e<f;e++){var g=c[e];if(axe.commons.text.accessibleText(g).toLowerCase()===d&&\"presentation\"!==g.getAttribute(\"role\")&&axe.commons.dom.isVisible(g))return!0}return!1}},{id:\"explicit-label\",evaluate:function(a,b){if(a.getAttribute(\"id\")){var c=axe.commons.utils.escapeSelector(a.getAttribute(\"id\")),d=document.querySelector('label[for=\"'+c+'\"]');if(d)return!!axe.commons.text.accessibleText(d)}return!1}},{id:\"help-same-as-label\",evaluate:function(a,b){var c=axe.commons.text.label(a),d=a.getAttribute(\"title\");if(!c)return!1;if(!d&&(d=\"\",a.getAttribute(\"aria-describedby\"))){d=axe.commons.dom.idrefs(a,\"aria-describedby\").map(function(a){return a?axe.commons.text.accessibleText(a):\"\"}).join(\"\")}return axe.commons.text.sanitize(d)===axe.commons.text.sanitize(c)},enabled:!1},{id:\"implicit-label\",evaluate:function(a,b){var c=axe.commons.dom.findUp(a,\"label\");return!!c&&!!axe.commons.text.accessibleText(c)}},{id:\"multiple-label\",evaluate:function(a,b){var c=axe.commons.utils.escapeSelector(a.getAttribute(\"id\")),d=Array.from(document.querySelectorAll('label[for=\"'+c+'\"]')),e=a.parentNode;for(d.length&&(d=d.filter(function(a,b){if(0===b&&!axe.commons.dom.isVisible(a,!0)||axe.commons.dom.isVisible(a,!0))return a}));e;)\"LABEL\"===e.tagName&&-1===d.indexOf(e)&&d.push(e),e=e.parentNode;return this.relatedNodes(d),d.length>1}},{id:\"title-only\",evaluate:function(a,b){return!(axe.commons.text.label(a)||!a.getAttribute(\"title\")&&!a.getAttribute(\"aria-describedby\"))}},{id:\"has-lang\",evaluate:function(a,b){return!!(a.getAttribute(\"lang\")||a.getAttribute(\"xml:lang\")||\"\").trim()}},{id:\"valid-lang\",evaluate:function(a,b){function c(a){return a.trim().split(\"-\")[0].toLowerCase()}var d,e;return d=(b||axe.commons.utils.validLangs()).map(c),e=[\"lang\",\"xml:lang\"].reduce(function(b,e){var f=a.getAttribute(e);if(\"string\"!=typeof f)return b;var g=c(f);return\"\"!==g&&-1===d.indexOf(g)&&b.push(e+'=\"'+a.getAttribute(e)+'\"'),b},[]),!!e.length&&(this.data(e),!0)}},{id:\"dlitem\",evaluate:function(a,b){return\"DL\"===a.parentNode.tagName.toUpperCase()}},{id:\"has-listitem\",evaluate:function(a,b){var c=a.children;if(0===c.length)return!0;for(var d=0;d<c.length;d++)if(\"LI\"===c[d].nodeName.toUpperCase())return!1;return!0}},{id:\"listitem\",evaluate:function(a,b){return-1!==[\"UL\",\"OL\"].indexOf(a.parentNode.nodeName.toUpperCase())||\"list\"===a.parentNode.getAttribute(\"role\")}},{id:\"only-dlitems\",evaluate:function(a,b){for(var c,d,e=[],f=a.childNodes,g=[\"STYLE\",\"META\",\"LINK\",\"MAP\",\"AREA\",\"SCRIPT\",\"DATALIST\",\"TEMPLATE\"],h=!1,i=0;i<f.length;i++){c=f[i];var d=c.nodeName.toUpperCase();1===c.nodeType&&\"DT\"!==d&&\"DD\"!==d&&-1===g.indexOf(d)?e.push(c):3===c.nodeType&&\"\"!==c.nodeValue.trim()&&(h=!0)}return e.length&&this.relatedNodes(e),!!e.length||h}},{id:\"only-listitems\",evaluate:function(a,b){for(var c,d,e=[],f=a.childNodes,g=[\"STYLE\",\"META\",\"LINK\",\"MAP\",\"AREA\",\"SCRIPT\",\"DATALIST\",\"TEMPLATE\"],h=!1,i=0;i<f.length;i++)c=f[i],d=c.nodeName.toUpperCase(),1===c.nodeType&&\"LI\"!==d&&-1===g.indexOf(d)?e.push(c):3===c.nodeType&&\"\"!==c.nodeValue.trim()&&(h=!0);return e.length&&this.relatedNodes(e),!!e.length||h}},{id:\"structured-dlitems\",evaluate:function(a,b){var c=a.children;if(!c||!c.length)return!1;for(var d,e=!1,f=!1,g=0;g<c.length;g++){if(d=c[g].nodeName.toUpperCase(),\"DT\"===d&&(e=!0),e&&\"DD\"===d)return!1;\"DD\"===d&&(f=!0)}return e||f}},{id:\"caption\",evaluate:function(a,b){var c=a.querySelectorAll(\"track\");if(c.length){for(var d=0;d<c.length;d++){var e=c[d].getAttribute(\"kind\");if(e&&\"captions\"===e)return!1}return!0}}},{id:\"description\",evaluate:function(a,b){var c=a.querySelectorAll(\"track\");if(c.length){for(var d=0;d<c.length;d++){var e=c[d].getAttribute(\"kind\");if(e&&\"descriptions\"===e)return!1}return!0}}},{id:\"meta-viewport-large\",evaluate:function(a,b){b=b||{};for(var c,d=a.getAttribute(\"content\")||\"\",e=d.split(/[;,]/),f={},g=b.scaleMinimum||2,h=b.lowerBound||!1,i=0,j=e.length;i<j;i++){c=e[i].split(\"=\");var k=c.shift().toLowerCase();k&&c.length&&(f[k.trim()]=c.shift().trim().toLowerCase())}return!!(h&&f[\"maximum-scale\"]&&parseFloat(f[\"maximum-scale\"])<h)||!(!h&&\"no\"===f[\"user-scalable\"])&&!(f[\"maximum-scale\"]&&parseFloat(f[\"maximum-scale\"])<g)},options:{scaleMinimum:5,lowerBound:2}},{id:\"meta-viewport\",evaluate:function(a,b){b=b||{};for(var c,d=a.getAttribute(\"content\")||\"\",e=d.split(/[;,]/),f={},g=b.scaleMinimum||2,h=b.lowerBound||!1,i=0,j=e.length;i<j;i++){c=e[i].split(\"=\");var k=c.shift().toLowerCase();k&&c.length&&(f[k.trim()]=c.shift().trim().toLowerCase())}return!!(h&&f[\"maximum-scale\"]&&parseFloat(f[\"maximum-scale\"])<h)||!(!h&&\"no\"===f[\"user-scalable\"])&&!(f[\"maximum-scale\"]&&parseFloat(f[\"maximum-scale\"])<g)},options:{scaleMinimum:2}},{id:\"header-present\",evaluate:function(a,b){return!!a.querySelector('h1, h2, h3, h4, h5, h6, [role=\"heading\"]')}},{id:\"heading-order\",evaluate:function(a,b){var c=a.getAttribute(\"aria-level\");if(null!==c)return this.data(parseInt(c,10)),!0;var d=a.tagName.match(/H(\\d)/);return!d||(this.data(parseInt(d[1],10)),!0)},after:function(a,b){if(a.length<2)return a;for(var c=a[0].data,d=1;d<a.length;d++)a[d].result&&a[d].data>c+1&&(a[d].result=!1),c=a[d].data;return a}},{id:\"href-no-hash\",evaluate:function(a,b){return\"#\"!==a.getAttribute(\"href\")}},{id:\"internal-link-present\",evaluate:function(a,b){return!!a.querySelector('a[href^=\"#\"]')}},{id:\"landmark\",evaluate:function(a,b){return a.getElementsByTagName(\"main\").length>0||!!a.querySelector('[role=\"main\"]')}},{id:\"meta-refresh\",evaluate:function(a,b){var c=a.getAttribute(\"content\")||\"\",d=c.split(/[;,]/);return\"\"===c||\"0\"===d[0]}},{id:\"p-as-heading\",evaluate:function(a,b){function c(a){for(var b=a,c=a.textContent.trim(),d=c;d===c&&void 0!==b;){var e=-1;if(a=b,0===a.children.length)return a;do{e++,d=a.children[e].textContent.trim()}while(\"\"===d&&e+1<a.children.length);b=a.children[e]}return a}function d(a){switch(a){case\"lighter\":return 100;case\"normal\":return 400;case\"bold\":return 700;case\"bolder\":return 900}return a=parseInt(a),isNaN(a)?400:a}function e(a){var b=window.getComputedStyle(c(a));return{fontWeight:d(b.getPropertyValue(\"font-weight\")),fontSize:parseInt(b.getPropertyValue(\"font-size\")),isItalic:\"italic\"===b.getPropertyValue(\"font-style\")}}function f(a,b,c){return c.reduce(function(c,d){return c||(!d.size||a.fontSize/d.size>b.fontSize)&&(!d.weight||a.fontWeight-d.weight>b.fontWeight)&&(!d.italic||a.isItalic&&!b.isItalic)},!1)}var g=Array.from(a.parentNode.children),h=g.indexOf(a);b=b||{};var i=b.margins||[],j=g.slice(h+1).find(function(a){return\"P\"===a.nodeName.toUpperCase()}),k=g.slice(0,h).reverse().find(function(a){return\"P\"===a.nodeName.toUpperCase()}),l=e(a),m=j?e(j):null,n=k?e(k):null;if(!m||!f(l,m,i))return!0;var o=axe.commons.dom.findUp(a,\"blockquote\");return!!(o&&\"BLOCKQUOTE\"===o.nodeName.toUpperCase()||n&&!f(l,n,i))&&void 0},options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]}},{id:\"region\",evaluate:function(a,b){function c(a){return h&&axe.commons.dom.getElementByReference(h,\"href\")&&h===a}function d(a){return a.hasAttribute(\"role\")?g.includes(a.getAttribute(\"role\").toLowerCase()):i.some(function(b){return axe.utils.matchesSelector(a,b)})}function e(a){return d(a)?null:c(a)?f(a):axe.commons.dom.isVisible(a,!0)&&(axe.commons.text.visible(a,!0,!0)||axe.commons.dom.isVisualContent(a))?a:f(a)}function f(a){var b=axe.commons.utils.toArray(a.children);return 0===b.length?[]:b.map(e).filter(function(a){return null!==a}).reduce(function(a,b){return a.concat(b)},[])}var g=axe.commons.aria.getRolesByType(\"landmark\"),h=a.querySelector(\"a[href]\"),i=g.reduce(function(a,b){return a.concat(axe.commons.aria.implicitNodes(b))},[]).filter(function(a){return null!==a}),j=f(a);return this.relatedNodes(j),!j.length},after:function(a,b){return[a[0]]}},{id:\"skip-link\",evaluate:function(a,b){var c=axe.commons.dom.getElementByReference(a,\"href\");return!!c&&axe.commons.dom.isFocusable(c)},after:function(a,b){return[a[0]]}},{id:\"unique-frame-title\",evaluate:function(a,b){var c=axe.commons.text.sanitize(a.title).trim().toLowerCase();return this.data(c),!0},after:function(a,b){var c={};return a.forEach(function(a){c[a.data]=void 0!==c[a.data]?++c[a.data]:0}),a.forEach(function(a){a.result=!!c[a.data]}),a}},{id:\"aria-label\",evaluate:function(a,b){var c=a.getAttribute(\"aria-label\");return!!(c?axe.commons.text.sanitize(c).trim():\"\")}},{id:\"aria-labelledby\",evaluate:function(a,b){return(0,axe.commons.dom.idrefs)(a,\"aria-labelledby\").some(function(a){return a&&axe.commons.text.accessibleText(a,!0)})}},{id:\"button-has-visible-text\",evaluate:function(a,b){var c=a.nodeName.toUpperCase(),d=a.getAttribute(\"role\"),e=void 0;return(\"BUTTON\"===c||\"button\"===d&&\"INPUT\"!==c)&&(e=axe.commons.text.accessibleText(a),this.data(e),!!e)}},{id:\"doc-has-title\",evaluate:function(a,b){var c=document.title;return!!(c?axe.commons.text.sanitize(c).trim():\"\")}},{id:\"duplicate-id\",evaluate:function(a,b){if(!a.getAttribute(\"id\").trim())return!0;for(var c=axe.commons.utils.escapeSelector(a.getAttribute(\"id\")),d=document.querySelectorAll('[id=\"'+c+'\"]'),e=[],f=0;f<d.length;f++)d[f]!==a&&e.push(d[f]);return e.length&&this.relatedNodes(e),this.data(a.getAttribute(\"id\")),d.length<=1},after:function(a,b){var c=[];return a.filter(function(a){return-1===c.indexOf(a.data)&&(c.push(a.data),!0)})}},{id:\"exists\",evaluate:function(a,b){return!0}},{id:\"has-alt\",evaluate:function(a,b){var c=a.nodeName.toLowerCase();return a.hasAttribute(\"alt\")&&(\"img\"===c||\"input\"===c||\"area\"===c)}},{id:\"has-visible-text\",evaluate:function(a,b){return axe.commons.text.accessibleText(a).length>0}},{id:\"is-on-screen\",evaluate:function(a,b){return axe.commons.dom.isVisible(a,!1)&&!axe.commons.dom.isOffscreen(a)}},{id:\"non-empty-alt\",evaluate:function(a,b){var c=a.getAttribute(\"alt\");return!!(c?axe.commons.text.sanitize(c).trim():\"\")}},{id:\"non-empty-if-present\",evaluate:function(a,b){var c=a.nodeName.toUpperCase(),d=(a.getAttribute(\"type\")||\"\").toLowerCase(),e=a.getAttribute(\"value\");return this.data(e),\"INPUT\"===c&&-1!==[\"submit\",\"reset\"].indexOf(d)&&null===e}},{id:\"non-empty-title\",evaluate:function(a,b){var c=a.getAttribute(\"title\");return!!(c?axe.commons.text.sanitize(c).trim():\"\")}},{id:\"non-empty-value\",evaluate:function(a,b){var c=a.getAttribute(\"value\");return!!(c?axe.commons.text.sanitize(c).trim():\"\")}},{id:\"role-none\",evaluate:function(a,b){return\"none\"===a.getAttribute(\"role\")}},{id:\"role-presentation\",evaluate:function(a,b){return\"presentation\"===a.getAttribute(\"role\")}},{id:\"caption-faked\",evaluate:function(a,b){var c=axe.commons.table.toGrid(a),d=c[0];return c.length<=1||d.length<=1||a.rows.length<=1||d.reduce(function(a,b,c){return a||b!==d[c+1]&&void 0!==d[c+1]},!1)}},{id:\"has-caption\",evaluate:function(a,b){return!!a.caption}},{id:\"has-summary\",evaluate:function(a,b){return!!a.summary}},{id:\"has-th\",evaluate:function(a,b){for(var c,d,e=[],f=0,g=a.rows.length;f<g;f++){c=a.rows[f];for(var h=0,i=c.cells.length;h<i;h++)d=c.cells[h],\"TH\"!==d.nodeName.toUpperCase()&&-1===[\"rowheader\",\"columnheader\"].indexOf(d.getAttribute(\"role\"))||e.push(d)}return!!e.length&&(this.relatedNodes(e),!0)}},{id:\"html5-scope\",evaluate:function(a,b){return!axe.commons.dom.isHTML5(document)||\"TH\"===a.nodeName.toUpperCase()}},{id:\"same-caption-summary\",evaluate:function(a,b){return!(!a.summary||!a.caption)&&a.summary===axe.commons.text.accessibleText(a.caption)}},{id:\"scope-value\",evaluate:function(a,b){b=b||{};var c=a.getAttribute(\"scope\").toLowerCase();return-1!==([\"row\",\"col\",\"rowgroup\",\"colgroup\"]||b.values).indexOf(c)}},{id:\"td-has-header\",evaluate:function(a,b){var c=axe.commons.table,d=[];return c.getAllCells(a).forEach(function(a){if(axe.commons.dom.hasContent(a)&&c.isDataCell(a)&&!axe.commons.aria.label(a)){var b=c.getHeaders(a);(b=b.reduce(function(a,b){return a||null!==b&&!!axe.commons.dom.hasContent(b)},!1))||d.push(a)}}),!d.length||(this.relatedNodes(d),!1)}},{id:\"td-headers-attr\",evaluate:function(a,b){for(var c=[],d=0,e=a.rows.length;d<e;d++)for(var f=a.rows[d],g=0,h=f.cells.length;g<h;g++)c.push(f.cells[g]);var i=c.reduce(function(a,b){return b.getAttribute(\"id\")&&a.push(b.getAttribute(\"id\")),a},[]),j=c.reduce(function(a,b){var c,d,e=(b.getAttribute(\"headers\")||\"\").split(/\\s/).reduce(function(a,b){return b=b.trim(),b&&a.push(b),a},[]);return 0!==e.length&&(b.getAttribute(\"id\")&&(c=-1!==e.indexOf(b.getAttribute(\"id\").trim())),d=e.reduce(function(a,b){return a||-1===i.indexOf(b)},!1),(c||d)&&a.push(b)),a},[]);return!(j.length>0)||(this.relatedNodes(j),!1)}},{id:\"th-has-data-cells\",evaluate:function(a,b){var c=axe.commons.table,d=c.getAllCells(a),e=this,f=[];d.forEach(function(a){var b=a.getAttribute(\"headers\");b&&(f=f.concat(b.split(/\\s+/)));var c=a.getAttribute(\"aria-labelledby\");c&&(f=f.concat(c.split(/\\s+/)))});var g=d.filter(function(a){return\"\"!==axe.commons.text.sanitize(a.textContent)&&(\"TH\"===a.nodeName.toUpperCase()||-1!==[\"rowheader\",\"columnheader\"].indexOf(a.getAttribute(\"role\")))}),h=c.toGrid(a);return!!g.reduce(function(a,b){if(b.getAttribute(\"id\")&&f.includes(b.getAttribute(\"id\")))return!!a||a;var d=!1,g=c.getCellPosition(b,h);return c.isColumnHeader(b)&&(d=c.traverse(\"down\",g,h).reduce(function(a,b){return a||axe.commons.dom.hasContent(b)&&!c.isColumnHeader(b)},!1)),!d&&c.isRowHeader(b)&&(d=c.traverse(\"right\",g,h).reduce(function(a,b){return a||axe.commons.dom.hasContent(b)&&!c.isRowHeader(b)},!1)),d||e.relatedNodes(b),a&&d},!0)||void 0}},{id:\"hidden-content\",evaluate:function(a,b){var c=window.getComputedStyle(a);if(![\"SCRIPT\",\"HEAD\",\"TITLE\",\"NOSCRIPT\",\"STYLE\",\"TEMPLATE\"].includes(a.tagName.toUpperCase())&&axe.commons.dom.hasContent(a)){if(\"none\"===c.getPropertyValue(\"display\"))return;if(\"hidden\"===c.getPropertyValue(\"visibility\")){if(a.parentNode)var d=window.getComputedStyle(a.parentNode);if(!d||\"hidden\"!==d.getPropertyValue(\"visibility\"))return}}return!0}}],commons:function(){function a(a){return a.getPropertyValue(\"font-family\").split(/[,;]/g).map(function(a){return a.trim().toLowerCase()})}function b(b,c){var d=window.getComputedStyle(b);if(\"none\"!==d.getPropertyValue(\"background-image\"))return!0;if([\"border-bottom\",\"border-top\",\"outline\"].reduce(function(a,b){var c=new y.Color;return c.parseRgbString(d.getPropertyValue(b+\"-color\")),a||\"none\"!==d.getPropertyValue(b+\"-style\")&&parseFloat(d.getPropertyValue(b+\"-width\"))>0&&0!==c.alpha},!1))return!0;var e=window.getComputedStyle(c);if(a(d)[0]!==a(e)[0])return!0;var f=[\"text-decoration-line\",\"text-decoration-style\",\"font-weight\",\"font-style\",\"font-size\"].reduce(function(a,b){return a||d.getPropertyValue(b)!==e.getPropertyValue(b)},!1),g=d.getPropertyValue(\"text-decoration\");return g.split(\" \").length<3&&(f=f||g!==e.getPropertyValue(\"text-decoration\")),f}function c(a,b){var c=a.nodeName.toUpperCase();if(C.includes(c))return axe.commons.color.incompleteData.set(\"bgColor\",\"imgNode\"),!0;b=b||window.getComputedStyle(a);var d=b.getPropertyValue(\"background-image\"),e=\"none\"!==d;if(e){var f=/gradient/.test(d);axe.commons.color.incompleteData.set(\"bgColor\",f?\"bgGradient\":\"bgImage\")}return e}function d(a,b){b=b||window.getComputedStyle(a);var c=new y.Color;if(c.parseRgbString(b.getPropertyValue(\"background-color\")),0!==c.alpha){var d=b.getPropertyValue(\"opacity\");c.alpha=c.alpha*d}return c}function e(a,b){var c=a.getClientRects()[0],d=document.elementsFromPoint(c.left,c.top);if(d)for(var e=0;e<d.length;e++)if(d[e]!==a&&d[e]===b)return!0;return!1}function f(a,b,c){var f=0;if(a>0)for(var g=a-1;g>=0;g--){var h=b[g],i=window.getComputedStyle(h),j=d(h,i);j.alpha&&e(c,h)?f+=j.alpha:b.splice(g,1)}return f}function g(a,b,c){var d=a!==b&&!z.visuallyContains(a,b)&&0!==c.alpha;return d&&axe.commons.color.incompleteData.set(\"bgColor\",\"elmPartiallyObscured\"),d}function h(a,b){var c={TD:[\"TR\",\"TBODY\"],TH:[\"TR\",\"THEAD\"],INPUT:[\"LABEL\"]},d=a.map(function(a){return a.tagName}),e=a;for(var f in c)if(d.includes(f))for(var g in c[f])if(f.hasOwnProperty(g)){var h=axe.commons.dom.findUp(b,c[f][g]);if(h&&-1===a.indexOf(h)){var i=axe.commons.dom.visuallyOverlaps(b.getBoundingClientRect(),h);i&&e.splice(d.indexOf(f)+1,0,h)}b.tagName===c[f][g]&&-1===d.indexOf(b.tagName)&&e.splice(d.indexOf(f)+1,0,b)}return e}function i(a){var b=a.indexOf(document.body),e=a;return b>1&&!c(document.documentElement)&&0===d(document.documentElement).alpha&&(e.splice(b,1),e.splice(a.indexOf(document.documentElement),1),e.push(document.body)),e}function j(a,b){\"use strict\";var c=b(a);for(a=a.firstChild;a;)!1!==c&&j(a,b),a=a.nextSibling}function k(a){\"use strict\";var b=window.getComputedStyle(a).getPropertyValue(\"display\");return-1!==D.indexOf(b)||\"table-\"===b.substr(0,6)}function l(a){\"use strict\";var b=a.match(/rect\\s*\\(([0-9]+)px,?\\s*([0-9]+)px,?\\s*([0-9]+)px,?\\s*([0-9]+)px\\s*\\)/);return!(!b||5!==b.length)&&(b[3]-b[1]<=0&&b[2]-b[4]<=0)}function m(a){var b=null;if(a.getAttribute(\"id\")){var c=axe.utils.escapeSelector(a.getAttribute(\"id\"));if(b=document.querySelector('label[for=\"'+c+'\"]'))return b}return b=z.findUp(a,\"label\")}function n(a){return-1!==[\"button\",\"reset\",\"submit\"].indexOf(a.type)}function o(a){var b=a.nodeName.toUpperCase();return\"TEXTAREA\"===b||\"SELECT\"===b||\"INPUT\"===b&&\"hidden\"!==a.type.toLowerCase()}function p(a){return-1!==[\"BUTTON\",\"SUMMARY\",\"A\"].indexOf(a.nodeName.toUpperCase())}function q(a){return-1!==[\"TABLE\",\"FIGURE\"].indexOf(a.nodeName.toUpperCase())}function r(a){var b=a.nodeName.toUpperCase();if(\"INPUT\"===b)return!a.hasAttribute(\"type\")||-1!==G.indexOf(a.getAttribute(\"type\").toLowerCase())&&a.value?a.value:\"\";if(\"SELECT\"===b){var c=a.options;if(c&&c.length){for(var d=\"\",e=0;e<c.length;e++)c[e].selected&&(d+=\" \"+c[e].text);return B.sanitize(d)}return\"\"}return\"TEXTAREA\"===b&&a.value?a.value:\"\"}function s(a,b){var c=a.querySelector(b.toLowerCase());return c?B.accessibleText(c):\"\"}function t(a){if(!a)return!1;switch(a.nodeName.toUpperCase()){case\"SELECT\":case\"TEXTAREA\":return!0;case\"INPUT\":return!a.hasAttribute(\"type\")||-1!==G.indexOf(a.getAttribute(\"type\").toLowerCase());default:return!1}}function u(a){var b=a.nodeName.toUpperCase();return\"INPUT\"===b&&\"image\"===a.type.toLowerCase()||-1!==[\"IMG\",\"APPLET\",\"AREA\"].indexOf(b)}function v(a){return!!B.sanitize(a)}var commons={},w=commons.aria={},x=w.lookupTable={};x.attributes={\"aria-activedescendant\":{type:\"idref\"},\"aria-atomic\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-autocomplete\":{type:\"nmtoken\",values:[\"inline\",\"list\",\"both\",\"none\"]},\"aria-busy\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-checked\":{type:\"nmtoken\",values:[\"true\",\"false\",\"mixed\",\"undefined\"]},\"aria-colcount\":{type:\"int\"},\"aria-colindex\":{type:\"int\"},\"aria-colspan\":{type:\"int\"},\"aria-controls\":{type:\"idrefs\"},\"aria-current\":{type:\"nmtoken\",values:[\"page\",\"step\",\"location\",\"date\",\"time\",\"true\",\"false\"]},\"aria-describedby\":{type:\"idrefs\"},\"aria-disabled\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-dropeffect\":{type:\"nmtokens\",values:[\"copy\",\"move\",\"reference\",\"execute\",\"popup\",\"none\"]},\"aria-errormessage\":{type:\"idref\"},\"aria-expanded\":{type:\"nmtoken\",values:[\"true\",\"false\",\"undefined\"]},\"aria-flowto\":{type:\"idrefs\"},\"aria-grabbed\":{type:\"nmtoken\",values:[\"true\",\"false\",\"undefined\"]},\"aria-haspopup\":{type:\"nmtoken\",values:[\"true\",\"false\",\"menu\",\"listbox\",\"tree\",\"grid\",\"dialog\"]},\"aria-hidden\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-invalid\":{type:\"nmtoken\",values:[\"true\",\"false\",\"spelling\",\"grammar\"]},\"aria-keyshortcuts\":{type:\"string\"},\"aria-label\":{type:\"string\"},\"aria-labelledby\":{type:\"idrefs\"},\"aria-level\":{type:\"int\"},\"aria-live\":{type:\"nmtoken\",values:[\"off\",\"polite\",\"assertive\"]},\"aria-modal\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-multiline\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-multiselectable\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-orientation\":{type:\"nmtoken\",values:[\"horizontal\",\"vertical\"]},\"aria-owns\":{type:\"idrefs\"},\"aria-placeholder\":{type:\"string\"},\"aria-posinset\":{type:\"int\"},\"aria-pressed\":{type:\"nmtoken\",values:[\"true\",\"false\",\"mixed\",\"undefined\"]},\"aria-readonly\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-relevant\":{type:\"nmtokens\",values:[\"additions\",\"removals\",\"text\",\"all\"]},\"aria-required\":{type:\"boolean\",values:[\"true\",\"false\"]},\"aria-rowcount\":{type:\"int\"},\"aria-rowindex\":{type:\"int\"},\"aria-rowspan\":{type:\"int\"},\"aria-selected\":{type:\"nmtoken\",values:[\"true\",\"false\",\"undefined\"]},\"aria-setsize\":{type:\"int\"},\"aria-sort\":{type:\"nmtoken\",values:[\"ascending\",\"descending\",\"other\",\"none\"]},\"aria-valuemax\":{type:\"decimal\"},\"aria-valuemin\":{type:\"decimal\"},\"aria-valuenow\":{type:\"decimal\"},\"aria-valuetext\":{type:\"string\"}},x.globalAttributes=[\"aria-atomic\",\"aria-busy\",\"aria-controls\",\"aria-current\",\"aria-describedby\",\"aria-disabled\",\"aria-dropeffect\",\"aria-flowto\",\"aria-grabbed\",\"aria-haspopup\",\"aria-hidden\",\"aria-invalid\",\"aria-keyshortcuts\",\"aria-label\",\"aria-labelledby\",\"aria-live\",\"aria-owns\",\"aria-relevant\"],x.role={alert:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},alertdialog:{type:\"widget\",attributes:{allowed:[\"aria-expanded\",\"aria-modal\"]},owned:null,nameFrom:[\"author\"],context:null},application:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},article:{type:\"structure\",attributes:{allowed:[\"aria-expanded\",\"aria-posinset\",\"aria-setsize\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"article\"]},banner:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"header\"]},button:{type:\"widget\",attributes:{allowed:[\"aria-expanded\",\"aria-pressed\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null,implicit:[\"button\",'input[type=\"button\"]','input[type=\"image\"]','input[type=\"reset\"]','input[type=\"submit\"]',\"summary\"]},cell:{type:\"structure\",attributes:{allowed:[\"aria-colindex\",\"aria-colspan\",\"aria-rowindex\",\"aria-rowspan\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"row\"],implicit:[\"td\",\"th\"]},checkbox:{type:\"widget\",attributes:{allowed:[\"aria-checked\",\"aria-required\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null,implicit:['input[type=\"checkbox\"]']},columnheader:{type:\"structure\",attributes:{allowed:[\"aria-colindex\",\"aria-colspan\",\"aria-expanded\",\"aria-rowindex\",\"aria-rowspan\",\"aria-required\",\"aria-readonly\",\"aria-selected\",\"aria-sort\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"row\"],implicit:[\"th\"]},combobox:{type:\"composite\",attributes:{allowed:[\"aria-expanded\",\"aria-autocomplete\",\"aria-required\",\"aria-activedescendant\",\"aria-orientation\"]},owned:{all:[\"listbox\",\"textbox\"]},nameFrom:[\"author\"],context:null},command:{nameFrom:[\"author\"],type:\"abstract\"},complementary:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"aside\"]},composite:{nameFrom:[\"author\"],type:\"abstract\"},contentinfo:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"footer\"]},definition:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"dd\",\"dfn\"]},dialog:{type:\"widget\",attributes:{allowed:[\"aria-expanded\",\"aria-modal\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"dialog\"]},directory:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null},document:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"body\"]},feed:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:{one:[\"article\"]},nameFrom:[\"author\"],context:null},form:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"form\"]},grid:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\",\"aria-colcount\",\"aria-level\",\"aria-multiselectable\",\"aria-readonly\",\"aria-rowcount\"]},owned:{one:[\"rowgroup\",\"row\"]},nameFrom:[\"author\"],context:null,implicit:[\"table\"]},gridcell:{type:\"widget\",attributes:{allowed:[\"aria-colindex\",\"aria-colspan\",\"aria-expanded\",\"aria-rowindex\",\"aria-rowspan\",\"aria-selected\",\"aria-readonly\",\"aria-required\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"row\"],implicit:[\"td\",\"th\"]},group:{type:\"structure\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"details\",\"optgroup\"]},heading:{type:\"structure\",attributes:{allowed:[\"aria-level\",\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null,implicit:[\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\"]},img:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"img\"]},input:{nameFrom:[\"author\"],type:\"abstract\"},landmark:{nameFrom:[\"author\"],type:\"abstract\"},link:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null,implicit:[\"a[href]\"]},list:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:{all:[\"listitem\"]},nameFrom:[\"author\"],context:null,implicit:[\"ol\",\"ul\",\"dl\"]},listbox:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-multiselectable\",\"aria-required\",\"aria-expanded\",\"aria-orientation\"]},owned:{all:[\"option\"]},nameFrom:[\"author\"],context:null,implicit:[\"select\"]},listitem:{type:\"structure\",attributes:{allowed:[\"aria-level\",\"aria-posinset\",\"aria-setsize\",\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"list\"],implicit:[\"li\",\"dt\"]},log:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},main:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"main\"]},marquee:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},math:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"math\"]},menu:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\",\"aria-orientation\"]},owned:{one:[\"menuitem\",\"menuitemradio\",\"menuitemcheckbox\"]},nameFrom:[\"author\"],context:null,implicit:['menu[type=\"context\"]']},menubar:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\",\"aria-orientation\"]},owned:null,nameFrom:[\"author\"],context:null},menuitem:{type:\"widget\",attributes:{allowed:[\"aria-posinset\",\"aria-setsize\",\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"menu\",\"menubar\"],implicit:['menuitem[type=\"command\"]']},menuitemcheckbox:{type:\"widget\",attributes:{allowed:[\"aria-checked\",\"aria-posinset\",\"aria-setsize\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"menu\",\"menubar\"],implicit:['menuitem[type=\"checkbox\"]']},menuitemradio:{type:\"widget\",attributes:{allowed:[\"aria-checked\",\"aria-selected\",\"aria-posinset\",\"aria-setsize\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"menu\",\"menubar\"],implicit:['menuitem[type=\"radio\"]']},navigation:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"nav\"]},none:{type:\"structure\",attributes:null,owned:null,nameFrom:[\"author\"],context:null},note:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},option:{type:\"widget\",attributes:{allowed:[\"aria-selected\",\"aria-posinset\",\"aria-setsize\",\"aria-checked\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"listbox\"],implicit:[\"option\"]},presentation:{type:\"structure\",attributes:null,owned:null,nameFrom:[\"author\"],context:null},progressbar:{type:\"widget\",attributes:{allowed:[\"aria-valuetext\",\"aria-valuenow\",\"aria-valuemax\",\"aria-valuemin\"]},owned:null,nameFrom:[\"author\"],\ncontext:null,implicit:[\"progress\"]},radio:{type:\"widget\",attributes:{allowed:[\"aria-checked\",\"aria-selected\",\"aria-posinset\",\"aria-setsize\",\"aria-required\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null,implicit:['input[type=\"radio\"]']},radiogroup:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-required\",\"aria-expanded\"]},owned:{all:[\"radio\"]},nameFrom:[\"author\"],context:null},range:{nameFrom:[\"author\"],type:\"abstract\"},region:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"section[aria-label]\",\"section[aria-labelledby]\",\"section[title]\"]},roletype:{type:\"abstract\"},row:{type:\"structure\",attributes:{allowed:[\"aria-activedescendant\",\"aria-colindex\",\"aria-expanded\",\"aria-level\",\"aria-selected\",\"aria-rowindex\"]},owned:{one:[\"cell\",\"columnheader\",\"rowheader\",\"gridcell\"]},nameFrom:[\"author\",\"contents\"],context:[\"rowgroup\",\"grid\",\"treegrid\",\"table\"],implicit:[\"tr\"]},rowgroup:{type:\"structure\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\"]},owned:{all:[\"row\"]},nameFrom:[\"author\",\"contents\"],context:[\"grid\",\"table\"],implicit:[\"tbody\",\"thead\",\"tfoot\"]},rowheader:{type:\"structure\",attributes:{allowed:[\"aria-colindex\",\"aria-colspan\",\"aria-expanded\",\"aria-rowindex\",\"aria-rowspan\",\"aria-required\",\"aria-readonly\",\"aria-selected\",\"aria-sort\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"row\"],implicit:[\"th\"]},scrollbar:{type:\"widget\",attributes:{required:[\"aria-controls\",\"aria-valuenow\",\"aria-valuemax\",\"aria-valuemin\"],allowed:[\"aria-valuetext\",\"aria-orientation\"]},owned:null,nameFrom:[\"author\"],context:null},search:{type:\"landmark\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},searchbox:{type:\"widget\",attributes:{allowed:[\"aria-activedescendant\",\"aria-autocomplete\",\"aria-multiline\",\"aria-readonly\",\"aria-required\",\"aria-placeholder\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:['input[type=\"search\"]']},section:{nameFrom:[\"author\",\"contents\"],type:\"abstract\"},sectionhead:{nameFrom:[\"author\",\"contents\"],type:\"abstract\"},select:{nameFrom:[\"author\"],type:\"abstract\"},separator:{type:\"structure\",attributes:{allowed:[\"aria-expanded\",\"aria-orientation\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"hr\"]},slider:{type:\"widget\",attributes:{allowed:[\"aria-valuetext\",\"aria-orientation\"],required:[\"aria-valuenow\",\"aria-valuemax\",\"aria-valuemin\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:['input[type=\"range\"]']},spinbutton:{type:\"widget\",attributes:{allowed:[\"aria-valuetext\",\"aria-required\"],required:[\"aria-valuenow\",\"aria-valuemax\",\"aria-valuemin\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:['input[type=\"number\"]']},status:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:[\"output\"]},structure:{type:\"abstract\"},switch:{type:\"widget\",attributes:{required:[\"aria-checked\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null},tab:{type:\"widget\",attributes:{allowed:[\"aria-selected\",\"aria-expanded\",\"aria-setsize\",\"aria-posinset\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"tablist\"]},table:{type:\"structure\",attributes:{allowed:[\"aria-colcount\",\"aria-rowcount\"]},owned:{one:[\"rowgroup\",\"row\"]},nameFrom:[\"author\"],context:null,implicit:[\"table\"]},tablist:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\",\"aria-level\",\"aria-multiselectable\",\"aria-orientation\"]},owned:{all:[\"tab\"]},nameFrom:[\"author\"],context:null},tabpanel:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},term:{type:\"structure\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null,implicit:[\"dt\"]},text:{type:\"structure\",owned:null,nameFrom:[\"author\",\"contents\"],context:null},textbox:{type:\"widget\",attributes:{allowed:[\"aria-activedescendant\",\"aria-autocomplete\",\"aria-multiline\",\"aria-readonly\",\"aria-required\",\"aria-placeholder\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:['input[type=\"text\"]','input[type=\"email\"]','input[type=\"password\"]','input[type=\"tel\"]','input[type=\"url\"]',\"input:not([type])\",\"textarea\"]},timer:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null},toolbar:{type:\"structure\",attributes:{allowed:[\"aria-activedescendant\",\"aria-expanded\"]},owned:null,nameFrom:[\"author\"],context:null,implicit:['menu[type=\"toolbar\"]']},tooltip:{type:\"widget\",attributes:{allowed:[\"aria-expanded\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:null},tree:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-multiselectable\",\"aria-required\",\"aria-expanded\",\"aria-orientation\"]},owned:{all:[\"treeitem\"]},nameFrom:[\"author\"],context:null},treegrid:{type:\"composite\",attributes:{allowed:[\"aria-activedescendant\",\"aria-colcount\",\"aria-expanded\",\"aria-level\",\"aria-multiselectable\",\"aria-readonly\",\"aria-required\",\"aria-rowcount\",\"aria-orientation\"]},owned:{one:[\"rowgroup\",\"row\"]},nameFrom:[\"author\"],context:null},treeitem:{type:\"widget\",attributes:{allowed:[\"aria-checked\",\"aria-selected\",\"aria-expanded\",\"aria-level\",\"aria-posinset\",\"aria-setsize\"]},owned:null,nameFrom:[\"author\",\"contents\"],context:[\"group\",\"tree\"]},widget:{type:\"abstract\"},window:{nameFrom:[\"author\"],type:\"abstract\"}};var y={};commons.color=y;var z=commons.dom={},A=commons.table={},B=commons.text={};commons.utils=axe.utils;w.requiredAttr=function(a){\"use strict\";var b=w.lookupTable.role[a];return b&&b.attributes&&b.attributes.required||[]},w.allowedAttr=function(a){\"use strict\";var b=w.lookupTable.role[a],c=b&&b.attributes&&b.attributes.allowed||[],d=b&&b.attributes&&b.attributes.required||[];return c.concat(w.lookupTable.globalAttributes).concat(d)},w.validateAttr=function(a){\"use strict\";return!!w.lookupTable.attributes[a]},w.validateAttrValue=function(a,b){\"use strict\";var c,d,e=document,f=a.getAttribute(b),g=w.lookupTable.attributes[b];if(!g)return!0;switch(g.type){case\"boolean\":case\"nmtoken\":return\"string\"==typeof f&&-1!==g.values.indexOf(f.toLowerCase());case\"nmtokens\":return d=axe.utils.tokenList(f),d.reduce(function(a,b){return a&&-1!==g.values.indexOf(b)},0!==d.length);case\"idref\":return!(!f||!e.getElementById(f));case\"idrefs\":return d=axe.utils.tokenList(f),d.reduce(function(a,b){return!(!a||!e.getElementById(b))},0!==d.length);case\"string\":return!0;case\"decimal\":return!(!(c=f.match(/^[-+]?([0-9]*)\\.?([0-9]*)$/))||!c[1]&&!c[2]);case\"int\":return/^[-+]?[0-9]+$/.test(f)}},w.label=function(a){var b,c;return a.getAttribute(\"aria-labelledby\")&&(b=z.idrefs(a,\"aria-labelledby\"),c=b.map(function(a){return a?B.visible(a,!0):\"\"}).join(\" \").trim())?c:(c=a.getAttribute(\"aria-label\"),c&&(c=B.sanitize(c).trim())?c:null)},w.isValidRole=function(a){\"use strict\";return!!w.lookupTable.role[a]},w.getRolesWithNameFromContents=function(){return Object.keys(w.lookupTable.role).filter(function(a){return w.lookupTable.role[a].nameFrom&&-1!==w.lookupTable.role[a].nameFrom.indexOf(\"contents\")})},w.getRolesByType=function(a){return Object.keys(w.lookupTable.role).filter(function(b){return w.lookupTable.role[b].type===a})},w.getRoleType=function(a){var b=w.lookupTable.role[a];return b&&b.type||null},w.requiredOwned=function(a){\"use strict\";var b=null,c=w.lookupTable.role[a];return c&&(b=axe.utils.clone(c.owned)),b},w.requiredContext=function(a){\"use strict\";var b=null,c=w.lookupTable.role[a];return c&&(b=axe.utils.clone(c.context)),b},w.implicitNodes=function(a){\"use strict\";var b=null,c=w.lookupTable.role[a];return c&&c.implicit&&(b=axe.utils.clone(c.implicit)),b},w.implicitRole=function(a){\"use strict\";var b=function(b,c){var d=function(b){return axe.utils.matchesSelector(a,b)};return c.implicit&&c.implicit.some(d)&&b.push(c.name),b},c=Object.keys(w.lookupTable.role).map(function(a){var b=w.lookupTable.role[a];return{name:a,implicit:b&&b.implicit}}),d=c.reduce(b,[]);if(!d.length)return null;for(var e=a.attributes,f=[],g=0,h=e.length;g<h;g++){var i=e[g];i.name.match(/^aria-/)&&f.push(i.name)}return function(a,b){var c=function(a){return w.allowedAttr(a).reduce(function(a,c){return a+(b.indexOf(c)>-1?1:0)},0)};return a.map(function(a){return{score:c(a),name:a}}).sort(function(a,b){return b.score-a.score}).map(function(a){return a.name})}(d,f).shift()},y.Color=function(a,b,c,d){this.red=a,this.green=b,this.blue=c,this.alpha=d,this.toHexString=function(){var a=Math.round(this.red).toString(16),b=Math.round(this.green).toString(16),c=Math.round(this.blue).toString(16);return\"#\"+(this.red>15.5?a:\"0\"+a)+(this.green>15.5?b:\"0\"+b)+(this.blue>15.5?c:\"0\"+c)};var e=/^rgb\\((\\d+), (\\d+), (\\d+)\\)$/,f=/^rgba\\((\\d+), (\\d+), (\\d+), (\\d*(\\.\\d+)?)\\)/;this.parseRgbString=function(a){if(\"transparent\"===a)return this.red=0,this.green=0,this.blue=0,void(this.alpha=0);var b=a.match(e);return b?(this.red=parseInt(b[1],10),this.green=parseInt(b[2],10),this.blue=parseInt(b[3],10),void(this.alpha=1)):(b=a.match(f),b?(this.red=parseInt(b[1],10),this.green=parseInt(b[2],10),this.blue=parseInt(b[3],10),void(this.alpha=parseFloat(b[4]))):void 0)},this.getRelativeLuminance=function(){var a=this.red/255,b=this.green/255,c=this.blue/255;return.2126*(a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4))+.7152*(b<=.03928?b/12.92:Math.pow((b+.055)/1.055,2.4))+.0722*(c<=.03928?c/12.92:Math.pow((c+.055)/1.055,2.4))}},y.flattenColors=function(a,b){var c=a.alpha,d=(1-c)*b.red+c*a.red,e=(1-c)*b.green+c*a.green,f=(1-c)*b.blue+c*a.blue,g=a.alpha+b.alpha*(1-a.alpha);return new y.Color(d,e,f,g)},y.getContrast=function(a,b){if(!b||!a)return null;b.alpha<1&&(b=y.flattenColors(b,a));var c=a.getRelativeLuminance(),d=b.getRelativeLuminance();return(Math.max(d,c)+.05)/(Math.min(d,c)+.05)},y.hasValidContrastRatio=function(a,b,c,d){var e=y.getContrast(a,b),f=d&&Math.ceil(72*c)/96<14||!d&&Math.ceil(72*c)/96<18,g=f?4.5:3;return{isValid:e>g,contrastRatio:e,expectedContrastRatio:g}},y.elementIsDistinct=b;var C=[\"IMG\",\"CANVAS\",\"OBJECT\",\"IFRAME\",\"VIDEO\",\"SVG\"];y.getCoords=function(a){var b=void 0,c=void 0;if(!(a.left>window.innerWidth||a.top>window.innerHeight))return b=Math.min(Math.ceil(a.left+a.width/2),window.innerWidth-1),c=Math.min(Math.ceil(a.top+a.height/2),window.innerHeight-1),{x:b,y:c}},y.getRectStack=function(a){var b=y.getCoords(a.getBoundingClientRect());if(b){var c=Array.from(a.getClientRects()),d=Array.from(document.elementsFromPoint(b.x,b.y));if(c&&c.length>1){var e=c.filter(function(a){return a.width&&a.width>0}).map(function(a){var b=y.getCoords(a);if(b)return Array.from(document.elementsFromPoint(b.x,b.y))});return e.splice(0,0,d),e}return[d]}return null},y.filteredRectStack=function(a){var b=y.getRectStack(a);if(b&&1===b.length)return b[0];if(b&&b.length>1){var c=b.shift(),d=void 0;return b.forEach(function(e,f){if(0!==f){var g=b[f-1],h=b[f];d=g.every(function(a,b){return a===h[b]})||c.includes(a)}}),d?b[0]:(axe.commons.color.incompleteData.set(\"bgColor\",\"elmPartiallyObscuring\"),null)}return axe.commons.color.incompleteData.set(\"bgColor\",\"outsideViewport\"),null},y.getBackgroundStack=function(a){var b=y.filteredRectStack(a);if(null===b)return null;b=h(b,a),b=z.reduceToElementsBelowFloating(b,a),b=i(b);var c=b.indexOf(a);return f(c,b,a)>=.99?(axe.commons.color.incompleteData.set(\"bgColor\",\"bgOverlap\"),null):-1!==c?b:null},y.getBackgroundColor=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];if(!0!==(arguments.length>2&&void 0!==arguments[2]&&arguments[2])){var e=a.clientHeight-2>=2*window.innerHeight;a.scrollIntoView(e)}var f=[],h=y.getBackgroundStack(a);if((h||[]).some(function(e){var h=window.getComputedStyle(e),i=d(e,h);return g(a,e,i)||c(e,h)?(f=null,b.push(e),!0):0!==i.alpha&&(b.push(e),f.push(i),1===i.alpha)}),null!==f&&null!==h){f.push(new y.Color(255,255,255,1));return f.reduce(y.flattenColors)}return null},z.isOpaque=function(a){var b=window.getComputedStyle(a);return c(a,b)||1===d(a,b).alpha},y.getForegroundColor=function(a,b){var c=window.getComputedStyle(a),d=new y.Color;d.parseRgbString(c.getPropertyValue(\"color\"));var e=c.getPropertyValue(\"opacity\");if(d.alpha=d.alpha*e,1===d.alpha)return d;var f=y.getBackgroundColor(a,[],b);if(null===f){var g=axe.commons.color.incompleteData.get(\"bgColor\");return axe.commons.color.incompleteData.set(\"fgColor\",g),null}return y.flattenColors(d,f)},y.incompleteData=function(){var a={};return{set:function(b,c){if(\"string\"!=typeof b)throw new Error(\"Incomplete data: key must be a string\");return c&&(a[b]=c),a[b]},get:function(b){return a[b]},clear:function(){a={}}}}(),z.reduceToElementsBelowFloating=function(a,b){var c,d,e,f=[\"fixed\",\"sticky\"],g=[],h=!1;for(c=0;c<a.length;++c)d=a[c],d===b&&(h=!0),e=window.getComputedStyle(d),h||-1===f.indexOf(e.position)?g.push(d):g=[];return g},z.findUp=function(a,b){\"use strict\";var c,d=document.querySelectorAll(b);if(!d.length)return null;for(d=axe.utils.toArray(d),c=a.parentNode;c&&-1===d.indexOf(c);)c=c.parentNode;return c},z.getElementByReference=function(a,b){\"use strict\";var c,d=a.getAttribute(b),e=document;if(d&&\"#\"===d.charAt(0)){if(d=d.substring(1),c=e.getElementById(d))return c;if(c=e.getElementsByName(d),c.length)return c[0]}return null},z.getElementCoordinates=function(a){\"use strict\";var b=z.getScrollOffset(document),c=b.left,d=b.top,e=a.getBoundingClientRect();return{top:e.top+d,right:e.right+c,bottom:e.bottom+d,left:e.left+c,width:e.right-e.left,height:e.bottom-e.top}},z.getScrollOffset=function(a){\"use strict\";if(!a.nodeType&&a.document&&(a=a.document),9===a.nodeType){var b=a.documentElement,c=a.body;return{left:b&&b.scrollLeft||c&&c.scrollLeft||0,top:b&&b.scrollTop||c&&c.scrollTop||0}}return{left:a.scrollLeft,top:a.scrollTop}},z.getViewportSize=function(a){\"use strict\";var b,c=a.document,d=c.documentElement;return a.innerWidth?{width:a.innerWidth,height:a.innerHeight}:d?{width:d.clientWidth,height:d.clientHeight}:(b=c.body,{width:b.clientWidth,height:b.clientHeight})},z.hasContent=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];if(a.textContent.trim()||w.label(a))return!0;for(var c=a.querySelectorAll(\"*\"),d=0;d<c.length;d++)if(-1===b.indexOf(c[d])&&w.label(c[d])||z.isVisualContent(c[d]))return!0;return!1},z.idrefs=function(a,b){\"use strict\";var c,d,e=document,f=[],g=a.getAttribute(b);if(g)for(g=axe.utils.tokenList(g),c=0,d=g.length;c<d;c++)f.push(e.getElementById(g[c]));return f},z.isFocusable=function(a){\"use strict\";if(z.isNativelyFocusable(a))return!0;var b=a.getAttribute(\"tabindex\");return!(!b||isNaN(parseInt(b,10)))},z.isNativelyFocusable=function(a){\"use strict\";if(!a||a.disabled||!z.isVisible(a)&&\"AREA\"!==a.nodeName.toUpperCase())return!1;switch(a.nodeName.toUpperCase()){case\"A\":case\"AREA\":if(a.href)return!0;break;case\"INPUT\":return\"hidden\"!==a.type;case\"TEXTAREA\":case\"SELECT\":case\"DETAILS\":case\"BUTTON\":return!0}return!1},z.isHTML5=function(a){var b=a.doctype;return null!==b&&(\"html\"===b.name&&!b.publicId&&!b.systemId)};var D=[\"block\",\"list-item\",\"table\",\"flex\",\"grid\",\"inline-block\"];z.isInTextBlock=function(a){\"use strict\";if(k(a))return!1;for(var b=a.parentNode;1===b.nodeType&&!k(b);)b=b.parentNode;var c=\"\",d=\"\",e=0;return j(b,function(b){if(2===e)return!1;if(3===b.nodeType&&(c+=b.nodeValue),1===b.nodeType){var f=(b.nodeName||\"\").toUpperCase();if(-1!==[\"BR\",\"HR\"].indexOf(f))0===e?(c=\"\",d=\"\"):e=2;else{if(\"none\"===b.style.display||\"hidden\"===b.style.overflow||-1===[\"\",null,\"none\"].indexOf(b.style.float)||-1===[\"\",null,\"relative\"].indexOf(b.style.position))return!1;if(\"A\"===f&&b.href||\"link\"===(b.getAttribute(\"role\")||\"\").toLowerCase())return b===a&&(e=1),d+=b.textContent,!1}}}),c=axe.commons.text.sanitize(c),d=axe.commons.text.sanitize(d),c.length>d.length},z.isNode=function(a){\"use strict\";return a instanceof Node},z.isOffscreen=function(a){\"use strict\";var b,c=document.documentElement,d=window.getComputedStyle(document.body||c).getPropertyValue(\"direction\"),e=z.getElementCoordinates(a);if(e.bottom<0&&function(a,b){for(a=a.parentNode;\"html\"!==a.nodeName.toLowerCase();){if(a.scrollTop&&(b+=a.scrollTop)>=0)return!1;a=a.parentNode}return!0}(a,e.bottom))return!0;if(0===e.left&&0===e.right)return!1;if(\"ltr\"===d){if(e.right<=0)return!0}else if(b=Math.max(c.scrollWidth,z.getViewportSize(window).width),e.left>=b)return!0;return!1},z.isVisible=function(a,b,c){\"use strict\";var d,e=a.nodeName.toUpperCase(),f=a.parentNode;return 9===a.nodeType||null!==(d=window.getComputedStyle(a,null))&&(!(\"none\"===d.getPropertyValue(\"display\")||\"STYLE\"===e.toUpperCase()||\"SCRIPT\"===e.toUpperCase()||!b&&l(d.getPropertyValue(\"clip\"))||!c&&(\"hidden\"===d.getPropertyValue(\"visibility\")||!b&&z.isOffscreen(a))||b&&\"true\"===a.getAttribute(\"aria-hidden\"))&&(!!f&&z.isVisible(f,b,!0)))};var E=[\"checkbox\",\"img\",\"radio\",\"range\",\"slider\",\"spinbutton\",\"textbox\"];z.isVisualContent=function(a){var b=a.getAttribute(\"role\");if(b)return-1!==E.indexOf(b);switch(a.tagName.toUpperCase()){case\"IMG\":case\"IFRAME\":case\"OBJECT\":case\"VIDEO\":case\"AUDIO\":case\"CANVAS\":case\"SVG\":case\"MATH\":case\"BUTTON\":case\"SELECT\":case\"TEXTAREA\":case\"KEYGEN\":case\"PROGRESS\":case\"METER\":return!0;case\"INPUT\":return\"hidden\"!==a.type;default:return!1}},z.visuallyContains=function(a,b){var c=a.getBoundingClientRect(),d={top:c.top+.01,bottom:c.bottom-.01,left:c.left+.01,right:c.right-.01},e=b.getBoundingClientRect(),f=e.top,g=e.left,h={top:f-b.scrollTop,bottom:f-b.scrollTop+b.scrollHeight,left:g-b.scrollLeft,right:g-b.scrollLeft+b.scrollWidth},i=window.getComputedStyle(b);return\"inline\"===i.getPropertyValue(\"display\")||!(d.left<h.left&&d.left<e.left||d.top<h.top&&d.top<e.top||d.right>h.right&&d.right>e.right||d.bottom>h.bottom&&d.bottom>e.bottom)&&(!(d.right>e.right||d.bottom>e.bottom)||(\"scroll\"===i.overflow||\"auto\"===i.overflow||\"hidden\"===i.overflow||b instanceof HTMLBodyElement||b instanceof HTMLHtmlElement))},z.visuallyOverlaps=function(a,b){var c=b.getBoundingClientRect(),d=c.top,e=c.left,f={top:d-b.scrollTop,bottom:d-b.scrollTop+b.scrollHeight,left:e-b.scrollLeft,right:e-b.scrollLeft+b.scrollWidth};if(a.left>f.right&&a.left>c.right||a.top>f.bottom&&a.top>c.bottom||a.right<f.left&&a.right<c.left||a.bottom<f.top&&a.bottom<c.top)return!1;var g=window.getComputedStyle(b);return!(a.left>c.right||a.top>c.bottom)||(\"scroll\"===g.overflow||\"auto\"===g.overflow||b instanceof HTMLBodyElement||b instanceof HTMLHtmlElement)},A.getAllCells=function(a){var b,c,d,e,f=[];for(b=0,d=a.rows.length;b<d;b++)for(c=0,e=a.rows[b].cells.length;c<e;c++)f.push(a.rows[b].cells[c]);return f},A.getCellPosition=function(a,b){var c,d;for(b||(b=A.toGrid(z.findUp(a,\"table\"))),c=0;c<b.length;c++)if(b[c]&&-1!==(d=b[c].indexOf(a)))return{x:d,y:c}},A.getHeaders=function(a){if(a.hasAttribute(\"headers\"))return commons.dom.idrefs(a,\"headers\");var b=commons.table.toGrid(commons.dom.findUp(a,\"table\")),c=commons.table.getCellPosition(a,b);return[].concat(A.traverse(\"left\",c,b).filter(function(a){return A.isRowHeader(a)}),A.traverse(\"up\",c,b).filter(function(a){return A.isColumnHeader(a)})).reverse()},A.getScope=function(a){var b=a.getAttribute(\"scope\"),c=a.getAttribute(\"role\");if(a instanceof Element==!1||-1===[\"TD\",\"TH\"].indexOf(a.nodeName.toUpperCase()))throw new TypeError(\"Expected TD or TH element\");if(\"columnheader\"===c)return\"col\";if(\"rowheader\"===c)return\"row\";if(\"col\"===b||\"row\"===b)return b;if(\"TH\"!==a.nodeName.toUpperCase())return!1;var d=A.toGrid(z.findUp(a,\"table\")),e=A.getCellPosition(a);return d[e.y].reduce(function(a,b){return a&&\"TH\"===b.nodeName.toUpperCase()},!0)?\"col\":d.map(function(a){return a[e.x]}).reduce(function(a,b){return a&&\"TH\"===b.nodeName.toUpperCase()},!0)?\"row\":\"auto\"},A.isColumnHeader=function(a){return-1!==[\"col\",\"auto\"].indexOf(A.getScope(a))},A.isDataCell=function(a){return!(!a.children.length&&!a.textContent.trim())&&\"TD\"===a.nodeName.toUpperCase()},A.isDataTable=function(a){var b=a.getAttribute(\"role\");if((\"presentation\"===b||\"none\"===b)&&!z.isFocusable(a))return!1;if(\"true\"===a.getAttribute(\"contenteditable\")||z.findUp(a,'[contenteditable=\"true\"]'))return!0;if(\"grid\"===b||\"treegrid\"===b||\"table\"===b)return!0;if(\"landmark\"===commons.aria.getRoleType(b))return!0;if(\"0\"===a.getAttribute(\"datatable\"))return!1;if(a.getAttribute(\"summary\"))return!0;if(a.tHead||a.tFoot||a.caption)return!0;for(var c=0,d=a.children.length;c<d;c++)if(\"COLGROUP\"===a.children[c].nodeName.toUpperCase())return!0;for(var e,f,g=0,h=a.rows.length,i=!1,j=0;j<h;j++){e=a.rows[j];for(var k=0,l=e.cells.length;k<l;k++){if(f=e.cells[k],\"TH\"===f.nodeName.toUpperCase())return!0;if(i||f.offsetWidth===f.clientWidth&&f.offsetHeight===f.clientHeight||(i=!0),f.getAttribute(\"scope\")||f.getAttribute(\"headers\")||f.getAttribute(\"abbr\"))return!0;if(-1!==[\"columnheader\",\"rowheader\"].indexOf(f.getAttribute(\"role\")))return!0;if(1===f.children.length&&\"ABBR\"===f.children[0].nodeName.toUpperCase())return!0;g++}}if(a.getElementsByTagName(\"table\").length)return!1;if(h<2)return!1;var m=a.rows[Math.ceil(h/2)];if(1===m.cells.length&&1===m.cells[0].colSpan)return!1;if(m.cells.length>=5)return!0;if(i)return!0;var n,o;for(j=0;j<h;j++){if(e=a.rows[j],n&&n!==window.getComputedStyle(e).getPropertyValue(\"background-color\"))return!0;if(n=window.getComputedStyle(e).getPropertyValue(\"background-color\"),o&&o!==window.getComputedStyle(e).getPropertyValue(\"background-image\"))return!0;o=window.getComputedStyle(e).getPropertyValue(\"background-image\")}return h>=20||!(z.getElementCoordinates(a).width>.95*z.getViewportSize(window).width)&&(!(g<10)&&!a.querySelector(\"object, embed, iframe, applet\"))},A.isHeader=function(a){if(A.isColumnHeader(a)||A.isRowHeader(a))return!0;if(a.getAttribute(\"id\")){var b=axe.utils.escapeSelector(a.getAttribute(\"id\"));return!!document.querySelector('[headers~=\"'+b+'\"]')}return!1},A.isRowHeader=function(a){return[\"row\",\"auto\"].includes(A.getScope(a))},A.toGrid=function(a){for(var b=[],c=a.rows,d=0,e=c.length;d<e;d++){var f=c[d].cells;b[d]=b[d]||[];for(var g=0,h=0,i=f.length;h<i;h++)for(var j=0;j<f[h].colSpan;j++){for(var k=0;k<f[h].rowSpan;k++){for(b[d+k]=b[d+k]||[];b[d+k][g];)g++;b[d+k][g]=f[h]}g++}}return b},A.toArray=A.toGrid,function(a){var b=function a(b,c,d,e){var f,g=d[c.y]?d[c.y][c.x]:void 0;return g?\"function\"==typeof e&&!0===(f=e(g,c,d))?[g]:(f=a(b,{x:c.x+b.x,y:c.y+b.y},d,e),f.unshift(g),f):[]};a.traverse=function(a,c,d,e){if(Array.isArray(c)&&(e=d,d=c,c={x:0,y:0}),\"string\"==typeof a)switch(a){case\"left\":a={x:-1,y:0};break;case\"up\":a={x:0,y:-1};break;case\"right\":a={x:1,y:0};break;case\"down\":a={x:0,y:1}}return b(a,{x:c.x+a.x,y:c.y+a.y},d,e)}}(A);var F={submit:\"Submit\",reset:\"Reset\"},G=[\"text\",\"search\",\"tel\",\"url\",\"email\",\"date\",\"time\",\"number\",\"range\",\"color\"],H=[\"A\",\"EM\",\"STRONG\",\"SMALL\",\"MARK\",\"ABBR\",\"DFN\",\"I\",\"B\",\"S\",\"U\",\"CODE\",\"VAR\",\"SAMP\",\"KBD\",\"SUP\",\"SUB\",\"Q\",\"CITE\",\"SPAN\",\"BDO\",\"BDI\",\"BR\",\"WBR\",\"INS\",\"DEL\",\"IMG\",\"EMBED\",\"OBJECT\",\"IFRAME\",\"MAP\",\"AREA\",\"SCRIPT\",\"NOSCRIPT\",\"RUBY\",\"VIDEO\",\"AUDIO\",\"INPUT\",\"TEXTAREA\",\"SELECT\",\"BUTTON\",\"LABEL\",\"OUTPUT\",\"DATALIST\",\"KEYGEN\",\"PROGRESS\",\"COMMAND\",\"CANVAS\",\"TIME\",\"METER\"];B.accessibleText=function(a,b){function c(a,b,c){for(var d,e=a.childNodes,f=\"\",h=0;h<e.length;h++)d=e[h],3===d.nodeType?f+=d.textContent:1===d.nodeType&&(-1===H.indexOf(d.nodeName.toUpperCase())&&(f+=\" \"),f+=g(e[h],b,c));return f}function d(a){return axe.commons.table.isDataTable(a)||1!==axe.commons.table.getAllCells(a).length?\"\":c(a,!1,!1).trim()}function e(a,b,e){var f=\"\",h=a.nodeName.toUpperCase();if(p(a)&&(f=c(a,!1,!1)||\"\",v(f)))return f;if(\"FIGURE\"===h&&(f=s(a,\"figcaption\"),v(f)))return f;if(\"TABLE\"===h){if(f=s(a,\"caption\"),v(f))return f;if(f=a.getAttribute(\"title\")||a.getAttribute(\"summary\")||d(a)||\"\",v(f))return f}if(u(a))return a.getAttribute(\"alt\")||\"\";if(o(a)&&!e){if(n(a))return a.value||a.title||F[a.type]||\"\";var i=m(a);if(i)return g(i,b,!0)}return\"\"}function f(a,b,c){return!b&&a.hasAttribute(\"aria-labelledby\")?B.sanitize(z.idrefs(a,\"aria-labelledby\").map(function(b){return a===b&&h.pop(),g(b,!0,a!==b)}).join(\" \")):c&&t(a)||!a.hasAttribute(\"aria-label\")?\"\":B.sanitize(a.getAttribute(\"aria-label\"))}var g,h=[];return g=function(a,b,d){\"use strict\";var g;if(null===a||-1!==h.indexOf(a))return\"\";if(!b&&!z.isVisible(a,!0))return\"\";h.push(a);var i=a.getAttribute(\"role\");return g=f(a,b,d),v(g)?g:(g=e(a,b,d),v(g)?g:d&&(g=r(a),v(g))?g:q(a)||i&&-1===w.getRolesWithNameFromContents().indexOf(i)||(g=c(a,b,d),!v(g))?a.hasAttribute(\"title\")?a.getAttribute(\"title\"):\"\":g)},B.sanitize(g(a,b))},B.label=function(a){var b,c;if(c=w.label(a))return c;if(a.getAttribute(\"id\")){var d=axe.commons.utils.escapeSelector(a.getAttribute(\"id\"));if(b=document.querySelector('label[for=\"'+d+'\"]'),c=b&&B.visible(b,!0))return c}return b=z.findUp(a,\"label\"),(c=b&&B.visible(b,!0))||null},B.sanitize=function(a){\"use strict\";return a.replace(/\\r\\n/g,\"\\n\").replace(/\\u00A0/g,\" \").replace(/[\\s]{2,}/g,\" \").trim()},B.visible=function(a,b,c){\"use strict\";var d,e,f=a.childNodes,g=f.length,h=\"\";for(d=0;d<g;d++)e=f[d],3===e.nodeType?e.nodeValue&&z.isVisible(a,b)&&(h+=e.nodeValue):c||(h+=B.visible(e,b));return B.sanitize(h)},axe.utils.toArray=function(a){\"use strict\";return Array.prototype.slice.call(a)},axe.utils.tokenList=function(a){\"use strict\";return a.trim().replace(/\\s{2,}/g,\" \").split(\" \")}\n;var I=[\"aa\",\"ab\",\"ae\",\"af\",\"ak\",\"am\",\"an\",\"ar\",\"as\",\"av\",\"ay\",\"az\",\"ba\",\"be\",\"bg\",\"bh\",\"bi\",\"bm\",\"bn\",\"bo\",\"br\",\"bs\",\"ca\",\"ce\",\"ch\",\"co\",\"cr\",\"cs\",\"cu\",\"cv\",\"cy\",\"da\",\"de\",\"dv\",\"dz\",\"ee\",\"el\",\"en\",\"eo\",\"es\",\"et\",\"eu\",\"fa\",\"ff\",\"fi\",\"fj\",\"fo\",\"fr\",\"fy\",\"ga\",\"gd\",\"gl\",\"gn\",\"gu\",\"gv\",\"ha\",\"he\",\"hi\",\"ho\",\"hr\",\"ht\",\"hu\",\"hy\",\"hz\",\"ia\",\"id\",\"ie\",\"ig\",\"ii\",\"ik\",\"in\",\"io\",\"is\",\"it\",\"iu\",\"iw\",\"ja\",\"ji\",\"jv\",\"jw\",\"ka\",\"kg\",\"ki\",\"kj\",\"kk\",\"kl\",\"km\",\"kn\",\"ko\",\"kr\",\"ks\",\"ku\",\"kv\",\"kw\",\"ky\",\"la\",\"lb\",\"lg\",\"li\",\"ln\",\"lo\",\"lt\",\"lu\",\"lv\",\"mg\",\"mh\",\"mi\",\"mk\",\"ml\",\"mn\",\"mo\",\"mr\",\"ms\",\"mt\",\"my\",\"na\",\"nb\",\"nd\",\"ne\",\"ng\",\"nl\",\"nn\",\"no\",\"nr\",\"nv\",\"ny\",\"oc\",\"oj\",\"om\",\"or\",\"os\",\"pa\",\"pi\",\"pl\",\"ps\",\"pt\",\"qu\",\"rm\",\"rn\",\"ro\",\"ru\",\"rw\",\"sa\",\"sc\",\"sd\",\"se\",\"sg\",\"sh\",\"si\",\"sk\",\"sl\",\"sm\",\"sn\",\"so\",\"sq\",\"sr\",\"ss\",\"st\",\"su\",\"sv\",\"sw\",\"ta\",\"te\",\"tg\",\"th\",\"ti\",\"tk\",\"tl\",\"tn\",\"to\",\"tr\",\"ts\",\"tt\",\"tw\",\"ty\",\"ug\",\"uk\",\"ur\",\"uz\",\"ve\",\"vi\",\"vo\",\"wa\",\"wo\",\"xh\",\"yi\",\"yo\",\"za\",\"zh\",\"zu\",\"aaa\",\"aab\",\"aac\",\"aad\",\"aae\",\"aaf\",\"aag\",\"aah\",\"aai\",\"aak\",\"aal\",\"aam\",\"aan\",\"aao\",\"aap\",\"aaq\",\"aas\",\"aat\",\"aau\",\"aav\",\"aaw\",\"aax\",\"aaz\",\"aba\",\"abb\",\"abc\",\"abd\",\"abe\",\"abf\",\"abg\",\"abh\",\"abi\",\"abj\",\"abl\",\"abm\",\"abn\",\"abo\",\"abp\",\"abq\",\"abr\",\"abs\",\"abt\",\"abu\",\"abv\",\"abw\",\"abx\",\"aby\",\"abz\",\"aca\",\"acb\",\"acd\",\"ace\",\"acf\",\"ach\",\"aci\",\"ack\",\"acl\",\"acm\",\"acn\",\"acp\",\"acq\",\"acr\",\"acs\",\"act\",\"acu\",\"acv\",\"acw\",\"acx\",\"acy\",\"acz\",\"ada\",\"adb\",\"add\",\"ade\",\"adf\",\"adg\",\"adh\",\"adi\",\"adj\",\"adl\",\"adn\",\"ado\",\"adp\",\"adq\",\"adr\",\"ads\",\"adt\",\"adu\",\"adw\",\"adx\",\"ady\",\"adz\",\"aea\",\"aeb\",\"aec\",\"aed\",\"aee\",\"aek\",\"ael\",\"aem\",\"aen\",\"aeq\",\"aer\",\"aes\",\"aeu\",\"aew\",\"aey\",\"aez\",\"afa\",\"afb\",\"afd\",\"afe\",\"afg\",\"afh\",\"afi\",\"afk\",\"afn\",\"afo\",\"afp\",\"afs\",\"aft\",\"afu\",\"afz\",\"aga\",\"agb\",\"agc\",\"agd\",\"age\",\"agf\",\"agg\",\"agh\",\"agi\",\"agj\",\"agk\",\"agl\",\"agm\",\"agn\",\"ago\",\"agp\",\"agq\",\"agr\",\"ags\",\"agt\",\"agu\",\"agv\",\"agw\",\"agx\",\"agy\",\"agz\",\"aha\",\"ahb\",\"ahg\",\"ahh\",\"ahi\",\"ahk\",\"ahl\",\"ahm\",\"ahn\",\"aho\",\"ahp\",\"ahr\",\"ahs\",\"aht\",\"aia\",\"aib\",\"aic\",\"aid\",\"aie\",\"aif\",\"aig\",\"aih\",\"aii\",\"aij\",\"aik\",\"ail\",\"aim\",\"ain\",\"aio\",\"aip\",\"aiq\",\"air\",\"ais\",\"ait\",\"aiw\",\"aix\",\"aiy\",\"aja\",\"ajg\",\"aji\",\"ajn\",\"ajp\",\"ajt\",\"aju\",\"ajw\",\"ajz\",\"akb\",\"akc\",\"akd\",\"ake\",\"akf\",\"akg\",\"akh\",\"aki\",\"akj\",\"akk\",\"akl\",\"akm\",\"ako\",\"akp\",\"akq\",\"akr\",\"aks\",\"akt\",\"aku\",\"akv\",\"akw\",\"akx\",\"aky\",\"akz\",\"ala\",\"alc\",\"ald\",\"ale\",\"alf\",\"alg\",\"alh\",\"ali\",\"alj\",\"alk\",\"all\",\"alm\",\"aln\",\"alo\",\"alp\",\"alq\",\"alr\",\"als\",\"alt\",\"alu\",\"alv\",\"alw\",\"alx\",\"aly\",\"alz\",\"ama\",\"amb\",\"amc\",\"ame\",\"amf\",\"amg\",\"ami\",\"amj\",\"amk\",\"aml\",\"amm\",\"amn\",\"amo\",\"amp\",\"amq\",\"amr\",\"ams\",\"amt\",\"amu\",\"amv\",\"amw\",\"amx\",\"amy\",\"amz\",\"ana\",\"anb\",\"anc\",\"and\",\"ane\",\"anf\",\"ang\",\"anh\",\"ani\",\"anj\",\"ank\",\"anl\",\"anm\",\"ann\",\"ano\",\"anp\",\"anq\",\"anr\",\"ans\",\"ant\",\"anu\",\"anv\",\"anw\",\"anx\",\"any\",\"anz\",\"aoa\",\"aob\",\"aoc\",\"aod\",\"aoe\",\"aof\",\"aog\",\"aoh\",\"aoi\",\"aoj\",\"aok\",\"aol\",\"aom\",\"aon\",\"aor\",\"aos\",\"aot\",\"aou\",\"aox\",\"aoz\",\"apa\",\"apb\",\"apc\",\"apd\",\"ape\",\"apf\",\"apg\",\"aph\",\"api\",\"apj\",\"apk\",\"apl\",\"apm\",\"apn\",\"apo\",\"app\",\"apq\",\"apr\",\"aps\",\"apt\",\"apu\",\"apv\",\"apw\",\"apx\",\"apy\",\"apz\",\"aqa\",\"aqc\",\"aqd\",\"aqg\",\"aql\",\"aqm\",\"aqn\",\"aqp\",\"aqr\",\"aqt\",\"aqz\",\"arb\",\"arc\",\"ard\",\"are\",\"arh\",\"ari\",\"arj\",\"ark\",\"arl\",\"arn\",\"aro\",\"arp\",\"arq\",\"arr\",\"ars\",\"art\",\"aru\",\"arv\",\"arw\",\"arx\",\"ary\",\"arz\",\"asa\",\"asb\",\"asc\",\"asd\",\"ase\",\"asf\",\"asg\",\"ash\",\"asi\",\"asj\",\"ask\",\"asl\",\"asn\",\"aso\",\"asp\",\"asq\",\"asr\",\"ass\",\"ast\",\"asu\",\"asv\",\"asw\",\"asx\",\"asy\",\"asz\",\"ata\",\"atb\",\"atc\",\"atd\",\"ate\",\"atg\",\"ath\",\"ati\",\"atj\",\"atk\",\"atl\",\"atm\",\"atn\",\"ato\",\"atp\",\"atq\",\"atr\",\"ats\",\"att\",\"atu\",\"atv\",\"atw\",\"atx\",\"aty\",\"atz\",\"aua\",\"aub\",\"auc\",\"aud\",\"aue\",\"auf\",\"aug\",\"auh\",\"aui\",\"auj\",\"auk\",\"aul\",\"aum\",\"aun\",\"auo\",\"aup\",\"auq\",\"aur\",\"aus\",\"aut\",\"auu\",\"auw\",\"aux\",\"auy\",\"auz\",\"avb\",\"avd\",\"avi\",\"avk\",\"avl\",\"avm\",\"avn\",\"avo\",\"avs\",\"avt\",\"avu\",\"avv\",\"awa\",\"awb\",\"awc\",\"awd\",\"awe\",\"awg\",\"awh\",\"awi\",\"awk\",\"awm\",\"awn\",\"awo\",\"awr\",\"aws\",\"awt\",\"awu\",\"awv\",\"aww\",\"awx\",\"awy\",\"axb\",\"axe\",\"axg\",\"axk\",\"axl\",\"axm\",\"axx\",\"aya\",\"ayb\",\"ayc\",\"ayd\",\"aye\",\"ayg\",\"ayh\",\"ayi\",\"ayk\",\"ayl\",\"ayn\",\"ayo\",\"ayp\",\"ayq\",\"ayr\",\"ays\",\"ayt\",\"ayu\",\"ayx\",\"ayy\",\"ayz\",\"aza\",\"azb\",\"azc\",\"azd\",\"azg\",\"azj\",\"azm\",\"azn\",\"azo\",\"azt\",\"azz\",\"baa\",\"bab\",\"bac\",\"bad\",\"bae\",\"baf\",\"bag\",\"bah\",\"bai\",\"baj\",\"bal\",\"ban\",\"bao\",\"bap\",\"bar\",\"bas\",\"bat\",\"bau\",\"bav\",\"baw\",\"bax\",\"bay\",\"baz\",\"bba\",\"bbb\",\"bbc\",\"bbd\",\"bbe\",\"bbf\",\"bbg\",\"bbh\",\"bbi\",\"bbj\",\"bbk\",\"bbl\",\"bbm\",\"bbn\",\"bbo\",\"bbp\",\"bbq\",\"bbr\",\"bbs\",\"bbt\",\"bbu\",\"bbv\",\"bbw\",\"bbx\",\"bby\",\"bbz\",\"bca\",\"bcb\",\"bcc\",\"bcd\",\"bce\",\"bcf\",\"bcg\",\"bch\",\"bci\",\"bcj\",\"bck\",\"bcl\",\"bcm\",\"bcn\",\"bco\",\"bcp\",\"bcq\",\"bcr\",\"bcs\",\"bct\",\"bcu\",\"bcv\",\"bcw\",\"bcy\",\"bcz\",\"bda\",\"bdb\",\"bdc\",\"bdd\",\"bde\",\"bdf\",\"bdg\",\"bdh\",\"bdi\",\"bdj\",\"bdk\",\"bdl\",\"bdm\",\"bdn\",\"bdo\",\"bdp\",\"bdq\",\"bdr\",\"bds\",\"bdt\",\"bdu\",\"bdv\",\"bdw\",\"bdx\",\"bdy\",\"bdz\",\"bea\",\"beb\",\"bec\",\"bed\",\"bee\",\"bef\",\"beg\",\"beh\",\"bei\",\"bej\",\"bek\",\"bem\",\"beo\",\"bep\",\"beq\",\"ber\",\"bes\",\"bet\",\"beu\",\"bev\",\"bew\",\"bex\",\"bey\",\"bez\",\"bfa\",\"bfb\",\"bfc\",\"bfd\",\"bfe\",\"bff\",\"bfg\",\"bfh\",\"bfi\",\"bfj\",\"bfk\",\"bfl\",\"bfm\",\"bfn\",\"bfo\",\"bfp\",\"bfq\",\"bfr\",\"bfs\",\"bft\",\"bfu\",\"bfw\",\"bfx\",\"bfy\",\"bfz\",\"bga\",\"bgb\",\"bgc\",\"bgd\",\"bge\",\"bgf\",\"bgg\",\"bgi\",\"bgj\",\"bgk\",\"bgl\",\"bgm\",\"bgn\",\"bgo\",\"bgp\",\"bgq\",\"bgr\",\"bgs\",\"bgt\",\"bgu\",\"bgv\",\"bgw\",\"bgx\",\"bgy\",\"bgz\",\"bha\",\"bhb\",\"bhc\",\"bhd\",\"bhe\",\"bhf\",\"bhg\",\"bhh\",\"bhi\",\"bhj\",\"bhk\",\"bhl\",\"bhm\",\"bhn\",\"bho\",\"bhp\",\"bhq\",\"bhr\",\"bhs\",\"bht\",\"bhu\",\"bhv\",\"bhw\",\"bhx\",\"bhy\",\"bhz\",\"bia\",\"bib\",\"bic\",\"bid\",\"bie\",\"bif\",\"big\",\"bij\",\"bik\",\"bil\",\"bim\",\"bin\",\"bio\",\"bip\",\"biq\",\"bir\",\"bit\",\"biu\",\"biv\",\"biw\",\"bix\",\"biy\",\"biz\",\"bja\",\"bjb\",\"bjc\",\"bjd\",\"bje\",\"bjf\",\"bjg\",\"bjh\",\"bji\",\"bjj\",\"bjk\",\"bjl\",\"bjm\",\"bjn\",\"bjo\",\"bjp\",\"bjq\",\"bjr\",\"bjs\",\"bjt\",\"bju\",\"bjv\",\"bjw\",\"bjx\",\"bjy\",\"bjz\",\"bka\",\"bkb\",\"bkc\",\"bkd\",\"bkf\",\"bkg\",\"bkh\",\"bki\",\"bkj\",\"bkk\",\"bkl\",\"bkm\",\"bkn\",\"bko\",\"bkp\",\"bkq\",\"bkr\",\"bks\",\"bkt\",\"bku\",\"bkv\",\"bkw\",\"bkx\",\"bky\",\"bkz\",\"bla\",\"blb\",\"blc\",\"bld\",\"ble\",\"blf\",\"blg\",\"blh\",\"bli\",\"blj\",\"blk\",\"bll\",\"blm\",\"bln\",\"blo\",\"blp\",\"blq\",\"blr\",\"bls\",\"blt\",\"blv\",\"blw\",\"blx\",\"bly\",\"blz\",\"bma\",\"bmb\",\"bmc\",\"bmd\",\"bme\",\"bmf\",\"bmg\",\"bmh\",\"bmi\",\"bmj\",\"bmk\",\"bml\",\"bmm\",\"bmn\",\"bmo\",\"bmp\",\"bmq\",\"bmr\",\"bms\",\"bmt\",\"bmu\",\"bmv\",\"bmw\",\"bmx\",\"bmy\",\"bmz\",\"bna\",\"bnb\",\"bnc\",\"bnd\",\"bne\",\"bnf\",\"bng\",\"bni\",\"bnj\",\"bnk\",\"bnl\",\"bnm\",\"bnn\",\"bno\",\"bnp\",\"bnq\",\"bnr\",\"bns\",\"bnt\",\"bnu\",\"bnv\",\"bnw\",\"bnx\",\"bny\",\"bnz\",\"boa\",\"bob\",\"boe\",\"bof\",\"bog\",\"boh\",\"boi\",\"boj\",\"bok\",\"bol\",\"bom\",\"bon\",\"boo\",\"bop\",\"boq\",\"bor\",\"bot\",\"bou\",\"bov\",\"bow\",\"box\",\"boy\",\"boz\",\"bpa\",\"bpb\",\"bpd\",\"bpg\",\"bph\",\"bpi\",\"bpj\",\"bpk\",\"bpl\",\"bpm\",\"bpn\",\"bpo\",\"bpp\",\"bpq\",\"bpr\",\"bps\",\"bpt\",\"bpu\",\"bpv\",\"bpw\",\"bpx\",\"bpy\",\"bpz\",\"bqa\",\"bqb\",\"bqc\",\"bqd\",\"bqf\",\"bqg\",\"bqh\",\"bqi\",\"bqj\",\"bqk\",\"bql\",\"bqm\",\"bqn\",\"bqo\",\"bqp\",\"bqq\",\"bqr\",\"bqs\",\"bqt\",\"bqu\",\"bqv\",\"bqw\",\"bqx\",\"bqy\",\"bqz\",\"bra\",\"brb\",\"brc\",\"brd\",\"brf\",\"brg\",\"brh\",\"bri\",\"brj\",\"brk\",\"brl\",\"brm\",\"brn\",\"bro\",\"brp\",\"brq\",\"brr\",\"brs\",\"brt\",\"bru\",\"brv\",\"brw\",\"brx\",\"bry\",\"brz\",\"bsa\",\"bsb\",\"bsc\",\"bse\",\"bsf\",\"bsg\",\"bsh\",\"bsi\",\"bsj\",\"bsk\",\"bsl\",\"bsm\",\"bsn\",\"bso\",\"bsp\",\"bsq\",\"bsr\",\"bss\",\"bst\",\"bsu\",\"bsv\",\"bsw\",\"bsx\",\"bsy\",\"bta\",\"btb\",\"btc\",\"btd\",\"bte\",\"btf\",\"btg\",\"bth\",\"bti\",\"btj\",\"btk\",\"btl\",\"btm\",\"btn\",\"bto\",\"btp\",\"btq\",\"btr\",\"bts\",\"btt\",\"btu\",\"btv\",\"btw\",\"btx\",\"bty\",\"btz\",\"bua\",\"bub\",\"buc\",\"bud\",\"bue\",\"buf\",\"bug\",\"buh\",\"bui\",\"buj\",\"buk\",\"bum\",\"bun\",\"buo\",\"bup\",\"buq\",\"bus\",\"but\",\"buu\",\"buv\",\"buw\",\"bux\",\"buy\",\"buz\",\"bva\",\"bvb\",\"bvc\",\"bvd\",\"bve\",\"bvf\",\"bvg\",\"bvh\",\"bvi\",\"bvj\",\"bvk\",\"bvl\",\"bvm\",\"bvn\",\"bvo\",\"bvp\",\"bvq\",\"bvr\",\"bvt\",\"bvu\",\"bvv\",\"bvw\",\"bvx\",\"bvy\",\"bvz\",\"bwa\",\"bwb\",\"bwc\",\"bwd\",\"bwe\",\"bwf\",\"bwg\",\"bwh\",\"bwi\",\"bwj\",\"bwk\",\"bwl\",\"bwm\",\"bwn\",\"bwo\",\"bwp\",\"bwq\",\"bwr\",\"bws\",\"bwt\",\"bwu\",\"bww\",\"bwx\",\"bwy\",\"bwz\",\"bxa\",\"bxb\",\"bxc\",\"bxd\",\"bxe\",\"bxf\",\"bxg\",\"bxh\",\"bxi\",\"bxj\",\"bxk\",\"bxl\",\"bxm\",\"bxn\",\"bxo\",\"bxp\",\"bxq\",\"bxr\",\"bxs\",\"bxu\",\"bxv\",\"bxw\",\"bxx\",\"bxz\",\"bya\",\"byb\",\"byc\",\"byd\",\"bye\",\"byf\",\"byg\",\"byh\",\"byi\",\"byj\",\"byk\",\"byl\",\"bym\",\"byn\",\"byo\",\"byp\",\"byq\",\"byr\",\"bys\",\"byt\",\"byv\",\"byw\",\"byx\",\"byy\",\"byz\",\"bza\",\"bzb\",\"bzc\",\"bzd\",\"bze\",\"bzf\",\"bzg\",\"bzh\",\"bzi\",\"bzj\",\"bzk\",\"bzl\",\"bzm\",\"bzn\",\"bzo\",\"bzp\",\"bzq\",\"bzr\",\"bzs\",\"bzt\",\"bzu\",\"bzv\",\"bzw\",\"bzx\",\"bzy\",\"bzz\",\"caa\",\"cab\",\"cac\",\"cad\",\"cae\",\"caf\",\"cag\",\"cah\",\"cai\",\"caj\",\"cak\",\"cal\",\"cam\",\"can\",\"cao\",\"cap\",\"caq\",\"car\",\"cas\",\"cau\",\"cav\",\"caw\",\"cax\",\"cay\",\"caz\",\"cba\",\"cbb\",\"cbc\",\"cbd\",\"cbe\",\"cbg\",\"cbh\",\"cbi\",\"cbj\",\"cbk\",\"cbl\",\"cbn\",\"cbo\",\"cbq\",\"cbr\",\"cbs\",\"cbt\",\"cbu\",\"cbv\",\"cbw\",\"cby\",\"cca\",\"ccc\",\"ccd\",\"cce\",\"ccg\",\"cch\",\"ccj\",\"ccl\",\"ccm\",\"ccn\",\"cco\",\"ccp\",\"ccq\",\"ccr\",\"ccs\",\"cda\",\"cdc\",\"cdd\",\"cde\",\"cdf\",\"cdg\",\"cdh\",\"cdi\",\"cdj\",\"cdm\",\"cdn\",\"cdo\",\"cdr\",\"cds\",\"cdy\",\"cdz\",\"cea\",\"ceb\",\"ceg\",\"cek\",\"cel\",\"cen\",\"cet\",\"cfa\",\"cfd\",\"cfg\",\"cfm\",\"cga\",\"cgc\",\"cgg\",\"cgk\",\"chb\",\"chc\",\"chd\",\"chf\",\"chg\",\"chh\",\"chj\",\"chk\",\"chl\",\"chm\",\"chn\",\"cho\",\"chp\",\"chq\",\"chr\",\"cht\",\"chw\",\"chx\",\"chy\",\"chz\",\"cia\",\"cib\",\"cic\",\"cid\",\"cie\",\"cih\",\"cik\",\"cim\",\"cin\",\"cip\",\"cir\",\"ciw\",\"ciy\",\"cja\",\"cje\",\"cjh\",\"cji\",\"cjk\",\"cjm\",\"cjn\",\"cjo\",\"cjp\",\"cjr\",\"cjs\",\"cjv\",\"cjy\",\"cka\",\"ckb\",\"ckh\",\"ckl\",\"ckn\",\"cko\",\"ckq\",\"ckr\",\"cks\",\"ckt\",\"cku\",\"ckv\",\"ckx\",\"cky\",\"ckz\",\"cla\",\"clc\",\"cld\",\"cle\",\"clh\",\"cli\",\"clj\",\"clk\",\"cll\",\"clm\",\"clo\",\"clt\",\"clu\",\"clw\",\"cly\",\"cma\",\"cmc\",\"cme\",\"cmg\",\"cmi\",\"cmk\",\"cml\",\"cmm\",\"cmn\",\"cmo\",\"cmr\",\"cms\",\"cmt\",\"cna\",\"cnb\",\"cnc\",\"cng\",\"cnh\",\"cni\",\"cnk\",\"cnl\",\"cno\",\"cns\",\"cnt\",\"cnu\",\"cnw\",\"cnx\",\"coa\",\"cob\",\"coc\",\"cod\",\"coe\",\"cof\",\"cog\",\"coh\",\"coj\",\"cok\",\"col\",\"com\",\"con\",\"coo\",\"cop\",\"coq\",\"cot\",\"cou\",\"cov\",\"cow\",\"cox\",\"coy\",\"coz\",\"cpa\",\"cpb\",\"cpc\",\"cpe\",\"cpf\",\"cpg\",\"cpi\",\"cpn\",\"cpo\",\"cpp\",\"cps\",\"cpu\",\"cpx\",\"cpy\",\"cqd\",\"cqu\",\"cra\",\"crb\",\"crc\",\"crd\",\"crf\",\"crg\",\"crh\",\"cri\",\"crj\",\"crk\",\"crl\",\"crm\",\"crn\",\"cro\",\"crp\",\"crq\",\"crr\",\"crs\",\"crt\",\"crv\",\"crw\",\"crx\",\"cry\",\"crz\",\"csa\",\"csb\",\"csc\",\"csd\",\"cse\",\"csf\",\"csg\",\"csh\",\"csi\",\"csj\",\"csk\",\"csl\",\"csm\",\"csn\",\"cso\",\"csq\",\"csr\",\"css\",\"cst\",\"csu\",\"csv\",\"csw\",\"csy\",\"csz\",\"cta\",\"ctc\",\"ctd\",\"cte\",\"ctg\",\"cth\",\"ctl\",\"ctm\",\"ctn\",\"cto\",\"ctp\",\"cts\",\"ctt\",\"ctu\",\"ctz\",\"cua\",\"cub\",\"cuc\",\"cug\",\"cuh\",\"cui\",\"cuj\",\"cuk\",\"cul\",\"cum\",\"cuo\",\"cup\",\"cuq\",\"cur\",\"cus\",\"cut\",\"cuu\",\"cuv\",\"cuw\",\"cux\",\"cvg\",\"cvn\",\"cwa\",\"cwb\",\"cwd\",\"cwe\",\"cwg\",\"cwt\",\"cya\",\"cyb\",\"cyo\",\"czh\",\"czk\",\"czn\",\"czo\",\"czt\",\"daa\",\"dac\",\"dad\",\"dae\",\"daf\",\"dag\",\"dah\",\"dai\",\"daj\",\"dak\",\"dal\",\"dam\",\"dao\",\"dap\",\"daq\",\"dar\",\"das\",\"dau\",\"dav\",\"daw\",\"dax\",\"day\",\"daz\",\"dba\",\"dbb\",\"dbd\",\"dbe\",\"dbf\",\"dbg\",\"dbi\",\"dbj\",\"dbl\",\"dbm\",\"dbn\",\"dbo\",\"dbp\",\"dbq\",\"dbr\",\"dbt\",\"dbu\",\"dbv\",\"dbw\",\"dby\",\"dcc\",\"dcr\",\"dda\",\"ddd\",\"dde\",\"ddg\",\"ddi\",\"ddj\",\"ddn\",\"ddo\",\"ddr\",\"dds\",\"ddw\",\"dec\",\"ded\",\"dee\",\"def\",\"deg\",\"deh\",\"dei\",\"dek\",\"del\",\"dem\",\"den\",\"dep\",\"deq\",\"der\",\"des\",\"dev\",\"dez\",\"dga\",\"dgb\",\"dgc\",\"dgd\",\"dge\",\"dgg\",\"dgh\",\"dgi\",\"dgk\",\"dgl\",\"dgn\",\"dgo\",\"dgr\",\"dgs\",\"dgt\",\"dgu\",\"dgw\",\"dgx\",\"dgz\",\"dha\",\"dhd\",\"dhg\",\"dhi\",\"dhl\",\"dhm\",\"dhn\",\"dho\",\"dhr\",\"dhs\",\"dhu\",\"dhv\",\"dhw\",\"dhx\",\"dia\",\"dib\",\"dic\",\"did\",\"dif\",\"dig\",\"dih\",\"dii\",\"dij\",\"dik\",\"dil\",\"dim\",\"din\",\"dio\",\"dip\",\"diq\",\"dir\",\"dis\",\"dit\",\"diu\",\"diw\",\"dix\",\"diy\",\"diz\",\"dja\",\"djb\",\"djc\",\"djd\",\"dje\",\"djf\",\"dji\",\"djj\",\"djk\",\"djl\",\"djm\",\"djn\",\"djo\",\"djr\",\"dju\",\"djw\",\"dka\",\"dkk\",\"dkl\",\"dkr\",\"dks\",\"dkx\",\"dlg\",\"dlk\",\"dlm\",\"dln\",\"dma\",\"dmb\",\"dmc\",\"dmd\",\"dme\",\"dmg\",\"dmk\",\"dml\",\"dmm\",\"dmn\",\"dmo\",\"dmr\",\"dms\",\"dmu\",\"dmv\",\"dmw\",\"dmx\",\"dmy\",\"dna\",\"dnd\",\"dne\",\"dng\",\"dni\",\"dnj\",\"dnk\",\"dnn\",\"dnr\",\"dnt\",\"dnu\",\"dnv\",\"dnw\",\"dny\",\"doa\",\"dob\",\"doc\",\"doe\",\"dof\",\"doh\",\"doi\",\"dok\",\"dol\",\"don\",\"doo\",\"dop\",\"doq\",\"dor\",\"dos\",\"dot\",\"dov\",\"dow\",\"dox\",\"doy\",\"doz\",\"dpp\",\"dra\",\"drb\",\"drc\",\"drd\",\"dre\",\"drg\",\"drh\",\"dri\",\"drl\",\"drn\",\"dro\",\"drq\",\"drr\",\"drs\",\"drt\",\"dru\",\"drw\",\"dry\",\"dsb\",\"dse\",\"dsh\",\"dsi\",\"dsl\",\"dsn\",\"dso\",\"dsq\",\"dta\",\"dtb\",\"dtd\",\"dth\",\"dti\",\"dtk\",\"dtm\",\"dtn\",\"dto\",\"dtp\",\"dtr\",\"dts\",\"dtt\",\"dtu\",\"dty\",\"dua\",\"dub\",\"duc\",\"dud\",\"due\",\"duf\",\"dug\",\"duh\",\"dui\",\"duj\",\"duk\",\"dul\",\"dum\",\"dun\",\"duo\",\"dup\",\"duq\",\"dur\",\"dus\",\"duu\",\"duv\",\"duw\",\"dux\",\"duy\",\"duz\",\"dva\",\"dwa\",\"dwl\",\"dwr\",\"dws\",\"dwu\",\"dww\",\"dwy\",\"dya\",\"dyb\",\"dyd\",\"dyg\",\"dyi\",\"dym\",\"dyn\",\"dyo\",\"dyu\",\"dyy\",\"dza\",\"dzd\",\"dze\",\"dzg\",\"dzl\",\"dzn\",\"eaa\",\"ebg\",\"ebk\",\"ebo\",\"ebr\",\"ebu\",\"ecr\",\"ecs\",\"ecy\",\"eee\",\"efa\",\"efe\",\"efi\",\"ega\",\"egl\",\"ego\",\"egx\",\"egy\",\"ehu\",\"eip\",\"eit\",\"eiv\",\"eja\",\"eka\",\"ekc\",\"eke\",\"ekg\",\"eki\",\"ekk\",\"ekl\",\"ekm\",\"eko\",\"ekp\",\"ekr\",\"eky\",\"ele\",\"elh\",\"eli\",\"elk\",\"elm\",\"elo\",\"elp\",\"elu\",\"elx\",\"ema\",\"emb\",\"eme\",\"emg\",\"emi\",\"emk\",\"emm\",\"emn\",\"emo\",\"emp\",\"ems\",\"emu\",\"emw\",\"emx\",\"emy\",\"ena\",\"enb\",\"enc\",\"end\",\"enf\",\"enh\",\"enl\",\"enm\",\"enn\",\"eno\",\"enq\",\"enr\",\"enu\",\"env\",\"enw\",\"enx\",\"eot\",\"epi\",\"era\",\"erg\",\"erh\",\"eri\",\"erk\",\"ero\",\"err\",\"ers\",\"ert\",\"erw\",\"ese\",\"esg\",\"esh\",\"esi\",\"esk\",\"esl\",\"esm\",\"esn\",\"eso\",\"esq\",\"ess\",\"esu\",\"esx\",\"esy\",\"etb\",\"etc\",\"eth\",\"etn\",\"eto\",\"etr\",\"ets\",\"ett\",\"etu\",\"etx\",\"etz\",\"euq\",\"eve\",\"evh\",\"evn\",\"ewo\",\"ext\",\"eya\",\"eyo\",\"eza\",\"eze\",\"faa\",\"fab\",\"fad\",\"faf\",\"fag\",\"fah\",\"fai\",\"faj\",\"fak\",\"fal\",\"fam\",\"fan\",\"fap\",\"far\",\"fat\",\"fau\",\"fax\",\"fay\",\"faz\",\"fbl\",\"fcs\",\"fer\",\"ffi\",\"ffm\",\"fgr\",\"fia\",\"fie\",\"fil\",\"fip\",\"fir\",\"fit\",\"fiu\",\"fiw\",\"fkk\",\"fkv\",\"fla\",\"flh\",\"fli\",\"fll\",\"fln\",\"flr\",\"fly\",\"fmp\",\"fmu\",\"fnb\",\"fng\",\"fni\",\"fod\",\"foi\",\"fom\",\"fon\",\"for\",\"fos\",\"fox\",\"fpe\",\"fqs\",\"frc\",\"frd\",\"frk\",\"frm\",\"fro\",\"frp\",\"frq\",\"frr\",\"frs\",\"frt\",\"fse\",\"fsl\",\"fss\",\"fub\",\"fuc\",\"fud\",\"fue\",\"fuf\",\"fuh\",\"fui\",\"fuj\",\"fum\",\"fun\",\"fuq\",\"fur\",\"fut\",\"fuu\",\"fuv\",\"fuy\",\"fvr\",\"fwa\",\"fwe\",\"gaa\",\"gab\",\"gac\",\"gad\",\"gae\",\"gaf\",\"gag\",\"gah\",\"gai\",\"gaj\",\"gak\",\"gal\",\"gam\",\"gan\",\"gao\",\"gap\",\"gaq\",\"gar\",\"gas\",\"gat\",\"gau\",\"gav\",\"gaw\",\"gax\",\"gay\",\"gaz\",\"gba\",\"gbb\",\"gbc\",\"gbd\",\"gbe\",\"gbf\",\"gbg\",\"gbh\",\"gbi\",\"gbj\",\"gbk\",\"gbl\",\"gbm\",\"gbn\",\"gbo\",\"gbp\",\"gbq\",\"gbr\",\"gbs\",\"gbu\",\"gbv\",\"gbw\",\"gbx\",\"gby\",\"gbz\",\"gcc\",\"gcd\",\"gce\",\"gcf\",\"gcl\",\"gcn\",\"gcr\",\"gct\",\"gda\",\"gdb\",\"gdc\",\"gdd\",\"gde\",\"gdf\",\"gdg\",\"gdh\",\"gdi\",\"gdj\",\"gdk\",\"gdl\",\"gdm\",\"gdn\",\"gdo\",\"gdq\",\"gdr\",\"gds\",\"gdt\",\"gdu\",\"gdx\",\"gea\",\"geb\",\"gec\",\"ged\",\"geg\",\"geh\",\"gei\",\"gej\",\"gek\",\"gel\",\"gem\",\"geq\",\"ges\",\"gev\",\"gew\",\"gex\",\"gey\",\"gez\",\"gfk\",\"gft\",\"gfx\",\"gga\",\"ggb\",\"ggd\",\"gge\",\"ggg\",\"ggk\",\"ggl\",\"ggn\",\"ggo\",\"ggr\",\"ggt\",\"ggu\",\"ggw\",\"gha\",\"ghc\",\"ghe\",\"ghh\",\"ghk\",\"ghl\",\"ghn\",\"gho\",\"ghr\",\"ghs\",\"ght\",\"gia\",\"gib\",\"gic\",\"gid\",\"gie\",\"gig\",\"gih\",\"gil\",\"gim\",\"gin\",\"gio\",\"gip\",\"giq\",\"gir\",\"gis\",\"git\",\"giu\",\"giw\",\"gix\",\"giy\",\"giz\",\"gji\",\"gjk\",\"gjm\",\"gjn\",\"gjr\",\"gju\",\"gka\",\"gke\",\"gkn\",\"gko\",\"gkp\",\"gku\",\"glc\",\"gld\",\"glh\",\"gli\",\"glj\",\"glk\",\"gll\",\"glo\",\"glr\",\"glu\",\"glw\",\"gly\",\"gma\",\"gmb\",\"gmd\",\"gme\",\"gmg\",\"gmh\",\"gml\",\"gmm\",\"gmn\",\"gmq\",\"gmu\",\"gmv\",\"gmw\",\"gmx\",\"gmy\",\"gmz\",\"gna\",\"gnb\",\"gnc\",\"gnd\",\"gne\",\"gng\",\"gnh\",\"gni\",\"gnk\",\"gnl\",\"gnm\",\"gnn\",\"gno\",\"gnq\",\"gnr\",\"gnt\",\"gnu\",\"gnw\",\"gnz\",\"goa\",\"gob\",\"goc\",\"god\",\"goe\",\"gof\",\"gog\",\"goh\",\"goi\",\"goj\",\"gok\",\"gol\",\"gom\",\"gon\",\"goo\",\"gop\",\"goq\",\"gor\",\"gos\",\"got\",\"gou\",\"gow\",\"gox\",\"goy\",\"goz\",\"gpa\",\"gpe\",\"gpn\",\"gqa\",\"gqi\",\"gqn\",\"gqr\",\"gqu\",\"gra\",\"grb\",\"grc\",\"grd\",\"grg\",\"grh\",\"gri\",\"grj\",\"grk\",\"grm\",\"gro\",\"grq\",\"grr\",\"grs\",\"grt\",\"gru\",\"grv\",\"grw\",\"grx\",\"gry\",\"grz\",\"gse\",\"gsg\",\"gsl\",\"gsm\",\"gsn\",\"gso\",\"gsp\",\"gss\",\"gsw\",\"gta\",\"gti\",\"gtu\",\"gua\",\"gub\",\"guc\",\"gud\",\"gue\",\"guf\",\"gug\",\"guh\",\"gui\",\"guk\",\"gul\",\"gum\",\"gun\",\"guo\",\"gup\",\"guq\",\"gur\",\"gus\",\"gut\",\"guu\",\"guv\",\"guw\",\"gux\",\"guz\",\"gva\",\"gvc\",\"gve\",\"gvf\",\"gvj\",\"gvl\",\"gvm\",\"gvn\",\"gvo\",\"gvp\",\"gvr\",\"gvs\",\"gvy\",\"gwa\",\"gwb\",\"gwc\",\"gwd\",\"gwe\",\"gwf\",\"gwg\",\"gwi\",\"gwj\",\"gwm\",\"gwn\",\"gwr\",\"gwt\",\"gwu\",\"gww\",\"gwx\",\"gxx\",\"gya\",\"gyb\",\"gyd\",\"gye\",\"gyf\",\"gyg\",\"gyi\",\"gyl\",\"gym\",\"gyn\",\"gyr\",\"gyy\",\"gza\",\"gzi\",\"gzn\",\"haa\",\"hab\",\"hac\",\"had\",\"hae\",\"haf\",\"hag\",\"hah\",\"hai\",\"haj\",\"hak\",\"hal\",\"ham\",\"han\",\"hao\",\"hap\",\"haq\",\"har\",\"has\",\"hav\",\"haw\",\"hax\",\"hay\",\"haz\",\"hba\",\"hbb\",\"hbn\",\"hbo\",\"hbu\",\"hca\",\"hch\",\"hdn\",\"hds\",\"hdy\",\"hea\",\"hed\",\"heg\",\"heh\",\"hei\",\"hem\",\"hgm\",\"hgw\",\"hhi\",\"hhr\",\"hhy\",\"hia\",\"hib\",\"hid\",\"hif\",\"hig\",\"hih\",\"hii\",\"hij\",\"hik\",\"hil\",\"him\",\"hio\",\"hir\",\"hit\",\"hiw\",\"hix\",\"hji\",\"hka\",\"hke\",\"hkk\",\"hks\",\"hla\",\"hlb\",\"hld\",\"hle\",\"hlt\",\"hlu\",\"hma\",\"hmb\",\"hmc\",\"hmd\",\"hme\",\"hmf\",\"hmg\",\"hmh\",\"hmi\",\"hmj\",\"hmk\",\"hml\",\"hmm\",\"hmn\",\"hmp\",\"hmq\",\"hmr\",\"hms\",\"hmt\",\"hmu\",\"hmv\",\"hmw\",\"hmx\",\"hmy\",\"hmz\",\"hna\",\"hnd\",\"hne\",\"hnh\",\"hni\",\"hnj\",\"hnn\",\"hno\",\"hns\",\"hnu\",\"hoa\",\"hob\",\"hoc\",\"hod\",\"hoe\",\"hoh\",\"hoi\",\"hoj\",\"hok\",\"hol\",\"hom\",\"hoo\",\"hop\",\"hor\",\"hos\",\"hot\",\"hov\",\"how\",\"hoy\",\"hoz\",\"hpo\",\"hps\",\"hra\",\"hrc\",\"hre\",\"hrk\",\"hrm\",\"hro\",\"hrp\",\"hrr\",\"hrt\",\"hru\",\"hrw\",\"hrx\",\"hrz\",\"hsb\",\"hsh\",\"hsl\",\"hsn\",\"hss\",\"hti\",\"hto\",\"hts\",\"htu\",\"htx\",\"hub\",\"huc\",\"hud\",\"hue\",\"huf\",\"hug\",\"huh\",\"hui\",\"huj\",\"huk\",\"hul\",\"hum\",\"huo\",\"hup\",\"huq\",\"hur\",\"hus\",\"hut\",\"huu\",\"huv\",\"huw\",\"hux\",\"huy\",\"huz\",\"hvc\",\"hve\",\"hvk\",\"hvn\",\"hvv\",\"hwa\",\"hwc\",\"hwo\",\"hya\",\"hyx\",\"iai\",\"ian\",\"iap\",\"iar\",\"iba\",\"ibb\",\"ibd\",\"ibe\",\"ibg\",\"ibh\",\"ibi\",\"ibl\",\"ibm\",\"ibn\",\"ibr\",\"ibu\",\"iby\",\"ica\",\"ich\",\"icl\",\"icr\",\"ida\",\"idb\",\"idc\",\"idd\",\"ide\",\"idi\",\"idr\",\"ids\",\"idt\",\"idu\",\"ifa\",\"ifb\",\"ife\",\"iff\",\"ifk\",\"ifm\",\"ifu\",\"ify\",\"igb\",\"ige\",\"igg\",\"igl\",\"igm\",\"ign\",\"igo\",\"igs\",\"igw\",\"ihb\",\"ihi\",\"ihp\",\"ihw\",\"iin\",\"iir\",\"ijc\",\"ije\",\"ijj\",\"ijn\",\"ijo\",\"ijs\",\"ike\",\"iki\",\"ikk\",\"ikl\",\"iko\",\"ikp\",\"ikr\",\"iks\",\"ikt\",\"ikv\",\"ikw\",\"ikx\",\"ikz\",\"ila\",\"ilb\",\"ilg\",\"ili\",\"ilk\",\"ill\",\"ilm\",\"ilo\",\"ilp\",\"ils\",\"ilu\",\"ilv\",\"ilw\",\"ima\",\"ime\",\"imi\",\"iml\",\"imn\",\"imo\",\"imr\",\"ims\",\"imy\",\"inb\",\"inc\",\"ine\",\"ing\",\"inh\",\"inj\",\"inl\",\"inm\",\"inn\",\"ino\",\"inp\",\"ins\",\"int\",\"inz\",\"ior\",\"iou\",\"iow\",\"ipi\",\"ipo\",\"iqu\",\"iqw\",\"ira\",\"ire\",\"irh\",\"iri\",\"irk\",\"irn\",\"iro\",\"irr\",\"iru\",\"irx\",\"iry\",\"isa\",\"isc\",\"isd\",\"ise\",\"isg\",\"ish\",\"isi\",\"isk\",\"ism\",\"isn\",\"iso\",\"isr\",\"ist\",\"isu\",\"itb\",\"itc\",\"itd\",\"ite\",\"iti\",\"itk\",\"itl\",\"itm\",\"ito\",\"itr\",\"its\",\"itt\",\"itv\",\"itw\",\"itx\",\"ity\",\"itz\",\"ium\",\"ivb\",\"ivv\",\"iwk\",\"iwm\",\"iwo\",\"iws\",\"ixc\",\"ixl\",\"iya\",\"iyo\",\"iyx\",\"izh\",\"izi\",\"izr\",\"izz\",\"jaa\",\"jab\",\"jac\",\"jad\",\"jae\",\"jaf\",\"jah\",\"jaj\",\"jak\",\"jal\",\"jam\",\"jan\",\"jao\",\"jaq\",\"jar\",\"jas\",\"jat\",\"jau\",\"jax\",\"jay\",\"jaz\",\"jbe\",\"jbi\",\"jbj\",\"jbk\",\"jbn\",\"jbo\",\"jbr\",\"jbt\",\"jbu\",\"jbw\",\"jcs\",\"jct\",\"jda\",\"jdg\",\"jdt\",\"jeb\",\"jee\",\"jeg\",\"jeh\",\"jei\",\"jek\",\"jel\",\"jen\",\"jer\",\"jet\",\"jeu\",\"jgb\",\"jge\",\"jgk\",\"jgo\",\"jhi\",\"jhs\",\"jia\",\"jib\",\"jic\",\"jid\",\"jie\",\"jig\",\"jih\",\"jii\",\"jil\",\"jim\",\"jio\",\"jiq\",\"jit\",\"jiu\",\"jiv\",\"jiy\",\"jje\",\"jjr\",\"jka\",\"jkm\",\"jko\",\"jkp\",\"jkr\",\"jku\",\"jle\",\"jls\",\"jma\",\"jmb\",\"jmc\",\"jmd\",\"jmi\",\"jml\",\"jmn\",\"jmr\",\"jms\",\"jmw\",\"jmx\",\"jna\",\"jnd\",\"jng\",\"jni\",\"jnj\",\"jnl\",\"jns\",\"job\",\"jod\",\"jog\",\"jor\",\"jos\",\"jow\",\"jpa\",\"jpr\",\"jpx\",\"jqr\",\"jra\",\"jrb\",\"jrr\",\"jrt\",\"jru\",\"jsl\",\"jua\",\"jub\",\"juc\",\"jud\",\"juh\",\"jui\",\"juk\",\"jul\",\"jum\",\"jun\",\"juo\",\"jup\",\"jur\",\"jus\",\"jut\",\"juu\",\"juw\",\"juy\",\"jvd\",\"jvn\",\"jwi\",\"jya\",\"jye\",\"jyy\",\"kaa\",\"kab\",\"kac\",\"kad\",\"kae\",\"kaf\",\"kag\",\"kah\",\"kai\",\"kaj\",\"kak\",\"kam\",\"kao\",\"kap\",\"kaq\",\"kar\",\"kav\",\"kaw\",\"kax\",\"kay\",\"kba\",\"kbb\",\"kbc\",\"kbd\",\"kbe\",\"kbf\",\"kbg\",\"kbh\",\"kbi\",\"kbj\",\"kbk\",\"kbl\",\"kbm\",\"kbn\",\"kbo\",\"kbp\",\"kbq\",\"kbr\",\"kbs\",\"kbt\",\"kbu\",\"kbv\",\"kbw\",\"kbx\",\"kby\",\"kbz\",\"kca\",\"kcb\",\"kcc\",\"kcd\",\"kce\",\"kcf\",\"kcg\",\"kch\",\"kci\",\"kcj\",\"kck\",\"kcl\",\"kcm\",\"kcn\",\"kco\",\"kcp\",\"kcq\",\"kcr\",\"kcs\",\"kct\",\"kcu\",\"kcv\",\"kcw\",\"kcx\",\"kcy\",\"kcz\",\"kda\",\"kdc\",\"kdd\",\"kde\",\"kdf\",\"kdg\",\"kdh\",\"kdi\",\"kdj\",\"kdk\",\"kdl\",\"kdm\",\"kdn\",\"kdo\",\"kdp\",\"kdq\",\"kdr\",\"kdt\",\"kdu\",\"kdv\",\"kdw\",\"kdx\",\"kdy\",\"kdz\",\"kea\",\"keb\",\"kec\",\"ked\",\"kee\",\"kef\",\"keg\",\"keh\",\"kei\",\"kej\",\"kek\",\"kel\",\"kem\",\"ken\",\"keo\",\"kep\",\"keq\",\"ker\",\"kes\",\"ket\",\"keu\",\"kev\",\"kew\",\"kex\",\"key\",\"kez\",\"kfa\",\"kfb\",\"kfc\",\"kfd\",\"kfe\",\"kff\",\"kfg\",\"kfh\",\"kfi\",\"kfj\",\"kfk\",\"kfl\",\"kfm\",\"kfn\",\"kfo\",\"kfp\",\"kfq\",\"kfr\",\"kfs\",\"kft\",\"kfu\",\"kfv\",\"kfw\",\"kfx\",\"kfy\",\"kfz\",\"kga\",\"kgb\",\"kgc\",\"kgd\",\"kge\",\"kgf\",\"kgg\",\"kgh\",\"kgi\",\"kgj\",\"kgk\",\"kgl\",\"kgm\",\"kgn\",\"kgo\",\"kgp\",\"kgq\",\"kgr\",\"kgs\",\"kgt\",\"kgu\",\"kgv\",\"kgw\",\"kgx\",\"kgy\",\"kha\",\"khb\",\"khc\",\"khd\",\"khe\",\"khf\",\"khg\",\"khh\",\"khi\",\"khj\",\"khk\",\"khl\",\"khn\",\"kho\",\"khp\",\"khq\",\"khr\",\"khs\",\"kht\",\"khu\",\"khv\",\"khw\",\"khx\",\"khy\",\"khz\",\"kia\",\"kib\",\"kic\",\"kid\",\"kie\",\"kif\",\"kig\",\"kih\",\"kii\",\"kij\",\"kil\",\"kim\",\"kio\",\"kip\",\"kiq\",\"kis\",\"kit\",\"kiu\",\"kiv\",\"kiw\",\"kix\",\"kiy\",\"kiz\",\"kja\",\"kjb\",\"kjc\",\"kjd\",\"kje\",\"kjf\",\"kjg\",\"kjh\",\"kji\",\"kjj\",\"kjk\",\"kjl\",\"kjm\",\"kjn\",\"kjo\",\"kjp\",\"kjq\",\"kjr\",\"kjs\",\"kjt\",\"kju\",\"kjv\",\"kjx\",\"kjy\",\"kjz\",\"kka\",\"kkb\",\"kkc\",\"kkd\",\"kke\",\"kkf\",\"kkg\",\"kkh\",\"kki\",\"kkj\",\"kkk\",\"kkl\",\"kkm\",\"kkn\",\"kko\",\"kkp\",\"kkq\",\"kkr\",\"kks\",\"kkt\",\"kku\",\"kkv\",\"kkw\",\"kkx\",\"kky\",\"kkz\",\"kla\",\"klb\",\"klc\",\"kld\",\"kle\",\"klf\",\"klg\",\"klh\",\"kli\",\"klj\",\"klk\",\"kll\",\"klm\",\"kln\",\"klo\",\"klp\",\"klq\",\"klr\",\"kls\",\"klt\",\"klu\",\"klv\",\"klw\",\"klx\",\"kly\",\"klz\",\"kma\",\"kmb\",\"kmc\",\"kmd\",\"kme\",\"kmf\",\"kmg\",\"kmh\",\"kmi\",\"kmj\",\"kmk\",\"kml\",\"kmm\",\"kmn\",\"kmo\",\"kmp\",\"kmq\",\"kmr\",\"kms\",\"kmt\",\"kmu\",\"kmv\",\"kmw\",\"kmx\",\"kmy\",\"kmz\",\"kna\",\"knb\",\"knc\",\"knd\",\"kne\",\"knf\",\"kng\",\"kni\",\"knj\",\"knk\",\"knl\",\"knm\",\"knn\",\"kno\",\"knp\",\"knq\",\"knr\",\"kns\",\"knt\",\"knu\",\"knv\",\"knw\",\"knx\",\"kny\",\"knz\",\"koa\",\"koc\",\"kod\",\"koe\",\"kof\",\"kog\",\"koh\",\"koi\",\"koj\",\"kok\",\"kol\",\"koo\",\"kop\",\"koq\",\"kos\",\"kot\",\"kou\",\"kov\",\"kow\",\"kox\",\"koy\",\"koz\",\"kpa\",\"kpb\",\"kpc\",\"kpd\",\"kpe\",\"kpf\",\"kpg\",\"kph\",\"kpi\",\"kpj\",\"kpk\",\"kpl\",\"kpm\",\"kpn\",\"kpo\",\"kpp\",\"kpq\",\"kpr\",\"kps\",\"kpt\",\"kpu\",\"kpv\",\"kpw\",\"kpx\",\"kpy\",\"kpz\",\"kqa\",\"kqb\",\"kqc\",\"kqd\",\"kqe\",\"kqf\",\"kqg\",\"kqh\",\"kqi\",\"kqj\",\"kqk\",\"kql\",\"kqm\",\"kqn\",\"kqo\",\"kqp\",\"kqq\",\"kqr\",\"kqs\",\"kqt\",\"kqu\",\"kqv\",\"kqw\",\"kqx\",\"kqy\",\"kqz\",\"kra\",\"krb\",\"krc\",\"krd\",\"kre\",\"krf\",\"krh\",\"kri\",\"krj\",\"krk\",\"krl\",\"krm\",\"krn\",\"kro\",\"krp\",\"krr\",\"krs\",\"krt\",\"kru\",\"krv\",\"krw\",\"krx\",\"kry\",\"krz\",\"ksa\",\"ksb\",\"ksc\",\"ksd\",\"kse\",\"ksf\",\"ksg\",\"ksh\",\"ksi\",\"ksj\",\"ksk\",\"ksl\",\"ksm\",\"ksn\",\"kso\",\"ksp\",\"ksq\",\"ksr\",\"kss\",\"kst\",\"ksu\",\"ksv\",\"ksw\",\"ksx\",\"ksy\",\"ksz\",\"kta\",\"ktb\",\"ktc\",\"ktd\",\"kte\",\"ktf\",\"ktg\",\"kth\",\"kti\",\"ktj\",\"ktk\",\"ktl\",\"ktm\",\"ktn\",\"kto\",\"ktp\",\"ktq\",\"ktr\",\"kts\",\"ktt\",\"ktu\",\"ktv\",\"ktw\",\"ktx\",\"kty\",\"ktz\",\"kub\",\"kuc\",\"kud\",\"kue\",\"kuf\",\"kug\",\"kuh\",\"kui\",\"kuj\",\"kuk\",\"kul\",\"kum\",\"kun\",\"kuo\",\"kup\",\"kuq\",\"kus\",\"kut\",\"kuu\",\"kuv\",\"kuw\",\"kux\",\"kuy\",\"kuz\",\"kva\",\"kvb\",\"kvc\",\"kvd\",\"kve\",\"kvf\",\"kvg\",\"kvh\",\"kvi\",\"kvj\",\"kvk\",\"kvl\",\"kvm\",\"kvn\",\"kvo\",\"kvp\",\"kvq\",\"kvr\",\"kvs\",\"kvt\",\"kvu\",\"kvv\",\"kvw\",\"kvx\",\"kvy\",\"kvz\",\"kwa\",\"kwb\",\"kwc\",\"kwd\",\"kwe\",\"kwf\",\"kwg\",\"kwh\",\"kwi\",\"kwj\",\"kwk\",\"kwl\",\"kwm\",\"kwn\",\"kwo\",\"kwp\",\"kwq\",\"kwr\",\"kws\",\"kwt\",\"kwu\",\"kwv\",\"kww\",\"kwx\",\"kwy\",\"kwz\",\"kxa\",\"kxb\",\"kxc\",\"kxd\",\"kxe\",\"kxf\",\"kxh\",\"kxi\",\"kxj\",\"kxk\",\"kxl\",\"kxm\",\"kxn\",\"kxo\",\"kxp\",\"kxq\",\"kxr\",\"kxs\",\"kxt\",\"kxu\",\"kxv\",\"kxw\",\"kxx\",\"kxy\",\"kxz\",\"kya\",\"kyb\",\"kyc\",\"kyd\",\"kye\",\"kyf\",\"kyg\",\"kyh\",\"kyi\",\"kyj\",\"kyk\",\"kyl\",\"kym\",\"kyn\",\"kyo\",\"kyp\",\"kyq\",\"kyr\",\"kys\",\"kyt\",\"kyu\",\"kyv\",\"kyw\",\"kyx\",\"kyy\",\"kyz\",\"kza\",\"kzb\",\"kzc\",\"kzd\",\"kze\",\"kzf\",\"kzg\",\"kzh\",\"kzi\",\"kzj\",\"kzk\",\"kzl\",\"kzm\",\"kzn\",\"kzo\",\"kzp\",\"kzq\",\"kzr\",\"kzs\",\"kzt\",\"kzu\",\"kzv\",\"kzw\",\"kzx\",\"kzy\",\"kzz\",\"laa\",\"lab\",\"lac\",\"lad\",\"lae\",\"laf\",\"lag\",\"lah\",\"lai\",\"laj\",\"lak\",\"lal\",\"lam\",\"lan\",\"lap\",\"laq\",\"lar\",\"las\",\"lau\",\"law\",\"lax\",\"lay\",\"laz\",\"lba\",\"lbb\",\"lbc\",\"lbe\",\"lbf\",\"lbg\",\"lbi\",\"lbj\",\"lbk\",\"lbl\",\"lbm\",\"lbn\",\"lbo\",\"lbq\",\"lbr\",\"lbs\",\"lbt\",\"lbu\",\"lbv\",\"lbw\",\"lbx\",\"lby\",\"lbz\",\"lcc\",\"lcd\",\"lce\",\"lcf\",\"lch\",\"lcl\",\"lcm\",\"lcp\",\"lcq\",\"lcs\",\"lda\",\"ldb\",\"ldd\",\"ldg\",\"ldh\",\"ldi\",\"ldj\",\"ldk\",\"ldl\",\"ldm\",\"ldn\",\"ldo\",\"ldp\",\"ldq\",\"lea\",\"leb\",\"lec\",\"led\",\"lee\",\"lef\",\"leg\",\"leh\",\"lei\",\"lej\",\"lek\",\"lel\",\"lem\",\"len\",\"leo\",\"lep\",\"leq\",\"ler\",\"les\",\"let\",\"leu\",\"lev\",\"lew\",\"lex\",\"ley\",\"lez\",\"lfa\",\"lfn\",\"lga\",\"lgb\",\"lgg\",\"lgh\",\"lgi\",\"lgk\",\"lgl\",\"lgm\",\"lgn\",\"lgq\",\"lgr\",\"lgt\",\"lgu\",\"lgz\",\"lha\",\"lhh\",\"lhi\",\"lhl\",\"lhm\",\"lhn\",\"lhp\",\"lhs\",\"lht\",\"lhu\",\"lia\",\"lib\",\"lic\",\"lid\",\"lie\",\"lif\",\"lig\",\"lih\",\"lii\",\"lij\",\"lik\",\"lil\",\"lio\",\"lip\",\"liq\",\"lir\",\"lis\",\"liu\",\"liv\",\"liw\",\"lix\",\"liy\",\"liz\",\"lja\",\"lje\",\"lji\",\"ljl\",\"ljp\",\"ljw\",\"ljx\",\"lka\",\"lkb\",\"lkc\",\"lkd\",\"lke\",\"lkh\",\"lki\",\"lkj\",\"lkl\",\"lkm\",\"lkn\",\"lko\",\"lkr\",\"lks\",\"lkt\",\"lku\",\"lky\",\"lla\",\"llb\",\"llc\",\"lld\",\"lle\",\"llf\",\"llg\",\"llh\",\"lli\",\"llj\",\"llk\",\"lll\",\"llm\",\"lln\",\"llo\",\"llp\",\"llq\",\"lls\",\"llu\",\"llx\",\"lma\",\"lmb\",\"lmc\",\"lmd\",\"lme\",\"lmf\",\"lmg\",\"lmh\",\"lmi\",\"lmj\",\"lmk\",\"lml\",\"lmm\",\"lmn\",\"lmo\",\"lmp\",\"lmq\",\"lmr\",\"lmu\",\"lmv\",\"lmw\",\"lmx\",\"lmy\",\"lmz\",\"lna\",\"lnb\",\"lnd\",\"lng\",\"lnh\",\"lni\",\"lnj\",\"lnl\",\"lnm\",\"lnn\",\"lno\",\"lns\",\"lnu\",\"lnw\",\"lnz\",\"loa\",\"lob\",\"loc\",\"loe\",\"lof\",\"log\",\"loh\",\"loi\",\"loj\",\"lok\",\"lol\",\"lom\",\"lon\",\"loo\",\"lop\",\"loq\",\"lor\",\"los\",\"lot\",\"lou\",\"lov\",\"low\",\"lox\",\"loy\",\"loz\",\"lpa\",\"lpe\",\"lpn\",\"lpo\",\"lpx\",\"lra\",\"lrc\",\"lre\",\"lrg\",\"lri\",\"lrk\",\"lrl\",\"lrm\",\"lrn\",\"lro\",\"lrr\",\"lrt\",\"lrv\",\"lrz\",\"lsa\",\"lsd\",\"lse\",\"lsg\",\"lsh\",\"lsi\",\"lsl\",\"lsm\",\"lso\",\"lsp\",\"lsr\",\"lss\",\"lst\",\"lsy\",\"ltc\",\"ltg\",\"lth\",\"lti\",\"ltn\",\"lto\",\"lts\",\"ltu\",\"lua\",\"luc\",\"lud\",\"lue\",\"luf\",\"lui\",\"luj\",\"luk\",\"lul\",\"lum\",\"lun\",\"luo\",\"lup\",\"luq\",\"lur\",\"lus\",\"lut\",\"luu\",\"luv\",\"luw\",\"luy\",\"luz\",\"lva\",\"lvk\",\"lvs\",\"lvu\",\"lwa\",\"lwe\",\"lwg\",\"lwh\",\"lwl\",\"lwm\",\"lwo\",\"lwt\",\"lwu\",\"lww\",\"lya\",\"lyg\",\"lyn\",\"lzh\",\"lzl\",\"lzn\",\"lzz\",\"maa\",\"mab\",\"mad\",\"mae\",\"maf\",\"mag\",\"mai\",\"maj\",\"mak\",\"mam\",\"man\",\"map\",\"maq\",\"mas\",\"mat\",\"mau\",\"mav\",\"maw\",\"max\",\"maz\",\"mba\",\"mbb\",\"mbc\",\"mbd\",\"mbe\",\"mbf\",\"mbh\",\"mbi\",\"mbj\",\"mbk\",\"mbl\",\"mbm\",\"mbn\",\"mbo\",\"mbp\",\"mbq\",\"mbr\",\"mbs\",\"mbt\",\"mbu\",\"mbv\",\"mbw\",\"mbx\",\"mby\",\"mbz\",\"mca\",\"mcb\",\"mcc\",\"mcd\",\"mce\",\"mcf\",\"mcg\",\"mch\",\"mci\",\"mcj\",\"mck\",\"mcl\",\"mcm\",\"mcn\",\"mco\",\"mcp\",\"mcq\",\"mcr\",\"mcs\",\"mct\",\"mcu\",\"mcv\",\"mcw\",\"mcx\",\"mcy\",\"mcz\",\"mda\",\"mdb\",\"mdc\",\"mdd\",\"mde\",\"mdf\",\"mdg\",\"mdh\",\"mdi\",\"mdj\",\"mdk\",\"mdl\",\"mdm\",\"mdn\",\"mdp\",\"mdq\",\"mdr\",\"mds\",\"mdt\",\"mdu\",\"mdv\",\"mdw\",\"mdx\",\"mdy\",\"mdz\",\"mea\",\"meb\",\"mec\",\"med\",\"mee\",\"mef\",\"meg\",\"meh\",\"mei\",\"mej\",\"mek\",\"mel\",\"mem\",\"men\",\"meo\",\"mep\",\"meq\",\"mer\",\"mes\",\"met\",\"meu\",\"mev\",\"mew\",\"mey\",\"mez\",\"mfa\",\"mfb\",\"mfc\",\"mfd\",\"mfe\",\"mff\",\"mfg\",\"mfh\",\"mfi\",\"mfj\",\"mfk\",\"mfl\",\"mfm\",\"mfn\",\"mfo\",\"mfp\",\"mfq\",\"mfr\",\"mfs\",\"mft\",\"mfu\",\"mfv\",\"mfw\",\"mfx\",\"mfy\",\"mfz\",\"mga\",\"mgb\",\"mgc\",\"mgd\",\"mge\",\"mgf\",\"mgg\",\"mgh\",\"mgi\",\"mgj\",\"mgk\",\"mgl\",\"mgm\",\"mgn\",\"mgo\",\"mgp\",\"mgq\",\"mgr\",\"mgs\",\"mgt\",\"mgu\",\"mgv\",\"mgw\",\"mgx\",\"mgy\",\"mgz\",\"mha\",\"mhb\",\"mhc\",\"mhd\",\"mhe\",\"mhf\",\"mhg\",\"mhh\",\"mhi\",\"mhj\",\"mhk\",\"mhl\",\"mhm\",\"mhn\",\"mho\",\"mhp\",\"mhq\",\"mhr\",\"mhs\",\"mht\",\"mhu\",\"mhw\",\"mhx\",\"mhy\",\"mhz\",\"mia\",\"mib\",\"mic\",\"mid\",\"mie\",\"mif\",\"mig\",\"mih\",\"mii\",\"mij\",\"mik\",\"mil\",\"mim\",\"min\",\"mio\",\"mip\",\"miq\",\"mir\",\"mis\",\"mit\",\"miu\",\"miw\",\"mix\",\"miy\",\"miz\",\"mja\",\"mjb\",\"mjc\",\"mjd\",\"mje\",\"mjg\",\"mjh\",\"mji\",\"mjj\",\"mjk\",\"mjl\",\"mjm\",\"mjn\",\"mjo\",\"mjp\",\"mjq\",\"mjr\",\"mjs\",\"mjt\",\"mju\",\"mjv\",\"mjw\",\"mjx\",\"mjy\",\"mjz\",\"mka\",\"mkb\",\"mkc\",\"mke\",\"mkf\",\"mkg\",\"mkh\",\"mki\",\"mkj\",\"mkk\",\"mkl\",\"mkm\",\"mkn\",\"mko\",\"mkp\",\"mkq\",\"mkr\",\"mks\",\"mkt\",\"mku\",\"mkv\",\"mkw\",\"mkx\",\"mky\",\"mkz\",\"mla\",\"mlb\",\"mlc\",\"mld\",\"mle\",\"mlf\",\"mlh\",\"mli\",\"mlj\",\"mlk\",\"mll\",\"mlm\",\"mln\",\"mlo\",\"mlp\",\"mlq\",\"mlr\",\"mls\",\"mlu\",\"mlv\",\"mlw\",\"mlx\",\"mlz\",\"mma\",\"mmb\",\"mmc\",\"mmd\",\"mme\",\"mmf\",\"mmg\",\"mmh\",\"mmi\",\"mmj\",\"mmk\",\"mml\",\"mmm\",\"mmn\",\"mmo\",\"mmp\",\"mmq\",\"mmr\",\"mmt\",\"mmu\",\"mmv\",\"mmw\",\"mmx\",\"mmy\",\"mmz\",\"mna\",\"mnb\",\"mnc\",\"mnd\",\"mne\",\"mnf\",\"mng\",\"mnh\",\"mni\",\"mnj\",\"mnk\",\"mnl\",\"mnm\",\"mnn\",\"mno\",\"mnp\",\"mnq\",\"mnr\",\"mns\",\"mnt\",\"mnu\",\"mnv\",\"mnw\",\"mnx\",\"mny\",\"mnz\",\"moa\",\"moc\",\"mod\",\"moe\",\"mof\",\"mog\",\"moh\",\"moi\",\"moj\",\"mok\",\"mom\",\"moo\",\"mop\",\"moq\",\"mor\",\"mos\",\"mot\",\"mou\",\"mov\",\"mow\",\"mox\",\"moy\",\"moz\",\"mpa\",\"mpb\",\"mpc\",\"mpd\",\"mpe\",\"mpg\",\"mph\",\"mpi\",\"mpj\",\"mpk\",\"mpl\",\"mpm\",\"mpn\",\"mpo\",\"mpp\",\"mpq\",\"mpr\",\"mps\",\"mpt\",\"mpu\",\"mpv\",\"mpw\",\"mpx\",\"mpy\",\"mpz\",\"mqa\",\"mqb\",\"mqc\",\"mqe\",\"mqf\",\"mqg\",\"mqh\",\"mqi\",\"mqj\",\"mqk\",\"mql\",\"mqm\",\"mqn\",\"mqo\",\"mqp\",\"mqq\",\"mqr\",\"mqs\",\"mqt\",\"mqu\",\"mqv\",\"mqw\",\"mqx\",\"mqy\",\"mqz\",\"mra\",\"mrb\",\"mrc\",\"mrd\",\"mre\",\"mrf\",\"mrg\",\"mrh\",\"mrj\",\"mrk\",\"mrl\",\"mrm\",\"mrn\",\"mro\",\"mrp\",\"mrq\",\"mrr\",\"mrs\",\"mrt\",\"mru\",\"mrv\",\"mrw\",\"mrx\",\"mry\",\"mrz\",\"msb\",\"msc\",\"msd\",\"mse\",\"msf\",\"msg\",\"msh\",\"msi\",\"msj\",\"msk\",\"msl\",\"msm\",\"msn\",\"mso\",\"msp\",\"msq\",\"msr\",\"mss\",\"mst\",\"msu\",\"msv\",\"msw\",\"msx\",\"msy\",\"msz\",\"mta\",\"mtb\",\"mtc\",\"mtd\",\"mte\",\"mtf\",\"mtg\",\"mth\",\"mti\",\"mtj\",\"mtk\",\"mtl\",\"mtm\",\"mtn\",\"mto\",\"mtp\",\"mtq\",\"mtr\",\"mts\",\"mtt\",\"mtu\",\"mtv\",\"mtw\",\"mtx\",\"mty\",\"mua\",\"mub\",\"muc\",\"mud\",\"mue\",\"mug\",\"muh\",\"mui\",\"muj\",\"muk\",\"mul\",\"mum\",\"mun\",\"muo\",\"mup\",\"muq\",\"mur\",\"mus\",\"mut\",\"muu\",\"muv\",\"mux\",\"muy\",\"muz\",\"mva\",\"mvb\",\"mvd\",\"mve\",\"mvf\",\"mvg\",\"mvh\",\"mvi\",\"mvk\",\"mvl\",\"mvm\",\"mvn\",\"mvo\",\"mvp\",\"mvq\",\"mvr\",\"mvs\",\"mvt\",\"mvu\",\"mvv\",\"mvw\",\"mvx\",\"mvy\",\"mvz\",\"mwa\",\"mwb\",\"mwc\",\"mwd\",\"mwe\",\"mwf\",\"mwg\",\"mwh\",\"mwi\",\"mwj\",\"mwk\",\"mwl\",\"mwm\",\"mwn\",\"mwo\",\"mwp\",\"mwq\",\"mwr\",\"mws\",\"mwt\",\"mwu\",\"mwv\",\"mww\",\"mwx\",\"mwy\",\"mwz\",\"mxa\",\"mxb\",\"mxc\",\"mxd\",\"mxe\",\"mxf\",\"mxg\",\"mxh\",\"mxi\",\"mxj\",\"mxk\",\"mxl\",\"mxm\",\"mxn\",\"mxo\",\"mxp\",\"mxq\",\"mxr\",\"mxs\",\"mxt\",\"mxu\",\"mxv\",\"mxw\",\"mxx\",\"mxy\",\"mxz\",\"myb\",\"myc\",\"myd\",\"mye\",\"myf\",\"myg\",\"myh\",\"myi\",\"myj\",\"myk\",\"myl\",\"mym\",\"myn\",\"myo\",\"myp\",\"myq\",\"myr\",\"mys\",\"myt\",\"myu\",\"myv\",\"myw\",\"myx\",\"myy\",\"myz\",\"mza\",\"mzb\",\"mzc\",\"mzd\",\"mze\",\"mzg\",\"mzh\",\"mzi\",\"mzj\",\"mzk\",\"mzl\",\"mzm\",\"mzn\",\"mzo\",\"mzp\",\"mzq\",\"mzr\",\"mzs\",\"mzt\",\"mzu\",\"mzv\",\"mzw\",\"mzx\",\"mzy\",\"mzz\",\"naa\",\"nab\",\"nac\",\"nad\",\"nae\",\"naf\",\"nag\",\"nah\",\"nai\",\"naj\",\"nak\",\"nal\",\"nam\",\"nan\",\"nao\",\"nap\",\"naq\",\"nar\",\"nas\",\"nat\",\"naw\",\"nax\",\"nay\",\"naz\",\"nba\",\"nbb\",\"nbc\",\"nbd\",\"nbe\",\"nbf\",\"nbg\",\"nbh\",\"nbi\",\"nbj\",\"nbk\",\"nbm\",\"nbn\",\"nbo\",\"nbp\",\"nbq\",\"nbr\",\"nbs\",\"nbt\",\"nbu\",\"nbv\",\"nbw\",\"nbx\",\"nby\",\"nca\",\"ncb\",\"ncc\",\"ncd\",\"nce\",\"ncf\",\"ncg\",\"nch\",\"nci\",\"ncj\",\"nck\",\"ncl\",\"ncm\",\"ncn\",\"nco\",\"ncp\",\"ncq\",\"ncr\",\"ncs\",\"nct\",\"ncu\",\"ncx\",\"ncz\",\"nda\",\"ndb\",\"ndc\",\"ndd\",\"ndf\",\"ndg\",\"ndh\",\"ndi\",\"ndj\",\"ndk\",\"ndl\",\"ndm\",\"ndn\",\"ndp\",\"ndq\",\"ndr\",\"nds\",\"ndt\",\"ndu\",\"ndv\",\"ndw\",\"ndx\",\"ndy\",\"ndz\",\"nea\",\"neb\",\"nec\",\"ned\",\"nee\",\"nef\",\"neg\",\"neh\",\"nei\",\"nej\",\"nek\",\"nem\",\"nen\",\"neo\",\"neq\",\"ner\",\"nes\",\"net\",\"neu\",\"nev\",\"new\",\"nex\",\"ney\",\"nez\",\"nfa\",\"nfd\",\"nfl\",\"nfr\",\"nfu\",\"nga\",\"ngb\",\"ngc\",\"ngd\",\"nge\",\"ngf\",\"ngg\",\"ngh\",\"ngi\",\"ngj\",\"ngk\",\"ngl\",\"ngm\",\"ngn\",\"ngo\",\"ngp\",\"ngq\",\"ngr\",\"ngs\",\"ngt\",\"ngu\",\"ngv\",\"ngw\",\"ngx\",\"ngy\",\"ngz\",\"nha\",\"nhb\",\"nhc\",\"nhd\",\"nhe\",\"nhf\",\"nhg\",\"nhh\",\"nhi\",\"nhk\",\"nhm\",\"nhn\",\"nho\",\"nhp\",\"nhq\",\"nhr\",\"nht\",\"nhu\",\"nhv\",\"nhw\",\"nhx\",\"nhy\",\"nhz\",\"nia\",\"nib\",\"nic\",\"nid\",\"nie\",\"nif\",\"nig\",\"nih\",\"nii\",\"nij\",\"nik\",\"nil\",\"nim\",\"nin\",\"nio\",\"niq\",\"nir\",\"nis\",\"nit\",\"niu\",\"niv\",\"niw\",\"nix\",\"niy\",\"niz\",\"nja\",\"njb\",\"njd\",\"njh\",\"nji\",\"njj\",\"njl\",\"njm\",\"njn\",\"njo\",\"njr\",\"njs\",\"njt\",\"nju\",\"njx\",\"njy\",\"njz\",\"nka\",\"nkb\",\"nkc\",\"nkd\",\"nke\",\"nkf\",\"nkg\",\"nkh\",\"nki\",\"nkj\",\"nkk\",\"nkm\",\"nkn\",\"nko\",\"nkp\",\"nkq\",\"nkr\",\"nks\",\"nkt\",\"nku\",\"nkv\",\"nkw\",\"nkx\",\"nkz\",\"nla\",\"nlc\",\"nle\",\"nlg\",\"nli\",\"nlj\",\"nlk\",\"nll\",\"nln\",\"nlo\",\"nlq\",\"nlr\",\"nlu\",\"nlv\",\"nlw\",\"nlx\",\"nly\",\"nlz\",\"nma\",\"nmb\",\"nmc\",\"nmd\",\"nme\",\"nmf\",\"nmg\",\"nmh\",\"nmi\",\"nmj\",\"nmk\",\"nml\",\"nmm\",\"nmn\",\"nmo\",\"nmp\",\"nmq\",\"nmr\",\"nms\",\"nmt\",\"nmu\",\"nmv\",\"nmw\",\"nmx\",\"nmy\",\"nmz\",\"nna\",\"nnb\",\"nnc\",\"nnd\",\"nne\",\"nnf\",\"nng\",\"nnh\",\"nni\",\"nnj\",\"nnk\",\"nnl\",\"nnm\",\"nnn\",\"nnp\",\"nnq\",\"nnr\",\"nns\",\"nnt\",\"nnu\",\"nnv\",\"nnw\",\"nnx\",\"nny\",\"nnz\",\"noa\",\"noc\",\"nod\",\"noe\",\"nof\",\"nog\",\"noh\",\"noi\",\"noj\",\"nok\",\"nol\",\"nom\",\"non\",\"noo\",\"nop\",\"noq\",\"nos\",\"not\",\"nou\",\"nov\",\"now\",\"noy\",\"noz\",\"npa\",\"npb\",\"npg\",\"nph\",\"npi\",\"npl\",\"npn\",\"npo\",\"nps\",\"npu\",\"npx\",\"npy\",\"nqg\",\"nqk\",\"nql\",\"nqm\",\"nqn\",\"nqo\",\"nqq\",\"nqy\",\"nra\",\"nrb\",\"nrc\",\"nre\",\"nrf\",\"nrg\",\"nri\",\"nrk\",\"nrl\",\"nrm\",\"nrn\",\"nrp\",\"nrr\",\"nrt\",\"nru\",\"nrx\",\"nrz\",\"nsa\",\"nsc\",\"nsd\",\"nse\",\"nsf\",\"nsg\",\"nsh\",\"nsi\",\"nsk\",\"nsl\",\"nsm\",\"nsn\",\"nso\",\"nsp\",\"nsq\",\"nsr\",\"nss\",\"nst\",\"nsu\",\"nsv\",\"nsw\",\"nsx\",\"nsy\",\"nsz\",\"ntd\",\"nte\",\"ntg\",\"nti\",\"ntj\",\"ntk\",\"ntm\",\"nto\",\"ntp\",\"ntr\",\"nts\",\"ntu\",\"ntw\",\"ntx\",\"nty\",\"ntz\",\"nua\",\"nub\",\"nuc\",\"nud\",\"nue\",\"nuf\",\"nug\",\"nuh\",\"nui\",\"nuj\",\"nuk\",\"nul\",\"num\",\"nun\",\"nuo\",\"nup\",\"nuq\",\"nur\",\"nus\",\"nut\",\"nuu\",\"nuv\",\"nuw\",\"nux\",\"nuy\",\"nuz\",\"nvh\",\"nvm\",\"nvo\",\"nwa\",\"nwb\",\"nwc\",\"nwe\",\"nwg\",\"nwi\",\"nwm\",\"nwo\",\"nwr\",\"nwx\",\"nwy\",\"nxa\",\"nxd\",\"nxe\",\"nxg\",\"nxi\",\"nxk\",\"nxl\",\"nxm\",\"nxn\",\"nxo\",\"nxq\",\"nxr\",\"nxu\",\"nxx\",\"nyb\",\"nyc\",\"nyd\",\"nye\",\"nyf\",\"nyg\",\"nyh\",\"nyi\",\"nyj\",\"nyk\",\"nyl\",\"nym\",\"nyn\",\"nyo\",\"nyp\",\"nyq\",\"nyr\",\"nys\",\"nyt\",\"nyu\",\"nyv\",\"nyw\",\"nyx\",\"nyy\",\"nza\",\"nzb\",\"nzi\",\"nzk\",\"nzm\",\"nzs\",\"nzu\",\"nzy\",\"nzz\",\"oaa\",\"oac\",\"oar\",\"oav\",\"obi\",\"obk\",\"obl\",\"obm\",\"obo\",\"obr\",\"obt\",\"obu\",\"oca\",\"och\",\"oco\",\"ocu\",\"oda\",\"odk\",\"odt\",\"odu\",\"ofo\",\"ofs\",\"ofu\",\"ogb\",\"ogc\",\"oge\",\"ogg\",\"ogo\",\"ogu\",\"oht\",\"ohu\",\"oia\",\"oin\",\"ojb\",\"ojc\",\"ojg\",\"ojp\",\"ojs\",\"ojv\",\"ojw\",\"oka\",\"okb\",\"okd\",\"oke\",\"okg\",\"okh\",\"oki\",\"okj\",\"okk\",\"okl\",\"okm\",\"okn\",\"oko\",\"okr\",\"oks\",\"oku\",\"okv\",\"okx\",\"ola\",\"old\",\"ole\",\"olk\",\"olm\",\"olo\",\"olr\",\"olt\",\"olu\",\"oma\",\"omb\",\"omc\",\"ome\",\"omg\",\"omi\",\"omk\",\"oml\",\"omn\",\"omo\",\"omp\",\"omq\",\"omr\",\"omt\",\"omu\",\"omv\",\"omw\",\"omx\",\"ona\",\"onb\",\"one\",\"ong\",\"oni\",\"onj\",\"onk\",\"onn\",\"ono\",\"onp\",\"onr\",\"ons\",\"ont\",\"onu\",\"onw\",\"onx\",\"ood\",\"oog\",\"oon\",\"oor\",\"oos\",\"opa\",\"opk\",\"opm\",\"opo\",\"opt\",\"opy\",\"ora\",\"orc\",\"ore\",\"org\",\"orh\",\"orn\",\"oro\",\"orr\",\"ors\",\"ort\",\"oru\",\"orv\",\"orw\",\"orx\",\"ory\",\"orz\",\"osa\",\"osc\",\"osi\",\"oso\",\"osp\",\"ost\",\"osu\",\"osx\",\"ota\",\"otb\",\"otd\",\"ote\",\"oti\",\"otk\",\"otl\",\"otm\",\"otn\",\"oto\",\"otq\",\"otr\",\"ots\",\"ott\",\"otu\",\"otw\",\"otx\",\"oty\",\"otz\",\"oua\",\"oub\",\"oue\",\"oui\",\"oum\",\"oun\",\"ovd\",\"owi\",\"owl\",\"oyb\",\"oyd\",\"oym\",\"oyy\",\"ozm\",\"paa\",\"pab\",\"pac\",\"pad\",\"pae\",\"paf\",\"pag\",\"pah\",\"pai\",\"pak\",\"pal\",\"pam\",\"pao\",\"pap\",\"paq\",\"par\",\"pas\",\"pat\",\"pau\",\"pav\",\"paw\",\"pax\",\"pay\",\"paz\",\"pbb\",\"pbc\",\"pbe\",\"pbf\",\"pbg\",\"pbh\",\"pbi\",\"pbl\",\"pbn\",\"pbo\",\"pbp\",\"pbr\",\"pbs\",\"pbt\",\"pbu\",\"pbv\",\"pby\",\"pbz\",\"pca\",\"pcb\",\"pcc\",\"pcd\",\"pce\",\"pcf\",\"pcg\",\"pch\",\"pci\",\"pcj\",\"pck\",\"pcl\",\"pcm\",\"pcn\",\"pcp\",\"pcr\",\"pcw\",\"pda\",\"pdc\",\"pdi\",\"pdn\",\"pdo\",\"pdt\",\"pdu\",\"pea\",\"peb\",\"ped\",\"pee\",\"pef\",\"peg\",\"peh\",\"pei\",\"pej\",\"pek\",\"pel\",\"pem\",\"peo\",\"pep\",\"peq\",\"pes\",\"pev\",\"pex\",\"pey\",\"pez\",\"pfa\",\"pfe\",\"pfl\",\"pga\",\"pgd\",\"pgg\",\"pgi\",\"pgk\",\"pgl\",\"pgn\",\"pgs\",\"pgu\",\"pgy\",\"pgz\",\"pha\",\"phd\",\"phg\",\"phh\",\"phi\",\"phk\",\"phl\",\"phm\",\"phn\",\"pho\",\"phq\",\"phr\",\"pht\",\"phu\",\"phv\",\"phw\",\"pia\",\"pib\",\"pic\",\"pid\",\"pie\",\"pif\",\"pig\",\"pih\",\"pii\",\"pij\",\"pil\",\"pim\",\"pin\",\"pio\",\"pip\",\"pir\",\"pis\",\"pit\",\"piu\",\"piv\",\"piw\",\"pix\",\"piy\",\"piz\",\"pjt\",\"pka\",\"pkb\",\"pkc\",\"pkg\",\"pkh\",\"pkn\",\"pko\",\"pkp\",\"pkr\",\"pks\",\"pkt\",\"pku\",\"pla\",\"plb\",\"plc\",\"pld\",\"ple\",\"plf\",\"plg\",\"plh\",\"plj\",\"plk\",\"pll\",\"pln\",\"plo\",\"plp\",\"plq\",\"plr\",\"pls\",\"plt\",\"plu\",\"plv\",\"plw\",\"ply\",\"plz\",\"pma\",\"pmb\",\"pmc\",\"pmd\",\"pme\",\"pmf\",\"pmh\",\"pmi\",\"pmj\",\"pmk\",\"pml\",\"pmm\",\"pmn\",\"pmo\",\"pmq\",\"pmr\",\"pms\",\"pmt\",\"pmu\",\"pmw\",\"pmx\",\"pmy\",\"pmz\",\"pna\",\"pnb\",\"pnc\",\"pne\",\"png\",\"pnh\",\"pni\",\"pnj\",\"pnk\",\"pnl\",\"pnm\",\"pnn\",\"pno\",\"pnp\",\"pnq\",\"pnr\",\"pns\",\"pnt\",\"pnu\",\"pnv\",\"pnw\",\"pnx\",\"pny\",\"pnz\",\"poc\",\"pod\",\"poe\",\"pof\",\"pog\",\"poh\",\"poi\",\"pok\",\"pom\",\"pon\",\"poo\",\"pop\",\"poq\",\"pos\",\"pot\",\"pov\",\"pow\",\"pox\",\"poy\",\"poz\",\"ppa\",\"ppe\",\"ppi\",\"ppk\",\"ppl\",\"ppm\",\"ppn\",\"ppo\",\"ppp\",\"ppq\",\"ppr\",\"pps\",\"ppt\",\"ppu\",\"pqa\",\"pqe\",\"pqm\",\"pqw\",\"pra\",\"prb\",\"prc\",\"prd\",\"pre\",\"prf\",\"prg\",\"prh\",\"pri\",\"prk\",\"prl\",\"prm\",\"prn\",\"pro\",\"prp\",\"prq\",\"prr\",\"prs\",\"prt\",\"pru\",\"prw\",\"prx\",\"pry\",\"prz\",\"psa\",\"psc\",\"psd\",\"pse\",\"psg\",\"psh\",\"psi\",\"psl\",\"psm\",\"psn\",\"pso\",\"psp\",\"psq\",\"psr\",\"pss\",\"pst\",\"psu\",\"psw\",\"psy\",\"pta\",\"pth\",\"pti\",\"ptn\",\"pto\",\"ptp\",\"ptq\",\"ptr\",\"ptt\",\"ptu\",\"ptv\",\"ptw\",\"pty\",\"pua\",\"pub\",\"puc\",\"pud\",\"pue\",\"puf\",\"pug\",\"pui\",\"puj\",\"puk\",\"pum\",\"puo\",\"pup\",\"puq\",\"pur\",\"put\",\"puu\",\"puw\",\"pux\",\"puy\",\"puz\",\"pwa\",\"pwb\",\"pwg\",\"pwi\",\"pwm\",\"pwn\",\"pwo\",\"pwr\",\"pww\",\"pxm\",\"pye\",\"pym\",\"pyn\",\"pys\",\"pyu\",\"pyx\",\"pyy\",\"pzn\",\"qaa..qtz\",\"qua\",\"qub\",\"quc\",\"qud\",\"quf\",\"qug\",\"quh\",\"qui\",\"quk\",\"qul\",\"qum\",\"qun\",\"qup\",\"quq\",\"qur\",\"qus\",\"quv\",\"quw\",\"qux\",\"quy\",\"quz\",\"qva\",\"qvc\",\"qve\",\"qvh\",\"qvi\",\"qvj\",\"qvl\",\"qvm\",\"qvn\",\"qvo\",\"qvp\",\"qvs\",\"qvw\",\"qvy\",\"qvz\",\"qwa\",\"qwc\",\"qwe\",\"qwh\",\"qwm\",\"qws\",\"qwt\",\"qxa\",\"qxc\",\"qxh\",\"qxl\",\"qxn\",\"qxo\",\"qxp\",\"qxq\",\"qxr\",\"qxs\",\"qxt\",\"qxu\",\"qxw\",\"qya\",\"qyp\",\"raa\",\"rab\",\"rac\",\"rad\",\"raf\",\"rag\",\"rah\",\"rai\",\"raj\",\"rak\",\"ral\",\"ram\",\"ran\",\"rao\",\"rap\",\"raq\",\"rar\",\"ras\",\"rat\",\"rau\",\"rav\",\"raw\",\"rax\",\"ray\",\"raz\",\"rbb\",\"rbk\",\"rbl\",\"rbp\",\"rcf\",\"rdb\",\"rea\",\"reb\",\"ree\",\"reg\",\"rei\",\"rej\",\"rel\",\"rem\",\"ren\",\"rer\",\"res\",\"ret\",\"rey\",\"rga\",\"rge\",\"rgk\",\"rgn\",\"rgr\",\"rgs\",\"rgu\",\"rhg\",\"rhp\",\"ria\",\"rie\",\"rif\",\"ril\",\"rim\",\"rin\",\"rir\",\"rit\",\"riu\",\"rjg\",\"rji\",\"rjs\",\"rka\",\"rkb\",\"rkh\",\"rki\",\"rkm\",\"rkt\",\"rkw\",\"rma\",\"rmb\",\"rmc\",\"rmd\",\"rme\",\"rmf\",\"rmg\",\"rmh\",\"rmi\",\"rmk\",\"rml\",\"rmm\",\"rmn\",\"rmo\",\"rmp\",\"rmq\",\"rmr\",\"rms\",\"rmt\",\"rmu\",\"rmv\",\"rmw\",\"rmx\",\"rmy\",\"rmz\",\"rna\",\"rnd\",\"rng\",\"rnl\",\"rnn\",\"rnp\",\"rnr\",\"rnw\",\"roa\",\"rob\",\"roc\",\"rod\",\"roe\",\"rof\",\"rog\",\"rol\",\"rom\",\"roo\",\"rop\",\"ror\",\"rou\",\"row\",\"rpn\",\"rpt\",\"rri\",\"rro\",\"rrt\",\"rsb\",\"rsi\",\"rsl\",\"rsm\",\"rtc\",\"rth\",\"rtm\",\"rts\",\"rtw\",\"rub\",\"ruc\",\"rue\",\"ruf\",\"rug\",\"ruh\",\"rui\",\"ruk\",\"ruo\",\"rup\",\"ruq\",\"rut\",\"ruu\",\"ruy\",\"ruz\",\"rwa\",\"rwk\",\"rwm\",\"rwo\",\"rwr\",\"rxd\",\"rxw\",\"ryn\",\"rys\",\"ryu\",\"rzh\",\"saa\",\"sab\",\"sac\",\"sad\",\"sae\",\"saf\",\"sah\",\"sai\",\"saj\",\"sak\",\"sal\",\"sam\",\"sao\",\"sap\",\"saq\",\"sar\",\"sas\",\"sat\",\"sau\",\"sav\",\"saw\",\"sax\",\"say\",\"saz\",\"sba\",\"sbb\",\"sbc\",\"sbd\",\"sbe\",\"sbf\",\"sbg\",\"sbh\",\"sbi\",\"sbj\",\"sbk\",\"sbl\",\"sbm\",\"sbn\",\"sbo\",\"sbp\",\"sbq\",\"sbr\",\"sbs\",\"sbt\",\"sbu\",\"sbv\",\"sbw\",\"sbx\",\"sby\",\"sbz\",\"sca\",\"scb\",\"sce\",\"scf\",\"scg\",\"sch\",\"sci\",\"sck\",\"scl\",\"scn\",\"sco\",\"scp\",\"scq\",\"scs\",\"sct\",\"scu\",\"scv\",\"scw\",\"scx\",\"sda\",\"sdb\",\"sdc\",\"sde\",\"sdf\",\"sdg\",\"sdh\",\"sdj\",\"sdk\",\"sdl\",\"sdm\",\"sdn\",\"sdo\",\"sdp\",\"sdr\",\"sds\",\"sdt\",\"sdu\",\"sdv\",\"sdx\",\"sdz\",\"sea\",\"seb\",\"sec\",\"sed\",\"see\",\"sef\",\"seg\",\"seh\",\"sei\",\"sej\",\"sek\",\"sel\",\"sem\",\"sen\",\"seo\",\"sep\",\"seq\",\"ser\",\"ses\",\"set\",\"seu\",\"sev\",\"sew\",\"sey\",\"sez\",\"sfb\",\"sfe\",\"sfm\",\"sfs\",\"sfw\",\"sga\",\"sgb\",\"sgc\",\"sgd\",\"sge\",\"sgg\",\"sgh\",\"sgi\",\"sgj\",\"sgk\",\"sgl\",\"sgm\",\"sgn\",\"sgo\",\"sgp\",\"sgr\",\"sgs\",\"sgt\",\"sgu\",\"sgw\",\"sgx\",\"sgy\",\"sgz\",\"sha\",\"shb\",\"shc\",\"shd\",\"she\",\"shg\",\"shh\",\"shi\",\"shj\",\"shk\",\"shl\",\"shm\",\"shn\",\"sho\",\"shp\",\"shq\",\"shr\",\"shs\",\"sht\",\"shu\",\"shv\",\"shw\",\"shx\",\"shy\",\"shz\",\"sia\",\"sib\",\"sid\",\"sie\",\"sif\",\"sig\",\"sih\",\"sii\",\"sij\",\"sik\",\"sil\",\"sim\",\"sio\",\"sip\",\"siq\",\"sir\",\"sis\",\"sit\",\"siu\",\"siv\",\"siw\",\"six\",\"siy\",\"siz\",\"sja\",\"sjb\",\"sjd\",\"sje\",\"sjg\",\"sjk\",\"sjl\",\"sjm\",\"sjn\",\"sjo\",\"sjp\",\"sjr\",\"sjs\",\"sjt\",\"sju\",\"sjw\",\"ska\",\"skb\",\"skc\",\"skd\",\"ske\",\"skf\",\"skg\",\"skh\",\"ski\",\"skj\",\"skk\",\"skm\",\"skn\",\"sko\",\"skp\",\"skq\",\"skr\",\"sks\",\"skt\",\"sku\",\"skv\",\"skw\",\"skx\",\"sky\",\"skz\",\"sla\",\"slc\",\"sld\",\"sle\",\"slf\",\"slg\",\"slh\",\"sli\",\"slj\",\"sll\",\"slm\",\"sln\",\"slp\",\"slq\",\"slr\",\"sls\",\"slt\",\"slu\",\"slw\",\"slx\",\"sly\",\"slz\",\"sma\",\"smb\",\"smc\",\"smd\",\"smf\",\"smg\",\"smh\",\"smi\",\"smj\",\"smk\",\"sml\",\"smm\",\"smn\",\"smp\",\"smq\",\"smr\",\"sms\",\"smt\",\"smu\",\"smv\",\"smw\",\"smx\",\"smy\",\"smz\",\"snb\",\"snc\",\"sne\",\"snf\",\"sng\",\"snh\",\"sni\",\"snj\",\"snk\",\"snl\",\"snm\",\"snn\",\"sno\",\"snp\",\"snq\",\"snr\",\"sns\",\"snu\",\"snv\",\"snw\",\"snx\",\"sny\",\"snz\",\"soa\",\"sob\",\"soc\",\"sod\",\"soe\",\"sog\",\"soh\",\"soi\",\"soj\",\"sok\",\"sol\",\"son\",\"soo\",\"sop\",\"soq\",\"sor\",\"sos\",\"sou\",\"sov\",\"sow\",\"sox\",\"soy\",\"soz\",\"spb\",\"spc\",\"spd\",\"spe\",\"spg\",\"spi\",\"spk\",\"spl\",\"spm\",\"spn\",\"spo\",\"spp\",\"spq\",\"spr\",\"sps\",\"spt\",\"spu\",\"spv\",\"spx\",\"spy\",\"sqa\",\"sqh\",\"sqj\",\"sqk\",\"sqm\",\"sqn\",\"sqo\",\"sqq\",\"sqr\",\"sqs\",\"sqt\",\"squ\",\"sra\",\"srb\",\"src\",\"sre\",\"srf\",\"srg\",\"srh\",\"sri\",\"srk\",\"srl\",\"srm\",\"srn\",\"sro\",\"srq\",\"srr\",\"srs\",\"srt\",\"sru\",\"srv\",\"srw\",\"srx\",\"sry\",\"srz\",\"ssa\",\"ssb\",\"ssc\",\"ssd\",\"sse\",\"ssf\",\"ssg\",\"ssh\",\"ssi\",\"ssj\",\"ssk\",\"ssl\",\"ssm\",\"ssn\",\"sso\",\"ssp\",\"ssq\",\"ssr\",\"sss\",\"sst\",\"ssu\",\"ssv\",\"ssx\",\"ssy\",\"ssz\",\"sta\",\"stb\",\"std\",\"ste\",\"stf\",\"stg\",\"sth\",\"sti\",\"stj\",\"stk\",\"stl\",\"stm\",\"stn\",\"sto\",\"stp\",\"stq\",\"str\",\"sts\",\"stt\",\"stu\",\"stv\",\"stw\",\"sty\",\"sua\",\"sub\",\"suc\",\"sue\",\"sug\",\"sui\",\"suj\",\"suk\",\"sul\",\"sum\",\"suq\",\"sur\",\"sus\",\"sut\",\"suv\",\"suw\",\"sux\",\"suy\",\"suz\",\"sva\",\"svb\",\"svc\",\"sve\",\"svk\",\"svm\",\"svr\",\"svs\",\"svx\",\"swb\",\"swc\",\"swf\",\"swg\",\"swh\",\"swi\",\"swj\",\"swk\",\"swl\",\"swm\",\"swn\",\"swo\",\"swp\",\"swq\",\"swr\",\"sws\",\"swt\",\"swu\",\"swv\",\"sww\",\"swx\",\"swy\",\"sxb\",\"sxc\",\"sxe\",\"sxg\",\"sxk\",\"sxl\",\"sxm\",\"sxn\",\"sxo\",\"sxr\",\"sxs\",\"sxu\",\"sxw\",\"sya\",\"syb\",\"syc\",\"syd\",\"syi\",\"syk\",\"syl\",\"sym\",\"syn\",\"syo\",\"syr\",\"sys\",\"syw\",\"syx\",\"syy\",\"sza\",\"szb\",\"szc\",\"szd\",\"sze\",\"szg\",\"szl\",\"szn\",\"szp\",\"szs\",\"szv\",\"szw\",\"taa\",\"tab\",\"tac\",\"tad\",\"tae\",\"taf\",\"tag\",\"tai\",\"taj\",\"tak\",\"tal\",\"tan\",\"tao\",\"tap\",\"taq\",\"tar\",\"tas\",\"tau\",\"tav\",\"taw\",\"tax\",\"tay\",\"taz\",\"tba\",\"tbb\",\"tbc\",\"tbd\",\"tbe\",\"tbf\",\"tbg\",\"tbh\",\"tbi\",\"tbj\",\"tbk\",\"tbl\",\"tbm\",\"tbn\",\"tbo\",\"tbp\",\"tbq\",\"tbr\",\"tbs\",\"tbt\",\"tbu\",\"tbv\",\"tbw\",\"tbx\",\"tby\",\"tbz\",\"tca\",\"tcb\",\"tcc\",\"tcd\",\"tce\",\"tcf\",\"tcg\",\"tch\",\"tci\",\"tck\",\"tcl\",\"tcm\",\"tcn\",\"tco\",\"tcp\",\"tcq\",\"tcs\",\"tct\",\"tcu\",\"tcw\",\"tcx\",\"tcy\",\"tcz\",\"tda\",\"tdb\",\"tdc\",\"tdd\",\"tde\",\"tdf\",\"tdg\",\"tdh\",\"tdi\",\"tdj\",\"tdk\",\"tdl\",\"tdm\",\"tdn\",\"tdo\",\"tdq\",\"tdr\",\"tds\",\"tdt\",\"tdu\",\"tdv\",\"tdx\",\"tdy\",\"tea\",\"teb\",\"tec\",\"ted\",\"tee\",\"tef\",\"teg\",\"teh\",\"tei\",\"tek\",\"tem\",\"ten\",\"teo\",\"tep\",\"teq\",\"ter\",\"tes\",\"tet\",\"teu\",\"tev\",\"tew\",\"tex\",\"tey\",\"tfi\",\"tfn\",\"tfo\",\"tfr\",\"tft\",\"tga\",\"tgb\",\"tgc\",\"tgd\",\"tge\",\"tgf\",\"tgg\",\"tgh\",\"tgi\",\"tgj\",\"tgn\",\"tgo\",\"tgp\",\"tgq\",\"tgr\",\"tgs\",\"tgt\",\"tgu\",\"tgv\",\"tgw\",\"tgx\",\"tgy\",\"tgz\",\"thc\",\"thd\",\"the\",\"thf\",\"thh\",\"thi\",\"thk\",\"thl\",\"thm\",\"thn\",\"thp\",\"thq\",\"thr\",\"ths\",\"tht\",\"thu\",\"thv\",\"thw\",\"thx\",\"thy\",\"thz\",\"tia\",\"tic\",\"tid\",\"tie\",\"tif\",\"tig\",\"tih\",\"tii\",\"tij\",\"tik\",\"til\",\"tim\",\"tin\",\"tio\",\"tip\",\"tiq\",\"tis\",\"tit\",\"tiu\",\"tiv\",\"tiw\",\"tix\",\"tiy\",\"tiz\",\"tja\",\"tjg\",\"tji\",\"tjl\",\"tjm\",\"tjn\",\"tjo\",\"tjs\",\"tju\",\"tjw\",\"tka\",\"tkb\",\"tkd\",\"tke\",\"tkf\",\"tkg\",\"tkk\",\"tkl\",\"tkm\",\"tkn\",\"tkp\",\"tkq\",\"tkr\",\"tks\",\"tkt\",\"tku\",\"tkv\",\"tkw\",\"tkx\",\"tkz\",\"tla\",\"tlb\",\"tlc\",\"tld\",\"tlf\",\"tlg\",\"tlh\",\"tli\",\"tlj\",\"tlk\",\"tll\",\"tlm\",\"tln\",\"tlo\",\"tlp\",\"tlq\",\"tlr\",\"tls\",\"tlt\",\"tlu\",\"tlv\",\"tlw\",\"tlx\",\"tly\",\"tma\",\"tmb\",\"tmc\",\"tmd\",\"tme\",\"tmf\",\"tmg\",\"tmh\",\"tmi\",\"tmj\",\"tmk\",\"tml\",\"tmm\",\"tmn\",\"tmo\",\"tmp\",\"tmq\",\"tmr\",\"tms\",\"tmt\",\"tmu\",\"tmv\",\"tmw\",\"tmy\",\"tmz\",\"tna\",\"tnb\",\"tnc\",\"tnd\",\"tne\",\"tnf\",\"tng\",\"tnh\",\"tni\",\"tnk\",\"tnl\",\"tnm\",\"tnn\",\"tno\",\"tnp\",\"tnq\",\"tnr\",\"tns\",\"tnt\",\"tnu\",\"tnv\",\"tnw\",\"tnx\",\"tny\",\"tnz\",\"tob\",\"toc\",\"tod\",\"toe\",\"tof\",\"tog\",\"toh\",\"toi\",\"toj\",\"tol\",\"tom\",\"too\",\"top\",\"toq\",\"tor\",\"tos\",\"tou\",\"tov\",\"tow\",\"tox\",\"toy\",\"toz\",\"tpa\",\"tpc\",\"tpe\",\"tpf\",\"tpg\",\"tpi\",\"tpj\",\"tpk\",\"tpl\",\"tpm\",\"tpn\",\"tpo\",\"tpp\",\"tpq\",\"tpr\",\"tpt\",\"tpu\",\"tpv\",\"tpw\",\"tpx\",\"tpy\",\"tpz\",\"tqb\",\"tql\",\"tqm\",\"tqn\",\"tqo\",\"tqp\",\"tqq\",\"tqr\",\"tqt\",\"tqu\",\"tqw\",\"tra\",\"trb\",\"trc\",\"trd\",\"tre\",\"trf\",\"trg\",\"trh\",\"tri\",\"trj\",\"trk\",\"trl\",\"trm\",\"trn\",\"tro\",\"trp\",\"trq\",\"trr\",\"trs\",\"trt\",\"tru\",\"trv\",\"trw\",\"trx\",\"try\",\"trz\",\"tsa\",\"tsb\",\"tsc\",\"tsd\",\"tse\",\"tsf\",\"tsg\",\"tsh\",\"tsi\",\"tsj\",\"tsk\",\"tsl\",\"tsm\",\"tsp\",\"tsq\",\"tsr\",\"tss\",\"tst\",\"tsu\",\"tsv\",\"tsw\",\"tsx\",\"tsy\",\"tsz\",\"tta\",\"ttb\",\"ttc\",\"ttd\",\"tte\",\"ttf\",\"ttg\",\"tth\",\"tti\",\"ttj\",\"ttk\",\"ttl\",\"ttm\",\"ttn\",\"tto\",\"ttp\",\"ttq\",\"ttr\",\"tts\",\"ttt\",\"ttu\",\"ttv\",\"ttw\",\"tty\",\"ttz\",\"tua\",\"tub\",\"tuc\",\"tud\",\"tue\",\"tuf\",\"tug\",\"tuh\",\"tui\",\"tuj\",\"tul\",\"tum\",\"tun\",\"tuo\",\"tup\",\"tuq\",\"tus\",\"tut\",\"tuu\",\"tuv\",\"tuw\",\"tux\",\"tuy\",\"tuz\",\"tva\",\"tvd\",\"tve\",\"tvk\",\"tvl\",\"tvm\",\"tvn\",\"tvo\",\"tvs\",\"tvt\",\"tvu\",\"tvw\",\"tvy\",\"twa\",\"twb\",\"twc\",\"twd\",\"twe\",\"twf\",\"twg\",\"twh\",\"twl\",\"twm\",\"twn\",\"two\",\"twp\",\"twq\",\"twr\",\"twt\",\"twu\",\"tww\",\"twx\",\"twy\",\"txa\",\"txb\",\"txc\",\"txe\",\"txg\",\"txh\",\"txi\",\"txj\",\"txm\",\"txn\",\"txo\",\"txq\",\"txr\",\"txs\",\"txt\",\"txu\",\"txx\",\"txy\",\"tya\",\"tye\",\"tyh\",\"tyi\",\"tyj\",\"tyl\",\"tyn\",\"typ\",\"tyr\",\"tys\",\"tyt\",\"tyu\",\"tyv\",\"tyx\",\"tyz\",\"tza\",\"tzh\",\"tzj\",\"tzl\",\"tzm\",\"tzn\",\"tzo\",\"tzx\",\"uam\",\"uan\",\"uar\",\"uba\",\"ubi\",\"ubl\",\"ubr\",\"ubu\",\"uby\",\"uda\",\"ude\",\"udg\",\"udi\",\"udj\",\"udl\",\"udm\",\"udu\",\"ues\",\"ufi\",\"uga\",\"ugb\",\"uge\",\"ugn\",\"ugo\",\"ugy\",\"uha\",\"uhn\",\"uis\",\"uiv\",\"uji\",\"uka\",\"ukg\",\"ukh\",\"ukk\",\"ukl\",\"ukp\",\"ukq\",\"uks\",\"uku\",\"ukw\",\"uky\",\"ula\",\"ulb\",\"ulc\",\"ule\",\"ulf\",\"uli\",\"ulk\",\"ull\",\"ulm\",\"uln\",\"ulu\",\"ulw\",\"uma\",\"umb\",\"umc\",\"umd\",\"umg\",\"umi\",\"umm\",\"umn\",\"umo\",\"ump\",\"umr\",\"ums\",\"umu\",\"una\",\"und\",\"une\",\"ung\",\"unk\",\"unm\",\"unn\",\"unp\",\"unr\",\"unu\",\"unx\",\"unz\",\"uok\",\"upi\",\"upv\",\"ura\",\"urb\",\"urc\",\"ure\",\"urf\",\"urg\",\"urh\",\"uri\",\"urj\",\"urk\",\"url\",\"urm\",\"urn\",\"uro\",\"urp\",\"urr\",\"urt\",\"uru\",\"urv\",\"urw\",\"urx\",\"ury\",\"urz\",\"usa\",\"ush\",\"usi\",\"usk\",\"usp\",\"usu\",\"uta\",\"ute\",\"utp\",\"utr\",\"utu\",\"uum\",\"uun\",\"uur\",\"uuu\",\"uve\",\"uvh\",\"uvl\",\"uwa\",\"uya\",\"uzn\",\"uzs\",\"vaa\",\"vae\",\"vaf\",\"vag\",\"vah\",\"vai\",\"vaj\",\"val\",\"vam\",\"van\",\"vao\",\"vap\",\"var\",\"vas\",\"vau\",\"vav\",\"vay\",\"vbb\",\"vbk\",\"vec\",\"ved\",\"vel\",\"vem\",\"veo\",\"vep\",\"ver\",\"vgr\",\"vgt\",\"vic\",\"vid\",\"vif\",\"vig\",\"vil\",\"vin\",\"vis\",\"vit\",\"viv\",\"vka\",\"vki\",\"vkj\",\"vkk\",\"vkl\",\"vkm\",\"vko\",\"vkp\",\"vkt\",\"vku\",\"vlp\",\"vls\",\"vma\",\"vmb\",\"vmc\",\"vmd\",\"vme\",\"vmf\",\"vmg\",\"vmh\",\"vmi\",\"vmj\",\"vmk\",\"vml\",\"vmm\",\"vmp\",\"vmq\",\"vmr\",\"vms\",\"vmu\",\"vmv\",\"vmw\",\"vmx\",\"vmy\",\"vmz\",\"vnk\",\"vnm\",\"vnp\",\"vor\",\"vot\",\"vra\",\"vro\",\"vrs\",\"vrt\",\"vsi\",\"vsl\",\"vsv\",\"vto\",\"vum\",\"vun\",\"vut\",\"vwa\",\"waa\",\"wab\",\"wac\",\"wad\",\"wae\",\"waf\",\"wag\",\"wah\",\"wai\",\"waj\",\"wak\",\"wal\",\"wam\",\"wan\",\"wao\",\"wap\",\"waq\",\"war\",\"was\",\"wat\",\"wau\",\"wav\",\"waw\",\"wax\",\"way\",\"waz\",\"wba\",\"wbb\",\"wbe\",\"wbf\",\"wbh\",\"wbi\",\"wbj\",\"wbk\",\"wbl\",\"wbm\",\"wbp\",\"wbq\",\"wbr\",\"wbs\",\"wbt\",\"wbv\",\"wbw\",\"wca\",\"wci\",\"wdd\",\"wdg\",\"wdj\",\"wdk\",\"wdu\",\"wdy\",\"wea\",\"wec\",\"wed\",\"weg\",\"weh\",\"wei\",\"wem\",\"wen\",\"weo\",\"wep\",\"wer\",\"wes\",\"wet\",\"weu\",\"wew\",\"wfg\",\"wga\",\"wgb\",\"wgg\",\"wgi\",\"wgo\",\"wgu\",\"wgw\",\"wgy\",\"wha\",\"whg\",\"whk\",\"whu\",\"wib\",\"wic\",\"wie\",\"wif\",\"wig\",\"wih\",\"wii\",\"wij\",\"wik\",\"wil\",\"wim\",\"win\",\"wir\",\"wit\",\"wiu\",\"wiv\",\"wiw\",\"wiy\",\"wja\",\"wji\",\"wka\",\"wkb\",\"wkd\",\"wkl\",\"wku\",\"wkw\",\"wky\",\"wla\",\"wlc\",\"wle\",\"wlg\",\"wli\",\"wlk\",\"wll\",\"wlm\",\"wlo\",\"wlr\",\"wls\",\"wlu\",\"wlv\",\"wlw\",\"wlx\",\"wly\",\"wma\",\"wmb\",\"wmc\",\"wmd\",\"wme\",\"wmh\",\"wmi\",\"wmm\",\"wmn\",\"wmo\",\"wms\",\"wmt\",\"wmw\",\"wmx\",\"wnb\",\"wnc\",\"wnd\",\"wne\",\"wng\",\"wni\",\"wnk\",\"wnm\",\"wnn\",\"wno\",\"wnp\",\"wnu\",\"wnw\",\"wny\",\"woa\",\"wob\",\"woc\",\"wod\",\"woe\",\"wof\",\"wog\",\"woi\",\"wok\",\"wom\",\"won\",\"woo\",\"wor\",\"wos\",\"wow\",\"woy\",\"wpc\",\"wra\",\"wrb\",\"wrd\",\"wrg\",\"wrh\",\"wri\",\"wrk\",\"wrl\",\"wrm\",\"wrn\",\"wro\",\"wrp\",\"wrr\",\"wrs\",\"wru\",\"wrv\",\"wrw\",\"wrx\",\"wry\",\"wrz\",\"wsa\",\"wsg\",\"wsi\",\"wsk\",\"wsr\",\"wss\",\"wsu\",\"wsv\",\"wtf\",\"wth\",\"wti\",\"wtk\",\"wtm\",\"wtw\",\"wua\",\"wub\",\"wud\",\"wuh\",\"wul\",\"wum\",\"wun\",\"wur\",\"wut\",\"wuu\",\"wuv\",\"wux\",\"wuy\",\"wwa\",\"wwb\",\"wwo\",\"wwr\",\"www\",\"wxa\",\"wxw\",\"wya\",\"wyb\",\"wyi\",\"wym\",\"wyr\",\"wyy\",\"xaa\",\"xab\",\"xac\",\"xad\",\"xae\",\"xag\",\"xai\",\"xaj\",\"xak\",\"xal\",\"xam\",\"xan\",\"xao\",\"xap\",\"xaq\",\"xar\",\"xas\",\"xat\",\"xau\",\"xav\",\"xaw\",\"xay\",\"xba\",\"xbb\",\"xbc\",\"xbd\",\"xbe\",\"xbg\",\"xbi\",\"xbj\",\"xbm\",\"xbn\",\"xbo\",\"xbp\",\"xbr\",\"xbw\",\"xbx\",\"xby\",\"xcb\",\"xcc\",\"xce\",\"xcg\",\"xch\",\"xcl\",\"xcm\",\"xcn\",\"xco\",\"xcr\",\"xct\",\"xcu\",\"xcv\",\"xcw\",\"xcy\",\"xda\",\"xdc\",\"xdk\",\"xdm\",\"xdo\",\"xdy\",\"xeb\",\"xed\",\"xeg\",\"xel\",\"xem\",\"xep\",\"xer\",\"xes\",\"xet\",\"xeu\",\"xfa\",\"xga\",\"xgb\",\"xgd\",\"xgf\",\"xgg\",\"xgi\",\"xgl\",\"xgm\",\"xgn\",\"xgr\",\"xgu\",\"xgw\",\"xha\",\"xhc\",\"xhd\",\"xhe\",\"xhr\",\"xht\",\"xhu\",\"xhv\",\"xia\",\"xib\",\"xii\",\"xil\",\"xin\",\"xip\",\"xir\",\"xis\",\"xiv\",\"xiy\",\"xjb\",\"xjt\",\"xka\",\"xkb\",\"xkc\",\"xkd\",\"xke\",\"xkf\",\"xkg\",\"xkh\",\"xki\",\"xkj\",\"xkk\",\"xkl\",\"xkn\",\"xko\",\"xkp\",\"xkq\",\"xkr\",\"xks\",\"xkt\",\"xku\",\"xkv\",\"xkw\",\"xkx\",\"xky\",\"xkz\",\"xla\",\"xlb\",\"xlc\",\"xld\",\"xle\",\"xlg\",\"xli\",\"xln\",\"xlo\",\"xlp\",\"xls\",\"xlu\",\"xly\",\"xma\",\"xmb\",\"xmc\",\"xmd\",\"xme\",\"xmf\",\"xmg\",\"xmh\",\"xmj\",\"xmk\",\"xml\",\"xmm\",\"xmn\",\"xmo\",\"xmp\",\"xmq\",\"xmr\",\"xms\",\"xmt\",\"xmu\",\"xmv\",\"xmw\",\"xmx\",\"xmy\",\"xmz\",\"xna\",\"xnb\",\"xnd\",\"xng\",\"xnh\",\"xni\",\"xnk\",\"xnn\",\"xno\",\"xnr\",\"xns\",\"xnt\",\"xnu\",\"xny\",\"xnz\",\"xoc\",\"xod\",\"xog\",\"xoi\",\"xok\",\"xom\",\"xon\",\"xoo\",\"xop\",\"xor\",\"xow\",\"xpa\",\"xpc\",\"xpe\",\"xpg\",\"xpi\",\"xpj\",\"xpk\",\"xpm\",\"xpn\",\"xpo\",\"xpp\",\"xpq\",\"xpr\",\"xps\",\"xpt\",\"xpu\",\"xpy\",\"xqa\",\"xqt\",\"xra\",\"xrb\",\"xrd\",\"xre\",\"xrg\",\"xri\",\"xrm\",\"xrn\",\"xrq\",\"xrr\",\"xrt\",\"xru\",\"xrw\",\"xsa\",\"xsb\",\"xsc\",\"xsd\",\"xse\",\"xsh\",\"xsi\",\"xsj\",\"xsl\",\"xsm\",\"xsn\",\"xso\",\"xsp\",\"xsq\",\"xsr\",\"xss\",\"xsu\",\"xsv\",\"xsy\",\"xta\",\"xtb\",\"xtc\",\"xtd\",\"xte\",\"xtg\",\"xth\",\"xti\",\"xtj\",\"xtl\",\"xtm\",\"xtn\",\"xto\",\"xtp\",\"xtq\",\"xtr\",\"xts\",\"xtt\",\"xtu\",\"xtv\",\"xtw\",\"xty\",\"xtz\",\"xua\",\"xub\",\"xud\",\"xug\",\"xuj\",\"xul\",\"xum\",\"xun\",\"xuo\",\"xup\",\"xur\",\"xut\",\"xuu\",\"xve\",\"xvi\",\"xvn\",\"xvo\",\"xvs\",\"xwa\",\"xwc\",\"xwd\",\"xwe\",\"xwg\",\"xwj\",\"xwk\",\"xwl\",\"xwo\",\"xwr\",\"xwt\",\"xww\",\"xxb\",\"xxk\",\"xxm\",\"xxr\",\"xxt\",\"xya\",\"xyb\",\"xyj\",\"xyk\",\"xyl\",\"xyt\",\"xyy\",\"xzh\",\"xzm\",\"xzp\",\"yaa\",\"yab\",\"yac\",\"yad\",\"yae\",\"yaf\",\"yag\",\"yah\",\"yai\",\"yaj\",\"yak\",\"yal\",\"yam\",\"yan\",\"yao\",\"yap\",\"yaq\",\"yar\",\"yas\",\"yat\",\"yau\",\"yav\",\"yaw\",\"yax\",\"yay\",\"yaz\",\"yba\",\"ybb\",\"ybd\",\"ybe\",\"ybh\",\"ybi\",\"ybj\",\"ybk\",\"ybl\",\"ybm\",\"ybn\",\"ybo\",\"ybx\",\"yby\",\"ych\",\"ycl\",\"ycn\",\"ycp\",\"yda\",\"ydd\",\"yde\",\"ydg\",\"ydk\",\"yds\",\"yea\",\"yec\",\"yee\",\"yei\",\"yej\",\"yel\",\"yen\",\"yer\",\"yes\",\"yet\",\"yeu\",\"yev\",\"yey\",\"yga\",\"ygi\",\"ygl\",\"ygm\",\"ygp\",\"ygr\",\"ygs\",\"ygu\",\"ygw\",\"yha\",\"yhd\",\"yhl\",\"yhs\",\"yia\",\"yif\",\"yig\",\"yih\",\"yii\",\"yij\",\"yik\",\"yil\",\"yim\",\"yin\",\"yip\",\"yiq\",\"yir\",\"yis\",\"yit\",\"yiu\",\"yiv\",\"yix\",\"yiy\",\"yiz\",\"yka\",\"ykg\",\"yki\",\"ykk\",\"ykl\",\"ykm\",\"ykn\",\"yko\",\"ykr\",\"ykt\",\"yku\",\"yky\",\"yla\",\"ylb\",\"yle\",\"ylg\",\"yli\",\"yll\",\"ylm\",\"yln\",\"ylo\",\"ylr\",\"ylu\",\"yly\",\"yma\",\"ymb\",\"ymc\",\"ymd\",\"yme\",\"ymg\",\"ymh\",\"ymi\",\"ymk\",\"yml\",\"ymm\",\"ymn\",\"ymo\",\"ymp\",\"ymq\",\"ymr\",\"yms\",\"ymt\",\"ymx\",\"ymz\",\"yna\",\"ynd\",\"yne\",\"yng\",\"ynh\",\"ynk\",\"ynl\",\"ynn\",\"yno\",\"ynq\",\"yns\",\"ynu\",\"yob\",\"yog\",\"yoi\",\"yok\",\"yol\",\"yom\",\"yon\",\"yos\",\"yot\",\"yox\",\"yoy\",\"ypa\",\"ypb\",\"ypg\",\"yph\",\"ypk\",\"ypm\",\"ypn\",\"ypo\",\"ypp\",\"ypz\",\"yra\",\"yrb\",\"yre\",\"yri\",\"yrk\",\"yrl\",\"yrm\",\"yrn\",\"yro\",\"yrs\",\"yrw\",\"yry\",\"ysc\",\"ysd\",\"ysg\",\"ysl\",\"ysn\",\"yso\",\"ysp\",\"ysr\",\"yss\",\"ysy\",\"yta\",\"ytl\",\"ytp\",\"ytw\",\"yty\",\"yua\",\"yub\",\"yuc\",\"yud\",\"yue\",\"yuf\",\"yug\",\"yui\",\"yuj\",\"yuk\",\"yul\",\"yum\",\"yun\",\"yup\",\"yuq\",\"yur\",\"yut\",\"yuu\",\"yuw\",\"yux\",\"yuy\",\"yuz\",\"yva\",\"yvt\",\"ywa\",\"ywg\",\"ywl\",\"ywn\",\"ywq\",\"ywr\",\"ywt\",\"ywu\",\"yww\",\"yxa\",\"yxg\",\"yxl\",\"yxm\",\"yxu\",\"yxy\",\"yyr\",\"yyu\",\"yyz\",\"yzg\",\"yzk\",\"zaa\",\"zab\",\"zac\",\"zad\",\"zae\",\"zaf\",\"zag\",\"zah\",\"zai\",\"zaj\",\"zak\",\"zal\",\"zam\",\"zao\",\"zap\",\"zaq\",\"zar\",\"zas\",\"zat\",\"zau\",\"zav\",\"zaw\",\"zax\",\"zay\",\"zaz\",\"zbc\",\"zbe\",\"zbl\",\"zbt\",\"zbw\",\"zca\",\"zch\",\"zdj\",\"zea\",\"zeg\",\"zeh\",\"zen\",\"zga\",\"zgb\",\"zgh\",\"zgm\",\"zgn\",\"zgr\",\"zhb\",\"zhd\",\"zhi\",\"zhn\",\"zhw\",\"zhx\",\"zia\",\"zib\",\"zik\",\"zil\",\"zim\",\"zin\",\"zir\",\"ziw\",\"ziz\",\"zka\",\"zkb\",\"zkd\",\"zkg\",\"zkh\",\"zkk\",\"zkn\",\"zko\",\"zkp\",\"zkr\",\"zkt\",\"zku\",\"zkv\",\"zkz\",\"zle\",\"zlj\",\"zlm\",\"zln\",\"zlq\",\"zls\",\"zlw\",\"zma\",\"zmb\",\"zmc\",\"zmd\",\"zme\",\"zmf\",\"zmg\",\"zmh\",\"zmi\",\"zmj\",\"zmk\",\"zml\",\"zmm\",\"zmn\",\"zmo\",\"zmp\",\"zmq\",\"zmr\",\"zms\",\"zmt\",\"zmu\",\"zmv\",\"zmw\",\"zmx\",\"zmy\",\"zmz\",\"zna\",\"znd\",\"zne\",\"zng\",\"znk\",\"zns\",\"zoc\",\"zoh\",\"zom\",\"zoo\",\"zoq\",\"zor\",\"zos\",\"zpa\",\"zpb\",\"zpc\",\"zpd\",\"zpe\",\"zpf\",\"zpg\",\"zph\",\"zpi\",\"zpj\",\"zpk\",\"zpl\",\"zpm\",\"zpn\",\"zpo\",\"zpp\",\"zpq\",\"zpr\",\"zps\",\"zpt\",\"zpu\",\"zpv\",\"zpw\",\"zpx\",\"zpy\",\"zpz\",\"zqe\",\"zra\",\"zrg\",\"zrn\",\"zro\",\"zrp\",\"zrs\",\"zsa\",\"zsk\",\"zsl\",\"zsm\",\"zsr\",\"zsu\",\"zte\",\"ztg\",\"ztl\",\"ztm\",\"ztn\",\"ztp\",\"ztq\",\"zts\",\"ztt\",\"ztu\",\"ztx\",\"zty\",\"zua\",\"zuh\",\"zum\",\"zun\",\"zuy\",\"zwa\",\"zxx\",\"zyb\",\"zyg\",\"zyj\",\"zyn\",\"zyp\",\"zza\",\"zzj\"]\n;return axe.utils.validLangs=function(){\"use strict\";return I},commons}()})}(\"object\"==typeof window?window:this);";
-
-
-
-
-
-function runA11yChecks(){
-return window.axe.run(document,{
-elementRef:true,
-runOnly:{
-type:'tag',
-values:[
-'wcag2a',
-'wcag2aa']},
-
-
-resultTypes:['violations','inapplicable'],
-rules:{
-'tabindex':{enabled:true},
-'table-fake-caption':{enabled:true},
-'td-has-header':{enabled:true},
-'area-alt':{enabled:false},
-'blink':{enabled:false},
-'server-side-image-map':{enabled:false}}}).
-
-then(axeResult=>{
-
-axeResult.violations.forEach(v=>v.nodes.forEach(node=>{
-node.path=getNodePath(node.element);
-node.snippet=getOuterHTMLSnippet(node.element);
-
-node.element=node.any=node.all=node.none=undefined;
-}));
-
-
-axeResult={violations:axeResult.violations,notApplicable:axeResult.inapplicable};
-return axeResult;
-});
-
-
-
-
-function getNodePath(node){
-function getNodeIndex(node){
-let index=0;
-while(node=node.previousSibling){
-
-if(node.nodeType===Node.TEXT_NODE&&
-node.textContent.trim().length===0)continue;
-index++;
-}
-return index;
-}
-
-const path=[];
-while(node&&node.parentNode){
-const index=getNodeIndex(node);
-path.push([index,node.nodeName]);
-node=node.parentNode;
-}
-path.reverse();
-return path.join(',');
-}
-
-
-
-
-
-
-function getOuterHTMLSnippet(node){
-const reOpeningTag=/^.*?>/;
-const match=node.outerHTML.match(reOpeningTag);
-return match&&match[0];
-}
-}
-
-class Accessibility extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-const expression=`(function () {
-      ${axeLibSource};
-      return (${runA11yChecks.toString()}());
-    })()`;
-
-return driver.evaluateAsync(expression,{useIsolation:true}).then(returnedValue=>{
-if(!returnedValue){
-throw new Error('No axe-core results returned');
-}
-if(!Array.isArray(returnedValue.violations)){
-throw new Error('Unable to parse axe results'+returnedValue);
-}
-return returnedValue;
-});
-}}
-
-
-module.exports=Accessibility;
-
-},{"./gatherer":16}],"./gatherers/cache-contents":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-const Gatherer=require('./gatherer');
-
-
-
-function getCacheContents(){
-
-return caches.keys().
-
-
-then(cacheNames=>Promise.all(cacheNames.map(cacheName=>caches.open(cacheName)))).
-
-then(caches=>{
-const requests=[];
-
-
-return Promise.all(caches.map(cache=>{
-return cache.keys().
-then(reqs=>{
-requests.push(...reqs.map(r=>r.url));
-});
-})).then(_=>{
-return requests;
-});
-});
-}
-
-class CacheContents extends Gatherer{
-
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.
-evaluateAsync(`(${getCacheContents.toString()}())`).
-then(returnedValue=>{
-if(!returnedValue||!Array.isArray(returnedValue)){
-throw new Error('Unable to retrieve cache contents');
-}
-return returnedValue;
-});
-}}
-
-
-module.exports=CacheContents;
-
-},{"./gatherer":16}],"./gatherers/chrome-console-messages":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-class ChromeConsoleMessages extends Gatherer{
-constructor(){
-super();
-this._logEntries=[];
-this._onConsoleEntryAdded=this.onConsoleEntry.bind(this);
-}
-
-onConsoleEntry(entry){
-this._logEntries.push(entry);
-}
-
-beforePass(options){
-const driver=options.driver;
-driver.on('Log.entryAdded',this._onConsoleEntryAdded);
-return driver.sendCommand('Log.enable').
-then(()=>driver.sendCommand('Log.startViolationsReport',{
-config:[{name:'discouragedAPIUse',threshold:-1}]}));
-
-}
-
-afterPass(options){
-return Promise.resolve().
-then(_=>options.driver.sendCommand('Log.stopViolationsReport')).
-then(_=>options.driver.off('Log.entryAdded',this._onConsoleEntryAdded)).
-then(_=>options.driver.sendCommand('Log.disable')).
-then(_=>this._logEntries);
-}}
-
-
-module.exports=ChromeConsoleMessages;
-
-},{"./gatherer":16}],"./gatherers/css-usage":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-
-
-
-class CSSUsage extends Gatherer{
-afterPass(options){
-const driver=options.driver;
-
-const stylesheets=[];
-const onStylesheetAdded=sheet=>stylesheets.push(sheet);
-driver.on('CSS.styleSheetAdded',onStylesheetAdded);
-
-return driver.
-sendCommand('DOM.enable').
-then(_=>driver.sendCommand('CSS.enable')).
-then(_=>driver.sendCommand('CSS.startRuleUsageTracking')).
-then(_=>driver.evaluateAsync('getComputedStyle(document.body)')).
-then(_=>{
-driver.off('CSS.styleSheetAdded',onStylesheetAdded);
-const promises=stylesheets.map(sheet=>{
-const styleSheetId=sheet.header.styleSheetId;
-return driver.sendCommand('CSS.getStyleSheetText',{styleSheetId}).then(content=>{
-sheet.content=content.text;
-});
-});
-
-return Promise.all(promises);
-}).
-then(_=>driver.sendCommand('CSS.stopRuleUsageTracking')).
-then(results=>{
-return driver.
-sendCommand('CSS.disable').
-then(_=>driver.sendCommand('DOM.disable')).
-then(_=>{
-const dedupedStylesheets=new Map(stylesheets.map(sheet=>[sheet.content,sheet]));
-return{rules:results.ruleUsage,stylesheets:Array.from(dedupedStylesheets.values())};
-});
-});
-}}
-
-
-module.exports=CSSUsage;
-
-},{"./gatherer":16}],"./gatherers/dobetterweb/all-event-listeners":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-class EventListeners extends Gatherer{
-listenForScriptParsedEvents(){
-this._listener=script=>{
-this._parsedScripts.set(script.scriptId,script);
-};
-this.driver.on('Debugger.scriptParsed',this._listener);
-return this.driver.sendCommand('Debugger.enable');
-}
-
-unlistenForScriptParsedEvents(){
-this.driver.off('Debugger.scriptParsed',this._listener);
-return this.driver.sendCommand('Debugger.disable');
-}
-
-
-
-
-
-
-
-_listEventListeners(nodeIdOrObject){
-let promise;
-
-if(typeof nodeIdOrObject==='string'){
-promise=this.driver.sendCommand('Runtime.evaluate',{
-expression:nodeIdOrObject,
-objectGroup:'event-listeners-gatherer'});
-
-}else{
-promise=this.driver.sendCommand('DOM.resolveNode',{
-nodeId:nodeIdOrObject,
-objectGroup:'event-listeners-gatherer'});
-
-}
-
-return promise.then(result=>{
-const obj=result.object||result.result;
-return this.driver.sendCommand('DOMDebugger.getEventListeners',{
-objectId:obj.objectId}).
-then(results=>{
-return{listeners:results.listeners,tagName:obj.description};
-});
-});
-}
-
-
-
-
-
-
-
-
-
-getEventListeners(nodeId){
-const matchedListeners=[];
-
-return this._listEventListeners(nodeId).then(results=>{
-results.listeners.forEach(listener=>{
-
-
-const script=this._parsedScripts.get(listener.scriptId);
-if(script){
-
-
-
-const combo=Object.assign(listener,script);
-combo.objectName=results.tagName;
-
-
-
-combo.line=combo.lineNumber+1;
-combo.col=combo.columnNumber+1;
-
-matchedListeners.push(combo);
-}
-});
-
-return matchedListeners;
-});
-}
-
-
-
-
-
-
-
-collectListeners(nodes){
-
-return Promise.all(nodes.map(node=>{
-return this.getEventListeners(node.element?node.element.nodeId:node);
-})).then(nestedListeners=>[].concat(...nestedListeners));
-}
-
-
-
-
-
-afterPass(options){
-this.driver=options.driver;
-this._parsedScripts=new Map();
-return options.driver.sendCommand('DOM.enable').
-then(()=>this.listenForScriptParsedEvents()).
-then(()=>this.unlistenForScriptParsedEvents()).
-then(()=>options.driver.getElementsInDocument()).
-then(nodes=>{
-nodes.push('document','window');
-return this.collectListeners(nodes);
-}).then(listeners=>{
-return options.driver.sendCommand('DOM.disable').
-then(()=>listeners);
-});
-}}
-
-
-module.exports=EventListeners;
-
-},{"../gatherer":16}],"./gatherers/dobetterweb/anchors-with-no-rel-noopener":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-const DOMHelpers=require('../../../lib/dom-helpers.js');
-
-class AnchorsWithNoRelNoopener extends Gatherer{
-
-
-
-
-afterPass(options){
-const expression=`(function() {
-      ${DOMHelpers.getElementsInDocumentFnString}; // define function on page
-      const selector = 'a[target="_blank"]:not([rel~="noopener"])';
-      const elements = getElementsInDocument(selector);
-      return elements.map(node => ({
-        href: node.href,
-        rel: node.getAttribute('rel'),
-        target: node.getAttribute('target')
-      }));
-    })()`;
-
-return options.driver.evaluateAsync(expression);
-}}
-
-
-module.exports=AnchorsWithNoRelNoopener;
-
-},{"../../../lib/dom-helpers.js":25,"../gatherer":16}],"./gatherers/dobetterweb/appcache":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-class AppCacheManifest extends Gatherer{
-
-
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelector('html').
-then(node=>node&&node.getAttribute('manifest'));
-}}
-
-
-module.exports=AppCacheManifest;
-
-},{"../gatherer":16}],"./gatherers/dobetterweb/domstats":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-
-
-
-
-
-
-
-function createSelectorsLabel(element){
-let name=element.localName||'';
-const idAttr=element.getAttribute&&element.getAttribute('id');
-if(idAttr){
-name+=`#${idAttr}`;
-}
-
-
-if(element.classList){
-const className=element.classList.toString();
-if(className){
-name+=`.${className.trim().replace(/\s+/g,'.')}`;
-}
-}else if(ShadowRoot.prototype.isPrototypeOf(element)){
-name+='#shadow-root';
-}
-
-return name;
-}
-
-
-
-
-
-
-function elementPathInDOM(element){
-const visited=new Set();
-const path=[createSelectorsLabel(element)];
-let node=element;
-while(node){
-visited.add(node);
-
-
-
-if(ShadowRoot.prototype.isPrototypeOf(node)){
-const isShadowHost=node.host&&node.localName!=='a';
-node=isShadowHost?node.host:node.parentElement;
-}else{
-const isShadowHost=node.parentNode&&node.parentNode.host&&
-node.parentNode.localName!=='a';
-node=isShadowHost?node.parentNode.host:node.parentElement;
-}
-
-if(visited.has(node)){
-node=null;
-}
-
-if(node){
-path.unshift(createSelectorsLabel(node));
-}
-}
-return path;
-}
-
-
-
-
-
-
-
-
-function getDOMStats(element,deep=true){
-let deepestNode=null;
-let maxDepth=0;
-let maxWidth=0;
-let parentWithMostChildren=null;
-
-const _calcDOMWidthAndHeight=function(element,depth=1){
-if(depth>maxDepth){
-deepestNode=element;
-maxDepth=depth;
-}
-if(element.children.length>maxWidth){
-parentWithMostChildren=element;
-maxWidth=element.children.length;
-}
-
-let child=element.firstElementChild;
-while(child){
-_calcDOMWidthAndHeight(child,depth+1);
-
-if(deep&&child.shadowRoot){
-_calcDOMWidthAndHeight(child.shadowRoot,depth+1);
-}
-child=child.nextElementSibling;
-}
-
-return{maxDepth,maxWidth};
-};
-
-const result=_calcDOMWidthAndHeight(element);
-
-return{
-depth:{
-max:result.maxDepth,
-pathToElement:elementPathInDOM(deepestNode)},
-
-width:{
-max:result.maxWidth,
-pathToElement:elementPathInDOM(parentWithMostChildren)}};
-
-
-}
-
-class DOMStats extends Gatherer{
-
-
-
-
-afterPass(options){
-const expression=`(function() {
-      ${createSelectorsLabel.toString()};
-      ${elementPathInDOM.toString()};
-      return (${getDOMStats.toString()}(document.documentElement));
-    })()`;
-return options.driver.sendCommand('DOM.enable').
-then(()=>options.driver.evaluateAsync(expression)).
-then(results=>options.driver.getElementsInDocument().then(allNodes=>{
-results.totalDOMNodes=allNodes.length;
-return options.driver.sendCommand('DOM.disable').then(()=>results);
-}));
-}}
-
-
-module.exports=DOMStats;
-
-},{"../gatherer":16}],"./gatherers/dobetterweb/js-libraries":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-const libDetectorSource="var UNKNOWN_VERSION = null;\nvar d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests = {\n\n    'GWT': {\n        icon: 'gwt',\n        url: 'http://www.gwtproject.org/',\n        test: function(win) {\n            // pretty complicated, many possible tell tales\n            var doc = win.document,\n                hasHistFrame = doc.getElementById('__gwt_historyFrame'),\n                hasGwtUid = doc.gwt_uid,\n                hasBodyListener = doc.body.__listener,\n                hasBodyEventBits = doc.body.__eventBits,\n                hasModules = win.__gwt_activeModules,\n                hasJsonP = win.__gwt_jsonp__,\n                hasRootWinApp = win.__gwt_scriptsLoaded || win.__gwt_stylesLoaded || win.__gwt_activeModules;\n\n            // use the many possible indicators\n            if(hasHistFrame || hasGwtUid || hasBodyListener || hasBodyEventBits || hasModules || hasJsonP || hasRootWinApp) {\n\n                // carefully look at frames, but only if certain is GWT frame\n                var frames = doc.getElementsByTagName('iframe'),\n                    gwtVersion = UNKNOWN_VERSION;\n                for(var n=0; n<frames.length; n++) {\n                    // catch security access errors\n                    try {\n                        var hasNegativeTabIndex = frames[n].tabIndex < 0; // on for GWT\n                        if(hasNegativeTabIndex && frames[n].contentWindow && frames[n].contentWindow.$gwt_version) {\n                            gwtVersion = frames[n].contentWindow.$gwt_version;\n                            break;\n                        }\n                    }\n                    catch(e) {}\n                }\n\n                if(gwtVersion=='0.0.999') {\n                  gwtVersion = 'Google Internal';\n                }\n\n                return { version: gwtVersion };\n            }\n            return false;\n        }\n    },\n\n    'Ink': {\n        icon: 'ink',\n        url: 'http://ink.sapo.pt/',\n        test: function(win) {\n            if (win.Ink && win.Ink.createModule) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Vaadin': {\n        icon: 'vaadin',\n        url: 'http://vaadin.com/home',\n        test: function(win) {\n            if (win.vaadin && win.vaadin.registerWidgetset) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Bootstrap': {\n        icon: 'bootstrap',\n        url: 'http://getbootstrap.com/',\n        npm: 'bootstrap',\n        // look for a function Boostrap has added to jQuery - regex for BS 2 & 3\n        test: function(win) {\n            var jQueryAvailable = win.$ && win.$.fn,\n                RE_PREFIX_V2 = '\\\\$this\\\\.data\\\\((?:\\'|\")',\n                RE_PREFIX_V3 = '\\\\$this\\\\.data\\\\((?:\\'|\")(?:bs\\\\.){1}',\n                bootstrapComponents = [\n                    'affix', 'alert', 'button', 'carousel', 'collapse', 'dropdown',\n                    'modal', 'popover', 'scrollspy', 'tab', 'tooltip'\n                ];\n\n            if(jQueryAvailable) {\n                var bootstrapVersion;\n\n                bootstrapComponents.some(function(component) {\n                    if(win.$.fn[component]) {\n                        // Bootstrap >= 3.2.0 detection\n                        if(win.$.fn[component].Constructor && win.$.fn[component].Constructor.VERSION) {\n                            bootstrapVersion = win.$.fn[component].Constructor.VERSION;\n                            return true;\n                        // Bootstrap >= 2.0.0 and <= 3.1.0 detection\n                        } else if(new RegExp(RE_PREFIX_V3 + component).test(win.$.fn[component].toString())) {\n                            bootstrapVersion = '>= 3.0.0 & <= 3.1.1';\n                            return true;\n                        // Bootstrap < 3.1.0 detection\n                        } else if(new RegExp(RE_PREFIX_V2 + component).test(win.$.fn[component].toString())) {\n                            bootstrapVersion = '>= 2.0.0 & <= 2.3.2';\n                            return true;\n                        }\n                    }\n\n                    return false;\n                });\n\n                if (bootstrapVersion) {\n                    return { version: bootstrapVersion };\n                }\n            }\n\n            return false;\n        }\n    },\n\n    'Zurb': {\n        icon: 'zurb',\n        url: 'http://foundation.zurb.com/',\n        npm: 'foundation-sites',\n        test: function(win) {\n            if(win.Foundation && win.Foundation.Toggler) {\n                return { version: win.Foundation.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Polymer': {\n        icon: 'polymer',\n        url: 'http://www.polymer-project.org/',\n        npm: '@polymer/polymer',\n        test: function(win) {\n            if(win.Polymer && win.Polymer.dom) {\n                return { version: win.Polymer.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Highcharts': {\n        icon: 'highcharts',\n        url: 'http://www.highcharts.com',\n        npm: 'highcharts',\n        test: function(win) {\n            if(win.Highcharts && win.Highcharts.Point) {\n                return { version: win.Highcharts.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'InfoVis': {\n        icon: 'jit',\n        url: 'http://philogb.github.com/jit/',\n        test: function test(win) {\n            if(win.$jit && win.$jit.PieChart) {\n                return { version: win.$jit.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'FlotCharts': {\n        icon: 'icon_48',\n        url: 'http://www.flotcharts.org/',\n        npm: 'flot',\n        test: function(win) {\n            if(win.$ && win.$.plot) {\n                return { version: win.$.plot.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Blackbird': {\n        icon: 'blackbird',\n        url: 'http://www.gscottolson.com/blackbirdjs/',\n        test: function(win) {\n            if(win.log && win.log.warn) {\n                return { version: UNKNOWN_VERSION}; // no version info\n            }\n            return false;\n        }\n    },\n\n    'CreateJS': {\n        icon: 'createjs',\n        url: 'http://createjs.com/#!/CreateJS',\n        npm: 'createjs',\n        test: function(win) {\n            if(win.createjs && win.createjs.promote) {\n                return { version: UNKNOWN_VERSION}; // no version info available\n            }\n            return false;\n        }\n    },\n\n    'Google Maps': {\n        icon: 'gmaps',\n        url: 'https://developers.google.com/maps/',\n        test: function(win) {\n            if (win.google && win.google.maps) {\n                return { version: win.google.maps.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'jQuery': {\n        icon: 'jquery',\n        url: 'http://jquery.com',\n        npm: 'jquery',\n        test: function(win) {\n            var jq = win.jQuery || win.$;\n            if (jq && jq.fn) {\n                return { version: jq.fn.jquery.replace(/[^\\d+\\.+]/g, '') || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'jQuery UI': {\n        icon: 'jquery_ui',\n        url: 'http://jqueryui.com',\n        npm: 'jquery-ui',\n        test: function(win) {\n            var jq = win.jQuery || win.$ || win.$jq || win.$j;\n            if(jq && jq.fn && jq.fn.jquery && jq.ui) {\n                var plugins = 'accordion,datepicker,dialog,draggable,droppable,progressbar,resizable,selectable,slider,menu,grid,tabs'.split(','), concat = [];\n                for (var i=0; i < plugins.length; i++) { if(jq.ui[plugins[i]]) concat.push(plugins[i].substr(0,1).toUpperCase() + plugins[i].substr(1)); }\n                return { version: jq.ui.version || UNKNOWN_VERSION, details: concat.length ? 'Plugins used: '+concat.join(',') : '' };\n            }\n            return false;\n        }\n    },\n\n    'Dojo': {\n        icon: 'dojo',\n        url: 'http://dojotoolkit.org',\n        npm: 'dojo',\n        test: function(win) {\n            if(win.dojo && win.dojo.delegate) {\n                var version = win.dojo.version ? win.dojo.version.toString() : UNKNOWN_VERSION;\n                return { version: version, details: 'Details: '+(win.dijit ? 'Uses Dijit' : 'none') };\n            }\n            return false;\n        }\n    },\n\n    'Prototype': {\n        icon: 'prototype',\n        url: 'http://prototypejs.org',\n        test: function(win) {\n            if(win.Prototype && win.Prototype.BrowserFeatures) {\n                return { version: win.Prototype.Version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Scriptaculous': {\n        icon: 'scriptaculous',\n        url: 'http://script.aculo.us',\n        test: function(win) {\n            if(win.Scriptaculous && win.Scriptaculous.load) {\n                return { version: win.Scriptaculous.Version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'MooTools': {\n        icon: 'mootools',\n        url: 'http://mootools.net',\n        test: function(win) {\n            if(win.MooTools && win.MooTools.build) {\n                return { version: win.MooTools.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Spry': {\n        icon: 'spry',\n        url: 'http://labs.adobe.com/technologies/spry',\n        test: function(win) {\n            if (win.Spry && win.Spry.Data) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'YUI 2': {\n        icon: 'yui',\n        url: 'http://developer.yahoo.com/yui/2/',\n        test: function(win) {\n            if (win.YAHOO && win.YAHOO.util) {\n                return { version: win.YAHOO.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'YUI 3': {\n        icon: 'yui3',\n        url: 'http://yuilibrary.com/',\n        npm: 'yui',\n        test: function(win) {\n            if (win.YUI && win.YUI.Env) {\n                return { version: win.YUI.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Qooxdoo': {\n        icon: 'qooxdoo',\n        url: 'http://qooxdoo.org',\n        npm: 'qooxdoo',\n        test: function(win) {\n            if(win.qx && win.qx.Bootstrap) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Ext JS': {\n        icon: 'extjs',\n        url: 'http://www.sencha.com/products/extjs',\n        test: function(win) {\n            if (win.Ext && win.Ext.versions) {\n                return { version: win.Ext.versions.core.version };\n            }\n            else if(win.Ext) {\n                return { version: win.Ext.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'base2': {\n        icon: 'base2',\n        url: 'http://code.google.com/p/base2',\n        test: function(win) {\n            if(win.base2 && win.base2.dom) {\n                return { version: win.base2.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Closure Library': {\n        icon: 'closure',\n        url: 'https://developers.google.com/closure/library',\n        npm: 'google-closure-library',\n        test: function(win) {\n            if(win.goog && win.goog.provide) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Rapha&euml;l': {\n        icon: 'raphael',\n        url: 'http://dmitrybaranovskiy.github.io/raphael',\n        test: function(win) {\n            if (win.Raphael && win.Raphael.circle) {\n                return { version: win.Raphael.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'React': {\n        icon: 'react',\n        url: 'https://facebook.github.io/react/',\n        npm: 'react',\n        test: function(win) {\n            var reactRoot = document.getElementById('react-root');\n            var altHasReact = document.querySelector('*[data-reactroot]');\n            if (reactRoot && reactRoot.innerText.length > 0 || altHasReact || win.React && win.React.Component) {\n                return { version: win.React && win.React.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Modernizr': {\n        icon: 'modernizr',\n        url: 'http://www.modernizr.com',\n        npm: 'modernizr',\n        test: function(win) {\n            if (win.Modernizr && win.Modernizr.addTest) {\n                return { version: win.Modernizr._version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Processing.js': {\n        icon: 'processingjs',\n        url: 'http://processingjs.org',\n        npm: 'processing-js',\n        test: function(win) {\n            if(win.Processing && win.Processing.box) {\n                return { version: Processing.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Backbone': {\n        icon: 'backbone',\n        url: 'http://backbonejs.org/',\n        npm: 'backbone',\n        test: function(win) {\n            if (win.Backbone && win.Backbone.Model.extend) {\n                return {version: win.Backbone.VERSION || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Leaflet': {\n        icon: 'leaflet',\n        url: 'http://leafletjs.com',\n        npm: 'leaflet',\n        test: function(win) {\n            // Leaflet 3.1 uses L.Marker and L.VERSION; later versions use L.marker and L.version\n            if (win.L && win.L.GeoJSON && (win.L.marker || win.L.Marker)) {\n                return { version: win.L.version || win.L.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Mapbox': {\n        icon: 'mapbox',\n        url: 'http://mapbox.com',\n        npm: 'mapbox-gl',\n        test: function(win) {\n            if (win.L && win.L.mapbox && win.L.mapbox.geocoder) {\n                return { version: win.L.mapbox.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Lo-Dash': {\n        icon: 'lodash',\n        url: 'http://lodash.com/',\n        npm: 'lodash',\n        test: function(win) {\n            var _ = typeof (_ = win._) == 'function' && _,\n                chain = typeof (chain = _ && _.chain) == 'function' && chain,\n                wrapper = (chain || _ || function() { return {}; })(1);\n\n            if (_ && wrapper.__wrapped__) {\n                return { version: _.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Underscore': {\n        icon: 'underscore',\n        url: 'http://underscorejs.org/',\n        npm: 'underscore',\n        test: function(win) {\n            if (win._ && typeof win._.tap === 'function' &&\n                !d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests['Lo-Dash'].test(win)) {\n                return {version: win._.VERSION || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Sammy': {\n        icon: 'sammy',\n        url: 'http://sammyjs.org',\n        test: function(win) {\n            if (win.Sammy && win.Sammy.Application.curry) {\n                return {version: win.Sammy.VERSION || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Rico': {\n        icon: 'rico',\n        url: 'http://openrico.sourceforge.net/examples/index.html',\n        test:  function(win) {\n            if (win.Rico && window.Rico.checkIfComplete) {\n                return {version: win.Rico.Version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'MochiKit': {\n        icon: 'mochikit',\n        url: 'https://mochi.github.io/mochikit/',\n        test: function(win) {\n            if (win.MochiKit && win.MochiKit.Base.module) {\n                return {version: MochiKit.VERSION || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'gRapha&euml;l': {\n        icon: 'graphael',\n        url: 'http://g.raphaeljs.com',\n        test: function(win) {\n            if (win.Raphael && win.Raphael.fn.g) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Glow': {\n        icon: 'glow',\n        url: 'http://www.bbc.co.uk/glow',\n        test: function(win) {\n            if (win.gloader && win.gloader.getRequests) {\n                return {version: UNKNOWN_VERSION};\n            }\n            else if (win.glow && win.glow.dom) {\n                return {version: win.glow.VERSION || UNKNOWN_VERSION};\n            }\n            else if (win.Glow) {\n                return {version: win.Glow.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Socket.IO': {\n        icon: 'socketio', // currently has no icon\n        url: 'http://socket.io',\n        npm: 'socket.io',\n        test: function(win) {\n            // version 0.6.2 uses only io.Socket; more recent versions also have io.sockets\n            if (win.io && (win.io.sockets || win.io.Socket)) {\n                return {version: win.io.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Mustache': {\n        icon: 'mustache',\n        url: 'http://mustache.github.com',\n        npm: 'mustache',\n        test: function(win) {\n            if (win.Mustache && win.Mustache.to_html) {\n                return {version: win.Mustache.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Fabric.js': {\n        icon: 'icon_48', // currently has no icon\n        url: 'http://fabricjs.com/',\n        npm: 'fabric',\n        test: function(win) {\n            if (win.fabric && win.fabric.util) {\n                return {version: win.fabric.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'FuseJS': {\n        icon: 'fusejs',\n        url: 'http://fusejs.io/',\n        npm: 'fuse.js',\n        test: function(win) {\n            if (win.Fuse) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Tween.js': {\n        icon: 'icon_48', // currently has no icon\n        url: 'https://github.com/sole/tween.js',\n        npm: 'tween.js',\n        test: function(win) {\n            if (win.TWEEN && win.TWEEN.Easing) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'SproutCore': {\n       icon: 'sproutcore',\n       url: 'http://www.sproutcore.com',\n       test: function(win) {\n           if (win.SC && win.SC.Application) {\n               return {version: UNKNOWN_VERSION};\n           }\n           return false;\n       }\n    },\n\n    'Zepto.js': {\n       icon: 'zepto',\n       url: 'http://zeptojs.com',\n       npm: 'zepto',\n       test: function(win) {\n           if (win.Zepto && win.Zepto.fn) {\n               return {version: UNKNOWN_VERSION};\n           }\n           return false;\n       }\n    },\n\n    'three.js': {\n       icon: 'icon_48', // currently has no icon\n       url: 'http://threejs.org/',\n       npm: 'three',\n       test: function(win) {\n           if (win.THREE && win.THREE.REVISION) {\n               return {version: 'r' + win.THREE.REVISION};\n           }\n           else if (win.THREE) {\n               return {version: UNKNOWN_VERSION};\n           }\n           return false;\n       }\n    },\n\n    'PhiloGL': {\n       icon: 'philogl',\n       url: 'http://www.senchalabs.org/philogl/',\n       npm: 'philogl',\n       test: function(win) {\n           if (win.PhiloGL && win.PhiloGL.Camera) {\n               return {version: win.PhiloGL.version || UNKNOWN_VERSION};\n           }\n           return false;\n       }\n    },\n\n    'CamanJS': {\n        icon: 'camanjs',\n        url: 'http://camanjs.com/',\n        npm: 'caman',\n        test: function(win) {\n            if (win.Caman && win.Caman.version) {\n                return {version: win.Caman.version.release};\n            }\n            else if (win.Caman) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'yepnope': {\n        icon: 'yepnope',\n        url: 'http://yepnopejs.com/',\n        test: function(win) {\n            if (win.yepnope && win.yepnope.injectJs) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'LABjs': {\n        icon: 'icon_48',\n        url: 'http://labjs.com/',\n        test: function(win) {\n            if (win.$LAB && win.$LAB.setOptions) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'Head JS': {\n        icon: 'headjs',\n        url: 'http://headjs.com/',\n        npm: 'headjs',\n        test: function(win) {\n            if (win.head && win.head.js) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'ControlJS': {\n        icon: 'icon_48',\n        url: 'http://stevesouders.com/controljs/',\n        test: function(win) {\n            if (win.CJS && win.CJS.start) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'RequireJS': {\n        icon: 'requirejs',\n        url: 'http://requirejs.org/',\n        npm: 'requirejs',\n        test: function(win) {\n            var req = win.require || win.requirejs;\n            if (req && (req.load || (req.s && req.s.contexts && req.s.contexts._ && (req.s.contexts._.loaded || req.s.contexts._.load)))) {\n                return { version: req.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'RightJS': {\n        icon: 'rightjs',\n        url: 'http://rightjs.org/',\n        test: function(win) {\n            if (win.RightJS && win.RightJS.isNode) {\n                return { version: win.RightJS.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'jQuery Tools': {\n       icon: 'jquerytools',\n       url: 'http://jquerytools.github.io/',\n       test: function(win) {\n            var jq = win.jQuery || win.$;\n            if(jq && jq.tools) {\n               return { version: jq.tools.version || UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'Pusher': {\n       icon: 'pusher',\n       url: 'http://pusher.com/docs/pusher_js/',\n       npm: 'pusher-js',\n       test: function(win) {\n            if(win.Pusher && win.Pusher.Channel) {\n               return { version: win.Pusher.VERSION || UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'Paper.js': {\n       icon: 'paperjs',\n       url: 'http://paperjs.org/',\n       npm: 'paper',\n       test: function(win) {\n            if(win.paper && win.paper.Point) {\n               return { version: win.paper.version || UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'Swiffy': {\n       icon: 'icon_48',\n       url: 'http://www.google.com/doubleclick/studio/swiffy/',\n       test: function(win) {\n            if(win.swiffy && win.swiffy.Stage) {\n               return { version: UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'Move': {\n       icon: 'move',\n       url: 'https://github.com/rsms/move',\n       npm: 'move',\n       test: function(win) {\n            if(win.move && win.move.compile) {\n               return { version: win.move.version() || UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'AmplifyJS': {\n       icon: 'amplifyjs',\n       url: 'http://amplifyjs.com/',\n       npm: 'amplifyjs',\n       test: function(win) {\n            if(win.amplify && win.amplify.publish) {\n               return { version: UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'Popcorn.js': {\n       icon: 'popcornjs',\n       url: 'http://popcornjs.org/',\n       test: function(win) {\n            if (win.Popcorn && win.Popcorn.Events) {\n               return { version: win.Popcorn.version || UNKNOWN_VERSION };\n           }\n           return false;\n       }\n    },\n\n    'D3': {\n        icon: 'd3',\n        url: 'http://d3js.org',\n        npm: 'd3',\n        test: function(win) {\n            if (win.d3 && win.d3.select) {\n                return { version: win.d3.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Handlebars': {\n        icon: 'handlebars',\n        url: 'http://handlebarsjs.com/',\n        npm: 'handlebars',\n        test: function(win) {\n            if(win.Handlebars && win.Handlebars.compile) {\n                return { version: win.Handlebars.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Knockout': {\n        icon: 'knockout',\n        url: 'http://knockoutjs.com/',\n        npm: 'knockout',\n        test: function(win) {\n            if (win.ko && win.ko.applyBindings) {\n                return { version: win.ko.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Spine': {\n        icon: 'icon_48',\n        url: 'http://spinejs.com/',\n        test: function(win) {\n            if (win.Spine && win.Spine.Controller) {\n                return {version: win.Spine.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n\n    'jQuery Mobile': {\n        icon: 'jquery_mobile',\n        url: 'http://jquerymobile.com/',\n        npm: 'jquery-mobile',\n        test: function(win) {\n            var jq = win.jQuery || win.$ || win.$jq || win.$j;\n            if(jq && jq.fn && jq.fn.jquery && jq.mobile) {\n                return { version: jq.mobile.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'WebFont Loader': {\n        icon: 'icon_48',\n        url: 'https://github.com/typekit/webfontloader',\n        npm: 'webfontloader',\n        test: function(win) {\n            if(win.WebFont && win.WebFont.load) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Angular': {\n        icon: 'angular',\n        url: 'https://angular.io/',\n        npm: '@angular/core',\n        test: function(win) {\n            var ng = win.document.querySelector('[ng-version]');\n            if (ng) {\n                return { version: ng.getAttribute('ng-version') || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'AngularJS': {\n        icon: 'angularjs',\n        url: 'http://angularjs.org',\n        npm: 'angular',\n        test: function(win) {\n            var ng = win.angular;\n            if(ng && ng.version && ng.version.full) {\n                return { version: ng.version.full };\n            }\n            else if (ng) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Ember.js': {\n        icon: 'emberjs',\n        url: 'http://emberjs.com/',\n        npm: 'ember-source',\n        test: function(win) {\n            var ember = win.Ember || win.Em;\n            if (ember && ember.propertyDidChange) {\n                return { version: ember.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Hammer.js': {\n        icon: 'hammerjs',\n        url: 'http://eightmedia.github.io/hammer.js/',\n        npm: 'hammerjs',\n        test: function(win) {\n            if(win.Hammer && win.Hammer.Pinch) {\n                // Hammer.VERSION available in 1.0.10+\n                return { version: win.Hammer.VERSION || \"&lt; 1.0.10\" };\n            }\n            return false;\n        }\n    },\n\n    'Visibility.js': {\n        icon: 'icon_48',\n        url: 'https://github.com/ai/visibilityjs',\n        npm: 'visibilityjs',\n        test: function(win) {\n            if(win.Visibility && win.Visibility.every) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'Velocity.js': {\n        icon: 'icon_48',\n        url: 'http://velocityjs.org/',\n        npm: 'velocity-animate',\n        test: function(win) {\n            var jq = win.jQuery || win.$,\n                velocity = jq ? jq.Velocity : win.Velocity;\n\n            if(velocity && velocity.RegisterEffect && velocity.version) {\n                return {\n                    version:\n                        velocity.version.major + \".\" +\n                        velocity.version.minor + \".\" +\n                        velocity.version.patch\n                };\n            }\n            else if (velocity && velocity.RegisterEffect) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n\n    'IfVisible.js': {\n        icon: 'icon_48',\n        url: 'http://serkanyersen.github.io/ifvisible.js/',\n        npm: 'ifvisible.js',\n        test: function(win) {\n            var iv = win.ifvisible;\n            if(iv && iv.__ceGUID === \"ifvisible.object.event.identifier\") {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Pixi.js': {\n        icon: 'pixi',\n        url: 'https://github.com/GoodBoyDigital/pixi.js',\n        npm: 'pixi.js',\n        test: function(win) {\n            var px = win.PIXI;\n            if(px && px.WebGLRenderer && px.VERSION) {\n                // version 4.4.3 returns simply \"4.4.3\"; version 1.5.2 returns \"v1.5.2\"\n                return { version: px.VERSION.replace('v', '') || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'DC.js': {\n        icon: 'icon_48',\n        url: 'http://dc-js.github.io/dc.js/',\n        npm: 'dc',\n        test: function(win) {\n            var dc = win.dc;\n            if(dc && dc.registerChart) {\n                return { version: dc.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'GreenSock JS': {\n        icon: 'greensock',\n        url: 'https://github.com/greensock/GreenSock-JS',\n        npm: 'gsap',\n        test: function(win) {\n            if (win.TweenMax && win.TweenMax.pauseAll) {\n                return { version: win.TweenMax.version || UNKNOWN_VERSION }\n            }\n            return false;\n        }\n    },\n    'FastClick': {\n        icon: 'fastclick',\n        url: 'https://github.com/ftlabs/fastclick',\n        npm: 'fastclick',\n        test: function(win) {\n            if(win.FastClick && win.FastClick.notNeeded) {\n                return { version: UNKNOWN_VERSION }\n            }\n            return false;\n        }\n    },\n    'Isotope': {\n        icon: 'isotope',\n        url: 'http://isotope.metafizzy.co/',\n        npm: 'isotope-layout',\n        test: function(win) {\n            if(win.Isotope || (win.$ != null && win.$.Isotope)) {\n                return { version: UNKNOWN_VERSION }\n            }\n            return false;\n        }\n    },\n    'Marionette': {\n        icon: 'marionette',\n        url: 'http://marionettejs.com/',\n        npm: 'backbone.marionette',\n        test: function(win) {\n            if(win.Marionette && win.Marionette.Application) {\n                return { version: win.Marionette.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Can': {\n        icon: 'icon_48',\n        url: 'http://canjs.com/',\n        npm: 'can',\n        test: function (win) {\n            if (win.can && win.can.Construct) {\n                return { version: win.can.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Vue': {\n        icon: 'vue',\n        url: 'http://vuejs.org/',\n        npm: 'vue',\n        test: function(win) {\n            if (win.Vue && win.Vue.nextTick) {\n                return { version: win.Vue.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Two': {\n        icon: 'two',\n        url: 'https://jonobr1.github.io/two.js',\n        npm: 'two.js',\n        test: function(win) {\n            if (win.Two && win.Two.Utils) {\n                return { version: win.Two.Version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Brewser': {\n        icon: 'brewser',\n        url: 'http://handcraftedldn.github.io/brewser/',\n        npm: 'brewser',\n        test: function(win) {\n            if(win.BREWSER && win.BREWSER.ua) {\n                return { version: BREWSER.VERSION || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Material Design Lite': {\n    \ticon: 'mdl',\n    \turl: 'http://www.getmdl.io/',\n        npm: 'material-design-lite',\n    \ttest: function(win) {\n    \t\tif(win.componentHandler && win.componentHandler.upgradeElement) {\n    \t\t\treturn { version: UNKNOWN_VERSION};\n    \t\t}\n    \t\treturn false;\n    \t}\n    },\n    'Kendo UI': {\n        icon: 'kendoui',\n        url: 'https://github.com/telerik/kendo-ui-core',\n        npm: 'kendo-ui-core',\n        test: function(win) {\n            if (win.kendo && win.kendo.View && win.kendo.View.extend) {\n                return {version: win.kendo.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n    'Matter.js': {\n        icon: 'matter-js',\n        url: 'http://brm.io/matter-js/',\n        npm: 'matter-js',\n        test: function(win) {\n            if (win.Matter && win.Matter.Engine) {\n                return {version: UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n    'Riot': {\n        icon: 'riot',\n        url: 'http://riotjs.com/',\n        npm: 'riot',\n        test: function(win) {\n            if (win.riot && win.riot.mixin) {\n                return { version: win.riot.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Sea.js': {\n        icon: 'icon_48',\n        url: 'http://seajs.org/',\n        npm: 'seajs',\n        test: function(win) {\n            if(win.seajs && win.seajs.use) {\n                return { version: win.seajs.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Moment.js': {\n        icon: 'momentjs',\n        url: 'http://momentjs.com/',\n        npm: 'moment',\n        test: function(win) {\n            if(win.moment && (win.moment.isMoment || win.moment.lang)) {\n                // version 1.0.0 has neither \"isMoment\" nor \"version\"\n                return { version: win.moment.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Moment Timezone': {\n        icon: 'momentjs',\n        url: 'http://momentjs.com/timezone/',\n        npm: 'moment-timezone',\n        test: function(win) {\n            if (win.moment && win.moment.tz) {\n                return { version: win.moment.tz.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'ScrollMagic': {\n        icon: 'scrollmagic',\n        url: 'http://scrollmagic.io/',\n        npm: 'scrollmagic',\n        test: function(win) {\n            if (win.ScrollMagic && win.ScrollMagic.Controller) {\n                return {version: ScrollMagic.version || UNKNOWN_VERSION};\n            }\n            return false;\n        }\n    },\n    'SWFObject': {\n        icon: 'icon_48', // currently has no icon\n        url: 'https://github.com/swfobject/swfobject',\n        test: function(win) {\n            if (win.swfobject && win.swfobject.embedSWF) {\n                // 2.x - exact version only for 2.3\n                return { version: win.swfobject.version || UNKNOWN_VERSION };\n            } else if(win.deconcept && win.deconcept.SWFObject) {\n                // 1.x\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'FlexSlider': {\n        icon: 'icon_48', // currently has no icon\n        url: 'https://woocommerce.com/flexslider/',\n        npm: 'flexslider',\n        test: function(win) {\n            var jq = win.jQuery || win.$ || win.$jq || win.$j;\n            if (jq && jq.fn && jq.fn.jquery && jq.flexslider){\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'SPF': {\n        icon: 'icon_48', // currently has no icon\n        url: 'https://youtube.github.io/spfjs/',\n        npm: 'spf',\n        test: function(win) {\n            if (win.spf && win.spf.init) {\n                return { version: UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Numeral.js': {\n        icon: 'icon_48', // currently has no icon\n        url: 'http://numeraljs.com/',\n        npm: 'numeraljs',\n        test: function(win) {\n            if (win.numeral && win.isNumeral) {\n                return { version: win.numeral.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'boomerang.js': {\n        icon: 'icon_48', // currently has no icon\n        url: 'https://soasta.github.io/boomerang/doc/',\n        npm: 'boomerangjs',\n        test: function(win) {\n            if (win.BOOMR && win.BOOMR.utils && win.BOOMR.init) {\n                return { version: win.BOOMR.version || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    },\n    'Framer': {\n        icon: 'framer',\n        url: 'https://framer.com/',\n        npm: 'framerjs',\n        test: function(win) {\n            if (win.Framer && win.Framer.Layer) {\n                return { version: win.Framer.Version.build || UNKNOWN_VERSION };\n            }\n            return false;\n        }\n    }\n};\n";
-
-
-
-
-
-
-
-function detectLibraries(){
-const libraries=[];
-
-
-
-Object.entries(d41d8cd98f00b204e9800998ecf8427e_LibraryDetectorTests).forEach(([name,lib])=>{
-try{
-const result=lib.test(window);
-if(result){
-libraries.push({
-name:name,
-version:result.version,
-npmPkgName:lib.npm});
-
-}
-}catch(e){}
-});
-
-return libraries;
-}
-
-
-class JSLibraries extends Gatherer{
-
-
-
-
-afterPass(options){
-const expression=`(function () {
-      ${libDetectorSource};
-      return (${detectLibraries.toString()}());
-    })()`;
-
-return options.driver.evaluateAsync(expression);
-}}
-
-
-module.exports=JSLibraries;
-
-},{"../gatherer":16}],"./gatherers/dobetterweb/optimized-images":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-const URL=require('../../../lib/url-shim');
-const Sentry=require('../../../lib/sentry');
-
-const JPEG_QUALITY=0.92;
-const WEBP_QUALITY=0.85;
-
-const MINIMUM_IMAGE_SIZE=4096;
-
-
-
-
-
-
-
-
-
-function getOptimizedNumBytes(url){
-return new Promise(function(resolve,reject){
-const img=new Image();
-const canvas=document.createElement('canvas');
-const context=canvas.getContext('2d');
-
-function getTypeStats(type,quality){
-const dataURI=canvas.toDataURL(type,quality);
-const base64=dataURI.slice(dataURI.indexOf(',')+1);
-return{base64:base64.length,binary:atob(base64).length};
-}
-
-img.addEventListener('error',reject);
-img.addEventListener('load',()=>{
-try{
-canvas.height=img.height;
-canvas.width=img.width;
-context.drawImage(img,0,0);
-
-const jpeg=getTypeStats('image/jpeg',0.92);
-const webp=getTypeStats('image/webp',0.85);
-
-resolve({jpeg,webp});
-}catch(err){
-reject(err);
-}
-},false);
-
-img.src=url;
-});
-}
-
-class OptimizedImages extends Gatherer{
-
-
-
-
-
-static filterImageRequests(pageUrl,networkRecords){
-const seenUrls=new Set();
-return networkRecords.reduce((prev,record)=>{
-if(seenUrls.has(record._url)||!record.finished){
-return prev;
-}
-
-seenUrls.add(record._url);
-const isOptimizableImage=record._resourceType&&
-record._resourceType._name==='image'&&
-/image\/(png|bmp|jpeg)/.test(record._mimeType);
-const isSameOrigin=URL.originsMatch(pageUrl,record._url);
-const isBase64DataUri=/^data:.{2,40}base64\s*,/.test(record._url);
-
-if(isOptimizableImage&&record._resourceSize>MINIMUM_IMAGE_SIZE){
-prev.push({
-isSameOrigin,
-isBase64DataUri,
-requestId:record._requestId,
-url:record._url,
-mimeType:record._mimeType,
-resourceSize:record._resourceSize});
-
-}
-
-return prev;
-},[]);
-}
-
-
-
-
-
-
-
-_getEncodedResponse(driver,requestId,encoding){
-const quality=encoding==='jpeg'?JPEG_QUALITY:WEBP_QUALITY;
-const params={requestId,encoding,quality,sizeOnly:true};
-return driver.sendCommand('Audits.getEncodedResponse',params);
-}
-
-
-
-
-
-
-calculateImageStats(driver,networkRecord){
-
-
-return Promise.resolve(networkRecord.requestId).then(requestId=>{
-if(this._getEncodedResponseUnsupported)return;
-return this._getEncodedResponse(driver,requestId,'jpeg').then(jpegData=>{
-return this._getEncodedResponse(driver,requestId,'webp').then(webpData=>{
-return{
-fromProtocol:true,
-originalSize:networkRecord.resourceSize,
-jpegSize:jpegData.encodedSize,
-webpSize:webpData.encodedSize};
-
-});
-}).catch(err=>{
-if(/wasn't found/.test(err.message)){
-
-this._getEncodedResponseUnsupported=true;
-}else{
-throw err;
-}
-});
-}).then(result=>{
-if(result)return result;
-
-
-
-if(!networkRecord.isSameOrigin&&!networkRecord.isBase64DataUri)return null;
-
-const script=`(${getOptimizedNumBytes.toString()})(${JSON.stringify(networkRecord.url)})`;
-return driver.evaluateAsync(script).then(stats=>{
-if(!stats)return null;
-const isBase64DataUri=networkRecord.isBase64DataUri;
-const base64Length=networkRecord.url.length-networkRecord.url.indexOf(',')-1;
-return{
-fromProtocol:false,
-originalSize:isBase64DataUri?base64Length:networkRecord.resourceSize,
-jpegSize:isBase64DataUri?stats.jpeg.base64:stats.jpeg.binary,
-webpSize:isBase64DataUri?stats.webp.base64:stats.webp.binary};
-
-});
-});
-}
-
-
-
-
-
-
-computeOptimizedImages(driver,imageRecords){
-return imageRecords.reduce((promise,record)=>{
-return promise.then(results=>{
-return this.calculateImageStats(driver,record).
-catch(err=>{
-
-
-Sentry.captureException(err,{
-tags:{gatherer:'OptimizedImages'},
-extra:{imageUrl:URL.elideDataURI(record.url)},
-level:'warning'});
-
-return{failed:true,err};
-}).
-then(stats=>{
-if(!stats){
-return results;
-}
-
-return results.concat(Object.assign(stats,record));
-});
-});
-},Promise.resolve([]));
-}
-
-
-
-
-
-
-afterPass(options,traceData){
-const networkRecords=traceData.networkRecords;
-const imageRecords=OptimizedImages.filterImageRequests(options.url,networkRecords);
-
-return Promise.resolve().
-then(_=>this.computeOptimizedImages(options.driver,imageRecords)).
-then(results=>{
-const successfulResults=results.filter(result=>!result.failed);
-if(results.length&&!successfulResults.length){
-throw new Error('All image optimizations failed');
-}
-
-return results;
-});
-}}
-
-
-module.exports=OptimizedImages;
-
-},{"../../../lib/sentry":33,"../../../lib/url-shim":41,"../gatherer":16}],"./gatherers/dobetterweb/password-inputs-with-prevented-paste":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-const Gatherer=require('../gatherer');
-
-
-
-function findPasswordInputsWithPreventedPaste(){
-
-
-
-
-
-function getOuterHTMLSnippet(node){
-const reOpeningTag=/^.*?>/;
-const match=node.outerHTML.match(reOpeningTag);
-return match&&match[0];
-}
-
-return Array.from(document.querySelectorAll('input[type="password"]')).
-filter(passwordInput=>
-!passwordInput.dispatchEvent(
-new ClipboardEvent('paste',{cancelable:true}))).
-
-
-map(passwordInput=>({
-snippet:getOuterHTMLSnippet(passwordInput)}));
-
-}
-
-class PasswordInputsWithPreventedPaste extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-return driver.evaluateAsync(
-`(${findPasswordInputsWithPreventedPaste.toString()}())`);
-
-}}
-
-
-
-module.exports=PasswordInputsWithPreventedPaste;
-
-},{"../gatherer":16}],"./gatherers/dobetterweb/response-compression":[function(require,module,exports){
-(function(Buffer){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-const gzip=require('zlib').gzip;
-
-const compressionTypes=['gzip','br','deflate'];
-const binaryMimeTypes=['image','audio','video'];
-const CHROME_EXTENSION_PROTOCOL='chrome-extension:';
-
-class ResponseCompression extends Gatherer{
-
-
-
-
-static filterUnoptimizedResponses(networkRecords){
-const unoptimizedResponses=[];
-
-networkRecords.forEach(record=>{
-const mimeType=record.mimeType;
-const resourceType=record.resourceType();
-
-const isBinaryResource=mimeType&&binaryMimeTypes.some(type=>mimeType.startsWith(type));
-const isTextBasedResource=!isBinaryResource&&resourceType&&resourceType.isTextType();
-const isChromeExtensionResource=record.url.startsWith(CHROME_EXTENSION_PROTOCOL);
-
-if(!isTextBasedResource||!record.resourceSize||!record.finished||
-isChromeExtensionResource||!record.transferSize||record.statusCode===304){
-return;
-}
-
-const isContentEncoded=record.responseHeaders.find(header=>
-header.name.toLowerCase()==='content-encoding'&&
-compressionTypes.includes(header.value));
-
-
-if(!isContentEncoded){
-unoptimizedResponses.push({
-requestId:record.requestId,
-url:record.url,
-mimeType:record.mimeType,
-transferSize:record.transferSize,
-resourceSize:record.resourceSize});
-
-}
-});
-
-return unoptimizedResponses;
-}
-
-afterPass(options,traceData){
-const networkRecords=traceData.networkRecords;
-const textRecords=ResponseCompression.filterUnoptimizedResponses(networkRecords);
-
-const driver=options.driver;
-return Promise.all(textRecords.map(record=>{
-const contentPromise=driver.getRequestContent(record.requestId);
-const timeoutPromise=new Promise(resolve=>setTimeout(resolve,3000));
-return Promise.race([contentPromise,timeoutPromise]).then(content=>{
-
-if(!content){
-record.gzipSize=0;
-
-return record;
-}
-
-return new Promise((resolve,reject)=>{
-return gzip(content,(err,res)=>{
-if(err){
-return reject(err);
-}
-
-
-record.gzipSize=Buffer.byteLength(res,'utf8');
-
-resolve(record);
-});
-});
-});
-}));
-}}
-
-
-module.exports=ResponseCompression;
-
-}).call(this,require("buffer").Buffer);
-},{"../gatherer":16,"buffer":54,"zlib":51}],"./gatherers/dobetterweb/tags-blocking-first-paint":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-
-
-
-function collectTagsThatBlockFirstPaint(){
-return new Promise((resolve,reject)=>{
-try{
-const tagList=[...document.querySelectorAll('link, head script[src]')].
-filter(tag=>{
-if(tag.tagName==='SCRIPT'){
-return!tag.hasAttribute('async')&&
-!tag.hasAttribute('defer')&&
-!/^data:/.test(tag.src)&&
-tag.getAttribute('type')!=='module';
-}
-
-
-
-
-const blockingStylesheet=tag.rel==='stylesheet'&&
-window.matchMedia(tag.media).matches&&!tag.disabled;
-const blockingImport=tag.rel==='import'&&!tag.hasAttribute('async');
-return blockingStylesheet||blockingImport;
-}).
-map(tag=>{
-return{
-tagName:tag.tagName,
-url:tag.tagName==='LINK'?tag.href:tag.src,
-src:tag.src,
-href:tag.href,
-rel:tag.rel,
-media:tag.media,
-disabled:tag.disabled};
-
-});
-resolve(tagList);
-}catch(e){
-const friendly='Unable to gather Scripts/Stylesheets/HTML Imports on the page';
-reject(new Error(`${friendly}: ${e.message}`));
-}
-});
-}
-
-function filteredAndIndexedByUrl(networkRecords){
-return networkRecords.reduce((prev,record)=>{
-if(!record.finished){
-return prev;
-}
-
-const isParserGenerated=record._initiator.type==='parser';
-
-
-const isParserScriptOrStyle=/(css|script)/.test(record._mimeType)&&isParserGenerated;
-const isFailedRequest=record._failed;
-const isHtml=record._mimeType&&record._mimeType.includes('html');
-
-
-
-if(isHtml||isParserScriptOrStyle||isFailedRequest&&isParserGenerated){
-prev[record._url]={
-isLinkPreload:record.isLinkPreload,
-transferSize:record._transferSize,
-startTime:record._startTime,
-endTime:record._endTime};
-
-}
-
-return prev;
-},{});
-}
-
-class TagsBlockingFirstPaint extends Gatherer{
-constructor(){
-super();
-this._filteredAndIndexedByUrl=filteredAndIndexedByUrl;
-}
-
-static findBlockingTags(driver,networkRecords){
-const scriptSrc=`(${collectTagsThatBlockFirstPaint.toString()}())`;
-return driver.evaluateAsync(scriptSrc).then(tags=>{
-const requests=filteredAndIndexedByUrl(networkRecords);
-
-return tags.reduce((prev,tag)=>{
-const request=requests[tag.url];
-if(request&&!request.isLinkPreload){
-prev.push({
-tag,
-transferSize:request.transferSize||0,
-startTime:request.startTime,
-endTime:request.endTime});
-
-
-
-requests[tag.url]=null;
-}
-
-return prev;
-},[]);
-});
-}
-
-
-
-
-
-
-afterPass(options,tracingData){
-return TagsBlockingFirstPaint.findBlockingTags(options.driver,tracingData.networkRecords);
-}}
-
-
-module.exports=TagsBlockingFirstPaint;
-
-},{"../gatherer":16}],"./gatherers/dobetterweb/websql":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-const MAX_WAIT_TIMEOUT=500;
-
-class WebSQL extends Gatherer{
-listenForDatabaseEvents(driver){
-let timeout;
-
-return new Promise((resolve,reject)=>{
-driver.once('Database.addDatabase',db=>{
-clearTimeout(timeout);
-driver.sendCommand('Database.disable').then(_=>resolve(db),reject);
-});
-
-driver.sendCommand('Database.enable').catch(reject);
-
-
-
-
-timeout=setTimeout(function(){
-resolve(null);
-},MAX_WAIT_TIMEOUT);
-});
-}
-
-
-
-
-
-
-afterPass(options){
-return this.listenForDatabaseEvents(options.driver).
-then(result=>{
-return result&&result.database;
-});
-}}
-
-
-module.exports=WebSQL;
-
-},{"../gatherer":16}],"./gatherers/fonts":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const Sentry=require('../../lib/sentry');
-const fontFaceDescriptors=[
-'display',
-'family',
-'featureSettings',
-'stretch',
-'style',
-'unicodeRange',
-'variant',
-'weight'];
-
-
-
-
-
-
-
-
-
-function getAllLoadedFonts(descriptors){
-const getFont=fontFace=>{
-const fontRule={};
-descriptors.forEach(descriptor=>{
-fontRule[descriptor]=fontFace[descriptor];
-});
-
-return fontRule;
-};
-
-return document.fonts.ready.then(()=>{
-return Array.from(document.fonts).filter(fontFace=>fontFace.status==='loaded').
-map(getFont);
-});
-}
-
-
-
-
-
-
-function getFontFaceFromStylesheets(){
-
-
-
-
-
-function getSheetsFontFaces(stylesheet){
-const fontUrlRegex='url\\((?:")([^"]+)(?:"|\')\\)';
-const fontFaceRules=[];
-if(stylesheet.cssRules){
-for(const rule of stylesheet.cssRules){
-if(rule instanceof CSSFontFaceRule){
-const fontsObject={
-display:rule.style.fontDisplay||'auto',
-family:rule.style.fontFamily.replace(/"|'/g,''),
-stretch:rule.style.fontStretch||'normal',
-style:rule.style.fontStyle||'normal',
-weight:rule.style.fontWeight||'normal',
-variant:rule.style.fontVariant||'normal',
-unicodeRange:rule.style.unicodeRange||'U+0-10FFFF',
-featureSettings:rule.style.featureSettings||'normal',
-src:[]};
-
-
-if(rule.style.src){
-const matches=rule.style.src.match(new RegExp(fontUrlRegex,'g'));
-if(matches){
-fontsObject.src=matches.map(match=>{
-const res=new RegExp(fontUrlRegex).exec(match);
-return new URL(res[1],location.href).href;
-});
-}
-}
-
-fontFaceRules.push(fontsObject);
-}
-}
-}
-
-return fontFaceRules;
-}
-
-
-
-
-
-
-
-function loadStylesheetWithCORS(oldNode){
-const newNode=oldNode.cloneNode(true);
-
-return new Promise(resolve=>{
-newNode.addEventListener('load',function onload(){
-newNode.removeEventListener('load',onload);
-resolve(getFontFaceFromStylesheets());
-});
-newNode.crossOrigin='anonymous';
-oldNode.parentNode.insertBefore(newNode,oldNode);
-oldNode.remove();
-});
-}
-
-const promises=[];
-
-for(const stylesheet of document.styleSheets){
-try{
-
-if(stylesheet.cssRules===null&&stylesheet.href&&stylesheet.ownerNode&&
-!stylesheet.ownerNode.crossOrigin){
-promises.push(loadStylesheetWithCORS(stylesheet.ownerNode));
-}else{
-promises.push(Promise.resolve(getSheetsFontFaces(stylesheet)));
-}
-}catch(err){
-promises.push({err:{message:err.message,stack:err.stack}});
-}
-}
-
-return Promise.all(promises).then(fontFaces=>[].concat(...fontFaces));
-}
-
-
-class Fonts extends Gatherer{
-_findSameFontFamily(fontFace,fontFacesList){
-return fontFacesList.find(fontItem=>{
-return!fontFaceDescriptors.find(descriptor=>{
-return fontFace[descriptor]!==fontItem[descriptor];
-});
-});
-}
-
-afterPass({driver}){
-const args=JSON.stringify(fontFaceDescriptors);
-return Promise.all(
-[
-driver.evaluateAsync(`(${getAllLoadedFonts.toString()})(${args})`),
-driver.evaluateAsync(`(${getFontFaceFromStylesheets.toString()})()`)]).
-
-then(([loadedFonts,fontFaces])=>{
-return loadedFonts.map(fontFace=>{
-if(fontFace.err){
-const err=new Error(fontFace.err.message);
-err.stack=fontFace.err.stack;
-Sentry.captureException(err,{tags:{gatherer:'Fonts'},level:'warning'});
-return null;
-}
-
-const fontFaceItem=this._findSameFontFamily(fontFace,fontFaces);
-fontFace.src=fontFaceItem&&fontFaceItem.src||[];
-
-return fontFace;
-}).filter(Boolean);
-});
-}}
-
-
-module.exports=Fonts;
-
-},{"../../lib/sentry":33,"./gatherer":16}],"./gatherers/html-without-javascript":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-
-
-
-
-
-
-
-
-function getBodyText(){
-
-const body=document.querySelector('body');
-return Promise.resolve(body?body.innerText:'');
-}
-
-class HTMLWithoutJavaScript extends Gatherer{
-beforePass(options){
-options.disableJavaScript=true;
-}
-
-afterPass(options){
-
-options.disableJavaScript=false;
-
-return options.driver.evaluateAsync(`(${getBodyText.toString()}())`).
-then(result=>{
-if(typeof result!=='string'){
-throw new Error('document body innerText returned by protocol was not a string');
-}
-
-return{
-value:result};
-
-});
-}}
-
-
-module.exports=HTMLWithoutJavaScript;
-
-},{"./gatherer":16}],"./gatherers/http-redirect":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-
-
-
-
-
-class HTTPRedirect extends Gatherer{
-constructor(){
-super();
-this._preRedirectURL=undefined;
-}
-
-beforePass(options){
-this._preRedirectURL=options.url;
-options.url=this._preRedirectURL.replace(/^https/,'http');
-}
-
-afterPass(options){
-
-options.url=this._preRedirectURL;
-
-
-const timeout=options._testTimeout||10000;
-
-const securityPromise=options.driver.getSecurityState().
-then(state=>{
-return{
-value:state.schemeIsCryptographic};
-
-});
-
-let noSecurityChangesTimeout;
-const timeoutPromise=new Promise((resolve,reject)=>{
-
-
-noSecurityChangesTimeout=setTimeout(_=>{
-reject(new Error('Timed out waiting for HTTP redirection.'));
-},timeout);
-});
-
-return Promise.race([
-securityPromise,
-timeoutPromise]).
-then(result=>{
-
-clearTimeout(noSecurityChangesTimeout);
-return result;
-}).catch(err=>{
-clearTimeout(noSecurityChangesTimeout);
-throw err;
-});
-}}
-
-
-module.exports=HTTPRedirect;
-
-},{"./gatherer":16}],"./gatherers/image-usage":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const DOMHelpers=require('../../lib/dom-helpers.js');
-
-
-
-
-function collectImageElementInfo(){
-function getClientRect(element){
-const clientRect=element.getBoundingClientRect();
-return{
-
-top:clientRect.top,
-bottom:clientRect.bottom,
-left:clientRect.left,
-right:clientRect.right};
-
-}
-
-const allElements=getElementsInDocument();
-const allImageElements=allElements.filter(element=>element.localName==='img');
-
-const htmlImages=allImageElements.map(element=>{
-const computedStyle=window.getComputedStyle(element);
-return{
-
-
-src:element.currentSrc,
-width:element.width,
-height:element.height,
-clientWidth:element.clientWidth,
-clientHeight:element.clientHeight,
-clientRect:getClientRect(element),
-naturalWidth:element.naturalWidth,
-naturalHeight:element.naturalHeight,
-isCss:false,
-isPicture:!!element.parentElement&&element.parentElement.tagName==='PICTURE',
-usesObjectFit:computedStyle.getPropertyValue('object-fit')==='cover'||
-computedStyle.getPropertyValue('object-fit')==='contain'};
-
-});
-
-
-
-const CSS_URL_REGEX=/^url\("([^"]+)"\)$/;
-
-const CSS_SIZE_REGEX=/(auto|contain|cover)/;
-
-const cssImages=allElements.reduce((images,element)=>{
-const style=window.getComputedStyle(element);
-if(!CSS_URL_REGEX.test(style.backgroundImage)||
-!CSS_SIZE_REGEX.test(style.backgroundSize)){
-return images;
-}
-
-const imageMatch=style.backgroundImage.match(CSS_URL_REGEX);
-const url=imageMatch[1];
-
-
-const differentImages=images.filter(image=>image.src!==url);
-if(images.length-differentImages.length>2){
-return differentImages;
-}
-
-images.push({
-src:url,
-clientWidth:element.clientWidth,
-clientHeight:element.clientHeight,
-clientRect:getClientRect(element),
-
-naturalWidth:Number.MAX_VALUE,
-naturalHeight:Number.MAX_VALUE,
-isCss:true,
-isPicture:false,
-usesObjectFit:false});
-
-
-return images;
-},[]);
-
-return htmlImages.concat(cssImages);
-}
-
-
-function determineNaturalSize(url){
-return new Promise((resolve,reject)=>{
-const img=new Image();
-img.addEventListener('error',reject);
-img.addEventListener('load',()=>{
-resolve({
-naturalWidth:img.naturalWidth,
-naturalHeight:img.naturalHeight});
-
-});
-
-img.src=url;
-});
-}
-
-class ImageUsage extends Gatherer{
-
-
-
-
-fetchElementWithSizeInformation(element){
-const url=JSON.stringify(element.src);
-return this.driver.evaluateAsync(`(${determineNaturalSize.toString()})(${url})`).
-then(size=>{
-return Object.assign(element,size);
-});
-}
-
-afterPass(options,traceData){
-const driver=this.driver=options.driver;
-const indexedNetworkRecords=traceData.networkRecords.reduce((map,record)=>{
-if(/^image/.test(record._mimeType)&&record.finished){
-map[record._url]={
-url:record.url,
-resourceSize:record.resourceSize,
-startTime:record.startTime,
-endTime:record.endTime,
-responseReceivedTime:record.responseReceivedTime,
-mimeType:record._mimeType};
-
-}
-
-return map;
-},{});
-
-const expression=`(function() {
-      ${DOMHelpers.getElementsInDocumentFnString}; // define function on page
-      return (${collectImageElementInfo.toString()})();
-    })()`;
-
-return driver.evaluateAsync(expression).
-then(elements=>{
-return elements.reduce((promise,element)=>{
-return promise.then(collector=>{
-
-element.networkRecord=indexedNetworkRecords[element.src];
-
-
-
-
-const elementPromise=(element.isPicture||element.isCss)&&element.networkRecord?
-this.fetchElementWithSizeInformation(element):
-Promise.resolve(element);
-
-return elementPromise.then(element=>{
-collector.push(element);
-return collector;
-});
-});
-},Promise.resolve([]));
-});
-}}
-
-
-module.exports=ImageUsage;
-
-},{"../../lib/dom-helpers.js":25,"./gatherer":16}],"./gatherers/js-usage":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-
-
-
-class JsUsage extends Gatherer{
-beforePass(options){
-return options.driver.sendCommand('Profiler.enable').
-then(_=>options.driver.sendCommand('Profiler.startPreciseCoverage'));
-}
-
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.sendCommand('Profiler.takePreciseCoverage').then(results=>{
-return driver.sendCommand('Profiler.stopPreciseCoverage').
-then(_=>driver.sendCommand('Profiler.disable')).
-then(_=>results.result);
-});
-}}
-
-
-module.exports=JsUsage;
-
-
-JsUsage.JsUsageArtifact;
-
-},{"./gatherer":16}],"./gatherers/manifest":[function(require,module,exports){
-(function(Buffer){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const manifestParser=require('../../lib/manifest-parser');
-const BOM_LENGTH=3;
-const BOM_FIRSTCHAR=65279;
-
-
-
-
-
-
-
-class Manifest extends Gatherer{
-
-
-
-
-
-
-
-afterPass(options){
-const manifestPromise=options.driver.getAppManifest();
-const timeoutPromise=new Promise(resolve=>setTimeout(resolve,3000));
-return Promise.race([manifestPromise,timeoutPromise]).
-then(response=>{
-if(!response){
-return null;
-}
-
-const isBomEncoded=response.data.charCodeAt(0)===BOM_FIRSTCHAR;
-if(isBomEncoded){
-response.data=Buffer.from(response.data).slice(BOM_LENGTH).toString();
-}
-
-return manifestParser(response.data,response.url,options.url);
-});
-}}
-
-
-module.exports=Manifest;
-
-}).call(this,require("buffer").Buffer);
-},{"../../lib/manifest-parser":31,"./gatherer":16,"buffer":54}],"./gatherers/mixed-content":[function(require,module,exports){
-(function(Buffer){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const URL=require('../../lib/url-shim');
-
-
-
-
-
-
-
-
-
-
-
-
-
-class MixedContent extends Gatherer{
-constructor(){
-super();
-this.ids=new Set();
-this.url=undefined;
-}
-
-
-
-
-
-upgradeURL(url){
-const parsedURL=new URL(url);
-parsedURL.protocol='https:';
-return parsedURL.href;
-}
-
-
-
-
-
-downgradeURL(url){
-const parsedURL=new URL(url);
-parsedURL.protocol='http:';
-return parsedURL.href;
-}
-
-_onRequestIntercepted(driver,event){
-
-
-
-if(new URL(event.request.url).protocol==='http:'&&
-!URL.equalWithExcludedFragments(event.request.url,this.url)&&
-!this.ids.has(event.interceptionId)){
-this.ids.add(event.interceptionId);
-event.request.url=this.upgradeURL(event.request.url);
-driver.sendCommand('Network.continueInterceptedRequest',{
-interceptionId:event.interceptionId,
-rawResponse:Buffer.from(
-`HTTP/1.1 302 Found\r\nLocation: ${event.request.url}\r\n\r\n`,
-'utf8').toString('base64')});
-
-}else{
-driver.sendCommand('Network.continueInterceptedRequest',{
-interceptionId:event.interceptionId});
-
-}
-}
-
-beforePass(options){
-const driver=options.driver;
-
-
-
-
-
-options.url=this.downgradeURL(options.url);
-this.url=options.url;
-
-driver.sendCommand('Network.enable',{});
-driver.on('Network.requestIntercepted',
-this._onRequestIntercepted.bind(this,driver));
-driver.sendCommand('Network.setCacheDisabled',{cacheDisabled:true});
-driver.sendCommand('Network.setRequestInterception',
-{patterns:[{urlPattern:'*'}]});
-}
-
-afterPass(options,_){
-const driver=options.driver;
-return Promise.resolve().then(_=>driver.sendCommand(
-'Network.setRequestInterception',{patterns:[]})).
-then(_=>driver.off(
-'Network.requestIntercepted',
-this._onRequestIntercepted.bind(this,driver))).
-then(driver.sendCommand(
-'Network.setCacheDisabled',{cacheDisabled:false})).
-then(_=>{
-return{url:options.url};
-});
-}}
-
-
-module.exports=MixedContent;
-
-}).call(this,require("buffer").Buffer);
-},{"../../lib/url-shim":41,"./gatherer":16,"buffer":54}],"./gatherers/offline":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const URL=require('../../lib/url-shim');
-
-class Offline extends Gatherer{
-beforePass(options){
-return options.driver.goOffline();
-}
-
-afterPass(options,tracingData){
-const navigationRecord=tracingData.networkRecords.filter(record=>{
-return URL.equalWithExcludedFragments(record._url,options.url)&&
-record._fetchedViaServiceWorker;
-}).pop();
-
-return options.driver.goOnline(options).
-then(_=>navigationRecord?navigationRecord.statusCode:-1);
-}}
-
-
-module.exports=Offline;
-
-},{"../../lib/url-shim":41,"./gatherer":16}],"./gatherers/runtime-exceptions":[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-class RuntimeExceptions extends Gatherer{
-constructor(){
-super();
-this._exceptions=[];
-this._onRuntimeExceptionThrown=this.onRuntimeExceptionThrown.bind(this);
-}
-
-onRuntimeExceptionThrown(entry){
-this._exceptions.push(entry);
-}
-
-beforePass(options){
-const driver=options.driver;
-driver.on('Runtime.exceptionThrown',this._onRuntimeExceptionThrown);
-}
-
-afterPass(options){
-return Promise.resolve().
-then(_=>options.driver.off('Runtime.exceptionThrown',this._onRuntimeExceptionThrown)).
-then(_=>this._exceptions);
-}}
-
-
-module.exports=RuntimeExceptions;
-
-},{"./gatherer":16}],"./gatherers/scripts":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const WebInspector=require('../../lib/web-inspector');
-
-
-
-
-class Scripts extends Gatherer{
-
-
-
-
-
-afterPass(options,traceData){
-const driver=options.driver;
-
-const scriptContentMap={};
-const scriptRecords=traceData.networkRecords.
-filter(record=>record.resourceType()===WebInspector.resourceTypes.Script);
-
-return scriptRecords.reduce((promise,record)=>{
-return promise.
-then(()=>{
-return driver.getRequestContent(record.requestId).
-catch(_=>null).
-then(content=>{
-if(!content)return;
-scriptContentMap[record.requestId]=content;
-});
-}).
-then(()=>scriptContentMap);
-},Promise.resolve(scriptContentMap));
-}}
-
-
-module.exports=Scripts;
-
-},{"../../lib/web-inspector":42,"./gatherer":16}],"./gatherers/seo/canonical":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-class Canonical extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelectorAll('head link[rel="canonical" i]').
-then(nodes=>Promise.all(nodes.map(node=>node.getAttribute('href'))));
-}}
-
-
-module.exports=Canonical;
-
-
-},{"../gatherer":16}],"./gatherers/seo/crawlable-links":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-const DOMHelpers=require('../../../lib/dom-helpers.js');
-
-class CrawlableLinks extends Gatherer{
-
-
-
-
-afterPass(options){
-const expression=`(function() {
-      ${DOMHelpers.getElementsInDocumentFnString}; // define function on page
-      const selector = 'a[href]:not([rel~="nofollow"])';
-      const elements = getElementsInDocument(selector);
-      return elements
-        .map(node => ({
-          href: node.href,
-          text: node.innerText
-        }));
-    })()`;
-
-return options.driver.evaluateAsync(expression);
-}}
-
-
-module.exports=CrawlableLinks;
-
-
-},{"../../../lib/dom-helpers.js":25,"../gatherer":16}],"./gatherers/seo/embedded-content":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-const DOMHelpers=require('../../../lib/dom-helpers.js');
-
-class EmbeddedContent extends Gatherer{
-
-
-
-
-afterPass(options){
-const expression=`(function() {
-      ${DOMHelpers.getElementsInDocumentFnString}; // define function on page
-      const selector = 'object, embed, applet';
-      const elements = getElementsInDocument(selector);
-      return elements
-        .map(node => ({
-          tagName: node.tagName,
-          type: node.getAttribute('type'),
-          src: node.getAttribute('src'),
-          data: node.getAttribute('data'),
-          code: node.getAttribute('code'),
-          params: Array.from(node.children)
-            .filter(el => el.tagName === 'PARAM')
-            .map(el => ({
-              name: el.getAttribute('name') || '',
-              value: el.getAttribute('value') || '',
-            })),
-        }));
-    })()`;
-
-return options.driver.evaluateAsync(expression);
-}}
-
-
-module.exports=EmbeddedContent;
-
-},{"../../../lib/dom-helpers.js":25,"../gatherer":16}],"./gatherers/seo/font-size":[function(require,module,exports){
-(function(global){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-
-
-const CSSMatchedStyles=require('../../../lib/web-inspector').CSSMatchedStyles;
-const Gatherer=require('../gatherer');
-const FONT_SIZE_PROPERTY_NAME='font-size';
-const TEXT_NODE_BLOCK_LIST=new Set(['SCRIPT','STYLE','NOSCRIPT']);
-
-const MINIMAL_LEGIBLE_FONT_SIZE_PX=16;
-
-const MAX_NODES_VISITED=500;
-const MAX_NODES_ANALYZED=50;
-
-
-
-
-
-function nodeInBody(node){
-if(!node){
-return false;
-}
-if(node.nodeName==='BODY'){
-return true;
-}
-return nodeInBody(node.parentNode);
-}
-
-
-
-
-
-
-
-function getAllNodesFromBody(driver){
-return driver.getNodesInDocument().
-then(nodes=>{
-const nodeMap=new Map();
-nodes.forEach(node=>nodeMap.set(node.nodeId,node));
-nodes.forEach(node=>node.parentNode=nodeMap.get(node.parentId));
-return nodes.filter(nodeInBody);
-});
-}
-
-
-
-
-
-
-
-
-
-function getEffectiveRule(property,node,{
-inlineStyle,
-attributesStyle,
-matchedCSSRules,
-inherited})
-{
-const cssModel={
-styleSheetHeaderForId:id=>({id})};
-
-
-const nodeType=node.nodeType;
-node.nodeType=()=>nodeType;
-const matchedStyles=new CSSMatchedStyles(
-cssModel,
-node,
-inlineStyle,
-attributesStyle,
-matchedCSSRules,
-null,
-inherited,
-null);
-
-
-const nodeStyles=matchedStyles.nodeStyles();
-const matchingRule=nodeStyles.
-find(style=>
-
-style.allProperties.some(item=>item.name===property&&
-matchedStyles.propertyState(item)!==CSSMatchedStyles.PropertyState.Overloaded));
-
-
-return matchingRule;
-}
-
-
-
-
-
-function getNodeTextLength(node){
-return!node.nodeValue?0:node.nodeValue.trim().length;
-}
-
-
-
-
-
-
-function getFontSizeSourceRule(driver,node){
-return driver.sendCommand('CSS.getMatchedStylesForNode',{nodeId:node.nodeId}).
-then(matchedRules=>getEffectiveRule(FONT_SIZE_PROPERTY_NAME,node,matchedRules));
-}
-
-
-
-
-
-
-function getFontSizeInformation(driver,node){
-return driver.sendCommand('CSS.getComputedStyleForNode',{nodeId:node.parentId}).
-then(result=>{
-const{computedStyle}=result;
-const fontSizeProperty=computedStyle.find(({name})=>name===FONT_SIZE_PROPERTY_NAME);
-
-return{
-fontSize:parseInt(fontSizeProperty.value,10),
-textLength:getNodeTextLength(node),
-node:node.parentNode};
-
-}).
-catch(err=>{
-require('../../../lib/sentry.js').captureException(err);
-return null;
-});
-}
-
-
-
-
-
-function isNonEmptyTextNode(node){
-return node.nodeType===global.Node.TEXT_NODE&&
-!TEXT_NODE_BLOCK_LIST.has(node.parentNode.nodeName)&&
-getNodeTextLength(node)>0;
-}
-
-class FontSize extends Gatherer{
-
-
-
-
-afterPass(options){
-const stylesheets=new Map();
-const onStylesheetAdd=sheet=>stylesheets.set(sheet.header.styleSheetId,sheet.header);
-options.driver.on('CSS.styleSheetAdded',onStylesheetAdd);
-
-const enableDOM=options.driver.sendCommand('DOM.enable');
-const enableCSS=options.driver.sendCommand('CSS.enable');
-
-let failingTextLength=0;
-let visitedTextLength=0;
-let totalTextLength=0;
-
-return Promise.all([enableDOM,enableCSS]).
-then(()=>getAllNodesFromBody(options.driver)).
-then(nodes=>{
-const textNodes=nodes.filter(isNonEmptyTextNode);
-totalTextLength=textNodes.reduce((sum,node)=>sum+=getNodeTextLength(node),0);
-const nodesToVisit=textNodes.
-sort((a,b)=>getNodeTextLength(b)-getNodeTextLength(a)).
-slice(0,MAX_NODES_VISITED);
-
-return nodesToVisit;
-}).
-then(textNodes=>
-Promise.all(textNodes.map(node=>getFontSizeInformation(options.driver,node)))).
-then(fontSizeInfo=>{
-const visitedNodes=fontSizeInfo.filter(Boolean);
-visitedTextLength=visitedNodes.reduce((sum,{textLength})=>sum+=textLength,0);
-const failingNodes=visitedNodes.
-filter(({fontSize})=>fontSize<MINIMAL_LEGIBLE_FONT_SIZE_PX);
-failingTextLength=failingNodes.reduce((sum,{textLength})=>sum+=textLength,0);
-
-return Promise.all(failingNodes.
-sort((a,b)=>b.textLength-a.textLength).
-slice(0,MAX_NODES_ANALYZED).
-map(info=>
-getFontSizeSourceRule(options.driver,info.node).
-then(sourceRule=>{
-if(sourceRule){
-info.cssRule={
-type:sourceRule.type,
-range:sourceRule.range,
-styleSheetId:sourceRule.styleSheetId};
-
-
-if(sourceRule.parentRule){
-info.cssRule.parentRule={
-origin:sourceRule.parentRule.origin,
-selectors:sourceRule.parentRule.selectors};
-
-}
-}
-return info;
-})));
-
-
-}).
-then(analyzedFailingNodesData=>{
-options.driver.off('CSS.styleSheetAdded',onStylesheetAdd);
-
-const analyzedFailingTextLength=analyzedFailingNodesData.
-reduce((sum,{textLength})=>sum+=textLength,0);
-
-analyzedFailingNodesData.
-filter(data=>data.cssRule&&data.cssRule.styleSheetId).
-forEach(data=>data.cssRule.stylesheet=stylesheets.get(data.cssRule.styleSheetId));
-
-return Promise.all([
-options.driver.sendCommand('DOM.disable'),
-options.driver.sendCommand('CSS.disable')]).
-then(_=>({
-analyzedFailingNodesData,
-analyzedFailingTextLength,
-failingTextLength,
-visitedTextLength,
-totalTextLength}));
-
-});
-}}
-
-
-module.exports=FontSize;
-
-
-
-
-
-
-
-
-
-
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"../../../lib/sentry.js":33,"../../../lib/web-inspector":42,"../gatherer":16}],"./gatherers/seo/hreflang":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-class Hreflang extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelectorAll('head link[rel="alternate" i][hreflang]').
-then(nodes=>Promise.all(nodes.map(node=>
-Promise.all([node.getAttribute('href'),node.getAttribute('hreflang')])))).
-
-then(attributeValues=>attributeValues&&
-attributeValues.map(values=>{
-const[href,hreflang]=values;
-return{href,hreflang};
-}));
-
-}}
-
-
-module.exports=Hreflang;
-
-
-},{"../gatherer":16}],"./gatherers/seo/meta-description":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-class MetaDescription extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelector('head meta[name="description" i]').
-then(node=>node&&node.getAttribute('content'));
-}}
-
-
-module.exports=MetaDescription;
-
-
-},{"../gatherer":16}],"./gatherers/seo/meta-robots":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('../gatherer');
-
-class MetaRobots extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelector('head meta[name="robots" i]').
-then(node=>node&&node.getAttribute('content'));
-}}
-
-
-module.exports=MetaRobots;
-
-},{"../gatherer":16}],"./gatherers/service-worker":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-class ServiceWorker extends Gatherer{
-beforePass(options){
-const driver=options.driver;
-return driver.
-getServiceWorkerVersions().
-then(data=>{
-return{
-versions:data.versions};
-
-});
-}}
-
-
-module.exports=ServiceWorker;
-
-},{"./gatherer":16}],"./gatherers/start-url":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-const URL=require('../../lib/url-shim');
-const manifestParser=require('../../lib/manifest-parser');
-
-class StartUrl extends Gatherer{
-constructor(){
-super();
-
-this.startUrl=null;
-this.err=null;
-}
-
-executeFetchRequest(driver,url){
-return driver.evaluateAsync(
-`fetch('${url}')
-        .then(response => response.status)
-        .catch(err => ({fetchFailed: true, message: err.message}))`);
-
-}
-
-pass(options){
-return options.driver.getAppManifest().
-then(response=>{
-return response&&manifestParser(response.data,response.url,options.url);
-}).
-then(manifest=>{
-if(!manifest||!manifest.value){
-const detailedMsg=manifest&&manifest.debugString;
-this.debugString=detailedMsg?
-`Error fetching web app manifest: ${detailedMsg}`:
-`No usable web app manifest found on page ${options.url}`;
-return;
-}
-
-if(manifest.value.start_url.debugString){
-
-
-this.debugString=manifest.value.start_url.debugString;
-}
-
-this.startUrl=manifest.value.start_url.value;
-return this.executeFetchRequest(options.driver,this.startUrl);
-});
-}
-
-afterPass(options,tracingData){
-const networkRecords=tracingData.networkRecords;
-const navigationRecord=networkRecords.filter(record=>{
-return URL.equalWithExcludedFragments(record._url,this.startUrl)&&
-record._fetchedViaServiceWorker;
-}).pop();
-
-const msgWithExtraDebugString=msg=>this.debugString?`${msg}: ${this.debugString}`:msg;
-return options.driver.goOnline(options).
-then(_=>{
-if(!this.startUrl){
-return{
-statusCode:-1,
-debugString:msgWithExtraDebugString('No start URL to fetch')};
-
-}else if(!navigationRecord){
-return{
-statusCode:-1,
-debugString:msgWithExtraDebugString('Unable to fetch start URL via service worker')};
-
-}else{
-return{
-statusCode:navigationRecord.statusCode,
-debugString:this.debugString};
-
-}
-});
-}}
-
-
-module.exports=StartUrl;
-
-},{"../../lib/manifest-parser":31,"../../lib/url-shim":41,"./gatherer":16}],"./gatherers/theme-color":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-class ThemeColor extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelector('head meta[name="theme-color" i]').
-then(node=>node&&node.getAttribute('content'));
-}}
-
-
-module.exports=ThemeColor;
-
-},{"./gatherer":16}],"./gatherers/url":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-class URL extends Gatherer{
-afterPass(options){
-
-
-
-
-return{
-initialUrl:options.initialUrl,
-finalUrl:options.url};
-
-}}
-
-
-module.exports=URL;
-
-},{"./gatherer":16}],"./gatherers/viewport-dimensions":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-
-
-
-function getViewportDimensions(){
-
-
-
-return Promise.resolve({
-innerWidth:window.innerWidth,
-innerHeight:window.innerHeight,
-outerWidth:window.outerWidth,
-outerHeight:window.outerHeight,
-devicePixelRatio:window.devicePixelRatio});
-
-}
-
-class ViewportDimensions extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.evaluateAsync(`(${getViewportDimensions.toString()}())`,{useIsolation:true}).
-
-then(dimensions=>{
-const allNumeric=Object.keys(dimensions).every(key=>Number.isFinite(dimensions[key]));
-if(!allNumeric){
-const results=JSON.stringify(dimensions);
-throw new Error(`ViewportDimensions results were not numeric: ${results}`);
-}
-
-return dimensions;
-});
-}}
-
-
-module.exports=ViewportDimensions;
-
-},{"./gatherer":16}],"./gatherers/viewport":[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Gatherer=require('./gatherer');
-
-class Viewport extends Gatherer{
-
-
-
-
-afterPass(options){
-const driver=options.driver;
-
-return driver.querySelector('head meta[name="viewport" i]').
-then(node=>node&&node.getAttribute('content'));
-}}
-
-
-module.exports=Viewport;
-
-},{"./gatherer":16}],1:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const Audit=require('../audit');
-
-class AxeAudit extends Audit{
-
-
-
-
-
-static audit(artifacts){
-
-
-
-const notApplicables=artifacts.Accessibility.notApplicable||[];
-const isNotApplicable=notApplicables.find(result=>result.id===this.meta.name);
-if(isNotApplicable){
-return{
-rawValue:false,
-notApplicable:true};
-
-}
-
-const violations=artifacts.Accessibility.violations||[];
-const rule=violations.find(result=>result.id===this.meta.name);
-
-let nodeDetails=[];
-if(rule&&rule.nodes){
-nodeDetails=rule.nodes.map(node=>({
-type:'node',
-selector:Array.isArray(node.target)?node.target.join(' '):'',
-path:node.path,
-snippet:node.snippet}));
-
-}
-
-return{
-rawValue:typeof rule==='undefined',
-extendedInfo:{
-value:rule},
-
-details:{
-type:'list',
-header:{
-type:'text',
-text:'View failing elements'},
-
-items:nodeDetails}};
-
-
-}}
-
-
-module.exports=AxeAudit;
-
-},{"../audit":2}],2:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const statistics=require('../lib/statistics');
-
-const DEFAULT_PASS='defaultPass';
-
-class Audit{
-
-
-
-static get DEFAULT_PASS(){
-return DEFAULT_PASS;
-}
-
-
-
-
-static get SCORING_MODES(){
-return{
-NUMERIC:'numeric',
-BINARY:'binary'};
-
-}
-
-
-
-
-static get meta(){
-throw new Error('Audit meta information must be overridden.');
-}
-
-
-
-
-
-
-
-
-
-
-
-static computeLogNormalScore(measuredValue,diminishingReturnsValue,medianValue){
-const distribution=statistics.getLogNormalDistribution(
-medianValue,
-diminishingReturnsValue);
-
-
-let score=100*distribution.computeComplementaryPercentile(measuredValue);
-score=Math.min(100,score);
-score=Math.max(0,score);
-return Math.round(score);
-}
-
-
-
-
-
-
-static generateErrorAuditResult(audit,debugString){
-return Audit.generateAuditResult(audit,{
-rawValue:null,
-error:true,
-debugString});
-
-}
-
-
-
-
-
-
-
-
-static makeTableRows(headings,results){
-const tableRows=results.map(item=>{
-return headings.map(heading=>{
-const value=item[heading.key];
-if(typeof value==='object'&&value&&value.type)return value;
-
-return{
-type:heading.itemType,
-text:value};
-
-});
-});
-return tableRows;
-}
-
-
-
-
-
-static makeTableHeaders(headings){
-return headings.map(heading=>({
-type:'text',
-itemType:heading.itemType,
-text:heading.text}));
-
-}
-
-
-
-
-
-
-static makeTableDetails(headings,results){
-const tableHeaders=Audit.makeTableHeaders(headings);
-const tableRows=Audit.makeTableRows(headings,results);
-return{
-type:'table',
-header:'View Details',
-itemHeaders:tableHeaders,
-items:tableRows};
-
-}
-
-
-
-
-
-
-static generateAuditResult(audit,result){
-if(typeof result.rawValue==='undefined'){
-throw new Error('generateAuditResult requires a rawValue');
-}
-
-const score=typeof result.score==='undefined'?result.rawValue:result.score;
-let displayValue=result.displayValue;
-if(typeof displayValue==='undefined'){
-displayValue=result.rawValue?result.rawValue:'';
-}
-
-
-if(displayValue===score){
-displayValue='';
-}
-let auditDescription=audit.meta.description;
-if(audit.meta.failureDescription){
-if(!score||typeof score==='number'&&score<100){
-auditDescription=audit.meta.failureDescription;
-}
-}
-return{
-score,
-displayValue:`${displayValue}`,
-rawValue:result.rawValue,
-error:result.error,
-debugString:result.debugString,
-extendedInfo:result.extendedInfo,
-scoringMode:audit.meta.scoringMode||Audit.SCORING_MODES.BINARY,
-informative:audit.meta.informative,
-manual:audit.meta.manual,
-notApplicable:result.notApplicable,
-name:audit.meta.name,
-description:auditDescription,
-helpText:audit.meta.helpText,
-details:result.details};
-
-}}
-
-
-module.exports=Audit;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-},{"../lib/statistics":34}],3:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('../audit');
-const Util=require('../../report/v2/renderer/util');
-
-const KB_IN_BYTES=1024;
-
-const WASTED_MS_FOR_AVERAGE=300;
-const WASTED_MS_FOR_POOR=750;
-
-
-
-
-
-class UnusedBytes extends Audit{
-
-
-
-
-static scoreForWastedMs(wastedMs){
-if(wastedMs===0)return 100;else
-if(wastedMs<WASTED_MS_FOR_AVERAGE)return 90;else
-if(wastedMs<WASTED_MS_FOR_POOR)return 65;else
-return 0;
-}
-
-
-
-
-
-static bytesToKbString(bytes){
-return Util.formatBytesToKB(bytes,0);
-}
-
-
-
-
-
-
-static toSavingsString(bytes=0,percent=0){
-const kbDisplay=this.bytesToKbString(bytes);
-const percentDisplay=Util.formatNumber(Math.round(percent))+'%';
-return`${kbDisplay} (${percentDisplay})`;
-}
-
-
-
-
-
-
-static bytesToMsString(bytes,networkThroughput){
-return Util.formatMilliseconds(bytes/networkThroughput*1000,10);
-}
-
-
-
-
-
-
-
-
-
-
-
-static estimateTransferSize(networkRecord,totalBytes,resourceType,compressionRatio=0.5){
-if(!networkRecord){
-
-
-
-return Math.round(totalBytes*compressionRatio);
-}else if(networkRecord._resourceType&&networkRecord._resourceType._name===resourceType){
-
-return networkRecord._transferSize;
-}else{
-
-
-const compressionRatio=networkRecord._transferSize/networkRecord._resourceSize||1;
-return Math.round(totalBytes*compressionRatio);
-}
-}
-
-
-
-
-
-static audit(artifacts){
-const devtoolsLog=artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-return artifacts.requestNetworkRecords(devtoolsLog).
-then(networkRecords=>this.audit_(artifacts,networkRecords)).
-then(result=>{
-return artifacts.requestNetworkThroughput(devtoolsLog).
-then(networkThroughput=>this.createAuditResult(result,networkThroughput));
-});
-}
-
-
-
-
-
-
-static createAuditResult(result,networkThroughput){
-if(!Number.isFinite(networkThroughput)&&result.results.length){
-throw new Error('Invalid network timing information');
-}
-
-const debugString=result.debugString;
-const results=result.results.
-map(item=>{
-const wastedPercent=100*item.wastedBytes/item.totalBytes;
-item.wastedKb=this.bytesToKbString(item.wastedBytes);
-item.wastedMs=this.bytesToMsString(item.wastedBytes,networkThroughput);
-item.totalKb=this.bytesToKbString(item.totalBytes);
-item.totalMs=this.bytesToMsString(item.totalBytes,networkThroughput);
-item.potentialSavings=this.toSavingsString(item.wastedBytes,wastedPercent);
-return item;
-}).
-sort((itemA,itemB)=>itemB.wastedBytes-itemA.wastedBytes);
-
-const wastedBytes=results.reduce((sum,item)=>sum+item.wastedBytes,0);
-const wastedKb=Math.round(wastedBytes/KB_IN_BYTES);
-const wastedMs=Math.round(wastedBytes/networkThroughput*100)*10;
-
-let displayValue=result.displayValue||'';
-if(typeof result.displayValue==='undefined'&&wastedBytes){
-const wastedKbDisplay=this.bytesToKbString(wastedBytes);
-const wastedMsDisplay=this.bytesToMsString(wastedBytes,networkThroughput);
-displayValue=`Potential savings of ${wastedKbDisplay} (~${wastedMsDisplay})`;
-}
-
-const tableDetails=Audit.makeTableDetails(result.headings,results);
-
-return{
-debugString,
-displayValue,
-rawValue:wastedMs,
-score:UnusedBytes.scoreForWastedMs(wastedMs),
-extendedInfo:{
-value:{
-wastedMs,
-wastedKb,
-results}},
-
-
-details:tableDetails};
-
-}
-
-
-
-
-
-static audit_(){
-throw new Error('audit_ unimplemented');
-}}
-
-
-module.exports=UnusedBytes;
-
-},{"../../report/v2/renderer/util":43,"../audit":2}],4:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-const Audit=require('../audit');
-
-class ManualAudit extends Audit{
-
-
-
-static get meta(){
-return{
-informative:true,
-manual:true,
-requiredArtifacts:[]};
-
-}
-
-
-
-
-static audit(){
-return{
-rawValue:false};
-
-
-}}
-
-
-module.exports=ManualAudit;
-
-},{"../audit":2}],5:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-const Audit=require('./audit');
-
-class MultiCheckAudit extends Audit{
-
-
-
-
-static audit(artifacts){
-return Promise.resolve(this.audit_(artifacts)).then(result=>this.createAuditResult(result));
-}
-
-
-
-
-
-static createAuditResult(result){
-const extendedInfo={
-value:result};
-
-
-
-if(result.failures.length>0){
-return{
-rawValue:false,
-debugString:`Failures: ${result.failures.join(', ')}.`,
-extendedInfo};
-
-}
-
-let debugString;
-if(result.warnings&&result.warnings.length>0){
-debugString=`Warnings: ${result.warnings.join(', ')}`;
-}
-
-
-return{
-rawValue:true,
-extendedInfo,
-debugString};
-
-}
-
-
-
-
-static audit_(){
-throw new Error('audit_ unimplemented');
-}}
-
-
-module.exports=MultiCheckAudit;
-
-},{"./audit":2}],6:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Audit=require('./audit');
-
-class ViolationAudit extends Audit{
-
-
-
-
-
-static getViolationResults(artifacts,pattern){
-return artifacts.ChromeConsoleMessages.
-map(message=>message.entry).
-filter(entry=>entry.url&&entry.source==='violation'&&pattern.test(entry.text)).
-map(entry=>Object.assign({label:`line: ${entry.lineNumber}`},entry));
-}}
-
-
-module.exports=ViolationAudit;
-
-},{"./audit":2}],7:[function(require,module,exports){
-(function(__dirname){
-
-
-
-
-
-
-'use strict';
-
-const defaultConfigPath='./default.js';
-const defaultConfig=require('./default.js');
-const fullConfig=require('./full-config.js');
-
-const GatherRunner=require('../gather/gather-runner');
-const log=require('lighthouse-logger');
-const path=require('path');
-const Audit=require('../audits/audit');
-const Runner=require('../runner');
-
-const _flatten=arr=>[].concat(...arr);
-
-
-
-
-
-function cleanTrace(trace){
-const traceEvents=trace.traceEvents;
-
-const threads=[];
-const countsByThread={};
-const traceStartEvents=[];
-const makeMockEvent=(evt,ts)=>{
-return{
-pid:evt.pid,
-tid:evt.tid,
-ts:ts||0,
-ph:'I',
-cat:'disabled-by-default-devtools.timeline',
-name:'TracingStartedInPage',
-args:{
-data:{
-page:evt.frame}},
-
-
-s:'t'};
-
-};
-
-let frame;
-let data;
-let name;
-let counter;
-
-traceEvents.forEach((evt,idx)=>{
-if(evt.name.startsWith('TracingStartedIn')){
-traceStartEvents.push(idx);
-}
-
-
-data=evt.args&&(evt.args.data||evt.args.beginData||evt.args.counters);
-frame=evt.args&&evt.args.frame||data&&(data.frame||data.page);
-
-if(!frame){
-return;
-}
-
-
-name=`pid${evt.pid}-tid${evt.tid}-frame${frame}`;
-counter=countsByThread[name];
-if(!counter){
-counter={
-pid:evt.pid,
-tid:evt.tid,
-frame:frame,
-count:0};
-
-countsByThread[name]=counter;
-threads.push(counter);
-}
-counter.count++;
-});
-
-
-threads.sort((a,b)=>b.count-a.count);
-const mostActiveFrame=threads[0];
-
-
-
-const ts=traceEvents[traceStartEvents[0]]&&traceEvents[traceStartEvents[0]].ts;
-
-
-let i=0;
-for(const dup of traceStartEvents){
-traceEvents.splice(dup-i,1);
-i++;
-}
-
-
-
-traceEvents.unshift(makeMockEvent(mostActiveFrame,ts));
-
-return trace;
-}
-
-function validatePasses(passes,audits,rootPath){
-if(!Array.isArray(passes)){
-return;
-}
-const requiredGatherers=Config.getGatherersNeededByAudits(audits);
-
-
-passes.forEach(pass=>{
-pass.gatherers.forEach(gatherer=>{
-const GathererClass=GatherRunner.getGathererClass(gatherer,rootPath);
-const isGatherRequiredByAudits=requiredGatherers.has(GathererClass.name);
-if(isGatherRequiredByAudits===false){
-const msg=`${GathererClass.name} gatherer requested, however no audit requires it.`;
-log.warn('config',msg);
-}
-});
-});
-
-
-const usedNames=new Set();
-let defaultUsed=false;
-passes.forEach((pass,index)=>{
-let passName=pass.passName;
-if(!passName){
-if(defaultUsed){
-throw new Error(`passes[${index}] requires a passName`);
-}
-
-passName=Audit.DEFAULT_PASS;
-defaultUsed=true;
-}
-
-if(usedNames.has(passName)){
-throw new Error(`Passes must have unique names (repeated passName: ${passName}.`);
-}
-usedNames.add(passName);
-});
-}
-
-function validateCategories(categories,audits,groups){
-if(!categories){
-return;
-}
-
-const auditIds=audits.map(audit=>audit.meta.name);
-Object.keys(categories).forEach(categoryId=>{
-categories[categoryId].audits.forEach((audit,index)=>{
-if(!audit.id){
-throw new Error(`missing an audit id at ${categoryId}[${index}]`);
-}
-
-if(!auditIds.includes(audit.id)){
-throw new Error(`could not find ${audit.id} audit for category ${categoryId}`);
-}
-
-if(categoryId==='accessibility'&&!audit.group){
-throw new Error(`${audit.id} accessibility audit does not have a group`);
-}
-
-if(audit.group&&!groups[audit.group]){
-throw new Error(`${audit.id} references unknown group ${audit.group}`);
-}
-});
-});
-}
-
-function assertValidAudit(auditDefinition,auditPath){
-const auditName=auditPath||auditDefinition.meta.name;
-
-if(typeof auditDefinition.audit!=='function'){
-throw new Error(`${auditName} has no audit() method.`);
-}
-
-if(typeof auditDefinition.meta.name!=='string'){
-throw new Error(`${auditName} has no meta.name property, or the property is not a string.`);
-}
-
-if(typeof auditDefinition.meta.description!=='string'){
-throw new Error(
-`${auditName} has no meta.description property, or the property is not a string.`);
-
-}
-
-
-if(typeof auditDefinition.meta.failureDescription!=='string'&&
-auditDefinition.meta.informative!==true&&
-auditDefinition.meta.scoringMode!==Audit.SCORING_MODES.NUMERIC){
-throw new Error(`${auditName} has no failureDescription and should.`);
-}
-
-if(typeof auditDefinition.meta.helpText!=='string'){
-throw new Error(
-`${auditName} has no meta.helpText property, or the property is not a string.`);
-
-}else if(auditDefinition.meta.helpText===''){
-throw new Error(
-`${auditName} has an empty meta.helpText string. Please add a description for the UI.`);
-
-}
-
-if(!Array.isArray(auditDefinition.meta.requiredArtifacts)){
-throw new Error(
-`${auditName} has no meta.requiredArtifacts property, or the property is not an array.`);
-
-}
-}
-
-function expandArtifacts(artifacts){
-if(!artifacts){
-return null;
-}
-
-if(artifacts.traces){
-Object.keys(artifacts.traces).forEach(key=>{
-log.log('info','Normalizng trace contents into expected state...');
-let trace=require(artifacts.traces[key]);
-
-
-
-if(Array.isArray(trace)){
-trace={
-traceEvents:trace};
-
-}
-trace=cleanTrace(trace);
-
-artifacts.traces[key]=trace;
-});
-}
-
-if(artifacts.devtoolsLogs){
-Object.keys(artifacts.devtoolsLogs).forEach(key=>{
-artifacts.devtoolsLogs[key]=require(artifacts.devtoolsLogs[key]);
-});
-}
-
-return artifacts;
-}
-
-function merge(base,extension){
-if(typeof base==='undefined'){
-return extension;
-}else if(Array.isArray(extension)){
-if(!Array.isArray(base))throw new TypeError(`Expected array but got ${typeof base}`);
-return base.concat(extension);
-}else if(typeof extension==='object'){
-if(typeof base!=='object')throw new TypeError(`Expected object but got ${typeof base}`);
-Object.keys(extension).forEach(key=>{
-base[key]=merge(base[key],extension[key]);
-});
-return base;
-}
-
-return extension;
-}
-
-function deepClone(json){
-return JSON.parse(JSON.stringify(json));
-}
-
-class Config{
-
-
-
-
-
-constructor(configJSON,configPath){
-if(!configJSON){
-configJSON=defaultConfig;
-configPath=path.resolve(__dirname,defaultConfigPath);
-}
-
-if(configPath&&!path.isAbsolute(configPath)){
-throw new Error('configPath must be an absolute path.');
-}
-
-
-const inputConfig=configJSON;
-configJSON=deepClone(configJSON);
-
-
-
-if(Array.isArray(inputConfig.passes)){
-configJSON.passes.forEach((pass,i)=>{
-pass.gatherers=Array.from(inputConfig.passes[i].gatherers);
-});
-}
-if(Array.isArray(inputConfig.audits)){
-configJSON.audits=Array.from(inputConfig.audits);
-}
-
-
-if(configJSON.extends==='lighthouse:full'){
-const explodedFullConfig=Config.extendConfigJSON(deepClone(defaultConfig),
-deepClone(fullConfig));
-configJSON=Config.extendConfigJSON(explodedFullConfig,configJSON);
-}else if(configJSON.extends){
-configJSON=Config.extendConfigJSON(deepClone(defaultConfig),configJSON);
-}
-
-
-if(configJSON.settings&&(
-Array.isArray(configJSON.settings.onlyCategories)||
-Array.isArray(configJSON.settings.onlyAudits)||
-Array.isArray(configJSON.settings.skipAudits))){
-const categoryIds=configJSON.settings.onlyCategories;
-const auditIds=configJSON.settings.onlyAudits;
-const skipAuditIds=configJSON.settings.skipAudits;
-configJSON=Config.generateNewFilteredConfig(configJSON,categoryIds,auditIds,
-skipAuditIds);
-}
-
-
-this._configDir=configPath?path.dirname(configPath):undefined;
-
-this._passes=configJSON.passes||null;
-
-this._audits=Config.requireAudits(configJSON.audits,this._configDir);
-this._artifacts=expandArtifacts(configJSON.artifacts);
-this._categories=configJSON.categories;
-this._groups=configJSON.groups;
-
-
-validatePasses(configJSON.passes,this._audits,this._configDir);
-validateCategories(configJSON.categories,this._audits,this._groups);
-}
-
-
-
-
-
-
-static extendConfigJSON(baseJSON,extendJSON){
-if(extendJSON.passes){
-extendJSON.passes.forEach(pass=>{
-const basePass=baseJSON.passes.find(candidate=>candidate.passName===pass.passName);
-if(!basePass||!pass.passName){
-baseJSON.passes.push(pass);
-}else{
-merge(basePass,pass);
-}
-});
-
-delete extendJSON.passes;
-}
-
-return merge(baseJSON,extendJSON);
-}
-
-
-
-
-
-
-
-
-
-static generateNewFilteredConfig(oldConfig,categoryIds,auditIds,skipAuditIds){
-
-const config=deepClone(oldConfig);
-
-config.categories=Config.filterCategoriesAndAudits(config.categories,categoryIds,auditIds,
-skipAuditIds);
-
-
-const requestedAuditNames=Config.getAuditIdsInCategories(config.categories);
-const auditPathToNameMap=Config.getMapOfAuditPathToName(config);
-config.audits=config.audits.filter(auditPath=>
-requestedAuditNames.has(auditPathToNameMap.get(auditPath)));
-
-
-const auditObjectsSelected=Config.requireAudits(config.audits);
-const requiredGatherers=Config.getGatherersNeededByAudits(auditObjectsSelected);
-
-
-config.passes=Config.generatePassesNeededByGatherers(config.passes,requiredGatherers);
-return config;
-}
-
-
-
-
-
-
-
-
-
-static filterCategoriesAndAudits(oldCategories,categoryIds,auditIds,skipAuditIds){
-if(auditIds&&skipAuditIds){
-throw new Error('Cannot set both skipAudits and onlyAudits');
-}
-
-const categories={};
-const filterByIncludedCategory=!!categoryIds;
-const filterByIncludedAudit=!!auditIds;
-categoryIds=categoryIds||[];
-auditIds=auditIds||[];
-skipAuditIds=skipAuditIds||[];
-
-
-categoryIds.forEach(categoryId=>{
-if(!oldCategories[categoryId]){
-log.warn('config',`unrecognized category in 'onlyCategories': ${categoryId}`);
-}
-});
-
-
-const auditsToValidate=new Set(auditIds.concat(skipAuditIds));
-for(const auditId of auditsToValidate){
-const foundCategory=Object.keys(oldCategories).find(categoryId=>{
-const audits=oldCategories[categoryId].audits;
-return audits.find(candidate=>candidate.id===auditId);
-});
-
-if(!foundCategory){
-const parentKeyName=skipAuditIds.includes(auditId)?'skipAudits':'onlyAudits';
-log.warn('config',`unrecognized audit in '${parentKeyName}': ${auditId}`);
-}
-
-if(auditIds.includes(auditId)&&categoryIds.includes(foundCategory)){
-log.warn('config',`${auditId} in 'onlyAudits' is already included by `+
-`${foundCategory} in 'onlyCategories'`);
-}
-}
-
-Object.keys(oldCategories).forEach(categoryId=>{
-const category=deepClone(oldCategories[categoryId]);
-
-if(filterByIncludedCategory&&filterByIncludedAudit){
-
-if(!categoryIds.includes(categoryId)){
-category.audits=category.audits.filter(audit=>auditIds.includes(audit.id));
-}
-}else if(filterByIncludedCategory){
-
-if(!categoryIds.includes(categoryId)){
-return;
-}
-}else if(filterByIncludedAudit){
-category.audits=category.audits.filter(audit=>auditIds.includes(audit.id));
-}
-
-
-category.audits=category.audits.filter(audit=>!skipAuditIds.includes(audit.id));
-
-if(category.audits.length){
-categories[categoryId]=category;
-}
-});
-
-return categories;
-}
-
-
-
-
-
-
-static getAuditIdsInCategories(categories){
-const audits=_flatten(Object.keys(categories).map(id=>categories[id].audits));
-return new Set(audits.map(audit=>audit.id));
-}
-
-
-
-
-
-static getCategories(config){
-return Object.keys(config.categories).map(id=>{
-const name=config.categories[id].name;
-return{id,name};
-});
-}
-
-
-
-
-
-
-static getMapOfAuditPathToName(config){
-const auditObjectsAll=Config.requireAudits(config.audits);
-const auditPathToName=new Map(auditObjectsAll.map((AuditClass,index)=>{
-const auditPath=config.audits[index];
-const auditName=AuditClass.meta.name;
-return[auditPath,auditName];
-}));
-return auditPathToName;
-}
-
-
-
-
-
-
-static getGatherersNeededByAudits(audits){
-
-
-if(!audits){
-return new Set();
-}
-
-return audits.reduce((list,audit)=>{
-audit.meta.requiredArtifacts.forEach(artifact=>list.add(artifact));
-return list;
-},new Set());
-}
-
-
-
-
-
-
-
-static generatePassesNeededByGatherers(oldPasses,requiredGatherers){
-const auditsNeedTrace=requiredGatherers.has('traces');
-const passes=JSON.parse(JSON.stringify(oldPasses));
-const filteredPasses=passes.map(pass=>{
-
-pass.gatherers=pass.gatherers.filter(gathererName=>{
-gathererName=GatherRunner.getGathererClass(gathererName).name;
-return requiredGatherers.has(gathererName);
-});
-
-
-if(pass.recordTrace&&!auditsNeedTrace){
-const passName=pass.passName||'unknown pass';
-log.warn('config',`Trace not requested by an audit, dropping trace in ${passName}`);
-pass.recordTrace=false;
-}
-
-return pass;
-}).filter(pass=>{
-
-if(pass.recordTrace)return true;
-
-if(pass.passName==='defaultPass')return true;
-return pass.gatherers.length>0;
-});
-return filteredPasses;
-}
-
-
-
-
-
-
-
-
-
-static requireAudits(audits,configPath){
-if(!audits){
-return null;
-}
-
-const coreList=Runner.getAuditList();
-return audits.map(pathOrAuditClass=>{
-let AuditClass;
-if(typeof pathOrAuditClass==='string'){
-const path=pathOrAuditClass;
-
-const coreAudit=coreList.find(a=>a===`${path}.js`);
-let requirePath=`../audits/${path}`;
-if(!coreAudit){
-
-requirePath=Runner.resolvePlugin(path,configPath,'audit');
-}
-AuditClass=require(requirePath);
-assertValidAudit(AuditClass,path);
-}else{
-AuditClass=pathOrAuditClass;
-assertValidAudit(AuditClass);
-}
-
-return AuditClass;
-});
-}
-
-
-get configDir(){
-return this._configDir;
-}
-
-
-get passes(){
-return this._passes;
-}
-
-
-get audits(){
-return this._audits;
-}
-
-
-get artifacts(){
-return this._artifacts;
-}
-
-
-get categories(){
-return this._categories;
-}
-
-
-get groups(){
-return this._groups;
-}}
-
-
-module.exports=Config;
-
-}).call(this,"/../lighthouse-core/config");
-},{"../audits/audit":2,"../gather/gather-runner":15,"../runner":44,"./default.js":8,"./full-config.js":10,"lighthouse-logger":137,"path":69}],8:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-module.exports={
-settings:{},
-passes:[{
-passName:'defaultPass',
-recordTrace:true,
-pauseAfterLoadMs:5250,
-networkQuietThresholdMs:5250,
-cpuQuietThresholdMs:5250,
-useThrottling:true,
-gatherers:[
-'url',
-'scripts',
-'css-usage',
-'viewport',
-'viewport-dimensions',
-'theme-color',
-'manifest',
-'runtime-exceptions',
-'chrome-console-messages',
-'image-usage',
-'accessibility',
-'dobetterweb/all-event-listeners',
-'dobetterweb/anchors-with-no-rel-noopener',
-'dobetterweb/appcache',
-'dobetterweb/domstats',
-'dobetterweb/js-libraries',
-'dobetterweb/optimized-images',
-'dobetterweb/password-inputs-with-prevented-paste',
-'dobetterweb/response-compression',
-'dobetterweb/tags-blocking-first-paint',
-'dobetterweb/websql',
-'seo/meta-description',
-'seo/font-size',
-'seo/crawlable-links',
-'seo/meta-robots',
-'seo/hreflang',
-'seo/embedded-content',
-'seo/canonical',
-'fonts']},
-
-
-{
-passName:'offlinePass',
-useThrottling:false,
-
-networkQuietThresholdMs:0,
-gatherers:[
-'service-worker',
-'offline',
-'start-url']},
-
-
-{
-passName:'redirectPass',
-useThrottling:false,
-
-networkQuietThresholdMs:0,
-
-blockedUrlPatterns:['*.css','*.jpg','*.jpeg','*.png','*.gif','*.svg','*.ttf','*.woff','*.woff2'],
-gatherers:[
-'http-redirect',
-'html-without-javascript']}],
-
-
-audits:[
-'is-on-https',
-'redirects-http',
-'service-worker',
-'works-offline',
-'viewport',
-'without-javascript',
-'first-meaningful-paint',
-'load-fast-enough-for-pwa',
-'speed-index-metric',
-'screenshot-thumbnails',
-'estimated-input-latency',
-'errors-in-console',
-'time-to-first-byte',
-'first-interactive',
-'consistently-interactive',
-'user-timings',
-'critical-request-chains',
-'redirects',
-'webapp-install-banner',
-'splash-screen',
-'themed-omnibox',
-'manifest-short-name-length',
-'content-width',
-'image-aspect-ratio',
-'deprecations',
-'mainthread-work-breakdown',
-'bootup-time',
-'uses-rel-preload',
-'font-display',
-'manual/pwa-cross-browser',
-'manual/pwa-page-transitions',
-'manual/pwa-each-page-has-url',
-'accessibility/accesskeys',
-'accessibility/aria-allowed-attr',
-'accessibility/aria-required-attr',
-'accessibility/aria-required-children',
-'accessibility/aria-required-parent',
-'accessibility/aria-roles',
-'accessibility/aria-valid-attr-value',
-'accessibility/aria-valid-attr',
-'accessibility/audio-caption',
-'accessibility/button-name',
-'accessibility/bypass',
-'accessibility/color-contrast',
-'accessibility/definition-list',
-'accessibility/dlitem',
-'accessibility/document-title',
-'accessibility/duplicate-id',
-'accessibility/frame-title',
-'accessibility/html-has-lang',
-'accessibility/html-lang-valid',
-'accessibility/image-alt',
-'accessibility/input-image-alt',
-'accessibility/label',
-'accessibility/layout-table',
-'accessibility/link-name',
-'accessibility/list',
-'accessibility/listitem',
-'accessibility/meta-refresh',
-'accessibility/meta-viewport',
-'accessibility/object-alt',
-'accessibility/tabindex',
-'accessibility/td-headers-attr',
-'accessibility/th-has-data-cells',
-'accessibility/valid-lang',
-'accessibility/video-caption',
-'accessibility/video-description',
-'accessibility/manual/custom-controls-labels',
-'accessibility/manual/custom-controls-roles',
-'accessibility/manual/focus-traps',
-'accessibility/manual/focusable-controls',
-'accessibility/manual/heading-levels',
-'accessibility/manual/logical-tab-order',
-'accessibility/manual/managed-focus',
-'accessibility/manual/offscreen-content-hidden',
-'accessibility/manual/use-landmarks',
-'accessibility/manual/visual-order-follows-dom',
-'byte-efficiency/uses-long-cache-ttl',
-'byte-efficiency/total-byte-weight',
-'byte-efficiency/offscreen-images',
-'byte-efficiency/unminified-css',
-'byte-efficiency/unminified-javascript',
-'byte-efficiency/unused-css-rules',
-'byte-efficiency/uses-webp-images',
-'byte-efficiency/uses-optimized-images',
-'byte-efficiency/uses-request-compression',
-'byte-efficiency/uses-responsive-images',
-'dobetterweb/appcache-manifest',
-'dobetterweb/dom-size',
-'dobetterweb/external-anchors-use-rel-noopener',
-'dobetterweb/geolocation-on-start',
-'dobetterweb/link-blocking-first-paint',
-'dobetterweb/no-document-write',
-'dobetterweb/no-mutation-events',
-'dobetterweb/no-vulnerable-libraries',
-'dobetterweb/no-websql',
-'dobetterweb/notification-on-start',
-'dobetterweb/password-inputs-can-be-pasted-into',
-'dobetterweb/script-blocking-first-paint',
-'dobetterweb/uses-http2',
-'dobetterweb/uses-passive-event-listeners',
-'seo/meta-description',
-'seo/http-status-code',
-'seo/font-size',
-'seo/link-text',
-'seo/is-crawlable',
-'seo/hreflang',
-'seo/plugins',
-'seo/canonical',
-'seo/manual/mobile-friendly',
-'seo/manual/structured-data'],
-
-
-groups:{
-'perf-metric':{
-title:'Metrics',
-description:'These metrics encapsulate your web app\'s performance across a number of dimensions.'},
-
-'perf-hint':{
-title:'Opportunities',
-description:'These are opportunities to speed up your application by optimizing the following resources.'},
-
-'perf-info':{
-title:'Diagnostics',
-description:'More information about the performance of your application.'},
-
-'a11y-color-contrast':{
-title:'Color Contrast Is Satisfactory',
-description:'These are opportunities to improve the legibility of your content.'},
-
-'a11y-describe-contents':{
-title:'Elements Describe Contents Well',
-description:'These are opportunities to make your content easier to understand for a user of assistive technology, like a screen reader.'},
-
-'a11y-well-structured':{
-title:'Elements Are Well Structured',
-description:'These are opportunities to make sure your HTML is appropriately structured.'},
-
-'a11y-aria':{
-title:'ARIA Attributes Follow Best Practices',
-description:'These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader.'},
-
-'a11y-correct-attributes':{
-title:'Elements Use Attributes Correctly',
-description:'These are opportunities to improve the configuration of your HTML elements.'},
-
-'a11y-element-names':{
-title:'Elements Have Discernible Names',
-description:'These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader.'},
-
-'a11y-language':{
-title:'Page Specifies Valid Language',
-description:'These are opportunities to improve the interpretation of your content by users in different locales.'},
-
-'a11y-meta':{
-title:'Meta Tags Used Properly',
-description:'These are opportunities to improve the user experience of your site.'},
-
-'manual-a11y-checks':{
-title:'Additional items to manually check',
-description:'These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://developers.google.com/web/fundamentals/accessibility/how-to-review).'},
-
-'manual-pwa-checks':{
-title:'Additional items to manually check',
-description:'These checks are required by the baseline '+
-'[PWA Checklist](https://developers.google.com/web/progressive-web-apps/checklist) but are '+
-'not automatically checked by Lighthouse. They do not affect your score but it\'s important that you verify them manually.'},
-
-'seo-mobile':{
-title:'Mobile Friendly',
-description:'Make sure your pages are mobile friendly so users don’t have to pinch or zoom '+
-'in order to read the content pages. [Learn more](https://developers.google.com/search/mobile-sites/).'},
-
-'seo-content':{
-title:'Content Best Practices',
-description:'Format your HTML in a way that enables crawlers to better understand your app’s content.'},
-
-'seo-crawl':{
-title:'Crawling and Indexing',
-description:'To appear in search results, crawlers need access to your app.'},
-
-'manual-seo-checks':{
-title:'Additional items to manually check',
-description:'Run these additional validators on your site to check additional SEO best practices.'}},
-
-
-categories:{
-'performance':{
-name:'Performance',
-description:'These encapsulate your web app\'s current performance and opportunities to improve it.',
-audits:[
-{id:'first-meaningful-paint',weight:5,group:'perf-metric'},
-{id:'first-interactive',weight:5,group:'perf-metric'},
-{id:'consistently-interactive',weight:5,group:'perf-metric'},
-{id:'speed-index-metric',weight:1,group:'perf-metric'},
-{id:'estimated-input-latency',weight:1,group:'perf-metric'},
-{id:'link-blocking-first-paint',weight:0,group:'perf-hint'},
-{id:'script-blocking-first-paint',weight:0,group:'perf-hint'},
-{id:'uses-responsive-images',weight:0,group:'perf-hint'},
-{id:'offscreen-images',weight:0,group:'perf-hint'},
-{id:'unminified-css',weight:0,group:'perf-hint'},
-{id:'unminified-javascript',weight:0,group:'perf-hint'},
-{id:'unused-css-rules',weight:0,group:'perf-hint'},
-{id:'uses-optimized-images',weight:0,group:'perf-hint'},
-{id:'uses-webp-images',weight:0,group:'perf-hint'},
-{id:'uses-request-compression',weight:0,group:'perf-hint'},
-{id:'time-to-first-byte',weight:0,group:'perf-hint'},
-{id:'redirects',weight:0,group:'perf-hint'},
-{id:'uses-rel-preload',weight:0,group:'perf-hint'},
-{id:'total-byte-weight',weight:0,group:'perf-info'},
-{id:'uses-long-cache-ttl',weight:0,group:'perf-info'},
-{id:'dom-size',weight:0,group:'perf-info'},
-{id:'critical-request-chains',weight:0,group:'perf-info'},
-{id:'user-timings',weight:0,group:'perf-info'},
-{id:'bootup-time',weight:0,group:'perf-info'},
-{id:'screenshot-thumbnails',weight:0},
-{id:'mainthread-work-breakdown',weight:0,group:'perf-info'},
-{id:'font-display',weight:0,group:'perf-info'}]},
-
-
-'pwa':{
-name:'Progressive Web App',
-weight:1,
-description:'These checks validate the aspects of a Progressive Web App, as specified by the baseline [PWA Checklist](https://developers.google.com/web/progressive-web-apps/checklist).',
-audits:[
-{id:'service-worker',weight:1},
-{id:'works-offline',weight:1},
-{id:'without-javascript',weight:1},
-{id:'is-on-https',weight:1},
-{id:'redirects-http',weight:1},
-{id:'load-fast-enough-for-pwa',weight:1},
-{id:'webapp-install-banner',weight:1},
-{id:'splash-screen',weight:1},
-{id:'themed-omnibox',weight:1},
-{id:'viewport',weight:1},
-{id:'content-width',weight:1},
-{id:'pwa-cross-browser',weight:0,group:'manual-pwa-checks'},
-{id:'pwa-page-transitions',weight:0,group:'manual-pwa-checks'},
-{id:'pwa-each-page-has-url',weight:0,group:'manual-pwa-checks'}]},
-
-
-'accessibility':{
-name:'Accessibility',
-description:'These checks highlight opportunities to [improve the accessibility of your web app](https://developers.google.com/web/fundamentals/accessibility). Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.',
-audits:[
-{id:'accesskeys',weight:1,group:'a11y-correct-attributes'},
-{id:'aria-allowed-attr',weight:3,group:'a11y-aria'},
-{id:'aria-required-attr',weight:2,group:'a11y-aria'},
-{id:'aria-required-children',weight:5,group:'a11y-aria'},
-{id:'aria-required-parent',weight:2,group:'a11y-aria'},
-{id:'aria-roles',weight:3,group:'a11y-aria'},
-{id:'aria-valid-attr-value',weight:2,group:'a11y-aria'},
-{id:'aria-valid-attr',weight:5,group:'a11y-aria'},
-{id:'audio-caption',weight:4,group:'a11y-correct-attributes'},
-{id:'button-name',weight:10,group:'a11y-element-names'},
-{id:'bypass',weight:10,group:'a11y-describe-contents'},
-{id:'color-contrast',weight:6,group:'a11y-color-contrast'},
-{id:'definition-list',weight:1,group:'a11y-well-structured'},
-{id:'dlitem',weight:1,group:'a11y-well-structured'},
-{id:'document-title',weight:2,group:'a11y-describe-contents'},
-{id:'duplicate-id',weight:5,group:'a11y-well-structured'},
-{id:'frame-title',weight:5,group:'a11y-describe-contents'},
-{id:'html-has-lang',weight:4,group:'a11y-language'},
-{id:'html-lang-valid',weight:1,group:'a11y-language'},
-{id:'image-alt',weight:8,group:'a11y-correct-attributes'},
-{id:'input-image-alt',weight:1,group:'a11y-correct-attributes'},
-{id:'label',weight:10,group:'a11y-describe-contents'},
-{id:'layout-table',weight:1,group:'a11y-describe-contents'},
-{id:'link-name',weight:9,group:'a11y-element-names'},
-{id:'list',weight:5,group:'a11y-well-structured'},
-{id:'listitem',weight:4,group:'a11y-well-structured'},
-{id:'meta-refresh',weight:1,group:'a11y-meta'},
-{id:'meta-viewport',weight:3,group:'a11y-meta'},
-{id:'object-alt',weight:4,group:'a11y-describe-contents'},
-{id:'tabindex',weight:4,group:'a11y-correct-attributes'},
-{id:'td-headers-attr',weight:1,group:'a11y-correct-attributes'},
-{id:'th-has-data-cells',weight:1,group:'a11y-correct-attributes'},
-{id:'valid-lang',weight:1,group:'a11y-language'},
-{id:'video-caption',weight:4,group:'a11y-describe-contents'},
-{id:'video-description',weight:3,group:'a11y-describe-contents'},
-{id:'logical-tab-order',weight:0,group:'manual-a11y-checks'},
-{id:'focusable-controls',weight:0,group:'manual-a11y-checks'},
-{id:'managed-focus',weight:0,group:'manual-a11y-checks'},
-{id:'focus-traps',weight:0,group:'manual-a11y-checks'},
-{id:'custom-controls-labels',weight:0,group:'manual-a11y-checks'},
-{id:'custom-controls-roles',weight:0,group:'manual-a11y-checks'},
-{id:'visual-order-follows-dom',weight:0,group:'manual-a11y-checks'},
-{id:'offscreen-content-hidden',weight:0,group:'manual-a11y-checks'},
-{id:'heading-levels',weight:0,group:'manual-a11y-checks'},
-{id:'use-landmarks',weight:0,group:'manual-a11y-checks'}]},
-
-
-'best-practices':{
-name:'Best Practices',
-description:'We\'ve compiled some recommendations for modernizing your web app and avoiding performance pitfalls.',
-audits:[
-{id:'appcache-manifest',weight:1},
-{id:'no-websql',weight:1},
-{id:'is-on-https',weight:1},
-{id:'uses-http2',weight:1},
-{id:'uses-passive-event-listeners',weight:1},
-{id:'no-mutation-events',weight:1},
-{id:'no-document-write',weight:1},
-{id:'external-anchors-use-rel-noopener',weight:1},
-{id:'geolocation-on-start',weight:1},
-{id:'no-vulnerable-libraries',weight:1},
-{id:'notification-on-start',weight:1},
-{id:'deprecations',weight:1},
-{id:'manifest-short-name-length',weight:1},
-{id:'password-inputs-can-be-pasted-into',weight:1},
-{id:'errors-in-console',weight:1},
-{id:'image-aspect-ratio',weight:1}]},
-
-
-'seo':{
-name:'SEO',
-description:'These checks ensure that your page is optimized for search engine results ranking. '+
-'There are additional factors Lighthouse does not check that may affect your search ranking. '+
-'[Learn more](https://support.google.com/webmasters/answer/35769).',
-audits:[
-{id:'viewport',weight:1,group:'seo-mobile'},
-{id:'document-title',weight:1,group:'seo-content'},
-{id:'meta-description',weight:1,group:'seo-content'},
-{id:'http-status-code',weight:1,group:'seo-crawl'},
-{id:'link-text',weight:1,group:'seo-content'},
-{id:'is-crawlable',weight:1,group:'seo-crawl'},
-{id:'hreflang',weight:1,group:'seo-content'},
-{id:'canonical',weight:1,group:'seo-content'},
-{id:'font-size',weight:1,group:'seo-mobile'},
-{id:'plugins',weight:1,group:'seo-content'},
-{id:'mobile-friendly',weight:0,group:'manual-seo-checks'},
-{id:'structured-data',weight:0,group:'manual-seo-checks'}]}}};
-
-
-
-
-
-},{}],9:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-module.exports={
-extends:'lighthouse:default',
-settings:{
-skipAudits:[
-
-'no-mutation-events',
-'screenshot-thumbnails',
-
-
-'first-meaningful-paint',
-'first-interactive',
-'consistently-interactive',
-'estimated-input-latency',
-'speed-index-metric',
-'offscreen-images',
-'load-fast-enough-for-pwa'],
-
-
-onlyCategories:['performance','pwa','best-practices']},
-
-passes:[
-{
-passName:'defaultPass',
-
-useThrottling:false,
-pauseAfterLoadMs:0,
-networkQuietThresholdMs:500,
-cpuQuietThresholdMs:500,
-
-gatherers:[]}],
-
-
-audits:[
-'predictive-perf'],
-
-categories:{
-performance:{
-audits:[
-{id:'predictive-perf',weight:5,group:'perf-metric'}]}}};
-
-
-
-
-
-},{}],10:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-module.exports={
-extends:'lighthouse:default',
-passes:[
-{
-passName:'extraPass',
-gatherers:[
-'js-usage']}],
-
-
-
-audits:[
-'byte-efficiency/unused-javascript'],
-
-categories:{
-'performance':{
-audits:[
-{id:'unused-javascript',weight:0,group:'perf-hint'}]}}};
-
-
-
-
-
-},{}],11:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const EventEmitter=require('events').EventEmitter;
-const log=require('lighthouse-logger');
-const LHError=require('../../lib/errors');
-
-class Connection{
-constructor(){
-this._lastCommandId=0;
-
-this._callbacks=new Map();
-this._eventEmitter=new EventEmitter();
-}
-
-
-
-
-connect(){
-return Promise.reject(new Error('Not implemented'));
-}
-
-
-
-
-disconnect(){
-return Promise.reject(new Error('Not implemented'));
-}
-
-
-
-
-
-wsEndpoint(){
-return Promise.reject(new Error('Not implemented'));
-}
-
-
-
-
-
-
-
-
-
-sendCommand(method,params={},cmdOpts={}){
-log.formatProtocol('method => browser',{method,params},'verbose');
-const id=++this._lastCommandId;
-const message=JSON.stringify({id,method,params});
-this.sendRawMessage(message);
-return new Promise((resolve,reject)=>{
-this._callbacks.set(id,{resolve,reject,method,options:cmdOpts});
-});
-}
-
-
-
-
-
-
-on(eventName,cb){
-if(eventName!=='notification'){
-throw new Error('Only supports "notification" events');
-}
-this._eventEmitter.on(eventName,cb);
-}
-
-
-
-
-
-
-
-
-sendRawMessage(message){
-return Promise.reject(new Error('Not implemented'));
-}
-
-
-
-
-
-
-
-
-handleRawMessage(message){
-const object=JSON.parse(message);
-
-
-if(this._callbacks.has(object.id)){
-const callback=this._callbacks.get(object.id);
-this._callbacks.delete(object.id);
-
-return callback.resolve(Promise.resolve().then(_=>{
-if(object.error){
-const logLevel=callback.options&&callback.options.silent?'verbose':'error';
-log.formatProtocol('method <= browser ERR',{method:callback.method},logLevel);
-throw LHError.fromProtocolMessage(callback.method,object.error);
-}
-
-log.formatProtocol('method <= browser OK',
-{method:callback.method,params:object.result},'verbose');
-return object.result;
-}));
-}else if(object.id){
-
-
-const error=object.error&&object.error.message;
-log.formatProtocol(`disowned method <= browser ${error?'ERR':'OK'}`,
-{method:object.method,params:error||object.result},'verbose');
-}else{
-log.formatProtocol('<= event',
-{method:object.method,params:object.params},'verbose');
-this.emitNotification(object.method,object.params);
-}
-}
-
-
-
-
-
-
-emitNotification(method,params){
-this._eventEmitter.emit('notification',{method,params});
-}
-
-
-
-
-dispose(){
-this._eventEmitter.removeAllListeners();
-this._eventEmitter=null;
-}}
-
-
-module.exports=Connection;
-
-},{"../../lib/errors":28,"events":56,"lighthouse-logger":137}],12:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Connection=require('./connection.js');
-
-
-
-
-
-
-class Port{
-
-
-
-
-on(eventName,cb){}
-
-
-
-
-send(message){}
-
-close(){}}
-
-
-
-
-class RawConnection extends Connection{
-constructor(port){
-super();
-this._port=port;
-this._port.on('message',this.handleRawMessage.bind(this));
-this._port.on('close',this.dispose.bind(this));
-}
-
-
-
-
-
-connect(){
-return Promise.resolve();
-}
-
-
-
-
-disconnect(){
-this._port.close();
-return Promise.resolve();
-}
-
-
-
-
-
-sendRawMessage(message){
-this._port.send(message);
-}}
-
-
-module.exports=RawConnection;
-
-},{"./connection.js":11}],13:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-class DevtoolsLog{
-
-
-
-constructor(regexFilter){
-this._filter=regexFilter;
-
-
-this._messages=[];
-this._isRecording=false;
-}
-
-
-
-
-get messages(){
-return this._messages;
-}
-
-reset(){
-this._messages=[];
-}
-
-beginRecording(){
-this._isRecording=true;
-}
-
-endRecording(){
-this._isRecording=false;
-}
-
-
-
-
-
-record(message){
-if(this._isRecording&&(!this._filter||this._filter.test(message.method))){
-this._messages.push(message);
-}
-}}
-
-
-module.exports=DevtoolsLog;
-
-},{}],14:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const NetworkRecorder=require('../lib/network-recorder');
-const emulation=require('../lib/emulation');
-const Element=require('../lib/element');
-const EventEmitter=require('events').EventEmitter;
-const URL=require('../lib/url-shim');
-const TraceParser=require('../lib/traces/trace-parser');
-
-const log=require('lighthouse-logger');
-const DevtoolsLog=require('./devtools-log');
-
-
-const DEFAULT_PAUSE_AFTER_LOAD=0;
-
-const DEFAULT_NETWORK_QUIET_THRESHOLD=5000;
-
-const DEFAULT_CPU_QUIET_THRESHOLD=0;
-
-const _uniq=arr=>Array.from(new Set(arr));
-
-class Driver{
-static get MAX_WAIT_FOR_FULLY_LOADED(){
-return 45*1000;
-}
-
-
-
-
-constructor(connection){
-this._traceEvents=[];
-this._traceCategories=Driver.traceCategories;
-this._eventEmitter=new EventEmitter();
-this._connection=connection;
-
-this._devtoolsLog=new DevtoolsLog(/^(Page|Network)\./);
-this.online=true;
-this._domainEnabledCounts=new Map();
-this._isolatedExecutionContextId=undefined;
-
-
-
-
-
-this._networkStatusMonitor=null;
-
-
-
-
-
-this._monitoredUrl=null;
-
-connection.on('notification',event=>{
-this._devtoolsLog.record(event);
-if(this._networkStatusMonitor){
-this._networkStatusMonitor.dispatch(event.method,event.params);
-}
-this._eventEmitter.emit(event.method,event.params);
-});
-}
-
-static get traceCategories(){
-return[
-'-*',
-'toplevel',
-'v8.execute',
-'blink.console',
-'blink.user_timing',
-'benchmark',
-'loading',
-'latencyInfo',
-'devtools.timeline',
-'disabled-by-default-devtools.timeline',
-'disabled-by-default-devtools.timeline.frame',
-'disabled-by-default-devtools.timeline.stack',
-
-
-
-'disabled-by-default-devtools.screenshot'];
-
-}
-
-
-
-
-getUserAgent(){
-
-return this.evaluateAsync('navigator.userAgent');
-}
-
-
-
-
-connect(){
-return this._connection.connect();
-}
-
-disconnect(){
-return this._connection.disconnect();
-}
-
-
-
-
-
-
-wsEndpoint(){
-return this._connection.wsEndpoint();
-}
-
-
-
-
-
-
-on(eventName,cb){
-if(this._eventEmitter===null){
-throw new Error('connect() must be called before attempting to listen to events.');
-}
-
-
-log.formatProtocol('listen for event =>',{method:eventName},'verbose');
-this._eventEmitter.on(eventName,cb);
-}
-
-
-
-
-
-
-
-once(eventName,cb){
-if(this._eventEmitter===null){
-throw new Error('connect() must be called before attempting to listen to events.');
-}
-
-log.formatProtocol('listen once for event =>',{method:eventName},'verbose');
-this._eventEmitter.once(eventName,cb);
-}
-
-
-
-
-
-
-off(eventName,cb){
-if(this._eventEmitter===null){
-throw new Error('connect() must be called before attempting to remove an event listener.');
-}
-
-this._eventEmitter.removeListener(eventName,cb);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-_shouldToggleDomain(domain,enable){
-const enabledCount=this._domainEnabledCounts.get(domain)||0;
-const newCount=enabledCount+(enable?1:-1);
-this._domainEnabledCounts.set(domain,Math.max(0,newCount));
-
-
-if(enable&&newCount===1||!enable&&newCount===0){
-log.verbose('Driver',`${domain}.${enable?'enable':'disable'}`);
-return true;
-}else{
-if(newCount<0){
-log.error('Driver',`Attempted to disable domain '${domain}' when already disabled.`);
-}
-return false;
-}
-}
-
-
-
-
-
-
-
-
-sendCommand(method,params,cmdOpts){
-const domainCommand=/^(\w+)\.(enable|disable)$/.exec(method);
-if(domainCommand){
-const enable=domainCommand[2]==='enable';
-if(!this._shouldToggleDomain(domainCommand[1],enable)){
-return Promise.resolve();
-}
-}
-
-return this._connection.sendCommand(method,params,cmdOpts);
-}
-
-
-
-
-
-
-isDomainEnabled(domain){
-
-return!!this._domainEnabledCounts.get(domain);
-}
-
-
-
-
-
-
-evaluteScriptOnNewDocument(scriptSource){
-return this.sendCommand('Page.addScriptToEvaluateOnLoad',{
-scriptSource});
-
-}
-
-
-
-
-
-
-
-
-
-
-evaluateAsync(expression,options={}){
-const contextIdPromise=options.useIsolation?
-this._getOrCreateIsolatedContextId():
-Promise.resolve(undefined);
-return contextIdPromise.then(contextId=>this._evaluateInContext(expression,contextId));
-}
-
-
-
-
-
-
-
-
-_evaluateInContext(expression,contextId){
-return new Promise((resolve,reject)=>{
-
-const asyncTimeout=setTimeout(
-_=>reject(new Error('The asynchronous expression exceeded the allotted time of 60s')),
-60000);
-
-
-const evaluationParams={
-
-
-
-
-
-expression:`(function wrapInNativePromise() {
-          const __nativePromise = window.__nativePromise || Promise;
-          return new __nativePromise(function (resolve) {
-            return __nativePromise.resolve()
-              .then(_ => ${expression})
-              .catch(${wrapRuntimeEvalErrorInBrowser.toString()})
-              .then(resolve);
-          });
-        }())`,
-includeCommandLineAPI:true,
-awaitPromise:true,
-returnByValue:true,
-contextId};
-
-
-this.sendCommand('Runtime.evaluate',evaluationParams).then(result=>{
-clearTimeout(asyncTimeout);
-const value=result.result.value;
-
-if(result.exceptionDetails){
-
-reject(new Error('an unexpected driver error occurred'));
-}if(value&&value.__failedInBrowser){
-reject(Object.assign(new Error(),value));
-}else{
-resolve(value);
-}
-}).catch(err=>{
-clearTimeout(asyncTimeout);
-reject(err);
-});
-});
-}
-
-getAppManifest(){
-return this.sendCommand('Page.getAppManifest').
-then(response=>{
-
-
-
-if(!response.data){
-
-return null;
-}
-
-return response;
-});
-}
-
-getSecurityState(){
-return new Promise((resolve,reject)=>{
-this.once('Security.securityStateChanged',data=>{
-this.sendCommand('Security.disable').
-then(_=>resolve(data),reject);
-});
-
-this.sendCommand('Security.enable').catch(reject);
-});
-}
-
-getServiceWorkerVersions(){
-return new Promise((resolve,reject)=>{
-const versionUpdatedListener=data=>{
-
-
-const activateCandidates=data.versions.filter(sw=>{
-return sw.status!=='redundant';
-});
-const hasActiveServiceWorker=activateCandidates.find(sw=>{
-return sw.status==='activated';
-});
-
-if(!activateCandidates.length||hasActiveServiceWorker){
-this.off('ServiceWorker.workerVersionUpdated',versionUpdatedListener);
-this.sendCommand('ServiceWorker.disable').
-then(_=>resolve(data),reject);
-}
-};
-
-this.on('ServiceWorker.workerVersionUpdated',versionUpdatedListener);
-
-this.sendCommand('ServiceWorker.enable').catch(reject);
-});
-}
-
-getServiceWorkerRegistrations(){
-return new Promise((resolve,reject)=>{
-this.once('ServiceWorker.workerRegistrationUpdated',data=>{
-this.sendCommand('ServiceWorker.disable').
-then(_=>resolve(data),reject);
-});
-
-this.sendCommand('ServiceWorker.enable').catch(reject);
-});
-}
-
-
-
-
-
-
-
-
-assertNoSameOriginServiceWorkerClients(pageUrl){
-let registrations;
-let versions;
-return this.getServiceWorkerRegistrations().then(data=>{
-registrations=data.registrations;
-}).then(_=>this.getServiceWorkerVersions()).then(data=>{
-versions=data.versions;
-}).then(_=>{
-const origin=new URL(pageUrl).origin;
-
-registrations.
-filter(reg=>{
-const swOrigin=new URL(reg.scopeURL).origin;
-
-return origin===swOrigin;
-}).
-forEach(reg=>{
-versions.forEach(ver=>{
-
-if(ver.registrationId!==reg.registrationId){
-return;
-}
-
-
-if(ver.controlledClients&&ver.controlledClients.length>0){
-throw new Error('You probably have multiple tabs open to the same origin.');
-}
-});
-});
-});
-}
-
-
-
-
-
-
-
-
-_waitForNetworkIdle(networkQuietThresholdMs){
-let idleTimeout;
-let cancel;
-
-const promise=new Promise((resolve,reject)=>{
-const onIdle=()=>{
-
-this._networkStatusMonitor.once('network-2-busy',onBusy);
-idleTimeout=setTimeout(_=>{
-cancel();
-resolve();
-},networkQuietThresholdMs);
-};
-
-const onBusy=()=>{
-this._networkStatusMonitor.once('network-2-idle',onIdle);
-clearTimeout(idleTimeout);
-};
-
-const domContentLoadedListener=()=>{
-if(this._networkStatusMonitor.is2Idle()){
-onIdle();
-}else{
-onBusy();
-}
-};
-
-this.once('Page.domContentEventFired',domContentLoadedListener);
-cancel=()=>{
-clearTimeout(idleTimeout);
-this.off('Page.domContentEventFired',domContentLoadedListener);
-this._networkStatusMonitor.removeListener('network-2-busy',onBusy);
-this._networkStatusMonitor.removeListener('network-2-idle',onIdle);
-};
-});
-
-return{
-promise,
-cancel};
-
-}
-
-
-
-
-
-
-_waitForCPUIdle(waitForCPUQuiet){
-if(!waitForCPUQuiet){
-return{
-promise:Promise.resolve(),
-cancel:()=>undefined};
-
-}
-
-let lastTimeout;
-let cancelled=false;
-
-const checkForQuietExpression=`(${checkTimeSinceLastLongTask.toString()})()`;
-function checkForQuiet(driver,resolve){
-if(cancelled)return;
-
-return driver.evaluateAsync(checkForQuietExpression).
-then(timeSinceLongTask=>{
-if(cancelled)return;
-
-if(typeof timeSinceLongTask==='number'&&timeSinceLongTask>=waitForCPUQuiet){
-log.verbose('Driver',`CPU has been idle for ${timeSinceLongTask} ms`);
-resolve();
-}else{
-log.verbose('Driver',`CPU has been idle for ${timeSinceLongTask} ms`);
-const timeToWait=waitForCPUQuiet-timeSinceLongTask;
-lastTimeout=setTimeout(()=>checkForQuiet(driver,resolve),timeToWait);
-}
-});
-}
-
-let cancel;
-const promise=new Promise((resolve,reject)=>{
-checkForQuiet(this,resolve);
-cancel=()=>{
-cancelled=true;
-if(lastTimeout)clearTimeout(lastTimeout);
-reject(new Error('Wait for CPU idle cancelled'));
-};
-});
-
-return{
-promise,
-cancel};
-
-}
-
-
-
-
-
-
-
-
-_waitForLoadEvent(pauseAfterLoadMs){
-let loadListener;
-let loadTimeout;
-
-const promise=new Promise((resolve,reject)=>{
-loadListener=function(){
-loadTimeout=setTimeout(resolve,pauseAfterLoadMs);
-};
-this.once('Page.loadEventFired',loadListener);
-});
-const cancel=()=>{
-this.off('Page.loadEventFired',loadListener);
-clearTimeout(loadTimeout);
-};
-
-return{
-promise,
-cancel};
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-_waitForFullyLoaded(pauseAfterLoadMs,networkQuietThresholdMs,cpuQuietThresholdMs,
-maxWaitForLoadedMs){
-let maxTimeoutHandle;
-
-
-const waitForLoadEvent=this._waitForLoadEvent(pauseAfterLoadMs);
-
-const waitForNetworkIdle=this._waitForNetworkIdle(networkQuietThresholdMs);
-
-let waitForCPUIdle=null;
-
-
-
-const loadPromise=Promise.all([
-waitForLoadEvent.promise,
-waitForNetworkIdle.promise]).
-then(()=>{
-waitForCPUIdle=this._waitForCPUIdle(cpuQuietThresholdMs);
-return waitForCPUIdle.promise;
-}).then(()=>{
-return function(){
-log.verbose('Driver','loadEventFired and network considered idle');
-clearTimeout(maxTimeoutHandle);
-};
-});
-
-
-
-const maxTimeoutPromise=new Promise((resolve,reject)=>{
-maxTimeoutHandle=setTimeout(resolve,maxWaitForLoadedMs);
-}).then(_=>{
-return function(){
-log.warn('Driver','Timed out waiting for page load. Moving on...');
-waitForLoadEvent.cancel();
-waitForNetworkIdle.cancel();
-waitForCPUIdle&&waitForCPUIdle.cancel();
-};
-});
-
-
-return Promise.race([
-loadPromise,
-maxTimeoutPromise]).
-then(cleanup=>cleanup());
-}
-
-
-
-
-
-
-
-
-
-_beginNetworkStatusMonitoring(startingUrl){
-this._networkStatusMonitor=new NetworkRecorder([]);
-
-
-this._monitoredUrl=startingUrl;
-this._networkStatusMonitor.on('requestloaded',redirectRequest=>{
-
-if(!redirectRequest.redirectSource){
-return;
-}
-const earlierRequest=redirectRequest.redirectSource;
-if(earlierRequest.url===this._monitoredUrl){
-this._monitoredUrl=redirectRequest.url;
-}
-});
-
-return this.sendCommand('Network.enable');
-}
-
-
-
-
-
-
-
-_endNetworkStatusMonitoring(){
-this._networkStatusMonitor=null;
-const finalUrl=this._monitoredUrl;
-this._monitoredUrl=null;
-return finalUrl;
-}
-
-
-
-
-
-
-
-_getOrCreateIsolatedContextId(){
-if(typeof this._isolatedExecutionContextId==='number'){
-return Promise.resolve(this._isolatedExecutionContextId);
-}
-
-return this.sendCommand('Page.getResourceTree').
-then(data=>{
-const mainFrameId=data.frameTree.frame.id;
-return this.sendCommand('Page.createIsolatedWorld',{
-frameId:mainFrameId,
-worldName:'lighthouse_isolated_context'});
-
-}).
-then(data=>this._isolatedExecutionContextId=data.executionContextId);
-}
-
-_clearIsolatedContextId(){
-this._isolatedExecutionContextId=undefined;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-gotoURL(url,options={}){
-const waitForLoad=options.waitForLoad||false;
-const disableJS=options.disableJavaScript||false;
-
-let pauseAfterLoadMs=options.config&&options.config.pauseAfterLoadMs;
-let networkQuietThresholdMs=options.config&&options.config.networkQuietThresholdMs;
-let cpuQuietThresholdMs=options.config&&options.config.cpuQuietThresholdMs;
-let maxWaitMs=options.flags&&options.flags.maxWaitForLoad;
-
-
-if(typeof pauseAfterLoadMs!=='number')pauseAfterLoadMs=DEFAULT_PAUSE_AFTER_LOAD;
-if(typeof networkQuietThresholdMs!=='number')networkQuietThresholdMs=DEFAULT_NETWORK_QUIET_THRESHOLD;
-if(typeof cpuQuietThresholdMs!=='number')cpuQuietThresholdMs=DEFAULT_CPU_QUIET_THRESHOLD;
-if(typeof maxWaitMs!=='number')maxWaitMs=Driver.MAX_WAIT_FOR_FULLY_LOADED;
-
-
-return this._beginNetworkStatusMonitoring(url).
-then(_=>this._clearIsolatedContextId()).
-then(_=>{
-
-
-
-this.sendCommand('Page.enable');
-this.sendCommand('Emulation.setScriptExecutionDisabled',{value:disableJS});
-this.sendCommand('Page.navigate',{url});
-}).
-then(_=>waitForLoad&&this._waitForFullyLoaded(pauseAfterLoadMs,
-networkQuietThresholdMs,cpuQuietThresholdMs,maxWaitMs)).
-then(_=>this._endNetworkStatusMonitoring());
-}
-
-
-
-
-
-
-getObjectProperty(objectId,propName){
-return new Promise((resolve,reject)=>{
-this.sendCommand('Runtime.getProperties',{
-objectId,
-accessorPropertiesOnly:true,
-generatePreview:false,
-ownProperties:false}).
-
-then(properties=>{
-const propertyForName=properties.result.
-find(property=>property.name===propName);
-
-if(propertyForName&&propertyForName.value){
-resolve(propertyForName.value.value);
-}else{
-resolve(null);
-}
-}).catch(reject);
-});
-}
-
-
-
-
-
-
-getRequestContent(requestId){
-return this.sendCommand('Network.getResponseBody',{
-requestId}).
-
-then(result=>result.body);
-}
-
-
-
-
-
-
-queryPermissionState(name){
-const expressionToEval=`
-      navigator.permissions.query({name: '${name}'}).then(result => {
-        return result.state;
-      })
-    `;
-
-return this.evaluateAsync(expressionToEval);
-}
-
-
-
-
-
-querySelector(selector){
-return this.sendCommand('DOM.getDocument').
-then(result=>result.root.nodeId).
-then(nodeId=>this.sendCommand('DOM.querySelector',{
-nodeId,
-selector})).
-
-then(element=>{
-if(element.nodeId===0){
-return null;
-}
-return new Element(element,this);
-});
-}
-
-
-
-
-
-querySelectorAll(selector){
-return this.sendCommand('DOM.getDocument').
-then(result=>result.root.nodeId).
-then(nodeId=>this.sendCommand('DOM.querySelectorAll',{
-nodeId,
-selector})).
-
-then(nodeList=>{
-const elementList=[];
-nodeList.nodeIds.forEach(nodeId=>{
-if(nodeId!==0){
-elementList.push(new Element({nodeId},this));
-}
-});
-return elementList;
-});
-}
-
-
-
-
-
-
-
-getElementsInDocument(pierce=true){
-return this.getNodesInDocument(pierce).
-then(nodes=>nodes.
-filter(node=>node.nodeType===1).
-map(node=>new Element({nodeId:node.nodeId},this)));
-
-}
-
-
-
-
-
-
-
-getNodesInDocument(pierce=true){
-return this.sendCommand('DOM.getFlattenedDocument',{depth:-1,pierce}).
-then(result=>result.nodes?result.nodes:[]);
-}
-
-
-
-
-beginTrace(flags){
-const additionalCategories=flags&&flags.additionalTraceCategories&&
-flags.additionalTraceCategories.split(',')||[];
-const traceCategories=this._traceCategories.concat(additionalCategories);
-const tracingOpts={
-categories:_uniq(traceCategories).join(','),
-transferMode:'ReturnAsStream',
-options:'sampling-frequency=10000'};
-
-
-
-if(this.isDomainEnabled('Debugger')){
-throw new Error('Debugger domain enabled when starting trace');
-}
-if(this.isDomainEnabled('CSS')){
-throw new Error('CSS domain enabled when starting trace');
-}
-if(this.isDomainEnabled('DOM')){
-throw new Error('DOM domain enabled when starting trace');
-}
-
-
-return this.sendCommand('Page.enable').
-
-
-then(_=>this.endTraceIfStarted()).
-then(_=>this.sendCommand('Tracing.start',tracingOpts));
-}
-
-endTraceIfStarted(){
-return new Promise(resolve=>{
-const traceCallback=()=>resolve();
-this.once('Tracing.tracingComplete',traceCallback);
-return this.sendCommand('Tracing.end',undefined,{silent:true}).catch(()=>{
-this.off('Tracing.tracingComplete',traceCallback);
-traceCallback();
-});
-});
-}
-
-endTrace(){
-return new Promise((resolve,reject)=>{
-
-this.once('Tracing.tracingComplete',streamHandle=>{
-this._readTraceFromStream(streamHandle).
-then(traceContents=>resolve(traceContents),reject);
-});
-
-
-return this.sendCommand('Tracing.end').catch(reject);
-});
-}
-
-_readTraceFromStream(streamHandle){
-return new Promise((resolve,reject)=>{
-let isEOF=false;
-const parser=new TraceParser();
-
-const readArguments={
-handle:streamHandle.stream};
-
-
-const onChunkRead=response=>{
-if(isEOF){
-return;
-}
-
-parser.parseChunk(response.data);
-
-if(response.eof){
-isEOF=true;
-return resolve(parser.getTrace());
-}
-
-return this.sendCommand('IO.read',readArguments).then(onChunkRead);
-};
-
-this.sendCommand('IO.read',readArguments).then(onChunkRead).catch(reject);
-});
-}
-
-
-
-
-beginDevtoolsLog(){
-this._devtoolsLog.reset();
-this._devtoolsLog.beginRecording();
-}
-
-
-
-
-
-endDevtoolsLog(){
-this._devtoolsLog.endRecording();
-return this._devtoolsLog.messages;
-}
-
-enableRuntimeEvents(){
-return this.sendCommand('Runtime.enable');
-}
-
-beginEmulation(flags){
-return Promise.resolve().then(_=>{
-if(!flags.disableDeviceEmulation)return emulation.enableNexus5X(this);
-}).then(_=>this.setThrottling(flags,{useThrottling:true}));
-}
-
-setThrottling(flags,passConfig){
-const throttleCpu=passConfig.useThrottling&&!flags.disableCpuThrottling;
-const throttleNetwork=passConfig.useThrottling&&!flags.disableNetworkThrottling;
-const cpuPromise=throttleCpu?
-emulation.enableCPUThrottling(this):
-emulation.disableCPUThrottling(this);
-const networkPromise=throttleNetwork?
-emulation.enableNetworkThrottling(this):
-emulation.disableNetworkThrottling(this);
-
-return Promise.all([cpuPromise,networkPromise]);
-}
-
-
-
-
-
-goOffline(){
-return this.sendCommand('Network.enable').
-then(_=>emulation.goOffline(this)).
-then(_=>this.online=false);
-}
-
-
-
-
-
-
-
-goOnline(options){
-return this.setThrottling(options.flags,options.config).
-then(_=>this.online=true);
-}
-
-cleanBrowserCaches(){
-
-return this.sendCommand('Network.clearBrowserCache').
-
-then(_=>this.sendCommand('Network.setCacheDisabled',{cacheDisabled:true})).
-then(_=>this.sendCommand('Network.setCacheDisabled',{cacheDisabled:false}));
-}
-
-
-
-
-
-setExtraHTTPHeaders(headers){
-if(headers){
-return this.sendCommand('Network.setExtraHTTPHeaders',{
-headers});
-
-}
-
-return Promise.resolve({});
-}
-
-clearDataForOrigin(url){
-const origin=new URL(url).origin;
-
-
-
-const typesToClear=[
-'appcache',
-
-'file_systems',
-'indexeddb',
-'local_storage',
-'shader_cache',
-'websql',
-'service_workers',
-'cache_storage'].
-join(',');
-
-return this.sendCommand('Storage.clearDataForOrigin',{
-origin:origin,
-storageTypes:typesToClear});
-
-}
-
-
-
-
-
-
-cacheNatives(){
-return this.evaluteScriptOnNewDocument(`window.__nativePromise = Promise;
-        window.__nativeError = Error;`);
-}
-
-
-
-
-
-registerPerformanceObserver(){
-return this.evaluteScriptOnNewDocument(`(${registerPerformanceObserverInPage.toString()})()`);
-}
-
-
-
-
-
-
-
-
-captureFunctionCallSites(funcName){
-const globalVarToPopulate=`window['__${funcName}StackTraces']`;
-const collectUsage=()=>{
-return this.evaluateAsync(
-`Array.from(${globalVarToPopulate}).map(item => JSON.parse(item))`).
-then(result=>{
-if(!Array.isArray(result)){
-throw new Error(
-'Driver failure: Expected evaluateAsync results to be an array '+
-`but got "${JSON.stringify(result)}" instead.`);
-}
-
-return result.filter(item=>!item.isExtension);
-});
-};
-
-const funcBody=captureJSCallUsage.toString();
-
-this.evaluteScriptOnNewDocument(`
-        ${globalVarToPopulate} = new Set();
-        (${funcName} = ${funcBody}(${funcName}, ${globalVarToPopulate}))`);
-
-return collectUsage;
-}
-
-
-
-
-
-blockUrlPatterns(urls){
-return this.sendCommand('Network.setBlockedURLs',{urls}).
-catch(err=>{
-
-if(!/wasn't found/.test(err.message)){
-throw err;
-}
-});
-}
-
-
-
-
-
-
-dismissJavaScriptDialogs(){
-return this.sendCommand('Page.enable').then(_=>{
-this.on('Page.javascriptDialogOpening',data=>{
-log.warn('Driver',`${data.type} dialog opened by the page automatically suppressed.`);
-
-
-this.sendCommand('Page.handleJavaScriptDialog',{
-accept:true,
-promptText:'Lighthouse prompt response'});
-
-});
-});
-}}
-
-
-
-
-
-
-
-
-
-
-function captureJSCallUsage(funcRef,set){
-
-const __nativeError=window.__nativeError||Error;
-const originalFunc=funcRef;
-const originalPrepareStackTrace=__nativeError.prepareStackTrace;
-
-return function(...args){
-
-
-
-__nativeError.prepareStackTrace=function(error,structStackTrace){
-
-
-const callFrame=structStackTrace[1];
-let url=callFrame.getFileName()||callFrame.getEvalOrigin();
-const line=callFrame.getLineNumber();
-const col=callFrame.getColumnNumber();
-const isEval=callFrame.isEval();
-let isExtension=false;
-const stackTrace=structStackTrace.slice(1).map(callsite=>callsite.toString());
-
-
-
-
-
-if(isEval){
-url=stackTrace[1];
-}
-
-
-
-if(stackTrace[0].startsWith('<anonymous>')){
-
-
-
-url=stackTrace[0];
-isExtension=true;
-}
-
-
-
-
-
-return{url,args,line,col,isEval,isExtension};
-};
-const e=new __nativeError(`__called ${funcRef.name}__`);
-set.add(JSON.stringify(e.stack));
-
-
-
-__nativeError.prepareStackTrace=originalPrepareStackTrace;
-
-
-return originalFunc.apply(this,args);
-};
-}
-
-
-
-
-
-
-
-
-function wrapRuntimeEvalErrorInBrowser(err){
-err=err||new Error();
-const fallbackMessage=typeof err==='string'?err:'unknown error';
-
-return{
-__failedInBrowser:true,
-name:err.name||'Error',
-message:err.message||fallbackMessage,
-stack:err.stack||new Error().stack};
-
-}
-
-
-
-
-
-
-function registerPerformanceObserverInPage(){
-window.____lastLongTask=window.performance.now();
-const observer=new window.PerformanceObserver(entryList=>{
-const entries=entryList.getEntries();
-for(const entry of entries){
-if(entry.entryType==='longtask'){
-const taskEnd=entry.startTime+entry.duration;
-window.____lastLongTask=Math.max(window.____lastLongTask,taskEnd);
-}
-}
-});
-
-observer.observe({entryTypes:['longtask']});
-
-
-
-
-
-window.____lhPerformanceObserver=observer;
-}
-
-
-
-
-
-
-function checkTimeSinceLastLongTask(){
-
-
-return new Promise(resolve=>{
-const timeoutRequested=window.performance.now()+50;
-
-setTimeout(()=>{
-
-const timeoutFired=window.performance.now();
-const timeSinceLongTask=timeoutFired-timeoutRequested<50?
-timeoutFired-window.____lastLongTask:0;
-resolve(timeSinceLongTask);
-},50);
-});
-}
-
-module.exports=Driver;
-
-},{"../lib/element":26,"../lib/emulation":27,"../lib/network-recorder":32,"../lib/traces/trace-parser":39,"../lib/url-shim":41,"./devtools-log":13,"events":56,"lighthouse-logger":137}],15:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const log=require('lighthouse-logger');
-const Audit=require('../audits/audit');
-const LHError=require('../lib/errors');
-const URL=require('../lib/url-shim');
-const NetworkRecorder=require('../lib/network-recorder.js');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class GatherRunner{
-
-
-
-
-
-
-
-
-
-
-static loadBlank(driver,url='about:blank',duration=300){
-return driver.gotoURL(url).then(_=>new Promise(resolve=>setTimeout(resolve,duration)));
-}
-
-
-
-
-
-
-
-
-
-
-static loadPage(driver,options){
-return driver.gotoURL(options.url,{
-waitForLoad:true,
-disableJavaScript:!!options.disableJavaScript,
-flags:options.flags,
-config:options.config}).
-then(finalUrl=>{
-options.url=finalUrl;
-});
-}
-
-
-
-
-
-
-
-static setupDriver(driver,gathererResults,options){
-log.log('status','Initializing…');
-const resetStorage=!options.flags.disableStorageReset;
-
-return driver.assertNoSameOriginServiceWorkerClients(options.url).
-then(_=>driver.getUserAgent()).
-then(userAgent=>{
-gathererResults.UserAgent=[userAgent];
-GatherRunner.warnOnHeadless(userAgent,gathererResults);
-}).
-then(_=>driver.beginEmulation(options.flags)).
-then(_=>driver.enableRuntimeEvents()).
-then(_=>driver.cacheNatives()).
-then(_=>driver.registerPerformanceObserver()).
-then(_=>driver.dismissJavaScriptDialogs()).
-then(_=>resetStorage&&driver.clearDataForOrigin(options.url));
-}
-
-static disposeDriver(driver){
-log.log('status','Disconnecting from browser...');
-return driver.disconnect().catch(err=>{
-
-
-if(!/close\/.*status: 500$/.test(err.message)){
-log.error('GatherRunner disconnect',err.message);
-}
-});
-}
-
-
-
-
-
-
-
-static recoverOrThrow(promise){
-return promise.catch(err=>{
-if(err.fatal){
-throw err;
-}
-});
-}
-
-
-
-
-
-
-
-static getPageLoadError(url,networkRecords){
-const mainRecord=networkRecords.find(record=>{
-
-return URL.equalWithExcludedFragments(record.url,url);
-});
-
-let errorCode;
-let errorReason;
-if(!mainRecord){
-errorCode=LHError.errors.NO_DOCUMENT_REQUEST;
-}else if(mainRecord.failed){
-errorCode=LHError.errors.FAILED_DOCUMENT_REQUEST;
-errorReason=mainRecord.localizedFailDescription;
-}
-
-if(errorCode){
-const error=new LHError(errorCode,{reason:errorReason});
-log.error('GatherRunner',error.message,url);
-return error;
-}
-}
-
-
-
-
-
-
-static warnOnHeadless(userAgent,gathererResults){
-const chromeVersion=userAgent.split(/HeadlessChrome\/(.*) /)[1];
-
-
-const minVersion='63.0.3239.0';
-if(chromeVersion&&chromeVersion<minVersion){
-gathererResults.LighthouseRunWarnings.push('Your site\'s mobile performance may be '+
-'worse than the numbers presented in this report. Lighthouse could not test on a '+
-'mobile connection because Headless Chrome does not support network throttling '+
-'prior to version '+minVersion+'. The version used was '+chromeVersion);
-}
-}
-
-
-
-
-
-
-
-
-static beforePass(options,gathererResults){
-const blockedUrls=(options.config.blockedUrlPatterns||[]).
-concat(options.flags.blockedUrlPatterns||[]);
-const blankPage=options.config.blankPage;
-const blankDuration=options.config.blankDuration;
-const pass=GatherRunner.loadBlank(options.driver,blankPage,blankDuration).
-
-
-
-then(()=>options.driver.blockUrlPatterns(blockedUrls)).
-then(()=>options.driver.setExtraHTTPHeaders(options.flags.extraHeaders));
-
-return options.config.gatherers.reduce((chain,gatherer)=>{
-return chain.then(_=>{
-const artifactPromise=Promise.resolve().then(_=>gatherer.beforePass(options));
-gathererResults[gatherer.name]=[artifactPromise];
-return GatherRunner.recoverOrThrow(artifactPromise);
-});
-},pass);
-}
-
-
-
-
-
-
-
-
-static pass(options,gathererResults){
-const driver=options.driver;
-const config=options.config;
-const gatherers=config.gatherers;
-
-const recordTrace=config.recordTrace;
-const isPerfRun=!options.flags.disableStorageReset&&recordTrace&&config.useThrottling;
-
-const gatherernames=gatherers.map(g=>g.name).join(', ');
-const status='Loading page & waiting for onload';
-log.log('status',status,gatherernames);
-
-const pass=Promise.resolve().
-
-then(_=>isPerfRun&&driver.cleanBrowserCaches()).
-
-then(_=>driver.beginDevtoolsLog()).
-
-then(_=>recordTrace&&driver.beginTrace(options.flags)).
-
-then(_=>GatherRunner.loadPage(driver,options)).
-then(_=>log.log('statusEnd',status));
-
-return gatherers.reduce((chain,gatherer)=>{
-return chain.then(_=>{
-const artifactPromise=Promise.resolve().then(_=>gatherer.pass(options));
-gathererResults[gatherer.name].push(artifactPromise);
-return GatherRunner.recoverOrThrow(artifactPromise);
-});
-},pass);
-}
-
-
-
-
-
-
-
-
-
-static afterPass(options,gathererResults){
-const driver=options.driver;
-const config=options.config;
-const gatherers=config.gatherers;
-const passData={};
-
-let pass=Promise.resolve();
-let pageLoadError;
-
-if(config.recordTrace){
-pass=pass.then(_=>{
-log.log('status','Retrieving trace');
-return driver.endTrace();
-}).then(traceContents=>{
-
-
-
-passData.trace=Array.isArray(traceContents)?
-{traceEvents:traceContents}:traceContents;
-log.verbose('statusEnd','Retrieving trace');
-});
-}
-
-pass=pass.then(_=>{
-const status='Retrieving devtoolsLog and network records';
-log.log('status',status);
-const devtoolsLog=driver.endDevtoolsLog();
-const networkRecords=NetworkRecorder.recordsFromLogs(devtoolsLog);
-log.verbose('statusEnd',status);
-
-pageLoadError=GatherRunner.getPageLoadError(options.url,networkRecords);
-
-if(!driver.online)pageLoadError=null;
-
-if(pageLoadError){
-gathererResults.LighthouseRunWarnings.push('Lighthouse was unable to reliably load the '+
-'page you requested. Make sure you are testing the correct URL and that the server is '+
-'properly responding to all requests.');
-}
-
-
-passData.devtoolsLog=devtoolsLog;
-passData.networkRecords=networkRecords;
-});
-
-
-pass=pass.then(_=>driver.setThrottling(options.flags,{useThrottling:false}));
-
-pass=gatherers.reduce((chain,gatherer)=>{
-const status=`Retrieving: ${gatherer.name}`;
-return chain.then(_=>{
-log.log('status',status);
-const artifactPromise=pageLoadError?
-Promise.reject(pageLoadError):
-Promise.resolve().then(_=>gatherer.afterPass(options,passData));
-gathererResults[gatherer.name].push(artifactPromise);
-return GatherRunner.recoverOrThrow(artifactPromise);
-}).then(_=>{
-log.verbose('statusEnd',status);
-});
-},pass);
-
-
-return pass.then(_=>passData);
-}
-
-
-
-
-
-
-
-
-
-static collectArtifacts(gathererResults){
-const artifacts={};
-
-
-const uniqueWarnings=Array.from(new Set(gathererResults.LighthouseRunWarnings));
-gathererResults.LighthouseRunWarnings=[uniqueWarnings];
-
-const pageLoadFailures=[];
-return Object.keys(gathererResults).reduce((chain,gathererName)=>{
-return chain.then(_=>{
-const phaseResultsPromises=gathererResults[gathererName];
-return Promise.all(phaseResultsPromises).then(phaseResults=>{
-
-const definedResults=phaseResults.filter(element=>element!==undefined);
-const artifact=definedResults[definedResults.length-1];
-if(artifact===undefined){
-throw new Error(`${gathererName} failed to provide an artifact.`);
-}
-artifacts[gathererName]=artifact;
-},err=>{
-
-
-artifacts[gathererName]=err;
-
-if(LHError.isPageLoadError(err))pageLoadFailures.push(err);
-});
-});
-},Promise.resolve()).then(_=>{
-
-if(pageLoadFailures.length>Object.keys(artifacts).length*.5){
-throw pageLoadFailures[0];
-}
-
-return artifacts;
-});
-}
-
-static run(passes,options){
-const driver=options.driver;
-const tracingData={
-traces:{},
-devtoolsLogs:{}};
-
-
-if(typeof options.url!=='string'||options.url.length===0){
-return Promise.reject(new Error('You must provide a url to the gather-runner'));
-}
-
-if(typeof options.flags==='undefined'){
-options.flags={};
-}
-
-if(typeof options.config==='undefined'){
-return Promise.reject(new Error('You must provide a config'));
-}
-
-if(typeof options.flags.disableCpuThrottling==='undefined'){
-options.flags.disableCpuThrottling=false;
-}
-
-passes=this.instantiateGatherers(passes,options.config.configDir);
-
-const gathererResults={
-LighthouseRunWarnings:[]};
-
-
-return driver.connect().
-then(_=>GatherRunner.loadBlank(driver)).
-then(_=>GatherRunner.setupDriver(driver,gathererResults,options)).
-
-
-then(_=>{
-
-let urlAfterRedirects;
-return passes.reduce((chain,config,passIndex)=>{
-const runOptions=Object.assign({},options,{config});
-return chain.
-then(_=>driver.setThrottling(options.flags,config)).
-then(_=>GatherRunner.beforePass(runOptions,gathererResults)).
-then(_=>GatherRunner.pass(runOptions,gathererResults)).
-then(_=>GatherRunner.afterPass(runOptions,gathererResults)).
-then(passData=>{
-const passName=config.passName||Audit.DEFAULT_PASS;
-
-
-tracingData.devtoolsLogs[passName]=passData.devtoolsLog;
-
-
-if(config.recordTrace){
-tracingData.traces[passName]=passData.trace;
-}
-
-if(passIndex===0){
-urlAfterRedirects=runOptions.url;
-}
-});
-},Promise.resolve()).then(_=>{
-options.url=urlAfterRedirects;
-});
-}).
-then(_=>GatherRunner.disposeDriver(driver)).
-then(_=>GatherRunner.collectArtifacts(gathererResults)).
-then(artifacts=>{
-
-return Object.assign(artifacts,tracingData);
-}).
-
-catch(err=>{
-GatherRunner.disposeDriver(driver);
-
-throw err;
-});
-}
-
-static getGathererClass(nameOrGathererClass,configPath){
-const Runner=require('../runner');
-const coreList=Runner.getGathererList();
-
-let GathererClass;
-if(typeof nameOrGathererClass==='string'){
-const name=nameOrGathererClass;
-
-
-const coreGatherer=coreList.find(a=>a===`${name}.js`);
-let requirePath=`./gatherers/${name}`;
-if(!coreGatherer){
-
-requirePath=Runner.resolvePlugin(name,configPath,'gatherer');
-}
-
-GathererClass=require(requirePath);
-
-this.assertValidGatherer(GathererClass,name);
-}else{
-GathererClass=nameOrGathererClass;
-this.assertValidGatherer(GathererClass);
-}
-
-return GathererClass;
-}
-
-static assertValidGatherer(GathererDefinition,gathererName){
-const gathererInstance=new GathererDefinition();
-gathererName=gathererName||gathererInstance.name||'gatherer';
-
-if(typeof gathererInstance.beforePass!=='function'){
-throw new Error(`${gathererName} has no beforePass() method.`);
-}
-
-if(typeof gathererInstance.pass!=='function'){
-throw new Error(`${gathererName} has no pass() method.`);
-}
-
-if(typeof gathererInstance.afterPass!=='function'){
-throw new Error(`${gathererName} has no afterPass() method.`);
-}
-}
-
-static instantiateGatherers(passes,rootPath){
-return passes.map(pass=>{
-pass.gatherers=pass.gatherers.map(gatherer=>{
-
-if(typeof gatherer!=='string'){
-return gatherer;
-}
-
-const GathererClass=GatherRunner.getGathererClass(gatherer,rootPath);
-return new GathererClass();
-});
-
-return pass;
-});
-}}
-
-
-module.exports=GatherRunner;
-
-},{"../audits/audit":2,"../lib/errors":28,"../lib/network-recorder.js":32,"../lib/url-shim":41,"../runner":44,"lighthouse-logger":137}],16:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-
-
-
-
-class Gatherer{
-
-
-
-get name(){
-return this.constructor.name;
-}
-
-
-
-
-
-
-
-beforePass(options){}
-
-
-
-
-
-
-pass(options){}
-
-
-
-
-
-
-
-
-
-afterPass(options,loadData){}}
-
-
-
-
-module.exports=Gatherer;
-
-},{}],17:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const isEqual=require('lodash.isequal');
-
-
-
-
-
-
-module.exports=class ArbitraryEqualityMap{
-constructor(){
-this._equalsFn=(a,b)=>a===b;
-this._entries=[];
-}
-
-
-
-
-setEqualityFn(equalsFn){
-this._equalsFn=equalsFn;
-}
-
-has(key){
-return this._findIndexOf(key)!==-1;
-}
-
-get(key){
-const entry=this._entries[this._findIndexOf(key)];
-return entry&&entry.value;
-}
-
-set(key,value){
-let index=this._findIndexOf(key);
-if(index===-1)index=this._entries.length;
-this._entries[index]={key,value};
-}
-
-_findIndexOf(key){
-for(let i=0;i<this._entries.length;i++){
-if(this._equalsFn(key,this._entries[i].key))return i;
-}
-
-return-1;
-}
-
-
-
-
-
-
-
-
-
-static deepEquals(objA,objB){
-return isEqual(objA,objB);
-}};
-
-
-},{"lodash.isequal":138}],18:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-
-const path=require('path');
-const log=require('lighthouse-logger');
-const stream=require('stream');
-const Metrics=require('./traces/pwmetrics-events');
-const TraceParser=require('./traces/trace-parser');
-const rimraf=require('rimraf');
-const mkdirp=require('mkdirp');
-
-
-
-
-
-
-function screenshotDump(screenshots){
-return`
-  <!doctype html>
-  <meta charset="utf-8">
-  <title>screenshots</title>
-  <style>
-html {
-    overflow-x: scroll;
-    overflow-y: hidden;
-    height: 100%;
-    background-image: linear-gradient(to left, #4ca1af , #c4e0e5);
-    background-attachment: fixed;
-    padding: 10px;
-}
-body {
-    white-space: nowrap;
-    background-image: linear-gradient(to left, #4ca1af , #c4e0e5);
-    width: 100%;
-    margin: 0;
-}
-img {
-    margin: 4px;
-}
-</style>
-  <body>
-    <script>
-      var shots = ${JSON.stringify(screenshots)};
-
-  shots.forEach(s => {
-    var i = document.createElement('img');
-    i.src = s.datauri;
-    i.title = s.timestamp;
-    document.body.appendChild(i);
-  });
-  </script>
-  `;
-}
-
-const artifactsFilename='artifacts.json';
-const traceSuffix='.trace.json';
-const devtoolsLogSuffix='.devtoolslog.json';
-
-
-
-
-
-
-
-
-
-function loadArtifacts(basePath){
-log.log('Reading artifacts from disk:',basePath);
-
-if(!fs.existsSync(basePath))return Promise.reject(new Error('No saved artifacts found'));
-
-
-const filenames=fs.readdirSync(basePath);
-const artifacts=JSON.parse(fs.readFileSync(path.join(basePath,artifactsFilename),'utf8'));
-
-
-artifacts.devtoolsLogs={};
-filenames.filter(f=>f.endsWith(devtoolsLogSuffix)).map(filename=>{
-const passName=filename.replace(devtoolsLogSuffix,'');
-const devtoolsLog=JSON.parse(fs.readFileSync(path.join(basePath,filename),'utf8'));
-artifacts.devtoolsLogs[passName]=devtoolsLog;
-});
-
-
-artifacts.traces={};
-const promises=filenames.filter(f=>f.endsWith(traceSuffix)).map(filename=>{
-return new Promise(resolve=>{
-const passName=filename.replace(traceSuffix,'');
-const readStream=fs.createReadStream(path.join(basePath,filename),{
-encoding:'utf-8',
-highWaterMark:4*1024*1024});
-
-const parser=new TraceParser();
-readStream.on('data',chunk=>parser.parseChunk(chunk));
-readStream.on('end',_=>{
-artifacts.traces[passName]=parser.getTrace();
-resolve();
-});
-});
-});
-return Promise.all(promises).then(_=>artifacts);
-}
-
-
-
-
-
-
-
-
-
-function saveArtifacts(artifacts,basePath){
-mkdirp.sync(basePath);
-rimraf.sync(`${basePath}/*${traceSuffix}`);
-rimraf.sync(`${basePath}/${artifactsFilename}`);
-
-
-artifacts=Object.assign({},artifacts);
-
-
-const traces=artifacts.traces;
-let promise=Promise.all(Object.keys(traces).map(passName=>{
-return saveTrace(traces[passName],`${basePath}/${passName}${traceSuffix}`);
-}));
-
-
-const devtoolsLogs=artifacts.devtoolsLogs;
-promise=promise.then(_=>{
-Object.keys(devtoolsLogs).map(passName=>{
-const log=JSON.stringify(devtoolsLogs[passName]);
-fs.writeFileSync(`${basePath}/${passName}${devtoolsLogSuffix}`,log,'utf8');
-});
-delete artifacts.traces;
-delete artifacts.devtoolsLogs;
-});
-
-
-promise=promise.then(_=>{
-fs.writeFileSync(`${basePath}/${artifactsFilename}`,JSON.stringify(artifacts,0,2),'utf8');
-log.log('Artifacts saved to disk in folder:',basePath);
-});
-return promise;
-}
-
-
-
-
-
-
-
-function prepareAssets(artifacts,audits){
-const passNames=Object.keys(artifacts.traces);
-const assets=[];
-
-return passNames.reduce((chain,passName)=>{
-const trace=artifacts.traces[passName];
-const devtoolsLog=artifacts.devtoolsLogs[passName];
-
-return chain.then(_=>artifacts.requestScreenshots(trace)).
-then(screenshots=>{
-const traceData=Object.assign({},trace);
-const screenshotsHTML=screenshotDump(screenshots);
-
-if(audits){
-const evts=new Metrics(traceData.traceEvents,audits).generateFakeEvents();
-traceData.traceEvents=traceData.traceEvents.concat(evts);
-}
-
-assets.push({
-passName,
-traceData,
-devtoolsLog,
-screenshotsHTML,
-screenshots});
-
-});
-},Promise.resolve()).
-then(_=>assets);
-}
-
-
-
-
-
-
-
-function*traceJsonGenerator(traceData){
-const keys=Object.keys(traceData);
-
-yield'{\n';
-
-
-yield'"traceEvents": [\n';
-if(traceData.traceEvents.length>0){
-const eventsIterator=traceData.traceEvents[Symbol.iterator]();
-
-const firstEvent=eventsIterator.next().value;
-yield`  ${JSON.stringify(firstEvent)}`;
-for(const event of eventsIterator){
-yield`,\n  ${JSON.stringify(event)}`;
-}
-}
-yield'\n]';
-
-
-if(keys.length>1){
-for(const key of keys){
-if(key==='traceEvents')continue;
-
-yield`,\n"${key}": ${JSON.stringify(traceData[key],null,2)}`;
-}
-}
-
-yield'}\n';
-}
-
-
-
-
-
-
-
-function saveTrace(traceData,traceFilename){
-return new Promise((resolve,reject)=>{
-const traceIter=traceJsonGenerator(traceData);
-
-
-const traceStream=new stream.Readable({
-read(){
-const next=traceIter.next();
-this.push(next.done?null:next.value);
-}});
-
-
-const writeStream=fs.createWriteStream(traceFilename);
-writeStream.on('finish',resolve);
-writeStream.on('error',reject);
-
-traceStream.pipe(writeStream);
-});
-}
-
-
-
-
-
-
-
-
-function saveAssets(artifacts,audits,pathWithBasename){
-return prepareAssets(artifacts,audits).then(assets=>{
-return Promise.all(assets.map((data,index)=>{
-const devtoolsLogFilename=`${pathWithBasename}-${index}${devtoolsLogSuffix}`;
-fs.writeFileSync(devtoolsLogFilename,JSON.stringify(data.devtoolsLog,null,2));
-log.log('saveAssets','devtools log saved to disk: '+devtoolsLogFilename);
-
-const screenshotsHTMLFilename=`${pathWithBasename}-${index}.screenshots.html`;
-fs.writeFileSync(screenshotsHTMLFilename,data.screenshotsHTML);
-log.log('saveAssets','screenshots saved to disk: '+screenshotsHTMLFilename);
-
-const screenshotsJSONFilename=`${pathWithBasename}-${index}.screenshots.json`;
-fs.writeFileSync(screenshotsJSONFilename,JSON.stringify(data.screenshots,null,2));
-log.log('saveAssets','screenshots saved to disk: '+screenshotsJSONFilename);
-
-const streamTraceFilename=`${pathWithBasename}-${index}${traceSuffix}`;
-log.log('saveAssets','streaming trace file to disk: '+streamTraceFilename);
-return saveTrace(data.traceData,streamTraceFilename).then(_=>{
-log.log('saveAssets','trace file streamed to disk: '+streamTraceFilename);
-});
-}));
-});
-}
-
-
-
-
-
-
-
-function logAssets(artifacts,audits){
-return prepareAssets(artifacts,audits).then(assets=>{
-assets.map(data=>{
-log.log(`devtoolslog-${data.passName}.json`,JSON.stringify(data.devtoolsLog));
-const traceIter=traceJsonGenerator(data.traceData);
-let traceJson='';
-for(const trace of traceIter){
-traceJson+=trace;
-}
-log.log(`trace-${data.passName}.json`,traceJson);
-});
-});
-}
-
-module.exports={
-saveArtifacts,
-loadArtifacts,
-saveAssets,
-prepareAssets,
-saveTrace,
-logAssets};
-
-
-},{"./traces/pwmetrics-events":38,"./traces/trace-parser":39,"lighthouse-logger":137,"mkdirp":52,"path":69,"rimraf":52,"stream":86}],19:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-const log=require('lighthouse-logger');
-
-class ConsoleQuieter{
-static mute(opts){
-ConsoleQuieter._logs=ConsoleQuieter._logs||[];
-
-console.log=function(...args){
-ConsoleQuieter._logs.push({type:'log',args,prefix:opts.prefix});
-};
-console.warn=function(...args){
-ConsoleQuieter._logs.push({type:'warn',args,prefix:opts.prefix});
-};
-console.error=function(...args){
-ConsoleQuieter._logs.push({type:'error',args,prefix:opts.prefix});
-};
-}
-
-static unmuteAndFlush(){
-console.log=ConsoleQuieter._consolelog;
-console.warn=ConsoleQuieter._consolewarn;
-console.error=ConsoleQuieter._consoleerror;
-
-ConsoleQuieter._logs.forEach(entry=>{
-log.verbose(`${entry.prefix}-${entry.type}`,...entry.args);
-});
-ConsoleQuieter._logs=[];
-}}
-
-
-ConsoleQuieter._consolelog=console.log.bind(console);
-ConsoleQuieter._consolewarn=console.warn.bind(console);
-ConsoleQuieter._consoleerror=console.error.bind(console);
-
-module.exports=ConsoleQuieter;
-
-},{"lighthouse-logger":137}],20:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Node=require('./node');
-
-class CPUNode extends Node{
-
-
-
-
-constructor(parentEvent,childEvents=[]){
-const nodeId=`${parentEvent.tid}.${parentEvent.ts}`;
-super(nodeId);
-
-this._event=parentEvent;
-this._childEvents=childEvents;
-}
-
-
-
-
-get type(){
-return Node.TYPES.CPU;
-}
-
-
-
-
-get startTime(){
-return this._event.ts;
-}
-
-
-
-
-get endTime(){
-return this._event.ts+this._event.dur;
-}
-
-
-
-
-get event(){
-return this._event;
-}
-
-
-
-
-get childEvents(){
-return this._childEvents;
-}
-
-
-
-
-
-didPerformLayout(){
-return this._childEvents.some(evt=>evt.name==='Layout');
-}
-
-
-
-
-
-
-isEvaluateScriptFor(urls){
-return this._childEvents.some(evt=>{
-return evt.name==='EvaluateScript'&&
-evt.args.data&&
-urls.has(evt.args.data.url);
-});
-}
-
-
-
-
-cloneWithoutRelationships(){
-return new CPUNode(this._event,this._childEvents);
-}}
-
-
-module.exports=CPUNode;
-
-},{"./node":22}],21:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Node=require('./node');
-const WebInspector=require('../web-inspector');
-
-class NetworkNode extends Node{
-
-
-
-constructor(networkRecord){
-super(networkRecord.requestId);
-this._record=networkRecord;
-}
-
-
-
-
-get type(){
-return Node.TYPES.NETWORK;
-}
-
-
-
-
-get startTime(){
-return this._record.startTime*1000*1000;
-}
-
-
-
-
-get endTime(){
-return this._record.endTime*1000*1000;
-}
-
-
-
-
-get record(){
-return this._record;
-}
-
-
-
-
-get initiatorType(){
-return this._record._initiator&&this._record._initiator.type;
-}
-
-
-
-
-hasRenderBlockingPriority(){
-const priority=this._record.priority();
-const isScript=this._record._resourceType===WebInspector.resourceTypes.Script;
-return priority==='VeryHigh'||priority==='High'&&isScript;
-}
-
-
-
-
-cloneWithoutRelationships(){
-return new NetworkNode(this._record);
-}}
-
-
-module.exports=NetworkNode;
-
-},{"../web-inspector":42,"./node":22}],22:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-
-
-
-
-
-class Node{
-
-
-
-constructor(id){
-this._id=id;
-this._dependents=[];
-this._dependencies=[];
-}
-
-
-
-
-get id(){
-return this._id;
-}
-
-
-
-
-get type(){
-throw new Error('Unimplemented');
-}
-
-
-
-
-get startTime(){
-throw new Error('Unimplemented');
-}
-
-
-
-
-get endTime(){
-throw new Error('Unimplemented');
-}
-
-
-
-
-getDependents(){
-return this._dependents.slice();
-}
-
-
-
-
-getDependencies(){
-return this._dependencies.slice();
-}
-
-
-
-
-getNumberOfDependencies(){
-return this._dependencies.length;
-}
-
-
-
-
-getRootNode(){
-let rootNode=this;
-while(rootNode._dependencies.length){
-rootNode=rootNode._dependencies[0];
-}
-
-return rootNode;
-}
-
-
-
-
-addDependent(node){
-node.addDependency(this);
-}
-
-
-
-
-addDependency(node){
-if(this._dependencies.includes(node)){
-return;
-}
-
-node._dependents.push(this);
-this._dependencies.push(node);
-}
-
-
-
-
-
-cloneWithoutRelationships(){
-return new Node(this.id);
-}
-
-
-
-
-
-
-
-
-
-cloneWithRelationships(predicate){
-const rootNode=this.getRootNode();
-
-let shouldIncludeNode=()=>true;
-if(predicate){
-const idsToInclude=new Set();
-rootNode.traverse(node=>{
-if(predicate(node)){
-node.traverse(
-node=>idsToInclude.add(node.id),
-node=>node._dependencies.filter(parent=>!idsToInclude.has(parent)));
-
-}
-});
-
-shouldIncludeNode=node=>idsToInclude.has(node.id);
-}
-
-const idToNodeMap=new Map();
-rootNode.traverse(originalNode=>{
-if(!shouldIncludeNode(originalNode))return;
-const clonedNode=originalNode.cloneWithoutRelationships();
-idToNodeMap.set(clonedNode.id,clonedNode);
-});
-
-rootNode.traverse(originalNode=>{
-if(!shouldIncludeNode(originalNode))return;
-const clonedNode=idToNodeMap.get(originalNode.id);
-
-for(const dependency of originalNode._dependencies){
-const clonedDependency=idToNodeMap.get(dependency.id);
-clonedNode.addDependency(clonedDependency);
-}
-});
-
-return idToNodeMap.get(this.id);
-}
-
-
-
-
-
-
-
-_traversePaths(iterator,getNext){
-const stack=[[this]];
-while(stack.length){
-const path=stack.shift();
-const node=path[0];
-iterator(node,path);
-
-const nodesToAdd=getNext(node);
-for(const nextNode of nodesToAdd){
-stack.push([nextNode].concat(path));
-}
-}
-}
-
-
-
-
-
-
-
-traverse(iterator,getNext){
-if(!getNext){
-getNext=node=>node.getDependents();
-}
-
-const visited=new Set();
-const originalGetNext=getNext;
-
-getNext=node=>{
-visited.add(node.id);
-const allNodesToVisit=originalGetNext(node);
-const nodesToVisit=allNodesToVisit.filter(nextNode=>!visited.has(nextNode.id));
-nodesToVisit.forEach(nextNode=>visited.add(nextNode.id));
-return nodesToVisit;
-};
-
-this._traversePaths(iterator,getNext);
-}
-
-
-
-
-
-
-static hasCycle(node){
-const visited=new Set();
-const currentPath=[];
-const toVisit=[node];
-const depthAdded=new Map([[node,0]]);
-
-
-while(toVisit.length){
-
-const currentNode=toVisit.pop();
-
-
-if(currentPath.includes(currentNode))return true;
-
-if(visited.has(currentNode))continue;
-
-
-while(currentPath.length>depthAdded.get(currentNode))currentPath.pop();
-
-
-visited.add(currentNode);
-currentPath.push(currentNode);
-
-
-for(const dependent of currentNode._dependents){
-if(toVisit.includes(dependent))continue;
-toVisit.push(dependent);
-depthAdded.set(dependent,currentPath.length);
-}
-}
-
-return false;
-}}
-
-
-Node.TYPES={
-NETWORK:'network',
-CPU:'cpu'};
-
-
-module.exports=Node;
-
-},{}],23:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const Node=require('../node');
-const TcpConnection=require('./tcp-connection');
-const emulation=require('../../emulation').settings;
-
-
-const DEFAULT_MAXIMUM_CONCURRENT_REQUESTS=10;
-
-
-const DEFAULT_FALLBACK_TTFB=30;
-const DEFAULT_RTT=emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetLatency;
-const DEFAULT_THROUGHPUT=emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetDownloadThroughput*8;
-
-
-const DEFAULT_CPU_TASK_MULTIPLIER=emulation.CPU_THROTTLE_METRICS.rate;
-
-const DEFAULT_LAYOUT_TASK_MULTIPLIER=DEFAULT_CPU_TASK_MULTIPLIER/2;
-
-const DEFAULT_MAXIMUM_CPU_TASK_DURATION=10000;
-
-const TLS_SCHEMES=['https','wss'];
-
-function groupBy(items,keyFunc){
-const grouped=new Map();
-items.forEach(item=>{
-const key=keyFunc(item);
-const group=grouped.get(key)||[];
-group.push(item);
-grouped.set(key,group);
-});
-
-return grouped;
-}
-
-const NodeState={
-NotReadyToStart:0,
-ReadyToStart:1,
-InProgress:2,
-Complete:3};
-
-
-class Simulator{
-
-
-
-
-
-constructor(graph,options){
-this._graph=graph;
-this._options=Object.assign(
-{
-rtt:DEFAULT_RTT,
-throughput:DEFAULT_THROUGHPUT,
-fallbackTTFB:DEFAULT_FALLBACK_TTFB,
-maximumConcurrentRequests:DEFAULT_MAXIMUM_CONCURRENT_REQUESTS,
-cpuTaskMultiplier:DEFAULT_CPU_TASK_MULTIPLIER,
-layoutTaskMultiplier:DEFAULT_LAYOUT_TASK_MULTIPLIER},
-
-options);
-
-
-this._rtt=this._options.rtt;
-this._throughput=this._options.throughput;
-this._fallbackTTFB=this._options.fallbackTTFB;
-this._maximumConcurrentRequests=Math.min(
-TcpConnection.maximumSaturatedConnections(this._rtt,this._throughput),
-this._options.maximumConcurrentRequests);
-
-this._cpuTaskMultiplier=this._options.cpuTaskMultiplier;
-this._layoutTaskMultiplier=this._options.layoutTaskMultiplier;
-}
-
-
-
-
-
-
-static getTTFB(record){
-const timing=record._timing;
-return timing&&timing.receiveHeadersEnd-timing.sendEnd||Infinity;
-}
-
-
-
-
-_initializeNetworkRecords(){
-this._networkRecords=[];
-
-this._graph.getRootNode().traverse(node=>{
-if(node.type===Node.TYPES.NETWORK){
-this._networkRecords.push(node.record);
-}
-});
-}
-
-
-
-
-_initializeNetworkConnections(){
-const connections=new Map();
-const recordsByConnection=groupBy(this._networkRecords,record=>record.connectionId);
-
-for(const[connectionId,records]of recordsByConnection.entries()){
-const isTLS=TLS_SCHEMES.includes(records[0].parsedURL.scheme);
-const isH2=records[0].protocol==='h2';
-
-
-
-
-
-
-
-let estimatedResponseTime=Math.min(...records.map(Simulator.getTTFB));
-
-
-if(!Number.isFinite(estimatedResponseTime)){
-estimatedResponseTime=this._fallbackTTFB;
-}
-
-const connection=new TcpConnection(
-this._rtt,
-this._throughput,
-estimatedResponseTime,
-isTLS,
-isH2);
-
-
-connections.set(connectionId,connection);
-}
-
-this._connections=connections;
-return connections;
-}
-
-
-
-
-_initializeAuxiliaryData(){
-this._nodeTiming=new Map();
-this._connectionsInUse=new Set();
-this._numberInProgressByType=new Map();
-
-this._nodes=[];
-for(const key of Object.keys(NodeState)){
-this._nodes[NodeState[key]]=new Set();
-}
-}
-
-
-
-
-
-_numberInProgress(type){
-return this._numberInProgressByType.get(type)||0;
-}
-
-
-
-
-
-_setTimingData(node,values){
-const timingData=this._nodeTiming.get(node)||{};
-Object.assign(timingData,values);
-this._nodeTiming.set(node,timingData);
-}
-
-
-
-
-
-_markNodeAsReadyToStart(node,queuedTime){
-this._nodes[NodeState.ReadyToStart].add(node);
-this._nodes[NodeState.NotReadyToStart].delete(node);
-this._setTimingData(node,{queuedTime});
-}
-
-
-
-
-
-_markNodeAsInProgress(node,startTime){
-this._nodes[NodeState.InProgress].add(node);
-this._nodes[NodeState.ReadyToStart].delete(node);
-this._numberInProgressByType.set(node.type,this._numberInProgress(node.type)+1);
-this._setTimingData(node,{startTime});
-}
-
-
-
-
-
-_markNodeAsComplete(node,endTime){
-this._nodes[NodeState.Complete].add(node);
-this._nodes[NodeState.InProgress].delete(node);
-this._numberInProgressByType.set(node.type,this._numberInProgress(node.type)-1);
-this._setTimingData(node,{endTime});
-
-
-for(const dependent of node.getDependents()){
-
-const dependencies=dependent.getDependencies();
-if(dependencies.some(dep=>!this._nodes[NodeState.Complete].has(dep)))continue;
-
-
-this._markNodeAsReadyToStart(dependent,endTime);
-}
-}
-
-
-
-
-
-_startNodeIfPossible(node,totalElapsedTime){
-if(node.type===Node.TYPES.CPU){
-
-if(this._numberInProgress(node.type)===0){
-this._markNodeAsInProgress(node,totalElapsedTime);
-this._setTimingData(node,{timeElapsed:0});
-}
-
-return;
-}
-
-if(node.type!==Node.TYPES.NETWORK)throw new Error('Unsupported');
-
-const connection=this._connections.get(node.record.connectionId);
-const numberOfActiveRequests=this._numberInProgress(node.type);
-
-
-if(
-numberOfActiveRequests>=this._maximumConcurrentRequests||
-this._connectionsInUse.has(connection))
-{
-return;
-}
-
-this._markNodeAsInProgress(node,totalElapsedTime);
-this._setTimingData(node,{
-timeElapsed:0,
-timeElapsedOvershoot:0,
-bytesDownloaded:0});
-
-
-this._connectionsInUse.add(connection);
-}
-
-
-
-
-
-_updateNetworkCapacity(){
-for(const connection of this._connectionsInUse){
-connection.setThroughput(this._throughput/this._nodes[NodeState.InProgress].size);
-}
-}
-
-
-
-
-
-
-_estimateTimeRemaining(node){
-if(node.type===Node.TYPES.CPU){
-const timingData=this._nodeTiming.get(node);
-const multiplier=node.didPerformLayout()?
-this._layoutTaskMultiplier:
-this._cpuTaskMultiplier;
-const totalDuration=Math.min(
-Math.round(node.event.dur/1000*multiplier),
-DEFAULT_MAXIMUM_CPU_TASK_DURATION);
-
-const estimatedTimeElapsed=totalDuration-timingData.timeElapsed;
-this._setTimingData(node,{estimatedTimeElapsed});
-return estimatedTimeElapsed;
-}
-
-if(node.type!==Node.TYPES.NETWORK)throw new Error('Unsupported');
-
-const timingData=this._nodeTiming.get(node);
-const connection=this._connections.get(node.record.connectionId);
-const calculation=connection.simulateDownloadUntil(
-node.record.transferSize-timingData.bytesDownloaded,
-{timeAlreadyElapsed:timingData.timeElapsed});
-
-
-const estimatedTimeElapsed=calculation.timeElapsed+timingData.timeElapsedOvershoot;
-this._setTimingData(node,{estimatedTimeElapsed});
-return estimatedTimeElapsed;
-}
-
-
-
-
-
-_findNextNodeCompletionTime(){
-let minimumTime=Infinity;
-for(const node of this._nodes[NodeState.InProgress]){
-minimumTime=Math.min(minimumTime,this._estimateTimeRemaining(node));
-}
-
-return minimumTime;
-}
-
-
-
-
-
-
-
-_updateProgressMadeInTimePeriod(node,timePeriodLength,totalElapsedTime){
-const timingData=this._nodeTiming.get(node);
-const isFinished=timingData.estimatedTimeElapsed===timePeriodLength;
-
-if(node.type===Node.TYPES.CPU){
-return isFinished?
-this._markNodeAsComplete(node,totalElapsedTime):
-timingData.timeElapsed+=timePeriodLength;
-}
-
-if(node.type!==Node.TYPES.NETWORK)throw new Error('Unsupported');
-
-const connection=this._connections.get(node.record.connectionId);
-const calculation=connection.simulateDownloadUntil(
-node.record.transferSize-timingData.bytesDownloaded,
-{
-timeAlreadyElapsed:timingData.timeElapsed,
-maximumTimeToElapse:timePeriodLength-timingData.timeElapsedOvershoot});
-
-
-
-connection.setCongestionWindow(calculation.congestionWindow);
-connection.setH2OverflowBytesDownloaded(calculation.extraBytesDownloaded);
-
-if(isFinished){
-connection.setWarmed(true);
-this._connectionsInUse.delete(connection);
-this._markNodeAsComplete(node,totalElapsedTime);
-}else{
-timingData.timeElapsed+=calculation.timeElapsed;
-timingData.timeElapsedOvershoot+=calculation.timeElapsed-timePeriodLength;
-timingData.bytesDownloaded+=calculation.bytesDownloaded;
-}
-}
-
-
-
-
-
-simulate(){
-
-this._initializeNetworkRecords();
-this._initializeNetworkConnections();
-this._initializeAuxiliaryData();
-
-const nodesNotReadyToStart=this._nodes[NodeState.NotReadyToStart];
-const nodesReadyToStart=this._nodes[NodeState.ReadyToStart];
-const nodesInProgress=this._nodes[NodeState.InProgress];
-
-const rootNode=this._graph.getRootNode();
-rootNode.traverse(node=>nodesNotReadyToStart.add(node));
-
-let totalElapsedTime=0;
-
-
-this._markNodeAsReadyToStart(rootNode,totalElapsedTime);
-
-
-while(nodesReadyToStart.size||nodesInProgress.size){
-
-for(const node of nodesReadyToStart){
-this._startNodeIfPossible(node,totalElapsedTime);
-}
-
-
-this._updateNetworkCapacity();
-
-
-const minimumTime=this._findNextNodeCompletionTime();
-totalElapsedTime+=minimumTime;
-
-
-for(const node of nodesInProgress){
-this._updateProgressMadeInTimePeriod(node,minimumTime,totalElapsedTime);
-}
-}
-
-return{
-timeInMs:totalElapsedTime,
-nodeTiming:this._nodeTiming};
-
-}}
-
-
-module.exports=Simulator;
-
-
-
-
-
-
-
-
-
-Simulator.NodeTimingData;
-
-},{"../../emulation":27,"../node":22,"./tcp-connection":24}],24:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const INITIAL_CONGESTION_WINDOW=10;
-const TCP_SEGMENT_SIZE=1460;
-
-class TcpConnection{
-
-
-
-
-
-
-
-constructor(rtt,throughput,serverLatency=0,ssl=true,h2=false){
-this._warmed=false;
-this._ssl=ssl;
-this._h2=h2;
-this._rtt=rtt;
-this._throughput=throughput;
-this._serverLatency=serverLatency;
-this._congestionWindow=INITIAL_CONGESTION_WINDOW;
-this._h2OverflowBytesDownloaded=0;
-}
-
-
-
-
-
-
-static maximumSaturatedConnections(rtt,availableThroughput){
-const roundTripsPerSecond=1000/rtt;
-const bytesPerRoundTrip=TCP_SEGMENT_SIZE;
-const bytesPerSecond=roundTripsPerSecond*bytesPerRoundTrip;
-const minimumThroughputRequiredPerRequest=bytesPerSecond*8;
-return Math.floor(availableThroughput/minimumThroughputRequiredPerRequest);
-}
-
-
-
-
-_computeMaximumCongestionWindowInSegments(){
-const bytesPerSecond=this._throughput/8;
-const secondsPerRoundTrip=this._rtt/1000;
-const bytesPerRoundTrip=bytesPerSecond*secondsPerRoundTrip;
-return Math.floor(bytesPerRoundTrip/TCP_SEGMENT_SIZE);
-}
-
-
-
-
-setThroughput(throughput){
-this._throughput=throughput;
-}
-
-
-
-
-setCongestionWindow(congestion){
-this._congestionWindow=congestion;
-}
-
-
-
-
-setWarmed(warmed){
-this._warmed=warmed;
-}
-
-
-
-
-
-
-setH2OverflowBytesDownloaded(bytes){
-if(!this._h2)return;
-this._h2OverflowBytesDownloaded=bytes;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-simulateDownloadUntil(bytesToDownload,options){
-const{timeAlreadyElapsed=0,maximumTimeToElapse=Infinity}=options||{};
-
-if(this._warmed&&this._h2){
-bytesToDownload-=this._h2OverflowBytesDownloaded;
-}
-const twoWayLatency=this._rtt;
-const oneWayLatency=twoWayLatency/2;
-const maximumCongestionWindow=this._computeMaximumCongestionWindowInSegments();
-
-let handshakeAndRequest=oneWayLatency;
-if(!this._warmed){
-handshakeAndRequest=
-
-oneWayLatency+
-
-oneWayLatency+
-
-oneWayLatency+(
-
-this._ssl?twoWayLatency:0);
-}
-
-let roundTrips=Math.ceil(handshakeAndRequest/twoWayLatency);
-let timeToFirstByte=handshakeAndRequest+this._serverLatency+oneWayLatency;
-if(this._warmed&&this._h2)timeToFirstByte=0;
-
-const timeElapsedForTTFB=Math.max(timeToFirstByte-timeAlreadyElapsed,0);
-const maximumDownloadTimeToElapse=maximumTimeToElapse-timeElapsedForTTFB;
-
-let congestionWindow=Math.min(this._congestionWindow,maximumCongestionWindow);
-let totalBytesDownloaded=0;
-if(timeElapsedForTTFB>0){
-totalBytesDownloaded=congestionWindow*TCP_SEGMENT_SIZE;
-}else{
-roundTrips=0;
-}
-
-let downloadTimeElapsed=0;
-let bytesRemaining=bytesToDownload-totalBytesDownloaded;
-while(bytesRemaining>0&&downloadTimeElapsed<=maximumDownloadTimeToElapse){
-roundTrips++;
-downloadTimeElapsed+=twoWayLatency;
-congestionWindow=Math.max(Math.min(maximumCongestionWindow,congestionWindow*2),1);
-
-const bytesDownloadedInWindow=congestionWindow*TCP_SEGMENT_SIZE;
-totalBytesDownloaded+=bytesDownloadedInWindow;
-bytesRemaining-=bytesDownloadedInWindow;
-}
-
-const timeElapsed=timeElapsedForTTFB+downloadTimeElapsed;
-const extraBytesDownloaded=this._h2?Math.max(totalBytesDownloaded-bytesToDownload,0):0;
-const bytesDownloaded=Math.max(Math.min(totalBytesDownloaded,bytesToDownload),0);
-
-return{
-roundTrips,
-timeElapsed,
-bytesDownloaded,
-extraBytesDownloaded,
-congestionWindow};
-
-}}
-
-
-module.exports=TcpConnection;
-
-},{}],25:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-
-
-
-
-
-function getElementsInDocument(selector){
-const results=[];
-
-const _findAllElements=nodes=>{
-for(let i=0,el;el=nodes[i];++i){
-if(!selector||el.matches(selector)){
-results.push(el);
-}
-
-if(el.shadowRoot){
-_findAllElements(el.shadowRoot.querySelectorAll('*'));
-}
-}
-};
-_findAllElements(document.querySelectorAll('*'));
-
-return results;
-}
-
-module.exports={
-getElementsInDocumentFnString:getElementsInDocument.toString()};
-
-
-},{}],26:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-class Element{
-constructor(element,driver){
-if(!element||!driver){
-throw Error('Driver and element required to create Element');
-}
-this.driver=driver;
-this.element=element;
-}
-
-
-
-
-
-getAttribute(name){
-return this.driver.
-sendCommand('DOM.getAttributes',{
-nodeId:this.element.nodeId}).
-
-
-
-
-then(resp=>{
-const attrIndex=resp.attributes.indexOf(name);
-if(attrIndex===-1){
-return null;
-}
-
-return resp.attributes[attrIndex+1];
-});
-}
-
-
-
-
-
-getProperty(propName){
-return this.driver.
-sendCommand('DOM.resolveNode',{
-nodeId:this.element.nodeId}).
-
-then(resp=>{
-return this.driver.getObjectProperty(resp.object.objectId,propName);
-});
-}}
-
-
-module.exports=Element;
-
-},{}],27:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-
-
-
-const NEXUS5X_EMULATION_METRICS={
-mobile:true,
-screenWidth:412,
-screenHeight:732,
-width:412,
-height:732,
-positionX:0,
-positionY:0,
-scale:1,
-deviceScaleFactor:2.625,
-fitWindow:false,
-screenOrientation:{
-angle:0,
-type:'portraitPrimary'}};
-
-
-
-const NEXUS5X_USERAGENT={
-userAgent:'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36'+
-'(KHTML, like Gecko) Chrome/61.0.3116.0 Mobile Safari/537.36'};
-
-
-
-
-
-
-
-const LATENCY_FACTOR=3.75;
-const THROUGHPUT_FACTOR=0.9;
-
-const TARGET_LATENCY=150;
-const TARGET_DOWNLOAD_THROUGHPUT=Math.floor(1.6*1024*1024/8);
-const TARGET_UPLOAD_THROUGHPUT=Math.floor(750*1024/8);
-
-const TYPICAL_MOBILE_THROTTLING_METRICS={
-targetLatency:TARGET_LATENCY,
-latency:TARGET_LATENCY*LATENCY_FACTOR,
-targetDownloadThroughput:TARGET_DOWNLOAD_THROUGHPUT,
-downloadThroughput:TARGET_DOWNLOAD_THROUGHPUT*THROUGHPUT_FACTOR,
-targetUploadThroughput:TARGET_UPLOAD_THROUGHPUT,
-uploadThroughput:TARGET_UPLOAD_THROUGHPUT*THROUGHPUT_FACTOR,
-offline:false};
-
-
-const OFFLINE_METRICS={
-offline:true,
-
-latency:0,
-downloadThroughput:0,
-uploadThroughput:0};
-
-
-const NO_THROTTLING_METRICS={
-latency:0,
-downloadThroughput:0,
-uploadThroughput:0,
-offline:false};
-
-
-const NO_CPU_THROTTLE_METRICS={
-rate:1};
-
-const CPU_THROTTLE_METRICS={
-rate:4};
-
-
-function enableNexus5X(driver){
-
-
-
-
-
-
-
-
-
-
-
-
-const injectedTouchEventsFunction=function(){
-const touchEvents=['ontouchstart','ontouchend','ontouchmove','ontouchcancel'];
-const recepients=[window.__proto__,document.__proto__];
-for(let i=0;i<touchEvents.length;++i){
-for(let j=0;j<recepients.length;++j){
-if(!(touchEvents[i]in recepients[j])){
-Object.defineProperty(recepients[j],touchEvents[i],{
-value:null,writable:true,configurable:true,enumerable:true});
-
-}
-}
-}
-};
-
-
-return Promise.all([
-driver.sendCommand('Emulation.setDeviceMetricsOverride',NEXUS5X_EMULATION_METRICS),
-
-driver.sendCommand('Network.enable'),
-driver.sendCommand('Network.setUserAgentOverride',NEXUS5X_USERAGENT),
-driver.sendCommand('Emulation.setTouchEmulationEnabled',{
-enabled:true,
-configuration:'mobile'}),
-
-driver.sendCommand('Page.addScriptToEvaluateOnLoad',{
-scriptSource:'('+injectedTouchEventsFunction.toString()+')()'})]);
-
-
-}
-
-function enableNetworkThrottling(driver){
-return driver.sendCommand('Network.emulateNetworkConditions',TYPICAL_MOBILE_THROTTLING_METRICS);
-}
-
-function disableNetworkThrottling(driver){
-return driver.sendCommand('Network.emulateNetworkConditions',NO_THROTTLING_METRICS);
-}
-
-function goOffline(driver){
-return driver.sendCommand('Network.emulateNetworkConditions',OFFLINE_METRICS);
-}
-
-function enableCPUThrottling(driver){
-return driver.sendCommand('Emulation.setCPUThrottlingRate',CPU_THROTTLE_METRICS);
-}
-
-function disableCPUThrottling(driver){
-return driver.sendCommand('Emulation.setCPUThrottlingRate',NO_CPU_THROTTLE_METRICS);
-}
-
-function getEmulationDesc(){
-const{latency,downloadThroughput,uploadThroughput}=TYPICAL_MOBILE_THROTTLING_METRICS;
-const byteToMbit=bytes=>(bytes/1024/1024*8).toFixed(1);
-return{
-'deviceEmulation':'Nexus 5X',
-'cpuThrottling':`${CPU_THROTTLE_METRICS.rate}x slowdown`,
-'networkThrottling':`${latency}ms RTT, ${byteToMbit(downloadThroughput)}Mbps down, `+
-`${byteToMbit(uploadThroughput)}Mbps up`};
-
-}
-
-module.exports={
-enableNexus5X,
-enableNetworkThrottling,
-disableNetworkThrottling,
-enableCPUThrottling,
-disableCPUThrottling,
-goOffline,
-getEmulationDesc,
-settings:{
-NEXUS5X_EMULATION_METRICS,
-NEXUS5X_USERAGENT,
-TYPICAL_MOBILE_THROTTLING_METRICS,
-OFFLINE_METRICS,
-NO_THROTTLING_METRICS,
-NO_CPU_THROTTLE_METRICS,
-CPU_THROTTLE_METRICS}};
-
-
-
-},{}],28:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const strings=require('./strings');
-
-
-
-
-
-
-
-
-class LighthouseError extends Error{
-
-
-
-
-constructor(errorDefinition,properties){
-super(errorDefinition.code);
-this.name='LHError';
-this.code=errorDefinition.code;
-this.friendlyMessage=errorDefinition.message;
-if(properties)Object.assign(this,properties);
-
-Error.captureStackTrace(this,LighthouseError);
-}
-
-
-
-
-static isPageLoadError(err){
-return err.code===ERRORS.NO_DOCUMENT_REQUEST.code||
-err.code===ERRORS.FAILED_DOCUMENT_REQUEST.code;
-}
-
-
-
-
-
-
-static fromProtocolMessage(method,protocolError){
-
-const protocolErrors=Object.keys(ERRORS).filter(k=>ERRORS[k].pattern).map(k=>ERRORS[k]);
-
-const matchedErrorDefinition=protocolErrors.find(e=>e.pattern.test(protocolError.message));
-if(matchedErrorDefinition){
-return new LighthouseError(matchedErrorDefinition,{
-protocolMethod:method,
-protocolError:protocolError.message});
-
-}
-
-
-let errMsg=`(${method}): ${protocolError.message}`;
-if(protocolError.data)errMsg+=` (${protocolError.data})`;
-const error=new Error(`Protocol error ${errMsg}`);
-return Object.assign(error,{protocolMethod:method,protocolError:protocolError.message});
-}}
-
-
-const ERRORS={
-
-NO_SPEEDLINE_FRAMES:{message:strings.didntCollectScreenshots},
-SPEEDINDEX_OF_ZERO:{message:strings.didntCollectScreenshots},
-NO_SCREENSHOTS:{message:strings.didntCollectScreenshots},
-
-
-NO_TRACING_STARTED:{message:strings.badTraceRecording},
-NO_NAVSTART:{message:strings.badTraceRecording},
-NO_FMP:{message:strings.badTraceRecording},
-NO_DCL:{message:strings.badTraceRecording},
-
-
-FMP_TOO_LATE_FOR_FCPUI:{message:strings.pageLoadTookTooLong},
-NO_FCPUI_IDLE_PERIOD:{message:strings.pageLoadTookTooLong},
-NO_TTI_CPU_IDLE_PERIOD:{message:strings.pageLoadTookTooLong},
-NO_TTI_NETWORK_IDLE_PERIOD:{message:strings.pageLoadTookTooLong},
-
-
-NO_DOCUMENT_REQUEST:{message:strings.pageLoadFailed},
-FAILED_DOCUMENT_REQUEST:{message:strings.pageLoadFailed},
-
-
-TRACING_ALREADY_STARTED:{message:strings.internalChromeError,pattern:/Tracing.*started/},
-PARSING_PROBLEM:{message:strings.internalChromeError,pattern:/Parsing problem/},
-READ_FAILED:{message:strings.internalChromeError,pattern:/Read failed/}};
-
-
-Object.keys(ERRORS).forEach(code=>ERRORS[code].code=code);
-LighthouseError.errors=ERRORS;
-module.exports=LighthouseError;
-
-
-},{"./strings":35}],29:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-
-
-function addFormattedCodeSnippet(listener){
-const handler=listener.handler?listener.handler.description:'...';
-const objectName=listener.objectName.toLowerCase().replace('#document','document');
-return Object.assign({
-label:`line: ${listener.line}, col: ${listener.col}`,
-pre:`${objectName}.addEventListener('${listener.type}', ${handler})`},
-listener);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function groupCodeSnippetsByLocation(listeners){
-const locToListenersMap=new Map();
-listeners.forEach(loc=>{
-const key=JSON.stringify({line:loc.line,col:loc.col,url:loc.url,type:loc.type});
-if(locToListenersMap.has(key)){
-locToListenersMap.get(key).push(loc);
-}else{
-locToListenersMap.set(key,[loc]);
-}
-});
-
-const results=[];
-locToListenersMap.forEach((listenersForLocation,key)=>{
-const lineColUrlObj=JSON.parse(key);
-
-const codeSnippets=listenersForLocation.reduce((prev,loc)=>{
-return prev+loc.pre.trim()+'\n\n';
-},'');
-lineColUrlObj.pre=codeSnippets;
-
-
-lineColUrlObj.label=listenersForLocation[0].label;
-results.push(lineColUrlObj);
-});
-
-return results;
-}
-
-module.exports={
-addFormattedCodeSnippet,
-groupCodeSnippetsByLocation};
-
-
-},{}],30:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-function doExist(manifest){
-if(!manifest||!manifest.icons){
-return false;
-}
-if(manifest.icons.value.length===0){
-return false;
-}
-return true;
-}
-
-
-
-
-
-
-function sizeAtLeast(sizeRequirement,manifest){
-
-
-const iconValues=manifest.icons.value;
-const nestedSizes=iconValues.map(icon=>icon.value.sizes.value);
-const flattenedSizes=[].concat(...nestedSizes);
-
-return flattenedSizes.
-
-filter(size=>typeof size==='string').
-
-filter(size=>/\d+x\d+/.test(size)).
-filter(size=>{
-
-const sizeStrs=size.split(/x/i);
-
-const sizeNums=[parseFloat(sizeStrs[0]),parseFloat(sizeStrs[1])];
-
-const areIconsBigEnough=sizeNums[0]>=sizeRequirement&&sizeNums[1]>=sizeRequirement;
-
-const areIconsSquare=sizeNums[0]===sizeNums[1];
-return areIconsBigEnough&&areIconsSquare;
-});
-}
-
-module.exports={
-doExist,
-sizeAtLeast};
-
-
-},{}],31:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const URL=require('./url-shim');
-const validateColor=require('./web-inspector').Color.parse;
-
-const ALLOWED_DISPLAY_VALUES=[
-'fullscreen',
-'standalone',
-'minimal-ui',
-'browser'];
-
-
-
-
-
-const DEFAULT_DISPLAY_MODE='browser';
-
-const ALLOWED_ORIENTATION_VALUES=[
-'any',
-'natural',
-'landscape',
-'portrait',
-'portrait-primary',
-'portrait-secondary',
-'landscape-primary',
-'landscape-secondary'];
-
-
-function parseString(raw,trim){
-let value;
-let debugString;
-
-if(typeof raw==='string'){
-value=trim?raw.trim():raw;
-}else{
-if(raw!==undefined){
-debugString='ERROR: expected a string.';
-}
-value=undefined;
-}
-
-return{
-raw,
-value,
-debugString};
-
-}
-
-function parseColor(raw){
-const color=parseString(raw);
-
-
-if(color.value===undefined){
-return color;
-}
-
-
-const validatedColor=validateColor(color.raw);
-if(!validatedColor){
-color.value=undefined;
-color.debugString='ERROR: color parsing failed.';
-}
-
-return color;
-}
-
-function parseName(jsonInput){
-return parseString(jsonInput.name,true);
-}
-
-function parseShortName(jsonInput){
-return parseString(jsonInput.short_name,true);
-}
-
-
-
-
-
-
-
-function checkSameOrigin(url1,url2){
-const parsed1=new URL(url1);
-const parsed2=new URL(url2);
-
-return parsed1.origin===parsed2.origin;
-}
-
-
-
-
-function parseStartUrl(jsonInput,manifestUrl,documentUrl){
-const raw=jsonInput.start_url;
-
-
-if(raw===''){
-return{
-raw,
-value:documentUrl,
-debugString:'ERROR: start_url string empty'};
-
-}
-const parsedAsString=parseString(raw);
-if(!parsedAsString.value){
-parsedAsString.value=documentUrl;
-return parsedAsString;
-}
-
-
-let startUrl;
-try{
-startUrl=new URL(raw,manifestUrl).href;
-}catch(e){
-
-return{
-raw,
-value:documentUrl,
-debugString:'ERROR: invalid start_url relative to ${manifestUrl}'};
-
-}
-
-
-if(!checkSameOrigin(startUrl,documentUrl)){
-return{
-raw,
-value:documentUrl,
-debugString:'ERROR: start_url must be same-origin as document'};
-
-}
-
-return{
-raw,
-value:startUrl};
-
-}
-
-function parseDisplay(jsonInput){
-const display=parseString(jsonInput.display,true);
-
-if(!display.value){
-display.value=DEFAULT_DISPLAY_MODE;
-return display;
-}
-
-display.value=display.value.toLowerCase();
-if(!ALLOWED_DISPLAY_VALUES.includes(display.value)){
-display.debugString='ERROR: \'display\' has invalid value '+display.value+
-` will fall back to ${DEFAULT_DISPLAY_MODE}.`;
-display.value=DEFAULT_DISPLAY_MODE;
-}
-
-return display;
-}
-
-function parseOrientation(jsonInput){
-const orientation=parseString(jsonInput.orientation,true);
-
-if(orientation.value&&
-!ALLOWED_ORIENTATION_VALUES.includes(orientation.value.toLowerCase())){
-orientation.value=undefined;
-orientation.debugString='ERROR: \'orientation\' has an invalid value, will be ignored.';
-}
-
-return orientation;
-}
-
-function parseIcon(raw,manifestUrl){
-
-const src=parseString(raw.src,true);
-
-if(src.value===''){
-src.value=undefined;
-}
-if(src.value){
-
-src.value=new URL(src.value,manifestUrl).href;
-}
-
-const type=parseString(raw.type,true);
-
-const density={
-raw:raw.density,
-value:1,
-debugString:undefined};
-
-if(density.raw!==undefined){
-density.value=parseFloat(density.raw);
-if(isNaN(density.value)||!isFinite(density.value)||density.value<=0){
-density.value=1;
-density.debugString='ERROR: icon density cannot be NaN, +∞, or less than or equal to +0.';
-}
-}
-
-const sizes=parseString(raw.sizes);
-if(sizes.value!==undefined){
-const set=new Set();
-sizes.value.trim().split(/\s+/).forEach(size=>set.add(size.toLowerCase()));
-sizes.value=set.size>0?Array.from(set):undefined;
-}
-
-return{
-raw,
-value:{
-src,
-type,
-density,
-sizes},
-
-debugString:undefined};
-
-}
-
-function parseIcons(jsonInput,manifestUrl){
-const raw=jsonInput.icons;
-
-if(raw===undefined){
-return{
-raw,
-value:[],
-debugString:undefined};
-
-}
-
-if(!Array.isArray(raw)){
-return{
-raw,
-value:[],
-debugString:'ERROR: \'icons\' expected to be an array but is not.'};
-
-}
-
-
-
-const value=raw.
-
-filter(icon=>icon.src!==undefined).
-
-map(icon=>parseIcon(icon,manifestUrl)).
-
-filter(parsedIcon=>parsedIcon.value.src.value!==undefined);
-
-return{
-raw,
-value,
-debugString:undefined};
-
-}
-
-function parseApplication(raw){
-const platform=parseString(raw.platform,true);
-const id=parseString(raw.id,true);
-
-
-const appUrl=parseString(raw.url,true);
-if(appUrl.value){
-try{
-
-appUrl.value=new URL(appUrl.value).href;
-}catch(e){
-appUrl.value=undefined;
-appUrl.debugString='ERROR: invalid application URL ${raw.url}';
-}
-}
-
-return{
-raw,
-value:{
-platform,
-id,
-url:appUrl},
-
-debugString:undefined};
-
-}
-
-function parseRelatedApplications(jsonInput){
-const raw=jsonInput.related_applications;
-
-if(raw===undefined){
-return{
-raw,
-value:undefined,
-debugString:undefined};
-
-}
-
-if(!Array.isArray(raw)){
-return{
-raw,
-value:undefined,
-debugString:'ERROR: \'related_applications\' expected to be an array but is not.'};
-
-}
-
-
-
-const value=raw.
-filter(application=>!!application.platform).
-map(parseApplication).
-filter(parsedApp=>!!parsedApp.value.id.value||!!parsedApp.value.url.value);
-
-return{
-raw,
-value,
-debugString:undefined};
-
-}
-
-function parsePreferRelatedApplications(jsonInput){
-const raw=jsonInput.prefer_related_applications;
-let value;
-let debugString;
-
-if(typeof raw==='boolean'){
-value=raw;
-}else{
-if(raw!==undefined){
-debugString='ERROR: \'prefer_related_applications\' expected to be a boolean.';
-}
-value=undefined;
-}
-
-return{
-raw,
-value,
-debugString};
-
-}
-
-function parseThemeColor(jsonInput){
-return parseColor(jsonInput.theme_color);
-}
-
-function parseBackgroundColor(jsonInput){
-return parseColor(jsonInput.background_color);
-}
-
-
-
-
-
-
-
-
-function parse(string,manifestUrl,documentUrl){
-if(manifestUrl===undefined||documentUrl===undefined){
-throw new Error('Manifest and document URLs required for manifest parsing.');
-}
-
-let jsonInput;
-
-try{
-jsonInput=JSON.parse(string);
-}catch(e){
-return{
-raw:string,
-value:undefined,
-debugString:'ERROR: file isn\'t valid JSON: '+e};
-
-}
-
-
-const manifest={
-name:parseName(jsonInput),
-short_name:parseShortName(jsonInput),
-start_url:parseStartUrl(jsonInput,manifestUrl,documentUrl),
-display:parseDisplay(jsonInput),
-orientation:parseOrientation(jsonInput),
-icons:parseIcons(jsonInput,manifestUrl),
-related_applications:parseRelatedApplications(jsonInput),
-prefer_related_applications:parsePreferRelatedApplications(jsonInput),
-theme_color:parseThemeColor(jsonInput),
-background_color:parseBackgroundColor(jsonInput)};
-
-
-
-return{
-raw:string,
-value:manifest,
-debugString:undefined};
-
-}
-
-module.exports=parse;
-
-},{"./url-shim":41,"./web-inspector":42}],32:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const NetworkManager=require('./web-inspector').NetworkManager;
-const EventEmitter=require('events').EventEmitter;
-const log=require('lighthouse-logger');
-
-const IGNORED_NETWORK_SCHEMES=['data','ws'];
-
-class NetworkRecorder extends EventEmitter{
-
-
-
-
-constructor(recordArray){
-super();
-
-this._records=recordArray;
-this.networkManager=NetworkManager.createWithFakeTarget();
-
-this.networkManager.addEventListener(
-this.EventTypes.RequestStarted,
-this.onRequestStarted.bind(this));
-
-this.networkManager.addEventListener(
-this.EventTypes.RequestFinished,
-this.onRequestFinished.bind(this));
-
-}
-
-get EventTypes(){
-return NetworkManager.Events;
-}
-
-isIdle(){
-return!!this._getActiveIdlePeriod(0);
-}
-
-is2Idle(){
-return!!this._getActiveIdlePeriod(2);
-}
-
-_getActiveIdlePeriod(allowedRequests){
-const quietPeriods=NetworkRecorder.findNetworkQuietPeriods(this._records,allowedRequests);
-return quietPeriods.find(period=>!Number.isFinite(period.end));
-}
-
-_emitNetworkStatus(){
-const zeroQuiet=this._getActiveIdlePeriod(0);
-const twoQuiet=this._getActiveIdlePeriod(2);
-
-if(twoQuiet&&zeroQuiet){
-log.verbose('NetworkRecorder','network fully-quiet');
-this.emit('network-2-idle');
-this.emit('networkidle');
-}else if(twoQuiet&&!zeroQuiet){
-log.verbose('NetworkRecorder','network semi-quiet');
-this.emit('network-2-idle');
-this.emit('networkbusy');
-}else{
-log.verbose('NetworkRecorder','network busy');
-this.emit('network-2-busy');
-this.emit('networkbusy');
-}
-}
-
-
-
-
-
-
-
-
-
-static findNetworkQuietPeriods(networkRecords,allowedConcurrentRequests,endTime=Infinity){
-
-let timeBoundaries=[];
-networkRecords.forEach(record=>{
-const scheme=record.parsedURL&&record.parsedURL.scheme;
-if(IGNORED_NETWORK_SCHEMES.includes(scheme)){
-return;
-}
-
-
-timeBoundaries.push({time:record.startTime*1000,isStart:true});
-if(record.finished){
-timeBoundaries.push({time:record.endTime*1000,isStart:false});
-}
-});
-
-timeBoundaries=timeBoundaries.
-filter(boundary=>boundary.time<=endTime).
-sort((a,b)=>a.time-b.time);
-
-let numInflightRequests=0;
-let quietPeriodStart=0;
-const quietPeriods=[];
-timeBoundaries.forEach(boundary=>{
-if(boundary.isStart){
-
-if(numInflightRequests===allowedConcurrentRequests){
-quietPeriods.push({start:quietPeriodStart,end:boundary.time});
-}
-numInflightRequests++;
-}else{
-numInflightRequests--;
-
-if(numInflightRequests===allowedConcurrentRequests){
-quietPeriodStart=boundary.time;
-}
-}
-});
-
-
-if(numInflightRequests<=allowedConcurrentRequests){
-quietPeriods.push({start:quietPeriodStart,end:endTime});
-}
-
-return quietPeriods;
-}
-
-
-
-
-
-
-onRequestStarted(request){
-this._records.push(request.data);
-this._emitNetworkStatus();
-}
-
-
-
-
-
-
-
-onRequestFinished(request){
-this.emit('requestloaded',request.data);
-this._emitNetworkStatus();
-}
-
-
-
-
-
-onRequestWillBeSent(data){
-
-this.networkManager._dispatcher.requestWillBeSent(data.requestId,
-data.frameId,data.loaderId,data.documentURL,data.request,
-data.timestamp,data.wallTime,data.initiator,data.redirectResponse,
-data.type);
-}
-
-onRequestServedFromCache(data){
-this.networkManager._dispatcher.requestServedFromCache(data.requestId);
-}
-
-onResponseReceived(data){
-
-this.networkManager._dispatcher.responseReceived(data.requestId,
-data.frameId,data.loaderId,data.timestamp,data.type,data.response);
-}
-
-onDataReceived(data){
-
-this.networkManager._dispatcher.dataReceived(data.requestId,data.timestamp,
-data.dataLength,data.encodedDataLength);
-}
-
-onLoadingFinished(data){
-
-this.networkManager._dispatcher.loadingFinished(data.requestId,
-data.timestamp,data.encodedDataLength);
-}
-
-onLoadingFailed(data){
-
-
-this.networkManager._dispatcher.loadingFailed(data.requestId,
-data.timestamp,data.type,data.errorText,data.canceled,
-data.blockedReason);
-}
-
-onResourceChangedPriority(data){
-this.networkManager._dispatcher.resourceChangedPriority(data.requestId,
-data.newPriority,data.timestamp);
-}
-
-
-
-
-
-
-dispatch(method,params){
-if(!method.startsWith('Network.')){
-return;
-}
-
-switch(method){
-case'Network.requestWillBeSent':return this.onRequestWillBeSent(params);
-case'Network.requestServedFromCache':return this.onRequestServedFromCache(params);
-case'Network.responseReceived':return this.onResponseReceived(params);
-case'Network.dataReceived':return this.onDataReceived(params);
-case'Network.loadingFinished':return this.onLoadingFinished(params);
-case'Network.loadingFailed':return this.onLoadingFailed(params);
-case'Network.resourceChangedPriority':return this.onResourceChangedPriority(params);
-default:return;}
-
-}
-
-
-
-
-
-
-static recordsFromLogs(devtoolsLog){
-const records=[];
-const nr=new NetworkRecorder(records);
-devtoolsLog.forEach(message=>{
-nr.dispatch(message.method,message.params);
-});
-return records;
-}}
-
-
-module.exports=NetworkRecorder;
-
-},{"./web-inspector":42,"events":56,"lighthouse-logger":137}],33:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const log=require('lighthouse-logger');
-
-
-const SENTRY_URL='https://a6bb0da87ee048cc9ae2a345fc09ab2e:63a7029f46f74265981b7e005e0f69f8@sentry.io/174697';
-
-const noop=()=>Promise.resolve();
-const sentryApi={
-captureMessage:noop,
-captureException:noop,
-captureBreadcrumb:noop,
-mergeContext:noop,
-getContext:noop};
-
-
-const SAMPLED_ERRORS=[
-
-{pattern:/DOCUMENT_REQUEST$/,rate:0.1},
-{pattern:/(IDLE_PERIOD|FMP_TOO_LATE)/,rate:0.1},
-{pattern:/^NO_.*/,rate:0.1},
-
-{pattern:/Failed to decode/,rate:0.1},
-{pattern:/All image optimizations failed/,rate:0.1},
-{pattern:/No.*resource with given/,rate:0.01},
-{pattern:/No.*node with given id/,rate:0.01}];
-
-
-
-
-
-
-const sentryDelegate=Object.assign({},sentryApi);
-sentryDelegate.init=function init(opts){
-if(!opts.flags.enableErrorReporting){
-
-return;
-}
-
-const environmentData=opts.environmentData||{};
-const sentryConfig=Object.assign({},environmentData,{captureUnhandledRejections:true});
-
-try{
-const Sentry=require('raven');
-Sentry.config(SENTRY_URL,sentryConfig).install();
-Object.keys(sentryApi).forEach(functionName=>{
-
-sentryDelegate[functionName]=(...args)=>Sentry[functionName](...args);
-});
-
-
-sentryDelegate.captureException=(err,opts)=>{
-opts=opts||{};
-
-const empty=Promise.resolve();
-
-if(!err)return empty;
-
-if(err.expected)return empty;
-
-const sampledErrorMatch=SAMPLED_ERRORS.find(sample=>sample.pattern.test(err.message));
-if(sampledErrorMatch&&sampledErrorMatch.rate<=Math.random())return empty;
-
-if(err.protocolMethod){
-opts.fingerprint=['{{ default }}',err.protocolMethod,err.protocolError];
-}
-
-return new Promise(resolve=>{
-Sentry.captureException(err,opts,()=>resolve());
-});
-};
-}catch(e){
-log.warn(
-'sentry',
-'Could not load raven library, errors will not be reported.');
-
-}
-
-const context={
-url:opts.url,
-deviceEmulation:!opts.flags.disableDeviceEmulation,
-networkThrottling:!opts.flags.disableNetworkThrottling,
-cpuThrottling:!opts.flags.disableCpuThrottling};
-
-
-sentryDelegate.mergeContext({extra:Object.assign({},environmentData.extra,context)});
-return context;
-};
-
-module.exports=sentryDelegate;
-
-},{"lighthouse-logger":137,"raven":52}],34:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-
-function erf(x){
-
-const sign=Math.sign(x);
-x=Math.abs(x);
-
-const a1=0.254829592;
-const a2=-0.284496736;
-const a3=1.421413741;
-const a4=-1.453152027;
-const a5=1.061405429;
-const p=0.3275911;
-const t=1/(1+p*x);
-const y=t*(a1+t*(a2+t*(a3+t*(a4+t*a5))));
-return sign*(1-y*Math.exp(-x*x));
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function getLogNormalDistribution(median,falloff){
-const location=Math.log(median);
-
-
-
-
-const logRatio=Math.log(falloff/median);
-const shape=Math.sqrt(1-3*logRatio-Math.sqrt((logRatio-3)*(logRatio-3)-8))/2;
-
-return{
-computeComplementaryPercentile(x){
-const standardizedX=(Math.log(x)-location)/(Math.SQRT2*shape);
-return(1-erf(standardizedX))/2;
-}};
-
-}
-
-module.exports={
-getLogNormalDistribution};
-
-
-},{}],35:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-module.exports={
-didntCollectScreenshots:`Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse.`,
-badTraceRecording:`Something went wrong with recording the trace over your page load. Please run Lighthouse again.`,
-pageLoadTookTooLong:`Your page took too long to load. Please follow the opportunities in the report to reduce your page load time, and then try re-running Lighthouse.`,
-pageLoadFailed:`Your page failed to load. Verify that the URL is valid and re-run Lighthouse.`,
-internalChromeError:`An internal Chrome error occurred. Please restart Chrome and try re-running Lighthouse.`};
-
-
-},{}],36:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const groupIdToName={
-loading:'Network request loading',
-parseHTML:'Parsing HTML & CSS',
-styleLayout:'Style & Layout',
-compositing:'Compositing',
-painting:'Paint',
-gpu:'GPU',
-scripting:'Script Evaluation',
-scriptParseCompile:'Script Parsing & Compile',
-scriptGC:'Garbage collection',
-other:'Other',
-images:'Images'};
-
-
-const taskToGroup={
-'Animation':groupIdToName.painting,
-'Async Task':groupIdToName.other,
-'Frame Start':groupIdToName.painting,
-'Frame Start (main thread)':groupIdToName.painting,
-'Cancel Animation Frame':groupIdToName.scripting,
-'Cancel Idle Callback':groupIdToName.scripting,
-'Compile Script':groupIdToName.scriptParseCompile,
-'Composite Layers':groupIdToName.compositing,
-'Console Time':groupIdToName.scripting,
-'Image Decode':groupIdToName.images,
-'Draw Frame':groupIdToName.painting,
-'Embedder Callback':groupIdToName.scripting,
-'Evaluate Script':groupIdToName.scripting,
-'Event':groupIdToName.scripting,
-'Animation Frame Fired':groupIdToName.scripting,
-'Fire Idle Callback':groupIdToName.scripting,
-'Function Call':groupIdToName.scripting,
-'DOM GC':groupIdToName.scriptGC,
-'GC Event':groupIdToName.scriptGC,
-'GPU':groupIdToName.gpu,
-'Hit Test':groupIdToName.compositing,
-'Invalidate Layout':groupIdToName.styleLayout,
-'JS Frame':groupIdToName.scripting,
-'Input Latency':groupIdToName.scripting,
-'Layout':groupIdToName.styleLayout,
-'Major GC':groupIdToName.scriptGC,
-'DOMContentLoaded event':groupIdToName.scripting,
-'First paint':groupIdToName.painting,
-'FMP':groupIdToName.painting,
-'FMP candidate':groupIdToName.painting,
-'Load event':groupIdToName.scripting,
-'Minor GC':groupIdToName.scriptGC,
-'Paint':groupIdToName.painting,
-'Paint Image':groupIdToName.images,
-'Paint Setup':groupIdToName.painting,
-'Parse Stylesheet':groupIdToName.parseHTML,
-'Parse HTML':groupIdToName.parseHTML,
-'Parse Script':groupIdToName.scriptParseCompile,
-'Other':groupIdToName.other,
-'Rasterize Paint':groupIdToName.painting,
-'Recalculate Style':groupIdToName.styleLayout,
-'Request Animation Frame':groupIdToName.scripting,
-'Request Idle Callback':groupIdToName.scripting,
-'Request Main Thread Frame':groupIdToName.painting,
-'Image Resize':groupIdToName.images,
-'Finish Loading':groupIdToName.loading,
-'Receive Data':groupIdToName.loading,
-'Receive Response':groupIdToName.loading,
-'Send Request':groupIdToName.loading,
-'Run Microtasks':groupIdToName.scripting,
-'Schedule Style Recalculation':groupIdToName.styleLayout,
-'Scroll':groupIdToName.compositing,
-'Task':groupIdToName.other,
-'Timer Fired':groupIdToName.scripting,
-'Install Timer':groupIdToName.scripting,
-'Remove Timer':groupIdToName.scripting,
-'Timestamp':groupIdToName.scripting,
-'Update Layer':groupIdToName.compositing,
-'Update Layer Tree':groupIdToName.compositing,
-'User Timing':groupIdToName.scripting,
-'Create WebSocket':groupIdToName.scripting,
-'Destroy WebSocket':groupIdToName.scripting,
-'Receive WebSocket Handshake':groupIdToName.scripting,
-'Send WebSocket Handshake':groupIdToName.scripting,
-'XHR Load':groupIdToName.scripting,
-'XHR Ready State Change':groupIdToName.scripting};
-
-
-module.exports={
-groupIdToName,
-taskToGroup};
-
-
-},{}],37:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const WebInspector=require('../web-inspector');
-const ConsoleQuieter=require('../console-quieter');
-
-
-const TimelineModelTreeView=
-require('devtools-timeline-model/lib/timeline-model-treeview.js')(WebInspector);
-
-class TimelineModel{
-constructor(events){
-this.init(events);
-}
-
-init(events){
-
-this._tracingModel=
-new WebInspector.TracingModel(new WebInspector.TempFileBackingStorage('tracing'));
-
-this._timelineModel=
-new WebInspector.TimelineModel(WebInspector.TimelineUIUtils.visibleEventsFilter());
-
-if(typeof events==='string'){
-events=JSON.parse(events);
-}
-if(events.hasOwnProperty('traceEvents')){
-events=events.traceEvents;
-}
-
-
-this._tracingModel.reset();
-
-try{
-ConsoleQuieter.mute({prefix:'timelineModel'});
-this._tracingModel.addEvents(events);
-this._tracingModel.tracingComplete();
-this._timelineModel.setEvents(this._tracingModel);
-}finally{
-ConsoleQuieter.unmuteAndFlush();
-}
-
-return this;
-}
-
-_createAggregator(){
-return WebInspector.AggregatedTimelineTreeView.prototype._createAggregator();
-}
-
-timelineModel(){
-return this._timelineModel;
-}
-
-tracingModel(){
-return this._tracingModel;
-}
-
-topDown(){
-const filters=[];
-filters.push(WebInspector.TimelineUIUtils.visibleEventsFilter());
-filters.push(new WebInspector.ExcludeTopLevelFilter());
-const nonessentialEvents=[
-WebInspector.TimelineModel.RecordType.EventDispatch,
-WebInspector.TimelineModel.RecordType.FunctionCall,
-WebInspector.TimelineModel.RecordType.TimerFire];
-
-filters.push(new WebInspector.ExclusiveNameFilter(nonessentialEvents));
-
-const topDown=WebInspector.TimelineProfileTree.buildTopDown(
-this._timelineModel.mainThreadEvents(),
-filters,0,Infinity,
-WebInspector.TimelineAggregator.eventId);
-return topDown;
-}
-
-bottomUp(){
-const topDown=this.topDown();
-const noGrouping=WebInspector.TimelineAggregator.GroupBy.None;
-const noGroupAggregator=this._createAggregator().groupFunction(noGrouping);
-return WebInspector.TimelineProfileTree.buildBottomUp(topDown,noGroupAggregator);
-}
-
-
-
-
-
-bottomUpGroupBy(grouping){
-const topDown=this.topDown();
-
-const groupSetting=WebInspector.TimelineAggregator.GroupBy[grouping];
-const groupingAggregator=this._createAggregator().groupFunction(groupSetting);
-const bottomUpGrouped=
-WebInspector.TimelineProfileTree.buildBottomUp(topDown,groupingAggregator);
-
-
-new TimelineModelTreeView(bottomUpGrouped).sortingChanged('self','desc');
-return bottomUpGrouped;
-}
-
-frameModel(){
-const frameModel=new WebInspector.TimelineFrameModel(event=>
-WebInspector.TimelineUIUtils.eventStyle(event).category.name);
-
-frameModel.addTraceEvents({},
-this._timelineModel.inspectedTargetEvents(),this._timelineModel.sessionId()||'');
-return frameModel;
-}
-
-filmStripModel(){
-return new WebInspector.FilmStripModel(this._tracingModel);
-}
-
-interactionModel(){
-const irModel=new WebInspector.TimelineIRModel();
-irModel.populate(this._timelineModel);
-return irModel;
-}}
-
-
-module.exports=TimelineModel;
-
-},{"../console-quieter":19,"../web-inspector":42,"devtools-timeline-model/lib/timeline-model-treeview.js":129}],38:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const log=require('lighthouse-logger');
-
-
-
-
-
-
-function safeGet(object,path){
-const components=path.split('.');
-for(const component of components){
-if(!object){
-return null;
-}
-object=object[component];
-}
-return object;
-}
-
-class Metrics{
-constructor(traceEvents,auditResults){
-this._traceEvents=traceEvents;
-this._auditResults=auditResults;
-}
-
-
-
-
-
-static get metricsDefinitions(){
-return[
-{
-name:'Navigation Start',
-id:'navstart',
-getTs:auditResults=>{
-const fmpExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(fmpExt,'value.timestamps.navStart');
-},
-getTiming:auditResults=>{
-const fmpExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(fmpExt,'value.timings.navStart');
-}},
-
-{
-name:'First Contentful Paint',
-id:'ttfcp',
-getTs:auditResults=>{
-const fmpExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(fmpExt,'value.timestamps.fCP');
-},
-getTiming:auditResults=>{
-const fmpExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(fmpExt,'value.timings.fCP');
-}},
-
-{
-name:'First Meaningful Paint',
-id:'ttfmp',
-getTs:auditResults=>{
-const fmpExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(fmpExt,'value.timestamps.fMP');
-},
-getTiming:auditResults=>{
-const fmpExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(fmpExt,'value.timings.fMP');
-}},
-
-{
-name:'Perceptual Speed Index',
-id:'psi',
-getTs:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timestamps.perceptualSpeedIndex');
-},
-getTiming:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timings.perceptualSpeedIndex');
-}},
-
-{
-name:'First Visual Change',
-id:'fv',
-getTs:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timestamps.firstVisualChange');
-},
-getTiming:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timings.firstVisualChange');
-}},
-
-{
-name:'Visually Complete 85%',
-id:'vc85',
-getTs:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timestamps.visuallyReady');
-},
-getTiming:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timings.visuallyReady');
-}},
-
-{
-name:'Visually Complete 100%',
-id:'vc100',
-getTs:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timestamps.visuallyComplete');
-},
-getTiming:auditResults=>{
-const siExt=auditResults['speed-index-metric'].extendedInfo;
-return safeGet(siExt,'value.timings.visuallyComplete');
-}},
-
-{
-name:'First Interactive (vBeta)',
-id:'ttfi',
-getTs:auditResults=>{
-const ttfiExt=auditResults['first-interactive'].extendedInfo;
-return safeGet(ttfiExt,'value.timestamp');
-},
-getTiming:auditResults=>{
-const ttfiExt=auditResults['first-interactive'].extendedInfo;
-return safeGet(ttfiExt,'value.timeInMs');
-}},
-
-{
-name:'Time to Consistently Interactive (vBeta)',
-id:'ttci',
-getTs:auditResults=>{
-const ttiExt=auditResults['consistently-interactive'].extendedInfo;
-return safeGet(ttiExt,'value.timestamp');
-},
-getTiming:auditResults=>{
-const ttiExt=auditResults['consistently-interactive'].extendedInfo;
-return safeGet(ttiExt,'value.timeInMs');
-}},
-
-{
-name:'End of Trace',
-id:'eot',
-getTs:auditResults=>{
-const ttiExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(ttiExt,'value.timestamps.endOfTrace');
-},
-getTiming:auditResults=>{
-const ttiExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(ttiExt,'value.timings.endOfTrace');
-}},
-
-{
-name:'On Load',
-id:'onload',
-getTs:auditResults=>{
-const ttiExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(ttiExt,'value.timestamps.onLoad');
-},
-getTiming:auditResults=>{
-const ttiExt=auditResults['first-meaningful-paint'].extendedInfo;
-return safeGet(ttiExt,'value.timings.onLoad');
-}}];
-
-
-}
-
-
-
-
-
-gatherMetrics(){
-const metricDfns=Metrics.metricsDefinitions;
-const resolvedMetrics=[];
-metricDfns.forEach(metric=>{
-
-try{
-resolvedMetrics.push({
-id:metric.id,
-name:metric.name,
-ts:metric.getTs(this._auditResults)});
-
-}catch(e){
-log.error('pwmetrics-events',`${metric.name} timestamp not found: ${e.message}`);
-}
-});
-return resolvedMetrics;
-}
-
-
-
-
-
-identifyNavigationStartEvt(metrics){
-const navStartMetric=metrics.find(e=>e.id==='navstart');
-if(!navStartMetric)return;
-this._navigationStartEvt=this._traceEvents.find(
-e=>e.name==='navigationStart'&&e.ts===navStartMetric.ts);
-
-}
-
-
-
-
-
-
-
-
-synthesizeEventPair(metric){
-
-const eventBase={
-pid:this._navigationStartEvt.pid,
-tid:this._navigationStartEvt.tid,
-cat:'blink.user_timing',
-name:metric.name,
-args:{},
-
-id:`0x${(Math.random()*1000000|0).toString(16)}`};
-
-const fakeMeasureStartEvent=Object.assign({},eventBase,{
-ts:this._navigationStartEvt.ts,
-ph:'b'});
-
-const fakeMeasureEndEvent=Object.assign({},eventBase,{
-ts:metric.ts,
-ph:'e'});
-
-return[fakeMeasureStartEvent,fakeMeasureEndEvent];
-}
-
-
-
-
-generateFakeEvents(){
-const fakeEvents=[];
-const metrics=this.gatherMetrics();
-if(metrics.length===0){
-log.error('metrics-events','Metrics collection had errors, not synthetizing trace events');
-return[];
-}
-
-this.identifyNavigationStartEvt(metrics);
-if(!this._navigationStartEvt){
-log.error('pwmetrics-events','Reference navigationStart not found');
-return[];
-}
-
-metrics.forEach(metric=>{
-if(metric.id==='navstart'){
-return;
-}
-if(!metric.ts){
-log.error('pwmetrics-events',`(${metric.name}) missing timestamp. Skipping…`);
-return;
-}
-log.verbose('pwmetrics-events',`Sythesizing trace events for ${metric.name}`);
-fakeEvents.push(...this.synthesizeEventPair(metric));
-});
-return fakeEvents;
-}}
-
-
-module.exports=Metrics;
-
-},{"lighthouse-logger":137}],39:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-const WebInspector=require('../web-inspector');
-
-
-
-
-
-
-
-
-
-class TraceParser{
-constructor(){
-this.traceEvents=[];
-
-this.tracingModel={
-reset:_=>this._reset(),
-addEvents:evts=>this._addEvents(evts)};
-
-
-const delegateMock={
-loadingProgress:_=>{},
-loadingStarted:_=>{},
-loadingComplete:success=>{
-if(!success)throw new Error('Parsing problem');
-}};
-
-this.loader=new WebInspector.TimelineLoader(this.tracingModel,delegateMock);
-}
-
-
-
-
-_reset(){
-this.traceEvents=[];
-}
-
-
-
-
-
-_addEvents(evts){
-this.traceEvents.push(...evts);
-}
-
-
-
-
-
-parseChunk(data){
-this.loader.write(data);
-}
-
-
-
-
-
-getTrace(){
-return{
-traceEvents:this.traceEvents};
-
-}}
-
-
-module.exports=TraceParser;
-
-},{"../web-inspector":42}],40:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-const BASE_RESPONSE_LATENCY=16;
-const SCHEDULABLE_TASK_TITLE='TaskQueueManager::ProcessTaskFromWorkQueue';
-const SCHEDULABLE_TASK_TITLE_ALT='ThreadControllerImpl::DoWork';
-
-class TraceProcessor{
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-static _riskPercentiles(durations,totalTime,percentiles,clippedLength=0){
-let busyTime=0;
-for(let i=0;i<durations.length;i++){
-busyTime+=durations[i];
-}
-busyTime-=clippedLength;
-
-
-let completedTime=totalTime-busyTime;
-let duration=0;
-let cdfTime=completedTime;
-const results=[];
-
-let durationIndex=-1;
-let remainingCount=durations.length+1;
-if(clippedLength>0){
-
-remainingCount--;
-}
-
-
-for(const percentile of percentiles){
-
-
-const percentileTime=percentile*totalTime;
-while(cdfTime<percentileTime&&durationIndex<durations.length-1){
-completedTime+=duration;
-remainingCount-=duration<0?-1:1;
-
-if(clippedLength>0&&clippedLength<durations[durationIndex+1]){
-duration=-clippedLength;
-clippedLength=0;
-}else{
-durationIndex++;
-duration=durations[durationIndex];
-}
-
-
-cdfTime=completedTime+Math.abs(duration)*remainingCount;
-}
-
-
-results.push({
-percentile,
-time:Math.max(0,(percentileTime-completedTime)/remainingCount)+
-BASE_RESPONSE_LATENCY});
-
-}
-
-return results;
-}
-
-
-
-
-
-
-
-
-
-
-
-static getRiskToResponsiveness(
-tabTrace,
-startTime=0,
-endTime=tabTrace.timings.traceEnd,
-percentiles=[0.5,0.75,0.9,0.99,1])
-{
-const totalTime=endTime-startTime;
-percentiles.sort((a,b)=>a-b);
-
-const ret=TraceProcessor.getMainThreadTopLevelEventDurations(tabTrace,startTime,endTime);
-return TraceProcessor._riskPercentiles(ret.durations,totalTime,percentiles,
-ret.clippedLength);
-}
-
-
-
-
-
-
-
-
-static getMainThreadTopLevelEventDurations(tabTrace,startTime=0,endTime=Infinity){
-const topLevelEvents=TraceProcessor.getMainThreadTopLevelEvents(tabTrace,startTime,endTime);
-
-
-const durations=[];
-let clippedLength=0;
-
-topLevelEvents.forEach(event=>{
-let duration=event.duration;
-let eventStart=event.start;
-if(eventStart<startTime){
-
-eventStart=startTime;
-duration=event.end-startTime;
-}
-
-if(event.end>endTime){
-
-clippedLength=duration-(endTime-eventStart);
-}
-
-durations.push(duration);
-});
-durations.sort((a,b)=>a-b);
-
-return{
-durations,
-clippedLength};
-
-}
-
-
-
-
-
-
-
-
-
-static getMainThreadTopLevelEvents(tabTrace,startTime=0,endTime=Infinity){
-const topLevelEvents=[];
-
-for(const event of tabTrace.mainThreadEvents){
-if(!TraceProcessor.isScheduleableTask(event)||!event.dur)continue;
-
-const start=(event.ts-tabTrace.navigationStartEvt.ts)/1000;
-const end=(event.ts+event.dur-tabTrace.navigationStartEvt.ts)/1000;
-if(start>endTime||end<startTime)continue;
-
-topLevelEvents.push({
-start,
-end,
-duration:event.dur/1000});
-
-}
-
-
-
-if(!topLevelEvents.length){
-throw new Error('Could not find any top level events');
-}
-
-return topLevelEvents;
-}
-
-static isScheduleableTask(evt){
-return evt.name===SCHEDULABLE_TASK_TITLE||evt.name===SCHEDULABLE_TASK_TITLE_ALT;
-}}
-
-
-module.exports=TraceProcessor;
-
-},{}],41:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-
-
-
-
-
-
-const Util=require('../report/v2/renderer/util.js');
-
-
-
-const URL=typeof self!=='undefined'&&self.URL||require('whatwg-url').URL;
-
-URL.URLSearchParams=typeof self!=='undefined'&&self.URLSearchParams||
-require('whatwg-url').URLSearchParams;
-
-URL.INVALID_URL_DEBUG_STRING=
-'Lighthouse was unable to determine the URL of some script executions. '+
-'It\'s possible a Chrome extension or other eval\'d code is the source.';
-
-
-
-
-
-URL.isValid=function isValid(url){
-try{
-new URL(url);
-return true;
-}catch(e){
-return false;
-}
-};
-
-
-
-
-
-
-URL.hostsMatch=function hostsMatch(urlA,urlB){
-try{
-return new URL(urlA).host===new URL(urlB).host;
-}catch(e){
-return false;
-}
-};
-
-
-
-
-
-
-URL.originsMatch=function originsMatch(urlA,urlB){
-try{
-return new URL(urlA).origin===new URL(urlB).origin;
-}catch(e){
-return false;
-}
-};
-
-
-
-
-
-URL.getOrigin=function getOrigin(url){
-try{
-const urlInfo=new URL(url);
-
-
-return urlInfo.host&&urlInfo.origin||null;
-}catch(e){
-return null;
-}
-};
-
-
-
-
-
-
-URL.getURLDisplayName=function getURLDisplayName(url,options){
-return Util.getURLDisplayName(new URL(url),options);
-};
-
-
-
-
-
-
-URL.elideDataURI=function elideDataURI(url){
-try{
-const parsed=new URL(url);
-return parsed.protocol==='data:'?url.slice(0,100):url;
-}catch(e){
-return url;
-}
-};
-
-
-
-
-function rewriteChromeInternalUrl(url){
-if(!url||!url.startsWith('chrome://'))return url;
-
-
-if(url.endsWith('/'))url=url.replace(/\/$/,'');
-return url.replace(/^chrome:\/\/chrome\//,'chrome://');
-}
-
-
-
-
-
-
-
-URL.equalWithExcludedFragments=function(url1,url2){
-[url1,url2]=[url1,url2].map(rewriteChromeInternalUrl);
-try{
-url1=new URL(url1);
-url1.hash='';
-
-url2=new URL(url2);
-url2.hash='';
-
-return url1.href===url2.href;
-}catch(e){
-return false;
-}
-};
-
-module.exports=URL;
-
-},{"../report/v2/renderer/util.js":43,"whatwg-url":52}],42:[function(require,module,exports){
-(function(global){
-
-
-
-
-
-
-'use strict';
-
-
-
-
-
-module.exports=function(){
-if(global.WebInspector){
-return global.WebInspector;
-}
-
-
-
-if(global.self!==global){
-global.self=global;
-}
-
-if(typeof global.window==='undefined'){
-global.window=global;
-}
-
-global.Node={
-ELEMENT_NODE:1,
-TEXT_NODE:3};
-
-
-global.CSSAgent={};
-global.CSSAgent.StyleSheetOrigin={
-INJECTED:'injected',
-USER_AGENT:'user-agent',
-INSPECTOR:'inspector',
-REGULAR:'regular'};
-
-
-global.CSS={};
-global.CSS.supports=()=>true;
-
-
-
-const _setImmediate=global.setImmediate;
-
-global.Runtime=global.Runtime||{};
-global.Runtime.experiments=global.Runtime.experiments||{};
-
-
-global.Runtime.experiments.isEnabled=_=>false;
-
-const _queryParam=global.Runtime.queryParam;
-global.Runtime.queryParam=function(arg){
-switch(arg){
-case'remoteFrontend':
-return false;
-case'ws':
-return false;
-default:{
-if(_queryParam){
-return _queryParam.call(global.Runtime,arg);
-}
-throw new Error('Mock queryParam case not implemented.');
-}}
-
-};
-
-global.TreeElement={};
-global.WorkerRuntime={};
-
-global.Protocol={
-Agents(){}};
-
-
-global.WebInspector={};
-const WebInspector=global.WebInspector;
-WebInspector._moduleSettings={
-cacheDisabled:{
-addChangeListener(){},
-get(){
-return false;
-}},
-
-monitoringXHREnabled:{
-addChangeListener(){},
-get(){
-return false;
-}},
-
-showNativeFunctionsInJSProfile:{
-addChangeListener(){},
-get(){
-return true;
-}}};
-
-
-WebInspector.moduleSetting=function(settingName){
-return this._moduleSettings[settingName];
-};
-
-
-global.NetworkAgent={
-RequestMixedContentType:{
-Blockable:'blockable',
-OptionallyBlockable:'optionally-blockable',
-None:'none'},
-
-BlockedReason:{
-CSP:'csp',
-MixedContent:'mixed-content',
-Origin:'origin',
-Inspector:'inspector',
-Other:'other'},
-
-InitiatorType:{
-Other:'other',
-Parser:'parser',
-Redirect:'redirect',
-Script:'script'}};
-
-
-
-
-global.SecurityAgent={
-SecurityState:{
-Unknown:'unknown',
-Neutral:'neutral',
-Insecure:'insecure',
-Warning:'warning',
-Secure:'secure',
-Info:'info'}};
-
-
-
-global.PageAgent={
-ResourceType:{
-Document:'document',
-Stylesheet:'stylesheet',
-Image:'image',
-Media:'media',
-Font:'font',
-Script:'script',
-TextTrack:'texttrack',
-XHR:'xhr',
-Fetch:'fetch',
-EventSource:'eventsource',
-WebSocket:'websocket',
-Manifest:'manifest',
-Other:'other'}};
-
-
-
-require('chrome-devtools-frontend/front_end/common/Object.js');
-require('chrome-devtools-frontend/front_end/common/ParsedURL.js');
-require('chrome-devtools-frontend/front_end/common/ResourceType.js');
-require('chrome-devtools-frontend/front_end/common/UIString.js');
-require('chrome-devtools-frontend/front_end/platform/utilities.js');
-require('chrome-devtools-frontend/front_end/sdk/Target.js');
-require('chrome-devtools-frontend/front_end/sdk/TargetManager.js');
-require('chrome-devtools-frontend/front_end/sdk/NetworkManager.js');
-require('chrome-devtools-frontend/front_end/sdk/NetworkRequest.js');
-
-
-WebInspector.targetManager={
-observeTargets(){},
-addEventListener(){}};
-
-WebInspector.settings={
-createSetting(){
-return{
-get(){
-return false;
-},
-addChangeListener(){}};
-
-}};
-
-WebInspector.console={
-error(){}};
-
-WebInspector.VBox=function(){};
-WebInspector.HBox=function(){};
-WebInspector.ViewportDataGrid=function(){};
-WebInspector.ViewportDataGridNode=function(){};
-global.WorkerRuntime.Worker=function(){};
-
-require('chrome-devtools-frontend/front_end/common/SegmentedRange.js');
-require('chrome-devtools-frontend/front_end/bindings/TempFile.js');
-require('chrome-devtools-frontend/front_end/sdk/TracingModel.js');
-require('chrome-devtools-frontend/front_end/sdk/ProfileTreeModel.js');
-require('chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js');
-require('chrome-devtools-frontend/front_end/timeline_model/TimelineJSProfile.js');
-require('chrome-devtools-frontend/front_end/sdk/CPUProfileDataModel.js');
-require('chrome-devtools-frontend/front_end/timeline_model/LayerTreeModel.js');
-require('chrome-devtools-frontend/front_end/timeline_model/TimelineModel.js');
-require('chrome-devtools-frontend/front_end/ui_lazy/SortableDataGrid.js');
-require('chrome-devtools-frontend/front_end/timeline/TimelineTreeView.js');
-
-
-require('chrome-devtools-frontend/front_end/common/TextUtils.js');
-require('chrome-devtools-frontend/front_end/timeline/TimelineLoader.js');
-
-require('chrome-devtools-frontend/front_end/timeline_model/TimelineProfileTree.js');
-require('chrome-devtools-frontend/front_end/components_lazy/FilmStripModel.js');
-require('chrome-devtools-frontend/front_end/timeline_model/TimelineIRModel.js');
-require('chrome-devtools-frontend/front_end/timeline_model/TimelineFrameModel.js');
-
-
-WebInspector.DeferredTempFile=function(){};
-WebInspector.DeferredTempFile.prototype={
-write:function(){},
-finishWriting:function(){}};
-
-
-
-WebInspector.ConsoleMessage=function(){};
-WebInspector.ConsoleMessage.MessageSource={
-Network:'network'};
-
-WebInspector.ConsoleMessage.MessageLevel={
-Log:'log'};
-
-WebInspector.ConsoleMessage.MessageType={
-Log:'log'};
-
-
-
-WebInspector.NetworkLog=function(target){
-this._requests=new Map();
-target.networkManager.addEventListener(
-WebInspector.NetworkManager.Events.RequestStarted,this._onRequestStarted,this);
-};
-
-WebInspector.NetworkLog.prototype={
-requestForURL:function(url){
-return this._requests.get(url)||null;
-},
-
-_onRequestStarted:function(event){
-const request=event.data;
-if(this._requests.has(request.url)){
-return;
-}
-this._requests.set(request.url,request);
-}};
-
-
-
-require('chrome-devtools-frontend/front_end/common/Color.js');
-
-
-
-const Dispatcher=WebInspector.NetworkDispatcher;
-const origUpdateRequest=Dispatcher.prototype._updateNetworkRequestWithRequest;
-Dispatcher.prototype._updateNetworkRequestWithRequest=function(netRecord,request){
-origUpdateRequest.apply(this,arguments);
-netRecord.isLinkPreload=Boolean(request.isLinkPreload);
-netRecord._isLinkPreload=Boolean(request.isLinkPreload);
-};
-
-
-
-
-
-WebInspector.NetworkManager.createWithFakeTarget=function(){
-
-const fakeNetworkAgent={
-enable(){},
-getResponseBody(){
-throw new Error('Use driver.getRequestContent() for network request content');
-}};
-
-const fakeConsoleModel={
-addMessage(){},
-target(){}};
-
-const fakeTarget={
-_modelByConstructor:new Map(),
-get consoleModel(){
-return fakeConsoleModel;
-},
-networkAgent(){
-return fakeNetworkAgent;
-},
-registerNetworkDispatcher(){},
-model(){}};
-
-
-fakeTarget.networkManager=new WebInspector.NetworkManager(fakeTarget);
-fakeTarget.networkLog=new WebInspector.NetworkLog(fakeTarget);
-
-WebInspector.NetworkLog.fromTarget=()=>{
-return fakeTarget.networkLog;
-};
-
-return fakeTarget.networkManager;
-};
-
-
-require('chrome-devtools-frontend/front_end/common/TextRange.js');
-require('chrome-devtools-frontend/front_end/sdk/CSSMatchedStyles.js');
-require('chrome-devtools-frontend/front_end/sdk/CSSMedia.js');
-require('chrome-devtools-frontend/front_end/sdk/CSSMetadata.js');
-require('chrome-devtools-frontend/front_end/sdk/CSSProperty.js');
-require('chrome-devtools-frontend/front_end/sdk/CSSRule.js');
-require('chrome-devtools-frontend/front_end/sdk/CSSStyleDeclaration.js');
-
-WebInspector.CSSMetadata._generatedProperties=[
-{
-name:'font-size',
-inherited:true}];
-
-
-
-
-global.setImmediate=_setImmediate;
-
-return WebInspector;
-}();
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"chrome-devtools-frontend/front_end/bindings/TempFile.js":93,"chrome-devtools-frontend/front_end/common/Color.js":94,"chrome-devtools-frontend/front_end/common/Object.js":95,"chrome-devtools-frontend/front_end/common/ParsedURL.js":96,"chrome-devtools-frontend/front_end/common/ResourceType.js":97,"chrome-devtools-frontend/front_end/common/SegmentedRange.js":98,"chrome-devtools-frontend/front_end/common/TextRange.js":99,"chrome-devtools-frontend/front_end/common/TextUtils.js":100,"chrome-devtools-frontend/front_end/common/UIString.js":101,"chrome-devtools-frontend/front_end/components_lazy/FilmStripModel.js":102,"chrome-devtools-frontend/front_end/platform/utilities.js":103,"chrome-devtools-frontend/front_end/sdk/CPUProfileDataModel.js":104,"chrome-devtools-frontend/front_end/sdk/CSSMatchedStyles.js":105,"chrome-devtools-frontend/front_end/sdk/CSSMedia.js":106,"chrome-devtools-frontend/front_end/sdk/CSSMetadata.js":107,"chrome-devtools-frontend/front_end/sdk/CSSProperty.js":108,"chrome-devtools-frontend/front_end/sdk/CSSRule.js":109,"chrome-devtools-frontend/front_end/sdk/CSSStyleDeclaration.js":110,"chrome-devtools-frontend/front_end/sdk/NetworkManager.js":111,"chrome-devtools-frontend/front_end/sdk/NetworkRequest.js":112,"chrome-devtools-frontend/front_end/sdk/ProfileTreeModel.js":113,"chrome-devtools-frontend/front_end/sdk/Target.js":114,"chrome-devtools-frontend/front_end/sdk/TargetManager.js":115,"chrome-devtools-frontend/front_end/sdk/TracingModel.js":116,"chrome-devtools-frontend/front_end/timeline/TimelineLoader.js":117,"chrome-devtools-frontend/front_end/timeline/TimelineTreeView.js":118,"chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js":119,"chrome-devtools-frontend/front_end/timeline_model/LayerTreeModel.js":120,"chrome-devtools-frontend/front_end/timeline_model/TimelineFrameModel.js":121,"chrome-devtools-frontend/front_end/timeline_model/TimelineIRModel.js":122,"chrome-devtools-frontend/front_end/timeline_model/TimelineJSProfile.js":123,"chrome-devtools-frontend/front_end/timeline_model/TimelineModel.js":124,"chrome-devtools-frontend/front_end/timeline_model/TimelineProfileTree.js":125,"chrome-devtools-frontend/front_end/ui_lazy/SortableDataGrid.js":126}],43:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-const ELLIPSIS='\u2026';
-const NBSP='\xa0';
-
-const RATINGS={
-PASS:{label:'pass',minScore:75},
-AVERAGE:{label:'average',minScore:45},
-FAIL:{label:'fail'}};
-
-
-class Util{
-
-
-
-
-
-static calculateRating(score){
-let rating=RATINGS.FAIL.label;
-if(score>=RATINGS.PASS.minScore){
-rating=RATINGS.PASS.label;
-}else if(score>=RATINGS.AVERAGE.minScore){
-rating=RATINGS.AVERAGE.label;
-}
-return rating;
-}
-
-
-
-
-
-
-
-static formatNumber(number,decimalPlaces=1){
-return number.toLocaleString(undefined,{maximumFractionDigits:decimalPlaces});
-}
-
-
-
-
-
-
-static formatBytesToKB(size,decimalPlaces=2){
-const kbs=(size/1024).toLocaleString(undefined,{maximumFractionDigits:decimalPlaces});
-return`${kbs}${NBSP}KB`;
-}
-
-
-
-
-
-
-static formatMilliseconds(ms,granularity=10){
-const coarseTime=Math.round(ms/granularity)*granularity;
-return`${coarseTime.toLocaleString()}${NBSP}ms`;
-}
-
-
-
-
-
-
-static formatDateTime(date){
-const options={
-month:'short',day:'numeric',year:'numeric',
-hour:'numeric',minute:'numeric',timeZoneName:'short'};
-
-let formatter=new Intl.DateTimeFormat('en-US',options);
-
-
-
-const tz=formatter.resolvedOptions().timeZone;
-if(!tz||tz.toLowerCase()==='etc/unknown'){
-options.timeZone='UTC';
-formatter=new Intl.DateTimeFormat('en-US',options);
-}
-return formatter.format(new Date(date));
-}
-
-
-
-
-
-
-static formatDuration(timeInSeconds,zeroLabel='None'){
-if(timeInSeconds===0){
-return zeroLabel;
-}
-
-
-const parts=[];
-const unitLabels={
-d:60*60*24,
-h:60*60,
-m:60,
-s:1};
-
-
-Object.keys(unitLabels).forEach(label=>{
-const unit=unitLabels[label];
-const numberOfUnits=Math.floor(timeInSeconds/unit);
-if(numberOfUnits>0){
-timeInSeconds-=numberOfUnits*unit;
-parts.push(`${numberOfUnits}\xa0${label}`);
-}
-});
-
-return parts.join(' ');
-}
-
-
-
-
-
-
-static getURLDisplayName(parsedUrl,options){
-options=options||{};
-const numPathParts=options.numPathParts!==undefined?options.numPathParts:2;
-const preserveQuery=options.preserveQuery!==undefined?options.preserveQuery:true;
-const preserveHost=options.preserveHost||false;
-
-let name;
-
-if(parsedUrl.protocol==='about:'||parsedUrl.protocol==='data:'){
-
-name=parsedUrl.href;
-}else{
-name=parsedUrl.pathname;
-const parts=name.split('/').filter(part=>part.length);
-if(numPathParts&&parts.length>numPathParts){
-name=ELLIPSIS+parts.slice(-1*numPathParts).join('/');
-}
-
-if(preserveHost){
-name=`${parsedUrl.host}/${name.replace(/^\//,'')}`;
-}
-if(preserveQuery){
-name=`${name}${parsedUrl.search}`;
-}
-}
-
-const MAX_LENGTH=64;
-
-name=name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g,`$1${ELLIPSIS}`);
-
-name=name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
-`$1${ELLIPSIS}`);
-
-name=name.replace(/(\d{3})\d{6,}/g,`$1${ELLIPSIS}`);
-
-name=name.replace(/\u2026+/g,ELLIPSIS);
-
-
-if(name.length>MAX_LENGTH&&name.includes('?')){
-
-name=name.replace(/\?([^=]*)(=)?.*/,`?$1$2${ELLIPSIS}`);
-
-
-if(name.length>MAX_LENGTH){
-name=name.replace(/\?.*/,`?${ELLIPSIS}`);
-}
-}
-
-
-if(name.length>MAX_LENGTH){
-const dotIndex=name.lastIndexOf('.');
-if(dotIndex>=0){
-name=name.slice(0,MAX_LENGTH-1-(name.length-dotIndex))+
-
-`${ELLIPSIS}${name.slice(dotIndex)}`;
-}else{
-name=name.slice(0,MAX_LENGTH-1)+ELLIPSIS;
-}
-}
-
-return name;
-}
-
-
-
-
-
-
-static parseURL(url){
-const parsedUrl=new URL(url);
-return{file:Util.getURLDisplayName(parsedUrl),hostname:parsedUrl.hostname};
-}
-
-
-
-
-
-
-static chainDuration(startTime,endTime){
-return Util.formatNumber((endTime-startTime)*1000);
-}}
-
-
-if(typeof module!=='undefined'&&module.exports){
-module.exports=Util;
-}else{
-
-self.Util=Util;
-}
-
-},{}],44:[function(require,module,exports){
-(function(process,__dirname){
-
-
-
-
-
-
-'use strict';
-
-const Driver=require('./gather/driver.js');
-const GatherRunner=require('./gather/gather-runner');
-const ReportScoring=require('./scoring');
-const Audit=require('./audits/audit');
-const emulation=require('./lib/emulation');
-const log=require('lighthouse-logger');
-const assetSaver=require('./lib/asset-saver');
-
-const path=require('path');
-const URL=require('./lib/url-shim');
-const Sentry=require('./lib/sentry');
-
-const basePath=path.join(process.cwd(),'latest-run');
-
-class Runner{
-static run(connection,opts){
-
-opts.flags=opts.flags||{};
-
-
-const lighthouseRunWarnings=[];
-
-
-opts.initialUrl=opts.url;
-if(typeof opts.initialUrl!=='string'||opts.initialUrl.length===0){
-return Promise.reject(new Error('You must provide a url to the runner'));
-}
-
-let parsedURL;
-try{
-parsedURL=new URL(opts.url);
-}catch(e){
-const err=new Error('The url provided should have a proper protocol and hostname.');
-return Promise.reject(err);
-}
-
-const sentryContext=Sentry.getContext();
-Sentry.captureBreadcrumb({
-message:'Run started',
-category:'lifecycle',
-data:sentryContext&&sentryContext.extra});
-
-
-
-if(parsedURL.protocol!=='https:'&&parsedURL.hostname!=='localhost'){
-log.warn('Lighthouse','The URL provided should be on HTTPS');
-log.warn('Lighthouse','Performance stats will be skewed redirecting from HTTP to HTTPS.');
-}
-
-
-opts.url=parsedURL.href;
-
-
-let run=Promise.resolve();
-
-
-
-
-
-
-
-if(opts.flags.auditMode&&!opts.flags.gatherMode){
-run=run.then(_=>Runner._loadArtifactsFromDisk());
-}else if(opts.config.artifacts){
-run=run.then(_=>opts.config.artifacts);
-}else{
-run=run.then(_=>Runner._gatherArtifactsFromBrowser(opts,connection));
-}
-
-
-if(opts.flags.gatherMode&&!opts.flags.auditMode)return run;
-
-
-run=run.then(artifacts=>Runner._runAudits(opts,artifacts));
-
-
-run=run.then(runResults=>{
-log.log('status','Generating results...');
-
-if(runResults.artifacts.LighthouseRunWarnings){
-lighthouseRunWarnings.push(...runResults.artifacts.LighthouseRunWarnings);
-}
-
-
-const resultsById={};
-for(const audit of runResults.auditResults)resultsById[audit.name]=audit;
-
-let report;
-if(opts.config.categories){
-report=Runner._scoreAndCategorize(opts,resultsById);
-}
-
-return{
-userAgent:runResults.artifacts.UserAgent,
-lighthouseVersion:require('../package').version,
-generatedTime:new Date().toJSON(),
-initialUrl:opts.initialUrl,
-url:opts.url,
-runWarnings:lighthouseRunWarnings,
-audits:resultsById,
-artifacts:runResults.artifacts,
-runtimeConfig:Runner.getRuntimeConfig(opts.flags),
-score:report?report.score:0,
-reportCategories:report?report.categories:[],
-reportGroups:opts.config.groups};
-
-}).catch(err=>{
-return Sentry.captureException(err,{level:'fatal'}).then(()=>{
-throw err;
-});
-});
-
-return run;
-}
-
-
-
-
-
-static _loadArtifactsFromDisk(){
-return assetSaver.loadArtifacts(basePath);
-}
-
-
-
-
-
-
-
-static _gatherArtifactsFromBrowser(opts,connection){
-if(!opts.config.passes){
-return Promise.reject(new Error('No browser artifacts are either provided or requested.'));
-}
-
-opts.driver=opts.driverMock||new Driver(connection);
-return GatherRunner.run(opts.config.passes,opts).then(artifacts=>{
-const flags=opts.flags;
-const shouldSave=flags.gatherMode;
-const p=shouldSave?Runner._saveArtifacts(artifacts):Promise.resolve();
-return p.then(_=>artifacts);
-});
-}
-
-
-
-
-
-
-static _saveArtifacts(artifacts){
-return assetSaver.saveArtifacts(artifacts,basePath);
-}
-
-
-
-
-
-
-
-static _runAudits(opts,artifacts){
-if(!opts.config.audits){
-return Promise.reject(new Error('No audits to evaluate.'));
-}
-
-log.log('status','Analyzing and running audits...');
-artifacts=Object.assign(Runner.instantiateComputedArtifacts(),
-artifacts||opts.config.artifacts);
-
-
-const auditResults=[];
-let promise=Promise.resolve();
-for(const audit of opts.config.audits){
-promise=promise.then(_=>{
-return Runner._runAudit(audit,artifacts).then(ret=>auditResults.push(ret));
-});
-}
-return promise.then(_=>{
-const runResults={artifacts,auditResults};
-return runResults;
-});
-}
-
-
-
-
-
-static _scoreAndCategorize(opts,resultsById){
-return ReportScoring.scoreAllCategories(opts.config,resultsById);
-}
-
-
-
-
-
-
-
-
-
-static _runAudit(audit,artifacts){
-const status=`Evaluating: ${audit.meta.description}`;
-
-return Promise.resolve().then(_=>{
-log.log('status',status);
-
-
-for(const artifactName of audit.meta.requiredArtifacts){
-const noArtifact=typeof artifacts[artifactName]==='undefined';
-
-
-
-const noTrace=artifactName==='traces'&&!artifacts.traces[Audit.DEFAULT_PASS];
-
-if(noArtifact||noTrace){
-log.warn('Runner',
-`${artifactName} gatherer, required by audit ${audit.meta.name}, did not run.`);
-throw new Error(`Required ${artifactName} gatherer did not run.`);
-}
-
-
-
-if(artifacts[artifactName]instanceof Error){
-const artifactError=artifacts[artifactName];
-Sentry.captureException(artifactError,{
-tags:{gatherer:artifactName},
-level:'error'});
-
-
-log.warn('Runner',`${artifactName} gatherer, required by audit ${audit.meta.name},`+
-` encountered an error: ${artifactError.message}`);
-
-
-const error=new Error(
-`Required ${artifactName} gatherer encountered an error: ${artifactError.message}`);
-error.expected=true;
-throw error;
-}
-}
-
-return audit.audit(artifacts);
-
-}).then(auditResult=>Audit.generateAuditResult(audit,auditResult)).
-catch(err=>{
-log.warn(audit.meta.name,`Caught exception: ${err.message}`);
-if(err.fatal){
-throw err;
-}
-
-Sentry.captureException(err,{tags:{audit:audit.meta.name},level:'error'});
-
-const debugString=err.friendlyMessage?
-`${err.friendlyMessage} (${err.message})`:
-`Audit error: ${err.message}`;
-return Audit.generateErrorAuditResult(audit,debugString);
-}).then(result=>{
-log.verbose('statusEnd',status);
-return result;
-});
-}
-
-
-
-
-
-static getAuditList(){
-const ignoredFiles=[
-'audit.js',
-'violation-audit.js',
-'accessibility/axe-audit.js',
-'multi-check-audit.js',
-'byte-efficiency/byte-efficiency-audit.js',
-'manual/manual-audit.js'];
-
-
-const fileList=[
-...[".DS_Store","accessibility","audit.js","bootup-time.js","byte-efficiency","cache-start-url.js","consistently-interactive.js","content-width.js","critical-request-chains.js","deprecations.js","dobetterweb","errors-in-console.js","estimated-input-latency.js","first-interactive.js","first-meaningful-paint.js","font-display.js","image-aspect-ratio.js","is-on-https.js","load-fast-enough-for-pwa.js","mainthread-work-breakdown.js","manifest-short-name-length.js","manual","mixed-content.js","multi-check-audit.js","predictive-perf.js","redirects-http.js","redirects.js","screenshot-thumbnails.js","seo","service-worker.js","speed-index-metric.js","splash-screen.js","themed-omnibox.js","time-to-first-byte.js","user-timings.js","uses-rel-preload.js","viewport.js","violation-audit.js","webapp-install-banner.js","without-javascript.js","works-offline.js"],
-...["appcache-manifest.js","dom-size.js","external-anchors-use-rel-noopener.js","geolocation-on-start.js","link-blocking-first-paint.js","no-document-write.js","no-mutation-events.js","no-vulnerable-libraries.js","no-websql.js","notification-on-start.js","password-inputs-can-be-pasted-into.js","script-blocking-first-paint.js","uses-http2.js","uses-passive-event-listeners.js"].map(f=>`dobetterweb/${f}`),
-...["canonical.js","font-size.js","hreflang.js","http-status-code.js","is-crawlable.js","link-text.js","manual","meta-description.js","plugins.js"].map(f=>`seo/${f}`),
-...["mobile-friendly.js","structured-data.js"].map(f=>`seo/manual/${f}`),
-...["accesskeys.js","aria-allowed-attr.js","aria-required-attr.js","aria-required-children.js","aria-required-parent.js","aria-roles.js","aria-valid-attr-value.js","aria-valid-attr.js","audio-caption.js","axe-audit.js","button-name.js","bypass.js","color-contrast.js","definition-list.js","dlitem.js","document-title.js","duplicate-id.js","frame-title.js","html-has-lang.js","html-lang-valid.js","image-alt.js","input-image-alt.js","label.js","layout-table.js","link-name.js","list.js","listitem.js","manual","meta-refresh.js","meta-viewport.js","object-alt.js","tabindex.js","td-headers-attr.js","th-has-data-cells.js","valid-lang.js","video-caption.js","video-description.js"].
-map(f=>`accessibility/${f}`),
-...["custom-controls-labels.js","custom-controls-roles.js","focus-traps.js","focusable-controls.js","heading-levels.js","logical-tab-order.js","managed-focus.js","offscreen-content-hidden.js","use-landmarks.js","visual-order-follows-dom.js"].
-map(f=>`accessibility/manual/${f}`),
-...["byte-efficiency-audit.js","offscreen-images.js","total-byte-weight.js","unminified-css.js","unminified-javascript.js","unused-css-rules.js","unused-javascript.js","uses-long-cache-ttl.js","uses-optimized-images.js","uses-request-compression.js","uses-responsive-images.js","uses-webp-images.js"].
-map(f=>`byte-efficiency/${f}`),
-...["manual-audit.js","pwa-cross-browser.js","pwa-each-page-has-url.js","pwa-page-transitions.js"].map(f=>`manual/${f}`)];
-
-return fileList.filter(f=>{
-return /\.js$/.test(f)&&!ignoredFiles.includes(f);
-}).sort();
-}
-
-
-
-
-
-static getGathererList(){
-const fileList=[
-...["accessibility.js","cache-contents.js","chrome-console-messages.js","css-usage.js","dobetterweb","fonts.js","gatherer.js","html-without-javascript.js","http-redirect.js","image-usage.js","js-usage.js","manifest.js","mixed-content.js","offline.js","runtime-exceptions.js","scripts.js","seo","service-worker.js","start-url.js","theme-color.js","url.js","viewport-dimensions.js","viewport.js"],
-...["canonical.js","crawlable-links.js","embedded-content.js","font-size.js","hreflang.js","meta-description.js","meta-robots.js"].map(f=>`seo/${f}`),
-...["all-event-listeners.js","anchors-with-no-rel-noopener.js","appcache.js","domstats.js","js-libraries.js","optimized-images.js","password-inputs-with-prevented-paste.js","response-compression.js","tags-blocking-first-paint.js","websql.js"].
-map(f=>`dobetterweb/${f}`)];
-
-return fileList.filter(f=>/\.js$/.test(f)&&f!=='gatherer.js').sort();
-}
-
-
-
-
-static instantiateComputedArtifacts(){
-const computedArtifacts={};
-const filenamesToSkip=[
-'computed-artifact.js'];
-
-
-["computed-artifact.js","critical-request-chains.js","dtm-model.js","first-interactive.js","main-resource.js","manifest-values.js","network-records.js","network-throughput.js","page-dependency-graph.js","pushed-requests.js","screenshots.js","speedline.js","trace-of-tab.js"].forEach(function(filename){
-if(filenamesToSkip.includes(filename))return;
-
-
-filename=filename.replace(/\.js$/,'');
-const ArtifactClass=require('./gather/computed/'+filename);
-const artifact=new ArtifactClass(computedArtifacts);
-
-computedArtifacts['request'+artifact.name]=artifact.request.bind(artifact);
-});
-return computedArtifacts;
-}
-
-
-
-
-
-
-
-
-
-
-
-static resolvePlugin(plugin,configDir,category){
-
-
-
-
-try{
-return require.resolve(plugin);
-}catch(e){}
-
-
-
-
-const cwdPath=path.resolve(process.cwd(),plugin);
-try{
-return require.resolve(cwdPath);
-}catch(e){}
-
-const errorString='Unable to locate '+(
-category?`${category}: `:'')+
-`${plugin} (tried to require() from '${__dirname}' and load from '${cwdPath}'`;
-
-if(!configDir){
-throw new Error(errorString+')');
-}
-
-
-
-
-const relativePath=path.resolve(configDir,plugin);
-try{
-return require.resolve(relativePath);
-}catch(requireError){}
-
-throw new Error(errorString+` and '${relativePath}')`);
-}
-
-
-
-
-
-
-static getRuntimeConfig(flags){
-const emulationDesc=emulation.getEmulationDesc();
-const environment=[
-{
-name:'Device Emulation',
-enabled:!flags.disableDeviceEmulation,
-description:emulationDesc['deviceEmulation']},
-
-{
-name:'Network Throttling',
-enabled:!flags.disableNetworkThrottling,
-description:emulationDesc['networkThrottling']},
-
-{
-name:'CPU Throttling',
-enabled:!flags.disableCpuThrottling,
-description:emulationDesc['cpuThrottling']}];
-
-
-
-return{
-environment,
-blockedUrlPatterns:flags.blockedUrlPatterns||[],
-extraHeaders:flags.extraHeaders||{}};
-
-}}
-
-
-module.exports=Runner;
-
-}).call(this,require('_process'),"/../lighthouse-core");
-},{"../package":146,"./audits/audit":2,"./gather/driver.js":14,"./gather/gather-runner":15,"./lib/asset-saver":18,"./lib/emulation":27,"./lib/sentry":33,"./lib/url-shim":41,"./scoring":45,"_process":71,"lighthouse-logger":137,"path":69}],45:[function(require,module,exports){
-
-
-
-
-
-
-'use strict';
-
-class ReportScoring{
-
-
-
-
-
-static arithmeticMean(items){
-const results=items.reduce((result,item)=>{
-const score=Number(item.score)||0;
-const weight=Number(item.weight)||0;
-return{
-weight:result.weight+weight,
-sum:result.sum+score*weight};
-
-},{weight:0,sum:0});
-
-return results.sum/results.weight||0;
-}
-
-
-
-
-
-
-
-static scoreAllCategories(config,resultsByAuditId){
-const categories=Object.keys(config.categories).map(categoryId=>{
-const category=config.categories[categoryId];
-category.id=categoryId;
-
-const audits=category.audits.map(audit=>{
-const result=resultsByAuditId[audit.id];
-
-let auditScore=Number(result.score)||0;
-if(typeof result.score==='boolean'){
-auditScore=result.score?100:0;
-}
-
-
-
-
-if(result.notApplicable){
-auditScore=100;
-audit.weight=0;
-result.informative=true;
-}
-
-return Object.assign({},audit,{result,score:auditScore});
-});
-
-const categoryScore=ReportScoring.arithmeticMean(audits);
-return Object.assign({},category,{audits,score:categoryScore});
-});
-
-const overallScore=ReportScoring.arithmeticMean(categories);
-return{score:overallScore,categories};
-}}
-
-
-module.exports=ReportScoring;
-
-},{}],46:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-const RawProtocol=require('../../../lighthouse-core/gather/connections/raw');
-const Runner=require('../../../lighthouse-core/runner');
-const Config=require('../../../lighthouse-core/config/config');
-const defaultConfig=require('../../../lighthouse-core/config/default.js');
-const fastConfig=require('../../../lighthouse-core/config/fast-config.js');
-const log=require('lighthouse-logger');
-
-
-
-
-
-
-
-
-window.runLighthouseForConnection=function(
-connection,url,options,categoryIDs,
-updateBadgeFn=function(){}){
-const config=options&&options.fastMode?new Config(fastConfig):new Config({
-extends:'lighthouse:default',
-settings:{onlyCategories:categoryIDs}});
-
-
-
-const runOptions=Object.assign({},options,{url,config});
-updateBadgeFn(url);
-
-return Runner.run(connection,runOptions).
-then(result=>{
-updateBadgeFn();
-return result;
-}).
-catch(err=>{
-updateBadgeFn();
-throw err;
-});
-};
-
-
-
-
-
-
-
-
-window.runLighthouseInWorker=function(port,url,options,categoryIDs){
-
-log.setLevel('info');
-const connection=new RawProtocol(port);
-return window.runLighthouseForConnection(connection,url,options,categoryIDs);
-};
-
-
-
-
-
-window.getDefaultCategories=function(){
-return Config.getCategories(defaultConfig);
-};
-
-window.listenForStatus=function(listenCallback){
-log.events.addListener('status',listenCallback);
-};
-
-},{"../../../lighthouse-core/config/config":7,"../../../lighthouse-core/config/default.js":8,"../../../lighthouse-core/config/fast-config.js":9,"../../../lighthouse-core/gather/connections/raw":12,"../../../lighthouse-core/runner":44,"lighthouse-logger":137}],47:[function(require,module,exports){
-(function(global){
-'use strict';
-
-
-
-
-
-
-
-
-
-
-function compare(a,b){
-if(a===b){
-return 0;
-}
-
-var x=a.length;
-var y=b.length;
-
-for(var i=0,len=Math.min(x,y);i<len;++i){
-if(a[i]!==b[i]){
-x=a[i];
-y=b[i];
-break;
-}
-}
-
-if(x<y){
-return-1;
-}
-if(y<x){
-return 1;
-}
-return 0;
-}
-function isBuffer(b){
-if(global.Buffer&&typeof global.Buffer.isBuffer==='function'){
-return global.Buffer.isBuffer(b);
-}
-return!!(b!=null&&b._isBuffer);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var util=require('util/');
-var hasOwn=Object.prototype.hasOwnProperty;
-var pSlice=Array.prototype.slice;
-var functionsHaveNames=function(){
-return function foo(){}.name==='foo';
-}();
-function pToString(obj){
-return Object.prototype.toString.call(obj);
-}
-function isView(arrbuf){
-if(isBuffer(arrbuf)){
-return false;
-}
-if(typeof global.ArrayBuffer!=='function'){
-return false;
-}
-if(typeof ArrayBuffer.isView==='function'){
-return ArrayBuffer.isView(arrbuf);
-}
-if(!arrbuf){
-return false;
-}
-if(arrbuf instanceof DataView){
-return true;
-}
-if(arrbuf.buffer&&arrbuf.buffer instanceof ArrayBuffer){
-return true;
-}
-return false;
-}
-
-
-
-
-var assert=module.exports=ok;
-
-
-
-
-
-
-var regex=/\s*function\s+([^\(\s]*)\s*/;
-
-function getName(func){
-if(!util.isFunction(func)){
-return;
-}
-if(functionsHaveNames){
-return func.name;
-}
-var str=func.toString();
-var match=str.match(regex);
-return match&&match[1];
-}
-assert.AssertionError=function AssertionError(options){
-this.name='AssertionError';
-this.actual=options.actual;
-this.expected=options.expected;
-this.operator=options.operator;
-if(options.message){
-this.message=options.message;
-this.generatedMessage=false;
-}else{
-this.message=getMessage(this);
-this.generatedMessage=true;
-}
-var stackStartFunction=options.stackStartFunction||fail;
-if(Error.captureStackTrace){
-Error.captureStackTrace(this,stackStartFunction);
-}else{
-
-var err=new Error();
-if(err.stack){
-var out=err.stack;
-
-
-var fn_name=getName(stackStartFunction);
-var idx=out.indexOf('\n'+fn_name);
-if(idx>=0){
-
-
-var next_line=out.indexOf('\n',idx+1);
-out=out.substring(next_line+1);
-}
-
-this.stack=out;
-}
-}
-};
-
-
-util.inherits(assert.AssertionError,Error);
-
-function truncate(s,n){
-if(typeof s==='string'){
-return s.length<n?s:s.slice(0,n);
-}else{
-return s;
-}
-}
-function inspect(something){
-if(functionsHaveNames||!util.isFunction(something)){
-return util.inspect(something);
-}
-var rawname=getName(something);
-var name=rawname?': '+rawname:'';
-return'[Function'+name+']';
-}
-function getMessage(self){
-return truncate(inspect(self.actual),128)+' '+
-self.operator+' '+
-truncate(inspect(self.expected),128);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-function fail(actual,expected,message,operator,stackStartFunction){
-throw new assert.AssertionError({
-message:message,
-actual:actual,
-expected:expected,
-operator:operator,
-stackStartFunction:stackStartFunction});
-
-}
-
-
-assert.fail=fail;
-
-
-
-
-
-
-
-
-function ok(value,message){
-if(!value)fail(value,true,message,'==',assert.ok);
-}
-assert.ok=ok;
-
-
-
-
-
-assert.equal=function equal(actual,expected,message){
-if(actual!=expected)fail(actual,expected,message,'==',assert.equal);
-};
-
-
-
-
-assert.notEqual=function notEqual(actual,expected,message){
-if(actual==expected){
-fail(actual,expected,message,'!=',assert.notEqual);
-}
-};
-
-
-
-
-assert.deepEqual=function deepEqual(actual,expected,message){
-if(!_deepEqual(actual,expected,false)){
-fail(actual,expected,message,'deepEqual',assert.deepEqual);
-}
-};
-
-assert.deepStrictEqual=function deepStrictEqual(actual,expected,message){
-if(!_deepEqual(actual,expected,true)){
-fail(actual,expected,message,'deepStrictEqual',assert.deepStrictEqual);
-}
-};
-
-function _deepEqual(actual,expected,strict,memos){
-
-if(actual===expected){
-return true;
-}else if(isBuffer(actual)&&isBuffer(expected)){
-return compare(actual,expected)===0;
-
-
-
-}else if(util.isDate(actual)&&util.isDate(expected)){
-return actual.getTime()===expected.getTime();
-
-
-
-
-}else if(util.isRegExp(actual)&&util.isRegExp(expected)){
-return actual.source===expected.source&&
-actual.global===expected.global&&
-actual.multiline===expected.multiline&&
-actual.lastIndex===expected.lastIndex&&
-actual.ignoreCase===expected.ignoreCase;
-
-
-
-}else if((actual===null||typeof actual!=='object')&&(
-expected===null||typeof expected!=='object')){
-return strict?actual===expected:actual==expected;
-
-
-
-
-
-
-
-}else if(isView(actual)&&isView(expected)&&
-pToString(actual)===pToString(expected)&&
-!(actual instanceof Float32Array||
-actual instanceof Float64Array)){
-return compare(new Uint8Array(actual.buffer),
-new Uint8Array(expected.buffer))===0;
-
-
-
-
-
-
-
-}else if(isBuffer(actual)!==isBuffer(expected)){
-return false;
-}else{
-memos=memos||{actual:[],expected:[]};
-
-var actualIndex=memos.actual.indexOf(actual);
-if(actualIndex!==-1){
-if(actualIndex===memos.expected.indexOf(expected)){
-return true;
-}
-}
-
-memos.actual.push(actual);
-memos.expected.push(expected);
-
-return objEquiv(actual,expected,strict,memos);
-}
-}
-
-function isArguments(object){
-return Object.prototype.toString.call(object)=='[object Arguments]';
-}
-
-function objEquiv(a,b,strict,actualVisitedObjects){
-if(a===null||a===undefined||b===null||b===undefined)
-return false;
-
-if(util.isPrimitive(a)||util.isPrimitive(b))
-return a===b;
-if(strict&&Object.getPrototypeOf(a)!==Object.getPrototypeOf(b))
-return false;
-var aIsArgs=isArguments(a);
-var bIsArgs=isArguments(b);
-if(aIsArgs&&!bIsArgs||!aIsArgs&&bIsArgs)
-return false;
-if(aIsArgs){
-a=pSlice.call(a);
-b=pSlice.call(b);
-return _deepEqual(a,b,strict);
-}
-var ka=objectKeys(a);
-var kb=objectKeys(b);
-var key,i;
-
-
-if(ka.length!==kb.length)
-return false;
-
-ka.sort();
-kb.sort();
-
-for(i=ka.length-1;i>=0;i--){
-if(ka[i]!==kb[i])
-return false;
-}
-
-
-for(i=ka.length-1;i>=0;i--){
-key=ka[i];
-if(!_deepEqual(a[key],b[key],strict,actualVisitedObjects))
-return false;
-}
-return true;
-}
-
-
-
-
-assert.notDeepEqual=function notDeepEqual(actual,expected,message){
-if(_deepEqual(actual,expected,false)){
-fail(actual,expected,message,'notDeepEqual',assert.notDeepEqual);
-}
-};
-
-assert.notDeepStrictEqual=notDeepStrictEqual;
-function notDeepStrictEqual(actual,expected,message){
-if(_deepEqual(actual,expected,true)){
-fail(actual,expected,message,'notDeepStrictEqual',notDeepStrictEqual);
-}
-}
-
-
-
-
-
-assert.strictEqual=function strictEqual(actual,expected,message){
-if(actual!==expected){
-fail(actual,expected,message,'===',assert.strictEqual);
-}
-};
-
-
-
-
-assert.notStrictEqual=function notStrictEqual(actual,expected,message){
-if(actual===expected){
-fail(actual,expected,message,'!==',assert.notStrictEqual);
-}
-};
-
-function expectedException(actual,expected){
-if(!actual||!expected){
-return false;
-}
-
-if(Object.prototype.toString.call(expected)=='[object RegExp]'){
-return expected.test(actual);
-}
-
-try{
-if(actual instanceof expected){
-return true;
-}
-}catch(e){
-
-}
-
-if(Error.isPrototypeOf(expected)){
-return false;
-}
-
-return expected.call({},actual)===true;
-}
-
-function _tryBlock(block){
-var error;
-try{
-block();
-}catch(e){
-error=e;
-}
-return error;
-}
-
-function _throws(shouldThrow,block,expected,message){
-var actual;
-
-if(typeof block!=='function'){
-throw new TypeError('"block" argument must be a function');
-}
-
-if(typeof expected==='string'){
-message=expected;
-expected=null;
-}
-
-actual=_tryBlock(block);
-
-message=(expected&&expected.name?' ('+expected.name+').':'.')+(
-message?' '+message:'.');
-
-if(shouldThrow&&!actual){
-fail(actual,expected,'Missing expected exception'+message);
-}
-
-var userProvidedMessage=typeof message==='string';
-var isUnwantedException=!shouldThrow&&util.isError(actual);
-var isUnexpectedException=!shouldThrow&&actual&&!expected;
-
-if(isUnwantedException&&
-userProvidedMessage&&
-expectedException(actual,expected)||
-isUnexpectedException){
-fail(actual,expected,'Got unwanted exception'+message);
-}
-
-if(shouldThrow&&actual&&expected&&
-!expectedException(actual,expected)||!shouldThrow&&actual){
-throw actual;
-}
-}
-
-
-
-
-assert.throws=function(block,error,message){
-_throws(true,block,error,message);
-};
-
-
-assert.doesNotThrow=function(block,error,message){
-_throws(false,block,error,message);
-};
-
-assert.ifError=function(err){if(err)throw err;};
-
-var objectKeys=Object.keys||function(obj){
-var keys=[];
-for(var key in obj){
-if(hasOwn.call(obj,key))keys.push(key);
-}
-return keys;
-};
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"util/":91}],48:[function(require,module,exports){
-'use strict';
-
-exports.byteLength=byteLength;
-exports.toByteArray=toByteArray;
-exports.fromByteArray=fromByteArray;
-
-var lookup=[];
-var revLookup=[];
-var Arr=typeof Uint8Array!=='undefined'?Uint8Array:Array;
-
-var code='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-for(var i=0,len=code.length;i<len;++i){
-lookup[i]=code[i];
-revLookup[code.charCodeAt(i)]=i;
-}
-
-revLookup['-'.charCodeAt(0)]=62;
-revLookup['_'.charCodeAt(0)]=63;
-
-function placeHoldersCount(b64){
-var len=b64.length;
-if(len%4>0){
-throw new Error('Invalid string. Length must be a multiple of 4');
-}
-
-
-
-
-
-
-return b64[len-2]==='='?2:b64[len-1]==='='?1:0;
-}
-
-function byteLength(b64){
-
-return b64.length*3/4-placeHoldersCount(b64);
-}
-
-function toByteArray(b64){
-var i,j,l,tmp,placeHolders,arr;
-var len=b64.length;
-placeHolders=placeHoldersCount(b64);
-
-arr=new Arr(len*3/4-placeHolders);
-
-
-l=placeHolders>0?len-4:len;
-
-var L=0;
-
-for(i=0,j=0;i<l;i+=4,j+=3){
-tmp=revLookup[b64.charCodeAt(i)]<<18|revLookup[b64.charCodeAt(i+1)]<<12|revLookup[b64.charCodeAt(i+2)]<<6|revLookup[b64.charCodeAt(i+3)];
-arr[L++]=tmp>>16&0xFF;
-arr[L++]=tmp>>8&0xFF;
-arr[L++]=tmp&0xFF;
-}
-
-if(placeHolders===2){
-tmp=revLookup[b64.charCodeAt(i)]<<2|revLookup[b64.charCodeAt(i+1)]>>4;
-arr[L++]=tmp&0xFF;
-}else if(placeHolders===1){
-tmp=revLookup[b64.charCodeAt(i)]<<10|revLookup[b64.charCodeAt(i+1)]<<4|revLookup[b64.charCodeAt(i+2)]>>2;
-arr[L++]=tmp>>8&0xFF;
-arr[L++]=tmp&0xFF;
-}
-
-return arr;
-}
-
-function tripletToBase64(num){
-return lookup[num>>18&0x3F]+lookup[num>>12&0x3F]+lookup[num>>6&0x3F]+lookup[num&0x3F];
-}
-
-function encodeChunk(uint8,start,end){
-var tmp;
-var output=[];
-for(var i=start;i<end;i+=3){
-tmp=(uint8[i]<<16)+(uint8[i+1]<<8)+uint8[i+2];
-output.push(tripletToBase64(tmp));
-}
-return output.join('');
-}
-
-function fromByteArray(uint8){
-var tmp;
-var len=uint8.length;
-var extraBytes=len%3;
-var output='';
-var parts=[];
-var maxChunkLength=16383;
-
-
-for(var i=0,len2=len-extraBytes;i<len2;i+=maxChunkLength){
-parts.push(encodeChunk(uint8,i,i+maxChunkLength>len2?len2:i+maxChunkLength));
-}
-
-
-if(extraBytes===1){
-tmp=uint8[len-1];
-output+=lookup[tmp>>2];
-output+=lookup[tmp<<4&0x3F];
-output+='==';
-}else if(extraBytes===2){
-tmp=(uint8[len-2]<<8)+uint8[len-1];
-output+=lookup[tmp>>10];
-output+=lookup[tmp>>4&0x3F];
-output+=lookup[tmp<<2&0x3F];
-output+='=';
-}
-
-parts.push(output);
-
-return parts.join('');
-}
-
-},{}],49:[function(require,module,exports){
-
-},{}],50:[function(require,module,exports){
-(function(process,Buffer){
-var msg=require('pako/lib/zlib/messages');
-var zstream=require('pako/lib/zlib/zstream');
-var zlib_deflate=require('pako/lib/zlib/deflate.js');
-var zlib_inflate=require('pako/lib/zlib/inflate.js');
-var constants=require('pako/lib/zlib/constants');
-
-for(var key in constants){
-exports[key]=constants[key];
-}
-
-
-exports.NONE=0;
-exports.DEFLATE=1;
-exports.INFLATE=2;
-exports.GZIP=3;
-exports.GUNZIP=4;
-exports.DEFLATERAW=5;
-exports.INFLATERAW=6;
-exports.UNZIP=7;
-
-
-
-
-function Zlib(mode){
-if(mode<exports.DEFLATE||mode>exports.UNZIP)
-throw new TypeError("Bad argument");
-
-this.mode=mode;
-this.init_done=false;
-this.write_in_progress=false;
-this.pending_close=false;
-this.windowBits=0;
-this.level=0;
-this.memLevel=0;
-this.strategy=0;
-this.dictionary=null;
-}
-
-Zlib.prototype.init=function(windowBits,level,memLevel,strategy,dictionary){
-this.windowBits=windowBits;
-this.level=level;
-this.memLevel=memLevel;
-this.strategy=strategy;
-
-
-if(this.mode===exports.GZIP||this.mode===exports.GUNZIP)
-this.windowBits+=16;
-
-if(this.mode===exports.UNZIP)
-this.windowBits+=32;
-
-if(this.mode===exports.DEFLATERAW||this.mode===exports.INFLATERAW)
-this.windowBits=-this.windowBits;
-
-this.strm=new zstream();
-
-switch(this.mode){
-case exports.DEFLATE:
-case exports.GZIP:
-case exports.DEFLATERAW:
-var status=zlib_deflate.deflateInit2(
-this.strm,
-this.level,
-exports.Z_DEFLATED,
-this.windowBits,
-this.memLevel,
-this.strategy);
-
-break;
-case exports.INFLATE:
-case exports.GUNZIP:
-case exports.INFLATERAW:
-case exports.UNZIP:
-var status=zlib_inflate.inflateInit2(
-this.strm,
-this.windowBits);
-
-break;
-default:
-throw new Error("Unknown mode "+this.mode);}
-
-
-if(status!==exports.Z_OK){
-this._error(status);
-return;
-}
-
-this.write_in_progress=false;
-this.init_done=true;
-};
-
-Zlib.prototype.params=function(){
-throw new Error("deflateParams Not supported");
-};
-
-Zlib.prototype._writeCheck=function(){
-if(!this.init_done)
-throw new Error("write before init");
-
-if(this.mode===exports.NONE)
-throw new Error("already finalized");
-
-if(this.write_in_progress)
-throw new Error("write already in progress");
-
-if(this.pending_close)
-throw new Error("close is pending");
-};
-
-Zlib.prototype.write=function(flush,input,in_off,in_len,out,out_off,out_len){
-this._writeCheck();
-this.write_in_progress=true;
-
-var self=this;
-process.nextTick(function(){
-self.write_in_progress=false;
-var res=self._write(flush,input,in_off,in_len,out,out_off,out_len);
-self.callback(res[0],res[1]);
-
-if(self.pending_close)
-self.close();
-});
-
-return this;
-};
-
-
-function bufferSet(data,offset){
-for(var i=0;i<data.length;i++){
-this[offset+i]=data[i];
-}
-}
-
-Zlib.prototype.writeSync=function(flush,input,in_off,in_len,out,out_off,out_len){
-this._writeCheck();
-return this._write(flush,input,in_off,in_len,out,out_off,out_len);
-};
-
-Zlib.prototype._write=function(flush,input,in_off,in_len,out,out_off,out_len){
-this.write_in_progress=true;
-
-if(flush!==exports.Z_NO_FLUSH&&
-flush!==exports.Z_PARTIAL_FLUSH&&
-flush!==exports.Z_SYNC_FLUSH&&
-flush!==exports.Z_FULL_FLUSH&&
-flush!==exports.Z_FINISH&&
-flush!==exports.Z_BLOCK){
-throw new Error("Invalid flush value");
-}
-
-if(input==null){
-input=new Buffer(0);
-in_len=0;
-in_off=0;
-}
-
-if(out._set)
-out.set=out._set;else
-
-out.set=bufferSet;
-
-var strm=this.strm;
-strm.avail_in=in_len;
-strm.input=input;
-strm.next_in=in_off;
-strm.avail_out=out_len;
-strm.output=out;
-strm.next_out=out_off;
-
-switch(this.mode){
-case exports.DEFLATE:
-case exports.GZIP:
-case exports.DEFLATERAW:
-var status=zlib_deflate.deflate(strm,flush);
-break;
-case exports.UNZIP:
-case exports.INFLATE:
-case exports.GUNZIP:
-case exports.INFLATERAW:
-var status=zlib_inflate.inflate(strm,flush);
-break;
-default:
-throw new Error("Unknown mode "+this.mode);}
-
-
-if(status!==exports.Z_STREAM_END&&status!==exports.Z_OK){
-this._error(status);
-}
-
-this.write_in_progress=false;
-return[strm.avail_in,strm.avail_out];
-};
-
-Zlib.prototype.close=function(){
-if(this.write_in_progress){
-this.pending_close=true;
-return;
-}
-
-this.pending_close=false;
-
-if(this.mode===exports.DEFLATE||this.mode===exports.GZIP||this.mode===exports.DEFLATERAW){
-zlib_deflate.deflateEnd(this.strm);
-}else{
-zlib_inflate.inflateEnd(this.strm);
-}
-
-this.mode=exports.NONE;
-};
-
-Zlib.prototype.reset=function(){
-switch(this.mode){
-case exports.DEFLATE:
-case exports.DEFLATERAW:
-var status=zlib_deflate.deflateReset(this.strm);
-break;
-case exports.INFLATE:
-case exports.INFLATERAW:
-var status=zlib_inflate.inflateReset(this.strm);
-break;}
-
-
-if(status!==exports.Z_OK){
-this._error(status);
-}
-};
-
-Zlib.prototype._error=function(status){
-this.onerror(msg[status]+': '+this.strm.msg,status);
-
-this.write_in_progress=false;
-if(this.pending_close)
-this.close();
-};
-
-exports.Zlib=Zlib;
-
-}).call(this,require('_process'),require("buffer").Buffer);
-},{"_process":71,"buffer":54,"pako/lib/zlib/constants":63,"pako/lib/zlib/deflate.js":65,"pako/lib/zlib/inflate.js":52,"pako/lib/zlib/messages":66,"pako/lib/zlib/zstream":68}],51:[function(require,module,exports){
-(function(process,Buffer){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var Transform=require('_stream_transform');
-
-var binding=require('./binding');
-var util=require('util');
-var assert=require('assert').ok;
-
-
-
-binding.Z_MIN_WINDOWBITS=8;
-binding.Z_MAX_WINDOWBITS=15;
-binding.Z_DEFAULT_WINDOWBITS=15;
-
-
-
-
-binding.Z_MIN_CHUNK=64;
-binding.Z_MAX_CHUNK=Infinity;
-binding.Z_DEFAULT_CHUNK=16*1024;
-
-binding.Z_MIN_MEMLEVEL=1;
-binding.Z_MAX_MEMLEVEL=9;
-binding.Z_DEFAULT_MEMLEVEL=8;
-
-binding.Z_MIN_LEVEL=-1;
-binding.Z_MAX_LEVEL=9;
-binding.Z_DEFAULT_LEVEL=binding.Z_DEFAULT_COMPRESSION;
-
-
-Object.keys(binding).forEach(function(k){
-if(k.match(/^Z/))exports[k]=binding[k];
-});
-
-
-exports.codes={
-Z_OK:binding.Z_OK,
-Z_STREAM_END:binding.Z_STREAM_END,
-Z_NEED_DICT:binding.Z_NEED_DICT,
-Z_ERRNO:binding.Z_ERRNO,
-Z_STREAM_ERROR:binding.Z_STREAM_ERROR,
-Z_DATA_ERROR:binding.Z_DATA_ERROR,
-Z_MEM_ERROR:binding.Z_MEM_ERROR,
-Z_BUF_ERROR:binding.Z_BUF_ERROR,
-Z_VERSION_ERROR:binding.Z_VERSION_ERROR};
-
-
-Object.keys(exports.codes).forEach(function(k){
-exports.codes[exports.codes[k]]=k;
-});
-
-exports.Deflate=Deflate;
-exports.Inflate=Inflate;
-exports.Gzip=Gzip;
-exports.Gunzip=Gunzip;
-exports.DeflateRaw=DeflateRaw;
-exports.InflateRaw=InflateRaw;
-exports.Unzip=Unzip;
-
-exports.createDeflate=function(o){
-return new Deflate(o);
-};
-
-exports.createInflate=function(o){
-return new Inflate(o);
-};
-
-exports.createDeflateRaw=function(o){
-return new DeflateRaw(o);
-};
-
-exports.createInflateRaw=function(o){
-return new InflateRaw(o);
-};
-
-exports.createGzip=function(o){
-return new Gzip(o);
-};
-
-exports.createGunzip=function(o){
-return new Gunzip(o);
-};
-
-exports.createUnzip=function(o){
-return new Unzip(o);
-};
-
-
-
-
-exports.deflate=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new Deflate(opts),buffer,callback);
-};
-
-exports.deflateSync=function(buffer,opts){
-return zlibBufferSync(new Deflate(opts),buffer);
-};
-
-exports.gzip=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new Gzip(opts),buffer,callback);
-};
-
-exports.gzipSync=function(buffer,opts){
-return zlibBufferSync(new Gzip(opts),buffer);
-};
-
-exports.deflateRaw=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new DeflateRaw(opts),buffer,callback);
-};
-
-exports.deflateRawSync=function(buffer,opts){
-return zlibBufferSync(new DeflateRaw(opts),buffer);
-};
-
-exports.unzip=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new Unzip(opts),buffer,callback);
-};
-
-exports.unzipSync=function(buffer,opts){
-return zlibBufferSync(new Unzip(opts),buffer);
-};
-
-exports.inflate=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new Inflate(opts),buffer,callback);
-};
-
-exports.inflateSync=function(buffer,opts){
-return zlibBufferSync(new Inflate(opts),buffer);
-};
-
-exports.gunzip=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new Gunzip(opts),buffer,callback);
-};
-
-exports.gunzipSync=function(buffer,opts){
-return zlibBufferSync(new Gunzip(opts),buffer);
-};
-
-exports.inflateRaw=function(buffer,opts,callback){
-if(typeof opts==='function'){
-callback=opts;
-opts={};
-}
-return zlibBuffer(new InflateRaw(opts),buffer,callback);
-};
-
-exports.inflateRawSync=function(buffer,opts){
-return zlibBufferSync(new InflateRaw(opts),buffer);
-};
-
-function zlibBuffer(engine,buffer,callback){
-var buffers=[];
-var nread=0;
-
-engine.on('error',onError);
-engine.on('end',onEnd);
-
-engine.end(buffer);
-flow();
-
-function flow(){
-var chunk;
-while(null!==(chunk=engine.read())){
-buffers.push(chunk);
-nread+=chunk.length;
-}
-engine.once('readable',flow);
-}
-
-function onError(err){
-engine.removeListener('end',onEnd);
-engine.removeListener('readable',flow);
-callback(err);
-}
-
-function onEnd(){
-var buf=Buffer.concat(buffers,nread);
-buffers=[];
-callback(null,buf);
-engine.close();
-}
-}
-
-function zlibBufferSync(engine,buffer){
-if(typeof buffer==='string')
-buffer=new Buffer(buffer);
-if(!Buffer.isBuffer(buffer))
-throw new TypeError('Not a string or buffer');
-
-var flushFlag=binding.Z_FINISH;
-
-return engine._processChunk(buffer,flushFlag);
-}
-
-
-
-function Deflate(opts){
-if(!(this instanceof Deflate))return new Deflate(opts);
-Zlib.call(this,opts,binding.DEFLATE);
-}
-
-function Inflate(opts){
-if(!(this instanceof Inflate))return new Inflate(opts);
-Zlib.call(this,opts,binding.INFLATE);
-}
-
-
-
-
-function Gzip(opts){
-if(!(this instanceof Gzip))return new Gzip(opts);
-Zlib.call(this,opts,binding.GZIP);
-}
-
-function Gunzip(opts){
-if(!(this instanceof Gunzip))return new Gunzip(opts);
-Zlib.call(this,opts,binding.GUNZIP);
-}
-
-
-
-
-function DeflateRaw(opts){
-if(!(this instanceof DeflateRaw))return new DeflateRaw(opts);
-Zlib.call(this,opts,binding.DEFLATERAW);
-}
-
-function InflateRaw(opts){
-if(!(this instanceof InflateRaw))return new InflateRaw(opts);
-Zlib.call(this,opts,binding.INFLATERAW);
-}
-
-
-
-function Unzip(opts){
-if(!(this instanceof Unzip))return new Unzip(opts);
-Zlib.call(this,opts,binding.UNZIP);
-}
-
-
-
-
-
-
-
-function Zlib(opts,mode){
-this._opts=opts=opts||{};
-this._chunkSize=opts.chunkSize||exports.Z_DEFAULT_CHUNK;
-
-Transform.call(this,opts);
-
-if(opts.flush){
-if(opts.flush!==binding.Z_NO_FLUSH&&
-opts.flush!==binding.Z_PARTIAL_FLUSH&&
-opts.flush!==binding.Z_SYNC_FLUSH&&
-opts.flush!==binding.Z_FULL_FLUSH&&
-opts.flush!==binding.Z_FINISH&&
-opts.flush!==binding.Z_BLOCK){
-throw new Error('Invalid flush flag: '+opts.flush);
-}
-}
-this._flushFlag=opts.flush||binding.Z_NO_FLUSH;
-
-if(opts.chunkSize){
-if(opts.chunkSize<exports.Z_MIN_CHUNK||
-opts.chunkSize>exports.Z_MAX_CHUNK){
-throw new Error('Invalid chunk size: '+opts.chunkSize);
-}
-}
-
-if(opts.windowBits){
-if(opts.windowBits<exports.Z_MIN_WINDOWBITS||
-opts.windowBits>exports.Z_MAX_WINDOWBITS){
-throw new Error('Invalid windowBits: '+opts.windowBits);
-}
-}
-
-if(opts.level){
-if(opts.level<exports.Z_MIN_LEVEL||
-opts.level>exports.Z_MAX_LEVEL){
-throw new Error('Invalid compression level: '+opts.level);
-}
-}
-
-if(opts.memLevel){
-if(opts.memLevel<exports.Z_MIN_MEMLEVEL||
-opts.memLevel>exports.Z_MAX_MEMLEVEL){
-throw new Error('Invalid memLevel: '+opts.memLevel);
-}
-}
-
-if(opts.strategy){
-if(opts.strategy!=exports.Z_FILTERED&&
-opts.strategy!=exports.Z_HUFFMAN_ONLY&&
-opts.strategy!=exports.Z_RLE&&
-opts.strategy!=exports.Z_FIXED&&
-opts.strategy!=exports.Z_DEFAULT_STRATEGY){
-throw new Error('Invalid strategy: '+opts.strategy);
-}
-}
-
-if(opts.dictionary){
-if(!Buffer.isBuffer(opts.dictionary)){
-throw new Error('Invalid dictionary: it should be a Buffer instance');
-}
-}
-
-this._binding=new binding.Zlib(mode);
-
-var self=this;
-this._hadError=false;
-this._binding.onerror=function(message,errno){
-
-
-self._binding=null;
-self._hadError=true;
-
-var error=new Error(message);
-error.errno=errno;
-error.code=exports.codes[errno];
-self.emit('error',error);
-};
-
-var level=exports.Z_DEFAULT_COMPRESSION;
-if(typeof opts.level==='number')level=opts.level;
-
-var strategy=exports.Z_DEFAULT_STRATEGY;
-if(typeof opts.strategy==='number')strategy=opts.strategy;
-
-this._binding.init(opts.windowBits||exports.Z_DEFAULT_WINDOWBITS,
-level,
-opts.memLevel||exports.Z_DEFAULT_MEMLEVEL,
-strategy,
-opts.dictionary);
-
-this._buffer=new Buffer(this._chunkSize);
-this._offset=0;
-this._closed=false;
-this._level=level;
-this._strategy=strategy;
-
-this.once('end',this.close);
-}
-
-util.inherits(Zlib,Transform);
-
-Zlib.prototype.params=function(level,strategy,callback){
-if(level<exports.Z_MIN_LEVEL||
-level>exports.Z_MAX_LEVEL){
-throw new RangeError('Invalid compression level: '+level);
-}
-if(strategy!=exports.Z_FILTERED&&
-strategy!=exports.Z_HUFFMAN_ONLY&&
-strategy!=exports.Z_RLE&&
-strategy!=exports.Z_FIXED&&
-strategy!=exports.Z_DEFAULT_STRATEGY){
-throw new TypeError('Invalid strategy: '+strategy);
-}
-
-if(this._level!==level||this._strategy!==strategy){
-var self=this;
-this.flush(binding.Z_SYNC_FLUSH,function(){
-self._binding.params(level,strategy);
-if(!self._hadError){
-self._level=level;
-self._strategy=strategy;
-if(callback)callback();
-}
-});
-}else{
-process.nextTick(callback);
-}
-};
-
-Zlib.prototype.reset=function(){
-return this._binding.reset();
-};
-
-
-
-Zlib.prototype._flush=function(callback){
-this._transform(new Buffer(0),'',callback);
-};
-
-Zlib.prototype.flush=function(kind,callback){
-var ws=this._writableState;
-
-if(typeof kind==='function'||kind===void 0&&!callback){
-callback=kind;
-kind=binding.Z_FULL_FLUSH;
-}
-
-if(ws.ended){
-if(callback)
-process.nextTick(callback);
-}else if(ws.ending){
-if(callback)
-this.once('end',callback);
-}else if(ws.needDrain){
-var self=this;
-this.once('drain',function(){
-self.flush(callback);
-});
-}else{
-this._flushFlag=kind;
-this.write(new Buffer(0),'',callback);
-}
-};
-
-Zlib.prototype.close=function(callback){
-if(callback)
-process.nextTick(callback);
-
-if(this._closed)
-return;
-
-this._closed=true;
-
-this._binding.close();
-
-var self=this;
-process.nextTick(function(){
-self.emit('close');
-});
-};
-
-Zlib.prototype._transform=function(chunk,encoding,cb){
-var flushFlag;
-var ws=this._writableState;
-var ending=ws.ending||ws.ended;
-var last=ending&&(!chunk||ws.length===chunk.length);
-
-if(!chunk===null&&!Buffer.isBuffer(chunk))
-return cb(new Error('invalid input'));
-
-
-
-
-
-if(last)
-flushFlag=binding.Z_FINISH;else
-{
-flushFlag=this._flushFlag;
-
-
-if(chunk.length>=ws.length){
-this._flushFlag=this._opts.flush||binding.Z_NO_FLUSH;
-}
-}
-
-var self=this;
-this._processChunk(chunk,flushFlag,cb);
-};
-
-Zlib.prototype._processChunk=function(chunk,flushFlag,cb){
-var availInBefore=chunk&&chunk.length;
-var availOutBefore=this._chunkSize-this._offset;
-var inOff=0;
-
-var self=this;
-
-var async=typeof cb==='function';
-
-if(!async){
-var buffers=[];
-var nread=0;
-
-var error;
-this.on('error',function(er){
-error=er;
-});
-
-do{
-var res=this._binding.writeSync(flushFlag,
-chunk,
-inOff,
-availInBefore,
-this._buffer,
-this._offset,
-availOutBefore);
-}while(!this._hadError&&callback(res[0],res[1]));
-
-if(this._hadError){
-throw error;
-}
-
-var buf=Buffer.concat(buffers,nread);
-this.close();
-
-return buf;
-}
-
-var req=this._binding.write(flushFlag,
-chunk,
-inOff,
-availInBefore,
-this._buffer,
-this._offset,
-availOutBefore);
-
-req.buffer=chunk;
-req.callback=callback;
-
-function callback(availInAfter,availOutAfter){
-if(self._hadError)
-return;
-
-var have=availOutBefore-availOutAfter;
-assert(have>=0,'have should not go down');
-
-if(have>0){
-var out=self._buffer.slice(self._offset,self._offset+have);
-self._offset+=have;
-
-if(async){
-self.push(out);
-}else{
-buffers.push(out);
-nread+=out.length;
-}
-}
-
-
-if(availOutAfter===0||self._offset>=self._chunkSize){
-availOutBefore=self._chunkSize;
-self._offset=0;
-self._buffer=new Buffer(self._chunkSize);
-}
-
-if(availOutAfter===0){
-
-
-
-
-inOff+=availInBefore-availInAfter;
-availInBefore=availInAfter;
-
-if(!async)
-return true;
-
-var newReq=self._binding.write(flushFlag,
-chunk,
-inOff,
-availInBefore,
-self._buffer,
-self._offset,
-self._chunkSize);
-newReq.callback=callback;
-newReq.buffer=chunk;
-return;
-}
-
-if(!async)
-return false;
-
-
-cb();
-}
-};
-
-util.inherits(Deflate,Zlib);
-util.inherits(Inflate,Zlib);
-util.inherits(Gzip,Zlib);
-util.inherits(Gunzip,Zlib);
-util.inherits(DeflateRaw,Zlib);
-util.inherits(InflateRaw,Zlib);
-util.inherits(Unzip,Zlib);
-
-}).call(this,require('_process'),require("buffer").Buffer);
-},{"./binding":50,"_process":71,"_stream_transform":84,"assert":47,"buffer":54,"util":91}],52:[function(require,module,exports){
-arguments[4][49][0].apply(exports,arguments);
-},{"dup":49}],53:[function(require,module,exports){
-(function(global){
-'use strict';
-
-var buffer=require('buffer');
-var Buffer=buffer.Buffer;
-var SlowBuffer=buffer.SlowBuffer;
-var MAX_LEN=buffer.kMaxLength||2147483647;
-exports.alloc=function alloc(size,fill,encoding){
-if(typeof Buffer.alloc==='function'){
-return Buffer.alloc(size,fill,encoding);
-}
-if(typeof encoding==='number'){
-throw new TypeError('encoding must not be number');
-}
-if(typeof size!=='number'){
-throw new TypeError('size must be a number');
-}
-if(size>MAX_LEN){
-throw new RangeError('size is too large');
-}
-var enc=encoding;
-var _fill=fill;
-if(_fill===undefined){
-enc=undefined;
-_fill=0;
-}
-var buf=new Buffer(size);
-if(typeof _fill==='string'){
-var fillBuf=new Buffer(_fill,enc);
-var flen=fillBuf.length;
-var i=-1;
-while(++i<size){
-buf[i]=fillBuf[i%flen];
-}
-}else{
-buf.fill(_fill);
-}
-return buf;
-};
-exports.allocUnsafe=function allocUnsafe(size){
-if(typeof Buffer.allocUnsafe==='function'){
-return Buffer.allocUnsafe(size);
-}
-if(typeof size!=='number'){
-throw new TypeError('size must be a number');
-}
-if(size>MAX_LEN){
-throw new RangeError('size is too large');
-}
-return new Buffer(size);
-};
-exports.from=function from(value,encodingOrOffset,length){
-if(typeof Buffer.from==='function'&&(!global.Uint8Array||Uint8Array.from!==Buffer.from)){
-return Buffer.from(value,encodingOrOffset,length);
-}
-if(typeof value==='number'){
-throw new TypeError('"value" argument must not be a number');
-}
-if(typeof value==='string'){
-return new Buffer(value,encodingOrOffset);
-}
-if(typeof ArrayBuffer!=='undefined'&&value instanceof ArrayBuffer){
-var offset=encodingOrOffset;
-if(arguments.length===1){
-return new Buffer(value);
-}
-if(typeof offset==='undefined'){
-offset=0;
-}
-var len=length;
-if(typeof len==='undefined'){
-len=value.byteLength-offset;
-}
-if(offset>=value.byteLength){
-throw new RangeError('\'offset\' is out of bounds');
-}
-if(len>value.byteLength-offset){
-throw new RangeError('\'length\' is out of bounds');
-}
-return new Buffer(value.slice(offset,offset+len));
-}
-if(Buffer.isBuffer(value)){
-var out=new Buffer(value.length);
-value.copy(out,0,0,value.length);
-return out;
-}
-if(value){
-if(Array.isArray(value)||typeof ArrayBuffer!=='undefined'&&value.buffer instanceof ArrayBuffer||'length'in value){
-return new Buffer(value);
-}
-if(value.type==='Buffer'&&Array.isArray(value.data)){
-return new Buffer(value.data);
-}
-}
-
-throw new TypeError('First argument must be a string, Buffer, '+'ArrayBuffer, Array, or array-like object.');
-};
-exports.allocUnsafeSlow=function allocUnsafeSlow(size){
-if(typeof Buffer.allocUnsafeSlow==='function'){
-return Buffer.allocUnsafeSlow(size);
-}
-if(typeof size!=='number'){
-throw new TypeError('size must be a number');
-}
-if(size>=MAX_LEN){
-throw new RangeError('size is too large');
-}
-return new SlowBuffer(size);
-};
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"buffer":54}],54:[function(require,module,exports){
-(function(global){
-
-
-
-
-
-
-
-
-'use strict';
-
-var base64=require('base64-js');
-var ieee754=require('ieee754');
-var isArray=require('isarray');
-
-exports.Buffer=Buffer;
-exports.SlowBuffer=SlowBuffer;
-exports.INSPECT_MAX_BYTES=50;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Buffer.TYPED_ARRAY_SUPPORT=global.TYPED_ARRAY_SUPPORT!==undefined?
-global.TYPED_ARRAY_SUPPORT:
-typedArraySupport();
-
-
-
-
-exports.kMaxLength=kMaxLength();
-
-function typedArraySupport(){
-try{
-var arr=new Uint8Array(1);
-arr.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42;}};
-return arr.foo()===42&&
-typeof arr.subarray==='function'&&
-arr.subarray(1,1).byteLength===0;
-}catch(e){
-return false;
-}
-}
-
-function kMaxLength(){
-return Buffer.TYPED_ARRAY_SUPPORT?
-0x7fffffff:
-0x3fffffff;
-}
-
-function createBuffer(that,length){
-if(kMaxLength()<length){
-throw new RangeError('Invalid typed array length');
-}
-if(Buffer.TYPED_ARRAY_SUPPORT){
-
-that=new Uint8Array(length);
-that.__proto__=Buffer.prototype;
-}else{
-
-if(that===null){
-that=new Buffer(length);
-}
-that.length=length;
-}
-
-return that;
-}
-
-
-
-
-
-
-
-
-
-
-
-function Buffer(arg,encodingOrOffset,length){
-if(!Buffer.TYPED_ARRAY_SUPPORT&&!(this instanceof Buffer)){
-return new Buffer(arg,encodingOrOffset,length);
-}
-
-
-if(typeof arg==='number'){
-if(typeof encodingOrOffset==='string'){
-throw new Error(
-'If encoding is specified then the first argument must be a string');
-
-}
-return allocUnsafe(this,arg);
-}
-return from(this,arg,encodingOrOffset,length);
-}
-
-Buffer.poolSize=8192;
-
-
-Buffer._augment=function(arr){
-arr.__proto__=Buffer.prototype;
-return arr;
-};
-
-function from(that,value,encodingOrOffset,length){
-if(typeof value==='number'){
-throw new TypeError('"value" argument must not be a number');
-}
-
-if(typeof ArrayBuffer!=='undefined'&&value instanceof ArrayBuffer){
-return fromArrayBuffer(that,value,encodingOrOffset,length);
-}
-
-if(typeof value==='string'){
-return fromString(that,value,encodingOrOffset);
-}
-
-return fromObject(that,value);
-}
-
-
-
-
-
-
-
-
-
-Buffer.from=function(value,encodingOrOffset,length){
-return from(null,value,encodingOrOffset,length);
-};
-
-if(Buffer.TYPED_ARRAY_SUPPORT){
-Buffer.prototype.__proto__=Uint8Array.prototype;
-Buffer.__proto__=Uint8Array;
-if(typeof Symbol!=='undefined'&&Symbol.species&&
-Buffer[Symbol.species]===Buffer){
-
-Object.defineProperty(Buffer,Symbol.species,{
-value:null,
-configurable:true});
-
-}
-}
-
-function assertSize(size){
-if(typeof size!=='number'){
-throw new TypeError('"size" argument must be a number');
-}else if(size<0){
-throw new RangeError('"size" argument must not be negative');
-}
-}
-
-function alloc(that,size,fill,encoding){
-assertSize(size);
-if(size<=0){
-return createBuffer(that,size);
-}
-if(fill!==undefined){
-
-
-
-return typeof encoding==='string'?
-createBuffer(that,size).fill(fill,encoding):
-createBuffer(that,size).fill(fill);
-}
-return createBuffer(that,size);
-}
-
-
-
-
-
-Buffer.alloc=function(size,fill,encoding){
-return alloc(null,size,fill,encoding);
-};
-
-function allocUnsafe(that,size){
-assertSize(size);
-that=createBuffer(that,size<0?0:checked(size)|0);
-if(!Buffer.TYPED_ARRAY_SUPPORT){
-for(var i=0;i<size;++i){
-that[i]=0;
-}
-}
-return that;
-}
-
-
-
-
-Buffer.allocUnsafe=function(size){
-return allocUnsafe(null,size);
-};
-
-
-
-Buffer.allocUnsafeSlow=function(size){
-return allocUnsafe(null,size);
-};
-
-function fromString(that,string,encoding){
-if(typeof encoding!=='string'||encoding===''){
-encoding='utf8';
-}
-
-if(!Buffer.isEncoding(encoding)){
-throw new TypeError('"encoding" must be a valid string encoding');
-}
-
-var length=byteLength(string,encoding)|0;
-that=createBuffer(that,length);
-
-var actual=that.write(string,encoding);
-
-if(actual!==length){
-
-
-
-that=that.slice(0,actual);
-}
-
-return that;
-}
-
-function fromArrayLike(that,array){
-var length=array.length<0?0:checked(array.length)|0;
-that=createBuffer(that,length);
-for(var i=0;i<length;i+=1){
-that[i]=array[i]&255;
-}
-return that;
-}
-
-function fromArrayBuffer(that,array,byteOffset,length){
-array.byteLength;
-
-if(byteOffset<0||array.byteLength<byteOffset){
-throw new RangeError('\'offset\' is out of bounds');
-}
-
-if(array.byteLength<byteOffset+(length||0)){
-throw new RangeError('\'length\' is out of bounds');
-}
-
-if(byteOffset===undefined&&length===undefined){
-array=new Uint8Array(array);
-}else if(length===undefined){
-array=new Uint8Array(array,byteOffset);
-}else{
-array=new Uint8Array(array,byteOffset,length);
-}
-
-if(Buffer.TYPED_ARRAY_SUPPORT){
-
-that=array;
-that.__proto__=Buffer.prototype;
-}else{
-
-that=fromArrayLike(that,array);
-}
-return that;
-}
-
-function fromObject(that,obj){
-if(Buffer.isBuffer(obj)){
-var len=checked(obj.length)|0;
-that=createBuffer(that,len);
-
-if(that.length===0){
-return that;
-}
-
-obj.copy(that,0,0,len);
-return that;
-}
-
-if(obj){
-if(typeof ArrayBuffer!=='undefined'&&
-obj.buffer instanceof ArrayBuffer||'length'in obj){
-if(typeof obj.length!=='number'||isnan(obj.length)){
-return createBuffer(that,0);
-}
-return fromArrayLike(that,obj);
-}
-
-if(obj.type==='Buffer'&&isArray(obj.data)){
-return fromArrayLike(that,obj.data);
-}
-}
-
-throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.');
-}
-
-function checked(length){
-
-
-if(length>=kMaxLength()){
-throw new RangeError('Attempt to allocate Buffer larger than maximum '+
-'size: 0x'+kMaxLength().toString(16)+' bytes');
-}
-return length|0;
-}
-
-function SlowBuffer(length){
-if(+length!=length){
-length=0;
-}
-return Buffer.alloc(+length);
-}
-
-Buffer.isBuffer=function isBuffer(b){
-return!!(b!=null&&b._isBuffer);
-};
-
-Buffer.compare=function compare(a,b){
-if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){
-throw new TypeError('Arguments must be Buffers');
-}
-
-if(a===b)return 0;
-
-var x=a.length;
-var y=b.length;
-
-for(var i=0,len=Math.min(x,y);i<len;++i){
-if(a[i]!==b[i]){
-x=a[i];
-y=b[i];
-break;
-}
-}
-
-if(x<y)return-1;
-if(y<x)return 1;
-return 0;
-};
-
-Buffer.isEncoding=function isEncoding(encoding){
-switch(String(encoding).toLowerCase()){
-case'hex':
-case'utf8':
-case'utf-8':
-case'ascii':
-case'latin1':
-case'binary':
-case'base64':
-case'ucs2':
-case'ucs-2':
-case'utf16le':
-case'utf-16le':
-return true;
-default:
-return false;}
-
-};
-
-Buffer.concat=function concat(list,length){
-if(!isArray(list)){
-throw new TypeError('"list" argument must be an Array of Buffers');
-}
-
-if(list.length===0){
-return Buffer.alloc(0);
-}
-
-var i;
-if(length===undefined){
-length=0;
-for(i=0;i<list.length;++i){
-length+=list[i].length;
-}
-}
-
-var buffer=Buffer.allocUnsafe(length);
-var pos=0;
-for(i=0;i<list.length;++i){
-var buf=list[i];
-if(!Buffer.isBuffer(buf)){
-throw new TypeError('"list" argument must be an Array of Buffers');
-}
-buf.copy(buffer,pos);
-pos+=buf.length;
-}
-return buffer;
-};
-
-function byteLength(string,encoding){
-if(Buffer.isBuffer(string)){
-return string.length;
-}
-if(typeof ArrayBuffer!=='undefined'&&typeof ArrayBuffer.isView==='function'&&(
-ArrayBuffer.isView(string)||string instanceof ArrayBuffer)){
-return string.byteLength;
-}
-if(typeof string!=='string'){
-string=''+string;
-}
-
-var len=string.length;
-if(len===0)return 0;
-
-
-var loweredCase=false;
-for(;;){
-switch(encoding){
-case'ascii':
-case'latin1':
-case'binary':
-return len;
-case'utf8':
-case'utf-8':
-case undefined:
-return utf8ToBytes(string).length;
-case'ucs2':
-case'ucs-2':
-case'utf16le':
-case'utf-16le':
-return len*2;
-case'hex':
-return len>>>1;
-case'base64':
-return base64ToBytes(string).length;
-default:
-if(loweredCase)return utf8ToBytes(string).length;
-encoding=(''+encoding).toLowerCase();
-loweredCase=true;}
-
-}
-}
-Buffer.byteLength=byteLength;
-
-function slowToString(encoding,start,end){
-var loweredCase=false;
-
-
-
-
-
-
-
-
-if(start===undefined||start<0){
-start=0;
-}
-
-
-if(start>this.length){
-return'';
-}
-
-if(end===undefined||end>this.length){
-end=this.length;
-}
-
-if(end<=0){
-return'';
-}
-
-
-end>>>=0;
-start>>>=0;
-
-if(end<=start){
-return'';
-}
-
-if(!encoding)encoding='utf8';
-
-while(true){
-switch(encoding){
-case'hex':
-return hexSlice(this,start,end);
-
-case'utf8':
-case'utf-8':
-return utf8Slice(this,start,end);
-
-case'ascii':
-return asciiSlice(this,start,end);
-
-case'latin1':
-case'binary':
-return latin1Slice(this,start,end);
-
-case'base64':
-return base64Slice(this,start,end);
-
-case'ucs2':
-case'ucs-2':
-case'utf16le':
-case'utf-16le':
-return utf16leSlice(this,start,end);
-
-default:
-if(loweredCase)throw new TypeError('Unknown encoding: '+encoding);
-encoding=(encoding+'').toLowerCase();
-loweredCase=true;}
-
-}
-}
-
-
-
-Buffer.prototype._isBuffer=true;
-
-function swap(b,n,m){
-var i=b[n];
-b[n]=b[m];
-b[m]=i;
-}
-
-Buffer.prototype.swap16=function swap16(){
-var len=this.length;
-if(len%2!==0){
-throw new RangeError('Buffer size must be a multiple of 16-bits');
-}
-for(var i=0;i<len;i+=2){
-swap(this,i,i+1);
-}
-return this;
-};
-
-Buffer.prototype.swap32=function swap32(){
-var len=this.length;
-if(len%4!==0){
-throw new RangeError('Buffer size must be a multiple of 32-bits');
-}
-for(var i=0;i<len;i+=4){
-swap(this,i,i+3);
-swap(this,i+1,i+2);
-}
-return this;
-};
-
-Buffer.prototype.swap64=function swap64(){
-var len=this.length;
-if(len%8!==0){
-throw new RangeError('Buffer size must be a multiple of 64-bits');
-}
-for(var i=0;i<len;i+=8){
-swap(this,i,i+7);
-swap(this,i+1,i+6);
-swap(this,i+2,i+5);
-swap(this,i+3,i+4);
-}
-return this;
-};
-
-Buffer.prototype.toString=function toString(){
-var length=this.length|0;
-if(length===0)return'';
-if(arguments.length===0)return utf8Slice(this,0,length);
-return slowToString.apply(this,arguments);
-};
-
-Buffer.prototype.equals=function equals(b){
-if(!Buffer.isBuffer(b))throw new TypeError('Argument must be a Buffer');
-if(this===b)return true;
-return Buffer.compare(this,b)===0;
-};
-
-Buffer.prototype.inspect=function inspect(){
-var str='';
-var max=exports.INSPECT_MAX_BYTES;
-if(this.length>0){
-str=this.toString('hex',0,max).match(/.{2}/g).join(' ');
-if(this.length>max)str+=' ... ';
-}
-return'<Buffer '+str+'>';
-};
-
-Buffer.prototype.compare=function compare(target,start,end,thisStart,thisEnd){
-if(!Buffer.isBuffer(target)){
-throw new TypeError('Argument must be a Buffer');
-}
-
-if(start===undefined){
-start=0;
-}
-if(end===undefined){
-end=target?target.length:0;
-}
-if(thisStart===undefined){
-thisStart=0;
-}
-if(thisEnd===undefined){
-thisEnd=this.length;
-}
-
-if(start<0||end>target.length||thisStart<0||thisEnd>this.length){
-throw new RangeError('out of range index');
-}
-
-if(thisStart>=thisEnd&&start>=end){
-return 0;
-}
-if(thisStart>=thisEnd){
-return-1;
-}
-if(start>=end){
-return 1;
-}
-
-start>>>=0;
-end>>>=0;
-thisStart>>>=0;
-thisEnd>>>=0;
-
-if(this===target)return 0;
-
-var x=thisEnd-thisStart;
-var y=end-start;
-var len=Math.min(x,y);
-
-var thisCopy=this.slice(thisStart,thisEnd);
-var targetCopy=target.slice(start,end);
-
-for(var i=0;i<len;++i){
-if(thisCopy[i]!==targetCopy[i]){
-x=thisCopy[i];
-y=targetCopy[i];
-break;
-}
-}
-
-if(x<y)return-1;
-if(y<x)return 1;
-return 0;
-};
-
-
-
-
-
-
-
-
-
-
-function bidirectionalIndexOf(buffer,val,byteOffset,encoding,dir){
-
-if(buffer.length===0)return-1;
-
-
-if(typeof byteOffset==='string'){
-encoding=byteOffset;
-byteOffset=0;
-}else if(byteOffset>0x7fffffff){
-byteOffset=0x7fffffff;
-}else if(byteOffset<-0x80000000){
-byteOffset=-0x80000000;
-}
-byteOffset=+byteOffset;
-if(isNaN(byteOffset)){
-
-byteOffset=dir?0:buffer.length-1;
-}
-
-
-if(byteOffset<0)byteOffset=buffer.length+byteOffset;
-if(byteOffset>=buffer.length){
-if(dir)return-1;else
-byteOffset=buffer.length-1;
-}else if(byteOffset<0){
-if(dir)byteOffset=0;else
-return-1;
-}
-
-
-if(typeof val==='string'){
-val=Buffer.from(val,encoding);
-}
-
-
-if(Buffer.isBuffer(val)){
-
-if(val.length===0){
-return-1;
-}
-return arrayIndexOf(buffer,val,byteOffset,encoding,dir);
-}else if(typeof val==='number'){
-val=val&0xFF;
-if(Buffer.TYPED_ARRAY_SUPPORT&&
-typeof Uint8Array.prototype.indexOf==='function'){
-if(dir){
-return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset);
-}else{
-return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset);
-}
-}
-return arrayIndexOf(buffer,[val],byteOffset,encoding,dir);
-}
-
-throw new TypeError('val must be string, number or Buffer');
-}
-
-function arrayIndexOf(arr,val,byteOffset,encoding,dir){
-var indexSize=1;
-var arrLength=arr.length;
-var valLength=val.length;
-
-if(encoding!==undefined){
-encoding=String(encoding).toLowerCase();
-if(encoding==='ucs2'||encoding==='ucs-2'||
-encoding==='utf16le'||encoding==='utf-16le'){
-if(arr.length<2||val.length<2){
-return-1;
-}
-indexSize=2;
-arrLength/=2;
-valLength/=2;
-byteOffset/=2;
-}
-}
-
-function read(buf,i){
-if(indexSize===1){
-return buf[i];
-}else{
-return buf.readUInt16BE(i*indexSize);
-}
-}
-
-var i;
-if(dir){
-var foundIndex=-1;
-for(i=byteOffset;i<arrLength;i++){
-if(read(arr,i)===read(val,foundIndex===-1?0:i-foundIndex)){
-if(foundIndex===-1)foundIndex=i;
-if(i-foundIndex+1===valLength)return foundIndex*indexSize;
-}else{
-if(foundIndex!==-1)i-=i-foundIndex;
-foundIndex=-1;
-}
-}
-}else{
-if(byteOffset+valLength>arrLength)byteOffset=arrLength-valLength;
-for(i=byteOffset;i>=0;i--){
-var found=true;
-for(var j=0;j<valLength;j++){
-if(read(arr,i+j)!==read(val,j)){
-found=false;
-break;
-}
-}
-if(found)return i;
-}
-}
-
-return-1;
-}
-
-Buffer.prototype.includes=function includes(val,byteOffset,encoding){
-return this.indexOf(val,byteOffset,encoding)!==-1;
-};
-
-Buffer.prototype.indexOf=function indexOf(val,byteOffset,encoding){
-return bidirectionalIndexOf(this,val,byteOffset,encoding,true);
-};
-
-Buffer.prototype.lastIndexOf=function lastIndexOf(val,byteOffset,encoding){
-return bidirectionalIndexOf(this,val,byteOffset,encoding,false);
-};
-
-function hexWrite(buf,string,offset,length){
-offset=Number(offset)||0;
-var remaining=buf.length-offset;
-if(!length){
-length=remaining;
-}else{
-length=Number(length);
-if(length>remaining){
-length=remaining;
-}
-}
-
-
-var strLen=string.length;
-if(strLen%2!==0)throw new TypeError('Invalid hex string');
-
-if(length>strLen/2){
-length=strLen/2;
-}
-for(var i=0;i<length;++i){
-var parsed=parseInt(string.substr(i*2,2),16);
-if(isNaN(parsed))return i;
-buf[offset+i]=parsed;
-}
-return i;
-}
-
-function utf8Write(buf,string,offset,length){
-return blitBuffer(utf8ToBytes(string,buf.length-offset),buf,offset,length);
-}
-
-function asciiWrite(buf,string,offset,length){
-return blitBuffer(asciiToBytes(string),buf,offset,length);
-}
-
-function latin1Write(buf,string,offset,length){
-return asciiWrite(buf,string,offset,length);
-}
-
-function base64Write(buf,string,offset,length){
-return blitBuffer(base64ToBytes(string),buf,offset,length);
-}
-
-function ucs2Write(buf,string,offset,length){
-return blitBuffer(utf16leToBytes(string,buf.length-offset),buf,offset,length);
-}
-
-Buffer.prototype.write=function write(string,offset,length,encoding){
-
-if(offset===undefined){
-encoding='utf8';
-length=this.length;
-offset=0;
-
-}else if(length===undefined&&typeof offset==='string'){
-encoding=offset;
-length=this.length;
-offset=0;
-
-}else if(isFinite(offset)){
-offset=offset|0;
-if(isFinite(length)){
-length=length|0;
-if(encoding===undefined)encoding='utf8';
-}else{
-encoding=length;
-length=undefined;
-}
-
-}else{
-throw new Error(
-'Buffer.write(string, encoding, offset[, length]) is no longer supported');
-
-}
-
-var remaining=this.length-offset;
-if(length===undefined||length>remaining)length=remaining;
-
-if(string.length>0&&(length<0||offset<0)||offset>this.length){
-throw new RangeError('Attempt to write outside buffer bounds');
-}
-
-if(!encoding)encoding='utf8';
-
-var loweredCase=false;
-for(;;){
-switch(encoding){
-case'hex':
-return hexWrite(this,string,offset,length);
-
-case'utf8':
-case'utf-8':
-return utf8Write(this,string,offset,length);
-
-case'ascii':
-return asciiWrite(this,string,offset,length);
-
-case'latin1':
-case'binary':
-return latin1Write(this,string,offset,length);
-
-case'base64':
-
-return base64Write(this,string,offset,length);
-
-case'ucs2':
-case'ucs-2':
-case'utf16le':
-case'utf-16le':
-return ucs2Write(this,string,offset,length);
-
-default:
-if(loweredCase)throw new TypeError('Unknown encoding: '+encoding);
-encoding=(''+encoding).toLowerCase();
-loweredCase=true;}
-
-}
-};
-
-Buffer.prototype.toJSON=function toJSON(){
-return{
-type:'Buffer',
-data:Array.prototype.slice.call(this._arr||this,0)};
-
-};
-
-function base64Slice(buf,start,end){
-if(start===0&&end===buf.length){
-return base64.fromByteArray(buf);
-}else{
-return base64.fromByteArray(buf.slice(start,end));
-}
-}
-
-function utf8Slice(buf,start,end){
-end=Math.min(buf.length,end);
-var res=[];
-
-var i=start;
-while(i<end){
-var firstByte=buf[i];
-var codePoint=null;
-var bytesPerSequence=firstByte>0xEF?4:
-firstByte>0xDF?3:
-firstByte>0xBF?2:
-1;
-
-if(i+bytesPerSequence<=end){
-var secondByte,thirdByte,fourthByte,tempCodePoint;
-
-switch(bytesPerSequence){
-case 1:
-if(firstByte<0x80){
-codePoint=firstByte;
-}
-break;
-case 2:
-secondByte=buf[i+1];
-if((secondByte&0xC0)===0x80){
-tempCodePoint=(firstByte&0x1F)<<0x6|secondByte&0x3F;
-if(tempCodePoint>0x7F){
-codePoint=tempCodePoint;
-}
-}
-break;
-case 3:
-secondByte=buf[i+1];
-thirdByte=buf[i+2];
-if((secondByte&0xC0)===0x80&&(thirdByte&0xC0)===0x80){
-tempCodePoint=(firstByte&0xF)<<0xC|(secondByte&0x3F)<<0x6|thirdByte&0x3F;
-if(tempCodePoint>0x7FF&&(tempCodePoint<0xD800||tempCodePoint>0xDFFF)){
-codePoint=tempCodePoint;
-}
-}
-break;
-case 4:
-secondByte=buf[i+1];
-thirdByte=buf[i+2];
-fourthByte=buf[i+3];
-if((secondByte&0xC0)===0x80&&(thirdByte&0xC0)===0x80&&(fourthByte&0xC0)===0x80){
-tempCodePoint=(firstByte&0xF)<<0x12|(secondByte&0x3F)<<0xC|(thirdByte&0x3F)<<0x6|fourthByte&0x3F;
-if(tempCodePoint>0xFFFF&&tempCodePoint<0x110000){
-codePoint=tempCodePoint;
-}
-}}
-
-}
-
-if(codePoint===null){
-
-
-codePoint=0xFFFD;
-bytesPerSequence=1;
-}else if(codePoint>0xFFFF){
-
-codePoint-=0x10000;
-res.push(codePoint>>>10&0x3FF|0xD800);
-codePoint=0xDC00|codePoint&0x3FF;
-}
-
-res.push(codePoint);
-i+=bytesPerSequence;
-}
-
-return decodeCodePointsArray(res);
-}
-
-
-
-
-var MAX_ARGUMENTS_LENGTH=0x1000;
-
-function decodeCodePointsArray(codePoints){
-var len=codePoints.length;
-if(len<=MAX_ARGUMENTS_LENGTH){
-return String.fromCharCode.apply(String,codePoints);
-}
-
-
-var res='';
-var i=0;
-while(i<len){
-res+=String.fromCharCode.apply(
-String,
-codePoints.slice(i,i+=MAX_ARGUMENTS_LENGTH));
-
-}
-return res;
-}
-
-function asciiSlice(buf,start,end){
-var ret='';
-end=Math.min(buf.length,end);
-
-for(var i=start;i<end;++i){
-ret+=String.fromCharCode(buf[i]&0x7F);
-}
-return ret;
-}
-
-function latin1Slice(buf,start,end){
-var ret='';
-end=Math.min(buf.length,end);
-
-for(var i=start;i<end;++i){
-ret+=String.fromCharCode(buf[i]);
-}
-return ret;
-}
-
-function hexSlice(buf,start,end){
-var len=buf.length;
-
-if(!start||start<0)start=0;
-if(!end||end<0||end>len)end=len;
-
-var out='';
-for(var i=start;i<end;++i){
-out+=toHex(buf[i]);
-}
-return out;
-}
-
-function utf16leSlice(buf,start,end){
-var bytes=buf.slice(start,end);
-var res='';
-for(var i=0;i<bytes.length;i+=2){
-res+=String.fromCharCode(bytes[i]+bytes[i+1]*256);
-}
-return res;
-}
-
-Buffer.prototype.slice=function slice(start,end){
-var len=this.length;
-start=~~start;
-end=end===undefined?len:~~end;
-
-if(start<0){
-start+=len;
-if(start<0)start=0;
-}else if(start>len){
-start=len;
-}
-
-if(end<0){
-end+=len;
-if(end<0)end=0;
-}else if(end>len){
-end=len;
-}
-
-if(end<start)end=start;
-
-var newBuf;
-if(Buffer.TYPED_ARRAY_SUPPORT){
-newBuf=this.subarray(start,end);
-newBuf.__proto__=Buffer.prototype;
-}else{
-var sliceLen=end-start;
-newBuf=new Buffer(sliceLen,undefined);
-for(var i=0;i<sliceLen;++i){
-newBuf[i]=this[i+start];
-}
-}
-
-return newBuf;
-};
-
-
-
-
-function checkOffset(offset,ext,length){
-if(offset%1!==0||offset<0)throw new RangeError('offset is not uint');
-if(offset+ext>length)throw new RangeError('Trying to access beyond buffer length');
-}
-
-Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){
-offset=offset|0;
-byteLength=byteLength|0;
-if(!noAssert)checkOffset(offset,byteLength,this.length);
-
-var val=this[offset];
-var mul=1;
-var i=0;
-while(++i<byteLength&&(mul*=0x100)){
-val+=this[offset+i]*mul;
-}
-
-return val;
-};
-
-Buffer.prototype.readUIntBE=function readUIntBE(offset,byteLength,noAssert){
-offset=offset|0;
-byteLength=byteLength|0;
-if(!noAssert){
-checkOffset(offset,byteLength,this.length);
-}
-
-var val=this[offset+--byteLength];
-var mul=1;
-while(byteLength>0&&(mul*=0x100)){
-val+=this[offset+--byteLength]*mul;
-}
-
-return val;
-};
-
-Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){
-if(!noAssert)checkOffset(offset,1,this.length);
-return this[offset];
-};
-
-Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){
-if(!noAssert)checkOffset(offset,2,this.length);
-return this[offset]|this[offset+1]<<8;
-};
-
-Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){
-if(!noAssert)checkOffset(offset,2,this.length);
-return this[offset]<<8|this[offset+1];
-};
-
-Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){
-if(!noAssert)checkOffset(offset,4,this.length);
-
-return(this[offset]|
-this[offset+1]<<8|
-this[offset+2]<<16)+
-this[offset+3]*0x1000000;
-};
-
-Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){
-if(!noAssert)checkOffset(offset,4,this.length);
-
-return this[offset]*0x1000000+(
-this[offset+1]<<16|
-this[offset+2]<<8|
-this[offset+3]);
-};
-
-Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){
-offset=offset|0;
-byteLength=byteLength|0;
-if(!noAssert)checkOffset(offset,byteLength,this.length);
-
-var val=this[offset];
-var mul=1;
-var i=0;
-while(++i<byteLength&&(mul*=0x100)){
-val+=this[offset+i]*mul;
-}
-mul*=0x80;
-
-if(val>=mul)val-=Math.pow(2,8*byteLength);
-
-return val;
-};
-
-Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){
-offset=offset|0;
-byteLength=byteLength|0;
-if(!noAssert)checkOffset(offset,byteLength,this.length);
-
-var i=byteLength;
-var mul=1;
-var val=this[offset+--i];
-while(i>0&&(mul*=0x100)){
-val+=this[offset+--i]*mul;
-}
-mul*=0x80;
-
-if(val>=mul)val-=Math.pow(2,8*byteLength);
-
-return val;
-};
-
-Buffer.prototype.readInt8=function readInt8(offset,noAssert){
-if(!noAssert)checkOffset(offset,1,this.length);
-if(!(this[offset]&0x80))return this[offset];
-return(0xff-this[offset]+1)*-1;
-};
-
-Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){
-if(!noAssert)checkOffset(offset,2,this.length);
-var val=this[offset]|this[offset+1]<<8;
-return val&0x8000?val|0xFFFF0000:val;
-};
-
-Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){
-if(!noAssert)checkOffset(offset,2,this.length);
-var val=this[offset+1]|this[offset]<<8;
-return val&0x8000?val|0xFFFF0000:val;
-};
-
-Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){
-if(!noAssert)checkOffset(offset,4,this.length);
-
-return this[offset]|
-this[offset+1]<<8|
-this[offset+2]<<16|
-this[offset+3]<<24;
-};
-
-Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){
-if(!noAssert)checkOffset(offset,4,this.length);
-
-return this[offset]<<24|
-this[offset+1]<<16|
-this[offset+2]<<8|
-this[offset+3];
-};
-
-Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){
-if(!noAssert)checkOffset(offset,4,this.length);
-return ieee754.read(this,offset,true,23,4);
-};
-
-Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){
-if(!noAssert)checkOffset(offset,4,this.length);
-return ieee754.read(this,offset,false,23,4);
-};
-
-Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){
-if(!noAssert)checkOffset(offset,8,this.length);
-return ieee754.read(this,offset,true,52,8);
-};
-
-Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){
-if(!noAssert)checkOffset(offset,8,this.length);
-return ieee754.read(this,offset,false,52,8);
-};
-
-function checkInt(buf,value,offset,ext,max,min){
-if(!Buffer.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');
-if(value>max||value<min)throw new RangeError('"value" argument is out of bounds');
-if(offset+ext>buf.length)throw new RangeError('Index out of range');
-}
-
-Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){
-value=+value;
-offset=offset|0;
-byteLength=byteLength|0;
-if(!noAssert){
-var maxBytes=Math.pow(2,8*byteLength)-1;
-checkInt(this,value,offset,byteLength,maxBytes,0);
-}
-
-var mul=1;
-var i=0;
-this[offset]=value&0xFF;
-while(++i<byteLength&&(mul*=0x100)){
-this[offset+i]=value/mul&0xFF;
-}
-
-return offset+byteLength;
-};
-
-Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){
-value=+value;
-offset=offset|0;
-byteLength=byteLength|0;
-if(!noAssert){
-var maxBytes=Math.pow(2,8*byteLength)-1;
-checkInt(this,value,offset,byteLength,maxBytes,0);
-}
-
-var i=byteLength-1;
-var mul=1;
-this[offset+i]=value&0xFF;
-while(--i>=0&&(mul*=0x100)){
-this[offset+i]=value/mul&0xFF;
-}
-
-return offset+byteLength;
-};
-
-Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,1,0xff,0);
-if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);
-this[offset]=value&0xff;
-return offset+1;
-};
-
-function objectWriteUInt16(buf,value,offset,littleEndian){
-if(value<0)value=0xffff+value+1;
-for(var i=0,j=Math.min(buf.length-offset,2);i<j;++i){
-buf[offset+i]=(value&0xff<<8*(littleEndian?i:1-i))>>>
-(littleEndian?i:1-i)*8;
-}
-}
-
-Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,2,0xffff,0);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value&0xff;
-this[offset+1]=value>>>8;
-}else{
-objectWriteUInt16(this,value,offset,true);
-}
-return offset+2;
-};
-
-Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,2,0xffff,0);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value>>>8;
-this[offset+1]=value&0xff;
-}else{
-objectWriteUInt16(this,value,offset,false);
-}
-return offset+2;
-};
-
-function objectWriteUInt32(buf,value,offset,littleEndian){
-if(value<0)value=0xffffffff+value+1;
-for(var i=0,j=Math.min(buf.length-offset,4);i<j;++i){
-buf[offset+i]=value>>>(littleEndian?i:3-i)*8&0xff;
-}
-}
-
-Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,4,0xffffffff,0);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset+3]=value>>>24;
-this[offset+2]=value>>>16;
-this[offset+1]=value>>>8;
-this[offset]=value&0xff;
-}else{
-objectWriteUInt32(this,value,offset,true);
-}
-return offset+4;
-};
-
-Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,4,0xffffffff,0);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value>>>24;
-this[offset+1]=value>>>16;
-this[offset+2]=value>>>8;
-this[offset+3]=value&0xff;
-}else{
-objectWriteUInt32(this,value,offset,false);
-}
-return offset+4;
-};
-
-Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert){
-var limit=Math.pow(2,8*byteLength-1);
-
-checkInt(this,value,offset,byteLength,limit-1,-limit);
-}
-
-var i=0;
-var mul=1;
-var sub=0;
-this[offset]=value&0xFF;
-while(++i<byteLength&&(mul*=0x100)){
-if(value<0&&sub===0&&this[offset+i-1]!==0){
-sub=1;
-}
-this[offset+i]=(value/mul>>0)-sub&0xFF;
-}
-
-return offset+byteLength;
-};
-
-Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert){
-var limit=Math.pow(2,8*byteLength-1);
-
-checkInt(this,value,offset,byteLength,limit-1,-limit);
-}
-
-var i=byteLength-1;
-var mul=1;
-var sub=0;
-this[offset+i]=value&0xFF;
-while(--i>=0&&(mul*=0x100)){
-if(value<0&&sub===0&&this[offset+i+1]!==0){
-sub=1;
-}
-this[offset+i]=(value/mul>>0)-sub&0xFF;
-}
-
-return offset+byteLength;
-};
-
-Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,1,0x7f,-0x80);
-if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);
-if(value<0)value=0xff+value+1;
-this[offset]=value&0xff;
-return offset+1;
-};
-
-Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,2,0x7fff,-0x8000);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value&0xff;
-this[offset+1]=value>>>8;
-}else{
-objectWriteUInt16(this,value,offset,true);
-}
-return offset+2;
-};
-
-Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,2,0x7fff,-0x8000);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value>>>8;
-this[offset+1]=value&0xff;
-}else{
-objectWriteUInt16(this,value,offset,false);
-}
-return offset+2;
-};
-
-Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,4,0x7fffffff,-0x80000000);
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value&0xff;
-this[offset+1]=value>>>8;
-this[offset+2]=value>>>16;
-this[offset+3]=value>>>24;
-}else{
-objectWriteUInt32(this,value,offset,true);
-}
-return offset+4;
-};
-
-Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){
-value=+value;
-offset=offset|0;
-if(!noAssert)checkInt(this,value,offset,4,0x7fffffff,-0x80000000);
-if(value<0)value=0xffffffff+value+1;
-if(Buffer.TYPED_ARRAY_SUPPORT){
-this[offset]=value>>>24;
-this[offset+1]=value>>>16;
-this[offset+2]=value>>>8;
-this[offset+3]=value&0xff;
-}else{
-objectWriteUInt32(this,value,offset,false);
-}
-return offset+4;
-};
-
-function checkIEEE754(buf,value,offset,ext,max,min){
-if(offset+ext>buf.length)throw new RangeError('Index out of range');
-if(offset<0)throw new RangeError('Index out of range');
-}
-
-function writeFloat(buf,value,offset,littleEndian,noAssert){
-if(!noAssert){
-checkIEEE754(buf,value,offset,4,3.4028234663852886e+38,-3.4028234663852886e+38);
-}
-ieee754.write(buf,value,offset,littleEndian,23,4);
-return offset+4;
-}
-
-Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){
-return writeFloat(this,value,offset,true,noAssert);
-};
-
-Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){
-return writeFloat(this,value,offset,false,noAssert);
-};
-
-function writeDouble(buf,value,offset,littleEndian,noAssert){
-if(!noAssert){
-checkIEEE754(buf,value,offset,8,1.7976931348623157E+308,-1.7976931348623157E+308);
-}
-ieee754.write(buf,value,offset,littleEndian,52,8);
-return offset+8;
-}
-
-Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){
-return writeDouble(this,value,offset,true,noAssert);
-};
-
-Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){
-return writeDouble(this,value,offset,false,noAssert);
-};
-
-
-Buffer.prototype.copy=function copy(target,targetStart,start,end){
-if(!start)start=0;
-if(!end&&end!==0)end=this.length;
-if(targetStart>=target.length)targetStart=target.length;
-if(!targetStart)targetStart=0;
-if(end>0&&end<start)end=start;
-
-
-if(end===start)return 0;
-if(target.length===0||this.length===0)return 0;
-
-
-if(targetStart<0){
-throw new RangeError('targetStart out of bounds');
-}
-if(start<0||start>=this.length)throw new RangeError('sourceStart out of bounds');
-if(end<0)throw new RangeError('sourceEnd out of bounds');
-
-
-if(end>this.length)end=this.length;
-if(target.length-targetStart<end-start){
-end=target.length-targetStart+start;
-}
-
-var len=end-start;
-var i;
-
-if(this===target&&start<targetStart&&targetStart<end){
-
-for(i=len-1;i>=0;--i){
-target[i+targetStart]=this[i+start];
-}
-}else if(len<1000||!Buffer.TYPED_ARRAY_SUPPORT){
-
-for(i=0;i<len;++i){
-target[i+targetStart]=this[i+start];
-}
-}else{
-Uint8Array.prototype.set.call(
-target,
-this.subarray(start,start+len),
-targetStart);
-
-}
-
-return len;
-};
-
-
-
-
-
-Buffer.prototype.fill=function fill(val,start,end,encoding){
-
-if(typeof val==='string'){
-if(typeof start==='string'){
-encoding=start;
-start=0;
-end=this.length;
-}else if(typeof end==='string'){
-encoding=end;
-end=this.length;
-}
-if(val.length===1){
-var code=val.charCodeAt(0);
-if(code<256){
-val=code;
-}
-}
-if(encoding!==undefined&&typeof encoding!=='string'){
-throw new TypeError('encoding must be a string');
-}
-if(typeof encoding==='string'&&!Buffer.isEncoding(encoding)){
-throw new TypeError('Unknown encoding: '+encoding);
-}
-}else if(typeof val==='number'){
-val=val&255;
-}
-
-
-if(start<0||this.length<start||this.length<end){
-throw new RangeError('Out of range index');
-}
-
-if(end<=start){
-return this;
-}
-
-start=start>>>0;
-end=end===undefined?this.length:end>>>0;
-
-if(!val)val=0;
-
-var i;
-if(typeof val==='number'){
-for(i=start;i<end;++i){
-this[i]=val;
-}
-}else{
-var bytes=Buffer.isBuffer(val)?
-val:
-utf8ToBytes(new Buffer(val,encoding).toString());
-var len=bytes.length;
-for(i=0;i<end-start;++i){
-this[i+start]=bytes[i%len];
-}
-}
-
-return this;
-};
-
-
-
-
-var INVALID_BASE64_RE=/[^+\/0-9A-Za-z-_]/g;
-
-function base64clean(str){
-
-str=stringtrim(str).replace(INVALID_BASE64_RE,'');
-
-if(str.length<2)return'';
-
-while(str.length%4!==0){
-str=str+'=';
-}
-return str;
-}
-
-function stringtrim(str){
-if(str.trim)return str.trim();
-return str.replace(/^\s+|\s+$/g,'');
-}
-
-function toHex(n){
-if(n<16)return'0'+n.toString(16);
-return n.toString(16);
-}
-
-function utf8ToBytes(string,units){
-units=units||Infinity;
-var codePoint;
-var length=string.length;
-var leadSurrogate=null;
-var bytes=[];
-
-for(var i=0;i<length;++i){
-codePoint=string.charCodeAt(i);
-
-
-if(codePoint>0xD7FF&&codePoint<0xE000){
-
-if(!leadSurrogate){
-
-if(codePoint>0xDBFF){
-
-if((units-=3)>-1)bytes.push(0xEF,0xBF,0xBD);
-continue;
-}else if(i+1===length){
-
-if((units-=3)>-1)bytes.push(0xEF,0xBF,0xBD);
-continue;
-}
-
-
-leadSurrogate=codePoint;
-
-continue;
-}
-
-
-if(codePoint<0xDC00){
-if((units-=3)>-1)bytes.push(0xEF,0xBF,0xBD);
-leadSurrogate=codePoint;
-continue;
-}
-
-
-codePoint=(leadSurrogate-0xD800<<10|codePoint-0xDC00)+0x10000;
-}else if(leadSurrogate){
-
-if((units-=3)>-1)bytes.push(0xEF,0xBF,0xBD);
-}
-
-leadSurrogate=null;
-
-
-if(codePoint<0x80){
-if((units-=1)<0)break;
-bytes.push(codePoint);
-}else if(codePoint<0x800){
-if((units-=2)<0)break;
-bytes.push(
-codePoint>>0x6|0xC0,
-codePoint&0x3F|0x80);
-
-}else if(codePoint<0x10000){
-if((units-=3)<0)break;
-bytes.push(
-codePoint>>0xC|0xE0,
-codePoint>>0x6&0x3F|0x80,
-codePoint&0x3F|0x80);
-
-}else if(codePoint<0x110000){
-if((units-=4)<0)break;
-bytes.push(
-codePoint>>0x12|0xF0,
-codePoint>>0xC&0x3F|0x80,
-codePoint>>0x6&0x3F|0x80,
-codePoint&0x3F|0x80);
-
-}else{
-throw new Error('Invalid code point');
-}
-}
-
-return bytes;
-}
-
-function asciiToBytes(str){
-var byteArray=[];
-for(var i=0;i<str.length;++i){
-
-byteArray.push(str.charCodeAt(i)&0xFF);
-}
-return byteArray;
-}
-
-function utf16leToBytes(str,units){
-var c,hi,lo;
-var byteArray=[];
-for(var i=0;i<str.length;++i){
-if((units-=2)<0)break;
-
-c=str.charCodeAt(i);
-hi=c>>8;
-lo=c%256;
-byteArray.push(lo);
-byteArray.push(hi);
-}
-
-return byteArray;
-}
-
-function base64ToBytes(str){
-return base64.toByteArray(base64clean(str));
-}
-
-function blitBuffer(src,dst,offset,length){
-for(var i=0;i<length;++i){
-if(i+offset>=dst.length||i>=src.length)break;
-dst[i+offset]=src[i];
-}
-return i;
-}
-
-function isnan(val){
-return val!==val;
-}
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"base64-js":48,"ieee754":57,"isarray":60}],55:[function(require,module,exports){
-(function(Buffer){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isArray(arg){
-if(Array.isArray){
-return Array.isArray(arg);
-}
-return objectToString(arg)==='[object Array]';
-}
-exports.isArray=isArray;
-
-function isBoolean(arg){
-return typeof arg==='boolean';
-}
-exports.isBoolean=isBoolean;
-
-function isNull(arg){
-return arg===null;
-}
-exports.isNull=isNull;
-
-function isNullOrUndefined(arg){
-return arg==null;
-}
-exports.isNullOrUndefined=isNullOrUndefined;
-
-function isNumber(arg){
-return typeof arg==='number';
-}
-exports.isNumber=isNumber;
-
-function isString(arg){
-return typeof arg==='string';
-}
-exports.isString=isString;
-
-function isSymbol(arg){
-return typeof arg==='symbol';
-}
-exports.isSymbol=isSymbol;
-
-function isUndefined(arg){
-return arg===void 0;
-}
-exports.isUndefined=isUndefined;
-
-function isRegExp(re){
-return objectToString(re)==='[object RegExp]';
-}
-exports.isRegExp=isRegExp;
-
-function isObject(arg){
-return typeof arg==='object'&&arg!==null;
-}
-exports.isObject=isObject;
-
-function isDate(d){
-return objectToString(d)==='[object Date]';
-}
-exports.isDate=isDate;
-
-function isError(e){
-return objectToString(e)==='[object Error]'||e instanceof Error;
-}
-exports.isError=isError;
-
-function isFunction(arg){
-return typeof arg==='function';
-}
-exports.isFunction=isFunction;
-
-function isPrimitive(arg){
-return arg===null||
-typeof arg==='boolean'||
-typeof arg==='number'||
-typeof arg==='string'||
-typeof arg==='symbol'||
-typeof arg==='undefined';
-}
-exports.isPrimitive=isPrimitive;
-
-exports.isBuffer=Buffer.isBuffer;
-
-function objectToString(o){
-return Object.prototype.toString.call(o);
-}
-
-}).call(this,{"isBuffer":require("../../is-buffer/index.js")});
-},{"../../is-buffer/index.js":59}],56:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function EventEmitter(){
-this._events=this._events||{};
-this._maxListeners=this._maxListeners||undefined;
-}
-module.exports=EventEmitter;
-
-
-EventEmitter.EventEmitter=EventEmitter;
-
-EventEmitter.prototype._events=undefined;
-EventEmitter.prototype._maxListeners=undefined;
-
-
-
-EventEmitter.defaultMaxListeners=10;
-
-
-
-EventEmitter.prototype.setMaxListeners=function(n){
-if(!isNumber(n)||n<0||isNaN(n))
-throw TypeError('n must be a positive number');
-this._maxListeners=n;
-return this;
-};
-
-EventEmitter.prototype.emit=function(type){
-var er,handler,len,args,i,listeners;
-
-if(!this._events)
-this._events={};
-
-
-if(type==='error'){
-if(!this._events.error||
-isObject(this._events.error)&&!this._events.error.length){
-er=arguments[1];
-if(er instanceof Error){
-throw er;
-}else{
-
-var err=new Error('Uncaught, unspecified "error" event. ('+er+')');
-err.context=er;
-throw err;
-}
-}
-}
-
-handler=this._events[type];
-
-if(isUndefined(handler))
-return false;
-
-if(isFunction(handler)){
-switch(arguments.length){
-
-case 1:
-handler.call(this);
-break;
-case 2:
-handler.call(this,arguments[1]);
-break;
-case 3:
-handler.call(this,arguments[1],arguments[2]);
-break;
-
-default:
-args=Array.prototype.slice.call(arguments,1);
-handler.apply(this,args);}
-
-}else if(isObject(handler)){
-args=Array.prototype.slice.call(arguments,1);
-listeners=handler.slice();
-len=listeners.length;
-for(i=0;i<len;i++)
-listeners[i].apply(this,args);
-}
-
-return true;
-};
-
-EventEmitter.prototype.addListener=function(type,listener){
-var m;
-
-if(!isFunction(listener))
-throw TypeError('listener must be a function');
-
-if(!this._events)
-this._events={};
-
-
-
-if(this._events.newListener)
-this.emit('newListener',type,
-isFunction(listener.listener)?
-listener.listener:listener);
-
-if(!this._events[type])
-
-this._events[type]=listener;else
-if(isObject(this._events[type]))
-
-this._events[type].push(listener);else
-
-
-this._events[type]=[this._events[type],listener];
-
-
-if(isObject(this._events[type])&&!this._events[type].warned){
-if(!isUndefined(this._maxListeners)){
-m=this._maxListeners;
-}else{
-m=EventEmitter.defaultMaxListeners;
-}
-
-if(m&&m>0&&this._events[type].length>m){
-this._events[type].warned=true;
-console.error('(node) warning: possible EventEmitter memory '+
-'leak detected. %d listeners added. '+
-'Use emitter.setMaxListeners() to increase limit.',
-this._events[type].length);
-if(typeof console.trace==='function'){
-
-console.trace();
-}
-}
-}
-
-return this;
-};
-
-EventEmitter.prototype.on=EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once=function(type,listener){
-if(!isFunction(listener))
-throw TypeError('listener must be a function');
-
-var fired=false;
-
-function g(){
-this.removeListener(type,g);
-
-if(!fired){
-fired=true;
-listener.apply(this,arguments);
-}
-}
-
-g.listener=listener;
-this.on(type,g);
-
-return this;
-};
-
-
-EventEmitter.prototype.removeListener=function(type,listener){
-var list,position,length,i;
-
-if(!isFunction(listener))
-throw TypeError('listener must be a function');
-
-if(!this._events||!this._events[type])
-return this;
-
-list=this._events[type];
-length=list.length;
-position=-1;
-
-if(list===listener||
-isFunction(list.listener)&&list.listener===listener){
-delete this._events[type];
-if(this._events.removeListener)
-this.emit('removeListener',type,listener);
-
-}else if(isObject(list)){
-for(i=length;i-->0;){
-if(list[i]===listener||
-list[i].listener&&list[i].listener===listener){
-position=i;
-break;
-}
-}
-
-if(position<0)
-return this;
-
-if(list.length===1){
-list.length=0;
-delete this._events[type];
-}else{
-list.splice(position,1);
-}
-
-if(this._events.removeListener)
-this.emit('removeListener',type,listener);
-}
-
-return this;
-};
-
-EventEmitter.prototype.removeAllListeners=function(type){
-var key,listeners;
-
-if(!this._events)
-return this;
-
-
-if(!this._events.removeListener){
-if(arguments.length===0)
-this._events={};else
-if(this._events[type])
-delete this._events[type];
-return this;
-}
-
-
-if(arguments.length===0){
-for(key in this._events){
-if(key==='removeListener')continue;
-this.removeAllListeners(key);
-}
-this.removeAllListeners('removeListener');
-this._events={};
-return this;
-}
-
-listeners=this._events[type];
-
-if(isFunction(listeners)){
-this.removeListener(type,listeners);
-}else if(listeners){
-
-while(listeners.length)
-this.removeListener(type,listeners[listeners.length-1]);
-}
-delete this._events[type];
-
-return this;
-};
-
-EventEmitter.prototype.listeners=function(type){
-var ret;
-if(!this._events||!this._events[type])
-ret=[];else
-if(isFunction(this._events[type]))
-ret=[this._events[type]];else
-
-ret=this._events[type].slice();
-return ret;
-};
-
-EventEmitter.prototype.listenerCount=function(type){
-if(this._events){
-var evlistener=this._events[type];
-
-if(isFunction(evlistener))
-return 1;else
-if(evlistener)
-return evlistener.length;
-}
-return 0;
-};
-
-EventEmitter.listenerCount=function(emitter,type){
-return emitter.listenerCount(type);
-};
-
-function isFunction(arg){
-return typeof arg==='function';
-}
-
-function isNumber(arg){
-return typeof arg==='number';
-}
-
-function isObject(arg){
-return typeof arg==='object'&&arg!==null;
-}
-
-function isUndefined(arg){
-return arg===void 0;
-}
-
-},{}],57:[function(require,module,exports){
-exports.read=function(buffer,offset,isLE,mLen,nBytes){
-var e,m;
-var eLen=nBytes*8-mLen-1;
-var eMax=(1<<eLen)-1;
-var eBias=eMax>>1;
-var nBits=-7;
-var i=isLE?nBytes-1:0;
-var d=isLE?-1:1;
-var s=buffer[offset+i];
-
-i+=d;
-
-e=s&(1<<-nBits)-1;
-s>>=-nBits;
-nBits+=eLen;
-for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}
-
-m=e&(1<<-nBits)-1;
-e>>=-nBits;
-nBits+=mLen;
-for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}
-
-if(e===0){
-e=1-eBias;
-}else if(e===eMax){
-return m?NaN:(s?-1:1)*Infinity;
-}else{
-m=m+Math.pow(2,mLen);
-e=e-eBias;
-}
-return(s?-1:1)*m*Math.pow(2,e-mLen);
-};
-
-exports.write=function(buffer,value,offset,isLE,mLen,nBytes){
-var e,m,c;
-var eLen=nBytes*8-mLen-1;
-var eMax=(1<<eLen)-1;
-var eBias=eMax>>1;
-var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;
-var i=isLE?0:nBytes-1;
-var d=isLE?1:-1;
-var s=value<0||value===0&&1/value<0?1:0;
-
-value=Math.abs(value);
-
-if(isNaN(value)||value===Infinity){
-m=isNaN(value)?1:0;
-e=eMax;
-}else{
-e=Math.floor(Math.log(value)/Math.LN2);
-if(value*(c=Math.pow(2,-e))<1){
-e--;
-c*=2;
-}
-if(e+eBias>=1){
-value+=rt/c;
-}else{
-value+=rt*Math.pow(2,1-eBias);
-}
-if(value*c>=2){
-e++;
-c/=2;
-}
-
-if(e+eBias>=eMax){
-m=0;
-e=eMax;
-}else if(e+eBias>=1){
-m=(value*c-1)*Math.pow(2,mLen);
-e=e+eBias;
-}else{
-m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);
-e=0;
-}
-}
-
-for(;mLen>=8;buffer[offset+i]=m&0xff,i+=d,m/=256,mLen-=8){}
-
-e=e<<mLen|m;
-eLen+=mLen;
-for(;eLen>0;buffer[offset+i]=e&0xff,i+=d,e/=256,eLen-=8){}
-
-buffer[offset+i-d]|=s*128;
-};
-
-},{}],58:[function(require,module,exports){
-if(typeof Object.create==='function'){
-
-module.exports=function inherits(ctor,superCtor){
-ctor.super_=superCtor;
-ctor.prototype=Object.create(superCtor.prototype,{
-constructor:{
-value:ctor,
-enumerable:false,
-writable:true,
-configurable:true}});
-
-
-};
-}else{
-
-module.exports=function inherits(ctor,superCtor){
-ctor.super_=superCtor;
-var TempCtor=function(){};
-TempCtor.prototype=superCtor.prototype;
-ctor.prototype=new TempCtor();
-ctor.prototype.constructor=ctor;
-};
-}
-
-},{}],59:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-module.exports=function(obj){
-return obj!=null&&(isBuffer(obj)||isSlowBuffer(obj)||!!obj._isBuffer);
-};
-
-function isBuffer(obj){
-return!!obj.constructor&&typeof obj.constructor.isBuffer==='function'&&obj.constructor.isBuffer(obj);
-}
-
-
-function isSlowBuffer(obj){
-return typeof obj.readFloatLE==='function'&&typeof obj.slice==='function'&&isBuffer(obj.slice(0,0));
-}
-
-},{}],60:[function(require,module,exports){
-var toString={}.toString;
-
-module.exports=Array.isArray||function(arr){
-return toString.call(arr)=='[object Array]';
-};
-
-},{}],61:[function(require,module,exports){
-'use strict';
-
-
-var TYPED_OK=typeof Uint8Array!=='undefined'&&
-typeof Uint16Array!=='undefined'&&
-typeof Int32Array!=='undefined';
-
-
-exports.assign=function(obj){
-var sources=Array.prototype.slice.call(arguments,1);
-while(sources.length){
-var source=sources.shift();
-if(!source){continue;}
-
-if(typeof source!=='object'){
-throw new TypeError(source+'must be non-object');
-}
-
-for(var p in source){
-if(source.hasOwnProperty(p)){
-obj[p]=source[p];
-}
-}
-}
-
-return obj;
-};
-
-
-
-exports.shrinkBuf=function(buf,size){
-if(buf.length===size){return buf;}
-if(buf.subarray){return buf.subarray(0,size);}
-buf.length=size;
-return buf;
-};
-
-
-var fnTyped={
-arraySet:function(dest,src,src_offs,len,dest_offs){
-if(src.subarray&&dest.subarray){
-dest.set(src.subarray(src_offs,src_offs+len),dest_offs);
-return;
-}
-
-for(var i=0;i<len;i++){
-dest[dest_offs+i]=src[src_offs+i];
-}
-},
-
-flattenChunks:function(chunks){
-var i,l,len,pos,chunk,result;
-
-
-len=0;
-for(i=0,l=chunks.length;i<l;i++){
-len+=chunks[i].length;
-}
-
-
-result=new Uint8Array(len);
-pos=0;
-for(i=0,l=chunks.length;i<l;i++){
-chunk=chunks[i];
-result.set(chunk,pos);
-pos+=chunk.length;
-}
-
-return result;
-}};
-
-
-var fnUntyped={
-arraySet:function(dest,src,src_offs,len,dest_offs){
-for(var i=0;i<len;i++){
-dest[dest_offs+i]=src[src_offs+i];
-}
-},
-
-flattenChunks:function(chunks){
-return[].concat.apply([],chunks);
-}};
-
-
-
-
-
-exports.setTyped=function(on){
-if(on){
-exports.Buf8=Uint8Array;
-exports.Buf16=Uint16Array;
-exports.Buf32=Int32Array;
-exports.assign(exports,fnTyped);
-}else{
-exports.Buf8=Array;
-exports.Buf16=Array;
-exports.Buf32=Array;
-exports.assign(exports,fnUntyped);
-}
-};
-
-exports.setTyped(TYPED_OK);
-
-},{}],62:[function(require,module,exports){
-'use strict';
-
-
-
-
-
-function adler32(adler,buf,len,pos){
-var s1=adler&0xffff|0,
-s2=adler>>>16&0xffff|0,
-n=0;
-
-while(len!==0){
-
-
-
-n=len>2000?2000:len;
-len-=n;
-
-do{
-s1=s1+buf[pos++]|0;
-s2=s2+s1|0;
-}while(--n);
-
-s1%=65521;
-s2%=65521;
-}
-
-return s1|s2<<16|0;
-}
-
-
-module.exports=adler32;
-
-},{}],63:[function(require,module,exports){
-'use strict';
-
-
-module.exports={
-
-
-Z_NO_FLUSH:0,
-Z_PARTIAL_FLUSH:1,
-Z_SYNC_FLUSH:2,
-Z_FULL_FLUSH:3,
-Z_FINISH:4,
-Z_BLOCK:5,
-Z_TREES:6,
-
-
-
-
-Z_OK:0,
-Z_STREAM_END:1,
-Z_NEED_DICT:2,
-Z_ERRNO:-1,
-Z_STREAM_ERROR:-2,
-Z_DATA_ERROR:-3,
-
-Z_BUF_ERROR:-5,
-
-
-
-Z_NO_COMPRESSION:0,
-Z_BEST_SPEED:1,
-Z_BEST_COMPRESSION:9,
-Z_DEFAULT_COMPRESSION:-1,
-
-
-Z_FILTERED:1,
-Z_HUFFMAN_ONLY:2,
-Z_RLE:3,
-Z_FIXED:4,
-Z_DEFAULT_STRATEGY:0,
-
-
-Z_BINARY:0,
-Z_TEXT:1,
-
-Z_UNKNOWN:2,
-
-
-Z_DEFLATED:8};
-
-
-
-},{}],64:[function(require,module,exports){
-'use strict';
-
-
-
-
-
-
-
-function makeTable(){
-var c,table=[];
-
-for(var n=0;n<256;n++){
-c=n;
-for(var k=0;k<8;k++){
-c=c&1?0xEDB88320^c>>>1:c>>>1;
-}
-table[n]=c;
-}
-
-return table;
-}
-
-
-var crcTable=makeTable();
-
-
-function crc32(crc,buf,len,pos){
-var t=crcTable,
-end=pos+len;
-
-crc^=-1;
-
-for(var i=pos;i<end;i++){
-crc=crc>>>8^t[(crc^buf[i])&0xFF];
-}
-
-return crc^-1;
-}
-
-
-module.exports=crc32;
-
-},{}],65:[function(require,module,exports){
-'use strict';
-
-var utils=require('../utils/common');
-var trees=require('./trees');
-var adler32=require('./adler32');
-var crc32=require('./crc32');
-var msg=require('./messages');
-
-
-
-
-
-
-var Z_NO_FLUSH=0;
-var Z_PARTIAL_FLUSH=1;
-
-var Z_FULL_FLUSH=3;
-var Z_FINISH=4;
-var Z_BLOCK=5;
-
-
-
-
-
-
-var Z_OK=0;
-var Z_STREAM_END=1;
-
-
-var Z_STREAM_ERROR=-2;
-var Z_DATA_ERROR=-3;
-
-var Z_BUF_ERROR=-5;
-
-
-
-
-
-
-
-var Z_DEFAULT_COMPRESSION=-1;
-
-
-var Z_FILTERED=1;
-var Z_HUFFMAN_ONLY=2;
-var Z_RLE=3;
-var Z_FIXED=4;
-var Z_DEFAULT_STRATEGY=0;
-
-
-
-
-
-var Z_UNKNOWN=2;
-
-
-
-var Z_DEFLATED=8;
-
-
-
-
-var MAX_MEM_LEVEL=9;
-
-var MAX_WBITS=15;
-
-var DEF_MEM_LEVEL=8;
-
-
-var LENGTH_CODES=29;
-
-var LITERALS=256;
-
-var L_CODES=LITERALS+1+LENGTH_CODES;
-
-var D_CODES=30;
-
-var BL_CODES=19;
-
-var HEAP_SIZE=2*L_CODES+1;
-
-var MAX_BITS=15;
-
-
-var MIN_MATCH=3;
-var MAX_MATCH=258;
-var MIN_LOOKAHEAD=MAX_MATCH+MIN_MATCH+1;
-
-var PRESET_DICT=0x20;
-
-var INIT_STATE=42;
-var EXTRA_STATE=69;
-var NAME_STATE=73;
-var COMMENT_STATE=91;
-var HCRC_STATE=103;
-var BUSY_STATE=113;
-var FINISH_STATE=666;
-
-var BS_NEED_MORE=1;
-var BS_BLOCK_DONE=2;
-var BS_FINISH_STARTED=3;
-var BS_FINISH_DONE=4;
-
-var OS_CODE=0x03;
-
-function err(strm,errorCode){
-strm.msg=msg[errorCode];
-return errorCode;
-}
-
-function rank(f){
-return(f<<1)-(f>4?9:0);
-}
-
-function zero(buf){var len=buf.length;while(--len>=0){buf[len]=0;}}
-
-
-
-
-
-
-
-
-function flush_pending(strm){
-var s=strm.state;
-
-
-var len=s.pending;
-if(len>strm.avail_out){
-len=strm.avail_out;
-}
-if(len===0){return;}
-
-utils.arraySet(strm.output,s.pending_buf,s.pending_out,len,strm.next_out);
-strm.next_out+=len;
-s.pending_out+=len;
-strm.total_out+=len;
-strm.avail_out-=len;
-s.pending-=len;
-if(s.pending===0){
-s.pending_out=0;
-}
-}
-
-
-function flush_block_only(s,last){
-trees._tr_flush_block(s,s.block_start>=0?s.block_start:-1,s.strstart-s.block_start,last);
-s.block_start=s.strstart;
-flush_pending(s.strm);
-}
-
-
-function put_byte(s,b){
-s.pending_buf[s.pending++]=b;
-}
-
-
-
-
-
-
-
-function putShortMSB(s,b){
-
-
-s.pending_buf[s.pending++]=b>>>8&0xff;
-s.pending_buf[s.pending++]=b&0xff;
-}
-
-
-
-
-
-
-
-
-
-function read_buf(strm,buf,start,size){
-var len=strm.avail_in;
-
-if(len>size){len=size;}
-if(len===0){return 0;}
-
-strm.avail_in-=len;
-
-
-utils.arraySet(buf,strm.input,strm.next_in,len,start);
-if(strm.state.wrap===1){
-strm.adler=adler32(strm.adler,buf,len,start);
-}else
-
-if(strm.state.wrap===2){
-strm.adler=crc32(strm.adler,buf,len,start);
-}
-
-strm.next_in+=len;
-strm.total_in+=len;
-
-return len;
-}
-
-
-
-
-
-
-
-
-
-
-
-function longest_match(s,cur_match){
-var chain_length=s.max_chain_length;
-var scan=s.strstart;
-var match;
-var len;
-var best_len=s.prev_length;
-var nice_match=s.nice_match;
-var limit=s.strstart>s.w_size-MIN_LOOKAHEAD?
-s.strstart-(s.w_size-MIN_LOOKAHEAD):0;
-
-var _win=s.window;
-
-var wmask=s.w_mask;
-var prev=s.prev;
-
-
-
-
-
-var strend=s.strstart+MAX_MATCH;
-var scan_end1=_win[scan+best_len-1];
-var scan_end=_win[scan+best_len];
-
-
-
-
-
-
-
-if(s.prev_length>=s.good_match){
-chain_length>>=2;
-}
-
-
-
-if(nice_match>s.lookahead){nice_match=s.lookahead;}
-
-
-
-do{
-
-match=cur_match;
-
-
-
-
-
-
-
-
-
-
-if(_win[match+best_len]!==scan_end||
-_win[match+best_len-1]!==scan_end1||
-_win[match]!==_win[scan]||
-_win[++match]!==_win[scan+1]){
-continue;
-}
-
-
-
-
-
-
-
-scan+=2;
-match++;
-
-
-
-
-
-do{
-
-}while(_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&
-_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&
-_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&
-_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&
-scan<strend);
-
-
-
-len=MAX_MATCH-(strend-scan);
-scan=strend-MAX_MATCH;
-
-if(len>best_len){
-s.match_start=cur_match;
-best_len=len;
-if(len>=nice_match){
-break;
-}
-scan_end1=_win[scan+best_len-1];
-scan_end=_win[scan+best_len];
-}
-}while((cur_match=prev[cur_match&wmask])>limit&&--chain_length!==0);
-
-if(best_len<=s.lookahead){
-return best_len;
-}
-return s.lookahead;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-function fill_window(s){
-var _w_size=s.w_size;
-var p,n,m,more,str;
-
-
-
-do{
-more=s.window_size-s.lookahead-s.strstart;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if(s.strstart>=_w_size+(_w_size-MIN_LOOKAHEAD)){
-
-utils.arraySet(s.window,s.window,_w_size,_w_size,0);
-s.match_start-=_w_size;
-s.strstart-=_w_size;
-
-s.block_start-=_w_size;
-
-
-
-
-
-
-
-
-n=s.hash_size;
-p=n;
-do{
-m=s.head[--p];
-s.head[p]=m>=_w_size?m-_w_size:0;
-}while(--n);
-
-n=_w_size;
-p=n;
-do{
-m=s.prev[--p];
-s.prev[p]=m>=_w_size?m-_w_size:0;
-
-
-
-}while(--n);
-
-more+=_w_size;
-}
-if(s.strm.avail_in===0){
-break;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-n=read_buf(s.strm,s.window,s.strstart+s.lookahead,more);
-s.lookahead+=n;
-
-
-if(s.lookahead+s.insert>=MIN_MATCH){
-str=s.strstart-s.insert;
-s.ins_h=s.window[str];
-
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[str+1])&s.hash_mask;
-
-
-
-while(s.insert){
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[str+MIN_MATCH-1])&s.hash_mask;
-
-s.prev[str&s.w_mask]=s.head[s.ins_h];
-s.head[s.ins_h]=str;
-str++;
-s.insert--;
-if(s.lookahead+s.insert<MIN_MATCH){
-break;
-}
-}
-}
-
-
-
-
-}while(s.lookahead<MIN_LOOKAHEAD&&s.strm.avail_in!==0);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-}
-
-
-
-
-
-
-
-
-
-
-function deflate_stored(s,flush){
-
-
-
-var max_block_size=0xffff;
-
-if(max_block_size>s.pending_buf_size-5){
-max_block_size=s.pending_buf_size-5;
-}
-
-
-for(;;){
-
-if(s.lookahead<=1){
-
-
-
-
-
-
-
-
-fill_window(s);
-if(s.lookahead===0&&flush===Z_NO_FLUSH){
-return BS_NEED_MORE;
-}
-
-if(s.lookahead===0){
-break;
-}
-
-}
-
-
-
-s.strstart+=s.lookahead;
-s.lookahead=0;
-
-
-var max_start=s.block_start+max_block_size;
-
-if(s.strstart===0||s.strstart>=max_start){
-
-s.lookahead=s.strstart-max_start;
-s.strstart=max_start;
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-
-
-}
-
-
-
-if(s.strstart-s.block_start>=s.w_size-MIN_LOOKAHEAD){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-}
-
-s.insert=0;
-
-if(flush===Z_FINISH){
-
-flush_block_only(s,true);
-if(s.strm.avail_out===0){
-return BS_FINISH_STARTED;
-}
-
-return BS_FINISH_DONE;
-}
-
-if(s.strstart>s.block_start){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-
-return BS_NEED_MORE;
-}
-
-
-
-
-
-
-
-
-function deflate_fast(s,flush){
-var hash_head;
-var bflush;
-
-for(;;){
-
-
-
-
-
-if(s.lookahead<MIN_LOOKAHEAD){
-fill_window(s);
-if(s.lookahead<MIN_LOOKAHEAD&&flush===Z_NO_FLUSH){
-return BS_NEED_MORE;
-}
-if(s.lookahead===0){
-break;
-}
-}
-
-
-
-
-hash_head=0;
-if(s.lookahead>=MIN_MATCH){
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[s.strstart+MIN_MATCH-1])&s.hash_mask;
-hash_head=s.prev[s.strstart&s.w_mask]=s.head[s.ins_h];
-s.head[s.ins_h]=s.strstart;
-
-}
-
-
-
-
-if(hash_head!==0&&s.strstart-hash_head<=s.w_size-MIN_LOOKAHEAD){
-
-
-
-
-s.match_length=longest_match(s,hash_head);
-
-}
-if(s.match_length>=MIN_MATCH){
-
-
-
-
-bflush=trees._tr_tally(s,s.strstart-s.match_start,s.match_length-MIN_MATCH);
-
-s.lookahead-=s.match_length;
-
-
-
-
-if(s.match_length<=s.max_lazy_match&&s.lookahead>=MIN_MATCH){
-s.match_length--;
-do{
-s.strstart++;
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[s.strstart+MIN_MATCH-1])&s.hash_mask;
-hash_head=s.prev[s.strstart&s.w_mask]=s.head[s.ins_h];
-s.head[s.ins_h]=s.strstart;
-
-
-
-
-}while(--s.match_length!==0);
-s.strstart++;
-}else
-{
-s.strstart+=s.match_length;
-s.match_length=0;
-s.ins_h=s.window[s.strstart];
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[s.strstart+1])&s.hash_mask;
-
-
-
-
-
-
-
-}
-}else{
-
-
-
-bflush=trees._tr_tally(s,0,s.window[s.strstart]);
-
-s.lookahead--;
-s.strstart++;
-}
-if(bflush){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-}
-s.insert=s.strstart<MIN_MATCH-1?s.strstart:MIN_MATCH-1;
-if(flush===Z_FINISH){
-
-flush_block_only(s,true);
-if(s.strm.avail_out===0){
-return BS_FINISH_STARTED;
-}
-
-return BS_FINISH_DONE;
-}
-if(s.last_lit){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-return BS_BLOCK_DONE;
-}
-
-
-
-
-
-
-function deflate_slow(s,flush){
-var hash_head;
-var bflush;
-
-var max_insert;
-
-
-for(;;){
-
-
-
-
-
-if(s.lookahead<MIN_LOOKAHEAD){
-fill_window(s);
-if(s.lookahead<MIN_LOOKAHEAD&&flush===Z_NO_FLUSH){
-return BS_NEED_MORE;
-}
-if(s.lookahead===0){break;}
-}
-
-
-
-
-hash_head=0;
-if(s.lookahead>=MIN_MATCH){
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[s.strstart+MIN_MATCH-1])&s.hash_mask;
-hash_head=s.prev[s.strstart&s.w_mask]=s.head[s.ins_h];
-s.head[s.ins_h]=s.strstart;
-
-}
-
-
-
-s.prev_length=s.match_length;
-s.prev_match=s.match_start;
-s.match_length=MIN_MATCH-1;
-
-if(hash_head!==0&&s.prev_length<s.max_lazy_match&&
-s.strstart-hash_head<=s.w_size-MIN_LOOKAHEAD){
-
-
-
-
-s.match_length=longest_match(s,hash_head);
-
-
-if(s.match_length<=5&&(
-s.strategy===Z_FILTERED||s.match_length===MIN_MATCH&&s.strstart-s.match_start>4096)){
-
-
-
-
-s.match_length=MIN_MATCH-1;
-}
-}
-
-
-
-if(s.prev_length>=MIN_MATCH&&s.match_length<=s.prev_length){
-max_insert=s.strstart+s.lookahead-MIN_MATCH;
-
-
-
-
-
-
-bflush=trees._tr_tally(s,s.strstart-1-s.prev_match,s.prev_length-MIN_MATCH);
-
-
-
-
-
-s.lookahead-=s.prev_length-1;
-s.prev_length-=2;
-do{
-if(++s.strstart<=max_insert){
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[s.strstart+MIN_MATCH-1])&s.hash_mask;
-hash_head=s.prev[s.strstart&s.w_mask]=s.head[s.ins_h];
-s.head[s.ins_h]=s.strstart;
-
-}
-}while(--s.prev_length!==0);
-s.match_available=0;
-s.match_length=MIN_MATCH-1;
-s.strstart++;
-
-if(bflush){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-
-}else if(s.match_available){
-
-
-
-
-
-
-bflush=trees._tr_tally(s,0,s.window[s.strstart-1]);
-
-if(bflush){
-
-flush_block_only(s,false);
-
-}
-s.strstart++;
-s.lookahead--;
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-}else{
-
-
-
-s.match_available=1;
-s.strstart++;
-s.lookahead--;
-}
-}
-
-if(s.match_available){
-
-
-bflush=trees._tr_tally(s,0,s.window[s.strstart-1]);
-
-s.match_available=0;
-}
-s.insert=s.strstart<MIN_MATCH-1?s.strstart:MIN_MATCH-1;
-if(flush===Z_FINISH){
-
-flush_block_only(s,true);
-if(s.strm.avail_out===0){
-return BS_FINISH_STARTED;
-}
-
-return BS_FINISH_DONE;
-}
-if(s.last_lit){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-
-return BS_BLOCK_DONE;
-}
-
-
-
-
-
-
-
-function deflate_rle(s,flush){
-var bflush;
-var prev;
-var scan,strend;
-
-var _win=s.window;
-
-for(;;){
-
-
-
-
-if(s.lookahead<=MAX_MATCH){
-fill_window(s);
-if(s.lookahead<=MAX_MATCH&&flush===Z_NO_FLUSH){
-return BS_NEED_MORE;
-}
-if(s.lookahead===0){break;}
-}
-
-
-s.match_length=0;
-if(s.lookahead>=MIN_MATCH&&s.strstart>0){
-scan=s.strstart-1;
-prev=_win[scan];
-if(prev===_win[++scan]&&prev===_win[++scan]&&prev===_win[++scan]){
-strend=s.strstart+MAX_MATCH;
-do{
-
-}while(prev===_win[++scan]&&prev===_win[++scan]&&
-prev===_win[++scan]&&prev===_win[++scan]&&
-prev===_win[++scan]&&prev===_win[++scan]&&
-prev===_win[++scan]&&prev===_win[++scan]&&
-scan<strend);
-s.match_length=MAX_MATCH-(strend-scan);
-if(s.match_length>s.lookahead){
-s.match_length=s.lookahead;
-}
-}
-
-}
-
-
-if(s.match_length>=MIN_MATCH){
-
-
-
-bflush=trees._tr_tally(s,1,s.match_length-MIN_MATCH);
-
-s.lookahead-=s.match_length;
-s.strstart+=s.match_length;
-s.match_length=0;
-}else{
-
-
-
-bflush=trees._tr_tally(s,0,s.window[s.strstart]);
-
-s.lookahead--;
-s.strstart++;
-}
-if(bflush){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-}
-s.insert=0;
-if(flush===Z_FINISH){
-
-flush_block_only(s,true);
-if(s.strm.avail_out===0){
-return BS_FINISH_STARTED;
-}
-
-return BS_FINISH_DONE;
-}
-if(s.last_lit){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-return BS_BLOCK_DONE;
-}
-
-
-
-
-
-function deflate_huff(s,flush){
-var bflush;
-
-for(;;){
-
-if(s.lookahead===0){
-fill_window(s);
-if(s.lookahead===0){
-if(flush===Z_NO_FLUSH){
-return BS_NEED_MORE;
-}
-break;
-}
-}
-
-
-s.match_length=0;
-
-
-bflush=trees._tr_tally(s,0,s.window[s.strstart]);
-s.lookahead--;
-s.strstart++;
-if(bflush){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-}
-s.insert=0;
-if(flush===Z_FINISH){
-
-flush_block_only(s,true);
-if(s.strm.avail_out===0){
-return BS_FINISH_STARTED;
-}
-
-return BS_FINISH_DONE;
-}
-if(s.last_lit){
-
-flush_block_only(s,false);
-if(s.strm.avail_out===0){
-return BS_NEED_MORE;
-}
-
-}
-return BS_BLOCK_DONE;
-}
-
-
-
-
-
-
-function Config(good_length,max_lazy,nice_length,max_chain,func){
-this.good_length=good_length;
-this.max_lazy=max_lazy;
-this.nice_length=nice_length;
-this.max_chain=max_chain;
-this.func=func;
-}
-
-var configuration_table;
-
-configuration_table=[
-
-new Config(0,0,0,0,deflate_stored),
-new Config(4,4,8,4,deflate_fast),
-new Config(4,5,16,8,deflate_fast),
-new Config(4,6,32,32,deflate_fast),
-
-new Config(4,4,16,16,deflate_slow),
-new Config(8,16,32,32,deflate_slow),
-new Config(8,16,128,128,deflate_slow),
-new Config(8,32,128,256,deflate_slow),
-new Config(32,128,258,1024,deflate_slow),
-new Config(32,258,258,4096,deflate_slow)];
-
-
-
-
-
-
-function lm_init(s){
-s.window_size=2*s.w_size;
-
-
-zero(s.head);
-
-
-
-s.max_lazy_match=configuration_table[s.level].max_lazy;
-s.good_match=configuration_table[s.level].good_length;
-s.nice_match=configuration_table[s.level].nice_length;
-s.max_chain_length=configuration_table[s.level].max_chain;
-
-s.strstart=0;
-s.block_start=0;
-s.lookahead=0;
-s.insert=0;
-s.match_length=s.prev_length=MIN_MATCH-1;
-s.match_available=0;
-s.ins_h=0;
-}
-
-
-function DeflateState(){
-this.strm=null;
-this.status=0;
-this.pending_buf=null;
-this.pending_buf_size=0;
-this.pending_out=0;
-this.pending=0;
-this.wrap=0;
-this.gzhead=null;
-this.gzindex=0;
-this.method=Z_DEFLATED;
-this.last_flush=-1;
-
-this.w_size=0;
-this.w_bits=0;
-this.w_mask=0;
-
-this.window=null;
-
-
-
-
-
-
-
-this.window_size=0;
-
-
-
-
-this.prev=null;
-
-
-
-
-
-this.head=null;
-
-this.ins_h=0;
-this.hash_size=0;
-this.hash_bits=0;
-this.hash_mask=0;
-
-this.hash_shift=0;
-
-
-
-
-
-
-this.block_start=0;
-
-
-
-
-this.match_length=0;
-this.prev_match=0;
-this.match_available=0;
-this.strstart=0;
-this.match_start=0;
-this.lookahead=0;
-
-this.prev_length=0;
-
-
-
-
-this.max_chain_length=0;
-
-
-
-
-
-this.max_lazy_match=0;
-
-
-
-
-
-
-
-
-
-
-
-this.level=0;
-this.strategy=0;
-
-this.good_match=0;
-
-
-this.nice_match=0;
-
-
-
-
-
-
-
-
-
-
-
-this.dyn_ltree=new utils.Buf16(HEAP_SIZE*2);
-this.dyn_dtree=new utils.Buf16((2*D_CODES+1)*2);
-this.bl_tree=new utils.Buf16((2*BL_CODES+1)*2);
-zero(this.dyn_ltree);
-zero(this.dyn_dtree);
-zero(this.bl_tree);
-
-this.l_desc=null;
-this.d_desc=null;
-this.bl_desc=null;
-
-
-this.bl_count=new utils.Buf16(MAX_BITS+1);
-
-
-
-this.heap=new utils.Buf16(2*L_CODES+1);
-zero(this.heap);
-
-this.heap_len=0;
-this.heap_max=0;
-
-
-
-
-this.depth=new utils.Buf16(2*L_CODES+1);
-zero(this.depth);
-
-
-
-this.l_buf=0;
-
-this.lit_bufsize=0;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-this.last_lit=0;
-
-this.d_buf=0;
-
-
-
-
-
-this.opt_len=0;
-this.static_len=0;
-this.matches=0;
-this.insert=0;
-
-
-this.bi_buf=0;
-
-
-
-this.bi_valid=0;
-
-
-
-
-
-
-
-
-
-
-
-
-}
-
-
-function deflateResetKeep(strm){
-var s;
-
-if(!strm||!strm.state){
-return err(strm,Z_STREAM_ERROR);
-}
-
-strm.total_in=strm.total_out=0;
-strm.data_type=Z_UNKNOWN;
-
-s=strm.state;
-s.pending=0;
-s.pending_out=0;
-
-if(s.wrap<0){
-s.wrap=-s.wrap;
-
-}
-s.status=s.wrap?INIT_STATE:BUSY_STATE;
-strm.adler=s.wrap===2?
-0:
-
-1;
-s.last_flush=Z_NO_FLUSH;
-trees._tr_init(s);
-return Z_OK;
-}
-
-
-function deflateReset(strm){
-var ret=deflateResetKeep(strm);
-if(ret===Z_OK){
-lm_init(strm.state);
-}
-return ret;
-}
-
-
-function deflateSetHeader(strm,head){
-if(!strm||!strm.state){return Z_STREAM_ERROR;}
-if(strm.state.wrap!==2){return Z_STREAM_ERROR;}
-strm.state.gzhead=head;
-return Z_OK;
-}
-
-
-function deflateInit2(strm,level,method,windowBits,memLevel,strategy){
-if(!strm){
-return Z_STREAM_ERROR;
-}
-var wrap=1;
-
-if(level===Z_DEFAULT_COMPRESSION){
-level=6;
-}
-
-if(windowBits<0){
-wrap=0;
-windowBits=-windowBits;
-}else
-
-if(windowBits>15){
-wrap=2;
-windowBits-=16;
-}
-
-
-if(memLevel<1||memLevel>MAX_MEM_LEVEL||method!==Z_DEFLATED||
-windowBits<8||windowBits>15||level<0||level>9||
-strategy<0||strategy>Z_FIXED){
-return err(strm,Z_STREAM_ERROR);
-}
-
-
-if(windowBits===8){
-windowBits=9;
-}
-
-
-var s=new DeflateState();
-
-strm.state=s;
-s.strm=strm;
-
-s.wrap=wrap;
-s.gzhead=null;
-s.w_bits=windowBits;
-s.w_size=1<<s.w_bits;
-s.w_mask=s.w_size-1;
-
-s.hash_bits=memLevel+7;
-s.hash_size=1<<s.hash_bits;
-s.hash_mask=s.hash_size-1;
-s.hash_shift=~~((s.hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
-s.window=new utils.Buf8(s.w_size*2);
-s.head=new utils.Buf16(s.hash_size);
-s.prev=new utils.Buf16(s.w_size);
-
-
-
-
-s.lit_bufsize=1<<memLevel+6;
-
-s.pending_buf_size=s.lit_bufsize*4;
-
-
-
-s.pending_buf=new utils.Buf8(s.pending_buf_size);
-
-
-
-s.d_buf=1*s.lit_bufsize;
-
-
-s.l_buf=(1+2)*s.lit_bufsize;
-
-s.level=level;
-s.strategy=strategy;
-s.method=method;
-
-return deflateReset(strm);
-}
-
-function deflateInit(strm,level){
-return deflateInit2(strm,level,Z_DEFLATED,MAX_WBITS,DEF_MEM_LEVEL,Z_DEFAULT_STRATEGY);
-}
-
-
-function deflate(strm,flush){
-var old_flush,s;
-var beg,val;
-
-if(!strm||!strm.state||
-flush>Z_BLOCK||flush<0){
-return strm?err(strm,Z_STREAM_ERROR):Z_STREAM_ERROR;
-}
-
-s=strm.state;
-
-if(!strm.output||
-!strm.input&&strm.avail_in!==0||
-s.status===FINISH_STATE&&flush!==Z_FINISH){
-return err(strm,strm.avail_out===0?Z_BUF_ERROR:Z_STREAM_ERROR);
-}
-
-s.strm=strm;
-old_flush=s.last_flush;
-s.last_flush=flush;
-
-
-if(s.status===INIT_STATE){
-
-if(s.wrap===2){
-strm.adler=0;
-put_byte(s,31);
-put_byte(s,139);
-put_byte(s,8);
-if(!s.gzhead){
-put_byte(s,0);
-put_byte(s,0);
-put_byte(s,0);
-put_byte(s,0);
-put_byte(s,0);
-put_byte(s,s.level===9?2:
-s.strategy>=Z_HUFFMAN_ONLY||s.level<2?
-4:0);
-put_byte(s,OS_CODE);
-s.status=BUSY_STATE;
-}else
-{
-put_byte(s,(s.gzhead.text?1:0)+(
-s.gzhead.hcrc?2:0)+(
-!s.gzhead.extra?0:4)+(
-!s.gzhead.name?0:8)+(
-!s.gzhead.comment?0:16));
-
-put_byte(s,s.gzhead.time&0xff);
-put_byte(s,s.gzhead.time>>8&0xff);
-put_byte(s,s.gzhead.time>>16&0xff);
-put_byte(s,s.gzhead.time>>24&0xff);
-put_byte(s,s.level===9?2:
-s.strategy>=Z_HUFFMAN_ONLY||s.level<2?
-4:0);
-put_byte(s,s.gzhead.os&0xff);
-if(s.gzhead.extra&&s.gzhead.extra.length){
-put_byte(s,s.gzhead.extra.length&0xff);
-put_byte(s,s.gzhead.extra.length>>8&0xff);
-}
-if(s.gzhead.hcrc){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending,0);
-}
-s.gzindex=0;
-s.status=EXTRA_STATE;
-}
-}else
-
-{
-var header=Z_DEFLATED+(s.w_bits-8<<4)<<8;
-var level_flags=-1;
-
-if(s.strategy>=Z_HUFFMAN_ONLY||s.level<2){
-level_flags=0;
-}else if(s.level<6){
-level_flags=1;
-}else if(s.level===6){
-level_flags=2;
-}else{
-level_flags=3;
-}
-header|=level_flags<<6;
-if(s.strstart!==0){header|=PRESET_DICT;}
-header+=31-header%31;
-
-s.status=BUSY_STATE;
-putShortMSB(s,header);
-
-
-if(s.strstart!==0){
-putShortMSB(s,strm.adler>>>16);
-putShortMSB(s,strm.adler&0xffff);
-}
-strm.adler=1;
-}
-}
-
-
-if(s.status===EXTRA_STATE){
-if(s.gzhead.extra){
-beg=s.pending;
-
-while(s.gzindex<(s.gzhead.extra.length&0xffff)){
-if(s.pending===s.pending_buf_size){
-if(s.gzhead.hcrc&&s.pending>beg){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);
-}
-flush_pending(strm);
-beg=s.pending;
-if(s.pending===s.pending_buf_size){
-break;
-}
-}
-put_byte(s,s.gzhead.extra[s.gzindex]&0xff);
-s.gzindex++;
-}
-if(s.gzhead.hcrc&&s.pending>beg){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);
-}
-if(s.gzindex===s.gzhead.extra.length){
-s.gzindex=0;
-s.status=NAME_STATE;
-}
-}else
-{
-s.status=NAME_STATE;
-}
-}
-if(s.status===NAME_STATE){
-if(s.gzhead.name){
-beg=s.pending;
-
-
-do{
-if(s.pending===s.pending_buf_size){
-if(s.gzhead.hcrc&&s.pending>beg){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);
-}
-flush_pending(strm);
-beg=s.pending;
-if(s.pending===s.pending_buf_size){
-val=1;
-break;
-}
-}
-
-if(s.gzindex<s.gzhead.name.length){
-val=s.gzhead.name.charCodeAt(s.gzindex++)&0xff;
-}else{
-val=0;
-}
-put_byte(s,val);
-}while(val!==0);
-
-if(s.gzhead.hcrc&&s.pending>beg){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);
-}
-if(val===0){
-s.gzindex=0;
-s.status=COMMENT_STATE;
-}
-}else
-{
-s.status=COMMENT_STATE;
-}
-}
-if(s.status===COMMENT_STATE){
-if(s.gzhead.comment){
-beg=s.pending;
-
-
-do{
-if(s.pending===s.pending_buf_size){
-if(s.gzhead.hcrc&&s.pending>beg){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);
-}
-flush_pending(strm);
-beg=s.pending;
-if(s.pending===s.pending_buf_size){
-val=1;
-break;
-}
-}
-
-if(s.gzindex<s.gzhead.comment.length){
-val=s.gzhead.comment.charCodeAt(s.gzindex++)&0xff;
-}else{
-val=0;
-}
-put_byte(s,val);
-}while(val!==0);
-
-if(s.gzhead.hcrc&&s.pending>beg){
-strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);
-}
-if(val===0){
-s.status=HCRC_STATE;
-}
-}else
-{
-s.status=HCRC_STATE;
-}
-}
-if(s.status===HCRC_STATE){
-if(s.gzhead.hcrc){
-if(s.pending+2>s.pending_buf_size){
-flush_pending(strm);
-}
-if(s.pending+2<=s.pending_buf_size){
-put_byte(s,strm.adler&0xff);
-put_byte(s,strm.adler>>8&0xff);
-strm.adler=0;
-s.status=BUSY_STATE;
-}
-}else
-{
-s.status=BUSY_STATE;
-}
-}
-
-
-
-if(s.pending!==0){
-flush_pending(strm);
-if(strm.avail_out===0){
-
-
-
-
-
-
-s.last_flush=-1;
-return Z_OK;
-}
-
-
-
-
-
-}else if(strm.avail_in===0&&rank(flush)<=rank(old_flush)&&
-flush!==Z_FINISH){
-return err(strm,Z_BUF_ERROR);
-}
-
-
-if(s.status===FINISH_STATE&&strm.avail_in!==0){
-return err(strm,Z_BUF_ERROR);
-}
-
-
-
-if(strm.avail_in!==0||s.lookahead!==0||
-flush!==Z_NO_FLUSH&&s.status!==FINISH_STATE){
-var bstate=s.strategy===Z_HUFFMAN_ONLY?deflate_huff(s,flush):
-s.strategy===Z_RLE?deflate_rle(s,flush):
-configuration_table[s.level].func(s,flush);
-
-if(bstate===BS_FINISH_STARTED||bstate===BS_FINISH_DONE){
-s.status=FINISH_STATE;
-}
-if(bstate===BS_NEED_MORE||bstate===BS_FINISH_STARTED){
-if(strm.avail_out===0){
-s.last_flush=-1;
-
-}
-return Z_OK;
-
-
-
-
-
-
-
-}
-if(bstate===BS_BLOCK_DONE){
-if(flush===Z_PARTIAL_FLUSH){
-trees._tr_align(s);
-}else
-if(flush!==Z_BLOCK){
-
-trees._tr_stored_block(s,0,0,false);
-
-
-
-if(flush===Z_FULL_FLUSH){
-
-zero(s.head);
-
-if(s.lookahead===0){
-s.strstart=0;
-s.block_start=0;
-s.insert=0;
-}
-}
-}
-flush_pending(strm);
-if(strm.avail_out===0){
-s.last_flush=-1;
-return Z_OK;
-}
-}
-}
-
-
-
-if(flush!==Z_FINISH){return Z_OK;}
-if(s.wrap<=0){return Z_STREAM_END;}
-
-
-if(s.wrap===2){
-put_byte(s,strm.adler&0xff);
-put_byte(s,strm.adler>>8&0xff);
-put_byte(s,strm.adler>>16&0xff);
-put_byte(s,strm.adler>>24&0xff);
-put_byte(s,strm.total_in&0xff);
-put_byte(s,strm.total_in>>8&0xff);
-put_byte(s,strm.total_in>>16&0xff);
-put_byte(s,strm.total_in>>24&0xff);
-}else
-
-{
-putShortMSB(s,strm.adler>>>16);
-putShortMSB(s,strm.adler&0xffff);
-}
-
-flush_pending(strm);
-
-
-
-if(s.wrap>0){s.wrap=-s.wrap;}
-
-return s.pending!==0?Z_OK:Z_STREAM_END;
-}
-
-function deflateEnd(strm){
-var status;
-
-if(!strm||!strm.state){
-return Z_STREAM_ERROR;
-}
-
-status=strm.state.status;
-if(status!==INIT_STATE&&
-status!==EXTRA_STATE&&
-status!==NAME_STATE&&
-status!==COMMENT_STATE&&
-status!==HCRC_STATE&&
-status!==BUSY_STATE&&
-status!==FINISH_STATE)
-{
-return err(strm,Z_STREAM_ERROR);
-}
-
-strm.state=null;
-
-return status===BUSY_STATE?err(strm,Z_DATA_ERROR):Z_OK;
-}
-
-
-
-
-
-
-function deflateSetDictionary(strm,dictionary){
-var dictLength=dictionary.length;
-
-var s;
-var str,n;
-var wrap;
-var avail;
-var next;
-var input;
-var tmpDict;
-
-if(!strm||!strm.state){
-return Z_STREAM_ERROR;
-}
-
-s=strm.state;
-wrap=s.wrap;
-
-if(wrap===2||wrap===1&&s.status!==INIT_STATE||s.lookahead){
-return Z_STREAM_ERROR;
-}
-
-
-if(wrap===1){
-
-strm.adler=adler32(strm.adler,dictionary,dictLength,0);
-}
-
-s.wrap=0;
-
-
-if(dictLength>=s.w_size){
-if(wrap===0){
-
-zero(s.head);
-s.strstart=0;
-s.block_start=0;
-s.insert=0;
-}
-
-
-tmpDict=new utils.Buf8(s.w_size);
-utils.arraySet(tmpDict,dictionary,dictLength-s.w_size,s.w_size,0);
-dictionary=tmpDict;
-dictLength=s.w_size;
-}
-
-avail=strm.avail_in;
-next=strm.next_in;
-input=strm.input;
-strm.avail_in=dictLength;
-strm.next_in=0;
-strm.input=dictionary;
-fill_window(s);
-while(s.lookahead>=MIN_MATCH){
-str=s.strstart;
-n=s.lookahead-(MIN_MATCH-1);
-do{
-
-s.ins_h=(s.ins_h<<s.hash_shift^s.window[str+MIN_MATCH-1])&s.hash_mask;
-
-s.prev[str&s.w_mask]=s.head[s.ins_h];
-
-s.head[s.ins_h]=str;
-str++;
-}while(--n);
-s.strstart=str;
-s.lookahead=MIN_MATCH-1;
-fill_window(s);
-}
-s.strstart+=s.lookahead;
-s.block_start=s.strstart;
-s.insert=s.lookahead;
-s.lookahead=0;
-s.match_length=s.prev_length=MIN_MATCH-1;
-s.match_available=0;
-strm.next_in=next;
-strm.input=input;
-strm.avail_in=avail;
-s.wrap=wrap;
-return Z_OK;
-}
-
-
-exports.deflateInit=deflateInit;
-exports.deflateInit2=deflateInit2;
-exports.deflateReset=deflateReset;
-exports.deflateResetKeep=deflateResetKeep;
-exports.deflateSetHeader=deflateSetHeader;
-exports.deflate=deflate;
-exports.deflateEnd=deflateEnd;
-exports.deflateSetDictionary=deflateSetDictionary;
-exports.deflateInfo='pako deflate (from Nodeca project)';
-
-
-
-
-
-
-
-
-
-
-},{"../utils/common":61,"./adler32":62,"./crc32":64,"./messages":66,"./trees":67}],66:[function(require,module,exports){
-'use strict';
-
-module.exports={
-2:'need dictionary',
-1:'stream end',
-0:'',
-'-1':'file error',
-'-2':'stream error',
-'-3':'data error',
-'-4':'insufficient memory',
-'-5':'buffer error',
-'-6':'incompatible version'};
-
-
-},{}],67:[function(require,module,exports){
-'use strict';
-
-
-var utils=require('../utils/common');
-
-
-
-
-
-
-
-
-var Z_FIXED=4;
-
-
-
-var Z_BINARY=0;
-var Z_TEXT=1;
-
-var Z_UNKNOWN=2;
-
-
-
-
-function zero(buf){var len=buf.length;while(--len>=0){buf[len]=0;}}
-
-
-
-var STORED_BLOCK=0;
-var STATIC_TREES=1;
-var DYN_TREES=2;
-
-
-var MIN_MATCH=3;
-var MAX_MATCH=258;
-
-
-
-
-
-
-
-var LENGTH_CODES=29;
-
-
-var LITERALS=256;
-
-
-var L_CODES=LITERALS+1+LENGTH_CODES;
-
-
-var D_CODES=30;
-
-
-var BL_CODES=19;
-
-
-var HEAP_SIZE=2*L_CODES+1;
-
-
-var MAX_BITS=15;
-
-
-var Buf_size=16;
-
-
-
-
-
-
-
-var MAX_BL_BITS=7;
-
-
-var END_BLOCK=256;
-
-
-var REP_3_6=16;
-
-
-var REPZ_3_10=17;
-
-
-var REPZ_11_138=18;
-
-
-
-var extra_lbits=
-[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
-
-var extra_dbits=
-[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
-
-var extra_blbits=
-[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
-
-var bl_order=
-[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
-
-
-
-
-
-
-
-
-
-
-
-
-var DIST_CODE_LEN=512;
-
-
-var static_ltree=new Array((L_CODES+2)*2);
-zero(static_ltree);
-
-
-
-
-
-
-var static_dtree=new Array(D_CODES*2);
-zero(static_dtree);
-
-
-
-
-var _dist_code=new Array(DIST_CODE_LEN);
-zero(_dist_code);
-
-
-
-
-
-var _length_code=new Array(MAX_MATCH-MIN_MATCH+1);
-zero(_length_code);
-
-
-var base_length=new Array(LENGTH_CODES);
-zero(base_length);
-
-
-var base_dist=new Array(D_CODES);
-zero(base_dist);
-
-
-
-function StaticTreeDesc(static_tree,extra_bits,extra_base,elems,max_length){
-
-this.static_tree=static_tree;
-this.extra_bits=extra_bits;
-this.extra_base=extra_base;
-this.elems=elems;
-this.max_length=max_length;
-
-
-this.has_stree=static_tree&&static_tree.length;
-}
-
-
-var static_l_desc;
-var static_d_desc;
-var static_bl_desc;
-
-
-function TreeDesc(dyn_tree,stat_desc){
-this.dyn_tree=dyn_tree;
-this.max_code=0;
-this.stat_desc=stat_desc;
-}
-
-
-
-function d_code(dist){
-return dist<256?_dist_code[dist]:_dist_code[256+(dist>>>7)];
-}
-
-
-
-
-
-
-function put_short(s,w){
-
-
-s.pending_buf[s.pending++]=w&0xff;
-s.pending_buf[s.pending++]=w>>>8&0xff;
-}
-
-
-
-
-
-
-function send_bits(s,value,length){
-if(s.bi_valid>Buf_size-length){
-s.bi_buf|=value<<s.bi_valid&0xffff;
-put_short(s,s.bi_buf);
-s.bi_buf=value>>Buf_size-s.bi_valid;
-s.bi_valid+=length-Buf_size;
-}else{
-s.bi_buf|=value<<s.bi_valid&0xffff;
-s.bi_valid+=length;
-}
-}
-
-
-function send_code(s,c,tree){
-send_bits(s,tree[c*2],tree[c*2+1]);
-}
-
-
-
-
-
-
-
-function bi_reverse(code,len){
-var res=0;
-do{
-res|=code&1;
-code>>>=1;
-res<<=1;
-}while(--len>0);
-return res>>>1;
-}
-
-
-
-
-
-function bi_flush(s){
-if(s.bi_valid===16){
-put_short(s,s.bi_buf);
-s.bi_buf=0;
-s.bi_valid=0;
-
-}else if(s.bi_valid>=8){
-s.pending_buf[s.pending++]=s.bi_buf&0xff;
-s.bi_buf>>=8;
-s.bi_valid-=8;
-}
-}
-
-
-
-
-
-
-
-
-
-
-
-
-function gen_bitlen(s,desc)
-
-
-{
-var tree=desc.dyn_tree;
-var max_code=desc.max_code;
-var stree=desc.stat_desc.static_tree;
-var has_stree=desc.stat_desc.has_stree;
-var extra=desc.stat_desc.extra_bits;
-var base=desc.stat_desc.extra_base;
-var max_length=desc.stat_desc.max_length;
-var h;
-var n,m;
-var bits;
-var xbits;
-var f;
-var overflow=0;
-
-for(bits=0;bits<=MAX_BITS;bits++){
-s.bl_count[bits]=0;
-}
-
-
-
-
-tree[s.heap[s.heap_max]*2+1]=0;
-
-for(h=s.heap_max+1;h<HEAP_SIZE;h++){
-n=s.heap[h];
-bits=tree[tree[n*2+1]*2+1]+1;
-if(bits>max_length){
-bits=max_length;
-overflow++;
-}
-tree[n*2+1]=bits;
-
-
-if(n>max_code){continue;}
-
-s.bl_count[bits]++;
-xbits=0;
-if(n>=base){
-xbits=extra[n-base];
-}
-f=tree[n*2];
-s.opt_len+=f*(bits+xbits);
-if(has_stree){
-s.static_len+=f*(stree[n*2+1]+xbits);
-}
-}
-if(overflow===0){return;}
-
-
-
-
-
-do{
-bits=max_length-1;
-while(s.bl_count[bits]===0){bits--;}
-s.bl_count[bits]--;
-s.bl_count[bits+1]+=2;
-s.bl_count[max_length]--;
-
-
-
-overflow-=2;
-}while(overflow>0);
-
-
-
-
-
-
-for(bits=max_length;bits!==0;bits--){
-n=s.bl_count[bits];
-while(n!==0){
-m=s.heap[--h];
-if(m>max_code){continue;}
-if(tree[m*2+1]!==bits){
-
-s.opt_len+=(bits-tree[m*2+1])*tree[m*2];
-tree[m*2+1]=bits;
-}
-n--;
-}
-}
-}
-
-
-
-
-
-
-
-
-
-
-function gen_codes(tree,max_code,bl_count)
-
-
-
-{
-var next_code=new Array(MAX_BITS+1);
-var code=0;
-var bits;
-var n;
-
-
-
-
-for(bits=1;bits<=MAX_BITS;bits++){
-next_code[bits]=code=code+bl_count[bits-1]<<1;
-}
-
-
-
-
-
-
-
-for(n=0;n<=max_code;n++){
-var len=tree[n*2+1];
-if(len===0){continue;}
-
-tree[n*2]=bi_reverse(next_code[len]++,len);
-
-
-
-}
-}
-
-
-
-
-
-function tr_static_init(){
-var n;
-var bits;
-var length;
-var code;
-var dist;
-var bl_count=new Array(MAX_BITS+1);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-length=0;
-for(code=0;code<LENGTH_CODES-1;code++){
-base_length[code]=length;
-for(n=0;n<1<<extra_lbits[code];n++){
-_length_code[length++]=code;
-}
-}
-
-
-
-
-
-_length_code[length-1]=code;
-
-
-dist=0;
-for(code=0;code<16;code++){
-base_dist[code]=dist;
-for(n=0;n<1<<extra_dbits[code];n++){
-_dist_code[dist++]=code;
-}
-}
-
-dist>>=7;
-for(;code<D_CODES;code++){
-base_dist[code]=dist<<7;
-for(n=0;n<1<<extra_dbits[code]-7;n++){
-_dist_code[256+dist++]=code;
-}
-}
-
-
-
-for(bits=0;bits<=MAX_BITS;bits++){
-bl_count[bits]=0;
-}
-
-n=0;
-while(n<=143){
-static_ltree[n*2+1]=8;
-n++;
-bl_count[8]++;
-}
-while(n<=255){
-static_ltree[n*2+1]=9;
-n++;
-bl_count[9]++;
-}
-while(n<=279){
-static_ltree[n*2+1]=7;
-n++;
-bl_count[7]++;
-}
-while(n<=287){
-static_ltree[n*2+1]=8;
-n++;
-bl_count[8]++;
-}
-
-
-
-
-gen_codes(static_ltree,L_CODES+1,bl_count);
-
-
-for(n=0;n<D_CODES;n++){
-static_dtree[n*2+1]=5;
-static_dtree[n*2]=bi_reverse(n,5);
-}
-
-
-static_l_desc=new StaticTreeDesc(static_ltree,extra_lbits,LITERALS+1,L_CODES,MAX_BITS);
-static_d_desc=new StaticTreeDesc(static_dtree,extra_dbits,0,D_CODES,MAX_BITS);
-static_bl_desc=new StaticTreeDesc(new Array(0),extra_blbits,0,BL_CODES,MAX_BL_BITS);
-
-
-}
-
-
-
-
-
-function init_block(s){
-var n;
-
-
-for(n=0;n<L_CODES;n++){s.dyn_ltree[n*2]=0;}
-for(n=0;n<D_CODES;n++){s.dyn_dtree[n*2]=0;}
-for(n=0;n<BL_CODES;n++){s.bl_tree[n*2]=0;}
-
-s.dyn_ltree[END_BLOCK*2]=1;
-s.opt_len=s.static_len=0;
-s.last_lit=s.matches=0;
-}
-
-
-
-
-
-function bi_windup(s)
-{
-if(s.bi_valid>8){
-put_short(s,s.bi_buf);
-}else if(s.bi_valid>0){
-
-s.pending_buf[s.pending++]=s.bi_buf;
-}
-s.bi_buf=0;
-s.bi_valid=0;
-}
-
-
-
-
-
-function copy_block(s,buf,len,header)
-
-
-
-
-{
-bi_windup(s);
-
-if(header){
-put_short(s,len);
-put_short(s,~len);
-}
-
-
-
-utils.arraySet(s.pending_buf,s.window,buf,len,s.pending);
-s.pending+=len;
-}
-
-
-
-
-
-function smaller(tree,n,m,depth){
-var _n2=n*2;
-var _m2=m*2;
-return tree[_n2]<tree[_m2]||
-tree[_n2]===tree[_m2]&&depth[n]<=depth[m];
-}
-
-
-
-
-
-
-
-function pqdownheap(s,tree,k)
-
-
-
-{
-var v=s.heap[k];
-var j=k<<1;
-while(j<=s.heap_len){
-
-if(j<s.heap_len&&
-smaller(tree,s.heap[j+1],s.heap[j],s.depth)){
-j++;
-}
-
-if(smaller(tree,v,s.heap[j],s.depth)){break;}
-
-
-s.heap[k]=s.heap[j];
-k=j;
-
-
-j<<=1;
-}
-s.heap[k]=v;
-}
-
-
-
-
-
-
-
-
-function compress_block(s,ltree,dtree)
-
-
-
-{
-var dist;
-var lc;
-var lx=0;
-var code;
-var extra;
-
-if(s.last_lit!==0){
-do{
-dist=s.pending_buf[s.d_buf+lx*2]<<8|s.pending_buf[s.d_buf+lx*2+1];
-lc=s.pending_buf[s.l_buf+lx];
-lx++;
-
-if(dist===0){
-send_code(s,lc,ltree);
-
-}else{
-
-code=_length_code[lc];
-send_code(s,code+LITERALS+1,ltree);
-extra=extra_lbits[code];
-if(extra!==0){
-lc-=base_length[code];
-send_bits(s,lc,extra);
-}
-dist--;
-code=d_code(dist);
-
-
-send_code(s,code,dtree);
-extra=extra_dbits[code];
-if(extra!==0){
-dist-=base_dist[code];
-send_bits(s,dist,extra);
-}
-}
-
-
-
-
-
-}while(lx<s.last_lit);
-}
-
-send_code(s,END_BLOCK,ltree);
-}
-
-
-
-
-
-
-
-
-
-
-function build_tree(s,desc)
-
-
-{
-var tree=desc.dyn_tree;
-var stree=desc.stat_desc.static_tree;
-var has_stree=desc.stat_desc.has_stree;
-var elems=desc.stat_desc.elems;
-var n,m;
-var max_code=-1;
-var node;
-
-
-
-
-
-s.heap_len=0;
-s.heap_max=HEAP_SIZE;
-
-for(n=0;n<elems;n++){
-if(tree[n*2]!==0){
-s.heap[++s.heap_len]=max_code=n;
-s.depth[n]=0;
-
-}else{
-tree[n*2+1]=0;
-}
-}
-
-
-
-
-
-
-while(s.heap_len<2){
-node=s.heap[++s.heap_len]=max_code<2?++max_code:0;
-tree[node*2]=1;
-s.depth[node]=0;
-s.opt_len--;
-
-if(has_stree){
-s.static_len-=stree[node*2+1];
-}
-
-}
-desc.max_code=max_code;
-
-
-
-
-for(n=s.heap_len>>1;n>=1;n--){pqdownheap(s,tree,n);}
-
-
-
-
-node=elems;
-do{
-
-
-n=s.heap[1];
-s.heap[1]=s.heap[s.heap_len--];
-pqdownheap(s,tree,1);
-
-
-m=s.heap[1];
-
-s.heap[--s.heap_max]=n;
-s.heap[--s.heap_max]=m;
-
-
-tree[node*2]=tree[n*2]+tree[m*2];
-s.depth[node]=(s.depth[n]>=s.depth[m]?s.depth[n]:s.depth[m])+1;
-tree[n*2+1]=tree[m*2+1]=node;
-
-
-s.heap[1]=node++;
-pqdownheap(s,tree,1);
-
-}while(s.heap_len>=2);
-
-s.heap[--s.heap_max]=s.heap[1];
-
-
-
-
-gen_bitlen(s,desc);
-
-
-gen_codes(tree,max_code,s.bl_count);
-}
-
-
-
-
-
-
-function scan_tree(s,tree,max_code)
-
-
-
-{
-var n;
-var prevlen=-1;
-var curlen;
-
-var nextlen=tree[0*2+1];
-
-var count=0;
-var max_count=7;
-var min_count=4;
-
-if(nextlen===0){
-max_count=138;
-min_count=3;
-}
-tree[(max_code+1)*2+1]=0xffff;
-
-for(n=0;n<=max_code;n++){
-curlen=nextlen;
-nextlen=tree[(n+1)*2+1];
-
-if(++count<max_count&&curlen===nextlen){
-continue;
-
-}else if(count<min_count){
-s.bl_tree[curlen*2]+=count;
-
-}else if(curlen!==0){
-
-if(curlen!==prevlen){s.bl_tree[curlen*2]++;}
-s.bl_tree[REP_3_6*2]++;
-
-}else if(count<=10){
-s.bl_tree[REPZ_3_10*2]++;
-
-}else{
-s.bl_tree[REPZ_11_138*2]++;
-}
-
-count=0;
-prevlen=curlen;
-
-if(nextlen===0){
-max_count=138;
-min_count=3;
-
-}else if(curlen===nextlen){
-max_count=6;
-min_count=3;
-
-}else{
-max_count=7;
-min_count=4;
-}
-}
-}
-
-
-
-
-
-
-function send_tree(s,tree,max_code)
-
-
-
-{
-var n;
-var prevlen=-1;
-var curlen;
-
-var nextlen=tree[0*2+1];
-
-var count=0;
-var max_count=7;
-var min_count=4;
-
-
-if(nextlen===0){
-max_count=138;
-min_count=3;
-}
-
-for(n=0;n<=max_code;n++){
-curlen=nextlen;
-nextlen=tree[(n+1)*2+1];
-
-if(++count<max_count&&curlen===nextlen){
-continue;
-
-}else if(count<min_count){
-do{send_code(s,curlen,s.bl_tree);}while(--count!==0);
-
-}else if(curlen!==0){
-if(curlen!==prevlen){
-send_code(s,curlen,s.bl_tree);
-count--;
-}
-
-send_code(s,REP_3_6,s.bl_tree);
-send_bits(s,count-3,2);
-
-}else if(count<=10){
-send_code(s,REPZ_3_10,s.bl_tree);
-send_bits(s,count-3,3);
-
-}else{
-send_code(s,REPZ_11_138,s.bl_tree);
-send_bits(s,count-11,7);
-}
-
-count=0;
-prevlen=curlen;
-if(nextlen===0){
-max_count=138;
-min_count=3;
-
-}else if(curlen===nextlen){
-max_count=6;
-min_count=3;
-
-}else{
-max_count=7;
-min_count=4;
-}
-}
-}
-
-
-
-
-
-
-function build_bl_tree(s){
-var max_blindex;
-
-
-scan_tree(s,s.dyn_ltree,s.l_desc.max_code);
-scan_tree(s,s.dyn_dtree,s.d_desc.max_code);
-
-
-build_tree(s,s.bl_desc);
-
-
-
-
-
-
-
-
-for(max_blindex=BL_CODES-1;max_blindex>=3;max_blindex--){
-if(s.bl_tree[bl_order[max_blindex]*2+1]!==0){
-break;
-}
-}
-
-s.opt_len+=3*(max_blindex+1)+5+5+4;
-
-
-
-return max_blindex;
-}
-
-
-
-
-
-
-
-function send_all_trees(s,lcodes,dcodes,blcodes)
-
-
-{
-var rank;
-
-
-
-
-
-send_bits(s,lcodes-257,5);
-send_bits(s,dcodes-1,5);
-send_bits(s,blcodes-4,4);
-for(rank=0;rank<blcodes;rank++){
-
-send_bits(s,s.bl_tree[bl_order[rank]*2+1],3);
-}
-
-
-send_tree(s,s.dyn_ltree,lcodes-1);
-
-
-send_tree(s,s.dyn_dtree,dcodes-1);
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function detect_data_type(s){
-
-
-
-
-var black_mask=0xf3ffc07f;
-var n;
-
-
-for(n=0;n<=31;n++,black_mask>>>=1){
-if(black_mask&1&&s.dyn_ltree[n*2]!==0){
-return Z_BINARY;
-}
-}
-
-
-if(s.dyn_ltree[9*2]!==0||s.dyn_ltree[10*2]!==0||
-s.dyn_ltree[13*2]!==0){
-return Z_TEXT;
-}
-for(n=32;n<LITERALS;n++){
-if(s.dyn_ltree[n*2]!==0){
-return Z_TEXT;
-}
-}
-
-
-
-
-return Z_BINARY;
-}
-
-
-var static_init_done=false;
-
-
-
-
-function _tr_init(s)
-{
-
-if(!static_init_done){
-tr_static_init();
-static_init_done=true;
-}
-
-s.l_desc=new TreeDesc(s.dyn_ltree,static_l_desc);
-s.d_desc=new TreeDesc(s.dyn_dtree,static_d_desc);
-s.bl_desc=new TreeDesc(s.bl_tree,static_bl_desc);
-
-s.bi_buf=0;
-s.bi_valid=0;
-
-
-init_block(s);
-}
-
-
-
-
-
-function _tr_stored_block(s,buf,stored_len,last)
-
-
-
-
-{
-send_bits(s,(STORED_BLOCK<<1)+(last?1:0),3);
-copy_block(s,buf,stored_len,true);
-}
-
-
-
-
-
-
-function _tr_align(s){
-send_bits(s,STATIC_TREES<<1,3);
-send_code(s,END_BLOCK,static_ltree);
-bi_flush(s);
-}
-
-
-
-
-
-
-function _tr_flush_block(s,buf,stored_len,last)
-
-
-
-
-{
-var opt_lenb,static_lenb;
-var max_blindex=0;
-
-
-if(s.level>0){
-
-
-if(s.strm.data_type===Z_UNKNOWN){
-s.strm.data_type=detect_data_type(s);
-}
-
-
-build_tree(s,s.l_desc);
-
-
-
-build_tree(s,s.d_desc);
-
-
-
-
-
-
-
-
-
-max_blindex=build_bl_tree(s);
-
-
-opt_lenb=s.opt_len+3+7>>>3;
-static_lenb=s.static_len+3+7>>>3;
-
-
-
-
-
-if(static_lenb<=opt_lenb){opt_lenb=static_lenb;}
-
-}else{
-
-opt_lenb=static_lenb=stored_len+5;
-}
-
-if(stored_len+4<=opt_lenb&&buf!==-1){
-
-
-
-
-
-
-
-
-_tr_stored_block(s,buf,stored_len,last);
-
-}else if(s.strategy===Z_FIXED||static_lenb===opt_lenb){
-
-send_bits(s,(STATIC_TREES<<1)+(last?1:0),3);
-compress_block(s,static_ltree,static_dtree);
-
-}else{
-send_bits(s,(DYN_TREES<<1)+(last?1:0),3);
-send_all_trees(s,s.l_desc.max_code+1,s.d_desc.max_code+1,max_blindex+1);
-compress_block(s,s.dyn_ltree,s.dyn_dtree);
-}
-
-
-
-
-init_block(s);
-
-if(last){
-bi_windup(s);
-}
-
-
-}
-
-
-
-
-
-function _tr_tally(s,dist,lc)
-
-
-
-{
-
-
-s.pending_buf[s.d_buf+s.last_lit*2]=dist>>>8&0xff;
-s.pending_buf[s.d_buf+s.last_lit*2+1]=dist&0xff;
-
-s.pending_buf[s.l_buf+s.last_lit]=lc&0xff;
-s.last_lit++;
-
-if(dist===0){
-
-s.dyn_ltree[lc*2]++;
-}else{
-s.matches++;
-
-dist--;
-
-
-
-
-s.dyn_ltree[(_length_code[lc]+LITERALS+1)*2]++;
-s.dyn_dtree[d_code(dist)*2]++;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-return s.last_lit===s.lit_bufsize-1;
-
-
-
-
-}
-
-exports._tr_init=_tr_init;
-exports._tr_stored_block=_tr_stored_block;
-exports._tr_flush_block=_tr_flush_block;
-exports._tr_tally=_tr_tally;
-exports._tr_align=_tr_align;
-
-},{"../utils/common":61}],68:[function(require,module,exports){
-'use strict';
-
-
-function ZStream(){
-
-this.input=null;
-this.next_in=0;
-
-this.avail_in=0;
-
-this.total_in=0;
-
-this.output=null;
-this.next_out=0;
-
-this.avail_out=0;
-
-this.total_out=0;
-
-this.msg='';
-
-this.state=null;
-
-this.data_type=2;
-
-this.adler=0;
-}
-
-module.exports=ZStream;
-
-},{}],69:[function(require,module,exports){
-(function(process){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function normalizeArray(parts,allowAboveRoot){
-
-var up=0;
-for(var i=parts.length-1;i>=0;i--){
-var last=parts[i];
-if(last==='.'){
-parts.splice(i,1);
-}else if(last==='..'){
-parts.splice(i,1);
-up++;
-}else if(up){
-parts.splice(i,1);
-up--;
-}
-}
-
-
-if(allowAboveRoot){
-for(;up--;up){
-parts.unshift('..');
-}
-}
-
-return parts;
-}
-
-
-
-var splitPathRe=
-/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
-var splitPath=function(filename){
-return splitPathRe.exec(filename).slice(1);
-};
-
-
-
-exports.resolve=function(){
-var resolvedPath='',
-resolvedAbsolute=false;
-
-for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){
-var path=i>=0?arguments[i]:process.cwd();
-
-
-if(typeof path!=='string'){
-throw new TypeError('Arguments to path.resolve must be strings');
-}else if(!path){
-continue;
-}
-
-resolvedPath=path+'/'+resolvedPath;
-resolvedAbsolute=path.charAt(0)==='/';
-}
-
-
-
-
-
-resolvedPath=normalizeArray(filter(resolvedPath.split('/'),function(p){
-return!!p;
-}),!resolvedAbsolute).join('/');
-
-return(resolvedAbsolute?'/':'')+resolvedPath||'.';
-};
-
-
-
-exports.normalize=function(path){
-var isAbsolute=exports.isAbsolute(path),
-trailingSlash=substr(path,-1)==='/';
-
-
-path=normalizeArray(filter(path.split('/'),function(p){
-return!!p;
-}),!isAbsolute).join('/');
-
-if(!path&&!isAbsolute){
-path='.';
-}
-if(path&&trailingSlash){
-path+='/';
-}
-
-return(isAbsolute?'/':'')+path;
-};
-
-
-exports.isAbsolute=function(path){
-return path.charAt(0)==='/';
-};
-
-
-exports.join=function(){
-var paths=Array.prototype.slice.call(arguments,0);
-return exports.normalize(filter(paths,function(p,index){
-if(typeof p!=='string'){
-throw new TypeError('Arguments to path.join must be strings');
-}
-return p;
-}).join('/'));
-};
-
-
-
-
-exports.relative=function(from,to){
-from=exports.resolve(from).substr(1);
-to=exports.resolve(to).substr(1);
-
-function trim(arr){
-var start=0;
-for(;start<arr.length;start++){
-if(arr[start]!=='')break;
-}
-
-var end=arr.length-1;
-for(;end>=0;end--){
-if(arr[end]!=='')break;
-}
-
-if(start>end)return[];
-return arr.slice(start,end-start+1);
-}
-
-var fromParts=trim(from.split('/'));
-var toParts=trim(to.split('/'));
-
-var length=Math.min(fromParts.length,toParts.length);
-var samePartsLength=length;
-for(var i=0;i<length;i++){
-if(fromParts[i]!==toParts[i]){
-samePartsLength=i;
-break;
-}
-}
-
-var outputParts=[];
-for(var i=samePartsLength;i<fromParts.length;i++){
-outputParts.push('..');
-}
-
-outputParts=outputParts.concat(toParts.slice(samePartsLength));
-
-return outputParts.join('/');
-};
-
-exports.sep='/';
-exports.delimiter=':';
-
-exports.dirname=function(path){
-var result=splitPath(path),
-root=result[0],
-dir=result[1];
-
-if(!root&&!dir){
-
-return'.';
-}
-
-if(dir){
-
-dir=dir.substr(0,dir.length-1);
-}
-
-return root+dir;
-};
-
-
-exports.basename=function(path,ext){
-var f=splitPath(path)[2];
-
-if(ext&&f.substr(-1*ext.length)===ext){
-f=f.substr(0,f.length-ext.length);
-}
-return f;
-};
-
-
-exports.extname=function(path){
-return splitPath(path)[3];
-};
-
-function filter(xs,f){
-if(xs.filter)return xs.filter(f);
-var res=[];
-for(var i=0;i<xs.length;i++){
-if(f(xs[i],i,xs))res.push(xs[i]);
-}
-return res;
-}
-
-
-var substr='ab'.substr(-1)==='b'?
-function(str,start,len){return str.substr(start,len);}:
-function(str,start,len){
-if(start<0)start=str.length+start;
-return str.substr(start,len);
-};
-
-
-}).call(this,require('_process'));
-},{"_process":71}],70:[function(require,module,exports){
-(function(process){
-'use strict';
-
-if(!process.version||
-process.version.indexOf('v0.')===0||
-process.version.indexOf('v1.')===0&&process.version.indexOf('v1.8.')!==0){
-module.exports=nextTick;
-}else{
-module.exports=process.nextTick;
-}
-
-function nextTick(fn,arg1,arg2,arg3){
-if(typeof fn!=='function'){
-throw new TypeError('"callback" argument must be a function');
-}
-var len=arguments.length;
-var args,i;
-switch(len){
-case 0:
-case 1:
-return process.nextTick(fn);
-case 2:
-return process.nextTick(function afterTickOne(){
-fn.call(null,arg1);
-});
-case 3:
-return process.nextTick(function afterTickTwo(){
-fn.call(null,arg1,arg2);
-});
-case 4:
-return process.nextTick(function afterTickThree(){
-fn.call(null,arg1,arg2,arg3);
-});
-default:
-args=new Array(len-1);
-i=0;
-while(i<args.length){
-args[i++]=arguments[i];
-}
-return process.nextTick(function afterTick(){
-fn.apply(null,args);
-});}
-
-}
-
-}).call(this,require('_process'));
-},{"_process":71}],71:[function(require,module,exports){
-
-var process=module.exports={};
-
-
-
-
-
-
-var cachedSetTimeout;
-var cachedClearTimeout;
-
-function defaultSetTimout(){
-throw new Error('setTimeout has not been defined');
-}
-function defaultClearTimeout(){
-throw new Error('clearTimeout has not been defined');
-}
-(function(){
-try{
-if(typeof setTimeout==='function'){
-cachedSetTimeout=setTimeout;
-}else{
-cachedSetTimeout=defaultSetTimout;
-}
-}catch(e){
-cachedSetTimeout=defaultSetTimout;
-}
-try{
-if(typeof clearTimeout==='function'){
-cachedClearTimeout=clearTimeout;
-}else{
-cachedClearTimeout=defaultClearTimeout;
-}
-}catch(e){
-cachedClearTimeout=defaultClearTimeout;
-}
-})();
-function runTimeout(fun){
-if(cachedSetTimeout===setTimeout){
-
-return setTimeout(fun,0);
-}
-
-if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){
-cachedSetTimeout=setTimeout;
-return setTimeout(fun,0);
-}
-try{
-
-return cachedSetTimeout(fun,0);
-}catch(e){
-try{
-
-return cachedSetTimeout.call(null,fun,0);
-}catch(e){
-
-return cachedSetTimeout.call(this,fun,0);
-}
-}
-
-
-}
-function runClearTimeout(marker){
-if(cachedClearTimeout===clearTimeout){
-
-return clearTimeout(marker);
-}
-
-if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){
-cachedClearTimeout=clearTimeout;
-return clearTimeout(marker);
-}
-try{
-
-return cachedClearTimeout(marker);
-}catch(e){
-try{
-
-return cachedClearTimeout.call(null,marker);
-}catch(e){
-
-
-return cachedClearTimeout.call(this,marker);
-}
-}
-
-
-
-}
-var queue=[];
-var draining=false;
-var currentQueue;
-var queueIndex=-1;
-
-function cleanUpNextTick(){
-if(!draining||!currentQueue){
-return;
-}
-draining=false;
-if(currentQueue.length){
-queue=currentQueue.concat(queue);
-}else{
-queueIndex=-1;
-}
-if(queue.length){
-drainQueue();
-}
-}
-
-function drainQueue(){
-if(draining){
-return;
-}
-var timeout=runTimeout(cleanUpNextTick);
-draining=true;
-
-var len=queue.length;
-while(len){
-currentQueue=queue;
-queue=[];
-while(++queueIndex<len){
-if(currentQueue){
-currentQueue[queueIndex].run();
-}
-}
-queueIndex=-1;
-len=queue.length;
-}
-currentQueue=null;
-draining=false;
-runClearTimeout(timeout);
-}
-
-process.nextTick=function(fun){
-var args=new Array(arguments.length-1);
-if(arguments.length>1){
-for(var i=1;i<arguments.length;i++){
-args[i-1]=arguments[i];
-}
-}
-queue.push(new Item(fun,args));
-if(queue.length===1&&!draining){
-runTimeout(drainQueue);
-}
-};
-
-
-function Item(fun,array){
-this.fun=fun;
-this.array=array;
-}
-Item.prototype.run=function(){
-this.fun.apply(null,this.array);
-};
-process.title='browser';
-process.browser=true;
-process.env={};
-process.argv=[];
-process.version='';
-process.versions={};
-
-function noop(){}
-
-process.on=noop;
-process.addListener=noop;
-process.once=noop;
-process.off=noop;
-process.removeListener=noop;
-process.removeAllListeners=noop;
-process.emit=noop;
-
-process.binding=function(name){
-throw new Error('process.binding is not supported');
-};
-
-process.cwd=function(){return'/';};
-process.chdir=function(dir){
-throw new Error('process.chdir is not supported');
-};
-process.umask=function(){return 0;};
-
-},{}],72:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-
-
-
-function hasOwnProperty(obj,prop){
-return Object.prototype.hasOwnProperty.call(obj,prop);
-}
-
-module.exports=function(qs,sep,eq,options){
-sep=sep||'&';
-eq=eq||'=';
-var obj={};
-
-if(typeof qs!=='string'||qs.length===0){
-return obj;
-}
-
-var regexp=/\+/g;
-qs=qs.split(sep);
-
-var maxKeys=1000;
-if(options&&typeof options.maxKeys==='number'){
-maxKeys=options.maxKeys;
-}
-
-var len=qs.length;
-
-if(maxKeys>0&&len>maxKeys){
-len=maxKeys;
-}
-
-for(var i=0;i<len;++i){
-var x=qs[i].replace(regexp,'%20'),
-idx=x.indexOf(eq),
-kstr,vstr,k,v;
-
-if(idx>=0){
-kstr=x.substr(0,idx);
-vstr=x.substr(idx+1);
-}else{
-kstr=x;
-vstr='';
-}
-
-k=decodeURIComponent(kstr);
-v=decodeURIComponent(vstr);
-
-if(!hasOwnProperty(obj,k)){
-obj[k]=v;
-}else if(isArray(obj[k])){
-obj[k].push(v);
-}else{
-obj[k]=[obj[k],v];
-}
-}
-
-return obj;
-};
-
-var isArray=Array.isArray||function(xs){
-return Object.prototype.toString.call(xs)==='[object Array]';
-};
-
-},{}],73:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-var stringifyPrimitive=function(v){
-switch(typeof v){
-case'string':
-return v;
-
-case'boolean':
-return v?'true':'false';
-
-case'number':
-return isFinite(v)?v:'';
-
-default:
-return'';}
-
-};
-
-module.exports=function(obj,sep,eq,name){
-sep=sep||'&';
-eq=eq||'=';
-if(obj===null){
-obj=undefined;
-}
-
-if(typeof obj==='object'){
-return map(objectKeys(obj),function(k){
-var ks=encodeURIComponent(stringifyPrimitive(k))+eq;
-if(isArray(obj[k])){
-return map(obj[k],function(v){
-return ks+encodeURIComponent(stringifyPrimitive(v));
-}).join(sep);
-}else{
-return ks+encodeURIComponent(stringifyPrimitive(obj[k]));
-}
-}).join(sep);
-
-}
-
-if(!name)return'';
-return encodeURIComponent(stringifyPrimitive(name))+eq+
-encodeURIComponent(stringifyPrimitive(obj));
-};
-
-var isArray=Array.isArray||function(xs){
-return Object.prototype.toString.call(xs)==='[object Array]';
-};
-
-function map(xs,f){
-if(xs.map)return xs.map(f);
-var res=[];
-for(var i=0;i<xs.length;i++){
-res.push(f(xs[i],i));
-}
-return res;
-}
-
-var objectKeys=Object.keys||function(obj){
-var res=[];
-for(var key in obj){
-if(Object.prototype.hasOwnProperty.call(obj,key))res.push(key);
-}
-return res;
-};
-
-},{}],74:[function(require,module,exports){
-'use strict';
-
-exports.decode=exports.parse=require('./decode');
-exports.encode=exports.stringify=require('./encode');
-
-},{"./decode":72,"./encode":73}],75:[function(require,module,exports){
-module.exports=require("./lib/_stream_duplex.js");
-
-},{"./lib/_stream_duplex.js":76}],76:[function(require,module,exports){
-
-
-
-
-
-'use strict';
-
-
-
-var objectKeys=Object.keys||function(obj){
-var keys=[];
-for(var key in obj){
-keys.push(key);
-}return keys;
-};
-
-
-module.exports=Duplex;
-
-
-var processNextTick=require('process-nextick-args');
-
-
-
-var util=require('core-util-is');
-util.inherits=require('inherits');
-
-
-var Readable=require('./_stream_readable');
-var Writable=require('./_stream_writable');
-
-util.inherits(Duplex,Readable);
-
-var keys=objectKeys(Writable.prototype);
-for(var v=0;v<keys.length;v++){
-var method=keys[v];
-if(!Duplex.prototype[method])Duplex.prototype[method]=Writable.prototype[method];
-}
-
-function Duplex(options){
-if(!(this instanceof Duplex))return new Duplex(options);
-
-Readable.call(this,options);
-Writable.call(this,options);
-
-if(options&&options.readable===false)this.readable=false;
-
-if(options&&options.writable===false)this.writable=false;
-
-this.allowHalfOpen=true;
-if(options&&options.allowHalfOpen===false)this.allowHalfOpen=false;
-
-this.once('end',onend);
-}
-
-
-function onend(){
-
-
-if(this.allowHalfOpen||this._writableState.ended)return;
-
-
-
-processNextTick(onEndNT,this);
-}
-
-function onEndNT(self){
-self.end();
-}
-
-function forEach(xs,f){
-for(var i=0,l=xs.length;i<l;i++){
-f(xs[i],i);
-}
-}
-},{"./_stream_readable":78,"./_stream_writable":80,"core-util-is":55,"inherits":58,"process-nextick-args":70}],77:[function(require,module,exports){
-
-
-
-
-'use strict';
-
-module.exports=PassThrough;
-
-var Transform=require('./_stream_transform');
-
-
-var util=require('core-util-is');
-util.inherits=require('inherits');
-
-
-util.inherits(PassThrough,Transform);
-
-function PassThrough(options){
-if(!(this instanceof PassThrough))return new PassThrough(options);
-
-Transform.call(this,options);
-}
-
-PassThrough.prototype._transform=function(chunk,encoding,cb){
-cb(null,chunk);
-};
-},{"./_stream_transform":79,"core-util-is":55,"inherits":58}],78:[function(require,module,exports){
-(function(process){
-'use strict';
-
-module.exports=Readable;
-
-
-var processNextTick=require('process-nextick-args');
-
-
-
-var isArray=require('isarray');
-
-
-
-var Duplex;
-
-
-Readable.ReadableState=ReadableState;
-
-
-var EE=require('events').EventEmitter;
-
-var EElistenerCount=function(emitter,type){
-return emitter.listeners(type).length;
-};
-
-
-
-var Stream;
-(function(){
-try{
-Stream=require('st'+'ream');
-}catch(_){}finally{
-if(!Stream)Stream=require('events').EventEmitter;
-}
-})();
-
-
-var Buffer=require('buffer').Buffer;
-
-var bufferShim=require('buffer-shims');
-
-
-
-var util=require('core-util-is');
-util.inherits=require('inherits');
-
-
-
-var debugUtil=require('util');
-var debug=void 0;
-if(debugUtil&&debugUtil.debuglog){
-debug=debugUtil.debuglog('stream');
-}else{
-debug=function(){};
-}
-
-
-var BufferList=require('./internal/streams/BufferList');
-var StringDecoder;
-
-util.inherits(Readable,Stream);
-
-function prependListener(emitter,event,fn){
-
-
-if(typeof emitter.prependListener==='function'){
-return emitter.prependListener(event,fn);
-}else{
-
-
-
-
-if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]];
-}
-}
-
-function ReadableState(options,stream){
-Duplex=Duplex||require('./_stream_duplex');
-
-options=options||{};
-
-
-
-this.objectMode=!!options.objectMode;
-
-if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;
-
-
-
-var hwm=options.highWaterMark;
-var defaultHwm=this.objectMode?16:16*1024;
-this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;
-
-
-this.highWaterMark=~~this.highWaterMark;
-
-
-
-
-this.buffer=new BufferList();
-this.length=0;
-this.pipes=null;
-this.pipesCount=0;
-this.flowing=null;
-this.ended=false;
-this.endEmitted=false;
-this.reading=false;
-
-
-
-
-
-this.sync=true;
-
-
-
-this.needReadable=false;
-this.emittedReadable=false;
-this.readableListening=false;
-this.resumeScheduled=false;
-
-
-
-
-this.defaultEncoding=options.defaultEncoding||'utf8';
-
-
-
-this.ranOut=false;
-
-
-this.awaitDrain=0;
-
-
-this.readingMore=false;
-
-this.decoder=null;
-this.encoding=null;
-if(options.encoding){
-if(!StringDecoder)StringDecoder=require('string_decoder/').StringDecoder;
-this.decoder=new StringDecoder(options.encoding);
-this.encoding=options.encoding;
-}
-}
-
-function Readable(options){
-Duplex=Duplex||require('./_stream_duplex');
-
-if(!(this instanceof Readable))return new Readable(options);
-
-this._readableState=new ReadableState(options,this);
-
-
-this.readable=true;
-
-if(options&&typeof options.read==='function')this._read=options.read;
-
-Stream.call(this);
-}
-
-
-
-
-
-Readable.prototype.push=function(chunk,encoding){
-var state=this._readableState;
-
-if(!state.objectMode&&typeof chunk==='string'){
-encoding=encoding||state.defaultEncoding;
-if(encoding!==state.encoding){
-chunk=bufferShim.from(chunk,encoding);
-encoding='';
-}
-}
-
-return readableAddChunk(this,state,chunk,encoding,false);
-};
-
-
-Readable.prototype.unshift=function(chunk){
-var state=this._readableState;
-return readableAddChunk(this,state,chunk,'',true);
-};
-
-Readable.prototype.isPaused=function(){
-return this._readableState.flowing===false;
-};
-
-function readableAddChunk(stream,state,chunk,encoding,addToFront){
-var er=chunkInvalid(state,chunk);
-if(er){
-stream.emit('error',er);
-}else if(chunk===null){
-state.reading=false;
-onEofChunk(stream,state);
-}else if(state.objectMode||chunk&&chunk.length>0){
-if(state.ended&&!addToFront){
-var e=new Error('stream.push() after EOF');
-stream.emit('error',e);
-}else if(state.endEmitted&&addToFront){
-var _e=new Error('stream.unshift() after end event');
-stream.emit('error',_e);
-}else{
-var skipAdd;
-if(state.decoder&&!addToFront&&!encoding){
-chunk=state.decoder.write(chunk);
-skipAdd=!state.objectMode&&chunk.length===0;
-}
-
-if(!addToFront)state.reading=false;
-
-
-
-if(!skipAdd){
-
-if(state.flowing&&state.length===0&&!state.sync){
-stream.emit('data',chunk);
-stream.read(0);
-}else{
-
-state.length+=state.objectMode?1:chunk.length;
-if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);
-
-if(state.needReadable)emitReadable(stream);
-}
-}
-
-maybeReadMore(stream,state);
-}
-}else if(!addToFront){
-state.reading=false;
-}
-
-return needMoreData(state);
-}
-
-
-
-
-
-
-
-
-function needMoreData(state){
-return!state.ended&&(state.needReadable||state.length<state.highWaterMark||state.length===0);
-}
-
-
-Readable.prototype.setEncoding=function(enc){
-if(!StringDecoder)StringDecoder=require('string_decoder/').StringDecoder;
-this._readableState.decoder=new StringDecoder(enc);
-this._readableState.encoding=enc;
-return this;
-};
-
-
-var MAX_HWM=0x800000;
-function computeNewHighWaterMark(n){
-if(n>=MAX_HWM){
-n=MAX_HWM;
-}else{
-
-
-n--;
-n|=n>>>1;
-n|=n>>>2;
-n|=n>>>4;
-n|=n>>>8;
-n|=n>>>16;
-n++;
-}
-return n;
-}
-
-
-
-function howMuchToRead(n,state){
-if(n<=0||state.length===0&&state.ended)return 0;
-if(state.objectMode)return 1;
-if(n!==n){
-
-if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length;
-}
-
-if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);
-if(n<=state.length)return n;
-
-if(!state.ended){
-state.needReadable=true;
-return 0;
-}
-return state.length;
-}
-
-
-Readable.prototype.read=function(n){
-debug('read',n);
-n=parseInt(n,10);
-var state=this._readableState;
-var nOrig=n;
-
-if(n!==0)state.emittedReadable=false;
-
-
-
-
-if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){
-debug('read: emitReadable',state.length,state.ended);
-if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);
-return null;
-}
-
-n=howMuchToRead(n,state);
-
-
-if(n===0&&state.ended){
-if(state.length===0)endReadable(this);
-return null;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var doRead=state.needReadable;
-debug('need readable',doRead);
-
-
-if(state.length===0||state.length-n<state.highWaterMark){
-doRead=true;
-debug('length less than watermark',doRead);
-}
-
-
-
-if(state.ended||state.reading){
-doRead=false;
-debug('reading or ended',doRead);
-}else if(doRead){
-debug('do read');
-state.reading=true;
-state.sync=true;
-
-if(state.length===0)state.needReadable=true;
-
-this._read(state.highWaterMark);
-state.sync=false;
-
-
-if(!state.reading)n=howMuchToRead(nOrig,state);
-}
-
-var ret;
-if(n>0)ret=fromList(n,state);else ret=null;
-
-if(ret===null){
-state.needReadable=true;
-n=0;
-}else{
-state.length-=n;
-}
-
-if(state.length===0){
-
-
-if(!state.ended)state.needReadable=true;
-
-
-if(nOrig!==n&&state.ended)endReadable(this);
-}
-
-if(ret!==null)this.emit('data',ret);
-
-return ret;
-};
-
-function chunkInvalid(state,chunk){
-var er=null;
-if(!Buffer.isBuffer(chunk)&&typeof chunk!=='string'&&chunk!==null&&chunk!==undefined&&!state.objectMode){
-er=new TypeError('Invalid non-string/buffer chunk');
-}
-return er;
-}
-
-function onEofChunk(stream,state){
-if(state.ended)return;
-if(state.decoder){
-var chunk=state.decoder.end();
-if(chunk&&chunk.length){
-state.buffer.push(chunk);
-state.length+=state.objectMode?1:chunk.length;
-}
-}
-state.ended=true;
-
-
-emitReadable(stream);
-}
-
-
-
-
-function emitReadable(stream){
-var state=stream._readableState;
-state.needReadable=false;
-if(!state.emittedReadable){
-debug('emitReadable',state.flowing);
-state.emittedReadable=true;
-if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream);
-}
-}
-
-function emitReadable_(stream){
-debug('emit readable');
-stream.emit('readable');
-flow(stream);
-}
-
-
-
-
-
-
-
-function maybeReadMore(stream,state){
-if(!state.readingMore){
-state.readingMore=true;
-processNextTick(maybeReadMore_,stream,state);
-}
-}
-
-function maybeReadMore_(stream,state){
-var len=state.length;
-while(!state.reading&&!state.flowing&&!state.ended&&state.length<state.highWaterMark){
-debug('maybeReadMore read 0');
-stream.read(0);
-if(len===state.length)
-
-break;else len=state.length;
-}
-state.readingMore=false;
-}
-
-
-
-
-
-Readable.prototype._read=function(n){
-this.emit('error',new Error('_read() is not implemented'));
-};
-
-Readable.prototype.pipe=function(dest,pipeOpts){
-var src=this;
-var state=this._readableState;
-
-switch(state.pipesCount){
-case 0:
-state.pipes=dest;
-break;
-case 1:
-state.pipes=[state.pipes,dest];
-break;
-default:
-state.pipes.push(dest);
-break;}
-
-state.pipesCount+=1;
-debug('pipe count=%d opts=%j',state.pipesCount,pipeOpts);
-
-var doEnd=(!pipeOpts||pipeOpts.end!==false)&&dest!==process.stdout&&dest!==process.stderr;
-
-var endFn=doEnd?onend:cleanup;
-if(state.endEmitted)processNextTick(endFn);else src.once('end',endFn);
-
-dest.on('unpipe',onunpipe);
-function onunpipe(readable){
-debug('onunpipe');
-if(readable===src){
-cleanup();
-}
-}
-
-function onend(){
-debug('onend');
-dest.end();
-}
-
-
-
-
-
-var ondrain=pipeOnDrain(src);
-dest.on('drain',ondrain);
-
-var cleanedUp=false;
-function cleanup(){
-debug('cleanup');
-
-dest.removeListener('close',onclose);
-dest.removeListener('finish',onfinish);
-dest.removeListener('drain',ondrain);
-dest.removeListener('error',onerror);
-dest.removeListener('unpipe',onunpipe);
-src.removeListener('end',onend);
-src.removeListener('end',cleanup);
-src.removeListener('data',ondata);
-
-cleanedUp=true;
-
-
-
-
-
-
-if(state.awaitDrain&&(!dest._writableState||dest._writableState.needDrain))ondrain();
-}
-
-
-
-
-
-var increasedAwaitDrain=false;
-src.on('data',ondata);
-function ondata(chunk){
-debug('ondata');
-increasedAwaitDrain=false;
-var ret=dest.write(chunk);
-if(false===ret&&!increasedAwaitDrain){
-
-
-
-
-if((state.pipesCount===1&&state.pipes===dest||state.pipesCount>1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){
-debug('false write response, pause',src._readableState.awaitDrain);
-src._readableState.awaitDrain++;
-increasedAwaitDrain=true;
-}
-src.pause();
-}
-}
-
-
-
-function onerror(er){
-debug('onerror',er);
-unpipe();
-dest.removeListener('error',onerror);
-if(EElistenerCount(dest,'error')===0)dest.emit('error',er);
-}
-
-
-prependListener(dest,'error',onerror);
-
-
-function onclose(){
-dest.removeListener('finish',onfinish);
-unpipe();
-}
-dest.once('close',onclose);
-function onfinish(){
-debug('onfinish');
-dest.removeListener('close',onclose);
-unpipe();
-}
-dest.once('finish',onfinish);
-
-function unpipe(){
-debug('unpipe');
-src.unpipe(dest);
-}
-
-
-dest.emit('pipe',src);
-
-
-if(!state.flowing){
-debug('pipe resume');
-src.resume();
-}
-
-return dest;
-};
-
-function pipeOnDrain(src){
-return function(){
-var state=src._readableState;
-debug('pipeOnDrain',state.awaitDrain);
-if(state.awaitDrain)state.awaitDrain--;
-if(state.awaitDrain===0&&EElistenerCount(src,'data')){
-state.flowing=true;
-flow(src);
-}
-};
-}
-
-Readable.prototype.unpipe=function(dest){
-var state=this._readableState;
-
-
-if(state.pipesCount===0)return this;
-
-
-if(state.pipesCount===1){
-
-if(dest&&dest!==state.pipes)return this;
-
-if(!dest)dest=state.pipes;
-
-
-state.pipes=null;
-state.pipesCount=0;
-state.flowing=false;
-if(dest)dest.emit('unpipe',this);
-return this;
-}
-
-
-
-if(!dest){
-
-var dests=state.pipes;
-var len=state.pipesCount;
-state.pipes=null;
-state.pipesCount=0;
-state.flowing=false;
-
-for(var i=0;i<len;i++){
-dests[i].emit('unpipe',this);
-}return this;
-}
-
-
-var index=indexOf(state.pipes,dest);
-if(index===-1)return this;
-
-state.pipes.splice(index,1);
-state.pipesCount-=1;
-if(state.pipesCount===1)state.pipes=state.pipes[0];
-
-dest.emit('unpipe',this);
-
-return this;
-};
-
-
-
-Readable.prototype.on=function(ev,fn){
-var res=Stream.prototype.on.call(this,ev,fn);
-
-if(ev==='data'){
-
-if(this._readableState.flowing!==false)this.resume();
-}else if(ev==='readable'){
-var state=this._readableState;
-if(!state.endEmitted&&!state.readableListening){
-state.readableListening=state.needReadable=true;
-state.emittedReadable=false;
-if(!state.reading){
-processNextTick(nReadingNextTick,this);
-}else if(state.length){
-emitReadable(this,state);
-}
-}
-}
-
-return res;
-};
-Readable.prototype.addListener=Readable.prototype.on;
-
-function nReadingNextTick(self){
-debug('readable nexttick read 0');
-self.read(0);
-}
-
-
-
-Readable.prototype.resume=function(){
-var state=this._readableState;
-if(!state.flowing){
-debug('resume');
-state.flowing=true;
-resume(this,state);
-}
-return this;
-};
-
-function resume(stream,state){
-if(!state.resumeScheduled){
-state.resumeScheduled=true;
-processNextTick(resume_,stream,state);
-}
-}
-
-function resume_(stream,state){
-if(!state.reading){
-debug('resume read 0');
-stream.read(0);
-}
-
-state.resumeScheduled=false;
-state.awaitDrain=0;
-stream.emit('resume');
-flow(stream);
-if(state.flowing&&!state.reading)stream.read(0);
-}
-
-Readable.prototype.pause=function(){
-debug('call pause flowing=%j',this._readableState.flowing);
-if(false!==this._readableState.flowing){
-debug('pause');
-this._readableState.flowing=false;
-this.emit('pause');
-}
-return this;
-};
-
-function flow(stream){
-var state=stream._readableState;
-debug('flow',state.flowing);
-while(state.flowing&&stream.read()!==null){}
-}
-
-
-
-
-Readable.prototype.wrap=function(stream){
-var state=this._readableState;
-var paused=false;
-
-var self=this;
-stream.on('end',function(){
-debug('wrapped end');
-if(state.decoder&&!state.ended){
-var chunk=state.decoder.end();
-if(chunk&&chunk.length)self.push(chunk);
-}
-
-self.push(null);
-});
-
-stream.on('data',function(chunk){
-debug('wrapped data');
-if(state.decoder)chunk=state.decoder.write(chunk);
-
-
-if(state.objectMode&&(chunk===null||chunk===undefined))return;else if(!state.objectMode&&(!chunk||!chunk.length))return;
-
-var ret=self.push(chunk);
-if(!ret){
-paused=true;
-stream.pause();
-}
-});
-
-
-
-for(var i in stream){
-if(this[i]===undefined&&typeof stream[i]==='function'){
-this[i]=function(method){
-return function(){
-return stream[method].apply(stream,arguments);
-};
-}(i);
-}
-}
-
-
-var events=['error','close','destroy','pause','resume'];
-forEach(events,function(ev){
-stream.on(ev,self.emit.bind(self,ev));
-});
-
-
-
-self._read=function(n){
-debug('wrapped _read',n);
-if(paused){
-paused=false;
-stream.resume();
-}
-};
-
-return self;
-};
-
-
-Readable._fromList=fromList;
-
-
-
-
-
-function fromList(n,state){
-
-if(state.length===0)return null;
-
-var ret;
-if(state.objectMode)ret=state.buffer.shift();else if(!n||n>=state.length){
-
-if(state.decoder)ret=state.buffer.join('');else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);
-state.buffer.clear();
-}else{
-
-ret=fromListPartial(n,state.buffer,state.decoder);
-}
-
-return ret;
-}
-
-
-
-
-function fromListPartial(n,list,hasStrings){
-var ret;
-if(n<list.head.data.length){
-
-ret=list.head.data.slice(0,n);
-list.head.data=list.head.data.slice(n);
-}else if(n===list.head.data.length){
-
-ret=list.shift();
-}else{
-
-ret=hasStrings?copyFromBufferString(n,list):copyFromBuffer(n,list);
-}
-return ret;
-}
-
-
-
-
-
-function copyFromBufferString(n,list){
-var p=list.head;
-var c=1;
-var ret=p.data;
-n-=ret.length;
-while(p=p.next){
-var str=p.data;
-var nb=n>str.length?str.length:n;
-if(nb===str.length)ret+=str;else ret+=str.slice(0,n);
-n-=nb;
-if(n===0){
-if(nb===str.length){
-++c;
-if(p.next)list.head=p.next;else list.head=list.tail=null;
-}else{
-list.head=p;
-p.data=str.slice(nb);
-}
-break;
-}
-++c;
-}
-list.length-=c;
-return ret;
-}
-
-
-
-
-function copyFromBuffer(n,list){
-var ret=bufferShim.allocUnsafe(n);
-var p=list.head;
-var c=1;
-p.data.copy(ret);
-n-=p.data.length;
-while(p=p.next){
-var buf=p.data;
-var nb=n>buf.length?buf.length:n;
-buf.copy(ret,ret.length-n,0,nb);
-n-=nb;
-if(n===0){
-if(nb===buf.length){
-++c;
-if(p.next)list.head=p.next;else list.head=list.tail=null;
-}else{
-list.head=p;
-p.data=buf.slice(nb);
-}
-break;
-}
-++c;
-}
-list.length-=c;
-return ret;
-}
-
-function endReadable(stream){
-var state=stream._readableState;
-
-
-
-if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');
-
-if(!state.endEmitted){
-state.ended=true;
-processNextTick(endReadableNT,state,stream);
-}
-}
-
-function endReadableNT(state,stream){
-
-if(!state.endEmitted&&state.length===0){
-state.endEmitted=true;
-stream.readable=false;
-stream.emit('end');
-}
-}
-
-function forEach(xs,f){
-for(var i=0,l=xs.length;i<l;i++){
-f(xs[i],i);
-}
-}
-
-function indexOf(xs,x){
-for(var i=0,l=xs.length;i<l;i++){
-if(xs[i]===x)return i;
-}
-return-1;
-}
-}).call(this,require('_process'));
-},{"./_stream_duplex":76,"./internal/streams/BufferList":81,"_process":71,"buffer":54,"buffer-shims":53,"core-util-is":55,"events":56,"inherits":58,"isarray":60,"process-nextick-args":70,"string_decoder/":87,"util":49}],79:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'use strict';
-
-module.exports=Transform;
-
-var Duplex=require('./_stream_duplex');
-
-
-var util=require('core-util-is');
-util.inherits=require('inherits');
-
-
-util.inherits(Transform,Duplex);
-
-function TransformState(stream){
-this.afterTransform=function(er,data){
-return afterTransform(stream,er,data);
-};
-
-this.needTransform=false;
-this.transforming=false;
-this.writecb=null;
-this.writechunk=null;
-this.writeencoding=null;
-}
-
-function afterTransform(stream,er,data){
-var ts=stream._transformState;
-ts.transforming=false;
-
-var cb=ts.writecb;
-
-if(!cb)return stream.emit('error',new Error('no writecb in Transform class'));
-
-ts.writechunk=null;
-ts.writecb=null;
-
-if(data!==null&&data!==undefined)stream.push(data);
-
-cb(er);
-
-var rs=stream._readableState;
-rs.reading=false;
-if(rs.needReadable||rs.length<rs.highWaterMark){
-stream._read(rs.highWaterMark);
-}
-}
-
-function Transform(options){
-if(!(this instanceof Transform))return new Transform(options);
-
-Duplex.call(this,options);
-
-this._transformState=new TransformState(this);
-
-var stream=this;
-
-
-this._readableState.needReadable=true;
-
-
-
-
-this._readableState.sync=false;
-
-if(options){
-if(typeof options.transform==='function')this._transform=options.transform;
-
-if(typeof options.flush==='function')this._flush=options.flush;
-}
-
-
-this.once('prefinish',function(){
-if(typeof this._flush==='function')this._flush(function(er,data){
-done(stream,er,data);
-});else done(stream);
-});
-}
-
-Transform.prototype.push=function(chunk,encoding){
-this._transformState.needTransform=false;
-return Duplex.prototype.push.call(this,chunk,encoding);
-};
-
-
-
-
-
-
-
-
-
-
-
-Transform.prototype._transform=function(chunk,encoding,cb){
-throw new Error('_transform() is not implemented');
-};
-
-Transform.prototype._write=function(chunk,encoding,cb){
-var ts=this._transformState;
-ts.writecb=cb;
-ts.writechunk=chunk;
-ts.writeencoding=encoding;
-if(!ts.transforming){
-var rs=this._readableState;
-if(ts.needTransform||rs.needReadable||rs.length<rs.highWaterMark)this._read(rs.highWaterMark);
-}
-};
-
-
-
-
-Transform.prototype._read=function(n){
-var ts=this._transformState;
-
-if(ts.writechunk!==null&&ts.writecb&&!ts.transforming){
-ts.transforming=true;
-this._transform(ts.writechunk,ts.writeencoding,ts.afterTransform);
-}else{
-
-
-ts.needTransform=true;
-}
-};
-
-function done(stream,er,data){
-if(er)return stream.emit('error',er);
-
-if(data!==null&&data!==undefined)stream.push(data);
-
-
-
-var ws=stream._writableState;
-var ts=stream._transformState;
-
-if(ws.length)throw new Error('Calling transform done when ws.length != 0');
-
-if(ts.transforming)throw new Error('Calling transform done when still transforming');
-
-return stream.push(null);
-}
-},{"./_stream_duplex":76,"core-util-is":55,"inherits":58}],80:[function(require,module,exports){
-(function(process){
-
-
-
-
-'use strict';
-
-module.exports=Writable;
-
-
-var processNextTick=require('process-nextick-args');
-
-
-
-var asyncWrite=!process.browser&&['v0.10','v0.9.'].indexOf(process.version.slice(0,5))>-1?setImmediate:processNextTick;
-
-
-
-var Duplex;
-
-
-Writable.WritableState=WritableState;
-
-
-var util=require('core-util-is');
-util.inherits=require('inherits');
-
-
-
-var internalUtil={
-deprecate:require('util-deprecate')};
-
-
-
-
-var Stream;
-(function(){
-try{
-Stream=require('st'+'ream');
-}catch(_){}finally{
-if(!Stream)Stream=require('events').EventEmitter;
-}
-})();
-
-
-var Buffer=require('buffer').Buffer;
-
-var bufferShim=require('buffer-shims');
-
-
-util.inherits(Writable,Stream);
-
-function nop(){}
-
-function WriteReq(chunk,encoding,cb){
-this.chunk=chunk;
-this.encoding=encoding;
-this.callback=cb;
-this.next=null;
-}
-
-function WritableState(options,stream){
-Duplex=Duplex||require('./_stream_duplex');
-
-options=options||{};
-
-
-
-this.objectMode=!!options.objectMode;
-
-if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;
-
-
-
-
-var hwm=options.highWaterMark;
-var defaultHwm=this.objectMode?16:16*1024;
-this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;
-
-
-this.highWaterMark=~~this.highWaterMark;
-
-
-this.needDrain=false;
-
-this.ending=false;
-
-this.ended=false;
-
-this.finished=false;
-
-
-
-
-var noDecode=options.decodeStrings===false;
-this.decodeStrings=!noDecode;
-
-
-
-
-this.defaultEncoding=options.defaultEncoding||'utf8';
-
-
-
-
-this.length=0;
-
-
-this.writing=false;
-
-
-this.corked=0;
-
-
-
-
-
-this.sync=true;
-
-
-
-
-this.bufferProcessing=false;
-
-
-this.onwrite=function(er){
-onwrite(stream,er);
-};
-
-
-this.writecb=null;
-
-
-this.writelen=0;
-
-this.bufferedRequest=null;
-this.lastBufferedRequest=null;
-
-
-
-this.pendingcb=0;
-
-
-
-this.prefinished=false;
-
-
-this.errorEmitted=false;
-
-
-this.bufferedRequestCount=0;
-
-
-
-this.corkedRequestsFree=new CorkedRequest(this);
-}
-
-WritableState.prototype.getBuffer=function getBuffer(){
-var current=this.bufferedRequest;
-var out=[];
-while(current){
-out.push(current);
-current=current.next;
-}
-return out;
-};
-
-(function(){
-try{
-Object.defineProperty(WritableState.prototype,'buffer',{
-get:internalUtil.deprecate(function(){
-return this.getBuffer();
-},'_writableState.buffer is deprecated. Use _writableState.getBuffer '+'instead.')});
-
-}catch(_){}
-})();
-
-
-
-var realHasInstance;
-if(typeof Symbol==='function'&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==='function'){
-realHasInstance=Function.prototype[Symbol.hasInstance];
-Object.defineProperty(Writable,Symbol.hasInstance,{
-value:function(object){
-if(realHasInstance.call(this,object))return true;
-
-return object&&object._writableState instanceof WritableState;
-}});
-
-}else{
-realHasInstance=function(object){
-return object instanceof this;
-};
-}
-
-function Writable(options){
-Duplex=Duplex||require('./_stream_duplex');
-
-
-
-
-
-
-
-
-if(!realHasInstance.call(Writable,this)&&!(this instanceof Duplex)){
-return new Writable(options);
-}
-
-this._writableState=new WritableState(options,this);
-
-
-this.writable=true;
-
-if(options){
-if(typeof options.write==='function')this._write=options.write;
-
-if(typeof options.writev==='function')this._writev=options.writev;
-}
-
-Stream.call(this);
-}
-
-
-Writable.prototype.pipe=function(){
-this.emit('error',new Error('Cannot pipe, not readable'));
-};
-
-function writeAfterEnd(stream,cb){
-var er=new Error('write after end');
-
-stream.emit('error',er);
-processNextTick(cb,er);
-}
-
-
-
-
-
-
-function validChunk(stream,state,chunk,cb){
-var valid=true;
-var er=false;
-
-
-
-if(chunk===null){
-er=new TypeError('May not write null values to stream');
-}else if(!Buffer.isBuffer(chunk)&&typeof chunk!=='string'&&chunk!==undefined&&!state.objectMode){
-er=new TypeError('Invalid non-string/buffer chunk');
-}
-if(er){
-stream.emit('error',er);
-processNextTick(cb,er);
-valid=false;
-}
-return valid;
-}
-
-Writable.prototype.write=function(chunk,encoding,cb){
-var state=this._writableState;
-var ret=false;
-
-if(typeof encoding==='function'){
-cb=encoding;
-encoding=null;
-}
-
-if(Buffer.isBuffer(chunk))encoding='buffer';else if(!encoding)encoding=state.defaultEncoding;
-
-if(typeof cb!=='function')cb=nop;
-
-if(state.ended)writeAfterEnd(this,cb);else if(validChunk(this,state,chunk,cb)){
-state.pendingcb++;
-ret=writeOrBuffer(this,state,chunk,encoding,cb);
-}
-
-return ret;
-};
-
-Writable.prototype.cork=function(){
-var state=this._writableState;
-
-state.corked++;
-};
-
-Writable.prototype.uncork=function(){
-var state=this._writableState;
-
-if(state.corked){
-state.corked--;
-
-if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state);
-}
-};
-
-Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){
-
-if(typeof encoding==='string')encoding=encoding.toLowerCase();
-if(!(['hex','utf8','utf-8','ascii','binary','base64','ucs2','ucs-2','utf16le','utf-16le','raw'].indexOf((encoding+'').toLowerCase())>-1))throw new TypeError('Unknown encoding: '+encoding);
-this._writableState.defaultEncoding=encoding;
-return this;
-};
-
-function decodeChunk(state,chunk,encoding){
-if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==='string'){
-chunk=bufferShim.from(chunk,encoding);
-}
-return chunk;
-}
-
-
-
-
-function writeOrBuffer(stream,state,chunk,encoding,cb){
-chunk=decodeChunk(state,chunk,encoding);
-
-if(Buffer.isBuffer(chunk))encoding='buffer';
-var len=state.objectMode?1:chunk.length;
-
-state.length+=len;
-
-var ret=state.length<state.highWaterMark;
-
-if(!ret)state.needDrain=true;
-
-if(state.writing||state.corked){
-var last=state.lastBufferedRequest;
-state.lastBufferedRequest=new WriteReq(chunk,encoding,cb);
-if(last){
-last.next=state.lastBufferedRequest;
-}else{
-state.bufferedRequest=state.lastBufferedRequest;
-}
-state.bufferedRequestCount+=1;
-}else{
-doWrite(stream,state,false,len,chunk,encoding,cb);
-}
-
-return ret;
-}
-
-function doWrite(stream,state,writev,len,chunk,encoding,cb){
-state.writelen=len;
-state.writecb=cb;
-state.writing=true;
-state.sync=true;
-if(writev)stream._writev(chunk,state.onwrite);else stream._write(chunk,encoding,state.onwrite);
-state.sync=false;
-}
-
-function onwriteError(stream,state,sync,er,cb){
---state.pendingcb;
-if(sync)processNextTick(cb,er);else cb(er);
-
-stream._writableState.errorEmitted=true;
-stream.emit('error',er);
-}
-
-function onwriteStateUpdate(state){
-state.writing=false;
-state.writecb=null;
-state.length-=state.writelen;
-state.writelen=0;
-}
-
-function onwrite(stream,er){
-var state=stream._writableState;
-var sync=state.sync;
-var cb=state.writecb;
-
-onwriteStateUpdate(state);
-
-if(er)onwriteError(stream,state,sync,er,cb);else{
-
-var finished=needFinish(state);
-
-if(!finished&&!state.corked&&!state.bufferProcessing&&state.bufferedRequest){
-clearBuffer(stream,state);
-}
-
-if(sync){
-
-asyncWrite(afterWrite,stream,state,finished,cb);
-
-}else{
-afterWrite(stream,state,finished,cb);
-}
-}
-}
-
-function afterWrite(stream,state,finished,cb){
-if(!finished)onwriteDrain(stream,state);
-state.pendingcb--;
-cb();
-finishMaybe(stream,state);
-}
-
-
-
-
-function onwriteDrain(stream,state){
-if(state.length===0&&state.needDrain){
-state.needDrain=false;
-stream.emit('drain');
-}
-}
-
-
-function clearBuffer(stream,state){
-state.bufferProcessing=true;
-var entry=state.bufferedRequest;
-
-if(stream._writev&&entry&&entry.next){
-
-var l=state.bufferedRequestCount;
-var buffer=new Array(l);
-var holder=state.corkedRequestsFree;
-holder.entry=entry;
-
-var count=0;
-while(entry){
-buffer[count]=entry;
-entry=entry.next;
-count+=1;
-}
-
-doWrite(stream,state,true,state.length,buffer,'',holder.finish);
-
-
-
-state.pendingcb++;
-state.lastBufferedRequest=null;
-if(holder.next){
-state.corkedRequestsFree=holder.next;
-holder.next=null;
-}else{
-state.corkedRequestsFree=new CorkedRequest(state);
-}
-}else{
-
-while(entry){
-var chunk=entry.chunk;
-var encoding=entry.encoding;
-var cb=entry.callback;
-var len=state.objectMode?1:chunk.length;
-
-doWrite(stream,state,false,len,chunk,encoding,cb);
-entry=entry.next;
-
-
-
-
-if(state.writing){
-break;
-}
-}
-
-if(entry===null)state.lastBufferedRequest=null;
-}
-
-state.bufferedRequestCount=0;
-state.bufferedRequest=entry;
-state.bufferProcessing=false;
-}
-
-Writable.prototype._write=function(chunk,encoding,cb){
-cb(new Error('_write() is not implemented'));
-};
-
-Writable.prototype._writev=null;
-
-Writable.prototype.end=function(chunk,encoding,cb){
-var state=this._writableState;
-
-if(typeof chunk==='function'){
-cb=chunk;
-chunk=null;
-encoding=null;
-}else if(typeof encoding==='function'){
-cb=encoding;
-encoding=null;
-}
-
-if(chunk!==null&&chunk!==undefined)this.write(chunk,encoding);
-
-
-if(state.corked){
-state.corked=1;
-this.uncork();
-}
-
-
-if(!state.ending&&!state.finished)endWritable(this,state,cb);
-};
-
-function needFinish(state){
-return state.ending&&state.length===0&&state.bufferedRequest===null&&!state.finished&&!state.writing;
-}
-
-function prefinish(stream,state){
-if(!state.prefinished){
-state.prefinished=true;
-stream.emit('prefinish');
-}
-}
-
-function finishMaybe(stream,state){
-var need=needFinish(state);
-if(need){
-if(state.pendingcb===0){
-prefinish(stream,state);
-state.finished=true;
-stream.emit('finish');
-}else{
-prefinish(stream,state);
-}
-}
-return need;
-}
-
-function endWritable(stream,state,cb){
-state.ending=true;
-finishMaybe(stream,state);
-if(cb){
-if(state.finished)processNextTick(cb);else stream.once('finish',cb);
-}
-state.ended=true;
-stream.writable=false;
-}
-
-
-
-function CorkedRequest(state){
-var _this=this;
-
-this.next=null;
-this.entry=null;
-
-this.finish=function(err){
-var entry=_this.entry;
-_this.entry=null;
-while(entry){
-var cb=entry.callback;
-state.pendingcb--;
-cb(err);
-entry=entry.next;
-}
-if(state.corkedRequestsFree){
-state.corkedRequestsFree.next=_this;
-}else{
-state.corkedRequestsFree=_this;
-}
-};
-}
-}).call(this,require('_process'));
-},{"./_stream_duplex":76,"_process":71,"buffer":54,"buffer-shims":53,"core-util-is":55,"events":56,"inherits":58,"process-nextick-args":70,"util-deprecate":88}],81:[function(require,module,exports){
-'use strict';
-
-var Buffer=require('buffer').Buffer;
-
-var bufferShim=require('buffer-shims');
-
-
-module.exports=BufferList;
-
-function BufferList(){
-this.head=null;
-this.tail=null;
-this.length=0;
-}
-
-BufferList.prototype.push=function(v){
-var entry={data:v,next:null};
-if(this.length>0)this.tail.next=entry;else this.head=entry;
-this.tail=entry;
-++this.length;
-};
-
-BufferList.prototype.unshift=function(v){
-var entry={data:v,next:this.head};
-if(this.length===0)this.tail=entry;
-this.head=entry;
-++this.length;
-};
-
-BufferList.prototype.shift=function(){
-if(this.length===0)return;
-var ret=this.head.data;
-if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;
---this.length;
-return ret;
-};
-
-BufferList.prototype.clear=function(){
-this.head=this.tail=null;
-this.length=0;
-};
-
-BufferList.prototype.join=function(s){
-if(this.length===0)return'';
-var p=this.head;
-var ret=''+p.data;
-while(p=p.next){
-ret+=s+p.data;
-}return ret;
-};
-
-BufferList.prototype.concat=function(n){
-if(this.length===0)return bufferShim.alloc(0);
-if(this.length===1)return this.head.data;
-var ret=bufferShim.allocUnsafe(n>>>0);
-var p=this.head;
-var i=0;
-while(p){
-p.data.copy(ret,i);
-i+=p.data.length;
-p=p.next;
-}
-return ret;
-};
-},{"buffer":54,"buffer-shims":53}],82:[function(require,module,exports){
-module.exports=require("./lib/_stream_passthrough.js");
-
-},{"./lib/_stream_passthrough.js":77}],83:[function(require,module,exports){
-(function(process){
-var Stream=function(){
-try{
-return require('st'+'ream');
-}catch(_){}
-}();
-exports=module.exports=require('./lib/_stream_readable.js');
-exports.Stream=Stream||exports;
-exports.Readable=exports;
-exports.Writable=require('./lib/_stream_writable.js');
-exports.Duplex=require('./lib/_stream_duplex.js');
-exports.Transform=require('./lib/_stream_transform.js');
-exports.PassThrough=require('./lib/_stream_passthrough.js');
-
-if(!process.browser&&process.env.READABLE_STREAM==='disable'&&Stream){
-module.exports=Stream;
-}
-
-}).call(this,require('_process'));
-},{"./lib/_stream_duplex.js":76,"./lib/_stream_passthrough.js":77,"./lib/_stream_readable.js":78,"./lib/_stream_transform.js":79,"./lib/_stream_writable.js":80,"_process":71}],84:[function(require,module,exports){
-module.exports=require("./lib/_stream_transform.js");
-
-},{"./lib/_stream_transform.js":79}],85:[function(require,module,exports){
-module.exports=require("./lib/_stream_writable.js");
-
-},{"./lib/_stream_writable.js":80}],86:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-module.exports=Stream;
-
-var EE=require('events').EventEmitter;
-var inherits=require('inherits');
-
-inherits(Stream,EE);
-Stream.Readable=require('readable-stream/readable.js');
-Stream.Writable=require('readable-stream/writable.js');
-Stream.Duplex=require('readable-stream/duplex.js');
-Stream.Transform=require('readable-stream/transform.js');
-Stream.PassThrough=require('readable-stream/passthrough.js');
-
-
-Stream.Stream=Stream;
-
-
-
-
-
-
-function Stream(){
-EE.call(this);
-}
-
-Stream.prototype.pipe=function(dest,options){
-var source=this;
-
-function ondata(chunk){
-if(dest.writable){
-if(false===dest.write(chunk)&&source.pause){
-source.pause();
-}
-}
-}
-
-source.on('data',ondata);
-
-function ondrain(){
-if(source.readable&&source.resume){
-source.resume();
-}
-}
-
-dest.on('drain',ondrain);
-
-
-
-if(!dest._isStdio&&(!options||options.end!==false)){
-source.on('end',onend);
-source.on('close',onclose);
-}
-
-var didOnEnd=false;
-function onend(){
-if(didOnEnd)return;
-didOnEnd=true;
-
-dest.end();
-}
-
-
-function onclose(){
-if(didOnEnd)return;
-didOnEnd=true;
-
-if(typeof dest.destroy==='function')dest.destroy();
-}
-
-
-function onerror(er){
-cleanup();
-if(EE.listenerCount(this,'error')===0){
-throw er;
-}
-}
-
-source.on('error',onerror);
-dest.on('error',onerror);
-
-
-function cleanup(){
-source.removeListener('data',ondata);
-dest.removeListener('drain',ondrain);
-
-source.removeListener('end',onend);
-source.removeListener('close',onclose);
-
-source.removeListener('error',onerror);
-dest.removeListener('error',onerror);
-
-source.removeListener('end',cleanup);
-source.removeListener('close',cleanup);
-
-dest.removeListener('close',cleanup);
-}
-
-source.on('end',cleanup);
-source.on('close',cleanup);
-
-dest.on('close',cleanup);
-
-dest.emit('pipe',source);
-
-
-return dest;
-};
-
-},{"events":56,"inherits":58,"readable-stream/duplex.js":75,"readable-stream/passthrough.js":82,"readable-stream/readable.js":83,"readable-stream/transform.js":84,"readable-stream/writable.js":85}],87:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var Buffer=require('buffer').Buffer;
-
-var isBufferEncoding=Buffer.isEncoding||
-function(encoding){
-switch(encoding&&encoding.toLowerCase()){
-case'hex':case'utf8':case'utf-8':case'ascii':case'binary':case'base64':case'ucs2':case'ucs-2':case'utf16le':case'utf-16le':case'raw':return true;
-default:return false;}
-
-};
-
-
-function assertEncoding(encoding){
-if(encoding&&!isBufferEncoding(encoding)){
-throw new Error('Unknown encoding: '+encoding);
-}
-}
-
-
-
-
-
-
-
-
-
-var StringDecoder=exports.StringDecoder=function(encoding){
-this.encoding=(encoding||'utf8').toLowerCase().replace(/[-_]/,'');
-assertEncoding(encoding);
-switch(this.encoding){
-case'utf8':
-
-this.surrogateSize=3;
-break;
-case'ucs2':
-case'utf16le':
-
-this.surrogateSize=2;
-this.detectIncompleteChar=utf16DetectIncompleteChar;
-break;
-case'base64':
-
-this.surrogateSize=3;
-this.detectIncompleteChar=base64DetectIncompleteChar;
-break;
-default:
-this.write=passThroughWrite;
-return;}
-
-
-
-
-this.charBuffer=new Buffer(6);
-
-this.charReceived=0;
-
-this.charLength=0;
-};
-
-
-
-
-
-
-
-
-
-
-
-StringDecoder.prototype.write=function(buffer){
-var charStr='';
-
-while(this.charLength){
-
-var available=buffer.length>=this.charLength-this.charReceived?
-this.charLength-this.charReceived:
-buffer.length;
-
-
-buffer.copy(this.charBuffer,this.charReceived,0,available);
-this.charReceived+=available;
-
-if(this.charReceived<this.charLength){
-
-return'';
-}
-
-
-buffer=buffer.slice(available,buffer.length);
-
-
-charStr=this.charBuffer.slice(0,this.charLength).toString(this.encoding);
-
-
-var charCode=charStr.charCodeAt(charStr.length-1);
-if(charCode>=0xD800&&charCode<=0xDBFF){
-this.charLength+=this.surrogateSize;
-charStr='';
-continue;
-}
-this.charReceived=this.charLength=0;
-
-
-if(buffer.length===0){
-return charStr;
-}
-break;
-}
-
-
-this.detectIncompleteChar(buffer);
-
-var end=buffer.length;
-if(this.charLength){
-
-buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);
-end-=this.charReceived;
-}
-
-charStr+=buffer.toString(this.encoding,0,end);
-
-var end=charStr.length-1;
-var charCode=charStr.charCodeAt(end);
-
-if(charCode>=0xD800&&charCode<=0xDBFF){
-var size=this.surrogateSize;
-this.charLength+=size;
-this.charReceived+=size;
-this.charBuffer.copy(this.charBuffer,size,0,size);
-buffer.copy(this.charBuffer,0,0,size);
-return charStr.substring(0,end);
-}
-
-
-return charStr;
-};
-
-
-
-
-
-StringDecoder.prototype.detectIncompleteChar=function(buffer){
-
-var i=buffer.length>=3?3:buffer.length;
-
-
-
-for(;i>0;i--){
-var c=buffer[buffer.length-i];
-
-
-
-
-if(i==1&&c>>5==0x06){
-this.charLength=2;
-break;
-}
-
-
-if(i<=2&&c>>4==0x0E){
-this.charLength=3;
-break;
-}
-
-
-if(i<=3&&c>>3==0x1E){
-this.charLength=4;
-break;
-}
-}
-this.charReceived=i;
-};
-
-StringDecoder.prototype.end=function(buffer){
-var res='';
-if(buffer&&buffer.length)
-res=this.write(buffer);
-
-if(this.charReceived){
-var cr=this.charReceived;
-var buf=this.charBuffer;
-var enc=this.encoding;
-res+=buf.slice(0,cr).toString(enc);
-}
-
-return res;
-};
-
-function passThroughWrite(buffer){
-return buffer.toString(this.encoding);
-}
-
-function utf16DetectIncompleteChar(buffer){
-this.charReceived=buffer.length%2;
-this.charLength=this.charReceived?2:0;
-}
-
-function base64DetectIncompleteChar(buffer){
-this.charReceived=buffer.length%3;
-this.charLength=this.charReceived?3:0;
-}
-
-},{"buffer":54}],88:[function(require,module,exports){
-(function(global){
-
-
-
-
-
-module.exports=deprecate;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function deprecate(fn,msg){
-if(config('noDeprecation')){
-return fn;
-}
-
-var warned=false;
-function deprecated(){
-if(!warned){
-if(config('throwDeprecation')){
-throw new Error(msg);
-}else if(config('traceDeprecation')){
-console.trace(msg);
-}else{
-console.warn(msg);
-}
-warned=true;
-}
-return fn.apply(this,arguments);
-}
-
-return deprecated;
-}
-
-
-
-
-
-
-
-
-
-function config(name){
-
-try{
-if(!global.localStorage)return false;
-}catch(_){
-return false;
-}
-var val=global.localStorage[name];
-if(null==val)return false;
-return String(val).toLowerCase()==='true';
-}
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{}],89:[function(require,module,exports){
-arguments[4][58][0].apply(exports,arguments);
-},{"dup":58}],90:[function(require,module,exports){
-module.exports=function isBuffer(arg){
-return arg&&typeof arg==='object'&&
-typeof arg.copy==='function'&&
-typeof arg.fill==='function'&&
-typeof arg.readUInt8==='function';
-};
-},{}],91:[function(require,module,exports){
-(function(process,global){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var formatRegExp=/%[sdj%]/g;
-exports.format=function(f){
-if(!isString(f)){
-var objects=[];
-for(var i=0;i<arguments.length;i++){
-objects.push(inspect(arguments[i]));
-}
-return objects.join(' ');
-}
-
-var i=1;
-var args=arguments;
-var len=args.length;
-var str=String(f).replace(formatRegExp,function(x){
-if(x==='%%')return'%';
-if(i>=len)return x;
-switch(x){
-case'%s':return String(args[i++]);
-case'%d':return Number(args[i++]);
-case'%j':
-try{
-return JSON.stringify(args[i++]);
-}catch(_){
-return'[Circular]';
-}
-default:
-return x;}
-
-});
-for(var x=args[i];i<len;x=args[++i]){
-if(isNull(x)||!isObject(x)){
-str+=' '+x;
-}else{
-str+=' '+inspect(x);
-}
-}
-return str;
-};
-
-
-
-
-
-exports.deprecate=function(fn,msg){
-
-if(isUndefined(global.process)){
-return function(){
-return exports.deprecate(fn,msg).apply(this,arguments);
-};
-}
-
-if(process.noDeprecation===true){
-return fn;
-}
-
-var warned=false;
-function deprecated(){
-if(!warned){
-if(process.throwDeprecation){
-throw new Error(msg);
-}else if(process.traceDeprecation){
-console.trace(msg);
-}else{
-console.error(msg);
-}
-warned=true;
-}
-return fn.apply(this,arguments);
-}
-
-return deprecated;
-};
-
-
-var debugs={};
-var debugEnviron;
-exports.debuglog=function(set){
-if(isUndefined(debugEnviron))
-debugEnviron=process.env.NODE_DEBUG||'';
-set=set.toUpperCase();
-if(!debugs[set]){
-if(new RegExp('\\b'+set+'\\b','i').test(debugEnviron)){
-var pid=process.pid;
-debugs[set]=function(){
-var msg=exports.format.apply(exports,arguments);
-console.error('%s %d: %s',set,pid,msg);
-};
-}else{
-debugs[set]=function(){};
-}
-}
-return debugs[set];
-};
-
-
-
-
-
-
-
-
-
-
-function inspect(obj,opts){
-
-var ctx={
-seen:[],
-stylize:stylizeNoColor};
-
-
-if(arguments.length>=3)ctx.depth=arguments[2];
-if(arguments.length>=4)ctx.colors=arguments[3];
-if(isBoolean(opts)){
-
-ctx.showHidden=opts;
-}else if(opts){
-
-exports._extend(ctx,opts);
-}
-
-if(isUndefined(ctx.showHidden))ctx.showHidden=false;
-if(isUndefined(ctx.depth))ctx.depth=2;
-if(isUndefined(ctx.colors))ctx.colors=false;
-if(isUndefined(ctx.customInspect))ctx.customInspect=true;
-if(ctx.colors)ctx.stylize=stylizeWithColor;
-return formatValue(ctx,obj,ctx.depth);
-}
-exports.inspect=inspect;
-
-
-
-inspect.colors={
-'bold':[1,22],
-'italic':[3,23],
-'underline':[4,24],
-'inverse':[7,27],
-'white':[37,39],
-'grey':[90,39],
-'black':[30,39],
-'blue':[34,39],
-'cyan':[36,39],
-'green':[32,39],
-'magenta':[35,39],
-'red':[31,39],
-'yellow':[33,39]};
-
-
-
-inspect.styles={
-'special':'cyan',
-'number':'yellow',
-'boolean':'yellow',
-'undefined':'grey',
-'null':'bold',
-'string':'green',
-'date':'magenta',
-
-'regexp':'red'};
-
-
-
-function stylizeWithColor(str,styleType){
-var style=inspect.styles[styleType];
-
-if(style){
-return'\u001b['+inspect.colors[style][0]+'m'+str+
-'\u001b['+inspect.colors[style][1]+'m';
-}else{
-return str;
-}
-}
-
-
-function stylizeNoColor(str,styleType){
-return str;
-}
-
-
-function arrayToHash(array){
-var hash={};
-
-array.forEach(function(val,idx){
-hash[val]=true;
-});
-
-return hash;
-}
-
-
-function formatValue(ctx,value,recurseTimes){
-
-
-if(ctx.customInspect&&
-value&&
-isFunction(value.inspect)&&
-
-value.inspect!==exports.inspect&&
-
-!(value.constructor&&value.constructor.prototype===value)){
-var ret=value.inspect(recurseTimes,ctx);
-if(!isString(ret)){
-ret=formatValue(ctx,ret,recurseTimes);
-}
-return ret;
-}
-
-
-var primitive=formatPrimitive(ctx,value);
-if(primitive){
-return primitive;
-}
-
-
-var keys=Object.keys(value);
-var visibleKeys=arrayToHash(keys);
-
-if(ctx.showHidden){
-keys=Object.getOwnPropertyNames(value);
-}
-
-
-
-if(isError(value)&&(
-keys.indexOf('message')>=0||keys.indexOf('description')>=0)){
-return formatError(value);
-}
-
-
-if(keys.length===0){
-if(isFunction(value)){
-var name=value.name?': '+value.name:'';
-return ctx.stylize('[Function'+name+']','special');
-}
-if(isRegExp(value)){
-return ctx.stylize(RegExp.prototype.toString.call(value),'regexp');
-}
-if(isDate(value)){
-return ctx.stylize(Date.prototype.toString.call(value),'date');
-}
-if(isError(value)){
-return formatError(value);
-}
-}
-
-var base='',array=false,braces=['{','}'];
-
-
-if(isArray(value)){
-array=true;
-braces=['[',']'];
-}
-
-
-if(isFunction(value)){
-var n=value.name?': '+value.name:'';
-base=' [Function'+n+']';
-}
-
-
-if(isRegExp(value)){
-base=' '+RegExp.prototype.toString.call(value);
-}
-
-
-if(isDate(value)){
-base=' '+Date.prototype.toUTCString.call(value);
-}
-
-
-if(isError(value)){
-base=' '+formatError(value);
-}
-
-if(keys.length===0&&(!array||value.length==0)){
-return braces[0]+base+braces[1];
-}
-
-if(recurseTimes<0){
-if(isRegExp(value)){
-return ctx.stylize(RegExp.prototype.toString.call(value),'regexp');
-}else{
-return ctx.stylize('[Object]','special');
-}
-}
-
-ctx.seen.push(value);
-
-var output;
-if(array){
-output=formatArray(ctx,value,recurseTimes,visibleKeys,keys);
-}else{
-output=keys.map(function(key){
-return formatProperty(ctx,value,recurseTimes,visibleKeys,key,array);
-});
-}
-
-ctx.seen.pop();
-
-return reduceToSingleString(output,base,braces);
-}
-
-
-function formatPrimitive(ctx,value){
-if(isUndefined(value))
-return ctx.stylize('undefined','undefined');
-if(isString(value)){
-var simple='\''+JSON.stringify(value).replace(/^"|"$/g,'').
-replace(/'/g,"\\'").
-replace(/\\"/g,'"')+'\'';
-return ctx.stylize(simple,'string');
-}
-if(isNumber(value))
-return ctx.stylize(''+value,'number');
-if(isBoolean(value))
-return ctx.stylize(''+value,'boolean');
-
-if(isNull(value))
-return ctx.stylize('null','null');
-}
-
-
-function formatError(value){
-return'['+Error.prototype.toString.call(value)+']';
-}
-
-
-function formatArray(ctx,value,recurseTimes,visibleKeys,keys){
-var output=[];
-for(var i=0,l=value.length;i<l;++i){
-if(hasOwnProperty(value,String(i))){
-output.push(formatProperty(ctx,value,recurseTimes,visibleKeys,
-String(i),true));
-}else{
-output.push('');
-}
-}
-keys.forEach(function(key){
-if(!key.match(/^\d+$/)){
-output.push(formatProperty(ctx,value,recurseTimes,visibleKeys,
-key,true));
-}
-});
-return output;
-}
-
-
-function formatProperty(ctx,value,recurseTimes,visibleKeys,key,array){
-var name,str,desc;
-desc=Object.getOwnPropertyDescriptor(value,key)||{value:value[key]};
-if(desc.get){
-if(desc.set){
-str=ctx.stylize('[Getter/Setter]','special');
-}else{
-str=ctx.stylize('[Getter]','special');
-}
-}else{
-if(desc.set){
-str=ctx.stylize('[Setter]','special');
-}
-}
-if(!hasOwnProperty(visibleKeys,key)){
-name='['+key+']';
-}
-if(!str){
-if(ctx.seen.indexOf(desc.value)<0){
-if(isNull(recurseTimes)){
-str=formatValue(ctx,desc.value,null);
-}else{
-str=formatValue(ctx,desc.value,recurseTimes-1);
-}
-if(str.indexOf('\n')>-1){
-if(array){
-str=str.split('\n').map(function(line){
-return'  '+line;
-}).join('\n').substr(2);
-}else{
-str='\n'+str.split('\n').map(function(line){
-return'   '+line;
-}).join('\n');
-}
-}
-}else{
-str=ctx.stylize('[Circular]','special');
-}
-}
-if(isUndefined(name)){
-if(array&&key.match(/^\d+$/)){
-return str;
-}
-name=JSON.stringify(''+key);
-if(name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)){
-name=name.substr(1,name.length-2);
-name=ctx.stylize(name,'name');
-}else{
-name=name.replace(/'/g,"\\'").
-replace(/\\"/g,'"').
-replace(/(^"|"$)/g,"'");
-name=ctx.stylize(name,'string');
-}
-}
-
-return name+': '+str;
-}
-
-
-function reduceToSingleString(output,base,braces){
-var numLinesEst=0;
-var length=output.reduce(function(prev,cur){
-numLinesEst++;
-if(cur.indexOf('\n')>=0)numLinesEst++;
-return prev+cur.replace(/\u001b\[\d\d?m/g,'').length+1;
-},0);
-
-if(length>60){
-return braces[0]+(
-base===''?'':base+'\n ')+
-' '+
-output.join(',\n  ')+
-' '+
-braces[1];
-}
-
-return braces[0]+base+' '+output.join(', ')+' '+braces[1];
-}
-
-
-
-
-function isArray(ar){
-return Array.isArray(ar);
-}
-exports.isArray=isArray;
-
-function isBoolean(arg){
-return typeof arg==='boolean';
-}
-exports.isBoolean=isBoolean;
-
-function isNull(arg){
-return arg===null;
-}
-exports.isNull=isNull;
-
-function isNullOrUndefined(arg){
-return arg==null;
-}
-exports.isNullOrUndefined=isNullOrUndefined;
-
-function isNumber(arg){
-return typeof arg==='number';
-}
-exports.isNumber=isNumber;
-
-function isString(arg){
-return typeof arg==='string';
-}
-exports.isString=isString;
-
-function isSymbol(arg){
-return typeof arg==='symbol';
-}
-exports.isSymbol=isSymbol;
-
-function isUndefined(arg){
-return arg===void 0;
-}
-exports.isUndefined=isUndefined;
-
-function isRegExp(re){
-return isObject(re)&&objectToString(re)==='[object RegExp]';
-}
-exports.isRegExp=isRegExp;
-
-function isObject(arg){
-return typeof arg==='object'&&arg!==null;
-}
-exports.isObject=isObject;
-
-function isDate(d){
-return isObject(d)&&objectToString(d)==='[object Date]';
-}
-exports.isDate=isDate;
-
-function isError(e){
-return isObject(e)&&(
-objectToString(e)==='[object Error]'||e instanceof Error);
-}
-exports.isError=isError;
-
-function isFunction(arg){
-return typeof arg==='function';
-}
-exports.isFunction=isFunction;
-
-function isPrimitive(arg){
-return arg===null||
-typeof arg==='boolean'||
-typeof arg==='number'||
-typeof arg==='string'||
-typeof arg==='symbol'||
-typeof arg==='undefined';
-}
-exports.isPrimitive=isPrimitive;
-
-exports.isBuffer=require('./support/isBuffer');
-
-function objectToString(o){
-return Object.prototype.toString.call(o);
-}
-
-
-function pad(n){
-return n<10?'0'+n.toString(10):n.toString(10);
-}
-
-
-var months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep',
-'Oct','Nov','Dec'];
-
-
-function timestamp(){
-var d=new Date();
-var time=[pad(d.getHours()),
-pad(d.getMinutes()),
-pad(d.getSeconds())].join(':');
-return[d.getDate(),months[d.getMonth()],time].join(' ');
-}
-
-
-
-exports.log=function(){
-console.log('%s - %s',timestamp(),exports.format.apply(exports,arguments));
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-exports.inherits=require('inherits');
-
-exports._extend=function(origin,add){
-
-if(!add||!isObject(add))return origin;
-
-var keys=Object.keys(add);
-var i=keys.length;
-while(i--){
-origin[keys[i]]=add[keys[i]];
-}
-return origin;
-};
-
-function hasOwnProperty(obj,prop){
-return Object.prototype.hasOwnProperty.call(obj,prop);
-}
-
-}).call(this,require('_process'),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{"./support/isBuffer":90,"_process":71,"inherits":89}],92:[function(require,module,exports){
-
-
-var langs=[
-"aa",
-"ab",
-"ae",
-"af",
-"ak",
-"am",
-"an",
-"ar",
-"as",
-"av",
-"ay",
-"az",
-"ba",
-"be",
-"bg",
-"bh",
-"bi",
-"bm",
-"bn",
-"bo",
-"br",
-"bs",
-"ca",
-"ce",
-"ch",
-"co",
-"cr",
-"cs",
-"cu",
-"cv",
-"cy",
-"da",
-"de",
-"dv",
-"dz",
-"ee",
-"el",
-"en",
-"eo",
-"es",
-"et",
-"eu",
-"fa",
-"ff",
-"fi",
-"fj",
-"fo",
-"fr",
-"fy",
-"ga",
-"gd",
-"gl",
-"gn",
-"gu",
-"gv",
-"ha",
-"he",
-"hi",
-"ho",
-"hr",
-"ht",
-"hu",
-"hy",
-"hz",
-"ia",
-"id",
-"ie",
-"ig",
-"ii",
-"ik",
-"in",
-"io",
-"is",
-"it",
-"iu",
-"iw",
-"ja",
-"ji",
-"jv",
-"jw",
-"ka",
-"kg",
-"ki",
-"kj",
-"kk",
-"kl",
-"km",
-"kn",
-"ko",
-"kr",
-"ks",
-"ku",
-"kv",
-"kw",
-"ky",
-"la",
-"lb",
-"lg",
-"li",
-"ln",
-"lo",
-"lt",
-"lu",
-"lv",
-"mg",
-"mh",
-"mi",
-"mk",
-"ml",
-"mn",
-"mo",
-"mr",
-"ms",
-"mt",
-"my",
-"na",
-"nb",
-"nd",
-"ne",
-"ng",
-"nl",
-"nn",
-"no",
-"nr",
-"nv",
-"ny",
-"oc",
-"oj",
-"om",
-"or",
-"os",
-"pa",
-"pi",
-"pl",
-"ps",
-"pt",
-"qu",
-"rm",
-"rn",
-"ro",
-"ru",
-"rw",
-"sa",
-"sc",
-"sd",
-"se",
-"sg",
-"sh",
-"si",
-"sk",
-"sl",
-"sm",
-"sn",
-"so",
-"sq",
-"sr",
-"ss",
-"st",
-"su",
-"sv",
-"sw",
-"ta",
-"te",
-"tg",
-"th",
-"ti",
-"tk",
-"tl",
-"tn",
-"to",
-"tr",
-"ts",
-"tt",
-"tw",
-"ty",
-"ug",
-"uk",
-"ur",
-"uz",
-"ve",
-"vi",
-"vo",
-"wa",
-"wo",
-"xh",
-"yi",
-"yo",
-"za",
-"zh",
-"zu",
-"aaa",
-"aab",
-"aac",
-"aad",
-"aae",
-"aaf",
-"aag",
-"aah",
-"aai",
-"aak",
-"aal",
-"aam",
-"aan",
-"aao",
-"aap",
-"aaq",
-"aas",
-"aat",
-"aau",
-"aav",
-"aaw",
-"aax",
-"aaz",
-"aba",
-"abb",
-"abc",
-"abd",
-"abe",
-"abf",
-"abg",
-"abh",
-"abi",
-"abj",
-"abl",
-"abm",
-"abn",
-"abo",
-"abp",
-"abq",
-"abr",
-"abs",
-"abt",
-"abu",
-"abv",
-"abw",
-"abx",
-"aby",
-"abz",
-"aca",
-"acb",
-"acd",
-"ace",
-"acf",
-"ach",
-"aci",
-"ack",
-"acl",
-"acm",
-"acn",
-"acp",
-"acq",
-"acr",
-"acs",
-"act",
-"acu",
-"acv",
-"acw",
-"acx",
-"acy",
-"acz",
-"ada",
-"adb",
-"add",
-"ade",
-"adf",
-"adg",
-"adh",
-"adi",
-"adj",
-"adl",
-"adn",
-"ado",
-"adp",
-"adq",
-"adr",
-"ads",
-"adt",
-"adu",
-"adw",
-"adx",
-"ady",
-"adz",
-"aea",
-"aeb",
-"aec",
-"aed",
-"aee",
-"aek",
-"ael",
-"aem",
-"aen",
-"aeq",
-"aer",
-"aes",
-"aeu",
-"aew",
-"aey",
-"aez",
-"afa",
-"afb",
-"afd",
-"afe",
-"afg",
-"afh",
-"afi",
-"afk",
-"afn",
-"afo",
-"afp",
-"afs",
-"aft",
-"afu",
-"afz",
-"aga",
-"agb",
-"agc",
-"agd",
-"age",
-"agf",
-"agg",
-"agh",
-"agi",
-"agj",
-"agk",
-"agl",
-"agm",
-"agn",
-"ago",
-"agp",
-"agq",
-"agr",
-"ags",
-"agt",
-"agu",
-"agv",
-"agw",
-"agx",
-"agy",
-"agz",
-"aha",
-"ahb",
-"ahg",
-"ahh",
-"ahi",
-"ahk",
-"ahl",
-"ahm",
-"ahn",
-"aho",
-"ahp",
-"ahr",
-"ahs",
-"aht",
-"aia",
-"aib",
-"aic",
-"aid",
-"aie",
-"aif",
-"aig",
-"aih",
-"aii",
-"aij",
-"aik",
-"ail",
-"aim",
-"ain",
-"aio",
-"aip",
-"aiq",
-"air",
-"ais",
-"ait",
-"aiw",
-"aix",
-"aiy",
-"aja",
-"ajg",
-"aji",
-"ajn",
-"ajp",
-"ajt",
-"aju",
-"ajw",
-"ajz",
-"akb",
-"akc",
-"akd",
-"ake",
-"akf",
-"akg",
-"akh",
-"aki",
-"akj",
-"akk",
-"akl",
-"akm",
-"ako",
-"akp",
-"akq",
-"akr",
-"aks",
-"akt",
-"aku",
-"akv",
-"akw",
-"akx",
-"aky",
-"akz",
-"ala",
-"alc",
-"ald",
-"ale",
-"alf",
-"alg",
-"alh",
-"ali",
-"alj",
-"alk",
-"all",
-"alm",
-"aln",
-"alo",
-"alp",
-"alq",
-"alr",
-"als",
-"alt",
-"alu",
-"alv",
-"alw",
-"alx",
-"aly",
-"alz",
-"ama",
-"amb",
-"amc",
-"ame",
-"amf",
-"amg",
-"ami",
-"amj",
-"amk",
-"aml",
-"amm",
-"amn",
-"amo",
-"amp",
-"amq",
-"amr",
-"ams",
-"amt",
-"amu",
-"amv",
-"amw",
-"amx",
-"amy",
-"amz",
-"ana",
-"anb",
-"anc",
-"and",
-"ane",
-"anf",
-"ang",
-"anh",
-"ani",
-"anj",
-"ank",
-"anl",
-"anm",
-"ann",
-"ano",
-"anp",
-"anq",
-"anr",
-"ans",
-"ant",
-"anu",
-"anv",
-"anw",
-"anx",
-"any",
-"anz",
-"aoa",
-"aob",
-"aoc",
-"aod",
-"aoe",
-"aof",
-"aog",
-"aoh",
-"aoi",
-"aoj",
-"aok",
-"aol",
-"aom",
-"aon",
-"aor",
-"aos",
-"aot",
-"aou",
-"aox",
-"aoz",
-"apa",
-"apb",
-"apc",
-"apd",
-"ape",
-"apf",
-"apg",
-"aph",
-"api",
-"apj",
-"apk",
-"apl",
-"apm",
-"apn",
-"apo",
-"app",
-"apq",
-"apr",
-"aps",
-"apt",
-"apu",
-"apv",
-"apw",
-"apx",
-"apy",
-"apz",
-"aqa",
-"aqc",
-"aqd",
-"aqg",
-"aql",
-"aqm",
-"aqn",
-"aqp",
-"aqr",
-"aqt",
-"aqz",
-"arb",
-"arc",
-"ard",
-"are",
-"arh",
-"ari",
-"arj",
-"ark",
-"arl",
-"arn",
-"aro",
-"arp",
-"arq",
-"arr",
-"ars",
-"art",
-"aru",
-"arv",
-"arw",
-"arx",
-"ary",
-"arz",
-"asa",
-"asb",
-"asc",
-"asd",
-"ase",
-"asf",
-"asg",
-"ash",
-"asi",
-"asj",
-"ask",
-"asl",
-"asn",
-"aso",
-"asp",
-"asq",
-"asr",
-"ass",
-"ast",
-"asu",
-"asv",
-"asw",
-"asx",
-"asy",
-"asz",
-"ata",
-"atb",
-"atc",
-"atd",
-"ate",
-"atg",
-"ath",
-"ati",
-"atj",
-"atk",
-"atl",
-"atm",
-"atn",
-"ato",
-"atp",
-"atq",
-"atr",
-"ats",
-"att",
-"atu",
-"atv",
-"atw",
-"atx",
-"aty",
-"atz",
-"aua",
-"aub",
-"auc",
-"aud",
-"aue",
-"auf",
-"aug",
-"auh",
-"aui",
-"auj",
-"auk",
-"aul",
-"aum",
-"aun",
-"auo",
-"aup",
-"auq",
-"aur",
-"aus",
-"aut",
-"auu",
-"auw",
-"aux",
-"auy",
-"auz",
-"avb",
-"avd",
-"avi",
-"avk",
-"avl",
-"avm",
-"avn",
-"avo",
-"avs",
-"avt",
-"avu",
-"avv",
-"awa",
-"awb",
-"awc",
-"awd",
-"awe",
-"awg",
-"awh",
-"awi",
-"awk",
-"awm",
-"awn",
-"awo",
-"awr",
-"aws",
-"awt",
-"awu",
-"awv",
-"aww",
-"awx",
-"awy",
-"axb",
-"axe",
-"axg",
-"axk",
-"axl",
-"axm",
-"axx",
-"aya",
-"ayb",
-"ayc",
-"ayd",
-"aye",
-"ayg",
-"ayh",
-"ayi",
-"ayk",
-"ayl",
-"ayn",
-"ayo",
-"ayp",
-"ayq",
-"ayr",
-"ays",
-"ayt",
-"ayu",
-"ayx",
-"ayy",
-"ayz",
-"aza",
-"azb",
-"azc",
-"azd",
-"azg",
-"azj",
-"azm",
-"azn",
-"azo",
-"azt",
-"azz",
-"baa",
-"bab",
-"bac",
-"bad",
-"bae",
-"baf",
-"bag",
-"bah",
-"bai",
-"baj",
-"bal",
-"ban",
-"bao",
-"bap",
-"bar",
-"bas",
-"bat",
-"bau",
-"bav",
-"baw",
-"bax",
-"bay",
-"baz",
-"bba",
-"bbb",
-"bbc",
-"bbd",
-"bbe",
-"bbf",
-"bbg",
-"bbh",
-"bbi",
-"bbj",
-"bbk",
-"bbl",
-"bbm",
-"bbn",
-"bbo",
-"bbp",
-"bbq",
-"bbr",
-"bbs",
-"bbt",
-"bbu",
-"bbv",
-"bbw",
-"bbx",
-"bby",
-"bbz",
-"bca",
-"bcb",
-"bcc",
-"bcd",
-"bce",
-"bcf",
-"bcg",
-"bch",
-"bci",
-"bcj",
-"bck",
-"bcl",
-"bcm",
-"bcn",
-"bco",
-"bcp",
-"bcq",
-"bcr",
-"bcs",
-"bct",
-"bcu",
-"bcv",
-"bcw",
-"bcy",
-"bcz",
-"bda",
-"bdb",
-"bdc",
-"bdd",
-"bde",
-"bdf",
-"bdg",
-"bdh",
-"bdi",
-"bdj",
-"bdk",
-"bdl",
-"bdm",
-"bdn",
-"bdo",
-"bdp",
-"bdq",
-"bdr",
-"bds",
-"bdt",
-"bdu",
-"bdv",
-"bdw",
-"bdx",
-"bdy",
-"bdz",
-"bea",
-"beb",
-"bec",
-"bed",
-"bee",
-"bef",
-"beg",
-"beh",
-"bei",
-"bej",
-"bek",
-"bem",
-"beo",
-"bep",
-"beq",
-"ber",
-"bes",
-"bet",
-"beu",
-"bev",
-"bew",
-"bex",
-"bey",
-"bez",
-"bfa",
-"bfb",
-"bfc",
-"bfd",
-"bfe",
-"bff",
-"bfg",
-"bfh",
-"bfi",
-"bfj",
-"bfk",
-"bfl",
-"bfm",
-"bfn",
-"bfo",
-"bfp",
-"bfq",
-"bfr",
-"bfs",
-"bft",
-"bfu",
-"bfw",
-"bfx",
-"bfy",
-"bfz",
-"bga",
-"bgb",
-"bgc",
-"bgd",
-"bge",
-"bgf",
-"bgg",
-"bgi",
-"bgj",
-"bgk",
-"bgl",
-"bgm",
-"bgn",
-"bgo",
-"bgp",
-"bgq",
-"bgr",
-"bgs",
-"bgt",
-"bgu",
-"bgv",
-"bgw",
-"bgx",
-"bgy",
-"bgz",
-"bha",
-"bhb",
-"bhc",
-"bhd",
-"bhe",
-"bhf",
-"bhg",
-"bhh",
-"bhi",
-"bhj",
-"bhk",
-"bhl",
-"bhm",
-"bhn",
-"bho",
-"bhp",
-"bhq",
-"bhr",
-"bhs",
-"bht",
-"bhu",
-"bhv",
-"bhw",
-"bhx",
-"bhy",
-"bhz",
-"bia",
-"bib",
-"bic",
-"bid",
-"bie",
-"bif",
-"big",
-"bij",
-"bik",
-"bil",
-"bim",
-"bin",
-"bio",
-"bip",
-"biq",
-"bir",
-"bit",
-"biu",
-"biv",
-"biw",
-"bix",
-"biy",
-"biz",
-"bja",
-"bjb",
-"bjc",
-"bjd",
-"bje",
-"bjf",
-"bjg",
-"bjh",
-"bji",
-"bjj",
-"bjk",
-"bjl",
-"bjm",
-"bjn",
-"bjo",
-"bjp",
-"bjq",
-"bjr",
-"bjs",
-"bjt",
-"bju",
-"bjv",
-"bjw",
-"bjx",
-"bjy",
-"bjz",
-"bka",
-"bkb",
-"bkc",
-"bkd",
-"bkf",
-"bkg",
-"bkh",
-"bki",
-"bkj",
-"bkk",
-"bkl",
-"bkm",
-"bkn",
-"bko",
-"bkp",
-"bkq",
-"bkr",
-"bks",
-"bkt",
-"bku",
-"bkv",
-"bkw",
-"bkx",
-"bky",
-"bkz",
-"bla",
-"blb",
-"blc",
-"bld",
-"ble",
-"blf",
-"blg",
-"blh",
-"bli",
-"blj",
-"blk",
-"bll",
-"blm",
-"bln",
-"blo",
-"blp",
-"blq",
-"blr",
-"bls",
-"blt",
-"blv",
-"blw",
-"blx",
-"bly",
-"blz",
-"bma",
-"bmb",
-"bmc",
-"bmd",
-"bme",
-"bmf",
-"bmg",
-"bmh",
-"bmi",
-"bmj",
-"bmk",
-"bml",
-"bmm",
-"bmn",
-"bmo",
-"bmp",
-"bmq",
-"bmr",
-"bms",
-"bmt",
-"bmu",
-"bmv",
-"bmw",
-"bmx",
-"bmy",
-"bmz",
-"bna",
-"bnb",
-"bnc",
-"bnd",
-"bne",
-"bnf",
-"bng",
-"bni",
-"bnj",
-"bnk",
-"bnl",
-"bnm",
-"bnn",
-"bno",
-"bnp",
-"bnq",
-"bnr",
-"bns",
-"bnt",
-"bnu",
-"bnv",
-"bnw",
-"bnx",
-"bny",
-"bnz",
-"boa",
-"bob",
-"boe",
-"bof",
-"bog",
-"boh",
-"boi",
-"boj",
-"bok",
-"bol",
-"bom",
-"bon",
-"boo",
-"bop",
-"boq",
-"bor",
-"bot",
-"bou",
-"bov",
-"bow",
-"box",
-"boy",
-"boz",
-"bpa",
-"bpb",
-"bpd",
-"bpg",
-"bph",
-"bpi",
-"bpj",
-"bpk",
-"bpl",
-"bpm",
-"bpn",
-"bpo",
-"bpp",
-"bpq",
-"bpr",
-"bps",
-"bpt",
-"bpu",
-"bpv",
-"bpw",
-"bpx",
-"bpy",
-"bpz",
-"bqa",
-"bqb",
-"bqc",
-"bqd",
-"bqf",
-"bqg",
-"bqh",
-"bqi",
-"bqj",
-"bqk",
-"bql",
-"bqm",
-"bqn",
-"bqo",
-"bqp",
-"bqq",
-"bqr",
-"bqs",
-"bqt",
-"bqu",
-"bqv",
-"bqw",
-"bqx",
-"bqy",
-"bqz",
-"bra",
-"brb",
-"brc",
-"brd",
-"brf",
-"brg",
-"brh",
-"bri",
-"brj",
-"brk",
-"brl",
-"brm",
-"brn",
-"bro",
-"brp",
-"brq",
-"brr",
-"brs",
-"brt",
-"bru",
-"brv",
-"brw",
-"brx",
-"bry",
-"brz",
-"bsa",
-"bsb",
-"bsc",
-"bse",
-"bsf",
-"bsg",
-"bsh",
-"bsi",
-"bsj",
-"bsk",
-"bsl",
-"bsm",
-"bsn",
-"bso",
-"bsp",
-"bsq",
-"bsr",
-"bss",
-"bst",
-"bsu",
-"bsv",
-"bsw",
-"bsx",
-"bsy",
-"bta",
-"btb",
-"btc",
-"btd",
-"bte",
-"btf",
-"btg",
-"bth",
-"bti",
-"btj",
-"btk",
-"btl",
-"btm",
-"btn",
-"bto",
-"btp",
-"btq",
-"btr",
-"bts",
-"btt",
-"btu",
-"btv",
-"btw",
-"btx",
-"bty",
-"btz",
-"bua",
-"bub",
-"buc",
-"bud",
-"bue",
-"buf",
-"bug",
-"buh",
-"bui",
-"buj",
-"buk",
-"bum",
-"bun",
-"buo",
-"bup",
-"buq",
-"bus",
-"but",
-"buu",
-"buv",
-"buw",
-"bux",
-"buy",
-"buz",
-"bva",
-"bvb",
-"bvc",
-"bvd",
-"bve",
-"bvf",
-"bvg",
-"bvh",
-"bvi",
-"bvj",
-"bvk",
-"bvl",
-"bvm",
-"bvn",
-"bvo",
-"bvp",
-"bvq",
-"bvr",
-"bvt",
-"bvu",
-"bvv",
-"bvw",
-"bvx",
-"bvy",
-"bvz",
-"bwa",
-"bwb",
-"bwc",
-"bwd",
-"bwe",
-"bwf",
-"bwg",
-"bwh",
-"bwi",
-"bwj",
-"bwk",
-"bwl",
-"bwm",
-"bwn",
-"bwo",
-"bwp",
-"bwq",
-"bwr",
-"bws",
-"bwt",
-"bwu",
-"bww",
-"bwx",
-"bwy",
-"bwz",
-"bxa",
-"bxb",
-"bxc",
-"bxd",
-"bxe",
-"bxf",
-"bxg",
-"bxh",
-"bxi",
-"bxj",
-"bxk",
-"bxl",
-"bxm",
-"bxn",
-"bxo",
-"bxp",
-"bxq",
-"bxr",
-"bxs",
-"bxu",
-"bxv",
-"bxw",
-"bxx",
-"bxz",
-"bya",
-"byb",
-"byc",
-"byd",
-"bye",
-"byf",
-"byg",
-"byh",
-"byi",
-"byj",
-"byk",
-"byl",
-"bym",
-"byn",
-"byo",
-"byp",
-"byq",
-"byr",
-"bys",
-"byt",
-"byv",
-"byw",
-"byx",
-"byy",
-"byz",
-"bza",
-"bzb",
-"bzc",
-"bzd",
-"bze",
-"bzf",
-"bzg",
-"bzh",
-"bzi",
-"bzj",
-"bzk",
-"bzl",
-"bzm",
-"bzn",
-"bzo",
-"bzp",
-"bzq",
-"bzr",
-"bzs",
-"bzt",
-"bzu",
-"bzv",
-"bzw",
-"bzx",
-"bzy",
-"bzz",
-"caa",
-"cab",
-"cac",
-"cad",
-"cae",
-"caf",
-"cag",
-"cah",
-"cai",
-"caj",
-"cak",
-"cal",
-"cam",
-"can",
-"cao",
-"cap",
-"caq",
-"car",
-"cas",
-"cau",
-"cav",
-"caw",
-"cax",
-"cay",
-"caz",
-"cba",
-"cbb",
-"cbc",
-"cbd",
-"cbe",
-"cbg",
-"cbh",
-"cbi",
-"cbj",
-"cbk",
-"cbl",
-"cbn",
-"cbo",
-"cbq",
-"cbr",
-"cbs",
-"cbt",
-"cbu",
-"cbv",
-"cbw",
-"cby",
-"cca",
-"ccc",
-"ccd",
-"cce",
-"ccg",
-"cch",
-"ccj",
-"ccl",
-"ccm",
-"ccn",
-"cco",
-"ccp",
-"ccq",
-"ccr",
-"ccs",
-"cda",
-"cdc",
-"cdd",
-"cde",
-"cdf",
-"cdg",
-"cdh",
-"cdi",
-"cdj",
-"cdm",
-"cdn",
-"cdo",
-"cdr",
-"cds",
-"cdy",
-"cdz",
-"cea",
-"ceb",
-"ceg",
-"cek",
-"cel",
-"cen",
-"cet",
-"cfa",
-"cfd",
-"cfg",
-"cfm",
-"cga",
-"cgc",
-"cgg",
-"cgk",
-"chb",
-"chc",
-"chd",
-"chf",
-"chg",
-"chh",
-"chj",
-"chk",
-"chl",
-"chm",
-"chn",
-"cho",
-"chp",
-"chq",
-"chr",
-"cht",
-"chw",
-"chx",
-"chy",
-"chz",
-"cia",
-"cib",
-"cic",
-"cid",
-"cie",
-"cih",
-"cik",
-"cim",
-"cin",
-"cip",
-"cir",
-"ciw",
-"ciy",
-"cja",
-"cje",
-"cjh",
-"cji",
-"cjk",
-"cjm",
-"cjn",
-"cjo",
-"cjp",
-"cjr",
-"cjs",
-"cjv",
-"cjy",
-"cka",
-"ckb",
-"ckh",
-"ckl",
-"ckn",
-"cko",
-"ckq",
-"ckr",
-"cks",
-"ckt",
-"cku",
-"ckv",
-"ckx",
-"cky",
-"ckz",
-"cla",
-"clc",
-"cld",
-"cle",
-"clh",
-"cli",
-"clj",
-"clk",
-"cll",
-"clm",
-"clo",
-"clt",
-"clu",
-"clw",
-"cly",
-"cma",
-"cmc",
-"cme",
-"cmg",
-"cmi",
-"cmk",
-"cml",
-"cmm",
-"cmn",
-"cmo",
-"cmr",
-"cms",
-"cmt",
-"cna",
-"cnb",
-"cnc",
-"cng",
-"cnh",
-"cni",
-"cnk",
-"cnl",
-"cno",
-"cns",
-"cnt",
-"cnu",
-"cnw",
-"cnx",
-"coa",
-"cob",
-"coc",
-"cod",
-"coe",
-"cof",
-"cog",
-"coh",
-"coj",
-"cok",
-"col",
-"com",
-"con",
-"coo",
-"cop",
-"coq",
-"cot",
-"cou",
-"cov",
-"cow",
-"cox",
-"coy",
-"coz",
-"cpa",
-"cpb",
-"cpc",
-"cpe",
-"cpf",
-"cpg",
-"cpi",
-"cpn",
-"cpo",
-"cpp",
-"cps",
-"cpu",
-"cpx",
-"cpy",
-"cqd",
-"cqu",
-"cra",
-"crb",
-"crc",
-"crd",
-"crf",
-"crg",
-"crh",
-"cri",
-"crj",
-"crk",
-"crl",
-"crm",
-"crn",
-"cro",
-"crp",
-"crq",
-"crr",
-"crs",
-"crt",
-"crv",
-"crw",
-"crx",
-"cry",
-"crz",
-"csa",
-"csb",
-"csc",
-"csd",
-"cse",
-"csf",
-"csg",
-"csh",
-"csi",
-"csj",
-"csk",
-"csl",
-"csm",
-"csn",
-"cso",
-"csq",
-"csr",
-"css",
-"cst",
-"csu",
-"csv",
-"csw",
-"csy",
-"csz",
-"cta",
-"ctc",
-"ctd",
-"cte",
-"ctg",
-"cth",
-"ctl",
-"ctm",
-"ctn",
-"cto",
-"ctp",
-"cts",
-"ctt",
-"ctu",
-"ctz",
-"cua",
-"cub",
-"cuc",
-"cug",
-"cuh",
-"cui",
-"cuj",
-"cuk",
-"cul",
-"cum",
-"cuo",
-"cup",
-"cuq",
-"cur",
-"cus",
-"cut",
-"cuu",
-"cuv",
-"cuw",
-"cux",
-"cvg",
-"cvn",
-"cwa",
-"cwb",
-"cwd",
-"cwe",
-"cwg",
-"cwt",
-"cya",
-"cyb",
-"cyo",
-"czh",
-"czk",
-"czn",
-"czo",
-"czt",
-"daa",
-"dac",
-"dad",
-"dae",
-"daf",
-"dag",
-"dah",
-"dai",
-"daj",
-"dak",
-"dal",
-"dam",
-"dao",
-"dap",
-"daq",
-"dar",
-"das",
-"dau",
-"dav",
-"daw",
-"dax",
-"day",
-"daz",
-"dba",
-"dbb",
-"dbd",
-"dbe",
-"dbf",
-"dbg",
-"dbi",
-"dbj",
-"dbl",
-"dbm",
-"dbn",
-"dbo",
-"dbp",
-"dbq",
-"dbr",
-"dbt",
-"dbu",
-"dbv",
-"dbw",
-"dby",
-"dcc",
-"dcr",
-"dda",
-"ddd",
-"dde",
-"ddg",
-"ddi",
-"ddj",
-"ddn",
-"ddo",
-"ddr",
-"dds",
-"ddw",
-"dec",
-"ded",
-"dee",
-"def",
-"deg",
-"deh",
-"dei",
-"dek",
-"del",
-"dem",
-"den",
-"dep",
-"deq",
-"der",
-"des",
-"dev",
-"dez",
-"dga",
-"dgb",
-"dgc",
-"dgd",
-"dge",
-"dgg",
-"dgh",
-"dgi",
-"dgk",
-"dgl",
-"dgn",
-"dgo",
-"dgr",
-"dgs",
-"dgt",
-"dgu",
-"dgw",
-"dgx",
-"dgz",
-"dha",
-"dhd",
-"dhg",
-"dhi",
-"dhl",
-"dhm",
-"dhn",
-"dho",
-"dhr",
-"dhs",
-"dhu",
-"dhv",
-"dhw",
-"dhx",
-"dia",
-"dib",
-"dic",
-"did",
-"dif",
-"dig",
-"dih",
-"dii",
-"dij",
-"dik",
-"dil",
-"dim",
-"din",
-"dio",
-"dip",
-"diq",
-"dir",
-"dis",
-"dit",
-"diu",
-"diw",
-"dix",
-"diy",
-"diz",
-"dja",
-"djb",
-"djc",
-"djd",
-"dje",
-"djf",
-"dji",
-"djj",
-"djk",
-"djl",
-"djm",
-"djn",
-"djo",
-"djr",
-"dju",
-"djw",
-"dka",
-"dkk",
-"dkl",
-"dkr",
-"dks",
-"dkx",
-"dlg",
-"dlk",
-"dlm",
-"dln",
-"dma",
-"dmb",
-"dmc",
-"dmd",
-"dme",
-"dmg",
-"dmk",
-"dml",
-"dmm",
-"dmn",
-"dmo",
-"dmr",
-"dms",
-"dmu",
-"dmv",
-"dmw",
-"dmx",
-"dmy",
-"dna",
-"dnd",
-"dne",
-"dng",
-"dni",
-"dnj",
-"dnk",
-"dnn",
-"dnr",
-"dnt",
-"dnu",
-"dnv",
-"dnw",
-"dny",
-"doa",
-"dob",
-"doc",
-"doe",
-"dof",
-"doh",
-"doi",
-"dok",
-"dol",
-"don",
-"doo",
-"dop",
-"doq",
-"dor",
-"dos",
-"dot",
-"dov",
-"dow",
-"dox",
-"doy",
-"doz",
-"dpp",
-"dra",
-"drb",
-"drc",
-"drd",
-"dre",
-"drg",
-"drh",
-"dri",
-"drl",
-"drn",
-"dro",
-"drq",
-"drr",
-"drs",
-"drt",
-"dru",
-"drw",
-"dry",
-"dsb",
-"dse",
-"dsh",
-"dsi",
-"dsl",
-"dsn",
-"dso",
-"dsq",
-"dta",
-"dtb",
-"dtd",
-"dth",
-"dti",
-"dtk",
-"dtm",
-"dtn",
-"dto",
-"dtp",
-"dtr",
-"dts",
-"dtt",
-"dtu",
-"dty",
-"dua",
-"dub",
-"duc",
-"dud",
-"due",
-"duf",
-"dug",
-"duh",
-"dui",
-"duj",
-"duk",
-"dul",
-"dum",
-"dun",
-"duo",
-"dup",
-"duq",
-"dur",
-"dus",
-"duu",
-"duv",
-"duw",
-"dux",
-"duy",
-"duz",
-"dva",
-"dwa",
-"dwl",
-"dwr",
-"dws",
-"dwu",
-"dww",
-"dwy",
-"dya",
-"dyb",
-"dyd",
-"dyg",
-"dyi",
-"dym",
-"dyn",
-"dyo",
-"dyu",
-"dyy",
-"dza",
-"dzd",
-"dze",
-"dzg",
-"dzl",
-"dzn",
-"eaa",
-"ebg",
-"ebk",
-"ebo",
-"ebr",
-"ebu",
-"ecr",
-"ecs",
-"ecy",
-"eee",
-"efa",
-"efe",
-"efi",
-"ega",
-"egl",
-"ego",
-"egx",
-"egy",
-"ehu",
-"eip",
-"eit",
-"eiv",
-"eja",
-"eka",
-"ekc",
-"eke",
-"ekg",
-"eki",
-"ekk",
-"ekl",
-"ekm",
-"eko",
-"ekp",
-"ekr",
-"eky",
-"ele",
-"elh",
-"eli",
-"elk",
-"elm",
-"elo",
-"elp",
-"elu",
-"elx",
-"ema",
-"emb",
-"eme",
-"emg",
-"emi",
-"emk",
-"emm",
-"emn",
-"emo",
-"emp",
-"ems",
-"emu",
-"emw",
-"emx",
-"emy",
-"ena",
-"enb",
-"enc",
-"end",
-"enf",
-"enh",
-"enl",
-"enm",
-"enn",
-"eno",
-"enq",
-"enr",
-"enu",
-"env",
-"enw",
-"enx",
-"eot",
-"epi",
-"era",
-"erg",
-"erh",
-"eri",
-"erk",
-"ero",
-"err",
-"ers",
-"ert",
-"erw",
-"ese",
-"esg",
-"esh",
-"esi",
-"esk",
-"esl",
-"esm",
-"esn",
-"eso",
-"esq",
-"ess",
-"esu",
-"esx",
-"esy",
-"etb",
-"etc",
-"eth",
-"etn",
-"eto",
-"etr",
-"ets",
-"ett",
-"etu",
-"etx",
-"etz",
-"euq",
-"eve",
-"evh",
-"evn",
-"ewo",
-"ext",
-"eya",
-"eyo",
-"eza",
-"eze",
-"faa",
-"fab",
-"fad",
-"faf",
-"fag",
-"fah",
-"fai",
-"faj",
-"fak",
-"fal",
-"fam",
-"fan",
-"fap",
-"far",
-"fat",
-"fau",
-"fax",
-"fay",
-"faz",
-"fbl",
-"fcs",
-"fer",
-"ffi",
-"ffm",
-"fgr",
-"fia",
-"fie",
-"fil",
-"fip",
-"fir",
-"fit",
-"fiu",
-"fiw",
-"fkk",
-"fkv",
-"fla",
-"flh",
-"fli",
-"fll",
-"fln",
-"flr",
-"fly",
-"fmp",
-"fmu",
-"fnb",
-"fng",
-"fni",
-"fod",
-"foi",
-"fom",
-"fon",
-"for",
-"fos",
-"fox",
-"fpe",
-"fqs",
-"frc",
-"frd",
-"frk",
-"frm",
-"fro",
-"frp",
-"frq",
-"frr",
-"frs",
-"frt",
-"fse",
-"fsl",
-"fss",
-"fub",
-"fuc",
-"fud",
-"fue",
-"fuf",
-"fuh",
-"fui",
-"fuj",
-"fum",
-"fun",
-"fuq",
-"fur",
-"fut",
-"fuu",
-"fuv",
-"fuy",
-"fvr",
-"fwa",
-"fwe",
-"gaa",
-"gab",
-"gac",
-"gad",
-"gae",
-"gaf",
-"gag",
-"gah",
-"gai",
-"gaj",
-"gak",
-"gal",
-"gam",
-"gan",
-"gao",
-"gap",
-"gaq",
-"gar",
-"gas",
-"gat",
-"gau",
-"gav",
-"gaw",
-"gax",
-"gay",
-"gaz",
-"gba",
-"gbb",
-"gbc",
-"gbd",
-"gbe",
-"gbf",
-"gbg",
-"gbh",
-"gbi",
-"gbj",
-"gbk",
-"gbl",
-"gbm",
-"gbn",
-"gbo",
-"gbp",
-"gbq",
-"gbr",
-"gbs",
-"gbu",
-"gbv",
-"gbw",
-"gbx",
-"gby",
-"gbz",
-"gcc",
-"gcd",
-"gce",
-"gcf",
-"gcl",
-"gcn",
-"gcr",
-"gct",
-"gda",
-"gdb",
-"gdc",
-"gdd",
-"gde",
-"gdf",
-"gdg",
-"gdh",
-"gdi",
-"gdj",
-"gdk",
-"gdl",
-"gdm",
-"gdn",
-"gdo",
-"gdq",
-"gdr",
-"gds",
-"gdt",
-"gdu",
-"gdx",
-"gea",
-"geb",
-"gec",
-"ged",
-"geg",
-"geh",
-"gei",
-"gej",
-"gek",
-"gel",
-"gem",
-"geq",
-"ges",
-"gev",
-"gew",
-"gex",
-"gey",
-"gez",
-"gfk",
-"gft",
-"gfx",
-"gga",
-"ggb",
-"ggd",
-"gge",
-"ggg",
-"ggk",
-"ggl",
-"ggn",
-"ggo",
-"ggr",
-"ggt",
-"ggu",
-"ggw",
-"gha",
-"ghc",
-"ghe",
-"ghh",
-"ghk",
-"ghl",
-"ghn",
-"gho",
-"ghr",
-"ghs",
-"ght",
-"gia",
-"gib",
-"gic",
-"gid",
-"gie",
-"gig",
-"gih",
-"gil",
-"gim",
-"gin",
-"gio",
-"gip",
-"giq",
-"gir",
-"gis",
-"git",
-"giu",
-"giw",
-"gix",
-"giy",
-"giz",
-"gji",
-"gjk",
-"gjm",
-"gjn",
-"gjr",
-"gju",
-"gka",
-"gke",
-"gkn",
-"gko",
-"gkp",
-"gku",
-"glc",
-"gld",
-"glh",
-"gli",
-"glj",
-"glk",
-"gll",
-"glo",
-"glr",
-"glu",
-"glw",
-"gly",
-"gma",
-"gmb",
-"gmd",
-"gme",
-"gmg",
-"gmh",
-"gml",
-"gmm",
-"gmn",
-"gmq",
-"gmu",
-"gmv",
-"gmw",
-"gmx",
-"gmy",
-"gmz",
-"gna",
-"gnb",
-"gnc",
-"gnd",
-"gne",
-"gng",
-"gnh",
-"gni",
-"gnk",
-"gnl",
-"gnm",
-"gnn",
-"gno",
-"gnq",
-"gnr",
-"gnt",
-"gnu",
-"gnw",
-"gnz",
-"goa",
-"gob",
-"goc",
-"god",
-"goe",
-"gof",
-"gog",
-"goh",
-"goi",
-"goj",
-"gok",
-"gol",
-"gom",
-"gon",
-"goo",
-"gop",
-"goq",
-"gor",
-"gos",
-"got",
-"gou",
-"gow",
-"gox",
-"goy",
-"goz",
-"gpa",
-"gpe",
-"gpn",
-"gqa",
-"gqi",
-"gqn",
-"gqr",
-"gqu",
-"gra",
-"grb",
-"grc",
-"grd",
-"grg",
-"grh",
-"gri",
-"grj",
-"grk",
-"grm",
-"gro",
-"grq",
-"grr",
-"grs",
-"grt",
-"gru",
-"grv",
-"grw",
-"grx",
-"gry",
-"grz",
-"gse",
-"gsg",
-"gsl",
-"gsm",
-"gsn",
-"gso",
-"gsp",
-"gss",
-"gsw",
-"gta",
-"gti",
-"gtu",
-"gua",
-"gub",
-"guc",
-"gud",
-"gue",
-"guf",
-"gug",
-"guh",
-"gui",
-"guk",
-"gul",
-"gum",
-"gun",
-"guo",
-"gup",
-"guq",
-"gur",
-"gus",
-"gut",
-"guu",
-"guv",
-"guw",
-"gux",
-"guz",
-"gva",
-"gvc",
-"gve",
-"gvf",
-"gvj",
-"gvl",
-"gvm",
-"gvn",
-"gvo",
-"gvp",
-"gvr",
-"gvs",
-"gvy",
-"gwa",
-"gwb",
-"gwc",
-"gwd",
-"gwe",
-"gwf",
-"gwg",
-"gwi",
-"gwj",
-"gwm",
-"gwn",
-"gwr",
-"gwt",
-"gwu",
-"gww",
-"gwx",
-"gxx",
-"gya",
-"gyb",
-"gyd",
-"gye",
-"gyf",
-"gyg",
-"gyi",
-"gyl",
-"gym",
-"gyn",
-"gyr",
-"gyy",
-"gza",
-"gzi",
-"gzn",
-"haa",
-"hab",
-"hac",
-"had",
-"hae",
-"haf",
-"hag",
-"hah",
-"hai",
-"haj",
-"hak",
-"hal",
-"ham",
-"han",
-"hao",
-"hap",
-"haq",
-"har",
-"has",
-"hav",
-"haw",
-"hax",
-"hay",
-"haz",
-"hba",
-"hbb",
-"hbn",
-"hbo",
-"hbu",
-"hca",
-"hch",
-"hdn",
-"hds",
-"hdy",
-"hea",
-"hed",
-"heg",
-"heh",
-"hei",
-"hem",
-"hgm",
-"hgw",
-"hhi",
-"hhr",
-"hhy",
-"hia",
-"hib",
-"hid",
-"hif",
-"hig",
-"hih",
-"hii",
-"hij",
-"hik",
-"hil",
-"him",
-"hio",
-"hir",
-"hit",
-"hiw",
-"hix",
-"hji",
-"hka",
-"hke",
-"hkk",
-"hks",
-"hla",
-"hlb",
-"hld",
-"hle",
-"hlt",
-"hlu",
-"hma",
-"hmb",
-"hmc",
-"hmd",
-"hme",
-"hmf",
-"hmg",
-"hmh",
-"hmi",
-"hmj",
-"hmk",
-"hml",
-"hmm",
-"hmn",
-"hmp",
-"hmq",
-"hmr",
-"hms",
-"hmt",
-"hmu",
-"hmv",
-"hmw",
-"hmx",
-"hmy",
-"hmz",
-"hna",
-"hnd",
-"hne",
-"hnh",
-"hni",
-"hnj",
-"hnn",
-"hno",
-"hns",
-"hnu",
-"hoa",
-"hob",
-"hoc",
-"hod",
-"hoe",
-"hoh",
-"hoi",
-"hoj",
-"hok",
-"hol",
-"hom",
-"hoo",
-"hop",
-"hor",
-"hos",
-"hot",
-"hov",
-"how",
-"hoy",
-"hoz",
-"hpo",
-"hps",
-"hra",
-"hrc",
-"hre",
-"hrk",
-"hrm",
-"hro",
-"hrp",
-"hrr",
-"hrt",
-"hru",
-"hrw",
-"hrx",
-"hrz",
-"hsb",
-"hsh",
-"hsl",
-"hsn",
-"hss",
-"hti",
-"hto",
-"hts",
-"htu",
-"htx",
-"hub",
-"huc",
-"hud",
-"hue",
-"huf",
-"hug",
-"huh",
-"hui",
-"huj",
-"huk",
-"hul",
-"hum",
-"huo",
-"hup",
-"huq",
-"hur",
-"hus",
-"hut",
-"huu",
-"huv",
-"huw",
-"hux",
-"huy",
-"huz",
-"hvc",
-"hve",
-"hvk",
-"hvn",
-"hvv",
-"hwa",
-"hwc",
-"hwo",
-"hya",
-"hyx",
-"iai",
-"ian",
-"iap",
-"iar",
-"iba",
-"ibb",
-"ibd",
-"ibe",
-"ibg",
-"ibh",
-"ibi",
-"ibl",
-"ibm",
-"ibn",
-"ibr",
-"ibu",
-"iby",
-"ica",
-"ich",
-"icl",
-"icr",
-"ida",
-"idb",
-"idc",
-"idd",
-"ide",
-"idi",
-"idr",
-"ids",
-"idt",
-"idu",
-"ifa",
-"ifb",
-"ife",
-"iff",
-"ifk",
-"ifm",
-"ifu",
-"ify",
-"igb",
-"ige",
-"igg",
-"igl",
-"igm",
-"ign",
-"igo",
-"igs",
-"igw",
-"ihb",
-"ihi",
-"ihp",
-"ihw",
-"iin",
-"iir",
-"ijc",
-"ije",
-"ijj",
-"ijn",
-"ijo",
-"ijs",
-"ike",
-"iki",
-"ikk",
-"ikl",
-"iko",
-"ikp",
-"ikr",
-"iks",
-"ikt",
-"ikv",
-"ikw",
-"ikx",
-"ikz",
-"ila",
-"ilb",
-"ilg",
-"ili",
-"ilk",
-"ill",
-"ilm",
-"ilo",
-"ilp",
-"ils",
-"ilu",
-"ilv",
-"ilw",
-"ima",
-"ime",
-"imi",
-"iml",
-"imn",
-"imo",
-"imr",
-"ims",
-"imy",
-"inb",
-"inc",
-"ine",
-"ing",
-"inh",
-"inj",
-"inl",
-"inm",
-"inn",
-"ino",
-"inp",
-"ins",
-"int",
-"inz",
-"ior",
-"iou",
-"iow",
-"ipi",
-"ipo",
-"iqu",
-"iqw",
-"ira",
-"ire",
-"irh",
-"iri",
-"irk",
-"irn",
-"iro",
-"irr",
-"iru",
-"irx",
-"iry",
-"isa",
-"isc",
-"isd",
-"ise",
-"isg",
-"ish",
-"isi",
-"isk",
-"ism",
-"isn",
-"iso",
-"isr",
-"ist",
-"isu",
-"itb",
-"itc",
-"itd",
-"ite",
-"iti",
-"itk",
-"itl",
-"itm",
-"ito",
-"itr",
-"its",
-"itt",
-"itv",
-"itw",
-"itx",
-"ity",
-"itz",
-"ium",
-"ivb",
-"ivv",
-"iwk",
-"iwm",
-"iwo",
-"iws",
-"ixc",
-"ixl",
-"iya",
-"iyo",
-"iyx",
-"izh",
-"izi",
-"izr",
-"izz",
-"jaa",
-"jab",
-"jac",
-"jad",
-"jae",
-"jaf",
-"jah",
-"jaj",
-"jak",
-"jal",
-"jam",
-"jan",
-"jao",
-"jaq",
-"jar",
-"jas",
-"jat",
-"jau",
-"jax",
-"jay",
-"jaz",
-"jbe",
-"jbi",
-"jbj",
-"jbk",
-"jbn",
-"jbo",
-"jbr",
-"jbt",
-"jbu",
-"jbw",
-"jcs",
-"jct",
-"jda",
-"jdg",
-"jdt",
-"jeb",
-"jee",
-"jeg",
-"jeh",
-"jei",
-"jek",
-"jel",
-"jen",
-"jer",
-"jet",
-"jeu",
-"jgb",
-"jge",
-"jgk",
-"jgo",
-"jhi",
-"jhs",
-"jia",
-"jib",
-"jic",
-"jid",
-"jie",
-"jig",
-"jih",
-"jii",
-"jil",
-"jim",
-"jio",
-"jiq",
-"jit",
-"jiu",
-"jiv",
-"jiy",
-"jje",
-"jjr",
-"jka",
-"jkm",
-"jko",
-"jkp",
-"jkr",
-"jku",
-"jle",
-"jls",
-"jma",
-"jmb",
-"jmc",
-"jmd",
-"jmi",
-"jml",
-"jmn",
-"jmr",
-"jms",
-"jmw",
-"jmx",
-"jna",
-"jnd",
-"jng",
-"jni",
-"jnj",
-"jnl",
-"jns",
-"job",
-"jod",
-"jog",
-"jor",
-"jos",
-"jow",
-"jpa",
-"jpr",
-"jpx",
-"jqr",
-"jra",
-"jrb",
-"jrr",
-"jrt",
-"jru",
-"jsl",
-"jua",
-"jub",
-"juc",
-"jud",
-"juh",
-"jui",
-"juk",
-"jul",
-"jum",
-"jun",
-"juo",
-"jup",
-"jur",
-"jus",
-"jut",
-"juu",
-"juw",
-"juy",
-"jvd",
-"jvn",
-"jwi",
-"jya",
-"jye",
-"jyy",
-"kaa",
-"kab",
-"kac",
-"kad",
-"kae",
-"kaf",
-"kag",
-"kah",
-"kai",
-"kaj",
-"kak",
-"kam",
-"kao",
-"kap",
-"kaq",
-"kar",
-"kav",
-"kaw",
-"kax",
-"kay",
-"kba",
-"kbb",
-"kbc",
-"kbd",
-"kbe",
-"kbf",
-"kbg",
-"kbh",
-"kbi",
-"kbj",
-"kbk",
-"kbl",
-"kbm",
-"kbn",
-"kbo",
-"kbp",
-"kbq",
-"kbr",
-"kbs",
-"kbt",
-"kbu",
-"kbv",
-"kbw",
-"kbx",
-"kby",
-"kbz",
-"kca",
-"kcb",
-"kcc",
-"kcd",
-"kce",
-"kcf",
-"kcg",
-"kch",
-"kci",
-"kcj",
-"kck",
-"kcl",
-"kcm",
-"kcn",
-"kco",
-"kcp",
-"kcq",
-"kcr",
-"kcs",
-"kct",
-"kcu",
-"kcv",
-"kcw",
-"kcx",
-"kcy",
-"kcz",
-"kda",
-"kdc",
-"kdd",
-"kde",
-"kdf",
-"kdg",
-"kdh",
-"kdi",
-"kdj",
-"kdk",
-"kdl",
-"kdm",
-"kdn",
-"kdo",
-"kdp",
-"kdq",
-"kdr",
-"kdt",
-"kdu",
-"kdv",
-"kdw",
-"kdx",
-"kdy",
-"kdz",
-"kea",
-"keb",
-"kec",
-"ked",
-"kee",
-"kef",
-"keg",
-"keh",
-"kei",
-"kej",
-"kek",
-"kel",
-"kem",
-"ken",
-"keo",
-"kep",
-"keq",
-"ker",
-"kes",
-"ket",
-"keu",
-"kev",
-"kew",
-"kex",
-"key",
-"kez",
-"kfa",
-"kfb",
-"kfc",
-"kfd",
-"kfe",
-"kff",
-"kfg",
-"kfh",
-"kfi",
-"kfj",
-"kfk",
-"kfl",
-"kfm",
-"kfn",
-"kfo",
-"kfp",
-"kfq",
-"kfr",
-"kfs",
-"kft",
-"kfu",
-"kfv",
-"kfw",
-"kfx",
-"kfy",
-"kfz",
-"kga",
-"kgb",
-"kgc",
-"kgd",
-"kge",
-"kgf",
-"kgg",
-"kgh",
-"kgi",
-"kgj",
-"kgk",
-"kgl",
-"kgm",
-"kgn",
-"kgo",
-"kgp",
-"kgq",
-"kgr",
-"kgs",
-"kgt",
-"kgu",
-"kgv",
-"kgw",
-"kgx",
-"kgy",
-"kha",
-"khb",
-"khc",
-"khd",
-"khe",
-"khf",
-"khg",
-"khh",
-"khi",
-"khj",
-"khk",
-"khl",
-"khn",
-"kho",
-"khp",
-"khq",
-"khr",
-"khs",
-"kht",
-"khu",
-"khv",
-"khw",
-"khx",
-"khy",
-"khz",
-"kia",
-"kib",
-"kic",
-"kid",
-"kie",
-"kif",
-"kig",
-"kih",
-"kii",
-"kij",
-"kil",
-"kim",
-"kio",
-"kip",
-"kiq",
-"kis",
-"kit",
-"kiu",
-"kiv",
-"kiw",
-"kix",
-"kiy",
-"kiz",
-"kja",
-"kjb",
-"kjc",
-"kjd",
-"kje",
-"kjf",
-"kjg",
-"kjh",
-"kji",
-"kjj",
-"kjk",
-"kjl",
-"kjm",
-"kjn",
-"kjo",
-"kjp",
-"kjq",
-"kjr",
-"kjs",
-"kjt",
-"kju",
-"kjv",
-"kjx",
-"kjy",
-"kjz",
-"kka",
-"kkb",
-"kkc",
-"kkd",
-"kke",
-"kkf",
-"kkg",
-"kkh",
-"kki",
-"kkj",
-"kkk",
-"kkl",
-"kkm",
-"kkn",
-"kko",
-"kkp",
-"kkq",
-"kkr",
-"kks",
-"kkt",
-"kku",
-"kkv",
-"kkw",
-"kkx",
-"kky",
-"kkz",
-"kla",
-"klb",
-"klc",
-"kld",
-"kle",
-"klf",
-"klg",
-"klh",
-"kli",
-"klj",
-"klk",
-"kll",
-"klm",
-"kln",
-"klo",
-"klp",
-"klq",
-"klr",
-"kls",
-"klt",
-"klu",
-"klv",
-"klw",
-"klx",
-"kly",
-"klz",
-"kma",
-"kmb",
-"kmc",
-"kmd",
-"kme",
-"kmf",
-"kmg",
-"kmh",
-"kmi",
-"kmj",
-"kmk",
-"kml",
-"kmm",
-"kmn",
-"kmo",
-"kmp",
-"kmq",
-"kmr",
-"kms",
-"kmt",
-"kmu",
-"kmv",
-"kmw",
-"kmx",
-"kmy",
-"kmz",
-"kna",
-"knb",
-"knc",
-"knd",
-"kne",
-"knf",
-"kng",
-"kni",
-"knj",
-"knk",
-"knl",
-"knm",
-"knn",
-"kno",
-"knp",
-"knq",
-"knr",
-"kns",
-"knt",
-"knu",
-"knv",
-"knw",
-"knx",
-"kny",
-"knz",
-"koa",
-"koc",
-"kod",
-"koe",
-"kof",
-"kog",
-"koh",
-"koi",
-"koj",
-"kok",
-"kol",
-"koo",
-"kop",
-"koq",
-"kos",
-"kot",
-"kou",
-"kov",
-"kow",
-"kox",
-"koy",
-"koz",
-"kpa",
-"kpb",
-"kpc",
-"kpd",
-"kpe",
-"kpf",
-"kpg",
-"kph",
-"kpi",
-"kpj",
-"kpk",
-"kpl",
-"kpm",
-"kpn",
-"kpo",
-"kpp",
-"kpq",
-"kpr",
-"kps",
-"kpt",
-"kpu",
-"kpv",
-"kpw",
-"kpx",
-"kpy",
-"kpz",
-"kqa",
-"kqb",
-"kqc",
-"kqd",
-"kqe",
-"kqf",
-"kqg",
-"kqh",
-"kqi",
-"kqj",
-"kqk",
-"kql",
-"kqm",
-"kqn",
-"kqo",
-"kqp",
-"kqq",
-"kqr",
-"kqs",
-"kqt",
-"kqu",
-"kqv",
-"kqw",
-"kqx",
-"kqy",
-"kqz",
-"kra",
-"krb",
-"krc",
-"krd",
-"kre",
-"krf",
-"krh",
-"kri",
-"krj",
-"krk",
-"krl",
-"krm",
-"krn",
-"kro",
-"krp",
-"krr",
-"krs",
-"krt",
-"kru",
-"krv",
-"krw",
-"krx",
-"kry",
-"krz",
-"ksa",
-"ksb",
-"ksc",
-"ksd",
-"kse",
-"ksf",
-"ksg",
-"ksh",
-"ksi",
-"ksj",
-"ksk",
-"ksl",
-"ksm",
-"ksn",
-"kso",
-"ksp",
-"ksq",
-"ksr",
-"kss",
-"kst",
-"ksu",
-"ksv",
-"ksw",
-"ksx",
-"ksy",
-"ksz",
-"kta",
-"ktb",
-"ktc",
-"ktd",
-"kte",
-"ktf",
-"ktg",
-"kth",
-"kti",
-"ktj",
-"ktk",
-"ktl",
-"ktm",
-"ktn",
-"kto",
-"ktp",
-"ktq",
-"ktr",
-"kts",
-"ktt",
-"ktu",
-"ktv",
-"ktw",
-"ktx",
-"kty",
-"ktz",
-"kub",
-"kuc",
-"kud",
-"kue",
-"kuf",
-"kug",
-"kuh",
-"kui",
-"kuj",
-"kuk",
-"kul",
-"kum",
-"kun",
-"kuo",
-"kup",
-"kuq",
-"kus",
-"kut",
-"kuu",
-"kuv",
-"kuw",
-"kux",
-"kuy",
-"kuz",
-"kva",
-"kvb",
-"kvc",
-"kvd",
-"kve",
-"kvf",
-"kvg",
-"kvh",
-"kvi",
-"kvj",
-"kvk",
-"kvl",
-"kvm",
-"kvn",
-"kvo",
-"kvp",
-"kvq",
-"kvr",
-"kvs",
-"kvt",
-"kvu",
-"kvv",
-"kvw",
-"kvx",
-"kvy",
-"kvz",
-"kwa",
-"kwb",
-"kwc",
-"kwd",
-"kwe",
-"kwf",
-"kwg",
-"kwh",
-"kwi",
-"kwj",
-"kwk",
-"kwl",
-"kwm",
-"kwn",
-"kwo",
-"kwp",
-"kwq",
-"kwr",
-"kws",
-"kwt",
-"kwu",
-"kwv",
-"kww",
-"kwx",
-"kwy",
-"kwz",
-"kxa",
-"kxb",
-"kxc",
-"kxd",
-"kxe",
-"kxf",
-"kxh",
-"kxi",
-"kxj",
-"kxk",
-"kxl",
-"kxm",
-"kxn",
-"kxo",
-"kxp",
-"kxq",
-"kxr",
-"kxs",
-"kxt",
-"kxu",
-"kxv",
-"kxw",
-"kxx",
-"kxy",
-"kxz",
-"kya",
-"kyb",
-"kyc",
-"kyd",
-"kye",
-"kyf",
-"kyg",
-"kyh",
-"kyi",
-"kyj",
-"kyk",
-"kyl",
-"kym",
-"kyn",
-"kyo",
-"kyp",
-"kyq",
-"kyr",
-"kys",
-"kyt",
-"kyu",
-"kyv",
-"kyw",
-"kyx",
-"kyy",
-"kyz",
-"kza",
-"kzb",
-"kzc",
-"kzd",
-"kze",
-"kzf",
-"kzg",
-"kzh",
-"kzi",
-"kzj",
-"kzk",
-"kzl",
-"kzm",
-"kzn",
-"kzo",
-"kzp",
-"kzq",
-"kzr",
-"kzs",
-"kzt",
-"kzu",
-"kzv",
-"kzw",
-"kzx",
-"kzy",
-"kzz",
-"laa",
-"lab",
-"lac",
-"lad",
-"lae",
-"laf",
-"lag",
-"lah",
-"lai",
-"laj",
-"lak",
-"lal",
-"lam",
-"lan",
-"lap",
-"laq",
-"lar",
-"las",
-"lau",
-"law",
-"lax",
-"lay",
-"laz",
-"lba",
-"lbb",
-"lbc",
-"lbe",
-"lbf",
-"lbg",
-"lbi",
-"lbj",
-"lbk",
-"lbl",
-"lbm",
-"lbn",
-"lbo",
-"lbq",
-"lbr",
-"lbs",
-"lbt",
-"lbu",
-"lbv",
-"lbw",
-"lbx",
-"lby",
-"lbz",
-"lcc",
-"lcd",
-"lce",
-"lcf",
-"lch",
-"lcl",
-"lcm",
-"lcp",
-"lcq",
-"lcs",
-"lda",
-"ldb",
-"ldd",
-"ldg",
-"ldh",
-"ldi",
-"ldj",
-"ldk",
-"ldl",
-"ldm",
-"ldn",
-"ldo",
-"ldp",
-"ldq",
-"lea",
-"leb",
-"lec",
-"led",
-"lee",
-"lef",
-"leg",
-"leh",
-"lei",
-"lej",
-"lek",
-"lel",
-"lem",
-"len",
-"leo",
-"lep",
-"leq",
-"ler",
-"les",
-"let",
-"leu",
-"lev",
-"lew",
-"lex",
-"ley",
-"lez",
-"lfa",
-"lfn",
-"lga",
-"lgb",
-"lgg",
-"lgh",
-"lgi",
-"lgk",
-"lgl",
-"lgm",
-"lgn",
-"lgq",
-"lgr",
-"lgt",
-"lgu",
-"lgz",
-"lha",
-"lhh",
-"lhi",
-"lhl",
-"lhm",
-"lhn",
-"lhp",
-"lhs",
-"lht",
-"lhu",
-"lia",
-"lib",
-"lic",
-"lid",
-"lie",
-"lif",
-"lig",
-"lih",
-"lii",
-"lij",
-"lik",
-"lil",
-"lio",
-"lip",
-"liq",
-"lir",
-"lis",
-"liu",
-"liv",
-"liw",
-"lix",
-"liy",
-"liz",
-"lja",
-"lje",
-"lji",
-"ljl",
-"ljp",
-"ljw",
-"ljx",
-"lka",
-"lkb",
-"lkc",
-"lkd",
-"lke",
-"lkh",
-"lki",
-"lkj",
-"lkl",
-"lkm",
-"lkn",
-"lko",
-"lkr",
-"lks",
-"lkt",
-"lku",
-"lky",
-"lla",
-"llb",
-"llc",
-"lld",
-"lle",
-"llf",
-"llg",
-"llh",
-"lli",
-"llj",
-"llk",
-"lll",
-"llm",
-"lln",
-"llo",
-"llp",
-"llq",
-"lls",
-"llu",
-"llx",
-"lma",
-"lmb",
-"lmc",
-"lmd",
-"lme",
-"lmf",
-"lmg",
-"lmh",
-"lmi",
-"lmj",
-"lmk",
-"lml",
-"lmm",
-"lmn",
-"lmo",
-"lmp",
-"lmq",
-"lmr",
-"lmu",
-"lmv",
-"lmw",
-"lmx",
-"lmy",
-"lmz",
-"lna",
-"lnb",
-"lnd",
-"lng",
-"lnh",
-"lni",
-"lnj",
-"lnl",
-"lnm",
-"lnn",
-"lno",
-"lns",
-"lnu",
-"lnw",
-"lnz",
-"loa",
-"lob",
-"loc",
-"loe",
-"lof",
-"log",
-"loh",
-"loi",
-"loj",
-"lok",
-"lol",
-"lom",
-"lon",
-"loo",
-"lop",
-"loq",
-"lor",
-"los",
-"lot",
-"lou",
-"lov",
-"low",
-"lox",
-"loy",
-"loz",
-"lpa",
-"lpe",
-"lpn",
-"lpo",
-"lpx",
-"lra",
-"lrc",
-"lre",
-"lrg",
-"lri",
-"lrk",
-"lrl",
-"lrm",
-"lrn",
-"lro",
-"lrr",
-"lrt",
-"lrv",
-"lrz",
-"lsa",
-"lsd",
-"lse",
-"lsg",
-"lsh",
-"lsi",
-"lsl",
-"lsm",
-"lso",
-"lsp",
-"lsr",
-"lss",
-"lst",
-"lsy",
-"ltc",
-"ltg",
-"lth",
-"lti",
-"ltn",
-"lto",
-"lts",
-"ltu",
-"lua",
-"luc",
-"lud",
-"lue",
-"luf",
-"lui",
-"luj",
-"luk",
-"lul",
-"lum",
-"lun",
-"luo",
-"lup",
-"luq",
-"lur",
-"lus",
-"lut",
-"luu",
-"luv",
-"luw",
-"luy",
-"luz",
-"lva",
-"lvk",
-"lvs",
-"lvu",
-"lwa",
-"lwe",
-"lwg",
-"lwh",
-"lwl",
-"lwm",
-"lwo",
-"lwt",
-"lwu",
-"lww",
-"lya",
-"lyg",
-"lyn",
-"lzh",
-"lzl",
-"lzn",
-"lzz",
-"maa",
-"mab",
-"mad",
-"mae",
-"maf",
-"mag",
-"mai",
-"maj",
-"mak",
-"mam",
-"man",
-"map",
-"maq",
-"mas",
-"mat",
-"mau",
-"mav",
-"maw",
-"max",
-"maz",
-"mba",
-"mbb",
-"mbc",
-"mbd",
-"mbe",
-"mbf",
-"mbh",
-"mbi",
-"mbj",
-"mbk",
-"mbl",
-"mbm",
-"mbn",
-"mbo",
-"mbp",
-"mbq",
-"mbr",
-"mbs",
-"mbt",
-"mbu",
-"mbv",
-"mbw",
-"mbx",
-"mby",
-"mbz",
-"mca",
-"mcb",
-"mcc",
-"mcd",
-"mce",
-"mcf",
-"mcg",
-"mch",
-"mci",
-"mcj",
-"mck",
-"mcl",
-"mcm",
-"mcn",
-"mco",
-"mcp",
-"mcq",
-"mcr",
-"mcs",
-"mct",
-"mcu",
-"mcv",
-"mcw",
-"mcx",
-"mcy",
-"mcz",
-"mda",
-"mdb",
-"mdc",
-"mdd",
-"mde",
-"mdf",
-"mdg",
-"mdh",
-"mdi",
-"mdj",
-"mdk",
-"mdl",
-"mdm",
-"mdn",
-"mdp",
-"mdq",
-"mdr",
-"mds",
-"mdt",
-"mdu",
-"mdv",
-"mdw",
-"mdx",
-"mdy",
-"mdz",
-"mea",
-"meb",
-"mec",
-"med",
-"mee",
-"mef",
-"meg",
-"meh",
-"mei",
-"mej",
-"mek",
-"mel",
-"mem",
-"men",
-"meo",
-"mep",
-"meq",
-"mer",
-"mes",
-"met",
-"meu",
-"mev",
-"mew",
-"mey",
-"mez",
-"mfa",
-"mfb",
-"mfc",
-"mfd",
-"mfe",
-"mff",
-"mfg",
-"mfh",
-"mfi",
-"mfj",
-"mfk",
-"mfl",
-"mfm",
-"mfn",
-"mfo",
-"mfp",
-"mfq",
-"mfr",
-"mfs",
-"mft",
-"mfu",
-"mfv",
-"mfw",
-"mfx",
-"mfy",
-"mfz",
-"mga",
-"mgb",
-"mgc",
-"mgd",
-"mge",
-"mgf",
-"mgg",
-"mgh",
-"mgi",
-"mgj",
-"mgk",
-"mgl",
-"mgm",
-"mgn",
-"mgo",
-"mgp",
-"mgq",
-"mgr",
-"mgs",
-"mgt",
-"mgu",
-"mgv",
-"mgw",
-"mgx",
-"mgy",
-"mgz",
-"mha",
-"mhb",
-"mhc",
-"mhd",
-"mhe",
-"mhf",
-"mhg",
-"mhh",
-"mhi",
-"mhj",
-"mhk",
-"mhl",
-"mhm",
-"mhn",
-"mho",
-"mhp",
-"mhq",
-"mhr",
-"mhs",
-"mht",
-"mhu",
-"mhw",
-"mhx",
-"mhy",
-"mhz",
-"mia",
-"mib",
-"mic",
-"mid",
-"mie",
-"mif",
-"mig",
-"mih",
-"mii",
-"mij",
-"mik",
-"mil",
-"mim",
-"min",
-"mio",
-"mip",
-"miq",
-"mir",
-"mis",
-"mit",
-"miu",
-"miw",
-"mix",
-"miy",
-"miz",
-"mja",
-"mjb",
-"mjc",
-"mjd",
-"mje",
-"mjg",
-"mjh",
-"mji",
-"mjj",
-"mjk",
-"mjl",
-"mjm",
-"mjn",
-"mjo",
-"mjp",
-"mjq",
-"mjr",
-"mjs",
-"mjt",
-"mju",
-"mjv",
-"mjw",
-"mjx",
-"mjy",
-"mjz",
-"mka",
-"mkb",
-"mkc",
-"mke",
-"mkf",
-"mkg",
-"mkh",
-"mki",
-"mkj",
-"mkk",
-"mkl",
-"mkm",
-"mkn",
-"mko",
-"mkp",
-"mkq",
-"mkr",
-"mks",
-"mkt",
-"mku",
-"mkv",
-"mkw",
-"mkx",
-"mky",
-"mkz",
-"mla",
-"mlb",
-"mlc",
-"mld",
-"mle",
-"mlf",
-"mlh",
-"mli",
-"mlj",
-"mlk",
-"mll",
-"mlm",
-"mln",
-"mlo",
-"mlp",
-"mlq",
-"mlr",
-"mls",
-"mlu",
-"mlv",
-"mlw",
-"mlx",
-"mlz",
-"mma",
-"mmb",
-"mmc",
-"mmd",
-"mme",
-"mmf",
-"mmg",
-"mmh",
-"mmi",
-"mmj",
-"mmk",
-"mml",
-"mmm",
-"mmn",
-"mmo",
-"mmp",
-"mmq",
-"mmr",
-"mmt",
-"mmu",
-"mmv",
-"mmw",
-"mmx",
-"mmy",
-"mmz",
-"mna",
-"mnb",
-"mnc",
-"mnd",
-"mne",
-"mnf",
-"mng",
-"mnh",
-"mni",
-"mnj",
-"mnk",
-"mnl",
-"mnm",
-"mnn",
-"mno",
-"mnp",
-"mnq",
-"mnr",
-"mns",
-"mnt",
-"mnu",
-"mnv",
-"mnw",
-"mnx",
-"mny",
-"mnz",
-"moa",
-"moc",
-"mod",
-"moe",
-"mof",
-"mog",
-"moh",
-"moi",
-"moj",
-"mok",
-"mom",
-"moo",
-"mop",
-"moq",
-"mor",
-"mos",
-"mot",
-"mou",
-"mov",
-"mow",
-"mox",
-"moy",
-"moz",
-"mpa",
-"mpb",
-"mpc",
-"mpd",
-"mpe",
-"mpg",
-"mph",
-"mpi",
-"mpj",
-"mpk",
-"mpl",
-"mpm",
-"mpn",
-"mpo",
-"mpp",
-"mpq",
-"mpr",
-"mps",
-"mpt",
-"mpu",
-"mpv",
-"mpw",
-"mpx",
-"mpy",
-"mpz",
-"mqa",
-"mqb",
-"mqc",
-"mqe",
-"mqf",
-"mqg",
-"mqh",
-"mqi",
-"mqj",
-"mqk",
-"mql",
-"mqm",
-"mqn",
-"mqo",
-"mqp",
-"mqq",
-"mqr",
-"mqs",
-"mqt",
-"mqu",
-"mqv",
-"mqw",
-"mqx",
-"mqy",
-"mqz",
-"mra",
-"mrb",
-"mrc",
-"mrd",
-"mre",
-"mrf",
-"mrg",
-"mrh",
-"mrj",
-"mrk",
-"mrl",
-"mrm",
-"mrn",
-"mro",
-"mrp",
-"mrq",
-"mrr",
-"mrs",
-"mrt",
-"mru",
-"mrv",
-"mrw",
-"mrx",
-"mry",
-"mrz",
-"msb",
-"msc",
-"msd",
-"mse",
-"msf",
-"msg",
-"msh",
-"msi",
-"msj",
-"msk",
-"msl",
-"msm",
-"msn",
-"mso",
-"msp",
-"msq",
-"msr",
-"mss",
-"mst",
-"msu",
-"msv",
-"msw",
-"msx",
-"msy",
-"msz",
-"mta",
-"mtb",
-"mtc",
-"mtd",
-"mte",
-"mtf",
-"mtg",
-"mth",
-"mti",
-"mtj",
-"mtk",
-"mtl",
-"mtm",
-"mtn",
-"mto",
-"mtp",
-"mtq",
-"mtr",
-"mts",
-"mtt",
-"mtu",
-"mtv",
-"mtw",
-"mtx",
-"mty",
-"mua",
-"mub",
-"muc",
-"mud",
-"mue",
-"mug",
-"muh",
-"mui",
-"muj",
-"muk",
-"mul",
-"mum",
-"mun",
-"muo",
-"mup",
-"muq",
-"mur",
-"mus",
-"mut",
-"muu",
-"muv",
-"mux",
-"muy",
-"muz",
-"mva",
-"mvb",
-"mvd",
-"mve",
-"mvf",
-"mvg",
-"mvh",
-"mvi",
-"mvk",
-"mvl",
-"mvm",
-"mvn",
-"mvo",
-"mvp",
-"mvq",
-"mvr",
-"mvs",
-"mvt",
-"mvu",
-"mvv",
-"mvw",
-"mvx",
-"mvy",
-"mvz",
-"mwa",
-"mwb",
-"mwc",
-"mwd",
-"mwe",
-"mwf",
-"mwg",
-"mwh",
-"mwi",
-"mwj",
-"mwk",
-"mwl",
-"mwm",
-"mwn",
-"mwo",
-"mwp",
-"mwq",
-"mwr",
-"mws",
-"mwt",
-"mwu",
-"mwv",
-"mww",
-"mwx",
-"mwy",
-"mwz",
-"mxa",
-"mxb",
-"mxc",
-"mxd",
-"mxe",
-"mxf",
-"mxg",
-"mxh",
-"mxi",
-"mxj",
-"mxk",
-"mxl",
-"mxm",
-"mxn",
-"mxo",
-"mxp",
-"mxq",
-"mxr",
-"mxs",
-"mxt",
-"mxu",
-"mxv",
-"mxw",
-"mxx",
-"mxy",
-"mxz",
-"myb",
-"myc",
-"myd",
-"mye",
-"myf",
-"myg",
-"myh",
-"myi",
-"myj",
-"myk",
-"myl",
-"mym",
-"myn",
-"myo",
-"myp",
-"myq",
-"myr",
-"mys",
-"myt",
-"myu",
-"myv",
-"myw",
-"myx",
-"myy",
-"myz",
-"mza",
-"mzb",
-"mzc",
-"mzd",
-"mze",
-"mzg",
-"mzh",
-"mzi",
-"mzj",
-"mzk",
-"mzl",
-"mzm",
-"mzn",
-"mzo",
-"mzp",
-"mzq",
-"mzr",
-"mzs",
-"mzt",
-"mzu",
-"mzv",
-"mzw",
-"mzx",
-"mzy",
-"mzz",
-"naa",
-"nab",
-"nac",
-"nad",
-"nae",
-"naf",
-"nag",
-"nah",
-"nai",
-"naj",
-"nak",
-"nal",
-"nam",
-"nan",
-"nao",
-"nap",
-"naq",
-"nar",
-"nas",
-"nat",
-"naw",
-"nax",
-"nay",
-"naz",
-"nba",
-"nbb",
-"nbc",
-"nbd",
-"nbe",
-"nbf",
-"nbg",
-"nbh",
-"nbi",
-"nbj",
-"nbk",
-"nbm",
-"nbn",
-"nbo",
-"nbp",
-"nbq",
-"nbr",
-"nbs",
-"nbt",
-"nbu",
-"nbv",
-"nbw",
-"nbx",
-"nby",
-"nca",
-"ncb",
-"ncc",
-"ncd",
-"nce",
-"ncf",
-"ncg",
-"nch",
-"nci",
-"ncj",
-"nck",
-"ncl",
-"ncm",
-"ncn",
-"nco",
-"ncp",
-"ncq",
-"ncr",
-"ncs",
-"nct",
-"ncu",
-"ncx",
-"ncz",
-"nda",
-"ndb",
-"ndc",
-"ndd",
-"ndf",
-"ndg",
-"ndh",
-"ndi",
-"ndj",
-"ndk",
-"ndl",
-"ndm",
-"ndn",
-"ndp",
-"ndq",
-"ndr",
-"nds",
-"ndt",
-"ndu",
-"ndv",
-"ndw",
-"ndx",
-"ndy",
-"ndz",
-"nea",
-"neb",
-"nec",
-"ned",
-"nee",
-"nef",
-"neg",
-"neh",
-"nei",
-"nej",
-"nek",
-"nem",
-"nen",
-"neo",
-"neq",
-"ner",
-"nes",
-"net",
-"neu",
-"nev",
-"new",
-"nex",
-"ney",
-"nez",
-"nfa",
-"nfd",
-"nfl",
-"nfr",
-"nfu",
-"nga",
-"ngb",
-"ngc",
-"ngd",
-"nge",
-"ngf",
-"ngg",
-"ngh",
-"ngi",
-"ngj",
-"ngk",
-"ngl",
-"ngm",
-"ngn",
-"ngo",
-"ngp",
-"ngq",
-"ngr",
-"ngs",
-"ngt",
-"ngu",
-"ngv",
-"ngw",
-"ngx",
-"ngy",
-"ngz",
-"nha",
-"nhb",
-"nhc",
-"nhd",
-"nhe",
-"nhf",
-"nhg",
-"nhh",
-"nhi",
-"nhk",
-"nhm",
-"nhn",
-"nho",
-"nhp",
-"nhq",
-"nhr",
-"nht",
-"nhu",
-"nhv",
-"nhw",
-"nhx",
-"nhy",
-"nhz",
-"nia",
-"nib",
-"nic",
-"nid",
-"nie",
-"nif",
-"nig",
-"nih",
-"nii",
-"nij",
-"nik",
-"nil",
-"nim",
-"nin",
-"nio",
-"niq",
-"nir",
-"nis",
-"nit",
-"niu",
-"niv",
-"niw",
-"nix",
-"niy",
-"niz",
-"nja",
-"njb",
-"njd",
-"njh",
-"nji",
-"njj",
-"njl",
-"njm",
-"njn",
-"njo",
-"njr",
-"njs",
-"njt",
-"nju",
-"njx",
-"njy",
-"njz",
-"nka",
-"nkb",
-"nkc",
-"nkd",
-"nke",
-"nkf",
-"nkg",
-"nkh",
-"nki",
-"nkj",
-"nkk",
-"nkm",
-"nkn",
-"nko",
-"nkp",
-"nkq",
-"nkr",
-"nks",
-"nkt",
-"nku",
-"nkv",
-"nkw",
-"nkx",
-"nkz",
-"nla",
-"nlc",
-"nle",
-"nlg",
-"nli",
-"nlj",
-"nlk",
-"nll",
-"nln",
-"nlo",
-"nlq",
-"nlr",
-"nlu",
-"nlv",
-"nlw",
-"nlx",
-"nly",
-"nlz",
-"nma",
-"nmb",
-"nmc",
-"nmd",
-"nme",
-"nmf",
-"nmg",
-"nmh",
-"nmi",
-"nmj",
-"nmk",
-"nml",
-"nmm",
-"nmn",
-"nmo",
-"nmp",
-"nmq",
-"nmr",
-"nms",
-"nmt",
-"nmu",
-"nmv",
-"nmw",
-"nmx",
-"nmy",
-"nmz",
-"nna",
-"nnb",
-"nnc",
-"nnd",
-"nne",
-"nnf",
-"nng",
-"nnh",
-"nni",
-"nnj",
-"nnk",
-"nnl",
-"nnm",
-"nnn",
-"nnp",
-"nnq",
-"nnr",
-"nns",
-"nnt",
-"nnu",
-"nnv",
-"nnw",
-"nnx",
-"nny",
-"nnz",
-"noa",
-"noc",
-"nod",
-"noe",
-"nof",
-"nog",
-"noh",
-"noi",
-"noj",
-"nok",
-"nol",
-"nom",
-"non",
-"noo",
-"nop",
-"noq",
-"nos",
-"not",
-"nou",
-"nov",
-"now",
-"noy",
-"noz",
-"npa",
-"npb",
-"npg",
-"nph",
-"npi",
-"npl",
-"npn",
-"npo",
-"nps",
-"npu",
-"npx",
-"npy",
-"nqg",
-"nqk",
-"nql",
-"nqm",
-"nqn",
-"nqo",
-"nqq",
-"nqy",
-"nra",
-"nrb",
-"nrc",
-"nre",
-"nrf",
-"nrg",
-"nri",
-"nrk",
-"nrl",
-"nrm",
-"nrn",
-"nrp",
-"nrr",
-"nrt",
-"nru",
-"nrx",
-"nrz",
-"nsa",
-"nsc",
-"nsd",
-"nse",
-"nsf",
-"nsg",
-"nsh",
-"nsi",
-"nsk",
-"nsl",
-"nsm",
-"nsn",
-"nso",
-"nsp",
-"nsq",
-"nsr",
-"nss",
-"nst",
-"nsu",
-"nsv",
-"nsw",
-"nsx",
-"nsy",
-"nsz",
-"ntd",
-"nte",
-"ntg",
-"nti",
-"ntj",
-"ntk",
-"ntm",
-"nto",
-"ntp",
-"ntr",
-"nts",
-"ntu",
-"ntw",
-"ntx",
-"nty",
-"ntz",
-"nua",
-"nub",
-"nuc",
-"nud",
-"nue",
-"nuf",
-"nug",
-"nuh",
-"nui",
-"nuj",
-"nuk",
-"nul",
-"num",
-"nun",
-"nuo",
-"nup",
-"nuq",
-"nur",
-"nus",
-"nut",
-"nuu",
-"nuv",
-"nuw",
-"nux",
-"nuy",
-"nuz",
-"nvh",
-"nvm",
-"nvo",
-"nwa",
-"nwb",
-"nwc",
-"nwe",
-"nwg",
-"nwi",
-"nwm",
-"nwo",
-"nwr",
-"nwx",
-"nwy",
-"nxa",
-"nxd",
-"nxe",
-"nxg",
-"nxi",
-"nxk",
-"nxl",
-"nxm",
-"nxn",
-"nxo",
-"nxq",
-"nxr",
-"nxu",
-"nxx",
-"nyb",
-"nyc",
-"nyd",
-"nye",
-"nyf",
-"nyg",
-"nyh",
-"nyi",
-"nyj",
-"nyk",
-"nyl",
-"nym",
-"nyn",
-"nyo",
-"nyp",
-"nyq",
-"nyr",
-"nys",
-"nyt",
-"nyu",
-"nyv",
-"nyw",
-"nyx",
-"nyy",
-"nza",
-"nzb",
-"nzi",
-"nzk",
-"nzm",
-"nzs",
-"nzu",
-"nzy",
-"nzz",
-"oaa",
-"oac",
-"oar",
-"oav",
-"obi",
-"obk",
-"obl",
-"obm",
-"obo",
-"obr",
-"obt",
-"obu",
-"oca",
-"och",
-"oco",
-"ocu",
-"oda",
-"odk",
-"odt",
-"odu",
-"ofo",
-"ofs",
-"ofu",
-"ogb",
-"ogc",
-"oge",
-"ogg",
-"ogo",
-"ogu",
-"oht",
-"ohu",
-"oia",
-"oin",
-"ojb",
-"ojc",
-"ojg",
-"ojp",
-"ojs",
-"ojv",
-"ojw",
-"oka",
-"okb",
-"okd",
-"oke",
-"okg",
-"okh",
-"oki",
-"okj",
-"okk",
-"okl",
-"okm",
-"okn",
-"oko",
-"okr",
-"oks",
-"oku",
-"okv",
-"okx",
-"ola",
-"old",
-"ole",
-"olk",
-"olm",
-"olo",
-"olr",
-"olt",
-"olu",
-"oma",
-"omb",
-"omc",
-"ome",
-"omg",
-"omi",
-"omk",
-"oml",
-"omn",
-"omo",
-"omp",
-"omq",
-"omr",
-"omt",
-"omu",
-"omv",
-"omw",
-"omx",
-"ona",
-"onb",
-"one",
-"ong",
-"oni",
-"onj",
-"onk",
-"onn",
-"ono",
-"onp",
-"onr",
-"ons",
-"ont",
-"onu",
-"onw",
-"onx",
-"ood",
-"oog",
-"oon",
-"oor",
-"oos",
-"opa",
-"opk",
-"opm",
-"opo",
-"opt",
-"opy",
-"ora",
-"orc",
-"ore",
-"org",
-"orh",
-"orn",
-"oro",
-"orr",
-"ors",
-"ort",
-"oru",
-"orv",
-"orw",
-"orx",
-"ory",
-"orz",
-"osa",
-"osc",
-"osi",
-"oso",
-"osp",
-"ost",
-"osu",
-"osx",
-"ota",
-"otb",
-"otd",
-"ote",
-"oti",
-"otk",
-"otl",
-"otm",
-"otn",
-"oto",
-"otq",
-"otr",
-"ots",
-"ott",
-"otu",
-"otw",
-"otx",
-"oty",
-"otz",
-"oua",
-"oub",
-"oue",
-"oui",
-"oum",
-"oun",
-"ovd",
-"owi",
-"owl",
-"oyb",
-"oyd",
-"oym",
-"oyy",
-"ozm",
-"paa",
-"pab",
-"pac",
-"pad",
-"pae",
-"paf",
-"pag",
-"pah",
-"pai",
-"pak",
-"pal",
-"pam",
-"pao",
-"pap",
-"paq",
-"par",
-"pas",
-"pat",
-"pau",
-"pav",
-"paw",
-"pax",
-"pay",
-"paz",
-"pbb",
-"pbc",
-"pbe",
-"pbf",
-"pbg",
-"pbh",
-"pbi",
-"pbl",
-"pbn",
-"pbo",
-"pbp",
-"pbr",
-"pbs",
-"pbt",
-"pbu",
-"pbv",
-"pby",
-"pbz",
-"pca",
-"pcb",
-"pcc",
-"pcd",
-"pce",
-"pcf",
-"pcg",
-"pch",
-"pci",
-"pcj",
-"pck",
-"pcl",
-"pcm",
-"pcn",
-"pcp",
-"pcr",
-"pcw",
-"pda",
-"pdc",
-"pdi",
-"pdn",
-"pdo",
-"pdt",
-"pdu",
-"pea",
-"peb",
-"ped",
-"pee",
-"pef",
-"peg",
-"peh",
-"pei",
-"pej",
-"pek",
-"pel",
-"pem",
-"peo",
-"pep",
-"peq",
-"pes",
-"pev",
-"pex",
-"pey",
-"pez",
-"pfa",
-"pfe",
-"pfl",
-"pga",
-"pgd",
-"pgg",
-"pgi",
-"pgk",
-"pgl",
-"pgn",
-"pgs",
-"pgu",
-"pgy",
-"pgz",
-"pha",
-"phd",
-"phg",
-"phh",
-"phi",
-"phk",
-"phl",
-"phm",
-"phn",
-"pho",
-"phq",
-"phr",
-"pht",
-"phu",
-"phv",
-"phw",
-"pia",
-"pib",
-"pic",
-"pid",
-"pie",
-"pif",
-"pig",
-"pih",
-"pii",
-"pij",
-"pil",
-"pim",
-"pin",
-"pio",
-"pip",
-"pir",
-"pis",
-"pit",
-"piu",
-"piv",
-"piw",
-"pix",
-"piy",
-"piz",
-"pjt",
-"pka",
-"pkb",
-"pkc",
-"pkg",
-"pkh",
-"pkn",
-"pko",
-"pkp",
-"pkr",
-"pks",
-"pkt",
-"pku",
-"pla",
-"plb",
-"plc",
-"pld",
-"ple",
-"plf",
-"plg",
-"plh",
-"plj",
-"plk",
-"pll",
-"pln",
-"plo",
-"plp",
-"plq",
-"plr",
-"pls",
-"plt",
-"plu",
-"plv",
-"plw",
-"ply",
-"plz",
-"pma",
-"pmb",
-"pmc",
-"pmd",
-"pme",
-"pmf",
-"pmh",
-"pmi",
-"pmj",
-"pmk",
-"pml",
-"pmm",
-"pmn",
-"pmo",
-"pmq",
-"pmr",
-"pms",
-"pmt",
-"pmu",
-"pmw",
-"pmx",
-"pmy",
-"pmz",
-"pna",
-"pnb",
-"pnc",
-"pne",
-"png",
-"pnh",
-"pni",
-"pnj",
-"pnk",
-"pnl",
-"pnm",
-"pnn",
-"pno",
-"pnp",
-"pnq",
-"pnr",
-"pns",
-"pnt",
-"pnu",
-"pnv",
-"pnw",
-"pnx",
-"pny",
-"pnz",
-"poc",
-"pod",
-"poe",
-"pof",
-"pog",
-"poh",
-"poi",
-"pok",
-"pom",
-"pon",
-"poo",
-"pop",
-"poq",
-"pos",
-"pot",
-"pov",
-"pow",
-"pox",
-"poy",
-"poz",
-"ppa",
-"ppe",
-"ppi",
-"ppk",
-"ppl",
-"ppm",
-"ppn",
-"ppo",
-"ppp",
-"ppq",
-"ppr",
-"pps",
-"ppt",
-"ppu",
-"pqa",
-"pqe",
-"pqm",
-"pqw",
-"pra",
-"prb",
-"prc",
-"prd",
-"pre",
-"prf",
-"prg",
-"prh",
-"pri",
-"prk",
-"prl",
-"prm",
-"prn",
-"pro",
-"prp",
-"prq",
-"prr",
-"prs",
-"prt",
-"pru",
-"prw",
-"prx",
-"pry",
-"prz",
-"psa",
-"psc",
-"psd",
-"pse",
-"psg",
-"psh",
-"psi",
-"psl",
-"psm",
-"psn",
-"pso",
-"psp",
-"psq",
-"psr",
-"pss",
-"pst",
-"psu",
-"psw",
-"psy",
-"pta",
-"pth",
-"pti",
-"ptn",
-"pto",
-"ptp",
-"ptq",
-"ptr",
-"ptt",
-"ptu",
-"ptv",
-"ptw",
-"pty",
-"pua",
-"pub",
-"puc",
-"pud",
-"pue",
-"puf",
-"pug",
-"pui",
-"puj",
-"puk",
-"pum",
-"puo",
-"pup",
-"puq",
-"pur",
-"put",
-"puu",
-"puw",
-"pux",
-"puy",
-"puz",
-"pwa",
-"pwb",
-"pwg",
-"pwi",
-"pwm",
-"pwn",
-"pwo",
-"pwr",
-"pww",
-"pxm",
-"pye",
-"pym",
-"pyn",
-"pys",
-"pyu",
-"pyx",
-"pyy",
-"pzn",
-"qaa..qtz",
-"qua",
-"qub",
-"quc",
-"qud",
-"quf",
-"qug",
-"quh",
-"qui",
-"quk",
-"qul",
-"qum",
-"qun",
-"qup",
-"quq",
-"qur",
-"qus",
-"quv",
-"quw",
-"qux",
-"quy",
-"quz",
-"qva",
-"qvc",
-"qve",
-"qvh",
-"qvi",
-"qvj",
-"qvl",
-"qvm",
-"qvn",
-"qvo",
-"qvp",
-"qvs",
-"qvw",
-"qvy",
-"qvz",
-"qwa",
-"qwc",
-"qwe",
-"qwh",
-"qwm",
-"qws",
-"qwt",
-"qxa",
-"qxc",
-"qxh",
-"qxl",
-"qxn",
-"qxo",
-"qxp",
-"qxq",
-"qxr",
-"qxs",
-"qxt",
-"qxu",
-"qxw",
-"qya",
-"qyp",
-"raa",
-"rab",
-"rac",
-"rad",
-"raf",
-"rag",
-"rah",
-"rai",
-"raj",
-"rak",
-"ral",
-"ram",
-"ran",
-"rao",
-"rap",
-"raq",
-"rar",
-"ras",
-"rat",
-"rau",
-"rav",
-"raw",
-"rax",
-"ray",
-"raz",
-"rbb",
-"rbk",
-"rbl",
-"rbp",
-"rcf",
-"rdb",
-"rea",
-"reb",
-"ree",
-"reg",
-"rei",
-"rej",
-"rel",
-"rem",
-"ren",
-"rer",
-"res",
-"ret",
-"rey",
-"rga",
-"rge",
-"rgk",
-"rgn",
-"rgr",
-"rgs",
-"rgu",
-"rhg",
-"rhp",
-"ria",
-"rie",
-"rif",
-"ril",
-"rim",
-"rin",
-"rir",
-"rit",
-"riu",
-"rjg",
-"rji",
-"rjs",
-"rka",
-"rkb",
-"rkh",
-"rki",
-"rkm",
-"rkt",
-"rkw",
-"rma",
-"rmb",
-"rmc",
-"rmd",
-"rme",
-"rmf",
-"rmg",
-"rmh",
-"rmi",
-"rmk",
-"rml",
-"rmm",
-"rmn",
-"rmo",
-"rmp",
-"rmq",
-"rmr",
-"rms",
-"rmt",
-"rmu",
-"rmv",
-"rmw",
-"rmx",
-"rmy",
-"rmz",
-"rna",
-"rnd",
-"rng",
-"rnl",
-"rnn",
-"rnp",
-"rnr",
-"rnw",
-"roa",
-"rob",
-"roc",
-"rod",
-"roe",
-"rof",
-"rog",
-"rol",
-"rom",
-"roo",
-"rop",
-"ror",
-"rou",
-"row",
-"rpn",
-"rpt",
-"rri",
-"rro",
-"rrt",
-"rsb",
-"rsi",
-"rsl",
-"rsm",
-"rtc",
-"rth",
-"rtm",
-"rts",
-"rtw",
-"rub",
-"ruc",
-"rue",
-"ruf",
-"rug",
-"ruh",
-"rui",
-"ruk",
-"ruo",
-"rup",
-"ruq",
-"rut",
-"ruu",
-"ruy",
-"ruz",
-"rwa",
-"rwk",
-"rwm",
-"rwo",
-"rwr",
-"rxd",
-"rxw",
-"ryn",
-"rys",
-"ryu",
-"rzh",
-"saa",
-"sab",
-"sac",
-"sad",
-"sae",
-"saf",
-"sah",
-"sai",
-"saj",
-"sak",
-"sal",
-"sam",
-"sao",
-"sap",
-"saq",
-"sar",
-"sas",
-"sat",
-"sau",
-"sav",
-"saw",
-"sax",
-"say",
-"saz",
-"sba",
-"sbb",
-"sbc",
-"sbd",
-"sbe",
-"sbf",
-"sbg",
-"sbh",
-"sbi",
-"sbj",
-"sbk",
-"sbl",
-"sbm",
-"sbn",
-"sbo",
-"sbp",
-"sbq",
-"sbr",
-"sbs",
-"sbt",
-"sbu",
-"sbv",
-"sbw",
-"sbx",
-"sby",
-"sbz",
-"sca",
-"scb",
-"sce",
-"scf",
-"scg",
-"sch",
-"sci",
-"sck",
-"scl",
-"scn",
-"sco",
-"scp",
-"scq",
-"scs",
-"sct",
-"scu",
-"scv",
-"scw",
-"scx",
-"sda",
-"sdb",
-"sdc",
-"sde",
-"sdf",
-"sdg",
-"sdh",
-"sdj",
-"sdk",
-"sdl",
-"sdm",
-"sdn",
-"sdo",
-"sdp",
-"sdr",
-"sds",
-"sdt",
-"sdu",
-"sdv",
-"sdx",
-"sdz",
-"sea",
-"seb",
-"sec",
-"sed",
-"see",
-"sef",
-"seg",
-"seh",
-"sei",
-"sej",
-"sek",
-"sel",
-"sem",
-"sen",
-"seo",
-"sep",
-"seq",
-"ser",
-"ses",
-"set",
-"seu",
-"sev",
-"sew",
-"sey",
-"sez",
-"sfb",
-"sfe",
-"sfm",
-"sfs",
-"sfw",
-"sga",
-"sgb",
-"sgc",
-"sgd",
-"sge",
-"sgg",
-"sgh",
-"sgi",
-"sgj",
-"sgk",
-"sgl",
-"sgm",
-"sgn",
-"sgo",
-"sgp",
-"sgr",
-"sgs",
-"sgt",
-"sgu",
-"sgw",
-"sgx",
-"sgy",
-"sgz",
-"sha",
-"shb",
-"shc",
-"shd",
-"she",
-"shg",
-"shh",
-"shi",
-"shj",
-"shk",
-"shl",
-"shm",
-"shn",
-"sho",
-"shp",
-"shq",
-"shr",
-"shs",
-"sht",
-"shu",
-"shv",
-"shw",
-"shx",
-"shy",
-"shz",
-"sia",
-"sib",
-"sid",
-"sie",
-"sif",
-"sig",
-"sih",
-"sii",
-"sij",
-"sik",
-"sil",
-"sim",
-"sio",
-"sip",
-"siq",
-"sir",
-"sis",
-"sit",
-"siu",
-"siv",
-"siw",
-"six",
-"siy",
-"siz",
-"sja",
-"sjb",
-"sjd",
-"sje",
-"sjg",
-"sjk",
-"sjl",
-"sjm",
-"sjn",
-"sjo",
-"sjp",
-"sjr",
-"sjs",
-"sjt",
-"sju",
-"sjw",
-"ska",
-"skb",
-"skc",
-"skd",
-"ske",
-"skf",
-"skg",
-"skh",
-"ski",
-"skj",
-"skk",
-"skm",
-"skn",
-"sko",
-"skp",
-"skq",
-"skr",
-"sks",
-"skt",
-"sku",
-"skv",
-"skw",
-"skx",
-"sky",
-"skz",
-"sla",
-"slc",
-"sld",
-"sle",
-"slf",
-"slg",
-"slh",
-"sli",
-"slj",
-"sll",
-"slm",
-"sln",
-"slp",
-"slq",
-"slr",
-"sls",
-"slt",
-"slu",
-"slw",
-"slx",
-"sly",
-"slz",
-"sma",
-"smb",
-"smc",
-"smd",
-"smf",
-"smg",
-"smh",
-"smi",
-"smj",
-"smk",
-"sml",
-"smm",
-"smn",
-"smp",
-"smq",
-"smr",
-"sms",
-"smt",
-"smu",
-"smv",
-"smw",
-"smx",
-"smy",
-"smz",
-"snb",
-"snc",
-"sne",
-"snf",
-"sng",
-"snh",
-"sni",
-"snj",
-"snk",
-"snl",
-"snm",
-"snn",
-"sno",
-"snp",
-"snq",
-"snr",
-"sns",
-"snu",
-"snv",
-"snw",
-"snx",
-"sny",
-"snz",
-"soa",
-"sob",
-"soc",
-"sod",
-"soe",
-"sog",
-"soh",
-"soi",
-"soj",
-"sok",
-"sol",
-"son",
-"soo",
-"sop",
-"soq",
-"sor",
-"sos",
-"sou",
-"sov",
-"sow",
-"sox",
-"soy",
-"soz",
-"spb",
-"spc",
-"spd",
-"spe",
-"spg",
-"spi",
-"spk",
-"spl",
-"spm",
-"spn",
-"spo",
-"spp",
-"spq",
-"spr",
-"sps",
-"spt",
-"spu",
-"spv",
-"spx",
-"spy",
-"sqa",
-"sqh",
-"sqj",
-"sqk",
-"sqm",
-"sqn",
-"sqo",
-"sqq",
-"sqr",
-"sqs",
-"sqt",
-"squ",
-"sra",
-"srb",
-"src",
-"sre",
-"srf",
-"srg",
-"srh",
-"sri",
-"srk",
-"srl",
-"srm",
-"srn",
-"sro",
-"srq",
-"srr",
-"srs",
-"srt",
-"sru",
-"srv",
-"srw",
-"srx",
-"sry",
-"srz",
-"ssa",
-"ssb",
-"ssc",
-"ssd",
-"sse",
-"ssf",
-"ssg",
-"ssh",
-"ssi",
-"ssj",
-"ssk",
-"ssl",
-"ssm",
-"ssn",
-"sso",
-"ssp",
-"ssq",
-"ssr",
-"sss",
-"sst",
-"ssu",
-"ssv",
-"ssx",
-"ssy",
-"ssz",
-"sta",
-"stb",
-"std",
-"ste",
-"stf",
-"stg",
-"sth",
-"sti",
-"stj",
-"stk",
-"stl",
-"stm",
-"stn",
-"sto",
-"stp",
-"stq",
-"str",
-"sts",
-"stt",
-"stu",
-"stv",
-"stw",
-"sty",
-"sua",
-"sub",
-"suc",
-"sue",
-"sug",
-"sui",
-"suj",
-"suk",
-"sul",
-"sum",
-"suq",
-"sur",
-"sus",
-"sut",
-"suv",
-"suw",
-"sux",
-"suy",
-"suz",
-"sva",
-"svb",
-"svc",
-"sve",
-"svk",
-"svm",
-"svr",
-"svs",
-"svx",
-"swb",
-"swc",
-"swf",
-"swg",
-"swh",
-"swi",
-"swj",
-"swk",
-"swl",
-"swm",
-"swn",
-"swo",
-"swp",
-"swq",
-"swr",
-"sws",
-"swt",
-"swu",
-"swv",
-"sww",
-"swx",
-"swy",
-"sxb",
-"sxc",
-"sxe",
-"sxg",
-"sxk",
-"sxl",
-"sxm",
-"sxn",
-"sxo",
-"sxr",
-"sxs",
-"sxu",
-"sxw",
-"sya",
-"syb",
-"syc",
-"syd",
-"syi",
-"syk",
-"syl",
-"sym",
-"syn",
-"syo",
-"syr",
-"sys",
-"syw",
-"syx",
-"syy",
-"sza",
-"szb",
-"szc",
-"szd",
-"sze",
-"szg",
-"szl",
-"szn",
-"szp",
-"szs",
-"szv",
-"szw",
-"taa",
-"tab",
-"tac",
-"tad",
-"tae",
-"taf",
-"tag",
-"tai",
-"taj",
-"tak",
-"tal",
-"tan",
-"tao",
-"tap",
-"taq",
-"tar",
-"tas",
-"tau",
-"tav",
-"taw",
-"tax",
-"tay",
-"taz",
-"tba",
-"tbb",
-"tbc",
-"tbd",
-"tbe",
-"tbf",
-"tbg",
-"tbh",
-"tbi",
-"tbj",
-"tbk",
-"tbl",
-"tbm",
-"tbn",
-"tbo",
-"tbp",
-"tbq",
-"tbr",
-"tbs",
-"tbt",
-"tbu",
-"tbv",
-"tbw",
-"tbx",
-"tby",
-"tbz",
-"tca",
-"tcb",
-"tcc",
-"tcd",
-"tce",
-"tcf",
-"tcg",
-"tch",
-"tci",
-"tck",
-"tcl",
-"tcm",
-"tcn",
-"tco",
-"tcp",
-"tcq",
-"tcs",
-"tct",
-"tcu",
-"tcw",
-"tcx",
-"tcy",
-"tcz",
-"tda",
-"tdb",
-"tdc",
-"tdd",
-"tde",
-"tdf",
-"tdg",
-"tdh",
-"tdi",
-"tdj",
-"tdk",
-"tdl",
-"tdm",
-"tdn",
-"tdo",
-"tdq",
-"tdr",
-"tds",
-"tdt",
-"tdu",
-"tdv",
-"tdx",
-"tdy",
-"tea",
-"teb",
-"tec",
-"ted",
-"tee",
-"tef",
-"teg",
-"teh",
-"tei",
-"tek",
-"tem",
-"ten",
-"teo",
-"tep",
-"teq",
-"ter",
-"tes",
-"tet",
-"teu",
-"tev",
-"tew",
-"tex",
-"tey",
-"tfi",
-"tfn",
-"tfo",
-"tfr",
-"tft",
-"tga",
-"tgb",
-"tgc",
-"tgd",
-"tge",
-"tgf",
-"tgg",
-"tgh",
-"tgi",
-"tgj",
-"tgn",
-"tgo",
-"tgp",
-"tgq",
-"tgr",
-"tgs",
-"tgt",
-"tgu",
-"tgv",
-"tgw",
-"tgx",
-"tgy",
-"tgz",
-"thc",
-"thd",
-"the",
-"thf",
-"thh",
-"thi",
-"thk",
-"thl",
-"thm",
-"thn",
-"thp",
-"thq",
-"thr",
-"ths",
-"tht",
-"thu",
-"thv",
-"thw",
-"thx",
-"thy",
-"thz",
-"tia",
-"tic",
-"tid",
-"tie",
-"tif",
-"tig",
-"tih",
-"tii",
-"tij",
-"tik",
-"til",
-"tim",
-"tin",
-"tio",
-"tip",
-"tiq",
-"tis",
-"tit",
-"tiu",
-"tiv",
-"tiw",
-"tix",
-"tiy",
-"tiz",
-"tja",
-"tjg",
-"tji",
-"tjl",
-"tjm",
-"tjn",
-"tjo",
-"tjs",
-"tju",
-"tjw",
-"tka",
-"tkb",
-"tkd",
-"tke",
-"tkf",
-"tkg",
-"tkk",
-"tkl",
-"tkm",
-"tkn",
-"tkp",
-"tkq",
-"tkr",
-"tks",
-"tkt",
-"tku",
-"tkv",
-"tkw",
-"tkx",
-"tkz",
-"tla",
-"tlb",
-"tlc",
-"tld",
-"tlf",
-"tlg",
-"tlh",
-"tli",
-"tlj",
-"tlk",
-"tll",
-"tlm",
-"tln",
-"tlo",
-"tlp",
-"tlq",
-"tlr",
-"tls",
-"tlt",
-"tlu",
-"tlv",
-"tlw",
-"tlx",
-"tly",
-"tma",
-"tmb",
-"tmc",
-"tmd",
-"tme",
-"tmf",
-"tmg",
-"tmh",
-"tmi",
-"tmj",
-"tmk",
-"tml",
-"tmm",
-"tmn",
-"tmo",
-"tmp",
-"tmq",
-"tmr",
-"tms",
-"tmt",
-"tmu",
-"tmv",
-"tmw",
-"tmy",
-"tmz",
-"tna",
-"tnb",
-"tnc",
-"tnd",
-"tne",
-"tnf",
-"tng",
-"tnh",
-"tni",
-"tnk",
-"tnl",
-"tnm",
-"tnn",
-"tno",
-"tnp",
-"tnq",
-"tnr",
-"tns",
-"tnt",
-"tnu",
-"tnv",
-"tnw",
-"tnx",
-"tny",
-"tnz",
-"tob",
-"toc",
-"tod",
-"toe",
-"tof",
-"tog",
-"toh",
-"toi",
-"toj",
-"tol",
-"tom",
-"too",
-"top",
-"toq",
-"tor",
-"tos",
-"tou",
-"tov",
-"tow",
-"tox",
-"toy",
-"toz",
-"tpa",
-"tpc",
-"tpe",
-"tpf",
-"tpg",
-"tpi",
-"tpj",
-"tpk",
-"tpl",
-"tpm",
-"tpn",
-"tpo",
-"tpp",
-"tpq",
-"tpr",
-"tpt",
-"tpu",
-"tpv",
-"tpw",
-"tpx",
-"tpy",
-"tpz",
-"tqb",
-"tql",
-"tqm",
-"tqn",
-"tqo",
-"tqp",
-"tqq",
-"tqr",
-"tqt",
-"tqu",
-"tqw",
-"tra",
-"trb",
-"trc",
-"trd",
-"tre",
-"trf",
-"trg",
-"trh",
-"tri",
-"trj",
-"trk",
-"trl",
-"trm",
-"trn",
-"tro",
-"trp",
-"trq",
-"trr",
-"trs",
-"trt",
-"tru",
-"trv",
-"trw",
-"trx",
-"try",
-"trz",
-"tsa",
-"tsb",
-"tsc",
-"tsd",
-"tse",
-"tsf",
-"tsg",
-"tsh",
-"tsi",
-"tsj",
-"tsk",
-"tsl",
-"tsm",
-"tsp",
-"tsq",
-"tsr",
-"tss",
-"tst",
-"tsu",
-"tsv",
-"tsw",
-"tsx",
-"tsy",
-"tsz",
-"tta",
-"ttb",
-"ttc",
-"ttd",
-"tte",
-"ttf",
-"ttg",
-"tth",
-"tti",
-"ttj",
-"ttk",
-"ttl",
-"ttm",
-"ttn",
-"tto",
-"ttp",
-"ttq",
-"ttr",
-"tts",
-"ttt",
-"ttu",
-"ttv",
-"ttw",
-"tty",
-"ttz",
-"tua",
-"tub",
-"tuc",
-"tud",
-"tue",
-"tuf",
-"tug",
-"tuh",
-"tui",
-"tuj",
-"tul",
-"tum",
-"tun",
-"tuo",
-"tup",
-"tuq",
-"tus",
-"tut",
-"tuu",
-"tuv",
-"tuw",
-"tux",
-"tuy",
-"tuz",
-"tva",
-"tvd",
-"tve",
-"tvk",
-"tvl",
-"tvm",
-"tvn",
-"tvo",
-"tvs",
-"tvt",
-"tvu",
-"tvw",
-"tvy",
-"twa",
-"twb",
-"twc",
-"twd",
-"twe",
-"twf",
-"twg",
-"twh",
-"twl",
-"twm",
-"twn",
-"two",
-"twp",
-"twq",
-"twr",
-"twt",
-"twu",
-"tww",
-"twx",
-"twy",
-"txa",
-"txb",
-"txc",
-"txe",
-"txg",
-"txh",
-"txi",
-"txj",
-"txm",
-"txn",
-"txo",
-"txq",
-"txr",
-"txs",
-"txt",
-"txu",
-"txx",
-"txy",
-"tya",
-"tye",
-"tyh",
-"tyi",
-"tyj",
-"tyl",
-"tyn",
-"typ",
-"tyr",
-"tys",
-"tyt",
-"tyu",
-"tyv",
-"tyx",
-"tyz",
-"tza",
-"tzh",
-"tzj",
-"tzl",
-"tzm",
-"tzn",
-"tzo",
-"tzx",
-"uam",
-"uan",
-"uar",
-"uba",
-"ubi",
-"ubl",
-"ubr",
-"ubu",
-"uby",
-"uda",
-"ude",
-"udg",
-"udi",
-"udj",
-"udl",
-"udm",
-"udu",
-"ues",
-"ufi",
-"uga",
-"ugb",
-"uge",
-"ugn",
-"ugo",
-"ugy",
-"uha",
-"uhn",
-"uis",
-"uiv",
-"uji",
-"uka",
-"ukg",
-"ukh",
-"ukk",
-"ukl",
-"ukp",
-"ukq",
-"uks",
-"uku",
-"ukw",
-"uky",
-"ula",
-"ulb",
-"ulc",
-"ule",
-"ulf",
-"uli",
-"ulk",
-"ull",
-"ulm",
-"uln",
-"ulu",
-"ulw",
-"uma",
-"umb",
-"umc",
-"umd",
-"umg",
-"umi",
-"umm",
-"umn",
-"umo",
-"ump",
-"umr",
-"ums",
-"umu",
-"una",
-"und",
-"une",
-"ung",
-"unk",
-"unm",
-"unn",
-"unp",
-"unr",
-"unu",
-"unx",
-"unz",
-"uok",
-"upi",
-"upv",
-"ura",
-"urb",
-"urc",
-"ure",
-"urf",
-"urg",
-"urh",
-"uri",
-"urj",
-"urk",
-"url",
-"urm",
-"urn",
-"uro",
-"urp",
-"urr",
-"urt",
-"uru",
-"urv",
-"urw",
-"urx",
-"ury",
-"urz",
-"usa",
-"ush",
-"usi",
-"usk",
-"usp",
-"usu",
-"uta",
-"ute",
-"utp",
-"utr",
-"utu",
-"uum",
-"uun",
-"uur",
-"uuu",
-"uve",
-"uvh",
-"uvl",
-"uwa",
-"uya",
-"uzn",
-"uzs",
-"vaa",
-"vae",
-"vaf",
-"vag",
-"vah",
-"vai",
-"vaj",
-"val",
-"vam",
-"van",
-"vao",
-"vap",
-"var",
-"vas",
-"vau",
-"vav",
-"vay",
-"vbb",
-"vbk",
-"vec",
-"ved",
-"vel",
-"vem",
-"veo",
-"vep",
-"ver",
-"vgr",
-"vgt",
-"vic",
-"vid",
-"vif",
-"vig",
-"vil",
-"vin",
-"vis",
-"vit",
-"viv",
-"vka",
-"vki",
-"vkj",
-"vkk",
-"vkl",
-"vkm",
-"vko",
-"vkp",
-"vkt",
-"vku",
-"vlp",
-"vls",
-"vma",
-"vmb",
-"vmc",
-"vmd",
-"vme",
-"vmf",
-"vmg",
-"vmh",
-"vmi",
-"vmj",
-"vmk",
-"vml",
-"vmm",
-"vmp",
-"vmq",
-"vmr",
-"vms",
-"vmu",
-"vmv",
-"vmw",
-"vmx",
-"vmy",
-"vmz",
-"vnk",
-"vnm",
-"vnp",
-"vor",
-"vot",
-"vra",
-"vro",
-"vrs",
-"vrt",
-"vsi",
-"vsl",
-"vsv",
-"vto",
-"vum",
-"vun",
-"vut",
-"vwa",
-"waa",
-"wab",
-"wac",
-"wad",
-"wae",
-"waf",
-"wag",
-"wah",
-"wai",
-"waj",
-"wak",
-"wal",
-"wam",
-"wan",
-"wao",
-"wap",
-"waq",
-"war",
-"was",
-"wat",
-"wau",
-"wav",
-"waw",
-"wax",
-"way",
-"waz",
-"wba",
-"wbb",
-"wbe",
-"wbf",
-"wbh",
-"wbi",
-"wbj",
-"wbk",
-"wbl",
-"wbm",
-"wbp",
-"wbq",
-"wbr",
-"wbs",
-"wbt",
-"wbv",
-"wbw",
-"wca",
-"wci",
-"wdd",
-"wdg",
-"wdj",
-"wdk",
-"wdu",
-"wdy",
-"wea",
-"wec",
-"wed",
-"weg",
-"weh",
-"wei",
-"wem",
-"wen",
-"weo",
-"wep",
-"wer",
-"wes",
-"wet",
-"weu",
-"wew",
-"wfg",
-"wga",
-"wgb",
-"wgg",
-"wgi",
-"wgo",
-"wgu",
-"wgw",
-"wgy",
-"wha",
-"whg",
-"whk",
-"whu",
-"wib",
-"wic",
-"wie",
-"wif",
-"wig",
-"wih",
-"wii",
-"wij",
-"wik",
-"wil",
-"wim",
-"win",
-"wir",
-"wit",
-"wiu",
-"wiv",
-"wiw",
-"wiy",
-"wja",
-"wji",
-"wka",
-"wkb",
-"wkd",
-"wkl",
-"wku",
-"wkw",
-"wky",
-"wla",
-"wlc",
-"wle",
-"wlg",
-"wli",
-"wlk",
-"wll",
-"wlm",
-"wlo",
-"wlr",
-"wls",
-"wlu",
-"wlv",
-"wlw",
-"wlx",
-"wly",
-"wma",
-"wmb",
-"wmc",
-"wmd",
-"wme",
-"wmh",
-"wmi",
-"wmm",
-"wmn",
-"wmo",
-"wms",
-"wmt",
-"wmw",
-"wmx",
-"wnb",
-"wnc",
-"wnd",
-"wne",
-"wng",
-"wni",
-"wnk",
-"wnm",
-"wnn",
-"wno",
-"wnp",
-"wnu",
-"wnw",
-"wny",
-"woa",
-"wob",
-"woc",
-"wod",
-"woe",
-"wof",
-"wog",
-"woi",
-"wok",
-"wom",
-"won",
-"woo",
-"wor",
-"wos",
-"wow",
-"woy",
-"wpc",
-"wra",
-"wrb",
-"wrd",
-"wrg",
-"wrh",
-"wri",
-"wrk",
-"wrl",
-"wrm",
-"wrn",
-"wro",
-"wrp",
-"wrr",
-"wrs",
-"wru",
-"wrv",
-"wrw",
-"wrx",
-"wry",
-"wrz",
-"wsa",
-"wsg",
-"wsi",
-"wsk",
-"wsr",
-"wss",
-"wsu",
-"wsv",
-"wtf",
-"wth",
-"wti",
-"wtk",
-"wtm",
-"wtw",
-"wua",
-"wub",
-"wud",
-"wuh",
-"wul",
-"wum",
-"wun",
-"wur",
-"wut",
-"wuu",
-"wuv",
-"wux",
-"wuy",
-"wwa",
-"wwb",
-"wwo",
-"wwr",
-"www",
-"wxa",
-"wxw",
-"wya",
-"wyb",
-"wyi",
-"wym",
-"wyr",
-"wyy",
-"xaa",
-"xab",
-"xac",
-"xad",
-"xae",
-"xag",
-"xai",
-"xaj",
-"xak",
-"xal",
-"xam",
-"xan",
-"xao",
-"xap",
-"xaq",
-"xar",
-"xas",
-"xat",
-"xau",
-"xav",
-"xaw",
-"xay",
-"xba",
-"xbb",
-"xbc",
-"xbd",
-"xbe",
-"xbg",
-"xbi",
-"xbj",
-"xbm",
-"xbn",
-"xbo",
-"xbp",
-"xbr",
-"xbw",
-"xbx",
-"xby",
-"xcb",
-"xcc",
-"xce",
-"xcg",
-"xch",
-"xcl",
-"xcm",
-"xcn",
-"xco",
-"xcr",
-"xct",
-"xcu",
-"xcv",
-"xcw",
-"xcy",
-"xda",
-"xdc",
-"xdk",
-"xdm",
-"xdo",
-"xdy",
-"xeb",
-"xed",
-"xeg",
-"xel",
-"xem",
-"xep",
-"xer",
-"xes",
-"xet",
-"xeu",
-"xfa",
-"xga",
-"xgb",
-"xgd",
-"xgf",
-"xgg",
-"xgi",
-"xgl",
-"xgm",
-"xgn",
-"xgr",
-"xgu",
-"xgw",
-"xha",
-"xhc",
-"xhd",
-"xhe",
-"xhr",
-"xht",
-"xhu",
-"xhv",
-"xia",
-"xib",
-"xii",
-"xil",
-"xin",
-"xip",
-"xir",
-"xis",
-"xiv",
-"xiy",
-"xjb",
-"xjt",
-"xka",
-"xkb",
-"xkc",
-"xkd",
-"xke",
-"xkf",
-"xkg",
-"xkh",
-"xki",
-"xkj",
-"xkk",
-"xkl",
-"xkn",
-"xko",
-"xkp",
-"xkq",
-"xkr",
-"xks",
-"xkt",
-"xku",
-"xkv",
-"xkw",
-"xkx",
-"xky",
-"xkz",
-"xla",
-"xlb",
-"xlc",
-"xld",
-"xle",
-"xlg",
-"xli",
-"xln",
-"xlo",
-"xlp",
-"xls",
-"xlu",
-"xly",
-"xma",
-"xmb",
-"xmc",
-"xmd",
-"xme",
-"xmf",
-"xmg",
-"xmh",
-"xmj",
-"xmk",
-"xml",
-"xmm",
-"xmn",
-"xmo",
-"xmp",
-"xmq",
-"xmr",
-"xms",
-"xmt",
-"xmu",
-"xmv",
-"xmw",
-"xmx",
-"xmy",
-"xmz",
-"xna",
-"xnb",
-"xnd",
-"xng",
-"xnh",
-"xni",
-"xnk",
-"xnn",
-"xno",
-"xnr",
-"xns",
-"xnt",
-"xnu",
-"xny",
-"xnz",
-"xoc",
-"xod",
-"xog",
-"xoi",
-"xok",
-"xom",
-"xon",
-"xoo",
-"xop",
-"xor",
-"xow",
-"xpa",
-"xpc",
-"xpe",
-"xpg",
-"xpi",
-"xpj",
-"xpk",
-"xpm",
-"xpn",
-"xpo",
-"xpp",
-"xpq",
-"xpr",
-"xps",
-"xpt",
-"xpu",
-"xpy",
-"xqa",
-"xqt",
-"xra",
-"xrb",
-"xrd",
-"xre",
-"xrg",
-"xri",
-"xrm",
-"xrn",
-"xrq",
-"xrr",
-"xrt",
-"xru",
-"xrw",
-"xsa",
-"xsb",
-"xsc",
-"xsd",
-"xse",
-"xsh",
-"xsi",
-"xsj",
-"xsl",
-"xsm",
-"xsn",
-"xso",
-"xsp",
-"xsq",
-"xsr",
-"xss",
-"xsu",
-"xsv",
-"xsy",
-"xta",
-"xtb",
-"xtc",
-"xtd",
-"xte",
-"xtg",
-"xth",
-"xti",
-"xtj",
-"xtl",
-"xtm",
-"xtn",
-"xto",
-"xtp",
-"xtq",
-"xtr",
-"xts",
-"xtt",
-"xtu",
-"xtv",
-"xtw",
-"xty",
-"xtz",
-"xua",
-"xub",
-"xud",
-"xug",
-"xuj",
-"xul",
-"xum",
-"xun",
-"xuo",
-"xup",
-"xur",
-"xut",
-"xuu",
-"xve",
-"xvi",
-"xvn",
-"xvo",
-"xvs",
-"xwa",
-"xwc",
-"xwd",
-"xwe",
-"xwg",
-"xwj",
-"xwk",
-"xwl",
-"xwo",
-"xwr",
-"xwt",
-"xww",
-"xxb",
-"xxk",
-"xxm",
-"xxr",
-"xxt",
-"xya",
-"xyb",
-"xyj",
-"xyk",
-"xyl",
-"xyt",
-"xyy",
-"xzh",
-"xzm",
-"xzp",
-"yaa",
-"yab",
-"yac",
-"yad",
-"yae",
-"yaf",
-"yag",
-"yah",
-"yai",
-"yaj",
-"yak",
-"yal",
-"yam",
-"yan",
-"yao",
-"yap",
-"yaq",
-"yar",
-"yas",
-"yat",
-"yau",
-"yav",
-"yaw",
-"yax",
-"yay",
-"yaz",
-"yba",
-"ybb",
-"ybd",
-"ybe",
-"ybh",
-"ybi",
-"ybj",
-"ybk",
-"ybl",
-"ybm",
-"ybn",
-"ybo",
-"ybx",
-"yby",
-"ych",
-"ycl",
-"ycn",
-"ycp",
-"yda",
-"ydd",
-"yde",
-"ydg",
-"ydk",
-"yds",
-"yea",
-"yec",
-"yee",
-"yei",
-"yej",
-"yel",
-"yen",
-"yer",
-"yes",
-"yet",
-"yeu",
-"yev",
-"yey",
-"yga",
-"ygi",
-"ygl",
-"ygm",
-"ygp",
-"ygr",
-"ygs",
-"ygu",
-"ygw",
-"yha",
-"yhd",
-"yhl",
-"yhs",
-"yia",
-"yif",
-"yig",
-"yih",
-"yii",
-"yij",
-"yik",
-"yil",
-"yim",
-"yin",
-"yip",
-"yiq",
-"yir",
-"yis",
-"yit",
-"yiu",
-"yiv",
-"yix",
-"yiy",
-"yiz",
-"yka",
-"ykg",
-"yki",
-"ykk",
-"ykl",
-"ykm",
-"ykn",
-"yko",
-"ykr",
-"ykt",
-"yku",
-"yky",
-"yla",
-"ylb",
-"yle",
-"ylg",
-"yli",
-"yll",
-"ylm",
-"yln",
-"ylo",
-"ylr",
-"ylu",
-"yly",
-"yma",
-"ymb",
-"ymc",
-"ymd",
-"yme",
-"ymg",
-"ymh",
-"ymi",
-"ymk",
-"yml",
-"ymm",
-"ymn",
-"ymo",
-"ymp",
-"ymq",
-"ymr",
-"yms",
-"ymt",
-"ymx",
-"ymz",
-"yna",
-"ynd",
-"yne",
-"yng",
-"ynh",
-"ynk",
-"ynl",
-"ynn",
-"yno",
-"ynq",
-"yns",
-"ynu",
-"yob",
-"yog",
-"yoi",
-"yok",
-"yol",
-"yom",
-"yon",
-"yos",
-"yot",
-"yox",
-"yoy",
-"ypa",
-"ypb",
-"ypg",
-"yph",
-"ypk",
-"ypm",
-"ypn",
-"ypo",
-"ypp",
-"ypz",
-"yra",
-"yrb",
-"yre",
-"yri",
-"yrk",
-"yrl",
-"yrm",
-"yrn",
-"yro",
-"yrs",
-"yrw",
-"yry",
-"ysc",
-"ysd",
-"ysg",
-"ysl",
-"ysn",
-"yso",
-"ysp",
-"ysr",
-"yss",
-"ysy",
-"yta",
-"ytl",
-"ytp",
-"ytw",
-"yty",
-"yua",
-"yub",
-"yuc",
-"yud",
-"yue",
-"yuf",
-"yug",
-"yui",
-"yuj",
-"yuk",
-"yul",
-"yum",
-"yun",
-"yup",
-"yuq",
-"yur",
-"yut",
-"yuu",
-"yuw",
-"yux",
-"yuy",
-"yuz",
-"yva",
-"yvt",
-"ywa",
-"ywg",
-"ywl",
-"ywn",
-"ywq",
-"ywr",
-"ywt",
-"ywu",
-"yww",
-"yxa",
-"yxg",
-"yxl",
-"yxm",
-"yxu",
-"yxy",
-"yyr",
-"yyu",
-"yyz",
-"yzg",
-"yzk",
-"zaa",
-"zab",
-"zac",
-"zad",
-"zae",
-"zaf",
-"zag",
-"zah",
-"zai",
-"zaj",
-"zak",
-"zal",
-"zam",
-"zao",
-"zap",
-"zaq",
-"zar",
-"zas",
-"zat",
-"zau",
-"zav",
-"zaw",
-"zax",
-"zay",
-"zaz",
-"zbc",
-"zbe",
-"zbl",
-"zbt",
-"zbw",
-"zca",
-"zch",
-"zdj",
-"zea",
-"zeg",
-"zeh",
-"zen",
-"zga",
-"zgb",
-"zgh",
-"zgm",
-"zgn",
-"zgr",
-"zhb",
-"zhd",
-"zhi",
-"zhn",
-"zhw",
-"zhx",
-"zia",
-"zib",
-"zik",
-"zil",
-"zim",
-"zin",
-"zir",
-"ziw",
-"ziz",
-"zka",
-"zkb",
-"zkd",
-"zkg",
-"zkh",
-"zkk",
-"zkn",
-"zko",
-"zkp",
-"zkr",
-"zkt",
-"zku",
-"zkv",
-"zkz",
-"zle",
-"zlj",
-"zlm",
-"zln",
-"zlq",
-"zls",
-"zlw",
-"zma",
-"zmb",
-"zmc",
-"zmd",
-"zme",
-"zmf",
-"zmg",
-"zmh",
-"zmi",
-"zmj",
-"zmk",
-"zml",
-"zmm",
-"zmn",
-"zmo",
-"zmp",
-"zmq",
-"zmr",
-"zms",
-"zmt",
-"zmu",
-"zmv",
-"zmw",
-"zmx",
-"zmy",
-"zmz",
-"zna",
-"znd",
-"zne",
-"zng",
-"znk",
-"zns",
-"zoc",
-"zoh",
-"zom",
-"zoo",
-"zoq",
-"zor",
-"zos",
-"zpa",
-"zpb",
-"zpc",
-"zpd",
-"zpe",
-"zpf",
-"zpg",
-"zph",
-"zpi",
-"zpj",
-"zpk",
-"zpl",
-"zpm",
-"zpn",
-"zpo",
-"zpp",
-"zpq",
-"zpr",
-"zps",
-"zpt",
-"zpu",
-"zpv",
-"zpw",
-"zpx",
-"zpy",
-"zpz",
-"zqe",
-"zra",
-"zrg",
-"zrn",
-"zro",
-"zrp",
-"zrs",
-"zsa",
-"zsk",
-"zsl",
-"zsm",
-"zsr",
-"zsu",
-"zte",
-"ztg",
-"ztl",
-"ztm",
-"ztn",
-"ztp",
-"ztq",
-"zts",
-"ztt",
-"ztu",
-"ztx",
-"zty",
-"zua",
-"zuh",
-"zum",
-"zun",
-"zuy",
-"zwa",
-"zxx",
-"zyb",
-"zyg",
-"zyj",
-"zyn",
-"zyp",
-"zza",
-"zzj"];
-
-
-
-
-
-
-
-
-
-axe.utils.validLangs=function(){
-'use strict';
-return langs;
-};
-
-},{}],93:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-window.requestFileSystem=window.requestFileSystem||window.webkitRequestFileSystem;
-
-
-
-
-WebInspector.TempFile=function()
-{
-this._fileEntry=null;
-this._writer=null;
-};
-
-
-
-
-
-
-WebInspector.TempFile.create=function(dirPath,name)
-{
-var file=new WebInspector.TempFile();
-
-function requestTempFileSystem()
-{
-return new Promise(window.requestFileSystem.bind(window,window.TEMPORARY,10));
-}
-
-
-
-
-function getDirectoryEntry(fs)
-{
-return new Promise(fs.root.getDirectory.bind(fs.root,dirPath,{create:true}));
-}
-
-
-
-
-function getFileEntry(dir)
-{
-return new Promise(dir.getFile.bind(dir,name,{create:true}));
-}
-
-
-
-
-function createFileWriter(fileEntry)
-{
-file._fileEntry=fileEntry;
-return new Promise(fileEntry.createWriter.bind(fileEntry));
-}
-
-
-
-
-function truncateFile(writer)
-{
-if(!writer.length){
-file._writer=writer;
-return Promise.resolve(file);
-}
-
-
-
-
-
-function truncate(fulfill,reject)
-{
-writer.onwriteend=fulfill;
-writer.onerror=reject;
-writer.truncate(0);
-}
-
-function didTruncate()
-{
-file._writer=writer;
-writer.onwriteend=null;
-writer.onerror=null;
-return Promise.resolve(file);
-}
-
-function onTruncateError(e)
-{
-writer.onwriteend=null;
-writer.onerror=null;
-throw e;
-}
-
-return new Promise(truncate).then(didTruncate,onTruncateError);
-}
-
-return WebInspector.TempFile.ensureTempStorageCleared().
-then(requestTempFileSystem).
-then(getDirectoryEntry).
-then(getFileEntry).
-then(createFileWriter).
-then(truncateFile);
-};
-
-WebInspector.TempFile.prototype={
-
-
-
-
-write:function(strings,callback)
-{
-var blob=new Blob(strings,{type:"text/plain"});
-this._writer.onerror=function(e)
-{
-WebInspector.console.error("Failed to write into a temp file: "+e.target.error.message);
-callback(-1);
-};
-this._writer.onwriteend=function(e)
-{
-callback(e.target.length);
-};
-this._writer.write(blob);
-},
-
-finishWriting:function()
-{
-this._writer=null;
-},
-
-
-
-
-read:function(callback)
-{
-this.readRange(undefined,undefined,callback);
-},
-
-
-
-
-
-
-readRange:function(startOffset,endOffset,callback)
-{
-
-
-
-function didGetFile(file)
-{
-var reader=new FileReader();
-
-if(typeof startOffset==="number"||typeof endOffset==="number")
-file=file.slice(startOffset,endOffset);
-
-
-
-reader.onloadend=function(e)
-{
-callback(this.result);
-};
-reader.onerror=function(error)
-{
-WebInspector.console.error("Failed to read from temp file: "+error.message);
-};
-reader.readAsText(file);
-}
-function didFailToGetFile(error)
-{
-WebInspector.console.error("Failed to load temp file: "+error.message);
-callback(null);
-}
-this._fileEntry.file(didGetFile,didFailToGetFile);
-},
-
-
-
-
-
-copyToOutputStream:function(outputStream,delegate)
-{
-
-
-
-function didGetFile(file)
-{
-var reader=new WebInspector.ChunkedFileReader(file,10*1000*1000,delegate);
-reader.start(outputStream);
-}
-
-function didFailToGetFile(error)
-{
-WebInspector.console.error("Failed to load temp file: "+error.message);
-outputStream.close();
-}
-
-this._fileEntry.file(didGetFile,didFailToGetFile);
-},
-
-remove:function()
-{
-if(this._fileEntry)
-this._fileEntry.remove(function(){});
-}};
-
-
-
-
-
-
-
-WebInspector.DeferredTempFile=function(dirPath,name)
-{
-
-this._chunks=[];
-this._tempFile=null;
-this._isWriting=false;
-this._finishCallback=null;
-this._finishedWriting=false;
-this._callsPendingOpen=[];
-this._pendingReads=[];
-WebInspector.TempFile.create(dirPath,name).
-then(this._didCreateTempFile.bind(this),this._failedToCreateTempFile.bind(this));
-};
-
-WebInspector.DeferredTempFile.prototype={
-
-
-
-
-write:function(strings,callback)
-{
-if(this._finishCallback)
-throw new Error("No writes are allowed after close.");
-this._chunks.push({strings:strings,callback:callback||null});
-if(this._tempFile&&!this._isWriting)
-this._writeNextChunk();
-},
-
-
-
-
-finishWriting:function(callback)
-{
-this._finishCallback=callback;
-if(this._finishedWriting)
-callback(this._tempFile);else
-if(!this._isWriting&&!this._chunks.length)
-this._notifyFinished();
-},
-
-
-
-
-_failedToCreateTempFile:function(e)
-{
-WebInspector.console.error("Failed to create temp file "+e.code+" : "+e.message);
-this._notifyFinished();
-},
-
-
-
-
-_didCreateTempFile:function(tempFile)
-{
-this._tempFile=tempFile;
-var callsPendingOpen=this._callsPendingOpen;
-this._callsPendingOpen=null;
-for(var i=0;i<callsPendingOpen.length;++i)
-callsPendingOpen[i]();
-if(this._chunks.length)
-this._writeNextChunk();
-},
-
-_writeNextChunk:function()
-{
-
-if(!this._tempFile)
-return;
-var chunk=this._chunks.shift();
-this._isWriting=true;
-this._tempFile.write(chunk.strings,this._didWriteChunk.bind(this,chunk.callback));
-},
-
-
-
-
-
-_didWriteChunk:function(callback,size)
-{
-this._isWriting=false;
-if(size===-1){
-this._tempFile=null;
-this._notifyFinished();
-return;
-}
-if(callback)
-callback(size);
-if(this._chunks.length)
-this._writeNextChunk();else
-if(this._finishCallback)
-this._notifyFinished();
-},
-
-_notifyFinished:function()
-{
-this._finishedWriting=true;
-if(this._tempFile)
-this._tempFile.finishWriting();
-var chunks=this._chunks;
-this._chunks=[];
-for(var i=0;i<chunks.length;++i){
-if(chunks[i].callback)
-chunks[i].callback(-1);
-}
-if(this._finishCallback)
-this._finishCallback(this._tempFile);
-var pendingReads=this._pendingReads;
-this._pendingReads=[];
-for(var i=0;i<pendingReads.length;++i)
-pendingReads[i]();
-},
-
-
-
-
-
-
-readRange:function(startOffset,endOffset,callback)
-{
-if(!this._finishedWriting){
-this._pendingReads.push(this.readRange.bind(this,startOffset,endOffset,callback));
-return;
-}
-if(!this._tempFile){
-callback(null);
-return;
-}
-this._tempFile.readRange(startOffset,endOffset,callback);
-},
-
-
-
-
-
-copyToOutputStream:function(outputStream,delegate)
-{
-if(!this._finishedWriting){
-this._pendingReads.push(this.copyToOutputStream.bind(this,outputStream,delegate));
-return;
-}
-if(this._tempFile)
-this._tempFile.copyToOutputStream(outputStream,delegate);
-},
-
-remove:function()
-{
-if(this._callsPendingOpen){
-this._callsPendingOpen.push(this.remove.bind(this));
-return;
-}
-if(this._tempFile)
-this._tempFile.remove();
-this._tempFile=null;
-}};
-
-
-
-
-
-
-WebInspector.TempFile._clearTempStorage=function(fulfill,reject)
-{
-
-
-
-function handleError(event)
-{
-WebInspector.console.error(WebInspector.UIString("Failed to clear temp storage: %s",event.data));
-reject(event.data);
-}
-
-
-
-
-function handleMessage(event)
-{
-if(event.data.type==="tempStorageCleared"){
-if(event.data.error)
-WebInspector.console.error(event.data.error);else
-
-fulfill(undefined);
-return;
-}
-reject(event.data);
-}
-
-try{
-var worker=new WebInspector.Worker("temp_storage_shared_worker","TempStorageCleaner");
-worker.onerror=handleError;
-worker.onmessage=handleMessage;
-}catch(e){
-if(e.name==="URLMismatchError")
-console.log("Shared worker wasn't started due to url difference. "+e);else
-
-throw e;
-}
-};
-
-
-
-
-WebInspector.TempFile.ensureTempStorageCleared=function()
-{
-if(!WebInspector.TempFile._storageCleanerPromise)
-WebInspector.TempFile._storageCleanerPromise=new Promise(WebInspector.TempFile._clearTempStorage);
-return WebInspector.TempFile._storageCleanerPromise;
-};
-
-
-
-
-
-
-WebInspector.TempFileBackingStorage=function(dirName)
-{
-this._dirName=dirName;
-this.reset();
-};
-
-
-
-
-
-
-
-
-WebInspector.TempFileBackingStorage.Chunk;
-
-WebInspector.TempFileBackingStorage.prototype={
-
-
-
-
-appendString:function(string)
-{
-this._strings.push(string);
-this._stringsLength+=string.length;
-var flushStringLength=10*1024*1024;
-if(this._stringsLength>flushStringLength)
-this._flush(false);
-},
-
-
-
-
-
-
-appendAccessibleString:function(string)
-{
-this._flush(false);
-this._strings.push(string);
-var chunk=this._flush(true);
-
-
-
-
-
-
-function readString(chunk,file)
-{
-if(chunk.string)
-return Promise.resolve(chunk.string);
-
-console.assert(chunk.endOffset);
-if(!chunk.endOffset)
-return Promise.reject("Nor string nor offset to the string in the file were found.");
-
-
-
-
-
-function readRange(fulfill,reject)
-{
-
-file.readRange(chunk.startOffset,chunk.endOffset,fulfill);
-}
-
-return new Promise(readRange);
-}
-
-return readString.bind(null,chunk,this._file);
-},
-
-
-
-
-
-_flush:function(createChunk)
-{
-if(!this._strings.length)
-return null;
-
-var chunk=null;
-if(createChunk){
-console.assert(this._strings.length===1);
-chunk={
-string:this._strings[0],
-startOffset:0,
-endOffset:0};
-
-}
-
-
-
-
-
-
-function didWrite(chunk,fileSize)
-{
-if(fileSize===-1)
-return;
-if(chunk){
-chunk.startOffset=this._fileSize;
-chunk.endOffset=fileSize;
-chunk.string=null;
-}
-this._fileSize=fileSize;
-}
-
-this._file.write(this._strings,didWrite.bind(this,chunk));
-this._strings=[];
-this._stringsLength=0;
-return chunk;
-},
-
-
-
-
-finishWriting:function()
-{
-this._flush(false);
-this._file.finishWriting(function(){});
-},
-
-
-
-
-reset:function()
-{
-if(this._file)
-this._file.remove();
-this._file=new WebInspector.DeferredTempFile(this._dirName,String(Date.now()));
-
-
-
-this._strings=[];
-this._stringsLength=0;
-this._fileSize=0;
-},
-
-
-
-
-
-writeToStream:function(outputStream,delegate)
-{
-this._file.copyToOutputStream(outputStream,delegate);
-}};
-
-
-},{}],94:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.Color=function(rgba,format,originalText)
-{
-this._rgba=rgba;
-this._originalText=originalText||null;
-this._originalTextIsValid=!!this._originalText;
-this._format=format;
-if(typeof this._rgba[3]==="undefined")
-this._rgba[3]=1;
-
-for(var i=0;i<4;++i){
-if(this._rgba[i]<0){
-this._rgba[i]=0;
-this._originalTextIsValid=false;
-}
-if(this._rgba[i]>1){
-this._rgba[i]=1;
-this._originalTextIsValid=false;
-}
-}
-};
-
-
-WebInspector.Color.Regex=/((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b[a-zA-Z]+\b(?!-))/g;
-
-
-
-
-WebInspector.Color.Format={
-Original:"original",
-Nickname:"nickname",
-HEX:"hex",
-ShortHEX:"shorthex",
-RGB:"rgb",
-RGBA:"rgba",
-HSL:"hsl",
-HSLA:"hsla"};
-
-
-
-
-
-
-WebInspector.Color.parse=function(text)
-{
-
-var value=text.toLowerCase().replace(/\s+/g,"");
-var simple=/^(?:#([0-9a-f]{3}|[0-9a-f]{6})|rgb\(((?:-?\d+%?,){2}-?\d+%?)\)|(\w+)|hsl\((-?\d+\.?\d*(?:,-?\d+\.?\d*%){2})\))$/i;
-var match=value.match(simple);
-if(match){
-if(match[1]){
-var hex=match[1].toLowerCase();
-var format;
-if(hex.length===3){
-format=WebInspector.Color.Format.ShortHEX;
-hex=hex.charAt(0)+hex.charAt(0)+hex.charAt(1)+hex.charAt(1)+hex.charAt(2)+hex.charAt(2);
-}else
-format=WebInspector.Color.Format.HEX;
-var r=parseInt(hex.substring(0,2),16);
-var g=parseInt(hex.substring(2,4),16);
-var b=parseInt(hex.substring(4,6),16);
-return new WebInspector.Color([r/255,g/255,b/255,1],format,text);
-}
-
-if(match[2]){
-var rgbString=match[2].split(/\s*,\s*/);
-var rgba=[WebInspector.Color._parseRgbNumeric(rgbString[0]),
-WebInspector.Color._parseRgbNumeric(rgbString[1]),
-WebInspector.Color._parseRgbNumeric(rgbString[2]),1];
-return new WebInspector.Color(rgba,WebInspector.Color.Format.RGB,text);
-}
-
-if(match[3]){
-var nickname=match[3].toLowerCase();
-if(nickname in WebInspector.Color.Nicknames){
-var rgba=WebInspector.Color.Nicknames[nickname];
-var color=WebInspector.Color.fromRGBA(rgba);
-color._format=WebInspector.Color.Format.Nickname;
-color._originalText=text;
-return color;
-}
-return null;
-}
-
-if(match[4]){
-var hslString=match[4].replace(/%/g,"").split(/\s*,\s*/);
-var hsla=[WebInspector.Color._parseHueNumeric(hslString[0]),
-WebInspector.Color._parseSatLightNumeric(hslString[1]),
-WebInspector.Color._parseSatLightNumeric(hslString[2]),1];
-var rgba=[];
-WebInspector.Color.hsl2rgb(hsla,rgba);
-return new WebInspector.Color(rgba,WebInspector.Color.Format.HSL,text);
-}
-
-return null;
-}
-
-
-var advanced=/^(?:rgba\(((?:-?\d+%?,){3}-?(?:\d+|\d*\.\d+))\)|hsla\((-?(?:\d+|\d*\.\d+)(?:,-?(?:\d+|\d*\.\d+)*%){2},-?(?:\d+|\d*\.\d+))\))$/;
-match=value.match(advanced);
-if(match){
-if(match[1]){
-var rgbaString=match[1].split(/\s*,\s*/);
-var rgba=[WebInspector.Color._parseRgbNumeric(rgbaString[0]),
-WebInspector.Color._parseRgbNumeric(rgbaString[1]),
-WebInspector.Color._parseRgbNumeric(rgbaString[2]),
-WebInspector.Color._parseAlphaNumeric(rgbaString[3])];
-return new WebInspector.Color(rgba,WebInspector.Color.Format.RGBA,text);
-}
-
-if(match[2]){
-var hslaString=match[2].replace(/%/g,"").split(/\s*,\s*/);
-var hsla=[WebInspector.Color._parseHueNumeric(hslaString[0]),
-WebInspector.Color._parseSatLightNumeric(hslaString[1]),
-WebInspector.Color._parseSatLightNumeric(hslaString[2]),
-WebInspector.Color._parseAlphaNumeric(hslaString[3])];
-var rgba=[];
-WebInspector.Color.hsl2rgb(hsla,rgba);
-return new WebInspector.Color(rgba,WebInspector.Color.Format.HSLA,text);
-}
-}
-
-return null;
-};
-
-
-
-
-
-WebInspector.Color.fromRGBA=function(rgba)
-{
-return new WebInspector.Color([rgba[0]/255,rgba[1]/255,rgba[2]/255,rgba[3]],WebInspector.Color.Format.RGBA);
-};
-
-
-
-
-
-WebInspector.Color.fromHSVA=function(hsva)
-{
-var rgba=[];
-WebInspector.Color.hsva2rgba(hsva,rgba);
-return new WebInspector.Color(rgba,WebInspector.Color.Format.HSLA);
-};
-
-WebInspector.Color.prototype={
-
-
-
-format:function()
-{
-return this._format;
-},
-
-
-
-
-hsla:function()
-{
-if(this._hsla)
-return this._hsla;
-var r=this._rgba[0];
-var g=this._rgba[1];
-var b=this._rgba[2];
-var max=Math.max(r,g,b);
-var min=Math.min(r,g,b);
-var diff=max-min;
-var add=max+min;
-
-if(min===max)
-var h=0;else
-if(r===max)
-var h=(1/6*(g-b)/diff+1)%1;else
-if(g===max)
-var h=1/6*(b-r)/diff+1/3;else
-
-var h=1/6*(r-g)/diff+2/3;
-
-var l=0.5*add;
-
-if(l===0)
-var s=0;else
-if(l===1)
-var s=0;else
-if(l<=0.5)
-var s=diff/add;else
-
-var s=diff/(2-add);
-
-this._hsla=[h,s,l,this._rgba[3]];
-return this._hsla;
-},
-
-
-
-
-canonicalHSLA:function()
-{
-var hsla=this.hsla();
-return[Math.round(hsla[0]*360),Math.round(hsla[1]*100),Math.round(hsla[2]*100),hsla[3]];
-},
-
-
-
-
-hsva:function()
-{
-var hsla=this.hsla();
-var h=hsla[0];
-var s=hsla[1];
-var l=hsla[2];
-
-s*=l<0.5?l:1-l;
-return[h,s!==0?2*s/(l+s):0,l+s,hsla[3]];
-},
-
-
-
-
-hasAlpha:function()
-{
-return this._rgba[3]!==1;
-},
-
-
-
-
-canBeShortHex:function()
-{
-if(this.hasAlpha())
-return false;
-for(var i=0;i<3;++i){
-var c=Math.round(this._rgba[i]*255);
-if(c%17)
-return false;
-}
-return true;
-},
-
-
-
-
-asString:function(format)
-{
-if(format===this._format&&this._originalTextIsValid)
-return this._originalText;
-
-if(!format)
-format=this._format;
-
-
-
-
-
-function toRgbValue(value)
-{
-return Math.round(value*255);
-}
-
-
-
-
-
-function toHexValue(value)
-{
-var hex=Math.round(value*255).toString(16);
-return hex.length===1?"0"+hex:hex;
-}
-
-
-
-
-
-function toShortHexValue(value)
-{
-return(Math.round(value*255)/17).toString(16);
-}
-
-switch(format){
-case WebInspector.Color.Format.Original:
-return this._originalText;
-case WebInspector.Color.Format.RGB:
-if(this.hasAlpha())
-return null;
-return String.sprintf("rgb(%d, %d, %d)",toRgbValue(this._rgba[0]),toRgbValue(this._rgba[1]),toRgbValue(this._rgba[2]));
-case WebInspector.Color.Format.RGBA:
-return String.sprintf("rgba(%d, %d, %d, %f)",toRgbValue(this._rgba[0]),toRgbValue(this._rgba[1]),toRgbValue(this._rgba[2]),this._rgba[3]);
-case WebInspector.Color.Format.HSL:
-if(this.hasAlpha())
-return null;
-var hsl=this.hsla();
-return String.sprintf("hsl(%d, %d%, %d%)",Math.round(hsl[0]*360),Math.round(hsl[1]*100),Math.round(hsl[2]*100));
-case WebInspector.Color.Format.HSLA:
-var hsla=this.hsla();
-return String.sprintf("hsla(%d, %d%, %d%, %f)",Math.round(hsla[0]*360),Math.round(hsla[1]*100),Math.round(hsla[2]*100),hsla[3]);
-case WebInspector.Color.Format.HEX:
-if(this.hasAlpha())
-return null;
-return String.sprintf("#%s%s%s",toHexValue(this._rgba[0]),toHexValue(this._rgba[1]),toHexValue(this._rgba[2])).toLowerCase();
-case WebInspector.Color.Format.ShortHEX:
-if(!this.canBeShortHex())
-return null;
-return String.sprintf("#%s%s%s",toShortHexValue(this._rgba[0]),toShortHexValue(this._rgba[1]),toShortHexValue(this._rgba[2])).toLowerCase();
-case WebInspector.Color.Format.Nickname:
-return this.nickname();}
-
-
-return this._originalText;
-},
-
-
-
-
-
-rgba:function()
-{
-return this._rgba.slice();
-},
-
-
-
-
-canonicalRGBA:function()
-{
-var rgba=new Array(4);
-for(var i=0;i<3;++i)
-rgba[i]=Math.round(this._rgba[i]*255);
-rgba[3]=this._rgba[3];
-return rgba;
-},
-
-
-
-
-nickname:function()
-{
-if(!WebInspector.Color._rgbaToNickname){
-WebInspector.Color._rgbaToNickname={};
-for(var nickname in WebInspector.Color.Nicknames){
-var rgba=WebInspector.Color.Nicknames[nickname];
-if(rgba.length!==4)
-rgba=rgba.concat(1);
-WebInspector.Color._rgbaToNickname[rgba]=nickname;
-}
-}
-
-return WebInspector.Color._rgbaToNickname[this.canonicalRGBA()]||null;
-},
-
-
-
-
-toProtocolRGBA:function()
-{
-var rgba=this.canonicalRGBA();
-var result={r:rgba[0],g:rgba[1],b:rgba[2]};
-if(rgba[3]!==1)
-result.a=rgba[3];
-return result;
-},
-
-
-
-
-invert:function()
-{
-var rgba=[];
-rgba[0]=1-this._rgba[0];
-rgba[1]=1-this._rgba[1];
-rgba[2]=1-this._rgba[2];
-rgba[3]=this._rgba[3];
-return new WebInspector.Color(rgba,WebInspector.Color.Format.RGBA);
-},
-
-
-
-
-
-setAlpha:function(alpha)
-{
-var rgba=this._rgba.slice();
-rgba[3]=alpha;
-return new WebInspector.Color(rgba,WebInspector.Color.Format.RGBA);
-}};
-
-
-
-
-
-
-WebInspector.Color._parseRgbNumeric=function(value)
-{
-var parsed=parseInt(value,10);
-if(value.indexOf("%")!==-1)
-parsed/=100;else
-
-parsed/=255;
-return parsed;
-};
-
-
-
-
-
-WebInspector.Color._parseHueNumeric=function(value)
-{
-return isNaN(value)?0:parseFloat(value)/360%1;
-};
-
-
-
-
-
-WebInspector.Color._parseSatLightNumeric=function(value)
-{
-return Math.min(1,parseFloat(value)/100);
-};
-
-
-
-
-
-WebInspector.Color._parseAlphaNumeric=function(value)
-{
-return isNaN(value)?0:parseFloat(value);
-};
-
-
-
-
-
-WebInspector.Color._hsva2hsla=function(hsva,out_hsla)
-{
-var h=hsva[0];
-var s=hsva[1];
-var v=hsva[2];
-
-var t=(2-s)*v;
-if(v===0||s===0)
-s=0;else
-
-s*=v/(t<1?t:2-t);
-
-out_hsla[0]=h;
-out_hsla[1]=s;
-out_hsla[2]=t/2;
-out_hsla[3]=hsva[3];
-};
-
-
-
-
-
-WebInspector.Color.hsl2rgb=function(hsl,out_rgb)
-{
-var h=hsl[0];
-var s=hsl[1];
-var l=hsl[2];
-
-function hue2rgb(p,q,h)
-{
-if(h<0)
-h+=1;else
-if(h>1)
-h-=1;
-
-if(h*6<1)
-return p+(q-p)*h*6;else
-if(h*2<1)
-return q;else
-if(h*3<2)
-return p+(q-p)*(2/3-h)*6;else
-
-return p;
-}
-
-if(s<0)
-s=0;
-
-if(l<=0.5)
-var q=l*(1+s);else
-
-var q=l+s-l*s;
-
-var p=2*l-q;
-
-var tr=h+1/3;
-var tg=h;
-var tb=h-1/3;
-
-out_rgb[0]=hue2rgb(p,q,tr);
-out_rgb[1]=hue2rgb(p,q,tg);
-out_rgb[2]=hue2rgb(p,q,tb);
-out_rgb[3]=hsl[3];
-};
-
-
-
-
-
-WebInspector.Color.hsva2rgba=function(hsva,out_rgba)
-{
-WebInspector.Color._hsva2hsla(hsva,WebInspector.Color.hsva2rgba._tmpHSLA);
-WebInspector.Color.hsl2rgb(WebInspector.Color.hsva2rgba._tmpHSLA,out_rgba);
-
-for(var i=0;i<WebInspector.Color.hsva2rgba._tmpHSLA.length;i++)
-WebInspector.Color.hsva2rgba._tmpHSLA[i]=0;
-};
-
-
-WebInspector.Color.hsva2rgba._tmpHSLA=[0,0,0,0];
-
-
-
-
-
-
-
-
-WebInspector.Color.luminance=function(rgba)
-{
-var rSRGB=rgba[0];
-var gSRGB=rgba[1];
-var bSRGB=rgba[2];
-
-var r=rSRGB<=0.03928?rSRGB/12.92:Math.pow((rSRGB+0.055)/1.055,2.4);
-var g=gSRGB<=0.03928?gSRGB/12.92:Math.pow((gSRGB+0.055)/1.055,2.4);
-var b=bSRGB<=0.03928?bSRGB/12.92:Math.pow((bSRGB+0.055)/1.055,2.4);
-
-return 0.2126*r+0.7152*g+0.0722*b;
-};
-
-
-
-
-
-
-
-WebInspector.Color.blendColors=function(fgRGBA,bgRGBA,out_blended)
-{
-var alpha=fgRGBA[3];
-
-out_blended[0]=(1-alpha)*bgRGBA[0]+alpha*fgRGBA[0];
-out_blended[1]=(1-alpha)*bgRGBA[1]+alpha*fgRGBA[1];
-out_blended[2]=(1-alpha)*bgRGBA[2]+alpha*fgRGBA[2];
-out_blended[3]=alpha+bgRGBA[3]*(1-alpha);
-};
-
-
-
-
-
-
-
-
-
-WebInspector.Color.calculateContrastRatio=function(fgRGBA,bgRGBA)
-{
-WebInspector.Color.blendColors(fgRGBA,bgRGBA,WebInspector.Color.calculateContrastRatio._blendedFg);
-
-var fgLuminance=WebInspector.Color.luminance(WebInspector.Color.calculateContrastRatio._blendedFg);
-var bgLuminance=WebInspector.Color.luminance(bgRGBA);
-var contrastRatio=(Math.max(fgLuminance,bgLuminance)+0.05)/(
-Math.min(fgLuminance,bgLuminance)+0.05);
-
-for(var i=0;i<WebInspector.Color.calculateContrastRatio._blendedFg.length;i++)
-WebInspector.Color.calculateContrastRatio._blendedFg[i]=0;
-
-return contrastRatio;
-};
-
-WebInspector.Color.calculateContrastRatio._blendedFg=[0,0,0,0];
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.Color.desiredLuminance=function(luminance,contrast,lighter)
-{
-function computeLuminance()
-{
-if(lighter)
-return(luminance+0.05)*contrast-0.05;else
-
-return(luminance+0.05)/contrast-0.05;
-}
-var desiredLuminance=computeLuminance();
-if(desiredLuminance<0||desiredLuminance>1){
-lighter=!lighter;
-desiredLuminance=computeLuminance();
-}
-return desiredLuminance;
-};
-
-
-WebInspector.Color.Nicknames={
-"aliceblue":[240,248,255],
-"antiquewhite":[250,235,215],
-"aqua":[0,255,255],
-"aquamarine":[127,255,212],
-"azure":[240,255,255],
-"beige":[245,245,220],
-"bisque":[255,228,196],
-"black":[0,0,0],
-"blanchedalmond":[255,235,205],
-"blue":[0,0,255],
-"blueviolet":[138,43,226],
-"brown":[165,42,42],
-"burlywood":[222,184,135],
-"cadetblue":[95,158,160],
-"chartreuse":[127,255,0],
-"chocolate":[210,105,30],
-"coral":[255,127,80],
-"cornflowerblue":[100,149,237],
-"cornsilk":[255,248,220],
-"crimson":[237,20,61],
-"cyan":[0,255,255],
-"darkblue":[0,0,139],
-"darkcyan":[0,139,139],
-"darkgoldenrod":[184,134,11],
-"darkgray":[169,169,169],
-"darkgrey":[169,169,169],
-"darkgreen":[0,100,0],
-"darkkhaki":[189,183,107],
-"darkmagenta":[139,0,139],
-"darkolivegreen":[85,107,47],
-"darkorange":[255,140,0],
-"darkorchid":[153,50,204],
-"darkred":[139,0,0],
-"darksalmon":[233,150,122],
-"darkseagreen":[143,188,143],
-"darkslateblue":[72,61,139],
-"darkslategray":[47,79,79],
-"darkslategrey":[47,79,79],
-"darkturquoise":[0,206,209],
-"darkviolet":[148,0,211],
-"deeppink":[255,20,147],
-"deepskyblue":[0,191,255],
-"dimgray":[105,105,105],
-"dimgrey":[105,105,105],
-"dodgerblue":[30,144,255],
-"firebrick":[178,34,34],
-"floralwhite":[255,250,240],
-"forestgreen":[34,139,34],
-"fuchsia":[255,0,255],
-"gainsboro":[220,220,220],
-"ghostwhite":[248,248,255],
-"gold":[255,215,0],
-"goldenrod":[218,165,32],
-"gray":[128,128,128],
-"grey":[128,128,128],
-"green":[0,128,0],
-"greenyellow":[173,255,47],
-"honeydew":[240,255,240],
-"hotpink":[255,105,180],
-"indianred":[205,92,92],
-"indigo":[75,0,130],
-"ivory":[255,255,240],
-"khaki":[240,230,140],
-"lavender":[230,230,250],
-"lavenderblush":[255,240,245],
-"lawngreen":[124,252,0],
-"lemonchiffon":[255,250,205],
-"lightblue":[173,216,230],
-"lightcoral":[240,128,128],
-"lightcyan":[224,255,255],
-"lightgoldenrodyellow":[250,250,210],
-"lightgreen":[144,238,144],
-"lightgray":[211,211,211],
-"lightgrey":[211,211,211],
-"lightpink":[255,182,193],
-"lightsalmon":[255,160,122],
-"lightseagreen":[32,178,170],
-"lightskyblue":[135,206,250],
-"lightslategray":[119,136,153],
-"lightslategrey":[119,136,153],
-"lightsteelblue":[176,196,222],
-"lightyellow":[255,255,224],
-"lime":[0,255,0],
-"limegreen":[50,205,50],
-"linen":[250,240,230],
-"magenta":[255,0,255],
-"maroon":[128,0,0],
-"mediumaquamarine":[102,205,170],
-"mediumblue":[0,0,205],
-"mediumorchid":[186,85,211],
-"mediumpurple":[147,112,219],
-"mediumseagreen":[60,179,113],
-"mediumslateblue":[123,104,238],
-"mediumspringgreen":[0,250,154],
-"mediumturquoise":[72,209,204],
-"mediumvioletred":[199,21,133],
-"midnightblue":[25,25,112],
-"mintcream":[245,255,250],
-"mistyrose":[255,228,225],
-"moccasin":[255,228,181],
-"navajowhite":[255,222,173],
-"navy":[0,0,128],
-"oldlace":[253,245,230],
-"olive":[128,128,0],
-"olivedrab":[107,142,35],
-"orange":[255,165,0],
-"orangered":[255,69,0],
-"orchid":[218,112,214],
-"palegoldenrod":[238,232,170],
-"palegreen":[152,251,152],
-"paleturquoise":[175,238,238],
-"palevioletred":[219,112,147],
-"papayawhip":[255,239,213],
-"peachpuff":[255,218,185],
-"peru":[205,133,63],
-"pink":[255,192,203],
-"plum":[221,160,221],
-"powderblue":[176,224,230],
-"purple":[128,0,128],
-"rebeccapurple":[102,51,153],
-"red":[255,0,0],
-"rosybrown":[188,143,143],
-"royalblue":[65,105,225],
-"saddlebrown":[139,69,19],
-"salmon":[250,128,114],
-"sandybrown":[244,164,96],
-"seagreen":[46,139,87],
-"seashell":[255,245,238],
-"sienna":[160,82,45],
-"silver":[192,192,192],
-"skyblue":[135,206,235],
-"slateblue":[106,90,205],
-"slategray":[112,128,144],
-"slategrey":[112,128,144],
-"snow":[255,250,250],
-"springgreen":[0,255,127],
-"steelblue":[70,130,180],
-"tan":[210,180,140],
-"teal":[0,128,128],
-"thistle":[216,191,216],
-"tomato":[255,99,71],
-"turquoise":[64,224,208],
-"violet":[238,130,238],
-"wheat":[245,222,179],
-"white":[255,255,255],
-"whitesmoke":[245,245,245],
-"yellow":[255,255,0],
-"yellowgreen":[154,205,50],
-"transparent":[0,0,0,0]};
-
-
-WebInspector.Color.PageHighlight={
-Content:WebInspector.Color.fromRGBA([111,168,220,.66]),
-ContentLight:WebInspector.Color.fromRGBA([111,168,220,.5]),
-ContentOutline:WebInspector.Color.fromRGBA([9,83,148]),
-Padding:WebInspector.Color.fromRGBA([147,196,125,.55]),
-PaddingLight:WebInspector.Color.fromRGBA([147,196,125,.4]),
-Border:WebInspector.Color.fromRGBA([255,229,153,.66]),
-BorderLight:WebInspector.Color.fromRGBA([255,229,153,.5]),
-Margin:WebInspector.Color.fromRGBA([246,178,107,.66]),
-MarginLight:WebInspector.Color.fromRGBA([246,178,107,.5]),
-EventTarget:WebInspector.Color.fromRGBA([255,196,196,.66]),
-Shape:WebInspector.Color.fromRGBA([96,82,177,0.8]),
-ShapeMargin:WebInspector.Color.fromRGBA([96,82,127,.6])};
-
-
-
-
-
-
-WebInspector.Color.detectColorFormat=function(color)
-{
-const cf=WebInspector.Color.Format;
-var format;
-var formatSetting=WebInspector.moduleSetting("colorFormat").get();
-if(formatSetting===cf.Original)
-format=cf.Original;else
-if(formatSetting===cf.RGB)
-format=color.hasAlpha()?cf.RGBA:cf.RGB;else
-if(formatSetting===cf.HSL)
-format=color.hasAlpha()?cf.HSLA:cf.HSL;else
-if(!color.hasAlpha())
-format=color.canBeShortHex()?cf.ShortHEX:cf.HEX;else
-
-format=cf.RGBA;
-
-return format;
-};
-
-},{}],95:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.Object=function(){
-};
-
-WebInspector.Object.prototype={
-
-
-
-
-
-
-
-addEventListener:function(eventType,listener,thisObject)
-{
-if(!listener)
-console.assert(false);
-
-if(!this._listeners)
-this._listeners=new Map();
-if(!this._listeners.has(eventType))
-this._listeners.set(eventType,[]);
-this._listeners.get(eventType).push({thisObject:thisObject,listener:listener});
-return new WebInspector.EventTarget.EventDescriptor(this,eventType,thisObject,listener);
-},
-
-
-
-
-
-
-
-removeEventListener:function(eventType,listener,thisObject)
-{
-console.assert(listener);
-
-if(!this._listeners||!this._listeners.has(eventType))
-return;
-var listeners=this._listeners.get(eventType);
-for(var i=0;i<listeners.length;++i){
-if(listeners[i].listener===listener&&listeners[i].thisObject===thisObject)
-listeners.splice(i--,1);
-}
-
-if(!listeners.length)
-this._listeners.delete(eventType);
-},
-
-
-
-
-removeAllListeners:function()
-{
-delete this._listeners;
-},
-
-
-
-
-
-
-hasEventListeners:function(eventType)
-{
-return this._listeners&&this._listeners.has(eventType);
-},
-
-
-
-
-
-
-
-dispatchEventToListeners:function(eventType,eventData)
-{
-if(!this._listeners||!this._listeners.has(eventType))
-return false;
-
-var event=new WebInspector.Event(this,eventType,eventData);
-var listeners=this._listeners.get(eventType).slice(0);
-for(var i=0;i<listeners.length;++i){
-listeners[i].listener.call(listeners[i].thisObject,event);
-if(event._stoppedPropagation)
-break;
-}
-
-return event.defaultPrevented;
-}};
-
-
-
-
-
-
-
-
-WebInspector.Event=function(target,type,data)
-{
-this.target=target;
-this.type=type;
-this.data=data;
-this.defaultPrevented=false;
-this._stoppedPropagation=false;
-};
-
-WebInspector.Event.prototype={
-stopPropagation:function()
-{
-this._stoppedPropagation=true;
-},
-
-preventDefault:function()
-{
-this.defaultPrevented=true;
-},
-
-
-
-
-consume:function(preventDefault)
-{
-this.stopPropagation();
-if(preventDefault)
-this.preventDefault();
-}};
-
-
-
-
-
-WebInspector.EventTarget=function()
-{
-};
-
-
-
-
-WebInspector.EventTarget.removeEventListeners=function(eventList)
-{
-for(var i=0;i<eventList.length;++i){
-var eventInfo=eventList[i];
-eventInfo.eventTarget.removeEventListener(eventInfo.eventType,eventInfo.method,eventInfo.receiver);
-}
-
-eventList.splice(0,eventList.length);
-};
-
-WebInspector.EventTarget.prototype={
-
-
-
-
-
-
-addEventListener:function(eventType,listener,thisObject){},
-
-
-
-
-
-
-removeEventListener:function(eventType,listener,thisObject){},
-
-removeAllListeners:function(){},
-
-
-
-
-
-hasEventListeners:function(eventType){},
-
-
-
-
-
-
-dispatchEventToListeners:function(eventType,eventData){}};
-
-
-
-
-
-
-
-
-
-WebInspector.EventTarget.EventDescriptor=function(eventTarget,eventType,receiver,method)
-{
-this.eventTarget=eventTarget;
-this.eventType=eventType;
-this.receiver=receiver;
-this.method=method;
-};
-
-},{}],96:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.ParsedURL=function(url)
-{
-this.isValid=false;
-this.url=url;
-this.scheme="";
-this.host="";
-this.port="";
-this.path="";
-this.queryParams="";
-this.fragment="";
-this.folderPathComponents="";
-this.lastPathComponent="";
-
-
-
-
-
-
-
-var match=url.match(/^([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\s\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
-if(match){
-this.isValid=true;
-this.scheme=match[1].toLowerCase();
-this.host=match[2];
-this.port=match[3];
-this.path=match[4]||"/";
-this.fragment=match[5];
-}else{
-if(this.url.startsWith("data:")){
-this.scheme="data";
-return;
-}
-if(this.url==="about:blank"){
-this.scheme="about";
-return;
-}
-this.path=this.url;
-}
-
-
-var path=this.path;
-var indexOfQuery=path.indexOf("?");
-if(indexOfQuery!==-1){
-this.queryParams=path.substring(indexOfQuery+1);
-path=path.substring(0,indexOfQuery);
-}
-
-
-var lastSlashIndex=path.lastIndexOf("/");
-if(lastSlashIndex!==-1){
-this.folderPathComponents=path.substring(0,lastSlashIndex);
-this.lastPathComponent=path.substring(lastSlashIndex+1);
-}else
-this.lastPathComponent=path;
-};
-
-
-
-
-
-WebInspector.ParsedURL.splitURLIntoPathComponents=function(url)
-{
-if(url.startsWith("/"))
-url="file://"+url;
-var parsedURL=new WebInspector.ParsedURL(url);
-var origin;
-var folderPath;
-var name;
-if(parsedURL.isValid){
-origin=parsedURL.scheme+"://"+parsedURL.host;
-if(parsedURL.port)
-origin+=":"+parsedURL.port;
-folderPath=parsedURL.folderPathComponents;
-name=parsedURL.lastPathComponent;
-if(parsedURL.queryParams)
-name+="?"+parsedURL.queryParams;
-}else{
-origin="";
-folderPath="";
-name=url;
-}
-var result=[origin];
-var splittedPath=folderPath.split("/");
-for(var i=1;i<splittedPath.length;++i){
-if(!splittedPath[i])
-continue;
-result.push(splittedPath[i]);
-}
-result.push(name);
-return result;
-};
-
-
-
-
-
-WebInspector.ParsedURL.extractOrigin=function(url)
-{
-var parsedURL=new WebInspector.ParsedURL(url);
-if(!parsedURL.isValid)
-return"";
-
-var origin=parsedURL.scheme+"://"+parsedURL.host;
-if(parsedURL.port)
-origin+=":"+parsedURL.port;
-return origin;
-};
-
-
-
-
-
-WebInspector.ParsedURL.extractExtension=function(url)
-{
-var lastIndexOfDot=url.lastIndexOf(".");
-var extension=lastIndexOfDot!==-1?url.substr(lastIndexOfDot+1):"";
-var indexOfQuestionMark=extension.indexOf("?");
-if(indexOfQuestionMark!==-1)
-extension=extension.substr(0,indexOfQuestionMark);
-return extension;
-};
-
-
-
-
-
-WebInspector.ParsedURL.extractName=function(url)
-{
-var index=url.lastIndexOf("/");
-return index!==-1?url.substr(index+1):url;
-};
-
-
-
-
-
-
-WebInspector.ParsedURL.completeURL=function(baseURL,href)
-{
-if(href){
-
-var trimmedHref=href.trim();
-if(trimmedHref.startsWith("data:")||trimmedHref.startsWith("blob:")||trimmedHref.startsWith("javascript:"))
-return href;
-
-
-var parsedHref=trimmedHref.asParsedURL();
-if(parsedHref&&parsedHref.scheme)
-return trimmedHref;
-}else{
-return baseURL;
-}
-
-var parsedURL=baseURL.asParsedURL();
-if(parsedURL){
-if(parsedURL.isDataURL())
-return href;
-var path=href;
-
-var query=path.indexOf("?");
-var postfix="";
-if(query!==-1){
-postfix=path.substring(query);
-path=path.substring(0,query);
-}else{
-var fragment=path.indexOf("#");
-if(fragment!==-1){
-postfix=path.substring(fragment);
-path=path.substring(0,fragment);
-}
-}
-
-if(!path){
-var basePath=parsedURL.path;
-if(postfix.charAt(0)==="?"){
-
-
-var baseQuery=parsedURL.path.indexOf("?");
-if(baseQuery!==-1)
-basePath=basePath.substring(0,baseQuery);
-}
-return parsedURL.scheme+"://"+parsedURL.host+(parsedURL.port?":"+parsedURL.port:"")+basePath+postfix;
-}else if(path.charAt(0)!=="/"){
-var prefix=parsedURL.path;
-var prefixQuery=prefix.indexOf("?");
-if(prefixQuery!==-1)
-prefix=prefix.substring(0,prefixQuery);
-prefix=prefix.substring(0,prefix.lastIndexOf("/"))+"/";
-path=prefix+path;
-}else if(path.length>1&&path.charAt(1)==="/"){
-
-return parsedURL.scheme+":"+path+postfix;
-}
-return parsedURL.scheme+"://"+parsedURL.host+(parsedURL.port?":"+parsedURL.port:"")+Runtime.normalizePath(path)+postfix;
-}
-return null;
-};
-
-WebInspector.ParsedURL.prototype={
-get displayName()
-{
-if(this._displayName)
-return this._displayName;
-
-if(this.isDataURL())
-return this.dataURLDisplayName();
-if(this.isAboutBlank())
-return this.url;
-
-this._displayName=this.lastPathComponent;
-if(!this._displayName)
-this._displayName=(this.host||"")+"/";
-if(this._displayName==="/")
-this._displayName=this.url;
-return this._displayName;
-},
-
-
-
-
-dataURLDisplayName:function()
-{
-if(this._dataURLDisplayName)
-return this._dataURLDisplayName;
-if(!this.isDataURL())
-return"";
-this._dataURLDisplayName=this.url.trimEnd(20);
-return this._dataURLDisplayName;
-},
-
-
-
-
-isAboutBlank:function()
-{
-return this.url==="about:blank";
-},
-
-
-
-
-isDataURL:function()
-{
-return this.scheme==="data";
-},
-
-
-
-
-lastPathComponentWithFragment:function()
-{
-return this.lastPathComponent+(this.fragment?"#"+this.fragment:"");
-},
-
-
-
-
-domain:function()
-{
-if(this.isDataURL())
-return"data:";
-return this.host+(this.port?":"+this.port:"");
-},
-
-
-
-
-securityOrigin:function()
-{
-if(this.isDataURL())
-return"data:";
-return this.scheme+"://"+this.domain();
-},
-
-
-
-
-urlWithoutScheme:function()
-{
-if(this.scheme&&this.url.startsWith(this.scheme+"://"))
-return this.url.substring(this.scheme.length+3);
-return this.url;
-}};
-
-
-
-
-
-
-WebInspector.ParsedURL.splitLineAndColumn=function(string)
-{
-var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;
-var lineColumnMatch=lineColumnRegEx.exec(string);
-var lineNumber;
-var columnNumber;
-console.assert(lineColumnMatch);
-
-if(typeof lineColumnMatch[1]==="string"){
-lineNumber=parseInt(lineColumnMatch[1],10);
-
-lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;
-}
-if(typeof lineColumnMatch[2]==="string"){
-columnNumber=parseInt(lineColumnMatch[2],10);
-columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;
-}
-
-return{url:string.substring(0,string.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};
-};
-
-
-
-
-
-WebInspector.ParsedURL.isRelativeURL=function(url)
-{
-return!/^[A-Za-z][A-Za-z0-9+.-]*:/.test(url);
-};
-
-
-
-
-String.prototype.asParsedURL=function()
-{
-var parsedURL=new WebInspector.ParsedURL(this.toString());
-if(parsedURL.isValid)
-return parsedURL;
-return null;
-};
-
-},{}],97:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.ResourceType=function(name,title,category,isTextType)
-{
-this._name=name;
-this._title=title;
-this._category=category;
-this._isTextType=isTextType;
-};
-
-WebInspector.ResourceType.prototype={
-
-
-
-name:function()
-{
-return this._name;
-},
-
-
-
-
-title:function()
-{
-return this._title;
-},
-
-
-
-
-category:function()
-{
-return this._category;
-},
-
-
-
-
-isTextType:function()
-{
-return this._isTextType;
-},
-
-
-
-
-isScript:function()
-{
-return this._name==="script"||this._name==="sm-script";
-},
-
-
-
-
-hasScripts:function()
-{
-return this.isScript()||this.isDocument();
-},
-
-
-
-
-isStyleSheet:function()
-{
-return this._name==="stylesheet"||this._name==="sm-stylesheet";
-},
-
-
-
-
-isDocument:function()
-{
-return this._name==="document";
-},
-
-
-
-
-isDocumentOrScriptOrStyleSheet:function()
-{
-return this.isDocument()||this.isScript()||this.isStyleSheet();
-},
-
-
-
-
-isFromSourceMap:function()
-{
-return this._name.startsWith("sm-");
-},
-
-
-
-
-
-toString:function()
-{
-return this._name;
-},
-
-
-
-
-canonicalMimeType:function()
-{
-if(this.isDocument())
-return"text/html";
-if(this.isScript())
-return"text/javascript";
-if(this.isStyleSheet())
-return"text/css";
-return"";
-}};
-
-
-
-
-
-
-
-WebInspector.ResourceCategory=function(title,shortTitle)
-{
-this.title=title;
-this.shortTitle=shortTitle;
-};
-
-WebInspector.resourceCategories={
-XHR:new WebInspector.ResourceCategory("XHR and Fetch","XHR"),
-Script:new WebInspector.ResourceCategory("Scripts","JS"),
-Stylesheet:new WebInspector.ResourceCategory("Stylesheets","CSS"),
-Image:new WebInspector.ResourceCategory("Images","Img"),
-Media:new WebInspector.ResourceCategory("Media","Media"),
-Font:new WebInspector.ResourceCategory("Fonts","Font"),
-Document:new WebInspector.ResourceCategory("Documents","Doc"),
-WebSocket:new WebInspector.ResourceCategory("WebSockets","WS"),
-Manifest:new WebInspector.ResourceCategory("Manifest","Manifest"),
-Other:new WebInspector.ResourceCategory("Other","Other")};
-
-
-
-
-
-
-WebInspector.resourceTypes={
-XHR:new WebInspector.ResourceType("xhr","XHR",WebInspector.resourceCategories.XHR,true),
-Fetch:new WebInspector.ResourceType("fetch","Fetch",WebInspector.resourceCategories.XHR,true),
-EventSource:new WebInspector.ResourceType("eventsource","EventSource",WebInspector.resourceCategories.XHR,true),
-Script:new WebInspector.ResourceType("script","Script",WebInspector.resourceCategories.Script,true),
-Stylesheet:new WebInspector.ResourceType("stylesheet","Stylesheet",WebInspector.resourceCategories.Stylesheet,true),
-Image:new WebInspector.ResourceType("image","Image",WebInspector.resourceCategories.Image,false),
-Media:new WebInspector.ResourceType("media","Media",WebInspector.resourceCategories.Media,false),
-Font:new WebInspector.ResourceType("font","Font",WebInspector.resourceCategories.Font,false),
-Document:new WebInspector.ResourceType("document","Document",WebInspector.resourceCategories.Document,true),
-TextTrack:new WebInspector.ResourceType("texttrack","TextTrack",WebInspector.resourceCategories.Other,true),
-WebSocket:new WebInspector.ResourceType("websocket","WebSocket",WebInspector.resourceCategories.WebSocket,false),
-Other:new WebInspector.ResourceType("other","Other",WebInspector.resourceCategories.Other,false),
-SourceMapScript:new WebInspector.ResourceType("sm-script","Script",WebInspector.resourceCategories.Script,false),
-SourceMapStyleSheet:new WebInspector.ResourceType("sm-stylesheet","Stylesheet",WebInspector.resourceCategories.Stylesheet,false),
-Manifest:new WebInspector.ResourceType("manifest","Manifest",WebInspector.resourceCategories.Manifest,true)};
-
-
-
-
-
-
-WebInspector.ResourceType.mimeFromURL=function(url)
-{
-var name=WebInspector.ParsedURL.extractName(url);
-if(WebInspector.ResourceType._mimeTypeByName.has(name)){
-return WebInspector.ResourceType._mimeTypeByName.get(name);
-}
-var ext=WebInspector.ParsedURL.extractExtension(url).toLowerCase();
-return WebInspector.ResourceType._mimeTypeByExtension.get(ext);
-};
-
-WebInspector.ResourceType._mimeTypeByName=new Map([
-
-["Cakefile","text/x-coffeescript"]]);
-
-
-WebInspector.ResourceType._mimeTypeByExtension=new Map([
-
-["js","text/javascript"],
-["css","text/css"],
-["html","text/html"],
-["htm","text/html"],
-["xml","application/xml"],
-["xsl","application/xml"],
-
-
-["asp","application/x-aspx"],
-["aspx","application/x-aspx"],
-["jsp","application/x-jsp"],
-
-
-["c","text/x-c++src"],
-["cc","text/x-c++src"],
-["cpp","text/x-c++src"],
-["h","text/x-c++src"],
-["m","text/x-c++src"],
-["mm","text/x-c++src"],
-
-
-["coffee","text/x-coffeescript"],
-
-
-["dart","text/javascript"],
-
-
-["ts","text/typescript"],
-["tsx","text/typescript"],
-
-
-["json","application/json"],
-["gyp","application/json"],
-["gypi","application/json"],
-
-
-["cs","text/x-csharp"],
-
-
-["java","text/x-java"],
-
-
-["less","text/x-less"],
-
-
-["php","text/x-php"],
-["phtml","application/x-httpd-php"],
-
-
-["py","text/x-python"],
-
-
-["sh","text/x-sh"],
-
-
-["scss","text/x-scss"],
-
-
-["vtt","text/vtt"],
-
-
-["ls","text/x-livescript"],
-
-
-["cljs","text/x-clojure"],
-["cljc","text/x-clojure"],
-["cljx","text/x-clojure"],
-
-
-["styl","text/x-styl"],
-
-
-["jsx","text/jsx"],
-
-
-["jpeg","image/jpeg"],
-["jpg","image/jpeg"],
-["svg","image/svg"],
-["gif","image/gif"],
-["webp","image/webp"],
-["png","image/png"],
-["ico","image/ico"],
-["tiff","image/tiff"],
-["tif","image/tif"],
-["bmp","image/bmp"],
-
-
-["ttf","font/opentype"],
-["otf","font/opentype"],
-["ttc","font/opentype"],
-["woff","application/font-woff"]]);
-
-
-},{}],98:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-WebInspector.Segment=function(begin,end,data)
-{
-if(begin>end)
-console.assert(false,"Invalid segment");
-this.begin=begin;
-this.end=end;
-this.data=data;
-};
-
-WebInspector.Segment.prototype={
-
-
-
-
-intersects:function(that)
-{
-return this.begin<that.end&&that.begin<this.end;
-}};
-
-
-
-
-
-
-WebInspector.SegmentedRange=function(mergeCallback)
-{
-
-this._segments=[];
-this._mergeCallback=mergeCallback;
-};
-
-WebInspector.SegmentedRange.prototype={
-
-
-
-append:function(newSegment)
-{
-
-var startIndex=this._segments.lowerBound(newSegment,(a,b)=>a.begin-b.begin);
-var endIndex=startIndex;
-var merged=null;
-if(startIndex>0){
-
-var precedingSegment=this._segments[startIndex-1];
-merged=this._tryMerge(precedingSegment,newSegment);
-if(merged){
---startIndex;
-newSegment=merged;
-}else if(this._segments[startIndex-1].end>=newSegment.begin){
-
-
-if(newSegment.end<precedingSegment.end)
-this._segments.splice(startIndex,0,new WebInspector.Segment(newSegment.end,precedingSegment.end,precedingSegment.data));
-precedingSegment.end=newSegment.begin;
-}
-}
-
-while(endIndex<this._segments.length&&this._segments[endIndex].end<=newSegment.end)
-++endIndex;
-
-if(endIndex<this._segments.length){
-merged=this._tryMerge(newSegment,this._segments[endIndex]);
-if(merged){
-endIndex++;
-newSegment=merged;
-}else if(newSegment.intersects(this._segments[endIndex]))
-this._segments[endIndex].begin=newSegment.end;
-}
-this._segments.splice(startIndex,endIndex-startIndex,newSegment);
-},
-
-
-
-
-appendRange:function(that)
-{
-that.segments().forEach(segment=>this.append(segment));
-},
-
-
-
-
-segments:function()
-{
-return this._segments;
-},
-
-
-
-
-
-
-_tryMerge:function(first,second)
-{
-var merged=this._mergeCallback&&this._mergeCallback(first,second);
-if(!merged)
-return null;
-merged.begin=first.begin;
-merged.end=Math.max(first.end,second.end);
-return merged;
-}};
-
-
-},{}],99:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TextRange=function(startLine,startColumn,endLine,endColumn)
-{
-this.startLine=startLine;
-this.startColumn=startColumn;
-this.endLine=endLine;
-this.endColumn=endColumn;
-};
-
-
-
-
-
-
-WebInspector.TextRange.createFromLocation=function(line,column)
-{
-return new WebInspector.TextRange(line,column,line,column);
-};
-
-
-
-
-
-WebInspector.TextRange.fromObject=function(serializedTextRange)
-{
-return new WebInspector.TextRange(serializedTextRange.startLine,serializedTextRange.startColumn,serializedTextRange.endLine,serializedTextRange.endColumn);
-};
-
-
-
-
-
-
-WebInspector.TextRange.comparator=function(range1,range2)
-{
-return range1.compareTo(range2);
-};
-
-WebInspector.TextRange.prototype={
-
-
-
-isEmpty:function()
-{
-return this.startLine===this.endLine&&this.startColumn===this.endColumn;
-},
-
-
-
-
-
-immediatelyPrecedes:function(range)
-{
-if(!range)
-return false;
-return this.endLine===range.startLine&&this.endColumn===range.startColumn;
-},
-
-
-
-
-
-immediatelyFollows:function(range)
-{
-if(!range)
-return false;
-return range.immediatelyPrecedes(this);
-},
-
-
-
-
-
-follows:function(range)
-{
-return range.endLine===this.startLine&&range.endColumn<=this.startColumn||
-range.endLine<this.startLine;
-},
-
-
-
-
-get linesCount()
-{
-return this.endLine-this.startLine;
-},
-
-
-
-
-collapseToEnd:function()
-{
-return new WebInspector.TextRange(this.endLine,this.endColumn,this.endLine,this.endColumn);
-},
-
-
-
-
-collapseToStart:function()
-{
-return new WebInspector.TextRange(this.startLine,this.startColumn,this.startLine,this.startColumn);
-},
-
-
-
-
-normalize:function()
-{
-if(this.startLine>this.endLine||this.startLine===this.endLine&&this.startColumn>this.endColumn)
-return new WebInspector.TextRange(this.endLine,this.endColumn,this.startLine,this.startColumn);else
-
-return this.clone();
-},
-
-
-
-
-clone:function()
-{
-return new WebInspector.TextRange(this.startLine,this.startColumn,this.endLine,this.endColumn);
-},
-
-
-
-
-serializeToObject:function()
-{
-var serializedTextRange={};
-serializedTextRange.startLine=this.startLine;
-serializedTextRange.startColumn=this.startColumn;
-serializedTextRange.endLine=this.endLine;
-serializedTextRange.endColumn=this.endColumn;
-return serializedTextRange;
-},
-
-
-
-
-
-compareTo:function(other)
-{
-if(this.startLine>other.startLine)
-return 1;
-if(this.startLine<other.startLine)
-return-1;
-if(this.startColumn>other.startColumn)
-return 1;
-if(this.startColumn<other.startColumn)
-return-1;
-return 0;
-},
-
-
-
-
-
-
-compareToPosition:function(lineNumber,columnNumber)
-{
-if(lineNumber<this.startLine||lineNumber===this.startLine&&columnNumber<this.startColumn)
-return-1;
-if(lineNumber>this.endLine||lineNumber===this.endLine&&columnNumber>this.endColumn)
-return 1;
-return 0;
-},
-
-
-
-
-
-equal:function(other)
-{
-return this.startLine===other.startLine&&this.endLine===other.endLine&&
-this.startColumn===other.startColumn&&this.endColumn===other.endColumn;
-},
-
-
-
-
-
-
-relativeTo:function(line,column)
-{
-var relative=this.clone();
-
-if(this.startLine===line)
-relative.startColumn-=column;
-if(this.endLine===line)
-relative.endColumn-=column;
-
-relative.startLine-=line;
-relative.endLine-=line;
-return relative;
-},
-
-
-
-
-
-
-rebaseAfterTextEdit:function(originalRange,editedRange)
-{
-console.assert(originalRange.startLine===editedRange.startLine);
-console.assert(originalRange.startColumn===editedRange.startColumn);
-var rebase=this.clone();
-if(!this.follows(originalRange))
-return rebase;
-var lineDelta=editedRange.endLine-originalRange.endLine;
-var columnDelta=editedRange.endColumn-originalRange.endColumn;
-rebase.startLine+=lineDelta;
-rebase.endLine+=lineDelta;
-if(rebase.startLine===editedRange.endLine)
-rebase.startColumn+=columnDelta;
-if(rebase.endLine===editedRange.endLine)
-rebase.endColumn+=columnDelta;
-return rebase;
-},
-
-
-
-
-
-toString:function()
-{
-return JSON.stringify(this);
-},
-
-
-
-
-
-
-containsLocation:function(lineNumber,columnNumber)
-{
-if(this.startLine===this.endLine)
-return this.startLine===lineNumber&&this.startColumn<=columnNumber&&columnNumber<=this.endColumn;
-if(this.startLine===lineNumber)
-return this.startColumn<=columnNumber;
-if(this.endLine===lineNumber)
-return columnNumber<=this.endColumn;
-return this.startLine<lineNumber&&lineNumber<this.endLine;
-}};
-
-
-
-
-
-
-
-WebInspector.TextRange.fromEdit=function(oldRange,newText)
-{
-var endLine=oldRange.startLine;
-var endColumn=oldRange.startColumn+newText.length;
-var lineEndings=newText.computeLineEndings();
-if(lineEndings.length>1){
-endLine=oldRange.startLine+lineEndings.length-1;
-var len=lineEndings.length;
-endColumn=lineEndings[len-1]-lineEndings[len-2]-1;
-}
-return new WebInspector.TextRange(
-oldRange.startLine,
-oldRange.startColumn,
-endLine,
-endColumn);
-};
-
-
-
-
-
-
-WebInspector.SourceRange=function(offset,length)
-{
-this.offset=offset;
-this.length=length;
-};
-
-
-
-
-
-
-
-WebInspector.SourceEdit=function(sourceURL,oldRange,newText)
-{
-this.sourceURL=sourceURL;
-this.oldRange=oldRange;
-this.newText=newText;
-};
-
-WebInspector.SourceEdit.prototype={
-
-
-
-newRange:function()
-{
-return WebInspector.TextRange.fromEdit(this.oldRange,this.newText);
-}};
-
-
-
-
-
-
-
-WebInspector.SourceEdit.comparator=function(edit1,edit2)
-{
-return WebInspector.TextRange.comparator(edit1.oldRange,edit2.oldRange);
-};
-
-},{}],100:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TextUtils={
-
-
-
-
-isStopChar:function(char)
-{
-return char>" "&&char<"0"||
-char>"9"&&char<"A"||
-char>"Z"&&char<"_"||
-char>"_"&&char<"a"||
-char>"z"&&char<="~";
-},
-
-
-
-
-
-isWordChar:function(char)
-{
-return!WebInspector.TextUtils.isStopChar(char)&&!WebInspector.TextUtils.isSpaceChar(char);
-},
-
-
-
-
-
-isSpaceChar:function(char)
-{
-return WebInspector.TextUtils._SpaceCharRegex.test(char);
-},
-
-
-
-
-
-isWord:function(word)
-{
-for(var i=0;i<word.length;++i){
-if(!WebInspector.TextUtils.isWordChar(word.charAt(i)))
-return false;
-}
-return true;
-},
-
-
-
-
-
-isOpeningBraceChar:function(char)
-{
-return char==="("||char==="{";
-},
-
-
-
-
-
-isClosingBraceChar:function(char)
-{
-return char===")"||char==="}";
-},
-
-
-
-
-
-isBraceChar:function(char)
-{
-return WebInspector.TextUtils.isOpeningBraceChar(char)||WebInspector.TextUtils.isClosingBraceChar(char);
-},
-
-
-
-
-
-
-textToWords:function(text,isWordChar,wordCallback)
-{
-var startWord=-1;
-for(var i=0;i<text.length;++i){
-if(!isWordChar(text.charAt(i))){
-if(startWord!==-1)
-wordCallback(text.substring(startWord,i));
-startWord=-1;
-}else if(startWord===-1)
-startWord=i;
-}
-if(startWord!==-1)
-wordCallback(text.substring(startWord));
-},
-
-
-
-
-
-lineIndent:function(line)
-{
-var indentation=0;
-while(indentation<line.length&&WebInspector.TextUtils.isSpaceChar(line.charAt(indentation)))
-++indentation;
-return line.substr(0,indentation);
-},
-
-
-
-
-
-isUpperCase:function(text)
-{
-return text===text.toUpperCase();
-},
-
-
-
-
-
-isLowerCase:function(text)
-{
-return text===text.toLowerCase();
-},
-
-
-
-
-
-
-splitStringByRegexes(text,regexes)
-{
-var matches=[];
-var globalRegexes=[];
-for(var i=0;i<regexes.length;i++){
-var regex=regexes[i];
-if(!regex.global)
-globalRegexes.push(new RegExp(regex.source,regex.flags?regex.flags+"g":"g"));else
-
-globalRegexes.push(regex);
-}
-doSplit(text,0,0);
-return matches;
-
-
-
-
-
-
-function doSplit(text,regexIndex,startIndex)
-{
-if(regexIndex>=globalRegexes.length){
-
-matches.push({
-value:text,
-position:startIndex,
-regexIndex:-1});
-
-return;
-}
-var regex=globalRegexes[regexIndex];
-var currentIndex=0;
-var result;
-regex.lastIndex=0;
-while((result=regex.exec(text))!==null){
-var stringBeforeMatch=text.substring(currentIndex,result.index);
-if(stringBeforeMatch)
-doSplit(stringBeforeMatch,regexIndex+1,startIndex+currentIndex);
-var match=result[0];
-matches.push({
-value:match,
-position:startIndex+result.index,
-regexIndex:regexIndex});
-
-currentIndex=result.index+match.length;
-}
-var stringAfterMatches=text.substring(currentIndex);
-if(stringAfterMatches)
-doSplit(stringAfterMatches,regexIndex+1,startIndex+currentIndex);
-}
-}};
-
-
-WebInspector.TextUtils._SpaceCharRegex=/\s/;
-
-
-
-
-WebInspector.TextUtils.Indent={
-TwoSpaces:"  ",
-FourSpaces:"    ",
-EightSpaces:"        ",
-TabCharacter:"\t"};
-
-
-
-
-
-
-
-WebInspector.TextUtils.BalancedJSONTokenizer=function(callback,findMultiple)
-{
-this._callback=callback;
-this._index=0;
-this._balance=0;
-this._buffer="";
-this._findMultiple=findMultiple||false;
-this._closingDoubleQuoteRegex=/[^\\](?:\\\\)*"/g;
-};
-
-WebInspector.TextUtils.BalancedJSONTokenizer.prototype={
-
-
-
-
-write:function(chunk)
-{
-this._buffer+=chunk;
-var lastIndex=this._buffer.length;
-var buffer=this._buffer;
-for(var index=this._index;index<lastIndex;++index){
-var character=buffer[index];
-if(character==="\""){
-this._closingDoubleQuoteRegex.lastIndex=index;
-if(!this._closingDoubleQuoteRegex.test(buffer))
-break;
-index=this._closingDoubleQuoteRegex.lastIndex-1;
-}else if(character==="{"){
-++this._balance;
-}else if(character==="}"){
---this._balance;
-if(this._balance<0){
-this._reportBalanced();
-return false;
-}
-if(!this._balance){
-this._lastBalancedIndex=index+1;
-if(!this._findMultiple)
-break;
-}
-}else if(character==="]"&&!this._balance){
-this._reportBalanced();
-return false;
-}
-}
-this._index=index;
-this._reportBalanced();
-return true;
-},
-
-_reportBalanced:function()
-{
-if(!this._lastBalancedIndex)
-return;
-this._callback(this._buffer.slice(0,this._lastBalancedIndex));
-this._buffer=this._buffer.slice(this._lastBalancedIndex);
-this._index-=this._lastBalancedIndex;
-this._lastBalancedIndex=0;
-},
-
-
-
-
-remainder:function()
-{
-return this._buffer;
-}};
-
-
-
-
-
-WebInspector.TokenizerFactory=function(){};
-
-WebInspector.TokenizerFactory.prototype={
-
-
-
-
-createTokenizer:function(mimeType){}};
-
-
-},{}],101:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.UIString=function(string,vararg)
-{
-return String.vsprintf(WebInspector.localize(string),Array.prototype.slice.call(arguments,1));
-};
-
-
-
-
-
-
-WebInspector.UIString.capitalize=function(string,vararg)
-{
-if(WebInspector._useLowerCaseMenuTitles===undefined)
-throw"WebInspector.setLocalizationPlatform() has not been called";
-
-var localized=WebInspector.localize(string);
-var capitalized;
-if(WebInspector._useLowerCaseMenuTitles)
-capitalized=localized.replace(/\^(.)/g,"$1");else
-
-capitalized=localized.replace(/\^(.)/g,function(str,char){return char.toUpperCase();});
-return String.vsprintf(capitalized,Array.prototype.slice.call(arguments,1));
-};
-
-
-
-
-WebInspector.setLocalizationPlatform=function(platform)
-{
-WebInspector._useLowerCaseMenuTitles=platform==="windows";
-};
-
-
-
-
-
-WebInspector.localize=function(string)
-{
-return string;
-};
-
-
-
-
-
-WebInspector.UIStringFormat=function(format)
-{
-
-this._localizedFormat=WebInspector.localize(format);
-
-this._tokenizedFormat=String.tokenizeFormatString(this._localizedFormat,String.standardFormatters);
-};
-
-
-
-
-
-
-WebInspector.UIStringFormat._append=function(a,b)
-{
-return a+b;
-};
-
-WebInspector.UIStringFormat.prototype={
-
-
-
-
-format:function(vararg)
-{
-return String.format(this._localizedFormat,arguments,
-String.standardFormatters,"",WebInspector.UIStringFormat._append,this._tokenizedFormat).formattedResult;
-}};
-
-
-},{}],102:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.FilmStripModel=function(tracingModel,zeroTime)
-{
-this.reset(tracingModel,zeroTime);
-};
-
-WebInspector.FilmStripModel._category="disabled-by-default-devtools.screenshot";
-
-WebInspector.FilmStripModel.TraceEvents={
-CaptureFrame:"CaptureFrame",
-Screenshot:"Screenshot"};
-
-
-WebInspector.FilmStripModel.prototype={
-
-
-
-
-reset:function(tracingModel,zeroTime)
-{
-this._zeroTime=zeroTime||tracingModel.minimumRecordTime();
-this._spanTime=tracingModel.maximumRecordTime()-this._zeroTime;
-
-
-this._frames=[];
-var browserMain=WebInspector.TracingModel.browserMainThread(tracingModel);
-if(!browserMain)
-return;
-
-var events=browserMain.events();
-for(var i=0;i<events.length;++i){
-var event=events[i];
-if(event.startTime<this._zeroTime)
-continue;
-if(!event.hasCategory(WebInspector.FilmStripModel._category))
-continue;
-if(event.name===WebInspector.FilmStripModel.TraceEvents.CaptureFrame){
-var data=event.args["data"];
-if(data)
-this._frames.push(WebInspector.FilmStripModel.Frame._fromEvent(this,event,this._frames.length));
-}else if(event.name===WebInspector.FilmStripModel.TraceEvents.Screenshot){
-this._frames.push(WebInspector.FilmStripModel.Frame._fromSnapshot(this,event,this._frames.length));
-}
-}
-},
-
-
-
-
-frames:function()
-{
-return this._frames;
-},
-
-
-
-
-zeroTime:function()
-{
-return this._zeroTime;
-},
-
-
-
-
-spanTime:function()
-{
-return this._spanTime;
-},
-
-
-
-
-
-frameByTimestamp:function(timestamp)
-{
-var index=this._frames.upperBound(timestamp,(timestamp,frame)=>timestamp-frame.timestamp)-1;
-return index>=0?this._frames[index]:null;
-}};
-
-
-
-
-
-
-
-
-WebInspector.FilmStripModel.Frame=function(model,timestamp,index)
-{
-this._model=model;
-this.timestamp=timestamp;
-this.index=index;
-
-this._imageData=null;
-
-this._snapshot=null;
-};
-
-
-
-
-
-
-
-WebInspector.FilmStripModel.Frame._fromEvent=function(model,event,index)
-{
-var frame=new WebInspector.FilmStripModel.Frame(model,event.startTime,index);
-frame._imageData=event.args["data"];
-return frame;
-};
-
-
-
-
-
-
-
-WebInspector.FilmStripModel.Frame._fromSnapshot=function(model,snapshot,index)
-{
-var frame=new WebInspector.FilmStripModel.Frame(model,snapshot.startTime,index);
-frame._snapshot=snapshot;
-return frame;
-};
-
-WebInspector.FilmStripModel.Frame.prototype={
-
-
-
-model:function()
-{
-return this._model;
-},
-
-
-
-
-imageDataPromise:function()
-{
-if(this._imageData||!this._snapshot)
-return Promise.resolve(this._imageData);
-
-return this._snapshot.objectPromise();
-}};
-
-
-},{}],103:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-console=console;
-console.__originalAssert=console.assert;
-console.assert=function(value,message)
-{
-if(value)
-return;
-console.__originalAssert(value,message);
-};
-
-
-var ArrayLike;
-
-
-
-
-
-
-function mod(m,n)
-{
-return(m%n+n)%n;
-}
-
-
-
-
-
-String.prototype.findAll=function(string)
-{
-var matches=[];
-var i=this.indexOf(string);
-while(i!==-1){
-matches.push(i);
-i=this.indexOf(string,i+string.length);
-}
-return matches;
-};
-
-
-
-
-String.prototype.replaceControlCharacters=function()
-{
-
-
-return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g,"�");
-};
-
-
-
-
-String.prototype.isWhitespace=function()
-{
-return /^\s*$/.test(this);
-};
-
-
-
-
-String.prototype.computeLineEndings=function()
-{
-var endings=this.findAll("\n");
-endings.push(this.length);
-return endings;
-};
-
-
-
-
-
-String.prototype.escapeCharacters=function(chars)
-{
-var foundChar=false;
-for(var i=0;i<chars.length;++i){
-if(this.indexOf(chars.charAt(i))!==-1){
-foundChar=true;
-break;
-}
-}
-
-if(!foundChar)
-return String(this);
-
-var result="";
-for(var i=0;i<this.length;++i){
-if(chars.indexOf(this.charAt(i))!==-1)
-result+="\\";
-result+=this.charAt(i);
-}
-
-return result;
-};
-
-
-
-
-String.regexSpecialCharacters=function()
-{
-return"^[]{}()\\.^$*+?|-,";
-};
-
-
-
-
-String.prototype.escapeForRegExp=function()
-{
-return this.escapeCharacters(String.regexSpecialCharacters());
-};
-
-
-
-
-String.prototype.escapeHTML=function()
-{
-return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");
-};
-
-
-
-
-String.prototype.unescapeHTML=function()
-{
-return this.replace(/&lt;/g,"<").
-replace(/&gt;/g,">").
-replace(/&#58;/g,":").
-replace(/&quot;/g,"\"").
-replace(/&#60;/g,"<").
-replace(/&#62;/g,">").
-replace(/&amp;/g,"&");
-};
-
-
-
-
-String.prototype.collapseWhitespace=function()
-{
-return this.replace(/[\s\xA0]+/g," ");
-};
-
-
-
-
-
-String.prototype.trimMiddle=function(maxLength)
-{
-if(this.length<=maxLength)
-return String(this);
-var leftHalf=maxLength>>1;
-var rightHalf=maxLength-leftHalf-1;
-return this.substr(0,leftHalf)+"\u2026"+this.substr(this.length-rightHalf,rightHalf);
-};
-
-
-
-
-
-String.prototype.trimEnd=function(maxLength)
-{
-if(this.length<=maxLength)
-return String(this);
-return this.substr(0,maxLength-1)+"\u2026";
-};
-
-
-
-
-
-String.prototype.trimURL=function(baseURLDomain)
-{
-var result=this.replace(/^(https|http|file):\/\//i,"");
-if(baseURLDomain){
-if(result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
-result=result.substr(baseURLDomain.length);
-}
-return result;
-};
-
-
-
-
-String.prototype.toTitleCase=function()
-{
-return this.substring(0,1).toUpperCase()+this.substring(1);
-};
-
-
-
-
-
-String.prototype.compareTo=function(other)
-{
-if(this>other)
-return 1;
-if(this<other)
-return-1;
-return 0;
-};
-
-
-
-
-String.prototype.removeURLFragment=function()
-{
-var fragmentIndex=this.indexOf("#");
-if(fragmentIndex===-1)
-fragmentIndex=this.length;
-return this.substring(0,fragmentIndex);
-};
-
-
-
-
-
-String.hashCode=function(string)
-{
-if(!string)
-return 0;
-
-
-
-var p=(1<<30)*4-5;
-var z=0x5033d967;
-var z2=0x59d2f15d;
-var s=0;
-var zi=1;
-for(var i=0;i<string.length;i++){
-var xi=string.charCodeAt(i)*z2;
-s=(s+zi*xi)%p;
-zi=zi*z%p;
-}
-s=(s+zi*(p-1))%p;
-return Math.abs(s|0);
-};
-
-
-
-
-
-
-String.isDigitAt=function(string,index)
-{
-var c=string.charCodeAt(index);
-return 48<=c&&c<=57;
-};
-
-
-
-
-String.prototype.toBase64=function()
-{
-
-
-
-
-function encodeBits(b)
-{
-return b<26?b+65:b<52?b+71:b<62?b-4:b===62?43:b===63?47:65;
-}
-var encoder=new TextEncoder();
-var data=encoder.encode(this.toString());
-var n=data.length;
-var encoded="";
-if(n===0)
-return encoded;
-var shift;
-var v=0;
-for(var i=0;i<n;i++){
-shift=i%3;
-v|=data[i]<<(16>>>shift&24);
-if(shift===2){
-encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),encodeBits(v&63));
-v=0;
-}
-}
-if(shift===0)
-encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),61,61);else
-if(shift===1)
-encoded+=String.fromCharCode(encodeBits(v>>>18&63),encodeBits(v>>>12&63),encodeBits(v>>>6&63),61);
-return encoded;
-};
-
-
-
-
-
-
-String.naturalOrderComparator=function(a,b)
-{
-var chunk=/^\d+|^\D+/;
-var chunka,chunkb,anum,bnum;
-while(1){
-if(a){
-if(!b)
-return 1;
-}else{
-if(b)
-return-1;else
-
-return 0;
-}
-chunka=a.match(chunk)[0];
-chunkb=b.match(chunk)[0];
-anum=!isNaN(chunka);
-bnum=!isNaN(chunkb);
-if(anum&&!bnum)
-return-1;
-if(bnum&&!anum)
-return 1;
-if(anum&&bnum){
-var diff=chunka-chunkb;
-if(diff)
-return diff;
-if(chunka.length!==chunkb.length){
-if(!+chunka&&!+chunkb)
-return chunka.length-chunkb.length;else
-
-return chunkb.length-chunka.length;
-}
-}else if(chunka!==chunkb)
-return chunka<chunkb?-1:1;
-a=a.substring(chunka.length);
-b=b.substring(chunkb.length);
-}
-};
-
-
-
-
-
-
-String.caseInsensetiveComparator=function(a,b)
-{
-a=a.toUpperCase();
-b=b.toUpperCase();
-if(a===b)
-return 0;
-return a>b?1:-1;
-};
-
-
-
-
-
-
-
-Number.constrain=function(num,min,max)
-{
-if(num<min)
-num=min;else
-if(num>max)
-num=max;
-return num;
-};
-
-
-
-
-
-
-Number.gcd=function(a,b)
-{
-if(b===0)
-return a;else
-
-return Number.gcd(b,a%b);
-};
-
-
-
-
-
-Number.toFixedIfFloating=function(value)
-{
-if(!value||isNaN(value))
-return value;
-var number=Number(value);
-return number%1?number.toFixed(3):String(number);
-};
-
-
-
-
-Date.prototype.toISO8601Compact=function()
-{
-
-
-
-
-function leadZero(x)
-{
-return(x>9?"":"0")+x;
-}
-return this.getFullYear()+
-leadZero(this.getMonth()+1)+
-leadZero(this.getDate())+"T"+
-leadZero(this.getHours())+
-leadZero(this.getMinutes())+
-leadZero(this.getSeconds());
-};
-
-
-
-
-Date.prototype.toConsoleTime=function()
-{
-
-
-
-
-function leadZero2(x)
-{
-return(x>9?"":"0")+x;
-}
-
-
-
-
-
-function leadZero3(x)
-{
-return"0".repeat(3-x.toString().length)+x;
-}
-
-return this.getFullYear()+"-"+
-leadZero2(this.getMonth()+1)+"-"+
-leadZero2(this.getDate())+" "+
-leadZero2(this.getHours())+":"+
-leadZero2(this.getMinutes())+":"+
-leadZero2(this.getSeconds())+"."+
-leadZero3(this.getMilliseconds());
-};
-
-Object.defineProperty(Array.prototype,"remove",{
-
-
-
-
-
-
-
-value:function(value,firstOnly)
-{
-var index=this.indexOf(value);
-if(index===-1)
-return false;
-if(firstOnly){
-this.splice(index,1);
-return true;
-}
-for(var i=index+1,n=this.length;i<n;++i){
-if(this[i]!==value)
-this[index++]=this[i];
-}
-this.length=index;
-return true;
-}});
-
-
-Object.defineProperty(Array.prototype,"pushAll",{
-
-
-
-
-
-value:function(array)
-{
-Array.prototype.push.apply(this,array);
-}});
-
-
-Object.defineProperty(Array.prototype,"rotate",{
-
-
-
-
-
-
-value:function(index)
-{
-var result=[];
-for(var i=index;i<index+this.length;++i)
-result.push(this[i%this.length]);
-return result;
-}});
-
-
-Object.defineProperty(Array.prototype,"sortNumbers",{
-
-
-
-value:function()
-{
-
-
-
-
-
-function numericComparator(a,b)
-{
-return a-b;
-}
-
-this.sort(numericComparator);
-}});
-
-
-Object.defineProperty(Uint32Array.prototype,"sort",{
-value:Array.prototype.sort});
-
-
-(function(){
-var partition={
-
-
-
-
-
-
-
-value:function(comparator,left,right,pivotIndex)
-{
-function swap(array,i1,i2)
-{
-var temp=array[i1];
-array[i1]=array[i2];
-array[i2]=temp;
-}
-
-var pivotValue=this[pivotIndex];
-swap(this,right,pivotIndex);
-var storeIndex=left;
-for(var i=left;i<right;++i){
-if(comparator(this[i],pivotValue)<0){
-swap(this,storeIndex,i);
-++storeIndex;
-}
-}
-swap(this,right,storeIndex);
-return storeIndex;
-}};
-
-Object.defineProperty(Array.prototype,"partition",partition);
-Object.defineProperty(Uint32Array.prototype,"partition",partition);
-
-var sortRange={
-
-
-
-
-
-
-
-
-
-value:function(comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight)
-{
-function quickSortRange(array,comparator,left,right,sortWindowLeft,sortWindowRight)
-{
-if(right<=left)
-return;
-var pivotIndex=Math.floor(Math.random()*(right-left))+left;
-var pivotNewIndex=array.partition(comparator,left,right,pivotIndex);
-if(sortWindowLeft<pivotNewIndex)
-quickSortRange(array,comparator,left,pivotNewIndex-1,sortWindowLeft,sortWindowRight);
-if(pivotNewIndex<sortWindowRight)
-quickSortRange(array,comparator,pivotNewIndex+1,right,sortWindowLeft,sortWindowRight);
-}
-if(leftBound===0&&rightBound===this.length-1&&sortWindowLeft===0&&sortWindowRight>=rightBound)
-this.sort(comparator);else
-
-quickSortRange(this,comparator,leftBound,rightBound,sortWindowLeft,sortWindowRight);
-return this;
-}};
-
-Object.defineProperty(Array.prototype,"sortRange",sortRange);
-Object.defineProperty(Uint32Array.prototype,"sortRange",sortRange);
-})();
-
-Object.defineProperty(Array.prototype,"stableSort",{
-
-
-
-
-
-
-value:function(comparator)
-{
-function defaultComparator(a,b)
-{
-return a<b?-1:a>b?1:0;
-}
-comparator=comparator||defaultComparator;
-
-var indices=new Array(this.length);
-for(var i=0;i<this.length;++i)
-indices[i]=i;
-var self=this;
-
-
-
-
-
-function indexComparator(a,b)
-{
-var result=comparator(self[a],self[b]);
-return result?result:a-b;
-}
-indices.sort(indexComparator);
-
-for(var i=0;i<this.length;++i){
-if(indices[i]<0||i===indices[i])
-continue;
-var cyclical=i;
-var saved=this[i];
-while(true){
-var next=indices[cyclical];
-indices[cyclical]=-1;
-if(next===i){
-this[cyclical]=saved;
-break;
-}else{
-this[cyclical]=this[next];
-cyclical=next;
-}
-}
-}
-return this;
-}});
-
-
-Object.defineProperty(Array.prototype,"qselect",{
-
-
-
-
-
-
-value:function(k,comparator)
-{
-if(k<0||k>=this.length)
-return;
-if(!comparator)
-comparator=function(a,b){return a-b;};
-
-var low=0;
-var high=this.length-1;
-for(;;){
-var pivotPosition=this.partition(comparator,low,high,Math.floor((high+low)/2));
-if(pivotPosition===k)
-return this[k];else
-if(pivotPosition>k)
-high=pivotPosition-1;else
-
-low=pivotPosition+1;
-}
-}});
-
-
-Object.defineProperty(Array.prototype,"lowerBound",{
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-value:function(object,comparator,left,right)
-{
-function defaultComparator(a,b)
-{
-return a<b?-1:a>b?1:0;
-}
-comparator=comparator||defaultComparator;
-var l=left||0;
-var r=right!==undefined?right:this.length;
-while(l<r){
-var m=l+r>>1;
-if(comparator(object,this[m])>0)
-l=m+1;else
-
-r=m;
-}
-return r;
-}});
-
-
-Object.defineProperty(Array.prototype,"upperBound",{
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-value:function(object,comparator,left,right)
-{
-function defaultComparator(a,b)
-{
-return a<b?-1:a>b?1:0;
-}
-comparator=comparator||defaultComparator;
-var l=left||0;
-var r=right!==undefined?right:this.length;
-while(l<r){
-var m=l+r>>1;
-if(comparator(object,this[m])>=0)
-l=m+1;else
-
-r=m;
-}
-return r;
-}});
-
-
-Object.defineProperty(Uint32Array.prototype,"lowerBound",{
-value:Array.prototype.lowerBound});
-
-
-Object.defineProperty(Uint32Array.prototype,"upperBound",{
-value:Array.prototype.upperBound});
-
-
-Object.defineProperty(Float64Array.prototype,"lowerBound",{
-value:Array.prototype.lowerBound});
-
-
-Object.defineProperty(Array.prototype,"binaryIndexOf",{
-
-
-
-
-
-
-
-value:function(value,comparator)
-{
-var index=this.lowerBound(value,comparator);
-return index<this.length&&comparator(value,this[index])===0?index:-1;
-}});
-
-
-Object.defineProperty(Array.prototype,"select",{
-
-
-
-
-
-
-value:function(field)
-{
-var result=new Array(this.length);
-for(var i=0;i<this.length;++i)
-result[i]=this[i][field];
-return result;
-}});
-
-
-Object.defineProperty(Array.prototype,"peekLast",{
-
-
-
-
-
-value:function()
-{
-return this[this.length-1];
-}});
-
-
-(function(){
-
-
-
-
-
-
-
-
-function mergeOrIntersect(array1,array2,comparator,mergeNotIntersect)
-{
-var result=[];
-var i=0;
-var j=0;
-while(i<array1.length&&j<array2.length){
-var compareValue=comparator(array1[i],array2[j]);
-if(mergeNotIntersect||!compareValue)
-result.push(compareValue<=0?array1[i]:array2[j]);
-if(compareValue<=0)
-i++;
-if(compareValue>=0)
-j++;
-}
-if(mergeNotIntersect){
-while(i<array1.length)
-result.push(array1[i++]);
-while(j<array2.length)
-result.push(array2[j++]);
-}
-return result;
-}
-
-Object.defineProperty(Array.prototype,"intersectOrdered",{
-
-
-
-
-
-
-
-value:function(array,comparator)
-{
-return mergeOrIntersect(this,array,comparator,false);
-}});
-
-
-Object.defineProperty(Array.prototype,"mergeOrdered",{
-
-
-
-
-
-
-
-value:function(array,comparator)
-{
-return mergeOrIntersect(this,array,comparator,true);
-}});
-
-})();
-
-
-
-
-
-
-String.sprintf=function(format,var_arg)
-{
-return String.vsprintf(format,Array.prototype.slice.call(arguments,1));
-};
-
-
-
-
-
-
-String.tokenizeFormatString=function(format,formatters)
-{
-var tokens=[];
-var substitutionIndex=0;
-
-function addStringToken(str)
-{
-if(tokens.length&&tokens[tokens.length-1].type==="string")
-tokens[tokens.length-1].value+=str;else
-
-tokens.push({type:"string",value:str});
-}
-
-function addSpecifierToken(specifier,precision,substitutionIndex)
-{
-tokens.push({type:"specifier",specifier:specifier,precision:precision,substitutionIndex:substitutionIndex});
-}
-
-var index=0;
-for(var precentIndex=format.indexOf("%",index);precentIndex!==-1;precentIndex=format.indexOf("%",index)){
-if(format.length===index)
-break;
-addStringToken(format.substring(index,precentIndex));
-index=precentIndex+1;
-
-if(format[index]==="%"){
-
-addStringToken("%");
-++index;
-continue;
-}
-
-if(String.isDigitAt(format,index)){
-
-var number=parseInt(format.substring(index),10);
-while(String.isDigitAt(format,index))
-++index;
-
-
-
-if(number>0&&format[index]==="$"){
-substitutionIndex=number-1;
-++index;
-}
-}
-
-var precision=-1;
-if(format[index]==="."){
-
-
-++index;
-precision=parseInt(format.substring(index),10);
-if(isNaN(precision))
-precision=0;
-
-while(String.isDigitAt(format,index))
-++index;
-}
-
-if(!(format[index]in formatters)){
-addStringToken(format.substring(precentIndex,index+1));
-++index;
-continue;
-}
-
-addSpecifierToken(format[index],precision,substitutionIndex);
-
-++substitutionIndex;
-++index;
-}
-
-addStringToken(format.substring(index));
-
-return tokens;
-};
-
-String.standardFormatters={
-
-
-
-d:function(substitution)
-{
-return!isNaN(substitution)?substitution:0;
-},
-
-
-
-
-f:function(substitution,token)
-{
-if(substitution&&token.precision>-1)
-substitution=substitution.toFixed(token.precision);
-return!isNaN(substitution)?substitution:token.precision>-1?Number(0).toFixed(token.precision):0;
-},
-
-
-
-
-s:function(substitution)
-{
-return substitution;
-}};
-
-
-
-
-
-
-
-String.vsprintf=function(format,substitutions)
-{
-return String.format(format,substitutions,String.standardFormatters,"",function(a,b){return a+b;}).formattedResult;
-};
-
-
-
-
-
-
-
-
-
-
-
-String.format=function(format,substitutions,formatters,initialValue,append,tokenizedFormat)
-{
-if(!format||!substitutions||!substitutions.length)
-return{formattedResult:append(initialValue,format),unusedSubstitutions:substitutions};
-
-function prettyFunctionName()
-{
-return"String.format(\""+format+"\", \""+Array.prototype.join.call(substitutions,"\", \"")+"\")";
-}
-
-function warn(msg)
-{
-console.warn(prettyFunctionName()+": "+msg);
-}
-
-function error(msg)
-{
-console.error(prettyFunctionName()+": "+msg);
-}
-
-var result=initialValue;
-var tokens=tokenizedFormat||String.tokenizeFormatString(format,formatters);
-var usedSubstitutionIndexes={};
-
-for(var i=0;i<tokens.length;++i){
-var token=tokens[i];
-
-if(token.type==="string"){
-result=append(result,token.value);
-continue;
-}
-
-if(token.type!=="specifier"){
-error("Unknown token type \""+token.type+"\" found.");
-continue;
-}
-
-if(token.substitutionIndex>=substitutions.length){
-
-
-error("not enough substitution arguments. Had "+substitutions.length+" but needed "+(token.substitutionIndex+1)+", so substitution was skipped.");
-result=append(result,"%"+(token.precision>-1?token.precision:"")+token.specifier);
-continue;
-}
-
-usedSubstitutionIndexes[token.substitutionIndex]=true;
-
-if(!(token.specifier in formatters)){
-
-warn("unsupported format character \u201C"+token.specifier+"\u201D. Treating as a string.");
-result=append(result,substitutions[token.substitutionIndex]);
-continue;
-}
-
-result=append(result,formatters[token.specifier](substitutions[token.substitutionIndex],token));
-}
-
-var unusedSubstitutions=[];
-for(var i=0;i<substitutions.length;++i){
-if(i in usedSubstitutionIndexes)
-continue;
-unusedSubstitutions.push(substitutions[i]);
-}
-
-return{formattedResult:result,unusedSubstitutions:unusedSubstitutions};
-};
-
-
-
-
-
-
-
-function createSearchRegex(query,caseSensitive,isRegex)
-{
-var regexFlags=caseSensitive?"g":"gi";
-var regexObject;
-
-if(isRegex){
-try{
-regexObject=new RegExp(query,regexFlags);
-}catch(e){
-
-}
-}
-
-if(!regexObject)
-regexObject=createPlainTextSearchRegex(query,regexFlags);
-
-return regexObject;
-}
-
-
-
-
-
-
-function createPlainTextSearchRegex(query,flags)
-{
-
-var regexSpecialCharacters=String.regexSpecialCharacters();
-var regex="";
-for(var i=0;i<query.length;++i){
-var c=query.charAt(i);
-if(regexSpecialCharacters.indexOf(c)!==-1)
-regex+="\\";
-regex+=c;
-}
-return new RegExp(regex,flags||"");
-}
-
-
-
-
-
-
-function countRegexMatches(regex,content)
-{
-var text=content;
-var result=0;
-var match;
-while(text&&(match=regex.exec(text))){
-if(match[0].length>0)
-++result;
-text=text.substring(match.index+1);
-}
-return result;
-}
-
-
-
-
-
-function spacesPadding(spacesCount)
-{
-return"\u00a0".repeat(spacesCount);
-}
-
-
-
-
-
-
-function numberToStringWithSpacesPadding(value,symbolsCount)
-{
-var numberString=value.toString();
-var paddingLength=Math.max(0,symbolsCount-numberString.length);
-return spacesPadding(paddingLength)+numberString;
-}
-
-
-
-
-
-Set.prototype.valuesArray=function()
-{
-return Array.from(this.values());
-};
-
-
-
-
-
-Set.prototype.addAll=function(iterable)
-{
-for(var e of iterable)
-this.add(e);
-};
-
-
-
-
-
-
-Set.prototype.containsAll=function(iterable)
-{
-for(var e of iterable){
-if(!this.has(e))
-return false;
-}
-return true;
-};
-
-
-
-
-
-Map.prototype.remove=function(key)
-{
-var value=this.get(key);
-this.delete(key);
-return value;
-};
-
-
-
-
-Map.prototype.valuesArray=function()
-{
-return Array.from(this.values());
-};
-
-
-
-
-Map.prototype.keysArray=function()
-{
-return Array.from(this.keys());
-};
-
-
-
-
-Map.prototype.inverse=function()
-{
-var result=new Multimap();
-for(var key of this.keys()){
-var value=this.get(key);
-result.set(value,key);
-}
-return result;
-};
-
-
-
-
-
-var Multimap=function()
-{
-
-this._map=new Map();
-};
-
-Multimap.prototype={
-
-
-
-
-set:function(key,value)
-{
-var set=this._map.get(key);
-if(!set){
-set=new Set();
-this._map.set(key,set);
-}
-set.add(value);
-},
-
-
-
-
-
-get:function(key)
-{
-var result=this._map.get(key);
-if(!result)
-result=new Set();
-return result;
-},
-
-
-
-
-
-has:function(key)
-{
-return this._map.has(key);
-},
-
-
-
-
-
-
-hasValue:function(key,value)
-{
-var set=this._map.get(key);
-if(!set)
-return false;
-return set.has(value);
-},
-
-
-
-
-get size()
-{
-return this._map.size;
-},
-
-
-
-
-
-remove:function(key,value)
-{
-var values=this.get(key);
-values.delete(value);
-if(!values.size)
-this._map.delete(key);
-},
-
-
-
-
-removeAll:function(key)
-{
-this._map.delete(key);
-},
-
-
-
-
-keysArray:function()
-{
-return this._map.keysArray();
-},
-
-
-
-
-valuesArray:function()
-{
-var result=[];
-var keys=this.keysArray();
-for(var i=0;i<keys.length;++i)
-result.pushAll(this.get(keys[i]).valuesArray());
-return result;
-},
-
-clear:function()
-{
-this._map.clear();
-}};
-
-
-
-
-
-
-function loadXHR(url)
-{
-return new Promise(load);
-
-function load(successCallback,failureCallback)
-{
-function onReadyStateChanged()
-{
-if(xhr.readyState!==XMLHttpRequest.DONE)
-return;
-if(xhr.status!==200){
-xhr.onreadystatechange=null;
-failureCallback(new Error(xhr.status));
-return;
-}
-xhr.onreadystatechange=null;
-successCallback(xhr.responseText);
-}
-
-var xhr=new XMLHttpRequest();
-xhr.withCredentials=false;
-xhr.open("GET",url,true);
-xhr.onreadystatechange=onReadyStateChanged;
-xhr.send(null);
-}
-}
-
-
-
-
-function CallbackBarrier()
-{
-this._pendingIncomingCallbacksCount=0;
-}
-
-CallbackBarrier.prototype={
-
-
-
-
-createCallback:function(userCallback)
-{
-console.assert(!this._outgoingCallback,"CallbackBarrier.createCallback() is called after CallbackBarrier.callWhenDone()");
-++this._pendingIncomingCallbacksCount;
-return this._incomingCallback.bind(this,userCallback);
-},
-
-
-
-
-callWhenDone:function(callback)
-{
-console.assert(!this._outgoingCallback,"CallbackBarrier.callWhenDone() is called multiple times");
-this._outgoingCallback=callback;
-if(!this._pendingIncomingCallbacksCount)
-this._outgoingCallback();
-},
-
-
-
-
-donePromise:function()
-{
-return new Promise(promiseConstructor.bind(this));
-
-
-
-
-
-function promiseConstructor(success)
-{
-this.callWhenDone(success);
-}
-},
-
-
-
-
-_incomingCallback:function(userCallback)
-{
-console.assert(this._pendingIncomingCallbacksCount>0);
-if(userCallback){
-var args=Array.prototype.slice.call(arguments,1);
-userCallback.apply(null,args);
-}
-if(! --this._pendingIncomingCallbacksCount&&this._outgoingCallback)
-this._outgoingCallback();
-}};
-
-
-
-
-
-function suppressUnused(value)
-{
-}
-
-
-
-
-
-self.setImmediate=function(callback)
-{
-Promise.resolve().then(callback);
-return 0;
-};
-
-
-
-
-
-
-Promise.prototype.spread=function(callback)
-{
-return this.then(spreadPromise);
-
-function spreadPromise(arg)
-{
-return callback.apply(null,arg);
-}
-};
-
-
-
-
-
-
-Promise.prototype.catchException=function(defaultValue){
-return this.catch(function(error){
-console.error(error);
-return defaultValue;
-});
-};
-
-
-
-
-
-
-
-Map.prototype.diff=function(other,isEqual)
-{
-var leftKeys=this.keysArray();
-var rightKeys=other.keysArray();
-leftKeys.sort((a,b)=>a-b);
-rightKeys.sort((a,b)=>a-b);
-
-var removed=[];
-var added=[];
-var equal=[];
-var leftIndex=0;
-var rightIndex=0;
-while(leftIndex<leftKeys.length&&rightIndex<rightKeys.length){
-var leftKey=leftKeys[leftIndex];
-var rightKey=rightKeys[rightIndex];
-if(leftKey===rightKey&&isEqual(this.get(leftKey),other.get(rightKey))){
-equal.push(this.get(leftKey));
-++leftIndex;
-++rightIndex;
-continue;
-}
-if(leftKey<=rightKey){
-removed.push(this.get(leftKey));
-++leftIndex;
-continue;
-}
-added.push(other.get(rightKey));
-++rightIndex;
-}
-while(leftIndex<leftKeys.length){
-var leftKey=leftKeys[leftIndex++];
-removed.push(this.get(leftKey));
-}
-while(rightIndex<rightKeys.length){
-var rightKey=rightKeys[rightIndex++];
-added.push(other.get(rightKey));
-}
-return{
-added:added,
-removed:removed,
-equal:equal};
-
-};
-
-},{}],104:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-WebInspector.CPUProfileNode=function(node,sampleTime)
-{
-var callFrame=node.callFrame||{
-
-functionName:node["functionName"],
-scriptId:node["scriptId"],
-url:node["url"],
-lineNumber:node["lineNumber"]-1,
-columnNumber:node["columnNumber"]-1};
-
-WebInspector.ProfileNode.call(this,callFrame);
-this.id=node.id;
-this.self=node.hitCount*sampleTime;
-this.positionTicks=node.positionTicks;
-
-this.deoptReason=node.deoptReason&&node.deoptReason!=="no reason"?node.deoptReason:null;
-};
-
-WebInspector.CPUProfileNode.prototype={
-__proto__:WebInspector.ProfileNode.prototype};
-
-
-
-
-
-
-
-WebInspector.CPUProfileDataModel=function(profile)
-{
-var isLegacyFormat=!!profile["head"];
-if(isLegacyFormat){
-
-this.profileStartTime=profile.startTime*1000;
-this.profileEndTime=profile.endTime*1000;
-this.timestamps=profile.timestamps;
-this._compatibilityConversionHeadToNodes(profile);
-}else{
-
-this.profileStartTime=profile.startTime/1000;
-this.profileEndTime=profile.endTime/1000;
-this.timestamps=this._convertTimeDeltas(profile);
-}
-this.samples=profile.samples;
-this.totalHitCount=0;
-this.profileHead=this._translateProfileTree(profile.nodes);
-WebInspector.ProfileTreeModel.call(this,this.profileHead);
-this._extractMetaNodes();
-if(this.samples){
-this._buildIdToNodeMap();
-this._sortSamples();
-this._normalizeTimestamps();
-}
-};
-
-WebInspector.CPUProfileDataModel.prototype={
-
-
-
-_compatibilityConversionHeadToNodes:function(profile)
-{
-if(!profile.head||profile.nodes)
-return;
-
-var nodes=[];
-convertNodesTree(profile.head);
-profile.nodes=nodes;
-delete profile.head;
-
-
-
-
-function convertNodesTree(node)
-{
-nodes.push(node);
-node.children=node.children.map(convertNodesTree);
-return node.id;
-}
-},
-
-
-
-
-
-_convertTimeDeltas:function(profile)
-{
-if(!profile.timeDeltas)
-return null;
-var lastTimeUsec=profile.startTime;
-var timestamps=new Array(profile.timeDeltas.length);
-for(var i=0;i<timestamps.length;++i){
-lastTimeUsec+=profile.timeDeltas[i];
-timestamps[i]=lastTimeUsec;
-}
-return timestamps;
-},
-
-
-
-
-
-_translateProfileTree:function(nodes)
-{
-
-
-
-
-function isNativeNode(node)
-{
-if(node.callFrame)
-return!!node.callFrame.url&&node.callFrame.url.startsWith("native ");
-return!!node.url&&node.url.startsWith("native ");
-}
-
-
-
-function buildChildrenFromParents(nodes)
-{
-if(nodes[0].children)
-return;
-nodes[0].children=[];
-for(var i=1;i<nodes.length;++i){
-var node=nodes[i];
-var parentNode=nodeByIdMap.get(node.parent);
-if(parentNode.children)
-parentNode.children.push(node.id);else
-
-parentNode.children=[node.id];
-}
-}
-
-var nodeByIdMap=new Map();
-for(var i=0;i<nodes.length;++i){
-var node=nodes[i];
-nodeByIdMap.set(node.id,node);
-}
-buildChildrenFromParents(nodes);
-this.totalHitCount=nodes.reduce((acc,node)=>acc+node.hitCount,0);
-var sampleTime=(this.profileEndTime-this.profileStartTime)/this.totalHitCount;
-var keepNatives=!!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get();
-var root=nodes[0];
-
-var idMap=new Map([[root.id,root.id]]);
-var resultRoot=new WebInspector.CPUProfileNode(root,sampleTime);
-var parentNodeStack=root.children.map(()=>resultRoot);
-var sourceNodeStack=root.children.map(id=>nodeByIdMap.get(id));
-while(sourceNodeStack.length){
-var parentNode=parentNodeStack.pop();
-var sourceNode=sourceNodeStack.pop();
-if(!sourceNode.children)
-sourceNode.children=[];
-var targetNode=new WebInspector.CPUProfileNode(sourceNode,sampleTime);
-if(keepNatives||!isNativeNode(sourceNode)){
-parentNode.children.push(targetNode);
-parentNode=targetNode;
-}else{
-parentNode.self+=targetNode.self;
-}
-idMap.set(sourceNode.id,parentNode.id);
-parentNodeStack.push.apply(parentNodeStack,sourceNode.children.map(()=>parentNode));
-sourceNodeStack.push.apply(sourceNodeStack,sourceNode.children.map(id=>nodeByIdMap.get(id)));
-}
-if(this.samples)
-this.samples=this.samples.map(id=>idMap.get(id));
-return resultRoot;
-},
-
-_sortSamples:function()
-{
-var timestamps=this.timestamps;
-if(!timestamps)
-return;
-var samples=this.samples;
-var indices=timestamps.map((x,index)=>index);
-indices.sort((a,b)=>timestamps[a]-timestamps[b]);
-for(var i=0;i<timestamps.length;++i){
-var index=indices[i];
-if(index===i)
-continue;
-
-var savedTimestamp=timestamps[i];
-var savedSample=samples[i];
-var currentIndex=i;
-while(index!==i){
-samples[currentIndex]=samples[index];
-timestamps[currentIndex]=timestamps[index];
-currentIndex=index;
-index=indices[index];
-indices[currentIndex]=currentIndex;
-}
-samples[currentIndex]=savedSample;
-timestamps[currentIndex]=savedTimestamp;
-}
-},
-
-_normalizeTimestamps:function()
-{
-var timestamps=this.timestamps;
-if(!timestamps){
-
-
-var profileStartTime=this.profileStartTime;
-var interval=(this.profileEndTime-profileStartTime)/this.samples.length;
-timestamps=new Float64Array(this.samples.length+1);
-for(var i=0;i<timestamps.length;++i)
-timestamps[i]=profileStartTime+i*interval;
-this.timestamps=timestamps;
-return;
-}
-
-
-for(var i=0;i<timestamps.length;++i)
-timestamps[i]/=1000;
-var averageSample=(timestamps.peekLast()-timestamps[0])/(timestamps.length-1);
-
-this.timestamps.push(timestamps.peekLast()+averageSample);
-this.profileStartTime=timestamps[0];
-this.profileEndTime=timestamps.peekLast();
-},
-
-_buildIdToNodeMap:function()
-{
-
-this._idToNode=new Map();
-var idToNode=this._idToNode;
-var stack=[this.profileHead];
-while(stack.length){
-var node=stack.pop();
-idToNode.set(node.id,node);
-stack.push.apply(stack,node.children);
-}
-},
-
-_extractMetaNodes:function()
-{
-var topLevelNodes=this.profileHead.children;
-for(var i=0;i<topLevelNodes.length&&!(this.gcNode&&this.programNode&&this.idleNode);i++){
-var node=topLevelNodes[i];
-if(node.functionName==="(garbage collector)")
-this.gcNode=node;else
-if(node.functionName==="(program)")
-this.programNode=node;else
-if(node.functionName==="(idle)")
-this.idleNode=node;
-}
-},
-
-
-
-
-
-
-
-forEachFrame:function(openFrameCallback,closeFrameCallback,startTime,stopTime)
-{
-if(!this.profileHead||!this.samples)
-return;
-
-startTime=startTime||0;
-stopTime=stopTime||Infinity;
-var samples=this.samples;
-var timestamps=this.timestamps;
-var idToNode=this._idToNode;
-var gcNode=this.gcNode;
-var samplesCount=samples.length;
-var startIndex=timestamps.lowerBound(startTime);
-var stackTop=0;
-var stackNodes=[];
-var prevId=this.profileHead.id;
-var sampleTime=timestamps[samplesCount];
-var gcParentNode=null;
-
-if(!this._stackStartTimes)
-this._stackStartTimes=new Float64Array(this.maxDepth+2);
-var stackStartTimes=this._stackStartTimes;
-if(!this._stackChildrenDuration)
-this._stackChildrenDuration=new Float64Array(this.maxDepth+2);
-var stackChildrenDuration=this._stackChildrenDuration;
-
-for(var sampleIndex=startIndex;sampleIndex<samplesCount;sampleIndex++){
-sampleTime=timestamps[sampleIndex];
-if(sampleTime>=stopTime)
-break;
-var id=samples[sampleIndex];
-if(id===prevId)
-continue;
-var node=idToNode.get(id);
-var prevNode=idToNode.get(prevId);
-
-if(node===gcNode){
-
-gcParentNode=prevNode;
-openFrameCallback(gcParentNode.depth+1,gcNode,sampleTime);
-stackStartTimes[++stackTop]=sampleTime;
-stackChildrenDuration[stackTop]=0;
-prevId=id;
-continue;
-}
-if(prevNode===gcNode){
-
-var start=stackStartTimes[stackTop];
-var duration=sampleTime-start;
-stackChildrenDuration[stackTop-1]+=duration;
-closeFrameCallback(gcParentNode.depth+1,gcNode,start,duration,duration-stackChildrenDuration[stackTop]);
---stackTop;
-prevNode=gcParentNode;
-prevId=prevNode.id;
-gcParentNode=null;
-}
-
-while(node.depth>prevNode.depth){
-stackNodes.push(node);
-node=node.parent;
-}
-
-
-while(prevNode!==node){
-var start=stackStartTimes[stackTop];
-var duration=sampleTime-start;
-stackChildrenDuration[stackTop-1]+=duration;
-closeFrameCallback(prevNode.depth,prevNode,start,duration,duration-stackChildrenDuration[stackTop]);
---stackTop;
-if(node.depth===prevNode.depth){
-stackNodes.push(node);
-node=node.parent;
-}
-prevNode=prevNode.parent;
-}
-
-
-while(stackNodes.length){
-node=stackNodes.pop();
-openFrameCallback(node.depth,node,sampleTime);
-stackStartTimes[++stackTop]=sampleTime;
-stackChildrenDuration[stackTop]=0;
-}
-
-prevId=id;
-}
-
-if(idToNode.get(prevId)===gcNode){
-var start=stackStartTimes[stackTop];
-var duration=sampleTime-start;
-stackChildrenDuration[stackTop-1]+=duration;
-closeFrameCallback(gcParentNode.depth+1,node,start,duration,duration-stackChildrenDuration[stackTop]);
---stackTop;
-}
-
-for(var node=idToNode.get(prevId);node.parent;node=node.parent){
-var start=stackStartTimes[stackTop];
-var duration=sampleTime-start;
-stackChildrenDuration[stackTop-1]+=duration;
-closeFrameCallback(node.depth,node,start,duration,duration-stackChildrenDuration[stackTop]);
---stackTop;
-}
-},
-
-
-
-
-
-nodeByIndex:function(index)
-{
-return this._idToNode.get(this.samples[index])||null;
-},
-
-__proto__:WebInspector.ProfileTreeModel.prototype};
-
-
-},{}],105:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.CSSMatchedStyles=function(cssModel,node,inlinePayload,attributesPayload,matchedPayload,pseudoPayload,inheritedPayload,animationsPayload)
-{
-this._cssModel=cssModel;
-this._node=node;
-this._nodeStyles=[];
-this._nodeForStyle=new Map();
-this._inheritedStyles=new Set();
-this._keyframes=[];
-
-this._matchingSelectors=new Map();
-
-
-
-
-function addAttributesStyle()
-{
-if(!attributesPayload)
-return;
-var style=new WebInspector.CSSStyleDeclaration(cssModel,null,attributesPayload,WebInspector.CSSStyleDeclaration.Type.Attributes);
-this._nodeForStyle.set(style,this._node);
-this._nodeStyles.push(style);
-}
-
-
-if(inlinePayload&&this._node.nodeType()===Node.ELEMENT_NODE){
-var style=new WebInspector.CSSStyleDeclaration(cssModel,null,inlinePayload,WebInspector.CSSStyleDeclaration.Type.Inline);
-this._nodeForStyle.set(style,this._node);
-this._nodeStyles.push(style);
-}
-
-
-var addedAttributesStyle;
-for(var i=matchedPayload.length-1;i>=0;--i){
-var rule=new WebInspector.CSSStyleRule(cssModel,matchedPayload[i].rule);
-if((rule.isInjected()||rule.isUserAgent())&&!addedAttributesStyle){
-
-addedAttributesStyle=true;
-addAttributesStyle.call(this);
-}
-this._nodeForStyle.set(rule.style,this._node);
-this._nodeStyles.push(rule.style);
-addMatchingSelectors.call(this,this._node,rule,matchedPayload[i].matchingSelectors);
-}
-
-if(!addedAttributesStyle)
-addAttributesStyle.call(this);
-
-
-var parentNode=this._node.parentNode;
-for(var i=0;parentNode&&inheritedPayload&&i<inheritedPayload.length;++i){
-var entryPayload=inheritedPayload[i];
-var inheritedInlineStyle=entryPayload.inlineStyle?new WebInspector.CSSStyleDeclaration(cssModel,null,entryPayload.inlineStyle,WebInspector.CSSStyleDeclaration.Type.Inline):null;
-if(inheritedInlineStyle&&this._containsInherited(inheritedInlineStyle)){
-this._nodeForStyle.set(inheritedInlineStyle,parentNode);
-this._nodeStyles.push(inheritedInlineStyle);
-this._inheritedStyles.add(inheritedInlineStyle);
-}
-
-var inheritedMatchedCSSRules=entryPayload.matchedCSSRules||[];
-for(var j=inheritedMatchedCSSRules.length-1;j>=0;--j){
-var inheritedRule=new WebInspector.CSSStyleRule(cssModel,inheritedMatchedCSSRules[j].rule);
-addMatchingSelectors.call(this,parentNode,inheritedRule,inheritedMatchedCSSRules[j].matchingSelectors);
-if(!this._containsInherited(inheritedRule.style))
-continue;
-this._nodeForStyle.set(inheritedRule.style,parentNode);
-this._nodeStyles.push(inheritedRule.style);
-this._inheritedStyles.add(inheritedRule.style);
-}
-parentNode=parentNode.parentNode;
-}
-
-
-this._pseudoStyles=new Map();
-if(pseudoPayload){
-for(var i=0;i<pseudoPayload.length;++i){
-var entryPayload=pseudoPayload[i];
-
-var pseudoElement=this._node.pseudoElements().get(entryPayload.pseudoType)||null;
-var pseudoStyles=[];
-var rules=entryPayload.matches||[];
-for(var j=rules.length-1;j>=0;--j){
-var pseudoRule=new WebInspector.CSSStyleRule(cssModel,rules[j].rule);
-pseudoStyles.push(pseudoRule.style);
-this._nodeForStyle.set(pseudoRule.style,pseudoElement);
-if(pseudoElement)
-addMatchingSelectors.call(this,pseudoElement,pseudoRule,rules[j].matchingSelectors);
-}
-this._pseudoStyles.set(entryPayload.pseudoType,pseudoStyles);
-}
-}
-
-if(animationsPayload)
-this._keyframes=animationsPayload.map(rule=>new WebInspector.CSSKeyframesRule(cssModel,rule));
-
-this.resetActiveProperties();
-
-
-
-
-
-
-
-function addMatchingSelectors(node,rule,matchingSelectorIndices)
-{
-for(var matchingSelectorIndex of matchingSelectorIndices){
-var selector=rule.selectors[matchingSelectorIndex];
-this._setSelectorMatches(node,selector.text,true);
-}
-}
-};
-
-WebInspector.CSSMatchedStyles.prototype={
-
-
-
-node:function()
-{
-return this._node;
-},
-
-
-
-
-cssModel:function()
-{
-return this._cssModel;
-},
-
-
-
-
-
-hasMatchingSelectors:function(rule)
-{
-var matchingSelectors=this.matchingSelectors(rule);
-return matchingSelectors.length>0&&this.mediaMatches(rule.style);
-},
-
-
-
-
-
-matchingSelectors:function(rule)
-{
-var node=this.nodeForStyle(rule.style);
-if(!node)
-return[];
-var map=this._matchingSelectors.get(node.id);
-if(!map)
-return[];
-var result=[];
-for(var i=0;i<rule.selectors.length;++i){
-if(map.get(rule.selectors[i].text))
-result.push(i);
-}
-return result;
-},
-
-
-
-
-
-recomputeMatchingSelectors:function(rule)
-{
-var node=this.nodeForStyle(rule.style);
-if(!node)
-return Promise.resolve();
-var promises=[];
-for(var selector of rule.selectors)
-promises.push(querySelector.call(this,node,selector.text));
-return Promise.all(promises);
-
-
-
-
-
-
-
-function querySelector(node,selectorText)
-{
-var ownerDocument=node.ownerDocument||null;
-
-
-var map=this._matchingSelectors.get(node.id);
-if(map&&map.has(selectorText)||!ownerDocument)
-return Promise.resolve();
-
-var resolve;
-var promise=new Promise(fulfill=>resolve=fulfill);
-this._node.domModel().querySelectorAll(ownerDocument.id,selectorText,onQueryComplete.bind(this,node,selectorText,resolve));
-return promise;
-}
-
-
-
-
-
-
-
-
-function onQueryComplete(node,selectorText,callback,matchingNodeIds)
-{
-if(matchingNodeIds)
-this._setSelectorMatches(node,selectorText,matchingNodeIds.indexOf(node.id)!==-1);
-callback();
-}
-},
-
-
-
-
-
-
-addNewRule:function(rule,node)
-{
-this._nodeForStyle.set(rule.style,node);
-return this.recomputeMatchingSelectors(rule);
-},
-
-
-
-
-
-
-_setSelectorMatches:function(node,selectorText,value)
-{
-var map=this._matchingSelectors.get(node.id);
-if(!map){
-map=new Map();
-this._matchingSelectors.set(node.id,map);
-}
-map.set(selectorText,value);
-},
-
-
-
-
-
-mediaMatches:function(style)
-{
-var media=style.parentRule?style.parentRule.media:[];
-for(var i=0;media&&i<media.length;++i){
-if(!media[i].active())
-return false;
-}
-return true;
-},
-
-
-
-
-nodeStyles:function()
-{
-return this._nodeStyles;
-},
-
-
-
-
-keyframes:function()
-{
-return this._keyframes;
-},
-
-
-
-
-pseudoStyles:function()
-{
-return this._pseudoStyles;
-},
-
-
-
-
-
-_containsInherited:function(style)
-{
-var properties=style.allProperties;
-for(var i=0;i<properties.length;++i){
-var property=properties[i];
-
-if(property.activeInStyle()&&WebInspector.cssMetadata().isPropertyInherited(property.name))
-return true;
-}
-return false;
-},
-
-
-
-
-
-nodeForStyle:function(style)
-{
-return this._nodeForStyle.get(style)||null;
-},
-
-
-
-
-
-isInherited:function(style)
-{
-return this._inheritedStyles.has(style);
-},
-
-
-
-
-
-propertyState:function(property)
-{
-if(this._propertiesState.size===0){
-this._computeActiveProperties(this._nodeStyles,this._propertiesState);
-for(var pseudoElementStyles of this._pseudoStyles.valuesArray())
-this._computeActiveProperties(pseudoElementStyles,this._propertiesState);
-}
-return this._propertiesState.get(property)||null;
-},
-
-resetActiveProperties:function()
-{
-
-this._propertiesState=new Map();
-},
-
-
-
-
-
-_computeActiveProperties:function(styles,result)
-{
-
-var foundImportantProperties=new Set();
-
-var propertyToEffectiveRule=new Map();
-
-var inheritedPropertyToNode=new Map();
-
-var allUsedProperties=new Set();
-for(var i=0;i<styles.length;++i){
-var style=styles[i];
-var rule=style.parentRule;
-
-if(rule&&!(rule instanceof WebInspector.CSSStyleRule))
-continue;
-if(rule&&!this.hasMatchingSelectors(rule))
-continue;
-
-
-var styleActiveProperties=new Map();
-var allProperties=style.allProperties;
-for(var j=0;j<allProperties.length;++j){
-var property=allProperties[j];
-
-
-var inherited=this.isInherited(style);
-if(inherited&&!WebInspector.cssMetadata().isPropertyInherited(property.name))
-continue;
-
-if(!property.activeInStyle()){
-result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
-continue;
-}
-
-var canonicalName=WebInspector.cssMetadata().canonicalPropertyName(property.name);
-if(foundImportantProperties.has(canonicalName)){
-result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
-continue;
-}
-
-if(!property.important&&allUsedProperties.has(canonicalName)){
-result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
-continue;
-}
-
-var isKnownProperty=propertyToEffectiveRule.has(canonicalName);
-var inheritedFromNode=inherited?this.nodeForStyle(style):null;
-if(!isKnownProperty&&inheritedFromNode&&!inheritedPropertyToNode.has(canonicalName))
-inheritedPropertyToNode.set(canonicalName,inheritedFromNode);
-
-if(property.important){
-if(inherited&&isKnownProperty&&inheritedFromNode!==inheritedPropertyToNode.get(canonicalName)){
-result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
-continue;
-}
-
-foundImportantProperties.add(canonicalName);
-if(isKnownProperty){
-var overloaded=propertyToEffectiveRule.get(canonicalName).get(canonicalName);
-result.set(overloaded,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
-propertyToEffectiveRule.get(canonicalName).delete(canonicalName);
-}
-}
-
-styleActiveProperties.set(canonicalName,property);
-allUsedProperties.add(canonicalName);
-propertyToEffectiveRule.set(canonicalName,styleActiveProperties);
-result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Active);
-}
-
-
-for(var property of style.leadingProperties()){
-var canonicalName=WebInspector.cssMetadata().canonicalPropertyName(property.name);
-if(!styleActiveProperties.has(canonicalName))
-continue;
-var longhands=style.longhandProperties(property.name);
-if(!longhands.length)
-continue;
-var notUsed=true;
-for(var longhand of longhands){
-var longhandCanonicalName=WebInspector.cssMetadata().canonicalPropertyName(longhand.name);
-notUsed=notUsed&&!styleActiveProperties.has(longhandCanonicalName);
-}
-if(!notUsed)
-continue;
-styleActiveProperties.delete(canonicalName);
-allUsedProperties.delete(canonicalName);
-result.set(property,WebInspector.CSSMatchedStyles.PropertyState.Overloaded);
-}
-}
-}};
-
-
-
-WebInspector.CSSMatchedStyles.PropertyState={
-Active:"Active",
-Overloaded:"Overloaded"};
-
-
-},{}],106:[function(require,module,exports){
-
-
-
-
-
-
-
-
-WebInspector.CSSMediaQuery=function(payload)
-{
-this._active=payload.active;
-this._expressions=[];
-for(var j=0;j<payload.expressions.length;++j)
-this._expressions.push(WebInspector.CSSMediaQueryExpression.parsePayload(payload.expressions[j]));
-};
-
-
-
-
-
-WebInspector.CSSMediaQuery.parsePayload=function(payload)
-{
-return new WebInspector.CSSMediaQuery(payload);
-};
-
-WebInspector.CSSMediaQuery.prototype={
-
-
-
-active:function()
-{
-return this._active;
-},
-
-
-
-
-expressions:function()
-{
-return this._expressions;
-}};
-
-
-
-
-
-
-WebInspector.CSSMediaQueryExpression=function(payload)
-{
-this._value=payload.value;
-this._unit=payload.unit;
-this._feature=payload.feature;
-this._valueRange=payload.valueRange?WebInspector.TextRange.fromObject(payload.valueRange):null;
-this._computedLength=payload.computedLength||null;
-};
-
-
-
-
-
-WebInspector.CSSMediaQueryExpression.parsePayload=function(payload)
-{
-return new WebInspector.CSSMediaQueryExpression(payload);
-};
-
-WebInspector.CSSMediaQueryExpression.prototype={
-
-
-
-value:function()
-{
-return this._value;
-},
-
-
-
-
-unit:function()
-{
-return this._unit;
-},
-
-
-
-
-feature:function()
-{
-return this._feature;
-},
-
-
-
-
-valueRange:function()
-{
-return this._valueRange;
-},
-
-
-
-
-computedLength:function()
-{
-return this._computedLength;
-}};
-
-
-
-
-
-
-
-
-WebInspector.CSSMedia=function(cssModel,payload)
-{
-this._cssModel=cssModel;
-this._reinitialize(payload);
-};
-
-WebInspector.CSSMedia.Source={
-LINKED_SHEET:"linkedSheet",
-INLINE_SHEET:"inlineSheet",
-MEDIA_RULE:"mediaRule",
-IMPORT_RULE:"importRule"};
-
-
-
-
-
-
-
-WebInspector.CSSMedia.parsePayload=function(cssModel,payload)
-{
-return new WebInspector.CSSMedia(cssModel,payload);
-};
-
-
-
-
-
-
-WebInspector.CSSMedia.parseMediaArrayPayload=function(cssModel,payload)
-{
-var result=[];
-for(var i=0;i<payload.length;++i)
-result.push(WebInspector.CSSMedia.parsePayload(cssModel,payload[i]));
-return result;
-};
-
-WebInspector.CSSMedia.prototype={
-
-
-
-_reinitialize:function(payload)
-{
-this.text=payload.text;
-this.source=payload.source;
-this.sourceURL=payload.sourceURL||"";
-this.range=payload.range?WebInspector.TextRange.fromObject(payload.range):null;
-this.styleSheetId=payload.styleSheetId;
-this.mediaList=null;
-if(payload.mediaList){
-this.mediaList=[];
-for(var i=0;i<payload.mediaList.length;++i)
-this.mediaList.push(WebInspector.CSSMediaQuery.parsePayload(payload.mediaList[i]));
-}
-},
-
-
-
-
-rebase:function(edit)
-{
-if(this.styleSheetId!==edit.styleSheetId||!this.range)
-return;
-if(edit.oldRange.equal(this.range))
-this._reinitialize(edit.payload);else
-
-this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);
-},
-
-
-
-
-
-equal:function(other)
-{
-if(!this.styleSheetId||!this.range||!other.range)
-return false;
-return this.styleSheetId===other.styleSheetId&&this.range.equal(other.range);
-},
-
-
-
-
-active:function()
-{
-if(!this.mediaList)
-return true;
-for(var i=0;i<this.mediaList.length;++i){
-if(this.mediaList[i].active())
-return true;
-}
-return false;
-},
-
-
-
-
-lineNumberInSource:function()
-{
-if(!this.range)
-return undefined;
-var header=this.header();
-if(!header)
-return undefined;
-return header.lineNumberInSource(this.range.startLine);
-},
-
-
-
-
-columnNumberInSource:function()
-{
-if(!this.range)
-return undefined;
-var header=this.header();
-if(!header)
-return undefined;
-return header.columnNumberInSource(this.range.startLine,this.range.startColumn);
-},
-
-
-
-
-header:function()
-{
-return this.styleSheetId?this._cssModel.styleSheetHeaderForId(this.styleSheetId):null;
-},
-
-
-
-
-rawLocation:function()
-{
-var header=this.header();
-if(!header||this.lineNumberInSource()===undefined)
-return null;
-var lineNumber=Number(this.lineNumberInSource());
-return new WebInspector.CSSLocation(header,lineNumber,this.columnNumberInSource());
-}};
-
-
-},{}],107:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.CSSMetadata=function(properties)
-{
-this._values=[];
-
-this._longhands=new Map();
-
-this._shorthands=new Map();
-
-this._inherited=new Set();
-for(var i=0;i<properties.length;++i){
-var property=properties[i];
-var propertyName=property.name;
-if(!CSS.supports(propertyName,"initial"))
-continue;
-this._values.push(propertyName);
-
-if(property.inherited)
-this._inherited.add(propertyName);
-
-var longhands=properties[i].longhands;
-if(longhands){
-this._longhands.set(propertyName,longhands);
-for(var j=0;j<longhands.length;++j){
-var longhandName=longhands[j];
-var shorthands=this._shorthands.get(longhandName);
-if(!shorthands){
-shorthands=[];
-this._shorthands.set(longhandName,shorthands);
-}
-shorthands.push(propertyName);
-}
-}
-}
-this._values.sort();
-this._valuesSet=new Set(this._values);
-};
-
-WebInspector.CSSMetadata.VariableRegex=/(var\(--.*?\))/g;
-WebInspector.CSSMetadata.URLRegex=/url\(\s*('.+?'|".+?"|[^)]+)\s*\)/g;
-
-WebInspector.CSSMetadata.prototype={
-
-
-
-allProperties:function()
-{
-return this._values;
-},
-
-
-
-
-
-longhands:function(shorthand)
-{
-return this._longhands.get(shorthand)||null;
-},
-
-
-
-
-
-shorthands:function(longhand)
-{
-return this._shorthands.get(longhand)||null;
-},
-
-
-
-
-
-isColorAwareProperty:function(propertyName)
-{
-return!!WebInspector.CSSMetadata._colorAwareProperties.has(propertyName.toLowerCase())||this.isCustomProperty(propertyName.toLowerCase());
-},
-
-
-
-
-
-isLengthProperty:function(propertyName)
-{
-propertyName=propertyName.toLowerCase();
-if(propertyName==="line-height")
-return false;
-return WebInspector.CSSMetadata._distanceProperties.has(propertyName)||propertyName.startsWith("margin")||propertyName.startsWith("padding")||propertyName.indexOf("width")!==-1||propertyName.indexOf("height")!==-1;
-},
-
-
-
-
-
-isBezierAwareProperty:function(propertyName)
-{
-propertyName=propertyName.toLowerCase();
-return!!WebInspector.CSSMetadata._bezierAwareProperties.has(propertyName)||this.isCustomProperty(propertyName);
-},
-
-
-
-
-
-isCustomProperty:function(propertyName)
-{
-return propertyName.startsWith("--");
-},
-
-
-
-
-
-canonicalPropertyName:function(name)
-{
-name=name.toLowerCase();
-if(!name||name.length<9||name.charAt(0)!=="-")
-return name;
-var match=name.match(/(?:-webkit-)(.+)/);
-if(!match||!this._valuesSet.has(match[1]))
-return name;
-return match[1];
-},
-
-
-
-
-
-isCSSPropertyName:function(propertyName)
-{
-propertyName=propertyName.toLowerCase();
-if(propertyName.startsWith("-moz-")||propertyName.startsWith("-o-")||propertyName.startsWith("-webkit-")||propertyName.startsWith("-ms-"))
-return true;
-return this._valuesSet.has(propertyName);
-},
-
-
-
-
-
-isPropertyInherited:function(propertyName)
-{
-propertyName=propertyName.toLowerCase();
-return this._inherited.has(this.canonicalPropertyName(propertyName))||this._inherited.has(propertyName);
-},
-
-
-
-
-
-propertyValues:function(propertyName)
-{
-var acceptedKeywords=["inherit","initial"];
-propertyName=propertyName.toLowerCase();
-var unprefixedName=propertyName.replace(/^-webkit-/,"");
-var entry=WebInspector.CSSMetadata._propertyDataMap[propertyName]||WebInspector.CSSMetadata._propertyDataMap[unprefixedName];
-if(entry&&entry.values)
-acceptedKeywords.pushAll(entry.values);
-if(this.isColorAwareProperty(propertyName)){
-acceptedKeywords.push("currentColor");
-for(var color in WebInspector.Color.Nicknames)
-acceptedKeywords.push(color);
-}
-return acceptedKeywords.sort();
-},
-
-
-
-
-
-mostUsedProperty:function(properties)
-{
-var maxWeight=0;
-var index=0;
-for(var i=0;i<properties.length;i++){
-var weight=WebInspector.CSSMetadata.Weight[properties[i]];
-if(!weight)
-weight=WebInspector.CSSMetadata.Weight[this.canonicalPropertyName(properties[i])];
-if(weight>maxWeight){
-maxWeight=weight;
-index=i;
-}
-}
-return index;
-}};
-
-
-
-
-
-WebInspector.cssMetadata=function()
-{
-if(!WebInspector.CSSMetadata._instance)
-WebInspector.CSSMetadata._instance=new WebInspector.CSSMetadata(WebInspector.CSSMetadata._generatedProperties||[]);
-return WebInspector.CSSMetadata._instance;
-};
-
-WebInspector.CSSMetadata._distanceProperties=new Set([
-"background-position","border-spacing","bottom","font-size","height","left","letter-spacing","max-height","max-width","min-height",
-"min-width","right","text-indent","top","width","word-spacing"]);
-
-
-WebInspector.CSSMetadata._bezierAwareProperties=new Set([
-"animation","animation-timing-function","transition","transition-timing-function","-webkit-animation","-webkit-animation-timing-function",
-"-webkit-transition","-webkit-transition-timing-function"]);
-
-
-WebInspector.CSSMetadata._colorAwareProperties=new Set([
-"backdrop-filter","background","background-color","background-image","border","border-color","border-image",
-"border-image-source","border-bottom","border-bottom-color","border-left","border-left-color","border-right",
-"border-right-color","border-top","border-top-color","box-shadow","color","column-rule","column-rule-color","fill",
-"list-style","list-style-image","outline","outline-color","stroke","text-decoration-color","text-shadow",
-"-webkit-border-after","-webkit-border-after-color","-webkit-border-before","-webkit-border-before-color","-webkit-border-end",
-"-webkit-border-end-color","-webkit-border-start","-webkit-border-start-color","-webkit-box-reflect","-webkit-box-shadow",
-"-webkit-column-rule-color","-webkit-filter","-webkit-mask","-webkit-mask-box-image","-webkit-mask-box-image-source",
-"-webkit-mask-image","-webkit-tap-highlight-color","-webkit-text-decoration-color","-webkit-text-emphasis",
-"-webkit-text-emphasis-color","-webkit-text-fill-color","-webkit-text-stroke","-webkit-text-stroke-color"]);
-
-
-WebInspector.CSSMetadata._propertyDataMap={
-"table-layout":{values:[
-"auto","fixed"]},
-
-"visibility":{values:[
-"hidden","visible","collapse"]},
-
-"background-repeat":{values:[
-"repeat","repeat-x","repeat-y","no-repeat","space","round"]},
-
-"content":{values:[
-"list-item","close-quote","no-close-quote","no-open-quote","open-quote"]},
-
-"list-style-image":{values:[
-"none"]},
-
-"clear":{values:[
-"none","left","right","both"]},
-
-"overflow-x":{values:[
-"hidden","auto","visible","overlay","scroll"]},
-
-"stroke-linejoin":{values:[
-"round","miter","bevel"]},
-
-"baseline-shift":{values:[
-"baseline","sub","super"]},
-
-"border-bottom-width":{values:[
-"medium","thick","thin"]},
-
-"margin-top-collapse":{values:[
-"collapse","separate","discard"]},
-
-"max-height":{values:[
-"none"]},
-
-"box-orient":{values:[
-"horizontal","vertical","inline-axis","block-axis"]},
-
-"font-stretch":{values:[
-"normal","wider","narrower","ultra-condensed","extra-condensed","condensed","semi-condensed",
-"semi-expanded","expanded","extra-expanded","ultra-expanded"]},
-
-"border-left-width":{values:[
-"medium","thick","thin"]},
-
-"box-shadow":{values:[
-"inset","none"]},
-
-"writing-mode":{values:[
-"horizontal-tb","vertical-rl","vertical-lr"]},
-
-"-webkit-writing-mode":{values:[
-"lr","rl","tb","lr-tb","rl-tb","tb-rl","horizontal-tb","vertical-rl","vertical-lr"]},
-
-"border-collapse":{values:[
-"collapse","separate"]},
-
-"page-break-inside":{values:[
-"auto","avoid"]},
-
-"border-top-width":{values:[
-"medium","thick","thin"]},
-
-"outline-color":{values:[
-"invert"]},
-
-"outline-style":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"cursor":{values:[
-"none","copy","auto","crosshair","default","pointer","move","vertical-text","cell","context-menu",
-"alias","progress","no-drop","not-allowed","-webkit-zoom-in","-webkit-zoom-out","e-resize","ne-resize",
-"nw-resize","n-resize","se-resize","sw-resize","s-resize","w-resize","ew-resize","ns-resize",
-"nesw-resize","nwse-resize","col-resize","row-resize","text","wait","help","all-scroll","-webkit-grab",
-"-webkit-grabbing"]},
-
-"border-width":{values:[
-"medium","thick","thin"]},
-
-"border-style":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"size":{values:[
-"a3","a4","a5","b4","b5","landscape","ledger","legal","letter","portrait"]},
-
-"background-size":{values:[
-"contain","cover"]},
-
-"direction":{values:[
-"ltr","rtl"]},
-
-"enable-background":{values:[
-"accumulate","new"]},
-
-"float":{values:[
-"none","left","right"]},
-
-"overflow-y":{values:[
-"hidden","auto","visible","overlay","scroll"]},
-
-"margin-bottom-collapse":{values:[
-"collapse","separate","discard"]},
-
-"box-reflect":{values:[
-"left","right","above","below"]},
-
-"overflow":{values:[
-"hidden","auto","visible","overlay","scroll"]},
-
-"contain":{values:[
-"none","strict","content","size","layout","style","paint"]},
-
-"text-rendering":{values:[
-"auto","optimizeSpeed","optimizeLegibility","geometricPrecision"]},
-
-"text-align":{values:[
-"-webkit-auto","start","end","left","right","center","justify","-webkit-left","-webkit-right","-webkit-center"]},
-
-"list-style-position":{values:[
-"outside","inside","hanging"]},
-
-"margin-bottom":{values:[
-"auto"]},
-
-"color-interpolation":{values:[
-"linearrgb"]},
-
-"background-origin":{values:[
-"border-box","content-box","padding-box"]},
-
-"word-wrap":{values:[
-"normal","break-word"]},
-
-"font-weight":{values:[
-"normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"]},
-
-"margin-before-collapse":{values:[
-"collapse","separate","discard"]},
-
-"text-transform":{values:[
-"none","capitalize","uppercase","lowercase"]},
-
-"border-right-style":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"border-left-style":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"-webkit-text-emphasis":{values:[
-"circle","filled","open","dot","double-circle","triangle","sesame"]},
-
-"font-style":{values:[
-"italic","oblique","normal"]},
-
-"speak":{values:[
-"none","normal","spell-out","digits","literal-punctuation","no-punctuation"]},
-
-"color-rendering":{values:[
-"auto","optimizeSpeed","optimizeQuality"]},
-
-"list-style-type":{values:[
-"none","inline","disc","circle","square","decimal","decimal-leading-zero","arabic-indic","binary","bengali",
-"cambodian","khmer","devanagari","gujarati","gurmukhi","kannada","lower-hexadecimal","lao","malayalam",
-"mongolian","myanmar","octal","oriya","persian","urdu","telugu","tibetan","thai","upper-hexadecimal",
-"lower-roman","upper-roman","lower-greek","lower-alpha","lower-latin","upper-alpha","upper-latin","afar",
-"ethiopic-halehame-aa-et","ethiopic-halehame-aa-er","amharic","ethiopic-halehame-am-et","amharic-abegede",
-"ethiopic-abegede-am-et","cjk-earthly-branch","cjk-heavenly-stem","ethiopic","ethiopic-halehame-gez",
-"ethiopic-abegede","ethiopic-abegede-gez","hangul-consonant","hangul","lower-norwegian","oromo",
-"ethiopic-halehame-om-et","sidama","ethiopic-halehame-sid-et","somali","ethiopic-halehame-so-et","tigre",
-"ethiopic-halehame-tig","tigrinya-er","ethiopic-halehame-ti-er","tigrinya-er-abegede",
-"ethiopic-abegede-ti-er","tigrinya-et","ethiopic-halehame-ti-et","tigrinya-et-abegede",
-"ethiopic-abegede-ti-et","upper-greek","upper-norwegian","asterisks","footnotes","hebrew","armenian",
-"lower-armenian","upper-armenian","georgian","cjk-ideographic","hiragana","katakana","hiragana-iroha",
-"katakana-iroha"]},
-
-"text-combine-upright":{values:[
-"none","all"]},
-
-"-webkit-text-combine":{values:[
-"none","horizontal"]},
-
-"text-orientation":{values:[
-"mixed","upright","sideways"]},
-
-"outline":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"font":{values:[
-"caption","icon","menu","message-box","small-caption","-webkit-mini-control","-webkit-small-control",
-"-webkit-control","status-bar","italic","oblique","small-caps","normal","bold","bolder","lighter",
-"100","200","300","400","500","600","700","800","900","xx-small","x-small","small","medium",
-"large","x-large","xx-large","-webkit-xxx-large","smaller","larger","serif","sans-serif","cursive",
-"fantasy","monospace","-webkit-body","-webkit-pictograph"]},
-
-"dominant-baseline":{values:[
-"middle","auto","central","text-before-edge","text-after-edge","ideographic","alphabetic","hanging",
-"mathematical","use-script","no-change","reset-size"]},
-
-"display":{values:[
-"none","inline","block","list-item","run-in","inline-block","table","inline-table",
-"table-row-group","table-header-group","table-footer-group","table-row","table-column-group",
-"table-column","table-cell","table-caption","-webkit-box","-webkit-inline-box",
-"flex","inline-flex","grid","inline-grid"]},
-
-"-webkit-text-emphasis-position":{values:[
-"over","under"]},
-
-"image-rendering":{values:[
-"auto","optimizeSpeed","optimizeQuality","pixelated"]},
-
-"alignment-baseline":{values:[
-"baseline","middle","auto","before-edge","after-edge","central","text-before-edge","text-after-edge",
-"ideographic","alphabetic","hanging","mathematical"]},
-
-"outline-width":{values:[
-"medium","thick","thin"]},
-
-"box-align":{values:[
-"baseline","center","stretch","start","end"]},
-
-"border-right-width":{values:[
-"medium","thick","thin"]},
-
-"border-top-style":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"line-height":{values:[
-"normal"]},
-
-"text-overflow":{values:[
-"clip","ellipsis"]},
-
-"overflow-wrap":{values:[
-"normal","break-word"]},
-
-"box-direction":{values:[
-"normal","reverse"]},
-
-"margin-after-collapse":{values:[
-"collapse","separate","discard"]},
-
-"page-break-before":{values:[
-"left","right","auto","always","avoid"]},
-
-"border-image":{values:[
-"repeat","stretch"]},
-
-"text-decoration":{values:[
-"none","blink","line-through","overline","underline"]},
-
-"position":{values:[
-"absolute","fixed","relative","static"]},
-
-"font-family":{values:[
-"serif","sans-serif","cursive","fantasy","monospace","-webkit-body","-webkit-pictograph"]},
-
-"text-overflow-mode":{values:[
-"clip","ellipsis"]},
-
-"border-bottom-style":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"unicode-bidi":{values:[
-"normal","bidi-override","embed","isolate","isolate-override","plaintext"]},
-
-"clip-rule":{values:[
-"nonzero","evenodd"]},
-
-"margin-left":{values:[
-"auto"]},
-
-"margin-top":{values:[
-"auto"]},
-
-"zoom":{values:[
-"normal","document","reset"]},
-
-"max-width":{values:[
-"none"]},
-
-"caption-side":{values:[
-"top","bottom"]},
-
-"empty-cells":{values:[
-"hide","show"]},
-
-"pointer-events":{values:[
-"none","all","auto","visible","visiblepainted","visiblefill","visiblestroke","painted","fill","stroke","bounding-box"]},
-
-"letter-spacing":{values:[
-"normal"]},
-
-"background-clip":{values:[
-"border-box","content-box","padding-box"]},
-
-"-webkit-font-smoothing":{values:[
-"none","auto","antialiased","subpixel-antialiased"]},
-
-"border":{values:[
-"none","hidden","inset","groove","ridge","outset","dotted","dashed","solid","double"]},
-
-"font-size":{values:[
-"xx-small","x-small","small","medium","large","x-large","xx-large","-webkit-xxx-large","smaller",
-"larger"]},
-
-"font-variant":{values:[
-"small-caps","normal"]},
-
-"vertical-align":{values:[
-"baseline","middle","sub","super","text-top","text-bottom","top","bottom","-webkit-baseline-middle"]},
-
-"white-space":{values:[
-"normal","nowrap","pre","pre-line","pre-wrap"]},
-
-"box-lines":{values:[
-"single","multiple"]},
-
-"page-break-after":{values:[
-"left","right","auto","always","avoid"]},
-
-"clip-path":{values:[
-"none"]},
-
-"margin":{values:[
-"auto"]},
-
-"margin-right":{values:[
-"auto"]},
-
-"word-break":{values:[
-"normal","break-all","break-word"]},
-
-"word-spacing":{values:[
-"normal"]},
-
-"-webkit-text-emphasis-style":{values:[
-"circle","filled","open","dot","double-circle","triangle","sesame"]},
-
-"transform":{values:[
-"scale","scaleX","scaleY","scale3d","rotate","rotateX","rotateY","rotateZ","rotate3d","skew","skewX","skewY",
-"translate","translateX","translateY","translateZ","translate3d","matrix","matrix3d","perspective"]},
-
-"image-resolution":{values:[
-"from-image","snap"]},
-
-"box-sizing":{values:[
-"content-box","border-box"]},
-
-"clip":{values:[
-"auto"]},
-
-"resize":{values:[
-"none","both","horizontal","vertical"]},
-
-"align-content":{values:[
-"flex-start","flex-end","center","space-between","space-around","stretch"]},
-
-"align-items":{values:[
-"flex-start","flex-end","center","baseline","stretch"]},
-
-"align-self":{values:[
-"auto","flex-start","flex-end","center","baseline","stretch"]},
-
-"flex-direction":{values:[
-"row","row-reverse","column","column-reverse"]},
-
-"justify-content":{values:[
-"flex-start","flex-end","center","space-between","space-around"]},
-
-"flex-wrap":{values:[
-"nowrap","wrap","wrap-reverse"]},
-
-"perspective":{values:[
-"none"]},
-
-"perspective-origin":{values:[
-"left","center","right","top","bottom"]},
-
-"transform-origin":{values:[
-"left","center","right","top","bottom"]},
-
-"transform-style":{values:[
-"flat","preserve-3d"]},
-
-"transition-timing-function":{values:[
-"ease","linear","ease-in","ease-out","ease-in-out","step-start","step-end","steps","cubic-bezier"]},
-
-"animation-timing-function":{values:[
-"ease","linear","ease-in","ease-out","ease-in-out","step-start","step-end","steps","cubic-bezier"]},
-
-"animation-direction":{values:[
-"normal","reverse","alternate","alternate-reverse"]},
-
-"animation-play-state":{values:[
-"running","paused"]},
-
-"animation-fill-mode":{values:[
-"none","forwards","backwards","both"]},
-
-"-webkit-backface-visibility":{values:[
-"visible","hidden"]},
-
-"-webkit-box-decoration-break":{values:[
-"slice","clone"]},
-
-"-webkit-column-break-after":{values:[
-"auto","always","avoid","left","right","page","column","avoid-page","avoid-column"]},
-
-"-webkit-column-break-before":{values:[
-"auto","always","avoid","left","right","page","column","avoid-page","avoid-column"]},
-
-"-webkit-column-break-inside":{values:[
-"auto","avoid","avoid-page","avoid-column"]},
-
-"-webkit-column-span":{values:[
-"none","all"]},
-
-"-webkit-column-count":{values:[
-"auto"]},
-
-"-webkit-column-gap":{values:[
-"normal"]},
-
-"-webkit-filter":{values:[
-"url","blur","brightness","contrast","drop-shadow","grayscale","hue-rotate","invert","opacity","saturate","sepia"]},
-
-"-webkit-line-break":{values:[
-"auto","loose","normal","strict"]},
-
-"-webkit-user-select":{values:[
-"none","text","all"]},
-
-"-webkit-user-modify":{values:[
-"read-only","read-write","read-write-plaintext-only"]},
-
-"text-align-last":{values:[
-"auto","start","end","left","right","center","justify"]},
-
-"-webkit-text-decoration-line":{values:[
-"none","underline","overline","line-through","blink"]},
-
-"-webkit-text-decoration-style":{values:[
-"solid","double","dotted","dashed","wavy"]},
-
-"-webkit-text-decoration-skip":{values:[
-"none","objects","spaces","ink","edges","box-decoration"]},
-
-"mix-blend-mode":{values:[
-"normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light",
-"difference","exclusion","hue","saturation","color","luminosity","unset"]},
-
-"background-blend-mode":{values:[
-"normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light",
-"difference","exclusion","hue","saturation","color","luminosity","unset"]}};
-
-
-
-
-WebInspector.CSSMetadata.Weight={
-"align-content":57,
-"align-items":129,
-"align-self":55,
-"animation":175,
-"animation-delay":114,
-"animation-direction":113,
-"animation-duration":137,
-"animation-fill-mode":132,
-"animation-iteration-count":124,
-"animation-name":139,
-"animation-play-state":104,
-"animation-timing-function":141,
-"backface-visibility":123,
-"background":260,
-"background-attachment":119,
-"background-clip":165,
-"background-color":259,
-"background-image":246,
-"background-origin":107,
-"background-position":237,
-"background-position-x":108,
-"background-position-y":93,
-"background-repeat":234,
-"background-size":203,
-"border":263,
-"border-bottom":233,
-"border-bottom-color":190,
-"border-bottom-left-radius":186,
-"border-bottom-right-radius":185,
-"border-bottom-style":150,
-"border-bottom-width":179,
-"border-collapse":209,
-"border-color":226,
-"border-image":89,
-"border-image-outset":50,
-"border-image-repeat":49,
-"border-image-slice":58,
-"border-image-source":32,
-"border-image-width":52,
-"border-left":221,
-"border-left-color":174,
-"border-left-style":142,
-"border-left-width":172,
-"border-radius":224,
-"border-right":223,
-"border-right-color":182,
-"border-right-style":130,
-"border-right-width":178,
-"border-spacing":198,
-"border-style":206,
-"border-top":231,
-"border-top-color":192,
-"border-top-left-radius":187,
-"border-top-right-radius":189,
-"border-top-style":152,
-"border-top-width":180,
-"border-width":214,
-"bottom":227,
-"box-shadow":213,
-"box-sizing":216,
-"caption-side":96,
-"clear":229,
-"clip":173,
-"clip-rule":5,
-"color":256,
-"content":219,
-"counter-increment":111,
-"counter-reset":110,
-"cursor":250,
-"direction":176,
-"display":262,
-"empty-cells":99,
-"fill":140,
-"fill-opacity":82,
-"fill-rule":22,
-"filter":160,
-"flex":133,
-"flex-basis":66,
-"flex-direction":85,
-"flex-flow":94,
-"flex-grow":112,
-"flex-shrink":61,
-"flex-wrap":68,
-"float":252,
-"font":211,
-"font-family":254,
-"font-kerning":18,
-"font-size":264,
-"font-stretch":77,
-"font-style":220,
-"font-variant":161,
-"font-weight":257,
-"height":266,
-"image-rendering":90,
-"justify-content":127,
-"left":248,
-"letter-spacing":188,
-"line-height":244,
-"list-style":215,
-"list-style-image":145,
-"list-style-position":149,
-"list-style-type":199,
-"margin":267,
-"margin-bottom":241,
-"margin-left":243,
-"margin-right":238,
-"margin-top":253,
-"mask":20,
-"max-height":205,
-"max-width":225,
-"min-height":217,
-"min-width":218,
-"object-fit":33,
-"opacity":251,
-"order":117,
-"orphans":146,
-"outline":222,
-"outline-color":153,
-"outline-offset":147,
-"outline-style":151,
-"outline-width":148,
-"overflow":255,
-"overflow-wrap":105,
-"overflow-x":184,
-"overflow-y":196,
-"padding":265,
-"padding-bottom":230,
-"padding-left":235,
-"padding-right":232,
-"padding-top":240,
-"page":8,
-"page-break-after":120,
-"page-break-before":69,
-"page-break-inside":121,
-"perspective":92,
-"perspective-origin":103,
-"pointer-events":183,
-"position":261,
-"quotes":158,
-"resize":168,
-"right":245,
-"shape-rendering":38,
-"size":64,
-"speak":118,
-"src":170,
-"stop-color":42,
-"stop-opacity":31,
-"stroke":98,
-"stroke-dasharray":36,
-"stroke-dashoffset":3,
-"stroke-linecap":30,
-"stroke-linejoin":21,
-"stroke-miterlimit":12,
-"stroke-opacity":34,
-"stroke-width":87,
-"table-layout":171,
-"tab-size":46,
-"text-align":260,
-"text-anchor":35,
-"text-decoration":247,
-"text-indent":207,
-"text-overflow":204,
-"text-rendering":155,
-"text-shadow":208,
-"text-transform":202,
-"top":258,
-"touch-action":80,
-"transform":181,
-"transform-origin":162,
-"transform-style":86,
-"transition":193,
-"transition-delay":134,
-"transition-duration":135,
-"transition-property":131,
-"transition-timing-function":122,
-"unicode-bidi":156,
-"unicode-range":136,
-"vertical-align":236,
-"visibility":242,
-"-webkit-appearance":191,
-"-webkit-backface-visibility":154,
-"-webkit-background-clip":164,
-"-webkit-background-origin":40,
-"-webkit-background-size":163,
-"-webkit-border-end":9,
-"-webkit-border-horizontal-spacing":81,
-"-webkit-border-image":75,
-"-webkit-border-radius":212,
-"-webkit-border-start":10,
-"-webkit-border-start-color":16,
-"-webkit-border-start-width":13,
-"-webkit-border-vertical-spacing":43,
-"-webkit-box-align":101,
-"-webkit-box-direction":51,
-"-webkit-box-flex":128,
-"-webkit-box-lines":2,
-"-webkit-box-ordinal-group":91,
-"-webkit-box-orient":144,
-"-webkit-box-pack":106,
-"-webkit-box-reflect":39,
-"-webkit-box-shadow":210,
-"-webkit-column-break-inside":60,
-"-webkit-column-count":84,
-"-webkit-column-gap":76,
-"-webkit-column-rule":25,
-"-webkit-column-rule-color":23,
-"-webkit-columns":44,
-"-webkit-column-span":29,
-"-webkit-column-width":47,
-"-webkit-filter":159,
-"-webkit-font-feature-settings":59,
-"-webkit-font-smoothing":177,
-"-webkit-highlight":1,
-"-webkit-line-break":45,
-"-webkit-line-clamp":126,
-"-webkit-margin-after":67,
-"-webkit-margin-before":70,
-"-webkit-margin-collapse":14,
-"-webkit-margin-end":65,
-"-webkit-margin-start":100,
-"-webkit-margin-top-collapse":78,
-"-webkit-mask":19,
-"-webkit-mask-box-image":72,
-"-webkit-mask-image":88,
-"-webkit-mask-position":54,
-"-webkit-mask-repeat":63,
-"-webkit-mask-size":79,
-"-webkit-padding-after":15,
-"-webkit-padding-before":28,
-"-webkit-padding-end":48,
-"-webkit-padding-start":73,
-"-webkit-print-color-adjust":83,
-"-webkit-rtl-ordering":7,
-"-webkit-tap-highlight-color":169,
-"-webkit-text-emphasis-color":11,
-"-webkit-text-fill-color":71,
-"-webkit-text-security":17,
-"-webkit-text-stroke":56,
-"-webkit-text-stroke-color":37,
-"-webkit-text-stroke-width":53,
-"-webkit-user-drag":95,
-"-webkit-user-modify":62,
-"-webkit-user-select":194,
-"-webkit-writing-mode":4,
-"white-space":228,
-"widows":115,
-"width":268,
-"will-change":74,
-"word-break":166,
-"word-spacing":157,
-"word-wrap":197,
-"writing-mode":41,
-"z-index":239,
-"zoom":200};
-
-
-},{}],108:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.CSSProperty=function(ownerStyle,index,name,value,important,disabled,parsedOk,implicit,text,range)
-{
-this.ownerStyle=ownerStyle;
-this.index=index;
-this.name=name;
-this.value=value;
-this.important=important;
-this.disabled=disabled;
-this.parsedOk=parsedOk;
-this.implicit=implicit;
-this.text=text;
-this.range=range?WebInspector.TextRange.fromObject(range):null;
-this._active=true;
-this._nameRange=null;
-this._valueRange=null;
-};
-
-
-
-
-
-
-
-WebInspector.CSSProperty.parsePayload=function(ownerStyle,index,payload)
-{
-
-
-
-
-
-var result=new WebInspector.CSSProperty(
-ownerStyle,index,payload.name,payload.value,payload.important||false,payload.disabled||false,"parsedOk"in payload?!!payload.parsedOk:true,!!payload.implicit,payload.text,payload.range);
-return result;
-};
-
-WebInspector.CSSProperty.prototype={
-_ensureRanges:function()
-{
-if(this._nameRange&&this._valueRange)
-return;
-var range=this.range;
-var text=this.text?new WebInspector.Text(this.text):null;
-if(!range||!text)
-return;
-
-var nameIndex=text.value().indexOf(this.name);
-var valueIndex=text.value().lastIndexOf(this.value);
-if(nameIndex===-1||valueIndex===-1||nameIndex>valueIndex)
-return;
-
-var nameSourceRange=new WebInspector.SourceRange(nameIndex,this.name.length);
-var valueSourceRange=new WebInspector.SourceRange(valueIndex,this.value.length);
-
-this._nameRange=rebase(text.toTextRange(nameSourceRange),range.startLine,range.startColumn);
-this._valueRange=rebase(text.toTextRange(valueSourceRange),range.startLine,range.startColumn);
-
-
-
-
-
-
-
-function rebase(oneLineRange,lineOffset,columnOffset)
-{
-if(oneLineRange.startLine===0){
-oneLineRange.startColumn+=columnOffset;
-oneLineRange.endColumn+=columnOffset;
-}
-oneLineRange.startLine+=lineOffset;
-oneLineRange.endLine+=lineOffset;
-return oneLineRange;
-}
-},
-
-
-
-
-nameRange:function()
-{
-this._ensureRanges();
-return this._nameRange;
-},
-
-
-
-
-valueRange:function()
-{
-this._ensureRanges();
-return this._valueRange;
-},
-
-
-
-
-rebase:function(edit)
-{
-if(this.ownerStyle.styleSheetId!==edit.styleSheetId)
-return;
-if(this.range)
-this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);
-},
-
-
-
-
-_setActive:function(active)
-{
-this._active=active;
-},
-
-get propertyText()
-{
-if(this.text!==undefined)
-return this.text;
-
-if(this.name==="")
-return"";
-return this.name+": "+this.value+(this.important?" !important":"")+";";
-},
-
-
-
-
-activeInStyle:function()
-{
-return this._active;
-},
-
-
-
-
-
-
-
-setText:function(propertyText,majorChange,overwrite)
-{
-if(!this.ownerStyle)
-return Promise.reject(new Error("No ownerStyle for property"));
-
-if(!this.ownerStyle.styleSheetId)
-return Promise.reject(new Error("No owner style id"));
-
-if(!this.range||!this.ownerStyle.range)
-return Promise.reject(new Error("Style not editable"));
-
-if(majorChange)
-WebInspector.userMetrics.actionTaken(WebInspector.UserMetrics.Action.StyleRuleEdited);
-
-if(overwrite&&propertyText===this.propertyText){
-if(majorChange)
-this.ownerStyle.cssModel().domModel().markUndoableState();
-return Promise.resolve(true);
-}
-
-var range=this.range.relativeTo(this.ownerStyle.range.startLine,this.ownerStyle.range.startColumn);
-var indentation=this.ownerStyle.cssText?this._detectIndentation(this.ownerStyle.cssText):WebInspector.moduleSetting("textEditorIndent").get();
-var endIndentation=this.ownerStyle.cssText?indentation.substring(0,this.ownerStyle.range.endColumn):"";
-var text=new WebInspector.Text(this.ownerStyle.cssText||"");
-var newStyleText=text.replaceRange(range,String.sprintf(";%s;",propertyText));
-
-return self.runtime.extension(WebInspector.TokenizerFactory).instance().
-then(this._formatStyle.bind(this,newStyleText,indentation,endIndentation)).
-then(setStyleText.bind(this));
-
-
-
-
-
-
-function setStyleText(styleText)
-{
-return this.ownerStyle.setText(styleText,majorChange);
-}
-},
-
-
-
-
-
-
-
-
-_formatStyle:function(styleText,indentation,endIndentation,tokenizerFactory)
-{
-if(indentation)
-indentation="\n"+indentation;
-var result="";
-var propertyText;
-var insideProperty=false;
-var tokenize=tokenizerFactory.createTokenizer("text/css");
-
-tokenize("*{"+styleText+"}",processToken);
-if(insideProperty)
-result+=propertyText;
-result=result.substring(2,result.length-1).trimRight();
-return result+(indentation?"\n"+endIndentation:"");
-
-
-
-
-
-
-
-function processToken(token,tokenType,column,newColumn)
-{
-if(!insideProperty){
-var disabledProperty=tokenType&&tokenType.includes("css-comment")&&isDisabledProperty(token);
-var isPropertyStart=tokenType&&(tokenType.includes("css-string")||tokenType.includes("css-meta")||tokenType.includes("css-property")||tokenType.includes("css-variable-2"));
-if(disabledProperty){
-result=result.trimRight()+indentation+token;
-}else if(isPropertyStart){
-insideProperty=true;
-propertyText=token;
-}else if(token!==";"){
-result+=token;
-}
-return;
-}
-
-if(token==="}"||token===";"){
-result=result.trimRight()+indentation+propertyText.trim()+";";
-insideProperty=false;
-if(token==="}")
-result+="}";
-}else{
-propertyText+=token;
-}
-}
-
-
-
-
-
-function isDisabledProperty(text)
-{
-var colon=text.indexOf(":");
-if(colon===-1)
-return false;
-var propertyName=text.substring(2,colon).trim();
-return WebInspector.cssMetadata().isCSSPropertyName(propertyName);
-}
-},
-
-
-
-
-
-_detectIndentation:function(text)
-{
-var lines=text.split("\n");
-if(lines.length<2)
-return"";
-return WebInspector.TextUtils.lineIndent(lines[1]);
-},
-
-
-
-
-
-
-
-setValue:function(newValue,majorChange,overwrite,userCallback)
-{
-var text=this.name+": "+newValue+(this.important?" !important":"")+";";
-this.setText(text,majorChange,overwrite).then(userCallback);
-},
-
-
-
-
-
-setDisabled:function(disabled)
-{
-if(!this.ownerStyle)
-return Promise.resolve(false);
-if(disabled===this.disabled)
-return Promise.resolve(true);
-var propertyText=this.text.trim();
-var text=disabled?"/* "+propertyText+" */":this.text.substring(2,propertyText.length-2).trim();
-return this.setText(text,true,true);
-}};
-
-
-},{}],109:[function(require,module,exports){
-
-
-
-
-
-
-
-
-WebInspector.CSSValue=function(payload)
-{
-this.text=payload.text;
-if(payload.range)
-this.range=WebInspector.TextRange.fromObject(payload.range);
-};
-
-WebInspector.CSSValue.prototype={
-
-
-
-rebase:function(edit)
-{
-if(!this.range)
-return;
-this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);
-}};
-
-
-
-
-
-
-
-WebInspector.CSSRule=function(cssModel,payload)
-{
-this._cssModel=cssModel;
-this.styleSheetId=payload.styleSheetId;
-
-if(this.styleSheetId){
-var styleSheetHeader=cssModel.styleSheetHeaderForId(this.styleSheetId);
-this.sourceURL=styleSheetHeader.sourceURL;
-}
-this.origin=payload.origin;
-this.style=new WebInspector.CSSStyleDeclaration(this._cssModel,this,payload.style,WebInspector.CSSStyleDeclaration.Type.Regular);
-};
-
-WebInspector.CSSRule.prototype={
-
-
-
-rebase:function(edit)
-{
-if(this.styleSheetId!==edit.styleSheetId)
-return;
-this.style.rebase(edit);
-},
-
-
-
-
-resourceURL:function()
-{
-if(!this.styleSheetId)
-return"";
-var styleSheetHeader=this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-return styleSheetHeader.resourceURL();
-},
-
-
-
-
-isUserAgent:function()
-{
-return this.origin===CSSAgent.StyleSheetOrigin.UserAgent;
-},
-
-
-
-
-isInjected:function()
-{
-return this.origin===CSSAgent.StyleSheetOrigin.Injected;
-},
-
-
-
-
-isViaInspector:function()
-{
-return this.origin===CSSAgent.StyleSheetOrigin.Inspector;
-},
-
-
-
-
-isRegular:function()
-{
-return this.origin===CSSAgent.StyleSheetOrigin.Regular;
-}};
-
-
-
-
-
-
-
-
-WebInspector.CSSStyleRule=function(cssModel,payload)
-{
-WebInspector.CSSRule.call(this,cssModel,payload);
-
-this._reinitializeSelectors(payload.selectorList);
-this.media=payload.media?WebInspector.CSSMedia.parseMediaArrayPayload(cssModel,payload.media):[];
-};
-
-
-
-
-
-
-WebInspector.CSSStyleRule.createDummyRule=function(cssModel,selectorText)
-{
-var dummyPayload={
-selectorList:{
-selectors:[{text:selectorText}]},
-
-style:{
-styleSheetId:"0",
-range:new WebInspector.TextRange(0,0,0,0),
-shorthandEntries:[],
-cssProperties:[]}};
-
-
-return new WebInspector.CSSStyleRule(cssModel,dummyPayload);
-};
-
-WebInspector.CSSStyleRule.prototype={
-
-
-
-_reinitializeSelectors:function(selectorList)
-{
-
-this.selectors=[];
-for(var i=0;i<selectorList.selectors.length;++i)
-this.selectors.push(new WebInspector.CSSValue(selectorList.selectors[i]));
-},
-
-
-
-
-
-setSelectorText:function(newSelector)
-{
-var styleSheetId=this.styleSheetId;
-if(!styleSheetId)
-throw"No rule stylesheet id";
-var range=this.selectorRange();
-if(!range)
-throw"Rule selector is not editable";
-return this._cssModel.setSelectorText(styleSheetId,range,newSelector);
-},
-
-
-
-
-selectorText:function()
-{
-return this.selectors.select("text").join(", ");
-},
-
-
-
-
-selectorRange:function()
-{
-var firstRange=this.selectors[0].range;
-if(!firstRange)
-return null;
-var lastRange=this.selectors.peekLast().range;
-return new WebInspector.TextRange(firstRange.startLine,firstRange.startColumn,lastRange.endLine,lastRange.endColumn);
-},
-
-
-
-
-
-lineNumberInSource:function(selectorIndex)
-{
-var selector=this.selectors[selectorIndex];
-if(!selector||!selector.range||!this.styleSheetId)
-return 0;
-var styleSheetHeader=this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-return styleSheetHeader.lineNumberInSource(selector.range.startLine);
-},
-
-
-
-
-
-columnNumberInSource:function(selectorIndex)
-{
-var selector=this.selectors[selectorIndex];
-if(!selector||!selector.range||!this.styleSheetId)
-return undefined;
-var styleSheetHeader=this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-console.assert(styleSheetHeader);
-return styleSheetHeader.columnNumberInSource(selector.range.startLine,selector.range.startColumn);
-},
-
-
-
-
-
-rebase:function(edit)
-{
-if(this.styleSheetId!==edit.styleSheetId)
-return;
-if(this.selectorRange().equal(edit.oldRange)){
-this._reinitializeSelectors(edit.payload);
-}else{
-for(var i=0;i<this.selectors.length;++i)
-this.selectors[i].rebase(edit);
-}
-for(var media of this.media)
-media.rebase(edit);
-
-WebInspector.CSSRule.prototype.rebase.call(this,edit);
-},
-
-__proto__:WebInspector.CSSRule.prototype};
-
-
-
-
-
-
-
-WebInspector.CSSKeyframesRule=function(cssModel,payload)
-{
-this._cssModel=cssModel;
-this._animationName=new WebInspector.CSSValue(payload.animationName);
-this._keyframes=payload.keyframes.map(keyframeRule=>new WebInspector.CSSKeyframeRule(cssModel,keyframeRule));
-};
-
-WebInspector.CSSKeyframesRule.prototype={
-
-
-
-name:function()
-{
-return this._animationName;
-},
-
-
-
-
-keyframes:function()
-{
-return this._keyframes;
-}};
-
-
-
-
-
-
-
-
-WebInspector.CSSKeyframeRule=function(cssModel,payload)
-{
-WebInspector.CSSRule.call(this,cssModel,payload);
-this._reinitializeKey(payload.keyText);
-};
-
-WebInspector.CSSKeyframeRule.prototype={
-
-
-
-key:function()
-{
-return this._keyText;
-},
-
-
-
-
-_reinitializeKey:function(payload)
-{
-this._keyText=new WebInspector.CSSValue(payload);
-},
-
-
-
-
-
-rebase:function(edit)
-{
-if(this.styleSheetId!==edit.styleSheetId||!this._keyText.range)
-return;
-if(edit.oldRange.equal(this._keyText.range))
-this._reinitializeKey(edit.payload);else
-
-this._keyText.rebase(edit);
-
-WebInspector.CSSRule.prototype.rebase.call(this,edit);
-},
-
-
-
-
-
-setKeyText:function(newKeyText)
-{
-var styleSheetId=this.styleSheetId;
-if(!styleSheetId)
-throw"No rule stylesheet id";
-var range=this._keyText.range;
-if(!range)
-throw"Keyframe key is not editable";
-return this._cssModel.setKeyframeKey(styleSheetId,range,newKeyText);
-},
-
-__proto__:WebInspector.CSSRule.prototype};
-
-
-},{}],110:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.CSSStyleDeclaration=function(cssModel,parentRule,payload,type)
-{
-this._cssModel=cssModel;
-this.parentRule=parentRule;
-this._reinitialize(payload);
-this.type=type;
-};
-
-
-WebInspector.CSSStyleDeclaration.Type={
-Regular:"Regular",
-Inline:"Inline",
-Attributes:"Attributes"};
-
-
-WebInspector.CSSStyleDeclaration.prototype={
-
-
-
-rebase:function(edit)
-{
-if(this.styleSheetId!==edit.styleSheetId||!this.range)
-return;
-if(edit.oldRange.equal(this.range)){
-this._reinitialize(edit.payload);
-}else{
-this.range=this.range.rebaseAfterTextEdit(edit.oldRange,edit.newRange);
-for(var i=0;i<this._allProperties.length;++i)
-this._allProperties[i].rebase(edit);
-}
-},
-
-
-
-
-_reinitialize:function(payload)
-{
-this.styleSheetId=payload.styleSheetId;
-this.range=payload.range?WebInspector.TextRange.fromObject(payload.range):null;
-
-var shorthandEntries=payload.shorthandEntries;
-
-this._shorthandValues=new Map();
-
-this._shorthandIsImportant=new Set();
-for(var i=0;i<shorthandEntries.length;++i){
-this._shorthandValues.set(shorthandEntries[i].name,shorthandEntries[i].value);
-if(shorthandEntries[i].important)
-this._shorthandIsImportant.add(shorthandEntries[i].name);
-}
-
-this._allProperties=[];
-for(var i=0;i<payload.cssProperties.length;++i){
-var property=WebInspector.CSSProperty.parsePayload(this,i,payload.cssProperties[i]);
-this._allProperties.push(property);
-}
-
-this._generateSyntheticPropertiesIfNeeded();
-this._computeInactiveProperties();
-
-this._activePropertyMap=new Map();
-for(var property of this._allProperties){
-if(!property.activeInStyle())
-continue;
-this._activePropertyMap.set(property.name,property);
-}
-
-this.cssText=payload.cssText;
-this._leadingProperties=null;
-},
-
-_generateSyntheticPropertiesIfNeeded:function()
-{
-if(this.range)
-return;
-
-if(!this._shorthandValues.size)
-return;
-
-var propertiesSet=new Set();
-for(var property of this._allProperties)
-propertiesSet.add(property.name);
-
-var generatedProperties=[];
-
-for(var property of this._allProperties){
-
-var shorthands=WebInspector.cssMetadata().shorthands(property.name)||[];
-for(var shorthand of shorthands){
-if(propertiesSet.has(shorthand))
-continue;
-var shorthandValue=this._shorthandValues.get(shorthand);
-if(!shorthandValue)
-continue;
-
-
-var shorthandImportance=!!this._shorthandIsImportant.has(shorthand);
-var shorthandProperty=new WebInspector.CSSProperty(this,this.allProperties.length,shorthand,shorthandValue,shorthandImportance,false,true,false);
-generatedProperties.push(shorthandProperty);
-propertiesSet.add(shorthand);
-}
-}
-this._allProperties=this._allProperties.concat(generatedProperties);
-},
-
-
-
-
-_computeLeadingProperties:function()
-{
-
-
-
-
-function propertyHasRange(property)
-{
-return!!property.range;
-}
-
-if(this.range)
-return this._allProperties.filter(propertyHasRange);
-
-var leadingProperties=[];
-for(var property of this._allProperties){
-var shorthands=WebInspector.cssMetadata().shorthands(property.name)||[];
-var belongToAnyShorthand=false;
-for(var shorthand of shorthands){
-if(this._shorthandValues.get(shorthand)){
-belongToAnyShorthand=true;
-break;
-}
-}
-if(!belongToAnyShorthand)
-leadingProperties.push(property);
-}
-
-return leadingProperties;
-},
-
-
-
-
-leadingProperties:function()
-{
-if(!this._leadingProperties)
-this._leadingProperties=this._computeLeadingProperties();
-return this._leadingProperties;
-},
-
-
-
-
-target:function()
-{
-return this._cssModel.target();
-},
-
-
-
-
-cssModel:function()
-{
-return this._cssModel;
-},
-
-_computeInactiveProperties:function()
-{
-var activeProperties={};
-for(var i=0;i<this._allProperties.length;++i){
-var property=this._allProperties[i];
-if(property.disabled||!property.parsedOk){
-property._setActive(false);
-continue;
-}
-var canonicalName=WebInspector.cssMetadata().canonicalPropertyName(property.name);
-var activeProperty=activeProperties[canonicalName];
-if(!activeProperty){
-activeProperties[canonicalName]=property;
-}else if(!activeProperty.important||property.important){
-activeProperty._setActive(false);
-activeProperties[canonicalName]=property;
-}else{
-property._setActive(false);
-}
-}
-},
-
-get allProperties()
-{
-return this._allProperties;
-},
-
-
-
-
-
-getPropertyValue:function(name)
-{
-var property=this._activePropertyMap.get(name);
-return property?property.value:"";
-},
-
-
-
-
-
-isPropertyImplicit:function(name)
-{
-var property=this._activePropertyMap.get(name);
-return property?property.implicit:"";
-},
-
-
-
-
-
-longhandProperties:function(name)
-{
-var longhands=WebInspector.cssMetadata().longhands(name);
-var result=[];
-for(var i=0;longhands&&i<longhands.length;++i){
-var property=this._activePropertyMap.get(longhands[i]);
-if(property)
-result.push(property);
-}
-return result;
-},
-
-
-
-
-
-propertyAt:function(index)
-{
-return index<this.allProperties.length?this.allProperties[index]:null;
-},
-
-
-
-
-pastLastSourcePropertyIndex:function()
-{
-for(var i=this.allProperties.length-1;i>=0;--i){
-if(this.allProperties[i].range)
-return i+1;
-}
-return 0;
-},
-
-
-
-
-
-_insertionRange:function(index)
-{
-var property=this.propertyAt(index);
-return property&&property.range?property.range.collapseToStart():this.range.collapseToEnd();
-},
-
-
-
-
-
-newBlankProperty:function(index)
-{
-index=typeof index==="undefined"?this.pastLastSourcePropertyIndex():index;
-var property=new WebInspector.CSSProperty(this,index,"","",false,false,true,false,"",this._insertionRange(index));
-return property;
-},
-
-
-
-
-
-
-setText:function(text,majorChange)
-{
-return this._cssModel.setStyleText(this.styleSheetId,this.range,text,majorChange);
-},
-
-
-
-
-
-
-
-insertPropertyAt:function(index,name,value,userCallback)
-{
-this.newBlankProperty(index).setText(name+": "+value+";",false,true).
-then(userCallback);
-},
-
-
-
-
-
-
-appendProperty:function(name,value,userCallback)
-{
-this.insertPropertyAt(this.allProperties.length,name,value,userCallback);
-}};
-
-
-},{}],111:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.NetworkManager=function(target)
-{
-WebInspector.SDKModel.call(this,WebInspector.NetworkManager,target);
-this._dispatcher=new WebInspector.NetworkDispatcher(this);
-this._target=target;
-this._networkAgent=target.networkAgent();
-target.registerNetworkDispatcher(this._dispatcher);
-if(WebInspector.moduleSetting("cacheDisabled").get())
-this._networkAgent.setCacheDisabled(true);
-if(WebInspector.moduleSetting("monitoringXHREnabled").get())
-this._networkAgent.setMonitoringXHREnabled(true);
-
-
-if(Runtime.queryParam("remoteFrontend")||Runtime.queryParam("ws"))
-this._networkAgent.enable(10000000,5000000);else
-
-this._networkAgent.enable();
-
-this._bypassServiceWorkerSetting=WebInspector.settings.createSetting("bypassServiceWorker",false);
-if(this._bypassServiceWorkerSetting.get())
-this._bypassServiceWorkerChanged();
-this._bypassServiceWorkerSetting.addChangeListener(this._bypassServiceWorkerChanged,this);
-
-WebInspector.moduleSetting("cacheDisabled").addChangeListener(this._cacheDisabledSettingChanged,this);
-};
-
-
-WebInspector.NetworkManager.Events={
-RequestStarted:Symbol("RequestStarted"),
-RequestUpdated:Symbol("RequestUpdated"),
-RequestFinished:Symbol("RequestFinished"),
-RequestUpdateDropped:Symbol("RequestUpdateDropped"),
-ResponseReceived:Symbol("ResponseReceived")};
-
-
-WebInspector.NetworkManager._MIMETypes={
-"text/html":{"document":true},
-"text/xml":{"document":true},
-"text/plain":{"document":true},
-"application/xhtml+xml":{"document":true},
-"image/svg+xml":{"document":true},
-"text/css":{"stylesheet":true},
-"text/xsl":{"stylesheet":true},
-"text/vtt":{"texttrack":true}};
-
-
-
-
-
-
-WebInspector.NetworkManager.fromTarget=function(target)
-{
-return target.model(WebInspector.NetworkManager);
-};
-
-
-WebInspector.NetworkManager.Conditions;
-
-WebInspector.NetworkManager.NoThrottlingConditions={title:WebInspector.UIString("No throttling"),download:-1,upload:-1,latency:0};
-
-WebInspector.NetworkManager.OfflineConditions={title:WebInspector.UIString("Offline"),download:0,upload:0,latency:0};
-
-
-
-
-
-
-WebInspector.NetworkManager._connectionType=function(conditions)
-{
-if(!conditions.download&&!conditions.upload)
-return NetworkAgent.ConnectionType.None;
-var types=WebInspector.NetworkManager._connectionTypes;
-if(!types){
-WebInspector.NetworkManager._connectionTypes=[];
-types=WebInspector.NetworkManager._connectionTypes;
-types.push(["2g",NetworkAgent.ConnectionType.Cellular2g]);
-types.push(["3g",NetworkAgent.ConnectionType.Cellular3g]);
-types.push(["4g",NetworkAgent.ConnectionType.Cellular4g]);
-types.push(["bluetooth",NetworkAgent.ConnectionType.Bluetooth]);
-types.push(["wifi",NetworkAgent.ConnectionType.Wifi]);
-types.push(["wimax",NetworkAgent.ConnectionType.Wimax]);
-}
-for(var type of types){
-if(conditions.title.toLowerCase().indexOf(type[0])!==-1)
-return type[1];
-}
-return NetworkAgent.ConnectionType.Other;
-};
-
-WebInspector.NetworkManager.prototype={
-
-
-
-
-inflightRequestForURL:function(url)
-{
-return this._dispatcher._inflightRequestsByURL[url];
-},
-
-
-
-
-_cacheDisabledSettingChanged:function(event)
-{
-var enabled=event.data;
-this._networkAgent.setCacheDisabled(enabled);
-},
-
-dispose:function()
-{
-WebInspector.moduleSetting("cacheDisabled").removeChangeListener(this._cacheDisabledSettingChanged,this);
-},
-
-
-
-
-bypassServiceWorkerSetting:function()
-{
-return this._bypassServiceWorkerSetting;
-},
-
-_bypassServiceWorkerChanged:function()
-{
-this._networkAgent.setBypassServiceWorker(this._bypassServiceWorkerSetting.get());
-},
-
-__proto__:WebInspector.SDKModel.prototype};
-
-
-
-
-
-
-WebInspector.NetworkDispatcher=function(manager)
-{
-this._manager=manager;
-this._inflightRequestsById={};
-this._inflightRequestsByURL={};
-};
-
-WebInspector.NetworkDispatcher.prototype={
-
-
-
-
-_headersMapToHeadersArray:function(headersMap)
-{
-var result=[];
-for(var name in headersMap){
-var values=headersMap[name].split("\n");
-for(var i=0;i<values.length;++i)
-result.push({name:name,value:values[i]});
-}
-return result;
-},
-
-
-
-
-
-_updateNetworkRequestWithRequest:function(networkRequest,request)
-{
-networkRequest.requestMethod=request.method;
-networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));
-networkRequest.requestFormData=request.postData;
-networkRequest.setInitialPriority(request.initialPriority);
-networkRequest.mixedContentType=request.mixedContentType||NetworkAgent.RequestMixedContentType.None;
-},
-
-
-
-
-
-_updateNetworkRequestWithResponse:function(networkRequest,response)
-{
-if(response.url&&networkRequest.url!==response.url)
-networkRequest.url=response.url;
-networkRequest.mimeType=response.mimeType;
-networkRequest.statusCode=response.status;
-networkRequest.statusText=response.statusText;
-networkRequest.responseHeaders=this._headersMapToHeadersArray(response.headers);
-if(response.encodedDataLength>=0)
-networkRequest.setTransferSize(response.encodedDataLength);
-if(response.headersText)
-networkRequest.responseHeadersText=response.headersText;
-if(response.requestHeaders){
-networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
-networkRequest.setRequestHeadersText(response.requestHeadersText||"");
-}
-
-networkRequest.connectionReused=response.connectionReused;
-networkRequest.connectionId=String(response.connectionId);
-if(response.remoteIPAddress)
-networkRequest.setRemoteAddress(response.remoteIPAddress,response.remotePort||-1);
-
-if(response.fromServiceWorker)
-networkRequest.fetchedViaServiceWorker=true;
-
-if(response.fromDiskCache)
-networkRequest.setFromDiskCache();
-networkRequest.timing=response.timing;
-
-networkRequest.protocol=response.protocol;
-
-networkRequest.setSecurityState(response.securityState);
-
-if(!this._mimeTypeIsConsistentWithType(networkRequest)){
-var consoleModel=this._manager._target.consoleModel;
-consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(),WebInspector.ConsoleMessage.MessageSource.Network,
-WebInspector.ConsoleMessage.MessageLevel.Log,
-WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".",networkRequest.resourceType().title(),networkRequest.mimeType,networkRequest.url),
-WebInspector.ConsoleMessage.MessageType.Log,
-"",
-0,
-0,
-networkRequest.requestId));
-}
-
-if(response.securityDetails)
-networkRequest.setSecurityDetails(response.securityDetails);
-},
-
-
-
-
-
-_mimeTypeIsConsistentWithType:function(networkRequest)
-{
-
-
-
-
-
-
-if(networkRequest.hasErrorStatusCode()||networkRequest.statusCode===304||networkRequest.statusCode===204)
-return true;
-
-var resourceType=networkRequest.resourceType();
-if(resourceType!==WebInspector.resourceTypes.Stylesheet&&
-resourceType!==WebInspector.resourceTypes.Document&&
-resourceType!==WebInspector.resourceTypes.TextTrack){
-return true;
-}
-
-if(!networkRequest.mimeType)
-return true;
-
-if(networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
-return resourceType.name()in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];
-
-return false;
-},
-
-
-
-
-
-
-
-resourceChangedPriority:function(requestId,newPriority,timestamp)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(networkRequest)
-networkRequest.setPriority(newPriority);
-},
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-requestWillBeSent:function(requestId,frameId,loaderId,documentURL,request,time,wallTime,initiator,redirectResponse,resourceType)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(networkRequest){
-
-if(!redirectResponse)
-return;
-this.responseReceived(requestId,frameId,loaderId,time,PageAgent.ResourceType.Other,redirectResponse);
-networkRequest=this._appendRedirect(requestId,time,request.url);
-}else
-networkRequest=this._createNetworkRequest(requestId,frameId,loaderId,request.url,documentURL,initiator);
-networkRequest.hasNetworkData=true;
-this._updateNetworkRequestWithRequest(networkRequest,request);
-networkRequest.setIssueTime(time,wallTime);
-networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);
-
-this._startNetworkRequest(networkRequest);
-},
-
-
-
-
-
-requestServedFromCache:function(requestId)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.setFromMemoryCache();
-},
-
-
-
-
-
-
-
-
-
-
-responseReceived:function(requestId,frameId,loaderId,time,resourceType,response)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest){
-
-var eventData={};
-eventData.url=response.url;
-eventData.frameId=frameId;
-eventData.loaderId=loaderId;
-eventData.resourceType=resourceType;
-eventData.mimeType=response.mimeType;
-this._manager.dispatchEventToListeners(WebInspector.NetworkManager.Events.RequestUpdateDropped,eventData);
-return;
-}
-
-networkRequest.responseReceivedTime=time;
-networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);
-
-this._updateNetworkRequestWithResponse(networkRequest,response);
-
-this._updateNetworkRequest(networkRequest);
-this._manager.dispatchEventToListeners(WebInspector.NetworkManager.Events.ResponseReceived,networkRequest);
-},
-
-
-
-
-
-
-
-
-dataReceived:function(requestId,time,dataLength,encodedDataLength)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.resourceSize+=dataLength;
-if(encodedDataLength!==-1)
-networkRequest.increaseTransferSize(encodedDataLength);
-networkRequest.endTime=time;
-
-this._updateNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-
-loadingFinished:function(requestId,finishTime,encodedDataLength)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-this._finishNetworkRequest(networkRequest,finishTime,encodedDataLength);
-},
-
-
-
-
-
-
-
-
-
-
-loadingFailed:function(requestId,time,resourceType,localizedDescription,canceled,blockedReason)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.failed=true;
-networkRequest.setResourceType(WebInspector.resourceTypes[resourceType]);
-networkRequest.canceled=canceled;
-if(blockedReason){
-networkRequest.setBlockedReason(blockedReason);
-if(blockedReason===NetworkAgent.BlockedReason.Inspector){
-var consoleModel=this._manager._target.consoleModel;
-consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(),WebInspector.ConsoleMessage.MessageSource.Network,
-WebInspector.ConsoleMessage.MessageLevel.Warning,
-WebInspector.UIString("Request was blocked by DevTools: \"%s\".",networkRequest.url),
-WebInspector.ConsoleMessage.MessageType.Log,
-"",
-0,
-0,
-networkRequest.requestId));
-}
-}
-networkRequest.localizedFailDescription=localizedDescription;
-this._finishNetworkRequest(networkRequest,time,-1);
-},
-
-
-
-
-
-
-
-webSocketCreated:function(requestId,requestURL,initiator)
-{
-var networkRequest=new WebInspector.NetworkRequest(this._manager._target,requestId,requestURL,"","","",initiator||null);
-networkRequest.setResourceType(WebInspector.resourceTypes.WebSocket);
-this._startNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-
-
-webSocketWillSendHandshakeRequest:function(requestId,time,wallTime,request)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.requestMethod="GET";
-networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));
-networkRequest.setIssueTime(time,wallTime);
-
-this._updateNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-
-webSocketHandshakeResponseReceived:function(requestId,time,response)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.statusCode=response.status;
-networkRequest.statusText=response.statusText;
-networkRequest.responseHeaders=this._headersMapToHeadersArray(response.headers);
-networkRequest.responseHeadersText=response.headersText;
-if(response.requestHeaders)
-networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
-if(response.requestHeadersText)
-networkRequest.setRequestHeadersText(response.requestHeadersText);
-networkRequest.responseReceivedTime=time;
-networkRequest.protocol="websocket";
-
-this._updateNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-
-webSocketFrameReceived:function(requestId,time,response)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.addFrame(response,time);
-networkRequest.responseReceivedTime=time;
-
-this._updateNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-
-webSocketFrameSent:function(requestId,time,response)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.addFrame(response,time,true);
-networkRequest.responseReceivedTime=time;
-
-this._updateNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-
-webSocketFrameError:function(requestId,time,errorMessage)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-
-networkRequest.addFrameError(errorMessage,time);
-networkRequest.responseReceivedTime=time;
-
-this._updateNetworkRequest(networkRequest);
-},
-
-
-
-
-
-
-webSocketClosed:function(requestId,time)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-this._finishNetworkRequest(networkRequest,time,-1);
-},
-
-
-
-
-
-
-
-
-
-eventSourceMessageReceived:function(requestId,time,eventName,eventId,data)
-{
-var networkRequest=this._inflightRequestsById[requestId];
-if(!networkRequest)
-return;
-networkRequest.addEventSourceMessage(time,eventName,eventId,data);
-},
-
-
-
-
-
-
-
-_appendRedirect:function(requestId,time,redirectURL)
-{
-var originalNetworkRequest=this._inflightRequestsById[requestId];
-var previousRedirects=originalNetworkRequest.redirects||[];
-originalNetworkRequest.requestId=requestId+":redirected."+previousRedirects.length;
-delete originalNetworkRequest.redirects;
-if(previousRedirects.length>0)
-originalNetworkRequest.redirectSource=previousRedirects[previousRedirects.length-1];
-this._finishNetworkRequest(originalNetworkRequest,time,-1);
-var newNetworkRequest=this._createNetworkRequest(requestId,originalNetworkRequest.frameId,originalNetworkRequest.loaderId,
-redirectURL,originalNetworkRequest.documentURL,originalNetworkRequest.initiator());
-newNetworkRequest.redirects=previousRedirects.concat(originalNetworkRequest);
-return newNetworkRequest;
-},
-
-
-
-
-_startNetworkRequest:function(networkRequest)
-{
-this._inflightRequestsById[networkRequest.requestId]=networkRequest;
-this._inflightRequestsByURL[networkRequest.url]=networkRequest;
-this._dispatchEventToListeners(WebInspector.NetworkManager.Events.RequestStarted,networkRequest);
-},
-
-
-
-
-_updateNetworkRequest:function(networkRequest)
-{
-this._dispatchEventToListeners(WebInspector.NetworkManager.Events.RequestUpdated,networkRequest);
-},
-
-
-
-
-
-
-_finishNetworkRequest:function(networkRequest,finishTime,encodedDataLength)
-{
-networkRequest.endTime=finishTime;
-networkRequest.finished=true;
-if(encodedDataLength>=0)
-networkRequest.setTransferSize(encodedDataLength);
-this._dispatchEventToListeners(WebInspector.NetworkManager.Events.RequestFinished,networkRequest);
-delete this._inflightRequestsById[networkRequest.requestId];
-delete this._inflightRequestsByURL[networkRequest.url];
-},
-
-
-
-
-
-_dispatchEventToListeners:function(eventType,networkRequest)
-{
-this._manager.dispatchEventToListeners(eventType,networkRequest);
-},
-
-
-
-
-
-
-
-
-
-_createNetworkRequest:function(requestId,frameId,loaderId,url,documentURL,initiator)
-{
-return new WebInspector.NetworkRequest(this._manager._target,requestId,url,documentURL,frameId,loaderId,initiator);
-}};
-
-
-
-
-
-
-
-
-WebInspector.MultitargetNetworkManager=function()
-{
-WebInspector.Object.call(this);
-WebInspector.targetManager.observeTargets(this);
-
-
-this._blockedURLs=new Set();
-this._blockedSetting=WebInspector.moduleSetting("blockedURLs");
-this._blockedSetting.addChangeListener(this._updateBlockedURLs,this);
-this._blockedSetting.set([]);
-this._updateBlockedURLs();
-
-this._userAgentOverride="";
-
-this._agents=new Set();
-
-this._networkConditions=WebInspector.NetworkManager.NoThrottlingConditions;
-};
-
-
-WebInspector.MultitargetNetworkManager.Events={
-ConditionsChanged:Symbol("ConditionsChanged"),
-UserAgentChanged:Symbol("UserAgentChanged")};
-
-
-
-
-
-
-WebInspector.MultitargetNetworkManager.patchUserAgentWithChromeVersion=function(uaString)
-{
-
-var chromeRegex=new RegExp("(?:^|\\W)Chrome/(\\S+)");
-var chromeMatch=navigator.userAgent.match(chromeRegex);
-if(chromeMatch&&chromeMatch.length>1)
-return String.sprintf(uaString,chromeMatch[1]);
-return uaString;
-};
-
-WebInspector.MultitargetNetworkManager.prototype={
-
-
-
-
-targetAdded:function(target)
-{
-var networkAgent=target.networkAgent();
-if(this._extraHeaders)
-networkAgent.setExtraHTTPHeaders(this._extraHeaders);
-if(this._currentUserAgent())
-networkAgent.setUserAgentOverride(this._currentUserAgent());
-for(var url of this._blockedURLs)
-networkAgent.addBlockedURL(url);
-this._agents.add(networkAgent);
-if(this.isThrottling())
-this._updateNetworkConditions(networkAgent);
-},
-
-
-
-
-
-targetRemoved:function(target)
-{
-this._agents.delete(target.networkAgent());
-},
-
-
-
-
-isThrottling:function()
-{
-return this._networkConditions.download>=0||this._networkConditions.upload>=0||this._networkConditions.latency>0;
-},
-
-
-
-
-isOffline:function()
-{
-return!this._networkConditions.download&&!this._networkConditions.upload;
-},
-
-
-
-
-setNetworkConditions:function(conditions)
-{
-this._networkConditions=conditions;
-for(var agent of this._agents)
-this._updateNetworkConditions(agent);
-this.dispatchEventToListeners(WebInspector.MultitargetNetworkManager.Events.ConditionsChanged);
-},
-
-
-
-
-networkConditions:function()
-{
-return this._networkConditions;
-},
-
-
-
-
-_updateNetworkConditions:function(networkAgent)
-{
-var conditions=this._networkConditions;
-if(!this.isThrottling()){
-networkAgent.emulateNetworkConditions(false,0,0,0);
-}else{
-networkAgent.emulateNetworkConditions(this.isOffline(),conditions.latency,conditions.download<0?0:conditions.download,conditions.upload<0?0:conditions.upload,WebInspector.NetworkManager._connectionType(conditions));
-}
-},
-
-
-
-
-setExtraHTTPHeaders:function(headers)
-{
-this._extraHeaders=headers;
-for(var target of WebInspector.targetManager.targets())
-target.networkAgent().setExtraHTTPHeaders(this._extraHeaders);
-},
-
-
-
-
-_currentUserAgent:function()
-{
-return this._customUserAgent?this._customUserAgent:this._userAgentOverride;
-},
-
-_updateUserAgentOverride:function()
-{
-var userAgent=this._currentUserAgent();
-WebInspector.ResourceLoader.targetUserAgent=userAgent;
-for(var target of WebInspector.targetManager.targets())
-target.networkAgent().setUserAgentOverride(userAgent);
-},
-
-
-
-
-setUserAgentOverride:function(userAgent)
-{
-if(this._userAgentOverride===userAgent)
-return;
-this._userAgentOverride=userAgent;
-if(!this._customUserAgent)
-this._updateUserAgentOverride();
-this.dispatchEventToListeners(WebInspector.MultitargetNetworkManager.Events.UserAgentChanged);
-},
-
-
-
-
-userAgentOverride:function()
-{
-return this._userAgentOverride;
-},
-
-
-
-
-setCustomUserAgentOverride:function(userAgent)
-{
-this._customUserAgent=userAgent;
-this._updateUserAgentOverride();
-},
-
-_updateBlockedURLs:function()
-{
-var blocked=this._blockedSetting.get();
-for(var url of blocked){
-if(!this._blockedURLs.has(url))
-this._addBlockedURL(url);
-}
-for(var url of this._blockedURLs){
-if(blocked.indexOf(url)===-1)
-this._removeBlockedURL(url);
-}
-},
-
-
-
-
-_addBlockedURL:function(url)
-{
-this._blockedURLs.add(url);
-for(var target of WebInspector.targetManager.targets())
-target.networkAgent().addBlockedURL(url);
-},
-
-
-
-
-_removeBlockedURL:function(url)
-{
-this._blockedURLs.delete(url);
-for(var target of WebInspector.targetManager.targets())
-target.networkAgent().removeBlockedURL(url);
-},
-
-clearBrowserCache:function()
-{
-for(var target of WebInspector.targetManager.targets())
-target.networkAgent().clearBrowserCache();
-},
-
-clearBrowserCookies:function()
-{
-for(var target of WebInspector.targetManager.targets())
-target.networkAgent().clearBrowserCookies();
-},
-
-
-
-
-
-getCertificate:function(origin,callback)
-{
-var target=WebInspector.targetManager.mainTarget();
-target.networkAgent().getCertificate(origin,mycallback);
-
-
-
-
-
-function mycallback(error,certificate)
-{
-callback(error?[]:certificate);
-}
-},
-
-
-
-
-
-loadResource:function(url,callback)
-{
-var headers={};
-
-var currentUserAgent=this._currentUserAgent();
-if(currentUserAgent)
-headers["User-Agent"]=currentUserAgent;
-
-if(WebInspector.moduleSetting("cacheDisabled").get())
-headers["Cache-Control"]="no-cache";
-
-WebInspector.ResourceLoader.load(url,headers,callback);
-},
-
-__proto__:WebInspector.Object.prototype};
-
-
-
-
-
-WebInspector.multitargetNetworkManager;
-
-},{}],112:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.NetworkRequest=function(target,requestId,url,documentURL,frameId,loaderId,initiator)
-{
-WebInspector.SDKObject.call(this,target);
-
-this._networkLog=WebInspector.NetworkLog.fromTarget(target);
-this._networkManager=WebInspector.NetworkManager.fromTarget(target);
-this._requestId=requestId;
-this.url=url;
-this._documentURL=documentURL;
-this._frameId=frameId;
-this._loaderId=loaderId;
-
-this._initiator=initiator;
-this._issueTime=-1;
-this._startTime=-1;
-this._endTime=-1;
-
-this._blockedReason=undefined;
-
-this.statusCode=0;
-this.statusText="";
-this.requestMethod="";
-this.requestTime=0;
-this.protocol="";
-
-this.mixedContentType=NetworkAgent.RequestMixedContentType.None;
-
-
-this._initialPriority=null;
-
-this._currentPriority=null;
-
-
-this._resourceType=WebInspector.resourceTypes.Other;
-this._contentEncoded=false;
-this._pendingContentCallbacks=[];
-
-this._frames=[];
-
-this._eventSourceMessages=[];
-
-this._responseHeaderValues={};
-
-this._remoteAddress="";
-
-
-this._securityState=SecurityAgent.SecurityState.Unknown;
-
-this._securityDetails=null;
-
-
-this.connectionId="0";
-};
-
-
-WebInspector.NetworkRequest.Events={
-FinishedLoading:Symbol("FinishedLoading"),
-TimingChanged:Symbol("TimingChanged"),
-RemoteAddressChanged:Symbol("RemoteAddressChanged"),
-RequestHeadersChanged:Symbol("RequestHeadersChanged"),
-ResponseHeadersChanged:Symbol("ResponseHeadersChanged"),
-WebsocketFrameAdded:Symbol("WebsocketFrameAdded"),
-EventSourceMessageAdded:Symbol("EventSourceMessageAdded")};
-
-
-
-WebInspector.NetworkRequest.InitiatorType={
-Other:"other",
-Parser:"parser",
-Redirect:"redirect",
-Script:"script"};
-
-
-
-WebInspector.NetworkRequest.NameValue;
-
-
-WebInspector.NetworkRequest.WebSocketFrameType={
-Send:"send",
-Receive:"receive",
-Error:"error"};
-
-
-
-WebInspector.NetworkRequest.WebSocketFrame;
-
-
-WebInspector.NetworkRequest.EventSourceMessage;
-
-WebInspector.NetworkRequest.prototype={
-
-
-
-
-indentityCompare:function(other)
-{
-if(this._requestId>other._requestId)
-return 1;
-if(this._requestId<other._requestId)
-return-1;
-return 0;
-},
-
-
-
-
-get requestId()
-{
-return this._requestId;
-},
-
-set requestId(requestId)
-{
-this._requestId=requestId;
-},
-
-
-
-
-get url()
-{
-return this._url;
-},
-
-set url(x)
-{
-if(this._url===x)
-return;
-
-this._url=x;
-this._parsedURL=new WebInspector.ParsedURL(x);
-delete this._queryString;
-delete this._parsedQueryParameters;
-delete this._name;
-delete this._path;
-},
-
-
-
-
-get documentURL()
-{
-return this._documentURL;
-},
-
-get parsedURL()
-{
-return this._parsedURL;
-},
-
-
-
-
-get frameId()
-{
-return this._frameId;
-},
-
-
-
-
-get loaderId()
-{
-return this._loaderId;
-},
-
-
-
-
-
-setRemoteAddress:function(ip,port)
-{
-this._remoteAddress=ip+":"+port;
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RemoteAddressChanged,this);
-},
-
-
-
-
-remoteAddress:function()
-{
-return this._remoteAddress;
-},
-
-
-
-
-securityState:function()
-{
-return this._securityState;
-},
-
-
-
-
-setSecurityState:function(securityState)
-{
-this._securityState=securityState;
-},
-
-
-
-
-securityDetails:function()
-{
-return this._securityDetails;
-},
-
-
-
-
-setSecurityDetails:function(securityDetails)
-{
-this._securityDetails=securityDetails;
-},
-
-
-
-
-get startTime()
-{
-return this._startTime||-1;
-},
-
-
-
-
-
-setIssueTime:function(monotonicTime,wallTime)
-{
-this._issueTime=monotonicTime;
-this._wallIssueTime=wallTime;
-this._startTime=monotonicTime;
-},
-
-
-
-
-issueTime:function()
-{
-return this._issueTime;
-},
-
-
-
-
-
-pseudoWallTime:function(monotonicTime)
-{
-return this._wallIssueTime?this._wallIssueTime-this._issueTime+monotonicTime:monotonicTime;
-},
-
-
-
-
-get responseReceivedTime()
-{
-return this._responseReceivedTime||-1;
-},
-
-set responseReceivedTime(x)
-{
-this._responseReceivedTime=x;
-},
-
-
-
-
-get endTime()
-{
-return this._endTime||-1;
-},
-
-set endTime(x)
-{
-if(this.timing&&this.timing.requestTime){
-
-this._endTime=Math.max(x,this.responseReceivedTime);
-}else{
-
-this._endTime=x;
-if(this._responseReceivedTime>x)
-this._responseReceivedTime=x;
-}
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged,this);
-},
-
-
-
-
-get duration()
-{
-if(this._endTime===-1||this._startTime===-1)
-return-1;
-return this._endTime-this._startTime;
-},
-
-
-
-
-get latency()
-{
-if(this._responseReceivedTime===-1||this._startTime===-1)
-return-1;
-return this._responseReceivedTime-this._startTime;
-},
-
-
-
-
-get resourceSize()
-{
-return this._resourceSize||0;
-},
-
-set resourceSize(x)
-{
-this._resourceSize=x;
-},
-
-
-
-
-get transferSize()
-{
-return this._transferSize||0;
-},
-
-
-
-
-increaseTransferSize:function(x)
-{
-this._transferSize=(this._transferSize||0)+x;
-},
-
-
-
-
-setTransferSize:function(x)
-{
-this._transferSize=x;
-},
-
-
-
-
-get finished()
-{
-return this._finished;
-},
-
-set finished(x)
-{
-if(this._finished===x)
-return;
-
-this._finished=x;
-
-if(x){
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading,this);
-if(this._pendingContentCallbacks.length)
-this._innerRequestContent();
-}
-},
-
-
-
-
-get failed()
-{
-return this._failed;
-},
-
-set failed(x)
-{
-this._failed=x;
-},
-
-
-
-
-get canceled()
-{
-return this._canceled;
-},
-
-set canceled(x)
-{
-this._canceled=x;
-},
-
-
-
-
-blockedReason:function()
-{
-return this._blockedReason;
-},
-
-
-
-
-setBlockedReason:function(reason)
-{
-this._blockedReason=reason;
-},
-
-
-
-
-wasBlocked:function()
-{
-return!!this._blockedReason;
-},
-
-
-
-
-cached:function()
-{
-return(!!this._fromMemoryCache||!!this._fromDiskCache)&&!this._transferSize;
-},
-
-
-
-
-cachedInMemory:function()
-{
-return!!this._fromMemoryCache&&!this._transferSize;
-},
-
-setFromMemoryCache:function()
-{
-this._fromMemoryCache=true;
-delete this._timing;
-},
-
-setFromDiskCache:function()
-{
-this._fromDiskCache=true;
-},
-
-
-
-
-get fetchedViaServiceWorker()
-{
-return this._fetchedViaServiceWorker;
-},
-
-set fetchedViaServiceWorker(x)
-{
-this._fetchedViaServiceWorker=x;
-},
-
-
-
-
-get timing()
-{
-return this._timing;
-},
-
-set timing(x)
-{
-if(x&&!this._fromMemoryCache){
-
-
-this._startTime=x.requestTime;
-this._responseReceivedTime=x.requestTime+x.receiveHeadersEnd/1000.0;
-
-this._timing=x;
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged,this);
-}
-},
-
-
-
-
-get mimeType()
-{
-return this._mimeType;
-},
-
-set mimeType(x)
-{
-this._mimeType=x;
-},
-
-
-
-
-get displayName()
-{
-return this._parsedURL.displayName;
-},
-
-
-
-
-name:function()
-{
-if(this._name)
-return this._name;
-this._parseNameAndPathFromURL();
-return this._name;
-},
-
-
-
-
-path:function()
-{
-if(this._path)
-return this._path;
-this._parseNameAndPathFromURL();
-return this._path;
-},
-
-_parseNameAndPathFromURL:function()
-{
-if(this._parsedURL.isDataURL()){
-this._name=this._parsedURL.dataURLDisplayName();
-this._path="";
-}else if(this._parsedURL.isAboutBlank()){
-this._name=this._parsedURL.url;
-this._path="";
-}else{
-this._path=this._parsedURL.host+this._parsedURL.folderPathComponents;
-
-var inspectedURL=this.target().inspectedURL().asParsedURL();
-this._path=this._path.trimURL(inspectedURL?inspectedURL.host:"");
-if(this._parsedURL.lastPathComponent||this._parsedURL.queryParams)
-this._name=this._parsedURL.lastPathComponent+(this._parsedURL.queryParams?"?"+this._parsedURL.queryParams:"");else
-if(this._parsedURL.folderPathComponents){
-this._name=this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf("/")+1)+"/";
-this._path=this._path.substring(0,this._path.lastIndexOf("/"));
-}else{
-this._name=this._parsedURL.host;
-this._path="";
-}
-}
-},
-
-
-
-
-get folder()
-{
-var path=this._parsedURL.path;
-var indexOfQuery=path.indexOf("?");
-if(indexOfQuery!==-1)
-path=path.substring(0,indexOfQuery);
-var lastSlashIndex=path.lastIndexOf("/");
-return lastSlashIndex!==-1?path.substring(0,lastSlashIndex):"";
-},
-
-
-
-
-resourceType:function()
-{
-return this._resourceType;
-},
-
-
-
-
-setResourceType:function(resourceType)
-{
-this._resourceType=resourceType;
-},
-
-
-
-
-get domain()
-{
-return this._parsedURL.host;
-},
-
-
-
-
-get scheme()
-{
-return this._parsedURL.scheme;
-},
-
-
-
-
-get redirectSource()
-{
-if(this.redirects&&this.redirects.length>0)
-return this.redirects[this.redirects.length-1];
-return this._redirectSource;
-},
-
-set redirectSource(x)
-{
-this._redirectSource=x;
-delete this._initiatorInfo;
-},
-
-
-
-
-requestHeaders:function()
-{
-return this._requestHeaders||[];
-},
-
-
-
-
-setRequestHeaders:function(headers)
-{
-this._requestHeaders=headers;
-delete this._requestCookies;
-
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
-},
-
-
-
-
-requestHeadersText:function()
-{
-return this._requestHeadersText;
-},
-
-
-
-
-setRequestHeadersText:function(text)
-{
-this._requestHeadersText=text;
-
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
-},
-
-
-
-
-
-requestHeaderValue:function(headerName)
-{
-return this._headerValue(this.requestHeaders(),headerName);
-},
-
-
-
-
-get requestCookies()
-{
-if(!this._requestCookies)
-this._requestCookies=WebInspector.CookieParser.parseCookie(this.target(),this.requestHeaderValue("Cookie"));
-return this._requestCookies;
-},
-
-
-
-
-get requestFormData()
-{
-return this._requestFormData;
-},
-
-set requestFormData(x)
-{
-this._requestFormData=x;
-delete this._parsedFormParameters;
-},
-
-
-
-
-requestHttpVersion:function()
-{
-var headersText=this.requestHeadersText();
-if(!headersText)
-return this.requestHeaderValue("version")||this.requestHeaderValue(":version")||"unknown";
-var firstLine=headersText.split(/\r\n/)[0];
-var match=firstLine.match(/(HTTP\/\d+\.\d+)$/);
-return match?match[1]:"HTTP/0.9";
-},
-
-
-
-
-get responseHeaders()
-{
-return this._responseHeaders||[];
-},
-
-set responseHeaders(x)
-{
-this._responseHeaders=x;
-delete this._sortedResponseHeaders;
-delete this._serverTimings;
-delete this._responseCookies;
-this._responseHeaderValues={};
-
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
-},
-
-
-
-
-get responseHeadersText()
-{
-return this._responseHeadersText;
-},
-
-set responseHeadersText(x)
-{
-this._responseHeadersText=x;
-
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
-},
-
-
-
-
-get sortedResponseHeaders()
-{
-if(this._sortedResponseHeaders!==undefined)
-return this._sortedResponseHeaders;
-
-this._sortedResponseHeaders=this.responseHeaders.slice();
-this._sortedResponseHeaders.sort(function(a,b){return a.name.toLowerCase().compareTo(b.name.toLowerCase());});
-return this._sortedResponseHeaders;
-},
-
-
-
-
-
-responseHeaderValue:function(headerName)
-{
-var value=this._responseHeaderValues[headerName];
-if(value===undefined){
-value=this._headerValue(this.responseHeaders,headerName);
-this._responseHeaderValues[headerName]=value!==undefined?value:null;
-}
-return value!==null?value:undefined;
-},
-
-
-
-
-get responseCookies()
-{
-if(!this._responseCookies)
-this._responseCookies=WebInspector.CookieParser.parseSetCookie(this.target(),this.responseHeaderValue("Set-Cookie"));
-return this._responseCookies;
-},
-
-
-
-
-get serverTimings()
-{
-if(typeof this._serverTimings==="undefined")
-this._serverTimings=WebInspector.ServerTiming.parseHeaders(this.responseHeaders);
-return this._serverTimings;
-},
-
-
-
-
-queryString:function()
-{
-if(this._queryString!==undefined)
-return this._queryString;
-
-var queryString=null;
-var url=this.url;
-var questionMarkPosition=url.indexOf("?");
-if(questionMarkPosition!==-1){
-queryString=url.substring(questionMarkPosition+1);
-var hashSignPosition=queryString.indexOf("#");
-if(hashSignPosition!==-1)
-queryString=queryString.substring(0,hashSignPosition);
-}
-this._queryString=queryString;
-return this._queryString;
-},
-
-
-
-
-get queryParameters()
-{
-if(this._parsedQueryParameters)
-return this._parsedQueryParameters;
-var queryString=this.queryString();
-if(!queryString)
-return null;
-this._parsedQueryParameters=this._parseParameters(queryString);
-return this._parsedQueryParameters;
-},
-
-
-
-
-get formParameters()
-{
-if(this._parsedFormParameters)
-return this._parsedFormParameters;
-if(!this.requestFormData)
-return null;
-var requestContentType=this.requestContentType();
-if(!requestContentType||!requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
-return null;
-this._parsedFormParameters=this._parseParameters(this.requestFormData);
-return this._parsedFormParameters;
-},
-
-
-
-
-responseHttpVersion:function()
-{
-var headersText=this._responseHeadersText;
-if(!headersText)
-return this.responseHeaderValue("version")||this.responseHeaderValue(":version")||"unknown";
-var firstLine=headersText.split(/\r\n/)[0];
-var match=firstLine.match(/^(HTTP\/\d+\.\d+)/);
-return match?match[1]:"HTTP/0.9";
-},
-
-
-
-
-
-_parseParameters:function(queryString)
-{
-function parseNameValue(pair)
-{
-var position=pair.indexOf("=");
-if(position===-1)
-return{name:pair,value:""};else
-
-return{name:pair.substring(0,position),value:pair.substring(position+1)};
-}
-return queryString.split("&").map(parseNameValue);
-},
-
-
-
-
-
-
-_headerValue:function(headers,headerName)
-{
-headerName=headerName.toLowerCase();
-
-var values=[];
-for(var i=0;i<headers.length;++i){
-if(headers[i].name.toLowerCase()===headerName)
-values.push(headers[i].value);
-}
-if(!values.length)
-return undefined;
-
-if(headerName==="set-cookie")
-return values.join("\n");
-return values.join(", ");
-},
-
-
-
-
-get content()
-{
-return this._content;
-},
-
-
-
-
-contentError:function()
-{
-return this._contentError;
-},
-
-
-
-
-get contentEncoded()
-{
-return this._contentEncoded;
-},
-
-
-
-
-
-contentURL:function()
-{
-return this._url;
-},
-
-
-
-
-
-contentType:function()
-{
-return this._resourceType;
-},
-
-
-
-
-
-requestContent:function()
-{
-
-
-
-if(this._resourceType===WebInspector.resourceTypes.WebSocket)
-return Promise.resolve(null);
-if(typeof this._content!=="undefined")
-return Promise.resolve(this.content||null);
-var callback;
-var promise=new Promise(fulfill=>callback=fulfill);
-this._pendingContentCallbacks.push(callback);
-if(this.finished)
-this._innerRequestContent();
-return promise;
-},
-
-
-
-
-
-
-
-
-searchInContent:function(query,caseSensitive,isRegex,callback)
-{
-callback([]);
-},
-
-
-
-
-isHttpFamily:function()
-{
-return!!this.url.match(/^https?:/i);
-},
-
-
-
-
-requestContentType:function()
-{
-return this.requestHeaderValue("Content-Type");
-},
-
-
-
-
-hasErrorStatusCode:function()
-{
-return this.statusCode>=400;
-},
-
-
-
-
-setInitialPriority:function(priority)
-{
-this._initialPriority=priority;
-},
-
-
-
-
-initialPriority:function()
-{
-return this._initialPriority;
-},
-
-
-
-
-setPriority:function(priority)
-{
-this._currentPriority=priority;
-},
-
-
-
-
-priority:function()
-{
-return this._currentPriority||this._initialPriority||null;
-},
-
-
-
-
-populateImageSource:function(image)
-{
-
-
-
-
-function onResourceContent(content)
-{
-var imageSrc=WebInspector.ContentProvider.contentAsDataURL(content,this._mimeType,true);
-if(imageSrc===null)
-imageSrc=this._url;
-image.src=imageSrc;
-}
-
-this.requestContent().then(onResourceContent.bind(this));
-},
-
-
-
-
-asDataURL:function()
-{
-var content=this._content;
-var charset=null;
-if(!this._contentEncoded){
-content=content.toBase64();
-charset="utf-8";
-}
-return WebInspector.ContentProvider.contentAsDataURL(content,this.mimeType,true,charset);
-},
-
-_innerRequestContent:function()
-{
-if(this._contentRequested)
-return;
-this._contentRequested=true;
-
-
-
-
-
-
-
-function onResourceContent(error,content,contentEncoded)
-{
-this._content=error?null:content;
-this._contentError=error;
-this._contentEncoded=contentEncoded;
-var callbacks=this._pendingContentCallbacks.slice();
-for(var i=0;i<callbacks.length;++i)
-callbacks[i](this._content);
-this._pendingContentCallbacks.length=0;
-delete this._contentRequested;
-}
-this.target().networkAgent().getResponseBody(this._requestId,onResourceContent.bind(this));
-},
-
-
-
-
-initiator:function()
-{
-return this._initiator;
-},
-
-
-
-
-initiatorInfo:function()
-{
-if(this._initiatorInfo)
-return this._initiatorInfo;
-
-var type=WebInspector.NetworkRequest.InitiatorType.Other;
-var url="";
-var lineNumber=-Infinity;
-var columnNumber=-Infinity;
-var scriptId=null;
-var initiator=this._initiator;
-
-if(this.redirectSource){
-type=WebInspector.NetworkRequest.InitiatorType.Redirect;
-url=this.redirectSource.url;
-}else if(initiator){
-if(initiator.type===NetworkAgent.InitiatorType.Parser){
-type=WebInspector.NetworkRequest.InitiatorType.Parser;
-url=initiator.url?initiator.url:url;
-lineNumber=initiator.lineNumber?initiator.lineNumber:lineNumber;
-}else if(initiator.type===NetworkAgent.InitiatorType.Script){
-for(var stack=initiator.stack;stack;stack=stack.parent){
-var topFrame=stack.callFrames.length?stack.callFrames[0]:null;
-if(!topFrame)
-continue;
-type=WebInspector.NetworkRequest.InitiatorType.Script;
-url=topFrame.url||WebInspector.UIString("<anonymous>");
-lineNumber=topFrame.lineNumber;
-columnNumber=topFrame.columnNumber;
-scriptId=topFrame.scriptId;
-break;
-}
-}
-}
-
-this._initiatorInfo={type:type,url:url,lineNumber:lineNumber,columnNumber:columnNumber,scriptId:scriptId};
-return this._initiatorInfo;
-},
-
-
-
-
-initiatorRequest:function()
-{
-if(this._initiatorRequest===undefined)
-this._initiatorRequest=this._networkLog.requestForURL(this.initiatorInfo().url);
-return this._initiatorRequest;
-},
-
-
-
-
-initiatorChain:function()
-{
-if(this._initiatorChain)
-return this._initiatorChain;
-this._initiatorChain=new Set();
-var request=this;
-while(request){
-this._initiatorChain.add(request);
-request=request.initiatorRequest();
-}
-return this._initiatorChain;
-},
-
-
-
-
-frames:function()
-{
-return this._frames;
-},
-
-
-
-
-
-addFrameError:function(errorMessage,time)
-{
-this._addFrame({type:WebInspector.NetworkRequest.WebSocketFrameType.Error,text:errorMessage,time:this.pseudoWallTime(time),opCode:-1,mask:false});
-},
-
-
-
-
-
-
-addFrame:function(response,time,sent)
-{
-var type=sent?WebInspector.NetworkRequest.WebSocketFrameType.Send:WebInspector.NetworkRequest.WebSocketFrameType.Receive;
-this._addFrame({type:type,text:response.payloadData,time:this.pseudoWallTime(time),opCode:response.opcode,mask:response.mask});
-},
-
-
-
-
-_addFrame:function(frame)
-{
-this._frames.push(frame);
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.WebsocketFrameAdded,frame);
-},
-
-
-
-
-eventSourceMessages:function()
-{
-return this._eventSourceMessages;
-},
-
-
-
-
-
-
-
-addEventSourceMessage:function(time,eventName,eventId,data)
-{
-var message={time:this.pseudoWallTime(time),eventName:eventName,eventId:eventId,data:data};
-this._eventSourceMessages.push(message);
-this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.EventSourceMessageAdded,message);
-},
-
-replayXHR:function()
-{
-this.target().networkAgent().replayXHR(this.requestId);
-},
-
-
-
-
-networkLog:function()
-{
-return this._networkLog;
-},
-
-
-
-
-networkManager:function()
-{
-return this._networkManager;
-},
-
-__proto__:WebInspector.SDKObject.prototype};
-
-
-},{}],113:[function(require,module,exports){
-
-
-
-
-
-
-
-
-WebInspector.ProfileNode=function(callFrame)
-{
-
-this.callFrame=callFrame;
-
-this.callUID=`${this.callFrame.functionName}@${this.callFrame.scriptId}:${this.callFrame.lineNumber}`;
-
-this.self=0;
-
-this.total=0;
-
-this.id=0;
-
-this.parent=null;
-
-this.children=[];
-};
-
-WebInspector.ProfileNode.prototype={
-
-
-
-get functionName()
-{
-return this.callFrame.functionName;
-},
-
-
-
-
-get scriptId()
-{
-return this.callFrame.scriptId;
-},
-
-
-
-
-get url()
-{
-return this.callFrame.url;
-},
-
-
-
-
-get lineNumber()
-{
-return this.callFrame.lineNumber;
-},
-
-
-
-
-get columnNumber()
-{
-return this.callFrame.columnNumber;
-}};
-
-
-
-
-
-
-WebInspector.ProfileTreeModel=function(root)
-{
-this.root=root;
-this._assignDepthsAndParents();
-this.total=this._calculateTotals(this.root);
-};
-
-WebInspector.ProfileTreeModel.prototype={
-_assignDepthsAndParents:function()
-{
-var root=this.root;
-root.depth=-1;
-root.parent=null;
-this.maxDepth=0;
-var nodesToTraverse=[root];
-while(nodesToTraverse.length){
-var parent=nodesToTraverse.pop();
-var depth=parent.depth+1;
-if(depth>this.maxDepth)
-this.maxDepth=depth;
-var children=parent.children;
-var length=children.length;
-for(var i=0;i<length;++i){
-var child=children[i];
-child.depth=depth;
-child.parent=parent;
-if(child.children.length)
-nodesToTraverse.push(child);
-}
-}
-},
-
-
-
-
-
-_calculateTotals:function(root)
-{
-var nodesToTraverse=[root];
-var dfsList=[];
-while(nodesToTraverse.length){
-var node=nodesToTraverse.pop();
-node.total=node.self;
-dfsList.push(node);
-nodesToTraverse.push(...node.children);
-}
-while(dfsList.length>1){
-var node=dfsList.pop();
-node.parent.total+=node.total;
-}
-return root.total;
-}};
-
-
-},{}],114:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.Target=function(targetManager,name,capabilitiesMask,connection,parentTarget)
-{
-Protocol.Agents.call(this,connection.agentsMap());
-this._targetManager=targetManager;
-this._name=name;
-this._inspectedURL="";
-this._capabilitiesMask=capabilitiesMask;
-this._connection=connection;
-this._parentTarget=parentTarget;
-connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected,this._onDisconnect,this);
-this._id=WebInspector.Target._nextId++;
-
-
-this._modelByConstructor=new Map();
-};
-
-
-
-
-WebInspector.Target.Capability={
-Browser:1,
-DOM:2,
-JS:4,
-Log:8,
-Network:16,
-Worker:32};
-
-
-WebInspector.Target._nextId=1;
-
-WebInspector.Target.prototype={
-
-
-
-id:function()
-{
-return this._id;
-},
-
-
-
-
-name:function()
-{
-return this._name;
-},
-
-
-
-
-targetManager:function()
-{
-return this._targetManager;
-},
-
-
-
-
-
-hasAllCapabilities:function(capabilitiesMask)
-{
-return(this._capabilitiesMask&capabilitiesMask)===capabilitiesMask;
-},
-
-
-
-
-
-connection:function()
-{
-return this._connection;
-},
-
-
-
-
-
-decorateLabel:function(label)
-{
-return!this.hasBrowserCapability()?"\u2699 "+label:label;
-},
-
-
-
-
-
-
-registerDispatcher:function(domain,dispatcher)
-{
-this._connection.registerDispatcher(domain,dispatcher);
-},
-
-
-
-
-hasBrowserCapability:function()
-{
-return this.hasAllCapabilities(WebInspector.Target.Capability.Browser);
-},
-
-
-
-
-hasJSCapability:function()
-{
-return this.hasAllCapabilities(WebInspector.Target.Capability.JS);
-},
-
-
-
-
-hasLogCapability:function()
-{
-return this.hasAllCapabilities(WebInspector.Target.Capability.Log);
-},
-
-
-
-
-hasNetworkCapability:function()
-{
-return this.hasAllCapabilities(WebInspector.Target.Capability.Network);
-},
-
-
-
-
-hasWorkerCapability:function()
-{
-return this.hasAllCapabilities(WebInspector.Target.Capability.Worker);
-},
-
-
-
-
-hasDOMCapability:function()
-{
-return this.hasAllCapabilities(WebInspector.Target.Capability.DOM);
-},
-
-
-
-
-parentTarget:function()
-{
-return this._parentTarget;
-},
-
-_onDisconnect:function()
-{
-this._targetManager.removeTarget(this);
-this._dispose();
-},
-
-_dispose:function()
-{
-this._targetManager.dispatchEventToListeners(WebInspector.TargetManager.Events.TargetDisposed,this);
-if(this.workerManager)
-this.workerManager.dispose();
-},
-
-
-
-
-isDetached:function()
-{
-return this._connection.isClosed();
-},
-
-
-
-
-
-model:function(modelClass)
-{
-return this._modelByConstructor.get(modelClass)||null;
-},
-
-
-
-
-models:function()
-{
-return this._modelByConstructor.valuesArray();
-},
-
-
-
-
-inspectedURL:function()
-{
-return this._inspectedURL;
-},
-
-
-
-
-setInspectedURL:function(inspectedURL)
-{
-this._inspectedURL=inspectedURL;
-InspectorFrontendHost.inspectedURLChanged(inspectedURL||"");
-this._targetManager.dispatchEventToListeners(WebInspector.TargetManager.Events.InspectedURLChanged,this);
-},
-
-__proto__:Protocol.Agents.prototype};
-
-
-
-
-
-
-
-WebInspector.SDKObject=function(target)
-{
-WebInspector.Object.call(this);
-this._target=target;
-};
-
-WebInspector.SDKObject.prototype={
-
-
-
-target:function()
-{
-return this._target;
-},
-
-__proto__:WebInspector.Object.prototype};
-
-
-
-
-
-
-
-
-WebInspector.SDKModel=function(modelClass,target)
-{
-WebInspector.SDKObject.call(this,target);
-target._modelByConstructor.set(modelClass,this);
-WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.TargetDisposed,this._targetDisposed,this);
-};
-
-WebInspector.SDKModel.prototype={
-
-
-
-suspendModel:function()
-{
-return Promise.resolve();
-},
-
-
-
-
-resumeModel:function()
-{
-return Promise.resolve();
-},
-
-dispose:function(){},
-
-
-
-
-_targetDisposed:function(event)
-{
-var target=event.data;
-if(target!==this._target)
-return;
-this.dispose();
-WebInspector.targetManager.removeEventListener(WebInspector.TargetManager.Events.TargetDisposed,this._targetDisposed,this);
-},
-
-__proto__:WebInspector.SDKObject.prototype};
-
-
-},{}],115:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-WebInspector.TargetManager=function()
-{
-WebInspector.Object.call(this);
-
-this._targets=[];
-
-this._observers=[];
-this._observerCapabiliesMaskSymbol=Symbol("observerCapabilitiesMask");
-
-this._modelListeners=new Map();
-this._isSuspended=false;
-};
-
-
-WebInspector.TargetManager.Events={
-InspectedURLChanged:Symbol("InspectedURLChanged"),
-MainFrameNavigated:Symbol("MainFrameNavigated"),
-Load:Symbol("Load"),
-PageReloadRequested:Symbol("PageReloadRequested"),
-WillReloadPage:Symbol("WillReloadPage"),
-TargetDisposed:Symbol("TargetDisposed"),
-SuspendStateChanged:Symbol("SuspendStateChanged")};
-
-
-WebInspector.TargetManager._listenersSymbol=Symbol("WebInspector.TargetManager.Listeners");
-
-WebInspector.TargetManager.prototype={
-suspendAllTargets:function()
-{
-if(this._isSuspended)
-return;
-this._isSuspended=true;
-this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendStateChanged);
-
-for(var i=0;i<this._targets.length;++i){
-for(var model of this._targets[i].models())
-model.suspendModel();
-}
-},
-
-
-
-
-resumeAllTargets:function()
-{
-if(!this._isSuspended)
-throw new Error("Not suspended");
-this._isSuspended=false;
-this.dispatchEventToListeners(WebInspector.TargetManager.Events.SuspendStateChanged);
-
-var promises=[];
-for(var i=0;i<this._targets.length;++i){
-for(var model of this._targets[i].models())
-promises.push(model.resumeModel());
-}
-return Promise.all(promises);
-},
-
-suspendAndResumeAllTargets:function()
-{
-this.suspendAllTargets();
-this.resumeAllTargets();
-},
-
-
-
-
-allTargetsSuspended:function()
-{
-return this._isSuspended;
-},
-
-
-
-
-inspectedURL:function()
-{
-return this._targets[0]?this._targets[0].inspectedURL():"";
-},
-
-
-
-
-
-_redispatchEvent:function(eventName,event)
-{
-this.dispatchEventToListeners(eventName,event.data);
-},
-
-
-
-
-
-reloadPage:function(bypassCache,injectedScript)
-{
-if(!this._targets.length)
-return;
-
-var resourceTreeModel=WebInspector.ResourceTreeModel.fromTarget(this._targets[0]);
-if(!resourceTreeModel)
-return;
-
-resourceTreeModel.reloadPage(bypassCache,injectedScript);
-},
-
-
-
-
-
-
-
-addModelListener:function(modelClass,eventType,listener,thisObject)
-{
-for(var i=0;i<this._targets.length;++i){
-var model=this._targets[i].model(modelClass);
-if(model)
-model.addEventListener(eventType,listener,thisObject);
-}
-if(!this._modelListeners.has(eventType))
-this._modelListeners.set(eventType,[]);
-this._modelListeners.get(eventType).push({modelClass:modelClass,thisObject:thisObject,listener:listener});
-},
-
-
-
-
-
-
-
-removeModelListener:function(modelClass,eventType,listener,thisObject)
-{
-if(!this._modelListeners.has(eventType))
-return;
-
-for(var i=0;i<this._targets.length;++i){
-var model=this._targets[i].model(modelClass);
-if(model)
-model.removeEventListener(eventType,listener,thisObject);
-}
-
-var listeners=this._modelListeners.get(eventType);
-for(var i=0;i<listeners.length;++i){
-if(listeners[i].modelClass===modelClass&&listeners[i].listener===listener&&listeners[i].thisObject===thisObject)
-listeners.splice(i--,1);
-}
-if(!listeners.length)
-this._modelListeners.delete(eventType);
-},
-
-
-
-
-
-observeTargets:function(targetObserver,capabilitiesMask)
-{
-if(this._observerCapabiliesMaskSymbol in targetObserver)
-throw new Error("Observer can only be registered once");
-targetObserver[this._observerCapabiliesMaskSymbol]=capabilitiesMask||0;
-this.targets(capabilitiesMask).forEach(targetObserver.targetAdded.bind(targetObserver));
-this._observers.push(targetObserver);
-},
-
-
-
-
-unobserveTargets:function(targetObserver)
-{
-delete targetObserver[this._observerCapabiliesMaskSymbol];
-this._observers.remove(targetObserver);
-},
-
-
-
-
-
-
-
-
-createTarget:function(name,capabilitiesMask,connection,parentTarget)
-{
-var target=new WebInspector.Target(this,name,capabilitiesMask,connection,parentTarget);
-
-var logAgent=target.hasLogCapability()?target.logAgent():null;
-
-
-target.consoleModel=new WebInspector.ConsoleModel(target,logAgent);
-
-target.runtimeModel=new WebInspector.RuntimeModel(target);
-
-var networkManager=null;
-var resourceTreeModel=null;
-if(target.hasNetworkCapability())
-networkManager=new WebInspector.NetworkManager(target);
-if(networkManager&&target.hasDOMCapability()){
-resourceTreeModel=new WebInspector.ResourceTreeModel(target,networkManager,WebInspector.SecurityOriginManager.fromTarget(target));
-new WebInspector.NetworkLog(target,resourceTreeModel,networkManager);
-}
-
-if(target.hasJSCapability())
-new WebInspector.DebuggerModel(target);
-
-if(resourceTreeModel){
-var domModel=new WebInspector.DOMModel(target);
-
-new WebInspector.CSSModel(target,domModel);
-}
-
-
-target.workerManager=target.hasWorkerCapability()?new WebInspector.WorkerManager(target):null;
-
-target.cpuProfilerModel=new WebInspector.CPUProfilerModel(target);
-
-target.heapProfilerModel=new WebInspector.HeapProfilerModel(target);
-
-target.tracingManager=new WebInspector.TracingManager(target);
-
-if(target.hasBrowserCapability()){
-target.subTargetsManager=new WebInspector.SubTargetsManager(target);
-target.serviceWorkerManager=new WebInspector.ServiceWorkerManager(target,target.subTargetsManager);
-}
-
-this.addTarget(target);
-return target;
-},
-
-
-
-
-
-_observersForTarget:function(target)
-{
-return this._observers.filter(observer=>target.hasAllCapabilities(observer[this._observerCapabiliesMaskSymbol]||0));
-},
-
-
-
-
-addTarget:function(target)
-{
-this._targets.push(target);
-var resourceTreeModel=WebInspector.ResourceTreeModel.fromTarget(target);
-if(this._targets.length===1&&resourceTreeModel){
-resourceTreeModel[WebInspector.TargetManager._listenersSymbol]=[
-setupRedispatch.call(this,WebInspector.ResourceTreeModel.Events.MainFrameNavigated,WebInspector.TargetManager.Events.MainFrameNavigated),
-setupRedispatch.call(this,WebInspector.ResourceTreeModel.Events.Load,WebInspector.TargetManager.Events.Load),
-setupRedispatch.call(this,WebInspector.ResourceTreeModel.Events.PageReloadRequested,WebInspector.TargetManager.Events.PageReloadRequested),
-setupRedispatch.call(this,WebInspector.ResourceTreeModel.Events.WillReloadPage,WebInspector.TargetManager.Events.WillReloadPage)];
-
-}
-var copy=this._observersForTarget(target);
-for(var i=0;i<copy.length;++i)
-copy[i].targetAdded(target);
-
-for(var pair of this._modelListeners){
-var listeners=pair[1];
-for(var i=0;i<listeners.length;++i){
-var model=target.model(listeners[i].modelClass);
-if(model)
-model.addEventListener(pair[0],listeners[i].listener,listeners[i].thisObject);
-}
-}
-
-
-
-
-
-
-
-function setupRedispatch(sourceEvent,targetEvent)
-{
-return resourceTreeModel.addEventListener(sourceEvent,this._redispatchEvent.bind(this,targetEvent));
-}
-},
-
-
-
-
-removeTarget:function(target)
-{
-this._targets.remove(target);
-var resourceTreeModel=WebInspector.ResourceTreeModel.fromTarget(target);
-var treeModelListeners=resourceTreeModel&&resourceTreeModel[WebInspector.TargetManager._listenersSymbol];
-if(treeModelListeners)
-WebInspector.EventTarget.removeEventListeners(treeModelListeners);
-
-var copy=this._observersForTarget(target);
-for(var i=0;i<copy.length;++i)
-copy[i].targetRemoved(target);
-
-for(var pair of this._modelListeners){
-var listeners=pair[1];
-for(var i=0;i<listeners.length;++i){
-var model=target.model(listeners[i].modelClass);
-if(model)
-model.removeEventListener(pair[0],listeners[i].listener,listeners[i].thisObject);
-}
-}
-},
-
-
-
-
-
-targets:function(capabilitiesMask)
-{
-if(!capabilitiesMask)
-return this._targets.slice();else
-
-return this._targets.filter(target=>target.hasAllCapabilities(capabilitiesMask||0));
-},
-
-
-
-
-
-
-targetById:function(id)
-{
-for(var i=0;i<this._targets.length;++i){
-if(this._targets[i].id()===id)
-return this._targets[i];
-}
-return null;
-},
-
-
-
-
-mainTarget:function()
-{
-return this._targets[0]||null;
-},
-
-
-
-
-suspendReload:function(target)
-{
-var resourceTreeModel=WebInspector.ResourceTreeModel.fromTarget(target);
-if(resourceTreeModel)
-resourceTreeModel.suspendReload();
-},
-
-
-
-
-resumeReload:function(target)
-{
-var resourceTreeModel=WebInspector.ResourceTreeModel.fromTarget(target);
-if(resourceTreeModel)
-setImmediate(resourceTreeModel.resumeReload.bind(resourceTreeModel));
-},
-
-__proto__:WebInspector.Object.prototype};
-
-
-
-
-
-WebInspector.TargetManager.Observer=function()
-{
-};
-
-WebInspector.TargetManager.Observer.prototype={
-
-
-
-targetAdded:function(target){},
-
-
-
-
-targetRemoved:function(target){}};
-
-
-
-
-
-WebInspector.targetManager=new WebInspector.TargetManager();
-
-},{}],116:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-WebInspector.TracingModel=function(backingStorage)
-{
-this._backingStorage=backingStorage;
-
-this._firstWritePending=true;
-this.reset();
-};
-
-
-
-
-WebInspector.TracingModel.Phase={
-Begin:"B",
-End:"E",
-Complete:"X",
-Instant:"I",
-AsyncBegin:"S",
-AsyncStepInto:"T",
-AsyncStepPast:"p",
-AsyncEnd:"F",
-NestableAsyncBegin:"b",
-NestableAsyncEnd:"e",
-NestableAsyncInstant:"n",
-FlowBegin:"s",
-FlowStep:"t",
-FlowEnd:"f",
-Metadata:"M",
-Counter:"C",
-Sample:"P",
-CreateObject:"N",
-SnapshotObject:"O",
-DeleteObject:"D"};
-
-
-WebInspector.TracingModel.MetadataEvent={
-ProcessSortIndex:"process_sort_index",
-ProcessName:"process_name",
-ThreadSortIndex:"thread_sort_index",
-ThreadName:"thread_name"};
-
-
-WebInspector.TracingModel.TopLevelEventCategory="toplevel";
-WebInspector.TracingModel.DevToolsMetadataEventCategory="disabled-by-default-devtools.timeline";
-WebInspector.TracingModel.DevToolsTimelineEventCategory="disabled-by-default-devtools.timeline";
-
-WebInspector.TracingModel.FrameLifecycleEventCategory="cc,devtools";
-
-
-
-
-
-WebInspector.TracingModel.isNestableAsyncPhase=function(phase)
-{
-return phase==="b"||phase==="e"||phase==="n";
-};
-
-
-
-
-
-WebInspector.TracingModel.isAsyncBeginPhase=function(phase)
-{
-return phase==="S"||phase==="b";
-};
-
-
-
-
-
-WebInspector.TracingModel.isAsyncPhase=function(phase)
-{
-return WebInspector.TracingModel.isNestableAsyncPhase(phase)||phase==="S"||phase==="T"||phase==="F"||phase==="p";
-};
-
-
-
-
-
-WebInspector.TracingModel.isFlowPhase=function(phase)
-{
-return phase==="s"||phase==="t"||phase==="f";
-};
-
-
-
-
-
-WebInspector.TracingModel.isTopLevelEvent=function(event)
-{
-return event.hasCategory(WebInspector.TracingModel.TopLevelEventCategory)||
-event.hasCategory(WebInspector.TracingModel.DevToolsMetadataEventCategory)&&event.name==="Program";
-};
-
-
-
-
-
-WebInspector.TracingModel._extractId=function(payload)
-{
-var scope=payload.scope||"";
-if(typeof payload.id2==="undefined")
-return scope&&payload.id?`${scope}@${payload.id}`:payload.id;
-var id2=payload.id2;
-if(typeof id2==="object"&&"global"in id2!=="local"in id2)
-return typeof id2["global"]!=="undefined"?`:${scope}:${id2["global"]}`:`:${scope}:${payload.pid}:${id2["local"]}`;
-console.error(`Unexpected id2 field at ${payload.ts/1000}, one and only one of 'local' and 'global' should be present.`);
-};
-
-
-
-
-
-
-
-
-
-WebInspector.TracingModel.browserMainThread=function(tracingModel)
-{
-var processes=tracingModel.sortedProcesses();
-var browserProcesses=[];
-var crRendererMainThreads=[];
-for(var process of processes){
-if(process.name().toLowerCase().endsWith("browser"))
-browserProcesses.push(process);
-crRendererMainThreads.push(...process.sortedThreads().filter(t=>t.name()==="CrBrowserMain"));
-}
-if(crRendererMainThreads.length===1)
-return crRendererMainThreads[0];
-if(browserProcesses.length===1)
-return browserProcesses[0].threadByName("CrBrowserMain");
-var tracingStartedInBrowser=tracingModel.devToolsMetadataEvents().filter(e=>e.name==="TracingStartedInBrowser");
-if(tracingStartedInBrowser.length===1)
-return tracingStartedInBrowser[0].thread;
-WebInspector.console.error("Failed to find browser main thread in trace, some timeline features may be unavailable");
-return null;
-};
-
-
-
-
-WebInspector.BackingStorage=function()
-{
-};
-
-WebInspector.BackingStorage.prototype={
-
-
-
-appendString:function(string){},
-
-
-
-
-
-appendAccessibleString:function(string){},
-
-finishWriting:function(){},
-
-reset:function(){}};
-
-
-
-WebInspector.TracingModel.prototype={
-
-
-
-devToolsMetadataEvents:function()
-{
-return this._devToolsMetadataEvents;
-},
-
-
-
-
-setEventsForTest:function(events)
-{
-this.reset();
-this.addEvents(events);
-this.tracingComplete();
-},
-
-
-
-
-addEvents:function(events)
-{
-for(var i=0;i<events.length;++i)
-this._addEvent(events[i]);
-},
-
-tracingComplete:function()
-{
-this._processPendingAsyncEvents();
-this._backingStorage.appendString(this._firstWritePending?"[]":"]");
-this._backingStorage.finishWriting();
-this._firstWritePending=false;
-for(var process of this._processById.values()){
-for(var thread of process._threads.values())
-thread.tracingComplete();
-}
-},
-
-reset:function()
-{
-
-this._processById=new Map();
-this._processByName=new Map();
-this._minimumRecordTime=0;
-this._maximumRecordTime=0;
-this._devToolsMetadataEvents=[];
-if(!this._firstWritePending)
-this._backingStorage.reset();
-
-this._firstWritePending=true;
-
-this._asyncEvents=[];
-
-this._openAsyncEvents=new Map();
-
-this._openNestableAsyncEvents=new Map();
-
-this._parsedCategories=new Map();
-},
-
-
-
-
-_addEvent:function(payload)
-{
-var process=this._processById.get(payload.pid);
-if(!process){
-process=new WebInspector.TracingModel.Process(this,payload.pid);
-this._processById.set(payload.pid,process);
-}
-
-var eventsDelimiter=",\n";
-this._backingStorage.appendString(this._firstWritePending?"[":eventsDelimiter);
-this._firstWritePending=false;
-var stringPayload=JSON.stringify(payload);
-var isAccessible=payload.ph===WebInspector.TracingModel.Phase.SnapshotObject;
-var backingStorage=null;
-var keepStringsLessThan=10000;
-if(isAccessible&&stringPayload.length>keepStringsLessThan)
-backingStorage=this._backingStorage.appendAccessibleString(stringPayload);else
-
-this._backingStorage.appendString(stringPayload);
-
-var timestamp=payload.ts/1000;
-
-
-if(timestamp&&(!this._minimumRecordTime||timestamp<this._minimumRecordTime))
-this._minimumRecordTime=timestamp;
-var endTimeStamp=(payload.ts+(payload.dur||0))/1000;
-this._maximumRecordTime=Math.max(this._maximumRecordTime,endTimeStamp);
-var event=process._addEvent(payload);
-if(!event)
-return;
-
-
-
-if(WebInspector.TracingModel.isAsyncPhase(payload.ph))
-this._asyncEvents.push(event);
-event._setBackingStorage(backingStorage);
-if(event.hasCategory(WebInspector.TracingModel.DevToolsMetadataEventCategory))
-this._devToolsMetadataEvents.push(event);
-
-if(payload.ph!==WebInspector.TracingModel.Phase.Metadata)
-return;
-
-switch(payload.name){
-case WebInspector.TracingModel.MetadataEvent.ProcessSortIndex:
-process._setSortIndex(payload.args["sort_index"]);
-break;
-case WebInspector.TracingModel.MetadataEvent.ProcessName:
-var processName=payload.args["name"];
-process._setName(processName);
-this._processByName.set(processName,process);
-break;
-case WebInspector.TracingModel.MetadataEvent.ThreadSortIndex:
-process.threadById(payload.tid)._setSortIndex(payload.args["sort_index"]);
-break;
-case WebInspector.TracingModel.MetadataEvent.ThreadName:
-process.threadById(payload.tid)._setName(payload.args["name"]);
-break;}
-
-},
-
-
-
-
-minimumRecordTime:function()
-{
-return this._minimumRecordTime;
-},
-
-
-
-
-maximumRecordTime:function()
-{
-return this._maximumRecordTime;
-},
-
-
-
-
-sortedProcesses:function()
-{
-return WebInspector.TracingModel.NamedObject._sort(this._processById.valuesArray());
-},
-
-
-
-
-
-processByName:function(name)
-{
-return this._processByName.get(name);
-},
-
-
-
-
-
-
-threadByName:function(processName,threadName)
-{
-var process=this.processByName(processName);
-return process&&process.threadByName(threadName);
-},
-
-_processPendingAsyncEvents:function()
-{
-this._asyncEvents.stableSort(WebInspector.TracingModel.Event.compareStartTime);
-for(var i=0;i<this._asyncEvents.length;++i){
-var event=this._asyncEvents[i];
-if(WebInspector.TracingModel.isNestableAsyncPhase(event.phase))
-this._addNestableAsyncEvent(event);else
-
-this._addAsyncEvent(event);
-}
-this._asyncEvents=[];
-this._closeOpenAsyncEvents();
-},
-
-_closeOpenAsyncEvents:function()
-{
-for(var event of this._openAsyncEvents.values()){
-event.setEndTime(this._maximumRecordTime);
-
-
-event.steps[0].setEndTime(this._maximumRecordTime);
-}
-this._openAsyncEvents.clear();
-
-for(var eventStack of this._openNestableAsyncEvents.values()){
-while(eventStack.length)
-eventStack.pop().setEndTime(this._maximumRecordTime);
-}
-this._openNestableAsyncEvents.clear();
-},
-
-
-
-
-_addNestableAsyncEvent:function(event)
-{
-var phase=WebInspector.TracingModel.Phase;
-var key=event.categoriesString+"."+event.id;
-var openEventsStack=this._openNestableAsyncEvents.get(key);
-
-switch(event.phase){
-case phase.NestableAsyncBegin:
-if(!openEventsStack){
-openEventsStack=[];
-this._openNestableAsyncEvents.set(key,openEventsStack);
-}
-var asyncEvent=new WebInspector.TracingModel.AsyncEvent(event);
-openEventsStack.push(asyncEvent);
-event.thread._addAsyncEvent(asyncEvent);
-break;
-
-case phase.NestableAsyncInstant:
-if(openEventsStack&&openEventsStack.length)
-openEventsStack.peekLast()._addStep(event);
-break;
-
-case phase.NestableAsyncEnd:
-if(!openEventsStack||!openEventsStack.length)
-break;
-var top=openEventsStack.pop();
-if(top.name!==event.name){
-console.error(`Begin/end event mismatch for nestable async event, ${top.name} vs. ${event.name}, key: ${key}`);
-break;
-}
-top._addStep(event);}
-
-},
-
-
-
-
-_addAsyncEvent:function(event)
-{
-var phase=WebInspector.TracingModel.Phase;
-var key=event.categoriesString+"."+event.name+"."+event.id;
-var asyncEvent=this._openAsyncEvents.get(key);
-
-if(event.phase===phase.AsyncBegin){
-if(asyncEvent){
-console.error(`Event ${event.name} has already been started`);
-return;
-}
-asyncEvent=new WebInspector.TracingModel.AsyncEvent(event);
-this._openAsyncEvents.set(key,asyncEvent);
-event.thread._addAsyncEvent(asyncEvent);
-return;
-}
-if(!asyncEvent){
-
-return;
-}
-if(event.phase===phase.AsyncEnd){
-asyncEvent._addStep(event);
-this._openAsyncEvents.delete(key);
-return;
-}
-if(event.phase===phase.AsyncStepInto||event.phase===phase.AsyncStepPast){
-var lastStep=asyncEvent.steps.peekLast();
-if(lastStep.phase!==phase.AsyncBegin&&lastStep.phase!==event.phase){
-console.assert(false,"Async event step phase mismatch: "+lastStep.phase+" at "+lastStep.startTime+" vs. "+event.phase+" at "+event.startTime);
-return;
-}
-asyncEvent._addStep(event);
-return;
-}
-console.assert(false,"Invalid async event phase");
-},
-
-
-
-
-
-_parsedCategoriesForString:function(str)
-{
-var parsedCategories=this._parsedCategories.get(str);
-if(!parsedCategories){
-parsedCategories=new Set(str.split(","));
-this._parsedCategories.set(str,parsedCategories);
-}
-return parsedCategories;
-}};
-
-
-
-
-
-
-
-
-
-
-WebInspector.TracingModel.Event=function(categories,name,phase,startTime,thread)
-{
-
-this.categoriesString=categories;
-
-this._parsedCategories=thread._model._parsedCategoriesForString(categories);
-
-this.name=name;
-
-this.phase=phase;
-
-this.startTime=startTime;
-
-this.thread=thread;
-
-this.args={};
-
-
-this.warning=null;
-
-this.initiator=null;
-
-this.stackTrace=null;
-
-this.previewElement=null;
-
-this.url=null;
-
-this.backendNodeId=0;
-
-
-this.selfTime=0;
-};
-
-
-
-
-
-
-WebInspector.TracingModel.Event.fromPayload=function(payload,thread)
-{
-var event=new WebInspector.TracingModel.Event(payload.cat,payload.name,payload.ph,payload.ts/1000,thread);
-if(payload.args)
-event.addArgs(payload.args);else
-
-console.error("Missing mandatory event argument 'args' at "+payload.ts/1000);
-if(typeof payload.dur==="number")
-event.setEndTime((payload.ts+payload.dur)/1000);
-var id=WebInspector.TracingModel._extractId(payload);
-if(typeof id!=="undefined")
-event.id=id;
-if(payload.bind_id)
-event.bind_id=payload.bind_id;
-
-return event;
-};
-
-WebInspector.TracingModel.Event.prototype={
-
-
-
-
-hasCategory:function(categoryName)
-{
-return this._parsedCategories.has(categoryName);
-},
-
-
-
-
-setEndTime:function(endTime)
-{
-if(endTime<this.startTime){
-console.assert(false,"Event out of order: "+this.name);
-return;
-}
-this.endTime=endTime;
-this.duration=endTime-this.startTime;
-},
-
-
-
-
-addArgs:function(args)
-{
-
-for(var name in args){
-if(name in this.args)
-console.error("Same argument name ("+name+") is used for begin and end phases of "+this.name);
-this.args[name]=args[name];
-}
-},
-
-
-
-
-_complete:function(endEvent)
-{
-if(endEvent.args)
-this.addArgs(endEvent.args);else
-
-console.error("Missing mandatory event argument 'args' at "+endEvent.startTime);
-this.setEndTime(endEvent.startTime);
-},
-
-
-
-
-_setBackingStorage:function(backingStorage)
-{
-}};
-
-
-
-
-
-
-
-WebInspector.TracingModel.Event.compareStartTime=function(a,b)
-{
-return a.startTime-b.startTime;
-};
-
-
-
-
-
-
-WebInspector.TracingModel.Event.compareStartAndEndTime=function(a,b)
-{
-return a.startTime-b.startTime||b.endTime!==undefined&&a.endTime!==undefined&&b.endTime-a.endTime||0;
-};
-
-
-
-
-
-
-WebInspector.TracingModel.Event.orderedCompareStartTime=function(a,b)
-{
-
-
-
-return a.startTime-b.startTime||a.ordinal-b.ordinal||-1;
-};
-
-
-
-
-
-
-
-
-
-WebInspector.TracingModel.ObjectSnapshot=function(category,name,startTime,thread)
-{
-WebInspector.TracingModel.Event.call(this,category,name,WebInspector.TracingModel.Phase.SnapshotObject,startTime,thread);
-};
-
-
-
-
-
-
-WebInspector.TracingModel.ObjectSnapshot.fromPayload=function(payload,thread)
-{
-var snapshot=new WebInspector.TracingModel.ObjectSnapshot(payload.cat,payload.name,payload.ts/1000,thread);
-var id=WebInspector.TracingModel._extractId(payload);
-if(typeof id!=="undefined")
-snapshot.id=id;
-if(!payload.args||!payload.args["snapshot"]){
-console.error("Missing mandatory 'snapshot' argument at "+payload.ts/1000);
-return snapshot;
-}
-if(payload.args)
-snapshot.addArgs(payload.args);
-return snapshot;
-};
-
-WebInspector.TracingModel.ObjectSnapshot.prototype={
-
-
-
-requestObject:function(callback)
-{
-var snapshot=this.args["snapshot"];
-if(snapshot){
-callback(snapshot);
-return;
-}
-this._backingStorage().then(onRead,callback.bind(null,null));
-
-
-
-function onRead(result)
-{
-if(!result){
-callback(null);
-return;
-}
-try{
-var payload=JSON.parse(result);
-callback(payload["args"]["snapshot"]);
-}catch(e){
-WebInspector.console.error("Malformed event data in backing storage");
-callback(null);
-}
-}
-},
-
-
-
-
-objectPromise:function()
-{
-if(!this._objectPromise)
-this._objectPromise=new Promise(this.requestObject.bind(this));
-return this._objectPromise;
-},
-
-
-
-
-
-_setBackingStorage:function(backingStorage)
-{
-if(!backingStorage)
-return;
-this._backingStorage=backingStorage;
-this.args={};
-},
-
-__proto__:WebInspector.TracingModel.Event.prototype};
-
-
-
-
-
-
-
-WebInspector.TracingModel.AsyncEvent=function(startEvent)
-{
-WebInspector.TracingModel.Event.call(this,startEvent.categoriesString,startEvent.name,startEvent.phase,startEvent.startTime,startEvent.thread);
-this.addArgs(startEvent.args);
-this.steps=[startEvent];
-};
-
-WebInspector.TracingModel.AsyncEvent.prototype={
-
-
-
-_addStep:function(event)
-{
-this.steps.push(event);
-if(event.phase===WebInspector.TracingModel.Phase.AsyncEnd||event.phase===WebInspector.TracingModel.Phase.NestableAsyncEnd){
-this.setEndTime(event.startTime);
-
-
-this.steps[0].setEndTime(event.startTime);
-}
-},
-
-__proto__:WebInspector.TracingModel.Event.prototype};
-
-
-
-
-
-WebInspector.TracingModel.NamedObject=function()
-{
-};
-
-WebInspector.TracingModel.NamedObject.prototype=
-{
-
-
-
-_setName:function(name)
-{
-this._name=name;
-},
-
-
-
-
-name:function()
-{
-return this._name;
-},
-
-
-
-
-_setSortIndex:function(sortIndex)
-{
-this._sortIndex=sortIndex;
-}};
-
-
-
-
-
-WebInspector.TracingModel.NamedObject._sort=function(array)
-{
-
-
-
-
-function comparator(a,b)
-{
-return a._sortIndex!==b._sortIndex?a._sortIndex-b._sortIndex:a.name().localeCompare(b.name());
-}
-return array.sort(comparator);
-};
-
-
-
-
-
-
-
-WebInspector.TracingModel.Process=function(model,id)
-{
-WebInspector.TracingModel.NamedObject.call(this);
-this._setName("Process "+id);
-this._id=id;
-
-this._threads=new Map();
-this._threadByName=new Map();
-this._model=model;
-};
-
-WebInspector.TracingModel.Process.prototype={
-
-
-
-id:function()
-{
-return this._id;
-},
-
-
-
-
-
-threadById:function(id)
-{
-var thread=this._threads.get(id);
-if(!thread){
-thread=new WebInspector.TracingModel.Thread(this,id);
-this._threads.set(id,thread);
-}
-return thread;
-},
-
-
-
-
-
-threadByName:function(name)
-{
-return this._threadByName.get(name)||null;
-},
-
-
-
-
-
-_setThreadByName:function(name,thread)
-{
-this._threadByName.set(name,thread);
-},
-
-
-
-
-
-_addEvent:function(payload)
-{
-return this.threadById(payload.tid)._addEvent(payload);
-},
-
-
-
-
-sortedThreads:function()
-{
-return WebInspector.TracingModel.NamedObject._sort(this._threads.valuesArray());
-},
-
-__proto__:WebInspector.TracingModel.NamedObject.prototype};
-
-
-
-
-
-
-
-
-WebInspector.TracingModel.Thread=function(process,id)
-{
-WebInspector.TracingModel.NamedObject.call(this);
-this._process=process;
-this._setName("Thread "+id);
-this._events=[];
-this._asyncEvents=[];
-this._id=id;
-this._model=process._model;
-};
-
-WebInspector.TracingModel.Thread.prototype={
-tracingComplete:function()
-{
-this._asyncEvents.stableSort(WebInspector.TracingModel.Event.compareStartAndEndTime);
-this._events.stableSort(WebInspector.TracingModel.Event.compareStartTime);
-var phases=WebInspector.TracingModel.Phase;
-var stack=[];
-for(var i=0;i<this._events.length;++i){
-var e=this._events[i];
-e.ordinal=i;
-switch(e.phase){
-case phases.End:
-this._events[i]=null;
-
-if(!stack.length)
-continue;
-var top=stack.pop();
-if(top.name!==e.name||top.categoriesString!==e.categoriesString)
-console.error("B/E events mismatch at "+top.startTime+" ("+top.name+") vs. "+e.startTime+" ("+e.name+")");else
-
-top._complete(e);
-break;
-case phases.Begin:
-stack.push(e);
-break;}
-
-}
-while(stack.length)
-stack.pop().setEndTime(this._model.maximumRecordTime());
-this._events.remove(null,false);
-},
-
-
-
-
-
-_addEvent:function(payload)
-{
-var event=payload.ph===WebInspector.TracingModel.Phase.SnapshotObject?
-WebInspector.TracingModel.ObjectSnapshot.fromPayload(payload,this):
-WebInspector.TracingModel.Event.fromPayload(payload,this);
-if(WebInspector.TracingModel.isTopLevelEvent(event)){
-
-if(this._lastTopLevelEvent&&this._lastTopLevelEvent.endTime>event.startTime)
-return null;
-this._lastTopLevelEvent=event;
-}
-this._events.push(event);
-return event;
-},
-
-
-
-
-_addAsyncEvent:function(asyncEvent)
-{
-this._asyncEvents.push(asyncEvent);
-},
-
-
-
-
-
-_setName:function(name)
-{
-WebInspector.TracingModel.NamedObject.prototype._setName.call(this,name);
-this._process._setThreadByName(name,this);
-},
-
-
-
-
-id:function()
-{
-return this._id;
-},
-
-
-
-
-process:function()
-{
-return this._process;
-},
-
-
-
-
-events:function()
-{
-return this._events;
-},
-
-
-
-
-asyncEvents:function()
-{
-return this._asyncEvents;
-},
-
-__proto__:WebInspector.TracingModel.NamedObject.prototype};
-
-
-},{}],117:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineLoader=function(model,delegate)
-{
-this._model=model;
-this._delegate=delegate;
-
-
-this._canceledCallback=null;
-
-this._state=WebInspector.TimelineLoader.State.Initial;
-this._buffer="";
-this._firstChunk=true;
-
-this._loadedBytes=0;
-
-this._totalSize;
-this._jsonTokenizer=new WebInspector.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this),true);
-};
-
-
-
-
-
-
-
-WebInspector.TimelineLoader.loadFromFile=function(model,file,delegate)
-{
-var loader=new WebInspector.TimelineLoader(model,delegate);
-var fileReader=WebInspector.TimelineLoader._createFileReader(file,loader);
-loader._canceledCallback=fileReader.cancel.bind(fileReader);
-loader._totalSize=file.size;
-fileReader.start(loader);
-return loader;
-};
-
-
-
-
-
-
-
-WebInspector.TimelineLoader.loadFromURL=function(model,url,delegate)
-{
-var stream=new WebInspector.TimelineLoader(model,delegate);
-WebInspector.ResourceLoader.loadAsStream(url,null,stream);
-return stream;
-};
-
-WebInspector.TimelineLoader.TransferChunkLengthBytes=5000000;
-
-
-
-
-
-
-WebInspector.TimelineLoader._createFileReader=function(file,delegate)
-{
-return new WebInspector.ChunkedFileReader(file,WebInspector.TimelineLoader.TransferChunkLengthBytes,delegate);
-};
-
-
-
-
-WebInspector.TimelineLoader.State={
-Initial:Symbol("Initial"),
-LookingForEvents:Symbol("LookingForEvents"),
-ReadingEvents:Symbol("ReadingEvents"),
-SkippingTail:Symbol("SkippingTail")};
-
-
-WebInspector.TimelineLoader.prototype={
-cancel:function()
-{
-this._model.reset();
-this._delegate.loadingComplete(false);
-this._delegate=null;
-if(this._canceledCallback)
-this._canceledCallback();
-},
-
-
-
-
-
-write:function(chunk)
-{
-if(!this._delegate)
-return;
-this._loadedBytes+=chunk.length;
-if(!this._firstChunk)
-this._delegate.loadingProgress(this._totalSize?this._loadedBytes/this._totalSize:undefined);
-
-if(this._state===WebInspector.TimelineLoader.State.Initial){
-if(chunk[0]==="{")
-this._state=WebInspector.TimelineLoader.State.LookingForEvents;else
-if(chunk[0]==="[")
-this._state=WebInspector.TimelineLoader.State.ReadingEvents;else
-{
-this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: Unknown JSON format"));
-return;
-}
-}
-
-if(this._state===WebInspector.TimelineLoader.State.LookingForEvents){
-var objectName="\"traceEvents\":";
-var startPos=this._buffer.length-objectName.length;
-this._buffer+=chunk;
-var pos=this._buffer.indexOf(objectName,startPos);
-if(pos===-1)
-return;
-chunk=this._buffer.slice(pos+objectName.length);
-this._state=WebInspector.TimelineLoader.State.ReadingEvents;
-}
-
-if(this._state!==WebInspector.TimelineLoader.State.ReadingEvents)
-return;
-if(this._jsonTokenizer.write(chunk))
-return;
-this._state=WebInspector.TimelineLoader.State.SkippingTail;
-if(this._firstChunk){
-this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline input, wrong JSON brackets balance"));
-return;
-}
-},
-
-
-
-
-_writeBalancedJSON:function(data)
-{
-var json=data+"]";
-
-if(this._firstChunk){
-this._delegate.loadingStarted();
-}else{
-var commaIndex=json.indexOf(",");
-if(commaIndex!==-1)
-json=json.slice(commaIndex+1);
-json="["+json;
-}
-
-var items;
-try{
-items=JSON.parse(json);
-}catch(e){
-this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s",e.toString()));
-return;
-}
-
-if(this._firstChunk){
-this._firstChunk=false;
-this._model.reset();
-if(this._looksLikeAppVersion(items[0])){
-this._reportErrorAndCancelLoading(WebInspector.UIString("Legacy Timeline format is not supported."));
-return;
-}
-}
-
-try{
-this._model.addEvents(items);
-}catch(e){
-this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed timeline data: %s",e.toString()));
-return;
-}
-},
-
-
-
-
-_reportErrorAndCancelLoading:function(message)
-{
-if(message)
-WebInspector.console.error(message);
-this.cancel();
-},
-
-
-
-
-
-_looksLikeAppVersion:function(item)
-{
-return typeof item==="string"&&item.indexOf("Chrome")!==-1;
-},
-
-
-
-
-close:function()
-{
-this._model.tracingComplete();
-if(this._delegate)
-this._delegate.loadingComplete(true);
-},
-
-
-
-
-onTransferStarted:function(){},
-
-
-
-
-
-onChunkTransferred:function(reader){},
-
-
-
-
-onTransferFinished:function(){},
-
-
-
-
-
-
-onError:function(reader,event)
-{
-switch(event.target.error.name){
-case"NotFoundError":
-this._reportErrorAndCancelLoading(WebInspector.UIString("File \"%s\" not found.",reader.fileName()));
-break;
-case"NotReadableError":
-this._reportErrorAndCancelLoading(WebInspector.UIString("File \"%s\" is not readable",reader.fileName()));
-break;
-case"AbortError":
-break;
-default:
-this._reportErrorAndCancelLoading(WebInspector.UIString("An error occurred while reading the file \"%s\"",reader.fileName()));}
-
-}};
-
-
-
-
-
-
-WebInspector.TracingTimelineSaver=function()
-{
-};
-
-WebInspector.TracingTimelineSaver.prototype={
-
-
-
-onTransferStarted:function(){},
-
-
-
-
-onTransferFinished:function(){},
-
-
-
-
-
-onChunkTransferred:function(reader){},
-
-
-
-
-
-
-onError:function(reader,event)
-{
-var error=event.target.error;
-WebInspector.console.error(WebInspector.UIString("Failed to save timeline: %s (%s, %s)",error.message,error.name,error.code));
-}};
-
-
-},{}],118:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineTreeView=function(model,filters)
-{
-WebInspector.VBox.call(this);
-this.element.classList.add("timeline-tree-view");
-
-this._model=model;
-this._linkifier=new WebInspector.Linkifier();
-
-this._filters=filters.slice();
-
-var columns=[];
-this._populateColumns(columns);
-
-var mainView=new WebInspector.VBox();
-this._populateToolbar(mainView.element);
-this._dataGrid=new WebInspector.SortableDataGrid(columns);
-this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,this._sortingChanged,this);
-this._dataGrid.element.addEventListener("mousemove",this._onMouseMove.bind(this),true);
-this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
-this._dataGrid.asWidget().show(mainView.element);
-
-this._splitWidget=new WebInspector.SplitWidget(true,true,"timelineTreeViewDetailsSplitWidget");
-this._splitWidget.show(this.element);
-this._splitWidget.setMainWidget(mainView);
-
-this._detailsView=new WebInspector.VBox();
-this._detailsView.element.classList.add("timeline-details-view","timeline-details-view-body");
-this._splitWidget.setSidebarWidget(this._detailsView);
-this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._updateDetailsForSelection,this);
-
-
-this._lastSelectedNode;
-};
-
-WebInspector.TimelineTreeView.prototype={
-
-
-
-updateContents:function(selection)
-{
-this.setRange(selection.startTime(),selection.endTime());
-},
-
-
-
-
-
-setRange:function(startTime,endTime)
-{
-this._startTime=startTime;
-this._endTime=endTime;
-this._refreshTree();
-},
-
-
-
-
-_exposePercentages:function()
-{
-return false;
-},
-
-
-
-
-_populateToolbar:function(parent){},
-
-
-
-
-_onHover:function(node){},
-
-
-
-
-
-_linkifyLocation:function(event)
-{
-var target=this._model.targetByEvent(event);
-if(!target)
-return null;
-var frame=WebInspector.TimelineProfileTree.eventStackFrame(event);
-if(!frame)
-return null;
-return this._linkifier.maybeLinkifyConsoleCallFrame(target,frame);
-},
-
-
-
-
-
-selectProfileNode:function(treeNode,suppressSelectedEvent)
-{
-var pathToRoot=[];
-for(var node=treeNode;node;node=node.parent)
-pathToRoot.push(node);
-for(var i=pathToRoot.length-1;i>0;--i){
-var gridNode=this._dataGridNodeForTreeNode(pathToRoot[i]);
-if(gridNode&&gridNode.dataGrid)
-gridNode.expand();
-}
-var gridNode=this._dataGridNodeForTreeNode(treeNode);
-if(gridNode.dataGrid){
-gridNode.reveal();
-gridNode.select(suppressSelectedEvent);
-}
-},
-
-_refreshTree:function()
-{
-this._linkifier.reset();
-this._dataGrid.rootNode().removeChildren();
-var tree=this._buildTree();
-if(!tree.children)
-return;
-var maxSelfTime=0;
-var maxTotalTime=0;
-for(var child of tree.children.values()){
-maxSelfTime=Math.max(maxSelfTime,child.selfTime);
-maxTotalTime=Math.max(maxTotalTime,child.totalTime);
-}
-for(var child of tree.children.values()){
-
-var gridNode=new WebInspector.TimelineTreeView.TreeGridNode(child,tree.totalTime,maxSelfTime,maxTotalTime,this);
-this._dataGrid.insertChild(gridNode);
-}
-this._sortingChanged();
-this._updateDetailsForSelection();
-},
-
-
-
-
-_buildTree:function()
-{
-throw new Error("Not Implemented");
-},
-
-
-
-
-
-_buildTopDownTree:function(eventIdCallback)
-{
-return WebInspector.TimelineProfileTree.buildTopDown(this._model.mainThreadEvents(),this._filters,this._startTime,this._endTime,eventIdCallback);
-},
-
-
-
-
-_populateColumns:function(columns)
-{
-columns.push({id:"self",title:WebInspector.UIString("Self Time"),width:"110px",fixedWidth:true,sortable:true});
-columns.push({id:"total",title:WebInspector.UIString("Total Time"),width:"110px",fixedWidth:true,sortable:true});
-columns.push({id:"activity",title:WebInspector.UIString("Activity"),disclosure:true,sortable:true});
-},
-
-_sortingChanged:function()
-{
-var columnIdentifier=this._dataGrid.sortColumnIdentifier();
-if(!columnIdentifier)
-return;
-var sortFunction;
-switch(columnIdentifier){
-case"startTime":
-sortFunction=compareStartTime;
-break;
-case"self":
-sortFunction=compareNumericField.bind(null,"selfTime");
-break;
-case"total":
-sortFunction=compareNumericField.bind(null,"totalTime");
-break;
-case"activity":
-sortFunction=compareName;
-break;
-default:
-console.assert(false,"Unknown sort field: "+columnIdentifier);
-return;}
-
-this._dataGrid.sortNodes(sortFunction,!this._dataGrid.isSortOrderAscending());
-
-
-
-
-
-
-
-function compareNumericField(field,a,b)
-{
-var nodeA=a;
-var nodeB=b;
-return nodeA._profileNode[field]-nodeB._profileNode[field];
-}
-
-
-
-
-
-
-function compareStartTime(a,b)
-{
-var nodeA=a;
-var nodeB=b;
-return nodeA._profileNode.event.startTime-nodeB._profileNode.event.startTime;
-}
-
-
-
-
-
-
-function compareName(a,b)
-{
-var nodeA=a;
-var nodeB=b;
-var nameA=WebInspector.TimelineTreeView.eventNameForSorting(nodeA._profileNode.event);
-var nameB=WebInspector.TimelineTreeView.eventNameForSorting(nodeB._profileNode.event);
-return nameA.localeCompare(nameB);
-}
-},
-
-_updateDetailsForSelection:function()
-{
-var selectedNode=this._dataGrid.selectedNode?this._dataGrid.selectedNode._profileNode:null;
-if(selectedNode===this._lastSelectedNode)
-return;
-this._lastSelectedNode=selectedNode;
-this._detailsView.detachChildWidgets();
-this._detailsView.element.removeChildren();
-if(!selectedNode||!this._showDetailsForNode(selectedNode)){
-var banner=this._detailsView.element.createChild("div","full-widget-dimmed-banner");
-banner.createTextChild(WebInspector.UIString("Select item for details."));
-}
-},
-
-
-
-
-
-_showDetailsForNode:function(node)
-{
-return false;
-},
-
-
-
-
-_onMouseMove:function(event)
-{
-var gridNode=event.target&&event.target instanceof Node?
-this._dataGrid.dataGridNodeFromNode(event.target):
-null;
-var profileNode=gridNode&&gridNode._profileNode;
-if(profileNode===this._lastHoveredProfileNode)
-return;
-this._lastHoveredProfileNode=profileNode;
-this._onHover(profileNode);
-},
-
-
-
-
-
-_dataGridNodeForTreeNode:function(treeNode)
-{
-return treeNode[WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol]||null;
-},
-
-__proto__:WebInspector.VBox.prototype};
-
-
-
-
-
-
-WebInspector.TimelineTreeView.eventNameForSorting=function(event)
-{
-if(event.name===WebInspector.TimelineModel.RecordType.JSFrame){
-var data=event.args["data"];
-return data["functionName"]+"@"+(data["scriptId"]||data["url"]||"");
-}
-return event.name+":@"+WebInspector.TimelineProfileTree.eventURL(event);
-};
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineTreeView.GridNode=function(profileNode,grandTotalTime,maxSelfTime,maxTotalTime,treeView)
-{
-this._populated=false;
-this._profileNode=profileNode;
-this._treeView=treeView;
-this._grandTotalTime=grandTotalTime;
-this._maxSelfTime=maxSelfTime;
-this._maxTotalTime=maxTotalTime;
-WebInspector.SortableDataGridNode.call(this,null,false);
-};
-
-WebInspector.TimelineTreeView.GridNode.prototype={
-
-
-
-
-
-createCell:function(columnIdentifier)
-{
-if(columnIdentifier==="activity")
-return this._createNameCell(columnIdentifier);
-return this._createValueCell(columnIdentifier)||WebInspector.DataGridNode.prototype.createCell.call(this,columnIdentifier);
-},
-
-
-
-
-
-_createNameCell:function(columnIdentifier)
-{
-var cell=this.createTD(columnIdentifier);
-var container=cell.createChild("div","name-container");
-var icon=container.createChild("div","activity-icon");
-var name=container.createChild("div","activity-name");
-var event=this._profileNode.event;
-if(this._profileNode.isGroupNode()){
-var treeView=this._treeView;
-var info=treeView._displayInfoForGroupNode(this._profileNode);
-name.textContent=info.name;
-icon.style.backgroundColor=info.color;
-}else if(event){
-var data=event.args["data"];
-var deoptReason=data&&data["deoptReason"];
-if(deoptReason)
-container.createChild("div","activity-warning").title=WebInspector.UIString("Not optimized: %s",deoptReason);
-name.textContent=event.name===WebInspector.TimelineModel.RecordType.JSFrame?
-WebInspector.beautifyFunctionName(event.args["data"]["functionName"]):
-WebInspector.TimelineUIUtils.eventTitle(event);
-var link=this._treeView._linkifyLocation(event);
-if(link)
-container.createChild("div","activity-link").appendChild(link);
-icon.style.backgroundColor=WebInspector.TimelineUIUtils.eventColor(event);
-}
-return cell;
-},
-
-
-
-
-
-_createValueCell:function(columnIdentifier)
-{
-if(columnIdentifier!=="self"&&columnIdentifier!=="total"&&columnIdentifier!=="startTime")
-return null;
-
-var showPercents=false;
-var value;
-var maxTime;
-switch(columnIdentifier){
-case"startTime":
-value=this._profileNode.event.startTime-this._treeView._model.minimumRecordTime();
-break;
-case"self":
-value=this._profileNode.selfTime;
-maxTime=this._maxSelfTime;
-showPercents=true;
-break;
-case"total":
-value=this._profileNode.totalTime;
-maxTime=this._maxTotalTime;
-showPercents=true;
-break;
-default:
-return null;}
-
-var cell=this.createTD(columnIdentifier);
-cell.className="numeric-column";
-var textDiv=cell.createChild("div");
-textDiv.createChild("span").textContent=WebInspector.UIString("%.1f\u2009ms",value);
-
-if(showPercents&&this._treeView._exposePercentages())
-textDiv.createChild("span","percent-column").textContent=WebInspector.UIString("%.1f\u2009%%",value/this._grandTotalTime*100);
-if(maxTime){
-textDiv.classList.add("background-percent-bar");
-cell.createChild("div","background-bar-container").createChild("div","background-bar").style.width=(value*100/maxTime).toFixed(1)+"%";
-}
-return cell;
-},
-
-__proto__:WebInspector.SortableDataGridNode.prototype};
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineTreeView.TreeGridNode=function(profileNode,grandTotalTime,maxSelfTime,maxTotalTime,treeView)
-{
-WebInspector.TimelineTreeView.GridNode.call(this,profileNode,grandTotalTime,maxSelfTime,maxTotalTime,treeView);
-this.hasChildren=this._profileNode.children?this._profileNode.children.size>0:false;
-profileNode[WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol]=this;
-};
-
-WebInspector.TimelineTreeView.TreeGridNode._gridNodeSymbol=Symbol("treeGridNode");
-
-WebInspector.TimelineTreeView.TreeGridNode.prototype={
-
-
-
-populate:function()
-{
-if(this._populated)
-return;
-this._populated=true;
-if(!this._profileNode.children)
-return;
-for(var node of this._profileNode.children.values()){
-var gridNode=new WebInspector.TimelineTreeView.TreeGridNode(node,this._grandTotalTime,this._maxSelfTime,this._maxTotalTime,this._treeView);
-this.insertChildOrdered(gridNode);
-}
-},
-
-__proto__:WebInspector.TimelineTreeView.GridNode.prototype};
-
-
-
-
-
-
-
-
-
-WebInspector.AggregatedTimelineTreeView=function(model,filters)
-{
-this._groupBySetting=WebInspector.settings.createSetting("timelineTreeGroupBy",WebInspector.TimelineAggregator.GroupBy.Category);
-WebInspector.TimelineTreeView.call(this,model,filters);
-var nonessentialEvents=[
-WebInspector.TimelineModel.RecordType.EventDispatch,
-WebInspector.TimelineModel.RecordType.FunctionCall,
-WebInspector.TimelineModel.RecordType.TimerFire];
-
-this._filters.push(new WebInspector.ExclusiveNameFilter(nonessentialEvents));
-this._stackView=new WebInspector.TimelineStackView(this);
-this._stackView.addEventListener(WebInspector.TimelineStackView.Events.SelectionChanged,this._onStackViewSelectionChanged,this);
-};
-
-WebInspector.AggregatedTimelineTreeView.prototype={
-
-
-
-
-updateContents:function(selection)
-{
-this._updateExtensionResolver();
-WebInspector.TimelineTreeView.prototype.updateContents.call(this,selection);
-var rootNode=this._dataGrid.rootNode();
-if(rootNode.children.length)
-rootNode.children[0].revealAndSelect();
-},
-
-_updateExtensionResolver:function()
-{
-this._executionContextNamesByOrigin=new Map();
-for(var target of WebInspector.targetManager.targets()){
-for(var context of target.runtimeModel.executionContexts())
-this._executionContextNamesByOrigin.set(context.origin,context.name);
-}
-},
-
-
-
-
-
-_displayInfoForGroupNode:function(node)
-{
-var categories=WebInspector.TimelineUIUtils.categories();
-var color=node.id?WebInspector.TimelineUIUtils.eventColor(node.event):categories["other"].color;
-
-switch(this._groupBySetting.get()){
-case WebInspector.TimelineAggregator.GroupBy.Category:
-var category=categories[node.id]||categories["other"];
-return{name:category.title,color:category.color};
-
-case WebInspector.TimelineAggregator.GroupBy.Domain:
-case WebInspector.TimelineAggregator.GroupBy.Subdomain:
-var name=node.id;
-if(WebInspector.TimelineAggregator.isExtensionInternalURL(name))
-name=WebInspector.UIString("[Chrome extensions overhead]");else
-if(name.startsWith("chrome-extension"))
-name=this._executionContextNamesByOrigin.get(name)||name;
-return{
-name:name||WebInspector.UIString("unattributed"),
-color:color};
-
-
-case WebInspector.TimelineAggregator.GroupBy.EventName:
-var name=node.event.name===WebInspector.TimelineModel.RecordType.JSFrame?
-WebInspector.UIString("JavaScript"):WebInspector.TimelineUIUtils.eventTitle(node.event);
-return{
-name:name,
-color:node.event.name===WebInspector.TimelineModel.RecordType.JSFrame?
-WebInspector.TimelineUIUtils.eventStyle(node.event).category.color:color};
-
-
-case WebInspector.TimelineAggregator.GroupBy.URL:
-break;
-
-default:
-console.assert(false,"Unexpected aggregation type");}
-
-return{
-name:node.id||WebInspector.UIString("unattributed"),
-color:color};
-
-},
-
-
-
-
-
-_populateToolbar:function(parent)
-{
-var panelToolbar=new WebInspector.Toolbar("",parent);
-this._groupByCombobox=new WebInspector.ToolbarComboBox(this._onGroupByChanged.bind(this));
-
-
-
-
-
-function addGroupingOption(name,id)
-{
-var option=this._groupByCombobox.createOption(name,"",id);
-this._groupByCombobox.addOption(option);
-if(id===this._groupBySetting.get())
-this._groupByCombobox.select(option);
-}
-addGroupingOption.call(this,WebInspector.UIString("No Grouping"),WebInspector.TimelineAggregator.GroupBy.None);
-addGroupingOption.call(this,WebInspector.UIString("Group by Activity"),WebInspector.TimelineAggregator.GroupBy.EventName);
-addGroupingOption.call(this,WebInspector.UIString("Group by Category"),WebInspector.TimelineAggregator.GroupBy.Category);
-addGroupingOption.call(this,WebInspector.UIString("Group by Domain"),WebInspector.TimelineAggregator.GroupBy.Domain);
-addGroupingOption.call(this,WebInspector.UIString("Group by Subdomain"),WebInspector.TimelineAggregator.GroupBy.Subdomain);
-addGroupingOption.call(this,WebInspector.UIString("Group by URL"),WebInspector.TimelineAggregator.GroupBy.URL);
-panelToolbar.appendToolbarItem(this._groupByCombobox);
-},
-
-
-
-
-
-_buildHeaviestStack:function(treeNode)
-{
-console.assert(!!treeNode.parent,"Attempt to build stack for tree root");
-var result=[];
-
-for(var node=treeNode;node&&node.parent;node=node.parent)
-result.push(node);
-result=result.reverse();
-for(node=treeNode;node&&node.children&&node.children.size;){
-var children=Array.from(node.children.values());
-node=children.reduce((a,b)=>a.totalTime>b.totalTime?a:b);
-result.push(node);
-}
-return result;
-},
-
-
-
-
-
-_exposePercentages:function()
-{
-return true;
-},
-
-_onGroupByChanged:function()
-{
-this._groupBySetting.set(this._groupByCombobox.selectedOption().value);
-this._refreshTree();
-},
-
-_onStackViewSelectionChanged:function()
-{
-var treeNode=this._stackView.selectedTreeNode();
-if(treeNode)
-this.selectProfileNode(treeNode,true);
-},
-
-
-
-
-
-
-_showDetailsForNode:function(node)
-{
-var stack=this._buildHeaviestStack(node);
-this._stackView.setStack(stack,node);
-this._stackView.show(this._detailsView.element);
-return true;
-},
-
-
-
-
-_createAggregator:function()
-{
-return new WebInspector.TimelineAggregator(
-event=>WebInspector.TimelineUIUtils.eventStyle(event).title,
-event=>WebInspector.TimelineUIUtils.eventStyle(event).category.name);
-
-},
-
-__proto__:WebInspector.TimelineTreeView.prototype};
-
-
-
-
-
-
-
-
-WebInspector.CallTreeTimelineTreeView=function(model,filters)
-{
-WebInspector.AggregatedTimelineTreeView.call(this,model,filters);
-this._dataGrid.markColumnAsSortedBy("total",WebInspector.DataGrid.Order.Descending);
-};
-
-WebInspector.CallTreeTimelineTreeView.prototype={
-
-
-
-
-_buildTree:function()
-{
-var topDown=this._buildTopDownTree(WebInspector.TimelineAggregator.eventId);
-return this._createAggregator().performGrouping(topDown,this._groupBySetting.get());
-},
-
-__proto__:WebInspector.AggregatedTimelineTreeView.prototype};
-
-
-
-
-
-
-
-
-WebInspector.BottomUpTimelineTreeView=function(model,filters)
-{
-WebInspector.AggregatedTimelineTreeView.call(this,model,filters);
-this._dataGrid.markColumnAsSortedBy("self",WebInspector.DataGrid.Order.Descending);
-};
-
-WebInspector.BottomUpTimelineTreeView.prototype={
-
-
-
-
-_buildTree:function()
-{
-var topDown=this._buildTopDownTree(WebInspector.TimelineAggregator.eventId);
-return WebInspector.TimelineProfileTree.buildBottomUp(topDown,this._createAggregator().groupFunction(this._groupBySetting.get()));
-},
-
-__proto__:WebInspector.AggregatedTimelineTreeView.prototype};
-
-
-
-
-
-
-
-
-
-WebInspector.EventsTimelineTreeView=function(model,filters,delegate)
-{
-this._filtersControl=new WebInspector.TimelineFilters();
-this._filtersControl.addEventListener(WebInspector.TimelineFilters.Events.FilterChanged,this._onFilterChanged,this);
-WebInspector.TimelineTreeView.call(this,model,filters);
-this._delegate=delegate;
-this._filters.push.apply(this._filters,this._filtersControl.filters());
-this._dataGrid.markColumnAsSortedBy("startTime",WebInspector.DataGrid.Order.Ascending);
-};
-
-WebInspector.EventsTimelineTreeView.prototype={
-
-
-
-
-updateContents:function(selection)
-{
-WebInspector.TimelineTreeView.prototype.updateContents.call(this,selection);
-if(selection.type()===WebInspector.TimelineSelection.Type.TraceEvent){
-var event=selection.object();
-this._selectEvent(event,true);
-}
-},
-
-
-
-
-
-_buildTree:function()
-{
-this._currentTree=this._buildTopDownTree();
-return this._currentTree;
-},
-
-_onFilterChanged:function()
-{
-var selectedEvent=this._lastSelectedNode&&this._lastSelectedNode.event;
-this._refreshTree();
-if(selectedEvent)
-this._selectEvent(selectedEvent,false);
-},
-
-
-
-
-
-_findNodeWithEvent:function(event)
-{
-var iterators=[this._currentTree.children.values()];
-
-while(iterators.length){
-var iterator=iterators.peekLast().next();
-if(iterator.done){
-iterators.pop();
-continue;
-}
-var child=iterator.value;
-if(child.event===event)
-return child;
-if(child.children)
-iterators.push(child.children.values());
-}
-return null;
-},
-
-
-
-
-
-_selectEvent:function(event,expand)
-{
-var node=this._findNodeWithEvent(event);
-if(!node)
-return;
-this.selectProfileNode(node,false);
-if(expand)
-this._dataGridNodeForTreeNode(node).expand();
-},
-
-
-
-
-
-_populateColumns:function(columns)
-{
-columns.push({id:"startTime",title:WebInspector.UIString("Start Time"),width:"110px",fixedWidth:true,sortable:true});
-WebInspector.TimelineTreeView.prototype._populateColumns.call(this,columns);
-},
-
-
-
-
-
-_populateToolbar:function(parent)
-{
-var filtersWidget=this._filtersControl.filtersWidget();
-filtersWidget.forceShowFilterBar();
-filtersWidget.show(parent);
-},
-
-
-
-
-
-
-_showDetailsForNode:function(node)
-{
-var traceEvent=node.event;
-if(!traceEvent)
-return false;
-WebInspector.TimelineUIUtils.buildTraceEventDetails(traceEvent,this._model,this._linkifier,false,showDetails.bind(this));
-return true;
-
-
-
-
-
-function showDetails(fragment)
-{
-this._detailsView.element.appendChild(fragment);
-}
-},
-
-
-
-
-
-_onHover:function(node)
-{
-this._delegate.highlightEvent(node&&node.event);
-},
-
-__proto__:WebInspector.TimelineTreeView.prototype};
-
-
-
-
-
-
-WebInspector.TimelineStackView=function(treeView)
-{
-WebInspector.VBox.call(this);
-var header=this.element.createChild("div","timeline-stack-view-header");
-header.textContent=WebInspector.UIString("Heaviest stack");
-this._treeView=treeView;
-var columns=[
-{id:"total",title:WebInspector.UIString("Total Time"),fixedWidth:true,width:"110px"},
-{id:"activity",title:WebInspector.UIString("Activity")}];
-
-this._dataGrid=new WebInspector.ViewportDataGrid(columns);
-this._dataGrid.setResizeMethod(WebInspector.DataGrid.ResizeMethod.Last);
-this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode,this._onSelectionChanged,this);
-this._dataGrid.asWidget().show(this.element);
-};
-
-
-WebInspector.TimelineStackView.Events={
-SelectionChanged:Symbol("SelectionChanged")};
-
-
-WebInspector.TimelineStackView.prototype={
-
-
-
-
-setStack:function(stack,selectedNode)
-{
-var rootNode=this._dataGrid.rootNode();
-rootNode.removeChildren();
-var nodeToReveal=null;
-var totalTime=Math.max.apply(Math,stack.map(node=>node.totalTime));
-for(var node of stack){
-var gridNode=new WebInspector.TimelineTreeView.GridNode(node,totalTime,totalTime,totalTime,this._treeView);
-rootNode.appendChild(gridNode);
-if(node===selectedNode)
-nodeToReveal=gridNode;
-}
-nodeToReveal.revealAndSelect();
-},
-
-
-
-
-selectedTreeNode:function()
-{
-var selectedNode=this._dataGrid.selectedNode;
-return selectedNode&&selectedNode._profileNode;
-},
-
-_onSelectionChanged:function()
-{
-this.dispatchEventToListeners(WebInspector.TimelineStackView.Events.SelectionChanged);
-},
-
-__proto__:WebInspector.VBox.prototype};
-
-
-},{}],119:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils=function(){};
-
-
-
-
-
-
-
-WebInspector.TimelineRecordStyle=function(title,category,hidden)
-{
-this.title=title;
-this.category=category;
-this.hidden=!!hidden;
-};
-
-
-
-
-WebInspector.TimelineUIUtils._initEventStyles=function()
-{
-if(WebInspector.TimelineUIUtils._eventStylesMap)
-return WebInspector.TimelineUIUtils._eventStylesMap;
-
-var recordTypes=WebInspector.TimelineModel.RecordType;
-var categories=WebInspector.TimelineUIUtils.categories();
-
-var eventStyles={};
-eventStyles[recordTypes.Task]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Task"),categories["other"]);
-eventStyles[recordTypes.Program]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Other"),categories["other"]);
-eventStyles[recordTypes.Animation]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation"),categories["rendering"]);
-eventStyles[recordTypes.EventDispatch]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Event"),categories["scripting"]);
-eventStyles[recordTypes.RequestMainThreadFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Main Thread Frame"),categories["rendering"],true);
-eventStyles[recordTypes.BeginFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start"),categories["rendering"],true);
-eventStyles[recordTypes.BeginMainThreadFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start (main thread)"),categories["rendering"],true);
-eventStyles[recordTypes.DrawFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Draw Frame"),categories["rendering"],true);
-eventStyles[recordTypes.HitTest]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Hit Test"),categories["rendering"]);
-eventStyles[recordTypes.ScheduleStyleRecalculation]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Schedule Style Recalculation"),categories["rendering"],true);
-eventStyles[recordTypes.RecalculateStyles]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"),categories["rendering"]);
-eventStyles[recordTypes.UpdateLayoutTree]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"),categories["rendering"]);
-eventStyles[recordTypes.InvalidateLayout]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Invalidate Layout"),categories["rendering"],true);
-eventStyles[recordTypes.Layout]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Layout"),categories["rendering"]);
-eventStyles[recordTypes.PaintSetup]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Setup"),categories["painting"]);
-eventStyles[recordTypes.PaintImage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Image"),categories["painting"],true);
-eventStyles[recordTypes.UpdateLayer]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer"),categories["painting"],true);
-eventStyles[recordTypes.UpdateLayerTree]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer Tree"),categories["rendering"]);
-eventStyles[recordTypes.Paint]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint"),categories["painting"]);
-eventStyles[recordTypes.RasterTask]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Rasterize Paint"),categories["painting"]);
-eventStyles[recordTypes.ScrollLayer]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Scroll"),categories["rendering"]);
-eventStyles[recordTypes.CompositeLayers]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Composite Layers"),categories["painting"]);
-eventStyles[recordTypes.ParseHTML]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse HTML"),categories["loading"]);
-eventStyles[recordTypes.ParseAuthorStyleSheet]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Stylesheet"),categories["loading"]);
-eventStyles[recordTypes.TimerInstall]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Install Timer"),categories["scripting"]);
-eventStyles[recordTypes.TimerRemove]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Remove Timer"),categories["scripting"]);
-eventStyles[recordTypes.TimerFire]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timer Fired"),categories["scripting"]);
-eventStyles[recordTypes.XHRReadyStateChange]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Ready State Change"),categories["scripting"]);
-eventStyles[recordTypes.XHRLoad]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Load"),categories["scripting"]);
-eventStyles[recordTypes.CompileScript]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Compile Script"),categories["scripting"]);
-eventStyles[recordTypes.EvaluateScript]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Evaluate Script"),categories["scripting"]);
-eventStyles[recordTypes.ParseScriptOnBackground]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse Script"),categories["scripting"]);
-eventStyles[recordTypes.MarkLoad]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Load event"),categories["scripting"],true);
-eventStyles[recordTypes.MarkDOMContent]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOMContentLoaded event"),categories["scripting"],true);
-eventStyles[recordTypes.MarkFirstPaint]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("First paint"),categories["painting"],true);
-eventStyles[recordTypes.TimeStamp]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timestamp"),categories["scripting"]);
-eventStyles[recordTypes.ConsoleTime]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Console Time"),categories["scripting"]);
-eventStyles[recordTypes.UserTiming]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("User Timing"),categories["scripting"]);
-eventStyles[recordTypes.ResourceSendRequest]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send Request"),categories["loading"]);
-eventStyles[recordTypes.ResourceReceiveResponse]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Response"),categories["loading"]);
-eventStyles[recordTypes.ResourceFinish]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Finish Loading"),categories["loading"]);
-eventStyles[recordTypes.ResourceReceivedData]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Data"),categories["loading"]);
-eventStyles[recordTypes.RunMicrotasks]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Run Microtasks"),categories["scripting"]);
-eventStyles[recordTypes.FunctionCall]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Function Call"),categories["scripting"]);
-eventStyles[recordTypes.GCEvent]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("GC Event"),categories["scripting"]);
-eventStyles[recordTypes.MajorGC]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Major GC"),categories["scripting"]);
-eventStyles[recordTypes.MinorGC]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Minor GC"),categories["scripting"]);
-eventStyles[recordTypes.JSFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("JS Frame"),categories["scripting"]);
-eventStyles[recordTypes.RequestAnimationFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Animation Frame"),categories["scripting"]);
-eventStyles[recordTypes.CancelAnimationFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Animation Frame"),categories["scripting"]);
-eventStyles[recordTypes.FireAnimationFrame]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation Frame Fired"),categories["scripting"]);
-eventStyles[recordTypes.RequestIdleCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Idle Callback"),categories["scripting"]);
-eventStyles[recordTypes.CancelIdleCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Idle Callback"),categories["scripting"]);
-eventStyles[recordTypes.FireIdleCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Fire Idle Callback"),categories["scripting"]);
-eventStyles[recordTypes.WebSocketCreate]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Create WebSocket"),categories["scripting"]);
-eventStyles[recordTypes.WebSocketSendHandshakeRequest]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send WebSocket Handshake"),categories["scripting"]);
-eventStyles[recordTypes.WebSocketReceiveHandshakeResponse]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive WebSocket Handshake"),categories["scripting"]);
-eventStyles[recordTypes.WebSocketDestroy]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Destroy WebSocket"),categories["scripting"]);
-eventStyles[recordTypes.EmbedderCallback]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Embedder Callback"),categories["scripting"]);
-eventStyles[recordTypes.DecodeImage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Decode"),categories["painting"]);
-eventStyles[recordTypes.ResizeImage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Resize"),categories["painting"]);
-eventStyles[recordTypes.GPUTask]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("GPU"),categories["gpu"]);
-eventStyles[recordTypes.LatencyInfo]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("Input Latency"),categories["scripting"]);
-
-eventStyles[recordTypes.GCIdleLazySweep]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"),categories["scripting"]);
-eventStyles[recordTypes.GCCompleteSweep]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"),categories["scripting"]);
-eventStyles[recordTypes.GCCollectGarbage]=new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOM GC"),categories["scripting"]);
-
-WebInspector.TimelineUIUtils._eventStylesMap=eventStyles;
-return eventStyles;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.inputEventDisplayName=function(inputEventType)
-{
-if(!WebInspector.TimelineUIUtils._inputEventToDisplayName){
-var inputEvent=WebInspector.TimelineIRModel.InputEvents;
-
-
-WebInspector.TimelineUIUtils._inputEventToDisplayName=new Map([
-[inputEvent.Char,WebInspector.UIString("Key Character")],
-[inputEvent.KeyDown,WebInspector.UIString("Key Down")],
-[inputEvent.KeyDownRaw,WebInspector.UIString("Key Down")],
-[inputEvent.KeyUp,WebInspector.UIString("Key Up")],
-[inputEvent.Click,WebInspector.UIString("Click")],
-[inputEvent.ContextMenu,WebInspector.UIString("Context Menu")],
-[inputEvent.MouseDown,WebInspector.UIString("Mouse Down")],
-[inputEvent.MouseMove,WebInspector.UIString("Mouse Move")],
-[inputEvent.MouseUp,WebInspector.UIString("Mouse Up")],
-[inputEvent.MouseWheel,WebInspector.UIString("Mouse Wheel")],
-[inputEvent.ScrollBegin,WebInspector.UIString("Scroll Begin")],
-[inputEvent.ScrollEnd,WebInspector.UIString("Scroll End")],
-[inputEvent.ScrollUpdate,WebInspector.UIString("Scroll Update")],
-[inputEvent.FlingStart,WebInspector.UIString("Fling Start")],
-[inputEvent.FlingCancel,WebInspector.UIString("Fling Halt")],
-[inputEvent.Tap,WebInspector.UIString("Tap")],
-[inputEvent.TapCancel,WebInspector.UIString("Tap Halt")],
-[inputEvent.ShowPress,WebInspector.UIString("Tap Begin")],
-[inputEvent.TapDown,WebInspector.UIString("Tap Down")],
-[inputEvent.TouchCancel,WebInspector.UIString("Touch Cancel")],
-[inputEvent.TouchEnd,WebInspector.UIString("Touch End")],
-[inputEvent.TouchMove,WebInspector.UIString("Touch Move")],
-[inputEvent.TouchStart,WebInspector.UIString("Touch Start")],
-[inputEvent.PinchBegin,WebInspector.UIString("Pinch Begin")],
-[inputEvent.PinchEnd,WebInspector.UIString("Pinch End")],
-[inputEvent.PinchUpdate,WebInspector.UIString("Pinch Update")]]);
-
-}
-return WebInspector.TimelineUIUtils._inputEventToDisplayName.get(inputEventType)||null;
-};
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.testContentMatching=function(traceEvent,regExp)
-{
-var title=WebInspector.TimelineUIUtils.eventStyle(traceEvent).title;
-var tokens=[title];
-if(traceEvent.url)
-tokens.push(traceEvent.url);
-for(var argName in traceEvent.args){
-var argValue=traceEvent.args[argName];
-for(var key in argValue)
-tokens.push(argValue[key]);
-}
-return regExp.test(tokens.join("|"));
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.categoryForRecord=function(record)
-{
-return WebInspector.TimelineUIUtils.eventStyle(record.traceEvent()).category;
-};
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.eventStyle=function(event)
-{
-var eventStyles=WebInspector.TimelineUIUtils._initEventStyles();
-if(event.hasCategory(WebInspector.TimelineModel.Category.Console)||event.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
-return{title:event.name,category:WebInspector.TimelineUIUtils.categories()["scripting"]};
-
-if(event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)){
-
-var prefix="InputLatency::";
-var inputEventType=event.name.startsWith(prefix)?event.name.substr(prefix.length):event.name;
-var displayName=WebInspector.TimelineUIUtils.inputEventDisplayName(inputEventType);
-return{title:displayName||inputEventType,category:WebInspector.TimelineUIUtils.categories()["scripting"]};
-}
-var result=eventStyles[event.name];
-if(!result){
-result=new WebInspector.TimelineRecordStyle(event.name,WebInspector.TimelineUIUtils.categories()["other"],true);
-eventStyles[event.name]=result;
-}
-return result;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.eventColor=function(event)
-{
-if(event.name===WebInspector.TimelineModel.RecordType.JSFrame){
-var frame=event.args["data"];
-if(WebInspector.TimelineUIUtils.isUserFrame(frame))
-return WebInspector.TimelineUIUtils.colorForURL(frame.url);
-}
-return WebInspector.TimelineUIUtils.eventStyle(event).category.color;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.eventTitle=function(event)
-{
-var title=WebInspector.TimelineUIUtils.eventStyle(event).title;
-if(event.hasCategory(WebInspector.TimelineModel.Category.Console))
-return title;
-if(event.name===WebInspector.TimelineModel.RecordType.TimeStamp)
-return WebInspector.UIString("%s: %s",title,event.args["data"]["message"]);
-if(event.name===WebInspector.TimelineModel.RecordType.Animation&&event.args["data"]&&event.args["data"]["name"])
-return WebInspector.UIString("%s: %s",title,event.args["data"]["name"]);
-return title;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.eventURL=function(event)
-{
-if(event.url)
-return event.url;
-var data=event.args["data"]||event.args["beginData"];
-return data&&data.url||null;
-};
-
-
-
-
-WebInspector.TimelineUIUtils._interactionPhaseStyles=function()
-{
-var map=WebInspector.TimelineUIUtils._interactionPhaseStylesMap;
-if(!map){
-map=new Map([
-[WebInspector.TimelineIRModel.Phases.Idle,{color:"white",label:"Idle"}],
-[WebInspector.TimelineIRModel.Phases.Response,{color:"hsl(43, 83%, 64%)",label:WebInspector.UIString("Response")}],
-[WebInspector.TimelineIRModel.Phases.Scroll,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Scroll")}],
-[WebInspector.TimelineIRModel.Phases.Fling,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Fling")}],
-[WebInspector.TimelineIRModel.Phases.Drag,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Drag")}],
-[WebInspector.TimelineIRModel.Phases.Animation,{color:"hsl(256, 67%, 70%)",label:WebInspector.UIString("Animation")}],
-[WebInspector.TimelineIRModel.Phases.Uncategorized,{color:"hsl(0, 0%, 87%)",label:WebInspector.UIString("Uncategorized")}]]);
-
-WebInspector.TimelineUIUtils._interactionPhaseStylesMap=map;
-}
-return map;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.interactionPhaseColor=function(phase)
-{
-return WebInspector.TimelineUIUtils._interactionPhaseStyles().get(phase).color;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.interactionPhaseLabel=function(phase)
-{
-return WebInspector.TimelineUIUtils._interactionPhaseStyles().get(phase).label;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.isUserFrame=function(frame)
-{
-return frame.scriptId!=="0"&&!(frame.url&&frame.url.startsWith("native "));
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.topStackFrame=function(event)
-{
-var stackTrace=event.stackTrace||event.initiator&&event.initiator.stackTrace;
-return stackTrace&&stackTrace.length?stackTrace[0]:null;
-};
-
-
-
-
-WebInspector.TimelineUIUtils.NetworkCategory={
-HTML:Symbol("HTML"),
-Script:Symbol("Script"),
-Style:Symbol("Style"),
-Media:Symbol("Media"),
-Other:Symbol("Other")};
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.networkRequestCategory=function(request)
-{
-var categories=WebInspector.TimelineUIUtils.NetworkCategory;
-switch(request.mimeType){
-case"text/html":
-return categories.HTML;
-case"application/javascript":
-case"application/x-javascript":
-case"text/javascript":
-return categories.Script;
-case"text/css":
-return categories.Style;
-case"audio/ogg":
-case"image/gif":
-case"image/jpeg":
-case"image/png":
-case"image/svg+xml":
-case"image/webp":
-case"image/x-icon":
-case"font/opentype":
-case"font/woff2":
-case"application/font-woff":
-return categories.Media;
-default:
-return categories.Other;}
-
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.networkCategoryColor=function(category)
-{
-var categories=WebInspector.TimelineUIUtils.NetworkCategory;
-switch(category){
-case categories.HTML:return"hsl(214, 67%, 66%)";
-case categories.Script:return"hsl(43, 83%, 64%)";
-case categories.Style:return"hsl(256, 67%, 70%)";
-case categories.Media:return"hsl(109, 33%, 55%)";
-default:return"hsl(0, 0%, 70%)";}
-
-};
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent=function(event,target)
-{
-var recordType=WebInspector.TimelineModel.RecordType;
-var detailsText;
-var eventData=event.args["data"];
-switch(event.name){
-case recordType.GCEvent:
-case recordType.MajorGC:
-case recordType.MinorGC:
-var delta=event.args["usedHeapSizeBefore"]-event.args["usedHeapSizeAfter"];
-detailsText=WebInspector.UIString("%s collected",Number.bytesToString(delta));
-break;
-case recordType.FunctionCall:
-
-if(eventData)
-detailsText=linkifyLocationAsText(eventData["scriptId"],eventData["lineNumber"],0);
-break;
-case recordType.JSFrame:
-detailsText=WebInspector.beautifyFunctionName(eventData["functionName"]);
-break;
-case recordType.EventDispatch:
-detailsText=eventData?eventData["type"]:null;
-break;
-case recordType.Paint:
-var width=WebInspector.TimelineUIUtils.quadWidth(eventData.clip);
-var height=WebInspector.TimelineUIUtils.quadHeight(eventData.clip);
-if(width&&height)
-detailsText=WebInspector.UIString("%d\u2009\u00d7\u2009%d",width,height);
-break;
-case recordType.ParseHTML:
-var endLine=event.args["endData"]&&event.args["endData"]["endLine"];
-var url=WebInspector.displayNameForURL(event.args["beginData"]["url"]);
-detailsText=WebInspector.UIString("%s [%s\u2026%s]",url,event.args["beginData"]["startLine"]+1,endLine>=0?endLine+1:"");
-break;
-
-case recordType.CompileScript:
-case recordType.EvaluateScript:
-var url=eventData["url"];
-if(url)
-detailsText=WebInspector.displayNameForURL(url)+":"+(eventData["lineNumber"]+1);
-break;
-case recordType.ParseScriptOnBackground:
-case recordType.XHRReadyStateChange:
-case recordType.XHRLoad:
-var url=eventData["url"];
-if(url)
-detailsText=WebInspector.displayNameForURL(url);
-break;
-case recordType.TimeStamp:
-detailsText=eventData["message"];
-break;
-
-case recordType.WebSocketCreate:
-case recordType.WebSocketSendHandshakeRequest:
-case recordType.WebSocketReceiveHandshakeResponse:
-case recordType.WebSocketDestroy:
-case recordType.ResourceSendRequest:
-case recordType.ResourceReceivedData:
-case recordType.ResourceReceiveResponse:
-case recordType.ResourceFinish:
-case recordType.PaintImage:
-case recordType.DecodeImage:
-case recordType.ResizeImage:
-case recordType.DecodeLazyPixelRef:
-if(event.url)
-detailsText=WebInspector.displayNameForURL(event.url);
-break;
-
-case recordType.EmbedderCallback:
-detailsText=eventData["callbackName"];
-break;
-
-case recordType.Animation:
-detailsText=eventData&&eventData["name"];
-break;
-
-case recordType.GCIdleLazySweep:
-detailsText=WebInspector.UIString("idle sweep");
-break;
-
-case recordType.GCCompleteSweep:
-detailsText=WebInspector.UIString("complete sweep");
-break;
-
-case recordType.GCCollectGarbage:
-detailsText=WebInspector.UIString("collect");
-break;
-
-default:
-if(event.hasCategory(WebInspector.TimelineModel.Category.Console))
-detailsText=null;else
-
-detailsText=linkifyTopCallFrameAsText();
-break;}
-
-
-return detailsText;
-
-
-
-
-
-
-
-function linkifyLocationAsText(scriptId,lineNumber,columnNumber)
-{
-var debuggerModel=WebInspector.DebuggerModel.fromTarget(target);
-if(!target||target.isDetached()||!scriptId||!debuggerModel)
-return null;
-var rawLocation=debuggerModel.createRawLocationByScriptId(scriptId,lineNumber,columnNumber);
-if(!rawLocation)
-return null;
-var uiLocation=WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
-return uiLocation.linkText();
-}
-
-
-
-
-function linkifyTopCallFrameAsText()
-{
-var frame=WebInspector.TimelineUIUtils.topStackFrame(event);
-if(!frame)
-return null;
-var text=linkifyLocationAsText(frame.scriptId,frame.lineNumber,frame.columnNumber);
-if(!text){
-text=frame.url;
-if(typeof frame.lineNumber==="number")
-text+=":"+(frame.lineNumber+1);
-}
-return text;
-}
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent=function(event,target,linkifier)
-{
-var recordType=WebInspector.TimelineModel.RecordType;
-var details=null;
-var detailsText;
-var eventData=event.args["data"];
-switch(event.name){
-case recordType.GCEvent:
-case recordType.MajorGC:
-case recordType.MinorGC:
-case recordType.EventDispatch:
-case recordType.Paint:
-case recordType.Animation:
-case recordType.EmbedderCallback:
-case recordType.ParseHTML:
-case recordType.WebSocketCreate:
-case recordType.WebSocketSendHandshakeRequest:
-case recordType.WebSocketReceiveHandshakeResponse:
-case recordType.WebSocketDestroy:
-case recordType.GCIdleLazySweep:
-case recordType.GCCompleteSweep:
-case recordType.GCCollectGarbage:
-detailsText=WebInspector.TimelineUIUtils.buildDetailsTextForTraceEvent(event,target);
-break;
-case recordType.PaintImage:
-case recordType.DecodeImage:
-case recordType.ResizeImage:
-case recordType.DecodeLazyPixelRef:
-case recordType.XHRReadyStateChange:
-case recordType.XHRLoad:
-case recordType.ResourceSendRequest:
-case recordType.ResourceReceivedData:
-case recordType.ResourceReceiveResponse:
-case recordType.ResourceFinish:
-if(event.url)
-details=WebInspector.linkifyResourceAsNode(event.url);
-break;
-case recordType.FunctionCall:
-case recordType.JSFrame:
-details=createElement("span");
-details.createTextChild(WebInspector.beautifyFunctionName(eventData["functionName"]));
-var location=linkifyLocation(eventData["scriptId"],eventData["url"],eventData["lineNumber"],eventData["columnNumber"]);
-if(location){
-details.createTextChild(" @ ");
-details.appendChild(location);
-}
-break;
-case recordType.CompileScript:
-case recordType.EvaluateScript:
-var url=eventData["url"];
-if(url)
-details=linkifyLocation("",url,eventData["lineNumber"],0);
-break;
-case recordType.ParseScriptOnBackground:
-var url=eventData["url"];
-if(url)
-details=linkifyLocation("",url,0,0);
-break;
-default:
-if(event.hasCategory(WebInspector.TimelineModel.Category.Console))
-detailsText=null;else
-
-details=linkifyTopCallFrame();
-break;}
-
-
-if(!details&&detailsText)
-details=createTextNode(detailsText);
-return details;
-
-
-
-
-
-
-
-
-function linkifyLocation(scriptId,url,lineNumber,columnNumber)
-{
-return linkifier.linkifyScriptLocation(target,scriptId,url,lineNumber,columnNumber,"timeline-details");
-}
-
-
-
-
-function linkifyTopCallFrame()
-{
-var frame=WebInspector.TimelineUIUtils.topStackFrame(event);
-return frame?linkifier.maybeLinkifyConsoleCallFrame(target,frame,"timeline-details"):null;
-}
-};
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.buildTraceEventDetails=function(event,model,linkifier,detailed,callback)
-{
-var target=model.targetByEvent(event);
-if(!target){
-callbackWrapper();
-return;
-}
-var relatedNodes=null;
-var barrier=new CallbackBarrier();
-if(!event.previewElement){
-if(event.url)
-WebInspector.DOMPresentationUtils.buildImagePreviewContents(target,event.url,false,barrier.createCallback(saveImage));else
-if(event.picture)
-WebInspector.TimelineUIUtils.buildPicturePreviewContent(event,target,barrier.createCallback(saveImage));
-}
-var nodeIdsToResolve=new Set();
-if(event.backendNodeId)
-nodeIdsToResolve.add(event.backendNodeId);
-if(event.invalidationTrackingEvents)
-WebInspector.TimelineUIUtils._collectInvalidationNodeIds(nodeIdsToResolve,event.invalidationTrackingEvents);
-if(nodeIdsToResolve.size){
-var domModel=WebInspector.DOMModel.fromTarget(target);
-if(domModel)
-domModel.pushNodesByBackendIdsToFrontend(nodeIdsToResolve,barrier.createCallback(setRelatedNodeMap));
-}
-barrier.callWhenDone(callbackWrapper);
-
-
-
-
-function saveImage(element)
-{
-event.previewElement=element||null;
-}
-
-
-
-
-function setRelatedNodeMap(nodeMap)
-{
-relatedNodes=nodeMap;
-}
-
-function callbackWrapper()
-{
-callback(WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously(event,model,linkifier,detailed,relatedNodes));
-}
-};
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils._buildTraceEventDetailsSynchronously=function(event,model,linkifier,detailed,relatedNodesMap)
-{
-var stats={};
-var recordTypes=WebInspector.TimelineModel.RecordType;
-
-
-var relatedNodeLabel;
-
-var contentHelper=new WebInspector.TimelineDetailsContentHelper(model.targetByEvent(event),linkifier);
-contentHelper.addSection(WebInspector.TimelineUIUtils.eventTitle(event),WebInspector.TimelineUIUtils.eventStyle(event).category);
-
-var eventData=event.args["data"];
-var initiator=event.initiator;
-
-if(event.warning)
-contentHelper.appendWarningRow(event);
-if(event.name===recordTypes.JSFrame&&eventData["deoptReason"])
-contentHelper.appendWarningRow(event,WebInspector.TimelineModel.WarningType.V8Deopt);
-
-if(detailed){
-contentHelper.appendTextRow(WebInspector.UIString("Self Time"),Number.millisToString(event.selfTime,true));
-contentHelper.appendTextRow(WebInspector.UIString("Total Time"),Number.millisToString(event.duration||0,true));
-}
-
-switch(event.name){
-case recordTypes.GCEvent:
-case recordTypes.MajorGC:
-case recordTypes.MinorGC:
-var delta=event.args["usedHeapSizeBefore"]-event.args["usedHeapSizeAfter"];
-contentHelper.appendTextRow(WebInspector.UIString("Collected"),Number.bytesToString(delta));
-break;
-case recordTypes.JSFrame:
-case recordTypes.FunctionCall:
-var detailsNode=WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event,model.targetByEvent(event),linkifier);
-if(detailsNode)
-contentHelper.appendElementRow(WebInspector.UIString("Function"),detailsNode);
-break;
-case recordTypes.TimerFire:
-case recordTypes.TimerInstall:
-case recordTypes.TimerRemove:
-contentHelper.appendTextRow(WebInspector.UIString("Timer ID"),eventData["timerId"]);
-if(event.name===recordTypes.TimerInstall){
-contentHelper.appendTextRow(WebInspector.UIString("Timeout"),Number.millisToString(eventData["timeout"]));
-contentHelper.appendTextRow(WebInspector.UIString("Repeats"),!eventData["singleShot"]);
-}
-break;
-case recordTypes.FireAnimationFrame:
-contentHelper.appendTextRow(WebInspector.UIString("Callback ID"),eventData["id"]);
-break;
-case recordTypes.ResourceSendRequest:
-case recordTypes.ResourceReceiveResponse:
-case recordTypes.ResourceReceivedData:
-case recordTypes.ResourceFinish:
-var url=event.name===recordTypes.ResourceSendRequest?eventData["url"]:initiator&&initiator.args["data"]["url"];
-if(url)
-contentHelper.appendElementRow(WebInspector.UIString("Resource"),WebInspector.linkifyResourceAsNode(url));
-if(eventData["requestMethod"])
-contentHelper.appendTextRow(WebInspector.UIString("Request Method"),eventData["requestMethod"]);
-if(typeof eventData["statusCode"]==="number")
-contentHelper.appendTextRow(WebInspector.UIString("Status Code"),eventData["statusCode"]);
-if(eventData["mimeType"])
-contentHelper.appendTextRow(WebInspector.UIString("MIME Type"),eventData["mimeType"]);
-if("priority"in eventData){
-var priority=WebInspector.uiLabelForPriority(eventData["priority"]);
-contentHelper.appendTextRow(WebInspector.UIString("Priority"),priority);
-}
-if(eventData["encodedDataLength"])
-contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"),WebInspector.UIString("%d Bytes",eventData["encodedDataLength"]));
-break;
-case recordTypes.CompileScript:
-case recordTypes.EvaluateScript:
-var url=eventData["url"];
-if(url)
-contentHelper.appendLocationRow(WebInspector.UIString("Script"),url,eventData["lineNumber"],eventData["columnNumber"]);
-break;
-case recordTypes.Paint:
-var clip=eventData["clip"];
-contentHelper.appendTextRow(WebInspector.UIString("Location"),WebInspector.UIString("(%d, %d)",clip[0],clip[1]));
-var clipWidth=WebInspector.TimelineUIUtils.quadWidth(clip);
-var clipHeight=WebInspector.TimelineUIUtils.quadHeight(clip);
-contentHelper.appendTextRow(WebInspector.UIString("Dimensions"),WebInspector.UIString("%d × %d",clipWidth,clipHeight));
-
-
-case recordTypes.PaintSetup:
-case recordTypes.Rasterize:
-case recordTypes.ScrollLayer:
-relatedNodeLabel=WebInspector.UIString("Layer Root");
-break;
-case recordTypes.PaintImage:
-case recordTypes.DecodeLazyPixelRef:
-case recordTypes.DecodeImage:
-case recordTypes.ResizeImage:
-case recordTypes.DrawLazyPixelRef:
-relatedNodeLabel=WebInspector.UIString("Owner Element");
-if(event.url)
-contentHelper.appendElementRow(WebInspector.UIString("Image URL"),WebInspector.linkifyResourceAsNode(event.url));
-break;
-case recordTypes.ParseAuthorStyleSheet:
-var url=eventData["styleSheetUrl"];
-if(url)
-contentHelper.appendElementRow(WebInspector.UIString("Stylesheet URL"),WebInspector.linkifyResourceAsNode(url));
-break;
-case recordTypes.UpdateLayoutTree:
-case recordTypes.RecalculateStyles:
-contentHelper.appendTextRow(WebInspector.UIString("Elements Affected"),event.args["elementCount"]);
-break;
-case recordTypes.Layout:
-var beginData=event.args["beginData"];
-contentHelper.appendTextRow(WebInspector.UIString("Nodes That Need Layout"),WebInspector.UIString("%s of %s",beginData["dirtyObjects"],beginData["totalObjects"]));
-relatedNodeLabel=WebInspector.UIString("Layout root");
-break;
-case recordTypes.ConsoleTime:
-contentHelper.appendTextRow(WebInspector.UIString("Message"),event.name);
-break;
-case recordTypes.WebSocketCreate:
-case recordTypes.WebSocketSendHandshakeRequest:
-case recordTypes.WebSocketReceiveHandshakeResponse:
-case recordTypes.WebSocketDestroy:
-var initiatorData=initiator?initiator.args["data"]:eventData;
-if(typeof initiatorData["webSocketURL"]!=="undefined")
-contentHelper.appendTextRow(WebInspector.UIString("URL"),initiatorData["webSocketURL"]);
-if(typeof initiatorData["webSocketProtocol"]!=="undefined")
-contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"),initiatorData["webSocketProtocol"]);
-if(typeof eventData["message"]!=="undefined")
-contentHelper.appendTextRow(WebInspector.UIString("Message"),eventData["message"]);
-break;
-case recordTypes.EmbedderCallback:
-contentHelper.appendTextRow(WebInspector.UIString("Callback Function"),eventData["callbackName"]);
-break;
-case recordTypes.Animation:
-if(event.phase===WebInspector.TracingModel.Phase.NestableAsyncInstant)
-contentHelper.appendTextRow(WebInspector.UIString("State"),eventData["state"]);
-break;
-case recordTypes.ParseHTML:
-var beginData=event.args["beginData"];
-var url=beginData["url"];
-var startLine=beginData["startLine"]-1;
-var endLine=event.args["endData"]?event.args["endData"]["endLine"]-1:undefined;
-if(url)
-contentHelper.appendLocationRange(WebInspector.UIString("Range"),url,startLine,endLine);
-break;
-
-case recordTypes.FireIdleCallback:
-contentHelper.appendTextRow(WebInspector.UIString("Allotted Time"),Number.millisToString(eventData["allottedMilliseconds"]));
-contentHelper.appendTextRow(WebInspector.UIString("Invoked by Timeout"),eventData["timedOut"]);
-
-
-case recordTypes.RequestIdleCallback:
-case recordTypes.CancelIdleCallback:
-contentHelper.appendTextRow(WebInspector.UIString("Callback ID"),eventData["id"]);
-break;
-case recordTypes.EventDispatch:
-contentHelper.appendTextRow(WebInspector.UIString("Type"),eventData["type"]);
-break;
-
-default:
-var detailsNode=WebInspector.TimelineUIUtils.buildDetailsNodeForTraceEvent(event,model.targetByEvent(event),linkifier);
-if(detailsNode)
-contentHelper.appendElementRow(WebInspector.UIString("Details"),detailsNode);
-break;}
-
-
-if(event.timeWaitingForMainThread)
-contentHelper.appendTextRow(WebInspector.UIString("Time Waiting for Main Thread"),Number.millisToString(event.timeWaitingForMainThread,true));
-
-var relatedNode=relatedNodesMap&&relatedNodesMap.get(event.backendNodeId);
-if(relatedNode)
-contentHelper.appendElementRow(relatedNodeLabel||WebInspector.UIString("Related Node"),WebInspector.DOMPresentationUtils.linkifyNodeReference(relatedNode));
-
-if(event.previewElement){
-contentHelper.addSection(WebInspector.UIString("Preview"));
-contentHelper.appendElementRow("",event.previewElement);
-}
-
-if(event.stackTrace||event.initiator&&event.initiator.stackTrace||event.invalidationTrackingEvents)
-WebInspector.TimelineUIUtils._generateCauses(event,model.targetByEvent(event),relatedNodesMap,contentHelper);
-
-var showPieChart=detailed&&WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent(stats,model,event);
-if(showPieChart){
-contentHelper.addSection(WebInspector.UIString("Aggregated Time"));
-var pieChart=WebInspector.TimelineUIUtils.generatePieChart(stats,WebInspector.TimelineUIUtils.eventStyle(event).category,event.selfTime);
-contentHelper.appendElementRow("",pieChart);
-}
-
-return contentHelper.fragment;
-};
-
-WebInspector.TimelineUIUtils._aggregatedStatsKey=Symbol("aggregatedStats");
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.buildRangeStats=function(model,startTime,endTime)
-{
-var aggregatedStats={};
-
-
-
-
-
-
-function compareEndTime(value,task)
-{
-return value<task.endTime()?-1:1;
-}
-var mainThreadTasks=model.mainThreadTasks();
-var taskIndex=mainThreadTasks.lowerBound(startTime,compareEndTime);
-for(;taskIndex<mainThreadTasks.length;++taskIndex){
-var task=mainThreadTasks[taskIndex];
-if(task.startTime()>endTime)
-break;
-if(task.startTime()>startTime&&task.endTime()<endTime){
-
-var taskStats=task[WebInspector.TimelineUIUtils._aggregatedStatsKey];
-if(!taskStats){
-taskStats={};
-WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(task,startTime,endTime,taskStats);
-task[WebInspector.TimelineUIUtils._aggregatedStatsKey]=taskStats;
-}
-for(var key in taskStats)
-aggregatedStats[key]=(aggregatedStats[key]||0)+taskStats[key];
-continue;
-}
-WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(task,startTime,endTime,aggregatedStats);
-}
-
-var aggregatedTotal=0;
-for(var categoryName in aggregatedStats)
-aggregatedTotal+=aggregatedStats[categoryName];
-aggregatedStats["idle"]=Math.max(0,endTime-startTime-aggregatedTotal);
-
-var startOffset=startTime-model.minimumRecordTime();
-var endOffset=endTime-model.minimumRecordTime();
-
-var contentHelper=new WebInspector.TimelineDetailsContentHelper(null,null);
-contentHelper.addSection(WebInspector.UIString("Range:  %s \u2013 %s",Number.millisToString(startOffset),Number.millisToString(endOffset)));
-var pieChart=WebInspector.TimelineUIUtils.generatePieChart(aggregatedStats);
-contentHelper.appendElementRow("",pieChart);
-return contentHelper.fragment;
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord=function(record,startTime,endTime,aggregatedStats)
-{
-var records=[];
-
-if(!record.endTime()||record.endTime()<startTime||record.startTime()>endTime)
-return;
-
-var childrenTime=0;
-var children=record.children()||[];
-for(var i=0;i<children.length;++i){
-var child=children[i];
-if(!child.endTime()||child.endTime()<startTime||child.startTime()>endTime)
-continue;
-childrenTime+=Math.min(endTime,child.endTime())-Math.max(startTime,child.startTime());
-WebInspector.TimelineUIUtils._collectAggregatedStatsForRecord(child,startTime,endTime,aggregatedStats);
-}
-var categoryName=WebInspector.TimelineUIUtils.categoryForRecord(record).name;
-var ownTime=Math.min(endTime,record.endTime())-Math.max(startTime,record.startTime())-childrenTime;
-aggregatedStats[categoryName]=(aggregatedStats[categoryName]||0)+ownTime;
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.buildNetworkRequestDetails=function(request,model,linkifier)
-{
-var target=model.targetByEvent(request.children[0]);
-var contentHelper=new WebInspector.TimelineDetailsContentHelper(target,linkifier);
-
-var duration=request.endTime-(request.startTime||-Infinity);
-var items=[];
-if(request.url)
-contentHelper.appendElementRow(WebInspector.UIString("URL"),WebInspector.linkifyURLAsNode(request.url));
-if(isFinite(duration))
-contentHelper.appendTextRow(WebInspector.UIString("Duration"),Number.millisToString(duration,true));
-if(request.requestMethod)
-contentHelper.appendTextRow(WebInspector.UIString("Request Method"),request.requestMethod);
-if(typeof request.priority==="string"){
-var priority=WebInspector.uiLabelForPriority(request.priority);
-contentHelper.appendTextRow(WebInspector.UIString("Priority"),priority);
-}
-if(request.mimeType)
-contentHelper.appendTextRow(WebInspector.UIString("Mime Type"),request.mimeType);
-
-var title=WebInspector.UIString("Initiator");
-var sendRequest=request.children[0];
-var topFrame=WebInspector.TimelineUIUtils.topStackFrame(sendRequest);
-if(topFrame){
-var link=linkifier.maybeLinkifyConsoleCallFrame(target,topFrame);
-if(link)
-contentHelper.appendElementRow(title,link);
-}else if(sendRequest.initiator){
-var initiatorURL=WebInspector.TimelineUIUtils.eventURL(sendRequest.initiator);
-if(initiatorURL){
-var link=linkifier.maybeLinkifyScriptLocation(target,null,initiatorURL,0);
-if(link)
-contentHelper.appendElementRow(title,link);
-}
-}
-
-
-
-
-function action(fulfill)
-{
-WebInspector.DOMPresentationUtils.buildImagePreviewContents(target,request.url,false,saveImage);
-
-
-
-function saveImage(element)
-{
-request.previewElement=element||null;
-fulfill(request.previewElement);
-}
-}
-var previewPromise;
-if(request.previewElement)
-previewPromise=Promise.resolve(request.previewElement);else
-
-previewPromise=request.url&&target?new Promise(action):Promise.resolve(null);
-
-
-
-
-function appendPreview(element)
-{
-if(element)
-contentHelper.appendElementRow(WebInspector.UIString("Preview"),request.previewElement);
-return contentHelper.fragment;
-}
-return previewPromise.then(appendPreview);
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils._stackTraceFromCallFrames=function(callFrames)
-{
-return{callFrames:callFrames};
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils._generateCauses=function(event,target,relatedNodesMap,contentHelper)
-{
-var recordTypes=WebInspector.TimelineModel.RecordType;
-
-var callSiteStackLabel;
-var stackLabel;
-var initiator=event.initiator;
-
-switch(event.name){
-case recordTypes.TimerFire:
-callSiteStackLabel=WebInspector.UIString("Timer Installed");
-break;
-case recordTypes.FireAnimationFrame:
-callSiteStackLabel=WebInspector.UIString("Animation Frame Requested");
-break;
-case recordTypes.FireIdleCallback:
-callSiteStackLabel=WebInspector.UIString("Idle Callback Requested");
-break;
-case recordTypes.UpdateLayoutTree:
-case recordTypes.RecalculateStyles:
-stackLabel=WebInspector.UIString("Recalculation Forced");
-break;
-case recordTypes.Layout:
-callSiteStackLabel=WebInspector.UIString("First Layout Invalidation");
-stackLabel=WebInspector.UIString("Layout Forced");
-break;}
-
-
-
-if(event.stackTrace&&event.stackTrace.length){
-contentHelper.addSection(WebInspector.UIString("Call Stacks"));
-contentHelper.appendStackTrace(stackLabel||WebInspector.UIString("Stack Trace"),WebInspector.TimelineUIUtils._stackTraceFromCallFrames(event.stackTrace));
-}
-
-
-if(event.invalidationTrackingEvents&&target){
-contentHelper.addSection(WebInspector.UIString("Invalidations"));
-WebInspector.TimelineUIUtils._generateInvalidations(event,target,relatedNodesMap,contentHelper);
-}else if(initiator&&initiator.stackTrace){
-contentHelper.appendStackTrace(callSiteStackLabel||WebInspector.UIString("First Invalidated"),WebInspector.TimelineUIUtils._stackTraceFromCallFrames(initiator.stackTrace));
-}
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils._generateInvalidations=function(event,target,relatedNodesMap,contentHelper)
-{
-if(!event.invalidationTrackingEvents)
-return;
-
-var invalidations={};
-event.invalidationTrackingEvents.forEach(function(invalidation){
-if(!invalidations[invalidation.type])
-invalidations[invalidation.type]=[invalidation];else
-
-invalidations[invalidation.type].push(invalidation);
-});
-
-Object.keys(invalidations).forEach(function(type){
-WebInspector.TimelineUIUtils._generateInvalidationsForType(
-type,target,invalidations[type],relatedNodesMap,contentHelper);
-});
-};
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils._generateInvalidationsForType=function(type,target,invalidations,relatedNodesMap,contentHelper)
-{
-var title;
-switch(type){
-case WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking:
-title=WebInspector.UIString("Style Invalidations");
-break;
-case WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking:
-title=WebInspector.UIString("Layout Invalidations");
-break;
-default:
-title=WebInspector.UIString("Other Invalidations");
-break;}
-
-
-var invalidationsTreeOutline=new TreeOutlineInShadow();
-invalidationsTreeOutline.registerRequiredCSS("timeline/invalidationsTree.css");
-invalidationsTreeOutline.element.classList.add("invalidations-tree");
-
-var invalidationGroups=groupInvalidationsByCause(invalidations);
-invalidationGroups.forEach(function(group){
-var groupElement=new WebInspector.TimelineUIUtils.InvalidationsGroupElement(target,relatedNodesMap,contentHelper,group);
-invalidationsTreeOutline.appendChild(groupElement);
-});
-contentHelper.appendElementRow(title,invalidationsTreeOutline.element,false,true);
-
-
-
-
-
-function groupInvalidationsByCause(invalidations)
-{
-
-var causeToInvalidationMap=new Map();
-for(var index=0;index<invalidations.length;index++){
-var invalidation=invalidations[index];
-var causeKey="";
-if(invalidation.cause.reason)
-causeKey+=invalidation.cause.reason+".";
-if(invalidation.cause.stackTrace){
-invalidation.cause.stackTrace.forEach(function(stackFrame){
-causeKey+=stackFrame["functionName"]+".";
-causeKey+=stackFrame["scriptId"]+".";
-causeKey+=stackFrame["url"]+".";
-causeKey+=stackFrame["lineNumber"]+".";
-causeKey+=stackFrame["columnNumber"]+".";
-});
-}
-
-if(causeToInvalidationMap.has(causeKey))
-causeToInvalidationMap.get(causeKey).push(invalidation);else
-
-causeToInvalidationMap.set(causeKey,[invalidation]);
-}
-return causeToInvalidationMap.valuesArray();
-}
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils._collectInvalidationNodeIds=function(nodeIds,invalidations)
-{
-for(var i=0;i<invalidations.length;++i){
-if(invalidations[i].nodeId)
-nodeIds.add(invalidations[i].nodeId);
-}
-};
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.InvalidationsGroupElement=function(target,relatedNodesMap,contentHelper,invalidations)
-{
-TreeElement.call(this,"",true);
-
-this.listItemElement.classList.add("header");
-this.selectable=false;
-this.toggleOnClick=true;
-
-this._relatedNodesMap=relatedNodesMap;
-this._contentHelper=contentHelper;
-this._invalidations=invalidations;
-this.title=this._createTitle(target);
-};
-
-WebInspector.TimelineUIUtils.InvalidationsGroupElement.prototype={
-
-
-
-
-
-_createTitle:function(target)
-{
-var first=this._invalidations[0];
-var reason=first.cause.reason;
-var topFrame=first.cause.stackTrace&&first.cause.stackTrace[0];
-
-var title=createElement("span");
-if(reason)
-title.createTextChild(WebInspector.UIString("%s for ",reason));else
-
-title.createTextChild(WebInspector.UIString("Unknown cause for "));
-
-this._appendTruncatedNodeList(title,this._invalidations);
-
-if(topFrame&&this._contentHelper.linkifier()){
-title.createTextChild(WebInspector.UIString(". "));
-var stack=title.createChild("span","monospace");
-stack.createChild("span").textContent=WebInspector.beautifyFunctionName(topFrame.functionName);
-var link=this._contentHelper.linkifier().maybeLinkifyConsoleCallFrame(target,topFrame);
-if(link){
-stack.createChild("span").textContent=" @ ";
-stack.createChild("span").appendChild(link);
-}
-}
-
-return title;
-},
-
-
-
-
-onpopulate:function()
-{
-var content=createElementWithClass("div","content");
-
-var first=this._invalidations[0];
-if(first.cause.stackTrace){
-var stack=content.createChild("div");
-stack.createTextChild(WebInspector.UIString("Stack trace:"));
-this._contentHelper.createChildStackTraceElement(stack,WebInspector.TimelineUIUtils._stackTraceFromCallFrames(first.cause.stackTrace));
-}
-
-content.createTextChild(this._invalidations.length>1?WebInspector.UIString("Nodes:"):WebInspector.UIString("Node:"));
-var nodeList=content.createChild("div","node-list");
-var firstNode=true;
-for(var i=0;i<this._invalidations.length;i++){
-var invalidation=this._invalidations[i];
-var invalidationNode=this._createInvalidationNode(invalidation,true);
-if(invalidationNode){
-if(!firstNode)
-nodeList.createTextChild(WebInspector.UIString(", "));
-firstNode=false;
-
-nodeList.appendChild(invalidationNode);
-
-var extraData=invalidation.extraData?", "+invalidation.extraData:"";
-if(invalidation.changedId)
-nodeList.createTextChild(WebInspector.UIString("(changed id to \"%s\"%s)",invalidation.changedId,extraData));else
-if(invalidation.changedClass)
-nodeList.createTextChild(WebInspector.UIString("(changed class to \"%s\"%s)",invalidation.changedClass,extraData));else
-if(invalidation.changedAttribute)
-nodeList.createTextChild(WebInspector.UIString("(changed attribute to \"%s\"%s)",invalidation.changedAttribute,extraData));else
-if(invalidation.changedPseudo)
-nodeList.createTextChild(WebInspector.UIString("(changed pesudo to \"%s\"%s)",invalidation.changedPseudo,extraData));else
-if(invalidation.selectorPart)
-nodeList.createTextChild(WebInspector.UIString("(changed \"%s\"%s)",invalidation.selectorPart,extraData));
-}
-}
-
-var contentTreeElement=new TreeElement(content,false);
-contentTreeElement.selectable=false;
-this.appendChild(contentTreeElement);
-},
-
-
-
-
-
-_appendTruncatedNodeList:function(parentElement,invalidations)
-{
-var invalidationNodes=[];
-var invalidationNodeIdMap={};
-for(var i=0;i<invalidations.length;i++){
-var invalidation=invalidations[i];
-var invalidationNode=this._createInvalidationNode(invalidation,false);
-invalidationNode.addEventListener("click",consumeEvent,false);
-if(invalidationNode&&!invalidationNodeIdMap[invalidation.nodeId]){
-invalidationNodes.push(invalidationNode);
-invalidationNodeIdMap[invalidation.nodeId]=true;
-}
-}
-
-if(invalidationNodes.length===1){
-parentElement.appendChild(invalidationNodes[0]);
-}else if(invalidationNodes.length===2){
-parentElement.appendChild(invalidationNodes[0]);
-parentElement.createTextChild(WebInspector.UIString(" and "));
-parentElement.appendChild(invalidationNodes[1]);
-}else if(invalidationNodes.length>=3){
-parentElement.appendChild(invalidationNodes[0]);
-parentElement.createTextChild(WebInspector.UIString(", "));
-parentElement.appendChild(invalidationNodes[1]);
-parentElement.createTextChild(WebInspector.UIString(", and %s others",invalidationNodes.length-2));
-}
-},
-
-
-
-
-
-_createInvalidationNode:function(invalidation,showUnknownNodes)
-{
-var node=invalidation.nodeId&&this._relatedNodesMap?this._relatedNodesMap.get(invalidation.nodeId):null;
-if(node)
-return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
-if(invalidation.nodeName){
-var nodeSpan=createElement("span");
-nodeSpan.textContent=WebInspector.UIString("[ %s ]",invalidation.nodeName);
-return nodeSpan;
-}
-if(showUnknownNodes){
-var nodeSpan=createElement("span");
-return nodeSpan.createTextChild(WebInspector.UIString("[ unknown node ]"));
-}
-},
-
-__proto__:TreeElement.prototype};
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils._aggregatedStatsForTraceEvent=function(total,model,event)
-{
-var events=model.inspectedTargetEvents();
-
-
-
-
-
-function eventComparator(startTime,e)
-{
-return startTime-e.startTime;
-}
-var index=events.binaryIndexOf(event.startTime,eventComparator);
-
-if(index<0)
-return false;
-var hasChildren=false;
-var endTime=event.endTime;
-if(endTime){
-for(var i=index;i<events.length;i++){
-var nextEvent=events[i];
-if(nextEvent.startTime>=endTime)
-break;
-if(!nextEvent.selfTime)
-continue;
-if(nextEvent.thread!==event.thread)
-continue;
-if(i>index)
-hasChildren=true;
-var categoryName=WebInspector.TimelineUIUtils.eventStyle(nextEvent).category.name;
-total[categoryName]=(total[categoryName]||0)+nextEvent.selfTime;
-}
-}
-if(WebInspector.TracingModel.isAsyncPhase(event.phase)){
-if(event.endTime){
-var aggregatedTotal=0;
-for(var categoryName in total)
-aggregatedTotal+=total[categoryName];
-total["idle"]=Math.max(0,event.endTime-event.startTime-aggregatedTotal);
-}
-return false;
-}
-return hasChildren;
-};
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.buildPicturePreviewContent=function(event,target,callback)
-{
-new WebInspector.LayerPaintEvent(event,target).loadSnapshot(onSnapshotLoaded);
-
-
-
-
-function onSnapshotLoaded(rect,snapshot)
-{
-if(!snapshot){
-callback();
-return;
-}
-snapshot.requestImage(null,null,1,onGotImage);
-snapshot.dispose();
-}
-
-
-
-
-function onGotImage(imageURL)
-{
-if(!imageURL){
-callback();
-return;
-}
-var container=createElement("div");
-container.classList.add("image-preview-container","vbox","link");
-var img=container.createChild("img");
-img.src=imageURL;
-var paintProfilerButton=container.createChild("a");
-paintProfilerButton.textContent=WebInspector.UIString("Paint Profiler");
-container.addEventListener("click",showPaintProfiler,false);
-callback(container);
-}
-
-function showPaintProfiler()
-{
-WebInspector.TimelinePanel.instance().select(WebInspector.TimelineSelection.fromTraceEvent(event),WebInspector.TimelinePanel.DetailsTab.PaintProfiler);
-}
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.createEventDivider=function(recordType,title,position)
-{
-var eventDivider=createElement("div");
-eventDivider.className="resources-event-divider";
-var recordTypes=WebInspector.TimelineModel.RecordType;
-
-if(recordType===recordTypes.MarkDOMContent)
-eventDivider.className+=" resources-blue-divider";else
-if(recordType===recordTypes.MarkLoad)
-eventDivider.className+=" resources-red-divider";else
-if(recordType===recordTypes.MarkFirstPaint)
-eventDivider.className+=" resources-green-divider";else
-if(recordType===recordTypes.TimeStamp||recordType===recordTypes.ConsoleTime||recordType===recordTypes.UserTiming)
-eventDivider.className+=" resources-orange-divider";else
-if(recordType===recordTypes.BeginFrame)
-eventDivider.className+=" timeline-frame-divider";
-
-if(title)
-eventDivider.title=title;
-eventDivider.style.left=position+"px";
-return eventDivider;
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.createDividerForRecord=function(record,zeroTime,position)
-{
-var startTime=Number.millisToString(record.startTime()-zeroTime);
-var title=WebInspector.UIString("%s at %s",WebInspector.TimelineUIUtils.eventTitle(record.traceEvent()),startTime);
-return WebInspector.TimelineUIUtils.createEventDivider(record.type(),title,position);
-};
-
-
-
-
-WebInspector.TimelineUIUtils._visibleTypes=function()
-{
-var eventStyles=WebInspector.TimelineUIUtils._initEventStyles();
-var result=[];
-for(var name in eventStyles){
-if(!eventStyles[name].hidden)
-result.push(name);
-}
-return result;
-};
-
-
-
-
-WebInspector.TimelineUIUtils.visibleEventsFilter=function()
-{
-return new WebInspector.TimelineVisibleEventsFilter(WebInspector.TimelineUIUtils._visibleTypes());
-};
-
-
-
-
-WebInspector.TimelineUIUtils.categories=function()
-{
-if(WebInspector.TimelineUIUtils._categories)
-return WebInspector.TimelineUIUtils._categories;
-WebInspector.TimelineUIUtils._categories={
-loading:new WebInspector.TimelineCategory("loading",WebInspector.UIString("Loading"),true,"hsl(214, 67%, 74%)","hsl(214, 67%, 66%)"),
-scripting:new WebInspector.TimelineCategory("scripting",WebInspector.UIString("Scripting"),true,"hsl(43, 83%, 72%)","hsl(43, 83%, 64%) "),
-rendering:new WebInspector.TimelineCategory("rendering",WebInspector.UIString("Rendering"),true,"hsl(256, 67%, 76%)","hsl(256, 67%, 70%)"),
-painting:new WebInspector.TimelineCategory("painting",WebInspector.UIString("Painting"),true,"hsl(109, 33%, 64%)","hsl(109, 33%, 55%)"),
-gpu:new WebInspector.TimelineCategory("gpu",WebInspector.UIString("GPU"),false,"hsl(109, 33%, 64%)","hsl(109, 33%, 55%)"),
-other:new WebInspector.TimelineCategory("other",WebInspector.UIString("Other"),false,"hsl(0, 0%, 87%)","hsl(0, 0%, 79%)"),
-idle:new WebInspector.TimelineCategory("idle",WebInspector.UIString("Idle"),false,"hsl(0, 100%, 100%)","hsl(0, 100%, 100%)")};
-
-return WebInspector.TimelineUIUtils._categories;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.titleForAsyncEventGroup=function(group)
-{
-if(!WebInspector.TimelineUIUtils._titleForAsyncEventGroupMap){
-var groups=WebInspector.TimelineModel.AsyncEventGroup;
-WebInspector.TimelineUIUtils._titleForAsyncEventGroupMap=new Map([
-[groups.animation,WebInspector.UIString("Animation")],
-[groups.console,WebInspector.UIString("Console")],
-[groups.userTiming,WebInspector.UIString("User Timing")],
-[groups.input,WebInspector.UIString("Input")]]);
-
-}
-return WebInspector.TimelineUIUtils._titleForAsyncEventGroupMap.get(group)||"";
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.generatePieChart=function(aggregatedStats,selfCategory,selfTime)
-{
-var total=0;
-for(var categoryName in aggregatedStats)
-total+=aggregatedStats[categoryName];
-
-var element=createElementWithClass("div","timeline-details-view-pie-chart-wrapper hbox");
-var pieChart=new WebInspector.PieChart(100);
-pieChart.element.classList.add("timeline-details-view-pie-chart");
-pieChart.setTotal(total);
-var pieChartContainer=element.createChild("div","vbox");
-pieChartContainer.appendChild(pieChart.element);
-pieChartContainer.createChild("div","timeline-details-view-pie-chart-total").textContent=WebInspector.UIString("Total: %s",Number.millisToString(total,true));
-var footerElement=element.createChild("div","timeline-aggregated-info-legend");
-
-
-
-
-
-
-
-function appendLegendRow(name,title,value,color)
-{
-if(!value)
-return;
-pieChart.addSlice(value,color);
-var rowElement=footerElement.createChild("div");
-rowElement.createChild("span","timeline-aggregated-legend-value").textContent=Number.preciseMillisToString(value,1);
-rowElement.createChild("span","timeline-aggregated-legend-swatch").style.backgroundColor=color;
-rowElement.createChild("span","timeline-aggregated-legend-title").textContent=title;
-}
-
-
-if(selfCategory){
-if(selfTime)
-appendLegendRow(selfCategory.name,WebInspector.UIString("%s (self)",selfCategory.title),selfTime,selfCategory.color);
-
-var categoryTime=aggregatedStats[selfCategory.name];
-var value=categoryTime-selfTime;
-if(value>0)
-appendLegendRow(selfCategory.name,WebInspector.UIString("%s (children)",selfCategory.title),value,selfCategory.childColor);
-}
-
-
-for(var categoryName in WebInspector.TimelineUIUtils.categories()){
-var category=WebInspector.TimelineUIUtils.categories()[categoryName];
-if(category===selfCategory)
-continue;
-appendLegendRow(category.name,category.title,aggregatedStats[category.name],category.childColor);
-}
-return element;
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.generateDetailsContentForFrame=function(frameModel,frame,filmStripFrame)
-{
-var pieChart=WebInspector.TimelineUIUtils.generatePieChart(frame.timeByCategory);
-var contentHelper=new WebInspector.TimelineDetailsContentHelper(null,null);
-contentHelper.addSection(WebInspector.UIString("Frame"));
-
-var duration=WebInspector.TimelineUIUtils.frameDuration(frame);
-contentHelper.appendElementRow(WebInspector.UIString("Duration"),duration,frame.hasWarnings());
-if(filmStripFrame){
-var filmStripPreview=createElementWithClass("img","timeline-filmstrip-preview");
-filmStripFrame.imageDataPromise().then(onGotImageData.bind(null,filmStripPreview));
-contentHelper.appendElementRow("",filmStripPreview);
-filmStripPreview.addEventListener("click",frameClicked.bind(null,filmStripFrame),false);
-}
-var durationInMillis=frame.endTime-frame.startTime;
-contentHelper.appendTextRow(WebInspector.UIString("FPS"),Math.floor(1000/durationInMillis));
-contentHelper.appendTextRow(WebInspector.UIString("CPU time"),Number.millisToString(frame.cpuTime,true));
-
-if(Runtime.experiments.isEnabled("layersPanel")&&frame.layerTree){
-contentHelper.appendElementRow(WebInspector.UIString("Layer tree"),
-WebInspector.Linkifier.linkifyUsingRevealer(frame.layerTree,WebInspector.UIString("show")));
-}
-
-
-
-
-
-function onGotImageData(image,data)
-{
-if(data)
-image.src="data:image/jpg;base64,"+data;
-}
-
-
-
-
-function frameClicked(filmStripFrame)
-{
-new WebInspector.FilmStripView.Dialog(filmStripFrame,0);
-}
-
-return contentHelper.fragment;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.frameDuration=function(frame)
-{
-var durationText=WebInspector.UIString("%s (at %s)",Number.millisToString(frame.endTime-frame.startTime,true),
-Number.millisToString(frame.startTimeOffset,true));
-var element=createElement("span");
-element.createTextChild(durationText);
-if(!frame.hasWarnings())
-return element;
-element.createTextChild(WebInspector.UIString(". Long frame times are an indication of "));
-element.appendChild(WebInspector.linkifyURLAsNode("https://developers.google.com/web/fundamentals/performance/rendering/",
-WebInspector.UIString("jank"),undefined,true));
-element.createTextChild(".");
-return element;
-};
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.createFillStyle=function(context,width,height,color0,color1,color2)
-{
-var gradient=context.createLinearGradient(0,0,width,height);
-gradient.addColorStop(0,color0);
-gradient.addColorStop(0.25,color1);
-gradient.addColorStop(0.75,color1);
-gradient.addColorStop(1,color2);
-return gradient;
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.quadWidth=function(quad)
-{
-return Math.round(Math.sqrt(Math.pow(quad[0]-quad[2],2)+Math.pow(quad[1]-quad[3],2)));
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.quadHeight=function(quad)
-{
-return Math.round(Math.sqrt(Math.pow(quad[0]-quad[6],2)+Math.pow(quad[1]-quad[7],2)));
-};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor=function(priority,color,eventTypes)
-{
-this.priority=priority;
-this.color=color;
-this.eventTypes=eventTypes;
-};
-
-
-
-
-WebInspector.TimelineUIUtils.eventDispatchDesciptors=function()
-{
-if(WebInspector.TimelineUIUtils._eventDispatchDesciptors)
-return WebInspector.TimelineUIUtils._eventDispatchDesciptors;
-var lightOrange="hsl(40,100%,80%)";
-var orange="hsl(40,100%,50%)";
-var green="hsl(90,100%,40%)";
-var purple="hsl(256,100%,75%)";
-WebInspector.TimelineUIUtils._eventDispatchDesciptors=[
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(1,lightOrange,["mousemove","mouseenter","mouseleave","mouseout","mouseover"]),
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(1,lightOrange,["pointerover","pointerout","pointerenter","pointerleave","pointermove"]),
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(2,green,["wheel"]),
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,orange,["click","mousedown","mouseup"]),
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,orange,["touchstart","touchend","touchmove","touchcancel"]),
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,orange,["pointerdown","pointerup","pointercancel","gotpointercapture","lostpointercapture"]),
-new WebInspector.TimelineUIUtils.EventDispatchTypeDescriptor(3,purple,["keydown","keyup","keypress"])];
-
-return WebInspector.TimelineUIUtils._eventDispatchDesciptors;
-};
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineCategory=function(name,title,visible,childColor,color)
-{
-this.name=name;
-this.title=title;
-this.visible=visible;
-this.childColor=childColor;
-this.color=color;
-this.hidden=false;
-};
-
-
-WebInspector.TimelineCategory.Events={
-VisibilityChanged:Symbol("VisibilityChanged")};
-
-
-WebInspector.TimelineCategory.prototype={
-
-
-
-get hidden()
-{
-return this._hidden;
-},
-
-set hidden(hidden)
-{
-this._hidden=hidden;
-this.dispatchEventToListeners(WebInspector.TimelineCategory.Events.VisibilityChanged,this);
-},
-
-__proto__:WebInspector.Object.prototype};
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineMarkerStyle;
-
-
-
-
-
-WebInspector.TimelineUIUtils.markerStyleForEvent=function(event)
-{
-var red="rgb(255, 0, 0)";
-var blue="rgb(0, 0, 255)";
-var orange="rgb(255, 178, 23)";
-var green="rgb(0, 130, 0)";
-var tallMarkerDashStyle=[10,5];
-
-var title=WebInspector.TimelineUIUtils.eventTitle(event);
-
-if(event.hasCategory(WebInspector.TimelineModel.Category.Console)||event.hasCategory(WebInspector.TimelineModel.Category.UserTiming)){
-return{
-title:title,
-dashStyle:tallMarkerDashStyle,
-lineWidth:0.5,
-color:orange,
-tall:false,
-lowPriority:false};
-
-}
-var recordTypes=WebInspector.TimelineModel.RecordType;
-var tall=false;
-var color=green;
-switch(event.name){
-case recordTypes.MarkDOMContent:
-color=blue;
-tall=true;
-break;
-case recordTypes.MarkLoad:
-color=red;
-tall=true;
-break;
-case recordTypes.MarkFirstPaint:
-color=green;
-tall=true;
-break;
-case recordTypes.TimeStamp:
-color=orange;
-break;}
-
-return{
-title:title,
-dashStyle:tallMarkerDashStyle,
-lineWidth:0.5,
-color:color,
-tall:tall,
-lowPriority:false};
-
-};
-
-
-
-
-WebInspector.TimelineUIUtils.markerStyleForFrame=function()
-{
-return{
-title:WebInspector.UIString("Frame"),
-color:"rgba(100, 100, 100, 0.4)",
-lineWidth:3,
-dashStyle:[3],
-tall:true,
-lowPriority:true};
-
-};
-
-
-
-
-
-WebInspector.TimelineUIUtils.colorForURL=function(url)
-{
-if(!WebInspector.TimelineUIUtils.colorForURL._colorGenerator){
-WebInspector.TimelineUIUtils.colorForURL._colorGenerator=new WebInspector.FlameChart.ColorGenerator(
-{min:30,max:330},
-{min:50,max:80,count:3},
-85);
-}
-return WebInspector.TimelineUIUtils.colorForURL._colorGenerator.colorForID(url);
-};
-
-
-
-
-
-WebInspector.TimelinePopupContentHelper=function(title)
-{
-this._contentTable=createElement("table");
-var titleCell=this._createCell(WebInspector.UIString("%s - Details",title),"timeline-details-title");
-titleCell.colSpan=2;
-var titleRow=createElement("tr");
-titleRow.appendChild(titleCell);
-this._contentTable.appendChild(titleRow);
-};
-
-WebInspector.TimelinePopupContentHelper.prototype={
-
-
-
-contentTable:function()
-{
-return this._contentTable;
-},
-
-
-
-
-
-_createCell:function(content,styleName)
-{
-var text=createElement("label");
-text.createTextChild(String(content));
-var cell=createElement("td");
-cell.className="timeline-details";
-if(styleName)
-cell.className+=" "+styleName;
-cell.textContent=content;
-return cell;
-},
-
-
-
-
-
-appendTextRow:function(title,content)
-{
-var row=createElement("tr");
-row.appendChild(this._createCell(title,"timeline-details-row-title"));
-row.appendChild(this._createCell(content,"timeline-details-row-data"));
-this._contentTable.appendChild(row);
-},
-
-
-
-
-
-appendElementRow:function(title,content)
-{
-var row=createElement("tr");
-var titleCell=this._createCell(title,"timeline-details-row-title");
-row.appendChild(titleCell);
-var cell=createElement("td");
-cell.className="details";
-if(content instanceof Node)
-cell.appendChild(content);else
-
-cell.createTextChild(content||"");
-row.appendChild(cell);
-this._contentTable.appendChild(row);
-}};
-
-
-
-
-
-
-
-WebInspector.TimelineDetailsContentHelper=function(target,linkifier)
-{
-this.fragment=createDocumentFragment();
-
-this._linkifier=linkifier;
-this._target=target;
-
-this.element=createElementWithClass("div","timeline-details-view-block");
-this._tableElement=this.element.createChild("div","vbox timeline-details-chip-body");
-this.fragment.appendChild(this.element);
-};
-
-WebInspector.TimelineDetailsContentHelper.prototype={
-
-
-
-
-addSection:function(title,category)
-{
-if(!this._tableElement.hasChildNodes()){
-this.element.removeChildren();
-}else{
-this.element=createElementWithClass("div","timeline-details-view-block");
-this.fragment.appendChild(this.element);
-}
-
-if(title){
-var titleElement=this.element.createChild("div","timeline-details-chip-title");
-if(category)
-titleElement.createChild("div").style.backgroundColor=category.color;
-titleElement.createTextChild(title);
-}
-
-this._tableElement=this.element.createChild("div","vbox timeline-details-chip-body");
-this.fragment.appendChild(this.element);
-},
-
-
-
-
-linkifier:function()
-{
-return this._linkifier;
-},
-
-
-
-
-
-appendTextRow:function(title,value)
-{
-var rowElement=this._tableElement.createChild("div","timeline-details-view-row");
-rowElement.createChild("div","timeline-details-view-row-title").textContent=title;
-rowElement.createChild("div","timeline-details-view-row-value").textContent=value;
-},
-
-
-
-
-
-
-
-appendElementRow:function(title,content,isWarning,isStacked)
-{
-var rowElement=this._tableElement.createChild("div","timeline-details-view-row");
-if(isWarning)
-rowElement.classList.add("timeline-details-warning");
-if(isStacked)
-rowElement.classList.add("timeline-details-stack-values");
-var titleElement=rowElement.createChild("div","timeline-details-view-row-title");
-titleElement.textContent=title;
-var valueElement=rowElement.createChild("div","timeline-details-view-row-value");
-if(content instanceof Node)
-valueElement.appendChild(content);else
-
-valueElement.createTextChild(content||"");
-},
-
-
-
-
-
-
-
-appendLocationRow:function(title,url,startLine,startColumn)
-{
-if(!this._linkifier||!this._target)
-return;
-var link=this._linkifier.maybeLinkifyScriptLocation(this._target,null,url,startLine,startColumn);
-if(!link)
-return;
-this.appendElementRow(title,link);
-},
-
-
-
-
-
-
-
-appendLocationRange:function(title,url,startLine,endLine)
-{
-if(!this._linkifier||!this._target)
-return;
-var locationContent=createElement("span");
-var link=this._linkifier.maybeLinkifyScriptLocation(this._target,null,url,startLine);
-if(!link)
-return;
-locationContent.appendChild(link);
-locationContent.createTextChild(String.sprintf(" [%s\u2026%s]",startLine+1,endLine+1||""));
-this.appendElementRow(title,locationContent);
-},
-
-
-
-
-
-appendStackTrace:function(title,stackTrace)
-{
-if(!this._linkifier||!this._target)
-return;
-
-var rowElement=this._tableElement.createChild("div","timeline-details-view-row");
-rowElement.createChild("div","timeline-details-view-row-title").textContent=title;
-this.createChildStackTraceElement(rowElement,stackTrace);
-},
-
-
-
-
-
-createChildStackTraceElement:function(parentElement,stackTrace)
-{
-if(!this._linkifier||!this._target)
-return;
-parentElement.classList.add("timeline-details-stack-values");
-var stackTraceElement=parentElement.createChild("div","timeline-details-view-row-value timeline-details-view-row-stack-trace");
-var callFrameElem=WebInspector.DOMPresentationUtils.buildStackTracePreviewContents(this._target,this._linkifier,stackTrace);
-stackTraceElement.appendChild(callFrameElem);
-},
-
-
-
-
-
-appendWarningRow:function(event,warningType)
-{
-var warning=WebInspector.TimelineUIUtils.eventWarning(event,warningType);
-if(warning)
-this.appendElementRow(WebInspector.UIString("Warning"),warning,true);
-}};
-
-
-
-
-
-
-
-WebInspector.TimelineUIUtils.eventWarning=function(event,warningType)
-{
-var warning=warningType||event.warning;
-if(!warning)
-return null;
-var warnings=WebInspector.TimelineModel.WarningType;
-var span=createElement("span");
-var eventData=event.args["data"];
-
-switch(warning){
-case warnings.ForcedStyle:
-case warnings.ForcedLayout:
-span.appendChild(WebInspector.linkifyDocumentationURLAsNode("../../fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts",
-WebInspector.UIString("Forced reflow")));
-span.createTextChild(WebInspector.UIString(" is a likely performance bottleneck."));
-break;
-case warnings.IdleDeadlineExceeded:
-span.textContent=WebInspector.UIString("Idle callback execution extended beyond deadline by "+
-Number.millisToString(event.duration-eventData["allottedMilliseconds"],true));
-break;
-case warnings.V8Deopt:
-span.appendChild(WebInspector.linkifyURLAsNode("https://github.com/GoogleChrome/devtools-docs/issues/53",
-WebInspector.UIString("Not optimized"),undefined,true));
-span.createTextChild(WebInspector.UIString(": %s",eventData["deoptReason"]));
-break;
-default:
-console.assert(false,"Unhandled TimelineModel.WarningType");}
-
-return span;
-};
-
-},{}],120:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TracingLayerPayload;
-
-
-
-
-
-
-
-
-WebInspector.TracingLayerTile;
-
-
-
-
-
-WebInspector.LayerTreeModel=function(target)
-{
-WebInspector.SDKModel.call(this,WebInspector.LayerTreeModel,target);
-target.registerLayerTreeDispatcher(new WebInspector.LayerTreeDispatcher(this));
-WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Events.MainFrameNavigated,this._onMainFrameNavigated,this);
-
-this._layerTree=null;
-};
-
-
-WebInspector.LayerTreeModel.Events={
-LayerTreeChanged:Symbol("LayerTreeChanged"),
-LayerPainted:Symbol("LayerPainted")};
-
-
-WebInspector.LayerTreeModel.ScrollRectType={
-NonFastScrollable:{name:"NonFastScrollable",description:"Non fast scrollable"},
-TouchEventHandler:{name:"TouchEventHandler",description:"Touch event handler"},
-WheelEventHandler:{name:"WheelEventHandler",description:"Wheel event handler"},
-RepaintsOnScroll:{name:"RepaintsOnScroll",description:"Repaints on scroll"}};
-
-
-WebInspector.LayerTreeModel.prototype={
-disable:function()
-{
-if(!this._enabled)
-return;
-this._enabled=false;
-this._layerTree=null;
-this.target().layerTreeAgent().disable();
-},
-
-enable:function()
-{
-if(this._enabled)
-return;
-this._enabled=true;
-this._forceEnable();
-},
-
-_forceEnable:function()
-{
-this._layerTree=new WebInspector.AgentLayerTree(this.target());
-this._lastPaintRectByLayerId={};
-this.target().layerTreeAgent().enable();
-},
-
-
-
-
-setLayerTree:function(layerTree)
-{
-this.disable();
-this._layerTree=layerTree;
-this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
-},
-
-
-
-
-layerTree:function()
-{
-return this._layerTree;
-},
-
-
-
-
-_layerTreeChanged:function(layers)
-{
-if(!this._enabled)
-return;
-var layerTree=this._layerTree;
-layerTree.setLayers(layers,onLayersSet.bind(this));
-
-
-
-
-function onLayersSet()
-{
-for(var layerId in this._lastPaintRectByLayerId){
-var lastPaintRect=this._lastPaintRectByLayerId[layerId];
-var layer=layerTree.layerById(layerId);
-if(layer)
-layer._lastPaintRect=lastPaintRect;
-}
-this._lastPaintRectByLayerId={};
-
-this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
-}
-},
-
-
-
-
-
-_layerPainted:function(layerId,clipRect)
-{
-if(!this._enabled)
-return;
-var layerTree=this._layerTree;
-var layer=layerTree.layerById(layerId);
-if(!layer){
-this._lastPaintRectByLayerId[layerId]=clipRect;
-return;
-}
-layer._didPaint(clipRect);
-this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerPainted,layer);
-},
-
-_onMainFrameNavigated:function()
-{
-if(this._enabled)
-this._forceEnable();
-},
-
-__proto__:WebInspector.SDKModel.prototype};
-
-
-
-
-
-
-WebInspector.LayerTreeBase=function(target)
-{
-this._target=target;
-this._domModel=target?WebInspector.DOMModel.fromTarget(target):null;
-this._layersById={};
-
-this._backendNodeIdToNode=new Map();
-this._reset();
-};
-
-WebInspector.LayerTreeBase.prototype={
-_reset:function()
-{
-this._root=null;
-this._contentRoot=null;
-this._layers=null;
-},
-
-
-
-
-target:function()
-{
-return this._target;
-},
-
-
-
-
-root:function()
-{
-return this._root;
-},
-
-
-
-
-contentRoot:function()
-{
-return this._contentRoot;
-},
-
-
-
-
-layers:function()
-{
-return this._layers;
-},
-
-
-
-
-
-
-forEachLayer:function(callback,root)
-{
-if(!root){
-root=this.root();
-if(!root)
-return false;
-}
-return callback(root)||root.children().some(this.forEachLayer.bind(this,callback));
-},
-
-
-
-
-
-layerById:function(id)
-{
-return this._layersById[id]||null;
-},
-
-
-
-
-
-_resolveBackendNodeIds:function(requestedNodeIds,callback)
-{
-if(!requestedNodeIds.size||!this._domModel){
-callback();
-return;
-}
-if(this._domModel)
-this._domModel.pushNodesByBackendIdsToFrontend(requestedNodeIds,populateBackendNodeMap.bind(this));
-
-
-
-
-
-function populateBackendNodeMap(nodesMap)
-{
-if(nodesMap){
-for(var nodeId of nodesMap.keysArray())
-this._backendNodeIdToNode.set(nodeId,nodesMap.get(nodeId)||null);
-}
-callback();
-}
-},
-
-
-
-
-setViewportSize:function(viewportSize)
-{
-this._viewportSize=viewportSize;
-},
-
-
-
-
-viewportSize:function()
-{
-return this._viewportSize;
-},
-
-
-
-
-
-_nodeForId:function(id)
-{
-return this._domModel?this._domModel.nodeForId(id):null;
-}};
-
-
-
-
-
-
-
-WebInspector.TracingLayerTree=function(target)
-{
-WebInspector.LayerTreeBase.call(this,target);
-
-this._tileById=new Map();
-};
-
-WebInspector.TracingLayerTree.prototype={
-
-
-
-
-
-setLayers:function(root,layers,callback)
-{
-var idsToResolve=new Set();
-if(root){
-
-
-this._extractNodeIdsToResolve(idsToResolve,{},root);
-}else{
-for(var i=0;i<layers.length;++i)
-this._extractNodeIdsToResolve(idsToResolve,{},layers[i]);
-}
-this._resolveBackendNodeIds(idsToResolve,onBackendNodeIdsResolved.bind(this));
-
-
-
-
-function onBackendNodeIdsResolved()
-{
-var oldLayersById=this._layersById;
-this._layersById={};
-this._contentRoot=null;
-if(root){
-this._root=this._innerSetLayers(oldLayersById,root);
-}else{
-this._layers=layers.map(this._innerSetLayers.bind(this,oldLayersById));
-this._root=this._contentRoot;
-for(var i=0;i<this._layers.length;++i){
-if(this._layers[i].id()!==this._contentRoot.id()){
-this._contentRoot.addChild(this._layers[i]);
-}
-}
-}
-callback();
-}
-},
-
-
-
-
-setTiles:function(tiles)
-{
-this._tileById=new Map();
-for(var tile of tiles)
-this._tileById.set(tile.id,tile);
-},
-
-
-
-
-
-tileById:function(id)
-{
-return this._tileById.get(id)||null;
-},
-
-
-
-
-
-
-_innerSetLayers:function(oldLayersById,payload)
-{
-var layer=oldLayersById[payload.layer_id];
-if(layer)
-layer._reset(payload);else
-
-layer=new WebInspector.TracingLayer(payload);
-this._layersById[payload.layer_id]=layer;
-if(payload.owner_node)
-layer._setNode(this._backendNodeIdToNode.get(payload.owner_node)||null);
-if(!this._contentRoot&&layer.drawsContent())
-this._contentRoot=layer;
-for(var i=0;payload.children&&i<payload.children.length;++i)
-layer.addChild(this._innerSetLayers(oldLayersById,payload.children[i]));
-return layer;
-},
-
-
-
-
-
-
-_extractNodeIdsToResolve:function(nodeIdsToResolve,seenNodeIds,payload)
-{
-var backendNodeId=payload.owner_node;
-if(backendNodeId&&!this._backendNodeIdToNode.has(backendNodeId))
-nodeIdsToResolve.add(backendNodeId);
-for(var i=0;payload.children&&i<payload.children.length;++i)
-this._extractNodeIdsToResolve(nodeIdsToResolve,seenNodeIds,payload.children[i]);
-},
-
-__proto__:WebInspector.LayerTreeBase.prototype};
-
-
-
-
-
-
-
-WebInspector.AgentLayerTree=function(target)
-{
-WebInspector.LayerTreeBase.call(this,target);
-};
-
-WebInspector.AgentLayerTree.prototype={
-
-
-
-
-setLayers:function(payload,callback)
-{
-if(!payload){
-onBackendNodeIdsResolved.call(this);
-return;
-}
-
-var idsToResolve=new Set();
-for(var i=0;i<payload.length;++i){
-var backendNodeId=payload[i].backendNodeId;
-if(!backendNodeId||this._backendNodeIdToNode.has(backendNodeId))
-continue;
-idsToResolve.add(backendNodeId);
-}
-this._resolveBackendNodeIds(idsToResolve,onBackendNodeIdsResolved.bind(this));
-
-
-
-
-function onBackendNodeIdsResolved()
-{
-this._innerSetLayers(payload);
-callback();
-}
-},
-
-
-
-
-_innerSetLayers:function(layers)
-{
-this._reset();
-
-if(!layers)
-return;
-var oldLayersById=this._layersById;
-this._layersById={};
-for(var i=0;i<layers.length;++i){
-var layerId=layers[i].layerId;
-var layer=oldLayersById[layerId];
-if(layer)
-layer._reset(layers[i]);else
-
-layer=new WebInspector.AgentLayer(this._target,layers[i]);
-this._layersById[layerId]=layer;
-var backendNodeId=layers[i].backendNodeId;
-if(backendNodeId)
-layer._setNode(this._backendNodeIdToNode.get(backendNodeId));
-if(!this._contentRoot&&layer.drawsContent())
-this._contentRoot=layer;
-var parentId=layer.parentId();
-if(parentId){
-var parent=this._layersById[parentId];
-if(!parent)
-console.assert(parent,"missing parent "+parentId+" for layer "+layerId);
-parent.addChild(layer);
-}else{
-if(this._root)
-console.assert(false,"Multiple root layers");
-this._root=layer;
-}
-}
-if(this._root)
-this._root._calculateQuad(new WebKitCSSMatrix());
-},
-
-__proto__:WebInspector.LayerTreeBase.prototype};
-
-
-
-
-
-WebInspector.Layer=function()
-{
-};
-
-WebInspector.Layer.prototype={
-
-
-
-id:function(){},
-
-
-
-
-parentId:function(){},
-
-
-
-
-parent:function(){},
-
-
-
-
-isRoot:function(){},
-
-
-
-
-children:function(){},
-
-
-
-
-addChild:function(child){},
-
-
-
-
-node:function(){},
-
-
-
-
-nodeForSelfOrAncestor:function(){},
-
-
-
-
-offsetX:function(){},
-
-
-
-
-offsetY:function(){},
-
-
-
-
-width:function(){},
-
-
-
-
-height:function(){},
-
-
-
-
-transform:function(){},
-
-
-
-
-quad:function(){},
-
-
-
-
-anchorPoint:function(){},
-
-
-
-
-invisible:function(){},
-
-
-
-
-paintCount:function(){},
-
-
-
-
-lastPaintRect:function(){},
-
-
-
-
-scrollRects:function(){},
-
-
-
-
-gpuMemoryUsage:function(){},
-
-
-
-
-requestCompositingReasons:function(callback){},
-
-
-
-
-drawsContent:function(){}};
-
-
-
-
-
-
-
-
-WebInspector.AgentLayer=function(target,layerPayload)
-{
-this._target=target;
-this._reset(layerPayload);
-};
-
-WebInspector.AgentLayer.prototype={
-
-
-
-
-id:function()
-{
-return this._layerPayload.layerId;
-},
-
-
-
-
-
-parentId:function()
-{
-return this._layerPayload.parentLayerId;
-},
-
-
-
-
-
-parent:function()
-{
-return this._parent;
-},
-
-
-
-
-
-isRoot:function()
-{
-return!this.parentId();
-},
-
-
-
-
-
-children:function()
-{
-return this._children;
-},
-
-
-
-
-
-addChild:function(child)
-{
-if(child._parent)
-console.assert(false,"Child already has a parent");
-this._children.push(child);
-child._parent=this;
-},
-
-
-
-
-_setNode:function(node)
-{
-this._node=node;
-},
-
-
-
-
-
-node:function()
-{
-return this._node;
-},
-
-
-
-
-
-nodeForSelfOrAncestor:function()
-{
-for(var layer=this;layer;layer=layer._parent){
-if(layer._node)
-return layer._node;
-}
-return null;
-},
-
-
-
-
-
-offsetX:function()
-{
-return this._layerPayload.offsetX;
-},
-
-
-
-
-
-offsetY:function()
-{
-return this._layerPayload.offsetY;
-},
-
-
-
-
-
-width:function()
-{
-return this._layerPayload.width;
-},
-
-
-
-
-
-height:function()
-{
-return this._layerPayload.height;
-},
-
-
-
-
-
-transform:function()
-{
-return this._layerPayload.transform;
-},
-
-
-
-
-
-quad:function()
-{
-return this._quad;
-},
-
-
-
-
-
-anchorPoint:function()
-{
-return[
-this._layerPayload.anchorX||0,
-this._layerPayload.anchorY||0,
-this._layerPayload.anchorZ||0];
-
-},
-
-
-
-
-
-invisible:function()
-{
-return this._layerPayload.invisible;
-},
-
-
-
-
-
-paintCount:function()
-{
-return this._paintCount||this._layerPayload.paintCount;
-},
-
-
-
-
-
-lastPaintRect:function()
-{
-return this._lastPaintRect;
-},
-
-
-
-
-
-scrollRects:function()
-{
-return this._scrollRects;
-},
-
-
-
-
-
-requestCompositingReasons:function(callback)
-{
-if(!this._target){
-callback([]);
-return;
-}
-
-var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.reasonsForCompositingLayer(): ",undefined,[]);
-this._target.layerTreeAgent().compositingReasons(this.id(),wrappedCallback);
-},
-
-
-
-
-
-drawsContent:function()
-{
-return this._layerPayload.drawsContent;
-},
-
-
-
-
-
-gpuMemoryUsage:function()
-{
-
-
-
-var bytesPerPixel=4;
-return this.drawsContent()?this.width()*this.height()*bytesPerPixel:0;
-},
-
-
-
-
-requestSnapshot:function(callback)
-{
-if(!this._target){
-callback();
-return;
-}
-
-var wrappedCallback=InspectorBackend.wrapClientCallback(callback,"LayerTreeAgent.makeSnapshot(): ",WebInspector.PaintProfilerSnapshot.bind(null,this._target));
-this._target.layerTreeAgent().makeSnapshot(this.id(),wrappedCallback);
-},
-
-
-
-
-_didPaint:function(rect)
-{
-this._lastPaintRect=rect;
-this._paintCount=this.paintCount()+1;
-this._image=null;
-},
-
-
-
-
-_reset:function(layerPayload)
-{
-
-this._node=null;
-this._children=[];
-this._parent=null;
-this._paintCount=0;
-this._layerPayload=layerPayload;
-this._image=null;
-this._scrollRects=this._layerPayload.scrollRects||[];
-},
-
-
-
-
-
-_matrixFromArray:function(a)
-{
-function toFixed9(x){return x.toFixed(9);}
-return new WebKitCSSMatrix("matrix3d("+a.map(toFixed9).join(",")+")");
-},
-
-
-
-
-
-_calculateTransformToViewport:function(parentTransform)
-{
-var offsetMatrix=new WebKitCSSMatrix().translate(this._layerPayload.offsetX,this._layerPayload.offsetY);
-var matrix=offsetMatrix;
-
-if(this._layerPayload.transform){
-var transformMatrix=this._matrixFromArray(this._layerPayload.transform);
-var anchorVector=new WebInspector.Geometry.Vector(this._layerPayload.width*this.anchorPoint()[0],this._layerPayload.height*this.anchorPoint()[1],this.anchorPoint()[2]);
-var anchorPoint=WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector,matrix);
-var anchorMatrix=new WebKitCSSMatrix().translate(-anchorPoint.x,-anchorPoint.y,-anchorPoint.z);
-matrix=anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));
-}
-
-matrix=parentTransform.multiply(matrix);
-return matrix;
-},
-
-
-
-
-
-
-_createVertexArrayForRect:function(width,height)
-{
-return[0,0,0,width,0,0,width,height,0,0,height,0];
-},
-
-
-
-
-_calculateQuad:function(parentTransform)
-{
-var matrix=this._calculateTransformToViewport(parentTransform);
-this._quad=[];
-var vertices=this._createVertexArrayForRect(this._layerPayload.width,this._layerPayload.height);
-for(var i=0;i<4;++i){
-var point=WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(vertices[i*3],vertices[i*3+1],vertices[i*3+2]),matrix);
-this._quad.push(point.x,point.y);
-}
-
-function calculateQuadForLayer(layer)
-{
-layer._calculateQuad(matrix);
-}
-
-this._children.forEach(calculateQuadForLayer);
-}};
-
-
-
-
-
-
-
-WebInspector.TracingLayer=function(payload)
-{
-this._reset(payload);
-};
-
-WebInspector.TracingLayer.prototype={
-
-
-
-_reset:function(payload)
-{
-
-this._node=null;
-this._layerId=String(payload.layer_id);
-this._offsetX=payload.position[0];
-this._offsetY=payload.position[1];
-this._width=payload.bounds.width;
-this._height=payload.bounds.height;
-this._children=[];
-this._parentLayerId=null;
-this._parent=null;
-this._quad=payload.layer_quad||[];
-this._createScrollRects(payload);
-this._compositingReasons=payload.compositing_reasons||[];
-this._drawsContent=!!payload.draws_content;
-this._gpuMemoryUsage=payload.gpu_memory_usage;
-},
-
-
-
-
-
-id:function()
-{
-return this._layerId;
-},
-
-
-
-
-
-parentId:function()
-{
-return this._parentLayerId;
-},
-
-
-
-
-
-parent:function()
-{
-return this._parent;
-},
-
-
-
-
-
-isRoot:function()
-{
-return!this.parentId();
-},
-
-
-
-
-
-children:function()
-{
-return this._children;
-},
-
-
-
-
-
-addChild:function(child)
-{
-if(child._parent)
-console.assert(false,"Child already has a parent");
-this._children.push(child);
-child._parent=this;
-child._parentLayerId=this._layerId;
-},
-
-
-
-
-
-_setNode:function(node)
-{
-this._node=node;
-},
-
-
-
-
-
-node:function()
-{
-return this._node;
-},
-
-
-
-
-
-nodeForSelfOrAncestor:function()
-{
-for(var layer=this;layer;layer=layer._parent){
-if(layer._node)
-return layer._node;
-}
-return null;
-},
-
-
-
-
-
-offsetX:function()
-{
-return this._offsetX;
-},
-
-
-
-
-
-offsetY:function()
-{
-return this._offsetY;
-},
-
-
-
-
-
-width:function()
-{
-return this._width;
-},
-
-
-
-
-
-height:function()
-{
-return this._height;
-},
-
-
-
-
-
-transform:function()
-{
-return null;
-},
-
-
-
-
-
-quad:function()
-{
-return this._quad;
-},
-
-
-
-
-
-anchorPoint:function()
-{
-return[0.5,0.5,0];
-},
-
-
-
-
-
-invisible:function()
-{
-return false;
-},
-
-
-
-
-
-paintCount:function()
-{
-return 0;
-},
-
-
-
-
-
-lastPaintRect:function()
-{
-return null;
-},
-
-
-
-
-
-scrollRects:function()
-{
-return this._scrollRects;
-},
-
-
-
-
-
-gpuMemoryUsage:function()
-{
-return this._gpuMemoryUsage;
-},
-
-
-
-
-
-
-_scrollRectsFromParams:function(params,type)
-{
-return{rect:{x:params[0],y:params[1],width:params[2],height:params[3]},type:type};
-},
-
-
-
-
-_createScrollRects:function(payload)
-{
-this._scrollRects=[];
-if(payload.non_fast_scrollable_region)
-this._scrollRects.push(this._scrollRectsFromParams(payload.non_fast_scrollable_region,WebInspector.LayerTreeModel.ScrollRectType.NonFastScrollable.name));
-if(payload.touch_event_handler_region)
-this._scrollRects.push(this._scrollRectsFromParams(payload.touch_event_handler_region,WebInspector.LayerTreeModel.ScrollRectType.TouchEventHandler.name));
-if(payload.wheel_event_handler_region)
-this._scrollRects.push(this._scrollRectsFromParams(payload.wheel_event_handler_region,WebInspector.LayerTreeModel.ScrollRectType.WheelEventHandler.name));
-if(payload.scroll_event_handler_region)
-this._scrollRects.push(this._scrollRectsFromParams(payload.scroll_event_handler_region,WebInspector.LayerTreeModel.ScrollRectType.RepaintsOnScroll.name));
-},
-
-
-
-
-
-requestCompositingReasons:function(callback)
-{
-callback(this._compositingReasons);
-},
-
-
-
-
-
-drawsContent:function()
-{
-return this._drawsContent;
-}};
-
-
-
-
-
-
-WebInspector.DeferredLayerTree=function(target)
-{
-this._target=target;
-};
-
-WebInspector.DeferredLayerTree.prototype={
-
-
-
-resolve:function(callback){},
-
-
-
-
-target:function()
-{
-return this._target;
-}};
-
-
-
-
-
-
-
-WebInspector.LayerTreeDispatcher=function(layerTreeModel)
-{
-this._layerTreeModel=layerTreeModel;
-};
-
-WebInspector.LayerTreeDispatcher.prototype={
-
-
-
-
-layerTreeDidChange:function(layers)
-{
-this._layerTreeModel._layerTreeChanged(layers||null);
-},
-
-
-
-
-
-
-layerPainted:function(layerId,clipRect)
-{
-this._layerTreeModel._layerPainted(layerId,clipRect);
-}};
-
-
-
-
-
-
-WebInspector.LayerTreeModel.fromTarget=function(target)
-{
-if(!target.hasDOMCapability())
-return null;
-
-var model=target.model(WebInspector.LayerTreeModel);
-if(!model)
-model=new WebInspector.LayerTreeModel(target);
-return model;
-};
-
-},{}],121:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineFrameModel=function(categoryMapper)
-{
-this._categoryMapper=categoryMapper;
-this.reset();
-};
-
-WebInspector.TimelineFrameModel._mainFrameMarkers=[
-WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation,
-WebInspector.TimelineModel.RecordType.InvalidateLayout,
-WebInspector.TimelineModel.RecordType.BeginMainThreadFrame,
-WebInspector.TimelineModel.RecordType.ScrollLayer];
-
-
-WebInspector.TimelineFrameModel.prototype={
-
-
-
-frames:function()
-{
-return this._frames;
-},
-
-
-
-
-
-
-filteredFrames:function(startTime,endTime)
-{
-
-
-
-
-
-function compareStartTime(value,object)
-{
-return value-object.startTime;
-}
-
-
-
-
-
-function compareEndTime(value,object)
-{
-return value-object.endTime;
-}
-var frames=this._frames;
-var firstFrame=frames.lowerBound(startTime,compareEndTime);
-var lastFrame=frames.lowerBound(endTime,compareStartTime);
-return frames.slice(firstFrame,lastFrame);
-},
-
-
-
-
-
-hasRasterTile:function(rasterTask)
-{
-var data=rasterTask.args["tileData"];
-if(!data)
-return false;
-var frameId=data["sourceFrameNumber"];
-var frame=frameId&&this._frameById[frameId];
-if(!frame||!frame.layerTree)
-return false;
-return true;
-},
-
-
-
-
-
-requestRasterTile:function(rasterTask,callback)
-{
-var target=this._target;
-if(!target){
-callback(null,null);
-return;
-}
-var data=rasterTask.args["tileData"];
-var frameId=data["sourceFrameNumber"];
-var frame=frameId&&this._frameById[frameId];
-if(!frame||!frame.layerTree){
-callback(null,null);
-return;
-}
-
-var tileId=data["tileId"]&&data["tileId"]["id_ref"];
-
-var fragments=[];
-
-var tile=null;
-var x0=Infinity;
-var y0=Infinity;
-
-frame.layerTree.resolve(layerTreeResolved);
-
-
-
-function layerTreeResolved(layerTree)
-{
-tile=tileId&&layerTree.tileById("cc::Tile/"+tileId);
-if(!tile){
-console.error("Tile "+tileId+" missing in frame "+frameId);
-callback(null,null);
-return;
-}
-var fetchPictureFragmentsBarrier=new CallbackBarrier();
-for(var paint of frame.paints){
-if(tile.layer_id===paint.layerId())
-paint.loadPicture(fetchPictureFragmentsBarrier.createCallback(pictureLoaded));
-}
-fetchPictureFragmentsBarrier.callWhenDone(allPicturesLoaded);
-}
-
-
-
-
-
-
-
-
-function segmentsOverlap(a1,a2,b1,b2)
-{
-console.assert(a1<=a2&&b1<=b2,"segments should be specified as ordered pairs");
-return a2>b1&&a1<b2;
-}
-
-
-
-
-
-function rectsOverlap(a,b)
-{
-return segmentsOverlap(a[0],a[0]+a[2],b[0],b[0]+b[2])&&segmentsOverlap(a[1],a[1]+a[3],b[1],b[1]+b[3]);
-}
-
-
-
-
-
-function pictureLoaded(rect,picture)
-{
-if(!rect||!picture)
-return;
-if(!rectsOverlap(rect,tile.content_rect))
-return;
-var x=rect[0];
-var y=rect[1];
-x0=Math.min(x0,x);
-y0=Math.min(y0,y);
-fragments.push({x:x,y:y,picture:picture});
-}
-
-function allPicturesLoaded()
-{
-if(!fragments.length){
-callback(null,null);
-return;
-}
-var rectArray=tile.content_rect;
-
-var rect={x:rectArray[0]-x0,y:rectArray[1]-y0,width:rectArray[2],height:rectArray[3]};
-WebInspector.PaintProfilerSnapshot.loadFromFragments(target,fragments,callback.bind(null,rect));
-}
-},
-
-reset:function()
-{
-this._minimumRecordTime=Infinity;
-this._frames=[];
-this._frameById={};
-this._lastFrame=null;
-this._lastLayerTree=null;
-this._mainFrameCommitted=false;
-this._mainFrameRequested=false;
-this._framePendingCommit=null;
-this._lastBeginFrame=null;
-this._lastNeedsBeginFrame=null;
-this._framePendingActivation=null;
-this._lastTaskBeginTime=null;
-this._target=null;
-this._sessionId=null;
-this._currentTaskTimeByCategory={};
-},
-
-
-
-
-handleBeginFrame:function(startTime)
-{
-if(!this._lastFrame)
-this._startFrame(startTime);
-this._lastBeginFrame=startTime;
-},
-
-
-
-
-handleDrawFrame:function(startTime)
-{
-if(!this._lastFrame){
-this._startFrame(startTime);
-return;
-}
-
-
-
-if(this._mainFrameCommitted||!this._mainFrameRequested){
-if(this._lastNeedsBeginFrame){
-var idleTimeEnd=this._framePendingActivation?this._framePendingActivation.triggerTime:this._lastBeginFrame||this._lastNeedsBeginFrame;
-if(idleTimeEnd>this._lastFrame.startTime){
-this._lastFrame.idle=true;
-this._startFrame(idleTimeEnd);
-if(this._framePendingActivation)
-this._commitPendingFrame();
-this._lastBeginFrame=null;
-}
-this._lastNeedsBeginFrame=null;
-}
-this._startFrame(startTime);
-}
-this._mainFrameCommitted=false;
-},
-
-handleActivateLayerTree:function()
-{
-if(!this._lastFrame)
-return;
-if(this._framePendingActivation&&!this._lastNeedsBeginFrame)
-this._commitPendingFrame();
-},
-
-handleRequestMainThreadFrame:function()
-{
-if(!this._lastFrame)
-return;
-this._mainFrameRequested=true;
-},
-
-handleCompositeLayers:function()
-{
-if(!this._framePendingCommit)
-return;
-this._framePendingActivation=this._framePendingCommit;
-this._framePendingCommit=null;
-this._mainFrameRequested=false;
-this._mainFrameCommitted=true;
-},
-
-
-
-
-handleLayerTreeSnapshot:function(layerTree)
-{
-this._lastLayerTree=layerTree;
-},
-
-
-
-
-
-handleNeedFrameChanged:function(startTime,needsBeginFrame)
-{
-if(needsBeginFrame)
-this._lastNeedsBeginFrame=startTime;
-},
-
-
-
-
-_startFrame:function(startTime)
-{
-if(this._lastFrame)
-this._flushFrame(this._lastFrame,startTime);
-this._lastFrame=new WebInspector.TimelineFrame(startTime,startTime-this._minimumRecordTime);
-},
-
-
-
-
-
-_flushFrame:function(frame,endTime)
-{
-frame._setLayerTree(this._lastLayerTree);
-frame._setEndTime(endTime);
-if(this._frames.length&&(frame.startTime!==this._frames.peekLast().endTime||frame.startTime>frame.endTime))
-console.assert(false,`Inconsistent frame time for frame ${this._frames.length} (${frame.startTime} - ${frame.endTime})`);
-this._frames.push(frame);
-if(typeof frame._mainFrameId==="number")
-this._frameById[frame._mainFrameId]=frame;
-},
-
-_commitPendingFrame:function()
-{
-this._lastFrame._addTimeForCategories(this._framePendingActivation.timeByCategory);
-this._lastFrame.paints=this._framePendingActivation.paints;
-this._lastFrame._mainFrameId=this._framePendingActivation.mainFrameId;
-this._framePendingActivation=null;
-},
-
-
-
-
-
-
-_findRecordRecursively:function(types,record)
-{
-if(types.indexOf(record.type())>=0)
-return record;
-if(!record.children())
-return null;
-for(var i=0;i<record.children().length;++i){
-var result=this._findRecordRecursively(types,record.children()[i]);
-if(result)
-return result;
-}
-return null;
-},
-
-
-
-
-
-
-addTraceEvents:function(target,events,sessionId)
-{
-this._target=target;
-this._sessionId=sessionId;
-if(!events.length)
-return;
-if(events[0].startTime<this._minimumRecordTime)
-this._minimumRecordTime=events[0].startTime;
-for(var i=0;i<events.length;++i)
-this._addTraceEvent(events[i]);
-},
-
-
-
-
-_addTraceEvent:function(event)
-{
-var eventNames=WebInspector.TimelineModel.RecordType;
-
-if(event.name===eventNames.SetLayerTreeId){
-var sessionId=event.args["sessionId"]||event.args["data"]["sessionId"];
-if(this._sessionId===sessionId)
-this._layerTreeId=event.args["layerTreeId"]||event.args["data"]["layerTreeId"];
-}else if(event.name===eventNames.TracingStartedInPage){
-this._mainThread=event.thread;
-}else if(event.phase===WebInspector.TracingModel.Phase.SnapshotObject&&event.name===eventNames.LayerTreeHostImplSnapshot&&parseInt(event.id,0)===this._layerTreeId){
-var snapshot=event;
-this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(snapshot,this._target));
-}else{
-this._processCompositorEvents(event);
-if(event.thread===this._mainThread)
-this._addMainThreadTraceEvent(event);else
-if(this._lastFrame&&event.selfTime&&!WebInspector.TracingModel.isTopLevelEvent(event))
-this._lastFrame._addTimeForCategory(this._categoryMapper(event),event.selfTime);
-}
-},
-
-
-
-
-_processCompositorEvents:function(event)
-{
-var eventNames=WebInspector.TimelineModel.RecordType;
-
-if(event.args["layerTreeId"]!==this._layerTreeId)
-return;
-
-var timestamp=event.startTime;
-if(event.name===eventNames.BeginFrame)
-this.handleBeginFrame(timestamp);else
-if(event.name===eventNames.DrawFrame)
-this.handleDrawFrame(timestamp);else
-if(event.name===eventNames.ActivateLayerTree)
-this.handleActivateLayerTree();else
-if(event.name===eventNames.RequestMainThreadFrame)
-this.handleRequestMainThreadFrame();else
-if(event.name===eventNames.NeedsBeginFrameChanged)
-this.handleNeedFrameChanged(timestamp,event.args["data"]&&event.args["data"]["needsBeginFrame"]);
-},
-
-
-
-
-_addMainThreadTraceEvent:function(event)
-{
-var eventNames=WebInspector.TimelineModel.RecordType;
-var timestamp=event.startTime;
-var selfTime=event.selfTime||0;
-
-if(WebInspector.TracingModel.isTopLevelEvent(event)){
-this._currentTaskTimeByCategory={};
-this._lastTaskBeginTime=event.startTime;
-}
-if(!this._framePendingCommit&&WebInspector.TimelineFrameModel._mainFrameMarkers.indexOf(event.name)>=0)
-this._framePendingCommit=new WebInspector.PendingFrame(this._lastTaskBeginTime||event.startTime,this._currentTaskTimeByCategory);
-if(!this._framePendingCommit){
-this._addTimeForCategory(this._currentTaskTimeByCategory,event);
-return;
-}
-this._addTimeForCategory(this._framePendingCommit.timeByCategory,event);
-
-if(event.name===eventNames.BeginMainThreadFrame&&event.args["data"]&&event.args["data"]["frameId"])
-this._framePendingCommit.mainFrameId=event.args["data"]["frameId"];
-if(event.name===eventNames.Paint&&event.args["data"]["layerId"]&&event.picture&&this._target)
-this._framePendingCommit.paints.push(new WebInspector.LayerPaintEvent(event,this._target));
-if(event.name===eventNames.CompositeLayers&&event.args["layerTreeId"]===this._layerTreeId)
-this.handleCompositeLayers();
-},
-
-
-
-
-
-_addTimeForCategory:function(timeByCategory,event)
-{
-if(!event.selfTime)
-return;
-var categoryName=this._categoryMapper(event);
-timeByCategory[categoryName]=(timeByCategory[categoryName]||0)+event.selfTime;
-}};
-
-
-
-
-
-
-
-
-WebInspector.DeferredTracingLayerTree=function(snapshot,target)
-{
-WebInspector.DeferredLayerTree.call(this,target);
-this._snapshot=snapshot;
-};
-
-WebInspector.DeferredTracingLayerTree.prototype={
-
-
-
-
-resolve:function(callback)
-{
-this._snapshot.requestObject(onGotObject.bind(this));
-
-
-
-
-function onGotObject(result)
-{
-if(!result)
-return;
-var viewport=result["device_viewport_size"];
-var tiles=result["active_tiles"];
-var rootLayer=result["active_tree"]["root_layer"];
-var layers=result["active_tree"]["layers"];
-var layerTree=new WebInspector.TracingLayerTree(this._target);
-layerTree.setViewportSize(viewport);
-layerTree.setTiles(tiles);
-layerTree.setLayers(rootLayer,layers,callback.bind(null,layerTree));
-}
-},
-
-__proto__:WebInspector.DeferredLayerTree.prototype};
-
-
-
-
-
-
-
-
-WebInspector.TimelineFrame=function(startTime,startTimeOffset)
-{
-this.startTime=startTime;
-this.startTimeOffset=startTimeOffset;
-this.endTime=this.startTime;
-this.duration=0;
-this.timeByCategory={};
-this.cpuTime=0;
-this.idle=false;
-
-this.layerTree=null;
-
-this.paints=[];
-
-this._mainFrameId=undefined;
-};
-
-WebInspector.TimelineFrame.prototype={
-
-
-
-hasWarnings:function()
-{
-var longFrameDurationThresholdMs=22;
-return!this.idle&&this.duration>longFrameDurationThresholdMs;
-},
-
-
-
-
-_setEndTime:function(endTime)
-{
-this.endTime=endTime;
-this.duration=this.endTime-this.startTime;
-},
-
-
-
-
-_setLayerTree:function(layerTree)
-{
-this.layerTree=layerTree;
-},
-
-
-
-
-_addTimeForCategories:function(timeByCategory)
-{
-for(var category in timeByCategory)
-this._addTimeForCategory(category,timeByCategory[category]);
-},
-
-
-
-
-
-_addTimeForCategory:function(category,time)
-{
-this.timeByCategory[category]=(this.timeByCategory[category]||0)+time;
-this.cpuTime+=time;
-}};
-
-
-
-
-
-
-
-WebInspector.LayerPaintEvent=function(event,target)
-{
-this._event=event;
-this._target=target;
-};
-
-WebInspector.LayerPaintEvent.prototype={
-
-
-
-layerId:function()
-{
-return this._event.args["data"]["layerId"];
-},
-
-
-
-
-event:function()
-{
-return this._event;
-},
-
-
-
-
-loadPicture:function(callback)
-{
-this._event.picture.requestObject(onGotObject);
-
-
-
-function onGotObject(result)
-{
-if(!result||!result["skp64"]){
-callback(null,null);
-return;
-}
-var rect=result["params"]&&result["params"]["layer_rect"];
-callback(rect,result["skp64"]);
-}
-},
-
-
-
-
-loadSnapshot:function(callback)
-{
-this.loadPicture(onGotPicture.bind(this));
-
-
-
-
-
-function onGotPicture(rect,picture)
-{
-if(!rect||!picture||!this._target){
-callback(null,null);
-return;
-}
-WebInspector.PaintProfilerSnapshot.load(this._target,picture,callback.bind(null,rect));
-}
-}};
-
-
-
-
-
-
-
-WebInspector.PendingFrame=function(triggerTime,timeByCategory)
-{
-
-this.timeByCategory=timeByCategory;
-
-this.paints=[];
-
-this.mainFrameId=undefined;
-this.triggerTime=triggerTime;
-};
-
-},{}],122:[function(require,module,exports){
-
-
-
-
-
-
-
-WebInspector.TimelineIRModel=function()
-{
-this.reset();
-};
-
-
-
-
-WebInspector.TimelineIRModel.Phases={
-Idle:"Idle",
-Response:"Response",
-Scroll:"Scroll",
-Fling:"Fling",
-Drag:"Drag",
-Animation:"Animation",
-Uncategorized:"Uncategorized"};
-
-
-
-
-
-WebInspector.TimelineIRModel.InputEvents={
-Char:"Char",
-Click:"GestureClick",
-ContextMenu:"ContextMenu",
-FlingCancel:"GestureFlingCancel",
-FlingStart:"GestureFlingStart",
-ImplSideFling:WebInspector.TimelineModel.RecordType.ImplSideFling,
-KeyDown:"KeyDown",
-KeyDownRaw:"RawKeyDown",
-KeyUp:"KeyUp",
-LatencyScrollUpdate:"ScrollUpdate",
-MouseDown:"MouseDown",
-MouseMove:"MouseMove",
-MouseUp:"MouseUp",
-MouseWheel:"MouseWheel",
-PinchBegin:"GesturePinchBegin",
-PinchEnd:"GesturePinchEnd",
-PinchUpdate:"GesturePinchUpdate",
-ScrollBegin:"GestureScrollBegin",
-ScrollEnd:"GestureScrollEnd",
-ScrollUpdate:"GestureScrollUpdate",
-ScrollUpdateRenderer:"ScrollUpdate",
-ShowPress:"GestureShowPress",
-Tap:"GestureTap",
-TapCancel:"GestureTapCancel",
-TapDown:"GestureTapDown",
-TouchCancel:"TouchCancel",
-TouchEnd:"TouchEnd",
-TouchMove:"TouchMove",
-TouchStart:"TouchStart"};
-
-
-WebInspector.TimelineIRModel._mergeThresholdsMs={
-animation:1,
-mouse:40};
-
-
-WebInspector.TimelineIRModel._eventIRPhase=Symbol("eventIRPhase");
-
-
-
-
-
-WebInspector.TimelineIRModel.phaseForEvent=function(event)
-{
-return event[WebInspector.TimelineIRModel._eventIRPhase];
-};
-
-WebInspector.TimelineIRModel.prototype={
-
-
-
-
-populate:function(inputLatencies,animations)
-{
-var eventTypes=WebInspector.TimelineIRModel.InputEvents;
-var phases=WebInspector.TimelineIRModel.Phases;
-
-this.reset();
-if(!inputLatencies)
-return;
-this._processInputLatencies(inputLatencies);
-if(animations)
-this._processAnimations(animations);
-var range=new WebInspector.SegmentedRange();
-range.appendRange(this._drags);
-range.appendRange(this._cssAnimations);
-range.appendRange(this._scrolls);
-range.appendRange(this._responses);
-this._segments=range.segments();
-},
-
-
-
-
-_processInputLatencies:function(events)
-{
-var eventTypes=WebInspector.TimelineIRModel.InputEvents;
-var phases=WebInspector.TimelineIRModel.Phases;
-var thresholdsMs=WebInspector.TimelineIRModel._mergeThresholdsMs;
-
-var scrollStart;
-var flingStart;
-var touchStart;
-var firstTouchMove;
-var mouseWheel;
-var mouseDown;
-var mouseMove;
-
-for(var i=0;i<events.length;++i){
-var event=events[i];
-if(i>0&&events[i].startTime<events[i-1].startTime)
-console.assert(false,"Unordered input events");
-var type=this._inputEventType(event.name);
-switch(type){
-
-case eventTypes.ScrollBegin:
-this._scrolls.append(this._segmentForEvent(event,phases.Scroll));
-scrollStart=event;
-break;
-
-case eventTypes.ScrollEnd:
-if(scrollStart)
-this._scrolls.append(this._segmentForEventRange(scrollStart,event,phases.Scroll));else
-
-this._scrolls.append(this._segmentForEvent(event,phases.Scroll));
-scrollStart=null;
-break;
-
-case eventTypes.ScrollUpdate:
-touchStart=null;
-this._scrolls.append(this._segmentForEvent(event,phases.Scroll));
-break;
-
-case eventTypes.FlingStart:
-if(flingStart){
-WebInspector.console.error(WebInspector.UIString("Two flings at the same time? %s vs %s",flingStart.startTime,event.startTime));
-break;
-}
-flingStart=event;
-break;
-
-case eventTypes.FlingCancel:
-
-if(!flingStart)
-break;
-this._scrolls.append(this._segmentForEventRange(flingStart,event,phases.Fling));
-flingStart=null;
-break;
-
-case eventTypes.ImplSideFling:
-this._scrolls.append(this._segmentForEvent(event,phases.Fling));
-break;
-
-case eventTypes.ShowPress:
-case eventTypes.Tap:
-case eventTypes.KeyDown:
-case eventTypes.KeyDownRaw:
-case eventTypes.KeyUp:
-case eventTypes.Char:
-case eventTypes.Click:
-case eventTypes.ContextMenu:
-this._responses.append(this._segmentForEvent(event,phases.Response));
-break;
-
-case eventTypes.TouchStart:
-
-
-if(touchStart){
-WebInspector.console.error(WebInspector.UIString("Two touches at the same time? %s vs %s",touchStart.startTime,event.startTime));
-break;
-}
-touchStart=event;
-event.steps[0][WebInspector.TimelineIRModel._eventIRPhase]=phases.Response;
-firstTouchMove=null;
-break;
-
-case eventTypes.TouchCancel:
-touchStart=null;
-break;
-
-case eventTypes.TouchMove:
-if(firstTouchMove){
-this._drags.append(this._segmentForEvent(event,phases.Drag));
-}else if(touchStart){
-firstTouchMove=event;
-this._responses.append(this._segmentForEventRange(touchStart,event,phases.Response));
-}
-break;
-
-case eventTypes.TouchEnd:
-touchStart=null;
-break;
-
-case eventTypes.MouseDown:
-mouseDown=event;
-mouseMove=null;
-break;
-
-case eventTypes.MouseMove:
-if(mouseDown&&!mouseMove&&mouseDown.startTime+thresholdsMs.mouse>event.startTime){
-this._responses.append(this._segmentForEvent(mouseDown,phases.Response));
-this._responses.append(this._segmentForEvent(event,phases.Response));
-}else if(mouseDown){
-this._drags.append(this._segmentForEvent(event,phases.Drag));
-}
-mouseMove=event;
-break;
-
-case eventTypes.MouseUp:
-this._responses.append(this._segmentForEvent(event,phases.Response));
-mouseDown=null;
-break;
-
-case eventTypes.MouseWheel:
-
-if(mouseWheel&&canMerge(thresholdsMs.mouse,mouseWheel,event))
-this._scrolls.append(this._segmentForEventRange(mouseWheel,event,phases.Scroll));else
-
-this._scrolls.append(this._segmentForEvent(event,phases.Scroll));
-mouseWheel=event;
-break;}
-
-}
-
-
-
-
-
-
-
-function canMerge(threshold,first,second)
-{
-return first.endTime<second.startTime&&second.startTime<first.endTime+threshold;
-}
-},
-
-
-
-
-_processAnimations:function(events)
-{
-for(var i=0;i<events.length;++i)
-this._cssAnimations.append(this._segmentForEvent(events[i],WebInspector.TimelineIRModel.Phases.Animation));
-},
-
-
-
-
-
-
-_segmentForEvent:function(event,phase)
-{
-this._setPhaseForEvent(event,phase);
-return new WebInspector.Segment(event.startTime,event.endTime,phase);
-},
-
-
-
-
-
-
-
-_segmentForEventRange:function(startEvent,endEvent,phase)
-{
-this._setPhaseForEvent(startEvent,phase);
-this._setPhaseForEvent(endEvent,phase);
-return new WebInspector.Segment(startEvent.startTime,endEvent.endTime,phase);
-},
-
-
-
-
-
-_setPhaseForEvent:function(asyncEvent,phase)
-{
-asyncEvent.steps[0][WebInspector.TimelineIRModel._eventIRPhase]=phase;
-},
-
-
-
-
-interactionRecords:function()
-{
-return this._segments;
-},
-
-reset:function()
-{
-var thresholdsMs=WebInspector.TimelineIRModel._mergeThresholdsMs;
-
-this._segments=[];
-this._drags=new WebInspector.SegmentedRange(merge.bind(null,thresholdsMs.mouse));
-this._cssAnimations=new WebInspector.SegmentedRange(merge.bind(null,thresholdsMs.animation));
-this._responses=new WebInspector.SegmentedRange(merge.bind(null,0));
-this._scrolls=new WebInspector.SegmentedRange(merge.bind(null,thresholdsMs.animation));
-
-
-
-
-
-
-function merge(threshold,first,second)
-{
-return first.end+threshold>=second.begin&&first.data===second.data?first:null;
-}
-},
-
-
-
-
-
-_inputEventType:function(eventName)
-{
-var prefix="InputLatency::";
-if(!eventName.startsWith(prefix)){
-if(eventName===WebInspector.TimelineIRModel.InputEvents.ImplSideFling)
-return eventName;
-console.error("Unrecognized input latency event: "+eventName);
-return null;
-}
-return eventName.substr(prefix.length);
-}};
-
-
-
-},{}],123:[function(require,module,exports){
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor={};
-
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile=function(jsProfileModel,thread)
-{
-var idleNode=jsProfileModel.idleNode;
-var programNode=jsProfileModel.programNode;
-var gcNode=jsProfileModel.gcNode;
-var samples=jsProfileModel.samples;
-var timestamps=jsProfileModel.timestamps;
-var jsEvents=[];
-
-var nodeToStackMap=new Map();
-nodeToStackMap.set(programNode,[]);
-for(var i=0;i<samples.length;++i){
-var node=jsProfileModel.nodeByIndex(i);
-if(!node){
-console.error(`Node with unknown id ${samples[i]} at index ${i}`);
-continue;
-}
-if(node===gcNode||node===idleNode)
-continue;
-var callFrames=nodeToStackMap.get(node);
-if(!callFrames){
-callFrames=new Array(node.depth+1);
-nodeToStackMap.set(node,callFrames);
-for(var j=0;node.parent;node=node.parent)
-callFrames[j++]=node;
-}
-var jsSampleEvent=new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,
-WebInspector.TimelineModel.RecordType.JSSample,
-WebInspector.TracingModel.Phase.Instant,timestamps[i],thread);
-jsSampleEvent.args["data"]={stackTrace:callFrames};
-jsEvents.push(jsSampleEvent);
-}
-return jsEvents;
-};
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents=function(events)
-{
-
-
-
-
-
-function equalFrames(frame1,frame2)
-{
-return frame1.scriptId===frame2.scriptId&&frame1.functionName===frame2.functionName;
-}
-
-
-
-
-
-function eventEndTime(e)
-{
-return e.endTime||e.startTime;
-}
-
-
-
-
-
-function isJSInvocationEvent(e)
-{
-switch(e.name){
-case WebInspector.TimelineModel.RecordType.RunMicrotasks:
-case WebInspector.TimelineModel.RecordType.FunctionCall:
-case WebInspector.TimelineModel.RecordType.EvaluateScript:
-return true;}
-
-return false;
-}
-
-var jsFrameEvents=[];
-var jsFramesStack=[];
-var lockedJsStackDepth=[];
-var ordinal=0;
-var filterNativeFunctions=!WebInspector.moduleSetting("showNativeFunctionsInJSProfile").get();
-
-
-
-
-function onStartEvent(e)
-{
-e.ordinal=++ordinal;
-extractStackTrace(e);
-
-lockedJsStackDepth.push(jsFramesStack.length);
-}
-
-
-
-
-
-function onInstantEvent(e,parent)
-{
-e.ordinal=++ordinal;
-if(parent&&isJSInvocationEvent(parent))
-extractStackTrace(e);
-}
-
-
-
-
-function onEndEvent(e)
-{
-truncateJSStack(lockedJsStackDepth.pop(),e.endTime);
-}
-
-
-
-
-
-function truncateJSStack(depth,time)
-{
-if(lockedJsStackDepth.length){
-var lockedDepth=lockedJsStackDepth.peekLast();
-if(depth<lockedDepth){
-console.error("Child stack is shallower ("+depth+") than the parent stack ("+lockedDepth+") at "+time);
-depth=lockedDepth;
-}
-}
-if(jsFramesStack.length<depth){
-console.error("Trying to truncate higher than the current stack size at "+time);
-depth=jsFramesStack.length;
-}
-for(var k=0;k<jsFramesStack.length;++k)
-jsFramesStack[k].setEndTime(time);
-jsFramesStack.length=depth;
-}
-
-
-
-
-function filterStackFrames(stack)
-{
-for(var i=0,j=0;i<stack.length;++i){
-var url=stack[i].url;
-if(url&&url.startsWith("native "))
-continue;
-stack[j++]=stack[i];
-}
-stack.length=j;
-}
-
-
-
-
-function extractStackTrace(e)
-{
-var recordTypes=WebInspector.TimelineModel.RecordType;
-var callFrames;
-if(e.name===recordTypes.JSSample){
-var eventData=e.args["data"]||e.args["beginData"];
-callFrames=eventData&&eventData["stackTrace"];
-}else{
-callFrames=jsFramesStack.map(frameEvent=>frameEvent.args["data"]).reverse();
-}
-if(filterNativeFunctions)
-filterStackFrames(callFrames);
-var endTime=eventEndTime(e);
-var numFrames=callFrames.length;
-var minFrames=Math.min(numFrames,jsFramesStack.length);
-var i;
-for(i=lockedJsStackDepth.peekLast()||0;i<minFrames;++i){
-var newFrame=callFrames[numFrames-1-i];
-var oldFrame=jsFramesStack[i].args["data"];
-if(!equalFrames(newFrame,oldFrame))
-break;
-jsFramesStack[i].setEndTime(Math.max(jsFramesStack[i].endTime,endTime));
-}
-truncateJSStack(i,e.startTime);
-for(;i<numFrames;++i){
-var frame=callFrames[numFrames-1-i];
-var jsFrameEvent=new WebInspector.TracingModel.Event(WebInspector.TracingModel.DevToolsTimelineEventCategory,recordTypes.JSFrame,
-WebInspector.TracingModel.Phase.Complete,e.startTime,e.thread);
-jsFrameEvent.ordinal=e.ordinal;
-jsFrameEvent.addArgs({data:frame});
-jsFrameEvent.setEndTime(endTime);
-jsFramesStack.push(jsFrameEvent);
-jsFrameEvents.push(jsFrameEvent);
-}
-}
-
-
-
-
-
-function findFirstTopLevelEvent(events)
-{
-for(var i=0;i<events.length;++i){
-if(WebInspector.TracingModel.isTopLevelEvent(events[i]))
-return events[i];
-}
-return null;
-}
-
-var firstTopLevelEvent=findFirstTopLevelEvent(events);
-if(firstTopLevelEvent)
-WebInspector.TimelineModel.forEachEvent(events,onStartEvent,onEndEvent,onInstantEvent,firstTopLevelEvent.startTime);
-return jsFrameEvents;
-};
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.CodeMap=function()
-{
-
-this._banks=new Map();
-};
-
-
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.CodeMap.Entry=function(address,size,callFrame)
-{
-this.address=address;
-this.size=size;
-this.callFrame=callFrame;
-};
-
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.CodeMap.comparator=function(address,entry)
-{
-return address-entry.address;
-};
-
-WebInspector.TimelineJSProfileProcessor.CodeMap.prototype={
-
-
-
-
-
-addEntry:function(addressHex,size,callFrame)
-{
-var entry=new WebInspector.TimelineJSProfileProcessor.CodeMap.Entry(this._getAddress(addressHex),size,callFrame);
-this._addEntry(addressHex,entry);
-},
-
-
-
-
-
-
-moveEntry:function(oldAddressHex,newAddressHex,size)
-{
-var entry=this._getBank(oldAddressHex).removeEntry(this._getAddress(oldAddressHex));
-if(!entry){
-console.error("Entry at address "+oldAddressHex+" not found");
-return;
-}
-entry.address=this._getAddress(newAddressHex);
-entry.size=size;
-this._addEntry(newAddressHex,entry);
-},
-
-
-
-
-
-lookupEntry:function(addressHex)
-{
-return this._getBank(addressHex).lookupEntry(this._getAddress(addressHex));
-},
-
-
-
-
-
-_addEntry:function(addressHex,entry)
-{
-
-this._getBank(addressHex).addEntry(entry);
-},
-
-
-
-
-
-_getBank:function(addressHex)
-{
-addressHex=addressHex.slice(2);
-
-var bankSizeHexDigits=13;
-var maxHexDigits=16;
-var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);
-var bank=this._banks.get(bankName);
-if(!bank){
-bank=new WebInspector.TimelineJSProfileProcessor.CodeMap.Bank();
-this._banks.set(bankName,bank);
-}
-return bank;
-},
-
-
-
-
-
-_getAddress:function(addressHex)
-{
-
-var bankSizeHexDigits=13;
-addressHex=addressHex.slice(2);
-return parseInt(addressHex.slice(-bankSizeHexDigits),16);
-}};
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.CodeMap.Bank=function()
-{
-
-this._entries=[];
-};
-
-WebInspector.TimelineJSProfileProcessor.CodeMap.Bank.prototype={
-
-
-
-
-removeEntry:function(address)
-{
-var index=this._entries.lowerBound(address,WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);
-var entry=this._entries[index];
-if(!entry||entry.address!==address)
-return null;
-this._entries.splice(index,1);
-return entry;
-},
-
-
-
-
-
-lookupEntry:function(address)
-{
-var index=this._entries.upperBound(address,WebInspector.TimelineJSProfileProcessor.CodeMap.comparator)-1;
-var entry=this._entries[index];
-return entry&&address<entry.address+entry.size?entry.callFrame:null;
-},
-
-
-
-
-addEntry:function(newEntry)
-{
-var endAddress=newEntry.address+newEntry.size;
-var lastIndex=this._entries.lowerBound(endAddress,WebInspector.TimelineJSProfileProcessor.CodeMap.comparator);
-var index;
-for(index=lastIndex-1;index>=0;--index){
-var entry=this._entries[index];
-var entryEndAddress=entry.address+entry.size;
-if(entryEndAddress<=newEntry.address)
-break;
-}
-++index;
-this._entries.splice(index,lastIndex-index,newEntry);
-}};
-
-
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor._buildCallFrame=function(name,scriptId)
-{
-
-
-
-
-
-
-
-
-
-function createFrame(functionName,url,scriptId,line,column,isNative)
-{
-return{
-"functionName":functionName,
-"url":url||"",
-"scriptId":scriptId||"0",
-"lineNumber":line||0,
-"columnNumber":column||0,
-"isNative":isNative||false};
-
-}
-
-
-
-
-
-var rePrefix=/^(\w*:)?[*~]?(.*)$/m;
-var tokens=rePrefix.exec(name);
-var prefix=tokens[1];
-var body=tokens[2];
-var rawName;
-var rawUrl;
-if(prefix==="Script:"){
-rawName="";
-rawUrl=body;
-}else{
-var spacePos=body.lastIndexOf(" ");
-rawName=spacePos!==-1?body.substr(0,spacePos):body;
-rawUrl=spacePos!==-1?body.substr(spacePos+1):"";
-}
-var nativeSuffix=" native";
-var isNative=rawName.endsWith(nativeSuffix);
-var functionName=isNative?rawName.slice(0,-nativeSuffix.length):rawName;
-var urlData=WebInspector.ParsedURL.splitLineAndColumn(rawUrl);
-var url=urlData.url||"";
-var line=urlData.lineNumber||0;
-var column=urlData.columnNumber||0;
-return createFrame(functionName,url,String(scriptId),line,column,isNative);
-};
-
-
-
-
-
-WebInspector.TimelineJSProfileProcessor.processRawV8Samples=function(events)
-{
-var missingAddesses=new Set();
-
-
-
-
-
-function convertRawFrame(address)
-{
-var entry=codeMap.lookupEntry(address);
-if(entry)
-return entry.isNative?null:entry;
-if(!missingAddesses.has(address)){
-missingAddesses.add(address);
-console.error("Address "+address+" has missing code entry");
-}
-return null;
-}
-
-var recordTypes=WebInspector.TimelineModel.RecordType;
-var samples=[];
-var codeMap=new WebInspector.TimelineJSProfileProcessor.CodeMap();
-for(var i=0;i<events.length;++i){
-var e=events[i];
-var data=e.args["data"];
-switch(e.name){
-case recordTypes.JitCodeAdded:
-var frame=WebInspector.TimelineJSProfileProcessor._buildCallFrame(data["name"],data["script_id"]);
-codeMap.addEntry(data["code_start"],data["code_len"],frame);
-break;
-case recordTypes.JitCodeMoved:
-codeMap.moveEntry(data["code_start"],data["new_code_start"],data["code_len"]);
-break;
-case recordTypes.V8Sample:
-var rawStack=data["stack"];
-
-
-if(data["vm_state"]==="js"&&!rawStack.length)
-break;
-var stack=rawStack.map(convertRawFrame);
-stack.remove(null);
-var sampleEvent=new WebInspector.TracingModel.Event(
-WebInspector.TracingModel.DevToolsTimelineEventCategory,
-WebInspector.TimelineModel.RecordType.JSSample,
-WebInspector.TracingModel.Phase.Instant,e.startTime,e.thread);
-sampleEvent.ordinal=e.ordinal;
-sampleEvent.args={"data":{"stackTrace":stack}};
-samples.push(sampleEvent);
-break;}
-
-}
-
-return samples;
-};
-
-},{}],124:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineModel=function(eventFilter)
-{
-this._eventFilter=eventFilter;
-this.reset();
-};
-
-
-
-
-WebInspector.TimelineModel.RecordType={
-Task:"Task",
-Program:"Program",
-EventDispatch:"EventDispatch",
-
-GPUTask:"GPUTask",
-
-Animation:"Animation",
-RequestMainThreadFrame:"RequestMainThreadFrame",
-BeginFrame:"BeginFrame",
-NeedsBeginFrameChanged:"NeedsBeginFrameChanged",
-BeginMainThreadFrame:"BeginMainThreadFrame",
-ActivateLayerTree:"ActivateLayerTree",
-DrawFrame:"DrawFrame",
-HitTest:"HitTest",
-ScheduleStyleRecalculation:"ScheduleStyleRecalculation",
-RecalculateStyles:"RecalculateStyles",
-UpdateLayoutTree:"UpdateLayoutTree",
-InvalidateLayout:"InvalidateLayout",
-Layout:"Layout",
-UpdateLayer:"UpdateLayer",
-UpdateLayerTree:"UpdateLayerTree",
-PaintSetup:"PaintSetup",
-Paint:"Paint",
-PaintImage:"PaintImage",
-Rasterize:"Rasterize",
-RasterTask:"RasterTask",
-ScrollLayer:"ScrollLayer",
-CompositeLayers:"CompositeLayers",
-
-ScheduleStyleInvalidationTracking:"ScheduleStyleInvalidationTracking",
-StyleRecalcInvalidationTracking:"StyleRecalcInvalidationTracking",
-StyleInvalidatorInvalidationTracking:"StyleInvalidatorInvalidationTracking",
-LayoutInvalidationTracking:"LayoutInvalidationTracking",
-LayerInvalidationTracking:"LayerInvalidationTracking",
-PaintInvalidationTracking:"PaintInvalidationTracking",
-ScrollInvalidationTracking:"ScrollInvalidationTracking",
-
-ParseHTML:"ParseHTML",
-ParseAuthorStyleSheet:"ParseAuthorStyleSheet",
-
-TimerInstall:"TimerInstall",
-TimerRemove:"TimerRemove",
-TimerFire:"TimerFire",
-
-XHRReadyStateChange:"XHRReadyStateChange",
-XHRLoad:"XHRLoad",
-CompileScript:"v8.compile",
-EvaluateScript:"EvaluateScript",
-
-CommitLoad:"CommitLoad",
-MarkLoad:"MarkLoad",
-MarkDOMContent:"MarkDOMContent",
-MarkFirstPaint:"MarkFirstPaint",
-
-TimeStamp:"TimeStamp",
-ConsoleTime:"ConsoleTime",
-UserTiming:"UserTiming",
-
-ResourceSendRequest:"ResourceSendRequest",
-ResourceReceiveResponse:"ResourceReceiveResponse",
-ResourceReceivedData:"ResourceReceivedData",
-ResourceFinish:"ResourceFinish",
-
-RunMicrotasks:"RunMicrotasks",
-FunctionCall:"FunctionCall",
-GCEvent:"GCEvent",
-MajorGC:"MajorGC",
-MinorGC:"MinorGC",
-JSFrame:"JSFrame",
-JSSample:"JSSample",
-
-
-
-V8Sample:"V8Sample",
-JitCodeAdded:"JitCodeAdded",
-JitCodeMoved:"JitCodeMoved",
-ParseScriptOnBackground:"v8.parseOnBackground",
-
-UpdateCounters:"UpdateCounters",
-
-RequestAnimationFrame:"RequestAnimationFrame",
-CancelAnimationFrame:"CancelAnimationFrame",
-FireAnimationFrame:"FireAnimationFrame",
-
-RequestIdleCallback:"RequestIdleCallback",
-CancelIdleCallback:"CancelIdleCallback",
-FireIdleCallback:"FireIdleCallback",
-
-WebSocketCreate:"WebSocketCreate",
-WebSocketSendHandshakeRequest:"WebSocketSendHandshakeRequest",
-WebSocketReceiveHandshakeResponse:"WebSocketReceiveHandshakeResponse",
-WebSocketDestroy:"WebSocketDestroy",
-
-EmbedderCallback:"EmbedderCallback",
-
-SetLayerTreeId:"SetLayerTreeId",
-TracingStartedInPage:"TracingStartedInPage",
-TracingSessionIdForWorker:"TracingSessionIdForWorker",
-
-DecodeImage:"Decode Image",
-ResizeImage:"Resize Image",
-DrawLazyPixelRef:"Draw LazyPixelRef",
-DecodeLazyPixelRef:"Decode LazyPixelRef",
-
-LazyPixelRef:"LazyPixelRef",
-LayerTreeHostImplSnapshot:"cc::LayerTreeHostImpl",
-PictureSnapshot:"cc::Picture",
-DisplayItemListSnapshot:"cc::DisplayItemList",
-LatencyInfo:"LatencyInfo",
-LatencyInfoFlow:"LatencyInfo.Flow",
-InputLatencyMouseMove:"InputLatency::MouseMove",
-InputLatencyMouseWheel:"InputLatency::MouseWheel",
-ImplSideFling:"InputHandlerProxy::HandleGestureFling::started",
-GCIdleLazySweep:"ThreadState::performIdleLazySweep",
-GCCompleteSweep:"ThreadState::completeSweep",
-GCCollectGarbage:"BlinkGCMarking",
-
-
-
-CpuProfile:"CpuProfile"};
-
-
-WebInspector.TimelineModel.Category={
-Console:"blink.console",
-UserTiming:"blink.user_timing",
-LatencyInfo:"latencyInfo"};
-
-
-
-
-
-WebInspector.TimelineModel.WarningType={
-ForcedStyle:"ForcedStyle",
-ForcedLayout:"ForcedLayout",
-IdleDeadlineExceeded:"IdleDeadlineExceeded",
-V8Deopt:"V8Deopt"};
-
-
-WebInspector.TimelineModel.MainThreadName="main";
-WebInspector.TimelineModel.WorkerThreadName="DedicatedWorker Thread";
-WebInspector.TimelineModel.RendererMainThreadName="CrRendererMain";
-
-
-
-
-WebInspector.TimelineModel.AsyncEventGroup={
-animation:Symbol("animation"),
-console:Symbol("console"),
-userTiming:Symbol("userTiming"),
-input:Symbol("input")};
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineModel.forEachEvent=function(events,onStartEvent,onEndEvent,onInstantEvent,startTime,endTime)
-{
-startTime=startTime||0;
-endTime=endTime||Infinity;
-var stack=[];
-for(var i=0;i<events.length;++i){
-var e=events[i];
-if((e.endTime||e.startTime)<startTime)
-continue;
-if(e.startTime>=endTime)
-break;
-if(WebInspector.TracingModel.isAsyncPhase(e.phase)||WebInspector.TracingModel.isFlowPhase(e.phase))
-continue;
-while(stack.length&&stack.peekLast().endTime<=e.startTime)
-onEndEvent(stack.pop());
-if(e.duration){
-onStartEvent(e);
-stack.push(e);
-}else{
-onInstantEvent&&onInstantEvent(e,stack.peekLast()||null);
-}
-}
-while(stack.length)
-onEndEvent(stack.pop());
-};
-
-WebInspector.TimelineModel.DevToolsMetadataEvent={
-TracingStartedInBrowser:"TracingStartedInBrowser",
-TracingStartedInPage:"TracingStartedInPage",
-TracingSessionIdForWorker:"TracingSessionIdForWorker"};
-
-
-
-
-
-
-WebInspector.TimelineModel.VirtualThread=function(name)
-{
-this.name=name;
-
-this.events=[];
-
-this.asyncEventsByGroup=new Map();
-};
-
-WebInspector.TimelineModel.VirtualThread.prototype={
-
-
-
-isWorker:function()
-{
-return this.name===WebInspector.TimelineModel.WorkerThreadName;
-}};
-
-
-
-
-
-
-WebInspector.TimelineModel.Record=function(traceEvent)
-{
-this._event=traceEvent;
-this._children=[];
-};
-
-
-
-
-
-
-WebInspector.TimelineModel.Record._compareStartTime=function(a,b)
-{
-
-return a.startTime()<=b.startTime()?-1:1;
-};
-
-WebInspector.TimelineModel.Record.prototype={
-
-
-
-target:function()
-{
-var threadName=this._event.thread.name();
-
-return threadName===WebInspector.TimelineModel.RendererMainThreadName?WebInspector.targetManager.targets()[0]||null:null;
-},
-
-
-
-
-children:function()
-{
-return this._children;
-},
-
-
-
-
-startTime:function()
-{
-return this._event.startTime;
-},
-
-
-
-
-endTime:function()
-{
-return this._event.endTime||this._event.startTime;
-},
-
-
-
-
-thread:function()
-{
-if(this._event.thread.name()===WebInspector.TimelineModel.RendererMainThreadName)
-return WebInspector.TimelineModel.MainThreadName;
-return this._event.thread.name();
-},
-
-
-
-
-type:function()
-{
-return WebInspector.TimelineModel._eventType(this._event);
-},
-
-
-
-
-
-getUserObject:function(key)
-{
-if(key==="TimelineUIUtils::preview-element")
-return this._event.previewElement;
-throw new Error("Unexpected key: "+key);
-},
-
-
-
-
-
-setUserObject:function(key,value)
-{
-if(key!=="TimelineUIUtils::preview-element")
-throw new Error("Unexpected key: "+key);
-this._event.previewElement=value;
-},
-
-
-
-
-traceEvent:function()
-{
-return this._event;
-},
-
-
-
-
-_addChild:function(child)
-{
-this._children.push(child);
-child.parent=this;
-}};
-
-
-
-WebInspector.TimelineModel.MetadataEvents;
-
-
-
-
-WebInspector.TimelineModel._eventType=function(event)
-{
-if(event.hasCategory(WebInspector.TimelineModel.Category.Console))
-return WebInspector.TimelineModel.RecordType.ConsoleTime;
-if(event.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
-return WebInspector.TimelineModel.RecordType.UserTiming;
-if(event.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo))
-return WebInspector.TimelineModel.RecordType.LatencyInfo;
-return event.name;
-};
-
-WebInspector.TimelineModel.prototype={
-
-
-
-
-
-
-forAllRecords:function(preOrderCallback,postOrderCallback)
-{
-
-
-
-
-
-function processRecords(records,depth)
-{
-for(var i=0;i<records.length;++i){
-var record=records[i];
-if(preOrderCallback&&preOrderCallback(record,depth))
-return true;
-if(processRecords(record.children(),depth+1))
-return true;
-if(postOrderCallback&&postOrderCallback(record,depth))
-return true;
-}
-return false;
-}
-return processRecords(this._records,0);
-},
-
-
-
-
-
-forAllFilteredRecords:function(filters,callback)
-{
-
-
-
-
-
-
-function processRecord(record,depth)
-{
-var visible=WebInspector.TimelineModel.isVisible(filters,record.traceEvent());
-if(visible&&callback(record,depth))
-return true;
-
-for(var i=0;i<record.children().length;++i){
-if(processRecord.call(this,record.children()[i],visible?depth+1:depth))
-return true;
-}
-return false;
-}
-
-for(var i=0;i<this._records.length;++i)
-processRecord.call(this,this._records[i],0);
-},
-
-
-
-
-records:function()
-{
-return this._records;
-},
-
-
-
-
-cpuProfiles:function()
-{
-return this._cpuProfiles;
-},
-
-
-
-
-sessionId:function()
-{
-return this._sessionId;
-},
-
-
-
-
-
-targetByEvent:function(event)
-{
-
-var workerId=this._workerIdByThread.get(event.thread);
-var mainTarget=WebInspector.targetManager.mainTarget();
-return workerId?mainTarget.workerManager.targetByWorkerId(workerId):mainTarget;
-},
-
-
-
-
-
-setEvents:function(tracingModel,produceTraceStartedInPage)
-{
-this.reset();
-this._resetProcessingState();
-
-this._minimumRecordTime=tracingModel.minimumRecordTime();
-this._maximumRecordTime=tracingModel.maximumRecordTime();
-
-var metadataEvents=this._processMetadataEvents(tracingModel,!!produceTraceStartedInPage);
-if(Runtime.experiments.isEnabled("timelineShowAllProcesses")){
-var lastPageMetaEvent=metadataEvents.page.peekLast();
-for(var process of tracingModel.sortedProcesses()){
-for(var thread of process.sortedThreads())
-this._processThreadEvents(0,Infinity,thread,thread===lastPageMetaEvent.thread);
-}
-}else{
-var startTime=0;
-for(var i=0,length=metadataEvents.page.length;i<length;i++){
-var metaEvent=metadataEvents.page[i];
-var process=metaEvent.thread.process();
-var endTime=i+1<length?metadataEvents.page[i+1].startTime:Infinity;
-this._currentPage=metaEvent.args["data"]&&metaEvent.args["data"]["page"];
-for(var thread of process.sortedThreads()){
-if(thread.name()===WebInspector.TimelineModel.WorkerThreadName){
-var workerMetaEvent=metadataEvents.workers.find(e=>e.args["data"]["workerThreadId"]===thread.id());
-if(!workerMetaEvent)
-continue;
-var workerId=workerMetaEvent.args["data"]["workerId"];
-if(workerId)
-this._workerIdByThread.set(thread,workerId);
-}
-this._processThreadEvents(startTime,endTime,thread,thread===metaEvent.thread);
-}
-startTime=endTime;
-}
-}
-this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
-
-this._processBrowserEvents(tracingModel);
-this._buildTimelineRecords();
-this._buildGPUEvents(tracingModel);
-this._insertFirstPaintEvent();
-this._resetProcessingState();
-},
-
-
-
-
-
-
-_processMetadataEvents:function(tracingModel,produceTraceStartedInPage)
-{
-var metadataEvents=tracingModel.devToolsMetadataEvents();
-
-var pageDevToolsMetadataEvents=[];
-var workersDevToolsMetadataEvents=[];
-for(var event of metadataEvents){
-if(event.name===WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage){
-pageDevToolsMetadataEvents.push(event);
-}else if(event.name===WebInspector.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker){
-workersDevToolsMetadataEvents.push(event);
-}else if(event.name===WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser){
-console.assert(!this._mainFrameNodeId,"Multiple sessions in trace");
-this._mainFrameNodeId=event.args["frameTreeNodeId"];
-}
-}
-if(!pageDevToolsMetadataEvents.length){
-
-var pageMetaEvent=produceTraceStartedInPage?this._makeMockPageMetadataEvent(tracingModel):null;
-if(!pageMetaEvent){
-console.error(WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage+" event not found.");
-return{page:[],workers:[]};
-}
-pageDevToolsMetadataEvents.push(pageMetaEvent);
-}
-var sessionId=pageDevToolsMetadataEvents[0].args["sessionId"]||pageDevToolsMetadataEvents[0].args["data"]["sessionId"];
-this._sessionId=sessionId;
-
-var mismatchingIds=new Set();
-
-
-
-
-function checkSessionId(event)
-{
-var args=event.args;
-
-if(args["data"])
-args=args["data"];
-var id=args["sessionId"];
-if(id===sessionId)
-return true;
-mismatchingIds.add(id);
-return false;
-}
-var result={
-page:pageDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime),
-workers:workersDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime)};
-
-if(mismatchingIds.size)
-WebInspector.console.error("Timeline recording was started in more than one page simultaneously. Session id mismatch: "+this._sessionId+" and "+mismatchingIds.valuesArray()+".");
-return result;
-},
-
-
-
-
-
-_makeMockPageMetadataEvent:function(tracingModel)
-{
-var rendererMainThreadName=WebInspector.TimelineModel.RendererMainThreadName;
-
-var process=tracingModel.sortedProcesses().filter(function(p){return p.threadByName(rendererMainThreadName);})[0];
-var thread=process&&process.threadByName(rendererMainThreadName);
-if(!thread)
-return null;
-var pageMetaEvent=new WebInspector.TracingModel.Event(
-WebInspector.TracingModel.DevToolsMetadataEventCategory,
-WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage,
-WebInspector.TracingModel.Phase.Metadata,
-tracingModel.minimumRecordTime(),thread);
-pageMetaEvent.addArgs({"data":{"sessionId":"mockSessionId"}});
-return pageMetaEvent;
-},
-
-_insertFirstPaintEvent:function()
-{
-if(!this._firstCompositeLayers)
-return;
-
-
-var recordTypes=WebInspector.TimelineModel.RecordType;
-var i=this._inspectedTargetEvents.lowerBound(this._firstCompositeLayers,WebInspector.TracingModel.Event.compareStartTime);
-for(;i<this._inspectedTargetEvents.length&&this._inspectedTargetEvents[i].name!==recordTypes.DrawFrame;++i){}
-if(i>=this._inspectedTargetEvents.length)
-return;
-var drawFrameEvent=this._inspectedTargetEvents[i];
-var firstPaintEvent=new WebInspector.TracingModel.Event(drawFrameEvent.categoriesString,recordTypes.MarkFirstPaint,WebInspector.TracingModel.Phase.Instant,drawFrameEvent.startTime,drawFrameEvent.thread);
-this._mainThreadEvents.splice(this._mainThreadEvents.lowerBound(firstPaintEvent,WebInspector.TracingModel.Event.compareStartTime),0,firstPaintEvent);
-var firstPaintRecord=new WebInspector.TimelineModel.Record(firstPaintEvent);
-this._eventDividerRecords.splice(this._eventDividerRecords.lowerBound(firstPaintRecord,WebInspector.TimelineModel.Record._compareStartTime),0,firstPaintRecord);
-},
-
-
-
-
-_processBrowserEvents:function(tracingModel)
-{
-var browserMain=WebInspector.TracingModel.browserMainThread(tracingModel);
-if(!browserMain)
-return;
-
-
-browserMain.events().forEach(this._processBrowserEvent,this);
-
-var asyncEventsByGroup=new Map();
-this._processAsyncEvents(asyncEventsByGroup,browserMain.asyncEvents());
-this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup,asyncEventsByGroup);
-},
-
-_buildTimelineRecords:function()
-{
-var topLevelRecords=this._buildTimelineRecordsForThread(this.mainThreadEvents());
-for(var i=0;i<topLevelRecords.length;i++){
-var record=topLevelRecords[i];
-if(WebInspector.TracingModel.isTopLevelEvent(record.traceEvent()))
-this._mainThreadTasks.push(record);
-}
-
-
-
-
-
-function processVirtualThreadEvents(virtualThread)
-{
-var threadRecords=this._buildTimelineRecordsForThread(virtualThread.events);
-topLevelRecords=topLevelRecords.mergeOrdered(threadRecords,WebInspector.TimelineModel.Record._compareStartTime);
-}
-this.virtualThreads().forEach(processVirtualThreadEvents.bind(this));
-this._records=topLevelRecords;
-},
-
-
-
-
-_buildGPUEvents:function(tracingModel)
-{
-var thread=tracingModel.threadByName("GPU Process","CrGpuMain");
-if(!thread)
-return;
-var gpuEventName=WebInspector.TimelineModel.RecordType.GPUTask;
-this._gpuEvents=thread.events().filter(event=>event.name===gpuEventName);
-},
-
-
-
-
-
-_buildTimelineRecordsForThread:function(threadEvents)
-{
-var recordStack=[];
-var topLevelRecords=[];
-
-for(var i=0,size=threadEvents.length;i<size;++i){
-var event=threadEvents[i];
-for(var top=recordStack.peekLast();top&&top._event.endTime<=event.startTime;top=recordStack.peekLast())
-recordStack.pop();
-if(event.phase===WebInspector.TracingModel.Phase.AsyncEnd||event.phase===WebInspector.TracingModel.Phase.NestableAsyncEnd)
-continue;
-var parentRecord=recordStack.peekLast();
-
-if(WebInspector.TracingModel.isAsyncBeginPhase(event.phase)&&parentRecord&&event.endTime>parentRecord._event.endTime)
-continue;
-var record=new WebInspector.TimelineModel.Record(event);
-if(WebInspector.TimelineModel.isMarkerEvent(event))
-this._eventDividerRecords.push(record);
-if(!this._eventFilter.accept(event)&&!WebInspector.TracingModel.isTopLevelEvent(event))
-continue;
-if(parentRecord)
-parentRecord._addChild(record);else
-
-topLevelRecords.push(record);
-if(event.endTime)
-recordStack.push(record);
-}
-
-return topLevelRecords;
-},
-
-_resetProcessingState:function()
-{
-this._asyncEventTracker=new WebInspector.TimelineAsyncEventTracker();
-this._invalidationTracker=new WebInspector.InvalidationTracker();
-this._layoutInvalidate={};
-this._lastScheduleStyleRecalculation={};
-this._paintImageEventByPixelRefId={};
-this._lastPaintForLayer={};
-this._lastRecalculateStylesEvent=null;
-this._currentScriptEvent=null;
-this._eventStack=[];
-this._hadCommitLoad=false;
-this._firstCompositeLayers=null;
-
-this._knownInputEvents=new Set();
-this._currentPage=null;
-},
-
-
-
-
-
-
-
-_processThreadEvents:function(startTime,endTime,thread,isMainThread)
-{
-var events=thread.events();
-var asyncEvents=thread.asyncEvents();
-
-var jsSamples;
-if(Runtime.experiments.isEnabled("timelineTracingJSProfile")){
-jsSamples=WebInspector.TimelineJSProfileProcessor.processRawV8Samples(events);
-}else{
-var cpuProfileEvent=events.peekLast();
-if(cpuProfileEvent&&cpuProfileEvent.name===WebInspector.TimelineModel.RecordType.CpuProfile){
-var cpuProfile=cpuProfileEvent.args["data"]["cpuProfile"];
-if(cpuProfile){
-var jsProfileModel=new WebInspector.CPUProfileDataModel(cpuProfile);
-this._cpuProfiles.push(jsProfileModel);
-jsSamples=WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(jsProfileModel,thread);
-}
-}
-}
-
-if(jsSamples&&jsSamples.length)
-events=events.mergeOrdered(jsSamples,WebInspector.TracingModel.Event.orderedCompareStartTime);
-if(jsSamples||events.some(function(e){return e.name===WebInspector.TimelineModel.RecordType.JSSample;})){
-var jsFrameEvents=WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(events);
-if(jsFrameEvents&&jsFrameEvents.length)
-events=jsFrameEvents.mergeOrdered(events,WebInspector.TracingModel.Event.orderedCompareStartTime);
-}
-
-var threadEvents;
-var threadAsyncEventsByGroup;
-if(isMainThread){
-threadEvents=this._mainThreadEvents;
-threadAsyncEventsByGroup=this._mainThreadAsyncEventsByGroup;
-}else{
-var virtualThread=new WebInspector.TimelineModel.VirtualThread(thread.name());
-this._virtualThreads.push(virtualThread);
-threadEvents=virtualThread.events;
-threadAsyncEventsByGroup=virtualThread.asyncEventsByGroup;
-}
-
-this._eventStack=[];
-var i=events.lowerBound(startTime,function(time,event){return time-event.startTime;});
-var length=events.length;
-for(;i<length;i++){
-var event=events[i];
-if(endTime&&event.startTime>=endTime)
-break;
-if(!this._processEvent(event))
-continue;
-threadEvents.push(event);
-this._inspectedTargetEvents.push(event);
-}
-this._processAsyncEvents(threadAsyncEventsByGroup,asyncEvents,startTime,endTime);
-
-if(thread.name()==="Compositor"){
-this._mergeAsyncEvents(this._mainThreadAsyncEventsByGroup,threadAsyncEventsByGroup);
-threadAsyncEventsByGroup.clear();
-}
-},
-
-
-
-
-
-
-
-_processAsyncEvents:function(asyncEventsByGroup,asyncEvents,startTime,endTime)
-{
-var i=startTime?asyncEvents.lowerBound(startTime,function(time,asyncEvent){return time-asyncEvent.startTime;}):0;
-for(;i<asyncEvents.length;++i){
-var asyncEvent=asyncEvents[i];
-if(endTime&&asyncEvent.startTime>=endTime)
-break;
-var asyncGroup=this._processAsyncEvent(asyncEvent);
-if(!asyncGroup)
-continue;
-var groupAsyncEvents=asyncEventsByGroup.get(asyncGroup);
-if(!groupAsyncEvents){
-groupAsyncEvents=[];
-asyncEventsByGroup.set(asyncGroup,groupAsyncEvents);
-}
-groupAsyncEvents.push(asyncEvent);
-}
-},
-
-
-
-
-
-_processEvent:function(event)
-{
-var eventStack=this._eventStack;
-while(eventStack.length&&eventStack.peekLast().endTime<=event.startTime)
-eventStack.pop();
-
-var recordTypes=WebInspector.TimelineModel.RecordType;
-
-if(this._currentScriptEvent&&event.startTime>this._currentScriptEvent.endTime)
-this._currentScriptEvent=null;
-
-var eventData=event.args["data"]||event.args["beginData"]||{};
-if(eventData["stackTrace"])
-event.stackTrace=eventData["stackTrace"];
-if(event.stackTrace&&event.name!==recordTypes.JSSample){
-
-
-for(var i=0;i<event.stackTrace.length;++i){
---event.stackTrace[i].lineNumber;
---event.stackTrace[i].columnNumber;
-}
-}
-
-if(eventStack.length&&eventStack.peekLast().name===recordTypes.EventDispatch)
-eventStack.peekLast().hasChildren=true;
-this._asyncEventTracker.processEvent(event);
-if(event.initiator&&event.initiator.url)
-event.url=event.initiator.url;
-switch(event.name){
-case recordTypes.ResourceSendRequest:
-case recordTypes.WebSocketCreate:
-event.url=eventData["url"];
-event.initiator=eventStack.peekLast()||null;
-break;
-
-case recordTypes.ScheduleStyleRecalculation:
-this._lastScheduleStyleRecalculation[eventData["frame"]]=event;
-break;
-
-case recordTypes.UpdateLayoutTree:
-case recordTypes.RecalculateStyles:
-this._invalidationTracker.didRecalcStyle(event);
-if(event.args["beginData"])
-event.initiator=this._lastScheduleStyleRecalculation[event.args["beginData"]["frame"]];
-this._lastRecalculateStylesEvent=event;
-if(this._currentScriptEvent)
-event.warning=WebInspector.TimelineModel.WarningType.ForcedStyle;
-break;
-
-case recordTypes.ScheduleStyleInvalidationTracking:
-case recordTypes.StyleRecalcInvalidationTracking:
-case recordTypes.StyleInvalidatorInvalidationTracking:
-case recordTypes.LayoutInvalidationTracking:
-case recordTypes.LayerInvalidationTracking:
-case recordTypes.PaintInvalidationTracking:
-case recordTypes.ScrollInvalidationTracking:
-this._invalidationTracker.addInvalidation(new WebInspector.InvalidationTrackingEvent(event));
-break;
-
-case recordTypes.InvalidateLayout:
-
-
-var layoutInitator=event;
-var frameId=eventData["frame"];
-if(!this._layoutInvalidate[frameId]&&this._lastRecalculateStylesEvent&&this._lastRecalculateStylesEvent.endTime>event.startTime)
-layoutInitator=this._lastRecalculateStylesEvent.initiator;
-this._layoutInvalidate[frameId]=layoutInitator;
-break;
-
-case recordTypes.Layout:
-this._invalidationTracker.didLayout(event);
-var frameId=event.args["beginData"]["frame"];
-event.initiator=this._layoutInvalidate[frameId];
-
-if(event.args["endData"]){
-event.backendNodeId=event.args["endData"]["rootNode"];
-event.highlightQuad=event.args["endData"]["root"];
-}
-this._layoutInvalidate[frameId]=null;
-if(this._currentScriptEvent)
-event.warning=WebInspector.TimelineModel.WarningType.ForcedLayout;
-break;
-
-case recordTypes.FunctionCall:
-
-if(typeof eventData["scriptName"]==="string")
-eventData["url"]=eventData["scriptName"];
-if(typeof eventData["scriptLine"]==="number")
-eventData["lineNumber"]=eventData["scriptLine"];
-
-case recordTypes.EvaluateScript:
-case recordTypes.CompileScript:
-if(typeof eventData["lineNumber"]==="number")
---eventData["lineNumber"];
-if(typeof eventData["columnNumber"]==="number")
---eventData["columnNumber"];
-if(!this._currentScriptEvent)
-this._currentScriptEvent=event;
-break;
-
-case recordTypes.SetLayerTreeId:
-this._inspectedTargetLayerTreeId=event.args["layerTreeId"]||event.args["data"]["layerTreeId"];
-break;
-
-case recordTypes.Paint:
-this._invalidationTracker.didPaint(event);
-event.highlightQuad=eventData["clip"];
-event.backendNodeId=eventData["nodeId"];
-
-if(!eventData["layerId"])
-break;
-var layerId=eventData["layerId"];
-this._lastPaintForLayer[layerId]=event;
-break;
-
-case recordTypes.DisplayItemListSnapshot:
-case recordTypes.PictureSnapshot:
-var layerUpdateEvent=this._findAncestorEvent(recordTypes.UpdateLayer);
-if(!layerUpdateEvent||layerUpdateEvent.args["layerTreeId"]!==this._inspectedTargetLayerTreeId)
-break;
-var paintEvent=this._lastPaintForLayer[layerUpdateEvent.args["layerId"]];
-if(paintEvent)
-paintEvent.picture=event;
-break;
-
-case recordTypes.ScrollLayer:
-event.backendNodeId=eventData["nodeId"];
-break;
-
-case recordTypes.PaintImage:
-event.backendNodeId=eventData["nodeId"];
-event.url=eventData["url"];
-break;
-
-case recordTypes.DecodeImage:
-case recordTypes.ResizeImage:
-var paintImageEvent=this._findAncestorEvent(recordTypes.PaintImage);
-if(!paintImageEvent){
-var decodeLazyPixelRefEvent=this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);
-paintImageEvent=decodeLazyPixelRefEvent&&this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]];
-}
-if(!paintImageEvent)
-break;
-event.backendNodeId=paintImageEvent.backendNodeId;
-event.url=paintImageEvent.url;
-break;
-
-case recordTypes.DrawLazyPixelRef:
-var paintImageEvent=this._findAncestorEvent(recordTypes.PaintImage);
-if(!paintImageEvent)
-break;
-this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]]=paintImageEvent;
-event.backendNodeId=paintImageEvent.backendNodeId;
-event.url=paintImageEvent.url;
-break;
-
-case recordTypes.MarkDOMContent:
-case recordTypes.MarkLoad:
-var page=eventData["page"];
-if(page&&page!==this._currentPage)
-return false;
-break;
-
-case recordTypes.CommitLoad:
-var page=eventData["page"];
-if(page&&page!==this._currentPage)
-return false;
-if(!eventData["isMainFrame"])
-break;
-this._hadCommitLoad=true;
-this._firstCompositeLayers=null;
-break;
-
-case recordTypes.CompositeLayers:
-if(!this._firstCompositeLayers&&this._hadCommitLoad)
-this._firstCompositeLayers=event;
-break;
-
-case recordTypes.FireIdleCallback:
-if(event.duration>eventData["allottedMilliseconds"]){
-event.warning=WebInspector.TimelineModel.WarningType.IdleDeadlineExceeded;
-}
-break;}
-
-if(WebInspector.TracingModel.isAsyncPhase(event.phase))
-return true;
-var duration=event.duration;
-if(!duration)
-return true;
-if(eventStack.length){
-var parent=eventStack.peekLast();
-parent.selfTime-=duration;
-if(parent.selfTime<0){
-var epsilon=1e-3;
-if(parent.selfTime<-epsilon)
-console.error("Children are longer than parent at "+event.startTime+" ("+(event.startTime-this.minimumRecordTime()).toFixed(3)+") by "+parent.selfTime.toFixed(3));
-parent.selfTime=0;
-}
-}
-event.selfTime=duration;
-eventStack.push(event);
-return true;
-},
-
-
-
-
-_processBrowserEvent:function(event)
-{
-if(event.name!==WebInspector.TimelineModel.RecordType.LatencyInfoFlow)
-return;
-var frameId=event.args["frameTreeNodeId"];
-if(typeof frameId==="number"&&frameId===this._mainFrameNodeId)
-this._knownInputEvents.add(event.bind_id);
-},
-
-
-
-
-
-_processAsyncEvent:function(asyncEvent)
-{
-var groups=WebInspector.TimelineModel.AsyncEventGroup;
-if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.Console))
-return groups.console;
-if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.UserTiming))
-return groups.userTiming;
-if(asyncEvent.name===WebInspector.TimelineModel.RecordType.Animation)
-return groups.animation;
-if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)||asyncEvent.name===WebInspector.TimelineModel.RecordType.ImplSideFling){
-var lastStep=asyncEvent.steps.peekLast();
-
-if(lastStep.phase!==WebInspector.TracingModel.Phase.AsyncEnd)
-return null;
-var data=lastStep.args["data"];
-asyncEvent.causedFrame=!!(data&&data["INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT"]);
-if(asyncEvent.hasCategory(WebInspector.TimelineModel.Category.LatencyInfo)){
-if(!this._knownInputEvents.has(lastStep.id))
-return null;
-if(asyncEvent.name===WebInspector.TimelineModel.RecordType.InputLatencyMouseMove&&!asyncEvent.causedFrame)
-return null;
-var rendererMain=data["INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT"];
-if(rendererMain){
-var time=rendererMain["time"]/1000;
-asyncEvent.steps[0].timeWaitingForMainThread=time-asyncEvent.steps[0].startTime;
-}
-}
-return groups.input;
-}
-return null;
-},
-
-
-
-
-
-_findAncestorEvent:function(name)
-{
-for(var i=this._eventStack.length-1;i>=0;--i){
-var event=this._eventStack[i];
-if(event.name===name)
-return event;
-}
-return null;
-},
-
-
-
-
-
-_mergeAsyncEvents:function(target,source)
-{
-for(var group of source.keys()){
-var events=target.get(group)||[];
-events=events.mergeOrdered(source.get(group)||[],WebInspector.TracingModel.Event.compareStartAndEndTime);
-target.set(group,events);
-}
-},
-
-reset:function()
-{
-this._virtualThreads=[];
-
-this._mainThreadEvents=[];
-
-this._mainThreadAsyncEventsByGroup=new Map();
-
-this._inspectedTargetEvents=[];
-
-this._records=[];
-
-this._mainThreadTasks=[];
-
-this._gpuEvents=[];
-
-this._eventDividerRecords=[];
-
-this._sessionId=null;
-
-this._mainFrameNodeId=null;
-
-this._cpuProfiles=[];
-
-this._workerIdByThread=new WeakMap();
-this._minimumRecordTime=0;
-this._maximumRecordTime=0;
-},
-
-
-
-
-minimumRecordTime:function()
-{
-return this._minimumRecordTime;
-},
-
-
-
-
-maximumRecordTime:function()
-{
-return this._maximumRecordTime;
-},
-
-
-
-
-inspectedTargetEvents:function()
-{
-return this._inspectedTargetEvents;
-},
-
-
-
-
-mainThreadEvents:function()
-{
-return this._mainThreadEvents;
-},
-
-
-
-
-_setMainThreadEvents:function(events)
-{
-this._mainThreadEvents=events;
-},
-
-
-
-
-mainThreadAsyncEvents:function()
-{
-return this._mainThreadAsyncEventsByGroup;
-},
-
-
-
-
-virtualThreads:function()
-{
-return this._virtualThreads;
-},
-
-
-
-
-isEmpty:function()
-{
-return this.minimumRecordTime()===0&&this.maximumRecordTime()===0;
-},
-
-
-
-
-mainThreadTasks:function()
-{
-return this._mainThreadTasks;
-},
-
-
-
-
-gpuEvents:function()
-{
-return this._gpuEvents;
-},
-
-
-
-
-eventDividerRecords:function()
-{
-return this._eventDividerRecords;
-},
-
-
-
-
-networkRequests:function()
-{
-
-var requests=new Map();
-
-var requestsList=[];
-
-var zeroStartRequestsList=[];
-var types=WebInspector.TimelineModel.RecordType;
-var resourceTypes=new Set([
-types.ResourceSendRequest,
-types.ResourceReceiveResponse,
-types.ResourceReceivedData,
-types.ResourceFinish]);
-
-var events=this.mainThreadEvents();
-for(var i=0;i<events.length;++i){
-var e=events[i];
-if(!resourceTypes.has(e.name))
-continue;
-var id=e.args["data"]["requestId"];
-var request=requests.get(id);
-if(request){
-request.addEvent(e);
-}else{
-request=new WebInspector.TimelineModel.NetworkRequest(e);
-requests.set(id,request);
-if(request.startTime)
-requestsList.push(request);else
-
-zeroStartRequestsList.push(request);
-}
-}
-return zeroStartRequestsList.concat(requestsList);
-}};
-
-
-
-
-
-
-
-WebInspector.TimelineModel.isVisible=function(filters,event)
-{
-for(var i=0;i<filters.length;++i){
-if(!filters[i].accept(event))
-return false;
-}
-return true;
-};
-
-
-
-
-
-WebInspector.TimelineModel.isMarkerEvent=function(event)
-{
-var recordTypes=WebInspector.TimelineModel.RecordType;
-switch(event.name){
-case recordTypes.TimeStamp:
-case recordTypes.MarkFirstPaint:
-return true;
-case recordTypes.MarkDOMContent:
-case recordTypes.MarkLoad:
-return event.args["data"]["isMainFrame"];
-default:
-return false;}
-
-};
-
-
-
-
-
-WebInspector.TimelineModel.NetworkRequest=function(event)
-{
-this.startTime=event.name===WebInspector.TimelineModel.RecordType.ResourceSendRequest?event.startTime:0;
-this.endTime=Infinity;
-
-this.children=[];
-this.addEvent(event);
-};
-
-WebInspector.TimelineModel.NetworkRequest.prototype={
-
-
-
-addEvent:function(event)
-{
-this.children.push(event);
-var recordType=WebInspector.TimelineModel.RecordType;
-this.startTime=Math.min(this.startTime,event.startTime);
-var eventData=event.args["data"];
-if(eventData["mimeType"])
-this.mimeType=eventData["mimeType"];
-if("priority"in eventData)
-this.priority=eventData["priority"];
-if(event.name===recordType.ResourceFinish)
-this.endTime=event.startTime;
-if(!this.responseTime&&(event.name===recordType.ResourceReceiveResponse||event.name===recordType.ResourceReceivedData))
-this.responseTime=event.startTime;
-if(!this.url)
-this.url=eventData["url"];
-if(!this.requestMethod)
-this.requestMethod=eventData["requestMethod"];
-}};
-
-
-
-
-
-WebInspector.TimelineModel.Filter=function()
-{
-};
-
-WebInspector.TimelineModel.Filter.prototype={
-
-
-
-
-accept:function(event)
-{
-return true;
-}};
-
-
-
-
-
-
-
-WebInspector.TimelineVisibleEventsFilter=function(visibleTypes)
-{
-WebInspector.TimelineModel.Filter.call(this);
-this._visibleTypes=new Set(visibleTypes);
-};
-
-WebInspector.TimelineVisibleEventsFilter.prototype={
-
-
-
-
-
-accept:function(event)
-{
-return this._visibleTypes.has(WebInspector.TimelineModel._eventType(event));
-},
-
-__proto__:WebInspector.TimelineModel.Filter.prototype};
-
-
-
-
-
-
-
-WebInspector.ExclusiveNameFilter=function(excludeNames)
-{
-WebInspector.TimelineModel.Filter.call(this);
-this._excludeNames=new Set(excludeNames);
-};
-
-WebInspector.ExclusiveNameFilter.prototype={
-
-
-
-
-
-accept:function(event)
-{
-return!this._excludeNames.has(event.name);
-},
-
-__proto__:WebInspector.TimelineModel.Filter.prototype};
-
-
-
-
-
-
-WebInspector.ExcludeTopLevelFilter=function()
-{
-WebInspector.TimelineModel.Filter.call(this);
-};
-
-WebInspector.ExcludeTopLevelFilter.prototype={
-
-
-
-
-
-accept:function(event)
-{
-return!WebInspector.TracingModel.isTopLevelEvent(event);
-},
-
-__proto__:WebInspector.TimelineModel.Filter.prototype};
-
-
-
-
-
-
-WebInspector.InvalidationTrackingEvent=function(event)
-{
-
-this.type=event.name;
-
-this.startTime=event.startTime;
-
-this._tracingEvent=event;
-
-var eventData=event.args["data"];
-
-
-this.frame=eventData["frame"];
-
-this.nodeId=eventData["nodeId"];
-
-this.nodeName=eventData["nodeName"];
-
-this.paintId=eventData["paintId"];
-
-this.invalidationSet=eventData["invalidationSet"];
-
-this.invalidatedSelectorId=eventData["invalidatedSelectorId"];
-
-this.changedId=eventData["changedId"];
-
-this.changedClass=eventData["changedClass"];
-
-this.changedAttribute=eventData["changedAttribute"];
-
-this.changedPseudo=eventData["changedPseudo"];
-
-this.selectorPart=eventData["selectorPart"];
-
-this.extraData=eventData["extraData"];
-
-this.invalidationList=eventData["invalidationList"];
-
-this.cause={reason:eventData["reason"],stackTrace:eventData["stackTrace"]};
-
-
-if(!this.cause.reason&&this.cause.stackTrace&&this.type===WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking)
-this.cause.reason="Layout forced";
-};
-
-
-WebInspector.InvalidationCause;
-
-
-
-
-WebInspector.InvalidationTracker=function()
-{
-this._initializePerFrameState();
-};
-
-WebInspector.InvalidationTracker.prototype={
-
-
-
-addInvalidation:function(invalidation)
-{
-this._startNewFrameIfNeeded();
-
-if(!invalidation.nodeId&&!invalidation.paintId){
-console.error("Invalidation lacks node information.");
-console.error(invalidation);
-return;
-}
-
-
-
-
-var recordTypes=WebInspector.TimelineModel.RecordType;
-if(invalidation.type===recordTypes.PaintInvalidationTracking&&invalidation.nodeId){
-var invalidations=this._invalidationsByNodeId[invalidation.nodeId]||[];
-for(var i=0;i<invalidations.length;++i)
-invalidations[i].paintId=invalidation.paintId;
-
-
-return;
-}
-
-
-
-
-if(invalidation.type===recordTypes.StyleRecalcInvalidationTracking&&invalidation.cause.reason==="StyleInvalidator")
-return;
-
-
-
-
-var styleRecalcInvalidation=invalidation.type===recordTypes.ScheduleStyleInvalidationTracking||
-invalidation.type===recordTypes.StyleInvalidatorInvalidationTracking||
-invalidation.type===recordTypes.StyleRecalcInvalidationTracking;
-if(styleRecalcInvalidation){
-var duringRecalcStyle=invalidation.startTime&&this._lastRecalcStyle&&
-invalidation.startTime>=this._lastRecalcStyle.startTime&&
-invalidation.startTime<=this._lastRecalcStyle.endTime;
-if(duringRecalcStyle)
-this._associateWithLastRecalcStyleEvent(invalidation);
-}
-
-
-if(this._invalidations[invalidation.type])
-this._invalidations[invalidation.type].push(invalidation);else
-
-this._invalidations[invalidation.type]=[invalidation];
-if(invalidation.nodeId){
-if(this._invalidationsByNodeId[invalidation.nodeId])
-this._invalidationsByNodeId[invalidation.nodeId].push(invalidation);else
-
-this._invalidationsByNodeId[invalidation.nodeId]=[invalidation];
-}
-},
-
-
-
-
-didRecalcStyle:function(recalcStyleEvent)
-{
-this._lastRecalcStyle=recalcStyleEvent;
-var types=[WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking,
-WebInspector.TimelineModel.RecordType.StyleInvalidatorInvalidationTracking,
-WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking];
-for(var invalidation of this._invalidationsOfTypes(types))
-this._associateWithLastRecalcStyleEvent(invalidation);
-},
-
-
-
-
-_associateWithLastRecalcStyleEvent:function(invalidation)
-{
-if(invalidation.linkedRecalcStyleEvent)
-return;
-
-var recordTypes=WebInspector.TimelineModel.RecordType;
-var recalcStyleFrameId=this._lastRecalcStyle.args["beginData"]["frame"];
-if(invalidation.type===recordTypes.StyleInvalidatorInvalidationTracking){
-
-
-this._addSyntheticStyleRecalcInvalidations(this._lastRecalcStyle,recalcStyleFrameId,invalidation);
-}else if(invalidation.type===recordTypes.ScheduleStyleInvalidationTracking){
-
-
-}else{
-this._addInvalidationToEvent(this._lastRecalcStyle,recalcStyleFrameId,invalidation);
-}
-
-invalidation.linkedRecalcStyleEvent=true;
-},
-
-
-
-
-
-
-_addSyntheticStyleRecalcInvalidations:function(event,frameId,styleInvalidatorInvalidation)
-{
-if(!styleInvalidatorInvalidation.invalidationList){
-this._addSyntheticStyleRecalcInvalidation(styleInvalidatorInvalidation._tracingEvent,styleInvalidatorInvalidation);
-return;
-}
-if(!styleInvalidatorInvalidation.nodeId){
-console.error("Invalidation lacks node information.");
-console.error(invalidation);
-return;
-}
-for(var i=0;i<styleInvalidatorInvalidation.invalidationList.length;i++){
-var setId=styleInvalidatorInvalidation.invalidationList[i]["id"];
-var lastScheduleStyleRecalculation;
-var nodeInvalidations=this._invalidationsByNodeId[styleInvalidatorInvalidation.nodeId]||[];
-for(var j=0;j<nodeInvalidations.length;j++){
-var invalidation=nodeInvalidations[j];
-if(invalidation.frame!==frameId||invalidation.invalidationSet!==setId||invalidation.type!==WebInspector.TimelineModel.RecordType.ScheduleStyleInvalidationTracking)
-continue;
-lastScheduleStyleRecalculation=invalidation;
-}
-if(!lastScheduleStyleRecalculation){
-console.error("Failed to lookup the event that scheduled a style invalidator invalidation.");
-continue;
-}
-this._addSyntheticStyleRecalcInvalidation(lastScheduleStyleRecalculation._tracingEvent,styleInvalidatorInvalidation);
-}
-},
-
-
-
-
-
-_addSyntheticStyleRecalcInvalidation:function(baseEvent,styleInvalidatorInvalidation)
-{
-var invalidation=new WebInspector.InvalidationTrackingEvent(baseEvent);
-invalidation.type=WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking;
-invalidation.synthetic=true;
-if(styleInvalidatorInvalidation.cause.reason)
-invalidation.cause.reason=styleInvalidatorInvalidation.cause.reason;
-if(styleInvalidatorInvalidation.selectorPart)
-invalidation.selectorPart=styleInvalidatorInvalidation.selectorPart;
-
-this.addInvalidation(invalidation);
-if(!invalidation.linkedRecalcStyleEvent)
-this._associateWithLastRecalcStyleEvent(invalidation);
-},
-
-
-
-
-didLayout:function(layoutEvent)
-{
-var layoutFrameId=layoutEvent.args["beginData"]["frame"];
-for(var invalidation of this._invalidationsOfTypes([WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking])){
-if(invalidation.linkedLayoutEvent)
-continue;
-this._addInvalidationToEvent(layoutEvent,layoutFrameId,invalidation);
-invalidation.linkedLayoutEvent=true;
-}
-},
-
-
-
-
-didPaint:function(paintEvent)
-{
-this._didPaint=true;
-
-
-
-var layerId=paintEvent.args["data"]["layerId"];
-if(layerId)
-this._lastPaintWithLayer=paintEvent;
-
-
-if(!this._lastPaintWithLayer)
-return;
-
-var effectivePaintId=this._lastPaintWithLayer.args["data"]["nodeId"];
-var paintFrameId=paintEvent.args["data"]["frame"];
-var types=[WebInspector.TimelineModel.RecordType.StyleRecalcInvalidationTracking,
-WebInspector.TimelineModel.RecordType.LayoutInvalidationTracking,
-WebInspector.TimelineModel.RecordType.PaintInvalidationTracking,
-WebInspector.TimelineModel.RecordType.ScrollInvalidationTracking];
-for(var invalidation of this._invalidationsOfTypes(types)){
-if(invalidation.paintId===effectivePaintId)
-this._addInvalidationToEvent(paintEvent,paintFrameId,invalidation);
-}
-},
-
-
-
-
-
-
-_addInvalidationToEvent:function(event,eventFrameId,invalidation)
-{
-if(eventFrameId!==invalidation.frame)
-return;
-if(!event.invalidationTrackingEvents)
-event.invalidationTrackingEvents=[invalidation];else
-
-event.invalidationTrackingEvents.push(invalidation);
-},
-
-
-
-
-
-_invalidationsOfTypes:function(types)
-{
-var invalidations=this._invalidations;
-if(!types)
-types=Object.keys(invalidations);
-function*generator()
-{
-for(var i=0;i<types.length;++i){
-var invalidationList=invalidations[types[i]]||[];
-for(var j=0;j<invalidationList.length;++j)
-yield invalidationList[j];
-}
-}
-return generator();
-},
-
-_startNewFrameIfNeeded:function()
-{
-if(!this._didPaint)
-return;
-
-this._initializePerFrameState();
-},
-
-_initializePerFrameState:function()
-{
-
-this._invalidations={};
-
-this._invalidationsByNodeId={};
-
-this._lastRecalcStyle=undefined;
-this._lastPaintWithLayer=undefined;
-this._didPaint=false;
-}};
-
-
-
-
-
-WebInspector.TimelineAsyncEventTracker=function()
-{
-WebInspector.TimelineAsyncEventTracker._initialize();
-
-this._initiatorByType=new Map();
-for(var initiator of WebInspector.TimelineAsyncEventTracker._asyncEvents.keys())
-this._initiatorByType.set(initiator,new Map());
-};
-
-WebInspector.TimelineAsyncEventTracker._initialize=function()
-{
-if(WebInspector.TimelineAsyncEventTracker._asyncEvents)
-return;
-var events=new Map();
-var type=WebInspector.TimelineModel.RecordType;
-
-events.set(type.TimerInstall,{causes:[type.TimerFire],joinBy:"timerId"});
-events.set(type.ResourceSendRequest,{causes:[type.ResourceReceiveResponse,type.ResourceReceivedData,type.ResourceFinish],joinBy:"requestId"});
-events.set(type.RequestAnimationFrame,{causes:[type.FireAnimationFrame],joinBy:"id"});
-events.set(type.RequestIdleCallback,{causes:[type.FireIdleCallback],joinBy:"id"});
-events.set(type.WebSocketCreate,{causes:[type.WebSocketSendHandshakeRequest,type.WebSocketReceiveHandshakeResponse,type.WebSocketDestroy],joinBy:"identifier"});
-
-WebInspector.TimelineAsyncEventTracker._asyncEvents=events;
-
-WebInspector.TimelineAsyncEventTracker._typeToInitiator=new Map();
-for(var entry of events){
-var types=entry[1].causes;
-for(type of types)
-WebInspector.TimelineAsyncEventTracker._typeToInitiator.set(type,entry[0]);
-}
-};
-
-WebInspector.TimelineAsyncEventTracker.prototype={
-
-
-
-processEvent:function(event)
-{
-var initiatorType=WebInspector.TimelineAsyncEventTracker._typeToInitiator.get(event.name);
-var isInitiator=!initiatorType;
-if(!initiatorType)
-initiatorType=event.name;
-var initiatorInfo=WebInspector.TimelineAsyncEventTracker._asyncEvents.get(initiatorType);
-if(!initiatorInfo)
-return;
-var id=event.args["data"][initiatorInfo.joinBy];
-if(!id)
-return;
-
-var initiatorMap=this._initiatorByType.get(initiatorType);
-if(isInitiator)
-initiatorMap.set(id,event);else
-
-event.initiator=initiatorMap.get(id)||null;
-}};
-
-
-},{}],125:[function(require,module,exports){
-
-
-
-
-WebInspector.TimelineProfileTree={};
-
-
-
-
-WebInspector.TimelineProfileTree.Node=function()
-{
-
-this.totalTime;
-
-this.selfTime;
-
-this.id;
-
-this.event;
-
-this.children;
-
-this.parent;
-this._isGroupNode=false;
-};
-
-WebInspector.TimelineProfileTree.Node.prototype={
-
-
-
-isGroupNode:function()
-{
-return this._isGroupNode;
-}};
-
-
-
-
-
-
-
-
-
-
-WebInspector.TimelineProfileTree.buildTopDown=function(events,filters,startTime,endTime,eventIdCallback)
-{
-
-var initialTime=1e7;
-var root=new WebInspector.TimelineProfileTree.Node();
-root.totalTime=initialTime;
-root.selfTime=initialTime;
-root.children=new Map();
-var parent=root;
-
-
-
-
-function onStartEvent(e)
-{
-if(!WebInspector.TimelineModel.isVisible(filters,e))
-return;
-var time=e.endTime?Math.min(endTime,e.endTime)-Math.max(startTime,e.startTime):0;
-var id=eventIdCallback?eventIdCallback(e):Symbol("uniqueEventId");
-if(!parent.children)
-parent.children=new Map();
-var node=parent.children.get(id);
-if(node){
-node.selfTime+=time;
-node.totalTime+=time;
-}else{
-node=new WebInspector.TimelineProfileTree.Node();
-node.totalTime=time;
-node.selfTime=time;
-node.parent=parent;
-node.id=id;
-node.event=e;
-parent.children.set(id,node);
-}
-parent.selfTime-=time;
-if(parent.selfTime<0){
-console.log("Error: Negative self of "+parent.selfTime,e);
-parent.selfTime=0;
-}
-if(e.endTime)
-parent=node;
-}
-
-
-
-
-function onEndEvent(e)
-{
-if(!WebInspector.TimelineModel.isVisible(filters,e))
-return;
-parent=parent.parent;
-}
-
-var instantEventCallback=eventIdCallback?undefined:onStartEvent;
-WebInspector.TimelineModel.forEachEvent(events,onStartEvent,onEndEvent,instantEventCallback,startTime,endTime);
-root.totalTime-=root.selfTime;
-root.selfTime=0;
-return root;
-};
-
-
-
-
-
-
-WebInspector.TimelineProfileTree.buildBottomUp=function(topDownTree,groupingCallback)
-{
-var buRoot=new WebInspector.TimelineProfileTree.Node();
-buRoot.selfTime=0;
-buRoot.totalTime=0;
-
-buRoot.children=new Map();
-var nodesOnStack=new Set();
-if(topDownTree.children)
-topDownTree.children.forEach(processNode);
-buRoot.totalTime=topDownTree.totalTime;
-
-
-
-
-function processNode(tdNode)
-{
-var buParent=groupingCallback&&groupingCallback(tdNode)||buRoot;
-if(buParent!==buRoot){
-buRoot.children.set(buParent.id,buParent);
-buParent.parent=buRoot;
-}
-appendNode(tdNode,buParent);
-var hadNode=nodesOnStack.has(tdNode.id);
-if(!hadNode)
-nodesOnStack.add(tdNode.id);
-if(tdNode.children)
-tdNode.children.forEach(processNode);
-if(!hadNode)
-nodesOnStack.delete(tdNode.id);
-}
-
-
-
-
-
-function appendNode(tdNode,buParent)
-{
-var selfTime=tdNode.selfTime;
-var totalTime=tdNode.totalTime;
-buParent.selfTime+=selfTime;
-buParent.totalTime+=selfTime;
-while(tdNode.parent){
-if(!buParent.children)
-buParent.children=new Map();
-var id=tdNode.id;
-var buNode=buParent.children.get(id);
-if(!buNode){
-buNode=new WebInspector.TimelineProfileTree.Node();
-buNode.selfTime=selfTime;
-buNode.totalTime=totalTime;
-buNode.event=tdNode.event;
-buNode.id=id;
-buNode.parent=buParent;
-buParent.children.set(id,buNode);
-}else{
-buNode.selfTime+=selfTime;
-if(!nodesOnStack.has(id))
-buNode.totalTime+=totalTime;
-}
-tdNode=tdNode.parent;
-buParent=buNode;
-}
-}
-
-
-var rootChildren=buRoot.children;
-for(var item of rootChildren.entries()){
-if(item[1].selfTime===0)
-rootChildren.delete(item[0]);
-}
-
-return buRoot;
-};
-
-
-
-
-
-WebInspector.TimelineProfileTree.eventURL=function(event)
-{
-var data=event.args["data"]||event.args["beginData"];
-if(data&&data["url"])
-return data["url"];
-var frame=WebInspector.TimelineProfileTree.eventStackFrame(event);
-while(frame){
-var url=frame["url"];
-if(url)
-return url;
-frame=frame.parent;
-}
-return null;
-};
-
-
-
-
-
-WebInspector.TimelineProfileTree.eventStackFrame=function(event)
-{
-if(event.name===WebInspector.TimelineModel.RecordType.JSFrame)
-return event.args["data"]||null;
-var topFrame=event.stackTrace&&event.stackTrace[0];
-if(topFrame)
-return topFrame;
-var initiator=event.initiator;
-return initiator&&initiator.stackTrace&&initiator.stackTrace[0]||null;
-};
-
-
-
-
-
-
-WebInspector.TimelineAggregator=function(titleMapper,categoryMapper)
-{
-this._titleMapper=titleMapper;
-this._categoryMapper=categoryMapper;
-
-this._groupNodes=new Map();
-};
-
-
-
-
-WebInspector.TimelineAggregator.GroupBy={
-None:"None",
-EventName:"EventName",
-Category:"Category",
-Domain:"Domain",
-Subdomain:"Subdomain",
-URL:"URL"};
-
-
-
-
-
-
-WebInspector.TimelineAggregator.eventId=function(event)
-{
-if(event.name===WebInspector.TimelineModel.RecordType.JSFrame){
-var data=event.args["data"];
-return"f:"+data["functionName"]+"@"+(data["scriptId"]||data["url"]||"");
-}
-return event.name+":@"+WebInspector.TimelineProfileTree.eventURL(event);
-};
-
-WebInspector.TimelineAggregator._extensionInternalPrefix="extensions::";
-WebInspector.TimelineAggregator._groupNodeFlag=Symbol("groupNode");
-
-
-
-
-
-WebInspector.TimelineAggregator.isExtensionInternalURL=function(url)
-{
-return url.startsWith(WebInspector.TimelineAggregator._extensionInternalPrefix);
-};
-
-WebInspector.TimelineAggregator.prototype={
-
-
-
-
-groupFunction:function(groupBy)
-{
-var idMapper=this._nodeToGroupIdFunction(groupBy);
-return idMapper&&this._nodeToGroupNode.bind(this,idMapper);
-},
-
-
-
-
-
-
-performGrouping:function(root,groupBy)
-{
-var nodeMapper=this.groupFunction(groupBy);
-if(!nodeMapper)
-return root;
-for(var node of root.children.values()){
-var groupNode=nodeMapper(node);
-groupNode.parent=root;
-groupNode.selfTime+=node.selfTime;
-groupNode.totalTime+=node.totalTime;
-groupNode.children.set(node.id,node);
-node.parent=root;
-}
-root.children=this._groupNodes;
-return root;
-},
-
-
-
-
-
-_nodeToGroupIdFunction:function(groupBy)
-{
-
-
-
-
-function groupByURL(node)
-{
-return WebInspector.TimelineProfileTree.eventURL(node.event)||"";
-}
-
-
-
-
-
-
-function groupByDomain(groupSubdomains,node)
-{
-var url=WebInspector.TimelineProfileTree.eventURL(node.event)||"";
-if(WebInspector.TimelineAggregator.isExtensionInternalURL(url))
-return WebInspector.TimelineAggregator._extensionInternalPrefix;
-var parsedURL=url.asParsedURL();
-if(!parsedURL)
-return"";
-if(parsedURL.scheme==="chrome-extension")
-return parsedURL.scheme+"://"+parsedURL.host;
-if(!groupSubdomains)
-return parsedURL.host;
-if(/^[.0-9]+$/.test(parsedURL.host))
-return parsedURL.host;
-var domainMatch=/([^.]*\.)?[^.]*$/.exec(parsedURL.host);
-return domainMatch&&domainMatch[0]||"";
-}
-
-switch(groupBy){
-case WebInspector.TimelineAggregator.GroupBy.None:return null;
-case WebInspector.TimelineAggregator.GroupBy.EventName:return node=>node.event?this._titleMapper(node.event):"";
-case WebInspector.TimelineAggregator.GroupBy.Category:return node=>node.event?this._categoryMapper(node.event):"";
-case WebInspector.TimelineAggregator.GroupBy.Subdomain:return groupByDomain.bind(null,false);
-case WebInspector.TimelineAggregator.GroupBy.Domain:return groupByDomain.bind(null,true);
-case WebInspector.TimelineAggregator.GroupBy.URL:return groupByURL;
-default:return null;}
-
-},
-
-
-
-
-
-
-_buildGroupNode:function(id,event)
-{
-var groupNode=new WebInspector.TimelineProfileTree.Node();
-groupNode.id=id;
-groupNode.selfTime=0;
-groupNode.totalTime=0;
-groupNode.children=new Map();
-groupNode.event=event;
-groupNode._isGroupNode=true;
-this._groupNodes.set(id,groupNode);
-return groupNode;
-},
-
-
-
-
-
-
-_nodeToGroupNode:function(nodeToGroupId,node)
-{
-var id=nodeToGroupId(node);
-return this._groupNodes.get(id)||this._buildGroupNode(id,node.event);
-}};
-
-
-},{}],126:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-WebInspector.SortableDataGrid=function(columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback)
-{
-WebInspector.ViewportDataGrid.call(this,columnsArray,editCallback,deleteCallback,refreshCallback,contextMenuCallback);
-
-this._sortingFunction=WebInspector.SortableDataGrid.TrivialComparator;
-this.setRootNode(new WebInspector.SortableDataGridNode());
-};
-
-
-WebInspector.SortableDataGrid.NodeComparator;
-
-
-
-
-
-
-WebInspector.SortableDataGrid.TrivialComparator=function(a,b)
-{
-return 0;
-};
-
-
-
-
-
-
-
-WebInspector.SortableDataGrid.NumericComparator=function(columnIdentifier,a,b)
-{
-var aValue=a.data[columnIdentifier];
-var bValue=b.data[columnIdentifier];
-var aNumber=Number(aValue instanceof Node?aValue.textContent:aValue);
-var bNumber=Number(bValue instanceof Node?bValue.textContent:bValue);
-return aNumber<bNumber?-1:aNumber>bNumber?1:0;
-};
-
-
-
-
-
-
-
-WebInspector.SortableDataGrid.StringComparator=function(columnIdentifier,a,b)
-{
-var aValue=a.data[columnIdentifier];
-var bValue=b.data[columnIdentifier];
-var aString=aValue instanceof Node?aValue.textContent:String(aValue);
-var bString=bValue instanceof Node?bValue.textContent:String(bValue);
-return aString<bString?-1:aString>bString?1:0;
-};
-
-
-
-
-
-
-
-
-WebInspector.SortableDataGrid.Comparator=function(comparator,reverseMode,a,b)
-{
-return reverseMode?comparator(b,a):comparator(a,b);
-};
-
-
-
-
-
-
-WebInspector.SortableDataGrid.create=function(columnNames,values)
-{
-var numColumns=columnNames.length;
-if(!numColumns)
-return null;
-
-var columns=[];
-for(var i=0;i<columnNames.length;++i)
-columns.push({title:columnNames[i],width:columnNames[i].length,sortable:true});
-
-var nodes=[];
-for(var i=0;i<values.length/numColumns;++i){
-var data={};
-for(var j=0;j<columnNames.length;++j)
-data[j]=values[numColumns*i+j];
-
-var node=new WebInspector.SortableDataGridNode(data);
-node.selectable=false;
-nodes.push(node);
-}
-
-var dataGrid=new WebInspector.SortableDataGrid(columns);
-var length=nodes.length;
-var rootNode=dataGrid.rootNode();
-for(var i=0;i<length;++i)
-rootNode.appendChild(nodes[i]);
-
-dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,sortDataGrid);
-
-function sortDataGrid()
-{
-var nodes=dataGrid.rootNode().children;
-var sortColumnIdentifier=dataGrid.sortColumnIdentifier();
-if(!sortColumnIdentifier)
-return;
-
-var columnIsNumeric=true;
-for(var i=0;i<nodes.length;i++){
-var value=nodes[i].data[sortColumnIdentifier];
-if(isNaN(value instanceof Node?value.textContent:value)){
-columnIsNumeric=false;
-break;
-}
-}
-
-var comparator=columnIsNumeric?WebInspector.SortableDataGrid.NumericComparator:WebInspector.SortableDataGrid.StringComparator;
-dataGrid.sortNodes(comparator.bind(null,sortColumnIdentifier),!dataGrid.isSortOrderAscending());
-}
-return dataGrid;
-};
-
-WebInspector.SortableDataGrid.prototype={
-
-
-
-insertChild:function(node)
-{
-var root=this.rootNode();
-root.insertChildOrdered(node);
-},
-
-
-
-
-
-sortNodes:function(comparator,reverseMode)
-{
-this._sortingFunction=WebInspector.SortableDataGrid.Comparator.bind(null,comparator,reverseMode);
-this._rootNode._sortChildren(reverseMode);
-this.scheduleUpdateStructure();
-},
-
-__proto__:WebInspector.ViewportDataGrid.prototype};
-
-
-
-
-
-
-
-
-WebInspector.SortableDataGridNode=function(data,hasChildren)
-{
-WebInspector.ViewportDataGridNode.call(this,data,hasChildren);
-};
-
-WebInspector.SortableDataGridNode.prototype={
-
-
-
-insertChildOrdered:function(node)
-{
-this.insertChild(node,this.children.upperBound(node,this.dataGrid._sortingFunction));
-},
-
-_sortChildren:function()
-{
-this.children.sort(this.dataGrid._sortingFunction);
-for(var i=0;i<this.children.length;++i)
-this.children[i].recalculateSiblings(i);
-for(var child of this.children)
-child._sortChildren();
-},
-
-__proto__:WebInspector.ViewportDataGridNode.prototype};
-
-
-},{}],127:[function(require,module,exports){
-(function(process){
-
-
-
-
-
-
-exports=module.exports=require('./debug');
-exports.log=log;
-exports.formatArgs=formatArgs;
-exports.save=save;
-exports.load=load;
-exports.useColors=useColors;
-exports.storage='undefined'!=typeof chrome&&
-'undefined'!=typeof chrome.storage?
-chrome.storage.local:
-localstorage();
-
-
-
-
-
-exports.colors=[
-'lightseagreen',
-'forestgreen',
-'goldenrod',
-'dodgerblue',
-'darkorchid',
-'crimson'];
-
-
-
-
-
-
-
-
-
-
-function useColors(){
-
-
-
-if(typeof window!=='undefined'&&window.process&&window.process.type==='renderer'){
-return true;
-}
-
-
-
-return typeof document!=='undefined'&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||
-
-typeof window!=='undefined'&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||
-
-
-typeof navigator!=='undefined'&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||
-
-typeof navigator!=='undefined'&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
-}
-
-
-
-
-
-exports.formatters.j=function(v){
-try{
-return JSON.stringify(v);
-}catch(err){
-return'[UnexpectedJSONParseError]: '+err.message;
-}
-};
-
-
-
-
-
-
-
-
-function formatArgs(args){
-var useColors=this.useColors;
-
-args[0]=(useColors?'%c':'')+
-this.namespace+(
-useColors?' %c':' ')+
-args[0]+(
-useColors?'%c ':' ')+
-'+'+exports.humanize(this.diff);
-
-if(!useColors)return;
-
-var c='color: '+this.color;
-args.splice(1,0,c,'color: inherit');
-
-
-
-
-var index=0;
-var lastC=0;
-args[0].replace(/%[a-zA-Z%]/g,function(match){
-if('%%'===match)return;
-index++;
-if('%c'===match){
-
-
-lastC=index;
-}
-});
-
-args.splice(lastC,0,c);
-}
-
-
-
-
-
-
-
-
-function log(){
-
-
-return'object'===typeof console&&
-console.log&&
-Function.prototype.apply.call(console.log,console,arguments);
-}
-
-
-
-
-
-
-
-
-function save(namespaces){
-try{
-if(null==namespaces){
-exports.storage.removeItem('debug');
-}else{
-exports.storage.debug=namespaces;
-}
-}catch(e){}
-}
-
-
-
-
-
-
-
-
-function load(){
-var r;
-try{
-r=exports.storage.debug;
-}catch(e){}
-
-
-if(!r&&typeof process!=='undefined'&&'env'in process){
-r=process.env.DEBUG;
-}
-
-return r;
-}
-
-
-
-
-
-exports.enable(load());
-
-
-
-
-
-
-
-
-
-
-
-
-function localstorage(){
-try{
-return window.localStorage;
-}catch(e){}
-}
-
-}).call(this,require('_process'));
-},{"./debug":128,"_process":71}],128:[function(require,module,exports){
-
-
-
-
-
-
-
-
-exports=module.exports=createDebug.debug=createDebug['default']=createDebug;
-exports.coerce=coerce;
-exports.disable=disable;
-exports.enable=enable;
-exports.enabled=enabled;
-exports.humanize=require('ms');
-
-
-
-
-
-exports.names=[];
-exports.skips=[];
-
-
-
-
-
-
-
-exports.formatters={};
-
-
-
-
-
-var prevTime;
-
-
-
-
-
-
-
-
-function selectColor(namespace){
-var hash=0,i;
-
-for(i in namespace){
-hash=(hash<<5)-hash+namespace.charCodeAt(i);
-hash|=0;
-}
-
-return exports.colors[Math.abs(hash)%exports.colors.length];
-}
-
-
-
-
-
-
-
-
-
-function createDebug(namespace){
-
-function debug(){
-
-if(!debug.enabled)return;
-
-var self=debug;
-
-
-var curr=+new Date();
-var ms=curr-(prevTime||curr);
-self.diff=ms;
-self.prev=prevTime;
-self.curr=curr;
-prevTime=curr;
-
-
-var args=new Array(arguments.length);
-for(var i=0;i<args.length;i++){
-args[i]=arguments[i];
-}
-
-args[0]=exports.coerce(args[0]);
-
-if('string'!==typeof args[0]){
-
-args.unshift('%O');
-}
-
-
-var index=0;
-args[0]=args[0].replace(/%([a-zA-Z%])/g,function(match,format){
-
-if(match==='%%')return match;
-index++;
-var formatter=exports.formatters[format];
-if('function'===typeof formatter){
-var val=args[index];
-match=formatter.call(self,val);
-
-
-args.splice(index,1);
-index--;
-}
-return match;
-});
-
-
-exports.formatArgs.call(self,args);
-
-var logFn=debug.log||exports.log||console.log.bind(console);
-logFn.apply(self,args);
-}
-
-debug.namespace=namespace;
-debug.enabled=exports.enabled(namespace);
-debug.useColors=exports.useColors();
-debug.color=selectColor(namespace);
-
-
-if('function'===typeof exports.init){
-exports.init(debug);
-}
-
-return debug;
-}
-
-
-
-
-
-
-
-
-
-function enable(namespaces){
-exports.save(namespaces);
-
-exports.names=[];
-exports.skips=[];
-
-var split=(typeof namespaces==='string'?namespaces:'').split(/[\s,]+/);
-var len=split.length;
-
-for(var i=0;i<len;i++){
-if(!split[i])continue;
-namespaces=split[i].replace(/\*/g,'.*?');
-if(namespaces[0]==='-'){
-exports.skips.push(new RegExp('^'+namespaces.substr(1)+'$'));
-}else{
-exports.names.push(new RegExp('^'+namespaces+'$'));
-}
-}
-}
-
-
-
-
-
-
-
-function disable(){
-exports.enable('');
-}
-
-
-
-
-
-
-
-
-
-function enabled(name){
-var i,len;
-for(i=0,len=exports.skips.length;i<len;i++){
-if(exports.skips[i].test(name)){
-return false;
-}
-}
-for(i=0,len=exports.names.length;i<len;i++){
-if(exports.names[i].test(name)){
-return true;
-}
-}
-return false;
-}
-
-
-
-
-
-
-
-
-
-function coerce(val){
-if(val instanceof Error)return val.stack||val.message;
-return val;
-}
-
-},{"ms":140}],129:[function(require,module,exports){
-
-
-
-
-module.exports=function(WebInspector){
-
-function TimelineModelTreeView(model){
-this._rootNode=model;
-}
-
-TimelineModelTreeView.prototype.sortingChanged=function(sortItem,sortOrder){
-if(!sortItem)
-return;
-var sortFunction;
-switch(sortItem){
-case'startTime':
-sortFunction=compareStartTime;
-break;
-case'self':
-sortFunction=compareNumericField.bind(null,'selfTime');
-break;
-case'total':
-sortFunction=compareNumericField.bind(null,'totalTime');
-break;
-case'activity':
-sortFunction=compareName;
-break;
-default:
-console.assert(false,'Unknown sort field: '+sortItem);
-return;}
-
-return this.sortNodes(sortFunction,sortOrder!=='asc');
-
-function compareNumericField(field,a,b){
-var nodeA=a[1];
-var nodeB=b[1];
-return nodeA[field]-nodeB[field];
-}
-
-function compareStartTime(a,b){
-var nodeA=a[1];
-var nodeB=b[1];
-return nodeA.event.startTime-nodeB.event.startTime;
-}
-
-function compareName(a,b){
-var nodeA=a[1];
-var nodeB=b[1];
-var nameA=WebInspector.TimelineTreeView.eventNameForSorting(nodeA.event);
-var nameB=WebInspector.TimelineTreeView.eventNameForSorting(nodeB.event);
-return nameA.localeCompare(nameB);
-}
-};
-
-TimelineModelTreeView.prototype.sortNodes=function(comparator,reverseMode){
-this._sortingFunction=WebInspector.SortableDataGrid.Comparator.bind(null,comparator,reverseMode);
-sortChildren(this._rootNode,this._sortingFunction,reverseMode);
-};
-
-
-
-
-
-
-function sortChildren(parent,sortingFunction){
-if(!parent.children)return;
-parent.children=new Map([...parent.children.entries()].sort(sortingFunction));
-for(var i=0;i<parent.children.length;++i)
-recalculateSiblings(parent.children[i],i);
-for(var child of parent.children.values())
-sortChildren(child,sortingFunction);
-}
-
-
-
-
-
-function recalculateSiblings(node,myIndex){
-if(!node.parent)
-return;
-
-var previousChild=node.parent.children[myIndex-1]||null;
-if(previousChild)
-previousChild.nextSibling=node;
-node.previousSibling=previousChild;
-
-var nextChild=node.parent.children[myIndex+1]||null;
-if(nextChild)
-nextChild.previousSibling=node;
-node.nextSibling=nextChild;
-}
-
-return TimelineModelTreeView;
-
-};
-
-},{}],130:[function(require,module,exports){
-(function webpackUniversalModuleDefinition(root,factory){
-
-if(typeof exports==='object'&&typeof module==='object')
-module.exports=factory();else
-if(typeof define==='function'&&define.amd)
-define([],factory);else
-
-if(typeof exports==='object')
-exports["esprima"]=factory();else
-
-root["esprima"]=factory();
-})(this,function(){
-return function(modules){
-
-var installedModules={};
-
-
-function __webpack_require__(moduleId){
-
-
-
-if(installedModules[moduleId])
-return installedModules[moduleId].exports;
-
-
-var module=installedModules[moduleId]={
-exports:{},
-id:moduleId,
-loaded:false};
-
-
-
-modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);
-
-
-module.loaded=true;
-
-
-return module.exports;
-}
-
-
-
-__webpack_require__.m=modules;
-
-
-__webpack_require__.c=installedModules;
-
-
-__webpack_require__.p="";
-
-
-return __webpack_require__(0);
-}(
-
-[
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Object.defineProperty(exports,"__esModule",{value:true});
-var comment_handler_1=__webpack_require__(1);
-var jsx_parser_1=__webpack_require__(3);
-var parser_1=__webpack_require__(8);
-var tokenizer_1=__webpack_require__(15);
-function parse(code,options,delegate){
-var commentHandler=null;
-var proxyDelegate=function(node,metadata){
-if(delegate){
-delegate(node,metadata);
-}
-if(commentHandler){
-commentHandler.visit(node,metadata);
-}
-};
-var parserDelegate=typeof delegate==='function'?proxyDelegate:null;
-var collectComment=false;
-if(options){
-collectComment=typeof options.comment==='boolean'&&options.comment;
-var attachComment=typeof options.attachComment==='boolean'&&options.attachComment;
-if(collectComment||attachComment){
-commentHandler=new comment_handler_1.CommentHandler();
-commentHandler.attach=attachComment;
-options.comment=true;
-parserDelegate=proxyDelegate;
-}
-}
-var isModule=false;
-if(options&&typeof options.sourceType==='string'){
-isModule=options.sourceType==='module';
-}
-var parser;
-if(options&&typeof options.jsx==='boolean'&&options.jsx){
-parser=new jsx_parser_1.JSXParser(code,options,parserDelegate);
-}else
-{
-parser=new parser_1.Parser(code,options,parserDelegate);
-}
-var program=isModule?parser.parseModule():parser.parseScript();
-var ast=program;
-if(collectComment&&commentHandler){
-ast.comments=commentHandler.comments;
-}
-if(parser.config.tokens){
-ast.tokens=parser.tokens;
-}
-if(parser.config.tolerant){
-ast.errors=parser.errorHandler.errors;
-}
-return ast;
-}
-exports.parse=parse;
-function parseModule(code,options,delegate){
-var parsingOptions=options||{};
-parsingOptions.sourceType='module';
-return parse(code,parsingOptions,delegate);
-}
-exports.parseModule=parseModule;
-function parseScript(code,options,delegate){
-var parsingOptions=options||{};
-parsingOptions.sourceType='script';
-return parse(code,parsingOptions,delegate);
-}
-exports.parseScript=parseScript;
-function tokenize(code,options,delegate){
-var tokenizer=new tokenizer_1.Tokenizer(code,options);
-var tokens;
-tokens=[];
-try{
-while(true){
-var token=tokenizer.getNextToken();
-if(!token){
-break;
-}
-if(delegate){
-token=delegate(token);
-}
-tokens.push(token);
-}
-}
-catch(e){
-tokenizer.errorHandler.tolerate(e);
-}
-if(tokenizer.errorHandler.tolerant){
-tokens.errors=tokenizer.errors();
-}
-return tokens;
-}
-exports.tokenize=tokenize;
-var syntax_1=__webpack_require__(2);
-exports.Syntax=syntax_1.Syntax;
-
-exports.version='4.0.0';
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-var syntax_1=__webpack_require__(2);
-var CommentHandler=function(){
-function CommentHandler(){
-this.attach=false;
-this.comments=[];
-this.stack=[];
-this.leading=[];
-this.trailing=[];
-}
-CommentHandler.prototype.insertInnerComments=function(node,metadata){
-
-
-if(node.type===syntax_1.Syntax.BlockStatement&&node.body.length===0){
-var innerComments=[];
-for(var i=this.leading.length-1;i>=0;--i){
-var entry=this.leading[i];
-if(metadata.end.offset>=entry.start){
-innerComments.unshift(entry.comment);
-this.leading.splice(i,1);
-this.trailing.splice(i,1);
-}
-}
-if(innerComments.length){
-node.innerComments=innerComments;
-}
-}
-};
-CommentHandler.prototype.findTrailingComments=function(metadata){
-var trailingComments=[];
-if(this.trailing.length>0){
-for(var i=this.trailing.length-1;i>=0;--i){
-var entry_1=this.trailing[i];
-if(entry_1.start>=metadata.end.offset){
-trailingComments.unshift(entry_1.comment);
-}
-}
-this.trailing.length=0;
-return trailingComments;
-}
-var entry=this.stack[this.stack.length-1];
-if(entry&&entry.node.trailingComments){
-var firstComment=entry.node.trailingComments[0];
-if(firstComment&&firstComment.range[0]>=metadata.end.offset){
-trailingComments=entry.node.trailingComments;
-delete entry.node.trailingComments;
-}
-}
-return trailingComments;
-};
-CommentHandler.prototype.findLeadingComments=function(metadata){
-var leadingComments=[];
-var target;
-while(this.stack.length>0){
-var entry=this.stack[this.stack.length-1];
-if(entry&&entry.start>=metadata.start.offset){
-target=entry.node;
-this.stack.pop();
-}else
-{
-break;
-}
-}
-if(target){
-var count=target.leadingComments?target.leadingComments.length:0;
-for(var i=count-1;i>=0;--i){
-var comment=target.leadingComments[i];
-if(comment.range[1]<=metadata.start.offset){
-leadingComments.unshift(comment);
-target.leadingComments.splice(i,1);
-}
-}
-if(target.leadingComments&&target.leadingComments.length===0){
-delete target.leadingComments;
-}
-return leadingComments;
-}
-for(var i=this.leading.length-1;i>=0;--i){
-var entry=this.leading[i];
-if(entry.start<=metadata.start.offset){
-leadingComments.unshift(entry.comment);
-this.leading.splice(i,1);
-}
-}
-return leadingComments;
-};
-CommentHandler.prototype.visitNode=function(node,metadata){
-if(node.type===syntax_1.Syntax.Program&&node.body.length>0){
-return;
-}
-this.insertInnerComments(node,metadata);
-var trailingComments=this.findTrailingComments(metadata);
-var leadingComments=this.findLeadingComments(metadata);
-if(leadingComments.length>0){
-node.leadingComments=leadingComments;
-}
-if(trailingComments.length>0){
-node.trailingComments=trailingComments;
-}
-this.stack.push({
-node:node,
-start:metadata.start.offset});
-
-};
-CommentHandler.prototype.visitComment=function(node,metadata){
-var type=node.type[0]==='L'?'Line':'Block';
-var comment={
-type:type,
-value:node.value};
-
-if(node.range){
-comment.range=node.range;
-}
-if(node.loc){
-comment.loc=node.loc;
-}
-this.comments.push(comment);
-if(this.attach){
-var entry={
-comment:{
-type:type,
-value:node.value,
-range:[metadata.start.offset,metadata.end.offset]},
-
-start:metadata.start.offset};
-
-if(node.loc){
-entry.comment.loc=node.loc;
-}
-node.type=type;
-this.leading.push(entry);
-this.trailing.push(entry);
-}
-};
-CommentHandler.prototype.visit=function(node,metadata){
-if(node.type==='LineComment'){
-this.visitComment(node,metadata);
-}else
-if(node.type==='BlockComment'){
-this.visitComment(node,metadata);
-}else
-if(this.attach){
-this.visitNode(node,metadata);
-}
-};
-return CommentHandler;
-}();
-exports.CommentHandler=CommentHandler;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-exports.Syntax={
-AssignmentExpression:'AssignmentExpression',
-AssignmentPattern:'AssignmentPattern',
-ArrayExpression:'ArrayExpression',
-ArrayPattern:'ArrayPattern',
-ArrowFunctionExpression:'ArrowFunctionExpression',
-AwaitExpression:'AwaitExpression',
-BlockStatement:'BlockStatement',
-BinaryExpression:'BinaryExpression',
-BreakStatement:'BreakStatement',
-CallExpression:'CallExpression',
-CatchClause:'CatchClause',
-ClassBody:'ClassBody',
-ClassDeclaration:'ClassDeclaration',
-ClassExpression:'ClassExpression',
-ConditionalExpression:'ConditionalExpression',
-ContinueStatement:'ContinueStatement',
-DoWhileStatement:'DoWhileStatement',
-DebuggerStatement:'DebuggerStatement',
-EmptyStatement:'EmptyStatement',
-ExportAllDeclaration:'ExportAllDeclaration',
-ExportDefaultDeclaration:'ExportDefaultDeclaration',
-ExportNamedDeclaration:'ExportNamedDeclaration',
-ExportSpecifier:'ExportSpecifier',
-ExpressionStatement:'ExpressionStatement',
-ForStatement:'ForStatement',
-ForOfStatement:'ForOfStatement',
-ForInStatement:'ForInStatement',
-FunctionDeclaration:'FunctionDeclaration',
-FunctionExpression:'FunctionExpression',
-Identifier:'Identifier',
-IfStatement:'IfStatement',
-ImportDeclaration:'ImportDeclaration',
-ImportDefaultSpecifier:'ImportDefaultSpecifier',
-ImportNamespaceSpecifier:'ImportNamespaceSpecifier',
-ImportSpecifier:'ImportSpecifier',
-Literal:'Literal',
-LabeledStatement:'LabeledStatement',
-LogicalExpression:'LogicalExpression',
-MemberExpression:'MemberExpression',
-MetaProperty:'MetaProperty',
-MethodDefinition:'MethodDefinition',
-NewExpression:'NewExpression',
-ObjectExpression:'ObjectExpression',
-ObjectPattern:'ObjectPattern',
-Program:'Program',
-Property:'Property',
-RestElement:'RestElement',
-ReturnStatement:'ReturnStatement',
-SequenceExpression:'SequenceExpression',
-SpreadElement:'SpreadElement',
-Super:'Super',
-SwitchCase:'SwitchCase',
-SwitchStatement:'SwitchStatement',
-TaggedTemplateExpression:'TaggedTemplateExpression',
-TemplateElement:'TemplateElement',
-TemplateLiteral:'TemplateLiteral',
-ThisExpression:'ThisExpression',
-ThrowStatement:'ThrowStatement',
-TryStatement:'TryStatement',
-UnaryExpression:'UnaryExpression',
-UpdateExpression:'UpdateExpression',
-VariableDeclaration:'VariableDeclaration',
-VariableDeclarator:'VariableDeclarator',
-WhileStatement:'WhileStatement',
-WithStatement:'WithStatement',
-YieldExpression:'YieldExpression'};
-
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-
-var __extends=this&&this.__extends||function(){
-var extendStatics=Object.setPrototypeOf||
-{__proto__:[]}instanceof Array&&function(d,b){d.__proto__=b;}||
-function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];};
-return function(d,b){
-extendStatics(d,b);
-function __(){this.constructor=d;}
-d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __());
-};
-}();
-Object.defineProperty(exports,"__esModule",{value:true});
-var character_1=__webpack_require__(4);
-var JSXNode=__webpack_require__(5);
-var jsx_syntax_1=__webpack_require__(6);
-var Node=__webpack_require__(7);
-var parser_1=__webpack_require__(8);
-var token_1=__webpack_require__(13);
-var xhtml_entities_1=__webpack_require__(14);
-token_1.TokenName[100]='JSXIdentifier';
-token_1.TokenName[101]='JSXText';
-
-function getQualifiedElementName(elementName){
-var qualifiedName;
-switch(elementName.type){
-case jsx_syntax_1.JSXSyntax.JSXIdentifier:
-var id=elementName;
-qualifiedName=id.name;
-break;
-case jsx_syntax_1.JSXSyntax.JSXNamespacedName:
-var ns=elementName;
-qualifiedName=getQualifiedElementName(ns.namespace)+':'+
-getQualifiedElementName(ns.name);
-break;
-case jsx_syntax_1.JSXSyntax.JSXMemberExpression:
-var expr=elementName;
-qualifiedName=getQualifiedElementName(expr.object)+'.'+
-getQualifiedElementName(expr.property);
-break;
-
-default:
-break;}
-
-return qualifiedName;
-}
-var JSXParser=function(_super){
-__extends(JSXParser,_super);
-function JSXParser(code,options,delegate){
-return _super.call(this,code,options,delegate)||this;
-}
-JSXParser.prototype.parsePrimaryExpression=function(){
-return this.match('<')?this.parseJSXRoot():_super.prototype.parsePrimaryExpression.call(this);
-};
-JSXParser.prototype.startJSX=function(){
-
-this.scanner.index=this.startMarker.index;
-this.scanner.lineNumber=this.startMarker.line;
-this.scanner.lineStart=this.startMarker.index-this.startMarker.column;
-};
-JSXParser.prototype.finishJSX=function(){
-
-this.nextToken();
-};
-JSXParser.prototype.reenterJSX=function(){
-this.startJSX();
-this.expectJSX('}');
-
-if(this.config.tokens){
-this.tokens.pop();
-}
-};
-JSXParser.prototype.createJSXNode=function(){
-this.collectComments();
-return{
-index:this.scanner.index,
-line:this.scanner.lineNumber,
-column:this.scanner.index-this.scanner.lineStart};
-
-};
-JSXParser.prototype.createJSXChildNode=function(){
-return{
-index:this.scanner.index,
-line:this.scanner.lineNumber,
-column:this.scanner.index-this.scanner.lineStart};
-
-};
-JSXParser.prototype.scanXHTMLEntity=function(quote){
-var result='&';
-var valid=true;
-var terminated=false;
-var numeric=false;
-var hex=false;
-while(!this.scanner.eof()&&valid&&!terminated){
-var ch=this.scanner.source[this.scanner.index];
-if(ch===quote){
-break;
-}
-terminated=ch===';';
-result+=ch;
-++this.scanner.index;
-if(!terminated){
-switch(result.length){
-case 2:
-
-numeric=ch==='#';
-break;
-case 3:
-if(numeric){
-
-hex=ch==='x';
-valid=hex||character_1.Character.isDecimalDigit(ch.charCodeAt(0));
-numeric=numeric&&!hex;
-}
-break;
-default:
-valid=valid&&!(numeric&&!character_1.Character.isDecimalDigit(ch.charCodeAt(0)));
-valid=valid&&!(hex&&!character_1.Character.isHexDigit(ch.charCodeAt(0)));
-break;}
-
-}
-}
-if(valid&&terminated&&result.length>2){
-
-var str=result.substr(1,result.length-2);
-if(numeric&&str.length>1){
-result=String.fromCharCode(parseInt(str.substr(1),10));
-}else
-if(hex&&str.length>2){
-result=String.fromCharCode(parseInt('0'+str.substr(1),16));
-}else
-if(!numeric&&!hex&&xhtml_entities_1.XHTMLEntities[str]){
-result=xhtml_entities_1.XHTMLEntities[str];
-}
-}
-return result;
-};
-
-JSXParser.prototype.lexJSX=function(){
-var cp=this.scanner.source.charCodeAt(this.scanner.index);
-
-if(cp===60||cp===62||cp===47||cp===58||cp===61||cp===123||cp===125){
-var value=this.scanner.source[this.scanner.index++];
-return{
-type:7,
-value:value,
-lineNumber:this.scanner.lineNumber,
-lineStart:this.scanner.lineStart,
-start:this.scanner.index-1,
-end:this.scanner.index};
-
-}
-
-if(cp===34||cp===39){
-var start=this.scanner.index;
-var quote=this.scanner.source[this.scanner.index++];
-var str='';
-while(!this.scanner.eof()){
-var ch=this.scanner.source[this.scanner.index++];
-if(ch===quote){
-break;
-}else
-if(ch==='&'){
-str+=this.scanXHTMLEntity(quote);
-}else
-{
-str+=ch;
-}
-}
-return{
-type:8,
-value:str,
-lineNumber:this.scanner.lineNumber,
-lineStart:this.scanner.lineStart,
-start:start,
-end:this.scanner.index};
-
-}
-
-if(cp===46){
-var n1=this.scanner.source.charCodeAt(this.scanner.index+1);
-var n2=this.scanner.source.charCodeAt(this.scanner.index+2);
-var value=n1===46&&n2===46?'...':'.';
-var start=this.scanner.index;
-this.scanner.index+=value.length;
-return{
-type:7,
-value:value,
-lineNumber:this.scanner.lineNumber,
-lineStart:this.scanner.lineStart,
-start:start,
-end:this.scanner.index};
-
-}
-
-if(cp===96){
-
-return{
-type:10,
-value:'',
-lineNumber:this.scanner.lineNumber,
-lineStart:this.scanner.lineStart,
-start:this.scanner.index,
-end:this.scanner.index};
-
-}
-
-if(character_1.Character.isIdentifierStart(cp)&&cp!==92){
-var start=this.scanner.index;
-++this.scanner.index;
-while(!this.scanner.eof()){
-var ch=this.scanner.source.charCodeAt(this.scanner.index);
-if(character_1.Character.isIdentifierPart(ch)&&ch!==92){
-++this.scanner.index;
-}else
-if(ch===45){
-
-++this.scanner.index;
-}else
-{
-break;
-}
-}
-var id=this.scanner.source.slice(start,this.scanner.index);
-return{
-type:100,
-value:id,
-lineNumber:this.scanner.lineNumber,
-lineStart:this.scanner.lineStart,
-start:start,
-end:this.scanner.index};
-
-}
-return this.scanner.lex();
-};
-JSXParser.prototype.nextJSXToken=function(){
-this.collectComments();
-this.startMarker.index=this.scanner.index;
-this.startMarker.line=this.scanner.lineNumber;
-this.startMarker.column=this.scanner.index-this.scanner.lineStart;
-var token=this.lexJSX();
-this.lastMarker.index=this.scanner.index;
-this.lastMarker.line=this.scanner.lineNumber;
-this.lastMarker.column=this.scanner.index-this.scanner.lineStart;
-if(this.config.tokens){
-this.tokens.push(this.convertToken(token));
-}
-return token;
-};
-JSXParser.prototype.nextJSXText=function(){
-this.startMarker.index=this.scanner.index;
-this.startMarker.line=this.scanner.lineNumber;
-this.startMarker.column=this.scanner.index-this.scanner.lineStart;
-var start=this.scanner.index;
-var text='';
-while(!this.scanner.eof()){
-var ch=this.scanner.source[this.scanner.index];
-if(ch==='{'||ch==='<'){
-break;
-}
-++this.scanner.index;
-text+=ch;
-if(character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-++this.scanner.lineNumber;
-if(ch==='\r'&&this.scanner.source[this.scanner.index]==='\n'){
-++this.scanner.index;
-}
-this.scanner.lineStart=this.scanner.index;
-}
-}
-this.lastMarker.index=this.scanner.index;
-this.lastMarker.line=this.scanner.lineNumber;
-this.lastMarker.column=this.scanner.index-this.scanner.lineStart;
-var token={
-type:101,
-value:text,
-lineNumber:this.scanner.lineNumber,
-lineStart:this.scanner.lineStart,
-start:start,
-end:this.scanner.index};
-
-if(text.length>0&&this.config.tokens){
-this.tokens.push(this.convertToken(token));
-}
-return token;
-};
-JSXParser.prototype.peekJSXToken=function(){
-var state=this.scanner.saveState();
-this.scanner.scanComments();
-var next=this.lexJSX();
-this.scanner.restoreState(state);
-return next;
-};
-
-
-JSXParser.prototype.expectJSX=function(value){
-var token=this.nextJSXToken();
-if(token.type!==7||token.value!==value){
-this.throwUnexpectedToken(token);
-}
-};
-
-JSXParser.prototype.matchJSX=function(value){
-var next=this.peekJSXToken();
-return next.type===7&&next.value===value;
-};
-JSXParser.prototype.parseJSXIdentifier=function(){
-var node=this.createJSXNode();
-var token=this.nextJSXToken();
-if(token.type!==100){
-this.throwUnexpectedToken(token);
-}
-return this.finalize(node,new JSXNode.JSXIdentifier(token.value));
-};
-JSXParser.prototype.parseJSXElementName=function(){
-var node=this.createJSXNode();
-var elementName=this.parseJSXIdentifier();
-if(this.matchJSX(':')){
-var namespace=elementName;
-this.expectJSX(':');
-var name_1=this.parseJSXIdentifier();
-elementName=this.finalize(node,new JSXNode.JSXNamespacedName(namespace,name_1));
-}else
-if(this.matchJSX('.')){
-while(this.matchJSX('.')){
-var object=elementName;
-this.expectJSX('.');
-var property=this.parseJSXIdentifier();
-elementName=this.finalize(node,new JSXNode.JSXMemberExpression(object,property));
-}
-}
-return elementName;
-};
-JSXParser.prototype.parseJSXAttributeName=function(){
-var node=this.createJSXNode();
-var attributeName;
-var identifier=this.parseJSXIdentifier();
-if(this.matchJSX(':')){
-var namespace=identifier;
-this.expectJSX(':');
-var name_2=this.parseJSXIdentifier();
-attributeName=this.finalize(node,new JSXNode.JSXNamespacedName(namespace,name_2));
-}else
-{
-attributeName=identifier;
-}
-return attributeName;
-};
-JSXParser.prototype.parseJSXStringLiteralAttribute=function(){
-var node=this.createJSXNode();
-var token=this.nextJSXToken();
-if(token.type!==8){
-this.throwUnexpectedToken(token);
-}
-var raw=this.getTokenRaw(token);
-return this.finalize(node,new Node.Literal(token.value,raw));
-};
-JSXParser.prototype.parseJSXExpressionAttribute=function(){
-var node=this.createJSXNode();
-this.expectJSX('{');
-this.finishJSX();
-if(this.match('}')){
-this.tolerateError('JSX attributes must only be assigned a non-empty expression');
-}
-var expression=this.parseAssignmentExpression();
-this.reenterJSX();
-return this.finalize(node,new JSXNode.JSXExpressionContainer(expression));
-};
-JSXParser.prototype.parseJSXAttributeValue=function(){
-return this.matchJSX('{')?this.parseJSXExpressionAttribute():
-this.matchJSX('<')?this.parseJSXElement():this.parseJSXStringLiteralAttribute();
-};
-JSXParser.prototype.parseJSXNameValueAttribute=function(){
-var node=this.createJSXNode();
-var name=this.parseJSXAttributeName();
-var value=null;
-if(this.matchJSX('=')){
-this.expectJSX('=');
-value=this.parseJSXAttributeValue();
-}
-return this.finalize(node,new JSXNode.JSXAttribute(name,value));
-};
-JSXParser.prototype.parseJSXSpreadAttribute=function(){
-var node=this.createJSXNode();
-this.expectJSX('{');
-this.expectJSX('...');
-this.finishJSX();
-var argument=this.parseAssignmentExpression();
-this.reenterJSX();
-return this.finalize(node,new JSXNode.JSXSpreadAttribute(argument));
-};
-JSXParser.prototype.parseJSXAttributes=function(){
-var attributes=[];
-while(!this.matchJSX('/')&&!this.matchJSX('>')){
-var attribute=this.matchJSX('{')?this.parseJSXSpreadAttribute():
-this.parseJSXNameValueAttribute();
-attributes.push(attribute);
-}
-return attributes;
-};
-JSXParser.prototype.parseJSXOpeningElement=function(){
-var node=this.createJSXNode();
-this.expectJSX('<');
-var name=this.parseJSXElementName();
-var attributes=this.parseJSXAttributes();
-var selfClosing=this.matchJSX('/');
-if(selfClosing){
-this.expectJSX('/');
-}
-this.expectJSX('>');
-return this.finalize(node,new JSXNode.JSXOpeningElement(name,selfClosing,attributes));
-};
-JSXParser.prototype.parseJSXBoundaryElement=function(){
-var node=this.createJSXNode();
-this.expectJSX('<');
-if(this.matchJSX('/')){
-this.expectJSX('/');
-var name_3=this.parseJSXElementName();
-this.expectJSX('>');
-return this.finalize(node,new JSXNode.JSXClosingElement(name_3));
-}
-var name=this.parseJSXElementName();
-var attributes=this.parseJSXAttributes();
-var selfClosing=this.matchJSX('/');
-if(selfClosing){
-this.expectJSX('/');
-}
-this.expectJSX('>');
-return this.finalize(node,new JSXNode.JSXOpeningElement(name,selfClosing,attributes));
-};
-JSXParser.prototype.parseJSXEmptyExpression=function(){
-var node=this.createJSXChildNode();
-this.collectComments();
-this.lastMarker.index=this.scanner.index;
-this.lastMarker.line=this.scanner.lineNumber;
-this.lastMarker.column=this.scanner.index-this.scanner.lineStart;
-return this.finalize(node,new JSXNode.JSXEmptyExpression());
-};
-JSXParser.prototype.parseJSXExpressionContainer=function(){
-var node=this.createJSXNode();
-this.expectJSX('{');
-var expression;
-if(this.matchJSX('}')){
-expression=this.parseJSXEmptyExpression();
-this.expectJSX('}');
-}else
-{
-this.finishJSX();
-expression=this.parseAssignmentExpression();
-this.reenterJSX();
-}
-return this.finalize(node,new JSXNode.JSXExpressionContainer(expression));
-};
-JSXParser.prototype.parseJSXChildren=function(){
-var children=[];
-while(!this.scanner.eof()){
-var node=this.createJSXChildNode();
-var token=this.nextJSXText();
-if(token.start<token.end){
-var raw=this.getTokenRaw(token);
-var child=this.finalize(node,new JSXNode.JSXText(token.value,raw));
-children.push(child);
-}
-if(this.scanner.source[this.scanner.index]==='{'){
-var container=this.parseJSXExpressionContainer();
-children.push(container);
-}else
-{
-break;
-}
-}
-return children;
-};
-JSXParser.prototype.parseComplexJSXElement=function(el){
-var stack=[];
-while(!this.scanner.eof()){
-el.children=el.children.concat(this.parseJSXChildren());
-var node=this.createJSXChildNode();
-var element=this.parseJSXBoundaryElement();
-if(element.type===jsx_syntax_1.JSXSyntax.JSXOpeningElement){
-var opening=element;
-if(opening.selfClosing){
-var child=this.finalize(node,new JSXNode.JSXElement(opening,[],null));
-el.children.push(child);
-}else
-{
-stack.push(el);
-el={node:node,opening:opening,closing:null,children:[]};
-}
-}
-if(element.type===jsx_syntax_1.JSXSyntax.JSXClosingElement){
-el.closing=element;
-var open_1=getQualifiedElementName(el.opening.name);
-var close_1=getQualifiedElementName(el.closing.name);
-if(open_1!==close_1){
-this.tolerateError('Expected corresponding JSX closing tag for %0',open_1);
-}
-if(stack.length>0){
-var child=this.finalize(el.node,new JSXNode.JSXElement(el.opening,el.children,el.closing));
-el=stack[stack.length-1];
-el.children.push(child);
-stack.pop();
-}else
-{
-break;
-}
-}
-}
-return el;
-};
-JSXParser.prototype.parseJSXElement=function(){
-var node=this.createJSXNode();
-var opening=this.parseJSXOpeningElement();
-var children=[];
-var closing=null;
-if(!opening.selfClosing){
-var el=this.parseComplexJSXElement({node:node,opening:opening,closing:closing,children:children});
-children=el.children;
-closing=el.closing;
-}
-return this.finalize(node,new JSXNode.JSXElement(opening,children,closing));
-};
-JSXParser.prototype.parseJSXRoot=function(){
-
-if(this.config.tokens){
-this.tokens.pop();
-}
-this.startJSX();
-var element=this.parseJSXElement();
-this.finishJSX();
-return element;
-};
-JSXParser.prototype.isStartOfExpression=function(){
-return _super.prototype.isStartOfExpression.call(this)||this.match('<');
-};
-return JSXParser;
-}(parser_1.Parser);
-exports.JSXParser=JSXParser;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-
-var Regex={
-
-NonAsciiIdentifierStart:/[\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\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\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\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\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-\uA7AD\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
-
-NonAsciiIdentifierPart:/[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\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\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\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\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\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-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/};
-
-exports.Character={
-
-fromCodePoint:function(cp){
-return cp<0x10000?String.fromCharCode(cp):
-String.fromCharCode(0xD800+(cp-0x10000>>10))+
-String.fromCharCode(0xDC00+(cp-0x10000&1023));
-},
-
-isWhiteSpace:function(cp){
-return cp===0x20||cp===0x09||cp===0x0B||cp===0x0C||cp===0xA0||
-cp>=0x1680&&[0x1680,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200A,0x202F,0x205F,0x3000,0xFEFF].indexOf(cp)>=0;
-},
-
-isLineTerminator:function(cp){
-return cp===0x0A||cp===0x0D||cp===0x2028||cp===0x2029;
-},
-
-isIdentifierStart:function(cp){
-return cp===0x24||cp===0x5F||
-cp>=0x41&&cp<=0x5A||
-cp>=0x61&&cp<=0x7A||
-cp===0x5C||
-cp>=0x80&&Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(cp));
-},
-isIdentifierPart:function(cp){
-return cp===0x24||cp===0x5F||
-cp>=0x41&&cp<=0x5A||
-cp>=0x61&&cp<=0x7A||
-cp>=0x30&&cp<=0x39||
-cp===0x5C||
-cp>=0x80&&Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp));
-},
-
-isDecimalDigit:function(cp){
-return cp>=0x30&&cp<=0x39;
-},
-isHexDigit:function(cp){
-return cp>=0x30&&cp<=0x39||
-cp>=0x41&&cp<=0x46||
-cp>=0x61&&cp<=0x66;
-},
-isOctalDigit:function(cp){
-return cp>=0x30&&cp<=0x37;
-}};
-
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-var jsx_syntax_1=__webpack_require__(6);
-
-var JSXClosingElement=function(){
-function JSXClosingElement(name){
-this.type=jsx_syntax_1.JSXSyntax.JSXClosingElement;
-this.name=name;
-}
-return JSXClosingElement;
-}();
-exports.JSXClosingElement=JSXClosingElement;
-var JSXElement=function(){
-function JSXElement(openingElement,children,closingElement){
-this.type=jsx_syntax_1.JSXSyntax.JSXElement;
-this.openingElement=openingElement;
-this.children=children;
-this.closingElement=closingElement;
-}
-return JSXElement;
-}();
-exports.JSXElement=JSXElement;
-var JSXEmptyExpression=function(){
-function JSXEmptyExpression(){
-this.type=jsx_syntax_1.JSXSyntax.JSXEmptyExpression;
-}
-return JSXEmptyExpression;
-}();
-exports.JSXEmptyExpression=JSXEmptyExpression;
-var JSXExpressionContainer=function(){
-function JSXExpressionContainer(expression){
-this.type=jsx_syntax_1.JSXSyntax.JSXExpressionContainer;
-this.expression=expression;
-}
-return JSXExpressionContainer;
-}();
-exports.JSXExpressionContainer=JSXExpressionContainer;
-var JSXIdentifier=function(){
-function JSXIdentifier(name){
-this.type=jsx_syntax_1.JSXSyntax.JSXIdentifier;
-this.name=name;
-}
-return JSXIdentifier;
-}();
-exports.JSXIdentifier=JSXIdentifier;
-var JSXMemberExpression=function(){
-function JSXMemberExpression(object,property){
-this.type=jsx_syntax_1.JSXSyntax.JSXMemberExpression;
-this.object=object;
-this.property=property;
-}
-return JSXMemberExpression;
-}();
-exports.JSXMemberExpression=JSXMemberExpression;
-var JSXAttribute=function(){
-function JSXAttribute(name,value){
-this.type=jsx_syntax_1.JSXSyntax.JSXAttribute;
-this.name=name;
-this.value=value;
-}
-return JSXAttribute;
-}();
-exports.JSXAttribute=JSXAttribute;
-var JSXNamespacedName=function(){
-function JSXNamespacedName(namespace,name){
-this.type=jsx_syntax_1.JSXSyntax.JSXNamespacedName;
-this.namespace=namespace;
-this.name=name;
-}
-return JSXNamespacedName;
-}();
-exports.JSXNamespacedName=JSXNamespacedName;
-var JSXOpeningElement=function(){
-function JSXOpeningElement(name,selfClosing,attributes){
-this.type=jsx_syntax_1.JSXSyntax.JSXOpeningElement;
-this.name=name;
-this.selfClosing=selfClosing;
-this.attributes=attributes;
-}
-return JSXOpeningElement;
-}();
-exports.JSXOpeningElement=JSXOpeningElement;
-var JSXSpreadAttribute=function(){
-function JSXSpreadAttribute(argument){
-this.type=jsx_syntax_1.JSXSyntax.JSXSpreadAttribute;
-this.argument=argument;
-}
-return JSXSpreadAttribute;
-}();
-exports.JSXSpreadAttribute=JSXSpreadAttribute;
-var JSXText=function(){
-function JSXText(value,raw){
-this.type=jsx_syntax_1.JSXSyntax.JSXText;
-this.value=value;
-this.raw=raw;
-}
-return JSXText;
-}();
-exports.JSXText=JSXText;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-exports.JSXSyntax={
-JSXAttribute:'JSXAttribute',
-JSXClosingElement:'JSXClosingElement',
-JSXElement:'JSXElement',
-JSXEmptyExpression:'JSXEmptyExpression',
-JSXExpressionContainer:'JSXExpressionContainer',
-JSXIdentifier:'JSXIdentifier',
-JSXMemberExpression:'JSXMemberExpression',
-JSXNamespacedName:'JSXNamespacedName',
-JSXOpeningElement:'JSXOpeningElement',
-JSXSpreadAttribute:'JSXSpreadAttribute',
-JSXText:'JSXText'};
-
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-var syntax_1=__webpack_require__(2);
-
-var ArrayExpression=function(){
-function ArrayExpression(elements){
-this.type=syntax_1.Syntax.ArrayExpression;
-this.elements=elements;
-}
-return ArrayExpression;
-}();
-exports.ArrayExpression=ArrayExpression;
-var ArrayPattern=function(){
-function ArrayPattern(elements){
-this.type=syntax_1.Syntax.ArrayPattern;
-this.elements=elements;
-}
-return ArrayPattern;
-}();
-exports.ArrayPattern=ArrayPattern;
-var ArrowFunctionExpression=function(){
-function ArrowFunctionExpression(params,body,expression){
-this.type=syntax_1.Syntax.ArrowFunctionExpression;
-this.id=null;
-this.params=params;
-this.body=body;
-this.generator=false;
-this.expression=expression;
-this.async=false;
-}
-return ArrowFunctionExpression;
-}();
-exports.ArrowFunctionExpression=ArrowFunctionExpression;
-var AssignmentExpression=function(){
-function AssignmentExpression(operator,left,right){
-this.type=syntax_1.Syntax.AssignmentExpression;
-this.operator=operator;
-this.left=left;
-this.right=right;
-}
-return AssignmentExpression;
-}();
-exports.AssignmentExpression=AssignmentExpression;
-var AssignmentPattern=function(){
-function AssignmentPattern(left,right){
-this.type=syntax_1.Syntax.AssignmentPattern;
-this.left=left;
-this.right=right;
-}
-return AssignmentPattern;
-}();
-exports.AssignmentPattern=AssignmentPattern;
-var AsyncArrowFunctionExpression=function(){
-function AsyncArrowFunctionExpression(params,body,expression){
-this.type=syntax_1.Syntax.ArrowFunctionExpression;
-this.id=null;
-this.params=params;
-this.body=body;
-this.generator=false;
-this.expression=expression;
-this.async=true;
-}
-return AsyncArrowFunctionExpression;
-}();
-exports.AsyncArrowFunctionExpression=AsyncArrowFunctionExpression;
-var AsyncFunctionDeclaration=function(){
-function AsyncFunctionDeclaration(id,params,body){
-this.type=syntax_1.Syntax.FunctionDeclaration;
-this.id=id;
-this.params=params;
-this.body=body;
-this.generator=false;
-this.expression=false;
-this.async=true;
-}
-return AsyncFunctionDeclaration;
-}();
-exports.AsyncFunctionDeclaration=AsyncFunctionDeclaration;
-var AsyncFunctionExpression=function(){
-function AsyncFunctionExpression(id,params,body){
-this.type=syntax_1.Syntax.FunctionExpression;
-this.id=id;
-this.params=params;
-this.body=body;
-this.generator=false;
-this.expression=false;
-this.async=true;
-}
-return AsyncFunctionExpression;
-}();
-exports.AsyncFunctionExpression=AsyncFunctionExpression;
-var AwaitExpression=function(){
-function AwaitExpression(argument){
-this.type=syntax_1.Syntax.AwaitExpression;
-this.argument=argument;
-}
-return AwaitExpression;
-}();
-exports.AwaitExpression=AwaitExpression;
-var BinaryExpression=function(){
-function BinaryExpression(operator,left,right){
-var logical=operator==='||'||operator==='&&';
-this.type=logical?syntax_1.Syntax.LogicalExpression:syntax_1.Syntax.BinaryExpression;
-this.operator=operator;
-this.left=left;
-this.right=right;
-}
-return BinaryExpression;
-}();
-exports.BinaryExpression=BinaryExpression;
-var BlockStatement=function(){
-function BlockStatement(body){
-this.type=syntax_1.Syntax.BlockStatement;
-this.body=body;
-}
-return BlockStatement;
-}();
-exports.BlockStatement=BlockStatement;
-var BreakStatement=function(){
-function BreakStatement(label){
-this.type=syntax_1.Syntax.BreakStatement;
-this.label=label;
-}
-return BreakStatement;
-}();
-exports.BreakStatement=BreakStatement;
-var CallExpression=function(){
-function CallExpression(callee,args){
-this.type=syntax_1.Syntax.CallExpression;
-this.callee=callee;
-this.arguments=args;
-}
-return CallExpression;
-}();
-exports.CallExpression=CallExpression;
-var CatchClause=function(){
-function CatchClause(param,body){
-this.type=syntax_1.Syntax.CatchClause;
-this.param=param;
-this.body=body;
-}
-return CatchClause;
-}();
-exports.CatchClause=CatchClause;
-var ClassBody=function(){
-function ClassBody(body){
-this.type=syntax_1.Syntax.ClassBody;
-this.body=body;
-}
-return ClassBody;
-}();
-exports.ClassBody=ClassBody;
-var ClassDeclaration=function(){
-function ClassDeclaration(id,superClass,body){
-this.type=syntax_1.Syntax.ClassDeclaration;
-this.id=id;
-this.superClass=superClass;
-this.body=body;
-}
-return ClassDeclaration;
-}();
-exports.ClassDeclaration=ClassDeclaration;
-var ClassExpression=function(){
-function ClassExpression(id,superClass,body){
-this.type=syntax_1.Syntax.ClassExpression;
-this.id=id;
-this.superClass=superClass;
-this.body=body;
-}
-return ClassExpression;
-}();
-exports.ClassExpression=ClassExpression;
-var ComputedMemberExpression=function(){
-function ComputedMemberExpression(object,property){
-this.type=syntax_1.Syntax.MemberExpression;
-this.computed=true;
-this.object=object;
-this.property=property;
-}
-return ComputedMemberExpression;
-}();
-exports.ComputedMemberExpression=ComputedMemberExpression;
-var ConditionalExpression=function(){
-function ConditionalExpression(test,consequent,alternate){
-this.type=syntax_1.Syntax.ConditionalExpression;
-this.test=test;
-this.consequent=consequent;
-this.alternate=alternate;
-}
-return ConditionalExpression;
-}();
-exports.ConditionalExpression=ConditionalExpression;
-var ContinueStatement=function(){
-function ContinueStatement(label){
-this.type=syntax_1.Syntax.ContinueStatement;
-this.label=label;
-}
-return ContinueStatement;
-}();
-exports.ContinueStatement=ContinueStatement;
-var DebuggerStatement=function(){
-function DebuggerStatement(){
-this.type=syntax_1.Syntax.DebuggerStatement;
-}
-return DebuggerStatement;
-}();
-exports.DebuggerStatement=DebuggerStatement;
-var Directive=function(){
-function Directive(expression,directive){
-this.type=syntax_1.Syntax.ExpressionStatement;
-this.expression=expression;
-this.directive=directive;
-}
-return Directive;
-}();
-exports.Directive=Directive;
-var DoWhileStatement=function(){
-function DoWhileStatement(body,test){
-this.type=syntax_1.Syntax.DoWhileStatement;
-this.body=body;
-this.test=test;
-}
-return DoWhileStatement;
-}();
-exports.DoWhileStatement=DoWhileStatement;
-var EmptyStatement=function(){
-function EmptyStatement(){
-this.type=syntax_1.Syntax.EmptyStatement;
-}
-return EmptyStatement;
-}();
-exports.EmptyStatement=EmptyStatement;
-var ExportAllDeclaration=function(){
-function ExportAllDeclaration(source){
-this.type=syntax_1.Syntax.ExportAllDeclaration;
-this.source=source;
-}
-return ExportAllDeclaration;
-}();
-exports.ExportAllDeclaration=ExportAllDeclaration;
-var ExportDefaultDeclaration=function(){
-function ExportDefaultDeclaration(declaration){
-this.type=syntax_1.Syntax.ExportDefaultDeclaration;
-this.declaration=declaration;
-}
-return ExportDefaultDeclaration;
-}();
-exports.ExportDefaultDeclaration=ExportDefaultDeclaration;
-var ExportNamedDeclaration=function(){
-function ExportNamedDeclaration(declaration,specifiers,source){
-this.type=syntax_1.Syntax.ExportNamedDeclaration;
-this.declaration=declaration;
-this.specifiers=specifiers;
-this.source=source;
-}
-return ExportNamedDeclaration;
-}();
-exports.ExportNamedDeclaration=ExportNamedDeclaration;
-var ExportSpecifier=function(){
-function ExportSpecifier(local,exported){
-this.type=syntax_1.Syntax.ExportSpecifier;
-this.exported=exported;
-this.local=local;
-}
-return ExportSpecifier;
-}();
-exports.ExportSpecifier=ExportSpecifier;
-var ExpressionStatement=function(){
-function ExpressionStatement(expression){
-this.type=syntax_1.Syntax.ExpressionStatement;
-this.expression=expression;
-}
-return ExpressionStatement;
-}();
-exports.ExpressionStatement=ExpressionStatement;
-var ForInStatement=function(){
-function ForInStatement(left,right,body){
-this.type=syntax_1.Syntax.ForInStatement;
-this.left=left;
-this.right=right;
-this.body=body;
-this.each=false;
-}
-return ForInStatement;
-}();
-exports.ForInStatement=ForInStatement;
-var ForOfStatement=function(){
-function ForOfStatement(left,right,body){
-this.type=syntax_1.Syntax.ForOfStatement;
-this.left=left;
-this.right=right;
-this.body=body;
-}
-return ForOfStatement;
-}();
-exports.ForOfStatement=ForOfStatement;
-var ForStatement=function(){
-function ForStatement(init,test,update,body){
-this.type=syntax_1.Syntax.ForStatement;
-this.init=init;
-this.test=test;
-this.update=update;
-this.body=body;
-}
-return ForStatement;
-}();
-exports.ForStatement=ForStatement;
-var FunctionDeclaration=function(){
-function FunctionDeclaration(id,params,body,generator){
-this.type=syntax_1.Syntax.FunctionDeclaration;
-this.id=id;
-this.params=params;
-this.body=body;
-this.generator=generator;
-this.expression=false;
-this.async=false;
-}
-return FunctionDeclaration;
-}();
-exports.FunctionDeclaration=FunctionDeclaration;
-var FunctionExpression=function(){
-function FunctionExpression(id,params,body,generator){
-this.type=syntax_1.Syntax.FunctionExpression;
-this.id=id;
-this.params=params;
-this.body=body;
-this.generator=generator;
-this.expression=false;
-this.async=false;
-}
-return FunctionExpression;
-}();
-exports.FunctionExpression=FunctionExpression;
-var Identifier=function(){
-function Identifier(name){
-this.type=syntax_1.Syntax.Identifier;
-this.name=name;
-}
-return Identifier;
-}();
-exports.Identifier=Identifier;
-var IfStatement=function(){
-function IfStatement(test,consequent,alternate){
-this.type=syntax_1.Syntax.IfStatement;
-this.test=test;
-this.consequent=consequent;
-this.alternate=alternate;
-}
-return IfStatement;
-}();
-exports.IfStatement=IfStatement;
-var ImportDeclaration=function(){
-function ImportDeclaration(specifiers,source){
-this.type=syntax_1.Syntax.ImportDeclaration;
-this.specifiers=specifiers;
-this.source=source;
-}
-return ImportDeclaration;
-}();
-exports.ImportDeclaration=ImportDeclaration;
-var ImportDefaultSpecifier=function(){
-function ImportDefaultSpecifier(local){
-this.type=syntax_1.Syntax.ImportDefaultSpecifier;
-this.local=local;
-}
-return ImportDefaultSpecifier;
-}();
-exports.ImportDefaultSpecifier=ImportDefaultSpecifier;
-var ImportNamespaceSpecifier=function(){
-function ImportNamespaceSpecifier(local){
-this.type=syntax_1.Syntax.ImportNamespaceSpecifier;
-this.local=local;
-}
-return ImportNamespaceSpecifier;
-}();
-exports.ImportNamespaceSpecifier=ImportNamespaceSpecifier;
-var ImportSpecifier=function(){
-function ImportSpecifier(local,imported){
-this.type=syntax_1.Syntax.ImportSpecifier;
-this.local=local;
-this.imported=imported;
-}
-return ImportSpecifier;
-}();
-exports.ImportSpecifier=ImportSpecifier;
-var LabeledStatement=function(){
-function LabeledStatement(label,body){
-this.type=syntax_1.Syntax.LabeledStatement;
-this.label=label;
-this.body=body;
-}
-return LabeledStatement;
-}();
-exports.LabeledStatement=LabeledStatement;
-var Literal=function(){
-function Literal(value,raw){
-this.type=syntax_1.Syntax.Literal;
-this.value=value;
-this.raw=raw;
-}
-return Literal;
-}();
-exports.Literal=Literal;
-var MetaProperty=function(){
-function MetaProperty(meta,property){
-this.type=syntax_1.Syntax.MetaProperty;
-this.meta=meta;
-this.property=property;
-}
-return MetaProperty;
-}();
-exports.MetaProperty=MetaProperty;
-var MethodDefinition=function(){
-function MethodDefinition(key,computed,value,kind,isStatic){
-this.type=syntax_1.Syntax.MethodDefinition;
-this.key=key;
-this.computed=computed;
-this.value=value;
-this.kind=kind;
-this.static=isStatic;
-}
-return MethodDefinition;
-}();
-exports.MethodDefinition=MethodDefinition;
-var Module=function(){
-function Module(body){
-this.type=syntax_1.Syntax.Program;
-this.body=body;
-this.sourceType='module';
-}
-return Module;
-}();
-exports.Module=Module;
-var NewExpression=function(){
-function NewExpression(callee,args){
-this.type=syntax_1.Syntax.NewExpression;
-this.callee=callee;
-this.arguments=args;
-}
-return NewExpression;
-}();
-exports.NewExpression=NewExpression;
-var ObjectExpression=function(){
-function ObjectExpression(properties){
-this.type=syntax_1.Syntax.ObjectExpression;
-this.properties=properties;
-}
-return ObjectExpression;
-}();
-exports.ObjectExpression=ObjectExpression;
-var ObjectPattern=function(){
-function ObjectPattern(properties){
-this.type=syntax_1.Syntax.ObjectPattern;
-this.properties=properties;
-}
-return ObjectPattern;
-}();
-exports.ObjectPattern=ObjectPattern;
-var Property=function(){
-function Property(kind,key,computed,value,method,shorthand){
-this.type=syntax_1.Syntax.Property;
-this.key=key;
-this.computed=computed;
-this.value=value;
-this.kind=kind;
-this.method=method;
-this.shorthand=shorthand;
-}
-return Property;
-}();
-exports.Property=Property;
-var RegexLiteral=function(){
-function RegexLiteral(value,raw,pattern,flags){
-this.type=syntax_1.Syntax.Literal;
-this.value=value;
-this.raw=raw;
-this.regex={pattern:pattern,flags:flags};
-}
-return RegexLiteral;
-}();
-exports.RegexLiteral=RegexLiteral;
-var RestElement=function(){
-function RestElement(argument){
-this.type=syntax_1.Syntax.RestElement;
-this.argument=argument;
-}
-return RestElement;
-}();
-exports.RestElement=RestElement;
-var ReturnStatement=function(){
-function ReturnStatement(argument){
-this.type=syntax_1.Syntax.ReturnStatement;
-this.argument=argument;
-}
-return ReturnStatement;
-}();
-exports.ReturnStatement=ReturnStatement;
-var Script=function(){
-function Script(body){
-this.type=syntax_1.Syntax.Program;
-this.body=body;
-this.sourceType='script';
-}
-return Script;
-}();
-exports.Script=Script;
-var SequenceExpression=function(){
-function SequenceExpression(expressions){
-this.type=syntax_1.Syntax.SequenceExpression;
-this.expressions=expressions;
-}
-return SequenceExpression;
-}();
-exports.SequenceExpression=SequenceExpression;
-var SpreadElement=function(){
-function SpreadElement(argument){
-this.type=syntax_1.Syntax.SpreadElement;
-this.argument=argument;
-}
-return SpreadElement;
-}();
-exports.SpreadElement=SpreadElement;
-var StaticMemberExpression=function(){
-function StaticMemberExpression(object,property){
-this.type=syntax_1.Syntax.MemberExpression;
-this.computed=false;
-this.object=object;
-this.property=property;
-}
-return StaticMemberExpression;
-}();
-exports.StaticMemberExpression=StaticMemberExpression;
-var Super=function(){
-function Super(){
-this.type=syntax_1.Syntax.Super;
-}
-return Super;
-}();
-exports.Super=Super;
-var SwitchCase=function(){
-function SwitchCase(test,consequent){
-this.type=syntax_1.Syntax.SwitchCase;
-this.test=test;
-this.consequent=consequent;
-}
-return SwitchCase;
-}();
-exports.SwitchCase=SwitchCase;
-var SwitchStatement=function(){
-function SwitchStatement(discriminant,cases){
-this.type=syntax_1.Syntax.SwitchStatement;
-this.discriminant=discriminant;
-this.cases=cases;
-}
-return SwitchStatement;
-}();
-exports.SwitchStatement=SwitchStatement;
-var TaggedTemplateExpression=function(){
-function TaggedTemplateExpression(tag,quasi){
-this.type=syntax_1.Syntax.TaggedTemplateExpression;
-this.tag=tag;
-this.quasi=quasi;
-}
-return TaggedTemplateExpression;
-}();
-exports.TaggedTemplateExpression=TaggedTemplateExpression;
-var TemplateElement=function(){
-function TemplateElement(value,tail){
-this.type=syntax_1.Syntax.TemplateElement;
-this.value=value;
-this.tail=tail;
-}
-return TemplateElement;
-}();
-exports.TemplateElement=TemplateElement;
-var TemplateLiteral=function(){
-function TemplateLiteral(quasis,expressions){
-this.type=syntax_1.Syntax.TemplateLiteral;
-this.quasis=quasis;
-this.expressions=expressions;
-}
-return TemplateLiteral;
-}();
-exports.TemplateLiteral=TemplateLiteral;
-var ThisExpression=function(){
-function ThisExpression(){
-this.type=syntax_1.Syntax.ThisExpression;
-}
-return ThisExpression;
-}();
-exports.ThisExpression=ThisExpression;
-var ThrowStatement=function(){
-function ThrowStatement(argument){
-this.type=syntax_1.Syntax.ThrowStatement;
-this.argument=argument;
-}
-return ThrowStatement;
-}();
-exports.ThrowStatement=ThrowStatement;
-var TryStatement=function(){
-function TryStatement(block,handler,finalizer){
-this.type=syntax_1.Syntax.TryStatement;
-this.block=block;
-this.handler=handler;
-this.finalizer=finalizer;
-}
-return TryStatement;
-}();
-exports.TryStatement=TryStatement;
-var UnaryExpression=function(){
-function UnaryExpression(operator,argument){
-this.type=syntax_1.Syntax.UnaryExpression;
-this.operator=operator;
-this.argument=argument;
-this.prefix=true;
-}
-return UnaryExpression;
-}();
-exports.UnaryExpression=UnaryExpression;
-var UpdateExpression=function(){
-function UpdateExpression(operator,argument,prefix){
-this.type=syntax_1.Syntax.UpdateExpression;
-this.operator=operator;
-this.argument=argument;
-this.prefix=prefix;
-}
-return UpdateExpression;
-}();
-exports.UpdateExpression=UpdateExpression;
-var VariableDeclaration=function(){
-function VariableDeclaration(declarations,kind){
-this.type=syntax_1.Syntax.VariableDeclaration;
-this.declarations=declarations;
-this.kind=kind;
-}
-return VariableDeclaration;
-}();
-exports.VariableDeclaration=VariableDeclaration;
-var VariableDeclarator=function(){
-function VariableDeclarator(id,init){
-this.type=syntax_1.Syntax.VariableDeclarator;
-this.id=id;
-this.init=init;
-}
-return VariableDeclarator;
-}();
-exports.VariableDeclarator=VariableDeclarator;
-var WhileStatement=function(){
-function WhileStatement(test,body){
-this.type=syntax_1.Syntax.WhileStatement;
-this.test=test;
-this.body=body;
-}
-return WhileStatement;
-}();
-exports.WhileStatement=WhileStatement;
-var WithStatement=function(){
-function WithStatement(object,body){
-this.type=syntax_1.Syntax.WithStatement;
-this.object=object;
-this.body=body;
-}
-return WithStatement;
-}();
-exports.WithStatement=WithStatement;
-var YieldExpression=function(){
-function YieldExpression(argument,delegate){
-this.type=syntax_1.Syntax.YieldExpression;
-this.argument=argument;
-this.delegate=delegate;
-}
-return YieldExpression;
-}();
-exports.YieldExpression=YieldExpression;
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-var assert_1=__webpack_require__(9);
-var error_handler_1=__webpack_require__(10);
-var messages_1=__webpack_require__(11);
-var Node=__webpack_require__(7);
-var scanner_1=__webpack_require__(12);
-var syntax_1=__webpack_require__(2);
-var token_1=__webpack_require__(13);
-var ArrowParameterPlaceHolder='ArrowParameterPlaceHolder';
-var Parser=function(){
-function Parser(code,options,delegate){
-if(options===void 0){options={};}
-this.config={
-range:typeof options.range==='boolean'&&options.range,
-loc:typeof options.loc==='boolean'&&options.loc,
-source:null,
-tokens:typeof options.tokens==='boolean'&&options.tokens,
-comment:typeof options.comment==='boolean'&&options.comment,
-tolerant:typeof options.tolerant==='boolean'&&options.tolerant};
-
-if(this.config.loc&&options.source&&options.source!==null){
-this.config.source=String(options.source);
-}
-this.delegate=delegate;
-this.errorHandler=new error_handler_1.ErrorHandler();
-this.errorHandler.tolerant=this.config.tolerant;
-this.scanner=new scanner_1.Scanner(code,this.errorHandler);
-this.scanner.trackComment=this.config.comment;
-this.operatorPrecedence={
-')':0,
-';':0,
-',':0,
-'=':0,
-']':0,
-'||':1,
-'&&':2,
-'|':3,
-'^':4,
-'&':5,
-'==':6,
-'!=':6,
-'===':6,
-'!==':6,
-'<':7,
-'>':7,
-'<=':7,
-'>=':7,
-'<<':8,
-'>>':8,
-'>>>':8,
-'+':9,
-'-':9,
-'*':11,
-'/':11,
-'%':11};
-
-this.lookahead={
-type:2,
-value:'',
-lineNumber:this.scanner.lineNumber,
-lineStart:0,
-start:0,
-end:0};
-
-this.hasLineTerminator=false;
-this.context={
-isModule:false,
-await:false,
-allowIn:true,
-allowStrictDirective:true,
-allowYield:true,
-firstCoverInitializedNameError:null,
-isAssignmentTarget:false,
-isBindingElement:false,
-inFunctionBody:false,
-inIteration:false,
-inSwitch:false,
-labelSet:{},
-strict:false};
-
-this.tokens=[];
-this.startMarker={
-index:0,
-line:this.scanner.lineNumber,
-column:0};
-
-this.lastMarker={
-index:0,
-line:this.scanner.lineNumber,
-column:0};
-
-this.nextToken();
-this.lastMarker={
-index:this.scanner.index,
-line:this.scanner.lineNumber,
-column:this.scanner.index-this.scanner.lineStart};
-
-}
-Parser.prototype.throwError=function(messageFormat){
-var values=[];
-for(var _i=1;_i<arguments.length;_i++){
-values[_i-1]=arguments[_i];
-}
-var args=Array.prototype.slice.call(arguments,1);
-var msg=messageFormat.replace(/%(\d)/g,function(whole,idx){
-assert_1.assert(idx<args.length,'Message reference must be in range');
-return args[idx];
-});
-var index=this.lastMarker.index;
-var line=this.lastMarker.line;
-var column=this.lastMarker.column+1;
-throw this.errorHandler.createError(index,line,column,msg);
-};
-Parser.prototype.tolerateError=function(messageFormat){
-var values=[];
-for(var _i=1;_i<arguments.length;_i++){
-values[_i-1]=arguments[_i];
-}
-var args=Array.prototype.slice.call(arguments,1);
-var msg=messageFormat.replace(/%(\d)/g,function(whole,idx){
-assert_1.assert(idx<args.length,'Message reference must be in range');
-return args[idx];
-});
-var index=this.lastMarker.index;
-var line=this.scanner.lineNumber;
-var column=this.lastMarker.column+1;
-this.errorHandler.tolerateError(index,line,column,msg);
-};
-
-Parser.prototype.unexpectedTokenError=function(token,message){
-var msg=message||messages_1.Messages.UnexpectedToken;
-var value;
-if(token){
-if(!message){
-msg=token.type===2?messages_1.Messages.UnexpectedEOS:
-token.type===3?messages_1.Messages.UnexpectedIdentifier:
-token.type===6?messages_1.Messages.UnexpectedNumber:
-token.type===8?messages_1.Messages.UnexpectedString:
-token.type===10?messages_1.Messages.UnexpectedTemplate:
-messages_1.Messages.UnexpectedToken;
-if(token.type===4){
-if(this.scanner.isFutureReservedWord(token.value)){
-msg=messages_1.Messages.UnexpectedReserved;
-}else
-if(this.context.strict&&this.scanner.isStrictModeReservedWord(token.value)){
-msg=messages_1.Messages.StrictReservedWord;
-}
-}
-}
-value=token.value;
-}else
-{
-value='ILLEGAL';
-}
-msg=msg.replace('%0',value);
-if(token&&typeof token.lineNumber==='number'){
-var index=token.start;
-var line=token.lineNumber;
-var lastMarkerLineStart=this.lastMarker.index-this.lastMarker.column;
-var column=token.start-lastMarkerLineStart+1;
-return this.errorHandler.createError(index,line,column,msg);
-}else
-{
-var index=this.lastMarker.index;
-var line=this.lastMarker.line;
-var column=this.lastMarker.column+1;
-return this.errorHandler.createError(index,line,column,msg);
-}
-};
-Parser.prototype.throwUnexpectedToken=function(token,message){
-throw this.unexpectedTokenError(token,message);
-};
-Parser.prototype.tolerateUnexpectedToken=function(token,message){
-this.errorHandler.tolerate(this.unexpectedTokenError(token,message));
-};
-Parser.prototype.collectComments=function(){
-if(!this.config.comment){
-this.scanner.scanComments();
-}else
-{
-var comments=this.scanner.scanComments();
-if(comments.length>0&&this.delegate){
-for(var i=0;i<comments.length;++i){
-var e=comments[i];
-var node=void 0;
-node={
-type:e.multiLine?'BlockComment':'LineComment',
-value:this.scanner.source.slice(e.slice[0],e.slice[1])};
-
-if(this.config.range){
-node.range=e.range;
-}
-if(this.config.loc){
-node.loc=e.loc;
-}
-var metadata={
-start:{
-line:e.loc.start.line,
-column:e.loc.start.column,
-offset:e.range[0]},
-
-end:{
-line:e.loc.end.line,
-column:e.loc.end.column,
-offset:e.range[1]}};
-
-
-this.delegate(node,metadata);
-}
-}
-}
-};
-
-Parser.prototype.getTokenRaw=function(token){
-return this.scanner.source.slice(token.start,token.end);
-};
-Parser.prototype.convertToken=function(token){
-var t={
-type:token_1.TokenName[token.type],
-value:this.getTokenRaw(token)};
-
-if(this.config.range){
-t.range=[token.start,token.end];
-}
-if(this.config.loc){
-t.loc={
-start:{
-line:this.startMarker.line,
-column:this.startMarker.column},
-
-end:{
-line:this.scanner.lineNumber,
-column:this.scanner.index-this.scanner.lineStart}};
-
-
-}
-if(token.type===9){
-var pattern=token.pattern;
-var flags=token.flags;
-t.regex={pattern:pattern,flags:flags};
-}
-return t;
-};
-Parser.prototype.nextToken=function(){
-var token=this.lookahead;
-this.lastMarker.index=this.scanner.index;
-this.lastMarker.line=this.scanner.lineNumber;
-this.lastMarker.column=this.scanner.index-this.scanner.lineStart;
-this.collectComments();
-if(this.scanner.index!==this.startMarker.index){
-this.startMarker.index=this.scanner.index;
-this.startMarker.line=this.scanner.lineNumber;
-this.startMarker.column=this.scanner.index-this.scanner.lineStart;
-}
-var next=this.scanner.lex();
-this.hasLineTerminator=token.lineNumber!==next.lineNumber;
-if(next&&this.context.strict&&next.type===3){
-if(this.scanner.isStrictModeReservedWord(next.value)){
-next.type=4;
-}
-}
-this.lookahead=next;
-if(this.config.tokens&&next.type!==2){
-this.tokens.push(this.convertToken(next));
-}
-return token;
-};
-Parser.prototype.nextRegexToken=function(){
-this.collectComments();
-var token=this.scanner.scanRegExp();
-if(this.config.tokens){
-
-
-this.tokens.pop();
-this.tokens.push(this.convertToken(token));
-}
-
-this.lookahead=token;
-this.nextToken();
-return token;
-};
-Parser.prototype.createNode=function(){
-return{
-index:this.startMarker.index,
-line:this.startMarker.line,
-column:this.startMarker.column};
-
-};
-Parser.prototype.startNode=function(token){
-return{
-index:token.start,
-line:token.lineNumber,
-column:token.start-token.lineStart};
-
-};
-Parser.prototype.finalize=function(marker,node){
-if(this.config.range){
-node.range=[marker.index,this.lastMarker.index];
-}
-if(this.config.loc){
-node.loc={
-start:{
-line:marker.line,
-column:marker.column},
-
-end:{
-line:this.lastMarker.line,
-column:this.lastMarker.column}};
-
-
-if(this.config.source){
-node.loc.source=this.config.source;
-}
-}
-if(this.delegate){
-var metadata={
-start:{
-line:marker.line,
-column:marker.column,
-offset:marker.index},
-
-end:{
-line:this.lastMarker.line,
-column:this.lastMarker.column,
-offset:this.lastMarker.index}};
-
-
-this.delegate(node,metadata);
-}
-return node;
-};
-
-
-Parser.prototype.expect=function(value){
-var token=this.nextToken();
-if(token.type!==7||token.value!==value){
-this.throwUnexpectedToken(token);
-}
-};
-
-Parser.prototype.expectCommaSeparator=function(){
-if(this.config.tolerant){
-var token=this.lookahead;
-if(token.type===7&&token.value===','){
-this.nextToken();
-}else
-if(token.type===7&&token.value===';'){
-this.nextToken();
-this.tolerateUnexpectedToken(token);
-}else
-{
-this.tolerateUnexpectedToken(token,messages_1.Messages.UnexpectedToken);
-}
-}else
-{
-this.expect(',');
-}
-};
-
-
-Parser.prototype.expectKeyword=function(keyword){
-var token=this.nextToken();
-if(token.type!==4||token.value!==keyword){
-this.throwUnexpectedToken(token);
-}
-};
-
-Parser.prototype.match=function(value){
-return this.lookahead.type===7&&this.lookahead.value===value;
-};
-
-Parser.prototype.matchKeyword=function(keyword){
-return this.lookahead.type===4&&this.lookahead.value===keyword;
-};
-
-
-Parser.prototype.matchContextualKeyword=function(keyword){
-return this.lookahead.type===3&&this.lookahead.value===keyword;
-};
-
-Parser.prototype.matchAssign=function(){
-if(this.lookahead.type!==7){
-return false;
-}
-var op=this.lookahead.value;
-return op==='='||
-op==='*='||
-op==='**='||
-op==='/='||
-op==='%='||
-op==='+='||
-op==='-='||
-op==='<<='||
-op==='>>='||
-op==='>>>='||
-op==='&='||
-op==='^='||
-op==='|=';
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Parser.prototype.isolateCoverGrammar=function(parseFunction){
-var previousIsBindingElement=this.context.isBindingElement;
-var previousIsAssignmentTarget=this.context.isAssignmentTarget;
-var previousFirstCoverInitializedNameError=this.context.firstCoverInitializedNameError;
-this.context.isBindingElement=true;
-this.context.isAssignmentTarget=true;
-this.context.firstCoverInitializedNameError=null;
-var result=parseFunction.call(this);
-if(this.context.firstCoverInitializedNameError!==null){
-this.throwUnexpectedToken(this.context.firstCoverInitializedNameError);
-}
-this.context.isBindingElement=previousIsBindingElement;
-this.context.isAssignmentTarget=previousIsAssignmentTarget;
-this.context.firstCoverInitializedNameError=previousFirstCoverInitializedNameError;
-return result;
-};
-Parser.prototype.inheritCoverGrammar=function(parseFunction){
-var previousIsBindingElement=this.context.isBindingElement;
-var previousIsAssignmentTarget=this.context.isAssignmentTarget;
-var previousFirstCoverInitializedNameError=this.context.firstCoverInitializedNameError;
-this.context.isBindingElement=true;
-this.context.isAssignmentTarget=true;
-this.context.firstCoverInitializedNameError=null;
-var result=parseFunction.call(this);
-this.context.isBindingElement=this.context.isBindingElement&&previousIsBindingElement;
-this.context.isAssignmentTarget=this.context.isAssignmentTarget&&previousIsAssignmentTarget;
-this.context.firstCoverInitializedNameError=previousFirstCoverInitializedNameError||this.context.firstCoverInitializedNameError;
-return result;
-};
-Parser.prototype.consumeSemicolon=function(){
-if(this.match(';')){
-this.nextToken();
-}else
-if(!this.hasLineTerminator){
-if(this.lookahead.type!==2&&!this.match('}')){
-this.throwUnexpectedToken(this.lookahead);
-}
-this.lastMarker.index=this.startMarker.index;
-this.lastMarker.line=this.startMarker.line;
-this.lastMarker.column=this.startMarker.column;
-}
-};
-
-Parser.prototype.parsePrimaryExpression=function(){
-var node=this.createNode();
-var expr;
-var token,raw;
-switch(this.lookahead.type){
-case 3:
-if((this.context.isModule||this.context.await)&&this.lookahead.value==='await'){
-this.tolerateUnexpectedToken(this.lookahead);
-}
-expr=this.matchAsyncFunction()?this.parseFunctionExpression():this.finalize(node,new Node.Identifier(this.nextToken().value));
-break;
-case 6:
-case 8:
-if(this.context.strict&&this.lookahead.octal){
-this.tolerateUnexpectedToken(this.lookahead,messages_1.Messages.StrictOctalLiteral);
-}
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-token=this.nextToken();
-raw=this.getTokenRaw(token);
-expr=this.finalize(node,new Node.Literal(token.value,raw));
-break;
-case 1:
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-token=this.nextToken();
-raw=this.getTokenRaw(token);
-expr=this.finalize(node,new Node.Literal(token.value==='true',raw));
-break;
-case 5:
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-token=this.nextToken();
-raw=this.getTokenRaw(token);
-expr=this.finalize(node,new Node.Literal(null,raw));
-break;
-case 10:
-expr=this.parseTemplateLiteral();
-break;
-case 7:
-switch(this.lookahead.value){
-case'(':
-this.context.isBindingElement=false;
-expr=this.inheritCoverGrammar(this.parseGroupExpression);
-break;
-case'[':
-expr=this.inheritCoverGrammar(this.parseArrayInitializer);
-break;
-case'{':
-expr=this.inheritCoverGrammar(this.parseObjectInitializer);
-break;
-case'/':
-case'/=':
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-this.scanner.index=this.startMarker.index;
-token=this.nextRegexToken();
-raw=this.getTokenRaw(token);
-expr=this.finalize(node,new Node.RegexLiteral(token.regex,raw,token.pattern,token.flags));
-break;
-default:
-expr=this.throwUnexpectedToken(this.nextToken());}
-
-break;
-case 4:
-if(!this.context.strict&&this.context.allowYield&&this.matchKeyword('yield')){
-expr=this.parseIdentifierName();
-}else
-if(!this.context.strict&&this.matchKeyword('let')){
-expr=this.finalize(node,new Node.Identifier(this.nextToken().value));
-}else
-{
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-if(this.matchKeyword('function')){
-expr=this.parseFunctionExpression();
-}else
-if(this.matchKeyword('this')){
-this.nextToken();
-expr=this.finalize(node,new Node.ThisExpression());
-}else
-if(this.matchKeyword('class')){
-expr=this.parseClassExpression();
-}else
-{
-expr=this.throwUnexpectedToken(this.nextToken());
-}
-}
-break;
-default:
-expr=this.throwUnexpectedToken(this.nextToken());}
-
-return expr;
-};
-
-Parser.prototype.parseSpreadElement=function(){
-var node=this.createNode();
-this.expect('...');
-var arg=this.inheritCoverGrammar(this.parseAssignmentExpression);
-return this.finalize(node,new Node.SpreadElement(arg));
-};
-Parser.prototype.parseArrayInitializer=function(){
-var node=this.createNode();
-var elements=[];
-this.expect('[');
-while(!this.match(']')){
-if(this.match(',')){
-this.nextToken();
-elements.push(null);
-}else
-if(this.match('...')){
-var element=this.parseSpreadElement();
-if(!this.match(']')){
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-this.expect(',');
-}
-elements.push(element);
-}else
-{
-elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
-if(!this.match(']')){
-this.expect(',');
-}
-}
-}
-this.expect(']');
-return this.finalize(node,new Node.ArrayExpression(elements));
-};
-
-Parser.prototype.parsePropertyMethod=function(params){
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-var previousStrict=this.context.strict;
-var previousAllowStrictDirective=this.context.allowStrictDirective;
-this.context.allowStrictDirective=params.simple;
-var body=this.isolateCoverGrammar(this.parseFunctionSourceElements);
-if(this.context.strict&&params.firstRestricted){
-this.tolerateUnexpectedToken(params.firstRestricted,params.message);
-}
-if(this.context.strict&&params.stricted){
-this.tolerateUnexpectedToken(params.stricted,params.message);
-}
-this.context.strict=previousStrict;
-this.context.allowStrictDirective=previousAllowStrictDirective;
-return body;
-};
-Parser.prototype.parsePropertyMethodFunction=function(){
-var isGenerator=false;
-var node=this.createNode();
-var previousAllowYield=this.context.allowYield;
-this.context.allowYield=false;
-var params=this.parseFormalParameters();
-var method=this.parsePropertyMethod(params);
-this.context.allowYield=previousAllowYield;
-return this.finalize(node,new Node.FunctionExpression(null,params.params,method,isGenerator));
-};
-Parser.prototype.parsePropertyMethodAsyncFunction=function(){
-var node=this.createNode();
-var previousAllowYield=this.context.allowYield;
-var previousAwait=this.context.await;
-this.context.allowYield=false;
-this.context.await=true;
-var params=this.parseFormalParameters();
-var method=this.parsePropertyMethod(params);
-this.context.allowYield=previousAllowYield;
-this.context.await=previousAwait;
-return this.finalize(node,new Node.AsyncFunctionExpression(null,params.params,method));
-};
-Parser.prototype.parseObjectPropertyKey=function(){
-var node=this.createNode();
-var token=this.nextToken();
-var key;
-switch(token.type){
-case 8:
-case 6:
-if(this.context.strict&&token.octal){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictOctalLiteral);
-}
-var raw=this.getTokenRaw(token);
-key=this.finalize(node,new Node.Literal(token.value,raw));
-break;
-case 3:
-case 1:
-case 5:
-case 4:
-key=this.finalize(node,new Node.Identifier(token.value));
-break;
-case 7:
-if(token.value==='['){
-key=this.isolateCoverGrammar(this.parseAssignmentExpression);
-this.expect(']');
-}else
-{
-key=this.throwUnexpectedToken(token);
-}
-break;
-default:
-key=this.throwUnexpectedToken(token);}
-
-return key;
-};
-Parser.prototype.isPropertyKey=function(key,value){
-return key.type===syntax_1.Syntax.Identifier&&key.name===value||
-key.type===syntax_1.Syntax.Literal&&key.value===value;
-};
-Parser.prototype.parseObjectProperty=function(hasProto){
-var node=this.createNode();
-var token=this.lookahead;
-var kind;
-var key=null;
-var value=null;
-var computed=false;
-var method=false;
-var shorthand=false;
-var isAsync=false;
-if(token.type===3){
-var id=token.value;
-this.nextToken();
-computed=this.match('[');
-isAsync=!this.hasLineTerminator&&id==='async'&&
-!this.match(':')&&!this.match('(')&&!this.match('*');
-key=isAsync?this.parseObjectPropertyKey():this.finalize(node,new Node.Identifier(id));
-}else
-if(this.match('*')){
-this.nextToken();
-}else
-{
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-}
-var lookaheadPropertyKey=this.qualifiedPropertyName(this.lookahead);
-if(token.type===3&&!isAsync&&token.value==='get'&&lookaheadPropertyKey){
-kind='get';
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-this.context.allowYield=false;
-value=this.parseGetterMethod();
-}else
-if(token.type===3&&!isAsync&&token.value==='set'&&lookaheadPropertyKey){
-kind='set';
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-value=this.parseSetterMethod();
-}else
-if(token.type===7&&token.value==='*'&&lookaheadPropertyKey){
-kind='init';
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-value=this.parseGeneratorMethod();
-method=true;
-}else
-{
-if(!key){
-this.throwUnexpectedToken(this.lookahead);
-}
-kind='init';
-if(this.match(':')&&!isAsync){
-if(!computed&&this.isPropertyKey(key,'__proto__')){
-if(hasProto.value){
-this.tolerateError(messages_1.Messages.DuplicateProtoProperty);
-}
-hasProto.value=true;
-}
-this.nextToken();
-value=this.inheritCoverGrammar(this.parseAssignmentExpression);
-}else
-if(this.match('(')){
-value=isAsync?this.parsePropertyMethodAsyncFunction():this.parsePropertyMethodFunction();
-method=true;
-}else
-if(token.type===3){
-var id=this.finalize(node,new Node.Identifier(token.value));
-if(this.match('=')){
-this.context.firstCoverInitializedNameError=this.lookahead;
-this.nextToken();
-shorthand=true;
-var init=this.isolateCoverGrammar(this.parseAssignmentExpression);
-value=this.finalize(node,new Node.AssignmentPattern(id,init));
-}else
-{
-shorthand=true;
-value=id;
-}
-}else
-{
-this.throwUnexpectedToken(this.nextToken());
-}
-}
-return this.finalize(node,new Node.Property(kind,key,computed,value,method,shorthand));
-};
-Parser.prototype.parseObjectInitializer=function(){
-var node=this.createNode();
-this.expect('{');
-var properties=[];
-var hasProto={value:false};
-while(!this.match('}')){
-properties.push(this.parseObjectProperty(hasProto));
-if(!this.match('}')){
-this.expectCommaSeparator();
-}
-}
-this.expect('}');
-return this.finalize(node,new Node.ObjectExpression(properties));
-};
-
-Parser.prototype.parseTemplateHead=function(){
-assert_1.assert(this.lookahead.head,'Template literal must start with a template head');
-var node=this.createNode();
-var token=this.nextToken();
-var raw=token.value;
-var cooked=token.cooked;
-return this.finalize(node,new Node.TemplateElement({raw:raw,cooked:cooked},token.tail));
-};
-Parser.prototype.parseTemplateElement=function(){
-if(this.lookahead.type!==10){
-this.throwUnexpectedToken();
-}
-var node=this.createNode();
-var token=this.nextToken();
-var raw=token.value;
-var cooked=token.cooked;
-return this.finalize(node,new Node.TemplateElement({raw:raw,cooked:cooked},token.tail));
-};
-Parser.prototype.parseTemplateLiteral=function(){
-var node=this.createNode();
-var expressions=[];
-var quasis=[];
-var quasi=this.parseTemplateHead();
-quasis.push(quasi);
-while(!quasi.tail){
-expressions.push(this.parseExpression());
-quasi=this.parseTemplateElement();
-quasis.push(quasi);
-}
-return this.finalize(node,new Node.TemplateLiteral(quasis,expressions));
-};
-
-Parser.prototype.reinterpretExpressionAsPattern=function(expr){
-switch(expr.type){
-case syntax_1.Syntax.Identifier:
-case syntax_1.Syntax.MemberExpression:
-case syntax_1.Syntax.RestElement:
-case syntax_1.Syntax.AssignmentPattern:
-break;
-case syntax_1.Syntax.SpreadElement:
-expr.type=syntax_1.Syntax.RestElement;
-this.reinterpretExpressionAsPattern(expr.argument);
-break;
-case syntax_1.Syntax.ArrayExpression:
-expr.type=syntax_1.Syntax.ArrayPattern;
-for(var i=0;i<expr.elements.length;i++){
-if(expr.elements[i]!==null){
-this.reinterpretExpressionAsPattern(expr.elements[i]);
-}
-}
-break;
-case syntax_1.Syntax.ObjectExpression:
-expr.type=syntax_1.Syntax.ObjectPattern;
-for(var i=0;i<expr.properties.length;i++){
-this.reinterpretExpressionAsPattern(expr.properties[i].value);
-}
-break;
-case syntax_1.Syntax.AssignmentExpression:
-expr.type=syntax_1.Syntax.AssignmentPattern;
-delete expr.operator;
-this.reinterpretExpressionAsPattern(expr.left);
-break;
-default:
-
-break;}
-
-};
-Parser.prototype.parseGroupExpression=function(){
-var expr;
-this.expect('(');
-if(this.match(')')){
-this.nextToken();
-if(!this.match('=>')){
-this.expect('=>');
-}
-expr={
-type:ArrowParameterPlaceHolder,
-params:[],
-async:false};
-
-}else
-{
-var startToken=this.lookahead;
-var params=[];
-if(this.match('...')){
-expr=this.parseRestElement(params);
-this.expect(')');
-if(!this.match('=>')){
-this.expect('=>');
-}
-expr={
-type:ArrowParameterPlaceHolder,
-params:[expr],
-async:false};
-
-}else
-{
-var arrow=false;
-this.context.isBindingElement=true;
-expr=this.inheritCoverGrammar(this.parseAssignmentExpression);
-if(this.match(',')){
-var expressions=[];
-this.context.isAssignmentTarget=false;
-expressions.push(expr);
-while(this.lookahead.type!==2){
-if(!this.match(',')){
-break;
-}
-this.nextToken();
-if(this.match(')')){
-this.nextToken();
-for(var i=0;i<expressions.length;i++){
-this.reinterpretExpressionAsPattern(expressions[i]);
-}
-arrow=true;
-expr={
-type:ArrowParameterPlaceHolder,
-params:expressions,
-async:false};
-
-}else
-if(this.match('...')){
-if(!this.context.isBindingElement){
-this.throwUnexpectedToken(this.lookahead);
-}
-expressions.push(this.parseRestElement(params));
-this.expect(')');
-if(!this.match('=>')){
-this.expect('=>');
-}
-this.context.isBindingElement=false;
-for(var i=0;i<expressions.length;i++){
-this.reinterpretExpressionAsPattern(expressions[i]);
-}
-arrow=true;
-expr={
-type:ArrowParameterPlaceHolder,
-params:expressions,
-async:false};
-
-}else
-{
-expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression));
-}
-if(arrow){
-break;
-}
-}
-if(!arrow){
-expr=this.finalize(this.startNode(startToken),new Node.SequenceExpression(expressions));
-}
-}
-if(!arrow){
-this.expect(')');
-if(this.match('=>')){
-if(expr.type===syntax_1.Syntax.Identifier&&expr.name==='yield'){
-arrow=true;
-expr={
-type:ArrowParameterPlaceHolder,
-params:[expr],
-async:false};
-
-}
-if(!arrow){
-if(!this.context.isBindingElement){
-this.throwUnexpectedToken(this.lookahead);
-}
-if(expr.type===syntax_1.Syntax.SequenceExpression){
-for(var i=0;i<expr.expressions.length;i++){
-this.reinterpretExpressionAsPattern(expr.expressions[i]);
-}
-}else
-{
-this.reinterpretExpressionAsPattern(expr);
-}
-var parameters=expr.type===syntax_1.Syntax.SequenceExpression?expr.expressions:[expr];
-expr={
-type:ArrowParameterPlaceHolder,
-params:parameters,
-async:false};
-
-}
-}
-this.context.isBindingElement=false;
-}
-}
-}
-return expr;
-};
-
-Parser.prototype.parseArguments=function(){
-this.expect('(');
-var args=[];
-if(!this.match(')')){
-while(true){
-var expr=this.match('...')?this.parseSpreadElement():
-this.isolateCoverGrammar(this.parseAssignmentExpression);
-args.push(expr);
-if(this.match(')')){
-break;
-}
-this.expectCommaSeparator();
-if(this.match(')')){
-break;
-}
-}
-}
-this.expect(')');
-return args;
-};
-Parser.prototype.isIdentifierName=function(token){
-return token.type===3||
-token.type===4||
-token.type===1||
-token.type===5;
-};
-Parser.prototype.parseIdentifierName=function(){
-var node=this.createNode();
-var token=this.nextToken();
-if(!this.isIdentifierName(token)){
-this.throwUnexpectedToken(token);
-}
-return this.finalize(node,new Node.Identifier(token.value));
-};
-Parser.prototype.parseNewExpression=function(){
-var node=this.createNode();
-var id=this.parseIdentifierName();
-assert_1.assert(id.name==='new','New expression must start with `new`');
-var expr;
-if(this.match('.')){
-this.nextToken();
-if(this.lookahead.type===3&&this.context.inFunctionBody&&this.lookahead.value==='target'){
-var property=this.parseIdentifierName();
-expr=new Node.MetaProperty(id,property);
-}else
-{
-this.throwUnexpectedToken(this.lookahead);
-}
-}else
-{
-var callee=this.isolateCoverGrammar(this.parseLeftHandSideExpression);
-var args=this.match('(')?this.parseArguments():[];
-expr=new Node.NewExpression(callee,args);
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-}
-return this.finalize(node,expr);
-};
-Parser.prototype.parseAsyncArgument=function(){
-var arg=this.parseAssignmentExpression();
-this.context.firstCoverInitializedNameError=null;
-return arg;
-};
-Parser.prototype.parseAsyncArguments=function(){
-this.expect('(');
-var args=[];
-if(!this.match(')')){
-while(true){
-var expr=this.match('...')?this.parseSpreadElement():
-this.isolateCoverGrammar(this.parseAsyncArgument);
-args.push(expr);
-if(this.match(')')){
-break;
-}
-this.expectCommaSeparator();
-if(this.match(')')){
-break;
-}
-}
-}
-this.expect(')');
-return args;
-};
-Parser.prototype.parseLeftHandSideExpressionAllowCall=function(){
-var startToken=this.lookahead;
-var maybeAsync=this.matchContextualKeyword('async');
-var previousAllowIn=this.context.allowIn;
-this.context.allowIn=true;
-var expr;
-if(this.matchKeyword('super')&&this.context.inFunctionBody){
-expr=this.createNode();
-this.nextToken();
-expr=this.finalize(expr,new Node.Super());
-if(!this.match('(')&&!this.match('.')&&!this.match('[')){
-this.throwUnexpectedToken(this.lookahead);
-}
-}else
-{
-expr=this.inheritCoverGrammar(this.matchKeyword('new')?this.parseNewExpression:this.parsePrimaryExpression);
-}
-while(true){
-if(this.match('.')){
-this.context.isBindingElement=false;
-this.context.isAssignmentTarget=true;
-this.expect('.');
-var property=this.parseIdentifierName();
-expr=this.finalize(this.startNode(startToken),new Node.StaticMemberExpression(expr,property));
-}else
-if(this.match('(')){
-var asyncArrow=maybeAsync&&startToken.lineNumber===this.lookahead.lineNumber;
-this.context.isBindingElement=false;
-this.context.isAssignmentTarget=false;
-var args=asyncArrow?this.parseAsyncArguments():this.parseArguments();
-expr=this.finalize(this.startNode(startToken),new Node.CallExpression(expr,args));
-if(asyncArrow&&this.match('=>')){
-for(var i=0;i<args.length;++i){
-this.reinterpretExpressionAsPattern(args[i]);
-}
-expr={
-type:ArrowParameterPlaceHolder,
-params:args,
-async:true};
-
-}
-}else
-if(this.match('[')){
-this.context.isBindingElement=false;
-this.context.isAssignmentTarget=true;
-this.expect('[');
-var property=this.isolateCoverGrammar(this.parseExpression);
-this.expect(']');
-expr=this.finalize(this.startNode(startToken),new Node.ComputedMemberExpression(expr,property));
-}else
-if(this.lookahead.type===10&&this.lookahead.head){
-var quasi=this.parseTemplateLiteral();
-expr=this.finalize(this.startNode(startToken),new Node.TaggedTemplateExpression(expr,quasi));
-}else
-{
-break;
-}
-}
-this.context.allowIn=previousAllowIn;
-return expr;
-};
-Parser.prototype.parseSuper=function(){
-var node=this.createNode();
-this.expectKeyword('super');
-if(!this.match('[')&&!this.match('.')){
-this.throwUnexpectedToken(this.lookahead);
-}
-return this.finalize(node,new Node.Super());
-};
-Parser.prototype.parseLeftHandSideExpression=function(){
-assert_1.assert(this.context.allowIn,'callee of new expression always allow in keyword.');
-var node=this.startNode(this.lookahead);
-var expr=this.matchKeyword('super')&&this.context.inFunctionBody?this.parseSuper():
-this.inheritCoverGrammar(this.matchKeyword('new')?this.parseNewExpression:this.parsePrimaryExpression);
-while(true){
-if(this.match('[')){
-this.context.isBindingElement=false;
-this.context.isAssignmentTarget=true;
-this.expect('[');
-var property=this.isolateCoverGrammar(this.parseExpression);
-this.expect(']');
-expr=this.finalize(node,new Node.ComputedMemberExpression(expr,property));
-}else
-if(this.match('.')){
-this.context.isBindingElement=false;
-this.context.isAssignmentTarget=true;
-this.expect('.');
-var property=this.parseIdentifierName();
-expr=this.finalize(node,new Node.StaticMemberExpression(expr,property));
-}else
-if(this.lookahead.type===10&&this.lookahead.head){
-var quasi=this.parseTemplateLiteral();
-expr=this.finalize(node,new Node.TaggedTemplateExpression(expr,quasi));
-}else
-{
-break;
-}
-}
-return expr;
-};
-
-Parser.prototype.parseUpdateExpression=function(){
-var expr;
-var startToken=this.lookahead;
-if(this.match('++')||this.match('--')){
-var node=this.startNode(startToken);
-var token=this.nextToken();
-expr=this.inheritCoverGrammar(this.parseUnaryExpression);
-if(this.context.strict&&expr.type===syntax_1.Syntax.Identifier&&this.scanner.isRestrictedWord(expr.name)){
-this.tolerateError(messages_1.Messages.StrictLHSPrefix);
-}
-if(!this.context.isAssignmentTarget){
-this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
-}
-var prefix=true;
-expr=this.finalize(node,new Node.UpdateExpression(token.value,expr,prefix));
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-}else
-{
-expr=this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
-if(!this.hasLineTerminator&&this.lookahead.type===7){
-if(this.match('++')||this.match('--')){
-if(this.context.strict&&expr.type===syntax_1.Syntax.Identifier&&this.scanner.isRestrictedWord(expr.name)){
-this.tolerateError(messages_1.Messages.StrictLHSPostfix);
-}
-if(!this.context.isAssignmentTarget){
-this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
-}
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-var operator=this.nextToken().value;
-var prefix=false;
-expr=this.finalize(this.startNode(startToken),new Node.UpdateExpression(operator,expr,prefix));
-}
-}
-}
-return expr;
-};
-
-Parser.prototype.parseAwaitExpression=function(){
-var node=this.createNode();
-this.nextToken();
-var argument=this.parseUnaryExpression();
-return this.finalize(node,new Node.AwaitExpression(argument));
-};
-Parser.prototype.parseUnaryExpression=function(){
-var expr;
-if(this.match('+')||this.match('-')||this.match('~')||this.match('!')||
-this.matchKeyword('delete')||this.matchKeyword('void')||this.matchKeyword('typeof')){
-var node=this.startNode(this.lookahead);
-var token=this.nextToken();
-expr=this.inheritCoverGrammar(this.parseUnaryExpression);
-expr=this.finalize(node,new Node.UnaryExpression(token.value,expr));
-if(this.context.strict&&expr.operator==='delete'&&expr.argument.type===syntax_1.Syntax.Identifier){
-this.tolerateError(messages_1.Messages.StrictDelete);
-}
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-}else
-if(this.context.await&&this.matchContextualKeyword('await')){
-expr=this.parseAwaitExpression();
-}else
-{
-expr=this.parseUpdateExpression();
-}
-return expr;
-};
-Parser.prototype.parseExponentiationExpression=function(){
-var startToken=this.lookahead;
-var expr=this.inheritCoverGrammar(this.parseUnaryExpression);
-if(expr.type!==syntax_1.Syntax.UnaryExpression&&this.match('**')){
-this.nextToken();
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-var left=expr;
-var right=this.isolateCoverGrammar(this.parseExponentiationExpression);
-expr=this.finalize(this.startNode(startToken),new Node.BinaryExpression('**',left,right));
-}
-return expr;
-};
-
-
-
-
-
-
-
-
-Parser.prototype.binaryPrecedence=function(token){
-var op=token.value;
-var precedence;
-if(token.type===7){
-precedence=this.operatorPrecedence[op]||0;
-}else
-if(token.type===4){
-precedence=op==='instanceof'||this.context.allowIn&&op==='in'?7:0;
-}else
-{
-precedence=0;
-}
-return precedence;
-};
-Parser.prototype.parseBinaryExpression=function(){
-var startToken=this.lookahead;
-var expr=this.inheritCoverGrammar(this.parseExponentiationExpression);
-var token=this.lookahead;
-var prec=this.binaryPrecedence(token);
-if(prec>0){
-this.nextToken();
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-var markers=[startToken,this.lookahead];
-var left=expr;
-var right=this.isolateCoverGrammar(this.parseExponentiationExpression);
-var stack=[left,token.value,right];
-var precedences=[prec];
-while(true){
-prec=this.binaryPrecedence(this.lookahead);
-if(prec<=0){
-break;
-}
-
-while(stack.length>2&&prec<=precedences[precedences.length-1]){
-right=stack.pop();
-var operator=stack.pop();
-precedences.pop();
-left=stack.pop();
-markers.pop();
-var node=this.startNode(markers[markers.length-1]);
-stack.push(this.finalize(node,new Node.BinaryExpression(operator,left,right)));
-}
-
-stack.push(this.nextToken().value);
-precedences.push(prec);
-markers.push(this.lookahead);
-stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression));
-}
-
-var i=stack.length-1;
-expr=stack[i];
-markers.pop();
-while(i>1){
-var node=this.startNode(markers.pop());
-var operator=stack[i-1];
-expr=this.finalize(node,new Node.BinaryExpression(operator,stack[i-2],expr));
-i-=2;
-}
-}
-return expr;
-};
-
-Parser.prototype.parseConditionalExpression=function(){
-var startToken=this.lookahead;
-var expr=this.inheritCoverGrammar(this.parseBinaryExpression);
-if(this.match('?')){
-this.nextToken();
-var previousAllowIn=this.context.allowIn;
-this.context.allowIn=true;
-var consequent=this.isolateCoverGrammar(this.parseAssignmentExpression);
-this.context.allowIn=previousAllowIn;
-this.expect(':');
-var alternate=this.isolateCoverGrammar(this.parseAssignmentExpression);
-expr=this.finalize(this.startNode(startToken),new Node.ConditionalExpression(expr,consequent,alternate));
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-}
-return expr;
-};
-
-Parser.prototype.checkPatternParam=function(options,param){
-switch(param.type){
-case syntax_1.Syntax.Identifier:
-this.validateParam(options,param,param.name);
-break;
-case syntax_1.Syntax.RestElement:
-this.checkPatternParam(options,param.argument);
-break;
-case syntax_1.Syntax.AssignmentPattern:
-this.checkPatternParam(options,param.left);
-break;
-case syntax_1.Syntax.ArrayPattern:
-for(var i=0;i<param.elements.length;i++){
-if(param.elements[i]!==null){
-this.checkPatternParam(options,param.elements[i]);
-}
-}
-break;
-case syntax_1.Syntax.ObjectPattern:
-for(var i=0;i<param.properties.length;i++){
-this.checkPatternParam(options,param.properties[i].value);
-}
-break;
-default:
-break;}
-
-options.simple=options.simple&&param instanceof Node.Identifier;
-};
-Parser.prototype.reinterpretAsCoverFormalsList=function(expr){
-var params=[expr];
-var options;
-var asyncArrow=false;
-switch(expr.type){
-case syntax_1.Syntax.Identifier:
-break;
-case ArrowParameterPlaceHolder:
-params=expr.params;
-asyncArrow=expr.async;
-break;
-default:
-return null;}
-
-options={
-simple:true,
-paramSet:{}};
-
-for(var i=0;i<params.length;++i){
-var param=params[i];
-if(param.type===syntax_1.Syntax.AssignmentPattern){
-if(param.right.type===syntax_1.Syntax.YieldExpression){
-if(param.right.argument){
-this.throwUnexpectedToken(this.lookahead);
-}
-param.right.type=syntax_1.Syntax.Identifier;
-param.right.name='yield';
-delete param.right.argument;
-delete param.right.delegate;
-}
-}else
-if(asyncArrow&&param.type===syntax_1.Syntax.Identifier&&param.name==='await'){
-this.throwUnexpectedToken(this.lookahead);
-}
-this.checkPatternParam(options,param);
-params[i]=param;
-}
-if(this.context.strict||!this.context.allowYield){
-for(var i=0;i<params.length;++i){
-var param=params[i];
-if(param.type===syntax_1.Syntax.YieldExpression){
-this.throwUnexpectedToken(this.lookahead);
-}
-}
-}
-if(options.message===messages_1.Messages.StrictParamDupe){
-var token=this.context.strict?options.stricted:options.firstRestricted;
-this.throwUnexpectedToken(token,options.message);
-}
-return{
-simple:options.simple,
-params:params,
-stricted:options.stricted,
-firstRestricted:options.firstRestricted,
-message:options.message};
-
-};
-Parser.prototype.parseAssignmentExpression=function(){
-var expr;
-if(!this.context.allowYield&&this.matchKeyword('yield')){
-expr=this.parseYieldExpression();
-}else
-{
-var startToken=this.lookahead;
-var token=startToken;
-expr=this.parseConditionalExpression();
-if(token.type===3&&token.lineNumber===this.lookahead.lineNumber&&token.value==='async'){
-if(this.lookahead.type===3||this.matchKeyword('yield')){
-var arg=this.parsePrimaryExpression();
-this.reinterpretExpressionAsPattern(arg);
-expr={
-type:ArrowParameterPlaceHolder,
-params:[arg],
-async:true};
-
-}
-}
-if(expr.type===ArrowParameterPlaceHolder||this.match('=>')){
-
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-var isAsync=expr.async;
-var list=this.reinterpretAsCoverFormalsList(expr);
-if(list){
-if(this.hasLineTerminator){
-this.tolerateUnexpectedToken(this.lookahead);
-}
-this.context.firstCoverInitializedNameError=null;
-var previousStrict=this.context.strict;
-var previousAllowStrictDirective=this.context.allowStrictDirective;
-this.context.allowStrictDirective=list.simple;
-var previousAllowYield=this.context.allowYield;
-var previousAwait=this.context.await;
-this.context.allowYield=true;
-this.context.await=isAsync;
-var node=this.startNode(startToken);
-this.expect('=>');
-var body=void 0;
-if(this.match('{')){
-var previousAllowIn=this.context.allowIn;
-this.context.allowIn=true;
-body=this.parseFunctionSourceElements();
-this.context.allowIn=previousAllowIn;
-}else
-{
-body=this.isolateCoverGrammar(this.parseAssignmentExpression);
-}
-var expression=body.type!==syntax_1.Syntax.BlockStatement;
-if(this.context.strict&&list.firstRestricted){
-this.throwUnexpectedToken(list.firstRestricted,list.message);
-}
-if(this.context.strict&&list.stricted){
-this.tolerateUnexpectedToken(list.stricted,list.message);
-}
-expr=isAsync?this.finalize(node,new Node.AsyncArrowFunctionExpression(list.params,body,expression)):
-this.finalize(node,new Node.ArrowFunctionExpression(list.params,body,expression));
-this.context.strict=previousStrict;
-this.context.allowStrictDirective=previousAllowStrictDirective;
-this.context.allowYield=previousAllowYield;
-this.context.await=previousAwait;
-}
-}else
-{
-if(this.matchAssign()){
-if(!this.context.isAssignmentTarget){
-this.tolerateError(messages_1.Messages.InvalidLHSInAssignment);
-}
-if(this.context.strict&&expr.type===syntax_1.Syntax.Identifier){
-var id=expr;
-if(this.scanner.isRestrictedWord(id.name)){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictLHSAssignment);
-}
-if(this.scanner.isStrictModeReservedWord(id.name)){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictReservedWord);
-}
-}
-if(!this.match('=')){
-this.context.isAssignmentTarget=false;
-this.context.isBindingElement=false;
-}else
-{
-this.reinterpretExpressionAsPattern(expr);
-}
-token=this.nextToken();
-var operator=token.value;
-var right=this.isolateCoverGrammar(this.parseAssignmentExpression);
-expr=this.finalize(this.startNode(startToken),new Node.AssignmentExpression(operator,expr,right));
-this.context.firstCoverInitializedNameError=null;
-}
-}
-}
-return expr;
-};
-
-Parser.prototype.parseExpression=function(){
-var startToken=this.lookahead;
-var expr=this.isolateCoverGrammar(this.parseAssignmentExpression);
-if(this.match(',')){
-var expressions=[];
-expressions.push(expr);
-while(this.lookahead.type!==2){
-if(!this.match(',')){
-break;
-}
-this.nextToken();
-expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
-}
-expr=this.finalize(this.startNode(startToken),new Node.SequenceExpression(expressions));
-}
-return expr;
-};
-
-Parser.prototype.parseStatementListItem=function(){
-var statement;
-this.context.isAssignmentTarget=true;
-this.context.isBindingElement=true;
-if(this.lookahead.type===4){
-switch(this.lookahead.value){
-case'export':
-if(!this.context.isModule){
-this.tolerateUnexpectedToken(this.lookahead,messages_1.Messages.IllegalExportDeclaration);
-}
-statement=this.parseExportDeclaration();
-break;
-case'import':
-if(!this.context.isModule){
-this.tolerateUnexpectedToken(this.lookahead,messages_1.Messages.IllegalImportDeclaration);
-}
-statement=this.parseImportDeclaration();
-break;
-case'const':
-statement=this.parseLexicalDeclaration({inFor:false});
-break;
-case'function':
-statement=this.parseFunctionDeclaration();
-break;
-case'class':
-statement=this.parseClassDeclaration();
-break;
-case'let':
-statement=this.isLexicalDeclaration()?this.parseLexicalDeclaration({inFor:false}):this.parseStatement();
-break;
-default:
-statement=this.parseStatement();
-break;}
-
-}else
-{
-statement=this.parseStatement();
-}
-return statement;
-};
-Parser.prototype.parseBlock=function(){
-var node=this.createNode();
-this.expect('{');
-var block=[];
-while(true){
-if(this.match('}')){
-break;
-}
-block.push(this.parseStatementListItem());
-}
-this.expect('}');
-return this.finalize(node,new Node.BlockStatement(block));
-};
-
-Parser.prototype.parseLexicalBinding=function(kind,options){
-var node=this.createNode();
-var params=[];
-var id=this.parsePattern(params,kind);
-if(this.context.strict&&id.type===syntax_1.Syntax.Identifier){
-if(this.scanner.isRestrictedWord(id.name)){
-this.tolerateError(messages_1.Messages.StrictVarName);
-}
-}
-var init=null;
-if(kind==='const'){
-if(!this.matchKeyword('in')&&!this.matchContextualKeyword('of')){
-if(this.match('=')){
-this.nextToken();
-init=this.isolateCoverGrammar(this.parseAssignmentExpression);
-}else
-{
-this.throwError(messages_1.Messages.DeclarationMissingInitializer,'const');
-}
-}
-}else
-if(!options.inFor&&id.type!==syntax_1.Syntax.Identifier||this.match('=')){
-this.expect('=');
-init=this.isolateCoverGrammar(this.parseAssignmentExpression);
-}
-return this.finalize(node,new Node.VariableDeclarator(id,init));
-};
-Parser.prototype.parseBindingList=function(kind,options){
-var list=[this.parseLexicalBinding(kind,options)];
-while(this.match(',')){
-this.nextToken();
-list.push(this.parseLexicalBinding(kind,options));
-}
-return list;
-};
-Parser.prototype.isLexicalDeclaration=function(){
-var state=this.scanner.saveState();
-this.scanner.scanComments();
-var next=this.scanner.lex();
-this.scanner.restoreState(state);
-return next.type===3||
-next.type===7&&next.value==='['||
-next.type===7&&next.value==='{'||
-next.type===4&&next.value==='let'||
-next.type===4&&next.value==='yield';
-};
-Parser.prototype.parseLexicalDeclaration=function(options){
-var node=this.createNode();
-var kind=this.nextToken().value;
-assert_1.assert(kind==='let'||kind==='const','Lexical declaration must be either let or const');
-var declarations=this.parseBindingList(kind,options);
-this.consumeSemicolon();
-return this.finalize(node,new Node.VariableDeclaration(declarations,kind));
-};
-
-Parser.prototype.parseBindingRestElement=function(params,kind){
-var node=this.createNode();
-this.expect('...');
-var arg=this.parsePattern(params,kind);
-return this.finalize(node,new Node.RestElement(arg));
-};
-Parser.prototype.parseArrayPattern=function(params,kind){
-var node=this.createNode();
-this.expect('[');
-var elements=[];
-while(!this.match(']')){
-if(this.match(',')){
-this.nextToken();
-elements.push(null);
-}else
-{
-if(this.match('...')){
-elements.push(this.parseBindingRestElement(params,kind));
-break;
-}else
-{
-elements.push(this.parsePatternWithDefault(params,kind));
-}
-if(!this.match(']')){
-this.expect(',');
-}
-}
-}
-this.expect(']');
-return this.finalize(node,new Node.ArrayPattern(elements));
-};
-Parser.prototype.parsePropertyPattern=function(params,kind){
-var node=this.createNode();
-var computed=false;
-var shorthand=false;
-var method=false;
-var key;
-var value;
-if(this.lookahead.type===3){
-var keyToken=this.lookahead;
-key=this.parseVariableIdentifier();
-var init=this.finalize(node,new Node.Identifier(keyToken.value));
-if(this.match('=')){
-params.push(keyToken);
-shorthand=true;
-this.nextToken();
-var expr=this.parseAssignmentExpression();
-value=this.finalize(this.startNode(keyToken),new Node.AssignmentPattern(init,expr));
-}else
-if(!this.match(':')){
-params.push(keyToken);
-shorthand=true;
-value=init;
-}else
-{
-this.expect(':');
-value=this.parsePatternWithDefault(params,kind);
-}
-}else
-{
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-this.expect(':');
-value=this.parsePatternWithDefault(params,kind);
-}
-return this.finalize(node,new Node.Property('init',key,computed,value,method,shorthand));
-};
-Parser.prototype.parseObjectPattern=function(params,kind){
-var node=this.createNode();
-var properties=[];
-this.expect('{');
-while(!this.match('}')){
-properties.push(this.parsePropertyPattern(params,kind));
-if(!this.match('}')){
-this.expect(',');
-}
-}
-this.expect('}');
-return this.finalize(node,new Node.ObjectPattern(properties));
-};
-Parser.prototype.parsePattern=function(params,kind){
-var pattern;
-if(this.match('[')){
-pattern=this.parseArrayPattern(params,kind);
-}else
-if(this.match('{')){
-pattern=this.parseObjectPattern(params,kind);
-}else
-{
-if(this.matchKeyword('let')&&(kind==='const'||kind==='let')){
-this.tolerateUnexpectedToken(this.lookahead,messages_1.Messages.LetInLexicalBinding);
-}
-params.push(this.lookahead);
-pattern=this.parseVariableIdentifier(kind);
-}
-return pattern;
-};
-Parser.prototype.parsePatternWithDefault=function(params,kind){
-var startToken=this.lookahead;
-var pattern=this.parsePattern(params,kind);
-if(this.match('=')){
-this.nextToken();
-var previousAllowYield=this.context.allowYield;
-this.context.allowYield=true;
-var right=this.isolateCoverGrammar(this.parseAssignmentExpression);
-this.context.allowYield=previousAllowYield;
-pattern=this.finalize(this.startNode(startToken),new Node.AssignmentPattern(pattern,right));
-}
-return pattern;
-};
-
-Parser.prototype.parseVariableIdentifier=function(kind){
-var node=this.createNode();
-var token=this.nextToken();
-if(token.type===4&&token.value==='yield'){
-if(this.context.strict){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictReservedWord);
-}else
-if(!this.context.allowYield){
-this.throwUnexpectedToken(token);
-}
-}else
-if(token.type!==3){
-if(this.context.strict&&token.type===4&&this.scanner.isStrictModeReservedWord(token.value)){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictReservedWord);
-}else
-{
-if(this.context.strict||token.value!=='let'||kind!=='var'){
-this.throwUnexpectedToken(token);
-}
-}
-}else
-if((this.context.isModule||this.context.await)&&token.type===3&&token.value==='await'){
-this.tolerateUnexpectedToken(token);
-}
-return this.finalize(node,new Node.Identifier(token.value));
-};
-Parser.prototype.parseVariableDeclaration=function(options){
-var node=this.createNode();
-var params=[];
-var id=this.parsePattern(params,'var');
-if(this.context.strict&&id.type===syntax_1.Syntax.Identifier){
-if(this.scanner.isRestrictedWord(id.name)){
-this.tolerateError(messages_1.Messages.StrictVarName);
-}
-}
-var init=null;
-if(this.match('=')){
-this.nextToken();
-init=this.isolateCoverGrammar(this.parseAssignmentExpression);
-}else
-if(id.type!==syntax_1.Syntax.Identifier&&!options.inFor){
-this.expect('=');
-}
-return this.finalize(node,new Node.VariableDeclarator(id,init));
-};
-Parser.prototype.parseVariableDeclarationList=function(options){
-var opt={inFor:options.inFor};
-var list=[];
-list.push(this.parseVariableDeclaration(opt));
-while(this.match(',')){
-this.nextToken();
-list.push(this.parseVariableDeclaration(opt));
-}
-return list;
-};
-Parser.prototype.parseVariableStatement=function(){
-var node=this.createNode();
-this.expectKeyword('var');
-var declarations=this.parseVariableDeclarationList({inFor:false});
-this.consumeSemicolon();
-return this.finalize(node,new Node.VariableDeclaration(declarations,'var'));
-};
-
-Parser.prototype.parseEmptyStatement=function(){
-var node=this.createNode();
-this.expect(';');
-return this.finalize(node,new Node.EmptyStatement());
-};
-
-Parser.prototype.parseExpressionStatement=function(){
-var node=this.createNode();
-var expr=this.parseExpression();
-this.consumeSemicolon();
-return this.finalize(node,new Node.ExpressionStatement(expr));
-};
-
-Parser.prototype.parseIfClause=function(){
-if(this.context.strict&&this.matchKeyword('function')){
-this.tolerateError(messages_1.Messages.StrictFunction);
-}
-return this.parseStatement();
-};
-Parser.prototype.parseIfStatement=function(){
-var node=this.createNode();
-var consequent;
-var alternate=null;
-this.expectKeyword('if');
-this.expect('(');
-var test=this.parseExpression();
-if(!this.match(')')&&this.config.tolerant){
-this.tolerateUnexpectedToken(this.nextToken());
-consequent=this.finalize(this.createNode(),new Node.EmptyStatement());
-}else
-{
-this.expect(')');
-consequent=this.parseIfClause();
-if(this.matchKeyword('else')){
-this.nextToken();
-alternate=this.parseIfClause();
-}
-}
-return this.finalize(node,new Node.IfStatement(test,consequent,alternate));
-};
-
-Parser.prototype.parseDoWhileStatement=function(){
-var node=this.createNode();
-this.expectKeyword('do');
-var previousInIteration=this.context.inIteration;
-this.context.inIteration=true;
-var body=this.parseStatement();
-this.context.inIteration=previousInIteration;
-this.expectKeyword('while');
-this.expect('(');
-var test=this.parseExpression();
-if(!this.match(')')&&this.config.tolerant){
-this.tolerateUnexpectedToken(this.nextToken());
-}else
-{
-this.expect(')');
-if(this.match(';')){
-this.nextToken();
-}
-}
-return this.finalize(node,new Node.DoWhileStatement(body,test));
-};
-
-Parser.prototype.parseWhileStatement=function(){
-var node=this.createNode();
-var body;
-this.expectKeyword('while');
-this.expect('(');
-var test=this.parseExpression();
-if(!this.match(')')&&this.config.tolerant){
-this.tolerateUnexpectedToken(this.nextToken());
-body=this.finalize(this.createNode(),new Node.EmptyStatement());
-}else
-{
-this.expect(')');
-var previousInIteration=this.context.inIteration;
-this.context.inIteration=true;
-body=this.parseStatement();
-this.context.inIteration=previousInIteration;
-}
-return this.finalize(node,new Node.WhileStatement(test,body));
-};
-
-
-Parser.prototype.parseForStatement=function(){
-var init=null;
-var test=null;
-var update=null;
-var forIn=true;
-var left,right;
-var node=this.createNode();
-this.expectKeyword('for');
-this.expect('(');
-if(this.match(';')){
-this.nextToken();
-}else
-{
-if(this.matchKeyword('var')){
-init=this.createNode();
-this.nextToken();
-var previousAllowIn=this.context.allowIn;
-this.context.allowIn=false;
-var declarations=this.parseVariableDeclarationList({inFor:true});
-this.context.allowIn=previousAllowIn;
-if(declarations.length===1&&this.matchKeyword('in')){
-var decl=declarations[0];
-if(decl.init&&(decl.id.type===syntax_1.Syntax.ArrayPattern||decl.id.type===syntax_1.Syntax.ObjectPattern||this.context.strict)){
-this.tolerateError(messages_1.Messages.ForInOfLoopInitializer,'for-in');
-}
-init=this.finalize(init,new Node.VariableDeclaration(declarations,'var'));
-this.nextToken();
-left=init;
-right=this.parseExpression();
-init=null;
-}else
-if(declarations.length===1&&declarations[0].init===null&&this.matchContextualKeyword('of')){
-init=this.finalize(init,new Node.VariableDeclaration(declarations,'var'));
-this.nextToken();
-left=init;
-right=this.parseAssignmentExpression();
-init=null;
-forIn=false;
-}else
-{
-init=this.finalize(init,new Node.VariableDeclaration(declarations,'var'));
-this.expect(';');
-}
-}else
-if(this.matchKeyword('const')||this.matchKeyword('let')){
-init=this.createNode();
-var kind=this.nextToken().value;
-if(!this.context.strict&&this.lookahead.value==='in'){
-init=this.finalize(init,new Node.Identifier(kind));
-this.nextToken();
-left=init;
-right=this.parseExpression();
-init=null;
-}else
-{
-var previousAllowIn=this.context.allowIn;
-this.context.allowIn=false;
-var declarations=this.parseBindingList(kind,{inFor:true});
-this.context.allowIn=previousAllowIn;
-if(declarations.length===1&&declarations[0].init===null&&this.matchKeyword('in')){
-init=this.finalize(init,new Node.VariableDeclaration(declarations,kind));
-this.nextToken();
-left=init;
-right=this.parseExpression();
-init=null;
-}else
-if(declarations.length===1&&declarations[0].init===null&&this.matchContextualKeyword('of')){
-init=this.finalize(init,new Node.VariableDeclaration(declarations,kind));
-this.nextToken();
-left=init;
-right=this.parseAssignmentExpression();
-init=null;
-forIn=false;
-}else
-{
-this.consumeSemicolon();
-init=this.finalize(init,new Node.VariableDeclaration(declarations,kind));
-}
-}
-}else
-{
-var initStartToken=this.lookahead;
-var previousAllowIn=this.context.allowIn;
-this.context.allowIn=false;
-init=this.inheritCoverGrammar(this.parseAssignmentExpression);
-this.context.allowIn=previousAllowIn;
-if(this.matchKeyword('in')){
-if(!this.context.isAssignmentTarget||init.type===syntax_1.Syntax.AssignmentExpression){
-this.tolerateError(messages_1.Messages.InvalidLHSInForIn);
-}
-this.nextToken();
-this.reinterpretExpressionAsPattern(init);
-left=init;
-right=this.parseExpression();
-init=null;
-}else
-if(this.matchContextualKeyword('of')){
-if(!this.context.isAssignmentTarget||init.type===syntax_1.Syntax.AssignmentExpression){
-this.tolerateError(messages_1.Messages.InvalidLHSInForLoop);
-}
-this.nextToken();
-this.reinterpretExpressionAsPattern(init);
-left=init;
-right=this.parseAssignmentExpression();
-init=null;
-forIn=false;
-}else
-{
-if(this.match(',')){
-var initSeq=[init];
-while(this.match(',')){
-this.nextToken();
-initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression));
-}
-init=this.finalize(this.startNode(initStartToken),new Node.SequenceExpression(initSeq));
-}
-this.expect(';');
-}
-}
-}
-if(typeof left==='undefined'){
-if(!this.match(';')){
-test=this.parseExpression();
-}
-this.expect(';');
-if(!this.match(')')){
-update=this.parseExpression();
-}
-}
-var body;
-if(!this.match(')')&&this.config.tolerant){
-this.tolerateUnexpectedToken(this.nextToken());
-body=this.finalize(this.createNode(),new Node.EmptyStatement());
-}else
-{
-this.expect(')');
-var previousInIteration=this.context.inIteration;
-this.context.inIteration=true;
-body=this.isolateCoverGrammar(this.parseStatement);
-this.context.inIteration=previousInIteration;
-}
-return typeof left==='undefined'?
-this.finalize(node,new Node.ForStatement(init,test,update,body)):
-forIn?this.finalize(node,new Node.ForInStatement(left,right,body)):
-this.finalize(node,new Node.ForOfStatement(left,right,body));
-};
-
-Parser.prototype.parseContinueStatement=function(){
-var node=this.createNode();
-this.expectKeyword('continue');
-var label=null;
-if(this.lookahead.type===3&&!this.hasLineTerminator){
-var id=this.parseVariableIdentifier();
-label=id;
-var key='$'+id.name;
-if(!Object.prototype.hasOwnProperty.call(this.context.labelSet,key)){
-this.throwError(messages_1.Messages.UnknownLabel,id.name);
-}
-}
-this.consumeSemicolon();
-if(label===null&&!this.context.inIteration){
-this.throwError(messages_1.Messages.IllegalContinue);
-}
-return this.finalize(node,new Node.ContinueStatement(label));
-};
-
-Parser.prototype.parseBreakStatement=function(){
-var node=this.createNode();
-this.expectKeyword('break');
-var label=null;
-if(this.lookahead.type===3&&!this.hasLineTerminator){
-var id=this.parseVariableIdentifier();
-var key='$'+id.name;
-if(!Object.prototype.hasOwnProperty.call(this.context.labelSet,key)){
-this.throwError(messages_1.Messages.UnknownLabel,id.name);
-}
-label=id;
-}
-this.consumeSemicolon();
-if(label===null&&!this.context.inIteration&&!this.context.inSwitch){
-this.throwError(messages_1.Messages.IllegalBreak);
-}
-return this.finalize(node,new Node.BreakStatement(label));
-};
-
-Parser.prototype.parseReturnStatement=function(){
-if(!this.context.inFunctionBody){
-this.tolerateError(messages_1.Messages.IllegalReturn);
-}
-var node=this.createNode();
-this.expectKeyword('return');
-var hasArgument=!this.match(';')&&!this.match('}')&&
-!this.hasLineTerminator&&this.lookahead.type!==2;
-var argument=hasArgument?this.parseExpression():null;
-this.consumeSemicolon();
-return this.finalize(node,new Node.ReturnStatement(argument));
-};
-
-Parser.prototype.parseWithStatement=function(){
-if(this.context.strict){
-this.tolerateError(messages_1.Messages.StrictModeWith);
-}
-var node=this.createNode();
-var body;
-this.expectKeyword('with');
-this.expect('(');
-var object=this.parseExpression();
-if(!this.match(')')&&this.config.tolerant){
-this.tolerateUnexpectedToken(this.nextToken());
-body=this.finalize(this.createNode(),new Node.EmptyStatement());
-}else
-{
-this.expect(')');
-body=this.parseStatement();
-}
-return this.finalize(node,new Node.WithStatement(object,body));
-};
-
-Parser.prototype.parseSwitchCase=function(){
-var node=this.createNode();
-var test;
-if(this.matchKeyword('default')){
-this.nextToken();
-test=null;
-}else
-{
-this.expectKeyword('case');
-test=this.parseExpression();
-}
-this.expect(':');
-var consequent=[];
-while(true){
-if(this.match('}')||this.matchKeyword('default')||this.matchKeyword('case')){
-break;
-}
-consequent.push(this.parseStatementListItem());
-}
-return this.finalize(node,new Node.SwitchCase(test,consequent));
-};
-Parser.prototype.parseSwitchStatement=function(){
-var node=this.createNode();
-this.expectKeyword('switch');
-this.expect('(');
-var discriminant=this.parseExpression();
-this.expect(')');
-var previousInSwitch=this.context.inSwitch;
-this.context.inSwitch=true;
-var cases=[];
-var defaultFound=false;
-this.expect('{');
-while(true){
-if(this.match('}')){
-break;
-}
-var clause=this.parseSwitchCase();
-if(clause.test===null){
-if(defaultFound){
-this.throwError(messages_1.Messages.MultipleDefaultsInSwitch);
-}
-defaultFound=true;
-}
-cases.push(clause);
-}
-this.expect('}');
-this.context.inSwitch=previousInSwitch;
-return this.finalize(node,new Node.SwitchStatement(discriminant,cases));
-};
-
-Parser.prototype.parseLabelledStatement=function(){
-var node=this.createNode();
-var expr=this.parseExpression();
-var statement;
-if(expr.type===syntax_1.Syntax.Identifier&&this.match(':')){
-this.nextToken();
-var id=expr;
-var key='$'+id.name;
-if(Object.prototype.hasOwnProperty.call(this.context.labelSet,key)){
-this.throwError(messages_1.Messages.Redeclaration,'Label',id.name);
-}
-this.context.labelSet[key]=true;
-var body=void 0;
-if(this.matchKeyword('class')){
-this.tolerateUnexpectedToken(this.lookahead);
-body=this.parseClassDeclaration();
-}else
-if(this.matchKeyword('function')){
-var token=this.lookahead;
-var declaration=this.parseFunctionDeclaration();
-if(this.context.strict){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictFunction);
-}else
-if(declaration.generator){
-this.tolerateUnexpectedToken(token,messages_1.Messages.GeneratorInLegacyContext);
-}
-body=declaration;
-}else
-{
-body=this.parseStatement();
-}
-delete this.context.labelSet[key];
-statement=new Node.LabeledStatement(id,body);
-}else
-{
-this.consumeSemicolon();
-statement=new Node.ExpressionStatement(expr);
-}
-return this.finalize(node,statement);
-};
-
-Parser.prototype.parseThrowStatement=function(){
-var node=this.createNode();
-this.expectKeyword('throw');
-if(this.hasLineTerminator){
-this.throwError(messages_1.Messages.NewlineAfterThrow);
-}
-var argument=this.parseExpression();
-this.consumeSemicolon();
-return this.finalize(node,new Node.ThrowStatement(argument));
-};
-
-Parser.prototype.parseCatchClause=function(){
-var node=this.createNode();
-this.expectKeyword('catch');
-this.expect('(');
-if(this.match(')')){
-this.throwUnexpectedToken(this.lookahead);
-}
-var params=[];
-var param=this.parsePattern(params);
-var paramMap={};
-for(var i=0;i<params.length;i++){
-var key='$'+params[i].value;
-if(Object.prototype.hasOwnProperty.call(paramMap,key)){
-this.tolerateError(messages_1.Messages.DuplicateBinding,params[i].value);
-}
-paramMap[key]=true;
-}
-if(this.context.strict&&param.type===syntax_1.Syntax.Identifier){
-if(this.scanner.isRestrictedWord(param.name)){
-this.tolerateError(messages_1.Messages.StrictCatchVariable);
-}
-}
-this.expect(')');
-var body=this.parseBlock();
-return this.finalize(node,new Node.CatchClause(param,body));
-};
-Parser.prototype.parseFinallyClause=function(){
-this.expectKeyword('finally');
-return this.parseBlock();
-};
-Parser.prototype.parseTryStatement=function(){
-var node=this.createNode();
-this.expectKeyword('try');
-var block=this.parseBlock();
-var handler=this.matchKeyword('catch')?this.parseCatchClause():null;
-var finalizer=this.matchKeyword('finally')?this.parseFinallyClause():null;
-if(!handler&&!finalizer){
-this.throwError(messages_1.Messages.NoCatchOrFinally);
-}
-return this.finalize(node,new Node.TryStatement(block,handler,finalizer));
-};
-
-Parser.prototype.parseDebuggerStatement=function(){
-var node=this.createNode();
-this.expectKeyword('debugger');
-this.consumeSemicolon();
-return this.finalize(node,new Node.DebuggerStatement());
-};
-
-Parser.prototype.parseStatement=function(){
-var statement;
-switch(this.lookahead.type){
-case 1:
-case 5:
-case 6:
-case 8:
-case 10:
-case 9:
-statement=this.parseExpressionStatement();
-break;
-case 7:
-var value=this.lookahead.value;
-if(value==='{'){
-statement=this.parseBlock();
-}else
-if(value==='('){
-statement=this.parseExpressionStatement();
-}else
-if(value===';'){
-statement=this.parseEmptyStatement();
-}else
-{
-statement=this.parseExpressionStatement();
-}
-break;
-case 3:
-statement=this.matchAsyncFunction()?this.parseFunctionDeclaration():this.parseLabelledStatement();
-break;
-case 4:
-switch(this.lookahead.value){
-case'break':
-statement=this.parseBreakStatement();
-break;
-case'continue':
-statement=this.parseContinueStatement();
-break;
-case'debugger':
-statement=this.parseDebuggerStatement();
-break;
-case'do':
-statement=this.parseDoWhileStatement();
-break;
-case'for':
-statement=this.parseForStatement();
-break;
-case'function':
-statement=this.parseFunctionDeclaration();
-break;
-case'if':
-statement=this.parseIfStatement();
-break;
-case'return':
-statement=this.parseReturnStatement();
-break;
-case'switch':
-statement=this.parseSwitchStatement();
-break;
-case'throw':
-statement=this.parseThrowStatement();
-break;
-case'try':
-statement=this.parseTryStatement();
-break;
-case'var':
-statement=this.parseVariableStatement();
-break;
-case'while':
-statement=this.parseWhileStatement();
-break;
-case'with':
-statement=this.parseWithStatement();
-break;
-default:
-statement=this.parseExpressionStatement();
-break;}
-
-break;
-default:
-statement=this.throwUnexpectedToken(this.lookahead);}
-
-return statement;
-};
-
-Parser.prototype.parseFunctionSourceElements=function(){
-var node=this.createNode();
-this.expect('{');
-var body=this.parseDirectivePrologues();
-var previousLabelSet=this.context.labelSet;
-var previousInIteration=this.context.inIteration;
-var previousInSwitch=this.context.inSwitch;
-var previousInFunctionBody=this.context.inFunctionBody;
-this.context.labelSet={};
-this.context.inIteration=false;
-this.context.inSwitch=false;
-this.context.inFunctionBody=true;
-while(this.lookahead.type!==2){
-if(this.match('}')){
-break;
-}
-body.push(this.parseStatementListItem());
-}
-this.expect('}');
-this.context.labelSet=previousLabelSet;
-this.context.inIteration=previousInIteration;
-this.context.inSwitch=previousInSwitch;
-this.context.inFunctionBody=previousInFunctionBody;
-return this.finalize(node,new Node.BlockStatement(body));
-};
-Parser.prototype.validateParam=function(options,param,name){
-var key='$'+name;
-if(this.context.strict){
-if(this.scanner.isRestrictedWord(name)){
-options.stricted=param;
-options.message=messages_1.Messages.StrictParamName;
-}
-if(Object.prototype.hasOwnProperty.call(options.paramSet,key)){
-options.stricted=param;
-options.message=messages_1.Messages.StrictParamDupe;
-}
-}else
-if(!options.firstRestricted){
-if(this.scanner.isRestrictedWord(name)){
-options.firstRestricted=param;
-options.message=messages_1.Messages.StrictParamName;
-}else
-if(this.scanner.isStrictModeReservedWord(name)){
-options.firstRestricted=param;
-options.message=messages_1.Messages.StrictReservedWord;
-}else
-if(Object.prototype.hasOwnProperty.call(options.paramSet,key)){
-options.stricted=param;
-options.message=messages_1.Messages.StrictParamDupe;
-}
-}
-
-if(typeof Object.defineProperty==='function'){
-Object.defineProperty(options.paramSet,key,{value:true,enumerable:true,writable:true,configurable:true});
-}else
-{
-options.paramSet[key]=true;
-}
-};
-Parser.prototype.parseRestElement=function(params){
-var node=this.createNode();
-this.expect('...');
-var arg=this.parsePattern(params);
-if(this.match('=')){
-this.throwError(messages_1.Messages.DefaultRestParameter);
-}
-if(!this.match(')')){
-this.throwError(messages_1.Messages.ParameterAfterRestParameter);
-}
-return this.finalize(node,new Node.RestElement(arg));
-};
-Parser.prototype.parseFormalParameter=function(options){
-var params=[];
-var param=this.match('...')?this.parseRestElement(params):this.parsePatternWithDefault(params);
-for(var i=0;i<params.length;i++){
-this.validateParam(options,params[i],params[i].value);
-}
-options.simple=options.simple&&param instanceof Node.Identifier;
-options.params.push(param);
-};
-Parser.prototype.parseFormalParameters=function(firstRestricted){
-var options;
-options={
-simple:true,
-params:[],
-firstRestricted:firstRestricted};
-
-this.expect('(');
-if(!this.match(')')){
-options.paramSet={};
-while(this.lookahead.type!==2){
-this.parseFormalParameter(options);
-if(this.match(')')){
-break;
-}
-this.expect(',');
-if(this.match(')')){
-break;
-}
-}
-}
-this.expect(')');
-return{
-simple:options.simple,
-params:options.params,
-stricted:options.stricted,
-firstRestricted:options.firstRestricted,
-message:options.message};
-
-};
-Parser.prototype.matchAsyncFunction=function(){
-var match=this.matchContextualKeyword('async');
-if(match){
-var state=this.scanner.saveState();
-this.scanner.scanComments();
-var next=this.scanner.lex();
-this.scanner.restoreState(state);
-match=state.lineNumber===next.lineNumber&&next.type===4&&next.value==='function';
-}
-return match;
-};
-Parser.prototype.parseFunctionDeclaration=function(identifierIsOptional){
-var node=this.createNode();
-var isAsync=this.matchContextualKeyword('async');
-if(isAsync){
-this.nextToken();
-}
-this.expectKeyword('function');
-var isGenerator=isAsync?false:this.match('*');
-if(isGenerator){
-this.nextToken();
-}
-var message;
-var id=null;
-var firstRestricted=null;
-if(!identifierIsOptional||!this.match('(')){
-var token=this.lookahead;
-id=this.parseVariableIdentifier();
-if(this.context.strict){
-if(this.scanner.isRestrictedWord(token.value)){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictFunctionName);
-}
-}else
-{
-if(this.scanner.isRestrictedWord(token.value)){
-firstRestricted=token;
-message=messages_1.Messages.StrictFunctionName;
-}else
-if(this.scanner.isStrictModeReservedWord(token.value)){
-firstRestricted=token;
-message=messages_1.Messages.StrictReservedWord;
-}
-}
-}
-var previousAllowAwait=this.context.await;
-var previousAllowYield=this.context.allowYield;
-this.context.await=isAsync;
-this.context.allowYield=!isGenerator;
-var formalParameters=this.parseFormalParameters(firstRestricted);
-var params=formalParameters.params;
-var stricted=formalParameters.stricted;
-firstRestricted=formalParameters.firstRestricted;
-if(formalParameters.message){
-message=formalParameters.message;
-}
-var previousStrict=this.context.strict;
-var previousAllowStrictDirective=this.context.allowStrictDirective;
-this.context.allowStrictDirective=formalParameters.simple;
-var body=this.parseFunctionSourceElements();
-if(this.context.strict&&firstRestricted){
-this.throwUnexpectedToken(firstRestricted,message);
-}
-if(this.context.strict&&stricted){
-this.tolerateUnexpectedToken(stricted,message);
-}
-this.context.strict=previousStrict;
-this.context.allowStrictDirective=previousAllowStrictDirective;
-this.context.await=previousAllowAwait;
-this.context.allowYield=previousAllowYield;
-return isAsync?this.finalize(node,new Node.AsyncFunctionDeclaration(id,params,body)):
-this.finalize(node,new Node.FunctionDeclaration(id,params,body,isGenerator));
-};
-Parser.prototype.parseFunctionExpression=function(){
-var node=this.createNode();
-var isAsync=this.matchContextualKeyword('async');
-if(isAsync){
-this.nextToken();
-}
-this.expectKeyword('function');
-var isGenerator=isAsync?false:this.match('*');
-if(isGenerator){
-this.nextToken();
-}
-var message;
-var id=null;
-var firstRestricted;
-var previousAllowAwait=this.context.await;
-var previousAllowYield=this.context.allowYield;
-this.context.await=isAsync;
-this.context.allowYield=!isGenerator;
-if(!this.match('(')){
-var token=this.lookahead;
-id=!this.context.strict&&!isGenerator&&this.matchKeyword('yield')?this.parseIdentifierName():this.parseVariableIdentifier();
-if(this.context.strict){
-if(this.scanner.isRestrictedWord(token.value)){
-this.tolerateUnexpectedToken(token,messages_1.Messages.StrictFunctionName);
-}
-}else
-{
-if(this.scanner.isRestrictedWord(token.value)){
-firstRestricted=token;
-message=messages_1.Messages.StrictFunctionName;
-}else
-if(this.scanner.isStrictModeReservedWord(token.value)){
-firstRestricted=token;
-message=messages_1.Messages.StrictReservedWord;
-}
-}
-}
-var formalParameters=this.parseFormalParameters(firstRestricted);
-var params=formalParameters.params;
-var stricted=formalParameters.stricted;
-firstRestricted=formalParameters.firstRestricted;
-if(formalParameters.message){
-message=formalParameters.message;
-}
-var previousStrict=this.context.strict;
-var previousAllowStrictDirective=this.context.allowStrictDirective;
-this.context.allowStrictDirective=formalParameters.simple;
-var body=this.parseFunctionSourceElements();
-if(this.context.strict&&firstRestricted){
-this.throwUnexpectedToken(firstRestricted,message);
-}
-if(this.context.strict&&stricted){
-this.tolerateUnexpectedToken(stricted,message);
-}
-this.context.strict=previousStrict;
-this.context.allowStrictDirective=previousAllowStrictDirective;
-this.context.await=previousAllowAwait;
-this.context.allowYield=previousAllowYield;
-return isAsync?this.finalize(node,new Node.AsyncFunctionExpression(id,params,body)):
-this.finalize(node,new Node.FunctionExpression(id,params,body,isGenerator));
-};
-
-Parser.prototype.parseDirective=function(){
-var token=this.lookahead;
-var node=this.createNode();
-var expr=this.parseExpression();
-var directive=expr.type===syntax_1.Syntax.Literal?this.getTokenRaw(token).slice(1,-1):null;
-this.consumeSemicolon();
-return this.finalize(node,directive?new Node.Directive(expr,directive):new Node.ExpressionStatement(expr));
-};
-Parser.prototype.parseDirectivePrologues=function(){
-var firstRestricted=null;
-var body=[];
-while(true){
-var token=this.lookahead;
-if(token.type!==8){
-break;
-}
-var statement=this.parseDirective();
-body.push(statement);
-var directive=statement.directive;
-if(typeof directive!=='string'){
-break;
-}
-if(directive==='use strict'){
-this.context.strict=true;
-if(firstRestricted){
-this.tolerateUnexpectedToken(firstRestricted,messages_1.Messages.StrictOctalLiteral);
-}
-if(!this.context.allowStrictDirective){
-this.tolerateUnexpectedToken(token,messages_1.Messages.IllegalLanguageModeDirective);
-}
-}else
-{
-if(!firstRestricted&&token.octal){
-firstRestricted=token;
-}
-}
-}
-return body;
-};
-
-Parser.prototype.qualifiedPropertyName=function(token){
-switch(token.type){
-case 3:
-case 8:
-case 1:
-case 5:
-case 6:
-case 4:
-return true;
-case 7:
-return token.value==='[';
-default:
-break;}
-
-return false;
-};
-Parser.prototype.parseGetterMethod=function(){
-var node=this.createNode();
-var isGenerator=false;
-var previousAllowYield=this.context.allowYield;
-this.context.allowYield=false;
-var formalParameters=this.parseFormalParameters();
-if(formalParameters.params.length>0){
-this.tolerateError(messages_1.Messages.BadGetterArity);
-}
-var method=this.parsePropertyMethod(formalParameters);
-this.context.allowYield=previousAllowYield;
-return this.finalize(node,new Node.FunctionExpression(null,formalParameters.params,method,isGenerator));
-};
-Parser.prototype.parseSetterMethod=function(){
-var node=this.createNode();
-var isGenerator=false;
-var previousAllowYield=this.context.allowYield;
-this.context.allowYield=false;
-var formalParameters=this.parseFormalParameters();
-if(formalParameters.params.length!==1){
-this.tolerateError(messages_1.Messages.BadSetterArity);
-}else
-if(formalParameters.params[0]instanceof Node.RestElement){
-this.tolerateError(messages_1.Messages.BadSetterRestParameter);
-}
-var method=this.parsePropertyMethod(formalParameters);
-this.context.allowYield=previousAllowYield;
-return this.finalize(node,new Node.FunctionExpression(null,formalParameters.params,method,isGenerator));
-};
-Parser.prototype.parseGeneratorMethod=function(){
-var node=this.createNode();
-var isGenerator=true;
-var previousAllowYield=this.context.allowYield;
-this.context.allowYield=true;
-var params=this.parseFormalParameters();
-this.context.allowYield=false;
-var method=this.parsePropertyMethod(params);
-this.context.allowYield=previousAllowYield;
-return this.finalize(node,new Node.FunctionExpression(null,params.params,method,isGenerator));
-};
-
-Parser.prototype.isStartOfExpression=function(){
-var start=true;
-var value=this.lookahead.value;
-switch(this.lookahead.type){
-case 7:
-start=value==='['||value==='('||value==='{'||
-value==='+'||value==='-'||
-value==='!'||value==='~'||
-value==='++'||value==='--'||
-value==='/'||value==='/=';
-break;
-case 4:
-start=value==='class'||value==='delete'||
-value==='function'||value==='let'||value==='new'||
-value==='super'||value==='this'||value==='typeof'||
-value==='void'||value==='yield';
-break;
-default:
-break;}
-
-return start;
-};
-Parser.prototype.parseYieldExpression=function(){
-var node=this.createNode();
-this.expectKeyword('yield');
-var argument=null;
-var delegate=false;
-if(!this.hasLineTerminator){
-var previousAllowYield=this.context.allowYield;
-this.context.allowYield=false;
-delegate=this.match('*');
-if(delegate){
-this.nextToken();
-argument=this.parseAssignmentExpression();
-}else
-if(this.isStartOfExpression()){
-argument=this.parseAssignmentExpression();
-}
-this.context.allowYield=previousAllowYield;
-}
-return this.finalize(node,new Node.YieldExpression(argument,delegate));
-};
-
-Parser.prototype.parseClassElement=function(hasConstructor){
-var token=this.lookahead;
-var node=this.createNode();
-var kind='';
-var key=null;
-var value=null;
-var computed=false;
-var method=false;
-var isStatic=false;
-var isAsync=false;
-if(this.match('*')){
-this.nextToken();
-}else
-{
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-var id=key;
-if(id.name==='static'&&(this.qualifiedPropertyName(this.lookahead)||this.match('*'))){
-token=this.lookahead;
-isStatic=true;
-computed=this.match('[');
-if(this.match('*')){
-this.nextToken();
-}else
-{
-key=this.parseObjectPropertyKey();
-}
-}
-if(token.type===3&&!this.hasLineTerminator&&token.value==='async'){
-var punctuator=this.lookahead.value;
-if(punctuator!==':'&&punctuator!=='('&&punctuator!=='*'){
-isAsync=true;
-token=this.lookahead;
-key=this.parseObjectPropertyKey();
-if(token.type===3){
-if(token.value==='get'||token.value==='set'){
-this.tolerateUnexpectedToken(token);
-}else
-if(token.value==='constructor'){
-this.tolerateUnexpectedToken(token,messages_1.Messages.ConstructorIsAsync);
-}
-}
-}
-}
-}
-var lookaheadPropertyKey=this.qualifiedPropertyName(this.lookahead);
-if(token.type===3){
-if(token.value==='get'&&lookaheadPropertyKey){
-kind='get';
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-this.context.allowYield=false;
-value=this.parseGetterMethod();
-}else
-if(token.value==='set'&&lookaheadPropertyKey){
-kind='set';
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-value=this.parseSetterMethod();
-}
-}else
-if(token.type===7&&token.value==='*'&&lookaheadPropertyKey){
-kind='init';
-computed=this.match('[');
-key=this.parseObjectPropertyKey();
-value=this.parseGeneratorMethod();
-method=true;
-}
-if(!kind&&key&&this.match('(')){
-kind='init';
-value=isAsync?this.parsePropertyMethodAsyncFunction():this.parsePropertyMethodFunction();
-method=true;
-}
-if(!kind){
-this.throwUnexpectedToken(this.lookahead);
-}
-if(kind==='init'){
-kind='method';
-}
-if(!computed){
-if(isStatic&&this.isPropertyKey(key,'prototype')){
-this.throwUnexpectedToken(token,messages_1.Messages.StaticPrototype);
-}
-if(!isStatic&&this.isPropertyKey(key,'constructor')){
-if(kind!=='method'||!method||value&&value.generator){
-this.throwUnexpectedToken(token,messages_1.Messages.ConstructorSpecialMethod);
-}
-if(hasConstructor.value){
-this.throwUnexpectedToken(token,messages_1.Messages.DuplicateConstructor);
-}else
-{
-hasConstructor.value=true;
-}
-kind='constructor';
-}
-}
-return this.finalize(node,new Node.MethodDefinition(key,computed,value,kind,isStatic));
-};
-Parser.prototype.parseClassElementList=function(){
-var body=[];
-var hasConstructor={value:false};
-this.expect('{');
-while(!this.match('}')){
-if(this.match(';')){
-this.nextToken();
-}else
-{
-body.push(this.parseClassElement(hasConstructor));
-}
-}
-this.expect('}');
-return body;
-};
-Parser.prototype.parseClassBody=function(){
-var node=this.createNode();
-var elementList=this.parseClassElementList();
-return this.finalize(node,new Node.ClassBody(elementList));
-};
-Parser.prototype.parseClassDeclaration=function(identifierIsOptional){
-var node=this.createNode();
-var previousStrict=this.context.strict;
-this.context.strict=true;
-this.expectKeyword('class');
-var id=identifierIsOptional&&this.lookahead.type!==3?null:this.parseVariableIdentifier();
-var superClass=null;
-if(this.matchKeyword('extends')){
-this.nextToken();
-superClass=this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
-}
-var classBody=this.parseClassBody();
-this.context.strict=previousStrict;
-return this.finalize(node,new Node.ClassDeclaration(id,superClass,classBody));
-};
-Parser.prototype.parseClassExpression=function(){
-var node=this.createNode();
-var previousStrict=this.context.strict;
-this.context.strict=true;
-this.expectKeyword('class');
-var id=this.lookahead.type===3?this.parseVariableIdentifier():null;
-var superClass=null;
-if(this.matchKeyword('extends')){
-this.nextToken();
-superClass=this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall);
-}
-var classBody=this.parseClassBody();
-this.context.strict=previousStrict;
-return this.finalize(node,new Node.ClassExpression(id,superClass,classBody));
-};
-
-
-Parser.prototype.parseModule=function(){
-this.context.strict=true;
-this.context.isModule=true;
-var node=this.createNode();
-var body=this.parseDirectivePrologues();
-while(this.lookahead.type!==2){
-body.push(this.parseStatementListItem());
-}
-return this.finalize(node,new Node.Module(body));
-};
-Parser.prototype.parseScript=function(){
-var node=this.createNode();
-var body=this.parseDirectivePrologues();
-while(this.lookahead.type!==2){
-body.push(this.parseStatementListItem());
-}
-return this.finalize(node,new Node.Script(body));
-};
-
-Parser.prototype.parseModuleSpecifier=function(){
-var node=this.createNode();
-if(this.lookahead.type!==8){
-this.throwError(messages_1.Messages.InvalidModuleSpecifier);
-}
-var token=this.nextToken();
-var raw=this.getTokenRaw(token);
-return this.finalize(node,new Node.Literal(token.value,raw));
-};
-
-Parser.prototype.parseImportSpecifier=function(){
-var node=this.createNode();
-var imported;
-var local;
-if(this.lookahead.type===3){
-imported=this.parseVariableIdentifier();
-local=imported;
-if(this.matchContextualKeyword('as')){
-this.nextToken();
-local=this.parseVariableIdentifier();
-}
-}else
-{
-imported=this.parseIdentifierName();
-local=imported;
-if(this.matchContextualKeyword('as')){
-this.nextToken();
-local=this.parseVariableIdentifier();
-}else
-{
-this.throwUnexpectedToken(this.nextToken());
-}
-}
-return this.finalize(node,new Node.ImportSpecifier(local,imported));
-};
-
-Parser.prototype.parseNamedImports=function(){
-this.expect('{');
-var specifiers=[];
-while(!this.match('}')){
-specifiers.push(this.parseImportSpecifier());
-if(!this.match('}')){
-this.expect(',');
-}
-}
-this.expect('}');
-return specifiers;
-};
-
-Parser.prototype.parseImportDefaultSpecifier=function(){
-var node=this.createNode();
-var local=this.parseIdentifierName();
-return this.finalize(node,new Node.ImportDefaultSpecifier(local));
-};
-
-Parser.prototype.parseImportNamespaceSpecifier=function(){
-var node=this.createNode();
-this.expect('*');
-if(!this.matchContextualKeyword('as')){
-this.throwError(messages_1.Messages.NoAsAfterImportNamespace);
-}
-this.nextToken();
-var local=this.parseIdentifierName();
-return this.finalize(node,new Node.ImportNamespaceSpecifier(local));
-};
-Parser.prototype.parseImportDeclaration=function(){
-if(this.context.inFunctionBody){
-this.throwError(messages_1.Messages.IllegalImportDeclaration);
-}
-var node=this.createNode();
-this.expectKeyword('import');
-var src;
-var specifiers=[];
-if(this.lookahead.type===8){
-
-src=this.parseModuleSpecifier();
-}else
-{
-if(this.match('{')){
-
-specifiers=specifiers.concat(this.parseNamedImports());
-}else
-if(this.match('*')){
-
-specifiers.push(this.parseImportNamespaceSpecifier());
-}else
-if(this.isIdentifierName(this.lookahead)&&!this.matchKeyword('default')){
-
-specifiers.push(this.parseImportDefaultSpecifier());
-if(this.match(',')){
-this.nextToken();
-if(this.match('*')){
-
-specifiers.push(this.parseImportNamespaceSpecifier());
-}else
-if(this.match('{')){
-
-specifiers=specifiers.concat(this.parseNamedImports());
-}else
-{
-this.throwUnexpectedToken(this.lookahead);
-}
-}
-}else
-{
-this.throwUnexpectedToken(this.nextToken());
-}
-if(!this.matchContextualKeyword('from')){
-var message=this.lookahead.value?messages_1.Messages.UnexpectedToken:messages_1.Messages.MissingFromClause;
-this.throwError(message,this.lookahead.value);
-}
-this.nextToken();
-src=this.parseModuleSpecifier();
-}
-this.consumeSemicolon();
-return this.finalize(node,new Node.ImportDeclaration(specifiers,src));
-};
-
-Parser.prototype.parseExportSpecifier=function(){
-var node=this.createNode();
-var local=this.parseIdentifierName();
-var exported=local;
-if(this.matchContextualKeyword('as')){
-this.nextToken();
-exported=this.parseIdentifierName();
-}
-return this.finalize(node,new Node.ExportSpecifier(local,exported));
-};
-Parser.prototype.parseExportDeclaration=function(){
-if(this.context.inFunctionBody){
-this.throwError(messages_1.Messages.IllegalExportDeclaration);
-}
-var node=this.createNode();
-this.expectKeyword('export');
-var exportDeclaration;
-if(this.matchKeyword('default')){
-
-this.nextToken();
-if(this.matchKeyword('function')){
-
-
-var declaration=this.parseFunctionDeclaration(true);
-exportDeclaration=this.finalize(node,new Node.ExportDefaultDeclaration(declaration));
-}else
-if(this.matchKeyword('class')){
-
-var declaration=this.parseClassDeclaration(true);
-exportDeclaration=this.finalize(node,new Node.ExportDefaultDeclaration(declaration));
-}else
-if(this.matchContextualKeyword('async')){
-
-
-
-var declaration=this.matchAsyncFunction()?this.parseFunctionDeclaration(true):this.parseAssignmentExpression();
-exportDeclaration=this.finalize(node,new Node.ExportDefaultDeclaration(declaration));
-}else
-{
-if(this.matchContextualKeyword('from')){
-this.throwError(messages_1.Messages.UnexpectedToken,this.lookahead.value);
-}
-
-
-
-var declaration=this.match('{')?this.parseObjectInitializer():
-this.match('[')?this.parseArrayInitializer():this.parseAssignmentExpression();
-this.consumeSemicolon();
-exportDeclaration=this.finalize(node,new Node.ExportDefaultDeclaration(declaration));
-}
-}else
-if(this.match('*')){
-
-this.nextToken();
-if(!this.matchContextualKeyword('from')){
-var message=this.lookahead.value?messages_1.Messages.UnexpectedToken:messages_1.Messages.MissingFromClause;
-this.throwError(message,this.lookahead.value);
-}
-this.nextToken();
-var src=this.parseModuleSpecifier();
-this.consumeSemicolon();
-exportDeclaration=this.finalize(node,new Node.ExportAllDeclaration(src));
-}else
-if(this.lookahead.type===4){
-
-var declaration=void 0;
-switch(this.lookahead.value){
-case'let':
-case'const':
-declaration=this.parseLexicalDeclaration({inFor:false});
-break;
-case'var':
-case'class':
-case'function':
-declaration=this.parseStatementListItem();
-break;
-default:
-this.throwUnexpectedToken(this.lookahead);}
-
-exportDeclaration=this.finalize(node,new Node.ExportNamedDeclaration(declaration,[],null));
-}else
-if(this.matchAsyncFunction()){
-var declaration=this.parseFunctionDeclaration();
-exportDeclaration=this.finalize(node,new Node.ExportNamedDeclaration(declaration,[],null));
-}else
-{
-var specifiers=[];
-var source=null;
-var isExportFromIdentifier=false;
-this.expect('{');
-while(!this.match('}')){
-isExportFromIdentifier=isExportFromIdentifier||this.matchKeyword('default');
-specifiers.push(this.parseExportSpecifier());
-if(!this.match('}')){
-this.expect(',');
-}
-}
-this.expect('}');
-if(this.matchContextualKeyword('from')){
-
-
-this.nextToken();
-source=this.parseModuleSpecifier();
-this.consumeSemicolon();
-}else
-if(isExportFromIdentifier){
-
-var message=this.lookahead.value?messages_1.Messages.UnexpectedToken:messages_1.Messages.MissingFromClause;
-this.throwError(message,this.lookahead.value);
-}else
-{
-
-this.consumeSemicolon();
-}
-exportDeclaration=this.finalize(node,new Node.ExportNamedDeclaration(null,specifiers,source));
-}
-return exportDeclaration;
-};
-return Parser;
-}();
-exports.Parser=Parser;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-
-
-
-
-Object.defineProperty(exports,"__esModule",{value:true});
-function assert(condition,message){
-
-if(!condition){
-throw new Error('ASSERT: '+message);
-}
-}
-exports.assert=assert;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-
-Object.defineProperty(exports,"__esModule",{value:true});
-var ErrorHandler=function(){
-function ErrorHandler(){
-this.errors=[];
-this.tolerant=false;
-}
-ErrorHandler.prototype.recordError=function(error){
-this.errors.push(error);
-};
-ErrorHandler.prototype.tolerate=function(error){
-if(this.tolerant){
-this.recordError(error);
-}else
-{
-throw error;
-}
-};
-ErrorHandler.prototype.constructError=function(msg,column){
-var error=new Error(msg);
-try{
-throw error;
-}
-catch(base){
-
-if(Object.create&&Object.defineProperty){
-error=Object.create(base);
-Object.defineProperty(error,'column',{value:column});
-}
-}
-
-return error;
-};
-ErrorHandler.prototype.createError=function(index,line,col,description){
-var msg='Line '+line+': '+description;
-var error=this.constructError(msg,col);
-error.index=index;
-error.lineNumber=line;
-error.description=description;
-return error;
-};
-ErrorHandler.prototype.throwError=function(index,line,col,description){
-throw this.createError(index,line,col,description);
-};
-ErrorHandler.prototype.tolerateError=function(index,line,col,description){
-var error=this.createError(index,line,col,description);
-if(this.tolerant){
-this.recordError(error);
-}else
-{
-throw error;
-}
-};
-return ErrorHandler;
-}();
-exports.ErrorHandler=ErrorHandler;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-
-exports.Messages={
-BadGetterArity:'Getter must not have any formal parameters',
-BadSetterArity:'Setter must have exactly one formal parameter',
-BadSetterRestParameter:'Setter function argument must not be a rest parameter',
-ConstructorIsAsync:'Class constructor may not be an async method',
-ConstructorSpecialMethod:'Class constructor may not be an accessor',
-DeclarationMissingInitializer:'Missing initializer in %0 declaration',
-DefaultRestParameter:'Unexpected token =',
-DuplicateBinding:'Duplicate binding %0',
-DuplicateConstructor:'A class may only have one constructor',
-DuplicateProtoProperty:'Duplicate __proto__ fields are not allowed in object literals',
-ForInOfLoopInitializer:'%0 loop variable declaration may not have an initializer',
-GeneratorInLegacyContext:'Generator declarations are not allowed in legacy contexts',
-IllegalBreak:'Illegal break statement',
-IllegalContinue:'Illegal continue statement',
-IllegalExportDeclaration:'Unexpected token',
-IllegalImportDeclaration:'Unexpected token',
-IllegalLanguageModeDirective:'Illegal \'use strict\' directive in function with non-simple parameter list',
-IllegalReturn:'Illegal return statement',
-InvalidEscapedReservedWord:'Keyword must not contain escaped characters',
-InvalidHexEscapeSequence:'Invalid hexadecimal escape sequence',
-InvalidLHSInAssignment:'Invalid left-hand side in assignment',
-InvalidLHSInForIn:'Invalid left-hand side in for-in',
-InvalidLHSInForLoop:'Invalid left-hand side in for-loop',
-InvalidModuleSpecifier:'Unexpected token',
-InvalidRegExp:'Invalid regular expression',
-LetInLexicalBinding:'let is disallowed as a lexically bound name',
-MissingFromClause:'Unexpected token',
-MultipleDefaultsInSwitch:'More than one default clause in switch statement',
-NewlineAfterThrow:'Illegal newline after throw',
-NoAsAfterImportNamespace:'Unexpected token',
-NoCatchOrFinally:'Missing catch or finally after try',
-ParameterAfterRestParameter:'Rest parameter must be last formal parameter',
-Redeclaration:'%0 \'%1\' has already been declared',
-StaticPrototype:'Classes may not have static property named prototype',
-StrictCatchVariable:'Catch variable may not be eval or arguments in strict mode',
-StrictDelete:'Delete of an unqualified identifier in strict mode.',
-StrictFunction:'In strict mode code, functions can only be declared at top level or inside a block',
-StrictFunctionName:'Function name may not be eval or arguments in strict mode',
-StrictLHSAssignment:'Assignment to eval or arguments is not allowed in strict mode',
-StrictLHSPostfix:'Postfix increment/decrement may not have eval or arguments operand in strict mode',
-StrictLHSPrefix:'Prefix increment/decrement may not have eval or arguments operand in strict mode',
-StrictModeWith:'Strict mode code may not include a with statement',
-StrictOctalLiteral:'Octal literals are not allowed in strict mode.',
-StrictParamDupe:'Strict mode function may not have duplicate parameter names',
-StrictParamName:'Parameter name eval or arguments is not allowed in strict mode',
-StrictReservedWord:'Use of future reserved word in strict mode',
-StrictVarName:'Variable name may not be eval or arguments in strict mode',
-TemplateOctalLiteral:'Octal literals are not allowed in template strings.',
-UnexpectedEOS:'Unexpected end of input',
-UnexpectedIdentifier:'Unexpected identifier',
-UnexpectedNumber:'Unexpected number',
-UnexpectedReserved:'Unexpected reserved word',
-UnexpectedString:'Unexpected string',
-UnexpectedTemplate:'Unexpected quasi %0',
-UnexpectedToken:'Unexpected token %0',
-UnexpectedTokenIllegal:'Unexpected token ILLEGAL',
-UnknownLabel:'Undefined label \'%0\'',
-UnterminatedRegExp:'Invalid regular expression: missing /'};
-
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-var assert_1=__webpack_require__(9);
-var character_1=__webpack_require__(4);
-var messages_1=__webpack_require__(11);
-function hexValue(ch){
-return'0123456789abcdef'.indexOf(ch.toLowerCase());
-}
-function octalValue(ch){
-return'01234567'.indexOf(ch);
-}
-var Scanner=function(){
-function Scanner(code,handler){
-this.source=code;
-this.errorHandler=handler;
-this.trackComment=false;
-this.length=code.length;
-this.index=0;
-this.lineNumber=code.length>0?1:0;
-this.lineStart=0;
-this.curlyStack=[];
-}
-Scanner.prototype.saveState=function(){
-return{
-index:this.index,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart};
-
-};
-Scanner.prototype.restoreState=function(state){
-this.index=state.index;
-this.lineNumber=state.lineNumber;
-this.lineStart=state.lineStart;
-};
-Scanner.prototype.eof=function(){
-return this.index>=this.length;
-};
-Scanner.prototype.throwUnexpectedToken=function(message){
-if(message===void 0){message=messages_1.Messages.UnexpectedTokenIllegal;}
-return this.errorHandler.throwError(this.index,this.lineNumber,this.index-this.lineStart+1,message);
-};
-Scanner.prototype.tolerateUnexpectedToken=function(message){
-if(message===void 0){message=messages_1.Messages.UnexpectedTokenIllegal;}
-this.errorHandler.tolerateError(this.index,this.lineNumber,this.index-this.lineStart+1,message);
-};
-
-Scanner.prototype.skipSingleLineComment=function(offset){
-var comments=[];
-var start,loc;
-if(this.trackComment){
-comments=[];
-start=this.index-offset;
-loc={
-start:{
-line:this.lineNumber,
-column:this.index-this.lineStart-offset},
-
-end:{}};
-
-}
-while(!this.eof()){
-var ch=this.source.charCodeAt(this.index);
-++this.index;
-if(character_1.Character.isLineTerminator(ch)){
-if(this.trackComment){
-loc.end={
-line:this.lineNumber,
-column:this.index-this.lineStart-1};
-
-var entry={
-multiLine:false,
-slice:[start+offset,this.index-1],
-range:[start,this.index-1],
-loc:loc};
-
-comments.push(entry);
-}
-if(ch===13&&this.source.charCodeAt(this.index)===10){
-++this.index;
-}
-++this.lineNumber;
-this.lineStart=this.index;
-return comments;
-}
-}
-if(this.trackComment){
-loc.end={
-line:this.lineNumber,
-column:this.index-this.lineStart};
-
-var entry={
-multiLine:false,
-slice:[start+offset,this.index],
-range:[start,this.index],
-loc:loc};
-
-comments.push(entry);
-}
-return comments;
-};
-Scanner.prototype.skipMultiLineComment=function(){
-var comments=[];
-var start,loc;
-if(this.trackComment){
-comments=[];
-start=this.index-2;
-loc={
-start:{
-line:this.lineNumber,
-column:this.index-this.lineStart-2},
-
-end:{}};
-
-}
-while(!this.eof()){
-var ch=this.source.charCodeAt(this.index);
-if(character_1.Character.isLineTerminator(ch)){
-if(ch===0x0D&&this.source.charCodeAt(this.index+1)===0x0A){
-++this.index;
-}
-++this.lineNumber;
-++this.index;
-this.lineStart=this.index;
-}else
-if(ch===0x2A){
-
-if(this.source.charCodeAt(this.index+1)===0x2F){
-this.index+=2;
-if(this.trackComment){
-loc.end={
-line:this.lineNumber,
-column:this.index-this.lineStart};
-
-var entry={
-multiLine:true,
-slice:[start+2,this.index-2],
-range:[start,this.index],
-loc:loc};
-
-comments.push(entry);
-}
-return comments;
-}
-++this.index;
-}else
-{
-++this.index;
-}
-}
-
-if(this.trackComment){
-loc.end={
-line:this.lineNumber,
-column:this.index-this.lineStart};
-
-var entry={
-multiLine:true,
-slice:[start+2,this.index],
-range:[start,this.index],
-loc:loc};
-
-comments.push(entry);
-}
-this.tolerateUnexpectedToken();
-return comments;
-};
-Scanner.prototype.scanComments=function(){
-var comments;
-if(this.trackComment){
-comments=[];
-}
-var start=this.index===0;
-while(!this.eof()){
-var ch=this.source.charCodeAt(this.index);
-if(character_1.Character.isWhiteSpace(ch)){
-++this.index;
-}else
-if(character_1.Character.isLineTerminator(ch)){
-++this.index;
-if(ch===0x0D&&this.source.charCodeAt(this.index)===0x0A){
-++this.index;
-}
-++this.lineNumber;
-this.lineStart=this.index;
-start=true;
-}else
-if(ch===0x2F){
-ch=this.source.charCodeAt(this.index+1);
-if(ch===0x2F){
-this.index+=2;
-var comment=this.skipSingleLineComment(2);
-if(this.trackComment){
-comments=comments.concat(comment);
-}
-start=true;
-}else
-if(ch===0x2A){
-this.index+=2;
-var comment=this.skipMultiLineComment();
-if(this.trackComment){
-comments=comments.concat(comment);
-}
-}else
-{
-break;
-}
-}else
-if(start&&ch===0x2D){
-
-if(this.source.charCodeAt(this.index+1)===0x2D&&this.source.charCodeAt(this.index+2)===0x3E){
-
-this.index+=3;
-var comment=this.skipSingleLineComment(3);
-if(this.trackComment){
-comments=comments.concat(comment);
-}
-}else
-{
-break;
-}
-}else
-if(ch===0x3C){
-if(this.source.slice(this.index+1,this.index+4)==='!--'){
-this.index+=4;
-var comment=this.skipSingleLineComment(4);
-if(this.trackComment){
-comments=comments.concat(comment);
-}
-}else
-{
-break;
-}
-}else
-{
-break;
-}
-}
-return comments;
-};
-
-Scanner.prototype.isFutureReservedWord=function(id){
-switch(id){
-case'enum':
-case'export':
-case'import':
-case'super':
-return true;
-default:
-return false;}
-
-};
-Scanner.prototype.isStrictModeReservedWord=function(id){
-switch(id){
-case'implements':
-case'interface':
-case'package':
-case'private':
-case'protected':
-case'public':
-case'static':
-case'yield':
-case'let':
-return true;
-default:
-return false;}
-
-};
-Scanner.prototype.isRestrictedWord=function(id){
-return id==='eval'||id==='arguments';
-};
-
-Scanner.prototype.isKeyword=function(id){
-switch(id.length){
-case 2:
-return id==='if'||id==='in'||id==='do';
-case 3:
-return id==='var'||id==='for'||id==='new'||
-id==='try'||id==='let';
-case 4:
-return id==='this'||id==='else'||id==='case'||
-id==='void'||id==='with'||id==='enum';
-case 5:
-return id==='while'||id==='break'||id==='catch'||
-id==='throw'||id==='const'||id==='yield'||
-id==='class'||id==='super';
-case 6:
-return id==='return'||id==='typeof'||id==='delete'||
-id==='switch'||id==='export'||id==='import';
-case 7:
-return id==='default'||id==='finally'||id==='extends';
-case 8:
-return id==='function'||id==='continue'||id==='debugger';
-case 10:
-return id==='instanceof';
-default:
-return false;}
-
-};
-Scanner.prototype.codePointAt=function(i){
-var cp=this.source.charCodeAt(i);
-if(cp>=0xD800&&cp<=0xDBFF){
-var second=this.source.charCodeAt(i+1);
-if(second>=0xDC00&&second<=0xDFFF){
-var first=cp;
-cp=(first-0xD800)*0x400+second-0xDC00+0x10000;
-}
-}
-return cp;
-};
-Scanner.prototype.scanHexEscape=function(prefix){
-var len=prefix==='u'?4:2;
-var code=0;
-for(var i=0;i<len;++i){
-if(!this.eof()&&character_1.Character.isHexDigit(this.source.charCodeAt(this.index))){
-code=code*16+hexValue(this.source[this.index++]);
-}else
-{
-return null;
-}
-}
-return String.fromCharCode(code);
-};
-Scanner.prototype.scanUnicodeCodePointEscape=function(){
-var ch=this.source[this.index];
-var code=0;
-
-if(ch==='}'){
-this.throwUnexpectedToken();
-}
-while(!this.eof()){
-ch=this.source[this.index++];
-if(!character_1.Character.isHexDigit(ch.charCodeAt(0))){
-break;
-}
-code=code*16+hexValue(ch);
-}
-if(code>0x10FFFF||ch!=='}'){
-this.throwUnexpectedToken();
-}
-return character_1.Character.fromCodePoint(code);
-};
-Scanner.prototype.getIdentifier=function(){
-var start=this.index++;
-while(!this.eof()){
-var ch=this.source.charCodeAt(this.index);
-if(ch===0x5C){
-
-this.index=start;
-return this.getComplexIdentifier();
-}else
-if(ch>=0xD800&&ch<0xDFFF){
-
-this.index=start;
-return this.getComplexIdentifier();
-}
-if(character_1.Character.isIdentifierPart(ch)){
-++this.index;
-}else
-{
-break;
-}
-}
-return this.source.slice(start,this.index);
-};
-Scanner.prototype.getComplexIdentifier=function(){
-var cp=this.codePointAt(this.index);
-var id=character_1.Character.fromCodePoint(cp);
-this.index+=id.length;
-
-var ch;
-if(cp===0x5C){
-if(this.source.charCodeAt(this.index)!==0x75){
-this.throwUnexpectedToken();
-}
-++this.index;
-if(this.source[this.index]==='{'){
-++this.index;
-ch=this.scanUnicodeCodePointEscape();
-}else
-{
-ch=this.scanHexEscape('u');
-if(ch===null||ch==='\\'||!character_1.Character.isIdentifierStart(ch.charCodeAt(0))){
-this.throwUnexpectedToken();
-}
-}
-id=ch;
-}
-while(!this.eof()){
-cp=this.codePointAt(this.index);
-if(!character_1.Character.isIdentifierPart(cp)){
-break;
-}
-ch=character_1.Character.fromCodePoint(cp);
-id+=ch;
-this.index+=ch.length;
-
-if(cp===0x5C){
-id=id.substr(0,id.length-1);
-if(this.source.charCodeAt(this.index)!==0x75){
-this.throwUnexpectedToken();
-}
-++this.index;
-if(this.source[this.index]==='{'){
-++this.index;
-ch=this.scanUnicodeCodePointEscape();
-}else
-{
-ch=this.scanHexEscape('u');
-if(ch===null||ch==='\\'||!character_1.Character.isIdentifierPart(ch.charCodeAt(0))){
-this.throwUnexpectedToken();
-}
-}
-id+=ch;
-}
-}
-return id;
-};
-Scanner.prototype.octalToDecimal=function(ch){
-
-var octal=ch!=='0';
-var code=octalValue(ch);
-if(!this.eof()&&character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))){
-octal=true;
-code=code*8+octalValue(this.source[this.index++]);
-
-
-if('0123'.indexOf(ch)>=0&&!this.eof()&&character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))){
-code=code*8+octalValue(this.source[this.index++]);
-}
-}
-return{
-code:code,
-octal:octal};
-
-};
-
-Scanner.prototype.scanIdentifier=function(){
-var type;
-var start=this.index;
-
-var id=this.source.charCodeAt(start)===0x5C?this.getComplexIdentifier():this.getIdentifier();
-
-
-if(id.length===1){
-type=3;
-}else
-if(this.isKeyword(id)){
-type=4;
-}else
-if(id==='null'){
-type=5;
-}else
-if(id==='true'||id==='false'){
-type=1;
-}else
-{
-type=3;
-}
-if(type!==3&&start+id.length!==this.index){
-var restore=this.index;
-this.index=start;
-this.tolerateUnexpectedToken(messages_1.Messages.InvalidEscapedReservedWord);
-this.index=restore;
-}
-return{
-type:type,
-value:id,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-
-Scanner.prototype.scanPunctuator=function(){
-var start=this.index;
-
-var str=this.source[this.index];
-switch(str){
-case'(':
-case'{':
-if(str==='{'){
-this.curlyStack.push('{');
-}
-++this.index;
-break;
-case'.':
-++this.index;
-if(this.source[this.index]==='.'&&this.source[this.index+1]==='.'){
-
-this.index+=2;
-str='...';
-}
-break;
-case'}':
-++this.index;
-this.curlyStack.pop();
-break;
-case')':
-case';':
-case',':
-case'[':
-case']':
-case':':
-case'?':
-case'~':
-++this.index;
-break;
-default:
-
-str=this.source.substr(this.index,4);
-if(str==='>>>='){
-this.index+=4;
-}else
-{
-
-str=str.substr(0,3);
-if(str==='==='||str==='!=='||str==='>>>'||
-str==='<<='||str==='>>='||str==='**='){
-this.index+=3;
-}else
-{
-
-str=str.substr(0,2);
-if(str==='&&'||str==='||'||str==='=='||str==='!='||
-str==='+='||str==='-='||str==='*='||str==='/='||
-str==='++'||str==='--'||str==='<<'||str==='>>'||
-str==='&='||str==='|='||str==='^='||str==='%='||
-str==='<='||str==='>='||str==='=>'||str==='**'){
-this.index+=2;
-}else
-{
-
-str=this.source[this.index];
-if('<>=!+-*%&|^/'.indexOf(str)>=0){
-++this.index;
-}
-}
-}
-}}
-
-if(this.index===start){
-this.throwUnexpectedToken();
-}
-return{
-type:7,
-value:str,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-
-Scanner.prototype.scanHexLiteral=function(start){
-var num='';
-while(!this.eof()){
-if(!character_1.Character.isHexDigit(this.source.charCodeAt(this.index))){
-break;
-}
-num+=this.source[this.index++];
-}
-if(num.length===0){
-this.throwUnexpectedToken();
-}
-if(character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))){
-this.throwUnexpectedToken();
-}
-return{
-type:6,
-value:parseInt('0x'+num,16),
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-Scanner.prototype.scanBinaryLiteral=function(start){
-var num='';
-var ch;
-while(!this.eof()){
-ch=this.source[this.index];
-if(ch!=='0'&&ch!=='1'){
-break;
-}
-num+=this.source[this.index++];
-}
-if(num.length===0){
-
-this.throwUnexpectedToken();
-}
-if(!this.eof()){
-ch=this.source.charCodeAt(this.index);
-
-if(character_1.Character.isIdentifierStart(ch)||character_1.Character.isDecimalDigit(ch)){
-this.throwUnexpectedToken();
-}
-}
-return{
-type:6,
-value:parseInt(num,2),
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-Scanner.prototype.scanOctalLiteral=function(prefix,start){
-var num='';
-var octal=false;
-if(character_1.Character.isOctalDigit(prefix.charCodeAt(0))){
-octal=true;
-num='0'+this.source[this.index++];
-}else
-{
-++this.index;
-}
-while(!this.eof()){
-if(!character_1.Character.isOctalDigit(this.source.charCodeAt(this.index))){
-break;
-}
-num+=this.source[this.index++];
-}
-if(!octal&&num.length===0){
-
-this.throwUnexpectedToken();
-}
-if(character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))||character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))){
-this.throwUnexpectedToken();
-}
-return{
-type:6,
-value:parseInt(num,8),
-octal:octal,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-Scanner.prototype.isImplicitOctalLiteral=function(){
-
-
-for(var i=this.index+1;i<this.length;++i){
-var ch=this.source[i];
-if(ch==='8'||ch==='9'){
-return false;
-}
-if(!character_1.Character.isOctalDigit(ch.charCodeAt(0))){
-return true;
-}
-}
-return true;
-};
-Scanner.prototype.scanNumericLiteral=function(){
-var start=this.index;
-var ch=this.source[start];
-assert_1.assert(character_1.Character.isDecimalDigit(ch.charCodeAt(0))||ch==='.','Numeric literal must start with a decimal digit or a decimal point');
-var num='';
-if(ch!=='.'){
-num=this.source[this.index++];
-ch=this.source[this.index];
-
-
-
-
-if(num==='0'){
-if(ch==='x'||ch==='X'){
-++this.index;
-return this.scanHexLiteral(start);
-}
-if(ch==='b'||ch==='B'){
-++this.index;
-return this.scanBinaryLiteral(start);
-}
-if(ch==='o'||ch==='O'){
-return this.scanOctalLiteral(ch,start);
-}
-if(ch&&character_1.Character.isOctalDigit(ch.charCodeAt(0))){
-if(this.isImplicitOctalLiteral()){
-return this.scanOctalLiteral(ch,start);
-}
-}
-}
-while(character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))){
-num+=this.source[this.index++];
-}
-ch=this.source[this.index];
-}
-if(ch==='.'){
-num+=this.source[this.index++];
-while(character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))){
-num+=this.source[this.index++];
-}
-ch=this.source[this.index];
-}
-if(ch==='e'||ch==='E'){
-num+=this.source[this.index++];
-ch=this.source[this.index];
-if(ch==='+'||ch==='-'){
-num+=this.source[this.index++];
-}
-if(character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))){
-while(character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))){
-num+=this.source[this.index++];
-}
-}else
-{
-this.throwUnexpectedToken();
-}
-}
-if(character_1.Character.isIdentifierStart(this.source.charCodeAt(this.index))){
-this.throwUnexpectedToken();
-}
-return{
-type:6,
-value:parseFloat(num),
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-
-Scanner.prototype.scanStringLiteral=function(){
-var start=this.index;
-var quote=this.source[start];
-assert_1.assert(quote==='\''||quote==='"','String literal must starts with a quote');
-++this.index;
-var octal=false;
-var str='';
-while(!this.eof()){
-var ch=this.source[this.index++];
-if(ch===quote){
-quote='';
-break;
-}else
-if(ch==='\\'){
-ch=this.source[this.index++];
-if(!ch||!character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-switch(ch){
-case'u':
-if(this.source[this.index]==='{'){
-++this.index;
-str+=this.scanUnicodeCodePointEscape();
-}else
-{
-var unescaped_1=this.scanHexEscape(ch);
-if(unescaped_1===null){
-this.throwUnexpectedToken();
-}
-str+=unescaped_1;
-}
-break;
-case'x':
-var unescaped=this.scanHexEscape(ch);
-if(unescaped===null){
-this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence);
-}
-str+=unescaped;
-break;
-case'n':
-str+='\n';
-break;
-case'r':
-str+='\r';
-break;
-case't':
-str+='\t';
-break;
-case'b':
-str+='\b';
-break;
-case'f':
-str+='\f';
-break;
-case'v':
-str+='\x0B';
-break;
-case'8':
-case'9':
-str+=ch;
-this.tolerateUnexpectedToken();
-break;
-default:
-if(ch&&character_1.Character.isOctalDigit(ch.charCodeAt(0))){
-var octToDec=this.octalToDecimal(ch);
-octal=octToDec.octal||octal;
-str+=String.fromCharCode(octToDec.code);
-}else
-{
-str+=ch;
-}
-break;}
-
-}else
-{
-++this.lineNumber;
-if(ch==='\r'&&this.source[this.index]==='\n'){
-++this.index;
-}
-this.lineStart=this.index;
-}
-}else
-if(character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-break;
-}else
-{
-str+=ch;
-}
-}
-if(quote!==''){
-this.index=start;
-this.throwUnexpectedToken();
-}
-return{
-type:8,
-value:str,
-octal:octal,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-
-Scanner.prototype.scanTemplate=function(){
-var cooked='';
-var terminated=false;
-var start=this.index;
-var head=this.source[start]==='`';
-var tail=false;
-var rawOffset=2;
-++this.index;
-while(!this.eof()){
-var ch=this.source[this.index++];
-if(ch==='`'){
-rawOffset=1;
-tail=true;
-terminated=true;
-break;
-}else
-if(ch==='$'){
-if(this.source[this.index]==='{'){
-this.curlyStack.push('${');
-++this.index;
-terminated=true;
-break;
-}
-cooked+=ch;
-}else
-if(ch==='\\'){
-ch=this.source[this.index++];
-if(!character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-switch(ch){
-case'n':
-cooked+='\n';
-break;
-case'r':
-cooked+='\r';
-break;
-case't':
-cooked+='\t';
-break;
-case'u':
-if(this.source[this.index]==='{'){
-++this.index;
-cooked+=this.scanUnicodeCodePointEscape();
-}else
-{
-var restore=this.index;
-var unescaped_2=this.scanHexEscape(ch);
-if(unescaped_2!==null){
-cooked+=unescaped_2;
-}else
-{
-this.index=restore;
-cooked+=ch;
-}
-}
-break;
-case'x':
-var unescaped=this.scanHexEscape(ch);
-if(unescaped===null){
-this.throwUnexpectedToken(messages_1.Messages.InvalidHexEscapeSequence);
-}
-cooked+=unescaped;
-break;
-case'b':
-cooked+='\b';
-break;
-case'f':
-cooked+='\f';
-break;
-case'v':
-cooked+='\v';
-break;
-default:
-if(ch==='0'){
-if(character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index))){
-
-this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
-}
-cooked+='\0';
-}else
-if(character_1.Character.isOctalDigit(ch.charCodeAt(0))){
-
-this.throwUnexpectedToken(messages_1.Messages.TemplateOctalLiteral);
-}else
-{
-cooked+=ch;
-}
-break;}
-
-}else
-{
-++this.lineNumber;
-if(ch==='\r'&&this.source[this.index]==='\n'){
-++this.index;
-}
-this.lineStart=this.index;
-}
-}else
-if(character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-++this.lineNumber;
-if(ch==='\r'&&this.source[this.index]==='\n'){
-++this.index;
-}
-this.lineStart=this.index;
-cooked+='\n';
-}else
-{
-cooked+=ch;
-}
-}
-if(!terminated){
-this.throwUnexpectedToken();
-}
-if(!head){
-this.curlyStack.pop();
-}
-return{
-type:10,
-value:this.source.slice(start+1,this.index-rawOffset),
-cooked:cooked,
-head:head,
-tail:tail,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-
-Scanner.prototype.testRegExp=function(pattern,flags){
-
-
-
-
-
-
-var astralSubstitute='\uFFFF';
-var tmp=pattern;
-var self=this;
-if(flags.indexOf('u')>=0){
-tmp=tmp.
-replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g,function($0,$1,$2){
-var codePoint=parseInt($1||$2,16);
-if(codePoint>0x10FFFF){
-self.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
-}
-if(codePoint<=0xFFFF){
-return String.fromCharCode(codePoint);
-}
-return astralSubstitute;
-}).
-replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,astralSubstitute);
-}
-
-try{
-RegExp(tmp);
-}
-catch(e){
-this.throwUnexpectedToken(messages_1.Messages.InvalidRegExp);
-}
-
-
-
-try{
-return new RegExp(pattern,flags);
-}
-catch(exception){
-
-return null;
-}
-};
-Scanner.prototype.scanRegExpBody=function(){
-var ch=this.source[this.index];
-assert_1.assert(ch==='/','Regular expression literal must start with a slash');
-var str=this.source[this.index++];
-var classMarker=false;
-var terminated=false;
-while(!this.eof()){
-ch=this.source[this.index++];
-str+=ch;
-if(ch==='\\'){
-ch=this.source[this.index++];
-
-if(character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
-}
-str+=ch;
-}else
-if(character_1.Character.isLineTerminator(ch.charCodeAt(0))){
-this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
-}else
-if(classMarker){
-if(ch===']'){
-classMarker=false;
-}
-}else
-{
-if(ch==='/'){
-terminated=true;
-break;
-}else
-if(ch==='['){
-classMarker=true;
-}
-}
-}
-if(!terminated){
-this.throwUnexpectedToken(messages_1.Messages.UnterminatedRegExp);
-}
-
-return str.substr(1,str.length-2);
-};
-Scanner.prototype.scanRegExpFlags=function(){
-var str='';
-var flags='';
-while(!this.eof()){
-var ch=this.source[this.index];
-if(!character_1.Character.isIdentifierPart(ch.charCodeAt(0))){
-break;
-}
-++this.index;
-if(ch==='\\'&&!this.eof()){
-ch=this.source[this.index];
-if(ch==='u'){
-++this.index;
-var restore=this.index;
-var char=this.scanHexEscape('u');
-if(char!==null){
-flags+=char;
-for(str+='\\u';restore<this.index;++restore){
-str+=this.source[restore];
-}
-}else
-{
-this.index=restore;
-flags+='u';
-str+='\\u';
-}
-this.tolerateUnexpectedToken();
-}else
-{
-str+='\\';
-this.tolerateUnexpectedToken();
-}
-}else
-{
-flags+=ch;
-str+=ch;
-}
-}
-return flags;
-};
-Scanner.prototype.scanRegExp=function(){
-var start=this.index;
-var pattern=this.scanRegExpBody();
-var flags=this.scanRegExpFlags();
-var value=this.testRegExp(pattern,flags);
-return{
-type:9,
-value:'',
-pattern:pattern,
-flags:flags,
-regex:value,
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:start,
-end:this.index};
-
-};
-Scanner.prototype.lex=function(){
-if(this.eof()){
-return{
-type:2,
-value:'',
-lineNumber:this.lineNumber,
-lineStart:this.lineStart,
-start:this.index,
-end:this.index};
-
-}
-var cp=this.source.charCodeAt(this.index);
-if(character_1.Character.isIdentifierStart(cp)){
-return this.scanIdentifier();
-}
-
-if(cp===0x28||cp===0x29||cp===0x3B){
-return this.scanPunctuator();
-}
-
-if(cp===0x27||cp===0x22){
-return this.scanStringLiteral();
-}
-
-
-if(cp===0x2E){
-if(character_1.Character.isDecimalDigit(this.source.charCodeAt(this.index+1))){
-return this.scanNumericLiteral();
-}
-return this.scanPunctuator();
-}
-if(character_1.Character.isDecimalDigit(cp)){
-return this.scanNumericLiteral();
-}
-
-
-if(cp===0x60||cp===0x7D&&this.curlyStack[this.curlyStack.length-1]==='${'){
-return this.scanTemplate();
-}
-
-if(cp>=0xD800&&cp<0xDFFF){
-if(character_1.Character.isIdentifierStart(this.codePointAt(this.index))){
-return this.scanIdentifier();
-}
-}
-return this.scanPunctuator();
-};
-return Scanner;
-}();
-exports.Scanner=Scanner;
-
-
-},
-
-function(module,exports){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-exports.TokenName={};
-exports.TokenName[1]='Boolean';
-exports.TokenName[2]='<end>';
-exports.TokenName[3]='Identifier';
-exports.TokenName[4]='Keyword';
-exports.TokenName[5]='Null';
-exports.TokenName[6]='Numeric';
-exports.TokenName[7]='Punctuator';
-exports.TokenName[8]='String';
-exports.TokenName[9]='RegularExpression';
-exports.TokenName[10]='Template';
-
-
-},
-
-function(module,exports){
-
-"use strict";
-
-Object.defineProperty(exports,"__esModule",{value:true});
-exports.XHTMLEntities={
-quot:'\u0022',
-amp:'\u0026',
-apos:'\u0027',
-gt:'\u003E',
-nbsp:'\u00A0',
-iexcl:'\u00A1',
-cent:'\u00A2',
-pound:'\u00A3',
-curren:'\u00A4',
-yen:'\u00A5',
-brvbar:'\u00A6',
-sect:'\u00A7',
-uml:'\u00A8',
-copy:'\u00A9',
-ordf:'\u00AA',
-laquo:'\u00AB',
-not:'\u00AC',
-shy:'\u00AD',
-reg:'\u00AE',
-macr:'\u00AF',
-deg:'\u00B0',
-plusmn:'\u00B1',
-sup2:'\u00B2',
-sup3:'\u00B3',
-acute:'\u00B4',
-micro:'\u00B5',
-para:'\u00B6',
-middot:'\u00B7',
-cedil:'\u00B8',
-sup1:'\u00B9',
-ordm:'\u00BA',
-raquo:'\u00BB',
-frac14:'\u00BC',
-frac12:'\u00BD',
-frac34:'\u00BE',
-iquest:'\u00BF',
-Agrave:'\u00C0',
-Aacute:'\u00C1',
-Acirc:'\u00C2',
-Atilde:'\u00C3',
-Auml:'\u00C4',
-Aring:'\u00C5',
-AElig:'\u00C6',
-Ccedil:'\u00C7',
-Egrave:'\u00C8',
-Eacute:'\u00C9',
-Ecirc:'\u00CA',
-Euml:'\u00CB',
-Igrave:'\u00CC',
-Iacute:'\u00CD',
-Icirc:'\u00CE',
-Iuml:'\u00CF',
-ETH:'\u00D0',
-Ntilde:'\u00D1',
-Ograve:'\u00D2',
-Oacute:'\u00D3',
-Ocirc:'\u00D4',
-Otilde:'\u00D5',
-Ouml:'\u00D6',
-times:'\u00D7',
-Oslash:'\u00D8',
-Ugrave:'\u00D9',
-Uacute:'\u00DA',
-Ucirc:'\u00DB',
-Uuml:'\u00DC',
-Yacute:'\u00DD',
-THORN:'\u00DE',
-szlig:'\u00DF',
-agrave:'\u00E0',
-aacute:'\u00E1',
-acirc:'\u00E2',
-atilde:'\u00E3',
-auml:'\u00E4',
-aring:'\u00E5',
-aelig:'\u00E6',
-ccedil:'\u00E7',
-egrave:'\u00E8',
-eacute:'\u00E9',
-ecirc:'\u00EA',
-euml:'\u00EB',
-igrave:'\u00EC',
-iacute:'\u00ED',
-icirc:'\u00EE',
-iuml:'\u00EF',
-eth:'\u00F0',
-ntilde:'\u00F1',
-ograve:'\u00F2',
-oacute:'\u00F3',
-ocirc:'\u00F4',
-otilde:'\u00F5',
-ouml:'\u00F6',
-divide:'\u00F7',
-oslash:'\u00F8',
-ugrave:'\u00F9',
-uacute:'\u00FA',
-ucirc:'\u00FB',
-uuml:'\u00FC',
-yacute:'\u00FD',
-thorn:'\u00FE',
-yuml:'\u00FF',
-OElig:'\u0152',
-oelig:'\u0153',
-Scaron:'\u0160',
-scaron:'\u0161',
-Yuml:'\u0178',
-fnof:'\u0192',
-circ:'\u02C6',
-tilde:'\u02DC',
-Alpha:'\u0391',
-Beta:'\u0392',
-Gamma:'\u0393',
-Delta:'\u0394',
-Epsilon:'\u0395',
-Zeta:'\u0396',
-Eta:'\u0397',
-Theta:'\u0398',
-Iota:'\u0399',
-Kappa:'\u039A',
-Lambda:'\u039B',
-Mu:'\u039C',
-Nu:'\u039D',
-Xi:'\u039E',
-Omicron:'\u039F',
-Pi:'\u03A0',
-Rho:'\u03A1',
-Sigma:'\u03A3',
-Tau:'\u03A4',
-Upsilon:'\u03A5',
-Phi:'\u03A6',
-Chi:'\u03A7',
-Psi:'\u03A8',
-Omega:'\u03A9',
-alpha:'\u03B1',
-beta:'\u03B2',
-gamma:'\u03B3',
-delta:'\u03B4',
-epsilon:'\u03B5',
-zeta:'\u03B6',
-eta:'\u03B7',
-theta:'\u03B8',
-iota:'\u03B9',
-kappa:'\u03BA',
-lambda:'\u03BB',
-mu:'\u03BC',
-nu:'\u03BD',
-xi:'\u03BE',
-omicron:'\u03BF',
-pi:'\u03C0',
-rho:'\u03C1',
-sigmaf:'\u03C2',
-sigma:'\u03C3',
-tau:'\u03C4',
-upsilon:'\u03C5',
-phi:'\u03C6',
-chi:'\u03C7',
-psi:'\u03C8',
-omega:'\u03C9',
-thetasym:'\u03D1',
-upsih:'\u03D2',
-piv:'\u03D6',
-ensp:'\u2002',
-emsp:'\u2003',
-thinsp:'\u2009',
-zwnj:'\u200C',
-zwj:'\u200D',
-lrm:'\u200E',
-rlm:'\u200F',
-ndash:'\u2013',
-mdash:'\u2014',
-lsquo:'\u2018',
-rsquo:'\u2019',
-sbquo:'\u201A',
-ldquo:'\u201C',
-rdquo:'\u201D',
-bdquo:'\u201E',
-dagger:'\u2020',
-Dagger:'\u2021',
-bull:'\u2022',
-hellip:'\u2026',
-permil:'\u2030',
-prime:'\u2032',
-Prime:'\u2033',
-lsaquo:'\u2039',
-rsaquo:'\u203A',
-oline:'\u203E',
-frasl:'\u2044',
-euro:'\u20AC',
-image:'\u2111',
-weierp:'\u2118',
-real:'\u211C',
-trade:'\u2122',
-alefsym:'\u2135',
-larr:'\u2190',
-uarr:'\u2191',
-rarr:'\u2192',
-darr:'\u2193',
-harr:'\u2194',
-crarr:'\u21B5',
-lArr:'\u21D0',
-uArr:'\u21D1',
-rArr:'\u21D2',
-dArr:'\u21D3',
-hArr:'\u21D4',
-forall:'\u2200',
-part:'\u2202',
-exist:'\u2203',
-empty:'\u2205',
-nabla:'\u2207',
-isin:'\u2208',
-notin:'\u2209',
-ni:'\u220B',
-prod:'\u220F',
-sum:'\u2211',
-minus:'\u2212',
-lowast:'\u2217',
-radic:'\u221A',
-prop:'\u221D',
-infin:'\u221E',
-ang:'\u2220',
-and:'\u2227',
-or:'\u2228',
-cap:'\u2229',
-cup:'\u222A',
-int:'\u222B',
-there4:'\u2234',
-sim:'\u223C',
-cong:'\u2245',
-asymp:'\u2248',
-ne:'\u2260',
-equiv:'\u2261',
-le:'\u2264',
-ge:'\u2265',
-sub:'\u2282',
-sup:'\u2283',
-nsub:'\u2284',
-sube:'\u2286',
-supe:'\u2287',
-oplus:'\u2295',
-otimes:'\u2297',
-perp:'\u22A5',
-sdot:'\u22C5',
-lceil:'\u2308',
-rceil:'\u2309',
-lfloor:'\u230A',
-rfloor:'\u230B',
-loz:'\u25CA',
-spades:'\u2660',
-clubs:'\u2663',
-hearts:'\u2665',
-diams:'\u2666',
-lang:'\u27E8',
-rang:'\u27E9'};
-
-
-
-},
-
-function(module,exports,__webpack_require__){
-
-"use strict";
-Object.defineProperty(exports,"__esModule",{value:true});
-var error_handler_1=__webpack_require__(10);
-var scanner_1=__webpack_require__(12);
-var token_1=__webpack_require__(13);
-var Reader=function(){
-function Reader(){
-this.values=[];
-this.curly=this.paren=-1;
-}
-
-Reader.prototype.beforeFunctionExpression=function(t){
-return['(','{','[','in','typeof','instanceof','new',
-'return','case','delete','throw','void',
-
-'=','+=','-=','*=','**=','/=','%=','<<=','>>=','>>>=',
-'&=','|=','^=',',',
-
-'+','-','*','**','/','%','++','--','<<','>>','>>>','&',
-'|','^','!','~','&&','||','?',':','===','==','>=',
-'<=','<','>','!=','!=='].indexOf(t)>=0;
-};
-
-
-Reader.prototype.isRegexStart=function(){
-var previous=this.values[this.values.length-1];
-var regex=previous!==null;
-switch(previous){
-case'this':
-case']':
-regex=false;
-break;
-case')':
-var keyword=this.values[this.paren-1];
-regex=keyword==='if'||keyword==='while'||keyword==='for'||keyword==='with';
-break;
-case'}':
-
-
-regex=false;
-if(this.values[this.curly-3]==='function'){
-
-var check=this.values[this.curly-4];
-regex=check?!this.beforeFunctionExpression(check):false;
-}else
-if(this.values[this.curly-4]==='function'){
-
-var check=this.values[this.curly-5];
-regex=check?!this.beforeFunctionExpression(check):true;
-}
-break;
-default:
-break;}
-
-return regex;
-};
-Reader.prototype.push=function(token){
-if(token.type===7||token.type===4){
-if(token.value==='{'){
-this.curly=this.values.length;
-}else
-if(token.value==='('){
-this.paren=this.values.length;
-}
-this.values.push(token.value);
-}else
-{
-this.values.push(null);
-}
-};
-return Reader;
-}();
-var Tokenizer=function(){
-function Tokenizer(code,config){
-this.errorHandler=new error_handler_1.ErrorHandler();
-this.errorHandler.tolerant=config?typeof config.tolerant==='boolean'&&config.tolerant:false;
-this.scanner=new scanner_1.Scanner(code,this.errorHandler);
-this.scanner.trackComment=config?typeof config.comment==='boolean'&&config.comment:false;
-this.trackRange=config?typeof config.range==='boolean'&&config.range:false;
-this.trackLoc=config?typeof config.loc==='boolean'&&config.loc:false;
-this.buffer=[];
-this.reader=new Reader();
-}
-Tokenizer.prototype.errors=function(){
-return this.errorHandler.errors;
-};
-Tokenizer.prototype.getNextToken=function(){
-if(this.buffer.length===0){
-var comments=this.scanner.scanComments();
-if(this.scanner.trackComment){
-for(var i=0;i<comments.length;++i){
-var e=comments[i];
-var value=this.scanner.source.slice(e.slice[0],e.slice[1]);
-var comment={
-type:e.multiLine?'BlockComment':'LineComment',
-value:value};
-
-if(this.trackRange){
-comment.range=e.range;
-}
-if(this.trackLoc){
-comment.loc=e.loc;
-}
-this.buffer.push(comment);
-}
-}
-if(!this.scanner.eof()){
-var loc=void 0;
-if(this.trackLoc){
-loc={
-start:{
-line:this.scanner.lineNumber,
-column:this.scanner.index-this.scanner.lineStart},
-
-end:{}};
-
-}
-var startRegex=this.scanner.source[this.scanner.index]==='/'&&this.reader.isRegexStart();
-var token=startRegex?this.scanner.scanRegExp():this.scanner.lex();
-this.reader.push(token);
-var entry={
-type:token_1.TokenName[token.type],
-value:this.scanner.source.slice(token.start,token.end)};
-
-if(this.trackRange){
-entry.range=[token.start,token.end];
-}
-if(this.trackLoc){
-loc.end={
-line:this.scanner.lineNumber,
-column:this.scanner.index-this.scanner.lineStart};
-
-entry.loc=loc;
-}
-if(token.type===9){
-var pattern=token.pattern;
-var flags=token.flags;
-entry.regex={pattern:pattern,flags:flags};
-}
-this.buffer.push(entry);
-}
-}
-return this.buffer.shift();
-};
-return Tokenizer;
-}();
-exports.Tokenizer=Tokenizer;
-
-
-}]);
-
-});
-;
-},{}],131:[function(require,module,exports){
-(function(Buffer){
-var querystring=require('querystring');
-var trim=require('./trim');
-
-
-
-
-
-
-function Link(value){
-
-if(!(this instanceof Link)){
-return new Link(value);
-}
-
-
-this.refs=[];
-
-}
-
-
-
-
-
-Link.pattern=/(?:\<([^\>]+)\>)((\s*;\s*([a-z\*]+)=(("[^"]+")|('[^']+')|([^\,\;]+)))*)(\s*,\s*|$)/gi;
-
-
-
-
-
-Link.attrPattern=/([a-z\*]+)=(?:(?:"([^"]+)")|(?:'([^']+)')|([^\,\;]+))/gi;
-
-
-
-
-
-
-
-Link.isCompatibleEncoding=function(value){
-return /^utf-?8|ascii|utf-?16-?le|ucs-?2|base-?64|latin-?1$/i.test(value);
-};
-
-
-
-
-
-
-
-Link.formatExtendedAttribute=function(attr,data){
-
-var encoding=(data.encoding||'utf-8').toUpperCase();
-var language=data.language||'en';
-
-var encodedValue='';
-
-if(Buffer.isBuffer(data.value)&&Link.isCompatibleEncoding(encoding)){
-encodedValue=data.value.toString(encoding);
-}else if(Buffer.isBuffer(data.value)){
-encodedValue=data.value.toString('hex').
-replace(/[0-9a-f]{2}/gi,'%$1');
-}else{
-encodedValue=querystring.escape(data.value);
-}
-
-return attr+'='+encoding+'\''+
-language+'\''+encodedValue;
-
-};
-
-
-
-
-
-
-
-Link.formatAttribute=function(attr,value){
-
-
-if(/\*$/.test(attr)||typeof value!=='string')
-return Link.formatExtendedAttribute(attr,value);
-
-
-
-var needsQuotes=/[^a-z]/i.test(value);
-
-if(needsQuotes){
-
-value=querystring.escape(value).
-replace(/%20/g,' ').
-replace(/%2C/g,',').
-replace(/%3B/g,';');
-
-value='"'+value+'"';
-}
-
-return attr+'='+value;
-
-};
-
-
-
-
-
-
-
-Link.parseExtendedValue=function(value){
-var parts=/([^']+)?(?:'([^']+)')?(.+)/.exec(value);
-return{
-language:parts[2].toLowerCase(),
-encoding:Link.isCompatibleEncoding(parts[1])?
-null:parts[1].toLowerCase(),
-value:Link.isCompatibleEncoding(parts[1])?
-querystring.unescape(parts[3]):parts[3]};
-
-};
-
-
-
-
-
-
-
-Link.setAttr=function(link,attr,value){
-
-
-
-if(attr==='rel'&&link[attr]!=null)
-return link;
-
-if(Array.isArray(link[attr])){
-link[attr].push(value);
-}else if(link[attr]!=null){
-link[attr]=[link[attr],value];
-}else{
-link[attr]=value;
-}
-
-return link;
-
-};
-
-
-
-
-Link.parseParams=function(link,uri){
-
-var kvs={};
-var params=/(.+)\?(.+)/gi.exec(uri);
-
-if(!params){
-return link;
-}
-
-params=params[2].split('&');
-
-for(var i=0;i<params.length;i++){
-var param=params[i].split('=');
-kvs[param[0]]=param[1];
-}
-
-Link.setAttr(link,'params',kvs);
-
-return link;
-
-};
-
-
-
-
-
-
-
-
-Link.parseAttrs=function(link,parts){
-
-var match=null;
-var attr='';
-var value='';
-var attrs='';
-
-var uriAttrs=/<(.*)>;\s*(.*)/gi.exec(parts);
-if(uriAttrs){
-attrs=uriAttrs[2];
-link=Link.parseParams(link,uriAttrs[1]);
-}
-
-while(match=Link.attrPattern.exec(attrs)){
-attr=match[1].toLowerCase();
-value=match[4]||match[3]||match[2];
-if(/\*$/.test(attr)){
-Link.setAttr(link,attr,Link.parseExtendedValue(value));
-}else if(/%/.test(value)){
-Link.setAttr(link,attr,querystring.unescape(value));
-}else{
-Link.setAttr(link,attr,value);
-}
-}
-
-return link;
-
-};
-
-Link.parse=function(value){
-return new Link().parse(value);
-};
-
-
-
-
-
-Link.prototype={
-
-constructor:Link,
-
-
-
-
-
-
-rel:function(value){
-
-var links=[];
-
-for(var i=0;i<this.refs.length;i++){
-if(this.refs[i].rel===value){
-links.push(this.refs[i]);
-}
-}
-
-return links;
-
-},
-
-
-
-
-
-
-
-get:function(attr,value){
-
-attr=attr.toLowerCase();
-
-var links=[];
-
-for(var i=0;i<this.refs.length;i++){
-if(this.refs[i][attr]===value){
-links.push(this.refs[i]);
-}
-}
-
-return links;
-
-},
-
-set:function(link){
-this.refs.push(link);
-return this;
-},
-
-has:function(attr,value){
-return this.get(attr,value)!=null;
-},
-
-parse:function(value){
-
-
-value=trim(value).
-replace(/\r?\n[\x20\x09]+/g,'');
-
-var match=null;
-
-while(match=Link.pattern.exec(value)){
-var link=Link.parseAttrs({uri:match[1]},match[0]);
-this.refs.push(link);
-}
-
-return this;
-
-},
-
-toString:function(){
-
-var refs=[];
-var link='';
-var ref=null;
-
-for(var i=0;i<this.refs.length;i++){
-ref=this.refs[i];
-link=Object.keys(this.refs[i]).reduce(function(link,attr){
-if(attr==='uri')return link;
-return link+'; '+Link.formatAttribute(attr,ref[attr]);
-},'<'+ref.uri+'>');
-refs.push(link);
-}
-
-return refs.join(', ');
-
-}};
-
-
-
-
-module.exports=Link;
-
-}).call(this,{"isBuffer":require("../../../lighthouse-extension/node_modules/is-buffer/index.js")});
-},{"../../../lighthouse-extension/node_modules/is-buffer/index.js":59,"./trim":132,"querystring":74}],132:[function(require,module,exports){
-module.exports=function trim(value){
-return value.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,'');
-};
-
-},{}],133:[function(require,module,exports){
-
-
-
-
-
-
-
-
-
-
-
-
-
-var ImageSSIM;
-(function(ImageSSIM){
-'use strict';
-
-
-
-(function(Channels){
-Channels[Channels["Grey"]=1]="Grey";
-Channels[Channels["GreyAlpha"]=2]="GreyAlpha";
-Channels[Channels["RGB"]=3]="RGB";
-Channels[Channels["RGBAlpha"]=4]="RGBAlpha";
-})(ImageSSIM.Channels||(ImageSSIM.Channels={}));
-var Channels=ImageSSIM.Channels;
-
-
-
-
-function compare(image1,image2,windowSize,K1,K2,luminance,bitsPerComponent){
-if(windowSize===void 0){windowSize=8;}
-if(K1===void 0){K1=0.01;}
-if(K2===void 0){K2=0.03;}
-if(luminance===void 0){luminance=true;}
-if(bitsPerComponent===void 0){bitsPerComponent=8;}
-if(image1.width!==image2.width||image1.height!==image2.height){
-throw new Error('Images have different sizes!');
-}
-
-var L=(1<<bitsPerComponent)-1;
-
-var c1=Math.pow(K1*L,2),c2=Math.pow(K2*L,2),numWindows=0,mssim=0.0;
-var mcs=0.0;
-function iteration(lumaValues1,lumaValues2,averageLumaValue1,averageLumaValue2){
-
-var sigxy,sigsqx,sigsqy;
-sigxy=sigsqx=sigsqy=0.0;
-for(var i=0;i<lumaValues1.length;i++){
-sigsqx+=Math.pow(lumaValues1[i]-averageLumaValue1,2);
-sigsqy+=Math.pow(lumaValues2[i]-averageLumaValue2,2);
-sigxy+=(lumaValues1[i]-averageLumaValue1)*(lumaValues2[i]-averageLumaValue2);
-}
-var numPixelsInWin=lumaValues1.length-1;
-sigsqx/=numPixelsInWin;
-sigsqy/=numPixelsInWin;
-sigxy/=numPixelsInWin;
-
-var numerator=(2*averageLumaValue1*averageLumaValue2+c1)*(2*sigxy+c2);
-var denominator=(Math.pow(averageLumaValue1,2)+Math.pow(averageLumaValue2,2)+c1)*(sigsqx+sigsqy+c2);
-mssim+=numerator/denominator;
-mcs+=(2*sigxy+c2)/(sigsqx+sigsqy+c2);
-numWindows++;
-}
-
-Internals._iterate(image1,image2,windowSize,luminance,iteration);
-return{ssim:mssim/numWindows,mcs:mcs/numWindows};
-}
-ImageSSIM.compare=compare;
-
-
-
-var Internals;
-(function(Internals){
-function _iterate(image1,image2,windowSize,luminance,callback){
-var width=image1.width,height=image1.height;
-for(var y=0;y<height;y+=windowSize){
-for(var x=0;x<width;x+=windowSize){
-
-var windowWidth=Math.min(windowSize,width-x),windowHeight=Math.min(windowSize,height-y);
-var lumaValues1=_lumaValuesForWindow(image1,x,y,windowWidth,windowHeight,luminance),lumaValues2=_lumaValuesForWindow(image2,x,y,windowWidth,windowHeight,luminance),averageLuma1=_averageLuma(lumaValues1),averageLuma2=_averageLuma(lumaValues2);
-callback(lumaValues1,lumaValues2,averageLuma1,averageLuma2);
-}
-}
-}
-Internals._iterate=_iterate;
-function _lumaValuesForWindow(image,x,y,width,height,luminance){
-var array=image.data,lumaValues=new Float32Array(new ArrayBuffer(width*height*4)),counter=0;
-var maxj=y+height;
-for(var j=y;j<maxj;j++){
-var offset=j*image.width;
-var i=(offset+x)*image.channels;
-var maxi=(offset+x+width)*image.channels;
-switch(image.channels){
-case 1:
-while(i<maxi){
-
-lumaValues[counter++]=array[i++];
-}
-break;
-case 2:
-while(i<maxi){
-lumaValues[counter++]=array[i++]*(array[i++]/255);
-}
-break;
-case 3:
-if(luminance){
-while(i<maxi){
-lumaValues[counter++]=array[i++]*0.212655+array[i++]*0.715158+array[i++]*0.072187;
-}
-}else
-{
-while(i<maxi){
-lumaValues[counter++]=array[i++]+array[i++]+array[i++];
-}
-}
-break;
-case 4:
-if(luminance){
-while(i<maxi){
-lumaValues[counter++]=(array[i++]*0.212655+array[i++]*0.715158+array[i++]*0.072187)*(array[i++]/255);
-}
-}else
-{
-while(i<maxi){
-lumaValues[counter++]=(array[i++]+array[i++]+array[i++])*(array[i++]/255);
-}
-}
-break;}
-
-}
-return lumaValues;
-}
-function _averageLuma(lumaValues){
-var sumLuma=0.0;
-for(var i=0;i<lumaValues.length;i++){
-sumLuma+=lumaValues[i];
-}
-return sumLuma/lumaValues.length;
-}
-})(Internals||(Internals={}));
-})(ImageSSIM||(ImageSSIM={}));
-module.exports=ImageSSIM;
-
-},{}],134:[function(require,module,exports){
-var encode=require('./lib/encoder'),
-decode=require('./lib/decoder');
-
-module.exports={
-encode:encode,
-decode:decode};
-
-
-},{"./lib/decoder":135,"./lib/encoder":136}],135:[function(require,module,exports){
-(function(Buffer){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var JpegImage=function jpegImage(){
-"use strict";
-var dctZigZag=new Int32Array([
-0,
-1,8,
-16,9,2,
-3,10,17,24,
-32,25,18,11,4,
-5,12,19,26,33,40,
-48,41,34,27,20,13,6,
-7,14,21,28,35,42,49,56,
-57,50,43,36,29,22,15,
-23,30,37,44,51,58,
-59,52,45,38,31,
-39,46,53,60,
-61,54,47,
-55,62,
-63]);
-
-
-var dctCos1=4017;
-var dctSin1=799;
-var dctCos3=3406;
-var dctSin3=2276;
-var dctCos6=1567;
-var dctSin6=3784;
-var dctSqrt2=5793;
-var dctSqrt1d2=2896;
-
-function constructor(){
-}
-
-function buildHuffmanTable(codeLengths,values){
-var k=0,code=[],i,j,length=16;
-while(length>0&&!codeLengths[length-1])
-length--;
-code.push({children:[],index:0});
-var p=code[0],q;
-for(i=0;i<length;i++){
-for(j=0;j<codeLengths[i];j++){
-p=code.pop();
-p.children[p.index]=values[k];
-while(p.index>0){
-p=code.pop();
-}
-p.index++;
-code.push(p);
-while(code.length<=i){
-code.push(q={children:[],index:0});
-p.children[p.index]=q.children;
-p=q;
-}
-k++;
-}
-if(i+1<length){
-
-code.push(q={children:[],index:0});
-p.children[p.index]=q.children;
-p=q;
-}
-}
-return code[0].children;
-}
-
-function decodeScan(data,offset,
-frame,components,resetInterval,
-spectralStart,spectralEnd,
-successivePrev,successive){
-var precision=frame.precision;
-var samplesPerLine=frame.samplesPerLine;
-var scanLines=frame.scanLines;
-var mcusPerLine=frame.mcusPerLine;
-var progressive=frame.progressive;
-var maxH=frame.maxH,maxV=frame.maxV;
-
-var startOffset=offset,bitsData=0,bitsCount=0;
-function readBit(){
-if(bitsCount>0){
-bitsCount--;
-return bitsData>>bitsCount&1;
-}
-bitsData=data[offset++];
-if(bitsData==0xFF){
-var nextByte=data[offset++];
-if(nextByte){
-throw"unexpected marker: "+(bitsData<<8|nextByte).toString(16);
-}
-
-}
-bitsCount=7;
-return bitsData>>>7;
-}
-function decodeHuffman(tree){
-var node=tree,bit;
-while((bit=readBit())!==null){
-node=node[bit];
-if(typeof node==='number')
-return node;
-if(typeof node!=='object')
-throw"invalid huffman sequence";
-}
-return null;
-}
-function receive(length){
-var n=0;
-while(length>0){
-var bit=readBit();
-if(bit===null)return;
-n=n<<1|bit;
-length--;
-}
-return n;
-}
-function receiveAndExtend(length){
-var n=receive(length);
-if(n>=1<<length-1)
-return n;
-return n+(-1<<length)+1;
-}
-function decodeBaseline(component,zz){
-var t=decodeHuffman(component.huffmanTableDC);
-var diff=t===0?0:receiveAndExtend(t);
-zz[0]=component.pred+=diff;
-var k=1;
-while(k<64){
-var rs=decodeHuffman(component.huffmanTableAC);
-var s=rs&15,r=rs>>4;
-if(s===0){
-if(r<15)
-break;
-k+=16;
-continue;
-}
-k+=r;
-var z=dctZigZag[k];
-zz[z]=receiveAndExtend(s);
-k++;
-}
-}
-function decodeDCFirst(component,zz){
-var t=decodeHuffman(component.huffmanTableDC);
-var diff=t===0?0:receiveAndExtend(t)<<successive;
-zz[0]=component.pred+=diff;
-}
-function decodeDCSuccessive(component,zz){
-zz[0]|=readBit()<<successive;
-}
-var eobrun=0;
-function decodeACFirst(component,zz){
-if(eobrun>0){
-eobrun--;
-return;
-}
-var k=spectralStart,e=spectralEnd;
-while(k<=e){
-var rs=decodeHuffman(component.huffmanTableAC);
-var s=rs&15,r=rs>>4;
-if(s===0){
-if(r<15){
-eobrun=receive(r)+(1<<r)-1;
-break;
-}
-k+=16;
-continue;
-}
-k+=r;
-var z=dctZigZag[k];
-zz[z]=receiveAndExtend(s)*(1<<successive);
-k++;
-}
-}
-var successiveACState=0,successiveACNextValue;
-function decodeACSuccessive(component,zz){
-var k=spectralStart,e=spectralEnd,r=0;
-while(k<=e){
-var z=dctZigZag[k];
-switch(successiveACState){
-case 0:
-var rs=decodeHuffman(component.huffmanTableAC);
-var s=rs&15,r=rs>>4;
-if(s===0){
-if(r<15){
-eobrun=receive(r)+(1<<r);
-successiveACState=4;
-}else{
-r=16;
-successiveACState=1;
-}
-}else{
-if(s!==1)
-throw"invalid ACn encoding";
-successiveACNextValue=receiveAndExtend(s);
-successiveACState=r?2:3;
-}
-continue;
-case 1:
-case 2:
-if(zz[z])
-zz[z]+=readBit()<<successive;else
-{
-r--;
-if(r===0)
-successiveACState=successiveACState==2?3:0;
-}
-break;
-case 3:
-if(zz[z])
-zz[z]+=readBit()<<successive;else
-{
-zz[z]=successiveACNextValue<<successive;
-successiveACState=0;
-}
-break;
-case 4:
-if(zz[z])
-zz[z]+=readBit()<<successive;
-break;}
-
-k++;
-}
-if(successiveACState===4){
-eobrun--;
-if(eobrun===0)
-successiveACState=0;
-}
-}
-function decodeMcu(component,decode,mcu,row,col){
-var mcuRow=mcu/mcusPerLine|0;
-var mcuCol=mcu%mcusPerLine;
-var blockRow=mcuRow*component.v+row;
-var blockCol=mcuCol*component.h+col;
-decode(component,component.blocks[blockRow][blockCol]);
-}
-function decodeBlock(component,decode,mcu){
-var blockRow=mcu/component.blocksPerLine|0;
-var blockCol=mcu%component.blocksPerLine;
-decode(component,component.blocks[blockRow][blockCol]);
-}
-
-var componentsLength=components.length;
-var component,i,j,k,n;
-var decodeFn;
-if(progressive){
-if(spectralStart===0)
-decodeFn=successivePrev===0?decodeDCFirst:decodeDCSuccessive;else
-
-decodeFn=successivePrev===0?decodeACFirst:decodeACSuccessive;
-}else{
-decodeFn=decodeBaseline;
-}
-
-var mcu=0,marker;
-var mcuExpected;
-if(componentsLength==1){
-mcuExpected=components[0].blocksPerLine*components[0].blocksPerColumn;
-}else{
-mcuExpected=mcusPerLine*frame.mcusPerColumn;
-}
-if(!resetInterval)resetInterval=mcuExpected;
-
-var h,v;
-while(mcu<mcuExpected){
-
-for(i=0;i<componentsLength;i++)
-components[i].pred=0;
-eobrun=0;
-
-if(componentsLength==1){
-component=components[0];
-for(n=0;n<resetInterval;n++){
-decodeBlock(component,decodeFn,mcu);
-mcu++;
-}
-}else{
-for(n=0;n<resetInterval;n++){
-for(i=0;i<componentsLength;i++){
-component=components[i];
-h=component.h;
-v=component.v;
-for(j=0;j<v;j++){
-for(k=0;k<h;k++){
-decodeMcu(component,decodeFn,mcu,j,k);
-}
-}
-}
-mcu++;
-
-
-if(mcu===mcuExpected)break;
-}
-}
-
-
-bitsCount=0;
-marker=data[offset]<<8|data[offset+1];
-if(marker<0xFF00){
-throw"marker was not found";
-}
-
-if(marker>=0xFFD0&&marker<=0xFFD7){
-offset+=2;
-}else
-
-break;
-}
-
-return offset-startOffset;
-}
-
-function buildComponentData(frame,component){
-var lines=[];
-var blocksPerLine=component.blocksPerLine;
-var blocksPerColumn=component.blocksPerColumn;
-var samplesPerLine=blocksPerLine<<3;
-var R=new Int32Array(64),r=new Uint8Array(64);
-
-
-
-
-
-
-function quantizeAndInverse(zz,dataOut,dataIn){
-var qt=component.quantizationTable;
-var v0,v1,v2,v3,v4,v5,v6,v7,t;
-var p=dataIn;
-var i;
-
-
-for(i=0;i<64;i++)
-p[i]=zz[i]*qt[i];
-
-
-for(i=0;i<8;++i){
-var row=8*i;
-
-
-if(p[1+row]==0&&p[2+row]==0&&p[3+row]==0&&
-p[4+row]==0&&p[5+row]==0&&p[6+row]==0&&
-p[7+row]==0){
-t=dctSqrt2*p[0+row]+512>>10;
-p[0+row]=t;
-p[1+row]=t;
-p[2+row]=t;
-p[3+row]=t;
-p[4+row]=t;
-p[5+row]=t;
-p[6+row]=t;
-p[7+row]=t;
-continue;
-}
-
-
-v0=dctSqrt2*p[0+row]+128>>8;
-v1=dctSqrt2*p[4+row]+128>>8;
-v2=p[2+row];
-v3=p[6+row];
-v4=dctSqrt1d2*(p[1+row]-p[7+row])+128>>8;
-v7=dctSqrt1d2*(p[1+row]+p[7+row])+128>>8;
-v5=p[3+row]<<4;
-v6=p[5+row]<<4;
-
-
-t=v0-v1+1>>1;
-v0=v0+v1+1>>1;
-v1=t;
-t=v2*dctSin6+v3*dctCos6+128>>8;
-v2=v2*dctCos6-v3*dctSin6+128>>8;
-v3=t;
-t=v4-v6+1>>1;
-v4=v4+v6+1>>1;
-v6=t;
-t=v7+v5+1>>1;
-v5=v7-v5+1>>1;
-v7=t;
-
-
-t=v0-v3+1>>1;
-v0=v0+v3+1>>1;
-v3=t;
-t=v1-v2+1>>1;
-v1=v1+v2+1>>1;
-v2=t;
-t=v4*dctSin3+v7*dctCos3+2048>>12;
-v4=v4*dctCos3-v7*dctSin3+2048>>12;
-v7=t;
-t=v5*dctSin1+v6*dctCos1+2048>>12;
-v5=v5*dctCos1-v6*dctSin1+2048>>12;
-v6=t;
-
-
-p[0+row]=v0+v7;
-p[7+row]=v0-v7;
-p[1+row]=v1+v6;
-p[6+row]=v1-v6;
-p[2+row]=v2+v5;
-p[5+row]=v2-v5;
-p[3+row]=v3+v4;
-p[4+row]=v3-v4;
-}
-
-
-for(i=0;i<8;++i){
-var col=i;
-
-
-if(p[1*8+col]==0&&p[2*8+col]==0&&p[3*8+col]==0&&
-p[4*8+col]==0&&p[5*8+col]==0&&p[6*8+col]==0&&
-p[7*8+col]==0){
-t=dctSqrt2*dataIn[i+0]+8192>>14;
-p[0*8+col]=t;
-p[1*8+col]=t;
-p[2*8+col]=t;
-p[3*8+col]=t;
-p[4*8+col]=t;
-p[5*8+col]=t;
-p[6*8+col]=t;
-p[7*8+col]=t;
-continue;
-}
-
-
-v0=dctSqrt2*p[0*8+col]+2048>>12;
-v1=dctSqrt2*p[4*8+col]+2048>>12;
-v2=p[2*8+col];
-v3=p[6*8+col];
-v4=dctSqrt1d2*(p[1*8+col]-p[7*8+col])+2048>>12;
-v7=dctSqrt1d2*(p[1*8+col]+p[7*8+col])+2048>>12;
-v5=p[3*8+col];
-v6=p[5*8+col];
-
-
-t=v0-v1+1>>1;
-v0=v0+v1+1>>1;
-v1=t;
-t=v2*dctSin6+v3*dctCos6+2048>>12;
-v2=v2*dctCos6-v3*dctSin6+2048>>12;
-v3=t;
-t=v4-v6+1>>1;
-v4=v4+v6+1>>1;
-v6=t;
-t=v7+v5+1>>1;
-v5=v7-v5+1>>1;
-v7=t;
-
-
-t=v0-v3+1>>1;
-v0=v0+v3+1>>1;
-v3=t;
-t=v1-v2+1>>1;
-v1=v1+v2+1>>1;
-v2=t;
-t=v4*dctSin3+v7*dctCos3+2048>>12;
-v4=v4*dctCos3-v7*dctSin3+2048>>12;
-v7=t;
-t=v5*dctSin1+v6*dctCos1+2048>>12;
-v5=v5*dctCos1-v6*dctSin1+2048>>12;
-v6=t;
-
-
-p[0*8+col]=v0+v7;
-p[7*8+col]=v0-v7;
-p[1*8+col]=v1+v6;
-p[6*8+col]=v1-v6;
-p[2*8+col]=v2+v5;
-p[5*8+col]=v2-v5;
-p[3*8+col]=v3+v4;
-p[4*8+col]=v3-v4;
-}
-
-
-for(i=0;i<64;++i){
-var sample=128+(p[i]+8>>4);
-dataOut[i]=sample<0?0:sample>0xFF?0xFF:sample;
-}
-}
-
-var i,j;
-for(var blockRow=0;blockRow<blocksPerColumn;blockRow++){
-var scanLine=blockRow<<3;
-for(i=0;i<8;i++)
-lines.push(new Uint8Array(samplesPerLine));
-for(var blockCol=0;blockCol<blocksPerLine;blockCol++){
-quantizeAndInverse(component.blocks[blockRow][blockCol],r,R);
-
-var offset=0,sample=blockCol<<3;
-for(j=0;j<8;j++){
-var line=lines[scanLine+j];
-for(i=0;i<8;i++)
-line[sample+i]=r[offset++];
-}
-}
-}
-return lines;
-}
-
-function clampTo8bit(a){
-return a<0?0:a>255?255:a;
-}
-
-constructor.prototype={
-load:function load(path){
-var xhr=new XMLHttpRequest();
-xhr.open("GET",path,true);
-xhr.responseType="arraybuffer";
-xhr.onload=function(){
-
-var data=new Uint8Array(xhr.response||xhr.mozResponseArrayBuffer);
-this.parse(data);
-if(this.onload)
-this.onload();
-}.bind(this);
-xhr.send(null);
-},
-parse:function parse(data){
-var offset=0,length=data.length;
-function readUint16(){
-var value=data[offset]<<8|data[offset+1];
-offset+=2;
-return value;
-}
-function readDataBlock(){
-var length=readUint16();
-var array=data.subarray(offset,offset+length-2);
-offset+=array.length;
-return array;
-}
-function prepareComponents(frame){
-var maxH=0,maxV=0;
-var component,componentId;
-for(componentId in frame.components){
-if(frame.components.hasOwnProperty(componentId)){
-component=frame.components[componentId];
-if(maxH<component.h)maxH=component.h;
-if(maxV<component.v)maxV=component.v;
-}
-}
-var mcusPerLine=Math.ceil(frame.samplesPerLine/8/maxH);
-var mcusPerColumn=Math.ceil(frame.scanLines/8/maxV);
-for(componentId in frame.components){
-if(frame.components.hasOwnProperty(componentId)){
-component=frame.components[componentId];
-var blocksPerLine=Math.ceil(Math.ceil(frame.samplesPerLine/8)*component.h/maxH);
-var blocksPerColumn=Math.ceil(Math.ceil(frame.scanLines/8)*component.v/maxV);
-var blocksPerLineForMcu=mcusPerLine*component.h;
-var blocksPerColumnForMcu=mcusPerColumn*component.v;
-var blocks=[];
-for(var i=0;i<blocksPerColumnForMcu;i++){
-var row=[];
-for(var j=0;j<blocksPerLineForMcu;j++)
-row.push(new Int32Array(64));
-blocks.push(row);
-}
-component.blocksPerLine=blocksPerLine;
-component.blocksPerColumn=blocksPerColumn;
-component.blocks=blocks;
-}
-}
-frame.maxH=maxH;
-frame.maxV=maxV;
-frame.mcusPerLine=mcusPerLine;
-frame.mcusPerColumn=mcusPerColumn;
-}
-var jfif=null;
-var adobe=null;
-var pixels=null;
-var frame,resetInterval;
-var quantizationTables=[],frames=[];
-var huffmanTablesAC=[],huffmanTablesDC=[];
-var fileMarker=readUint16();
-if(fileMarker!=0xFFD8){
-throw"SOI not found";
-}
-
-fileMarker=readUint16();
-while(fileMarker!=0xFFD9){
-var i,j,l;
-switch(fileMarker){
-case 0xFF00:break;
-case 0xFFE0:
-case 0xFFE1:
-case 0xFFE2:
-case 0xFFE3:
-case 0xFFE4:
-case 0xFFE5:
-case 0xFFE6:
-case 0xFFE7:
-case 0xFFE8:
-case 0xFFE9:
-case 0xFFEA:
-case 0xFFEB:
-case 0xFFEC:
-case 0xFFED:
-case 0xFFEE:
-case 0xFFEF:
-case 0xFFFE:
-var appData=readDataBlock();
-
-if(fileMarker===0xFFE0){
-if(appData[0]===0x4A&&appData[1]===0x46&&appData[2]===0x49&&
-appData[3]===0x46&&appData[4]===0){
-jfif={
-version:{major:appData[5],minor:appData[6]},
-densityUnits:appData[7],
-xDensity:appData[8]<<8|appData[9],
-yDensity:appData[10]<<8|appData[11],
-thumbWidth:appData[12],
-thumbHeight:appData[13],
-thumbData:appData.subarray(14,14+3*appData[12]*appData[13])};
-
-}
-}
-
-if(fileMarker===0xFFEE){
-if(appData[0]===0x41&&appData[1]===0x64&&appData[2]===0x6F&&
-appData[3]===0x62&&appData[4]===0x65&&appData[5]===0){
-adobe={
-version:appData[6],
-flags0:appData[7]<<8|appData[8],
-flags1:appData[9]<<8|appData[10],
-transformCode:appData[11]};
-
-}
-}
-break;
-
-case 0xFFDB:
-var quantizationTablesLength=readUint16();
-var quantizationTablesEnd=quantizationTablesLength+offset-2;
-while(offset<quantizationTablesEnd){
-var quantizationTableSpec=data[offset++];
-var tableData=new Int32Array(64);
-if(quantizationTableSpec>>4===0){
-for(j=0;j<64;j++){
-var z=dctZigZag[j];
-tableData[z]=data[offset++];
-}
-}else if(quantizationTableSpec>>4===1){
-for(j=0;j<64;j++){
-var z=dctZigZag[j];
-tableData[z]=readUint16();
-}
-}else
-throw"DQT: invalid table spec";
-quantizationTables[quantizationTableSpec&15]=tableData;
-}
-break;
-
-case 0xFFC0:
-case 0xFFC1:
-case 0xFFC2:
-readUint16();
-frame={};
-frame.extended=fileMarker===0xFFC1;
-frame.progressive=fileMarker===0xFFC2;
-frame.precision=data[offset++];
-frame.scanLines=readUint16();
-frame.samplesPerLine=readUint16();
-frame.components={};
-frame.componentsOrder=[];
-var componentsCount=data[offset++],componentId;
-var maxH=0,maxV=0;
-for(i=0;i<componentsCount;i++){
-componentId=data[offset];
-var h=data[offset+1]>>4;
-var v=data[offset+1]&15;
-var qId=data[offset+2];
-frame.componentsOrder.push(componentId);
-frame.components[componentId]={
-h:h,
-v:v,
-quantizationIdx:qId};
-
-offset+=3;
-}
-prepareComponents(frame);
-frames.push(frame);
-break;
-
-case 0xFFC4:
-var huffmanLength=readUint16();
-for(i=2;i<huffmanLength;){
-var huffmanTableSpec=data[offset++];
-var codeLengths=new Uint8Array(16);
-var codeLengthSum=0;
-for(j=0;j<16;j++,offset++)
-codeLengthSum+=codeLengths[j]=data[offset];
-var huffmanValues=new Uint8Array(codeLengthSum);
-for(j=0;j<codeLengthSum;j++,offset++)
-huffmanValues[j]=data[offset];
-i+=17+codeLengthSum;
-
-(huffmanTableSpec>>4===0?
-huffmanTablesDC:huffmanTablesAC)[huffmanTableSpec&15]=
-buildHuffmanTable(codeLengths,huffmanValues);
-}
-break;
-
-case 0xFFDD:
-readUint16();
-resetInterval=readUint16();
-break;
-
-case 0xFFDA:
-var scanLength=readUint16();
-var selectorsCount=data[offset++];
-var components=[],component;
-for(i=0;i<selectorsCount;i++){
-component=frame.components[data[offset++]];
-var tableSpec=data[offset++];
-component.huffmanTableDC=huffmanTablesDC[tableSpec>>4];
-component.huffmanTableAC=huffmanTablesAC[tableSpec&15];
-components.push(component);
-}
-var spectralStart=data[offset++];
-var spectralEnd=data[offset++];
-var successiveApproximation=data[offset++];
-var processed=decodeScan(data,offset,
-frame,components,resetInterval,
-spectralStart,spectralEnd,
-successiveApproximation>>4,successiveApproximation&15);
-offset+=processed;
-break;
-default:
-if(data[offset-3]==0xFF&&
-data[offset-2]>=0xC0&&data[offset-2]<=0xFE){
-
-
-offset-=3;
-break;
-}
-throw"unknown JPEG marker "+fileMarker.toString(16);}
-
-fileMarker=readUint16();
-}
-if(frames.length!=1)
-throw"only single frame JPEGs supported";
-
-
-for(var i=0;i<frames.length;i++){
-var cp=frames[i].components;
-for(var j in cp){
-cp[j].quantizationTable=quantizationTables[cp[j].quantizationIdx];
-delete cp[j].quantizationIdx;
-}
-}
-
-this.width=frame.samplesPerLine;
-this.height=frame.scanLines;
-this.jfif=jfif;
-this.adobe=adobe;
-this.components=[];
-for(var i=0;i<frame.componentsOrder.length;i++){
-var component=frame.components[frame.componentsOrder[i]];
-this.components.push({
-lines:buildComponentData(frame,component),
-scaleX:component.h/frame.maxH,
-scaleY:component.v/frame.maxV});
-
-}
-},
-getData:function getData(width,height){
-var scaleX=this.width/width,scaleY=this.height/height;
-
-var component1,component2,component3,component4;
-var component1Line,component2Line,component3Line,component4Line;
-var x,y;
-var offset=0;
-var Y,Cb,Cr,K,C,M,Ye,R,G,B;
-var colorTransform;
-var dataLength=width*height*this.components.length;
-var data=new Uint8Array(dataLength);
-switch(this.components.length){
-case 1:
-component1=this.components[0];
-for(y=0;y<height;y++){
-component1Line=component1.lines[0|y*component1.scaleY*scaleY];
-for(x=0;x<width;x++){
-Y=component1Line[0|x*component1.scaleX*scaleX];
-
-data[offset++]=Y;
-}
-}
-break;
-case 2:
-
-component1=this.components[0];
-component2=this.components[1];
-for(y=0;y<height;y++){
-component1Line=component1.lines[0|y*component1.scaleY*scaleY];
-component2Line=component2.lines[0|y*component2.scaleY*scaleY];
-for(x=0;x<width;x++){
-Y=component1Line[0|x*component1.scaleX*scaleX];
-data[offset++]=Y;
-Y=component2Line[0|x*component2.scaleX*scaleX];
-data[offset++]=Y;
-}
-}
-break;
-case 3:
-
-colorTransform=true;
-
-if(this.adobe&&this.adobe.transformCode)
-colorTransform=true;else
-if(typeof this.colorTransform!=='undefined')
-colorTransform=!!this.colorTransform;
-
-component1=this.components[0];
-component2=this.components[1];
-component3=this.components[2];
-for(y=0;y<height;y++){
-component1Line=component1.lines[0|y*component1.scaleY*scaleY];
-component2Line=component2.lines[0|y*component2.scaleY*scaleY];
-component3Line=component3.lines[0|y*component3.scaleY*scaleY];
-for(x=0;x<width;x++){
-if(!colorTransform){
-R=component1Line[0|x*component1.scaleX*scaleX];
-G=component2Line[0|x*component2.scaleX*scaleX];
-B=component3Line[0|x*component3.scaleX*scaleX];
-}else{
-Y=component1Line[0|x*component1.scaleX*scaleX];
-Cb=component2Line[0|x*component2.scaleX*scaleX];
-Cr=component3Line[0|x*component3.scaleX*scaleX];
-
-R=clampTo8bit(Y+1.402*(Cr-128));
-G=clampTo8bit(Y-0.3441363*(Cb-128)-0.71413636*(Cr-128));
-B=clampTo8bit(Y+1.772*(Cb-128));
-}
-
-data[offset++]=R;
-data[offset++]=G;
-data[offset++]=B;
-}
-}
-break;
-case 4:
-if(!this.adobe)
-throw'Unsupported color mode (4 components)';
-
-colorTransform=false;
-
-if(this.adobe&&this.adobe.transformCode)
-colorTransform=true;else
-if(typeof this.colorTransform!=='undefined')
-colorTransform=!!this.colorTransform;
-
-component1=this.components[0];
-component2=this.components[1];
-component3=this.components[2];
-component4=this.components[3];
-for(y=0;y<height;y++){
-component1Line=component1.lines[0|y*component1.scaleY*scaleY];
-component2Line=component2.lines[0|y*component2.scaleY*scaleY];
-component3Line=component3.lines[0|y*component3.scaleY*scaleY];
-component4Line=component4.lines[0|y*component4.scaleY*scaleY];
-for(x=0;x<width;x++){
-if(!colorTransform){
-C=component1Line[0|x*component1.scaleX*scaleX];
-M=component2Line[0|x*component2.scaleX*scaleX];
-Ye=component3Line[0|x*component3.scaleX*scaleX];
-K=component4Line[0|x*component4.scaleX*scaleX];
-}else{
-Y=component1Line[0|x*component1.scaleX*scaleX];
-Cb=component2Line[0|x*component2.scaleX*scaleX];
-Cr=component3Line[0|x*component3.scaleX*scaleX];
-K=component4Line[0|x*component4.scaleX*scaleX];
-
-C=255-clampTo8bit(Y+1.402*(Cr-128));
-M=255-clampTo8bit(Y-0.3441363*(Cb-128)-0.71413636*(Cr-128));
-Ye=255-clampTo8bit(Y+1.772*(Cb-128));
-}
-data[offset++]=255-C;
-data[offset++]=255-M;
-data[offset++]=255-Ye;
-data[offset++]=255-K;
-}
-}
-break;
-default:
-throw'Unsupported color mode';}
-
-return data;
-},
-copyToImageData:function copyToImageData(imageData){
-var width=imageData.width,height=imageData.height;
-var imageDataArray=imageData.data;
-var data=this.getData(width,height);
-var i=0,j=0,x,y;
-var Y,K,C,M,R,G,B;
-switch(this.components.length){
-case 1:
-for(y=0;y<height;y++){
-for(x=0;x<width;x++){
-Y=data[i++];
-
-imageDataArray[j++]=Y;
-imageDataArray[j++]=Y;
-imageDataArray[j++]=Y;
-imageDataArray[j++]=255;
-}
-}
-break;
-case 3:
-for(y=0;y<height;y++){
-for(x=0;x<width;x++){
-R=data[i++];
-G=data[i++];
-B=data[i++];
-
-imageDataArray[j++]=R;
-imageDataArray[j++]=G;
-imageDataArray[j++]=B;
-imageDataArray[j++]=255;
-}
-}
-break;
-case 4:
-for(y=0;y<height;y++){
-for(x=0;x<width;x++){
-C=data[i++];
-M=data[i++];
-Y=data[i++];
-K=data[i++];
-
-R=255-clampTo8bit(C*(1-K/255)+K);
-G=255-clampTo8bit(M*(1-K/255)+K);
-B=255-clampTo8bit(Y*(1-K/255)+K);
-
-imageDataArray[j++]=R;
-imageDataArray[j++]=G;
-imageDataArray[j++]=B;
-imageDataArray[j++]=255;
-}
-}
-break;
-default:
-throw'Unsupported color mode';}
-
-}};
-
-
-return constructor;
-}();
-module.exports=decode;
-
-function decode(jpegData){
-var arr=new Uint8Array(jpegData);
-var decoder=new JpegImage();
-decoder.parse(arr);
-
-var image={
-width:decoder.width,
-height:decoder.height,
-data:new Buffer(decoder.width*decoder.height*4)};
-
-
-decoder.copyToImageData(image);
-
-return image;
-}
-
-}).call(this,require("buffer").Buffer);
-},{"buffer":54}],136:[function(require,module,exports){
-(function(Buffer){
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var btoa=btoa||function(buf){
-return new Buffer(buf).toString('base64');
-};
-
-function JPEGEncoder(quality){
-var self=this;
-var fround=Math.round;
-var ffloor=Math.floor;
-var YTable=new Array(64);
-var UVTable=new Array(64);
-var fdtbl_Y=new Array(64);
-var fdtbl_UV=new Array(64);
-var YDC_HT;
-var UVDC_HT;
-var YAC_HT;
-var UVAC_HT;
-
-var bitcode=new Array(65535);
-var category=new Array(65535);
-var outputfDCTQuant=new Array(64);
-var DU=new Array(64);
-var byteout=[];
-var bytenew=0;
-var bytepos=7;
-
-var YDU=new Array(64);
-var UDU=new Array(64);
-var VDU=new Array(64);
-var clt=new Array(256);
-var RGB_YUV_TABLE=new Array(2048);
-var currentQuality;
-
-var ZigZag=[
-0,1,5,6,14,15,27,28,
-2,4,7,13,16,26,29,42,
-3,8,12,17,25,30,41,43,
-9,11,18,24,31,40,44,53,
-10,19,23,32,39,45,52,54,
-20,22,33,38,46,51,55,60,
-21,34,37,47,50,56,59,61,
-35,36,48,49,57,58,62,63];
-
-
-var std_dc_luminance_nrcodes=[0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];
-var std_dc_luminance_values=[0,1,2,3,4,5,6,7,8,9,10,11];
-var std_ac_luminance_nrcodes=[0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];
-var std_ac_luminance_values=[
-0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
-0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
-0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
-0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
-0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
-0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
-0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
-0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
-0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
-0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
-0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
-0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
-0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
-0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
-0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
-0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
-0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
-0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
-0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
-0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
-0xf9,0xfa];
-
-
-var std_dc_chrominance_nrcodes=[0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];
-var std_dc_chrominance_values=[0,1,2,3,4,5,6,7,8,9,10,11];
-var std_ac_chrominance_nrcodes=[0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];
-var std_ac_chrominance_values=[
-0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
-0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
-0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
-0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
-0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
-0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
-0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
-0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
-0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
-0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
-0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
-0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
-0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
-0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
-0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
-0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
-0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
-0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
-0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
-0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
-0xf9,0xfa];
-
-
-function initQuantTables(sf){
-var YQT=[
-16,11,10,16,24,40,51,61,
-12,12,14,19,26,58,60,55,
-14,13,16,24,40,57,69,56,
-14,17,22,29,51,87,80,62,
-18,22,37,56,68,109,103,77,
-24,35,55,64,81,104,113,92,
-49,64,78,87,103,121,120,101,
-72,92,95,98,112,100,103,99];
-
-
-for(var i=0;i<64;i++){
-var t=ffloor((YQT[i]*sf+50)/100);
-if(t<1){
-t=1;
-}else if(t>255){
-t=255;
-}
-YTable[ZigZag[i]]=t;
-}
-var UVQT=[
-17,18,24,47,99,99,99,99,
-18,21,26,66,99,99,99,99,
-24,26,56,99,99,99,99,99,
-47,66,99,99,99,99,99,99,
-99,99,99,99,99,99,99,99,
-99,99,99,99,99,99,99,99,
-99,99,99,99,99,99,99,99,
-99,99,99,99,99,99,99,99];
-
-for(var j=0;j<64;j++){
-var u=ffloor((UVQT[j]*sf+50)/100);
-if(u<1){
-u=1;
-}else if(u>255){
-u=255;
-}
-UVTable[ZigZag[j]]=u;
-}
-var aasf=[
-1.0,1.387039845,1.306562965,1.175875602,
-1.0,0.785694958,0.541196100,0.275899379];
-
-var k=0;
-for(var row=0;row<8;row++)
-{
-for(var col=0;col<8;col++)
-{
-fdtbl_Y[k]=1.0/(YTable[ZigZag[k]]*aasf[row]*aasf[col]*8.0);
-fdtbl_UV[k]=1.0/(UVTable[ZigZag[k]]*aasf[row]*aasf[col]*8.0);
-k++;
-}
-}
-}
-
-function computeHuffmanTbl(nrcodes,std_table){
-var codevalue=0;
-var pos_in_table=0;
-var HT=new Array();
-for(var k=1;k<=16;k++){
-for(var j=1;j<=nrcodes[k];j++){
-HT[std_table[pos_in_table]]=[];
-HT[std_table[pos_in_table]][0]=codevalue;
-HT[std_table[pos_in_table]][1]=k;
-pos_in_table++;
-codevalue++;
-}
-codevalue*=2;
-}
-return HT;
-}
-
-function initHuffmanTbl()
-{
-YDC_HT=computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);
-UVDC_HT=computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);
-YAC_HT=computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);
-UVAC_HT=computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);
-}
-
-function initCategoryNumber()
-{
-var nrlower=1;
-var nrupper=2;
-for(var cat=1;cat<=15;cat++){
-
-for(var nr=nrlower;nr<nrupper;nr++){
-category[32767+nr]=cat;
-bitcode[32767+nr]=[];
-bitcode[32767+nr][1]=cat;
-bitcode[32767+nr][0]=nr;
-}
-
-for(var nrneg=-(nrupper-1);nrneg<=-nrlower;nrneg++){
-category[32767+nrneg]=cat;
-bitcode[32767+nrneg]=[];
-bitcode[32767+nrneg][1]=cat;
-bitcode[32767+nrneg][0]=nrupper-1+nrneg;
-}
-nrlower<<=1;
-nrupper<<=1;
-}
-}
-
-function initRGBYUVTable(){
-for(var i=0;i<256;i++){
-RGB_YUV_TABLE[i]=19595*i;
-RGB_YUV_TABLE[i+256>>0]=38470*i;
-RGB_YUV_TABLE[i+512>>0]=7471*i+0x8000;
-RGB_YUV_TABLE[i+768>>0]=-11059*i;
-RGB_YUV_TABLE[i+1024>>0]=-21709*i;
-RGB_YUV_TABLE[i+1280>>0]=32768*i+0x807FFF;
-RGB_YUV_TABLE[i+1536>>0]=-27439*i;
-RGB_YUV_TABLE[i+1792>>0]=-5329*i;
-}
-}
-
-
-function writeBits(bs)
-{
-var value=bs[0];
-var posval=bs[1]-1;
-while(posval>=0){
-if(value&1<<posval){
-bytenew|=1<<bytepos;
-}
-posval--;
-bytepos--;
-if(bytepos<0){
-if(bytenew==0xFF){
-writeByte(0xFF);
-writeByte(0);
-}else
-{
-writeByte(bytenew);
-}
-bytepos=7;
-bytenew=0;
-}
-}
-}
-
-function writeByte(value)
-{
-
-byteout.push(value);
-}
-
-function writeWord(value)
-{
-writeByte(value>>8&0xFF);
-writeByte(value&0xFF);
-}
-
-
-function fDCTQuant(data,fdtbl)
-{
-var d0,d1,d2,d3,d4,d5,d6,d7;
-
-var dataOff=0;
-var i;
-const I8=8;
-const I64=64;
-for(i=0;i<I8;++i)
-{
-d0=data[dataOff];
-d1=data[dataOff+1];
-d2=data[dataOff+2];
-d3=data[dataOff+3];
-d4=data[dataOff+4];
-d5=data[dataOff+5];
-d6=data[dataOff+6];
-d7=data[dataOff+7];
-
-var tmp0=d0+d7;
-var tmp7=d0-d7;
-var tmp1=d1+d6;
-var tmp6=d1-d6;
-var tmp2=d2+d5;
-var tmp5=d2-d5;
-var tmp3=d3+d4;
-var tmp4=d3-d4;
-
-
-var tmp10=tmp0+tmp3;
-var tmp13=tmp0-tmp3;
-var tmp11=tmp1+tmp2;
-var tmp12=tmp1-tmp2;
-
-data[dataOff]=tmp10+tmp11;
-data[dataOff+4]=tmp10-tmp11;
-
-var z1=(tmp12+tmp13)*0.707106781;
-data[dataOff+2]=tmp13+z1;
-data[dataOff+6]=tmp13-z1;
-
-
-tmp10=tmp4+tmp5;
-tmp11=tmp5+tmp6;
-tmp12=tmp6+tmp7;
-
-
-var z5=(tmp10-tmp12)*0.382683433;
-var z2=0.541196100*tmp10+z5;
-var z4=1.306562965*tmp12+z5;
-var z3=tmp11*0.707106781;
-
-var z11=tmp7+z3;
-var z13=tmp7-z3;
-
-data[dataOff+5]=z13+z2;
-data[dataOff+3]=z13-z2;
-data[dataOff+1]=z11+z4;
-data[dataOff+7]=z11-z4;
-
-dataOff+=8;
-}
-
-
-dataOff=0;
-for(i=0;i<I8;++i)
-{
-d0=data[dataOff];
-d1=data[dataOff+8];
-d2=data[dataOff+16];
-d3=data[dataOff+24];
-d4=data[dataOff+32];
-d5=data[dataOff+40];
-d6=data[dataOff+48];
-d7=data[dataOff+56];
-
-var tmp0p2=d0+d7;
-var tmp7p2=d0-d7;
-var tmp1p2=d1+d6;
-var tmp6p2=d1-d6;
-var tmp2p2=d2+d5;
-var tmp5p2=d2-d5;
-var tmp3p2=d3+d4;
-var tmp4p2=d3-d4;
-
-
-var tmp10p2=tmp0p2+tmp3p2;
-var tmp13p2=tmp0p2-tmp3p2;
-var tmp11p2=tmp1p2+tmp2p2;
-var tmp12p2=tmp1p2-tmp2p2;
-
-data[dataOff]=tmp10p2+tmp11p2;
-data[dataOff+32]=tmp10p2-tmp11p2;
-
-var z1p2=(tmp12p2+tmp13p2)*0.707106781;
-data[dataOff+16]=tmp13p2+z1p2;
-data[dataOff+48]=tmp13p2-z1p2;
-
-
-tmp10p2=tmp4p2+tmp5p2;
-tmp11p2=tmp5p2+tmp6p2;
-tmp12p2=tmp6p2+tmp7p2;
-
-
-var z5p2=(tmp10p2-tmp12p2)*0.382683433;
-var z2p2=0.541196100*tmp10p2+z5p2;
-var z4p2=1.306562965*tmp12p2+z5p2;
-var z3p2=tmp11p2*0.707106781;
-
-var z11p2=tmp7p2+z3p2;
-var z13p2=tmp7p2-z3p2;
-
-data[dataOff+40]=z13p2+z2p2;
-data[dataOff+24]=z13p2-z2p2;
-data[dataOff+8]=z11p2+z4p2;
-data[dataOff+56]=z11p2-z4p2;
-
-dataOff++;
-}
-
-
-var fDCTQuant;
-for(i=0;i<I64;++i)
-{
-
-fDCTQuant=data[i]*fdtbl[i];
-outputfDCTQuant[i]=fDCTQuant>0.0?fDCTQuant+0.5|0:fDCTQuant-0.5|0;
-
-
-}
-return outputfDCTQuant;
-}
-
-function writeAPP0()
-{
-writeWord(0xFFE0);
-writeWord(16);
-writeByte(0x4A);
-writeByte(0x46);
-writeByte(0x49);
-writeByte(0x46);
-writeByte(0);
-writeByte(1);
-writeByte(1);
-writeByte(0);
-writeWord(1);
-writeWord(1);
-writeByte(0);
-writeByte(0);
-}
-
-function writeSOF0(width,height)
-{
-writeWord(0xFFC0);
-writeWord(17);
-writeByte(8);
-writeWord(height);
-writeWord(width);
-writeByte(3);
-writeByte(1);
-writeByte(0x11);
-writeByte(0);
-writeByte(2);
-writeByte(0x11);
-writeByte(1);
-writeByte(3);
-writeByte(0x11);
-writeByte(1);
-}
-
-function writeDQT()
-{
-writeWord(0xFFDB);
-writeWord(132);
-writeByte(0);
-for(var i=0;i<64;i++){
-writeByte(YTable[i]);
-}
-writeByte(1);
-for(var j=0;j<64;j++){
-writeByte(UVTable[j]);
-}
-}
-
-function writeDHT()
-{
-writeWord(0xFFC4);
-writeWord(0x01A2);
-
-writeByte(0);
-for(var i=0;i<16;i++){
-writeByte(std_dc_luminance_nrcodes[i+1]);
-}
-for(var j=0;j<=11;j++){
-writeByte(std_dc_luminance_values[j]);
-}
-
-writeByte(0x10);
-for(var k=0;k<16;k++){
-writeByte(std_ac_luminance_nrcodes[k+1]);
-}
-for(var l=0;l<=161;l++){
-writeByte(std_ac_luminance_values[l]);
-}
-
-writeByte(1);
-for(var m=0;m<16;m++){
-writeByte(std_dc_chrominance_nrcodes[m+1]);
-}
-for(var n=0;n<=11;n++){
-writeByte(std_dc_chrominance_values[n]);
-}
-
-writeByte(0x11);
-for(var o=0;o<16;o++){
-writeByte(std_ac_chrominance_nrcodes[o+1]);
-}
-for(var p=0;p<=161;p++){
-writeByte(std_ac_chrominance_values[p]);
-}
-}
-
-function writeSOS()
-{
-writeWord(0xFFDA);
-writeWord(12);
-writeByte(3);
-writeByte(1);
-writeByte(0);
-writeByte(2);
-writeByte(0x11);
-writeByte(3);
-writeByte(0x11);
-writeByte(0);
-writeByte(0x3f);
-writeByte(0);
-}
-
-function processDU(CDU,fdtbl,DC,HTDC,HTAC){
-var EOB=HTAC[0x00];
-var M16zeroes=HTAC[0xF0];
-var pos;
-const I16=16;
-const I63=63;
-const I64=64;
-var DU_DCT=fDCTQuant(CDU,fdtbl);
-
-for(var j=0;j<I64;++j){
-DU[ZigZag[j]]=DU_DCT[j];
-}
-var Diff=DU[0]-DC;DC=DU[0];
-
-if(Diff==0){
-writeBits(HTDC[0]);
-}else{
-pos=32767+Diff;
-writeBits(HTDC[category[pos]]);
-writeBits(bitcode[pos]);
-}
-
-var end0pos=63;
-for(;end0pos>0&&DU[end0pos]==0;end0pos--){};
-
-if(end0pos==0){
-writeBits(EOB);
-return DC;
-}
-var i=1;
-var lng;
-while(i<=end0pos){
-var startpos=i;
-for(;DU[i]==0&&i<=end0pos;++i){}
-var nrzeroes=i-startpos;
-if(nrzeroes>=I16){
-lng=nrzeroes>>4;
-for(var nrmarker=1;nrmarker<=lng;++nrmarker)
-writeBits(M16zeroes);
-nrzeroes=nrzeroes&0xF;
-}
-pos=32767+DU[i];
-writeBits(HTAC[(nrzeroes<<4)+category[pos]]);
-writeBits(bitcode[pos]);
-i++;
-}
-if(end0pos!=I63){
-writeBits(EOB);
-}
-return DC;
-}
-
-function initCharLookupTable(){
-var sfcc=String.fromCharCode;
-for(var i=0;i<256;i++){
-clt[i]=sfcc(i);
-}
-}
-
-this.encode=function(image,quality)
-{
-var time_start=new Date().getTime();
-
-if(quality)setQuality(quality);
-
-
-byteout=new Array();
-bytenew=0;
-bytepos=7;
-
-
-writeWord(0xFFD8);
-writeAPP0();
-writeDQT();
-writeSOF0(image.width,image.height);
-writeDHT();
-writeSOS();
-
-
-
-var DCY=0;
-var DCU=0;
-var DCV=0;
-
-bytenew=0;
-bytepos=7;
-
-
-this.encode.displayName="_encode_";
-
-var imageData=image.data;
-var width=image.width;
-var height=image.height;
-
-var quadWidth=width*4;
-var tripleWidth=width*3;
-
-var x,y=0;
-var r,g,b;
-var start,p,col,row,pos;
-while(y<height){
-x=0;
-while(x<quadWidth){
-start=quadWidth*y+x;
-p=start;
-col=-1;
-row=0;
-
-for(pos=0;pos<64;pos++){
-row=pos>>3;
-col=(pos&7)*4;
-p=start+row*quadWidth+col;
-
-if(y+row>=height){
-p-=quadWidth*(y+1+row-height);
-}
-
-if(x+col>=quadWidth){
-p-=x+col-quadWidth+4;
-}
-
-r=imageData[p++];
-g=imageData[p++];
-b=imageData[p++];
-
-
-
-
-
-
-
-
-
-YDU[pos]=(RGB_YUV_TABLE[r]+RGB_YUV_TABLE[g+256>>0]+RGB_YUV_TABLE[b+512>>0]>>16)-128;
-UDU[pos]=(RGB_YUV_TABLE[r+768>>0]+RGB_YUV_TABLE[g+1024>>0]+RGB_YUV_TABLE[b+1280>>0]>>16)-128;
-VDU[pos]=(RGB_YUV_TABLE[r+1280>>0]+RGB_YUV_TABLE[g+1536>>0]+RGB_YUV_TABLE[b+1792>>0]>>16)-128;
-
-}
-
-DCY=processDU(YDU,fdtbl_Y,DCY,YDC_HT,YAC_HT);
-DCU=processDU(UDU,fdtbl_UV,DCU,UVDC_HT,UVAC_HT);
-DCV=processDU(VDU,fdtbl_UV,DCV,UVDC_HT,UVAC_HT);
-x+=32;
-}
-y+=8;
-}
-
-
-
-
-
-if(bytepos>=0){
-var fillbits=[];
-fillbits[1]=bytepos+1;
-fillbits[0]=(1<<bytepos+1)-1;
-writeBits(fillbits);
-}
-
-writeWord(0xFFD9);
-
-
-return new Buffer(byteout);
-
-var jpegDataUri='data:image/jpeg;base64,'+btoa(byteout.join(''));
-
-byteout=[];
-
-
-var duration=new Date().getTime()-time_start;
-
-
-
-return jpegDataUri;
-};
-
-function setQuality(quality){
-if(quality<=0){
-quality=1;
-}
-if(quality>100){
-quality=100;
-}
-
-if(currentQuality==quality)return;
-
-var sf=0;
-if(quality<50){
-sf=Math.floor(5000/quality);
-}else{
-sf=Math.floor(200-quality*2);
-}
-
-initQuantTables(sf);
-currentQuality=quality;
-
-}
-
-function init(){
-var time_start=new Date().getTime();
-if(!quality)quality=50;
-
-initCharLookupTable();
-initHuffmanTbl();
-initCategoryNumber();
-initRGBYUVTable();
-
-setQuality(quality);
-var duration=new Date().getTime()-time_start;
-
-}
-
-init();
-
-};
-module.exports=encode;
-
-function encode(imgData,qu){
-if(typeof qu==='undefined')qu=50;
-var encoder=new JPEGEncoder(qu);
-var data=encoder.encode(imgData,qu);
-return{
-data:data,
-width:imgData.width,
-height:imgData.height};
-
-}
-
-
-function getImageDataFromImage(idOrElement){
-var theImg=typeof idOrElement=='string'?document.getElementById(idOrElement):idOrElement;
-var cvs=document.createElement('canvas');
-cvs.width=theImg.width;
-cvs.height=theImg.height;
-var ctx=cvs.getContext("2d");
-ctx.drawImage(theImg,0,0);
-
-return ctx.getImageData(0,0,cvs.width,cvs.height);
-}
-
-}).call(this,require("buffer").Buffer);
-},{"buffer":54}],137:[function(require,module,exports){
-(function(process){
-
-
-
-
-
-'use strict';
-
-const debug=require('debug');
-const EventEmitter=require('events').EventEmitter;
-const isWindows=process.platform==='win32';
-
-
-const isBrowser=process.browser;
-
-const colors={
-red:isBrowser?'crimson':1,
-yellow:isBrowser?'gold':3,
-cyan:isBrowser?'darkturquoise':6,
-green:isBrowser?'forestgreen':2,
-blue:isBrowser?'steelblue':4,
-magenta:isBrowser?'palevioletred':5};
-
-
-
-debug.colors=[colors.cyan,colors.green,colors.blue,colors.magenta];
-
-class Emitter extends EventEmitter{
-
-
-
-
-
-
-issueStatus(title,argsArray){
-if(title==='status'||title==='statusEnd'){
-this.emit(title,[title,...argsArray]);
-}
-}
-
-
-
-
-
-
-
-issueWarning(title,argsArray){
-this.emit('warning',[title,...argsArray]);
-}}
-
-
-const loggersByTitle={};
-const loggingBufferColumns=25;
-
-class Log{
-
-static _logToStdErr(title,argsArray){
-const log=Log.loggerfn(title);
-log(...argsArray);
-}
-
-static loggerfn(title){
-let log=loggersByTitle[title];
-if(!log){
-log=debug(title);
-loggersByTitle[title]=log;
-
-if(title.endsWith('error')){
-log.color=colors.red;
-}else if(title.endsWith('warn')){
-log.color=colors.yellow;
-}
-}
-return log;
-}
-
-static setLevel(level){
-switch(level){
-case'silent':
-debug.enable('-*');
-break;
-case'verbose':
-debug.enable('*');
-break;
-case'error':
-debug.enable('-*, *:error');
-break;
-default:
-debug.enable('*, -*:verbose');}
-
-}
-
-
-
-
-
-
-
-static formatProtocol(prefix,data,level){
-const columns=!process||process.browser?Infinity:process.stdout.columns;
-const method=data.method||'?????';
-const maxLength=columns-method.length-prefix.length-loggingBufferColumns;
-
-const snippet=data.params&&method!=='IO.read'?
-JSON.stringify(data.params).substr(0,maxLength):'';
-Log._logToStdErr(`${prefix}:${level||''}`,[method,snippet]);
-}
-
-static log(title,...args){
-Log.events.issueStatus(title,args);
-return Log._logToStdErr(title,args);
-}
-
-static warn(title,...args){
-Log.events.issueWarning(title,args);
-return Log._logToStdErr(`${title}:warn`,args);
-}
-
-static error(title,...args){
-return Log._logToStdErr(`${title}:error`,args);
-}
-
-static verbose(title,...args){
-Log.events.issueStatus(title,args);
-return Log._logToStdErr(`${title}:verbose`,args);
-}
-
-
-
-
-
-
-static greenify(str){
-return`${Log.green}${str}${Log.reset}`;
-}
-
-
-
-
-
-
-static redify(str){
-return`${Log.red}${str}${Log.reset}`;
-}
-
-static get green(){
-return'\x1B[32m';
-}
-
-static get red(){
-return'\x1B[31m';
-}
-
-static get yellow(){
-return'\x1b[33m';
-}
-
-static get purple(){
-return'\x1b[95m';
-}
-
-static get reset(){
-return'\x1B[0m';
-}
-
-static get bold(){
-return'\x1b[1m';
-}
-
-static get dim(){
-return'\x1b[2m';
-}
-
-static get tick(){
-return isWindows?'\u221A':'✓';
-}
-
-static get cross(){
-return isWindows?'\u00D7':'✘';
-}
-
-static get whiteSmallSquare(){
-return isWindows?'\u0387':'▫';
-}
-
-static get heavyHorizontal(){
-return isWindows?'\u2500':'━';
-}
-
-static get heavyVertical(){
-return isWindows?'\u2502 ':'┃ ';
-}
-
-static get heavyUpAndRight(){
-return isWindows?'\u2514':'┗';
-}
-
-static get heavyVerticalAndRight(){
-return isWindows?'\u251C':'┣';
-}
-
-static get heavyDownAndHorizontal(){
-return isWindows?'\u252C':'┳';
-}
-
-static get doubleLightHorizontal(){
-return'──';
-}}
-
-
-Log.events=new Emitter();
-
-module.exports=Log;
-
-}).call(this,require('_process'));
-},{"_process":71,"debug":127,"events":56}],138:[function(require,module,exports){
-(function(global){
-
-
-
-
-
-
-
-
-
-
-var LARGE_ARRAY_SIZE=200;
-
-
-var HASH_UNDEFINED='__lodash_hash_undefined__';
-
-
-var COMPARE_PARTIAL_FLAG=1,
-COMPARE_UNORDERED_FLAG=2;
-
-
-var MAX_SAFE_INTEGER=9007199254740991;
-
-
-var argsTag='[object Arguments]',
-arrayTag='[object Array]',
-asyncTag='[object AsyncFunction]',
-boolTag='[object Boolean]',
-dateTag='[object Date]',
-errorTag='[object Error]',
-funcTag='[object Function]',
-genTag='[object GeneratorFunction]',
-mapTag='[object Map]',
-numberTag='[object Number]',
-nullTag='[object Null]',
-objectTag='[object Object]',
-promiseTag='[object Promise]',
-proxyTag='[object Proxy]',
-regexpTag='[object RegExp]',
-setTag='[object Set]',
-stringTag='[object String]',
-symbolTag='[object Symbol]',
-undefinedTag='[object Undefined]',
-weakMapTag='[object WeakMap]';
-
-var arrayBufferTag='[object ArrayBuffer]',
-dataViewTag='[object DataView]',
-float32Tag='[object Float32Array]',
-float64Tag='[object Float64Array]',
-int8Tag='[object Int8Array]',
-int16Tag='[object Int16Array]',
-int32Tag='[object Int32Array]',
-uint8Tag='[object Uint8Array]',
-uint8ClampedTag='[object Uint8ClampedArray]',
-uint16Tag='[object Uint16Array]',
-uint32Tag='[object Uint32Array]';
-
-
-
-
-
-var reRegExpChar=/[\\^$.*+?()[\]{}|]/g;
-
-
-var reIsHostCtor=/^\[object .+?Constructor\]$/;
-
-
-var reIsUint=/^(?:0|[1-9]\d*)$/;
-
-
-var typedArrayTags={};
-typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=
-typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=
-typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=
-typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=
-typedArrayTags[uint32Tag]=true;
-typedArrayTags[argsTag]=typedArrayTags[arrayTag]=
-typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=
-typedArrayTags[dataViewTag]=typedArrayTags[dateTag]=
-typedArrayTags[errorTag]=typedArrayTags[funcTag]=
-typedArrayTags[mapTag]=typedArrayTags[numberTag]=
-typedArrayTags[objectTag]=typedArrayTags[regexpTag]=
-typedArrayTags[setTag]=typedArrayTags[stringTag]=
-typedArrayTags[weakMapTag]=false;
-
-
-var freeGlobal=typeof global=='object'&&global&&global.Object===Object&&global;
-
-
-var freeSelf=typeof self=='object'&&self&&self.Object===Object&&self;
-
-
-var root=freeGlobal||freeSelf||Function('return this')();
-
-
-var freeExports=typeof exports=='object'&&exports&&!exports.nodeType&&exports;
-
-
-var freeModule=freeExports&&typeof module=='object'&&module&&!module.nodeType&&module;
-
-
-var moduleExports=freeModule&&freeModule.exports===freeExports;
-
-
-var freeProcess=moduleExports&&freeGlobal.process;
-
-
-var nodeUtil=function(){
-try{
-return freeProcess&&freeProcess.binding&&freeProcess.binding('util');
-}catch(e){}
-}();
-
-
-var nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray;
-
-
-
-
-
-
-
-
-
-
-function arrayFilter(array,predicate){
-var index=-1,
-length=array==null?0:array.length,
-resIndex=0,
-result=[];
-
-while(++index<length){
-var value=array[index];
-if(predicate(value,index,array)){
-result[resIndex++]=value;
-}
-}
-return result;
-}
-
-
-
-
-
-
-
-
-
-function arrayPush(array,values){
-var index=-1,
-length=values.length,
-offset=array.length;
-
-while(++index<length){
-array[offset+index]=values[index];
-}
-return array;
-}
-
-
-
-
-
-
-
-
-
-
-
-function arraySome(array,predicate){
-var index=-1,
-length=array==null?0:array.length;
-
-while(++index<length){
-if(predicate(array[index],index,array)){
-return true;
-}
-}
-return false;
-}
-
-
-
-
-
-
-
-
-
-
-function baseTimes(n,iteratee){
-var index=-1,
-result=Array(n);
-
-while(++index<n){
-result[index]=iteratee(index);
-}
-return result;
-}
-
-
-
-
-
-
-
-
-function baseUnary(func){
-return function(value){
-return func(value);
-};
-}
-
-
-
-
-
-
-
-
-
-function cacheHas(cache,key){
-return cache.has(key);
-}
-
-
-
-
-
-
-
-
-
-function getValue(object,key){
-return object==null?undefined:object[key];
-}
-
-
-
-
-
-
-
-
-function mapToArray(map){
-var index=-1,
-result=Array(map.size);
-
-map.forEach(function(value,key){
-result[++index]=[key,value];
-});
-return result;
-}
-
-
-
-
-
-
-
-
-
-function overArg(func,transform){
-return function(arg){
-return func(transform(arg));
-};
-}
-
-
-
-
-
-
-
-
-function setToArray(set){
-var index=-1,
-result=Array(set.size);
-
-set.forEach(function(value){
-result[++index]=value;
-});
-return result;
-}
-
-
-var arrayProto=Array.prototype,
-funcProto=Function.prototype,
-objectProto=Object.prototype;
-
-
-var coreJsData=root['__core-js_shared__'];
-
-
-var funcToString=funcProto.toString;
-
-
-var hasOwnProperty=objectProto.hasOwnProperty;
-
-
-var maskSrcKey=function(){
-var uid=/[^.]+$/.exec(coreJsData&&coreJsData.keys&&coreJsData.keys.IE_PROTO||'');
-return uid?'Symbol(src)_1.'+uid:'';
-}();
-
-
-
-
-
-
-var nativeObjectToString=objectProto.toString;
-
-
-var reIsNative=RegExp('^'+
-funcToString.call(hasOwnProperty).replace(reRegExpChar,'\\$&').
-replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,'$1.*?')+'$');
-
-
-
-var Buffer=moduleExports?root.Buffer:undefined,
-Symbol=root.Symbol,
-Uint8Array=root.Uint8Array,
-propertyIsEnumerable=objectProto.propertyIsEnumerable,
-splice=arrayProto.splice,
-symToStringTag=Symbol?Symbol.toStringTag:undefined;
-
-
-var nativeGetSymbols=Object.getOwnPropertySymbols,
-nativeIsBuffer=Buffer?Buffer.isBuffer:undefined,
-nativeKeys=overArg(Object.keys,Object);
-
-
-var DataView=getNative(root,'DataView'),
-Map=getNative(root,'Map'),
-Promise=getNative(root,'Promise'),
-Set=getNative(root,'Set'),
-WeakMap=getNative(root,'WeakMap'),
-nativeCreate=getNative(Object,'create');
-
-
-var dataViewCtorString=toSource(DataView),
-mapCtorString=toSource(Map),
-promiseCtorString=toSource(Promise),
-setCtorString=toSource(Set),
-weakMapCtorString=toSource(WeakMap);
-
-
-var symbolProto=Symbol?Symbol.prototype:undefined,
-symbolValueOf=symbolProto?symbolProto.valueOf:undefined;
-
-
-
-
-
-
-
-
-function Hash(entries){
-var index=-1,
-length=entries==null?0:entries.length;
-
-this.clear();
-while(++index<length){
-var entry=entries[index];
-this.set(entry[0],entry[1]);
-}
-}
-
-
-
-
-
-
-
-
-function hashClear(){
-this.__data__=nativeCreate?nativeCreate(null):{};
-this.size=0;
-}
-
-
-
-
-
-
-
-
-
-
-
-function hashDelete(key){
-var result=this.has(key)&&delete this.__data__[key];
-this.size-=result?1:0;
-return result;
-}
-
-
-
-
-
-
-
-
-
-
-function hashGet(key){
-var data=this.__data__;
-if(nativeCreate){
-var result=data[key];
-return result===HASH_UNDEFINED?undefined:result;
-}
-return hasOwnProperty.call(data,key)?data[key]:undefined;
-}
-
-
-
-
-
-
-
-
-
-
-function hashHas(key){
-var data=this.__data__;
-return nativeCreate?data[key]!==undefined:hasOwnProperty.call(data,key);
-}
-
-
-
-
-
-
-
-
-
-
-
-function hashSet(key,value){
-var data=this.__data__;
-this.size+=this.has(key)?0:1;
-data[key]=nativeCreate&&value===undefined?HASH_UNDEFINED:value;
-return this;
-}
-
-
-Hash.prototype.clear=hashClear;
-Hash.prototype['delete']=hashDelete;
-Hash.prototype.get=hashGet;
-Hash.prototype.has=hashHas;
-Hash.prototype.set=hashSet;
-
-
-
-
-
-
-
-
-function ListCache(entries){
-var index=-1,
-length=entries==null?0:entries.length;
-
-this.clear();
-while(++index<length){
-var entry=entries[index];
-this.set(entry[0],entry[1]);
-}
-}
-
-
-
-
-
-
-
-
-function listCacheClear(){
-this.__data__=[];
-this.size=0;
-}
-
-
-
-
-
-
-
-
-
-
-function listCacheDelete(key){
-var data=this.__data__,
-index=assocIndexOf(data,key);
-
-if(index<0){
-return false;
-}
-var lastIndex=data.length-1;
-if(index==lastIndex){
-data.pop();
-}else{
-splice.call(data,index,1);
-}
---this.size;
-return true;
-}
-
-
-
-
-
-
-
-
-
-
-function listCacheGet(key){
-var data=this.__data__,
-index=assocIndexOf(data,key);
-
-return index<0?undefined:data[index][1];
-}
-
-
-
-
-
-
-
-
-
-
-function listCacheHas(key){
-return assocIndexOf(this.__data__,key)>-1;
-}
-
-
-
-
-
-
-
-
-
-
-
-function listCacheSet(key,value){
-var data=this.__data__,
-index=assocIndexOf(data,key);
-
-if(index<0){
-++this.size;
-data.push([key,value]);
-}else{
-data[index][1]=value;
-}
-return this;
-}
-
-
-ListCache.prototype.clear=listCacheClear;
-ListCache.prototype['delete']=listCacheDelete;
-ListCache.prototype.get=listCacheGet;
-ListCache.prototype.has=listCacheHas;
-ListCache.prototype.set=listCacheSet;
-
-
-
-
-
-
-
-
-function MapCache(entries){
-var index=-1,
-length=entries==null?0:entries.length;
-
-this.clear();
-while(++index<length){
-var entry=entries[index];
-this.set(entry[0],entry[1]);
-}
-}
-
-
-
-
-
-
-
-
-function mapCacheClear(){
-this.size=0;
-this.__data__={
-'hash':new Hash(),
-'map':new(Map||ListCache)(),
-'string':new Hash()};
-
-}
-
-
-
-
-
-
-
-
-
-
-function mapCacheDelete(key){
-var result=getMapData(this,key)['delete'](key);
-this.size-=result?1:0;
-return result;
-}
-
-
-
-
-
-
-
-
-
-
-function mapCacheGet(key){
-return getMapData(this,key).get(key);
-}
-
-
-
-
-
-
-
-
-
-
-function mapCacheHas(key){
-return getMapData(this,key).has(key);
-}
-
-
-
-
-
-
-
-
-
-
-
-function mapCacheSet(key,value){
-var data=getMapData(this,key),
-size=data.size;
-
-data.set(key,value);
-this.size+=data.size==size?0:1;
-return this;
-}
-
-
-MapCache.prototype.clear=mapCacheClear;
-MapCache.prototype['delete']=mapCacheDelete;
-MapCache.prototype.get=mapCacheGet;
-MapCache.prototype.has=mapCacheHas;
-MapCache.prototype.set=mapCacheSet;
-
-
-
-
-
-
-
-
-
-function SetCache(values){
-var index=-1,
-length=values==null?0:values.length;
-
-this.__data__=new MapCache();
-while(++index<length){
-this.add(values[index]);
-}
-}
-
-
-
-
-
-
-
-
-
-
-
-function setCacheAdd(value){
-this.__data__.set(value,HASH_UNDEFINED);
-return this;
-}
-
-
-
-
-
-
-
-
-
-
-function setCacheHas(value){
-return this.__data__.has(value);
-}
-
-
-SetCache.prototype.add=SetCache.prototype.push=setCacheAdd;
-SetCache.prototype.has=setCacheHas;
-
-
-
-
-
-
-
-
-function Stack(entries){
-var data=this.__data__=new ListCache(entries);
-this.size=data.size;
-}
-
-
-
-
-
-
-
-
-function stackClear(){
-this.__data__=new ListCache();
-this.size=0;
-}
-
-
-
-
-
-
-
-
-
-
-function stackDelete(key){
-var data=this.__data__,
-result=data['delete'](key);
-
-this.size=data.size;
-return result;
-}
-
-
-
-
-
-
-
-
-
-
-function stackGet(key){
-return this.__data__.get(key);
-}
-
-
-
-
-
-
-
-
-
-
-function stackHas(key){
-return this.__data__.has(key);
-}
-
-
-
-
-
-
-
-
-
-
-
-function stackSet(key,value){
-var data=this.__data__;
-if(data instanceof ListCache){
-var pairs=data.__data__;
-if(!Map||pairs.length<LARGE_ARRAY_SIZE-1){
-pairs.push([key,value]);
-this.size=++data.size;
-return this;
-}
-data=this.__data__=new MapCache(pairs);
-}
-data.set(key,value);
-this.size=data.size;
-return this;
-}
-
-
-Stack.prototype.clear=stackClear;
-Stack.prototype['delete']=stackDelete;
-Stack.prototype.get=stackGet;
-Stack.prototype.has=stackHas;
-Stack.prototype.set=stackSet;
-
-
-
-
-
-
-
-
-
-function arrayLikeKeys(value,inherited){
-var isArr=isArray(value),
-isArg=!isArr&&isArguments(value),
-isBuff=!isArr&&!isArg&&isBuffer(value),
-isType=!isArr&&!isArg&&!isBuff&&isTypedArray(value),
-skipIndexes=isArr||isArg||isBuff||isType,
-result=skipIndexes?baseTimes(value.length,String):[],
-length=result.length;
-
-for(var key in value){
-if((inherited||hasOwnProperty.call(value,key))&&
-!(skipIndexes&&(
-
-key=='length'||
-
-isBuff&&(key=='offset'||key=='parent')||
-
-isType&&(key=='buffer'||key=='byteLength'||key=='byteOffset')||
-
-isIndex(key,length))))
-{
-result.push(key);
-}
-}
-return result;
-}
-
-
-
-
-
-
-
-
-
-function assocIndexOf(array,key){
-var length=array.length;
-while(length--){
-if(eq(array[length][0],key)){
-return length;
-}
-}
-return-1;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-function baseGetAllKeys(object,keysFunc,symbolsFunc){
-var result=keysFunc(object);
-return isArray(object)?result:arrayPush(result,symbolsFunc(object));
-}
-
-
-
-
-
-
-
-
-function baseGetTag(value){
-if(value==null){
-return value===undefined?undefinedTag:nullTag;
-}
-return symToStringTag&&symToStringTag in Object(value)?
-getRawTag(value):
-objectToString(value);
-}
-
-
-
-
-
-
-
-
-function baseIsArguments(value){
-return isObjectLike(value)&&baseGetTag(value)==argsTag;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function baseIsEqual(value,other,bitmask,customizer,stack){
-if(value===other){
-return true;
-}
-if(value==null||other==null||!isObjectLike(value)&&!isObjectLike(other)){
-return value!==value&&other!==other;
-}
-return baseIsEqualDeep(value,other,bitmask,customizer,baseIsEqual,stack);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function baseIsEqualDeep(object,other,bitmask,customizer,equalFunc,stack){
-var objIsArr=isArray(object),
-othIsArr=isArray(other),
-objTag=objIsArr?arrayTag:getTag(object),
-othTag=othIsArr?arrayTag:getTag(other);
-
-objTag=objTag==argsTag?objectTag:objTag;
-othTag=othTag==argsTag?objectTag:othTag;
-
-var objIsObj=objTag==objectTag,
-othIsObj=othTag==objectTag,
-isSameTag=objTag==othTag;
-
-if(isSameTag&&isBuffer(object)){
-if(!isBuffer(other)){
-return false;
-}
-objIsArr=true;
-objIsObj=false;
-}
-if(isSameTag&&!objIsObj){
-stack||(stack=new Stack());
-return objIsArr||isTypedArray(object)?
-equalArrays(object,other,bitmask,customizer,equalFunc,stack):
-equalByTag(object,other,objTag,bitmask,customizer,equalFunc,stack);
-}
-if(!(bitmask&COMPARE_PARTIAL_FLAG)){
-var objIsWrapped=objIsObj&&hasOwnProperty.call(object,'__wrapped__'),
-othIsWrapped=othIsObj&&hasOwnProperty.call(other,'__wrapped__');
-
-if(objIsWrapped||othIsWrapped){
-var objUnwrapped=objIsWrapped?object.value():object,
-othUnwrapped=othIsWrapped?other.value():other;
-
-stack||(stack=new Stack());
-return equalFunc(objUnwrapped,othUnwrapped,bitmask,customizer,stack);
-}
-}
-if(!isSameTag){
-return false;
-}
-stack||(stack=new Stack());
-return equalObjects(object,other,bitmask,customizer,equalFunc,stack);
-}
-
-
-
-
-
-
-
-
-
-function baseIsNative(value){
-if(!isObject(value)||isMasked(value)){
-return false;
-}
-var pattern=isFunction(value)?reIsNative:reIsHostCtor;
-return pattern.test(toSource(value));
-}
-
-
-
-
-
-
-
-
-function baseIsTypedArray(value){
-return isObjectLike(value)&&
-isLength(value.length)&&!!typedArrayTags[baseGetTag(value)];
-}
-
-
-
-
-
-
-
-
-function baseKeys(object){
-if(!isPrototype(object)){
-return nativeKeys(object);
-}
-var result=[];
-for(var key in Object(object)){
-if(hasOwnProperty.call(object,key)&&key!='constructor'){
-result.push(key);
-}
-}
-return result;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function equalArrays(array,other,bitmask,customizer,equalFunc,stack){
-var isPartial=bitmask&COMPARE_PARTIAL_FLAG,
-arrLength=array.length,
-othLength=other.length;
-
-if(arrLength!=othLength&&!(isPartial&&othLength>arrLength)){
-return false;
-}
-
-var stacked=stack.get(array);
-if(stacked&&stack.get(other)){
-return stacked==other;
-}
-var index=-1,
-result=true,
-seen=bitmask&COMPARE_UNORDERED_FLAG?new SetCache():undefined;
-
-stack.set(array,other);
-stack.set(other,array);
-
-
-while(++index<arrLength){
-var arrValue=array[index],
-othValue=other[index];
-
-if(customizer){
-var compared=isPartial?
-customizer(othValue,arrValue,index,other,array,stack):
-customizer(arrValue,othValue,index,array,other,stack);
-}
-if(compared!==undefined){
-if(compared){
-continue;
-}
-result=false;
-break;
-}
-
-if(seen){
-if(!arraySome(other,function(othValue,othIndex){
-if(!cacheHas(seen,othIndex)&&(
-arrValue===othValue||equalFunc(arrValue,othValue,bitmask,customizer,stack))){
-return seen.push(othIndex);
-}
-})){
-result=false;
-break;
-}
-}else if(!(
-arrValue===othValue||
-equalFunc(arrValue,othValue,bitmask,customizer,stack)))
-{
-result=false;
-break;
-}
-}
-stack['delete'](array);
-stack['delete'](other);
-return result;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function equalByTag(object,other,tag,bitmask,customizer,equalFunc,stack){
-switch(tag){
-case dataViewTag:
-if(object.byteLength!=other.byteLength||
-object.byteOffset!=other.byteOffset){
-return false;
-}
-object=object.buffer;
-other=other.buffer;
-
-case arrayBufferTag:
-if(object.byteLength!=other.byteLength||
-!equalFunc(new Uint8Array(object),new Uint8Array(other))){
-return false;
-}
-return true;
-
-case boolTag:
-case dateTag:
-case numberTag:
-
-
-return eq(+object,+other);
-
-case errorTag:
-return object.name==other.name&&object.message==other.message;
-
-case regexpTag:
-case stringTag:
-
-
-
-return object==other+'';
-
-case mapTag:
-var convert=mapToArray;
-
-case setTag:
-var isPartial=bitmask&COMPARE_PARTIAL_FLAG;
-convert||(convert=setToArray);
-
-if(object.size!=other.size&&!isPartial){
-return false;
-}
-
-var stacked=stack.get(object);
-if(stacked){
-return stacked==other;
-}
-bitmask|=COMPARE_UNORDERED_FLAG;
-
-
-stack.set(object,other);
-var result=equalArrays(convert(object),convert(other),bitmask,customizer,equalFunc,stack);
-stack['delete'](object);
-return result;
-
-case symbolTag:
-if(symbolValueOf){
-return symbolValueOf.call(object)==symbolValueOf.call(other);
-}}
-
-return false;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function equalObjects(object,other,bitmask,customizer,equalFunc,stack){
-var isPartial=bitmask&COMPARE_PARTIAL_FLAG,
-objProps=getAllKeys(object),
-objLength=objProps.length,
-othProps=getAllKeys(other),
-othLength=othProps.length;
-
-if(objLength!=othLength&&!isPartial){
-return false;
-}
-var index=objLength;
-while(index--){
-var key=objProps[index];
-if(!(isPartial?key in other:hasOwnProperty.call(other,key))){
-return false;
-}
-}
-
-var stacked=stack.get(object);
-if(stacked&&stack.get(other)){
-return stacked==other;
-}
-var result=true;
-stack.set(object,other);
-stack.set(other,object);
-
-var skipCtor=isPartial;
-while(++index<objLength){
-key=objProps[index];
-var objValue=object[key],
-othValue=other[key];
-
-if(customizer){
-var compared=isPartial?
-customizer(othValue,objValue,key,other,object,stack):
-customizer(objValue,othValue,key,object,other,stack);
-}
-
-if(!(compared===undefined?
-objValue===othValue||equalFunc(objValue,othValue,bitmask,customizer,stack):
-compared))
-{
-result=false;
-break;
-}
-skipCtor||(skipCtor=key=='constructor');
-}
-if(result&&!skipCtor){
-var objCtor=object.constructor,
-othCtor=other.constructor;
-
-
-if(objCtor!=othCtor&&
-'constructor'in object&&'constructor'in other&&
-!(typeof objCtor=='function'&&objCtor instanceof objCtor&&
-typeof othCtor=='function'&&othCtor instanceof othCtor)){
-result=false;
-}
-}
-stack['delete'](object);
-stack['delete'](other);
-return result;
-}
-
-
-
-
-
-
-
-
-function getAllKeys(object){
-return baseGetAllKeys(object,keys,getSymbols);
-}
-
-
-
-
-
-
-
-
-
-function getMapData(map,key){
-var data=map.__data__;
-return isKeyable(key)?
-data[typeof key=='string'?'string':'hash']:
-data.map;
-}
-
-
-
-
-
-
-
-
-
-function getNative(object,key){
-var value=getValue(object,key);
-return baseIsNative(value)?value:undefined;
-}
-
-
-
-
-
-
-
-
-function getRawTag(value){
-var isOwn=hasOwnProperty.call(value,symToStringTag),
-tag=value[symToStringTag];
-
-try{
-value[symToStringTag]=undefined;
-var unmasked=true;
-}catch(e){}
-
-var result=nativeObjectToString.call(value);
-if(unmasked){
-if(isOwn){
-value[symToStringTag]=tag;
-}else{
-delete value[symToStringTag];
-}
-}
-return result;
-}
-
-
-
-
-
-
-
-
-var getSymbols=!nativeGetSymbols?stubArray:function(object){
-if(object==null){
-return[];
-}
-object=Object(object);
-return arrayFilter(nativeGetSymbols(object),function(symbol){
-return propertyIsEnumerable.call(object,symbol);
-});
-};
-
-
-
-
-
-
-
-
-var getTag=baseGetTag;
-
-
-if(DataView&&getTag(new DataView(new ArrayBuffer(1)))!=dataViewTag||
-Map&&getTag(new Map())!=mapTag||
-Promise&&getTag(Promise.resolve())!=promiseTag||
-Set&&getTag(new Set())!=setTag||
-WeakMap&&getTag(new WeakMap())!=weakMapTag){
-getTag=function(value){
-var result=baseGetTag(value),
-Ctor=result==objectTag?value.constructor:undefined,
-ctorString=Ctor?toSource(Ctor):'';
-
-if(ctorString){
-switch(ctorString){
-case dataViewCtorString:return dataViewTag;
-case mapCtorString:return mapTag;
-case promiseCtorString:return promiseTag;
-case setCtorString:return setTag;
-case weakMapCtorString:return weakMapTag;}
-
-}
-return result;
-};
-}
-
-
-
-
-
-
-
-
-
-function isIndex(value,length){
-length=length==null?MAX_SAFE_INTEGER:length;
-return!!length&&(
-typeof value=='number'||reIsUint.test(value))&&
-value>-1&&value%1==0&&value<length;
-}
-
-
-
-
-
-
-
-
-function isKeyable(value){
-var type=typeof value;
-return type=='string'||type=='number'||type=='symbol'||type=='boolean'?
-value!=='__proto__':
-value===null;
-}
-
-
-
-
-
-
-
-
-function isMasked(func){
-return!!maskSrcKey&&maskSrcKey in func;
-}
-
-
-
-
-
-
-
-
-function isPrototype(value){
-var Ctor=value&&value.constructor,
-proto=typeof Ctor=='function'&&Ctor.prototype||objectProto;
-
-return value===proto;
-}
-
-
-
-
-
-
-
-
-function objectToString(value){
-return nativeObjectToString.call(value);
-}
-
-
-
-
-
-
-
-
-function toSource(func){
-if(func!=null){
-try{
-return funcToString.call(func);
-}catch(e){}
-try{
-return func+'';
-}catch(e){}
-}
-return'';
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function eq(value,other){
-return value===other||value!==value&&other!==other;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var isArguments=baseIsArguments(function(){return arguments;}())?baseIsArguments:function(value){
-return isObjectLike(value)&&hasOwnProperty.call(value,'callee')&&
-!propertyIsEnumerable.call(value,'callee');
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var isArray=Array.isArray;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isArrayLike(value){
-return value!=null&&isLength(value.length)&&!isFunction(value);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var isBuffer=nativeIsBuffer||stubFalse;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isEqual(value,other){
-return baseIsEqual(value,other);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isFunction(value){
-if(!isObject(value)){
-return false;
-}
-
-
-var tag=baseGetTag(value);
-return tag==funcTag||tag==genTag||tag==asyncTag||tag==proxyTag;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isLength(value){
-return typeof value=='number'&&
-value>-1&&value%1==0&&value<=MAX_SAFE_INTEGER;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isObject(value){
-var type=typeof value;
-return value!=null&&(type=='object'||type=='function');
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function isObjectLike(value){
-return value!=null&&typeof value=='object';
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-var isTypedArray=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function keys(object){
-return isArrayLike(object)?arrayLikeKeys(object):baseKeys(object);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function stubArray(){
-return[];
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function stubFalse(){
-return false;
-}
-
-module.exports=isEqual;
-
-}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{});
-},{}],139:[function(require,module,exports){
-exports.getRenderingDataFromViewport=function(viewportProperties,uaDeviceWidth,uaDeviceHeight,uaMaxZoom,uaMinZoom){
-
-var vw=uaDeviceWidth/100;
-var vh=uaDeviceHeight/100;
-
-
-
-var maxZoom=null;
-var minZoom=null;
-var zoom=null;
-var minWidth=null;
-var minHeight=null;
-var maxWidth=null;
-var maxHeight=null;
-var width=null,height=null;
-var initialWidth=uaDeviceWidth;
-var initialHeight=uaDeviceHeight;
-var userZoom="zoom";
-
-if(viewportProperties["maximum-scale"]!==undefined){
-maxZoom=translateZoomProperty(viewportProperties["maximum-scale"]);
-}
-if(viewportProperties["minimum-scale"]!==undefined){
-minZoom=translateZoomProperty(viewportProperties["minimum-scale"]);
-}
-if(viewportProperties["initial-scale"]!==undefined){
-zoom=translateZoomProperty(viewportProperties["initial-scale"]);
-}
-
-
-
-
-
-
-
-if(minZoom!==null&&maxZoom===null){
-minZoom=min(uaMaxZoom,translateZoomProperty(viewportProperties["minimum-scale"]));
-}
-
-if(viewportProperties["width"]!==undefined){
-minWidth="extend-to-zoom";
-maxWidth=translateLengthProperty(viewportProperties["width"],vw,vh);
-}
-
-if(viewportProperties["height"]!==undefined){
-minHeight="extend-to-zoom";
-maxHeight=translateLengthProperty(viewportProperties["height"],vw,vh);
-}
-
-
-if(viewportProperties["user-scalable"]!==undefined){
-userZoom=viewportProperties["user-scalable"];
-if(typeof userZoom==="number"){
-if(userZoom>=1||userZoom<=-1){
-userZoom="zoom";
-}else{
-userZoom="fixed";
-}
-}else{
-switch(userZoom){
-case"yes":
-case"device-width":
-case"device-height":
-userZoom="zoom";
-break;
-case"no":
-default:
-userZoom="fixed";
-break;}
-
-}
-}
-
-
-
-if(zoom!==null&&(
-viewportProperties["width"]===undefined||width===undefined)){
-if(viewportProperties["height"]!==undefined){
-
-minWidth=null;
-maxWidth=null;
-}else{
-
-minWidth="extend-to-zoom";
-maxWidth="extend-to-zoom";
-}
-}
-
-
-
-
-
-
-if(minZoom!==null&&maxZoom!==null){
-maxZoom=max(minZoom,maxZoom);
-}
-
-
-if(zoom!==null){
-zoom=clamp(zoom,minZoom,maxZoom);
-}
-
-
-var extendZoom=zoom===null&&maxZoom===null?null:min(zoom,maxZoom);
-var extendWidth,extendHeight;
-if(extendZoom===null){
-if(maxWidth==="extend-to-zoom"){
-maxWidth=null;
-}
-if(maxHeight==="extend-to-zoom"){
-maxHeight=null;
-}
-if(minWidth==="extend-to-zoom"){
-minWidth=maxWidth;
-}
-if(minHeight==="extend-to-zoom"){
-minHeight=maxHeight;
-}
-}else{
-extendWidth=initialWidth/extendZoom;
-extendHeight=initialHeight/extendZoom;
-
-if(maxWidth==="extend-to-zoom"){
-maxWidth=extendWidth;
-}
-if(maxHeight==="extend-to-zoom"){
-maxHeight=extendHeight;
-}
-if(minWidth==="extend-to-zoom"){
-minWidth=max(extendWidth,maxWidth);
-}
-if(minHeight==="extend-to-zoom"){
-minHeight=max(extendHeight,maxHeight);
-}
-}
-
-
-if(minWidth!==null||maxWidth!==null){
-width=max(minWidth,min(maxWidth,initialWidth));
-}
-if(minHeight!==null||maxHeight!==null){
-height=max(minHeight,min(maxHeight,initialHeight));
-}
-
-
-if(width===null){
-if(height===null){
-width=initialWidth;
-}else{
-if(initialHeight!==0){
-width=Math.round(height*(initialWidth/initialHeight));
-}else{
-width=initialWidth;
-}
-}
-}
-if(height===null){
-if(initialWidth!==0){
-height=Math.round(width*(initialHeight/initialWidth));
-}else{
-height=initialHeight;
-}
-}
-
-return{zoom:zoom,width:width,height:height,userZoom:userZoom};
-};
-
-function min(a,b){
-if(a===null)return b;
-if(b===null)return a;
-return Math.min(a,b);
-}
-
-function max(a,b){
-if(a===null)return b;
-if(b===null)return a;
-return Math.max(a,b);
-}
-
-
-function translateLengthProperty(prop,vw,vh){
-
-if(typeof prop==="number"){
-if(prop>=0){
-
-return clamp(prop,1,10000);
-}else{
-return undefined;
-}
-}
-if(prop==="device-width"){
-return 100*vw;
-}
-if(prop==="device-height"){
-return 100*vh;
-}
-return 1;
-}
-
-function translateZoomProperty(prop){
-
-if(typeof prop==="number"){
-if(prop>=0){
-
-return clamp(prop,0.1,10);
-}else{
-return undefined;
-}
-}
-if(prop==="yes"){
-return 1;
-}
-if(prop==="device-width"||prop==="device-height"){
-return 10;
-}
-if(prop==="no"||prop===null){
-return 0.1;
-}
-}
-
-
-function clamp(value,minv,maxv){
-return max(min(value,maxv),minv);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-exports.parseMetaViewPortContent=function(S){
-var parsedContent={
-validProperties:{},
-unknownProperties:{},
-invalidValues:{}};
-
-var i=1;
-while(i<=S.length){
-while(i<=S.length&&RegExp(' |\x0A|\x09|\0d|,|;|=').test(S[i-1])){
-i++;
-}
-if(i<=S.length){
-i=parseProperty(parsedContent,S,i);
-}
-}
-return parsedContent;
-};
-
-var propertyNames=["width","height","initial-scale","minimum-scale","maximum-scale","user-scalable","shrink-to-fit","viewport-fit"];
-
-function parseProperty(parsedContent,S,i){
-var start=i;
-while(i<=S.length&&!RegExp(' |\x0A|\x09|\0d|,|;|=').test(S[i-1])){
-i++;
-}
-if(i>S.length||RegExp(',|;').test(S[i-1])){
-return i;
-}
-var propertyName=S.slice(start-1,i-1);
-while(i<=S.length&&!RegExp(',|;|=').test(S[i-1])){
-i++;
-}
-if(i>S.length||RegExp(',|;').test(S[i-1])){
-return i;
-}
-while(i<=S.length&&RegExp(' |\x0A|\x09|\0d|=').test(S[i-1])){
-i++;
-}
-if(i>S.length||RegExp(',|;').test(S[i-1])){
-return i;
-}
-start=i;
-while(i<=S.length&&!RegExp(' |\x0A|\x09|\0d|,|;|=').test(S[i-1])){
-i++;
-}
-var propertyValue=S.slice(start-1,i-1);
-setProperty(parsedContent,propertyName,propertyValue);
-return i;
-}
-
-function setProperty(parsedContent,name,value){
-if(propertyNames.indexOf(name)>=0){
-var number=parseFloat(value);
-if(!isNaN(number)){
-parsedContent.validProperties[name]=number;
-return;
-}
-var string=value.toLowerCase();
-
-if(string==="yes"||string==="no"||string==="device-width"||string==="device-height"||
-
-
-name.toLowerCase()==='viewport-fit'&&(string==='auto'||string==='cover')){
-
-parsedContent.validProperties[name]=string;
-return;
-}
-
-parsedContent.validProperties[name]=null;
-parsedContent.invalidValues[name]=value;
-}else{
-parsedContent.unknownProperties[name]=value;
-}
-}
-
-exports.expectedValues={
-"width":["device-width","device-height","a positive number"],
-"height":["device-width","device-height","a positive number"],
-"initial-scale":["a positive number"],
-"minimum-scale":["a positive number"],
-"maximum-scale":["a positive number"],
-"user-scalable":["yes","no","0","1"],
-"shrink-to-fit":["yes","no"],
-"viewport-fit":["auto","cover"]};
-
-
-},{}],140:[function(require,module,exports){
-
-
-
-
-var s=1000;
-var m=s*60;
-var h=m*60;
-var d=h*24;
-var y=d*365.25;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-module.exports=function(val,options){
-options=options||{};
-var type=typeof val;
-if(type==='string'&&val.length>0){
-return parse(val);
-}else if(type==='number'&&isNaN(val)===false){
-return options.long?fmtLong(val):fmtShort(val);
-}
-throw new Error(
-'val is not a non-empty string or a valid number. val='+
-JSON.stringify(val));
-
-};
-
-
-
-
-
-
-
-
-
-function parse(str){
-str=String(str);
-if(str.length>100){
-return;
-}
-var match=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
-str);
-
-if(!match){
-return;
-}
-var n=parseFloat(match[1]);
-var type=(match[2]||'ms').toLowerCase();
-switch(type){
-case'years':
-case'year':
-case'yrs':
-case'yr':
-case'y':
-return n*y;
-case'days':
-case'day':
-case'd':
-return n*d;
-case'hours':
-case'hour':
-case'hrs':
-case'hr':
-case'h':
-return n*h;
-case'minutes':
-case'minute':
-case'mins':
-case'min':
-case'm':
-return n*m;
-case'seconds':
-case'second':
-case'secs':
-case'sec':
-case's':
-return n*s;
-case'milliseconds':
-case'millisecond':
-case'msecs':
-case'msec':
-case'ms':
-return n;
-default:
-return undefined;}
-
-}
-
-
-
-
-
-
-
-
-
-function fmtShort(ms){
-if(ms>=d){
-return Math.round(ms/d)+'d';
-}
-if(ms>=h){
-return Math.round(ms/h)+'h';
-}
-if(ms>=m){
-return Math.round(ms/m)+'m';
-}
-if(ms>=s){
-return Math.round(ms/s)+'s';
-}
-return ms+'ms';
-}
-
-
-
-
-
-
-
-
-
-function fmtLong(ms){
-return plural(ms,d,'day')||
-plural(ms,h,'hour')||
-plural(ms,m,'minute')||
-plural(ms,s,'second')||
-ms+' ms';
-}
-
-
-
-
-
-function plural(ms,n,name){
-if(ms<n){
-return;
-}
-if(ms<n*1.5){
-return Math.floor(ms/n)+' '+name;
-}
-return Math.ceil(ms/n)+' '+name+'s';
-}
-
-},{}],141:[function(require,module,exports){
-module.exports=function parseCacheControl(field){
-
-if(typeof field!=='string'){
-return null;
-}
-
-
-
-
-
-
-
-
-
-var regex=/(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g;
-
-var header={};
-var err=field.replace(regex,function($0,$1,$2,$3){
-var value=$2||$3;
-header[$1]=value?value.toLowerCase():true;
-return'';
-});
-
-if(header['max-age']){
-try{
-var maxAge=parseInt(header['max-age'],10);
-if(isNaN(maxAge)){
-return null;
-}
-
-header['max-age']=maxAge;
-}
-catch(err){}
-}
-
-return err?null:header;
-};
-
-},{}],142:[function(require,module,exports){
-(function(process){
-exports=module.exports=SemVer;
-
-
-var debug;
-if(typeof process==='object'&&
-process.env&&
-process.env.NODE_DEBUG&&
-/\bsemver\b/i.test(process.env.NODE_DEBUG))
-debug=function(){
-var args=Array.prototype.slice.call(arguments,0);
-args.unshift('SEMVER');
-console.log.apply(console,args);
-};else
-
-debug=function(){};
-
-
-
-exports.SEMVER_SPEC_VERSION='2.0.0';
-
-var MAX_LENGTH=256;
-var MAX_SAFE_INTEGER=Number.MAX_SAFE_INTEGER||9007199254740991;
-
-
-var re=exports.re=[];
-var src=exports.src=[];
-var R=0;
-
-
-
-
-
-
-
-var NUMERICIDENTIFIER=R++;
-src[NUMERICIDENTIFIER]='0|[1-9]\\d*';
-var NUMERICIDENTIFIERLOOSE=R++;
-src[NUMERICIDENTIFIERLOOSE]='[0-9]+';
-
-
-
-
-
-
-var NONNUMERICIDENTIFIER=R++;
-src[NONNUMERICIDENTIFIER]='\\d*[a-zA-Z-][a-zA-Z0-9-]*';
-
-
-
-
-
-var MAINVERSION=R++;
-src[MAINVERSION]='('+src[NUMERICIDENTIFIER]+')\\.'+
-'('+src[NUMERICIDENTIFIER]+')\\.'+
-'('+src[NUMERICIDENTIFIER]+')';
-
-var MAINVERSIONLOOSE=R++;
-src[MAINVERSIONLOOSE]='('+src[NUMERICIDENTIFIERLOOSE]+')\\.'+
-'('+src[NUMERICIDENTIFIERLOOSE]+')\\.'+
-'('+src[NUMERICIDENTIFIERLOOSE]+')';
-
-
-
-
-var PRERELEASEIDENTIFIER=R++;
-src[PRERELEASEIDENTIFIER]='(?:'+src[NUMERICIDENTIFIER]+
-'|'+src[NONNUMERICIDENTIFIER]+')';
-
-var PRERELEASEIDENTIFIERLOOSE=R++;
-src[PRERELEASEIDENTIFIERLOOSE]='(?:'+src[NUMERICIDENTIFIERLOOSE]+
-'|'+src[NONNUMERICIDENTIFIER]+')';
-
-
-
-
-
-
-var PRERELEASE=R++;
-src[PRERELEASE]='(?:-('+src[PRERELEASEIDENTIFIER]+
-'(?:\\.'+src[PRERELEASEIDENTIFIER]+')*))';
-
-var PRERELEASELOOSE=R++;
-src[PRERELEASELOOSE]='(?:-?('+src[PRERELEASEIDENTIFIERLOOSE]+
-'(?:\\.'+src[PRERELEASEIDENTIFIERLOOSE]+')*))';
-
-
-
-
-var BUILDIDENTIFIER=R++;
-src[BUILDIDENTIFIER]='[0-9A-Za-z-]+';
-
-
-
-
-
-var BUILD=R++;
-src[BUILD]='(?:\\+('+src[BUILDIDENTIFIER]+
-'(?:\\.'+src[BUILDIDENTIFIER]+')*))';
-
-
-
-
-
-
-
-
-
-
-
-var FULL=R++;
-var FULLPLAIN='v?'+src[MAINVERSION]+
-src[PRERELEASE]+'?'+
-src[BUILD]+'?';
-
-src[FULL]='^'+FULLPLAIN+'$';
-
-
-
-
-var LOOSEPLAIN='[v=\\s]*'+src[MAINVERSIONLOOSE]+
-src[PRERELEASELOOSE]+'?'+
-src[BUILD]+'?';
-
-var LOOSE=R++;
-src[LOOSE]='^'+LOOSEPLAIN+'$';
-
-var GTLT=R++;
-src[GTLT]='((?:<|>)?=?)';
-
-
-
-
-var XRANGEIDENTIFIERLOOSE=R++;
-src[XRANGEIDENTIFIERLOOSE]=src[NUMERICIDENTIFIERLOOSE]+'|x|X|\\*';
-var XRANGEIDENTIFIER=R++;
-src[XRANGEIDENTIFIER]=src[NUMERICIDENTIFIER]+'|x|X|\\*';
-
-var XRANGEPLAIN=R++;
-src[XRANGEPLAIN]='[v=\\s]*('+src[XRANGEIDENTIFIER]+')'+
-'(?:\\.('+src[XRANGEIDENTIFIER]+')'+
-'(?:\\.('+src[XRANGEIDENTIFIER]+')'+
-'(?:'+src[PRERELEASE]+')?'+
-src[BUILD]+'?'+
-')?)?';
-
-var XRANGEPLAINLOOSE=R++;
-src[XRANGEPLAINLOOSE]='[v=\\s]*('+src[XRANGEIDENTIFIERLOOSE]+')'+
-'(?:\\.('+src[XRANGEIDENTIFIERLOOSE]+')'+
-'(?:\\.('+src[XRANGEIDENTIFIERLOOSE]+')'+
-'(?:'+src[PRERELEASELOOSE]+')?'+
-src[BUILD]+'?'+
-')?)?';
-
-var XRANGE=R++;
-src[XRANGE]='^'+src[GTLT]+'\\s*'+src[XRANGEPLAIN]+'$';
-var XRANGELOOSE=R++;
-src[XRANGELOOSE]='^'+src[GTLT]+'\\s*'+src[XRANGEPLAINLOOSE]+'$';
-
-
-
-var LONETILDE=R++;
-src[LONETILDE]='(?:~>?)';
-
-var TILDETRIM=R++;
-src[TILDETRIM]='(\\s*)'+src[LONETILDE]+'\\s+';
-re[TILDETRIM]=new RegExp(src[TILDETRIM],'g');
-var tildeTrimReplace='$1~';
-
-var TILDE=R++;
-src[TILDE]='^'+src[LONETILDE]+src[XRANGEPLAIN]+'$';
-var TILDELOOSE=R++;
-src[TILDELOOSE]='^'+src[LONETILDE]+src[XRANGEPLAINLOOSE]+'$';
-
-
-
-var LONECARET=R++;
-src[LONECARET]='(?:\\^)';
-
-var CARETTRIM=R++;
-src[CARETTRIM]='(\\s*)'+src[LONECARET]+'\\s+';
-re[CARETTRIM]=new RegExp(src[CARETTRIM],'g');
-var caretTrimReplace='$1^';
-
-var CARET=R++;
-src[CARET]='^'+src[LONECARET]+src[XRANGEPLAIN]+'$';
-var CARETLOOSE=R++;
-src[CARETLOOSE]='^'+src[LONECARET]+src[XRANGEPLAINLOOSE]+'$';
-
-
-var COMPARATORLOOSE=R++;
-src[COMPARATORLOOSE]='^'+src[GTLT]+'\\s*('+LOOSEPLAIN+')$|^$';
-var COMPARATOR=R++;
-src[COMPARATOR]='^'+src[GTLT]+'\\s*('+FULLPLAIN+')$|^$';
-
-
-
-
-var COMPARATORTRIM=R++;
-src[COMPARATORTRIM]='(\\s*)'+src[GTLT]+
-'\\s*('+LOOSEPLAIN+'|'+src[XRANGEPLAIN]+')';
-
-
-re[COMPARATORTRIM]=new RegExp(src[COMPARATORTRIM],'g');
-var comparatorTrimReplace='$1$2$3';
-
-
-
-
-
-
-var HYPHENRANGE=R++;
-src[HYPHENRANGE]='^\\s*('+src[XRANGEPLAIN]+')'+
-'\\s+-\\s+'+
-'('+src[XRANGEPLAIN]+')'+
-'\\s*$';
-
-var HYPHENRANGELOOSE=R++;
-src[HYPHENRANGELOOSE]='^\\s*('+src[XRANGEPLAINLOOSE]+')'+
-'\\s+-\\s+'+
-'('+src[XRANGEPLAINLOOSE]+')'+
-'\\s*$';
-
-
-var STAR=R++;
-src[STAR]='(<|>)?=?\\s*\\*';
-
-
-
-for(var i=0;i<R;i++){
-debug(i,src[i]);
-if(!re[i])
-re[i]=new RegExp(src[i]);
-}
-
-exports.parse=parse;
-function parse(version,loose){
-if(version instanceof SemVer)
-return version;
-
-if(typeof version!=='string')
-return null;
-
-if(version.length>MAX_LENGTH)
-return null;
-
-var r=loose?re[LOOSE]:re[FULL];
-if(!r.test(version))
-return null;
-
-try{
-return new SemVer(version,loose);
-}catch(er){
-return null;
-}
-}
-
-exports.valid=valid;
-function valid(version,loose){
-var v=parse(version,loose);
-return v?v.version:null;
-}
-
-
-exports.clean=clean;
-function clean(version,loose){
-var s=parse(version.trim().replace(/^[=v]+/,''),loose);
-return s?s.version:null;
-}
-
-exports.SemVer=SemVer;
-
-function SemVer(version,loose){
-if(version instanceof SemVer){
-if(version.loose===loose)
-return version;else
-
-version=version.version;
-}else if(typeof version!=='string'){
-throw new TypeError('Invalid Version: '+version);
-}
-
-if(version.length>MAX_LENGTH)
-throw new TypeError('version is longer than '+MAX_LENGTH+' characters');
-
-if(!(this instanceof SemVer))
-return new SemVer(version,loose);
-
-debug('SemVer',version,loose);
-this.loose=loose;
-var m=version.trim().match(loose?re[LOOSE]:re[FULL]);
-
-if(!m)
-throw new TypeError('Invalid Version: '+version);
-
-this.raw=version;
-
-
-this.major=+m[1];
-this.minor=+m[2];
-this.patch=+m[3];
-
-if(this.major>MAX_SAFE_INTEGER||this.major<0)
-throw new TypeError('Invalid major version');
-
-if(this.minor>MAX_SAFE_INTEGER||this.minor<0)
-throw new TypeError('Invalid minor version');
-
-if(this.patch>MAX_SAFE_INTEGER||this.patch<0)
-throw new TypeError('Invalid patch version');
-
-
-if(!m[4])
-this.prerelease=[];else
-
-this.prerelease=m[4].split('.').map(function(id){
-if(/^[0-9]+$/.test(id)){
-var num=+id;
-if(num>=0&&num<MAX_SAFE_INTEGER)
-return num;
-}
-return id;
-});
-
-this.build=m[5]?m[5].split('.'):[];
-this.format();
-}
-
-SemVer.prototype.format=function(){
-this.version=this.major+'.'+this.minor+'.'+this.patch;
-if(this.prerelease.length)
-this.version+='-'+this.prerelease.join('.');
-return this.version;
-};
-
-SemVer.prototype.toString=function(){
-return this.version;
-};
-
-SemVer.prototype.compare=function(other){
-debug('SemVer.compare',this.version,this.loose,other);
-if(!(other instanceof SemVer))
-other=new SemVer(other,this.loose);
-
-return this.compareMain(other)||this.comparePre(other);
-};
-
-SemVer.prototype.compareMain=function(other){
-if(!(other instanceof SemVer))
-other=new SemVer(other,this.loose);
-
-return compareIdentifiers(this.major,other.major)||
-compareIdentifiers(this.minor,other.minor)||
-compareIdentifiers(this.patch,other.patch);
-};
-
-SemVer.prototype.comparePre=function(other){
-if(!(other instanceof SemVer))
-other=new SemVer(other,this.loose);
-
-
-if(this.prerelease.length&&!other.prerelease.length)
-return-1;else
-if(!this.prerelease.length&&other.prerelease.length)
-return 1;else
-if(!this.prerelease.length&&!other.prerelease.length)
-return 0;
-
-var i=0;
-do{
-var a=this.prerelease[i];
-var b=other.prerelease[i];
-debug('prerelease compare',i,a,b);
-if(a===undefined&&b===undefined)
-return 0;else
-if(b===undefined)
-return 1;else
-if(a===undefined)
-return-1;else
-if(a===b)
-continue;else
-
-return compareIdentifiers(a,b);
-}while(++i);
-};
-
-
-
-SemVer.prototype.inc=function(release,identifier){
-switch(release){
-case'premajor':
-this.prerelease.length=0;
-this.patch=0;
-this.minor=0;
-this.major++;
-this.inc('pre',identifier);
-break;
-case'preminor':
-this.prerelease.length=0;
-this.patch=0;
-this.minor++;
-this.inc('pre',identifier);
-break;
-case'prepatch':
-
-
-
-this.prerelease.length=0;
-this.inc('patch',identifier);
-this.inc('pre',identifier);
-break;
-
-
-case'prerelease':
-if(this.prerelease.length===0)
-this.inc('patch',identifier);
-this.inc('pre',identifier);
-break;
-
-case'major':
-
-
-
-
-if(this.minor!==0||this.patch!==0||this.prerelease.length===0)
-this.major++;
-this.minor=0;
-this.patch=0;
-this.prerelease=[];
-break;
-case'minor':
-
-
-
-
-if(this.patch!==0||this.prerelease.length===0)
-this.minor++;
-this.patch=0;
-this.prerelease=[];
-break;
-case'patch':
-
-
-
-
-if(this.prerelease.length===0)
-this.patch++;
-this.prerelease=[];
-break;
-
-
-case'pre':
-if(this.prerelease.length===0)
-this.prerelease=[0];else
-{
-var i=this.prerelease.length;
-while(--i>=0){
-if(typeof this.prerelease[i]==='number'){
-this.prerelease[i]++;
-i=-2;
-}
-}
-if(i===-1)
-this.prerelease.push(0);
-}
-if(identifier){
-
-
-if(this.prerelease[0]===identifier){
-if(isNaN(this.prerelease[1]))
-this.prerelease=[identifier,0];
-}else
-this.prerelease=[identifier,0];
-}
-break;
-
-default:
-throw new Error('invalid increment argument: '+release);}
-
-this.format();
-this.raw=this.version;
-return this;
-};
-
-exports.inc=inc;
-function inc(version,release,loose,identifier){
-if(typeof loose==='string'){
-identifier=loose;
-loose=undefined;
-}
-
-try{
-return new SemVer(version,loose).inc(release,identifier).version;
-}catch(er){
-return null;
-}
-}
-
-exports.diff=diff;
-function diff(version1,version2){
-if(eq(version1,version2)){
-return null;
-}else{
-var v1=parse(version1);
-var v2=parse(version2);
-if(v1.prerelease.length||v2.prerelease.length){
-for(var key in v1){
-if(key==='major'||key==='minor'||key==='patch'){
-if(v1[key]!==v2[key]){
-return'pre'+key;
-}
-}
-}
-return'prerelease';
-}
-for(var key in v1){
-if(key==='major'||key==='minor'||key==='patch'){
-if(v1[key]!==v2[key]){
-return key;
-}
-}
-}
-}
-}
-
-exports.compareIdentifiers=compareIdentifiers;
-
-var numeric=/^[0-9]+$/;
-function compareIdentifiers(a,b){
-var anum=numeric.test(a);
-var bnum=numeric.test(b);
-
-if(anum&&bnum){
-a=+a;
-b=+b;
-}
-
-return anum&&!bnum?-1:
-bnum&&!anum?1:
-a<b?-1:
-a>b?1:
-0;
-}
-
-exports.rcompareIdentifiers=rcompareIdentifiers;
-function rcompareIdentifiers(a,b){
-return compareIdentifiers(b,a);
-}
-
-exports.major=major;
-function major(a,loose){
-return new SemVer(a,loose).major;
-}
-
-exports.minor=minor;
-function minor(a,loose){
-return new SemVer(a,loose).minor;
-}
-
-exports.patch=patch;
-function patch(a,loose){
-return new SemVer(a,loose).patch;
-}
-
-exports.compare=compare;
-function compare(a,b,loose){
-return new SemVer(a,loose).compare(b);
-}
-
-exports.compareLoose=compareLoose;
-function compareLoose(a,b){
-return compare(a,b,true);
-}
-
-exports.rcompare=rcompare;
-function rcompare(a,b,loose){
-return compare(b,a,loose);
-}
-
-exports.sort=sort;
-function sort(list,loose){
-return list.sort(function(a,b){
-return exports.compare(a,b,loose);
-});
-}
-
-exports.rsort=rsort;
-function rsort(list,loose){
-return list.sort(function(a,b){
-return exports.rcompare(a,b,loose);
-});
-}
-
-exports.gt=gt;
-function gt(a,b,loose){
-return compare(a,b,loose)>0;
-}
-
-exports.lt=lt;
-function lt(a,b,loose){
-return compare(a,b,loose)<0;
-}
-
-exports.eq=eq;
-function eq(a,b,loose){
-return compare(a,b,loose)===0;
-}
-
-exports.neq=neq;
-function neq(a,b,loose){
-return compare(a,b,loose)!==0;
-}
-
-exports.gte=gte;
-function gte(a,b,loose){
-return compare(a,b,loose)>=0;
-}
-
-exports.lte=lte;
-function lte(a,b,loose){
-return compare(a,b,loose)<=0;
-}
-
-exports.cmp=cmp;
-function cmp(a,op,b,loose){
-var ret;
-switch(op){
-case'===':
-if(typeof a==='object')a=a.version;
-if(typeof b==='object')b=b.version;
-ret=a===b;
-break;
-case'!==':
-if(typeof a==='object')a=a.version;
-if(typeof b==='object')b=b.version;
-ret=a!==b;
-break;
-case'':case'=':case'==':ret=eq(a,b,loose);break;
-case'!=':ret=neq(a,b,loose);break;
-case'>':ret=gt(a,b,loose);break;
-case'>=':ret=gte(a,b,loose);break;
-case'<':ret=lt(a,b,loose);break;
-case'<=':ret=lte(a,b,loose);break;
-default:throw new TypeError('Invalid operator: '+op);}
-
-return ret;
-}
-
-exports.Comparator=Comparator;
-function Comparator(comp,loose){
-if(comp instanceof Comparator){
-if(comp.loose===loose)
-return comp;else
-
-comp=comp.value;
-}
-
-if(!(this instanceof Comparator))
-return new Comparator(comp,loose);
-
-debug('comparator',comp,loose);
-this.loose=loose;
-this.parse(comp);
-
-if(this.semver===ANY)
-this.value='';else
-
-this.value=this.operator+this.semver.version;
-
-debug('comp',this);
-}
-
-var ANY={};
-Comparator.prototype.parse=function(comp){
-var r=this.loose?re[COMPARATORLOOSE]:re[COMPARATOR];
-var m=comp.match(r);
-
-if(!m)
-throw new TypeError('Invalid comparator: '+comp);
-
-this.operator=m[1];
-if(this.operator==='=')
-this.operator='';
-
-
-if(!m[2])
-this.semver=ANY;else
-
-this.semver=new SemVer(m[2],this.loose);
-};
-
-Comparator.prototype.toString=function(){
-return this.value;
-};
-
-Comparator.prototype.test=function(version){
-debug('Comparator.test',version,this.loose);
-
-if(this.semver===ANY)
-return true;
-
-if(typeof version==='string')
-version=new SemVer(version,this.loose);
-
-return cmp(version,this.operator,this.semver,this.loose);
-};
-
-
-exports.Range=Range;
-function Range(range,loose){
-if(range instanceof Range&&range.loose===loose)
-return range;
-
-if(!(this instanceof Range))
-return new Range(range,loose);
-
-this.loose=loose;
-
-
-this.raw=range;
-this.set=range.split(/\s*\|\|\s*/).map(function(range){
-return this.parseRange(range.trim());
-},this).filter(function(c){
-
-return c.length;
-});
-
-if(!this.set.length){
-throw new TypeError('Invalid SemVer Range: '+range);
-}
-
-this.format();
-}
-
-Range.prototype.format=function(){
-this.range=this.set.map(function(comps){
-return comps.join(' ').trim();
-}).join('||').trim();
-return this.range;
-};
-
-Range.prototype.toString=function(){
-return this.range;
-};
-
-Range.prototype.parseRange=function(range){
-var loose=this.loose;
-range=range.trim();
-debug('range',range,loose);
-
-var hr=loose?re[HYPHENRANGELOOSE]:re[HYPHENRANGE];
-range=range.replace(hr,hyphenReplace);
-debug('hyphen replace',range);
-
-range=range.replace(re[COMPARATORTRIM],comparatorTrimReplace);
-debug('comparator trim',range,re[COMPARATORTRIM]);
-
-
-range=range.replace(re[TILDETRIM],tildeTrimReplace);
-
-
-range=range.replace(re[CARETTRIM],caretTrimReplace);
-
-
-range=range.split(/\s+/).join(' ');
-
-
-
-
-var compRe=loose?re[COMPARATORLOOSE]:re[COMPARATOR];
-var set=range.split(' ').map(function(comp){
-return parseComparator(comp,loose);
-}).join(' ').split(/\s+/);
-if(this.loose){
-
-set=set.filter(function(comp){
-return!!comp.match(compRe);
-});
-}
-set=set.map(function(comp){
-return new Comparator(comp,loose);
-});
-
-return set;
-};
-
-
-exports.toComparators=toComparators;
-function toComparators(range,loose){
-return new Range(range,loose).set.map(function(comp){
-return comp.map(function(c){
-return c.value;
-}).join(' ').trim().split(' ');
-});
-}
-
-
-
-
-function parseComparator(comp,loose){
-debug('comp',comp);
-comp=replaceCarets(comp,loose);
-debug('caret',comp);
-comp=replaceTildes(comp,loose);
-debug('tildes',comp);
-comp=replaceXRanges(comp,loose);
-debug('xrange',comp);
-comp=replaceStars(comp,loose);
-debug('stars',comp);
-return comp;
-}
-
-function isX(id){
-return!id||id.toLowerCase()==='x'||id==='*';
-}
-
-
-
-
-
-
-
-function replaceTildes(comp,loose){
-return comp.trim().split(/\s+/).map(function(comp){
-return replaceTilde(comp,loose);
-}).join(' ');
-}
-
-function replaceTilde(comp,loose){
-var r=loose?re[TILDELOOSE]:re[TILDE];
-return comp.replace(r,function(_,M,m,p,pr){
-debug('tilde',comp,_,M,m,p,pr);
-var ret;
-
-if(isX(M))
-ret='';else
-if(isX(m))
-ret='>='+M+'.0.0 <'+(+M+1)+'.0.0';else
-if(isX(p))
-
-ret='>='+M+'.'+m+'.0 <'+M+'.'+(+m+1)+'.0';else
-if(pr){
-debug('replaceTilde pr',pr);
-if(pr.charAt(0)!=='-')
-pr='-'+pr;
-ret='>='+M+'.'+m+'.'+p+pr+
-' <'+M+'.'+(+m+1)+'.0';
-}else
-
-ret='>='+M+'.'+m+'.'+p+
-' <'+M+'.'+(+m+1)+'.0';
-
-debug('tilde return',ret);
-return ret;
-});
-}
-
-
-
-
-
-
-
-function replaceCarets(comp,loose){
-return comp.trim().split(/\s+/).map(function(comp){
-return replaceCaret(comp,loose);
-}).join(' ');
-}
-
-function replaceCaret(comp,loose){
-debug('caret',comp,loose);
-var r=loose?re[CARETLOOSE]:re[CARET];
-return comp.replace(r,function(_,M,m,p,pr){
-debug('caret',comp,_,M,m,p,pr);
-var ret;
-
-if(isX(M))
-ret='';else
-if(isX(m))
-ret='>='+M+'.0.0 <'+(+M+1)+'.0.0';else
-if(isX(p)){
-if(M==='0')
-ret='>='+M+'.'+m+'.0 <'+M+'.'+(+m+1)+'.0';else
-
-ret='>='+M+'.'+m+'.0 <'+(+M+1)+'.0.0';
-}else if(pr){
-debug('replaceCaret pr',pr);
-if(pr.charAt(0)!=='-')
-pr='-'+pr;
-if(M==='0'){
-if(m==='0')
-ret='>='+M+'.'+m+'.'+p+pr+
-' <'+M+'.'+m+'.'+(+p+1);else
-
-ret='>='+M+'.'+m+'.'+p+pr+
-' <'+M+'.'+(+m+1)+'.0';
-}else
-ret='>='+M+'.'+m+'.'+p+pr+
-' <'+(+M+1)+'.0.0';
-}else{
-debug('no pr');
-if(M==='0'){
-if(m==='0')
-ret='>='+M+'.'+m+'.'+p+
-' <'+M+'.'+m+'.'+(+p+1);else
-
-ret='>='+M+'.'+m+'.'+p+
-' <'+M+'.'+(+m+1)+'.0';
-}else
-ret='>='+M+'.'+m+'.'+p+
-' <'+(+M+1)+'.0.0';
-}
-
-debug('caret return',ret);
-return ret;
-});
-}
-
-function replaceXRanges(comp,loose){
-debug('replaceXRanges',comp,loose);
-return comp.split(/\s+/).map(function(comp){
-return replaceXRange(comp,loose);
-}).join(' ');
-}
-
-function replaceXRange(comp,loose){
-comp=comp.trim();
-var r=loose?re[XRANGELOOSE]:re[XRANGE];
-return comp.replace(r,function(ret,gtlt,M,m,p,pr){
-debug('xRange',comp,ret,gtlt,M,m,p,pr);
-var xM=isX(M);
-var xm=xM||isX(m);
-var xp=xm||isX(p);
-var anyX=xp;
-
-if(gtlt==='='&&anyX)
-gtlt='';
-
-if(xM){
-if(gtlt==='>'||gtlt==='<'){
-
-ret='<0.0.0';
-}else{
-
-ret='*';
-}
-}else if(gtlt&&anyX){
-
-if(xm)
-m=0;
-if(xp)
-p=0;
-
-if(gtlt==='>'){
-
-
-
-gtlt='>=';
-if(xm){
-M=+M+1;
-m=0;
-p=0;
-}else if(xp){
-m=+m+1;
-p=0;
-}
-}else if(gtlt==='<='){
-
-
-gtlt='<';
-if(xm)
-M=+M+1;else
-
-m=+m+1;
-}
-
-ret=gtlt+M+'.'+m+'.'+p;
-}else if(xm){
-ret='>='+M+'.0.0 <'+(+M+1)+'.0.0';
-}else if(xp){
-ret='>='+M+'.'+m+'.0 <'+M+'.'+(+m+1)+'.0';
-}
-
-debug('xRange return',ret);
-
-return ret;
-});
-}
-
-
-
-function replaceStars(comp,loose){
-debug('replaceStars',comp,loose);
-
-return comp.trim().replace(re[STAR],'');
-}
-
-
-
-
-
-
-function hyphenReplace($0,
-from,fM,fm,fp,fpr,fb,
-to,tM,tm,tp,tpr,tb){
-
-if(isX(fM))
-from='';else
-if(isX(fm))
-from='>='+fM+'.0.0';else
-if(isX(fp))
-from='>='+fM+'.'+fm+'.0';else
-
-from='>='+from;
-
-if(isX(tM))
-to='';else
-if(isX(tm))
-to='<'+(+tM+1)+'.0.0';else
-if(isX(tp))
-to='<'+tM+'.'+(+tm+1)+'.0';else
-if(tpr)
-to='<='+tM+'.'+tm+'.'+tp+'-'+tpr;else
-
-to='<='+to;
-
-return(from+' '+to).trim();
-}
-
-
-
-Range.prototype.test=function(version){
-if(!version)
-return false;
-
-if(typeof version==='string')
-version=new SemVer(version,this.loose);
-
-for(var i=0;i<this.set.length;i++){
-if(testSet(this.set[i],version))
-return true;
-}
-return false;
-};
-
-function testSet(set,version){
-for(var i=0;i<set.length;i++){
-if(!set[i].test(version))
-return false;
-}
-
-if(version.prerelease.length){
-
-
-
-
-
-for(var i=0;i<set.length;i++){
-debug(set[i].semver);
-if(set[i].semver===ANY)
-continue;
-
-if(set[i].semver.prerelease.length>0){
-var allowed=set[i].semver;
-if(allowed.major===version.major&&
-allowed.minor===version.minor&&
-allowed.patch===version.patch)
-return true;
-}
-}
-
-
-return false;
-}
-
-return true;
-}
-
-exports.satisfies=satisfies;
-function satisfies(version,range,loose){
-try{
-range=new Range(range,loose);
-}catch(er){
-return false;
-}
-return range.test(version);
-}
-
-exports.maxSatisfying=maxSatisfying;
-function maxSatisfying(versions,range,loose){
-return versions.filter(function(version){
-return satisfies(version,range,loose);
-}).sort(function(a,b){
-return rcompare(a,b,loose);
-})[0]||null;
-}
-
-exports.minSatisfying=minSatisfying;
-function minSatisfying(versions,range,loose){
-return versions.filter(function(version){
-return satisfies(version,range,loose);
-}).sort(function(a,b){
-return compare(a,b,loose);
-})[0]||null;
-}
-
-exports.validRange=validRange;
-function validRange(range,loose){
-try{
-
-
-return new Range(range,loose).range||'*';
-}catch(er){
-return null;
-}
-}
-
-
-exports.ltr=ltr;
-function ltr(version,range,loose){
-return outside(version,range,'<',loose);
-}
-
-
-exports.gtr=gtr;
-function gtr(version,range,loose){
-return outside(version,range,'>',loose);
-}
-
-exports.outside=outside;
-function outside(version,range,hilo,loose){
-version=new SemVer(version,loose);
-range=new Range(range,loose);
-
-var gtfn,ltefn,ltfn,comp,ecomp;
-switch(hilo){
-case'>':
-gtfn=gt;
-ltefn=lte;
-ltfn=lt;
-comp='>';
-ecomp='>=';
-break;
-case'<':
-gtfn=lt;
-ltefn=gte;
-ltfn=gt;
-comp='<';
-ecomp='<=';
-break;
-default:
-throw new TypeError('Must provide a hilo val of "<" or ">"');}
-
-
-
-if(satisfies(version,range,loose)){
-return false;
-}
-
-
-
-
-for(var i=0;i<range.set.length;++i){
-var comparators=range.set[i];
-
-var high=null;
-var low=null;
-
-comparators.forEach(function(comparator){
-if(comparator.semver===ANY){
-comparator=new Comparator('>=0.0.0');
-}
-high=high||comparator;
-low=low||comparator;
-if(gtfn(comparator.semver,high.semver,loose)){
-high=comparator;
-}else if(ltfn(comparator.semver,low.semver,loose)){
-low=comparator;
-}
-});
-
-
-
-if(high.operator===comp||high.operator===ecomp){
-return false;
-}
-
-
-
-if((!low.operator||low.operator===comp)&&
-ltefn(version,low.semver)){
-return false;
-}else if(low.operator===ecomp&&ltfn(version,low.semver)){
-return false;
-}
-}
-return true;
-}
-
-exports.prerelease=prerelease;
-function prerelease(version,loose){
-var parsed=parse(version,loose);
-return parsed&&parsed.prerelease.length?parsed.prerelease:null;
-}
-
-}).call(this,require('_process'));
-},{"_process":71}],143:[function(require,module,exports){
-(function(Buffer){
-'use strict';
-
-
-const jpeg=require('jpeg-js');
-
-function getPixel(x,y,channel,width,buff){
-return buff[(x+y*width)*4+channel];
-}
-
-function isWhitePixel(i,j,img){
-return getPixel(i,j,0,img.width,img.data)>=249&&
-getPixel(i,j,1,img.width,img.data)>=249&&
-getPixel(i,j,2,img.width,img.data)>=249;
-}
-
-function convertPixelsToHistogram(img){
-const createHistogramArray=function(){
-const ret=new Array(256);
-for(let i=0;i<ret.length;i++){
-ret[i]=0;
-}
-return ret;
-};
-
-const width=img.width;
-const height=img.height;
-
-const histograms=[
-createHistogramArray(),
-createHistogramArray(),
-createHistogramArray()];
-
-
-for(let j=0;j<height;j++){
-for(let i=0;i<width;i++){
-
-if(isWhitePixel(i,j,img)){
-continue;
-}
-
-for(let channel=0;channel<histograms.length;channel++){
-const pixelValue=getPixel(i,j,channel,width,img.data);
-histograms[channel][pixelValue]++;
-}
-}
-}
-
-return histograms;
-}
-
-function synthesizeWhiteFrame(frames){
-const firstImageData=jpeg.decode(frames[0].getImage());
-const width=firstImageData.width;
-const height=firstImageData.height;
-
-const frameData=new Buffer(width*height*4);
-let i=0;
-while(i<frameData.length){
-frameData[i++]=0xFF;
-frameData[i++]=0xFF;
-frameData[i++]=0xFF;
-frameData[i++]=0xFF;
-}
-
-var jpegImageData=jpeg.encode({
-data:frameData,
-width:width,
-height:height});
-
-return jpegImageData.data;
-}
-
-const screenshotTraceCategory='disabled-by-default-devtools.screenshot';
-function extractFramesFromTimeline(timeline,opts){
-opts=opts||{};
-let trace;
-trace=typeof timeline==='string'?fs.readFileSync(timeline,'utf-8'):timeline;
-try{
-trace=typeof trace==='string'?JSON.parse(trace):trace;
-}catch(e){
-throw new Error('Speedline: Invalid JSON'+e.message);
-}
-let events=trace.traceEvents||trace;
-events=events.sort((a,b)=>a.ts-b.ts).filter(e=>e.ts!==0);
-
-const startTs=(opts.timeOrigin||events[0].ts)/1000;
-const endTs=events[events.length-1].ts/1000;
-
-let lastFrame=null;
-const rawScreenshots=events.filter(e=>e.cat.includes(screenshotTraceCategory)&&e.ts>=startTs*1000);
-const uniqueFrames=rawScreenshots.map(function(evt){
-const base64img=evt.args&&evt.args.snapshot;
-const timestamp=evt.ts/1000;
-
-if(base64img===lastFrame){
-return null;
-}
-
-lastFrame=base64img;
-const imgBuff=new Buffer(base64img,'base64');
-return frame(imgBuff,timestamp);
-}).filter(Boolean);
-
-if(uniqueFrames.length===0){
-return Promise.reject(new Error('No screenshots found in trace'));
-}
-
-const fakeWhiteFrame=frame(synthesizeWhiteFrame(uniqueFrames),startTs);
-uniqueFrames.unshift(fakeWhiteFrame);
-
-const data={
-startTs,
-endTs,
-frames:uniqueFrames};
-
-return Promise.resolve(data);
-}
-
-function frame(imgBuff,ts){
-let _histogram=null;
-let _progress=null;
-let _isProgressInterpolated=null;
-let _perceptualProgress=null;
-let _isPerceptualProgressInterpolated=null;
-let _parsedImage=null;
-
-return{
-getHistogram:function(){
-if(_histogram){
-return _histogram;
-}
-
-const pixels=this.getParsedImage();
-_histogram=convertPixelsToHistogram(pixels);
-return _histogram;
-},
-
-getTimeStamp:function(){
-return ts;
-},
-
-setProgress:function(progress,isInterpolated){
-_progress=progress;
-_isProgressInterpolated=Boolean(isInterpolated);
-},
-
-setPerceptualProgress:function(progress,isInterpolated){
-_perceptualProgress=progress;
-_isPerceptualProgressInterpolated=Boolean(isInterpolated);
-},
-
-getImage:function(){
-return imgBuff;
-},
-
-getParsedImage:function(){
-if(!_parsedImage){
-_parsedImage=jpeg.decode(imgBuff);
-}
-return _parsedImage;
-},
-
-getProgress:function(){
-return _progress;
-},
-
-isProgressInterpolated:function(){
-return _isProgressInterpolated;
-},
-
-getPerceptualProgress:function(){
-return _perceptualProgress;
-},
-
-isPerceptualProgressInterpolated:function(){
-return _isPerceptualProgressInterpolated;
-}};
-
-}
-
-module.exports={
-extractFramesFromTimeline,
-create:frame};
-
-
-}).call(this,require("buffer").Buffer);
-},{"buffer":54,"jpeg-js":134}],144:[function(require,module,exports){
-'use strict';
-
-const frame=require('./frame');
-const speedIndex=require('./speed-index');
-
-function calculateValues(frames,data){
-const indexes=speedIndex.calculateSpeedIndexes(frames,data);
-const duration=Math.floor(data.endTs-data.startTs);
-const first=Math.floor(indexes.firstPaintTs-data.startTs);
-const complete=Math.floor(indexes.visuallyCompleteTs-data.startTs);
-
-return{
-beginning:data.startTs,
-end:data.endTs,
-frames,
-first,
-complete,
-duration,
-speedIndex:indexes.speedIndex,
-perceptualSpeedIndex:indexes.perceptualSpeedIndex};
-
-}
-
-const Include={
-All:'all',
-pSI:'perceptualSpeedIndex',
-SI:'speedIndex'};
-
-
-
-
-
-
-
-
-module.exports=function(timeline,opts){
-const include=opts&&opts.include||Include.All;
-
-if(!Object.keys(Include).some(key=>Include[key]===include)){
-throw new Error(`Unrecognized include option: ${include}`);
-}
-
-return frame.extractFramesFromTimeline(timeline,opts).then(function(data){
-const frames=data.frames;
-
-if(include===Include.All||include===Include.SI){
-speedIndex.calculateVisualProgress(frames,opts);
-}
-
-if(include===Include.All||include===Include.pSI){
-speedIndex.calculatePerceptualProgress(frames,opts);
-}
-
-return calculateValues(frames,data);
-});
-};
-
-},{"./frame":143,"./speed-index":145}],145:[function(require,module,exports){
-'use strict';
-
-const imageSSIM=require('image-ssim');
-
-
-const fastModeAllowableChangeMax=5;
-const fastModeAllowableChangeMedian=3;
-const fastModeAllowableChangeMin=-1;
-
-const fastModeConstant=fastModeAllowableChangeMin;
-const fastModeMultiplier=fastModeAllowableChangeMax-fastModeConstant;
-const fastModeExponentiationCoefficient=Math.log((fastModeAllowableChangeMedian-fastModeConstant)/fastModeMultiplier);
-
-
-
-
-
-
-
-
-
-
-
-function calculateFastModeAllowableChange(elapsedTime){
-const elapsedTimeInSeconds=elapsedTime/1000;
-const allowableChange=fastModeMultiplier*Math.exp(fastModeExponentiationCoefficient*elapsedTimeInSeconds)+fastModeConstant;
-return allowableChange;
-}
-
-function calculateFrameProgress(current,initial,target){
-let total=0;
-let match=0;
-
-const currentHist=current.getHistogram();
-const initialHist=initial.getHistogram();
-const targetHist=target.getHistogram();
-
-for(let channel=0;channel<3;channel++){
-for(let pixelVal=0;pixelVal<256;pixelVal++){
-const currentCount=currentHist[channel][pixelVal];
-const initialCount=initialHist[channel][pixelVal];
-const targetCount=targetHist[channel][pixelVal];
-
-const currentDiff=Math.abs(currentCount-initialCount);
-const targetDiff=Math.abs(targetCount-initialCount);
-
-match+=Math.min(currentDiff,targetDiff);
-total+=targetDiff;
-}
-}
-
-let progress;
-if(match===0&&total===0){
-progress=100;
-}else{
-progress=Math.floor(match/total*100);
-}
-return progress;
-}
-
-function calculateProgressBetweenFrames(frames,lowerBound,upperBound,isFastMode,getProgress,setProgress){
-if(!isFastMode){
-frames.forEach(frame=>setProgress(frame,getProgress(frame),false));
-return;
-}
-
-const lowerFrame=frames[lowerBound];
-const upperFrame=frames[upperBound];
-const elapsedTime=upperFrame.getTimeStamp()-lowerFrame.getTimeStamp();
-
-const lowerProgress=getProgress(lowerFrame);
-const upperProgress=getProgress(upperFrame);
-
-setProgress(lowerFrame,lowerProgress,false);
-setProgress(upperFrame,upperProgress,false);
-
-if(Math.abs(lowerProgress-upperProgress)<calculateFastModeAllowableChange(elapsedTime)){
-for(let i=lowerBound+1;i<upperBound;i++){
-setProgress(frames[i],lowerProgress,true);
-}
-}else if(upperBound-lowerBound>1){
-const midpoint=Math.floor((lowerBound+upperBound)/2);
-calculateProgressBetweenFrames(frames,lowerBound,midpoint,isFastMode,getProgress,setProgress);
-calculateProgressBetweenFrames(frames,midpoint,upperBound,isFastMode,getProgress,setProgress);
-}
-}
-
-function calculateVisualProgress(frames,opts){
-const initial=frames[0];
-const target=frames[frames.length-1];
-
-function getProgress(frame){
-if(typeof frame.getProgress()==='number'){
-return frame.getProgress();
-}
-
-return calculateFrameProgress(frame,initial,target);
-}
-
-function setProgress(frame,progress,isInterpolated){
-return frame.setProgress(progress,isInterpolated);
-}
-
-calculateProgressBetweenFrames(
-frames,
-0,
-frames.length-1,
-opts&&opts.fastMode,
-getProgress,
-setProgress);
-
-
-return frames;
-}
-
-function calculateFrameSimilarity(frame,target){
-const defaultImageConfig={
-
-
-channels:4};
-
-
-const frameData=Object.assign(frame.getParsedImage(),defaultImageConfig);
-const targetData=Object.assign(target.getParsedImage(),defaultImageConfig);
-
-const diff=imageSSIM.compare(frameData,targetData);
-return diff.ssim;
-}
-
-function calculatePerceptualProgress(frames,opts){
-const initial=frames[0];
-const target=frames[frames.length-1];
-const initialSimilarity=calculateFrameSimilarity(initial,target);
-
-function getProgress(frame){
-if(typeof frame.getPerceptualProgress()==='number'){
-return frame.getPerceptualProgress();
-}
-
-const ssim=calculateFrameSimilarity(frame,target);
-return Math.max(100*(ssim-initialSimilarity)/(1-initialSimilarity),0);
-}
-
-function setProgress(frame,progress,isInterpolated){
-return frame.setPerceptualProgress(progress,isInterpolated);
-}
-
-calculateProgressBetweenFrames(
-frames,
-0,
-frames.length-1,
-opts&&opts.fastMode,
-getProgress,
-setProgress);
-
-
-return frames;
-}
-
-function calculateSpeedIndexes(frames,data){
-const hasVisualProgress=typeof frames[0].getProgress()==='number';
-const hasPerceptualProgress=typeof frames[0].getPerceptualProgress()==='number';
-const progressToUse=hasVisualProgress?'getProgress':'getPerceptualProgress';
-const startTs=data.startTs;
-let visuallyCompleteTs;
-let firstPaintTs;
-
-
-for(let i=0;i<frames.length&&!firstPaintTs;i++){
-if(frames[i][progressToUse]()>0){
-firstPaintTs=frames[i].getTimeStamp();
-}
-}
-
-
-for(let i=0;i<frames.length&&!visuallyCompleteTs;i++){
-if(frames[i][progressToUse]()>=100){
-visuallyCompleteTs=frames[i].getTimeStamp();
-}
-}
-
-let prevFrameTs=frames[0].getTimeStamp();
-let prevProgress=frames[0].getProgress();
-let prevPerceptualProgress=frames[0].getPerceptualProgress();
-
-
-
-let speedIndex=firstPaintTs-startTs;
-let perceptualSpeedIndex=firstPaintTs-startTs;
-
-frames.forEach(function(frame){
-
-if(frame.getTimeStamp()>firstPaintTs){
-const elapsed=frame.getTimeStamp()-prevFrameTs;
-speedIndex+=elapsed*(1-prevProgress);
-perceptualSpeedIndex+=elapsed*(1-prevPerceptualProgress);
-}
-
-prevFrameTs=frame.getTimeStamp();
-prevProgress=frame.getProgress()/100;
-prevPerceptualProgress=frame.getPerceptualProgress()/100;
-});
-
-speedIndex=hasVisualProgress?speedIndex:undefined;
-perceptualSpeedIndex=hasPerceptualProgress?perceptualSpeedIndex:undefined;
-
-return{
-firstPaintTs,
-visuallyCompleteTs,
-speedIndex,
-perceptualSpeedIndex};
-
-}
-
-module.exports={
-calculateFastModeAllowableChange,
-calculateFrameSimilarity,
-calculateVisualProgress,
-calculatePerceptualProgress,
-calculateSpeedIndexes};
-
-
-},{"image-ssim":133}],146:[function(require,module,exports){
-module.exports={
-"version":"2.9.1"};
-
-},{}],147:[function(require,module,exports){
-module.exports={"npm":{"angular":[{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10170"]},"severity":"medium","semver":{"unaffected":[">=1.2.0"],"vulnerable":["<=1.1.5"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N","disclosureTime":"2013-06-20T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:00:00.000Z","modificationTime":"2016-11-01T14:08:59.890Z","creationTime":"2016-11-01T14:08:59.890Z","id":"npm:angular:20130621","packageName":"angular","cvssScore":6.8,"alternativeIds":["SNYK-JS-ANGULAR-10170"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10179"]},"severity":"medium","semver":{"unaffected":[">=1.2.0"],"vulnerable":["<1.2.0 >=1.0.0"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-06-21T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:10:00.000Z","modificationTime":"2016-11-01T15:35:22.355Z","creationTime":"2016-11-01T15:35:22.355Z","id":"npm:angular:20130622","packageName":"angular","cvssScore":5.4,"alternativeIds":["SNYK-JS-ANGULAR-10179"]},{"title":"Arbitrary Script Injection","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10140"]},"severity":"high","semver":{"unaffected":[">=1.1.5"],"vulnerable":["<1.1.5"]},"credit":["Chirayu Krishnappa","Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","disclosureTime":"2013-06-24T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:20:00.000Z","modificationTime":"2016-11-01T12:48:50.251Z","creationTime":"2016-11-01T12:48:50.251Z","id":"npm:angular:20130625","packageName":"angular","cvssScore":8.1,"alternativeIds":["SNYK-JS-ANGULAR-10140"]},{"title":"Protection Bypass","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10200"]},"severity":"high","semver":{"unaffected":[">=1.2.2"],"vulnerable":["<1.2.2"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","disclosureTime":"2013-11-12T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:30:00.000Z","modificationTime":"2016-11-09T12:07:09.956Z","creationTime":"2016-11-09T12:07:09.956Z","id":"npm:angular:20131113","packageName":"angular","cvssScore":7.4,"alternativeIds":["SNYK-JS-ANGULAR-10200"]},{"title":"Arbitrary Code Execution","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10201"]},"severity":"low","semver":{"unaffected":[">=1.3.0"],"vulnerable":["<1.3.0"]},"credit":["Jann Horn"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N","disclosureTime":"2014-06-07T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:40:00.000Z","modificationTime":"2016-11-09T12:23:07.035Z","creationTime":"2016-11-09T12:23:07.035Z","id":"npm:angular:20140608","packageName":"angular","cvssScore":3.7,"alternativeIds":["SNYK-JS-ANGULAR-10201"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10191"]},"severity":"medium","semver":{"unaffected":[">=1.3.0-rc.4"],"vulnerable":["<1.3.0-rc.4"]},"credit":["Laurent Trillaud"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","disclosureTime":"2014-09-07T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T10:50:00.000Z","modificationTime":"2016-11-07T09:46:43.092Z","creationTime":"2016-11-07T09:46:43.092Z","id":"npm:angular:20140908","packageName":"angular","cvssScore":5.3,"alternativeIds":["SNYK-JS-ANGULAR-10191"]},{"title":"Unsafe Object Deserialization","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10141"]},"severity":"high","semver":{"unaffected":[">=1.2.24"],"vulnerable":["<1.2.24 >=1.2.19"]},"credit":["Chirayu Krishnappa"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","disclosureTime":"2014-09-08T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:00:00.000Z","modificationTime":"2016-11-01T13:57:31.962Z","creationTime":"2016-11-01T13:57:31.962Z","id":"npm:angular:20140909","packageName":"angular","cvssScore":7.4,"alternativeIds":["SNYK-JS-ANGULAR-10141"]},{"title":"Arbitrary Command Execution","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10173"]},"severity":"medium","semver":{"unaffected":[">=1.3.2"],"vulnerable":["<1.3.2"]},"credit":["Sebastian Lekies","Jann Horn","Gábor Molnár"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:L","disclosureTime":"2014-11-03T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:10:00.000Z","modificationTime":"2016-11-01T12:33:38.496Z","creationTime":"2016-11-01T12:33:38.496Z","id":"npm:angular:20141104","packageName":"angular","cvssScore":6.5,"alternativeIds":["SNYK-JS-ANGULAR-10173"]},{"title":"Arbitrary Code Execution","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10174"]},"severity":"high","semver":{"unaffected":[">=1.5.0-beta.2"],"vulnerable":["<1.5.0-beta.2"]},"credit":["Rodric Haddad"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","disclosureTime":"2015-03-09T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:20:00.000Z","modificationTime":"2017-02-13T14:24:12.988Z","creationTime":"2016-11-01T14:24:12.988Z","id":"npm:angular:20150310","packageName":"angular","cvssScore":7.4,"alternativeIds":["SNYK-JS-ANGULAR-10174"]},{"title":"JSONP Callback Attack","credit":["Pete Bacon Darwin"],"moduleName":"angular","packageName":"angular","language":"js","packageManager":"npm","id":"npm:angular:20150315","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10175"]},"semver":{"vulnerable":["<1.6.1"],"unaffected":[">=1.6.1"]},"patches":[],"cvssScore":6.5,"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2015-03-14T22:00:00.000Z","publicationTime":"2017-02-13T18:30:00.000Z","modificationTime":"2017-02-13T14:36:18.735Z","creationTime":"2016-11-01T14:36:18.735Z","alternativeIds":["SNYK-JS-ANGULAR-10175"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-78"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10176"]},"severity":"high","semver":{"unaffected":[">=1.5.0-beta.0"],"vulnerable":["<1.5.0-beta.0 >=1.0.0"]},"credit":["Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","disclosureTime":"2015-08-06T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:40:00.000Z","modificationTime":"2016-11-01T13:30:14.967Z","creationTime":"2016-11-01T13:30:14.967Z","id":"npm:angular:20150807","packageName":"angular","cvssScore":7.1,"alternativeIds":["SNYK-JS-ANGULAR-10176"]},{"title":"Clickjacking","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-693"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10177"]},"severity":"medium","semver":{"unaffected":[">=1.5.0-beta.0"],"vulnerable":["<1.5.0-beta.0 >=1.3.1"]},"credit":["Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N","disclosureTime":"2015-08-06T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T11:50:00.000Z","modificationTime":"2016-11-01T13:30:14.967Z","creationTime":"2016-11-01T13:30:14.967Z","id":"npm:angular:20150807-1","packageName":"angular","cvssScore":6.8,"alternativeIds":["SNYK-JS-ANGULAR-10177"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10182"]},"severity":"high","semver":{"unaffected":[">=1.5.0-beta.2"],"vulnerable":["<1.5.0-beta.2"]},"credit":["Igor Minar"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","disclosureTime":"2015-09-08T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:00:00.000Z","modificationTime":"2016-11-02T08:40:11.750Z","creationTime":"2016-11-02T08:40:11.750Z","id":"npm:angular:20150909","packageName":"angular","cvssScore":7.1,"alternativeIds":["SNYK-JS-ANGULAR-10182"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10180"]},"severity":"medium","semver":{"unaffected":[">=1.4.10"],"vulnerable":["<1.4.10"]},"credit":["Lucas Mirelmann"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2015-11-29T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:10:00.000Z","modificationTime":"2016-11-02T08:16:55.157Z","creationTime":"2016-11-02T08:16:55.157Z","id":"npm:angular:20151130","packageName":"angular","cvssScore":5.4,"alternativeIds":["SNYK-JS-ANGULAR-10180"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10181"]},"severity":"medium","semver":{"unaffected":[">=1.5.0-rc.0"],"vulnerable":["<1.5.0-rc.0"]},"credit":["Pete Bacon Darwin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2015-12-04T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:20:00.000Z","modificationTime":"2016-11-02T08:26:38.753Z","creationTime":"2016-11-02T08:26:38.753Z","id":"npm:angular:20151205","packageName":"angular","cvssScore":4.3,"alternativeIds":["SNYK-JS-ANGULAR-10181"]},{"title":"Cross-site Scripting (XSS)","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10202"]},"severity":"medium","semver":{"unaffected":[">=1.5.0-rc.2"],"vulnerable":["<1.5.0-rc.2 >=1.3.0"]},"credit":["Lucas Mirelmann"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2016-01-21T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:30:00.000Z","modificationTime":"2016-11-09T12:45:57.682Z","creationTime":"2016-11-09T12:45:57.682Z","id":"npm:angular:20160122","packageName":"angular","cvssScore":4.3,"alternativeIds":["SNYK-JS-ANGULAR-10202"]},{"title":"Arbitrary Script Injection","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10203"]},"severity":"medium","semver":{"unaffected":[">=1.2.30"],"vulnerable":["<1.2.30 >=1.0.0"]},"credit":["Raphaël Jamet"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2016-05-26T21:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:40:00.000Z","modificationTime":"2016-11-09T13:00:18.135Z","creationTime":"2016-11-09T13:00:18.135Z","id":"npm:angular:20160527","packageName":"angular","cvssScore":4.8,"alternativeIds":["SNYK-JS-ANGULAR-10203"]},{"title":"Content Security Policy (CSP) Bypass","moduleName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-10190"]},"severity":"medium","semver":{"unaffected":[">=1.5.9"],"vulnerable":["<1.5.9 >=1.5.0"]},"credit":["Martin Probst"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N","disclosureTime":"2016-10-31T22:00:00.000Z","patches":[],"publicationTime":"2017-01-23T12:50:00.000Z","modificationTime":"2017-01-24T09:16:32.893Z","creationTime":"2016-11-07T09:16:32.893Z","id":"npm:angular:20161101","packageName":"angular","cvssScore":6.5,"alternativeIds":["SNYK-JS-ANGULAR-10190"]},{"title":"Cross-site Scripting (XSS)","credit":["Unknown"],"moduleName":"angular","packageName":"angular","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-ANGULAR-12026"]},"semver":{"unaffected":[">=1.6.7"],"vulnerable":["<1.6.7"]},"patches":[],"cvssScore":6.5,"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2017-10-17T21:00:00.000Z","publicationTime":"2017-12-25T14:45:01.473Z","modificationTime":"2017-12-19T11:18:55.007Z","creationTime":"2017-12-19T11:18:55.007Z","id":"npm:angular:20171018","alternativeIds":["SNYK-JS-ANGULAR-12026"]}],"backbone":[{"title":"Cross-site Scripting (XSS)","credit":[],"language":"js","packageManager":"npm","packageName":"backbone","moduleName":"backbone","semver":{"vulnerable":["<0.5.0"],"unaffected":[">=0.5.0"]},"identifiers":{"CWE":[],"CVE":[],"ALTERNATIVE":["SNYK-JS-BACKBONE-10054"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/backbone/20110701/backbone_20110701_0_0_0cdc525961d3fa98e810ffae6bcc8e3838e36d93.patch"],"version":"<0.5.0 >=0.3.3","modificationTime":"2015-11-06T02:09:36.180Z","comments":["https://github.com/jashkenas/backbone/commit/0cdc525961d3fa98e810ffae6bcc8e3838e36d93.patch"],"id":"patch:npm:backbone:20110701:0"}],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","id":"npm:backbone:20110701","cvssScore":6.5,"alternativeIds":["SNYK-JS-BACKBONE-10054"]},{"title":"Cross-site Scripting (XSS)","credit":["Unknown"],"creationTime":"2016-05-24T06:45:20.086Z","modificationTime":"2016-05-24T06:45:20.086Z","publicationTime":"2016-06-22T17:50:20.000Z","disclosureTime":"2016-05-23T17:50:20.000Z","semver":{"vulnerable":["<= 0.3.3"],"unaffected":[">= 0.5.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":108,"ALTERNATIVE":["SNYK-JS-BACKBONE-10110"]},"patches":[],"moduleName":"backbone","language":"js","packageManager":"npm","id":"npm:backbone:20160523","packageName":"backbone","cvssScore":6.5,"alternativeIds":["SNYK-JS-BACKBONE-10110"]}],"bootstrap":[{"title":"Cross-site Scripting (XSS)","credit":["Peter Corsaro"],"packageName":"bootstrap","moduleName":"bootstrap","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-BOOTSTRAP-10433"]},"semver":{"unaffected":[">=2.1.0"],"vulnerable":["<2.1.0"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2012-05-09T21:00:00.000Z","publicationTime":"2017-04-10T09:39:59.975Z","modificationTime":"2017-02-27T10:05:00.075Z","creationTime":"2017-02-27T10:05:00.075Z","id":"npm:bootstrap:20120510","cvssScore":6.5,"alternativeIds":["SNYK-JS-BOOTSTRAP-10433"]},{"title":"Cross-Site Scripting (XSS)","credit":["Unknown"],"moduleName":"bootstrap","packageName":"bootstrap","language":"js","packageManager":"npm","identifiers":{"CVE":[],"CWE":["CWE-79"],"ALTERNATIVE":["SNYK-JS-BOOTSTRAP-10860"]},"semver":{"unaffected":[">=3.4.0 <4.0.0-alpha || >4.0.0-beta.2"],"vulnerable":["<3.4.0 || >=4.0.0-alpha <4.0.0-beta.2"]},"severity":"medium","cvssScore":6.5,"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","patches":[],"creationTime":"2017-11-25T17:23:26.518Z","modificationTime":"2017-11-25T17:23:26.518Z","publicationTime":"2018-01-19T09:37:48.056Z","disclosureTime":"2016-06-27T17:23:26.518Z","id":"npm:bootstrap:20160627","alternativeIds":["SNYK-JS-BOOTSTRAP-10860"]}],"dojo":[{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["<1.1"],"unaffected":[">=1.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2008-6681"],"ALTERNATIVE":["SNYK-JS-DOJO-10051"]},"patches":[],"moduleName":"dojo","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:dojo:20090409","packageName":"dojo","cvssScore":6.5,"alternativeIds":["SNYK-JS-DOJO-10051"]},{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":[">=0.4 <0.4.4 || >=1.0 <1.0.3 || >=1.1 <1.1.2 || >=1.2 <1.2.4 || >=1.3 <1.3.3 || >=1.4 <1.4.2"],"unaffected":["<0.4 >=0.4.4 || <1.0 >=1.0.3 || <1.1 >=1.1.2 || <1.2 >=1.2.4 || <1.3 >=1.3.3 || <1.4 >=1.4.2"]},"CVSSv2":"CVSS:2.0/AV:N/AC:L/Au:N/C:C/I:C/A:C","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H","severity":"high","identifiers":{"CWE":["CWE-16"],"CVE":["CVE-2010-2276","CVE-2010-2272"],"ALTERNATIVE":["npm:dojo:20100614-1","npm:dojo:20100614-2","npm:dojo:20100614-3","npm:dojo:20100614-4","npm:dojo:20100614-5","SNYK-JS-DOJO-10052"]},"patches":[],"moduleName":"dojo","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:dojo:20100614","packageName":"dojo","cvssScore":10,"alternativeIds":["npm:dojo:20100614-1","npm:dojo:20100614-2","npm:dojo:20100614-3","npm:dojo:20100614-4","npm:dojo:20100614-5","SNYK-JS-DOJO-10052"]},{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["<1.4.2"],"unaffected":[">=1.4.2"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2010-2275"],"ALTERNATIVE":["SNYK-JS-DOJO-10053"]},"patches":[],"moduleName":"dojo","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:dojo:20100614-6","packageName":"dojo","cvssScore":6.5,"alternativeIds":["SNYK-JS-DOJO-10053"]},{"title":"Cross Site Scripting","credit":["Unknown"],"creationTime":"2016-05-24T06:45:20.086Z","modificationTime":"2016-05-24T06:45:20.086Z","publicationTime":"2016-06-22T00:00:00.000Z","disclosureTime":"2016-05-23T16:48:27.000Z","semver":{"vulnerable":["<= 1.0.0"],"unaffected":[">= 1.1.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2008-6681"],"NSP":107,"ALTERNATIVE":["SNYK-JS-DOJO-10108"]},"patches":[],"moduleName":"dojo","language":"js","packageManager":"npm","id":"npm:dojo:20160523","packageName":"dojo","cvssScore":4.3,"alternativeIds":["SNYK-JS-DOJO-10108"]}],"foundation-sites":[{"title":"Cross-site Scripting (XSS)","credit":["Mathieu Amiot"],"moduleName":"foundation-sites","packageName":"foundation-sites","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-FOUNDATIONSITES-10413"]},"semver":{"unaffected":[">=3.0.6"],"vulnerable":["<3.0.6 >=3.0.0"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvssScore":6.5,"disclosureTime":"2012-07-16T21:00:00.000Z","publicationTime":"2017-03-13T08:00:22.155Z","modificationTime":"2017-03-06T12:29:55.952Z","creationTime":"2017-03-06T12:29:55.952Z","id":"npm:foundation-sites:20120717","alternativeIds":["SNYK-JS-FOUNDATIONSITES-10413"]},{"title":"Cross-site Scripting (XSS)","credit":["Maya Kokits"],"moduleName":"foundation-sites","packageName":"foundation-sites","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-FOUNDATIONSITES-10414"]},"semver":{"unaffected":[">=5.5.3"],"vulnerable":["<5.5.3"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2015-06-18T21:00:00.000Z","publicationTime":"2017-03-13T08:00:22.227Z","modificationTime":"2017-03-06T12:57:37.670Z","creationTime":"2017-03-06T12:57:37.670Z","id":"npm:foundation-sites:20150619","cvssScore":6.5,"alternativeIds":["SNYK-JS-FOUNDATIONSITES-10414"]},{"title":"Cross-site Scripting (XSS)","credit":["Nathaniel Paulus"],"moduleName":"foundation-sites","packageName":"foundation-sites","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-FOUNDATIONSITES-10743"]},"semver":{"vulnerable":["<6.0.0"],"unaffected":[">=6.0.0"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","cvssScore":6.5,"disclosureTime":"2017-08-01T21:00:00.000Z","publicationTime":"2017-08-02T13:09:44.451Z","modificationTime":"2017-08-02T10:42:11.945Z","creationTime":"2017-08-02T10:42:11.945Z","id":"npm:foundation-sites:20170802","alternativeIds":["SNYK-JS-FOUNDATIONSITES-10743"]}],"handlebars":[{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["<=1.0.0-beta.3"],"unaffected":[">1.0.0-beta.3"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-HANDLEBARS-10047"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/handlebars/20110425/handlebars_20110425_0_0_b291a1ad8c9a33f834d126450635f0b6ca546a0c.patch"],"version":"<=1.0.0-beta.3","modificationTime":"2015-11-06T02:09:36.180Z","comments":["https://github.com/rgrove/handlebars.js/commit/b291a1ad8c9a33f834d126450635f0b6ca546a0c.patch"],"id":"patch:npm:handlebars:20110425:0"}],"moduleName":"handlebars","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:handlebars:20110425","packageName":"handlebars","cvssScore":5.3,"alternativeIds":["SNYK-JS-HANDLEBARS-10047"]},{"title":"Content Injection (XSS)","credit":["Matias P. Brutti"],"semver":{"vulnerable":["<4.0.0"],"unaffected":[">=4.0.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":61,"ALTERNATIVE":["SNYK-JS-HANDLEBARS-10068"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/handlebars/20151207/handlebars_0.patch"],"version":"<4.0.0 >=3.0.2","modificationTime":"2015-12-14T23:52:16.811Z","comments":["https://github.com/wycats/handlebars.js/commit/83b8e846a3569bd366cf0b6bdc1e4604d1a2077e"],"id":"patch:npm:handlebars:20151207:0"}],"moduleName":"handlebars","creationTime":"2015-12-14T23:52:16.811Z","modificationTime":"2015-12-14T23:52:16.811Z","publicationTime":"2015-12-14T23:52:16.811Z","disclosureTime":"2015-12-07T16:52:07.962Z","language":"js","packageManager":"npm","id":"npm:handlebars:20151207","packageName":"handlebars","cvssScore":5.3,"alternativeIds":["SNYK-JS-HANDLEBARS-10068"]}],"jquery":[{"title":"Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2011-4969"],"ALTERNATIVE":["SNYK-JS-JQUERY-10183"]},"severity":"medium","semver":{"unaffected":[">=1.6.3"],"vulnerable":["<1.6.3"]},"credit":["Dave Methvin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2011-06-05T21:00:00.000Z","patches":[],"publicationTime":"2016-10-20T14:16:53.138Z","modificationTime":"2016-11-06T15:25:26.117Z","creationTime":"2016-11-06T15:25:26.117Z","id":"npm:jquery:20110606","packageName":"jquery","cvssScore":5.4,"alternativeIds":["SNYK-JS-JQUERY-10183"]},{"title":"Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2012-6708"],"NSP":329,"ALTERNATIVE":["SNYK-JS-JQUERY-10184"]},"severity":"medium","semver":{"unaffected":[">=1.9.0"],"vulnerable":["<1.9.0 >=1.7.1"]},"credit":["Richard Gibson"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-06-19T21:00:00.000Z","patches":[],"publicationTime":"2016-10-20T14:16:53.138Z","modificationTime":"2017-03-12T14:17:57.686Z","creationTime":"2016-11-06T13:53:57.686Z","id":"npm:jquery:20120206","packageName":"jquery","cvssScore":5.4,"alternativeIds":["SNYK-JS-JQUERY-10184"]},{"title":"DOM Based Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2014-6071"],"ALTERNATIVE":["SNYK-JS-JQUERY-10185"]},"severity":"medium","semver":{"unaffected":[">=1.6.2"],"vulnerable":["<=1.5.1 >=1.4.2"]},"credit":["Mauro Risonho de Paula Assumpção"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2014-09-01T21:00:00.000Z","patches":[],"publicationTime":"2016-10-20T14:16:53.138Z","modificationTime":"2016-10-06T14:16:53.138Z","creationTime":"2016-11-06T14:16:53.138Z","id":"npm:jquery:20140902","packageName":"jquery","cvssScore":5.4,"alternativeIds":["SNYK-JS-JQUERY-10185"]},{"title":"Cross-site Scripting (XSS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2015-9251"],"NSP":328,"ALTERNATIVE":["SNYK-JS-JQUERY-10186"]},"severity":"medium","semver":{"unaffected":[">=3.0.0-beta1 || >=1.12.0 <1.12.3"],"vulnerable":["<3.0.0-beta1 >1.12.3 || <1.12.0 >=1.4.0"]},"credit":["Egor Homakov"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2015-06-26T21:00:00.000Z","patches":[],"publicationTime":"2016-11-27T00:00:00.000Z","modificationTime":"2017-03-27T15:12:44.538Z","creationTime":"2016-11-06T15:12:44.538Z","id":"npm:jquery:20150627","packageName":"jquery","cvssScore":5.4,"alternativeIds":["SNYK-JS-JQUERY-10186"]},{"title":"Denial of Service (DoS)","moduleName":"jquery","language":"js","packageManager":"npm","identifiers":{"CWE":[],"CVE":["CVE-2016-10707"],"NSP":330,"ALTERNATIVE":["SNYK-JS-JQUERY-10187"]},"severity":"low","semver":{"unaffected":[">=3.0.0"],"vulnerable":["<3.0.0 >=2.1.0-beta1"]},"credit":["Michał Gołębiowski"],"CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","disclosureTime":"2016-05-28T21:00:00.000Z","patches":[],"publicationTime":"2016-12-26T15:37:35.224Z","modificationTime":"2016-12-26T15:37:35.224Z","creationTime":"2016-11-06T15:37:35.224Z","id":"npm:jquery:20160529","packageName":"jquery","cvssScore":3.7,"alternativeIds":["SNYK-JS-JQUERY-10187"]}],"jquery-mobile":[{"title":"Cross-site Scripting (XSS)","moduleName":"jquery-mobile","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-JQUERYMOBILE-10199"]},"severity":"medium","semver":{"unaffected":[">=1.2.0"],"vulnerable":["<1.2.0"]},"credit":["Masato Kinugawa"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","disclosureTime":"2012-08-01T21:00:00.000Z","patches":[],"publicationTime":"2016-12-26T11:28:34.624Z","modificationTime":"2016-12-26T11:28:34.624Z","creationTime":"2016-11-09T11:28:34.624Z","id":"npm:jquery-mobile:20120802","packageName":"jquery-mobile","cvssScore":6.5,"alternativeIds":["SNYK-JS-JQUERYMOBILE-10199"]}],"jquery-ui":[{"title":"Cross-site Scripting (XSS)","moduleName":"jquery-ui","packageName":"jquery-ui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2010-5312"],"ALTERNATIVE":["SNYK-JS-JQUERYUI-10188"]},"severity":"medium","semver":{"unaffected":[">=1.10.0"],"vulnerable":["<1.10.0"]},"credit":["shadowman131"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2010-09-02T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T14:37:13.516Z","modificationTime":"2017-02-13T14:37:13.516Z","creationTime":"2016-12-26T14:37:13.516Z","id":"npm:jquery-ui:20100903","cvssScore":4.3,"alternativeIds":["SNYK-JS-JQUERYUI-10188"]},{"title":"Cross-site Scripting (XSS) via Tooltip","moduleName":"jquery-ui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2012-6662"],"ALTERNATIVE":["SNYK-JS-JQUERYUI-10189"]},"severity":"medium","semver":{"unaffected":[">=1.10.0"],"vulnerable":["<1.10.0"]},"credit":["Scott González"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","disclosureTime":"2012-11-26T22:00:00.000Z","patches":[],"publicationTime":"2016-12-26T15:04:27.065Z","modificationTime":"2016-12-26T15:04:27.065Z","creationTime":"2016-11-06T15:04:27.065Z","id":"npm:jquery-ui:20121127","packageName":"jquery-ui","cvssScore":4.3,"alternativeIds":["SNYK-JS-JQUERYUI-10189"]},{"title":"XSS in dialog closeText","credit":["Phat Ly"],"creationTime":"2016-07-22T00:00:02.715Z","modificationTime":"2016-07-22T00:00:02.715Z","publicationTime":"2016-07-21T22:21:41.000Z","disclosureTime":"2016-07-21T22:21:41.000Z","semver":{"vulnerable":["<=1.11.4"],"unaffected":[">=1.12.0"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N","severity":"high","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":127,"ALTERNATIVE":["SNYK-JS-JQUERYUI-10118"]},"patches":[],"moduleName":"jquery-ui","language":"js","packageManager":"npm","id":"npm:jquery-ui:20160721","packageName":"jquery-ui","cvssScore":7.3,"alternativeIds":["SNYK-JS-JQUERYUI-10118"]}],"knockout":[{"title":"Cross-site Scripting (XSS)","credit":["Steven Sanderson"],"moduleName":"knockout","packageName":"knockout","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-KNOCKOUT-10415"]},"semver":{"unaffected":[">=3.0.0"],"vulnerable":["<3.0.0 >=2.1.0-pre"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-06-30T21:00:00.000Z","publicationTime":"2017-03-13T08:00:22.295Z","modificationTime":"2017-03-01T12:39:34.669Z","creationTime":"2017-03-01T12:39:34.669Z","id":"npm:knockout:20130701","cvssScore":5.4,"alternativeIds":["SNYK-JS-KNOCKOUT-10415"]}],"moment":[{"title":"Regular Expression Denial of Service (ReDoS)","credit":["Adam Baldwin"],"language":"js","packageManager":"npm","moduleName":"moment","packageName":"moment","id":"npm:moment:20160126","semver":{"vulnerable":["<=2.11.1"],"unaffected":[">2.11.1"]},"identifiers":{"CWE":["CWE-400"],"CVE":[],"NSP":55,"ALTERNATIVE":["SNYK-JS-MOMENT-10084"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_0_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<=2.11.1 >2.10.6","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:0"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_1_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<=2.10.6 >2.9.0","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:1"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_2_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<=2.9.0 >2.2.1","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:2"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_3_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"=2.2.1","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:3"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20160126/moment_20160126_0_4_34af63b8b21208a949dfaf42d228502c73d20ec0.patch"],"version":"<2.2.1 >2.0.0","modificationTime":"2016-01-26T20:04:21.225Z","comments":[],"id":"patch:npm:moment:20160126:4"}],"cvssScore":5.3,"severity":"low","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","disclosureTime":"2016-01-26T20:04:21.225Z","creationTime":"2016-02-01T19:00:03.862Z","modificationTime":"2016-09-28T19:00:03.862Z","publicationTime":"2016-02-01T19:00:03.862Z","alternativeIds":["SNYK-JS-MOMENT-10084"]},{"title":"Regular Expression Denial of Service (ReDoS)","credit":["Snyk Security Research Team"],"language":"js","packageManager":"npm","moduleName":"moment","packageName":"moment","id":"npm:moment:20161019","identifiers":{"CWE":["CWE-400"],"CVE":[],"ALTERNATIVE":["SNYK-JS-MOMENT-10164"]},"semver":{"vulnerable":["<2.15.2"],"unaffected":[">=2.15.2"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20161019/moment_20161019_0_1.patch"],"version":"<2.15.2 >=2.14.0","modificationTime":"2016-10-24T00:00:00.000Z","comments":[],"id":"patch:npm:moment:20161019:0"},{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20161019/moment_20161019_0_0.patch"],"version":"<2.14.0 >=2.12.0","modificationTime":"2016-10-24T00:00:00.000Z","comments":[],"id":"patch:npm:moment:20161019:1"}],"cvssScore":5.9,"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H","disclosureTime":"2016-10-18T21:00:00.000Z","publicationTime":"2016-10-24T06:57:59.675Z","modificationTime":"2016-10-23T06:57:59.675Z","creationTime":"2016-10-23T06:57:59.675Z","alternativeIds":["SNYK-JS-MOMENT-10164"]},{"title":"Regular Expression Denial of Service (ReDoS)","credit":["Cristian-Alexandru Staicu"],"moduleName":"moment","packageName":"moment","language":"js","packageManager":"npm","identifiers":{"NSP":532,"CWE":["CWE-400"],"CVE":[],"ALTERNATIVE":["SNYK-JS-MOMENT-10841"]},"semver":{"unaffected":[">=2.19.3"],"vulnerable":["<2.19.3"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/moment/20170905/moment_0_0_69ed9d44957fa6ab12b73d2ae29d286a857b80eb.patch"],"version":"<2.19.3 >=2.16.0","modificationTime":"2017-11-30T14:47:22.471Z","comments":[],"id":"patch:npm:moment:20170905:0"}],"cvssScore":3.7,"severity":"low","CVSSv3":"CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L","disclosureTime":"2017-09-05T21:00:00.000Z","publicationTime":"2017-11-28T14:47:22.471Z","modificationTime":"2017-11-28T06:55:05.106Z","creationTime":"2017-09-13T07:55:05.106Z","id":"npm:moment:20170905","alternativeIds":["SNYK-JS-MOMENT-10841"]}],"mustache":[{"title":"Cross-site Scripting (XSS)","credit":[],"semver":{"vulnerable":["< 0.3.1"],"unaffected":[">= 0.3.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-MUSTACHE-10046"]},"patches":[],"moduleName":"mustache","creationTime":"2015-11-06T02:09:36.180Z","publicationTime":"2015-11-06T02:09:36.180Z","modificationTime":"2015-11-06T02:09:36.180Z","disclosureTime":"2015-11-06T02:09:36.180Z","language":"js","packageManager":"npm","id":"npm:mustache:20110814","packageName":"mustache","cvssScore":5.4,"alternativeIds":["SNYK-JS-MUSTACHE-10046"]},{"title":"Content Injection due to quoteless attributes","credit":["Matias P. Brutti"],"semver":{"vulnerable":["<2.2.1"],"unaffected":[">=2.2.1"]},"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","severity":"medium","identifiers":{"CWE":["CWE-79"],"CVE":[],"NSP":62,"ALTERNATIVE":["SNYK-JS-MUSTACHE-10067"]},"patches":[{"urls":["https://s3.amazonaws.com/snyk-rules-pre-repository/snapshots/master/patches/npm/mustache/20151207/mustache_0.patch"],"version":"<2.2.1 >=2.1.0","modificationTime":"2015-12-14T23:52:16.806Z","comments":["https://github.com/janl/mustache.js/commit/378bcca8a5cfe4058f294a3dbb78e8755e8e0da5"],"id":"patch:npm:mustache:20151207:0"}],"moduleName":"mustache","creationTime":"2015-12-14T23:52:16.806Z","modificationTime":"2015-12-14T23:52:16.806Z","publicationTime":"2015-12-14T23:52:16.806Z","disclosureTime":"2015-12-07T17:13:57.565Z","language":"js","packageManager":"npm","id":"npm:mustache:20151207","packageName":"mustache","cvssScore":5.3,"alternativeIds":["SNYK-JS-MUSTACHE-10067"]}],"react":[{"title":"Cross-site Scripting (XSS)","moduleName":"react","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2013-7035"],"ALTERNATIVE":["SNYK-JS-REACT-10192"]},"severity":"medium","semver":{"unaffected":[">=0.5.2 || <=0.3.x || =0.4.2"],"vulnerable":[">=0.5.0 <0.5.2 || >=0.4.0 <0.4.2"]},"credit":["Paul O’Shannessy","Thomas Aylott"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N","disclosureTime":"2013-12-16T22:00:00.000Z","patches":[],"publicationTime":"2017-01-18T14:00:21.094Z","modificationTime":"2016-11-08T08:23:21.094Z","creationTime":"2016-11-08T08:23:21.094Z","id":"npm:react:20131217","packageName":"react","cvssScore":6.5,"alternativeIds":["SNYK-JS-REACT-10192"]},{"title":"Cross-site Scripting (XSS)","moduleName":"react","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-REACT-10193"]},"severity":"high","semver":{"unaffected":[">=0.14.0"],"vulnerable":["<0.14.0"]},"credit":["Daniel LeCheminant"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N","disclosureTime":"2015-03-17T22:00:00.000Z","patches":[],"publicationTime":"2017-01-18T14:00:38.403Z","modificationTime":"2016-11-08T09:59:38.403Z","creationTime":"2016-11-08T09:59:38.403Z","id":"npm:react:20150318","packageName":"react","cvssScore":7.1,"alternativeIds":["SNYK-JS-REACT-10193"]}],"riot":[{"title":"Cross-site Scripting (XSS)","credit":["crazy2be"],"moduleName":"riot","packageName":"riot","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-RIOT-10447"]},"semver":{"unaffected":[">=0.9.6"],"vulnerable":["<0.9.6"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2013-11-13T22:00:00.000Z","publicationTime":"2017-05-08T12:34:46.386Z","modificationTime":"2017-03-20T14:44:23.092Z","creationTime":"2017-03-20T14:44:23.092Z","id":"npm:riot:20131114","cvssScore":6.5,"alternativeIds":["SNYK-JS-RIOT-10447"]}],"socket.io":[{"title":"Insecure Randomness","credit":["Martin Thomson"],"moduleName":"socket.io","packageName":"socket.io","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-330"],"CVE":[],"NSP":321,"ALTERNATIVE":["SNYK-JS-SOCKETIO-10397"]},"semver":{"unaffected":[">=0.9.7"],"vulnerable":["<0.9.7"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","disclosureTime":"2012-03-22T22:00:00.000Z","publicationTime":"2017-02-13T13:46:59.513Z","modificationTime":"2017-02-13T13:46:59.513Z","creationTime":"2017-02-01T13:46:59.513Z","id":"npm:socket.io:20120323","cvssScore":5.3,"alternativeIds":["SNYK-JS-SOCKETIO-10397"]},{"title":"Cross-site Scripting (XSS)","credit":["Almog Melamed"],"moduleName":"socket.io","packageName":"socket.io","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-SOCKETIO-10398"]},"semver":{"unaffected":[">=0.9.6"],"vulnerable":["<0.9.6"]},"patches":[],"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-04-16T21:00:00.000Z","publicationTime":"2017-02-13T13:28:52.754Z","modificationTime":"2017-02-13T13:28:52.754Z","creationTime":"2017-02-01T13:28:52.754Z","id":"npm:socket.io:20120417","cvssScore":5.4,"alternativeIds":["SNYK-JS-SOCKETIO-10398"]}],"vue":[{"title":"Cross-site Scripting (XSS)","credit":["Unknown"],"moduleName":"vue","packageName":"vue","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-VUE-12035"]},"semver":{"unaffected":[">=2.3.0-beta.1"],"vulnerable":["<2.3.0-beta.1"]},"patches":[],"cvssScore":6.5,"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2017-03-31T21:00:00.000Z","publicationTime":"2017-12-25T14:45:02.463Z","modificationTime":"2017-12-19T11:55:30.354Z","creationTime":"2017-12-19T11:55:30.354Z","id":"npm:vue:20170401","alternativeIds":["SNYK-JS-VUE-12035"]},{"title":"Cross-site Scripting (XSS)","credit":["Unknown"],"moduleName":"vue","packageName":"vue","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-VUE-12036"]},"semver":{"unaffected":[">=2.4.3"],"vulnerable":["<2.4.3"]},"patches":[],"cvssScore":6.5,"severity":"medium","CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","disclosureTime":"2017-08-28T21:00:00.000Z","publicationTime":"2017-12-25T14:45:02.568Z","modificationTime":"2017-12-19T11:56:17.017Z","creationTime":"2017-12-19T11:56:17.017Z","id":"npm:vue:20170829","alternativeIds":["SNYK-JS-VUE-12036"]}],"yui":[{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2010-4207"],"ALTERNATIVE":["SNYK-JS-YUI-10383"]},"severity":"medium","semver":{"unaffected":[">=2.8.2 || <2.4.0"],"vulnerable":["<2.8.2 >=2.4.0"]},"credit":["Unknown"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2010-10-24T22:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:24:55.944Z","modificationTime":"2017-01-22T09:24:55.944Z","creationTime":"2017-01-22T09:24:55.944Z","id":"npm:yui:20101025","cvssScore":5.4,"alternativeIds":["SNYK-JS-YUI-10383"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":[],"ALTERNATIVE":["SNYK-JS-YUI-10384"]},"severity":"medium","semver":{"unaffected":[">=3.5.1 || <3.5.0-PR1"],"vulnerable":["<3.5.1 >=3.5.0-PR1"]},"credit":["Ryan Grove"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-04-27T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:12:40.841Z","modificationTime":"2017-02-13T09:12:40.841Z","creationTime":"2017-01-22T09:12:40.841Z","id":"npm:yui:20120428","cvssScore":5.4,"alternativeIds":["SNYK-JS-YUI-10384"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2012-5881","CVE-2012-5882","CVE-2012-5883"],"ALTERNATIVE":["SNYK-JS-YUI-10385"]},"severity":"medium","semver":{"unaffected":[">=3.0.0 || <2.4.0"],"vulnerable":["<3.0.0 >=2.4.0"]},"credit":["Unknwon"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2012-10-29T22:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:20:03.679Z","modificationTime":"2017-02-13T09:20:03.679Z","creationTime":"2017-01-22T09:20:03.679Z","id":"npm:yui:20121030","cvssScore":5.4,"alternativeIds":["SNYK-JS-YUI-10385"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2013-4941"],"NSP":332,"ALTERNATIVE":["SNYK-JS-YUI-10386"]},"severity":"medium","semver":{"unaffected":[">=3.10.0 || <3.0.0"],"vulnerable":["<3.10.0 >=3.0.0"]},"credit":["Aleksandr Dobkin"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-05-14T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T08:54:05.822Z","modificationTime":"2017-02-13T08:54:05.822Z","creationTime":"2017-01-22T08:54:05.822Z","id":"npm:yui:20130515","cvssScore":5.4,"alternativeIds":["SNYK-JS-YUI-10386"]},{"title":"Cross-site Scripting (XSS)","moduleName":"yui","packageName":"yui","language":"js","packageManager":"npm","identifiers":{"CWE":["CWE-79"],"CVE":["CVE-2013-4940"],"ALTERNATIVE":["SNYK-JS-YUI-10387"]},"severity":"medium","semver":{"unaffected":[">=3.10.3 <3.10.2"],"vulnerable":["=3.10.2"]},"credit":["Unknown"],"CVSSv3":"CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N","disclosureTime":"2013-06-03T21:00:00.000Z","patches":[],"publicationTime":"2017-02-13T09:01:24.863Z","modificationTime":"2017-02-13T09:01:24.863Z","creationTime":"2017-01-22T09:01:24.863Z","id":"npm:yui:20130604","cvssScore":5.4,"alternativeIds":["SNYK-JS-YUI-10387"]}]}};
-
-},{}]},{},[46]);
\ No newline at end of file
diff --git a/front_end/audits2_worker/module.json b/front_end/audits2_worker/module.json
deleted file mode 100644
index 22c9ed8..0000000
--- a/front_end/audits2_worker/module.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-    "dependencies": [
-        "worker_service"
-    ],
-    "extensions": [
-        {
-            "type": "@Service",
-            "factoryName": "Audits2Service",
-            "name": "Audits2Service"
-        }
-    ],
-    "scripts": [
-        "lighthouse/lighthouse-background.js",
-        "Audits2Service.js"
-    ],
-    "skip_compilation": [
-        "lighthouse/lighthouse-background.js"
-    ]
-}
diff --git a/front_end/bindings/BlackboxManager.js b/front_end/bindings/BlackboxManager.js
deleted file mode 100644
index f8f4fac..0000000
--- a/front_end/bindings/BlackboxManager.js
+++ /dev/null
@@ -1,434 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- */
-Bindings.BlackboxManager = class {
-  /**
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(debuggerWorkspaceBinding) {
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
-    Common.moduleSetting('skipStackFramesPattern').addChangeListener(this._patternChanged.bind(this));
-    Common.moduleSetting('skipContentScripts').addChangeListener(this._patternChanged.bind(this));
-
-    /** @type {!Set<function()>} */
-    this._listeners = new Set();
-
-    /** @type {!Map<!SDK.DebuggerModel, !Map<string, !Array<!Protocol.Debugger.ScriptPosition>>>} */
-    this._debuggerModelData = new Map();
-    /** @type {!Map<string, boolean>} */
-    this._isBlackboxedURLCache = new Map();
-
-    SDK.targetManager.observeModels(SDK.DebuggerModel, this);
-  }
-
-  /**
-   * @param {function()} listener
-   */
-  addChangeListener(listener) {
-    this._listeners.add(listener);
-  }
-
-  /**
-   * @param {function()} listener
-   */
-  removeChangeListener(listener) {
-    this._listeners.delete(listener);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelAdded(debuggerModel) {
-    this._setBlackboxPatterns(debuggerModel);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    this._debuggerModelData.delete(debuggerModel);
-    this._isBlackboxedURLCache.clear();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @return {!Promise<boolean>}
-   */
-  _setBlackboxPatterns(debuggerModel) {
-    const regexPatterns = Common.moduleSetting('skipStackFramesPattern').getAsArray();
-    const patterns = /** @type {!Array<string>} */ ([]);
-    for (const item of regexPatterns) {
-      if (!item.disabled && item.pattern)
-        patterns.push(item.pattern);
-    }
-    return debuggerModel.setBlackboxPatterns(patterns);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} location
-   * @return {boolean}
-   */
-  isBlackboxedRawLocation(location) {
-    const script = location.script();
-    if (!script)
-      return false;
-    const positions = this._scriptPositions(script);
-    if (!positions)
-      return this._isBlackboxedScript(script);
-    const index = positions.lowerBound(location, comparator);
-    return !!(index % 2);
-
-    /**
-     * @param {!SDK.DebuggerModel.Location} a
-     * @param {!Protocol.Debugger.ScriptPosition} b
-     * @return {number}
-     */
-    function comparator(a, b) {
-      if (a.lineNumber !== b.lineNumber)
-        return a.lineNumber - b.lineNumber;
-      return a.columnNumber - b.columnNumber;
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  isBlackboxedUISourceCode(uiSourceCode) {
-    const projectType = uiSourceCode.project().type();
-    const isContentScript = projectType === Workspace.projectTypes.ContentScripts;
-    if (isContentScript && Common.moduleSetting('skipContentScripts').get())
-      return true;
-    const url = this._uiSourceCodeURL(uiSourceCode);
-    return url ? this.isBlackboxedURL(url) : false;
-  }
-
-  /**
-   * @param {string} url
-   * @param {boolean=} isContentScript
-   * @return {boolean}
-   */
-  isBlackboxedURL(url, isContentScript) {
-    if (this._isBlackboxedURLCache.has(url))
-      return !!this._isBlackboxedURLCache.get(url);
-    if (isContentScript && Common.moduleSetting('skipContentScripts').get())
-      return true;
-    const regex = Common.moduleSetting('skipStackFramesPattern').asRegExp();
-    const isBlackboxed = regex && regex.test(url);
-    this._isBlackboxedURLCache.set(url, isBlackboxed);
-    return isBlackboxed;
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {?SDK.SourceMap} sourceMap
-   * @return {!Promise<undefined>}
-   */
-  sourceMapLoaded(script, sourceMap) {
-    if (!sourceMap)
-      return Promise.resolve();
-    const previousScriptState = this._scriptPositions(script);
-    if (!previousScriptState)
-      return Promise.resolve();
-
-    const hasBlackboxedMappings = sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url));
-    const mappings = hasBlackboxedMappings ? sourceMap.mappings().slice() : [];
-    if (!mappings.length) {
-      if (previousScriptState.length > 0)
-        return this._setScriptState(script, []);
-      return Promise.resolve();
-    }
-    mappings.sort(mappingComparator);
-
-    let currentBlackboxed = false;
-    let isBlackboxed = false;
-    const positions = [];
-    // If content in script file begin is not mapped and one or more ranges are blackboxed then blackbox it.
-    if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) {
-      positions.push({lineNumber: 0, columnNumber: 0});
-      currentBlackboxed = true;
-    }
-    for (const mapping of mappings) {
-      if (mapping.sourceURL && currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) {
-        positions.push({lineNumber: mapping.lineNumber, columnNumber: mapping.columnNumber});
-        currentBlackboxed = !currentBlackboxed;
-      }
-      isBlackboxed = currentBlackboxed || isBlackboxed;
-    }
-    return this._setScriptState(script, !isBlackboxed ? [] : positions);
-    /**
-     * @param {!SDK.SourceMapEntry} a
-     * @param {!SDK.SourceMapEntry} b
-     * @return {number}
-     */
-    function mappingComparator(a, b) {
-      if (a.lineNumber !== b.lineNumber)
-        return a.lineNumber - b.lineNumber;
-      return a.columnNumber - b.columnNumber;
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?string}
-   */
-  _uiSourceCodeURL(uiSourceCode) {
-    return uiSourceCode.project().type() === Workspace.projectTypes.Debugger ? null : uiSourceCode.url();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  canBlackboxUISourceCode(uiSourceCode) {
-    const url = this._uiSourceCodeURL(uiSourceCode);
-    return url ? !!this._urlToRegExpString(url) : false;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  blackboxUISourceCode(uiSourceCode) {
-    const url = this._uiSourceCodeURL(uiSourceCode);
-    if (url)
-      this._blackboxURL(url);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  unblackboxUISourceCode(uiSourceCode) {
-    const url = this._uiSourceCodeURL(uiSourceCode);
-    if (url)
-      this._unblackboxURL(url);
-  }
-
-  blackboxContentScripts() {
-    Common.moduleSetting('skipContentScripts').set(true);
-  }
-
-  unblackboxContentScripts() {
-    Common.moduleSetting('skipContentScripts').set(false);
-  }
-
-  /**
-   * @param {string} url
-   */
-  _blackboxURL(url) {
-    const regexPatterns = Common.moduleSetting('skipStackFramesPattern').getAsArray();
-    const regexValue = this._urlToRegExpString(url);
-    if (!regexValue)
-      return;
-    let found = false;
-    for (let i = 0; i < regexPatterns.length; ++i) {
-      const item = regexPatterns[i];
-      if (item.pattern === regexValue) {
-        item.disabled = false;
-        found = true;
-        break;
-      }
-    }
-    if (!found)
-      regexPatterns.push({pattern: regexValue});
-    Common.moduleSetting('skipStackFramesPattern').setAsArray(regexPatterns);
-  }
-
-  /**
-   * @param {string} url
-   */
-  _unblackboxURL(url) {
-    let regexPatterns = Common.moduleSetting('skipStackFramesPattern').getAsArray();
-    const regexValue = Bindings.blackboxManager._urlToRegExpString(url);
-    if (!regexValue)
-      return;
-    regexPatterns = regexPatterns.filter(function(item) {
-      return item.pattern !== regexValue;
-    });
-    for (let i = 0; i < regexPatterns.length; ++i) {
-      const item = regexPatterns[i];
-      if (item.disabled)
-        continue;
-      try {
-        const regex = new RegExp(item.pattern);
-        if (regex.test(url))
-          item.disabled = true;
-      } catch (e) {
-      }
-    }
-    Common.moduleSetting('skipStackFramesPattern').setAsArray(regexPatterns);
-  }
-
-  _patternChanged() {
-    this._isBlackboxedURLCache.clear();
-
-    /** @type {!Array<!Promise>} */
-    const promises = [];
-    for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) {
-      promises.push(this._setBlackboxPatterns(debuggerModel));
-      for (const script of debuggerModel.scripts())
-        promises.push(this._addScript(script).then(loadSourceMap.bind(this, script)));
-    }
-    Promise.all(promises).then(() => {
-      const listeners = Array.from(this._listeners);
-      for (const listener of listeners)
-        listener();
-      this._patternChangeFinishedForTests();
-    });
-
-    /**
-     * @param {!SDK.Script} script
-     * @return {!Promise<undefined>}
-     * @this {Bindings.BlackboxManager}
-     */
-    function loadSourceMap(script) {
-      return this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.sourceMapForScript(script));
-    }
-  }
-
-  _patternChangeFinishedForTests() {
-    // This method is sniffed in tests.
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _globalObjectCleared(event) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    this._debuggerModelData.delete(debuggerModel);
-    this._isBlackboxedURLCache.clear();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _parsedScriptSource(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-    this._addScript(script);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {!Promise<undefined>}
-   */
-  _addScript(script) {
-    if (!script.sourceURL && !script.sourceMapURL)
-      return Promise.resolve();
-    const blackboxed = this._isBlackboxedScript(script);
-    return this._setScriptState(script, blackboxed ? [{lineNumber: 0, columnNumber: 0}] : []);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {boolean}
-   */
-  _isBlackboxedScript(script) {
-    return this.isBlackboxedURL(script.sourceURL, script.isContentScript());
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {?Array<!Protocol.Debugger.ScriptPosition>}
-   */
-  _scriptPositions(script) {
-    if (this._debuggerModelData.has(script.debuggerModel))
-      return this._debuggerModelData.get(script.debuggerModel).get(script.scriptId) || null;
-    return null;
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions
-   */
-  _setScriptPositions(script, positions) {
-    const debuggerModel = script.debuggerModel;
-    if (!this._debuggerModelData.has(debuggerModel))
-      this._debuggerModelData.set(debuggerModel, new Map());
-    this._debuggerModelData.get(debuggerModel).set(script.scriptId, positions);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions
-   * @return {!Promise<undefined>}
-   */
-  _setScriptState(script, positions) {
-    const previousScriptState = this._scriptPositions(script);
-    if (previousScriptState) {
-      let hasChanged = false;
-      hasChanged = previousScriptState.length !== positions.length;
-      for (let i = 0; !hasChanged && i < positions.length; ++i) {
-        hasChanged = positions[i].lineNumber !== previousScriptState[i].lineNumber ||
-            positions[i].columnNumber !== previousScriptState[i].columnNumber;
-      }
-      if (!hasChanged)
-        return Promise.resolve();
-    } else {
-      if (positions.length === 0)
-        return Promise.resolve().then(updateState.bind(this, false));
-    }
-
-    return script.setBlackboxedRanges(positions).then(updateState.bind(this));
-
-    /**
-     * @param {boolean} success
-     * @this {Bindings.BlackboxManager}
-     */
-    function updateState(success) {
-      if (success) {
-        this._setScriptPositions(script, positions);
-        this._debuggerWorkspaceBinding.updateLocations(script);
-        const isBlackboxed = positions.length !== 0;
-        if (!isBlackboxed && script.sourceMapURL)
-          this._debuggerWorkspaceBinding.maybeLoadSourceMap(script);
-      } else {
-        const hasPositions = !!this._scriptPositions(script);
-        if (!hasPositions)
-          this._setScriptPositions(script, []);
-      }
-    }
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  _urlToRegExpString(url) {
-    const parsedURL = new Common.ParsedURL(url);
-    if (parsedURL.isAboutBlank() || parsedURL.isDataURL())
-      return '';
-    if (!parsedURL.isValid)
-      return '^' + url.escapeForRegExp() + '$';
-    let name = parsedURL.lastPathComponent;
-    if (name)
-      name = '/' + name;
-    else if (parsedURL.folderPathComponents)
-      name = parsedURL.folderPathComponents + '/';
-    if (!name)
-      name = parsedURL.host;
-    if (!name)
-      return '';
-    const scheme = parsedURL.scheme;
-    let prefix = '';
-    if (scheme && scheme !== 'http' && scheme !== 'https') {
-      prefix = '^' + scheme + '://';
-      if (scheme === 'chrome-extension')
-        prefix += parsedURL.host + '\\b';
-      prefix += '.*';
-    }
-    return prefix + name.escapeForRegExp() + (url.endsWith(name) ? '$' : '\\b');
-  }
-};
-
-/** @type {!Bindings.BlackboxManager} */
-Bindings.blackboxManager;
diff --git a/front_end/bindings/BreakpointManager.js b/front_end/bindings/BreakpointManager.js
deleted file mode 100644
index d57b5ff..0000000
--- a/front_end/bindings/BreakpointManager.js
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @unrestricted
- */
-Bindings.BreakpointManager = class extends Common.Object {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {!SDK.TargetManager} targetManager
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(workspace, targetManager, debuggerWorkspaceBinding) {
-    super();
-    this._storage = new Bindings.BreakpointManager.Storage();
-    this._workspace = workspace;
-    this._targetManager = targetManager;
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-
-    /** @type {!Map<!Workspace.UISourceCode, !Map<number, !Map<number, !Array<!Bindings.BreakpointManager.Breakpoint>>>>} */
-    this._breakpointsForUISourceCode = new Map();
-    /** @type {!Map<string, !Bindings.BreakpointManager.Breakpoint>} */
-    this._breakpointByStorageId = new Map();
-
-    this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
-    this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
-    this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
-  }
-
-  /**
-   * @param {string} url
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {string}
-   */
-  static _breakpointStorageId(url, lineNumber, columnNumber) {
-    if (!url)
-      return '';
-    return url + ':' + lineNumber + ':' + columnNumber;
-  }
-
-  /**
-   * @param {string} fromURL
-   * @param {!Workspace.UISourceCode} toSourceCode
-   */
-  copyBreakpoints(fromURL, toSourceCode) {
-    const breakpointItems = this._storage.breakpointItems(fromURL);
-    for (const item of breakpointItems)
-      this.setBreakpoint(toSourceCode, item.lineNumber, item.columnNumber, item.condition, item.enabled);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _restoreBreakpoints(uiSourceCode) {
-    const url = uiSourceCode.url();
-    if (!url)
-      return;
-
-    this._storage.mute();
-    const breakpointItems = this._storage.breakpointItems(url);
-    for (const item of breakpointItems)
-      this._innerSetBreakpoint(uiSourceCode, item.lineNumber, item.columnNumber, item.condition, item.enabled);
-    this._storage.unmute();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._restoreBreakpoints(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeRemoved(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._removeUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _removeUISourceCode(uiSourceCode) {
-    const breakpoints = uiSourceCode[Bindings.BreakpointManager._breakpointsSymbol] || new Set();
-    for (const breakpoint of breakpoints)
-      breakpoint._resetLocations();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string} condition
-   * @param {boolean} enabled
-   * @return {!Bindings.BreakpointManager.Breakpoint}
-   */
-  setBreakpoint(uiSourceCode, lineNumber, columnNumber, condition, enabled) {
-    let uiLocation = new Workspace.UILocation(uiSourceCode, lineNumber, columnNumber);
-    const normalizedLocation = this._debuggerWorkspaceBinding.normalizeUILocation(uiLocation);
-    if (normalizedLocation.id() !== uiLocation.id()) {
-      Common.Revealer.reveal(normalizedLocation);
-      uiLocation = normalizedLocation;
-    }
-    return this._innerSetBreakpoint(
-        uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, condition, enabled);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string} condition
-   * @param {boolean} enabled
-   * @return {!Bindings.BreakpointManager.Breakpoint}
-   */
-  _innerSetBreakpoint(uiSourceCode, lineNumber, columnNumber, condition, enabled) {
-    const itemId = Bindings.BreakpointManager._breakpointStorageId(uiSourceCode.url(), lineNumber, columnNumber);
-    let breakpoint = this._breakpointByStorageId.get(itemId);
-    if (breakpoint) {
-      breakpoint.setPrimaryUISourceCode(uiSourceCode);
-      breakpoint._updateState(condition, enabled);
-      breakpoint._updateBreakpoint();
-      return breakpoint;
-    }
-    breakpoint = new Bindings.BreakpointManager.Breakpoint(
-        this, uiSourceCode, uiSourceCode.url(), lineNumber, columnNumber, condition, enabled);
-    this._breakpointByStorageId.set(itemId, breakpoint);
-    return breakpoint;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @return {!Array<!Bindings.BreakpointManager.Breakpoint>}
-   */
-  findBreakpoints(uiSourceCode, lineNumber) {
-    const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
-    const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null;
-    return lineBreakpoints ? lineBreakpoints.valuesArray()[0] : [];
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?Bindings.BreakpointManager.Breakpoint}
-   */
-  findBreakpoint(uiSourceCode, lineNumber, columnNumber) {
-    const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
-    const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null;
-    const columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(columnNumber) : null;
-    return columnBreakpoints ? columnBreakpoints[0] : null;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!TextUtils.TextRange} textRange
-   * @return {!Promise<!Array<!Workspace.UILocation>>}
-   */
-  possibleBreakpoints(uiSourceCode, textRange) {
-    const startLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(
-        uiSourceCode, textRange.startLine, textRange.startColumn);
-    const endLocation =
-        Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, textRange.endLine, textRange.endColumn);
-    if (!startLocation || !endLocation || startLocation.debuggerModel !== endLocation.debuggerModel)
-      return Promise.resolve([]);
-
-    return startLocation.debuggerModel
-        .getPossibleBreakpoints(startLocation, endLocation, /* restrictToFunction */ false)
-        .then(toUILocations.bind(this));
-
-    /**
-     * @this {!Bindings.BreakpointManager}
-     * @param {!Array<!SDK.DebuggerModel.BreakLocation>} locations
-     * @return {!Array<!Workspace.UILocation>}
-     */
-    function toUILocations(locations) {
-      let sortedLocations = locations.map(location => this._debuggerWorkspaceBinding.rawLocationToUILocation(location));
-      sortedLocations = sortedLocations.filter(location => location && location.uiSourceCode === uiSourceCode);
-      sortedLocations.sort(Workspace.UILocation.comparator);
-      if (!sortedLocations.length)
-        return [];
-      const result = [sortedLocations[0]];
-      let lastLocation = sortedLocations[0];
-      for (let i = 1; i < sortedLocations.length; ++i) {
-        if (sortedLocations[i].id() === lastLocation.id())
-          continue;
-        result.push(sortedLocations[i]);
-        lastLocation = sortedLocations[i];
-      }
-      return result;
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>}
-   */
-  breakpointsForUISourceCode(uiSourceCode) {
-    let result = [];
-    const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
-    const breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valuesArray() : [];
-    for (let i = 0; i < breakpoints.length; ++i) {
-      const lineBreakpoints = breakpoints[i];
-      const columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.valuesArray() : [];
-      result = result.concat.apply(result, columnBreakpointArrays);
-    }
-    return result;
-  }
-
-  /**
-   * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>}
-   */
-  _allBreakpoints() {
-    let result = [];
-    const uiSourceCodes = this._breakpointsForUISourceCode.keysArray();
-    for (let i = 0; i < uiSourceCodes.length; ++i)
-      result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i]));
-    return result;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
-   */
-  breakpointLocationsForUISourceCode(uiSourceCode) {
-    const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
-    const lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keysArray() : [];
-    const result = [];
-    for (let i = 0; i < lineNumbers.length; ++i) {
-      const lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]);
-      const columnNumbers = lineBreakpoints.keysArray();
-      for (let j = 0; j < columnNumbers.length; ++j) {
-        const columnBreakpoints = lineBreakpoints.get(columnNumbers[j]);
-        const lineNumber = parseInt(lineNumbers[i], 10);
-        const columnNumber = parseInt(columnNumbers[j], 10);
-        for (let k = 0; k < columnBreakpoints.length; ++k) {
-          const breakpoint = columnBreakpoints[k];
-          const uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber);
-          result.push({breakpoint: breakpoint, uiLocation: uiLocation});
-        }
-      }
-    }
-    return result;
-  }
-
-  /**
-   * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
-   */
-  allBreakpointLocations() {
-    let result = [];
-    const uiSourceCodes = this._breakpointsForUISourceCode.keysArray();
-    for (let i = 0; i < uiSourceCodes.length; ++i)
-      result = result.concat(this.breakpointLocationsForUISourceCode(uiSourceCodes[i]));
-    return result;
-  }
-
-  /**
-   * @param {boolean} toggleState
-   */
-  toggleAllBreakpoints(toggleState) {
-    const breakpoints = this._allBreakpoints();
-    for (let i = 0; i < breakpoints.length; ++i)
-      breakpoints[i].setEnabled(toggleState);
-  }
-
-  removeAllBreakpoints() {
-    const breakpoints = this._allBreakpoints();
-    for (let i = 0; i < breakpoints.length; ++i)
-      breakpoints[i].remove(false /* keepInStorage */);
-  }
-
-  /**
-   * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints
-   */
-  removeOtherBreakpoints(selectedBreakpoints) {
-    const allBreakpoints = this._allBreakpoints();
-    allBreakpoints.forEach(breakpoint => {
-      if (!selectedBreakpoints.has(breakpoint))
-        breakpoint.remove(false /* keepInStorage */);
-    });
-  }
-
-  _projectRemoved(event) {
-    const project = /** @type {!Workspace.Project} */ (event.data);
-    const uiSourceCodes = project.uiSourceCodes();
-    for (let i = 0; i < uiSourceCodes.length; ++i)
-      this._removeUISourceCode(uiSourceCodes[i]);
-  }
-
-  /**
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   * @param {boolean} removeFromStorage
-   */
-  _removeBreakpoint(breakpoint, removeFromStorage) {
-    if (removeFromStorage)
-      this._storage._removeBreakpoint(breakpoint);
-    this._breakpointByStorageId.delete(breakpoint._breakpointStorageId());
-  }
-
-  /**
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   * @param {!Workspace.UILocation} uiLocation
-   */
-  _uiLocationAdded(breakpoint, uiLocation) {
-    let breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
-    if (!breakpoints) {
-      breakpoints = new Map();
-      this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakpoints);
-    }
-    let lineBreakpoints = breakpoints.get(uiLocation.lineNumber);
-    if (!lineBreakpoints) {
-      lineBreakpoints = new Map();
-      breakpoints.set(uiLocation.lineNumber, lineBreakpoints);
-    }
-    let columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber);
-    if (!columnBreakpoints) {
-      columnBreakpoints = [];
-      lineBreakpoints.set(uiLocation.columnNumber, columnBreakpoints);
-    }
-    columnBreakpoints.push(breakpoint);
-    this.dispatchEventToListeners(
-        Bindings.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
-  }
-
-  /**
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   * @param {!Workspace.UILocation} uiLocation
-   */
-  _uiLocationRemoved(breakpoint, uiLocation) {
-    const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
-    if (!breakpoints)
-      return;
-
-    const lineBreakpoints = breakpoints.get(uiLocation.lineNumber);
-    if (!lineBreakpoints)
-      return;
-    const columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber);
-    if (!columnBreakpoints)
-      return;
-    columnBreakpoints.remove(breakpoint);
-    if (!columnBreakpoints.length)
-      lineBreakpoints.remove(uiLocation.columnNumber);
-    if (!lineBreakpoints.size)
-      breakpoints.remove(uiLocation.lineNumber);
-    if (!breakpoints.size)
-      this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);
-    this.dispatchEventToListeners(
-        Bindings.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
-  }
-};
-
-/** @enum {symbol} */
-Bindings.BreakpointManager.Events = {
-  BreakpointAdded: Symbol('breakpoint-added'),
-  BreakpointRemoved: Symbol('breakpoint-removed')
-};
-
-
-/**
- * @unrestricted
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- */
-Bindings.BreakpointManager.Breakpoint = class {
-  /**
-   * @param {!Bindings.BreakpointManager} breakpointManager
-   * @param {!Workspace.UISourceCode} primaryUISourceCode
-   * @param {string} url
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string} condition
-   * @param {boolean} enabled
-   */
-  constructor(breakpointManager, primaryUISourceCode, url, lineNumber, columnNumber, condition, enabled) {
-    this._breakpointManager = breakpointManager;
-    this._url = url;
-    this._lineNumber = lineNumber;
-    this._columnNumber = columnNumber;
-
-    this.setPrimaryUISourceCode(primaryUISourceCode);
-
-    /** @type {!Map<string, number>} */
-    this._numberOfDebuggerLocationForUILocation = new Map();
-
-    /** @type {string} */ this._condition;
-    /** @type {boolean} */ this._enabled;
-    /** @type {boolean} */ this._isRemoved;
-    /** @type {!Workspace.UILocation|undefined} */ this._fakePrimaryLocation;
-
-    this._currentState = null;
-    /** @type {!Map.<!SDK.DebuggerModel, !Bindings.BreakpointManager.ModelBreakpoint>}*/
-    this._modelBreakpoints = new Map();
-    this._updateState(condition, enabled);
-    this._breakpointManager._targetManager.observeModels(SDK.DebuggerModel, this);
-  }
-
-  refreshInDebugger() {
-    if (this._isRemoved)
-      return;
-    for (const breakpoint of this._modelBreakpoints.values())
-      breakpoint._refreshBreakpoint();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelAdded(debuggerModel) {
-    const debuggerWorkspaceBinding = this._breakpointManager._debuggerWorkspaceBinding;
-    this._modelBreakpoints.set(
-        debuggerModel, new Bindings.BreakpointManager.ModelBreakpoint(debuggerModel, this, debuggerWorkspaceBinding));
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    const modelBreakpoint = this._modelBreakpoints.remove(debuggerModel);
-    modelBreakpoint._cleanUpAfterDebuggerIsGone();
-    modelBreakpoint._removeEventListeners();
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} primaryUISourceCode
-   */
-  setPrimaryUISourceCode(primaryUISourceCode) {
-    const symbol = Bindings.BreakpointManager._breakpointsSymbol;
-    if (this._primaryUISourceCode)
-      this._primaryUISourceCode[symbol].delete(this);
-    this._primaryUISourceCode = primaryUISourceCode;
-    if (!primaryUISourceCode)
-      return;
-    if (!this._primaryUISourceCode[symbol])
-      this._primaryUISourceCode[symbol] = new Set();
-    this._primaryUISourceCode[symbol].add(this);
-  }
-
-  /**
-   * @return {string}
-   */
-  url() {
-    return this._url;
-  }
-
-  /**
-   * @return {number}
-   */
-  lineNumber() {
-    return this._lineNumber;
-  }
-
-  /**
-   * @return {number}
-   */
-  columnNumber() {
-    return this._columnNumber;
-  }
-
-  /**
-   * @param {?Workspace.UILocation} oldUILocation
-   * @param {!Workspace.UILocation} newUILocation
-   */
-  _replaceUILocation(oldUILocation, newUILocation) {
-    if (this._isRemoved)
-      return;
-
-    this._removeUILocation(oldUILocation, true);
-    this._removeFakeBreakpointAtPrimaryLocation();
-
-    const current = (this._numberOfDebuggerLocationForUILocation.get(newUILocation.id()) || 0) + 1;
-    this._numberOfDebuggerLocationForUILocation.set(newUILocation.id(), current);
-    if (current === 1)
-      this._breakpointManager._uiLocationAdded(this, newUILocation);
-  }
-
-  /**
-   * @param {?Workspace.UILocation} uiLocation
-   * @param {boolean=} muteCreationFakeBreakpoint
-   */
-  _removeUILocation(uiLocation, muteCreationFakeBreakpoint) {
-    if (!uiLocation || !this._numberOfDebuggerLocationForUILocation.has(uiLocation.id()))
-      return;
-    const current = (this._numberOfDebuggerLocationForUILocation.get(uiLocation.id()) || 0) - 1;
-    this._numberOfDebuggerLocationForUILocation.set(uiLocation.id(), current);
-    if (current !== 0)
-      return;
-
-    this._numberOfDebuggerLocationForUILocation.delete(uiLocation.id());
-    this._breakpointManager._uiLocationRemoved(this, uiLocation);
-    if (!muteCreationFakeBreakpoint)
-      this._fakeBreakpointAtPrimaryLocation();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  enabled() {
-    return this._enabled;
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._updateState(this._condition, enabled);
-  }
-
-  /**
-   * @return {string}
-   */
-  condition() {
-    return this._condition;
-  }
-
-  /**
-   * @param {string} condition
-   */
-  setCondition(condition) {
-    this._updateState(condition, this._enabled);
-  }
-
-  /**
-   * @param {string} condition
-   * @param {boolean} enabled
-   */
-  _updateState(condition, enabled) {
-    if (this._enabled === enabled && this._condition === condition)
-      return;
-    this._enabled = enabled;
-    this._condition = condition;
-    this._breakpointManager._storage._updateBreakpoint(this);
-    this._updateBreakpoint();
-  }
-
-  _updateBreakpoint() {
-    this._removeFakeBreakpointAtPrimaryLocation();
-    this._fakeBreakpointAtPrimaryLocation();
-    const modelBreakpoints = this._modelBreakpoints.valuesArray();
-    for (let i = 0; i < modelBreakpoints.length; ++i)
-      modelBreakpoints[i]._scheduleUpdateInDebugger();
-  }
-
-  /**
-   * @param {boolean} keepInStorage
-   */
-  remove(keepInStorage) {
-    this._isRemoved = true;
-    const removeFromStorage = !keepInStorage;
-    this._removeFakeBreakpointAtPrimaryLocation();
-    const modelBreakpoints = this._modelBreakpoints.valuesArray();
-    for (let i = 0; i < modelBreakpoints.length; ++i) {
-      modelBreakpoints[i]._scheduleUpdateInDebugger();
-      modelBreakpoints[i]._removeEventListeners();
-    }
-
-    this.setPrimaryUISourceCode(null);
-    this._breakpointManager._removeBreakpoint(this, removeFromStorage);
-    this._breakpointManager._targetManager.unobserveModels(SDK.DebuggerModel, this);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _updateInDebuggerForModel(debuggerModel) {
-    this._modelBreakpoints.get(debuggerModel)._scheduleUpdateInDebugger();
-  }
-
-  /**
-   * @return {string}
-   */
-  _breakpointStorageId() {
-    return Bindings.BreakpointManager._breakpointStorageId(this._url, this._lineNumber, this._columnNumber);
-  }
-
-  _fakeBreakpointAtPrimaryLocation() {
-    if (this._isRemoved || this._numberOfDebuggerLocationForUILocation.size || this._fakePrimaryLocation)
-      return;
-
-    if (!this._primaryUISourceCode)
-      return;
-
-    this._fakePrimaryLocation = this._primaryUISourceCode.uiLocation(this._lineNumber, this._columnNumber);
-    if (this._fakePrimaryLocation)
-      this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation);
-  }
-
-  _removeFakeBreakpointAtPrimaryLocation() {
-    if (this._fakePrimaryLocation) {
-      this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLocation);
-      delete this._fakePrimaryLocation;
-    }
-  }
-
-  _resetLocations() {
-    this.setPrimaryUISourceCode(null);
-    this._removeFakeBreakpointAtPrimaryLocation();
-    const modelBreakpoints = this._modelBreakpoints.valuesArray();
-    for (let i = 0; i < modelBreakpoints.length; ++i)
-      modelBreakpoints[i]._resetLocations();
-  }
-};
-
-Bindings.BreakpointManager._breakpointsSymbol = Symbol('breakpoints');
-
-/**
- * @unrestricted
- */
-Bindings.BreakpointManager.ModelBreakpoint = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(debuggerModel, breakpoint, debuggerWorkspaceBinding) {
-    this._debuggerModel = debuggerModel;
-    this._breakpoint = breakpoint;
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-
-    this._liveLocations = new Bindings.LiveLocationPool();
-
-    /** @type {!Map<string, !Workspace.UILocation>} */
-    this._uiLocations = new Map();
-    this._debuggerModel.addEventListener(
-        SDK.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
-    this._debuggerModel.addEventListener(
-        SDK.DebuggerModel.Events.DebuggerWasEnabled, this._scheduleUpdateInDebugger, this);
-    this._hasPendingUpdate = false;
-    this._isUpdating = false;
-    this._cancelCallback = false;
-    this._currentState = null;
-    if (this._debuggerModel.debuggerEnabled())
-      this._scheduleUpdateInDebugger();
-  }
-
-  _resetLocations() {
-    for (const uiLocation of this._uiLocations.values())
-      this._breakpoint._removeUILocation(uiLocation);
-
-    this._uiLocations.clear();
-    this._liveLocations.disposeAll();
-  }
-
-  _scheduleUpdateInDebugger() {
-    if (this._isUpdating) {
-      this._hasPendingUpdate = true;
-      return;
-    }
-
-    this._isUpdating = true;
-    this._updateInDebugger(this._didUpdateInDebugger.bind(this));
-  }
-
-  _didUpdateInDebugger() {
-    this._isUpdating = false;
-    if (this._hasPendingUpdate) {
-      this._hasPendingUpdate = false;
-      this._scheduleUpdateInDebugger();
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _scriptDiverged() {
-    const uiSourceCode = this._breakpoint._primaryUISourceCode;
-    if (!uiSourceCode)
-      return false;
-    const scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode, this._debuggerModel);
-    return !!scriptFile && scriptFile.hasDivergedFromVM();
-  }
-
-  /**
-   * @param {function()} callback
-   * @return {!Promise}
-   */
-  async _updateInDebugger(callback) {
-    if (this._debuggerModel.target().isDisposed()) {
-      this._cleanUpAfterDebuggerIsGone();
-      callback();
-      return;
-    }
-
-    const uiSourceCode = this._breakpoint._primaryUISourceCode;
-    const lineNumber = this._breakpoint._lineNumber;
-    const columnNumber = this._breakpoint._columnNumber;
-    const condition = this._breakpoint.condition();
-
-    let debuggerLocation = uiSourceCode &&
-        Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-    if (debuggerLocation && debuggerLocation.debuggerModel !== this._debuggerModel)
-      debuggerLocation = null;
-    let newState;
-    if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._scriptDiverged()) {
-      newState = null;
-    } else if (debuggerLocation) {
-      const script = debuggerLocation.script();
-      if (script.sourceURL) {
-        newState = new Bindings.BreakpointManager.Breakpoint.State(
-            script.sourceURL, null, null, debuggerLocation.lineNumber, debuggerLocation.columnNumber, condition);
-      } else {
-        newState = new Bindings.BreakpointManager.Breakpoint.State(
-            null, script.scriptId, script.hash, debuggerLocation.lineNumber, debuggerLocation.columnNumber, condition);
-      }
-    } else if (this._breakpoint._currentState && this._breakpoint._currentState.url) {
-      const position = this._breakpoint._currentState;
-      newState = new Bindings.BreakpointManager.Breakpoint.State(
-          position.url, null, null, position.lineNumber, position.columnNumber, condition);
-    } else if (uiSourceCode) {
-      newState = new Bindings.BreakpointManager.Breakpoint.State(
-          uiSourceCode.url(), null, null, lineNumber, columnNumber, condition);
-    }
-    if (this._debuggerId && Bindings.BreakpointManager.Breakpoint.State.equals(newState, this._currentState)) {
-      callback();
-      return;
-    }
-
-    this._breakpoint._currentState = newState;
-
-    if (this._debuggerId) {
-      await this._refreshBreakpoint();
-      callback();
-      return;
-    }
-
-    if (!newState) {
-      callback();
-      return;
-    }
-
-    let result;
-    this._currentState = newState;
-    if (newState.url) {
-      result = await this._debuggerModel.setBreakpointByURL(
-          newState.url, newState.lineNumber, newState.columnNumber, newState.condition);
-    } else if (newState.scriptId && newState.scriptHash) {
-      result = await this._debuggerModel.setBreakpointInAnonymousScript(
-          newState.scriptId, newState.scriptHash, newState.lineNumber, newState.columnNumber, newState.condition);
-    }
-    if (result && result.breakpointId)
-      this._didSetBreakpointInDebugger(callback, result.breakpointId, result.locations);
-    else
-      this._didSetBreakpointInDebugger(callback, null, []);
-  }
-
-  async _refreshBreakpoint() {
-    if (!this._debuggerId)
-      return;
-    this._resetLocations();
-    await this._debuggerModel.removeBreakpoint(this._debuggerId);
-    this._didRemoveFromDebugger();
-    this._currentState = null;
-    this._scheduleUpdateInDebugger();
-  }
-
-  /**
-   * @param {function()} callback
-   * @param {?Protocol.Debugger.BreakpointId} breakpointId
-   * @param {!Array.<!SDK.DebuggerModel.Location>} locations
-   */
-  _didSetBreakpointInDebugger(callback, breakpointId, locations) {
-    if (this._cancelCallback) {
-      this._cancelCallback = false;
-      callback();
-      return;
-    }
-
-    if (!breakpointId) {
-      this._breakpoint.remove(true);
-      callback();
-      return;
-    }
-
-    this._debuggerId = breakpointId;
-    this._debuggerModel.addBreakpointListener(this._debuggerId, this._breakpointResolved, this);
-    for (let i = 0; i < locations.length; ++i) {
-      if (!this._addResolvedLocation(locations[i]))
-        break;
-    }
-    callback();
-  }
-
-  _didRemoveFromDebugger() {
-    if (this._cancelCallback) {
-      this._cancelCallback = false;
-      return;
-    }
-
-    this._resetLocations();
-    this._debuggerModel.removeBreakpointListener(this._debuggerId, this._breakpointResolved, this);
-    delete this._debuggerId;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _breakpointResolved(event) {
-    this._addResolvedLocation(/** @type {!SDK.DebuggerModel.Location}*/ (event.data));
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} location
-   * @param {!Bindings.LiveLocation} liveLocation
-   */
-  _locationUpdated(location, liveLocation) {
-    const uiLocation = liveLocation.uiLocation();
-    if (!uiLocation)
-      return;
-    const oldUILocation = this._uiLocations.get(location.id()) || null;
-    this._uiLocations.set(location.id(), uiLocation);
-    this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} location
-   * @return {boolean}
-   */
-  _addResolvedLocation(location) {
-    const uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(location);
-    if (!uiLocation)
-      return false;
-    const breakpoint = this._breakpoint._breakpointManager.findBreakpoint(
-        uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
-    if (breakpoint && breakpoint !== this._breakpoint) {
-      // location clash
-      this._breakpoint.remove(false /* keepInStorage */);
-      return false;
-    }
-    this._debuggerWorkspaceBinding.createLiveLocation(
-        location, this._locationUpdated.bind(this, location), this._liveLocations);
-    return true;
-  }
-
-  _cleanUpAfterDebuggerIsGone() {
-    if (this._isUpdating)
-      this._cancelCallback = true;
-
-    this._resetLocations();
-    this._currentState = null;
-    if (this._debuggerId)
-      this._didRemoveFromDebugger();
-  }
-
-  _removeEventListeners() {
-    this._debuggerModel.removeEventListener(
-        SDK.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
-    this._debuggerModel.removeEventListener(
-        SDK.DebuggerModel.Events.DebuggerWasEnabled, this._scheduleUpdateInDebugger, this);
-  }
-};
-
-Bindings.BreakpointManager.Breakpoint.State = class {
-  /**
-   * @param {?string} url
-   * @param {?string} scriptId
-   * @param {?string} scriptHash
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string} condition
-   */
-  constructor(url, scriptId, scriptHash, lineNumber, columnNumber, condition) {
-    this.url = url;
-    this.scriptId = scriptId;
-    this.scriptHash = scriptHash;
-    this.lineNumber = lineNumber;
-    this.columnNumber = columnNumber;
-    this.condition = condition;
-  }
-
-  /**
-   * @param {?Bindings.BreakpointManager.Breakpoint.State|undefined} stateA
-   * @param {?Bindings.BreakpointManager.Breakpoint.State|undefined} stateB
-   * @return {boolean}
-   */
-  static equals(stateA, stateB) {
-    if (!stateA || !stateB)
-      return false;
-    return stateA.url === stateB.url && stateA.scriptId === stateB.scriptId &&
-        stateA.scriptHash === stateB.scriptHash && stateA.lineNumber === stateB.lineNumber &&
-        stateA.columnNumber === stateB.columnNumber && stateA.condition === stateB.condition;
-  }
-};
-
-
-Bindings.BreakpointManager.Storage = class {
-  constructor() {
-    this._setting = Common.settings.createLocalSetting('breakpoints', []);
-    /** @type {!Map<string, !Bindings.BreakpointManager.Storage.Item>} */
-    this._breakpoints = new Map();
-    const items = /** @type {!Array<!Bindings.BreakpointManager.Storage.Item>} */ (this._setting.get());
-    for (const item of items) {
-      item.columnNumber = item.columnNumber || 0;
-      this._breakpoints.set(
-          Bindings.BreakpointManager._breakpointStorageId(item.url, item.lineNumber, item.columnNumber), item);
-    }
-    /** @type {boolean|undefined} */ this._muted;
-  }
-
-  mute() {
-    this._muted = true;
-  }
-
-  unmute() {
-    delete this._muted;
-  }
-
-  /**
-   * @param {string} url
-   * @return {!Array<!Bindings.BreakpointManager.Storage.Item>}
-   */
-  breakpointItems(url) {
-    return Array.from(this._breakpoints.values()).filter(item => item.url === url);
-  }
-
-  /**
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   */
-  _updateBreakpoint(breakpoint) {
-    if (this._muted || !breakpoint._breakpointStorageId())
-      return;
-    this._breakpoints.set(breakpoint._breakpointStorageId(), new Bindings.BreakpointManager.Storage.Item(breakpoint));
-    this._save();
-  }
-
-  /**
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   */
-  _removeBreakpoint(breakpoint) {
-    if (this._muted)
-      return;
-    this._breakpoints.delete(breakpoint._breakpointStorageId());
-    this._save();
-  }
-
-  _save() {
-    this._setting.set(Array.from(this._breakpoints.values()));
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.BreakpointManager.Storage.Item = class {
-  /**
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   */
-  constructor(breakpoint) {
-    this.url = breakpoint._url;
-    this.lineNumber = breakpoint.lineNumber();
-    this.columnNumber = breakpoint.columnNumber();
-    this.condition = breakpoint.condition();
-    this.enabled = breakpoint.enabled();
-  }
-};
-
-/** @type {!Bindings.BreakpointManager} */
-Bindings.breakpointManager;
diff --git a/front_end/bindings/CSSWorkspaceBinding.js b/front_end/bindings/CSSWorkspaceBinding.js
deleted file mode 100644
index e911674..0000000
--- a/front_end/bindings/CSSWorkspaceBinding.js
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.CSSModel>}
- */
-Bindings.CSSWorkspaceBinding = class {
-  /**
-   * @param {!SDK.TargetManager} targetManager
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(targetManager, workspace) {
-    this._workspace = workspace;
-
-    /** @type {!Map.<!SDK.CSSModel, !Bindings.CSSWorkspaceBinding.ModelInfo>} */
-    this._modelToInfo = new Map();
-    /** @type {!Array<!Bindings.CSSWorkspaceBinding.SourceMapping>} */
-    this._sourceMappings = [];
-    targetManager.observeModels(SDK.CSSModel, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSModel} cssModel
-   */
-  modelAdded(cssModel) {
-    this._modelToInfo.set(cssModel, new Bindings.CSSWorkspaceBinding.ModelInfo(cssModel, this._workspace));
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSModel} cssModel
-   */
-  modelRemoved(cssModel) {
-    this._modelToInfo.get(cssModel)._dispose();
-    this._modelToInfo.delete(cssModel);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  updateLocations(header) {
-    this._modelToInfo.get(header.cssModel())._updateLocations(header);
-  }
-
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   * @return {!Bindings.CSSWorkspaceBinding.LiveLocation}
-   */
-  createLiveLocation(rawLocation, updateDelegate, locationPool) {
-    return this._modelToInfo.get(rawLocation.cssModel())._createLiveLocation(rawLocation, updateDelegate, locationPool);
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} cssProperty
-   * @param {boolean} forName
-   * @return {?Workspace.UILocation}
-   */
-  propertyUILocation(cssProperty, forName) {
-    const style = cssProperty.ownerStyle;
-    if (!style || style.type !== SDK.CSSStyleDeclaration.Type.Regular || !style.styleSheetId)
-      return null;
-    const header = style.cssModel().styleSheetHeaderForId(style.styleSheetId);
-    if (!header)
-      return null;
-
-    const range = forName ? cssProperty.nameRange() : cssProperty.valueRange();
-    if (!range)
-      return null;
-
-    const lineNumber = range.startLine;
-    const columnNumber = range.startColumn;
-    const rawLocation = new SDK.CSSLocation(
-        header, header.lineNumberInSource(lineNumber), header.columnNumberInSource(lineNumber, columnNumber));
-    return this.rawLocationToUILocation(rawLocation);
-  }
-
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    for (let i = this._sourceMappings.length - 1; i >= 0; --i) {
-      const uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
-      if (uiLocation)
-        return uiLocation;
-    }
-    return this._modelToInfo.get(rawLocation.cssModel())._rawLocationToUILocation(rawLocation);
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  uiLocationToRawLocations(uiLocation) {
-    for (let i = this._sourceMappings.length - 1; i >= 0; --i) {
-      const rawLocations = this._sourceMappings[i].uiLocationToRawLocations(uiLocation);
-      if (rawLocations.length)
-        return rawLocations;
-    }
-    const rawLocations = [];
-    for (const modelInfo of this._modelToInfo.values())
-      rawLocations.pushAll(modelInfo._uiLocationToRawLocations(uiLocation));
-    return rawLocations;
-  }
-
-  /**
-   * @param {!Bindings.CSSWorkspaceBinding.SourceMapping} sourceMapping
-   */
-  addSourceMapping(sourceMapping) {
-    this._sourceMappings.push(sourceMapping);
-  }
-};
-
-/**
- * @interface
- */
-Bindings.CSSWorkspaceBinding.SourceMapping = function() {};
-
-Bindings.CSSWorkspaceBinding.SourceMapping.prototype = {
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {},
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  uiLocationToRawLocations(uiLocation) {},
-};
-
-Bindings.CSSWorkspaceBinding.ModelInfo = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(cssModel, workspace) {
-    this._eventListeners = [
-      cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this),
-      cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this)
-    ];
-
-    this._stylesSourceMapping = new Bindings.StylesSourceMapping(cssModel, workspace);
-    const sourceMapManager = cssModel.sourceMapManager();
-    this._sassSourceMapping = new Bindings.SASSSourceMapping(cssModel.target(), sourceMapManager, workspace);
-
-    /** @type {!Multimap<!SDK.CSSStyleSheetHeader, !Bindings.CSSWorkspaceBinding.LiveLocation>} */
-    this._locations = new Multimap();
-    /** @type {!Multimap<string, !Bindings.CSSWorkspaceBinding.LiveLocation>} */
-    this._unboundLocations = new Multimap();
-  }
-
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   * @return {!Bindings.CSSWorkspaceBinding.LiveLocation}
-   */
-  _createLiveLocation(rawLocation, updateDelegate, locationPool) {
-    const location = new Bindings.CSSWorkspaceBinding.LiveLocation(rawLocation, this, updateDelegate, locationPool);
-    const header = rawLocation.header();
-    if (header) {
-      location._header = header;
-      this._locations.set(header, location);
-      location.update();
-    } else {
-      this._unboundLocations.set(rawLocation.url, location);
-    }
-    return location;
-  }
-
-  /**
-   * @param {!Bindings.CSSWorkspaceBinding.LiveLocation} location
-   */
-  _disposeLocation(location) {
-    if (location._header)
-      this._locations.delete(location._header, location);
-    else
-      this._unboundLocations.delete(location._url, location);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  _updateLocations(header) {
-    for (const location of this._locations.get(header))
-      location.update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _styleSheetAdded(event) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);
-    if (!header.sourceURL)
-      return;
-
-    for (const location of this._unboundLocations.get(header.sourceURL)) {
-      location._header = header;
-      this._locations.set(header, location);
-      location.update();
-    }
-    this._unboundLocations.deleteAll(header.sourceURL);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _styleSheetRemoved(event) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);
-    for (const location of this._locations.get(header)) {
-      location._header = null;
-      this._unboundLocations.set(location._url, location);
-      location.update();
-    }
-    this._locations.deleteAll(header);
-  }
-
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  _rawLocationToUILocation(rawLocation) {
-    let uiLocation = null;
-    uiLocation = uiLocation || this._sassSourceMapping.rawLocationToUILocation(rawLocation);
-    uiLocation = uiLocation || this._stylesSourceMapping.rawLocationToUILocation(rawLocation);
-    uiLocation = uiLocation || Bindings.resourceMapping.cssLocationToUILocation(rawLocation);
-    return uiLocation;
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  _uiLocationToRawLocations(uiLocation) {
-    const rawLocations = this._sassSourceMapping.uiLocationToRawLocations(uiLocation);
-    if (rawLocations.length)
-      return rawLocations;
-    return this._stylesSourceMapping.uiLocationToRawLocations(uiLocation);
-  }
-
-  _dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._stylesSourceMapping.dispose();
-    this._sassSourceMapping.dispose();
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.CSSWorkspaceBinding.LiveLocation = class extends Bindings.LiveLocationWithPool {
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @param {!Bindings.CSSWorkspaceBinding.ModelInfo} info
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   */
-  constructor(rawLocation, info, updateDelegate, locationPool) {
-    super(updateDelegate, locationPool);
-    this._url = rawLocation.url;
-    this._lineNumber = rawLocation.lineNumber;
-    this._columnNumber = rawLocation.columnNumber;
-    this._info = info;
-    this._header = null;
-  }
-
-  /**
-   * @override
-   * @return {?Workspace.UILocation}
-   */
-  uiLocation() {
-    if (!this._header)
-      return null;
-    const rawLocation = new SDK.CSSLocation(this._header, this._lineNumber, this._columnNumber);
-    return Bindings.cssWorkspaceBinding.rawLocationToUILocation(rawLocation);
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    super.dispose();
-    this._info._disposeLocation(this);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isBlackboxed() {
-    return false;
-  }
-};
-
-/**
- * @type {!Bindings.CSSWorkspaceBinding}
- */
-Bindings.cssWorkspaceBinding;
diff --git a/front_end/bindings/CompilerScriptMapping.js b/front_end/bindings/CompilerScriptMapping.js
deleted file mode 100644
index d484ae0..0000000
--- a/front_end/bindings/CompilerScriptMapping.js
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Bindings.DebuggerSourceMapping}
- * @unrestricted
- */
-Bindings.CompilerScriptMapping = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Workspace.Workspace} workspace
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(debuggerModel, workspace, debuggerWorkspaceBinding) {
-    this._debuggerModel = debuggerModel;
-    this._sourceMapManager = this._debuggerModel.sourceMapManager();
-    this._workspace = workspace;
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-
-    const target = debuggerModel.target();
-    this._regularProject = new Bindings.ContentProviderBasedProject(
-        workspace, 'jsSourceMaps::' + target.id(), Workspace.projectTypes.Network, '', false /* isServiceProject */);
-    this._contentScriptsProject = new Bindings.ContentProviderBasedProject(
-        workspace, 'jsSourceMaps:extensions:' + target.id(), Workspace.projectTypes.ContentScripts, '',
-        false /* isServiceProject */);
-    Bindings.NetworkProject.setTargetForProject(this._regularProject, target);
-    Bindings.NetworkProject.setTargetForProject(this._contentScriptsProject, target);
-
-    /** @type {!Map<string, !Bindings.CompilerScriptMapping.Binding>} */
-    this._regularBindings = new Map();
-    /** @type {!Map<string, !Bindings.CompilerScriptMapping.Binding>} */
-    this._contentScriptsBindings = new Map();
-
-    /** @type {!Map<!SDK.Script, !Workspace.UISourceCode>} */
-    this._stubUISourceCodes = new Map();
-
-    this._stubProject = new Bindings.ContentProviderBasedProject(
-        workspace, 'jsSourceMaps:stub:' + target.id(), Workspace.projectTypes.Service, '', true /* isServiceProject */);
-    this._eventListeners = [
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapWillAttach, this._sourceMapWillAttach, this),
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapFailedToAttach, this._sourceMapFailedToAttach, this),
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this),
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this),
-    ];
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  _addStubUISourceCode(script) {
-    const stubUISourceCode = this._stubProject.addContentProvider(
-        script.sourceURL + ':sourcemap',
-        Common.StaticContentProvider.fromString(
-            script.sourceURL, Common.resourceTypes.Script,
-            '\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!'),
-        'text/javascript');
-    this._stubUISourceCodes.set(script, stubUISourceCode);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  _removeStubUISourceCode(script) {
-    const uiSourceCode = this._stubUISourceCodes.get(script);
-    this._stubUISourceCodes.delete(script);
-    this._stubProject.removeFile(uiSourceCode.url());
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?string}
-   */
-  static uiSourceCodeOrigin(uiSourceCode) {
-    const sourceMap = uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol];
-    if (!sourceMap)
-      return null;
-    return sourceMap.compiledURL();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {boolean}
-   */
-  mapsToSourceCode(rawLocation) {
-    const script = rawLocation.script();
-    const sourceMap = script ? this._sourceMapManager.sourceMapForClient(script) : null;
-    if (!sourceMap)
-      return true;
-    return !!sourceMap.findEntry(rawLocation.lineNumber, rawLocation.columnNumber);
-  }
-
-  /**
-   * @param {string} url
-   * @param {boolean} isContentScript
-   */
-  uiSourceCodeForURL(url, isContentScript) {
-    return isContentScript ? this._contentScriptsProject.uiSourceCodeForURL(url) :
-                             this._regularProject.uiSourceCodeForURL(url);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const script = rawLocation.script();
-    if (!script)
-      return null;
-
-    const lineNumber = rawLocation.lineNumber - script.lineOffset;
-    let columnNumber = rawLocation.columnNumber;
-    if (!lineNumber)
-      columnNumber -= script.columnOffset;
-
-    const stubUISourceCode = this._stubUISourceCodes.get(script);
-    if (stubUISourceCode)
-      return new Workspace.UILocation(stubUISourceCode, lineNumber, columnNumber);
-
-    const sourceMap = this._sourceMapManager.sourceMapForClient(script);
-    if (!sourceMap)
-      return null;
-    const entry = sourceMap.findEntry(lineNumber, columnNumber);
-    if (!entry || !entry.sourceURL)
-      return null;
-    const uiSourceCode = script.isContentScript() ? this._contentScriptsProject.uiSourceCodeForURL(entry.sourceURL) :
-                                                    this._regularProject.uiSourceCodeForURL(entry.sourceURL);
-    if (!uiSourceCode)
-      return null;
-    return uiSourceCode.uiLocation(
-        /** @type {number} */ (entry.sourceLineNumber), /** @type {number} */ (entry.sourceColumnNumber));
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    const sourceMap = uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol];
-    if (!sourceMap)
-      return null;
-    const scripts = this._sourceMapManager.clientsForSourceMap(sourceMap);
-    const script = scripts.length ? scripts[0] : null;
-    if (!script)
-      return null;
-    const entry = sourceMap.sourceLineMapping(uiSourceCode.url(), lineNumber, columnNumber);
-    if (!entry)
-      return null;
-    return this._debuggerModel.createRawLocation(
-        script, entry.lineNumber + script.lineOffset,
-        !entry.lineNumber ? entry.columnNumber + script.columnOffset : entry.columnNumber);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapWillAttach(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-    // Create stub UISourceCode for the time source mapping is being loaded.
-    this._addStubUISourceCode(script);
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapFailedToAttach(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-    this._removeStubUISourceCode(script);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapAttached(event) {
-    const script = /** @type {!SDK.Script} */ (event.data.client);
-    const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
-    this._removeStubUISourceCode(script);
-
-    if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript()))
-      return;
-    Bindings.blackboxManager.sourceMapLoaded(script, sourceMap);
-
-    this._populateSourceMapSources(script, sourceMap);
-    this._sourceMapAttachedForTest(sourceMap);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapDetached(event) {
-    const script = /** @type {!SDK.Script} */ (event.data.client);
-    const frameId = script[Bindings.CompilerScriptMapping._frameIdSymbol];
-    const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
-    const bindings = script.isContentScript() ? this._contentScriptsBindings : this._regularBindings;
-    for (const sourceURL of sourceMap.sourceURLs()) {
-      const binding = bindings.get(sourceURL);
-      binding.removeSourceMap(sourceMap, frameId);
-      if (!binding._uiSourceCode)
-        bindings.delete(sourceURL);
-    }
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {?SDK.SourceMap}
-   */
-  sourceMapForScript(script) {
-    return this._sourceMapManager.sourceMapForClient(script);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  maybeLoadSourceMap(script) {
-    const sourceMap = this._sourceMapManager.sourceMapForClient(script);
-    if (!sourceMap)
-      return;
-    this._populateSourceMapSources(script, sourceMap);
-  }
-
-  /**
-   * @param {?SDK.SourceMap} sourceMap
-   */
-  _sourceMapAttachedForTest(sourceMap) {
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {!SDK.SourceMap} sourceMap
-   */
-  _populateSourceMapSources(script, sourceMap) {
-    const frameId = Bindings.frameIdForScript(script);
-    script[Bindings.CompilerScriptMapping._frameIdSymbol] = frameId;
-    const project = script.isContentScript() ? this._contentScriptsProject : this._regularProject;
-    const bindings = script.isContentScript() ? this._contentScriptsBindings : this._regularBindings;
-    for (const sourceURL of sourceMap.sourceURLs()) {
-      let binding = bindings.get(sourceURL);
-      if (!binding) {
-        binding = new Bindings.CompilerScriptMapping.Binding(project, sourceURL);
-        bindings.set(sourceURL, binding);
-      }
-      binding.addSourceMap(sourceMap, frameId);
-    }
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @return {boolean}
-   */
-  static uiLineHasMapping(uiSourceCode, lineNumber) {
-    const sourceMap = uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol];
-    if (!sourceMap)
-      return true;
-    return !!sourceMap.sourceLineMapping(uiSourceCode.url(), lineNumber, 0);
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._regularProject.dispose();
-    this._contentScriptsProject.dispose();
-    this._stubProject.dispose();
-  }
-};
-
-Bindings.CompilerScriptMapping._frameIdSymbol = Symbol('Bindings.CompilerScriptMapping._frameIdSymbol');
-Bindings.CompilerScriptMapping._sourceMapSymbol = Symbol('Bindings.CompilerScriptMapping._sourceMapSymbol');
-
-
-Bindings.CompilerScriptMapping.Binding = class {
-  /**
-   * @param {!Bindings.ContentProviderBasedProject} project
-   * @param {string} url
-   */
-  constructor(project, url) {
-    this._project = project;
-    this._url = url;
-
-    /** @type {!Array<!SDK.SourceMap>} */
-    this._referringSourceMaps = [];
-    this._activeSourceMap = null;
-    this._uiSourceCode = null;
-  }
-
-  /**
-   * @param {string} frameId
-   */
-  _recreateUISourceCodeIfNeeded(frameId) {
-    const sourceMap = this._referringSourceMaps.peekLast();
-    if (this._activeSourceMap === sourceMap)
-      return;
-    this._activeSourceMap = sourceMap;
-
-    const newUISourceCode = this._project.createUISourceCode(this._url, Common.resourceTypes.SourceMapScript);
-    newUISourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol] = sourceMap;
-    const contentProvider = sourceMap.sourceContentProvider(this._url, Common.resourceTypes.SourceMapScript);
-    const mimeType = Common.ResourceType.mimeFromURL(this._url) || 'text/javascript';
-    const embeddedContent = sourceMap.embeddedContentByURL(this._url);
-    const metadata =
-        typeof embeddedContent === 'string' ? new Workspace.UISourceCodeMetadata(null, embeddedContent.length) : null;
-
-    if (this._uiSourceCode) {
-      Bindings.NetworkProject.cloneInitialFrameAttribution(this._uiSourceCode, newUISourceCode);
-      this._project.removeFile(this._uiSourceCode.url());
-    } else {
-      Bindings.NetworkProject.setInitialFrameAttribution(newUISourceCode, frameId);
-    }
-    this._uiSourceCode = newUISourceCode;
-    this._project.addUISourceCodeWithProvider(this._uiSourceCode, contentProvider, metadata, mimeType);
-  }
-
-  /**
-   * @param {!SDK.SourceMap} sourceMap
-   * @param {string} frameId
-   */
-  addSourceMap(sourceMap, frameId) {
-    if (this._uiSourceCode)
-      Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode, frameId);
-    this._referringSourceMaps.push(sourceMap);
-    this._recreateUISourceCodeIfNeeded(frameId);
-  }
-
-  /**
-   * @param {!SDK.SourceMap} sourceMap
-   * @param {string} frameId
-   */
-  removeSourceMap(sourceMap, frameId) {
-    Bindings.NetworkProject.removeFrameAttribution(
-        /** @type {!Workspace.UISourceCode} */ (this._uiSourceCode), frameId);
-    const lastIndex = this._referringSourceMaps.lastIndexOf(sourceMap);
-    if (lastIndex !== -1)
-      this._referringSourceMaps.splice(lastIndex, 1);
-    if (!this._referringSourceMaps.length) {
-      this._project.removeFile(this._uiSourceCode.url());
-      this._uiSourceCode = null;
-    } else {
-      this._recreateUISourceCodeIfNeeded(frameId);
-    }
-  }
-};
diff --git a/front_end/bindings/ContentProviderBasedProject.js b/front_end/bindings/ContentProviderBasedProject.js
deleted file mode 100644
index 97c5b71..0000000
--- a/front_end/bindings/ContentProviderBasedProject.js
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Workspace.Project}
- * @unrestricted
- */
-Bindings.ContentProviderBasedProject = class extends Workspace.ProjectStore {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {string} id
-   * @param {!Workspace.projectTypes} type
-   * @param {string} displayName
-   * @param {boolean} isServiceProject
-   */
-  constructor(workspace, id, type, displayName, isServiceProject) {
-    super(workspace, id, type, displayName);
-    /** @type {!Object.<string, !Common.ContentProvider>} */
-    this._contentProviders = {};
-    this._isServiceProject = isServiceProject;
-    workspace.addProject(this);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function(?string,boolean)} callback
-   */
-  requestFileContent(uiSourceCode, callback) {
-    const contentProvider = this._contentProviders[uiSourceCode.url()];
-    (async () => {
-      callback(await contentProvider.requestContent(), await contentProvider.contentEncoded());
-    })();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isServiceProject() {
-    return this._isServiceProject;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<?Workspace.UISourceCodeMetadata>}
-   */
-  requestMetadata(uiSourceCode) {
-    return Promise.resolve(uiSourceCode[Bindings.ContentProviderBasedProject._metadata]);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canSetFileContent() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newContent
-   * @param {boolean} isBase64
-   * @param {function(?string)} callback
-   */
-  setFileContent(uiSourceCode, newContent, isBase64, callback) {
-    callback(null);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  fullDisplayName(uiSourceCode) {
-    let parentPath = uiSourceCode.parentURL().replace(/^(?:https?|file)\:\/\//, '');
-    try {
-      parentPath = decodeURI(parentPath);
-    } catch (e) {
-    }
-    return parentPath + '/' + uiSourceCode.displayName(true);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  mimeType(uiSourceCode) {
-    return /** @type {string} */ (uiSourceCode[Bindings.ContentProviderBasedProject._mimeType]);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canRename() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newName
-   * @param {function(boolean, string=, string=, !Common.ResourceType=)} callback
-   */
-  rename(uiSourceCode, newName, callback) {
-    const path = uiSourceCode.url();
-    this.performRename(path, newName, innerCallback.bind(this));
-
-    /**
-     * @param {boolean} success
-     * @param {string=} newName
-     * @this {Bindings.ContentProviderBasedProject}
-     */
-    function innerCallback(success, newName) {
-      if (success && newName) {
-        const copyOfPath = path.split('/');
-        copyOfPath[copyOfPath.length - 1] = newName;
-        const newPath = copyOfPath.join('/');
-        this._contentProviders[newPath] = this._contentProviders[path];
-        delete this._contentProviders[path];
-        this.renameUISourceCode(uiSourceCode, newName);
-      }
-      callback(success, newName);
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} path
-   */
-  excludeFolder(path) {
-  }
-
-  /**
-   * @override
-   * @param {string} path
-   * @return {boolean}
-   */
-  canExcludeFolder(path) {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {string} path
-   * @param {?string} name
-   * @param {string} content
-   * @param {boolean=} isBase64
-   * @return {!Promise<?Workspace.UISourceCode>}
-   */
-  createFile(path, name, content, isBase64) {
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canCreateFile() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  deleteFile(uiSourceCode) {
-  }
-
-  /**
-   * @override
-   */
-  remove() {
-  }
-
-  /**
-   * @param {string} path
-   * @param {string} newName
-   * @param {function(boolean, string=)} callback
-   */
-  performRename(path, newName, callback) {
-    callback(false);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInFileContent(uiSourceCode, query, caseSensitive, isRegex) {
-    const contentProvider = this._contentProviders[uiSourceCode.url()];
-    return contentProvider.searchInContent(query, caseSensitive, isRegex);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.ProjectSearchConfig} searchConfig
-   * @param {!Array<string>} filesMathingFileQuery
-   * @param {!Common.Progress} progress
-   * @return {!Promise<!Array<string>>}
-   */
-  async findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, progress) {
-    const result = [];
-    progress.setTotalWork(filesMathingFileQuery.length);
-    await Promise.all(filesMathingFileQuery.map(searchInContent.bind(this)));
-    progress.done();
-    return result;
-
-    /**
-     * @param {string} path
-     * @this {Bindings.ContentProviderBasedProject}
-     */
-    async function searchInContent(path) {
-      const provider = this._contentProviders[path];
-      let allMatchesFound = true;
-      for (const query of searchConfig.queries().slice()) {
-        const searchMatches = await provider.searchInContent(query, !searchConfig.ignoreCase(), searchConfig.isRegex());
-        if (!searchMatches.length) {
-          allMatchesFound = false;
-          break;
-        }
-      }
-      if (allMatchesFound)
-        result.push(path);
-      progress.worked(1);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Common.Progress} progress
-   */
-  indexContent(progress) {
-    setImmediate(progress.done.bind(progress));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {?Workspace.UISourceCodeMetadata} metadata
-   * @param {string} mimeType
-   */
-  addUISourceCodeWithProvider(uiSourceCode, contentProvider, metadata, mimeType) {
-    uiSourceCode[Bindings.ContentProviderBasedProject._mimeType] = mimeType;
-    this._contentProviders[uiSourceCode.url()] = contentProvider;
-    uiSourceCode[Bindings.ContentProviderBasedProject._metadata] = metadata;
-    this.addUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @param {string} url
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {string} mimeType
-   * @return {!Workspace.UISourceCode}
-   */
-  addContentProvider(url, contentProvider, mimeType) {
-    const uiSourceCode = this.createUISourceCode(url, contentProvider.contentType());
-    this.addUISourceCodeWithProvider(uiSourceCode, contentProvider, null, mimeType);
-    return uiSourceCode;
-  }
-
-  /**
-   * @param {string} path
-   */
-  removeFile(path) {
-    delete this._contentProviders[path];
-    this.removeUISourceCode(path);
-  }
-
-  reset() {
-    this._contentProviders = {};
-    this.removeProject();
-    this.workspace().addProject(this);
-  }
-
-  dispose() {
-    this._contentProviders = {};
-    this.removeProject();
-  }
-};
-
-Bindings.ContentProviderBasedProject._metadata = Symbol('ContentProviderBasedProject.Metadata');
-Bindings.ContentProviderBasedProject._mimeType = Symbol('Bindings.ContentProviderBasedProject._mimeType');
diff --git a/front_end/bindings/DebuggerWorkspaceBinding.js b/front_end/bindings/DebuggerWorkspaceBinding.js
deleted file mode 100644
index 8b971eb..0000000
--- a/front_end/bindings/DebuggerWorkspaceBinding.js
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- */
-Bindings.DebuggerWorkspaceBinding = class {
-  /**
-   * @param {!SDK.TargetManager} targetManager
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(targetManager, workspace) {
-    this._workspace = workspace;
-
-    /** @type {!Array<!Bindings.DebuggerSourceMapping>} */
-    this._sourceMappings = [];
-
-    /** @type {!Map.<!SDK.DebuggerModel, !Bindings.DebuggerWorkspaceBinding.ModelData>} */
-    this._debuggerModelToData = new Map();
-    targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
-    targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
-    targetManager.observeModels(SDK.DebuggerModel, this);
-  }
-
-  /**
-   * @param {!Bindings.DebuggerSourceMapping} sourceMapping
-   */
-  addSourceMapping(sourceMapping) {
-    this._sourceMappings.push(sourceMapping);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelAdded(debuggerModel) {
-    this._debuggerModelToData.set(debuggerModel, new Bindings.DebuggerWorkspaceBinding.ModelData(debuggerModel, this));
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    const modelData = this._debuggerModelToData.get(debuggerModel);
-    modelData._dispose();
-    this._debuggerModelToData.remove(debuggerModel);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  updateLocations(script) {
-    const modelData = this._debuggerModelToData.get(script.debuggerModel);
-    if (modelData)
-      modelData._updateLocations(script);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   * @return {!Bindings.DebuggerWorkspaceBinding.Location}
-   */
-  createLiveLocation(rawLocation, updateDelegate, locationPool) {
-    const modelData = this._debuggerModelToData.get(rawLocation.script().debuggerModel);
-    return modelData._createLiveLocation(rawLocation, updateDelegate, locationPool);
-  }
-
-  /**
-   * @param {!Array<!SDK.DebuggerModel.Location>} rawLocations
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   * @return {!Bindings.LiveLocation}
-   */
-  createStackTraceTopFrameLiveLocation(rawLocations, updateDelegate, locationPool) {
-    console.assert(rawLocations.length);
-    const location = new Bindings.DebuggerWorkspaceBinding.StackTraceTopFrameLocation(
-        rawLocations, this, updateDelegate, locationPool);
-    location.update();
-    return location;
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} location
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   * @return {?Bindings.DebuggerWorkspaceBinding.Location}
-   */
-  createCallFrameLiveLocation(location, updateDelegate, locationPool) {
-    const script = location.script();
-    if (!script)
-      return null;
-    const debuggerModel = location.debuggerModel;
-    const liveLocation = this.createLiveLocation(location, updateDelegate, locationPool);
-    this._registerCallFrameLiveLocation(debuggerModel, liveLocation);
-    return liveLocation;
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    for (let i = 0; i < this._sourceMappings.length; ++i) {
-      const uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
-      if (uiLocation)
-        return uiLocation;
-    }
-    const modelData = this._debuggerModelToData.get(rawLocation.debuggerModel);
-    return modelData._rawLocationToUILocation(rawLocation);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {string} url
-   * @param {boolean} isContentScript
-   */
-  uiSourceCodeForSourceMapSourceURL(debuggerModel, url, isContentScript) {
-    const modelData = this._debuggerModelToData.get(debuggerModel);
-    if (!modelData)
-      return null;
-    return modelData._compilerMapping.uiSourceCodeForURL(url, isContentScript);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    for (let i = 0; i < this._sourceMappings.length; ++i) {
-      const rawLocation = this._sourceMappings[i].uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-      if (rawLocation)
-        return rawLocation;
-    }
-
-    for (const modelData of this._debuggerModelToData.values()) {
-      const rawLocation = modelData._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-      if (rawLocation)
-        return rawLocation;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Workspace.UILocation}
-   */
-  normalizeUILocation(uiLocation) {
-    const rawLocation =
-        this.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
-    if (rawLocation)
-      return this.rawLocationToUILocation(rawLocation) || uiLocation;
-    return uiLocation;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @return {?Bindings.ResourceScriptFile}
-   */
-  scriptFile(uiSourceCode, debuggerModel) {
-    const modelData = this._debuggerModelToData.get(debuggerModel);
-    return modelData ? modelData._resourceMapping.scriptFile(uiSourceCode) : null;
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {?SDK.SourceMap}
-   */
-  sourceMapForScript(script) {
-    const modelData = this._debuggerModelToData.get(script.debuggerModel);
-    if (!modelData)
-      return null;
-    return modelData._compilerMapping.sourceMapForScript(script);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  maybeLoadSourceMap(script) {
-    const modelData = this._debuggerModelToData.get(script.debuggerModel);
-    if (!modelData)
-      return;
-    modelData._compilerMapping.maybeLoadSourceMap(script);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _globalObjectCleared(event) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    this._reset(debuggerModel);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _reset(debuggerModel) {
-    const modelData = this._debuggerModelToData.get(debuggerModel);
-    modelData.callFrameLocations.valuesArray().forEach(location => this._removeLiveLocation(location));
-    modelData.callFrameLocations.clear();
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  _resetForTest(target) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (target.model(SDK.DebuggerModel));
-    const modelData = this._debuggerModelToData.get(debuggerModel);
-    modelData._resourceMapping.resetForTest();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Bindings.DebuggerWorkspaceBinding.Location} location
-   */
-  _registerCallFrameLiveLocation(debuggerModel, location) {
-    const locations = this._debuggerModelToData.get(debuggerModel).callFrameLocations;
-    locations.add(location);
-  }
-
-  /**
-   * @param {!Bindings.DebuggerWorkspaceBinding.Location} location
-   */
-  _removeLiveLocation(location) {
-    const modelData = this._debuggerModelToData.get(location._script.debuggerModel);
-    if (modelData)
-      modelData._disposeLocation(location);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _debuggerResumed(event) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    this._reset(debuggerModel);
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.DebuggerWorkspaceBinding.ModelData = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(debuggerModel, debuggerWorkspaceBinding) {
-    this._debuggerModel = debuggerModel;
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-
-    /** @type {!Set.<!Bindings.DebuggerWorkspaceBinding.Location>} */
-    this.callFrameLocations = new Set();
-
-    const workspace = debuggerWorkspaceBinding._workspace;
-
-    this._defaultMapping = new Bindings.DefaultScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
-    this._resourceMapping = new Bindings.ResourceScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
-    this._compilerMapping = new Bindings.CompilerScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
-
-    /** @type {!Multimap<!SDK.Script, !Bindings.DebuggerWorkspaceBinding.Location>} */
-    this._locations = new Multimap();
-
-    debuggerModel.setBeforePausedCallback(this._beforePaused.bind(this));
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   * @return {!Bindings.DebuggerWorkspaceBinding.Location}
-   */
-  _createLiveLocation(rawLocation, updateDelegate, locationPool) {
-    const script = /** @type {!SDK.Script} */ (rawLocation.script());
-    console.assert(script);
-    const location = new Bindings.DebuggerWorkspaceBinding.Location(
-        script, rawLocation, this._debuggerWorkspaceBinding, updateDelegate, locationPool);
-    this._locations.set(script, location);
-    location.update();
-    return location;
-  }
-
-  /**
-   * @param {!Bindings.DebuggerWorkspaceBinding.Location} location
-   */
-  _disposeLocation(location) {
-    this._locations.delete(location._script, location);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  _updateLocations(script) {
-    for (const location of this._locations.get(script))
-      location.update();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  _rawLocationToUILocation(rawLocation) {
-    let uiLocation = null;
-    uiLocation = uiLocation || this._compilerMapping.rawLocationToUILocation(rawLocation);
-    uiLocation = uiLocation || this._resourceMapping.rawLocationToUILocation(rawLocation);
-    uiLocation = uiLocation || Bindings.resourceMapping.jsLocationToUILocation(rawLocation);
-    uiLocation = uiLocation || this._defaultMapping.rawLocationToUILocation(rawLocation);
-    return /** @type {!Workspace.UILocation} */ (uiLocation);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  _uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    let rawLocation = null;
-    rawLocation = rawLocation || this._compilerMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-    rawLocation = rawLocation || this._resourceMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-    rawLocation =
-        rawLocation || Bindings.resourceMapping.uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber);
-    rawLocation = rawLocation || this._defaultMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-    return rawLocation;
-  }
-
-  /**
-   * @param {!SDK.DebuggerPausedDetails} debuggerPausedDetails
-   * @return {boolean}
-   */
-  _beforePaused(debuggerPausedDetails) {
-    return !!this._compilerMapping.mapsToSourceCode(debuggerPausedDetails.callFrames[0].location());
-  }
-
-  _dispose() {
-    this._debuggerModel.setBeforePausedCallback(null);
-    this._compilerMapping.dispose();
-    this._resourceMapping.dispose();
-    this._defaultMapping.dispose();
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.DebuggerWorkspaceBinding.Location = class extends Bindings.LiveLocationWithPool {
-  /**
-   * @param {!SDK.Script} script
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @param {!Bindings.DebuggerWorkspaceBinding} binding
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   */
-  constructor(script, rawLocation, binding, updateDelegate, locationPool) {
-    super(updateDelegate, locationPool);
-    this._script = script;
-    this._rawLocation = rawLocation;
-    this._binding = binding;
-  }
-
-  /**
-   * @override
-   * @return {?Workspace.UILocation}
-   */
-  uiLocation() {
-    const debuggerModelLocation = this._rawLocation;
-    return this._binding.rawLocationToUILocation(debuggerModelLocation);
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    super.dispose();
-    this._binding._removeLiveLocation(this);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isBlackboxed() {
-    return Bindings.blackboxManager.isBlackboxedRawLocation(this._rawLocation);
-  }
-};
-
-Bindings.DebuggerWorkspaceBinding.StackTraceTopFrameLocation = class extends Bindings.LiveLocationWithPool {
-  /**
-   * @param {!Array<!SDK.DebuggerModel.Location>} rawLocations
-   * @param {!Bindings.DebuggerWorkspaceBinding} binding
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   */
-  constructor(rawLocations, binding, updateDelegate, locationPool) {
-    super(updateDelegate, locationPool);
-    this._updateScheduled = true;
-    this._current = null;
-    this._locations = rawLocations.map(
-        location => binding.createLiveLocation(location, this._scheduleUpdate.bind(this), locationPool));
-    this._updateLocation();
-  }
-
-  /**
-   * @override
-   * @return {?Workspace.UILocation}
-   */
-  uiLocation() {
-    return this._current.uiLocation();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isBlackboxed() {
-    return this._current.isBlackboxed();
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    super.dispose();
-    for (const location of this._locations)
-      location.dispose();
-    this._locations = null;
-    this._current = null;
-  }
-
-  _scheduleUpdate() {
-    if (this._updateScheduled)
-      return;
-    this._updateScheduled = true;
-    setImmediate(this._updateLocation.bind(this));
-  }
-
-  _updateLocation() {
-    this._updateScheduled = false;
-    if (!this._locations)
-      return;
-    this._current = this._locations.find(location => !location.isBlackboxed()) || this._locations[0];
-    this.update();
-  }
-};
-
-/**
- * @interface
- */
-Bindings.DebuggerSourceMapping = function() {};
-
-Bindings.DebuggerSourceMapping.prototype = {
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {},
-};
-
-/**
- * @type {!Bindings.DebuggerWorkspaceBinding}
- */
-Bindings.debuggerWorkspaceBinding;
diff --git a/front_end/bindings/DefaultScriptMapping.js b/front_end/bindings/DefaultScriptMapping.js
deleted file mode 100644
index dab1e80..0000000
--- a/front_end/bindings/DefaultScriptMapping.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Bindings.DebuggerSourceMapping}
- * @unrestricted
- */
-Bindings.DefaultScriptMapping = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Workspace.Workspace} workspace
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(debuggerModel, workspace, debuggerWorkspaceBinding) {
-    this._debuggerModel = debuggerModel;
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-    this._project = new Bindings.ContentProviderBasedProject(
-        workspace, 'debugger:' + debuggerModel.target().id(), Workspace.projectTypes.Debugger, '',
-        true /* isServiceProject */);
-    this._eventListeners = [
-      debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this),
-      debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this),
-      debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this),
-      debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this._discardedScriptSource, this)
-    ];
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?SDK.Script}
-   */
-  static scriptForUISourceCode(uiSourceCode) {
-    return uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol] || null;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const script = rawLocation.script();
-    if (!script)
-      return null;
-    const uiSourceCode = script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol];
-    const lineNumber = rawLocation.lineNumber - (script.isInlineScriptWithSourceURL() ? script.lineOffset : 0);
-    let columnNumber = rawLocation.columnNumber || 0;
-    if (script.isInlineScriptWithSourceURL() && !lineNumber && columnNumber)
-      columnNumber -= script.columnOffset;
-    return uiSourceCode.uiLocation(lineNumber, columnNumber);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    const script = uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol];
-    if (!script)
-      return null;
-    if (script.isInlineScriptWithSourceURL()) {
-      return this._debuggerModel.createRawLocation(
-          script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset);
-    }
-    return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _parsedScriptSource(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-    const name = Common.ParsedURL.extractName(script.sourceURL);
-    const url = 'debugger:///VM' + script.scriptId + (name ? ' ' + name : '');
-
-    const uiSourceCode = this._project.createUISourceCode(url, Common.resourceTypes.Script);
-    uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol] = script;
-    script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol] = uiSourceCode;
-    this._project.addUISourceCodeWithProvider(uiSourceCode, script, null, 'text/javascript');
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _discardedScriptSource(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-    const uiSourceCode = script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol];
-    if (!uiSourceCode)
-      return;
-    delete script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol];
-    delete uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol];
-    this._project.removeUISourceCode(uiSourceCode.url());
-  }
-
-  _debuggerReset() {
-    this._project.reset();
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._debuggerReset();
-    this._project.dispose();
-  }
-};
-
-Bindings.DefaultScriptMapping._scriptSymbol = Symbol('symbol');
-Bindings.DefaultScriptMapping._uiSourceCodeSymbol = Symbol('uiSourceCodeSymbol');
diff --git a/front_end/bindings/FileUtils.js b/front_end/bindings/FileUtils.js
deleted file mode 100644
index 0afebe5..0000000
--- a/front_end/bindings/FileUtils.js
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @interface
- */
-Bindings.ChunkedReader = function() {};
-
-Bindings.ChunkedReader.prototype = {
-  /**
-   * @return {number}
-   */
-  fileSize() {},
-
-  /**
-   * @return {number}
-   */
-  loadedSize() {},
-
-  /**
-   * @return {string}
-   */
-  fileName() {},
-
-  cancel() {},
-
-  /**
-   * @return {?FileError}
-   */
-  error() {}
-};
-
-/**
- * @implements {Bindings.ChunkedReader}
- * @unrestricted
- */
-Bindings.ChunkedFileReader = class {
-  /**
-   * @param {!Blob} blob
-   * @param {number} chunkSize
-   * @param {function(!Bindings.ChunkedReader)=} chunkTransferredCallback
-   */
-  constructor(blob, chunkSize, chunkTransferredCallback) {
-    this._file = blob;
-    this._fileSize = blob.size;
-    this._loadedSize = 0;
-    this._chunkSize = chunkSize;
-    this._chunkTransferredCallback = chunkTransferredCallback;
-    this._decoder = new TextDecoder();
-    this._isCanceled = false;
-    /** @type {?FileError} */
-    this._error = null;
-  }
-
-  /**
-   * @param {!Common.OutputStream} output
-   * @return {!Promise<boolean>}
-   */
-  read(output) {
-    if (this._chunkTransferredCallback)
-      this._chunkTransferredCallback(this);
-    this._output = output;
-    this._reader = new FileReader();
-    this._reader.onload = this._onChunkLoaded.bind(this);
-    this._reader.onerror = this._onError.bind(this);
-    this._loadChunk();
-    return new Promise(resolve => this._transferFinished = resolve);
-  }
-
-  /**
-   * @override
-   */
-  cancel() {
-    this._isCanceled = true;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  loadedSize() {
-    return this._loadedSize;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  fileSize() {
-    return this._fileSize;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  fileName() {
-    return this._file.name;
-  }
-
-  /**
-   * @override
-   * @return {?FileError}
-   */
-  error() {
-    return this._error;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onChunkLoaded(event) {
-    if (this._isCanceled)
-      return;
-
-    if (event.target.readyState !== FileReader.DONE)
-      return;
-
-    const buffer = event.target.result;
-    this._loadedSize += buffer.byteLength;
-    const endOfFile = this._loadedSize === this._fileSize;
-    const decodedString = this._decoder.decode(buffer, {stream: !endOfFile});
-    this._output.write(decodedString);
-    if (this._isCanceled)
-      return;
-    if (this._chunkTransferredCallback)
-      this._chunkTransferredCallback(this);
-
-    if (endOfFile) {
-      this._file = null;
-      this._reader = null;
-      this._output.close();
-      this._transferFinished(!this._error);
-      return;
-    }
-
-    this._loadChunk();
-  }
-
-  _loadChunk() {
-    const chunkStart = this._loadedSize;
-    const chunkEnd = Math.min(this._fileSize, chunkStart + this._chunkSize);
-    const nextPart = this._file.slice(chunkStart, chunkEnd);
-    this._reader.readAsArrayBuffer(nextPart);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onError(event) {
-    this._error = event.target.error;
-    this._transferFinished(false);
-  }
-};
-
-/**
- * @implements {Common.OutputStream}
- * @unrestricted
- */
-Bindings.FileOutputStream = class {
-  /**
-   * @param {string} fileName
-   * @return {!Promise<boolean>}
-   */
-  async open(fileName) {
-    this._closed = false;
-    /** @type {!Array<function()>} */
-    this._writeCallbacks = [];
-    this._fileName = fileName;
-    const saveResponse = await Workspace.fileManager.save(this._fileName, '', true);
-    if (saveResponse)
-      Workspace.fileManager.addEventListener(Workspace.FileManager.Events.AppendedToURL, this._onAppendDone, this);
-    return !!saveResponse;
-  }
-
-  /**
-   * @override
-   * @param {string} data
-   * @return {!Promise}
-   */
-  write(data) {
-    return new Promise(resolve => {
-      this._writeCallbacks.push(resolve);
-      Workspace.fileManager.append(this._fileName, data);
-    });
-  }
-
-  /**
-   * @override
-   */
-  close() {
-    this._closed = true;
-    if (this._writeCallbacks.length)
-      return;
-    Workspace.fileManager.removeEventListener(Workspace.FileManager.Events.AppendedToURL, this._onAppendDone, this);
-    Workspace.fileManager.close(this._fileName);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onAppendDone(event) {
-    if (event.data !== this._fileName)
-      return;
-    this._writeCallbacks.shift()();
-    if (this._writeCallbacks.length)
-      return;
-    if (!this._closed)
-      return;
-    Workspace.fileManager.removeEventListener(Workspace.FileManager.Events.AppendedToURL, this._onAppendDone, this);
-    Workspace.fileManager.close(this._fileName);
-  }
-};
diff --git a/front_end/bindings/LiveLocation.js b/front_end/bindings/LiveLocation.js
deleted file mode 100644
index d4b13f7..0000000
--- a/front_end/bindings/LiveLocation.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/** @interface */
-Bindings.LiveLocation = function() {};
-
-Bindings.LiveLocation.prototype = {
-  update() {},
-
-  /**
-   * @return {?Workspace.UILocation}
-   */
-  uiLocation() {},
-
-  dispose() {},
-
-  /**
-   * @return {boolean}
-   */
-  isBlackboxed() {}
-};
-
-/**
- * @implements {Bindings.LiveLocation}
- * @unrestricted
- */
-Bindings.LiveLocationWithPool = class {
-  /**
-   * @param {function(!Bindings.LiveLocation)} updateDelegate
-   * @param {!Bindings.LiveLocationPool} locationPool
-   */
-  constructor(updateDelegate, locationPool) {
-    this._updateDelegate = updateDelegate;
-    this._locationPool = locationPool;
-    this._locationPool._add(this);
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    this._updateDelegate(this);
-  }
-
-  /**
-   * @override
-   * @return {?Workspace.UILocation}
-   */
-  uiLocation() {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this._locationPool._delete(this);
-    this._updateDelegate = null;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isBlackboxed() {
-    throw 'Not implemented';
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.LiveLocationPool = class {
-  constructor() {
-    this._locations = new Set();
-  }
-
-  /**
-   * @param {!Bindings.LiveLocation} location
-   */
-  _add(location) {
-    this._locations.add(location);
-  }
-
-  /**
-   * @param {!Bindings.LiveLocation} location
-   */
-  _delete(location) {
-    this._locations.delete(location);
-  }
-
-  disposeAll() {
-    for (const location of this._locations)
-      location.dispose();
-  }
-};
diff --git a/front_end/bindings/NetworkProject.js b/front_end/bindings/NetworkProject.js
deleted file mode 100644
index 50c7d67..0000000
--- a/front_end/bindings/NetworkProject.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-Bindings.NetworkProjectManager = class extends Common.Object {
-};
-
-Bindings.NetworkProjectManager.Events = {
-  FrameAttributionAdded: Symbol('FrameAttributionAdded'),
-  FrameAttributionRemoved: Symbol('FrameAttributionRemoved')
-};
-
-/**
- * @unrestricted
- */
-Bindings.NetworkProject = class {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} frameId
-   */
-  static _resolveFrame(uiSourceCode, frameId) {
-    const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-    const resourceTreeModel = target && target.model(SDK.ResourceTreeModel);
-    return resourceTreeModel ? resourceTreeModel.frameForId(frameId) : null;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} frameId
-   */
-  static setInitialFrameAttribution(uiSourceCode, frameId) {
-    const frame = Bindings.NetworkProject._resolveFrame(uiSourceCode, frameId);
-    if (!frame)
-      return;
-    /** @type {!Map<string, !{frame: !SDK.ResourceTreeFrame, count: number}>} */
-    const attribution = new Map();
-    attribution.set(frameId, {frame: frame, count: 1});
-    uiSourceCode[Bindings.NetworkProject._frameAttributionSymbol] = attribution;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} fromUISourceCode
-   * @param {!Workspace.UISourceCode} toUISourceCode
-   */
-  static cloneInitialFrameAttribution(fromUISourceCode, toUISourceCode) {
-    const fromAttribution = fromUISourceCode[Bindings.NetworkProject._frameAttributionSymbol];
-    if (!fromAttribution)
-      return;
-    /** @type {!Map<string, !{frame: !SDK.ResourceTreeFrame, count: number}>} */
-    const toAttribution = new Map();
-    toUISourceCode[Bindings.NetworkProject._frameAttributionSymbol] = toAttribution;
-    for (const frameId of fromAttribution.keys()) {
-      const value = fromAttribution.get(frameId);
-      toAttribution.set(frameId, {frame: value.frame, count: value.count});
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} frameId
-   */
-  static addFrameAttribution(uiSourceCode, frameId) {
-    const frame = Bindings.NetworkProject._resolveFrame(uiSourceCode, frameId);
-    if (!frame)
-      return;
-    const frameAttribution = uiSourceCode[Bindings.NetworkProject._frameAttributionSymbol];
-    const attributionInfo = frameAttribution.get(frameId) || {frame: frame, count: 0};
-    attributionInfo.count += 1;
-    frameAttribution.set(frameId, attributionInfo);
-    if (attributionInfo.count !== 1)
-      return;
-
-    const data = {uiSourceCode: uiSourceCode, frame: frame};
-    Bindings.networkProjectManager.dispatchEventToListeners(
-        Bindings.NetworkProjectManager.Events.FrameAttributionAdded, data);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} frameId
-   */
-  static removeFrameAttribution(uiSourceCode, frameId) {
-    const frameAttribution = uiSourceCode[Bindings.NetworkProject._frameAttributionSymbol];
-    const attributionInfo = frameAttribution.get(frameId);
-    console.assert(attributionInfo, 'Failed to remove frame attribution for url: ' + uiSourceCode.url());
-    attributionInfo.count -= 1;
-    if (attributionInfo.count > 0)
-      return;
-    frameAttribution.delete(frameId);
-    const data = {uiSourceCode: uiSourceCode, frame: attributionInfo.frame};
-    Bindings.networkProjectManager.dispatchEventToListeners(
-        Bindings.NetworkProjectManager.Events.FrameAttributionRemoved, data);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?SDK.Target} target
-   */
-  static targetForUISourceCode(uiSourceCode) {
-    return uiSourceCode.project()[Bindings.NetworkProject._targetSymbol] || null;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {!SDK.Target} target
-   */
-  static setTargetForProject(project, target) {
-    project[Bindings.NetworkProject._targetSymbol] = target;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array<!SDK.ResourceTreeFrame>}
-   */
-  static framesForUISourceCode(uiSourceCode) {
-    const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-    const resourceTreeModel = target && target.model(SDK.ResourceTreeModel);
-    const attribution = uiSourceCode[Bindings.NetworkProject._frameAttributionSymbol];
-    if (!resourceTreeModel || !attribution)
-      return [];
-    const frames = Array.from(attribution.keys()).map(frameId => resourceTreeModel.frameForId(frameId));
-    return frames.filter(frame => !!frame);
-  }
-};
-
-Bindings.NetworkProject._targetSymbol = Symbol('target');
-Bindings.NetworkProject._frameAttributionSymbol = Symbol('Bindings.NetworkProject._frameAttributionSymbol');
diff --git a/front_end/bindings/PresentationConsoleMessageHelper.js b/front_end/bindings/PresentationConsoleMessageHelper.js
deleted file mode 100644
index f639ae6..0000000
--- a/front_end/bindings/PresentationConsoleMessageHelper.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- */
-Bindings.PresentationConsoleMessageManager = class {
-  constructor() {
-    SDK.targetManager.observeModels(SDK.DebuggerModel, this);
-
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
-    SDK.consoleModel.addEventListener(
-        SDK.ConsoleModel.Events.MessageAdded,
-        event => this._consoleMessageAdded(/** @type {!SDK.ConsoleMessage} */ (event.data)));
-    SDK.consoleModel.messages().forEach(this._consoleMessageAdded, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelAdded(debuggerModel) {
-    debuggerModel[Bindings.PresentationConsoleMessageManager._symbol] =
-        new Bindings.PresentationConsoleMessageHelper(debuggerModel);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    debuggerModel[Bindings.PresentationConsoleMessageManager._symbol]._consoleCleared();
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   */
-  _consoleMessageAdded(message) {
-    if (!message.isErrorOrWarning() || !message.runtimeModel() ||
-        message.source === SDK.ConsoleMessage.MessageSource.Violation)
-      return;
-    const debuggerModel = message.runtimeModel().debuggerModel();
-    debuggerModel[Bindings.PresentationConsoleMessageManager._symbol]._consoleMessageAdded(message);
-  }
-
-  _consoleCleared() {
-    for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel))
-      debuggerModel[Bindings.PresentationConsoleMessageManager._symbol]._consoleCleared();
-  }
-};
-
-Bindings.PresentationConsoleMessageManager._symbol = Symbol('PresentationConsoleMessageHelper');
-
-Bindings.PresentationConsoleMessageHelper = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  constructor(debuggerModel) {
-    this._debuggerModel = debuggerModel;
-
-    /** @type {!Object.<string, !Array.<!SDK.ConsoleMessage>>} */
-    this._pendingConsoleMessages = {};
-
-    /** @type {!Array.<!Bindings.PresentationConsoleMessage>} */
-    this._presentationConsoleMessages = [];
-
-    // TODO(dgozman): setImmediate because we race with DebuggerWorkspaceBinding on ParsedScriptSource event delivery.
-    debuggerModel.addEventListener(
-        SDK.DebuggerModel.Events.ParsedScriptSource, event => setImmediate(this._parsedScriptSource.bind(this, event)));
-    debuggerModel.addEventListener(
-        SDK.DebuggerModel.Events.FailedToParseScriptSource,
-        event => setImmediate(this._parsedScriptSource.bind(this, event)));
-    debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
-
-    this._locationPool = new Bindings.LiveLocationPool();
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   */
-  _consoleMessageAdded(message) {
-    const rawLocation = this._rawLocation(message);
-    if (rawLocation)
-      this._addConsoleMessageToScript(message, rawLocation);
-    else
-      this._addPendingConsoleMessage(message);
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  _rawLocation(message) {
-    if (message.scriptId)
-      return this._debuggerModel.createRawLocationByScriptId(message.scriptId, message.line, message.column);
-    const callFrame = message.stackTrace && message.stackTrace.callFrames ? message.stackTrace.callFrames[0] : null;
-    if (callFrame) {
-      return this._debuggerModel.createRawLocationByScriptId(
-          callFrame.scriptId, callFrame.lineNumber, callFrame.columnNumber);
-    }
-    if (message.url)
-      return this._debuggerModel.createRawLocationByURL(message.url, message.line, message.column);
-    return null;
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   */
-  _addConsoleMessageToScript(message, rawLocation) {
-    this._presentationConsoleMessages.push(
-        new Bindings.PresentationConsoleMessage(message, rawLocation, this._locationPool));
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   */
-  _addPendingConsoleMessage(message) {
-    if (!message.url)
-      return;
-    if (!this._pendingConsoleMessages[message.url])
-      this._pendingConsoleMessages[message.url] = [];
-    this._pendingConsoleMessages[message.url].push(message);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _parsedScriptSource(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-
-    const messages = this._pendingConsoleMessages[script.sourceURL];
-    if (!messages)
-      return;
-
-    const pendingMessages = [];
-    for (let i = 0; i < messages.length; i++) {
-      const message = messages[i];
-      const rawLocation = this._rawLocation(message);
-      if (!rawLocation)
-        continue;
-      if (script.scriptId === rawLocation.scriptId)
-        this._addConsoleMessageToScript(message, rawLocation);
-      else
-        pendingMessages.push(message);
-    }
-
-    if (pendingMessages.length)
-      this._pendingConsoleMessages[script.sourceURL] = pendingMessages;
-    else
-      delete this._pendingConsoleMessages[script.sourceURL];
-  }
-
-  _consoleCleared() {
-    this._pendingConsoleMessages = {};
-    this._debuggerReset();
-  }
-
-  _debuggerReset() {
-    for (const message of this._presentationConsoleMessages)
-      message.dispose();
-    this._presentationConsoleMessages = [];
-    this._locationPool.disposeAll();
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.PresentationConsoleMessage = class {
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @param {!Bindings.LiveLocationPool} locationPool
-   */
-  constructor(message, rawLocation, locationPool) {
-    this._text = message.messageText;
-    this._level = message.level === SDK.ConsoleMessage.MessageLevel.Error ?
-        Workspace.UISourceCode.Message.Level.Error :
-        Workspace.UISourceCode.Message.Level.Warning;
-    Bindings.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this._updateLocation.bind(this), locationPool);
-  }
-
-  /**
-   * @param {!Bindings.LiveLocation} liveLocation
-   */
-  _updateLocation(liveLocation) {
-    if (this._uiMessage)
-      this._uiMessage.remove();
-    const uiLocation = liveLocation.uiLocation();
-    if (!uiLocation)
-      return;
-    this._uiMessage =
-        uiLocation.uiSourceCode.addLineMessage(this._level, this._text, uiLocation.lineNumber, uiLocation.columnNumber);
-  }
-
-  dispose() {
-    if (this._uiMessage)
-      this._uiMessage.remove();
-  }
-};
diff --git a/front_end/bindings/ResourceMapping.js b/front_end/bindings/ResourceMapping.js
deleted file mode 100644
index 2acdd12..0000000
--- a/front_end/bindings/ResourceMapping.js
+++ /dev/null
@@ -1,410 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.ResourceTreeModel>}
- */
-Bindings.ResourceMapping = class {
-  /**
-   * @param {!SDK.TargetManager} targetManager
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(targetManager, workspace) {
-    this._workspace = workspace;
-    /** @type {!Map<!SDK.ResourceTreeModel, !Bindings.ResourceMapping.ModelInfo>} */
-    this._modelToInfo = new Map();
-    targetManager.observeModels(SDK.ResourceTreeModel, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  modelAdded(resourceTreeModel) {
-    const info = new Bindings.ResourceMapping.ModelInfo(this._workspace, resourceTreeModel);
-    this._modelToInfo.set(resourceTreeModel, info);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  modelRemoved(resourceTreeModel) {
-    const info = this._modelToInfo.get(resourceTreeModel);
-    info.dispose();
-    this._modelToInfo.delete(resourceTreeModel);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @return {?Bindings.ResourceMapping.ModelInfo}
-   */
-  _infoForTarget(target) {
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    return resourceTreeModel ? this._modelToInfo.get(resourceTreeModel) : null;
-  }
-
-  /**
-   * @param {!SDK.CSSLocation} cssLocation
-   * @return {?Workspace.UILocation}
-   */
-  cssLocationToUILocation(cssLocation) {
-    const header = cssLocation.header();
-    if (!header)
-      return null;
-    const info = this._infoForTarget(cssLocation.cssModel().target());
-    if (!info)
-      return null;
-    const uiSourceCode = info._project.uiSourceCodeForURL(cssLocation.url);
-    if (!uiSourceCode)
-      return null;
-    const offset = header[Bindings.ResourceMapping._offsetSymbol] ||
-        TextUtils.TextRange.createFromLocation(header.startLine, header.startColumn);
-    const lineNumber = cssLocation.lineNumber + offset.startLine - header.startLine;
-    let columnNumber = cssLocation.columnNumber;
-    if (cssLocation.lineNumber === header.startLine)
-      columnNumber += offset.startColumn - header.startColumn;
-    return uiSourceCode.uiLocation(lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} jsLocation
-   * @return {?Workspace.UILocation}
-   */
-  jsLocationToUILocation(jsLocation) {
-    const script = jsLocation.script();
-    if (!script)
-      return null;
-    const info = this._infoForTarget(jsLocation.debuggerModel.target());
-    if (!info)
-      return null;
-    const uiSourceCode = info._project.uiSourceCodeForURL(script.sourceURL);
-    if (!uiSourceCode)
-      return null;
-    const offset = script[Bindings.ResourceMapping._offsetSymbol] ||
-        TextUtils.TextRange.createFromLocation(script.lineOffset, script.columnOffset);
-    const lineNumber = jsLocation.lineNumber + offset.startLine - script.lineOffset;
-    let columnNumber = jsLocation.columnNumber;
-    if (jsLocation.lineNumber === script.lineOffset)
-      columnNumber += offset.startColumn - script.columnOffset;
-    return uiSourceCode.uiLocation(lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber) {
-    if (!uiSourceCode[Bindings.ResourceMapping._symbol])
-      return null;
-    const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-    if (!target)
-      return null;
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (!debuggerModel)
-      return null;
-    return debuggerModel.createRawLocationByURL(uiSourceCode.url(), lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  _resetForTest(target) {
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    const info = resourceTreeModel ? this._modelToInfo.get(resourceTreeModel) : null;
-    if (info)
-      info._resetForTest();
-  }
-};
-
-Bindings.ResourceMapping.ModelInfo = class {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  constructor(workspace, resourceTreeModel) {
-    const target = resourceTreeModel.target();
-    this._project = new Bindings.ContentProviderBasedProject(
-        workspace, 'resources:' + target.id(), Workspace.projectTypes.Network, '', false /* isServiceProject */);
-    Bindings.NetworkProject.setTargetForProject(this._project, target);
-
-    /** @type {!Map<string, !Bindings.ResourceMapping.Binding>} */
-    this._bindings = new Map();
-
-    const cssModel = target.model(SDK.CSSModel);
-    this._cssModel = cssModel;
-    this._eventListeners = [
-      resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.ResourceAdded, this._resourceAdded, this),
-      resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameWillNavigate, this._frameWillNavigate, this),
-      resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameDetached, this._frameDetached, this),
-      cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._styleSheetChanged, this)
-    ];
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _styleSheetChanged(event) {
-    const header = this._cssModel.styleSheetHeaderForId(event.data.styleSheetId);
-    if (!header || !header.isInline)
-      return;
-    const binding = this._bindings.get(header.resourceURL());
-    if (!binding)
-      return;
-    binding._styleSheetChanged(header, event.data.edit);
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  _acceptsResource(resource) {
-    const resourceType = resource.resourceType();
-    // Only load selected resource types from resources.
-    if (resourceType !== Common.resourceTypes.Image && resourceType !== Common.resourceTypes.Font &&
-        resourceType !== Common.resourceTypes.Document && resourceType !== Common.resourceTypes.Manifest)
-      return false;
-
-    // Ignore non-images and non-fonts.
-    if (resourceType === Common.resourceTypes.Image && resource.mimeType && !resource.mimeType.startsWith('image'))
-      return false;
-    if (resourceType === Common.resourceTypes.Font && resource.mimeType && !resource.mimeType.includes('font'))
-      return false;
-    if ((resourceType === Common.resourceTypes.Image || resourceType === Common.resourceTypes.Font) &&
-        resource.contentURL().startsWith('data:'))
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _resourceAdded(event) {
-    const resource = /** @type {!SDK.Resource} */ (event.data);
-    if (!this._acceptsResource(resource))
-      return;
-
-    let binding = this._bindings.get(resource.url);
-    if (!binding) {
-      binding = new Bindings.ResourceMapping.Binding(this._project, resource);
-      this._bindings.set(resource.url, binding);
-    } else {
-      binding.addResource(resource);
-    }
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _removeFrameResources(frame) {
-    for (const resource of frame.resources()) {
-      if (!this._acceptsResource(resource))
-        continue;
-      const binding = this._bindings.get(resource.url);
-      if (binding._resources.size === 1) {
-        binding.dispose();
-        this._bindings.delete(resource.url);
-      } else {
-        binding.removeResource(resource);
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameWillNavigate(event) {
-    const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    this._removeFrameResources(frame);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameDetached(event) {
-    const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    this._removeFrameResources(frame);
-  }
-
-  _resetForTest() {
-    for (const binding of this._bindings.valuesArray())
-      binding.dispose();
-    this._bindings.clear();
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    for (const binding of this._bindings.valuesArray())
-      binding.dispose();
-    this._bindings.clear();
-    this._project.removeProject();
-  }
-};
-
-/**
- * @implements {Common.ContentProvider}
- */
-Bindings.ResourceMapping.Binding = class {
-  /**
-   * @param {!Bindings.ContentProviderBasedProject} project
-   * @param {!SDK.Resource} resource
-   */
-  constructor(project, resource) {
-    this._resources = new Set([resource]);
-    this._project = project;
-    this._uiSourceCode = this._project.createUISourceCode(resource.url, resource.contentType());
-    this._uiSourceCode[Bindings.ResourceMapping._symbol] = true;
-    Bindings.NetworkProject.setInitialFrameAttribution(this._uiSourceCode, resource.frameId);
-    this._project.addUISourceCodeWithProvider(
-        this._uiSourceCode, this, Bindings.resourceMetadata(resource), resource.mimeType);
-    /** @type {!Array<{stylesheet: !SDK.CSSStyleSheetHeader, edit: !SDK.CSSModel.Edit}>} */
-    this._edits = [];
-  }
-
-  /**
-   * @return {!Array<!SDK.CSSStyleSheetHeader>}
-   */
-  _inlineStyles() {
-    const target = Bindings.NetworkProject.targetForUISourceCode(this._uiSourceCode);
-    const cssModel = target.model(SDK.CSSModel);
-    const stylesheets = [];
-    if (cssModel) {
-      for (const headerId of cssModel.styleSheetIdsForURL(this._uiSourceCode.url())) {
-        const header = cssModel.styleSheetHeaderForId(headerId);
-        if (header)
-          stylesheets.push(header);
-      }
-    }
-    return stylesheets;
-  }
-
-  /**
-   * @return {!Array<!SDK.Script>}
-   */
-  _inlineScripts() {
-    const target = Bindings.NetworkProject.targetForUISourceCode(this._uiSourceCode);
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (!debuggerModel)
-      return [];
-    return debuggerModel.scriptsForSourceURL(this._uiSourceCode.url());
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} stylesheet
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  async _styleSheetChanged(stylesheet, edit) {
-    this._edits.push({stylesheet, edit});
-    if (this._edits.length > 1)
-      return;  // There is already a _styleSheetChanged loop running
-
-    const content = await this._uiSourceCode.requestContent();
-    if (content !== null)
-      this._innerStyleSheetChanged(content);
-    this._edits = [];
-  }
-
-  /**
-   * @param {string} content
-   */
-  _innerStyleSheetChanged(content) {
-    const scripts = this._inlineScripts();
-    const styles = this._inlineStyles();
-    let text = new TextUtils.Text(content);
-    for (const data of this._edits) {
-      const edit = data.edit;
-      const stylesheet = data.stylesheet;
-      const startLocation = stylesheet[Bindings.ResourceMapping._offsetSymbol] ||
-          TextUtils.TextRange.createFromLocation(stylesheet.startLine, stylesheet.startColumn);
-
-      const oldRange = edit.oldRange.relativeFrom(startLocation.startLine, startLocation.startColumn);
-      const newRange = edit.newRange.relativeFrom(startLocation.startLine, startLocation.startColumn);
-      text = new TextUtils.Text(text.replaceRange(oldRange, edit.newText));
-      for (const script of scripts) {
-        const scriptOffset = script[Bindings.ResourceMapping._offsetSymbol] ||
-            TextUtils.TextRange.createFromLocation(script.lineOffset, script.columnOffset);
-        if (!scriptOffset.follows(oldRange))
-          continue;
-        script[Bindings.ResourceMapping._offsetSymbol] = scriptOffset.rebaseAfterTextEdit(oldRange, newRange);
-        Bindings.debuggerWorkspaceBinding.updateLocations(script);
-      }
-      for (const style of styles) {
-        const styleOffset = style[Bindings.ResourceMapping._offsetSymbol] ||
-            TextUtils.TextRange.createFromLocation(style.startLine, style.startColumn);
-        if (!styleOffset.follows(oldRange))
-          continue;
-        style[Bindings.ResourceMapping._offsetSymbol] = styleOffset.rebaseAfterTextEdit(oldRange, newRange);
-        Bindings.cssWorkspaceBinding.updateLocations(style);
-      }
-    }
-    this._uiSourceCode.addRevision(text.value());
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  addResource(resource) {
-    this._resources.add(resource);
-    Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode, resource.frameId);
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  removeResource(resource) {
-    this._resources.delete(resource);
-    Bindings.NetworkProject.removeFrameAttribution(this._uiSourceCode, resource.frameId);
-  }
-
-  dispose() {
-    this._project.removeFile(this._uiSourceCode.url());
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._resources.firstValue().contentURL();
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._resources.firstValue().contentType();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return this._resources.firstValue().contentEncoded();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    return this._resources.firstValue().requestContent();
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInContent(query, caseSensitive, isRegex) {
-    return this._resources.firstValue().searchInContent(query, caseSensitive, isRegex);
-  }
-};
-
-Bindings.ResourceMapping._symbol = Symbol('Bindings.ResourceMapping._symbol');
-Bindings.ResourceMapping._offsetSymbol = Symbol('Bindings.ResourceMapping._offsetSymbol');
\ No newline at end of file
diff --git a/front_end/bindings/ResourceScriptMapping.js b/front_end/bindings/ResourceScriptMapping.js
deleted file mode 100644
index f6eea9a..0000000
--- a/front_end/bindings/ResourceScriptMapping.js
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Bindings.DebuggerSourceMapping}
- * @unrestricted
- */
-Bindings.ResourceScriptMapping = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Workspace.Workspace} workspace
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   */
-  constructor(debuggerModel, workspace, debuggerWorkspaceBinding) {
-    this._debuggerModel = debuggerModel;
-    this._workspace = workspace;
-    this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
-    /** @type {!Map.<!Workspace.UISourceCode, !Bindings.ResourceScriptFile>} */
-    this._uiSourceCodeToScriptFile = new Map();
-
-    /** @type {!Map<string, !Bindings.ContentProviderBasedProject>} */
-    this._projects = new Map();
-
-    /** @type {!Set<!SDK.Script>} */
-    this._acceptedScripts = new Set();
-    const runtimeModel = debuggerModel.runtimeModel();
-    this._eventListeners = [
-      this._debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this),
-      this._debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this),
-      this._debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this),
-      runtimeModel.addEventListener(
-          SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._executionContextDestroyed, this),
-    ];
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {!Bindings.ContentProviderBasedProject}
-   */
-  _project(script) {
-    const frameId = script[Bindings.ResourceScriptMapping._frameIdSymbol];
-    const prefix = script.isContentScript() ? 'js:extensions:' : 'js::';
-    const projectId = prefix + this._debuggerModel.target().id() + ':' + frameId;
-    let project = this._projects.get(projectId);
-    if (!project) {
-      const projectType =
-          script.isContentScript() ? Workspace.projectTypes.ContentScripts : Workspace.projectTypes.Network;
-      project = new Bindings.ContentProviderBasedProject(
-          this._workspace, projectId, projectType, '' /* displayName */, false /* isServiceProject */);
-      Bindings.NetworkProject.setTargetForProject(project, this._debuggerModel.target());
-      this._projects.set(projectId, project);
-    }
-    return project;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const script = rawLocation.script();
-    if (!script)
-      return null;
-    const project = this._project(script);
-    const uiSourceCode = project.uiSourceCodeForURL(script.sourceURL);
-    if (!uiSourceCode)
-      return null;
-    const scriptFile = this._uiSourceCodeToScriptFile.get(uiSourceCode);
-    if (!scriptFile)
-      return null;
-    if ((scriptFile.hasDivergedFromVM() && !scriptFile.isMergingToVM()) || scriptFile.isDivergingFromVM())
-      return null;
-    if (!scriptFile._hasScripts([script]))
-      return null;
-    const lineNumber = rawLocation.lineNumber - (script.isInlineScriptWithSourceURL() ? script.lineOffset : 0);
-    let columnNumber = rawLocation.columnNumber || 0;
-    if (script.isInlineScriptWithSourceURL() && !lineNumber && columnNumber)
-      columnNumber -= script.columnOffset;
-    return uiSourceCode.uiLocation(lineNumber, columnNumber);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    const scriptFile = this._uiSourceCodeToScriptFile.get(uiSourceCode);
-    if (!scriptFile)
-      return null;
-    const script = scriptFile._script;
-    if (script.isInlineScriptWithSourceURL()) {
-      return this._debuggerModel.createRawLocation(
-          script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset);
-    }
-    return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @return {boolean}
-   */
-  _acceptsScript(script) {
-    if (!script.sourceURL || script.isLiveEdit() || (script.isInlineScript() && !script.hasSourceURL))
-      return false;
-    // Filter out embedder injected content scripts.
-    if (script.isContentScript() && !script.hasSourceURL) {
-      const parsedURL = new Common.ParsedURL(script.sourceURL);
-      if (!parsedURL.isValid)
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _parsedScriptSource(event) {
-    const script = /** @type {!SDK.Script} */ (event.data);
-    if (!this._acceptsScript(script))
-      return;
-    this._acceptedScripts.add(script);
-    const originalContentProvider = script.originalContentProvider();
-    const frameId = Bindings.frameIdForScript(script);
-    script[Bindings.ResourceScriptMapping._frameIdSymbol] = frameId;
-
-    const url = script.sourceURL;
-    const project = this._project(script);
-
-    // Remove previous UISourceCode, if any
-    const oldUISourceCode = project.uiSourceCodeForURL(url);
-    if (oldUISourceCode) {
-      const scriptFile = this._uiSourceCodeToScriptFile.get(oldUISourceCode);
-      this._removeScript(scriptFile._script);
-    }
-
-    // Create UISourceCode.
-    const uiSourceCode = project.createUISourceCode(url, originalContentProvider.contentType());
-    Bindings.NetworkProject.setInitialFrameAttribution(uiSourceCode, frameId);
-    const metadata = Bindings.metadataForURL(this._debuggerModel.target(), frameId, url);
-
-    // Bind UISourceCode to scripts.
-    const scriptFile = new Bindings.ResourceScriptFile(this, uiSourceCode, [script]);
-    this._uiSourceCodeToScriptFile.set(uiSourceCode, scriptFile);
-
-    project.addUISourceCodeWithProvider(uiSourceCode, originalContentProvider, metadata, 'text/javascript');
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?Bindings.ResourceScriptFile}
-   */
-  scriptFile(uiSourceCode) {
-    return this._uiSourceCodeToScriptFile.get(uiSourceCode) || null;
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  _removeScript(script) {
-    if (!this._acceptedScripts.has(script))
-      return;
-    this._acceptedScripts.delete(script);
-    const project = this._project(script);
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (project.uiSourceCodeForURL(script.sourceURL));
-    const scriptFile = this._uiSourceCodeToScriptFile.get(uiSourceCode);
-    scriptFile.dispose();
-    this._uiSourceCodeToScriptFile.delete(uiSourceCode);
-    project.removeFile(script.sourceURL);
-    this._debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _executionContextDestroyed(event) {
-    const executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
-    const scripts = this._debuggerModel.scriptsForExecutionContext(executionContext);
-    for (const script of scripts)
-      this._removeScript(script);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _globalObjectCleared(event) {
-    const scripts = Array.from(this._acceptedScripts);
-    for (const script of scripts)
-      this._removeScript(script);
-  }
-
-  resetForTest() {
-    const scripts = Array.from(this._acceptedScripts);
-    for (const script of scripts)
-      this._removeScript(script);
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    const scripts = Array.from(this._acceptedScripts);
-    for (const script of scripts)
-      this._removeScript(script);
-    for (const project of this._projects.values())
-      project.removeProject();
-    this._projects.clear();
-  }
-};
-
-/**
- * @unrestricted
- */
-Bindings.ResourceScriptFile = class extends Common.Object {
-  /**
-   * @param {!Bindings.ResourceScriptMapping} resourceScriptMapping
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Array.<!SDK.Script>} scripts
-   */
-  constructor(resourceScriptMapping, uiSourceCode, scripts) {
-    super();
-    console.assert(scripts.length);
-
-    this._resourceScriptMapping = resourceScriptMapping;
-    this._uiSourceCode = uiSourceCode;
-
-    if (this._uiSourceCode.contentType().isScript())
-      this._script = scripts[scripts.length - 1];
-
-    this._uiSourceCode.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
-    this._uiSourceCode.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-  }
-
-  /**
-   * @param {!Array.<!SDK.Script>} scripts
-   * @return {boolean}
-   */
-  _hasScripts(scripts) {
-    return this._script && this._script === scripts[0];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isDiverged() {
-    if (this._uiSourceCode.isDirty())
-      return true;
-    if (!this._script)
-      return false;
-    if (typeof this._scriptSource === 'undefined')
-      return false;
-    const workingCopy = this._uiSourceCode.workingCopy();
-    if (!workingCopy)
-      return false;
-
-    // Match ignoring sourceURL.
-    if (!workingCopy.startsWith(this._scriptSource.trimRight()))
-      return true;
-    const suffix = this._uiSourceCode.workingCopy().substr(this._scriptSource.length);
-    return !!suffix.length && !suffix.match(SDK.Script.sourceURLRegex);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyChanged(event) {
-    this._update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyCommitted(event) {
-    if (this._uiSourceCode.project().canSetFileContent())
-      return;
-    if (!this._script)
-      return;
-    const debuggerModel = this._resourceScriptMapping._debuggerModel;
-    const breakpoints = Bindings.breakpointManager.breakpointsForUISourceCode(this._uiSourceCode);
-    const source = this._uiSourceCode.workingCopy();
-    debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this));
-
-    /**
-     * @param {?string} error
-     * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
-     * @this {Bindings.ResourceScriptFile}
-     */
-    async function scriptSourceWasSet(error, exceptionDetails) {
-      if (!error && !exceptionDetails)
-        this._scriptSource = source;
-      this._update();
-
-      if (!error && !exceptionDetails) {
-        // Live edit can cause breakpoints to be in the wrong position, or to be lost altogether.
-        // If any breakpoints were in the pre-live edit script, they need to be re-added.
-        breakpoints.map(breakpoint => breakpoint.refreshInDebugger());
-        return;
-      }
-      if (!exceptionDetails) {
-        Common.console.addMessage(Common.UIString('LiveEdit failed: %s', error), Common.Console.MessageLevel.Warning);
-        return;
-      }
-      const messageText = Common.UIString('LiveEdit compile failed: %s', exceptionDetails.text);
-      this._uiSourceCode.addLineMessage(
-          Workspace.UISourceCode.Message.Level.Error, messageText, exceptionDetails.lineNumber,
-          exceptionDetails.columnNumber);
-    }
-  }
-
-  _update() {
-    if (this._isDiverged() && !this._hasDivergedFromVM)
-      this._divergeFromVM();
-    else if (!this._isDiverged() && this._hasDivergedFromVM)
-      this._mergeToVM();
-  }
-
-  _divergeFromVM() {
-    this._isDivergingFromVM = true;
-    this._resourceScriptMapping._debuggerWorkspaceBinding.updateLocations(this._script);
-    delete this._isDivergingFromVM;
-    this._hasDivergedFromVM = true;
-    this.dispatchEventToListeners(Bindings.ResourceScriptFile.Events.DidDivergeFromVM, this._uiSourceCode);
-  }
-
-  _mergeToVM() {
-    delete this._hasDivergedFromVM;
-    this._isMergingToVM = true;
-    this._resourceScriptMapping._debuggerWorkspaceBinding.updateLocations(this._script);
-    delete this._isMergingToVM;
-    this.dispatchEventToListeners(Bindings.ResourceScriptFile.Events.DidMergeToVM, this._uiSourceCode);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasDivergedFromVM() {
-    return this._hasDivergedFromVM;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDivergingFromVM() {
-    return this._isDivergingFromVM;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isMergingToVM() {
-    return this._isMergingToVM;
-  }
-
-  checkMapping() {
-    if (!this._script || typeof this._scriptSource !== 'undefined') {
-      this._mappingCheckedForTest();
-      return;
-    }
-    this._script.requestContent().then(callback.bind(this));
-
-    /**
-     * @param {?string} source
-     * @this {Bindings.ResourceScriptFile}
-     */
-    function callback(source) {
-      this._scriptSource = source;
-      this._update();
-      this._mappingCheckedForTest();
-    }
-  }
-
-  _mappingCheckedForTest() {
-  }
-
-  dispose() {
-    this._uiSourceCode.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
-    this._uiSourceCode.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-  }
-
-  /**
-   * @param {string} sourceMapURL
-   */
-  addSourceMapURL(sourceMapURL) {
-    if (!this._script)
-      return;
-    this._script.debuggerModel.setSourceMapURL(this._script, sourceMapURL);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasSourceMapURL() {
-    return this._script && !!this._script.sourceMapURL;
-  }
-};
-
-Bindings.ResourceScriptMapping._frameIdSymbol = Symbol('frameid');
-
-/** @enum {symbol} */
-Bindings.ResourceScriptFile.Events = {
-  DidMergeToVM: Symbol('DidMergeToVM'),
-  DidDivergeFromVM: Symbol('DidDivergeFromVM'),
-};
diff --git a/front_end/bindings/ResourceUtils.js b/front_end/bindings/ResourceUtils.js
deleted file mode 100644
index 917741b..0000000
--- a/front_end/bindings/ResourceUtils.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @param {string} url
- * @return {?SDK.Resource}
- */
-Bindings.resourceForURL = function(url) {
-  for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel)) {
-    const resource = resourceTreeModel.resourceForURL(url);
-    if (resource)
-      return resource;
-  }
-  return null;
-};
-
-/**
- * @param {function(!SDK.Resource)} callback
- */
-Bindings.forAllResources = function(callback) {
-  for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel))
-    resourceTreeModel.forAllResources(callback);
-};
-
-/**
- * @param {string} url
- * @return {string}
- */
-Bindings.displayNameForURL = function(url) {
-  if (!url)
-    return '';
-
-  const resource = Bindings.resourceForURL(url);
-  if (resource)
-    return resource.displayName;
-
-  const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
-  if (uiSourceCode)
-    return uiSourceCode.displayName();
-
-  const mainTarget = SDK.targetManager.mainTarget();
-  const inspectedURL = mainTarget && mainTarget.inspectedURL();
-  if (!inspectedURL)
-    return url.trimURL('');
-
-  const parsedURL = inspectedURL.asParsedURL();
-  const lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
-  const index = inspectedURL.indexOf(lastPathComponent);
-  if (index !== -1 && index + lastPathComponent.length === inspectedURL.length) {
-    const baseURL = inspectedURL.substring(0, index);
-    if (url.startsWith(baseURL))
-      return url.substring(index);
-  }
-
-  if (!parsedURL)
-    return url;
-
-  const displayName = url.trimURL(parsedURL.host);
-  return displayName === '/' ? parsedURL.host + '/' : displayName;
-};
-
-/**
- * @param {!SDK.Target} target
- * @param {string} frameId
- * @param {string} url
- * @return {?Workspace.UISourceCodeMetadata}
- */
-Bindings.metadataForURL = function(target, frameId, url) {
-  const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-  if (!resourceTreeModel)
-    return null;
-  const frame = resourceTreeModel.frameForId(frameId);
-  if (!frame)
-    return null;
-  return Bindings.resourceMetadata(frame.resourceForURL(url));
-};
-
-/**
- * @param {?SDK.Resource} resource
- * @return {?Workspace.UISourceCodeMetadata}
- */
-Bindings.resourceMetadata = function(resource) {
-  if (!resource || (typeof resource.contentSize() !== 'number' && !resource.lastModified()))
-    return null;
-  return new Workspace.UISourceCodeMetadata(resource.lastModified(), resource.contentSize());
-};
-
-/**
- * @param {!SDK.Script} script
- * @return {string}
- */
-Bindings.frameIdForScript = function(script) {
-  const executionContext = script.executionContext();
-  if (executionContext)
-    return executionContext.frameId || '';
-  // This is to overcome compilation cache which doesn't get reset.
-  const resourceTreeModel = script.debuggerModel.target().model(SDK.ResourceTreeModel);
-  if (!resourceTreeModel || !resourceTreeModel.mainFrame)
-    return '';
-  return resourceTreeModel.mainFrame.id;
-};
diff --git a/front_end/bindings/SASSSourceMapping.js b/front_end/bindings/SASSSourceMapping.js
deleted file mode 100644
index c106236..0000000
--- a/front_end/bindings/SASSSourceMapping.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Bindings.CSSWorkspaceBinding.SourceMapping}
- */
-Bindings.SASSSourceMapping = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {!SDK.SourceMapManager} sourceMapManager
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(target, sourceMapManager, workspace) {
-    this._sourceMapManager = sourceMapManager;
-    this._project = new Bindings.ContentProviderBasedProject(
-        workspace, 'cssSourceMaps:' + target.id(), Workspace.projectTypes.Network, '', false /* isServiceProject */);
-    Bindings.NetworkProject.setTargetForProject(this._project, target);
-
-    this._eventListeners = [
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this),
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this),
-      this._sourceMapManager.addEventListener(
-          SDK.SourceMapManager.Events.SourceMapChanged, this._sourceMapChanged, this)
-    ];
-  }
-
-  /**
-   * @param {?SDK.SourceMap} sourceMap
-   */
-  _sourceMapAttachedForTest(sourceMap) {
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapAttached(event) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data.client);
-    const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
-    for (const sassURL of sourceMap.sourceURLs()) {
-      let uiSourceCode = this._project.uiSourceCodeForURL(sassURL);
-      if (uiSourceCode) {
-        Bindings.NetworkProject.addFrameAttribution(uiSourceCode, header.frameId);
-        continue;
-      }
-
-      const contentProvider = sourceMap.sourceContentProvider(sassURL, Common.resourceTypes.SourceMapStyleSheet);
-      const mimeType = Common.ResourceType.mimeFromURL(sassURL) || contentProvider.contentType().canonicalMimeType();
-      const embeddedContent = sourceMap.embeddedContentByURL(sassURL);
-      const metadata =
-          typeof embeddedContent === 'string' ? new Workspace.UISourceCodeMetadata(null, embeddedContent.length) : null;
-      uiSourceCode = this._project.createUISourceCode(sassURL, contentProvider.contentType());
-      Bindings.NetworkProject.setInitialFrameAttribution(uiSourceCode, header.frameId);
-      uiSourceCode[Bindings.SASSSourceMapping._sourceMapSymbol] = sourceMap;
-      this._project.addUISourceCodeWithProvider(uiSourceCode, contentProvider, metadata, mimeType);
-    }
-    Bindings.cssWorkspaceBinding.updateLocations(header);
-    this._sourceMapAttachedForTest(sourceMap);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapDetached(event) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data.client);
-    const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
-    const headers = this._sourceMapManager.clientsForSourceMap(sourceMap);
-    for (const sassURL of sourceMap.sourceURLs()) {
-      if (headers.length) {
-        const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (this._project.uiSourceCodeForURL(sassURL));
-        Bindings.NetworkProject.removeFrameAttribution(uiSourceCode, header.frameId);
-      } else {
-        this._project.removeFile(sassURL);
-      }
-    }
-    Bindings.cssWorkspaceBinding.updateLocations(header);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _sourceMapChanged(event) {
-    const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
-    const newSources = /** @type {!Map<string, string>} */ (event.data.newSources);
-    const headers = this._sourceMapManager.clientsForSourceMap(sourceMap);
-    for (const sourceURL of newSources.keys()) {
-      const uiSourceCode = this._project.uiSourceCodeForURL(sourceURL);
-      if (!uiSourceCode) {
-        console.error('Failed to update source for ' + sourceURL);
-        continue;
-      }
-      const sassText = /** @type {string} */ (newSources.get(sourceURL));
-      uiSourceCode.setWorkingCopy(sassText);
-    }
-    for (const header of headers)
-      Bindings.cssWorkspaceBinding.updateLocations(header);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSLocation} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const header = rawLocation.header();
-    if (!header)
-      return null;
-    const sourceMap = this._sourceMapManager.sourceMapForClient(header);
-    if (!sourceMap)
-      return null;
-    const entry = sourceMap.findEntry(rawLocation.lineNumber, rawLocation.columnNumber);
-    if (!entry || !entry.sourceURL)
-      return null;
-    const uiSourceCode = this._project.uiSourceCodeForURL(entry.sourceURL);
-    if (!uiSourceCode)
-      return null;
-    return uiSourceCode.uiLocation(entry.sourceLineNumber || 0, entry.sourceColumnNumber);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  uiLocationToRawLocations(uiLocation) {
-    const sourceMap = uiLocation.uiSourceCode[Bindings.SASSSourceMapping._sourceMapSymbol];
-    if (!sourceMap)
-      return [];
-    const entries =
-        sourceMap.findReverseEntries(uiLocation.uiSourceCode.url(), uiLocation.lineNumber, uiLocation.columnNumber);
-    const locations = [];
-    for (const header of this._sourceMapManager.clientsForSourceMap(sourceMap))
-      locations.pushAll(entries.map(entry => new SDK.CSSLocation(header, entry.lineNumber, entry.columnNumber)));
-    return locations;
-  }
-
-  dispose() {
-    this._project.dispose();
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-  }
-};
-
-Bindings.SASSSourceMapping._sourceMapSymbol = Symbol('sourceMap');
diff --git a/front_end/bindings/StylesSourceMapping.js b/front_end/bindings/StylesSourceMapping.js
deleted file mode 100644
index 1b8877a..0000000
--- a/front_end/bindings/StylesSourceMapping.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Bindings.CSSWorkspaceBinding.SourceMapping}
- * @unrestricted
- */
-Bindings.StylesSourceMapping = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(cssModel, workspace) {
-    this._cssModel = cssModel;
-    const target = this._cssModel.target();
-    this._project = new Bindings.ContentProviderBasedProject(
-        workspace, 'css:' + target.id(), Workspace.projectTypes.Network, '', false /* isServiceProject */);
-    Bindings.NetworkProject.setTargetForProject(this._project, target);
-
-    /** @type {!Map.<string, !Bindings.StyleFile>} */
-    this._styleFiles = new Map();
-    this._eventListeners = [
-      this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._styleSheetAdded, this),
-      this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this),
-      this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._styleSheetChanged, this),
-    ];
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSLocation} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const header = rawLocation.header();
-    if (!header || !this._acceptsHeader(header))
-      return null;
-    const styleFile = this._styleFiles.get(header.resourceURL());
-    if (!styleFile)
-      return null;
-    let lineNumber = rawLocation.lineNumber;
-    let columnNumber = rawLocation.columnNumber;
-    if (header.isInline && header.hasSourceURL) {
-      lineNumber -= header.lineNumberInSource(0);
-      columnNumber -= header.columnNumberInSource(lineNumber, 0);
-    }
-    return styleFile._uiSourceCode.uiLocation(lineNumber, columnNumber);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  uiLocationToRawLocations(uiLocation) {
-    const styleFile = uiLocation.uiSourceCode[Bindings.StyleFile._symbol];
-    if (!styleFile)
-      return [];
-    const rawLocations = [];
-    for (const header of styleFile._headers) {
-      let lineNumber = uiLocation.lineNumber;
-      let columnNumber = uiLocation.columnNumber;
-      if (header.isInline && header.hasSourceURL) {
-        columnNumber = header.columnNumberInSource(lineNumber, columnNumber);
-        lineNumber = header.lineNumberInSource(lineNumber);
-      }
-      rawLocations.push(new SDK.CSSLocation(header, lineNumber, columnNumber));
-    }
-    return rawLocations;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  _acceptsHeader(header) {
-    if (header.isInline && !header.hasSourceURL && header.origin !== 'inspector')
-      return false;
-    if (!header.resourceURL())
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _styleSheetAdded(event) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);
-    if (!this._acceptsHeader(header))
-      return;
-
-    const url = header.resourceURL();
-    let styleFile = this._styleFiles.get(url);
-    if (!styleFile) {
-      styleFile = new Bindings.StyleFile(this._cssModel, this._project, header);
-      this._styleFiles.set(url, styleFile);
-    } else {
-      styleFile.addHeader(header);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _styleSheetRemoved(event) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);
-    if (!this._acceptsHeader(header))
-      return;
-    const url = header.resourceURL();
-    const styleFile = this._styleFiles.get(url);
-    if (styleFile._headers.size === 1) {
-      styleFile.dispose();
-      this._styleFiles.delete(url);
-    } else {
-      styleFile.removeHeader(header);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _styleSheetChanged(event) {
-    const header = this._cssModel.styleSheetHeaderForId(event.data.styleSheetId);
-    if (!header || !this._acceptsHeader(header))
-      return;
-    const styleFile = this._styleFiles.get(header.resourceURL());
-    styleFile._styleSheetChanged(header);
-  }
-
-  dispose() {
-    for (const styleFile of this._styleFiles.values())
-      styleFile.dispose();
-    this._styleFiles.clear();
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._project.removeProject();
-  }
-};
-
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-Bindings.StyleFile = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Bindings.ContentProviderBasedProject} project
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  constructor(cssModel, project, header) {
-    this._cssModel = cssModel;
-    this._project = project;
-    /** @type {!Set<!SDK.CSSStyleSheetHeader>} */
-    this._headers = new Set([header]);
-
-    const target = cssModel.target();
-
-    const url = header.resourceURL();
-    const metadata = Bindings.metadataForURL(target, header.frameId, url);
-
-    this._uiSourceCode = this._project.createUISourceCode(url, header.contentType());
-    this._uiSourceCode[Bindings.StyleFile._symbol] = this;
-    Bindings.NetworkProject.setInitialFrameAttribution(this._uiSourceCode, header.frameId);
-    this._project.addUISourceCodeWithProvider(this._uiSourceCode, this, metadata, 'text/css');
-
-    this._eventListeners = [
-      this._uiSourceCode.addEventListener(
-          Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this),
-      this._uiSourceCode.addEventListener(
-          Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this)
-    ];
-    this._throttler = new Common.Throttler(Bindings.StyleFile.updateTimeout);
-    this._terminated = false;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  addHeader(header) {
-    this._headers.add(header);
-    Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode, header.frameId);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  removeHeader(header) {
-    this._headers.delete(header);
-    Bindings.NetworkProject.removeFrameAttribution(this._uiSourceCode, header.frameId);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  _styleSheetChanged(header) {
-    console.assert(this._headers.has(header));
-    if (this._isUpdatingHeaders || !this._headers.has(header))
-      return;
-    const mirrorContentBound = this._mirrorContent.bind(this, header, true /* majorChange */);
-    this._throttler.schedule(mirrorContentBound, false /* asSoonAsPossible */);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyCommitted(event) {
-    if (this._isAddingRevision)
-      return;
-    const mirrorContentBound = this._mirrorContent.bind(this, this._uiSourceCode, true /* majorChange */);
-    this._throttler.schedule(mirrorContentBound, true /* asSoonAsPossible */);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyChanged(event) {
-    if (this._isAddingRevision)
-      return;
-    const mirrorContentBound = this._mirrorContent.bind(this, this._uiSourceCode, false /* majorChange */);
-    this._throttler.schedule(mirrorContentBound, false /* asSoonAsPossible */);
-  }
-
-  /**
-   * @param {!Common.ContentProvider} fromProvider
-   * @param {boolean} majorChange
-   * @return {!Promise}
-   */
-  async _mirrorContent(fromProvider, majorChange) {
-    if (this._terminated) {
-      this._styleFileSyncedForTest();
-      return;
-    }
-
-    let newContent = null;
-    if (fromProvider === this._uiSourceCode) {
-      newContent = this._uiSourceCode.workingCopy();
-    } else {
-      // ------ ASYNC ------
-      newContent = await fromProvider.requestContent();
-    }
-
-    if (newContent === null || this._terminated) {
-      this._styleFileSyncedForTest();
-      return;
-    }
-
-    if (fromProvider !== this._uiSourceCode) {
-      this._isAddingRevision = true;
-      this._uiSourceCode.addRevision(newContent);
-      this._isAddingRevision = false;
-    }
-
-    this._isUpdatingHeaders = true;
-    const promises = [];
-    for (const header of this._headers) {
-      if (header === fromProvider)
-        continue;
-      promises.push(this._cssModel.setStyleSheetText(header.id, newContent, majorChange));
-    }
-    // ------ ASYNC ------
-    await Promise.all(promises);
-    this._isUpdatingHeaders = false;
-    this._styleFileSyncedForTest();
-  }
-
-  _styleFileSyncedForTest() {
-  }
-
-  dispose() {
-    if (this._terminated)
-      return;
-    this._terminated = true;
-    this._project.removeFile(this._uiSourceCode.url());
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._headers.firstValue().originalContentProvider().contentURL();
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._headers.firstValue().originalContentProvider().contentType();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return this._headers.firstValue().originalContentProvider().contentEncoded();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    return this._headers.firstValue().originalContentProvider().requestContent();
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInContent(query, caseSensitive, isRegex) {
-    return this._headers.firstValue().originalContentProvider().searchInContent(query, caseSensitive, isRegex);
-  }
-};
-
-Bindings.StyleFile._symbol = Symbol('Bindings.StyleFile._symbol');
-
-Bindings.StyleFile.updateTimeout = 200;
diff --git a/front_end/bindings/TempFile.js b/front_end/bindings/TempFile.js
deleted file mode 100644
index 9d74521..0000000
--- a/front_end/bindings/TempFile.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Bindings.TempFile = class {
-  constructor() {
-    /** @type {?Blob} */
-    this._lastBlob = null;
-  }
-
-  /**
-   * @param {!Array<string|!Blob>} pieces
-   */
-  write(pieces) {
-    if (this._lastBlob)
-      pieces.unshift(this._lastBlob);
-    this._lastBlob = new Blob(pieces, {type: 'text/plain'});
-  }
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  read() {
-    return this.readRange();
-  }
-
-  /**
-   * @return {number}
-   */
-  size() {
-    return this._lastBlob ? this._lastBlob.size : 0;
-  }
-
-  /**
-   * @param {number=} startOffset
-   * @param {number=} endOffset
-   * @return {!Promise<?string>}
-   */
-  async readRange(startOffset, endOffset) {
-    if (!this._lastBlob) {
-      Common.console.error('Attempt to read a temp file that was never written');
-      return Promise.resolve('');
-    }
-    const blob = typeof startOffset === 'number' || typeof endOffset === 'number' ?
-        this._lastBlob.slice(/** @type {number} */ (startOffset), /** @type {number} */ (endOffset)) :
-        this._lastBlob;
-
-    const reader = new FileReader();
-    try {
-      await new Promise((resolve, reject) => {
-        reader.onloadend = resolve;
-        reader.onerror = reject;
-        reader.readAsText(blob);
-      });
-    } catch (error) {
-      Common.console.error('Failed to read from temp file: ' + error.message);
-    }
-
-    return reader.result;
-  }
-
-  /**
-   * @param {!Common.OutputStream} outputStream
-   * @param {function(!Bindings.ChunkedReader)=} progress
-   * @return {!Promise<?FileError>}
-   */
-  copyToOutputStream(outputStream, progress) {
-    if (!this._lastBlob) {
-      outputStream.close();
-      return Promise.resolve(/** @type {?FileError} */ (null));
-    }
-    const reader = new Bindings.ChunkedFileReader(/** @type {!Blob} */ (this._lastBlob), 10 * 1000 * 1000, progress);
-    return reader.read(outputStream).then(success => success ? null : reader.error());
-  }
-
-  remove() {
-    this._lastBlob = null;
-  }
-};
-
-/**
- * @implements {SDK.BackingStorage}
- */
-Bindings.TempFileBackingStorage = class {
-  constructor() {
-    /** @type {?Bindings.TempFile} */
-    this._file = null;
-    /** @type {!Array<string>} */
-    this._strings;
-    /** @type {number} */
-    this._stringsLength;
-    this.reset();
-  }
-
-  /**
-   * @override
-   * @param {string} string
-   */
-  appendString(string) {
-    this._strings.push(string);
-    this._stringsLength += string.length;
-    const flushStringLength = 10 * 1024 * 1024;
-    if (this._stringsLength > flushStringLength)
-      this._flush();
-  }
-
-  /**
-   * @override
-   * @param {string} string
-   * @return {function():!Promise<?string>}
-   */
-  appendAccessibleString(string) {
-    this._flush();
-    const startOffset = this._file.size();
-    this._strings.push(string);
-    this._flush();
-    return this._file.readRange.bind(this._file, startOffset, this._file.size());
-  }
-
-  _flush() {
-    if (!this._strings.length)
-      return;
-    if (!this._file)
-      this._file = new Bindings.TempFile();
-    this._stringsLength = 0;
-    this._file.write(this._strings.splice(0));
-  }
-
-  /**
-   * @override
-   */
-  finishWriting() {
-    this._flush();
-  }
-
-  /**
-   * @override
-   */
-  reset() {
-    if (this._file)
-      this._file.remove();
-    this._file = null;
-    /** @type {!Array<string>} */
-    this._strings = [];
-    this._stringsLength = 0;
-  }
-
-  /**
-   * @param {!Common.OutputStream} outputStream
-   * @return {!Promise<?FileError>}
-   */
-  writeToStream(outputStream) {
-    return this._file ? this._file.copyToOutputStream(outputStream) : Promise.resolve(null);
-  }
-};
-
-/**
- * @typedef {{
- *      startOffset: number,
- *      endOffset: number
- * }}
- */
-Bindings.TempFileBackingStorage.Chunk;
diff --git a/front_end/bindings/module.json b/front_end/bindings/module.json
deleted file mode 100644
index 918802a..0000000
--- a/front_end/bindings/module.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "dependencies": [
-        "sdk",
-        "platform",
-        "services",
-        "workspace"
-    ],
-    "scripts": [
-        "LiveLocation.js",
-        "ResourceMapping.js",
-        "CompilerScriptMapping.js",
-        "ResourceScriptMapping.js",
-        "SASSSourceMapping.js",
-        "StylesSourceMapping.js",
-        "CSSWorkspaceBinding.js",
-        "DebuggerWorkspaceBinding.js",
-        "BreakpointManager.js",
-        "ContentProviderBasedProject.js",
-        "DefaultScriptMapping.js",
-        "FileUtils.js",
-        "BlackboxManager.js",
-        "NetworkProject.js",
-        "PresentationConsoleMessageHelper.js",
-        "ResourceUtils.js",
-        "TempFile.js"
-    ]
-}
diff --git a/front_end/bindings_test_runner/AutomappingTestRunner.js b/front_end/bindings_test_runner/AutomappingTestRunner.js
deleted file mode 100644
index 4a4ed69..0000000
--- a/front_end/bindings_test_runner/AutomappingTestRunner.js
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-BindingsTestRunner.addFiles = function(testFileSystem, files) {
-  for (const filePath in files) {
-    const file = files[filePath];
-    testFileSystem.addFile(filePath, file.content, (file.time ? file.time.getTime() : 0));
-  }
-};
-
-let timeOverrides;
-let originalRequestMetadata;
-
-BindingsTestRunner.overrideNetworkModificationTime = function(urlToTime) {
-  if (!timeOverrides) {
-    timeOverrides = new Map();
-    originalRequestMetadata =
-        TestRunner.override(Bindings.ContentProviderBasedProject.prototype, 'requestMetadata', overrideTime, true);
-  }
-
-  for (const url in urlToTime)
-    timeOverrides.set(url, urlToTime[url]);
-
-  function overrideTime(uiSourceCode) {
-    if (!timeOverrides.has(uiSourceCode.url()))
-      return originalRequestMetadata.call(this, uiSourceCode);
-
-    const override = timeOverrides.get(uiSourceCode.url());
-    return originalRequestMetadata.call(this, uiSourceCode).then(onOriginalMetadata.bind(null, override));
-  }
-
-  function onOriginalMetadata(timeOverride, metadata) {
-    if (!timeOverride && !metadata)
-      return null;
-
-    return new Workspace.UISourceCodeMetadata(timeOverride, (metadata ? metadata.contentSize : null));
-  }
-};
-
-BindingsTestRunner.AutomappingTest = function(workspace) {
-  this._workspace = workspace;
-  this._networkProject = new Bindings.ContentProviderBasedProject(
-      this._workspace, 'AUTOMAPPING', Workspace.projectTypes.Network, 'simple website');
-
-  if (workspace !== Workspace.workspace)
-    new Persistence.FileSystemWorkspaceBinding(Persistence.isolatedFileSystemManager, this._workspace);
-
-  this._failedBindingsCount = 0;
-  this._automapping =
-      new Persistence.Automapping(this._workspace, this._onStatusAdded.bind(this), this._onStatusRemoved.bind(this));
-  TestRunner.addSniffer(this._automapping, '_onBindingFailedForTest', this._onBindingFailed.bind(this), true);
-  TestRunner.addSniffer(this._automapping, '_onSweepHappenedForTest', this._onSweepHappened.bind(this), true);
-};
-
-BindingsTestRunner.AutomappingTest.prototype = {
-  removeResources: function(urls) {
-    for (const url of urls)
-      this._networkProject.removeFile(url);
-  },
-
-  addNetworkResources: function(assets) {
-    for (const url in assets) {
-      const asset = assets[url];
-      const contentType = asset.contentType || Common.resourceTypes.Script;
-      const contentProvider = Common.StaticContentProvider.fromString(url, contentType, asset.content);
-      const metadata =
-          (typeof asset.content === 'string' || asset.time ?
-               new Workspace.UISourceCodeMetadata(asset.time, asset.content.length) :
-               null);
-      const uiSourceCode = this._networkProject.createUISourceCode(url, contentType);
-      this._networkProject.addUISourceCodeWithProvider(uiSourceCode, contentProvider, metadata);
-    }
-  },
-
-  waitUntilMappingIsStabilized: function() {
-    const promise = new Promise(x => this._stabilizedCallback = x);
-    this._checkStabilized();
-    return promise;
-  },
-
-  _onSweepHappened: function() {
-    this._failedBindingsCount = 0;
-    this._checkStabilized();
-  },
-
-  _onStatusRemoved: function(status) {
-    TestRunner.addResult('Binding removed: ' + status);
-    this._checkStabilized();
-  },
-
-  _onStatusAdded: function(status) {
-    TestRunner.addResult('Binding created: ' + status);
-    this._checkStabilized();
-  },
-
-  _onBindingFailed: function() {
-    ++this._failedBindingsCount;
-    this._checkStabilized();
-  },
-
-  _checkStabilized: function() {
-    if (!this._stabilizedCallback || this._automapping._sweepThrottler._process)
-      return;
-
-    const networkUISourceCodes = this._workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Network);
-    const stabilized = this._failedBindingsCount + this._automapping._statuses.size === networkUISourceCodes.length;
-
-    if (stabilized) {
-      TestRunner.addResult('Mapping has stabilized.');
-      const callback = this._stabilizedCallback;
-      delete this._stabilizedCallback;
-      callback.call(null);
-    }
-  }
-};
diff --git a/front_end/bindings_test_runner/BindingsTestRunner.js b/front_end/bindings_test_runner/BindingsTestRunner.js
deleted file mode 100644
index 472853f..0000000
--- a/front_end/bindings_test_runner/BindingsTestRunner.js
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-BindingsTestRunner.cleanupURL = function(url) {
-  if (!url.startsWith('debugger://'))
-    return url;
-
-  return url.replace(/VM\d+/g, 'VM[XXX]');
-};
-
-BindingsTestRunner.dumpWorkspace = function(previousSnapshot) {
-  const uiSourceCodes = Workspace.workspace.uiSourceCodes().slice();
-  let urls = uiSourceCodes.map(code => code.url());
-
-  urls = urls.map(BindingsTestRunner.cleanupURL);
-
-  urls.sort(String.caseInsensetiveComparator);
-  const isAdded = new Array(urls.length).fill(false);
-  let removedLines = [];
-
-  if (previousSnapshot) {
-    const diff = Diff.Diff.lineDiff(previousSnapshot, urls);
-    const removedEntries = diff.filter(entry => entry[0] === Diff.Diff.Operation.Delete).map(entry => entry[1]);
-    removedLines = [].concat.apply([], removedEntries);
-    let index = 0;
-
-    for (const entry of diff) {
-      if (entry[0] === Diff.Diff.Operation.Delete)
-        continue;
-
-      if (entry[0] === Diff.Diff.Operation.Equal) {
-        index += entry[1].length;
-        continue;
-      }
-
-      // eslint-disable-next-line no-unused-vars
-      for (const line of entry[1])
-        isAdded[index++] = true;
-    }
-
-    const addedEntries = diff.filter(entry => entry[0] === Diff.Diff.Operation.Insert).map(entry => entry[1]);
-    addedLines = [].concat.apply([], addedEntries);
-  }
-
-  TestRunner.addResult(`Removed: ${removedLines.length} uiSourceCodes`);
-
-  for (const url of removedLines)
-    TestRunner.addResult('[-] ' + url);
-
-  TestRunner.addResult(`Workspace: ${urls.length} uiSourceCodes.`);
-
-  for (let i = 0; i < urls.length; ++i) {
-    const url = urls[i];
-    const prefix = (isAdded[i] ? '[+] ' : '    ');
-    TestRunner.addResult(prefix + url);
-  }
-
-  return urls;
-};
-
-BindingsTestRunner.attachFrame = function(frameId, url, evalSourceURL) {
-  let evalSource = `(${attachFrame.toString()})('${frameId}', '${url}')`;
-
-  if (evalSourceURL)
-    evalSource += '//# sourceURL=' + evalSourceURL;
-
-  return TestRunner.evaluateInPageAsync(evalSource);
-
-  function attachFrame(frameId, url) {
-    const frame = document.createElement('iframe');
-    frame.src = url;
-    frame.id = frameId;
-    document.body.appendChild(frame);
-    return new Promise(x => frame.onload = x);
-  }
-};
-
-BindingsTestRunner.detachFrame = function(frameId, evalSourceURL) {
-  let evalSource = `(${detachFrame.toString()})('${frameId}')`;
-
-  if (evalSourceURL)
-    evalSource += '//# sourceURL=' + evalSourceURL;
-
-  return TestRunner.evaluateInPageAnonymously(evalSource);
-
-  function detachFrame(frameId) {
-    const frame = document.getElementById(frameId);
-    frame.remove();
-  }
-};
-
-BindingsTestRunner.navigateFrame = function(frameId, navigateURL, evalSourceURL) {
-  let evalSource = `(${navigateFrame.toString()})('${frameId}', '${navigateURL}')`;
-
-  if (evalSourceURL)
-    evalSource += '//# sourceURL=' + evalSourceURL;
-
-  return TestRunner.evaluateInPageAsync(evalSource);
-
-  function navigateFrame(frameId, url) {
-    const frame = document.getElementById(frameId);
-    frame.src = url;
-    return new Promise(x => frame.onload = x);
-  }
-};
-
-BindingsTestRunner.attachShadowDOM = function(id, templateSelector, evalSourceURL) {
-  let evalSource = `(${createShadowDOM.toString()})('${id}', '${templateSelector}')`;
-
-  if (evalSourceURL)
-    evalSource += '//# sourceURL=' + evalSourceURL;
-
-  return TestRunner.evaluateInPageAnonymously(evalSource);
-
-  function createShadowDOM(id, templateSelector) {
-    const shadowHost = document.createElement('div');
-    shadowHost.setAttribute('id', id);
-
-    const shadowRoot = shadowHost.attachShadow({mode: 'open'});
-
-    const t = document.querySelector(templateSelector);
-    const instance = t.content.cloneNode(true);
-    shadowRoot.appendChild(instance);
-    document.body.appendChild(shadowHost);
-  }
-};
-
-BindingsTestRunner.detachShadowDOM = function(id, evalSourceURL) {
-  let evalSource = `(${removeShadowDOM.toString()})('${id}')`;
-
-  if (evalSourceURL)
-    evalSource += '//# sourceURL=' + evalSourceURL;
-
-  return TestRunner.evaluateInPageAnonymously(evalSource);
-
-  function removeShadowDOM(id) {
-    document.querySelector('#' + id).remove();
-  }
-};
-
-BindingsTestRunner.waitForStyleSheetRemoved = function(urlSuffix) {
-  let fulfill;
-  const promise = new Promise(x => fulfill = x);
-  TestRunner.cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, onStyleSheetRemoved);
-  return promise;
-
-  function onStyleSheetRemoved(event) {
-    const styleSheetHeader = event.data;
-
-    if (!styleSheetHeader.resourceURL().endsWith(urlSuffix))
-      return;
-
-    TestRunner.cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetRemoved, onStyleSheetRemoved);
-    fulfill();
-  }
-};
-
-TestRunner.addSniffer(Bindings.CompilerScriptMapping.prototype, '_sourceMapAttachedForTest', onSourceMap, true);
-TestRunner.addSniffer(Bindings.SASSSourceMapping.prototype, '_sourceMapAttachedForTest', onSourceMap, true);
-const sourceMapCallbacks = new Map();
-
-function onSourceMap(sourceMap) {
-  for (const urlSuffix of sourceMapCallbacks.keys()) {
-    if (sourceMap.url().endsWith(urlSuffix)) {
-      const callback = sourceMapCallbacks.get(urlSuffix);
-      callback.call(null);
-      sourceMapCallbacks.delete(urlSuffix);
-    }
-  }
-}
-
-BindingsTestRunner.waitForSourceMap = function(sourceMapURLSuffix) {
-  let fulfill;
-  const promise = new Promise(x => fulfill = x);
-  sourceMapCallbacks.set(sourceMapURLSuffix, fulfill);
-  return promise;
-};
-
-const locationPool = new Bindings.LiveLocationPool();
-const nameSymbol = Symbol('LiveLocationNameForTest');
-const createdSymbol = Symbol('LiveLocationCreated');
-
-BindingsTestRunner.createDebuggerLiveLocation = function(name, urlSuffix, lineNumber, columnNumber) {
-  const script = TestRunner.debuggerModel.scripts().find(script => script.sourceURL.endsWith(urlSuffix));
-  const rawLocation = TestRunner.debuggerModel.createRawLocation(script, lineNumber || 0, columnNumber || 0);
-  return Bindings.debuggerWorkspaceBinding.createLiveLocation(
-      rawLocation, updateDelegate.bind(null, name), locationPool);
-};
-
-BindingsTestRunner.createCSSLiveLocation = function(name, urlSuffix, lineNumber, columnNumber) {
-  const header = TestRunner.cssModel.styleSheetHeaders().find(header => header.resourceURL().endsWith(urlSuffix));
-  const rawLocation = new SDK.CSSLocation(header, lineNumber || 0, columnNumber || 0);
-  return Bindings.cssWorkspaceBinding.createLiveLocation(rawLocation, updateDelegate.bind(null, name), locationPool);
-};
-
-function updateDelegate(name, liveLocation) {
-  liveLocation[nameSymbol] = name;
-  const hint = (liveLocation[createdSymbol] ? '[ UPDATE ]' : '[ CREATE ]');
-  liveLocation[createdSymbol] = true;
-  BindingsTestRunner.dumpLocation(liveLocation, hint);
-}
-
-BindingsTestRunner.dumpLocation = function(liveLocation, hint) {
-  hint = hint || '[  GET   ]';
-  const prefix = `${hint}  LiveLocation-${liveLocation[nameSymbol]}: `;
-  const uiLocation = liveLocation.uiLocation();
-
-  if (!uiLocation) {
-    TestRunner.addResult(prefix + 'null');
-    return;
-  }
-
-  TestRunner.addResult(
-      prefix + BindingsTestRunner.cleanupURL(uiLocation.uiSourceCode.url()) + ':' + uiLocation.lineNumber + ':' +
-      uiLocation.columnNumber);
-};
diff --git a/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js b/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js
deleted file mode 100644
index a6e75d1..0000000
--- a/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-InspectorFrontendHost.isolatedFileSystem = function(name) {
-  return BindingsTestRunner.TestFileSystem._instances[name];
-};
-
-BindingsTestRunner.TestFileSystem = function(fileSystemPath) {
-  this.root = new BindingsTestRunner.TestFileSystem.Entry(this, '', true, null);
-  this.fileSystemPath = fileSystemPath;
-};
-
-BindingsTestRunner.TestFileSystem._instances = {};
-
-BindingsTestRunner.TestFileSystem.prototype = {
-  dumpAsText: function() {
-    const result = [];
-    dfs(this.root, '');
-    result[0] = this.fileSystemPath;
-    return result.join('\n');
-
-    function dfs(node, indent) {
-      result.push(indent + node.name);
-      const newIndent = indent + '    ';
-
-      for (const child of node._children)
-        dfs(child, newIndent);
-    }
-  },
-
-  reportCreatedPromise: function(type) {
-    return new Promise(fulfill => this.reportCreated(fulfill, type));
-  },
-
-  reportCreated: function(callback, type) {
-    const fileSystemPath = this.fileSystemPath;
-    BindingsTestRunner.TestFileSystem._instances[this.fileSystemPath] = this;
-
-    InspectorFrontendHost.events.dispatchEventToListeners(
-        InspectorFrontendHostAPI.Events.FileSystemAdded,
-        {fileSystem: {fileSystemPath: this.fileSystemPath, fileSystemName: this.fileSystemPath, type}});
-
-    Persistence.isolatedFileSystemManager.addEventListener(
-        Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, created);
-
-    function created(event) {
-      const fileSystem = event.data;
-
-      if (fileSystem.path() !== fileSystemPath)
-        return;
-
-      Persistence.isolatedFileSystemManager.removeEventListener(
-          Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, created);
-      callback(fileSystem);
-    }
-  },
-
-  reportRemoved: function() {
-    delete BindingsTestRunner.TestFileSystem._instances[this.fileSystemPath];
-    InspectorFrontendHost.events.dispatchEventToListeners(
-        InspectorFrontendHostAPI.Events.FileSystemRemoved, this.fileSystemPath);
-  },
-
-  addFile: function(path, content, lastModified) {
-    const pathTokens = path.split('/');
-    let node = this.root;
-    const folders = pathTokens.slice(0, pathTokens.length - 1);
-    const fileName = pathTokens.peekLast();
-
-    for (const folder of folders) {
-      let dir = node._childrenMap[folder];
-
-      if (!dir)
-        dir = node.mkdir(folder);
-
-      node = dir;
-    }
-
-    const file = node.addFile(fileName, content);
-
-    if (lastModified)
-      file._timestamp = lastModified;
-
-    return file;
-  }
-};
-
-BindingsTestRunner.TestFileSystem.Entry = function(fileSystem, name, isDirectory, parent) {
-  this._fileSystem = fileSystem;
-  this.name = name;
-  this._children = [];
-  this._childrenMap = {};
-  this.isDirectory = isDirectory;
-  this._timestamp = 1000000;
-  this._parent = parent;
-};
-
-BindingsTestRunner.TestFileSystem.Entry.prototype = {
-  get fullPath() {
-    return (this.parent ? this.parent.fullPath + '/' + this.name : '');
-  },
-
-  remove: function(success, failure) {
-    this._parent._removeChild(this, success, failure);
-  },
-
-  _removeChild: function(child, success, failure) {
-    const index = this._children.indexOf(child);
-
-    if (index === -1) {
-      failure('Failed to remove file: file not found.');
-      return;
-    }
-
-    const fullPath = this._fileSystem.fileSystemPath + child.fullPath;
-    this._children.splice(index, 1);
-    delete this._childrenMap[child.name];
-    child.parent = null;
-
-    InspectorFrontendHost.events.dispatchEventToListeners(
-        InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved,
-        {changed: [], added: [], removed: [fullPath]});
-
-    success();
-  },
-
-  mkdir: function(name) {
-    const child = new BindingsTestRunner.TestFileSystem.Entry(this._fileSystem, name, true, this);
-    this._childrenMap[name] = child;
-    this._children.push(child);
-    child.parent = this;
-    return child;
-  },
-
-  addFile: function(name, content) {
-    const child = new BindingsTestRunner.TestFileSystem.Entry(this._fileSystem, name, false, this);
-    this._childrenMap[name] = child;
-    this._children.push(child);
-    child.parent = this;
-
-    child.content = new Blob([content], {type: 'text/plain'});
-
-    const fullPath = this._fileSystem.fileSystemPath + child.fullPath;
-
-    InspectorFrontendHost.events.dispatchEventToListeners(
-        InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved,
-        {changed: [], added: [fullPath], removed: []});
-
-    return child;
-  },
-
-  setContent: function(content) {
-    this.content = new Blob([content], {type: 'text/plain'});
-
-    this._timestamp += 1000;
-    const fullPath = this._fileSystem.fileSystemPath + this.fullPath;
-
-    InspectorFrontendHost.events.dispatchEventToListeners(
-        InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved,
-        {changed: [fullPath], added: [], removed: []});
-  },
-
-  createReader: function() {
-    return new BindingsTestRunner.TestFileSystem.Reader(this._children);
-  },
-
-  createWriter: function(success, failure) {
-    success(new BindingsTestRunner.TestFileSystem.Writer(this));
-  },
-
-  file: function(callback) {
-    callback(this.content);
-  },
-
-  getDirectory: function(path, noop, callback, errorCallback) {
-    this.getEntry(path, noop, callback, errorCallback);
-  },
-
-  getFile: function(path, noop, callback, errorCallback) {
-    this.getEntry(path, noop, callback, errorCallback);
-  },
-
-  _createEntry: function(path, options, callback, errorCallback) {
-    const tokens = path.split('/');
-    const name = tokens.pop();
-    let parentEntry = this;
-
-    for (const token of tokens)
-      parentEntry = parentEntry._childrenMap[token];
-
-    let entry = parentEntry._childrenMap[name];
-
-    if (entry && options.exclusive) {
-      errorCallback(new DOMException('File exists: ' + path, 'InvalidModificationError'));
-      return;
-    }
-
-    if (!entry)
-      entry = parentEntry.addFile(name, '');
-
-    callback(entry);
-  },
-
-  getEntry: function(path, options, callback, errorCallback) {
-    if (path.startsWith('/'))
-      path = path.substring(1);
-
-    if (options && options.create) {
-      this._createEntry(path, options, callback, errorCallback);
-      return;
-    }
-
-    if (!path) {
-      callback(this);
-      return;
-    }
-
-    let entry = this;
-
-    for (const token of path.split('/')) {
-      entry = entry._childrenMap[token];
-      if (!entry)
-        break;
-    }
-
-    (entry ? callback(entry) : errorCallback(new DOMException('Path not found: ' + path, 'NotFoundError')));
-  },
-
-  getMetadata: function(success, failure) {
-    success({modificationTime: new Date(this._timestamp), size: (this.isDirectory ? 0 : this.content.size)});
-  },
-
-  moveTo: function(parent, newName, callback, errorCallback) {
-    this._parent._children.remove(this);
-    delete this._parent._childrenMap[this.name];
-    this._parent = parent;
-    this._parent._children.push(this);
-    this.name = newName;
-    this._parent._childrenMap[this.name] = this;
-    callback(this);
-  },
-
-  getParent: function(callback, errorCallback) {
-    callback(this._parent);
-  }
-};
-
-BindingsTestRunner.TestFileSystem.Reader = function(children) {
-  this._children = children;
-};
-
-BindingsTestRunner.TestFileSystem.Reader.prototype = {
-  readEntries: function(callback) {
-    const children = this._children;
-    this._children = [];
-    callback(children);
-  }
-};
-
-BindingsTestRunner.TestFileSystem.Writer = function(entry) {
-  this._entry = entry;
-  this._modificationTimesDelta = 500;
-};
-
-BindingsTestRunner.TestFileSystem.Writer.prototype = {
-  write: function(blob) {
-    this._entry._timestamp += this._modificationTimesDelta;
-    this._entry.content = blob;
-
-    if (this.onwriteend)
-      this.onwriteend();
-  },
-
-  truncate: function(num) {
-    this._entry._timestamp += this._modificationTimesDelta;
-    this._entry.content = this._entry.content.slice(0, num);
-
-    if (this.onwriteend)
-      this.onwriteend();
-  }
-};
diff --git a/front_end/bindings_test_runner/OverridesTestRunner.js b/front_end/bindings_test_runner/OverridesTestRunner.js
deleted file mode 100644
index 2e3d34c..0000000
--- a/front_end/bindings_test_runner/OverridesTestRunner.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @param {string} folderPath
- * @return {!{isolatedFileSystem: !Persistence.IsolatedFileSystem, project: !Workspace.Project, testFileSystem: !BindingsTestRunner.TestFileSystem}}
- */
-BindingsTestRunner.createOverrideProject = async function(folderPath) {
-  const testFileSystem = new BindingsTestRunner.TestFileSystem(folderPath);
-  const isolatedFileSystem = await testFileSystem.reportCreatedPromise('overrides');
-  isolatedFileSystem._type = 'overrides';
-  const project =
-      Workspace.workspace.project(Persistence.FileSystemWorkspaceBinding.projectId(isolatedFileSystem.path()));
-  console.assert(project);
-  return {isolatedFileSystem, project, testFileSystem};
-};
-
-/**
- * @param {boolean} enabled
- */
-BindingsTestRunner.setOverridesEnabled = function(enabled) {
-  Common.settings.moduleSetting('persistenceNetworkOverridesEnabled').set(enabled);
-};
diff --git a/front_end/bindings_test_runner/PersistenceTestRunner.js b/front_end/bindings_test_runner/PersistenceTestRunner.js
deleted file mode 100644
index 8b8ddef..0000000
--- a/front_end/bindings_test_runner/PersistenceTestRunner.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-Persistence.PersistenceBinding.prototype.toString = function() {
-  const lines = ['{', '       network: ' + this.network.url(), '    fileSystem: ' + this.fileSystem.url(), '}'];
-
-  return lines.join('\n');
-};
-
-Persistence.AutomappingStatus.prototype.toString = function() {
-  const lines = [
-    '{', '       network: ' + this.network.url(), '    fileSystem: ' + this.fileSystem.url(),
-    '    exactMatch: ' + this.exactMatch, '}'
-  ];
-
-  return lines.join('\n');
-};
-
-
-BindingsTestRunner.waitForBinding = function(fileName) {
-  const uiSourceCodes = Workspace.workspace.uiSourceCodes();
-
-  for (const uiSourceCode of uiSourceCodes) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-
-    if (!binding)
-      continue;
-
-    if (uiSourceCode.name() === fileName)
-      return Promise.resolve(binding);
-  }
-
-  return TestRunner.waitForEvent(
-      Persistence.Persistence.Events.BindingCreated, Persistence.persistence,
-      binding => binding.network.name() === fileName || binding.fileSystem.name() === fileName);
-};
-
-BindingsTestRunner.addFooJSFile = function(fs) {
-  return fs.root.mkdir('devtools')
-      .mkdir('persistence')
-      .mkdir('resources')
-      .addFile('foo.js', '\n\nwindow.foo = ()=>\'foo\';\n');
-};
-
-BindingsTestRunner.initializeTestMapping = function() {
-  return new TestMapping(Persistence.persistence);
-};
-
-class TestMapping {
-  constructor(persistence) {
-    this._persistence = persistence;
-    persistence.setAutomappingEnabled(false);
-    this._bindings = new Set();
-  }
-
-  async addBinding(urlSuffix) {
-    if (this._findBinding(urlSuffix)) {
-      TestRunner.addResult(`FAILED TO ADD BINDING: binding already exists for ${urlSuffix}`);
-      TestRunner.completeTest();
-      return;
-    }
-
-    const networkUISourceCode = await TestRunner.waitForUISourceCode(urlSuffix, Workspace.projectTypes.Network);
-    const fileSystemUISourceCode = await TestRunner.waitForUISourceCode(urlSuffix, Workspace.projectTypes.FileSystem);
-    const binding = new Persistence.PersistenceBinding(networkUISourceCode, fileSystemUISourceCode);
-    this._bindings.add(binding);
-    this._persistence.addBindingForTest(binding);
-  }
-
-  _findBinding(urlSuffix) {
-    for (const binding of this._bindings) {
-      if (binding.network.url().endsWith(urlSuffix))
-        return binding;
-    }
-
-    return null;
-  }
-
-  async removeBinding(urlSuffix) {
-    const binding = this._findBinding(urlSuffix);
-
-    if (!binding) {
-      TestRunner.addResult(`FAILED TO REMOVE BINDING: binding does not exist for ${urlSuffix}`);
-      TestRunner.completeTest();
-      return;
-    }
-
-    this._bindings.delete(binding);
-    this._persistence.removeBindingForTest(binding);
-  }
-
-  dispose() {
-    for (const binding of this._bindings)
-      this._persistence.removeBindingForTest(binding);
-
-    this._bindings.clear();
-  }
-}
diff --git a/front_end/bindings_test_runner/module.json b/front_end/bindings_test_runner/module.json
deleted file mode 100644
index 1b37b2e..0000000
--- a/front_end/bindings_test_runner/module.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "workspace",
-    "diff",
-    "bindings",
-    "persistence"
-  ],
-  "scripts": [
-    "BindingsTestRunner.js",
-    "IsolatedFilesystemTestRunner.js",
-    "AutomappingTestRunner.js",
-    "PersistenceTestRunner.js",
-    "OverridesTestRunner.js"
-  ],
-  "skip_compilation": [
-    "BindingsTestRunner.js",
-    "IsolatedFilesystemTestRunner.js",
-    "AutomappingTestRunner.js",
-    "PersistenceTestRunner.js",
-    "OverridesTestRunner.js"
-  ]
-}
diff --git a/front_end/browser_components/ImagePreview.js b/front_end/browser_components/ImagePreview.js
deleted file mode 100644
index 4abc3c3..0000000
--- a/front_end/browser_components/ImagePreview.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-BrowserComponents.ImagePreview = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {string} originalImageURL
-   * @param {boolean} showDimensions
-   * @param {!Object=} precomputedFeatures
-   * @return {!Promise<?Element>}
-   */
-  static build(target, originalImageURL, showDimensions, precomputedFeatures) {
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (!resourceTreeModel)
-      return Promise.resolve(/** @type {?Element} */ (null));
-    let resource = resourceTreeModel.resourceForURL(originalImageURL);
-    let imageURL = originalImageURL;
-    if (!isImageResource(resource) && precomputedFeatures && precomputedFeatures.currentSrc) {
-      imageURL = precomputedFeatures.currentSrc;
-      resource = resourceTreeModel.resourceForURL(imageURL);
-    }
-    if (!isImageResource(resource))
-      return Promise.resolve(/** @type {?Element} */ (null));
-
-    let fulfill;
-    const promise = new Promise(x => fulfill = x);
-    const imageElement = createElement('img');
-    imageElement.addEventListener('load', buildContent, false);
-    imageElement.addEventListener('error', () => fulfill(null), false);
-    resource.populateImageSource(imageElement);
-    return promise;
-
-    /**
-     * @param {?SDK.Resource} resource
-     * @return {boolean}
-     */
-    function isImageResource(resource) {
-      return !!resource && resource.resourceType() === Common.resourceTypes.Image;
-    }
-
-    function buildContent() {
-      const container = createElement('table');
-      UI.appendStyle(container, 'browser_components/imagePreview.css');
-      container.className = 'image-preview-container';
-      const naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidth : imageElement.naturalWidth;
-      const naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHeight : imageElement.naturalHeight;
-      const offsetWidth = precomputedFeatures ? precomputedFeatures.offsetWidth : naturalWidth;
-      const offsetHeight = precomputedFeatures ? precomputedFeatures.offsetHeight : naturalHeight;
-      let description;
-      if (showDimensions) {
-        if (offsetHeight === naturalHeight && offsetWidth === naturalWidth) {
-          description = Common.UIString('%d \xd7 %d pixels', offsetWidth, offsetHeight);
-        } else {
-          description = Common.UIString(
-              '%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)', offsetWidth, offsetHeight, naturalWidth, naturalHeight);
-        }
-      }
-
-      container.createChild('tr').createChild('td', 'image-container').appendChild(imageElement);
-      if (description)
-        container.createChild('tr').createChild('td').createChild('span', 'description').textContent = description;
-      if (imageURL !== originalImageURL) {
-        container.createChild('tr').createChild('td').createChild('span', 'description').textContent =
-            String.sprintf('currentSrc: %s', imageURL.trimMiddle(100));
-      }
-      fulfill(container);
-    }
-  }
-};
diff --git a/front_end/browser_components/imagePreview.css b/front_end/browser_components/imagePreview.css
deleted file mode 100644
index 08020e5..0000000
--- a/front_end/browser_components/imagePreview.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.image-preview-container {
-    background: transparent;
-    text-align: center;
-    border-spacing: 0;
-}
-
-.image-preview-container img {
-    margin: 2px auto;
-    max-width: 100px;
-    max-height: 100px;
-    background-image: url(Images/checker.png);
-    -webkit-user-select: text;
-    -webkit-user-drag: auto;
-}
-
-.image-container {
-    padding: 0;
-}
diff --git a/front_end/browser_components/module.json b/front_end/browser_components/module.json
deleted file mode 100644
index bf178cb..0000000
--- a/front_end/browser_components/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": [
-        "browser_sdk",
-        "components"
-    ],
-    "scripts": [
-        "ImagePreview.js"
-    ],
-    "resources": [
-        "imagePreview.css"
-    ]
-}
diff --git a/front_end/browser_console/BrowserConsole.js b/front_end/browser_console/BrowserConsole.js
deleted file mode 100644
index c961bc2..0000000
--- a/front_end/browser_console/BrowserConsole.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.Renderer}
- * @implements {UI.ContextMenu.Provider}
- */
-BrowserConsole.BrowserConsole = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} object
-   */
-  appendApplicableItems(event, contextMenu, object) {
-    const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object);
-    const request = BrowserSDK.NetworkLog.requestForConsoleMessage(consoleMessage);
-    if (request && SDK.NetworkManager.canReplayRequest(request)) {
-      contextMenu.debugSection().appendItem(
-          Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request));
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Object} object
-   * @param {!Common.Renderer.Options} options
-   * @return {!Promise.<?Node>}
-   */
-  render(object, options) {
-    const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object);
-    const request = BrowserSDK.NetworkLog.requestForConsoleMessage(consoleMessage);
-    let messageElement = null;
-    if (request) {
-      messageElement = createElement('span');
-      if (consoleMessage.level === SDK.ConsoleMessage.MessageLevel.Error) {
-        messageElement.createTextChild(request.requestMethod + ' ');
-        messageElement.appendChild(Components.Linkifier.linkifyRevealable(request, request.url(), request.url()));
-        messageElement.createTextChildren(' ', String(request.statusCode), ' (', request.statusText, ')');
-      } else {
-        const fragment = Console.ConsoleViewMessage.linkifyWithCustomLinkifier(
-            consoleMessage.messageText,
-            title => Components.Linkifier.linkifyRevealable(
-                /** @type {!SDK.NetworkRequest} */ (request), title, request.url()));
-        messageElement.appendChild(fragment);
-      }
-    }
-    return Promise.resolve(/** @type {?Node} */ (messageElement));
-  }
-};
diff --git a/front_end/browser_console/module.json b/front_end/browser_console/module.json
deleted file mode 100644
index 7dbf71b..0000000
--- a/front_end/browser_console/module.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "SDK.ConsoleMessage"
-            ],
-            "className": "BrowserConsole.BrowserConsole"
-        },
-        {
-            "type": "@Common.Renderer",
-            "contextTypes": [
-                "SDK.ConsoleMessage"
-            ],
-            "source": "network",
-            "className": "BrowserConsole.BrowserConsole"
-        }
-    ],
-    "dependencies": [
-        "browser_sdk",
-        "console"
-    ],
-    "scripts": [
-        "BrowserConsole.js"
-    ]
-}
diff --git a/front_end/browser_debugger/DOMBreakpointsSidebarPane.js b/front_end/browser_debugger/DOMBreakpointsSidebarPane.js
deleted file mode 100644
index 67a94a8..0000000
--- a/front_end/browser_debugger/DOMBreakpointsSidebarPane.js
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {UI.ContextFlavorListener}
- */
-BrowserDebugger.DOMBreakpointsSidebarPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('browser_debugger/domBreakpointsSidebarPane.css');
-
-    this._listElement = this.contentElement.createChild('div', 'breakpoint-list hidden');
-    this._emptyElement = this.contentElement.createChild('div', 'gray-info-message');
-    this._emptyElement.textContent = Common.UIString('No breakpoints');
-
-    /** @type {!Map<!SDK.DOMDebuggerModel.DOMBreakpoint, !BrowserDebugger.DOMBreakpointsSidebarPane.Item>} */
-    this._items = new Map();
-    SDK.targetManager.addModelListener(
-        SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, this._breakpointAdded, this);
-    SDK.targetManager.addModelListener(
-        SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointToggled, this._breakpointToggled, this);
-    SDK.targetManager.addModelListener(
-        SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved, this._breakpointsRemoved, this);
-
-    for (const domDebuggerModel of SDK.targetManager.models(SDK.DOMDebuggerModel)) {
-      domDebuggerModel.retrieveDOMBreakpoints();
-      for (const breakpoint of domDebuggerModel.domBreakpoints())
-        this._addBreakpoint(breakpoint);
-    }
-
-    this._highlightedElement = null;
-    this._update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _breakpointAdded(event) {
-    this._addBreakpoint(/** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (event.data));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _breakpointToggled(event) {
-    const breakpoint = /** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (event.data);
-    const item = this._items.get(breakpoint);
-    if (item)
-      item.checkbox.checked = breakpoint.enabled;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _breakpointsRemoved(event) {
-    const breakpoints = /** @type {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} */ (event.data);
-    for (const breakpoint of breakpoints) {
-      const item = this._items.get(breakpoint);
-      if (item) {
-        this._items.delete(breakpoint);
-        this._listElement.removeChild(item.element);
-      }
-    }
-    if (!this._listElement.firstChild) {
-      this._emptyElement.classList.remove('hidden');
-      this._listElement.classList.add('hidden');
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint
-   */
-  _addBreakpoint(breakpoint) {
-    const element = createElementWithClass('div', 'breakpoint-entry');
-    element.addEventListener('contextmenu', this._contextMenu.bind(this, breakpoint), true);
-
-    const checkboxLabel = UI.CheckboxLabel.create('', breakpoint.enabled);
-    const checkboxElement = checkboxLabel.checkboxElement;
-    checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, breakpoint), false);
-    element.appendChild(checkboxLabel);
-
-    const labelElement = createElementWithClass('div', 'dom-breakpoint');
-    element.appendChild(labelElement);
-
-    const linkifiedNode = createElementWithClass('monospace');
-    linkifiedNode.style.display = 'block';
-    labelElement.appendChild(linkifiedNode);
-    Common.Linkifier.linkify(breakpoint.node).then(linkified => linkifiedNode.appendChild(linkified));
-
-    const description = createElement('div');
-    description.textContent = BrowserDebugger.DOMBreakpointsSidebarPane.BreakpointTypeLabels.get(breakpoint.type);
-    labelElement.appendChild(description);
-
-    const item = {breakpoint: breakpoint, element: element, checkbox: checkboxElement};
-    element._item = item;
-    this._items.set(breakpoint, item);
-
-    let currentElement = this._listElement.firstChild;
-    while (currentElement) {
-      if (currentElement._item && currentElement._item.breakpoint.type < breakpoint.type)
-        break;
-      currentElement = currentElement.nextSibling;
-    }
-    this._listElement.insertBefore(element, currentElement);
-    this._emptyElement.classList.add('hidden');
-    this._listElement.classList.remove('hidden');
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint
-   * @param {!Event} event
-   */
-  _contextMenu(breakpoint, event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Remove breakpoint'), () => {
-      breakpoint.domDebuggerModel.removeDOMBreakpoint(breakpoint.node, breakpoint.type);
-    });
-    contextMenu.defaultSection().appendItem(Common.UIString('Remove all DOM breakpoints'), () => {
-      breakpoint.domDebuggerModel.removeAllDOMBreakpoints();
-    });
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint
-   */
-  _checkboxClicked(breakpoint) {
-    const item = this._items.get(breakpoint);
-    if (!item)
-      return;
-    breakpoint.domDebuggerModel.toggleDOMBreakpoint(breakpoint, item.checkbox.checked);
-  }
-
-  /**
-   * @override
-   * @param {?Object} object
-   */
-  flavorChanged(object) {
-    this._update();
-  }
-
-  _update() {
-    const details = UI.context.flavor(SDK.DebuggerPausedDetails);
-    if (!details || !details.auxData || details.reason !== SDK.DebuggerModel.BreakReason.DOM) {
-      if (this._highlightedElement) {
-        this._highlightedElement.classList.remove('breakpoint-hit');
-        delete this._highlightedElement;
-      }
-      return;
-    }
-    const domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerModel);
-    if (!domDebuggerModel)
-      return;
-    const data = domDebuggerModel.resolveDOMBreakpointData(/** @type {!Object} */ (details.auxData));
-    if (!data)
-      return;
-
-    let element = null;
-    for (const item of this._items.values()) {
-      if (item.breakpoint.node === data.node && item.breakpoint.type === data.type)
-        element = item.element;
-    }
-    if (!element)
-      return;
-    UI.viewManager.showView('sources.domBreakpoints');
-    element.classList.add('breakpoint-hit');
-    this._highlightedElement = element;
-  }
-};
-
-/** @typedef {!{element: !Element, checkbox: !Element, breakpoint: !SDK.DOMDebuggerModel.DOMBreakpoint}} */
-BrowserDebugger.DOMBreakpointsSidebarPane.Item;
-
-BrowserDebugger.DOMBreakpointsSidebarPane.BreakpointTypeLabels = new Map([
-  [SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified, Common.UIString('Subtree modified')],
-  [SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified, Common.UIString('Attribute modified')],
-  [SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved, Common.UIString('Node removed')],
-]);
-
-/**
- * @implements {UI.ContextMenu.Provider}
- */
-BrowserDebugger.DOMBreakpointsSidebarPane.ContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} object
-   */
-  appendApplicableItems(event, contextMenu, object) {
-    const node = /** @type {!SDK.DOMNode} */ (object);
-    if (node.pseudoType())
-      return;
-    const domDebuggerModel = node.domModel().target().model(SDK.DOMDebuggerModel);
-    if (!domDebuggerModel)
-      return;
-
-    /**
-     * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
-     */
-    function toggleBreakpoint(type) {
-      if (domDebuggerModel.hasDOMBreakpoint(node, type))
-        domDebuggerModel.removeDOMBreakpoint(node, type);
-      else
-        domDebuggerModel.setDOMBreakpoint(node, type);
-    }
-
-    const breakpointsMenu = contextMenu.debugSection().appendSubMenuItem(Common.UIString('Break on'));
-    for (const key in SDK.DOMDebuggerModel.DOMBreakpoint.Type) {
-      const type = SDK.DOMDebuggerModel.DOMBreakpoint.Type[key];
-      const label = Sources.DebuggerPausedMessage.BreakpointTypeNouns.get(type);
-      breakpointsMenu.defaultSection().appendCheckboxItem(
-          label, toggleBreakpoint.bind(null, type), domDebuggerModel.hasDOMBreakpoint(node, type));
-    }
-  }
-};
diff --git a/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js b/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
deleted file mode 100644
index a72ac4e..0000000
--- a/front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-BrowserDebugger.EventListenerBreakpointsSidebarPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this._categoriesTreeOutline = new UI.TreeOutlineInShadow();
-    this._categoriesTreeOutline.element.tabIndex = 0;
-    this._categoriesTreeOutline.registerRequiredCSS('browser_debugger/eventListenerBreakpoints.css');
-    this.contentElement.appendChild(this._categoriesTreeOutline.element);
-
-    /** @type {!Map<string, !BrowserDebugger.EventListenerBreakpointsSidebarPane.Item>} */
-    this._categories = new Map();
-    const categories = SDK.domDebuggerManager.eventListenerBreakpoints().map(breakpoint => breakpoint.category());
-    categories.sort();
-    for (const category of categories) {
-      if (!this._categories.has(category))
-        this._createCategory(category);
-    }
-
-    /** @type {!Map<!SDK.DOMDebuggerModel.EventListenerBreakpoint, !BrowserDebugger.EventListenerBreakpointsSidebarPane.Item>} */
-    this._breakpoints = new Map();
-    for (const breakpoint of SDK.domDebuggerManager.eventListenerBreakpoints())
-      this._createBreakpoint(breakpoint);
-
-    SDK.targetManager.addModelListener(SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._update, this);
-    SDK.targetManager.addModelListener(SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._update, this);
-    UI.context.addFlavorChangeListener(SDK.Target, this._update, this);
-  }
-
-  /**
-   * @param {string} name
-   */
-  _createCategory(name) {
-    const labelNode = UI.CheckboxLabel.create(name);
-    labelNode.checkboxElement.addEventListener('click', this._categoryCheckboxClicked.bind(this, name), true);
-
-    const treeElement = new UI.TreeElement(labelNode);
-    treeElement.selectable = false;
-    this._categoriesTreeOutline.appendChild(treeElement);
-
-    this._categories.set(name, {element: treeElement, checkbox: labelNode.checkboxElement});
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.EventListenerBreakpoint} breakpoint
-   */
-  _createBreakpoint(breakpoint) {
-    const labelNode = UI.CheckboxLabel.create(breakpoint.title());
-    labelNode.classList.add('source-code');
-    labelNode.checkboxElement.addEventListener('click', this._breakpointCheckboxClicked.bind(this, breakpoint), true);
-
-    const treeElement = new UI.TreeElement(labelNode);
-    treeElement.listItemElement.createChild('div', 'breakpoint-hit-marker');
-    treeElement.selectable = false;
-    this._categories.get(breakpoint.category()).element.appendChild(treeElement);
-
-    this._breakpoints.set(breakpoint, {element: treeElement, checkbox: labelNode.checkboxElement});
-  }
-
-  _update() {
-    const target = UI.context.flavor(SDK.Target);
-    const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
-    const details = debuggerModel ? debuggerModel.debuggerPausedDetails() : null;
-
-    if (!details || details.reason !== SDK.DebuggerModel.BreakReason.EventListener || !details.auxData) {
-      if (this._highlightedElement) {
-        this._highlightedElement.classList.remove('breakpoint-hit');
-        delete this._highlightedElement;
-      }
-      return;
-    }
-
-    const breakpoint = SDK.domDebuggerManager.resolveEventListenerBreakpoint(/** @type {!Object} */ (details.auxData));
-    if (!breakpoint)
-      return;
-
-    UI.viewManager.showView('sources.eventListenerBreakpoints');
-    this._categories.get(breakpoint.category()).element.expand();
-    this._highlightedElement = this._breakpoints.get(breakpoint).element.listItemElement;
-    this._highlightedElement.classList.add('breakpoint-hit');
-  }
-
-  /**
-   * @param {string} category
-   */
-  _categoryCheckboxClicked(category) {
-    const item = this._categories.get(category);
-    const enabled = item.checkbox.checked;
-    for (const breakpoint of this._breakpoints.keys()) {
-      if (breakpoint.category() === category) {
-        breakpoint.setEnabled(enabled);
-        this._breakpoints.get(breakpoint).checkbox.checked = enabled;
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.EventListenerBreakpoint} breakpoint
-   */
-  _breakpointCheckboxClicked(breakpoint) {
-    const item = this._breakpoints.get(breakpoint);
-    breakpoint.setEnabled(item.checkbox.checked);
-
-    let hasEnabled = false;
-    let hasDisabled = false;
-    for (const other of this._breakpoints.keys()) {
-      if (other.category() === breakpoint.category()) {
-        if (other.enabled())
-          hasEnabled = true;
-        else
-          hasDisabled = true;
-      }
-    }
-
-    const checkbox = this._categories.get(breakpoint.category()).checkbox;
-    checkbox.checked = hasEnabled;
-    checkbox.indeterminate = hasEnabled && hasDisabled;
-  }
-};
-
-/** @typedef {!{element: !UI.TreeElement, checkbox: !Element}} */
-BrowserDebugger.EventListenerBreakpointsSidebarPane.Item;
diff --git a/front_end/browser_debugger/ObjectEventListenersSidebarPane.js b/front_end/browser_debugger/ObjectEventListenersSidebarPane.js
deleted file mode 100644
index 37bdd75..0000000
--- a/front_end/browser_debugger/ObjectEventListenersSidebarPane.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.ToolbarItem.ItemsProvider}
- * @unrestricted
- */
-BrowserDebugger.ObjectEventListenersSidebarPane = class extends UI.VBox {
-  constructor() {
-    super();
-    this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshClick, this);
-    this._refreshButton.setEnabled(false);
-
-    this._eventListenersView = new EventListeners.EventListenersView(this.update.bind(this));
-    this._eventListenersView.show(this.element);
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  toolbarItems() {
-    return [this._refreshButton];
-  }
-
-  update() {
-    if (this._lastRequestedContext) {
-      this._lastRequestedContext.runtimeModel.releaseObjectGroup(
-          BrowserDebugger.ObjectEventListenersSidebarPane._objectGroupName);
-      delete this._lastRequestedContext;
-    }
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext) {
-      this._eventListenersView.reset();
-      this._eventListenersView.addEmptyHolderIfNeeded();
-      return;
-    }
-    this._lastRequestedContext = executionContext;
-    Promise.all([this._windowObjectInContext(executionContext)])
-        .then(this._eventListenersView.addObjects.bind(this._eventListenersView));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    UI.context.addFlavorChangeListener(SDK.ExecutionContext, this.update, this);
-    this._refreshButton.setEnabled(true);
-    this.update();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-    UI.context.removeFlavorChangeListener(SDK.ExecutionContext, this.update, this);
-    this._refreshButton.setEnabled(false);
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {!Promise<?SDK.RemoteObject>} object
-   */
-  _windowObjectInContext(executionContext) {
-    return executionContext
-        .evaluate(
-            {
-              expression: 'self',
-              objectGroup: BrowserDebugger.ObjectEventListenersSidebarPane._objectGroupName,
-              includeCommandLineAPI: false,
-              silent: true,
-              returnByValue: false,
-              generatePreview: false
-            },
-            /* userGesture */ false,
-            /* awaitPromise */ false)
-        .then(result => result.object && !result.exceptionDetails ? result.object : null);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _refreshClick(event) {
-    event.data.consume();
-    this.update();
-  }
-};
-
-BrowserDebugger.ObjectEventListenersSidebarPane._objectGroupName = 'object-event-listeners-sidebar-pane';
diff --git a/front_end/browser_debugger/XHRBreakpointsSidebarPane.js b/front_end/browser_debugger/XHRBreakpointsSidebarPane.js
deleted file mode 100644
index 2de8ea2..0000000
--- a/front_end/browser_debugger/XHRBreakpointsSidebarPane.js
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.ContextFlavorListener}
- * @implements {UI.ToolbarItem.ItemsProvider}
- * @unrestricted
- */
-BrowserDebugger.XHRBreakpointsSidebarPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('browser_debugger/xhrBreakpointsSidebarPane.css');
-
-    this._listElement = this.contentElement.createChild('div', 'breakpoint-list hidden');
-    this._emptyElement = this.contentElement.createChild('div', 'gray-info-message');
-    this._emptyElement.textContent = Common.UIString('No breakpoints');
-
-    /** @type {!Map.<string, !Element>} */
-    this._breakpointElements = new Map();
-
-    this._addButton = new UI.ToolbarButton(Common.UIString('Add breakpoint'), 'largeicon-add');
-    this._addButton.addEventListener(UI.ToolbarButton.Events.Click, this._addButtonClicked.bind(this));
-
-    this._emptyElement.addEventListener('contextmenu', this._emptyElementContextMenu.bind(this), true);
-    this._restoreBreakpoints();
-    this._update();
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  toolbarItems() {
-    return [this._addButton];
-  }
-
-  _emptyElementContextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Add breakpoint'), this._addButtonClicked.bind(this));
-    contextMenu.show();
-  }
-
-  _addButtonClicked() {
-    UI.viewManager.showView('sources.xhrBreakpoints');
-
-    const inputElementContainer = createElementWithClass('p', 'breakpoint-condition');
-    inputElementContainer.textContent = Common.UIString('Break when URL contains:');
-
-    const inputElement = inputElementContainer.createChild('span', 'breakpoint-condition-input');
-    this._addListElement(inputElementContainer, /** @type {?Element} */ (this._listElement.firstChild));
-
-    /**
-     * @param {boolean} accept
-     * @param {!Element} e
-     * @param {string} text
-     * @this {BrowserDebugger.XHRBreakpointsSidebarPane}
-     */
-    function finishEditing(accept, e, text) {
-      this._removeListElement(inputElementContainer);
-      if (accept) {
-        SDK.domDebuggerManager.addXHRBreakpoint(text, true);
-        this._setBreakpoint(text, true);
-      }
-    }
-
-    const config = new UI.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
-    UI.InplaceEditor.startEditing(inputElement, config);
-  }
-
-  /**
-   * @param {string} url
-   * @param {boolean} enabled
-   */
-  _setBreakpoint(url, enabled) {
-    if (this._breakpointElements.has(url)) {
-      this._breakpointElements.get(url)._checkboxElement.checked = enabled;
-      return;
-    }
-
-    const element = createElementWithClass('div', 'breakpoint-entry');
-    element._url = url;
-    element.addEventListener('contextmenu', this._contextMenu.bind(this, url), true);
-
-    const title = url ? Common.UIString('URL contains "%s"', url) : Common.UIString('Any XHR or fetch');
-    const label = UI.CheckboxLabel.create(title, enabled);
-    element.appendChild(label);
-    label.checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, url), false);
-    element._checkboxElement = label.checkboxElement;
-
-    label.classList.add('cursor-auto');
-    label.textElement.addEventListener('dblclick', this._labelClicked.bind(this, url), false);
-
-    let currentElement = /** @type {?Element} */ (this._listElement.firstChild);
-    while (currentElement) {
-      if (currentElement._url && currentElement._url < element._url)
-        break;
-      currentElement = /** @type {?Element} */ (currentElement.nextSibling);
-    }
-    this._addListElement(element, currentElement);
-    this._breakpointElements.set(url, element);
-  }
-
-  /**
-   * @param {string} url
-   */
-  _removeBreakpoint(url) {
-    const element = this._breakpointElements.get(url);
-    if (!element)
-      return;
-
-    this._removeListElement(element);
-    this._breakpointElements.delete(url);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {?Node} beforeNode
-   */
-  _addListElement(element, beforeNode) {
-    this._listElement.insertBefore(element, beforeNode);
-    this._emptyElement.classList.add('hidden');
-    this._listElement.classList.remove('hidden');
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  _removeListElement(element) {
-    this._listElement.removeChild(element);
-    if (!this._listElement.firstChild) {
-      this._emptyElement.classList.remove('hidden');
-      this._listElement.classList.add('hidden');
-    }
-  }
-
-  _contextMenu(url, event) {
-    const contextMenu = new UI.ContextMenu(event);
-
-    /**
-     * @this {BrowserDebugger.XHRBreakpointsSidebarPane}
-     */
-    function removeBreakpoint() {
-      SDK.domDebuggerManager.removeXHRBreakpoint(url);
-      this._removeBreakpoint(url);
-    }
-
-    /**
-     * @this {BrowserDebugger.XHRBreakpointsSidebarPane}
-     */
-    function removeAllBreakpoints() {
-      for (const url of this._breakpointElements.keys()) {
-        SDK.domDebuggerManager.removeXHRBreakpoint(url);
-        this._removeBreakpoint(url);
-      }
-    }
-    const removeAllTitle = Common.UIString('Remove all breakpoints');
-
-    contextMenu.defaultSection().appendItem(Common.UIString('Add breakpoint'), this._addButtonClicked.bind(this));
-    contextMenu.defaultSection().appendItem(Common.UIString('Remove breakpoint'), removeBreakpoint.bind(this));
-    contextMenu.defaultSection().appendItem(removeAllTitle, removeAllBreakpoints.bind(this));
-    contextMenu.show();
-  }
-
-  _checkboxClicked(url, event) {
-    SDK.domDebuggerManager.toggleXHRBreakpoint(url, event.target.checked);
-  }
-
-  _labelClicked(url) {
-    const element = this._breakpointElements.get(url) || null;
-    const inputElement = createElementWithClass('span', 'breakpoint-condition');
-    inputElement.textContent = url;
-    this._listElement.insertBefore(inputElement, element);
-    element.classList.add('hidden');
-
-    /**
-     * @param {boolean} accept
-     * @param {!Element} e
-     * @param {string} text
-     * @this {BrowserDebugger.XHRBreakpointsSidebarPane}
-     */
-    function finishEditing(accept, e, text) {
-      this._removeListElement(inputElement);
-      if (accept) {
-        SDK.domDebuggerManager.removeXHRBreakpoint(url);
-        this._removeBreakpoint(url);
-        const enabled = element ? element._checkboxElement.checked : true;
-        SDK.domDebuggerManager.addXHRBreakpoint(text, enabled);
-        this._setBreakpoint(text, enabled);
-      } else {
-        element.classList.remove('hidden');
-      }
-    }
-
-    UI.InplaceEditor.startEditing(
-        inputElement, new UI.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false)));
-  }
-
-  /**
-   * @override
-   * @param {?Object} object
-   */
-  flavorChanged(object) {
-    this._update();
-  }
-
-  _update() {
-    const details = UI.context.flavor(SDK.DebuggerPausedDetails);
-    if (!details || details.reason !== SDK.DebuggerModel.BreakReason.XHR) {
-      if (this._highlightedElement) {
-        this._highlightedElement.classList.remove('breakpoint-hit');
-        delete this._highlightedElement;
-      }
-      return;
-    }
-    const url = details.auxData['breakpointURL'];
-    const element = this._breakpointElements.get(url);
-    if (!element)
-      return;
-    UI.viewManager.showView('sources.xhrBreakpoints');
-    element.classList.add('breakpoint-hit');
-    this._highlightedElement = element;
-  }
-
-  _restoreBreakpoints() {
-    const breakpoints = SDK.domDebuggerManager.xhrBreakpoints();
-    for (const url of breakpoints.keys())
-      this._setBreakpoint(url, breakpoints.get(url));
-  }
-};
diff --git a/front_end/browser_debugger/domBreakpointsSidebarPane.css b/front_end/browser_debugger/domBreakpointsSidebarPane.css
deleted file mode 100644
index e58d820..0000000
--- a/front_end/browser_debugger/domBreakpointsSidebarPane.css
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.breakpoint-list {
-    padding-bottom: 3px;
-}
-
-.breakpoint-list .dom-breakpoint > div {
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.breakpoint-entry {
-    display: flex;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    padding: 2px 0;
-}
-
-.breakpoint-list .breakpoint-entry:hover {
-    background-color: #eee;
-}
-
-.breakpoint-hit {
-    background-color: rgb(255, 255, 194);
-}
-
-:host-context(.-theme-with-dark-background) .breakpoint-hit {
-    background-color: hsl(46, 98%, 22%);
-    color: #ccc;
-}
diff --git a/front_end/browser_debugger/eventListenerBreakpoints.css b/front_end/browser_debugger/eventListenerBreakpoints.css
deleted file mode 100644
index fe842e2..0000000
--- a/front_end/browser_debugger/eventListenerBreakpoints.css
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    margin: 0;
-    padding: 2px 4px;
-    min-height: 18px;
-}
-
-.tree-outline {
-    padding: 0;
-}
-
-.tree-outline li {
-    margin-left: 14px;
-    -webkit-user-select: text;
-    cursor: default;
-}
-
-.tree-outline li.parent {
-    margin-left: 1px;
-}
-
-.tree-outline li:not(.parent)::before {
-    display: none;
-}
-
-.breakpoint-hit {
-    background-color: rgb(255, 255, 194);
-}
-
-:host-context(.-theme-with-dark-background) .breakpoint-hit {
-    background-color: hsl(46, 98%, 22%);
-    color: #ccc;
-}
-
-.breakpoint-hit .breakpoint-hit-marker {
-    background-color: rgb(255, 255, 194);
-    height: 18px;
-    left: 0;
-    margin-left: -30px;
-    position: absolute;
-    right: -4px;
-    z-index: -1;
-}
diff --git a/front_end/browser_debugger/module.json b/front_end/browser_debugger/module.json
deleted file mode 100644
index 10f1b3d..0000000
--- a/front_end/browser_debugger/module.json
+++ /dev/null
@@ -1,104 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "sources-sidebar",
-            "id": "sources.eventListenerBreakpoints",
-            "title": "Event Listener Breakpoints",
-            "order": 9,
-            "persistence": "permanent",
-            "className": "BrowserDebugger.EventListenerBreakpointsSidebarPane"
-        },
-        {
-            "type": "@UI.ContextFlavorListener",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "className": "BrowserDebugger.XHRBreakpointsSidebarPane"
-        },
-        {
-            "type": "view",
-            "location": "sources-sidebar",
-            "id": "sources.xhrBreakpoints",
-            "title": "XHR/fetch Breakpoints",
-            "order": 5,
-            "hasToolbar": true,
-            "persistence": "permanent",
-            "className": "BrowserDebugger.XHRBreakpointsSidebarPane"
-        },
-        {
-            "type": "view",
-            "location": "sources-sidebar",
-            "id": "sources.domBreakpoints",
-            "title": "DOM Breakpoints",
-            "order": 7,
-            "persistence": "permanent",
-            "factoryName": "BrowserDebugger.DOMBreakpointsSidebarPane"
-        },
-        {
-            "type": "view",
-            "location": "elements-sidebar",
-            "id": "elements.domBreakpoints",
-            "title": "DOM Breakpoints",
-            "order": 6,
-            "persistence": "permanent",
-            "factoryName": "BrowserDebugger.DOMBreakpointsSidebarPane"
-        },
-        {
-            "type": "@Elements.MarkerDecorator",
-            "factoryName": "Elements.GenericDecorator",
-            "marker": "breakpoint-marker",
-            "title": "DOM Breakpoint",
-            "color": "rgb(105, 140, 254)"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "SDK.DOMNode"
-            ],
-            "className": "BrowserDebugger.DOMBreakpointsSidebarPane.ContextMenuProvider"
-        },
-        {
-            "type": "@UI.ContextFlavorListener",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "className": "BrowserDebugger.DOMBreakpointsSidebarPane"
-        },
-        {
-            "type": "view",
-            "location": "sources-sidebar",
-            "id": "sources.globalListeners",
-            "title": "Global Listeners",
-            "order": 8,
-            "hasToolbar": true,
-            "persistence": "permanent",
-            "className": "BrowserDebugger.ObjectEventListenersSidebarPane"
-        },
-        {
-            "type": "view",
-            "location": "navigator-view",
-            "id": "navigator-network",
-            "title": "Page",
-            "order": 2,
-            "persistence": "permanent",
-            "className": "Sources.NetworkNavigatorView"
-        }
-    ],
-    "dependencies": [
-        "elements",
-        "sources",
-        "console"
-    ],
-    "scripts": [
-        "DOMBreakpointsSidebarPane.js",
-        "EventListenerBreakpointsSidebarPane.js",
-        "ObjectEventListenersSidebarPane.js",
-        "XHRBreakpointsSidebarPane.js"
-    ],
-    "resources": [
-        "domBreakpointsSidebarPane.css",
-        "eventListenerBreakpoints.css",
-        "xhrBreakpointsSidebarPane.css"
-    ]
-}
diff --git a/front_end/browser_debugger/xhrBreakpointsSidebarPane.css b/front_end/browser_debugger/xhrBreakpointsSidebarPane.css
deleted file mode 100644
index 317bf57..0000000
--- a/front_end/browser_debugger/xhrBreakpointsSidebarPane.css
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.breakpoint-list {
-    padding-bottom: 3px;
-}
-
-.breakpoint-list .editing.being-edited {
-    overflow: hidden;
-    white-space: nowrap;
-}
-
-.breakpoint-condition {
-    display: block;
-    margin-top: 4px;
-    margin-bottom: 4px;
-    margin-left: 23px;
-    margin-right: 8px;
-}
-
-.breakpoint-condition-input {
-    display: block;
-    margin-left: 0;
-    margin-right: 0;
-    outline: none !important;
-    border: 1px solid rgb(66%, 66%, 66%);
-}
-
-.breakpoint-entry {
-    white-space: nowrap;
-    padding: 2px 0;
-}
-
-.breakpoint-list .breakpoint-entry:hover {
-    background-color: #eee;
-}
-
-.breakpoint-entry [is=dt-checkbox] {
-    max-width: 100%;
-}
-
-.breakpoint-hit {
-    background-color: rgb(255, 255, 194);
-}
-
-:host-context(.-theme-with-dark-background) .breakpoint-hit {
-    background-color: hsl(46, 98%, 22%);
-    color: #ccc;
-}
diff --git a/front_end/browser_sdk/HAREntry.js b/front_end/browser_sdk/HAREntry.js
deleted file mode 100644
index cf90721..0000000
--- a/front_end/browser_sdk/HAREntry.js
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// See http://www.softwareishard.com/blog/har-12-spec/
-// for HAR specification.
-
-// FIXME: Some fields are not yet supported due to back-end limitations.
-// See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.
-
-/**
- * @unrestricted
- */
-BrowserSDK.HAREntry = class {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    this._request = request;
-  }
-
-  /**
-   * @param {number} time
-   * @return {number}
-   */
-  static _toMilliseconds(time) {
-    return time === -1 ? -1 : time * 1000;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<!Object>}
-   */
-  static async build(request) {
-    const harEntry = new BrowserSDK.HAREntry(request);
-    let ipAddress = harEntry._request.remoteAddress();
-    const portPositionInString = ipAddress.lastIndexOf(':');
-    if (portPositionInString !== -1)
-      ipAddress = ipAddress.substr(0, portPositionInString);
-
-    const timings = harEntry._buildTimings();
-    let time = 0;
-    // "ssl" is included in the connect field, so do not double count it.
-    for (const t of [timings.blocked, timings.dns, timings.connect, timings.send, timings.wait, timings.receive])
-      time += Math.max(t, 0);
-
-    const entry = {
-      startedDateTime: BrowserSDK.HARLog.pseudoWallTime(harEntry._request, harEntry._request.issueTime()).toJSON(),
-      time: time,
-      request: await harEntry._buildRequest(),
-      response: harEntry._buildResponse(),
-      cache: {},  // Not supported yet.
-      timings: timings,
-      // IPv6 address should not have square brackets per (https://tools.ietf.org/html/rfc2373#section-2.2).
-      serverIPAddress: ipAddress.replace(/\[\]/g, '')
-    };
-
-    // Chrome specific.
-    if (harEntry._request.cached())
-      entry._fromCache = harEntry._request.cachedInMemory() ? 'memory' : 'disk';
-
-    if (harEntry._request.connectionId !== '0')
-      entry.connection = harEntry._request.connectionId;
-    const page = BrowserSDK.PageLoad.forRequest(harEntry._request);
-    if (page)
-      entry.pageref = 'page_' + page.id;
-    return entry;
-  }
-
-  /**
-   * @return {!Promise<!Object>}
-   */
-  async _buildRequest() {
-    const headersText = this._request.requestHeadersText();
-    const res = {
-      method: this._request.requestMethod,
-      url: this._buildRequestURL(this._request.url()),
-      httpVersion: this._request.requestHttpVersion(),
-      headers: this._request.requestHeaders(),
-      queryString: this._buildParameters(this._request.queryParameters || []),
-      cookies: this._buildCookies(this._request.requestCookies || []),
-      headersSize: headersText ? headersText.length : -1,
-      bodySize: this.requestBodySize
-    };
-    const postData = await this._buildPostData();
-    if (postData)
-      res.postData = postData;
-
-    return res;
-  }
-
-  /**
-   * @return {!Object}
-   */
-  _buildResponse() {
-    const headersText = this._request.responseHeadersText;
-    return {
-      status: this._request.statusCode,
-      statusText: this._request.statusText,
-      httpVersion: this._request.responseHttpVersion(),
-      headers: this._request.responseHeaders,
-      cookies: this._buildCookies(this._request.responseCookies || []),
-      content: this._buildContent(),
-      redirectURL: this._request.responseHeaderValue('Location') || '',
-      headersSize: headersText ? headersText.length : -1,
-      bodySize: this.responseBodySize,
-      _transferSize: this._request.transferSize,
-      _error: this._request.localizedFailDescription
-    };
-  }
-
-  /**
-   * @return {!Object}
-   */
-  _buildContent() {
-    const content = {
-      size: this._request.resourceSize,
-      mimeType: this._request.mimeType || 'x-unknown',
-      // text: this._request.content // TODO: pull out into a boolean flag, as content can be huge (and needs to be requested with an async call)
-    };
-    const compression = this.responseCompression;
-    if (typeof compression === 'number')
-      content.compression = compression;
-    return content;
-  }
-
-  /**
-   * @return {!BrowserSDK.HAREntry.Timing}
-   */
-  _buildTimings() {
-    // Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], duration
-    const timing = this._request.timing;
-    const issueTime = this._request.issueTime();
-    const startTime = this._request.startTime;
-
-    const result = {blocked: -1, dns: -1, ssl: -1, connect: -1, send: 0, wait: 0, receive: 0, _blocked_queueing: -1};
-
-    const queuedTime = (issueTime < startTime) ? startTime - issueTime : -1;
-    result.blocked = queuedTime;
-    result._blocked_queueing = BrowserSDK.HAREntry._toMilliseconds(queuedTime);
-
-    let highestTime = 0;
-    if (timing) {
-      // "blocked" here represents both queued + blocked/stalled + proxy (ie: anything before request was started).
-      // We pick the better of when the network request start was reported and pref timing.
-      const blockedStart = leastNonNegative([timing.dnsStart, timing.connectStart, timing.sendStart]);
-      if (blockedStart !== Infinity)
-        result.blocked += blockedStart;
-
-      // Proxy is part of blocked but sometimes (like quic) blocked is -1 but has proxy timings.
-      if (timing.proxyEnd !== -1)
-        result._blocked_proxy = timing.proxyEnd - timing.proxyStart;
-      if (result._blocked_proxy && result._blocked_proxy > result.blocked)
-        result.blocked = result._blocked_proxy;
-
-      const dnsStart = timing.dnsEnd >= 0 ? blockedStart : 0;
-      const dnsEnd = timing.dnsEnd >= 0 ? timing.dnsEnd : -1;
-      result.dns = dnsEnd - dnsStart;
-
-      // SSL timing is included in connection timing.
-      const sslStart = timing.sslEnd > 0 ? timing.sslStart : 0;
-      const sslEnd = timing.sslEnd > 0 ? timing.sslEnd : -1;
-      result.ssl = sslEnd - sslStart;
-
-      const connectStart = timing.connectEnd >= 0 ? leastNonNegative([dnsEnd, blockedStart]) : 0;
-      const connectEnd = timing.connectEnd >= 0 ? timing.connectEnd : -1;
-      result.connect = connectEnd - connectStart;
-
-      // Send should not be -1 for legacy reasons even if it is served from cache.
-      const sendStart = timing.sendEnd >= 0 ? Math.max(connectEnd, dnsEnd, blockedStart) : 0;
-      const sendEnd = timing.sendEnd >= 0 ? timing.sendEnd : 0;
-      result.send = sendEnd - sendStart;
-      // Quic sometimes says that sendStart is before connectionEnd (see: crbug.com/740792)
-      if (result.send < 0)
-        result.send = 0;
-      highestTime = Math.max(sendEnd, connectEnd, sslEnd, dnsEnd, blockedStart, 0);
-    } else if (this._request.responseReceivedTime === -1) {
-      // Means that we don't have any more details after blocked, so attribute all to blocked.
-      result.blocked = this._request.endTime - issueTime;
-      return result;
-    }
-
-    const requestTime = timing ? timing.requestTime : startTime;
-    const waitStart = highestTime;
-    const waitEnd = BrowserSDK.HAREntry._toMilliseconds(this._request.responseReceivedTime - requestTime);
-    result.wait = waitEnd - waitStart;
-
-    const receiveStart = waitEnd;
-    const receiveEnd = BrowserSDK.HAREntry._toMilliseconds(this._request.endTime - issueTime);
-    result.receive = Math.max(receiveEnd - receiveStart, 0);
-
-    return result;
-
-    /**
-     * @param {!Array<number>} values
-     * @return {number}
-     */
-    function leastNonNegative(values) {
-      return values.reduce((best, value) => (value >= 0 && value < best) ? value : best, Infinity);
-    }
-  }
-
-  /**
-   * @return {!Promise<!Object>}
-   */
-  async _buildPostData() {
-    const postData = await this._request.requestFormData();
-    if (!postData)
-      return null;
-    const res = {mimeType: this._request.requestContentType(), text: postData};
-    const formParameters = await this._request.formParameters();
-    if (formParameters)
-      res.params = this._buildParameters(formParameters);
-    return res;
-  }
-
-  /**
-   * @param {!Array.<!Object>} parameters
-   * @return {!Array.<!Object>}
-   */
-  _buildParameters(parameters) {
-    return parameters.slice();
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  _buildRequestURL(url) {
-    return url.split('#', 2)[0];
-  }
-
-  /**
-   * @param {!Array.<!SDK.Cookie>} cookies
-   * @return {!Array.<!Object>}
-   */
-  _buildCookies(cookies) {
-    return cookies.map(this._buildCookie.bind(this));
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookie
-   * @return {!Object}
-   */
-  _buildCookie(cookie) {
-    const c = {
-      name: cookie.name(),
-      value: cookie.value(),
-      path: cookie.path(),
-      domain: cookie.domain(),
-      expires: cookie.expiresDate(BrowserSDK.HARLog.pseudoWallTime(this._request, this._request.startTime)),
-      httpOnly: cookie.httpOnly(),
-      secure: cookie.secure()
-    };
-    if (cookie.sameSite())
-      c.sameSite = cookie.sameSite();
-    return c;
-  }
-
-  /**
-   * @return {number}
-   */
-  get requestBodySize() {
-    return !this._request.requestFormData ? 0 : this._request.requestFormData.length;
-  }
-
-  /**
-   * @return {number}
-   */
-  get responseBodySize() {
-    if (this._request.cached() || this._request.statusCode === 304)
-      return 0;
-    if (!this._request.responseHeadersText)
-      return -1;
-    return this._request.transferSize - this._request.responseHeadersText.length;
-  }
-
-  /**
-   * @return {number|undefined}
-   */
-  get responseCompression() {
-    if (this._request.cached() || this._request.statusCode === 304 || this._request.statusCode === 206)
-      return;
-    if (!this._request.responseHeadersText)
-      return;
-    return this._request.resourceSize - this.responseBodySize;
-  }
-};
-
-/** @typedef {!{
-  blocked: number,
-  dns: number,
-  ssl: number,
-  connect: number,
-  send: number,
-  wait: number,
-  receive: number,
-  _blocked_queueing: number,
-  _blocked_proxy: (number|undefined)
-}} */
-BrowserSDK.HAREntry.Timing;
-
-
-/**
- * @unrestricted
- */
-BrowserSDK.HARLog = class {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {number} monotonicTime
-   * @return {!Date}
-   */
-  static pseudoWallTime(request, monotonicTime) {
-    return new Date(request.pseudoWallTime(monotonicTime) * 1000);
-  }
-
-  /**
-   * @param {!Array.<!SDK.NetworkRequest>} requests
-   * @return {!Promise<!Object>}
-   */
-  static async build(requests) {
-    const log = new BrowserSDK.HARLog();
-    const entryPromises = [];
-    for (const request of requests)
-      entryPromises.push(BrowserSDK.HAREntry.build(request));
-    const entries = await Promise.all(entryPromises);
-    return {version: '1.2', creator: log._creator(), pages: log._buildPages(requests), entries: entries};
-  }
-
-  _creator() {
-    const webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);
-
-    return {name: 'WebInspector', version: webKitVersion ? webKitVersion[1] : 'n/a'};
-  }
-
-  /**
-   * @param {!Array.<!SDK.NetworkRequest>} requests
-   * @return {!Array.<!Object>}
-   */
-  _buildPages(requests) {
-    const seenIdentifiers = {};
-    const pages = [];
-    for (let i = 0; i < requests.length; ++i) {
-      const request = requests[i];
-      const page = BrowserSDK.PageLoad.forRequest(request);
-      if (!page || seenIdentifiers[page.id])
-        continue;
-      seenIdentifiers[page.id] = true;
-      pages.push(this._convertPage(page, request));
-    }
-    return pages;
-  }
-
-  /**
-   * @param {!BrowserSDK.PageLoad} page
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Object}
-   */
-  _convertPage(page, request) {
-    return {
-      startedDateTime: BrowserSDK.HARLog.pseudoWallTime(request, page.startTime).toJSON(),
-      id: 'page_' + page.id,
-      title: page.url,  // We don't have actual page title here. URL is probably better than nothing.
-      pageTimings: {
-        onContentLoad: this._pageEventTime(page, page.contentLoadTime),
-        onLoad: this._pageEventTime(page, page.loadTime)
-      }
-    };
-  }
-
-  /**
-   * @param {!BrowserSDK.PageLoad} page
-   * @param {number} time
-   * @return {number}
-   */
-  _pageEventTime(page, time) {
-    const startTime = page.startTime;
-    if (time === -1 || startTime === -1)
-      return -1;
-    return BrowserSDK.HAREntry._toMilliseconds(time - startTime);
-  }
-};
diff --git a/front_end/browser_sdk/LogManager.js b/front_end/browser_sdk/LogManager.js
deleted file mode 100644
index 0681aa9..0000000
--- a/front_end/browser_sdk/LogManager.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.LogModel>}
- */
-BrowserSDK.LogManager = class {
-  constructor() {
-    SDK.targetManager.observeModels(SDK.LogModel, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.LogModel} logModel
-   */
-  modelAdded(logModel) {
-    const eventListeners = [];
-    eventListeners.push(logModel.addEventListener(SDK.LogModel.Events.EntryAdded, this._logEntryAdded, this));
-    logModel[BrowserSDK.LogManager._eventSymbol] = eventListeners;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.LogModel} logModel
-   */
-  modelRemoved(logModel) {
-    Common.EventTarget.removeEventListeners(logModel[BrowserSDK.LogManager._eventSymbol]);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _logEntryAdded(event) {
-    const data = /** @type {{logModel: !SDK.LogModel, entry: !Protocol.Log.LogEntry}} */ (event.data);
-    const target = data.logModel.target();
-
-    const consoleMessage = new SDK.ConsoleMessage(
-        target.model(SDK.RuntimeModel), data.entry.source, data.entry.level, data.entry.text, undefined, data.entry.url,
-        data.entry.lineNumber, undefined, [data.entry.text, ...(data.entry.args || [])], data.entry.stackTrace,
-        data.entry.timestamp, undefined, undefined, data.entry.workerId);
-
-    if (data.entry.networkRequestId)
-      BrowserSDK.networkLog.associateConsoleMessageWithRequest(consoleMessage, data.entry.networkRequestId);
-    SDK.consoleModel.addMessage(consoleMessage);
-  }
-};
-
-BrowserSDK.LogManager._eventSymbol = Symbol('_events');
-
-new BrowserSDK.LogManager();
diff --git a/front_end/browser_sdk/NetworkLog.js b/front_end/browser_sdk/NetworkLog.js
deleted file mode 100644
index 2baf45b..0000000
--- a/front_end/browser_sdk/NetworkLog.js
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.NetworkManager>}
- */
-BrowserSDK.NetworkLog = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!Array<!SDK.NetworkRequest>} */
-    this._requests = [];
-    /** @type {!Set<!SDK.NetworkRequest>} */
-    this._requestsSet = new Set();
-    /** @type {!Map<!SDK.NetworkManager, !BrowserSDK.PageLoad>} */
-    this._pageLoadForManager = new Map();
-    this._isRecording = true;
-    SDK.targetManager.observeModels(SDK.NetworkManager, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager} networkManager
-   */
-  modelAdded(networkManager) {
-    const eventListeners = [];
-    eventListeners.push(
-        networkManager.addEventListener(SDK.NetworkManager.Events.RequestStarted, this._onRequestStarted, this));
-    eventListeners.push(
-        networkManager.addEventListener(SDK.NetworkManager.Events.RequestUpdated, this._onRequestUpdated, this));
-    eventListeners.push(
-        networkManager.addEventListener(SDK.NetworkManager.Events.RequestRedirected, this._onRequestRedirect, this));
-    eventListeners.push(
-        networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, this._onRequestUpdated, this));
-    eventListeners.push(networkManager.addEventListener(
-        SDK.NetworkManager.Events.MessageGenerated, this._networkMessageGenerated.bind(this, networkManager)));
-
-    const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
-    if (resourceTreeModel) {
-      eventListeners.push(
-          resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.WillReloadPage, this._willReloadPage, this));
-      eventListeners.push(resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this));
-      eventListeners.push(resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, this._onLoad, this));
-      eventListeners.push(resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.DOMContentLoaded, this._onDOMContentLoaded.bind(this, resourceTreeModel)));
-    }
-
-    networkManager[BrowserSDK.NetworkLog._events] = eventListeners;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager} networkManager
-   */
-  modelRemoved(networkManager) {
-    this._removeNetworkManagerListeners(networkManager);
-  }
-
-  /**
-   * @param {!SDK.NetworkManager} networkManager
-   */
-  _removeNetworkManagerListeners(networkManager) {
-    Common.EventTarget.removeEventListeners(networkManager[BrowserSDK.NetworkLog._events]);
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setIsRecording(enabled) {
-    if (this._isRecording === enabled)
-      return;
-    this._isRecording = enabled;
-    if (enabled) {
-      SDK.targetManager.observeModels(SDK.NetworkManager, this);
-    } else {
-      SDK.targetManager.unobserveModels(SDK.NetworkManager, this);
-      SDK.targetManager.models(SDK.NetworkManager).forEach(this._removeNetworkManagerListeners.bind(this));
-    }
-  }
-
-  /**
-   * @param {string} url
-   * @return {?SDK.NetworkRequest}
-   */
-  requestForURL(url) {
-    return this._requests.find(request => request.url() === url) || null;
-  }
-
-  /**
-   * @return {!Array<!SDK.NetworkRequest>}
-   */
-  requests() {
-    return this._requests;
-  }
-
-  /**
-   * @param {!SDK.NetworkManager} networkManager
-   * @param {!Protocol.Network.RequestId} requestId
-   * @return {?SDK.NetworkRequest}
-   */
-  requestByManagerAndId(networkManager, requestId) {
-    // We itterate backwards because the last item will likely be the one needed for console network request lookups.
-    for (let i = this._requests.length - 1; i >= 0; i--) {
-      const request = this._requests[i];
-      if (requestId === request.requestId() && networkManager === SDK.NetworkManager.forRequest(request))
-        return request;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.NetworkManager} networkManager
-   * @param {string} url
-   * @return {?SDK.NetworkRequest}
-   */
-  _requestByManagerAndURL(networkManager, url) {
-    for (const request of this._requests) {
-      if (url === request.url() && networkManager === SDK.NetworkManager.forRequest(request))
-        return request;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  _initializeInitiatorSymbolIfNeeded(request) {
-    if (!request[BrowserSDK.NetworkLog._initiatorDataSymbol]) {
-      /** @type {!{info: ?BrowserSDK.NetworkLog._InitiatorInfo, chain: !Set<!SDK.NetworkRequest>, request: (?SDK.NetworkRequest|undefined)}} */
-      request[BrowserSDK.NetworkLog._initiatorDataSymbol] = {
-        info: null,
-        chain: null,
-        request: undefined,
-      };
-    }
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!BrowserSDK.NetworkLog._InitiatorInfo}
-   */
-  initiatorInfoForRequest(request) {
-    this._initializeInitiatorSymbolIfNeeded(request);
-    if (request[BrowserSDK.NetworkLog._initiatorDataSymbol].info)
-      return request[BrowserSDK.NetworkLog._initiatorDataSymbol].info;
-
-    let type = SDK.NetworkRequest.InitiatorType.Other;
-    let url = '';
-    let lineNumber = -Infinity;
-    let columnNumber = -Infinity;
-    let scriptId = null;
-    let initiatorStack = null;
-    const initiator = request.initiator();
-
-    const redirectSource = request.redirectSource();
-    if (redirectSource) {
-      type = SDK.NetworkRequest.InitiatorType.Redirect;
-      url = redirectSource.url();
-    } else if (initiator) {
-      if (initiator.type === Protocol.Network.InitiatorType.Parser) {
-        type = SDK.NetworkRequest.InitiatorType.Parser;
-        url = initiator.url ? initiator.url : url;
-        lineNumber = initiator.lineNumber ? initiator.lineNumber : lineNumber;
-      } else if (initiator.type === Protocol.Network.InitiatorType.Script) {
-        for (let stack = initiator.stack; stack; stack = stack.parent) {
-          const topFrame = stack.callFrames.length ? stack.callFrames[0] : null;
-          if (!topFrame)
-            continue;
-          type = SDK.NetworkRequest.InitiatorType.Script;
-          url = topFrame.url || Common.UIString('<anonymous>');
-          lineNumber = topFrame.lineNumber;
-          columnNumber = topFrame.columnNumber;
-          scriptId = topFrame.scriptId;
-          break;
-        }
-        if (!initiator.stack && initiator.url) {
-          type = SDK.NetworkRequest.InitiatorType.Script;
-          url = initiator.url;
-          lineNumber = initiator.lineNumber || 0;
-        }
-        if (initiator.stack && initiator.stack.callFrames && initiator.stack.callFrames.length)
-          initiatorStack = initiator.stack || null;
-      } else if (initiator.type === Protocol.Network.InitiatorType.Preload) {
-        type = SDK.NetworkRequest.InitiatorType.Preload;
-      }
-    }
-
-    request[BrowserSDK.NetworkLog._initiatorDataSymbol].info = {
-      type: type,
-      url: url,
-      lineNumber: lineNumber,
-      columnNumber: columnNumber,
-      scriptId: scriptId,
-      stack: initiatorStack
-    };
-    return request[BrowserSDK.NetworkLog._initiatorDataSymbol].info;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!BrowserSDK.NetworkLog.InitiatorGraph}
-   */
-  initiatorGraphForRequest(request) {
-    /** @type {!Set<!SDK.NetworkRequest>} */
-    const initiated = new Set();
-    const networkManager = SDK.NetworkManager.forRequest(request);
-    for (const otherRequest of this._requests) {
-      const otherRequestManager = SDK.NetworkManager.forRequest(request);
-      if (networkManager === otherRequestManager && this._initiatorChain(otherRequest).has(request))
-        initiated.add(otherRequest);
-    }
-    return {initiators: this._initiatorChain(request), initiated: initiated};
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Set<!SDK.NetworkRequest>}
-   */
-  _initiatorChain(request) {
-    this._initializeInitiatorSymbolIfNeeded(request);
-    let initiatorChainCache =
-        /** @type {?Set<!SDK.NetworkRequest>} */ (request[BrowserSDK.NetworkLog._initiatorDataSymbol].chain);
-    if (initiatorChainCache)
-      return initiatorChainCache;
-
-    initiatorChainCache = new Set();
-
-    let checkRequest = request;
-    do {
-      if (checkRequest[BrowserSDK.NetworkLog._initiatorDataSymbol].chain) {
-        initiatorChainCache.addAll(checkRequest[BrowserSDK.NetworkLog._initiatorDataSymbol].chain);
-        break;
-      }
-      if (initiatorChainCache.has(checkRequest))
-        break;
-      initiatorChainCache.add(checkRequest);
-      checkRequest = this._initiatorRequest(checkRequest);
-    } while (checkRequest);
-    request[BrowserSDK.NetworkLog._initiatorDataSymbol].chain = initiatorChainCache;
-    return initiatorChainCache;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?SDK.NetworkRequest}
-   */
-  _initiatorRequest(request) {
-    this._initializeInitiatorSymbolIfNeeded(request);
-    if (request[BrowserSDK.NetworkLog._initiatorDataSymbol].request !== undefined)
-      return request[BrowserSDK.NetworkLog._initiatorDataSymbol].request;
-    const url = this.initiatorInfoForRequest(request).url;
-    const networkManager = SDK.NetworkManager.forRequest(request);
-    request[BrowserSDK.NetworkLog._initiatorDataSymbol].request =
-        networkManager ? this._requestByManagerAndURL(networkManager, url) : null;
-    return request[BrowserSDK.NetworkLog._initiatorDataSymbol].request;
-  }
-
-  _willReloadPage() {
-    if (!Common.moduleSetting('network_log.preserve-log').get())
-      this.reset();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onMainFrameNavigated(event) {
-    const mainFrame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    const manager = mainFrame.resourceTreeModel().target().model(SDK.NetworkManager);
-    if (!manager || mainFrame.resourceTreeModel().target().parentTarget())
-      return;
-
-    const oldManagerRequests = this._requests.filter(request => SDK.NetworkManager.forRequest(request) === manager);
-    const oldRequestsSet = this._requestsSet;
-    this._requests = [];
-    this._requestsSet = new Set();
-    this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.Reset);
-
-    // Preserve requests from the new session.
-    let currentPageLoad = null;
-    const requestsToAdd = [];
-    for (const request of oldManagerRequests) {
-      if (request.loaderId !== mainFrame.loaderId)
-        continue;
-      if (!currentPageLoad) {
-        currentPageLoad = new BrowserSDK.PageLoad(request);
-        let redirectSource = request.redirectSource();
-        while (redirectSource) {
-          requestsToAdd.push(redirectSource);
-          redirectSource = redirectSource.redirectSource();
-        }
-      }
-      requestsToAdd.push(request);
-    }
-
-    for (const request of requestsToAdd) {
-      oldRequestsSet.delete(request);
-      this._requests.push(request);
-      this._requestsSet.add(request);
-      currentPageLoad.bindRequest(request);
-      this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
-    }
-
-    if (Common.moduleSetting('network_log.preserve-log').get()) {
-      for (const request of oldRequestsSet) {
-        this._requests.push(request);
-        this._requestsSet.add(request);
-        this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
-      }
-    }
-
-    if (currentPageLoad)
-      this._pageLoadForManager.set(manager, currentPageLoad);
-  }
-
-  /**
-   * @param {!Array<!SDK.NetworkRequest>} requests
-   */
-  importRequests(requests) {
-    this.reset();
-    this._requests = [];
-    this._requestsSet.clear();
-    for (const request of requests) {
-      this._requests.push(request);
-      this._requestsSet.add(request);
-      this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestStarted(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    this._requests.push(request);
-    this._requestsSet.add(request);
-    const manager = SDK.NetworkManager.forRequest(request);
-    const pageLoad = manager ? this._pageLoadForManager.get(manager) : null;
-    if (pageLoad)
-      pageLoad.bindRequest(request);
-    this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestUpdated(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    if (!this._requestsSet.has(request))
-      return;
-    this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestUpdated, request);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestRedirect(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    delete request[BrowserSDK.NetworkLog._initiatorDataSymbol];
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   * @param {!Common.Event} event
-   */
-  _onDOMContentLoaded(resourceTreeModel, event) {
-    const networkManager = resourceTreeModel.target().model(SDK.NetworkManager);
-    const pageLoad = networkManager ? this._pageLoadForManager.get(networkManager) : null;
-    if (pageLoad)
-      pageLoad.contentLoadTime = /** @type {number} */ (event.data);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onLoad(event) {
-    const networkManager = event.data.resourceTreeModel.target().model(SDK.NetworkManager);
-    const pageLoad = networkManager ? this._pageLoadForManager.get(networkManager) : null;
-    if (pageLoad)
-      pageLoad.loadTime = /** @type {number} */ (event.data.loadTime);
-  }
-
-  reset() {
-    this._requests = [];
-    this._requestsSet.clear();
-    const managers = new Set(SDK.targetManager.models(SDK.NetworkManager));
-    for (const manager of this._pageLoadForManager.keys()) {
-      if (!managers.has(manager))
-        this._pageLoadForManager.delete(manager);
-    }
-
-    this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.Reset);
-  }
-
-  /**
-   * @param {!SDK.NetworkManager} networkManager
-   * @param {!Common.Event} event
-   */
-  _networkMessageGenerated(networkManager, event) {
-    const message = /** @type {!SDK.NetworkManager.Message} */ (event.data);
-    const consoleMessage = new SDK.ConsoleMessage(
-        networkManager.target().model(SDK.RuntimeModel), SDK.ConsoleMessage.MessageSource.Network,
-        message.warning ? SDK.ConsoleMessage.MessageLevel.Warning : SDK.ConsoleMessage.MessageLevel.Info,
-        message.message);
-    this.associateConsoleMessageWithRequest(consoleMessage, message.requestId);
-    SDK.consoleModel.addMessage(consoleMessage);
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} consoleMessage
-   * @param {!Protocol.Network.RequestId} requestId
-   */
-  associateConsoleMessageWithRequest(consoleMessage, requestId) {
-    const target = consoleMessage.target();
-    const networkManager = target ? target.model(SDK.NetworkManager) : null;
-    if (!networkManager)
-      return;
-    const request = this.requestByManagerAndId(networkManager, requestId);
-    if (!request)
-      return;
-    consoleMessage[BrowserSDK.NetworkLog._requestSymbol] = request;
-    const initiator = request.initiator();
-    if (initiator) {
-      consoleMessage.stackTrace = initiator.stack || undefined;
-      if (initiator.url) {
-        consoleMessage.url = initiator.url;
-        consoleMessage.line = initiator.lineNumber || 0;
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} consoleMessage
-   * @return {?SDK.NetworkRequest}
-   */
-  static requestForConsoleMessage(consoleMessage) {
-    return consoleMessage[BrowserSDK.NetworkLog._requestSymbol] || null;
-  }
-};
-
-BrowserSDK.PageLoad = class {
-  /**
-   * @param {!SDK.NetworkRequest} mainRequest
-   */
-  constructor(mainRequest) {
-    this.id = ++BrowserSDK.PageLoad._lastIdentifier;
-    this.url = mainRequest.url();
-    this.startTime = mainRequest.startTime;
-    /** @type {number} */
-    this.loadTime;
-    /** @type {number} */
-    this.contentLoadTime;
-    this.mainRequest = mainRequest;
-
-    this._showDataSaverWarningIfNeeded();
-  }
-
-  async _showDataSaverWarningIfNeeded() {
-    const manager = SDK.NetworkManager.forRequest(this.mainRequest);
-    if (!manager)
-      return;
-    if (!this.mainRequest.finished)
-      await this.mainRequest.once(SDK.NetworkRequest.Events.FinishedLoading);
-    const saveDataHeader = this.mainRequest.requestHeaderValue('Save-Data');
-    if (!BrowserSDK.PageLoad._dataSaverMessageWasShown && saveDataHeader && saveDataHeader === 'on') {
-      const message = Common.UIString(
-          'Consider disabling %s while debugging. For more info see: %s', Common.UIString('Chrome Data Saver'),
-          'https://support.google.com/chrome/?p=datasaver');
-      manager.dispatchEventToListeners(
-          SDK.NetworkManager.Events.MessageGenerated,
-          {message: message, requestId: this.mainRequest.requestId(), warning: true});
-      BrowserSDK.PageLoad._dataSaverMessageWasShown = true;
-    }
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?BrowserSDK.PageLoad}
-   */
-  static forRequest(request) {
-    return request[BrowserSDK.PageLoad._pageLoadForRequestSymbol] || null;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  bindRequest(request) {
-    request[BrowserSDK.PageLoad._pageLoadForRequestSymbol] = this;
-  }
-};
-
-BrowserSDK.PageLoad._lastIdentifier = 0;
-BrowserSDK.PageLoad._pageLoadForRequestSymbol = Symbol('PageLoadForRequest');
-BrowserSDK.NetworkLog._requestSymbol = Symbol('_request');
-
-BrowserSDK.PageLoad._dataSaverMessageWasShown = false;
-
-/** @typedef {!{initiators: !Set<!SDK.NetworkRequest>, initiated: !Set<!SDK.NetworkRequest>}} */
-BrowserSDK.NetworkLog.InitiatorGraph;
-
-BrowserSDK.NetworkLog.Events = {
-  Reset: Symbol('Reset'),
-  RequestAdded: Symbol('RequestAdded'),
-  RequestUpdated: Symbol('RequestUpdated')
-};
-
-/** @typedef {!{type: !SDK.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number, scriptId: ?string, stack: ?Protocol.Runtime.StackTrace}} */
-BrowserSDK.NetworkLog._InitiatorInfo;
-
-BrowserSDK.NetworkLog._initiatorDataSymbol = Symbol('InitiatorData');
-BrowserSDK.NetworkLog._events = Symbol('BrowserSDK.NetworkLog.events');
-
-/** @type {!BrowserSDK.NetworkLog} */
-BrowserSDK.networkLog = new BrowserSDK.NetworkLog();
diff --git a/front_end/browser_sdk/module.json b/front_end/browser_sdk/module.json
deleted file mode 100644
index 445eb49..0000000
--- a/front_end/browser_sdk/module.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "setting",
-            "category": "Network",
-            "storageType": "session",
-            "title": "Preserve log",
-            "settingName": "network_log.preserve-log",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "tags": "preserve, clear, reset",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Do not preserve log on page reload / navigation"
-                },
-                {
-                    "value": false,
-                    "title": "Preserve log on page reload / navigation"
-                }
-            ]
-        }
-    ],
-    "scripts": [
-        "LogManager.js",
-        "NetworkLog.js",
-        "HAREntry.js"
-    ],
-    "dependencies": [
-        "sdk"
-    ]
-}
diff --git a/front_end/changes/ChangesHighlighter.js b/front_end/changes/ChangesHighlighter.js
deleted file mode 100644
index 01f9c24..0000000
--- a/front_end/changes/ChangesHighlighter.js
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @param {!Object} config
- * @param {{diffRows: !Array<!Changes.ChangesView.Row>, baselineLines: !Array<string>, currentLines: !Array<string>, mimeType: string}} parserConfig
- * @return {{
- *  startState: function():!Changes.ChangesHighlighter.DiffState,
- *  token: function(!CodeMirror.StringStream, !Changes.ChangesHighlighter.DiffState):string,
- *  blankLine: function(!Changes.ChangesHighlighter.DiffState):string,
- *  copyState: function(!Changes.ChangesHighlighter.DiffState):Changes.ChangesHighlighter.DiffState
- * }}
- */
-Changes.ChangesHighlighter = function(config, parserConfig) {
-  const diffRows = parserConfig.diffRows;
-  const baselineLines = parserConfig.baselineLines;
-  const currentLines = parserConfig.currentLines;
-  const syntaxHighlightMode = CodeMirror.getMode({}, parserConfig.mimeType);
-
-  /**
-   * @param {!Changes.ChangesHighlighter.DiffState} state
-   * @param {number} baselineLineNumber
-   * @param {number} currentLineNumber
-   */
-  function fastForward(state, baselineLineNumber, currentLineNumber) {
-    if (baselineLineNumber > state.baselineLineNumber) {
-      fastForwardSyntaxHighlighter(state.baselineSyntaxState, state.baselineLineNumber, baselineLineNumber, baselineLines);
-      state.baselineLineNumber = baselineLineNumber;
-    }
-    if (currentLineNumber > state.currentLineNumber) {
-      fastForwardSyntaxHighlighter(state.currentSyntaxState, state.currentLineNumber, currentLineNumber, currentLines);
-      state.currentLineNumber = currentLineNumber;
-    }
-  }
-
-  /**
-   * @param {!Object} syntaxState
-   * @param {number} from
-   * @param {number} to
-   * @param {!Array<string>} lines
-   */
-  function fastForwardSyntaxHighlighter(syntaxState, from, to, lines) {
-    let lineNumber = from;
-    while (lineNumber < to && lineNumber < lines.length) {
-      const stream = new CodeMirror.StringStream(lines[lineNumber]);
-      if (stream.eol() && syntaxHighlightMode.blankLine)
-        syntaxHighlightMode.blankLine(syntaxState);
-      while (!stream.eol()) {
-        syntaxHighlightMode.token(stream, syntaxState);
-        stream.start = stream.pos;
-      }
-      lineNumber++;
-    }
-  }
-
-  return {
-    /**
-     * @return {!Changes.ChangesHighlighter.DiffState}
-     */
-    startState: function() {
-      return {
-        rowNumber: 0,
-        diffTokenIndex: 0,
-        currentLineNumber: 0,
-        baselineLineNumber: 0,
-        currentSyntaxState: CodeMirror.startState(syntaxHighlightMode),
-        baselineSyntaxState: CodeMirror.startState(syntaxHighlightMode),
-        syntaxPosition: 0,
-        diffPosition: 0,
-        syntaxStyle: '',
-        diffStyle: ''
-      };
-    },
-
-    /**
-     * @param {!CodeMirror.StringStream} stream
-     * @param {!Changes.ChangesHighlighter.DiffState} state
-     * @return {string}
-     */
-    token: function(stream, state) {
-      const diffRow = diffRows[state.rowNumber];
-      if (!diffRow) {
-        stream.next();
-        return '';
-      }
-      fastForward(state, diffRow.baselineLineNumber - 1, diffRow.currentLineNumber - 1);
-      let classes = '';
-      if (stream.pos === 0)
-        classes += ' line-background-' + diffRow.type + ' line-' + diffRow.type;
-
-      const syntaxHighlighterNeedsRefresh = state.diffPosition >= state.syntaxPosition;
-      if (state.diffPosition <= state.syntaxPosition) {
-        state.diffPosition += diffRow.tokens[state.diffTokenIndex].text.length;
-        state.diffStyle = diffRow.tokens[state.diffTokenIndex].className;
-        state.diffTokenIndex++;
-      }
-
-      if (syntaxHighlighterNeedsRefresh) {
-        if (diffRow.type === Changes.ChangesView.RowType.Deletion || diffRow.type === Changes.ChangesView.RowType.Addition ||
-            diffRow.type === Changes.ChangesView.RowType.Equal) {
-          state.syntaxStyle = syntaxHighlightMode.token(
-              stream, diffRow.type === Changes.ChangesView.RowType.Deletion ? state.baselineSyntaxState : state.currentSyntaxState);
-          state.syntaxPosition = stream.pos;
-        } else {
-          state.syntaxStyle = '';
-          state.syntaxPosition = Infinity;
-        }
-      }
-
-      stream.pos = Math.min(state.syntaxPosition, state.diffPosition);
-      classes += ' ' + state.syntaxStyle;
-      classes += ' ' + state.diffStyle;
-
-      if (stream.eol()) {
-        state.rowNumber++;
-        if (diffRow.type === Changes.ChangesView.RowType.Deletion)
-          state.baselineLineNumber++;
-        else
-          state.currentLineNumber++;
-        state.diffPosition = 0;
-        state.syntaxPosition = 0;
-        state.diffTokenIndex = 0;
-      }
-      return classes;
-    },
-
-    /**
-     * @param {!Changes.ChangesHighlighter.DiffState} state
-     * @return {string}
-     */
-    blankLine: function(state) {
-      const diffRow = diffRows[state.rowNumber];
-      state.rowNumber++;
-      state.syntaxPosition = 0;
-      state.diffPosition = 0;
-      state.diffTokenIndex = 0;
-      if (!diffRow)
-        return '';
-
-      let style = '';
-      if (syntaxHighlightMode.blankLine) {
-        if (diffRow.type === Changes.ChangesView.RowType.Equal || diffRow.type === Changes.ChangesView.RowType.Addition) {
-          style = syntaxHighlightMode.blankLine(state.currentSyntaxState);
-          state.currentLineNumber++;
-        } else if (diffRow.type === Changes.ChangesView.RowType.Deletion) {
-          style = syntaxHighlightMode.blankLine(state.baselineSyntaxState);
-          state.baselineLineNumber++;
-        }
-      }
-      return style + ' line-background-' + diffRow.type + ' line-' + diffRow.type;
-    },
-
-    /**
-     * @param {!Changes.ChangesHighlighter.DiffState} state
-     * @return {!Changes.ChangesHighlighter.DiffState}
-     */
-    copyState: function(state) {
-      const newState = Object.assign({}, state);
-      newState.currentSyntaxState = CodeMirror.copyState(syntaxHighlightMode, state.currentSyntaxState);
-      newState.baselineSyntaxState = CodeMirror.copyState(syntaxHighlightMode, state.baselineSyntaxState);
-      return /** @type {!Changes.ChangesHighlighter.DiffState} */ (newState);
-    }
-  };
-};
-
-/**
- * @typedef {!{
- *  rowNumber: number,
- *  diffTokenIndex: number,
- *  currentLineNumber: number,
- *  baselineLineNumber: number,
- *  currentSyntaxState: !Object,
- *  baselineSyntaxState: !Object,
- *  syntaxPosition: number,
- *  diffPosition: number,
- *  syntaxStyle: string,
- *  diffStyle: string
- * }}
- */
-Changes.ChangesHighlighter.DiffState;
-
-CodeMirror.defineMode('devtools-diff', Changes.ChangesHighlighter);
diff --git a/front_end/changes/ChangesSidebar.js b/front_end/changes/ChangesSidebar.js
deleted file mode 100644
index 5c01d53..0000000
--- a/front_end/changes/ChangesSidebar.js
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Changes.ChangesSidebar = class extends UI.Widget {
-  /**
-   * @param {!WorkspaceDiff.WorkspaceDiff} workspaceDiff
-   */
-  constructor(workspaceDiff) {
-    super();
-    this._treeoutline = new UI.TreeOutlineInShadow();
-    this._treeoutline.registerRequiredCSS('changes/changesSidebar.css');
-    this._treeoutline.setComparator((a, b) => a.titleAsText().compareTo(b.titleAsText()));
-    this._treeoutline.addEventListener(UI.TreeOutline.Events.ElementSelected, this._selectionChanged, this);
-
-    this.element.appendChild(this._treeoutline.element);
-
-    /** @type {!Map<!Workspace.UISourceCode, !Changes.ChangesSidebar.UISourceCodeTreeElement>} */
-    this._treeElements = new Map();
-    this._workspaceDiff = workspaceDiff;
-    this._workspaceDiff.modifiedUISourceCodes().forEach(this._addUISourceCode.bind(this));
-    this._workspaceDiff.addEventListener(
-        WorkspaceDiff.Events.ModifiedStatusChanged, this._uiSourceCodeMofiedStatusChanged, this);
-  }
-
-  /**
-   * @return {?Workspace.UISourceCode}
-   */
-  selectedUISourceCode() {
-    return this._treeoutline.selectedTreeElement ? this._treeoutline.selectedTreeElement.uiSourceCode : null;
-  }
-
-  _selectionChanged() {
-    this.dispatchEventToListeners(Changes.ChangesSidebar.Events.SelectedUISourceCodeChanged);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeMofiedStatusChanged(event) {
-    if (event.data.isModified)
-      this._addUISourceCode(event.data.uiSourceCode);
-    else
-      this._removeUISourceCode(event.data.uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _removeUISourceCode(uiSourceCode) {
-    const treeElement = this._treeElements.get(uiSourceCode);
-    this._treeElements.delete(uiSourceCode);
-    if (this._treeoutline.selectedTreeElement === treeElement) {
-      const nextElementToSelect = treeElement.previousSibling || treeElement.nextSibling;
-      if (nextElementToSelect) {
-        nextElementToSelect.select(true);
-      } else {
-        treeElement.deselect();
-        this._selectionChanged();
-      }
-    }
-    this._treeoutline.removeChild(treeElement);
-    treeElement.dispose();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _addUISourceCode(uiSourceCode) {
-    const treeElement = new Changes.ChangesSidebar.UISourceCodeTreeElement(uiSourceCode);
-    this._treeElements.set(uiSourceCode, treeElement);
-    this._treeoutline.appendChild(treeElement);
-    if (!this._treeoutline.selectedTreeElement)
-      treeElement.select(true);
-  }
-};
-
-/**
- * @enum {symbol}
- */
-Changes.ChangesSidebar.Events = {
-  SelectedUISourceCodeChanged: Symbol('SelectedUISourceCodeChanged')
-};
-
-Changes.ChangesSidebar.UISourceCodeTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  constructor(uiSourceCode) {
-    super();
-    this.uiSourceCode = uiSourceCode;
-    this.listItemElement.classList.add('navigator-' + uiSourceCode.contentType().name() + '-tree-item');
-
-    let iconType = 'largeicon-navigator-file';
-    if (this.uiSourceCode.contentType() === Common.resourceTypes.Snippet)
-      iconType = 'largeicon-navigator-snippet';
-    const defaultIcon = UI.Icon.create(iconType, 'icon');
-    this.setLeadingIcons([defaultIcon]);
-
-    this._eventListeners = [
-      uiSourceCode.addEventListener(Workspace.UISourceCode.Events.TitleChanged, this._updateTitle, this),
-      uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this._updateTitle, this),
-      uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted, this._updateTitle, this)
-    ];
-
-    this._updateTitle();
-  }
-
-  _updateTitle() {
-    let titleText = this.uiSourceCode.displayName();
-    if (this.uiSourceCode.isDirty())
-      titleText = '*' + titleText;
-    this.title = titleText;
-
-    let tooltip = this.uiSourceCode.url();
-    if (this.uiSourceCode.contentType().isFromSourceMap())
-      tooltip = Common.UIString('%s (from source map)', this.uiSourceCode.displayName());
-    this.tooltip = tooltip;
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-  }
-};
\ No newline at end of file
diff --git a/front_end/changes/ChangesView.js b/front_end/changes/ChangesView.js
deleted file mode 100644
index 1d97d1a..0000000
--- a/front_end/changes/ChangesView.js
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Changes.ChangesView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('changes/changesView.css');
-    const splitWidget = new UI.SplitWidget(true /* vertical */, false /* sidebar on left */);
-    const mainWidget = new UI.Widget();
-    splitWidget.setMainWidget(mainWidget);
-    splitWidget.show(this.contentElement);
-
-    this._emptyWidget = new UI.EmptyWidget('');
-    this._emptyWidget.show(mainWidget.element);
-
-    this._workspaceDiff = WorkspaceDiff.workspaceDiff();
-    this._changesSidebar = new Changes.ChangesSidebar(this._workspaceDiff);
-    this._changesSidebar.addEventListener(
-        Changes.ChangesSidebar.Events.SelectedUISourceCodeChanged, this._selectedUISourceCodeChanged, this);
-    splitWidget.setSidebarWidget(this._changesSidebar);
-
-    /** @type {?Workspace.UISourceCode} */
-    this._selectedUISourceCode = null;
-
-    /** @type {!Array<!Changes.ChangesView.Row>} */
-    this._diffRows = [];
-
-    this._maxLineDigits = 1;
-
-    this._editor = new TextEditor.CodeMirrorTextEditor({
-      lineNumbers: true,
-      lineWrapping: false,
-      maxHighlightLength: Infinity  // This is to avoid CodeMirror bailing out of highlighting big diffs.
-    });
-    this._editor.setReadOnly(true);
-    this._editor.show(mainWidget.element.createChild('div', 'editor-container'));
-    this._editor.hideWidget();
-
-    this._editor.element.addEventListener('click', this._click.bind(this), false);
-
-    this._toolbar = new UI.Toolbar('changes-toolbar', mainWidget.element);
-    const revertButton = new UI.ToolbarButton(Common.UIString('Revert all changes'), 'largeicon-undo');
-    revertButton.addEventListener(UI.ToolbarButton.Events.Click, this._revert.bind(this));
-    this._toolbar.appendToolbarItem(revertButton);
-    this._diffStats = new UI.ToolbarText('');
-    this._toolbar.appendToolbarItem(this._diffStats);
-    this._toolbar.setEnabled(false);
-
-    this._hideDiff(ls`No changes`);
-    this._selectedUISourceCodeChanged();
-  }
-
-  _selectedUISourceCodeChanged() {
-    this._revealUISourceCode(this._changesSidebar.selectedUISourceCode());
-  }
-
-  _revert() {
-    const uiSourceCode = this._selectedUISourceCode;
-    if (!uiSourceCode)
-      return;
-    this._workspaceDiff.revertToOriginal(uiSourceCode);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _click(event) {
-    const selection = this._editor.selection();
-    if (!selection.isEmpty())
-      return;
-    const row = this._diffRows[selection.startLine];
-    Common.Revealer.reveal(
-        this._selectedUISourceCode.uiLocation(row.currentLineNumber - 1, selection.startColumn), false);
-    event.consume(true);
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   */
-  _revealUISourceCode(uiSourceCode) {
-    if (this._selectedUISourceCode === uiSourceCode)
-      return;
-
-    if (this._selectedUISourceCode)
-      this._workspaceDiff.unsubscribeFromDiffChange(this._selectedUISourceCode, this._refreshDiff, this);
-    if (uiSourceCode && this.isShowing())
-      this._workspaceDiff.subscribeToDiffChange(uiSourceCode, this._refreshDiff, this);
-
-    this._selectedUISourceCode = uiSourceCode;
-    this._refreshDiff();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._refreshDiff();
-  }
-
-  _refreshDiff() {
-    if (!this.isShowing())
-      return;
-
-    if (!this._selectedUISourceCode) {
-      this._renderDiffRows(null);
-      return;
-    }
-    const uiSourceCode = this._selectedUISourceCode;
-    if (!uiSourceCode.contentType().isTextType()) {
-      this._hideDiff(ls`Binary data`);
-      return;
-    }
-    this._workspaceDiff.requestDiff(uiSourceCode).then(diff => {
-      if (this._selectedUISourceCode !== uiSourceCode)
-        return;
-      this._renderDiffRows(diff);
-    });
-  }
-
-  /**
-   * @param {string} message
-   */
-  _hideDiff(message) {
-    this._diffStats.setText('');
-    this._toolbar.setEnabled(false);
-    this._editor.hideWidget();
-    this._emptyWidget.text = message;
-    this._emptyWidget.showWidget();
-  }
-
-  /**
-   * @param {?Diff.Diff.DiffArray} diff
-   */
-  _renderDiffRows(diff) {
-    this._diffRows = [];
-
-    if (!diff || (diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal)) {
-      this._hideDiff(ls`No changes`);
-      return;
-    }
-
-    let insertions = 0;
-    let deletions = 0;
-    let currentLineNumber = 0;
-    let baselineLineNumber = 0;
-    const paddingLines = 3;
-    const originalLines = [];
-    const currentLines = [];
-
-    for (let i = 0; i < diff.length; ++i) {
-      const token = diff[i];
-      switch (token[0]) {
-        case Diff.Diff.Operation.Equal:
-          this._diffRows.pushAll(createEqualRows(token[1], i === 0, i === diff.length - 1));
-          originalLines.pushAll(token[1]);
-          currentLines.pushAll(token[1]);
-          break;
-        case Diff.Diff.Operation.Insert:
-          for (const line of token[1])
-            this._diffRows.push(createRow(line, Changes.ChangesView.RowType.Addition));
-          insertions += token[1].length;
-          currentLines.pushAll(token[1]);
-          break;
-        case Diff.Diff.Operation.Delete:
-          deletions += token[1].length;
-          originalLines.pushAll(token[1]);
-          if (diff[i + 1] && diff[i + 1][0] === Diff.Diff.Operation.Insert) {
-            i++;
-            this._diffRows.pushAll(createModifyRows(token[1].join('\n'), diff[i][1].join('\n')));
-            insertions += diff[i][1].length;
-            currentLines.pushAll(diff[i][1]);
-          } else {
-            for (const line of token[1])
-              this._diffRows.push(createRow(line, Changes.ChangesView.RowType.Deletion));
-          }
-          break;
-      }
-    }
-
-    this._maxLineDigits = Math.ceil(Math.log10(Math.max(currentLineNumber, baselineLineNumber)));
-
-    this._diffStats.setText(Common.UIString(
-        '%d insertion%s (+), %d deletion%s (-)', insertions, insertions !== 1 ? 's' : '', deletions,
-        deletions !== 1 ? 's' : ''));
-    this._toolbar.setEnabled(true);
-    this._emptyWidget.hideWidget();
-
-    this._editor.operation(() => {
-      this._editor.showWidget();
-      this._editor.setHighlightMode({
-        name: 'devtools-diff',
-        diffRows: this._diffRows,
-        mimeType: /** @type {!Workspace.UISourceCode} */ (this._selectedUISourceCode).mimeType(),
-        baselineLines: originalLines,
-        currentLines: currentLines
-      });
-      this._editor.setText(this._diffRows.map(row => row.tokens.map(t => t.text).join('')).join('\n'));
-      this._editor.setLineNumberFormatter(this._lineFormatter.bind(this));
-    });
-
-    /**
-     * @param {!Array<string>} lines
-     * @param {boolean} atStart
-     * @param {boolean} atEnd
-     * @return {!Array<!Changes.ChangesView.Row>}}
-     */
-    function createEqualRows(lines, atStart, atEnd) {
-      const equalRows = [];
-      if (!atStart) {
-        for (let i = 0; i < paddingLines && i < lines.length; i++)
-          equalRows.push(createRow(lines[i], Changes.ChangesView.RowType.Equal));
-        if (lines.length > paddingLines * 2 + 1 && !atEnd) {
-          equalRows.push(createRow(
-              Common.UIString('( \u2026 Skipping ') + (lines.length - paddingLines * 2) +
-                  Common.UIString(' matching lines \u2026 )'),
-              Changes.ChangesView.RowType.Spacer));
-        }
-      }
-      if (!atEnd) {
-        const start = Math.max(lines.length - paddingLines - 1, atStart ? 0 : paddingLines);
-        let skip = lines.length - paddingLines - 1;
-        if (!atStart)
-          skip -= paddingLines;
-        if (skip > 0) {
-          baselineLineNumber += skip;
-          currentLineNumber += skip;
-        }
-
-        for (let i = start; i < lines.length; i++)
-          equalRows.push(createRow(lines[i], Changes.ChangesView.RowType.Equal));
-      }
-      return equalRows;
-    }
-
-    /**
-     * @param {string} before
-     * @param {string} after
-     * @return {!Array<!Changes.ChangesView.Row>}}
-     */
-    function createModifyRows(before, after) {
-      const internalDiff = Diff.Diff.charDiff(before, after, true /* cleanup diff */);
-      const deletionRows = [createRow('', Changes.ChangesView.RowType.Deletion)];
-      const insertionRows = [createRow('', Changes.ChangesView.RowType.Addition)];
-
-      for (const token of internalDiff) {
-        const text = token[1];
-        const type = token[0];
-        const className = type === Diff.Diff.Operation.Equal ? '' : 'inner-diff';
-        const lines = text.split('\n');
-        for (let i = 0; i < lines.length; i++) {
-          if (i > 0 && type !== Diff.Diff.Operation.Insert)
-            deletionRows.push(createRow('', Changes.ChangesView.RowType.Deletion));
-          if (i > 0 && type !== Diff.Diff.Operation.Delete)
-            insertionRows.push(createRow('', Changes.ChangesView.RowType.Addition));
-          if (!lines[i])
-            continue;
-          if (type !== Diff.Diff.Operation.Insert)
-            deletionRows[deletionRows.length - 1].tokens.push({text: lines[i], className});
-          if (type !== Diff.Diff.Operation.Delete)
-            insertionRows[insertionRows.length - 1].tokens.push({text: lines[i], className});
-        }
-      }
-      return deletionRows.concat(insertionRows);
-    }
-
-    /**
-     * @param {string} text
-     * @param {!Changes.ChangesView.RowType} type
-     * @return {!Changes.ChangesView.Row}
-     */
-    function createRow(text, type) {
-      if (type === Changes.ChangesView.RowType.Addition)
-        currentLineNumber++;
-      if (type === Changes.ChangesView.RowType.Deletion)
-        baselineLineNumber++;
-      if (type === Changes.ChangesView.RowType.Equal) {
-        baselineLineNumber++;
-        currentLineNumber++;
-      }
-
-      return {baselineLineNumber, currentLineNumber, tokens: text ? [{text, className: 'inner-diff'}] : [], type};
-    }
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @return {string}
-   */
-  _lineFormatter(lineNumber) {
-    const row = this._diffRows[lineNumber - 1];
-    let showBaseNumber = row.type === Changes.ChangesView.RowType.Deletion;
-    let showCurrentNumber = row.type === Changes.ChangesView.RowType.Addition;
-    if (row.type === Changes.ChangesView.RowType.Equal) {
-      showBaseNumber = true;
-      showCurrentNumber = true;
-    }
-    const base = showBaseNumber ? numberToStringWithSpacesPadding(row.baselineLineNumber, this._maxLineDigits) :
-                                  spacesPadding(this._maxLineDigits);
-    const current = showCurrentNumber ? numberToStringWithSpacesPadding(row.currentLineNumber, this._maxLineDigits) :
-                                        spacesPadding(this._maxLineDigits);
-    return base + spacesPadding(1) + current;
-  }
-};
-
-/**
- * @typedef {!{
- *  baselineLineNumber: number,
- *  currentLineNumber: number,
- *  tokens: !Array<!{text: string, className: string}>,
- *  type: !Changes.ChangesView.RowType
- * }}
- */
-Changes.ChangesView.Row;
-
-/** @enum {string} */
-Changes.ChangesView.RowType = {
-  Deletion: 'deletion',
-  Addition: 'addition',
-  Equal: 'equal',
-  Spacer: 'spacer'
-};
\ No newline at end of file
diff --git a/front_end/changes/changesSidebar.css b/front_end/changes/changesSidebar.css
deleted file mode 100644
index f10384d..0000000
--- a/front_end/changes/changesSidebar.css
+++ /dev/null
@@ -1,33 +0,0 @@
-li .icon {
-  margin: -3px -5px -3px -5px;
-  background: linear-gradient(45deg, hsl(0, 0%, 50%), hsl(0, 0%, 70%));
-}
-
-.tree-outline li {
-  min-height: 20px;
-}
-
-.tree-outline li:hover:not(.selected) .selection {
-  display: block;
-  background-color: rgba(56, 121, 217, 0.1);
-}
-
-.navigator-fs-tree-item .icon{
-  background: linear-gradient(45deg, hsl(28, 75%, 50%), hsl(28, 75%, 70%));
-}
-
-.navigator-sm-script-tree-item .icon,
-.navigator-script-tree-item .icon,
-.navigator-snippet-tree-item .icon {
-  background: linear-gradient(45deg, hsl(48, 70%, 50%), hsl(48, 70%, 70%));
-}
-
-.navigator-sm-stylesheet-tree-item .icon,
-.navigator-stylesheet-tree-item .icon {
-  background: linear-gradient(45deg, hsl(256, 50%, 50%), hsl(256, 50%, 70%));
-}
-
-.navigator-image-tree-item .icon,
-.navigator-font-tree-item .icon {
-  background: linear-gradient(45deg, hsl(109, 33%, 50%), hsl(109, 33%, 70%));
-}
\ No newline at end of file
diff --git a/front_end/changes/changesView.css b/front_end/changes/changesView.css
deleted file mode 100644
index 8d3ad90..0000000
--- a/front_end/changes/changesView.css
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-.insertion-point-main{
-    flex-direction: column;
-    display: flex;
-}
-
-.insertion-point-sidebar {
-    overflow: auto;
-}
-.editor-container{
-    flex: 1;
-}
-
-:focus.selected {
-    background-color: var(--selection-bg-color);
-    color: #FFF;
-}
-
-.CodeMirror-lines:not(:active) {
-    cursor: default !important;
-}
-
-.CodeMirror-line:hover {
-    cursor: default !important;
-    background-color: rgba(0,0,255,0.05);
-}
-
-.CodeMirror .CodeMirror-linebackground.spacer {
-    text-align: center;
-    color: rgba(0, 0, 0, 0.5);
-    background-color: rgba(0, 0, 255, 0.1);
-}
-
-.CodeMirror .equal > span > span {
-    opacity: .5;
-}
-
-.CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) {
-    opacity: 1.0;
-}
-
-.CodeMirror .CodeMirror-linebackground.addition, -theme-preserve {
-    background-color: hsla(144, 55%, 49%, .2);
-}
-
-.CodeMirror .CodeMirror-linebackground.deletion, -theme-preserve {
-    background-color: rgba(255, 0, 0, .2);
-}
-
-.CodeMirror .addition .cm-inner-diff:not(.CodeMirror-selectedtext), -theme-preserve {
-    background-color: hsla(144, 55%, 49%, .3);
-}
-
-.CodeMirror .deletion .cm-inner-diff:not(.CodeMirror-selectedtext), -theme-preserve {
-    background-color: rgba(255, 0, 0, .3);
-}
-
-.changes-toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-top: var(--divider-border);
-}
diff --git a/front_end/changes/module.json b/front_end/changes/module.json
deleted file mode 100644
index a1d831a..0000000
--- a/front_end/changes/module.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "changes.changes",
-            "title": "Changes",
-            "persistence": "closeable",
-            "className": "Changes.ChangesView"
-        }
-    ],
-    "dependencies": [
-      "workspace_diff",
-      "text_editor",
-      "workspace",
-      "diff",
-      "bindings",
-      "persistence",
-      "ui"
-    ],
-    "scripts": [
-      "ChangesHighlighter.js",
-      "ChangesView.js",
-      "ChangesSidebar.js"
-    ],
-    "resources": [
-      "changesView.css",
-      "changesSidebar.css"
-    ]
-}
diff --git a/front_end/cm/LICENSE b/front_end/cm/LICENSE
deleted file mode 100644
index ff7db4b..0000000
--- a/front_end/cm/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/front_end/cm/LICENSE_python b/front_end/cm/LICENSE_python
deleted file mode 100644
index 918866b..0000000
--- a/front_end/cm/LICENSE_python
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2010 Timothy Farrell
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/front_end/cm/PRESUBMIT.py b/front_end/cm/PRESUBMIT.py
deleted file mode 100644
index 354b013..0000000
--- a/front_end/cm/PRESUBMIT.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2014 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-def _CheckCodeMirrorChanges(input_api, output_api):
-    errorText = ("ERROR: Attempt to modify CodeMirror. The only allowed changes are "
-                 "rolls from the upstream (http://codemirror.net). If this is a roll, "
-                 "make sure you mention 'roll CodeMirror' (no quotes) in the change description.\n"
-                 "CodeMirror rolling instructions:\n"
-                 "    src/third_party/WebKit/Source/devtools/front_end/cm/README.md")
-    changeDescription = input_api.change.DescriptionText()
-    errors = []
-    if not "roll codemirror" in changeDescription.lower():
-        errors.append(output_api.PresubmitError(errorText))
-    return errors
-
-
-def CheckChangeOnUpload(input_api, output_api):
-    results = []
-    results.extend(_CheckCodeMirrorChanges(input_api, output_api))
-    return results
diff --git a/front_end/cm/README.md b/front_end/cm/README.md
deleted file mode 100644
index 68f5303..0000000
--- a/front_end/cm/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Rolling CodeMirror
-
-## What's this about?
-CodeMirror is a third-party library, which supports editing experience in Chrome DevTools. DevTools does not fork CodeMirror, thus all CodeMirror patches should go upstream to http://codemirror.net.
-Every once in a while, the CodeMirror dependency (which is located in Source/devtools/front_end/cm/ folder) should be updated to a newer version.
-
-## Updating CodeMirror
-This requires the following steps to be done:
-1. File `headlesscodemirror.js` is a `runmode-standalone.js` file from CodeMirror distribution, but wrapped in `(function(window) { ... }(this))`
-construction. This is needed to support in web workers.
-2. File `markselection.js` is a `mark-selection.js` from CodeMirror distribution. The "dash" is removed due to the restriction on the chromium grd generator.
-4. File codemirror.css contains both the default theme of CodeMirror and structural css required for it to work. Discard everything in the file up to the word `/* STOP */`.
-3. All other files in front_end/cm/ folder should be substituted with their newer versions from the upstream.
-
-## Testing
-DevTools wrap CodeMirror via `CodeMirrorTextEditor.js` and `cmdevtools.css` files.
-Although there are a couple of automated tests (LayoutTests/inspector/editor/) to verify overall sanity of the setup, a manual testing is mandatory before
-landing a roll. Here is a rough testing scenario outline:
-1. Create a new snippet and type in a small function with a few nested for-loops. (The author suggests a bubble-sort). Make sure that:
-   * Words `function`, `for`, `var` are highlighted
-   * "Smart braces" behavior works
-   * "Enter" after opening curly brace adds correct indent
-   * Autocompletion works
-   * Multiple cursors functionality works as intended - Ctrl+D/Ctrl+U shortcuts
-   * Set a breakpoint inside a function, select some text and summon a context menu over it.
-2. Make sure there are items such as "Add to Watch", "Evaluate in Console" and "Copy/Paste"
-Make sure minified jquery opens nicely in the editor (minified jquery could be found as a resource on http://jquery.com)
-   * Verify `jquery.min.js` is formatted via "Pretty print" action
-3. Go to the Elements panel, select a node and verify the "Edit it as HTML" command works.
-
-## Committing
-The only changes allowed to front_end/cm/ folder are CodeMirror rolls. There's a presubmit check that enforces this, so make sure you include the phrase "roll CodeMirror" into
-your patch description.
-
-## Example
-Example CodeMirror roll patchset: https://codereview.chromium.org/273763003
diff --git a/front_end/cm/activeline.js b/front_end/cm/activeline.js
deleted file mode 100644
index aa295d0..0000000
--- a/front_end/cm/activeline.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-  var WRAP_CLASS = "CodeMirror-activeline";
-  var BACK_CLASS = "CodeMirror-activeline-background";
-  var GUTT_CLASS = "CodeMirror-activeline-gutter";
-
-  CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
-    var prev = old == CodeMirror.Init ? false : old;
-    if (val == prev) return
-    if (prev) {
-      cm.off("beforeSelectionChange", selectionChange);
-      clearActiveLines(cm);
-      delete cm.state.activeLines;
-    }
-    if (val) {
-      cm.state.activeLines = [];
-      updateActiveLines(cm, cm.listSelections());
-      cm.on("beforeSelectionChange", selectionChange);
-    }
-  });
-
-  function clearActiveLines(cm) {
-    for (var i = 0; i < cm.state.activeLines.length; i++) {
-      cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
-      cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
-      cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
-    }
-  }
-
-  function sameArray(a, b) {
-    if (a.length != b.length) return false;
-    for (var i = 0; i < a.length; i++)
-      if (a[i] != b[i]) return false;
-    return true;
-  }
-
-  function updateActiveLines(cm, ranges) {
-    var active = [];
-    for (var i = 0; i < ranges.length; i++) {
-      var range = ranges[i];
-      var option = cm.getOption("styleActiveLine");
-      if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
-        continue
-      var line = cm.getLineHandleVisualStart(range.head.line);
-      if (active[active.length - 1] != line) active.push(line);
-    }
-    if (sameArray(cm.state.activeLines, active)) return;
-    cm.operation(function() {
-      clearActiveLines(cm);
-      for (var i = 0; i < active.length; i++) {
-        cm.addLineClass(active[i], "wrap", WRAP_CLASS);
-        cm.addLineClass(active[i], "background", BACK_CLASS);
-        cm.addLineClass(active[i], "gutter", GUTT_CLASS);
-      }
-      cm.state.activeLines = active;
-    });
-  }
-
-  function selectionChange(cm, sel) {
-    updateActiveLines(cm, sel.ranges);
-  }
-});
diff --git a/front_end/cm/closebrackets.js b/front_end/cm/closebrackets.js
deleted file mode 100644
index 460f662..0000000
--- a/front_end/cm/closebrackets.js
+++ /dev/null
@@ -1,194 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  var defaults = {
-    pairs: "()[]{}''\"\"",
-    triples: "",
-    explode: "[]{}"
-  };
-
-  var Pos = CodeMirror.Pos;
-
-  CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
-    if (old && old != CodeMirror.Init) {
-      cm.removeKeyMap(keyMap);
-      cm.state.closeBrackets = null;
-    }
-    if (val) {
-      ensureBound(getOption(val, "pairs"))
-      cm.state.closeBrackets = val;
-      cm.addKeyMap(keyMap);
-    }
-  });
-
-  function getOption(conf, name) {
-    if (name == "pairs" && typeof conf == "string") return conf;
-    if (typeof conf == "object" && conf[name] != null) return conf[name];
-    return defaults[name];
-  }
-
-  var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
-  function ensureBound(chars) {
-    for (var i = 0; i < chars.length; i++) {
-      var ch = chars.charAt(i), key = "'" + ch + "'"
-      if (!keyMap[key]) keyMap[key] = handler(ch)
-    }
-  }
-  ensureBound(defaults.pairs + "`")
-
-  function handler(ch) {
-    return function(cm) { return handleChar(cm, ch); };
-  }
-
-  function getConfig(cm) {
-    var deflt = cm.state.closeBrackets;
-    if (!deflt || deflt.override) return deflt;
-    var mode = cm.getModeAt(cm.getCursor());
-    return mode.closeBrackets || deflt;
-  }
-
-  function handleBackspace(cm) {
-    var conf = getConfig(cm);
-    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
-
-    var pairs = getOption(conf, "pairs");
-    var ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++) {
-      if (!ranges[i].empty()) return CodeMirror.Pass;
-      var around = charsAround(cm, ranges[i].head);
-      if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
-    }
-    for (var i = ranges.length - 1; i >= 0; i--) {
-      var cur = ranges[i].head;
-      cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
-    }
-  }
-
-  function handleEnter(cm) {
-    var conf = getConfig(cm);
-    var explode = conf && getOption(conf, "explode");
-    if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
-
-    var ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++) {
-      if (!ranges[i].empty()) return CodeMirror.Pass;
-      var around = charsAround(cm, ranges[i].head);
-      if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
-    }
-    cm.operation(function() {
-      var linesep = cm.lineSeparator() || "\n";
-      cm.replaceSelection(linesep + linesep, null);
-      cm.execCommand("goCharLeft");
-      ranges = cm.listSelections();
-      for (var i = 0; i < ranges.length; i++) {
-        var line = ranges[i].head.line;
-        cm.indentLine(line, null, true);
-        cm.indentLine(line + 1, null, true);
-      }
-    });
-  }
-
-  function contractSelection(sel) {
-    var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
-    return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
-            head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
-  }
-
-  function handleChar(cm, ch) {
-    var conf = getConfig(cm);
-    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
-
-    var pairs = getOption(conf, "pairs");
-    var pos = pairs.indexOf(ch);
-    if (pos == -1) return CodeMirror.Pass;
-    var triples = getOption(conf, "triples");
-
-    var identical = pairs.charAt(pos + 1) == ch;
-    var ranges = cm.listSelections();
-    var opening = pos % 2 == 0;
-
-    var type;
-    for (var i = 0; i < ranges.length; i++) {
-      var range = ranges[i], cur = range.head, curType;
-      var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
-      if (opening && !range.empty()) {
-        curType = "surround";
-      } else if ((identical || !opening) && next == ch) {
-        if (identical && stringStartsAfter(cm, cur))
-          curType = "both";
-        else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
-          curType = "skipThree";
-        else
-          curType = "skip";
-      } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
-                 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
-                 (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
-        curType = "addFour";
-      } else if (identical) {
-        var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
-        if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
-        else return CodeMirror.Pass;
-      } else if (opening && (cm.getLine(cur.line).length == cur.ch ||
-                             isClosingBracket(next, pairs) ||
-                             /\s/.test(next))) {
-        curType = "both";
-      } else {
-        return CodeMirror.Pass;
-      }
-      if (!type) type = curType;
-      else if (type != curType) return CodeMirror.Pass;
-    }
-
-    var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
-    var right = pos % 2 ? ch : pairs.charAt(pos + 1);
-    cm.operation(function() {
-      if (type == "skip") {
-        cm.execCommand("goCharRight");
-      } else if (type == "skipThree") {
-        for (var i = 0; i < 3; i++)
-          cm.execCommand("goCharRight");
-      } else if (type == "surround") {
-        var sels = cm.getSelections();
-        for (var i = 0; i < sels.length; i++)
-          sels[i] = left + sels[i] + right;
-        cm.replaceSelections(sels, "around");
-        sels = cm.listSelections().slice();
-        for (var i = 0; i < sels.length; i++)
-          sels[i] = contractSelection(sels[i]);
-        cm.setSelections(sels);
-      } else if (type == "both") {
-        cm.replaceSelection(left + right, null);
-        cm.triggerElectric(left + right);
-        cm.execCommand("goCharLeft");
-      } else if (type == "addFour") {
-        cm.replaceSelection(left + left + left + left, "before");
-        cm.execCommand("goCharRight");
-      }
-    });
-  }
-
-  function isClosingBracket(ch, pairs) {
-    var pos = pairs.lastIndexOf(ch);
-    return pos > -1 && pos % 2 == 1;
-  }
-
-  function charsAround(cm, pos) {
-    var str = cm.getRange(Pos(pos.line, pos.ch - 1),
-                          Pos(pos.line, pos.ch + 1));
-    return str.length == 2 ? str : null;
-  }
-
-  function stringStartsAfter(cm, pos) {
-    var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
-    return /\bstring/.test(token.type) && token.start == pos.ch &&
-      (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
-  }
-});
diff --git a/front_end/cm/codemirror.css b/front_end/cm/codemirror.css
deleted file mode 100644
index 3360cac..0000000
--- a/front_end/cm/codemirror.css
+++ /dev/null
@@ -1,194 +0,0 @@
-/* STOP */
-
-/* The rest of this file contains styles related to the mechanics of
-   the editor. You probably shouldn't touch them. */
-
-   .CodeMirror {
-    position: relative;
-    overflow: hidden;
-    background: white;
-  }
-
-  .CodeMirror-scroll {
-    overflow: scroll !important; /* Things will break if this is overridden */
-    /* 30px is the magic margin used to hide the element's real scrollbars */
-    /* See overflow: hidden in .CodeMirror */
-    margin-bottom: -30px; margin-right: -30px;
-    padding-bottom: 30px;
-    height: 100%;
-    outline: none; /* Prevent dragging from highlighting the element */
-    position: relative;
-  }
-  .CodeMirror-sizer {
-    position: relative;
-    border-right: 30px solid transparent;
-  }
-
-  /* The fake, visible scrollbars. Used to force redraw during scrolling
-     before actual scrolling happens, thus preventing shaking and
-     flickering artifacts. */
-  .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
-    position: absolute;
-    z-index: 6;
-    display: none;
-  }
-  .CodeMirror-vscrollbar {
-    right: 0; top: 0;
-    overflow-x: hidden;
-    overflow-y: scroll;
-  }
-  .CodeMirror-hscrollbar {
-    bottom: 0; left: 0;
-    overflow-y: hidden;
-    overflow-x: scroll;
-  }
-  .CodeMirror-scrollbar-filler {
-    right: 0; bottom: 0;
-  }
-  .CodeMirror-gutter-filler {
-    left: 0; bottom: 0;
-  }
-
-  .CodeMirror-gutters {
-    position: absolute; left: 0; top: 0;
-    min-height: 100%;
-    z-index: 3;
-  }
-  .CodeMirror-gutter {
-    white-space: normal;
-    height: 100%;
-    display: inline-block;
-    vertical-align: top;
-    margin-bottom: -30px;
-  }
-  .CodeMirror-gutter-wrapper {
-    position: absolute;
-    z-index: 4;
-    background: none !important;
-    border: none !important;
-  }
-  .CodeMirror-gutter-background {
-    position: absolute;
-    top: 0; bottom: 0;
-    z-index: 4;
-  }
-  .CodeMirror-gutter-elt {
-    position: absolute;
-    cursor: default;
-    z-index: 4;
-  }
-  .CodeMirror-gutter-wrapper ::selection { background-color: transparent }
-  .CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
-
-  .CodeMirror-lines {
-    cursor: text;
-    min-height: 1px; /* prevents collapsing before first draw */
-  }
-  .CodeMirror pre {
-    /* Reset some styles that the rest of the page might have set */
-    -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
-    border-width: 0;
-    background: transparent;
-    font-family: inherit;
-    font-size: inherit;
-    margin: 0;
-    white-space: pre;
-    word-wrap: normal;
-    line-height: inherit;
-    color: inherit;
-    z-index: 2;
-    position: relative;
-    overflow: visible;
-    -webkit-tap-highlight-color: transparent;
-    -webkit-font-variant-ligatures: contextual;
-    font-variant-ligatures: contextual;
-  }
-  .CodeMirror-wrap pre {
-    word-wrap: break-word;
-    white-space: pre-wrap;
-    word-break: normal;
-  }
-
-  .CodeMirror-linebackground {
-    position: absolute;
-    left: 0; right: 0; top: 0; bottom: 0;
-    z-index: 0;
-  }
-
-  .CodeMirror-linewidget {
-    position: relative;
-    z-index: 2;
-    overflow: auto;
-  }
-
-  .CodeMirror-widget {}
-
-  .CodeMirror-rtl pre { direction: rtl; }
-
-  .CodeMirror-code {
-    outline: none;
-  }
-
-  /* Force content-box sizing for the elements where we expect it */
-  .CodeMirror-scroll,
-  .CodeMirror-sizer,
-  .CodeMirror-gutter,
-  .CodeMirror-gutters,
-  .CodeMirror-linenumber {
-    -moz-box-sizing: content-box;
-    box-sizing: content-box;
-  }
-
-  .CodeMirror-measure {
-    position: absolute;
-    width: 100%;
-    height: 0;
-    overflow: hidden;
-    visibility: hidden;
-  }
-
-  .CodeMirror-cursor {
-    position: absolute;
-    pointer-events: none;
-  }
-  .CodeMirror-measure pre { position: static; }
-
-  div.CodeMirror-cursors {
-    visibility: hidden;
-    position: relative;
-    z-index: 3;
-  }
-  div.CodeMirror-dragcursors {
-    visibility: visible;
-  }
-
-  .CodeMirror-focused div.CodeMirror-cursors {
-    visibility: visible;
-  }
-
-  .CodeMirror-selected { background: #d9d9d9; }
-  .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
-  .CodeMirror-crosshair { cursor: crosshair; }
-  .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
-  .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
-
-  .cm-searching {
-    background-color: #ffa;
-    background-color: rgba(255, 255, 0, .4);
-  }
-
-  /* Used to force a border model for a node */
-  .cm-force-border { padding-right: .1px; }
-
-  @media print {
-    /* Hide the cursor when printing */
-    .CodeMirror div.CodeMirror-cursors {
-      visibility: hidden;
-    }
-  }
-
-  /* See issue #2901 */
-  .cm-tab-wrap-hack:after { content: ''; }
-
-  /* Help users use markselection to safely style text background */
-  span.CodeMirror-selectedtext { background: none; }
diff --git a/front_end/cm/codemirror.js b/front_end/cm/codemirror.js
deleted file mode 100644
index 069c579..0000000
--- a/front_end/cm/codemirror.js
+++ /dev/null
@@ -1,9665 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-// This is CodeMirror (http://codemirror.net), a code editor
-// implemented in JavaScript on top of the browser's DOM.
-//
-// You can find some technical background for some of the code below
-// at http://marijnhaverbeke.nl/blog/#cm-internals .
-
-(function (global, factory) {
-	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-	typeof define === 'function' && define.amd ? define(factory) :
-	(global.CodeMirror = factory());
-}(this, (function () { 'use strict';
-
-// Kludges for bugs and behavior differences that can't be feature
-// detected are enabled based on userAgent etc sniffing.
-var userAgent = navigator.userAgent;
-var platform = navigator.platform;
-
-var gecko = /gecko\/\d/i.test(userAgent);
-var ie_upto10 = /MSIE \d/.test(userAgent);
-var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
-var edge = /Edge\/(\d+)/.exec(userAgent);
-var ie = ie_upto10 || ie_11up || edge;
-var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]);
-var webkit = !edge && /WebKit\//.test(userAgent);
-var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
-var chrome = !edge && /Chrome\//.test(userAgent);
-var presto = /Opera\//.test(userAgent);
-var safari = /Apple Computer/.test(navigator.vendor);
-var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
-var phantom = /PhantomJS/.test(userAgent);
-
-var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
-var android = /Android/.test(userAgent);
-// This is woefully incomplete. Suggestions for alternative methods welcome.
-var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
-var mac = ios || /Mac/.test(platform);
-var chromeOS = /\bCrOS\b/.test(userAgent);
-var windows = /win/i.test(platform);
-
-var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
-if (presto_version) { presto_version = Number(presto_version[1]); }
-if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
-// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
-var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
-var captureRightClick = gecko || (ie && ie_version >= 9);
-
-function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
-
-var rmClass = function(node, cls) {
-  var current = node.className;
-  var match = classTest(cls).exec(current);
-  if (match) {
-    var after = current.slice(match.index + match[0].length);
-    node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
-  }
-};
-
-function removeChildren(e) {
-  for (var count = e.childNodes.length; count > 0; --count)
-    { e.removeChild(e.firstChild); }
-  return e
-}
-
-function removeChildrenAndAdd(parent, e) {
-  return removeChildren(parent).appendChild(e)
-}
-
-function elt(tag, content, className, style) {
-  var e = document.createElement(tag);
-  if (className) { e.className = className; }
-  if (style) { e.style.cssText = style; }
-  if (typeof content == "string") { e.appendChild(document.createTextNode(content)); }
-  else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } }
-  return e
-}
-// wrapper for elt, which removes the elt from the accessibility tree
-function eltP(tag, content, className, style) {
-  var e = elt(tag, content, className, style);
-  e.setAttribute("role", "presentation");
-  return e
-}
-
-var range;
-if (document.createRange) { range = function(node, start, end, endNode) {
-  var r = document.createRange();
-  r.setEnd(endNode || node, end);
-  r.setStart(node, start);
-  return r
-}; }
-else { range = function(node, start, end) {
-  var r = document.body.createTextRange();
-  try { r.moveToElementText(node.parentNode); }
-  catch(e) { return r }
-  r.collapse(true);
-  r.moveEnd("character", end);
-  r.moveStart("character", start);
-  return r
-}; }
-
-function contains(parent, child) {
-  if (child.nodeType == 3) // Android browser always returns false when child is a textnode
-    { child = child.parentNode; }
-  if (parent.contains)
-    { return parent.contains(child) }
-  do {
-    if (child.nodeType == 11) { child = child.host; }
-    if (child == parent) { return true }
-  } while (child = child.parentNode)
-}
-
-function activeElt() {
-  // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
-  // IE < 10 will throw when accessed while the page is loading or in an iframe.
-  // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
-  var activeElement;
-  try {
-    activeElement = document.activeElement;
-  } catch(e) {
-    activeElement = document.body || null;
-  }
-  while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
-    { activeElement = activeElement.shadowRoot.activeElement; }
-  return activeElement
-}
-
-function addClass(node, cls) {
-  var current = node.className;
-  if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; }
-}
-function joinClasses(a, b) {
-  var as = a.split(" ");
-  for (var i = 0; i < as.length; i++)
-    { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } }
-  return b
-}
-
-var selectInput = function(node) { node.select(); };
-if (ios) // Mobile Safari apparently has a bug where select() is broken.
-  { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; }
-else if (ie) // Suppress mysterious IE10 errors
-  { selectInput = function(node) { try { node.select(); } catch(_e) {} }; }
-
-function bind(f) {
-  var args = Array.prototype.slice.call(arguments, 1);
-  return function(){return f.apply(null, args)}
-}
-
-function copyObj(obj, target, overwrite) {
-  if (!target) { target = {}; }
-  for (var prop in obj)
-    { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
-      { target[prop] = obj[prop]; } }
-  return target
-}
-
-// Counts the column offset in a string, taking tabs into account.
-// Used mostly to find indentation.
-function countColumn(string, end, tabSize, startIndex, startValue) {
-  if (end == null) {
-    end = string.search(/[^\s\u00a0]/);
-    if (end == -1) { end = string.length; }
-  }
-  for (var i = startIndex || 0, n = startValue || 0;;) {
-    var nextTab = string.indexOf("\t", i);
-    if (nextTab < 0 || nextTab >= end)
-      { return n + (end - i) }
-    n += nextTab - i;
-    n += tabSize - (n % tabSize);
-    i = nextTab + 1;
-  }
-}
-
-var Delayed = function() {this.id = null;};
-Delayed.prototype.set = function (ms, f) {
-  clearTimeout(this.id);
-  this.id = setTimeout(f, ms);
-};
-
-function indexOf(array, elt) {
-  for (var i = 0; i < array.length; ++i)
-    { if (array[i] == elt) { return i } }
-  return -1
-}
-
-// Number of pixels added to scroller and sizer to hide scrollbar
-var scrollerGap = 30;
-
-// Returned or thrown by various protocols to signal 'I'm not
-// handling this'.
-var Pass = {toString: function(){return "CodeMirror.Pass"}};
-
-// Reused option objects for setSelection & friends
-var sel_dontScroll = {scroll: false};
-var sel_mouse = {origin: "*mouse"};
-var sel_move = {origin: "+move"};
-
-// The inverse of countColumn -- find the offset that corresponds to
-// a particular column.
-function findColumn(string, goal, tabSize) {
-  for (var pos = 0, col = 0;;) {
-    var nextTab = string.indexOf("\t", pos);
-    if (nextTab == -1) { nextTab = string.length; }
-    var skipped = nextTab - pos;
-    if (nextTab == string.length || col + skipped >= goal)
-      { return pos + Math.min(skipped, goal - col) }
-    col += nextTab - pos;
-    col += tabSize - (col % tabSize);
-    pos = nextTab + 1;
-    if (col >= goal) { return pos }
-  }
-}
-
-var spaceStrs = [""];
-function spaceStr(n) {
-  while (spaceStrs.length <= n)
-    { spaceStrs.push(lst(spaceStrs) + " "); }
-  return spaceStrs[n]
-}
-
-function lst(arr) { return arr[arr.length-1] }
-
-function map(array, f) {
-  var out = [];
-  for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); }
-  return out
-}
-
-function insertSorted(array, value, score) {
-  var pos = 0, priority = score(value);
-  while (pos < array.length && score(array[pos]) <= priority) { pos++; }
-  array.splice(pos, 0, value);
-}
-
-function nothing() {}
-
-function createObj(base, props) {
-  var inst;
-  if (Object.create) {
-    inst = Object.create(base);
-  } else {
-    nothing.prototype = base;
-    inst = new nothing();
-  }
-  if (props) { copyObj(props, inst); }
-  return inst
-}
-
-var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
-function isWordCharBasic(ch) {
-  return /\w/.test(ch) || ch > "\x80" &&
-    (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
-}
-function isWordChar(ch, helper) {
-  if (!helper) { return isWordCharBasic(ch) }
-  if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true }
-  return helper.test(ch)
-}
-
-function isEmpty(obj) {
-  for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }
-  return true
-}
-
-// Extending unicode characters. A series of a non-extending char +
-// any number of extending chars is treated as a single unit as far
-// as editing and measuring is concerned. This is not fully correct,
-// since some scripts/fonts/browsers also treat other configurations
-// of code points as a group.
-var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
-function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }
-
-// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.
-function skipExtendingChars(str, pos, dir) {
-  while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; }
-  return pos
-}
-
-// Returns the value from the range [`from`; `to`] that satisfies
-// `pred` and is closest to `from`. Assumes that at least `to`
-// satisfies `pred`. Supports `from` being greater than `to`.
-function findFirst(pred, from, to) {
-  // At any point we are certain `to` satisfies `pred`, don't know
-  // whether `from` does.
-  var dir = from > to ? -1 : 1;
-  for (;;) {
-    if (from == to) { return from }
-    var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF);
-    if (mid == from) { return pred(mid) ? from : to }
-    if (pred(mid)) { to = mid; }
-    else { from = mid + dir; }
-  }
-}
-
-// The display handles the DOM integration, both for input reading
-// and content drawing. It holds references to DOM nodes and
-// display-related state.
-
-function Display(place, doc, input) {
-  var d = this;
-  this.input = input;
-
-  // Covers bottom-right square when both scrollbars are present.
-  d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
-  d.scrollbarFiller.setAttribute("cm-not-content", "true");
-  // Covers bottom of gutter when coverGutterNextToScrollbar is on
-  // and h scrollbar is present.
-  d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
-  d.gutterFiller.setAttribute("cm-not-content", "true");
-  // Will contain the actual code, positioned to cover the viewport.
-  d.lineDiv = eltP("div", null, "CodeMirror-code");
-  // Elements are added to these to represent selection and cursors.
-  d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
-  d.cursorDiv = elt("div", null, "CodeMirror-cursors");
-  // A visibility: hidden element used to find the size of things.
-  d.measure = elt("div", null, "CodeMirror-measure");
-  // When lines outside of the viewport are measured, they are drawn in this.
-  d.lineMeasure = elt("div", null, "CodeMirror-measure");
-  // Wraps everything that needs to exist inside the vertically-padded coordinate system
-  d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
-                    null, "position: relative; outline: none");
-  var lines = eltP("div", [d.lineSpace], "CodeMirror-lines");
-  // Moved around its parent to cover visible view.
-  d.mover = elt("div", [lines], null, "position: relative");
-  // Set to the height of the document, allowing scrolling.
-  d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
-  d.sizerWidth = null;
-  // Behavior of elts with overflow: auto and padding is
-  // inconsistent across browsers. This is used to ensure the
-  // scrollable area is big enough.
-  d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
-  // Will contain the gutters, if any.
-  d.gutters = elt("div", null, "CodeMirror-gutters");
-  d.lineGutter = null;
-  // Actual scrollable element.
-  d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
-  d.scroller.setAttribute("tabIndex", "-1");
-  // The element in which the editor lives.
-  d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
-
-  // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
-  if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
-  if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; }
-
-  if (place) {
-    if (place.appendChild) { place.appendChild(d.wrapper); }
-    else { place(d.wrapper); }
-  }
-
-  // Current rendered range (may be bigger than the view window).
-  d.viewFrom = d.viewTo = doc.first;
-  d.reportedViewFrom = d.reportedViewTo = doc.first;
-  // Information about the rendered lines.
-  d.view = [];
-  d.renderedView = null;
-  // Holds info about a single rendered line when it was rendered
-  // for measurement, while not in view.
-  d.externalMeasured = null;
-  // Empty space (in pixels) above the view
-  d.viewOffset = 0;
-  d.lastWrapHeight = d.lastWrapWidth = 0;
-  d.updateLineNumbers = null;
-
-  d.nativeBarWidth = d.barHeight = d.barWidth = 0;
-  d.scrollbarsClipped = false;
-
-  // Used to only resize the line number gutter when necessary (when
-  // the amount of lines crosses a boundary that makes its width change)
-  d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
-  // Set to true when a non-horizontal-scrolling line widget is
-  // added. As an optimization, line widget aligning is skipped when
-  // this is false.
-  d.alignWidgets = false;
-
-  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
-
-  // Tracks the maximum line length so that the horizontal scrollbar
-  // can be kept static when scrolling.
-  d.maxLine = null;
-  d.maxLineLength = 0;
-  d.maxLineChanged = false;
-
-  // Used for measuring wheel scrolling granularity
-  d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
-
-  // True when shift is held down.
-  d.shift = false;
-
-  // Used to track whether anything happened since the context menu
-  // was opened.
-  d.selForContextMenu = null;
-
-  d.activeTouch = null;
-
-  input.init(d);
-}
-
-// Find the line object corresponding to the given line number.
-function getLine(doc, n) {
-  n -= doc.first;
-  if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
-  var chunk = doc;
-  while (!chunk.lines) {
-    for (var i = 0;; ++i) {
-      var child = chunk.children[i], sz = child.chunkSize();
-      if (n < sz) { chunk = child; break }
-      n -= sz;
-    }
-  }
-  return chunk.lines[n]
-}
-
-// Get the part of a document between two positions, as an array of
-// strings.
-function getBetween(doc, start, end) {
-  var out = [], n = start.line;
-  doc.iter(start.line, end.line + 1, function (line) {
-    var text = line.text;
-    if (n == end.line) { text = text.slice(0, end.ch); }
-    if (n == start.line) { text = text.slice(start.ch); }
-    out.push(text);
-    ++n;
-  });
-  return out
-}
-// Get the lines between from and to, as array of strings.
-function getLines(doc, from, to) {
-  var out = [];
-  doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value
-  return out
-}
-
-// Update the height of a line, propagating the height change
-// upwards to parent nodes.
-function updateLineHeight(line, height) {
-  var diff = height - line.height;
-  if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } }
-}
-
-// Given a line object, find its line number by walking up through
-// its parent links.
-function lineNo(line) {
-  if (line.parent == null) { return null }
-  var cur = line.parent, no = indexOf(cur.lines, line);
-  for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
-    for (var i = 0;; ++i) {
-      if (chunk.children[i] == cur) { break }
-      no += chunk.children[i].chunkSize();
-    }
-  }
-  return no + cur.first
-}
-
-// Find the line at the given vertical position, using the height
-// information in the document tree.
-function lineAtHeight(chunk, h) {
-  var n = chunk.first;
-  outer: do {
-    for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {
-      var child = chunk.children[i$1], ch = child.height;
-      if (h < ch) { chunk = child; continue outer }
-      h -= ch;
-      n += child.chunkSize();
-    }
-    return n
-  } while (!chunk.lines)
-  var i = 0;
-  for (; i < chunk.lines.length; ++i) {
-    var line = chunk.lines[i], lh = line.height;
-    if (h < lh) { break }
-    h -= lh;
-  }
-  return n + i
-}
-
-function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
-
-function lineNumberFor(options, i) {
-  return String(options.lineNumberFormatter(i + options.firstLineNumber))
-}
-
-// A Pos instance represents a position within the text.
-function Pos(line, ch, sticky) {
-  if ( sticky === void 0 ) sticky = null;
-
-  if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }
-  this.line = line;
-  this.ch = ch;
-  this.sticky = sticky;
-}
-
-// Compare two positions, return 0 if they are the same, a negative
-// number when a is less, and a positive number otherwise.
-function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
-
-function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
-
-function copyPos(x) {return Pos(x.line, x.ch)}
-function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
-function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
-
-// Most of the external API clips given positions to make sure they
-// actually exist within the document.
-function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
-function clipPos(doc, pos) {
-  if (pos.line < doc.first) { return Pos(doc.first, 0) }
-  var last = doc.first + doc.size - 1;
-  if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }
-  return clipToLen(pos, getLine(doc, pos.line).text.length)
-}
-function clipToLen(pos, linelen) {
-  var ch = pos.ch;
-  if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }
-  else if (ch < 0) { return Pos(pos.line, 0) }
-  else { return pos }
-}
-function clipPosArray(doc, array) {
-  var out = [];
-  for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); }
-  return out
-}
-
-// Optimize some code when these features are not used.
-var sawReadOnlySpans = false;
-var sawCollapsedSpans = false;
-
-function seeReadOnlySpans() {
-  sawReadOnlySpans = true;
-}
-
-function seeCollapsedSpans() {
-  sawCollapsedSpans = true;
-}
-
-// TEXTMARKER SPANS
-
-function MarkedSpan(marker, from, to) {
-  this.marker = marker;
-  this.from = from; this.to = to;
-}
-
-// Search an array of spans for a span matching the given marker.
-function getMarkedSpanFor(spans, marker) {
-  if (spans) { for (var i = 0; i < spans.length; ++i) {
-    var span = spans[i];
-    if (span.marker == marker) { return span }
-  } }
-}
-// Remove a span from an array, returning undefined if no spans are
-// left (we don't store arrays for lines without spans).
-function removeMarkedSpan(spans, span) {
-  var r;
-  for (var i = 0; i < spans.length; ++i)
-    { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } }
-  return r
-}
-// Add a span to a line.
-function addMarkedSpan(line, span) {
-  line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
-  span.marker.attachLine(line);
-}
-
-// Used for the algorithm that adjusts markers for a change in the
-// document. These functions cut an array of spans at a given
-// character position, returning an array of remaining chunks (or
-// undefined if nothing remains).
-function markedSpansBefore(old, startCh, isInsert) {
-  var nw;
-  if (old) { for (var i = 0; i < old.length; ++i) {
-    var span = old[i], marker = span.marker;
-    var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
-    if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
-      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
-    }
-  } }
-  return nw
-}
-function markedSpansAfter(old, endCh, isInsert) {
-  var nw;
-  if (old) { for (var i = 0; i < old.length; ++i) {
-    var span = old[i], marker = span.marker;
-    var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
-    if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
-      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
-                                            span.to == null ? null : span.to - endCh));
-    }
-  } }
-  return nw
-}
-
-// Given a change object, compute the new set of marker spans that
-// cover the line in which the change took place. Removes spans
-// entirely within the change, reconnects spans belonging to the
-// same marker that appear on both sides of the change, and cuts off
-// spans partially within the change. Returns an array of span
-// arrays with one element for each line in (after) the change.
-function stretchSpansOverChange(doc, change) {
-  if (change.full) { return null }
-  var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
-  var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
-  if (!oldFirst && !oldLast) { return null }
-
-  var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
-  // Get the spans that 'stick out' on both sides
-  var first = markedSpansBefore(oldFirst, startCh, isInsert);
-  var last = markedSpansAfter(oldLast, endCh, isInsert);
-
-  // Next, merge those two ends
-  var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
-  if (first) {
-    // Fix up .to properties of first
-    for (var i = 0; i < first.length; ++i) {
-      var span = first[i];
-      if (span.to == null) {
-        var found = getMarkedSpanFor(last, span.marker);
-        if (!found) { span.to = startCh; }
-        else if (sameLine) { span.to = found.to == null ? null : found.to + offset; }
-      }
-    }
-  }
-  if (last) {
-    // Fix up .from in last (or move them into first in case of sameLine)
-    for (var i$1 = 0; i$1 < last.length; ++i$1) {
-      var span$1 = last[i$1];
-      if (span$1.to != null) { span$1.to += offset; }
-      if (span$1.from == null) {
-        var found$1 = getMarkedSpanFor(first, span$1.marker);
-        if (!found$1) {
-          span$1.from = offset;
-          if (sameLine) { (first || (first = [])).push(span$1); }
-        }
-      } else {
-        span$1.from += offset;
-        if (sameLine) { (first || (first = [])).push(span$1); }
-      }
-    }
-  }
-  // Make sure we didn't create any zero-length spans
-  if (first) { first = clearEmptySpans(first); }
-  if (last && last != first) { last = clearEmptySpans(last); }
-
-  var newMarkers = [first];
-  if (!sameLine) {
-    // Fill gap with whole-line-spans
-    var gap = change.text.length - 2, gapMarkers;
-    if (gap > 0 && first)
-      { for (var i$2 = 0; i$2 < first.length; ++i$2)
-        { if (first[i$2].to == null)
-          { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } }
-    for (var i$3 = 0; i$3 < gap; ++i$3)
-      { newMarkers.push(gapMarkers); }
-    newMarkers.push(last);
-  }
-  return newMarkers
-}
-
-// Remove spans that are empty and don't have a clearWhenEmpty
-// option of false.
-function clearEmptySpans(spans) {
-  for (var i = 0; i < spans.length; ++i) {
-    var span = spans[i];
-    if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
-      { spans.splice(i--, 1); }
-  }
-  if (!spans.length) { return null }
-  return spans
-}
-
-// Used to 'clip' out readOnly ranges when making a change.
-function removeReadOnlyRanges(doc, from, to) {
-  var markers = null;
-  doc.iter(from.line, to.line + 1, function (line) {
-    if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
-      var mark = line.markedSpans[i].marker;
-      if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
-        { (markers || (markers = [])).push(mark); }
-    } }
-  });
-  if (!markers) { return null }
-  var parts = [{from: from, to: to}];
-  for (var i = 0; i < markers.length; ++i) {
-    var mk = markers[i], m = mk.find(0);
-    for (var j = 0; j < parts.length; ++j) {
-      var p = parts[j];
-      if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }
-      var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
-      if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
-        { newParts.push({from: p.from, to: m.from}); }
-      if (dto > 0 || !mk.inclusiveRight && !dto)
-        { newParts.push({from: m.to, to: p.to}); }
-      parts.splice.apply(parts, newParts);
-      j += newParts.length - 3;
-    }
-  }
-  return parts
-}
-
-// Connect or disconnect spans from a line.
-function detachMarkedSpans(line) {
-  var spans = line.markedSpans;
-  if (!spans) { return }
-  for (var i = 0; i < spans.length; ++i)
-    { spans[i].marker.detachLine(line); }
-  line.markedSpans = null;
-}
-function attachMarkedSpans(line, spans) {
-  if (!spans) { return }
-  for (var i = 0; i < spans.length; ++i)
-    { spans[i].marker.attachLine(line); }
-  line.markedSpans = spans;
-}
-
-// Helpers used when computing which overlapping collapsed span
-// counts as the larger one.
-function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
-function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
-
-// Returns a number indicating which of two overlapping collapsed
-// spans is larger (and thus includes the other). Falls back to
-// comparing ids when the spans cover exactly the same range.
-function compareCollapsedMarkers(a, b) {
-  var lenDiff = a.lines.length - b.lines.length;
-  if (lenDiff != 0) { return lenDiff }
-  var aPos = a.find(), bPos = b.find();
-  var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
-  if (fromCmp) { return -fromCmp }
-  var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
-  if (toCmp) { return toCmp }
-  return b.id - a.id
-}
-
-// Find out whether a line ends or starts in a collapsed span. If
-// so, return the marker for that span.
-function collapsedSpanAtSide(line, start) {
-  var sps = sawCollapsedSpans && line.markedSpans, found;
-  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
-    sp = sps[i];
-    if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
-        (!found || compareCollapsedMarkers(found, sp.marker) < 0))
-      { found = sp.marker; }
-  } }
-  return found
-}
-function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
-function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
-
-// Test whether there exists a collapsed span that partially
-// overlaps (covers the start or end, but not both) of a new span.
-// Such overlap is not allowed.
-function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) {
-  var line = getLine(doc, lineNo$$1);
-  var sps = sawCollapsedSpans && line.markedSpans;
-  if (sps) { for (var i = 0; i < sps.length; ++i) {
-    var sp = sps[i];
-    if (!sp.marker.collapsed) { continue }
-    var found = sp.marker.find(0);
-    var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
-    var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
-    if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }
-    if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||
-        fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))
-      { return true }
-  } }
-}
-
-// A visual line is a line as drawn on the screen. Folding, for
-// example, can cause multiple logical lines to appear on the same
-// visual line. This finds the start of the visual line that the
-// given line is part of (usually that is the line itself).
-function visualLine(line) {
-  var merged;
-  while (merged = collapsedSpanAtStart(line))
-    { line = merged.find(-1, true).line; }
-  return line
-}
-
-function visualLineEnd(line) {
-  var merged;
-  while (merged = collapsedSpanAtEnd(line))
-    { line = merged.find(1, true).line; }
-  return line
-}
-
-// Returns an array of logical lines that continue the visual line
-// started by the argument, or undefined if there are no such lines.
-function visualLineContinued(line) {
-  var merged, lines;
-  while (merged = collapsedSpanAtEnd(line)) {
-    line = merged.find(1, true).line
-    ;(lines || (lines = [])).push(line);
-  }
-  return lines
-}
-
-// Get the line number of the start of the visual line that the
-// given line number is part of.
-function visualLineNo(doc, lineN) {
-  var line = getLine(doc, lineN), vis = visualLine(line);
-  if (line == vis) { return lineN }
-  return lineNo(vis)
-}
-
-// Get the line number of the start of the next visual line after
-// the given line.
-function visualLineEndNo(doc, lineN) {
-  if (lineN > doc.lastLine()) { return lineN }
-  var line = getLine(doc, lineN), merged;
-  if (!lineIsHidden(doc, line)) { return lineN }
-  while (merged = collapsedSpanAtEnd(line))
-    { line = merged.find(1, true).line; }
-  return lineNo(line) + 1
-}
-
-// Compute whether a line is hidden. Lines count as hidden when they
-// are part of a visual line that starts with another line, or when
-// they are entirely covered by collapsed, non-widget span.
-function lineIsHidden(doc, line) {
-  var sps = sawCollapsedSpans && line.markedSpans;
-  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
-    sp = sps[i];
-    if (!sp.marker.collapsed) { continue }
-    if (sp.from == null) { return true }
-    if (sp.marker.widgetNode) { continue }
-    if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
-      { return true }
-  } }
-}
-function lineIsHiddenInner(doc, line, span) {
-  if (span.to == null) {
-    var end = span.marker.find(1, true);
-    return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))
-  }
-  if (span.marker.inclusiveRight && span.to == line.text.length)
-    { return true }
-  for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {
-    sp = line.markedSpans[i];
-    if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
-        (sp.to == null || sp.to != span.from) &&
-        (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
-        lineIsHiddenInner(doc, line, sp)) { return true }
-  }
-}
-
-// Find the height above the given line.
-function heightAtLine(lineObj) {
-  lineObj = visualLine(lineObj);
-
-  var h = 0, chunk = lineObj.parent;
-  for (var i = 0; i < chunk.lines.length; ++i) {
-    var line = chunk.lines[i];
-    if (line == lineObj) { break }
-    else { h += line.height; }
-  }
-  for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
-    for (var i$1 = 0; i$1 < p.children.length; ++i$1) {
-      var cur = p.children[i$1];
-      if (cur == chunk) { break }
-      else { h += cur.height; }
-    }
-  }
-  return h
-}
-
-// Compute the character length of a line, taking into account
-// collapsed ranges (see markText) that might hide parts, and join
-// other lines onto it.
-function lineLength(line) {
-  if (line.height == 0) { return 0 }
-  var len = line.text.length, merged, cur = line;
-  while (merged = collapsedSpanAtStart(cur)) {
-    var found = merged.find(0, true);
-    cur = found.from.line;
-    len += found.from.ch - found.to.ch;
-  }
-  cur = line;
-  while (merged = collapsedSpanAtEnd(cur)) {
-    var found$1 = merged.find(0, true);
-    len -= cur.text.length - found$1.from.ch;
-    cur = found$1.to.line;
-    len += cur.text.length - found$1.to.ch;
-  }
-  return len
-}
-
-// Find the longest line in the document.
-function findMaxLine(cm) {
-  var d = cm.display, doc = cm.doc;
-  d.maxLine = getLine(doc, doc.first);
-  d.maxLineLength = lineLength(d.maxLine);
-  d.maxLineChanged = true;
-  doc.iter(function (line) {
-    var len = lineLength(line);
-    if (len > d.maxLineLength) {
-      d.maxLineLength = len;
-      d.maxLine = line;
-    }
-  });
-}
-
-// BIDI HELPERS
-
-function iterateBidiSections(order, from, to, f) {
-  if (!order) { return f(from, to, "ltr", 0) }
-  var found = false;
-  for (var i = 0; i < order.length; ++i) {
-    var part = order[i];
-    if (part.from < to && part.to > from || from == to && part.to == from) {
-      f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i);
-      found = true;
-    }
-  }
-  if (!found) { f(from, to, "ltr"); }
-}
-
-var bidiOther = null;
-function getBidiPartAt(order, ch, sticky) {
-  var found;
-  bidiOther = null;
-  for (var i = 0; i < order.length; ++i) {
-    var cur = order[i];
-    if (cur.from < ch && cur.to > ch) { return i }
-    if (cur.to == ch) {
-      if (cur.from != cur.to && sticky == "before") { found = i; }
-      else { bidiOther = i; }
-    }
-    if (cur.from == ch) {
-      if (cur.from != cur.to && sticky != "before") { found = i; }
-      else { bidiOther = i; }
-    }
-  }
-  return found != null ? found : bidiOther
-}
-
-// Bidirectional ordering algorithm
-// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
-// that this (partially) implements.
-
-// One-char codes used for character types:
-// L (L):   Left-to-Right
-// R (R):   Right-to-Left
-// r (AL):  Right-to-Left Arabic
-// 1 (EN):  European Number
-// + (ES):  European Number Separator
-// % (ET):  European Number Terminator
-// n (AN):  Arabic Number
-// , (CS):  Common Number Separator
-// m (NSM): Non-Spacing Mark
-// b (BN):  Boundary Neutral
-// s (B):   Paragraph Separator
-// t (S):   Segment Separator
-// w (WS):  Whitespace
-// N (ON):  Other Neutrals
-
-// Returns null if characters are ordered as they appear
-// (left-to-right), or an array of sections ({from, to, level}
-// objects) in the order in which they occur visually.
-var bidiOrdering = (function() {
-  // Character types for codepoints 0 to 0xff
-  var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
-  // Character types for codepoints 0x600 to 0x6f9
-  var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";
-  function charType(code) {
-    if (code <= 0xf7) { return lowTypes.charAt(code) }
-    else if (0x590 <= code && code <= 0x5f4) { return "R" }
-    else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }
-    else if (0x6ee <= code && code <= 0x8ac) { return "r" }
-    else if (0x2000 <= code && code <= 0x200b) { return "w" }
-    else if (code == 0x200c) { return "b" }
-    else { return "L" }
-  }
-
-  var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
-  var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
-
-  function BidiSpan(level, from, to) {
-    this.level = level;
-    this.from = from; this.to = to;
-  }
-
-  return function(str, direction) {
-    var outerType = direction == "ltr" ? "L" : "R";
-
-    if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false }
-    var len = str.length, types = [];
-    for (var i = 0; i < len; ++i)
-      { types.push(charType(str.charCodeAt(i))); }
-
-    // W1. Examine each non-spacing mark (NSM) in the level run, and
-    // change the type of the NSM to the type of the previous
-    // character. If the NSM is at the start of the level run, it will
-    // get the type of sor.
-    for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {
-      var type = types[i$1];
-      if (type == "m") { types[i$1] = prev; }
-      else { prev = type; }
-    }
-
-    // W2. Search backwards from each instance of a European number
-    // until the first strong type (R, L, AL, or sor) is found. If an
-    // AL is found, change the type of the European number to Arabic
-    // number.
-    // W3. Change all ALs to R.
-    for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {
-      var type$1 = types[i$2];
-      if (type$1 == "1" && cur == "r") { types[i$2] = "n"; }
-      else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } }
-    }
-
-    // W4. A single European separator between two European numbers
-    // changes to a European number. A single common separator between
-    // two numbers of the same type changes to that type.
-    for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {
-      var type$2 = types[i$3];
-      if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; }
-      else if (type$2 == "," && prev$1 == types[i$3+1] &&
-               (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; }
-      prev$1 = type$2;
-    }
-
-    // W5. A sequence of European terminators adjacent to European
-    // numbers changes to all European numbers.
-    // W6. Otherwise, separators and terminators change to Other
-    // Neutral.
-    for (var i$4 = 0; i$4 < len; ++i$4) {
-      var type$3 = types[i$4];
-      if (type$3 == ",") { types[i$4] = "N"; }
-      else if (type$3 == "%") {
-        var end = (void 0);
-        for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {}
-        var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
-        for (var j = i$4; j < end; ++j) { types[j] = replace; }
-        i$4 = end - 1;
-      }
-    }
-
-    // W7. Search backwards from each instance of a European number
-    // until the first strong type (R, L, or sor) is found. If an L is
-    // found, then change the type of the European number to L.
-    for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {
-      var type$4 = types[i$5];
-      if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; }
-      else if (isStrong.test(type$4)) { cur$1 = type$4; }
-    }
-
-    // N1. A sequence of neutrals takes the direction of the
-    // surrounding strong text if the text on both sides has the same
-    // direction. European and Arabic numbers act as if they were R in
-    // terms of their influence on neutrals. Start-of-level-run (sor)
-    // and end-of-level-run (eor) are used at level run boundaries.
-    // N2. Any remaining neutrals take the embedding direction.
-    for (var i$6 = 0; i$6 < len; ++i$6) {
-      if (isNeutral.test(types[i$6])) {
-        var end$1 = (void 0);
-        for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}
-        var before = (i$6 ? types[i$6-1] : outerType) == "L";
-        var after = (end$1 < len ? types[end$1] : outerType) == "L";
-        var replace$1 = before == after ? (before ? "L" : "R") : outerType;
-        for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; }
-        i$6 = end$1 - 1;
-      }
-    }
-
-    // Here we depart from the documented algorithm, in order to avoid
-    // building up an actual levels array. Since there are only three
-    // levels (0, 1, 2) in an implementation that doesn't take
-    // explicit embedding into account, we can build up the order on
-    // the fly, without following the level-based algorithm.
-    var order = [], m;
-    for (var i$7 = 0; i$7 < len;) {
-      if (countsAsLeft.test(types[i$7])) {
-        var start = i$7;
-        for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
-        order.push(new BidiSpan(0, start, i$7));
-      } else {
-        var pos = i$7, at = order.length;
-        for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
-        for (var j$2 = pos; j$2 < i$7;) {
-          if (countsAsNum.test(types[j$2])) {
-            if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
-            var nstart = j$2;
-            for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
-            order.splice(at, 0, new BidiSpan(2, nstart, j$2));
-            pos = j$2;
-          } else { ++j$2; }
-        }
-        if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); }
-      }
-    }
-    if (direction == "ltr") {
-      if (order[0].level == 1 && (m = str.match(/^\s+/))) {
-        order[0].from = m[0].length;
-        order.unshift(new BidiSpan(0, 0, m[0].length));
-      }
-      if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
-        lst(order).to -= m[0].length;
-        order.push(new BidiSpan(0, len - m[0].length, len));
-      }
-    }
-
-    return direction == "rtl" ? order.reverse() : order
-  }
-})();
-
-// Get the bidi ordering for the given line (and cache it). Returns
-// false for lines that are fully left-to-right, and an array of
-// BidiSpan objects otherwise.
-function getOrder(line, direction) {
-  var order = line.order;
-  if (order == null) { order = line.order = bidiOrdering(line.text, direction); }
-  return order
-}
-
-// EVENT HANDLING
-
-// Lightweight event framework. on/off also work on DOM nodes,
-// registering native DOM handlers.
-
-var noHandlers = [];
-
-var on = function(emitter, type, f) {
-  if (emitter.addEventListener) {
-    emitter.addEventListener(type, f, false);
-  } else if (emitter.attachEvent) {
-    emitter.attachEvent("on" + type, f);
-  } else {
-    var map$$1 = emitter._handlers || (emitter._handlers = {});
-    map$$1[type] = (map$$1[type] || noHandlers).concat(f);
-  }
-};
-
-function getHandlers(emitter, type) {
-  return emitter._handlers && emitter._handlers[type] || noHandlers
-}
-
-function off(emitter, type, f) {
-  if (emitter.removeEventListener) {
-    emitter.removeEventListener(type, f, false);
-  } else if (emitter.detachEvent) {
-    emitter.detachEvent("on" + type, f);
-  } else {
-    var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type];
-    if (arr) {
-      var index = indexOf(arr, f);
-      if (index > -1)
-        { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
-    }
-  }
-}
-
-function signal(emitter, type /*, values...*/) {
-  var handlers = getHandlers(emitter, type);
-  if (!handlers.length) { return }
-  var args = Array.prototype.slice.call(arguments, 2);
-  for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); }
-}
-
-// The DOM events that CodeMirror handles can be overridden by
-// registering a (non-DOM) handler on the editor for the event name,
-// and preventDefault-ing the event in that handler.
-function signalDOMEvent(cm, e, override) {
-  if (typeof e == "string")
-    { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; }
-  signal(cm, override || e.type, cm, e);
-  return e_defaultPrevented(e) || e.codemirrorIgnore
-}
-
-function signalCursorActivity(cm) {
-  var arr = cm._handlers && cm._handlers.cursorActivity;
-  if (!arr) { return }
-  var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
-  for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)
-    { set.push(arr[i]); } }
-}
-
-function hasHandler(emitter, type) {
-  return getHandlers(emitter, type).length > 0
-}
-
-// Add on and off methods to a constructor's prototype, to make
-// registering events on such objects more convenient.
-function eventMixin(ctor) {
-  ctor.prototype.on = function(type, f) {on(this, type, f);};
-  ctor.prototype.off = function(type, f) {off(this, type, f);};
-}
-
-// Due to the fact that we still support jurassic IE versions, some
-// compatibility wrappers are needed.
-
-function e_preventDefault(e) {
-  if (e.preventDefault) { e.preventDefault(); }
-  else { e.returnValue = false; }
-}
-function e_stopPropagation(e) {
-  if (e.stopPropagation) { e.stopPropagation(); }
-  else { e.cancelBubble = true; }
-}
-function e_defaultPrevented(e) {
-  return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false
-}
-function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
-
-function e_target(e) {return e.target || e.srcElement}
-function e_button(e) {
-  var b = e.which;
-  if (b == null) {
-    if (e.button & 1) { b = 1; }
-    else if (e.button & 2) { b = 3; }
-    else if (e.button & 4) { b = 2; }
-  }
-  if (mac && e.ctrlKey && b == 1) { b = 3; }
-  return b
-}
-
-// Detect drag-and-drop
-var dragAndDrop = function() {
-  // There is *some* kind of drag-and-drop support in IE6-8, but I
-  // couldn't get it to work yet.
-  if (ie && ie_version < 9) { return false }
-  var div = elt('div');
-  return "draggable" in div || "dragDrop" in div
-}();
-
-var zwspSupported;
-function zeroWidthElement(measure) {
-  if (zwspSupported == null) {
-    var test = elt("span", "\u200b");
-    removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
-    if (measure.firstChild.offsetHeight != 0)
-      { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); }
-  }
-  var node = zwspSupported ? elt("span", "\u200b") :
-    elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
-  node.setAttribute("cm-text", "");
-  return node
-}
-
-// Feature-detect IE's crummy client rect reporting for bidi text
-var badBidiRects;
-function hasBadBidiRects(measure) {
-  if (badBidiRects != null) { return badBidiRects }
-  var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
-  var r0 = range(txt, 0, 1).getBoundingClientRect();
-  var r1 = range(txt, 1, 2).getBoundingClientRect();
-  removeChildren(measure);
-  if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)
-  return badBidiRects = (r1.right - r0.right < 3)
-}
-
-// See if "".split is the broken IE version, if so, provide an
-// alternative way to split lines.
-var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) {
-  var pos = 0, result = [], l = string.length;
-  while (pos <= l) {
-    var nl = string.indexOf("\n", pos);
-    if (nl == -1) { nl = string.length; }
-    var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
-    var rt = line.indexOf("\r");
-    if (rt != -1) {
-      result.push(line.slice(0, rt));
-      pos += rt + 1;
-    } else {
-      result.push(line);
-      pos = nl + 1;
-    }
-  }
-  return result
-} : function (string) { return string.split(/\r\n?|\n/); };
-
-var hasSelection = window.getSelection ? function (te) {
-  try { return te.selectionStart != te.selectionEnd }
-  catch(e) { return false }
-} : function (te) {
-  var range$$1;
-  try {range$$1 = te.ownerDocument.selection.createRange();}
-  catch(e) {}
-  if (!range$$1 || range$$1.parentElement() != te) { return false }
-  return range$$1.compareEndPoints("StartToEnd", range$$1) != 0
-};
-
-var hasCopyEvent = (function () {
-  var e = elt("div");
-  if ("oncopy" in e) { return true }
-  e.setAttribute("oncopy", "return;");
-  return typeof e.oncopy == "function"
-})();
-
-var badZoomedRects = null;
-function hasBadZoomedRects(measure) {
-  if (badZoomedRects != null) { return badZoomedRects }
-  var node = removeChildrenAndAdd(measure, elt("span", "x"));
-  var normal = node.getBoundingClientRect();
-  var fromRange = range(node, 0, 1).getBoundingClientRect();
-  return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1
-}
-
-// Known modes, by name and by MIME
-var modes = {};
-var mimeModes = {};
-
-// Extra arguments are stored as the mode's dependencies, which is
-// used by (legacy) mechanisms like loadmode.js to automatically
-// load a mode. (Preferred mechanism is the require/define calls.)
-function defineMode(name, mode) {
-  if (arguments.length > 2)
-    { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
-  modes[name] = mode;
-}
-
-function defineMIME(mime, spec) {
-  mimeModes[mime] = spec;
-}
-
-// Given a MIME type, a {name, ...options} config object, or a name
-// string, return a mode config object.
-function resolveMode(spec) {
-  if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
-    spec = mimeModes[spec];
-  } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
-    var found = mimeModes[spec.name];
-    if (typeof found == "string") { found = {name: found}; }
-    spec = createObj(found, spec);
-    spec.name = found.name;
-  } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
-    return resolveMode("application/xml")
-  } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
-    return resolveMode("application/json")
-  }
-  if (typeof spec == "string") { return {name: spec} }
-  else { return spec || {name: "null"} }
-}
-
-// Given a mode spec (anything that resolveMode accepts), find and
-// initialize an actual mode object.
-function getMode(options, spec) {
-  spec = resolveMode(spec);
-  var mfactory = modes[spec.name];
-  if (!mfactory) { return getMode(options, "text/plain") }
-  var modeObj = mfactory(options, spec);
-  if (modeExtensions.hasOwnProperty(spec.name)) {
-    var exts = modeExtensions[spec.name];
-    for (var prop in exts) {
-      if (!exts.hasOwnProperty(prop)) { continue }
-      if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
-      modeObj[prop] = exts[prop];
-    }
-  }
-  modeObj.name = spec.name;
-  if (spec.helperType) { modeObj.helperType = spec.helperType; }
-  if (spec.modeProps) { for (var prop$1 in spec.modeProps)
-    { modeObj[prop$1] = spec.modeProps[prop$1]; } }
-
-  return modeObj
-}
-
-// This can be used to attach properties to mode objects from
-// outside the actual mode definition.
-var modeExtensions = {};
-function extendMode(mode, properties) {
-  var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
-  copyObj(properties, exts);
-}
-
-function copyState(mode, state) {
-  if (state === true) { return state }
-  if (mode.copyState) { return mode.copyState(state) }
-  var nstate = {};
-  for (var n in state) {
-    var val = state[n];
-    if (val instanceof Array) { val = val.concat([]); }
-    nstate[n] = val;
-  }
-  return nstate
-}
-
-// Given a mode and a state (for that mode), find the inner mode and
-// state at the position that the state refers to.
-function innerMode(mode, state) {
-  var info;
-  while (mode.innerMode) {
-    info = mode.innerMode(state);
-    if (!info || info.mode == mode) { break }
-    state = info.state;
-    mode = info.mode;
-  }
-  return info || {mode: mode, state: state}
-}
-
-function startState(mode, a1, a2) {
-  return mode.startState ? mode.startState(a1, a2) : true
-}
-
-// STRING STREAM
-
-// Fed to the mode parsers, provides helper functions to make
-// parsers more succinct.
-
-var StringStream = function(string, tabSize, lineOracle) {
-  this.pos = this.start = 0;
-  this.string = string;
-  this.tabSize = tabSize || 8;
-  this.lastColumnPos = this.lastColumnValue = 0;
-  this.lineStart = 0;
-  this.lineOracle = lineOracle;
-};
-
-StringStream.prototype.eol = function () {return this.pos >= this.string.length};
-StringStream.prototype.sol = function () {return this.pos == this.lineStart};
-StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
-StringStream.prototype.next = function () {
-  if (this.pos < this.string.length)
-    { return this.string.charAt(this.pos++) }
-};
-StringStream.prototype.eat = function (match) {
-  var ch = this.string.charAt(this.pos);
-  var ok;
-  if (typeof match == "string") { ok = ch == match; }
-  else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
-  if (ok) {++this.pos; return ch}
-};
-StringStream.prototype.eatWhile = function (match) {
-  var start = this.pos;
-  while (this.eat(match)){}
-  return this.pos > start
-};
-StringStream.prototype.eatSpace = function () {
-    var this$1 = this;
-
-  var start = this.pos;
-  while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; }
-  return this.pos > start
-};
-StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
-StringStream.prototype.skipTo = function (ch) {
-  var found = this.string.indexOf(ch, this.pos);
-  if (found > -1) {this.pos = found; return true}
-};
-StringStream.prototype.backUp = function (n) {this.pos -= n;};
-StringStream.prototype.column = function () {
-  if (this.lastColumnPos < this.start) {
-    this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
-    this.lastColumnPos = this.start;
-  }
-  return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
-};
-StringStream.prototype.indentation = function () {
-  return countColumn(this.string, null, this.tabSize) -
-    (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
-};
-StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
-  if (typeof pattern == "string") {
-    var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
-    var substr = this.string.substr(this.pos, pattern.length);
-    if (cased(substr) == cased(pattern)) {
-      if (consume !== false) { this.pos += pattern.length; }
-      return true
-    }
-  } else {
-    var match = this.string.slice(this.pos).match(pattern);
-    if (match && match.index > 0) { return null }
-    if (match && consume !== false) { this.pos += match[0].length; }
-    return match
-  }
-};
-StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
-StringStream.prototype.hideFirstChars = function (n, inner) {
-  this.lineStart += n;
-  try { return inner() }
-  finally { this.lineStart -= n; }
-};
-StringStream.prototype.lookAhead = function (n) {
-  var oracle = this.lineOracle;
-  return oracle && oracle.lookAhead(n)
-};
-StringStream.prototype.baseToken = function () {
-  var oracle = this.lineOracle;
-  return oracle && oracle.baseToken(this.pos)
-};
-
-var SavedContext = function(state, lookAhead) {
-  this.state = state;
-  this.lookAhead = lookAhead;
-};
-
-var Context = function(doc, state, line, lookAhead) {
-  this.state = state;
-  this.doc = doc;
-  this.line = line;
-  this.maxLookAhead = lookAhead || 0;
-  this.baseTokens = null;
-  this.baseTokenPos = 1;
-};
-
-Context.prototype.lookAhead = function (n) {
-  var line = this.doc.getLine(this.line + n);
-  if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; }
-  return line
-};
-
-Context.prototype.baseToken = function (n) {
-    var this$1 = this;
-
-  if (!this.baseTokens) { return null }
-  while (this.baseTokens[this.baseTokenPos] <= n)
-    { this$1.baseTokenPos += 2; }
-  var type = this.baseTokens[this.baseTokenPos + 1];
-  return {type: type && type.replace(/( |^)overlay .*/, ""),
-          size: this.baseTokens[this.baseTokenPos] - n}
-};
-
-Context.prototype.nextLine = function () {
-  this.line++;
-  if (this.maxLookAhead > 0) { this.maxLookAhead--; }
-};
-
-Context.fromSaved = function (doc, saved, line) {
-  if (saved instanceof SavedContext)
-    { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) }
-  else
-    { return new Context(doc, copyState(doc.mode, saved), line) }
-};
-
-Context.prototype.save = function (copy) {
-  var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state;
-  return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state
-};
-
-
-// Compute a style array (an array starting with a mode generation
-// -- for invalidation -- followed by pairs of end positions and
-// style strings), which is used to highlight the tokens on the
-// line.
-function highlightLine(cm, line, context, forceToEnd) {
-  // A styles array always starts with a number identifying the
-  // mode/overlays that it is based on (for easy invalidation).
-  var st = [cm.state.modeGen], lineClasses = {};
-  // Compute the base array of styles
-  runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },
-          lineClasses, forceToEnd);
-  var state = context.state;
-
-  // Run overlays, adjust style array.
-  var loop = function ( o ) {
-    context.baseTokens = st;
-    var overlay = cm.state.overlays[o], i = 1, at = 0;
-    context.state = true;
-    runMode(cm, line.text, overlay.mode, context, function (end, style) {
-      var start = i;
-      // Ensure there's a token end at the current position, and that i points at it
-      while (at < end) {
-        var i_end = st[i];
-        if (i_end > end)
-          { st.splice(i, 1, end, st[i+1], i_end); }
-        i += 2;
-        at = Math.min(end, i_end);
-      }
-      if (!style) { return }
-      if (overlay.opaque) {
-        st.splice(start, i - start, end, "overlay " + style);
-        i = start + 2;
-      } else {
-        for (; start < i; start += 2) {
-          var cur = st[start+1];
-          st[start+1] = (cur ? cur + " " : "") + "overlay " + style;
-        }
-      }
-    }, lineClasses);
-    context.state = state;
-    context.baseTokens = null;
-    context.baseTokenPos = 1;
-  };
-
-  for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
-
-  return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
-}
-
-function getLineStyles(cm, line, updateFrontier) {
-  if (!line.styles || line.styles[0] != cm.state.modeGen) {
-    var context = getContextBefore(cm, lineNo(line));
-    var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state);
-    var result = highlightLine(cm, line, context);
-    if (resetState) { context.state = resetState; }
-    line.stateAfter = context.save(!resetState);
-    line.styles = result.styles;
-    if (result.classes) { line.styleClasses = result.classes; }
-    else if (line.styleClasses) { line.styleClasses = null; }
-    if (updateFrontier === cm.doc.highlightFrontier)
-      { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); }
-  }
-  return line.styles
-}
-
-function getContextBefore(cm, n, precise) {
-  var doc = cm.doc, display = cm.display;
-  if (!doc.mode.startState) { return new Context(doc, true, n) }
-  var start = findStartLine(cm, n, precise);
-  var saved = start > doc.first && getLine(doc, start - 1).stateAfter;
-  var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start);
-
-  doc.iter(start, n, function (line) {
-    processLine(cm, line.text, context);
-    var pos = context.line;
-    line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null;
-    context.nextLine();
-  });
-  if (precise) { doc.modeFrontier = context.line; }
-  return context
-}
-
-// Lightweight form of highlight -- proceed over this line and
-// update state, but don't save a style array. Used for lines that
-// aren't currently visible.
-function processLine(cm, text, context, startAt) {
-  var mode = cm.doc.mode;
-  var stream = new StringStream(text, cm.options.tabSize, context);
-  stream.start = stream.pos = startAt || 0;
-  if (text == "") { callBlankLine(mode, context.state); }
-  while (!stream.eol()) {
-    readToken(mode, stream, context.state);
-    stream.start = stream.pos;
-  }
-}
-
-function callBlankLine(mode, state) {
-  if (mode.blankLine) { return mode.blankLine(state) }
-  if (!mode.innerMode) { return }
-  var inner = innerMode(mode, state);
-  if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
-}
-
-function readToken(mode, stream, state, inner) {
-  for (var i = 0; i < 10; i++) {
-    if (inner) { inner[0] = innerMode(mode, state).mode; }
-    var style = mode.token(stream, state);
-    if (stream.pos > stream.start) { return style }
-  }
-  throw new Error("Mode " + mode.name + " failed to advance stream.")
-}
-
-var Token = function(stream, type, state) {
-  this.start = stream.start; this.end = stream.pos;
-  this.string = stream.current();
-  this.type = type || null;
-  this.state = state;
-};
-
-// Utility for getTokenAt and getLineTokens
-function takeToken(cm, pos, precise, asArray) {
-  var doc = cm.doc, mode = doc.mode, style;
-  pos = clipPos(doc, pos);
-  var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);
-  var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;
-  if (asArray) { tokens = []; }
-  while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
-    stream.start = stream.pos;
-    style = readToken(mode, stream, context.state);
-    if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); }
-  }
-  return asArray ? tokens : new Token(stream, style, context.state)
-}
-
-function extractLineClasses(type, output) {
-  if (type) { for (;;) {
-    var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
-    if (!lineClass) { break }
-    type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
-    var prop = lineClass[1] ? "bgClass" : "textClass";
-    if (output[prop] == null)
-      { output[prop] = lineClass[2]; }
-    else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
-      { output[prop] += " " + lineClass[2]; }
-  } }
-  return type
-}
-
-// Run the given mode's parser over a line, calling f for each token.
-function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
-  var flattenSpans = mode.flattenSpans;
-  if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; }
-  var curStart = 0, curStyle = null;
-  var stream = new StringStream(text, cm.options.tabSize, context), style;
-  var inner = cm.options.addModeClass && [null];
-  if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); }
-  while (!stream.eol()) {
-    if (stream.pos > cm.options.maxHighlightLength) {
-      flattenSpans = false;
-      if (forceToEnd) { processLine(cm, text, context, stream.pos); }
-      stream.pos = text.length;
-      style = null;
-    } else {
-      style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses);
-    }
-    if (inner) {
-      var mName = inner[0].name;
-      if (mName) { style = "m-" + (style ? mName + " " + style : mName); }
-    }
-    if (!flattenSpans || curStyle != style) {
-      while (curStart < stream.start) {
-        curStart = Math.min(stream.start, curStart + 5000);
-        f(curStart, curStyle);
-      }
-      curStyle = style;
-    }
-    stream.start = stream.pos;
-  }
-  while (curStart < stream.pos) {
-    // Webkit seems to refuse to render text nodes longer than 57444
-    // characters, and returns inaccurate measurements in nodes
-    // starting around 5000 chars.
-    var pos = Math.min(stream.pos, curStart + 5000);
-    f(pos, curStyle);
-    curStart = pos;
-  }
-}
-
-// Finds the line to start with when starting a parse. Tries to
-// find a line with a stateAfter, so that it can start with a
-// valid state. If that fails, it returns the line with the
-// smallest indentation, which tends to need the least context to
-// parse correctly.
-function findStartLine(cm, n, precise) {
-  var minindent, minline, doc = cm.doc;
-  var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
-  for (var search = n; search > lim; --search) {
-    if (search <= doc.first) { return doc.first }
-    var line = getLine(doc, search - 1), after = line.stateAfter;
-    if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))
-      { return search }
-    var indented = countColumn(line.text, null, cm.options.tabSize);
-    if (minline == null || minindent > indented) {
-      minline = search - 1;
-      minindent = indented;
-    }
-  }
-  return minline
-}
-
-function retreatFrontier(doc, n) {
-  doc.modeFrontier = Math.min(doc.modeFrontier, n);
-  if (doc.highlightFrontier < n - 10) { return }
-  var start = doc.first;
-  for (var line = n - 1; line > start; line--) {
-    var saved = getLine(doc, line).stateAfter;
-    // change is on 3
-    // state on line 1 looked ahead 2 -- so saw 3
-    // test 1 + 2 < 3 should cover this
-    if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {
-      start = line + 1;
-      break
-    }
-  }
-  doc.highlightFrontier = Math.min(doc.highlightFrontier, start);
-}
-
-// LINE DATA STRUCTURE
-
-// Line objects. These hold state related to a line, including
-// highlighting info (the styles array).
-var Line = function(text, markedSpans, estimateHeight) {
-  this.text = text;
-  attachMarkedSpans(this, markedSpans);
-  this.height = estimateHeight ? estimateHeight(this) : 1;
-};
-
-Line.prototype.lineNo = function () { return lineNo(this) };
-eventMixin(Line);
-
-// Change the content (text, markers) of a line. Automatically
-// invalidates cached information and tries to re-estimate the
-// line's height.
-function updateLine(line, text, markedSpans, estimateHeight) {
-  line.text = text;
-  if (line.stateAfter) { line.stateAfter = null; }
-  if (line.styles) { line.styles = null; }
-  if (line.order != null) { line.order = null; }
-  detachMarkedSpans(line);
-  attachMarkedSpans(line, markedSpans);
-  var estHeight = estimateHeight ? estimateHeight(line) : 1;
-  if (estHeight != line.height) { updateLineHeight(line, estHeight); }
-}
-
-// Detach a line from the document tree and its markers.
-function cleanUpLine(line) {
-  line.parent = null;
-  detachMarkedSpans(line);
-}
-
-// Convert a style as returned by a mode (either null, or a string
-// containing one or more styles) to a CSS style. This is cached,
-// and also looks for line-wide styles.
-var styleToClassCache = {};
-var styleToClassCacheWithMode = {};
-function interpretTokenStyle(style, options) {
-  if (!style || /^\s*$/.test(style)) { return null }
-  var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
-  return cache[style] ||
-    (cache[style] = style.replace(/\S+/g, "cm-$&"))
-}
-
-// Render the DOM representation of the text of a line. Also builds
-// up a 'line map', which points at the DOM nodes that represent
-// specific stretches of text, and is used by the measuring code.
-// The returned object contains the DOM node, this map, and
-// information about line-wide styles that were set by the mode.
-function buildLineContent(cm, lineView) {
-  // The padding-right forces the element to have a 'border', which
-  // is needed on Webkit to be able to get line-level bounding
-  // rectangles for it (in measureChar).
-  var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null);
-  var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
-                 col: 0, pos: 0, cm: cm,
-                 trailingSpace: false,
-                 splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
-  lineView.measure = {};
-
-  // Iterate over the logical lines that make up this visual line.
-  for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
-    var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0);
-    builder.pos = 0;
-    builder.addToken = buildToken;
-    // Optionally wire in some hacks into the token-rendering
-    // algorithm, to deal with browser quirks.
-    if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))
-      { builder.addToken = buildTokenBadBidi(builder.addToken, order); }
-    builder.map = [];
-    var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
-    insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
-    if (line.styleClasses) {
-      if (line.styleClasses.bgClass)
-        { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); }
-      if (line.styleClasses.textClass)
-        { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); }
-    }
-
-    // Ensure at least a single node is present, for measuring.
-    if (builder.map.length == 0)
-      { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); }
-
-    // Store the map and a cache object for the current logical line
-    if (i == 0) {
-      lineView.measure.map = builder.map;
-      lineView.measure.cache = {};
-    } else {
-      (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)
-      ;(lineView.measure.caches || (lineView.measure.caches = [])).push({});
-    }
-  }
-
-  // See issue #2901
-  if (webkit) {
-    var last = builder.content.lastChild;
-    if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab")))
-      { builder.content.className = "cm-tab-wrap-hack"; }
-  }
-
-  signal(cm, "renderLine", cm, lineView.line, builder.pre);
-  if (builder.pre.className)
-    { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); }
-
-  return builder
-}
-
-function defaultSpecialCharPlaceholder(ch) {
-  var token = elt("span", "\u2022", "cm-invalidchar");
-  token.title = "\\u" + ch.charCodeAt(0).toString(16);
-  token.setAttribute("aria-label", token.title);
-  return token
-}
-
-// Build up the DOM representation for a single token, and add it to
-// the line map. Takes care to render special characters separately.
-function buildToken(builder, text, style, startStyle, endStyle, title, css) {
-  if (!text) { return }
-  var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text;
-  var special = builder.cm.state.specialChars, mustWrap = false;
-  var content;
-  if (!special.test(text)) {
-    builder.col += text.length;
-    content = document.createTextNode(displayText);
-    builder.map.push(builder.pos, builder.pos + text.length, content);
-    if (ie && ie_version < 9) { mustWrap = true; }
-    builder.pos += text.length;
-  } else {
-    content = document.createDocumentFragment();
-    var pos = 0;
-    while (true) {
-      special.lastIndex = pos;
-      var m = special.exec(text);
-      var skipped = m ? m.index - pos : text.length - pos;
-      if (skipped) {
-        var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
-        if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); }
-        else { content.appendChild(txt); }
-        builder.map.push(builder.pos, builder.pos + skipped, txt);
-        builder.col += skipped;
-        builder.pos += skipped;
-      }
-      if (!m) { break }
-      pos += skipped + 1;
-      var txt$1 = (void 0);
-      if (m[0] == "\t") {
-        var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
-        txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
-        txt$1.setAttribute("role", "presentation");
-        txt$1.setAttribute("cm-text", "\t");
-        builder.col += tabWidth;
-      } else if (m[0] == "\r" || m[0] == "\n") {
-        txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
-        txt$1.setAttribute("cm-text", m[0]);
-        builder.col += 1;
-      } else {
-        txt$1 = builder.cm.options.specialCharPlaceholder(m[0]);
-        txt$1.setAttribute("cm-text", m[0]);
-        if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); }
-        else { content.appendChild(txt$1); }
-        builder.col += 1;
-      }
-      builder.map.push(builder.pos, builder.pos + 1, txt$1);
-      builder.pos++;
-    }
-  }
-  builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32;
-  if (style || startStyle || endStyle || mustWrap || css) {
-    var fullStyle = style || "";
-    if (startStyle) { fullStyle += startStyle; }
-    if (endStyle) { fullStyle += endStyle; }
-    var token = elt("span", [content], fullStyle, css);
-    if (title) { token.title = title; }
-    return builder.content.appendChild(token)
-  }
-  builder.content.appendChild(content);
-}
-
-function splitSpaces(text, trailingBefore) {
-  if (text.length > 1 && !/  /.test(text)) { return text }
-  var spaceBefore = trailingBefore, result = "";
-  for (var i = 0; i < text.length; i++) {
-    var ch = text.charAt(i);
-    if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))
-      { ch = "\u00a0"; }
-    result += ch;
-    spaceBefore = ch == " ";
-  }
-  return result
-}
-
-// Work around nonsense dimensions being reported for stretches of
-// right-to-left text.
-function buildTokenBadBidi(inner, order) {
-  return function (builder, text, style, startStyle, endStyle, title, css) {
-    style = style ? style + " cm-force-border" : "cm-force-border";
-    var start = builder.pos, end = start + text.length;
-    for (;;) {
-      // Find the part that overlaps with the start of this text
-      var part = (void 0);
-      for (var i = 0; i < order.length; i++) {
-        part = order[i];
-        if (part.to > start && part.from <= start) { break }
-      }
-      if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) }
-      inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
-      startStyle = null;
-      text = text.slice(part.to - start);
-      start = part.to;
-    }
-  }
-}
-
-function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
-  var widget = !ignoreWidget && marker.widgetNode;
-  if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); }
-  if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
-    if (!widget)
-      { widget = builder.content.appendChild(document.createElement("span")); }
-    widget.setAttribute("cm-marker", marker.id);
-  }
-  if (widget) {
-    builder.cm.display.input.setUneditable(widget);
-    builder.content.appendChild(widget);
-  }
-  builder.pos += size;
-  builder.trailingSpace = false;
-}
-
-// Outputs a number of spans to make up a line, taking highlighting
-// and marked text into account.
-function insertLineContent(line, builder, styles) {
-  var spans = line.markedSpans, allText = line.text, at = 0;
-  if (!spans) {
-    for (var i$1 = 1; i$1 < styles.length; i$1+=2)
-      { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); }
-    return
-  }
-
-  var len = allText.length, pos = 0, i = 1, text = "", style, css;
-  var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
-  for (;;) {
-    if (nextChange == pos) { // Update current marker set
-      spanStyle = spanEndStyle = spanStartStyle = title = css = "";
-      collapsed = null; nextChange = Infinity;
-      var foundBookmarks = [], endStyles = (void 0);
-      for (var j = 0; j < spans.length; ++j) {
-        var sp = spans[j], m = sp.marker;
-        if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
-          foundBookmarks.push(m);
-        } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
-          if (sp.to != null && sp.to != pos && nextChange > sp.to) {
-            nextChange = sp.to;
-            spanEndStyle = "";
-          }
-          if (m.className) { spanStyle += " " + m.className; }
-          if (m.css) { css = (css ? css + ";" : "") + m.css; }
-          if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; }
-          if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); }
-          if (m.title && !title) { title = m.title; }
-          if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
-            { collapsed = sp; }
-        } else if (sp.from > pos && nextChange > sp.from) {
-          nextChange = sp.from;
-        }
-      }
-      if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)
-        { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } }
-
-      if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)
-        { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } }
-      if (collapsed && (collapsed.from || 0) == pos) {
-        buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
-                           collapsed.marker, collapsed.from == null);
-        if (collapsed.to == null) { return }
-        if (collapsed.to == pos) { collapsed = false; }
-      }
-    }
-    if (pos >= len) { break }
-
-    var upto = Math.min(len, nextChange);
-    while (true) {
-      if (text) {
-        var end = pos + text.length;
-        if (!collapsed) {
-          var tokenText = end > upto ? text.slice(0, upto - pos) : text;
-          builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
-                           spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
-        }
-        if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}
-        pos = end;
-        spanStartStyle = "";
-      }
-      text = allText.slice(at, at = styles[i++]);
-      style = interpretTokenStyle(styles[i++], builder.cm.options);
-    }
-  }
-}
-
-
-// These objects are used to represent the visible (currently drawn)
-// part of the document. A LineView may correspond to multiple
-// logical lines, if those are connected by collapsed ranges.
-function LineView(doc, line, lineN) {
-  // The starting line
-  this.line = line;
-  // Continuing lines, if any
-  this.rest = visualLineContinued(line);
-  // Number of logical lines in this visual line
-  this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
-  this.node = this.text = null;
-  this.hidden = lineIsHidden(doc, line);
-}
-
-// Create a range of LineView objects for the given lines.
-function buildViewArray(cm, from, to) {
-  var array = [], nextPos;
-  for (var pos = from; pos < to; pos = nextPos) {
-    var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
-    nextPos = pos + view.size;
-    array.push(view);
-  }
-  return array
-}
-
-var operationGroup = null;
-
-function pushOperation(op) {
-  if (operationGroup) {
-    operationGroup.ops.push(op);
-  } else {
-    op.ownsGroup = operationGroup = {
-      ops: [op],
-      delayedCallbacks: []
-    };
-  }
-}
-
-function fireCallbacksForOps(group) {
-  // Calls delayed callbacks and cursorActivity handlers until no
-  // new ones appear
-  var callbacks = group.delayedCallbacks, i = 0;
-  do {
-    for (; i < callbacks.length; i++)
-      { callbacks[i].call(null); }
-    for (var j = 0; j < group.ops.length; j++) {
-      var op = group.ops[j];
-      if (op.cursorActivityHandlers)
-        { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
-          { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } }
-    }
-  } while (i < callbacks.length)
-}
-
-function finishOperation(op, endCb) {
-  var group = op.ownsGroup;
-  if (!group) { return }
-
-  try { fireCallbacksForOps(group); }
-  finally {
-    operationGroup = null;
-    endCb(group);
-  }
-}
-
-var orphanDelayedCallbacks = null;
-
-// Often, we want to signal events at a point where we are in the
-// middle of some work, but don't want the handler to start calling
-// other methods on the editor, which might be in an inconsistent
-// state or simply not expect any other events to happen.
-// signalLater looks whether there are any handlers, and schedules
-// them to be executed when the last operation ends, or, if no
-// operation is active, when a timeout fires.
-function signalLater(emitter, type /*, values...*/) {
-  var arr = getHandlers(emitter, type);
-  if (!arr.length) { return }
-  var args = Array.prototype.slice.call(arguments, 2), list;
-  if (operationGroup) {
-    list = operationGroup.delayedCallbacks;
-  } else if (orphanDelayedCallbacks) {
-    list = orphanDelayedCallbacks;
-  } else {
-    list = orphanDelayedCallbacks = [];
-    setTimeout(fireOrphanDelayed, 0);
-  }
-  var loop = function ( i ) {
-    list.push(function () { return arr[i].apply(null, args); });
-  };
-
-  for (var i = 0; i < arr.length; ++i)
-    loop( i );
-}
-
-function fireOrphanDelayed() {
-  var delayed = orphanDelayedCallbacks;
-  orphanDelayedCallbacks = null;
-  for (var i = 0; i < delayed.length; ++i) { delayed[i](); }
-}
-
-// When an aspect of a line changes, a string is added to
-// lineView.changes. This updates the relevant part of the line's
-// DOM structure.
-function updateLineForChanges(cm, lineView, lineN, dims) {
-  for (var j = 0; j < lineView.changes.length; j++) {
-    var type = lineView.changes[j];
-    if (type == "text") { updateLineText(cm, lineView); }
-    else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); }
-    else if (type == "class") { updateLineClasses(cm, lineView); }
-    else if (type == "widget") { updateLineWidgets(cm, lineView, dims); }
-  }
-  lineView.changes = null;
-}
-
-// Lines with gutter elements, widgets or a background class need to
-// be wrapped, and have the extra elements added to the wrapper div
-function ensureLineWrapped(lineView) {
-  if (lineView.node == lineView.text) {
-    lineView.node = elt("div", null, null, "position: relative");
-    if (lineView.text.parentNode)
-      { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); }
-    lineView.node.appendChild(lineView.text);
-    if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; }
-  }
-  return lineView.node
-}
-
-function updateLineBackground(cm, lineView) {
-  var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
-  if (cls) { cls += " CodeMirror-linebackground"; }
-  if (lineView.background) {
-    if (cls) { lineView.background.className = cls; }
-    else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
-  } else if (cls) {
-    var wrap = ensureLineWrapped(lineView);
-    lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
-    cm.display.input.setUneditable(lineView.background);
-  }
-}
-
-// Wrapper around buildLineContent which will reuse the structure
-// in display.externalMeasured when possible.
-function getLineContent(cm, lineView) {
-  var ext = cm.display.externalMeasured;
-  if (ext && ext.line == lineView.line) {
-    cm.display.externalMeasured = null;
-    lineView.measure = ext.measure;
-    return ext.built
-  }
-  return buildLineContent(cm, lineView)
-}
-
-// Redraw the line's text. Interacts with the background and text
-// classes because the mode may output tokens that influence these
-// classes.
-function updateLineText(cm, lineView) {
-  var cls = lineView.text.className;
-  var built = getLineContent(cm, lineView);
-  if (lineView.text == lineView.node) { lineView.node = built.pre; }
-  lineView.text.parentNode.replaceChild(built.pre, lineView.text);
-  lineView.text = built.pre;
-  if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
-    lineView.bgClass = built.bgClass;
-    lineView.textClass = built.textClass;
-    updateLineClasses(cm, lineView);
-  } else if (cls) {
-    lineView.text.className = cls;
-  }
-}
-
-function updateLineClasses(cm, lineView) {
-  updateLineBackground(cm, lineView);
-  if (lineView.line.wrapClass)
-    { ensureLineWrapped(lineView).className = lineView.line.wrapClass; }
-  else if (lineView.node != lineView.text)
-    { lineView.node.className = ""; }
-  var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
-  lineView.text.className = textClass || "";
-}
-
-function updateLineGutter(cm, lineView, lineN, dims) {
-  if (lineView.gutter) {
-    lineView.node.removeChild(lineView.gutter);
-    lineView.gutter = null;
-  }
-  if (lineView.gutterBackground) {
-    lineView.node.removeChild(lineView.gutterBackground);
-    lineView.gutterBackground = null;
-  }
-  if (lineView.line.gutterClass) {
-    var wrap = ensureLineWrapped(lineView);
-    lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
-                                    ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px"));
-    cm.display.input.setUneditable(lineView.gutterBackground);
-    wrap.insertBefore(lineView.gutterBackground, lineView.text);
-  }
-  var markers = lineView.line.gutterMarkers;
-  if (cm.options.lineNumbers || markers) {
-    var wrap$1 = ensureLineWrapped(lineView);
-    var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
-    cm.display.input.setUneditable(gutterWrap);
-    wrap$1.insertBefore(gutterWrap, lineView.text);
-    if (lineView.line.gutterClass)
-      { gutterWrap.className += " " + lineView.line.gutterClass; }
-    if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
-      { lineView.lineNumber = gutterWrap.appendChild(
-        elt("div", lineNumberFor(cm.options, lineN),
-            "CodeMirror-linenumber CodeMirror-gutter-elt",
-            ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); }
-    if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) {
-      var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
-      if (found)
-        { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt",
-                                   ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); }
-    } }
-  }
-}
-
-function updateLineWidgets(cm, lineView, dims) {
-  if (lineView.alignable) { lineView.alignable = null; }
-  for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
-    next = node.nextSibling;
-    if (node.className == "CodeMirror-linewidget")
-      { lineView.node.removeChild(node); }
-  }
-  insertLineWidgets(cm, lineView, dims);
-}
-
-// Build a line's DOM representation from scratch
-function buildLineElement(cm, lineView, lineN, dims) {
-  var built = getLineContent(cm, lineView);
-  lineView.text = lineView.node = built.pre;
-  if (built.bgClass) { lineView.bgClass = built.bgClass; }
-  if (built.textClass) { lineView.textClass = built.textClass; }
-
-  updateLineClasses(cm, lineView);
-  updateLineGutter(cm, lineView, lineN, dims);
-  insertLineWidgets(cm, lineView, dims);
-  return lineView.node
-}
-
-// A lineView may contain multiple logical lines (when merged by
-// collapsed spans). The widgets for all of them need to be drawn.
-function insertLineWidgets(cm, lineView, dims) {
-  insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
-  if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
-    { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } }
-}
-
-function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
-  if (!line.widgets) { return }
-  var wrap = ensureLineWrapped(lineView);
-  for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
-    var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
-    if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
-    positionLineWidget(widget, node, lineView, dims);
-    cm.display.input.setUneditable(node);
-    if (allowAbove && widget.above)
-      { wrap.insertBefore(node, lineView.gutter || lineView.text); }
-    else
-      { wrap.appendChild(node); }
-    signalLater(widget, "redraw");
-  }
-}
-
-function positionLineWidget(widget, node, lineView, dims) {
-  if (widget.noHScroll) {
-    (lineView.alignable || (lineView.alignable = [])).push(node);
-    var width = dims.wrapperWidth;
-    node.style.left = dims.fixedPos + "px";
-    if (!widget.coverGutter) {
-      width -= dims.gutterTotalWidth;
-      node.style.paddingLeft = dims.gutterTotalWidth + "px";
-    }
-    node.style.width = width + "px";
-  }
-  if (widget.coverGutter) {
-    node.style.zIndex = 5;
-    node.style.position = "relative";
-    if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; }
-  }
-}
-
-function widgetHeight(widget) {
-  if (widget.height != null) { return widget.height }
-  var cm = widget.doc.cm;
-  if (!cm) { return 0 }
-  if (!contains(document.body, widget.node)) {
-    var parentStyle = "position: relative;";
-    if (widget.coverGutter)
-      { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; }
-    if (widget.noHScroll)
-      { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; }
-    removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
-  }
-  return widget.height = widget.node.parentNode.offsetHeight
-}
-
-// Return true when the given mouse event happened in a widget
-function eventInWidget(display, e) {
-  for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
-    if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
-        (n.parentNode == display.sizer && n != display.mover))
-      { return true }
-  }
-}
-
-// POSITION MEASUREMENT
-
-function paddingTop(display) {return display.lineSpace.offsetTop}
-function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
-function paddingH(display) {
-  if (display.cachedPaddingH) { return display.cachedPaddingH }
-  var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
-  var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
-  var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
-  if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; }
-  return data
-}
-
-function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
-function displayWidth(cm) {
-  return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
-}
-function displayHeight(cm) {
-  return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
-}
-
-// Ensure the lineView.wrapping.heights array is populated. This is
-// an array of bottom offsets for the lines that make up a drawn
-// line. When lineWrapping is on, there might be more than one
-// height.
-function ensureLineHeights(cm, lineView, rect) {
-  var wrapping = cm.options.lineWrapping;
-  var curWidth = wrapping && displayWidth(cm);
-  if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
-    var heights = lineView.measure.heights = [];
-    if (wrapping) {
-      lineView.measure.width = curWidth;
-      var rects = lineView.text.firstChild.getClientRects();
-      for (var i = 0; i < rects.length - 1; i++) {
-        var cur = rects[i], next = rects[i + 1];
-        if (Math.abs(cur.bottom - next.bottom) > 2)
-          { heights.push((cur.bottom + next.top) / 2 - rect.top); }
-      }
-    }
-    heights.push(rect.bottom - rect.top);
-  }
-}
-
-// Find a line map (mapping character offsets to text nodes) and a
-// measurement cache for the given line number. (A line view might
-// contain multiple lines when collapsed ranges are present.)
-function mapFromLineView(lineView, line, lineN) {
-  if (lineView.line == line)
-    { return {map: lineView.measure.map, cache: lineView.measure.cache} }
-  for (var i = 0; i < lineView.rest.length; i++)
-    { if (lineView.rest[i] == line)
-      { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
-  for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
-    { if (lineNo(lineView.rest[i$1]) > lineN)
-      { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
-}
-
-// Render a line into the hidden node display.externalMeasured. Used
-// when measurement is needed for a line that's not in the viewport.
-function updateExternalMeasurement(cm, line) {
-  line = visualLine(line);
-  var lineN = lineNo(line);
-  var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
-  view.lineN = lineN;
-  var built = view.built = buildLineContent(cm, view);
-  view.text = built.pre;
-  removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
-  return view
-}
-
-// Get a {top, bottom, left, right} box (in line-local coordinates)
-// for a given character.
-function measureChar(cm, line, ch, bias) {
-  return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
-}
-
-// Find a line view that corresponds to the given line number.
-function findViewForLine(cm, lineN) {
-  if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
-    { return cm.display.view[findViewIndex(cm, lineN)] }
-  var ext = cm.display.externalMeasured;
-  if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
-    { return ext }
-}
-
-// Measurement can be split in two steps, the set-up work that
-// applies to the whole line, and the measurement of the actual
-// character. Functions like coordsChar, that need to do a lot of
-// measurements in a row, can thus ensure that the set-up work is
-// only done once.
-function prepareMeasureForLine(cm, line) {
-  var lineN = lineNo(line);
-  var view = findViewForLine(cm, lineN);
-  if (view && !view.text) {
-    view = null;
-  } else if (view && view.changes) {
-    updateLineForChanges(cm, view, lineN, getDimensions(cm));
-    cm.curOp.forceUpdate = true;
-  }
-  if (!view)
-    { view = updateExternalMeasurement(cm, line); }
-
-  var info = mapFromLineView(view, line, lineN);
-  return {
-    line: line, view: view, rect: null,
-    map: info.map, cache: info.cache, before: info.before,
-    hasHeights: false
-  }
-}
-
-// Given a prepared measurement object, measures the position of an
-// actual character (or fetches it from the cache).
-function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
-  if (prepared.before) { ch = -1; }
-  var key = ch + (bias || ""), found;
-  if (prepared.cache.hasOwnProperty(key)) {
-    found = prepared.cache[key];
-  } else {
-    if (!prepared.rect)
-      { prepared.rect = prepared.view.text.getBoundingClientRect(); }
-    if (!prepared.hasHeights) {
-      ensureLineHeights(cm, prepared.view, prepared.rect);
-      prepared.hasHeights = true;
-    }
-    found = measureCharInner(cm, prepared, ch, bias);
-    if (!found.bogus) { prepared.cache[key] = found; }
-  }
-  return {left: found.left, right: found.right,
-          top: varHeight ? found.rtop : found.top,
-          bottom: varHeight ? found.rbottom : found.bottom}
-}
-
-var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
-
-function nodeAndOffsetInLineMap(map$$1, ch, bias) {
-  var node, start, end, collapse, mStart, mEnd;
-  // First, search the line map for the text node corresponding to,
-  // or closest to, the target character.
-  for (var i = 0; i < map$$1.length; i += 3) {
-    mStart = map$$1[i];
-    mEnd = map$$1[i + 1];
-    if (ch < mStart) {
-      start = 0; end = 1;
-      collapse = "left";
-    } else if (ch < mEnd) {
-      start = ch - mStart;
-      end = start + 1;
-    } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) {
-      end = mEnd - mStart;
-      start = end - 1;
-      if (ch >= mEnd) { collapse = "right"; }
-    }
-    if (start != null) {
-      node = map$$1[i + 2];
-      if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
-        { collapse = bias; }
-      if (bias == "left" && start == 0)
-        { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) {
-          node = map$$1[(i -= 3) + 2];
-          collapse = "left";
-        } }
-      if (bias == "right" && start == mEnd - mStart)
-        { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) {
-          node = map$$1[(i += 3) + 2];
-          collapse = "right";
-        } }
-      break
-    }
-  }
-  return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
-}
-
-function getUsefulRect(rects, bias) {
-  var rect = nullRect;
-  if (bias == "left") { for (var i = 0; i < rects.length; i++) {
-    if ((rect = rects[i]).left != rect.right) { break }
-  } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {
-    if ((rect = rects[i$1]).left != rect.right) { break }
-  } }
-  return rect
-}
-
-function measureCharInner(cm, prepared, ch, bias) {
-  var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
-  var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
-
-  var rect;
-  if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
-    for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned
-      while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; }
-      while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; }
-      if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
-        { rect = node.parentNode.getBoundingClientRect(); }
-      else
-        { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); }
-      if (rect.left || rect.right || start == 0) { break }
-      end = start;
-      start = start - 1;
-      collapse = "right";
-    }
-    if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); }
-  } else { // If it is a widget, simply get the box for the whole widget.
-    if (start > 0) { collapse = bias = "right"; }
-    var rects;
-    if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
-      { rect = rects[bias == "right" ? rects.length - 1 : 0]; }
-    else
-      { rect = node.getBoundingClientRect(); }
-  }
-  if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
-    var rSpan = node.parentNode.getClientRects()[0];
-    if (rSpan)
-      { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; }
-    else
-      { rect = nullRect; }
-  }
-
-  var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
-  var mid = (rtop + rbot) / 2;
-  var heights = prepared.view.measure.heights;
-  var i = 0;
-  for (; i < heights.length - 1; i++)
-    { if (mid < heights[i]) { break } }
-  var top = i ? heights[i - 1] : 0, bot = heights[i];
-  var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
-                right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
-                top: top, bottom: bot};
-  if (!rect.left && !rect.right) { result.bogus = true; }
-  if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
-
-  return result
-}
-
-// Work around problem with bounding client rects on ranges being
-// returned incorrectly when zoomed on IE10 and below.
-function maybeUpdateRectForZooming(measure, rect) {
-  if (!window.screen || screen.logicalXDPI == null ||
-      screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
-    { return rect }
-  var scaleX = screen.logicalXDPI / screen.deviceXDPI;
-  var scaleY = screen.logicalYDPI / screen.deviceYDPI;
-  return {left: rect.left * scaleX, right: rect.right * scaleX,
-          top: rect.top * scaleY, bottom: rect.bottom * scaleY}
-}
-
-function clearLineMeasurementCacheFor(lineView) {
-  if (lineView.measure) {
-    lineView.measure.cache = {};
-    lineView.measure.heights = null;
-    if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
-      { lineView.measure.caches[i] = {}; } }
-  }
-}
-
-function clearLineMeasurementCache(cm) {
-  cm.display.externalMeasure = null;
-  removeChildren(cm.display.lineMeasure);
-  for (var i = 0; i < cm.display.view.length; i++)
-    { clearLineMeasurementCacheFor(cm.display.view[i]); }
-}
-
-function clearCaches(cm) {
-  clearLineMeasurementCache(cm);
-  cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
-  if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; }
-  cm.display.lineNumChars = null;
-}
-
-function pageScrollX() {
-  // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
-  // which causes page_Offset and bounding client rects to use
-  // different reference viewports and invalidate our calculations.
-  if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
-  return window.pageXOffset || (document.documentElement || document.body).scrollLeft
-}
-function pageScrollY() {
-  if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
-  return window.pageYOffset || (document.documentElement || document.body).scrollTop
-}
-
-function widgetTopHeight(lineObj) {
-  var height = 0;
-  if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above)
-    { height += widgetHeight(lineObj.widgets[i]); } } }
-  return height
-}
-
-// Converts a {top, bottom, left, right} box from line-local
-// coordinates into another coordinate system. Context may be one of
-// "line", "div" (display.lineDiv), "local"./null (editor), "window",
-// or "page".
-function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
-  if (!includeWidgets) {
-    var height = widgetTopHeight(lineObj);
-    rect.top += height; rect.bottom += height;
-  }
-  if (context == "line") { return rect }
-  if (!context) { context = "local"; }
-  var yOff = heightAtLine(lineObj);
-  if (context == "local") { yOff += paddingTop(cm.display); }
-  else { yOff -= cm.display.viewOffset; }
-  if (context == "page" || context == "window") {
-    var lOff = cm.display.lineSpace.getBoundingClientRect();
-    yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
-    var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
-    rect.left += xOff; rect.right += xOff;
-  }
-  rect.top += yOff; rect.bottom += yOff;
-  return rect
-}
-
-// Coverts a box from "div" coords to another coordinate system.
-// Context may be "window", "page", "div", or "local"./null.
-function fromCoordSystem(cm, coords, context) {
-  if (context == "div") { return coords }
-  var left = coords.left, top = coords.top;
-  // First move into "page" coordinate system
-  if (context == "page") {
-    left -= pageScrollX();
-    top -= pageScrollY();
-  } else if (context == "local" || !context) {
-    var localBox = cm.display.sizer.getBoundingClientRect();
-    left += localBox.left;
-    top += localBox.top;
-  }
-
-  var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
-  return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
-}
-
-function charCoords(cm, pos, context, lineObj, bias) {
-  if (!lineObj) { lineObj = getLine(cm.doc, pos.line); }
-  return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
-}
-
-// Returns a box for a given cursor position, which may have an
-// 'other' property containing the position of the secondary cursor
-// on a bidi boundary.
-// A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
-// and after `char - 1` in writing order of `char - 1`
-// A cursor Pos(line, char, "after") is on the same visual line as `char`
-// and before `char` in writing order of `char`
-// Examples (upper-case letters are RTL, lower-case are LTR):
-//     Pos(0, 1, ...)
-//     before   after
-// ab     a|b     a|b
-// aB     a|B     aB|
-// Ab     |Ab     A|b
-// AB     B|A     B|A
-// Every position after the last character on a line is considered to stick
-// to the last character on the line.
-function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
-  lineObj = lineObj || getLine(cm.doc, pos.line);
-  if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
-  function get(ch, right) {
-    var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
-    if (right) { m.left = m.right; } else { m.right = m.left; }
-    return intoCoordSystem(cm, lineObj, m, context)
-  }
-  var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky;
-  if (ch >= lineObj.text.length) {
-    ch = lineObj.text.length;
-    sticky = "before";
-  } else if (ch <= 0) {
-    ch = 0;
-    sticky = "after";
-  }
-  if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
-
-  function getBidi(ch, partPos, invert) {
-    var part = order[partPos], right = part.level == 1;
-    return get(invert ? ch - 1 : ch, right != invert)
-  }
-  var partPos = getBidiPartAt(order, ch, sticky);
-  var other = bidiOther;
-  var val = getBidi(ch, partPos, sticky == "before");
-  if (other != null) { val.other = getBidi(ch, other, sticky != "before"); }
-  return val
-}
-
-// Used to cheaply estimate the coordinates for a position. Used for
-// intermediate scroll updates.
-function estimateCoords(cm, pos) {
-  var left = 0;
-  pos = clipPos(cm.doc, pos);
-  if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; }
-  var lineObj = getLine(cm.doc, pos.line);
-  var top = heightAtLine(lineObj) + paddingTop(cm.display);
-  return {left: left, right: left, top: top, bottom: top + lineObj.height}
-}
-
-// Positions returned by coordsChar contain some extra information.
-// xRel is the relative x position of the input coordinates compared
-// to the found position (so xRel > 0 means the coordinates are to
-// the right of the character position, for example). When outside
-// is true, that means the coordinates lie outside the line's
-// vertical range.
-function PosWithInfo(line, ch, sticky, outside, xRel) {
-  var pos = Pos(line, ch, sticky);
-  pos.xRel = xRel;
-  if (outside) { pos.outside = true; }
-  return pos
-}
-
-// Compute the character position closest to the given coordinates.
-// Input must be lineSpace-local ("div" coordinate system).
-function coordsChar(cm, x, y) {
-  var doc = cm.doc;
-  y += cm.display.viewOffset;
-  if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
-  var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
-  if (lineN > last)
-    { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
-  if (x < 0) { x = 0; }
-
-  var lineObj = getLine(doc, lineN);
-  for (;;) {
-    var found = coordsCharInner(cm, lineObj, lineN, x, y);
-    var merged = collapsedSpanAtEnd(lineObj);
-    var mergedPos = merged && merged.find(0, true);
-    if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
-      { lineN = lineNo(lineObj = mergedPos.to.line); }
-    else
-      { return found }
-  }
-}
-
-function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
-  y -= widgetTopHeight(lineObj);
-  var end = lineObj.text.length;
-  var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0);
-  end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end);
-  return {begin: begin, end: end}
-}
-
-function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
-  if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
-  var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top;
-  return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
-}
-
-// Returns true if the given side of a box is after the given
-// coordinates, in top-to-bottom, left-to-right order.
-function boxIsAfter(box, x, y, left) {
-  return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
-}
-
-function coordsCharInner(cm, lineObj, lineNo$$1, x, y) {
-  // Move y into line-local coordinate space
-  y -= heightAtLine(lineObj);
-  var preparedMeasure = prepareMeasureForLine(cm, lineObj);
-  // When directly calling `measureCharPrepared`, we have to adjust
-  // for the widgets at this line.
-  var widgetHeight$$1 = widgetTopHeight(lineObj);
-  var begin = 0, end = lineObj.text.length, ltr = true;
-
-  var order = getOrder(lineObj, cm.doc.direction);
-  // If the line isn't plain left-to-right text, first figure out
-  // which bidi section the coordinates fall into.
-  if (order) {
-    var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
-                 (cm, lineObj, lineNo$$1, preparedMeasure, order, x, y);
-    ltr = part.level != 1;
-    // The awkward -1 offsets are needed because findFirst (called
-    // on these below) will treat its first bound as inclusive,
-    // second as exclusive, but we want to actually address the
-    // characters in the part's range
-    begin = ltr ? part.from : part.to - 1;
-    end = ltr ? part.to : part.from - 1;
-  }
-
-  // A binary search to find the first character whose bounding box
-  // starts after the coordinates. If we run across any whose box wrap
-  // the coordinates, store that.
-  var chAround = null, boxAround = null;
-  var ch = findFirst(function (ch) {
-    var box = measureCharPrepared(cm, preparedMeasure, ch);
-    box.top += widgetHeight$$1; box.bottom += widgetHeight$$1;
-    if (!boxIsAfter(box, x, y, false)) { return false }
-    if (box.top <= y && box.left <= x) {
-      chAround = ch;
-      boxAround = box;
-    }
-    return true
-  }, begin, end);
-
-  var baseX, sticky, outside = false;
-  // If a box around the coordinates was found, use that
-  if (boxAround) {
-    // Distinguish coordinates nearer to the left or right side of the box
-    var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr;
-    ch = chAround + (atStart ? 0 : 1);
-    sticky = atStart ? "after" : "before";
-    baseX = atLeft ? boxAround.left : boxAround.right;
-  } else {
-    // (Adjust for extended bound, if necessary.)
-    if (!ltr && (ch == end || ch == begin)) { ch++; }
-    // To determine which side to associate with, get the box to the
-    // left of the character and compare it's vertical position to the
-    // coordinates
-    sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" :
-      (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight$$1 <= y) == ltr ?
-      "after" : "before";
-    // Now get accurate coordinates for this place, in order to get a
-    // base X position
-    var coords = cursorCoords(cm, Pos(lineNo$$1, ch, sticky), "line", lineObj, preparedMeasure);
-    baseX = coords.left;
-    outside = y < coords.top || y >= coords.bottom;
-  }
-
-  ch = skipExtendingChars(lineObj.text, ch, 1);
-  return PosWithInfo(lineNo$$1, ch, sticky, outside, x - baseX)
-}
-
-function coordsBidiPart(cm, lineObj, lineNo$$1, preparedMeasure, order, x, y) {
-  // Bidi parts are sorted left-to-right, and in a non-line-wrapping
-  // situation, we can take this ordering to correspond to the visual
-  // ordering. This finds the first part whose end is after the given
-  // coordinates.
-  var index = findFirst(function (i) {
-    var part = order[i], ltr = part.level != 1;
-    return boxIsAfter(cursorCoords(cm, Pos(lineNo$$1, ltr ? part.to : part.from, ltr ? "before" : "after"),
-                                   "line", lineObj, preparedMeasure), x, y, true)
-  }, 0, order.length - 1);
-  var part = order[index];
-  // If this isn't the first part, the part's start is also after
-  // the coordinates, and the coordinates aren't on the same line as
-  // that start, move one part back.
-  if (index > 0) {
-    var ltr = part.level != 1;
-    var start = cursorCoords(cm, Pos(lineNo$$1, ltr ? part.from : part.to, ltr ? "after" : "before"),
-                             "line", lineObj, preparedMeasure);
-    if (boxIsAfter(start, x, y, true) && start.top > y)
-      { part = order[index - 1]; }
-  }
-  return part
-}
-
-function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) {
-  // In a wrapped line, rtl text on wrapping boundaries can do things
-  // that don't correspond to the ordering in our `order` array at
-  // all, so a binary search doesn't work, and we want to return a
-  // part that only spans one line so that the binary search in
-  // coordsCharInner is safe. As such, we first find the extent of the
-  // wrapped line, and then do a flat search in which we discard any
-  // spans that aren't on the line.
-  var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
-  var begin = ref.begin;
-  var end = ref.end;
-  if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; }
-  var part = null, closestDist = null;
-  for (var i = 0; i < order.length; i++) {
-    var p = order[i];
-    if (p.from >= end || p.to <= begin) { continue }
-    var ltr = p.level != 1;
-    var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right;
-    // Weigh against spans ending before this, so that they are only
-    // picked if nothing ends after
-    var dist = endX < x ? x - endX + 1e9 : endX - x;
-    if (!part || closestDist > dist) {
-      part = p;
-      closestDist = dist;
-    }
-  }
-  if (!part) { part = order[order.length - 1]; }
-  // Clip the part to the wrapped line.
-  if (part.from < begin) { part = {from: begin, to: part.to, level: part.level}; }
-  if (part.to > end) { part = {from: part.from, to: end, level: part.level}; }
-  return part
-}
-
-var measureText;
-// Compute the default text height.
-function textHeight(display) {
-  if (display.cachedTextHeight != null) { return display.cachedTextHeight }
-  if (measureText == null) {
-    measureText = elt("pre");
-    // Measure a bunch of lines, for browsers that compute
-    // fractional heights.
-    for (var i = 0; i < 49; ++i) {
-      measureText.appendChild(document.createTextNode("x"));
-      measureText.appendChild(elt("br"));
-    }
-    measureText.appendChild(document.createTextNode("x"));
-  }
-  removeChildrenAndAdd(display.measure, measureText);
-  var height = measureText.offsetHeight / 50;
-  if (height > 3) { display.cachedTextHeight = height; }
-  removeChildren(display.measure);
-  return height || 1
-}
-
-// Compute the default character width.
-function charWidth(display) {
-  if (display.cachedCharWidth != null) { return display.cachedCharWidth }
-  var anchor = elt("span", "xxxxxxxxxx");
-  var pre = elt("pre", [anchor]);
-  removeChildrenAndAdd(display.measure, pre);
-  var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
-  if (width > 2) { display.cachedCharWidth = width; }
-  return width || 10
-}
-
-// Do a bulk-read of the DOM positions and sizes needed to draw the
-// view, so that we don't interleave reading and writing to the DOM.
-function getDimensions(cm) {
-  var d = cm.display, left = {}, width = {};
-  var gutterLeft = d.gutters.clientLeft;
-  for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
-    left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
-    width[cm.options.gutters[i]] = n.clientWidth;
-  }
-  return {fixedPos: compensateForHScroll(d),
-          gutterTotalWidth: d.gutters.offsetWidth,
-          gutterLeft: left,
-          gutterWidth: width,
-          wrapperWidth: d.wrapper.clientWidth}
-}
-
-// Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
-// but using getBoundingClientRect to get a sub-pixel-accurate
-// result.
-function compensateForHScroll(display) {
-  return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
-}
-
-// Returns a function that estimates the height of a line, to use as
-// first approximation until the line becomes visible (and is thus
-// properly measurable).
-function estimateHeight(cm) {
-  var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
-  var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
-  return function (line) {
-    if (lineIsHidden(cm.doc, line)) { return 0 }
-
-    var widgetsHeight = 0;
-    if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {
-      if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; }
-    } }
-
-    if (wrapping)
-      { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }
-    else
-      { return widgetsHeight + th }
-  }
-}
-
-function estimateLineHeights(cm) {
-  var doc = cm.doc, est = estimateHeight(cm);
-  doc.iter(function (line) {
-    var estHeight = est(line);
-    if (estHeight != line.height) { updateLineHeight(line, estHeight); }
-  });
-}
-
-// Given a mouse event, find the corresponding position. If liberal
-// is false, it checks whether a gutter or scrollbar was clicked,
-// and returns null if it was. forRect is used by rectangular
-// selections, and tries to estimate a character position even for
-// coordinates beyond the right of the text.
-function posFromMouse(cm, e, liberal, forRect) {
-  var display = cm.display;
-  if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null }
-
-  var x, y, space = display.lineSpace.getBoundingClientRect();
-  // Fails unpredictably on IE[67] when mouse is dragged around quickly.
-  try { x = e.clientX - space.left; y = e.clientY - space.top; }
-  catch (e) { return null }
-  var coords = coordsChar(cm, x, y), line;
-  if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
-    var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
-    coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
-  }
-  return coords
-}
-
-// Find the view element corresponding to a given line. Return null
-// when the line isn't visible.
-function findViewIndex(cm, n) {
-  if (n >= cm.display.viewTo) { return null }
-  n -= cm.display.viewFrom;
-  if (n < 0) { return null }
-  var view = cm.display.view;
-  for (var i = 0; i < view.length; i++) {
-    n -= view[i].size;
-    if (n < 0) { return i }
-  }
-}
-
-function updateSelection(cm) {
-  cm.display.input.showSelection(cm.display.input.prepareSelection());
-}
-
-function prepareSelection(cm, primary) {
-  if ( primary === void 0 ) primary = true;
-
-  var doc = cm.doc, result = {};
-  var curFragment = result.cursors = document.createDocumentFragment();
-  var selFragment = result.selection = document.createDocumentFragment();
-
-  for (var i = 0; i < doc.sel.ranges.length; i++) {
-    if (!primary && i == doc.sel.primIndex) { continue }
-    var range$$1 = doc.sel.ranges[i];
-    if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue }
-    var collapsed = range$$1.empty();
-    if (collapsed || cm.options.showCursorWhenSelecting)
-      { drawSelectionCursor(cm, range$$1.head, curFragment); }
-    if (!collapsed)
-      { drawSelectionRange(cm, range$$1, selFragment); }
-  }
-  return result
-}
-
-// Draws a cursor for the given range
-function drawSelectionCursor(cm, head, output) {
-  var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
-
-  var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
-  cursor.style.left = pos.left + "px";
-  cursor.style.top = pos.top + "px";
-  cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
-
-  if (pos.other) {
-    // Secondary cursor, shown when on a 'jump' in bi-directional text
-    var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
-    otherCursor.style.display = "";
-    otherCursor.style.left = pos.other.left + "px";
-    otherCursor.style.top = pos.other.top + "px";
-    otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
-  }
-}
-
-function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
-
-// Draws the given range as a highlighted selection
-function drawSelectionRange(cm, range$$1, output) {
-  var display = cm.display, doc = cm.doc;
-  var fragment = document.createDocumentFragment();
-  var padding = paddingH(cm.display), leftSide = padding.left;
-  var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
-  var docLTR = doc.direction == "ltr";
-
-  function add(left, top, width, bottom) {
-    if (top < 0) { top = 0; }
-    top = Math.round(top);
-    bottom = Math.round(bottom);
-    fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n                             top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n                             height: " + (bottom - top) + "px")));
-  }
-
-  function drawForLine(line, fromArg, toArg) {
-    var lineObj = getLine(doc, line);
-    var lineLen = lineObj.text.length;
-    var start, end;
-    function coords(ch, bias) {
-      return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
-    }
-
-    function wrapX(pos, dir, side) {
-      var extent = wrappedLineExtentChar(cm, lineObj, null, pos);
-      var prop = (dir == "ltr") == (side == "after") ? "left" : "right";
-      var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1);
-      return coords(ch, prop)[prop]
-    }
-
-    var order = getOrder(lineObj, doc.direction);
-    iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
-      var ltr = dir == "ltr";
-      var fromPos = coords(from, ltr ? "left" : "right");
-      var toPos = coords(to - 1, ltr ? "right" : "left");
-
-      var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen;
-      var first = i == 0, last = !order || i == order.length - 1;
-      if (toPos.top - fromPos.top <= 3) { // Single line
-        var openLeft = (docLTR ? openStart : openEnd) && first;
-        var openRight = (docLTR ? openEnd : openStart) && last;
-        var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left;
-        var right = openRight ? rightSide : (ltr ? toPos : fromPos).right;
-        add(left, fromPos.top, right - left, fromPos.bottom);
-      } else { // Multiple lines
-        var topLeft, topRight, botLeft, botRight;
-        if (ltr) {
-          topLeft = docLTR && openStart && first ? leftSide : fromPos.left;
-          topRight = docLTR ? rightSide : wrapX(from, dir, "before");
-          botLeft = docLTR ? leftSide : wrapX(to, dir, "after");
-          botRight = docLTR && openEnd && last ? rightSide : toPos.right;
-        } else {
-          topLeft = !docLTR ? leftSide : wrapX(from, dir, "before");
-          topRight = !docLTR && openStart && first ? rightSide : fromPos.right;
-          botLeft = !docLTR && openEnd && last ? leftSide : toPos.left;
-          botRight = !docLTR ? rightSide : wrapX(to, dir, "after");
-        }
-        add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom);
-        if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); }
-        add(botLeft, toPos.top, botRight - botLeft, toPos.bottom);
-      }
-
-      if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; }
-      if (cmpCoords(toPos, start) < 0) { start = toPos; }
-      if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; }
-      if (cmpCoords(toPos, end) < 0) { end = toPos; }
-    });
-    return {start: start, end: end}
-  }
-
-  var sFrom = range$$1.from(), sTo = range$$1.to();
-  if (sFrom.line == sTo.line) {
-    drawForLine(sFrom.line, sFrom.ch, sTo.ch);
-  } else {
-    var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
-    var singleVLine = visualLine(fromLine) == visualLine(toLine);
-    var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
-    var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
-    if (singleVLine) {
-      if (leftEnd.top < rightStart.top - 2) {
-        add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
-        add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
-      } else {
-        add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
-      }
-    }
-    if (leftEnd.bottom < rightStart.top)
-      { add(leftSide, leftEnd.bottom, null, rightStart.top); }
-  }
-
-  output.appendChild(fragment);
-}
-
-// Cursor-blinking
-function restartBlink(cm) {
-  if (!cm.state.focused) { return }
-  var display = cm.display;
-  clearInterval(display.blinker);
-  var on = true;
-  display.cursorDiv.style.visibility = "";
-  if (cm.options.cursorBlinkRate > 0)
-    { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
-      cm.options.cursorBlinkRate); }
-  else if (cm.options.cursorBlinkRate < 0)
-    { display.cursorDiv.style.visibility = "hidden"; }
-}
-
-function ensureFocus(cm) {
-  if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
-}
-
-function delayBlurEvent(cm) {
-  cm.state.delayingBlurEvent = true;
-  setTimeout(function () { if (cm.state.delayingBlurEvent) {
-    cm.state.delayingBlurEvent = false;
-    onBlur(cm);
-  } }, 100);
-}
-
-function onFocus(cm, e) {
-  if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; }
-
-  if (cm.options.readOnly == "nocursor") { return }
-  if (!cm.state.focused) {
-    signal(cm, "focus", cm, e);
-    cm.state.focused = true;
-    addClass(cm.display.wrapper, "CodeMirror-focused");
-    // This test prevents this from firing when a context
-    // menu is closed (since the input reset would kill the
-    // select-all detection hack)
-    if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
-      cm.display.input.reset();
-      if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730
-    }
-    cm.display.input.receivedFocus();
-  }
-  restartBlink(cm);
-}
-function onBlur(cm, e) {
-  if (cm.state.delayingBlurEvent) { return }
-
-  if (cm.state.focused) {
-    signal(cm, "blur", cm, e);
-    cm.state.focused = false;
-    rmClass(cm.display.wrapper, "CodeMirror-focused");
-  }
-  clearInterval(cm.display.blinker);
-  setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150);
-}
-
-// Read the actual heights of the rendered lines, and update their
-// stored heights to match.
-function updateHeightsInViewport(cm) {
-  var display = cm.display;
-  var prevBottom = display.lineDiv.offsetTop;
-  for (var i = 0; i < display.view.length; i++) {
-    var cur = display.view[i], height = (void 0);
-    if (cur.hidden) { continue }
-    if (ie && ie_version < 8) {
-      var bot = cur.node.offsetTop + cur.node.offsetHeight;
-      height = bot - prevBottom;
-      prevBottom = bot;
-    } else {
-      var box = cur.node.getBoundingClientRect();
-      height = box.bottom - box.top;
-    }
-    var diff = cur.line.height - height;
-    if (height < 2) { height = textHeight(display); }
-    if (diff > .005 || diff < -.005) {
-      updateLineHeight(cur.line, height);
-      updateWidgetHeight(cur.line);
-      if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
-        { updateWidgetHeight(cur.rest[j]); } }
-    }
-  }
-}
-
-// Read and store the height of line widgets associated with the
-// given line.
-function updateWidgetHeight(line) {
-  if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) {
-    var w = line.widgets[i], parent = w.node.parentNode;
-    if (parent) { w.height = parent.offsetHeight; }
-  } }
-}
-
-// Compute the lines that are visible in a given viewport (defaults
-// the the current scroll position). viewport may contain top,
-// height, and ensure (see op.scrollToPos) properties.
-function visibleLines(display, doc, viewport) {
-  var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
-  top = Math.floor(top - paddingTop(display));
-  var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
-
-  var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
-  // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
-  // forces those lines into the viewport (if possible).
-  if (viewport && viewport.ensure) {
-    var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
-    if (ensureFrom < from) {
-      from = ensureFrom;
-      to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
-    } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
-      from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
-      to = ensureTo;
-    }
-  }
-  return {from: from, to: Math.max(to, from + 1)}
-}
-
-// Re-align line numbers and gutter marks to compensate for
-// horizontal scrolling.
-function alignHorizontally(cm) {
-  var display = cm.display, view = display.view;
-  if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }
-  var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
-  var gutterW = display.gutters.offsetWidth, left = comp + "px";
-  for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {
-    if (cm.options.fixedGutter) {
-      if (view[i].gutter)
-        { view[i].gutter.style.left = left; }
-      if (view[i].gutterBackground)
-        { view[i].gutterBackground.style.left = left; }
-    }
-    var align = view[i].alignable;
-    if (align) { for (var j = 0; j < align.length; j++)
-      { align[j].style.left = left; } }
-  } }
-  if (cm.options.fixedGutter)
-    { display.gutters.style.left = (comp + gutterW) + "px"; }
-}
-
-// Used to ensure that the line number gutter is still the right
-// size for the current document size. Returns true when an update
-// is needed.
-function maybeUpdateLineNumberWidth(cm) {
-  if (!cm.options.lineNumbers) { return false }
-  var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
-  if (last.length != display.lineNumChars) {
-    var test = display.measure.appendChild(elt("div", [elt("div", last)],
-                                               "CodeMirror-linenumber CodeMirror-gutter-elt"));
-    var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
-    display.lineGutter.style.width = "";
-    display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
-    display.lineNumWidth = display.lineNumInnerWidth + padding;
-    display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
-    display.lineGutter.style.width = display.lineNumWidth + "px";
-    updateGutterSpace(cm);
-    return true
-  }
-  return false
-}
-
-// SCROLLING THINGS INTO VIEW
-
-// If an editor sits on the top or bottom of the window, partially
-// scrolled out of view, this ensures that the cursor is visible.
-function maybeScrollWindow(cm, rect) {
-  if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
-
-  var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
-  if (rect.top + box.top < 0) { doScroll = true; }
-  else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; }
-  if (doScroll != null && !phantom) {
-    var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n                         top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n                         height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n                         left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"));
-    cm.display.lineSpace.appendChild(scrollNode);
-    scrollNode.scrollIntoView(doScroll);
-    cm.display.lineSpace.removeChild(scrollNode);
-  }
-}
-
-// Scroll a given position into view (immediately), verifying that
-// it actually became visible (as line heights are accurately
-// measured, the position of something may 'drift' during drawing).
-function scrollPosIntoView(cm, pos, end, margin) {
-  if (margin == null) { margin = 0; }
-  var rect;
-  if (!cm.options.lineWrapping && pos == end) {
-    // Set pos and end to the cursor positions around the character pos sticks to
-    // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch
-    // If pos == Pos(_, 0, "before"), pos and end are unchanged
-    pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos;
-    end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos;
-  }
-  for (var limit = 0; limit < 5; limit++) {
-    var changed = false;
-    var coords = cursorCoords(cm, pos);
-    var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
-    rect = {left: Math.min(coords.left, endCoords.left),
-            top: Math.min(coords.top, endCoords.top) - margin,
-            right: Math.max(coords.left, endCoords.left),
-            bottom: Math.max(coords.bottom, endCoords.bottom) + margin};
-    var scrollPos = calculateScrollPos(cm, rect);
-    var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
-    if (scrollPos.scrollTop != null) {
-      updateScrollTop(cm, scrollPos.scrollTop);
-      if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; }
-    }
-    if (scrollPos.scrollLeft != null) {
-      setScrollLeft(cm, scrollPos.scrollLeft);
-      if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; }
-    }
-    if (!changed) { break }
-  }
-  return rect
-}
-
-// Scroll a given set of coordinates into view (immediately).
-function scrollIntoView(cm, rect) {
-  var scrollPos = calculateScrollPos(cm, rect);
-  if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); }
-  if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); }
-}
-
-// Calculate a new scroll position needed to scroll the given
-// rectangle into view. Returns an object with scrollTop and
-// scrollLeft properties. When these are undefined, the
-// vertical/horizontal position does not need to be adjusted.
-function calculateScrollPos(cm, rect) {
-  var display = cm.display, snapMargin = textHeight(cm.display);
-  if (rect.top < 0) { rect.top = 0; }
-  var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
-  var screen = displayHeight(cm), result = {};
-  if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; }
-  var docBottom = cm.doc.height + paddingVert(display);
-  var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin;
-  if (rect.top < screentop) {
-    result.scrollTop = atTop ? 0 : rect.top;
-  } else if (rect.bottom > screentop + screen) {
-    var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen);
-    if (newTop != screentop) { result.scrollTop = newTop; }
-  }
-
-  var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
-  var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
-  var tooWide = rect.right - rect.left > screenw;
-  if (tooWide) { rect.right = rect.left + screenw; }
-  if (rect.left < 10)
-    { result.scrollLeft = 0; }
-  else if (rect.left < screenleft)
-    { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)); }
-  else if (rect.right > screenw + screenleft - 3)
-    { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; }
-  return result
-}
-
-// Store a relative adjustment to the scroll position in the current
-// operation (to be applied when the operation finishes).
-function addToScrollTop(cm, top) {
-  if (top == null) { return }
-  resolveScrollToPos(cm);
-  cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
-}
-
-// Make sure that at the end of the operation the current cursor is
-// shown.
-function ensureCursorVisible(cm) {
-  resolveScrollToPos(cm);
-  var cur = cm.getCursor();
-  cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin};
-}
-
-function scrollToCoords(cm, x, y) {
-  if (x != null || y != null) { resolveScrollToPos(cm); }
-  if (x != null) { cm.curOp.scrollLeft = x; }
-  if (y != null) { cm.curOp.scrollTop = y; }
-}
-
-function scrollToRange(cm, range$$1) {
-  resolveScrollToPos(cm);
-  cm.curOp.scrollToPos = range$$1;
-}
-
-// When an operation has its scrollToPos property set, and another
-// scroll action is applied before the end of the operation, this
-// 'simulates' scrolling that position into view in a cheap way, so
-// that the effect of intermediate scroll commands is not ignored.
-function resolveScrollToPos(cm) {
-  var range$$1 = cm.curOp.scrollToPos;
-  if (range$$1) {
-    cm.curOp.scrollToPos = null;
-    var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to);
-    scrollToCoordsRange(cm, from, to, range$$1.margin);
-  }
-}
-
-function scrollToCoordsRange(cm, from, to, margin) {
-  var sPos = calculateScrollPos(cm, {
-    left: Math.min(from.left, to.left),
-    top: Math.min(from.top, to.top) - margin,
-    right: Math.max(from.right, to.right),
-    bottom: Math.max(from.bottom, to.bottom) + margin
-  });
-  scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop);
-}
-
-// Sync the scrollable area and scrollbars, ensure the viewport
-// covers the visible area.
-function updateScrollTop(cm, val) {
-  if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
-  if (!gecko) { updateDisplaySimple(cm, {top: val}); }
-  setScrollTop(cm, val, true);
-  if (gecko) { updateDisplaySimple(cm); }
-  startWorker(cm, 100);
-}
-
-function setScrollTop(cm, val, forceScroll) {
-  val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
-  if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
-  cm.doc.scrollTop = val;
-  cm.display.scrollbars.setScrollTop(val);
-  if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; }
-}
-
-// Sync scroller and scrollbar, ensure the gutter elements are
-// aligned.
-function setScrollLeft(cm, val, isScroller, forceScroll) {
-  val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
-  if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
-  cm.doc.scrollLeft = val;
-  alignHorizontally(cm);
-  if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; }
-  cm.display.scrollbars.setScrollLeft(val);
-}
-
-// SCROLLBARS
-
-// Prepare DOM reads needed to update the scrollbars. Done in one
-// shot to minimize update/measure roundtrips.
-function measureForScrollbars(cm) {
-  var d = cm.display, gutterW = d.gutters.offsetWidth;
-  var docH = Math.round(cm.doc.height + paddingVert(cm.display));
-  return {
-    clientHeight: d.scroller.clientHeight,
-    viewHeight: d.wrapper.clientHeight,
-    scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
-    viewWidth: d.wrapper.clientWidth,
-    barLeft: cm.options.fixedGutter ? gutterW : 0,
-    docHeight: docH,
-    scrollHeight: docH + scrollGap(cm) + d.barHeight,
-    nativeBarWidth: d.nativeBarWidth,
-    gutterWidth: gutterW
-  }
-}
-
-var NativeScrollbars = function(place, scroll, cm) {
-  this.cm = cm;
-  var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
-  var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
-  place(vert); place(horiz);
-
-  on(vert, "scroll", function () {
-    if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); }
-  });
-  on(horiz, "scroll", function () {
-    if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); }
-  });
-
-  this.checkedZeroWidth = false;
-  // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
-  if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; }
-};
-
-NativeScrollbars.prototype.update = function (measure) {
-  var needsH = measure.scrollWidth > measure.clientWidth + 1;
-  var needsV = measure.scrollHeight > measure.clientHeight + 1;
-  var sWidth = measure.nativeBarWidth;
-
-  if (needsV) {
-    this.vert.style.display = "block";
-    this.vert.style.bottom = needsH ? sWidth + "px" : "0";
-    var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
-    // A bug in IE8 can cause this value to be negative, so guard it.
-    this.vert.firstChild.style.height =
-      Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
-  } else {
-    this.vert.style.display = "";
-    this.vert.firstChild.style.height = "0";
-  }
-
-  if (needsH) {
-    this.horiz.style.display = "block";
-    this.horiz.style.right = needsV ? sWidth + "px" : "0";
-    this.horiz.style.left = measure.barLeft + "px";
-    var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
-    this.horiz.firstChild.style.width =
-      Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
-  } else {
-    this.horiz.style.display = "";
-    this.horiz.firstChild.style.width = "0";
-  }
-
-  if (!this.checkedZeroWidth && measure.clientHeight > 0) {
-    if (sWidth == 0) { this.zeroWidthHack(); }
-    this.checkedZeroWidth = true;
-  }
-
-  return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}
-};
-
-NativeScrollbars.prototype.setScrollLeft = function (pos) {
-  if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; }
-  if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); }
-};
-
-NativeScrollbars.prototype.setScrollTop = function (pos) {
-  if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; }
-  if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); }
-};
-
-NativeScrollbars.prototype.zeroWidthHack = function () {
-  var w = mac && !mac_geMountainLion ? "12px" : "18px";
-  this.horiz.style.height = this.vert.style.width = w;
-  this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
-  this.disableHoriz = new Delayed;
-  this.disableVert = new Delayed;
-};
-
-NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
-  bar.style.pointerEvents = "auto";
-  function maybeDisable() {
-    // To find out whether the scrollbar is still visible, we
-    // check whether the element under the pixel in the bottom
-    // right corner of the scrollbar box is the scrollbar box
-    // itself (when the bar is still visible) or its filler child
-    // (when the bar is hidden). If it is still visible, we keep
-    // it enabled, if it's hidden, we disable pointer events.
-    var box = bar.getBoundingClientRect();
-    var elt$$1 = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
-        : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1);
-    if (elt$$1 != bar) { bar.style.pointerEvents = "none"; }
-    else { delay.set(1000, maybeDisable); }
-  }
-  delay.set(1000, maybeDisable);
-};
-
-NativeScrollbars.prototype.clear = function () {
-  var parent = this.horiz.parentNode;
-  parent.removeChild(this.horiz);
-  parent.removeChild(this.vert);
-};
-
-var NullScrollbars = function () {};
-
-NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };
-NullScrollbars.prototype.setScrollLeft = function () {};
-NullScrollbars.prototype.setScrollTop = function () {};
-NullScrollbars.prototype.clear = function () {};
-
-function updateScrollbars(cm, measure) {
-  if (!measure) { measure = measureForScrollbars(cm); }
-  var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
-  updateScrollbarsInner(cm, measure);
-  for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
-    if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
-      { updateHeightsInViewport(cm); }
-    updateScrollbarsInner(cm, measureForScrollbars(cm));
-    startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
-  }
-}
-
-// Re-synchronize the fake scrollbars with the actual size of the
-// content.
-function updateScrollbarsInner(cm, measure) {
-  var d = cm.display;
-  var sizes = d.scrollbars.update(measure);
-
-  d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
-  d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
-  d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent";
-
-  if (sizes.right && sizes.bottom) {
-    d.scrollbarFiller.style.display = "block";
-    d.scrollbarFiller.style.height = sizes.bottom + "px";
-    d.scrollbarFiller.style.width = sizes.right + "px";
-  } else { d.scrollbarFiller.style.display = ""; }
-  if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
-    d.gutterFiller.style.display = "block";
-    d.gutterFiller.style.height = sizes.bottom + "px";
-    d.gutterFiller.style.width = measure.gutterWidth + "px";
-  } else { d.gutterFiller.style.display = ""; }
-}
-
-var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
-
-function initScrollbars(cm) {
-  if (cm.display.scrollbars) {
-    cm.display.scrollbars.clear();
-    if (cm.display.scrollbars.addClass)
-      { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
-  }
-
-  cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {
-    cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
-    // Prevent clicks in the scrollbars from killing focus
-    on(node, "mousedown", function () {
-      if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); }
-    });
-    node.setAttribute("cm-not-content", "true");
-  }, function (pos, axis) {
-    if (axis == "horizontal") { setScrollLeft(cm, pos); }
-    else { updateScrollTop(cm, pos); }
-  }, cm);
-  if (cm.display.scrollbars.addClass)
-    { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
-}
-
-// Operations are used to wrap a series of changes to the editor
-// state in such a way that each change won't have to update the
-// cursor and display (which would be awkward, slow, and
-// error-prone). Instead, display updates are batched and then all
-// combined and executed at once.
-
-var nextOpId = 0;
-// Start a new operation.
-function startOperation(cm) {
-  cm.curOp = {
-    cm: cm,
-    viewChanged: false,      // Flag that indicates that lines might need to be redrawn
-    startHeight: cm.doc.height, // Used to detect need to update scrollbar
-    forceUpdate: false,      // Used to force a redraw
-    updateInput: null,       // Whether to reset the input textarea
-    typing: false,           // Whether this reset should be careful to leave existing text (for compositing)
-    changeObjs: null,        // Accumulated changes, for firing change events
-    cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
-    cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
-    selectionChanged: false, // Whether the selection needs to be redrawn
-    updateMaxLine: false,    // Set when the widest line needs to be determined anew
-    scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
-    scrollToPos: null,       // Used to scroll to a specific position
-    focus: false,
-    id: ++nextOpId           // Unique ID
-  };
-  pushOperation(cm.curOp);
-}
-
-// Finish an operation, updating the display and signalling delayed events
-function endOperation(cm) {
-  var op = cm.curOp;
-  finishOperation(op, function (group) {
-    for (var i = 0; i < group.ops.length; i++)
-      { group.ops[i].cm.curOp = null; }
-    endOperations(group);
-  });
-}
-
-// The DOM updates done when an operation finishes are batched so
-// that the minimum number of relayouts are required.
-function endOperations(group) {
-  var ops = group.ops;
-  for (var i = 0; i < ops.length; i++) // Read DOM
-    { endOperation_R1(ops[i]); }
-  for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)
-    { endOperation_W1(ops[i$1]); }
-  for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM
-    { endOperation_R2(ops[i$2]); }
-  for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)
-    { endOperation_W2(ops[i$3]); }
-  for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM
-    { endOperation_finish(ops[i$4]); }
-}
-
-function endOperation_R1(op) {
-  var cm = op.cm, display = cm.display;
-  maybeClipScrollbars(cm);
-  if (op.updateMaxLine) { findMaxLine(cm); }
-
-  op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
-    op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
-                       op.scrollToPos.to.line >= display.viewTo) ||
-    display.maxLineChanged && cm.options.lineWrapping;
-  op.update = op.mustUpdate &&
-    new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
-}
-
-function endOperation_W1(op) {
-  op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
-}
-
-function endOperation_R2(op) {
-  var cm = op.cm, display = cm.display;
-  if (op.updatedDisplay) { updateHeightsInViewport(cm); }
-
-  op.barMeasure = measureForScrollbars(cm);
-
-  // If the max line changed since it was last measured, measure it,
-  // and ensure the document's width matches it.
-  // updateDisplay_W2 will use these properties to do the actual resizing
-  if (display.maxLineChanged && !cm.options.lineWrapping) {
-    op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
-    cm.display.sizerWidth = op.adjustWidthTo;
-    op.barMeasure.scrollWidth =
-      Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
-    op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
-  }
-
-  if (op.updatedDisplay || op.selectionChanged)
-    { op.preparedSelection = display.input.prepareSelection(); }
-}
-
-function endOperation_W2(op) {
-  var cm = op.cm;
-
-  if (op.adjustWidthTo != null) {
-    cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
-    if (op.maxScrollLeft < cm.doc.scrollLeft)
-      { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); }
-    cm.display.maxLineChanged = false;
-  }
-
-  var takeFocus = op.focus && op.focus == activeElt();
-  if (op.preparedSelection)
-    { cm.display.input.showSelection(op.preparedSelection, takeFocus); }
-  if (op.updatedDisplay || op.startHeight != cm.doc.height)
-    { updateScrollbars(cm, op.barMeasure); }
-  if (op.updatedDisplay)
-    { setDocumentHeight(cm, op.barMeasure); }
-
-  if (op.selectionChanged) { restartBlink(cm); }
-
-  if (cm.state.focused && op.updateInput)
-    { cm.display.input.reset(op.typing); }
-  if (takeFocus) { ensureFocus(op.cm); }
-}
-
-function endOperation_finish(op) {
-  var cm = op.cm, display = cm.display, doc = cm.doc;
-
-  if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); }
-
-  // Abort mouse wheel delta measurement, when scrolling explicitly
-  if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
-    { display.wheelStartX = display.wheelStartY = null; }
-
-  // Propagate the scroll position to the actual DOM scroller
-  if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); }
-
-  if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); }
-  // If we need to scroll a specific position into view, do so.
-  if (op.scrollToPos) {
-    var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
-                                 clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
-    maybeScrollWindow(cm, rect);
-  }
-
-  // Fire events for markers that are hidden/unidden by editing or
-  // undoing
-  var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
-  if (hidden) { for (var i = 0; i < hidden.length; ++i)
-    { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } }
-  if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)
-    { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } }
-
-  if (display.wrapper.offsetHeight)
-    { doc.scrollTop = cm.display.scroller.scrollTop; }
-
-  // Fire change events, and delayed event handlers
-  if (op.changeObjs)
-    { signal(cm, "changes", cm, op.changeObjs); }
-  if (op.update)
-    { op.update.finish(); }
-}
-
-// Run the given function in an operation
-function runInOp(cm, f) {
-  if (cm.curOp) { return f() }
-  startOperation(cm);
-  try { return f() }
-  finally { endOperation(cm); }
-}
-// Wraps a function in an operation. Returns the wrapped function.
-function operation(cm, f) {
-  return function() {
-    if (cm.curOp) { return f.apply(cm, arguments) }
-    startOperation(cm);
-    try { return f.apply(cm, arguments) }
-    finally { endOperation(cm); }
-  }
-}
-// Used to add methods to editor and doc instances, wrapping them in
-// operations.
-function methodOp(f) {
-  return function() {
-    if (this.curOp) { return f.apply(this, arguments) }
-    startOperation(this);
-    try { return f.apply(this, arguments) }
-    finally { endOperation(this); }
-  }
-}
-function docMethodOp(f) {
-  return function() {
-    var cm = this.cm;
-    if (!cm || cm.curOp) { return f.apply(this, arguments) }
-    startOperation(cm);
-    try { return f.apply(this, arguments) }
-    finally { endOperation(cm); }
-  }
-}
-
-// Updates the display.view data structure for a given change to the
-// document. From and to are in pre-change coordinates. Lendiff is
-// the amount of lines added or subtracted by the change. This is
-// used for changes that span multiple lines, or change the way
-// lines are divided into visual lines. regLineChange (below)
-// registers single-line changes.
-function regChange(cm, from, to, lendiff) {
-  if (from == null) { from = cm.doc.first; }
-  if (to == null) { to = cm.doc.first + cm.doc.size; }
-  if (!lendiff) { lendiff = 0; }
-
-  var display = cm.display;
-  if (lendiff && to < display.viewTo &&
-      (display.updateLineNumbers == null || display.updateLineNumbers > from))
-    { display.updateLineNumbers = from; }
-
-  cm.curOp.viewChanged = true;
-
-  if (from >= display.viewTo) { // Change after
-    if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
-      { resetView(cm); }
-  } else if (to <= display.viewFrom) { // Change before
-    if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
-      resetView(cm);
-    } else {
-      display.viewFrom += lendiff;
-      display.viewTo += lendiff;
-    }
-  } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
-    resetView(cm);
-  } else if (from <= display.viewFrom) { // Top overlap
-    var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
-    if (cut) {
-      display.view = display.view.slice(cut.index);
-      display.viewFrom = cut.lineN;
-      display.viewTo += lendiff;
-    } else {
-      resetView(cm);
-    }
-  } else if (to >= display.viewTo) { // Bottom overlap
-    var cut$1 = viewCuttingPoint(cm, from, from, -1);
-    if (cut$1) {
-      display.view = display.view.slice(0, cut$1.index);
-      display.viewTo = cut$1.lineN;
-    } else {
-      resetView(cm);
-    }
-  } else { // Gap in the middle
-    var cutTop = viewCuttingPoint(cm, from, from, -1);
-    var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
-    if (cutTop && cutBot) {
-      display.view = display.view.slice(0, cutTop.index)
-        .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
-        .concat(display.view.slice(cutBot.index));
-      display.viewTo += lendiff;
-    } else {
-      resetView(cm);
-    }
-  }
-
-  var ext = display.externalMeasured;
-  if (ext) {
-    if (to < ext.lineN)
-      { ext.lineN += lendiff; }
-    else if (from < ext.lineN + ext.size)
-      { display.externalMeasured = null; }
-  }
-}
-
-// Register a change to a single line. Type must be one of "text",
-// "gutter", "class", "widget"
-function regLineChange(cm, line, type) {
-  cm.curOp.viewChanged = true;
-  var display = cm.display, ext = cm.display.externalMeasured;
-  if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
-    { display.externalMeasured = null; }
-
-  if (line < display.viewFrom || line >= display.viewTo) { return }
-  var lineView = display.view[findViewIndex(cm, line)];
-  if (lineView.node == null) { return }
-  var arr = lineView.changes || (lineView.changes = []);
-  if (indexOf(arr, type) == -1) { arr.push(type); }
-}
-
-// Clear the view.
-function resetView(cm) {
-  cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
-  cm.display.view = [];
-  cm.display.viewOffset = 0;
-}
-
-function viewCuttingPoint(cm, oldN, newN, dir) {
-  var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
-  if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
-    { return {index: index, lineN: newN} }
-  var n = cm.display.viewFrom;
-  for (var i = 0; i < index; i++)
-    { n += view[i].size; }
-  if (n != oldN) {
-    if (dir > 0) {
-      if (index == view.length - 1) { return null }
-      diff = (n + view[index].size) - oldN;
-      index++;
-    } else {
-      diff = n - oldN;
-    }
-    oldN += diff; newN += diff;
-  }
-  while (visualLineNo(cm.doc, newN) != newN) {
-    if (index == (dir < 0 ? 0 : view.length - 1)) { return null }
-    newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
-    index += dir;
-  }
-  return {index: index, lineN: newN}
-}
-
-// Force the view to cover a given range, adding empty view element
-// or clipping off existing ones as needed.
-function adjustView(cm, from, to) {
-  var display = cm.display, view = display.view;
-  if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
-    display.view = buildViewArray(cm, from, to);
-    display.viewFrom = from;
-  } else {
-    if (display.viewFrom > from)
-      { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); }
-    else if (display.viewFrom < from)
-      { display.view = display.view.slice(findViewIndex(cm, from)); }
-    display.viewFrom = from;
-    if (display.viewTo < to)
-      { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); }
-    else if (display.viewTo > to)
-      { display.view = display.view.slice(0, findViewIndex(cm, to)); }
-  }
-  display.viewTo = to;
-}
-
-// Count the number of lines in the view whose DOM representation is
-// out of date (or nonexistent).
-function countDirtyView(cm) {
-  var view = cm.display.view, dirty = 0;
-  for (var i = 0; i < view.length; i++) {
-    var lineView = view[i];
-    if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; }
-  }
-  return dirty
-}
-
-// HIGHLIGHT WORKER
-
-function startWorker(cm, time) {
-  if (cm.doc.highlightFrontier < cm.display.viewTo)
-    { cm.state.highlight.set(time, bind(highlightWorker, cm)); }
-}
-
-function highlightWorker(cm) {
-  var doc = cm.doc;
-  if (doc.highlightFrontier >= cm.display.viewTo) { return }
-  var end = +new Date + cm.options.workTime;
-  var context = getContextBefore(cm, doc.highlightFrontier);
-  var changedLines = [];
-
-  doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
-    if (context.line >= cm.display.viewFrom) { // Visible
-      var oldStyles = line.styles;
-      var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null;
-      var highlighted = highlightLine(cm, line, context, true);
-      if (resetState) { context.state = resetState; }
-      line.styles = highlighted.styles;
-      var oldCls = line.styleClasses, newCls = highlighted.classes;
-      if (newCls) { line.styleClasses = newCls; }
-      else if (oldCls) { line.styleClasses = null; }
-      var ischange = !oldStyles || oldStyles.length != line.styles.length ||
-        oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
-      for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; }
-      if (ischange) { changedLines.push(context.line); }
-      line.stateAfter = context.save();
-      context.nextLine();
-    } else {
-      if (line.text.length <= cm.options.maxHighlightLength)
-        { processLine(cm, line.text, context); }
-      line.stateAfter = context.line % 5 == 0 ? context.save() : null;
-      context.nextLine();
-    }
-    if (+new Date > end) {
-      startWorker(cm, cm.options.workDelay);
-      return true
-    }
-  });
-  doc.highlightFrontier = context.line;
-  doc.modeFrontier = Math.max(doc.modeFrontier, context.line);
-  if (changedLines.length) { runInOp(cm, function () {
-    for (var i = 0; i < changedLines.length; i++)
-      { regLineChange(cm, changedLines[i], "text"); }
-  }); }
-}
-
-// DISPLAY DRAWING
-
-var DisplayUpdate = function(cm, viewport, force) {
-  var display = cm.display;
-
-  this.viewport = viewport;
-  // Store some values that we'll need later (but don't want to force a relayout for)
-  this.visible = visibleLines(display, cm.doc, viewport);
-  this.editorIsHidden = !display.wrapper.offsetWidth;
-  this.wrapperHeight = display.wrapper.clientHeight;
-  this.wrapperWidth = display.wrapper.clientWidth;
-  this.oldDisplayWidth = displayWidth(cm);
-  this.force = force;
-  this.dims = getDimensions(cm);
-  this.events = [];
-};
-
-DisplayUpdate.prototype.signal = function (emitter, type) {
-  if (hasHandler(emitter, type))
-    { this.events.push(arguments); }
-};
-DisplayUpdate.prototype.finish = function () {
-    var this$1 = this;
-
-  for (var i = 0; i < this.events.length; i++)
-    { signal.apply(null, this$1.events[i]); }
-};
-
-function maybeClipScrollbars(cm) {
-  var display = cm.display;
-  if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
-    display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
-    display.heightForcer.style.height = scrollGap(cm) + "px";
-    display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
-    display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
-    display.scrollbarsClipped = true;
-  }
-}
-
-function selectionSnapshot(cm) {
-  if (cm.hasFocus()) { return null }
-  var active = activeElt();
-  if (!active || !contains(cm.display.lineDiv, active)) { return null }
-  var result = {activeElt: active};
-  if (window.getSelection) {
-    var sel = window.getSelection();
-    if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
-      result.anchorNode = sel.anchorNode;
-      result.anchorOffset = sel.anchorOffset;
-      result.focusNode = sel.focusNode;
-      result.focusOffset = sel.focusOffset;
-    }
-  }
-  return result
-}
-
-function restoreSelection(snapshot) {
-  if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
-  snapshot.activeElt.focus();
-  if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
-    var sel = window.getSelection(), range$$1 = document.createRange();
-    range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
-    range$$1.collapse(false);
-    sel.removeAllRanges();
-    sel.addRange(range$$1);
-    sel.extend(snapshot.focusNode, snapshot.focusOffset);
-  }
-}
-
-// Does the actual updating of the line display. Bails out
-// (returning false) when there is nothing to be done and forced is
-// false.
-function updateDisplayIfNeeded(cm, update) {
-  var display = cm.display, doc = cm.doc;
-
-  if (update.editorIsHidden) {
-    resetView(cm);
-    return false
-  }
-
-  // Bail out if the visible area is already rendered and nothing changed.
-  if (!update.force &&
-      update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
-      (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
-      display.renderedView == display.view && countDirtyView(cm) == 0)
-    { return false }
-
-  if (maybeUpdateLineNumberWidth(cm)) {
-    resetView(cm);
-    update.dims = getDimensions(cm);
-  }
-
-  // Compute a suitable new viewport (from & to)
-  var end = doc.first + doc.size;
-  var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
-  var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
-  if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); }
-  if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); }
-  if (sawCollapsedSpans) {
-    from = visualLineNo(cm.doc, from);
-    to = visualLineEndNo(cm.doc, to);
-  }
-
-  var different = from != display.viewFrom || to != display.viewTo ||
-    display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
-  adjustView(cm, from, to);
-
-  display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
-  // Position the mover div to align with the current scroll position
-  cm.display.mover.style.top = display.viewOffset + "px";
-
-  var toUpdate = countDirtyView(cm);
-  if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
-      (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
-    { return false }
-
-  // For big changes, we hide the enclosing element during the
-  // update, since that speeds up the operations on most browsers.
-  var selSnapshot = selectionSnapshot(cm);
-  if (toUpdate > 4) { display.lineDiv.style.display = "none"; }
-  patchDisplay(cm, display.updateLineNumbers, update.dims);
-  if (toUpdate > 4) { display.lineDiv.style.display = ""; }
-  display.renderedView = display.view;
-  // There might have been a widget with a focused element that got
-  // hidden or updated, if so re-focus it.
-  restoreSelection(selSnapshot);
-
-  // Prevent selection and cursors from interfering with the scroll
-  // width and height.
-  removeChildren(display.cursorDiv);
-  removeChildren(display.selectionDiv);
-  display.gutters.style.height = display.sizer.style.minHeight = 0;
-
-  if (different) {
-    display.lastWrapHeight = update.wrapperHeight;
-    display.lastWrapWidth = update.wrapperWidth;
-    startWorker(cm, 400);
-  }
-
-  display.updateLineNumbers = null;
-
-  return true
-}
-
-function postUpdateDisplay(cm, update) {
-  var viewport = update.viewport;
-
-  for (var first = true;; first = false) {
-    if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
-      // Clip forced viewport to actual scrollable area.
-      if (viewport && viewport.top != null)
-        { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; }
-      // Updated line heights might result in the drawn area not
-      // actually covering the viewport. Keep looping until it does.
-      update.visible = visibleLines(cm.display, cm.doc, viewport);
-      if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
-        { break }
-    }
-    if (!updateDisplayIfNeeded(cm, update)) { break }
-    updateHeightsInViewport(cm);
-    var barMeasure = measureForScrollbars(cm);
-    updateSelection(cm);
-    updateScrollbars(cm, barMeasure);
-    setDocumentHeight(cm, barMeasure);
-    update.force = false;
-  }
-
-  update.signal(cm, "update", cm);
-  if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
-    update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
-    cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
-  }
-}
-
-function updateDisplaySimple(cm, viewport) {
-  var update = new DisplayUpdate(cm, viewport);
-  if (updateDisplayIfNeeded(cm, update)) {
-    updateHeightsInViewport(cm);
-    postUpdateDisplay(cm, update);
-    var barMeasure = measureForScrollbars(cm);
-    updateSelection(cm);
-    updateScrollbars(cm, barMeasure);
-    setDocumentHeight(cm, barMeasure);
-    update.finish();
-  }
-}
-
-// Sync the actual display DOM structure with display.view, removing
-// nodes for lines that are no longer in view, and creating the ones
-// that are not there yet, and updating the ones that are out of
-// date.
-function patchDisplay(cm, updateNumbersFrom, dims) {
-  var display = cm.display, lineNumbers = cm.options.lineNumbers;
-  var container = display.lineDiv, cur = container.firstChild;
-
-  function rm(node) {
-    var next = node.nextSibling;
-    // Works around a throw-scroll bug in OS X Webkit
-    if (webkit && mac && cm.display.currentWheelTarget == node)
-      { node.style.display = "none"; }
-    else
-      { node.parentNode.removeChild(node); }
-    return next
-  }
-
-  var view = display.view, lineN = display.viewFrom;
-  // Loop over the elements in the view, syncing cur (the DOM nodes
-  // in display.lineDiv) with the view as we go.
-  for (var i = 0; i < view.length; i++) {
-    var lineView = view[i];
-    if (lineView.hidden) {
-    } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
-      var node = buildLineElement(cm, lineView, lineN, dims);
-      container.insertBefore(node, cur);
-    } else { // Already drawn
-      while (cur != lineView.node) { cur = rm(cur); }
-      var updateNumber = lineNumbers && updateNumbersFrom != null &&
-        updateNumbersFrom <= lineN && lineView.lineNumber;
-      if (lineView.changes) {
-        if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; }
-        updateLineForChanges(cm, lineView, lineN, dims);
-      }
-      if (updateNumber) {
-        removeChildren(lineView.lineNumber);
-        lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
-      }
-      cur = lineView.node.nextSibling;
-    }
-    lineN += lineView.size;
-  }
-  while (cur) { cur = rm(cur); }
-}
-
-function updateGutterSpace(cm) {
-  var width = cm.display.gutters.offsetWidth;
-  cm.display.sizer.style.marginLeft = width + "px";
-}
-
-function setDocumentHeight(cm, measure) {
-  cm.display.sizer.style.minHeight = measure.docHeight + "px";
-  cm.display.heightForcer.style.top = measure.docHeight + "px";
-  cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px";
-}
-
-// Rebuild the gutter elements, ensure the margin to the left of the
-// code matches their width.
-function updateGutters(cm) {
-  var gutters = cm.display.gutters, specs = cm.options.gutters;
-  removeChildren(gutters);
-  var i = 0;
-  for (; i < specs.length; ++i) {
-    var gutterClass = specs[i];
-    var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
-    if (gutterClass == "CodeMirror-linenumbers") {
-      cm.display.lineGutter = gElt;
-      gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
-    }
-  }
-  gutters.style.display = i ? "" : "none";
-  updateGutterSpace(cm);
-}
-
-// Make sure the gutters options contains the element
-// "CodeMirror-linenumbers" when the lineNumbers option is true.
-function setGuttersForLineNumbers(options) {
-  var found = indexOf(options.gutters, "CodeMirror-linenumbers");
-  if (found == -1 && options.lineNumbers) {
-    options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
-  } else if (found > -1 && !options.lineNumbers) {
-    options.gutters = options.gutters.slice(0);
-    options.gutters.splice(found, 1);
-  }
-}
-
-// Since the delta values reported on mouse wheel events are
-// unstandardized between browsers and even browser versions, and
-// generally horribly unpredictable, this code starts by measuring
-// the scroll effect that the first few mouse wheel events have,
-// and, from that, detects the way it can convert deltas to pixel
-// offsets afterwards.
-//
-// The reason we want to know the amount a wheel event will scroll
-// is that it gives us a chance to update the display before the
-// actual scrolling happens, reducing flickering.
-
-var wheelSamples = 0;
-var wheelPixelsPerUnit = null;
-// Fill in a browser-detected starting value on browsers where we
-// know one. These don't have to be accurate -- the result of them
-// being wrong would just be a slight flicker on the first wheel
-// scroll (if it is large enough).
-if (ie) { wheelPixelsPerUnit = -.53; }
-else if (gecko) { wheelPixelsPerUnit = 15; }
-else if (chrome) { wheelPixelsPerUnit = -.7; }
-else if (safari) { wheelPixelsPerUnit = -1/3; }
-
-function wheelEventDelta(e) {
-  var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
-  if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; }
-  if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; }
-  else if (dy == null) { dy = e.wheelDelta; }
-  return {x: dx, y: dy}
-}
-function wheelEventPixels(e) {
-  var delta = wheelEventDelta(e);
-  delta.x *= wheelPixelsPerUnit;
-  delta.y *= wheelPixelsPerUnit;
-  return delta
-}
-
-function onScrollWheel(cm, e) {
-  var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
-
-  var display = cm.display, scroll = display.scroller;
-  // Quit if there's nothing to scroll here
-  var canScrollX = scroll.scrollWidth > scroll.clientWidth;
-  var canScrollY = scroll.scrollHeight > scroll.clientHeight;
-  if (!(dx && canScrollX || dy && canScrollY)) { return }
-
-  // Webkit browsers on OS X abort momentum scrolls when the target
-  // of the scroll event is removed from the scrollable element.
-  // This hack (see related code in patchDisplay) makes sure the
-  // element is kept around.
-  if (dy && mac && webkit) {
-    outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
-      for (var i = 0; i < view.length; i++) {
-        if (view[i].node == cur) {
-          cm.display.currentWheelTarget = cur;
-          break outer
-        }
-      }
-    }
-  }
-
-  // On some browsers, horizontal scrolling will cause redraws to
-  // happen before the gutter has been realigned, causing it to
-  // wriggle around in a most unseemly way. When we have an
-  // estimated pixels/delta value, we just handle horizontal
-  // scrolling entirely here. It'll be slightly off from native, but
-  // better than glitching out.
-  if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
-    if (dy && canScrollY)
-      { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); }
-    setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit));
-    // Only prevent default scrolling if vertical scrolling is
-    // actually possible. Otherwise, it causes vertical scroll
-    // jitter on OSX trackpads when deltaX is small and deltaY
-    // is large (issue #3579)
-    if (!dy || (dy && canScrollY))
-      { e_preventDefault(e); }
-    display.wheelStartX = null; // Abort measurement, if in progress
-    return
-  }
-
-  // 'Project' the visible viewport to cover the area that is being
-  // scrolled into view (if we know enough to estimate it).
-  if (dy && wheelPixelsPerUnit != null) {
-    var pixels = dy * wheelPixelsPerUnit;
-    var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
-    if (pixels < 0) { top = Math.max(0, top + pixels - 50); }
-    else { bot = Math.min(cm.doc.height, bot + pixels + 50); }
-    updateDisplaySimple(cm, {top: top, bottom: bot});
-  }
-
-  if (wheelSamples < 20) {
-    if (display.wheelStartX == null) {
-      display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
-      display.wheelDX = dx; display.wheelDY = dy;
-      setTimeout(function () {
-        if (display.wheelStartX == null) { return }
-        var movedX = scroll.scrollLeft - display.wheelStartX;
-        var movedY = scroll.scrollTop - display.wheelStartY;
-        var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
-          (movedX && display.wheelDX && movedX / display.wheelDX);
-        display.wheelStartX = display.wheelStartY = null;
-        if (!sample) { return }
-        wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
-        ++wheelSamples;
-      }, 200);
-    } else {
-      display.wheelDX += dx; display.wheelDY += dy;
-    }
-  }
-}
-
-// Selection objects are immutable. A new one is created every time
-// the selection changes. A selection is one or more non-overlapping
-// (and non-touching) ranges, sorted, and an integer that indicates
-// which one is the primary selection (the one that's scrolled into
-// view, that getCursor returns, etc).
-var Selection = function(ranges, primIndex) {
-  this.ranges = ranges;
-  this.primIndex = primIndex;
-};
-
-Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
-
-Selection.prototype.equals = function (other) {
-    var this$1 = this;
-
-  if (other == this) { return true }
-  if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
-  for (var i = 0; i < this.ranges.length; i++) {
-    var here = this$1.ranges[i], there = other.ranges[i];
-    if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
-  }
-  return true
-};
-
-Selection.prototype.deepCopy = function () {
-    var this$1 = this;
-
-  var out = [];
-  for (var i = 0; i < this.ranges.length; i++)
-    { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)); }
-  return new Selection(out, this.primIndex)
-};
-
-Selection.prototype.somethingSelected = function () {
-    var this$1 = this;
-
-  for (var i = 0; i < this.ranges.length; i++)
-    { if (!this$1.ranges[i].empty()) { return true } }
-  return false
-};
-
-Selection.prototype.contains = function (pos, end) {
-    var this$1 = this;
-
-  if (!end) { end = pos; }
-  for (var i = 0; i < this.ranges.length; i++) {
-    var range = this$1.ranges[i];
-    if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
-      { return i }
-  }
-  return -1
-};
-
-var Range = function(anchor, head) {
-  this.anchor = anchor; this.head = head;
-};
-
-Range.prototype.from = function () { return minPos(this.anchor, this.head) };
-Range.prototype.to = function () { return maxPos(this.anchor, this.head) };
-Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };
-
-// Take an unsorted, potentially overlapping set of ranges, and
-// build a selection out of it. 'Consumes' ranges array (modifying
-// it).
-function normalizeSelection(ranges, primIndex) {
-  var prim = ranges[primIndex];
-  ranges.sort(function (a, b) { return cmp(a.from(), b.from()); });
-  primIndex = indexOf(ranges, prim);
-  for (var i = 1; i < ranges.length; i++) {
-    var cur = ranges[i], prev = ranges[i - 1];
-    if (cmp(prev.to(), cur.from()) >= 0) {
-      var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
-      var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
-      if (i <= primIndex) { --primIndex; }
-      ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
-    }
-  }
-  return new Selection(ranges, primIndex)
-}
-
-function simpleSelection(anchor, head) {
-  return new Selection([new Range(anchor, head || anchor)], 0)
-}
-
-// Compute the position of the end of a change (its 'to' property
-// refers to the pre-change end).
-function changeEnd(change) {
-  if (!change.text) { return change.to }
-  return Pos(change.from.line + change.text.length - 1,
-             lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))
-}
-
-// Adjust a position to refer to the post-change position of the
-// same text, or the end of the change if the change covers it.
-function adjustForChange(pos, change) {
-  if (cmp(pos, change.from) < 0) { return pos }
-  if (cmp(pos, change.to) <= 0) { return changeEnd(change) }
-
-  var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
-  if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; }
-  return Pos(line, ch)
-}
-
-function computeSelAfterChange(doc, change) {
-  var out = [];
-  for (var i = 0; i < doc.sel.ranges.length; i++) {
-    var range = doc.sel.ranges[i];
-    out.push(new Range(adjustForChange(range.anchor, change),
-                       adjustForChange(range.head, change)));
-  }
-  return normalizeSelection(out, doc.sel.primIndex)
-}
-
-function offsetPos(pos, old, nw) {
-  if (pos.line == old.line)
-    { return Pos(nw.line, pos.ch - old.ch + nw.ch) }
-  else
-    { return Pos(nw.line + (pos.line - old.line), pos.ch) }
-}
-
-// Used by replaceSelections to allow moving the selection to the
-// start or around the replaced test. Hint may be "start" or "around".
-function computeReplacedSel(doc, changes, hint) {
-  var out = [];
-  var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
-  for (var i = 0; i < changes.length; i++) {
-    var change = changes[i];
-    var from = offsetPos(change.from, oldPrev, newPrev);
-    var to = offsetPos(changeEnd(change), oldPrev, newPrev);
-    oldPrev = change.to;
-    newPrev = to;
-    if (hint == "around") {
-      var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
-      out[i] = new Range(inv ? to : from, inv ? from : to);
-    } else {
-      out[i] = new Range(from, from);
-    }
-  }
-  return new Selection(out, doc.sel.primIndex)
-}
-
-// Used to get the editor into a consistent state again when options change.
-
-function loadMode(cm) {
-  cm.doc.mode = getMode(cm.options, cm.doc.modeOption);
-  resetModeState(cm);
-}
-
-function resetModeState(cm) {
-  cm.doc.iter(function (line) {
-    if (line.stateAfter) { line.stateAfter = null; }
-    if (line.styles) { line.styles = null; }
-  });
-  cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first;
-  startWorker(cm, 100);
-  cm.state.modeGen++;
-  if (cm.curOp) { regChange(cm); }
-}
-
-// DOCUMENT DATA STRUCTURE
-
-// By default, updates that start and end at the beginning of a line
-// are treated specially, in order to make the association of line
-// widgets and marker elements with the text behave more intuitive.
-function isWholeLineUpdate(doc, change) {
-  return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
-    (!doc.cm || doc.cm.options.wholeLineUpdateBefore)
-}
-
-// Perform a change on the document data structure.
-function updateDoc(doc, change, markedSpans, estimateHeight$$1) {
-  function spansFor(n) {return markedSpans ? markedSpans[n] : null}
-  function update(line, text, spans) {
-    updateLine(line, text, spans, estimateHeight$$1);
-    signalLater(line, "change", line, change);
-  }
-  function linesFor(start, end) {
-    var result = [];
-    for (var i = start; i < end; ++i)
-      { result.push(new Line(text[i], spansFor(i), estimateHeight$$1)); }
-    return result
-  }
-
-  var from = change.from, to = change.to, text = change.text;
-  var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
-  var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
-
-  // Adjust the line structure
-  if (change.full) {
-    doc.insert(0, linesFor(0, text.length));
-    doc.remove(text.length, doc.size - text.length);
-  } else if (isWholeLineUpdate(doc, change)) {
-    // This is a whole-line replace. Treated specially to make
-    // sure line objects move the way they are supposed to.
-    var added = linesFor(0, text.length - 1);
-    update(lastLine, lastLine.text, lastSpans);
-    if (nlines) { doc.remove(from.line, nlines); }
-    if (added.length) { doc.insert(from.line, added); }
-  } else if (firstLine == lastLine) {
-    if (text.length == 1) {
-      update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
-    } else {
-      var added$1 = linesFor(1, text.length - 1);
-      added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight$$1));
-      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
-      doc.insert(from.line + 1, added$1);
-    }
-  } else if (text.length == 1) {
-    update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
-    doc.remove(from.line + 1, nlines);
-  } else {
-    update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
-    update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
-    var added$2 = linesFor(1, text.length - 1);
-    if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); }
-    doc.insert(from.line + 1, added$2);
-  }
-
-  signalLater(doc, "change", doc, change);
-}
-
-// Call f for all linked documents.
-function linkedDocs(doc, f, sharedHistOnly) {
-  function propagate(doc, skip, sharedHist) {
-    if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {
-      var rel = doc.linked[i];
-      if (rel.doc == skip) { continue }
-      var shared = sharedHist && rel.sharedHist;
-      if (sharedHistOnly && !shared) { continue }
-      f(rel.doc, shared);
-      propagate(rel.doc, doc, shared);
-    } }
-  }
-  propagate(doc, null, true);
-}
-
-// Attach a document to an editor.
-function attachDoc(cm, doc) {
-  if (doc.cm) { throw new Error("This document is already in use.") }
-  cm.doc = doc;
-  doc.cm = cm;
-  estimateLineHeights(cm);
-  loadMode(cm);
-  setDirectionClass(cm);
-  if (!cm.options.lineWrapping) { findMaxLine(cm); }
-  cm.options.mode = doc.modeOption;
-  regChange(cm);
-}
-
-function setDirectionClass(cm) {
-  (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl");
-}
-
-function directionChanged(cm) {
-  runInOp(cm, function () {
-    setDirectionClass(cm);
-    regChange(cm);
-  });
-}
-
-function History(startGen) {
-  // Arrays of change events and selections. Doing something adds an
-  // event to done and clears undo. Undoing moves events from done
-  // to undone, redoing moves them in the other direction.
-  this.done = []; this.undone = [];
-  this.undoDepth = Infinity;
-  // Used to track when changes can be merged into a single undo
-  // event
-  this.lastModTime = this.lastSelTime = 0;
-  this.lastOp = this.lastSelOp = null;
-  this.lastOrigin = this.lastSelOrigin = null;
-  // Used by the isClean() method
-  this.generation = this.maxGeneration = startGen || 1;
-}
-
-// Create a history change event from an updateDoc-style change
-// object.
-function historyChangeFromChange(doc, change) {
-  var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
-  attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
-  linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true);
-  return histChange
-}
-
-// Pop all selection events off the end of a history array. Stop at
-// a change event.
-function clearSelectionEvents(array) {
-  while (array.length) {
-    var last = lst(array);
-    if (last.ranges) { array.pop(); }
-    else { break }
-  }
-}
-
-// Find the top change event in the history. Pop off selection
-// events that are in the way.
-function lastChangeEvent(hist, force) {
-  if (force) {
-    clearSelectionEvents(hist.done);
-    return lst(hist.done)
-  } else if (hist.done.length && !lst(hist.done).ranges) {
-    return lst(hist.done)
-  } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
-    hist.done.pop();
-    return lst(hist.done)
-  }
-}
-
-// Register a change in the history. Merges changes that are within
-// a single operation, or are close together with an origin that
-// allows merging (starting with "+") into a single event.
-function addChangeToHistory(doc, change, selAfter, opId) {
-  var hist = doc.history;
-  hist.undone.length = 0;
-  var time = +new Date, cur;
-  var last;
-
-  if ((hist.lastOp == opId ||
-       hist.lastOrigin == change.origin && change.origin &&
-       ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
-        change.origin.charAt(0) == "*")) &&
-      (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
-    // Merge this change into the last event
-    last = lst(cur.changes);
-    if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
-      // Optimized case for simple insertion -- don't want to add
-      // new changesets for every character typed
-      last.to = changeEnd(change);
-    } else {
-      // Add new sub-event
-      cur.changes.push(historyChangeFromChange(doc, change));
-    }
-  } else {
-    // Can not be merged, start a new event.
-    var before = lst(hist.done);
-    if (!before || !before.ranges)
-      { pushSelectionToHistory(doc.sel, hist.done); }
-    cur = {changes: [historyChangeFromChange(doc, change)],
-           generation: hist.generation};
-    hist.done.push(cur);
-    while (hist.done.length > hist.undoDepth) {
-      hist.done.shift();
-      if (!hist.done[0].ranges) { hist.done.shift(); }
-    }
-  }
-  hist.done.push(selAfter);
-  hist.generation = ++hist.maxGeneration;
-  hist.lastModTime = hist.lastSelTime = time;
-  hist.lastOp = hist.lastSelOp = opId;
-  hist.lastOrigin = hist.lastSelOrigin = change.origin;
-
-  if (!last) { signal(doc, "historyAdded"); }
-}
-
-function selectionEventCanBeMerged(doc, origin, prev, sel) {
-  var ch = origin.charAt(0);
-  return ch == "*" ||
-    ch == "+" &&
-    prev.ranges.length == sel.ranges.length &&
-    prev.somethingSelected() == sel.somethingSelected() &&
-    new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)
-}
-
-// Called whenever the selection changes, sets the new selection as
-// the pending selection in the history, and pushes the old pending
-// selection into the 'done' array when it was significantly
-// different (in number of selected ranges, emptiness, or time).
-function addSelectionToHistory(doc, sel, opId, options) {
-  var hist = doc.history, origin = options && options.origin;
-
-  // A new event is started when the previous origin does not match
-  // the current, or the origins don't allow matching. Origins
-  // starting with * are always merged, those starting with + are
-  // merged when similar and close together in time.
-  if (opId == hist.lastSelOp ||
-      (origin && hist.lastSelOrigin == origin &&
-       (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
-        selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
-    { hist.done[hist.done.length - 1] = sel; }
-  else
-    { pushSelectionToHistory(sel, hist.done); }
-
-  hist.lastSelTime = +new Date;
-  hist.lastSelOrigin = origin;
-  hist.lastSelOp = opId;
-  if (options && options.clearRedo !== false)
-    { clearSelectionEvents(hist.undone); }
-}
-
-function pushSelectionToHistory(sel, dest) {
-  var top = lst(dest);
-  if (!(top && top.ranges && top.equals(sel)))
-    { dest.push(sel); }
-}
-
-// Used to store marked span information in the history.
-function attachLocalSpans(doc, change, from, to) {
-  var existing = change["spans_" + doc.id], n = 0;
-  doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
-    if (line.markedSpans)
-      { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; }
-    ++n;
-  });
-}
-
-// When un/re-doing restores text containing marked spans, those
-// that have been explicitly cleared should not be restored.
-function removeClearedSpans(spans) {
-  if (!spans) { return null }
-  var out;
-  for (var i = 0; i < spans.length; ++i) {
-    if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } }
-    else if (out) { out.push(spans[i]); }
-  }
-  return !out ? spans : out.length ? out : null
-}
-
-// Retrieve and filter the old marked spans stored in a change event.
-function getOldSpans(doc, change) {
-  var found = change["spans_" + doc.id];
-  if (!found) { return null }
-  var nw = [];
-  for (var i = 0; i < change.text.length; ++i)
-    { nw.push(removeClearedSpans(found[i])); }
-  return nw
-}
-
-// Used for un/re-doing changes from the history. Combines the
-// result of computing the existing spans with the set of spans that
-// existed in the history (so that deleting around a span and then
-// undoing brings back the span).
-function mergeOldSpans(doc, change) {
-  var old = getOldSpans(doc, change);
-  var stretched = stretchSpansOverChange(doc, change);
-  if (!old) { return stretched }
-  if (!stretched) { return old }
-
-  for (var i = 0; i < old.length; ++i) {
-    var oldCur = old[i], stretchCur = stretched[i];
-    if (oldCur && stretchCur) {
-      spans: for (var j = 0; j < stretchCur.length; ++j) {
-        var span = stretchCur[j];
-        for (var k = 0; k < oldCur.length; ++k)
-          { if (oldCur[k].marker == span.marker) { continue spans } }
-        oldCur.push(span);
-      }
-    } else if (stretchCur) {
-      old[i] = stretchCur;
-    }
-  }
-  return old
-}
-
-// Used both to provide a JSON-safe object in .getHistory, and, when
-// detaching a document, to split the history in two
-function copyHistoryArray(events, newGroup, instantiateSel) {
-  var copy = [];
-  for (var i = 0; i < events.length; ++i) {
-    var event = events[i];
-    if (event.ranges) {
-      copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
-      continue
-    }
-    var changes = event.changes, newChanges = [];
-    copy.push({changes: newChanges});
-    for (var j = 0; j < changes.length; ++j) {
-      var change = changes[j], m = (void 0);
-      newChanges.push({from: change.from, to: change.to, text: change.text});
-      if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) {
-        if (indexOf(newGroup, Number(m[1])) > -1) {
-          lst(newChanges)[prop] = change[prop];
-          delete change[prop];
-        }
-      } } }
-    }
-  }
-  return copy
-}
-
-// The 'scroll' parameter given to many of these indicated whether
-// the new cursor position should be scrolled into view after
-// modifying the selection.
-
-// If shift is held or the extend flag is set, extends a range to
-// include a given position (and optionally a second position).
-// Otherwise, simply returns the range between the given positions.
-// Used for cursor motion and such.
-function extendRange(range, head, other, extend) {
-  if (extend) {
-    var anchor = range.anchor;
-    if (other) {
-      var posBefore = cmp(head, anchor) < 0;
-      if (posBefore != (cmp(other, anchor) < 0)) {
-        anchor = head;
-        head = other;
-      } else if (posBefore != (cmp(head, other) < 0)) {
-        head = other;
-      }
-    }
-    return new Range(anchor, head)
-  } else {
-    return new Range(other || head, head)
-  }
-}
-
-// Extend the primary selection range, discard the rest.
-function extendSelection(doc, head, other, options, extend) {
-  if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); }
-  setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options);
-}
-
-// Extend all selections (pos is an array of selections with length
-// equal the number of selections)
-function extendSelections(doc, heads, options) {
-  var out = [];
-  var extend = doc.cm && (doc.cm.display.shift || doc.extend);
-  for (var i = 0; i < doc.sel.ranges.length; i++)
-    { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); }
-  var newSel = normalizeSelection(out, doc.sel.primIndex);
-  setSelection(doc, newSel, options);
-}
-
-// Updates a single range in the selection.
-function replaceOneSelection(doc, i, range, options) {
-  var ranges = doc.sel.ranges.slice(0);
-  ranges[i] = range;
-  setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
-}
-
-// Reset the selection to a single range.
-function setSimpleSelection(doc, anchor, head, options) {
-  setSelection(doc, simpleSelection(anchor, head), options);
-}
-
-// Give beforeSelectionChange handlers a change to influence a
-// selection update.
-function filterSelectionChange(doc, sel, options) {
-  var obj = {
-    ranges: sel.ranges,
-    update: function(ranges) {
-      var this$1 = this;
-
-      this.ranges = [];
-      for (var i = 0; i < ranges.length; i++)
-        { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
-                                   clipPos(doc, ranges[i].head)); }
-    },
-    origin: options && options.origin
-  };
-  signal(doc, "beforeSelectionChange", doc, obj);
-  if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); }
-  if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) }
-  else { return sel }
-}
-
-function setSelectionReplaceHistory(doc, sel, options) {
-  var done = doc.history.done, last = lst(done);
-  if (last && last.ranges) {
-    done[done.length - 1] = sel;
-    setSelectionNoUndo(doc, sel, options);
-  } else {
-    setSelection(doc, sel, options);
-  }
-}
-
-// Set a new selection.
-function setSelection(doc, sel, options) {
-  setSelectionNoUndo(doc, sel, options);
-  addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
-}
-
-function setSelectionNoUndo(doc, sel, options) {
-  if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
-    { sel = filterSelectionChange(doc, sel, options); }
-
-  var bias = options && options.bias ||
-    (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
-  setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
-
-  if (!(options && options.scroll === false) && doc.cm)
-    { ensureCursorVisible(doc.cm); }
-}
-
-function setSelectionInner(doc, sel) {
-  if (sel.equals(doc.sel)) { return }
-
-  doc.sel = sel;
-
-  if (doc.cm) {
-    doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
-    signalCursorActivity(doc.cm);
-  }
-  signalLater(doc, "cursorActivity", doc);
-}
-
-// Verify that the selection does not partially select any atomic
-// marked ranges.
-function reCheckSelection(doc) {
-  setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false));
-}
-
-// Return a selection that does not partially select any atomic
-// ranges.
-function skipAtomicInSelection(doc, sel, bias, mayClear) {
-  var out;
-  for (var i = 0; i < sel.ranges.length; i++) {
-    var range = sel.ranges[i];
-    var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
-    var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
-    var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
-    if (out || newAnchor != range.anchor || newHead != range.head) {
-      if (!out) { out = sel.ranges.slice(0, i); }
-      out[i] = new Range(newAnchor, newHead);
-    }
-  }
-  return out ? normalizeSelection(out, sel.primIndex) : sel
-}
-
-function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
-  var line = getLine(doc, pos.line);
-  if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
-    var sp = line.markedSpans[i], m = sp.marker;
-    if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
-        (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
-      if (mayClear) {
-        signal(m, "beforeCursorEnter");
-        if (m.explicitlyCleared) {
-          if (!line.markedSpans) { break }
-          else {--i; continue}
-        }
-      }
-      if (!m.atomic) { continue }
-
-      if (oldPos) {
-        var near = m.find(dir < 0 ? 1 : -1), diff = (void 0);
-        if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)
-          { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); }
-        if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
-          { return skipAtomicInner(doc, near, pos, dir, mayClear) }
-      }
-
-      var far = m.find(dir < 0 ? -1 : 1);
-      if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)
-        { far = movePos(doc, far, dir, far.line == pos.line ? line : null); }
-      return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
-    }
-  } }
-  return pos
-}
-
-// Ensure a given position is not inside an atomic range.
-function skipAtomic(doc, pos, oldPos, bias, mayClear) {
-  var dir = bias || 1;
-  var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
-      (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
-      skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
-      (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
-  if (!found) {
-    doc.cantEdit = true;
-    return Pos(doc.first, 0)
-  }
-  return found
-}
-
-function movePos(doc, pos, dir, line) {
-  if (dir < 0 && pos.ch == 0) {
-    if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }
-    else { return null }
-  } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
-    if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }
-    else { return null }
-  } else {
-    return new Pos(pos.line, pos.ch + dir)
-  }
-}
-
-function selectAll(cm) {
-  cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);
-}
-
-// UPDATING
-
-// Allow "beforeChange" event handlers to influence a change
-function filterChange(doc, change, update) {
-  var obj = {
-    canceled: false,
-    from: change.from,
-    to: change.to,
-    text: change.text,
-    origin: change.origin,
-    cancel: function () { return obj.canceled = true; }
-  };
-  if (update) { obj.update = function (from, to, text, origin) {
-    if (from) { obj.from = clipPos(doc, from); }
-    if (to) { obj.to = clipPos(doc, to); }
-    if (text) { obj.text = text; }
-    if (origin !== undefined) { obj.origin = origin; }
-  }; }
-  signal(doc, "beforeChange", doc, obj);
-  if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); }
-
-  if (obj.canceled) { return null }
-  return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}
-}
-
-// Apply a change to a document, and add it to the document's
-// history, and propagating it to all linked documents.
-function makeChange(doc, change, ignoreReadOnly) {
-  if (doc.cm) {
-    if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }
-    if (doc.cm.state.suppressEdits) { return }
-  }
-
-  if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
-    change = filterChange(doc, change, true);
-    if (!change) { return }
-  }
-
-  // Possibly split or suppress the update based on the presence
-  // of read-only spans in its range.
-  var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
-  if (split) {
-    for (var i = split.length - 1; i >= 0; --i)
-      { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}); }
-  } else {
-    makeChangeInner(doc, change);
-  }
-}
-
-function makeChangeInner(doc, change) {
-  if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return }
-  var selAfter = computeSelAfterChange(doc, change);
-  addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
-
-  makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
-  var rebased = [];
-
-  linkedDocs(doc, function (doc, sharedHist) {
-    if (!sharedHist && indexOf(rebased, doc.history) == -1) {
-      rebaseHist(doc.history, change);
-      rebased.push(doc.history);
-    }
-    makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
-  });
-}
-
-// Revert a change stored in a document's history.
-function makeChangeFromHistory(doc, type, allowSelectionOnly) {
-  if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return }
-
-  var hist = doc.history, event, selAfter = doc.sel;
-  var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
-
-  // Verify that there is a useable event (so that ctrl-z won't
-  // needlessly clear selection events)
-  var i = 0;
-  for (; i < source.length; i++) {
-    event = source[i];
-    if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
-      { break }
-  }
-  if (i == source.length) { return }
-  hist.lastOrigin = hist.lastSelOrigin = null;
-
-  for (;;) {
-    event = source.pop();
-    if (event.ranges) {
-      pushSelectionToHistory(event, dest);
-      if (allowSelectionOnly && !event.equals(doc.sel)) {
-        setSelection(doc, event, {clearRedo: false});
-        return
-      }
-      selAfter = event;
-    }
-    else { break }
-  }
-
-  // Build up a reverse change object to add to the opposite history
-  // stack (redo when undoing, and vice versa).
-  var antiChanges = [];
-  pushSelectionToHistory(selAfter, dest);
-  dest.push({changes: antiChanges, generation: hist.generation});
-  hist.generation = event.generation || ++hist.maxGeneration;
-
-  var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
-
-  var loop = function ( i ) {
-    var change = event.changes[i];
-    change.origin = type;
-    if (filter && !filterChange(doc, change, false)) {
-      source.length = 0;
-      return {}
-    }
-
-    antiChanges.push(historyChangeFromChange(doc, change));
-
-    var after = i ? computeSelAfterChange(doc, change) : lst(source);
-    makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
-    if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); }
-    var rebased = [];
-
-    // Propagate to the linked documents
-    linkedDocs(doc, function (doc, sharedHist) {
-      if (!sharedHist && indexOf(rebased, doc.history) == -1) {
-        rebaseHist(doc.history, change);
-        rebased.push(doc.history);
-      }
-      makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
-    });
-  };
-
-  for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {
-    var returned = loop( i$1 );
-
-    if ( returned ) return returned.v;
-  }
-}
-
-// Sub-views need their line numbers shifted when text is added
-// above or below them in the parent document.
-function shiftDoc(doc, distance) {
-  if (distance == 0) { return }
-  doc.first += distance;
-  doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(
-    Pos(range.anchor.line + distance, range.anchor.ch),
-    Pos(range.head.line + distance, range.head.ch)
-  ); }), doc.sel.primIndex);
-  if (doc.cm) {
-    regChange(doc.cm, doc.first, doc.first - distance, distance);
-    for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
-      { regLineChange(doc.cm, l, "gutter"); }
-  }
-}
-
-// More lower-level change function, handling only a single document
-// (not linked ones).
-function makeChangeSingleDoc(doc, change, selAfter, spans) {
-  if (doc.cm && !doc.cm.curOp)
-    { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }
-
-  if (change.to.line < doc.first) {
-    shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
-    return
-  }
-  if (change.from.line > doc.lastLine()) { return }
-
-  // Clip the change to the size of this doc
-  if (change.from.line < doc.first) {
-    var shift = change.text.length - 1 - (doc.first - change.from.line);
-    shiftDoc(doc, shift);
-    change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
-              text: [lst(change.text)], origin: change.origin};
-  }
-  var last = doc.lastLine();
-  if (change.to.line > last) {
-    change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
-              text: [change.text[0]], origin: change.origin};
-  }
-
-  change.removed = getBetween(doc, change.from, change.to);
-
-  if (!selAfter) { selAfter = computeSelAfterChange(doc, change); }
-  if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); }
-  else { updateDoc(doc, change, spans); }
-  setSelectionNoUndo(doc, selAfter, sel_dontScroll);
-}
-
-// Handle the interaction of a change to a document with the editor
-// that this document is part of.
-function makeChangeSingleDocInEditor(cm, change, spans) {
-  var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
-
-  var recomputeMaxLength = false, checkWidthStart = from.line;
-  if (!cm.options.lineWrapping) {
-    checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
-    doc.iter(checkWidthStart, to.line + 1, function (line) {
-      if (line == display.maxLine) {
-        recomputeMaxLength = true;
-        return true
-      }
-    });
-  }
-
-  if (doc.sel.contains(change.from, change.to) > -1)
-    { signalCursorActivity(cm); }
-
-  updateDoc(doc, change, spans, estimateHeight(cm));
-
-  if (!cm.options.lineWrapping) {
-    doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
-      var len = lineLength(line);
-      if (len > display.maxLineLength) {
-        display.maxLine = line;
-        display.maxLineLength = len;
-        display.maxLineChanged = true;
-        recomputeMaxLength = false;
-      }
-    });
-    if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; }
-  }
-
-  retreatFrontier(doc, from.line);
-  startWorker(cm, 400);
-
-  var lendiff = change.text.length - (to.line - from.line) - 1;
-  // Remember that these lines changed, for updating the display
-  if (change.full)
-    { regChange(cm); }
-  else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
-    { regLineChange(cm, from.line, "text"); }
-  else
-    { regChange(cm, from.line, to.line + 1, lendiff); }
-
-  var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
-  if (changeHandler || changesHandler) {
-    var obj = {
-      from: from, to: to,
-      text: change.text,
-      removed: change.removed,
-      origin: change.origin
-    };
-    if (changeHandler) { signalLater(cm, "change", cm, obj); }
-    if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); }
-  }
-  cm.display.selForContextMenu = null;
-}
-
-function replaceRange(doc, code, from, to, origin) {
-  if (!to) { to = from; }
-  if (cmp(to, from) < 0) { var assign;
-    (assign = [to, from], from = assign[0], to = assign[1]); }
-  if (typeof code == "string") { code = doc.splitLines(code); }
-  makeChange(doc, {from: from, to: to, text: code, origin: origin});
-}
-
-// Rebasing/resetting history to deal with externally-sourced changes
-
-function rebaseHistSelSingle(pos, from, to, diff) {
-  if (to < pos.line) {
-    pos.line += diff;
-  } else if (from < pos.line) {
-    pos.line = from;
-    pos.ch = 0;
-  }
-}
-
-// Tries to rebase an array of history events given a change in the
-// document. If the change touches the same lines as the event, the
-// event, and everything 'behind' it, is discarded. If the change is
-// before the event, the event's positions are updated. Uses a
-// copy-on-write scheme for the positions, to avoid having to
-// reallocate them all on every rebase, but also avoid problems with
-// shared position objects being unsafely updated.
-function rebaseHistArray(array, from, to, diff) {
-  for (var i = 0; i < array.length; ++i) {
-    var sub = array[i], ok = true;
-    if (sub.ranges) {
-      if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
-      for (var j = 0; j < sub.ranges.length; j++) {
-        rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
-        rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
-      }
-      continue
-    }
-    for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {
-      var cur = sub.changes[j$1];
-      if (to < cur.from.line) {
-        cur.from = Pos(cur.from.line + diff, cur.from.ch);
-        cur.to = Pos(cur.to.line + diff, cur.to.ch);
-      } else if (from <= cur.to.line) {
-        ok = false;
-        break
-      }
-    }
-    if (!ok) {
-      array.splice(0, i + 1);
-      i = 0;
-    }
-  }
-}
-
-function rebaseHist(hist, change) {
-  var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
-  rebaseHistArray(hist.done, from, to, diff);
-  rebaseHistArray(hist.undone, from, to, diff);
-}
-
-// Utility for applying a change to a line by handle or number,
-// returning the number and optionally registering the line as
-// changed.
-function changeLine(doc, handle, changeType, op) {
-  var no = handle, line = handle;
-  if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); }
-  else { no = lineNo(handle); }
-  if (no == null) { return null }
-  if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); }
-  return line
-}
-
-// The document is represented as a BTree consisting of leaves, with
-// chunk of lines in them, and branches, with up to ten leaves or
-// other branch nodes below them. The top node is always a branch
-// node, and is the document object itself (meaning it has
-// additional methods and properties).
-//
-// All nodes have parent links. The tree is used both to go from
-// line numbers to line objects, and to go from objects to numbers.
-// It also indexes by height, and is used to convert between height
-// and line object, and to find the total height of the document.
-//
-// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
-
-function LeafChunk(lines) {
-  var this$1 = this;
-
-  this.lines = lines;
-  this.parent = null;
-  var height = 0;
-  for (var i = 0; i < lines.length; ++i) {
-    lines[i].parent = this$1;
-    height += lines[i].height;
-  }
-  this.height = height;
-}
-
-LeafChunk.prototype = {
-  chunkSize: function() { return this.lines.length },
-
-  // Remove the n lines at offset 'at'.
-  removeInner: function(at, n) {
-    var this$1 = this;
-
-    for (var i = at, e = at + n; i < e; ++i) {
-      var line = this$1.lines[i];
-      this$1.height -= line.height;
-      cleanUpLine(line);
-      signalLater(line, "delete");
-    }
-    this.lines.splice(at, n);
-  },
-
-  // Helper used to collapse a small branch into a single leaf.
-  collapse: function(lines) {
-    lines.push.apply(lines, this.lines);
-  },
-
-  // Insert the given array of lines at offset 'at', count them as
-  // having the given height.
-  insertInner: function(at, lines, height) {
-    var this$1 = this;
-
-    this.height += height;
-    this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
-    for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1; }
-  },
-
-  // Used to iterate over a part of the tree.
-  iterN: function(at, n, op) {
-    var this$1 = this;
-
-    for (var e = at + n; at < e; ++at)
-      { if (op(this$1.lines[at])) { return true } }
-  }
-};
-
-function BranchChunk(children) {
-  var this$1 = this;
-
-  this.children = children;
-  var size = 0, height = 0;
-  for (var i = 0; i < children.length; ++i) {
-    var ch = children[i];
-    size += ch.chunkSize(); height += ch.height;
-    ch.parent = this$1;
-  }
-  this.size = size;
-  this.height = height;
-  this.parent = null;
-}
-
-BranchChunk.prototype = {
-  chunkSize: function() { return this.size },
-
-  removeInner: function(at, n) {
-    var this$1 = this;
-
-    this.size -= n;
-    for (var i = 0; i < this.children.length; ++i) {
-      var child = this$1.children[i], sz = child.chunkSize();
-      if (at < sz) {
-        var rm = Math.min(n, sz - at), oldHeight = child.height;
-        child.removeInner(at, rm);
-        this$1.height -= oldHeight - child.height;
-        if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null; }
-        if ((n -= rm) == 0) { break }
-        at = 0;
-      } else { at -= sz; }
-    }
-    // If the result is smaller than 25 lines, ensure that it is a
-    // single leaf node.
-    if (this.size - n < 25 &&
-        (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
-      var lines = [];
-      this.collapse(lines);
-      this.children = [new LeafChunk(lines)];
-      this.children[0].parent = this;
-    }
-  },
-
-  collapse: function(lines) {
-    var this$1 = this;
-
-    for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines); }
-  },
-
-  insertInner: function(at, lines, height) {
-    var this$1 = this;
-
-    this.size += lines.length;
-    this.height += height;
-    for (var i = 0; i < this.children.length; ++i) {
-      var child = this$1.children[i], sz = child.chunkSize();
-      if (at <= sz) {
-        child.insertInner(at, lines, height);
-        if (child.lines && child.lines.length > 50) {
-          // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
-          // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
-          var remaining = child.lines.length % 25 + 25;
-          for (var pos = remaining; pos < child.lines.length;) {
-            var leaf = new LeafChunk(child.lines.slice(pos, pos += 25));
-            child.height -= leaf.height;
-            this$1.children.splice(++i, 0, leaf);
-            leaf.parent = this$1;
-          }
-          child.lines = child.lines.slice(0, remaining);
-          this$1.maybeSpill();
-        }
-        break
-      }
-      at -= sz;
-    }
-  },
-
-  // When a node has grown, check whether it should be split.
-  maybeSpill: function() {
-    if (this.children.length <= 10) { return }
-    var me = this;
-    do {
-      var spilled = me.children.splice(me.children.length - 5, 5);
-      var sibling = new BranchChunk(spilled);
-      if (!me.parent) { // Become the parent node
-        var copy = new BranchChunk(me.children);
-        copy.parent = me;
-        me.children = [copy, sibling];
-        me = copy;
-     } else {
-        me.size -= sibling.size;
-        me.height -= sibling.height;
-        var myIndex = indexOf(me.parent.children, me);
-        me.parent.children.splice(myIndex + 1, 0, sibling);
-      }
-      sibling.parent = me.parent;
-    } while (me.children.length > 10)
-    me.parent.maybeSpill();
-  },
-
-  iterN: function(at, n, op) {
-    var this$1 = this;
-
-    for (var i = 0; i < this.children.length; ++i) {
-      var child = this$1.children[i], sz = child.chunkSize();
-      if (at < sz) {
-        var used = Math.min(n, sz - at);
-        if (child.iterN(at, used, op)) { return true }
-        if ((n -= used) == 0) { break }
-        at = 0;
-      } else { at -= sz; }
-    }
-  }
-};
-
-// Line widgets are block elements displayed above or below a line.
-
-var LineWidget = function(doc, node, options) {
-  var this$1 = this;
-
-  if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
-    { this$1[opt] = options[opt]; } } }
-  this.doc = doc;
-  this.node = node;
-};
-
-LineWidget.prototype.clear = function () {
-    var this$1 = this;
-
-  var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
-  if (no == null || !ws) { return }
-  for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1); } }
-  if (!ws.length) { line.widgets = null; }
-  var height = widgetHeight(this);
-  updateLineHeight(line, Math.max(0, line.height - height));
-  if (cm) {
-    runInOp(cm, function () {
-      adjustScrollWhenAboveVisible(cm, line, -height);
-      regLineChange(cm, no, "widget");
-    });
-    signalLater(cm, "lineWidgetCleared", cm, this, no);
-  }
-};
-
-LineWidget.prototype.changed = function () {
-    var this$1 = this;
-
-  var oldH = this.height, cm = this.doc.cm, line = this.line;
-  this.height = null;
-  var diff = widgetHeight(this) - oldH;
-  if (!diff) { return }
-  updateLineHeight(line, line.height + diff);
-  if (cm) {
-    runInOp(cm, function () {
-      cm.curOp.forceUpdate = true;
-      adjustScrollWhenAboveVisible(cm, line, diff);
-      signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line));
-    });
-  }
-};
-eventMixin(LineWidget);
-
-function adjustScrollWhenAboveVisible(cm, line, diff) {
-  if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
-    { addToScrollTop(cm, diff); }
-}
-
-function addLineWidget(doc, handle, node, options) {
-  var widget = new LineWidget(doc, node, options);
-  var cm = doc.cm;
-  if (cm && widget.noHScroll) { cm.display.alignWidgets = true; }
-  changeLine(doc, handle, "widget", function (line) {
-    var widgets = line.widgets || (line.widgets = []);
-    if (widget.insertAt == null) { widgets.push(widget); }
-    else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); }
-    widget.line = line;
-    if (cm && !lineIsHidden(doc, line)) {
-      var aboveVisible = heightAtLine(line) < doc.scrollTop;
-      updateLineHeight(line, line.height + widgetHeight(widget));
-      if (aboveVisible) { addToScrollTop(cm, widget.height); }
-      cm.curOp.forceUpdate = true;
-    }
-    return true
-  });
-  signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle));
-  return widget
-}
-
-// TEXTMARKERS
-
-// Created with markText and setBookmark methods. A TextMarker is a
-// handle that can be used to clear or find a marked position in the
-// document. Line objects hold arrays (markedSpans) containing
-// {from, to, marker} object pointing to such marker objects, and
-// indicating that such a marker is present on that line. Multiple
-// lines may point to the same marker when it spans across lines.
-// The spans will have null for their from/to properties when the
-// marker continues beyond the start/end of the line. Markers have
-// links back to the lines they currently touch.
-
-// Collapsed markers have unique ids, in order to be able to order
-// them, which is needed for uniquely determining an outer marker
-// when they overlap (they may nest, but not partially overlap).
-var nextMarkerId = 0;
-
-var TextMarker = function(doc, type) {
-  this.lines = [];
-  this.type = type;
-  this.doc = doc;
-  this.id = ++nextMarkerId;
-};
-
-// Clear the marker.
-TextMarker.prototype.clear = function () {
-    var this$1 = this;
-
-  if (this.explicitlyCleared) { return }
-  var cm = this.doc.cm, withOp = cm && !cm.curOp;
-  if (withOp) { startOperation(cm); }
-  if (hasHandler(this, "clear")) {
-    var found = this.find();
-    if (found) { signalLater(this, "clear", found.from, found.to); }
-  }
-  var min = null, max = null;
-  for (var i = 0; i < this.lines.length; ++i) {
-    var line = this$1.lines[i];
-    var span = getMarkedSpanFor(line.markedSpans, this$1);
-    if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text"); }
-    else if (cm) {
-      if (span.to != null) { max = lineNo(line); }
-      if (span.from != null) { min = lineNo(line); }
-    }
-    line.markedSpans = removeMarkedSpan(line.markedSpans, span);
-    if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
-      { updateLineHeight(line, textHeight(cm.display)); }
-  }
-  if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
-    var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual);
-    if (len > cm.display.maxLineLength) {
-      cm.display.maxLine = visual;
-      cm.display.maxLineLength = len;
-      cm.display.maxLineChanged = true;
-    }
-  } }
-
-  if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); }
-  this.lines.length = 0;
-  this.explicitlyCleared = true;
-  if (this.atomic && this.doc.cantEdit) {
-    this.doc.cantEdit = false;
-    if (cm) { reCheckSelection(cm.doc); }
-  }
-  if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); }
-  if (withOp) { endOperation(cm); }
-  if (this.parent) { this.parent.clear(); }
-};
-
-// Find the position of the marker in the document. Returns a {from,
-// to} object by default. Side can be passed to get a specific side
-// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
-// Pos objects returned contain a line object, rather than a line
-// number (used to prevent looking up the same line twice).
-TextMarker.prototype.find = function (side, lineObj) {
-    var this$1 = this;
-
-  if (side == null && this.type == "bookmark") { side = 1; }
-  var from, to;
-  for (var i = 0; i < this.lines.length; ++i) {
-    var line = this$1.lines[i];
-    var span = getMarkedSpanFor(line.markedSpans, this$1);
-    if (span.from != null) {
-      from = Pos(lineObj ? line : lineNo(line), span.from);
-      if (side == -1) { return from }
-    }
-    if (span.to != null) {
-      to = Pos(lineObj ? line : lineNo(line), span.to);
-      if (side == 1) { return to }
-    }
-  }
-  return from && {from: from, to: to}
-};
-
-// Signals that the marker's widget changed, and surrounding layout
-// should be recomputed.
-TextMarker.prototype.changed = function () {
-    var this$1 = this;
-
-  var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
-  if (!pos || !cm) { return }
-  runInOp(cm, function () {
-    var line = pos.line, lineN = lineNo(pos.line);
-    var view = findViewForLine(cm, lineN);
-    if (view) {
-      clearLineMeasurementCacheFor(view);
-      cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
-    }
-    cm.curOp.updateMaxLine = true;
-    if (!lineIsHidden(widget.doc, line) && widget.height != null) {
-      var oldHeight = widget.height;
-      widget.height = null;
-      var dHeight = widgetHeight(widget) - oldHeight;
-      if (dHeight)
-        { updateLineHeight(line, line.height + dHeight); }
-    }
-    signalLater(cm, "markerChanged", cm, this$1);
-  });
-};
-
-TextMarker.prototype.attachLine = function (line) {
-  if (!this.lines.length && this.doc.cm) {
-    var op = this.doc.cm.curOp;
-    if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
-      { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); }
-  }
-  this.lines.push(line);
-};
-
-TextMarker.prototype.detachLine = function (line) {
-  this.lines.splice(indexOf(this.lines, line), 1);
-  if (!this.lines.length && this.doc.cm) {
-    var op = this.doc.cm.curOp;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
-  }
-};
-eventMixin(TextMarker);
-
-// Create a marker, wire it up to the right lines, and
-function markText(doc, from, to, options, type) {
-  // Shared markers (across linked documents) are handled separately
-  // (markTextShared will call out to this again, once per
-  // document).
-  if (options && options.shared) { return markTextShared(doc, from, to, options, type) }
-  // Ensure we are in an operation.
-  if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }
-
-  var marker = new TextMarker(doc, type), diff = cmp(from, to);
-  if (options) { copyObj(options, marker, false); }
-  // Don't connect empty markers unless clearWhenEmpty is false
-  if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
-    { return marker }
-  if (marker.replacedWith) {
-    // Showing up as a widget implies collapsed (widget replaces text)
-    marker.collapsed = true;
-    marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget");
-    if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); }
-    if (options.insertLeft) { marker.widgetNode.insertLeft = true; }
-  }
-  if (marker.collapsed) {
-    if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
-        from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
-      { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
-    seeCollapsedSpans();
-  }
-
-  if (marker.addToHistory)
-    { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); }
-
-  var curLine = from.line, cm = doc.cm, updateMaxLine;
-  doc.iter(curLine, to.line + 1, function (line) {
-    if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
-      { updateMaxLine = true; }
-    if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); }
-    addMarkedSpan(line, new MarkedSpan(marker,
-                                       curLine == from.line ? from.ch : null,
-                                       curLine == to.line ? to.ch : null));
-    ++curLine;
-  });
-  // lineIsHidden depends on the presence of the spans, so needs a second pass
-  if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {
-    if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); }
-  }); }
-
-  if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); }
-
-  if (marker.readOnly) {
-    seeReadOnlySpans();
-    if (doc.history.done.length || doc.history.undone.length)
-      { doc.clearHistory(); }
-  }
-  if (marker.collapsed) {
-    marker.id = ++nextMarkerId;
-    marker.atomic = true;
-  }
-  if (cm) {
-    // Sync editor state
-    if (updateMaxLine) { cm.curOp.updateMaxLine = true; }
-    if (marker.collapsed)
-      { regChange(cm, from.line, to.line + 1); }
-    else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
-      { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } }
-    if (marker.atomic) { reCheckSelection(cm.doc); }
-    signalLater(cm, "markerAdded", cm, marker);
-  }
-  return marker
-}
-
-// SHARED TEXTMARKERS
-
-// A shared marker spans multiple linked documents. It is
-// implemented as a meta-marker-object controlling multiple normal
-// markers.
-var SharedTextMarker = function(markers, primary) {
-  var this$1 = this;
-
-  this.markers = markers;
-  this.primary = primary;
-  for (var i = 0; i < markers.length; ++i)
-    { markers[i].parent = this$1; }
-};
-
-SharedTextMarker.prototype.clear = function () {
-    var this$1 = this;
-
-  if (this.explicitlyCleared) { return }
-  this.explicitlyCleared = true;
-  for (var i = 0; i < this.markers.length; ++i)
-    { this$1.markers[i].clear(); }
-  signalLater(this, "clear");
-};
-
-SharedTextMarker.prototype.find = function (side, lineObj) {
-  return this.primary.find(side, lineObj)
-};
-eventMixin(SharedTextMarker);
-
-function markTextShared(doc, from, to, options, type) {
-  options = copyObj(options);
-  options.shared = false;
-  var markers = [markText(doc, from, to, options, type)], primary = markers[0];
-  var widget = options.widgetNode;
-  linkedDocs(doc, function (doc) {
-    if (widget) { options.widgetNode = widget.cloneNode(true); }
-    markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
-    for (var i = 0; i < doc.linked.length; ++i)
-      { if (doc.linked[i].isParent) { return } }
-    primary = lst(markers);
-  });
-  return new SharedTextMarker(markers, primary)
-}
-
-function findSharedMarkers(doc) {
-  return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })
-}
-
-function copySharedMarkers(doc, markers) {
-  for (var i = 0; i < markers.length; i++) {
-    var marker = markers[i], pos = marker.find();
-    var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
-    if (cmp(mFrom, mTo)) {
-      var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
-      marker.markers.push(subMark);
-      subMark.parent = marker;
-    }
-  }
-}
-
-function detachSharedMarkers(markers) {
-  var loop = function ( i ) {
-    var marker = markers[i], linked = [marker.primary.doc];
-    linkedDocs(marker.primary.doc, function (d) { return linked.push(d); });
-    for (var j = 0; j < marker.markers.length; j++) {
-      var subMarker = marker.markers[j];
-      if (indexOf(linked, subMarker.doc) == -1) {
-        subMarker.parent = null;
-        marker.markers.splice(j--, 1);
-      }
-    }
-  };
-
-  for (var i = 0; i < markers.length; i++) loop( i );
-}
-
-var nextDocId = 0;
-var Doc = function(text, mode, firstLine, lineSep, direction) {
-  if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }
-  if (firstLine == null) { firstLine = 0; }
-
-  BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
-  this.first = firstLine;
-  this.scrollTop = this.scrollLeft = 0;
-  this.cantEdit = false;
-  this.cleanGeneration = 1;
-  this.modeFrontier = this.highlightFrontier = firstLine;
-  var start = Pos(firstLine, 0);
-  this.sel = simpleSelection(start);
-  this.history = new History(null);
-  this.id = ++nextDocId;
-  this.modeOption = mode;
-  this.lineSep = lineSep;
-  this.direction = (direction == "rtl") ? "rtl" : "ltr";
-  this.extend = false;
-
-  if (typeof text == "string") { text = this.splitLines(text); }
-  updateDoc(this, {from: start, to: start, text: text});
-  setSelection(this, simpleSelection(start), sel_dontScroll);
-};
-
-Doc.prototype = createObj(BranchChunk.prototype, {
-  constructor: Doc,
-  // Iterate over the document. Supports two forms -- with only one
-  // argument, it calls that for each line in the document. With
-  // three, it iterates over the range given by the first two (with
-  // the second being non-inclusive).
-  iter: function(from, to, op) {
-    if (op) { this.iterN(from - this.first, to - from, op); }
-    else { this.iterN(this.first, this.first + this.size, from); }
-  },
-
-  // Non-public interface for adding and removing lines.
-  insert: function(at, lines) {
-    var height = 0;
-    for (var i = 0; i < lines.length; ++i) { height += lines[i].height; }
-    this.insertInner(at - this.first, lines, height);
-  },
-  remove: function(at, n) { this.removeInner(at - this.first, n); },
-
-  // From here, the methods are part of the public interface. Most
-  // are also available from CodeMirror (editor) instances.
-
-  getValue: function(lineSep) {
-    var lines = getLines(this, this.first, this.first + this.size);
-    if (lineSep === false) { return lines }
-    return lines.join(lineSep || this.lineSeparator())
-  },
-  setValue: docMethodOp(function(code) {
-    var top = Pos(this.first, 0), last = this.first + this.size - 1;
-    makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
-                      text: this.splitLines(code), origin: "setValue", full: true}, true);
-    if (this.cm) { scrollToCoords(this.cm, 0, 0); }
-    setSelection(this, simpleSelection(top), sel_dontScroll);
-  }),
-  replaceRange: function(code, from, to, origin) {
-    from = clipPos(this, from);
-    to = to ? clipPos(this, to) : from;
-    replaceRange(this, code, from, to, origin);
-  },
-  getRange: function(from, to, lineSep) {
-    var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
-    if (lineSep === false) { return lines }
-    return lines.join(lineSep || this.lineSeparator())
-  },
-
-  getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},
-
-  getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},
-  getLineNumber: function(line) {return lineNo(line)},
-
-  getLineHandleVisualStart: function(line) {
-    if (typeof line == "number") { line = getLine(this, line); }
-    return visualLine(line)
-  },
-
-  lineCount: function() {return this.size},
-  firstLine: function() {return this.first},
-  lastLine: function() {return this.first + this.size - 1},
-
-  clipPos: function(pos) {return clipPos(this, pos)},
-
-  getCursor: function(start) {
-    var range$$1 = this.sel.primary(), pos;
-    if (start == null || start == "head") { pos = range$$1.head; }
-    else if (start == "anchor") { pos = range$$1.anchor; }
-    else if (start == "end" || start == "to" || start === false) { pos = range$$1.to(); }
-    else { pos = range$$1.from(); }
-    return pos
-  },
-  listSelections: function() { return this.sel.ranges },
-  somethingSelected: function() {return this.sel.somethingSelected()},
-
-  setCursor: docMethodOp(function(line, ch, options) {
-    setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
-  }),
-  setSelection: docMethodOp(function(anchor, head, options) {
-    setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
-  }),
-  extendSelection: docMethodOp(function(head, other, options) {
-    extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
-  }),
-  extendSelections: docMethodOp(function(heads, options) {
-    extendSelections(this, clipPosArray(this, heads), options);
-  }),
-  extendSelectionsBy: docMethodOp(function(f, options) {
-    var heads = map(this.sel.ranges, f);
-    extendSelections(this, clipPosArray(this, heads), options);
-  }),
-  setSelections: docMethodOp(function(ranges, primary, options) {
-    var this$1 = this;
-
-    if (!ranges.length) { return }
-    var out = [];
-    for (var i = 0; i < ranges.length; i++)
-      { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
-                         clipPos(this$1, ranges[i].head)); }
-    if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
-    setSelection(this, normalizeSelection(out, primary), options);
-  }),
-  addSelection: docMethodOp(function(anchor, head, options) {
-    var ranges = this.sel.ranges.slice(0);
-    ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
-    setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
-  }),
-
-  getSelection: function(lineSep) {
-    var this$1 = this;
-
-    var ranges = this.sel.ranges, lines;
-    for (var i = 0; i < ranges.length; i++) {
-      var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
-      lines = lines ? lines.concat(sel) : sel;
-    }
-    if (lineSep === false) { return lines }
-    else { return lines.join(lineSep || this.lineSeparator()) }
-  },
-  getSelections: function(lineSep) {
-    var this$1 = this;
-
-    var parts = [], ranges = this.sel.ranges;
-    for (var i = 0; i < ranges.length; i++) {
-      var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
-      if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()); }
-      parts[i] = sel;
-    }
-    return parts
-  },
-  replaceSelection: function(code, collapse, origin) {
-    var dup = [];
-    for (var i = 0; i < this.sel.ranges.length; i++)
-      { dup[i] = code; }
-    this.replaceSelections(dup, collapse, origin || "+input");
-  },
-  replaceSelections: docMethodOp(function(code, collapse, origin) {
-    var this$1 = this;
-
-    var changes = [], sel = this.sel;
-    for (var i = 0; i < sel.ranges.length; i++) {
-      var range$$1 = sel.ranges[i];
-      changes[i] = {from: range$$1.from(), to: range$$1.to(), text: this$1.splitLines(code[i]), origin: origin};
-    }
-    var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
-    for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
-      { makeChange(this$1, changes[i$1]); }
-    if (newSel) { setSelectionReplaceHistory(this, newSel); }
-    else if (this.cm) { ensureCursorVisible(this.cm); }
-  }),
-  undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
-  redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
-  undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
-  redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
-
-  setExtending: function(val) {this.extend = val;},
-  getExtending: function() {return this.extend},
-
-  historySize: function() {
-    var hist = this.history, done = 0, undone = 0;
-    for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } }
-    for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } }
-    return {undo: done, redo: undone}
-  },
-  clearHistory: function() {this.history = new History(this.history.maxGeneration);},
-
-  markClean: function() {
-    this.cleanGeneration = this.changeGeneration(true);
-  },
-  changeGeneration: function(forceSplit) {
-    if (forceSplit)
-      { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; }
-    return this.history.generation
-  },
-  isClean: function (gen) {
-    return this.history.generation == (gen || this.cleanGeneration)
-  },
-
-  getHistory: function() {
-    return {done: copyHistoryArray(this.history.done),
-            undone: copyHistoryArray(this.history.undone)}
-  },
-  setHistory: function(histData) {
-    var hist = this.history = new History(this.history.maxGeneration);
-    hist.done = copyHistoryArray(histData.done.slice(0), null, true);
-    hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
-  },
-
-  setGutterMarker: docMethodOp(function(line, gutterID, value) {
-    return changeLine(this, line, "gutter", function (line) {
-      var markers = line.gutterMarkers || (line.gutterMarkers = {});
-      markers[gutterID] = value;
-      if (!value && isEmpty(markers)) { line.gutterMarkers = null; }
-      return true
-    })
-  }),
-
-  clearGutter: docMethodOp(function(gutterID) {
-    var this$1 = this;
-
-    this.iter(function (line) {
-      if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
-        changeLine(this$1, line, "gutter", function () {
-          line.gutterMarkers[gutterID] = null;
-          if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; }
-          return true
-        });
-      }
-    });
-  }),
-
-  lineInfo: function(line) {
-    var n;
-    if (typeof line == "number") {
-      if (!isLine(this, line)) { return null }
-      n = line;
-      line = getLine(this, line);
-      if (!line) { return null }
-    } else {
-      n = lineNo(line);
-      if (n == null) { return null }
-    }
-    return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
-            textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
-            widgets: line.widgets}
-  },
-
-  addLineClass: docMethodOp(function(handle, where, cls) {
-    return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
-      var prop = where == "text" ? "textClass"
-               : where == "background" ? "bgClass"
-               : where == "gutter" ? "gutterClass" : "wrapClass";
-      if (!line[prop]) { line[prop] = cls; }
-      else if (classTest(cls).test(line[prop])) { return false }
-      else { line[prop] += " " + cls; }
-      return true
-    })
-  }),
-  removeLineClass: docMethodOp(function(handle, where, cls) {
-    return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
-      var prop = where == "text" ? "textClass"
-               : where == "background" ? "bgClass"
-               : where == "gutter" ? "gutterClass" : "wrapClass";
-      var cur = line[prop];
-      if (!cur) { return false }
-      else if (cls == null) { line[prop] = null; }
-      else {
-        var found = cur.match(classTest(cls));
-        if (!found) { return false }
-        var end = found.index + found[0].length;
-        line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
-      }
-      return true
-    })
-  }),
-
-  addLineWidget: docMethodOp(function(handle, node, options) {
-    return addLineWidget(this, handle, node, options)
-  }),
-  removeLineWidget: function(widget) { widget.clear(); },
-
-  markText: function(from, to, options) {
-    return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range")
-  },
-  setBookmark: function(pos, options) {
-    var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
-                    insertLeft: options && options.insertLeft,
-                    clearWhenEmpty: false, shared: options && options.shared,
-                    handleMouseEvents: options && options.handleMouseEvents};
-    pos = clipPos(this, pos);
-    return markText(this, pos, pos, realOpts, "bookmark")
-  },
-  findMarksAt: function(pos) {
-    pos = clipPos(this, pos);
-    var markers = [], spans = getLine(this, pos.line).markedSpans;
-    if (spans) { for (var i = 0; i < spans.length; ++i) {
-      var span = spans[i];
-      if ((span.from == null || span.from <= pos.ch) &&
-          (span.to == null || span.to >= pos.ch))
-        { markers.push(span.marker.parent || span.marker); }
-    } }
-    return markers
-  },
-  findMarks: function(from, to, filter) {
-    from = clipPos(this, from); to = clipPos(this, to);
-    var found = [], lineNo$$1 = from.line;
-    this.iter(from.line, to.line + 1, function (line) {
-      var spans = line.markedSpans;
-      if (spans) { for (var i = 0; i < spans.length; i++) {
-        var span = spans[i];
-        if (!(span.to != null && lineNo$$1 == from.line && from.ch >= span.to ||
-              span.from == null && lineNo$$1 != from.line ||
-              span.from != null && lineNo$$1 == to.line && span.from >= to.ch) &&
-            (!filter || filter(span.marker)))
-          { found.push(span.marker.parent || span.marker); }
-      } }
-      ++lineNo$$1;
-    });
-    return found
-  },
-  getAllMarks: function() {
-    var markers = [];
-    this.iter(function (line) {
-      var sps = line.markedSpans;
-      if (sps) { for (var i = 0; i < sps.length; ++i)
-        { if (sps[i].from != null) { markers.push(sps[i].marker); } } }
-    });
-    return markers
-  },
-
-  posFromIndex: function(off) {
-    var ch, lineNo$$1 = this.first, sepSize = this.lineSeparator().length;
-    this.iter(function (line) {
-      var sz = line.text.length + sepSize;
-      if (sz > off) { ch = off; return true }
-      off -= sz;
-      ++lineNo$$1;
-    });
-    return clipPos(this, Pos(lineNo$$1, ch))
-  },
-  indexFromPos: function (coords) {
-    coords = clipPos(this, coords);
-    var index = coords.ch;
-    if (coords.line < this.first || coords.ch < 0) { return 0 }
-    var sepSize = this.lineSeparator().length;
-    this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value
-      index += line.text.length + sepSize;
-    });
-    return index
-  },
-
-  copy: function(copyHistory) {
-    var doc = new Doc(getLines(this, this.first, this.first + this.size),
-                      this.modeOption, this.first, this.lineSep, this.direction);
-    doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
-    doc.sel = this.sel;
-    doc.extend = false;
-    if (copyHistory) {
-      doc.history.undoDepth = this.history.undoDepth;
-      doc.setHistory(this.getHistory());
-    }
-    return doc
-  },
-
-  linkedDoc: function(options) {
-    if (!options) { options = {}; }
-    var from = this.first, to = this.first + this.size;
-    if (options.from != null && options.from > from) { from = options.from; }
-    if (options.to != null && options.to < to) { to = options.to; }
-    var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction);
-    if (options.sharedHist) { copy.history = this.history
-    ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
-    copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
-    copySharedMarkers(copy, findSharedMarkers(this));
-    return copy
-  },
-  unlinkDoc: function(other) {
-    var this$1 = this;
-
-    if (other instanceof CodeMirror$1) { other = other.doc; }
-    if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
-      var link = this$1.linked[i];
-      if (link.doc != other) { continue }
-      this$1.linked.splice(i, 1);
-      other.unlinkDoc(this$1);
-      detachSharedMarkers(findSharedMarkers(this$1));
-      break
-    } }
-    // If the histories were shared, split them again
-    if (other.history == this.history) {
-      var splitIds = [other.id];
-      linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true);
-      other.history = new History(null);
-      other.history.done = copyHistoryArray(this.history.done, splitIds);
-      other.history.undone = copyHistoryArray(this.history.undone, splitIds);
-    }
-  },
-  iterLinkedDocs: function(f) {linkedDocs(this, f);},
-
-  getMode: function() {return this.mode},
-  getEditor: function() {return this.cm},
-
-  splitLines: function(str) {
-    if (this.lineSep) { return str.split(this.lineSep) }
-    return splitLinesAuto(str)
-  },
-  lineSeparator: function() { return this.lineSep || "\n" },
-
-  setDirection: docMethodOp(function (dir) {
-    if (dir != "rtl") { dir = "ltr"; }
-    if (dir == this.direction) { return }
-    this.direction = dir;
-    this.iter(function (line) { return line.order = null; });
-    if (this.cm) { directionChanged(this.cm); }
-  })
-});
-
-// Public alias.
-Doc.prototype.eachLine = Doc.prototype.iter;
-
-// Kludge to work around strange IE behavior where it'll sometimes
-// re-fire a series of drag-related events right after the drop (#1551)
-var lastDrop = 0;
-
-function onDrop(e) {
-  var cm = this;
-  clearDragCursor(cm);
-  if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
-    { return }
-  e_preventDefault(e);
-  if (ie) { lastDrop = +new Date; }
-  var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
-  if (!pos || cm.isReadOnly()) { return }
-  // Might be a file drop, in which case we simply extract the text
-  // and insert it.
-  if (files && files.length && window.FileReader && window.File) {
-    var n = files.length, text = Array(n), read = 0;
-    var loadFile = function (file, i) {
-      if (cm.options.allowDropFileTypes &&
-          indexOf(cm.options.allowDropFileTypes, file.type) == -1)
-        { return }
-
-      var reader = new FileReader;
-      reader.onload = operation(cm, function () {
-        var content = reader.result;
-        if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
-        text[i] = content;
-        if (++read == n) {
-          pos = clipPos(cm.doc, pos);
-          var change = {from: pos, to: pos,
-                        text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
-                        origin: "paste"};
-          makeChange(cm.doc, change);
-          setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
-        }
-      });
-      reader.readAsText(file);
-    };
-    for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
-  } else { // Normal drop
-    // Don't do a replace if the drop happened inside of the selected text.
-    if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
-      cm.state.draggingText(e);
-      // Ensure the editor is re-focused
-      setTimeout(function () { return cm.display.input.focus(); }, 20);
-      return
-    }
-    try {
-      var text$1 = e.dataTransfer.getData("Text");
-      if (text$1) {
-        var selected;
-        if (cm.state.draggingText && !cm.state.draggingText.copy)
-          { selected = cm.listSelections(); }
-        setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
-        if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)
-          { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } }
-        cm.replaceSelection(text$1, "around", "paste");
-        cm.display.input.focus();
-      }
-    }
-    catch(e){}
-  }
-}
-
-function onDragStart(cm, e) {
-  if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
-  if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }
-
-  e.dataTransfer.setData("Text", cm.getSelection());
-  e.dataTransfer.effectAllowed = "copyMove";
-
-  // Use dummy image instead of default browsers image.
-  // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
-  if (e.dataTransfer.setDragImage && !safari) {
-    var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
-    img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
-    if (presto) {
-      img.width = img.height = 1;
-      cm.display.wrapper.appendChild(img);
-      // Force a relayout, or Opera won't use our image for some obscure reason
-      img._top = img.offsetTop;
-    }
-    e.dataTransfer.setDragImage(img, 0, 0);
-    if (presto) { img.parentNode.removeChild(img); }
-  }
-}
-
-function onDragOver(cm, e) {
-  var pos = posFromMouse(cm, e);
-  if (!pos) { return }
-  var frag = document.createDocumentFragment();
-  drawSelectionCursor(cm, pos, frag);
-  if (!cm.display.dragCursor) {
-    cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
-    cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
-  }
-  removeChildrenAndAdd(cm.display.dragCursor, frag);
-}
-
-function clearDragCursor(cm) {
-  if (cm.display.dragCursor) {
-    cm.display.lineSpace.removeChild(cm.display.dragCursor);
-    cm.display.dragCursor = null;
-  }
-}
-
-// These must be handled carefully, because naively registering a
-// handler for each editor will cause the editors to never be
-// garbage collected.
-
-function forEachCodeMirror(f) {
-  if (!document.getElementsByClassName) { return }
-  var byClass = document.getElementsByClassName("CodeMirror");
-  for (var i = 0; i < byClass.length; i++) {
-    var cm = byClass[i].CodeMirror;
-    if (cm) { f(cm); }
-  }
-}
-
-var globalsRegistered = false;
-function ensureGlobalHandlers() {
-  if (globalsRegistered) { return }
-  registerGlobalHandlers();
-  globalsRegistered = true;
-}
-function registerGlobalHandlers() {
-  // When the window resizes, we need to refresh active editors.
-  var resizeTimer;
-  on(window, "resize", function () {
-    if (resizeTimer == null) { resizeTimer = setTimeout(function () {
-      resizeTimer = null;
-      forEachCodeMirror(onResize);
-    }, 100); }
-  });
-  // When the window loses focus, we want to show the editor as blurred
-  on(window, "blur", function () { return forEachCodeMirror(onBlur); });
-}
-// Called when the window resizes
-function onResize(cm) {
-  var d = cm.display;
-  if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
-    { return }
-  // Might be a text scaling operation, clear size caches.
-  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
-  d.scrollbarsClipped = false;
-  cm.setSize();
-}
-
-var keyNames = {
-  3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
-  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
-  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
-  46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
-  106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
-  173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
-  221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
-  63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
-};
-
-// Number keys
-for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); }
-// Alphabetic keys
-for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); }
-// Function keys
-for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; }
-
-var keyMap = {};
-
-keyMap.basic = {
-  "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
-  "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
-  "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
-  "Tab": "defaultTab", "Shift-Tab": "indentAuto",
-  "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
-  "Esc": "singleSelection"
-};
-// Note that the save and find-related commands aren't defined by
-// default. User code or addons can define them. Unknown commands
-// are simply ignored.
-keyMap.pcDefault = {
-  "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
-  "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
-  "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
-  "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
-  "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
-  "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
-  "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
-  fallthrough: "basic"
-};
-// Very basic readline/emacs-style bindings, which are standard on Mac.
-keyMap.emacsy = {
-  "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
-  "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
-  "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
-  "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
-  "Ctrl-O": "openLine"
-};
-keyMap.macDefault = {
-  "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
-  "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
-  "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
-  "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
-  "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
-  "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
-  "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
-  fallthrough: ["basic", "emacsy"]
-};
-keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
-
-// KEYMAP DISPATCH
-
-function normalizeKeyName(name) {
-  var parts = name.split(/-(?!$)/);
-  name = parts[parts.length - 1];
-  var alt, ctrl, shift, cmd;
-  for (var i = 0; i < parts.length - 1; i++) {
-    var mod = parts[i];
-    if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; }
-    else if (/^a(lt)?$/i.test(mod)) { alt = true; }
-    else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; }
-    else if (/^s(hift)?$/i.test(mod)) { shift = true; }
-    else { throw new Error("Unrecognized modifier name: " + mod) }
-  }
-  if (alt) { name = "Alt-" + name; }
-  if (ctrl) { name = "Ctrl-" + name; }
-  if (cmd) { name = "Cmd-" + name; }
-  if (shift) { name = "Shift-" + name; }
-  return name
-}
-
-// This is a kludge to keep keymaps mostly working as raw objects
-// (backwards compatibility) while at the same time support features
-// like normalization and multi-stroke key bindings. It compiles a
-// new normalized keymap, and then updates the old object to reflect
-// this.
-function normalizeKeyMap(keymap) {
-  var copy = {};
-  for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {
-    var value = keymap[keyname];
-    if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }
-    if (value == "...") { delete keymap[keyname]; continue }
-
-    var keys = map(keyname.split(" "), normalizeKeyName);
-    for (var i = 0; i < keys.length; i++) {
-      var val = (void 0), name = (void 0);
-      if (i == keys.length - 1) {
-        name = keys.join(" ");
-        val = value;
-      } else {
-        name = keys.slice(0, i + 1).join(" ");
-        val = "...";
-      }
-      var prev = copy[name];
-      if (!prev) { copy[name] = val; }
-      else if (prev != val) { throw new Error("Inconsistent bindings for " + name) }
-    }
-    delete keymap[keyname];
-  } }
-  for (var prop in copy) { keymap[prop] = copy[prop]; }
-  return keymap
-}
-
-function lookupKey(key, map$$1, handle, context) {
-  map$$1 = getKeyMap(map$$1);
-  var found = map$$1.call ? map$$1.call(key, context) : map$$1[key];
-  if (found === false) { return "nothing" }
-  if (found === "...") { return "multi" }
-  if (found != null && handle(found)) { return "handled" }
-
-  if (map$$1.fallthrough) {
-    if (Object.prototype.toString.call(map$$1.fallthrough) != "[object Array]")
-      { return lookupKey(key, map$$1.fallthrough, handle, context) }
-    for (var i = 0; i < map$$1.fallthrough.length; i++) {
-      var result = lookupKey(key, map$$1.fallthrough[i], handle, context);
-      if (result) { return result }
-    }
-  }
-}
-
-// Modifier key presses don't count as 'real' key presses for the
-// purpose of keymap fallthrough.
-function isModifierKey(value) {
-  var name = typeof value == "string" ? value : keyNames[value.keyCode];
-  return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
-}
-
-function addModifierNames(name, event, noShift) {
-  var base = name;
-  if (event.altKey && base != "Alt") { name = "Alt-" + name; }
-  if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; }
-  if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name; }
-  if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; }
-  return name
-}
-
-// Look up the name of a key as indicated by an event object.
-function keyName(event, noShift) {
-  if (presto && event.keyCode == 34 && event["char"]) { return false }
-  var name = keyNames[event.keyCode];
-  if (name == null || event.altGraphKey) { return false }
-  return addModifierNames(name, event, noShift)
-}
-
-function getKeyMap(val) {
-  return typeof val == "string" ? keyMap[val] : val
-}
-
-// Helper for deleting text near the selection(s), used to implement
-// backspace, delete, and similar functionality.
-function deleteNearSelection(cm, compute) {
-  var ranges = cm.doc.sel.ranges, kill = [];
-  // Build up a set of ranges to kill first, merging overlapping
-  // ranges.
-  for (var i = 0; i < ranges.length; i++) {
-    var toKill = compute(ranges[i]);
-    while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
-      var replaced = kill.pop();
-      if (cmp(replaced.from, toKill.from) < 0) {
-        toKill.from = replaced.from;
-        break
-      }
-    }
-    kill.push(toKill);
-  }
-  // Next, remove those actual ranges.
-  runInOp(cm, function () {
-    for (var i = kill.length - 1; i >= 0; i--)
-      { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); }
-    ensureCursorVisible(cm);
-  });
-}
-
-function moveCharLogically(line, ch, dir) {
-  var target = skipExtendingChars(line.text, ch + dir, dir);
-  return target < 0 || target > line.text.length ? null : target
-}
-
-function moveLogically(line, start, dir) {
-  var ch = moveCharLogically(line, start.ch, dir);
-  return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
-}
-
-function endOfLine(visually, cm, lineObj, lineNo, dir) {
-  if (visually) {
-    var order = getOrder(lineObj, cm.doc.direction);
-    if (order) {
-      var part = dir < 0 ? lst(order) : order[0];
-      var moveInStorageOrder = (dir < 0) == (part.level == 1);
-      var sticky = moveInStorageOrder ? "after" : "before";
-      var ch;
-      // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
-      // it could be that the last bidi part is not on the last visual line,
-      // since visual lines contain content order-consecutive chunks.
-      // Thus, in rtl, we are looking for the first (content-order) character
-      // in the rtl chunk that is on the last line (that is, the same line
-      // as the last (content-order) character).
-      if (part.level > 0 || cm.doc.direction == "rtl") {
-        var prep = prepareMeasureForLine(cm, lineObj);
-        ch = dir < 0 ? lineObj.text.length - 1 : 0;
-        var targetTop = measureCharPrepared(cm, prep, ch).top;
-        ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch);
-        if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); }
-      } else { ch = dir < 0 ? part.to : part.from; }
-      return new Pos(lineNo, ch, sticky)
-    }
-  }
-  return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
-}
-
-function moveVisually(cm, line, start, dir) {
-  var bidi = getOrder(line, cm.doc.direction);
-  if (!bidi) { return moveLogically(line, start, dir) }
-  if (start.ch >= line.text.length) {
-    start.ch = line.text.length;
-    start.sticky = "before";
-  } else if (start.ch <= 0) {
-    start.ch = 0;
-    start.sticky = "after";
-  }
-  var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos];
-  if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
-    // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
-    // nothing interesting happens.
-    return moveLogically(line, start, dir)
-  }
-
-  var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); };
-  var prep;
-  var getWrappedLineExtent = function (ch) {
-    if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
-    prep = prep || prepareMeasureForLine(cm, line);
-    return wrappedLineExtentChar(cm, line, prep, ch)
-  };
-  var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch);
-
-  if (cm.doc.direction == "rtl" || part.level == 1) {
-    var moveInStorageOrder = (part.level == 1) == (dir < 0);
-    var ch = mv(start, moveInStorageOrder ? 1 : -1);
-    if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
-      // Case 2: We move within an rtl part or in an rtl editor on the same visual line
-      var sticky = moveInStorageOrder ? "before" : "after";
-      return new Pos(start.line, ch, sticky)
-    }
-  }
-
-  // Case 3: Could not move within this bidi part in this visual line, so leave
-  // the current bidi part
-
-  var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
-    var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
-      ? new Pos(start.line, mv(ch, 1), "before")
-      : new Pos(start.line, ch, "after"); };
-
-    for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
-      var part = bidi[partPos];
-      var moveInStorageOrder = (dir > 0) == (part.level != 1);
-      var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1);
-      if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
-      ch = moveInStorageOrder ? part.from : mv(part.to, -1);
-      if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
-    }
-  };
-
-  // Case 3a: Look for other bidi parts on the same visual line
-  var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent);
-  if (res) { return res }
-
-  // Case 3b: Look for other bidi parts on the next visual line
-  var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1);
-  if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
-    res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh));
-    if (res) { return res }
-  }
-
-  // Case 4: Nowhere to move
-  return null
-}
-
-// Commands are parameter-less actions that can be performed on an
-// editor, mostly used for keybindings.
-var commands = {
-  selectAll: selectAll,
-  singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); },
-  killLine: function (cm) { return deleteNearSelection(cm, function (range) {
-    if (range.empty()) {
-      var len = getLine(cm.doc, range.head.line).text.length;
-      if (range.head.ch == len && range.head.line < cm.lastLine())
-        { return {from: range.head, to: Pos(range.head.line + 1, 0)} }
-      else
-        { return {from: range.head, to: Pos(range.head.line, len)} }
-    } else {
-      return {from: range.from(), to: range.to()}
-    }
-  }); },
-  deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({
-    from: Pos(range.from().line, 0),
-    to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
-  }); }); },
-  delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({
-    from: Pos(range.from().line, 0), to: range.from()
-  }); }); },
-  delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
-    var top = cm.charCoords(range.head, "div").top + 5;
-    var leftPos = cm.coordsChar({left: 0, top: top}, "div");
-    return {from: leftPos, to: range.from()}
-  }); },
-  delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {
-    var top = cm.charCoords(range.head, "div").top + 5;
-    var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
-    return {from: range.from(), to: rightPos }
-  }); },
-  undo: function (cm) { return cm.undo(); },
-  redo: function (cm) { return cm.redo(); },
-  undoSelection: function (cm) { return cm.undoSelection(); },
-  redoSelection: function (cm) { return cm.redoSelection(); },
-  goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },
-  goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },
-  goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },
-    {origin: "+move", bias: 1}
-  ); },
-  goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },
-    {origin: "+move", bias: 1}
-  ); },
-  goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },
-    {origin: "+move", bias: -1}
-  ); },
-  goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
-    var top = cm.cursorCoords(range.head, "div").top + 5;
-    return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
-  }, sel_move); },
-  goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
-    var top = cm.cursorCoords(range.head, "div").top + 5;
-    return cm.coordsChar({left: 0, top: top}, "div")
-  }, sel_move); },
-  goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
-    var top = cm.cursorCoords(range.head, "div").top + 5;
-    var pos = cm.coordsChar({left: 0, top: top}, "div");
-    if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
-    return pos
-  }, sel_move); },
-  goLineUp: function (cm) { return cm.moveV(-1, "line"); },
-  goLineDown: function (cm) { return cm.moveV(1, "line"); },
-  goPageUp: function (cm) { return cm.moveV(-1, "page"); },
-  goPageDown: function (cm) { return cm.moveV(1, "page"); },
-  goCharLeft: function (cm) { return cm.moveH(-1, "char"); },
-  goCharRight: function (cm) { return cm.moveH(1, "char"); },
-  goColumnLeft: function (cm) { return cm.moveH(-1, "column"); },
-  goColumnRight: function (cm) { return cm.moveH(1, "column"); },
-  goWordLeft: function (cm) { return cm.moveH(-1, "word"); },
-  goGroupRight: function (cm) { return cm.moveH(1, "group"); },
-  goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
-  goWordRight: function (cm) { return cm.moveH(1, "word"); },
-  delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
-  delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
-  delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
-  delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
-  delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); },
-  delGroupAfter: function (cm) { return cm.deleteH(1, "group"); },
-  indentAuto: function (cm) { return cm.indentSelection("smart"); },
-  indentMore: function (cm) { return cm.indentSelection("add"); },
-  indentLess: function (cm) { return cm.indentSelection("subtract"); },
-  insertTab: function (cm) { return cm.replaceSelection("\t"); },
-  insertSoftTab: function (cm) {
-    var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
-    for (var i = 0; i < ranges.length; i++) {
-      var pos = ranges[i].from();
-      var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
-      spaces.push(spaceStr(tabSize - col % tabSize));
-    }
-    cm.replaceSelections(spaces);
-  },
-  defaultTab: function (cm) {
-    if (cm.somethingSelected()) { cm.indentSelection("add"); }
-    else { cm.execCommand("insertTab"); }
-  },
-  // Swap the two chars left and right of each selection's head.
-  // Move cursor behind the two swapped characters afterwards.
-  //
-  // Doesn't consider line feeds a character.
-  // Doesn't scan more than one line above to find a character.
-  // Doesn't do anything on an empty line.
-  // Doesn't do anything with non-empty selections.
-  transposeChars: function (cm) { return runInOp(cm, function () {
-    var ranges = cm.listSelections(), newSel = [];
-    for (var i = 0; i < ranges.length; i++) {
-      if (!ranges[i].empty()) { continue }
-      var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
-      if (line) {
-        if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); }
-        if (cur.ch > 0) {
-          cur = new Pos(cur.line, cur.ch + 1);
-          cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
-                          Pos(cur.line, cur.ch - 2), cur, "+transpose");
-        } else if (cur.line > cm.doc.first) {
-          var prev = getLine(cm.doc, cur.line - 1).text;
-          if (prev) {
-            cur = new Pos(cur.line, 1);
-            cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
-                            prev.charAt(prev.length - 1),
-                            Pos(cur.line - 1, prev.length - 1), cur, "+transpose");
-          }
-        }
-      }
-      newSel.push(new Range(cur, cur));
-    }
-    cm.setSelections(newSel);
-  }); },
-  newlineAndIndent: function (cm) { return runInOp(cm, function () {
-    var sels = cm.listSelections();
-    for (var i = sels.length - 1; i >= 0; i--)
-      { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); }
-    sels = cm.listSelections();
-    for (var i$1 = 0; i$1 < sels.length; i$1++)
-      { cm.indentLine(sels[i$1].from().line, null, true); }
-    ensureCursorVisible(cm);
-  }); },
-  openLine: function (cm) { return cm.replaceSelection("\n", "start"); },
-  toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }
-};
-
-
-function lineStart(cm, lineN) {
-  var line = getLine(cm.doc, lineN);
-  var visual = visualLine(line);
-  if (visual != line) { lineN = lineNo(visual); }
-  return endOfLine(true, cm, visual, lineN, 1)
-}
-function lineEnd(cm, lineN) {
-  var line = getLine(cm.doc, lineN);
-  var visual = visualLineEnd(line);
-  if (visual != line) { lineN = lineNo(visual); }
-  return endOfLine(true, cm, line, lineN, -1)
-}
-function lineStartSmart(cm, pos) {
-  var start = lineStart(cm, pos.line);
-  var line = getLine(cm.doc, start.line);
-  var order = getOrder(line, cm.doc.direction);
-  if (!order || order[0].level == 0) {
-    var firstNonWS = Math.max(0, line.text.search(/\S/));
-    var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
-    return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
-  }
-  return start
-}
-
-// Run a handler that was bound to a key.
-function doHandleBinding(cm, bound, dropShift) {
-  if (typeof bound == "string") {
-    bound = commands[bound];
-    if (!bound) { return false }
-  }
-  // Ensure previous input has been read, so that the handler sees a
-  // consistent view of the document
-  cm.display.input.ensurePolled();
-  var prevShift = cm.display.shift, done = false;
-  try {
-    if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
-    if (dropShift) { cm.display.shift = false; }
-    done = bound(cm) != Pass;
-  } finally {
-    cm.display.shift = prevShift;
-    cm.state.suppressEdits = false;
-  }
-  return done
-}
-
-function lookupKeyForEditor(cm, name, handle) {
-  for (var i = 0; i < cm.state.keyMaps.length; i++) {
-    var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
-    if (result) { return result }
-  }
-  return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
-    || lookupKey(name, cm.options.keyMap, handle, cm)
-}
-
-// Note that, despite the name, this function is also used to check
-// for bound mouse clicks.
-
-var stopSeq = new Delayed;
-
-function dispatchKey(cm, name, e, handle) {
-  var seq = cm.state.keySeq;
-  if (seq) {
-    if (isModifierKey(name)) { return "handled" }
-    if (/\'$/.test(name))
-      { cm.state.keySeq = null; }
-    else
-      { stopSeq.set(50, function () {
-        if (cm.state.keySeq == seq) {
-          cm.state.keySeq = null;
-          cm.display.input.reset();
-        }
-      }); }
-    if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true }
-  }
-  return dispatchKeyInner(cm, name, e, handle)
-}
-
-function dispatchKeyInner(cm, name, e, handle) {
-  var result = lookupKeyForEditor(cm, name, handle);
-
-  if (result == "multi")
-    { cm.state.keySeq = name; }
-  if (result == "handled")
-    { signalLater(cm, "keyHandled", cm, name, e); }
-
-  if (result == "handled" || result == "multi") {
-    e_preventDefault(e);
-    restartBlink(cm);
-  }
-
-  return !!result
-}
-
-// Handle a key from the keydown event.
-function handleKeyBinding(cm, e) {
-  var name = keyName(e, true);
-  if (!name) { return false }
-
-  if (e.shiftKey && !cm.state.keySeq) {
-    // First try to resolve full name (including 'Shift-'). Failing
-    // that, see if there is a cursor-motion command (starting with
-    // 'go') bound to the keyname without 'Shift-'.
-    return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); })
-        || dispatchKey(cm, name, e, function (b) {
-             if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
-               { return doHandleBinding(cm, b) }
-           })
-  } else {
-    return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); })
-  }
-}
-
-// Handle a key from the keypress event
-function handleCharBinding(cm, e, ch) {
-  return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); })
-}
-
-var lastStoppedKey = null;
-function onKeyDown(e) {
-  var cm = this;
-  cm.curOp.focus = activeElt();
-  if (signalDOMEvent(cm, e)) { return }
-  // IE does strange things with escape.
-  if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; }
-  var code = e.keyCode;
-  cm.display.shift = code == 16 || e.shiftKey;
-  var handled = handleKeyBinding(cm, e);
-  if (presto) {
-    lastStoppedKey = handled ? code : null;
-    // Opera has no cut event... we try to at least catch the key combo
-    if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
-      { cm.replaceSelection("", null, "cut"); }
-  }
-
-  // Turn mouse into crosshair when Alt is held on Mac.
-  if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
-    { showCrossHair(cm); }
-}
-
-function showCrossHair(cm) {
-  var lineDiv = cm.display.lineDiv;
-  addClass(lineDiv, "CodeMirror-crosshair");
-
-  function up(e) {
-    if (e.keyCode == 18 || !e.altKey) {
-      rmClass(lineDiv, "CodeMirror-crosshair");
-      off(document, "keyup", up);
-      off(document, "mouseover", up);
-    }
-  }
-  on(document, "keyup", up);
-  on(document, "mouseover", up);
-}
-
-function onKeyUp(e) {
-  if (e.keyCode == 16) { this.doc.sel.shift = false; }
-  signalDOMEvent(this, e);
-}
-
-function onKeyPress(e) {
-  var cm = this;
-  if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
-  var keyCode = e.keyCode, charCode = e.charCode;
-  if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
-  if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return }
-  var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
-  // Some browsers fire keypress events for backspace
-  if (ch == "\x08") { return }
-  if (handleCharBinding(cm, e, ch)) { return }
-  cm.display.input.onKeyPress(e);
-}
-
-var DOUBLECLICK_DELAY = 400;
-
-var PastClick = function(time, pos, button) {
-  this.time = time;
-  this.pos = pos;
-  this.button = button;
-};
-
-PastClick.prototype.compare = function (time, pos, button) {
-  return this.time + DOUBLECLICK_DELAY > time &&
-    cmp(pos, this.pos) == 0 && button == this.button
-};
-
-var lastClick;
-var lastDoubleClick;
-function clickRepeat(pos, button) {
-  var now = +new Date;
-  if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {
-    lastClick = lastDoubleClick = null;
-    return "triple"
-  } else if (lastClick && lastClick.compare(now, pos, button)) {
-    lastDoubleClick = new PastClick(now, pos, button);
-    lastClick = null;
-    return "double"
-  } else {
-    lastClick = new PastClick(now, pos, button);
-    lastDoubleClick = null;
-    return "single"
-  }
-}
-
-// A mouse down can be a single click, double click, triple click,
-// start of selection drag, start of text drag, new cursor
-// (ctrl-click), rectangle drag (alt-drag), or xwin
-// middle-click-paste. Or it might be a click on something we should
-// not interfere with, such as a scrollbar or widget.
-function onMouseDown(e) {
-  var cm = this, display = cm.display;
-  if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return }
-  display.input.ensurePolled();
-  display.shift = e.shiftKey;
-
-  if (eventInWidget(display, e)) {
-    if (!webkit) {
-      // Briefly turn off draggability, to allow widgets to do
-      // normal dragging things.
-      display.scroller.draggable = false;
-      setTimeout(function () { return display.scroller.draggable = true; }, 100);
-    }
-    return
-  }
-  if (clickInGutter(cm, e)) { return }
-  var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single";
-  window.focus();
-
-  // #3261: make sure, that we're not starting a second selection
-  if (button == 1 && cm.state.selectingText)
-    { cm.state.selectingText(e); }
-
-  if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return }
-
-  if (button == 1) {
-    if (pos) { leftButtonDown(cm, pos, repeat, e); }
-    else if (e_target(e) == display.scroller) { e_preventDefault(e); }
-  } else if (button == 2) {
-    if (pos) { extendSelection(cm.doc, pos); }
-    setTimeout(function () { return display.input.focus(); }, 20);
-  } else if (button == 3) {
-    if (captureRightClick) { onContextMenu(cm, e); }
-    else { delayBlurEvent(cm); }
-  }
-}
-
-function handleMappedButton(cm, button, pos, repeat, event) {
-  var name = "Click";
-  if (repeat == "double") { name = "Double" + name; }
-  else if (repeat == "triple") { name = "Triple" + name; }
-  name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name;
-
-  return dispatchKey(cm,  addModifierNames(name, event), event, function (bound) {
-    if (typeof bound == "string") { bound = commands[bound]; }
-    if (!bound) { return false }
-    var done = false;
-    try {
-      if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
-      done = bound(cm, pos) != Pass;
-    } finally {
-      cm.state.suppressEdits = false;
-    }
-    return done
-  })
-}
-
-function configureMouse(cm, repeat, event) {
-  var option = cm.getOption("configureMouse");
-  var value = option ? option(cm, repeat, event) : {};
-  if (value.unit == null) {
-    var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey;
-    value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line";
-  }
-  if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey; }
-  if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey; }
-  if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey); }
-  return value
-}
-
-function leftButtonDown(cm, pos, repeat, event) {
-  if (ie) { setTimeout(bind(ensureFocus, cm), 0); }
-  else { cm.curOp.focus = activeElt(); }
-
-  var behavior = configureMouse(cm, repeat, event);
-
-  var sel = cm.doc.sel, contained;
-  if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
-      repeat == "single" && (contained = sel.contains(pos)) > -1 &&
-      (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) &&
-      (cmp(contained.to(), pos) > 0 || pos.xRel < 0))
-    { leftButtonStartDrag(cm, event, pos, behavior); }
-  else
-    { leftButtonSelect(cm, event, pos, behavior); }
-}
-
-// Start a text drag. When it ends, see if any dragging actually
-// happen, and treat as a click if it didn't.
-function leftButtonStartDrag(cm, event, pos, behavior) {
-  var display = cm.display, moved = false;
-  var dragEnd = operation(cm, function (e) {
-    if (webkit) { display.scroller.draggable = false; }
-    cm.state.draggingText = false;
-    off(document, "mouseup", dragEnd);
-    off(document, "mousemove", mouseMove);
-    off(display.scroller, "dragstart", dragStart);
-    off(display.scroller, "drop", dragEnd);
-    if (!moved) {
-      e_preventDefault(e);
-      if (!behavior.addNew)
-        { extendSelection(cm.doc, pos, null, null, behavior.extend); }
-      // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
-      if (webkit || ie && ie_version == 9)
-        { setTimeout(function () {document.body.focus(); display.input.focus();}, 20); }
-      else
-        { display.input.focus(); }
-    }
-  });
-  var mouseMove = function(e2) {
-    moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10;
-  };
-  var dragStart = function () { return moved = true; };
-  // Let the drag handler handle this.
-  if (webkit) { display.scroller.draggable = true; }
-  cm.state.draggingText = dragEnd;
-  dragEnd.copy = !behavior.moveOnDrag;
-  // IE's approach to draggable
-  if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
-  on(document, "mouseup", dragEnd);
-  on(document, "mousemove", mouseMove);
-  on(display.scroller, "dragstart", dragStart);
-  on(display.scroller, "drop", dragEnd);
-
-  delayBlurEvent(cm);
-  setTimeout(function () { return display.input.focus(); }, 20);
-}
-
-function rangeForUnit(cm, pos, unit) {
-  if (unit == "char") { return new Range(pos, pos) }
-  if (unit == "word") { return cm.findWordAt(pos) }
-  if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }
-  var result = unit(cm, pos);
-  return new Range(result.from, result.to)
-}
-
-// Normal selection, as opposed to text dragging.
-function leftButtonSelect(cm, event, start, behavior) {
-  var display = cm.display, doc = cm.doc;
-  e_preventDefault(event);
-
-  var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
-  if (behavior.addNew && !behavior.extend) {
-    ourIndex = doc.sel.contains(start);
-    if (ourIndex > -1)
-      { ourRange = ranges[ourIndex]; }
-    else
-      { ourRange = new Range(start, start); }
-  } else {
-    ourRange = doc.sel.primary();
-    ourIndex = doc.sel.primIndex;
-  }
-
-  if (behavior.unit == "rectangle") {
-    if (!behavior.addNew) { ourRange = new Range(start, start); }
-    start = posFromMouse(cm, event, true, true);
-    ourIndex = -1;
-  } else {
-    var range$$1 = rangeForUnit(cm, start, behavior.unit);
-    if (behavior.extend)
-      { ourRange = extendRange(ourRange, range$$1.anchor, range$$1.head, behavior.extend); }
-    else
-      { ourRange = range$$1; }
-  }
-
-  if (!behavior.addNew) {
-    ourIndex = 0;
-    setSelection(doc, new Selection([ourRange], 0), sel_mouse);
-    startSel = doc.sel;
-  } else if (ourIndex == -1) {
-    ourIndex = ranges.length;
-    setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
-                 {scroll: false, origin: "*mouse"});
-  } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) {
-    setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
-                 {scroll: false, origin: "*mouse"});
-    startSel = doc.sel;
-  } else {
-    replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
-  }
-
-  var lastPos = start;
-  function extendTo(pos) {
-    if (cmp(lastPos, pos) == 0) { return }
-    lastPos = pos;
-
-    if (behavior.unit == "rectangle") {
-      var ranges = [], tabSize = cm.options.tabSize;
-      var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
-      var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
-      var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
-      for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
-           line <= end; line++) {
-        var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
-        if (left == right)
-          { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); }
-        else if (text.length > leftPos)
-          { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); }
-      }
-      if (!ranges.length) { ranges.push(new Range(start, start)); }
-      setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
-                   {origin: "*mouse", scroll: false});
-      cm.scrollIntoView(pos);
-    } else {
-      var oldRange = ourRange;
-      var range$$1 = rangeForUnit(cm, pos, behavior.unit);
-      var anchor = oldRange.anchor, head;
-      if (cmp(range$$1.anchor, anchor) > 0) {
-        head = range$$1.head;
-        anchor = minPos(oldRange.from(), range$$1.anchor);
-      } else {
-        head = range$$1.anchor;
-        anchor = maxPos(oldRange.to(), range$$1.head);
-      }
-      var ranges$1 = startSel.ranges.slice(0);
-      ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head));
-      setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse);
-    }
-  }
-
-  var editorSize = display.wrapper.getBoundingClientRect();
-  // Used to ensure timeout re-tries don't fire when another extend
-  // happened in the meantime (clearTimeout isn't reliable -- at
-  // least on Chrome, the timeouts still happen even when cleared,
-  // if the clear happens after their scheduled firing time).
-  var counter = 0;
-
-  function extend(e) {
-    var curCount = ++counter;
-    var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle");
-    if (!cur) { return }
-    if (cmp(cur, lastPos) != 0) {
-      cm.curOp.focus = activeElt();
-      extendTo(cur);
-      var visible = visibleLines(display, doc);
-      if (cur.line >= visible.to || cur.line < visible.from)
-        { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); }
-    } else {
-      var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
-      if (outside) { setTimeout(operation(cm, function () {
-        if (counter != curCount) { return }
-        display.scroller.scrollTop += outside;
-        extend(e);
-      }), 50); }
-    }
-  }
-
-  function done(e) {
-    cm.state.selectingText = false;
-    counter = Infinity;
-    e_preventDefault(e);
-    display.input.focus();
-    off(document, "mousemove", move);
-    off(document, "mouseup", up);
-    doc.history.lastSelOrigin = null;
-  }
-
-  var move = operation(cm, function (e) {
-    if (!e_button(e)) { done(e); }
-    else { extend(e); }
-  });
-  var up = operation(cm, done);
-  cm.state.selectingText = up;
-  on(document, "mousemove", move);
-  on(document, "mouseup", up);
-}
-
-// Used when mouse-selecting to adjust the anchor to the proper side
-// of a bidi jump depending on the visual position of the head.
-function bidiSimplify(cm, range$$1) {
-  var anchor = range$$1.anchor;
-  var head = range$$1.head;
-  var anchorLine = getLine(cm.doc, anchor.line);
-  if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range$$1 }
-  var order = getOrder(anchorLine);
-  if (!order) { return range$$1 }
-  var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index];
-  if (part.from != anchor.ch && part.to != anchor.ch) { return range$$1 }
-  var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1);
-  if (boundary == 0 || boundary == order.length) { return range$$1 }
-
-  // Compute the relative visual position of the head compared to the
-  // anchor (<0 is to the left, >0 to the right)
-  var leftSide;
-  if (head.line != anchor.line) {
-    leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0;
-  } else {
-    var headIndex = getBidiPartAt(order, head.ch, head.sticky);
-    var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1);
-    if (headIndex == boundary - 1 || headIndex == boundary)
-      { leftSide = dir < 0; }
-    else
-      { leftSide = dir > 0; }
-  }
-
-  var usePart = order[boundary + (leftSide ? -1 : 0)];
-  var from = leftSide == (usePart.level == 1);
-  var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before";
-  return anchor.ch == ch && anchor.sticky == sticky ? range$$1 : new Range(new Pos(anchor.line, ch, sticky), head)
-}
-
-
-// Determines whether an event happened in the gutter, and fires the
-// handlers for the corresponding event.
-function gutterEvent(cm, e, type, prevent) {
-  var mX, mY;
-  if (e.touches) {
-    mX = e.touches[0].clientX;
-    mY = e.touches[0].clientY;
-  } else {
-    try { mX = e.clientX; mY = e.clientY; }
-    catch(e) { return false }
-  }
-  if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
-  if (prevent) { e_preventDefault(e); }
-
-  var display = cm.display;
-  var lineBox = display.lineDiv.getBoundingClientRect();
-
-  if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) }
-  mY -= lineBox.top - display.viewOffset;
-
-  for (var i = 0; i < cm.options.gutters.length; ++i) {
-    var g = display.gutters.childNodes[i];
-    if (g && g.getBoundingClientRect().right >= mX) {
-      var line = lineAtHeight(cm.doc, mY);
-      var gutter = cm.options.gutters[i];
-      signal(cm, type, cm, line, gutter, e);
-      return e_defaultPrevented(e)
-    }
-  }
-}
-
-function clickInGutter(cm, e) {
-  return gutterEvent(cm, e, "gutterClick", true)
-}
-
-// CONTEXT MENU HANDLING
-
-// To make the context menu work, we need to briefly unhide the
-// textarea (making it as unobtrusive as possible) to let the
-// right-click take effect on it.
-function onContextMenu(cm, e) {
-  if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return }
-  if (signalDOMEvent(cm, e, "contextmenu")) { return }
-  cm.display.input.onContextMenu(e);
-}
-
-function contextMenuInGutter(cm, e) {
-  if (!hasHandler(cm, "gutterContextMenu")) { return false }
-  return gutterEvent(cm, e, "gutterContextMenu", false)
-}
-
-function themeChanged(cm) {
-  cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
-    cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
-  clearCaches(cm);
-}
-
-var Init = {toString: function(){return "CodeMirror.Init"}};
-
-var defaults = {};
-var optionHandlers = {};
-
-function defineOptions(CodeMirror) {
-  var optionHandlers = CodeMirror.optionHandlers;
-
-  function option(name, deflt, handle, notOnInit) {
-    CodeMirror.defaults[name] = deflt;
-    if (handle) { optionHandlers[name] =
-      notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old); }} : handle; }
-  }
-
-  CodeMirror.defineOption = option;
-
-  // Passed to option handlers when there is no old value.
-  CodeMirror.Init = Init;
-
-  // These two are, on init, called from the constructor because they
-  // have to be initialized before the editor can start at all.
-  option("value", "", function (cm, val) { return cm.setValue(val); }, true);
-  option("mode", null, function (cm, val) {
-    cm.doc.modeOption = val;
-    loadMode(cm);
-  }, true);
-
-  option("indentUnit", 2, loadMode, true);
-  option("indentWithTabs", false);
-  option("smartIndent", true);
-  option("tabSize", 4, function (cm) {
-    resetModeState(cm);
-    clearCaches(cm);
-    regChange(cm);
-  }, true);
-  option("lineSeparator", null, function (cm, val) {
-    cm.doc.lineSep = val;
-    if (!val) { return }
-    var newBreaks = [], lineNo = cm.doc.first;
-    cm.doc.iter(function (line) {
-      for (var pos = 0;;) {
-        var found = line.text.indexOf(val, pos);
-        if (found == -1) { break }
-        pos = found + val.length;
-        newBreaks.push(Pos(lineNo, found));
-      }
-      lineNo++;
-    });
-    for (var i = newBreaks.length - 1; i >= 0; i--)
-      { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
-  });
-  option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) {
-    cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
-    if (old != Init) { cm.refresh(); }
-  });
-  option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true);
-  option("electricChars", true);
-  option("inputStyle", mobile ? "contenteditable" : "textarea", function () {
-    throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME
-  }, true);
-  option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true);
-  option("rtlMoveVisually", !windows);
-  option("wholeLineUpdateBefore", true);
-
-  option("theme", "default", function (cm) {
-    themeChanged(cm);
-    guttersChanged(cm);
-  }, true);
-  option("keyMap", "default", function (cm, val, old) {
-    var next = getKeyMap(val);
-    var prev = old != Init && getKeyMap(old);
-    if (prev && prev.detach) { prev.detach(cm, next); }
-    if (next.attach) { next.attach(cm, prev || null); }
-  });
-  option("extraKeys", null);
-  option("configureMouse", null);
-
-  option("lineWrapping", false, wrappingChanged, true);
-  option("gutters", [], function (cm) {
-    setGuttersForLineNumbers(cm.options);
-    guttersChanged(cm);
-  }, true);
-  option("fixedGutter", true, function (cm, val) {
-    cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
-    cm.refresh();
-  }, true);
-  option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true);
-  option("scrollbarStyle", "native", function (cm) {
-    initScrollbars(cm);
-    updateScrollbars(cm);
-    cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
-    cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
-  }, true);
-  option("lineNumbers", false, function (cm) {
-    setGuttersForLineNumbers(cm.options);
-    guttersChanged(cm);
-  }, true);
-  option("firstLineNumber", 1, guttersChanged, true);
-  option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true);
-  option("showCursorWhenSelecting", false, updateSelection, true);
-
-  option("resetSelectionOnContextMenu", true);
-  option("lineWiseCopyCut", true);
-  option("pasteLinesPerSelection", true);
-
-  option("readOnly", false, function (cm, val) {
-    if (val == "nocursor") {
-      onBlur(cm);
-      cm.display.input.blur();
-    }
-    cm.display.input.readOnlyChanged(val);
-  });
-  option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
-  option("dragDrop", true, dragDropChanged);
-  option("allowDropFileTypes", null);
-
-  option("cursorBlinkRate", 530);
-  option("cursorScrollMargin", 0);
-  option("cursorHeight", 1, updateSelection, true);
-  option("singleCursorHeightPerLine", true, updateSelection, true);
-  option("workTime", 100);
-  option("workDelay", 100);
-  option("flattenSpans", true, resetModeState, true);
-  option("addModeClass", false, resetModeState, true);
-  option("pollInterval", 100);
-  option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; });
-  option("historyEventDelay", 1250);
-  option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true);
-  option("maxHighlightLength", 10000, resetModeState, true);
-  option("moveInputWithCursor", true, function (cm, val) {
-    if (!val) { cm.display.input.resetPosition(); }
-  });
-
-  option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; });
-  option("autofocus", null);
-  option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true);
-}
-
-function guttersChanged(cm) {
-  updateGutters(cm);
-  regChange(cm);
-  alignHorizontally(cm);
-}
-
-function dragDropChanged(cm, value, old) {
-  var wasOn = old && old != Init;
-  if (!value != !wasOn) {
-    var funcs = cm.display.dragFunctions;
-    var toggle = value ? on : off;
-    toggle(cm.display.scroller, "dragstart", funcs.start);
-    toggle(cm.display.scroller, "dragenter", funcs.enter);
-    toggle(cm.display.scroller, "dragover", funcs.over);
-    toggle(cm.display.scroller, "dragleave", funcs.leave);
-    toggle(cm.display.scroller, "drop", funcs.drop);
-  }
-}
-
-function wrappingChanged(cm) {
-  if (cm.options.lineWrapping) {
-    addClass(cm.display.wrapper, "CodeMirror-wrap");
-    cm.display.sizer.style.minWidth = "";
-    cm.display.sizerWidth = null;
-  } else {
-    rmClass(cm.display.wrapper, "CodeMirror-wrap");
-    findMaxLine(cm);
-  }
-  estimateLineHeights(cm);
-  regChange(cm);
-  clearCaches(cm);
-  setTimeout(function () { return updateScrollbars(cm); }, 100);
-}
-
-// A CodeMirror instance represents an editor. This is the object
-// that user code is usually dealing with.
-
-function CodeMirror$1(place, options) {
-  var this$1 = this;
-
-  if (!(this instanceof CodeMirror$1)) { return new CodeMirror$1(place, options) }
-
-  this.options = options = options ? copyObj(options) : {};
-  // Determine effective options based on given values and defaults.
-  copyObj(defaults, options, false);
-  setGuttersForLineNumbers(options);
-
-  var doc = options.value;
-  if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); }
-  this.doc = doc;
-
-  var input = new CodeMirror$1.inputStyles[options.inputStyle](this);
-  var display = this.display = new Display(place, doc, input);
-  display.wrapper.CodeMirror = this;
-  updateGutters(this);
-  themeChanged(this);
-  if (options.lineWrapping)
-    { this.display.wrapper.className += " CodeMirror-wrap"; }
-  initScrollbars(this);
-
-  this.state = {
-    keyMaps: [],  // stores maps added by addKeyMap
-    overlays: [], // highlighting overlays, as added by addOverlay
-    modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
-    overwrite: false,
-    delayingBlurEvent: false,
-    focused: false,
-    suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
-    pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
-    selectingText: false,
-    draggingText: false,
-    highlight: new Delayed(), // stores highlight worker timeout
-    keySeq: null,  // Unfinished key sequence
-    specialChars: null
-  };
-
-  if (options.autofocus && !mobile) { display.input.focus(); }
-
-  // Override magic textarea content restore that IE sometimes does
-  // on our hidden textarea on reload
-  if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20); }
-
-  registerEventHandlers(this);
-  ensureGlobalHandlers();
-
-  startOperation(this);
-  this.curOp.forceUpdate = true;
-  attachDoc(this, doc);
-
-  if ((options.autofocus && !mobile) || this.hasFocus())
-    { setTimeout(bind(onFocus, this), 20); }
-  else
-    { onBlur(this); }
-
-  for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt))
-    { optionHandlers[opt](this$1, options[opt], Init); } }
-  maybeUpdateLineNumberWidth(this);
-  if (options.finishInit) { options.finishInit(this); }
-  for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1); }
-  endOperation(this);
-  // Suppress optimizelegibility in Webkit, since it breaks text
-  // measuring on line wrapping boundaries.
-  if (webkit && options.lineWrapping &&
-      getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
-    { display.lineDiv.style.textRendering = "auto"; }
-}
-
-// The default configuration options.
-CodeMirror$1.defaults = defaults;
-// Functions to run when options are changed.
-CodeMirror$1.optionHandlers = optionHandlers;
-
-// Attach the necessary event handlers when initializing the editor
-function registerEventHandlers(cm) {
-  var d = cm.display;
-  on(d.scroller, "mousedown", operation(cm, onMouseDown));
-  // Older IE's will not fire a second mousedown for a double click
-  if (ie && ie_version < 11)
-    { on(d.scroller, "dblclick", operation(cm, function (e) {
-      if (signalDOMEvent(cm, e)) { return }
-      var pos = posFromMouse(cm, e);
-      if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return }
-      e_preventDefault(e);
-      var word = cm.findWordAt(pos);
-      extendSelection(cm.doc, word.anchor, word.head);
-    })); }
-  else
-    { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }); }
-  // Some browsers fire contextmenu *after* opening the menu, at
-  // which point we can't mess with it anymore. Context menu is
-  // handled in onMouseDown for these browsers.
-  if (!captureRightClick) { on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }); }
-
-  // Used to suppress mouse event handling when a touch happens
-  var touchFinished, prevTouch = {end: 0};
-  function finishTouch() {
-    if (d.activeTouch) {
-      touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000);
-      prevTouch = d.activeTouch;
-      prevTouch.end = +new Date;
-    }
-  }
-  function isMouseLikeTouchEvent(e) {
-    if (e.touches.length != 1) { return false }
-    var touch = e.touches[0];
-    return touch.radiusX <= 1 && touch.radiusY <= 1
-  }
-  function farAway(touch, other) {
-    if (other.left == null) { return true }
-    var dx = other.left - touch.left, dy = other.top - touch.top;
-    return dx * dx + dy * dy > 20 * 20
-  }
-  on(d.scroller, "touchstart", function (e) {
-    if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) {
-      d.input.ensurePolled();
-      clearTimeout(touchFinished);
-      var now = +new Date;
-      d.activeTouch = {start: now, moved: false,
-                       prev: now - prevTouch.end <= 300 ? prevTouch : null};
-      if (e.touches.length == 1) {
-        d.activeTouch.left = e.touches[0].pageX;
-        d.activeTouch.top = e.touches[0].pageY;
-      }
-    }
-  });
-  on(d.scroller, "touchmove", function () {
-    if (d.activeTouch) { d.activeTouch.moved = true; }
-  });
-  on(d.scroller, "touchend", function (e) {
-    var touch = d.activeTouch;
-    if (touch && !eventInWidget(d, e) && touch.left != null &&
-        !touch.moved && new Date - touch.start < 300) {
-      var pos = cm.coordsChar(d.activeTouch, "page"), range;
-      if (!touch.prev || farAway(touch, touch.prev)) // Single tap
-        { range = new Range(pos, pos); }
-      else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
-        { range = cm.findWordAt(pos); }
-      else // Triple tap
-        { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); }
-      cm.setSelection(range.anchor, range.head);
-      cm.focus();
-      e_preventDefault(e);
-    }
-    finishTouch();
-  });
-  on(d.scroller, "touchcancel", finishTouch);
-
-  // Sync scrolling between fake scrollbars and real scrollable
-  // area, ensure viewport is updated when scrolling.
-  on(d.scroller, "scroll", function () {
-    if (d.scroller.clientHeight) {
-      updateScrollTop(cm, d.scroller.scrollTop);
-      setScrollLeft(cm, d.scroller.scrollLeft, true);
-      signal(cm, "scroll", cm);
-    }
-  });
-
-  // Listen to wheel events in order to try and update the viewport on time.
-  on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); });
-  on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); });
-
-  // Prevent wrapper from ever scrolling
-  on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
-
-  d.dragFunctions = {
-    enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e); }},
-    over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }},
-    start: function (e) { return onDragStart(cm, e); },
-    drop: operation(cm, onDrop),
-    leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); }}
-  };
-
-  var inp = d.input.getField();
-  on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); });
-  on(inp, "keydown", operation(cm, onKeyDown));
-  on(inp, "keypress", operation(cm, onKeyPress));
-  on(inp, "focus", function (e) { return onFocus(cm, e); });
-  on(inp, "blur", function (e) { return onBlur(cm, e); });
-}
-
-var initHooks = [];
-CodeMirror$1.defineInitHook = function (f) { return initHooks.push(f); };
-
-// Indent the given line. The how parameter can be "smart",
-// "add"/null, "subtract", or "prev". When aggressive is false
-// (typically set to true for forced single-line indents), empty
-// lines are not indented, and places where the mode returns Pass
-// are left alone.
-function indentLine(cm, n, how, aggressive) {
-  var doc = cm.doc, state;
-  if (how == null) { how = "add"; }
-  if (how == "smart") {
-    // Fall back to "prev" when the mode doesn't have an indentation
-    // method.
-    if (!doc.mode.indent) { how = "prev"; }
-    else { state = getContextBefore(cm, n).state; }
-  }
-
-  var tabSize = cm.options.tabSize;
-  var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
-  if (line.stateAfter) { line.stateAfter = null; }
-  var curSpaceString = line.text.match(/^\s*/)[0], indentation;
-  if (!aggressive && !/\S/.test(line.text)) {
-    indentation = 0;
-    how = "not";
-  } else if (how == "smart") {
-    indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
-    if (indentation == Pass || indentation > 150) {
-      if (!aggressive) { return }
-      how = "prev";
-    }
-  }
-  if (how == "prev") {
-    if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize); }
-    else { indentation = 0; }
-  } else if (how == "add") {
-    indentation = curSpace + cm.options.indentUnit;
-  } else if (how == "subtract") {
-    indentation = curSpace - cm.options.indentUnit;
-  } else if (typeof how == "number") {
-    indentation = curSpace + how;
-  }
-  indentation = Math.max(0, indentation);
-
-  var indentString = "", pos = 0;
-  if (cm.options.indentWithTabs)
-    { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} }
-  if (pos < indentation) { indentString += spaceStr(indentation - pos); }
-
-  if (indentString != curSpaceString) {
-    replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
-    line.stateAfter = null;
-    return true
-  } else {
-    // Ensure that, if the cursor was in the whitespace at the start
-    // of the line, it is moved to the end of that space.
-    for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) {
-      var range = doc.sel.ranges[i$1];
-      if (range.head.line == n && range.head.ch < curSpaceString.length) {
-        var pos$1 = Pos(n, curSpaceString.length);
-        replaceOneSelection(doc, i$1, new Range(pos$1, pos$1));
-        break
-      }
-    }
-  }
-}
-
-// This will be set to a {lineWise: bool, text: [string]} object, so
-// that, when pasting, we know what kind of selections the copied
-// text was made out of.
-var lastCopied = null;
-
-function setLastCopied(newLastCopied) {
-  lastCopied = newLastCopied;
-}
-
-function applyTextInput(cm, inserted, deleted, sel, origin) {
-  var doc = cm.doc;
-  cm.display.shift = false;
-  if (!sel) { sel = doc.sel; }
-
-  var paste = cm.state.pasteIncoming || origin == "paste";
-  var textLines = splitLinesAuto(inserted), multiPaste = null;
-  // When pasing N lines into N selections, insert one line per selection
-  if (paste && sel.ranges.length > 1) {
-    if (lastCopied && lastCopied.text.join("\n") == inserted) {
-      if (sel.ranges.length % lastCopied.text.length == 0) {
-        multiPaste = [];
-        for (var i = 0; i < lastCopied.text.length; i++)
-          { multiPaste.push(doc.splitLines(lastCopied.text[i])); }
-      }
-    } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) {
-      multiPaste = map(textLines, function (l) { return [l]; });
-    }
-  }
-
-  var updateInput;
-  // Normal behavior is to insert the new text into every selection
-  for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) {
-    var range$$1 = sel.ranges[i$1];
-    var from = range$$1.from(), to = range$$1.to();
-    if (range$$1.empty()) {
-      if (deleted && deleted > 0) // Handle deletion
-        { from = Pos(from.line, from.ch - deleted); }
-      else if (cm.state.overwrite && !paste) // Handle overwrite
-        { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); }
-      else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
-        { from = to = Pos(from.line, 0); }
-    }
-    updateInput = cm.curOp.updateInput;
-    var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
-                       origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
-    makeChange(cm.doc, changeEvent);
-    signalLater(cm, "inputRead", cm, changeEvent);
-  }
-  if (inserted && !paste)
-    { triggerElectric(cm, inserted); }
-
-  ensureCursorVisible(cm);
-  cm.curOp.updateInput = updateInput;
-  cm.curOp.typing = true;
-  cm.state.pasteIncoming = cm.state.cutIncoming = false;
-}
-
-function handlePaste(e, cm) {
-  var pasted = e.clipboardData && e.clipboardData.getData("Text");
-  if (pasted) {
-    e.preventDefault();
-    if (!cm.isReadOnly() && !cm.options.disableInput)
-      { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }); }
-    return true
-  }
-}
-
-function triggerElectric(cm, inserted) {
-  // When an 'electric' character is inserted, immediately trigger a reindent
-  if (!cm.options.electricChars || !cm.options.smartIndent) { return }
-  var sel = cm.doc.sel;
-
-  for (var i = sel.ranges.length - 1; i >= 0; i--) {
-    var range$$1 = sel.ranges[i];
-    if (range$$1.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range$$1.head.line)) { continue }
-    var mode = cm.getModeAt(range$$1.head);
-    var indented = false;
-    if (mode.electricChars) {
-      for (var j = 0; j < mode.electricChars.length; j++)
-        { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
-          indented = indentLine(cm, range$$1.head.line, "smart");
-          break
-        } }
-    } else if (mode.electricInput) {
-      if (mode.electricInput.test(getLine(cm.doc, range$$1.head.line).text.slice(0, range$$1.head.ch)))
-        { indented = indentLine(cm, range$$1.head.line, "smart"); }
-    }
-    if (indented) { signalLater(cm, "electricInput", cm, range$$1.head.line); }
-  }
-}
-
-function copyableRanges(cm) {
-  var text = [], ranges = [];
-  for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
-    var line = cm.doc.sel.ranges[i].head.line;
-    var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
-    ranges.push(lineRange);
-    text.push(cm.getRange(lineRange.anchor, lineRange.head));
-  }
-  return {text: text, ranges: ranges}
-}
-
-function disableBrowserMagic(field, spellcheck) {
-  field.setAttribute("autocorrect", "off");
-  field.setAttribute("autocapitalize", "off");
-  field.setAttribute("spellcheck", !!spellcheck);
-}
-
-function hiddenTextarea() {
-  var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none");
-  var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
-  // The textarea is kept positioned near the cursor to prevent the
-  // fact that it'll be scrolled into view on input from scrolling
-  // our fake cursor out of view. On webkit, when wrap=off, paste is
-  // very slow. So make the area wide instead.
-  if (webkit) { te.style.width = "1000px"; }
-  else { te.setAttribute("wrap", "off"); }
-  // If border: 0; -- iOS fails to open keyboard (issue #1287)
-  if (ios) { te.style.border = "1px solid black"; }
-  disableBrowserMagic(te);
-  return div
-}
-
-// The publicly visible API. Note that methodOp(f) means
-// 'wrap f in an operation, performed on its `this` parameter'.
-
-// This is not the complete set of editor methods. Most of the
-// methods defined on the Doc type are also injected into
-// CodeMirror.prototype, for backwards compatibility and
-// convenience.
-
-var addEditorMethods = function(CodeMirror) {
-  var optionHandlers = CodeMirror.optionHandlers;
-
-  var helpers = CodeMirror.helpers = {};
-
-  CodeMirror.prototype = {
-    constructor: CodeMirror,
-    focus: function(){window.focus(); this.display.input.focus();},
-
-    setOption: function(option, value) {
-      var options = this.options, old = options[option];
-      if (options[option] == value && option != "mode") { return }
-      options[option] = value;
-      if (optionHandlers.hasOwnProperty(option))
-        { operation(this, optionHandlers[option])(this, value, old); }
-      signal(this, "optionChange", this, option);
-    },
-
-    getOption: function(option) {return this.options[option]},
-    getDoc: function() {return this.doc},
-
-    addKeyMap: function(map$$1, bottom) {
-      this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map$$1));
-    },
-    removeKeyMap: function(map$$1) {
-      var maps = this.state.keyMaps;
-      for (var i = 0; i < maps.length; ++i)
-        { if (maps[i] == map$$1 || maps[i].name == map$$1) {
-          maps.splice(i, 1);
-          return true
-        } }
-    },
-
-    addOverlay: methodOp(function(spec, options) {
-      var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
-      if (mode.startState) { throw new Error("Overlays may not be stateful.") }
-      insertSorted(this.state.overlays,
-                   {mode: mode, modeSpec: spec, opaque: options && options.opaque,
-                    priority: (options && options.priority) || 0},
-                   function (overlay) { return overlay.priority; });
-      this.state.modeGen++;
-      regChange(this);
-    }),
-    removeOverlay: methodOp(function(spec) {
-      var this$1 = this;
-
-      var overlays = this.state.overlays;
-      for (var i = 0; i < overlays.length; ++i) {
-        var cur = overlays[i].modeSpec;
-        if (cur == spec || typeof spec == "string" && cur.name == spec) {
-          overlays.splice(i, 1);
-          this$1.state.modeGen++;
-          regChange(this$1);
-          return
-        }
-      }
-    }),
-
-    indentLine: methodOp(function(n, dir, aggressive) {
-      if (typeof dir != "string" && typeof dir != "number") {
-        if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev"; }
-        else { dir = dir ? "add" : "subtract"; }
-      }
-      if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive); }
-    }),
-    indentSelection: methodOp(function(how) {
-      var this$1 = this;
-
-      var ranges = this.doc.sel.ranges, end = -1;
-      for (var i = 0; i < ranges.length; i++) {
-        var range$$1 = ranges[i];
-        if (!range$$1.empty()) {
-          var from = range$$1.from(), to = range$$1.to();
-          var start = Math.max(end, from.line);
-          end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
-          for (var j = start; j < end; ++j)
-            { indentLine(this$1, j, how); }
-          var newRanges = this$1.doc.sel.ranges;
-          if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
-            { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); }
-        } else if (range$$1.head.line > end) {
-          indentLine(this$1, range$$1.head.line, how, true);
-          end = range$$1.head.line;
-          if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1); }
-        }
-      }
-    }),
-
-    // Fetch the parser token for a given character. Useful for hacks
-    // that want to inspect the mode state (say, for completion).
-    getTokenAt: function(pos, precise) {
-      return takeToken(this, pos, precise)
-    },
-
-    getLineTokens: function(line, precise) {
-      return takeToken(this, Pos(line), precise, true)
-    },
-
-    getTokenTypeAt: function(pos) {
-      pos = clipPos(this.doc, pos);
-      var styles = getLineStyles(this, getLine(this.doc, pos.line));
-      var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
-      var type;
-      if (ch == 0) { type = styles[2]; }
-      else { for (;;) {
-        var mid = (before + after) >> 1;
-        if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid; }
-        else if (styles[mid * 2 + 1] < ch) { before = mid + 1; }
-        else { type = styles[mid * 2 + 2]; break }
-      } }
-      var cut = type ? type.indexOf("overlay ") : -1;
-      return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1)
-    },
-
-    getModeAt: function(pos) {
-      var mode = this.doc.mode;
-      if (!mode.innerMode) { return mode }
-      return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode
-    },
-
-    getHelper: function(pos, type) {
-      return this.getHelpers(pos, type)[0]
-    },
-
-    getHelpers: function(pos, type) {
-      var this$1 = this;
-
-      var found = [];
-      if (!helpers.hasOwnProperty(type)) { return found }
-      var help = helpers[type], mode = this.getModeAt(pos);
-      if (typeof mode[type] == "string") {
-        if (help[mode[type]]) { found.push(help[mode[type]]); }
-      } else if (mode[type]) {
-        for (var i = 0; i < mode[type].length; i++) {
-          var val = help[mode[type][i]];
-          if (val) { found.push(val); }
-        }
-      } else if (mode.helperType && help[mode.helperType]) {
-        found.push(help[mode.helperType]);
-      } else if (help[mode.name]) {
-        found.push(help[mode.name]);
-      }
-      for (var i$1 = 0; i$1 < help._global.length; i$1++) {
-        var cur = help._global[i$1];
-        if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1)
-          { found.push(cur.val); }
-      }
-      return found
-    },
-
-    getStateAfter: function(line, precise) {
-      var doc = this.doc;
-      line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
-      return getContextBefore(this, line + 1, precise).state
-    },
-
-    cursorCoords: function(start, mode) {
-      var pos, range$$1 = this.doc.sel.primary();
-      if (start == null) { pos = range$$1.head; }
-      else if (typeof start == "object") { pos = clipPos(this.doc, start); }
-      else { pos = start ? range$$1.from() : range$$1.to(); }
-      return cursorCoords(this, pos, mode || "page")
-    },
-
-    charCoords: function(pos, mode) {
-      return charCoords(this, clipPos(this.doc, pos), mode || "page")
-    },
-
-    coordsChar: function(coords, mode) {
-      coords = fromCoordSystem(this, coords, mode || "page");
-      return coordsChar(this, coords.left, coords.top)
-    },
-
-    lineAtHeight: function(height, mode) {
-      height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
-      return lineAtHeight(this.doc, height + this.display.viewOffset)
-    },
-    heightAtLine: function(line, mode, includeWidgets) {
-      var end = false, lineObj;
-      if (typeof line == "number") {
-        var last = this.doc.first + this.doc.size - 1;
-        if (line < this.doc.first) { line = this.doc.first; }
-        else if (line > last) { line = last; end = true; }
-        lineObj = getLine(this.doc, line);
-      } else {
-        lineObj = line;
-      }
-      return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top +
-        (end ? this.doc.height - heightAtLine(lineObj) : 0)
-    },
-
-    defaultTextHeight: function() { return textHeight(this.display) },
-    defaultCharWidth: function() { return charWidth(this.display) },
-
-    getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}},
-
-    addWidget: function(pos, node, scroll, vert, horiz) {
-      var display = this.display;
-      pos = cursorCoords(this, clipPos(this.doc, pos));
-      var top = pos.bottom, left = pos.left;
-      node.style.position = "absolute";
-      node.setAttribute("cm-ignore-events", "true");
-      this.display.input.setUneditable(node);
-      display.sizer.appendChild(node);
-      if (vert == "over") {
-        top = pos.top;
-      } else if (vert == "above" || vert == "near") {
-        var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
-        hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
-        // Default to positioning above (if specified and possible); otherwise default to positioning below
-        if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
-          { top = pos.top - node.offsetHeight; }
-        else if (pos.bottom + node.offsetHeight <= vspace)
-          { top = pos.bottom; }
-        if (left + node.offsetWidth > hspace)
-          { left = hspace - node.offsetWidth; }
-      }
-      node.style.top = top + "px";
-      node.style.left = node.style.right = "";
-      if (horiz == "right") {
-        left = display.sizer.clientWidth - node.offsetWidth;
-        node.style.right = "0px";
-      } else {
-        if (horiz == "left") { left = 0; }
-        else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2; }
-        node.style.left = left + "px";
-      }
-      if (scroll)
-        { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}); }
-    },
-
-    triggerOnKeyDown: methodOp(onKeyDown),
-    triggerOnKeyPress: methodOp(onKeyPress),
-    triggerOnKeyUp: onKeyUp,
-    triggerOnMouseDown: methodOp(onMouseDown),
-
-    execCommand: function(cmd) {
-      if (commands.hasOwnProperty(cmd))
-        { return commands[cmd].call(null, this) }
-    },
-
-    triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
-
-    findPosH: function(from, amount, unit, visually) {
-      var this$1 = this;
-
-      var dir = 1;
-      if (amount < 0) { dir = -1; amount = -amount; }
-      var cur = clipPos(this.doc, from);
-      for (var i = 0; i < amount; ++i) {
-        cur = findPosH(this$1.doc, cur, dir, unit, visually);
-        if (cur.hitSide) { break }
-      }
-      return cur
-    },
-
-    moveH: methodOp(function(dir, unit) {
-      var this$1 = this;
-
-      this.extendSelectionsBy(function (range$$1) {
-        if (this$1.display.shift || this$1.doc.extend || range$$1.empty())
-          { return findPosH(this$1.doc, range$$1.head, dir, unit, this$1.options.rtlMoveVisually) }
-        else
-          { return dir < 0 ? range$$1.from() : range$$1.to() }
-      }, sel_move);
-    }),
-
-    deleteH: methodOp(function(dir, unit) {
-      var sel = this.doc.sel, doc = this.doc;
-      if (sel.somethingSelected())
-        { doc.replaceSelection("", null, "+delete"); }
-      else
-        { deleteNearSelection(this, function (range$$1) {
-          var other = findPosH(doc, range$$1.head, dir, unit, false);
-          return dir < 0 ? {from: other, to: range$$1.head} : {from: range$$1.head, to: other}
-        }); }
-    }),
-
-    findPosV: function(from, amount, unit, goalColumn) {
-      var this$1 = this;
-
-      var dir = 1, x = goalColumn;
-      if (amount < 0) { dir = -1; amount = -amount; }
-      var cur = clipPos(this.doc, from);
-      for (var i = 0; i < amount; ++i) {
-        var coords = cursorCoords(this$1, cur, "div");
-        if (x == null) { x = coords.left; }
-        else { coords.left = x; }
-        cur = findPosV(this$1, coords, dir, unit);
-        if (cur.hitSide) { break }
-      }
-      return cur
-    },
-
-    moveV: methodOp(function(dir, unit) {
-      var this$1 = this;
-
-      var doc = this.doc, goals = [];
-      var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected();
-      doc.extendSelectionsBy(function (range$$1) {
-        if (collapse)
-          { return dir < 0 ? range$$1.from() : range$$1.to() }
-        var headPos = cursorCoords(this$1, range$$1.head, "div");
-        if (range$$1.goalColumn != null) { headPos.left = range$$1.goalColumn; }
-        goals.push(headPos.left);
-        var pos = findPosV(this$1, headPos, dir, unit);
-        if (unit == "page" && range$$1 == doc.sel.primary())
-          { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top); }
-        return pos
-      }, sel_move);
-      if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++)
-        { doc.sel.ranges[i].goalColumn = goals[i]; } }
-    }),
-
-    // Find the word at the given position (as returned by coordsChar).
-    findWordAt: function(pos) {
-      var doc = this.doc, line = getLine(doc, pos.line).text;
-      var start = pos.ch, end = pos.ch;
-      if (line) {
-        var helper = this.getHelper(pos, "wordChars");
-        if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end; }
-        var startChar = line.charAt(start);
-        var check = isWordChar(startChar, helper)
-          ? function (ch) { return isWordChar(ch, helper); }
-          : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); }
-          : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); };
-        while (start > 0 && check(line.charAt(start - 1))) { --start; }
-        while (end < line.length && check(line.charAt(end))) { ++end; }
-      }
-      return new Range(Pos(pos.line, start), Pos(pos.line, end))
-    },
-
-    toggleOverwrite: function(value) {
-      if (value != null && value == this.state.overwrite) { return }
-      if (this.state.overwrite = !this.state.overwrite)
-        { addClass(this.display.cursorDiv, "CodeMirror-overwrite"); }
-      else
-        { rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); }
-
-      signal(this, "overwriteToggle", this, this.state.overwrite);
-    },
-    hasFocus: function() { return this.display.input.getField() == activeElt() },
-    isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },
-
-    scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }),
-    getScrollInfo: function() {
-      var scroller = this.display.scroller;
-      return {left: scroller.scrollLeft, top: scroller.scrollTop,
-              height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
-              width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
-              clientHeight: displayHeight(this), clientWidth: displayWidth(this)}
-    },
-
-    scrollIntoView: methodOp(function(range$$1, margin) {
-      if (range$$1 == null) {
-        range$$1 = {from: this.doc.sel.primary().head, to: null};
-        if (margin == null) { margin = this.options.cursorScrollMargin; }
-      } else if (typeof range$$1 == "number") {
-        range$$1 = {from: Pos(range$$1, 0), to: null};
-      } else if (range$$1.from == null) {
-        range$$1 = {from: range$$1, to: null};
-      }
-      if (!range$$1.to) { range$$1.to = range$$1.from; }
-      range$$1.margin = margin || 0;
-
-      if (range$$1.from.line != null) {
-        scrollToRange(this, range$$1);
-      } else {
-        scrollToCoordsRange(this, range$$1.from, range$$1.to, range$$1.margin);
-      }
-    }),
-
-    setSize: methodOp(function(width, height) {
-      var this$1 = this;
-
-      var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; };
-      if (width != null) { this.display.wrapper.style.width = interpret(width); }
-      if (height != null) { this.display.wrapper.style.height = interpret(height); }
-      if (this.options.lineWrapping) { clearLineMeasurementCache(this); }
-      var lineNo$$1 = this.display.viewFrom;
-      this.doc.iter(lineNo$$1, this.display.viewTo, function (line) {
-        if (line.widgets) { for (var i = 0; i < line.widgets.length; i++)
-          { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo$$1, "widget"); break } } }
-        ++lineNo$$1;
-      });
-      this.curOp.forceUpdate = true;
-      signal(this, "refresh", this);
-    }),
-
-    operation: function(f){return runInOp(this, f)},
-    startOperation: function(){return startOperation(this)},
-    endOperation: function(){return endOperation(this)},
-
-    refresh: methodOp(function() {
-      var oldHeight = this.display.cachedTextHeight;
-      regChange(this);
-      this.curOp.forceUpdate = true;
-      clearCaches(this);
-      scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
-      updateGutterSpace(this);
-      if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
-        { estimateLineHeights(this); }
-      signal(this, "refresh", this);
-    }),
-
-    swapDoc: methodOp(function(doc) {
-      var old = this.doc;
-      old.cm = null;
-      attachDoc(this, doc);
-      clearCaches(this);
-      this.display.input.reset();
-      scrollToCoords(this, doc.scrollLeft, doc.scrollTop);
-      this.curOp.forceScroll = true;
-      signalLater(this, "swapDoc", this, old);
-      return old
-    }),
-
-    getInputField: function(){return this.display.input.getField()},
-    getWrapperElement: function(){return this.display.wrapper},
-    getScrollerElement: function(){return this.display.scroller},
-    getGutterElement: function(){return this.display.gutters}
-  };
-  eventMixin(CodeMirror);
-
-  CodeMirror.registerHelper = function(type, name, value) {
-    if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []}; }
-    helpers[type][name] = value;
-  };
-  CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
-    CodeMirror.registerHelper(type, name, value);
-    helpers[type]._global.push({pred: predicate, val: value});
-  };
-};
-
-// Used for horizontal relative motion. Dir is -1 or 1 (left or
-// right), unit can be "char", "column" (like char, but doesn't
-// cross line boundaries), "word" (across next word), or "group" (to
-// the start of next group of word or non-word-non-whitespace
-// chars). The visually param controls whether, in right-to-left
-// text, direction 1 means to move towards the next index in the
-// string, or towards the character to the right of the current
-// position. The resulting position will have a hitSide=true
-// property if it reached the end of the document.
-function findPosH(doc, pos, dir, unit, visually) {
-  var oldPos = pos;
-  var origDir = dir;
-  var lineObj = getLine(doc, pos.line);
-  function findNextLine() {
-    var l = pos.line + dir;
-    if (l < doc.first || l >= doc.first + doc.size) { return false }
-    pos = new Pos(l, pos.ch, pos.sticky);
-    return lineObj = getLine(doc, l)
-  }
-  function moveOnce(boundToLine) {
-    var next;
-    if (visually) {
-      next = moveVisually(doc.cm, lineObj, pos, dir);
-    } else {
-      next = moveLogically(lineObj, pos, dir);
-    }
-    if (next == null) {
-      if (!boundToLine && findNextLine())
-        { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir); }
-      else
-        { return false }
-    } else {
-      pos = next;
-    }
-    return true
-  }
-
-  if (unit == "char") {
-    moveOnce();
-  } else if (unit == "column") {
-    moveOnce(true);
-  } else if (unit == "word" || unit == "group") {
-    var sawType = null, group = unit == "group";
-    var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
-    for (var first = true;; first = false) {
-      if (dir < 0 && !moveOnce(!first)) { break }
-      var cur = lineObj.text.charAt(pos.ch) || "\n";
-      var type = isWordChar(cur, helper) ? "w"
-        : group && cur == "\n" ? "n"
-        : !group || /\s/.test(cur) ? null
-        : "p";
-      if (group && !first && !type) { type = "s"; }
-      if (sawType && sawType != type) {
-        if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after";}
-        break
-      }
-
-      if (type) { sawType = type; }
-      if (dir > 0 && !moveOnce(!first)) { break }
-    }
-  }
-  var result = skipAtomic(doc, pos, oldPos, origDir, true);
-  if (equalCursorPos(oldPos, result)) { result.hitSide = true; }
-  return result
-}
-
-// For relative vertical movement. Dir may be -1 or 1. Unit can be
-// "page" or "line". The resulting position will have a hitSide=true
-// property if it reached the end of the document.
-function findPosV(cm, pos, dir, unit) {
-  var doc = cm.doc, x = pos.left, y;
-  if (unit == "page") {
-    var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
-    var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3);
-    y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount;
-
-  } else if (unit == "line") {
-    y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
-  }
-  var target;
-  for (;;) {
-    target = coordsChar(cm, x, y);
-    if (!target.outside) { break }
-    if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break }
-    y += dir * 5;
-  }
-  return target
-}
-
-// CONTENTEDITABLE INPUT STYLE
-
-var ContentEditableInput = function(cm) {
-  this.cm = cm;
-  this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
-  this.polling = new Delayed();
-  this.composing = null;
-  this.gracePeriod = false;
-  this.readDOMTimeout = null;
-};
-
-ContentEditableInput.prototype.init = function (display) {
-    var this$1 = this;
-
-  var input = this, cm = input.cm;
-  var div = input.div = display.lineDiv;
-  disableBrowserMagic(div, cm.options.spellcheck);
-
-  on(div, "paste", function (e) {
-    if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
-    // IE doesn't fire input events, so we schedule a read for the pasted content in this way
-    if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
-  });
-
-  on(div, "compositionstart", function (e) {
-    this$1.composing = {data: e.data, done: false};
-  });
-  on(div, "compositionupdate", function (e) {
-    if (!this$1.composing) { this$1.composing = {data: e.data, done: false}; }
-  });
-  on(div, "compositionend", function (e) {
-    if (this$1.composing) {
-      if (e.data != this$1.composing.data) { this$1.readFromDOMSoon(); }
-      this$1.composing.done = true;
-    }
-  });
-
-  on(div, "touchstart", function () { return input.forceCompositionEnd(); });
-
-  on(div, "input", function () {
-    if (!this$1.composing) { this$1.readFromDOMSoon(); }
-  });
-
-  function onCopyCut(e) {
-    if (signalDOMEvent(cm, e)) { return }
-    if (cm.somethingSelected()) {
-      setLastCopied({lineWise: false, text: cm.getSelections()});
-      if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
-    } else if (!cm.options.lineWiseCopyCut) {
-      return
-    } else {
-      var ranges = copyableRanges(cm);
-      setLastCopied({lineWise: true, text: ranges.text});
-      if (e.type == "cut") {
-        cm.operation(function () {
-          cm.setSelections(ranges.ranges, 0, sel_dontScroll);
-          cm.replaceSelection("", null, "cut");
-        });
-      }
-    }
-    if (e.clipboardData) {
-      e.clipboardData.clearData();
-      var content = lastCopied.text.join("\n");
-      // iOS exposes the clipboard API, but seems to discard content inserted into it
-      e.clipboardData.setData("Text", content);
-      if (e.clipboardData.getData("Text") == content) {
-        e.preventDefault();
-        return
-      }
-    }
-    // Old-fashioned briefly-focus-a-textarea hack
-    var kludge = hiddenTextarea(), te = kludge.firstChild;
-    cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
-    te.value = lastCopied.text.join("\n");
-    var hadFocus = document.activeElement;
-    selectInput(te);
-    setTimeout(function () {
-      cm.display.lineSpace.removeChild(kludge);
-      hadFocus.focus();
-      if (hadFocus == div) { input.showPrimarySelection(); }
-    }, 50);
-  }
-  on(div, "copy", onCopyCut);
-  on(div, "cut", onCopyCut);
-};
-
-ContentEditableInput.prototype.prepareSelection = function () {
-  var result = prepareSelection(this.cm, false);
-  result.focus = this.cm.state.focused;
-  return result
-};
-
-ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
-  if (!info || !this.cm.display.view.length) { return }
-  if (info.focus || takeFocus) { this.showPrimarySelection(); }
-  this.showMultipleSelections(info);
-};
-
-ContentEditableInput.prototype.showPrimarySelection = function () {
-  var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary();
-  var from = prim.from(), to = prim.to();
-
-  if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
-    sel.removeAllRanges();
-    return
-  }
-
-  var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
-  var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset);
-  if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
-      cmp(minPos(curAnchor, curFocus), from) == 0 &&
-      cmp(maxPos(curAnchor, curFocus), to) == 0)
-    { return }
-
-  var view = cm.display.view;
-  var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) ||
-      {node: view[0].measure.map[2], offset: 0};
-  var end = to.line < cm.display.viewTo && posToDOM(cm, to);
-  if (!end) {
-    var measure = view[view.length - 1].measure;
-    var map$$1 = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
-    end = {node: map$$1[map$$1.length - 1], offset: map$$1[map$$1.length - 2] - map$$1[map$$1.length - 3]};
-  }
-
-  if (!start || !end) {
-    sel.removeAllRanges();
-    return
-  }
-
-  var old = sel.rangeCount && sel.getRangeAt(0), rng;
-  try { rng = range(start.node, start.offset, end.offset, end.node); }
-  catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
-  if (rng) {
-    if (!gecko && cm.state.focused) {
-      sel.collapse(start.node, start.offset);
-      if (!rng.collapsed) {
-        sel.removeAllRanges();
-        sel.addRange(rng);
-      }
-    } else {
-      sel.removeAllRanges();
-      sel.addRange(rng);
-    }
-    if (old && sel.anchorNode == null) { sel.addRange(old); }
-    else if (gecko) { this.startGracePeriod(); }
-  }
-  this.rememberSelection();
-};
-
-ContentEditableInput.prototype.startGracePeriod = function () {
-    var this$1 = this;
-
-  clearTimeout(this.gracePeriod);
-  this.gracePeriod = setTimeout(function () {
-    this$1.gracePeriod = false;
-    if (this$1.selectionChanged())
-      { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }); }
-  }, 20);
-};
-
-ContentEditableInput.prototype.showMultipleSelections = function (info) {
-  removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
-  removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
-};
-
-ContentEditableInput.prototype.rememberSelection = function () {
-  var sel = window.getSelection();
-  this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
-  this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
-};
-
-ContentEditableInput.prototype.selectionInEditor = function () {
-  var sel = window.getSelection();
-  if (!sel.rangeCount) { return false }
-  var node = sel.getRangeAt(0).commonAncestorContainer;
-  return contains(this.div, node)
-};
-
-ContentEditableInput.prototype.focus = function () {
-  if (this.cm.options.readOnly != "nocursor") {
-    if (!this.selectionInEditor())
-      { this.showSelection(this.prepareSelection(), true); }
-    this.div.focus();
-  }
-};
-ContentEditableInput.prototype.blur = function () { this.div.blur(); };
-ContentEditableInput.prototype.getField = function () { return this.div };
-
-ContentEditableInput.prototype.supportsTouch = function () { return true };
-
-ContentEditableInput.prototype.receivedFocus = function () {
-  var input = this;
-  if (this.selectionInEditor())
-    { this.pollSelection(); }
-  else
-    { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }); }
-
-  function poll() {
-    if (input.cm.state.focused) {
-      input.pollSelection();
-      input.polling.set(input.cm.options.pollInterval, poll);
-    }
-  }
-  this.polling.set(this.cm.options.pollInterval, poll);
-};
-
-ContentEditableInput.prototype.selectionChanged = function () {
-  var sel = window.getSelection();
-  return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
-    sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset
-};
-
-ContentEditableInput.prototype.pollSelection = function () {
-  if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }
-  var sel = window.getSelection(), cm = this.cm;
-  // On Android Chrome (version 56, at least), backspacing into an
-  // uneditable block element will put the cursor in that element,
-  // and then, because it's not editable, hide the virtual keyboard.
-  // Because Android doesn't allow us to actually detect backspace
-  // presses in a sane way, this code checks for when that happens
-  // and simulates a backspace press in this case.
-  if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) {
-    this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs});
-    this.blur();
-    this.focus();
-    return
-  }
-  if (this.composing) { return }
-  this.rememberSelection();
-  var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
-  var head = domToPos(cm, sel.focusNode, sel.focusOffset);
-  if (anchor && head) { runInOp(cm, function () {
-    setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
-    if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true; }
-  }); }
-};
-
-ContentEditableInput.prototype.pollContent = function () {
-  if (this.readDOMTimeout != null) {
-    clearTimeout(this.readDOMTimeout);
-    this.readDOMTimeout = null;
-  }
-
-  var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
-  var from = sel.from(), to = sel.to();
-  if (from.ch == 0 && from.line > cm.firstLine())
-    { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length); }
-  if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine())
-    { to = Pos(to.line + 1, 0); }
-  if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false }
-
-  var fromIndex, fromLine, fromNode;
-  if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
-    fromLine = lineNo(display.view[0].line);
-    fromNode = display.view[0].node;
-  } else {
-    fromLine = lineNo(display.view[fromIndex].line);
-    fromNode = display.view[fromIndex - 1].node.nextSibling;
-  }
-  var toIndex = findViewIndex(cm, to.line);
-  var toLine, toNode;
-  if (toIndex == display.view.length - 1) {
-    toLine = display.viewTo - 1;
-    toNode = display.lineDiv.lastChild;
-  } else {
-    toLine = lineNo(display.view[toIndex + 1].line) - 1;
-    toNode = display.view[toIndex + 1].node.previousSibling;
-  }
-
-  if (!fromNode) { return false }
-  var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
-  var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
-  while (newText.length > 1 && oldText.length > 1) {
-    if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
-    else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
-    else { break }
-  }
-
-  var cutFront = 0, cutEnd = 0;
-  var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
-  while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
-    { ++cutFront; }
-  var newBot = lst(newText), oldBot = lst(oldText);
-  var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
-                           oldBot.length - (oldText.length == 1 ? cutFront : 0));
-  while (cutEnd < maxCutEnd &&
-         newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
-    { ++cutEnd; }
-  // Try to move start of change to start of selection if ambiguous
-  if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) {
-    while (cutFront && cutFront > from.ch &&
-           newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) {
-      cutFront--;
-      cutEnd++;
-    }
-  }
-
-  newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "");
-  newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "");
-
-  var chFrom = Pos(fromLine, cutFront);
-  var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
-  if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
-    replaceRange(cm.doc, newText, chFrom, chTo, "+input");
-    return true
-  }
-};
-
-ContentEditableInput.prototype.ensurePolled = function () {
-  this.forceCompositionEnd();
-};
-ContentEditableInput.prototype.reset = function () {
-  this.forceCompositionEnd();
-};
-ContentEditableInput.prototype.forceCompositionEnd = function () {
-  if (!this.composing) { return }
-  clearTimeout(this.readDOMTimeout);
-  this.composing = null;
-  this.updateFromDOM();
-  this.div.blur();
-  this.div.focus();
-};
-ContentEditableInput.prototype.readFromDOMSoon = function () {
-    var this$1 = this;
-
-  if (this.readDOMTimeout != null) { return }
-  this.readDOMTimeout = setTimeout(function () {
-    this$1.readDOMTimeout = null;
-    if (this$1.composing) {
-      if (this$1.composing.done) { this$1.composing = null; }
-      else { return }
-    }
-    this$1.updateFromDOM();
-  }, 80);
-};
-
-ContentEditableInput.prototype.updateFromDOM = function () {
-    var this$1 = this;
-
-  if (this.cm.isReadOnly() || !this.pollContent())
-    { runInOp(this.cm, function () { return regChange(this$1.cm); }); }
-};
-
-ContentEditableInput.prototype.setUneditable = function (node) {
-  node.contentEditable = "false";
-};
-
-ContentEditableInput.prototype.onKeyPress = function (e) {
-  if (e.charCode == 0) { return }
-  e.preventDefault();
-  if (!this.cm.isReadOnly())
-    { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); }
-};
-
-ContentEditableInput.prototype.readOnlyChanged = function (val) {
-  this.div.contentEditable = String(val != "nocursor");
-};
-
-ContentEditableInput.prototype.onContextMenu = function () {};
-ContentEditableInput.prototype.resetPosition = function () {};
-
-ContentEditableInput.prototype.needsContentAttribute = true;
-
-function posToDOM(cm, pos) {
-  var view = findViewForLine(cm, pos.line);
-  if (!view || view.hidden) { return null }
-  var line = getLine(cm.doc, pos.line);
-  var info = mapFromLineView(view, line, pos.line);
-
-  var order = getOrder(line, cm.doc.direction), side = "left";
-  if (order) {
-    var partPos = getBidiPartAt(order, pos.ch);
-    side = partPos % 2 ? "right" : "left";
-  }
-  var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
-  result.offset = result.collapse == "right" ? result.end : result.start;
-  return result
-}
-
-function isInGutter(node) {
-  for (var scan = node; scan; scan = scan.parentNode)
-    { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } }
-  return false
-}
-
-function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
-
-function domTextBetween(cm, from, to, fromLine, toLine) {
-  var text = "", closing = false, lineSep = cm.doc.lineSeparator();
-  function recognizeMarker(id) { return function (marker) { return marker.id == id; } }
-  function close() {
-    if (closing) {
-      text += lineSep;
-      closing = false;
-    }
-  }
-  function addText(str) {
-    if (str) {
-      close();
-      text += str;
-    }
-  }
-  function walk(node) {
-    if (node.nodeType == 1) {
-      var cmText = node.getAttribute("cm-text");
-      if (cmText != null) {
-        addText(cmText || node.textContent.replace(/\u200b/g, ""));
-        return
-      }
-      var markerID = node.getAttribute("cm-marker"), range$$1;
-      if (markerID) {
-        var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
-        if (found.length && (range$$1 = found[0].find(0)))
-          { addText(getBetween(cm.doc, range$$1.from, range$$1.to).join(lineSep)); }
-        return
-      }
-      if (node.getAttribute("contenteditable") == "false") { return }
-      var isBlock = /^(pre|div|p)$/i.test(node.nodeName);
-      if (isBlock) { close(); }
-      for (var i = 0; i < node.childNodes.length; i++)
-        { walk(node.childNodes[i]); }
-      if (isBlock) { closing = true; }
-    } else if (node.nodeType == 3) {
-      addText(node.nodeValue);
-    }
-  }
-  for (;;) {
-    walk(from);
-    if (from == to) { break }
-    from = from.nextSibling;
-  }
-  return text
-}
-
-function domToPos(cm, node, offset) {
-  var lineNode;
-  if (node == cm.display.lineDiv) {
-    lineNode = cm.display.lineDiv.childNodes[offset];
-    if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) }
-    node = null; offset = 0;
-  } else {
-    for (lineNode = node;; lineNode = lineNode.parentNode) {
-      if (!lineNode || lineNode == cm.display.lineDiv) { return null }
-      if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break }
-    }
-  }
-  for (var i = 0; i < cm.display.view.length; i++) {
-    var lineView = cm.display.view[i];
-    if (lineView.node == lineNode)
-      { return locateNodeInLineView(lineView, node, offset) }
-  }
-}
-
-function locateNodeInLineView(lineView, node, offset) {
-  var wrapper = lineView.text.firstChild, bad = false;
-  if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) }
-  if (node == wrapper) {
-    bad = true;
-    node = wrapper.childNodes[offset];
-    offset = 0;
-    if (!node) {
-      var line = lineView.rest ? lst(lineView.rest) : lineView.line;
-      return badPos(Pos(lineNo(line), line.text.length), bad)
-    }
-  }
-
-  var textNode = node.nodeType == 3 ? node : null, topNode = node;
-  if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
-    textNode = node.firstChild;
-    if (offset) { offset = textNode.nodeValue.length; }
-  }
-  while (topNode.parentNode != wrapper) { topNode = topNode.parentNode; }
-  var measure = lineView.measure, maps = measure.maps;
-
-  function find(textNode, topNode, offset) {
-    for (var i = -1; i < (maps ? maps.length : 0); i++) {
-      var map$$1 = i < 0 ? measure.map : maps[i];
-      for (var j = 0; j < map$$1.length; j += 3) {
-        var curNode = map$$1[j + 2];
-        if (curNode == textNode || curNode == topNode) {
-          var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
-          var ch = map$$1[j] + offset;
-          if (offset < 0 || curNode != textNode) { ch = map$$1[j + (offset ? 1 : 0)]; }
-          return Pos(line, ch)
-        }
-      }
-    }
-  }
-  var found = find(textNode, topNode, offset);
-  if (found) { return badPos(found, bad) }
-
-  // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
-  for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
-    found = find(after, after.firstChild, 0);
-    if (found)
-      { return badPos(Pos(found.line, found.ch - dist), bad) }
-    else
-      { dist += after.textContent.length; }
-  }
-  for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) {
-    found = find(before, before.firstChild, -1);
-    if (found)
-      { return badPos(Pos(found.line, found.ch + dist$1), bad) }
-    else
-      { dist$1 += before.textContent.length; }
-  }
-}
-
-// TEXTAREA INPUT STYLE
-
-var TextareaInput = function(cm) {
-  this.cm = cm;
-  // See input.poll and input.reset
-  this.prevInput = "";
-
-  // Flag that indicates whether we expect input to appear real soon
-  // now (after some event like 'keypress' or 'input') and are
-  // polling intensively.
-  this.pollingFast = false;
-  // Self-resetting timeout for the poller
-  this.polling = new Delayed();
-  // Used to work around IE issue with selection being forgotten when focus moves away from textarea
-  this.hasSelection = false;
-  this.composing = null;
-};
-
-TextareaInput.prototype.init = function (display) {
-    var this$1 = this;
-
-  var input = this, cm = this.cm;
-
-  // Wraps and hides input textarea
-  var div = this.wrapper = hiddenTextarea();
-  // The semihidden textarea that is focused when the editor is
-  // focused, and receives input.
-  var te = this.textarea = div.firstChild;
-  display.wrapper.insertBefore(div, display.wrapper.firstChild);
-
-  // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
-  if (ios) { te.style.width = "0px"; }
-
-  on(te, "input", function () {
-    if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null; }
-    input.poll();
-  });
-
-  on(te, "paste", function (e) {
-    if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
-
-    cm.state.pasteIncoming = true;
-    input.fastPoll();
-  });
-
-  function prepareCopyCut(e) {
-    if (signalDOMEvent(cm, e)) { return }
-    if (cm.somethingSelected()) {
-      setLastCopied({lineWise: false, text: cm.getSelections()});
-    } else if (!cm.options.lineWiseCopyCut) {
-      return
-    } else {
-      var ranges = copyableRanges(cm);
-      setLastCopied({lineWise: true, text: ranges.text});
-      if (e.type == "cut") {
-        cm.setSelections(ranges.ranges, null, sel_dontScroll);
-      } else {
-        input.prevInput = "";
-        te.value = ranges.text.join("\n");
-        selectInput(te);
-      }
-    }
-    if (e.type == "cut") { cm.state.cutIncoming = true; }
-  }
-  on(te, "cut", prepareCopyCut);
-  on(te, "copy", prepareCopyCut);
-
-  on(display.scroller, "paste", function (e) {
-    if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return }
-    cm.state.pasteIncoming = true;
-    input.focus();
-  });
-
-  // Prevent normal selection in the editor (we handle our own)
-  on(display.lineSpace, "selectstart", function (e) {
-    if (!eventInWidget(display, e)) { e_preventDefault(e); }
-  });
-
-  on(te, "compositionstart", function () {
-    var start = cm.getCursor("from");
-    if (input.composing) { input.composing.range.clear(); }
-    input.composing = {
-      start: start,
-      range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
-    };
-  });
-  on(te, "compositionend", function () {
-    if (input.composing) {
-      input.poll();
-      input.composing.range.clear();
-      input.composing = null;
-    }
-  });
-};
-
-TextareaInput.prototype.prepareSelection = function () {
-  // Redraw the selection and/or cursor
-  var cm = this.cm, display = cm.display, doc = cm.doc;
-  var result = prepareSelection(cm);
-
-  // Move the hidden textarea near the cursor to prevent scrolling artifacts
-  if (cm.options.moveInputWithCursor) {
-    var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
-    var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
-    result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
-                                        headPos.top + lineOff.top - wrapOff.top));
-    result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
-                                         headPos.left + lineOff.left - wrapOff.left));
-  }
-
-  return result
-};
-
-TextareaInput.prototype.showSelection = function (drawn) {
-  var cm = this.cm, display = cm.display;
-  removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
-  removeChildrenAndAdd(display.selectionDiv, drawn.selection);
-  if (drawn.teTop != null) {
-    this.wrapper.style.top = drawn.teTop + "px";
-    this.wrapper.style.left = drawn.teLeft + "px";
-  }
-};
-
-// Reset the input to correspond to the selection (or to be empty,
-// when not typing and nothing is selected)
-TextareaInput.prototype.reset = function (typing) {
-  if (this.contextMenuPending || this.composing) { return }
-  var cm = this.cm;
-  if (cm.somethingSelected()) {
-    this.prevInput = "";
-    var content = cm.getSelection();
-    this.textarea.value = content;
-    if (cm.state.focused) { selectInput(this.textarea); }
-    if (ie && ie_version >= 9) { this.hasSelection = content; }
-  } else if (!typing) {
-    this.prevInput = this.textarea.value = "";
-    if (ie && ie_version >= 9) { this.hasSelection = null; }
-  }
-};
-
-TextareaInput.prototype.getField = function () { return this.textarea };
-
-TextareaInput.prototype.supportsTouch = function () { return false };
-
-TextareaInput.prototype.focus = function () {
-  if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
-    try { this.textarea.focus(); }
-    catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
-  }
-};
-
-TextareaInput.prototype.blur = function () { this.textarea.blur(); };
-
-TextareaInput.prototype.resetPosition = function () {
-  this.wrapper.style.top = this.wrapper.style.left = 0;
-};
-
-TextareaInput.prototype.receivedFocus = function () { this.slowPoll(); };
-
-// Poll for input changes, using the normal rate of polling. This
-// runs as long as the editor is focused.
-TextareaInput.prototype.slowPoll = function () {
-    var this$1 = this;
-
-  if (this.pollingFast) { return }
-  this.polling.set(this.cm.options.pollInterval, function () {
-    this$1.poll();
-    if (this$1.cm.state.focused) { this$1.slowPoll(); }
-  });
-};
-
-// When an event has just come in that is likely to add or change
-// something in the input textarea, we poll faster, to ensure that
-// the change appears on the screen quickly.
-TextareaInput.prototype.fastPoll = function () {
-  var missed = false, input = this;
-  input.pollingFast = true;
-  function p() {
-    var changed = input.poll();
-    if (!changed && !missed) {missed = true; input.polling.set(60, p);}
-    else {input.pollingFast = false; input.slowPoll();}
-  }
-  input.polling.set(20, p);
-};
-
-// Read input from the textarea, and update the document to match.
-// When something is selected, it is present in the textarea, and
-// selected (unless it is huge, in which case a placeholder is
-// used). When nothing is selected, the cursor sits after previously
-// seen text (can be empty), which is stored in prevInput (we must
-// not reset the textarea when typing, because that breaks IME).
-TextareaInput.prototype.poll = function () {
-    var this$1 = this;
-
-  var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
-  // Since this is called a *lot*, try to bail out as cheaply as
-  // possible when it is clear that nothing happened. hasSelection
-  // will be the case when there is a lot of text in the textarea,
-  // in which case reading its value would be expensive.
-  if (this.contextMenuPending || !cm.state.focused ||
-      (hasSelection(input) && !prevInput && !this.composing) ||
-      cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
-    { return false }
-
-  var text = input.value;
-  // If nothing changed, bail.
-  if (text == prevInput && !cm.somethingSelected()) { return false }
-  // Work around nonsensical selection resetting in IE9/10, and
-  // inexplicable appearance of private area unicode characters on
-  // some key combos in Mac (#2689).
-  if (ie && ie_version >= 9 && this.hasSelection === text ||
-      mac && /[\uf700-\uf7ff]/.test(text)) {
-    cm.display.input.reset();
-    return false
-  }
-
-  if (cm.doc.sel == cm.display.selForContextMenu) {
-    var first = text.charCodeAt(0);
-    if (first == 0x200b && !prevInput) { prevInput = "\u200b"; }
-    if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") }
-  }
-  // Find the part of the input that is actually new
-  var same = 0, l = Math.min(prevInput.length, text.length);
-  while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same; }
-
-  runInOp(cm, function () {
-    applyTextInput(cm, text.slice(same), prevInput.length - same,
-                   null, this$1.composing ? "*compose" : null);
-
-    // Don't leave long text in the textarea, since it makes further polling slow
-    if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = ""; }
-    else { this$1.prevInput = text; }
-
-    if (this$1.composing) {
-      this$1.composing.range.clear();
-      this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"),
-                                         {className: "CodeMirror-composing"});
-    }
-  });
-  return true
-};
-
-TextareaInput.prototype.ensurePolled = function () {
-  if (this.pollingFast && this.poll()) { this.pollingFast = false; }
-};
-
-TextareaInput.prototype.onKeyPress = function () {
-  if (ie && ie_version >= 9) { this.hasSelection = null; }
-  this.fastPoll();
-};
-
-TextareaInput.prototype.onContextMenu = function (e) {
-  var input = this, cm = input.cm, display = cm.display, te = input.textarea;
-  var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
-  if (!pos || presto) { return } // Opera is difficult.
-
-  // Reset the current text selection only if the click is done outside of the selection
-  // and 'resetSelectionOnContextMenu' option is true.
-  var reset = cm.options.resetSelectionOnContextMenu;
-  if (reset && cm.doc.sel.contains(pos) == -1)
-    { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); }
-
-  var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText;
-  input.wrapper.style.cssText = "position: absolute";
-  var wrapperBox = input.wrapper.getBoundingClientRect();
-  te.style.cssText = "position: absolute; width: 30px; height: 30px;\n      top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n      z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n      outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
-  var oldScrollY;
-  if (webkit) { oldScrollY = window.scrollY; } // Work around Chrome issue (#2712)
-  display.input.focus();
-  if (webkit) { window.scrollTo(null, oldScrollY); }
-  display.input.reset();
-  // Adds "Select all" to context menu in FF
-  if (!cm.somethingSelected()) { te.value = input.prevInput = " "; }
-  input.contextMenuPending = true;
-  display.selForContextMenu = cm.doc.sel;
-  clearTimeout(display.detectingSelectAll);
-
-  // Select-all will be greyed out if there's nothing to select, so
-  // this adds a zero-width space so that we can later check whether
-  // it got selected.
-  function prepareSelectAllHack() {
-    if (te.selectionStart != null) {
-      var selected = cm.somethingSelected();
-      var extval = "\u200b" + (selected ? te.value : "");
-      te.value = "\u21da"; // Used to catch context-menu undo
-      te.value = extval;
-      input.prevInput = selected ? "" : "\u200b";
-      te.selectionStart = 1; te.selectionEnd = extval.length;
-      // Re-set this, in case some other handler touched the
-      // selection in the meantime.
-      display.selForContextMenu = cm.doc.sel;
-    }
-  }
-  function rehide() {
-    input.contextMenuPending = false;
-    input.wrapper.style.cssText = oldWrapperCSS;
-    te.style.cssText = oldCSS;
-    if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); }
-
-    // Try to detect the user choosing select-all
-    if (te.selectionStart != null) {
-      if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack(); }
-      var i = 0, poll = function () {
-        if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
-            te.selectionEnd > 0 && input.prevInput == "\u200b") {
-          operation(cm, selectAll)(cm);
-        } else if (i++ < 10) {
-          display.detectingSelectAll = setTimeout(poll, 500);
-        } else {
-          display.selForContextMenu = null;
-          display.input.reset();
-        }
-      };
-      display.detectingSelectAll = setTimeout(poll, 200);
-    }
-  }
-
-  if (ie && ie_version >= 9) { prepareSelectAllHack(); }
-  if (captureRightClick) {
-    e_stop(e);
-    var mouseup = function () {
-      off(window, "mouseup", mouseup);
-      setTimeout(rehide, 20);
-    };
-    on(window, "mouseup", mouseup);
-  } else {
-    setTimeout(rehide, 50);
-  }
-};
-
-TextareaInput.prototype.readOnlyChanged = function (val) {
-  if (!val) { this.reset(); }
-  this.textarea.disabled = val == "nocursor";
-};
-
-TextareaInput.prototype.setUneditable = function () {};
-
-TextareaInput.prototype.needsContentAttribute = false;
-
-function fromTextArea(textarea, options) {
-  options = options ? copyObj(options) : {};
-  options.value = textarea.value;
-  if (!options.tabindex && textarea.tabIndex)
-    { options.tabindex = textarea.tabIndex; }
-  if (!options.placeholder && textarea.placeholder)
-    { options.placeholder = textarea.placeholder; }
-  // Set autofocus to true if this textarea is focused, or if it has
-  // autofocus and no other element is focused.
-  if (options.autofocus == null) {
-    var hasFocus = activeElt();
-    options.autofocus = hasFocus == textarea ||
-      textarea.getAttribute("autofocus") != null && hasFocus == document.body;
-  }
-
-  function save() {textarea.value = cm.getValue();}
-
-  var realSubmit;
-  if (textarea.form) {
-    on(textarea.form, "submit", save);
-    // Deplorable hack to make the submit method do the right thing.
-    if (!options.leaveSubmitMethodAlone) {
-      var form = textarea.form;
-      realSubmit = form.submit;
-      try {
-        var wrappedSubmit = form.submit = function () {
-          save();
-          form.submit = realSubmit;
-          form.submit();
-          form.submit = wrappedSubmit;
-        };
-      } catch(e) {}
-    }
-  }
-
-  options.finishInit = function (cm) {
-    cm.save = save;
-    cm.getTextArea = function () { return textarea; };
-    cm.toTextArea = function () {
-      cm.toTextArea = isNaN; // Prevent this from being ran twice
-      save();
-      textarea.parentNode.removeChild(cm.getWrapperElement());
-      textarea.style.display = "";
-      if (textarea.form) {
-        off(textarea.form, "submit", save);
-        if (typeof textarea.form.submit == "function")
-          { textarea.form.submit = realSubmit; }
-      }
-    };
-  };
-
-  textarea.style.display = "none";
-  var cm = CodeMirror$1(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); },
-    options);
-  return cm
-}
-
-function addLegacyProps(CodeMirror) {
-  CodeMirror.off = off;
-  CodeMirror.on = on;
-  CodeMirror.wheelEventPixels = wheelEventPixels;
-  CodeMirror.Doc = Doc;
-  CodeMirror.splitLines = splitLinesAuto;
-  CodeMirror.countColumn = countColumn;
-  CodeMirror.findColumn = findColumn;
-  CodeMirror.isWordChar = isWordCharBasic;
-  CodeMirror.Pass = Pass;
-  CodeMirror.signal = signal;
-  CodeMirror.Line = Line;
-  CodeMirror.changeEnd = changeEnd;
-  CodeMirror.scrollbarModel = scrollbarModel;
-  CodeMirror.Pos = Pos;
-  CodeMirror.cmpPos = cmp;
-  CodeMirror.modes = modes;
-  CodeMirror.mimeModes = mimeModes;
-  CodeMirror.resolveMode = resolveMode;
-  CodeMirror.getMode = getMode;
-  CodeMirror.modeExtensions = modeExtensions;
-  CodeMirror.extendMode = extendMode;
-  CodeMirror.copyState = copyState;
-  CodeMirror.startState = startState;
-  CodeMirror.innerMode = innerMode;
-  CodeMirror.commands = commands;
-  CodeMirror.keyMap = keyMap;
-  CodeMirror.keyName = keyName;
-  CodeMirror.isModifierKey = isModifierKey;
-  CodeMirror.lookupKey = lookupKey;
-  CodeMirror.normalizeKeyMap = normalizeKeyMap;
-  CodeMirror.StringStream = StringStream;
-  CodeMirror.SharedTextMarker = SharedTextMarker;
-  CodeMirror.TextMarker = TextMarker;
-  CodeMirror.LineWidget = LineWidget;
-  CodeMirror.e_preventDefault = e_preventDefault;
-  CodeMirror.e_stopPropagation = e_stopPropagation;
-  CodeMirror.e_stop = e_stop;
-  CodeMirror.addClass = addClass;
-  CodeMirror.contains = contains;
-  CodeMirror.rmClass = rmClass;
-  CodeMirror.keyNames = keyNames;
-}
-
-// EDITOR CONSTRUCTOR
-
-defineOptions(CodeMirror$1);
-
-addEditorMethods(CodeMirror$1);
-
-// Set up methods on CodeMirror's prototype to redirect to the editor's document.
-var dontDelegate = "iter insert remove copy getEditor constructor".split(" ");
-for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
-  { CodeMirror$1.prototype[prop] = (function(method) {
-    return function() {return method.apply(this.doc, arguments)}
-  })(Doc.prototype[prop]); } }
-
-eventMixin(Doc);
-
-// INPUT HANDLING
-
-CodeMirror$1.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
-
-// MODE DEFINITION AND QUERYING
-
-// Extra arguments are stored as the mode's dependencies, which is
-// used by (legacy) mechanisms like loadmode.js to automatically
-// load a mode. (Preferred mechanism is the require/define calls.)
-CodeMirror$1.defineMode = function(name/*, mode, …*/) {
-  if (!CodeMirror$1.defaults.mode && name != "null") { CodeMirror$1.defaults.mode = name; }
-  defineMode.apply(this, arguments);
-};
-
-CodeMirror$1.defineMIME = defineMIME;
-
-// Minimal default mode.
-CodeMirror$1.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
-CodeMirror$1.defineMIME("text/plain", "null");
-
-// EXTENSIONS
-
-CodeMirror$1.defineExtension = function (name, func) {
-  CodeMirror$1.prototype[name] = func;
-};
-CodeMirror$1.defineDocExtension = function (name, func) {
-  Doc.prototype[name] = func;
-};
-
-CodeMirror$1.fromTextArea = fromTextArea;
-
-addLegacyProps(CodeMirror$1);
-
-CodeMirror$1.version = "5.31.1";
-
-return CodeMirror$1;
-
-})));
diff --git a/front_end/cm/comment.js b/front_end/cm/comment.js
deleted file mode 100644
index 84c67ed..0000000
--- a/front_end/cm/comment.js
+++ /dev/null
@@ -1,209 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  var noOptions = {};
-  var nonWS = /[^\s\u00a0]/;
-  var Pos = CodeMirror.Pos;
-
-  function firstNonWS(str) {
-    var found = str.search(nonWS);
-    return found == -1 ? 0 : found;
-  }
-
-  CodeMirror.commands.toggleComment = function(cm) {
-    cm.toggleComment();
-  };
-
-  CodeMirror.defineExtension("toggleComment", function(options) {
-    if (!options) options = noOptions;
-    var cm = this;
-    var minLine = Infinity, ranges = this.listSelections(), mode = null;
-    for (var i = ranges.length - 1; i >= 0; i--) {
-      var from = ranges[i].from(), to = ranges[i].to();
-      if (from.line >= minLine) continue;
-      if (to.line >= minLine) to = Pos(minLine, 0);
-      minLine = from.line;
-      if (mode == null) {
-        if (cm.uncomment(from, to, options)) mode = "un";
-        else { cm.lineComment(from, to, options); mode = "line"; }
-      } else if (mode == "un") {
-        cm.uncomment(from, to, options);
-      } else {
-        cm.lineComment(from, to, options);
-      }
-    }
-  });
-
-  // Rough heuristic to try and detect lines that are part of multi-line string
-  function probablyInsideString(cm, pos, line) {
-    return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
-  }
-
-  function getMode(cm, pos) {
-    var mode = cm.getMode()
-    return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
-  }
-
-  CodeMirror.defineExtension("lineComment", function(from, to, options) {
-    if (!options) options = noOptions;
-    var self = this, mode = getMode(self, from);
-    var firstLine = self.getLine(from.line);
-    if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
-
-    var commentString = options.lineComment || mode.lineComment;
-    if (!commentString) {
-      if (options.blockCommentStart || mode.blockCommentStart) {
-        options.fullLines = true;
-        self.blockComment(from, to, options);
-      }
-      return;
-    }
-
-    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
-    var pad = options.padding == null ? " " : options.padding;
-    var blankLines = options.commentBlankLines || from.line == to.line;
-
-    self.operation(function() {
-      if (options.indent) {
-        var baseString = null;
-        for (var i = from.line; i < end; ++i) {
-          var line = self.getLine(i);
-          var whitespace = line.slice(0, firstNonWS(line));
-          if (baseString == null || baseString.length > whitespace.length) {
-            baseString = whitespace;
-          }
-        }
-        for (var i = from.line; i < end; ++i) {
-          var line = self.getLine(i), cut = baseString.length;
-          if (!blankLines && !nonWS.test(line)) continue;
-          if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
-          self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
-        }
-      } else {
-        for (var i = from.line; i < end; ++i) {
-          if (blankLines || nonWS.test(self.getLine(i)))
-            self.replaceRange(commentString + pad, Pos(i, 0));
-        }
-      }
-    });
-  });
-
-  CodeMirror.defineExtension("blockComment", function(from, to, options) {
-    if (!options) options = noOptions;
-    var self = this, mode = getMode(self, from);
-    var startString = options.blockCommentStart || mode.blockCommentStart;
-    var endString = options.blockCommentEnd || mode.blockCommentEnd;
-    if (!startString || !endString) {
-      if ((options.lineComment || mode.lineComment) && options.fullLines != false)
-        self.lineComment(from, to, options);
-      return;
-    }
-    if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
-
-    var end = Math.min(to.line, self.lastLine());
-    if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
-
-    var pad = options.padding == null ? " " : options.padding;
-    if (from.line > end) return;
-
-    self.operation(function() {
-      if (options.fullLines != false) {
-        var lastLineHasText = nonWS.test(self.getLine(end));
-        self.replaceRange(pad + endString, Pos(end));
-        self.replaceRange(startString + pad, Pos(from.line, 0));
-        var lead = options.blockCommentLead || mode.blockCommentLead;
-        if (lead != null) for (var i = from.line + 1; i <= end; ++i)
-          if (i != end || lastLineHasText)
-            self.replaceRange(lead + pad, Pos(i, 0));
-      } else {
-        self.replaceRange(endString, to);
-        self.replaceRange(startString, from);
-      }
-    });
-  });
-
-  CodeMirror.defineExtension("uncomment", function(from, to, options) {
-    if (!options) options = noOptions;
-    var self = this, mode = getMode(self, from);
-    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
-
-    // Try finding line comments
-    var lineString = options.lineComment || mode.lineComment, lines = [];
-    var pad = options.padding == null ? " " : options.padding, didSomething;
-    lineComment: {
-      if (!lineString) break lineComment;
-      for (var i = start; i <= end; ++i) {
-        var line = self.getLine(i);
-        var found = line.indexOf(lineString);
-        if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
-        if (found == -1 && nonWS.test(line)) break lineComment;
-        if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
-        lines.push(line);
-      }
-      self.operation(function() {
-        for (var i = start; i <= end; ++i) {
-          var line = lines[i - start];
-          var pos = line.indexOf(lineString), endPos = pos + lineString.length;
-          if (pos < 0) continue;
-          if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
-          didSomething = true;
-          self.replaceRange("", Pos(i, pos), Pos(i, endPos));
-        }
-      });
-      if (didSomething) return true;
-    }
-
-    // Try block comments
-    var startString = options.blockCommentStart || mode.blockCommentStart;
-    var endString = options.blockCommentEnd || mode.blockCommentEnd;
-    if (!startString || !endString) return false;
-    var lead = options.blockCommentLead || mode.blockCommentLead;
-    var startLine = self.getLine(start), open = startLine.indexOf(startString)
-    if (open == -1) return false
-    var endLine = end == start ? startLine : self.getLine(end)
-    var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
-    var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
-    if (close == -1 ||
-        !/comment/.test(self.getTokenTypeAt(insideStart)) ||
-        !/comment/.test(self.getTokenTypeAt(insideEnd)) ||
-        self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
-      return false;
-
-    // Avoid killing block comments completely outside the selection.
-    // Positions of the last startString before the start of the selection, and the first endString after it.
-    var lastStart = startLine.lastIndexOf(startString, from.ch);
-    var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
-    if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
-    // Positions of the first endString after the end of the selection, and the last startString before it.
-    firstEnd = endLine.indexOf(endString, to.ch);
-    var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
-    lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
-    if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
-
-    self.operation(function() {
-      self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
-                        Pos(end, close + endString.length));
-      var openEnd = open + startString.length;
-      if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
-      self.replaceRange("", Pos(start, open), Pos(start, openEnd));
-      if (lead) for (var i = start + 1; i <= end; ++i) {
-        var line = self.getLine(i), found = line.indexOf(lead);
-        if (found == -1 || nonWS.test(line.slice(0, found))) continue;
-        var foundEnd = found + lead.length;
-        if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
-        self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
-      }
-    });
-    return true;
-  });
-});
diff --git a/front_end/cm/markselection.js b/front_end/cm/markselection.js
deleted file mode 100644
index 1602acc..0000000
--- a/front_end/cm/markselection.js
+++ /dev/null
@@ -1,119 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-// Because sometimes you need to mark the selected *text*.
-//
-// Adds an option 'styleSelectedText' which, when enabled, gives
-// selected text the CSS class given as option value, or
-// "CodeMirror-selectedtext" when the value is not a string.
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
-    var prev = old && old != CodeMirror.Init;
-    if (val && !prev) {
-      cm.state.markedSelection = [];
-      cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
-      reset(cm);
-      cm.on("cursorActivity", onCursorActivity);
-      cm.on("change", onChange);
-    } else if (!val && prev) {
-      cm.off("cursorActivity", onCursorActivity);
-      cm.off("change", onChange);
-      clear(cm);
-      cm.state.markedSelection = cm.state.markedSelectionStyle = null;
-    }
-  });
-
-  function onCursorActivity(cm) {
-    if (cm.state.markedSelection)
-      cm.operation(function() { update(cm); });
-  }
-
-  function onChange(cm) {
-    if (cm.state.markedSelection && cm.state.markedSelection.length)
-      cm.operation(function() { clear(cm); });
-  }
-
-  var CHUNK_SIZE = 8;
-  var Pos = CodeMirror.Pos;
-  var cmp = CodeMirror.cmpPos;
-
-  function coverRange(cm, from, to, addAt) {
-    if (cmp(from, to) == 0) return;
-    var array = cm.state.markedSelection;
-    var cls = cm.state.markedSelectionStyle;
-    for (var line = from.line;;) {
-      var start = line == from.line ? from : Pos(line, 0);
-      var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
-      var end = atEnd ? to : Pos(endLine, 0);
-      var mark = cm.markText(start, end, {className: cls});
-      if (addAt == null) array.push(mark);
-      else array.splice(addAt++, 0, mark);
-      if (atEnd) break;
-      line = endLine;
-    }
-  }
-
-  function clear(cm) {
-    var array = cm.state.markedSelection;
-    for (var i = 0; i < array.length; ++i) array[i].clear();
-    array.length = 0;
-  }
-
-  function reset(cm) {
-    clear(cm);
-    var ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++)
-      coverRange(cm, ranges[i].from(), ranges[i].to());
-  }
-
-  function update(cm) {
-    if (!cm.somethingSelected()) return clear(cm);
-    if (cm.listSelections().length > 1) return reset(cm);
-
-    var from = cm.getCursor("start"), to = cm.getCursor("end");
-
-    var array = cm.state.markedSelection;
-    if (!array.length) return coverRange(cm, from, to);
-
-    var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
-    if (!coverStart || !coverEnd || to.line - from.line <= CHUNK_SIZE ||
-        cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
-      return reset(cm);
-
-    while (cmp(from, coverStart.from) > 0) {
-      array.shift().clear();
-      coverStart = array[0].find();
-    }
-    if (cmp(from, coverStart.from) < 0) {
-      if (coverStart.to.line - from.line < CHUNK_SIZE) {
-        array.shift().clear();
-        coverRange(cm, from, coverStart.to, 0);
-      } else {
-        coverRange(cm, from, coverStart.from, 0);
-      }
-    }
-
-    while (cmp(to, coverEnd.to) < 0) {
-      array.pop().clear();
-      coverEnd = array[array.length - 1].find();
-    }
-    if (cmp(to, coverEnd.to) > 0) {
-      if (to.line - coverEnd.from.line < CHUNK_SIZE) {
-        array.pop().clear();
-        coverRange(cm, coverEnd.from, to);
-      } else {
-        coverRange(cm, coverEnd.to, to);
-      }
-    }
-  }
-});
diff --git a/front_end/cm/matchbrackets.js b/front_end/cm/matchbrackets.js
deleted file mode 100644
index 4d7a230..0000000
--- a/front_end/cm/matchbrackets.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
-    (document.documentMode == null || document.documentMode < 8);
-
-  var Pos = CodeMirror.Pos;
-
-  var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
-
-  function findMatchingBracket(cm, where, config) {
-    var line = cm.getLineHandle(where.line), pos = where.ch - 1;
-    var afterCursor = config && config.afterCursor
-    if (afterCursor == null)
-      afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
-
-    // A cursor is defined as between two characters, but in in vim command mode
-    // (i.e. not insert mode), the cursor is visually represented as a
-    // highlighted box on top of the 2nd character. Otherwise, we allow matches
-    // from before or after the cursor.
-    var match = (!afterCursor && pos >= 0 && matching[line.text.charAt(pos)]) ||
-        matching[line.text.charAt(++pos)];
-    if (!match) return null;
-    var dir = match.charAt(1) == ">" ? 1 : -1;
-    if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
-    var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
-
-    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
-    if (found == null) return null;
-    return {from: Pos(where.line, pos), to: found && found.pos,
-            match: found && found.ch == match.charAt(0), forward: dir > 0};
-  }
-
-  // bracketRegex is used to specify which type of bracket to scan
-  // should be a regexp, e.g. /[[\]]/
-  //
-  // Note: If "where" is on an open bracket, then this bracket is ignored.
-  //
-  // Returns false when no bracket was found, null when it reached
-  // maxScanLines and gave up
-  function scanForBracket(cm, where, dir, style, config) {
-    var maxScanLen = (config && config.maxScanLineLength) || 10000;
-    var maxScanLines = (config && config.maxScanLines) || 1000;
-
-    var stack = [];
-    var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
-    var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
-                          : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
-    for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
-      var line = cm.getLine(lineNo);
-      if (!line) continue;
-      var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
-      if (line.length > maxScanLen) continue;
-      if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
-      for (; pos != end; pos += dir) {
-        var ch = line.charAt(pos);
-        if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
-          var match = matching[ch];
-          if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
-          else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
-          else stack.pop();
-        }
-      }
-    }
-    return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
-  }
-
-  function matchBrackets(cm, autoclear, config) {
-    // Disable brace matching in long lines, since it'll cause hugely slow updates
-    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
-    var marks = [], ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++) {
-      var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
-      if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
-        var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
-        marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
-        if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
-          marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
-      }
-    }
-
-    if (marks.length) {
-      // Kludge to work around the IE bug from issue #1193, where text
-      // input stops going to the textare whever this fires.
-      if (ie_lt8 && cm.state.focused) cm.focus();
-
-      var clear = function() {
-        cm.operation(function() {
-          for (var i = 0; i < marks.length; i++) marks[i].clear();
-        });
-      };
-      if (autoclear) setTimeout(clear, 800);
-      else return clear;
-    }
-  }
-
-  var currentlyHighlighted = null;
-  function doMatchBrackets(cm) {
-    cm.operation(function() {
-      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
-      currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
-    });
-  }
-
-  CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
-    if (old && old != CodeMirror.Init) {
-      cm.off("cursorActivity", doMatchBrackets);
-      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
-    }
-    if (val) {
-      cm.state.matchBrackets = typeof val == "object" ? val : {};
-      cm.on("cursorActivity", doMatchBrackets);
-    }
-  });
-
-  CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
-  CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
-    // Backwards-compatibility kludge
-    if (oldConfig || typeof config == "boolean") {
-      if (!oldConfig) {
-        config = config ? {strict: true} : null
-      } else {
-        oldConfig.strict = config
-        config = oldConfig
-      }
-    }
-    return findMatchingBracket(this, pos, config)
-  });
-  CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
-    return scanForBracket(this, pos, dir, style, config);
-  });
-});
diff --git a/front_end/cm/module.json b/front_end/cm/module.json
deleted file mode 100644
index 7ed2f5e..0000000
--- a/front_end/cm/module.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-    "scripts": [
-        "codemirror.js",
-        "multiplex.js",
-        "matchbrackets.js",
-        "closebrackets.js",
-        "markselection.js",
-        "comment.js",
-        "overlay.js",
-        "activeline.js"
-    ],
-    "skip_compilation": [
-        "codemirror.js",
-        "multiplex.js",
-        "matchbrackets.js",
-        "closebrackets.js",
-        "markselection.js",
-        "comment.js",
-        "overlay.js",
-        "activeline.js"
-    ],
-    "resources": [
-        "codemirror.css"
-    ]
-}
diff --git a/front_end/cm/multiplex.js b/front_end/cm/multiplex.js
deleted file mode 100644
index 3d8b34c..0000000
--- a/front_end/cm/multiplex.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.multiplexingMode = function(outer /*, others */) {
-  // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
-  var others = Array.prototype.slice.call(arguments, 1);
-
-  function indexOf(string, pattern, from, returnEnd) {
-    if (typeof pattern == "string") {
-      var found = string.indexOf(pattern, from);
-      return returnEnd && found > -1 ? found + pattern.length : found;
-    }
-    var m = pattern.exec(from ? string.slice(from) : string);
-    return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1;
-  }
-
-  return {
-    startState: function() {
-      return {
-        outer: CodeMirror.startState(outer),
-        innerActive: null,
-        inner: null
-      };
-    },
-
-    copyState: function(state) {
-      return {
-        outer: CodeMirror.copyState(outer, state.outer),
-        innerActive: state.innerActive,
-        inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
-      };
-    },
-
-    token: function(stream, state) {
-      if (!state.innerActive) {
-        var cutOff = Infinity, oldContent = stream.string;
-        for (var i = 0; i < others.length; ++i) {
-          var other = others[i];
-          var found = indexOf(oldContent, other.open, stream.pos);
-          if (found == stream.pos) {
-            if (!other.parseDelimiters) stream.match(other.open);
-            state.innerActive = other;
-            state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
-            return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
-          } else if (found != -1 && found < cutOff) {
-            cutOff = found;
-          }
-        }
-        if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
-        var outerToken = outer.token(stream, state.outer);
-        if (cutOff != Infinity) stream.string = oldContent;
-        return outerToken;
-      } else {
-        var curInner = state.innerActive, oldContent = stream.string;
-        if (!curInner.close && stream.sol()) {
-          state.innerActive = state.inner = null;
-          return this.token(stream, state);
-        }
-        var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
-        if (found == stream.pos && !curInner.parseDelimiters) {
-          stream.match(curInner.close);
-          state.innerActive = state.inner = null;
-          return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
-        }
-        if (found > -1) stream.string = oldContent.slice(0, found);
-        var innerToken = curInner.mode.token(stream, state.inner);
-        if (found > -1) stream.string = oldContent;
-
-        if (found == stream.pos && curInner.parseDelimiters)
-          state.innerActive = state.inner = null;
-
-        if (curInner.innerStyle) {
-          if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
-          else innerToken = curInner.innerStyle;
-        }
-
-        return innerToken;
-      }
-    },
-
-    indent: function(state, textAfter) {
-      var mode = state.innerActive ? state.innerActive.mode : outer;
-      if (!mode.indent) return CodeMirror.Pass;
-      return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
-    },
-
-    blankLine: function(state) {
-      var mode = state.innerActive ? state.innerActive.mode : outer;
-      if (mode.blankLine) {
-        mode.blankLine(state.innerActive ? state.inner : state.outer);
-      }
-      if (!state.innerActive) {
-        for (var i = 0; i < others.length; ++i) {
-          var other = others[i];
-          if (other.open === "\n") {
-            state.innerActive = other;
-            state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0);
-          }
-        }
-      } else if (state.innerActive.close === "\n") {
-        state.innerActive = state.inner = null;
-      }
-    },
-
-    electricChars: outer.electricChars,
-
-    innerMode: function(state) {
-      return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
-    }
-  };
-};
-
-});
diff --git a/front_end/cm/overlay.js b/front_end/cm/overlay.js
deleted file mode 100644
index 4a9f99a..0000000
--- a/front_end/cm/overlay.js
+++ /dev/null
@@ -1,90 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-// Utility function that allows modes to be combined. The mode given
-// as the base argument takes care of most of the normal mode
-// functionality, but a second (typically simple) mode is used, which
-// can override the style of text. Both modes get to parse all of the
-// text, but when both assign a non-null style to a piece of code, the
-// overlay wins, unless the combine argument was true and not overridden,
-// or state.overlay.combineTokens was true, in which case the styles are
-// combined.
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.overlayMode = function(base, overlay, combine) {
-  return {
-    startState: function() {
-      return {
-        base: CodeMirror.startState(base),
-        overlay: CodeMirror.startState(overlay),
-        basePos: 0, baseCur: null,
-        overlayPos: 0, overlayCur: null,
-        streamSeen: null
-      };
-    },
-    copyState: function(state) {
-      return {
-        base: CodeMirror.copyState(base, state.base),
-        overlay: CodeMirror.copyState(overlay, state.overlay),
-        basePos: state.basePos, baseCur: null,
-        overlayPos: state.overlayPos, overlayCur: null
-      };
-    },
-
-    token: function(stream, state) {
-      if (stream != state.streamSeen ||
-          Math.min(state.basePos, state.overlayPos) < stream.start) {
-        state.streamSeen = stream;
-        state.basePos = state.overlayPos = stream.start;
-      }
-
-      if (stream.start == state.basePos) {
-        state.baseCur = base.token(stream, state.base);
-        state.basePos = stream.pos;
-      }
-      if (stream.start == state.overlayPos) {
-        stream.pos = stream.start;
-        state.overlayCur = overlay.token(stream, state.overlay);
-        state.overlayPos = stream.pos;
-      }
-      stream.pos = Math.min(state.basePos, state.overlayPos);
-
-      // state.overlay.combineTokens always takes precedence over combine,
-      // unless set to null
-      if (state.overlayCur == null) return state.baseCur;
-      else if (state.baseCur != null &&
-               state.overlay.combineTokens ||
-               combine && state.overlay.combineTokens == null)
-        return state.baseCur + " " + state.overlayCur;
-      else return state.overlayCur;
-    },
-
-    indent: base.indent && function(state, textAfter) {
-      return base.indent(state.base, textAfter);
-    },
-    electricChars: base.electricChars,
-
-    innerMode: function(state) { return {state: state.base, mode: base}; },
-
-    blankLine: function(state) {
-      var baseToken, overlayToken;
-      if (base.blankLine) baseToken = base.blankLine(state.base);
-      if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay);
-
-      return overlayToken == null ?
-        baseToken :
-        (combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken);
-    }
-  };
-};
-
-});
diff --git a/front_end/cm_headless/headlesscodemirror.js b/front_end/cm_headless/headlesscodemirror.js
deleted file mode 100644
index f7aec5b..0000000
--- a/front_end/cm_headless/headlesscodemirror.js
+++ /dev/null
@@ -1,162 +0,0 @@
-// Content of the function is equal to runmode-standalone.js file
-// from CodeMirror distribution
-(function(window) {
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-window.CodeMirror = {};
-
-(function() {
-"use strict";
-
-function splitLines(string){ return string.split(/\r?\n|\r/); };
-
-function StringStream(string) {
-  this.pos = this.start = 0;
-  this.string = string;
-  this.lineStart = 0;
-}
-StringStream.prototype = {
-  eol: function() {return this.pos >= this.string.length;},
-  sol: function() {return this.pos == 0;},
-  peek: function() {return this.string.charAt(this.pos) || null;},
-  next: function() {
-    if (this.pos < this.string.length)
-      return this.string.charAt(this.pos++);
-  },
-  eat: function(match) {
-    var ch = this.string.charAt(this.pos);
-    if (typeof match == "string") var ok = ch == match;
-    else var ok = ch && (match.test ? match.test(ch) : match(ch));
-    if (ok) {++this.pos; return ch;}
-  },
-  eatWhile: function(match) {
-    var start = this.pos;
-    while (this.eat(match)){}
-    return this.pos > start;
-  },
-  eatSpace: function() {
-    var start = this.pos;
-    while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
-    return this.pos > start;
-  },
-  skipToEnd: function() {this.pos = this.string.length;},
-  skipTo: function(ch) {
-    var found = this.string.indexOf(ch, this.pos);
-    if (found > -1) {this.pos = found; return true;}
-  },
-  backUp: function(n) {this.pos -= n;},
-  column: function() {return this.start - this.lineStart;},
-  indentation: function() {return 0;},
-  match: function(pattern, consume, caseInsensitive) {
-    if (typeof pattern == "string") {
-      var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
-      var substr = this.string.substr(this.pos, pattern.length);
-      if (cased(substr) == cased(pattern)) {
-        if (consume !== false) this.pos += pattern.length;
-        return true;
-      }
-    } else {
-      var match = this.string.slice(this.pos).match(pattern);
-      if (match && match.index > 0) return null;
-      if (match && consume !== false) this.pos += match[0].length;
-      return match;
-    }
-  },
-  current: function(){return this.string.slice(this.start, this.pos);},
-  hideFirstChars: function(n, inner) {
-    this.lineStart += n;
-    try { return inner(); }
-    finally { this.lineStart -= n; }
-  },
-  lookAhead: function() { return null }
-};
-CodeMirror.StringStream = StringStream;
-
-CodeMirror.startState = function (mode, a1, a2) {
-  return mode.startState ? mode.startState(a1, a2) : true;
-};
-
-var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
-CodeMirror.defineMode = function (name, mode) {
-  if (arguments.length > 2)
-    mode.dependencies = Array.prototype.slice.call(arguments, 2);
-  modes[name] = mode;
-};
-CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
-CodeMirror.resolveMode = function(spec) {
-  if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
-    spec = mimeModes[spec];
-  } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
-    spec = mimeModes[spec.name];
-  }
-  if (typeof spec == "string") return {name: spec};
-  else return spec || {name: "null"};
-};
-CodeMirror.getMode = function (options, spec) {
-  spec = CodeMirror.resolveMode(spec);
-  var mfactory = modes[spec.name];
-  if (!mfactory) throw new Error("Unknown mode: " + spec);
-  return mfactory(options, spec);
-};
-CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
-CodeMirror.defineMode("null", function() {
-  return {token: function(stream) {stream.skipToEnd();}};
-});
-CodeMirror.defineMIME("text/plain", "null");
-
-CodeMirror.runMode = function (string, modespec, callback, options) {
-  var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
-
-  if (callback.nodeType == 1) {
-    var tabSize = (options && options.tabSize) || 4;
-    var node = callback, col = 0;
-    node.innerHTML = "";
-    callback = function (text, style) {
-      if (text == "\n") {
-        node.appendChild(document.createElement("br"));
-        col = 0;
-        return;
-      }
-      var content = "";
-      // replace tabs
-      for (var pos = 0; ;) {
-        var idx = text.indexOf("\t", pos);
-        if (idx == -1) {
-          content += text.slice(pos);
-          col += text.length - pos;
-          break;
-        } else {
-          col += idx - pos;
-          content += text.slice(pos, idx);
-          var size = tabSize - col % tabSize;
-          col += size;
-          for (var i = 0; i < size; ++i) content += " ";
-          pos = idx + 1;
-        }
-      }
-
-      if (style) {
-        var sp = node.appendChild(document.createElement("span"));
-        sp.className = "cm-" + style.replace(/ +/g, " cm-");
-        sp.appendChild(document.createTextNode(content));
-      } else {
-        node.appendChild(document.createTextNode(content));
-      }
-    };
-  }
-
-  var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
-  for (var i = 0, e = lines.length; i < e; ++i) {
-    if (i) callback("\n");
-    var stream = new CodeMirror.StringStream(lines[i]);
-    if (!stream.string && mode.blankLine) mode.blankLine(state);
-    while (!stream.eol()) {
-      var style = mode.token(stream, state);
-      callback(stream.current(), style, i, stream.start, state);
-      stream.start = stream.pos;
-    }
-  }
-};
-})();
-}(this))
diff --git a/front_end/cm_headless/module.json b/front_end/cm_headless/module.json
deleted file mode 100644
index daf8483..0000000
--- a/front_end/cm_headless/module.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "scripts": [
-        "headlesscodemirror.js"
-    ],
-    "skip_compilation": [
-        "headlesscodemirror.js"
-    ]
-}
diff --git a/front_end/cm_modes/DefaultCodeMirrorMimeMode.js b/front_end/cm_modes/DefaultCodeMirrorMimeMode.js
deleted file mode 100644
index 31497d4..0000000
--- a/front_end/cm_modes/DefaultCodeMirrorMimeMode.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @constructor
- * @implements {TextEditor.CodeMirrorMimeMode}
- */
-CmModes.DefaultCodeMirrorMimeMode = function()
-{
-}
-
-CmModes.DefaultCodeMirrorMimeMode.prototype = {
-    /**
-     * @param {!Runtime.Extension} extension
-     * @override
-     */
-    install: function(extension)
-    {
-        var modeFileName = extension.descriptor()["fileName"];
-        var modeContent = extension.module().resource(modeFileName);
-        self.eval(modeContent + "\n//# sourceURL=" + modeFileName);
-    }
-}
diff --git a/front_end/cm_modes/LICENSE b/front_end/cm_modes/LICENSE
deleted file mode 100644
index 7661321..0000000
--- a/front_end/cm_modes/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2016 by Marijn Haverbeke <marijnh@gmail.com> and others
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/front_end/cm_modes/PRESUBMIT.py b/front_end/cm_modes/PRESUBMIT.py
deleted file mode 100644
index 57ab9d0..0000000
--- a/front_end/cm_modes/PRESUBMIT.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-def _CheckCodeMirrorChanges(input_api, output_api):
-    errorText = ("ERROR: Attempt to modify CodeMirror. The only allowed changes are "
-                 "rolls from the upstream (http://codemirror.net). If this is a roll, "
-                 "make sure you mention 'roll CodeMirror' (no quotes) in the change description.\n"
-                 "CodeMirror rolling instructions:\n"
-                 "    src/third_party/WebKit/Source/devtools/front_end/cm/README.md")
-    changeDescription = input_api.change.DescriptionText()
-    errors = []
-    if "roll codemirror" not in changeDescription.lower():
-        errors.append(output_api.PresubmitError(errorText))
-    return errors
-
-
-def CheckChangeOnUpload(input_api, output_api):
-    results = []
-    results.extend(_CheckCodeMirrorChanges(input_api, output_api))
-    return results
diff --git a/front_end/cm_modes/clike.js b/front_end/cm_modes/clike.js
deleted file mode 100644
index 02a8531..0000000
--- a/front_end/cm_modes/clike.js
+++ /dev/null
@@ -1,790 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-function Context(indented, column, type, info, align, prev) {
-  this.indented = indented;
-  this.column = column;
-  this.type = type;
-  this.info = info;
-  this.align = align;
-  this.prev = prev;
-}
-function pushContext(state, col, type, info) {
-  var indent = state.indented;
-  if (state.context && state.context.type == "statement" && type != "statement")
-    indent = state.context.indented;
-  return state.context = new Context(indent, col, type, info, null, state.context);
-}
-function popContext(state) {
-  var t = state.context.type;
-  if (t == ")" || t == "]" || t == "}")
-    state.indented = state.context.indented;
-  return state.context = state.context.prev;
-}
-
-function typeBefore(stream, state, pos) {
-  if (state.prevToken == "variable" || state.prevToken == "type") return true;
-  if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
-  if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
-}
-
-function isTopScope(context) {
-  for (;;) {
-    if (!context || context.type == "top") return true;
-    if (context.type == "}" && context.prev.info != "namespace") return false;
-    context = context.prev;
-  }
-}
-
-CodeMirror.defineMode("clike", function(config, parserConfig) {
-  var indentUnit = config.indentUnit,
-      statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
-      dontAlignCalls = parserConfig.dontAlignCalls,
-      keywords = parserConfig.keywords || {},
-      types = parserConfig.types || {},
-      builtin = parserConfig.builtin || {},
-      blockKeywords = parserConfig.blockKeywords || {},
-      defKeywords = parserConfig.defKeywords || {},
-      atoms = parserConfig.atoms || {},
-      hooks = parserConfig.hooks || {},
-      multiLineStrings = parserConfig.multiLineStrings,
-      indentStatements = parserConfig.indentStatements !== false,
-      indentSwitch = parserConfig.indentSwitch !== false,
-      namespaceSeparator = parserConfig.namespaceSeparator,
-      isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
-      numberStart = parserConfig.numberStart || /[\d\.]/,
-      number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
-      isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
-      isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/;
-
-  var curPunc, isDefKeyword;
-
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (hooks[ch]) {
-      var result = hooks[ch](stream, state);
-      if (result !== false) return result;
-    }
-    if (ch == '"' || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    }
-    if (isPunctuationChar.test(ch)) {
-      curPunc = ch;
-      return null;
-    }
-    if (numberStart.test(ch)) {
-      stream.backUp(1)
-      if (stream.match(number)) return "number"
-      stream.next()
-    }
-    if (ch == "/") {
-      if (stream.eat("*")) {
-        state.tokenize = tokenComment;
-        return tokenComment(stream, state);
-      }
-      if (stream.eat("/")) {
-        stream.skipToEnd();
-        return "comment";
-      }
-    }
-    if (isOperatorChar.test(ch)) {
-      while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
-      return "operator";
-    }
-    stream.eatWhile(isIdentifierChar);
-    if (namespaceSeparator) while (stream.match(namespaceSeparator))
-      stream.eatWhile(isIdentifierChar);
-
-    var cur = stream.current();
-    if (contains(keywords, cur)) {
-      if (contains(blockKeywords, cur)) curPunc = "newstatement";
-      if (contains(defKeywords, cur)) isDefKeyword = true;
-      return "keyword";
-    }
-    if (contains(types, cur)) return "type";
-    if (contains(builtin, cur)) {
-      if (contains(blockKeywords, cur)) curPunc = "newstatement";
-      return "builtin";
-    }
-    if (contains(atoms, cur)) return "atom";
-    return "variable";
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, next, end = false;
-      while ((next = stream.next()) != null) {
-        if (next == quote && !escaped) {end = true; break;}
-        escaped = !escaped && next == "\\";
-      }
-      if (end || !(escaped || multiLineStrings))
-        state.tokenize = null;
-      return "string";
-    };
-  }
-
-  function tokenComment(stream, state) {
-    var maybeEnd = false, ch;
-    while (ch = stream.next()) {
-      if (ch == "/" && maybeEnd) {
-        state.tokenize = null;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return "comment";
-  }
-
-  function maybeEOL(stream, state) {
-    if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
-      state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
-  }
-
-  // Interface
-
-  return {
-    startState: function(basecolumn) {
-      return {
-        tokenize: null,
-        context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false),
-        indented: 0,
-        startOfLine: true,
-        prevToken: null
-      };
-    },
-
-    token: function(stream, state) {
-      var ctx = state.context;
-      if (stream.sol()) {
-        if (ctx.align == null) ctx.align = false;
-        state.indented = stream.indentation();
-        state.startOfLine = true;
-      }
-      if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
-      curPunc = isDefKeyword = null;
-      var style = (state.tokenize || tokenBase)(stream, state);
-      if (style == "comment" || style == "meta") return style;
-      if (ctx.align == null) ctx.align = true;
-
-      if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false)))
-        while (state.context.type == "statement") popContext(state);
-      else if (curPunc == "{") pushContext(state, stream.column(), "}");
-      else if (curPunc == "[") pushContext(state, stream.column(), "]");
-      else if (curPunc == "(") pushContext(state, stream.column(), ")");
-      else if (curPunc == "}") {
-        while (ctx.type == "statement") ctx = popContext(state);
-        if (ctx.type == "}") ctx = popContext(state);
-        while (ctx.type == "statement") ctx = popContext(state);
-      }
-      else if (curPunc == ctx.type) popContext(state);
-      else if (indentStatements &&
-               (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
-                (ctx.type == "statement" && curPunc == "newstatement"))) {
-        pushContext(state, stream.column(), "statement", stream.current());
-      }
-
-      if (style == "variable" &&
-          ((state.prevToken == "def" ||
-            (parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
-             isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
-        style = "def";
-
-      if (hooks.token) {
-        var result = hooks.token(stream, state, style);
-        if (result !== undefined) style = result;
-      }
-
-      if (style == "def" && parserConfig.styleDefs === false) style = "variable";
-
-      state.startOfLine = false;
-      state.prevToken = isDefKeyword ? "def" : style || curPunc;
-      maybeEOL(stream, state);
-      return style;
-    },
-
-    indent: function(state, textAfter) {
-      if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
-      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
-      if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
-      if (parserConfig.dontIndentStatements)
-        while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
-          ctx = ctx.prev
-      if (hooks.indent) {
-        var hook = hooks.indent(state, ctx, textAfter);
-        if (typeof hook == "number") return hook
-      }
-      var closing = firstChar == ctx.type;
-      var switchBlock = ctx.prev && ctx.prev.info == "switch";
-      if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
-        while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
-        return ctx.indented
-      }
-      if (ctx.type == "statement")
-        return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
-      if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
-        return ctx.column + (closing ? 0 : 1);
-      if (ctx.type == ")" && !closing)
-        return ctx.indented + statementIndentUnit;
-
-      return ctx.indented + (closing ? 0 : indentUnit) +
-        (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
-    },
-
-    electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
-    blockCommentStart: "/*",
-    blockCommentEnd: "*/",
-    blockCommentContinue: " * ",
-    lineComment: "//",
-    fold: "brace"
-  };
-});
-
-  function words(str) {
-    var obj = {}, words = str.split(" ");
-    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
-    return obj;
-  }
-  function contains(words, word) {
-    if (typeof words === "function") {
-      return words(word);
-    } else {
-      return words.propertyIsEnumerable(word);
-    }
-  }
-  var cKeywords = "auto if break case register continue return default do sizeof " +
-    "static else struct switch extern typedef union for goto while enum const volatile";
-  var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
-
-  function cppHook(stream, state) {
-    if (!state.startOfLine) return false
-    for (var ch, next = null; ch = stream.peek();) {
-      if (ch == "\\" && stream.match(/^.$/)) {
-        next = cppHook
-        break
-      } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
-        break
-      }
-      stream.next()
-    }
-    state.tokenize = next
-    return "meta"
-  }
-
-  function pointerHook(_stream, state) {
-    if (state.prevToken == "type") return "type";
-    return false;
-  }
-
-  function cpp14Literal(stream) {
-    stream.eatWhile(/[\w\.']/);
-    return "number";
-  }
-
-  function cpp11StringHook(stream, state) {
-    stream.backUp(1);
-    // Raw strings.
-    if (stream.match(/(R|u8R|uR|UR|LR)/)) {
-      var match = stream.match(/"([^\s\\()]{0,16})\(/);
-      if (!match) {
-        return false;
-      }
-      state.cpp11RawStringDelim = match[1];
-      state.tokenize = tokenRawString;
-      return tokenRawString(stream, state);
-    }
-    // Unicode strings/chars.
-    if (stream.match(/(u8|u|U|L)/)) {
-      if (stream.match(/["']/, /* eat */ false)) {
-        return "string";
-      }
-      return false;
-    }
-    // Ignore this hook.
-    stream.next();
-    return false;
-  }
-
-  function cppLooksLikeConstructor(word) {
-    var lastTwo = /(\w+)::~?(\w+)$/.exec(word);
-    return lastTwo && lastTwo[1] == lastTwo[2];
-  }
-
-  // C#-style strings where "" escapes a quote.
-  function tokenAtString(stream, state) {
-    var next;
-    while ((next = stream.next()) != null) {
-      if (next == '"' && !stream.eat('"')) {
-        state.tokenize = null;
-        break;
-      }
-    }
-    return "string";
-  }
-
-  // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
-  // <delim> can be a string up to 16 characters long.
-  function tokenRawString(stream, state) {
-    // Escape characters that have special regex meanings.
-    var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
-    var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
-    if (match)
-      state.tokenize = null;
-    else
-      stream.skipToEnd();
-    return "string";
-  }
-
-  function def(mimes, mode) {
-    if (typeof mimes == "string") mimes = [mimes];
-    var words = [];
-    function add(obj) {
-      if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
-        words.push(prop);
-    }
-    add(mode.keywords);
-    add(mode.types);
-    add(mode.builtin);
-    add(mode.atoms);
-    if (words.length) {
-      mode.helperType = mimes[0];
-      CodeMirror.registerHelper("hintWords", mimes[0], words);
-    }
-
-    for (var i = 0; i < mimes.length; ++i)
-      CodeMirror.defineMIME(mimes[i], mode);
-  }
-
-  def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
-    name: "clike",
-    keywords: words(cKeywords),
-    types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
-                 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
-                 "uint32_t uint64_t"),
-    blockKeywords: words("case do else for if switch while struct"),
-    defKeywords: words("struct"),
-    typeFirstDefinitions: true,
-    atoms: words("null true false"),
-    hooks: {"#": cppHook, "*": pointerHook},
-    modeProps: {fold: ["brace", "include"]}
-  });
-
-  def(["text/x-c++src", "text/x-c++hdr"], {
-    name: "clike",
-    keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
-                    "static_cast typeid catch operator template typename class friend private " +
-                    "this using const_cast inline public throw virtual delete mutable protected " +
-                    "alignas alignof constexpr decltype nullptr noexcept thread_local final " +
-                    "static_assert override"),
-    types: words(cTypes + " bool wchar_t"),
-    blockKeywords: words("catch class do else finally for if struct switch try while"),
-    defKeywords: words("class namespace struct enum union"),
-    typeFirstDefinitions: true,
-    atoms: words("true false null"),
-    dontIndentStatements: /^template$/,
-    isIdentifierChar: /[\w\$_~\xa1-\uffff]/,
-    hooks: {
-      "#": cppHook,
-      "*": pointerHook,
-      "u": cpp11StringHook,
-      "U": cpp11StringHook,
-      "L": cpp11StringHook,
-      "R": cpp11StringHook,
-      "0": cpp14Literal,
-      "1": cpp14Literal,
-      "2": cpp14Literal,
-      "3": cpp14Literal,
-      "4": cpp14Literal,
-      "5": cpp14Literal,
-      "6": cpp14Literal,
-      "7": cpp14Literal,
-      "8": cpp14Literal,
-      "9": cpp14Literal,
-      token: function(stream, state, style) {
-        if (style == "variable" && stream.peek() == "(" &&
-            (state.prevToken == ";" || state.prevToken == null ||
-             state.prevToken == "}") &&
-            cppLooksLikeConstructor(stream.current()))
-          return "def";
-      }
-    },
-    namespaceSeparator: "::",
-    modeProps: {fold: ["brace", "include"]}
-  });
-
-  def("text/x-java", {
-    name: "clike",
-    keywords: words("abstract assert break case catch class const continue default " +
-                    "do else enum extends final finally float for goto if implements import " +
-                    "instanceof interface native new package private protected public " +
-                    "return static strictfp super switch synchronized this throw throws transient " +
-                    "try volatile while @interface"),
-    types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
-                 "Integer Long Number Object Short String StringBuffer StringBuilder Void"),
-    blockKeywords: words("catch class do else finally for if switch try while"),
-    defKeywords: words("class interface enum @interface"),
-    typeFirstDefinitions: true,
-    atoms: words("true false null"),
-    number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
-    hooks: {
-      "@": function(stream) {
-        // Don't match the @interface keyword.
-        if (stream.match('interface', false)) return false;
-
-        stream.eatWhile(/[\w\$_]/);
-        return "meta";
-      }
-    },
-    modeProps: {fold: ["brace", "import"]}
-  });
-
-  def("text/x-csharp", {
-    name: "clike",
-    keywords: words("abstract as async await base break case catch checked class const continue" +
-                    " default delegate do else enum event explicit extern finally fixed for" +
-                    " foreach goto if implicit in interface internal is lock namespace new" +
-                    " operator out override params private protected public readonly ref return sealed" +
-                    " sizeof stackalloc static struct switch this throw try typeof unchecked" +
-                    " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
-                    " global group into join let orderby partial remove select set value var yield"),
-    types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
-                 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
-                 " UInt64 bool byte char decimal double short int long object"  +
-                 " sbyte float string ushort uint ulong"),
-    blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
-    defKeywords: words("class interface namespace struct var"),
-    typeFirstDefinitions: true,
-    atoms: words("true false null"),
-    hooks: {
-      "@": function(stream, state) {
-        if (stream.eat('"')) {
-          state.tokenize = tokenAtString;
-          return tokenAtString(stream, state);
-        }
-        stream.eatWhile(/[\w\$_]/);
-        return "meta";
-      }
-    }
-  });
-
-  function tokenTripleString(stream, state) {
-    var escaped = false;
-    while (!stream.eol()) {
-      if (!escaped && stream.match('"""')) {
-        state.tokenize = null;
-        break;
-      }
-      escaped = stream.next() == "\\" && !escaped;
-    }
-    return "string";
-  }
-
-  def("text/x-scala", {
-    name: "clike",
-    keywords: words(
-
-      /* scala */
-      "abstract case catch class def do else extends final finally for forSome if " +
-      "implicit import lazy match new null object override package private protected return " +
-      "sealed super this throw trait try type val var while with yield _ " +
-
-      /* package scala */
-      "assert assume require print println printf readLine readBoolean readByte readShort " +
-      "readChar readInt readLong readFloat readDouble"
-    ),
-    types: words(
-      "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
-      "Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " +
-      "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
-      "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
-      "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
-
-      /* package java.lang */
-      "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
-      "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
-      "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
-      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
-    ),
-    multiLineStrings: true,
-    blockKeywords: words("catch class enum do else finally for forSome if match switch try while"),
-    defKeywords: words("class enum def object package trait type val var"),
-    atoms: words("true false null"),
-    indentStatements: false,
-    indentSwitch: false,
-    isOperatorChar: /[+\-*&%=<>!?|\/#:@]/,
-    hooks: {
-      "@": function(stream) {
-        stream.eatWhile(/[\w\$_]/);
-        return "meta";
-      },
-      '"': function(stream, state) {
-        if (!stream.match('""')) return false;
-        state.tokenize = tokenTripleString;
-        return state.tokenize(stream, state);
-      },
-      "'": function(stream) {
-        stream.eatWhile(/[\w\$_\xa1-\uffff]/);
-        return "atom";
-      },
-      "=": function(stream, state) {
-        var cx = state.context
-        if (cx.type == "}" && cx.align && stream.eat(">")) {
-          state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
-          return "operator"
-        } else {
-          return false
-        }
-      }
-    },
-    modeProps: {closeBrackets: {triples: '"'}}
-  });
-
-  function tokenKotlinString(tripleString){
-    return function (stream, state) {
-      var escaped = false, next, end = false;
-      while (!stream.eol()) {
-        if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
-        if (tripleString && stream.match('"""')) {end = true; break;}
-        next = stream.next();
-        if(!escaped && next == "$" && stream.match('{'))
-          stream.skipTo("}");
-        escaped = !escaped && next == "\\" && !tripleString;
-      }
-      if (end || !tripleString)
-        state.tokenize = null;
-      return "string";
-    }
-  }
-
-  def("text/x-kotlin", {
-    name: "clike",
-    keywords: words(
-      /*keywords*/
-      "package as typealias class interface this super val " +
-      "var fun for is in This throw return " +
-      "break continue object if else while do try when !in !is as? " +
-
-      /*soft keywords*/
-      "file import where by get set abstract enum open inner override private public internal " +
-      "protected catch finally out final vararg reified dynamic companion constructor init " +
-      "sealed field property receiver param sparam lateinit data inline noinline tailrec " +
-      "external annotation crossinline const operator infix suspend"
-    ),
-    types: words(
-      /* package java.lang */
-      "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
-      "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
-      "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
-      "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
-    ),
-    intendSwitch: false,
-    indentStatements: false,
-    multiLineStrings: true,
-    number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
-    blockKeywords: words("catch class do else finally for if where try while enum"),
-    defKeywords: words("class val var object interface fun"),
-    atoms: words("true false null this"),
-    hooks: {
-      '"': function(stream, state) {
-        state.tokenize = tokenKotlinString(stream.match('""'));
-        return state.tokenize(stream, state);
-      }
-    },
-    modeProps: {closeBrackets: {triples: '"'}}
-  });
-
-  def(["x-shader/x-vertex", "x-shader/x-fragment"], {
-    name: "clike",
-    keywords: words("sampler1D sampler2D sampler3D samplerCube " +
-                    "sampler1DShadow sampler2DShadow " +
-                    "const attribute uniform varying " +
-                    "break continue discard return " +
-                    "for while do if else struct " +
-                    "in out inout"),
-    types: words("float int bool void " +
-                 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
-                 "mat2 mat3 mat4"),
-    blockKeywords: words("for while do if else struct"),
-    builtin: words("radians degrees sin cos tan asin acos atan " +
-                    "pow exp log exp2 sqrt inversesqrt " +
-                    "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
-                    "length distance dot cross normalize ftransform faceforward " +
-                    "reflect refract matrixCompMult " +
-                    "lessThan lessThanEqual greaterThan greaterThanEqual " +
-                    "equal notEqual any all not " +
-                    "texture1D texture1DProj texture1DLod texture1DProjLod " +
-                    "texture2D texture2DProj texture2DLod texture2DProjLod " +
-                    "texture3D texture3DProj texture3DLod texture3DProjLod " +
-                    "textureCube textureCubeLod " +
-                    "shadow1D shadow2D shadow1DProj shadow2DProj " +
-                    "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
-                    "dFdx dFdy fwidth " +
-                    "noise1 noise2 noise3 noise4"),
-    atoms: words("true false " +
-                "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
-                "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
-                "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
-                "gl_FogCoord gl_PointCoord " +
-                "gl_Position gl_PointSize gl_ClipVertex " +
-                "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
-                "gl_TexCoord gl_FogFragCoord " +
-                "gl_FragCoord gl_FrontFacing " +
-                "gl_FragData gl_FragDepth " +
-                "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
-                "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
-                "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
-                "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
-                "gl_ProjectionMatrixInverseTranspose " +
-                "gl_ModelViewProjectionMatrixInverseTranspose " +
-                "gl_TextureMatrixInverseTranspose " +
-                "gl_NormalScale gl_DepthRange gl_ClipPlane " +
-                "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
-                "gl_FrontLightModelProduct gl_BackLightModelProduct " +
-                "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
-                "gl_FogParameters " +
-                "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
-                "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
-                "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
-                "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
-                "gl_MaxDrawBuffers"),
-    indentSwitch: false,
-    hooks: {"#": cppHook},
-    modeProps: {fold: ["brace", "include"]}
-  });
-
-  def("text/x-nesc", {
-    name: "clike",
-    keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
-                    "implementation includes interface module new norace nx_struct nx_union post provides " +
-                    "signal task uses abstract extends"),
-    types: words(cTypes),
-    blockKeywords: words("case do else for if switch while struct"),
-    atoms: words("null true false"),
-    hooks: {"#": cppHook},
-    modeProps: {fold: ["brace", "include"]}
-  });
-
-  def("text/x-objectivec", {
-    name: "clike",
-    keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in " +
-                    "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
-    types: words(cTypes),
-    atoms: words("YES NO NULL NILL ON OFF true false"),
-    hooks: {
-      "@": function(stream) {
-        stream.eatWhile(/[\w\$]/);
-        return "keyword";
-      },
-      "#": cppHook,
-      indent: function(_state, ctx, textAfter) {
-        if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
-      }
-    },
-    modeProps: {fold: "brace"}
-  });
-
-  def("text/x-squirrel", {
-    name: "clike",
-    keywords: words("base break clone continue const default delete enum extends function in class" +
-                    " foreach local resume return this throw typeof yield constructor instanceof static"),
-    types: words(cTypes),
-    blockKeywords: words("case catch class else for foreach if switch try while"),
-    defKeywords: words("function local class"),
-    typeFirstDefinitions: true,
-    atoms: words("true false null"),
-    hooks: {"#": cppHook},
-    modeProps: {fold: ["brace", "include"]}
-  });
-
-  // Ceylon Strings need to deal with interpolation
-  var stringTokenizer = null;
-  function tokenCeylonString(type) {
-    return function(stream, state) {
-      var escaped = false, next, end = false;
-      while (!stream.eol()) {
-        if (!escaped && stream.match('"') &&
-              (type == "single" || stream.match('""'))) {
-          end = true;
-          break;
-        }
-        if (!escaped && stream.match('``')) {
-          stringTokenizer = tokenCeylonString(type);
-          end = true;
-          break;
-        }
-        next = stream.next();
-        escaped = type == "single" && !escaped && next == "\\";
-      }
-      if (end)
-          state.tokenize = null;
-      return "string";
-    }
-  }
-
-  def("text/x-ceylon", {
-    name: "clike",
-    keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
-                    " exists extends finally for function given if import in interface is let module new" +
-                    " nonempty object of out outer package return satisfies super switch then this throw" +
-                    " try value void while"),
-    types: function(word) {
-        // In Ceylon all identifiers that start with an uppercase are types
-        var first = word.charAt(0);
-        return (first === first.toUpperCase() && first !== first.toLowerCase());
-    },
-    blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
-    defKeywords: words("class dynamic function interface module object package value"),
-    builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
-                   " native optional sealed see serializable shared suppressWarnings tagged throws variable"),
-    isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
-    isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
-    numberStart: /[\d#$]/,
-    number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
-    multiLineStrings: true,
-    typeFirstDefinitions: true,
-    atoms: words("true false null larger smaller equal empty finished"),
-    indentSwitch: false,
-    styleDefs: false,
-    hooks: {
-      "@": function(stream) {
-        stream.eatWhile(/[\w\$_]/);
-        return "meta";
-      },
-      '"': function(stream, state) {
-          state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
-          return state.tokenize(stream, state);
-        },
-      '`': function(stream, state) {
-          if (!stringTokenizer || !stream.match('`')) return false;
-          state.tokenize = stringTokenizer;
-          stringTokenizer = null;
-          return state.tokenize(stream, state);
-        },
-      "'": function(stream) {
-        stream.eatWhile(/[\w\$_\xa1-\uffff]/);
-        return "atom";
-      },
-      token: function(_stream, state, style) {
-          if ((style == "variable" || style == "type") &&
-              state.prevToken == ".") {
-            return "variable-2";
-          }
-        }
-    },
-    modeProps: {
-        fold: ["brace", "import"],
-        closeBrackets: {triples: '"'}
-    }
-  });
-
-});
diff --git a/front_end/cm_modes/clojure.js b/front_end/cm_modes/clojure.js
deleted file mode 100644
index ed6af2c..0000000
--- a/front_end/cm_modes/clojure.js
+++ /dev/null
@@ -1,306 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-/**
- * Author: Hans Engel
- * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
- */
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("clojure", function (options) {
-    var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
-        ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
-    var INDENT_WORD_SKIP = options.indentUnit || 2;
-    var NORMAL_INDENT_UNIT = options.indentUnit || 2;
-
-    function makeKeywords(str) {
-        var obj = {}, words = str.split(" ");
-        for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
-        return obj;
-    }
-
-    var atoms = makeKeywords("true false nil");
-
-    var keywords = makeKeywords(
-      "defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest " +
-      "slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn " +
-      "do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync " +
-      "doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars " +
-      "binding gen-class gen-and-load-class gen-and-save-class handler-case handle");
-
-    var builtins = makeKeywords(
-        "* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* " +
-        "*compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* " +
-        "*math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* " +
-        "*source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> " +
-        "->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor " +
-        "aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! " +
-        "alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double " +
-        "aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 " +
-        "bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set " +
-        "bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast " +
-        "byte byte-array bytes case cat cast char char-array char-escape-string char-name-string char? chars chunk chunk-append " +
-        "chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors " +
-        "clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement completing concat cond condp " +
-        "conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? " +
-        "declare dedupe default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol " +
-        "defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc " +
-        "dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last " +
-        "drop-while eduction empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info " +
-        "extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword " +
-        "find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? " +
-        "fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? " +
-        "gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash " +
-        "hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? " +
-        "int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep " +
-        "keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file " +
-        "load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array " +
-        "make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods " +
-        "min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty " +
-        "not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias " +
-        "ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all " +
-        "partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers " +
-        "primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str " +
-        "prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues " +
-        "quot rand rand-int rand-nth random-sample range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern " +
-        "re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history " +
-        "ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods " +
-        "remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest " +
-        "restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? " +
-        "seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts " +
-        "shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? " +
-        "special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol " +
-        "symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transduce " +
-        "transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec " +
-        "unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int " +
-        "unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int "+
-        "unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote " +
-        "unquote-splicing update update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of " +
-        "vector? volatile! volatile? vreset! vswap! when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context " +
-        "with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap " +
-        "*default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! " +
-        "set-agent-send-off-executor! some-> some->>");
-
-    var indentKeys = makeKeywords(
-        // Built-ins
-        "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto " +
-        "locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type " +
-        "try catch " +
-
-        // Binding forms
-        "let letfn binding loop for doseq dotimes when-let if-let " +
-
-        // Data structures
-        "defstruct struct-map assoc " +
-
-        // clojure.test
-        "testing deftest " +
-
-        // contrib
-        "handler-case handle dotrace deftrace");
-
-    var tests = {
-        digit: /\d/,
-        digit_or_colon: /[\d:]/,
-        hex: /[0-9a-f]/i,
-        sign: /[+-]/,
-        exponent: /e/i,
-        keyword_char: /[^\s\(\[\;\)\]]/,
-        symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/,
-        block_indent: /^(?:def|with)[^\/]+$|\/(?:def|with)/
-    };
-
-    function stateStack(indent, type, prev) { // represents a state stack object
-        this.indent = indent;
-        this.type = type;
-        this.prev = prev;
-    }
-
-    function pushStack(state, indent, type) {
-        state.indentStack = new stateStack(indent, type, state.indentStack);
-    }
-
-    function popStack(state) {
-        state.indentStack = state.indentStack.prev;
-    }
-
-    function isNumber(ch, stream){
-        // hex
-        if ( ch === '0' && stream.eat(/x/i) ) {
-            stream.eatWhile(tests.hex);
-            return true;
-        }
-
-        // leading sign
-        if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
-          stream.eat(tests.sign);
-          ch = stream.next();
-        }
-
-        if ( tests.digit.test(ch) ) {
-            stream.eat(ch);
-            stream.eatWhile(tests.digit);
-
-            if ( '.' == stream.peek() ) {
-                stream.eat('.');
-                stream.eatWhile(tests.digit);
-            } else if ('/' == stream.peek() ) {
-                stream.eat('/');
-                stream.eatWhile(tests.digit);
-            }
-
-            if ( stream.eat(tests.exponent) ) {
-                stream.eat(tests.sign);
-                stream.eatWhile(tests.digit);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    // Eat character that starts after backslash \
-    function eatCharacter(stream) {
-        var first = stream.next();
-        // Read special literals: backspace, newline, space, return.
-        // Just read all lowercase letters.
-        if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
-            return;
-        }
-        // Read unicode character: \u1000 \uA0a1
-        if (first === "u") {
-            stream.match(/[0-9a-z]{4}/i, true);
-        }
-    }
-
-    return {
-        startState: function () {
-            return {
-                indentStack: null,
-                indentation: 0,
-                mode: false
-            };
-        },
-
-        token: function (stream, state) {
-            if (state.indentStack == null && stream.sol()) {
-                // update indentation, but only if indentStack is empty
-                state.indentation = stream.indentation();
-            }
-
-            // skip spaces
-            if (state.mode != "string" && stream.eatSpace()) {
-                return null;
-            }
-            var returnType = null;
-
-            switch(state.mode){
-                case "string": // multi-line string parsing mode
-                    var next, escaped = false;
-                    while ((next = stream.next()) != null) {
-                        if (next == "\"" && !escaped) {
-
-                            state.mode = false;
-                            break;
-                        }
-                        escaped = !escaped && next == "\\";
-                    }
-                    returnType = STRING; // continue on in string mode
-                    break;
-                default: // default parsing mode
-                    var ch = stream.next();
-
-                    if (ch == "\"") {
-                        state.mode = "string";
-                        returnType = STRING;
-                    } else if (ch == "\\") {
-                        eatCharacter(stream);
-                        returnType = CHARACTER;
-                    } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
-                        returnType = ATOM;
-                    } else if (ch == ";") { // comment
-                        stream.skipToEnd(); // rest of the line is a comment
-                        returnType = COMMENT;
-                    } else if (isNumber(ch,stream)){
-                        returnType = NUMBER;
-                    } else if (ch == "(" || ch == "[" || ch == "{" ) {
-                        var keyWord = '', indentTemp = stream.column(), letter;
-                        /**
-                        Either
-                        (indent-word ..
-                        (non-indent-word ..
-                        (;something else, bracket, etc.
-                        */
-
-                        if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
-                            keyWord += letter;
-                        }
-
-                        if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
-                                                   tests.block_indent.test(keyWord))) { // indent-word
-                            pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
-                        } else { // non-indent word
-                            // we continue eating the spaces
-                            stream.eatSpace();
-                            if (stream.eol() || stream.peek() == ";") {
-                                // nothing significant after
-                                // we restart indentation the user defined spaces after
-                                pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
-                            } else {
-                                pushStack(state, indentTemp + stream.current().length, ch); // else we match
-                            }
-                        }
-                        stream.backUp(stream.current().length - 1); // undo all the eating
-
-                        returnType = BRACKET;
-                    } else if (ch == ")" || ch == "]" || ch == "}") {
-                        returnType = BRACKET;
-                        if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
-                            popStack(state);
-                        }
-                    } else if ( ch == ":" ) {
-                        stream.eatWhile(tests.symbol);
-                        return ATOM;
-                    } else {
-                        stream.eatWhile(tests.symbol);
-
-                        if (keywords && keywords.propertyIsEnumerable(stream.current())) {
-                            returnType = KEYWORD;
-                        } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
-                            returnType = BUILTIN;
-                        } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
-                            returnType = ATOM;
-                        } else {
-                          returnType = VAR;
-                        }
-                    }
-            }
-
-            return returnType;
-        },
-
-        indent: function (state) {
-            if (state.indentStack == null) return state.indentation;
-            return state.indentStack.indent;
-        },
-
-        closeBrackets: {pairs: "()[]{}\"\""},
-        lineComment: ";;"
-    };
-});
-
-CodeMirror.defineMIME("text/x-clojure", "clojure");
-CodeMirror.defineMIME("text/x-clojurescript", "clojure");
-CodeMirror.defineMIME("application/edn", "clojure");
-
-});
diff --git a/front_end/cm_modes/coffeescript.js b/front_end/cm_modes/coffeescript.js
deleted file mode 100644
index ae955db..0000000
--- a/front_end/cm_modes/coffeescript.js
+++ /dev/null
@@ -1,359 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-/**
- * Link to the project's GitHub page:
- * https://github.com/pickhardt/coffeescript-codemirror-mode
- */
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
-  var ERRORCLASS = "error";
-
-  function wordRegexp(words) {
-    return new RegExp("^((" + words.join(")|(") + "))\\b");
-  }
-
-  var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
-  var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
-  var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
-  var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/;
-
-  var wordOperators = wordRegexp(["and", "or", "not",
-                                  "is", "isnt", "in",
-                                  "instanceof", "typeof"]);
-  var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
-                        "switch", "try", "catch", "finally", "class"];
-  var commonKeywords = ["break", "by", "continue", "debugger", "delete",
-                        "do", "in", "of", "new", "return", "then",
-                        "this", "@", "throw", "when", "until", "extends"];
-
-  var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
-
-  indentKeywords = wordRegexp(indentKeywords);
-
-
-  var stringPrefixes = /^('{3}|\"{3}|['\"])/;
-  var regexPrefixes = /^(\/{3}|\/)/;
-  var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
-  var constants = wordRegexp(commonConstants);
-
-  // Tokenizers
-  function tokenBase(stream, state) {
-    // Handle scope changes
-    if (stream.sol()) {
-      if (state.scope.align === null) state.scope.align = false;
-      var scopeOffset = state.scope.offset;
-      if (stream.eatSpace()) {
-        var lineOffset = stream.indentation();
-        if (lineOffset > scopeOffset && state.scope.type == "coffee") {
-          return "indent";
-        } else if (lineOffset < scopeOffset) {
-          return "dedent";
-        }
-        return null;
-      } else {
-        if (scopeOffset > 0) {
-          dedent(stream, state);
-        }
-      }
-    }
-    if (stream.eatSpace()) {
-      return null;
-    }
-
-    var ch = stream.peek();
-
-    // Handle docco title comment (single line)
-    if (stream.match("####")) {
-      stream.skipToEnd();
-      return "comment";
-    }
-
-    // Handle multi line comments
-    if (stream.match("###")) {
-      state.tokenize = longComment;
-      return state.tokenize(stream, state);
-    }
-
-    // Single line comment
-    if (ch === "#") {
-      stream.skipToEnd();
-      return "comment";
-    }
-
-    // Handle number literals
-    if (stream.match(/^-?[0-9\.]/, false)) {
-      var floatLiteral = false;
-      // Floats
-      if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
-        floatLiteral = true;
-      }
-      if (stream.match(/^-?\d+\.\d*/)) {
-        floatLiteral = true;
-      }
-      if (stream.match(/^-?\.\d+/)) {
-        floatLiteral = true;
-      }
-
-      if (floatLiteral) {
-        // prevent from getting extra . on 1..
-        if (stream.peek() == "."){
-          stream.backUp(1);
-        }
-        return "number";
-      }
-      // Integers
-      var intLiteral = false;
-      // Hex
-      if (stream.match(/^-?0x[0-9a-f]+/i)) {
-        intLiteral = true;
-      }
-      // Decimal
-      if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
-        intLiteral = true;
-      }
-      // Zero by itself with no other piece of number.
-      if (stream.match(/^-?0(?![\dx])/i)) {
-        intLiteral = true;
-      }
-      if (intLiteral) {
-        return "number";
-      }
-    }
-
-    // Handle strings
-    if (stream.match(stringPrefixes)) {
-      state.tokenize = tokenFactory(stream.current(), false, "string");
-      return state.tokenize(stream, state);
-    }
-    // Handle regex literals
-    if (stream.match(regexPrefixes)) {
-      if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
-        state.tokenize = tokenFactory(stream.current(), true, "string-2");
-        return state.tokenize(stream, state);
-      } else {
-        stream.backUp(1);
-      }
-    }
-
-
-
-    // Handle operators and delimiters
-    if (stream.match(operators) || stream.match(wordOperators)) {
-      return "operator";
-    }
-    if (stream.match(delimiters)) {
-      return "punctuation";
-    }
-
-    if (stream.match(constants)) {
-      return "atom";
-    }
-
-    if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
-      return "property";
-    }
-
-    if (stream.match(keywords)) {
-      return "keyword";
-    }
-
-    if (stream.match(identifiers)) {
-      return "variable";
-    }
-
-    // Handle non-detected items
-    stream.next();
-    return ERRORCLASS;
-  }
-
-  function tokenFactory(delimiter, singleline, outclass) {
-    return function(stream, state) {
-      while (!stream.eol()) {
-        stream.eatWhile(/[^'"\/\\]/);
-        if (stream.eat("\\")) {
-          stream.next();
-          if (singleline && stream.eol()) {
-            return outclass;
-          }
-        } else if (stream.match(delimiter)) {
-          state.tokenize = tokenBase;
-          return outclass;
-        } else {
-          stream.eat(/['"\/]/);
-        }
-      }
-      if (singleline) {
-        if (parserConf.singleLineStringErrors) {
-          outclass = ERRORCLASS;
-        } else {
-          state.tokenize = tokenBase;
-        }
-      }
-      return outclass;
-    };
-  }
-
-  function longComment(stream, state) {
-    while (!stream.eol()) {
-      stream.eatWhile(/[^#]/);
-      if (stream.match("###")) {
-        state.tokenize = tokenBase;
-        break;
-      }
-      stream.eatWhile("#");
-    }
-    return "comment";
-  }
-
-  function indent(stream, state, type) {
-    type = type || "coffee";
-    var offset = 0, align = false, alignOffset = null;
-    for (var scope = state.scope; scope; scope = scope.prev) {
-      if (scope.type === "coffee" || scope.type == "}") {
-        offset = scope.offset + conf.indentUnit;
-        break;
-      }
-    }
-    if (type !== "coffee") {
-      align = null;
-      alignOffset = stream.column() + stream.current().length;
-    } else if (state.scope.align) {
-      state.scope.align = false;
-    }
-    state.scope = {
-      offset: offset,
-      type: type,
-      prev: state.scope,
-      align: align,
-      alignOffset: alignOffset
-    };
-  }
-
-  function dedent(stream, state) {
-    if (!state.scope.prev) return;
-    if (state.scope.type === "coffee") {
-      var _indent = stream.indentation();
-      var matched = false;
-      for (var scope = state.scope; scope; scope = scope.prev) {
-        if (_indent === scope.offset) {
-          matched = true;
-          break;
-        }
-      }
-      if (!matched) {
-        return true;
-      }
-      while (state.scope.prev && state.scope.offset !== _indent) {
-        state.scope = state.scope.prev;
-      }
-      return false;
-    } else {
-      state.scope = state.scope.prev;
-      return false;
-    }
-  }
-
-  function tokenLexer(stream, state) {
-    var style = state.tokenize(stream, state);
-    var current = stream.current();
-
-    // Handle scope changes.
-    if (current === "return") {
-      state.dedent = true;
-    }
-    if (((current === "->" || current === "=>") && stream.eol())
-        || style === "indent") {
-      indent(stream, state);
-    }
-    var delimiter_index = "[({".indexOf(current);
-    if (delimiter_index !== -1) {
-      indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
-    }
-    if (indentKeywords.exec(current)){
-      indent(stream, state);
-    }
-    if (current == "then"){
-      dedent(stream, state);
-    }
-
-
-    if (style === "dedent") {
-      if (dedent(stream, state)) {
-        return ERRORCLASS;
-      }
-    }
-    delimiter_index = "])}".indexOf(current);
-    if (delimiter_index !== -1) {
-      while (state.scope.type == "coffee" && state.scope.prev)
-        state.scope = state.scope.prev;
-      if (state.scope.type == current)
-        state.scope = state.scope.prev;
-    }
-    if (state.dedent && stream.eol()) {
-      if (state.scope.type == "coffee" && state.scope.prev)
-        state.scope = state.scope.prev;
-      state.dedent = false;
-    }
-
-    return style;
-  }
-
-  var external = {
-    startState: function(basecolumn) {
-      return {
-        tokenize: tokenBase,
-        scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
-        prop: false,
-        dedent: 0
-      };
-    },
-
-    token: function(stream, state) {
-      var fillAlign = state.scope.align === null && state.scope;
-      if (fillAlign && stream.sol()) fillAlign.align = false;
-
-      var style = tokenLexer(stream, state);
-      if (style && style != "comment") {
-        if (fillAlign) fillAlign.align = true;
-        state.prop = style == "punctuation" && stream.current() == "."
-      }
-
-      return style;
-    },
-
-    indent: function(state, text) {
-      if (state.tokenize != tokenBase) return 0;
-      var scope = state.scope;
-      var closer = text && "])}".indexOf(text.charAt(0)) > -1;
-      if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
-      var closes = closer && scope.type === text.charAt(0);
-      if (scope.align)
-        return scope.alignOffset - (closes ? 1 : 0);
-      else
-        return (closes ? scope.prev : scope).offset;
-    },
-
-    lineComment: "#",
-    fold: "indent"
-  };
-  return external;
-});
-
-// IANA registered media type
-// https://www.iana.org/assignments/media-types/
-CodeMirror.defineMIME("application/vnd.coffeescript", "coffeescript");
-
-CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
-CodeMirror.defineMIME("text/coffeescript", "coffeescript");
-
-});
diff --git a/front_end/cm_modes/jsx.js b/front_end/cm_modes/jsx.js
deleted file mode 100644
index 45c3024..0000000
--- a/front_end/cm_modes/jsx.js
+++ /dev/null
@@ -1,148 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
-  else // Plain browser env
-    mod(CodeMirror)
-})(function(CodeMirror) {
-  "use strict"
-
-  // Depth means the amount of open braces in JS context, in XML
-  // context 0 means not in tag, 1 means in tag, and 2 means in tag
-  // and js block comment.
-  function Context(state, mode, depth, prev) {
-    this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
-  }
-
-  function copyContext(context) {
-    return new Context(CodeMirror.copyState(context.mode, context.state),
-                       context.mode,
-                       context.depth,
-                       context.prev && copyContext(context.prev))
-  }
-
-  CodeMirror.defineMode("jsx", function(config, modeConfig) {
-    var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
-    var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
-
-    function flatXMLIndent(state) {
-      var tagName = state.tagName
-      state.tagName = null
-      var result = xmlMode.indent(state, "")
-      state.tagName = tagName
-      return result
-    }
-
-    function token(stream, state) {
-      if (state.context.mode == xmlMode)
-        return xmlToken(stream, state, state.context)
-      else
-        return jsToken(stream, state, state.context)
-    }
-
-    function xmlToken(stream, state, cx) {
-      if (cx.depth == 2) { // Inside a JS /* */ comment
-        if (stream.match(/^.*?\*\//)) cx.depth = 1
-        else stream.skipToEnd()
-        return "comment"
-      }
-
-      if (stream.peek() == "{") {
-        xmlMode.skipAttribute(cx.state)
-
-        var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
-        // If JS starts on same line as tag
-        if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
-          while (xmlContext.prev && !xmlContext.startOfLine)
-            xmlContext = xmlContext.prev
-          // If tag starts the line, use XML indentation level
-          if (xmlContext.startOfLine) indent -= config.indentUnit
-          // Else use JS indentation level
-          else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
-        // Else if inside of tag
-        } else if (cx.depth == 1) {
-          indent += config.indentUnit
-        }
-
-        state.context = new Context(CodeMirror.startState(jsMode, indent),
-                                    jsMode, 0, state.context)
-        return null
-      }
-
-      if (cx.depth == 1) { // Inside of tag
-        if (stream.peek() == "<") { // Tag inside of tag
-          xmlMode.skipAttribute(cx.state)
-          state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
-                                      xmlMode, 0, state.context)
-          return null
-        } else if (stream.match("//")) {
-          stream.skipToEnd()
-          return "comment"
-        } else if (stream.match("/*")) {
-          cx.depth = 2
-          return token(stream, state)
-        }
-      }
-
-      var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
-      if (/\btag\b/.test(style)) {
-        if (/>$/.test(cur)) {
-          if (cx.state.context) cx.depth = 0
-          else state.context = state.context.prev
-        } else if (/^</.test(cur)) {
-          cx.depth = 1
-        }
-      } else if (!style && (stop = cur.indexOf("{")) > -1) {
-        stream.backUp(cur.length - stop)
-      }
-      return style
-    }
-
-    function jsToken(stream, state, cx) {
-      if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
-        jsMode.skipExpression(cx.state)
-        state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
-                                    xmlMode, 0, state.context)
-        return null
-      }
-
-      var style = jsMode.token(stream, cx.state)
-      if (!style && cx.depth != null) {
-        var cur = stream.current()
-        if (cur == "{") {
-          cx.depth++
-        } else if (cur == "}") {
-          if (--cx.depth == 0) state.context = state.context.prev
-        }
-      }
-      return style
-    }
-
-    return {
-      startState: function() {
-        return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
-      },
-
-      copyState: function(state) {
-        return {context: copyContext(state.context)}
-      },
-
-      token: token,
-
-      indent: function(state, textAfter, fullLine) {
-        return state.context.mode.indent(state.context.state, textAfter, fullLine)
-      },
-
-      innerMode: function(state) {
-        return state.context
-      }
-    }
-  }, "xml", "javascript")
-
-  CodeMirror.defineMIME("text/jsx", "jsx")
-  CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}})
-});
diff --git a/front_end/cm_modes/livescript.js b/front_end/cm_modes/livescript.js
deleted file mode 100644
index 1e363f8..0000000
--- a/front_end/cm_modes/livescript.js
+++ /dev/null
@@ -1,280 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-/**
- * Link to the project's GitHub page:
- * https://github.com/duralog/CodeMirror
- */
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  CodeMirror.defineMode('livescript', function(){
-    var tokenBase = function(stream, state) {
-      var next_rule = state.next || "start";
-      if (next_rule) {
-        state.next = state.next;
-        var nr = Rules[next_rule];
-        if (nr.splice) {
-          for (var i$ = 0; i$ < nr.length; ++i$) {
-            var r = nr[i$];
-            if (r.regex && stream.match(r.regex)) {
-              state.next = r.next || state.next;
-              return r.token;
-            }
-          }
-          stream.next();
-          return 'error';
-        }
-        if (stream.match(r = Rules[next_rule])) {
-          if (r.regex && stream.match(r.regex)) {
-            state.next = r.next;
-            return r.token;
-          } else {
-            stream.next();
-            return 'error';
-          }
-        }
-      }
-      stream.next();
-      return 'error';
-    };
-    var external = {
-      startState: function(){
-        return {
-          next: 'start',
-          lastToken: {style: null, indent: 0, content: ""}
-        };
-      },
-      token: function(stream, state){
-        while (stream.pos == stream.start)
-          var style = tokenBase(stream, state);
-        state.lastToken = {
-          style: style,
-          indent: stream.indentation(),
-          content: stream.current()
-        };
-        return style.replace(/\./g, ' ');
-      },
-      indent: function(state){
-        var indentation = state.lastToken.indent;
-        if (state.lastToken.content.match(indenter)) {
-          indentation += 2;
-        }
-        return indentation;
-      }
-    };
-    return external;
-  });
-
-  var identifier = '(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*';
-  var indenter = RegExp('(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*' + identifier + ')?))\\s*$');
-  var keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
-  var stringfill = {
-    token: 'string',
-    regex: '.+'
-  };
-  var Rules = {
-    start: [
-      {
-        token: 'comment.doc',
-        regex: '/\\*',
-        next: 'comment'
-      }, {
-        token: 'comment',
-        regex: '#.*'
-      }, {
-        token: 'keyword',
-        regex: '(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)' + keywordend
-      }, {
-        token: 'constant.language',
-        regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend
-      }, {
-        token: 'invalid.illegal',
-        regex: '(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)' + keywordend
-      }, {
-        token: 'language.support.class',
-        regex: '(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)' + keywordend
-      }, {
-        token: 'language.support.function',
-        regex: '(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)' + keywordend
-      }, {
-        token: 'variable.language',
-        regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend
-      }, {
-        token: 'identifier',
-        regex: identifier + '\\s*:(?![:=])'
-      }, {
-        token: 'variable',
-        regex: identifier
-      }, {
-        token: 'keyword.operator',
-        regex: '(?:\\.{3}|\\s+\\?)'
-      }, {
-        token: 'keyword.variable',
-        regex: '(?:@+|::|\\.\\.)',
-        next: 'key'
-      }, {
-        token: 'keyword.operator',
-        regex: '\\.\\s*',
-        next: 'key'
-      }, {
-        token: 'string',
-        regex: '\\\\\\S[^\\s,;)}\\]]*'
-      }, {
-        token: 'string.doc',
-        regex: '\'\'\'',
-        next: 'qdoc'
-      }, {
-        token: 'string.doc',
-        regex: '"""',
-        next: 'qqdoc'
-      }, {
-        token: 'string',
-        regex: '\'',
-        next: 'qstring'
-      }, {
-        token: 'string',
-        regex: '"',
-        next: 'qqstring'
-      }, {
-        token: 'string',
-        regex: '`',
-        next: 'js'
-      }, {
-        token: 'string',
-        regex: '<\\[',
-        next: 'words'
-      }, {
-        token: 'string.regex',
-        regex: '//',
-        next: 'heregex'
-      }, {
-        token: 'string.regex',
-        regex: '\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}',
-        next: 'key'
-      }, {
-        token: 'constant.numeric',
-        regex: '(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)'
-      }, {
-        token: 'lparen',
-        regex: '[({[]'
-      }, {
-        token: 'rparen',
-        regex: '[)}\\]]',
-        next: 'key'
-      }, {
-        token: 'keyword.operator',
-        regex: '\\S+'
-      }, {
-        token: 'text',
-        regex: '\\s+'
-      }
-    ],
-    heregex: [
-      {
-        token: 'string.regex',
-        regex: '.*?//[gimy$?]{0,4}',
-        next: 'start'
-      }, {
-        token: 'string.regex',
-        regex: '\\s*#{'
-      }, {
-        token: 'comment.regex',
-        regex: '\\s+(?:#.*)?'
-      }, {
-        token: 'string.regex',
-        regex: '\\S+'
-      }
-    ],
-    key: [
-      {
-        token: 'keyword.operator',
-        regex: '[.?@!]+'
-      }, {
-        token: 'identifier',
-        regex: identifier,
-        next: 'start'
-      }, {
-        token: 'text',
-        regex: '',
-        next: 'start'
-      }
-    ],
-    comment: [
-      {
-        token: 'comment.doc',
-        regex: '.*?\\*/',
-        next: 'start'
-      }, {
-        token: 'comment.doc',
-        regex: '.+'
-      }
-    ],
-    qdoc: [
-      {
-        token: 'string',
-        regex: ".*?'''",
-        next: 'key'
-      }, stringfill
-    ],
-    qqdoc: [
-      {
-        token: 'string',
-        regex: '.*?"""',
-        next: 'key'
-      }, stringfill
-    ],
-    qstring: [
-      {
-        token: 'string',
-        regex: '[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'',
-        next: 'key'
-      }, stringfill
-    ],
-    qqstring: [
-      {
-        token: 'string',
-        regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',
-        next: 'key'
-      }, stringfill
-    ],
-    js: [
-      {
-        token: 'string',
-        regex: '[^\\\\`]*(?:\\\\.[^\\\\`]*)*`',
-        next: 'key'
-      }, stringfill
-    ],
-    words: [
-      {
-        token: 'string',
-        regex: '.*?\\]>',
-        next: 'key'
-      }, stringfill
-    ]
-  };
-  for (var idx in Rules) {
-    var r = Rules[idx];
-    if (r.splice) {
-      for (var i = 0, len = r.length; i < len; ++i) {
-        var rr = r[i];
-        if (typeof rr.regex === 'string') {
-          Rules[idx][i].regex = new RegExp('^' + rr.regex);
-        }
-      }
-    } else if (typeof rr.regex === 'string') {
-      Rules[idx].regex = new RegExp('^' + r.regex);
-    }
-  }
-
-  CodeMirror.defineMIME('text/x-livescript', 'livescript');
-
-});
diff --git a/front_end/cm_modes/markdown.js b/front_end/cm_modes/markdown.js
deleted file mode 100644
index 61e0c4f..0000000
--- a/front_end/cm_modes/markdown.js
+++ /dev/null
@@ -1,872 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
-
-  var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
-  var htmlModeMissing = htmlMode.name == "null"
-
-  function getMode(name) {
-    if (CodeMirror.findModeByName) {
-      var found = CodeMirror.findModeByName(name);
-      if (found) name = found.mime || found.mimes[0];
-    }
-    var mode = CodeMirror.getMode(cmCfg, name);
-    return mode.name == "null" ? null : mode;
-  }
-
-  // Should characters that affect highlighting be highlighted separate?
-  // Does not include characters that will be output (such as `1.` and `-` for lists)
-  if (modeCfg.highlightFormatting === undefined)
-    modeCfg.highlightFormatting = false;
-
-  // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
-  // Excess `>` will emit `error` token.
-  if (modeCfg.maxBlockquoteDepth === undefined)
-    modeCfg.maxBlockquoteDepth = 0;
-
-  // Turn on task lists? ("- [ ] " and "- [x] ")
-  if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
-
-  // Turn on strikethrough syntax
-  if (modeCfg.strikethrough === undefined)
-    modeCfg.strikethrough = false;
-
-  if (modeCfg.emoji === undefined)
-    modeCfg.emoji = false;
-
-  if (modeCfg.fencedCodeBlockHighlighting === undefined)
-    modeCfg.fencedCodeBlockHighlighting = true;
-
-  if (modeCfg.xml === undefined)
-    modeCfg.xml = true;
-
-  // Allow token types to be overridden by user-provided token types.
-  if (modeCfg.tokenTypeOverrides === undefined)
-    modeCfg.tokenTypeOverrides = {};
-
-  var tokenTypes = {
-    header: "header",
-    code: "comment",
-    quote: "quote",
-    list1: "variable-2",
-    list2: "variable-3",
-    list3: "keyword",
-    hr: "hr",
-    image: "image",
-    imageAltText: "image-alt-text",
-    imageMarker: "image-marker",
-    formatting: "formatting",
-    linkInline: "link",
-    linkEmail: "link",
-    linkText: "link",
-    linkHref: "string",
-    em: "em",
-    strong: "strong",
-    strikethrough: "strikethrough",
-    emoji: "builtin"
-  };
-
-  for (var tokenType in tokenTypes) {
-    if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
-      tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
-    }
-  }
-
-  var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
-  ,   listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
-  ,   taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE
-  ,   atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
-  ,   setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
-  ,   textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
-  ,   fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/
-  ,   linkDefRE = /^\s*\[[^\]]+?\]:\s*\S+(\s*\S*\s*)?$/ // naive link-definition
-  ,   punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~\u2014]/
-  ,   expandedTab = "    " // CommonMark specifies tab as 4 spaces
-
-  function switchInline(stream, state, f) {
-    state.f = state.inline = f;
-    return f(stream, state);
-  }
-
-  function switchBlock(stream, state, f) {
-    state.f = state.block = f;
-    return f(stream, state);
-  }
-
-  function lineIsEmpty(line) {
-    return !line || !/\S/.test(line.string)
-  }
-
-  // Blocks
-
-  function blankLine(state) {
-    // Reset linkTitle state
-    state.linkTitle = false;
-    state.linkHref = false;
-    state.linkText = false;
-    // Reset EM state
-    state.em = false;
-    // Reset STRONG state
-    state.strong = false;
-    // Reset strikethrough state
-    state.strikethrough = false;
-    // Reset state.quote
-    state.quote = 0;
-    // Reset state.indentedCode
-    state.indentedCode = false;
-    if (state.f == htmlBlock) {
-      state.f = inlineNormal;
-      state.block = blockNormal;
-    }
-    // Reset state.trailingSpace
-    state.trailingSpace = 0;
-    state.trailingSpaceNewLine = false;
-    // Mark this line as blank
-    state.prevLine = state.thisLine
-    state.thisLine = {stream: null}
-    return null;
-  }
-
-  function blockNormal(stream, state) {
-    var firstTokenOnLine = stream.column() === state.indentation;
-    var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream);
-    var prevLineIsIndentedCode = state.indentedCode;
-    var prevLineIsHr = state.prevLine.hr;
-    var prevLineIsList = state.list !== false;
-    var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3;
-
-    state.indentedCode = false;
-
-    var lineIndentation = state.indentation;
-    // compute once per line (on first token)
-    if (state.indentationDiff === null) {
-      state.indentationDiff = state.indentation;
-      if (prevLineIsList) {
-        // Reset inline styles which shouldn't propagate aross list items
-        state.em = false;
-        state.strong = false;
-        state.code = false;
-        state.strikethrough = false;
-
-        state.list = null;
-        // While this list item's marker's indentation is less than the deepest
-        //  list item's content's indentation,pop the deepest list item
-        //  indentation off the stack, and update block indentation state
-        while (lineIndentation < state.listStack[state.listStack.length - 1]) {
-          state.listStack.pop();
-          if (state.listStack.length) {
-            state.indentation = state.listStack[state.listStack.length - 1];
-          // less than the first list's indent -> the line is no longer a list
-          } else {
-            state.list = false;
-          }
-        }
-        if (state.list !== false) {
-          state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1]
-        }
-      }
-    }
-
-    // not comprehensive (currently only for setext detection purposes)
-    var allowsInlineContinuation = (
-        !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header &&
-        (!prevLineIsList || !prevLineIsIndentedCode) &&
-        !state.prevLine.fencedCodeEnd
-    );
-
-    var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) &&
-      state.indentation <= maxNonCodeIndentation && stream.match(hrRE);
-
-    var match = null;
-    if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd ||
-         state.prevLine.header || prevLineLineIsEmpty)) {
-      stream.skipToEnd();
-      state.indentedCode = true;
-      return tokenTypes.code;
-    } else if (stream.eatSpace()) {
-      return null;
-    } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
-      state.quote = 0;
-      state.header = match[1].length;
-      state.thisLine.header = true;
-      if (modeCfg.highlightFormatting) state.formatting = "header";
-      state.f = state.inline;
-      return getType(state);
-    } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) {
-      state.quote = firstTokenOnLine ? 1 : state.quote + 1;
-      if (modeCfg.highlightFormatting) state.formatting = "quote";
-      stream.eatSpace();
-      return getType(state);
-    } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) {
-      var listType = match[1] ? "ol" : "ul";
-
-      state.indentation = lineIndentation + stream.current().length;
-      state.list = true;
-      state.quote = 0;
-
-      // Add this list item's content's indentation to the stack
-      state.listStack.push(state.indentation);
-
-      if (modeCfg.taskLists && stream.match(taskListRE, false)) {
-        state.taskList = true;
-      }
-      state.f = state.inline;
-      if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
-      return getType(state);
-    } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) {
-      state.quote = 0;
-      state.fencedEndRE = new RegExp(match[1] + "+ *$");
-      // try switching mode
-      state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2]);
-      if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
-      state.f = state.block = local;
-      if (modeCfg.highlightFormatting) state.formatting = "code-block";
-      state.code = -1
-      return getType(state);
-    // SETEXT has lowest block-scope precedence after HR, so check it after
-    //  the others (code, blockquote, list...)
-    } else if (
-      // if setext set, indicates line after ---/===
-      state.setext || (
-        // line before ---/===
-        (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false &&
-        !state.code && !isHr && !linkDefRE.test(stream.string) &&
-        (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE))
-      )
-    ) {
-      if ( !state.setext ) {
-        state.header = match[0].charAt(0) == '=' ? 1 : 2;
-        state.setext = state.header;
-      } else {
-        state.header = state.setext;
-        // has no effect on type so we can reset it now
-        state.setext = 0;
-        stream.skipToEnd();
-        if (modeCfg.highlightFormatting) state.formatting = "header";
-      }
-      state.thisLine.header = true;
-      state.f = state.inline;
-      return getType(state);
-    } else if (isHr) {
-      stream.skipToEnd();
-      state.hr = true;
-      state.thisLine.hr = true;
-      return tokenTypes.hr;
-    } else if (stream.peek() === '[') {
-      return switchInline(stream, state, footnoteLink);
-    }
-
-    return switchInline(stream, state, state.inline);
-  }
-
-  function htmlBlock(stream, state) {
-    var style = htmlMode.token(stream, state.htmlState);
-    if (!htmlModeMissing) {
-      var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
-      if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
-           (!inner.state.context && inner.state.tokenize.isInText)) ||
-          (state.md_inside && stream.current().indexOf(">") > -1)) {
-        state.f = inlineNormal;
-        state.block = blockNormal;
-        state.htmlState = null;
-      }
-    }
-    return style;
-  }
-
-  function local(stream, state) {
-    var currListInd = state.listStack[state.listStack.length - 1] || 0;
-    var hasExitedList = state.indentation < currListInd;
-    var maxFencedEndInd = currListInd + 3;
-    if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) {
-      if (modeCfg.highlightFormatting) state.formatting = "code-block";
-      var returnType;
-      if (!hasExitedList) returnType = getType(state)
-      state.localMode = state.localState = null;
-      state.block = blockNormal;
-      state.f = inlineNormal;
-      state.fencedEndRE = null;
-      state.code = 0
-      state.thisLine.fencedCodeEnd = true;
-      if (hasExitedList) return switchBlock(stream, state, state.block);
-      return returnType;
-    } else if (state.localMode) {
-      return state.localMode.token(stream, state.localState);
-    } else {
-      stream.skipToEnd();
-      return tokenTypes.code;
-    }
-  }
-
-  // Inline
-  function getType(state) {
-    var styles = [];
-
-    if (state.formatting) {
-      styles.push(tokenTypes.formatting);
-
-      if (typeof state.formatting === "string") state.formatting = [state.formatting];
-
-      for (var i = 0; i < state.formatting.length; i++) {
-        styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
-
-        if (state.formatting[i] === "header") {
-          styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
-        }
-
-        // Add `formatting-quote` and `formatting-quote-#` for blockquotes
-        // Add `error` instead if the maximum blockquote nesting depth is passed
-        if (state.formatting[i] === "quote") {
-          if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
-            styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
-          } else {
-            styles.push("error");
-          }
-        }
-      }
-    }
-
-    if (state.taskOpen) {
-      styles.push("meta");
-      return styles.length ? styles.join(' ') : null;
-    }
-    if (state.taskClosed) {
-      styles.push("property");
-      return styles.length ? styles.join(' ') : null;
-    }
-
-    if (state.linkHref) {
-      styles.push(tokenTypes.linkHref, "url");
-    } else { // Only apply inline styles to non-url text
-      if (state.strong) { styles.push(tokenTypes.strong); }
-      if (state.em) { styles.push(tokenTypes.em); }
-      if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
-      if (state.emoji) { styles.push(tokenTypes.emoji); }
-      if (state.linkText) { styles.push(tokenTypes.linkText); }
-      if (state.code) { styles.push(tokenTypes.code); }
-      if (state.image) { styles.push(tokenTypes.image); }
-      if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
-      if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
-    }
-
-    if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
-
-    if (state.quote) {
-      styles.push(tokenTypes.quote);
-
-      // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
-      if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
-        styles.push(tokenTypes.quote + "-" + state.quote);
-      } else {
-        styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
-      }
-    }
-
-    if (state.list !== false) {
-      var listMod = (state.listStack.length - 1) % 3;
-      if (!listMod) {
-        styles.push(tokenTypes.list1);
-      } else if (listMod === 1) {
-        styles.push(tokenTypes.list2);
-      } else {
-        styles.push(tokenTypes.list3);
-      }
-    }
-
-    if (state.trailingSpaceNewLine) {
-      styles.push("trailing-space-new-line");
-    } else if (state.trailingSpace) {
-      styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
-    }
-
-    return styles.length ? styles.join(' ') : null;
-  }
-
-  function handleText(stream, state) {
-    if (stream.match(textRE, true)) {
-      return getType(state);
-    }
-    return undefined;
-  }
-
-  function inlineNormal(stream, state) {
-    var style = state.text(stream, state);
-    if (typeof style !== 'undefined')
-      return style;
-
-    if (state.list) { // List marker (*, +, -, 1., etc)
-      state.list = null;
-      return getType(state);
-    }
-
-    if (state.taskList) {
-      var taskOpen = stream.match(taskListRE, true)[1] === " ";
-      if (taskOpen) state.taskOpen = true;
-      else state.taskClosed = true;
-      if (modeCfg.highlightFormatting) state.formatting = "task";
-      state.taskList = false;
-      return getType(state);
-    }
-
-    state.taskOpen = false;
-    state.taskClosed = false;
-
-    if (state.header && stream.match(/^#+$/, true)) {
-      if (modeCfg.highlightFormatting) state.formatting = "header";
-      return getType(state);
-    }
-
-    var ch = stream.next();
-
-    // Matches link titles present on next line
-    if (state.linkTitle) {
-      state.linkTitle = false;
-      var matchCh = ch;
-      if (ch === '(') {
-        matchCh = ')';
-      }
-      matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
-      var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
-      if (stream.match(new RegExp(regex), true)) {
-        return tokenTypes.linkHref;
-      }
-    }
-
-    // If this block is changed, it may need to be updated in GFM mode
-    if (ch === '`') {
-      var previousFormatting = state.formatting;
-      if (modeCfg.highlightFormatting) state.formatting = "code";
-      stream.eatWhile('`');
-      var count = stream.current().length
-      if (state.code == 0 && (!state.quote || count == 1)) {
-        state.code = count
-        return getType(state)
-      } else if (count == state.code) { // Must be exact
-        var t = getType(state)
-        state.code = 0
-        return t
-      } else {
-        state.formatting = previousFormatting
-        return getType(state)
-      }
-    } else if (state.code) {
-      return getType(state);
-    }
-
-    if (ch === '\\') {
-      stream.next();
-      if (modeCfg.highlightFormatting) {
-        var type = getType(state);
-        var formattingEscape = tokenTypes.formatting + "-escape";
-        return type ? type + " " + formattingEscape : formattingEscape;
-      }
-    }
-
-    if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
-      state.imageMarker = true;
-      state.image = true;
-      if (modeCfg.highlightFormatting) state.formatting = "image";
-      return getType(state);
-    }
-
-    if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
-      state.imageMarker = false;
-      state.imageAltText = true
-      if (modeCfg.highlightFormatting) state.formatting = "image";
-      return getType(state);
-    }
-
-    if (ch === ']' && state.imageAltText) {
-      if (modeCfg.highlightFormatting) state.formatting = "image";
-      var type = getType(state);
-      state.imageAltText = false;
-      state.image = false;
-      state.inline = state.f = linkHref;
-      return type;
-    }
-
-    if (ch === '[' && !state.image) {
-      state.linkText = true;
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      return getType(state);
-    }
-
-    if (ch === ']' && state.linkText) {
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      var type = getType(state);
-      state.linkText = false;
-      state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
-      return type;
-    }
-
-    if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
-      state.f = state.inline = linkInline;
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      var type = getType(state);
-      if (type){
-        type += " ";
-      } else {
-        type = "";
-      }
-      return type + tokenTypes.linkInline;
-    }
-
-    if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
-      state.f = state.inline = linkInline;
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      var type = getType(state);
-      if (type){
-        type += " ";
-      } else {
-        type = "";
-      }
-      return type + tokenTypes.linkEmail;
-    }
-
-    if (modeCfg.xml && ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
-      var end = stream.string.indexOf(">", stream.pos);
-      if (end != -1) {
-        var atts = stream.string.substring(stream.start, end);
-        if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
-      }
-      stream.backUp(1);
-      state.htmlState = CodeMirror.startState(htmlMode);
-      return switchBlock(stream, state, htmlBlock);
-    }
-
-    if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) {
-      state.md_inside = false;
-      return "tag";
-    } else if (ch === "*" || ch === "_") {
-      var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
-      while (len < 3 && stream.eat(ch)) len++
-      var after = stream.peek() || " "
-      // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
-      var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
-      var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
-      var setEm = null, setStrong = null
-      if (len % 2) { // Em
-        if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
-          setEm = true
-        else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
-          setEm = false
-      }
-      if (len > 1) { // Strong
-        if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
-          setStrong = true
-        else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
-          setStrong = false
-      }
-      if (setStrong != null || setEm != null) {
-        if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
-        if (setEm === true) state.em = ch
-        if (setStrong === true) state.strong = ch
-        var t = getType(state)
-        if (setEm === false) state.em = false
-        if (setStrong === false) state.strong = false
-        return t
-      }
-    } else if (ch === ' ') {
-      if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
-        if (stream.peek() === ' ') { // Surrounded by spaces, ignore
-          return getType(state);
-        } else { // Not surrounded by spaces, back up pointer
-          stream.backUp(1);
-        }
-      }
-    }
-
-    if (modeCfg.strikethrough) {
-      if (ch === '~' && stream.eatWhile(ch)) {
-        if (state.strikethrough) {// Remove strikethrough
-          if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
-          var t = getType(state);
-          state.strikethrough = false;
-          return t;
-        } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
-          state.strikethrough = true;
-          if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
-          return getType(state);
-        }
-      } else if (ch === ' ') {
-        if (stream.match(/^~~/, true)) { // Probably surrounded by space
-          if (stream.peek() === ' ') { // Surrounded by spaces, ignore
-            return getType(state);
-          } else { // Not surrounded by spaces, back up pointer
-            stream.backUp(2);
-          }
-        }
-      }
-    }
-
-    if (modeCfg.emoji && ch === ":" && stream.match(/^[a-z_\d+-]+:/)) {
-      state.emoji = true;
-      if (modeCfg.highlightFormatting) state.formatting = "emoji";
-      var retType = getType(state);
-      state.emoji = false;
-      return retType;
-    }
-
-    if (ch === ' ') {
-      if (stream.match(/ +$/, false)) {
-        state.trailingSpace++;
-      } else if (state.trailingSpace) {
-        state.trailingSpaceNewLine = true;
-      }
-    }
-
-    return getType(state);
-  }
-
-  function linkInline(stream, state) {
-    var ch = stream.next();
-
-    if (ch === ">") {
-      state.f = state.inline = inlineNormal;
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      var type = getType(state);
-      if (type){
-        type += " ";
-      } else {
-        type = "";
-      }
-      return type + tokenTypes.linkInline;
-    }
-
-    stream.match(/^[^>]+/, true);
-
-    return tokenTypes.linkInline;
-  }
-
-  function linkHref(stream, state) {
-    // Check if space, and return NULL if so (to avoid marking the space)
-    if(stream.eatSpace()){
-      return null;
-    }
-    var ch = stream.next();
-    if (ch === '(' || ch === '[') {
-      state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
-      if (modeCfg.highlightFormatting) state.formatting = "link-string";
-      state.linkHref = true;
-      return getType(state);
-    }
-    return 'error';
-  }
-
-  var linkRE = {
-    ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
-    "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
-  }
-
-  function getLinkHrefInside(endChar) {
-    return function(stream, state) {
-      var ch = stream.next();
-
-      if (ch === endChar) {
-        state.f = state.inline = inlineNormal;
-        if (modeCfg.highlightFormatting) state.formatting = "link-string";
-        var returnState = getType(state);
-        state.linkHref = false;
-        return returnState;
-      }
-
-      stream.match(linkRE[endChar])
-      state.linkHref = true;
-      return getType(state);
-    };
-  }
-
-  function footnoteLink(stream, state) {
-    if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
-      state.f = footnoteLinkInside;
-      stream.next(); // Consume [
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      state.linkText = true;
-      return getType(state);
-    }
-    return switchInline(stream, state, inlineNormal);
-  }
-
-  function footnoteLinkInside(stream, state) {
-    if (stream.match(/^\]:/, true)) {
-      state.f = state.inline = footnoteUrl;
-      if (modeCfg.highlightFormatting) state.formatting = "link";
-      var returnType = getType(state);
-      state.linkText = false;
-      return returnType;
-    }
-
-    stream.match(/^([^\]\\]|\\.)+/, true);
-
-    return tokenTypes.linkText;
-  }
-
-  function footnoteUrl(stream, state) {
-    // Check if space, and return NULL if so (to avoid marking the space)
-    if(stream.eatSpace()){
-      return null;
-    }
-    // Match URL
-    stream.match(/^[^\s]+/, true);
-    // Check for link title
-    if (stream.peek() === undefined) { // End of line, set flag to check next line
-      state.linkTitle = true;
-    } else { // More content on line, check if link title
-      stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
-    }
-    state.f = state.inline = inlineNormal;
-    return tokenTypes.linkHref + " url";
-  }
-
-  var mode = {
-    startState: function() {
-      return {
-        f: blockNormal,
-
-        prevLine: {stream: null},
-        thisLine: {stream: null},
-
-        block: blockNormal,
-        htmlState: null,
-        indentation: 0,
-
-        inline: inlineNormal,
-        text: handleText,
-
-        formatting: false,
-        linkText: false,
-        linkHref: false,
-        linkTitle: false,
-        code: 0,
-        em: false,
-        strong: false,
-        header: 0,
-        setext: 0,
-        hr: false,
-        taskList: false,
-        list: false,
-        listStack: [],
-        quote: 0,
-        trailingSpace: 0,
-        trailingSpaceNewLine: false,
-        strikethrough: false,
-        emoji: false,
-        fencedEndRE: null
-      };
-    },
-
-    copyState: function(s) {
-      return {
-        f: s.f,
-
-        prevLine: s.prevLine,
-        thisLine: s.thisLine,
-
-        block: s.block,
-        htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
-        indentation: s.indentation,
-
-        localMode: s.localMode,
-        localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
-
-        inline: s.inline,
-        text: s.text,
-        formatting: false,
-        linkText: s.linkText,
-        linkTitle: s.linkTitle,
-        linkHref: s.linkHref,
-        code: s.code,
-        em: s.em,
-        strong: s.strong,
-        strikethrough: s.strikethrough,
-        emoji: s.emoji,
-        header: s.header,
-        setext: s.setext,
-        hr: s.hr,
-        taskList: s.taskList,
-        list: s.list,
-        listStack: s.listStack.slice(0),
-        quote: s.quote,
-        indentedCode: s.indentedCode,
-        trailingSpace: s.trailingSpace,
-        trailingSpaceNewLine: s.trailingSpaceNewLine,
-        md_inside: s.md_inside,
-        fencedEndRE: s.fencedEndRE
-      };
-    },
-
-    token: function(stream, state) {
-
-      // Reset state.formatting
-      state.formatting = false;
-
-      if (stream != state.thisLine.stream) {
-        state.header = 0;
-        state.hr = false;
-
-        if (stream.match(/^\s*$/, true)) {
-          blankLine(state);
-          return null;
-        }
-
-        state.prevLine = state.thisLine
-        state.thisLine = {stream: stream}
-
-        // Reset state.taskList
-        state.taskList = false;
-
-        // Reset state.trailingSpace
-        state.trailingSpace = 0;
-        state.trailingSpaceNewLine = false;
-
-        if (!state.localState) {
-          state.f = state.block;
-          if (state.f != htmlBlock) {
-            var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length;
-            state.indentation = indentation;
-            state.indentationDiff = null;
-            if (indentation > 0) return null;
-          }
-        }
-      }
-      return state.f(stream, state);
-    },
-
-    innerMode: function(state) {
-      if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
-      if (state.localState) return {state: state.localState, mode: state.localMode};
-      return {state: state, mode: mode};
-    },
-
-    indent: function(state, textAfter, line) {
-      if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line)
-      if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line)
-      return CodeMirror.Pass
-    },
-
-    blankLine: blankLine,
-
-    getType: getType,
-
-    closeBrackets: "()[]{}''\"\"``",
-    fold: "markdown"
-  };
-  return mode;
-}, "xml");
-
-CodeMirror.defineMIME("text/markdown", "markdown");
-
-CodeMirror.defineMIME("text/x-markdown", "markdown");
-
-});
diff --git a/front_end/cm_modes/module.json b/front_end/cm_modes/module.json
deleted file mode 100644
index bdcfc73..0000000
--- a/front_end/cm_modes/module.json
+++ /dev/null
@@ -1,118 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "clike.js",
-            "mimeTypes": [
-                "text/x-csrc",
-                "text/x-c",
-                "text/x-chdr",
-                "text/x-c++src",
-                "text/x-c++hdr",
-                "text/x-java",
-                "text/x-csharp",
-                "text/x-scala",
-                "x-shader/x-vertex",
-                "x-shader/x-fragment"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "coffeescript.js",
-            "mimeTypes": [
-                "text/x-coffeescript"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "markdown.js",
-            "mimeTypes": [
-                "text/markdown",
-                "text/x-markdown"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "php.js",
-            "dependencies": [
-                "clike.js"
-            ],
-            "mimeTypes": [
-                "application/x-httpd-php",
-                "application/x-httpd-php-open",
-                "text/x-php"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "python.js",
-            "mimeTypes": [
-                "text/x-python",
-                "text/x-cython"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "shell.js",
-            "mimeTypes": [
-                "text/x-sh"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "livescript.js",
-            "mimeTypes": [
-                "text/x-livescript"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "clojure.js",
-            "mimeTypes": [
-                "text/x-clojure"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "jsx.js",
-            "mimeTypes": [
-                "text/jsx"
-            ]
-        },
-        {
-            "type": "@TextEditor.CodeMirrorMimeMode",
-            "className": "CmModes.DefaultCodeMirrorMimeMode",
-            "fileName": "stylus.js",
-            "mimeTypes": [
-                "text/x-styl"
-            ]
-        }
-    ],
-    "dependencies": [
-        "text_editor"
-    ],
-    "scripts": [
-        "DefaultCodeMirrorMimeMode.js"
-    ],
-    "resources": [
-        "clike.js",
-        "coffeescript.js",
-        "php.js",
-        "python.js",
-        "shell.js",
-        "livescript.js",
-        "markdown.js",
-        "clojure.js",
-        "stylus.js",
-        "jsx.js"
-    ]
-}
diff --git a/front_end/cm_modes/php.js b/front_end/cm_modes/php.js
deleted file mode 100644
index 589c9a6..0000000
--- a/front_end/cm_modes/php.js
+++ /dev/null
@@ -1,234 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  function keywords(str) {
-    var obj = {}, words = str.split(" ");
-    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
-    return obj;
-  }
-
-  // Helper for phpString
-  function matchSequence(list, end, escapes) {
-    if (list.length == 0) return phpString(end);
-    return function (stream, state) {
-      var patterns = list[0];
-      for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
-        state.tokenize = matchSequence(list.slice(1), end);
-        return patterns[i][1];
-      }
-      state.tokenize = phpString(end, escapes);
-      return "string";
-    };
-  }
-  function phpString(closing, escapes) {
-    return function(stream, state) { return phpString_(stream, state, closing, escapes); };
-  }
-  function phpString_(stream, state, closing, escapes) {
-    // "Complex" syntax
-    if (escapes !== false && stream.match("${", false) || stream.match("{$", false)) {
-      state.tokenize = null;
-      return "string";
-    }
-
-    // Simple syntax
-    if (escapes !== false && stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
-      // After the variable name there may appear array or object operator.
-      if (stream.match("[", false)) {
-        // Match array operator
-        state.tokenize = matchSequence([
-          [["[", null]],
-          [[/\d[\w\.]*/, "number"],
-           [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
-           [/[\w\$]+/, "variable"]],
-          [["]", null]]
-        ], closing, escapes);
-      }
-      if (stream.match(/\-\>\w/, false)) {
-        // Match object operator
-        state.tokenize = matchSequence([
-          [["->", null]],
-          [[/[\w]+/, "variable"]]
-        ], closing, escapes);
-      }
-      return "variable-2";
-    }
-
-    var escaped = false;
-    // Normal string
-    while (!stream.eol() &&
-           (escaped || escapes === false ||
-            (!stream.match("{$", false) &&
-             !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) {
-      if (!escaped && stream.match(closing)) {
-        state.tokenize = null;
-        state.tokStack.pop(); state.tokStack.pop();
-        break;
-      }
-      escaped = stream.next() == "\\" && !escaped;
-    }
-    return "string";
-  }
-
-  var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
-    "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
-    "for foreach function global goto if implements interface instanceof namespace " +
-    "new or private protected public static switch throw trait try use var while xor " +
-    "die echo empty exit eval include include_once isset list require require_once return " +
-    "print unset __halt_compiler self static parent yield insteadof finally";
-  var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
-  var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists array_intersect_key array_combine array_column pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
-  CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
-  CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
-
-  var phpConfig = {
-    name: "clike",
-    helperType: "php",
-    keywords: keywords(phpKeywords),
-    blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
-    defKeywords: keywords("class function interface namespace trait"),
-    atoms: keywords(phpAtoms),
-    builtin: keywords(phpBuiltin),
-    multiLineStrings: true,
-    hooks: {
-      "$": function(stream) {
-        stream.eatWhile(/[\w\$_]/);
-        return "variable-2";
-      },
-      "<": function(stream, state) {
-        var before;
-        if (before = stream.match(/<<\s*/)) {
-          var quoted = stream.eat(/['"]/);
-          stream.eatWhile(/[\w\.]/);
-          var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));
-          if (quoted) stream.eat(quoted);
-          if (delim) {
-            (state.tokStack || (state.tokStack = [])).push(delim, 0);
-            state.tokenize = phpString(delim, quoted != "'");
-            return "string";
-          }
-        }
-        return false;
-      },
-      "#": function(stream) {
-        while (!stream.eol() && !stream.match("?>", false)) stream.next();
-        return "comment";
-      },
-      "/": function(stream) {
-        if (stream.eat("/")) {
-          while (!stream.eol() && !stream.match("?>", false)) stream.next();
-          return "comment";
-        }
-        return false;
-      },
-      '"': function(_stream, state) {
-        (state.tokStack || (state.tokStack = [])).push('"', 0);
-        state.tokenize = phpString('"');
-        return "string";
-      },
-      "{": function(_stream, state) {
-        if (state.tokStack && state.tokStack.length)
-          state.tokStack[state.tokStack.length - 1]++;
-        return false;
-      },
-      "}": function(_stream, state) {
-        if (state.tokStack && state.tokStack.length > 0 &&
-            !--state.tokStack[state.tokStack.length - 1]) {
-          state.tokenize = phpString(state.tokStack[state.tokStack.length - 2]);
-        }
-        return false;
-      }
-    }
-  };
-
-  CodeMirror.defineMode("php", function(config, parserConfig) {
-    var htmlMode = CodeMirror.getMode(config, (parserConfig && parserConfig.htmlMode) || "text/html");
-    var phpMode = CodeMirror.getMode(config, phpConfig);
-
-    function dispatch(stream, state) {
-      var isPHP = state.curMode == phpMode;
-      if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
-      if (!isPHP) {
-        if (stream.match(/^<\?\w*/)) {
-          state.curMode = phpMode;
-          if (!state.php) state.php = CodeMirror.startState(phpMode, htmlMode.indent(state.html, ""))
-          state.curState = state.php;
-          return "meta";
-        }
-        if (state.pending == '"' || state.pending == "'") {
-          while (!stream.eol() && stream.next() != state.pending) {}
-          var style = "string";
-        } else if (state.pending && stream.pos < state.pending.end) {
-          stream.pos = state.pending.end;
-          var style = state.pending.style;
-        } else {
-          var style = htmlMode.token(stream, state.curState);
-        }
-        if (state.pending) state.pending = null;
-        var cur = stream.current(), openPHP = cur.search(/<\?/), m;
-        if (openPHP != -1) {
-          if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
-          else state.pending = {end: stream.pos, style: style};
-          stream.backUp(cur.length - openPHP);
-        }
-        return style;
-      } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
-        state.curMode = htmlMode;
-        state.curState = state.html;
-        if (!state.php.context.prev) state.php = null;
-        return "meta";
-      } else {
-        return phpMode.token(stream, state.curState);
-      }
-    }
-
-    return {
-      startState: function() {
-        var html = CodeMirror.startState(htmlMode)
-        var php = parserConfig.startOpen ? CodeMirror.startState(phpMode) : null
-        return {html: html,
-                php: php,
-                curMode: parserConfig.startOpen ? phpMode : htmlMode,
-                curState: parserConfig.startOpen ? php : html,
-                pending: null};
-      },
-
-      copyState: function(state) {
-        var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
-            php = state.php, phpNew = php && CodeMirror.copyState(phpMode, php), cur;
-        if (state.curMode == htmlMode) cur = htmlNew;
-        else cur = phpNew;
-        return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
-                pending: state.pending};
-      },
-
-      token: dispatch,
-
-      indent: function(state, textAfter) {
-        if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
-            (state.curMode == phpMode && /^\?>/.test(textAfter)))
-          return htmlMode.indent(state.html, textAfter);
-        return state.curMode.indent(state.curState, textAfter);
-      },
-
-      blockCommentStart: "/*",
-      blockCommentEnd: "*/",
-      lineComment: "//",
-
-      innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
-    };
-  }, "htmlmixed", "clike");
-
-  CodeMirror.defineMIME("application/x-httpd-php", "php");
-  CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
-  CodeMirror.defineMIME("text/x-php", phpConfig);
-});
diff --git a/front_end/cm_modes/python.js b/front_end/cm_modes/python.js
deleted file mode 100644
index c318793..0000000
--- a/front_end/cm_modes/python.js
+++ /dev/null
@@ -1,334 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  function wordRegexp(words) {
-    return new RegExp("^((" + words.join(")|(") + "))\\b");
-  }
-
-  var wordOperators = wordRegexp(["and", "or", "not", "is"]);
-  var commonKeywords = ["as", "assert", "break", "class", "continue",
-                        "def", "del", "elif", "else", "except", "finally",
-                        "for", "from", "global", "if", "import",
-                        "lambda", "pass", "raise", "return",
-                        "try", "while", "with", "yield", "in"];
-  var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
-                        "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
-                        "enumerate", "eval", "filter", "float", "format", "frozenset",
-                        "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
-                        "input", "int", "isinstance", "issubclass", "iter", "len",
-                        "list", "locals", "map", "max", "memoryview", "min", "next",
-                        "object", "oct", "open", "ord", "pow", "property", "range",
-                        "repr", "reversed", "round", "set", "setattr", "slice",
-                        "sorted", "staticmethod", "str", "sum", "super", "tuple",
-                        "type", "vars", "zip", "__import__", "NotImplemented",
-                        "Ellipsis", "__debug__"];
-  CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
-
-  function top(state) {
-    return state.scopes[state.scopes.length - 1];
-  }
-
-  CodeMirror.defineMode("python", function(conf, parserConf) {
-    var ERRORCLASS = "error";
-
-    var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
-    //               (Backwards-compatiblity with old, cumbersome config system)
-    var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
-                     parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
-    for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
-
-    var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
-
-    var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
-    if (parserConf.extra_keywords != undefined)
-      myKeywords = myKeywords.concat(parserConf.extra_keywords);
-
-    if (parserConf.extra_builtins != undefined)
-      myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
-
-    var py3 = !(parserConf.version && Number(parserConf.version) < 3)
-    if (py3) {
-      // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
-      var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
-      myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
-      myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
-      var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i");
-    } else {
-      var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
-      myKeywords = myKeywords.concat(["exec", "print"]);
-      myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
-                                      "file", "intern", "long", "raw_input", "reduce", "reload",
-                                      "unichr", "unicode", "xrange", "False", "True", "None"]);
-      var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
-    }
-    var keywords = wordRegexp(myKeywords);
-    var builtins = wordRegexp(myBuiltins);
-
-    // tokenizers
-    function tokenBase(stream, state) {
-      if (stream.sol()) state.indent = stream.indentation()
-      // Handle scope changes
-      if (stream.sol() && top(state).type == "py") {
-        var scopeOffset = top(state).offset;
-        if (stream.eatSpace()) {
-          var lineOffset = stream.indentation();
-          if (lineOffset > scopeOffset)
-            pushPyScope(state);
-          else if (lineOffset < scopeOffset && dedent(stream, state) && stream.peek() != "#")
-            state.errorToken = true;
-          return null;
-        } else {
-          var style = tokenBaseInner(stream, state);
-          if (scopeOffset > 0 && dedent(stream, state))
-            style += " " + ERRORCLASS;
-          return style;
-        }
-      }
-      return tokenBaseInner(stream, state);
-    }
-
-    function tokenBaseInner(stream, state) {
-      if (stream.eatSpace()) return null;
-
-      var ch = stream.peek();
-
-      // Handle Comments
-      if (ch == "#") {
-        stream.skipToEnd();
-        return "comment";
-      }
-
-      // Handle Number Literals
-      if (stream.match(/^[0-9\.]/, false)) {
-        var floatLiteral = false;
-        // Floats
-        if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
-        if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; }
-        if (stream.match(/^\.\d+/)) { floatLiteral = true; }
-        if (floatLiteral) {
-          // Float literals may be "imaginary"
-          stream.eat(/J/i);
-          return "number";
-        }
-        // Integers
-        var intLiteral = false;
-        // Hex
-        if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true;
-        // Binary
-        if (stream.match(/^0b[01_]+/i)) intLiteral = true;
-        // Octal
-        if (stream.match(/^0o[0-7_]+/i)) intLiteral = true;
-        // Decimal
-        if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) {
-          // Decimal literals may be "imaginary"
-          stream.eat(/J/i);
-          // TODO - Can you have imaginary longs?
-          intLiteral = true;
-        }
-        // Zero by itself with no other piece of number.
-        if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
-        if (intLiteral) {
-          // Integer literals may be "long"
-          stream.eat(/L/i);
-          return "number";
-        }
-      }
-
-      // Handle Strings
-      if (stream.match(stringPrefixes)) {
-        state.tokenize = tokenStringFactory(stream.current());
-        return state.tokenize(stream, state);
-      }
-
-      for (var i = 0; i < operators.length; i++)
-        if (stream.match(operators[i])) return "operator"
-
-      if (stream.match(delimiters)) return "punctuation";
-
-      if (state.lastToken == "." && stream.match(identifiers))
-        return "property";
-
-      if (stream.match(keywords) || stream.match(wordOperators))
-        return "keyword";
-
-      if (stream.match(builtins))
-        return "builtin";
-
-      if (stream.match(/^(self|cls)\b/))
-        return "variable-2";
-
-      if (stream.match(identifiers)) {
-        if (state.lastToken == "def" || state.lastToken == "class")
-          return "def";
-        return "variable";
-      }
-
-      // Handle non-detected items
-      stream.next();
-      return ERRORCLASS;
-    }
-
-    function tokenStringFactory(delimiter) {
-      while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
-        delimiter = delimiter.substr(1);
-
-      var singleline = delimiter.length == 1;
-      var OUTCLASS = "string";
-
-      function tokenString(stream, state) {
-        while (!stream.eol()) {
-          stream.eatWhile(/[^'"\\]/);
-          if (stream.eat("\\")) {
-            stream.next();
-            if (singleline && stream.eol())
-              return OUTCLASS;
-          } else if (stream.match(delimiter)) {
-            state.tokenize = tokenBase;
-            return OUTCLASS;
-          } else {
-            stream.eat(/['"]/);
-          }
-        }
-        if (singleline) {
-          if (parserConf.singleLineStringErrors)
-            return ERRORCLASS;
-          else
-            state.tokenize = tokenBase;
-        }
-        return OUTCLASS;
-      }
-      tokenString.isString = true;
-      return tokenString;
-    }
-
-    function pushPyScope(state) {
-      while (top(state).type != "py") state.scopes.pop()
-      state.scopes.push({offset: top(state).offset + conf.indentUnit,
-                         type: "py",
-                         align: null})
-    }
-
-    function pushBracketScope(stream, state, type) {
-      var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
-      state.scopes.push({offset: state.indent + hangingIndent,
-                         type: type,
-                         align: align})
-    }
-
-    function dedent(stream, state) {
-      var indented = stream.indentation();
-      while (state.scopes.length > 1 && top(state).offset > indented) {
-        if (top(state).type != "py") return true;
-        state.scopes.pop();
-      }
-      return top(state).offset != indented;
-    }
-
-    function tokenLexer(stream, state) {
-      if (stream.sol()) state.beginningOfLine = true;
-
-      var style = state.tokenize(stream, state);
-      var current = stream.current();
-
-      // Handle decorators
-      if (state.beginningOfLine && current == "@")
-        return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ERRORCLASS;
-
-      if (/\S/.test(current)) state.beginningOfLine = false;
-
-      if ((style == "variable" || style == "builtin")
-          && state.lastToken == "meta")
-        style = "meta";
-
-      // Handle scope changes.
-      if (current == "pass" || current == "return")
-        state.dedent += 1;
-
-      if (current == "lambda") state.lambda = true;
-      if (current == ":" && !state.lambda && top(state).type == "py")
-        pushPyScope(state);
-
-      var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
-      if (delimiter_index != -1)
-        pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
-
-      delimiter_index = "])}".indexOf(current);
-      if (delimiter_index != -1) {
-        if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
-        else return ERRORCLASS;
-      }
-      if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
-        if (state.scopes.length > 1) state.scopes.pop();
-        state.dedent -= 1;
-      }
-
-      return style;
-    }
-
-    var external = {
-      startState: function(basecolumn) {
-        return {
-          tokenize: tokenBase,
-          scopes: [{offset: basecolumn || 0, type: "py", align: null}],
-          indent: basecolumn || 0,
-          lastToken: null,
-          lambda: false,
-          dedent: 0
-        };
-      },
-
-      token: function(stream, state) {
-        var addErr = state.errorToken;
-        if (addErr) state.errorToken = false;
-        var style = tokenLexer(stream, state);
-
-        if (style && style != "comment")
-          state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
-        if (style == "punctuation") style = null;
-
-        if (stream.eol() && state.lambda)
-          state.lambda = false;
-        return addErr ? style + " " + ERRORCLASS : style;
-      },
-
-      indent: function(state, textAfter) {
-        if (state.tokenize != tokenBase)
-          return state.tokenize.isString ? CodeMirror.Pass : 0;
-
-        var scope = top(state), closing = scope.type == textAfter.charAt(0)
-        if (scope.align != null)
-          return scope.align - (closing ? 1 : 0)
-        else
-          return scope.offset - (closing ? hangingIndent : 0)
-      },
-
-      electricInput: /^\s*[\}\]\)]$/,
-      closeBrackets: {triples: "'\""},
-      lineComment: "#",
-      fold: "indent"
-    };
-    return external;
-  });
-
-  CodeMirror.defineMIME("text/x-python", "python");
-
-  var words = function(str) { return str.split(" "); };
-
-  CodeMirror.defineMIME("text/x-cython", {
-    name: "python",
-    extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
-                          "extern gil include nogil property public "+
-                          "readonly struct union DEF IF ELIF ELSE")
-  });
-
-});
diff --git a/front_end/cm_modes/shell.js b/front_end/cm_modes/shell.js
deleted file mode 100644
index 9b8b90b..0000000
--- a/front_end/cm_modes/shell.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode('shell', function() {
-
-  var words = {};
-  function define(style, string) {
-    var split = string.split(' ');
-    for(var i = 0; i < split.length; i++) {
-      words[split[i]] = style;
-    }
-  };
-
-  // Atoms
-  define('atom', 'true false');
-
-  // Keywords
-  define('keyword', 'if then do else elif while until for in esac fi fin ' +
-    'fil done exit set unset export function');
-
-  // Commands
-  define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
-    'curl cut diff echo find gawk gcc get git grep hg kill killall ln ls make ' +
-    'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
-    'shopt shred source sort sleep ssh start stop su sudo svn tee telnet top ' +
-    'touch vi vim wall wc wget who write yes zsh');
-
-  function tokenBase(stream, state) {
-    if (stream.eatSpace()) return null;
-
-    var sol = stream.sol();
-    var ch = stream.next();
-
-    if (ch === '\\') {
-      stream.next();
-      return null;
-    }
-    if (ch === '\'' || ch === '"' || ch === '`') {
-      state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string"));
-      return tokenize(stream, state);
-    }
-    if (ch === '#') {
-      if (sol && stream.eat('!')) {
-        stream.skipToEnd();
-        return 'meta'; // 'comment'?
-      }
-      stream.skipToEnd();
-      return 'comment';
-    }
-    if (ch === '$') {
-      state.tokens.unshift(tokenDollar);
-      return tokenize(stream, state);
-    }
-    if (ch === '+' || ch === '=') {
-      return 'operator';
-    }
-    if (ch === '-') {
-      stream.eat('-');
-      stream.eatWhile(/\w/);
-      return 'attribute';
-    }
-    if (/\d/.test(ch)) {
-      stream.eatWhile(/\d/);
-      if(stream.eol() || !/\w/.test(stream.peek())) {
-        return 'number';
-      }
-    }
-    stream.eatWhile(/[\w-]/);
-    var cur = stream.current();
-    if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
-    return words.hasOwnProperty(cur) ? words[cur] : null;
-  }
-
-  function tokenString(quote, style) {
-    var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
-    return function(stream, state) {
-      var next, end = false, escaped = false;
-      while ((next = stream.next()) != null) {
-        if (next === close && !escaped) {
-          end = true;
-          break;
-        }
-        if (next === '$' && !escaped && quote !== "'") {
-          escaped = true;
-          stream.backUp(1);
-          state.tokens.unshift(tokenDollar);
-          break;
-        }
-        if (!escaped && next === quote && quote !== close) {
-          state.tokens.unshift(tokenString(quote, style))
-          return tokenize(stream, state)
-        }
-        escaped = !escaped && next === '\\';
-      }
-      if (end) state.tokens.shift();
-      return style;
-    };
-  };
-
-  var tokenDollar = function(stream, state) {
-    if (state.tokens.length > 1) stream.eat('$');
-    var ch = stream.next()
-    if (/['"({]/.test(ch)) {
-      state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string");
-      return tokenize(stream, state);
-    }
-    if (!/\d/.test(ch)) stream.eatWhile(/\w/);
-    state.tokens.shift();
-    return 'def';
-  };
-
-  function tokenize(stream, state) {
-    return (state.tokens[0] || tokenBase) (stream, state);
-  };
-
-  return {
-    startState: function() {return {tokens:[]};},
-    token: function(stream, state) {
-      return tokenize(stream, state);
-    },
-    closeBrackets: "()[]{}''\"\"``",
-    lineComment: '#',
-    fold: "brace"
-  };
-});
-
-CodeMirror.defineMIME('text/x-sh', 'shell');
-// Apache uses a slightly different Media Type for Shell scripts
-// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
-CodeMirror.defineMIME('application/x-sh', 'shell');
-
-});
diff --git a/front_end/cm_modes/stylus.js b/front_end/cm_modes/stylus.js
deleted file mode 100644
index b83be16..0000000
--- a/front_end/cm_modes/stylus.js
+++ /dev/null
@@ -1,771 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  CodeMirror.defineMode("stylus", function(config) {
-    var indentUnit = config.indentUnit,
-        indentUnitString = '',
-        tagKeywords = keySet(tagKeywords_),
-        tagVariablesRegexp = /^(a|b|i|s|col|em)$/i,
-        propertyKeywords = keySet(propertyKeywords_),
-        nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_),
-        valueKeywords = keySet(valueKeywords_),
-        colorKeywords = keySet(colorKeywords_),
-        documentTypes = keySet(documentTypes_),
-        documentTypesRegexp = wordRegexp(documentTypes_),
-        mediaFeatures = keySet(mediaFeatures_),
-        mediaTypes = keySet(mediaTypes_),
-        fontProperties = keySet(fontProperties_),
-        operatorsRegexp = /^\s*([.]{2,3}|&&|\|\||\*\*|[?!=:]?=|[-+*\/%<>]=?|\?:|\~)/,
-        wordOperatorKeywordsRegexp = wordRegexp(wordOperatorKeywords_),
-        blockKeywords = keySet(blockKeywords_),
-        vendorPrefixesRegexp = new RegExp(/^\-(moz|ms|o|webkit)-/i),
-        commonAtoms = keySet(commonAtoms_),
-        firstWordMatch = "",
-        states = {},
-        ch,
-        style,
-        type,
-        override;
-
-    while (indentUnitString.length < indentUnit) indentUnitString += ' ';
-
-    /**
-     * Tokenizers
-     */
-    function tokenBase(stream, state) {
-      firstWordMatch = stream.string.match(/(^[\w-]+\s*=\s*$)|(^\s*[\w-]+\s*=\s*[\w-])|(^\s*(\.|#|@|\$|\&|\[|\d|\+|::?|\{|\>|~|\/)?\s*[\w-]*([a-z0-9-]|\*|\/\*)(\(|,)?)/);
-      state.context.line.firstWord = firstWordMatch ? firstWordMatch[0].replace(/^\s*/, "") : "";
-      state.context.line.indent = stream.indentation();
-      ch = stream.peek();
-
-      // Line comment
-      if (stream.match("//")) {
-        stream.skipToEnd();
-        return ["comment", "comment"];
-      }
-      // Block comment
-      if (stream.match("/*")) {
-        state.tokenize = tokenCComment;
-        return tokenCComment(stream, state);
-      }
-      // String
-      if (ch == "\"" || ch == "'") {
-        stream.next();
-        state.tokenize = tokenString(ch);
-        return state.tokenize(stream, state);
-      }
-      // Def
-      if (ch == "@") {
-        stream.next();
-        stream.eatWhile(/[\w\\-]/);
-        return ["def", stream.current()];
-      }
-      // ID selector or Hex color
-      if (ch == "#") {
-        stream.next();
-        // Hex color
-        if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) {
-          return ["atom", "atom"];
-        }
-        // ID selector
-        if (stream.match(/^[a-z][\w-]*/i)) {
-          return ["builtin", "hash"];
-        }
-      }
-      // Vendor prefixes
-      if (stream.match(vendorPrefixesRegexp)) {
-        return ["meta", "vendor-prefixes"];
-      }
-      // Numbers
-      if (stream.match(/^-?[0-9]?\.?[0-9]/)) {
-        stream.eatWhile(/[a-z%]/i);
-        return ["number", "unit"];
-      }
-      // !important|optional
-      if (ch == "!") {
-        stream.next();
-        return [stream.match(/^(important|optional)/i) ? "keyword": "operator", "important"];
-      }
-      // Class
-      if (ch == "." && stream.match(/^\.[a-z][\w-]*/i)) {
-        return ["qualifier", "qualifier"];
-      }
-      // url url-prefix domain regexp
-      if (stream.match(documentTypesRegexp)) {
-        if (stream.peek() == "(") state.tokenize = tokenParenthesized;
-        return ["property", "word"];
-      }
-      // Mixins / Functions
-      if (stream.match(/^[a-z][\w-]*\(/i)) {
-        stream.backUp(1);
-        return ["keyword", "mixin"];
-      }
-      // Block mixins
-      if (stream.match(/^(\+|-)[a-z][\w-]*\(/i)) {
-        stream.backUp(1);
-        return ["keyword", "block-mixin"];
-      }
-      // Parent Reference BEM naming
-      if (stream.string.match(/^\s*&/) && stream.match(/^[-_]+[a-z][\w-]*/)) {
-        return ["qualifier", "qualifier"];
-      }
-      // / Root Reference & Parent Reference
-      if (stream.match(/^(\/|&)(-|_|:|\.|#|[a-z])/)) {
-        stream.backUp(1);
-        return ["variable-3", "reference"];
-      }
-      if (stream.match(/^&{1}\s*$/)) {
-        return ["variable-3", "reference"];
-      }
-      // Word operator
-      if (stream.match(wordOperatorKeywordsRegexp)) {
-        return ["operator", "operator"];
-      }
-      // Word
-      if (stream.match(/^\$?[-_]*[a-z0-9]+[\w-]*/i)) {
-        // Variable
-        if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
-          if (!wordIsTag(stream.current())) {
-            stream.match(/\./);
-            return ["variable-2", "variable-name"];
-          }
-        }
-        return ["variable-2", "word"];
-      }
-      // Operators
-      if (stream.match(operatorsRegexp)) {
-        return ["operator", stream.current()];
-      }
-      // Delimiters
-      if (/[:;,{}\[\]\(\)]/.test(ch)) {
-        stream.next();
-        return [null, ch];
-      }
-      // Non-detected items
-      stream.next();
-      return [null, null];
-    }
-
-    /**
-     * Token comment
-     */
-    function tokenCComment(stream, state) {
-      var maybeEnd = false, ch;
-      while ((ch = stream.next()) != null) {
-        if (maybeEnd && ch == "/") {
-          state.tokenize = null;
-          break;
-        }
-        maybeEnd = (ch == "*");
-      }
-      return ["comment", "comment"];
-    }
-
-    /**
-     * Token string
-     */
-    function tokenString(quote) {
-      return function(stream, state) {
-        var escaped = false, ch;
-        while ((ch = stream.next()) != null) {
-          if (ch == quote && !escaped) {
-            if (quote == ")") stream.backUp(1);
-            break;
-          }
-          escaped = !escaped && ch == "\\";
-        }
-        if (ch == quote || !escaped && quote != ")") state.tokenize = null;
-        return ["string", "string"];
-      };
-    }
-
-    /**
-     * Token parenthesized
-     */
-    function tokenParenthesized(stream, state) {
-      stream.next(); // Must be "("
-      if (!stream.match(/\s*[\"\')]/, false))
-        state.tokenize = tokenString(")");
-      else
-        state.tokenize = null;
-      return [null, "("];
-    }
-
-    /**
-     * Context management
-     */
-    function Context(type, indent, prev, line) {
-      this.type = type;
-      this.indent = indent;
-      this.prev = prev;
-      this.line = line || {firstWord: "", indent: 0};
-    }
-
-    function pushContext(state, stream, type, indent) {
-      indent = indent >= 0 ? indent : indentUnit;
-      state.context = new Context(type, stream.indentation() + indent, state.context);
-      return type;
-    }
-
-    function popContext(state, currentIndent) {
-      var contextIndent = state.context.indent - indentUnit;
-      currentIndent = currentIndent || false;
-      state.context = state.context.prev;
-      if (currentIndent) state.context.indent = contextIndent;
-      return state.context.type;
-    }
-
-    function pass(type, stream, state) {
-      return states[state.context.type](type, stream, state);
-    }
-
-    function popAndPass(type, stream, state, n) {
-      for (var i = n || 1; i > 0; i--)
-        state.context = state.context.prev;
-      return pass(type, stream, state);
-    }
-
-
-    /**
-     * Parser
-     */
-    function wordIsTag(word) {
-      return word.toLowerCase() in tagKeywords;
-    }
-
-    function wordIsProperty(word) {
-      word = word.toLowerCase();
-      return word in propertyKeywords || word in fontProperties;
-    }
-
-    function wordIsBlock(word) {
-      return word.toLowerCase() in blockKeywords;
-    }
-
-    function wordIsVendorPrefix(word) {
-      return word.toLowerCase().match(vendorPrefixesRegexp);
-    }
-
-    function wordAsValue(word) {
-      var wordLC = word.toLowerCase();
-      var override = "variable-2";
-      if (wordIsTag(word)) override = "tag";
-      else if (wordIsBlock(word)) override = "block-keyword";
-      else if (wordIsProperty(word)) override = "property";
-      else if (wordLC in valueKeywords || wordLC in commonAtoms) override = "atom";
-      else if (wordLC == "return" || wordLC in colorKeywords) override = "keyword";
-
-      // Font family
-      else if (word.match(/^[A-Z]/)) override = "string";
-      return override;
-    }
-
-    function typeIsBlock(type, stream) {
-      return ((endOfLine(stream) && (type == "{" || type == "]" || type == "hash" || type == "qualifier")) || type == "block-mixin");
-    }
-
-    function typeIsInterpolation(type, stream) {
-      return type == "{" && stream.match(/^\s*\$?[\w-]+/i, false);
-    }
-
-    function typeIsPseudo(type, stream) {
-      return type == ":" && stream.match(/^[a-z-]+/, false);
-    }
-
-    function startOfLine(stream) {
-      return stream.sol() || stream.string.match(new RegExp("^\\s*" + escapeRegExp(stream.current())));
-    }
-
-    function endOfLine(stream) {
-      return stream.eol() || stream.match(/^\s*$/, false);
-    }
-
-    function firstWordOfLine(line) {
-      var re = /^\s*[-_]*[a-z0-9]+[\w-]*/i;
-      var result = typeof line == "string" ? line.match(re) : line.string.match(re);
-      return result ? result[0].replace(/^\s*/, "") : "";
-    }
-
-
-    /**
-     * Block
-     */
-    states.block = function(type, stream, state) {
-      if ((type == "comment" && startOfLine(stream)) ||
-          (type == "," && endOfLine(stream)) ||
-          type == "mixin") {
-        return pushContext(state, stream, "block", 0);
-      }
-      if (typeIsInterpolation(type, stream)) {
-        return pushContext(state, stream, "interpolation");
-      }
-      if (endOfLine(stream) && type == "]") {
-        if (!/^\s*(\.|#|:|\[|\*|&)/.test(stream.string) && !wordIsTag(firstWordOfLine(stream))) {
-          return pushContext(state, stream, "block", 0);
-        }
-      }
-      if (typeIsBlock(type, stream)) {
-        return pushContext(state, stream, "block");
-      }
-      if (type == "}" && endOfLine(stream)) {
-        return pushContext(state, stream, "block", 0);
-      }
-      if (type == "variable-name") {
-        if (stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/) || wordIsBlock(firstWordOfLine(stream))) {
-          return pushContext(state, stream, "variableName");
-        }
-        else {
-          return pushContext(state, stream, "variableName", 0);
-        }
-      }
-      if (type == "=") {
-        if (!endOfLine(stream) && !wordIsBlock(firstWordOfLine(stream))) {
-          return pushContext(state, stream, "block", 0);
-        }
-        return pushContext(state, stream, "block");
-      }
-      if (type == "*") {
-        if (endOfLine(stream) || stream.match(/\s*(,|\.|#|\[|:|{)/,false)) {
-          override = "tag";
-          return pushContext(state, stream, "block");
-        }
-      }
-      if (typeIsPseudo(type, stream)) {
-        return pushContext(state, stream, "pseudo");
-      }
-      if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {
-        return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock");
-      }
-      if (/@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
-        return pushContext(state, stream, "keyframes");
-      }
-      if (/@extends?/.test(type)) {
-        return pushContext(state, stream, "extend", 0);
-      }
-      if (type && type.charAt(0) == "@") {
-
-        // Property Lookup
-        if (stream.indentation() > 0 && wordIsProperty(stream.current().slice(1))) {
-          override = "variable-2";
-          return "block";
-        }
-        if (/(@import|@require|@charset)/.test(type)) {
-          return pushContext(state, stream, "block", 0);
-        }
-        return pushContext(state, stream, "block");
-      }
-      if (type == "reference" && endOfLine(stream)) {
-        return pushContext(state, stream, "block");
-      }
-      if (type == "(") {
-        return pushContext(state, stream, "parens");
-      }
-
-      if (type == "vendor-prefixes") {
-        return pushContext(state, stream, "vendorPrefixes");
-      }
-      if (type == "word") {
-        var word = stream.current();
-        override = wordAsValue(word);
-
-        if (override == "property") {
-          if (startOfLine(stream)) {
-            return pushContext(state, stream, "block", 0);
-          } else {
-            override = "atom";
-            return "block";
-          }
-        }
-
-        if (override == "tag") {
-
-          // tag is a css value
-          if (/embed|menu|pre|progress|sub|table/.test(word)) {
-            if (wordIsProperty(firstWordOfLine(stream))) {
-              override = "atom";
-              return "block";
-            }
-          }
-
-          // tag is an attribute
-          if (stream.string.match(new RegExp("\\[\\s*" + word + "|" + word +"\\s*\\]"))) {
-            override = "atom";
-            return "block";
-          }
-
-          // tag is a variable
-          if (tagVariablesRegexp.test(word)) {
-            if ((startOfLine(stream) && stream.string.match(/=/)) ||
-                (!startOfLine(stream) &&
-                 !stream.string.match(/^(\s*\.|#|\&|\[|\/|>|\*)/) &&
-                 !wordIsTag(firstWordOfLine(stream)))) {
-              override = "variable-2";
-              if (wordIsBlock(firstWordOfLine(stream)))  return "block";
-              return pushContext(state, stream, "block", 0);
-            }
-          }
-
-          if (endOfLine(stream)) return pushContext(state, stream, "block");
-        }
-        if (override == "block-keyword") {
-          override = "keyword";
-
-          // Postfix conditionals
-          if (stream.current(/(if|unless)/) && !startOfLine(stream)) {
-            return "block";
-          }
-          return pushContext(state, stream, "block");
-        }
-        if (word == "return") return pushContext(state, stream, "block", 0);
-
-        // Placeholder selector
-        if (override == "variable-2" && stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/)) {
-          return pushContext(state, stream, "block");
-        }
-      }
-      return state.context.type;
-    };
-
-
-    /**
-     * Parens
-     */
-    states.parens = function(type, stream, state) {
-      if (type == "(") return pushContext(state, stream, "parens");
-      if (type == ")") {
-        if (state.context.prev.type == "parens") {
-          return popContext(state);
-        }
-        if ((stream.string.match(/^[a-z][\w-]*\(/i) && endOfLine(stream)) ||
-            wordIsBlock(firstWordOfLine(stream)) ||
-            /(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(firstWordOfLine(stream)) ||
-            (!stream.string.match(/^-?[a-z][\w-\.\[\]\'\"]*\s*=/) &&
-             wordIsTag(firstWordOfLine(stream)))) {
-          return pushContext(state, stream, "block");
-        }
-        if (stream.string.match(/^[\$-]?[a-z][\w-\.\[\]\'\"]*\s*=/) ||
-            stream.string.match(/^\s*(\(|\)|[0-9])/) ||
-            stream.string.match(/^\s+[a-z][\w-]*\(/i) ||
-            stream.string.match(/^\s+[\$-]?[a-z]/i)) {
-          return pushContext(state, stream, "block", 0);
-        }
-        if (endOfLine(stream)) return pushContext(state, stream, "block");
-        else return pushContext(state, stream, "block", 0);
-      }
-      if (type && type.charAt(0) == "@" && wordIsProperty(stream.current().slice(1))) {
-        override = "variable-2";
-      }
-      if (type == "word") {
-        var word = stream.current();
-        override = wordAsValue(word);
-        if (override == "tag" && tagVariablesRegexp.test(word)) {
-          override = "variable-2";
-        }
-        if (override == "property" || word == "to") override = "atom";
-      }
-      if (type == "variable-name") {
-        return pushContext(state, stream, "variableName");
-      }
-      if (typeIsPseudo(type, stream)) {
-        return pushContext(state, stream, "pseudo");
-      }
-      return state.context.type;
-    };
-
-
-    /**
-     * Vendor prefixes
-     */
-    states.vendorPrefixes = function(type, stream, state) {
-      if (type == "word") {
-        override = "property";
-        return pushContext(state, stream, "block", 0);
-      }
-      return popContext(state);
-    };
-
-
-    /**
-     * Pseudo
-     */
-    states.pseudo = function(type, stream, state) {
-      if (!wordIsProperty(firstWordOfLine(stream.string))) {
-        stream.match(/^[a-z-]+/);
-        override = "variable-3";
-        if (endOfLine(stream)) return pushContext(state, stream, "block");
-        return popContext(state);
-      }
-      return popAndPass(type, stream, state);
-    };
-
-
-    /**
-     * atBlock
-     */
-    states.atBlock = function(type, stream, state) {
-      if (type == "(") return pushContext(state, stream, "atBlock_parens");
-      if (typeIsBlock(type, stream)) {
-        return pushContext(state, stream, "block");
-      }
-      if (typeIsInterpolation(type, stream)) {
-        return pushContext(state, stream, "interpolation");
-      }
-      if (type == "word") {
-        var word = stream.current().toLowerCase();
-        if (/^(only|not|and|or)$/.test(word))
-          override = "keyword";
-        else if (documentTypes.hasOwnProperty(word))
-          override = "tag";
-        else if (mediaTypes.hasOwnProperty(word))
-          override = "attribute";
-        else if (mediaFeatures.hasOwnProperty(word))
-          override = "property";
-        else if (nonStandardPropertyKeywords.hasOwnProperty(word))
-          override = "string-2";
-        else override = wordAsValue(stream.current());
-        if (override == "tag" && endOfLine(stream)) {
-          return pushContext(state, stream, "block");
-        }
-      }
-      if (type == "operator" && /^(not|and|or)$/.test(stream.current())) {
-        override = "keyword";
-      }
-      return state.context.type;
-    };
-
-    states.atBlock_parens = function(type, stream, state) {
-      if (type == "{" || type == "}") return state.context.type;
-      if (type == ")") {
-        if (endOfLine(stream)) return pushContext(state, stream, "block");
-        else return pushContext(state, stream, "atBlock");
-      }
-      if (type == "word") {
-        var word = stream.current().toLowerCase();
-        override = wordAsValue(word);
-        if (/^(max|min)/.test(word)) override = "property";
-        if (override == "tag") {
-          tagVariablesRegexp.test(word) ? override = "variable-2" : override = "atom";
-        }
-        return state.context.type;
-      }
-      return states.atBlock(type, stream, state);
-    };
-
-
-    /**
-     * Keyframes
-     */
-    states.keyframes = function(type, stream, state) {
-      if (stream.indentation() == "0" && ((type == "}" && startOfLine(stream)) || type == "]" || type == "hash"
-                                          || type == "qualifier" || wordIsTag(stream.current()))) {
-        return popAndPass(type, stream, state);
-      }
-      if (type == "{") return pushContext(state, stream, "keyframes");
-      if (type == "}") {
-        if (startOfLine(stream)) return popContext(state, true);
-        else return pushContext(state, stream, "keyframes");
-      }
-      if (type == "unit" && /^[0-9]+\%$/.test(stream.current())) {
-        return pushContext(state, stream, "keyframes");
-      }
-      if (type == "word") {
-        override = wordAsValue(stream.current());
-        if (override == "block-keyword") {
-          override = "keyword";
-          return pushContext(state, stream, "keyframes");
-        }
-      }
-      if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {
-        return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock");
-      }
-      if (type == "mixin") {
-        return pushContext(state, stream, "block", 0);
-      }
-      return state.context.type;
-    };
-
-
-    /**
-     * Interpolation
-     */
-    states.interpolation = function(type, stream, state) {
-      if (type == "{") popContext(state) && pushContext(state, stream, "block");
-      if (type == "}") {
-        if (stream.string.match(/^\s*(\.|#|:|\[|\*|&|>|~|\+|\/)/i) ||
-            (stream.string.match(/^\s*[a-z]/i) && wordIsTag(firstWordOfLine(stream)))) {
-          return pushContext(state, stream, "block");
-        }
-        if (!stream.string.match(/^(\{|\s*\&)/) ||
-            stream.match(/\s*[\w-]/,false)) {
-          return pushContext(state, stream, "block", 0);
-        }
-        return pushContext(state, stream, "block");
-      }
-      if (type == "variable-name") {
-        return pushContext(state, stream, "variableName", 0);
-      }
-      if (type == "word") {
-        override = wordAsValue(stream.current());
-        if (override == "tag") override = "atom";
-      }
-      return state.context.type;
-    };
-
-
-    /**
-     * Extend/s
-     */
-    states.extend = function(type, stream, state) {
-      if (type == "[" || type == "=") return "extend";
-      if (type == "]") return popContext(state);
-      if (type == "word") {
-        override = wordAsValue(stream.current());
-        return "extend";
-      }
-      return popContext(state);
-    };
-
-
-    /**
-     * Variable name
-     */
-    states.variableName = function(type, stream, state) {
-      if (type == "string" || type == "[" || type == "]" || stream.current().match(/^(\.|\$)/)) {
-        if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2";
-        return "variableName";
-      }
-      return popAndPass(type, stream, state);
-    };
-
-
-    return {
-      startState: function(base) {
-        return {
-          tokenize: null,
-          state: "block",
-          context: new Context("block", base || 0, null)
-        };
-      },
-      token: function(stream, state) {
-        if (!state.tokenize && stream.eatSpace()) return null;
-        style = (state.tokenize || tokenBase)(stream, state);
-        if (style && typeof style == "object") {
-          type = style[1];
-          style = style[0];
-        }
-        override = style;
-        state.state = states[state.state](type, stream, state);
-        return override;
-      },
-      indent: function(state, textAfter, line) {
-
-        var cx = state.context,
-            ch = textAfter && textAfter.charAt(0),
-            indent = cx.indent,
-            lineFirstWord = firstWordOfLine(textAfter),
-            lineIndent = line.match(/^\s*/)[0].replace(/\t/g, indentUnitString).length,
-            prevLineFirstWord = state.context.prev ? state.context.prev.line.firstWord : "",
-            prevLineIndent = state.context.prev ? state.context.prev.line.indent : lineIndent;
-
-        if (cx.prev &&
-            (ch == "}" && (cx.type == "block" || cx.type == "atBlock" || cx.type == "keyframes") ||
-             ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
-             ch == "{" && (cx.type == "at"))) {
-          indent = cx.indent - indentUnit;
-        } else if (!(/(\})/.test(ch))) {
-          if (/@|\$|\d/.test(ch) ||
-              /^\{/.test(textAfter) ||
-/^\s*\/(\/|\*)/.test(textAfter) ||
-              /^\s*\/\*/.test(prevLineFirstWord) ||
-              /^\s*[\w-\.\[\]\'\"]+\s*(\?|:|\+)?=/i.test(textAfter) ||
-/^(\+|-)?[a-z][\w-]*\(/i.test(textAfter) ||
-/^return/.test(textAfter) ||
-              wordIsBlock(lineFirstWord)) {
-            indent = lineIndent;
-          } else if (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(ch) || wordIsTag(lineFirstWord)) {
-            if (/\,\s*$/.test(prevLineFirstWord)) {
-              indent = prevLineIndent;
-            } else if (/^\s+/.test(line) && (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(prevLineFirstWord) || wordIsTag(prevLineFirstWord))) {
-              indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;
-            } else {
-              indent = lineIndent;
-            }
-          } else if (!/,\s*$/.test(line) && (wordIsVendorPrefix(lineFirstWord) || wordIsProperty(lineFirstWord))) {
-            if (wordIsBlock(prevLineFirstWord)) {
-              indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;
-            } else if (/^\{/.test(prevLineFirstWord)) {
-              indent = lineIndent <= prevLineIndent ? lineIndent : prevLineIndent + indentUnit;
-            } else if (wordIsVendorPrefix(prevLineFirstWord) || wordIsProperty(prevLineFirstWord)) {
-              indent = lineIndent >= prevLineIndent ? prevLineIndent : lineIndent;
-            } else if (/^(\.|#|:|\[|\*|&|@|\+|\-|>|~|\/)/.test(prevLineFirstWord) ||
-                      /=\s*$/.test(prevLineFirstWord) ||
-                      wordIsTag(prevLineFirstWord) ||
-                      /^\$[\w-\.\[\]\'\"]/.test(prevLineFirstWord)) {
-              indent = prevLineIndent + indentUnit;
-            } else {
-              indent = lineIndent;
-            }
-          }
-        }
-        return indent;
-      },
-      electricChars: "}",
-      lineComment: "//",
-      fold: "indent"
-    };
-  });
-
-  // developer.mozilla.org/en-US/docs/Web/HTML/Element
-  var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b", "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","caption","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe", "img","input","ins","kbd","keygen","label","legend","li","link","main","map", "mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "noscript","object","ol","optgroup","option","output","p","param","pre", "progress","q","rp","rt","ruby","s","samp","script","section","select", "small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","track", "u","ul","var","video"];
-
-  // github.com/codemirror/CodeMirror/blob/master/mode/css/css.js
-  var documentTypes_ = ["domain", "regexp", "url", "url-prefix"];
-  var mediaTypes_ = ["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"];
-  var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"];
-  var propertyKeywords_ = ["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode","font-smoothing","osx-font-smoothing"];
-  var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
-  var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
-  var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
-  var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"];
-
-  var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
-      blockKeywords_ = ["for","if","else","unless", "from", "to"],
-      commonAtoms_ = ["null","true","false","href","title","type","not-allowed","readonly","disabled"],
-      commonDef_ = ["@font-face", "@keyframes", "@media", "@viewport", "@page", "@host", "@supports", "@block", "@css"];
-
-  var hintWords = tagKeywords_.concat(documentTypes_,mediaTypes_,mediaFeatures_,
-                                      propertyKeywords_,nonStandardPropertyKeywords_,
-                                      colorKeywords_,valueKeywords_,fontProperties_,
-                                      wordOperatorKeywords_,blockKeywords_,
-                                      commonAtoms_,commonDef_);
-
-  function wordRegexp(words) {
-    words = words.sort(function(a,b){return b > a;});
-    return new RegExp("^((" + words.join(")|(") + "))\\b");
-  }
-
-  function keySet(array) {
-    var keys = {};
-    for (var i = 0; i < array.length; ++i) keys[array[i]] = true;
-    return keys;
-  }
-
-  function escapeRegExp(text) {
-    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
-  }
-
-  CodeMirror.registerHelper("hintWords", "stylus", hintWords);
-  CodeMirror.defineMIME("text/x-styl", "stylus");
-});
diff --git a/front_end/cm_web_modes/css.js b/front_end/cm_web_modes/css.js
deleted file mode 100644
index 00e9b3d..0000000
--- a/front_end/cm_web_modes/css.js
+++ /dev/null
@@ -1,832 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("css", function(config, parserConfig) {
-  var inline = parserConfig.inline
-  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
-
-  var indentUnit = config.indentUnit,
-      tokenHooks = parserConfig.tokenHooks,
-      documentTypes = parserConfig.documentTypes || {},
-      mediaTypes = parserConfig.mediaTypes || {},
-      mediaFeatures = parserConfig.mediaFeatures || {},
-      mediaValueKeywords = parserConfig.mediaValueKeywords || {},
-      propertyKeywords = parserConfig.propertyKeywords || {},
-      nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
-      fontProperties = parserConfig.fontProperties || {},
-      counterDescriptors = parserConfig.counterDescriptors || {},
-      colorKeywords = parserConfig.colorKeywords || {},
-      valueKeywords = parserConfig.valueKeywords || {},
-      allowNested = parserConfig.allowNested,
-      lineComment = parserConfig.lineComment,
-      supportsAtComponent = parserConfig.supportsAtComponent === true;
-
-  var type, override;
-  function ret(style, tp) { type = tp; return style; }
-
-  // Tokenizers
-
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (tokenHooks[ch]) {
-      var result = tokenHooks[ch](stream, state);
-      if (result !== false) return result;
-    }
-    if (ch == "@") {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("def", stream.current());
-    } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
-      return ret(null, "compare");
-    } else if (ch == "\"" || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    } else if (ch == "#") {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("atom", "hash");
-    } else if (ch == "!") {
-      stream.match(/^\s*\w*/);
-      return ret("keyword", "important");
-    } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
-      stream.eatWhile(/[\w.%]/);
-      return ret("number", "unit");
-    } else if (ch === "-") {
-      if (/[\d.]/.test(stream.peek())) {
-        stream.eatWhile(/[\w.%]/);
-        return ret("number", "unit");
-      } else if (stream.match(/^-[\w\\\-]+/)) {
-        stream.eatWhile(/[\w\\\-]/);
-        if (stream.match(/^\s*:/, false))
-          return ret("variable-2", "variable-definition");
-        return ret("variable-2", "variable");
-      } else if (stream.match(/^\w+-/)) {
-        return ret("meta", "meta");
-      }
-    } else if (/[,+>*\/]/.test(ch)) {
-      return ret(null, "select-op");
-    } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
-      return ret("qualifier", "qualifier");
-    } else if (/[:;{}\[\]\(\)]/.test(ch)) {
-      return ret(null, ch);
-    } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
-               (ch == "d" && stream.match("omain(")) ||
-               (ch == "r" && stream.match("egexp("))) {
-      stream.backUp(1);
-      state.tokenize = tokenParenthesized;
-      return ret("property", "word");
-    } else if (/[\w\\\-]/.test(ch)) {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("property", "word");
-    } else {
-      return ret(null, null);
-    }
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, ch;
-      while ((ch = stream.next()) != null) {
-        if (ch == quote && !escaped) {
-          if (quote == ")") stream.backUp(1);
-          break;
-        }
-        escaped = !escaped && ch == "\\";
-      }
-      if (ch == quote || !escaped && quote != ")") state.tokenize = null;
-      return ret("string", "string");
-    };
-  }
-
-  function tokenParenthesized(stream, state) {
-    stream.next(); // Must be '('
-    if (!stream.match(/\s*[\"\')]/, false))
-      state.tokenize = tokenString(")");
-    else
-      state.tokenize = null;
-    return ret(null, "(");
-  }
-
-  // Context management
-
-  function Context(type, indent, prev) {
-    this.type = type;
-    this.indent = indent;
-    this.prev = prev;
-  }
-
-  function pushContext(state, stream, type, indent) {
-    state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
-    return type;
-  }
-
-  function popContext(state) {
-    if (state.context.prev)
-      state.context = state.context.prev;
-    return state.context.type;
-  }
-
-  function pass(type, stream, state) {
-    return states[state.context.type](type, stream, state);
-  }
-  function popAndPass(type, stream, state, n) {
-    for (var i = n || 1; i > 0; i--)
-      state.context = state.context.prev;
-    return pass(type, stream, state);
-  }
-
-  // Parser
-
-  function wordAsValue(stream) {
-    var word = stream.current().toLowerCase();
-    if (valueKeywords.hasOwnProperty(word))
-      override = "atom";
-    else if (colorKeywords.hasOwnProperty(word))
-      override = "keyword";
-    else
-      override = "variable";
-  }
-
-  var states = {};
-
-  states.top = function(type, stream, state) {
-    if (type == "{") {
-      return pushContext(state, stream, "block");
-    } else if (type == "}" && state.context.prev) {
-      return popContext(state);
-    } else if (supportsAtComponent && /@component/.test(type)) {
-      return pushContext(state, stream, "atComponentBlock");
-    } else if (/^@(-moz-)?document$/.test(type)) {
-      return pushContext(state, stream, "documentTypes");
-    } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
-      return pushContext(state, stream, "atBlock");
-    } else if (/^@(font-face|counter-style)/.test(type)) {
-      state.stateArg = type;
-      return "restricted_atBlock_before";
-    } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
-      return "keyframes";
-    } else if (type && type.charAt(0) == "@") {
-      return pushContext(state, stream, "at");
-    } else if (type == "hash") {
-      override = "builtin";
-    } else if (type == "word") {
-      override = "tag";
-    } else if (type == "variable-definition") {
-      return "maybeprop";
-    } else if (type == "interpolation") {
-      return pushContext(state, stream, "interpolation");
-    } else if (type == ":") {
-      return "pseudo";
-    } else if (allowNested && type == "(") {
-      return pushContext(state, stream, "parens");
-    }
-    return state.context.type;
-  };
-
-  states.block = function(type, stream, state) {
-    if (type == "word") {
-      var word = stream.current().toLowerCase();
-      if (propertyKeywords.hasOwnProperty(word)) {
-        override = "property";
-        return "maybeprop";
-      } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
-        override = "string-2";
-        return "maybeprop";
-      } else if (allowNested) {
-        override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
-        return "block";
-      } else {
-        override += " error";
-        return "maybeprop";
-      }
-    } else if (type == "meta") {
-      return "block";
-    } else if (!allowNested && (type == "hash" || type == "qualifier")) {
-      override = "error";
-      return "block";
-    } else {
-      return states.top(type, stream, state);
-    }
-  };
-
-  states.maybeprop = function(type, stream, state) {
-    if (type == ":") return pushContext(state, stream, "prop");
-    return pass(type, stream, state);
-  };
-
-  states.prop = function(type, stream, state) {
-    if (type == ";") return popContext(state);
-    if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
-    if (type == "}" || type == "{") return popAndPass(type, stream, state);
-    if (type == "(") return pushContext(state, stream, "parens");
-
-    if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
-      override += " error";
-    } else if (type == "word") {
-      wordAsValue(stream);
-    } else if (type == "interpolation") {
-      return pushContext(state, stream, "interpolation");
-    }
-    return "prop";
-  };
-
-  states.propBlock = function(type, _stream, state) {
-    if (type == "}") return popContext(state);
-    if (type == "word") { override = "property"; return "maybeprop"; }
-    return state.context.type;
-  };
-
-  states.parens = function(type, stream, state) {
-    if (type == "{" || type == "}") return popAndPass(type, stream, state);
-    if (type == ")") return popContext(state);
-    if (type == "(") return pushContext(state, stream, "parens");
-    if (type == "interpolation") return pushContext(state, stream, "interpolation");
-    if (type == "word") wordAsValue(stream);
-    return "parens";
-  };
-
-  states.pseudo = function(type, stream, state) {
-    if (type == "meta") return "pseudo";
-
-    if (type == "word") {
-      override = "variable-3";
-      return state.context.type;
-    }
-    return pass(type, stream, state);
-  };
-
-  states.documentTypes = function(type, stream, state) {
-    if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
-      override = "tag";
-      return state.context.type;
-    } else {
-      return states.atBlock(type, stream, state);
-    }
-  };
-
-  states.atBlock = function(type, stream, state) {
-    if (type == "(") return pushContext(state, stream, "atBlock_parens");
-    if (type == "}" || type == ";") return popAndPass(type, stream, state);
-    if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
-
-    if (type == "interpolation") return pushContext(state, stream, "interpolation");
-
-    if (type == "word") {
-      var word = stream.current().toLowerCase();
-      if (word == "only" || word == "not" || word == "and" || word == "or")
-        override = "keyword";
-      else if (mediaTypes.hasOwnProperty(word))
-        override = "attribute";
-      else if (mediaFeatures.hasOwnProperty(word))
-        override = "property";
-      else if (mediaValueKeywords.hasOwnProperty(word))
-        override = "keyword";
-      else if (propertyKeywords.hasOwnProperty(word))
-        override = "property";
-      else if (nonStandardPropertyKeywords.hasOwnProperty(word))
-        override = "string-2";
-      else if (valueKeywords.hasOwnProperty(word))
-        override = "atom";
-      else if (colorKeywords.hasOwnProperty(word))
-        override = "keyword";
-      else
-        override = "error";
-    }
-    return state.context.type;
-  };
-
-  states.atComponentBlock = function(type, stream, state) {
-    if (type == "}")
-      return popAndPass(type, stream, state);
-    if (type == "{")
-      return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
-    if (type == "word")
-      override = "error";
-    return state.context.type;
-  };
-
-  states.atBlock_parens = function(type, stream, state) {
-    if (type == ")") return popContext(state);
-    if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
-    return states.atBlock(type, stream, state);
-  };
-
-  states.restricted_atBlock_before = function(type, stream, state) {
-    if (type == "{")
-      return pushContext(state, stream, "restricted_atBlock");
-    if (type == "word" && state.stateArg == "@counter-style") {
-      override = "variable";
-      return "restricted_atBlock_before";
-    }
-    return pass(type, stream, state);
-  };
-
-  states.restricted_atBlock = function(type, stream, state) {
-    if (type == "}") {
-      state.stateArg = null;
-      return popContext(state);
-    }
-    if (type == "word") {
-      if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
-          (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
-        override = "error";
-      else
-        override = "property";
-      return "maybeprop";
-    }
-    return "restricted_atBlock";
-  };
-
-  states.keyframes = function(type, stream, state) {
-    if (type == "word") { override = "variable"; return "keyframes"; }
-    if (type == "{") return pushContext(state, stream, "top");
-    return pass(type, stream, state);
-  };
-
-  states.at = function(type, stream, state) {
-    if (type == ";") return popContext(state);
-    if (type == "{" || type == "}") return popAndPass(type, stream, state);
-    if (type == "word") override = "tag";
-    else if (type == "hash") override = "builtin";
-    return "at";
-  };
-
-  states.interpolation = function(type, stream, state) {
-    if (type == "}") return popContext(state);
-    if (type == "{" || type == ";") return popAndPass(type, stream, state);
-    if (type == "word") override = "variable";
-    else if (type != "variable" && type != "(" && type != ")") override = "error";
-    return "interpolation";
-  };
-
-  return {
-    startState: function(base) {
-      return {tokenize: null,
-              state: inline ? "block" : "top",
-              stateArg: null,
-              context: new Context(inline ? "block" : "top", base || 0, null)};
-    },
-
-    token: function(stream, state) {
-      if (!state.tokenize && stream.eatSpace()) return null;
-      var style = (state.tokenize || tokenBase)(stream, state);
-      if (style && typeof style == "object") {
-        type = style[1];
-        style = style[0];
-      }
-      override = style;
-      if (type != "comment")
-        state.state = states[state.state](type, stream, state);
-      return override;
-    },
-
-    indent: function(state, textAfter) {
-      var cx = state.context, ch = textAfter && textAfter.charAt(0);
-      var indent = cx.indent;
-      if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
-      if (cx.prev) {
-        if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
-                          cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
-          // Resume indentation from parent context.
-          cx = cx.prev;
-          indent = cx.indent;
-        } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
-            ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
-          // Dedent relative to current context.
-          indent = Math.max(0, cx.indent - indentUnit);
-        }
-      }
-      return indent;
-    },
-
-    electricChars: "}",
-    blockCommentStart: "/*",
-    blockCommentEnd: "*/",
-    blockCommentContinue: " * ",
-    lineComment: lineComment,
-    fold: "brace"
-  };
-});
-
-  function keySet(array) {
-    var keys = {};
-    for (var i = 0; i < array.length; ++i) {
-      keys[array[i].toLowerCase()] = true;
-    }
-    return keys;
-  }
-
-  var documentTypes_ = [
-    "domain", "regexp", "url", "url-prefix"
-  ], documentTypes = keySet(documentTypes_);
-
-  var mediaTypes_ = [
-    "all", "aural", "braille", "handheld", "print", "projection", "screen",
-    "tty", "tv", "embossed"
-  ], mediaTypes = keySet(mediaTypes_);
-
-  var mediaFeatures_ = [
-    "width", "min-width", "max-width", "height", "min-height", "max-height",
-    "device-width", "min-device-width", "max-device-width", "device-height",
-    "min-device-height", "max-device-height", "aspect-ratio",
-    "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
-    "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
-    "max-color", "color-index", "min-color-index", "max-color-index",
-    "monochrome", "min-monochrome", "max-monochrome", "resolution",
-    "min-resolution", "max-resolution", "scan", "grid", "orientation",
-    "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
-    "pointer", "any-pointer", "hover", "any-hover"
-  ], mediaFeatures = keySet(mediaFeatures_);
-
-  var mediaValueKeywords_ = [
-    "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
-    "interlace", "progressive"
-  ], mediaValueKeywords = keySet(mediaValueKeywords_);
-
-  var propertyKeywords_ = [
-    "align-content", "align-items", "align-self", "alignment-adjust",
-    "alignment-baseline", "anchor-point", "animation", "animation-delay",
-    "animation-direction", "animation-duration", "animation-fill-mode",
-    "animation-iteration-count", "animation-name", "animation-play-state",
-    "animation-timing-function", "appearance", "azimuth", "backface-visibility",
-    "background", "background-attachment", "background-blend-mode", "background-clip",
-    "background-color", "background-image", "background-origin", "background-position",
-    "background-repeat", "background-size", "baseline-shift", "binding",
-    "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
-    "bookmark-target", "border", "border-bottom", "border-bottom-color",
-    "border-bottom-left-radius", "border-bottom-right-radius",
-    "border-bottom-style", "border-bottom-width", "border-collapse",
-    "border-color", "border-image", "border-image-outset",
-    "border-image-repeat", "border-image-slice", "border-image-source",
-    "border-image-width", "border-left", "border-left-color",
-    "border-left-style", "border-left-width", "border-radius", "border-right",
-    "border-right-color", "border-right-style", "border-right-width",
-    "border-spacing", "border-style", "border-top", "border-top-color",
-    "border-top-left-radius", "border-top-right-radius", "border-top-style",
-    "border-top-width", "border-width", "bottom", "box-decoration-break",
-    "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
-    "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
-    "column-fill", "column-gap", "column-rule", "column-rule-color",
-    "column-rule-style", "column-rule-width", "column-span", "column-width",
-    "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
-    "cue-after", "cue-before", "cursor", "direction", "display",
-    "dominant-baseline", "drop-initial-after-adjust",
-    "drop-initial-after-align", "drop-initial-before-adjust",
-    "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
-    "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
-    "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
-    "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
-    "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
-    "font-stretch", "font-style", "font-synthesis", "font-variant",
-    "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
-    "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
-    "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
-    "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
-    "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
-    "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
-    "grid-template-rows", "hanging-punctuation", "height", "hyphens",
-    "icon", "image-orientation", "image-rendering", "image-resolution",
-    "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
-    "line-break", "line-height", "line-stacking", "line-stacking-ruby",
-    "line-stacking-shift", "line-stacking-strategy", "list-style",
-    "list-style-image", "list-style-position", "list-style-type", "margin",
-    "margin-bottom", "margin-left", "margin-right", "margin-top",
-    "marks", "marquee-direction", "marquee-loop",
-    "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
-    "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
-    "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
-    "opacity", "order", "orphans", "outline",
-    "outline-color", "outline-offset", "outline-style", "outline-width",
-    "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
-    "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
-    "page", "page-break-after", "page-break-before", "page-break-inside",
-    "page-policy", "pause", "pause-after", "pause-before", "perspective",
-    "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
-    "presentation-level", "punctuation-trim", "quotes", "region-break-after",
-    "region-break-before", "region-break-inside", "region-fragment",
-    "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
-    "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
-    "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
-    "shape-outside", "size", "speak", "speak-as", "speak-header",
-    "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
-    "tab-size", "table-layout", "target", "target-name", "target-new",
-    "target-position", "text-align", "text-align-last", "text-decoration",
-    "text-decoration-color", "text-decoration-line", "text-decoration-skip",
-    "text-decoration-style", "text-emphasis", "text-emphasis-color",
-    "text-emphasis-position", "text-emphasis-style", "text-height",
-    "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
-    "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
-    "text-wrap", "top", "transform", "transform-origin", "transform-style",
-    "transition", "transition-delay", "transition-duration",
-    "transition-property", "transition-timing-function", "unicode-bidi",
-    "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
-    "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
-    "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
-    "word-spacing", "word-wrap", "z-index",
-    // SVG-specific
-    "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
-    "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
-    "color-interpolation", "color-interpolation-filters",
-    "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
-    "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
-    "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
-    "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
-    "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
-    "glyph-orientation-vertical", "text-anchor", "writing-mode"
-  ], propertyKeywords = keySet(propertyKeywords_);
-
-  var nonStandardPropertyKeywords_ = [
-    "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
-    "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
-    "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
-    "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
-    "searchfield-results-decoration", "zoom"
-  ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
-
-  var fontProperties_ = [
-    "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
-    "font-stretch", "font-weight", "font-style"
-  ], fontProperties = keySet(fontProperties_);
-
-  var counterDescriptors_ = [
-    "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
-    "speak-as", "suffix", "symbols", "system"
-  ], counterDescriptors = keySet(counterDescriptors_);
-
-  var colorKeywords_ = [
-    "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
-    "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
-    "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
-    "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
-    "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
-    "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
-    "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
-    "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
-    "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
-    "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
-    "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
-    "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
-    "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
-    "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
-    "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
-    "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
-    "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
-    "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
-    "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
-    "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
-    "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
-    "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
-    "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
-    "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
-    "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
-    "whitesmoke", "yellow", "yellowgreen"
-  ], colorKeywords = keySet(colorKeywords_);
-
-  var valueKeywords_ = [
-    "above", "absolute", "activeborder", "additive", "activecaption", "afar",
-    "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
-    "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
-    "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
-    "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
-    "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
-    "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
-    "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
-    "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
-    "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
-    "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
-    "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
-    "compact", "condensed", "contain", "content", "contents",
-    "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
-    "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
-    "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
-    "destination-in", "destination-out", "destination-over", "devanagari", "difference",
-    "disc", "discard", "disclosure-closed", "disclosure-open", "document",
-    "dot-dash", "dot-dot-dash",
-    "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
-    "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
-    "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
-    "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
-    "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
-    "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
-    "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
-    "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
-    "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
-    "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
-    "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
-    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
-    "help", "hidden", "hide", "higher", "highlight", "highlighttext",
-    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
-    "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
-    "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
-    "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
-    "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
-    "katakana", "katakana-iroha", "keep-all", "khmer",
-    "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
-    "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
-    "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
-    "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
-    "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
-    "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
-    "media-controls-background", "media-current-time-display",
-    "media-fullscreen-button", "media-mute-button", "media-play-button",
-    "media-return-to-realtime-button", "media-rewind-button",
-    "media-seek-back-button", "media-seek-forward-button", "media-slider",
-    "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
-    "media-volume-slider-container", "media-volume-sliderthumb", "medium",
-    "menu", "menulist", "menulist-button", "menulist-text",
-    "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
-    "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
-    "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
-    "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
-    "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
-    "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
-    "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
-    "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
-    "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
-    "progress", "push-button", "radial-gradient", "radio", "read-only",
-    "read-write", "read-write-plaintext-only", "rectangle", "region",
-    "relative", "repeat", "repeating-linear-gradient",
-    "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
-    "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
-    "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
-    "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
-    "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
-    "searchfield-cancel-button", "searchfield-decoration",
-    "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
-    "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
-    "simp-chinese-formal", "simp-chinese-informal", "single",
-    "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
-    "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
-    "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
-    "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
-    "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
-    "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
-    "table-caption", "table-cell", "table-column", "table-column-group",
-    "table-footer-group", "table-header-group", "table-row", "table-row-group",
-    "tamil",
-    "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
-    "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
-    "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
-    "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
-    "trad-chinese-formal", "trad-chinese-informal", "transform",
-    "translate", "translate3d", "translateX", "translateY", "translateZ",
-    "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
-    "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
-    "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
-    "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
-    "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
-    "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
-    "xx-large", "xx-small"
-  ], valueKeywords = keySet(valueKeywords_);
-
-  var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
-    .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
-    .concat(valueKeywords_);
-  CodeMirror.registerHelper("hintWords", "css", allWords);
-
-  function tokenCComment(stream, state) {
-    var maybeEnd = false, ch;
-    while ((ch = stream.next()) != null) {
-      if (maybeEnd && ch == "/") {
-        state.tokenize = null;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return ["comment", "comment"];
-  }
-
-  CodeMirror.defineMIME("text/css", {
-    documentTypes: documentTypes,
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    mediaValueKeywords: mediaValueKeywords,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    fontProperties: fontProperties,
-    counterDescriptors: counterDescriptors,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (!stream.eat("*")) return false;
-        state.tokenize = tokenCComment;
-        return tokenCComment(stream, state);
-      }
-    },
-    name: "css"
-  });
-
-  CodeMirror.defineMIME("text/x-scss", {
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    mediaValueKeywords: mediaValueKeywords,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    fontProperties: fontProperties,
-    allowNested: true,
-    lineComment: "//",
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (stream.eat("/")) {
-          stream.skipToEnd();
-          return ["comment", "comment"];
-        } else if (stream.eat("*")) {
-          state.tokenize = tokenCComment;
-          return tokenCComment(stream, state);
-        } else {
-          return ["operator", "operator"];
-        }
-      },
-      ":": function(stream) {
-        if (stream.match(/\s*\{/, false))
-          return [null, null]
-        return false;
-      },
-      "$": function(stream) {
-        stream.match(/^[\w-]+/);
-        if (stream.match(/^\s*:/, false))
-          return ["variable-2", "variable-definition"];
-        return ["variable-2", "variable"];
-      },
-      "#": function(stream) {
-        if (!stream.eat("{")) return false;
-        return [null, "interpolation"];
-      }
-    },
-    name: "css",
-    helperType: "scss"
-  });
-
-  CodeMirror.defineMIME("text/x-less", {
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    mediaValueKeywords: mediaValueKeywords,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    fontProperties: fontProperties,
-    allowNested: true,
-    lineComment: "//",
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (stream.eat("/")) {
-          stream.skipToEnd();
-          return ["comment", "comment"];
-        } else if (stream.eat("*")) {
-          state.tokenize = tokenCComment;
-          return tokenCComment(stream, state);
-        } else {
-          return ["operator", "operator"];
-        }
-      },
-      "@": function(stream) {
-        if (stream.eat("{")) return [null, "interpolation"];
-        if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
-        stream.eatWhile(/[\w\\\-]/);
-        if (stream.match(/^\s*:/, false))
-          return ["variable-2", "variable-definition"];
-        return ["variable-2", "variable"];
-      },
-      "&": function() {
-        return ["atom", "atom"];
-      }
-    },
-    name: "css",
-    helperType: "less"
-  });
-
-  CodeMirror.defineMIME("text/x-gss", {
-    documentTypes: documentTypes,
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    fontProperties: fontProperties,
-    counterDescriptors: counterDescriptors,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    supportsAtComponent: true,
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (!stream.eat("*")) return false;
-        state.tokenize = tokenCComment;
-        return tokenCComment(stream, state);
-      }
-    },
-    name: "css",
-    helperType: "gss"
-  });
-
-});
diff --git a/front_end/cm_web_modes/htmlembedded.js b/front_end/cm_web_modes/htmlembedded.js
deleted file mode 100644
index 464dc57..0000000
--- a/front_end/cm_web_modes/htmlembedded.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
-        require("../../addon/mode/multiplex"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
-            "../../addon/mode/multiplex"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
-    return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
-      open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
-      close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
-      mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
-    });
-  }, "htmlmixed");
-
-  CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"});
-  CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
-  CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"});
-  CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"});
-});
diff --git a/front_end/cm_web_modes/htmlmixed.js b/front_end/cm_web_modes/htmlmixed.js
deleted file mode 100644
index 33398ec..0000000
--- a/front_end/cm_web_modes/htmlmixed.js
+++ /dev/null
@@ -1,152 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  var defaultTags = {
-    script: [
-      ["lang", /(javascript|babel)/i, "javascript"],
-      ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
-      ["type", /./, "text/plain"],
-      [null, null, "javascript"]
-    ],
-    style:  [
-      ["lang", /^css$/i, "css"],
-      ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
-      ["type", /./, "text/plain"],
-      [null, null, "css"]
-    ]
-  };
-
-  function maybeBackup(stream, pat, style) {
-    var cur = stream.current(), close = cur.search(pat);
-    if (close > -1) {
-      stream.backUp(cur.length - close);
-    } else if (cur.match(/<\/?$/)) {
-      stream.backUp(cur.length);
-      if (!stream.match(pat, false)) stream.match(cur);
-    }
-    return style;
-  }
-
-  var attrRegexpCache = {};
-  function getAttrRegexp(attr) {
-    var regexp = attrRegexpCache[attr];
-    if (regexp) return regexp;
-    return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
-  }
-
-  function getAttrValue(text, attr) {
-    var match = text.match(getAttrRegexp(attr))
-    return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
-  }
-
-  function getTagRegexp(tagName, anchored) {
-    return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
-  }
-
-  function addTags(from, to) {
-    for (var tag in from) {
-      var dest = to[tag] || (to[tag] = []);
-      var source = from[tag];
-      for (var i = source.length - 1; i >= 0; i--)
-        dest.unshift(source[i])
-    }
-  }
-
-  function findMatchingMode(tagInfo, tagText) {
-    for (var i = 0; i < tagInfo.length; i++) {
-      var spec = tagInfo[i];
-      if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
-    }
-  }
-
-  CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
-    var htmlMode = CodeMirror.getMode(config, {
-      name: "xml",
-      htmlMode: true,
-      multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
-      multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
-    });
-
-    var tags = {};
-    var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
-    addTags(defaultTags, tags);
-    if (configTags) addTags(configTags, tags);
-    if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
-      tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
-
-    function html(stream, state) {
-      var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
-      if (tag && !/[<>\s\/]/.test(stream.current()) &&
-          (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
-          tags.hasOwnProperty(tagName)) {
-        state.inTag = tagName + " "
-      } else if (state.inTag && tag && />$/.test(stream.current())) {
-        var inTag = /^([\S]+) (.*)/.exec(state.inTag)
-        state.inTag = null
-        var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
-        var mode = CodeMirror.getMode(config, modeSpec)
-        var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
-        state.token = function (stream, state) {
-          if (stream.match(endTagA, false)) {
-            state.token = html;
-            state.localState = state.localMode = null;
-            return null;
-          }
-          return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
-        };
-        state.localMode = mode;
-        state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
-      } else if (state.inTag) {
-        state.inTag += stream.current()
-        if (stream.eol()) state.inTag += " "
-      }
-      return style;
-    };
-
-    return {
-      startState: function () {
-        var state = CodeMirror.startState(htmlMode);
-        return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
-      },
-
-      copyState: function (state) {
-        var local;
-        if (state.localState) {
-          local = CodeMirror.copyState(state.localMode, state.localState);
-        }
-        return {token: state.token, inTag: state.inTag,
-                localMode: state.localMode, localState: local,
-                htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
-      },
-
-      token: function (stream, state) {
-        return state.token(stream, state);
-      },
-
-      indent: function (state, textAfter, line) {
-        if (!state.localMode || /^\s*<\//.test(textAfter))
-          return htmlMode.indent(state.htmlState, textAfter);
-        else if (state.localMode.indent)
-          return state.localMode.indent(state.localState, textAfter, line);
-        else
-          return CodeMirror.Pass;
-      },
-
-      innerMode: function (state) {
-        return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
-      }
-    };
-  }, "xml", "javascript", "css");
-
-  CodeMirror.defineMIME("text/html", "htmlmixed");
-});
diff --git a/front_end/cm_web_modes/javascript.js b/front_end/cm_web_modes/javascript.js
deleted file mode 100644
index 139e53d..0000000
--- a/front_end/cm_web_modes/javascript.js
+++ /dev/null
@@ -1,861 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("javascript", function(config, parserConfig) {
-  var indentUnit = config.indentUnit;
-  var statementIndent = parserConfig.statementIndent;
-  var jsonldMode = parserConfig.jsonld;
-  var jsonMode = parserConfig.json || jsonldMode;
-  var isTS = parserConfig.typescript;
-  var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
-
-  // Tokenizer
-
-  var keywords = function(){
-    function kw(type) {return {type: type, style: "keyword"};}
-    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
-    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
-
-    var jsKeywords = {
-      "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
-      "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
-      "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
-      "function": kw("function"), "catch": kw("catch"),
-      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
-      "in": operator, "typeof": operator, "instanceof": operator,
-      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
-      "this": kw("this"), "class": kw("class"), "super": kw("atom"),
-      "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
-      "await": C
-    };
-
-    // Extend the 'normal' keywords with the TypeScript language extensions
-    if (isTS) {
-      var type = {type: "variable", style: "type"};
-      var tsKeywords = {
-        // object-like things
-        "interface": kw("class"),
-        "implements": C,
-        "namespace": C,
-
-        // scope modifiers
-        "public": kw("modifier"),
-        "private": kw("modifier"),
-        "protected": kw("modifier"),
-        "abstract": kw("modifier"),
-        "readonly": kw("modifier"),
-
-        // types
-        "string": type, "number": type, "boolean": type, "any": type
-      };
-
-      for (var attr in tsKeywords) {
-        jsKeywords[attr] = tsKeywords[attr];
-      }
-    }
-
-    return jsKeywords;
-  }();
-
-  var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
-  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
-
-  function readRegexp(stream) {
-    var escaped = false, next, inSet = false;
-    while ((next = stream.next()) != null) {
-      if (!escaped) {
-        if (next == "/" && !inSet) return;
-        if (next == "[") inSet = true;
-        else if (inSet && next == "]") inSet = false;
-      }
-      escaped = !escaped && next == "\\";
-    }
-  }
-
-  // Used as scratch variables to communicate multiple values without
-  // consing up tons of objects.
-  var type, content;
-  function ret(tp, style, cont) {
-    type = tp; content = cont;
-    return style;
-  }
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (ch == '"' || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
-      return ret("number", "number");
-    } else if (ch == "." && stream.match("..")) {
-      return ret("spread", "meta");
-    } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
-      return ret(ch);
-    } else if (ch == "=" && stream.eat(">")) {
-      return ret("=>", "operator");
-    } else if (ch == "0" && stream.eat(/x/i)) {
-      stream.eatWhile(/[\da-f]/i);
-      return ret("number", "number");
-    } else if (ch == "0" && stream.eat(/o/i)) {
-      stream.eatWhile(/[0-7]/i);
-      return ret("number", "number");
-    } else if (ch == "0" && stream.eat(/b/i)) {
-      stream.eatWhile(/[01]/i);
-      return ret("number", "number");
-    } else if (/\d/.test(ch)) {
-      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
-      return ret("number", "number");
-    } else if (ch == "/") {
-      if (stream.eat("*")) {
-        state.tokenize = tokenComment;
-        return tokenComment(stream, state);
-      } else if (stream.eat("/")) {
-        stream.skipToEnd();
-        return ret("comment", "comment");
-      } else if (expressionAllowed(stream, state, 1)) {
-        readRegexp(stream);
-        stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
-        return ret("regexp", "string-2");
-      } else {
-        stream.eat("=");
-        return ret("operator", "operator", stream.current());
-      }
-    } else if (ch == "`") {
-      state.tokenize = tokenQuasi;
-      return tokenQuasi(stream, state);
-    } else if (ch == "#") {
-      stream.skipToEnd();
-      return ret("error", "error");
-    } else if (isOperatorChar.test(ch)) {
-      if (ch != ">" || !state.lexical || state.lexical.type != ">") {
-        if (stream.eat("=")) {
-          if (ch == "!" || ch == "=") stream.eat("=")
-        } else if (/[<>*+\-]/.test(ch)) {
-          stream.eat(ch)
-          if (ch == ">") stream.eat(ch)
-        }
-      }
-      return ret("operator", "operator", stream.current());
-    } else if (wordRE.test(ch)) {
-      stream.eatWhile(wordRE);
-      var word = stream.current()
-      if (state.lastType != ".") {
-        if (keywords.propertyIsEnumerable(word)) {
-          var kw = keywords[word]
-          return ret(kw.type, kw.style, word)
-        }
-        if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\(\w]/, false))
-          return ret("async", "keyword", word)
-      }
-      return ret("variable", "variable", word)
-    }
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, next;
-      if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
-        state.tokenize = tokenBase;
-        return ret("jsonld-keyword", "meta");
-      }
-      while ((next = stream.next()) != null) {
-        if (next == quote && !escaped) break;
-        escaped = !escaped && next == "\\";
-      }
-      if (!escaped) state.tokenize = tokenBase;
-      return ret("string", "string");
-    };
-  }
-
-  function tokenComment(stream, state) {
-    var maybeEnd = false, ch;
-    while (ch = stream.next()) {
-      if (ch == "/" && maybeEnd) {
-        state.tokenize = tokenBase;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return ret("comment", "comment");
-  }
-
-  function tokenQuasi(stream, state) {
-    var escaped = false, next;
-    while ((next = stream.next()) != null) {
-      if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
-        state.tokenize = tokenBase;
-        break;
-      }
-      escaped = !escaped && next == "\\";
-    }
-    return ret("quasi", "string-2", stream.current());
-  }
-
-  var brackets = "([{}])";
-  // This is a crude lookahead trick to try and notice that we're
-  // parsing the argument patterns for a fat-arrow function before we
-  // actually hit the arrow token. It only works if the arrow is on
-  // the same line as the arguments and there's no strange noise
-  // (comments) in between. Fallback is to only notice when we hit the
-  // arrow, and not declare the arguments as locals for the arrow
-  // body.
-  function findFatArrow(stream, state) {
-    if (state.fatArrowAt) state.fatArrowAt = null;
-    var arrow = stream.string.indexOf("=>", stream.start);
-    if (arrow < 0) return;
-
-    if (isTS) { // Try to skip TypeScript return type declarations after the arguments
-      var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
-      if (m) arrow = m.index
-    }
-
-    var depth = 0, sawSomething = false;
-    for (var pos = arrow - 1; pos >= 0; --pos) {
-      var ch = stream.string.charAt(pos);
-      var bracket = brackets.indexOf(ch);
-      if (bracket >= 0 && bracket < 3) {
-        if (!depth) { ++pos; break; }
-        if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
-      } else if (bracket >= 3 && bracket < 6) {
-        ++depth;
-      } else if (wordRE.test(ch)) {
-        sawSomething = true;
-      } else if (/["'\/]/.test(ch)) {
-        return;
-      } else if (sawSomething && !depth) {
-        ++pos;
-        break;
-      }
-    }
-    if (sawSomething && !depth) state.fatArrowAt = pos;
-  }
-
-  // Parser
-
-  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
-
-  function JSLexical(indented, column, type, align, prev, info) {
-    this.indented = indented;
-    this.column = column;
-    this.type = type;
-    this.prev = prev;
-    this.info = info;
-    if (align != null) this.align = align;
-  }
-
-  function inScope(state, varname) {
-    for (var v = state.localVars; v; v = v.next)
-      if (v.name == varname) return true;
-    for (var cx = state.context; cx; cx = cx.prev) {
-      for (var v = cx.vars; v; v = v.next)
-        if (v.name == varname) return true;
-    }
-  }
-
-  function parseJS(state, style, type, content, stream) {
-    var cc = state.cc;
-    // Communicate our context to the combinators.
-    // (Less wasteful than consing up a hundred closures on every call.)
-    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
-
-    if (!state.lexical.hasOwnProperty("align"))
-      state.lexical.align = true;
-
-    while(true) {
-      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
-      if (combinator(type, content)) {
-        while(cc.length && cc[cc.length - 1].lex)
-          cc.pop()();
-        if (cx.marked) return cx.marked;
-        if (type == "variable" && inScope(state, content)) return "variable-2";
-        return style;
-      }
-    }
-  }
-
-  // Combinator utils
-
-  var cx = {state: null, column: null, marked: null, cc: null};
-  function pass() {
-    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
-  }
-  function cont() {
-    pass.apply(null, arguments);
-    return true;
-  }
-  function register(varname) {
-    function inList(list) {
-      for (var v = list; v; v = v.next)
-        if (v.name == varname) return true;
-      return false;
-    }
-    var state = cx.state;
-    cx.marked = "def";
-    if (state.context) {
-      if (inList(state.localVars)) return;
-      state.localVars = {name: varname, next: state.localVars};
-    } else {
-      if (inList(state.globalVars)) return;
-      if (parserConfig.globalVars)
-        state.globalVars = {name: varname, next: state.globalVars};
-    }
-  }
-
-  // Combinators
-
-  var defaultVars = {name: "this", next: {name: "arguments"}};
-  function pushcontext() {
-    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
-    cx.state.localVars = defaultVars;
-  }
-  function popcontext() {
-    cx.state.localVars = cx.state.context.vars;
-    cx.state.context = cx.state.context.prev;
-  }
-  function pushlex(type, info) {
-    var result = function() {
-      var state = cx.state, indent = state.indented;
-      if (state.lexical.type == "stat") indent = state.lexical.indented;
-      else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
-        indent = outer.indented;
-      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
-    };
-    result.lex = true;
-    return result;
-  }
-  function poplex() {
-    var state = cx.state;
-    if (state.lexical.prev) {
-      if (state.lexical.type == ")")
-        state.indented = state.lexical.indented;
-      state.lexical = state.lexical.prev;
-    }
-  }
-  poplex.lex = true;
-
-  function expect(wanted) {
-    function exp(type) {
-      if (type == wanted) return cont();
-      else if (wanted == ";") return pass();
-      else return cont(exp);
-    };
-    return exp;
-  }
-
-  function statement(type, value) {
-    if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
-    if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
-    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
-    if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
-    if (type == "debugger") return cont(expect(";"));
-    if (type == "{") return cont(pushlex("}"), block, poplex);
-    if (type == ";") return cont();
-    if (type == "if") {
-      if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
-        cx.state.cc.pop()();
-      return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
-    }
-    if (type == "function") return cont(functiondef);
-    if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
-    if (type == "variable") {
-      if (isTS && value == "type") {
-        cx.marked = "keyword"
-        return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
-      } else if (isTS && value == "declare") {
-        cx.marked = "keyword"
-        return cont(statement)
-      } else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) {
-        cx.marked = "keyword"
-        return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
-      } else {
-        return cont(pushlex("stat"), maybelabel);
-      }
-    }
-    if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
-                                      block, poplex, poplex);
-    if (type == "case") return cont(expression, expect(":"));
-    if (type == "default") return cont(expect(":"));
-    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
-                                     statement, poplex, popcontext);
-    if (type == "class") return cont(pushlex("form"), className, poplex);
-    if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
-    if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
-    if (type == "async") return cont(statement)
-    if (value == "@") return cont(expression, statement)
-    return pass(pushlex("stat"), expression, expect(";"), poplex);
-  }
-  function expression(type) {
-    return expressionInner(type, false);
-  }
-  function expressionNoComma(type) {
-    return expressionInner(type, true);
-  }
-  function parenExpr(type) {
-    if (type != "(") return pass()
-    return cont(pushlex(")"), expression, expect(")"), poplex)
-  }
-  function expressionInner(type, noComma) {
-    if (cx.state.fatArrowAt == cx.stream.start) {
-      var body = noComma ? arrowBodyNoComma : arrowBody;
-      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
-      else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
-    }
-
-    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
-    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
-    if (type == "function") return cont(functiondef, maybeop);
-    if (type == "class") return cont(pushlex("form"), classExpression, poplex);
-    if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
-    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
-    if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
-    if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
-    if (type == "{") return contCommasep(objprop, "}", null, maybeop);
-    if (type == "quasi") return pass(quasi, maybeop);
-    if (type == "new") return cont(maybeTarget(noComma));
-    return cont();
-  }
-  function maybeexpression(type) {
-    if (type.match(/[;\}\)\],]/)) return pass();
-    return pass(expression);
-  }
-
-  function maybeoperatorComma(type, value) {
-    if (type == ",") return cont(expression);
-    return maybeoperatorNoComma(type, value, false);
-  }
-  function maybeoperatorNoComma(type, value, noComma) {
-    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
-    var expr = noComma == false ? expression : expressionNoComma;
-    if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
-    if (type == "operator") {
-      if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
-      if (value == "?") return cont(expression, expect(":"), expr);
-      return cont(expr);
-    }
-    if (type == "quasi") { return pass(quasi, me); }
-    if (type == ";") return;
-    if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
-    if (type == ".") return cont(property, me);
-    if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
-    if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
-    if (type == "regexp") {
-      cx.state.lastType = cx.marked = "operator"
-      cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
-      return cont(expr)
-    }
-  }
-  function quasi(type, value) {
-    if (type != "quasi") return pass();
-    if (value.slice(value.length - 2) != "${") return cont(quasi);
-    return cont(expression, continueQuasi);
-  }
-  function continueQuasi(type) {
-    if (type == "}") {
-      cx.marked = "string-2";
-      cx.state.tokenize = tokenQuasi;
-      return cont(quasi);
-    }
-  }
-  function arrowBody(type) {
-    findFatArrow(cx.stream, cx.state);
-    return pass(type == "{" ? statement : expression);
-  }
-  function arrowBodyNoComma(type) {
-    findFatArrow(cx.stream, cx.state);
-    return pass(type == "{" ? statement : expressionNoComma);
-  }
-  function maybeTarget(noComma) {
-    return function(type) {
-      if (type == ".") return cont(noComma ? targetNoComma : target);
-      else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
-      else return pass(noComma ? expressionNoComma : expression);
-    };
-  }
-  function target(_, value) {
-    if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
-  }
-  function targetNoComma(_, value) {
-    if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
-  }
-  function maybelabel(type) {
-    if (type == ":") return cont(poplex, statement);
-    return pass(maybeoperatorComma, expect(";"), poplex);
-  }
-  function property(type) {
-    if (type == "variable") {cx.marked = "property"; return cont();}
-  }
-  function objprop(type, value) {
-    if (type == "async") {
-      cx.marked = "property";
-      return cont(objprop);
-    } else if (type == "variable" || cx.style == "keyword") {
-      cx.marked = "property";
-      if (value == "get" || value == "set") return cont(getterSetter);
-      var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
-      if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
-        cx.state.fatArrowAt = cx.stream.pos + m[0].length
-      return cont(afterprop);
-    } else if (type == "number" || type == "string") {
-      cx.marked = jsonldMode ? "property" : (cx.style + " property");
-      return cont(afterprop);
-    } else if (type == "jsonld-keyword") {
-      return cont(afterprop);
-    } else if (type == "modifier") {
-      return cont(objprop)
-    } else if (type == "[") {
-      return cont(expression, expect("]"), afterprop);
-    } else if (type == "spread") {
-      return cont(expressionNoComma, afterprop);
-    } else if (value == "*") {
-      cx.marked = "keyword";
-      return cont(objprop);
-    } else if (type == ":") {
-      return pass(afterprop)
-    }
-  }
-  function getterSetter(type) {
-    if (type != "variable") return pass(afterprop);
-    cx.marked = "property";
-    return cont(functiondef);
-  }
-  function afterprop(type) {
-    if (type == ":") return cont(expressionNoComma);
-    if (type == "(") return pass(functiondef);
-  }
-  function commasep(what, end, sep) {
-    function proceed(type, value) {
-      if (sep ? sep.indexOf(type) > -1 : type == ",") {
-        var lex = cx.state.lexical;
-        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
-        return cont(function(type, value) {
-          if (type == end || value == end) return pass()
-          return pass(what)
-        }, proceed);
-      }
-      if (type == end || value == end) return cont();
-      return cont(expect(end));
-    }
-    return function(type, value) {
-      if (type == end || value == end) return cont();
-      return pass(what, proceed);
-    };
-  }
-  function contCommasep(what, end, info) {
-    for (var i = 3; i < arguments.length; i++)
-      cx.cc.push(arguments[i]);
-    return cont(pushlex(end, info), commasep(what, end), poplex);
-  }
-  function block(type) {
-    if (type == "}") return cont();
-    return pass(statement, block);
-  }
-  function maybetype(type, value) {
-    if (isTS) {
-      if (type == ":") return cont(typeexpr);
-      if (value == "?") return cont(maybetype);
-    }
-  }
-  function typeexpr(type, value) {
-    if (type == "variable" || value == "void") {
-      if (value == "keyof") {
-        cx.marked = "keyword"
-        return cont(typeexpr)
-      } else {
-        cx.marked = "type"
-        return cont(afterType)
-      }
-    }
-    if (type == "string" || type == "number" || type == "atom") return cont(afterType);
-    if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
-    if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
-    if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
-  }
-  function maybeReturnType(type) {
-    if (type == "=>") return cont(typeexpr)
-  }
-  function typeprop(type, value) {
-    if (type == "variable" || cx.style == "keyword") {
-      cx.marked = "property"
-      return cont(typeprop)
-    } else if (value == "?") {
-      return cont(typeprop)
-    } else if (type == ":") {
-      return cont(typeexpr)
-    } else if (type == "[") {
-      return cont(expression, maybetype, expect("]"), typeprop)
-    }
-  }
-  function typearg(type) {
-    if (type == "variable") return cont(typearg)
-    else if (type == ":") return cont(typeexpr)
-  }
-  function afterType(type, value) {
-    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
-    if (value == "|" || type == ".") return cont(typeexpr)
-    if (type == "[") return cont(expect("]"), afterType)
-    if (value == "extends") return cont(typeexpr)
-  }
-  function maybeTypeArgs(_, value) {
-    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
-  }
-  function typeparam() {
-    return pass(typeexpr, maybeTypeDefault)
-  }
-  function maybeTypeDefault(_, value) {
-    if (value == "=") return cont(typeexpr)
-  }
-  function vardef() {
-    return pass(pattern, maybetype, maybeAssign, vardefCont);
-  }
-  function pattern(type, value) {
-    if (type == "modifier") return cont(pattern)
-    if (type == "variable") { register(value); return cont(); }
-    if (type == "spread") return cont(pattern);
-    if (type == "[") return contCommasep(pattern, "]");
-    if (type == "{") return contCommasep(proppattern, "}");
-  }
-  function proppattern(type, value) {
-    if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
-      register(value);
-      return cont(maybeAssign);
-    }
-    if (type == "variable") cx.marked = "property";
-    if (type == "spread") return cont(pattern);
-    if (type == "}") return pass();
-    return cont(expect(":"), pattern, maybeAssign);
-  }
-  function maybeAssign(_type, value) {
-    if (value == "=") return cont(expressionNoComma);
-  }
-  function vardefCont(type) {
-    if (type == ",") return cont(vardef);
-  }
-  function maybeelse(type, value) {
-    if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
-  }
-  function forspec(type) {
-    if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
-  }
-  function forspec1(type) {
-    if (type == "var") return cont(vardef, expect(";"), forspec2);
-    if (type == ";") return cont(forspec2);
-    if (type == "variable") return cont(formaybeinof);
-    return pass(expression, expect(";"), forspec2);
-  }
-  function formaybeinof(_type, value) {
-    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
-    return cont(maybeoperatorComma, forspec2);
-  }
-  function forspec2(type, value) {
-    if (type == ";") return cont(forspec3);
-    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
-    return pass(expression, expect(";"), forspec3);
-  }
-  function forspec3(type) {
-    if (type != ")") cont(expression);
-  }
-  function functiondef(type, value) {
-    if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
-    if (type == "variable") {register(value); return cont(functiondef);}
-    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
-    if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
-  }
-  function funarg(type, value) {
-    if (value == "@") cont(expression, funarg)
-    if (type == "spread" || type == "modifier") return cont(funarg);
-    return pass(pattern, maybetype, maybeAssign);
-  }
-  function classExpression(type, value) {
-    // Class expressions may have an optional name.
-    if (type == "variable") return className(type, value);
-    return classNameAfter(type, value);
-  }
-  function className(type, value) {
-    if (type == "variable") {register(value); return cont(classNameAfter);}
-  }
-  function classNameAfter(type, value) {
-    if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
-    if (value == "extends" || value == "implements" || (isTS && type == ","))
-      return cont(isTS ? typeexpr : expression, classNameAfter);
-    if (type == "{") return cont(pushlex("}"), classBody, poplex);
-  }
-  function classBody(type, value) {
-    if (type == "modifier" || type == "async" ||
-        (type == "variable" &&
-         (value == "static" || value == "get" || value == "set") &&
-         cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
-      cx.marked = "keyword";
-      return cont(classBody);
-    }
-    if (type == "variable" || cx.style == "keyword") {
-      cx.marked = "property";
-      return cont(isTS ? classfield : functiondef, classBody);
-    }
-    if (type == "[")
-      return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
-    if (value == "*") {
-      cx.marked = "keyword";
-      return cont(classBody);
-    }
-    if (type == ";") return cont(classBody);
-    if (type == "}") return cont();
-    if (value == "@") return cont(expression, classBody)
-  }
-  function classfield(type, value) {
-    if (value == "?") return cont(classfield)
-    if (type == ":") return cont(typeexpr, maybeAssign)
-    if (value == "=") return cont(expressionNoComma)
-    return pass(functiondef)
-  }
-  function afterExport(type, value) {
-    if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
-    if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
-    if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
-    return pass(statement);
-  }
-  function exportField(type, value) {
-    if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
-    if (type == "variable") return pass(expressionNoComma, exportField);
-  }
-  function afterImport(type) {
-    if (type == "string") return cont();
-    return pass(importSpec, maybeMoreImports, maybeFrom);
-  }
-  function importSpec(type, value) {
-    if (type == "{") return contCommasep(importSpec, "}");
-    if (type == "variable") register(value);
-    if (value == "*") cx.marked = "keyword";
-    return cont(maybeAs);
-  }
-  function maybeMoreImports(type) {
-    if (type == ",") return cont(importSpec, maybeMoreImports)
-  }
-  function maybeAs(_type, value) {
-    if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
-  }
-  function maybeFrom(_type, value) {
-    if (value == "from") { cx.marked = "keyword"; return cont(expression); }
-  }
-  function arrayLiteral(type) {
-    if (type == "]") return cont();
-    return pass(commasep(expressionNoComma, "]"));
-  }
-
-  function isContinuedStatement(state, textAfter) {
-    return state.lastType == "operator" || state.lastType == "," ||
-      isOperatorChar.test(textAfter.charAt(0)) ||
-      /[,.]/.test(textAfter.charAt(0));
-  }
-
-  function expressionAllowed(stream, state, backUp) {
-    return state.tokenize == tokenBase &&
-      /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
-      (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
-  }
-
-  // Interface
-
-  return {
-    startState: function(basecolumn) {
-      var state = {
-        tokenize: tokenBase,
-        lastType: "sof",
-        cc: [],
-        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
-        localVars: parserConfig.localVars,
-        context: parserConfig.localVars && {vars: parserConfig.localVars},
-        indented: basecolumn || 0
-      };
-      if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
-        state.globalVars = parserConfig.globalVars;
-      return state;
-    },
-
-    token: function(stream, state) {
-      if (stream.sol()) {
-        if (!state.lexical.hasOwnProperty("align"))
-          state.lexical.align = false;
-        state.indented = stream.indentation();
-        findFatArrow(stream, state);
-      }
-      if (state.tokenize != tokenComment && stream.eatSpace()) return null;
-      var style = state.tokenize(stream, state);
-      if (type == "comment") return style;
-      state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
-      return parseJS(state, style, type, content, stream);
-    },
-
-    indent: function(state, textAfter) {
-      if (state.tokenize == tokenComment) return CodeMirror.Pass;
-      if (state.tokenize != tokenBase) return 0;
-      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
-      // Kludge to prevent 'maybelse' from blocking lexical scope pops
-      if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
-        var c = state.cc[i];
-        if (c == poplex) lexical = lexical.prev;
-        else if (c != maybeelse) break;
-      }
-      while ((lexical.type == "stat" || lexical.type == "form") &&
-             (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
-                                   (top == maybeoperatorComma || top == maybeoperatorNoComma) &&
-                                   !/^[,\.=+\-*:?[\(]/.test(textAfter))))
-        lexical = lexical.prev;
-      if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
-        lexical = lexical.prev;
-      var type = lexical.type, closing = firstChar == type;
-
-      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
-      else if (type == "form" && firstChar == "{") return lexical.indented;
-      else if (type == "form") return lexical.indented + indentUnit;
-      else if (type == "stat")
-        return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
-      else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
-        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
-      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
-      else return lexical.indented + (closing ? 0 : indentUnit);
-    },
-
-    electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
-    blockCommentStart: jsonMode ? null : "/*",
-    blockCommentEnd: jsonMode ? null : "*/",
-    blockCommentContinue: jsonMode ? null : " * ",
-    lineComment: jsonMode ? null : "//",
-    fold: "brace",
-    closeBrackets: "()[]{}''\"\"``",
-
-    helperType: jsonMode ? "json" : "javascript",
-    jsonldMode: jsonldMode,
-    jsonMode: jsonMode,
-
-    expressionAllowed: expressionAllowed,
-
-    skipExpression: function(state) {
-      var top = state.cc[state.cc.length - 1]
-      if (top == expression || top == expressionNoComma) state.cc.pop()
-    }
-  };
-});
-
-CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
-
-CodeMirror.defineMIME("text/javascript", "javascript");
-CodeMirror.defineMIME("text/ecmascript", "javascript");
-CodeMirror.defineMIME("application/javascript", "javascript");
-CodeMirror.defineMIME("application/x-javascript", "javascript");
-CodeMirror.defineMIME("application/ecmascript", "javascript");
-CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
-CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
-CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
-
-});
diff --git a/front_end/cm_web_modes/xml.js b/front_end/cm_web_modes/xml.js
deleted file mode 100644
index a365739..0000000
--- a/front_end/cm_web_modes/xml.js
+++ /dev/null
@@ -1,394 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-var htmlConfig = {
-  autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
-                    'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
-                    'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
-                    'track': true, 'wbr': true, 'menuitem': true},
-  implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
-                     'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
-                     'th': true, 'tr': true},
-  contextGrabbers: {
-    'dd': {'dd': true, 'dt': true},
-    'dt': {'dd': true, 'dt': true},
-    'li': {'li': true},
-    'option': {'option': true, 'optgroup': true},
-    'optgroup': {'optgroup': true},
-    'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
-          'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
-          'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
-          'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
-          'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
-    'rp': {'rp': true, 'rt': true},
-    'rt': {'rp': true, 'rt': true},
-    'tbody': {'tbody': true, 'tfoot': true},
-    'td': {'td': true, 'th': true},
-    'tfoot': {'tbody': true},
-    'th': {'td': true, 'th': true},
-    'thead': {'tbody': true, 'tfoot': true},
-    'tr': {'tr': true}
-  },
-  doNotIndent: {"pre": true},
-  allowUnquoted: true,
-  allowMissing: true,
-  caseFold: true
-}
-
-var xmlConfig = {
-  autoSelfClosers: {},
-  implicitlyClosed: {},
-  contextGrabbers: {},
-  doNotIndent: {},
-  allowUnquoted: false,
-  allowMissing: false,
-  caseFold: false
-}
-
-CodeMirror.defineMode("xml", function(editorConf, config_) {
-  var indentUnit = editorConf.indentUnit
-  var config = {}
-  var defaults = config_.htmlMode ? htmlConfig : xmlConfig
-  for (var prop in defaults) config[prop] = defaults[prop]
-  for (var prop in config_) config[prop] = config_[prop]
-
-  // Return variables for tokenizers
-  var type, setStyle;
-
-  function inText(stream, state) {
-    function chain(parser) {
-      state.tokenize = parser;
-      return parser(stream, state);
-    }
-
-    var ch = stream.next();
-    if (ch == "<") {
-      if (stream.eat("!")) {
-        if (stream.eat("[")) {
-          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
-          else return null;
-        } else if (stream.match("--")) {
-          return chain(inBlock("comment", "-->"));
-        } else if (stream.match("DOCTYPE", true, true)) {
-          stream.eatWhile(/[\w\._\-]/);
-          return chain(doctype(1));
-        } else {
-          return null;
-        }
-      } else if (stream.eat("?")) {
-        stream.eatWhile(/[\w\._\-]/);
-        state.tokenize = inBlock("meta", "?>");
-        return "meta";
-      } else {
-        type = stream.eat("/") ? "closeTag" : "openTag";
-        state.tokenize = inTag;
-        return "tag bracket";
-      }
-    } else if (ch == "&") {
-      var ok;
-      if (stream.eat("#")) {
-        if (stream.eat("x")) {
-          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
-        } else {
-          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
-        }
-      } else {
-        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
-      }
-      return ok ? "atom" : "error";
-    } else {
-      stream.eatWhile(/[^&<]/);
-      return null;
-    }
-  }
-  inText.isInText = true;
-
-  function inTag(stream, state) {
-    var ch = stream.next();
-    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
-      state.tokenize = inText;
-      type = ch == ">" ? "endTag" : "selfcloseTag";
-      return "tag bracket";
-    } else if (ch == "=") {
-      type = "equals";
-      return null;
-    } else if (ch == "<") {
-      state.tokenize = inText;
-      state.state = baseState;
-      state.tagName = state.tagStart = null;
-      var next = state.tokenize(stream, state);
-      return next ? next + " tag error" : "tag error";
-    } else if (/[\'\"]/.test(ch)) {
-      state.tokenize = inAttribute(ch);
-      state.stringStartCol = stream.column();
-      return state.tokenize(stream, state);
-    } else {
-      stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
-      return "word";
-    }
-  }
-
-  function inAttribute(quote) {
-    var closure = function(stream, state) {
-      while (!stream.eol()) {
-        if (stream.next() == quote) {
-          state.tokenize = inTag;
-          break;
-        }
-      }
-      return "string";
-    };
-    closure.isInAttribute = true;
-    return closure;
-  }
-
-  function inBlock(style, terminator) {
-    return function(stream, state) {
-      while (!stream.eol()) {
-        if (stream.match(terminator)) {
-          state.tokenize = inText;
-          break;
-        }
-        stream.next();
-      }
-      return style;
-    };
-  }
-  function doctype(depth) {
-    return function(stream, state) {
-      var ch;
-      while ((ch = stream.next()) != null) {
-        if (ch == "<") {
-          state.tokenize = doctype(depth + 1);
-          return state.tokenize(stream, state);
-        } else if (ch == ">") {
-          if (depth == 1) {
-            state.tokenize = inText;
-            break;
-          } else {
-            state.tokenize = doctype(depth - 1);
-            return state.tokenize(stream, state);
-          }
-        }
-      }
-      return "meta";
-    };
-  }
-
-  function Context(state, tagName, startOfLine) {
-    this.prev = state.context;
-    this.tagName = tagName;
-    this.indent = state.indented;
-    this.startOfLine = startOfLine;
-    if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
-      this.noIndent = true;
-  }
-  function popContext(state) {
-    if (state.context) state.context = state.context.prev;
-  }
-  function maybePopContext(state, nextTagName) {
-    var parentTagName;
-    while (true) {
-      if (!state.context) {
-        return;
-      }
-      parentTagName = state.context.tagName;
-      if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
-          !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
-        return;
-      }
-      popContext(state);
-    }
-  }
-
-  function baseState(type, stream, state) {
-    if (type == "openTag") {
-      state.tagStart = stream.column();
-      return tagNameState;
-    } else if (type == "closeTag") {
-      return closeTagNameState;
-    } else {
-      return baseState;
-    }
-  }
-  function tagNameState(type, stream, state) {
-    if (type == "word") {
-      state.tagName = stream.current();
-      setStyle = "tag";
-      return attrState;
-    } else {
-      setStyle = "error";
-      return tagNameState;
-    }
-  }
-  function closeTagNameState(type, stream, state) {
-    if (type == "word") {
-      var tagName = stream.current();
-      if (state.context && state.context.tagName != tagName &&
-          config.implicitlyClosed.hasOwnProperty(state.context.tagName))
-        popContext(state);
-      if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
-        setStyle = "tag";
-        return closeState;
-      } else {
-        setStyle = "tag error";
-        return closeStateErr;
-      }
-    } else {
-      setStyle = "error";
-      return closeStateErr;
-    }
-  }
-
-  function closeState(type, _stream, state) {
-    if (type != "endTag") {
-      setStyle = "error";
-      return closeState;
-    }
-    popContext(state);
-    return baseState;
-  }
-  function closeStateErr(type, stream, state) {
-    setStyle = "error";
-    return closeState(type, stream, state);
-  }
-
-  function attrState(type, _stream, state) {
-    if (type == "word") {
-      setStyle = "attribute";
-      return attrEqState;
-    } else if (type == "endTag" || type == "selfcloseTag") {
-      var tagName = state.tagName, tagStart = state.tagStart;
-      state.tagName = state.tagStart = null;
-      if (type == "selfcloseTag" ||
-          config.autoSelfClosers.hasOwnProperty(tagName)) {
-        maybePopContext(state, tagName);
-      } else {
-        maybePopContext(state, tagName);
-        state.context = new Context(state, tagName, tagStart == state.indented);
-      }
-      return baseState;
-    }
-    setStyle = "error";
-    return attrState;
-  }
-  function attrEqState(type, stream, state) {
-    if (type == "equals") return attrValueState;
-    if (!config.allowMissing) setStyle = "error";
-    return attrState(type, stream, state);
-  }
-  function attrValueState(type, stream, state) {
-    if (type == "string") return attrContinuedState;
-    if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
-    setStyle = "error";
-    return attrState(type, stream, state);
-  }
-  function attrContinuedState(type, stream, state) {
-    if (type == "string") return attrContinuedState;
-    return attrState(type, stream, state);
-  }
-
-  return {
-    startState: function(baseIndent) {
-      var state = {tokenize: inText,
-                   state: baseState,
-                   indented: baseIndent || 0,
-                   tagName: null, tagStart: null,
-                   context: null}
-      if (baseIndent != null) state.baseIndent = baseIndent
-      return state
-    },
-
-    token: function(stream, state) {
-      if (!state.tagName && stream.sol())
-        state.indented = stream.indentation();
-
-      if (stream.eatSpace()) return null;
-      type = null;
-      var style = state.tokenize(stream, state);
-      if ((style || type) && style != "comment") {
-        setStyle = null;
-        state.state = state.state(type || style, stream, state);
-        if (setStyle)
-          style = setStyle == "error" ? style + " error" : setStyle;
-      }
-      return style;
-    },
-
-    indent: function(state, textAfter, fullLine) {
-      var context = state.context;
-      // Indent multi-line strings (e.g. css).
-      if (state.tokenize.isInAttribute) {
-        if (state.tagStart == state.indented)
-          return state.stringStartCol + 1;
-        else
-          return state.indented + indentUnit;
-      }
-      if (context && context.noIndent) return CodeMirror.Pass;
-      if (state.tokenize != inTag && state.tokenize != inText)
-        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
-      // Indent the starts of attribute names.
-      if (state.tagName) {
-        if (config.multilineTagIndentPastTag !== false)
-          return state.tagStart + state.tagName.length + 2;
-        else
-          return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
-      }
-      if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
-      var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
-      if (tagAfter && tagAfter[1]) { // Closing tag spotted
-        while (context) {
-          if (context.tagName == tagAfter[2]) {
-            context = context.prev;
-            break;
-          } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
-            context = context.prev;
-          } else {
-            break;
-          }
-        }
-      } else if (tagAfter) { // Opening tag spotted
-        while (context) {
-          var grabbers = config.contextGrabbers[context.tagName];
-          if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
-            context = context.prev;
-          else
-            break;
-        }
-      }
-      while (context && context.prev && !context.startOfLine)
-        context = context.prev;
-      if (context) return context.indent + indentUnit;
-      else return state.baseIndent || 0;
-    },
-
-    electricInput: /<\/[\s\w:]+>$/,
-    blockCommentStart: "<!--",
-    blockCommentEnd: "-->",
-
-    configuration: config.htmlMode ? "html" : "xml",
-    helperType: config.htmlMode ? "html" : "xml",
-
-    skipAttribute: function(state) {
-      if (state.state == attrValueState)
-        state.state = attrState
-    }
-  };
-});
-
-CodeMirror.defineMIME("text/xml", "xml");
-CodeMirror.defineMIME("application/xml", "xml");
-if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
-  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
-
-});
\ No newline at end of file
diff --git a/front_end/color_picker/ContrastDetails.js b/front_end/color_picker/ContrastDetails.js
deleted file mode 100644
index 0ad9aa1..0000000
--- a/front_end/color_picker/ContrastDetails.js
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-ColorPicker.ContrastDetails = class {
-  /**
-   * @param {!ColorPicker.ContrastInfo} contrastInfo
-   * @param {!Element} contentElement
-   * @param {function(boolean=, !Common.Event=)} toggleMainColorPickerCallback
-   * @param {function()} expandedChangedCallback
-   */
-  constructor(contrastInfo, contentElement, toggleMainColorPickerCallback, expandedChangedCallback) {
-    /** @type {!ColorPicker.ContrastInfo} */
-    this._contrastInfo = contrastInfo;
-
-    /** @type {!Element} */
-    this._element = contentElement.createChild('div', 'spectrum-contrast-details collapsed');
-
-    /** @type {function(boolean=, !Common.Event=)} */
-    this._toggleMainColorPicker = toggleMainColorPickerCallback;
-
-    /** @type {function()} */
-    this._expandedChangedCallback = expandedChangedCallback;
-
-    /** @type {boolean} */
-    this._expanded = false;
-
-    /** @type {boolean} */
-    this._passesAA = true;
-
-    /** @type {boolean} */
-    this._contrastUnknown = false;
-
-    // This will not be visible if we don't get ContrastInfo,
-    // e.g. for a non-font color property such as border-color.
-    /** @type {boolean} */
-    this._visible = false;
-
-    const contrastValueRow = this._element.createChild('div');
-    contrastValueRow.addEventListener('click', this._topRowClicked.bind(this));
-    const contrastValueRowContents = contrastValueRow.createChild('div', 'container');
-    contrastValueRowContents.createTextChild(Common.UIString('Contrast ratio'));
-
-    this._contrastValueBubble = contrastValueRowContents.createChild('span', 'contrast-details-value');
-    this._contrastValue = this._contrastValueBubble.createChild('span');
-    this._contrastValueBubbleIcons = [];
-    this._contrastValueBubbleIcons.push(
-        this._contrastValueBubble.appendChild(UI.Icon.create('smallicon-checkmark-square')));
-    this._contrastValueBubbleIcons.push(
-        this._contrastValueBubble.appendChild(UI.Icon.create('smallicon-checkmark-behind')));
-    this._contrastValueBubbleIcons.push(this._contrastValueBubble.appendChild(UI.Icon.create('smallicon-no')));
-    this._contrastValueBubbleIcons.forEach(button => button.addEventListener('click', event => {
-      ColorPicker.ContrastDetails._showHelp();
-      event.consume(false);
-    }));
-
-    const expandToolbar = new UI.Toolbar('expand', contrastValueRowContents);
-    this._expandButton = new UI.ToolbarButton(Common.UIString('Show more'), 'smallicon-expand-more');
-    this._expandButton.addEventListener(UI.ToolbarButton.Events.Click, this._expandButtonClicked.bind(this));
-    UI.ARIAUtils.setExpanded(this._expandButton.element, false);
-    expandToolbar.appendToolbarItem(this._expandButton);
-
-    this._expandedDetails = this._element.createChild('div', 'expanded-details');
-    this._expandedDetails.id = 'expanded-contrast-details';
-    UI.ARIAUtils.setControls(this._expandButton.element, this._expandedDetails);
-
-    this._contrastThresholds = this._expandedDetails.createChild('div', 'contrast-thresholds');
-
-    this._contrastAA = this._contrastThresholds.createChild('div', 'contrast-threshold');
-    this._contrastPassFailAA = this._contrastAA.createChild('span', 'contrast-pass-fail');
-
-    this._contrastAAA = this._contrastThresholds.createChild('div', 'contrast-threshold');
-    this._contrastPassFailAAA = this._contrastAAA.createChild('span', 'contrast-pass-fail');
-
-    this._chooseBgColor = this._expandedDetails.createChild('div', 'contrast-choose-bg-color');
-    this._chooseBgColor.textContent = Common.UIString('Pick background color');
-
-    const bgColorContainer = this._expandedDetails.createChild('div', 'background-color');
-
-    const pickerToolbar = new UI.Toolbar('spectrum-eye-dropper', bgColorContainer);
-    this._bgColorPickerButton =
-        new UI.ToolbarToggle(Common.UIString('Toggle background color picker'), 'largeicon-eyedropper');
-    this._bgColorPickerButton.addEventListener(
-        UI.ToolbarButton.Events.Click, this._toggleBackgroundColorPicker.bind(this, undefined));
-    pickerToolbar.appendToolbarItem(this._bgColorPickerButton);
-    this._bgColorPickedBound = this._bgColorPicked.bind(this);
-
-    this._bgColorSwatch = new ColorPicker.ContrastDetails.Swatch(bgColorContainer);
-
-    this._contrastInfo.addEventListener(ColorPicker.ContrastInfo.Events.ContrastInfoUpdated, this._update.bind(this));
-  }
-
-  _update() {
-    if (this._contrastInfo.isNull()) {
-      this.setVisible(false);
-      return;
-    }
-
-    this.setVisible(true);
-
-    const contrastRatio = this._contrastInfo.contrastRatio();
-    const bgColor = this._contrastInfo.bgColor();
-    if (!contrastRatio || !bgColor) {
-      this._contrastUnknown = true;
-      this._contrastValue.textContent = '';
-      this._contrastValueBubble.classList.add('contrast-unknown');
-      this._chooseBgColor.classList.remove('hidden');
-      this._contrastThresholds.classList.add('hidden');
-      return;
-    }
-
-    this._contrastUnknown = false;
-    this._chooseBgColor.classList.add('hidden');
-    this._contrastThresholds.classList.remove('hidden');
-    this._contrastValueBubble.classList.remove('contrast-unknown');
-    this._contrastValue.textContent = contrastRatio.toFixed(2);
-
-    this._bgColorSwatch.setBackgroundColor(bgColor);
-    this._bgColorSwatch.setTextColor(this._contrastInfo.colorString());
-
-    const aa = this._contrastInfo.contrastRatioThreshold('aa');
-    this._passesAA = this._contrastInfo.contrastRatio() >= aa;
-    this._contrastPassFailAA.removeChildren();
-    const labelAA = this._contrastPassFailAA.createChild('span', 'contrast-link-label');
-    labelAA.textContent = Common.UIString('AA');
-    this._contrastPassFailAA.createChild('span').textContent = Common.UIString(': %s', aa.toFixed(1));
-    if (this._passesAA)
-      this._contrastPassFailAA.appendChild(UI.Icon.create('smallicon-checkmark-square'));
-    else
-      this._contrastPassFailAA.appendChild(UI.Icon.create('smallicon-no'));
-
-    const aaa = this._contrastInfo.contrastRatioThreshold('aaa');
-    const passesAAA = this._contrastInfo.contrastRatio() >= aaa;
-    this._contrastPassFailAAA.removeChildren();
-    const labelAAA = this._contrastPassFailAAA.createChild('span', 'contrast-link-label');
-    labelAAA.textContent = Common.UIString('AAA');
-    this._contrastPassFailAAA.createChild('span').textContent = Common.UIString(': %s', aaa.toFixed(1));
-    if (passesAAA)
-      this._contrastPassFailAAA.appendChild(UI.Icon.create('smallicon-checkmark-square'));
-    else
-      this._contrastPassFailAAA.appendChild(UI.Icon.create('smallicon-no'));
-
-    [labelAA, labelAAA].forEach(e => e.addEventListener('click', event => ColorPicker.ContrastDetails._showHelp()));
-
-    this._element.classList.toggle('contrast-fail', !this._passesAA);
-    this._contrastValueBubble.classList.toggle('contrast-aa', this._passesAA);
-    this._contrastValueBubble.classList.toggle('contrast-aaa', passesAAA);
-  }
-
-  static _showHelp() {
-    InspectorFrontendHost.openInNewTab(
-        'https://developers.google.com/web/fundamentals/accessibility/accessible-styles#color_and_contrast');
-  }
-
-  /**
-   * @param {boolean} visible
-   */
-  setVisible(visible) {
-    this._visible = visible;
-    this._element.classList.toggle('hidden', !visible);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  visible() {
-    return this._visible;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _expandButtonClicked(event) {
-    this._contrastValueBubble.getComponentSelection().empty();
-    this._toggleExpanded();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _topRowClicked(event) {
-    this._contrastValueBubble.getComponentSelection().empty();
-    this._toggleExpanded();
-    event.consume(true);
-  }
-
-  _toggleExpanded() {
-    this._expanded = !this._expanded;
-    UI.ARIAUtils.setExpanded(this._expandButton.element, this._expanded);
-    this._element.classList.toggle('collapsed', !this._expanded);
-    if (this._expanded) {
-      this._toggleMainColorPicker(false);
-      this._expandButton.setGlyph('smallicon-expand-less');
-      this._expandButton.setTitle(Common.UIString('Show less'));
-      if (this._contrastUnknown)
-        this._toggleBackgroundColorPicker(true);
-    } else {
-      this._toggleBackgroundColorPicker(false);
-      this._expandButton.setGlyph('smallicon-expand-more');
-      this._expandButton.setTitle(Common.UIString('Show more'));
-    }
-    this._expandedChangedCallback();
-  }
-
-  collapse() {
-    this._element.classList.remove('expanded');
-    this._toggleBackgroundColorPicker(false);
-    this._toggleMainColorPicker(false);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  expanded() {
-    return this._expanded;
-  }
-
-  /**
-   * @param {boolean=} enabled
-   */
-  _toggleBackgroundColorPicker(enabled) {
-    if (enabled === undefined)
-      enabled = !this._bgColorPickerButton.toggled();
-    this._bgColorPickerButton.setToggled(enabled);
-    InspectorFrontendHost.setEyeDropperActive(enabled);
-    if (enabled) {
-      InspectorFrontendHost.events.addEventListener(
-          InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._bgColorPickedBound);
-    } else {
-      InspectorFrontendHost.events.removeEventListener(
-          InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._bgColorPickedBound);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _bgColorPicked(event) {
-    const rgbColor = /** @type {!{r: number, g: number, b: number, a: number}} */ (event.data);
-    const rgba = [rgbColor.r, rgbColor.g, rgbColor.b, (rgbColor.a / 2.55 | 0) / 100];
-    const color = Common.Color.fromRGBA(rgba);
-    this._contrastInfo.setBgColor(color);
-    this._toggleBackgroundColorPicker(false);
-    InspectorFrontendHost.bringToFront();
-  }
-};
-
-ColorPicker.ContrastDetails.Swatch = class {
-  /**
-   * @param {!Element} parentElement
-   */
-  constructor(parentElement) {
-    this._parentElement = parentElement;
-    this._swatchElement = parentElement.createChild('span', 'swatch contrast swatch-inner-white');
-    this._swatchInnerElement = this._swatchElement.createChild('span', 'swatch-inner');
-    this._textPreview = this._swatchElement.createChild('div', 'text-preview');
-    this._textPreview.textContent = 'Aa';
-  }
-
-  /**
-   * @param {!Common.Color} color
-   */
-  setBackgroundColor(color) {
-    this._swatchInnerElement.style.background =
-        /** @type {string} */ (color.asString(Common.Color.Format.RGBA));
-    // Show border if the swatch is white.
-    this._swatchElement.classList.toggle('swatch-inner-white', color.hsla()[2] > 0.9);
-  }
-
-  /**
-   * @param {string} colorString
-   */
-  setTextColor(colorString) {
-    this._textPreview.style.color = colorString;
-  }
-};
diff --git a/front_end/color_picker/ContrastInfo.js b/front_end/color_picker/ContrastInfo.js
deleted file mode 100644
index 25c5899..0000000
--- a/front_end/color_picker/ContrastInfo.js
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-ColorPicker.ContrastInfo = class extends Common.Object {
-  constructor() {
-    super();
-
-    /** @type {?Array<number>} */
-    this._hsva = null;
-
-    /** @type {?Common.Color} */
-    this._fgColor = null;
-
-    /** @type {?Common.Color} */
-    this._bgColor = null;
-
-    /** @type {?number} */
-    this._contrastRatio = null;
-
-    /** @type {?Object<string, number>} */
-    this._contrastRatioThresholds = null;
-
-    /** @type {string} */
-    this._colorString = '';
-
-    /** @type {boolean} */
-    this._isNull = true;
-  }
-
-  /**
-   * @param {?SDK.CSSModel.ContrastInfo} contrastInfo
-   */
-  update(contrastInfo) {
-    this._isNull = true;
-    this._contrastRatio = null;
-    this._contrastRatioThresholds = null;
-    this._bgColor = null;
-
-    if (contrastInfo.computedFontSize && contrastInfo.computedFontWeight && contrastInfo.computedBodyFontSize) {
-      this._isNull = false;
-      const isLargeFont = ColorPicker.ContrastInfo.computeIsLargeFont(
-          contrastInfo.computedFontSize, contrastInfo.computedFontWeight, contrastInfo.computedBodyFontSize);
-
-      this._contrastRatioThresholds =
-          ColorPicker.ContrastInfo._ContrastThresholds[(isLargeFont ? 'largeFont' : 'normalFont')];
-    }
-
-    if (contrastInfo.backgroundColors && contrastInfo.backgroundColors.length === 1) {
-      const bgColorText = contrastInfo.backgroundColors[0];
-      const bgColor = Common.Color.parse(bgColorText);
-      if (bgColor)
-        this._setBgColorInternal(bgColor);
-    }
-
-    this.dispatchEventToListeners(ColorPicker.ContrastInfo.Events.ContrastInfoUpdated);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isNull() {
-    return this._isNull;
-  }
-
-  /**
-   * @param {!Array<number>} hsva
-   * @param {string} colorString
-   */
-  setColor(hsva, colorString) {
-    this._hsva = hsva;
-    this._fgColor = Common.Color.fromHSVA(hsva);
-    this._colorString = colorString;
-    this._updateContrastRatio();
-    this.dispatchEventToListeners(ColorPicker.ContrastInfo.Events.ContrastInfoUpdated);
-  }
-
-  /**
-   * @return {?number}
-   */
-  contrastRatio() {
-    return this._contrastRatio;
-  }
-
-  /**
-   * @return {string}
-   */
-  colorString() {
-    return this._colorString;
-  }
-
-  /**
-   * @return {?Array<number>}
-   */
-  hsva() {
-    return this._hsva;
-  }
-
-  /**
-   * @param {!Common.Color} bgColor
-   */
-  setBgColor(bgColor) {
-    this._setBgColorInternal(bgColor);
-    this.dispatchEventToListeners(ColorPicker.ContrastInfo.Events.ContrastInfoUpdated);
-  }
-
-  /**
-   * @param {!Common.Color} bgColor
-   */
-  _setBgColorInternal(bgColor) {
-    this._bgColor = bgColor;
-
-    if (!this._fgColor)
-      return;
-
-    const fgRGBA = this._fgColor.rgba();
-
-    // If we have a semi-transparent background color over an unknown
-    // background, draw the line for the "worst case" scenario: where
-    // the unknown background is the same color as the text.
-    if (bgColor.hasAlpha) {
-      const blendedRGBA = [];
-      Common.Color.blendColors(bgColor.rgba(), fgRGBA, blendedRGBA);
-      this._bgColor = new Common.Color(blendedRGBA, Common.Color.Format.RGBA);
-    }
-
-    this._contrastRatio = Common.Color.calculateContrastRatio(fgRGBA, this._bgColor.rgba());
-  }
-
-  /**
-   * @return {?Common.Color}
-   */
-  bgColor() {
-    return this._bgColor;
-  }
-
-  _updateContrastRatio() {
-    if (!this._bgColor || !this._fgColor)
-      return;
-    this._contrastRatio = Common.Color.calculateContrastRatio(this._fgColor.rgba(), this._bgColor.rgba());
-  }
-
-  /**
-   * @param {string} level
-   * @return {?number}
-   */
-  contrastRatioThreshold(level) {
-    if (!this._contrastRatioThresholds)
-      return null;
-    return this._contrastRatioThresholds[level];
-  }
-
-  /**
-   * @param {string} fontSize
-   * @param {string} fontWeight
-   * @param {?string} bodyFontSize
-   * @return {boolean}
-   */
-  static computeIsLargeFont(fontSize, fontWeight, bodyFontSize) {
-    const boldWeights = ['bold', 'bolder', '600', '700', '800', '900'];
-
-    const fontSizePx = parseFloat(fontSize.replace('px', ''));
-    const isBold = (boldWeights.indexOf(fontWeight) !== -1);
-
-    const fontSizePt = fontSizePx * 72 / 96;
-    if (isBold)
-      return fontSizePt >= 14;
-    else
-      return fontSizePt >= 18;
-  }
-};
-
-/** @enum {symbol} */
-ColorPicker.ContrastInfo.Events = {
-  ContrastInfoUpdated: Symbol('ContrastInfoUpdated')
-};
-
-ColorPicker.ContrastInfo._ContrastThresholds = {
-  largeFont: {aa: 3.0, aaa: 4.5},
-  normalFont: {aa: 4.5, aaa: 7.0}
-};
diff --git a/front_end/color_picker/ContrastOverlay.js b/front_end/color_picker/ContrastOverlay.js
deleted file mode 100644
index 573da0e..0000000
--- a/front_end/color_picker/ContrastOverlay.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-ColorPicker.ContrastOverlay = class {
-  /**
-   * @param {!ColorPicker.ContrastInfo} contrastInfo
-   * @param {!Element} colorElement
-   */
-  constructor(contrastInfo, colorElement) {
-    /** @type {!ColorPicker.ContrastInfo} */
-    this._contrastInfo = contrastInfo;
-
-    this._visible = false;
-
-    const contrastRatioSVG = colorElement.createSVGChild('svg', 'spectrum-contrast-container fill');
-    this._contrastRatioLine = contrastRatioSVG.createSVGChild('path', 'spectrum-contrast-line');
-
-    this._width = 0;
-    this._height = 0;
-
-    this._contrastRatioLineBuilder = new ColorPicker.ContrastRatioLineBuilder(this._contrastInfo);
-    this._contrastRatioLineThrottler = new Common.Throttler(0);
-    this._drawContrastRatioLineBound = this._drawContrastRatioLine.bind(this);
-
-    this._contrastInfo.addEventListener(ColorPicker.ContrastInfo.Events.ContrastInfoUpdated, this._update.bind(this));
-  }
-
-  _update() {
-    if (!this._visible || this._contrastInfo.isNull() || !this._contrastInfo.contrastRatio())
-      return;
-
-    this._contrastRatioLineThrottler.schedule(this._drawContrastRatioLineBound);
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  setDimensions(width, height) {
-    this._width = width;
-    this._height = height;
-    this._update();
-  }
-
-  /**
-   * @param {boolean} visible
-   */
-  setVisible(visible) {
-    this._visible = visible;
-    this._contrastRatioLine.classList.toggle('hidden', !visible);
-    this._update();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _drawContrastRatioLine() {
-    const path = this._contrastRatioLineBuilder.drawContrastRatioLine(this._width, this._height);
-    if (path)
-      this._contrastRatioLine.setAttribute('d', path);
-    return Promise.resolve();
-  }
-};
-
-ColorPicker.ContrastRatioLineBuilder = class {
-  /**
-   * @param {!ColorPicker.ContrastInfo} contrastInfo
-   */
-  constructor(contrastInfo) {
-    /** @type {!ColorPicker.ContrastInfo} */
-    this._contrastInfo = contrastInfo;
-
-    /** @type {?string} */
-    this._bgColorForPreviousLine = null;
-
-    this._hueForPreviousLine = 0;
-    this._alphaForPreviousLine = 0;
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   * @return {?string}
-   */
-  drawContrastRatioLine(width, height) {
-    const requiredContrast = this._contrastInfo.contrastRatioThreshold('aa');
-    if (!width || !height || !requiredContrast)
-      return null;
-
-    const dS = 0.02;
-    const epsilon = 0.0002;
-    const H = 0;
-    const S = 1;
-    const V = 2;
-    const A = 3;
-
-    const hsva = this._contrastInfo.hsva();
-    const bgColor = this._contrastInfo.bgColor();
-    if (!hsva || !bgColor)
-      return null;
-
-    const bgColorString = bgColor.asString(Common.Color.Format.RGBA);
-
-    // Don't compute a new line if it would be identical to the previous line.
-    if (hsva[H] === this._hueForPreviousLine && hsva[A] === this._alphaForPreviousLine &&
-        bgColorString === this._bgColorForPreviousLine)
-      return null;
-
-    const fgRGBA = [];
-    Common.Color.hsva2rgba(hsva, fgRGBA);
-    const bgRGBA = bgColor.rgba();
-    const bgLuminance = Common.Color.luminance(bgRGBA);
-    const blendedRGBA = [];
-    Common.Color.blendColors(fgRGBA, bgRGBA, blendedRGBA);
-    const fgLuminance = Common.Color.luminance(blendedRGBA);
-    const fgIsLighter = fgLuminance > bgLuminance;
-    const desiredLuminance = Common.Color.desiredLuminance(bgLuminance, requiredContrast, fgIsLighter);
-
-    let lastV = hsva[V];
-    let currentSlope = 0;
-    const candidateHSVA = [hsva[H], 0, 0, hsva[A]];
-    let pathBuilder = [];
-    const candidateRGBA = [];
-    Common.Color.hsva2rgba(candidateHSVA, candidateRGBA);
-    Common.Color.blendColors(candidateRGBA, bgRGBA, blendedRGBA);
-
-    /**
-     * @param {number} index
-     * @param {number} x
-     */
-    function updateCandidateAndComputeDelta(index, x) {
-      candidateHSVA[index] = x;
-      Common.Color.hsva2rgba(candidateHSVA, candidateRGBA);
-      Common.Color.blendColors(candidateRGBA, bgRGBA, blendedRGBA);
-      return Common.Color.luminance(blendedRGBA) - desiredLuminance;
-    }
-
-    /**
-     * Approach a value of the given component of `candidateHSVA` such that the
-     * calculated luminance of `candidateHSVA` approximates `desiredLuminance`.
-     * @param {number} index The component of `candidateHSVA` to modify.
-     * @return {?number} The new value for the modified component, or `null` if
-     *     no suitable value exists.
-     */
-    function approach(index) {
-      let x = candidateHSVA[index];
-      let multiplier = 1;
-      let dLuminance = updateCandidateAndComputeDelta(index, x);
-      let previousSign = Math.sign(dLuminance);
-
-      for (let guard = 100; guard; guard--) {
-        if (Math.abs(dLuminance) < epsilon)
-          return x;
-
-        const sign = Math.sign(dLuminance);
-        if (sign !== previousSign) {
-          // If `x` overshoots the correct value, halve the step size.
-          multiplier /= 2;
-          previousSign = sign;
-        } else if (x < 0 || x > 1) {
-          // If there is no overshoot and `x` is out of bounds, there is no
-          // acceptable value for `x`.
-          return null;
-        }
-
-        // Adjust `x` by a multiple of `dLuminance` to decrease step size as
-        // the computed luminance converges on `desiredLuminance`.
-        x += multiplier * (index === V ? -dLuminance : dLuminance);
-
-        dLuminance = updateCandidateAndComputeDelta(index, x);
-      }
-      // The loop should always converge or go out of bounds on its own.
-      console.error('Loop exited unexpectedly');
-      return null;
-    }
-
-    // Plot V for values of S such that the computed luminance approximates
-    // `desiredLuminance`, until no suitable value for V can be found, or the
-    // current value of S goes of out bounds.
-    let s;
-    for (s = 0; s < 1 + dS; s += dS) {
-      s = Math.min(1, s);
-      candidateHSVA[S] = s;
-
-      // Extrapolate the approximate next value for `v` using the approximate
-      // gradient of the curve.
-      candidateHSVA[V] = lastV + currentSlope * dS;
-
-      const v = approach(V);
-      if (v === null)
-        break;
-
-      // Approximate the current gradient of the curve.
-      currentSlope = s === 0 ? 0 : (v - lastV) / dS;
-      lastV = v;
-
-      pathBuilder.push(pathBuilder.length ? 'L' : 'M');
-      pathBuilder.push((s * width).toFixed(2));
-      pathBuilder.push(((1 - v) * height).toFixed(2));
-    }
-
-    // If no suitable V value for an in-bounds S value was found, find the value
-    // of S such that V === 1 and add that to the path.
-    if (s < 1 + dS) {
-      s -= dS;
-      candidateHSVA[V] = 1;
-      s = approach(S);
-      if (s !== null)
-        pathBuilder = pathBuilder.concat(['L', (s * width).toFixed(2), '-0.1']);
-    }
-
-    this._bgColorForPreviousLine = bgColorString;
-    this._hueForPreviousLine = hsva[H];
-    this._alphaForPreviousLine = hsva[A];
-
-    return pathBuilder.join(' ');
-  }
-};
diff --git a/front_end/color_picker/Spectrum.js b/front_end/color_picker/Spectrum.js
deleted file mode 100644
index de28da1..0000000
--- a/front_end/color_picker/Spectrum.js
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- * Copyright (C) 2011 Brian Grinstead All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-ColorPicker.Spectrum = class extends UI.VBox {
-  constructor() {
-    /**
-     * @param {!Element} parentElement
-     */
-    function appendSwitcherIcon(parentElement) {
-      const icon = parentElement.createSVGChild('svg');
-      icon.setAttribute('height', 16);
-      icon.setAttribute('width', 16);
-      const path = icon.createSVGChild('path');
-      path.setAttribute('d', 'M5,6 L11,6 L8,2 Z M5,10 L11,10 L8,14 Z');
-      return icon;
-    }
-
-    super(true);
-    this.registerRequiredCSS('color_picker/spectrum.css');
-    this.contentElement.tabIndex = 0;
-    this.setDefaultFocusedElement(this.contentElement);
-
-    this._colorElement = this.contentElement.createChild('div', 'spectrum-color');
-    this._colorDragElement = this._colorElement.createChild('div', 'spectrum-sat fill')
-                                 .createChild('div', 'spectrum-val fill')
-                                 .createChild('div', 'spectrum-dragger');
-    this._dragX = 0;
-    this._dragY = 0;
-
-    const toolsContainer = this.contentElement.createChild('div', 'spectrum-tools');
-    const toolbar = new UI.Toolbar('spectrum-eye-dropper', toolsContainer);
-    this._colorPickerButton = new UI.ToolbarToggle(Common.UIString('Toggle color picker'), 'largeicon-eyedropper');
-    this._colorPickerButton.setToggled(true);
-    this._colorPickerButton.addEventListener(
-        UI.ToolbarButton.Events.Click, this._toggleColorPicker.bind(this, undefined));
-    toolbar.appendToolbarItem(this._colorPickerButton);
-
-    this._swatch = new ColorPicker.Spectrum.Swatch(toolsContainer);
-
-    this._hueElement = toolsContainer.createChild('div', 'spectrum-hue');
-    this._hueSlider = this._hueElement.createChild('div', 'spectrum-slider');
-    this._alphaElement = toolsContainer.createChild('div', 'spectrum-alpha');
-    this._alphaElementBackground = this._alphaElement.createChild('div', 'spectrum-alpha-background');
-    this._alphaSlider = this._alphaElement.createChild('div', 'spectrum-slider');
-
-    const displaySwitcher = toolsContainer.createChild('div', 'spectrum-display-switcher spectrum-switcher');
-    appendSwitcherIcon(displaySwitcher);
-    displaySwitcher.addEventListener('click', this._formatViewSwitch.bind(this));
-
-    // RGBA/HSLA display.
-    this._displayContainer = toolsContainer.createChild('div', 'spectrum-text source-code');
-    this._textValues = [];
-    for (let i = 0; i < 4; ++i) {
-      const inputValue = UI.createInput('spectrum-text-value');
-      this._displayContainer.appendChild(inputValue);
-      inputValue.maxLength = 4;
-      this._textValues.push(inputValue);
-      inputValue.addEventListener('keydown', this._inputChanged.bind(this), false);
-      inputValue.addEventListener('input', this._inputChanged.bind(this), false);
-      inputValue.addEventListener('mousewheel', this._inputChanged.bind(this), false);
-    }
-
-    this._textLabels = this._displayContainer.createChild('div', 'spectrum-text-label');
-
-    // HEX display.
-    this._hexContainer = toolsContainer.createChild('div', 'spectrum-text spectrum-text-hex source-code');
-    this._hexValue = UI.createInput('spectrum-text-value');
-    this._hexContainer.appendChild(this._hexValue);
-    this._hexValue.maxLength = 9;
-    this._hexValue.addEventListener('keydown', this._inputChanged.bind(this), false);
-    this._hexValue.addEventListener('input', this._inputChanged.bind(this), false);
-    this._hexValue.addEventListener('mousewheel', this._inputChanged.bind(this), false);
-
-    const label = this._hexContainer.createChild('div', 'spectrum-text-label');
-    label.textContent = 'HEX';
-
-    UI.installDragHandle(
-        this._hueElement, dragStart.bind(this, positionHue.bind(this)), positionHue.bind(this), null, 'pointer',
-        'default');
-    UI.installDragHandle(
-        this._alphaElement, dragStart.bind(this, positionAlpha.bind(this)), positionAlpha.bind(this), null, 'pointer',
-        'default');
-    UI.installDragHandle(
-        this._colorElement, dragStart.bind(this, positionColor.bind(this)), positionColor.bind(this), null, 'pointer',
-        'default');
-
-    if (Runtime.experiments.isEnabled('colorContrastRatio')) {
-      const boundToggleColorPicker = this._toggleColorPicker.bind(this);
-      const boundContrastPanelExpanded = this._contrastPanelExpanded.bind(this);
-      /** @type {!ColorPicker.ContrastInfo} */
-      this._contrastInfo = new ColorPicker.ContrastInfo();
-      this._contrastOverlay = new ColorPicker.ContrastOverlay(this._contrastInfo, this._colorElement);
-      this._contrastDetails = new ColorPicker.ContrastDetails(
-          this._contrastInfo, this.contentElement, boundToggleColorPicker, boundContrastPanelExpanded);
-    }
-
-    this.element.classList.add('palettes-enabled', 'flex-none');
-    /** @type {!Map.<string, !ColorPicker.Spectrum.Palette>} */
-    this._palettes = new Map();
-    this._palettePanel = this.contentElement.createChild('div', 'palette-panel');
-    this._palettePanelShowing = false;
-    this._paletteSectionContainer = this.contentElement.createChild('div', 'spectrum-palette-container');
-    this._paletteContainer = this._paletteSectionContainer.createChild('div', 'spectrum-palette');
-    this._paletteContainer.addEventListener('contextmenu', this._showPaletteColorContextMenu.bind(this, -1));
-    this._shadesContainer = this.contentElement.createChild('div', 'palette-color-shades hidden');
-    UI.installDragHandle(
-        this._paletteContainer, this._paletteDragStart.bind(this), this._paletteDrag.bind(this),
-        this._paletteDragEnd.bind(this), 'default');
-    const paletteSwitcher =
-        this._paletteSectionContainer.createChild('div', 'spectrum-palette-switcher spectrum-switcher');
-    appendSwitcherIcon(paletteSwitcher);
-    paletteSwitcher.addEventListener('click', this._togglePalettePanel.bind(this, true));
-
-    this._deleteIconToolbar = new UI.Toolbar('delete-color-toolbar');
-    this._deleteButton = new UI.ToolbarButton('', 'largeicon-trash-bin');
-    this._deleteIconToolbar.appendToolbarItem(this._deleteButton);
-
-    const overlay = this.contentElement.createChild('div', 'spectrum-overlay fill');
-    overlay.addEventListener('click', this._togglePalettePanel.bind(this, false));
-
-    this._addColorToolbar = new UI.Toolbar('add-color-toolbar');
-    const addColorButton = new UI.ToolbarButton(Common.UIString('Add to palette'), 'largeicon-add');
-    addColorButton.addEventListener(UI.ToolbarButton.Events.Click, this._addColorToCustomPalette, this);
-    this._addColorToolbar.appendToolbarItem(addColorButton);
-
-    this._colorPickedBound = this._colorPicked.bind(this);
-
-    this._loadPalettes();
-    new ColorPicker.Spectrum.PaletteGenerator(this._generatedPaletteLoaded.bind(this));
-
-    /**
-     * @param {function(!Event)} callback
-     * @param {!Event} event
-     * @return {boolean}
-     * @this {ColorPicker.Spectrum}
-     */
-    function dragStart(callback, event) {
-      this._hueAlphaLeft = this._hueElement.totalOffsetLeft();
-      this._colorOffset = this._colorElement.totalOffset();
-      callback(event);
-      return true;
-    }
-
-    /**
-     * @param {!Event} event
-     * @this {ColorPicker.Spectrum}
-     */
-    function positionHue(event) {
-      const hsva = this._hsv.slice();
-      hsva[0] = Number.constrain(1 - (event.x - this._hueAlphaLeft) / this._hueAlphaWidth, 0, 1);
-      this._innerSetColor(hsva, '', undefined, ColorPicker.Spectrum._ChangeSource.Other);
-    }
-
-    /**
-     * @param {!Event} event
-     * @this {ColorPicker.Spectrum}
-     */
-    function positionAlpha(event) {
-      const newAlpha = Math.round((event.x - this._hueAlphaLeft) / this._hueAlphaWidth * 100) / 100;
-      const hsva = this._hsv.slice();
-      hsva[3] = Number.constrain(newAlpha, 0, 1);
-      this._innerSetColor(hsva, '', undefined, ColorPicker.Spectrum._ChangeSource.Other);
-    }
-
-    /**
-     * @param {!Event} event
-     * @this {ColorPicker.Spectrum}
-     */
-    function positionColor(event) {
-      const hsva = this._hsv.slice();
-      hsva[1] = Number.constrain((event.x - this._colorOffset.left) / this.dragWidth, 0, 1);
-      hsva[2] = Number.constrain(1 - (event.y - this._colorOffset.top) / this.dragHeight, 0, 1);
-
-      this._innerSetColor(hsva, '', undefined, ColorPicker.Spectrum._ChangeSource.Other);
-    }
-  }
-
-  _contrastPanelExpanded() {
-    if (this._contrastDetails.expanded())
-      this._contrastOverlay.setVisible(true);
-    else
-      this._contrastOverlay.setVisible(false);
-    this._resizeForSelectedPalette(true);
-  }
-
-  _updatePalettePanel() {
-    this._palettePanel.removeChildren();
-    const title = this._palettePanel.createChild('div', 'palette-title');
-    title.textContent = Common.UIString('Color Palettes');
-    const toolbar = new UI.Toolbar('', this._palettePanel);
-    const closeButton = new UI.ToolbarButton('Return to color picker', 'largeicon-delete');
-    closeButton.addEventListener(UI.ToolbarButton.Events.Click, this._togglePalettePanel.bind(this, false));
-    toolbar.appendToolbarItem(closeButton);
-    for (const palette of this._palettes.values())
-      this._palettePanel.appendChild(this._createPreviewPaletteElement(palette));
-  }
-
-  /**
-   * @param {boolean} show
-   */
-  _togglePalettePanel(show) {
-    if (this._palettePanelShowing === show)
-      return;
-    if (show)
-      this._updatePalettePanel();
-    this._focus();
-    this._palettePanelShowing = show;
-    this.contentElement.classList.toggle('palette-panel-showing', show);
-  }
-
-  _focus() {
-    if (this.isShowing())
-      this.contentElement.focus();
-  }
-
-  /**
-   * @param {string} colorText
-   * @param {number=} animationDelay
-   * @return {!Element}
-   */
-  _createPaletteColor(colorText, animationDelay) {
-    const element = createElementWithClass('div', 'spectrum-palette-color');
-    element.style.background = String.sprintf('linear-gradient(%s, %s), url(Images/checker.png)', colorText, colorText);
-    if (animationDelay)
-      element.animate([{opacity: 0}, {opacity: 1}], {duration: 100, delay: animationDelay, fill: 'backwards'});
-    element.title = colorText;
-    return element;
-  }
-
-  /**
-   * @param {!ColorPicker.Spectrum.Palette} palette
-   * @param {boolean} animate
-   * @param {!Event=} event
-   */
-  _showPalette(palette, animate, event) {
-    this._resizeForSelectedPalette();
-    this._paletteContainer.removeChildren();
-    for (let i = 0; i < palette.colors.length; i++) {
-      const animationDelay = animate ? i * 100 / palette.colors.length : 0;
-      const colorElement = this._createPaletteColor(palette.colors[i], animationDelay);
-      colorElement.addEventListener(
-          'mousedown', this._paletteColorSelected.bind(this, palette.colors[i], palette.matchUserFormat));
-      if (palette.mutable) {
-        colorElement.__mutable = true;
-        colorElement.__color = palette.colors[i];
-        colorElement.addEventListener('contextmenu', this._showPaletteColorContextMenu.bind(this, i));
-      } else if (palette === ColorPicker.Spectrum.MaterialPalette) {
-        colorElement.classList.add('has-material-shades');
-        let shadow = colorElement.createChild('div', 'spectrum-palette-color spectrum-palette-color-shadow');
-        shadow.style.background = palette.colors[i];
-        shadow = colorElement.createChild('div', 'spectrum-palette-color spectrum-palette-color-shadow');
-        shadow.style.background = palette.colors[i];
-        colorElement.title = Common.UIString(palette.colors[i] + '. Long-click to show alternate shades.');
-        new UI.LongClickController(colorElement, this._showLightnessShades.bind(this, colorElement, palette.colors[i]));
-      }
-      this._paletteContainer.appendChild(colorElement);
-    }
-    this._paletteContainerMutable = palette.mutable;
-
-    if (palette.mutable) {
-      this._paletteContainer.appendChild(this._addColorToolbar.element);
-      this._paletteContainer.appendChild(this._deleteIconToolbar.element);
-    } else {
-      this._addColorToolbar.element.remove();
-      this._deleteIconToolbar.element.remove();
-    }
-
-    this._togglePalettePanel(false);
-    this._focus();
-  }
-
-  /**
-   * @param {!Element} colorElement
-   * @param {string} colorText
-   * @param {!Event} event
-   */
-  _showLightnessShades(colorElement, colorText, event) {
-    /**
-     * @param {!Element} element
-     * @this {!ColorPicker.Spectrum}
-     */
-    function closeLightnessShades(element) {
-      this._shadesContainer.classList.add('hidden');
-      element.classList.remove('spectrum-shades-shown');
-      this._shadesContainer.ownerDocument.removeEventListener('mousedown', this._shadesCloseHandler, true);
-      delete this._shadesCloseHandler;
-    }
-
-    if (this._shadesCloseHandler)
-      this._shadesCloseHandler();
-
-    this._shadesContainer.classList.remove('hidden');
-    this._shadesContainer.removeChildren();
-    this._shadesContainer.animate(
-        [{transform: 'scaleY(0)', opacity: '0'}, {transform: 'scaleY(1)', opacity: '1'}],
-        {duration: 200, easing: 'cubic-bezier(0.4, 0, 0.2, 1)'});
-    let shadesTop = this._paletteContainer.offsetTop + colorElement.offsetTop + colorElement.parentElement.offsetTop;
-    if (this._contrastDetails && this._contrastDetails.visible())
-      shadesTop += this._contrastDetails.element().offsetHeight;
-    this._shadesContainer.style.top = shadesTop + 'px';
-    this._shadesContainer.style.left = colorElement.offsetLeft + 'px';
-    colorElement.classList.add('spectrum-shades-shown');
-
-    const shades = ColorPicker.Spectrum.MaterialPaletteShades[colorText];
-    for (let i = shades.length - 1; i >= 0; i--) {
-      const shadeElement = this._createPaletteColor(shades[i], i * 200 / shades.length + 100);
-      shadeElement.addEventListener('mousedown', this._paletteColorSelected.bind(this, shades[i], false));
-      this._shadesContainer.appendChild(shadeElement);
-    }
-
-    this._shadesContainer.focus();
-    this._shadesCloseHandler = closeLightnessShades.bind(this, colorElement);
-    this._shadesContainer.ownerDocument.addEventListener('mousedown', this._shadesCloseHandler, true);
-  }
-
-  /**
-   * @param {!Event} e
-   * @return {number}
-   */
-  _slotIndexForEvent(e) {
-    const localX = e.pageX - this._paletteContainer.totalOffsetLeft();
-    const localY = e.pageY - this._paletteContainer.totalOffsetTop();
-    const col =
-        Math.min(localX / ColorPicker.Spectrum._colorChipSize | 0, ColorPicker.Spectrum._itemsPerPaletteRow - 1);
-    const row = (localY / ColorPicker.Spectrum._colorChipSize) | 0;
-    return Math.min(
-        row * ColorPicker.Spectrum._itemsPerPaletteRow + col, this._customPaletteSetting.get().colors.length - 1);
-  }
-
-  /**
-   * @param {!Event} e
-   * @return {boolean}
-   */
-  _isDraggingToBin(e) {
-    return e.pageX > this._deleteIconToolbar.element.totalOffsetLeft();
-  }
-
-  /**
-   * @param {!Event} e
-   * @return {boolean}
-   */
-  _paletteDragStart(e) {
-    const element = e.deepElementFromPoint();
-    if (!element || !element.__mutable)
-      return false;
-
-    const index = this._slotIndexForEvent(e);
-    this._dragElement = element;
-    this._dragHotSpotX =
-        e.pageX - (index % ColorPicker.Spectrum._itemsPerPaletteRow) * ColorPicker.Spectrum._colorChipSize;
-    this._dragHotSpotY =
-        e.pageY - (index / ColorPicker.Spectrum._itemsPerPaletteRow | 0) * ColorPicker.Spectrum._colorChipSize;
-    return true;
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _paletteDrag(e) {
-    if (e.pageX < this._paletteContainer.totalOffsetLeft() || e.pageY < this._paletteContainer.totalOffsetTop())
-      return;
-    const newIndex = this._slotIndexForEvent(e);
-    const offsetX =
-        e.pageX - (newIndex % ColorPicker.Spectrum._itemsPerPaletteRow) * ColorPicker.Spectrum._colorChipSize;
-    const offsetY =
-        e.pageY - (newIndex / ColorPicker.Spectrum._itemsPerPaletteRow | 0) * ColorPicker.Spectrum._colorChipSize;
-
-    const isDeleting = this._isDraggingToBin(e);
-    this._deleteIconToolbar.element.classList.add('dragging');
-    this._deleteIconToolbar.element.classList.toggle('delete-color-toolbar-active', isDeleting);
-    const dragElementTransform =
-        'translateX(' + (offsetX - this._dragHotSpotX) + 'px) translateY(' + (offsetY - this._dragHotSpotY) + 'px)';
-    this._dragElement.style.transform = isDeleting ? dragElementTransform + ' scale(0.8)' : dragElementTransform;
-    const children = Array.prototype.slice.call(this._paletteContainer.children);
-    const index = children.indexOf(this._dragElement);
-    /** @type {!Map.<!Element, {left: number, top: number}>} */
-    const swatchOffsets = new Map();
-    for (const swatch of children)
-      swatchOffsets.set(swatch, swatch.totalOffset());
-
-    if (index !== newIndex)
-      this._paletteContainer.insertBefore(this._dragElement, children[newIndex > index ? newIndex + 1 : newIndex]);
-
-    for (const swatch of children) {
-      if (swatch === this._dragElement)
-        continue;
-      const before = swatchOffsets.get(swatch);
-      const after = swatch.totalOffset();
-      if (before.left !== after.left || before.top !== after.top) {
-        swatch.animate(
-            [
-              {
-                transform:
-                    'translateX(' + (before.left - after.left) + 'px) translateY(' + (before.top - after.top) + 'px)'
-              },
-              {transform: 'none'}
-            ],
-            {duration: 100, easing: 'cubic-bezier(0, 0, 0.2, 1)'});
-      }
-    }
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _paletteDragEnd(e) {
-    if (this._isDraggingToBin(e))
-      this._dragElement.remove();
-    this._dragElement.style.removeProperty('transform');
-    const children = this._paletteContainer.children;
-    const colors = [];
-    for (let i = 0; i < children.length; ++i) {
-      if (children[i].__color)
-        colors.push(children[i].__color);
-    }
-    const palette = this._customPaletteSetting.get();
-    palette.colors = colors;
-    this._customPaletteSetting.set(palette);
-    this._showPalette(this._customPaletteSetting.get(), false);
-
-    this._deleteIconToolbar.element.classList.remove('dragging');
-    this._deleteIconToolbar.element.classList.remove('delete-color-toolbar-active');
-  }
-
-  _loadPalettes() {
-    this._palettes.set(ColorPicker.Spectrum.MaterialPalette.title, ColorPicker.Spectrum.MaterialPalette);
-    /** @type {!ColorPicker.Spectrum.Palette} */
-    const defaultCustomPalette = {title: 'Custom', colors: [], mutable: true};
-    this._customPaletteSetting = Common.settings.createSetting('customColorPalette', defaultCustomPalette);
-    this._palettes.set(this._customPaletteSetting.get().title, this._customPaletteSetting.get());
-
-    this._selectedColorPalette =
-        Common.settings.createSetting('selectedColorPalette', ColorPicker.Spectrum.GeneratedPaletteTitle);
-    const palette = this._palettes.get(this._selectedColorPalette.get());
-    if (palette)
-      this._showPalette(palette, true);
-  }
-
-  /**
-   * @param {!ColorPicker.Spectrum.Palette} generatedPalette
-   */
-  _generatedPaletteLoaded(generatedPalette) {
-    if (generatedPalette.colors.length)
-      this._palettes.set(generatedPalette.title, generatedPalette);
-    if (this._selectedColorPalette.get() !== generatedPalette.title) {
-      return;
-    } else if (!generatedPalette.colors.length) {
-      this._paletteSelected(ColorPicker.Spectrum.MaterialPalette);
-      return;
-    }
-    this._showPalette(generatedPalette, true);
-  }
-
-  /**
-   * @param {!ColorPicker.Spectrum.Palette} palette
-   * @return {!Element}
-   */
-  _createPreviewPaletteElement(palette) {
-    const colorsPerPreviewRow = 5;
-    const previewElement = createElementWithClass('div', 'palette-preview');
-    const titleElement = previewElement.createChild('div', 'palette-preview-title');
-    titleElement.textContent = palette.title;
-    let i;
-    for (i = 0; i < colorsPerPreviewRow && i < palette.colors.length; i++)
-      previewElement.appendChild(this._createPaletteColor(palette.colors[i]));
-    for (; i < colorsPerPreviewRow; i++)
-      previewElement.createChild('div', 'spectrum-palette-color empty-color');
-    previewElement.addEventListener('click', this._paletteSelected.bind(this, palette));
-    return previewElement;
-  }
-
-  /**
-   * @param {!ColorPicker.Spectrum.Palette} palette
-   */
-  _paletteSelected(palette) {
-    this._selectedColorPalette.set(palette.title);
-    this._showPalette(palette, true);
-  }
-
-  /**
-   * @param {boolean=} force
-   */
-  _resizeForSelectedPalette(force) {
-    const palette = this._palettes.get(this._selectedColorPalette.get());
-    if (!palette)
-      return;
-    let numColors = palette.colors.length;
-    if (palette === this._customPaletteSetting.get())
-      numColors++;
-    const rowsNeeded = Math.max(1, Math.ceil(numColors / ColorPicker.Spectrum._itemsPerPaletteRow));
-    if (this._numPaletteRowsShown === rowsNeeded && !force)
-      return;
-    this._numPaletteRowsShown = rowsNeeded;
-    const paletteColorHeight = 12;
-    const paletteMargin = 12;
-    let paletteTop = 236;
-    if (this._contrastDetails && this._contrastDetails.visible()) {
-      if (this._contrastDetails.expanded())
-        paletteTop += 78;
-      else
-        paletteTop += 36;
-    }
-    this.element.style.height = (paletteTop + paletteMargin + (paletteColorHeight + paletteMargin) * rowsNeeded) + 'px';
-    this.dispatchEventToListeners(ColorPicker.Spectrum.Events.SizeChanged);
-  }
-
-  /**
-   * @param {string} colorText
-   * @param {boolean} matchUserFormat
-   */
-  _paletteColorSelected(colorText, matchUserFormat) {
-    const color = Common.Color.parse(colorText);
-    if (!color)
-      return;
-    this._innerSetColor(
-        color.hsva(), colorText, matchUserFormat ? this._colorFormat : color.format(),
-        ColorPicker.Spectrum._ChangeSource.Other);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _addColorToCustomPalette(event) {
-    const palette = this._customPaletteSetting.get();
-    palette.colors.push(this.colorString());
-    this._customPaletteSetting.set(palette);
-    this._showPalette(this._customPaletteSetting.get(), false);
-  }
-
-  /**
-   * @param {number} colorIndex
-   * @param {!Event} event
-   */
-  _showPaletteColorContextMenu(colorIndex, event) {
-    if (!this._paletteContainerMutable)
-      return;
-    const contextMenu = new UI.ContextMenu(event);
-    if (colorIndex !== -1) {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString('Remove color'), this._deletePaletteColors.bind(this, colorIndex, false));
-      contextMenu.defaultSection().appendItem(
-          Common.UIString('Remove all to the right'), this._deletePaletteColors.bind(this, colorIndex, true));
-    }
-    contextMenu.defaultSection().appendItem(
-        Common.UIString('Clear palette'), this._deletePaletteColors.bind(this, -1, true));
-    contextMenu.show();
-  }
-
-  /**
-   * @param {number} colorIndex
-   * @param {boolean} toRight
-   */
-  _deletePaletteColors(colorIndex, toRight) {
-    const palette = this._customPaletteSetting.get();
-    if (toRight)
-      palette.colors.splice(colorIndex + 1, palette.colors.length - colorIndex - 1);
-    else
-      palette.colors.splice(colorIndex, 1);
-    this._customPaletteSetting.set(palette);
-    this._showPalette(this._customPaletteSetting.get(), false);
-  }
-
-  /**
-   * @param {!Common.Color} color
-   * @param {string} colorFormat
-   */
-  setColor(color, colorFormat) {
-    this._originalFormat = colorFormat;
-    this._innerSetColor(color.hsva(), '', colorFormat, ColorPicker.Spectrum._ChangeSource.Model);
-  }
-
-  /**
-   * @param {?SDK.CSSModel.ContrastInfo} contrastInfo
-   */
-  setContrastInfo(contrastInfo) {
-    if (!this._contrastInfo)
-      return;
-
-    this._contrastInfo.update(contrastInfo);
-
-    // Contrast info may cause contrast details to become visible.
-    if (this._contrastDetails.visible())
-      this._resizeForSelectedPalette(true);
-  }
-
-  /**
-   * @param {!Array<number>|undefined} hsva
-   * @param {string|undefined} colorString
-   * @param {string|undefined} colorFormat
-   * @param {string} changeSource
-   */
-  _innerSetColor(hsva, colorString, colorFormat, changeSource) {
-    if (hsva !== undefined)
-      this._hsv = hsva;
-    if (colorString !== undefined)
-      this._colorString = colorString;
-    if (colorFormat !== undefined) {
-      const cf = Common.Color.Format;
-      console.assert(colorFormat !== cf.Original, 'Spectrum\'s color format cannot be Original');
-      if (colorFormat === cf.RGBA)
-        colorFormat = cf.RGB;
-      else if (colorFormat === cf.HSLA)
-        colorFormat = cf.HSL;
-      else if (colorFormat === cf.HEXA)
-        colorFormat = cf.HEX;
-      else if (colorFormat === cf.ShortHEXA)
-        colorFormat = cf.ShortHEX;
-      this._colorFormat = colorFormat;
-    }
-
-    if (hsva && this._contrastInfo)
-      this._contrastInfo.setColor(hsva, this.colorString());
-
-    this._updateHelperLocations();
-    this._updateUI();
-
-    if (changeSource !== ColorPicker.Spectrum._ChangeSource.Input)
-      this._updateInput();
-    if (changeSource !== ColorPicker.Spectrum._ChangeSource.Model)
-      this.dispatchEventToListeners(ColorPicker.Spectrum.Events.ColorChanged, this.colorString());
-  }
-
-  /**
-   * @return {!Common.Color}
-   */
-  _color() {
-    return Common.Color.fromHSVA(this._hsv);
-  }
-
-  /**
-   * @return {string}
-   */
-  colorString() {
-    if (this._colorString)
-      return this._colorString;
-    const cf = Common.Color.Format;
-    const color = this._color();
-    let colorString = color.asString(this._colorFormat);
-    if (colorString)
-      return colorString;
-
-    if (this._colorFormat === cf.Nickname)
-      colorString = color.asString(color.hasAlpha() ? cf.HEXA : cf.HEX);
-    else if (this._colorFormat === cf.ShortHEX)
-      colorString = color.asString(color.detectHEXFormat());
-    else if (this._colorFormat === cf.HEX)
-      colorString = color.asString(cf.HEXA);
-    else if (this._colorFormat === cf.HSL)
-      colorString = color.asString(cf.HSLA);
-    else
-      colorString = color.asString(cf.RGBA);
-
-    console.assert(colorString);
-    return colorString || '';
-  }
-
-  _updateHelperLocations() {
-    const h = this._hsv[0];
-    const s = this._hsv[1];
-    const v = this._hsv[2];
-    const alpha = this._hsv[3];
-
-    // Where to show the little circle that displays your current selected color.
-    this._dragX = s * this.dragWidth;
-    this._dragY = this.dragHeight - (v * this.dragHeight);
-
-    const dragX = Math.max(
-        -this._colorDragElementHeight,
-        Math.min(this.dragWidth - this._colorDragElementHeight, this._dragX - this._colorDragElementHeight));
-    const dragY = Math.max(
-        -this._colorDragElementHeight,
-        Math.min(this.dragHeight - this._colorDragElementHeight, this._dragY - this._colorDragElementHeight));
-
-    this._colorDragElement.positionAt(dragX, dragY);
-
-    // Where to show the bar that displays your current selected hue.
-    const hueSlideX = (1 - h) * this._hueAlphaWidth - this.slideHelperWidth;
-    this._hueSlider.style.left = hueSlideX + 'px';
-    const alphaSlideX = alpha * this._hueAlphaWidth - this.slideHelperWidth;
-    this._alphaSlider.style.left = alphaSlideX + 'px';
-  }
-
-  _updateInput() {
-    const cf = Common.Color.Format;
-    if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX || this._colorFormat === cf.Nickname) {
-      this._hexContainer.hidden = false;
-      this._displayContainer.hidden = true;
-      if (this._colorFormat === cf.ShortHEX) {
-        this._hexValue.value = this._color().asString(this._color().detectHEXFormat());
-      } else {  // Don't use ShortHEX if original was not in that format.
-        this._hexValue.value = this._color().asString(this._color().hasAlpha() ? cf.HEXA : cf.HEX);
-      }
-    } else {
-      // RGBA, HSLA display.
-      this._hexContainer.hidden = true;
-      this._displayContainer.hidden = false;
-      const isRgb = this._colorFormat === cf.RGB;
-      this._textLabels.textContent = isRgb ? 'RGBA' : 'HSLA';
-      const colorValues = isRgb ? this._color().canonicalRGBA() : this._color().canonicalHSLA();
-      for (let i = 0; i < 3; ++i) {
-        this._textValues[i].value = colorValues[i];
-        if (!isRgb && (i === 1 || i === 2))
-          this._textValues[i].value += '%';
-      }
-      this._textValues[3].value = Math.round(colorValues[3] * 100) / 100;
-    }
-  }
-
-  _updateUI() {
-    const h = Common.Color.fromHSVA([this._hsv[0], 1, 1, 1]);
-    this._colorElement.style.backgroundColor = /** @type {string} */ (h.asString(Common.Color.Format.RGB));
-    if (this._contrastOverlay)
-      this._contrastOverlay.setDimensions(this.dragWidth, this.dragHeight);
-
-    this._swatch.setColor(this._color(), this.colorString());
-    this._colorDragElement.style.backgroundColor =
-        /** @type {string} */ (this._color().asString(Common.Color.Format.RGBA));
-    const noAlpha = Common.Color.fromHSVA(this._hsv.slice(0, 3).concat(1));
-    this._alphaElementBackground.style.backgroundImage =
-        String.sprintf('linear-gradient(to right, rgba(0,0,0,0), %s)', noAlpha.asString(Common.Color.Format.RGB));
-  }
-
-  _formatViewSwitch() {
-    const cf = Common.Color.Format;
-    let format = cf.RGB;
-    if (this._colorFormat === cf.RGB)
-      format = cf.HSL;
-    else if (this._colorFormat === cf.HSL)
-      format = (this._originalFormat === cf.ShortHEX || this._originalFormat === cf.ShortHEXA) ? cf.ShortHEX : cf.HEX;
-    this._innerSetColor(undefined, '', format, ColorPicker.Spectrum._ChangeSource.Other);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _inputChanged(event) {
-    /**
-     * @param {!Element} element
-     * @return {string}
-     */
-    function elementValue(element) {
-      return element.value;
-    }
-
-    const inputElement = /** @type {!Element} */ (event.currentTarget);
-    const newValue = UI.createReplacementString(inputElement.value, event);
-    if (newValue) {
-      inputElement.value = newValue;
-      inputElement.selectionStart = 0;
-      inputElement.selectionEnd = newValue.length;
-      event.consume(true);
-    }
-
-    const cf = Common.Color.Format;
-    let colorString;
-    if (this._colorFormat === cf.Nickname || this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX) {
-      colorString = this._hexValue.value;
-    } else {
-      const format = this._colorFormat === cf.RGB ? 'rgba' : 'hsla';
-      const values = this._textValues.map(elementValue).join(', ');
-      colorString = String.sprintf('%s(%s)', format, values);
-    }
-
-    const color = Common.Color.parse(colorString);
-    if (!color)
-      return;
-
-    let colorFormat = undefined;
-    if (this._colorFormat === cf.HEX || this._colorFormat === cf.ShortHEX)
-      colorFormat = color.detectHEXFormat();
-    this._innerSetColor(color.hsva(), colorString, colorFormat, ColorPicker.Spectrum._ChangeSource.Input);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._hueAlphaWidth = this._hueElement.offsetWidth;
-    this.slideHelperWidth = this._hueSlider.offsetWidth / 2;
-    this.dragWidth = this._colorElement.offsetWidth;
-    this.dragHeight = this._colorElement.offsetHeight;
-    this._colorDragElementHeight = this._colorDragElement.offsetHeight / 2;
-    this._innerSetColor(undefined, undefined, undefined, ColorPicker.Spectrum._ChangeSource.Model);
-    this._toggleColorPicker(true);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._toggleColorPicker(false);
-  }
-
-  /**
-   * @param {boolean=} enabled
-   * @param {!Common.Event=} event
-   */
-  _toggleColorPicker(enabled, event) {
-    if (enabled === undefined)
-      enabled = !this._colorPickerButton.toggled();
-    this._colorPickerButton.setToggled(enabled);
-    InspectorFrontendHost.setEyeDropperActive(enabled);
-    if (enabled) {
-      InspectorFrontendHost.events.addEventListener(
-          InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._colorPickedBound);
-    } else {
-      InspectorFrontendHost.events.removeEventListener(
-          InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._colorPickedBound);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _colorPicked(event) {
-    const rgbColor = /** @type {!{r: number, g: number, b: number, a: number}} */ (event.data);
-    const rgba = [rgbColor.r, rgbColor.g, rgbColor.b, (rgbColor.a / 2.55 | 0) / 100];
-    const color = Common.Color.fromRGBA(rgba);
-    this._innerSetColor(color.hsva(), '', undefined, ColorPicker.Spectrum._ChangeSource.Other);
-    InspectorFrontendHost.bringToFront();
-  }
-};
-
-ColorPicker.Spectrum._ChangeSource = {
-  Input: 'Input',
-  Model: 'Model',
-  Other: 'Other'
-};
-
-/** @enum {symbol} */
-ColorPicker.Spectrum.Events = {
-  ColorChanged: Symbol('ColorChanged'),
-  SizeChanged: Symbol('SizeChanged')
-};
-
-ColorPicker.Spectrum._colorChipSize = 24;
-ColorPicker.Spectrum._itemsPerPaletteRow = 8;
-
-/** @typedef {{ title: string, colors: !Array.<string>, mutable: boolean }} */
-ColorPicker.Spectrum.Palette;
-ColorPicker.Spectrum.GeneratedPaletteTitle = 'Page colors';
-
-ColorPicker.Spectrum.PaletteGenerator = class {
-  /**
-   * @param {function(!ColorPicker.Spectrum.Palette)} callback
-   */
-  constructor(callback) {
-    this._callback = callback;
-    /** @type {!Map.<string, number>} */
-    this._frequencyMap = new Map();
-    const stylesheetPromises = [];
-    for (const cssModel of SDK.targetManager.models(SDK.CSSModel)) {
-      for (const stylesheet of cssModel.allStyleSheets())
-        stylesheetPromises.push(this._processStylesheet(stylesheet));
-    }
-    Promise.all(stylesheetPromises).catchException(null).then(this._finish.bind(this));
-  }
-
-  /**
-   * @param {string} a
-   * @param {string} b
-   * @return {number}
-   */
-  _frequencyComparator(a, b) {
-    return this._frequencyMap.get(b) - this._frequencyMap.get(a);
-  }
-
-  _finish() {
-    /**
-     * @param {string} a
-     * @param {string} b
-     * @return {number}
-     */
-    function hueComparator(a, b) {
-      const hsva = paletteColors.get(a).hsva();
-      const hsvb = paletteColors.get(b).hsva();
-
-      // First trim the shades of gray
-      if (hsvb[1] < 0.12 && hsva[1] < 0.12)
-        return hsvb[2] * hsvb[3] - hsva[2] * hsva[3];
-      if (hsvb[1] < 0.12)
-        return -1;
-      if (hsva[1] < 0.12)
-        return 1;
-
-      // Equal hue -> sort by sat
-      if (hsvb[0] === hsva[0])
-        return hsvb[1] * hsvb[3] - hsva[1] * hsva[3];
-
-      return (hsvb[0] + 0.94) % 1 - (hsva[0] + 0.94) % 1;
-    }
-
-    let colors = this._frequencyMap.keysArray();
-    colors = colors.sort(this._frequencyComparator.bind(this));
-    /** @type {!Map.<string, !Common.Color>} */
-    const paletteColors = new Map();
-    const colorsPerRow = 24;
-    while (paletteColors.size < colorsPerRow && colors.length) {
-      const colorText = colors.shift();
-      const color = Common.Color.parse(colorText);
-      if (!color || color.nickname() === 'white' || color.nickname() === 'black')
-        continue;
-      paletteColors.set(colorText, color);
-    }
-
-    this._callback({
-      title: ColorPicker.Spectrum.GeneratedPaletteTitle,
-      colors: paletteColors.keysArray().sort(hueComparator),
-      mutable: false
-    });
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} stylesheet
-   * @return {!Promise}
-   */
-  async _processStylesheet(stylesheet) {
-    let text = await stylesheet.requestContent() || '';
-    text = text.toLowerCase();
-    const regexResult = text.match(/((?:rgb|hsl)a?\([^)]+\)|#[0-9a-f]{6}|#[0-9a-f]{3})/g) || [];
-    for (const c of regexResult) {
-      let frequency = this._frequencyMap.get(c) || 0;
-      this._frequencyMap.set(c, ++frequency);
-    }
-  }
-};
-
-ColorPicker.Spectrum.MaterialPaletteShades = {
-  '#F44336':
-      ['#FFEBEE', '#FFCDD2', '#EF9A9A', '#E57373', '#EF5350', '#F44336', '#E53935', '#D32F2F', '#C62828', '#B71C1C'],
-  '#E91E63':
-      ['#FCE4EC', '#F8BBD0', '#F48FB1', '#F06292', '#EC407A', '#E91E63', '#D81B60', '#C2185B', '#AD1457', '#880E4F'],
-  '#9C27B0':
-      ['#F3E5F5', '#E1BEE7', '#CE93D8', '#BA68C8', '#AB47BC', '#9C27B0', '#8E24AA', '#7B1FA2', '#6A1B9A', '#4A148C'],
-  '#673AB7':
-      ['#EDE7F6', '#D1C4E9', '#B39DDB', '#9575CD', '#7E57C2', '#673AB7', '#5E35B1', '#512DA8', '#4527A0', '#311B92'],
-  '#3F51B5':
-      ['#E8EAF6', '#C5CAE9', '#9FA8DA', '#7986CB', '#5C6BC0', '#3F51B5', '#3949AB', '#303F9F', '#283593', '#1A237E'],
-  '#2196F3':
-      ['#E3F2FD', '#BBDEFB', '#90CAF9', '#64B5F6', '#42A5F5', '#2196F3', '#1E88E5', '#1976D2', '#1565C0', '#0D47A1'],
-  '#03A9F4':
-      ['#E1F5FE', '#B3E5FC', '#81D4FA', '#4FC3F7', '#29B6F6', '#03A9F4', '#039BE5', '#0288D1', '#0277BD', '#01579B'],
-  '#00BCD4':
-      ['#E0F7FA', '#B2EBF2', '#80DEEA', '#4DD0E1', '#26C6DA', '#00BCD4', '#00ACC1', '#0097A7', '#00838F', '#006064'],
-  '#009688':
-      ['#E0F2F1', '#B2DFDB', '#80CBC4', '#4DB6AC', '#26A69A', '#009688', '#00897B', '#00796B', '#00695C', '#004D40'],
-  '#4CAF50':
-      ['#E8F5E9', '#C8E6C9', '#A5D6A7', '#81C784', '#66BB6A', '#4CAF50', '#43A047', '#388E3C', '#2E7D32', '#1B5E20'],
-  '#8BC34A':
-      ['#F1F8E9', '#DCEDC8', '#C5E1A5', '#AED581', '#9CCC65', '#8BC34A', '#7CB342', '#689F38', '#558B2F', '#33691E'],
-  '#CDDC39':
-      ['#F9FBE7', '#F0F4C3', '#E6EE9C', '#DCE775', '#D4E157', '#CDDC39', '#C0CA33', '#AFB42B', '#9E9D24', '#827717'],
-  '#FFEB3B':
-      ['#FFFDE7', '#FFF9C4', '#FFF59D', '#FFF176', '#FFEE58', '#FFEB3B', '#FDD835', '#FBC02D', '#F9A825', '#F57F17'],
-  '#FFC107':
-      ['#FFF8E1', '#FFECB3', '#FFE082', '#FFD54F', '#FFCA28', '#FFC107', '#FFB300', '#FFA000', '#FF8F00', '#FF6F00'],
-  '#FF9800':
-      ['#FFF3E0', '#FFE0B2', '#FFCC80', '#FFB74D', '#FFA726', '#FF9800', '#FB8C00', '#F57C00', '#EF6C00', '#E65100'],
-  '#FF5722':
-      ['#FBE9E7', '#FFCCBC', '#FFAB91', '#FF8A65', '#FF7043', '#FF5722', '#F4511E', '#E64A19', '#D84315', '#BF360C'],
-  '#795548':
-      ['#EFEBE9', '#D7CCC8', '#BCAAA4', '#A1887F', '#8D6E63', '#795548', '#6D4C41', '#5D4037', '#4E342E', '#3E2723'],
-  '#9E9E9E':
-      ['#FAFAFA', '#F5F5F5', '#EEEEEE', '#E0E0E0', '#BDBDBD', '#9E9E9E', '#757575', '#616161', '#424242', '#212121'],
-  '#607D8B':
-      ['#ECEFF1', '#CFD8DC', '#B0BEC5', '#90A4AE', '#78909C', '#607D8B', '#546E7A', '#455A64', '#37474F', '#263238']
-};
-
-ColorPicker.Spectrum.MaterialPalette = {
-  title: 'Material',
-  mutable: false,
-  matchUserFormat: true,
-  colors: Object.keys(ColorPicker.Spectrum.MaterialPaletteShades)
-};
-
-ColorPicker.Spectrum.Swatch = class {
-  /**
-   * @param {!Element} parentElement
-   */
-  constructor(parentElement) {
-    /** @type {?string} */
-    this._colorString;
-
-    const swatchElement = parentElement.createChild('span', 'swatch');
-    this._swatchInnerElement = swatchElement.createChild('span', 'swatch-inner');
-
-    this._swatchOverlayElement = swatchElement.createChild('span', 'swatch-overlay');
-    this._swatchOverlayElement.addEventListener('click', this._onCopyIconClick.bind(this));
-    this._swatchOverlayElement.addEventListener('mouseout', this._onCopyIconMouseout.bind(this));
-    this._swatchCopyIcon = UI.Icon.create('largeicon-copy', 'copy-color-icon');
-    this._swatchCopyIcon.title = Common.UIString('Copy color to clipboard');
-    this._swatchOverlayElement.appendChild(this._swatchCopyIcon);
-  }
-
-  /**
-   * @param {!Common.Color} color
-   * @param {string=} colorString
-   */
-  setColor(color, colorString) {
-    this._swatchInnerElement.style.backgroundColor =
-        /** @type {string} */ (color.asString(Common.Color.Format.RGBA));
-    // Show border if the swatch is white.
-    this._swatchInnerElement.classList.toggle('swatch-inner-white', color.hsla()[2] > 0.9);
-    this._colorString = colorString || null;
-    if (colorString)
-      this._swatchOverlayElement.hidden = false;
-    else
-      this._swatchOverlayElement.hidden = true;
-  }
-
-  _onCopyIconClick() {
-    this._swatchCopyIcon.setIconType('largeicon-checkmark');
-    InspectorFrontendHost.copyText(this._colorString);
-  }
-
-  _onCopyIconMouseout() {
-    this._swatchCopyIcon.setIconType('largeicon-copy');
-  }
-};
diff --git a/front_end/color_picker/module.json b/front_end/color_picker/module.json
deleted file mode 100644
index deba8dd..0000000
--- a/front_end/color_picker/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "dependencies": [
-        "ui",
-        "sdk"
-    ],
-    "scripts": [
-        "ContrastInfo.js",
-        "ContrastOverlay.js",
-        "ContrastDetails.js",
-        "Spectrum.js"
-    ],
-    "resources": [
-        "spectrum.css"
-    ]
-}
diff --git a/front_end/color_picker/spectrum.css b/front_end/color_picker/spectrum.css
deleted file mode 100644
index b07eb58..0000000
--- a/front_end/color_picker/spectrum.css
+++ /dev/null
@@ -1,627 +0,0 @@
-/* https://github.com/bgrins/spectrum */
-:host {
-    width: 232px;
-    height: 240px;
-    -webkit-user-select: none;
-    overflow: hidden;
-}
-
-:host-context(.palettes-enabled) {
-    height: 319px;
-}
-
-:selection {
-    background-color: blue;
-    color: white;
-}
-
-.spectrum-color {
-    position: relative;
-    width: 232px;
-    height: 124px;
-    border-radius: 2px 2px 0 0;
-    overflow: hidden;
-    flex: none;
-}
-
-.spectrum-tools {
-    position: relative;
-    height: 111px;
-    width: 100%;
-    flex: none;
-}
-
-.spectrum-display-value {
-    -webkit-user-select: text;
-    display: inline-block;
-    padding-left: 2px;
-}
-
-.spectrum-hue {
-    top: 16px;
-}
-
-.spectrum-alpha {
-    top: 35px;
-    background-image: url(Images/checker.png);
-    background-size: 12px 11px;
-}
-
-.spectrum-alpha-background {
-    height: 100%;
-    border-radius: 2px;
-}
-
-.spectrum-hue, .spectrum-alpha {
-    position: absolute;
-    left: 86px;
-    width: 130px;
-    height: 11px;
-    border-radius: 2px;
-}
-
-.spectrum-dragger,
-.spectrum-slider {
-    -webkit-user-select: none;
-}
-
-.spectrum-sat,
-.-theme-preserve {
-    background-image: linear-gradient(to right, white, rgba(204, 154, 129, 0));
-}
-
-.spectrum-val,
-.-theme-preserve {
-    background-image: linear-gradient(to top, black, rgba(204, 154, 129, 0));
-}
-
-.spectrum-hue {
-    background: linear-gradient(to left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
-}
-
-.spectrum-dragger {
-    border-radius: 12px;
-    height: 12px;
-    width: 12px;
-    border: 1px solid white;
-    cursor: pointer;
-    position: absolute;
-    top: 0;
-    left: 0;
-    background: black;
-    box-shadow: 0 0 2px 0px rgba(0, 0, 0, 0.24);
-}
-
-.spectrum-slider {
-    position: absolute;
-    top: -1px;
-    cursor: pointer;
-    width: 13px;
-    height: 13px;
-    border-radius: 13px;
-    background-color: rgb(248, 248, 248);
-    box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37);
-}
-
-.spectrum-contrast-details {
-    position: relative;
-    background-color: white;
-    width: 100%;
-    height: 111px;
-    top: 0;
-    font-size: 13px;
-    color: #333;
-    border-top: var(--divider-border);
-    line-height: initial;
-    overflow: hidden;
-    flex: none;
-}
-
-.spectrum-contrast-details {
-    height: 78px;
-    flex: none;
-}
-
-.spectrum-contrast-details.collapsed {
-    height: 36px;
-    flex: none;
-}
-
-.spectrum-contrast-details div.toolbar.expand {
-    position: absolute;
-    right: 6px;
-    top: 6px;
-    margin: 0;
-}
-
-.spectrum-contrast-details .toolbar-state-on [is=ui-icon] {
-    background-color: rgb(110, 110, 110);
-}
-
-.spectrum-contrast-details.visible {
-    display: initial;
-}
-
-.spectrum-contrast-details div.container {
-    margin: 10px;
-}
-
-.spectrum-contrast-details.collapsed .expanded-details {
-    display: none;
-}
-
-.spectrum-contrast-details .expanded-details {
-    display: flex;
-    margin: 12px 12px 0 4px;
-}
-
-.contrast-pass-fail {
-    margin-left: 0.5em;
-}
-
-.spectrum-contrast-details .contrast-choose-bg-color,
-.spectrum-contrast-details .contrast-thresholds {
-    width: 145px;
-}
-
-.contrast-choose-bg-color {
-    margin: 8px 0 0 5px;
-    font-style: italic;
-}
-
-.contrast-link-label {
-    cursor: pointer;
-}
-
-.contrast-link-label:hover {
-    text-decoration: underline;
-}
-
-.spectrum-contrast-details .background-color {
-    position: absolute;
-    flex: none;
-    right: 12px;
-}
-
-.spectrum-contrast-details .spectrum-eye-dropper {
-    top: 2px;
-    right: 34px;
-    position: absolute;
-    left: auto;
-}
-
-.contrast-threshold-value {
-    font-weight: bold;
-}
-
-.contrast-link {
-    margin-left: 0.5em;
-}
-
-.contrast-details-value {
-    color: #333;
-    margin: 1px 5px;
-    user-select: text;
-}
-
-.contrast-details-value [is=ui-icon] {
-    display: none;
-    margin-left: 5px;
-    background-color: #333;
-}
-
-[is=ui-icon].smallicon-no {
-    background-color: red;
-}
-
-.contrast-pass-fail span[is=ui-icon] {
-    margin-left: 5px;
-}
-
-[is=ui-icon].smallicon-checkmark-square,
-[is=ui-icon].smallicon-checkmark-behind {
-    background-color: #00b06f;
-}
-
-.spectrum-contrast-details .contrast-details-value.contrast-unknown {
-    background-color: white;
-    color: #333;
-    width: 3em;
-    text-align: center;
-}
-
-.contrast-details-value .smallicon-checkmark-behind {
-    margin-left: -6px;
-}
-
-.spectrum-contrast-details.contrast-fail .contrast-details-value .smallicon-no,
-.contrast-details-value.contrast-aa .smallicon-checkmark-square,
-.contrast-details-value.contrast-aaa .smallicon-checkmark-behind {
-    display: inline-block;
-}
-
-
-.contrast-details-value .smallicon-no,
-.contrast-details-value .smallicon-checkmark-square,
-.contrast-details-value .smallicon-checkmark-behind {
-    cursor: pointer;
-}
-
-.swatch {
-    width: 32px;
-    height: 32px;
-    margin: 0;
-    position: absolute;
-    top: 15px;
-    left: 44px;
-    background-image: url(Images/checker.png);
-    border-radius: 16px;
-}
-
-.swatch-inner,
-.swatch-overlay {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    display: inline-block;
-    border-radius: 16px;
-}
-
-.swatch-inner-white {
-    border: 1px solid #ddd;
-}
-
-.swatch-overlay {
-    cursor: pointer;
-    opacity: 0;
-    padding: 4px;
-}
-
-.swatch-overlay:hover {
-    background-color: rgba(0, 0, 0, .3);
-    opacity: 1;
-}
-
-.swatch-overlay:active {
-    background-color: rgba(0, 0, 0, .5);
-}
-
-.copy-color-icon {
-    background-color: white;
-}
-
-.spectrum-text {
-    position: absolute;
-    top: 60px;
-    left: 16px;
-}
-
-.spectrum-text-value {
-    display: inline-block;
-    width: 40px;
-    overflow: hidden;
-    text-align: center;
-    margin-right: 6px;
-    line-height: 20px;
-    padding: 0;
-    color: #333;
-    white-space: nowrap;
-    box-shadow: var(--focus-ring-inactive-shadow);
-}
-
-.spectrum-text-label {
-    letter-spacing: 39.5px;
-    margin-top: 8px;
-    display: block;
-    color: #969696;
-    margin-left: 16px;
-    width: 174px;
-}
-
-.spectrum-text-hex > .spectrum-text-value {
-    width: 178px;
-}
-
-.spectrum-text-hex > .spectrum-text-label {
-    letter-spacing: normal;
-    margin-left: 0px;
-    text-align: center;
-}
-
-.spectrum-palette-value {
-    background-color: rgb(65, 75, 217);
-    border-radius: 2px;
-    margin-top: 12px;
-    margin-left: 12px;
-    width: 12px;
-    height: 12px;
-    display: inline-block;
-}
-
-.spectrum-switcher {
-    border-radius: 2px;
-    height: 20px;
-    width: 20px;
-    padding: 2px;
-}
-
-:host-context(.-theme-with-dark-background) .spectrum-switcher {
-    -webkit-filter: invert(60%);
-}
-
-.spectrum-display-switcher {
-    top: 72px;
-    position: absolute;
-    right: 10px;
-}
-
-.spectrum-switcher:hover {
-    background-color: #EEEEEE;
-}
-
-.spectrum-eye-dropper {
-    width: 32px;
-    height: 24px;
-    position: relative;
-    left: 8px;
-    top: 17px;
-    cursor: pointer;
-}
-
-.spectrum-palette-container {
-    border-top: var(--divider-border);
-    position: relative;
-    width: 100%;
-    padding: 6px 24px 6px 6px;
-    display: flex;
-    flex-wrap: wrap;
-}
-
-.spectrum-palette {
-    display: flex;
-    flex-wrap: wrap;
-    width: 198px;
-}
-
-.spectrum-palette-color {
-    width: 12px;
-    height: 12px;
-    flex: 0 0 12px;
-    border-radius: 2px;
-    margin: 6px;
-    cursor: pointer;
-    position: relative;
-    border: 1px solid rgba(0, 0, 0, 0.1);
-    background-position: -1px !important;
-    z-index: 14;
-}
-
-.spectrum-palette-color:hover:not(.spectrum-shades-shown) > .spectrum-palette-color-shadow {
-    opacity: 0.2;
-}
-
-.spectrum-palette-color:hover:not(.spectrum-shades-shown) > .spectrum-palette-color-shadow:first-child {
-    opacity: 0.6;
-    top: -3px;
-    left: 1px;
-}
-
-.spectrum-palette-color-shadow {
-    position: absolute;
-    opacity: 0;
-    margin: 0;
-    top: -5px;
-    left: 3px;
-}
-
-.palette-color-shades {
-    position: absolute;
-    background-color: white;
-    height: 228px;
-    width: 28px;
-    box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.4);
-    z-index: 14;
-    border-radius: 2px;
-    transform-origin: 0px 228px;
-    margin-top: 16px;
-    margin-left: -8px;
-}
-
-.spectrum-palette > .spectrum-palette-color.spectrum-shades-shown {
-    z-index: 15;
-}
-
-.palette-color-shades > .spectrum-palette-color {
-    margin: 8px 0 0 0;
-    margin-left: 8px;
-    width: 12px;
-}
-
-.spectrum-palette > .spectrum-palette-color {
-    transition: transform 100ms cubic-bezier(0, 0, 0.2, 1);
-    will-change: transform;
-    z-index: 13;
-}
-
-.spectrum-palette > .spectrum-palette-color.empty-color {
-    border-color: transparent;
-}
-
-.spectrum-palette > .spectrum-palette-color:not(.empty-color):not(.has-material-shades):hover,
-.palette-color-shades > .spectrum-palette-color:not(.empty-color):hover {
-    transform: scale(1.15);
-}
-
-.add-color-toolbar {
-    margin-left: -3px;
-    margin-top: -1px;
-}
-
-.spectrum-palette-switcher {
-    right: 10px;
-    top: 0;
-    margin-top: 9px;
-    position: absolute;
-}
-
-.palette-panel {
-    width: 100%;
-    height: 100%;
-    position: absolute;
-    top: 100%;
-    display: flex;
-    flex-direction: column;
-    background-color: white;
-    z-index: 14;
-    transition: transform 200ms cubic-bezier(0, 0, 0.2, 1), visibility 0s 200ms;
-    border-top: var(--divider-border);
-    visibility: hidden;
-}
-
-.palette-panel-showing > .palette-panel {
-    transform: translateY(calc(-100% + 117px));
-    transition-delay: 0s;
-    visibility: visible;
-}
-
-.palette-panel > div.toolbar {
-    position: absolute;
-    right: 6px;
-    top: 6px;
-}
-
-.palette-panel > div:not(.toolbar) {
-    flex: 0 0 38px;
-    border-bottom: var(--divider-border);
-    padding: 12px;
-    line-height: 14px;
-    color: #333;
-}
-
-.palette-panel > div.palette-title {
-    font-size: 14px;
-    line-height: 16px;
-    color: #333;
-    flex-basis: 40px;
-}
-
-div.palette-preview {
-    display: flex;
-    cursor: pointer;
-}
-
-.palette-preview-title {
-    flex: 0 0 84px;
-}
-
-.palette-preview > .spectrum-palette-color {
-    margin-top: 1px;
-}
-
-.palette-preview:hover {
-    background-color: #eee;
-}
-
-.spectrum-overlay {
-    z-index: 13;
-    visibility: hidden;
-    background-color: hsla(0, 0%, 0%, 0.5);
-    opacity: 0;
-    transition: opacity 100ms cubic-bezier(0, 0, 0.2, 1), visibility 0s 100ms;
-}
-
-.palette-panel-showing > .spectrum-overlay {
-    transition-delay: 0s;
-    visibility: visible;
-    opacity: 1;
-}
-
-.spectrum-contrast-container {
-    width: 100%;
-    height: 100%;
-}
-
-.spectrum-contrast-line {
-    fill: none;
-    stroke: white;
-    opacity: 0.7;
-    stroke-width: 1.5px;
-}
-
-.delete-color-toolbar {
-    position: absolute;
-    right: 0;
-    top: 0;
-    background-color: #EFEFEF;
-    visibility: hidden;
-    z-index: 3;
-    width: 36px;
-    display: flex;
-    align-items: center;
-    padding-left: 4px;
-    bottom: 2px;
-    border-bottom-right-radius: 2px;
-}
-
-@keyframes showDeleteToolbar {
-    from {
-        opacity: 0;
-    }
-    to {
-        opacity: 1;
-    }
-}
-
-.delete-color-toolbar.dragging {
-    visibility: visible;
-    animation: showDeleteToolbar 100ms 150ms cubic-bezier(0, 0, 0.2, 1) backwards;
-}
-
-.delete-color-toolbar-active {
-    background-color: #ddd;
-    color: white;
-}
-
-.swatch.contrast {
-    width: 30px;
-    height: 30px;
-    position: absolute;
-    top: 0px;
-    right: 0;
-    left: auto;
-    background-image: url(Images/checker.png);
-    border-radius: 15px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.swatch.contrast .swatch-overlay {
-    padding: 0;
-}
-
-.background-color .text-preview {
-    color: black;
-    font-size: 16px;
-    position: relative;
-    padding-bottom: 2px;
-}
-
-.swatch.contrast [is=ui-icon] {
-    margin: -2px;
-}
-
-button.background-color-picker {
-    border: 0;
-    padding:  0;
-    background: none;
-    position: relative;
-    margin: 0;
-}
-
-button.background-color-picker.active [is=ui-icon].largeicon-eyedropper.icon-mask {
-    background-color: hsl(218, 81%, 59%);
-}
-
-button.background-color-picker:hover [is=ui-icon].largeicon-eyedropper.icon-mask {
-    background-color: #333;
diff --git a/front_end/common/CharacterIdMap.js b/front_end/common/CharacterIdMap.js
deleted file mode 100644
index 627df76..0000000
--- a/front_end/common/CharacterIdMap.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @template T
- * @unrestricted
- */
-Common.CharacterIdMap = class {
-  constructor() {
-    /** @type {!Map<T, string>} */
-    this._elementToCharacter = new Map();
-    /** @type {!Map<string, T>} */
-    this._characterToElement = new Map();
-    this._charCode = 33;
-  }
-
-  /**
-   * @param {T} object
-   * @return {string}
-   */
-  toChar(object) {
-    let character = this._elementToCharacter.get(object);
-    if (!character) {
-      if (this._charCode >= 0xFFFF)
-        throw new Error('CharacterIdMap ran out of capacity!');
-      character = String.fromCharCode(this._charCode++);
-      this._elementToCharacter.set(object, character);
-      this._characterToElement.set(character, object);
-    }
-    return character;
-  }
-
-  /**
-   * @param {string} character
-   * @return {?T}
-   */
-  fromChar(character) {
-    const object = this._characterToElement.get(character);
-    if (object === undefined)
-      return null;
-    return object;
-  }
-};
diff --git a/front_end/common/Color.js b/front_end/common/Color.js
deleted file mode 100644
index 1fa43f2..0000000
--- a/front_end/common/Color.js
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Common.Color = class {
-  /**
-   * @param {!Array.<number>} rgba
-   * @param {!Common.Color.Format} format
-   * @param {string=} originalText
-   */
-  constructor(rgba, format, originalText) {
-    this._rgba = rgba;
-    this._originalText = originalText || null;
-    this._originalTextIsValid = !!this._originalText;
-    this._format = format;
-    if (typeof this._rgba[3] === 'undefined')
-      this._rgba[3] = 1;
-
-    for (let i = 0; i < 4; ++i) {
-      if (this._rgba[i] < 0) {
-        this._rgba[i] = 0;
-        this._originalTextIsValid = false;
-      }
-      if (this._rgba[i] > 1) {
-        this._rgba[i] = 1;
-        this._originalTextIsValid = false;
-      }
-    }
-  }
-
-  /**
-   * @param {string} text
-   * @return {?Common.Color}
-   */
-  static parse(text) {
-    // Simple - #hex, nickname
-    const value = text.toLowerCase().replace(/\s+/g, '');
-    const simple = /^(?:#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|(\w+))$/i;
-    let match = value.match(simple);
-    if (match) {
-      if (match[1]) {  // hex
-        let hex = match[1].toLowerCase();
-        let format;
-        if (hex.length === 3) {
-          format = Common.Color.Format.ShortHEX;
-          hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
-        } else if (hex.length === 4) {
-          format = Common.Color.Format.ShortHEXA;
-          hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2) +
-              hex.charAt(3) + hex.charAt(3);
-        } else if (hex.length === 6) {
-          format = Common.Color.Format.HEX;
-        } else {
-          format = Common.Color.Format.HEXA;
-        }
-        const r = parseInt(hex.substring(0, 2), 16);
-        const g = parseInt(hex.substring(2, 4), 16);
-        const b = parseInt(hex.substring(4, 6), 16);
-        let a = 1;
-        if (hex.length === 8)
-          a = parseInt(hex.substring(6, 8), 16) / 255;
-        return new Common.Color([r / 255, g / 255, b / 255, a], format, text);
-      }
-
-      if (match[2]) {  // nickname
-        const nickname = match[2].toLowerCase();
-        if (nickname in Common.Color.Nicknames) {
-          const rgba = Common.Color.Nicknames[nickname];
-          const color = Common.Color.fromRGBA(rgba);
-          color._format = Common.Color.Format.Nickname;
-          color._originalText = text;
-          return color;
-        }
-        return null;
-      }
-
-      return null;
-    }
-
-    // rgb/rgba(), hsl/hsla()
-    match = text.toLowerCase().match(/^\s*(?:(rgba?)|(hsla?))\((.*)\)\s*$/);
-
-    if (match) {
-      const components = match[3].trim();
-      let values = components.split(/\s*,\s*/);
-      if (values.length === 1) {
-        values = components.split(/\s+/);
-        if (values[3] === '/') {
-          values.splice(3, 1);
-          if (values.length !== 4)
-            return null;
-        } else if ((values.length > 2 && values[2].indexOf('/') !== -1) || (values.length > 3 && values[3].indexOf('/') !== -1)) {
-          const alpha = values.slice(2, 4).join('');
-          values = values.slice(0, 2).concat(alpha.split(/\//)).concat(values.slice(4));
-        } else if (values.length >= 4) {
-          return null;
-        }
-      }
-      if (values.length !== 3 && values.length !== 4 || values.indexOf('') > -1)
-        return null;
-      const hasAlpha = (values[3] !== undefined);
-
-      if (match[1]) {  // rgb/rgba
-        const rgba = [
-          Common.Color._parseRgbNumeric(values[0]), Common.Color._parseRgbNumeric(values[1]),
-          Common.Color._parseRgbNumeric(values[2]), hasAlpha ? Common.Color._parseAlphaNumeric(values[3]) : 1
-        ];
-        if (rgba.indexOf(null) > -1)
-          return null;
-        return new Common.Color(rgba, hasAlpha ? Common.Color.Format.RGBA : Common.Color.Format.RGB, text);
-      }
-
-      if (match[2]) {  // hsl/hsla
-        const hsla = [
-          Common.Color._parseHueNumeric(values[0]), Common.Color._parseSatLightNumeric(values[1]),
-          Common.Color._parseSatLightNumeric(values[2]), hasAlpha ? Common.Color._parseAlphaNumeric(values[3]) : 1
-        ];
-        if (hsla.indexOf(null) > -1)
-          return null;
-        const rgba = [];
-        Common.Color.hsl2rgb(hsla, rgba);
-        return new Common.Color(rgba, hasAlpha ? Common.Color.Format.HSLA : Common.Color.Format.HSL, text);
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * @param {!Array.<number>} rgba
-   * @return {!Common.Color}
-   */
-  static fromRGBA(rgba) {
-    return new Common.Color([rgba[0] / 255, rgba[1] / 255, rgba[2] / 255, rgba[3]], Common.Color.Format.RGBA);
-  }
-
-  /**
-   * @param {!Array.<number>} hsva
-   * @return {!Common.Color}
-   */
-  static fromHSVA(hsva) {
-    const rgba = [];
-    Common.Color.hsva2rgba(hsva, rgba);
-    return new Common.Color(rgba, Common.Color.Format.HSLA);
-  }
-
-  /**
-   * @param {string} value
-   * return {number}
-   */
-  static _parsePercentOrNumber(value) {
-    if (isNaN(value.replace('%', '')))
-      return null;
-    const parsed = parseFloat(value);
-
-    if (value.indexOf('%') !== -1) {
-      if (value.indexOf('%') !== value.length - 1)
-        return null;
-      return parsed / 100;
-    }
-    return parsed;
-  }
-
-  /**
-   * @param {string} value
-   * return {number}
-   */
-  static _parseRgbNumeric(value) {
-    const parsed = Common.Color._parsePercentOrNumber(value);
-    if (parsed === null)
-      return null;
-
-    if (value.indexOf('%') !== -1)
-      return parsed;
-    return parsed / 255;
-  }
-
-  /**
-   * @param {string} value
-   * return {number}
-   */
-  static _parseHueNumeric(value) {
-    const angle = value.replace(/(deg|g?rad|turn)$/, '');
-    if (isNaN(angle) || value.match(/\s+(deg|g?rad|turn)/))
-      return null;
-    const number = parseFloat(angle);
-
-    if (value.indexOf('turn') !== -1)
-      return number % 1;
-    else if (value.indexOf('grad') !== -1)
-      return (number / 400) % 1;
-    else if (value.indexOf('rad') !== -1)
-      return (number / (2 * Math.PI)) % 1;
-    return (number / 360) % 1;
-  }
-
-  /**
-   * @param {string} value
-   * return {number}
-   */
-  static _parseSatLightNumeric(value) {
-    if (value.indexOf('%') !== value.length - 1 || isNaN(value.replace('%', '')))
-      return null;
-    const parsed = parseFloat(value);
-    return Math.min(1, parsed / 100);
-  }
-
-  /**
-   * @param {string} value
-   * return {number}
-   */
-  static _parseAlphaNumeric(value) {
-    return Common.Color._parsePercentOrNumber(value);
-  }
-
-  /**
-   * @param {!Array.<number>} hsva
-   * @param {!Array.<number>} out_hsla
-   */
-  static _hsva2hsla(hsva, out_hsla) {
-    const h = hsva[0];
-    let s = hsva[1];
-    const v = hsva[2];
-
-    const t = (2 - s) * v;
-    if (v === 0 || s === 0)
-      s = 0;
-    else
-      s *= v / (t < 1 ? t : 2 - t);
-
-    out_hsla[0] = h;
-    out_hsla[1] = s;
-    out_hsla[2] = t / 2;
-    out_hsla[3] = hsva[3];
-  }
-
-  /**
-   * @param {!Array.<number>} hsl
-   * @param {!Array.<number>} out_rgb
-   */
-  static hsl2rgb(hsl, out_rgb) {
-    const h = hsl[0];
-    let s = hsl[1];
-    const l = hsl[2];
-
-    function hue2rgb(p, q, h) {
-      if (h < 0)
-        h += 1;
-      else if (h > 1)
-        h -= 1;
-
-      if ((h * 6) < 1)
-        return p + (q - p) * h * 6;
-      else if ((h * 2) < 1)
-        return q;
-      else if ((h * 3) < 2)
-        return p + (q - p) * ((2 / 3) - h) * 6;
-      else
-        return p;
-    }
-
-    if (s < 0)
-      s = 0;
-
-    let q;
-    if (l <= 0.5)
-      q = l * (1 + s);
-    else
-      q = l + s - (l * s);
-
-    const p = 2 * l - q;
-
-    const tr = h + (1 / 3);
-    const tg = h;
-    const tb = h - (1 / 3);
-
-    out_rgb[0] = hue2rgb(p, q, tr);
-    out_rgb[1] = hue2rgb(p, q, tg);
-    out_rgb[2] = hue2rgb(p, q, tb);
-    out_rgb[3] = hsl[3];
-  }
-
-  /**
-   * @param {!Array<number>} hsva
-   * @param {!Array<number>} out_rgba
-   */
-  static hsva2rgba(hsva, out_rgba) {
-    Common.Color._hsva2hsla(hsva, Common.Color.hsva2rgba._tmpHSLA);
-    Common.Color.hsl2rgb(Common.Color.hsva2rgba._tmpHSLA, out_rgba);
-
-    for (let i = 0; i < Common.Color.hsva2rgba._tmpHSLA.length; i++)
-      Common.Color.hsva2rgba._tmpHSLA[i] = 0;
-  }
-
-  /**
-   * Calculate the luminance of this color using the WCAG algorithm.
-   * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
-   * @param {!Array<number>} rgba
-   * @return {number}
-   */
-  static luminance(rgba) {
-    const rSRGB = rgba[0];
-    const gSRGB = rgba[1];
-    const bSRGB = rgba[2];
-
-    const r = rSRGB <= 0.03928 ? rSRGB / 12.92 : Math.pow(((rSRGB + 0.055) / 1.055), 2.4);
-    const g = gSRGB <= 0.03928 ? gSRGB / 12.92 : Math.pow(((gSRGB + 0.055) / 1.055), 2.4);
-    const b = bSRGB <= 0.03928 ? bSRGB / 12.92 : Math.pow(((bSRGB + 0.055) / 1.055), 2.4);
-
-    return 0.2126 * r + 0.7152 * g + 0.0722 * b;
-  }
-
-  /**
-   * Combine the two given color according to alpha blending.
-   * @param {!Array<number>} fgRGBA
-   * @param {!Array<number>} bgRGBA
-   * @param {!Array<number>} out_blended
-   */
-  static blendColors(fgRGBA, bgRGBA, out_blended) {
-    const alpha = fgRGBA[3];
-
-    out_blended[0] = ((1 - alpha) * bgRGBA[0]) + (alpha * fgRGBA[0]);
-    out_blended[1] = ((1 - alpha) * bgRGBA[1]) + (alpha * fgRGBA[1]);
-    out_blended[2] = ((1 - alpha) * bgRGBA[2]) + (alpha * fgRGBA[2]);
-    out_blended[3] = alpha + (bgRGBA[3] * (1 - alpha));
-  }
-
-  /**
-   * Calculate the contrast ratio between a foreground and a background color.
-   * Returns the ratio to 1, for example for two two colors with a contrast ratio of 21:1, this function will return 21.
-   * See http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
-   * @param {!Array<number>} fgRGBA
-   * @param {!Array<number>} bgRGBA
-   * @return {number}
-   */
-  static calculateContrastRatio(fgRGBA, bgRGBA) {
-    Common.Color.blendColors(fgRGBA, bgRGBA, Common.Color.calculateContrastRatio._blendedFg);
-
-    const fgLuminance = Common.Color.luminance(Common.Color.calculateContrastRatio._blendedFg);
-    const bgLuminance = Common.Color.luminance(bgRGBA);
-    const contrastRatio = (Math.max(fgLuminance, bgLuminance) + 0.05) / (Math.min(fgLuminance, bgLuminance) + 0.05);
-
-    for (let i = 0; i < Common.Color.calculateContrastRatio._blendedFg.length; i++)
-      Common.Color.calculateContrastRatio._blendedFg[i] = 0;
-
-    return contrastRatio;
-  }
-
-  /**
-   * Compute a desired luminance given a given luminance and a desired contrast
-   * ratio.
-   * @param {number} luminance The given luminance.
-   * @param {number} contrast The desired contrast ratio.
-   * @param {boolean} lighter Whether the desired luminance is lighter or darker
-   * than the given luminance. If no luminance can be found which meets this
-   * requirement, a luminance which meets the inverse requirement will be
-   * returned.
-   * @return {number} The desired luminance.
-   */
-  static desiredLuminance(luminance, contrast, lighter) {
-    function computeLuminance() {
-      if (lighter)
-        return (luminance + 0.05) * contrast - 0.05;
-      else
-        return (luminance + 0.05) / contrast - 0.05;
-    }
-    let desiredLuminance = computeLuminance();
-    if (desiredLuminance < 0 || desiredLuminance > 1) {
-      lighter = !lighter;
-      desiredLuminance = computeLuminance();
-    }
-    return desiredLuminance;
-  }
-
-  /**
-   * @param {!Common.Color} color
-   * @return {!Common.Color.Format}
-   */
-  static detectColorFormat(color) {
-    const cf = Common.Color.Format;
-    let format;
-    const formatSetting = Common.moduleSetting('colorFormat').get();
-    if (formatSetting === cf.Original)
-      format = cf.Original;
-    else if (formatSetting === cf.RGB)
-      format = (color.hasAlpha() ? cf.RGBA : cf.RGB);
-    else if (formatSetting === cf.HSL)
-      format = (color.hasAlpha() ? cf.HSLA : cf.HSL);
-    else if (formatSetting === cf.HEX)
-      format = color.detectHEXFormat();
-    else
-      format = cf.RGBA;
-
-    return format;
-  }
-
-  /**
-   * @return {!Common.Color.Format}
-   */
-  format() {
-    return this._format;
-  }
-
-  /**
-   * @return {!Array.<number>} HSLA with components within [0..1]
-   */
-  hsla() {
-    if (this._hsla)
-      return this._hsla;
-    const r = this._rgba[0];
-    const g = this._rgba[1];
-    const b = this._rgba[2];
-    const max = Math.max(r, g, b);
-    const min = Math.min(r, g, b);
-    const diff = max - min;
-    const add = max + min;
-
-    let h;
-    if (min === max)
-      h = 0;
-    else if (r === max)
-      h = ((1 / 6 * (g - b) / diff) + 1) % 1;
-    else if (g === max)
-      h = (1 / 6 * (b - r) / diff) + 1 / 3;
-    else
-      h = (1 / 6 * (r - g) / diff) + 2 / 3;
-
-    const l = 0.5 * add;
-
-    let s;
-    if (l === 0)
-      s = 0;
-    else if (l === 1)
-      s = 0;
-    else if (l <= 0.5)
-      s = diff / add;
-    else
-      s = diff / (2 - add);
-
-    this._hsla = [h, s, l, this._rgba[3]];
-    return this._hsla;
-  }
-
-  /**
-   * @return {!Array.<number>}
-   */
-  canonicalHSLA() {
-    const hsla = this.hsla();
-    return [Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100), hsla[3]];
-  }
-
-  /**
-   * @return {!Array.<number>} HSVA with components within [0..1]
-   */
-  hsva() {
-    const hsla = this.hsla();
-    const h = hsla[0];
-    let s = hsla[1];
-    const l = hsla[2];
-
-    s *= l < 0.5 ? l : 1 - l;
-    return [h, s !== 0 ? 2 * s / (l + s) : 0, (l + s), hsla[3]];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasAlpha() {
-    return this._rgba[3] !== 1;
-  }
-
-  /**
-   * @return {!Common.Color.Format}
-   */
-  detectHEXFormat() {
-    let canBeShort = true;
-    for (let i = 0; i < 4; ++i) {
-      const c = Math.round(this._rgba[i] * 255);
-      if (c % 17) {
-        canBeShort = false;
-        break;
-      }
-    }
-
-    const hasAlpha = this.hasAlpha();
-    const cf = Common.Color.Format;
-    if (canBeShort)
-      return hasAlpha ? cf.ShortHEXA : cf.ShortHEX;
-    return hasAlpha ? cf.HEXA : cf.HEX;
-  }
-
-  /**
-   * @return {?string}
-   */
-  asString(format) {
-    if (format === this._format && this._originalTextIsValid)
-      return this._originalText;
-
-    if (!format)
-      format = this._format;
-
-    /**
-     * @param {number} value
-     * @return {number}
-     */
-    function toRgbValue(value) {
-      return Math.round(value * 255);
-    }
-
-    /**
-     * @param {number} value
-     * @return {string}
-     */
-    function toHexValue(value) {
-      const hex = Math.round(value * 255).toString(16);
-      return hex.length === 1 ? '0' + hex : hex;
-    }
-
-    /**
-     * @param {number} value
-     * @return {string}
-     */
-    function toShortHexValue(value) {
-      return (Math.round(value * 255) / 17).toString(16);
-    }
-
-    switch (format) {
-      case Common.Color.Format.Original:
-        return this._originalText;
-      case Common.Color.Format.RGB:
-        if (this.hasAlpha())
-          return null;
-        return String.sprintf(
-            'rgb(%d, %d, %d)', toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]));
-      case Common.Color.Format.RGBA:
-        return String.sprintf(
-            'rgba(%d, %d, %d, %f)', toRgbValue(this._rgba[0]), toRgbValue(this._rgba[1]), toRgbValue(this._rgba[2]),
-            this._rgba[3]);
-      case Common.Color.Format.HSL:
-        if (this.hasAlpha())
-          return null;
-        const hsl = this.hsla();
-        return String.sprintf(
-            'hsl(%d, %d%, %d%)', Math.round(hsl[0] * 360), Math.round(hsl[1] * 100), Math.round(hsl[2] * 100));
-      case Common.Color.Format.HSLA:
-        const hsla = this.hsla();
-        return String.sprintf(
-            'hsla(%d, %d%, %d%, %f)', Math.round(hsla[0] * 360), Math.round(hsla[1] * 100), Math.round(hsla[2] * 100),
-            hsla[3]);
-      case Common.Color.Format.HEXA:
-        return String
-            .sprintf(
-                '#%s%s%s%s', toHexValue(this._rgba[0]), toHexValue(this._rgba[1]), toHexValue(this._rgba[2]),
-                toHexValue(this._rgba[3]))
-            .toLowerCase();
-      case Common.Color.Format.HEX:
-        if (this.hasAlpha())
-          return null;
-        return String
-            .sprintf('#%s%s%s', toHexValue(this._rgba[0]), toHexValue(this._rgba[1]), toHexValue(this._rgba[2]))
-            .toLowerCase();
-      case Common.Color.Format.ShortHEXA:
-        const hexFormat = this.detectHEXFormat();
-        if (hexFormat !== Common.Color.Format.ShortHEXA && hexFormat !== Common.Color.Format.ShortHEX)
-          return null;
-        return String
-            .sprintf(
-                '#%s%s%s%s', toShortHexValue(this._rgba[0]), toShortHexValue(this._rgba[1]),
-                toShortHexValue(this._rgba[2]), toShortHexValue(this._rgba[3]))
-            .toLowerCase();
-      case Common.Color.Format.ShortHEX:
-        if (this.hasAlpha())
-          return null;
-        if (this.detectHEXFormat() !== Common.Color.Format.ShortHEX)
-          return null;
-        return String
-            .sprintf(
-                '#%s%s%s', toShortHexValue(this._rgba[0]), toShortHexValue(this._rgba[1]),
-                toShortHexValue(this._rgba[2]))
-            .toLowerCase();
-      case Common.Color.Format.Nickname:
-        return this.nickname();
-    }
-
-    return this._originalText;
-  }
-
-  /**
-   * @return {!Array<number>}
-   */
-  rgba() {
-    return this._rgba.slice();
-  }
-
-  /**
-   * @return {!Array.<number>}
-   */
-  canonicalRGBA() {
-    const rgba = new Array(4);
-    for (let i = 0; i < 3; ++i)
-      rgba[i] = Math.round(this._rgba[i] * 255);
-    rgba[3] = this._rgba[3];
-    return rgba;
-  }
-
-  /**
-   * @return {?string} nickname
-   */
-  nickname() {
-    if (!Common.Color._rgbaToNickname) {
-      Common.Color._rgbaToNickname = {};
-      for (const nickname in Common.Color.Nicknames) {
-        let rgba = Common.Color.Nicknames[nickname];
-        if (rgba.length !== 4)
-          rgba = rgba.concat(1);
-        Common.Color._rgbaToNickname[rgba] = nickname;
-      }
-    }
-
-    return Common.Color._rgbaToNickname[this.canonicalRGBA()] || null;
-  }
-
-  /**
-   * @return {!{r: number, g: number, b: number, a: (number|undefined)}}
-   */
-  toProtocolRGBA() {
-    const rgba = this.canonicalRGBA();
-    const result = {r: rgba[0], g: rgba[1], b: rgba[2]};
-    if (rgba[3] !== 1)
-      result.a = rgba[3];
-    return result;
-  }
-
-  /**
-   * @return {!Common.Color}
-   */
-  invert() {
-    const rgba = [];
-    rgba[0] = 1 - this._rgba[0];
-    rgba[1] = 1 - this._rgba[1];
-    rgba[2] = 1 - this._rgba[2];
-    rgba[3] = this._rgba[3];
-    return new Common.Color(rgba, Common.Color.Format.RGBA);
-  }
-
-  /**
-   * @param {number} alpha
-   * @return {!Common.Color}
-   */
-  setAlpha(alpha) {
-    const rgba = this._rgba.slice();
-    rgba[3] = alpha;
-    return new Common.Color(rgba, Common.Color.Format.RGBA);
-  }
-
-  /**
-   * @param {!Common.Color} fgColor
-   * @return {!Common.Color}
-   */
-  blendWith(fgColor) {
-    const rgba = [];
-    Common.Color.blendColors(fgColor._rgba, this._rgba, rgba);
-    return new Common.Color(rgba, Common.Color.Format.RGBA);
-  }
-};
-
-/** @type {!RegExp} */
-Common.Color.Regex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{8}|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3,4}|\b[a-zA-Z]+\b(?!-))/g;
-
-/**
- * @enum {string}
- */
-Common.Color.Format = {
-  Original: 'original',
-  Nickname: 'nickname',
-  HEX: 'hex',
-  ShortHEX: 'shorthex',
-  HEXA: 'hexa',
-  ShortHEXA: 'shorthexa',
-  RGB: 'rgb',
-  RGBA: 'rgba',
-  HSL: 'hsl',
-  HSLA: 'hsla'
-};
-
-
-/** @type {!Array<number>} */
-Common.Color.hsva2rgba._tmpHSLA = [0, 0, 0, 0];
-
-
-Common.Color.calculateContrastRatio._blendedFg = [0, 0, 0, 0];
-
-
-Common.Color.Nicknames = {
-  'aliceblue': [240, 248, 255],
-  'antiquewhite': [250, 235, 215],
-  'aqua': [0, 255, 255],
-  'aquamarine': [127, 255, 212],
-  'azure': [240, 255, 255],
-  'beige': [245, 245, 220],
-  'bisque': [255, 228, 196],
-  'black': [0, 0, 0],
-  'blanchedalmond': [255, 235, 205],
-  'blue': [0, 0, 255],
-  'blueviolet': [138, 43, 226],
-  'brown': [165, 42, 42],
-  'burlywood': [222, 184, 135],
-  'cadetblue': [95, 158, 160],
-  'chartreuse': [127, 255, 0],
-  'chocolate': [210, 105, 30],
-  'coral': [255, 127, 80],
-  'cornflowerblue': [100, 149, 237],
-  'cornsilk': [255, 248, 220],
-  'crimson': [237, 20, 61],
-  'cyan': [0, 255, 255],
-  'darkblue': [0, 0, 139],
-  'darkcyan': [0, 139, 139],
-  'darkgoldenrod': [184, 134, 11],
-  'darkgray': [169, 169, 169],
-  'darkgrey': [169, 169, 169],
-  'darkgreen': [0, 100, 0],
-  'darkkhaki': [189, 183, 107],
-  'darkmagenta': [139, 0, 139],
-  'darkolivegreen': [85, 107, 47],
-  'darkorange': [255, 140, 0],
-  'darkorchid': [153, 50, 204],
-  'darkred': [139, 0, 0],
-  'darksalmon': [233, 150, 122],
-  'darkseagreen': [143, 188, 143],
-  'darkslateblue': [72, 61, 139],
-  'darkslategray': [47, 79, 79],
-  'darkslategrey': [47, 79, 79],
-  'darkturquoise': [0, 206, 209],
-  'darkviolet': [148, 0, 211],
-  'deeppink': [255, 20, 147],
-  'deepskyblue': [0, 191, 255],
-  'dimgray': [105, 105, 105],
-  'dimgrey': [105, 105, 105],
-  'dodgerblue': [30, 144, 255],
-  'firebrick': [178, 34, 34],
-  'floralwhite': [255, 250, 240],
-  'forestgreen': [34, 139, 34],
-  'fuchsia': [255, 0, 255],
-  'gainsboro': [220, 220, 220],
-  'ghostwhite': [248, 248, 255],
-  'gold': [255, 215, 0],
-  'goldenrod': [218, 165, 32],
-  'gray': [128, 128, 128],
-  'grey': [128, 128, 128],
-  'green': [0, 128, 0],
-  'greenyellow': [173, 255, 47],
-  'honeydew': [240, 255, 240],
-  'hotpink': [255, 105, 180],
-  'indianred': [205, 92, 92],
-  'indigo': [75, 0, 130],
-  'ivory': [255, 255, 240],
-  'khaki': [240, 230, 140],
-  'lavender': [230, 230, 250],
-  'lavenderblush': [255, 240, 245],
-  'lawngreen': [124, 252, 0],
-  'lemonchiffon': [255, 250, 205],
-  'lightblue': [173, 216, 230],
-  'lightcoral': [240, 128, 128],
-  'lightcyan': [224, 255, 255],
-  'lightgoldenrodyellow': [250, 250, 210],
-  'lightgreen': [144, 238, 144],
-  'lightgray': [211, 211, 211],
-  'lightgrey': [211, 211, 211],
-  'lightpink': [255, 182, 193],
-  'lightsalmon': [255, 160, 122],
-  'lightseagreen': [32, 178, 170],
-  'lightskyblue': [135, 206, 250],
-  'lightslategray': [119, 136, 153],
-  'lightslategrey': [119, 136, 153],
-  'lightsteelblue': [176, 196, 222],
-  'lightyellow': [255, 255, 224],
-  'lime': [0, 255, 0],
-  'limegreen': [50, 205, 50],
-  'linen': [250, 240, 230],
-  'magenta': [255, 0, 255],
-  'maroon': [128, 0, 0],
-  'mediumaquamarine': [102, 205, 170],
-  'mediumblue': [0, 0, 205],
-  'mediumorchid': [186, 85, 211],
-  'mediumpurple': [147, 112, 219],
-  'mediumseagreen': [60, 179, 113],
-  'mediumslateblue': [123, 104, 238],
-  'mediumspringgreen': [0, 250, 154],
-  'mediumturquoise': [72, 209, 204],
-  'mediumvioletred': [199, 21, 133],
-  'midnightblue': [25, 25, 112],
-  'mintcream': [245, 255, 250],
-  'mistyrose': [255, 228, 225],
-  'moccasin': [255, 228, 181],
-  'navajowhite': [255, 222, 173],
-  'navy': [0, 0, 128],
-  'oldlace': [253, 245, 230],
-  'olive': [128, 128, 0],
-  'olivedrab': [107, 142, 35],
-  'orange': [255, 165, 0],
-  'orangered': [255, 69, 0],
-  'orchid': [218, 112, 214],
-  'palegoldenrod': [238, 232, 170],
-  'palegreen': [152, 251, 152],
-  'paleturquoise': [175, 238, 238],
-  'palevioletred': [219, 112, 147],
-  'papayawhip': [255, 239, 213],
-  'peachpuff': [255, 218, 185],
-  'peru': [205, 133, 63],
-  'pink': [255, 192, 203],
-  'plum': [221, 160, 221],
-  'powderblue': [176, 224, 230],
-  'purple': [128, 0, 128],
-  'rebeccapurple': [102, 51, 153],
-  'red': [255, 0, 0],
-  'rosybrown': [188, 143, 143],
-  'royalblue': [65, 105, 225],
-  'saddlebrown': [139, 69, 19],
-  'salmon': [250, 128, 114],
-  'sandybrown': [244, 164, 96],
-  'seagreen': [46, 139, 87],
-  'seashell': [255, 245, 238],
-  'sienna': [160, 82, 45],
-  'silver': [192, 192, 192],
-  'skyblue': [135, 206, 235],
-  'slateblue': [106, 90, 205],
-  'slategray': [112, 128, 144],
-  'slategrey': [112, 128, 144],
-  'snow': [255, 250, 250],
-  'springgreen': [0, 255, 127],
-  'steelblue': [70, 130, 180],
-  'tan': [210, 180, 140],
-  'teal': [0, 128, 128],
-  'thistle': [216, 191, 216],
-  'tomato': [255, 99, 71],
-  'turquoise': [64, 224, 208],
-  'violet': [238, 130, 238],
-  'wheat': [245, 222, 179],
-  'white': [255, 255, 255],
-  'whitesmoke': [245, 245, 245],
-  'yellow': [255, 255, 0],
-  'yellowgreen': [154, 205, 50],
-  'transparent': [0, 0, 0, 0],
-};
-
-Common.Color.PageHighlight = {
-  Content: Common.Color.fromRGBA([111, 168, 220, .66]),
-  ContentLight: Common.Color.fromRGBA([111, 168, 220, .5]),
-  ContentOutline: Common.Color.fromRGBA([9, 83, 148]),
-  Padding: Common.Color.fromRGBA([147, 196, 125, .55]),
-  PaddingLight: Common.Color.fromRGBA([147, 196, 125, .4]),
-  Border: Common.Color.fromRGBA([255, 229, 153, .66]),
-  BorderLight: Common.Color.fromRGBA([255, 229, 153, .5]),
-  Margin: Common.Color.fromRGBA([246, 178, 107, .66]),
-  MarginLight: Common.Color.fromRGBA([246, 178, 107, .5]),
-  EventTarget: Common.Color.fromRGBA([255, 196, 196, .66]),
-  Shape: Common.Color.fromRGBA([96, 82, 177, 0.8]),
-  ShapeMargin: Common.Color.fromRGBA([96, 82, 127, .6]),
-  CssGrid: Common.Color.fromRGBA([0x4b, 0, 0x82, 1])
-};
-
-Common.Color.Generator = class {
-  /**
-   * @param {!{min: number, max: number}|number=} hueSpace
-   * @param {!{min: number, max: number, count: (number|undefined)}|number=} satSpace
-   * @param {!{min: number, max: number, count: (number|undefined)}|number=} lightnessSpace
-   * @param {!{min: number, max: number, count: (number|undefined)}|number=} alphaSpace
-   */
-  constructor(hueSpace, satSpace, lightnessSpace, alphaSpace) {
-    this._hueSpace = hueSpace || {min: 0, max: 360};
-    this._satSpace = satSpace || 67;
-    this._lightnessSpace = lightnessSpace || 80;
-    this._alphaSpace = alphaSpace || 1;
-    /** @type {!Map<string, string>} */
-    this._colors = new Map();
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} color
-   */
-  setColorForID(id, color) {
-    this._colors.set(id, color);
-  }
-
-  /**
-   * @param {string} id
-   * @return {string}
-   */
-  colorForID(id) {
-    let color = this._colors.get(id);
-    if (!color) {
-      color = this._generateColorForID(id);
-      this._colors.set(id, color);
-    }
-    return color;
-  }
-
-  /**
-   * @param {string} id
-   * @return {string}
-   */
-  _generateColorForID(id) {
-    const hash = String.hashCode(id);
-    const h = this._indexToValueInSpace(hash, this._hueSpace);
-    const s = this._indexToValueInSpace(hash >> 8, this._satSpace);
-    const l = this._indexToValueInSpace(hash >> 16, this._lightnessSpace);
-    const a = this._indexToValueInSpace(hash >> 24, this._alphaSpace);
-    return `hsla(${h}, ${s}%, ${l}%, ${a})`;
-  }
-
-  /**
-   * @param {number} index
-   * @param {!{min: number, max: number, count: (number|undefined)}|number} space
-   * @return {number}
-   */
-  _indexToValueInSpace(index, space) {
-    if (typeof space === 'number')
-      return space;
-    const count = space.count || space.max - space.min;
-    index %= count;
-    return space.min + Math.floor(index / (count - 1) * (space.max - space.min));
-  }
-};
diff --git a/front_end/common/Console.js b/front_end/common/Console.js
deleted file mode 100644
index 71350cb..0000000
--- a/front_end/common/Console.js
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Common.Console = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!Array.<!Common.Console.Message>} */
-    this._messages = [];
-  }
-
-  /**
-   * @param {string} text
-   * @param {!Common.Console.MessageLevel} level
-   * @param {boolean=} show
-   */
-  addMessage(text, level, show) {
-    const message =
-        new Common.Console.Message(text, level || Common.Console.MessageLevel.Info, Date.now(), show || false);
-    this._messages.push(message);
-    this.dispatchEventToListeners(Common.Console.Events.MessageAdded, message);
-  }
-
-  /**
-   * @param {string} text
-   */
-  log(text) {
-    this.addMessage(text, Common.Console.MessageLevel.Info);
-  }
-
-  /**
-   * @param {string} text
-   */
-  warn(text) {
-    this.addMessage(text, Common.Console.MessageLevel.Warning);
-  }
-
-  /**
-   * @param {string} text
-   */
-  error(text) {
-    this.addMessage(text, Common.Console.MessageLevel.Error, true);
-  }
-
-  /**
-   * @return {!Array.<!Common.Console.Message>}
-   */
-  messages() {
-    return this._messages;
-  }
-
-  show() {
-    this.showPromise();
-  }
-
-  /**
-   * @return {!Promise.<undefined>}
-   */
-  showPromise() {
-    return Common.Revealer.reveal(this);
-  }
-};
-
-/** @enum {symbol} */
-Common.Console.Events = {
-  MessageAdded: Symbol('messageAdded')
-};
-
-/**
- * @enum {string}
- */
-Common.Console.MessageLevel = {
-  Info: 'info',
-  Warning: 'warning',
-  Error: 'error'
-};
-
-/**
- * @unrestricted
- */
-Common.Console.Message = class {
-  /**
-   * @param {string} text
-   * @param {!Common.Console.MessageLevel} level
-   * @param {number} timestamp
-   * @param {boolean} show
-   */
-  constructor(text, level, timestamp, show) {
-    this.text = text;
-    this.level = level;
-    this.timestamp = (typeof timestamp === 'number') ? timestamp : Date.now();
-    this.show = show;
-  }
-};
-
-Common.console = new Common.Console();
diff --git a/front_end/common/ContentProvider.js b/front_end/common/ContentProvider.js
deleted file mode 100644
index b5fdf23..0000000
--- a/front_end/common/ContentProvider.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-Common.ContentProvider = function() {};
-
-Common.ContentProvider.prototype = {
-  /**
-   * @return {string}
-   */
-  contentURL() {},
-
-  /**
-   * @return {!Common.ResourceType}
-   */
-  contentType() {},
-
-  /**
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {},
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  requestContent() {},
-
-  /**
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInContent(query, caseSensitive, isRegex) {}
-};
-
-/**
- * @unrestricted
- */
-Common.ContentProvider.SearchMatch = class {
-  /**
-   * @param {number} lineNumber
-   * @param {string} lineContent
-   */
-  constructor(lineNumber, lineContent) {
-    this.lineNumber = lineNumber;
-    this.lineContent = lineContent;
-  }
-};
-
-/**
- * @param {string} content
- * @param {string} query
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
- * @return {!Array.<!Common.ContentProvider.SearchMatch>}
- */
-Common.ContentProvider.performSearchInContent = function(content, query, caseSensitive, isRegex) {
-  const regex = createSearchRegex(query, caseSensitive, isRegex);
-
-  const text = new TextUtils.Text(content);
-  const result = [];
-  for (let i = 0; i < text.lineCount(); ++i) {
-    const lineContent = text.lineAt(i);
-    regex.lastIndex = 0;
-    if (regex.exec(lineContent))
-      result.push(new Common.ContentProvider.SearchMatch(i, lineContent));
-  }
-  return result;
-};
-
-/**
- * @param {?string} content
- * @param {string} mimeType
- * @param {boolean} contentEncoded
- * @param {?string=} charset
- * @return {?string}
- */
-Common.ContentProvider.contentAsDataURL = function(content, mimeType, contentEncoded, charset) {
-  const maxDataUrlSize = 1024 * 1024;
-  if (content === null || content.length > maxDataUrlSize)
-    return null;
-
-  return 'data:' + mimeType + (charset ? ';charset=' + charset : '') + (contentEncoded ? ';base64' : '') + ',' +
-      content;
-};
diff --git a/front_end/common/ModuleExtensionInterfaces.js b/front_end/common/ModuleExtensionInterfaces.js
deleted file mode 100644
index e3343de..0000000
--- a/front_end/common/ModuleExtensionInterfaces.js
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @interface
- */
-Common.Renderer = function() {};
-
-Common.Renderer.prototype = {
-  /**
-   * @param {!Object} object
-   * @param {!Common.Renderer.Options} options
-   * @return {!Promise.<?Node>}
-   */
-  render(object, options) {}
-};
-
-/**
- * @param {?Object} object
- * @param {!Common.Renderer.Options=} options
- * @return {!Promise.<?Node>}
- */
-Common.Renderer.render = function(object, options) {
-  if (!object)
-    return Promise.reject(new Error('Can\'t render ' + object));
-  return self.runtime.extension(Common.Renderer, object)
-      .instance()
-      .then(renderer => renderer.render(object, options || {}));
-};
-
-/** @typedef {!{title: (string|!Element|undefined), expanded: (boolean|undefined),
- *    editable: (boolean|undefined) }} */
-Common.Renderer.Options;
-
-/**
- * @interface
- */
-Common.Revealer = function() {};
-
-/**
- * @param {?Object} revealable
- * @param {boolean=} omitFocus
- * @return {!Promise.<undefined>}
- */
-Common.Revealer.reveal = function(revealable, omitFocus) {
-  if (!revealable)
-    return Promise.reject(new Error('Can\'t reveal ' + revealable));
-  return self.runtime.allInstances(Common.Revealer, revealable).then(reveal);
-
-  /**
-   * @param {!Array.<!Common.Revealer>} revealers
-   * @return {!Promise.<undefined>}
-   */
-  function reveal(revealers) {
-    const promises = [];
-    for (let i = 0; i < revealers.length; ++i)
-      promises.push(revealers[i].reveal(/** @type {!Object} */ (revealable), omitFocus));
-    return Promise.race(promises);
-  }
-};
-
-/**
- * @param {?Object} revealable
- * @return {?string}
- */
-Common.Revealer.revealDestination = function(revealable) {
-  const extension = self.runtime.extension(Common.Revealer, revealable);
-  if (!extension)
-    return null;
-  return extension.descriptor()['destination'];
-};
-
-Common.Revealer.prototype = {
-  /**
-   * @param {!Object} object
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  reveal(object, omitFocus) {}
-};
-
-/**
- * @interface
- */
-Common.App = function() {};
-
-Common.App.prototype = {
-  /**
-   * @param {!Document} document
-   */
-  presentUI(document) {}
-};
-
-/**
- * @interface
- */
-Common.AppProvider = function() {};
-
-Common.AppProvider.prototype = {
-  /**
-   * @return {!Common.App}
-   */
-  createApp() {}
-};
-
-/**
- * @interface
- */
-Common.QueryParamHandler = function() {};
-
-Common.QueryParamHandler.prototype = {
-  /**
-   * @param {string} value
-   */
-  handleQueryParam(value) {}
-};
-
-/**
- * @interface
- */
-Common.Runnable = function() {};
-
-Common.Runnable.prototype = {
-  run() {}
-};
-
-/**
- * @interface
- */
-Common.Linkifier = function() {};
-
-Common.Linkifier.prototype = {
-  /**
-   * @param {!Object} object
-   * @param {!Common.Linkifier.Options=} options
-   * @return {!Node}
-   */
-  linkify(object, options) {}
-};
-
-/**
- * @param {?Object} object
- * @param {!Common.Linkifier.Options=} options
- * @return {!Promise<!Node>}
- */
-Common.Linkifier.linkify = function(object, options) {
-  if (!object)
-    return Promise.reject(new Error('Can\'t linkify ' + object));
-  return self.runtime.extension(Common.Linkifier, object)
-      .instance()
-      .then(linkifier => linkifier.linkify(object, options));
-};
-
-/** @typedef {{tooltip: string}} */
-Common.Linkifier.Options;
diff --git a/front_end/common/Object.js b/front_end/common/Object.js
deleted file mode 100644
index 6c8fb3c..0000000
--- a/front_end/common/Object.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Common.EventTarget}
- * @unrestricted
- */
-Common.Object = class {
-  constructor() {
-    /** @type {(!Map<symbol, !Array<!Common.Object._listenerCallbackTuple>>|undefined)} */
-    this._listeners;
-  }
-
-  /**
-   * @override
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   * @return {!Common.EventTarget.EventDescriptor}
-   */
-  addEventListener(eventType, listener, thisObject) {
-    if (!listener)
-      console.assert(false);
-
-    if (!this._listeners)
-      this._listeners = new Map();
-
-    if (!this._listeners.has(eventType))
-      this._listeners.set(eventType, []);
-    this._listeners.get(eventType).push({thisObject: thisObject, listener: listener});
-    return {eventTarget: this, eventType: eventType, thisObject: thisObject, listener: listener};
-  }
-
-  /**
-   * @override
-   * @param {symbol} eventType
-   * @return {!Promise<*>}
-   */
-  once(eventType) {
-    return new Promise(resolve => {
-      const descriptor = this.addEventListener(eventType, event => {
-        this.removeEventListener(eventType, descriptor.listener);
-        resolve(event.data);
-      });
-    });
-  }
-
-  /**
-   * @override
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  removeEventListener(eventType, listener, thisObject) {
-    console.assert(listener);
-
-    if (!this._listeners || !this._listeners.has(eventType))
-      return;
-    const listeners = this._listeners.get(eventType);
-    for (let i = 0; i < listeners.length; ++i) {
-      if (listeners[i].listener === listener && listeners[i].thisObject === thisObject) {
-        listeners[i].disposed = true;
-        listeners.splice(i--, 1);
-      }
-    }
-
-    if (!listeners.length)
-      this._listeners.delete(eventType);
-  }
-
-  /**
-   * @override
-   * @param {symbol} eventType
-   * @return {boolean}
-   */
-  hasEventListeners(eventType) {
-    return !!(this._listeners && this._listeners.has(eventType));
-  }
-
-  /**
-   * @override
-   * @param {symbol} eventType
-   * @param {*=} eventData
-   */
-  dispatchEventToListeners(eventType, eventData) {
-    if (!this._listeners || !this._listeners.has(eventType))
-      return;
-
-    const event = /** @type {!Common.Event} */ ({data: eventData});
-    const listeners = this._listeners.get(eventType).slice(0);
-    for (let i = 0; i < listeners.length; ++i) {
-      if (!listeners[i].disposed)
-        listeners[i].listener.call(listeners[i].thisObject, event);
-    }
-  }
-};
-
-/**
- * @typedef {!{data: *}}
- */
-Common.Event;
-
-/**
- * @typedef {!{thisObject: (!Object|undefined), listener: function(!Common.Event), disposed: (boolean|undefined)}}
- */
-Common.Object._listenerCallbackTuple;
-
-/**
- * @interface
- */
-Common.EventTarget = function() {};
-
-/**
- * @typedef {!{eventTarget: !Common.EventTarget, eventType: symbol, thisObject: (!Object|undefined), listener: function(!Common.Event)}}
- */
-Common.EventTarget.EventDescriptor;
-
-/**
- * @param {!Array<!Common.EventTarget.EventDescriptor>} eventList
- */
-Common.EventTarget.removeEventListeners = function(eventList) {
-  for (let i = 0; i < eventList.length; ++i) {
-    const eventInfo = eventList[i];
-    eventInfo.eventTarget.removeEventListener(eventInfo.eventType, eventInfo.listener, eventInfo.thisObject);
-  }
-  // Do not hold references on unused event descriptors.
-  eventList.splice(0, eventList.length);
-};
-
-Common.EventTarget.prototype = {
-  /**
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   * @return {!Common.EventTarget.EventDescriptor}
-   */
-  addEventListener(eventType, listener, thisObject) {},
-
-  /**
-   * @param {symbol} eventType
-   * @return {!Promise<*>}
-   */
-  once(eventType) {},
-
-  /**
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  removeEventListener(eventType, listener, thisObject) {},
-
-  /**
-   * @param {symbol} eventType
-   * @return {boolean}
-   */
-  hasEventListeners(eventType) {},
-
-  /**
-   * @param {symbol} eventType
-   * @param {*=} eventData
-   */
-  dispatchEventToListeners(eventType, eventData) {},
-};
diff --git a/front_end/common/OutputStream.js b/front_end/common/OutputStream.js
deleted file mode 100644
index a4fa83b..0000000
--- a/front_end/common/OutputStream.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @interface
- */
-Common.OutputStream = function() {};
-
-Common.OutputStream.prototype = {
-  /**
-   * @param {string} data
-   * @return {!Promise}
-   */
-  write(data) {},
-
-  close() {}
-};
-
-/**
- * @implements {Common.OutputStream}
- */
-Common.StringOutputStream = class {
-  constructor() {
-    this._data = '';
-  }
-
-  /**
-   * @override
-   * @param {string} chunk
-   * @return {!Promise}
-   */
-  async write(chunk) {
-    this._data += chunk;
-  }
-
-  /**
-   * @override
-   */
-  close() {
-  }
-
-  /**
-   * @return {string}
-   */
-  data() {
-    return this._data;
-  }
-};
diff --git a/front_end/common/ParsedURL.js b/front_end/common/ParsedURL.js
deleted file mode 100644
index 92599f5..0000000
--- a/front_end/common/ParsedURL.js
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Common.ParsedURL = class {
-  /**
-   * @param {string} url
-   */
-  constructor(url) {
-    this.isValid = false;
-    this.url = url;
-    this.scheme = '';
-    this.user = '';
-    this.host = '';
-    this.port = '';
-    this.path = '';
-    this.queryParams = '';
-    this.fragment = '';
-    this.folderPathComponents = '';
-    this.lastPathComponent = '';
-
-    const match = url.match(Common.ParsedURL._urlRegex());
-    if (match) {
-      this.isValid = true;
-      this.scheme = match[2].toLowerCase();
-      this.user = match[3];
-      this.host = match[4];
-      this.port = match[5];
-      this.path = match[6] || '/';
-      this.queryParams = match[7] || '';
-      this.fragment = match[8];
-    } else {
-      if (this.url.startsWith('data:')) {
-        this.scheme = 'data';
-        return;
-      }
-      if (this.url === 'about:blank') {
-        this.scheme = 'about';
-        return;
-      }
-      this.path = this.url;
-    }
-
-    const lastSlashIndex = this.path.lastIndexOf('/');
-    if (lastSlashIndex !== -1) {
-      this.folderPathComponents = this.path.substring(0, lastSlashIndex);
-      this.lastPathComponent = this.path.substring(lastSlashIndex + 1);
-    } else {
-      this.lastPathComponent = this.path;
-    }
-  }
-
-  /**
-   * @param {string} fileSystemPath
-   * @return {string}
-   */
-  static platformPathToURL(fileSystemPath) {
-    fileSystemPath = fileSystemPath.replace(/\\/g, '/');
-    if (!fileSystemPath.startsWith('file://')) {
-      if (fileSystemPath.startsWith('/'))
-        fileSystemPath = 'file://' + fileSystemPath;
-      else
-        fileSystemPath = 'file:///' + fileSystemPath;
-    }
-    return fileSystemPath;
-  }
-
-  /**
-   * @param {string} fileURL
-   * @param {boolean} isWindows
-   * @return {string}
-   */
-  static urlToPlatformPath(fileURL, isWindows) {
-    console.assert(fileURL.startsWith('file://'), 'This must be a file URL.');
-    if (isWindows)
-      return fileURL.substr('file:///'.length).replace(/\//g, '\\');
-    return fileURL.substr('file://'.length);
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  static urlWithoutHash(url) {
-    const hashIndex = url.indexOf('#');
-    if (hashIndex !== -1)
-      return url.substr(0, hashIndex);
-    return url;
-  }
-
-  /**
-   * @return {!RegExp}
-   */
-  static _urlRegex() {
-    if (Common.ParsedURL._urlRegexInstance)
-      return Common.ParsedURL._urlRegexInstance;
-    // RegExp groups:
-    // 1 - scheme, hostname, ?port
-    // 2 - scheme (using the RFC3986 grammar)
-    // 3 - ?user:password
-    // 4 - hostname
-    // 5 - ?port
-    // 6 - ?path
-    // 7 - ?query
-    // 8 - ?fragment
-    const schemeRegex = /([A-Za-z][A-Za-z0-9+.-]*):\/\//;
-    const userRegex = /(?:([A-Za-z0-9\-._~%!$&'()*+,;=:]*)@)?/;
-    const hostRegex = /((?:\[::\d?\])|(?:[^\s\/:]*))/;
-    const portRegex = /(?::([\d]+))?/;
-    const pathRegex = /(\/[^#?]*)?/;
-    const queryRegex = /(?:\?([^#]*))?/;
-    const fragmentRegex = /(?:#(.*))?/;
-
-    Common.ParsedURL._urlRegexInstance = new RegExp(
-        '^(' + schemeRegex.source + userRegex.source + hostRegex.source + portRegex.source + ')' + pathRegex.source +
-        queryRegex.source + fragmentRegex.source + '$');
-    return Common.ParsedURL._urlRegexInstance;
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  static extractPath(url) {
-    const parsedURL = url.asParsedURL();
-    return parsedURL ? parsedURL.path : '';
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  static extractOrigin(url) {
-    const parsedURL = url.asParsedURL();
-    return parsedURL ? parsedURL.securityOrigin() : '';
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  static extractExtension(url) {
-    url = Common.ParsedURL.urlWithoutHash(url);
-    const indexOfQuestionMark = url.indexOf('?');
-    if (indexOfQuestionMark !== -1)
-      url = url.substr(0, indexOfQuestionMark);
-    const lastIndexOfSlash = url.lastIndexOf('/');
-    if (lastIndexOfSlash !== -1)
-      url = url.substr(lastIndexOfSlash + 1);
-    const lastIndexOfDot = url.lastIndexOf('.');
-    if (lastIndexOfDot !== -1) {
-      url = url.substr(lastIndexOfDot + 1);
-      const lastIndexOfPercent = url.indexOf('%');
-      if (lastIndexOfPercent !== -1)
-        return url.substr(0, lastIndexOfPercent);
-      return url;
-    }
-    return '';
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  static extractName(url) {
-    let index = url.lastIndexOf('/');
-    const pathAndQuery = index !== -1 ? url.substr(index + 1) : url;
-    index = pathAndQuery.indexOf('?');
-    return index < 0 ? pathAndQuery : pathAndQuery.substr(0, index);
-  }
-
-  /**
-   * @param {string} baseURL
-   * @param {string} href
-   * @return {?string}
-   */
-  static completeURL(baseURL, href) {
-    // Return special URLs as-is.
-    const trimmedHref = href.trim();
-    if (trimmedHref.startsWith('data:') || trimmedHref.startsWith('blob:') || trimmedHref.startsWith('javascript:'))
-      return href;
-
-    // Return absolute URLs as-is.
-    const parsedHref = trimmedHref.asParsedURL();
-    if (parsedHref && parsedHref.scheme)
-      return trimmedHref;
-
-    const parsedURL = baseURL.asParsedURL();
-    if (!parsedURL)
-      return null;
-
-    if (parsedURL.isDataURL())
-      return href;
-
-    if (href.length > 1 && href.charAt(0) === '/' && href.charAt(1) === '/') {
-      // href starts with "//" which is a full URL with the protocol dropped (use the baseURL protocol).
-      return parsedURL.scheme + ':' + href;
-    }
-
-    const securityOrigin = parsedURL.securityOrigin();
-    const pathText = parsedURL.path;
-    const queryText = parsedURL.queryParams ? '?' + parsedURL.queryParams : '';
-
-    // Empty href resolves to a URL without fragment.
-    if (!href.length)
-      return securityOrigin + pathText + queryText;
-
-    if (href.charAt(0) === '#')
-      return securityOrigin + pathText + queryText + href;
-
-    if (href.charAt(0) === '?')
-      return securityOrigin + pathText + href;
-
-    let hrefPath = href.match(/^[^#?]*/)[0];
-    const hrefSuffix = href.substring(hrefPath.length);
-    if (hrefPath.charAt(0) !== '/')
-      hrefPath = parsedURL.folderPathComponents + '/' + hrefPath;
-    return securityOrigin + Runtime.normalizePath(hrefPath) + hrefSuffix;
-  }
-
-  /**
-   * @param {string} string
-   * @return {!{url: string, lineNumber: (number|undefined), columnNumber: (number|undefined)}}
-   */
-  static splitLineAndColumn(string) {
-    // Only look for line and column numbers in the path to avoid matching port numbers.
-    const beforePathMatch = string.match(Common.ParsedURL._urlRegex());
-    let beforePath = '';
-    let pathAndAfter = string;
-    if (beforePathMatch) {
-      beforePath = beforePathMatch[1];
-      pathAndAfter = string.substring(beforePathMatch[1].length);
-    }
-
-    const lineColumnRegEx = /(?::(\d+))?(?::(\d+))?$/;
-    const lineColumnMatch = lineColumnRegEx.exec(pathAndAfter);
-    let lineNumber;
-    let columnNumber;
-    console.assert(lineColumnMatch);
-
-    if (typeof(lineColumnMatch[1]) === 'string') {
-      lineNumber = parseInt(lineColumnMatch[1], 10);
-      // Immediately convert line and column to 0-based numbers.
-      lineNumber = isNaN(lineNumber) ? undefined : lineNumber - 1;
-    }
-    if (typeof(lineColumnMatch[2]) === 'string') {
-      columnNumber = parseInt(lineColumnMatch[2], 10);
-      columnNumber = isNaN(columnNumber) ? undefined : columnNumber - 1;
-    }
-
-    return {
-      url: beforePath + pathAndAfter.substring(0, pathAndAfter.length - lineColumnMatch[0].length),
-      lineNumber: lineNumber,
-      columnNumber: columnNumber
-    };
-  }
-
-  /**
-   * @param {string} url
-   * @return {boolean}
-   */
-  static isRelativeURL(url) {
-    return !(/^[A-Za-z][A-Za-z0-9+.-]*:/.test(url));
-  }
-
-  get displayName() {
-    if (this._displayName)
-      return this._displayName;
-
-    if (this.isDataURL())
-      return this.dataURLDisplayName();
-    if (this.isAboutBlank())
-      return this.url;
-
-    this._displayName = this.lastPathComponent;
-    if (!this._displayName)
-      this._displayName = (this.host || '') + '/';
-    if (this._displayName === '/')
-      this._displayName = this.url;
-    return this._displayName;
-  }
-
-  /**
-   * @return {string}
-   */
-  dataURLDisplayName() {
-    if (this._dataURLDisplayName)
-      return this._dataURLDisplayName;
-    if (!this.isDataURL())
-      return '';
-    this._dataURLDisplayName = this.url.trimEnd(20);
-    return this._dataURLDisplayName;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isAboutBlank() {
-    return this.url === 'about:blank';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDataURL() {
-    return this.scheme === 'data';
-  }
-
-  /**
-   * @return {string}
-   */
-  lastPathComponentWithFragment() {
-    return this.lastPathComponent + (this.fragment ? '#' + this.fragment : '');
-  }
-
-  /**
-   * @return {string}
-   */
-  domain() {
-    if (this.isDataURL())
-      return 'data:';
-    return this.host + (this.port ? ':' + this.port : '');
-  }
-
-  /**
-   * @return {string}
-   */
-  securityOrigin() {
-    if (this.isDataURL())
-      return 'data:';
-    return this.scheme + '://' + this.domain();
-  }
-
-  /**
-   * @return {string}
-   */
-  urlWithoutScheme() {
-    if (this.scheme && this.url.startsWith(this.scheme + '://'))
-      return this.url.substring(this.scheme.length + 3);
-    return this.url;
-  }
-};
-
-
-/**
- * @return {?Common.ParsedURL}
- */
-String.prototype.asParsedURL = function() {
-  const parsedURL = new Common.ParsedURL(this.toString());
-  if (parsedURL.isValid)
-    return parsedURL;
-  return null;
-};
diff --git a/front_end/common/Progress.js b/front_end/common/Progress.js
deleted file mode 100644
index 669ecf0..0000000
--- a/front_end/common/Progress.js
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-Common.Progress = function() {};
-
-Common.Progress.prototype = {
-  /**
-   * @param {number} totalWork
-   */
-  setTotalWork(totalWork) {},
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {},
-
-  /**
-   * @param {number} worked
-   * @param {string=} title
-   */
-  setWorked(worked, title) {},
-
-  /**
-   * @param {number=} worked
-   */
-  worked(worked) {},
-
-  done() {},
-
-  /**
-   * @return {boolean}
-   */
-  isCanceled() {
-    return false;
-  },
-};
-
-/**
- * @unrestricted
- */
-Common.CompositeProgress = class {
-  /**
-   * @param {!Common.Progress} parent
-   */
-  constructor(parent) {
-    this._parent = parent;
-    this._children = [];
-    this._childrenDone = 0;
-    this._parent.setTotalWork(1);
-    this._parent.setWorked(0);
-  }
-
-  _childDone() {
-    if (++this._childrenDone !== this._children.length)
-      return;
-    this._parent.done();
-  }
-
-  /**
-   * @param {number=} weight
-   * @return {!Common.SubProgress}
-   */
-  createSubProgress(weight) {
-    const child = new Common.SubProgress(this, weight);
-    this._children.push(child);
-    return child;
-  }
-
-  _update() {
-    let totalWeights = 0;
-    let done = 0;
-
-    for (let i = 0; i < this._children.length; ++i) {
-      const child = this._children[i];
-      if (child._totalWork)
-        done += child._weight * child._worked / child._totalWork;
-      totalWeights += child._weight;
-    }
-    this._parent.setWorked(done / totalWeights);
-  }
-};
-
-/**
- * @implements {Common.Progress}
- * @unrestricted
- */
-Common.SubProgress = class {
-  /**
-   * @param {!Common.CompositeProgress} composite
-   * @param {number=} weight
-   */
-  constructor(composite, weight) {
-    this._composite = composite;
-    this._weight = weight || 1;
-    this._worked = 0;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isCanceled() {
-    return this._composite._parent.isCanceled();
-  }
-
-  /**
-   * @override
-   * @param {string} title
-   */
-  setTitle(title) {
-    this._composite._parent.setTitle(title);
-  }
-
-  /**
-   * @override
-   */
-  done() {
-    this.setWorked(this._totalWork);
-    this._composite._childDone();
-  }
-
-  /**
-   * @override
-   * @param {number} totalWork
-   */
-  setTotalWork(totalWork) {
-    this._totalWork = totalWork;
-    this._composite._update();
-  }
-
-  /**
-   * @override
-   * @param {number} worked
-   * @param {string=} title
-   */
-  setWorked(worked, title) {
-    this._worked = worked;
-    if (typeof title !== 'undefined')
-      this.setTitle(title);
-    this._composite._update();
-  }
-
-  /**
-   * @override
-   * @param {number=} worked
-   */
-  worked(worked) {
-    this.setWorked(this._worked + (worked || 1));
-  }
-};
-
-/**
- * @implements {Common.Progress}
- * @unrestricted
- */
-Common.ProgressProxy = class {
-  /**
-   * @param {?Common.Progress} delegate
-   * @param {function()=} doneCallback
-   */
-  constructor(delegate, doneCallback) {
-    this._delegate = delegate;
-    this._doneCallback = doneCallback;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isCanceled() {
-    return this._delegate ? this._delegate.isCanceled() : false;
-  }
-
-  /**
-   * @override
-   * @param {string} title
-   */
-  setTitle(title) {
-    if (this._delegate)
-      this._delegate.setTitle(title);
-  }
-
-  /**
-   * @override
-   */
-  done() {
-    if (this._delegate)
-      this._delegate.done();
-    if (this._doneCallback)
-      this._doneCallback();
-  }
-
-  /**
-   * @override
-   * @param {number} totalWork
-   */
-  setTotalWork(totalWork) {
-    if (this._delegate)
-      this._delegate.setTotalWork(totalWork);
-  }
-
-  /**
-   * @override
-   * @param {number} worked
-   * @param {string=} title
-   */
-  setWorked(worked, title) {
-    if (this._delegate)
-      this._delegate.setWorked(worked, title);
-  }
-
-  /**
-   * @override
-   * @param {number=} worked
-   */
-  worked(worked) {
-    if (this._delegate)
-      this._delegate.worked(worked);
-  }
-};
diff --git a/front_end/common/ResourceType.js b/front_end/common/ResourceType.js
deleted file mode 100644
index 647af08..0000000
--- a/front_end/common/ResourceType.js
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc.  All rights reserved.
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Common.ResourceType = class {
-  /**
-   * @param {string} name
-   * @param {string} title
-   * @param {!Common.ResourceCategory} category
-   * @param {boolean} isTextType
-   */
-  constructor(name, title, category, isTextType) {
-    this._name = name;
-    this._title = title;
-    this._category = category;
-    this._isTextType = isTextType;
-  }
-
-  /**
-   * @param {?string} mimeType
-   * @return {!Common.ResourceType}
-   */
-  static fromMimeType(mimeType) {
-    if (mimeType.startsWith('text/html'))
-      return Common.resourceTypes.Document;
-    if (mimeType.startsWith('text/css'))
-      return Common.resourceTypes.Stylesheet;
-    if (mimeType.startsWith('image/'))
-      return Common.resourceTypes.Image;
-    if (mimeType.startsWith('text/'))
-      return Common.resourceTypes.Script;
-
-    if (mimeType.includes('font'))
-      return Common.resourceTypes.Font;
-    if (mimeType.includes('script'))
-      return Common.resourceTypes.Script;
-    if (mimeType.includes('octet'))
-      return Common.resourceTypes.Other;
-    if (mimeType.includes('application'))
-      return Common.resourceTypes.Script;
-
-    return Common.resourceTypes.Other;
-  }
-
-  /**
-   * @param {string} url
-   * @return {?Common.ResourceType}
-   */
-  static fromURL(url) {
-    return Common.ResourceType._resourceTypeByExtension.get(Common.ParsedURL.extractExtension(url)) || null;
-  }
-
-  /**
-   * @param {string} url
-   * @return {string|undefined}
-   */
-  static mimeFromURL(url) {
-    const name = Common.ParsedURL.extractName(url);
-    if (Common.ResourceType._mimeTypeByName.has(name))
-      return Common.ResourceType._mimeTypeByName.get(name);
-
-    const ext = Common.ParsedURL.extractExtension(url).toLowerCase();
-    return Common.ResourceType._mimeTypeByExtension.get(ext);
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._name;
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-
-  /**
-   * @return {!Common.ResourceCategory}
-   */
-  category() {
-    return this._category;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isTextType() {
-    return this._isTextType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isScript() {
-    return this._name === 'script' || this._name === 'sm-script' || this._name === 'snippet';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasScripts() {
-    return this.isScript() || this.isDocument();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStyleSheet() {
-    return this._name === 'stylesheet' || this._name === 'sm-stylesheet';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDocument() {
-    return this._name === 'document';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDocumentOrScriptOrStyleSheet() {
-    return this.isDocument() || this.isScript() || this.isStyleSheet();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isFromSourceMap() {
-    return this._name.startsWith('sm-');
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return this._name;
-  }
-
-  /**
-   * @return {string}
-   */
-  canonicalMimeType() {
-    if (this.isDocument())
-      return 'text/html';
-    if (this.isScript())
-      return 'text/javascript';
-    if (this.isStyleSheet())
-      return 'text/css';
-    return '';
-  }
-};
-
-/**
- * @unrestricted
- */
-Common.ResourceCategory = class {
-  /**
-   * @param {string} title
-   * @param {string} shortTitle
-   */
-  constructor(title, shortTitle) {
-    this.title = title;
-    this.shortTitle = shortTitle;
-  }
-};
-
-Common.resourceCategories = {
-  XHR: new Common.ResourceCategory('XHR and Fetch', 'XHR'),
-  Script: new Common.ResourceCategory('Scripts', 'JS'),
-  Stylesheet: new Common.ResourceCategory('Stylesheets', 'CSS'),
-  Image: new Common.ResourceCategory('Images', 'Img'),
-  Media: new Common.ResourceCategory('Media', 'Media'),
-  Font: new Common.ResourceCategory('Fonts', 'Font'),
-  Document: new Common.ResourceCategory('Documents', 'Doc'),
-  WebSocket: new Common.ResourceCategory('WebSockets', 'WS'),
-  Manifest: new Common.ResourceCategory('Manifest', 'Manifest'),
-  Other: new Common.ResourceCategory('Other', 'Other')
-};
-
-/**
- * Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson
- * @enum {!Common.ResourceType}
- */
-Common.resourceTypes = {
-  XHR: new Common.ResourceType('xhr', 'XHR', Common.resourceCategories.XHR, true),
-  Fetch: new Common.ResourceType('fetch', 'Fetch', Common.resourceCategories.XHR, true),
-  EventSource: new Common.ResourceType('eventsource', 'EventSource', Common.resourceCategories.XHR, true),
-  Script: new Common.ResourceType('script', 'Script', Common.resourceCategories.Script, true),
-  Snippet: new Common.ResourceType('snippet', 'Snippet', Common.resourceCategories.Script, true),
-  Stylesheet: new Common.ResourceType('stylesheet', 'Stylesheet', Common.resourceCategories.Stylesheet, true),
-  Image: new Common.ResourceType('image', 'Image', Common.resourceCategories.Image, false),
-  Media: new Common.ResourceType('media', 'Media', Common.resourceCategories.Media, false),
-  Font: new Common.ResourceType('font', 'Font', Common.resourceCategories.Font, false),
-  Document: new Common.ResourceType('document', 'Document', Common.resourceCategories.Document, true),
-  TextTrack: new Common.ResourceType('texttrack', 'TextTrack', Common.resourceCategories.Other, true),
-  WebSocket: new Common.ResourceType('websocket', 'WebSocket', Common.resourceCategories.WebSocket, false),
-  Other: new Common.ResourceType('other', 'Other', Common.resourceCategories.Other, false),
-  SourceMapScript: new Common.ResourceType('sm-script', 'Script', Common.resourceCategories.Script, true),
-  SourceMapStyleSheet:
-      new Common.ResourceType('sm-stylesheet', 'Stylesheet', Common.resourceCategories.Stylesheet, true),
-  Manifest: new Common.ResourceType('manifest', 'Manifest', Common.resourceCategories.Manifest, true),
-};
-
-
-Common.ResourceType._mimeTypeByName = new Map([
-  // CoffeeScript
-  ['Cakefile', 'text/x-coffeescript']
-]);
-
-Common.ResourceType._resourceTypeByExtension = new Map([
-  ['js', Common.resourceTypes.Script],
-
-  ['css', Common.resourceTypes.Stylesheet], ['xsl', Common.resourceTypes.Stylesheet],
-
-  ['jpeg', Common.resourceTypes.Image], ['jpg', Common.resourceTypes.Image], ['svg', Common.resourceTypes.Image],
-  ['gif', Common.resourceTypes.Image], ['png', Common.resourceTypes.Image], ['ico', Common.resourceTypes.Image],
-  ['tiff', Common.resourceTypes.Image], ['tif', Common.resourceTypes.Image], ['bmp', Common.resourceTypes.Image],
-
-  ['webp', Common.resourceTypes.Media],
-
-  ['ttf', Common.resourceTypes.Font], ['otf', Common.resourceTypes.Font], ['ttc', Common.resourceTypes.Font],
-  ['woff', Common.resourceTypes.Font]
-]);
-
-Common.ResourceType._mimeTypeByExtension = new Map([
-  // Web extensions
-  ['js', 'text/javascript'], ['css', 'text/css'], ['html', 'text/html'], ['htm', 'text/html'],
-  ['mjs', 'text/javascript'], ['xml', 'application/xml'], ['xsl', 'application/xml'],
-
-  // HTML Embedded Scripts, ASP], JSP
-  ['asp', 'application/x-aspx'], ['aspx', 'application/x-aspx'], ['jsp', 'application/x-jsp'],
-
-  // C/C++
-  ['c', 'text/x-c++src'], ['cc', 'text/x-c++src'], ['cpp', 'text/x-c++src'], ['h', 'text/x-c++src'],
-  ['m', 'text/x-c++src'], ['mm', 'text/x-c++src'],
-
-  // CoffeeScript
-  ['coffee', 'text/x-coffeescript'],
-
-  // Dart
-  ['dart', 'text/javascript'],
-
-  // TypeScript
-  ['ts', 'text/typescript'], ['tsx', 'text/typescript'],
-
-  // JSON
-  ['json', 'application/json'], ['gyp', 'application/json'], ['gypi', 'application/json'],
-
-  // C#
-  ['cs', 'text/x-csharp'],
-
-  // Java
-  ['java', 'text/x-java'],
-
-  // Less
-  ['less', 'text/x-less'],
-
-  // PHP
-  ['php', 'text/x-php'], ['phtml', 'application/x-httpd-php'],
-
-  // Python
-  ['py', 'text/x-python'],
-
-  // Shell
-  ['sh', 'text/x-sh'],
-
-  // SCSS
-  ['scss', 'text/x-scss'],
-
-  // Video Text Tracks.
-  ['vtt', 'text/vtt'],
-
-  // LiveScript
-  ['ls', 'text/x-livescript'],
-
-  // Markdown
-  ['md', 'text/markdown'],
-
-  // ClojureScript
-  ['cljs', 'text/x-clojure'], ['cljc', 'text/x-clojure'], ['cljx', 'text/x-clojure'],
-
-  // Stylus
-  ['styl', 'text/x-styl'],
-
-  // JSX
-  ['jsx', 'text/jsx'],
-
-  // Image
-  ['jpeg', 'image/jpeg'], ['jpg', 'image/jpeg'], ['svg', 'image/svg+xml'], ['gif', 'image/gif'], ['webp', 'image/webp'],
-  ['png', 'image/png'], ['ico', 'image/ico'], ['tiff', 'image/tiff'], ['tif', 'image/tif'], ['bmp', 'image/bmp'],
-
-  // Font
-  ['ttf', 'font/opentype'], ['otf', 'font/opentype'], ['ttc', 'font/opentype'], ['woff', 'application/font-woff']
-]);
diff --git a/front_end/common/SegmentedRange.js b/front_end/common/SegmentedRange.js
deleted file mode 100644
index ddb66da..0000000
--- a/front_end/common/SegmentedRange.js
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Common.Segment = class {
-  /**
-   * @param {number} begin
-   * @param {number} end
-   * @param {*} data
-   */
-  constructor(begin, end, data) {
-    if (begin > end)
-      console.assert(false, 'Invalid segment');
-    this.begin = begin;
-    this.end = end;
-    this.data = data;
-  }
-
-  /**
-   * @param {!Common.Segment} that
-   * @return {boolean}
-   */
-  intersects(that) {
-    return this.begin < that.end && that.begin < this.end;
-  }
-};
-
-/**
- * @unrestricted
- */
-Common.SegmentedRange = class {
-  /**
-   * @param {(function(!Common.Segment, !Common.Segment): ?Common.Segment)=} mergeCallback
-   */
-  constructor(mergeCallback) {
-    /** @type {!Array<!Common.Segment>} */
-    this._segments = [];
-    this._mergeCallback = mergeCallback;
-  }
-
-  /**
-   * @param {!Common.Segment} newSegment
-   */
-  append(newSegment) {
-    // 1. Find the proper insertion point for new segment
-    let startIndex = this._segments.lowerBound(newSegment, (a, b) => a.begin - b.begin);
-    let endIndex = startIndex;
-    let merged = null;
-    if (startIndex > 0) {
-      // 2. Try mering the preceding segment
-      const precedingSegment = this._segments[startIndex - 1];
-      merged = this._tryMerge(precedingSegment, newSegment);
-      if (merged) {
-        --startIndex;
-        newSegment = merged;
-      } else if (this._segments[startIndex - 1].end >= newSegment.begin) {
-        // 2a. If merge failed and segments overlap, adjust preceding segment.
-        // If an old segment entirely contains new one, split it in two.
-        if (newSegment.end < precedingSegment.end) {
-          this._segments.splice(
-              startIndex, 0, new Common.Segment(newSegment.end, precedingSegment.end, precedingSegment.data));
-        }
-        precedingSegment.end = newSegment.begin;
-      }
-    }
-    // 3. Consume all segments that are entirely covered by the new one.
-    while (endIndex < this._segments.length && this._segments[endIndex].end <= newSegment.end)
-      ++endIndex;
-    // 4. Merge or adjust the succeeding segment if it overlaps.
-    if (endIndex < this._segments.length) {
-      merged = this._tryMerge(newSegment, this._segments[endIndex]);
-      if (merged) {
-        endIndex++;
-        newSegment = merged;
-      } else if (newSegment.intersects(this._segments[endIndex])) {
-        this._segments[endIndex].begin = newSegment.end;
-      }
-    }
-    this._segments.splice(startIndex, endIndex - startIndex, newSegment);
-  }
-
-  /**
-   * @param {!Common.SegmentedRange} that
-   */
-  appendRange(that) {
-    that.segments().forEach(segment => this.append(segment));
-  }
-
-  /**
-   * @return {!Array<!Common.Segment>}
-   */
-  segments() {
-    return this._segments;
-  }
-
-  /**
-   * @param {!Common.Segment} first
-   * @param {!Common.Segment} second
-   * @return {?Common.Segment}
-   */
-  _tryMerge(first, second) {
-    const merged = this._mergeCallback && this._mergeCallback(first, second);
-    if (!merged)
-      return null;
-    merged.begin = first.begin;
-    merged.end = Math.max(first.end, second.end);
-    return merged;
-  }
-};
diff --git a/front_end/common/Settings.js b/front_end/common/Settings.js
deleted file mode 100644
index a5bcc63..0000000
--- a/front_end/common/Settings.js
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Common.Settings = class {
-  /**
-   * @param {!Common.SettingsStorage} globalStorage
-   * @param {!Common.SettingsStorage} localStorage
-   */
-  constructor(globalStorage, localStorage) {
-    this._globalStorage = globalStorage;
-    this._localStorage = localStorage;
-    this._sessionStorage = new Common.SettingsStorage({});
-
-    this._eventSupport = new Common.Object();
-    /** @type {!Map<string, !Common.Setting>} */
-    this._registry = new Map();
-    /** @type {!Map<string, !Common.Setting>} */
-    this._moduleSettings = new Map();
-    self.runtime.extensions('setting').forEach(this._registerModuleSetting.bind(this));
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  _registerModuleSetting(extension) {
-    const descriptor = extension.descriptor();
-    const settingName = descriptor['settingName'];
-    const isRegex = descriptor['settingType'] === 'regex';
-    const defaultValue = descriptor['defaultValue'];
-    let storageType;
-    switch (descriptor['storageType']) {
-      case ('local'):
-        storageType = Common.SettingStorageType.Local;
-        break;
-      case ('session'):
-        storageType = Common.SettingStorageType.Session;
-        break;
-      case ('global'):
-        storageType = Common.SettingStorageType.Global;
-        break;
-      default:
-        storageType = Common.SettingStorageType.Global;
-    }
-    const setting = isRegex ? this.createRegExpSetting(settingName, defaultValue, undefined, storageType) :
-                              this.createSetting(settingName, defaultValue, storageType);
-    if (descriptor['title'])
-      setting.setTitle(descriptor['title']);
-    if (descriptor['userActionCondition'])
-      setting.setRequiresUserAction(!!Runtime.queryParam(descriptor['userActionCondition']));
-    setting._extension = extension;
-    this._moduleSettings.set(settingName, setting);
-  }
-
-  /**
-   * @param {string} settingName
-   * @return {!Common.Setting}
-   */
-  moduleSetting(settingName) {
-    const setting = this._moduleSettings.get(settingName);
-    if (!setting)
-      throw new Error('No setting registered: ' + settingName);
-    return setting;
-  }
-
-  /**
-   * @param {string} settingName
-   * @return {!Common.Setting}
-   */
-  settingForTest(settingName) {
-    const setting = this._registry.get(settingName);
-    if (!setting)
-      throw new Error('No setting registered: ' + settingName);
-    return setting;
-  }
-
-  /**
-   * @param {string} key
-   * @param {*} defaultValue
-   * @param {!Common.SettingStorageType=} storageType
-   * @return {!Common.Setting}
-   */
-  createSetting(key, defaultValue, storageType) {
-    const storage = this._storageFromType(storageType);
-    if (!this._registry.get(key))
-      this._registry.set(key, new Common.Setting(this, key, defaultValue, this._eventSupport, storage));
-    return /** @type {!Common.Setting} */ (this._registry.get(key));
-  }
-
-  /**
-   * @param {string} key
-   * @param {*} defaultValue
-   * @return {!Common.Setting}
-   */
-  createLocalSetting(key, defaultValue) {
-    return this.createSetting(key, defaultValue, Common.SettingStorageType.Local);
-  }
-
-  /**
-   * @param {string} key
-   * @param {string} defaultValue
-   * @param {string=} regexFlags
-   * @param {!Common.SettingStorageType=} storageType
-   * @return {!Common.RegExpSetting}
-   */
-  createRegExpSetting(key, defaultValue, regexFlags, storageType) {
-    if (!this._registry.get(key)) {
-      this._registry.set(
-          key,
-          new Common.RegExpSetting(
-              this, key, defaultValue, this._eventSupport, this._storageFromType(storageType), regexFlags));
-    }
-    return /** @type {!Common.RegExpSetting} */ (this._registry.get(key));
-  }
-
-  clearAll() {
-    this._globalStorage.removeAll();
-    this._localStorage.removeAll();
-    const versionSetting = Common.settings.createSetting(Common.VersionController._currentVersionName, 0);
-    versionSetting.set(Common.VersionController.currentVersion);
-  }
-
-  /**
-   * @param {!Common.SettingStorageType=} storageType
-   * @return {!Common.SettingsStorage}
-   */
-  _storageFromType(storageType) {
-    switch (storageType) {
-      case (Common.SettingStorageType.Local):
-        return this._localStorage;
-      case (Common.SettingStorageType.Session):
-        return this._sessionStorage;
-      case (Common.SettingStorageType.Global):
-        return this._globalStorage;
-    }
-    return this._globalStorage;
-  }
-};
-
-/**
- * @unrestricted
- */
-Common.SettingsStorage = class {
-  /**
-   * @param {!Object} object
-   * @param {function(string, string)=} setCallback
-   * @param {function(string)=} removeCallback
-   * @param {function(string)=} removeAllCallback
-   * @param {string=} storagePrefix
-   */
-  constructor(object, setCallback, removeCallback, removeAllCallback, storagePrefix) {
-    this._object = object;
-    this._setCallback = setCallback || function() {};
-    this._removeCallback = removeCallback || function() {};
-    this._removeAllCallback = removeAllCallback || function() {};
-    this._storagePrefix = storagePrefix || '';
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   */
-  set(name, value) {
-    name = this._storagePrefix + name;
-    this._object[name] = value;
-    this._setCallback(name, value);
-  }
-
-  /**
-   * @param {string} name
-   * @return {boolean}
-   */
-  has(name) {
-    name = this._storagePrefix + name;
-    return name in this._object;
-  }
-
-  /**
-   * @param {string} name
-   * @return {string}
-   */
-  get(name) {
-    name = this._storagePrefix + name;
-    return this._object[name];
-  }
-
-  /**
-   * @param {string} name
-   */
-  remove(name) {
-    name = this._storagePrefix + name;
-    delete this._object[name];
-    this._removeCallback(name);
-  }
-
-  removeAll() {
-    this._object = {};
-    this._removeAllCallback();
-  }
-
-  _dumpSizes() {
-    Common.console.log('Ten largest settings: ');
-
-    const sizes = {__proto__: null};
-    for (const key in this._object)
-      sizes[key] = this._object[key].length;
-    const keys = Object.keys(sizes);
-
-    function comparator(key1, key2) {
-      return sizes[key2] - sizes[key1];
-    }
-
-    keys.sort(comparator);
-
-    for (let i = 0; i < 10 && i < keys.length; ++i)
-      Common.console.log('Setting: \'' + keys[i] + '\', size: ' + sizes[keys[i]]);
-  }
-};
-
-/**
- * @template V
- * @unrestricted
- */
-Common.Setting = class {
-  /**
-   * @param {!Common.Settings} settings
-   * @param {string} name
-   * @param {V} defaultValue
-   * @param {!Common.Object} eventSupport
-   * @param {!Common.SettingsStorage} storage
-   */
-  constructor(settings, name, defaultValue, eventSupport, storage) {
-    this._settings = settings;
-    this._name = name;
-    this._defaultValue = defaultValue;
-    this._eventSupport = eventSupport;
-    this._storage = storage;
-    /** @type {string} */
-    this._title = '';
-    this._extension = null;
-  }
-
-  /**
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  addChangeListener(listener, thisObject) {
-    this._eventSupport.addEventListener(this._name, listener, thisObject);
-  }
-
-  /**
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  removeChangeListener(listener, thisObject) {
-    this._eventSupport.removeEventListener(this._name, listener, thisObject);
-  }
-
-  get name() {
-    return this._name;
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    this._title = title;
-  }
-
-  /**
-   * @param {boolean} requiresUserAction
-   */
-  setRequiresUserAction(requiresUserAction) {
-    this._requiresUserAction = requiresUserAction;
-  }
-
-  /**
-   * @return {V}
-   */
-  get() {
-    if (this._requiresUserAction && !this._hadUserAction)
-      return this._defaultValue;
-
-    if (typeof this._value !== 'undefined')
-      return this._value;
-
-    this._value = this._defaultValue;
-    if (this._storage.has(this._name)) {
-      try {
-        this._value = JSON.parse(this._storage.get(this._name));
-      } catch (e) {
-        this._storage.remove(this._name);
-      }
-    }
-    return this._value;
-  }
-
-  /**
-   * @param {V} value
-   */
-  set(value) {
-    this._hadUserAction = true;
-    this._value = value;
-    try {
-      const settingString = JSON.stringify(value);
-      try {
-        this._storage.set(this._name, settingString);
-      } catch (e) {
-        this._printSettingsSavingError(e.message, this._name, settingString);
-      }
-    } catch (e) {
-      Common.console.error('Cannot stringify setting with name: ' + this._name + ', error: ' + e.message);
-    }
-    this._eventSupport.dispatchEventToListeners(this._name, value);
-  }
-
-  remove() {
-    this._settings._registry.delete(this._name);
-    this._settings._moduleSettings.delete(this._name);
-    this._storage.remove(this._name);
-  }
-
-  /**
-   * @return {?Runtime.Extension}
-   */
-  extension() {
-    return this._extension;
-  }
-
-  /**
-   * @param {string} message
-   * @param {string} name
-   * @param {string} value
-   */
-  _printSettingsSavingError(message, name, value) {
-    const errorMessage =
-        'Error saving setting with name: ' + this._name + ', value length: ' + value.length + '. Error: ' + message;
-    console.error(errorMessage);
-    Common.console.error(errorMessage);
-    this._storage._dumpSizes();
-  }
-};
-
-/**
- * @unrestricted
- */
-Common.RegExpSetting = class extends Common.Setting {
-  /**
-   * @param {!Common.Settings} settings
-   * @param {string} name
-   * @param {string} defaultValue
-   * @param {!Common.Object} eventSupport
-   * @param {!Common.SettingsStorage} storage
-   * @param {string=} regexFlags
-   */
-  constructor(settings, name, defaultValue, eventSupport, storage, regexFlags) {
-    super(settings, name, defaultValue ? [{pattern: defaultValue}] : [], eventSupport, storage);
-    this._regexFlags = regexFlags;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  get() {
-    const result = [];
-    const items = this.getAsArray();
-    for (let i = 0; i < items.length; ++i) {
-      const item = items[i];
-      if (item.pattern && !item.disabled)
-        result.push(item.pattern);
-    }
-    return result.join('|');
-  }
-
-  /**
-   * @return {!Array.<{pattern: string, disabled: (boolean|undefined)}>}
-   */
-  getAsArray() {
-    return super.get();
-  }
-
-  /**
-   * @override
-   * @param {string} value
-   */
-  set(value) {
-    this.setAsArray([{pattern: value}]);
-  }
-
-  /**
-   * @param {!Array.<{pattern: string, disabled: (boolean|undefined)}>} value
-   */
-  setAsArray(value) {
-    delete this._regex;
-    super.set(value);
-  }
-
-  /**
-   * @return {?RegExp}
-   */
-  asRegExp() {
-    if (typeof this._regex !== 'undefined')
-      return this._regex;
-    this._regex = null;
-    try {
-      const pattern = this.get();
-      if (pattern)
-        this._regex = new RegExp(pattern, this._regexFlags || '');
-    } catch (e) {
-    }
-    return this._regex;
-  }
-};
-
-/**
- * @unrestricted
- */
-Common.VersionController = class {
-  updateVersion() {
-    const localStorageVersion =
-        window.localStorage ? window.localStorage[Common.VersionController._currentVersionName] : 0;
-    const versionSetting = Common.settings.createSetting(Common.VersionController._currentVersionName, 0);
-    const currentVersion = Common.VersionController.currentVersion;
-    const oldVersion = versionSetting.get() || parseInt(localStorageVersion || '0', 10);
-    if (oldVersion === 0) {
-      // First run, no need to do anything.
-      versionSetting.set(currentVersion);
-      return;
-    }
-    const methodsToRun = this._methodsToRunToUpdateVersion(oldVersion, currentVersion);
-    for (let i = 0; i < methodsToRun.length; ++i)
-      this[methodsToRun[i]].call(this);
-    versionSetting.set(currentVersion);
-  }
-
-  /**
-   * @param {number} oldVersion
-   * @param {number} currentVersion
-   */
-  _methodsToRunToUpdateVersion(oldVersion, currentVersion) {
-    const result = [];
-    for (let i = oldVersion; i < currentVersion; ++i)
-      result.push('_updateVersionFrom' + i + 'To' + (i + 1));
-    return result;
-  }
-
-  _updateVersionFrom0To1() {
-    this._clearBreakpointsWhenTooMany(Common.settings.createLocalSetting('breakpoints', []), 500000);
-  }
-
-  _updateVersionFrom1To2() {
-    Common.settings.createSetting('previouslyViewedFiles', []).set([]);
-  }
-
-  _updateVersionFrom2To3() {
-    Common.settings.createSetting('fileSystemMapping', {}).set({});
-    Common.settings.createSetting('fileMappingEntries', []).remove();
-  }
-
-  _updateVersionFrom3To4() {
-    const advancedMode = Common.settings.createSetting('showHeaSnapshotObjectsHiddenProperties', false);
-    Common.moduleSetting('showAdvancedHeapSnapshotProperties').set(advancedMode.get());
-    advancedMode.remove();
-  }
-
-  _updateVersionFrom4To5() {
-    const settingNames = {
-      'FileSystemViewSidebarWidth': 'fileSystemViewSplitViewState',
-      'elementsSidebarWidth': 'elementsPanelSplitViewState',
-      'StylesPaneSplitRatio': 'stylesPaneSplitViewState',
-      'heapSnapshotRetainersViewSize': 'heapSnapshotSplitViewState',
-      'InspectorView.splitView': 'InspectorView.splitViewState',
-      'InspectorView.screencastSplitView': 'InspectorView.screencastSplitViewState',
-      'Inspector.drawerSplitView': 'Inspector.drawerSplitViewState',
-      'layerDetailsSplitView': 'layerDetailsSplitViewState',
-      'networkSidebarWidth': 'networkPanelSplitViewState',
-      'sourcesSidebarWidth': 'sourcesPanelSplitViewState',
-      'scriptsPanelNavigatorSidebarWidth': 'sourcesPanelNavigatorSplitViewState',
-      'sourcesPanelSplitSidebarRatio': 'sourcesPanelDebuggerSidebarSplitViewState',
-      'timeline-details': 'timelinePanelDetailsSplitViewState',
-      'timeline-split': 'timelinePanelRecorsSplitViewState',
-      'timeline-view': 'timelinePanelTimelineStackSplitViewState',
-      'auditsSidebarWidth': 'auditsPanelSplitViewState',
-      'layersSidebarWidth': 'layersPanelSplitViewState',
-      'profilesSidebarWidth': 'profilesPanelSplitViewState',
-      'resourcesSidebarWidth': 'resourcesPanelSplitViewState'
-    };
-    const empty = {};
-    for (const oldName in settingNames) {
-      const newName = settingNames[oldName];
-      const oldNameH = oldName + 'H';
-
-      let newValue = null;
-      const oldSetting = Common.settings.createSetting(oldName, empty);
-      if (oldSetting.get() !== empty) {
-        newValue = newValue || {};
-        newValue.vertical = {};
-        newValue.vertical.size = oldSetting.get();
-        oldSetting.remove();
-      }
-      const oldSettingH = Common.settings.createSetting(oldNameH, empty);
-      if (oldSettingH.get() !== empty) {
-        newValue = newValue || {};
-        newValue.horizontal = {};
-        newValue.horizontal.size = oldSettingH.get();
-        oldSettingH.remove();
-      }
-      if (newValue)
-        Common.settings.createSetting(newName, {}).set(newValue);
-    }
-  }
-
-  _updateVersionFrom5To6() {
-    const settingNames = {
-      'debuggerSidebarHidden': 'sourcesPanelSplitViewState',
-      'navigatorHidden': 'sourcesPanelNavigatorSplitViewState',
-      'WebInspector.Drawer.showOnLoad': 'Inspector.drawerSplitViewState'
-    };
-
-    for (const oldName in settingNames) {
-      const oldSetting = Common.settings.createSetting(oldName, null);
-      if (oldSetting.get() === null) {
-        oldSetting.remove();
-        continue;
-      }
-
-      const newName = settingNames[oldName];
-      const invert = oldName === 'WebInspector.Drawer.showOnLoad';
-      const hidden = oldSetting.get() !== invert;
-      oldSetting.remove();
-      const showMode = hidden ? 'OnlyMain' : 'Both';
-
-      const newSetting = Common.settings.createSetting(newName, {});
-      const newValue = newSetting.get() || {};
-      newValue.vertical = newValue.vertical || {};
-      newValue.vertical.showMode = showMode;
-      newValue.horizontal = newValue.horizontal || {};
-      newValue.horizontal.showMode = showMode;
-      newSetting.set(newValue);
-    }
-  }
-
-  _updateVersionFrom6To7() {
-    const settingNames = {
-      'sourcesPanelNavigatorSplitViewState': 'sourcesPanelNavigatorSplitViewState',
-      'elementsPanelSplitViewState': 'elementsPanelSplitViewState',
-      'stylesPaneSplitViewState': 'stylesPaneSplitViewState',
-      'sourcesPanelDebuggerSidebarSplitViewState': 'sourcesPanelDebuggerSidebarSplitViewState'
-    };
-
-    const empty = {};
-    for (const name in settingNames) {
-      const setting = Common.settings.createSetting(name, empty);
-      const value = setting.get();
-      if (value === empty)
-        continue;
-      // Zero out saved percentage sizes, and they will be restored to defaults.
-      if (value.vertical && value.vertical.size && value.vertical.size < 1)
-        value.vertical.size = 0;
-      if (value.horizontal && value.horizontal.size && value.horizontal.size < 1)
-        value.horizontal.size = 0;
-      setting.set(value);
-    }
-  }
-
-  _updateVersionFrom7To8() {
-  }
-
-  _updateVersionFrom8To9() {
-    const settingNames = ['skipStackFramesPattern', 'workspaceFolderExcludePattern'];
-
-    for (let i = 0; i < settingNames.length; ++i) {
-      const setting = Common.settings.createSetting(settingNames[i], '');
-      let value = setting.get();
-      if (!value)
-        return;
-      if (typeof value === 'string')
-        value = [value];
-      for (let j = 0; j < value.length; ++j) {
-        if (typeof value[j] === 'string')
-          value[j] = {pattern: value[j]};
-      }
-      setting.set(value);
-    }
-  }
-
-  _updateVersionFrom9To10() {
-    // This one is localStorage specific, which is fine.
-    if (!window.localStorage)
-      return;
-    for (const key in window.localStorage) {
-      if (key.startsWith('revision-history'))
-        window.localStorage.removeItem(key);
-    }
-  }
-
-  _updateVersionFrom10To11() {
-    const oldSettingName = 'customDevicePresets';
-    const newSettingName = 'customEmulatedDeviceList';
-    const oldSetting = Common.settings.createSetting(oldSettingName, undefined);
-    const list = oldSetting.get();
-    if (!Array.isArray(list))
-      return;
-    const newList = [];
-    for (let i = 0; i < list.length; ++i) {
-      const value = list[i];
-      const device = {};
-      device['title'] = value['title'];
-      device['type'] = 'unknown';
-      device['user-agent'] = value['userAgent'];
-      device['capabilities'] = [];
-      if (value['touch'])
-        device['capabilities'].push('touch');
-      if (value['mobile'])
-        device['capabilities'].push('mobile');
-      device['screen'] = {};
-      device['screen']['vertical'] = {width: value['width'], height: value['height']};
-      device['screen']['horizontal'] = {width: value['height'], height: value['width']};
-      device['screen']['device-pixel-ratio'] = value['deviceScaleFactor'];
-      device['modes'] = [];
-      device['show-by-default'] = true;
-      device['show'] = 'Default';
-      newList.push(device);
-    }
-    if (newList.length)
-      Common.settings.createSetting(newSettingName, []).set(newList);
-    oldSetting.remove();
-  }
-
-  _updateVersionFrom11To12() {
-    this._migrateSettingsFromLocalStorage();
-  }
-
-  _updateVersionFrom12To13() {
-    this._migrateSettingsFromLocalStorage();
-    Common.settings.createSetting('timelineOverviewMode', '').remove();
-  }
-
-  _updateVersionFrom13To14() {
-    const defaultValue = {'throughput': -1, 'latency': 0};
-    Common.settings.createSetting('networkConditions', defaultValue).set(defaultValue);
-  }
-
-  _updateVersionFrom14To15() {
-    const setting = Common.settings.createLocalSetting('workspaceExcludedFolders', {});
-    const oldValue = setting.get();
-    const newValue = {};
-    for (const fileSystemPath in oldValue) {
-      newValue[fileSystemPath] = [];
-      for (const entry of oldValue[fileSystemPath])
-        newValue[fileSystemPath].push(entry.path);
-    }
-    setting.set(newValue);
-  }
-
-  _updateVersionFrom15To16() {
-    const setting = Common.settings.createSetting('InspectorView.panelOrder', {});
-    const tabOrders = setting.get();
-    for (const key of Object.keys(tabOrders))
-      tabOrders[key] = (tabOrders[key] + 1) * 10;
-    setting.set(tabOrders);
-  }
-
-  _updateVersionFrom16To17() {
-    const setting = Common.settings.createSetting('networkConditionsCustomProfiles', []);
-    const oldValue = setting.get();
-    const newValue = [];
-    if (Array.isArray(oldValue)) {
-      for (const preset of oldValue) {
-        if (typeof preset.title === 'string' && typeof preset.value === 'object' &&
-            typeof preset.value.throughput === 'number' && typeof preset.value.latency === 'number') {
-          newValue.push({
-            title: preset.title,
-            value:
-                {download: preset.value.throughput, upload: preset.value.throughput, latency: preset.value.latency}
-          });
-        }
-      }
-    }
-    setting.set(newValue);
-  }
-
-  _updateVersionFrom17To18() {
-    const setting = Common.settings.createLocalSetting('workspaceExcludedFolders', {});
-    const oldValue = setting.get();
-    const newValue = {};
-    for (const oldKey in oldValue) {
-      let newKey = oldKey.replace(/\\/g, '/');
-      if (!newKey.startsWith('file://')) {
-        if (newKey.startsWith('/'))
-          newKey = 'file://' + newKey;
-        else
-          newKey = 'file:///' + newKey;
-      }
-      newValue[newKey] = oldValue[oldKey];
-    }
-    setting.set(newValue);
-  }
-
-  _updateVersionFrom18To19() {
-    const defaultColumns = {status: true, type: true, initiator: true, size: true, time: true};
-    const visibleColumnSettings = Common.settings.createSetting('networkLogColumnsVisibility', defaultColumns);
-    const visibleColumns = visibleColumnSettings.get();
-    visibleColumns.name = true;
-    visibleColumns.timeline = true;
-
-    const configs = {};
-    for (const columnId in visibleColumns) {
-      if (!visibleColumns.hasOwnProperty(columnId))
-        continue;
-      configs[columnId.toLowerCase()] = {visible: visibleColumns[columnId]};
-    }
-    const newSetting = Common.settings.createSetting('networkLogColumns', {});
-    newSetting.set(configs);
-    visibleColumnSettings.remove();
-  }
-
-  _updateVersionFrom19To20() {
-    const oldSetting = Common.settings.createSetting('InspectorView.panelOrder', {});
-    const newSetting = Common.settings.createSetting('panel-tabOrder', {});
-    newSetting.set(oldSetting.get());
-    oldSetting.remove();
-  }
-
-  _updateVersionFrom20To21() {
-    const networkColumns = Common.settings.createSetting('networkLogColumns', {});
-    const columns = /** @type {!Object} */ (networkColumns.get());
-    delete columns['timeline'];
-    delete columns['waterfall'];
-    networkColumns.set(columns);
-  }
-
-  _updateVersionFrom21To22() {
-    const breakpointsSetting = Common.settings.createLocalSetting('breakpoints', []);
-    const breakpoints = breakpointsSetting.get();
-    for (const breakpoint of breakpoints) {
-      breakpoint['url'] = breakpoint['sourceFileId'];
-      delete breakpoint['sourceFileId'];
-    }
-    breakpointsSetting.set(breakpoints);
-  }
-
-  _updateVersionFrom22To23() {
-    // This update is no-op.
-  }
-
-  _updateVersionFrom23To24() {
-    const oldSetting = Common.settings.createSetting('searchInContentScripts', false);
-    const newSetting = Common.settings.createSetting('searchInAnonymousAndContentScripts', false);
-    newSetting.set(oldSetting.get());
-    oldSetting.remove();
-  }
-
-  _updateVersionFrom24To25() {
-    const defaultColumns = {status: true, type: true, initiator: true, size: true, time: true};
-    const networkLogColumnsSetting = Common.settings.createSetting('networkLogColumns', defaultColumns);
-    const columns = networkLogColumnsSetting.get();
-    delete columns.product;
-    networkLogColumnsSetting.set(columns);
-  }
-
-  _migrateSettingsFromLocalStorage() {
-    // This step migrates all the settings except for the ones below into the browser profile.
-    const localSettings = new Set([
-      'advancedSearchConfig', 'breakpoints', 'consoleHistory', 'domBreakpoints', 'eventListenerBreakpoints',
-      'fileSystemMapping', 'lastSelectedSourcesSidebarPaneTab', 'previouslyViewedFiles', 'savedURLs',
-      'watchExpressions', 'workspaceExcludedFolders', 'xhrBreakpoints'
-    ]);
-    if (!window.localStorage)
-      return;
-
-    for (const key in window.localStorage) {
-      if (localSettings.has(key))
-        continue;
-      const value = window.localStorage[key];
-      window.localStorage.removeItem(key);
-      Common.settings._globalStorage[key] = value;
-    }
-  }
-
-  /**
-   * @param {!Common.Setting} breakpointsSetting
-   * @param {number} maxBreakpointsCount
-   */
-  _clearBreakpointsWhenTooMany(breakpointsSetting, maxBreakpointsCount) {
-    // If there are too many breakpoints in a storage, it is likely due to a recent bug that caused
-    // periodical breakpoints duplication leading to inspector slowness.
-    if (breakpointsSetting.get().length > maxBreakpointsCount)
-      breakpointsSetting.set([]);
-  }
-};
-
-Common.VersionController._currentVersionName = 'inspectorVersion';
-Common.VersionController.currentVersion = 25;
-
-/**
- * @type {!Common.Settings}
- */
-Common.settings;
-
-/**
- * @enum {symbol}
- */
-Common.SettingStorageType = {
-  Global: Symbol('Global'),
-  Local: Symbol('Local'),
-  Session: Symbol('Session')
-};
-
-/**
- * @param {string} settingName
- * @return {!Common.Setting}
- */
-Common.moduleSetting = function(settingName) {
-  return Common.settings.moduleSetting(settingName);
-};
-
-/**
- * @param {string} settingName
- * @return {!Common.Setting}
- */
-Common.settingForTest = function(settingName) {
-  return Common.settings.settingForTest(settingName);
-};
diff --git a/front_end/common/StaticContentProvider.js b/front_end/common/StaticContentProvider.js
deleted file mode 100644
index f871b5b..0000000
--- a/front_end/common/StaticContentProvider.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-Common.StaticContentProvider = class {
-  /**
-   * @param {string} contentURL
-   * @param {!Common.ResourceType} contentType
-   * @param {function():!Promise<?string>} lazyContent
-   */
-  constructor(contentURL, contentType, lazyContent) {
-    this._contentURL = contentURL;
-    this._contentType = contentType;
-    this._lazyContent = lazyContent;
-  }
-
-  /**
-   * @param {string} contentURL
-   * @param {!Common.ResourceType} contentType
-   * @param {string} content
-   * @return {!Common.StaticContentProvider}
-   */
-  static fromString(contentURL, contentType, content) {
-    const lazyContent = () => Promise.resolve(content);
-    return new Common.StaticContentProvider(contentURL, contentType, lazyContent);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._contentURL;
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._contentType;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    return this._lazyContent();
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  async searchInContent(query, caseSensitive, isRegex) {
-    const content = await this._lazyContent();
-    return content ? Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex) : [];
-  }
-};
diff --git a/front_end/common/TextDictionary.js b/front_end/common/TextDictionary.js
deleted file mode 100644
index 9c555b2..0000000
--- a/front_end/common/TextDictionary.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Common.TextDictionary = class {
-  constructor() {
-    /** @type {!Map<string, number>} */
-    this._words = new Map();
-    this._index = new Common.Trie();
-  }
-
-  /**
-   * @param {string} word
-   */
-  addWord(word) {
-    let count = this._words.get(word) || 0;
-    ++count;
-    this._words.set(word, count);
-    this._index.add(word);
-  }
-
-  /**
-   * @param {string} word
-   */
-  removeWord(word) {
-    let count = this._words.get(word) || 0;
-    if (!count)
-      return;
-    if (count === 1) {
-      this._words.delete(word);
-      this._index.remove(word);
-      return;
-    }
-    --count;
-    this._words.set(word, count);
-  }
-
-  /**
-   * @param {string} prefix
-   * @return {!Array.<string>}
-   */
-  wordsWithPrefix(prefix) {
-    return this._index.words(prefix);
-  }
-
-  /**
-   * @param {string} word
-   * @return {boolean}
-   */
-  hasWord(word) {
-    return this._words.has(word);
-  }
-
-  /**
-   * @param {string} word
-   * @return {number}
-   */
-  wordCount(word) {
-    return this._words.get(word) || 0;
-  }
-
-  reset() {
-    this._words.clear();
-    this._index.clear();
-  }
-};
diff --git a/front_end/common/Throttler.js b/front_end/common/Throttler.js
deleted file mode 100644
index a88e78f..0000000
--- a/front_end/common/Throttler.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Common.Throttler = class {
-  /**
-   * @param {number} timeout
-   */
-  constructor(timeout) {
-    this._timeout = timeout;
-    this._isRunningProcess = false;
-    this._asSoonAsPossible = false;
-    /** @type {?function():(!Promise.<?>)} */
-    this._process = null;
-    this._lastCompleteTime = 0;
-
-    this._schedulePromise = new Promise(fulfill => {
-      this._scheduleResolve = fulfill;
-    });
-  }
-
-  _processCompleted() {
-    this._lastCompleteTime = this._getTime();
-    this._isRunningProcess = false;
-    if (this._process)
-      this._innerSchedule(false);
-    this._processCompletedForTests();
-  }
-
-  _processCompletedForTests() {
-    // For sniffing in tests.
-  }
-
-  _onTimeout() {
-    delete this._processTimeout;
-    this._asSoonAsPossible = false;
-    this._isRunningProcess = true;
-
-    Promise.resolve()
-        .then(this._process)
-        .catch(console.error.bind(console))
-        .then(this._processCompleted.bind(this))
-        .then(this._scheduleResolve);
-    this._schedulePromise = new Promise(fulfill => {
-      this._scheduleResolve = fulfill;
-    });
-    this._process = null;
-  }
-
-  /**
-   * @param {function():(!Promise.<?>)} process
-   * @param {boolean=} asSoonAsPossible
-   * @return {!Promise}
-   */
-  schedule(process, asSoonAsPossible) {
-    // Deliberately skip previous process.
-    this._process = process;
-
-    // Run the first scheduled task instantly.
-    const hasScheduledTasks = !!this._processTimeout || this._isRunningProcess;
-    const okToFire = this._getTime() - this._lastCompleteTime > this._timeout;
-    asSoonAsPossible = !!asSoonAsPossible || (!hasScheduledTasks && okToFire);
-
-    const forceTimerUpdate = asSoonAsPossible && !this._asSoonAsPossible;
-    this._asSoonAsPossible = this._asSoonAsPossible || asSoonAsPossible;
-
-    this._innerSchedule(forceTimerUpdate);
-
-    return this._schedulePromise;
-  }
-
-  /**
-   * @param {boolean} forceTimerUpdate
-   */
-  _innerSchedule(forceTimerUpdate) {
-    if (this._isRunningProcess)
-      return;
-    if (this._processTimeout && !forceTimerUpdate)
-      return;
-    if (this._processTimeout)
-      this._clearTimeout(this._processTimeout);
-
-    const timeout = this._asSoonAsPossible ? 0 : this._timeout;
-    this._processTimeout = this._setTimeout(this._onTimeout.bind(this), timeout);
-  }
-
-  /**
-   *  @param {number} timeoutId
-   */
-  _clearTimeout(timeoutId) {
-    clearTimeout(timeoutId);
-  }
-
-  /**
-   * @param {function()} operation
-   * @param {number} timeout
-   * @return {number}
-   */
-  _setTimeout(operation, timeout) {
-    return setTimeout(operation, timeout);
-  }
-
-  /**
-   * @return {number}
-   */
-  _getTime() {
-    return window.performance.now();
-  }
-};
-
-/** @typedef {function(!Error=)} */
-Common.Throttler.FinishCallback;
diff --git a/front_end/common/Trie.js b/front_end/common/Trie.js
deleted file mode 100644
index 98291c5..0000000
--- a/front_end/common/Trie.js
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Common.Trie = class {
-  constructor() {
-    this.clear();
-  }
-
-  /**
-   * @param {string} word
-   */
-  add(word) {
-    let node = this._root;
-    ++this._wordsInSubtree[this._root];
-    for (let i = 0; i < word.length; ++i) {
-      const edge = word[i];
-      let next = this._edges[node][edge];
-      if (!next) {
-        if (this._freeNodes.length) {
-          // No need to reset any fields since they were properly cleaned up in remove().
-          next = this._freeNodes.pop();
-        } else {
-          next = this._size++;
-          this._isWord.push(false);
-          this._wordsInSubtree.push(0);
-          this._edges.push({__proto__: null});
-        }
-        this._edges[node][edge] = next;
-      }
-      ++this._wordsInSubtree[next];
-      node = next;
-    }
-    this._isWord[node] = true;
-  }
-
-  /**
-   * @param {string} word
-   * @return {boolean}
-   */
-  remove(word) {
-    if (!this.has(word))
-      return false;
-    let node = this._root;
-    --this._wordsInSubtree[this._root];
-    for (let i = 0; i < word.length; ++i) {
-      const edge = word[i];
-      const next = this._edges[node][edge];
-      if (!--this._wordsInSubtree[next]) {
-        delete this._edges[node][edge];
-        this._freeNodes.push(next);
-      }
-      node = next;
-    }
-    this._isWord[node] = false;
-    return true;
-  }
-
-  /**
-   * @param {string} word
-   * @return {boolean}
-   */
-  has(word) {
-    let node = this._root;
-    for (let i = 0; i < word.length; ++i) {
-      node = this._edges[node][word[i]];
-      if (!node)
-        return false;
-    }
-    return this._isWord[node];
-  }
-
-  /**
-   * @param {string=} prefix
-   * @return {!Array<string>}
-   */
-  words(prefix) {
-    prefix = prefix || '';
-    let node = this._root;
-    for (let i = 0; i < prefix.length; ++i) {
-      node = this._edges[node][prefix[i]];
-      if (!node)
-        return [];
-    }
-    const results = [];
-    this._dfs(node, prefix, results);
-    return results;
-  }
-
-  /**
-   * @param {number} node
-   * @param {string} prefix
-   * @param {!Array<string>} results
-   */
-  _dfs(node, prefix, results) {
-    if (this._isWord[node])
-      results.push(prefix);
-    const edges = this._edges[node];
-    for (const edge in edges)
-      this._dfs(edges[edge], prefix + edge, results);
-  }
-
-  /**
-   * @param {string} word
-   * @param {boolean} fullWordOnly
-   * @return {string}
-   */
-  longestPrefix(word, fullWordOnly) {
-    let node = this._root;
-    let wordIndex = 0;
-    for (let i = 0; i < word.length; ++i) {
-      node = this._edges[node][word[i]];
-      if (!node)
-        break;
-      if (!fullWordOnly || this._isWord[node])
-        wordIndex = i + 1;
-    }
-    return word.substring(0, wordIndex);
-  }
-
-  clear() {
-    this._size = 1;
-    this._root = 0;
-    /** @type {!Array<!Object<string, number>>} */
-    this._edges = [{__proto__: null}];
-    /** @type {!Array<boolean>} */
-    this._isWord = [false];
-    /** @type {!Array<number>} */
-    this._wordsInSubtree = [0];
-    /** @type {!Array<number>} */
-    this._freeNodes = [];
-  }
-};
diff --git a/front_end/common/UIString.js b/front_end/common/UIString.js
deleted file mode 100644
index 7bd56dd..0000000
--- a/front_end/common/UIString.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.  All rights reserved.
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-self['Common'] = self['Common'] || {};
-
-/**
- * @param {string} string
- * @param {...*} vararg
- * @return {string}
- */
-Common.UIString = function(string, vararg) {
-  return String.vsprintf(Common.localize(string), Array.prototype.slice.call(arguments, 1));
-};
-
-/**
- * @param {string} string
- * @return {string}
- */
-Common.localize = function(string) {
-  return string;
-};
-
-/**
- * @unrestricted
- */
-Common.UIStringFormat = class {
-  /**
-   * @param {string} format
-   */
-  constructor(format) {
-    /** @type {string} */
-    this._localizedFormat = Common.localize(format);
-    /** @type {!Array.<!Object>} */
-    this._tokenizedFormat = String.tokenizeFormatString(this._localizedFormat, String.standardFormatters);
-  }
-
-  /**
-   * @param {string} a
-   * @param {string} b
-   * @return {string}
-   */
-  static _append(a, b) {
-    return a + b;
-  }
-
-  /**
-   * @param {...*} vararg
-   * @return {string}
-   */
-  format(vararg) {
-    return String
-        .format(
-            this._localizedFormat, arguments, String.standardFormatters, '', Common.UIStringFormat._append,
-            this._tokenizedFormat)
-        .formattedResult;
-  }
-};
-
-
-/**
- * @param {!Array<string>|string} strings
- * @param {...*} vararg
- * @return {string}
- */
-self.ls = function(strings, vararg) {
-  if (typeof strings === 'string')
-    return strings;
-  const values = Array.prototype.slice.call(arguments, 1);
-  if (!values.length)
-    return strings[0];
-  let result = '';
-  for (let i = 0; i < values.length; i++) {
-    result += strings[i];
-    result += '' + values[i];
-  }
-  return result + strings[values.length];
-};
diff --git a/front_end/common/Worker.js b/front_end/common/Worker.js
deleted file mode 100644
index 5bdaced..0000000
--- a/front_end/common/Worker.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Common.Worker = class {
-  /**
-   * @param {string} appName
-   */
-  constructor(appName) {
-    let url = appName + '.js';
-    url += Runtime.queryParamsString();
-
-    /** @type {!Promise<!Worker>} */
-    this._workerPromise = new Promise(fulfill => {
-      this._worker = new Worker(url);
-      this._worker.onmessage = onMessage.bind(this);
-
-      /**
-       * @param {!Event} event
-       * @this {Common.Worker}
-       */
-      function onMessage(event) {
-        console.assert(event.data === 'workerReady');
-        this._worker.onmessage = null;
-        fulfill(this._worker);
-        // No need to hold a reference to worker anymore as it's stored in
-        // the resolved promise.
-        this._worker = null;
-      }
-    });
-  }
-
-  /**
-   * @param {*} message
-   */
-  postMessage(message) {
-    this._workerPromise.then(worker => {
-      if (!this._disposed)
-        worker.postMessage(message);
-    });
-  }
-
-  dispose() {
-    this._disposed = true;
-    this._workerPromise.then(worker => worker.terminate());
-  }
-
-  terminate() {
-    this.dispose();
-  }
-
-  /**
-   * @param {?function(!MessageEvent<*>)} listener
-   */
-  set onmessage(listener) {
-    this._workerPromise.then(worker => worker.onmessage = listener);
-  }
-
-  /**
-   * @param {?function(!Event)} listener
-   */
-  set onerror(listener) {
-    this._workerPromise.then(worker => worker.onerror = listener);
-  }
-};
diff --git a/front_end/common/module.json b/front_end/common/module.json
deleted file mode 100644
index 99b5427..0000000
--- a/front_end/common/module.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    "dependencies": [
-        "text_utils",
-        "platform"
-    ],
-    "scripts": [
-        "Worker.js",
-        "TextDictionary.js",
-        "Object.js",
-        "Color.js",
-        "Console.js",
-        "ContentProvider.js",
-        "ParsedURL.js",
-        "Progress.js",
-        "ResourceType.js",
-        "Settings.js",
-        "StaticContentProvider.js",
-        "OutputStream.js",
-        "SegmentedRange.js",
-        "Throttler.js",
-        "Trie.js",
-        "UIString.js",
-        "ModuleExtensionInterfaces.js",
-        "CharacterIdMap.js"
-    ]
-}
diff --git a/front_end/components/DockController.js b/front_end/components/DockController.js
deleted file mode 100644
index 801f25d..0000000
--- a/front_end/components/DockController.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Components.DockController = class extends Common.Object {
-  /**
-   * @param {boolean} canDock
-   */
-  constructor(canDock) {
-    super();
-    this._canDock = canDock;
-
-    this._closeButton = new UI.ToolbarButton(Common.UIString('Close'), 'largeicon-delete');
-    this._closeButton.addEventListener(
-        UI.ToolbarButton.Events.Click, InspectorFrontendHost.closeWindow.bind(InspectorFrontendHost));
-
-    if (!canDock) {
-      this._dockSide = Components.DockController.State.Undocked;
-      this._closeButton.setVisible(false);
-      return;
-    }
-
-    this._states = [
-      Components.DockController.State.DockedToRight, Components.DockController.State.DockedToBottom,
-      Components.DockController.State.DockedToLeft, Components.DockController.State.Undocked
-    ];
-    this._currentDockStateSetting = Common.settings.moduleSetting('currentDockState');
-    this._currentDockStateSetting.addChangeListener(this._dockSideChanged, this);
-    this._lastDockStateSetting = Common.settings.createSetting('lastDockState', 'bottom');
-    if (this._states.indexOf(this._currentDockStateSetting.get()) === -1)
-      this._currentDockStateSetting.set('right');
-    if (this._states.indexOf(this._lastDockStateSetting.get()) === -1)
-      this._currentDockStateSetting.set('bottom');
-  }
-
-  initialize() {
-    if (!this._canDock)
-      return;
-
-    this._titles = [
-      Common.UIString('Dock to right'), Common.UIString('Dock to bottom'), Common.UIString('Dock to left'),
-      Common.UIString('Undock into separate window')
-    ];
-    this._dockSideChanged();
-  }
-
-  _dockSideChanged() {
-    this.setDockSide(this._currentDockStateSetting.get());
-  }
-
-  /**
-   * @return {string}
-   */
-  dockSide() {
-    return this._dockSide;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canDock() {
-    return this._canDock;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isVertical() {
-    return this._dockSide === Components.DockController.State.DockedToRight ||
-        this._dockSide === Components.DockController.State.DockedToLeft;
-  }
-
-  /**
-   * @param {string} dockSide
-   * @suppressGlobalPropertiesCheck
-   */
-  setDockSide(dockSide) {
-    if (this._states.indexOf(dockSide) === -1)
-      dockSide = this._states[0];
-
-    if (this._dockSide === dockSide)
-      return;
-
-    if (this._dockSide)
-      this._lastDockStateSetting.set(this._dockSide);
-
-    this._savedFocus = document.deepActiveElement();
-    const eventData = {from: this._dockSide, to: dockSide};
-    this.dispatchEventToListeners(Components.DockController.Events.BeforeDockSideChanged, eventData);
-    console.timeStamp('DockController.setIsDocked');
-    this._dockSide = dockSide;
-    this._currentDockStateSetting.set(dockSide);
-    InspectorFrontendHost.setIsDocked(
-        dockSide !== Components.DockController.State.Undocked, this._setIsDockedResponse.bind(this, eventData));
-    this._closeButton.setVisible(this._dockSide !== Components.DockController.State.Undocked);
-    this.dispatchEventToListeners(Components.DockController.Events.DockSideChanged, eventData);
-  }
-
-  /**
-   * @param {{from: string, to: string}} eventData
-   */
-  _setIsDockedResponse(eventData) {
-    this.dispatchEventToListeners(Components.DockController.Events.AfterDockSideChanged, eventData);
-    if (this._savedFocus) {
-      this._savedFocus.focus();
-      this._savedFocus = null;
-    }
-  }
-
-  _toggleDockSide() {
-    if (this._lastDockStateSetting.get() === this._currentDockStateSetting.get()) {
-      const index = this._states.indexOf(this._currentDockStateSetting.get()) || 0;
-      this._lastDockStateSetting.set(this._states[(index + 1) % this._states.length]);
-    }
-    this.setDockSide(this._lastDockStateSetting.get());
-  }
-};
-
-Components.DockController.State = {
-  DockedToBottom: 'bottom',
-  DockedToRight: 'right',
-  DockedToLeft: 'left',
-  Undocked: 'undocked'
-};
-
-// Use BeforeDockSideChanged to do something before all the UI bits are updated,
-// DockSideChanged to update UI, and AfterDockSideChanged to perform actions
-// after frontend is docked/undocked in the browser.
-
-/** @enum {symbol} */
-Components.DockController.Events = {
-  BeforeDockSideChanged: Symbol('BeforeDockSideChanged'),
-  DockSideChanged: Symbol('DockSideChanged'),
-  AfterDockSideChanged: Symbol('AfterDockSideChanged')
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Components.DockController.ToggleDockActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    Components.dockController._toggleDockSide();
-    return true;
-  }
-};
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- * @unrestricted
- */
-Components.DockController.CloseButtonProvider = class {
-  /**
-   * @override
-   * @return {?UI.ToolbarItem}
-   */
-  item() {
-    return Components.dockController._closeButton;
-  }
-};
-
-/**
- * @type {!Components.DockController}
- */
-Components.dockController;
diff --git a/front_end/components/JSPresentationUtils.js b/front_end/components/JSPresentationUtils.js
deleted file mode 100644
index 9dd411d..0000000
--- a/front_end/components/JSPresentationUtils.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.  All rights reserved.
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-Components.JSPresentationUtils = {};
-
-/**
- * @param {?SDK.Target} target
- * @param {!Components.Linkifier} linkifier
- * @param {!Protocol.Runtime.StackTrace=} stackTrace
- * @param {function()=} contentUpdated
- * @return {!Element}
- */
-Components.JSPresentationUtils.buildStackTracePreviewContents = function(
-    target, linkifier, stackTrace, contentUpdated) {
-  const element = createElement('span');
-  element.style.display = 'inline-block';
-  const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css');
-  const contentElement = shadowRoot.createChild('table', 'stack-preview-container');
-  const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
-  let totalHiddenCallFramesCount = 0;
-
-  /**
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   * @return {boolean}
-   */
-  function appendStackTrace(stackTrace) {
-    let hiddenCallFrames = 0;
-    for (const stackFrame of stackTrace.callFrames) {
-      const row = createElement('tr');
-      row.createChild('td').textContent = '\n';
-      row.createChild('td', 'function-name').textContent = UI.beautifyFunctionName(stackFrame.functionName);
-      const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame);
-      if (link) {
-        link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
-        if (debuggerModel) {
-          const location = debuggerModel.createRawLocationByScriptId(
-              stackFrame.scriptId, stackFrame.lineNumber, stackFrame.columnNumber);
-          if (location && Bindings.blackboxManager.isBlackboxedRawLocation(location)) {
-            row.classList.add('blackboxed');
-            ++hiddenCallFrames;
-          }
-        }
-
-        row.createChild('td').textContent = ' @ ';
-        row.createChild('td').appendChild(link);
-      }
-      contentElement.appendChild(row);
-    }
-    totalHiddenCallFramesCount += hiddenCallFrames;
-    return stackTrace.callFrames.length === hiddenCallFrames;
-  }
-
-  /**
-   * @param {!Element} link
-   * @param {!Event} event
-   */
-  function populateContextMenu(link, event) {
-    const contextMenu = new UI.ContextMenu(event);
-    event.consume(true);
-    const uiLocation = Components.Linkifier.uiLocation(link);
-    if (uiLocation && Bindings.blackboxManager.canBlackboxUISourceCode(uiLocation.uiSourceCode)) {
-      if (Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) {
-        contextMenu.debugSection().appendItem(
-            ls`Stop blackboxing`, () => Bindings.blackboxManager.unblackboxUISourceCode(uiLocation.uiSourceCode));
-      } else {
-        contextMenu.debugSection().appendItem(
-            ls`Blackbox script`, () => Bindings.blackboxManager.blackboxUISourceCode(uiLocation.uiSourceCode));
-      }
-    }
-    contextMenu.appendApplicableItems(event);
-    contextMenu.show();
-  }
-
-  if (!stackTrace)
-    return element;
-
-  appendStackTrace(stackTrace);
-
-  let asyncStackTrace = stackTrace.parent;
-  while (asyncStackTrace) {
-    if (!asyncStackTrace.callFrames.length) {
-      asyncStackTrace = asyncStackTrace.parent;
-      continue;
-    }
-    const row = contentElement.createChild('tr');
-    row.createChild('td').textContent = '\n';
-    row.createChild('td', 'stack-preview-async-description').textContent =
-        UI.asyncStackTraceLabel(asyncStackTrace.description);
-    row.createChild('td');
-    row.createChild('td');
-    if (appendStackTrace(asyncStackTrace))
-      row.classList.add('blackboxed');
-    asyncStackTrace = asyncStackTrace.parent;
-  }
-
-  if (totalHiddenCallFramesCount) {
-    const row = contentElement.createChild('tr', 'show-blackboxed-link');
-    row.createChild('td').textContent = '\n';
-    const cell = row.createChild('td');
-    cell.colSpan = 4;
-    const showAllLink = cell.createChild('span', 'link');
-    if (totalHiddenCallFramesCount === 1)
-      showAllLink.textContent = ls`Show 1 more blackboxed frame`;
-    else
-      showAllLink.textContent = ls`Show ${totalHiddenCallFramesCount} more blackboxed frames`;
-    showAllLink.addEventListener('click', () => {
-      contentElement.classList.add('show-blackboxed');
-      if (contentUpdated)
-        contentUpdated();
-    }, false);
-  }
-
-  return element;
-};
diff --git a/front_end/components/Linkifier.js b/front_end/components/Linkifier.js
deleted file mode 100644
index 61f6cbf..0000000
--- a/front_end/components/Linkifier.js
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-Components.Linkifier = class {
-  /**
-   * @param {number=} maxLengthForDisplayedURLs
-   * @param {boolean=} useLinkDecorator
-   */
-  constructor(maxLengthForDisplayedURLs, useLinkDecorator) {
-    this._maxLength = maxLengthForDisplayedURLs || UI.MaxLengthForDisplayedURLs;
-    /** @type {!Map<!SDK.Target, !Array<!Element>>} */
-    this._anchorsByTarget = new Map();
-    /** @type {!Map<!SDK.Target, !Bindings.LiveLocationPool>} */
-    this._locationPoolByTarget = new Map();
-    this._useLinkDecorator = !!useLinkDecorator;
-    Components.Linkifier._instances.add(this);
-    SDK.targetManager.observeTargets(this);
-  }
-
-  /**
-   * @param {!Components.LinkDecorator} decorator
-   */
-  static setLinkDecorator(decorator) {
-    console.assert(!Components.Linkifier._decorator, 'Cannot re-register link decorator.');
-    Components.Linkifier._decorator = decorator;
-    decorator.addEventListener(Components.LinkDecorator.Events.LinkIconChanged, onLinkIconChanged);
-    for (const linkifier of Components.Linkifier._instances)
-      linkifier._updateAllAnchorDecorations();
-
-    /**
-     * @param {!Common.Event} event
-     */
-    function onLinkIconChanged(event) {
-      const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-      const links = uiSourceCode[Components.Linkifier._sourceCodeAnchors] || [];
-      for (const link of links)
-        Components.Linkifier._updateLinkDecorations(link);
-    }
-  }
-
-  _updateAllAnchorDecorations() {
-    for (const anchors of this._anchorsByTarget.values()) {
-      for (const anchor of anchors)
-        Components.Linkifier._updateLinkDecorations(anchor);
-    }
-  }
-
-  /**
-   * @param {!Element} anchor
-   * @param {!Workspace.UILocation} uiLocation
-   */
-  static _bindUILocation(anchor, uiLocation) {
-    Components.Linkifier._linkInfo(anchor).uiLocation = uiLocation;
-    if (!uiLocation)
-      return;
-    const uiSourceCode = uiLocation.uiSourceCode;
-    let sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors];
-    if (!sourceCodeAnchors) {
-      sourceCodeAnchors = new Set();
-      uiSourceCode[Components.Linkifier._sourceCodeAnchors] = sourceCodeAnchors;
-    }
-    sourceCodeAnchors.add(anchor);
-  }
-
-  /**
-   * @param {!Element} anchor
-   */
-  static _unbindUILocation(anchor) {
-    const info = Components.Linkifier._linkInfo(anchor);
-    if (!info.uiLocation)
-      return;
-
-    const uiSourceCode = info.uiLocation.uiSourceCode;
-    info.uiLocation = null;
-    const sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors];
-    if (sourceCodeAnchors)
-      sourceCodeAnchors.delete(anchor);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    this._anchorsByTarget.set(target, []);
-    this._locationPoolByTarget.set(target, new Bindings.LiveLocationPool());
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    const locationPool = /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.remove(target));
-    locationPool.disposeAll();
-    const anchors = this._anchorsByTarget.remove(target);
-    for (const anchor of anchors) {
-      const info = Components.Linkifier._linkInfo(anchor);
-      info.liveLocation = null;
-      Components.Linkifier._unbindUILocation(anchor);
-      if (info.fallback) {
-        anchor.href = info.fallback.href;
-        anchor.title = info.fallback.title;
-        anchor.className = info.fallback.className;
-        anchor.textContent = info.fallback.textContent;
-        anchor[Components.Linkifier._infoSymbol] = info.fallback[Components.Linkifier._infoSymbol];
-      }
-    }
-  }
-
-  /**
-   * @param {?SDK.Target} target
-   * @param {?string} scriptId
-   * @param {string} sourceURL
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @param {string=} classes
-   * @return {?Element}
-   */
-  maybeLinkifyScriptLocation(target, scriptId, sourceURL, lineNumber, columnNumber, classes) {
-    let fallbackAnchor = null;
-    if (sourceURL) {
-      fallbackAnchor = Components.Linkifier.linkifyURL(
-          sourceURL,
-          {className: classes, lineNumber: lineNumber, columnNumber: columnNumber, maxLength: this._maxLength});
-    }
-    if (!target || target.isDisposed())
-      return fallbackAnchor;
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (!debuggerModel)
-      return fallbackAnchor;
-
-    const rawLocation =
-        (scriptId ? debuggerModel.createRawLocationByScriptId(scriptId, lineNumber, columnNumber || 0) : null) ||
-        debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
-    if (!rawLocation)
-      return fallbackAnchor;
-
-    const anchor = Components.Linkifier._createLink('', classes || '');
-    const info = Components.Linkifier._linkInfo(anchor);
-    info.enableDecorator = this._useLinkDecorator;
-    info.fallback = fallbackAnchor;
-    info.liveLocation = Bindings.debuggerWorkspaceBinding.createLiveLocation(
-        rawLocation, this._updateAnchor.bind(this, anchor),
-        /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.get(rawLocation.debuggerModel.target())));
-
-    const anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(rawLocation.debuggerModel.target()));
-    anchors.push(anchor);
-    return anchor;
-  }
-
-  /**
-   * @param {?SDK.Target} target
-   * @param {?string} scriptId
-   * @param {string} sourceURL
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @param {string=} classes
-   * @return {!Element}
-   */
-  linkifyScriptLocation(target, scriptId, sourceURL, lineNumber, columnNumber, classes) {
-    const scriptLink = this.maybeLinkifyScriptLocation(target, scriptId, sourceURL, lineNumber, columnNumber, classes);
-    return scriptLink ||
-        Components.Linkifier.linkifyURL(
-            sourceURL,
-            {className: classes, lineNumber: lineNumber, columnNumber: columnNumber, maxLength: this._maxLength});
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @param {string} fallbackUrl
-   * @param {string=} classes
-   * @return {!Element}
-   */
-  linkifyRawLocation(rawLocation, fallbackUrl, classes) {
-    return this.linkifyScriptLocation(
-        rawLocation.debuggerModel.target(), rawLocation.scriptId, fallbackUrl, rawLocation.lineNumber,
-        rawLocation.columnNumber, classes);
-  }
-
-  /**
-   * @param {?SDK.Target} target
-   * @param {!Protocol.Runtime.CallFrame} callFrame
-   * @param {string=} classes
-   * @return {?Element}
-   */
-  maybeLinkifyConsoleCallFrame(target, callFrame, classes) {
-    return this.maybeLinkifyScriptLocation(
-        target, callFrame.scriptId, callFrame.url, callFrame.lineNumber, callFrame.columnNumber, classes);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   * @param {string=} classes
-   * @return {!Element}
-   */
-  linkifyStackTraceTopFrame(target, stackTrace, classes) {
-    console.assert(stackTrace.callFrames && stackTrace.callFrames.length);
-
-    const topFrame = stackTrace.callFrames[0];
-    const fallbackAnchor = Components.Linkifier.linkifyURL(topFrame.url, {
-      className: classes,
-      lineNumber: topFrame.lineNumber,
-      columnNumber: topFrame.columnNumber,
-      maxLength: this._maxLength
-    });
-    if (target.isDisposed())
-      return fallbackAnchor;
-
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    const rawLocations = debuggerModel.createRawLocationsByStackTrace(stackTrace);
-    if (rawLocations.length === 0)
-      return fallbackAnchor;
-
-    const anchor = Components.Linkifier._createLink('', classes || '');
-    const info = Components.Linkifier._linkInfo(anchor);
-    info.enableDecorator = this._useLinkDecorator;
-    info.fallback = fallbackAnchor;
-    info.liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(
-        rawLocations, this._updateAnchor.bind(this, anchor),
-        /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.get(target)));
-
-    const anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(target));
-    anchors.push(anchor);
-    return anchor;
-  }
-
-  /**
-   * @param {!SDK.CSSLocation} rawLocation
-   * @param {string=} classes
-   * @return {!Element}
-   */
-  linkifyCSSLocation(rawLocation, classes) {
-    const anchor = Components.Linkifier._createLink('', classes || '');
-    const info = Components.Linkifier._linkInfo(anchor);
-    info.enableDecorator = this._useLinkDecorator;
-    info.liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation(
-        rawLocation, this._updateAnchor.bind(this, anchor),
-        /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.get(rawLocation.cssModel().target())));
-
-    const anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(rawLocation.cssModel().target()));
-    anchors.push(anchor);
-    return anchor;
-  }
-
-  reset() {
-    for (const target of this._anchorsByTarget.keysArray()) {
-      this.targetRemoved(target);
-      this.targetAdded(target);
-    }
-  }
-
-  dispose() {
-    for (const target of this._anchorsByTarget.keysArray())
-      this.targetRemoved(target);
-    SDK.targetManager.unobserveTargets(this);
-    Components.Linkifier._instances.delete(this);
-  }
-
-  /**
-   * @param {!Element} anchor
-   * @param {!Bindings.LiveLocation} liveLocation
-   */
-  _updateAnchor(anchor, liveLocation) {
-    Components.Linkifier._unbindUILocation(anchor);
-    const uiLocation = liveLocation.uiLocation();
-    if (!uiLocation)
-      return;
-
-    Components.Linkifier._bindUILocation(anchor, uiLocation);
-    const text = uiLocation.linkText(true /* skipTrim */);
-    Components.Linkifier._setTrimmedText(anchor, text, this._maxLength);
-
-    let titleText = uiLocation.uiSourceCode.url();
-    if (typeof uiLocation.lineNumber === 'number')
-      titleText += ':' + (uiLocation.lineNumber + 1);
-    anchor.title = titleText;
-    anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackboxed());
-    Components.Linkifier._updateLinkDecorations(anchor);
-  }
-
-  /**
-   * @param {!Element} anchor
-   */
-  static _updateLinkDecorations(anchor) {
-    const info = Components.Linkifier._linkInfo(anchor);
-    if (!info || !info.enableDecorator)
-      return;
-    if (!Components.Linkifier._decorator || !info.uiLocation)
-      return;
-    if (info.icon && info.icon.parentElement)
-      anchor.removeChild(info.icon);
-    const icon = Components.Linkifier._decorator.linkIcon(info.uiLocation.uiSourceCode);
-    if (icon) {
-      icon.style.setProperty('margin-right', '2px');
-      anchor.insertBefore(icon, anchor.firstChild);
-    }
-    info.icon = icon;
-  }
-
-  /**
-   * @param {string} url
-   * @param  {!Components.LinkifyURLOptions=} options
-   * @return {!Element}
-   */
-  static linkifyURL(url, options) {
-    options = options || {};
-    const text = options.text;
-    const className = options.className || '';
-    const lineNumber = options.lineNumber;
-    const columnNumber = options.columnNumber;
-    const preventClick = options.preventClick;
-    const maxLength = options.maxLength || UI.MaxLengthForDisplayedURLs;
-    if (!url || url.trim().toLowerCase().startsWith('javascript:')) {
-      const element = createElementWithClass('span', className);
-      element.textContent = text || url || Common.UIString('(unknown)');
-      return element;
-    }
-
-    let linkText = text || Bindings.displayNameForURL(url);
-    if (typeof lineNumber === 'number' && !text)
-      linkText += ':' + (lineNumber + 1);
-    const title = linkText !== url ? url : '';
-    const link = Components.Linkifier._createLink(linkText, className, maxLength, title, url, preventClick);
-    const info = Components.Linkifier._linkInfo(link);
-    if (typeof lineNumber === 'number')
-      info.lineNumber = lineNumber;
-    if (typeof columnNumber === 'number')
-      info.columnNumber = columnNumber;
-    return link;
-  }
-
-  /**
-   * @param {!Object} revealable
-   * @param {string} text
-   * @param {string=} fallbackHref
-   * @return {!Element}
-   */
-  static linkifyRevealable(revealable, text, fallbackHref) {
-    const link = Components.Linkifier._createLink(text, '', UI.MaxLengthForDisplayedURLs, undefined, fallbackHref);
-    Components.Linkifier._linkInfo(link).revealable = revealable;
-    return link;
-  }
-
-  /**
-   * @param {string} text
-   * @param {string} className
-   * @param {number=} maxLength
-   * @param {string=} title
-   * @param {string=} href
-   * @param {boolean=} preventClick
-   * @returns{!Element}
-   */
-  static _createLink(text, className, maxLength, title, href, preventClick) {
-    const link = createElementWithClass('span', className);
-    link.classList.add('devtools-link');
-    if (title)
-      link.title = title;
-    if (href)
-      link.href = href;
-    Components.Linkifier._setTrimmedText(link, text, maxLength);
-    link[Components.Linkifier._infoSymbol] = {
-      icon: null,
-      enableDecorator: false,
-      uiLocation: null,
-      liveLocation: null,
-      url: href || null,
-      lineNumber: null,
-      columnNumber: null,
-      revealable: null,
-      fallback: null
-    };
-    if (!preventClick)
-      link.addEventListener('click', Components.Linkifier._handleClick, false);
-    else
-      link.classList.add('devtools-link-prevent-click');
-    return link;
-  }
-
-  /**
-   * @param {!Element} link
-   * @param {string} text
-   * @param {number=} maxLength
-   */
-  static _setTrimmedText(link, text, maxLength) {
-    link.removeChildren();
-    if (maxLength && text.length > maxLength) {
-      const middleSplit = splitMiddle(text, maxLength);
-      appendTextWithoutHashes(middleSplit[0]);
-      appendHiddenText(middleSplit[1]);
-      appendTextWithoutHashes(middleSplit[2]);
-    } else {
-      appendTextWithoutHashes(text);
-    }
-
-    /**
-     * @param {string} string
-     */
-    function appendHiddenText(string) {
-      const ellipsisNode = link.createChild('span', 'devtools-link-ellipsis').createTextChild('\u2026');
-      ellipsisNode[Components.Linkifier._untruncatedNodeTextSymbol] = string;
-    }
-
-    /**
-     * @param {string} string
-     */
-    function appendTextWithoutHashes(string) {
-      const hashSplit = TextUtils.TextUtils.splitStringByRegexes(string, [/[a-f0-9]{20,}/g]);
-      for (const match of hashSplit) {
-        if (match.regexIndex === -1) {
-          link.createTextChild(match.value);
-        } else {
-          link.createTextChild(match.value.substring(0, 7));
-          appendHiddenText(match.value.substring(7));
-        }
-      }
-    }
-
-    /**
-     * @param {string} string
-     * @param {number} maxLength
-     * @return {!Array<string>}
-     */
-    function splitMiddle(string, maxLength) {
-      let leftIndex = Math.floor(maxLength / 2);
-      let rightIndex = string.length - Math.ceil(maxLength / 2) + 1;
-
-      // Do not truncate between characters that use multiple code points (emojis).
-      if (string.codePointAt(rightIndex - 1) >= 0x10000) {
-        rightIndex++;
-        leftIndex++;
-      }
-      if (leftIndex > 0 && string.codePointAt(leftIndex - 1) >= 0x10000)
-        leftIndex--;
-      return [string.substring(0, leftIndex), string.substring(leftIndex, rightIndex), string.substring(rightIndex)];
-    }
-  }
-
-  /**
-   * @param {!Node} node
-   * @return {string}
-   */
-  static untruncatedNodeText(node) {
-    return node[Components.Linkifier._untruncatedNodeTextSymbol] || node.textContent;
-  }
-
-  /**
-   * @param {?Element} link
-   * @return {?Components._LinkInfo}
-   */
-  static _linkInfo(link) {
-    return /** @type {?Components._LinkInfo} */ (link ? link[Components.Linkifier._infoSymbol] || null : null);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  static _handleClick(event) {
-    const link = /** @type {!Element} */ (event.currentTarget);
-    event.consume(true);
-    if (UI.isBeingEdited(/** @type {!Node} */ (event.target)) || link.hasSelection())
-      return;
-    const actions = Components.Linkifier._linkActions(link);
-    if (actions.length)
-      actions[0].handler.call(null);
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  static _linkHandlerSetting() {
-    if (!Components.Linkifier._linkHandlerSettingInstance) {
-      Components.Linkifier._linkHandlerSettingInstance =
-          Common.settings.createSetting('openLinkHandler', Common.UIString('auto'));
-    }
-    return Components.Linkifier._linkHandlerSettingInstance;
-  }
-
-  /**
-   * @param {string} title
-   * @param {!Components.Linkifier.LinkHandler} handler
-   */
-  static registerLinkHandler(title, handler) {
-    Components.Linkifier._linkHandlers.set(title, handler);
-    self.runtime.sharedInstance(Components.Linkifier.LinkHandlerSettingUI)._update();
-  }
-
-  /**
-   * @param {string} title
-   */
-  static unregisterLinkHandler(title) {
-    Components.Linkifier._linkHandlers.delete(title);
-    self.runtime.sharedInstance(Components.Linkifier.LinkHandlerSettingUI)._update();
-  }
-
-  /**
-   * @param {!Element} link
-   * @return {?Workspace.UILocation}
-   */
-  static uiLocation(link) {
-    const info = Components.Linkifier._linkInfo(link);
-    return info ? info.uiLocation : null;
-  }
-
-  /**
-   * @param {?Element} link
-   * @return {!Array<{title: string, handler: function()}>}
-   */
-  static _linkActions(link) {
-    const info = Components.Linkifier._linkInfo(link);
-    const result = [];
-    if (!info)
-      return result;
-
-    let url = '';
-    let uiLocation = null;
-    if (info.uiLocation) {
-      uiLocation = info.uiLocation;
-      url = uiLocation.uiSourceCode.contentURL();
-    } else if (info.url) {
-      url = info.url;
-      const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url) ||
-          Workspace.workspace.uiSourceCodeForURL(Common.ParsedURL.urlWithoutHash(url));
-      uiLocation = uiSourceCode ? uiSourceCode.uiLocation(info.lineNumber || 0, info.columnNumber || 0) : null;
-    }
-    const resource = url ? Bindings.resourceForURL(url) : null;
-    const contentProvider = uiLocation ? uiLocation.uiSourceCode : resource;
-
-    const revealable = info.revealable || uiLocation || resource;
-    if (revealable) {
-      const destination = Common.Revealer.revealDestination(revealable);
-      result.push({
-        section: 'reveal',
-        title: destination ? ls`Reveal in ${destination}` : ls`Reveal`,
-        handler: () => Common.Revealer.reveal(revealable)
-      });
-    }
-    if (contentProvider) {
-      const lineNumber = uiLocation ? uiLocation.lineNumber : info.lineNumber || 0;
-      for (const title of Components.Linkifier._linkHandlers.keys()) {
-        const handler = Components.Linkifier._linkHandlers.get(title);
-        const action = {
-          section: 'reveal',
-          title: Common.UIString('Open using %s', title),
-          handler: handler.bind(null, contentProvider, lineNumber)
-        };
-        if (title === Components.Linkifier._linkHandlerSetting().get())
-          result.unshift(action);
-        else
-          result.push(action);
-      }
-    }
-    if (resource || info.url) {
-      result.push({
-        section: 'reveal',
-        title: UI.openLinkExternallyLabel(),
-        handler: () => InspectorFrontendHost.openInNewTab(url)
-      });
-      result.push(
-          {section: 'clipboard', title: UI.copyLinkAddressLabel(), handler: () => InspectorFrontendHost.copyText(url)});
-    }
-    return result;
-  }
-};
-
-/** @type {!Set<!Components.Linkifier>} */
-Components.Linkifier._instances = new Set();
-/** @type {?Components.LinkDecorator} */
-Components.Linkifier._decorator = null;
-
-Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors');
-Components.Linkifier._infoSymbol = Symbol('Linkifier.info');
-Components.Linkifier._untruncatedNodeTextSymbol = Symbol('Linkifier.untruncatedNodeText');
-
-/**
- * @typedef {{
- *     icon: ?UI.Icon,
- *     enableDecorator: boolean,
- *     uiLocation: ?Workspace.UILocation,
- *     liveLocation: ?Bindings.LiveLocation,
- *     url: ?string,
- *     lineNumber: ?number,
- *     columnNumber: ?number,
- *     revealable: ?Object,
- *     fallback: ?Element
- * }}
- */
-Components._LinkInfo;
-
-/**
- * @typedef {{
- *     text: (string|undefined),
- *     className: (string|undefined),
- *     lineNumber: (number|undefined),
- *     columnNumber: (number|undefined),
- *     preventClick: (boolean|undefined),
- *     maxLength: (number|undefined)
- * }}
- */
-Components.LinkifyURLOptions;
-
-/**
- * The maximum length before strings are considered too long for finding URLs.
- * @const
- * @type {number}
- */
-Components.Linkifier.MaxLengthToIgnoreLinkifier = 10000;
-
-/**
- * @typedef {function(!Common.ContentProvider, number)}
- */
-Components.Linkifier.LinkHandler;
-
-/** @type {!Map<string, !Components.Linkifier.LinkHandler>} */
-Components.Linkifier._linkHandlers = new Map();
-
-/**
- * @extends {Common.EventTarget}
- * @interface
- */
-Components.LinkDecorator = function() {};
-
-Components.LinkDecorator.prototype = {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?UI.Icon}
-   */
-  linkIcon(uiSourceCode) {}
-};
-
-Components.LinkDecorator.Events = {
-  LinkIconChanged: Symbol('LinkIconChanged')
-};
-
-/**
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Components.Linkifier.LinkContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    let targetNode = /** @type {!Node} */ (target);
-    while (targetNode && !targetNode[Components.Linkifier._infoSymbol])
-      targetNode = targetNode.parentNodeOrShadowHost();
-    const link = /** @type {?Element} */ (targetNode);
-    const actions = Components.Linkifier._linkActions(link);
-    for (const action of actions)
-      contextMenu.section(action.section).appendItem(action.title, action.handler);
-  }
-};
-
-/**
- * @implements {UI.SettingUI}
- * @unrestricted
- */
-Components.Linkifier.LinkHandlerSettingUI = class {
-  constructor() {
-    this._element = createElementWithClass('select', 'chrome-select');
-    this._element.addEventListener('change', this._onChange.bind(this), false);
-    this._update();
-  }
-
-  _update() {
-    this._element.removeChildren();
-    const names = Components.Linkifier._linkHandlers.keysArray();
-    names.unshift(Common.UIString('auto'));
-    for (const name of names) {
-      const option = createElement('option');
-      option.textContent = name;
-      option.selected = name === Components.Linkifier._linkHandlerSetting().get();
-      this._element.appendChild(option);
-    }
-    this._element.disabled = names.length <= 1;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onChange(event) {
-    const value = event.target.value;
-    Components.Linkifier._linkHandlerSetting().set(value);
-  }
-
-  /**
-   * @override
-   * @return {?Element}
-   */
-  settingElement() {
-    return UI.SettingsUI.createCustomSetting(Common.UIString('Link handling:'), this._element);
-  }
-};
-
-/**
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Components.Linkifier.ContentProviderContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    const contentProvider = /** @type {!Common.ContentProvider} */ (target);
-    if (!contentProvider.contentURL())
-      return;
-
-    contextMenu.revealSection().appendItem(
-        UI.openLinkExternallyLabel(), () => InspectorFrontendHost.openInNewTab(contentProvider.contentURL()));
-    for (const title of Components.Linkifier._linkHandlers.keys()) {
-      const handler = Components.Linkifier._linkHandlers.get(title);
-      contextMenu.revealSection().appendItem(
-          Common.UIString('Open using %s', title), handler.bind(null, contentProvider, 0));
-    }
-    if (contentProvider instanceof SDK.NetworkRequest)
-      return;
-
-    contextMenu.clipboardSection().appendItem(
-        UI.copyLinkAddressLabel(), () => InspectorFrontendHost.copyText(contentProvider.contentURL()));
-  }
-};
diff --git a/front_end/components/Reload.js b/front_end/components/Reload.js
deleted file mode 100644
index 105f5c9..0000000
--- a/front_end/components/Reload.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Components.reload = function() {
-  if (Components.dockController.canDock() &&
-      Components.dockController.dockSide() === Components.DockController.State.Undocked)
-    InspectorFrontendHost.setIsDocked(true, function() {});
-  window.location.reload();
-};
diff --git a/front_end/components/TargetDetachedDialog.js b/front_end/components/TargetDetachedDialog.js
deleted file mode 100644
index e589c8d..0000000
--- a/front_end/components/TargetDetachedDialog.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Protocol.InspectorDispatcher}
- */
-Components.TargetDetachedDialog = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    if (target.parentTarget())
-      return;
-    target.registerInspectorDispatcher(this);
-    target.inspectorAgent().enable();
-    this._hideCrashedDialog = null;
-    Components.TargetDetachedDialog._disconnectedScreenWithReasonWasShown = false;
-  }
-
-  /**
-   * @override
-   * @param {string} reason
-   */
-  detached(reason) {
-    Components.TargetDetachedDialog._disconnectedScreenWithReasonWasShown = true;
-    UI.RemoteDebuggingTerminatedScreen.show(reason);
-  }
-
-  static webSocketConnectionLost() {
-    UI.RemoteDebuggingTerminatedScreen.show('WebSocket disconnected');
-  }
-
-  /**
-   * @override
-   */
-  targetCrashed() {
-    const dialog = new UI.Dialog();
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.addCloseButton();
-    dialog.setDimmed(true);
-    this._hideCrashedDialog = dialog.hide.bind(dialog);
-    new UI.TargetCrashedScreen(() => this._hideCrashedDialog = null).show(dialog.contentElement);
-    dialog.show();
-  }
-
-  /**
-   * @override;
-   */
-  targetReloadedAfterCrash() {
-    if (this._hideCrashedDialog) {
-      this._hideCrashedDialog.call(null);
-      this._hideCrashedDialog = null;
-    }
-  }
-};
-
-SDK.SDKModel.register(Components.TargetDetachedDialog, 0, true);
diff --git a/front_end/components/jsUtils.css b/front_end/components/jsUtils.css
deleted file mode 100644
index ead5928..0000000
--- a/front_end/components/jsUtils.css
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-  display: inline;
-}
-
-.stack-preview-async-description {
-    padding: 3px 0 1px;
-    font-style: italic;
-}
-
-.stack-preview-container .webkit-html-blackbox-link {
-    opacity: 0.6;
-}
-
-.stack-preview-container > tr {
-    height: 16px;
-    line-height: 16px;
-}
-
-.stack-preview-container td {
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.stack-preview-container .function-name {
-    max-width: 80em;
-}
-
-.stack-preview-container:not(.show-blackboxed) > tr.blackboxed {
-    display: none;
-}
-
-.stack-preview-container.show-blackboxed > tr.show-blackboxed-link {
-    display: none;
-}
-
-.stack-preview-container > tr.show-blackboxed-link {
-    font-style: italic;
-}
diff --git a/front_end/components/module.json b/front_end/components/module.json
deleted file mode 100644
index 8986fdf..0000000
--- a/front_end/components/module.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "dependencies": [
-        "bindings",
-        "platform",
-        "ui"
-    ],
-    "scripts": [
-        "JSPresentationUtils.js",
-        "DockController.js",
-        "Linkifier.js",
-        "Reload.js",
-        "TargetDetachedDialog.js"
-    ],
-    "resources": [
-        "jsUtils.css"
-    ]
-}
diff --git a/front_end/console/ConsoleContextSelector.js b/front_end/console/ConsoleContextSelector.js
deleted file mode 100644
index 2dbae2f..0000000
--- a/front_end/console/ConsoleContextSelector.js
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!SDK.RuntimeModel>}
- * @implements {UI.SoftDropDown.Delegate<!SDK.ExecutionContext>}
- */
-Console.ConsoleContextSelector = class {
-  constructor() {
-    /** @type {!UI.ListModel<!SDK.ExecutionContext>} */
-    this._items = new UI.ListModel();
-    /** @type {!UI.SoftDropDown<!SDK.ExecutionContext>} */
-    this._dropDown = new UI.SoftDropDown(this._items, this);
-    this._dropDown.setRowHeight(36);
-    this._toolbarItem = new UI.ToolbarItem(this._dropDown.element);
-    this._toolbarItem.setEnabled(false);
-    this._items.addEventListener(
-        UI.ListModel.Events.ItemsReplaced, () => this._toolbarItem.setEnabled(!!this._items.length));
-
-    /** @type {!Map<!SDK.ExecutionContext, !ProductRegistry.BadgePool>} */
-    this._badgePoolForExecutionContext = new Map();
-
-    this._toolbarItem.element.classList.add('toolbar-has-dropdown');
-
-    SDK.targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
-    SDK.targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextChanged, this._onExecutionContextChanged, this);
-    SDK.targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
-    SDK.targetManager.addModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this);
-
-    UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChangedExternally, this);
-    UI.context.addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this._callFrameSelectedInUI, this);
-    SDK.targetManager.observeModels(SDK.RuntimeModel, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.CallFrameSelected, this._callFrameSelectedInModel, this);
-  }
-
-  /**
-   * @return {!UI.ToolbarItem}
-   */
-  toolbarItem() {
-    return this._toolbarItem;
-  }
-
-  /**
-   * @override
-   * @param {?SDK.ExecutionContext} from
-   * @param {?SDK.ExecutionContext} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  highlightedItemChanged(from, to, fromElement, toElement) {
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    if (to && to.frameId) {
-      const overlayModel = to.target().model(SDK.OverlayModel);
-      if (overlayModel)
-        overlayModel.highlightFrame(to.frameId);
-    }
-    if (fromElement)
-      fromElement.classList.remove('highlighted');
-    if (toElement)
-      toElement.classList.add('highlighted');
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {string}
-   */
-  titleFor(executionContext) {
-    const target = executionContext.target();
-    let label = executionContext.label() ? target.decorateLabel(executionContext.label()) : '';
-    if (executionContext.frameId) {
-      const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-      const frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
-      if (frame)
-        label = label || frame.displayName();
-    }
-    label = label || executionContext.origin;
-
-    return label;
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {number}
-   */
-  _depthFor(executionContext) {
-    let target = executionContext.target();
-    let depth = 0;
-    if (!executionContext.isDefault)
-      depth++;
-    if (executionContext.frameId) {
-      const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-      let frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
-      while (frame && frame.parentFrame) {
-        depth++;
-        frame = frame.parentFrame;
-      }
-    }
-    let targetDepth = 0;
-    while (target.parentTarget()) {
-      if (target.parentTarget().hasJSCapability()) {
-        targetDepth++;
-      } else {
-        // Special casing service workers to be top-level.
-        targetDepth = 0;
-        break;
-      }
-      target = target.parentTarget();
-    }
-    depth += targetDepth;
-    return depth;
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {?Element}
-   */
-  _badgeFor(executionContext) {
-    if (!executionContext.frameId || !executionContext.isDefault)
-      return null;
-    const resourceTreeModel = executionContext.target().model(SDK.ResourceTreeModel);
-    const frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
-    if (!frame)
-      return null;
-    const badgePool = new ProductRegistry.BadgePool();
-    this._badgePoolForExecutionContext.set(executionContext, badgePool);
-    return badgePool.badgeForFrame(frame);
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   */
-  _disposeExecutionContextBadge(executionContext) {
-    const badgePool = this._badgePoolForExecutionContext.get(executionContext);
-    if (!badgePool)
-      return;
-    badgePool.reset();
-    this._badgePoolForExecutionContext.delete(executionContext);
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   */
-  _executionContextCreated(executionContext) {
-    // FIXME(413886): We never want to show execution context for the main thread of shadow page in service/shared worker frontend.
-    // This check could be removed once we do not send this context to frontend.
-    if (!executionContext.target().hasJSCapability())
-      return;
-
-    this._items.insertWithComparator(executionContext, executionContext.runtimeModel.executionContextComparator());
-
-    if (executionContext === UI.context.flavor(SDK.ExecutionContext))
-      this._dropDown.selectItem(executionContext);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onExecutionContextCreated(event) {
-    const executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
-    this._executionContextCreated(executionContext);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onExecutionContextChanged(event) {
-    const executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
-    if (this._items.indexOf(executionContext) === -1)
-      return;
-    this._executionContextDestroyed(executionContext);
-    this._executionContextCreated(executionContext);
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   */
-  _executionContextDestroyed(executionContext) {
-    const index = this._items.indexOf(executionContext);
-    if (index === -1)
-      return;
-    this._disposeExecutionContextBadge(executionContext);
-    this._items.remove(index);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onExecutionContextDestroyed(event) {
-    const executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
-    this._executionContextDestroyed(executionContext);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _executionContextChangedExternally(event) {
-    const executionContext = /** @type {?SDK.ExecutionContext} */ (event.data);
-    this._dropDown.selectItem(executionContext);
-  }
-
-  /**
-   * @param {?SDK.ExecutionContext} executionContext
-   * @return {boolean}
-   */
-  _isTopContext(executionContext) {
-    if (!executionContext || !executionContext.isDefault)
-      return false;
-    const resourceTreeModel = executionContext.target().model(SDK.ResourceTreeModel);
-    const frame =
-        executionContext.frameId && resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
-    if (!frame)
-      return false;
-    return frame.isTopFrame();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _hasTopContext() {
-    return this._items.some(executionContext => this._isTopContext(executionContext));
-  }
-
-  /**
-   * @override
-   * @param {!SDK.RuntimeModel} runtimeModel
-   */
-  modelAdded(runtimeModel) {
-    runtimeModel.executionContexts().forEach(this._executionContextCreated, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.RuntimeModel} runtimeModel
-   */
-  modelRemoved(runtimeModel) {
-    for (let i = 0; i < this._items.length; i++) {
-      if (this._items.at(i).runtimeModel === runtimeModel)
-        this._executionContextDestroyed(this._items.at(i));
-    }
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ExecutionContext} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    const element = createElementWithClass('div');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'console/consoleContextSelector.css');
-    const title = shadowRoot.createChild('div', 'title');
-    title.createTextChild(this.titleFor(item).trimEnd(100));
-    const subTitle = shadowRoot.createChild('div', 'subtitle');
-    const badgeElement = this._badgeFor(item);
-    if (badgeElement) {
-      badgeElement.classList.add('badge');
-      subTitle.appendChild(badgeElement);
-    }
-    subTitle.createTextChild(this._subtitleFor(item));
-    element.style.paddingLeft = (8 + this._depthFor(item) * 15) + 'px';
-    return element;
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {string}
-   */
-  _subtitleFor(executionContext) {
-    const target = executionContext.target();
-    let frame;
-    if (executionContext.frameId) {
-      const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-      frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
-    }
-    if (executionContext.origin.startsWith('chrome-extension://'))
-      return Common.UIString('Extension');
-    if (!frame || !frame.parentFrame || frame.parentFrame.securityOrigin !== executionContext.origin) {
-      const url = executionContext.origin.asParsedURL();
-      if (url)
-        return url.domain();
-    }
-
-    if (frame) {
-      const callFrame = frame.findCreationCallFrame(callFrame => !!callFrame.url);
-      if (callFrame)
-        return new Common.ParsedURL(callFrame.url).domain();
-      return Common.UIString('IFrame');
-    }
-    return '';
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ExecutionContext} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    const callFrame = item.debuggerModel.selectedCallFrame();
-    const callFrameContext = callFrame && callFrame.script.executionContext();
-    return !callFrameContext || item === callFrameContext;
-  }
-
-  /**
-   * @override
-   * @param {?SDK.ExecutionContext} item
-   */
-  itemSelected(item) {
-    this._toolbarItem.element.classList.toggle('warning', !this._isTopContext(item) && this._hasTopContext());
-    UI.context.setFlavor(SDK.ExecutionContext, item);
-  }
-
-  _callFrameSelectedInUI() {
-    const callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-    const callFrameContext = callFrame && callFrame.script.executionContext();
-    if (callFrameContext)
-      UI.context.setFlavor(SDK.ExecutionContext, callFrameContext);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _callFrameSelectedInModel(event) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    for (const executionContext of this._items) {
-      if (executionContext.debuggerModel === debuggerModel) {
-        this._disposeExecutionContextBadge(executionContext);
-        this._dropDown.refreshItem(executionContext);
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameNavigated(event) {
-    const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    const runtimeModel = frame.resourceTreeModel().target().model(SDK.RuntimeModel);
-    if (!runtimeModel)
-      return;
-    for (const executionContext of runtimeModel.executionContexts()) {
-      if (frame.id === executionContext.frameId) {
-        this._disposeExecutionContextBadge(executionContext);
-        this._dropDown.refreshItem(executionContext);
-      }
-    }
-  }
-};
diff --git a/front_end/console/ConsoleFilter.js b/front_end/console/ConsoleFilter.js
deleted file mode 100644
index 5a86749..0000000
--- a/front_end/console/ConsoleFilter.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Console.ConsoleFilter = class {
-  /**
-   * @param {string} name
-   * @param {!Array<!TextUtils.FilterParser.ParsedFilter>} parsedFilters
-   * @param {?SDK.ExecutionContext} executionContext
-   * @param {!Object<string, boolean>=} levelsMask
-   */
-  constructor(name, parsedFilters, executionContext, levelsMask) {
-    this.name = name;
-    this.parsedFilters = parsedFilters;
-    this.executionContext = executionContext;
-    this.levelsMask = levelsMask || Console.ConsoleFilter.defaultLevelsFilterValue();
-  }
-
-  /**
-   * @return {!Object<string, boolean>}
-   */
-  static allLevelsFilterValue() {
-    const result = {};
-    for (const name of Object.values(SDK.ConsoleMessage.MessageLevel))
-      result[name] = true;
-    return result;
-  }
-
-  /**
-   * @return {!Object<string, boolean>}
-   */
-  static defaultLevelsFilterValue() {
-    const result = Console.ConsoleFilter.allLevelsFilterValue();
-    result[SDK.ConsoleMessage.MessageLevel.Verbose] = false;
-    return result;
-  }
-
-  /**
-   * @param {string} level
-   * @return {!Object<string, boolean>}
-   */
-  static singleLevelMask(level) {
-    const result = {};
-    result[level] = true;
-    return result;
-  }
-
-  /**
-   * @return {!Console.ConsoleFilter}
-   */
-  clone() {
-    const parsedFilters = this.parsedFilters.map(TextUtils.FilterParser.cloneFilter);
-    const levelsMask = Object.assign({}, this.levelsMask);
-    return new Console.ConsoleFilter(this.name, parsedFilters, this.executionContext, levelsMask);
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   * @return {boolean}
-   */
-  shouldBeVisible(viewMessage) {
-    const message = viewMessage.consoleMessage();
-    if (this.executionContext &&
-        (this.executionContext.runtimeModel !== message.runtimeModel() ||
-         this.executionContext.id !== message.executionContextId))
-      return false;
-
-    if (message.type === SDK.ConsoleMessage.MessageType.Command ||
-        message.type === SDK.ConsoleMessage.MessageType.Result || message.isGroupMessage())
-      return true;
-
-    if (message.level && !this.levelsMask[/** @type {string} */ (message.level)])
-      return false;
-
-    for (const filter of this.parsedFilters) {
-      if (!filter.key) {
-        if (filter.regex && viewMessage.matchesFilterRegex(filter.regex) === filter.negative)
-          return false;
-        if (filter.text && viewMessage.matchesFilterText(filter.text) === filter.negative)
-          return false;
-      } else {
-        switch (filter.key) {
-          case Console.ConsoleFilter.FilterType.Context:
-            if (!passesFilter(filter, message.context, false /* exactMatch */))
-              return false;
-            break;
-          case Console.ConsoleFilter.FilterType.Source:
-            const sourceNameForMessage = message.source ?
-                SDK.ConsoleMessage.MessageSourceDisplayName.get(
-                    /** @type {!SDK.ConsoleMessage.MessageSource} */ (message.source)) :
-                message.source;
-            if (!passesFilter(filter, sourceNameForMessage, true /* exactMatch */))
-              return false;
-            break;
-          case Console.ConsoleFilter.FilterType.Url:
-            if (!passesFilter(filter, message.url, false /* exactMatch */))
-              return false;
-            break;
-        }
-      }
-    }
-    return true;
-
-    /**
-     * @param {!TextUtils.FilterParser.ParsedFilter} filter
-     * @param {?string|undefined} value
-     * @param {boolean} exactMatch
-     * @return {boolean}
-     */
-    function passesFilter(filter, value, exactMatch) {
-      if (!filter.text)
-        return !!value === filter.negative;
-      if (!value)
-        return !filter.text === !filter.negative;
-      const filterText = /** @type {string} */ (filter.text).toLowerCase();
-      const lowerCaseValue = value.toLowerCase();
-      if (exactMatch && (lowerCaseValue === filterText) === filter.negative)
-        return false;
-      if (!exactMatch && lowerCaseValue.includes(filterText) === filter.negative)
-        return false;
-      return true;
-    }
-  }
-};
-
-/** @enum {string} */
-Console.ConsoleFilter.FilterType = {
-  Context: 'context',
-  Source: 'source',
-  Url: 'url'
-};
diff --git a/front_end/console/ConsolePanel.js b/front_end/console/ConsolePanel.js
deleted file mode 100644
index 862721f..0000000
--- a/front_end/console/ConsolePanel.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Console.ConsolePanel = class extends UI.Panel {
-  constructor() {
-    super('console');
-    this._view = Console.ConsoleView.instance();
-  }
-
-  /**
-   * @return {!Console.ConsolePanel}
-   */
-  static instance() {
-    return /** @type {!Console.ConsolePanel} */ (self.runtime.sharedInstance(Console.ConsolePanel));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    const wrapper = Console.ConsolePanel.WrapperView._instance;
-    if (wrapper && wrapper.isShowing())
-      UI.inspectorView.setDrawerMinimized(true);
-    this._view.show(this.element);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-    // The minimized drawer has 0 height, and showing Console inside may set
-    // Console's scrollTop to 0. Unminimize before calling show to avoid this.
-    UI.inspectorView.setDrawerMinimized(false);
-    if (Console.ConsolePanel.WrapperView._instance)
-      Console.ConsolePanel.WrapperView._instance._showViewInWrapper();
-  }
-
-  /**
-   * @override
-   * @return {?UI.SearchableView}
-   */
-  searchableView() {
-    return Console.ConsoleView.instance().searchableView();
-  }
-};
-
-/**
- * @unrestricted
- */
-Console.ConsolePanel.WrapperView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.element.classList.add('console-view-wrapper');
-
-    Console.ConsolePanel.WrapperView._instance = this;
-
-    this._view = Console.ConsoleView.instance();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (!Console.ConsolePanel.instance().isShowing())
-      this._showViewInWrapper();
-    else
-      UI.inspectorView.setDrawerMinimized(true);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.inspectorView.setDrawerMinimized(false);
-  }
-
-  _showViewInWrapper() {
-    this._view.show(this.element);
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Console.ConsolePanel.ConsoleRevealer = class {
-  /**
-   * @override
-   * @param {!Object} object
-   * @return {!Promise}
-   */
-  reveal(object) {
-    const consoleView = Console.ConsoleView.instance();
-    if (consoleView.isShowing()) {
-      consoleView.focus();
-      return Promise.resolve();
-    }
-    UI.viewManager.showView('console-view');
-    return Promise.resolve();
-  }
-};
diff --git a/front_end/console/ConsolePrompt.js b/front_end/console/ConsolePrompt.js
deleted file mode 100644
index f6cab07..0000000
--- a/front_end/console/ConsolePrompt.js
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Console.ConsolePrompt = class extends UI.Widget {
-  constructor() {
-    super();
-    this._addCompletionsFromHistory = true;
-    this._history = new Console.ConsoleHistoryManager();
-
-    this._initialText = '';
-    this._editor = null;
-
-    this.element.tabIndex = 0;
-
-    self.runtime.extension(UI.TextEditorFactory).instance().then(gotFactory.bind(this));
-
-    /**
-     * @param {!UI.TextEditorFactory} factory
-     * @this {Console.ConsolePrompt}
-     */
-    function gotFactory(factory) {
-      this._editor =
-          factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true});
-
-      this._editor.configureAutocomplete({
-        substituteRangeCallback: this._substituteRange.bind(this),
-        suggestionsCallback: this._wordsWithQuery.bind(this),
-        captureEnter: true
-      });
-      this._editor.widget().element.addEventListener('keydown', this._editorKeyDown.bind(this), true);
-      this._editor.widget().show(this.element);
-      this._editor.addEventListener(UI.TextEditor.Events.TextChanged, this._onTextChanged, this);
-
-      this.setText(this._initialText);
-      delete this._initialText;
-      if (this.hasFocus())
-        this.focus();
-      this.element.tabIndex = -1;
-
-      this._editorSetForTest();
-    }
-  }
-
-  _onTextChanged() {
-    this.dispatchEventToListeners(Console.ConsolePrompt.Events.TextChanged);
-  }
-
-  /**
-   * @return {!Console.ConsoleHistoryManager}
-   */
-  history() {
-    return this._history;
-  }
-
-  clearAutocomplete() {
-    if (this._editor)
-      this._editor.clearAutocomplete();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isCaretAtEndOfPrompt() {
-    return !!this._editor && this._editor.selection().collapseToEnd().equal(this._editor.fullRange().collapseToEnd());
-  }
-
-  moveCaretToEndOfPrompt() {
-    if (this._editor)
-      this._editor.setSelection(TextUtils.TextRange.createFromLocation(Infinity, Infinity));
-  }
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {
-    if (this._editor)
-      this._editor.setText(text);
-    else
-      this._initialText = text;
-    this.dispatchEventToListeners(Console.ConsolePrompt.Events.TextChanged);
-  }
-
-  /**
-   * @return {string}
-   */
-  text() {
-    return this._editor ? this._editor.text() : this._initialText;
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setAddCompletionsFromHistory(value) {
-    this._addCompletionsFromHistory = value;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _editorKeyDown(event) {
-    const keyboardEvent = /** @type {!KeyboardEvent} */ (event);
-    let newText;
-    let isPrevious;
-    // Check against visual coordinates in case lines wrap.
-    const selection = this._editor.selection();
-    const cursorY = this._editor.visualCoordinates(selection.endLine, selection.endColumn).y;
-
-    switch (keyboardEvent.keyCode) {
-      case UI.KeyboardShortcut.Keys.Up.code:
-        const startY = this._editor.visualCoordinates(0, 0).y;
-        if (keyboardEvent.shiftKey || !selection.isEmpty() || cursorY !== startY)
-          break;
-        newText = this._history.previous(this.text());
-        isPrevious = true;
-        break;
-      case UI.KeyboardShortcut.Keys.Down.code:
-        const fullRange = this._editor.fullRange();
-        const endY = this._editor.visualCoordinates(fullRange.endLine, fullRange.endColumn).y;
-        if (keyboardEvent.shiftKey || !selection.isEmpty() || cursorY !== endY)
-          break;
-        newText = this._history.next();
-        break;
-      case UI.KeyboardShortcut.Keys.P.code:  // Ctrl+P = Previous
-        if (Host.isMac() && keyboardEvent.ctrlKey && !keyboardEvent.metaKey && !keyboardEvent.altKey &&
-            !keyboardEvent.shiftKey) {
-          newText = this._history.previous(this.text());
-          isPrevious = true;
-        }
-        break;
-      case UI.KeyboardShortcut.Keys.N.code:  // Ctrl+N = Next
-        if (Host.isMac() && keyboardEvent.ctrlKey && !keyboardEvent.metaKey && !keyboardEvent.altKey &&
-            !keyboardEvent.shiftKey)
-          newText = this._history.next();
-        break;
-      case UI.KeyboardShortcut.Keys.Enter.code:
-        this._enterKeyPressed(keyboardEvent);
-        break;
-      case UI.KeyboardShortcut.Keys.Tab.code:
-        if (!this.text())
-          keyboardEvent.consume();
-        break;
-    }
-
-    if (newText === undefined)
-      return;
-    keyboardEvent.consume(true);
-    this.setText(newText);
-
-    if (isPrevious)
-      this._editor.setSelection(TextUtils.TextRange.createFromLocation(0, Infinity));
-    else
-      this.moveCaretToEndOfPrompt();
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   */
-  async _enterKeyPressed(event) {
-    if (event.altKey || event.ctrlKey || event.shiftKey)
-      return;
-
-    event.consume(true);
-
-    this.clearAutocomplete();
-
-    const str = this.text();
-    if (!str.length)
-      return;
-
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!this._isCaretAtEndOfPrompt() || !currentExecutionContext) {
-      this._appendCommand(str, true);
-      return;
-    }
-    const result = await currentExecutionContext.runtimeModel.compileScript(str, '', false, currentExecutionContext.id);
-    if (str !== this.text())
-      return;
-    const exceptionDetails = result.exceptionDetails;
-    if (exceptionDetails &&
-        (exceptionDetails.exception.description.startsWith('SyntaxError: Unexpected end of input') ||
-         exceptionDetails.exception.description.startsWith('SyntaxError: Unterminated template literal'))) {
-      this._editor.newlineAndIndent();
-      this._enterProcessedForTest();
-      return;
-    }
-    await this._appendCommand(str, true);
-    this._enterProcessedForTest();
-  }
-
-  /**
-   * @param {string} text
-   * @param {boolean} useCommandLineAPI
-   */
-  async _appendCommand(text, useCommandLineAPI) {
-    this.setText('');
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (currentExecutionContext) {
-      const executionContext = currentExecutionContext;
-      const message = SDK.consoleModel.addCommandMessage(executionContext, text);
-      text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text);
-      let preprocessed = false;
-      if (text.indexOf('await') !== -1) {
-        const preprocessedText = await Formatter.formatterWorkerPool().preprocessTopLevelAwaitExpressions(text);
-        preprocessed = !!preprocessedText;
-        text = preprocessedText || text;
-      }
-      SDK.consoleModel.evaluateCommandInConsole(
-          executionContext, message, text, useCommandLineAPI, /* awaitPromise */ preprocessed);
-      if (Console.ConsolePanel.instance().isShowing())
-        Host.userMetrics.actionTaken(Host.UserMetrics.Action.CommandEvaluatedInConsolePanel);
-    }
-  }
-
-  _enterProcessedForTest() {
-  }
-
-  /**
-   * @param {string} prefix
-   * @param {boolean=} force
-   * @return {!UI.SuggestBox.Suggestions}
-   */
-  _historyCompletions(prefix, force) {
-    if (!this._addCompletionsFromHistory || !this._isCaretAtEndOfPrompt() || (!prefix && !force))
-      return [];
-    const result = [];
-    const text = this.text();
-    const set = new Set();
-    const data = this._history.historyData();
-    for (let i = data.length - 1; i >= 0 && result.length < 50; --i) {
-      const item = data[i];
-      if (!item.startsWith(text))
-        continue;
-      if (set.has(item))
-        continue;
-      set.add(item);
-      result.push(
-          {text: item.substring(text.length - prefix.length), iconType: 'smallicon-text-prompt', isSecondary: true});
-    }
-    return result;
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (this._editor)
-      this._editor.widget().focus();
-    else
-      this.element.focus();
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?TextUtils.TextRange}
-   */
-  _substituteRange(lineNumber, columnNumber) {
-    const token = this._editor.tokenAtTextPosition(lineNumber, columnNumber);
-    if (token && token.type === 'js-string')
-      return new TextUtils.TextRange(lineNumber, token.startColumn, lineNumber, columnNumber);
-
-    const lineText = this._editor.line(lineNumber);
-    let index;
-    for (index = columnNumber - 1; index >= 0; index--) {
-      if (' =:[({;,!+-*/&|^<>.\t\r\n'.indexOf(lineText.charAt(index)) !== -1)
-        break;
-    }
-    return new TextUtils.TextRange(lineNumber, index + 1, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} queryRange
-   * @param {!TextUtils.TextRange} substituteRange
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  _wordsWithQuery(queryRange, substituteRange, force) {
-    const query = this._editor.text(queryRange);
-    const before = this._editor.text(new TextUtils.TextRange(0, 0, queryRange.startLine, queryRange.startColumn));
-    const historyWords = this._historyCompletions(query, force);
-    const token = this._editor.tokenAtTextPosition(substituteRange.startLine, substituteRange.startColumn);
-    if (token) {
-      const excludedTokens = new Set(['js-comment', 'js-string-2', 'js-def']);
-      const trimmedBefore = before.trim();
-      if (!trimmedBefore.endsWith('[') && !trimmedBefore.match(/\.\s*(get|set|delete)\s*\(\s*$/))
-        excludedTokens.add('js-string');
-      if (!trimmedBefore.endsWith('.'))
-        excludedTokens.add('js-property');
-      if (excludedTokens.has(token.type))
-        return Promise.resolve(historyWords);
-    }
-    return ObjectUI.javaScriptAutocomplete.completionsForTextInCurrentContext(before, query, force)
-        .then(words => words.concat(historyWords));
-  }
-
-  _editorSetForTest() {
-  }
-};
-
-/**
- * @unrestricted
- */
-Console.ConsoleHistoryManager = class {
-  constructor() {
-    /**
-     * @type {!Array.<string>}
-     */
-    this._data = [];
-
-    /**
-     * 1-based entry in the history stack.
-     * @type {number}
-     */
-    this._historyOffset = 1;
-  }
-
-  /**
-   * @return {!Array.<string>}
-   */
-  historyData() {
-    return this._data;
-  }
-
-  /**
-   * @param {!Array.<string>} data
-   */
-  setHistoryData(data) {
-    this._data = data.slice();
-    this._historyOffset = 1;
-  }
-
-  /**
-   * Pushes a committed text into the history.
-   * @param {string} text
-   */
-  pushHistoryItem(text) {
-    if (this._uncommittedIsTop) {
-      this._data.pop();
-      delete this._uncommittedIsTop;
-    }
-
-    this._historyOffset = 1;
-    if (text === this._currentHistoryItem())
-      return;
-    this._data.push(text);
-  }
-
-  /**
-   * Pushes the current (uncommitted) text into the history.
-   * @param {string} currentText
-   */
-  _pushCurrentText(currentText) {
-    if (this._uncommittedIsTop)
-      this._data.pop();  // Throw away obsolete uncommitted text.
-    this._uncommittedIsTop = true;
-    this._data.push(currentText);
-  }
-
-  /**
-   * @param {string} currentText
-   * @return {string|undefined}
-   */
-  previous(currentText) {
-    if (this._historyOffset > this._data.length)
-      return undefined;
-    if (this._historyOffset === 1)
-      this._pushCurrentText(currentText);
-    ++this._historyOffset;
-    return this._currentHistoryItem();
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  next() {
-    if (this._historyOffset === 1)
-      return undefined;
-    --this._historyOffset;
-    return this._currentHistoryItem();
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  _currentHistoryItem() {
-    return this._data[this._data.length - this._historyOffset];
-  }
-};
-
-Console.ConsolePrompt.Events = {
-  TextChanged: Symbol('TextChanged')
-};
diff --git a/front_end/console/ConsoleSidebar.js b/front_end/console/ConsoleSidebar.js
deleted file mode 100644
index 8154fb9..0000000
--- a/front_end/console/ConsoleSidebar.js
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Console.ConsoleSidebar = class extends UI.VBox {
-  /**
-   * @param {!ProductRegistry.BadgePool} badgePool
-   */
-  constructor(badgePool) {
-    super(true);
-    this.setMinimumSize(125, 0);
-
-    this._tree = new UI.TreeOutlineInShadow();
-    this._tree.registerRequiredCSS('console/consoleSidebar.css');
-    this._tree.addEventListener(UI.TreeOutline.Events.ElementSelected, this._selectionChanged.bind(this));
-    this.contentElement.appendChild(this._tree.element);
-    /** @type {?UI.TreeElement} */
-    this._selectedTreeElement = null;
-    /** @type {!Array<!Console.ConsoleSidebar.FilterTreeElement>} */
-    this._treeElements = [];
-    const selectedFilterSetting = Common.settings.createSetting('console.sidebarSelectedFilter', null);
-
-    const Levels = SDK.ConsoleMessage.MessageLevel;
-    const consoleAPIParsedFilters = [{
-      key: Console.ConsoleFilter.FilterType.Source,
-      text: SDK.ConsoleMessage.MessageSource.ConsoleAPI,
-      negative: false
-    }];
-    this._appendGroup(
-        Console.ConsoleSidebar._groupSingularName.All, [], Console.ConsoleFilter.allLevelsFilterValue(),
-        UI.Icon.create('mediumicon-list'), badgePool, selectedFilterSetting);
-    this._appendGroup(
-        Console.ConsoleSidebar._groupSingularName.ConsoleAPI, consoleAPIParsedFilters,
-        Console.ConsoleFilter.allLevelsFilterValue(), UI.Icon.create('mediumicon-account-circle'), badgePool,
-        selectedFilterSetting);
-    this._appendGroup(
-        Console.ConsoleSidebar._groupSingularName.Error, [], Console.ConsoleFilter.singleLevelMask(Levels.Error),
-        UI.Icon.create('mediumicon-error-circle'), badgePool, selectedFilterSetting);
-    this._appendGroup(
-        Console.ConsoleSidebar._groupSingularName.Warning, [], Console.ConsoleFilter.singleLevelMask(Levels.Warning),
-        UI.Icon.create('mediumicon-warning-triangle'), badgePool, selectedFilterSetting);
-    this._appendGroup(
-        Console.ConsoleSidebar._groupSingularName.Info, [], Console.ConsoleFilter.singleLevelMask(Levels.Info),
-        UI.Icon.create('mediumicon-info-circle'), badgePool, selectedFilterSetting);
-    this._appendGroup(
-        Console.ConsoleSidebar._groupSingularName.Verbose, [], Console.ConsoleFilter.singleLevelMask(Levels.Verbose),
-        UI.Icon.create('mediumicon-bug'), badgePool, selectedFilterSetting);
-    const selectedTreeElementName = selectedFilterSetting.get();
-    const defaultTreeElement =
-        this._treeElements.find(x => x.name() === selectedTreeElementName) || this._treeElements[0];
-    defaultTreeElement.select();
-  }
-
-  /**
-   * @param {string} name
-   * @param {!Array<!TextUtils.FilterParser.ParsedFilter>} parsedFilters
-   * @param {!Object<string, boolean>} levelsMask
-   * @param {!Element} icon
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {!Common.Setting} selectedFilterSetting
-   */
-  _appendGroup(name, parsedFilters, levelsMask, icon, badgePool, selectedFilterSetting) {
-    const filter = new Console.ConsoleFilter(name, parsedFilters, null, levelsMask);
-    const treeElement = new Console.ConsoleSidebar.FilterTreeElement(filter, icon, badgePool, selectedFilterSetting);
-    this._tree.appendChild(treeElement);
-    this._treeElements.push(treeElement);
-  }
-
-  clear() {
-    for (const treeElement of this._treeElements)
-      treeElement.clear();
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   */
-  onMessageAdded(viewMessage) {
-    for (const treeElement of this._treeElements)
-      treeElement.onMessageAdded(viewMessage);
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   * @return {boolean}
-   */
-  shouldBeVisible(viewMessage) {
-    if (!this._selectedTreeElement)
-      return true;
-    return this._selectedTreeElement._filter.shouldBeVisible(viewMessage);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _selectionChanged(event) {
-    this._selectedTreeElement = /** @type {!UI.TreeElement} */ (event.data);
-    this.dispatchEventToListeners(Console.ConsoleSidebar.Events.FilterSelected);
-  }
-};
-
-/** @enum {symbol} */
-Console.ConsoleSidebar.Events = {
-  FilterSelected: Symbol('FilterSelected')
-};
-
-Console.ConsoleSidebar.URLGroupTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Console.ConsoleFilter} filter
-   * @param {?Element} badge
-   */
-  constructor(filter, badge) {
-    super(filter.name);
-    this._filter = filter;
-    this._countElement = this.listItemElement.createChild('span', 'count');
-    const leadingIcons = [UI.Icon.create('largeicon-navigator-file')];
-    if (badge)
-      leadingIcons.push(badge);
-    this.setLeadingIcons(leadingIcons);
-    this._messageCount = 0;
-  }
-
-  incrementAndUpdateCounter() {
-    this._messageCount++;
-    this._countElement.textContent = this._messageCount;
-  }
-};
-
-Console.ConsoleSidebar.FilterTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Console.ConsoleFilter} filter
-   * @param {!Element} icon
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {!Common.Setting} selectedFilterSetting
-   */
-  constructor(filter, icon, badgePool, selectedFilterSetting) {
-    super(filter.name);
-    this._filter = filter;
-    this._badgePool = badgePool;
-    this._selectedFilterSetting = selectedFilterSetting;
-    /** @type {!Map<?string, !Console.ConsoleSidebar.URLGroupTreeElement>} */
-    this._urlTreeElements = new Map();
-    this.setLeadingIcons([icon]);
-    this._messageCount = 0;
-    this._updateCounter();
-  }
-
-  clear() {
-    this._urlTreeElements.clear();
-    this.removeChildren();
-    this._messageCount = 0;
-    this._updateCounter();
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._filter.name;
-  }
-
-  /**
-   * @param {boolean=} selectedByUser
-   * @return {boolean}
-   * @override
-   */
-  onselect(selectedByUser) {
-    this._selectedFilterSetting.set(this._filter.name);
-    return super.onselect(selectedByUser);
-  }
-
-  _updateCounter() {
-    const prefix = this._messageCount ? this._messageCount : Common.UIString('No');
-    const pluralizedName = this._messageCount === 1 ? this._filter.name :
-                                                      Console.ConsoleSidebar._groupPluralNameMap.get(this._filter.name);
-    this.title = `${prefix} ${pluralizedName}`;
-    this.setExpandable(!!this.childCount());
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   */
-  onMessageAdded(viewMessage) {
-    const message = viewMessage.consoleMessage();
-    const shouldIncrementCounter = message.type !== SDK.ConsoleMessage.MessageType.Command &&
-        message.type !== SDK.ConsoleMessage.MessageType.Result && !message.isGroupMessage();
-    if (!this._filter.shouldBeVisible(viewMessage) || !shouldIncrementCounter)
-      return;
-    const child = this._childElement(message.url);
-    child.incrementAndUpdateCounter();
-    this._messageCount++;
-    this._updateCounter();
-  }
-
-  /**
-   * @param {string=} url
-   * @return {!Console.ConsoleSidebar.URLGroupTreeElement}
-   */
-  _childElement(url) {
-    const urlValue = url || null;
-    let child = this._urlTreeElements.get(urlValue);
-    if (child)
-      return child;
-
-    const filter = this._filter.clone();
-    const parsedURL = urlValue ? urlValue.asParsedURL() : null;
-    if (urlValue)
-      filter.name = parsedURL ? parsedURL.displayName : urlValue;
-    else
-      filter.name = Common.UIString('<other>');
-    filter.parsedFilters.push({key: Console.ConsoleFilter.FilterType.Url, text: urlValue, negative: false});
-    const badge = parsedURL ? this._badgePool.badgeForURL(parsedURL) : null;
-    child = new Console.ConsoleSidebar.URLGroupTreeElement(filter, badge);
-    if (urlValue)
-      child.tooltip = urlValue;
-    this._urlTreeElements.set(urlValue, child);
-    this.appendChild(child);
-    return child;
-  }
-};
-
-/** @enum {string} */
-Console.ConsoleSidebar._groupSingularName = {
-  ConsoleAPI: Common.UIString('user message'),
-  All: Common.UIString('message'),
-  Error: Common.UIString('error'),
-  Warning: Common.UIString('warning'),
-  Info: Common.UIString('info'),
-  Verbose: Common.UIString('verbose')
-};
-
-/** @const {!Map<string, string>} */
-Console.ConsoleSidebar._groupPluralNameMap = new Map([
-  [Console.ConsoleSidebar._groupSingularName.ConsoleAPI, Common.UIString('user messages')],
-  [Console.ConsoleSidebar._groupSingularName.All, Common.UIString('messages')],
-  [Console.ConsoleSidebar._groupSingularName.Error, Common.UIString('errors')],
-  [Console.ConsoleSidebar._groupSingularName.Warning, Common.UIString('warnings')],
-  [Console.ConsoleSidebar._groupSingularName.Info, Common.UIString('info')],
-  [Console.ConsoleSidebar._groupSingularName.Verbose, Common.UIString('verbose')]
-]);
diff --git a/front_end/console/ConsoleView.js b/front_end/console/ConsoleView.js
deleted file mode 100644
index 607e8a2..0000000
--- a/front_end/console/ConsoleView.js
+++ /dev/null
@@ -1,1521 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.Searchable}
- * @implements {Console.ConsoleViewportProvider}
- * @unrestricted
- */
-Console.ConsoleView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.setMinimumSize(0, 35);
-    this.registerRequiredCSS('console/consoleView.css');
-    this.registerRequiredCSS('object_ui/objectValue.css');
-
-    this._searchableView = new UI.SearchableView(this);
-    this._searchableView.element.classList.add('console-searchable-view');
-    this._searchableView.setPlaceholder(Common.UIString('Find string in logs'));
-    this._searchableView.setMinimalSearchQuerySize(0);
-    this._badgePool = new ProductRegistry.BadgePool();
-    this._sidebar = new Console.ConsoleSidebar(this._badgePool);
-    this._sidebar.addEventListener(Console.ConsoleSidebar.Events.FilterSelected, this._onFilterChanged.bind(this));
-    this._isSidebarOpen = false;
-    this._filter = new Console.ConsoleViewFilter(this._onFilterChanged.bind(this));
-
-    const toolbar = new UI.Toolbar('', this.element);
-    this._splitWidget =
-        new UI.SplitWidget(true /* isVertical */, false /* secondIsSidebar */, 'console.sidebar.width', 100);
-    this._splitWidget.setMainWidget(this._searchableView);
-    this._splitWidget.setSidebarWidget(this._sidebar);
-    this._splitWidget.show(this.element);
-    this._splitWidget.hideSidebar();
-    this._splitWidget.enableShowModeSaving();
-    this._isSidebarOpen = this._splitWidget.showMode() === UI.SplitWidget.ShowMode.Both;
-    if (this._isSidebarOpen)
-      this._filter._levelMenuButton.setEnabled(false);
-    toolbar.appendToolbarItem(this._splitWidget.createShowHideSidebarButton('console sidebar'));
-    this._splitWidget.addEventListener(UI.SplitWidget.Events.ShowModeChanged, event => {
-      this._isSidebarOpen = event.data === UI.SplitWidget.ShowMode.Both;
-      this._filter._levelMenuButton.setEnabled(!this._isSidebarOpen);
-      this._onFilterChanged();
-    });
-    this._contentsElement = this._searchableView.element;
-    this.element.classList.add('console-view');
-
-    /** @type {!Array.<!Console.ConsoleViewMessage>} */
-    this._visibleViewMessages = [];
-    this._urlToMessageCount = {};
-    this._hiddenByFilterCount = 0;
-    /** @type {!Set<!Console.ConsoleViewMessage>} */
-    this._shouldBeHiddenCache = new Set();
-
-    /** @type {!Map<string, !Array<!Console.ConsoleViewMessage>>} */
-    this._groupableMessages = new Map();
-    /** @type {!Map<string, !Console.ConsoleViewMessage>} */
-    this._groupableMessageTitle = new Map();
-
-    /**
-     * @type {!Array.<!Console.ConsoleView.RegexMatchRange>}
-     */
-    this._regexMatchRanges = [];
-
-    this._consoleContextSelector = new Console.ConsoleContextSelector();
-
-    this._filterStatusText = new UI.ToolbarText();
-    this._filterStatusText.element.classList.add('dimmed');
-    this._showSettingsPaneSetting = Common.settings.createSetting('consoleShowSettingsToolbar', false);
-    this._showSettingsPaneButton = new UI.ToolbarSettingToggle(
-        this._showSettingsPaneSetting, 'largeicon-settings-gear', Common.UIString('Console settings'));
-    this._progressToolbarItem = new UI.ToolbarItem(createElement('div'));
-    this._groupSimilarSetting = Common.settings.moduleSetting('consoleGroupSimilar');
-    this._groupSimilarSetting.addChangeListener(() => this._updateMessageList());
-    const groupSimilarToggle =
-        new UI.ToolbarSettingCheckbox(this._groupSimilarSetting, Common.UIString('Group similar'));
-
-    toolbar.appendToolbarItem(UI.Toolbar.createActionButton(
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('console.clear'))));
-    toolbar.appendSeparator();
-    toolbar.appendToolbarItem(this._consoleContextSelector.toolbarItem());
-    toolbar.appendSeparator();
-    toolbar.appendToolbarItem(this._filter._textFilterUI);
-    toolbar.appendToolbarItem(this._filter._levelMenuButton);
-    toolbar.appendToolbarItem(groupSimilarToggle);
-    toolbar.appendToolbarItem(this._progressToolbarItem);
-    toolbar.appendSpacer();
-    toolbar.appendToolbarItem(this._filterStatusText);
-    toolbar.appendSeparator();
-    toolbar.appendToolbarItem(this._showSettingsPaneButton);
-
-    this._preserveLogCheckbox = new UI.ToolbarSettingCheckbox(
-        Common.moduleSetting('preserveConsoleLog'), Common.UIString('Do not clear log on page reload / navigation'),
-        Common.UIString('Preserve log'));
-    this._hideNetworkMessagesCheckbox = new UI.ToolbarSettingCheckbox(
-        this._filter._hideNetworkMessagesSetting, this._filter._hideNetworkMessagesSetting.title(),
-        Common.UIString('Hide network'));
-    const filterByExecutionContextCheckbox = new UI.ToolbarSettingCheckbox(
-        this._filter._filterByExecutionContextSetting,
-        Common.UIString('Only show messages from the current context (top, iframe, worker, extension)'),
-        Common.UIString('Selected context only'));
-    const monitoringXHREnabledSetting = Common.moduleSetting('monitoringXHREnabled');
-    this._timestampsSetting = Common.moduleSetting('consoleTimestampsEnabled');
-    this._consoleHistoryAutocompleteSetting = Common.moduleSetting('consoleHistoryAutocomplete');
-
-    const settingsPane = new UI.HBox();
-    settingsPane.show(this._contentsElement);
-    settingsPane.element.classList.add('console-settings-pane');
-
-    const settingsToolbarLeft = new UI.Toolbar('', settingsPane.element);
-    settingsToolbarLeft.makeVertical();
-    settingsToolbarLeft.appendToolbarItem(this._hideNetworkMessagesCheckbox);
-    settingsToolbarLeft.appendToolbarItem(this._preserveLogCheckbox);
-    settingsToolbarLeft.appendToolbarItem(filterByExecutionContextCheckbox);
-
-    const settingsToolbarRight = new UI.Toolbar('', settingsPane.element);
-    settingsToolbarRight.makeVertical();
-    settingsToolbarRight.appendToolbarItem(new UI.ToolbarSettingCheckbox(monitoringXHREnabledSetting));
-    settingsToolbarRight.appendToolbarItem(new UI.ToolbarSettingCheckbox(this._timestampsSetting));
-    settingsToolbarRight.appendToolbarItem(new UI.ToolbarSettingCheckbox(this._consoleHistoryAutocompleteSetting));
-    if (!this._showSettingsPaneSetting.get())
-      settingsPane.element.classList.add('hidden');
-    this._showSettingsPaneSetting.addChangeListener(
-        () => settingsPane.element.classList.toggle('hidden', !this._showSettingsPaneSetting.get()));
-
-    this._viewport = new Console.ConsoleViewport(this);
-    this._viewport.setStickToBottom(true);
-    this._viewport.contentElement().classList.add('console-group', 'console-group-messages');
-    this._contentsElement.appendChild(this._viewport.element);
-    this._messagesElement = this._viewport.element;
-    this._messagesElement.id = 'console-messages';
-    this._messagesElement.classList.add('monospace');
-    this._messagesElement.addEventListener('click', this._messagesClicked.bind(this), true);
-    this._messagesElement.addEventListener('paste', this._messagesPasted.bind(this), true);
-
-    this._viewportThrottler = new Common.Throttler(50);
-
-    this._topGroup = Console.ConsoleGroup.createTopGroup();
-    this._currentGroup = this._topGroup;
-
-    this._promptElement = this._messagesElement.createChild('div', 'source-code');
-    const promptIcon = UI.Icon.create('smallicon-text-prompt', 'console-prompt-icon');
-    this._promptElement.appendChild(promptIcon);
-    this._promptElement.id = 'console-prompt';
-
-    // FIXME: This is a workaround for the selection machinery bug. See crbug.com/410899
-    const selectAllFixer = this._messagesElement.createChild('div', 'console-view-fix-select-all');
-    selectAllFixer.textContent = '.';
-
-    this._registerShortcuts();
-
-    this._messagesElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
-
-    this._linkifier = new Components.Linkifier(Console.ConsoleViewMessage.MaxLengthForLinks);
-
-    /** @type {!Array.<!Console.ConsoleViewMessage>} */
-    this._consoleMessages = [];
-    this._viewMessageSymbol = Symbol('viewMessage');
-
-    this._consoleHistorySetting = Common.settings.createLocalSetting('consoleHistory', []);
-
-    this._prompt = new Console.ConsolePrompt();
-    this._prompt.show(this._promptElement);
-    this._prompt.element.addEventListener('keydown', this._promptKeyDown.bind(this), true);
-    this._prompt.addEventListener(Console.ConsolePrompt.Events.TextChanged, this._promptTextChanged, this);
-
-    this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHistoryAutocompleteChanged, this);
-
-    const historyData = this._consoleHistorySetting.get();
-    this._prompt.history().setHistoryData(historyData);
-    this._consoleHistoryAutocompleteChanged();
-
-    this._updateFilterStatus();
-    this._timestampsSetting.addChangeListener(this._consoleTimestampsSettingChanged, this);
-
-    this._registerWithMessageSink();
-
-    UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this);
-
-    this._messagesElement.addEventListener('mousedown', this._updateStickToBottomOnMouseDown.bind(this), false);
-    this._messagesElement.addEventListener('mouseup', this._updateStickToBottomOnMouseUp.bind(this), false);
-    this._messagesElement.addEventListener('mouseleave', this._updateStickToBottomOnMouseUp.bind(this), false);
-    this._messagesElement.addEventListener('wheel', this._updateStickToBottomOnWheel.bind(this), false);
-
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this);
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageUpdated, this._onConsoleMessageUpdated, this);
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this);
-    SDK.consoleModel.messages().forEach(this._addConsoleMessage, this);
-  }
-
-  /**
-   * @return {!Console.ConsoleView}
-   */
-  static instance() {
-    if (!Console.ConsoleView._instance)
-      Console.ConsoleView._instance = new Console.ConsoleView();
-    return Console.ConsoleView._instance;
-  }
-
-  static clearConsole() {
-    SDK.consoleModel.requestClearMessages();
-  }
-
-  _onFilterChanged() {
-    this._filter._currentFilter.levelsMask = this._isSidebarOpen ? Console.ConsoleFilter.allLevelsFilterValue() :
-                                                                   this._filter._messageLevelFiltersSetting.get();
-    this._cancelBuildHiddenCache();
-    if (this._immediatelyFilterMessagesForTest) {
-      for (const viewMessage of this._consoleMessages)
-        this._computeShouldMessageBeVisible(viewMessage);
-      this._updateMessageList();
-      return;
-    }
-    this._buildHiddenCache(0, this._consoleMessages.slice());
-  }
-
-  _setImmediatelyFilterMessagesForTest() {
-    this._immediatelyFilterMessagesForTest = true;
-  }
-
-  /**
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  _clearHistory() {
-    this._consoleHistorySetting.set([]);
-    this._prompt.history().setHistoryData([]);
-  }
-
-  _consoleHistoryAutocompleteChanged() {
-    this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocompleteSetting.get());
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemCount() {
-    return this._visibleViewMessages.length;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?Console.ConsoleViewportElement}
-   */
-  itemElement(index) {
-    return this._visibleViewMessages[index];
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {number}
-   */
-  fastHeight(index) {
-    return this._visibleViewMessages[index].fastHeight();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumRowHeight() {
-    return 16;
-  }
-
-  _registerWithMessageSink() {
-    Common.console.messages().forEach(this._addSinkMessage, this);
-    Common.console.addEventListener(Common.Console.Events.MessageAdded, messageAdded, this);
-
-    /**
-     * @param {!Common.Event} event
-     * @this {Console.ConsoleView}
-     */
-    function messageAdded(event) {
-      this._addSinkMessage(/** @type {!Common.Console.Message} */ (event.data));
-    }
-  }
-
-  /**
-   * @param {!Common.Console.Message} message
-   */
-  _addSinkMessage(message) {
-    let level = SDK.ConsoleMessage.MessageLevel.Verbose;
-    switch (message.level) {
-      case Common.Console.MessageLevel.Info:
-        level = SDK.ConsoleMessage.MessageLevel.Info;
-        break;
-      case Common.Console.MessageLevel.Error:
-        level = SDK.ConsoleMessage.MessageLevel.Error;
-        break;
-      case Common.Console.MessageLevel.Warning:
-        level = SDK.ConsoleMessage.MessageLevel.Warning;
-        break;
-    }
-
-    const consoleMessage = new SDK.ConsoleMessage(
-        null, SDK.ConsoleMessage.MessageSource.Other, level, message.text, SDK.ConsoleMessage.MessageType.System,
-        undefined, undefined, undefined, undefined, undefined, message.timestamp);
-    this._addConsoleMessage(consoleMessage);
-  }
-
-  _consoleTimestampsSettingChanged() {
-    this._updateMessageList();
-    this._consoleMessages.forEach(viewMessage => viewMessage.updateTimestamp());
-    this._groupableMessageTitle.forEach(viewMessage => viewMessage.updateTimestamp());
-  }
-
-  _executionContextChanged() {
-    this._prompt.clearAutocomplete();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._hidePromptSuggestBox();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._viewport.refresh();
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (!this._prompt.hasFocus()) {
-      const oldScrollTop = this._viewport.element.scrollTop;
-      this._prompt.focus();
-      this._viewport.element.scrollTop = oldScrollTop;
-    }
-  }
-
-  /**
-   * @override
-   */
-  restoreScrollPositions() {
-    if (this._viewport.stickToBottom())
-      this._immediatelyScrollToBottom();
-    else
-      super.restoreScrollPositions();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._scheduleViewportRefresh();
-    this._hidePromptSuggestBox();
-    if (this._viewport.stickToBottom())
-      this._immediatelyScrollToBottom();
-    for (let i = 0; i < this._visibleViewMessages.length; ++i)
-      this._visibleViewMessages[i].onResize();
-  }
-
-  _hidePromptSuggestBox() {
-    this._prompt.clearAutocomplete();
-  }
-
-  /**
-   * @return {!Promise.<undefined>}
-   */
-  _invalidateViewport() {
-    if (this._muteViewportUpdates) {
-      this._maybeDirtyWhileMuted = true;
-      return Promise.resolve();
-    }
-    if (this._needsFullUpdate) {
-      this._updateMessageList();
-      delete this._needsFullUpdate;
-    } else {
-      this._viewport.invalidate();
-    }
-    return Promise.resolve();
-  }
-
-  _scheduleViewportRefresh() {
-    if (this._muteViewportUpdates) {
-      this._maybeDirtyWhileMuted = true;
-      this._scheduleViewportRefreshForTest(true);
-      return;
-    } else {
-      this._scheduleViewportRefreshForTest(false);
-    }
-    this._scheduledRefreshPromiseForTest = this._viewportThrottler.schedule(this._invalidateViewport.bind(this));
-  }
-
-  /**
-   * @param {boolean} muted
-   */
-  _scheduleViewportRefreshForTest(muted) {
-    // This functions is sniffed in tests.
-  }
-
-  _immediatelyScrollToBottom() {
-    // This will scroll viewport and trigger its refresh.
-    this._viewport.setStickToBottom(true);
-    this._promptElement.scrollIntoView(true);
-  }
-
-  _updateFilterStatus() {
-    if (this._hiddenByFilterCount === this._lastShownHiddenByFilterCount)
-      return;
-    this._filterStatusText.setText(Common.UIString(this._hiddenByFilterCount + ' hidden'));
-    this._filterStatusText.setVisible(!!this._hiddenByFilterCount);
-    this._lastShownHiddenByFilterCount = this._hiddenByFilterCount;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onConsoleMessageAdded(event) {
-    const message = /** @type {!SDK.ConsoleMessage} */ (event.data);
-    this._addConsoleMessage(message);
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   */
-  _addConsoleMessage(message) {
-    const viewMessage = this._createViewMessage(message);
-    message[this._viewMessageSymbol] = viewMessage;
-    if (message.type === SDK.ConsoleMessage.MessageType.Command ||
-        message.type === SDK.ConsoleMessage.MessageType.Result) {
-      const lastMessage = this._consoleMessages.peekLast();
-      viewMessage[Console.ConsoleView._messageSortingTimeSymbol] =
-          lastMessage ? lastMessage[Console.ConsoleView._messageSortingTimeSymbol] : 0;
-    } else {
-      viewMessage[Console.ConsoleView._messageSortingTimeSymbol] = viewMessage.consoleMessage().timestamp;
-    }
-
-    let insertAt;
-    if (!this._consoleMessages.length ||
-        timeComparator(viewMessage, this._consoleMessages[this._consoleMessages.length - 1]) > 0)
-      insertAt = this._consoleMessages.length;
-    else
-      insertAt = this._consoleMessages.upperBound(viewMessage, timeComparator);
-    const insertedInMiddle = insertAt < this._consoleMessages.length;
-    this._consoleMessages.splice(insertAt, 0, viewMessage);
-
-    if (this._urlToMessageCount[message.url])
-      ++this._urlToMessageCount[message.url];
-    else
-      this._urlToMessageCount[message.url] = 1;
-
-    this._filter.onMessageAdded(message);
-    this._sidebar.onMessageAdded(viewMessage);
-
-    // If we already have similar messages, go slow path.
-    let shouldGoIntoGroup = false;
-    if (message.isGroupable()) {
-      const groupKey = viewMessage.groupKey();
-      shouldGoIntoGroup = this._groupSimilarSetting.get() && this._groupableMessages.has(groupKey);
-      let list = this._groupableMessages.get(groupKey);
-      if (!list) {
-        list = [];
-        this._groupableMessages.set(groupKey, list);
-      }
-      list.push(viewMessage);
-    }
-
-    this._computeShouldMessageBeVisible(viewMessage);
-    if (!shouldGoIntoGroup && !insertedInMiddle) {
-      this._appendMessageToEnd(viewMessage);
-      this._updateFilterStatus();
-      this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);
-    } else {
-      this._needsFullUpdate = true;
-    }
-
-    this._scheduleViewportRefresh();
-    this._consoleMessageAddedForTest(viewMessage);
-
-    /**
-     * @param {!Console.ConsoleViewMessage} viewMessage1
-     * @param {!Console.ConsoleViewMessage} viewMessage2
-     */
-    function timeComparator(viewMessage1, viewMessage2) {
-      return viewMessage1[Console.ConsoleView._messageSortingTimeSymbol] -
-          viewMessage2[Console.ConsoleView._messageSortingTimeSymbol];
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onConsoleMessageUpdated(event) {
-    const message = /** @type {!SDK.ConsoleMessage} */ (event.data);
-    const viewMessage = message[this._viewMessageSymbol];
-    if (viewMessage) {
-      viewMessage.updateMessageElement();
-      this._updateMessageList();
-    }
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   */
-  _consoleMessageAddedForTest(viewMessage) {
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   * @return {boolean}
-   */
-  _shouldMessageBeVisible(viewMessage) {
-    return !this._shouldBeHiddenCache.has(viewMessage);
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   */
-  _computeShouldMessageBeVisible(viewMessage) {
-    if (this._filter.shouldBeVisible(viewMessage) &&
-        (!this._isSidebarOpen || this._sidebar.shouldBeVisible(viewMessage)))
-      this._shouldBeHiddenCache.delete(viewMessage);
-    else
-      this._shouldBeHiddenCache.add(viewMessage);
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   * @param {boolean=} preventCollapse
-   */
-  _appendMessageToEnd(viewMessage, preventCollapse) {
-    if (!this._shouldMessageBeVisible(viewMessage)) {
-      this._hiddenByFilterCount++;
-      return;
-    }
-
-    if (!preventCollapse && this._tryToCollapseMessages(viewMessage, this._visibleViewMessages.peekLast()))
-      return;
-
-    const lastMessage = this._visibleViewMessages.peekLast();
-    if (viewMessage.consoleMessage().type === SDK.ConsoleMessage.MessageType.EndGroup) {
-      if (lastMessage && !this._currentGroup.messagesHidden())
-        lastMessage.incrementCloseGroupDecorationCount();
-      this._currentGroup = this._currentGroup.parentGroup() || this._currentGroup;
-      return;
-    }
-    if (!this._currentGroup.messagesHidden()) {
-      const originatingMessage = viewMessage.consoleMessage().originatingMessage();
-      if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage)
-        lastMessage.toMessageElement().classList.add('console-adjacent-user-command-result');
-
-      this._visibleViewMessages.push(viewMessage);
-      this._searchMessage(this._visibleViewMessages.length - 1);
-    }
-
-    if (viewMessage.consoleMessage().isGroupStartMessage())
-      this._currentGroup = new Console.ConsoleGroup(this._currentGroup, viewMessage);
-
-    this._messageAppendedForTests();
-  }
-
-  _messageAppendedForTests() {
-    // This method is sniffed in tests.
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   * @return {!Console.ConsoleViewMessage}
-   */
-  _createViewMessage(message) {
-    const nestingLevel = this._currentGroup.nestingLevel();
-    switch (message.type) {
-      case SDK.ConsoleMessage.MessageType.Command:
-        return new Console.ConsoleCommand(message, this._linkifier, this._badgePool, nestingLevel);
-      case SDK.ConsoleMessage.MessageType.Result:
-        return new Console.ConsoleCommandResult(message, this._linkifier, this._badgePool, nestingLevel);
-      case SDK.ConsoleMessage.MessageType.StartGroupCollapsed:
-      case SDK.ConsoleMessage.MessageType.StartGroup:
-        return new Console.ConsoleGroupViewMessage(message, this._linkifier, this._badgePool, nestingLevel);
-      default:
-        return new Console.ConsoleViewMessage(message, this._linkifier, this._badgePool, nestingLevel);
-    }
-  }
-
-  _consoleCleared() {
-    this._cancelBuildHiddenCache();
-    this._currentMatchRangeIndex = -1;
-    this._consoleMessages = [];
-    this._groupableMessages.clear();
-    this._groupableMessageTitle.clear();
-    this._sidebar.clear();
-    this._updateMessageList();
-    this._hidePromptSuggestBox();
-    this._viewport.setStickToBottom(true);
-    this._linkifier.reset();
-    this._badgePool.reset();
-    this._filter.clear();
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    if (event.target.isSelfOrDescendant(this._promptElement)) {
-      contextMenu.show();
-      return;
-    }
-
-    const sourceElement = event.target.enclosingNodeOrSelfWithClass('console-message-wrapper');
-    const consoleMessage = sourceElement ? sourceElement.message.consoleMessage() : null;
-
-    const filterSubMenu = contextMenu.headerSection().appendSubMenuItem(Common.UIString('Filter'));
-
-    if (consoleMessage && consoleMessage.url) {
-      const menuTitle = Common.UIString('Hide messages from %s', new Common.ParsedURL(consoleMessage.url).displayName);
-      filterSubMenu.headerSection().appendItem(
-          menuTitle, this._filter.addMessageURLFilter.bind(this._filter, consoleMessage.url));
-    }
-
-    const unhideAll = filterSubMenu.footerSection().appendItem(
-        Common.UIString('Unhide all'), this._filter.removeMessageURLFilter.bind(this._filter));
-
-    let hasFilters = false;
-
-    for (const url in this._filter.messageURLFilters()) {
-      filterSubMenu.defaultSection().appendCheckboxItem(
-          String.sprintf('%s (%d)', new Common.ParsedURL(url).displayName, this._urlToMessageCount[url]),
-          this._filter.removeMessageURLFilter.bind(this._filter, url), true);
-      hasFilters = true;
-    }
-
-    filterSubMenu.setEnabled(hasFilters || (consoleMessage && consoleMessage.url));
-    unhideAll.setEnabled(hasFilters);
-
-    contextMenu.defaultSection().appendAction('console.clear');
-    contextMenu.defaultSection().appendAction('console.clear.history');
-    contextMenu.saveSection().appendItem(Common.UIString('Save as...'), this._saveConsole.bind(this));
-    if (this.element.hasSelection()) {
-      contextMenu.clipboardSection().appendItem(
-          Common.UIString('Copy visible styled selection'), this._viewport.copyWithStyles.bind(this._viewport));
-    }
-
-    if (consoleMessage)
-      contextMenu.appendApplicableItems(consoleMessage);
-
-    contextMenu.show();
-  }
-
-  async _saveConsole() {
-    const url = SDK.targetManager.mainTarget().inspectedURL();
-    const parsedURL = url.asParsedURL();
-    const filename = String.sprintf('%s-%d.log', parsedURL ? parsedURL.host : 'console', Date.now());
-    const stream = new Bindings.FileOutputStream();
-
-    const progressIndicator = new UI.ProgressIndicator();
-    progressIndicator.setTitle(Common.UIString('Writing file…'));
-    progressIndicator.setTotalWork(this.itemCount());
-
-    /** @const */
-    const chunkSize = 350;
-
-    if (!await stream.open(filename))
-      return;
-    this._progressToolbarItem.element.appendChild(progressIndicator.element);
-
-    let messageIndex = 0;
-    while (messageIndex < this.itemCount() && !progressIndicator.isCanceled()) {
-      const messageContents = [];
-      let i;
-      for (i = 0; i < chunkSize && i + messageIndex < this.itemCount(); ++i) {
-        const message = this.itemElement(messageIndex + i);
-        messageContents.push(message.toExportString());
-      }
-      messageIndex += i;
-      await stream.write(messageContents.join('\n') + '\n');
-      progressIndicator.setWorked(messageIndex);
-    }
-
-    stream.close();
-    progressIndicator.done();
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   * @param {!Console.ConsoleViewMessage=} lastMessage
-   * @return {boolean}
-   */
-  _tryToCollapseMessages(viewMessage, lastMessage) {
-    const timestampsShown = this._timestampsSetting.get();
-    if (!timestampsShown && lastMessage && !viewMessage.consoleMessage().isGroupMessage() &&
-        viewMessage.consoleMessage().isEqual(lastMessage.consoleMessage())) {
-      lastMessage.incrementRepeatCount();
-      if (viewMessage.isLastInSimilarGroup())
-        lastMessage.setInSimilarGroup(true, true);
-      return true;
-    }
-
-    return false;
-  }
-
-  /**
-   * @param {number} startIndex
-   * @param {!Array<!Console.ConsoleViewMessage>} viewMessages
-   */
-  _buildHiddenCache(startIndex, viewMessages) {
-    const startTime = Date.now();
-    let i;
-    for (i = startIndex; i < viewMessages.length; ++i) {
-      this._computeShouldMessageBeVisible(viewMessages[i]);
-      if (i % 10 === 0 && Date.now() - startTime > 12)
-        break;
-    }
-
-    if (i === viewMessages.length) {
-      this._updateMessageList();
-      return;
-    }
-    this._buildHiddenCacheTimeout =
-        this.element.window().requestAnimationFrame(this._buildHiddenCache.bind(this, i, viewMessages));
-  }
-
-  _cancelBuildHiddenCache() {
-    this._shouldBeHiddenCache.clear();
-    if (this._buildHiddenCacheTimeout) {
-      this.element.window().cancelAnimationFrame(this._buildHiddenCacheTimeout);
-      delete this._buildHiddenCacheTimeout;
-    }
-  }
-
-  _updateMessageList() {
-    this._topGroup = Console.ConsoleGroup.createTopGroup();
-    this._currentGroup = this._topGroup;
-    this._regexMatchRanges = [];
-    this._hiddenByFilterCount = 0;
-    for (let i = 0; i < this._visibleViewMessages.length; ++i) {
-      this._visibleViewMessages[i].resetCloseGroupDecorationCount();
-      this._visibleViewMessages[i].resetIncrementRepeatCount();
-    }
-    this._visibleViewMessages = [];
-    if (this._groupSimilarSetting.get()) {
-      this._addGroupableMessagesToEnd();
-    } else {
-      for (let i = 0; i < this._consoleMessages.length; ++i) {
-        this._consoleMessages[i].setInSimilarGroup(false);
-        this._appendMessageToEnd(this._consoleMessages[i]);
-      }
-    }
-    this._updateFilterStatus();
-    this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);
-    this._viewport.invalidate();
-  }
-
-  _addGroupableMessagesToEnd() {
-    /** @type {!Set<!SDK.ConsoleMessage>} */
-    const alreadyAdded = new Set();
-    for (let i = 0; i < this._consoleMessages.length; ++i) {
-      const viewMessage = this._consoleMessages[i];
-      const message = viewMessage.consoleMessage();
-      if (alreadyAdded.has(message))
-        continue;
-
-      if (!message.isGroupable()) {
-        this._appendMessageToEnd(viewMessage);
-        alreadyAdded.add(message);
-        continue;
-      }
-
-      const key = viewMessage.groupKey();
-      const viewMessagesInGroup = this._groupableMessages.get(key);
-      if (!viewMessagesInGroup || viewMessagesInGroup.length < 5) {
-        viewMessage.setInSimilarGroup(false);
-        this._appendMessageToEnd(viewMessage);
-        alreadyAdded.add(message);
-        continue;
-      }
-
-      if (!viewMessagesInGroup.find(x => this._shouldMessageBeVisible(x))) {
-        // Optimize for speed.
-        alreadyAdded.addAll(viewMessagesInGroup);
-        continue;
-      }
-
-      // Create artificial group start and end messages.
-      let startGroupViewMessage = this._groupableMessageTitle.get(key);
-      if (!startGroupViewMessage) {
-        const startGroupMessage = new SDK.ConsoleMessage(
-            null, message.source, message.level, viewMessage.groupTitle(),
-            SDK.ConsoleMessage.MessageType.StartGroupCollapsed);
-        startGroupViewMessage = this._createViewMessage(startGroupMessage);
-        this._groupableMessageTitle.set(key, startGroupViewMessage);
-      }
-      startGroupViewMessage.setRepeatCount(viewMessagesInGroup.length);
-      this._appendMessageToEnd(startGroupViewMessage);
-
-      for (const viewMessageInGroup of viewMessagesInGroup) {
-        viewMessageInGroup.setInSimilarGroup(true, viewMessagesInGroup.peekLast() === viewMessageInGroup);
-        this._appendMessageToEnd(viewMessageInGroup, true);
-        alreadyAdded.add(viewMessageInGroup.consoleMessage());
-      }
-
-      const endGroupMessage = new SDK.ConsoleMessage(
-          null, message.source, message.level, message.messageText, SDK.ConsoleMessage.MessageType.EndGroup);
-      this._appendMessageToEnd(this._createViewMessage(endGroupMessage));
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _messagesClicked(event) {
-    // Do not focus prompt if messages have selection.
-    if (!this._messagesElement.hasSelection()) {
-      const clickedOutsideMessageList = event.target === this._messagesElement;
-      if (clickedOutsideMessageList)
-        this._prompt.moveCaretToEndOfPrompt();
-      this.focus();
-    }
-    // TODO: fix this.
-    const groupMessage = event.target.enclosingNodeOrSelfWithClass('console-group-title');
-    if (!groupMessage)
-      return;
-    const consoleGroupViewMessage = groupMessage.message;
-    consoleGroupViewMessage.setCollapsed(!consoleGroupViewMessage.collapsed());
-    this._updateMessageList();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _messagesPasted(event) {
-    if (UI.isEditing())
-      return;
-    this._prompt.focus();
-  }
-
-  _registerShortcuts() {
-    this._shortcuts = {};
-
-    const shortcut = UI.KeyboardShortcut;
-    const section = UI.shortcutsScreen.section(Common.UIString('Console'));
-
-    const shortcutL = shortcut.makeDescriptor('l', UI.KeyboardShortcut.Modifiers.Ctrl);
-    let keys = [shortcutL];
-    if (Host.isMac()) {
-      const shortcutK = shortcut.makeDescriptor('k', UI.KeyboardShortcut.Modifiers.Meta);
-      keys.unshift(shortcutK);
-    }
-    section.addAlternateKeys(keys, Common.UIString('Clear console'));
-
-    keys = [shortcut.makeDescriptor(shortcut.Keys.Tab), shortcut.makeDescriptor(shortcut.Keys.Right)];
-    section.addRelatedKeys(keys, Common.UIString('Accept suggestion'));
-
-    const shortcutU = shortcut.makeDescriptor('u', UI.KeyboardShortcut.Modifiers.Ctrl);
-    this._shortcuts[shortcutU.key] = this._clearPromptBackwards.bind(this);
-    section.addAlternateKeys([shortcutU], Common.UIString('Clear console prompt'));
-
-    keys = [shortcut.makeDescriptor(shortcut.Keys.Down), shortcut.makeDescriptor(shortcut.Keys.Up)];
-    section.addRelatedKeys(keys, Common.UIString('Next/previous line'));
-
-    if (Host.isMac()) {
-      keys =
-          [shortcut.makeDescriptor('N', shortcut.Modifiers.Alt), shortcut.makeDescriptor('P', shortcut.Modifiers.Alt)];
-      section.addRelatedKeys(keys, Common.UIString('Next/previous command'));
-    }
-
-    section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), Common.UIString('Execute command'));
-  }
-
-  _clearPromptBackwards() {
-    this._prompt.setText('');
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _promptKeyDown(event) {
-    const keyboardEvent = /** @type {!KeyboardEvent} */ (event);
-    if (keyboardEvent.key === 'PageUp') {
-      this._updateStickToBottomOnWheel();
-      return;
-    }
-
-    const shortcut = UI.KeyboardShortcut.makeKeyFromEvent(keyboardEvent);
-    const handler = this._shortcuts[shortcut];
-    if (handler) {
-      handler();
-      keyboardEvent.preventDefault();
-    }
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} result
-   * @param {!SDK.ConsoleMessage} originatingConsoleMessage
-   * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
-   */
-  _printResult(result, originatingConsoleMessage, exceptionDetails) {
-    if (!result)
-      return;
-
-    const level = !!exceptionDetails ? SDK.ConsoleMessage.MessageLevel.Error : SDK.ConsoleMessage.MessageLevel.Info;
-    let message;
-    if (!exceptionDetails) {
-      message = new SDK.ConsoleMessage(
-          result.runtimeModel(), SDK.ConsoleMessage.MessageSource.JS, level, '', SDK.ConsoleMessage.MessageType.Result,
-          undefined, undefined, undefined, [result]);
-    } else {
-      message = SDK.ConsoleMessage.fromException(
-          result.runtimeModel(), exceptionDetails, SDK.ConsoleMessage.MessageType.Result, undefined, undefined);
-    }
-    message.setOriginatingMessage(originatingConsoleMessage);
-    SDK.consoleModel.addMessage(message);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _commandEvaluated(event) {
-    const data =
-        /** @type {{result: ?SDK.RemoteObject, commandMessage: !SDK.ConsoleMessage, exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined)}} */
-        (event.data);
-    this._prompt.history().pushHistoryItem(data.commandMessage.messageText);
-    this._consoleHistorySetting.set(
-        this._prompt.history().historyData().slice(-Console.ConsoleView.persistedHistorySize));
-    this._printResult(data.result, data.commandMessage, data.exceptionDetails);
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [this._messagesElement];
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._cleanupAfterSearch();
-    for (let i = 0; i < this._visibleViewMessages.length; ++i) {
-      const message = this._visibleViewMessages[i];
-      message.setSearchRegex(null);
-    }
-    this._currentMatchRangeIndex = -1;
-    this._regexMatchRanges = [];
-    delete this._searchRegex;
-    this._viewport.refresh();
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this.searchCanceled();
-    this._searchableView.updateSearchMatchesCount(0);
-
-    this._searchRegex = searchConfig.toSearchRegex(true);
-
-    this._regexMatchRanges = [];
-    this._currentMatchRangeIndex = -1;
-
-    if (shouldJump)
-      this._searchShouldJumpBackwards = !!jumpBackwards;
-
-    this._searchProgressIndicator = new UI.ProgressIndicator();
-    this._searchProgressIndicator.setTitle(Common.UIString('Searching…'));
-    this._searchProgressIndicator.setTotalWork(this._visibleViewMessages.length);
-    this._progressToolbarItem.element.appendChild(this._searchProgressIndicator.element);
-
-    this._innerSearch(0);
-  }
-
-  _cleanupAfterSearch() {
-    delete this._searchShouldJumpBackwards;
-    if (this._innerSearchTimeoutId) {
-      clearTimeout(this._innerSearchTimeoutId);
-      delete this._innerSearchTimeoutId;
-    }
-    if (this._searchProgressIndicator) {
-      this._searchProgressIndicator.done();
-      delete this._searchProgressIndicator;
-    }
-  }
-
-  _searchFinishedForTests() {
-    // This method is sniffed in tests.
-  }
-
-  /**
-   * @param {number} index
-   */
-  _innerSearch(index) {
-    delete this._innerSearchTimeoutId;
-    if (this._searchProgressIndicator.isCanceled()) {
-      this._cleanupAfterSearch();
-      return;
-    }
-
-    const startTime = Date.now();
-    for (; index < this._visibleViewMessages.length && Date.now() - startTime < 100; ++index)
-      this._searchMessage(index);
-
-    this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length);
-    if (typeof this._searchShouldJumpBackwards !== 'undefined' && this._regexMatchRanges.length) {
-      this._jumpToMatch(this._searchShouldJumpBackwards ? -1 : 0);
-      delete this._searchShouldJumpBackwards;
-    }
-
-    if (index === this._visibleViewMessages.length) {
-      this._cleanupAfterSearch();
-      setTimeout(this._searchFinishedForTests.bind(this), 0);
-      return;
-    }
-
-    this._innerSearchTimeoutId = setTimeout(this._innerSearch.bind(this, index), 100);
-    this._searchProgressIndicator.setWorked(index);
-  }
-
-  /**
-   * @param {number} index
-   */
-  _searchMessage(index) {
-    const message = this._visibleViewMessages[index];
-    message.setSearchRegex(this._searchRegex);
-    for (let i = 0; i < message.searchCount(); ++i)
-      this._regexMatchRanges.push({messageIndex: index, matchIndex: i});
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    this._jumpToMatch(this._currentMatchRangeIndex + 1);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    this._jumpToMatch(this._currentMatchRangeIndex - 1);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-
-  /**
-   * @param {number} index
-   */
-  _jumpToMatch(index) {
-    if (!this._regexMatchRanges.length)
-      return;
-
-    let matchRange;
-    if (this._currentMatchRangeIndex >= 0) {
-      matchRange = this._regexMatchRanges[this._currentMatchRangeIndex];
-      const message = this._visibleViewMessages[matchRange.messageIndex];
-      message.searchHighlightNode(matchRange.matchIndex).classList.remove(UI.highlightedCurrentSearchResultClassName);
-    }
-
-    index = mod(index, this._regexMatchRanges.length);
-    this._currentMatchRangeIndex = index;
-    this._searchableView.updateCurrentMatchIndex(index);
-    matchRange = this._regexMatchRanges[index];
-    const message = this._visibleViewMessages[matchRange.messageIndex];
-    const highlightNode = message.searchHighlightNode(matchRange.matchIndex);
-    highlightNode.classList.add(UI.highlightedCurrentSearchResultClassName);
-    this._viewport.scrollItemIntoView(matchRange.messageIndex);
-    highlightNode.scrollIntoViewIfNeeded();
-  }
-
-  _updateStickToBottomOnMouseDown() {
-    this._muteViewportUpdates = true;
-    this._viewport.setStickToBottom(false);
-    if (this._waitForScrollTimeout) {
-      clearTimeout(this._waitForScrollTimeout);
-      delete this._waitForScrollTimeout;
-    }
-  }
-
-  _updateStickToBottomOnMouseUp() {
-    if (!this._muteViewportUpdates)
-      return;
-
-    // Delay querying isScrolledToBottom to give time for smooth scroll
-    // events to arrive. The value for the longest timeout duration is
-    // retrieved from crbug.com/575409.
-    this._waitForScrollTimeout = setTimeout(updateViewportState.bind(this), 200);
-
-    /**
-     * @this {!Console.ConsoleView}
-     */
-    function updateViewportState() {
-      this._muteViewportUpdates = false;
-      if (this.isShowing())
-        this._viewport.setStickToBottom(this._messagesElement.isScrolledToBottom());
-      if (this._maybeDirtyWhileMuted) {
-        this._scheduleViewportRefresh();
-        delete this._maybeDirtyWhileMuted;
-      }
-      delete this._waitForScrollTimeout;
-      this._updateViewportStickinessForTest();
-    }
-  }
-
-  _updateViewportStickinessForTest() {
-    // This method is sniffed in tests.
-  }
-
-  _updateStickToBottomOnWheel() {
-    this._updateStickToBottomOnMouseDown();
-    this._updateStickToBottomOnMouseUp();
-  }
-
-  _promptTextChanged() {
-    this._viewport.setStickToBottom(this._messagesElement.isScrolledToBottom());
-    this._promptTextChangedForTest();
-  }
-
-  _promptTextChangedForTest() {
-    // This method is sniffed in tests.
-  }
-};
-
-Console.ConsoleView.persistedHistorySize = 300;
-
-Console.ConsoleViewFilter = class {
-  /**
-   * @param {function()} filterChangedCallback
-   */
-  constructor(filterChangedCallback) {
-    this._filterChanged = filterChangedCallback;
-
-    this._messageURLFiltersSetting = Common.settings.createSetting('messageURLFilters', {});
-    this._messageLevelFiltersSetting = Console.ConsoleViewFilter.levelFilterSetting();
-    this._hideNetworkMessagesSetting = Common.moduleSetting('hideNetworkMessages');
-    this._filterByExecutionContextSetting = Common.moduleSetting('selectedContextFilterEnabled');
-
-    this._messageURLFiltersSetting.addChangeListener(this._onFilterChanged.bind(this));
-    this._messageLevelFiltersSetting.addChangeListener(this._onFilterChanged.bind(this));
-    this._hideNetworkMessagesSetting.addChangeListener(this._onFilterChanged.bind(this));
-    this._filterByExecutionContextSetting.addChangeListener(this._onFilterChanged.bind(this));
-    UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._onFilterChanged, this);
-
-    const filterKeys = Object.values(Console.ConsoleFilter.FilterType);
-    this._suggestionBuilder = new UI.FilterSuggestionBuilder(filterKeys);
-    this._textFilterUI = new UI.ToolbarInput(
-        Common.UIString('Filter'), 0.2, 1, Common.UIString('e.g. /event\\d/ -cdn url:a.com'),
-        this._suggestionBuilder.completions.bind(this._suggestionBuilder));
-    this._textFilterSetting = Common.settings.createSetting('console.textFilter', '');
-    if (this._textFilterSetting.get())
-      this._textFilterUI.setValue(this._textFilterSetting.get());
-    this._textFilterUI.addEventListener(UI.ToolbarInput.Event.TextChanged, () => {
-      this._textFilterSetting.set(this._textFilterUI.value());
-      this._onFilterChanged();
-    });
-    this._filterParser = new TextUtils.FilterParser(filterKeys);
-    this._currentFilter = new Console.ConsoleFilter('', [], null, this._messageLevelFiltersSetting.get());
-    this._updateCurrentFilter();
-
-    this._levelLabels = {};
-    this._levelLabels[SDK.ConsoleMessage.MessageLevel.Verbose] = Common.UIString('Verbose');
-    this._levelLabels[SDK.ConsoleMessage.MessageLevel.Info] = Common.UIString('Info');
-    this._levelLabels[SDK.ConsoleMessage.MessageLevel.Warning] = Common.UIString('Warnings');
-    this._levelLabels[SDK.ConsoleMessage.MessageLevel.Error] = Common.UIString('Errors');
-
-    this._levelMenuButton = new UI.ToolbarButton('');
-    this._levelMenuButton.turnIntoSelect();
-    this._levelMenuButton.addEventListener(UI.ToolbarButton.Events.Click, this._showLevelContextMenu.bind(this));
-
-    this._updateLevelMenuButtonText();
-    this._messageLevelFiltersSetting.addChangeListener(this._updateLevelMenuButtonText.bind(this));
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   */
-  onMessageAdded(message) {
-    if (message.type === SDK.ConsoleMessage.MessageType.Command ||
-        message.type === SDK.ConsoleMessage.MessageType.Result || message.isGroupMessage())
-      return;
-    if (message.context)
-      this._suggestionBuilder.addItem(Console.ConsoleFilter.FilterType.Context, message.context);
-    if (message.source)
-      this._suggestionBuilder.addItem(Console.ConsoleFilter.FilterType.Source, message.source);
-    if (message.url)
-      this._suggestionBuilder.addItem(Console.ConsoleFilter.FilterType.Url, message.url);
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  static levelFilterSetting() {
-    return Common.settings.createSetting('messageLevelFilters', Console.ConsoleFilter.defaultLevelsFilterValue());
-  }
-
-  _updateCurrentFilter() {
-    let parsedFilters = this._filterParser.parse(this._textFilterUI.value());
-
-    if (this._hideNetworkMessagesSetting.get()) {
-      parsedFilters.push({
-        key: Console.ConsoleFilter.FilterType.Source,
-        text: SDK.ConsoleMessage.MessageSource.Network,
-        negative: true
-      });
-    }
-
-    const blockedURLs = Object.keys(this._messageURLFiltersSetting.get());
-    const urlFilters = blockedURLs.map(url => ({key: Console.ConsoleFilter.FilterType.Url, text: url, negative: true}));
-    parsedFilters = parsedFilters.concat(urlFilters);
-
-    this._currentFilter.executionContext =
-        this._filterByExecutionContextSetting.get() ? UI.context.flavor(SDK.ExecutionContext) : null;
-    this._currentFilter.parsedFilters = parsedFilters;
-    this._currentFilter.levelsMask = this._messageLevelFiltersSetting.get();
-  }
-
-  _onFilterChanged() {
-    this._updateCurrentFilter();
-    this._filterChanged();
-  }
-
-  _updateLevelMenuButtonText() {
-    let isAll = true;
-    let isDefault = true;
-    const allValue = Console.ConsoleFilter.allLevelsFilterValue();
-    const defaultValue = Console.ConsoleFilter.defaultLevelsFilterValue();
-
-    let text = null;
-    const levels = this._messageLevelFiltersSetting.get();
-    for (const name of Object.values(SDK.ConsoleMessage.MessageLevel)) {
-      isAll = isAll && levels[name] === allValue[name];
-      isDefault = isDefault && levels[name] === defaultValue[name];
-      if (levels[name])
-        text = text ? Common.UIString('Custom levels') : Common.UIString('%s only', this._levelLabels[name]);
-    }
-    if (isAll)
-      text = Common.UIString('All levels');
-    else if (isDefault)
-      text = Common.UIString('Default levels');
-    else
-      text = text || Common.UIString('Hide all');
-    this._levelMenuButton.setText(text);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _showLevelContextMenu(event) {
-    const mouseEvent = /** @type {!Event} */ (event.data);
-    const setting = this._messageLevelFiltersSetting;
-    const levels = setting.get();
-
-    const contextMenu = new UI.ContextMenu(
-        mouseEvent, true /* useSoftMenu */, this._levelMenuButton.element.totalOffsetLeft(),
-        this._levelMenuButton.element.totalOffsetTop() + this._levelMenuButton.element.offsetHeight);
-    contextMenu.headerSection().appendItem(
-        Common.UIString('Default'), () => setting.set(Console.ConsoleFilter.defaultLevelsFilterValue()));
-    for (const level in this._levelLabels) {
-      contextMenu.defaultSection().appendCheckboxItem(
-          this._levelLabels[level], toggleShowLevel.bind(null, level), levels[level]);
-    }
-    contextMenu.show();
-
-    /**
-     * @param {string} level
-     */
-    function toggleShowLevel(level) {
-      levels[level] = !levels[level];
-      setting.set(levels);
-    }
-  }
-
-  /**
-   * @param {string} url
-   */
-  addMessageURLFilter(url) {
-    const value = this._messageURLFiltersSetting.get();
-    value[url] = true;
-    this._messageURLFiltersSetting.set(value);
-  }
-
-  /**
-   * @param {string} url
-   */
-  removeMessageURLFilter(url) {
-    let value;
-    if (url) {
-      value = this._messageURLFiltersSetting.get();
-      delete value[url];
-    } else {
-      value = {};
-    }
-    this._messageURLFiltersSetting.set(value);
-  }
-
-  /**
-   * @returns {!Object}
-   */
-  messageURLFilters() {
-    return this._messageURLFiltersSetting.get();
-  }
-
-  /**
-   * @param {!Console.ConsoleViewMessage} viewMessage
-   * @return {boolean}
-   */
-  shouldBeVisible(viewMessage) {
-    return this._currentFilter.shouldBeVisible(viewMessage);
-  }
-
-  clear() {
-    this._suggestionBuilder.clear();
-  }
-
-  reset() {
-    this._messageURLFiltersSetting.set({});
-    this._messageLevelFiltersSetting.set(Console.ConsoleFilter.defaultLevelsFilterValue());
-    this._filterByExecutionContextSetting.set(false);
-    this._hideNetworkMessagesSetting.set(false);
-    this._textFilterUI.setValue('');
-    this._onFilterChanged();
-  }
-};
-
-/**
- * @unrestricted
- */
-Console.ConsoleCommand = class extends Console.ConsoleViewMessage {
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   * @param {!Components.Linkifier} linkifier
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {number} nestingLevel
-   */
-  constructor(message, linkifier, badgePool, nestingLevel) {
-    super(message, linkifier, badgePool, nestingLevel);
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  contentElement() {
-    if (!this._contentElement) {
-      this._contentElement = createElementWithClass('div', 'console-user-command');
-      const icon = UI.Icon.create('smallicon-user-command', 'command-result-icon');
-      this._contentElement.appendChild(icon);
-
-      this._contentElement.message = this;
-
-      this._formattedCommand = createElementWithClass('span', 'source-code');
-      this._formattedCommand.textContent = this.text.replaceControlCharacters();
-      this._contentElement.appendChild(this._formattedCommand);
-
-      if (this._formattedCommand.textContent.length < Console.ConsoleCommand.MaxLengthToIgnoreHighlighter) {
-        const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter('text/javascript', true);
-        javascriptSyntaxHighlighter.syntaxHighlightNode(this._formattedCommand).then(this._updateSearch.bind(this));
-      } else {
-        this._updateSearch();
-      }
-
-      this.updateTimestamp();
-    }
-    return this._contentElement;
-  }
-
-  _updateSearch() {
-    this.setSearchRegex(this.searchRegex());
-  }
-};
-
-/**
- * The maximum length before strings are considered too long for syntax highlighting.
- * @const
- * @type {number}
- */
-Console.ConsoleCommand.MaxLengthToIgnoreHighlighter = 10000;
-
-Console.ConsoleCommandResult = class extends Console.ConsoleViewMessage {
-  /**
-   * @param {!SDK.ConsoleMessage} message
-   * @param {!Components.Linkifier} linkifier
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {number} nestingLevel
-   */
-  constructor(message, linkifier, badgePool, nestingLevel) {
-    super(message, linkifier, badgePool, nestingLevel);
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  contentElement() {
-    const element = super.contentElement();
-    if (!element.classList.contains('console-user-command-result')) {
-      element.classList.add('console-user-command-result');
-      if (this.consoleMessage().level === SDK.ConsoleMessage.MessageLevel.Info) {
-        const icon = UI.Icon.create('smallicon-command-result', 'command-result-icon');
-        element.insertBefore(icon, element.firstChild);
-      }
-    }
-    return element;
-  }
-};
-
-Console.ConsoleGroup = class {
-  /**
-   * @param {?Console.ConsoleGroup} parentGroup
-   * @param {?Console.ConsoleViewMessage} groupMessage
-   */
-  constructor(parentGroup, groupMessage) {
-    this._parentGroup = parentGroup;
-    this._nestingLevel = parentGroup ? parentGroup.nestingLevel() + 1 : 0;
-    this._messagesHidden =
-        groupMessage && groupMessage.collapsed() || this._parentGroup && this._parentGroup.messagesHidden();
-  }
-
-  /**
-   * @return {!Console.ConsoleGroup}
-   */
-  static createTopGroup() {
-    return new Console.ConsoleGroup(null, null);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  messagesHidden() {
-    return this._messagesHidden;
-  }
-
-  /**
-   * @return {number}
-   */
-  nestingLevel() {
-    return this._nestingLevel;
-  }
-
-  /**
-   * @return {?Console.ConsoleGroup}
-   */
-  parentGroup() {
-    return this._parentGroup;
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Console.ConsoleView.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    switch (actionId) {
-      case 'console.show':
-        InspectorFrontendHost.bringToFront();
-        Common.console.show();
-        return true;
-      case 'console.clear':
-        Console.ConsoleView.clearConsole();
-        return true;
-      case 'console.clear.history':
-        Console.ConsoleView.instance()._clearHistory();
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @typedef {{messageIndex: number, matchIndex: number}}
- */
-Console.ConsoleView.RegexMatchRange;
-
-/** @type {symbol} */
-Console.ConsoleView._messageSortingTimeSymbol = Symbol('messageSortingTime');
diff --git a/front_end/console/ConsoleViewMessage.js b/front_end/console/ConsoleViewMessage.js
deleted file mode 100644
index 4862be3..0000000
--- a/front_end/console/ConsoleViewMessage.js
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.  All rights reserved.
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Console.ConsoleViewportElement}
- * @unrestricted
- */
-Console.ConsoleViewMessage = class {
-  /**
-   * @param {!SDK.ConsoleMessage} consoleMessage
-   * @param {!Components.Linkifier} linkifier
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {number} nestingLevel
-   */
-  constructor(consoleMessage, linkifier, badgePool, nestingLevel) {
-    this._message = consoleMessage;
-    this._linkifier = linkifier;
-    this._badgePool = badgePool;
-    this._repeatCount = 1;
-    this._closeGroupDecorationCount = 0;
-    this._nestingLevel = nestingLevel;
-
-    /** @type {?DataGrid.DataGrid} */
-    this._dataGrid = null;
-    this._previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter();
-    this._searchRegex = null;
-    /** @type {?UI.Icon} */
-    this._messageLevelIcon = null;
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  element() {
-    return this.toMessageElement();
-  }
-
-  /**
-   * @return {!Promise<!Element>}
-   */
-  async completeElementForTest() {
-    const element = this.toMessageElement();
-    if (this._completeElementForTestPromise)
-      await this._completeElementForTestPromise;
-    return element;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._dataGrid)
-      this._dataGrid.updateWidths();
-    this._isVisible = true;
-  }
-
-  onResize() {
-    if (!this._isVisible)
-      return;
-    if (this._dataGrid)
-      this._dataGrid.onResize();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._isVisible = false;
-    this._cachedHeight = this.contentElement().offsetHeight;
-  }
-
-  /**
-   * @return {number}
-   */
-  fastHeight() {
-    if (this._cachedHeight)
-      return this._cachedHeight;
-    // This value reflects the 18px min-height of .console-message, plus the
-    // 1px border of .console-message-wrapper. Keep in sync with consoleView.css.
-    const defaultConsoleRowHeight = 19;
-    if (this._message.type === SDK.ConsoleMessage.MessageType.Table) {
-      const table = this._message.parameters[0];
-      if (table && table.preview)
-        return defaultConsoleRowHeight * table.preview.properties.length;
-    }
-    return defaultConsoleRowHeight;
-  }
-
-  /**
-   * @return {!SDK.ConsoleMessage}
-   */
-  consoleMessage() {
-    return this._message;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _buildTableMessage() {
-    const formattedMessage = createElementWithClass('span', 'source-code');
-    const anchorElement = this._buildMessageAnchor();
-    if (anchorElement)
-      formattedMessage.appendChild(anchorElement);
-    const badgeElement = this._buildMessageBadge();
-    if (badgeElement)
-      formattedMessage.appendChild(badgeElement);
-
-    let table = this._message.parameters && this._message.parameters.length ? this._message.parameters[0] : null;
-    if (table)
-      table = this._parameterToRemoteObject(table);
-    if (!table || !table.preview)
-      return formattedMessage;
-
-    const rawValueColumnSymbol = Symbol('rawValueColumn');
-    const columnNames = [];
-    const preview = table.preview;
-    const rows = [];
-    for (let i = 0; i < preview.properties.length; ++i) {
-      const rowProperty = preview.properties[i];
-      let rowSubProperties;
-      if (rowProperty.valuePreview)
-        rowSubProperties = rowProperty.valuePreview.properties;
-      else if (rowProperty.value)
-        rowSubProperties = [{name: rawValueColumnSymbol, type: rowProperty.type, value: rowProperty.value}];
-      else
-        continue;
-
-      const rowValue = {};
-      const maxColumnsToRender = 20;
-      for (let j = 0; j < rowSubProperties.length; ++j) {
-        const cellProperty = rowSubProperties[j];
-        let columnRendered = columnNames.indexOf(cellProperty.name) !== -1;
-        if (!columnRendered) {
-          if (columnNames.length === maxColumnsToRender)
-            continue;
-          columnRendered = true;
-          columnNames.push(cellProperty.name);
-        }
-
-        if (columnRendered) {
-          const cellElement = this._renderPropertyPreviewOrAccessor(table, [rowProperty, cellProperty]);
-          cellElement.classList.add('console-message-nowrap-below');
-          rowValue[cellProperty.name] = cellElement;
-        }
-      }
-      rows.push([rowProperty.name, rowValue]);
-    }
-
-    const flatValues = [];
-    for (let i = 0; i < rows.length; ++i) {
-      const rowName = rows[i][0];
-      const rowValue = rows[i][1];
-      flatValues.push(rowName);
-      for (let j = 0; j < columnNames.length; ++j)
-        flatValues.push(rowValue[columnNames[j]]);
-    }
-    columnNames.unshift(Common.UIString('(index)'));
-    const columnDisplayNames = columnNames.map(name => name === rawValueColumnSymbol ? Common.UIString('Value') : name);
-
-    if (flatValues.length) {
-      this._dataGrid = DataGrid.SortableDataGrid.create(columnDisplayNames, flatValues);
-      this._dataGrid.setStriped(true);
-
-      const formattedResult = createElementWithClass('span', 'console-message-text');
-      const tableElement = formattedResult.createChild('div', 'console-message-formatted-table');
-      const dataGridContainer = tableElement.createChild('span');
-      tableElement.appendChild(this._formatParameter(table, true, false));
-      dataGridContainer.appendChild(this._dataGrid.element);
-      formattedMessage.appendChild(formattedResult);
-      this._dataGrid.renderInline();
-    }
-    return formattedMessage;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _buildMessage() {
-    let messageElement;
-    let messageText = this._message.messageText;
-    if (this._message.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI) {
-      switch (this._message.type) {
-        case SDK.ConsoleMessage.MessageType.Trace:
-          messageElement = this._format(this._message.parameters || ['console.trace']);
-          break;
-        case SDK.ConsoleMessage.MessageType.Clear:
-          messageElement = createElementWithClass('span', 'console-info');
-          if (Common.moduleSetting('preserveConsoleLog').get())
-            messageElement.textContent = Common.UIString('console.clear() was prevented due to \'Preserve log\'');
-          else
-            messageElement.textContent = Common.UIString('Console was cleared');
-          messageElement.title =
-              Common.UIString('Clear all messages with ' + UI.shortcutRegistry.shortcutTitleForAction('console.clear'));
-          break;
-        case SDK.ConsoleMessage.MessageType.Assert: {
-          let args = [Common.UIString('Assertion failed:')];
-          if (this._message.parameters)
-            args = args.concat(this._message.parameters);
-          messageElement = this._format(args);
-          break;
-        }
-        case SDK.ConsoleMessage.MessageType.Dir: {
-          const obj = this._message.parameters ? this._message.parameters[0] : undefined;
-          const args = ['%O', obj];
-          messageElement = this._format(args);
-          break;
-        }
-        case SDK.ConsoleMessage.MessageType.Profile:
-        case SDK.ConsoleMessage.MessageType.ProfileEnd:
-          messageElement = this._format([messageText]);
-          break;
-        default: {
-          if (this._message.parameters && this._message.parameters.length === 1 &&
-              this._message.parameters[0].type === 'string')
-            messageElement = this._tryFormatAsError(/** @type {string} */ (this._message.parameters[0].value));
-          const args = this._message.parameters || [messageText];
-          messageElement = messageElement || this._format(args);
-        }
-      }
-    } else {
-      let rendered = false;
-      this._completeElementForTestPromise = null;
-      for (const extension of self.runtime.extensions(Common.Renderer, this._message)) {
-        if (extension.descriptor()['source'] === this._message.source) {
-          messageElement = createElement('span');
-          let callback;
-          this._completeElementForTestPromise = new Promise(fulfill => callback = fulfill);
-          extension.instance().then(renderer => {
-            renderer.render(this._message)
-                .then(element => messageElement.appendChild(element || this._format([messageText])))
-                .then(callback);
-          });
-          rendered = true;
-          break;
-        }
-      }
-      if (!rendered) {
-        const messageInParameters =
-            this._message.parameters && messageText === /** @type {string} */ (this._message.parameters[0]);
-        if (this._message.source === SDK.ConsoleMessage.MessageSource.Violation)
-          messageText = Common.UIString('[Violation] %s', messageText);
-        else if (this._message.source === SDK.ConsoleMessage.MessageSource.Intervention)
-          messageText = Common.UIString('[Intervention] %s', messageText);
-        else if (this._message.source === SDK.ConsoleMessage.MessageSource.Deprecation)
-          messageText = Common.UIString('[Deprecation] %s', messageText);
-        const args = this._message.parameters || [messageText];
-        if (messageInParameters)
-          args[0] = messageText;
-        messageElement = this._format(args);
-      }
-    }
-    messageElement.classList.add('console-message-text');
-
-    const formattedMessage = createElementWithClass('span', 'source-code');
-    const anchorElement = this._buildMessageAnchor();
-    if (anchorElement)
-      formattedMessage.appendChild(anchorElement);
-    const badgeElement = this._buildMessageBadge();
-    if (badgeElement)
-      formattedMessage.appendChild(badgeElement);
-    formattedMessage.appendChild(messageElement);
-    return formattedMessage;
-  }
-
-  /**
-   * @return {?Element}
-   */
-  _buildMessageAnchor() {
-    let anchorElement = null;
-    if (this._message.scriptId) {
-      anchorElement = this._linkifyScriptId(
-          this._message.scriptId, this._message.url || '', this._message.line, this._message.column);
-    } else if (this._message.stackTrace && this._message.stackTrace.callFrames.length) {
-      anchorElement = this._linkifyStackTraceTopFrame(this._message.stackTrace);
-    } else if (this._message.url && this._message.url !== 'undefined') {
-      anchorElement = this._linkifyLocation(this._message.url, this._message.line, this._message.column);
-    }
-
-    // Append a space to prevent the anchor text from being glued to the console message when the user selects and copies the console messages.
-    if (anchorElement) {
-      const anchorWrapperElement = createElementWithClass('span', 'console-message-anchor');
-      anchorWrapperElement.appendChild(anchorElement);
-      anchorWrapperElement.createTextChild(' ');
-      return anchorWrapperElement;
-    }
-    return null;
-  }
-
-  /**
-   * @return {?Element}
-   */
-  _buildMessageBadge() {
-    const badgeElement = this._badgeElement();
-    if (!badgeElement)
-      return null;
-    badgeElement.classList.add('console-message-badge');
-    return badgeElement;
-  }
-
-  /**
-   * @return {?Element}
-   */
-  _badgeElement() {
-    if (this._message._url)
-      return this._badgePool.badgeForURL(new Common.ParsedURL(this._message._url));
-    if (this._message.stackTrace) {
-      let stackTrace = this._message.stackTrace;
-      while (stackTrace) {
-        for (const callFrame of this._message.stackTrace.callFrames) {
-          if (callFrame.url)
-            return this._badgePool.badgeForURL(new Common.ParsedURL(callFrame.url));
-        }
-        stackTrace = stackTrace.parent;
-      }
-    }
-    if (!this._message.executionContextId)
-      return null;
-    const runtimeModel = this._message.runtimeModel();
-    if (!runtimeModel)
-      return null;
-    const executionContext = runtimeModel.executionContext(this._message.executionContextId);
-    if (!executionContext || !executionContext.frameId)
-      return null;
-    const resourceTreeModel = executionContext.target().model(SDK.ResourceTreeModel);
-    if (!resourceTreeModel)
-      return null;
-    const frame = resourceTreeModel.frameForId(executionContext.frameId);
-    if (!frame || !frame.parentFrame)
-      return null;
-    return this._badgePool.badgeForFrame(frame);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _buildMessageWithStackTrace() {
-    const toggleElement = createElementWithClass('div', 'console-message-stack-trace-toggle');
-    const contentElement = toggleElement.createChild('div', 'console-message-stack-trace-wrapper');
-
-    const messageElement = this._buildMessage();
-    const icon = UI.Icon.create('smallicon-triangle-right', 'console-message-expand-icon');
-    const clickableElement = contentElement.createChild('div');
-    clickableElement.appendChild(icon);
-
-    clickableElement.appendChild(messageElement);
-    const stackTraceElement = contentElement.createChild('div');
-    const stackTracePreview = Components.JSPresentationUtils.buildStackTracePreviewContents(
-        this._message.runtimeModel().target(), this._linkifier, this._message.stackTrace);
-    stackTraceElement.appendChild(stackTracePreview);
-    stackTraceElement.classList.add('hidden');
-
-    /**
-     * @param {boolean} expand
-     */
-    function expandStackTrace(expand) {
-      icon.setIconType(expand ? 'smallicon-triangle-down' : 'smallicon-triangle-right');
-      stackTraceElement.classList.toggle('hidden', !expand);
-    }
-
-    /**
-     * @param {?Event} event
-     */
-    function toggleStackTrace(event) {
-      if (event.target.hasSelection())
-        return;
-      expandStackTrace(stackTraceElement.classList.contains('hidden'));
-      event.consume();
-    }
-
-    clickableElement.addEventListener('click', toggleStackTrace, false);
-    if (this._message.type === SDK.ConsoleMessage.MessageType.Trace)
-      expandStackTrace(true);
-
-    toggleElement._expandStackTraceForTest = expandStackTrace.bind(null, true);
-    return toggleElement;
-  }
-
-  /**
-   * @param {string} url
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?Element}
-   */
-  _linkifyLocation(url, lineNumber, columnNumber) {
-    if (!this._message.runtimeModel())
-      return null;
-    return this._linkifier.linkifyScriptLocation(
-        this._message.runtimeModel().target(), null, url, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   * @return {?Element}
-   */
-  _linkifyStackTraceTopFrame(stackTrace) {
-    if (!this._message.runtimeModel())
-      return null;
-    return this._linkifier.linkifyStackTraceTopFrame(this._message.runtimeModel().target(), stackTrace);
-  }
-
-  /**
-   * @param {string} scriptId
-   * @param {string} url
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?Element}
-   */
-  _linkifyScriptId(scriptId, url, lineNumber, columnNumber) {
-    if (!this._message.runtimeModel())
-      return null;
-    return this._linkifier.linkifyScriptLocation(
-        this._message.runtimeModel().target(), scriptId, url, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject|!Protocol.Runtime.RemoteObject|string} parameter
-   * @return {!SDK.RemoteObject}
-   */
-  _parameterToRemoteObject(parameter) {
-    if (parameter instanceof SDK.RemoteObject)
-      return parameter;
-    const runtimeModel = this._message.runtimeModel();
-    if (!runtimeModel)
-      return SDK.RemoteObject.fromLocalObject(parameter);
-    if (typeof parameter === 'object')
-      return runtimeModel.createRemoteObject(parameter);
-    return runtimeModel.createRemoteObjectFromPrimitiveValue(parameter);
-  }
-
-  /**
-   * @param {!Array.<!SDK.RemoteObject|string>} rawParameters
-   * @return {!Element}
-   */
-  _format(rawParameters) {
-    // This node is used like a Builder. Values are continually appended onto it.
-    const formattedResult = createElement('span');
-    if (!rawParameters.length)
-      return formattedResult;
-
-    // Formatting code below assumes that parameters are all wrappers whereas frontend console
-    // API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
-    // FIXME: Only pass runtime wrappers here.
-    let parameters = [];
-    for (let i = 0; i < rawParameters.length; ++i)
-      parameters[i] = this._parameterToRemoteObject(rawParameters[i]);
-
-    // There can be string log and string eval result. We distinguish between them based on message type.
-    const shouldFormatMessage =
-        SDK.RemoteObject.type((/** @type {!Array.<!SDK.RemoteObject>} **/ (parameters))[0]) === 'string' &&
-        (this._message.type !== SDK.ConsoleMessage.MessageType.Result ||
-         this._message.level === SDK.ConsoleMessage.MessageLevel.Error);
-
-    // Multiple parameters with the first being a format string. Save unused substitutions.
-    if (shouldFormatMessage) {
-      const result = this._formatWithSubstitutionString(
-          /** @type {string} **/ (parameters[0].description), parameters.slice(1), formattedResult);
-      parameters = result.unusedSubstitutions;
-      if (parameters.length)
-        formattedResult.createTextChild(' ');
-    }
-
-    // Single parameter, or unused substitutions from above.
-    for (let i = 0; i < parameters.length; ++i) {
-      // Inline strings when formatting.
-      if (shouldFormatMessage && parameters[i].type === 'string')
-        formattedResult.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(parameters[i].description));
-      else
-        formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
-      if (i < parameters.length - 1)
-        formattedResult.createTextChild(' ');
-    }
-    return formattedResult;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} output
-   * @param {boolean=} forceObjectFormat
-   * @param {boolean=} includePreview
-   * @return {!Element}
-   */
-  _formatParameter(output, forceObjectFormat, includePreview) {
-    if (output.customPreview())
-      return (new ObjectUI.CustomPreviewComponent(output)).element;
-
-    const type = forceObjectFormat ? 'object' : (output.subtype || output.type);
-    let element;
-    switch (type) {
-      case 'error':
-        element = this._formatParameterAsError(output);
-        break;
-      case 'function':
-        element = this._formatParameterAsFunction(output, includePreview);
-        break;
-      case 'array':
-      case 'arraybuffer':
-      case 'blob':
-      case 'dataview':
-      case 'generator':
-      case 'iterator':
-      case 'map':
-      case 'object':
-      case 'promise':
-      case 'proxy':
-      case 'set':
-      case 'typedarray':
-      case 'weakmap':
-      case 'weakset':
-        element = this._formatParameterAsObject(output, includePreview);
-        break;
-      case 'node':
-        element = output.isNode() ? this._formatParameterAsNode(output) : this._formatParameterAsObject(output, false);
-        break;
-      case 'string':
-        element = this._formatParameterAsString(output);
-        break;
-      case 'boolean':
-      case 'date':
-      case 'null':
-      case 'number':
-      case 'regexp':
-      case 'symbol':
-      case 'undefined':
-      case 'bigint':
-        element = this._formatParameterAsValue(output);
-        break;
-      default:
-        element = this._formatParameterAsValue(output);
-        console.error('Tried to format remote object of unknown type.');
-    }
-    element.classList.add('object-value-' + type);
-    element.classList.add('source-code');
-    return element;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} obj
-   * @return {!Element}
-   */
-  _formatParameterAsValue(obj) {
-    const result = createElement('span');
-    const description = obj.description || '';
-    if (description.length > Console.ConsoleViewMessage._MaxTokenizableStringLength)
-      result.appendChild(Console.ConsoleViewMessage._createExpandableFragment(description));
-    else
-      result.createTextChild(description);
-    if (obj.objectId)
-      result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, obj), false);
-    return result;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} obj
-   * @param {boolean=} includePreview
-   * @return {!Element}
-   */
-  _formatParameterAsObject(obj, includePreview) {
-    const titleElement = createElementWithClass('span', 'console-object');
-    if (includePreview && obj.preview) {
-      titleElement.classList.add('console-object-preview');
-      this._previewFormatter.appendObjectPreview(titleElement, obj.preview, false /* isEntry */);
-    } else if (obj.type === 'function') {
-      const functionElement = titleElement.createChild('span');
-      ObjectUI.ObjectPropertiesSection.formatObjectAsFunction(obj, functionElement, false);
-      titleElement.classList.add('object-value-function');
-    } else {
-      titleElement.createTextChild(obj.description || '');
-    }
-
-    if (!obj.hasChildren || obj.customPreview())
-      return titleElement;
-
-    const note = titleElement.createChild('span', 'object-state-note info-note');
-    if (this._message.type === SDK.ConsoleMessage.MessageType.QueryObjectResult)
-      note.title = ls`This value will not be collected until console is cleared.`;
-    else
-      note.title = ls`Value below was evaluated just now.`;
-
-    const section = new ObjectUI.ObjectPropertiesSection(obj, titleElement, this._linkifier);
-    section.element.classList.add('console-view-object-properties-section');
-    section.enableContextMenu();
-    return section.element;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} func
-   * @param {boolean=} includePreview
-   * @return {!Element}
-   */
-  _formatParameterAsFunction(func, includePreview) {
-    const result = createElement('span');
-    SDK.RemoteFunction.objectAsFunction(func).targetFunction().then(formatTargetFunction.bind(this));
-    return result;
-
-    /**
-     * @param {!SDK.RemoteObject} targetFunction
-     * @this {Console.ConsoleViewMessage}
-     */
-    function formatTargetFunction(targetFunction) {
-      const functionElement = createElement('span');
-      ObjectUI.ObjectPropertiesSection.formatObjectAsFunction(targetFunction, functionElement, true, includePreview);
-      result.appendChild(functionElement);
-      if (targetFunction !== func) {
-        const note = result.createChild('span', 'object-info-state-note');
-        note.title = Common.UIString('Function was resolved from bound function.');
-      }
-      result.addEventListener('contextmenu', this._contextMenuEventFired.bind(this, targetFunction), false);
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} obj
-   * @param {!Event} event
-   */
-  _contextMenuEventFired(obj, event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.appendApplicableItems(obj);
-    contextMenu.show();
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} object
-   * @param {!Array.<!Protocol.Runtime.PropertyPreview>} propertyPath
-   * @return {!Element}
-   */
-  _renderPropertyPreviewOrAccessor(object, propertyPath) {
-    const property = propertyPath.peekLast();
-    if (property.type === 'accessor')
-      return this._formatAsAccessorProperty(object, propertyPath.map(property => property.name), false);
-    return this._previewFormatter.renderPropertyPreview(
-        property.type, /** @type {string} */ (property.subtype), property.value);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} remoteObject
-   * @return {!Element}
-   */
-  _formatParameterAsNode(remoteObject) {
-    const result = createElement('span');
-
-    const domModel = remoteObject.runtimeModel().target().model(SDK.DOMModel);
-    if (!domModel)
-      return result;
-    domModel.pushObjectAsNodeToFrontend(remoteObject).then(node => {
-      if (!node) {
-        result.appendChild(this._formatParameterAsObject(remoteObject, false));
-        return;
-      }
-      Common.Renderer.render(node).then(rendererNode => {
-        if (rendererNode)
-          result.appendChild(rendererNode);
-        else
-          result.appendChild(this._formatParameterAsObject(remoteObject, false));
-        this._formattedParameterAsNodeForTest();
-      });
-    });
-
-    return result;
-  }
-
-  _formattedParameterAsNodeForTest() {
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} output
-   * @return {!Element}
-   */
-  _formatParameterAsString(output) {
-    const span = createElement('span');
-    span.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(output.description || ''));
-
-    const result = createElement('span');
-    result.createChild('span', 'object-value-string-quote').textContent = '"';
-    result.appendChild(span);
-    result.createChild('span', 'object-value-string-quote').textContent = '"';
-    return result;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} output
-   * @return {!Element}
-   */
-  _formatParameterAsError(output) {
-    const result = createElement('span');
-    const errorSpan = this._tryFormatAsError(output.description || '');
-    result.appendChild(
-        errorSpan ? errorSpan : Console.ConsoleViewMessage._linkifyStringAsFragment(output.description || ''));
-    return result;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} output
-   * @return {!Element}
-   */
-  _formatAsArrayEntry(output) {
-    return this._previewFormatter.renderPropertyPreview(output.type, output.subtype, output.description);
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} object
-   * @param {!Array.<string>} propertyPath
-   * @param {boolean} isArrayEntry
-   * @return {!Element}
-   */
-  _formatAsAccessorProperty(object, propertyPath, isArrayEntry) {
-    const rootElement = ObjectUI.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
-        object, propertyPath, onInvokeGetterClick.bind(this));
-
-    /**
-     * @param {?SDK.RemoteObject} result
-     * @param {boolean=} wasThrown
-     * @this {Console.ConsoleViewMessage}
-     */
-    function onInvokeGetterClick(result, wasThrown) {
-      if (!result)
-        return;
-      rootElement.removeChildren();
-      if (wasThrown) {
-        const element = rootElement.createChild('span');
-        element.textContent = Common.UIString('<exception>');
-        element.title = /** @type {string} */ (result.description);
-      } else if (isArrayEntry) {
-        rootElement.appendChild(this._formatAsArrayEntry(result));
-      } else {
-        // Make a PropertyPreview from the RemoteObject similar to the backend logic.
-        const maxLength = 100;
-        const type = result.type;
-        const subtype = result.subtype;
-        let description = '';
-        if (type !== 'function' && result.description) {
-          if (type === 'string' || subtype === 'regexp')
-            description = result.description.trimMiddle(maxLength);
-          else
-            description = result.description.trimEnd(maxLength);
-        }
-        rootElement.appendChild(this._previewFormatter.renderPropertyPreview(type, subtype, description));
-      }
-    }
-
-    return rootElement;
-  }
-
-  /**
-   * @param {string} format
-   * @param {!Array.<!SDK.RemoteObject>} parameters
-   * @param {!Element} formattedResult
-   */
-  _formatWithSubstitutionString(format, parameters, formattedResult) {
-    const formatters = {};
-
-    /**
-     * @param {boolean} force
-     * @param {boolean} includePreview
-     * @param {!SDK.RemoteObject} obj
-     * @return {!Element}
-     * @this {Console.ConsoleViewMessage}
-     */
-    function parameterFormatter(force, includePreview, obj) {
-      return this._formatParameter(obj, force, includePreview);
-    }
-
-    function stringFormatter(obj) {
-      return obj.description;
-    }
-
-    function floatFormatter(obj) {
-      if (typeof obj.value !== 'number')
-        return 'NaN';
-      return obj.value;
-    }
-
-    function integerFormatter(obj) {
-      if (typeof obj.value !== 'number')
-        return 'NaN';
-      return Math.floor(obj.value);
-    }
-
-    function bypassFormatter(obj) {
-      return (obj instanceof Node) ? obj : '';
-    }
-
-    let currentStyle = null;
-    function styleFormatter(obj) {
-      currentStyle = {};
-      const buffer = createElement('span');
-      buffer.setAttribute('style', obj.description);
-      for (let i = 0; i < buffer.style.length; i++) {
-        const property = buffer.style[i];
-        if (isWhitelistedProperty(property))
-          currentStyle[property] = buffer.style[property];
-      }
-    }
-
-    function isWhitelistedProperty(property) {
-      // Make sure that allowed properties do not interfere with link visibility.
-      const prefixes = [
-        'background', 'border', 'color', 'font', 'line', 'margin', 'padding', 'text', '-webkit-background',
-        '-webkit-border', '-webkit-font', '-webkit-margin', '-webkit-padding', '-webkit-text'
-      ];
-      for (let i = 0; i < prefixes.length; i++) {
-        if (property.startsWith(prefixes[i]))
-          return true;
-      }
-      return false;
-    }
-
-    // Firebug uses %o for formatting objects.
-    formatters.o = parameterFormatter.bind(this, false /* force */, true /* includePreview */);
-    formatters.s = stringFormatter;
-    formatters.f = floatFormatter;
-    // Firebug allows both %i and %d for formatting integers.
-    formatters.i = integerFormatter;
-    formatters.d = integerFormatter;
-
-    // Firebug uses %c for styling the message.
-    formatters.c = styleFormatter;
-
-    // Support %O to force object formatting, instead of the type-based %o formatting.
-    formatters.O = parameterFormatter.bind(this, true /* force */, false /* includePreview */);
-
-    formatters._ = bypassFormatter;
-
-    /**
-     * @param {!Element} a
-     * @param {*} b
-     * @this {!Console.ConsoleViewMessage}
-     */
-    function append(a, b) {
-      if (b instanceof Node) {
-        a.appendChild(b);
-      } else if (typeof b !== 'undefined') {
-        let toAppend = Console.ConsoleViewMessage._linkifyStringAsFragment(String(b));
-        if (currentStyle) {
-          const wrapper = createElement('span');
-          wrapper.style.setProperty('contain', 'paint');
-          wrapper.style.setProperty('display', 'inline-block');
-          wrapper.appendChild(toAppend);
-          applyCurrentStyle(wrapper);
-          for (const child of wrapper.children) {
-            if (child.classList.contains('devtools-link'))
-              this._applyForcedVisibleStyle(child);
-            else
-              applyCurrentStyle(child);
-          }
-          toAppend = wrapper;
-        }
-        a.appendChild(toAppend);
-      }
-      return a;
-    }
-
-    /**
-     * @param {!Element} element
-     */
-    function applyCurrentStyle(element) {
-      for (const key in currentStyle)
-        element.style[key] = currentStyle[key];
-    }
-
-    // String.format does treat formattedResult like a Builder, result is an object.
-    return String.format(format, parameters, formatters, formattedResult, append.bind(this));
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  _applyForcedVisibleStyle(element) {
-    element.style.setProperty('-webkit-text-stroke', '0', 'important');
-    element.style.setProperty('text-decoration', 'underline', 'important');
-
-    const themedColor = UI.themeSupport.patchColorText('rgb(33%, 33%, 33%)', UI.ThemeSupport.ColorUsage.Foreground);
-    element.style.setProperty('color', themedColor, 'important');
-
-    let backgroundColor = 'hsl(0, 0%, 100%)';
-    if (this._message.level === SDK.ConsoleMessage.MessageLevel.Error)
-      backgroundColor = 'hsl(0, 100%, 97%)';
-    else if (this._message.level === SDK.ConsoleMessage.MessageLevel.Warning || this._shouldRenderAsWarning())
-      backgroundColor = 'hsl(50, 100%, 95%)';
-    const themedBackgroundColor =
-        UI.themeSupport.patchColorText(backgroundColor, UI.ThemeSupport.ColorUsage.Background);
-    element.style.setProperty('background-color', themedBackgroundColor, 'important');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  matchesFilterRegex(regexObject) {
-    regexObject.lastIndex = 0;
-    const text = this.contentElement().deepTextContent();
-    return regexObject.test(text);
-  }
-
-  /**
-   * @param {string} filter
-   * @return {boolean}
-   */
-  matchesFilterText(filter) {
-    const text = this.contentElement().deepTextContent();
-    return text.toLowerCase().includes(filter.toLowerCase());
-  }
-
-  updateTimestamp() {
-    if (!this._contentElement)
-      return;
-
-    if (Common.moduleSetting('consoleTimestampsEnabled').get()) {
-      if (!this._timestampElement)
-        this._timestampElement = createElementWithClass('span', 'console-timestamp');
-      this._timestampElement.textContent = formatTimestamp(this._message.timestamp, false) + ' ';
-      this._timestampElement.title = formatTimestamp(this._message.timestamp, true);
-      this._contentElement.insertBefore(this._timestampElement, this._contentElement.firstChild);
-    } else if (this._timestampElement) {
-      this._timestampElement.remove();
-      delete this._timestampElement;
-    }
-
-    /**
-     * @param {number} timestamp
-     * @param {boolean} full
-     * @return {string}
-     */
-    function formatTimestamp(timestamp, full) {
-      const date = new Date(timestamp);
-      const yymmdd = date.getFullYear() + '-' + leadZero(date.getMonth() + 1, 2) + '-' + leadZero(date.getDate(), 2);
-      const hhmmssfff = leadZero(date.getHours(), 2) + ':' + leadZero(date.getMinutes(), 2) + ':' +
-          leadZero(date.getSeconds(), 2) + '.' + leadZero(date.getMilliseconds(), 3);
-      return full ? (yymmdd + ' ' + hhmmssfff) : hhmmssfff;
-
-      /**
-       * @param {number} value
-       * @param {number} length
-       * @return {string}
-       */
-      function leadZero(value, length) {
-        const valueString = value.toString();
-        const padding = length - valueString.length;
-        return padding <= 0 ? valueString : '0'.repeat(padding) + valueString;
-      }
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  nestingLevel() {
-    return this._nestingLevel;
-  }
-
-  /**
-   * @param {boolean} inSimilarGroup
-   * @param {boolean=} isLast
-   */
-  setInSimilarGroup(inSimilarGroup, isLast) {
-    this._inSimilarGroup = inSimilarGroup;
-    this._lastInSimilarGroup = inSimilarGroup && !!isLast;
-    if (this._similarGroupMarker && !inSimilarGroup) {
-      this._similarGroupMarker.remove();
-      this._similarGroupMarker = null;
-    } else if (this._element && !this._similarGroupMarker && inSimilarGroup) {
-      this._similarGroupMarker = createElementWithClass('div', 'nesting-level-marker');
-      this._element.insertBefore(this._similarGroupMarker, this._element.firstChild);
-      this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isLastInSimilarGroup() {
-    return this._inSimilarGroup && this._lastInSimilarGroup;
-  }
-
-  resetCloseGroupDecorationCount() {
-    if (!this._closeGroupDecorationCount)
-      return;
-    this._closeGroupDecorationCount = 0;
-    this._updateCloseGroupDecorations();
-  }
-
-  incrementCloseGroupDecorationCount() {
-    ++this._closeGroupDecorationCount;
-    this._updateCloseGroupDecorations();
-  }
-
-  _updateCloseGroupDecorations() {
-    if (!this._nestingLevelMarkers)
-      return;
-    for (let i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
-      const marker = this._nestingLevelMarkers[i];
-      marker.classList.toggle('group-closed', n - i <= this._closeGroupDecorationCount);
-    }
-  }
-
-  /**
-   * @return {!Element}
-   */
-  contentElement() {
-    if (this._contentElement)
-      return this._contentElement;
-
-    const contentElement = createElementWithClass('div', 'console-message');
-    if (this._messageLevelIcon)
-      contentElement.appendChild(this._messageLevelIcon);
-    this._contentElement = contentElement;
-
-    let formattedMessage;
-    const shouldIncludeTrace = !!this._message.stackTrace &&
-        (this._message.source === SDK.ConsoleMessage.MessageSource.Network ||
-         this._message.source === SDK.ConsoleMessage.MessageSource.Violation ||
-         this._message.level === SDK.ConsoleMessage.MessageLevel.Error ||
-         this._message.level === SDK.ConsoleMessage.MessageLevel.Warning ||
-         this._message.type === SDK.ConsoleMessage.MessageType.Trace);
-    if (this._message.runtimeModel() && shouldIncludeTrace)
-      formattedMessage = this._buildMessageWithStackTrace();
-    else if (this._message.type === SDK.ConsoleMessage.MessageType.Table)
-      formattedMessage = this._buildTableMessage();
-    else
-      formattedMessage = this._buildMessage();
-    contentElement.appendChild(formattedMessage);
-
-    this.updateTimestamp();
-    return this._contentElement;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  toMessageElement() {
-    if (this._element)
-      return this._element;
-
-    this._element = createElement('div');
-    this.updateMessageElement();
-    return this._element;
-  }
-
-  updateMessageElement() {
-    if (!this._element)
-      return;
-
-    this._element.className = 'console-message-wrapper';
-    this._element.removeChildren();
-    if (this._message.isGroupStartMessage())
-      this._element.classList.add('console-group-title');
-    if (this._message.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI)
-      this._element.classList.add('console-from-api');
-    if (this._inSimilarGroup) {
-      this._similarGroupMarker = this._element.createChild('div', 'nesting-level-marker');
-      this._similarGroupMarker.classList.toggle('group-closed', this._lastInSimilarGroup);
-    }
-
-    this._nestingLevelMarkers = [];
-    for (let i = 0; i < this._nestingLevel; ++i)
-      this._nestingLevelMarkers.push(this._element.createChild('div', 'nesting-level-marker'));
-    this._updateCloseGroupDecorations();
-    this._element.message = this;
-
-    switch (this._message.level) {
-      case SDK.ConsoleMessage.MessageLevel.Verbose:
-        this._element.classList.add('console-verbose-level');
-        this._updateMessageLevelIcon('');
-        break;
-      case SDK.ConsoleMessage.MessageLevel.Info:
-        this._element.classList.add('console-info-level');
-        if (this._message.type === SDK.ConsoleMessage.MessageType.System)
-          this._element.classList.add('console-system-type');
-        break;
-      case SDK.ConsoleMessage.MessageLevel.Warning:
-        this._element.classList.add('console-warning-level');
-        this._updateMessageLevelIcon('smallicon-warning');
-        break;
-      case SDK.ConsoleMessage.MessageLevel.Error:
-        this._element.classList.add('console-error-level');
-        this._updateMessageLevelIcon('smallicon-error');
-        break;
-    }
-    if (this._shouldRenderAsWarning())
-      this._element.classList.add('console-warning-level');
-
-    this._element.appendChild(this.contentElement());
-    if (this._repeatCount > 1)
-      this._showRepeatCountElement();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _shouldRenderAsWarning() {
-    return (this._message.level === SDK.ConsoleMessage.MessageLevel.Verbose ||
-            this._message.level === SDK.ConsoleMessage.MessageLevel.Info) &&
-        (this._message.source === SDK.ConsoleMessage.MessageSource.Violation ||
-         this._message.source === SDK.ConsoleMessage.MessageSource.Deprecation ||
-         this._message.source === SDK.ConsoleMessage.MessageSource.Intervention ||
-         this._message.source === SDK.ConsoleMessage.MessageSource.Recommendation);
-  }
-
-  /**
-   * @param {string} iconType
-   */
-  _updateMessageLevelIcon(iconType) {
-    if (!iconType && !this._messageLevelIcon)
-      return;
-    if (iconType && !this._messageLevelIcon) {
-      this._messageLevelIcon = UI.Icon.create('', 'message-level-icon');
-      if (this._contentElement)
-        this._contentElement.insertBefore(this._messageLevelIcon, this._contentElement.firstChild);
-    }
-    this._messageLevelIcon.setIconType(iconType);
-  }
-
-  /**
-   * @return {number}
-   */
-  repeatCount() {
-    return this._repeatCount || 1;
-  }
-
-  resetIncrementRepeatCount() {
-    this._repeatCount = 1;
-    if (!this._repeatCountElement)
-      return;
-
-    this._repeatCountElement.remove();
-    if (this._contentElement)
-      this._contentElement.classList.remove('repeated-message');
-    delete this._repeatCountElement;
-  }
-
-  incrementRepeatCount() {
-    this._repeatCount++;
-    this._showRepeatCountElement();
-  }
-
-  /**
-   * @param {number} repeatCount
-   */
-  setRepeatCount(repeatCount) {
-    this._repeatCount = repeatCount;
-    this._showRepeatCountElement();
-  }
-
-  _showRepeatCountElement() {
-    if (!this._element)
-      return;
-
-    if (!this._repeatCountElement) {
-      this._repeatCountElement = createElementWithClass('label', 'console-message-repeat-count', 'dt-small-bubble');
-      switch (this._message.level) {
-        case SDK.ConsoleMessage.MessageLevel.Warning:
-          this._repeatCountElement.type = 'warning';
-          break;
-        case SDK.ConsoleMessage.MessageLevel.Error:
-          this._repeatCountElement.type = 'error';
-          break;
-        case SDK.ConsoleMessage.MessageLevel.Verbose:
-          this._repeatCountElement.type = 'verbose';
-          break;
-        default:
-          this._repeatCountElement.type = 'info';
-      }
-      if (this._shouldRenderAsWarning())
-        this._repeatCountElement.type = 'warning';
-
-      this._element.insertBefore(this._repeatCountElement, this._contentElement);
-      this._contentElement.classList.add('repeated-message');
-    }
-    this._repeatCountElement.textContent = this._repeatCount;
-  }
-
-  get text() {
-    return this._message.messageText;
-  }
-
-  /**
-   * @return {string}
-   */
-  toExportString() {
-    const lines = [];
-    const nodes = this.contentElement().childTextNodes();
-    const messageContent = nodes.map(Components.Linkifier.untruncatedNodeText).join('');
-    for (let i = 0; i < this.repeatCount(); ++i)
-      lines.push(messageContent);
-    return lines.join('\n');
-  }
-
-  /**
-   * @param {?RegExp} regex
-   */
-  setSearchRegex(regex) {
-    if (this._searchHiglightNodeChanges && this._searchHiglightNodeChanges.length)
-      UI.revertDomChanges(this._searchHiglightNodeChanges);
-    this._searchRegex = regex;
-    this._searchHighlightNodes = [];
-    this._searchHiglightNodeChanges = [];
-    if (!this._searchRegex)
-      return;
-
-    const text = this.contentElement().deepTextContent();
-    let match;
-    this._searchRegex.lastIndex = 0;
-    const sourceRanges = [];
-    while ((match = this._searchRegex.exec(text)) && match[0])
-      sourceRanges.push(new TextUtils.SourceRange(match.index, match[0].length));
-
-    if (sourceRanges.length) {
-      this._searchHighlightNodes =
-          UI.highlightSearchResults(this.contentElement(), sourceRanges, this._searchHiglightNodeChanges);
-    }
-  }
-
-  /**
-   * @return {?RegExp}
-   */
-  searchRegex() {
-    return this._searchRegex;
-  }
-
-  /**
-   * @return {number}
-   */
-  searchCount() {
-    return this._searchHighlightNodes.length;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  searchHighlightNode(index) {
-    return this._searchHighlightNodes[index];
-  }
-
-  /**
-   * @param {string} string
-   * @return {?Element}
-   */
-  _tryFormatAsError(string) {
-    /**
-     * @param {string} prefix
-     */
-    function startsWith(prefix) {
-      return string.startsWith(prefix);
-    }
-
-    const errorPrefixes =
-        ['EvalError', 'ReferenceError', 'SyntaxError', 'TypeError', 'RangeError', 'Error', 'URIError'];
-    if (!this._message.runtimeModel() || !errorPrefixes.some(startsWith))
-      return null;
-    const debuggerModel = this._message.runtimeModel().debuggerModel();
-    const baseURL = this._message.runtimeModel().target().inspectedURL();
-
-    const lines = string.split('\n');
-    const links = [];
-    let position = 0;
-    for (let i = 0; i < lines.length; ++i) {
-      position += i > 0 ? lines[i - 1].length + 1 : 0;
-      const isCallFrameLine = /^\s*at\s/.test(lines[i]);
-      if (!isCallFrameLine && links.length)
-        return null;
-
-      if (!isCallFrameLine)
-        continue;
-
-      let openBracketIndex = -1;
-      let closeBracketIndex = -1;
-      const match = /\([^\)\(]+\)/.exec(lines[i]);
-      if (match) {
-        openBracketIndex = match.index;
-        closeBracketIndex = match.index + match[0].length - 1;
-      }
-      const hasOpenBracket = openBracketIndex !== -1;
-      const left = hasOpenBracket ? openBracketIndex + 1 : lines[i].indexOf('at') + 3;
-      const right = hasOpenBracket ? closeBracketIndex : lines[i].length;
-      const linkCandidate = lines[i].substring(left, right);
-      const splitResult = Common.ParsedURL.splitLineAndColumn(linkCandidate);
-      if (!splitResult)
-        return null;
-
-      if (splitResult.url === '<anonymous>')
-        continue;
-      let url = parseOrScriptMatch(splitResult.url);
-      if (!url && Common.ParsedURL.isRelativeURL(splitResult.url))
-        url = parseOrScriptMatch(Common.ParsedURL.completeURL(baseURL, splitResult.url));
-      if (!url)
-        return null;
-
-      links.push({
-        url: url,
-        positionLeft: position + left,
-        positionRight: position + right,
-        lineNumber: splitResult.lineNumber,
-        columnNumber: splitResult.columnNumber
-      });
-    }
-
-    if (!links.length)
-      return null;
-
-    const formattedResult = createElement('span');
-    let start = 0;
-    for (let i = 0; i < links.length; ++i) {
-      formattedResult.appendChild(
-          Console.ConsoleViewMessage._linkifyStringAsFragment(string.substring(start, links[i].positionLeft)));
-      formattedResult.appendChild(this._linkifier.linkifyScriptLocation(
-          debuggerModel.target(), null, links[i].url, links[i].lineNumber, links[i].columnNumber));
-      start = links[i].positionRight;
-    }
-
-    if (start !== string.length)
-      formattedResult.appendChild(Console.ConsoleViewMessage._linkifyStringAsFragment(string.substring(start)));
-
-    return formattedResult;
-
-    /**
-     * @param {?string} url
-     * @return {?string}
-     */
-    function parseOrScriptMatch(url) {
-      if (!url)
-        return null;
-      const parsedURL = url.asParsedURL();
-      if (parsedURL)
-        return parsedURL.url;
-      if (debuggerModel.scriptsForSourceURL(url).length)
-        return url;
-      return null;
-    }
-  }
-
-  /**
-   * @param {string} string
-   * @param {function(string,string,number=,number=):!Node} linkifier
-   * @return {!DocumentFragment}
-   */
-  static linkifyWithCustomLinkifier(string, linkifier) {
-    if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength)
-      return Console.ConsoleViewMessage._createExpandableFragment(string);
-    const container = createDocumentFragment();
-    const tokens = this._tokenizeMessageText(string);
-    for (const token of tokens) {
-      switch (token.type) {
-        case 'url': {
-          const realURL = (token.text.startsWith('www.') ? 'http://' + token.text : token.text);
-          const splitResult = Common.ParsedURL.splitLineAndColumn(realURL);
-          let linkNode;
-          if (splitResult)
-            linkNode = linkifier(token.text, splitResult.url, splitResult.lineNumber, splitResult.columnNumber);
-          else
-            linkNode = linkifier(token.text, token.value);
-          container.appendChild(linkNode);
-          break;
-        }
-        default:
-          container.appendChild(createTextNode(token.text));
-          break;
-      }
-    }
-    return container;
-  }
-
-  /**
-   * @param {string} text
-   * @return {!DocumentFragment}
-   */
-  static _createExpandableFragment(text) {
-    const fragment = createDocumentFragment();
-    fragment.textContent = text.slice(0, Console.ConsoleViewMessage._LongStringVisibleLength);
-    const hiddenText = text.slice(Console.ConsoleViewMessage._LongStringVisibleLength);
-
-    const expandButton = fragment.createChild('span', 'console-inline-button');
-    expandButton.setAttribute('data-text', ls`Show ${Number.withThousandsSeparator(hiddenText.length)} more`);
-    expandButton.addEventListener('click', () => {
-      if (expandButton.parentElement)
-        expandButton.parentElement.insertBefore(createTextNode(hiddenText), expandButton);
-      expandButton.remove();
-    });
-
-    const copyButton = fragment.createChild('span', 'console-inline-button');
-    copyButton.setAttribute('data-text', ls`Copy`);
-    copyButton.addEventListener('click', () => {
-      InspectorFrontendHost.copyText(text);
-    });
-    return fragment;
-  }
-
-  /**
-   * @param {string} string
-   * @return {!DocumentFragment}
-   */
-  static _linkifyStringAsFragment(string) {
-    return Console.ConsoleViewMessage.linkifyWithCustomLinkifier(string, (text, url, lineNumber, columnNumber) => {
-      return Components.Linkifier.linkifyURL(url, {text, lineNumber, columnNumber});
-    });
-  }
-
-  /**
-   * @param {string} string
-   * @return {!Array<{type: string, text: (string|undefined)}>}
-   */
-  static _tokenizeMessageText(string) {
-    if (!Console.ConsoleViewMessage._tokenizerRegexes) {
-      const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
-      const linkStringRegex = new RegExp(
-          '(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + controlCodes + '"]{2,}[^\\s' + controlCodes +
-              '"\')}\\],:;.!?]',
-          'u');
-      const pathLineRegex = /(?:\/[\w\.-]*)+\:[\d]+/;
-      const timeRegex = /took [\d]+ms/;
-      const eventRegex = /'\w+' event/;
-      const milestoneRegex = /\sM[6-7]\d/;
-      const autofillRegex = /\(suggested: \"[\w-]+\"\)/;
-      const handlers = new Map();
-      handlers.set(linkStringRegex, 'url');
-      handlers.set(pathLineRegex, 'url');
-      handlers.set(timeRegex, 'time');
-      handlers.set(eventRegex, 'event');
-      handlers.set(milestoneRegex, 'milestone');
-      handlers.set(autofillRegex, 'autofill');
-      Console.ConsoleViewMessage._tokenizerRegexes = Array.from(handlers.keys());
-      Console.ConsoleViewMessage._tokenizerTypes = Array.from(handlers.values());
-    }
-    if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength)
-      return [{text: string, type: undefined}];
-    const results = TextUtils.TextUtils.splitStringByRegexes(string, Console.ConsoleViewMessage._tokenizerRegexes);
-    return results.map(
-        result => ({text: result.value, type: Console.ConsoleViewMessage._tokenizerTypes[result.regexIndex]}));
-  }
-
-  /**
-   * @return {string}
-   */
-  groupKey() {
-    if (!this._groupKey)
-      this._groupKey = this._message.groupCategoryKey() + ':' + this.groupTitle();
-    return this._groupKey;
-  }
-
-  /**
-   * @return {string}
-   */
-  groupTitle() {
-    const tokens = Console.ConsoleViewMessage._tokenizeMessageText(this._message.messageText);
-    const result = tokens.reduce((acc, token) => {
-      let text = token.text;
-      if (token.type === 'url')
-        text = Common.UIString('<URL>');
-      else if (token.type === 'time')
-        text = Common.UIString('took <N>ms');
-      else if (token.type === 'event')
-        text = Common.UIString('<some> event');
-      else if (token.type === 'milestone')
-        text = Common.UIString(' M<XX>');
-      else if (token.type === 'autofill')
-        text = Common.UIString('<attribute>');
-      return acc + text;
-    }, '');
-    return result.replace(/[%]o/g, '');
-  }
-};
-
-/**
- * @unrestricted
- */
-Console.ConsoleGroupViewMessage = class extends Console.ConsoleViewMessage {
-  /**
-   * @param {!SDK.ConsoleMessage} consoleMessage
-   * @param {!Components.Linkifier} linkifier
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {number} nestingLevel
-   */
-  constructor(consoleMessage, linkifier, badgePool, nestingLevel) {
-    console.assert(consoleMessage.isGroupStartMessage());
-    super(consoleMessage, linkifier, badgePool, nestingLevel);
-    this._collapsed = consoleMessage.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed;
-    /** @type {?UI.Icon} */
-    this._expandGroupIcon = null;
-  }
-
-  /**
-   * @param {boolean} collapsed
-   */
-  setCollapsed(collapsed) {
-    this._collapsed = collapsed;
-    if (this._expandGroupIcon)
-      this._expandGroupIcon.setIconType(this._collapsed ? 'smallicon-triangle-right' : 'smallicon-triangle-down');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  collapsed() {
-    return this._collapsed;
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  toMessageElement() {
-    if (!this._element) {
-      super.toMessageElement();
-      this._expandGroupIcon = UI.Icon.create('', 'expand-group-icon');
-      if (this._repeatCountElement)
-        this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
-      else
-        this._element.insertBefore(this._expandGroupIcon, this._contentElement);
-      this.setCollapsed(this._collapsed);
-    }
-    return this._element;
-  }
-
-  /**
-   * @override
-   */
-  _showRepeatCountElement() {
-    super._showRepeatCountElement();
-    if (this._repeatCountElement && this._expandGroupIcon)
-      this._repeatCountElement.insertBefore(this._expandGroupIcon, this._repeatCountElement.firstChild);
-  }
-};
-
-/**
- * @const
- * @type {number}
- */
-Console.ConsoleViewMessage.MaxLengthForLinks = 40;
-
-Console.ConsoleViewMessage._MaxTokenizableStringLength = 10000;
-
-Console.ConsoleViewMessage._LongStringVisibleLength = 5000;
diff --git a/front_end/console/ConsoleViewport.js b/front_end/console/ConsoleViewport.js
deleted file mode 100644
index 023ecc6..0000000
--- a/front_end/console/ConsoleViewport.js
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Console.ConsoleViewport = class {
-  /**
-   * @param {!Console.ConsoleViewportProvider} provider
-   */
-  constructor(provider) {
-    this.element = createElement('div');
-    this.element.style.overflow = 'auto';
-    this._topGapElement = this.element.createChild('div');
-    this._topGapElement.style.height = '0px';
-    this._topGapElement.style.color = 'transparent';
-    this._contentElement = this.element.createChild('div');
-    this._bottomGapElement = this.element.createChild('div');
-    this._bottomGapElement.style.height = '0px';
-    this._bottomGapElement.style.color = 'transparent';
-
-    // Text content needed for range intersection checks in _updateSelectionModel.
-    // Use Unicode ZERO WIDTH NO-BREAK SPACE, which avoids contributing any height to the element's layout overflow.
-    this._topGapElement.textContent = '\uFEFF';
-    this._bottomGapElement.textContent = '\uFEFF';
-
-    this._provider = provider;
-    this.element.addEventListener('scroll', this._onScroll.bind(this), false);
-    this.element.addEventListener('copy', this._onCopy.bind(this), false);
-    this.element.addEventListener('dragstart', this._onDragStart.bind(this), false);
-
-    this._firstActiveIndex = -1;
-    this._lastActiveIndex = -1;
-    this._renderedItems = [];
-    this._anchorSelection = null;
-    this._headSelection = null;
-    this._itemCount = 0;
-    this._cumulativeHeights = new Int32Array(0);
-    this._muteCopyHandler = false;
-
-    // Listen for any changes to descendants and trigger a refresh. This ensures
-    // that items updated asynchronously will not break stick-to-bottom behavior
-    // if they change the scroll height.
-    this._observer = new MutationObserver(this.refresh.bind(this));
-    this._observerConfig = {childList: true, subtree: true};
-  }
-
-  /**
-   * @return {boolean}
-   */
-  stickToBottom() {
-    return this._stickToBottom;
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setStickToBottom(value) {
-    this._stickToBottom = value;
-    if (this._stickToBottom)
-      this._observer.observe(this._contentElement, this._observerConfig);
-    else
-      this._observer.disconnect();
-  }
-
-  copyWithStyles() {
-    this._muteCopyHandler = true;
-    this.element.ownerDocument.execCommand('copy');
-    this._muteCopyHandler = false;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onCopy(event) {
-    if (this._muteCopyHandler)
-      return;
-    const text = this._selectedText();
-    if (!text)
-      return;
-    event.preventDefault();
-    event.clipboardData.setData('text/plain', text);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDragStart(event) {
-    const text = this._selectedText();
-    if (!text)
-      return false;
-    event.dataTransfer.clearData();
-    event.dataTransfer.setData('text/plain', text);
-    event.dataTransfer.effectAllowed = 'copy';
-    return true;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  contentElement() {
-    return this._contentElement;
-  }
-
-  invalidate() {
-    delete this._cachedProviderElements;
-    this._itemCount = this._provider.itemCount();
-    this._rebuildCumulativeHeights();
-    this.refresh();
-  }
-
-  /**
-   * @param {number} index
-   * @return {?Console.ConsoleViewportElement}
-   */
-  _providerElement(index) {
-    if (!this._cachedProviderElements)
-      this._cachedProviderElements = new Array(this._itemCount);
-    let element = this._cachedProviderElements[index];
-    if (!element) {
-      element = this._provider.itemElement(index);
-      this._cachedProviderElements[index] = element;
-    }
-    return element;
-  }
-
-  _rebuildCumulativeHeights() {
-    const firstActiveIndex = this._firstActiveIndex;
-    const lastActiveIndex = this._lastActiveIndex;
-    let height = 0;
-    this._cumulativeHeights = new Int32Array(this._itemCount);
-    for (let i = 0; i < this._itemCount; ++i) {
-      if (firstActiveIndex <= i && i - firstActiveIndex < this._renderedItems.length && i <= lastActiveIndex)
-        height += this._renderedItems[i - firstActiveIndex].element().offsetHeight;
-      else
-        height += this._provider.fastHeight(i);
-      this._cumulativeHeights[i] = height;
-    }
-  }
-
-  _rebuildCumulativeHeightsIfNeeded() {
-    // Check whether current items in DOM have changed heights. Tolerate 1-pixel
-    // error due to double-to-integer rounding errors.
-    for (let i = 0; i < this._renderedItems.length; ++i) {
-      const cachedItemHeight = this._cachedItemHeight(this._firstActiveIndex + i);
-      if (Math.abs(cachedItemHeight - this._renderedItems[i].element().offsetHeight) > 1) {
-        this._rebuildCumulativeHeights();
-        break;
-      }
-    }
-  }
-
-  /**
-   * @param {number} index
-   * @return {number}
-   */
-  _cachedItemHeight(index) {
-    return index === 0 ? this._cumulativeHeights[0] :
-                         this._cumulativeHeights[index] - this._cumulativeHeights[index - 1];
-  }
-
-  /**
-   * @param {?Selection} selection
-   * @suppressGlobalPropertiesCheck
-   */
-  _isSelectionBackwards(selection) {
-    if (!selection || !selection.rangeCount)
-      return false;
-    const range = document.createRange();
-    range.setStart(selection.anchorNode, selection.anchorOffset);
-    range.setEnd(selection.focusNode, selection.focusOffset);
-    return range.collapsed;
-  }
-
-  /**
-   * @param {number} itemIndex
-   * @param {!Node} node
-   * @param {number} offset
-   * @return {!{item: number, node: !Node, offset: number}}
-   */
-  _createSelectionModel(itemIndex, node, offset) {
-    return {item: itemIndex, node: node, offset: offset};
-  }
-
-  /**
-   * @param {?Selection} selection
-   */
-  _updateSelectionModel(selection) {
-    const range = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
-    if (!range || selection.isCollapsed || !this.element.hasSelection()) {
-      this._headSelection = null;
-      this._anchorSelection = null;
-      return false;
-    }
-
-    let firstSelected = Number.MAX_VALUE;
-    let lastSelected = -1;
-
-    let hasVisibleSelection = false;
-    for (let i = 0; i < this._renderedItems.length; ++i) {
-      if (range.intersectsNode(this._renderedItems[i].element())) {
-        const index = i + this._firstActiveIndex;
-        firstSelected = Math.min(firstSelected, index);
-        lastSelected = Math.max(lastSelected, index);
-        hasVisibleSelection = true;
-      }
-    }
-    if (hasVisibleSelection) {
-      firstSelected =
-          this._createSelectionModel(firstSelected, /** @type {!Node} */ (range.startContainer), range.startOffset);
-      lastSelected =
-          this._createSelectionModel(lastSelected, /** @type {!Node} */ (range.endContainer), range.endOffset);
-    }
-    const topOverlap = range.intersectsNode(this._topGapElement) && this._topGapElement._active;
-    const bottomOverlap = range.intersectsNode(this._bottomGapElement) && this._bottomGapElement._active;
-    if (!topOverlap && !bottomOverlap && !hasVisibleSelection) {
-      this._headSelection = null;
-      this._anchorSelection = null;
-      return false;
-    }
-
-    if (!this._anchorSelection || !this._headSelection) {
-      this._anchorSelection = this._createSelectionModel(0, this.element, 0);
-      this._headSelection = this._createSelectionModel(this._itemCount - 1, this.element, this.element.children.length);
-      this._selectionIsBackward = false;
-    }
-
-    const isBackward = this._isSelectionBackwards(selection);
-    const startSelection = this._selectionIsBackward ? this._headSelection : this._anchorSelection;
-    const endSelection = this._selectionIsBackward ? this._anchorSelection : this._headSelection;
-    if (topOverlap && bottomOverlap && hasVisibleSelection) {
-      firstSelected = firstSelected.item < startSelection.item ? firstSelected : startSelection;
-      lastSelected = lastSelected.item > endSelection.item ? lastSelected : endSelection;
-    } else if (!hasVisibleSelection) {
-      firstSelected = startSelection;
-      lastSelected = endSelection;
-    } else if (topOverlap) {
-      firstSelected = isBackward ? this._headSelection : this._anchorSelection;
-    } else if (bottomOverlap) {
-      lastSelected = isBackward ? this._anchorSelection : this._headSelection;
-    }
-
-    if (isBackward) {
-      this._anchorSelection = lastSelected;
-      this._headSelection = firstSelected;
-    } else {
-      this._anchorSelection = firstSelected;
-      this._headSelection = lastSelected;
-    }
-    this._selectionIsBackward = isBackward;
-    return true;
-  }
-
-  /**
-   * @param {?Selection} selection
-   */
-  _restoreSelection(selection) {
-    let anchorElement = null;
-    let anchorOffset;
-    if (this._firstActiveIndex <= this._anchorSelection.item && this._anchorSelection.item <= this._lastActiveIndex) {
-      anchorElement = this._anchorSelection.node;
-      anchorOffset = this._anchorSelection.offset;
-    } else {
-      if (this._anchorSelection.item < this._firstActiveIndex)
-        anchorElement = this._topGapElement;
-      else if (this._anchorSelection.item > this._lastActiveIndex)
-        anchorElement = this._bottomGapElement;
-      anchorOffset = this._selectionIsBackward ? 1 : 0;
-    }
-
-    let headElement = null;
-    let headOffset;
-    if (this._firstActiveIndex <= this._headSelection.item && this._headSelection.item <= this._lastActiveIndex) {
-      headElement = this._headSelection.node;
-      headOffset = this._headSelection.offset;
-    } else {
-      if (this._headSelection.item < this._firstActiveIndex)
-        headElement = this._topGapElement;
-      else if (this._headSelection.item > this._lastActiveIndex)
-        headElement = this._bottomGapElement;
-      headOffset = this._selectionIsBackward ? 0 : 1;
-    }
-
-    selection.setBaseAndExtent(anchorElement, anchorOffset, headElement, headOffset);
-  }
-
-  refresh() {
-    this._observer.disconnect();
-    this._innerRefresh();
-    if (this._stickToBottom)
-      this._observer.observe(this._contentElement, this._observerConfig);
-  }
-
-  _innerRefresh() {
-    if (!this._visibleHeight())
-      return;  // Do nothing for invisible controls.
-
-    if (!this._itemCount) {
-      for (let i = 0; i < this._renderedItems.length; ++i)
-        this._renderedItems[i].willHide();
-      this._renderedItems = [];
-      this._contentElement.removeChildren();
-      this._topGapElement.style.height = '0px';
-      this._bottomGapElement.style.height = '0px';
-      this._firstActiveIndex = -1;
-      this._lastActiveIndex = -1;
-      return;
-    }
-
-    const selection = this.element.getComponentSelection();
-    const shouldRestoreSelection = this._updateSelectionModel(selection);
-
-    const visibleFrom = this.element.scrollTop;
-    const visibleHeight = this._visibleHeight();
-    const activeHeight = visibleHeight * 2;
-    this._rebuildCumulativeHeightsIfNeeded();
-
-    // When the viewport is scrolled to the bottom, using the cumulative heights estimate is not
-    // precise enough to determine next visible indices. This stickToBottom check avoids extra
-    // calls to refresh in those cases.
-    if (this._stickToBottom) {
-      this._firstActiveIndex =
-          Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.minimumRowHeight()), 0);
-      this._lastActiveIndex = this._itemCount - 1;
-    } else {
-      this._firstActiveIndex =
-          Math.max(this._cumulativeHeights.lowerBound(visibleFrom + 1 - (activeHeight - visibleHeight) / 2), 0);
-      // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169
-      this._lastActiveIndex = this._firstActiveIndex + Math.ceil(activeHeight / this._provider.minimumRowHeight()) - 1;
-      this._lastActiveIndex = Math.min(this._lastActiveIndex, this._itemCount - 1);
-    }
-
-    const topGapHeight = this._cumulativeHeights[this._firstActiveIndex - 1] || 0;
-    const bottomGapHeight =
-        this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastActiveIndex];
-
-    /**
-     * @this {Console.ConsoleViewport}
-     */
-    function prepare() {
-      this._topGapElement.style.height = topGapHeight + 'px';
-      this._bottomGapElement.style.height = bottomGapHeight + 'px';
-      this._topGapElement._active = !!topGapHeight;
-      this._bottomGapElement._active = !!bottomGapHeight;
-      this._contentElement.style.setProperty('height', '10000000px');
-    }
-
-    this._partialViewportUpdate(prepare.bind(this));
-    this._contentElement.style.removeProperty('height');
-    // Should be the last call in the method as it might force layout.
-    if (shouldRestoreSelection)
-      this._restoreSelection(selection);
-    if (this._stickToBottom)
-      this.element.scrollTop = 10000000;
-  }
-
-  /**
-   * @param {function()} prepare
-   */
-  _partialViewportUpdate(prepare) {
-    const itemsToRender = new Set();
-    for (let i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i)
-      itemsToRender.add(this._providerElement(i));
-    const willBeHidden = this._renderedItems.filter(item => !itemsToRender.has(item));
-    for (let i = 0; i < willBeHidden.length; ++i)
-      willBeHidden[i].willHide();
-    prepare();
-    for (let i = 0; i < willBeHidden.length; ++i)
-      willBeHidden[i].element().remove();
-
-    const wasShown = [];
-    let anchor = this._contentElement.firstChild;
-    for (const viewportElement of itemsToRender) {
-      const element = viewportElement.element();
-      if (element !== anchor) {
-        const shouldCallWasShown = !element.parentElement;
-        if (shouldCallWasShown)
-          wasShown.push(viewportElement);
-        this._contentElement.insertBefore(element, anchor);
-      } else {
-        anchor = anchor.nextSibling;
-      }
-    }
-    for (let i = 0; i < wasShown.length; ++i)
-      wasShown[i].wasShown();
-    this._renderedItems = Array.from(itemsToRender);
-  }
-
-  /**
-   * @return {?string}
-   */
-  _selectedText() {
-    this._updateSelectionModel(this.element.getComponentSelection());
-    if (!this._headSelection || !this._anchorSelection)
-      return null;
-
-    let startSelection = null;
-    let endSelection = null;
-    if (this._selectionIsBackward) {
-      startSelection = this._headSelection;
-      endSelection = this._anchorSelection;
-    } else {
-      startSelection = this._anchorSelection;
-      endSelection = this._headSelection;
-    }
-
-    const textLines = [];
-    for (let i = startSelection.item; i <= endSelection.item; ++i) {
-      const element = this._providerElement(i).element();
-      const lineContent = element.childTextNodes().map(Components.Linkifier.untruncatedNodeText).join('');
-      textLines.push(lineContent);
-    }
-
-    const endSelectionElement = this._providerElement(endSelection.item).element();
-    if (endSelection.node && endSelection.node.isSelfOrDescendant(endSelectionElement)) {
-      const itemTextOffset = this._textOffsetInNode(endSelectionElement, endSelection.node, endSelection.offset);
-      textLines[textLines.length - 1] = textLines.peekLast().substring(0, itemTextOffset);
-    }
-
-    const startSelectionElement = this._providerElement(startSelection.item).element();
-    if (startSelection.node && startSelection.node.isSelfOrDescendant(startSelectionElement)) {
-      const itemTextOffset = this._textOffsetInNode(startSelectionElement, startSelection.node, startSelection.offset);
-      textLines[0] = textLines[0].substring(itemTextOffset);
-    }
-
-    return textLines.join('\n');
-  }
-
-  /**
-   * @param {!Element} itemElement
-   * @param {!Node} selectionNode
-   * @param {number} offset
-   * @return {number}
-   */
-  _textOffsetInNode(itemElement, selectionNode, offset) {
-    // If the selectionNode is not a TextNode, we may need to convert a child offset into a character offset.
-    if (selectionNode.nodeType !== Node.TEXT_NODE) {
-      if (offset < selectionNode.childNodes.length) {
-        selectionNode = /** @type {!Node} */ (selectionNode.childNodes.item(offset));
-        offset = 0;
-      } else {
-        offset = selectionNode.textContent.length;
-      }
-    }
-
-    let chars = 0;
-    let node = itemElement;
-    while ((node = node.traverseNextNode(itemElement)) && node !== selectionNode) {
-      if (node.nodeType !== Node.TEXT_NODE || node.parentElement.nodeName === 'STYLE' ||
-          node.parentElement.nodeName === 'SCRIPT')
-        continue;
-      chars += Components.Linkifier.untruncatedNodeText(node).length;
-    }
-    // If the selected node text was truncated, treat any non-zero offset as the full length.
-    const untruncatedContainerLength = Components.Linkifier.untruncatedNodeText(selectionNode).length;
-    if (offset > 0 && untruncatedContainerLength !== selectionNode.textContent.length)
-      offset = untruncatedContainerLength;
-    return chars + offset;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onScroll(event) {
-    this.refresh();
-  }
-
-  /**
-   * @return {number}
-   */
-  firstVisibleIndex() {
-    if (!this._cumulativeHeights.length)
-      return -1;
-    this._rebuildCumulativeHeightsIfNeeded();
-    return this._cumulativeHeights.lowerBound(this.element.scrollTop + 1);
-  }
-
-  /**
-   * @return {number}
-   */
-  lastVisibleIndex() {
-    if (!this._cumulativeHeights.length)
-      return -1;
-    this._rebuildCumulativeHeightsIfNeeded();
-    const scrollBottom = this.element.scrollTop + this.element.clientHeight;
-    const right = this._itemCount - 1;
-    return this._cumulativeHeights.lowerBound(scrollBottom, undefined, undefined, right);
-  }
-
-  /**
-   * @return {?Element}
-   */
-  renderedElementAt(index) {
-    if (index < this._firstActiveIndex)
-      return null;
-    if (index > this._lastActiveIndex)
-      return null;
-    return this._renderedItems[index - this._firstActiveIndex].element();
-  }
-
-  /**
-   * @param {number} index
-   * @param {boolean=} makeLast
-   */
-  scrollItemIntoView(index, makeLast) {
-    const firstVisibleIndex = this.firstVisibleIndex();
-    const lastVisibleIndex = this.lastVisibleIndex();
-    if (index > firstVisibleIndex && index < lastVisibleIndex)
-      return;
-    if (makeLast)
-      this.forceScrollItemToBeLast(index);
-    else if (index <= firstVisibleIndex)
-      this.forceScrollItemToBeFirst(index);
-    else if (index >= lastVisibleIndex)
-      this.forceScrollItemToBeLast(index);
-  }
-
-  /**
-   * @param {number} index
-   */
-  forceScrollItemToBeFirst(index) {
-    console.assert(index >= 0 && index < this._itemCount, 'Cannot scroll item at invalid index');
-    this.setStickToBottom(false);
-    this._rebuildCumulativeHeightsIfNeeded();
-    this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0;
-    if (this.element.isScrolledToBottom())
-      this.setStickToBottom(true);
-    this.refresh();
-  }
-
-  /**
-   * @param {number} index
-   */
-  forceScrollItemToBeLast(index) {
-    console.assert(index >= 0 && index < this._itemCount, 'Cannot scroll item at invalid index');
-    this.setStickToBottom(false);
-    this._rebuildCumulativeHeightsIfNeeded();
-    this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeight();
-    if (this.element.isScrolledToBottom())
-      this.setStickToBottom(true);
-    this.refresh();
-  }
-
-  /**
-   * @return {number}
-   */
-  _visibleHeight() {
-    // Use offsetHeight instead of clientHeight to avoid being affected by horizontal scroll.
-    return this.element.offsetHeight;
-  }
-};
-
-/**
- * @interface
- */
-Console.ConsoleViewportProvider = function() {};
-
-Console.ConsoleViewportProvider.prototype = {
-  /**
-   * @param {number} index
-   * @return {number}
-   */
-  fastHeight(index) {
-    return 0;
-  },
-
-  /**
-   * @return {number}
-   */
-  itemCount() {
-    return 0;
-  },
-
-  /**
-   * @return {number}
-   */
-  minimumRowHeight() {
-    return 0;
-  },
-
-  /**
-   * @param {number} index
-   * @return {?Console.ConsoleViewportElement}
-   */
-  itemElement(index) {
-    return null;
-  }
-};
-
-/**
- * @interface
- */
-Console.ConsoleViewportElement = function() {};
-Console.ConsoleViewportElement.prototype = {
-  willHide() {},
-
-  wasShown() {},
-
-  /**
-   * @return {!Element}
-   */
-  element() {},
-};
diff --git a/front_end/console/consoleContextSelector.css b/front_end/console/consoleContextSelector.css
deleted file mode 100644
index 6fd4126..0000000
--- a/front_end/console/consoleContextSelector.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    padding: 2px 1px 2px 2px;
-    white-space: nowrap;
-    display: flex;
-    flex-direction: column;
-    height: 36px;
-    justify-content: center;
-}
-
-.title {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    flex-grow: 0;
-}
-
-.badge {
-    pointer-events: none;
-    margin-right: 4px;
-    display: inline-block;
-    height: 15px;
-}
-
-.subtitle {
-    color: #999;
-    margin-right: 3px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    flex-grow: 0;
-}
-
-:host(.highlighted) .subtitle {
-    color: inherit;
-}
diff --git a/front_end/console/consoleSidebar.css b/front_end/console/consoleSidebar.css
deleted file mode 100644
index 01ad4e1..0000000
--- a/front_end/console/consoleSidebar.css
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    overflow: auto;
-    background-color: var(--toolbar-bg-color);
-}
-
-.tree-outline-disclosure {
-    max-width: 100%;
-    padding-left: 6px;
-}
-
-.count {
-    flex: none;
-    margin: 0 8px;
-}
-
-[is=ui-icon] {
-    margin: 0 5px;
-}
-
-[is=ui-icon].icon-warning {
-    background: linear-gradient(45deg, hsla(48, 100%, 50%, 1), hsla(48, 70%, 50%, 1));
-}
-
-li {
-    height: 24px;
-}
-
-li .largeicon-navigator-file {
-    background: linear-gradient(45deg, hsl(48, 70%, 50%), hsl(48, 70%, 70%));
-    margin: 0;
-}
-
-li .largeicon-navigator-folder {
-    background: linear-gradient(45deg, hsl(210, 82%, 65%), hsl(210, 82%, 80%));
-    margin: -3px -3px 0 -5px;
-}
-
-.tree-element-title {
-    flex-shrink: 100;
-    flex-grow: 1;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.tree-outline li:hover:not(.selected) .selection {
-    display: block;
-    background-color: rgba(56, 121, 217, 0.1);
-}
diff --git a/front_end/console/consoleView.css b/front_end/console/consoleView.css
deleted file mode 100644
index 5fe2a6e..0000000
--- a/front_end/console/consoleView.css
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.console-view {
-    background-color: white;
-    overflow: hidden;
-}
-
-.console-view > .toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.console-view-wrapper {
-    background-color: #eee;
-}
-
-.console-view-fix-select-all {
-    height: 0;
-    overflow: hidden;
-}
-
-.console-settings-pane {
-    flex: none;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.console-settings-pane .toolbar {
-    flex: 1 1;
-}
-
-#console-messages {
-    flex: 1 1;
-    padding: 2px 0;
-    overflow-y: auto;
-    word-wrap: break-word;
-    -webkit-user-select: text;
-    transform: translateZ(0);
-}
-
-#console-prompt {
-    clear: right;
-    position: relative;
-    margin: 0 22px 0 20px;
-    min-height: 18px;  /* Sync with ConsoleViewMessage.js */
-}
-
-#console-prompt .CodeMirror {
-    padding: 3px 0 1px 0;
-}
-
-#console-prompt .CodeMirror-line {
-    padding-top: 0;
-}
-
-#console-prompt .CodeMirror-lines {
-    padding-top: 0;
-}
-
-#console-prompt .console-prompt-icon {
-    position: absolute;
-    left: -13px;
-    top: 5px;
-    -webkit-user-select: none;
-}
-
-.console-message,
-.console-user-command {
-    clear: right;
-    position: relative;
-    padding: 3px 22px 1px 0;
-    margin-left: 24px;
-    min-height: 18px;  /* Sync with ConsoleViewMessage.js */
-    flex: auto;
-    display: flex;
-}
-
-.console-message > * {
-    flex: auto;
-}
-
-.console-timestamp {
-    color: gray;
-    -webkit-user-select: none;
-    flex: none;
-    margin-right: 5px;
-}
-
-.message-level-icon, .command-result-icon {
-    position: absolute;
-    left: -17px;
-    top: 4px;
-    -webkit-user-select: none;
-}
-
-.console-message-repeat-count {
-    margin: 2px 0 0 10px;
-    flex: none;
-}
-
-.repeated-message {
-    margin-left: 4px;
-}
-
-.repeated-message .message-level-icon {
-    display: none;
-}
-
-.repeated-message .console-message-stack-trace-toggle,
-.repeated-message > .console-message-text {
-    flex: 1;
-}
-
-.console-error-level .repeated-message,
-.console-warning-level .repeated-message,
-.console-verbose-level .repeated-message,
-.console-info-level .repeated-message {
-    display: flex;
-}
-
-.console-info {
-    color: rgb(128, 128, 128);
-    font-style: italic;
-    padding-bottom: 2px;
-}
-
-.console-group .console-group > .console-group-messages {
-    margin-left: 16px;
-}
-
-.console-group-title.console-from-api {
-    font-weight: bold;
-}
-
-.console-group-title .console-message {
-    margin-left: 12px;
-}
-
-.expand-group-icon {
-    -webkit-user-select: none;
-    flex: none;
-    background-color: rgb(110, 110, 110);
-    position: relative;
-    left: 10px;
-    top: 5px;
-    margin-right: 2px;
-}
-
-.console-group-title .message-level-icon {
-    display: none;
-}
-
-.console-message-repeat-count .expand-group-icon {
-    left: 2px;
-    top: 2px;
-    background-color: #fff;
-    margin-right: 4px;
-}
-
-.console-group {
-    position: relative;
-}
-
-.console-message-wrapper {
-    display: flex;
-    border-bottom: 1px solid rgb(240, 240, 240);
-}
-
-.console-message-wrapper.console-adjacent-user-command-result {
-    border-bottom: none;
-}
-
-.console-message-wrapper.console-error-level {
-    border-top: 1px solid hsl(0, 100%, 92%);
-    border-bottom: 1px solid hsl(0, 100%, 92%);
-    margin-top: -1px;
-}
-
-.console-message-wrapper.console-warning-level {
-    border-top: 1px solid hsl(50, 100%, 88%);
-    border-bottom: 1px solid hsl(50, 100%, 88%);
-    margin-top: -1px;
-}
-
-.console-message-wrapper .nesting-level-marker {
-    width: 14px;
-    flex: 0 0 auto;
-    border-right: 1px solid #a5a5a5;
-    position: relative;
-    margin-bottom: -1px;
-}
-
-.console-message-wrapper:last-child .nesting-level-marker::before,
-.console-message-wrapper .nesting-level-marker.group-closed::before {
-    content: "";
-}
-
-.console-message-wrapper .nesting-level-marker::before {
-    border-bottom: 1px solid #a5a5a5;
-    position: absolute;
-    top: 0;
-    left: 0;
-    margin-left: 100%;
-    width: 3px;
-    height: 100%;
-    box-sizing: border-box;
-}
-
-.console-error-level {
-    background-color: hsl(0, 100%, 97%);
-}
-
-.-theme-with-dark-background .console-error-level {
-    background-color: hsl(0, 100%, 8%);
-}
-
-.console-warning-level {
-    background-color: hsl(50, 100%, 95%);
-}
-
-.-theme-with-dark-background .console-warning-level {
-    background-color: hsl(50, 100%, 10%);
-}
-
-.console-warning-level .console-message-text {
-    color: hsl(39, 100%, 18%);
-}
-
-.console-error-level .console-message-text,
-.console-error-level .console-view-object-properties-section {
-    color: red !important;
-}
-
-.console-system-type.console-info-level {
-    color: blue;
-}
-
-.-theme-with-dark-background .console-error-level .console-message-text,
-.-theme-with-dark-background .console-error-level .console-view-object-properties-section {
-    color: hsl(0, 100%, 75%) !important;
-}
-
-.-theme-with-dark-background .console-verbose-level:not(.console-warning-level) .console-message-text,
-.-theme-with-dark-background .console-system-type.console-info-level {
-    color: hsl(220, 100%, 65%) !important;
-}
-
-.console-message.console-warning-level {
-    background-color: rgb(255, 250, 224);
-}
-
-#console-messages .link {
-    text-decoration: underline;
-}
-
-#console-messages .link,
-#console-messages .devtools-link {
-    color: rgb(33%, 33%, 33%);
-    cursor: pointer;
-    word-break: break-all;
-}
-
-#console-messages .link:hover,
-#console-messages .devtools-link:hover {
-    color: rgb(15%, 15%, 15%);
-}
-
-.console-group-messages .section {
-    margin: 0 0 0 12px !important;
-}
-
-.console-group-messages .section > .header {
-    padding: 0 8px 0 0;
-    background-image: none;
-    border: none;
-    min-height: 0;
-}
-
-.console-group-messages .section > .header::before {
-    margin-left: -12px;
-}
-
-.console-group-messages .section > .header .title {
-    color: #222;
-    font-weight: normal;
-    line-height: 13px;
-}
-
-.console-group-messages .section .properties li .info {
-    padding-top: 0;
-    padding-bottom: 0;
-    color: rgb(60%, 60%, 60%);
-}
-
-.console-object-preview {
-    white-space: normal;
-    word-wrap: break-word;
-    font-style: italic;
-}
-
-.console-object-preview .name {
-    /* Follows .section .properties .name, .event-properties .name */
-    color: rgb(136, 19, 145);
-    flex-shrink: 0;
-}
-
-.console-message-text .object-value-string,
-.console-message-text .object-value-regexp,
-.console-message-text .object-value-symbol {
-    white-space: pre-wrap;
-    word-break: break-all;
-}
-
-.console-message-formatted-table {
-    clear: both;
-}
-
-.console-message-anchor {
-    float: right;
-    text-align: right;
-    max-width: 100%;
-    margin-left: 4px;
-}
-
-.console-message-badge {
-    float: right;
-    margin-left: 4px;
-}
-
-.console-message-nowrap-below,
-.console-message-nowrap-below div,
-.console-message-nowrap-below span {
-    white-space: nowrap !important;
-}
-
-.object-state-note {
-    display: inline-block;
-    width: 11px;
-    height: 11px;
-    color: white;
-    text-align: center;
-    border-radius: 3px;
-    line-height: 13px;
-    margin: 0 6px;
-    font-size: 9px;
-}
-
-.-theme-with-dark-background .object-state-note {
-    background-color: hsl(230, 100%, 80%);
-}
-
-.info-note {
-    background-color: rgb(179, 203, 247);
-}
-
-.info-note::before {
-    content: "i";
-}
-
-.console-view-object-properties-section:not(.expanded) .info-note {
-    display: none;
-}
-
-.console-view-object-properties-section {
-    padding: 0px;
-    position: relative;
-    vertical-align: baseline;
-    color: inherit;
-    display: inline-block;
-    overflow-wrap: break-word;
-    max-width: 100%;
-}
-
-.console-object {
-    white-space: pre-wrap;
-    word-break: break-all;
-}
-
-.console-message-stack-trace-toggle {
-    display: flex;
-    flex-direction: row;
-    align-items: flex-start;
-}
-
-.console-message-stack-trace-wrapper {
-    flex: 1 1 auto;
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-}
-
-.console-message-stack-trace-wrapper > * {
-    flex: none;
-}
-
-.console-message-expand-icon {
-    margin-bottom: -2px;
-}
-
-.console-inline-button {
-    background-color: #dedede;
-    padding: 2px 4px;
-    margin: 0 2px;
-    color: #333;
-    cursor: pointer;
-    border-radius: 3px;
-    font-size: 12px;
-    font-family: sans-serif;
-    white-space: nowrap;
-    display: inline-block;
-}
-
-.console-inline-button::after {
-    content: attr(data-text);
-}
-
-.console-inline-button:hover {
-    background-color: #d5d5d5;
-}
-
-.console-searchable-view {
-    max-height: 100%;
-}
diff --git a/front_end/console/module.json b/front_end/console/module.json
deleted file mode 100644
index 0a848c2..0000000
--- a/front_end/console/module.json
+++ /dev/null
@@ -1,185 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "console",
-            "title": "Console",
-            "order": 20,
-            "className": "Console.ConsolePanel"
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "console-view",
-            "title": "Console",
-            "persistence": "permanent",
-            "order": 0,
-            "className": "Console.ConsolePanel.WrapperView"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "Common.Console"
-            ],
-            "className": "Console.ConsolePanel.ConsoleRevealer"
-        },
-        {
-            "type": "action",
-            "actionId": "console.show",
-            "className": "Console.ConsoleView.ActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "Ctrl+`"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Console",
-            "actionId": "console.clear",
-            "title": "Clear console",
-            "iconClass": "largeicon-clear",
-            "className": "Console.ConsoleView.ActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+L"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Ctrl+L Meta+K"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Console",
-            "actionId": "console.clear.history",
-            "title": "Clear console history",
-            "className": "Console.ConsoleView.ActionDelegate"
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Hide network messages",
-            "settingName": "hideNetworkMessages",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Hide network messages"
-                },
-                {
-                    "value": false,
-                    "title": "Show network messages"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Selected context only",
-            "settingName": "selectedContextFilterEnabled",
-            "settingType": "boolean",
-            "storageType": "session",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Only show messages from the current context (top, iframe, worker, extension)"
-                },
-                {
-                    "value": false,
-                    "title": "Show messages from all contexts"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Log XMLHttpRequests",
-            "settingName": "monitoringXHREnabled",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Show timestamps",
-            "settingName": "consoleTimestampsEnabled",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show timestamps"
-                },
-                {
-                    "value": false,
-                    "title": "Hide timestamps"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Autocomplete from history",
-            "settingName": "consoleHistoryAutocomplete",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Autocomplete from history"
-                },
-                {
-                    "value": false,
-                    "title": "Do not autocomplete from history"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Group similar",
-            "settingName": "consoleGroupSimilar",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Group similar messages in console"
-                },
-                {
-                    "value": false,
-                    "title": "Do not group similar messages in console"
-                }
-            ]
-        }
-    ],
-    "dependencies": [
-        "components",
-        "data_grid",
-        "object_ui",
-        "sdk",
-        "product_registry",
-        "formatter"
-    ],
-    "scripts": [
-        "ConsoleContextSelector.js",
-        "ConsoleFilter.js",
-        "ConsoleSidebar.js",
-        "ConsoleViewport.js",
-        "ConsoleViewMessage.js",
-        "ConsolePrompt.js",
-        "ConsoleView.js",
-        "ConsolePanel.js"
-    ],
-    "resources": [
-        "consoleContextSelector.css",
-        "consoleSidebar.css",
-        "consoleView.css"
-    ]
-}
diff --git a/front_end/console_counters/WarningErrorCounter.js b/front_end/console_counters/WarningErrorCounter.js
deleted file mode 100644
index b51e2ef..0000000
--- a/front_end/console_counters/WarningErrorCounter.js
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- * @unrestricted
- */
-ConsoleCounters.WarningErrorCounter = class {
-  constructor() {
-    ConsoleCounters.WarningErrorCounter._instanceForTest = this;
-
-    this._counter = createElement('div');
-    this._counter.addEventListener('click', Common.console.show.bind(Common.console), false);
-    this._toolbarItem = new UI.ToolbarItem(this._counter);
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this._counter, 'console_counters/errorWarningCounter.css');
-
-    this._errors = this._createItem(shadowRoot, 'smallicon-error');
-    this._warnings = this._createItem(shadowRoot, 'smallicon-warning');
-    this._titles = [];
-    this._errorCount = -1;
-    this._warningCount = -1;
-    this._throttler = new Common.Throttler(100);
-
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.ConsoleCleared, this._update, this);
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageAdded, this._update, this);
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.MessageUpdated, this._update, this);
-    this._update();
-  }
-
-  _updatedForTest() {
-    // Sniffed in tests.
-  }
-
-  /**
-   * @param {!Node} shadowRoot
-   * @param {string} iconType
-   * @return {!{item: !Element, text: !Element}}
-   */
-  _createItem(shadowRoot, iconType) {
-    const item = createElementWithClass('span', 'counter-item');
-    const icon = item.createChild('label', '', 'dt-icon-label');
-    icon.type = iconType;
-    const text = icon.createChild('span');
-    shadowRoot.appendChild(item);
-    return {item: item, text: text};
-  }
-
-  /**
-   * @param {!{item: !Element, text: !Element}} item
-   * @param {number} count
-   * @param {boolean} first
-   * @param {string} title
-   */
-  _updateItem(item, count, first, title) {
-    item.item.classList.toggle('hidden', !count);
-    item.item.classList.toggle('counter-item-first', first);
-    item.text.textContent = count;
-    if (count)
-      this._titles.push(title);
-  }
-
-  _update() {
-    this._updatingForTest = true;
-    this._throttler.schedule(this._updateThrottled.bind(this));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _updateThrottled() {
-    const errors = SDK.consoleModel.errors();
-    const warnings = SDK.consoleModel.warnings();
-    if (errors === this._errorCount && warnings === this._warningCount)
-      return Promise.resolve();
-    this._errorCount = errors;
-    this._warningCount = warnings;
-
-    this._titles = [];
-    this._toolbarItem.setVisible(!!(errors || warnings));
-    this._updateItem(this._errors, errors, false, Common.UIString(errors === 1 ? '%d error' : '%d errors', errors));
-    this._updateItem(
-        this._warnings, warnings, !errors, Common.UIString(warnings === 1 ? '%d warning' : '%d warnings', warnings));
-    this._counter.title = this._titles.join(', ');
-    UI.inspectorView.toolbarItemResized();
-    this._updatingForTest = false;
-    this._updatedForTest();
-    return Promise.resolve();
-  }
-
-  /**
-   * @override
-   * @return {?UI.ToolbarItem}
-   */
-  item() {
-    return this._toolbarItem;
-  }
-};
\ No newline at end of file
diff --git a/front_end/console_counters/errorWarningCounter.css b/front_end/console_counters/errorWarningCounter.css
deleted file mode 100644
index d6ad447..0000000
--- a/front_end/console_counters/errorWarningCounter.css
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    cursor: pointer;
-    padding: 0 2px;
-    min-width: 26px;
-}
-
-:host:hover {
-    color: #333;
-}
-
-.counter-item {
-    margin-left: 6px;
-}
-
-.counter-item label {
-    cursor: inherit;
-}
-
-.counter-item.counter-item-first {
-    margin-left: 0;
-}
diff --git a/front_end/console_counters/module.json b/front_end/console_counters/module.json
deleted file mode 100644
index f24e3cf..0000000
--- a/front_end/console_counters/module.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "extensions": [
-    {
-      "type": "@UI.ToolbarItem.Provider",
-      "className": "ConsoleCounters.WarningErrorCounter",
-      "order": 1,
-      "location": "main-toolbar-right"
-    }
-  ],
-  "dependencies": [
-    "common",
-    "ui",
-    "sdk"
-  ],
-  "scripts": [
-    "WarningErrorCounter.js"
-  ],
-  "resources": [
-    "errorWarningCounter.css"
-  ]
-}
\ No newline at end of file
diff --git a/front_end/console_test_runner/ConsoleTestRunner.js b/front_end/console_test_runner/ConsoleTestRunner.js
deleted file mode 100644
index 9575313..0000000
--- a/front_end/console_test_runner/ConsoleTestRunner.js
+++ /dev/null
@@ -1,622 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-/** @typedef {function(!Element, !SDK.ConsoleMessage=):string} */
-ConsoleTestRunner.Formatter;
-
-/**
- * @param {boolean=} printOriginatingCommand
- * @param {boolean=} dumpClassNames
- * @param {!ConsoleTestRunner.Formatter=} formatter
- */
-ConsoleTestRunner.dumpConsoleMessages = function(printOriginatingCommand, dumpClassNames, formatter) {
-  TestRunner.addResults(
-      ConsoleTestRunner.dumpConsoleMessagesIntoArray(printOriginatingCommand, dumpClassNames, formatter));
-};
-
-ConsoleTestRunner.renderCompleteMessages = async function() {
-  const consoleView = Console.ConsoleView.instance();
-  if (consoleView._needsFullUpdate)
-    consoleView._updateMessageList();
-  const viewMessages = consoleView._visibleViewMessages;
-  await Promise.all(viewMessages.map(uiMessage => uiMessage.completeElementForTest()));
-};
-
-/**
- * @param {boolean=} printOriginatingCommand
- * @param {boolean=} dumpClassNames
- * @param {!ConsoleTestRunner.Formatter=} formatter
- * @return {!Array<string>}
- */
-ConsoleTestRunner.dumpConsoleMessagesIntoArray = function(printOriginatingCommand, dumpClassNames, formatter) {
-  formatter = formatter || ConsoleTestRunner.prepareConsoleMessageText;
-  const result = [];
-  ConsoleTestRunner.disableConsoleViewport();
-  const consoleView = Console.ConsoleView.instance();
-  if (consoleView._needsFullUpdate)
-    consoleView._updateMessageList();
-  const viewMessages = consoleView._visibleViewMessages;
-  for (let i = 0; i < viewMessages.length; ++i) {
-    const uiMessage = viewMessages[i];
-    const message = uiMessage.consoleMessage();
-    const element = uiMessage.element();
-
-    let classNames;
-    if (dumpClassNames) {
-      classNames = [];
-      for (let node = element.firstChild; node; node = node.traverseNextNode(element)) {
-        if (node.nodeType === Node.ELEMENT_NODE && node.className) {
-          classNames.push(node.className.replace('platform-linux', 'platform-*')
-                              .replace('platform-mac', 'platform-*')
-                              .replace('platform-windows', 'platform-*'));
-        }
-      }
-    }
-
-    if (ConsoleTestRunner.dumpConsoleTableMessage(uiMessage, false, result)) {
-      if (dumpClassNames)
-        result.push(classNames.join(' > '));
-    } else {
-      let messageText = formatter(element, message);
-      messageText = messageText.replace(/VM\d+/g, 'VM');
-      result.push(messageText + (dumpClassNames ? ' ' + classNames.join(' > ') : ''));
-    }
-
-    if (printOriginatingCommand && uiMessage.consoleMessage().originatingMessage())
-      result.push('Originating from: ' + uiMessage.consoleMessage().originatingMessage().messageText);
-  }
-  return result;
-};
-
-/**
- * @param {!Element} messageElement
- * @return {string}
- */
-ConsoleTestRunner.prepareConsoleMessageText = function(messageElement) {
-  let messageText = messageElement.deepTextContent().replace(/\u200b/g, '');
-  // Replace scriptIds with generic scriptId string to avoid flakiness.
-  messageText = messageText.replace(/VM\d+/g, 'VM');
-  // Remove line and column of evaluate method.
-  messageText = messageText.replace(/(at eval \(eval at evaluate) \(:\d+:\d+\)/, '$1');
-
-  if (messageText.startsWith('Navigated to')) {
-    const fileName = messageText.split(' ').pop().split('/').pop();
-    messageText = 'Navigated to ' + fileName;
-  }
-  // The message might be extremely long in case of dumping stack overflow message.
-  messageText = messageText.substring(0, 1024);
-  return messageText;
-};
-
-/**
- * @param {!Console.ConsoleViewMessage} viewMessage
- * @param {boolean} forceInvalidate
- * @param {!Array<string>} results
- * @return {boolean}
- */
-ConsoleTestRunner.dumpConsoleTableMessage = function(viewMessage, forceInvalidate, results) {
-  if (forceInvalidate)
-    Console.ConsoleView.instance()._viewport.invalidate();
-  const table = viewMessage.element();
-  const headers = table.querySelectorAll('th > div:first-child');
-  if (!headers.length)
-    return false;
-
-  let headerLine = '';
-  for (let i = 0; i < headers.length; i++)
-    headerLine += headers[i].textContent + ' | ';
-
-  addResult('HEADER ' + headerLine);
-
-  const rows = table.querySelectorAll('.data-container tr');
-
-  for (let i = 0; i < rows.length; i++) {
-    const row = rows[i];
-    let rowLine = '';
-    const items = row.querySelectorAll('td > span');
-    for (let j = 0; j < items.length; j++)
-      rowLine += items[j].textContent + ' | ';
-
-    if (rowLine.trim())
-      addResult('ROW ' + rowLine);
-  }
-
-  /**
-   * @param {string} x
-   */
-  function addResult(x) {
-    if (results)
-      results.push(x);
-    else
-      TestRunner.addResult(x);
-  }
-
-  return true;
-};
-
-ConsoleTestRunner.disableConsoleViewport = function() {
-  ConsoleTestRunner.fixConsoleViewportDimensions(600, 2000);
-};
-
-/**
- * @param {number} width
- * @param {number} height
- */
-ConsoleTestRunner.fixConsoleViewportDimensions = function(width, height) {
-  const viewport = Console.ConsoleView.instance()._viewport;
-  viewport.element.style.width = width + 'px';
-  viewport.element.style.height = height + 'px';
-  viewport.element.style.position = 'absolute';
-  viewport.invalidate();
-};
-
-ConsoleTestRunner.selectMainExecutionContext = function() {
-  const executionContexts = TestRunner.runtimeModel.executionContexts();
-  for (const context of executionContexts) {
-    if (context.isDefault) {
-      UI.context.setFlavor(SDK.ExecutionContext, context);
-      return;
-    }
-  }
-};
-
-/**
- * @param {string} code
- * @param {!Function=} callback
- * @param {boolean=} dontForceMainContext
- */
-ConsoleTestRunner.evaluateInConsole = function(code, callback, dontForceMainContext) {
-  if (!dontForceMainContext)
-    ConsoleTestRunner.selectMainExecutionContext();
-  callback = TestRunner.safeWrap(callback);
-
-  const consoleView = Console.ConsoleView.instance();
-  consoleView._prompt._appendCommand(code, true);
-  ConsoleTestRunner.addConsoleViewSniffer(function(commandResult) {
-    callback(commandResult.toMessageElement().deepTextContent());
-  });
-};
-
-/**
- * @param {string} code
- * @param {boolean=} dontForceMainContext
- * @return {!Promise}
- */
-ConsoleTestRunner.evaluateInConsolePromise = function(code, dontForceMainContext) {
-  return new Promise(fulfill => ConsoleTestRunner.evaluateInConsole(code, fulfill, dontForceMainContext));
-};
-
-/**
- * @param {!Function} override
- * @param {boolean=} opt_sticky
- */
-ConsoleTestRunner.addConsoleViewSniffer = function(override, opt_sticky) {
-  TestRunner.addSniffer(Console.ConsoleView.prototype, '_consoleMessageAddedForTest', override, opt_sticky);
-};
-
-ConsoleTestRunner.waitForPendingViewportUpdates = async function() {
-  const refreshPromise = Console.ConsoleView.instance()._scheduledRefreshPromiseForTest || Promise.resolve();
-  await refreshPromise;
-};
-
-/**
- * @param {string} code
- * @param {!Function=} callback
- * @param {boolean=} dontForceMainContext
- */
-ConsoleTestRunner.evaluateInConsoleAndDump = function(code, callback, dontForceMainContext) {
-  callback = TestRunner.safeWrap(callback);
-  /**
-   * @param {string} text
-   */
-  function mycallback(text) {
-    text = text.replace(/\bVM\d+/g, 'VM');
-    TestRunner.addResult(code + ' = ' + text);
-    callback(text);
-  }
-  ConsoleTestRunner.evaluateInConsole(code, mycallback, dontForceMainContext);
-};
-
-/**
- * @return {number}
- */
-ConsoleTestRunner.consoleMessagesCount = function() {
-  const consoleView = Console.ConsoleView.instance();
-  return consoleView._consoleMessages.length;
-};
-
-/**
- * @param {function(!Element):string|undefined} messageFormatter
- * @param {!Element} node
- * @return {string}
- */
-ConsoleTestRunner.formatterIgnoreStackFrameUrls = function(messageFormatter, node) {
-  /**
-   * @param {string} string
-   */
-  function isNotEmptyLine(string) {
-    return string.trim().length > 0;
-  }
-
-  /**
-   * @param {string} string
-   */
-  function ignoreStackFrameAndMutableData(string) {
-    let buffer = string.replace(/\u200b/g, '');
-    buffer = buffer.replace(/VM\d+/g, 'VM');
-    return buffer.replace(/^\s+at [^\]]+(]?)$/, '$1');
-  }
-
-  messageFormatter = messageFormatter || TestRunner.textContentWithLineBreaks;
-  const buffer = messageFormatter(node);
-  return buffer.split('\n').map(ignoreStackFrameAndMutableData).filter(isNotEmptyLine).join('\n');
-};
-
-/**
- * @param {!Element} element
- * @param {!SDK.ConsoleMessage} message
- * @return {string}
- */
-ConsoleTestRunner.simpleFormatter = function(element, message) {
-  return message.messageText + ':' + message.line + ':' + message.column;
-};
-
-/**
- * @param {boolean=} printOriginatingCommand
- * @param {boolean=} dumpClassNames
- * @param {!ConsoleTestRunner.Formatter=} messageFormatter
- */
-ConsoleTestRunner.dumpConsoleMessagesIgnoreErrorStackFrames = function(
-    printOriginatingCommand, dumpClassNames, messageFormatter) {
-  TestRunner.addResults(ConsoleTestRunner.dumpConsoleMessagesIntoArray(
-      printOriginatingCommand, dumpClassNames,
-      ConsoleTestRunner.formatterIgnoreStackFrameUrls.bind(this, messageFormatter)));
-};
-
-ConsoleTestRunner.dumpConsoleMessagesWithStyles = function() {
-  const messageViews = Console.ConsoleView.instance()._visibleViewMessages;
-  for (let i = 0; i < messageViews.length; ++i) {
-    const element = messageViews[i].element();
-    const messageText = ConsoleTestRunner.prepareConsoleMessageText(element);
-    TestRunner.addResult(messageText);
-    const spans = element.querySelectorAll('.console-message-text *');
-    for (let j = 0; j < spans.length; ++j)
-      TestRunner.addResult('Styled text #' + j + ': ' + (spans[j].style.cssText || 'NO STYLES DEFINED'));
-  }
-};
-
-/**
- * @param {boolean=} sortMessages
- */
-ConsoleTestRunner.dumpConsoleMessagesWithClasses = function(sortMessages) {
-  const result = [];
-  const messageViews = Console.ConsoleView.instance()._visibleViewMessages;
-  for (let i = 0; i < messageViews.length; ++i) {
-    const element = messageViews[i].element();
-    const contentElement = messageViews[i].contentElement();
-    const messageText = ConsoleTestRunner.prepareConsoleMessageText(element);
-    result.push(messageText + ' ' + element.getAttribute('class') + ' > ' + contentElement.getAttribute('class'));
-  }
-  if (sortMessages)
-    result.sort();
-  TestRunner.addResults(result);
-};
-
-ConsoleTestRunner.dumpConsoleClassesBrief = function() {
-  const messageViews = Console.ConsoleView.instance()._visibleViewMessages;
-  for (let i = 0; i < messageViews.length; ++i) {
-    const repeatText = messageViews[i].repeatCount() > 1 ? (' x' + messageViews[i].repeatCount()) : '';
-    TestRunner.addResult(messageViews[i].toMessageElement().className + repeatText);
-  }
-};
-
-ConsoleTestRunner.dumpConsoleCounters = async function() {
-  const counter = ConsoleCounters.WarningErrorCounter._instanceForTest;
-  if (counter._updatingForTest)
-    await TestRunner.addSnifferPromise(counter, '_updatedForTest');
-  for (let index = 0; index < counter._titles.length; ++index)
-    TestRunner.addResult(counter._titles[index]);
-  ConsoleTestRunner.dumpConsoleClassesBrief();
-};
-
-/**
- * @param {!Function} callback
- * @param {function(!Element):boolean} deepFilter
- * @param {function(!ObjectUI.ObjectPropertiesSection):boolean} sectionFilter
- */
-ConsoleTestRunner.expandConsoleMessages = function(callback, deepFilter, sectionFilter) {
-  Console.ConsoleView.instance()._invalidateViewport();
-  const messageViews = Console.ConsoleView.instance()._visibleViewMessages;
-
-  // Initiate round-trips to fetch necessary data for further rendering.
-  for (let i = 0; i < messageViews.length; ++i)
-    messageViews[i].element();
-
-  TestRunner.deprecatedRunAfterPendingDispatches(expandTreeElements);
-
-  function expandTreeElements() {
-    for (let i = 0; i < messageViews.length; ++i) {
-      const element = messageViews[i].element();
-      for (let node = element; node; node = node.traverseNextNode(element)) {
-        if (node.treeElementForTest)
-          node.treeElementForTest.expand();
-        if (node._expandStackTraceForTest)
-          node._expandStackTraceForTest();
-        if (!node._section)
-          continue;
-        if (sectionFilter && !sectionFilter(node._section))
-          continue;
-        node._section.expand();
-
-        if (!deepFilter)
-          continue;
-        const treeElements = node._section.rootElement().children();
-        for (let j = 0; j < treeElements.length; ++j) {
-          for (let treeElement = treeElements[j]; treeElement;
-               treeElement = treeElement.traverseNextTreeElement(true, null, true)) {
-            if (deepFilter(treeElement))
-              treeElement.expand();
-          }
-        }
-      }
-    }
-    TestRunner.deprecatedRunAfterPendingDispatches(callback);
-  }
-};
-
-/**
- * @param {!Function} callback
- */
-ConsoleTestRunner.expandGettersInConsoleMessages = function(callback) {
-  const messageViews = Console.ConsoleView.instance()._visibleViewMessages;
-  const properties = [];
-  let propertiesCount = 0;
-  TestRunner.addSniffer(ObjectUI.ObjectPropertyTreeElement.prototype, '_updateExpandable', propertyExpandableUpdated);
-  for (let i = 0; i < messageViews.length; ++i) {
-    const element = messageViews[i].element();
-    for (let node = element; node; node = node.traverseNextNode(element)) {
-      if (node.classList && node.classList.contains('object-value-calculate-value-button')) {
-        ++propertiesCount;
-        node.click();
-        properties.push(node.parentElement.parentElement);
-      }
-    }
-  }
-
-  function propertyExpandableUpdated() {
-    --propertiesCount;
-    if (propertiesCount === 0) {
-      for (let i = 0; i < properties.length; ++i)
-        properties[i].click();
-      TestRunner.deprecatedRunAfterPendingDispatches(callback);
-    } else {
-      TestRunner.addSniffer(
-          ObjectUI.ObjectPropertyTreeElement.prototype, '_updateExpandable', propertyExpandableUpdated);
-    }
-  }
-};
-
-/**
- * @param {!Function} callback
- */
-ConsoleTestRunner.expandConsoleMessagesErrorParameters = function(callback) {
-  const messageViews = Console.ConsoleView.instance()._visibleViewMessages;
-  // Initiate round-trips to fetch necessary data for further rendering.
-  for (let i = 0; i < messageViews.length; ++i)
-    messageViews[i].element();
-  TestRunner.deprecatedRunAfterPendingDispatches(callback);
-};
-
-/**
- * @param {!Function} callback
- */
-ConsoleTestRunner.waitForRemoteObjectsConsoleMessages = function(callback) {
-  const messages = Console.ConsoleView.instance()._visibleViewMessages;
-  for (let i = 0; i < messages.length; ++i)
-    messages[i].toMessageElement();
-  TestRunner.deprecatedRunAfterPendingDispatches(callback);
-};
-
-/**
- * @return {!Promise}
- */
-ConsoleTestRunner.waitUntilConsoleEditorLoaded = function() {
-  let fulfill;
-  const promise = new Promise(x => (fulfill = x));
-  const prompt = Console.ConsoleView.instance()._prompt;
-  if (prompt._editor)
-    fulfill(prompt._editor);
-  else
-    TestRunner.addSniffer(Console.ConsolePrompt.prototype, '_editorSetForTest', _ => fulfill(prompt._editor));
-  return promise;
-};
-
-/**
- * @param {!Function} callback
- */
-ConsoleTestRunner.waitUntilMessageReceived = function(callback) {
-  TestRunner.addSniffer(SDK.consoleModel, 'addMessage', callback, false);
-};
-
-/**
- * @return {!Promise}
- */
-ConsoleTestRunner.waitUntilMessageReceivedPromise = function() {
-  return new Promise(fulfill => ConsoleTestRunner.waitUntilMessageReceived(fulfill));
-};
-
-/**
- * @param {number} count
- * @param {!Function} callback
- */
-ConsoleTestRunner.waitUntilNthMessageReceived = function(count, callback) {
-  function override() {
-    if (--count === 0)
-      TestRunner.safeWrap(callback)();
-    else
-      TestRunner.addSniffer(SDK.consoleModel, 'addMessage', override, false);
-  }
-  TestRunner.addSniffer(SDK.consoleModel, 'addMessage', override, false);
-};
-
-/**
- * @param {number} count
- * @return {!Promise}
- */
-ConsoleTestRunner.waitUntilNthMessageReceivedPromise = function(count) {
-  return new Promise(fulfill => ConsoleTestRunner.waitUntilNthMessageReceived(count, fulfill));
-};
-
-/**
- * @param {string} namePrefix
- */
-ConsoleTestRunner.changeExecutionContext = function(namePrefix) {
-  const selector = Console.ConsoleView.instance()._consoleContextSelector;
-  for (const executionContext of selector._items) {
-    if (selector.titleFor(executionContext).startsWith(namePrefix)) {
-      UI.context.setFlavor(SDK.ExecutionContext, executionContext);
-      return;
-    }
-  }
-  TestRunner.addResult('FAILED: context with prefix: ' + namePrefix + ' not found in the context list');
-};
-
-/**
- * @param {number} expectedCount
- * @param {!Function} callback
- */
-ConsoleTestRunner.waitForConsoleMessages = function(expectedCount, callback) {
-  const consoleView = Console.ConsoleView.instance();
-  checkAndReturn();
-
-  function checkAndReturn() {
-    if (consoleView._visibleViewMessages.length === expectedCount) {
-      TestRunner.addResult('Message count: ' + expectedCount);
-      callback();
-    } else {
-      TestRunner.addSniffer(consoleView, '_messageAppendedForTests', checkAndReturn);
-    }
-  }
-};
-
-/**
- * @param {number} expectedCount
- * @return {!Promise}
- */
-ConsoleTestRunner.waitForConsoleMessagesPromise = async function(expectedCount) {
-  await new Promise(fulfill => ConsoleTestRunner.waitForConsoleMessages(expectedCount, fulfill));
-  return ConsoleTestRunner.renderCompleteMessages();
-};
-
-/**
- * @param {number} fromMessage
- * @param {number} fromTextOffset
- * @param {number} toMessage
- * @param {number} toTextOffset
- * @suppressGlobalPropertiesCheck
- */
-ConsoleTestRunner.selectConsoleMessages = function(fromMessage, fromTextOffset, toMessage, toTextOffset) {
-  const consoleView = Console.ConsoleView.instance();
-  const from = selectionContainerAndOffset(consoleView.itemElement(fromMessage).element(), fromTextOffset);
-  const to = selectionContainerAndOffset(consoleView.itemElement(toMessage).element(), toTextOffset);
-  window.getSelection().setBaseAndExtent(from.container, from.offset, to.container, to.offset);
-
-  /**
-   * @param {!Node} container
-   * @param {number} offset
-   * @return {?{container: !Node, offset: number}}
-   */
-  function selectionContainerAndOffset(container, offset) {
-    /** @type {?Node} */
-    let node = container;
-    if (offset === 0 && container.nodeType !== Node.TEXT_NODE) {
-      container = /** @type {!Node} */ (container.traverseNextTextNode());
-      node = container;
-    }
-    let charCount = 0;
-    while ((node = node.traverseNextTextNode(container))) {
-      const length = node.textContent.length;
-      if (charCount + length >= offset)
-        return {container: node, offset: offset - charCount};
-
-      charCount += length;
-    }
-    return null;
-  }
-};
-
-/**
- * @param {!Function} override
- * @param {boolean=} opt_sticky
- */
-ConsoleTestRunner.addConsoleSniffer = function(override, opt_sticky) {
-  TestRunner.addSniffer(SDK.ConsoleModel.prototype, 'addMessage', override, opt_sticky);
-};
-
-/**
- * @param {!Function} func
- * @return {!Function}
- */
-ConsoleTestRunner.wrapListener = function(func) {
-  /**
-   * @this {*}
-   */
-  async function wrapper() {
-    await Promise.resolve();
-    func.apply(this, arguments);
-  }
-  return wrapper;
-};
-
-ConsoleTestRunner.dumpStackTraces = function() {
-  const viewMessages = Console.ConsoleView.instance()._visibleViewMessages;
-  for (let i = 0; i < viewMessages.length; ++i) {
-    const m = viewMessages[i].consoleMessage();
-    TestRunner.addResult(
-        'Message[' + i + ']: ' + Bindings.displayNameForURL(m.url || '') + ':' + m.line + ' ' + m.messageText);
-    const trace = m.stackTrace ? m.stackTrace.callFrames : null;
-    if (!trace) {
-      TestRunner.addResult('FAIL: no stack trace attached to message #' + i);
-    } else {
-      TestRunner.addResult('Stack Trace:\n');
-      TestRunner.addResult('  url: ' + trace[0].url);
-      TestRunner.addResult('  function: ' + trace[0].functionName);
-      TestRunner.addResult('  line: ' + trace[0].lineNumber);
-    }
-  }
-};
-
-/**
- * Returns actual visible indices. Messages in the margin are treated as NOT visible.
- * @return {!{first: number, last: number, count: number}}
- */
-ConsoleTestRunner.visibleIndices = function() {
-  const consoleView = Console.ConsoleView.instance();
-  const viewport = consoleView._viewport;
-  const viewportRect = viewport.element.getBoundingClientRect();
-  const viewportPadding = parseFloat(window.getComputedStyle(viewport.element).paddingTop);
-  let first = -1;
-  let last = -1;
-  let count = 0;
-  for (let i = 0; i < consoleView._visibleViewMessages.length; i++) {
-    // Created message elements may have a bounding rect, but not be connected to DOM.
-    const item = consoleView._visibleViewMessages[i];
-    if (!item._element || !item._element.isConnected)
-      continue;
-    const itemRect = item._element.getBoundingClientRect();
-    const isVisible = (itemRect.bottom > viewportRect.top + viewportPadding + 1) &&
-        (itemRect.top <= viewportRect.bottom - viewportPadding - 1);
-    if (isVisible) {
-      first = first === -1 ? i : first;
-      last = i;
-      count++;
-    }
-  }
-  return {first, last, count};
-};
diff --git a/front_end/console_test_runner/module.json b/front_end/console_test_runner/module.json
deleted file mode 100644
index 54c106b..0000000
--- a/front_end/console_test_runner/module.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "console",
-    "console_counters"
-  ],
-  "scripts": [
-    "ConsoleTestRunner.js"
-  ]
-}
\ No newline at end of file
diff --git a/front_end/cookie_table/CookiesTable.js b/front_end/cookie_table/CookiesTable.js
deleted file mode 100644
index 051561f..0000000
--- a/front_end/cookie_table/CookiesTable.js
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-CookieTable.CookiesTable = class extends UI.VBox {
-  /**
-   * @param {function(!SDK.Cookie, ?SDK.Cookie): !Promise<boolean>=} saveCallback
-   * @param {function()=} refreshCallback
-   * @param {function()=} selectedCallback
-   * @param {function(!SDK.Cookie, function())=} deleteCallback
-   */
-  constructor(saveCallback, refreshCallback, selectedCallback, deleteCallback) {
-    super();
-
-    this._saveCallback = saveCallback;
-    this._refreshCallback = refreshCallback;
-    this._deleteCallback = deleteCallback;
-
-    const editable = !!saveCallback;
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {
-        id: 'name',
-        title: Common.UIString('Name'),
-        sortable: true,
-        disclosure: editable,
-        sort: DataGrid.DataGrid.Order.Ascending,
-        longText: true,
-        weight: 24,
-        editable: editable
-      },
-      {id: 'value', title: Common.UIString('Value'), sortable: true, longText: true, weight: 34, editable: editable},
-      {id: 'domain', title: Common.UIString('Domain'), sortable: true, weight: 7, editable: editable},
-      {id: 'path', title: Common.UIString('Path'), sortable: true, weight: 7, editable: editable},
-      {id: 'expires', title: Common.UIString('Expires / Max-Age'), sortable: true, weight: 7, editable: editable},
-      {id: 'size', title: Common.UIString('Size'), sortable: true, align: DataGrid.DataGrid.Align.Right, weight: 7}, {
-        id: 'httpOnly',
-        title: Common.UIString('HTTP'),
-        sortable: true,
-        align: DataGrid.DataGrid.Align.Center,
-        weight: 7
-      },
-      {
-        id: 'secure',
-        title: Common.UIString('Secure'),
-        sortable: true,
-        align: DataGrid.DataGrid.Align.Center,
-        weight: 7
-      },
-      {
-        id: 'sameSite',
-        title: Common.UIString('SameSite'),
-        sortable: true,
-        align: DataGrid.DataGrid.Align.Center,
-        weight: 7
-      }
-    ]);
-
-    if (editable) {
-      this._dataGrid = new DataGrid.DataGrid(
-          columns, this._onUpdateCookie.bind(this), this._onDeleteCookie.bind(this), refreshCallback);
-    } else {
-      this._dataGrid = new DataGrid.DataGrid(columns);
-    }
-    this._dataGrid.setStriped(true);
-
-    this._dataGrid.setName('cookiesTable');
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._rebuildTable, this);
-
-    if (selectedCallback)
-      this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, selectedCallback, this);
-
-    /** @type {?string} */
-    this._lastEditedColumnId = null;
-
-    this._dataGrid.asWidget().show(this.element);
-    this._data = [];
-
-    /** @type {string} */
-    this._cookieDomain = '';
-  }
-
-  /**
-   * @param {!Array.<!SDK.Cookie>} cookies
-   */
-  setCookies(cookies) {
-    this.setCookieFolders([{cookies: cookies}]);
-  }
-
-  /**
-   * @param {!Array.<!{folderName: ?string, cookies: ?Array.<!SDK.Cookie>}>} cookieFolders
-   */
-  setCookieFolders(cookieFolders) {
-    this._data = cookieFolders;
-    this._rebuildTable();
-  }
-
-  /**
-   * @param {string} cookieDomain
-   */
-  setCookieDomain(cookieDomain) {
-    this._cookieDomain = cookieDomain;
-  }
-
-  /**
-   * @return {?SDK.Cookie}
-   */
-  selectedCookie() {
-    const node = this._dataGrid.selectedNode;
-    return node ? node.cookie : null;
-  }
-
-  /**
-   * @return {{current: ?SDK.Cookie, neighbor: ?SDK.Cookie}}
-   */
-  _getSelectionCookies() {
-    const node = this._dataGrid.selectedNode;
-    const nextNeighbor = node && node.traverseNextNode(true);
-    const previousNeighbor = node && node.traversePreviousNode(true);
-
-    return {
-      current: node && node.cookie,
-      neighbor: (nextNeighbor && nextNeighbor.cookie) || (previousNeighbor && previousNeighbor.cookie)
-    };
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._lastEditedColumnId = null;
-  }
-
-  /**
-   * @param {{current: ?SDK.Cookie, neighbor: ?SDK.Cookie}} selectionCookies
-   * @param {?Array<!SDK.Cookie>} cookies
-   * @return {?SDK.Cookie}
-   */
-  _findSelectedCookie(selectionCookies, cookies) {
-    if (!cookies)
-      return null;
-
-    const current = selectionCookies.current;
-    const foundCurrent = cookies.find(cookie => this._isSameCookie(cookie, current));
-    if (foundCurrent)
-      return foundCurrent;
-
-    const neighbor = selectionCookies.neighbor;
-    const foundNeighbor = cookies.find(cookie => this._isSameCookie(cookie, neighbor));
-    if (foundNeighbor)
-      return foundNeighbor;
-
-    return null;
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookieA
-   * @param {?SDK.Cookie} cookieB
-   * @return {boolean}
-   */
-  _isSameCookie(cookieA, cookieB) {
-    return !!cookieB && cookieB.name() === cookieA.name() && cookieB.domain() === cookieA.domain() &&
-        cookieB.path() === cookieA.path();
-  }
-
-  _rebuildTable() {
-    const selectionCookies = this._getSelectionCookies();
-    const lastEditedColumnId = this._lastEditedColumnId;
-    this._lastEditedColumnId = null;
-    this._dataGrid.rootNode().removeChildren();
-    for (let i = 0; i < this._data.length; ++i) {
-      const item = this._data[i];
-      const selectedCookie = this._findSelectedCookie(selectionCookies, item.cookies);
-      if (item.folderName) {
-        const groupData = {
-          name: item.folderName,
-          value: '',
-          domain: '',
-          path: '',
-          expires: '',
-          size: this._totalSize(item.cookies),
-          httpOnly: '',
-          secure: '',
-          sameSite: ''
-        };
-        const groupNode = new DataGrid.DataGridNode(groupData);
-        groupNode.selectable = true;
-        this._dataGrid.rootNode().appendChild(groupNode);
-        groupNode.element().classList.add('row-group');
-        this._populateNode(groupNode, item.cookies, selectedCookie, lastEditedColumnId);
-        groupNode.expand();
-      } else {
-        this._populateNode(this._dataGrid.rootNode(), item.cookies, selectedCookie, lastEditedColumnId);
-      }
-    }
-    if (selectionCookies.current && lastEditedColumnId && !this._dataGrid.selectedNode)
-      this._addInactiveNode(this._dataGrid.rootNode(), selectionCookies.current, lastEditedColumnId);
-    if (this._saveCallback)
-      this._dataGrid.addCreationNode(false);
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} parentNode
-   * @param {?Array.<!SDK.Cookie>} cookies
-   * @param {?SDK.Cookie} selectedCookie
-   * @param {?string} lastEditedColumnId
-   */
-  _populateNode(parentNode, cookies, selectedCookie, lastEditedColumnId) {
-    parentNode.removeChildren();
-    if (!cookies)
-      return;
-
-    this._sortCookies(cookies);
-    for (let i = 0; i < cookies.length; ++i) {
-      const cookie = cookies[i];
-      const cookieNode = this._createGridNode(cookie);
-      parentNode.appendChild(cookieNode);
-      if (this._isSameCookie(cookie, selectedCookie)) {
-        cookieNode.select();
-        if (lastEditedColumnId !== null)
-          this._dataGrid.startEditingNextEditableColumnOfDataGridNode(cookieNode, lastEditedColumnId);
-      }
-    }
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} parentNode
-   * @param {!SDK.Cookie} cookie
-   * @param {?string} editedColumnId
-   */
-  _addInactiveNode(parentNode, cookie, editedColumnId) {
-    const cookieNode = this._createGridNode(cookie);
-    parentNode.appendChild(cookieNode);
-    cookieNode.select();
-    cookieNode.setInactive(true);
-    if (editedColumnId !== null)
-      this._dataGrid.startEditingNextEditableColumnOfDataGridNode(cookieNode, editedColumnId);
-  }
-
-  _totalSize(cookies) {
-    let totalSize = 0;
-    for (let i = 0; cookies && i < cookies.length; ++i)
-      totalSize += cookies[i].size();
-    return totalSize;
-  }
-
-  /**
-   * @param {!Array.<!SDK.Cookie>} cookies
-   */
-  _sortCookies(cookies) {
-    const sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;
-
-    /**
-     * @param {!SDK.Cookie} cookie
-     * @param {string} property
-     * @return {string}
-     */
-    function getValue(cookie, property) {
-      return typeof cookie[property] === 'function' ? String(cookie[property]()) : String(cookie.name());
-    }
-
-    /**
-     * @param {string} property
-     * @param {!SDK.Cookie} cookie1
-     * @param {!SDK.Cookie} cookie2
-     */
-    function compareTo(property, cookie1, cookie2) {
-      return sortDirection * getValue(cookie1, property).compareTo(getValue(cookie2, property));
-    }
-
-    /**
-     * @param {!SDK.Cookie} cookie1
-     * @param {!SDK.Cookie} cookie2
-     */
-    function numberCompare(cookie1, cookie2) {
-      return sortDirection * (cookie1.size() - cookie2.size());
-    }
-
-    /**
-     * @param {!SDK.Cookie} cookie1
-     * @param {!SDK.Cookie} cookie2
-     */
-    function expiresCompare(cookie1, cookie2) {
-      if (cookie1.session() !== cookie2.session())
-        return sortDirection * (cookie1.session() ? 1 : -1);
-
-      if (cookie1.session())
-        return 0;
-
-      if (cookie1.maxAge() && cookie2.maxAge())
-        return sortDirection * (cookie1.maxAge() - cookie2.maxAge());
-      if (cookie1.expires() && cookie2.expires())
-        return sortDirection * (cookie1.expires() - cookie2.expires());
-      return sortDirection * (cookie1.expires() ? 1 : -1);
-    }
-
-    let comparator;
-    const columnId = this._dataGrid.sortColumnId() || 'name';
-    if (columnId === 'expires')
-      comparator = expiresCompare;
-    else if (columnId === 'size')
-      comparator = numberCompare;
-    else
-      comparator = compareTo.bind(null, columnId);
-    cookies.sort(comparator);
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookie
-   * @return {!DataGrid.DataGridNode}
-   */
-  _createGridNode(cookie) {
-    const data = {};
-    data.name = cookie.name();
-    data.value = cookie.value();
-    if (cookie.type() === SDK.Cookie.Type.Request) {
-      data.domain = Common.UIString('N/A');
-      data.path = Common.UIString('N/A');
-      data.expires = Common.UIString('N/A');
-    } else {
-      data.domain = cookie.domain() || '';
-      data.path = cookie.path() || '';
-      if (cookie.maxAge())
-        data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
-      else if (cookie.expires())
-        data.expires = new Date(cookie.expires()).toISOString();
-      else
-        data.expires = CookieTable.CookiesTable._expiresSessionValue;
-    }
-    data.size = cookie.size();
-    const checkmark = '\u2713';
-    data.httpOnly = (cookie.httpOnly() ? checkmark : '');
-    data.secure = (cookie.secure() ? checkmark : '');
-    data.sameSite = cookie.sameSite() || '';
-
-    const node = new DataGrid.DataGridNode(data);
-    node.cookie = cookie;
-    node.selectable = true;
-    return node;
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} node
-   */
-  _onDeleteCookie(node) {
-    if (node.cookie && this._deleteCallback)
-      this._deleteCallback(node.cookie, () => this._refresh());
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} editingNode
-   * @param {string} columnIdentifier
-   * @param {string} oldText
-   * @param {string} newText
-   */
-  _onUpdateCookie(editingNode, columnIdentifier, oldText, newText) {
-    this._lastEditedColumnId = columnIdentifier;
-    this._setDefaults(editingNode);
-    if (this._isValidCookieData(editingNode.data))
-      this._saveNode(editingNode);
-    else
-      editingNode.setDirty(true);
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} node
-   */
-  _setDefaults(node) {
-    if (node.data.name === null)
-      node.data.name = '';
-    if (node.data.value === null)
-      node.data.value = '';
-    if (node.data.domain === null)
-      node.data.domain = this._cookieDomain;
-    if (node.data.path === null)
-      node.data.path = '/';
-    if (node.data.expires === null)
-      node.data.expires = CookieTable.CookiesTable._expiresSessionValue;
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} node
-   */
-  _saveNode(node) {
-    const oldCookie = node.cookie;
-    const newCookie = this._createCookieFromData(node.data);
-    node.cookie = newCookie;
-    this._saveCallback(newCookie, oldCookie).then(success => {
-      if (success)
-        this._refresh();
-      else
-        node.setDirty(true);
-    });
-  }
-
-  /**
-   * @param {!Object.<string, *>} data
-   * @returns {!SDK.Cookie}
-   */
-  _createCookieFromData(data) {
-    const cookie = new SDK.Cookie(data.name, data.value, null);
-    cookie.addAttribute('domain', data.domain);
-    cookie.addAttribute('path', data.path);
-    if (data.expires && data.expires !== CookieTable.CookiesTable._expiresSessionValue)
-      cookie.addAttribute('expires', (new Date(data.expires)).toUTCString());
-    if (data.httpOnly)
-      cookie.addAttribute('httpOnly');
-    if (data.secure)
-      cookie.addAttribute('secure');
-    if (data.sameSite)
-      cookie.addAttribute('sameSite', data.sameSite);
-    cookie.setSize(data.name.length + data.value.length);
-    return cookie;
-  }
-
-  /**
-   * @param {!Object.<string, *>} data
-   * @returns {boolean}
-   */
-  _isValidCookieData(data) {
-    return (data.name || data.value) && this._isValidDomain(data.domain) && this._isValidPath(data.path) &&
-        this._isValidDate(data.expires);
-  }
-
-  /**
-   * @param {string} domain
-   * @returns {boolean}
-   */
-  _isValidDomain(domain) {
-    if (!domain)
-      return true;
-    const parsedURL = ('http://' + domain).asParsedURL();
-    return !!parsedURL && parsedURL.domain() === domain;
-  }
-
-  /**
-   * @param {string} path
-   * @returns {boolean}
-   */
-  _isValidPath(path) {
-    const parsedURL = ('http://example.com' + path).asParsedURL();
-    return !!parsedURL && parsedURL.path === path;
-  }
-
-  /**
-   * @param {string} date
-   * @returns {boolean}
-   */
-  _isValidDate(date) {
-    return date === '' || date === CookieTable.CookiesTable._expiresSessionValue || !isNaN(Date.parse(date));
-  }
-
-  _refresh() {
-    if (this._refreshCallback)
-      this._refreshCallback();
-  }
-};
-
-/** @const */
-CookieTable.CookiesTable._expiresSessionValue = Common.UIString('Session');
diff --git a/front_end/cookie_table/module.json b/front_end/cookie_table/module.json
deleted file mode 100644
index e3e7a3b..0000000
--- a/front_end/cookie_table/module.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "dependencies": [
-        "ui",
-        "sdk",
-        "data_grid"
-    ],
-    "scripts": [
-        "CookiesTable.js"
-    ]
-}
diff --git a/front_end/coverage/CoverageDecorationManager.js b/front_end/coverage/CoverageDecorationManager.js
deleted file mode 100644
index aec0f90..0000000
--- a/front_end/coverage/CoverageDecorationManager.js
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @typedef {!{
- *    id: string,
- *    contentProvider: !Common.ContentProvider,
- *    line: number,
- *    column: number
- * }}
- */
-Coverage.RawLocation;
-
-Coverage.CoverageDecorationManager = class {
-  /**
-   * @param {!Coverage.CoverageModel} coverageModel
-   */
-  constructor(coverageModel) {
-    this._coverageModel = coverageModel;
-    /** @type {!Map<!Common.ContentProvider, ?TextUtils.Text>} */
-    this._textByProvider = new Map();
-    /** @type {!Multimap<!Common.ContentProvider, !Workspace.UISourceCode>} */
-    this._uiSourceCodeByContentProvider = new Multimap();
-    // TODO(crbug.com/720162): get rid of this, use bindings.
-    /** @type {!WeakMap<!Workspace.UISourceCode, !Array<!SDK.CSSStyleSheetHeader>>} */
-    this._documentUISouceCodeToStylesheets = new WeakMap();
-
-    for (const uiSourceCode of Workspace.workspace.uiSourceCodes())
-      uiSourceCode.addLineDecoration(0, Coverage.CoverageDecorationManager._decoratorType, this);
-    Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._onUISourceCodeAdded, this);
-  }
-
-  reset() {
-    for (const uiSourceCode of Workspace.workspace.uiSourceCodes())
-      uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager._decoratorType);
-  }
-
-  dispose() {
-    this.reset();
-    Workspace.workspace.removeEventListener(
-        Workspace.Workspace.Events.UISourceCodeAdded, this._onUISourceCodeAdded, this);
-  }
-
-  /**
-   * @param {!Array<!Coverage.CoverageInfo>} updatedEntries
-   */
-  update(updatedEntries) {
-    for (const entry of updatedEntries) {
-      for (const uiSourceCode of this._uiSourceCodeByContentProvider.get(entry.contentProvider())) {
-        uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager._decoratorType);
-        uiSourceCode.addLineDecoration(0, Coverage.CoverageDecorationManager._decoratorType, this);
-      }
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<!Array<boolean>>}
-   */
-  async usageByLine(uiSourceCode) {
-    const result = [];
-    const sourceText = new TextUtils.Text(uiSourceCode.content() || '');
-    await this._updateTexts(uiSourceCode, sourceText);
-    const lineEndings = sourceText.lineEndings();
-    for (let line = 0; line < sourceText.lineCount(); ++line) {
-      const lineLength = lineEndings[line] - (line ? lineEndings[line - 1] : 0) - 1;
-      if (!lineLength) {
-        result.push(undefined);
-        continue;
-      }
-      const startLocations = this._rawLocationsForSourceLocation(uiSourceCode, line, 0);
-      const endLocations = this._rawLocationsForSourceLocation(uiSourceCode, line, lineLength);
-      let used = undefined;
-      for (let startIndex = 0, endIndex = 0; startIndex < startLocations.length; ++startIndex) {
-        const start = startLocations[startIndex];
-        while (endIndex < endLocations.length &&
-               Coverage.CoverageDecorationManager._compareLocations(start, endLocations[endIndex]) >= 0)
-          ++endIndex;
-        if (endIndex >= endLocations.length || endLocations[endIndex].id !== start.id)
-          continue;
-        const end = endLocations[endIndex++];
-        const text = this._textByProvider.get(end.contentProvider);
-        if (!text)
-          continue;
-        const textValue = text.value();
-        let startOffset = Math.min(text.offsetFromPosition(start.line, start.column), textValue.length - 1);
-        let endOffset = Math.min(text.offsetFromPosition(end.line, end.column), textValue.length - 1);
-        while (startOffset <= endOffset && /\s/.test(textValue[startOffset]))
-          ++startOffset;
-        while (startOffset <= endOffset && /\s/.test(textValue[endOffset]))
-          --endOffset;
-        if (startOffset <= endOffset)
-          used = this._coverageModel.usageForRange(end.contentProvider, startOffset, endOffset);
-        if (used)
-          break;
-      }
-      result.push(used);
-    }
-    return result;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!TextUtils.Text} text
-   * @return {!Promise}
-   */
-  _updateTexts(uiSourceCode, text) {
-    const promises = [];
-    for (let line = 0; line < text.lineCount(); ++line) {
-      for (const entry of this._rawLocationsForSourceLocation(uiSourceCode, line, 0)) {
-        if (this._textByProvider.has(entry.contentProvider))
-          continue;
-        this._textByProvider.set(entry.contentProvider, null);
-        this._uiSourceCodeByContentProvider.set(entry.contentProvider, uiSourceCode);
-        promises.push(this._updateTextForProvider(entry.contentProvider));
-      }
-    }
-    return Promise.all(promises);
-  }
-
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   * @return {!Promise}
-   */
-  async _updateTextForProvider(contentProvider) {
-    const content = await contentProvider.requestContent();
-    this._textByProvider.set(contentProvider, new TextUtils.Text(content));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} line
-   * @param {number} column
-   * @return {!Array<!Coverage.RawLocation>}
-   */
-  _rawLocationsForSourceLocation(uiSourceCode, line, column) {
-    const result = [];
-    const contentType = uiSourceCode.contentType();
-    if (contentType.hasScripts()) {
-      let location = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, line, column);
-      if (location && location.script()) {
-        const script = location.script();
-        if (script.isInlineScript() && contentType.isDocument()) {
-          if (comparePositions(script.lineOffset, script.columnOffset, location.lineNumber, location.columnNumber) >
-                  0 ||
-              comparePositions(script.endLine, script.endColumn, location.lineNumber, location.columnNumber) <= 0) {
-            location = null;
-          } else {
-            location.lineNumber -= script.lineOffset;
-            if (!location.lineNumber)
-              location.columnNumber -= script.columnOffset;
-          }
-        }
-        if (location) {
-          result.push({
-            id: `js:${location.scriptId}`,
-            contentProvider: location.script(),
-            line: location.lineNumber,
-            column: location.columnNumber
-          });
-        }
-      }
-    }
-    if (contentType.isStyleSheet() || contentType.isDocument()) {
-      const rawStyleLocations = contentType.isDocument() ?
-          this._documentUILocationToCSSRawLocations(uiSourceCode, line, column) :
-          Bindings.cssWorkspaceBinding.uiLocationToRawLocations(new Workspace.UILocation(uiSourceCode, line, column));
-      for (const location of rawStyleLocations) {
-        const header = location.header();
-        if (!header)
-          continue;
-        if (header.isInline && contentType.isDocument()) {
-          location.lineNumber -= header.startLine;
-          if (!location.lineNumber)
-            location.columnNumber -= header.startColumn;
-        }
-        result.push({
-          id: `css:${location.styleSheetId}`,
-          contentProvider: location.header(),
-          line: location.lineNumber,
-          column: location.columnNumber
-        });
-      }
-    }
-    result.sort(Coverage.CoverageDecorationManager._compareLocations);
-
-    /**
-     * @param {number} aLine
-     * @param {number} aColumn
-     * @param {number} bLine
-     * @param {number} bColumn
-     * @return {number}
-     */
-    function comparePositions(aLine, aColumn, bLine, bColumn) {
-      return aLine - bLine || aColumn - bColumn;
-    }
-    return result;
-  }
-
-  /**
-   * TODO(crbug.com/720162): get rid of this, use bindings.
-   *
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} line
-   * @param {number} column
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  _documentUILocationToCSSRawLocations(uiSourceCode, line, column) {
-    let stylesheets = this._documentUISouceCodeToStylesheets.get(uiSourceCode);
-    if (!stylesheets) {
-      stylesheets = [];
-      const cssModel = this._coverageModel.target().model(SDK.CSSModel);
-      if (!cssModel)
-        return [];
-      for (const headerId of cssModel.styleSheetIdsForURL(uiSourceCode.url())) {
-        const header = cssModel.styleSheetHeaderForId(headerId);
-        if (header)
-          stylesheets.push(header);
-      }
-      stylesheets.sort(stylesheetComparator);
-      this._documentUISouceCodeToStylesheets.set(uiSourceCode, stylesheets);
-    }
-    const endIndex =
-        stylesheets.upperBound(undefined, (unused, header) => line - header.startLine || column - header.startColumn);
-    if (!endIndex)
-      return [];
-    const locations = [];
-    const last = stylesheets[endIndex - 1];
-    for (let index = endIndex - 1; index >= 0 && stylesheets[index].startLine === last.startLine &&
-         stylesheets[index].startColumn === last.startColumn;
-         --index)
-      locations.push(new SDK.CSSLocation(stylesheets[index], line, column));
-
-    return locations;
-    /**
-     * @param {!SDK.CSSStyleSheetHeader} a
-     * @param {!SDK.CSSStyleSheetHeader} b
-     * @return {number}
-     */
-    function stylesheetComparator(a, b) {
-      return a.startLine - b.startLine || a.startColumn - b.startColumn || a.id.localeCompare(b.id);
-    }
-  }
-
-  /**
-   * @param {!Coverage.RawLocation} a
-   * @param {!Coverage.RawLocation} b
-   */
-  static _compareLocations(a, b) {
-    return a.id.localeCompare(b.id) || a.line - b.line || a.column - b.column;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onUISourceCodeAdded(event) {
-    const uiSourceCode = /** @type !Workspace.UISourceCode */ (event.data);
-    uiSourceCode.addLineDecoration(0, Coverage.CoverageDecorationManager._decoratorType, this);
-  }
-};
-
-Coverage.CoverageDecorationManager._decoratorType = 'coverage';
-
-/**
- * @implements {SourceFrame.LineDecorator}
- */
-Coverage.CoverageView.LineDecorator = class {
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   */
-  decorate(uiSourceCode, textEditor) {
-    const decorations = uiSourceCode.decorationsForType(Coverage.CoverageDecorationManager._decoratorType);
-    if (!decorations || !decorations.size) {
-      textEditor.uninstallGutter(Coverage.CoverageView.LineDecorator._gutterType);
-      return;
-    }
-    const decorationManager =
-        /** @type {!Coverage.CoverageDecorationManager} */ (decorations.values().next().value.data());
-    decorationManager.usageByLine(uiSourceCode).then(lineUsage => {
-      textEditor.operation(() => this._innerDecorate(textEditor, lineUsage));
-    });
-  }
-
-  /**
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   * @param {!Array<boolean>} lineUsage
-   */
-  _innerDecorate(textEditor, lineUsage) {
-    const gutterType = Coverage.CoverageView.LineDecorator._gutterType;
-    textEditor.uninstallGutter(gutterType);
-    textEditor.installGutter(gutterType, false);
-    for (let line = 0; line < lineUsage.length; ++line) {
-      // Do not decorate the line if we don't have data.
-      if (typeof lineUsage[line] !== 'boolean')
-        continue;
-      const className = lineUsage[line] ? 'text-editor-coverage-used-marker' : 'text-editor-coverage-unused-marker';
-      textEditor.setGutterDecoration(line, gutterType, createElementWithClass('div', className));
-    }
-  }
-};
-
-Coverage.CoverageView.LineDecorator._gutterType = 'CodeMirror-gutter-coverage';
\ No newline at end of file
diff --git a/front_end/coverage/CoverageListView.js b/front_end/coverage/CoverageListView.js
deleted file mode 100644
index c3ed61c..0000000
--- a/front_end/coverage/CoverageListView.js
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Coverage.CoverageListView = class extends UI.VBox {
-  /**
-   * @param {function(!Coverage.URLCoverageInfo):boolean} filterCallback
-   */
-  constructor(filterCallback) {
-    super(true);
-    /** @type {!Map<!Coverage.URLCoverageInfo, !Coverage.CoverageListView.GridNode>} */
-    this._nodeForCoverageInfo = new Map();
-    this._filterCallback = filterCallback;
-    /** @type {?RegExp} */
-    this._highlightRegExp = null;
-    this.registerRequiredCSS('coverage/coverageListView.css');
-    const columns = [
-      {id: 'url', title: Common.UIString('URL'), width: '250px', fixedWidth: false, sortable: true},
-      {id: 'type', title: Common.UIString('Type'), width: '45px', fixedWidth: true, sortable: true}, {
-        id: 'size',
-        title: Common.UIString('Total Bytes'),
-        width: '60px',
-        fixedWidth: true,
-        sortable: true,
-        align: DataGrid.DataGrid.Align.Right
-      },
-      {
-        id: 'unusedSize',
-        title: Common.UIString('Unused Bytes'),
-        width: '100px',
-        fixedWidth: true,
-        sortable: true,
-        align: DataGrid.DataGrid.Align.Right,
-        sort: DataGrid.DataGrid.Order.Descending
-      },
-      {id: 'bars', title: '', width: '250px', fixedWidth: false, sortable: true}
-    ];
-    this._dataGrid = new DataGrid.SortableDataGrid(columns);
-    this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
-    this._dataGrid.element.classList.add('flex-auto');
-    this._dataGrid.element.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.OpenedNode, this._onOpenedNode, this);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortingChanged, this);
-
-    const dataGridWidget = this._dataGrid.asWidget();
-    dataGridWidget.show(this.contentElement);
-  }
-
-  /**
-   * @param {!Array<!Coverage.URLCoverageInfo>} coverageInfo
-   */
-  update(coverageInfo) {
-    let hadUpdates = false;
-    const maxSize = coverageInfo.reduce((acc, entry) => Math.max(acc, entry.size()), 0);
-    const rootNode = this._dataGrid.rootNode();
-    for (const entry of coverageInfo) {
-      let node = this._nodeForCoverageInfo.get(entry);
-      if (node) {
-        if (this._filterCallback(node._coverageInfo))
-          hadUpdates = node._refreshIfNeeded(maxSize) || hadUpdates;
-        continue;
-      }
-      node = new Coverage.CoverageListView.GridNode(entry, maxSize);
-      this._nodeForCoverageInfo.set(entry, node);
-      if (this._filterCallback(node._coverageInfo)) {
-        rootNode.appendChild(node);
-        hadUpdates = true;
-      }
-    }
-    if (hadUpdates)
-      this._sortingChanged();
-  }
-
-  reset() {
-    this._nodeForCoverageInfo.clear();
-    this._dataGrid.rootNode().removeChildren();
-  }
-
-  /**
-   * @param {?RegExp} highlightRegExp
-   */
-  updateFilterAndHighlight(highlightRegExp) {
-    this._highlightRegExp = highlightRegExp;
-    let hadTreeUpdates = false;
-    for (const node of this._nodeForCoverageInfo.values()) {
-      const shouldBeVisible = this._filterCallback(node._coverageInfo);
-      const isVisible = !!node.parent;
-      if (shouldBeVisible)
-        node._setHighlight(this._highlightRegExp);
-      if (shouldBeVisible === isVisible)
-        continue;
-      hadTreeUpdates = true;
-      if (!shouldBeVisible)
-        node.remove();
-      else
-        this._dataGrid.rootNode().appendChild(node);
-    }
-    if (hadTreeUpdates)
-      this._sortingChanged();
-  }
-
-  _onOpenedNode() {
-    this._revealSourceForSelectedNode();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (!isEnterKey(event))
-      return;
-    event.consume(true);
-    this._revealSourceForSelectedNode();
-  }
-
-  async _revealSourceForSelectedNode() {
-    const node = this._dataGrid.selectedNode;
-    if (!node)
-      return;
-    const coverageInfo = /** @type {!Coverage.CoverageListView.GridNode} */ (node)._coverageInfo;
-    let sourceCode = Workspace.workspace.uiSourceCodeForURL(coverageInfo.url());
-    if (!sourceCode)
-      return;
-    const content = await sourceCode.requestContent();
-    if (TextUtils.isMinified(content)) {
-      const formatData = await Sources.sourceFormatter.format(sourceCode);
-      // ------------ ASYNC ------------
-      sourceCode = formatData.formattedSourceCode;
-    }
-    if (this._dataGrid.selectedNode !== node)
-      return;
-    Common.Revealer.reveal(sourceCode);
-  }
-
-  _sortingChanged() {
-    const columnId = this._dataGrid.sortColumnId();
-    if (!columnId)
-      return;
-    let sortFunction;
-    switch (columnId) {
-      case 'url':
-        sortFunction = compareURL;
-        break;
-      case 'type':
-        sortFunction = compareType;
-        break;
-      case 'size':
-        sortFunction = compareNumericField.bind(null, 'size');
-        break;
-      case 'bars':
-      case 'unusedSize':
-        sortFunction = compareNumericField.bind(null, 'unusedSize');
-        break;
-      default:
-        console.assert(false, 'Unknown sort field: ' + columnId);
-        return;
-    }
-
-    this._dataGrid.sortNodes(sortFunction, !this._dataGrid.isSortOrderAscending());
-
-    /**
-     * @param {!DataGrid.DataGridNode} a
-     * @param {!DataGrid.DataGridNode} b
-     * @return {number}
-     */
-    function compareURL(a, b) {
-      const nodeA = /** @type {!Coverage.CoverageListView.GridNode} */ (a);
-      const nodeB = /** @type {!Coverage.CoverageListView.GridNode} */ (b);
-
-      return nodeA._url.localeCompare(nodeB._url);
-    }
-
-    /**
-     * @param {string} fieldName
-     * @param {!DataGrid.DataGridNode} a
-     * @param {!DataGrid.DataGridNode} b
-     * @return {number}
-     */
-    function compareNumericField(fieldName, a, b) {
-      const nodeA = /** @type {!Coverage.CoverageListView.GridNode} */ (a);
-      const nodeB = /** @type {!Coverage.CoverageListView.GridNode} */ (b);
-
-      return nodeA._coverageInfo[fieldName]() - nodeB._coverageInfo[fieldName]() || compareURL(a, b);
-    }
-
-    /**
-     * @param {!DataGrid.DataGridNode} a
-     * @param {!DataGrid.DataGridNode} b
-     * @return {number}
-     */
-    function compareType(a, b) {
-      const nodeA = /** @type {!Coverage.CoverageListView.GridNode} */ (a);
-      const nodeB = /** @type {!Coverage.CoverageListView.GridNode} */ (b);
-      const typeA = Coverage.CoverageListView._typeToString(nodeA._coverageInfo.type());
-      const typeB = Coverage.CoverageListView._typeToString(nodeB._coverageInfo.type());
-      return typeA.localeCompare(typeB) || compareURL(a, b);
-    }
-  }
-
-  /**
-   * @param {!Coverage.CoverageType} type
-   */
-  static _typeToString(type) {
-    const types = [];
-    if (type & Coverage.CoverageType.CSS)
-      types.push(Common.UIString('CSS'));
-    if (type & Coverage.CoverageType.JavaScriptCoarse)
-      types.push(Common.UIString('JS (coarse)'));
-    else if (type & Coverage.CoverageType.JavaScript)
-      types.push(Common.UIString('JS'));
-    return types.join('+');
-  }
-};
-
-Coverage.CoverageListView.GridNode = class extends DataGrid.SortableDataGridNode {
-  /**
-   * @param {!Coverage.URLCoverageInfo} coverageInfo
-   * @param {number} maxSize
-   */
-  constructor(coverageInfo, maxSize) {
-    super();
-    this._coverageInfo = coverageInfo;
-    /** @type {number|undefined} */
-    this._lastUsedSize;
-    this._url = coverageInfo.url();
-    this._maxSize = maxSize;
-    this._highlightDOMChanges = [];
-    /** @type {?RegExp} */
-    this._highlightRegExp = null;
-  }
-
-  /**
-   * @param {?RegExp} highlightRegExp
-   */
-  _setHighlight(highlightRegExp) {
-    if (this._highlightRegExp === highlightRegExp)
-      return;
-    this._highlightRegExp = highlightRegExp;
-    this.refresh();
-  }
-
-  /**
-   * @param {number} maxSize
-   * @return {boolean}
-   */
-  _refreshIfNeeded(maxSize) {
-    if (this._lastUsedSize === this._coverageInfo.usedSize() && maxSize === this._maxSize)
-      return false;
-    this._lastUsedSize = this._coverageInfo.usedSize();
-    this._maxSize = maxSize;
-    this.refresh();
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = this.createTD(columnId);
-    switch (columnId) {
-      case 'url':
-        cell.title = this._url;
-        const outer = cell.createChild('div', 'url-outer');
-        const prefix = outer.createChild('div', 'url-prefix');
-        const suffix = outer.createChild('div', 'url-suffix');
-        const splitURL = /^(.*)(\/[^/]*)$/.exec(this._url);
-        prefix.textContent = splitURL ? splitURL[1] : this._url;
-        suffix.textContent = splitURL ? splitURL[2] : '';
-        if (this._highlightRegExp)
-          this._highlight(outer, this._url);
-        break;
-      case 'type':
-        cell.textContent = Coverage.CoverageListView._typeToString(this._coverageInfo.type());
-        if (this._coverageInfo.type() & Coverage.CoverageType.JavaScriptCoarse)
-          cell.title = Common.UIString('JS coverage is function-level only. Reload the page for block-level coverage.');
-        break;
-      case 'size':
-        cell.textContent = Number.withThousandsSeparator(this._coverageInfo.size() || 0);
-        break;
-      case 'unusedSize':
-        const unusedSize = this._coverageInfo.unusedSize() || 0;
-        const unusedSizeSpan = cell.createChild('span');
-        const unusedPercentsSpan = cell.createChild('span', 'percent-value');
-        unusedSizeSpan.textContent = Number.withThousandsSeparator(unusedSize);
-        unusedPercentsSpan.textContent = Common.UIString('%.1f\xa0%%', unusedSize / this._coverageInfo.size() * 100);
-        break;
-      case 'bars':
-        const barContainer = cell.createChild('div', 'bar-container');
-        const unusedSizeBar = barContainer.createChild('div', 'bar bar-unused-size');
-        unusedSizeBar.style.width = (100 * this._coverageInfo.unusedSize() / this._maxSize).toFixed(4) + '%';
-        const usedSizeBar = barContainer.createChild('div', 'bar bar-used-size');
-        usedSizeBar.style.width = (100 * this._coverageInfo.usedSize() / this._maxSize).toFixed(4) + '%';
-    }
-    return cell;
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} textContent
-   */
-  _highlight(element, textContent) {
-    const matches = this._highlightRegExp.exec(textContent);
-    if (!matches || !matches.length)
-      return;
-    const range = new TextUtils.SourceRange(matches.index, matches[0].length);
-    UI.highlightRangesWithStyleClass(element, [range], 'filter-highlight');
-  }
-};
diff --git a/front_end/coverage/CoverageModel.js b/front_end/coverage/CoverageModel.js
deleted file mode 100644
index ff58087..0000000
--- a/front_end/coverage/CoverageModel.js
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/** @typedef {{startOffset: number, endOffset: number, count: number}} */
-Coverage.RangeUseCount;
-
-/** @typedef {{end: number, count: (number|undefined)}} */
-Coverage.CoverageSegment;
-
-/**
- * @enum {number}
- */
-Coverage.CoverageType = {
-  CSS: (1 << 0),
-  JavaScript: (1 << 1),
-  JavaScriptCoarse: (1 << 2),
-};
-
-Coverage.CoverageModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._cpuProfilerModel = target.model(SDK.CPUProfilerModel);
-    this._cssModel = target.model(SDK.CSSModel);
-    this._debuggerModel = target.model(SDK.DebuggerModel);
-
-    /** @type {!Map<string, !Coverage.URLCoverageInfo>} */
-    this._coverageByURL = new Map();
-    /** @type {!Map<!Common.ContentProvider, !Coverage.CoverageInfo>} */
-    this._coverageByContentProvider = new Map();
-    /** @type {?Promise<!Array<!Protocol.Profiler.ScriptCoverage>>} */
-    this._bestEffortCoveragePromise = null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  start() {
-    if (this._cssModel) {
-      // Note there's no JS coverage since JS won't ever return
-      // coverage twice, even after it's restarted.
-      this._clearCSS();
-      this._cssModel.startCoverage();
-    }
-    if (this._cpuProfilerModel) {
-      this._bestEffortCoveragePromise = this._cpuProfilerModel.bestEffortCoverage();
-      this._cpuProfilerModel.startPreciseCoverage();
-    }
-    return !!(this._cssModel || this._cpuProfilerModel);
-  }
-
-  /**
-   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
-   */
-  stop() {
-    const pollPromise = this.poll();
-    if (this._cpuProfilerModel)
-      this._cpuProfilerModel.stopPreciseCoverage();
-    if (this._cssModel)
-      this._cssModel.stopCoverage();
-    return pollPromise;
-  }
-
-  reset() {
-    this._coverageByURL = new Map();
-    this._coverageByContentProvider = new Map();
-  }
-
-  /**
-   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
-   */
-  async poll() {
-    const updates = await Promise.all([this._takeCSSCoverage(), this._takeJSCoverage()]);
-    return updates[0].concat(updates[1]);
-  }
-
-  /**
-   * @return {!Array<!Coverage.URLCoverageInfo>}
-   */
-  entries() {
-    return Array.from(this._coverageByURL.values());
-  }
-
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {number} startOffset
-   * @param {number} endOffset
-   * @return {boolean|undefined}
-   */
-  usageForRange(contentProvider, startOffset, endOffset) {
-    const coverageInfo = this._coverageByContentProvider.get(contentProvider);
-    return coverageInfo && coverageInfo.usageForRange(startOffset, endOffset);
-  }
-
-  _clearCSS() {
-    for (const entry of this._coverageByContentProvider.values()) {
-      if (entry.type() !== Coverage.CoverageType.CSS)
-        continue;
-      const contentProvider = /** @type {!SDK.CSSStyleSheetHeader} */ (entry.contentProvider());
-      this._coverageByContentProvider.delete(contentProvider);
-      const key = `${contentProvider.startLine}:${contentProvider.startColumn}`;
-      const urlEntry = this._coverageByURL.get(entry.url());
-      if (!urlEntry || !urlEntry._coverageInfoByLocation.delete(key))
-        continue;
-      urlEntry._size -= entry._size;
-      urlEntry._usedSize -= entry._usedSize;
-      if (!urlEntry._coverageInfoByLocation.size)
-        this._coverageByURL.delete(entry.url());
-    }
-  }
-
-  /**
-   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
-   */
-  async _takeJSCoverage() {
-    if (!this._cpuProfilerModel)
-      return [];
-    let rawCoverageData = await this._cpuProfilerModel.takePreciseCoverage();
-    if (this._bestEffortCoveragePromise) {
-      const bestEffortCoverage = await this._bestEffortCoveragePromise;
-      this._bestEffortCoveragePromise = null;
-      rawCoverageData = bestEffortCoverage.concat(rawCoverageData);
-    }
-    return this._processJSCoverage(rawCoverageData);
-  }
-
-  /**
-   * @param {!Array<!Protocol.Profiler.ScriptCoverage>} scriptsCoverage
-   * @return {!Array<!Coverage.CoverageInfo>}
-   */
-  _processJSCoverage(scriptsCoverage) {
-    const updatedEntries = [];
-    for (const entry of scriptsCoverage) {
-      const script = this._debuggerModel.scriptForId(entry.scriptId);
-      if (!script)
-        continue;
-      const ranges = [];
-      let type = Coverage.CoverageType.JavaScript;
-      for (const func of entry.functions) {
-        // Do not coerce undefined to false, i.e. only consider blockLevel to be false
-        // if back-end explicitly provides blockLevel field, otherwise presume blockLevel
-        // coverage is not available. Also, ignore non-block level functions that weren't
-        // ever called.
-        if (func.isBlockCoverage === false && !(func.ranges.length === 1 && !func.ranges[0].count))
-          type |= Coverage.CoverageType.JavaScriptCoarse;
-        for (const range of func.ranges)
-          ranges.push(range);
-      }
-      const subentry =
-          this._addCoverage(script, script.contentLength, script.lineOffset, script.columnOffset, ranges, type);
-      if (subentry)
-        updatedEntries.push(subentry);
-    }
-    return updatedEntries;
-  }
-
-  /**
-   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
-   */
-  async _takeCSSCoverage() {
-    if (!this._cssModel)
-      return [];
-    const rawCoverageData = await this._cssModel.takeCoverageDelta();
-    return this._processCSSCoverage(rawCoverageData);
-  }
-
-  /**
-   * @param {!Array<!Protocol.CSS.RuleUsage>} ruleUsageList
-   * @return {!Array<!Coverage.CoverageInfo>}
-   */
-  _processCSSCoverage(ruleUsageList) {
-    const updatedEntries = [];
-    /** @type {!Map<!SDK.CSSStyleSheetHeader, !Array<!Coverage.RangeUseCount>>} */
-    const rulesByStyleSheet = new Map();
-    for (const rule of ruleUsageList) {
-      const styleSheetHeader = this._cssModel.styleSheetHeaderForId(rule.styleSheetId);
-      if (!styleSheetHeader)
-        continue;
-      let ranges = rulesByStyleSheet.get(styleSheetHeader);
-      if (!ranges) {
-        ranges = [];
-        rulesByStyleSheet.set(styleSheetHeader, ranges);
-      }
-      ranges.push({startOffset: rule.startOffset, endOffset: rule.endOffset, count: Number(rule.used)});
-    }
-    for (const entry of rulesByStyleSheet) {
-      const styleSheetHeader = /** @type {!SDK.CSSStyleSheetHeader} */ (entry[0]);
-      const ranges = /** @type {!Array<!Coverage.RangeUseCount>} */ (entry[1]);
-      const subentry = this._addCoverage(
-          styleSheetHeader, styleSheetHeader.contentLength, styleSheetHeader.startLine, styleSheetHeader.startColumn,
-          ranges, Coverage.CoverageType.CSS);
-      if (subentry)
-        updatedEntries.push(subentry);
-    }
-    return updatedEntries;
-  }
-
-  /**
-   * @param {!Array<!Coverage.RangeUseCount>} ranges
-   * @return {!Array<!Coverage.CoverageSegment>}
-   */
-  static _convertToDisjointSegments(ranges) {
-    ranges.sort((a, b) => a.startOffset - b.startOffset);
-
-    const result = [];
-    const stack = [];
-    for (const entry of ranges) {
-      let top = stack.peekLast();
-      while (top && top.endOffset <= entry.startOffset) {
-        append(top.endOffset, top.count);
-        stack.pop();
-        top = stack.peekLast();
-      }
-      append(entry.startOffset, top ? top.count : undefined);
-      stack.push(entry);
-    }
-
-    while (stack.length) {
-      const top = stack.pop();
-      append(top.endOffset, top.count);
-    }
-
-    /**
-     * @param {number} end
-     * @param {number} count
-     */
-    function append(end, count) {
-      const last = result.peekLast();
-      if (last) {
-        if (last.end === end)
-          return;
-        if (last.count === count) {
-          last.end = end;
-          return;
-        }
-      }
-      result.push({end: end, count: count});
-    }
-
-    return result;
-  }
-
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {number} contentLength
-   * @param {number} startLine
-   * @param {number} startColumn
-   * @param {!Array<!Coverage.RangeUseCount>} ranges
-   * @param {!Coverage.CoverageType} type
-   * @return {?Coverage.CoverageInfo}
-   */
-  _addCoverage(contentProvider, contentLength, startLine, startColumn, ranges, type) {
-    const url = contentProvider.contentURL();
-    if (!url)
-      return null;
-    let urlCoverage = this._coverageByURL.get(url);
-    if (!urlCoverage) {
-      urlCoverage = new Coverage.URLCoverageInfo(url);
-      this._coverageByURL.set(url, urlCoverage);
-    }
-
-    const coverageInfo = urlCoverage._ensureEntry(contentProvider, contentLength, startLine, startColumn, type);
-    this._coverageByContentProvider.set(contentProvider, coverageInfo);
-    const segments = Coverage.CoverageModel._convertToDisjointSegments(ranges);
-    if (segments.length && segments.peekLast().end < contentLength)
-      segments.push({end: contentLength});
-    const oldUsedSize = coverageInfo._usedSize;
-    coverageInfo.mergeCoverage(segments);
-    if (coverageInfo._usedSize === oldUsedSize)
-      return null;
-    urlCoverage._usedSize += coverageInfo._usedSize - oldUsedSize;
-    return coverageInfo;
-  }
-};
-
-Coverage.URLCoverageInfo = class {
-  /**
-   * @param {string} url
-   */
-  constructor(url) {
-    this._url = url;
-    /** @type {!Map<string, !Coverage.CoverageInfo>} */
-    this._coverageInfoByLocation = new Map();
-    this._size = 0;
-    this._usedSize = 0;
-    /** @type {!Coverage.CoverageType} */
-    this._type;
-    this._isContentScript = false;
-  }
-
-  /**
-   * @return {string}
-   */
-  url() {
-    return this._url;
-  }
-
-  /**
-   * @return {!Coverage.CoverageType}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {number}
-   */
-  size() {
-    return this._size;
-  }
-
-  /**
-   * @return {number}
-   */
-  usedSize() {
-    return this._usedSize;
-  }
-
-  /**
-   * @return {number}
-   */
-  unusedSize() {
-    return this._size - this._usedSize;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isContentScript() {
-    return this._isContentScript;
-  }
-
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {number} contentLength
-   * @param {number} lineOffset
-   * @param {number} columnOffset
-   * @param {!Coverage.CoverageType} type
-   * @return {!Coverage.CoverageInfo}
-   */
-  _ensureEntry(contentProvider, contentLength, lineOffset, columnOffset, type) {
-    const key = `${lineOffset}:${columnOffset}`;
-    let entry = this._coverageInfoByLocation.get(key);
-
-    if ((type & Coverage.CoverageType.JavaScript) && !this._coverageInfoByLocation.size)
-      this._isContentScript = /** @type {!SDK.Script} */ (contentProvider).isContentScript();
-    this._type |= type;
-
-    if (entry) {
-      entry._coverageType |= type;
-      return entry;
-    }
-
-    if ((type & Coverage.CoverageType.JavaScript) && !this._coverageInfoByLocation.size)
-      this._isContentScript = /** @type {!SDK.Script} */ (contentProvider).isContentScript();
-
-    entry = new Coverage.CoverageInfo(contentProvider, contentLength, type);
-    this._coverageInfoByLocation.set(key, entry);
-    this._size += contentLength;
-
-    return entry;
-  }
-};
-
-Coverage.CoverageInfo = class {
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {number} size
-   * @param {!Coverage.CoverageType} type
-   */
-  constructor(contentProvider, size, type) {
-    this._contentProvider = contentProvider;
-    this._size = size;
-    this._usedSize = 0;
-    this._coverageType = type;
-
-    /** !Array<!Coverage.CoverageSegment> */
-    this._segments = [];
-  }
-
-  /**
-   * @return {!Common.ContentProvider}
-   */
-  contentProvider() {
-    return this._contentProvider;
-  }
-
-  /**
-   * @return {string}
-   */
-  url() {
-    return this._contentProvider.contentURL();
-  }
-
-  /**
-   * @return {!Coverage.CoverageType}
-   */
-  type() {
-    return this._coverageType;
-  }
-
-  /**
-   * @param {!Array<!Coverage.CoverageSegment>} segments
-   */
-  mergeCoverage(segments) {
-    this._segments = Coverage.CoverageInfo._mergeCoverage(this._segments, segments);
-    this._updateStats();
-  }
-
-  /**
-   * @param {number} start
-   * @param {number} end
-   * @return {boolean}
-   */
-  usageForRange(start, end) {
-    let index = this._segments.upperBound(start, (position, segment) => position - segment.end);
-    for (; index < this._segments.length && this._segments[index].end < end; ++index) {
-      if (this._segments[index].count)
-        return true;
-    }
-    return index < this._segments.length && !!this._segments[index].count;
-  }
-
-  /**
-   * @param {!Array<!Coverage.CoverageSegment>} segmentsA
-   * @param {!Array<!Coverage.CoverageSegment>} segmentsB
-   */
-  static _mergeCoverage(segmentsA, segmentsB) {
-    const result = [];
-
-    let indexA = 0;
-    let indexB = 0;
-    while (indexA < segmentsA.length && indexB < segmentsB.length) {
-      const a = segmentsA[indexA];
-      const b = segmentsB[indexB];
-      const count =
-          typeof a.count === 'number' || typeof b.count === 'number' ? (a.count || 0) + (b.count || 0) : undefined;
-      const end = Math.min(a.end, b.end);
-      const last = result.peekLast();
-      if (!last || last.count !== count)
-        result.push({end: end, count: count});
-      else
-        last.end = end;
-      if (a.end <= b.end)
-        indexA++;
-      if (a.end >= b.end)
-        indexB++;
-    }
-
-    for (; indexA < segmentsA.length; indexA++)
-      result.push(segmentsA[indexA]);
-    for (; indexB < segmentsB.length; indexB++)
-      result.push(segmentsB[indexB]);
-    return result;
-  }
-
-  _updateStats() {
-    this._usedSize = 0;
-
-    let last = 0;
-    for (const segment of this._segments) {
-      if (segment.count)
-        this._usedSize += segment.end - last;
-      last = segment.end;
-    }
-  }
-};
diff --git a/front_end/coverage/CoverageView.js b/front_end/coverage/CoverageView.js
deleted file mode 100644
index b0367fa..0000000
--- a/front_end/coverage/CoverageView.js
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Coverage.CoverageView = class extends UI.VBox {
-  constructor() {
-    super(true);
-
-    /** @type {?Coverage.CoverageModel} */
-    this._model = null;
-    /** @type {number|undefined} */
-    this._pollTimer;
-    /** @type {?Coverage.CoverageDecorationManager} */
-    this._decorationManager = null;
-    /** @type {?SDK.ResourceTreeModel} */
-    this._resourceTreeModel = null;
-
-    this.registerRequiredCSS('coverage/coverageView.css');
-
-    const toolbarContainer = this.contentElement.createChild('div', 'coverage-toolbar-container');
-    const toolbar = new UI.Toolbar('coverage-toolbar', toolbarContainer);
-
-    this._toggleRecordAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('coverage.toggle-recording'));
-    this._toggleRecordButton = UI.Toolbar.createActionButton(this._toggleRecordAction);
-    toolbar.appendToolbarItem(this._toggleRecordButton);
-
-    const mainTarget = SDK.targetManager.mainTarget();
-    if (mainTarget && mainTarget.model(SDK.ResourceTreeModel)) {
-      const startWithReloadAction =
-          /** @type {!UI.Action }*/ (UI.actionRegistry.action('coverage.start-with-reload'));
-      this._startWithReloadButton = UI.Toolbar.createActionButton(startWithReloadAction);
-      toolbar.appendToolbarItem(this._startWithReloadButton);
-    }
-    this._clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largeicon-clear');
-    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clear.bind(this));
-    toolbar.appendToolbarItem(this._clearButton);
-
-    /** @type {?RegExp} */
-    this._textFilterRegExp = null;
-
-    toolbar.appendSeparator();
-    this._filterInput = new UI.ToolbarInput(Common.UIString('URL filter'), 0.4, 1);
-    this._filterInput.setEnabled(false);
-    this._filterInput.addEventListener(UI.ToolbarInput.Event.TextChanged, this._onFilterChanged, this);
-    toolbar.appendToolbarItem(this._filterInput);
-
-    toolbar.appendSeparator();
-    this._showContentScriptsSetting = Common.settings.createSetting('showContentScripts', false);
-    this._showContentScriptsSetting.addChangeListener(this._onFilterChanged, this);
-    const contentScriptsCheckbox = new UI.ToolbarSettingCheckbox(
-        this._showContentScriptsSetting, Common.UIString('Include extension content scripts'),
-        Common.UIString('Content scripts'));
-    toolbar.appendToolbarItem(contentScriptsCheckbox);
-
-    this._coverageResultsElement = this.contentElement.createChild('div', 'coverage-results');
-    this._landingPage = this._buildLandingPage();
-    this._listView = new Coverage.CoverageListView(this._isVisible.bind(this, false));
-
-    this._statusToolbarElement = this.contentElement.createChild('div', 'coverage-toolbar-summary');
-    this._statusMessageElement = this._statusToolbarElement.createChild('div', 'coverage-message');
-    this._landingPage.show(this._coverageResultsElement);
-  }
-
-  /**
-   * @return {!UI.VBox}
-   */
-  _buildLandingPage() {
-    const recordButton = UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));
-    const widget = new UI.VBox();
-    let message;
-    if (this._startWithReloadButton) {
-      const reloadButton = UI.createInlineButton(UI.Toolbar.createActionButtonForId('coverage.start-with-reload'));
-      message = UI.formatLocalized(
-          'Click the record button %s to start capturing coverage.\n' +
-              'Click the reload button %s to reload and start capturing coverage.',
-          [recordButton, reloadButton]);
-    } else {
-      message = UI.formatLocalized('Click the record button %s to start capturing coverage.', [recordButton]);
-    }
-    message.classList.add('message');
-    widget.contentElement.appendChild(message);
-    widget.element.classList.add('landing-page');
-    return widget;
-  }
-
-  _clear() {
-    this._model = null;
-    this._reset();
-  }
-
-  _reset() {
-    if (this._decorationManager) {
-      this._decorationManager.dispose();
-      this._decorationManager = null;
-    }
-    this._listView.reset();
-    this._listView.detach();
-    this._landingPage.show(this._coverageResultsElement);
-    this._statusMessageElement.textContent = '';
-    this._filterInput.setEnabled(false);
-  }
-
-  _toggleRecording() {
-    const enable = !this._toggleRecordAction.toggled();
-
-    if (enable)
-      this._startRecording(false);
-    else
-      this._stopRecording();
-  }
-
-  /**
-   * @param {boolean} reload
-   */
-  _startRecording(reload) {
-    this._reset();
-    const mainTarget = SDK.targetManager.mainTarget();
-    if (!mainTarget)
-      return;
-    if (!this._model || reload)
-      this._model = new Coverage.CoverageModel(mainTarget);
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.CoverageStarted);
-    if (!this._model.start())
-      return;
-    this._resourceTreeModel = /** @type {?SDK.ResourceTreeModel} */ (mainTarget.model(SDK.ResourceTreeModel));
-    if (this._resourceTreeModel) {
-      this._resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
-    }
-    this._decorationManager = new Coverage.CoverageDecorationManager(this._model);
-    this._toggleRecordAction.setToggled(true);
-    this._clearButton.setEnabled(false);
-    if (this._startWithReloadButton)
-      this._startWithReloadButton.setEnabled(false);
-    this._filterInput.setEnabled(true);
-    if (this._landingPage.isShowing())
-      this._landingPage.detach();
-    this._listView.show(this._coverageResultsElement);
-    if (reload && this._resourceTreeModel)
-      this._resourceTreeModel.reloadPage();
-    else
-      this._poll();
-  }
-
-  async _poll() {
-    delete this._pollTimer;
-    const updates = await this._model.poll();
-    this._updateViews(updates);
-    this._pollTimer = setTimeout(() => this._poll(), 700);
-  }
-
-  async _stopRecording() {
-    if (this._pollTimer) {
-      clearTimeout(this._pollTimer);
-      delete this._pollTimer;
-    }
-    if (this._resourceTreeModel) {
-      this._resourceTreeModel.removeEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
-      this._resourceTreeModel = null;
-    }
-    const updatedEntries = await this._model.stop();
-    this._updateViews(updatedEntries);
-    this._toggleRecordAction.setToggled(false);
-    if (this._startWithReloadButton)
-      this._startWithReloadButton.setEnabled(true);
-    this._clearButton.setEnabled(true);
-  }
-
-  _onMainFrameNavigated() {
-    this._model.reset();
-    this._decorationManager.reset();
-    this._listView.reset();
-    this._poll();
-  }
-
-  /**
-   * @param {!Array<!Coverage.CoverageInfo>} updatedEntries
-   */
-  async _updateViews(updatedEntries) {
-    this._updateStats();
-    this._listView.update(this._model.entries());
-    this._decorationManager.update(updatedEntries);
-  }
-
-  _updateStats() {
-    let total = 0;
-    let unused = 0;
-    for (const info of this._model.entries()) {
-      if (!this._isVisible(true, info))
-        continue;
-      total += info.size();
-      unused += info.unusedSize();
-    }
-
-    const percentUnused = total ? Math.round(100 * unused / total) : 0;
-    this._statusMessageElement.textContent = Common.UIString(
-        '%s of %s bytes are not used. (%d%%)', Number.bytesToString(unused), Number.bytesToString(total),
-        percentUnused);
-  }
-
-  _onFilterChanged() {
-    if (!this._listView)
-      return;
-    const text = this._filterInput.value();
-    this._textFilterRegExp = text ? createPlainTextSearchRegex(text, 'i') : null;
-    this._listView.updateFilterAndHighlight(this._textFilterRegExp);
-    this._updateStats();
-  }
-
-  /**
-   * @param {boolean} ignoreTextFilter
-   * @param {!Coverage.URLCoverageInfo} coverageInfo
-   * @return {boolean}
-   */
-  _isVisible(ignoreTextFilter, coverageInfo) {
-    const url = coverageInfo.url();
-    if (url.startsWith(Coverage.CoverageView._extensionBindingsURLPrefix))
-      return false;
-    if (coverageInfo.isContentScript() && !this._showContentScriptsSetting.get())
-      return false;
-    return ignoreTextFilter || !this._textFilterRegExp || this._textFilterRegExp.test(url);
-  }
-};
-
-Coverage.CoverageView._extensionBindingsURLPrefix = 'extensions::';
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Coverage.CoverageView.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const coverageViewId = 'coverage';
-    UI.viewManager.showView(coverageViewId)
-        .then(() => UI.viewManager.view(coverageViewId).widget())
-        .then(widget => this._innerHandleAction(/** @type !Coverage.CoverageView} */ (widget), actionId));
-
-    return true;
-  }
-
-  /**
-   * @param {!Coverage.CoverageView} coverageView
-   * @param {string} actionId
-   */
-  _innerHandleAction(coverageView, actionId) {
-    switch (actionId) {
-      case 'coverage.toggle-recording':
-        coverageView._toggleRecording();
-        break;
-      case 'coverage.start-with-reload':
-        coverageView._startRecording(true);
-        break;
-      default:
-        console.assert(false, `Unknown action: ${actionId}`);
-    }
-  }
-};
diff --git a/front_end/coverage/coverageListView.css b/front_end/coverage/coverageListView.css
deleted file mode 100644
index 3b915e2..0000000
--- a/front_end/coverage/coverageListView.css
+++ /dev/null
@@ -1,61 +0,0 @@
-.data-grid {
-  border: none;
-}
-
-.data-grid td .url-outer {
-  width: 100%;
-  display: inline-flex;
-  justify-content: flex-start;
-}
-
-.data-grid td .url-outer .filter-highlight {
-  font-weight: bold;
-}
-
-.data-grid td .url-prefix {
-  overflow-x: hidden;
-  text-overflow: ellipsis;
-}
-
-.data-grid td .url-suffix {
-  flex: none;
-}
-
-.data-grid td .bar {
-  display: inline-block;
-  height: 8px;
-}
-
-.data-grid .selected td .bar {
-  border-top: 1px white solid;
-  border-bottom: 1px white solid;
-}
-
-.data-grid .selected td .bar:last-child {
-  border-right: 1px white solid;
-}
-
-.data-grid .selected td .bar:first-child {
-  border-left: 1px white solid;
-}
-
-.data-grid td .bar-container {
-}
-
-.data-grid td .bar-unused-size {
-  background-color: #E57373;
-}
-
-.data-grid td .bar-used-size {
-  background-color: #81C784;
-}
-
-.data-grid td .percent-value {
-  color: #888;
-  width: 45px;
-  display: inline-block;
-}
-
-.data-grid:focus tr.selected span.percent-value {
-  color: #eee;
-}
diff --git a/front_end/coverage/coverageView.css b/front_end/coverage/coverageView.css
deleted file mode 100644
index 816ef2a..0000000
--- a/front_end/coverage/coverageView.css
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    overflow: hidden;
-}
-
-.coverage-toolbar-container {
-    display: flex;
-    border-bottom: 1px solid #ccc;
-    flex: 0 0;
-}
-
-.coverage-toolbar {
-    display: inline-block;
-}
-
-.coverage-toolbar-summary {
-    background-color: #eee;
-    border-top: 1px solid #ccc;
-    padding-left: 5px;
-    flex: 0 0 19px;
-    display: flex;
-    padding-right: 5px;
-}
-
-.coverage-toolbar-summary .coverage-message {
-    padding-top: 2px;
-    padding-left: 1ex;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    overflow: hidden;
-}
-
-.coverage-results {
-    overflow-y: auto;
-    display: flex;
-    flex: auto;
-}
-
-.landing-page {
-    justify-content: center;
-    align-items:  center;
-    padding: 20px;
-}
-
-.landing-page .message {
-    white-space: pre-line;
-}
diff --git a/front_end/coverage/module.json b/front_end/coverage/module.json
deleted file mode 100644
index ca5239f..0000000
--- a/front_end/coverage/module.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "coverage",
-            "title": "Coverage",
-            "persistence": "closeable",
-            "className": "Coverage.CoverageView",
-            "order": 100
-        },
-        {
-            "type": "@SourceFrame.LineDecorator",
-            "className": "Coverage.CoverageView.LineDecorator",
-            "decoratorType": "coverage"
-        },
-        {
-            "type": "action",
-            "actionId": "coverage.toggle-recording",
-            "iconClass": "largeicon-start-recording",
-            "toggledIconClass": "largeicon-stop-recording",
-            "toggleWithRedColor": true,
-            "className": "Coverage.CoverageView.ActionDelegate",
-            "category": "Performance",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Instrument coverage"
-                },
-                {
-                    "value": false,
-                    "title": "Stop instrumenting coverage and show results"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "coverage.start-with-reload",
-            "iconClass": "largeicon-refresh",
-            "className": "Coverage.CoverageView.ActionDelegate",
-            "category": "Performance",
-            "title": "Start instrumenting coverage and reload page"
-        }
-    ],
-    "dependencies": [
-        "sdk",
-        "ui",
-        "source_frame",
-        "sources",
-        "data_grid"
-    ],
-    "scripts": [
-        "CoverageModel.js",
-        "CoverageListView.js",
-        "CoverageView.js",
-        "CoverageDecorationManager.js"
-    ],
-    "resources": [
-        "coverageListView.css",
-        "coverageView.css"
-    ]
-}
diff --git a/front_end/coverage_test_runner/CoverageTestRunner.js b/front_end/coverage_test_runner/CoverageTestRunner.js
deleted file mode 100644
index 0757efb..0000000
--- a/front_end/coverage_test_runner/CoverageTestRunner.js
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-CoverageTestRunner.startCoverage = function() {
-  UI.viewManager.showView('coverage');
-  const coverageView = self.runtime.sharedInstance(Coverage.CoverageView);
-  coverageView._startRecording();
-};
-
-/**
- * @return {!Promise}
- */
-CoverageTestRunner.stopCoverage = function() {
-  const coverageView = self.runtime.sharedInstance(Coverage.CoverageView);
-  return coverageView._stopRecording();
-};
-
-/**
- * @return {!Promise}
- */
-CoverageTestRunner.pollCoverage = function() {
-  const coverageView = self.runtime.sharedInstance(Coverage.CoverageView);
-  return coverageView._poll();
-};
-
-/**
- * @return {!Promise<!SourceFrame.SourceFrame>}
- */
-CoverageTestRunner.sourceDecorated = async function(source) {
-  await UI.inspectorView.showPanel('sources');
-  const decoratePromise = TestRunner.addSnifferPromise(Coverage.CoverageView.LineDecorator.prototype, '_innerDecorate');
-  const sourceFrame = await SourcesTestRunner.showScriptSourcePromise(source);
-  await decoratePromise;
-  return sourceFrame;
-};
-
-CoverageTestRunner.dumpDecorations = async function(source) {
-  const sourceFrame = await CoverageTestRunner.sourceDecorated(source);
-  CoverageTestRunner.dumpDecorationsInSourceFrame(sourceFrame);
-};
-
-/**
- * @return {?DataGrid.DataGridNode}
- */
-CoverageTestRunner.findCoverageNodeForURL = function(url) {
-  const coverageListView = self.runtime.sharedInstance(Coverage.CoverageView)._listView;
-  const rootNode = coverageListView._dataGrid.rootNode();
-
-  for (const child of rootNode.children) {
-    if (child._coverageInfo.url().endsWith(url))
-      return child;
-  }
-
-  return null;
-};
-
-CoverageTestRunner.dumpDecorationsInSourceFrame = function(sourceFrame) {
-  const markerMap = new Map([['used', '+'], ['unused', '-']]);
-  const codeMirror = sourceFrame.textEditor.codeMirror();
-
-  for (let line = 0; line < codeMirror.lineCount(); ++line) {
-    const text = codeMirror.getLine(line);
-    let markerType = ' ';
-    const lineInfo = codeMirror.lineInfo(line);
-
-    if (!lineInfo)
-      continue;
-
-    const gutterElement = lineInfo.gutterMarkers && lineInfo.gutterMarkers['CodeMirror-gutter-coverage'];
-
-    if (gutterElement) {
-      const markerClass = /^text-editor-coverage-(\w*)-marker$/.exec(gutterElement.classList)[1];
-      markerType = markerMap.get(markerClass) || gutterElement.classList;
-    }
-
-    TestRunner.addResult(`${line}: ${markerType} ${text}`);
-  }
-};
-
-CoverageTestRunner.dumpCoverageListView = function() {
-  const coverageListView = self.runtime.sharedInstance(Coverage.CoverageView)._listView;
-  const dataGrid = coverageListView._dataGrid;
-  dataGrid.updateInstantly();
-
-  for (const child of dataGrid.rootNode().children) {
-    const data = child._coverageInfo;
-    const url = TestRunner.formatters.formatAsURL(data.url());
-
-    if (url.startsWith('test://'))
-      continue;
-
-    const type = Coverage.CoverageListView._typeToString(data.type());
-    TestRunner.addResult(`${url} ${type} used: ${data.usedSize()} unused: ${data.unusedSize()} total: ${data.size()}`);
-  }
-};
diff --git a/front_end/coverage_test_runner/module.json b/front_end/coverage_test_runner/module.json
deleted file mode 100644
index ef78c8c..0000000
--- a/front_end/coverage_test_runner/module.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "coverage",
-    "sources_test_runner"
-  ],
-  "scripts": [
-    "CoverageTestRunner.js"
-  ],
-  "skip_compilation": [
-    "CoverageTestRunner.js"
-  ]
-}
diff --git a/front_end/cpu_profiler_test_runner/ProfilerTestRunner.js b/front_end/cpu_profiler_test_runner/ProfilerTestRunner.js
deleted file mode 100644
index 49abf7d..0000000
--- a/front_end/cpu_profiler_test_runner/ProfilerTestRunner.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-CPUProfilerTestRunner.startProfilerTest = function(callback) {
-  TestRunner.addResult('Profiler was enabled.');
-  TestRunner.addSniffer(UI.panels.js_profiler, '_addProfileHeader', CPUProfilerTestRunner._profileHeaderAdded, true);
-  TestRunner.addSniffer(Profiler.ProfileView.prototype, 'refresh', CPUProfilerTestRunner._profileViewRefresh, true);
-  TestRunner.safeWrap(callback)();
-};
-
-CPUProfilerTestRunner.completeProfilerTest = function() {
-  TestRunner.addResult('');
-  TestRunner.addResult('Profiler was disabled.');
-  TestRunner.completeTest();
-};
-
-CPUProfilerTestRunner.runProfilerTestSuite = function(testSuite) {
-  const testSuiteTests = testSuite.slice();
-
-  function runner() {
-    if (!testSuiteTests.length) {
-      CPUProfilerTestRunner.completeProfilerTest();
-      return;
-    }
-
-    const nextTest = testSuiteTests.shift();
-    TestRunner.addResult('');
-    TestRunner.addResult(
-        'Running: ' +
-        /function\s([^(]*)/.exec(nextTest)[1]);
-    TestRunner.safeWrap(nextTest)(runner, runner);
-  }
-
-  CPUProfilerTestRunner.startProfilerTest(runner);
-};
-
-CPUProfilerTestRunner.showProfileWhenAdded = function(title) {
-  CPUProfilerTestRunner._showProfileWhenAdded = title;
-};
-
-CPUProfilerTestRunner._profileHeaderAdded = function(profile) {
-  if (CPUProfilerTestRunner._showProfileWhenAdded === profile.title)
-    UI.panels.js_profiler.showProfile(profile);
-};
-
-CPUProfilerTestRunner.waitUntilProfileViewIsShown = function(title, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const profilesPanel = UI.panels.js_profiler;
-
-  if (profilesPanel.visibleView && profilesPanel.visibleView.profile &&
-      profilesPanel.visibleView._profileHeader.title === title)
-    callback(profilesPanel.visibleView);
-  else
-    CPUProfilerTestRunner._waitUntilProfileViewIsShownCallback = {title: title, callback: callback};
-
-};
-
-CPUProfilerTestRunner._profileViewRefresh = function() {
-  if (CPUProfilerTestRunner._waitUntilProfileViewIsShownCallback &&
-      CPUProfilerTestRunner._waitUntilProfileViewIsShownCallback.title === this._profileHeader.title) {
-    const callback = CPUProfilerTestRunner._waitUntilProfileViewIsShownCallback;
-    delete CPUProfilerTestRunner._waitUntilProfileViewIsShownCallback;
-    callback.callback(this);
-  }
-};
diff --git a/front_end/cpu_profiler_test_runner/module.json b/front_end/cpu_profiler_test_runner/module.json
deleted file mode 100644
index e8539cc..0000000
--- a/front_end/cpu_profiler_test_runner/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": [
-        "profiler",
-        "test_runner"
-    ],
-    "scripts": [
-        "ProfilerTestRunner.js"
-    ],
-    "skip_compilation": [
-        "ProfilerTestRunner.js"
-    ]
-}
diff --git a/front_end/data_grid/DataGrid.js b/front_end/data_grid/DataGrid.js
deleted file mode 100644
index 79f42c2..0000000
--- a/front_end/data_grid/DataGrid.js
+++ /dev/null
@@ -1,2071 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *        notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *        notice, this list of conditions and the following disclaimer in the
- *        documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.         IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- * @template NODE_TYPE
- */
-DataGrid.DataGrid = class extends Common.Object {
-  /**
-   * @param {!Array.<!DataGrid.DataGrid.ColumnDescriptor>} columnsArray
-   * @param {function(!NODE_TYPE, string, string, string)=} editCallback
-   * @param {function(!NODE_TYPE)=} deleteCallback
-   * @param {function()=} refreshCallback
-   */
-  constructor(columnsArray, editCallback, deleteCallback, refreshCallback) {
-    super();
-    this.element = createElementWithClass('div', 'data-grid');
-    UI.appendStyle(this.element, 'data_grid/dataGrid.css');
-    this.element.tabIndex = 0;
-    this.element.addEventListener('keydown', this._keyDown.bind(this), false);
-    this.element.addEventListener('contextmenu', this._contextMenu.bind(this), true);
-
-    this._editCallback = editCallback;
-    this._deleteCallback = deleteCallback;
-    this._refreshCallback = refreshCallback;
-
-    const headerContainer = this.element.createChild('div', 'header-container');
-    /** @type {!Element} */
-    this._headerTable = headerContainer.createChild('table', 'header');
-    /** @type {!Object.<string, !Element>} */
-    this._headerTableHeaders = {};
-    /** @type {!Element} */
-    this._scrollContainer = this.element.createChild('div', 'data-container');
-    /** @type {!Element} */
-    this._dataTable = this._scrollContainer.createChild('table', 'data');
-
-    // FIXME: Add a createCallback which is different from editCallback and has different
-    // behavior when creating a new node.
-    if (editCallback)
-      this._dataTable.addEventListener('dblclick', this._ondblclick.bind(this), false);
-    this._dataTable.addEventListener('mousedown', this._mouseDownInDataTable.bind(this));
-    this._dataTable.addEventListener('click', this._clickInDataTable.bind(this), true);
-
-    /** @type {boolean} */
-    this._inline = false;
-
-    /** @type {!Array.<!DataGrid.DataGrid.ColumnDescriptor>} */
-    this._columnsArray = [];
-    /** @type {!Object.<string, !DataGrid.DataGrid.ColumnDescriptor>} */
-    this._columns = {};
-    /** @type {!Array.<!DataGrid.DataGrid.ColumnDescriptor>} */
-    this._visibleColumnsArray = columnsArray;
-
-    columnsArray.forEach(column => this._innerAddColumn(column));
-
-    /** @type {?string} */
-    this._cellClass = null;
-
-    /** @type {!Element} */
-    this._headerTableColumnGroup = this._headerTable.createChild('colgroup');
-    /** @type {!Element} */
-    this._headerTableBody = this._headerTable.createChild('tbody');
-    /** @type {!Element} */
-    this._headerRow = this._headerTableBody.createChild('tr');
-
-    /** @type {!Element} */
-    this._dataTableColumnGroup = this._dataTable.createChild('colgroup');
-    /**
-     * @protected
-     * @type {!Element}
-     */
-    this.dataTableBody = this._dataTable.createChild('tbody');
-    /** @type {!Element} */
-    this._topFillerRow = this.dataTableBody.createChild('tr', 'data-grid-filler-row revealed');
-    /** @type {!Element} */
-    this._bottomFillerRow = this.dataTableBody.createChild('tr', 'data-grid-filler-row revealed');
-
-    this.setVerticalPadding(0, 0);
-    this._refreshHeader();
-
-    /** @type {boolean} */
-    this._editing = false;
-    /** @type {?NODE_TYPE} */
-    this.selectedNode = null;
-    /** @type {boolean} */
-    this.expandNodesWhenArrowing = false;
-    this.setRootNode(/** @type {!NODE_TYPE} */ (new DataGrid.DataGridNode()));
-    /** @type {number} */
-    this.indentWidth = 15;
-    /** @type {!Array.<!Element|{__index: number, __position: number}>} */
-    this._resizers = [];
-    /** @type {boolean} */
-    this._columnWidthsInitialized = false;
-    /** @type {number} */
-    this._cornerWidth = DataGrid.DataGrid.CornerWidth;
-    /** @type {!DataGrid.DataGrid.ResizeMethod} */
-    this._resizeMethod = DataGrid.DataGrid.ResizeMethod.Nearest;
-
-    /** @type {?function(!UI.ContextMenu)} */
-    this._headerContextMenuCallback = null;
-    /** @type {?function(!UI.ContextMenu, !NODE_TYPE)} */
-    this._rowContextMenuCallback = null;
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} newText
-   * @param {boolean} longText
-   */
-  static setElementText(element, newText, longText) {
-    if (longText && newText.length > 1000) {
-      element.textContent = newText.trimEnd(1000);
-      element.title = newText;
-      element[DataGrid.DataGrid._longTextSymbol] = newText;
-    } else {
-      element.textContent = newText;
-      element.title = '';
-      element[DataGrid.DataGrid._longTextSymbol] = undefined;
-    }
-  }
-
-  /**
-   * @param {boolean} isStriped
-   */
-  setStriped(isStriped) {
-    this.element.classList.toggle('striped-data-grid', isStriped);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  headerTableBody() {
-    return this._headerTableBody;
-  }
-
-  /**
-   * @param {!DataGrid.DataGrid.ColumnDescriptor} column
-   * @param {number=} position
-   */
-  _innerAddColumn(column, position) {
-    const columnId = column.id;
-    if (columnId in this._columns)
-      this._innerRemoveColumn(columnId);
-
-    if (position === undefined)
-      position = this._columnsArray.length;
-
-    this._columnsArray.splice(position, 0, column);
-    this._columns[columnId] = column;
-    if (column.disclosure)
-      this.disclosureColumnId = columnId;
-
-    const cell = createElement('th');
-    cell.className = columnId + '-column';
-    cell[DataGrid.DataGrid._columnIdSymbol] = columnId;
-    this._headerTableHeaders[columnId] = cell;
-
-    const div = createElement('div');
-    if (column.titleDOMFragment)
-      div.appendChild(column.titleDOMFragment);
-    else
-      div.textContent = column.title;
-    cell.appendChild(div);
-
-    if (column.sort) {
-      cell.classList.add(column.sort);
-      this._sortColumnCell = cell;
-    }
-
-    if (column.sortable) {
-      cell.addEventListener('click', this._clickInHeaderCell.bind(this), false);
-      cell.classList.add('sortable');
-      const icon = UI.Icon.create('', 'sort-order-icon');
-      cell.createChild('div', 'sort-order-icon-container').appendChild(icon);
-      cell[DataGrid.DataGrid._sortIconSymbol] = icon;
-    }
-  }
-
-  /**
-   * @param {!DataGrid.DataGrid.ColumnDescriptor} column
-   * @param {number=} position
-   */
-  addColumn(column, position) {
-    this._innerAddColumn(column, position);
-  }
-
-  /**
-   * @param {string} columnId
-   */
-  _innerRemoveColumn(columnId) {
-    const column = this._columns[columnId];
-    if (!column)
-      return;
-    delete this._columns[columnId];
-    const index = this._columnsArray.findIndex(columnConfig => columnConfig.id === columnId);
-    this._columnsArray.splice(index, 1);
-    const cell = this._headerTableHeaders[columnId];
-    if (cell.parentElement)
-      cell.parentElement.removeChild(cell);
-    delete this._headerTableHeaders[columnId];
-  }
-
-  /**
-   * @param {string} columnId
-   */
-  removeColumn(columnId) {
-    this._innerRemoveColumn(columnId);
-  }
-
-  /**
-   * @param {string} cellClass
-   */
-  setCellClass(cellClass) {
-    this._cellClass = cellClass;
-  }
-
-  _refreshHeader() {
-    this._headerTableColumnGroup.removeChildren();
-    this._dataTableColumnGroup.removeChildren();
-    this._headerRow.removeChildren();
-    this._topFillerRow.removeChildren();
-    this._bottomFillerRow.removeChildren();
-
-    for (let i = 0; i < this._visibleColumnsArray.length; ++i) {
-      const column = this._visibleColumnsArray[i];
-      const columnId = column.id;
-      const headerColumn = this._headerTableColumnGroup.createChild('col');
-      const dataColumn = this._dataTableColumnGroup.createChild('col');
-      if (column.width) {
-        headerColumn.style.width = column.width;
-        dataColumn.style.width = column.width;
-      }
-      this._headerRow.appendChild(this._headerTableHeaders[columnId]);
-      this._topFillerRow.createChild('td', 'top-filler-td');
-      this._bottomFillerRow.createChild('td', 'bottom-filler-td')[DataGrid.DataGrid._columnIdSymbol] = columnId;
-    }
-
-    this._headerRow.createChild('th', 'corner');
-    this._topFillerRow.createChild('td', 'corner').classList.add('top-filler-td');
-    this._bottomFillerRow.createChild('td', 'corner').classList.add('bottom-filler-td');
-    this._headerTableColumnGroup.createChild('col', 'corner');
-    this._dataTableColumnGroup.createChild('col', 'corner');
-  }
-
-  /**
-   * @param {number} top
-   * @param {number} bottom
-   * @protected
-   */
-  setVerticalPadding(top, bottom) {
-    const topPx = top + 'px';
-    const bottomPx = (top || bottom) ? bottom + 'px' : 'auto';
-    if (this._topFillerRow.style.height === topPx && this._bottomFillerRow.style.height === bottomPx)
-      return;
-    this._topFillerRow.style.height = topPx;
-    this._bottomFillerRow.style.height = bottomPx;
-    this.dispatchEventToListeners(DataGrid.DataGrid.Events.PaddingChanged);
-  }
-
-  /**
-   * @param {!NODE_TYPE} rootNode
-   * @protected
-   */
-  setRootNode(rootNode) {
-    if (this._rootNode) {
-      this._rootNode.removeChildren();
-      this._rootNode.dataGrid = null;
-      this._rootNode._isRoot = false;
-    }
-    /** @type {!NODE_TYPE} */
-    this._rootNode = rootNode;
-    rootNode._isRoot = true;
-    rootNode.setHasChildren(false);
-    rootNode._expanded = true;
-    rootNode._revealed = true;
-    rootNode.selectable = false;
-    rootNode.dataGrid = this;
-  }
-
-  /**
-   * @return {!NODE_TYPE}
-   */
-  rootNode() {
-    return this._rootNode;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _ondblclick(event) {
-    if (this._editing || this._editingNode)
-      return;
-
-    const columnId = this.columnIdFromNode(/** @type {!Node} */ (event.target));
-    if (!columnId || !this._columns[columnId].editable)
-      return;
-    this._startEditing(/** @type {!Node} */ (event.target));
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} node
-   * @param {number} cellIndex
-   */
-  _startEditingColumnOfDataGridNode(node, cellIndex) {
-    this._editing = true;
-    /** @type {?DataGrid.DataGridNode} */
-    this._editingNode = node;
-    this._editingNode.select();
-
-    const element = this._editingNode._element.children[cellIndex];
-    UI.InplaceEditor.startEditing(element, this._startEditingConfig(element));
-    element.getComponentSelection().selectAllChildren(element);
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} node
-   * @param {string} columnIdentifier
-   */
-  startEditingNextEditableColumnOfDataGridNode(node, columnIdentifier) {
-    const column = this._columns[columnIdentifier];
-    const cellIndex = this._visibleColumnsArray.indexOf(column);
-    const nextEditableColumn = this._nextEditableColumn(cellIndex);
-    if (nextEditableColumn !== -1)
-      this._startEditingColumnOfDataGridNode(node, nextEditableColumn);
-  }
-
-  /**
-   * @param {!Node} target
-   */
-  _startEditing(target) {
-    const element = /** @type {?Element} */ (target.enclosingNodeOrSelfWithNodeName('td'));
-    if (!element)
-      return;
-
-    this._editingNode = this.dataGridNodeFromNode(target);
-    if (!this._editingNode) {
-      if (!this.creationNode)
-        return;
-      this._editingNode = this.creationNode;
-    }
-
-    // Force editing the 1st column when editing the creation node
-    if (this._editingNode.isCreationNode) {
-      this._startEditingColumnOfDataGridNode(this._editingNode, this._nextEditableColumn(-1));
-      return;
-    }
-
-    this._editing = true;
-    if (element[DataGrid.DataGrid._longTextSymbol])
-      element.textContent = element[DataGrid.DataGrid._longTextSymbol];
-    UI.InplaceEditor.startEditing(element, this._startEditingConfig(element));
-
-    element.getComponentSelection().selectAllChildren(element);
-  }
-
-  renderInline() {
-    this.element.classList.add('inline');
-    this._cornerWidth = 0;
-    this._inline = true;
-    this.updateWidths();
-  }
-
-  /**
-   * @param {!Element} element
-   * @return {!UI.InplaceEditor.Config}
-   */
-  _startEditingConfig(element) {
-    return new UI.InplaceEditor.Config(this._editingCommitted.bind(this), this._editingCancelled.bind(this));
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} newText
-   * @param {string} oldText
-   * @param {string|undefined} context
-   * @param {string} moveDirection
-   */
-  _editingCommitted(element, newText, oldText, context, moveDirection) {
-    const columnId = this.columnIdFromNode(element);
-    if (!columnId) {
-      this._editingCancelled(element);
-      return;
-    }
-    const column = this._columns[columnId];
-    const cellIndex = this._visibleColumnsArray.indexOf(column);
-    const textBeforeEditing = /** @type {string} */ (this._editingNode.data[columnId] || '');
-    const currentEditingNode = this._editingNode;
-
-    /**
-     * @param {boolean} wasChange
-     * @this {DataGrid.DataGrid}
-     */
-    function moveToNextIfNeeded(wasChange) {
-      if (!moveDirection)
-        return;
-
-      if (moveDirection === 'forward') {
-        const firstEditableColumn = this._nextEditableColumn(-1);
-        if (currentEditingNode.isCreationNode && cellIndex === firstEditableColumn && !wasChange)
-          return;
-
-        const nextEditableColumn = this._nextEditableColumn(cellIndex);
-        if (nextEditableColumn !== -1) {
-          this._startEditingColumnOfDataGridNode(currentEditingNode, nextEditableColumn);
-          return;
-        }
-
-        const nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
-        if (nextDataGridNode) {
-          this._startEditingColumnOfDataGridNode(nextDataGridNode, firstEditableColumn);
-          return;
-        }
-        if (currentEditingNode.isCreationNode && wasChange) {
-          this.addCreationNode(false);
-          this._startEditingColumnOfDataGridNode(this.creationNode, firstEditableColumn);
-          return;
-        }
-        return;
-      }
-
-      if (moveDirection === 'backward') {
-        const prevEditableColumn = this._nextEditableColumn(cellIndex, true);
-        if (prevEditableColumn !== -1) {
-          this._startEditingColumnOfDataGridNode(currentEditingNode, prevEditableColumn);
-          return;
-        }
-
-        const lastEditableColumn = this._nextEditableColumn(this._visibleColumnsArray.length, true);
-        const nextDataGridNode = currentEditingNode.traversePreviousNode(true, true);
-        if (nextDataGridNode)
-          this._startEditingColumnOfDataGridNode(nextDataGridNode, lastEditableColumn);
-        return;
-      }
-    }
-
-    // Show trimmed text after editing.
-    DataGrid.DataGrid.setElementText(element, newText, !!column.longText);
-
-    if (textBeforeEditing === newText) {
-      this._editingCancelled(element);
-      moveToNextIfNeeded.call(this, false);
-      return;
-    }
-
-    // Update the text in the datagrid that we typed
-    this._editingNode.data[columnId] = newText;
-
-    // Make the callback - expects an editing node (table row), the column number that is being edited,
-    // the text that used to be there, and the new text.
-    this._editCallback(this._editingNode, columnId, textBeforeEditing, newText);
-
-    if (this._editingNode.isCreationNode)
-      this.addCreationNode(false);
-
-    this._editingCancelled(element);
-    moveToNextIfNeeded.call(this, true);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  _editingCancelled(element) {
-    this._editing = false;
-    this._editingNode = null;
-  }
-
-  /**
-   * @param {number} cellIndex
-   * @param {boolean=} moveBackward
-   * @return {number}
-   */
-  _nextEditableColumn(cellIndex, moveBackward) {
-    const increment = moveBackward ? -1 : 1;
-    const columns = this._visibleColumnsArray;
-    for (let i = cellIndex + increment; (i >= 0) && (i < columns.length); i += increment) {
-      if (columns[i].editable)
-        return i;
-    }
-    return -1;
-  }
-
-  /**
-   * @return {?string}
-   */
-  sortColumnId() {
-    if (!this._sortColumnCell)
-      return null;
-    return this._sortColumnCell[DataGrid.DataGrid._columnIdSymbol];
-  }
-
-  /**
-   * @return {?string}
-   */
-  sortOrder() {
-    if (!this._sortColumnCell || this._sortColumnCell.classList.contains(DataGrid.DataGrid.Order.Ascending))
-      return DataGrid.DataGrid.Order.Ascending;
-    if (this._sortColumnCell.classList.contains(DataGrid.DataGrid.Order.Descending))
-      return DataGrid.DataGrid.Order.Descending;
-    return null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isSortOrderAscending() {
-    return !this._sortColumnCell || this._sortColumnCell.classList.contains(DataGrid.DataGrid.Order.Ascending);
-  }
-
-  /**
-   * @param {!Array.<number>} widths
-   * @param {number} minPercent
-   * @param {number=} maxPercent
-   * @return {!Array.<number>}
-   */
-  _autoSizeWidths(widths, minPercent, maxPercent) {
-    if (minPercent)
-      minPercent = Math.min(minPercent, Math.floor(100 / widths.length));
-    let totalWidth = 0;
-    for (let i = 0; i < widths.length; ++i)
-      totalWidth += widths[i];
-    let totalPercentWidth = 0;
-    for (let i = 0; i < widths.length; ++i) {
-      let width = Math.round(100 * widths[i] / totalWidth);
-      if (minPercent && width < minPercent)
-        width = minPercent;
-      else if (maxPercent && width > maxPercent)
-        width = maxPercent;
-      totalPercentWidth += width;
-      widths[i] = width;
-    }
-    let recoupPercent = totalPercentWidth - 100;
-
-    while (minPercent && recoupPercent > 0) {
-      for (let i = 0; i < widths.length; ++i) {
-        if (widths[i] > minPercent) {
-          --widths[i];
-          --recoupPercent;
-          if (!recoupPercent)
-            break;
-        }
-      }
-    }
-
-    while (maxPercent && recoupPercent < 0) {
-      for (let i = 0; i < widths.length; ++i) {
-        if (widths[i] < maxPercent) {
-          ++widths[i];
-          ++recoupPercent;
-          if (!recoupPercent)
-            break;
-        }
-      }
-    }
-
-    return widths;
-  }
-
-  /**
-   * @param {number} minPercent
-   * @param {number=} maxPercent
-   * @param {number=} maxDescentLevel
-   */
-  autoSizeColumns(minPercent, maxPercent, maxDescentLevel) {
-    let widths = [];
-    for (let i = 0; i < this._columnsArray.length; ++i)
-      widths.push((this._columnsArray[i].title || '').length);
-
-    maxDescentLevel = maxDescentLevel || 0;
-    const children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1);
-    for (let i = 0; i < children.length; ++i) {
-      const node = children[i];
-      for (let j = 0; j < this._columnsArray.length; ++j) {
-        const text = node.data[this._columnsArray[j].id];
-        if (text.length > widths[j])
-          widths[j] = text.length;
-      }
-    }
-
-    widths = this._autoSizeWidths(widths, minPercent, maxPercent);
-
-    for (let i = 0; i < this._columnsArray.length; ++i)
-      this._columnsArray[i].weight = widths[i];
-    this._columnWidthsInitialized = false;
-    this.updateWidths();
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} rootNode
-   * @param {!Array<!DataGrid.DataGridNode>} result
-   * @param {number} maxLevel
-   * @return {!Array<!NODE_TYPE>}
-   */
-  _enumerateChildren(rootNode, result, maxLevel) {
-    if (!rootNode._isRoot)
-      result.push(rootNode);
-    if (!maxLevel)
-      return [];
-    for (let i = 0; i < rootNode.children.length; ++i)
-      this._enumerateChildren(rootNode.children[i], result, maxLevel - 1);
-    return result;
-  }
-
-  onResize() {
-    this.updateWidths();
-  }
-
-  // Updates the widths of the table, including the positions of the column
-  // resizers.
-  //
-  // IMPORTANT: This function MUST be called once after the element of the
-  // DataGrid is attached to its parent element and every subsequent time the
-  // width of the parent element is changed in order to make it possible to
-  // resize the columns.
-  //
-  // If this function is not called after the DataGrid is attached to its
-  // parent element, then the DataGrid's columns will not be resizable.
-  updateWidths() {
-    // Do not attempt to use offsetes if we're not attached to the document tree yet.
-    if (!this._columnWidthsInitialized && this.element.offsetWidth) {
-      // Give all the columns initial widths now so that during a resize,
-      // when the two columns that get resized get a percent value for
-      // their widths, all the other columns already have percent values
-      // for their widths.
-
-      // Use container size to avoid changes of table width caused by change of column widths.
-      const tableWidth = this.element.offsetWidth - this._cornerWidth;
-      const cells = this._headerTableBody.rows[0].cells;
-      const numColumns = cells.length - 1;  // Do not process corner column.
-      for (let i = 0; i < numColumns; i++) {
-        const column = this._visibleColumnsArray[i];
-        if (!column.weight)
-          column.weight = 100 * cells[i].offsetWidth / tableWidth || 10;
-      }
-      this._columnWidthsInitialized = true;
-    }
-    this._applyColumnWeights();
-  }
-
-  /**
-   * @param {string} name
-   */
-  setName(name) {
-    this._columnWeightsSetting = Common.settings.createSetting('dataGrid-' + name + '-columnWeights', {});
-    this._loadColumnWeights();
-  }
-
-  _loadColumnWeights() {
-    if (!this._columnWeightsSetting)
-      return;
-    const weights = this._columnWeightsSetting.get();
-    for (let i = 0; i < this._columnsArray.length; ++i) {
-      const column = this._columnsArray[i];
-      const weight = weights[column.id];
-      if (weight)
-        column.weight = weight;
-    }
-    this._applyColumnWeights();
-  }
-
-  _saveColumnWeights() {
-    if (!this._columnWeightsSetting)
-      return;
-    const weights = {};
-    for (let i = 0; i < this._columnsArray.length; ++i) {
-      const column = this._columnsArray[i];
-      weights[column.id] = column.weight;
-    }
-    this._columnWeightsSetting.set(weights);
-  }
-
-  wasShown() {
-    this._loadColumnWeights();
-  }
-
-  willHide() {
-  }
-
-  _applyColumnWeights() {
-    let tableWidth = this.element.offsetWidth - this._cornerWidth;
-    if (tableWidth <= 0)
-      return;
-
-    let sumOfWeights = 0.0;
-    const fixedColumnWidths = [];
-    for (let i = 0; i < this._visibleColumnsArray.length; ++i) {
-      const column = this._visibleColumnsArray[i];
-      if (column.fixedWidth) {
-        const width = this._headerTableColumnGroup.children[i][DataGrid.DataGrid._preferredWidthSymbol] ||
-            this._headerTableBody.rows[0].cells[i].offsetWidth;
-        fixedColumnWidths[i] = width;
-        tableWidth -= width;
-      } else {
-        sumOfWeights += this._visibleColumnsArray[i].weight;
-      }
-    }
-    let sum = 0;
-    let lastOffset = 0;
-
-    for (let i = 0; i < this._visibleColumnsArray.length; ++i) {
-      const column = this._visibleColumnsArray[i];
-      let width;
-      if (column.fixedWidth) {
-        width = fixedColumnWidths[i];
-      } else {
-        sum += column.weight;
-        const offset = (sum * tableWidth / sumOfWeights) | 0;
-        width = offset - lastOffset;
-        lastOffset = offset;
-      }
-      this._setPreferredWidth(i, width);
-    }
-
-    this._positionResizers();
-  }
-
-  /**
-   * @param {!Object.<string, boolean>} columnsVisibility
-   */
-  setColumnsVisiblity(columnsVisibility) {
-    this._visibleColumnsArray = [];
-    for (let i = 0; i < this._columnsArray.length; ++i) {
-      const column = this._columnsArray[i];
-      if (columnsVisibility[column.id])
-        this._visibleColumnsArray.push(column);
-    }
-    this._refreshHeader();
-    this._applyColumnWeights();
-    const nodes = this._enumerateChildren(this.rootNode(), [], -1);
-    for (let i = 0; i < nodes.length; ++i)
-      nodes[i].refresh();
-  }
-
-  get scrollContainer() {
-    return this._scrollContainer;
-  }
-
-  _positionResizers() {
-    const headerTableColumns = this._headerTableColumnGroup.children;
-    const numColumns = headerTableColumns.length - 1;  // Do not process corner column.
-    const left = [];
-    const resizers = this._resizers;
-
-    while (resizers.length > numColumns - 1)
-      resizers.pop().remove();
-
-    for (let i = 0; i < numColumns - 1; i++) {
-      // Get the width of the cell in the first (and only) row of the
-      // header table in order to determine the width of the column, since
-      // it is not possible to query a column for its width.
-      left[i] = (left[i - 1] || 0) + this._headerTableBody.rows[0].cells[i].offsetWidth;
-    }
-
-    // Make n - 1 resizers for n columns.
-    for (let i = 0; i < numColumns - 1; i++) {
-      let resizer = resizers[i];
-      if (!resizer) {
-        // This is the first call to updateWidth, so the resizers need
-        // to be created.
-        resizer = createElement('div');
-        resizer.__index = i;
-        resizer.classList.add('data-grid-resizer');
-        // This resizer is associated with the column to its right.
-        UI.installDragHandle(
-            resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this),
-            this._endResizerDragging.bind(this), 'col-resize');
-        this.element.appendChild(resizer);
-        resizers.push(resizer);
-      }
-      if (resizer.__position !== left[i]) {
-        resizer.__position = left[i];
-        resizer.style.left = left[i] + 'px';
-      }
-    }
-  }
-
-  addCreationNode(hasChildren) {
-    if (this.creationNode)
-      this.creationNode.makeNormal();
-
-    const emptyData = {};
-    for (const column in this._columns)
-      emptyData[column] = null;
-    this.creationNode = new DataGrid.CreationDataGridNode(emptyData, hasChildren);
-    this.rootNode().appendChild(this.creationNode);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _keyDown(event) {
-    if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing)
-      return;
-
-    let handled = false;
-    let nextSelectedNode;
-    if (event.key === 'ArrowUp' && !event.altKey) {
-      nextSelectedNode = this.selectedNode.traversePreviousNode(true);
-      while (nextSelectedNode && !nextSelectedNode.selectable)
-        nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
-      handled = nextSelectedNode ? true : false;
-    } else if (event.key === 'ArrowDown' && !event.altKey) {
-      nextSelectedNode = this.selectedNode.traverseNextNode(true);
-      while (nextSelectedNode && !nextSelectedNode.selectable)
-        nextSelectedNode = nextSelectedNode.traverseNextNode(true);
-      handled = nextSelectedNode ? true : false;
-    } else if (event.key === 'ArrowLeft') {
-      if (this.selectedNode.expanded) {
-        if (event.altKey)
-          this.selectedNode.collapseRecursively();
-        else
-          this.selectedNode.collapse();
-        handled = true;
-      } else if (this.selectedNode.parent && !this.selectedNode.parent._isRoot) {
-        handled = true;
-        if (this.selectedNode.parent.selectable) {
-          nextSelectedNode = this.selectedNode.parent;
-          handled = nextSelectedNode ? true : false;
-        } else if (this.selectedNode.parent) {
-          this.selectedNode.parent.collapse();
-        }
-      }
-    } else if (event.key === 'ArrowRight') {
-      if (!this.selectedNode.revealed) {
-        this.selectedNode.reveal();
-        handled = true;
-      } else if (this.selectedNode.hasChildren()) {
-        handled = true;
-        if (this.selectedNode.expanded) {
-          nextSelectedNode = this.selectedNode.children[0];
-          handled = nextSelectedNode ? true : false;
-        } else {
-          if (event.altKey)
-            this.selectedNode.expandRecursively();
-          else
-            this.selectedNode.expand();
-        }
-      }
-    } else if (event.keyCode === 8 || event.keyCode === 46) {
-      if (this._deleteCallback) {
-        handled = true;
-        this._deleteCallback(this.selectedNode);
-      }
-    } else if (isEnterKey(event)) {
-      if (this._editCallback) {
-        handled = true;
-        this._startEditing(this.selectedNode._element.children[this._nextEditableColumn(-1)]);
-      } else {
-        this.dispatchEventToListeners(DataGrid.DataGrid.Events.OpenedNode, this.selectedNode);
-      }
-    }
-
-    if (nextSelectedNode) {
-      nextSelectedNode.reveal();
-      nextSelectedNode.select();
-    }
-    if (handled)
-      event.consume(true);
-  }
-
-  /**
-   * @param {?NODE_TYPE} root
-   * @param {boolean} onlyAffectsSubtree
-   */
-  updateSelectionBeforeRemoval(root, onlyAffectsSubtree) {
-    let ancestor = this.selectedNode;
-    while (ancestor && ancestor !== root)
-      ancestor = ancestor.parent;
-    // Selection is not in the subtree being deleted.
-    if (!ancestor)
-      return;
-
-    let nextSelectedNode;
-    // Skip subtree being deleted when looking for the next selectable node.
-    for (ancestor = root; ancestor && !ancestor.nextSibling; ancestor = ancestor.parent) {
-    }
-    if (ancestor)
-      nextSelectedNode = ancestor.nextSibling;
-    while (nextSelectedNode && !nextSelectedNode.selectable)
-      nextSelectedNode = nextSelectedNode.traverseNextNode(true);
-
-    if (!nextSelectedNode || nextSelectedNode.isCreationNode) {
-      nextSelectedNode = root.traversePreviousNode(true);
-      while (nextSelectedNode && !nextSelectedNode.selectable)
-        nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
-    }
-    if (nextSelectedNode) {
-      nextSelectedNode.reveal();
-      nextSelectedNode.select();
-    } else {
-      this.selectedNode.deselect();
-    }
-  }
-
-  /**
-   * @param {!Node} target
-   * @return {?NODE_TYPE}
-   */
-  dataGridNodeFromNode(target) {
-    const rowElement = target.enclosingNodeOrSelfWithNodeName('tr');
-    return rowElement && rowElement._dataGridNode;
-  }
-
-  /**
-   * @param {!Node} target
-   * @return {?string}
-   */
-  columnIdFromNode(target) {
-    const cellElement = target.enclosingNodeOrSelfWithNodeName('td');
-    return cellElement && cellElement[DataGrid.DataGrid._columnIdSymbol];
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _clickInHeaderCell(event) {
-    const cell = event.target.enclosingNodeOrSelfWithNodeName('th');
-    if (!cell || (cell[DataGrid.DataGrid._columnIdSymbol] === undefined) || !cell.classList.contains('sortable'))
-      return;
-
-    let sortOrder = DataGrid.DataGrid.Order.Ascending;
-    if ((cell === this._sortColumnCell) && this.isSortOrderAscending())
-      sortOrder = DataGrid.DataGrid.Order.Descending;
-
-    if (this._sortColumnCell)
-      this._sortColumnCell.classList.remove(DataGrid.DataGrid.Order.Ascending, DataGrid.DataGrid.Order.Descending);
-    this._sortColumnCell = cell;
-
-    cell.classList.add(sortOrder);
-    const icon = cell[DataGrid.DataGrid._sortIconSymbol];
-    icon.setIconType(
-        sortOrder === DataGrid.DataGrid.Order.Ascending ? 'smallicon-triangle-up' : 'smallicon-triangle-down');
-
-    this.dispatchEventToListeners(DataGrid.DataGrid.Events.SortingChanged);
-  }
-
-  /**
-   * @param {string} columnId
-   * @param {!DataGrid.DataGrid.Order} sortOrder
-   */
-  markColumnAsSortedBy(columnId, sortOrder) {
-    if (this._sortColumnCell)
-      this._sortColumnCell.classList.remove(DataGrid.DataGrid.Order.Ascending, DataGrid.DataGrid.Order.Descending);
-    this._sortColumnCell = this._headerTableHeaders[columnId];
-    this._sortColumnCell.classList.add(sortOrder);
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  headerTableHeader(columnId) {
-    return this._headerTableHeaders[columnId];
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseDownInDataTable(event) {
-    const target = /** @type {!Node} */ (event.target);
-    const gridNode = this.dataGridNodeFromNode(target);
-    if (!gridNode || !gridNode.selectable || gridNode.isEventWithinDisclosureTriangle(event))
-      return;
-
-    const columnId = this.columnIdFromNode(target);
-    if (columnId && this._columns[columnId].nonSelectable)
-      return;
-
-    if (event.metaKey) {
-      if (gridNode.selected)
-        gridNode.deselect();
-      else
-        gridNode.select();
-    } else {
-      gridNode.select();
-      this.dispatchEventToListeners(DataGrid.DataGrid.Events.OpenedNode, gridNode);
-    }
-  }
-
-  /**
-   * @param {?function(!UI.ContextMenu)} callback
-   */
-  setHeaderContextMenuCallback(callback) {
-    this._headerContextMenuCallback = callback;
-  }
-
-  /**
-   * @param {?function(!UI.ContextMenu, !NODE_TYPE)} callback
-   */
-  setRowContextMenuCallback(callback) {
-    this._rowContextMenuCallback = callback;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _contextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    const target = /** @type {!Node} */ (event.target);
-
-    if (target.isSelfOrDescendant(this._headerTableBody)) {
-      if (this._headerContextMenuCallback)
-        this._headerContextMenuCallback(contextMenu);
-      return;
-    }
-
-    const gridNode = this.dataGridNodeFromNode(target);
-    if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode))
-      contextMenu.defaultSection().appendItem(Common.UIString('Refresh'), this._refreshCallback.bind(this));
-
-    if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {
-      if (this._editCallback) {
-        if (gridNode === this.creationNode) {
-          contextMenu.defaultSection().appendItem(Common.UIString('Add new'), this._startEditing.bind(this, target));
-        } else {
-          const columnId = this.columnIdFromNode(target);
-          if (columnId && this._columns[columnId].editable) {
-            contextMenu.defaultSection().appendItem(
-                Common.UIString('Edit "%s"', this._columns[columnId].title), this._startEditing.bind(this, target));
-          }
-        }
-      }
-      if (this._deleteCallback && gridNode !== this.creationNode)
-        contextMenu.defaultSection().appendItem(Common.UIString('Delete'), this._deleteCallback.bind(this, gridNode));
-      if (this._rowContextMenuCallback)
-        this._rowContextMenuCallback(contextMenu, gridNode);
-    }
-
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _clickInDataTable(event) {
-    const gridNode = this.dataGridNodeFromNode(/** @type {!Node} */ (event.target));
-    if (!gridNode || !gridNode.hasChildren() || !gridNode.isEventWithinDisclosureTriangle(event))
-      return;
-
-    if (gridNode.expanded) {
-      if (event.altKey)
-        gridNode.collapseRecursively();
-      else
-        gridNode.collapse();
-    } else {
-      if (event.altKey)
-        gridNode.expandRecursively();
-      else
-        gridNode.expand();
-    }
-  }
-
-  /**
-   * @param {!DataGrid.DataGrid.ResizeMethod} method
-   */
-  setResizeMethod(method) {
-    this._resizeMethod = method;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _startResizerDragging(event) {
-    this._currentResizer = event.target;
-    return true;
-  }
-
-  _endResizerDragging() {
-    this._currentResizer = null;
-    this._saveColumnWeights();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _resizerDragging(event) {
-    const resizer = this._currentResizer;
-    if (!resizer)
-      return;
-
-    // Constrain the dragpoint to be within the containing div of the
-    // datagrid.
-    let dragPoint = event.clientX - this.element.totalOffsetLeft();
-    const firstRowCells = this._headerTableBody.rows[0].cells;
-    let leftEdgeOfPreviousColumn = 0;
-    // Constrain the dragpoint to be within the space made up by the
-    // column directly to the left and the column directly to the right.
-    let leftCellIndex = resizer.__index;
-    let rightCellIndex = leftCellIndex + 1;
-    for (let i = 0; i < leftCellIndex; i++)
-      leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;
-
-    // Differences for other resize methods
-    if (this._resizeMethod === DataGrid.DataGrid.ResizeMethod.Last) {
-      rightCellIndex = this._resizers.length;
-    } else if (this._resizeMethod === DataGrid.DataGrid.ResizeMethod.First) {
-      leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
-      leftCellIndex = 0;
-    }
-
-    const rightEdgeOfNextColumn =
-        leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth;
-
-    // Give each column some padding so that they don't disappear.
-    const leftMinimum = leftEdgeOfPreviousColumn + DataGrid.DataGrid.ColumnResizePadding;
-    const rightMaximum = rightEdgeOfNextColumn - DataGrid.DataGrid.ColumnResizePadding;
-    if (leftMinimum > rightMaximum)
-      return;
-
-    dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);
-
-    const position = (dragPoint - DataGrid.DataGrid.CenterResizerOverBorderAdjustment);
-    resizer.__position = position;
-    resizer.style.left = position + 'px';
-
-    this._setPreferredWidth(leftCellIndex, dragPoint - leftEdgeOfPreviousColumn);
-    this._setPreferredWidth(rightCellIndex, rightEdgeOfNextColumn - dragPoint);
-
-    const leftColumn = this._visibleColumnsArray[leftCellIndex];
-    const rightColumn = this._visibleColumnsArray[rightCellIndex];
-    if (leftColumn.weight || rightColumn.weight) {
-      const sumOfWeights = leftColumn.weight + rightColumn.weight;
-      const delta = rightEdgeOfNextColumn - leftEdgeOfPreviousColumn;
-      leftColumn.weight = (dragPoint - leftEdgeOfPreviousColumn) * sumOfWeights / delta;
-      rightColumn.weight = (rightEdgeOfNextColumn - dragPoint) * sumOfWeights / delta;
-    }
-
-    this._positionResizers();
-    event.preventDefault();
-  }
-
-  /**
-   * @param {number} columnIndex
-   * @param {number} width
-   */
-  _setPreferredWidth(columnIndex, width) {
-    const pxWidth = width + 'px';
-    this._headerTableColumnGroup.children[columnIndex][DataGrid.DataGrid._preferredWidthSymbol] = width;
-    this._headerTableColumnGroup.children[columnIndex].style.width = pxWidth;
-    this._dataTableColumnGroup.children[columnIndex].style.width = pxWidth;
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {number}
-   */
-  columnOffset(columnId) {
-    if (!this.element.offsetWidth)
-      return 0;
-    for (let i = 1; i < this._visibleColumnsArray.length; ++i) {
-      if (columnId === this._visibleColumnsArray[i].id) {
-        if (this._resizers[i - 1])
-          return this._resizers[i - 1].__position;
-      }
-    }
-    return 0;
-  }
-
-  /**
-   * @return {!DataGrid.DataGridWidget}
-   */
-  asWidget() {
-    if (!this._dataGridWidget)
-      this._dataGridWidget = new DataGrid.DataGridWidget(this);
-    return this._dataGridWidget;
-  }
-
-  topFillerRowElement() {
-    return this._topFillerRow;
-  }
-};
-
-// Keep in sync with .data-grid col.corner style rule.
-DataGrid.DataGrid.CornerWidth = 14;
-
-/**
- * @typedef {{
- *   id: string,
- *   title: (string|undefined),
- *   titleDOMFragment: (?DocumentFragment|undefined),
- *   sortable: boolean,
- *   sort: (?DataGrid.DataGrid.Order|undefined),
- *   align: (?DataGrid.DataGrid.Align|undefined),
- *   fixedWidth: (boolean|undefined),
- *   editable: (boolean|undefined),
- *   nonSelectable: (boolean|undefined),
- *   longText: (boolean|undefined),
- *   disclosure: (boolean|undefined),
- *   weight: (number|undefined)
- * }}
- */
-DataGrid.DataGrid.ColumnDescriptor;
-
-/** @enum {symbol} */
-DataGrid.DataGrid.Events = {
-  SelectedNode: Symbol('SelectedNode'),
-  DeselectedNode: Symbol('DeselectedNode'),
-  OpenedNode: Symbol('OpenedNode'),
-  SortingChanged: Symbol('SortingChanged'),
-  PaddingChanged: Symbol('PaddingChanged'),
-};
-
-/** @enum {string} */
-DataGrid.DataGrid.Order = {
-  Ascending: 'sort-ascending',
-  Descending: 'sort-descending'
-};
-
-/** @enum {string} */
-DataGrid.DataGrid.Align = {
-  Center: 'center',
-  Right: 'right'
-};
-
-DataGrid.DataGrid._preferredWidthSymbol = Symbol('preferredWidth');
-DataGrid.DataGrid._columnIdSymbol = Symbol('columnId');
-DataGrid.DataGrid._sortIconSymbol = Symbol('sortIcon');
-DataGrid.DataGrid._longTextSymbol = Symbol('longText');
-
-DataGrid.DataGrid.ColumnResizePadding = 24;
-DataGrid.DataGrid.CenterResizerOverBorderAdjustment = 3;
-
-/** @enum {string} */
-DataGrid.DataGrid.ResizeMethod = {
-  Nearest: 'nearest',
-  First: 'first',
-  Last: 'last'
-};
-
-/**
- * @unrestricted
- * @template NODE_TYPE
- */
-DataGrid.DataGridNode = class extends Common.Object {
-  /**
-   * @param {?Object.<string, *>=} data
-   * @param {boolean=} hasChildren
-   */
-  constructor(data, hasChildren) {
-    super();
-    /** @type {?Element} */
-    this._element = null;
-    /** @type {boolean} */
-    this._expanded = false;
-    /** @type {boolean} */
-    this._selected = false;
-    /** @type {boolean} */
-    this._dirty = false;
-    /** @type {boolean} */
-    this._inactive = false;
-    /** @type {number|undefined} */
-    this._depth;
-    /** @type {boolean|undefined} */
-    this._revealed;
-    /** @type {boolean} */
-    this._attached = false;
-    /** @type {?{parent: !NODE_TYPE, index: number}} */
-    this._savedPosition = null;
-    /** @type {boolean} */
-    this._shouldRefreshChildren = true;
-    /** @type {!Object.<string, *>} */
-    this._data = data || {};
-    /** @type {boolean} */
-    this._hasChildren = hasChildren || false;
-    /** @type {!Array.<!NODE_TYPE>} */
-    this.children = [];
-    /** @type {?DataGrid.DataGrid} */
-    this.dataGrid = null;
-    /** @type {?NODE_TYPE} */
-    this.parent = null;
-    /** @type {?NODE_TYPE} */
-    this.previousSibling = null;
-    /** @type {?NODE_TYPE} */
-    this.nextSibling = null;
-    /** @type {number} */
-    this.disclosureToggleWidth = 10;
-
-    /** @type {boolean} */
-    this.selectable = true;
-
-    /** @type {boolean} */
-    this._isRoot = false;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    if (!this._element) {
-      const element = this.createElement();
-      this.createCells(element);
-    }
-    return /** @type {!Element} */ (this._element);
-  }
-
-  /**
-   * @protected
-   * @return {!Element}
-   */
-  createElement() {
-    this._element = createElementWithClass('tr', 'data-grid-data-grid-node');
-    this._element._dataGridNode = this;
-
-    if (this._hasChildren)
-      this._element.classList.add('parent');
-    if (this.expanded)
-      this._element.classList.add('expanded');
-    if (this.selected)
-      this._element.classList.add('selected');
-    if (this.revealed)
-      this._element.classList.add('revealed');
-    if (this.dirty)
-      this._element.classList.add('dirty');
-    if (this.inactive)
-      this._element.classList.add('inactive');
-    return this._element;
-  }
-
-  /**
-   * @return {?Element}
-   */
-  existingElement() {
-    return this._element || null;
-  }
-
-  /**
-   * @protected
-   */
-  resetElement() {
-    this._element = null;
-  }
-
-  /**
-   * @param {!Element} element
-   * @protected
-   */
-  createCells(element) {
-    element.removeChildren();
-    const columnsArray = this.dataGrid._visibleColumnsArray;
-    for (let i = 0; i < columnsArray.length; ++i)
-      element.appendChild(this.createCell(columnsArray[i].id));
-    element.appendChild(this._createTDWithClass('corner'));
-  }
-
-  /**
-   * @return {!Object.<string, *>}
-   */
-  get data() {
-    return this._data;
-  }
-
-  /**
-   * @param {!Object.<string, *>} x
-   */
-  set data(x) {
-    this._data = x || {};
-    this.refresh();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get revealed() {
-    if (this._revealed !== undefined)
-      return this._revealed;
-
-    let currentAncestor = this.parent;
-    while (currentAncestor && !currentAncestor._isRoot) {
-      if (!currentAncestor.expanded) {
-        this._revealed = false;
-        return false;
-      }
-
-      currentAncestor = currentAncestor.parent;
-    }
-
-    this.revealed = true;
-    return true;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set revealed(x) {
-    if (this._revealed === x)
-      return;
-
-    this._revealed = x;
-
-    if (this._element)
-      this._element.classList.toggle('revealed', this._revealed);
-
-    for (let i = 0; i < this.children.length; ++i)
-      this.children[i].revealed = x && this.expanded;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDirty() {
-    return this._dirty;
-  }
-
-  /**
-   * @param {boolean} dirty
-   */
-  setDirty(dirty) {
-    if (this._dirty === dirty)
-      return;
-    this._dirty = dirty;
-    if (!this._element)
-      return;
-    if (dirty)
-      this._element.classList.add('dirty');
-    else
-      this._element.classList.remove('dirty');
-  }
-
-
-  /**
-   * @return {boolean}
-   */
-  isInactive() {
-    return this._inactive;
-  }
-
-  /**
-   * @param {boolean} inactive
-   */
-  setInactive(inactive) {
-    if (this._inactive === inactive)
-      return;
-    this._inactive = inactive;
-    if (!this._element)
-      return;
-    if (inactive)
-      this._element.classList.add('inactive');
-    else
-      this._element.classList.remove('inactive');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasChildren() {
-    return this._hasChildren;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  setHasChildren(x) {
-    if (this._hasChildren === x)
-      return;
-
-    this._hasChildren = x;
-
-    if (!this._element)
-      return;
-
-    this._element.classList.toggle('parent', this._hasChildren);
-    this._element.classList.toggle('expanded', this._hasChildren && this.expanded);
-  }
-
-  /**
-   * @return {number}
-   */
-  get depth() {
-    if (this._depth !== undefined)
-      return this._depth;
-    if (this.parent && !this.parent._isRoot)
-      this._depth = this.parent.depth + 1;
-    else
-      this._depth = 0;
-    return this._depth;
-  }
-
-  /**
-   * @return {number}
-   */
-  get leftPadding() {
-    return this.depth * this.dataGrid.indentWidth;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get shouldRefreshChildren() {
-    return this._shouldRefreshChildren;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set shouldRefreshChildren(x) {
-    this._shouldRefreshChildren = x;
-    if (x && this.expanded)
-      this.expand();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get selected() {
-    return this._selected;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set selected(x) {
-    if (x)
-      this.select();
-    else
-      this.deselect();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get expanded() {
-    return this._expanded;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set expanded(x) {
-    if (x)
-      this.expand();
-    else
-      this.collapse();
-  }
-
-  refresh() {
-    if (!this.dataGrid)
-      this._element = null;
-    if (!this._element)
-      return;
-    this.createCells(this._element);
-  }
-
-  /**
-   * @param {string} className
-   * @return {!Element}
-   */
-  _createTDWithClass(className) {
-    const cell = createElementWithClass('td', className);
-    const cellClass = this.dataGrid._cellClass;
-    if (cellClass)
-      cell.classList.add(cellClass);
-    return cell;
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createTD(columnId) {
-    const cell = this._createTDWithClass(columnId + '-column');
-    cell[DataGrid.DataGrid._columnIdSymbol] = columnId;
-
-    const alignment = this.dataGrid._columns[columnId].align;
-    if (alignment)
-      cell.classList.add(alignment);
-
-    if (columnId === this.dataGrid.disclosureColumnId) {
-      cell.classList.add('disclosure');
-      if (this.leftPadding)
-        cell.style.setProperty('padding-left', this.leftPadding + 'px');
-    }
-
-    return cell;
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = this.createTD(columnId);
-
-    const data = this.data[columnId];
-    if (data instanceof Node)
-      cell.appendChild(data);
-    else if (data !== null)
-      DataGrid.DataGrid.setElementText(cell, /** @type {string} */ (data), !!this.dataGrid._columns[columnId].longText);
-
-    return cell;
-  }
-
-  /**
-   * @return {number}
-   */
-  nodeSelfHeight() {
-    return 20;
-  }
-
-  /**
-   * @param {!NODE_TYPE} child
-   */
-  appendChild(child) {
-    this.insertChild(child, this.children.length);
-  }
-
-  /**
-   * @param {boolean=} onlyCaches
-   */
-  resetNode(onlyCaches) {
-    // @TODO(allada) This is a hack to make sure ViewportDataGrid can clean up these caches. Try Not To Use.
-    delete this._depth;
-    delete this._revealed;
-    if (onlyCaches)
-      return;
-    if (this.previousSibling)
-      this.previousSibling.nextSibling = this.nextSibling;
-    if (this.nextSibling)
-      this.nextSibling.previousSibling = this.previousSibling;
-    this.dataGrid = null;
-    this.parent = null;
-    this.nextSibling = null;
-    this.previousSibling = null;
-    this._attached = false;
-  }
-
-  /**
-   * @param {!NODE_TYPE} child
-   * @param {number} index
-   */
-  insertChild(child, index) {
-    if (!child)
-      throw 'insertChild: Node can\'t be undefined or null.';
-    if (child.parent === this) {
-      const currentIndex = this.children.indexOf(child);
-      if (currentIndex < 0)
-        console.assert(false, 'Inconsistent DataGrid state');
-      if (currentIndex === index)
-        return;
-      if (currentIndex < index)
-        --index;
-    }
-
-    child.remove();
-
-    this.children.splice(index, 0, child);
-    this.setHasChildren(true);
-
-    child.parent = this;
-    child.dataGrid = this.dataGrid;
-    child.recalculateSiblings(index);
-
-    child._shouldRefreshChildren = true;
-
-    let current = child.children[0];
-    while (current) {
-      current.resetNode(true);
-      current.dataGrid = this.dataGrid;
-      current._attached = false;
-      current._shouldRefreshChildren = true;
-      current = current.traverseNextNode(false, child, true);
-    }
-
-    if (this.expanded)
-      child._attach();
-    if (!this.revealed)
-      child.revealed = false;
-  }
-
-  remove() {
-    if (this.parent)
-      this.parent.removeChild(this);
-  }
-
-  /**
-   * @param {!NODE_TYPE} child
-   */
-  removeChild(child) {
-    if (!child)
-      throw 'removeChild: Node can\'t be undefined or null.';
-    if (child.parent !== this)
-      throw 'removeChild: Node is not a child of this node.';
-
-    if (this.dataGrid)
-      this.dataGrid.updateSelectionBeforeRemoval(child, false);
-
-    child._detach();
-    child.resetNode();
-    this.children.remove(child, true);
-
-    if (this.children.length <= 0)
-      this.setHasChildren(false);
-  }
-
-  removeChildren() {
-    if (this.dataGrid)
-      this.dataGrid.updateSelectionBeforeRemoval(this, true);
-    for (let i = 0; i < this.children.length; ++i) {
-      const child = this.children[i];
-      child._detach();
-      child.resetNode();
-    }
-
-    this.children = [];
-    this.setHasChildren(false);
-  }
-
-  /**
-   * @param {number} myIndex
-   */
-  recalculateSiblings(myIndex) {
-    if (!this.parent)
-      return;
-
-    const previousChild = this.parent.children[myIndex - 1] || null;
-    if (previousChild)
-      previousChild.nextSibling = this;
-    this.previousSibling = previousChild;
-
-    const nextChild = this.parent.children[myIndex + 1] || null;
-    if (nextChild)
-      nextChild.previousSibling = this;
-    this.nextSibling = nextChild;
-  }
-
-  collapse() {
-    if (this._isRoot)
-      return;
-    if (this._element)
-      this._element.classList.remove('expanded');
-
-    this._expanded = false;
-
-    for (let i = 0; i < this.children.length; ++i)
-      this.children[i].revealed = false;
-  }
-
-  collapseRecursively() {
-    let item = this;
-    while (item) {
-      if (item.expanded)
-        item.collapse();
-      item = item.traverseNextNode(false, this, true);
-    }
-  }
-
-  populate() {
-  }
-
-  expand() {
-    if (!this._hasChildren || this.expanded)
-      return;
-    if (this._isRoot)
-      return;
-
-    if (this.revealed && !this._shouldRefreshChildren) {
-      for (let i = 0; i < this.children.length; ++i)
-        this.children[i].revealed = true;
-    }
-
-    if (this._shouldRefreshChildren) {
-      for (let i = 0; i < this.children.length; ++i)
-        this.children[i]._detach();
-
-      this.populate();
-
-      if (this._attached) {
-        for (let i = 0; i < this.children.length; ++i) {
-          const child = this.children[i];
-          if (this.revealed)
-            child.revealed = true;
-          child._attach();
-        }
-      }
-
-      this._shouldRefreshChildren = false;
-    }
-
-    if (this._element)
-      this._element.classList.add('expanded');
-
-    this._expanded = true;
-  }
-
-  expandRecursively() {
-    let item = this;
-    while (item) {
-      item.expand();
-      item = item.traverseNextNode(false, this);
-    }
-  }
-
-  reveal() {
-    if (this._isRoot)
-      return;
-    let currentAncestor = this.parent;
-    while (currentAncestor && !currentAncestor._isRoot) {
-      if (!currentAncestor.expanded)
-        currentAncestor.expand();
-      currentAncestor = currentAncestor.parent;
-    }
-
-    this.element().scrollIntoViewIfNeeded(false);
-  }
-
-  /**
-   * @param {boolean=} supressSelectedEvent
-   */
-  select(supressSelectedEvent) {
-    if (!this.dataGrid || !this.selectable || this.selected)
-      return;
-
-    if (this.dataGrid.selectedNode)
-      this.dataGrid.selectedNode.deselect();
-
-    this._selected = true;
-    this.dataGrid.selectedNode = this;
-
-    if (this._element)
-      this._element.classList.add('selected');
-
-    if (!supressSelectedEvent)
-      this.dataGrid.dispatchEventToListeners(DataGrid.DataGrid.Events.SelectedNode, this);
-  }
-
-  revealAndSelect() {
-    if (this._isRoot)
-      return;
-    this.reveal();
-    this.select();
-  }
-
-  /**
-   * @param {boolean=} supressDeselectedEvent
-   */
-  deselect(supressDeselectedEvent) {
-    if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
-      return;
-
-    this._selected = false;
-    this.dataGrid.selectedNode = null;
-
-    if (this._element)
-      this._element.classList.remove('selected');
-
-    if (!supressDeselectedEvent)
-      this.dataGrid.dispatchEventToListeners(DataGrid.DataGrid.Events.DeselectedNode);
-  }
-
-  /**
-   * @param {boolean} skipHidden
-   * @param {?NODE_TYPE=} stayWithin
-   * @param {boolean=} dontPopulate
-   * @param {!Object=} info
-   * @return {?NODE_TYPE}
-   */
-  traverseNextNode(skipHidden, stayWithin, dontPopulate, info) {
-    if (!dontPopulate && this._hasChildren)
-      this.populate();
-
-    if (info)
-      info.depthChange = 0;
-
-    let node = (!skipHidden || this.revealed) ? this.children[0] : null;
-    if (node && (!skipHidden || this.expanded)) {
-      if (info)
-        info.depthChange = 1;
-      return node;
-    }
-
-    if (this === stayWithin)
-      return null;
-
-    node = (!skipHidden || this.revealed) ? this.nextSibling : null;
-    if (node)
-      return node;
-
-    node = this;
-    while (node && !node._isRoot && !((!skipHidden || node.revealed) ? node.nextSibling : null) &&
-           node.parent !== stayWithin) {
-      if (info)
-        info.depthChange -= 1;
-      node = node.parent;
-    }
-
-    if (!node)
-      return null;
-
-    return (!skipHidden || node.revealed) ? node.nextSibling : null;
-  }
-
-  /**
-   * @param {boolean} skipHidden
-   * @param {boolean=} dontPopulate
-   * @return {?NODE_TYPE}
-   */
-  traversePreviousNode(skipHidden, dontPopulate) {
-    let node = (!skipHidden || this.revealed) ? this.previousSibling : null;
-    if (!dontPopulate && node && node._hasChildren)
-      node.populate();
-
-    while (node &&
-           ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) {
-      if (!dontPopulate && node._hasChildren)
-        node.populate();
-      node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null);
-    }
-
-    if (node)
-      return node;
-
-    if (!this.parent || this.parent._isRoot)
-      return null;
-
-    return this.parent;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  isEventWithinDisclosureTriangle(event) {
-    if (!this._hasChildren)
-      return false;
-    const cell = event.target.enclosingNodeOrSelfWithNodeName('td');
-    if (!cell || !cell.classList.contains('disclosure'))
-      return false;
-
-    const left = cell.totalOffsetLeft() + this.leftPadding;
-    return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
-  }
-
-  _attach() {
-    if (!this.dataGrid || this._attached)
-      return;
-
-    this._attached = true;
-
-    const previousNode = this.traversePreviousNode(true, true);
-    const previousElement = previousNode ? previousNode.element() : this.dataGrid._topFillerRow;
-    this.dataGrid.dataTableBody.insertBefore(this.element(), previousElement.nextSibling);
-
-    if (this.expanded) {
-      for (let i = 0; i < this.children.length; ++i)
-        this.children[i]._attach();
-    }
-  }
-
-  _detach() {
-    if (!this._attached)
-      return;
-
-    this._attached = false;
-
-    if (this._element)
-      this._element.remove();
-
-    for (let i = 0; i < this.children.length; ++i)
-      this.children[i]._detach();
-  }
-
-  savePosition() {
-    if (this._savedPosition)
-      return;
-
-    if (!this.parent)
-      throw 'savePosition: Node must have a parent.';
-    this._savedPosition = {parent: this.parent, index: this.parent.children.indexOf(this)};
-  }
-
-  restorePosition() {
-    if (!this._savedPosition)
-      return;
-
-    if (this.parent !== this._savedPosition.parent)
-      this._savedPosition.parent.insertChild(this, this._savedPosition.index);
-
-    this._savedPosition = null;
-  }
-};
-
-/**
- * @unrestricted
- * @extends {DataGrid.DataGridNode<!NODE_TYPE>}
- * @template NODE_TYPE
- */
-DataGrid.CreationDataGridNode = class extends DataGrid.DataGridNode {
-  constructor(data, hasChildren) {
-    super(data, hasChildren);
-    /** @type {boolean} */
-    this.isCreationNode = true;
-  }
-
-  makeNormal() {
-    this.isCreationNode = false;
-  }
-};
-
-/**
- * @unrestricted
- */
-DataGrid.DataGridWidget = class extends UI.VBox {
-  /**
-   * @param {!DataGrid.DataGrid} dataGrid
-   */
-  constructor(dataGrid) {
-    super();
-    this._dataGrid = dataGrid;
-    this.element.appendChild(dataGrid.element);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._dataGrid.wasShown();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._dataGrid.willHide();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._dataGrid.onResize();
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [this._dataGrid._scrollContainer];
-  }
-
-  /**
-   * @override
-   */
-  detachChildWidgets() {
-    super.detachChildWidgets();
-    for (const dataGrid of this._dataGrids)
-      this.element.removeChild(dataGrid.element);
-    this._dataGrids = [];
-  }
-};
diff --git a/front_end/data_grid/ShowMoreDataGridNode.js b/front_end/data_grid/ShowMoreDataGridNode.js
deleted file mode 100644
index 0ac60d7..0000000
--- a/front_end/data_grid/ShowMoreDataGridNode.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-DataGrid.ShowMoreDataGridNode = class extends DataGrid.DataGridNode {
-  /**
-   * @param {function(number, number)} callback
-   * @param {number} startPosition
-   * @param {number} endPosition
-   * @param {number} chunkSize
-   */
-  constructor(callback, startPosition, endPosition, chunkSize) {
-    super({summaryRow: true}, false);
-    this._callback = callback;
-    this._startPosition = startPosition;
-    this._endPosition = endPosition;
-    this._chunkSize = chunkSize;
-
-    this.showNext = createElement('button');
-    this.showNext.setAttribute('type', 'button');
-    this.showNext.addEventListener('click', this._showNextChunk.bind(this), false);
-    this.showNext.textContent = Common.UIString('Show %d before', this._chunkSize);
-
-    this.showAll = createElement('button');
-    this.showAll.setAttribute('type', 'button');
-    this.showAll.addEventListener('click', this._showAll.bind(this), false);
-
-    this.showLast = createElement('button');
-    this.showLast.setAttribute('type', 'button');
-    this.showLast.addEventListener('click', this._showLastChunk.bind(this), false);
-    this.showLast.textContent = Common.UIString('Show %d after', this._chunkSize);
-
-    this._updateLabels();
-    this.selectable = false;
-  }
-
-  _showNextChunk() {
-    this._callback(this._startPosition, this._startPosition + this._chunkSize);
-  }
-
-  _showAll() {
-    this._callback(this._startPosition, this._endPosition);
-  }
-
-  _showLastChunk() {
-    this._callback(this._endPosition - this._chunkSize, this._endPosition);
-  }
-
-  _updateLabels() {
-    const totalSize = this._endPosition - this._startPosition;
-    if (totalSize > this._chunkSize) {
-      this.showNext.classList.remove('hidden');
-      this.showLast.classList.remove('hidden');
-    } else {
-      this.showNext.classList.add('hidden');
-      this.showLast.classList.add('hidden');
-    }
-    this.showAll.textContent = Common.UIString('Show all %d', totalSize);
-  }
-
-  /**
-   * @override
-   * @param {!Element} element
-   */
-  createCells(element) {
-    this._hasCells = false;
-    super.createCells(element);
-  }
-
-  /**
-   * @override
-   * @param {string} columnIdentifier
-   * @return {!Element}
-   */
-  createCell(columnIdentifier) {
-    const cell = this.createTD(columnIdentifier);
-    if (!this._hasCells) {
-      this._hasCells = true;
-      if (this.depth)
-        cell.style.setProperty('padding-left', (this.depth * this.dataGrid.indentWidth) + 'px');
-      cell.appendChild(this.showNext);
-      cell.appendChild(this.showAll);
-      cell.appendChild(this.showLast);
-    }
-    return cell;
-  }
-
-  /**
-   * @param {number} from
-   */
-  setStartPosition(from) {
-    this._startPosition = from;
-    this._updateLabels();
-  }
-
-  /**
-   * @param {number} to
-   */
-  setEndPosition(to) {
-    this._endPosition = to;
-    this._updateLabels();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  nodeSelfHeight() {
-    return 40;
-  }
-
-  dispose() {
-  }
-};
diff --git a/front_end/data_grid/SortableDataGrid.js b/front_end/data_grid/SortableDataGrid.js
deleted file mode 100644
index 56df121..0000000
--- a/front_end/data_grid/SortableDataGrid.js
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- * @extends {DataGrid.ViewportDataGrid<!NODE_TYPE>}
- * @template NODE_TYPE
- */
-DataGrid.SortableDataGrid = class extends DataGrid.ViewportDataGrid {
-  /**
-   * @param {!Array<!DataGrid.DataGrid.ColumnDescriptor>} columnsArray
-   * @param {function(!NODE_TYPE, string, string, string)=} editCallback
-   * @param {function(!NODE_TYPE)=} deleteCallback
-   * @param {function()=} refreshCallback
-   */
-  constructor(columnsArray, editCallback, deleteCallback, refreshCallback) {
-    super(columnsArray, editCallback, deleteCallback, refreshCallback);
-    /** @type {function(!NODE_TYPE, !NODE_TYPE):number} */
-    this._sortingFunction = DataGrid.SortableDataGrid.TrivialComparator;
-    this.setRootNode(/** @type {!DataGrid.SortableDataGridNode<!NODE_TYPE>} */ (new DataGrid.SortableDataGridNode()));
-  }
-
-  /**
-   * @param {!DataGrid.SortableDataGridNode} a
-   * @param {!DataGrid.SortableDataGridNode} b
-   * @return {number}
-   */
-  static TrivialComparator(a, b) {
-    return 0;
-  }
-
-  /**
-   * @param {string} columnId
-   * @param {!DataGrid.SortableDataGridNode} a
-   * @param {!DataGrid.SortableDataGridNode} b
-   * @return {number}
-   */
-  static NumericComparator(columnId, a, b) {
-    const aValue = a.data[columnId];
-    const bValue = b.data[columnId];
-    const aNumber = Number(aValue instanceof Node ? aValue.textContent : aValue);
-    const bNumber = Number(bValue instanceof Node ? bValue.textContent : bValue);
-    return aNumber < bNumber ? -1 : (aNumber > bNumber ? 1 : 0);
-  }
-
-  /**
-   * @param {string} columnId
-   * @param {!DataGrid.SortableDataGridNode} a
-   * @param {!DataGrid.SortableDataGridNode} b
-   * @return {number}
-   */
-  static StringComparator(columnId, a, b) {
-    const aValue = a.data[columnId];
-    const bValue = b.data[columnId];
-    const aString = aValue instanceof Node ? aValue.textContent : String(aValue);
-    const bString = bValue instanceof Node ? bValue.textContent : String(bValue);
-    return aString < bString ? -1 : (aString > bString ? 1 : 0);
-  }
-
-  /**
-   * @param {function(!NODE_TYPE, !NODE_TYPE):number} comparator
-   * @param {boolean} reverseMode
-   * @param {!NODE_TYPE} a
-   * @param {!NODE_TYPE} b
-   * @return {number}
-   * @template NODE_TYPE
-   */
-  static Comparator(comparator, reverseMode, a, b) {
-    return reverseMode ? comparator(b, a) : comparator(a, b);
-  }
-
-  /**
-   * @param {!Array.<string>} columnNames
-   * @param {!Array.<string>} values
-   * @return {?DataGrid.SortableDataGrid<!DataGrid.SortableDataGridNode>}
-   */
-  static create(columnNames, values) {
-    const numColumns = columnNames.length;
-    if (!numColumns)
-      return null;
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([]);
-    for (let i = 0; i < columnNames.length; ++i)
-      columns.push({id: String(i), title: columnNames[i], width: columnNames[i].length, sortable: true});
-
-    const nodes = [];
-    for (let i = 0; i < values.length / numColumns; ++i) {
-      const data = {};
-      for (let j = 0; j < columnNames.length; ++j)
-        data[j] = values[numColumns * i + j];
-
-      const node = new DataGrid.SortableDataGridNode(data);
-      node.selectable = false;
-      nodes.push(node);
-    }
-
-    const dataGrid = new DataGrid.SortableDataGrid(columns);
-    const length = nodes.length;
-    const rootNode = dataGrid.rootNode();
-    for (let i = 0; i < length; ++i)
-      rootNode.appendChild(nodes[i]);
-
-    dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, sortDataGrid);
-
-    function sortDataGrid() {
-      const nodes = dataGrid.rootNode().children;
-      const sortColumnId = dataGrid.sortColumnId();
-      if (!sortColumnId)
-        return;
-
-      let columnIsNumeric = true;
-      for (let i = 0; i < nodes.length; i++) {
-        const value = nodes[i].data[sortColumnId];
-        if (isNaN(value instanceof Node ? value.textContent : value)) {
-          columnIsNumeric = false;
-          break;
-        }
-      }
-
-      const comparator =
-          columnIsNumeric ? DataGrid.SortableDataGrid.NumericComparator : DataGrid.SortableDataGrid.StringComparator;
-      dataGrid.sortNodes(comparator.bind(null, sortColumnId), !dataGrid.isSortOrderAscending());
-    }
-    return dataGrid;
-  }
-
-  /**
-   * @param {!NODE_TYPE} node
-   */
-  insertChild(node) {
-    const root = /** @type {!DataGrid.SortableDataGridNode<!NODE_TYPE>} */ (this.rootNode());
-    root.insertChildOrdered(node);
-  }
-
-  /**
-   * @param {function(!NODE_TYPE, !NODE_TYPE):number} comparator
-   * @param {boolean} reverseMode
-   */
-  sortNodes(comparator, reverseMode) {
-    this._sortingFunction = DataGrid.SortableDataGrid.Comparator.bind(null, comparator, reverseMode);
-    this.rootNode().recalculateSiblings(0);
-    this.rootNode()._sortChildren(reverseMode);
-    this.scheduleUpdateStructure();
-  }
-};
-
-/**
- * @unrestricted
- * @extends {DataGrid.ViewportDataGridNode<!NODE_TYPE>}
- * @template NODE_TYPE
- */
-DataGrid.SortableDataGridNode = class extends DataGrid.ViewportDataGridNode {
-  /**
-   * @param {?Object.<string, *>=} data
-   * @param {boolean=} hasChildren
-   */
-  constructor(data, hasChildren) {
-    super(data, hasChildren);
-  }
-
-  /**
-   * @param {!NODE_TYPE} node
-   */
-  insertChildOrdered(node) {
-    this.insertChild(node, this.children.upperBound(node, this.dataGrid._sortingFunction));
-  }
-
-  _sortChildren() {
-    this.children.sort(this.dataGrid._sortingFunction);
-    for (let i = 0; i < this.children.length; ++i)
-      this.children[i].recalculateSiblings(i);
-    for (const child of this.children)
-      child._sortChildren();
-  }
-};
diff --git a/front_end/data_grid/ViewportDataGrid.js b/front_end/data_grid/ViewportDataGrid.js
deleted file mode 100644
index 90a0ed1..0000000
--- a/front_end/data_grid/ViewportDataGrid.js
+++ /dev/null
@@ -1,488 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- * @extends {DataGrid.DataGrid<!NODE_TYPE>}
- * @template NODE_TYPE
- */
-DataGrid.ViewportDataGrid = class extends DataGrid.DataGrid {
-  /**
-   * @param {!Array.<!DataGrid.DataGrid.ColumnDescriptor>} columnsArray
-   * @param {function(!NODE_TYPE, string, string, string)=} editCallback
-   * @param {function(!NODE_TYPE)=} deleteCallback
-   * @param {function()=} refreshCallback
-   */
-  constructor(columnsArray, editCallback, deleteCallback, refreshCallback) {
-    super(columnsArray, editCallback, deleteCallback, refreshCallback);
-
-    this._onScrollBound = this._onScroll.bind(this);
-    this._scrollContainer.addEventListener('scroll', this._onScrollBound, true);
-
-    /** @type {!Array.<!DataGrid.ViewportDataGridNode>} */
-    this._visibleNodes = [];
-    this._inline = false;
-
-    this._stickToBottom = false;
-    this._updateIsFromUser = false;
-    this._lastScrollTop = 0;
-    this._firstVisibleIsStriped = false;
-    this._isStriped = false;
-
-    this.setRootNode(new DataGrid.ViewportDataGridNode());
-  }
-
-  /**
-   * @param {boolean} striped
-   * @override
-   */
-  setStriped(striped) {
-    this._isStriped = striped;
-    let startsWithOdd = true;
-    if (this._visibleNodes.length) {
-      const allChildren = this.rootNode().flatChildren();
-      startsWithOdd = !!(allChildren.indexOf(this._visibleNodes[0]));
-    }
-    this._updateStripesClass(startsWithOdd);
-  }
-
-  /**
-   * @param {boolean} startsWithOdd
-   */
-  _updateStripesClass(startsWithOdd) {
-    this.element.classList.toggle('striped-data-grid', !startsWithOdd && this._isStriped);
-    this.element.classList.toggle('striped-data-grid-starts-with-odd', startsWithOdd && this._isStriped);
-  }
-
-  /**
-   * @param {!Element} scrollContainer
-   */
-  setScrollContainer(scrollContainer) {
-    this._scrollContainer.removeEventListener('scroll', this._onScrollBound, true);
-    this._scrollContainer = scrollContainer;
-    this._scrollContainer.addEventListener('scroll', this._onScrollBound, true);
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._stickToBottom)
-      this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.clientHeight;
-    this.scheduleUpdate();
-    super.onResize();
-  }
-
-  /**
-   * @param {boolean} stick
-   */
-  setStickToBottom(stick) {
-    this._stickToBottom = stick;
-  }
-
-  /**
-   * @param {?Event} event
-   */
-  _onScroll(event) {
-    this._stickToBottom = this._scrollContainer.isScrolledToBottom();
-    if (this._lastScrollTop !== this._scrollContainer.scrollTop)
-      this.scheduleUpdate(true);
-  }
-
-  /**
-   * @protected
-   */
-  scheduleUpdateStructure() {
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {boolean=} isFromUser
-   */
-  scheduleUpdate(isFromUser) {
-    if (this._stickToBottom && isFromUser)
-      this._stickToBottom = this._scrollContainer.isScrolledToBottom();
-    this._updateIsFromUser = this._updateIsFromUser || isFromUser;
-    if (this._updateAnimationFrameId)
-      return;
-    this._updateAnimationFrameId = this.element.window().requestAnimationFrame(this._update.bind(this));
-  }
-
-  // TODO(allada) This should be fixed to never be needed. It is needed right now for network because removing
-  // elements happens followed by a scheduleRefresh() which causes white space to be visible, but the waterfall
-  // updates instantly.
-  updateInstantly() {
-    this._update();
-  }
-
-  /**
-   * @override
-   */
-  renderInline() {
-    this._inline = true;
-    super.renderInline();
-    this._update();
-  }
-
-  /**
-   * @param {number} clientHeight
-   * @param {number} scrollTop
-   * @return {{topPadding: number, bottomPadding: number, contentHeight: number, visibleNodes: !Array.<!DataGrid.ViewportDataGridNode>, offset: number}}
-   */
-  _calculateVisibleNodes(clientHeight, scrollTop) {
-    const nodes = this.rootNode().flatChildren();
-    if (this._inline)
-      return {topPadding: 0, bottomPadding: 0, contentHeight: 0, visibleNodes: nodes, offset: 0};
-
-    const size = nodes.length;
-    let i = 0;
-    let y = 0;
-
-    for (; i < size && y + nodes[i].nodeSelfHeight() < scrollTop; ++i)
-      y += nodes[i].nodeSelfHeight();
-    const start = i;
-    const topPadding = y;
-
-    for (; i < size && y < scrollTop + clientHeight; ++i)
-      y += nodes[i].nodeSelfHeight();
-    const end = i;
-
-    let bottomPadding = 0;
-    for (; i < size; ++i)
-      bottomPadding += nodes[i].nodeSelfHeight();
-
-    return {
-      topPadding: topPadding,
-      bottomPadding: bottomPadding,
-      contentHeight: y - topPadding,
-      visibleNodes: nodes.slice(start, end),
-      offset: start
-    };
-  }
-
-  /**
-   * @return {number}
-   */
-  _contentHeight() {
-    const nodes = this.rootNode().flatChildren();
-    let result = 0;
-    for (let i = 0, size = nodes.length; i < size; ++i)
-      result += nodes[i].nodeSelfHeight();
-    return result;
-  }
-
-  _update() {
-    if (this._updateAnimationFrameId) {
-      this.element.window().cancelAnimationFrame(this._updateAnimationFrameId);
-      delete this._updateAnimationFrameId;
-    }
-
-    const clientHeight = this._scrollContainer.clientHeight;
-    let scrollTop = this._scrollContainer.scrollTop;
-    const currentScrollTop = scrollTop;
-    const maxScrollTop = Math.max(0, this._contentHeight() - clientHeight);
-    if (!this._updateIsFromUser && this._stickToBottom)
-      scrollTop = maxScrollTop;
-    this._updateIsFromUser = false;
-    scrollTop = Math.min(maxScrollTop, scrollTop);
-
-    const viewportState = this._calculateVisibleNodes(clientHeight, scrollTop);
-    const visibleNodes = viewportState.visibleNodes;
-    const visibleNodesSet = new Set(visibleNodes);
-
-    for (let i = 0; i < this._visibleNodes.length; ++i) {
-      const oldNode = this._visibleNodes[i];
-      if (!visibleNodesSet.has(oldNode) && oldNode.attached()) {
-        const element = oldNode.existingElement();
-        element.remove();
-      }
-    }
-
-    let previousElement = this.topFillerRowElement();
-    const tBody = this.dataTableBody;
-    let offset = viewportState.offset;
-
-    if (visibleNodes.length) {
-      const nodes = this.rootNode().flatChildren();
-      const index = nodes.indexOf(visibleNodes[0]);
-      this._updateStripesClass(!!(index % 2));
-      if (this._stickToBottom && index !== -1 && !!(index % 2) !== this._firstVisibleIsStriped)
-        offset += 1;
-    }
-
-    this._firstVisibleIsStriped = !!(offset % 2);
-
-    for (let i = 0; i < visibleNodes.length; ++i) {
-      const node = visibleNodes[i];
-      const element = node.element();
-      node.setStriped((offset + i) % 2 === 0);
-      if (element !== previousElement.nextSibling)
-        tBody.insertBefore(element, previousElement.nextSibling);
-      node.revealed = true;
-      previousElement = element;
-    }
-
-    this.setVerticalPadding(viewportState.topPadding, viewportState.bottomPadding);
-    this._lastScrollTop = scrollTop;
-    if (scrollTop !== currentScrollTop)
-      this._scrollContainer.scrollTop = scrollTop;
-    const contentFits =
-        viewportState.contentHeight <= clientHeight && viewportState.topPadding + viewportState.bottomPadding === 0;
-    if (contentFits !== this.element.classList.contains('data-grid-fits-viewport')) {
-      this.element.classList.toggle('data-grid-fits-viewport', contentFits);
-      this.updateWidths();
-    }
-    this._visibleNodes = visibleNodes;
-    this.dispatchEventToListeners(DataGrid.ViewportDataGrid.Events.ViewportCalculated);
-  }
-
-  /**
-   * @param {!DataGrid.ViewportDataGridNode} node
-   */
-  _revealViewportNode(node) {
-    const nodes = this.rootNode().flatChildren();
-    const index = nodes.indexOf(node);
-    if (index === -1)
-      return;
-    let fromY = 0;
-    for (let i = 0; i < index; ++i)
-      fromY += nodes[i].nodeSelfHeight();
-    const toY = fromY + node.nodeSelfHeight();
-
-    let scrollTop = this._scrollContainer.scrollTop;
-    if (scrollTop > fromY) {
-      scrollTop = fromY;
-      this._stickToBottom = false;
-    } else if (scrollTop + this._scrollContainer.offsetHeight < toY) {
-      scrollTop = toY - this._scrollContainer.offsetHeight;
-    }
-    this._scrollContainer.scrollTop = scrollTop;
-  }
-};
-
-DataGrid.ViewportDataGrid.Events = {
-  ViewportCalculated: Symbol('ViewportCalculated')
-};
-
-/**
- * @unrestricted
- * @extends {DataGrid.DataGridNode<!NODE_TYPE>}
- * @template NODE_TYPE
- */
-DataGrid.ViewportDataGridNode = class extends DataGrid.DataGridNode {
-  /**
-   * @param {?Object.<string, *>=} data
-   * @param {boolean=} hasChildren
-   */
-  constructor(data, hasChildren) {
-    super(data, hasChildren);
-    /** @type {boolean} */
-    this._stale = false;
-    /** @type {?Array<!DataGrid.ViewportDataGridNode>} */
-    this._flatNodes = null;
-    this._isStriped = false;
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  element() {
-    const existingElement = this.existingElement();
-    const element = existingElement || this.createElement();
-    if (!existingElement || this._stale) {
-      this.createCells(element);
-      this._stale = false;
-    }
-    return element;
-  }
-
-  /**
-   * @param {boolean} isStriped
-   */
-  setStriped(isStriped) {
-    this._isStriped = isStriped;
-    this.element().classList.toggle('odd', isStriped);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStriped() {
-    return this._isStriped;
-  }
-
-  /**
-   * @protected
-   */
-  clearFlatNodes() {
-    this._flatNodes = null;
-    const parent = /** @type {!DataGrid.ViewportDataGridNode} */ (this.parent);
-    if (parent)
-      parent.clearFlatNodes();
-  }
-
-  /**
-   * @return {!Array<!DataGrid.ViewportDataGridNode>}
-   */
-  flatChildren() {
-    if (this._flatNodes)
-      return this._flatNodes;
-    /** @type {!Array<!DataGrid.ViewportDataGridNode>} */
-    const flatNodes = [];
-    /** @type {!Array<!Array<!DataGrid.ViewportDataGridNode>>} */
-    const children = [this.children];
-    /** @type {!Array<number>} */
-    const counters = [0];
-    let depth = 0;
-    while (depth >= 0) {
-      if (children[depth].length <= counters[depth]) {
-        depth--;
-        continue;
-      }
-      const node = children[depth][counters[depth]++];
-      flatNodes.push(node);
-      if (node._expanded && node.children.length) {
-        depth++;
-        children[depth] = node.children;
-        counters[depth] = 0;
-      }
-    }
-
-    this._flatNodes = flatNodes;
-    return flatNodes;
-  }
-
-  /**
-   * @override
-   * @param {!NODE_TYPE} child
-   * @param {number} index
-   */
-  insertChild(child, index) {
-    this.clearFlatNodes();
-    if (child.parent === this) {
-      const currentIndex = this.children.indexOf(child);
-      if (currentIndex < 0)
-        console.assert(false, 'Inconsistent DataGrid state');
-      if (currentIndex === index)
-        return;
-      if (currentIndex < index)
-        --index;
-    }
-    child.remove();
-    child.parent = this;
-    child.dataGrid = this.dataGrid;
-    if (!this.children.length)
-      this.setHasChildren(true);
-    this.children.splice(index, 0, child);
-    child.recalculateSiblings(index);
-    if (this._expanded)
-      this.dataGrid.scheduleUpdateStructure();
-  }
-
-  /**
-   * @override
-   * @param {!NODE_TYPE} child
-   */
-  removeChild(child) {
-    this.clearFlatNodes();
-    if (this.dataGrid)
-      this.dataGrid.updateSelectionBeforeRemoval(child, false);
-    if (child.previousSibling)
-      child.previousSibling.nextSibling = child.nextSibling;
-    if (child.nextSibling)
-      child.nextSibling.previousSibling = child.previousSibling;
-    if (child.parent !== this)
-      throw 'removeChild: Node is not a child of this node.';
-
-    this.children.remove(child, true);
-    child._unlink();
-
-    if (!this.children.length)
-      this.setHasChildren(false);
-    if (this._expanded)
-      this.dataGrid.scheduleUpdateStructure();
-  }
-
-  /**
-   * @override
-   */
-  removeChildren() {
-    this.clearFlatNodes();
-    if (this.dataGrid)
-      this.dataGrid.updateSelectionBeforeRemoval(this, true);
-    for (let i = 0; i < this.children.length; ++i)
-      this.children[i]._unlink();
-    this.children = [];
-
-    if (this._expanded)
-      this.dataGrid.scheduleUpdateStructure();
-  }
-
-  _unlink() {
-    if (this.attached())
-      this.existingElement().remove();
-    this.resetNode();
-  }
-
-  /**
-   * @override
-   */
-  collapse() {
-    if (!this._expanded)
-      return;
-    this.clearFlatNodes();
-    this._expanded = false;
-    if (this.existingElement())
-      this.existingElement().classList.remove('expanded');
-    this.dataGrid.scheduleUpdateStructure();
-  }
-
-  /**
-   * @override
-   */
-  expand() {
-    if (this._expanded)
-      return;
-    this.dataGrid._stickToBottom = false;
-    this.clearFlatNodes();
-    super.expand();
-    this.dataGrid.scheduleUpdateStructure();
-  }
-
-  /**
-   * @protected
-   * @return {boolean}
-   */
-  attached() {
-    return !!(this.dataGrid && this.existingElement() && this.existingElement().parentElement);
-  }
-
-  /**
-   * @override
-   */
-  refresh() {
-    if (this.attached()) {
-      this._stale = true;
-      this.dataGrid.scheduleUpdate();
-    } else {
-      this.resetElement();
-    }
-  }
-
-  /**
-   * @override
-   */
-  reveal() {
-    this.dataGrid._revealViewportNode(this);
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   */
-  recalculateSiblings(index) {
-    this.clearFlatNodes();
-    super.recalculateSiblings(index);
-  }
-};
diff --git a/front_end/data_grid/dataGrid.css b/front_end/data_grid/dataGrid.css
deleted file mode 100644
index 66292df..0000000
--- a/front_end/data_grid/dataGrid.css
+++ /dev/null
@@ -1,255 +0,0 @@
-.data-grid {
-    position: relative;
-    border: 1px solid #aaa;
-    line-height: 120%;
-}
-
-.data-grid table {
-    table-layout: fixed;
-    border-spacing: 0;
-    border-collapse: separate;
-    height: 100%;
-    width: 100%;
-}
-
-.data-grid .header-container,
-.data-grid .data-container {
-    position: absolute;
-    left: 0;
-    right: 0;
-    overflow-x: hidden;
-}
-
-.data-grid .header-container {
-    top: 0;
-    height: 21px;
-}
-
-.data-grid .data-container {
-    top: 21px;
-    bottom: 0;
-    overflow-y: overlay;
-    transform: translateZ(0);
-}
-
-.data-grid.inline .header-container,
-.data-grid.inline .data-container {
-    position: static;
-}
-
-.data-grid.inline .corner {
-    display: none;
-}
-
-.platform-mac .data-grid .corner,
-.data-grid.data-grid-fits-viewport .corner {
-    display: none;
-}
-
-.data-grid .corner {
-    width: 14px;
-    padding-right: 0;
-    padding-left: 0;
-    border-left: 0 none transparent !important;
-}
-
-.data-grid .top-filler-td,
-.data-grid .bottom-filler-td {
-    height: auto !important;
-    padding: 0 !important;
-}
-
-.data-grid table.data {
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    border-top: 0 none transparent;
-    table-layout: fixed;
-}
-
-.data-grid.inline table.data {
-    position: static;
-}
-
-.data-grid table.data tr {
-    display: none;
-    height: 20px;
-}
-
-.data-grid table.data tr.revealed {
-    display: table-row;
-}
-
-.striped-data-grid .revealed.data-grid-data-grid-node:nth-child(odd),
-.striped-data-grid-starts-with-odd .revealed.data-grid-data-grid-node:nth-child(even) {
-    background-color: hsl(214, 70%, 97%);
-}
-
-.data-grid td,
-.data-grid th {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    line-height: 18px;
-    height: 18px;
-    border-left: 1px solid #aaa;
-    padding: 1px 4px;
-}
-
-.data-grid th:first-child,
-.data-grid td:first-child {
-    border-left: none !important;
-}
-
-.data-grid td {
-    vertical-align: top;
-    -webkit-user-select: text;
-}
-
-.data-grid th {
-    text-align: left;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: 1px solid #aaa;
-    font-weight: normal;
-    vertical-align: middle;
-}
-
-.data-grid td > div,
-.data-grid th > div {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.data-grid td.editing > div {
-    text-overflow: clip;
-}
-
-.data-grid .center {
-    text-align: center;
-}
-
-.data-grid .right {
-    text-align: right;
-}
-
-.data-grid th.sortable {
-    position: relative;
-}
-
-.data-grid th.sortable:active::after {
-    content: "";
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, 0.15);
-}
-
-.data-grid th .sort-order-icon-container {
-    position: absolute;
-    top: 1px;
-    right: 0;
-    bottom: 1px;
-    display: flex;
-    align-items: center;
-}
-
-.data-grid th .sort-order-icon {
-    margin-right: 4px;
-    margin-bottom: -2px;
-    display: none;
-}
-
-.data-grid th.sort-ascending .sort-order-icon,
-.data-grid th.sort-descending .sort-order-icon {
-    display: block;
-}
-
-.data-grid th.sortable:hover {
-    background-color: hsla(0, 0%, 90%, 1);
-}
-
-.data-grid button {
-    line-height: 18px;
-    color: inherit;
-}
-
-.data-grid td.disclosure::before {
-    -webkit-user-select: none;
-    -webkit-mask-image: url(Images/treeoutlineTriangles.png);
-    -webkit-mask-position: 0 0;
-    -webkit-mask-size: 32px 24px;
-    float: left;
-    width: 8px;
-    height: 12px;
-    margin-right: 2px;
-    content: "";
-    position: relative;
-    top: 3px;
-    background-color: rgb(110, 110, 110);
-}
-
-.data-grid tr:not(.parent) td.disclosure::before {
-    background-color: transparent;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-.data-grid tr.parent td.disclosure::before {
-    -webkit-mask-image: url(Images/treeoutlineTriangles_2x.png);
-}
-} /* media */
-
-.data-grid tr.expanded td.disclosure::before {
-    -webkit-mask-position: -16px 0;
-}
-
-.data-grid table.data tr.revealed.selected {
-    background-color: rgb(212, 212, 212);
-    color: inherit;
-}
-
-.data-grid:focus table.data tr.selected {
-    background-color: var(--selection-bg-color);
-    color: var(--selection-fg-color);
-}
-
-.data-grid:focus tr.selected .devtools-link {
-    color: var(--selection-fg-color);
-}
-
-.data-grid:focus tr.parent.selected td.disclosure::before {
-    background-color: var(--selection-fg-color);
-    -webkit-mask-position: 0 0;
-}
-
-.data-grid:focus tr.expanded.selected td.disclosure::before {
-    background-color: var(--selection-fg-color);
-    -webkit-mask-position: -16px 0;
-}
-
-.data-grid tr.inactive {
-    color: rgb(128, 128, 128);
-    font-style: italic;
-}
-
-.data-grid tr.dirty {
-    background-color: hsl(0, 100%, 92%);
-    color: red;
-    font-style: normal;
-}
-
-.data-grid:focus tr.selected.dirty {
-    background-color: hsl(0, 100%, 70%);
-}
-
-.data-grid-resizer {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    width: 5px;
-    z-index: 500;
-}
diff --git a/front_end/data_grid/module.json b/front_end/data_grid/module.json
deleted file mode 100644
index fa1b3b7..0000000
--- a/front_end/data_grid/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "dependencies": [
-        "ui"
-    ],
-    "scripts": [
-        "DataGrid.js",
-        "ViewportDataGrid.js",
-        "SortableDataGrid.js",
-        "ShowMoreDataGridNode.js"
-    ],
-    "resources": [
-        "dataGrid.css"
-    ]
-}
diff --git a/front_end/data_grid_test_runner/DataGridTestRunner.js b/front_end/data_grid_test_runner/DataGridTestRunner.js
deleted file mode 100644
index 8a11a8f..0000000
--- a/front_end/data_grid_test_runner/DataGridTestRunner.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-DataGridTestRunner.dumpDataGrid = function(root, descentIntoCollapsed, prefix) {
-  if (!prefix)
-    prefix = '';
-  const suffix = root.selected ? ' <- selected' : '';
-  const columnKeys = root.dataGrid._columnsArray.map(column => column.id);
-  const outputColumns = [];
-  for (const key of columnKeys) {
-    if (key in root.data)
-      outputColumns.push(root.data[key]);
-  }
-  if (outputColumns.length)
-    TestRunner.addResult(prefix + outputColumns.join(' | ') + suffix);
-
-  if (!descentIntoCollapsed && !root.expanded)
-    return;
-  for (const child of root.children)
-    DataGridTestRunner.dumpDataGrid(child, descentIntoCollapsed, prefix + ' ');
-};
-
-DataGridTestRunner.validateDataGrid = function(root) {
-  const children = root.children;
-
-  for (let i = 0; i < children.length; ++i) {
-    const child = children[i];
-
-    if (child.parent !== root)
-      throw 'Wrong parent for child ' + child.data.id + ' of ' + root.data.id;
-
-    if (child.nextSibling !== ((i + 1 === children.length ? null : children[i + 1])))
-      throw 'Wrong child.nextSibling for ' + child.data.id + ' (' + i + ' of ' + children.length + ') ';
-
-    if (child.previousSibling !== ((i ? children[i - 1] : null)))
-      throw 'Wrong child.previousSibling for ' + child.data.id + ' (' + i + ' of ' + children.length + ') ';
-
-    if (child.parent && !child.parent._isRoot && child.depth !== root.depth + 1)
-      throw 'Wrong depth for ' + child.data.id + ' expected ' + (root.depth + 1) + ' but got ' + child.depth;
-
-    DataGridTestRunner.validateDataGrid(child);
-  }
-
-  const selectedNode = root.dataGrid.selectedNode;
-
-  if (!root.parent && selectedNode) {
-    if (!selectedNode.selectable)
-      throw 'Selected node is not selectable';
-    let node = selectedNode;
-    for (; node && node !== root; node = node.parent) {
-    }
-
-    if (!node)
-      throw 'Selected node (' + selectedNode.data.id + ') is not within the DataGrid';
-  }
-};
-
-DataGridTestRunner.dumpAndValidateDataGrid = function(root) {
-  DataGridTestRunner.dumpDataGrid(root);
-  DataGridTestRunner.validateDataGrid(root);
-};
diff --git a/front_end/data_grid_test_runner/module.json b/front_end/data_grid_test_runner/module.json
deleted file mode 100644
index 8a1da51..0000000
--- a/front_end/data_grid_test_runner/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "data_grid"
-  ],
-  "scripts": [
-    "DataGridTestRunner.js"
-  ],
-  "skip_compilation": [
-    "DataGridTestRunner.js"
-  ]
-}
diff --git a/front_end/device_mode_test_runner/DeviceModeTestRunner.js b/front_end/device_mode_test_runner/DeviceModeTestRunner.js
deleted file mode 100644
index cfe3cd1..0000000
--- a/front_end/device_mode_test_runner/DeviceModeTestRunner.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-DeviceModeTestRunner.buildFakePhone = function(overrides) {
-  const StandardPhoneJSON = {
-    'show-by-default': false,
-    'title': 'Fake Phone 1',
-
-    'screen': {
-      'horizontal': {'width': 480, 'height': 320},
-
-      'device-pixel-ratio': 2,
-
-      'vertical': {'width': 320, 'height': 480}
-    },
-
-    'capabilities': ['touch', 'mobile'],
-    'user-agent': 'fakeUserAgent',
-    'type': 'phone',
-
-    'modes': [
-      {
-        'title': 'default',
-        'orientation': 'vertical',
-
-        'insets': {'left': 0, 'top': 0, 'right': 0, 'bottom': 0}
-      },
-      {
-        'title': 'default',
-        'orientation': 'horizontal',
-
-        'insets': {'left': 0, 'top': 0, 'right': 0, 'bottom': 0}
-      }
-    ]
-  };
-
-  const json = Object.assign(StandardPhoneJSON, overrides || {});
-  return Emulation.EmulatedDevice.fromJSONV1(json);
-};
diff --git a/front_end/device_mode_test_runner/module.json b/front_end/device_mode_test_runner/module.json
deleted file mode 100644
index d737775..0000000
--- a/front_end/device_mode_test_runner/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "emulation"
-  ],
-  "scripts": [
-    "DeviceModeTestRunner.js"
-  ],
-  "skip_compilation": [
-    "DeviceModeTestRunner.js"
-  ]
-}
diff --git a/front_end/devices/DevicesView.js b/front_end/devices/DevicesView.js
deleted file mode 100644
index 7a82bdf..0000000
--- a/front_end/devices/DevicesView.js
+++ /dev/null
@@ -1,710 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Devices.DevicesView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('devices/devicesView.css');
-    this.contentElement.classList.add('devices-view');
-
-    const hbox = this.contentElement.createChild('div', 'hbox devices-container');
-    const sidebar = hbox.createChild('div', 'devices-sidebar');
-    sidebar.createChild('div', 'devices-view-title').createTextChild(Common.UIString('Devices'));
-    this._sidebarList = sidebar.createChild('div', 'devices-sidebar-list');
-
-    this._discoveryView = new Devices.DevicesView.DiscoveryView();
-    this._sidebarListSpacer = this._sidebarList.createChild('div', 'devices-sidebar-spacer');
-    this._discoveryListItem = this._sidebarList.createChild('div', 'devices-sidebar-item');
-    this._discoveryListItem.textContent = Common.UIString('Settings');
-    this._discoveryListItem.addEventListener(
-        'click', this._selectSidebarListItem.bind(this, this._discoveryListItem, this._discoveryView));
-
-    /** @type {!Map<string, !Devices.DevicesView.DeviceView>} */
-    this._viewById = new Map();
-    /** @type {!Array<!Adb.Device>} */
-    this._devices = [];
-    /** @type {!Map<string, !Element>} */
-    this._listItemById = new Map();
-    /** @type {?Element} */
-    this._selectedListItem = null;
-    /** @type {?UI.Widget} */
-    this._visibleView = null;
-
-    this._viewContainer = hbox.createChild('div', 'flex-auto vbox');
-
-    const discoveryFooter = this.contentElement.createChild('div', 'devices-footer');
-    this._deviceCountSpan = discoveryFooter.createChild('span');
-    discoveryFooter.createChild('span').textContent = Common.UIString(' Read ');
-    discoveryFooter.appendChild(UI.XLink.create(
-        'https://developers.google.com/chrome-developer-tools/docs/remote-debugging',
-        Common.UIString('remote debugging documentation')));
-    discoveryFooter.createChild('span').textContent = Common.UIString(' for more information.');
-    this._updateFooter();
-    this._selectSidebarListItem(this._discoveryListItem, this._discoveryView);
-
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.DevicesUpdated, this._devicesUpdated, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, this._devicesPortForwardingStatusChanged,
-        this);
-
-    this.contentElement.tabIndex = 0;
-    this.setDefaultFocusedElement(this.contentElement);
-  }
-
-  /**
-   * @return {!Devices.DevicesView}
-   */
-  static _instance() {
-    if (!Devices.DevicesView._instanceObject)
-      Devices.DevicesView._instanceObject = new Devices.DevicesView();
-    return Devices.DevicesView._instanceObject;
-  }
-
-  /**
-   * @param {!Element} listItem
-   * @param {!UI.Widget} view
-   */
-  _selectSidebarListItem(listItem, view) {
-    if (this._selectedListItem === listItem)
-      return;
-
-    if (this._selectedListItem) {
-      this._selectedListItem.classList.remove('selected');
-      this._visibleView.detach();
-    }
-
-    this._visibleView = view;
-    this._selectedListItem = listItem;
-    this._visibleView.show(this._viewContainer);
-    this._selectedListItem.classList.add('selected');
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _devicesUpdated(event) {
-    this._devices =
-        /** @type {!Array.<!Adb.Device>} */ (event.data)
-            .slice()
-            .filter(d => d.adbSerial.toUpperCase() !== 'WEBRTC' && d.adbSerial.toUpperCase() !== 'LOCALHOST');
-    for (const device of this._devices) {
-      if (!device.adbConnected)
-        device.adbModel = Common.UIString('Unknown');
-    }
-
-    const ids = new Set();
-    for (const device of this._devices)
-      ids.add(device.id);
-
-    let selectedRemoved = false;
-    for (const deviceId of this._viewById.keys()) {
-      if (!ids.has(deviceId)) {
-        const listItem = /** @type {!Element} */ (this._listItemById.get(deviceId));
-        this._listItemById.remove(deviceId);
-        this._viewById.remove(deviceId);
-        listItem.remove();
-        if (listItem === this._selectedListItem)
-          selectedRemoved = true;
-      }
-    }
-
-    for (const device of this._devices) {
-      let view = this._viewById.get(device.id);
-      let listItem = this._listItemById.get(device.id);
-
-      if (!view) {
-        view = new Devices.DevicesView.DeviceView();
-        this._viewById.set(device.id, view);
-        listItem = this._createSidebarListItem(view);
-        this._listItemById.set(device.id, listItem);
-        this._sidebarList.insertBefore(listItem, this._sidebarListSpacer);
-      }
-
-      listItem._title.textContent = device.adbModel;
-      listItem._status.textContent =
-          device.adbConnected ? Common.UIString('Connected') : Common.UIString('Pending Authorization');
-      listItem.classList.toggle('device-connected', device.adbConnected);
-      view.update(device);
-    }
-
-    if (selectedRemoved)
-      this._selectSidebarListItem(this._discoveryListItem, this._discoveryView);
-
-    this._updateFooter();
-  }
-
-  /**
-   * @param {!UI.Widget} view
-   * @return {!Element}
-   */
-  _createSidebarListItem(view) {
-    const listItem = createElementWithClass('div', 'devices-sidebar-item');
-    listItem.addEventListener('click', this._selectSidebarListItem.bind(this, listItem, view));
-    listItem._title = listItem.createChild('div', 'devices-sidebar-item-title');
-    listItem._status = listItem.createChild('div', 'devices-sidebar-item-status');
-    return listItem;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _devicesDiscoveryConfigChanged(event) {
-    const config = /** @type {!Adb.Config} */ (event.data);
-    this._discoveryView.discoveryConfigChanged(config);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _devicesPortForwardingStatusChanged(event) {
-    const status = /** @type {!Adb.PortForwardingStatus} */ (event.data);
-    for (const deviceId in status) {
-      const view = this._viewById.get(deviceId);
-      if (view)
-        view.portForwardingStatusChanged(status[deviceId]);
-    }
-    for (const deviceId of this._viewById.keys()) {
-      const view = this._viewById.get(deviceId);
-      if (view && !(deviceId in status))
-        view.portForwardingStatusChanged({ports: {}, browserId: ''});
-    }
-  }
-
-  _updateFooter() {
-    this._deviceCountSpan.textContent = !this._devices.length ?
-        Common.UIString('No devices detected.') :
-        this._devices.length === 1 ? Common.UIString('1 device detected.') :
-                                     Common.UIString('%d devices detected.', this._devices.length);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    InspectorFrontendHost.setDevicesUpdatesEnabled(true);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-    InspectorFrontendHost.setDevicesUpdatesEnabled(false);
-  }
-};
-
-Devices.DevicesView.DiscoveryView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.setMinimumSize(100, 100);
-    this.element.classList.add('discovery-view');
-
-    this.contentElement.createChild('div', 'hbox device-text-row').createChild('div', 'view-title').textContent =
-        Common.UIString('Settings');
-
-    const discoverUsbDevicesCheckbox = UI.CheckboxLabel.create(Common.UIString('Discover USB devices'));
-    discoverUsbDevicesCheckbox.classList.add('usb-checkbox');
-    this.element.appendChild(discoverUsbDevicesCheckbox);
-    this._discoverUsbDevicesCheckbox = discoverUsbDevicesCheckbox.checkboxElement;
-    this._discoverUsbDevicesCheckbox.addEventListener('click', () => {
-      this._config.discoverUsbDevices = this._discoverUsbDevicesCheckbox.checked;
-      InspectorFrontendHost.setDevicesDiscoveryConfig(this._config);
-    }, false);
-
-    const help = this.element.createChild('div', 'discovery-help');
-    help.createChild('span').textContent = Common.UIString('Need help? Read Chrome ');
-    help.appendChild(UI.XLink.create(
-        'https://developers.google.com/chrome-developer-tools/docs/remote-debugging',
-        Common.UIString('remote debugging documentation.')));
-
-    /** @type {!Adb.Config} */
-    this._config;
-
-    this._portForwardingView = new Devices.DevicesView.PortForwardingView((enabled, config) => {
-      this._config.portForwardingEnabled = enabled;
-      this._config.portForwardingConfig = {};
-      for (const rule of config)
-        this._config.portForwardingConfig[rule.port] = rule.address;
-      InspectorFrontendHost.setDevicesDiscoveryConfig(this._config);
-    });
-    this._portForwardingView.show(this.element);
-  }
-
-  /**
-   * @param {!Adb.Config} config
-   */
-  discoveryConfigChanged(config) {
-    this._config = config;
-    this._discoverUsbDevicesCheckbox.checked = config.discoverUsbDevices;
-    this._portForwardingView.discoveryConfigChanged(config.portForwardingEnabled, config.portForwardingConfig);
-  }
-};
-
-/**
- * @implements {UI.ListWidget.Delegate<Adb.PortForwardingRule>}
- */
-Devices.DevicesView.PortForwardingView = class extends UI.VBox {
-  /**
-   * @param {function(boolean, !Array<!Adb.PortForwardingRule>)} callback
-   */
-  constructor(callback) {
-    super();
-    this._callback = callback;
-    this.element.classList.add('port-forwarding-view');
-
-    const portForwardingHeader = this.element.createChild('div', 'port-forwarding-header');
-    const portForwardingEnabledCheckbox = UI.CheckboxLabel.create(Common.UIString('Port forwarding'));
-    portForwardingEnabledCheckbox.classList.add('port-forwarding-checkbox');
-    portForwardingHeader.appendChild(portForwardingEnabledCheckbox);
-    this._portForwardingEnabledCheckbox = portForwardingEnabledCheckbox.checkboxElement;
-    this._portForwardingEnabledCheckbox.addEventListener('click', this._update.bind(this), false);
-
-    const portForwardingFooter = this.element.createChild('div', 'port-forwarding-footer');
-    portForwardingFooter.createChild('span').textContent = Common.UIString(
-        'Define the listening port on your device that maps to a port accessible from your development machine. ');
-    portForwardingFooter.appendChild(UI.XLink.create(
-        'https://developer.chrome.com/devtools/docs/remote-debugging#port-forwarding', Common.UIString('Learn more')));
-
-    /** @type {!UI.ListWidget<!Adb.PortForwardingRule>} */
-    this._list = new UI.ListWidget(this);
-    this._list.registerRequiredCSS('devices/devicesView.css');
-    this._list.element.classList.add('port-forwarding-list');
-    const placeholder = createElementWithClass('div', 'port-forwarding-list-empty');
-    placeholder.textContent = Common.UIString('No rules');
-    this._list.setEmptyPlaceholder(placeholder);
-    this._list.show(this.element);
-    /** @type {?UI.ListWidget.Editor<!Adb.PortForwardingRule>} */
-    this._editor = null;
-
-    this.element.appendChild(
-        UI.createTextButton(Common.UIString('Add rule'), this._addRuleButtonClicked.bind(this), 'add-rule-button'));
-
-    /** @type {!Array<!Adb.PortForwardingRule>} */
-    this._portForwardingConfig = [];
-  }
-
-  _update() {
-    this._callback.call(null, this._portForwardingEnabledCheckbox.checked, this._portForwardingConfig);
-  }
-
-  _addRuleButtonClicked() {
-    this._list.addNewItem(this._portForwardingConfig.length, {port: '', address: ''});
-  }
-
-  /**
-   * @param {boolean} portForwardingEnabled
-   * @param {!Adb.PortForwardingConfig} portForwardingConfig
-   */
-  discoveryConfigChanged(portForwardingEnabled, portForwardingConfig) {
-    this._portForwardingEnabledCheckbox.checked = portForwardingEnabled;
-    this._portForwardingConfig = [];
-    this._list.clear();
-    for (const key of Object.keys(portForwardingConfig)) {
-      const rule = /** @type {!Adb.PortForwardingRule} */ ({port: key, address: portForwardingConfig[key]});
-      this._portForwardingConfig.push(rule);
-      this._list.appendItem(rule, true);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(rule, editable) {
-    const element = createElementWithClass('div', 'port-forwarding-list-item');
-    const port = element.createChild('div', 'port-forwarding-value port-forwarding-port');
-    port.createChild('span', 'port-localhost').textContent = Common.UIString('localhost:');
-    port.createTextChild(rule.port);
-    element.createChild('div', 'port-forwarding-separator');
-    element.createChild('div', 'port-forwarding-value').textContent = rule.address;
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @param {number} index
-   */
-  removeItemRequested(rule, index) {
-    this._portForwardingConfig.splice(index, 1);
-    this._list.removeItem(index);
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(rule, editor, isNew) {
-    rule.port = editor.control('port').value.trim();
-    rule.address = editor.control('address').value.trim();
-    if (isNew)
-      this._portForwardingConfig.push(rule);
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(rule) {
-    const editor = this._createEditor();
-    editor.control('port').value = rule.port;
-    editor.control('address').value = rule.address;
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor<!Adb.PortForwardingRule>}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._editor = editor;
-    const content = editor.contentElement();
-    const fields = content.createChild('div', 'port-forwarding-edit-row');
-    fields.createChild('div', 'port-forwarding-value port-forwarding-port')
-        .appendChild(editor.createInput('port', 'text', 'Device port (3333)', portValidator.bind(this)));
-    fields.createChild('div', 'port-forwarding-separator port-forwarding-separator-invisible');
-    fields.createChild('div', 'port-forwarding-value')
-        .appendChild(editor.createInput('address', 'text', 'Local address (dev.example.corp:3333)', addressValidator));
-    return editor;
-
-    /**
-     * @param {!Adb.PortForwardingRule} rule
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @this {Devices.DevicesView.PortForwardingView}
-     * @return {boolean}
-     */
-    function portValidator(rule, index, input) {
-      const value = input.value.trim();
-      const match = value.match(/^(\d+)$/);
-      if (!match)
-        return false;
-      const port = parseInt(match[1], 10);
-      if (port < 1024 || port > 65535)
-        return false;
-      for (let i = 0; i < this._portForwardingConfig.length; ++i) {
-        if (i !== index && this._portForwardingConfig[i].port === value)
-          return false;
-      }
-      return true;
-    }
-
-    /**
-     * @param {!Adb.PortForwardingRule} rule
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function addressValidator(rule, index, input) {
-      const match = input.value.trim().match(/^([a-zA-Z0-9\.\-_]+):(\d+)$/);
-      if (!match)
-        return false;
-      const port = parseInt(match[2], 10);
-      return port <= 65535;
-    }
-  }
-};
-
-Devices.DevicesView.DeviceView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.setMinimumSize(100, 100);
-    this.contentElement.classList.add('device-view');
-
-    const topRow = this.contentElement.createChild('div', 'hbox device-text-row');
-    this._deviceTitle = topRow.createChild('div', 'view-title');
-    this._deviceSerial = topRow.createChild('div', 'device-serial');
-    this._portStatus = this.contentElement.createChild('div', 'device-port-status hidden');
-
-    this._deviceOffline = this.contentElement.createChild('div');
-    this._deviceOffline.textContent =
-        Common.UIString('Pending authentication: please accept debugging session on the device.');
-
-    this._noBrowsers = this.contentElement.createChild('div');
-    this._noBrowsers.textContent = Common.UIString('No browsers detected.');
-
-    this._browsers = this.contentElement.createChild('div', 'device-browser-list vbox');
-
-    /** @type {!Map<string, !Devices.DevicesView.BrowserSection>} */
-    this._browserById = new Map();
-
-    /** @type {?string} */
-    this._cachedPortStatus = null;
-    /** @type {?Adb.Device} */
-    this._device = null;
-  }
-
-  /**
-   * @param {!Adb.Device} device
-   */
-  update(device) {
-    if (!this._device || this._device.adbModel !== device.adbModel)
-      this._deviceTitle.textContent = device.adbModel;
-
-    if (!this._device || this._device.adbSerial !== device.adbSerial)
-      this._deviceSerial.textContent = '#' + device.adbSerial;
-
-    this._deviceOffline.classList.toggle('hidden', device.adbConnected);
-    this._noBrowsers.classList.toggle('hidden', !device.adbConnected || !!device.browsers.length);
-    this._browsers.classList.toggle('hidden', !device.adbConnected || !device.browsers.length);
-
-    const browserIds = new Set();
-    for (const browser of device.browsers)
-      browserIds.add(browser.id);
-
-    for (const browserId of this._browserById.keys()) {
-      if (!browserIds.has(browserId)) {
-        this._browserById.get(browserId).element.remove();
-        this._browserById.remove(browserId);
-      }
-    }
-
-    for (const browser of device.browsers) {
-      let section = this._browserById.get(browser.id);
-      if (!section) {
-        section = this._createBrowserSection();
-        this._browserById.set(browser.id, section);
-        this._browsers.appendChild(section.element);
-      }
-      this._updateBrowserSection(section, browser);
-    }
-
-    this._device = device;
-  }
-
-  /**
-   * @return {!Devices.DevicesView.BrowserSection}
-   */
-  _createBrowserSection() {
-    const element = createElementWithClass('div', 'vbox flex-none');
-    const topRow = element.createChild('div', '');
-    const title = topRow.createChild('div', 'device-browser-title');
-
-    const newTabRow = element.createChild('div', 'device-browser-new-tab');
-    newTabRow.createChild('div', '').textContent = Common.UIString('New tab:');
-    const newTabInput = UI.createInput('', 'text');
-    newTabRow.appendChild(newTabInput);
-    newTabInput.placeholder = Common.UIString('Enter URL');
-    newTabInput.addEventListener('keydown', newTabKeyDown, false);
-    const newTabButton = UI.createTextButton(Common.UIString('Open'), openNewTab);
-    newTabRow.appendChild(newTabButton);
-
-    const pages = element.createChild('div', 'device-page-list vbox');
-
-    const viewMore = element.createChild('div', 'device-view-more');
-    viewMore.addEventListener('click', viewMoreClick, false);
-    updateViewMoreTitle();
-
-    const section = {
-      browser: null,
-      element: element,
-      title: title,
-      pages: pages,
-      viewMore: viewMore,
-      newTab: newTabRow,
-      pageSections: new Map()
-    };
-    return section;
-
-    function viewMoreClick() {
-      pages.classList.toggle('device-view-more-toggled');
-      updateViewMoreTitle();
-    }
-
-    function updateViewMoreTitle() {
-      viewMore.textContent = pages.classList.contains('device-view-more-toggled') ?
-          Common.UIString('View less tabs\u2026') :
-          Common.UIString('View more tabs\u2026');
-    }
-
-    /**
-     * @param {!Event} event
-     */
-    function newTabKeyDown(event) {
-      if (event.key === 'Enter') {
-        event.consume(true);
-        openNewTab();
-      }
-    }
-
-    function openNewTab() {
-      if (section.browser) {
-        InspectorFrontendHost.openRemotePage(section.browser.id, newTabInput.value.trim() || 'about:blank');
-        newTabInput.value = '';
-      }
-    }
-  }
-
-  /**
-   * @param {!Devices.DevicesView.BrowserSection} section
-   * @param {!Adb.Browser} browser
-   */
-  _updateBrowserSection(section, browser) {
-    if (!section.browser || section.browser.adbBrowserName !== browser.adbBrowserName ||
-        section.browser.adbBrowserVersion !== browser.adbBrowserVersion) {
-      if (browser.adbBrowserVersion)
-        section.title.textContent = String.sprintf('%s (%s)', browser.adbBrowserName, browser.adbBrowserVersion);
-      else
-        section.title.textContent = browser.adbBrowserName;
-    }
-
-    const pageIds = new Set();
-    for (const page of browser.pages)
-      pageIds.add(page.id);
-
-    for (const pageId of section.pageSections.keys()) {
-      if (!pageIds.has(pageId)) {
-        section.pageSections.get(pageId).element.remove();
-        section.pageSections.remove(pageId);
-      }
-    }
-
-    for (let index = 0; index < browser.pages.length; ++index) {
-      const page = browser.pages[index];
-      let pageSection = section.pageSections.get(page.id);
-      if (!pageSection) {
-        pageSection = this._createPageSection();
-        section.pageSections.set(page.id, pageSection);
-        section.pages.appendChild(pageSection.element);
-      }
-      this._updatePageSection(pageSection, page);
-      if (!index && section.pages.firstChild !== pageSection.element)
-        section.pages.insertBefore(pageSection.element, section.pages.firstChild);
-    }
-
-    const kViewMoreCount = 3;
-    for (let index = 0, element = section.pages.firstChild; element; element = element.nextSibling, ++index)
-      element.classList.toggle('device-view-more-page', index >= kViewMoreCount);
-    section.viewMore.classList.toggle('device-needs-view-more', browser.pages.length > kViewMoreCount);
-    section.newTab.classList.toggle('hidden', !browser.adbBrowserChromeVersion);
-    section.browser = browser;
-  }
-
-  /**
-   * @return {!Devices.DevicesView.PageSection}
-   */
-  _createPageSection() {
-    const element = createElementWithClass('div', 'vbox');
-
-    const titleRow = element.createChild('div', 'device-page-title-row');
-    const title = titleRow.createChild('div', 'device-page-title');
-    const inspect = UI.createTextButton(Common.UIString('Inspect'), doAction.bind(null, 'inspect'));
-    titleRow.appendChild(inspect);
-
-    const toolbar = new UI.Toolbar('');
-    toolbar.appendToolbarItem(new UI.ToolbarMenuButton(appendActions));
-    titleRow.appendChild(toolbar.element);
-
-    const url = element.createChild('div', 'device-page-url');
-    const section = {page: null, element: element, title: title, url: url, inspect: inspect};
-    return section;
-
-    /**
-     * @param {!UI.ContextMenu} contextMenu
-     */
-    function appendActions(contextMenu) {
-      contextMenu.defaultSection().appendItem(Common.UIString('Reload'), doAction.bind(null, 'reload'));
-      contextMenu.defaultSection().appendItem(Common.UIString('Focus'), doAction.bind(null, 'activate'));
-      contextMenu.defaultSection().appendItem(Common.UIString('Close'), doAction.bind(null, 'close'));
-    }
-
-    /**
-     * @param {string} action
-     */
-    function doAction(action) {
-      if (section.page)
-        InspectorFrontendHost.performActionOnRemotePage(section.page.id, action);
-    }
-  }
-
-  /**
-   * @param {!Devices.DevicesView.PageSection} section
-   * @param {!Adb.Page} page
-   */
-  _updatePageSection(section, page) {
-    if (!section.page || section.page.name !== page.name) {
-      section.title.textContent = page.name;
-      section.title.title = page.name;
-    }
-    if (!section.page || section.page.url !== page.url) {
-      section.url.textContent = '';
-      section.url.appendChild(UI.XLink.create(page.url));
-    }
-    section.inspect.disabled = page.attached;
-
-    section.page = page;
-  }
-
-  /**
-   * @param {!Adb.DevicePortForwardingStatus} status
-   */
-  portForwardingStatusChanged(status) {
-    const json = JSON.stringify(status);
-    if (json === this._cachedPortStatus)
-      return;
-    this._cachedPortStatus = json;
-
-    this._portStatus.removeChildren();
-    this._portStatus.createChild('div', 'device-port-status-text').textContent = Common.UIString('Port Forwarding:');
-    const connected = [];
-    const transient = [];
-    const error = [];
-    let empty = true;
-    for (const port in status.ports) {
-      if (!status.ports.hasOwnProperty(port))
-        continue;
-
-      empty = false;
-      const portStatus = status.ports[port];
-      const portNumber = createElementWithClass('div', 'device-view-port-number monospace');
-      portNumber.textContent = ':' + port;
-      if (portStatus >= 0)
-        this._portStatus.appendChild(portNumber);
-      else
-        this._portStatus.insertBefore(portNumber, this._portStatus.firstChild);
-
-      const portIcon = createElementWithClass('div', 'device-view-port-icon');
-      if (portStatus >= 0) {
-        connected.push(port);
-      } else if (portStatus === -1 || portStatus === -2) {
-        portIcon.classList.add('device-view-port-icon-transient');
-        transient.push(port);
-      } else if (portStatus < 0) {
-        portIcon.classList.add('device-view-port-icon-error');
-        error.push(port);
-      }
-      this._portStatus.insertBefore(portIcon, portNumber);
-    }
-
-    const title = [];
-    if (connected.length)
-      title.push(Common.UIString('Connected: %s', connected.join(', ')));
-    if (transient.length)
-      title.push(Common.UIString('Transient: %s', transient.join(', ')));
-    if (error.length)
-      title.push(Common.UIString('Error: %s', error.join(', ')));
-    this._portStatus.title = title.join('; ');
-    this._portStatus.classList.toggle('hidden', empty);
-  }
-};
-
-/** @typedef {!{browser: ?Adb.Browser, element: !Element, title: !Element, pages: !Element, viewMore: !Element, newTab: !Element, pageSections: !Map<string, !Devices.DevicesView.PageSection>}} */
-Devices.DevicesView.BrowserSection;
-
-/** @typedef {!{page: ?Adb.Page, element: !Element, title: !Element, url: !Element, inspect: !Element}} */
-Devices.DevicesView.PageSection;
diff --git a/front_end/devices/devicesView.css b/front_end/devices/devicesView.css
deleted file mode 100644
index 6836381..0000000
--- a/front_end/devices/devicesView.css
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.devices-container {
-    overflow: hidden;
-    flex: auto;
-}
-
-.devices-sidebar {
-    flex: 0 0 150px;
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-    padding-top: 15px;
-}
-
-.devices-sidebar-list {
-    flex: none;
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-}
-
-.devices-sidebar-item {
-    color: #222 !important;
-    padding: 6px 6px 6px 16px;
-    flex: auto;
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-    font-size: 14px;
-}
-
-.devices-sidebar-item.selected {
-    border-left: 6px solid #666 !important;
-    padding-left: 10px;
-}
-
-.devices-sidebar-item-status:before {
-    content: "\25cf";
-    font-size: 16px;
-    color: red;
-    position: relative;
-    top: 1px;
-    margin-right: 2px;
-}
-
-.devices-sidebar-item.device-connected .devices-sidebar-item-status:before {
-    color: green;
-}
-
-.devices-sidebar-spacer {
-    flex: none;
-}
-
-.devices-view-title {
-    font-size: 16px;
-    margin: 0 0 15px 15px;
-    padding-top: 1px;
-}
-
-.view-title {
-    font-size: 16px;
-    flex: none;
-}
-
-.devices-footer {
-    border-top: 1px solid #cdcdcd;
-    background-color: var(--toolbar-bg-color);
-    flex: none;
-    padding: 3px 10px;
-    overflow: hidden;
-}
-
-.devices-footer > span {
-    white-space: pre;
-}
-
-.discovery-view {
-    overflow-x: hidden;
-    overflow-y: auto;
-    padding: 15px 15px 0px 0px;
-}
-
-.discovery-view > * {
-    flex: none;
-}
-
-.usb-checkbox {
-    padding-bottom: 8px;
-    margin-top: 20px;
-}
-
-.port-forwarding-header {
-    display: flex;
-    align-items: center;
-    flex-direction: row;
-    margin-top: 5px;
-}
-
-.add-rule-button {
-    margin: 10px 25px;
-    align-self: flex-start;
-}
-
-.discovery-help {
-    margin: 5px 0 25px 25px;
-}
-
-.discovery-help > span {
-    white-space: pre;
-}
-
-.port-forwarding-list {
-    margin: 10px 0 0 25px;
-    max-width: 500px;
-    flex: none;
-}
-
-.port-forwarding-list-empty {
-    flex: auto;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.port-forwarding-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    position: relative;
-    flex: auto 1 1;
-}
-
-.list-item .port-forwarding-value {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -webkit-user-select: none;
-    color: #222;
-    overflow: hidden;
-}
-
-.port-forwarding-value {
-    flex: 3 1 0;
-}
-
-.port-forwarding-value.port-forwarding-port {
-    flex: 1 1 0;
-}
-
-.port-localhost {
-    color: #aaa;
-}
-
-.port-forwarding-separator {
-    flex: 0 0 1px;
-    background-color: rgb(231, 231, 231);
-    height: 30px;
-    margin: 0 4px;
-}
-
-.port-forwarding-separator-invisible {
-    visibility: hidden;
-    height: 100% !important;
-}
-
-.port-forwarding-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 6px 5px;
-    align-items: center;
-}
-
-.port-forwarding-edit-row input {
-    width: 100%;
-    text-align: inherit;
-}
-
-.port-forwarding-footer {
-    overflow: hidden;
-    margin: 15px 0 0 25px;
-    max-width: 500px;
-}
-
-.port-forwarding-footer > * {
-    white-space: pre-wrap;
-}
-
-.network-discovery-header {
-    display: flex;
-    align-items: center;
-    flex-direction: row;
-    margin-top: 5px;
-}
-
-.add-network-target-button {
-    margin: 10px 25px;
-    align-self: flex-start;
-}
-
-.network-discovery-list {
-    margin: 10px 0 0 25px;
-    max-width: 500px;
-    flex: none;
-}
-
-.network-discovery-list-empty {
-    flex: auto;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.network-discovery-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    position: relative;
-    flex: auto 1 1;
-}
-
-.list-item .network-discovery-value {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -webkit-user-select: none;
-    color: #222;
-    overflow: hidden;
-}
-
-.network-discovery-value {
-    flex: 3 1 0;
-}
-
-.network-discovery-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 6px 5px;
-    align-items: center;
-}
-
-.network-discovery-edit-row input {
-    width: 100%;
-    text-align: inherit;
-}
-
-.network-discovery-footer {
-    overflow: hidden;
-    margin: 15px 0 0 25px;
-    max-width: 500px;
-}
-
-.network-discovery-footer > * {
-    white-space: pre-wrap;
-}
-
-.device-view {
-    overflow: auto;
-    -webkit-user-select: text;
-    flex: auto;
-}
-
-.device-text-row {
-    align-items: baseline;
-    margin-right: 25px;
-}
-
-.device-serial {
-    color: #777;
-    margin-left: 5px;
-    flex: none;
-}
-
-.device-browser-list {
-    flex: auto;
-    overflow: auto;
-    padding-right: 10px;
-    margin-top: 30px;
-}
-
-.device-browser-list > div {
-    margin-bottom: 15px;
-}
-
-.device-browser-title {
-    font-size: 16px;
-}
-
-.device-browser-new-tab {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    margin: 10px 0 0 10px;
-}
-
-.device-browser-new-tab > div {
-    font-size: 13px;
-}
-
-.device-browser-new-tab > input {
-    margin: 0 10px;
-}
-
-.device-page-list {
-    margin: 10px 0 0 10px;
-    overflow-x: auto;
-    align-items: stretch;
-    flex: none;
-}
-
-.device-page-list > div {
-    flex: none;
-    padding: 5px 0;
-}
-
-.device-page-list:not(.device-view-more-toggled) > div.device-view-more-page {
-    display: none;
-}
-
-.device-page-title-row {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-}
-
-.device-page-title {
-    font-size: 15px;
-    flex: auto;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.device-page-title-row .toolbar {
-    margin-left: 3px;
-    padding: 0;
-    border-radius: 3px;
-}
-
-.device-page-title-row .toolbar:hover {
-    background-color: hsl(0, 0%, 90%);
-}
-
-.device-page-url {
-    margin: 3px 100px 3px 0;
-}
-
-.device-page-url a {
-    color: #777;
-    word-break: break-all;
-}
-
-.device-view-more {
-    cursor: pointer;
-    text-decoration: underline;
-    color: rgb(17, 85, 204);
-    margin: 5px 0 0 10px;
-    display: none;
-}
-
-.device-view-more.device-needs-view-more  {
-    display: block;
-}
-
-.device-port-status {
-    overflow: hidden;
-    flex: none;
-    display: flex;
-    align-items: baseline;
-    margin: 10px 0 0 10px;
-}
-
-.device-port-status-text {
-    margin-right: 10px;
-}
-
-.device-view-port-icon {
-    background-color: green;
-    border: 0 solid transparent;
-    border-radius: 6px;
-    height: 12px;
-    width: 12px;
-    position: relative;
-    top: 2px;
-    flex: none;
-}
-
-.device-view-port-number {
-    margin: 0 10px 0 2px;
-    flex: none;
-}
-
-.device-view-port-icon.device-view-port-icon-error {
-    background-color: red;
-}
-
-.device-view-port-icon.device-view-port-icon-transient {
-    transform: scale(1.2);
-    background-color: orange;
-}
diff --git a/front_end/devices/module.json b/front_end/devices/module.json
deleted file mode 100644
index 4231f0a..0000000
--- a/front_end/devices/module.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "remote-devices",
-            "title": "Remote devices",
-            "persistence": "closeable",
-            "order": 50,
-            "className": "Devices.DevicesView",
-            "tags": "usb, android, mobile"
-        }
-    ],
-    "dependencies": ["platform", "ui", "host", "components"],
-    "scripts": [
-        "DevicesView.js"
-    ],
-    "resources": [
-        "devicesView.css"
-    ]
-}
diff --git a/front_end/devtools_app.html b/front_end/devtools_app.html
deleted file mode 100644
index c0b162b..0000000
--- a/front_end/devtools_app.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <meta name="referrer" content="no-referrer">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="devtools_app.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/devtools_app.js b/front_end/devtools_app.js
deleted file mode 100644
index 17310fa..0000000
--- a/front_end/devtools_app.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Runtime.startApplication('devtools_app');
diff --git a/front_end/devtools_app.json b/front_end/devtools_app.json
deleted file mode 100644
index e444158..0000000
--- a/front_end/devtools_app.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "modules" : [
-    { "name": "emulation", "type": "autostart" },
-    { "name": "inspector_main", "type": "autostart" },
-    { "name": "mobile_throttling", "type": "autostart" },
-    { "name": "browser_components", "type": "autostart" },
-
-    { "name": "accessibility", "type": "remote" },
-    { "name": "animation" },
-    { "name": "audits2" },
-    { "name": "browser_console" },
-    { "name": "browser_debugger" },
-    { "name": "cookie_table" },
-    { "name": "devices" },
-    { "name": "elements" },
-    { "name": "emulated_devices" , "type": "remote" },
-    { "name": "har_importer" },
-    { "name": "help" },
-    { "name": "layers" },
-    { "name": "layer_viewer" },
-    { "name": "network" },
-    { "name": "performance_monitor" },
-    { "name": "product_registry_impl", "type": "remote" },
-    { "name": "resources" },
-    { "name": "security" },
-    { "name": "timeline" },
-    { "name": "timeline_model" }
-  ],
-  "extends": "shell",
-  "has_html": true
-}
diff --git a/front_end/devtools_compatibility.js b/front_end/devtools_compatibility.js
deleted file mode 100644
index e4ddb50..0000000
--- a/front_end/devtools_compatibility.js
+++ /dev/null
@@ -1,1337 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/* eslint-disable indent */
-(function(window) {
-
-  // DevToolsAPI ----------------------------------------------------------------
-
-  /**
-   * @unrestricted
-   */
-  const DevToolsAPIImpl = class {
-    constructor() {
-      /**
-       * @type {number}
-       */
-      this._lastCallId = 0;
-
-      /**
-       * @type {!Object.<number, function(?Object)>}
-       */
-      this._callbacks = {};
-    }
-
-    /**
-     * @param {number} id
-     * @param {?Object} arg
-     */
-    embedderMessageAck(id, arg) {
-      const callback = this._callbacks[id];
-      delete this._callbacks[id];
-      if (callback)
-        callback(arg);
-    }
-
-    /**
-     * @param {string} method
-     * @param {!Array.<*>} args
-     * @param {?function(?Object)} callback
-     */
-    sendMessageToEmbedder(method, args, callback) {
-      const callId = ++this._lastCallId;
-      if (callback)
-        this._callbacks[callId] = callback;
-      const message = {'id': callId, 'method': method};
-      if (args.length)
-        message.params = args;
-      DevToolsHost.sendMessageToEmbedder(JSON.stringify(message));
-    }
-
-    /**
-     * @param {string} method
-     * @param {!Array<*>} args
-     */
-    _dispatchOnInspectorFrontendAPI(method, args) {
-      const inspectorFrontendAPI = /** @type {!Object<string, function()>} */ (window['InspectorFrontendAPI']);
-      inspectorFrontendAPI[method].apply(inspectorFrontendAPI, args);
-    }
-
-    // API methods below this line --------------------------------------------
-
-    /**
-     * @param {!Array.<!ExtensionDescriptor>} extensions
-     */
-    addExtensions(extensions) {
-      // Support for legacy front-ends (<M41).
-      if (window['WebInspector'] && window['WebInspector']['addExtensions']) {
-        window['WebInspector']['addExtensions'](extensions);
-      } else if (window['InspectorFrontendAPI']) {
-        // The addExtensions command is sent as the onload event happens for
-        // DevTools front-end. In case of hosted mode, this
-        // happens before the InspectorFrontendAPI is initialized.
-        this._dispatchOnInspectorFrontendAPI('addExtensions', [extensions]);
-      }
-    }
-
-    /**
-     * @param {string} url
-     */
-    appendedToURL(url) {
-      this._dispatchOnInspectorFrontendAPI('appendedToURL', [url]);
-    }
-
-    /**
-     * @param {string} url
-     */
-    canceledSaveURL(url) {
-      this._dispatchOnInspectorFrontendAPI('canceledSaveURL', [url]);
-    }
-
-    contextMenuCleared() {
-      this._dispatchOnInspectorFrontendAPI('contextMenuCleared', []);
-    }
-
-    /**
-     * @param {string} id
-     */
-    contextMenuItemSelected(id) {
-      this._dispatchOnInspectorFrontendAPI('contextMenuItemSelected', [id]);
-    }
-
-    /**
-     * @param {number} count
-     */
-    deviceCountUpdated(count) {
-      this._dispatchOnInspectorFrontendAPI('deviceCountUpdated', [count]);
-    }
-
-    /**
-     * @param {!Adb.Config} config
-     */
-    devicesDiscoveryConfigChanged(config) {
-      this._dispatchOnInspectorFrontendAPI('devicesDiscoveryConfigChanged', [config]);
-    }
-
-    /**
-     * @param {!Adb.PortForwardingStatus} status
-     */
-    devicesPortForwardingStatusChanged(status) {
-      this._dispatchOnInspectorFrontendAPI('devicesPortForwardingStatusChanged', [status]);
-    }
-
-    /**
-     * @param {!Array.<!Adb.Device>} devices
-     */
-    devicesUpdated(devices) {
-      this._dispatchOnInspectorFrontendAPI('devicesUpdated', [devices]);
-    }
-
-    /**
-     * @param {string} message
-     */
-    dispatchMessage(message) {
-      this._dispatchOnInspectorFrontendAPI('dispatchMessage', [message]);
-    }
-
-    /**
-     * @param {string} messageChunk
-     * @param {number} messageSize
-     */
-    dispatchMessageChunk(messageChunk, messageSize) {
-      this._dispatchOnInspectorFrontendAPI('dispatchMessageChunk', [messageChunk, messageSize]);
-    }
-
-    enterInspectElementMode() {
-      this._dispatchOnInspectorFrontendAPI('enterInspectElementMode', []);
-    }
-
-    /**
-     * @param {!{r: number, g: number, b: number, a: number}} color
-     */
-    eyeDropperPickedColor(color) {
-      this._dispatchOnInspectorFrontendAPI('eyeDropperPickedColor', [color]);
-    }
-
-    /**
-     * @param {!Array.<!{fileSystemName: string, rootURL: string, fileSystemPath: string}>} fileSystems
-     */
-    fileSystemsLoaded(fileSystems) {
-      this._dispatchOnInspectorFrontendAPI('fileSystemsLoaded', [fileSystems]);
-    }
-
-    /**
-     * @param {string} fileSystemPath
-     */
-    fileSystemRemoved(fileSystemPath) {
-      this._dispatchOnInspectorFrontendAPI('fileSystemRemoved', [fileSystemPath]);
-    }
-
-    /**
-     * @param {?string} error
-     * @param {?{type: string, fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem
-     */
-    fileSystemAdded(error, fileSystem) {
-      this._dispatchOnInspectorFrontendAPI('fileSystemAdded', [error, fileSystem]);
-    }
-
-    /**
-     * @param {!Array<string>} changedPaths
-     * @param {!Array<string>} addedPaths
-     * @param {!Array<string>} removedPaths
-     */
-    fileSystemFilesChangedAddedRemoved(changedPaths, addedPaths, removedPaths) {
-      // Support for legacy front-ends (<M58)
-      if (window['InspectorFrontendAPI'] && window['InspectorFrontendAPI']['fileSystemFilesChanged']) {
-        this._dispatchOnInspectorFrontendAPI(
-            'fileSystemFilesChanged', [changedPaths.concat(addedPaths).concat(removedPaths)]);
-      } else {
-        this._dispatchOnInspectorFrontendAPI(
-            'fileSystemFilesChangedAddedRemoved', [changedPaths, addedPaths, removedPaths]);
-      }
-    }
-
-    /**
-     * @param {number} requestId
-     * @param {string} fileSystemPath
-     * @param {number} totalWork
-     */
-    indexingTotalWorkCalculated(requestId, fileSystemPath, totalWork) {
-      this._dispatchOnInspectorFrontendAPI('indexingTotalWorkCalculated', [requestId, fileSystemPath, totalWork]);
-    }
-
-    /**
-     * @param {number} requestId
-     * @param {string} fileSystemPath
-     * @param {number} worked
-     */
-    indexingWorked(requestId, fileSystemPath, worked) {
-      this._dispatchOnInspectorFrontendAPI('indexingWorked', [requestId, fileSystemPath, worked]);
-    }
-
-    /**
-     * @param {number} requestId
-     * @param {string} fileSystemPath
-     */
-    indexingDone(requestId, fileSystemPath) {
-      this._dispatchOnInspectorFrontendAPI('indexingDone', [requestId, fileSystemPath]);
-    }
-
-    /**
-     * @param {{type: string, key: string, code: string, keyCode: number, modifiers: number}} event
-     */
-    keyEventUnhandled(event) {
-      event.keyIdentifier = keyCodeToKeyIdentifier(event.keyCode);
-      this._dispatchOnInspectorFrontendAPI('keyEventUnhandled', [event]);
-    }
-
-    /**
-     * @param {boolean} hard
-     */
-    reloadInspectedPage(hard) {
-      this._dispatchOnInspectorFrontendAPI('reloadInspectedPage', [hard]);
-    }
-
-    /**
-     * @param {string} url
-     * @param {number} lineNumber
-     * @param {number} columnNumber
-     */
-    revealSourceLine(url, lineNumber, columnNumber) {
-      this._dispatchOnInspectorFrontendAPI('revealSourceLine', [url, lineNumber, columnNumber]);
-    }
-
-    /**
-     * @param {string} url
-     * @param {string=} fileSystemPath
-     */
-    savedURL(url, fileSystemPath) {
-      this._dispatchOnInspectorFrontendAPI('savedURL', [url, fileSystemPath]);
-    }
-
-    /**
-     * @param {number} requestId
-     * @param {string} fileSystemPath
-     * @param {!Array.<string>} files
-     */
-    searchCompleted(requestId, fileSystemPath, files) {
-      this._dispatchOnInspectorFrontendAPI('searchCompleted', [requestId, fileSystemPath, files]);
-    }
-
-    /**
-     * @param {string} tabId
-     */
-    setInspectedTabId(tabId) {
-      // Support for legacy front-ends (<M41).
-      if (window['WebInspector'] && window['WebInspector']['setInspectedTabId'])
-        window['WebInspector']['setInspectedTabId'](tabId);
-      else
-        this._dispatchOnInspectorFrontendAPI('setInspectedTabId', [tabId]);
-    }
-
-    /**
-     * @param {boolean} useSoftMenu
-     */
-    setUseSoftMenu(useSoftMenu) {
-      this._dispatchOnInspectorFrontendAPI('setUseSoftMenu', [useSoftMenu]);
-    }
-
-    /**
-     * @param {string} panelName
-     */
-    showPanel(panelName) {
-      this._dispatchOnInspectorFrontendAPI('showPanel', [panelName]);
-    }
-
-    /**
-     * @param {number} id
-     * @param {string} chunk
-     * @param {boolean} encoded
-     */
-    streamWrite(id, chunk, encoded) {
-      this._dispatchOnInspectorFrontendAPI('streamWrite', [id, encoded ? this._decodeBase64(chunk) : chunk]);
-    }
-
-    /**
-     * @param {string} chunk
-     * @return {string}
-     */
-    _decodeBase64(chunk) {
-      const request = new XMLHttpRequest();
-      request.open('GET', 'data:text/plain;base64,' + chunk, false);
-      request.send(null);
-      if (request.status === 200) {
-        return request.responseText;
-      } else {
-        console.error('Error while decoding chunk in streamWrite');
-        return '';
-      }
-    }
-  };
-
-  const DevToolsAPI = new DevToolsAPIImpl();
-  window.DevToolsAPI = DevToolsAPI;
-
-  // InspectorFrontendHostImpl --------------------------------------------------
-
-  /**
-   * @implements {InspectorFrontendHostAPI}
-   * @unrestricted
-   */
-  const InspectorFrontendHostImpl = class {
-    /**
-     * @override
-     * @return {string}
-     */
-    getSelectionBackgroundColor() {
-      return DevToolsHost.getSelectionBackgroundColor();
-    }
-
-    /**
-     * @override
-     * @return {string}
-     */
-    getSelectionForegroundColor() {
-      return DevToolsHost.getSelectionForegroundColor();
-    }
-
-    /**
-     * @override
-     * @return {string}
-     */
-    getInactiveSelectionBackgroundColor() {
-      return DevToolsHost.getInactiveSelectionBackgroundColor();
-    }
-
-    /**
-     * @override
-     * @return {string}
-     */
-    getInactiveSelectionForegroundColor() {
-      return DevToolsHost.getInactiveSelectionForegroundColor();
-    }
-
-    /**
-     * @override
-     * @return {string}
-     */
-    platform() {
-      return DevToolsHost.platform();
-    }
-
-    /**
-     * @override
-     */
-    loadCompleted() {
-      DevToolsAPI.sendMessageToEmbedder('loadCompleted', [], null);
-      // Support for legacy (<57) frontends.
-      if (window.Runtime && window.Runtime.queryParam) {
-        const panelToOpen = window.Runtime.queryParam('panel');
-        if (panelToOpen)
-          window.DevToolsAPI.showPanel(panelToOpen);
-      }
-    }
-
-    /**
-     * @override
-     */
-    bringToFront() {
-      DevToolsAPI.sendMessageToEmbedder('bringToFront', [], null);
-    }
-
-    /**
-     * @override
-     */
-    closeWindow() {
-      DevToolsAPI.sendMessageToEmbedder('closeWindow', [], null);
-    }
-
-    /**
-     * @override
-     * @param {boolean} isDocked
-     * @param {function()} callback
-     */
-    setIsDocked(isDocked, callback) {
-      DevToolsAPI.sendMessageToEmbedder('setIsDocked', [isDocked], callback);
-    }
-
-    /**
-     * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
-     * @override
-     * @param {{x: number, y: number, width: number, height: number}} bounds
-     */
-    setInspectedPageBounds(bounds) {
-      DevToolsAPI.sendMessageToEmbedder('setInspectedPageBounds', [bounds], null);
-    }
-
-    /**
-     * @override
-     */
-    inspectElementCompleted() {
-      DevToolsAPI.sendMessageToEmbedder('inspectElementCompleted', [], null);
-    }
-
-    /**
-     * @override
-     * @param {string} url
-     * @param {string} headers
-     * @param {number} streamId
-     * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback
-     */
-    loadNetworkResource(url, headers, streamId, callback) {
-      DevToolsAPI.sendMessageToEmbedder(
-          'loadNetworkResource', [url, headers, streamId], /** @type {function(?Object)} */ (callback));
-    }
-
-    /**
-     * @override
-     * @param {function(!Object<string, string>)} callback
-     */
-    getPreferences(callback) {
-      DevToolsAPI.sendMessageToEmbedder('getPreferences', [], /** @type {function(?Object)} */ (callback));
-    }
-
-    /**
-     * @override
-     * @param {string} name
-     * @param {string} value
-     */
-    setPreference(name, value) {
-      DevToolsAPI.sendMessageToEmbedder('setPreference', [name, value], null);
-    }
-
-    /**
-     * @override
-     * @param {string} name
-     */
-    removePreference(name) {
-      DevToolsAPI.sendMessageToEmbedder('removePreference', [name], null);
-    }
-
-    /**
-     * @override
-     */
-    clearPreferences() {
-      DevToolsAPI.sendMessageToEmbedder('clearPreferences', [], null);
-    }
-
-    /**
-     * @override
-     * @param {string} origin
-     * @param {string} script
-     */
-    setInjectedScriptForOrigin(origin, script) {
-      DevToolsAPI.sendMessageToEmbedder('registerExtensionsAPI', [origin, script], null);
-    }
-
-    /**
-     * @override
-     * @param {string} url
-     */
-    inspectedURLChanged(url) {
-      DevToolsAPI.sendMessageToEmbedder('inspectedURLChanged', [url], null);
-    }
-
-    /**
-     * @override
-     * @param {string} text
-     */
-    copyText(text) {
-      DevToolsHost.copyText(text);
-    }
-
-    /**
-     * @override
-     * @param {string} url
-     */
-    openInNewTab(url) {
-      DevToolsAPI.sendMessageToEmbedder('openInNewTab', [url], null);
-    }
-
-    /**
-     * @override
-     * @param {string} fileSystemPath
-     */
-    showItemInFolder(fileSystemPath) {
-      DevToolsAPI.sendMessageToEmbedder('showItemInFolder', [fileSystemPath], null);
-    }
-
-    /**
-     * @override
-     * @param {string} url
-     * @param {string} content
-     * @param {boolean} forceSaveAs
-     */
-    save(url, content, forceSaveAs) {
-      DevToolsAPI.sendMessageToEmbedder('save', [url, content, forceSaveAs], null);
-    }
-
-    /**
-     * @override
-     * @param {string} url
-     * @param {string} content
-     */
-    append(url, content) {
-      DevToolsAPI.sendMessageToEmbedder('append', [url, content], null);
-    }
-
-    /**
-     * @override
-     * @param {string} message
-     */
-    sendMessageToBackend(message) {
-      DevToolsAPI.sendMessageToEmbedder('dispatchProtocolMessage', [message], null);
-    }
-
-    /**
-     * @override
-     * @param {string} actionName
-     * @param {number} actionCode
-     * @param {number} bucketSize
-     */
-    recordEnumeratedHistogram(actionName, actionCode, bucketSize) {
-      // Support for M49 frontend.
-      if (actionName === 'DevTools.DrawerShown')
-        return;
-      DevToolsAPI.sendMessageToEmbedder('recordEnumeratedHistogram', [actionName, actionCode, bucketSize], null);
-    }
-
-    /**
-     * @override
-     */
-    requestFileSystems() {
-      DevToolsAPI.sendMessageToEmbedder('requestFileSystems', [], null);
-    }
-
-    /**
-     * @override
-     * @param {string=} type
-     */
-    addFileSystem(type) {
-      DevToolsAPI.sendMessageToEmbedder('addFileSystem', [type || ''], null);
-    }
-
-    /**
-     * @override
-     * @param {string} fileSystemPath
-     */
-    removeFileSystem(fileSystemPath) {
-      DevToolsAPI.sendMessageToEmbedder('removeFileSystem', [fileSystemPath], null);
-    }
-
-    /**
-     * @override
-     * @param {string} fileSystemId
-     * @param {string} registeredName
-     * @return {?DOMFileSystem}
-     */
-    isolatedFileSystem(fileSystemId, registeredName) {
-      return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName);
-    }
-
-    /**
-     * @override
-     * @param {!FileSystem} fileSystem
-     */
-    upgradeDraggedFileSystemPermissions(fileSystem) {
-      DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem);
-    }
-
-    /**
-     * @override
-     * @param {number} requestId
-     * @param {string} fileSystemPath
-     * @param {string} excludedFolders
-     */
-    indexPath(requestId, fileSystemPath, excludedFolders) {
-      // |excludedFolders| added in M67. For backward compatibility,
-      // pass empty array.
-      excludedFolders = excludedFolders || '[]';
-      DevToolsAPI.sendMessageToEmbedder('indexPath', [requestId, fileSystemPath, excludedFolders], null);
-    }
-
-    /**
-     * @override
-     * @param {number} requestId
-     */
-    stopIndexing(requestId) {
-      DevToolsAPI.sendMessageToEmbedder('stopIndexing', [requestId], null);
-    }
-
-    /**
-     * @override
-     * @param {number} requestId
-     * @param {string} fileSystemPath
-     * @param {string} query
-     */
-    searchInPath(requestId, fileSystemPath, query) {
-      DevToolsAPI.sendMessageToEmbedder('searchInPath', [requestId, fileSystemPath, query], null);
-    }
-
-    /**
-     * @override
-     * @return {number}
-     */
-    zoomFactor() {
-      return DevToolsHost.zoomFactor();
-    }
-
-    /**
-     * @override
-     */
-    zoomIn() {
-      DevToolsAPI.sendMessageToEmbedder('zoomIn', [], null);
-    }
-
-    /**
-     * @override
-     */
-    zoomOut() {
-      DevToolsAPI.sendMessageToEmbedder('zoomOut', [], null);
-    }
-
-    /**
-     * @override
-     */
-    resetZoom() {
-      DevToolsAPI.sendMessageToEmbedder('resetZoom', [], null);
-    }
-
-    /**
-     * @override
-     * @param {string} shortcuts
-     */
-    setWhitelistedShortcuts(shortcuts) {
-      DevToolsAPI.sendMessageToEmbedder('setWhitelistedShortcuts', [shortcuts], null);
-    }
-
-    /**
-     * @override
-     * @param {boolean} active
-     */
-    setEyeDropperActive(active) {
-      DevToolsAPI.sendMessageToEmbedder('setEyeDropperActive', [active], null);
-    }
-
-    /**
-     * @override
-     * @param {!Array<string>} certChain
-     */
-    showCertificateViewer(certChain) {
-      DevToolsAPI.sendMessageToEmbedder('showCertificateViewer', [JSON.stringify(certChain)], null);
-    }
-
-    /**
-     * @override
-     * @param {function()} callback
-     */
-    reattach(callback) {
-      DevToolsAPI.sendMessageToEmbedder('reattach', [], callback);
-    }
-
-    /**
-     * @override
-     */
-    readyForTest() {
-      DevToolsAPI.sendMessageToEmbedder('readyForTest', [], null);
-    }
-
-    /**
-     * @override
-     */
-    connectionReady() {
-      DevToolsAPI.sendMessageToEmbedder('connectionReady', [], null);
-    }
-
-    /**
-     * @override
-     * @param {boolean} value
-     */
-    setOpenNewWindowForPopups(value) {
-      DevToolsAPI.sendMessageToEmbedder('setOpenNewWindowForPopups', [value], null);
-    }
-
-    /**
-     * @override
-     * @param {!Adb.Config} config
-     */
-    setDevicesDiscoveryConfig(config) {
-      DevToolsAPI.sendMessageToEmbedder(
-          'setDevicesDiscoveryConfig',
-          [
-            config.discoverUsbDevices, config.portForwardingEnabled, JSON.stringify(config.portForwardingConfig),
-            config.networkDiscoveryEnabled, JSON.stringify(config.networkDiscoveryConfig)
-          ],
-          null);
-    }
-
-    /**
-     * @override
-     * @param {boolean} enabled
-     */
-    setDevicesUpdatesEnabled(enabled) {
-      DevToolsAPI.sendMessageToEmbedder('setDevicesUpdatesEnabled', [enabled], null);
-    }
-
-    /**
-     * @override
-     * @param {string} pageId
-     * @param {string} action
-     */
-    performActionOnRemotePage(pageId, action) {
-      DevToolsAPI.sendMessageToEmbedder('performActionOnRemotePage', [pageId, action], null);
-    }
-
-    /**
-     * @override
-     * @param {string} browserId
-     * @param {string} url
-     */
-    openRemotePage(browserId, url) {
-      DevToolsAPI.sendMessageToEmbedder('openRemotePage', [browserId, url], null);
-    }
-
-    /**
-     * @override
-     */
-    openNodeFrontend() {
-      DevToolsAPI.sendMessageToEmbedder('openNodeFrontend', [], null);
-    }
-
-    /**
-     * @override
-     * @param {number} x
-     * @param {number} y
-     * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
-     * @param {!Document} document
-     */
-    showContextMenuAtPoint(x, y, items, document) {
-      DevToolsHost.showContextMenuAtPoint(x, y, items, document);
-    }
-
-    /**
-     * @override
-     * @return {boolean}
-     */
-    isHostedMode() {
-      return DevToolsHost.isHostedMode();
-    }
-
-    // Backward-compatible methods below this line --------------------------------------------
-
-    /**
-     * Support for legacy front-ends (<M65).
-     * @return {boolean}
-     */
-    isUnderTest() {
-      return false;
-    }
-
-    /**
-     * Support for legacy front-ends (<M50).
-     * @param {string} message
-     */
-    sendFrontendAPINotification(message) {
-    }
-
-    /**
-     * Support for legacy front-ends (<M41).
-     * @return {string}
-     */
-    port() {
-      return 'unknown';
-    }
-
-    /**
-     * Support for legacy front-ends (<M38).
-     * @param {number} zoomFactor
-     */
-    setZoomFactor(zoomFactor) {
-    }
-
-    /**
-     * Support for legacy front-ends (<M34).
-     */
-    sendMessageToEmbedder() {
-    }
-
-    /**
-     * Support for legacy front-ends (<M34).
-     * @param {string} dockSide
-     */
-    requestSetDockSide(dockSide) {
-      DevToolsAPI.sendMessageToEmbedder('setIsDocked', [dockSide !== 'undocked'], null);
-    }
-
-    /**
-     * Support for legacy front-ends (<M34).
-     * @return {boolean}
-     */
-    supportsFileSystems() {
-      return true;
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     * @return {boolean}
-     */
-    canInspectWorkers() {
-      return true;
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     * @return {boolean}
-     */
-    canSaveAs() {
-      return true;
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     * @return {boolean}
-     */
-    canSave() {
-      return true;
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     */
-    loaded() {
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     * @return {string}
-     */
-    hiddenPanels() {
-      return '';
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     * @return {string}
-     */
-    localizedStringsURL() {
-      return '';
-    }
-
-    /**
-     * Support for legacy front-ends (<M28).
-     * @param {string} url
-     */
-    close(url) {
-    }
-
-    /**
-     * Support for legacy front-ends (<M44).
-     * @param {number} actionCode
-     */
-    recordActionTaken(actionCode) {
-      this.recordEnumeratedHistogram('DevTools.ActionTaken', actionCode, 100);
-    }
-
-    /**
-     * Support for legacy front-ends (<M44).
-     * @param {number} panelCode
-     */
-    recordPanelShown(panelCode) {
-      this.recordEnumeratedHistogram('DevTools.PanelShown', panelCode, 20);
-    }
-  };
-
-  window.InspectorFrontendHost = new InspectorFrontendHostImpl();
-
-  // DevToolsApp ---------------------------------------------------------------
-
-  function installObjectObserve() {
-    /** @type {!Array<string>} */
-    const properties = [
-      'advancedSearchConfig',
-      'auditsPanelSplitViewState',
-      'auditsSidebarWidth',
-      'blockedURLs',
-      'breakpoints',
-      'cacheDisabled',
-      'colorFormat',
-      'consoleHistory',
-      'consoleTimestampsEnabled',
-      'cpuProfilerView',
-      'cssSourceMapsEnabled',
-      'currentDockState',
-      'customColorPalette',
-      'customDevicePresets',
-      'customEmulatedDeviceList',
-      'customFormatters',
-      'customUserAgent',
-      'databaseTableViewVisibleColumns',
-      'dataGrid-cookiesTable',
-      'dataGrid-DOMStorageItemsView',
-      'debuggerSidebarHidden',
-      'disableDataSaverInfobar',
-      'disablePausedStateOverlay',
-      'domBreakpoints',
-      'domWordWrap',
-      'elementsPanelSplitViewState',
-      'elementsSidebarWidth',
-      'emulation.deviceHeight',
-      'emulation.deviceModeValue',
-      'emulation.deviceOrientationOverride',
-      'emulation.deviceScale',
-      'emulation.deviceScaleFactor',
-      'emulation.deviceUA',
-      'emulation.deviceWidth',
-      'emulation.geolocationOverride',
-      'emulation.showDeviceMode',
-      'emulation.showRulers',
-      'enableAsyncStackTraces',
-      'eventListenerBreakpoints',
-      'fileMappingEntries',
-      'fileSystemMapping',
-      'FileSystemViewSidebarWidth',
-      'fileSystemViewSplitViewState',
-      'filterBar-consoleView',
-      'filterBar-networkPanel',
-      'filterBar-promisePane',
-      'filterBar-timelinePanel',
-      'frameViewerHideChromeWindow',
-      'heapSnapshotRetainersViewSize',
-      'heapSnapshotSplitViewState',
-      'hideCollectedPromises',
-      'hideNetworkMessages',
-      'highlightNodeOnHoverInOverlay',
-      'highResolutionCpuProfiling',
-      'inlineVariableValues',
-      'Inspector.drawerSplitView',
-      'Inspector.drawerSplitViewState',
-      'InspectorView.panelOrder',
-      'InspectorView.screencastSplitView',
-      'InspectorView.screencastSplitViewState',
-      'InspectorView.splitView',
-      'InspectorView.splitViewState',
-      'javaScriptDisabled',
-      'jsSourceMapsEnabled',
-      'lastActivePanel',
-      'lastDockState',
-      'lastSelectedSourcesSidebarPaneTab',
-      'lastSnippetEvaluationIndex',
-      'layerDetailsSplitView',
-      'layerDetailsSplitViewState',
-      'layersPanelSplitViewState',
-      'layersShowInternalLayers',
-      'layersSidebarWidth',
-      'messageLevelFilters',
-      'messageURLFilters',
-      'monitoringXHREnabled',
-      'navigatorGroupByFolder',
-      'navigatorHidden',
-      'networkColorCodeResourceTypes',
-      'networkConditions',
-      'networkConditionsCustomProfiles',
-      'networkHideDataURL',
-      'networkLogColumnsVisibility',
-      'networkLogLargeRows',
-      'networkLogShowOverview',
-      'networkPanelSplitViewState',
-      'networkRecordFilmStripSetting',
-      'networkResourceTypeFilters',
-      'networkShowPrimaryLoadWaterfall',
-      'networkSidebarWidth',
-      'openLinkHandler',
-      'pauseOnCaughtException',
-      'pauseOnExceptionEnabled',
-      'preserveConsoleLog',
-      'prettyPrintInfobarDisabled',
-      'previouslyViewedFiles',
-      'profilesPanelSplitViewState',
-      'profilesSidebarWidth',
-      'promiseStatusFilters',
-      'recordAllocationStacks',
-      'requestHeaderFilterSetting',
-      'request-info-formData-category-expanded',
-      'request-info-general-category-expanded',
-      'request-info-queryString-category-expanded',
-      'request-info-requestHeaders-category-expanded',
-      'request-info-requestPayload-category-expanded',
-      'request-info-responseHeaders-category-expanded',
-      'resources',
-      'resourcesLastSelectedItem',
-      'resourcesPanelSplitViewState',
-      'resourcesSidebarWidth',
-      'resourceViewTab',
-      'savedURLs',
-      'screencastEnabled',
-      'scriptsPanelNavigatorSidebarWidth',
-      'searchInContentScripts',
-      'selectedAuditCategories',
-      'selectedColorPalette',
-      'selectedProfileType',
-      'shortcutPanelSwitch',
-      'showAdvancedHeapSnapshotProperties',
-      'showEventListenersForAncestors',
-      'showFrameowkrListeners',
-      'showHeaSnapshotObjectsHiddenProperties',
-      'showInheritedComputedStyleProperties',
-      'showMediaQueryInspector',
-      'showNativeFunctionsInJSProfile',
-      'showUAShadowDOM',
-      'showWhitespacesInEditor',
-      'sidebarPosition',
-      'skipContentScripts',
-      'skipStackFramesPattern',
-      'sourceMapInfobarDisabled',
-      'sourcesPanelDebuggerSidebarSplitViewState',
-      'sourcesPanelNavigatorSplitViewState',
-      'sourcesPanelSplitSidebarRatio',
-      'sourcesPanelSplitViewState',
-      'sourcesSidebarWidth',
-      'standardEmulatedDeviceList',
-      'StylesPaneSplitRatio',
-      'stylesPaneSplitViewState',
-      'textEditorAutocompletion',
-      'textEditorAutoDetectIndent',
-      'textEditorBracketMatching',
-      'textEditorIndent',
-      'timelineCaptureFilmStrip',
-      'timelineCaptureLayersAndPictures',
-      'timelineCaptureMemory',
-      'timelineCaptureNetwork',
-      'timeline-details',
-      'timelineEnableJSSampling',
-      'timelineOverviewMode',
-      'timelinePanelDetailsSplitViewState',
-      'timelinePanelRecorsSplitViewState',
-      'timelinePanelTimelineStackSplitViewState',
-      'timelinePerspective',
-      'timeline-split',
-      'timelineTreeGroupBy',
-      'timeline-view',
-      'timelineViewMode',
-      'uiTheme',
-      'watchExpressions',
-      'WebInspector.Drawer.lastSelectedView',
-      'WebInspector.Drawer.showOnLoad',
-      'workspaceExcludedFolders',
-      'workspaceFolderExcludePattern',
-      'workspaceInfobarDisabled',
-      'workspaceMappingInfobarDisabled',
-      'xhrBreakpoints'
-    ];
-
-    /**
-     * @this {!{_storage: Object, _name: string}}
-     */
-    function settingRemove() {
-      this._storage[this._name] = undefined;
-    }
-
-    /**
-     * @param {!Object} object
-     * @param {function(!Array<!{name: string}>)} observer
-     */
-    function objectObserve(object, observer) {
-      if (window['WebInspector']) {
-        const settingPrototype = /** @type {!Object} */ (window['WebInspector']['Setting']['prototype']);
-        if (typeof settingPrototype['remove'] === 'function')
-          settingPrototype['remove'] = settingRemove;
-      }
-      /** @type {!Set<string>} */
-      const changedProperties = new Set();
-      let scheduled = false;
-
-      function scheduleObserver() {
-        if (scheduled)
-          return;
-        scheduled = true;
-        setImmediate(callObserver);
-      }
-
-      function callObserver() {
-        scheduled = false;
-        const changes = /** @type {!Array<!{name: string}>} */ ([]);
-        changedProperties.forEach(function(name) {
-          changes.push({name: name});
-        });
-        changedProperties.clear();
-        observer.call(null, changes);
-      }
-
-      /** @type {!Map<string, *>} */
-      const storage = new Map();
-
-      /**
-       * @param {string} property
-       */
-      function defineProperty(property) {
-        if (property in object) {
-          storage.set(property, object[property]);
-          delete object[property];
-        }
-
-        Object.defineProperty(object, property, {
-          /**
-           * @return {*}
-           */
-          get: function() {
-            return storage.get(property);
-          },
-
-          /**
-           * @param {*} value
-           */
-          set: function(value) {
-            storage.set(property, value);
-            changedProperties.add(property);
-            scheduleObserver();
-          }
-        });
-      }
-
-      for (let i = 0; i < properties.length; ++i)
-        defineProperty(properties[i]);
-    }
-
-    window.Object.observe = objectObserve;
-  }
-
-  /** @type {!Map<number, string>} */
-  const staticKeyIdentifiers = new Map([
-    [0x12, 'Alt'],
-    [0x11, 'Control'],
-    [0x10, 'Shift'],
-    [0x14, 'CapsLock'],
-    [0x5b, 'Win'],
-    [0x5c, 'Win'],
-    [0x0c, 'Clear'],
-    [0x28, 'Down'],
-    [0x23, 'End'],
-    [0x0a, 'Enter'],
-    [0x0d, 'Enter'],
-    [0x2b, 'Execute'],
-    [0x70, 'F1'],
-    [0x71, 'F2'],
-    [0x72, 'F3'],
-    [0x73, 'F4'],
-    [0x74, 'F5'],
-    [0x75, 'F6'],
-    [0x76, 'F7'],
-    [0x77, 'F8'],
-    [0x78, 'F9'],
-    [0x79, 'F10'],
-    [0x7a, 'F11'],
-    [0x7b, 'F12'],
-    [0x7c, 'F13'],
-    [0x7d, 'F14'],
-    [0x7e, 'F15'],
-    [0x7f, 'F16'],
-    [0x80, 'F17'],
-    [0x81, 'F18'],
-    [0x82, 'F19'],
-    [0x83, 'F20'],
-    [0x84, 'F21'],
-    [0x85, 'F22'],
-    [0x86, 'F23'],
-    [0x87, 'F24'],
-    [0x2f, 'Help'],
-    [0x24, 'Home'],
-    [0x2d, 'Insert'],
-    [0x25, 'Left'],
-    [0x22, 'PageDown'],
-    [0x21, 'PageUp'],
-    [0x13, 'Pause'],
-    [0x2c, 'PrintScreen'],
-    [0x27, 'Right'],
-    [0x91, 'Scroll'],
-    [0x29, 'Select'],
-    [0x26, 'Up'],
-    [0x2e, 'U+007F'],  // Standard says that DEL becomes U+007F.
-    [0xb0, 'MediaNextTrack'],
-    [0xb1, 'MediaPreviousTrack'],
-    [0xb2, 'MediaStop'],
-    [0xb3, 'MediaPlayPause'],
-    [0xad, 'VolumeMute'],
-    [0xae, 'VolumeDown'],
-    [0xaf, 'VolumeUp'],
-  ]);
-
-  /**
-   * @param {number} keyCode
-   * @return {string}
-   */
-  function keyCodeToKeyIdentifier(keyCode) {
-    let result = staticKeyIdentifiers.get(keyCode);
-    if (result !== undefined)
-      return result;
-    result = 'U+';
-    const hexString = keyCode.toString(16).toUpperCase();
-    for (let i = hexString.length; i < 4; ++i)
-      result += '0';
-    result += hexString;
-    return result;
-  }
-
-  function installBackwardsCompatibility() {
-    if (window.location.href.indexOf('/remote/') === -1)
-      return;
-
-    // Support for legacy (<M65) frontends.
-    /** @type {(!function(number, number):Element|undefined)} */
-    ShadowRoot.prototype.__originalShadowRootElementFromPoint;
-
-    if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) {
-      ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint;
-      /**
-       *  @param {number} x
-       *  @param {number} y
-       *  @return {Element}
-       */
-      ShadowRoot.prototype.elementFromPoint = function(x, y) {
-        const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments);
-        if (this.host && originalResult === this.host)
-          return null;
-        return originalResult;
-      };
-    }
-
-    // Support for legacy (<M53) frontends.
-    if (!window.KeyboardEvent.prototype.hasOwnProperty('keyIdentifier')) {
-      Object.defineProperty(window.KeyboardEvent.prototype, 'keyIdentifier', {
-        /**
-         * @return {string}
-         * @this {KeyboardEvent}
-         */
-        get: function() {
-          return keyCodeToKeyIdentifier(this.keyCode);
-        }
-      });
-    }
-
-    // Support for legacy (<M50) frontends.
-    installObjectObserve();
-
-    /**
-     * @param {string} property
-     * @return {!CSSValue|null}
-     * @this {CSSStyleDeclaration}
-     */
-    function getValue(property) {
-      // Note that |property| comes from another context, so we can't use === here.
-      // eslint-disable-next-line eqeqeq
-      if (property == 'padding-left') {
-        return /** @type {!CSSValue} */ ({
-          /**
-           * @return {number}
-           * @this {!{__paddingLeft: number}}
-           */
-          getFloatValue: function() {
-            return this.__paddingLeft;
-          },
-          __paddingLeft: parseFloat(this.paddingLeft)
-        });
-      }
-      throw new Error('getPropertyCSSValue is undefined');
-    }
-
-    // Support for legacy (<M41) frontends.
-    window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue;
-
-    function CSSPrimitiveValue() {
-    }
-    CSSPrimitiveValue.CSS_PX = 5;
-    window.CSSPrimitiveValue = CSSPrimitiveValue;
-
-    // Support for legacy (<M44) frontends.
-    const styleElement = window.document.createElement('style');
-    styleElement.type = 'text/css';
-    styleElement.textContent = 'html /deep/ * { min-width: 0; min-height: 0; }';
-
-    // Support for quirky border-image behavior (<M51), see:
-    // https://bugs.chromium.org/p/chromium/issues/detail?id=559258
-    styleElement.textContent +=
-        '\nhtml /deep/ .cm-breakpoint .CodeMirror-linenumber { border-style: solid !important; }';
-    styleElement.textContent +=
-        '\nhtml /deep/ .cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber { border-style: solid !important; }';
-    window.document.head.appendChild(styleElement);
-
-    // Support for legacy (<M49) frontends.
-    Event.prototype.deepPath = undefined;
-
-    // Support for legacy (<53) frontends.
-    window.FileError = /** @type {!function (new: FileError) : ?} */ ({
-      NOT_FOUND_ERR: DOMException.NOT_FOUND_ERR,
-      ABORT_ERR: DOMException.ABORT_ERR,
-      INVALID_MODIFICATION_ERR: DOMException.INVALID_MODIFICATION_ERR,
-      NOT_READABLE_ERR: 0  // No matching DOMException, so code will be 0.
-    });
-  }
-
-  function windowLoaded() {
-    window.removeEventListener('DOMContentLoaded', windowLoaded, false);
-    installBackwardsCompatibility();
-  }
-
-  if (window.document.head &&
-      (window.document.readyState === 'complete' || window.document.readyState === 'interactive'))
-    installBackwardsCompatibility();
-  else
-    window.addEventListener('DOMContentLoaded', windowLoaded, false);
-
-  /** @type {(!function(string, boolean=):boolean)|undefined} */
-  DOMTokenList.prototype.__originalDOMTokenListToggle;
-
-  if (!DOMTokenList.prototype.__originalDOMTokenListToggle) {
-    DOMTokenList.prototype.__originalDOMTokenListToggle = DOMTokenList.prototype.toggle;
-    /**
-     * @param {string} token
-     * @param {boolean=} force
-     * @return {boolean}
-     */
-    DOMTokenList.prototype.toggle = function(token, force) {
-      if (arguments.length === 1)
-        force = !this.contains(token);
-      return this.__originalDOMTokenListToggle(token, !!force);
-    };
-  }
-
-})(window);
diff --git a/front_end/diff/Diff.js b/front_end/diff/Diff.js
deleted file mode 100644
index 0111d08..0000000
--- a/front_end/diff/Diff.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Diff.Diff = {
-  /**
-   * @param {string} text1
-   * @param {string} text2
-   * @param {boolean=} cleanup
-   * @return {!Array.<!{0: number, 1: string}>}
-   */
-  charDiff: function(text1, text2, cleanup) {
-    const differ = new diff_match_patch();
-    const diff = differ.diff_main(text1, text2);
-    if (cleanup)
-      differ.diff_cleanupSemantic(diff);
-    return diff;
-  },
-
-  /**
-   * @param {!Array.<string>} lines1
-   * @param {!Array.<string>} lines2
-   * @return {!Diff.Diff.DiffArray}
-   */
-  lineDiff: function(lines1, lines2) {
-    /** @type {!Common.CharacterIdMap<string>} */
-    const idMap = new Common.CharacterIdMap();
-    const text1 = lines1.map(line => idMap.toChar(line)).join('');
-    const text2 = lines2.map(line => idMap.toChar(line)).join('');
-
-    const diff = Diff.Diff.charDiff(text1, text2);
-    const lineDiff = [];
-    for (let i = 0; i < diff.length; i++) {
-      const lines = [];
-      for (let j = 0; j < diff[i][1].length; j++)
-        lines.push(idMap.fromChar(diff[i][1][j]));
-
-      lineDiff.push({0: diff[i][0], 1: lines});
-    }
-    return lineDiff;
-  },
-
-  /**
-   * @param {!Diff.Diff.DiffArray} diff
-   * @return {!Array<!Array<number>>}
-   */
-  convertToEditDiff: function(diff) {
-    const normalized = [];
-    let added = 0;
-    let removed = 0;
-    for (let i = 0; i < diff.length; ++i) {
-      const token = diff[i];
-      if (token[0] === Diff.Diff.Operation.Equal) {
-        flush();
-        normalized.push([Diff.Diff.Operation.Equal, token[1].length]);
-      } else if (token[0] === Diff.Diff.Operation.Delete) {
-        removed += token[1].length;
-      } else {
-        added += token[1].length;
-      }
-    }
-    flush();
-    return normalized;
-
-    function flush() {
-      if (added && removed) {
-        const min = Math.min(added, removed);
-        normalized.push([Diff.Diff.Operation.Edit, min]);
-        added -= min;
-        removed -= min;
-      }
-      if (added || removed) {
-        const balance = added - removed;
-        const type = balance < 0 ? Diff.Diff.Operation.Delete : Diff.Diff.Operation.Insert;
-        normalized.push([type, Math.abs(balance)]);
-        added = 0;
-        removed = 0;
-      }
-    }
-  }
-
-};
-
-/** @enum {number} */
-Diff.Diff.Operation = {
-  Equal: 0,
-  Insert: 1,
-  Delete: -1,
-  Edit: 2
-};
-
-/** @typedef {!Array<!{0: !Diff.Diff.Operation, 1: !Array<string>}>} */
-Diff.Diff.DiffArray;
\ No newline at end of file
diff --git a/front_end/diff/diff_match_patch.js b/front_end/diff/diff_match_patch.js
deleted file mode 100644
index c41b513..0000000
--- a/front_end/diff/diff_match_patch.js
+++ /dev/null
@@ -1,49 +0,0 @@
-(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
-diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
-b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
-diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
-d):this.diff_bisect_(a,b,d)};
-diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
-diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
-u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
-diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
-diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
-diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
-diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
-diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
-diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
-var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
-diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
-d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
-diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
-return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
-h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
-diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
-diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
-g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
-a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
-diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&amp;").replace(d,"&lt;").replace(e,"&gt;").replace(f,"&para;<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
-diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
-diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
-diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
-f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
-diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
-k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
-diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
-diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
-c.length+d.length;a.length2+=c.length+d.length}};
-diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
-if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
-e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
-diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
-if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
-j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
-diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
-c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
-diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
-j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
-(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
-diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
-parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
-diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
-this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})()
diff --git a/front_end/diff/module.json b/front_end/diff/module.json
deleted file mode 100644
index ad06cf0..0000000
--- a/front_end/diff/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": [
-        "common"
-    ],
-    "scripts": [
-        "Diff.js",
-        "diff_match_patch.js"
-    ],
-    "skip_compilation": [
-        "diff_match_patch.js"
-    ]
-}
diff --git a/front_end/dom_extension/DOMExtension.js b/front_end/dom_extension/DOMExtension.js
deleted file mode 100644
index baa2879..0000000
--- a/front_end/dom_extension/DOMExtension.js
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Contains diff method based on Javascript Diff Algorithm By John Resig
- * http://ejohn.org/files/jsdiff.js (released under the MIT license).
- */
-/**
- * @param {number} offset
- * @param {string} stopCharacters
- * @param {!Node} stayWithinNode
- * @param {string=} direction
- * @return {!Range}
- */
-Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction) {
-  let startNode;
-  let startOffset = 0;
-  let endNode;
-  let endOffset = 0;
-
-  if (!stayWithinNode)
-    stayWithinNode = this;
-
-  if (!direction || direction === 'backward' || direction === 'both') {
-    let node = this;
-    while (node) {
-      if (node === stayWithinNode) {
-        if (!startNode)
-          startNode = stayWithinNode;
-        break;
-      }
-
-      if (node.nodeType === Node.TEXT_NODE) {
-        const start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
-        for (let i = start; i >= 0; --i) {
-          if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
-            startNode = node;
-            startOffset = i + 1;
-            break;
-          }
-        }
-      }
-
-      if (startNode)
-        break;
-
-      node = node.traversePreviousNode(stayWithinNode);
-    }
-
-    if (!startNode) {
-      startNode = stayWithinNode;
-      startOffset = 0;
-    }
-  } else {
-    startNode = this;
-    startOffset = offset;
-  }
-
-  if (!direction || direction === 'forward' || direction === 'both') {
-    let node = this;
-    while (node) {
-      if (node === stayWithinNode) {
-        if (!endNode)
-          endNode = stayWithinNode;
-        break;
-      }
-
-      if (node.nodeType === Node.TEXT_NODE) {
-        const start = (node === this ? offset : 0);
-        for (let i = start; i < node.nodeValue.length; ++i) {
-          if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
-            endNode = node;
-            endOffset = i;
-            break;
-          }
-        }
-      }
-
-      if (endNode)
-        break;
-
-      node = node.traverseNextNode(stayWithinNode);
-    }
-
-    if (!endNode) {
-      endNode = stayWithinNode;
-      endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length :
-                                                               stayWithinNode.childNodes.length;
-    }
-  } else {
-    endNode = this;
-    endOffset = offset;
-  }
-
-  const result = this.ownerDocument.createRange();
-  result.setStart(startNode, startOffset);
-  result.setEnd(endNode, endOffset);
-
-  return result;
-};
-
-/**
- * @param {!Node=} stayWithin
- * @return {?Node}
- */
-Node.prototype.traverseNextTextNode = function(stayWithin) {
-  let node = this.traverseNextNode(stayWithin);
-  if (!node)
-    return null;
-  const nonTextTags = {'STYLE': 1, 'SCRIPT': 1};
-  while (node && (node.nodeType !== Node.TEXT_NODE || nonTextTags[node.parentElement.nodeName]))
-    node = node.traverseNextNode(stayWithin);
-
-  return node;
-};
-
-/**
- * @param {number|undefined} x
- * @param {number|undefined} y
- * @param {!Element=} relativeTo
- */
-Element.prototype.positionAt = function(x, y, relativeTo) {
-  let shift = {x: 0, y: 0};
-  if (relativeTo)
-    shift = relativeTo.boxInWindow(this.ownerDocument.defaultView);
-
-  if (typeof x === 'number')
-    this.style.setProperty('left', (shift.x + x) + 'px');
-  else
-    this.style.removeProperty('left');
-
-  if (typeof y === 'number')
-    this.style.setProperty('top', (shift.y + y) + 'px');
-  else
-    this.style.removeProperty('top');
-
-  if (typeof x === 'number' || typeof y === 'number')
-    this.style.setProperty('position', 'absolute');
-  else
-    this.style.removeProperty('position');
-};
-
-/**
- * @return {boolean}
- */
-Element.prototype.isScrolledToBottom = function() {
-  // This code works only for 0-width border.
-  // The scrollTop, clientHeight and scrollHeight are computed in double values internally.
-  // However, they are exposed to javascript differently, each being either rounded (via
-  // round, ceil or floor functions) or left intouch.
-  // This adds up a total error up to 2.
-  return Math.abs(this.scrollTop + this.clientHeight - this.scrollHeight) <= 2;
-};
-
-/**
- * @param {!Array.<string>} nameArray
- * @return {?Node}
- */
-Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) {
-  for (let node = this; node && node !== this.ownerDocument; node = node.parentNodeOrShadowHost()) {
-    for (let i = 0; i < nameArray.length; ++i) {
-      if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
-        return node;
-    }
-  }
-  return null;
-};
-
-/**
- * @param {string} nodeName
- * @return {?Node}
- */
-Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) {
-  return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
-};
-
-/**
- * @param {string} className
- * @param {!Element=} stayWithin
- * @return {?Element}
- */
-Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin) {
-  return this.enclosingNodeOrSelfWithClassList([className], stayWithin);
-};
-
-/**
- * @param {!Array.<string>} classNames
- * @param {!Element=} stayWithin
- * @return {?Element}
- */
-Node.prototype.enclosingNodeOrSelfWithClassList = function(classNames, stayWithin) {
-  for (let node = this; node && node !== stayWithin && node !== this.ownerDocument;
-       node = node.parentNodeOrShadowHost()) {
-    if (node.nodeType === Node.ELEMENT_NODE) {
-      let containsAll = true;
-      for (let i = 0; i < classNames.length && containsAll; ++i) {
-        if (!node.classList.contains(classNames[i]))
-          containsAll = false;
-      }
-      if (containsAll)
-        return /** @type {!Element} */ (node);
-    }
-  }
-  return null;
-};
-
-/**
- * @return {?Element}
- */
-Node.prototype.parentElementOrShadowHost = function() {
-  if (this.nodeType === Node.DOCUMENT_FRAGMENT_NODE && this.host)
-    return /** @type {!Element} */ (this.host);
-  const node = this.parentNode;
-  if (!node)
-    return null;
-  if (node.nodeType === Node.ELEMENT_NODE)
-    return /** @type {!Element} */ (node);
-  if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
-    return /** @type {!Element} */ (node.host);
-  return null;
-};
-
-/**
- * @return {?Node}
- */
-Node.prototype.parentNodeOrShadowHost = function() {
-  if (this.parentNode)
-    return this.parentNode;
-  if (this.nodeType === Node.DOCUMENT_FRAGMENT_NODE && this.host)
-    return this.host;
-  return null;
-};
-
-/**
- * @return {?Selection}
- */
-Node.prototype.getComponentSelection = function() {
-  let parent = this.parentNode;
-  while (parent && parent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE)
-    parent = parent.parentNode;
-  return parent instanceof ShadowRoot ? parent.getSelection() : this.window().getSelection();
-};
-
-/**
- * @return {boolean}
- */
-Node.prototype.hasSelection = function() {
-  // TODO(luoe): use contains(node, {includeShadow: true}) when it is fixed for shadow dom.
-  const contents = this.querySelectorAll('content');
-  for (const content of contents) {
-    if (Array.prototype.some.call(content.getDistributedNodes(), node => node.hasSelection()))
-      return true;
-  }
-
-  const selection = this.getComponentSelection();
-  if (selection.type !== 'Range')
-    return false;
-  return selection.containsNode(this, true) || selection.anchorNode.isSelfOrDescendant(this) ||
-      selection.focusNode.isSelfOrDescendant(this);
-};
-
-/**
- * @return {!Window}
- */
-Node.prototype.window = function() {
-  return /** @type {!Window} */ (this.ownerDocument.defaultView);
-};
-
-Element.prototype.removeChildren = function() {
-  if (this.firstChild)
-    this.textContent = '';
-};
-
-/**
- * @param {string} tagName
- * @param {string=} customElementType
- * @return {!Element}
- * @suppressGlobalPropertiesCheck
- */
-function createElement(tagName, customElementType) {
-  return document.createElement(tagName, customElementType || '');
-}
-
-/**
- * @param {number|string} data
- * @return {!Text}
- * @suppressGlobalPropertiesCheck
- */
-function createTextNode(data) {
-  return document.createTextNode(data);
-}
-
-/**
- * @param {string} elementName
- * @param {string=} className
- * @param {string=} customElementType
- * @return {!Element}
- */
-Document.prototype.createElementWithClass = function(elementName, className, customElementType) {
-  const element = this.createElement(elementName, customElementType || '');
-  if (className)
-    element.className = className;
-  return element;
-};
-
-/**
- * @param {string} elementName
- * @param {string=} className
- * @param {string=} customElementType
- * @return {!Element}
- * @suppressGlobalPropertiesCheck
- */
-function createElementWithClass(elementName, className, customElementType) {
-  return document.createElementWithClass(elementName, className, customElementType);
-}
-
-/**
- * @param {string} childType
- * @param {string=} className
- * @return {!Element}
- */
-Document.prototype.createSVGElement = function(childType, className) {
-  const element = this.createElementNS('http://www.w3.org/2000/svg', childType);
-  if (className)
-    element.setAttribute('class', className);
-  return element;
-};
-
-/**
- * @param {string} childType
- * @param {string=} className
- * @return {!Element}
- * @suppressGlobalPropertiesCheck
- */
-function createSVGElement(childType, className) {
-  return document.createSVGElement(childType, className);
-}
-
-/**
- * @return {!DocumentFragment}
- * @suppressGlobalPropertiesCheck
- */
-function createDocumentFragment() {
-  return document.createDocumentFragment();
-}
-
-/**
- * @param {string} elementName
- * @param {string=} className
- * @param {string=} customElementType
- * @return {!Element}
- */
-Element.prototype.createChild = function(elementName, className, customElementType) {
-  const element = this.ownerDocument.createElementWithClass(elementName, className, customElementType);
-  this.appendChild(element);
-  return element;
-};
-
-DocumentFragment.prototype.createChild = Element.prototype.createChild;
-
-/**
- * @param {string} text
- * @return {!Text}
- */
-Element.prototype.createTextChild = function(text) {
-  const element = this.ownerDocument.createTextNode(text);
-  this.appendChild(element);
-  return element;
-};
-
-DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;
-
-/**
- * @param {...string} var_args
- */
-Element.prototype.createTextChildren = function(var_args) {
-  for (let i = 0, n = arguments.length; i < n; ++i)
-    this.createTextChild(arguments[i]);
-};
-
-DocumentFragment.prototype.createTextChildren = Element.prototype.createTextChildren;
-
-/**
- * @return {number}
- */
-Element.prototype.totalOffsetLeft = function() {
-  return this.totalOffset().left;
-};
-
-/**
- * @return {number}
- */
-Element.prototype.totalOffsetTop = function() {
-  return this.totalOffset().top;
-};
-
-/**
- * @return {!{left: number, top: number}}
- */
-Element.prototype.totalOffset = function() {
-  const rect = this.getBoundingClientRect();
-  return {left: rect.left, top: rect.top};
-};
-
-/**
- * @param {string} childType
- * @param {string=} className
- * @return {!Element}
- */
-Element.prototype.createSVGChild = function(childType, className) {
-  const child = this.ownerDocument.createSVGElement(childType, className);
-  this.appendChild(child);
-  return child;
-};
-
-/**
- * @unrestricted
- */
-var AnchorBox = class {  // eslint-disable-line
-  /**
-   * @param {number=} x
-   * @param {number=} y
-   * @param {number=} width
-   * @param {number=} height
-   */
-  constructor(x, y, width, height) {
-    this.x = x || 0;
-    this.y = y || 0;
-    this.width = width || 0;
-    this.height = height || 0;
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @return {boolean}
-   */
-  contains(x, y) {
-    return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height;
-  }
-};
-
-/**
- * @param {!AnchorBox} box
- * @return {!AnchorBox}
- */
-AnchorBox.prototype.relativeTo = function(box) {
-  return new AnchorBox(this.x - box.x, this.y - box.y, this.width, this.height);
-};
-
-/**
- * @param {!Element} element
- * @return {!AnchorBox}
- */
-AnchorBox.prototype.relativeToElement = function(element) {
-  return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView));
-};
-
-/**
- * @param {?AnchorBox} anchorBox
- * @return {boolean}
- */
-AnchorBox.prototype.equals = function(anchorBox) {
-  return !!anchorBox && this.x === anchorBox.x && this.y === anchorBox.y && this.width === anchorBox.width &&
-      this.height === anchorBox.height;
-};
-
-/**
- * @param {?Window=} targetWindow
- * @return {!AnchorBox}
- */
-Element.prototype.boxInWindow = function(targetWindow) {
-  targetWindow = targetWindow || this.ownerDocument.defaultView;
-
-  const anchorBox = new AnchorBox();
-  let curElement = this;
-  let curWindow = this.ownerDocument.defaultView;
-  while (curWindow && curElement) {
-    anchorBox.x += curElement.totalOffsetLeft();
-    anchorBox.y += curElement.totalOffsetTop();
-    if (curWindow === targetWindow)
-      break;
-    curElement = curWindow.frameElement;
-    curWindow = curWindow.parent;
-  }
-
-  anchorBox.width = Math.min(this.offsetWidth, targetWindow.innerWidth - anchorBox.x);
-  anchorBox.height = Math.min(this.offsetHeight, targetWindow.innerHeight - anchorBox.y);
-  return anchorBox;
-};
-
-/**
- * @param {boolean=} preventDefault
- */
-Event.prototype.consume = function(preventDefault) {
-  this.stopImmediatePropagation();
-  if (preventDefault)
-    this.preventDefault();
-  this.handled = true;
-};
-
-/**
- * @param {number=} start
- * @param {number=} end
- * @return {!Text}
- */
-Text.prototype.select = function(start, end) {
-  start = start || 0;
-  end = end || this.textContent.length;
-
-  if (start < 0)
-    start = end + start;
-
-  const selection = this.getComponentSelection();
-  selection.removeAllRanges();
-  const range = this.ownerDocument.createRange();
-  range.setStart(this, start);
-  range.setEnd(this, end);
-  selection.addRange(range);
-  return this;
-};
-
-/**
- * @return {?number}
- */
-Element.prototype.selectionLeftOffset = function() {
-  // Calculate selection offset relative to the current element.
-
-  const selection = this.getComponentSelection();
-  if (!selection.containsNode(this, true))
-    return null;
-
-  let leftOffset = selection.anchorOffset;
-  let node = selection.anchorNode;
-
-  while (node !== this) {
-    while (node.previousSibling) {
-      node = node.previousSibling;
-      leftOffset += node.textContent.length;
-    }
-    node = node.parentNodeOrShadowHost();
-  }
-
-  return leftOffset;
-};
-
-/**
- * @param {...!Node} var_args
- */
-Node.prototype.appendChildren = function(var_args) {
-  for (let i = 0, n = arguments.length; i < n; ++i)
-    this.appendChild(arguments[i]);
-};
-
-/**
- * @return {string}
- */
-Node.prototype.deepTextContent = function() {
-  return this.childTextNodes()
-      .map(function(node) {
-        return node.textContent;
-      })
-      .join('');
-};
-
-/**
- * @return {!Array.<!Node>}
- */
-Node.prototype.childTextNodes = function() {
-  let node = this.traverseNextTextNode(this);
-  const result = [];
-  const nonTextTags = {'STYLE': 1, 'SCRIPT': 1};
-  while (node) {
-    if (!nonTextTags[node.parentElement.nodeName])
-      result.push(node);
-    node = node.traverseNextTextNode(this);
-  }
-  return result;
-};
-
-/**
- * @param {?Node} node
- * @return {boolean}
- */
-Node.prototype.isAncestor = function(node) {
-  if (!node)
-    return false;
-
-  let currentNode = node.parentNodeOrShadowHost();
-  while (currentNode) {
-    if (this === currentNode)
-      return true;
-    currentNode = currentNode.parentNodeOrShadowHost();
-  }
-  return false;
-};
-
-/**
- * @param {?Node} descendant
- * @return {boolean}
- */
-Node.prototype.isDescendant = function(descendant) {
-  return !!descendant && descendant.isAncestor(this);
-};
-
-/**
- * @param {?Node} node
- * @return {boolean}
- */
-Node.prototype.isSelfOrAncestor = function(node) {
-  return !!node && (node === this || this.isAncestor(node));
-};
-
-/**
- * @param {?Node} node
- * @return {boolean}
- */
-Node.prototype.isSelfOrDescendant = function(node) {
-  return !!node && (node === this || this.isDescendant(node));
-};
-
-/**
- * @param {!Node=} stayWithin
- * @return {?Node}
- */
-Node.prototype.traverseNextNode = function(stayWithin) {
-  if (this.shadowRoot)
-    return this.shadowRoot;
-
-  const distributedNodes = this.getDistributedNodes ? this.getDistributedNodes() : [];
-
-  if (distributedNodes.length)
-    return distributedNodes[0];
-
-  if (this.firstChild)
-    return this.firstChild;
-
-  let node = this;
-  while (node) {
-    if (stayWithin && node === stayWithin)
-      return null;
-
-    const sibling = nextSibling(node);
-    if (sibling)
-      return sibling;
-
-    node = insertionPoint(node) || node.parentNodeOrShadowHost();
-  }
-
-  /**
-   * @param {!Node} node
-   * @return {?Node}
-   */
-  function nextSibling(node) {
-    const parent = insertionPoint(node);
-    if (!parent)
-      return node.nextSibling;
-    const distributedNodes = parent.getDistributedNodes ? parent.getDistributedNodes() : [];
-
-    const position = Array.prototype.indexOf.call(distributedNodes, node);
-    if (position + 1 < distributedNodes.length)
-      return distributedNodes[position + 1];
-    return null;
-  }
-
-  /**
-   * @param {!Node} node
-   * @return {?Node}
-   */
-  function insertionPoint(node) {
-    const insertionPoints = node.getDestinationInsertionPoints ? node.getDestinationInsertionPoints() : [];
-    return insertionPoints.length > 0 ? insertionPoints[insertionPoints.length - 1] : null;
-  }
-
-  return null;
-};
-
-/**
- * @param {!Node=} stayWithin
- * @return {?Node}
- */
-Node.prototype.traversePreviousNode = function(stayWithin) {
-  if (stayWithin && this === stayWithin)
-    return null;
-  let node = this.previousSibling;
-  while (node && node.lastChild)
-    node = node.lastChild;
-  if (node)
-    return node;
-  return this.parentNodeOrShadowHost();
-};
-
-/**
- * @param {*} text
- * @param {string=} placeholder
- * @return {boolean} true if was truncated
- */
-Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder) {
-  // Huge texts in the UI reduce rendering performance drastically.
-  // Moreover, Blink/WebKit uses <unsigned short> internally for storing text content
-  // length, so texts longer than 65535 are inherently displayed incorrectly.
-  const maxTextContentLength = 10000;
-
-  if (typeof text === 'string' && text.length > maxTextContentLength) {
-    this.textContent = typeof placeholder === 'string' ? placeholder : text.trimMiddle(maxTextContentLength);
-    return true;
-  }
-
-  this.textContent = text;
-  return false;
-};
-
-/**
- * @return {?Node}
- */
-Event.prototype.deepElementFromPoint = function() {
-  // Some synthetic events have zero coordinates which lead to a wrong element. Better return nothing in this case.
-  if (!this.which && !this.pageX && !this.pageY && !this.clientX && !this.clientY && !this.movementX && !this.movementY)
-    return null;
-  const root = this.target && this.target.getComponentRoot();
-  return root ? root.deepElementFromPoint(this.pageX, this.pageY) : null;
-};
-
-/**
- * @param {number} x
- * @param {number} y
- * @return {?Node}
- */
-Document.prototype.deepElementFromPoint = function(x, y) {
-  let container = this;
-  let node = null;
-  while (container) {
-    const innerNode = container.elementFromPoint(x, y);
-    if (!innerNode || node === innerNode)
-      break;
-    node = innerNode;
-    container = node.shadowRoot;
-  }
-  return node;
-};
-
-DocumentFragment.prototype.deepElementFromPoint = Document.prototype.deepElementFromPoint;
-
-/**
- * @return {?Element}
- */
-Document.prototype.deepActiveElement = function() {
-  let activeElement = this.activeElement;
-  while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
-    activeElement = activeElement.shadowRoot.activeElement;
-  return activeElement;
-};
-
-DocumentFragment.prototype.deepActiveElement = Document.prototype.deepActiveElement;
-
-/**
- * @return {boolean}
- */
-Element.prototype.hasFocus = function() {
-  const root = this.getComponentRoot();
-  return !!root && this.isSelfOrAncestor(root.activeElement);
-};
-
-/**
- * @return {?Document|?DocumentFragment}
- */
-Node.prototype.getComponentRoot = function() {
-  let node = this;
-  while (node && node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && node.nodeType !== Node.DOCUMENT_NODE)
-    node = node.parentNode;
-  return /** @type {?Document|?DocumentFragment} */ (node);
-};
-
-/**
- * @param {!Event} event
- * @return {boolean}
- */
-function isEnterKey(event) {
-  // Check if in IME.
-  return event.keyCode !== 229 && event.key === 'Enter';
-}
-
-/**
- * @param {!Event} event
- * @return {boolean}
- */
-function isEscKey(event) {
-  return event.keyCode === 27;
-}
diff --git a/front_end/dom_extension/module.json b/front_end/dom_extension/module.json
deleted file mode 100644
index 7f64ee3..0000000
--- a/front_end/dom_extension/module.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "dependencies": [
-        "platform"
-    ],
-    "scripts": [
-        "DOMExtension.js"
-    ]
-}
diff --git a/front_end/elements/ClassesPaneWidget.js b/front_end/elements/ClassesPaneWidget.js
deleted file mode 100644
index ff33a6d..0000000
--- a/front_end/elements/ClassesPaneWidget.js
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.ClassesPaneWidget = class extends UI.Widget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('elements/classesPaneWidget.css');
-    this.contentElement.className = 'styles-element-classes-pane';
-    const container = this.contentElement.createChild('div', 'title-container');
-    this._input = container.createChild('div', 'new-class-input monospace');
-    this.setDefaultFocusedElement(this._input);
-    this._classesContainer = this.contentElement.createChild('div', 'source-code');
-    this._classesContainer.classList.add('styles-element-classes-container');
-    this._prompt = new Elements.ClassesPaneWidget.ClassNamePrompt(this._nodeClasses.bind(this));
-    this._prompt.setAutocompletionTimeout(0);
-    this._prompt.renderAsBlock();
-
-    const proxyElement = this._prompt.attach(this._input);
-    this._prompt.setPlaceholder(Common.UIString('Add new class'));
-    this._prompt.addEventListener(UI.TextPrompt.Events.TextChanged, this._onTextChanged, this);
-    proxyElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
-
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.DOMMutated, this._onDOMMutated, this);
-    /** @type {!Set<!SDK.DOMNode>} */
-    this._mutatingNodes = new Set();
-    /** @type {!Map<!SDK.DOMNode, string>} */
-    this._pendingNodeClasses = new Map();
-    this._updateNodeThrottler = new Common.Throttler(0);
-    /** @type {?SDK.DOMNode} */
-    this._previousTarget = null;
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this._onSelectedNodeChanged, this);
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Array.<string>}
-   */
-  _splitTextIntoClasses(text) {
-    return text.split(/[.,\s]/)
-      .map(className => className.trim())
-      .filter(className => className.length);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (!isEnterKey(event) && !isEscKey(event))
-      return;
-
-    if (isEnterKey(event)) {
-      event.consume();
-      if (this._prompt.acceptAutoComplete())
-        return;
-    }
-
-    let text = event.target.textContent;
-    if (isEscKey(event)) {
-      if (!text.isWhitespace())
-        event.consume(true);
-      text = '';
-    }
-
-    this._prompt.clearAutocomplete();
-    event.target.textContent = '';
-
-    const node = UI.context.flavor(SDK.DOMNode);
-    if (!node)
-      return;
-
-    const classNames = this._splitTextIntoClasses(text);
-    for (const className of classNames)
-      this._toggleClass(node, className, true);
-    this._installNodeClasses(node);
-    this._update();
-  }
-
-  _onTextChanged() {
-    const node = UI.context.flavor(SDK.DOMNode);
-    if (!node)
-      return;
-    this._installNodeClasses(node);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onDOMMutated(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    if (this._mutatingNodes.has(node))
-      return;
-    delete node[Elements.ClassesPaneWidget._classesSymbol];
-    this._update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onSelectedNodeChanged(event) {
-    if (this._previousTarget && this._prompt.text()) {
-      this._input.textContent = '';
-      this._installNodeClasses(this._previousTarget);
-    }
-    this._previousTarget = /** @type {?SDK.DOMNode} */ (event.data);
-    this._update();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._update();
-  }
-
-  _update() {
-    if (!this.isShowing())
-      return;
-
-    let node = UI.context.flavor(SDK.DOMNode);
-    if (node)
-      node = node.enclosingElementOrSelf();
-
-    this._classesContainer.removeChildren();
-    this._input.disabled = !node;
-
-    if (!node)
-      return;
-
-    const classes = this._nodeClasses(node);
-    const keys = classes.keysArray();
-    keys.sort(String.caseInsensetiveComparator);
-    for (let i = 0; i < keys.length; ++i) {
-      const className = keys[i];
-      const label = UI.CheckboxLabel.create(className, classes.get(className));
-      label.classList.add('monospace');
-      label.checkboxElement.addEventListener('click', this._onClick.bind(this, className), false);
-      this._classesContainer.appendChild(label);
-    }
-  }
-
-  /**
-   * @param {string} className
-   * @param {!Event} event
-   */
-  _onClick(className, event) {
-    const node = UI.context.flavor(SDK.DOMNode);
-    if (!node)
-      return;
-    const enabled = event.target.checked;
-    this._toggleClass(node, className, enabled);
-    this._installNodeClasses(node);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Map<string, boolean>}
-   */
-  _nodeClasses(node) {
-    let result = node[Elements.ClassesPaneWidget._classesSymbol];
-    if (!result) {
-      const classAttribute = node.getAttribute('class') || '';
-      const classes = classAttribute.split(/\s/);
-      result = new Map();
-      for (let i = 0; i < classes.length; ++i) {
-        const className = classes[i].trim();
-        if (!className.length)
-          continue;
-        result.set(className, true);
-      }
-      node[Elements.ClassesPaneWidget._classesSymbol] = result;
-    }
-    return result;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {string} className
-   * @param {boolean} enabled
-   */
-  _toggleClass(node, className, enabled) {
-    const classes = this._nodeClasses(node);
-    classes.set(className, enabled);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   */
-  _installNodeClasses(node) {
-    const classes = this._nodeClasses(node);
-    const activeClasses = new Set();
-    for (const className of classes.keys()) {
-      if (classes.get(className))
-        activeClasses.add(className);
-    }
-
-    const additionalClasses = this._splitTextIntoClasses(this._prompt.textWithCurrentSuggestion());
-    for (const className of additionalClasses)
-      activeClasses.add(className);
-
-    const newClasses = activeClasses.valuesArray();
-    newClasses.sort();
-
-    this._pendingNodeClasses.set(node, newClasses.join(' '));
-    this._updateNodeThrottler.schedule(this._flushPendingClasses.bind(this));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _flushPendingClasses() {
-    const promises = [];
-    for (const node of this._pendingNodeClasses.keys()) {
-      this._mutatingNodes.add(node);
-      const promise = node.setAttributeValuePromise('class', this._pendingNodeClasses.get(node))
-                          .then(onClassValueUpdated.bind(this, node));
-      promises.push(promise);
-    }
-    this._pendingNodeClasses.clear();
-    return Promise.all(promises);
-
-    /**
-     * @param {!SDK.DOMNode} node
-     * @this {Elements.ClassesPaneWidget}
-     */
-    function onClassValueUpdated(node) {
-      this._mutatingNodes.delete(node);
-    }
-  }
-};
-
-Elements.ClassesPaneWidget._classesSymbol = Symbol('Elements.ClassesPaneWidget._classesSymbol');
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- * @unrestricted
- */
-Elements.ClassesPaneWidget.ButtonProvider = class {
-  constructor() {
-    this._button = new UI.ToolbarToggle(Common.UIString('Element Classes'), '');
-    this._button.setText('.cls');
-    this._button.element.classList.add('monospace');
-    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._clicked, this);
-    this._view = new Elements.ClassesPaneWidget();
-  }
-
-  _clicked() {
-    Elements.ElementsPanel.instance().showToolbarPane(!this._view.isShowing() ? this._view : null, this._button);
-  }
-
-  /**
-   * @override
-   * @return {!UI.ToolbarItem}
-   */
-  item() {
-    return this._button;
-  }
-};
-
-/**
- * @unrestricted
- */
-Elements.ClassesPaneWidget.ClassNamePrompt = class extends UI.TextPrompt {
-  /**
-   * @param {function(!SDK.DOMNode):!Map<string, boolean>} nodeClasses
-   */
-  constructor(nodeClasses) {
-    super();
-    this._nodeClasses = nodeClasses;
-    this.initialize(this._buildClassNameCompletions.bind(this), ' ');
-    this.disableDefaultSuggestionForEmptyInput();
-    this._selectedFrameId = '';
-    this._classNamesPromise = null;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} selectedNode
-   * @return {!Promise.<!Array.<string>>}
-   */
-  _getClassNames(selectedNode) {
-    const promises = [];
-    const completions = new Set();
-    this._selectedFrameId = selectedNode.frameId();
-
-    const cssModel = selectedNode.domModel().cssModel();
-    const allStyleSheets = cssModel.allStyleSheets();
-    for (const stylesheet of allStyleSheets) {
-      if (stylesheet.frameId !== this._selectedFrameId)
-        continue;
-      const cssPromise = cssModel.classNamesPromise(stylesheet.id).then(classes => completions.addAll(classes));
-      promises.push(cssPromise);
-    }
-
-    const domPromise = selectedNode.domModel()
-                           .classNamesPromise(selectedNode.ownerDocument.id)
-                           .then(classes => completions.addAll(classes));
-    promises.push(domPromise);
-    return Promise.all(promises).then(() => completions.valuesArray());
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} prefix
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  _buildClassNameCompletions(expression, prefix, force) {
-    if (!prefix || force)
-      this._classNamesPromise = null;
-
-    const selectedNode = UI.context.flavor(SDK.DOMNode);
-    if (!selectedNode || (!prefix && !force && !expression.trim()))
-      return Promise.resolve([]);
-
-    if (!this._classNamesPromise || this._selectedFrameId !== selectedNode.frameId())
-      this._classNamesPromise = this._getClassNames(selectedNode);
-
-    return this._classNamesPromise.then(completions => {
-      const classesMap = this._nodeClasses(/** @type {!SDK.DOMNode} */ (selectedNode));
-      completions = completions.filter(value => !classesMap.get(value));
-
-      if (prefix[0] === '.')
-        completions = completions.map(value => '.' + value);
-      return completions.filter(value => value.startsWith(prefix)).sort().map(completion => ({text: completion}));
-    });
-  }
-};
diff --git a/front_end/elements/ColorSwatchPopoverIcon.js b/front_end/elements/ColorSwatchPopoverIcon.js
deleted file mode 100644
index ad9e540..0000000
--- a/front_end/elements/ColorSwatchPopoverIcon.js
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.BezierPopoverIcon = class {
-  /**
-   * @param {!Elements.StylePropertyTreeElement} treeElement
-   * @param {!InlineEditor.SwatchPopoverHelper} swatchPopoverHelper
-   * @param {!InlineEditor.BezierSwatch} swatch
-   */
-  constructor(treeElement, swatchPopoverHelper, swatch) {
-    this._treeElement = treeElement;
-    this._swatchPopoverHelper = swatchPopoverHelper;
-    this._swatch = swatch;
-
-    this._swatch.iconElement().title = Common.UIString('Open cubic bezier editor.');
-    this._swatch.iconElement().addEventListener('click', this._iconClick.bind(this), false);
-    this._swatch.iconElement().addEventListener('mousedown', event => event.consume(), false);
-
-    this._boundBezierChanged = this._bezierChanged.bind(this);
-    this._boundOnScroll = this._onScroll.bind(this);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _iconClick(event) {
-    event.consume(true);
-    if (this._swatchPopoverHelper.isShowing()) {
-      this._swatchPopoverHelper.hide(true);
-      return;
-    }
-
-    this._bezierEditor = new InlineEditor.BezierEditor();
-    let cubicBezier = UI.Geometry.CubicBezier.parse(this._swatch.bezierText());
-    if (!cubicBezier) {
-      cubicBezier =
-          /** @type {!UI.Geometry.CubicBezier} */ (UI.Geometry.CubicBezier.parse('linear'));
-    }
-    this._bezierEditor.setBezier(cubicBezier);
-    this._bezierEditor.addEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
-    this._swatchPopoverHelper.show(this._bezierEditor, this._swatch.iconElement(), this._onPopoverHidden.bind(this));
-    this._scrollerElement = this._swatch.enclosingNodeOrSelfWithClass('style-panes-wrapper');
-    if (this._scrollerElement)
-      this._scrollerElement.addEventListener('scroll', this._boundOnScroll, false);
-
-    this._originalPropertyText = this._treeElement.property.propertyText;
-    this._treeElement.parentPane().setEditingStyle(true);
-    const uiLocation = Bindings.cssWorkspaceBinding.propertyUILocation(this._treeElement.property, false /* forName */);
-    if (uiLocation)
-      Common.Revealer.reveal(uiLocation, true /* omitFocus */);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _bezierChanged(event) {
-    this._swatch.setBezierText(/** @type {string} */ (event.data));
-    this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onScroll(event) {
-    this._swatchPopoverHelper.reposition();
-  }
-
-  /**
-   * @param {boolean} commitEdit
-   */
-  _onPopoverHidden(commitEdit) {
-    if (this._scrollerElement)
-      this._scrollerElement.removeEventListener('scroll', this._boundOnScroll, false);
-
-    this._bezierEditor.removeEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
-    delete this._bezierEditor;
-
-    const propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
-    this._treeElement.applyStyleText(propertyText, true);
-    this._treeElement.parentPane().setEditingStyle(false);
-    delete this._originalPropertyText;
-  }
-};
-
-/**
- * @unrestricted
- */
-Elements.ColorSwatchPopoverIcon = class {
-  /**
-   * @param {!Elements.StylePropertyTreeElement} treeElement
-   * @param {!InlineEditor.SwatchPopoverHelper} swatchPopoverHelper
-   * @param {!InlineEditor.ColorSwatch} swatch
-   */
-  constructor(treeElement, swatchPopoverHelper, swatch) {
-    this._treeElement = treeElement;
-    this._treeElement[Elements.ColorSwatchPopoverIcon._treeElementSymbol] = this;
-    this._swatchPopoverHelper = swatchPopoverHelper;
-    this._swatch = swatch;
-
-    const shiftClickMessage = Common.UIString('Shift + Click to change color format.');
-    this._swatch.iconElement().title = Common.UIString('Open color picker. %s', shiftClickMessage);
-    this._swatch.iconElement().addEventListener('click', this._iconClick.bind(this));
-    this._swatch.iconElement().addEventListener('mousedown', event => event.consume(), false);
-    this._contrastInfo = null;
-
-    this._boundSpectrumChanged = this._spectrumChanged.bind(this);
-    this._boundOnScroll = this._onScroll.bind(this);
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement} treeElement
-   * @return {?Elements.ColorSwatchPopoverIcon}
-   */
-  static forTreeElement(treeElement) {
-    return treeElement[Elements.ColorSwatchPopoverIcon._treeElementSymbol] || null;
-  }
-
-  /**
-   * @param {?SDK.CSSModel.ContrastInfo} contrastInfo
-   */
-  setContrastInfo(contrastInfo) {
-    this._contrastInfo = contrastInfo;
-    if (this._spectrum)
-      this._spectrum.setContrastInfo(contrastInfo);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _iconClick(event) {
-    event.consume(true);
-    this.showPopover();
-  }
-
-  showPopover() {
-    if (this._swatchPopoverHelper.isShowing()) {
-      this._swatchPopoverHelper.hide(true);
-      return;
-    }
-
-    const color = this._swatch.color();
-    let format = this._swatch.format();
-    if (format === Common.Color.Format.Original)
-      format = color.format();
-    this._spectrum = new ColorPicker.Spectrum();
-    this._spectrum.setColor(color, format);
-    if (this._contrastInfo)
-      this._spectrum.setContrastInfo(this._contrastInfo);
-
-    this._spectrum.addEventListener(ColorPicker.Spectrum.Events.SizeChanged, this._spectrumResized, this);
-    this._spectrum.addEventListener(ColorPicker.Spectrum.Events.ColorChanged, this._boundSpectrumChanged);
-    this._swatchPopoverHelper.show(this._spectrum, this._swatch.iconElement(), this._onPopoverHidden.bind(this));
-    this._scrollerElement = this._swatch.enclosingNodeOrSelfWithClass('style-panes-wrapper');
-    if (this._scrollerElement)
-      this._scrollerElement.addEventListener('scroll', this._boundOnScroll, false);
-
-    this._originalPropertyText = this._treeElement.property.propertyText;
-    this._treeElement.parentPane().setEditingStyle(true);
-    const uiLocation = Bindings.cssWorkspaceBinding.propertyUILocation(this._treeElement.property, false /* forName */);
-    if (uiLocation)
-      Common.Revealer.reveal(uiLocation, true /* omitFocus */);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _spectrumResized(event) {
-    this._swatchPopoverHelper.reposition();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _spectrumChanged(event) {
-    const color = Common.Color.parse(/** @type {string} */ (event.data));
-    if (!color)
-      return;
-    this._swatch.setColor(color);
-    this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onScroll(event) {
-    this._swatchPopoverHelper.reposition();
-  }
-
-  /**
-   * @param {boolean} commitEdit
-   */
-  _onPopoverHidden(commitEdit) {
-    if (this._scrollerElement)
-      this._scrollerElement.removeEventListener('scroll', this._boundOnScroll, false);
-
-    this._spectrum.removeEventListener(ColorPicker.Spectrum.Events.ColorChanged, this._boundSpectrumChanged);
-    delete this._spectrum;
-
-    const propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
-    this._treeElement.applyStyleText(propertyText, true);
-    this._treeElement.parentPane().setEditingStyle(false);
-    delete this._originalPropertyText;
-  }
-};
-
-Elements.ColorSwatchPopoverIcon._treeElementSymbol = Symbol('Elements.ColorSwatchPopoverIcon._treeElementSymbol');
-
-
-/**
- * @unrestricted
- */
-Elements.ShadowSwatchPopoverHelper = class {
-  /**
-   * @param {!Elements.StylePropertyTreeElement} treeElement
-   * @param {!InlineEditor.SwatchPopoverHelper} swatchPopoverHelper
-   * @param {!InlineEditor.CSSShadowSwatch} shadowSwatch
-   */
-  constructor(treeElement, swatchPopoverHelper, shadowSwatch) {
-    this._treeElement = treeElement;
-    this._treeElement[Elements.ShadowSwatchPopoverHelper._treeElementSymbol] = this;
-    this._swatchPopoverHelper = swatchPopoverHelper;
-    this._shadowSwatch = shadowSwatch;
-    this._iconElement = shadowSwatch.iconElement();
-
-    this._iconElement.title = Common.UIString('Open shadow editor.');
-    this._iconElement.addEventListener('click', this._iconClick.bind(this), false);
-    this._iconElement.addEventListener('mousedown', event => event.consume(), false);
-
-    this._boundShadowChanged = this._shadowChanged.bind(this);
-    this._boundOnScroll = this._onScroll.bind(this);
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement} treeElement
-   * @return {?Elements.ShadowSwatchPopoverHelper}
-   */
-  static forTreeElement(treeElement) {
-    return treeElement[Elements.ShadowSwatchPopoverHelper._treeElementSymbol] || null;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _iconClick(event) {
-    event.consume(true);
-    this.showPopover();
-  }
-
-  showPopover() {
-    if (this._swatchPopoverHelper.isShowing()) {
-      this._swatchPopoverHelper.hide(true);
-      return;
-    }
-
-    this._cssShadowEditor = new InlineEditor.CSSShadowEditor();
-    this._cssShadowEditor.setModel(this._shadowSwatch.model());
-    this._cssShadowEditor.addEventListener(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._boundShadowChanged);
-    this._swatchPopoverHelper.show(this._cssShadowEditor, this._iconElement, this._onPopoverHidden.bind(this));
-    this._scrollerElement = this._iconElement.enclosingNodeOrSelfWithClass('style-panes-wrapper');
-    if (this._scrollerElement)
-      this._scrollerElement.addEventListener('scroll', this._boundOnScroll, false);
-
-    this._originalPropertyText = this._treeElement.property.propertyText;
-    this._treeElement.parentPane().setEditingStyle(true);
-    const uiLocation = Bindings.cssWorkspaceBinding.propertyUILocation(this._treeElement.property, false /* forName */);
-    if (uiLocation)
-      Common.Revealer.reveal(uiLocation, true /* omitFocus */);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _shadowChanged(event) {
-    this._shadowSwatch.setCSSShadow(/** @type {!InlineEditor.CSSShadowModel} */ (event.data));
-    this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onScroll(event) {
-    this._swatchPopoverHelper.reposition();
-  }
-
-  /**
-   * @param {boolean} commitEdit
-   */
-  _onPopoverHidden(commitEdit) {
-    if (this._scrollerElement)
-      this._scrollerElement.removeEventListener('scroll', this._boundOnScroll, false);
-
-    this._cssShadowEditor.removeEventListener(
-        InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._boundShadowChanged);
-    delete this._cssShadowEditor;
-
-    const propertyText = commitEdit ? this._treeElement.renderedPropertyText() : this._originalPropertyText;
-    this._treeElement.applyStyleText(propertyText, true);
-    this._treeElement.parentPane().setEditingStyle(false);
-    delete this._originalPropertyText;
-  }
-};
-
-Elements.ShadowSwatchPopoverHelper._treeElementSymbol = Symbol('Elements.ShadowSwatchPopoverHelper._treeElementSymbol');
diff --git a/front_end/elements/ComputedStyleModel.js b/front_end/elements/ComputedStyleModel.js
deleted file mode 100644
index 6236dea..0000000
--- a/front_end/elements/ComputedStyleModel.js
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.ComputedStyleModel = class extends Common.Object {
-  constructor() {
-    super();
-    this._node = UI.context.flavor(SDK.DOMNode);
-    this._cssModel = null;
-    this._eventListeners = [];
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this._onNodeChanged, this);
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @return {?SDK.CSSModel}
-   */
-  cssModel() {
-    return this._cssModel && this._cssModel.isEnabled() ? this._cssModel : null;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onNodeChanged(event) {
-    this._node = /** @type {?SDK.DOMNode} */ (event.data);
-    this._updateModel(this._node ? this._node.domModel().cssModel() : null);
-    this._onComputedStyleChanged(null);
-  }
-
-  /**
-   * @param {?SDK.CSSModel} cssModel
-   */
-  _updateModel(cssModel) {
-    if (this._cssModel === cssModel)
-      return;
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._cssModel = cssModel;
-    const domModel = cssModel ? cssModel.domModel() : null;
-    const resourceTreeModel = cssModel ? cssModel.target().model(SDK.ResourceTreeModel) : null;
-    if (cssModel && domModel && resourceTreeModel) {
-      this._eventListeners = [
-        cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._onComputedStyleChanged, this),
-        cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this._onComputedStyleChanged, this),
-        cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._onComputedStyleChanged, this),
-        cssModel.addEventListener(SDK.CSSModel.Events.FontsUpdated, this._onComputedStyleChanged, this),
-        cssModel.addEventListener(SDK.CSSModel.Events.MediaQueryResultChanged, this._onComputedStyleChanged, this),
-        cssModel.addEventListener(SDK.CSSModel.Events.PseudoStateForced, this._onComputedStyleChanged, this),
-        cssModel.addEventListener(SDK.CSSModel.Events.ModelWasEnabled, this._onComputedStyleChanged, this),
-        domModel.addEventListener(SDK.DOMModel.Events.DOMMutated, this._onDOMModelChanged, this),
-        resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameResized, this._onFrameResized, this),
-      ];
-    }
-  }
-
-  /**
-   * @param {?Common.Event} event
-   */
-  _onComputedStyleChanged(event) {
-    delete this._computedStylePromise;
-    this.dispatchEventToListeners(Elements.ComputedStyleModel.Events.ComputedStyleChanged, event ? event.data : null);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onDOMModelChanged(event) {
-    // Any attribute removal or modification can affect the styles of "related" nodes.
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    if (!this._node || this._node !== node && node.parentNode !== this._node.parentNode && !node.isAncestor(this._node))
-      return;
-    this._onComputedStyleChanged(null);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFrameResized(event) {
-    /**
-     * @this {Elements.ComputedStyleModel}
-     */
-    function refreshContents() {
-      this._onComputedStyleChanged(null);
-      delete this._frameResizedTimer;
-    }
-
-    if (this._frameResizedTimer)
-      clearTimeout(this._frameResizedTimer);
-
-    this._frameResizedTimer = setTimeout(refreshContents.bind(this), 100);
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  _elementNode() {
-    return this.node() ? this.node().enclosingElementOrSelf() : null;
-  }
-
-  /**
-   * @return {!Promise.<?Elements.ComputedStyleModel.ComputedStyle>}
-   */
-  fetchComputedStyle() {
-    const elementNode = this._elementNode();
-    const cssModel = this.cssModel();
-    if (!elementNode || !cssModel)
-      return Promise.resolve(/** @type {?Elements.ComputedStyleModel.ComputedStyle} */ (null));
-
-    if (!this._computedStylePromise) {
-      this._computedStylePromise =
-          cssModel.computedStylePromise(elementNode.id).then(verifyOutdated.bind(this, elementNode));
-    }
-
-    return this._computedStylePromise;
-
-    /**
-     * @param {!SDK.DOMNode} elementNode
-     * @param {?Map.<string, string>} style
-     * @return {?Elements.ComputedStyleModel.ComputedStyle}
-     * @this {Elements.ComputedStyleModel}
-     */
-    function verifyOutdated(elementNode, style) {
-      return elementNode === this._elementNode() && style ?
-          new Elements.ComputedStyleModel.ComputedStyle(elementNode, style) :
-          /** @type {?Elements.ComputedStyleModel.ComputedStyle} */ (null);
-    }
-  }
-};
-
-/** @enum {symbol} */
-Elements.ComputedStyleModel.Events = {
-  ComputedStyleChanged: Symbol('ComputedStyleChanged')
-};
-
-/**
- * @unrestricted
- */
-Elements.ComputedStyleModel.ComputedStyle = class {
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {!Map.<string, string>} computedStyle
-   */
-  constructor(node, computedStyle) {
-    this.node = node;
-    this.computedStyle = computedStyle;
-  }
-};
diff --git a/front_end/elements/ComputedStyleWidget.js b/front_end/elements/ComputedStyleWidget.js
deleted file mode 100644
index aceeed5..0000000
--- a/front_end/elements/ComputedStyleWidget.js
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Elements.ComputedStyleWidget = class extends UI.ThrottledWidget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('elements/computedStyleSidebarPane.css');
-    this._alwaysShowComputedProperties = {'display': true, 'height': true, 'width': true};
-
-    this._computedStyleModel = new Elements.ComputedStyleModel();
-    this._computedStyleModel.addEventListener(
-        Elements.ComputedStyleModel.Events.ComputedStyleChanged, this.update, this);
-
-    this._showInheritedComputedStylePropertiesSetting =
-        Common.settings.createSetting('showInheritedComputedStyleProperties', false);
-    this._showInheritedComputedStylePropertiesSetting.addChangeListener(
-        this._showInheritedComputedStyleChanged.bind(this));
-
-    const hbox = this.contentElement.createChild('div', 'hbox styles-sidebar-pane-toolbar');
-    const filterContainerElement = hbox.createChild('div', 'styles-sidebar-pane-filter-box');
-    const filterInput = Elements.StylesSidebarPane.createPropertyFilterElement(
-        Common.UIString('Filter'), hbox, filterCallback.bind(this), 'styles-filter-engaged');
-    UI.ARIAUtils.setAccessibleName(filterInput, Common.UIString('Filter Computed Styles'));
-    filterContainerElement.appendChild(filterInput);
-    this.setDefaultFocusedElement(filterInput);
-
-    const toolbar = new UI.Toolbar('styles-pane-toolbar', hbox);
-    toolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
-        this._showInheritedComputedStylePropertiesSetting, undefined, Common.UIString('Show all')));
-
-    this._propertiesOutline = new UI.TreeOutlineInShadow();
-    this._propertiesOutline.hideOverflow();
-    this._propertiesOutline.registerRequiredCSS('elements/computedStyleWidgetTree.css');
-    this._propertiesOutline.element.classList.add('monospace', 'computed-properties');
-    this.contentElement.appendChild(this._propertiesOutline.element);
-
-    this._linkifier = new Components.Linkifier(Elements.ComputedStyleWidget._maxLinkLength);
-
-    /**
-     * @param {?RegExp} regex
-     * @this {Elements.ComputedStyleWidget}
-     */
-    function filterCallback(regex) {
-      this._filterRegex = regex;
-      this._updateFilter(regex);
-    }
-
-    const fontsWidget = new Elements.PlatformFontsWidget(this._computedStyleModel);
-    fontsWidget.show(this.contentElement);
-  }
-
-  _showInheritedComputedStyleChanged() {
-    this.update();
-  }
-
-  /**
-   * @override
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    const promises = [this._computedStyleModel.fetchComputedStyle(), this._fetchMatchedCascade()];
-    return Promise.all(promises).spread(this._innerRebuildUpdate.bind(this));
-  }
-
-  /**
-   * @return {!Promise.<?SDK.CSSMatchedStyles>}
-   */
-  _fetchMatchedCascade() {
-    const node = this._computedStyleModel.node();
-    if (!node || !this._computedStyleModel.cssModel())
-      return Promise.resolve(/** @type {?SDK.CSSMatchedStyles} */ (null));
-
-    return this._computedStyleModel.cssModel().cachedMatchedCascadeForNode(node).then(validateStyles.bind(this));
-
-    /**
-     * @param {?SDK.CSSMatchedStyles} matchedStyles
-     * @return {?SDK.CSSMatchedStyles}
-     * @this {Elements.ComputedStyleWidget}
-     */
-    function validateStyles(matchedStyles) {
-      return matchedStyles && matchedStyles.node() === this._computedStyleModel.node() ? matchedStyles : null;
-    }
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Node}
-   */
-  _processColor(text) {
-    const color = Common.Color.parse(text);
-    if (!color)
-      return createTextNode(text);
-    const swatch = InlineEditor.ColorSwatch.create();
-    swatch.setColor(color);
-    swatch.setFormat(Common.Color.detectColorFormat(color));
-    return swatch;
-  }
-
-  /**
-   * @param {?Elements.ComputedStyleModel.ComputedStyle} nodeStyle
-   * @param {?SDK.CSSMatchedStyles} matchedStyles
-   */
-  _innerRebuildUpdate(nodeStyle, matchedStyles) {
-    /** @type {!Set<string>} */
-    const expandedProperties = new Set();
-    for (const treeElement of this._propertiesOutline.rootElement().children()) {
-      if (!treeElement.expanded)
-        continue;
-      const propertyName = treeElement[Elements.ComputedStyleWidget._propertySymbol].name;
-      expandedProperties.add(propertyName);
-    }
-    this._propertiesOutline.removeChildren();
-    this._linkifier.reset();
-    const cssModel = this._computedStyleModel.cssModel();
-    if (!nodeStyle || !matchedStyles || !cssModel)
-      return;
-
-    const uniqueProperties = nodeStyle.computedStyle.keysArray();
-    uniqueProperties.sort(propertySorter);
-
-    const propertyTraces = this._computePropertyTraces(matchedStyles);
-    const inhertiedProperties = this._computeInheritedProperties(matchedStyles);
-    const showInherited = this._showInheritedComputedStylePropertiesSetting.get();
-    for (let i = 0; i < uniqueProperties.length; ++i) {
-      const propertyName = uniqueProperties[i];
-      const propertyValue = nodeStyle.computedStyle.get(propertyName);
-      const canonicalName = SDK.cssMetadata().canonicalPropertyName(propertyName);
-      const inherited = !inhertiedProperties.has(canonicalName);
-      if (!showInherited && inherited && !(propertyName in this._alwaysShowComputedProperties))
-        continue;
-      if (!showInherited && propertyName.startsWith('--'))
-        continue;
-      if (propertyName !== canonicalName && propertyValue === nodeStyle.computedStyle.get(canonicalName))
-        continue;
-
-      const propertyElement = createElement('div');
-      propertyElement.classList.add('computed-style-property');
-      propertyElement.classList.toggle('computed-style-property-inherited', inherited);
-      const renderer = new Elements.StylesSidebarPropertyRenderer(
-          null, nodeStyle.node, propertyName, /** @type {string} */ (propertyValue));
-      renderer.setColorHandler(this._processColor.bind(this));
-      const propertyNameElement = renderer.renderName();
-      propertyNameElement.classList.add('property-name');
-      propertyElement.appendChild(propertyNameElement);
-
-      const colon = createElementWithClass('span', 'delimeter');
-      colon.textContent = ':';
-      propertyNameElement.appendChild(colon);
-
-      const propertyValueElement = propertyElement.createChild('span', 'property-value');
-
-      const propertyValueText = renderer.renderValue();
-      propertyValueText.classList.add('property-value-text');
-      propertyValueElement.appendChild(propertyValueText);
-
-      const semicolon = createElementWithClass('span', 'delimeter');
-      semicolon.textContent = ';';
-      propertyValueElement.appendChild(semicolon);
-
-      const treeElement = new UI.TreeElement();
-      treeElement.selectable = false;
-      treeElement.title = propertyElement;
-      treeElement[Elements.ComputedStyleWidget._propertySymbol] = {name: propertyName, value: propertyValue};
-      const isOdd = this._propertiesOutline.rootElement().children().length % 2 === 0;
-      treeElement.listItemElement.classList.toggle('odd-row', isOdd);
-      this._propertiesOutline.appendChild(treeElement);
-
-      const trace = propertyTraces.get(propertyName);
-      if (trace) {
-        const activeProperty = this._renderPropertyTrace(cssModel, matchedStyles, nodeStyle.node, treeElement, trace);
-        treeElement.listItemElement.addEventListener('mousedown', e => e.consume(), false);
-        treeElement.listItemElement.addEventListener('dblclick', e => e.consume(), false);
-        treeElement.listItemElement.addEventListener('click', handleClick.bind(null, treeElement), false);
-        const gotoSourceElement = UI.Icon.create('mediumicon-arrow-in-circle', 'goto-source-icon');
-        gotoSourceElement.addEventListener('click', this._navigateToSource.bind(this, activeProperty));
-        propertyValueElement.appendChild(gotoSourceElement);
-        if (expandedProperties.has(propertyName))
-          treeElement.expand();
-      }
-    }
-
-    this._updateFilter(this._filterRegex);
-
-    /**
-     * @param {string} a
-     * @param {string} b
-     * @return {number}
-     */
-    function propertySorter(a, b) {
-      if (a.startsWith('--') ^ b.startsWith('--'))
-        return a.startsWith('--') ? 1 : -1;
-      if (a.startsWith('-webkit') ^ b.startsWith('-webkit'))
-        return a.startsWith('-webkit') ? 1 : -1;
-      const canonical1 = SDK.cssMetadata().canonicalPropertyName(a);
-      const canonical2 = SDK.cssMetadata().canonicalPropertyName(b);
-      return canonical1.compareTo(canonical2);
-    }
-
-    /**
-     * @param {!UI.TreeElement} treeElement
-     * @param {!Event} event
-     */
-    function handleClick(treeElement, event) {
-      if (!treeElement.expanded)
-        treeElement.expand();
-      else
-        treeElement.collapse();
-      event.consume();
-    }
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} cssProperty
-   * @param {!Event} event
-   */
-  _navigateToSource(cssProperty, event) {
-    Common.Revealer.reveal(cssProperty);
-    event.consume(true);
-  }
-
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {!SDK.DOMNode} node
-   * @param {!UI.TreeElement} rootTreeElement
-   * @param {!Array<!SDK.CSSProperty>} tracedProperties
-   * @return {!SDK.CSSProperty}
-   */
-  _renderPropertyTrace(cssModel, matchedStyles, node, rootTreeElement, tracedProperties) {
-    let activeProperty = null;
-    for (const property of tracedProperties) {
-      const trace = createElement('div');
-      trace.classList.add('property-trace');
-      if (matchedStyles.propertyState(property) === SDK.CSSMatchedStyles.PropertyState.Overloaded)
-        trace.classList.add('property-trace-inactive');
-      else
-        activeProperty = property;
-
-      const renderer =
-          new Elements.StylesSidebarPropertyRenderer(null, node, property.name, /** @type {string} */ (property.value));
-      renderer.setColorHandler(this._processColor.bind(this));
-      const valueElement = renderer.renderValue();
-      valueElement.classList.add('property-trace-value');
-      valueElement.addEventListener('click', this._navigateToSource.bind(this, property), false);
-      const gotoSourceElement = UI.Icon.create('mediumicon-arrow-in-circle', 'goto-source-icon');
-      gotoSourceElement.addEventListener('click', this._navigateToSource.bind(this, property));
-      valueElement.insertBefore(gotoSourceElement, valueElement.firstChild);
-
-      trace.appendChild(valueElement);
-
-      const rule = property.ownerStyle.parentRule;
-      const selectorElement = trace.createChild('span', 'property-trace-selector');
-      selectorElement.textContent = rule ? rule.selectorText() : 'element.style';
-      selectorElement.title = selectorElement.textContent;
-
-      if (rule) {
-        const linkSpan = trace.createChild('span', 'trace-link');
-        linkSpan.appendChild(
-            Elements.StylePropertiesSection.createRuleOriginNode(matchedStyles, this._linkifier, rule));
-      }
-
-      const traceTreeElement = new UI.TreeElement();
-      traceTreeElement.title = trace;
-      traceTreeElement.selectable = false;
-      rootTreeElement.appendChild(traceTreeElement);
-    }
-    return /** @type {!SDK.CSSProperty} */ (activeProperty);
-  }
-
-  /**
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @return {!Map<string, !Array<!SDK.CSSProperty>>}
-   */
-  _computePropertyTraces(matchedStyles) {
-    const result = new Map();
-    for (const style of matchedStyles.nodeStyles()) {
-      const allProperties = style.allProperties();
-      for (const property of allProperties) {
-        if (!property.activeInStyle() || !matchedStyles.propertyState(property))
-          continue;
-        if (!result.has(property.name))
-          result.set(property.name, []);
-        result.get(property.name).push(property);
-      }
-    }
-    return result;
-  }
-
-  /**
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @return {!Set<string>}
-   */
-  _computeInheritedProperties(matchedStyles) {
-    const result = new Set();
-    for (const style of matchedStyles.nodeStyles()) {
-      for (const property of style.allProperties()) {
-        if (!matchedStyles.propertyState(property))
-          continue;
-        result.add(SDK.cssMetadata().canonicalPropertyName(property.name));
-      }
-    }
-    return result;
-  }
-
-  /**
-   * @param {?RegExp} regex
-   */
-  _updateFilter(regex) {
-    const children = this._propertiesOutline.rootElement().children();
-    for (const child of children) {
-      const property = child[Elements.ComputedStyleWidget._propertySymbol];
-      const matched = !regex || regex.test(property.name) || regex.test(property.value);
-      child.hidden = !matched;
-    }
-  }
-};
-
-Elements.ComputedStyleWidget._maxLinkLength = 30;
-
-Elements.ComputedStyleWidget._propertySymbol = Symbol('property');
diff --git a/front_end/elements/DOMLinkifier.js b/front_end/elements/DOMLinkifier.js
deleted file mode 100644
index b6d3cc5..0000000
--- a/front_end/elements/DOMLinkifier.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Elements.DOMLinkifier = {};
-
-/**
- * @param {!SDK.DOMNode} node
- * @param {!Element} parentElement
- * @param {string=} tooltipContent
- */
-Elements.DOMLinkifier.decorateNodeLabel = function(node, parentElement, tooltipContent) {
-  const originalNode = node;
-  const isPseudo = node.nodeType() === Node.ELEMENT_NODE && node.pseudoType();
-  if (isPseudo && node.parentNode)
-    node = node.parentNode;
-
-  let title = node.nodeNameInCorrectCase();
-
-  const nameElement = parentElement.createChild('span', 'node-label-name');
-  nameElement.textContent = title;
-
-  const idAttribute = node.getAttribute('id');
-  if (idAttribute) {
-    const idElement = parentElement.createChild('span', 'node-label-id');
-    const part = '#' + idAttribute;
-    title += part;
-    idElement.createTextChild(part);
-
-    // Mark the name as extra, since the ID is more important.
-    nameElement.classList.add('extra');
-  }
-
-  const classAttribute = node.getAttribute('class');
-  if (classAttribute) {
-    const classes = classAttribute.split(/\s+/);
-    const foundClasses = {};
-
-    if (classes.length) {
-      const classesElement = parentElement.createChild('span', 'extra node-label-class');
-      for (let i = 0; i < classes.length; ++i) {
-        const className = classes[i];
-        if (className && !(className in foundClasses)) {
-          const part = '.' + className;
-          title += part;
-          classesElement.createTextChild(part);
-          foundClasses[className] = true;
-        }
-      }
-    }
-  }
-
-  if (isPseudo) {
-    const pseudoElement = parentElement.createChild('span', 'extra node-label-pseudo');
-    const pseudoText = '::' + originalNode.pseudoType();
-    pseudoElement.createTextChild(pseudoText);
-    title += pseudoText;
-  }
-  parentElement.title = tooltipContent || title;
-};
-
-/**
- * @param {?SDK.DOMNode} node
- * @param {string=} tooltipContent
- * @return {!Node}
- */
-Elements.DOMLinkifier.linkifyNodeReference = function(node, tooltipContent) {
-  if (!node)
-    return createTextNode(Common.UIString('<node>'));
-
-  const root = createElementWithClass('span', 'monospace');
-  const shadowRoot = UI.createShadowRootWithCoreStyles(root, 'elements/domLinkifier.css');
-  const link = shadowRoot.createChild('div', 'node-link');
-
-  Elements.DOMLinkifier.decorateNodeLabel(node, link, tooltipContent);
-
-  link.addEventListener('click', () => Common.Revealer.reveal(node, false) && false, false);
-  link.addEventListener('mouseover', node.highlight.bind(node, undefined, undefined), false);
-  link.addEventListener('mouseleave', () => SDK.OverlayModel.hideDOMNodeHighlight(), false);
-
-  return root;
-};
-
-/**
- * @param {!SDK.DeferredDOMNode} deferredNode
- * @return {!Node}
- */
-Elements.DOMLinkifier.linkifyDeferredNodeReference = function(deferredNode) {
-  const root = createElement('div');
-  const shadowRoot = UI.createShadowRootWithCoreStyles(root, 'elements/domLinkifier.css');
-  const link = shadowRoot.createChild('div', 'node-link');
-  link.createChild('content');
-  link.addEventListener('click', deferredNode.resolve.bind(deferredNode, onDeferredNodeResolved), false);
-  link.addEventListener('mousedown', e => e.consume(), false);
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  function onDeferredNodeResolved(node) {
-    Common.Revealer.reveal(node);
-  }
-
-  return root;
-};
-
-/**
- * @implements {Common.Linkifier}
- */
-Elements.DOMLinkifier.Linkifier = class {
-  /**
-   * @override
-   * @param {!Object} object
-   * @param {!Common.Linkifier.Options=} options
-   * @return {!Node}
-   */
-  linkify(object, options) {
-    if (object instanceof SDK.DOMNode)
-      return Elements.DOMLinkifier.linkifyNodeReference(object, options ? options.title : undefined);
-    if (object instanceof SDK.DeferredDOMNode)
-      return Elements.DOMLinkifier.linkifyDeferredNodeReference(object);
-    throw new Error('Can\'t linkify non-node');
-  }
-};
diff --git a/front_end/elements/DOMPath.js b/front_end/elements/DOMPath.js
deleted file mode 100644
index d37015d..0000000
--- a/front_end/elements/DOMPath.js
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Elements.DOMPath = {};
-
-/**
- * @param {!SDK.DOMNode} node
- * @param {boolean=} justSelector
- * @return {string}
- */
-Elements.DOMPath.fullQualifiedSelector = function(node, justSelector) {
-  if (node.nodeType() !== Node.ELEMENT_NODE)
-    return node.localName() || node.nodeName().toLowerCase();
-  return Elements.DOMPath.cssPath(node, justSelector);
-};
-
-/**
- * @param {!SDK.DOMNode} node
- * @param {boolean=} optimized
- * @return {string}
- */
-Elements.DOMPath.cssPath = function(node, optimized) {
-  if (node.nodeType() !== Node.ELEMENT_NODE)
-    return '';
-
-  const steps = [];
-  let contextNode = node;
-  while (contextNode) {
-    const step = Elements.DOMPath._cssPathStep(contextNode, !!optimized, contextNode === node);
-    if (!step)
-      break;  // Error - bail out early.
-    steps.push(step);
-    if (step.optimized)
-      break;
-    contextNode = contextNode.parentNode;
-  }
-
-  steps.reverse();
-  return steps.join(' > ');
-};
-
-/**
- * @param {!SDK.DOMNode} node
- * @param {boolean} optimized
- * @param {boolean} isTargetNode
- * @return {?Elements.DOMPath.Step}
- */
-Elements.DOMPath._cssPathStep = function(node, optimized, isTargetNode) {
-  if (node.nodeType() !== Node.ELEMENT_NODE)
-    return null;
-
-  const id = node.getAttribute('id');
-  if (optimized) {
-    if (id)
-      return new Elements.DOMPath.Step(idSelector(id), true);
-    const nodeNameLower = node.nodeName().toLowerCase();
-    if (nodeNameLower === 'body' || nodeNameLower === 'head' || nodeNameLower === 'html')
-      return new Elements.DOMPath.Step(node.nodeNameInCorrectCase(), true);
-  }
-  const nodeName = node.nodeNameInCorrectCase();
-
-  if (id)
-    return new Elements.DOMPath.Step(nodeName + idSelector(id), true);
-  const parent = node.parentNode;
-  if (!parent || parent.nodeType() === Node.DOCUMENT_NODE)
-    return new Elements.DOMPath.Step(nodeName, true);
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Array.<string>}
-   */
-  function prefixedElementClassNames(node) {
-    const classAttribute = node.getAttribute('class');
-    if (!classAttribute)
-      return [];
-
-    return classAttribute.split(/\s+/g).filter(Boolean).map(function(name) {
-      // The prefix is required to store "__proto__" in a object-based map.
-      return '$' + name;
-    });
-  }
-
-  /**
-   * @param {string} id
-   * @return {string}
-   */
-  function idSelector(id) {
-    return '#' + escapeIdentifierIfNeeded(id);
-  }
-
-  /**
-   * @param {string} ident
-   * @return {string}
-   */
-  function escapeIdentifierIfNeeded(ident) {
-    if (isCSSIdentifier(ident))
-      return ident;
-    const shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);
-    const lastIndex = ident.length - 1;
-    return ident.replace(/./g, function(c, i) {
-      return ((shouldEscapeFirst && i === 0) || !isCSSIdentChar(c)) ? escapeAsciiChar(c, i === lastIndex) : c;
-    });
-  }
-
-  /**
-   * @param {string} c
-   * @param {boolean} isLast
-   * @return {string}
-   */
-  function escapeAsciiChar(c, isLast) {
-    return '\\' + toHexByte(c) + (isLast ? '' : ' ');
-  }
-
-  /**
-   * @param {string} c
-   */
-  function toHexByte(c) {
-    let hexByte = c.charCodeAt(0).toString(16);
-    if (hexByte.length === 1)
-      hexByte = '0' + hexByte;
-    return hexByte;
-  }
-
-  /**
-   * @param {string} c
-   * @return {boolean}
-   */
-  function isCSSIdentChar(c) {
-    if (/[a-zA-Z0-9_-]/.test(c))
-      return true;
-    return c.charCodeAt(0) >= 0xA0;
-  }
-
-  /**
-   * @param {string} value
-   * @return {boolean}
-   */
-  function isCSSIdentifier(value) {
-    // Double hyphen prefixes are not allowed by specification, but many sites use it.
-    return /^-{0,2}[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);
-  }
-
-  const prefixedOwnClassNamesArray = prefixedElementClassNames(node);
-  let needsClassNames = false;
-  let needsNthChild = false;
-  let ownIndex = -1;
-  let elementIndex = -1;
-  const siblings = parent.children();
-  for (let i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {
-    const sibling = siblings[i];
-    if (sibling.nodeType() !== Node.ELEMENT_NODE)
-      continue;
-    elementIndex += 1;
-    if (sibling === node) {
-      ownIndex = elementIndex;
-      continue;
-    }
-    if (needsNthChild)
-      continue;
-    if (sibling.nodeNameInCorrectCase() !== nodeName)
-      continue;
-
-    needsClassNames = true;
-    const ownClassNames = new Set(prefixedOwnClassNamesArray);
-    if (!ownClassNames.size) {
-      needsNthChild = true;
-      continue;
-    }
-    const siblingClassNamesArray = prefixedElementClassNames(sibling);
-    for (let j = 0; j < siblingClassNamesArray.length; ++j) {
-      const siblingClass = siblingClassNamesArray[j];
-      if (!ownClassNames.has(siblingClass))
-        continue;
-      ownClassNames.delete(siblingClass);
-      if (!ownClassNames.size) {
-        needsNthChild = true;
-        break;
-      }
-    }
-  }
-
-  let result = nodeName;
-  if (isTargetNode && nodeName.toLowerCase() === 'input' && node.getAttribute('type') && !node.getAttribute('id') &&
-      !node.getAttribute('class'))
-    result += '[type="' + node.getAttribute('type') + '"]';
-  if (needsNthChild) {
-    result += ':nth-child(' + (ownIndex + 1) + ')';
-  } else if (needsClassNames) {
-    for (const prefixedName of prefixedOwnClassNamesArray)
-      result += '.' + escapeIdentifierIfNeeded(prefixedName.substr(1));
-  }
-
-  return new Elements.DOMPath.Step(result, false);
-};
-
-/**
- * @param {!SDK.DOMNode} node
- * @param {boolean=} optimized
- * @return {string}
- */
-Elements.DOMPath.xPath = function(node, optimized) {
-  if (node.nodeType() === Node.DOCUMENT_NODE)
-    return '/';
-
-  const steps = [];
-  let contextNode = node;
-  while (contextNode) {
-    const step = Elements.DOMPath._xPathValue(contextNode, optimized);
-    if (!step)
-      break;  // Error - bail out early.
-    steps.push(step);
-    if (step.optimized)
-      break;
-    contextNode = contextNode.parentNode;
-  }
-
-  steps.reverse();
-  return (steps.length && steps[0].optimized ? '' : '/') + steps.join('/');
-};
-
-/**
- * @param {!SDK.DOMNode} node
- * @param {boolean=} optimized
- * @return {?Elements.DOMPath.Step}
- */
-Elements.DOMPath._xPathValue = function(node, optimized) {
-  let ownValue;
-  const ownIndex = Elements.DOMPath._xPathIndex(node);
-  if (ownIndex === -1)
-    return null;  // Error.
-
-  switch (node.nodeType()) {
-    case Node.ELEMENT_NODE:
-      if (optimized && node.getAttribute('id'))
-        return new Elements.DOMPath.Step('//*[@id="' + node.getAttribute('id') + '"]', true);
-      ownValue = node.localName();
-      break;
-    case Node.ATTRIBUTE_NODE:
-      ownValue = '@' + node.nodeName();
-      break;
-    case Node.TEXT_NODE:
-    case Node.CDATA_SECTION_NODE:
-      ownValue = 'text()';
-      break;
-    case Node.PROCESSING_INSTRUCTION_NODE:
-      ownValue = 'processing-instruction()';
-      break;
-    case Node.COMMENT_NODE:
-      ownValue = 'comment()';
-      break;
-    case Node.DOCUMENT_NODE:
-      ownValue = '';
-      break;
-    default:
-      ownValue = '';
-      break;
-  }
-
-  if (ownIndex > 0)
-    ownValue += '[' + ownIndex + ']';
-
-  return new Elements.DOMPath.Step(ownValue, node.nodeType() === Node.DOCUMENT_NODE);
-};
-
-/**
- * @param {!SDK.DOMNode} node
- * @return {number}
- */
-Elements.DOMPath._xPathIndex = function(node) {
-  // Returns -1 in case of error, 0 if no siblings matching the same expression, <XPath index among the same expression-matching sibling nodes> otherwise.
-  function areNodesSimilar(left, right) {
-    if (left === right)
-      return true;
-
-    if (left.nodeType() === Node.ELEMENT_NODE && right.nodeType() === Node.ELEMENT_NODE)
-      return left.localName() === right.localName();
-
-    if (left.nodeType() === right.nodeType())
-      return true;
-
-    // XPath treats CDATA as text nodes.
-    const leftType = left.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left.nodeType();
-    const rightType = right.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : right.nodeType();
-    return leftType === rightType;
-  }
-
-  const siblings = node.parentNode ? node.parentNode.children() : null;
-  if (!siblings)
-    return 0;  // Root node - no siblings.
-  let hasSameNamedElements;
-  for (let i = 0; i < siblings.length; ++i) {
-    if (areNodesSimilar(node, siblings[i]) && siblings[i] !== node) {
-      hasSameNamedElements = true;
-      break;
-    }
-  }
-  if (!hasSameNamedElements)
-    return 0;
-  let ownIndex = 1;  // XPath indices start with 1.
-  for (let i = 0; i < siblings.length; ++i) {
-    if (areNodesSimilar(node, siblings[i])) {
-      if (siblings[i] === node)
-        return ownIndex;
-      ++ownIndex;
-    }
-  }
-  return -1;  // An error occurred: |node| not found in parent's children.
-};
-
-/**
- * @unrestricted
- */
-Elements.DOMPath.Step = class {
-  /**
-   * @param {string} value
-   * @param {boolean} optimized
-   */
-  constructor(value, optimized) {
-    this.value = value;
-    this.optimized = optimized || false;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return this.value;
-  }
-};
diff --git a/front_end/elements/ElementStatePaneWidget.js b/front_end/elements/ElementStatePaneWidget.js
deleted file mode 100644
index a2fd799..0000000
--- a/front_end/elements/ElementStatePaneWidget.js
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.ElementStatePaneWidget = class extends UI.Widget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('elements/elementStatePaneWidget.css');
-    this.contentElement.className = 'styles-element-state-pane';
-    this.contentElement.createChild('div').createTextChild(Common.UIString('Force element state'));
-    const table = createElementWithClass('table', 'source-code');
-
-    const inputs = [];
-    this._inputs = inputs;
-
-    /**
-     * @param {!Event} event
-     */
-    function clickListener(event) {
-      const node = UI.context.flavor(SDK.DOMNode);
-      if (!node)
-        return;
-      node.domModel().cssModel().forcePseudoState(node, event.target.state, event.target.checked);
-    }
-
-    /**
-     * @param {string} state
-     * @return {!Element}
-     */
-    function createCheckbox(state) {
-      const td = createElement('td');
-      const label = UI.CheckboxLabel.create(':' + state);
-      const input = label.checkboxElement;
-      input.state = state;
-      input.addEventListener('click', clickListener, false);
-      inputs.push(input);
-      td.appendChild(label);
-      return td;
-    }
-
-    let tr = table.createChild('tr');
-    tr.appendChild(createCheckbox.call(null, 'active'));
-    tr.appendChild(createCheckbox.call(null, 'hover'));
-
-    tr = table.createChild('tr');
-    tr.appendChild(createCheckbox.call(null, 'focus'));
-    tr.appendChild(createCheckbox.call(null, 'visited'));
-
-    tr = table.createChild('tr');
-    tr.appendChild(createCheckbox.call(null, 'focus-within'));
-    try {
-      tr.querySelector(':focus-visible');  // Will throw if not supported
-      tr.appendChild(createCheckbox.call(null, 'focus-visible'));
-    } catch (e) {
-    }
-
-    this.contentElement.appendChild(table);
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this._update, this);
-  }
-
-  /**
-   * @param {?SDK.CSSModel} cssModel
-   */
-  _updateModel(cssModel) {
-    if (this._cssModel === cssModel)
-      return;
-    if (this._cssModel)
-      this._cssModel.removeEventListener(SDK.CSSModel.Events.PseudoStateForced, this._update, this);
-    this._cssModel = cssModel;
-    if (this._cssModel)
-      this._cssModel.addEventListener(SDK.CSSModel.Events.PseudoStateForced, this._update, this);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._update();
-  }
-
-  _update() {
-    if (!this.isShowing())
-      return;
-
-    let node = UI.context.flavor(SDK.DOMNode);
-    if (node)
-      node = node.enclosingElementOrSelf();
-
-    this._updateModel(node ? node.domModel().cssModel() : null);
-    if (node) {
-      const nodePseudoState = node.domModel().cssModel().pseudoState(node);
-      for (const input of this._inputs) {
-        input.disabled = !!node.pseudoType();
-        input.checked = nodePseudoState.indexOf(input.state) >= 0;
-      }
-    } else {
-      for (const input of this._inputs) {
-        input.disabled = true;
-        input.checked = false;
-      }
-    }
-  }
-};
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- * @unrestricted
- */
-Elements.ElementStatePaneWidget.ButtonProvider = class {
-  constructor() {
-    this._button = new UI.ToolbarToggle(Common.UIString('Toggle Element State'), '');
-    this._button.setText(Common.UIString(':hov'));
-    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._clicked, this);
-    this._button.element.classList.add('monospace');
-    this._view = new Elements.ElementStatePaneWidget();
-  }
-
-  _clicked() {
-    Elements.ElementsPanel.instance().showToolbarPane(!this._view.isShowing() ? this._view : null, this._button);
-  }
-
-  /**
-   * @override
-   * @return {!UI.ToolbarItem}
-   */
-  item() {
-    return this._button;
-  }
-};
diff --git a/front_end/elements/ElementsBreadcrumbs.js b/front_end/elements/ElementsBreadcrumbs.js
deleted file mode 100644
index deb7e9a..0000000
--- a/front_end/elements/ElementsBreadcrumbs.js
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.ElementsBreadcrumbs = class extends UI.HBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('elements/breadcrumbs.css');
-
-    this.crumbsElement = this.contentElement.createChild('div', 'crumbs');
-    this.crumbsElement.addEventListener('mousemove', this._mouseMovedInCrumbs.bind(this), false);
-    this.crumbsElement.addEventListener('mouseleave', this._mouseMovedOutOfCrumbs.bind(this), false);
-    this._nodeSymbol = Symbol('node');
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.update();
-  }
-
-  /**
-   * @param {!Array.<!SDK.DOMNode>} nodes
-   */
-  updateNodes(nodes) {
-    if (!nodes.length)
-      return;
-
-    const crumbs = this.crumbsElement;
-    for (let crumb = crumbs.firstChild; crumb; crumb = crumb.nextSibling) {
-      if (nodes.indexOf(crumb[this._nodeSymbol]) !== -1) {
-        this.update(true);
-        return;
-      }
-    }
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  setSelectedNode(node) {
-    this._currentDOMNode = node;
-    this.crumbsElement.window().requestAnimationFrame(() => this.update());
-  }
-
-  _mouseMovedInCrumbs(event) {
-    const nodeUnderMouse = event.target;
-    const crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass('crumb');
-    const node = /** @type {?SDK.DOMNode} */ (crumbElement ? crumbElement[this._nodeSymbol] : null);
-    if (node)
-      node.highlight();
-  }
-
-  _mouseMovedOutOfCrumbs(event) {
-    if (this._currentDOMNode)
-      SDK.OverlayModel.hideDOMNodeHighlight();
-  }
-
-
-  /**
-   * @param {!Event} event
-   * @this {Elements.ElementsBreadcrumbs}
-   */
-  _onClickCrumb(event) {
-    event.preventDefault();
-    let crumb = /** @type {!Element} */ (event.currentTarget);
-    if (!crumb.classList.contains('collapsed')) {
-      this.dispatchEventToListeners(Elements.ElementsBreadcrumbs.Events.NodeSelected, crumb[this._nodeSymbol]);
-      return;
-    }
-
-    // Clicking a collapsed crumb will expose the hidden crumbs.
-    if (crumb === this.crumbsElement.firstChild) {
-      // If the clicked crumb is the first child, pick the farthest crumb
-      // that is still hidden. This allows the user to expose every crumb.
-      let currentCrumb = crumb;
-      while (currentCrumb) {
-        const hidden = currentCrumb.classList.contains('hidden');
-        const collapsed = currentCrumb.classList.contains('collapsed');
-        if (!hidden && !collapsed)
-          break;
-        crumb = currentCrumb;
-        currentCrumb = currentCrumb.nextSiblingElement;
-      }
-    }
-
-    this.updateSizes(crumb);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} domNode
-   * @return {?string}
-   */
-  _determineElementTitle(domNode) {
-    switch (domNode.nodeType()) {
-      case Node.ELEMENT_NODE:
-        if (domNode.pseudoType())
-          return '::' + domNode.pseudoType();
-        return null;
-      case Node.TEXT_NODE:
-        return Common.UIString('(text)');
-      case Node.COMMENT_NODE:
-        return '<!-->';
-      case Node.DOCUMENT_TYPE_NODE:
-        return '<!doctype>';
-      case Node.DOCUMENT_FRAGMENT_NODE:
-        return domNode.shadowRootType() ? '#shadow-root' : domNode.nodeNameInCorrectCase();
-      default:
-        return domNode.nodeNameInCorrectCase();
-    }
-  }
-
-  /**
-   * @param {boolean=} force
-   */
-  update(force) {
-    if (!this.isShowing())
-      return;
-
-    const currentDOMNode = this._currentDOMNode;
-    const crumbs = this.crumbsElement;
-
-    let handled = false;
-    let crumb = crumbs.firstChild;
-    while (crumb) {
-      if (crumb[this._nodeSymbol] === currentDOMNode) {
-        crumb.classList.add('selected');
-        handled = true;
-      } else {
-        crumb.classList.remove('selected');
-      }
-
-      crumb = crumb.nextSibling;
-    }
-
-    if (handled && !force) {
-      // We don't need to rebuild the crumbs, but we need to adjust sizes
-      // to reflect the new focused or root node.
-      this.updateSizes();
-      return;
-    }
-
-    crumbs.removeChildren();
-
-    for (let current = currentDOMNode; current; current = current.parentNode) {
-      if (current.nodeType() === Node.DOCUMENT_NODE)
-        continue;
-
-      crumb = createElementWithClass('span', 'crumb');
-      crumb[this._nodeSymbol] = current;
-      crumb.addEventListener('mousedown', this._onClickCrumb.bind(this), false);
-
-      const crumbTitle = this._determineElementTitle(current);
-      if (crumbTitle) {
-        const nameElement = createElement('span');
-        nameElement.textContent = crumbTitle;
-        crumb.appendChild(nameElement);
-        crumb.title = crumbTitle;
-      } else {
-        Elements.DOMLinkifier.decorateNodeLabel(current, crumb);
-      }
-
-      if (current === currentDOMNode)
-        crumb.classList.add('selected');
-      crumbs.insertBefore(crumb, crumbs.firstChild);
-    }
-
-    this.updateSizes();
-  }
-
-  /**
-   * @param {!Element=} focusedCrumb
-   * @return {{selectedIndex: number, focusedIndex: number, selectedCrumb: ?Element}}
-   */
-  _resetCrumbStylesAndFindSelections(focusedCrumb) {
-    const crumbs = this.crumbsElement;
-    let selectedIndex = 0;
-    let focusedIndex = 0;
-    let selectedCrumb = null;
-
-    // Reset crumb styles.
-    for (let i = 0; i < crumbs.childNodes.length; ++i) {
-      const crumb = crumbs.children[i];
-      // Find the selected crumb and index.
-      if (!selectedCrumb && crumb.classList.contains('selected')) {
-        selectedCrumb = crumb;
-        selectedIndex = i;
-      }
-
-      // Find the focused crumb index.
-      if (crumb === focusedCrumb)
-        focusedIndex = i;
-
-      crumb.classList.remove('compact', 'collapsed', 'hidden');
-    }
-
-    return {selectedIndex: selectedIndex, focusedIndex: focusedIndex, selectedCrumb: selectedCrumb};
-  }
-
-  /**
-   * @return {{normal: !Array.<number>, compact: !Array.<number>, collapsed: number, available: number}}
-   */
-  _measureElementSizes() {
-    const crumbs = this.crumbsElement;
-
-    // Layout 1: Measure total and normal crumb sizes at the same time as a
-    // dummy element for the collapsed size.
-    const collapsedElement = createElementWithClass('span', 'crumb collapsed');
-    crumbs.insertBefore(collapsedElement, crumbs.firstChild);
-
-    const available = crumbs.offsetWidth;
-    const collapsed = collapsedElement.offsetWidth;
-
-    const normalSizes = [];
-    for (let i = 1; i < crumbs.childNodes.length; ++i) {
-      const crumb = crumbs.childNodes[i];
-      normalSizes[i - 1] = crumb.offsetWidth;
-    }
-
-    crumbs.removeChild(collapsedElement);
-
-    // Layout 2: Measure collapsed crumb sizes
-    const compactSizes = [];
-    for (let i = 0; i < crumbs.childNodes.length; ++i) {
-      const crumb = crumbs.childNodes[i];
-      crumb.classList.add('compact');
-    }
-    for (let i = 0; i < crumbs.childNodes.length; ++i) {
-      const crumb = crumbs.childNodes[i];
-      compactSizes[i] = crumb.offsetWidth;
-    }
-
-    // Clean up.
-    for (let i = 0; i < crumbs.childNodes.length; ++i) {
-      const crumb = crumbs.childNodes[i];
-      crumb.classList.remove('compact', 'collapsed');
-    }
-
-    return {normal: normalSizes, compact: compactSizes, collapsed: collapsed, available: available};
-  }
-
-  /**
-   * @param {!Element=} focusedCrumb
-   */
-  updateSizes(focusedCrumb) {
-    if (!this.isShowing())
-      return;
-
-    const crumbs = this.crumbsElement;
-    if (!crumbs.firstChild)
-      return;
-
-    const selections = this._resetCrumbStylesAndFindSelections(focusedCrumb);
-    const sizes = this._measureElementSizes();
-    const selectedIndex = selections.selectedIndex;
-    const focusedIndex = selections.focusedIndex;
-    const selectedCrumb = selections.selectedCrumb;
-
-    function crumbsAreSmallerThanContainer() {
-      let totalSize = 0;
-      for (let i = 0; i < crumbs.childNodes.length; ++i) {
-        const crumb = crumbs.childNodes[i];
-        if (crumb.classList.contains('hidden'))
-          continue;
-        if (crumb.classList.contains('collapsed')) {
-          totalSize += sizes.collapsed;
-          continue;
-        }
-        totalSize += crumb.classList.contains('compact') ? sizes.compact[i] : sizes.normal[i];
-      }
-      const rightPadding = 10;
-      return totalSize + rightPadding < sizes.available;
-    }
-
-    if (crumbsAreSmallerThanContainer())
-      return;  // No need to compact the crumbs, they all fit at full size.
-
-    const BothSides = 0;
-    const AncestorSide = -1;
-    const ChildSide = 1;
-
-    /**
-     * @param {function(!Element)} shrinkingFunction
-     * @param {number} direction
-     */
-    function makeCrumbsSmaller(shrinkingFunction, direction) {
-      const significantCrumb = focusedCrumb || selectedCrumb;
-      const significantIndex = significantCrumb === selectedCrumb ? selectedIndex : focusedIndex;
-
-      function shrinkCrumbAtIndex(index) {
-        const shrinkCrumb = crumbs.children[index];
-        if (shrinkCrumb && shrinkCrumb !== significantCrumb)
-          shrinkingFunction(shrinkCrumb);
-        if (crumbsAreSmallerThanContainer())
-          return true;  // No need to compact the crumbs more.
-        return false;
-      }
-
-      // Shrink crumbs one at a time by applying the shrinkingFunction until the crumbs
-      // fit in the container or we run out of crumbs to shrink.
-      if (direction) {
-        // Crumbs are shrunk on only one side (based on direction) of the signifcant crumb.
-        let index = (direction > 0 ? 0 : crumbs.childNodes.length - 1);
-        while (index !== significantIndex) {
-          if (shrinkCrumbAtIndex(index))
-            return true;
-          index += (direction > 0 ? 1 : -1);
-        }
-      } else {
-        // Crumbs are shrunk in order of descending distance from the signifcant crumb,
-        // with a tie going to child crumbs.
-        let startIndex = 0;
-        let endIndex = crumbs.childNodes.length - 1;
-        while (startIndex !== significantIndex || endIndex !== significantIndex) {
-          const startDistance = significantIndex - startIndex;
-          const endDistance = endIndex - significantIndex;
-          let index;
-          if (startDistance >= endDistance)
-            index = startIndex++;
-          else
-            index = endIndex--;
-          if (shrinkCrumbAtIndex(index))
-            return true;
-        }
-      }
-
-      // We are not small enough yet, return false so the caller knows.
-      return false;
-    }
-
-    function coalesceCollapsedCrumbs() {
-      let crumb = crumbs.firstChild;
-      let collapsedRun = false;
-      let newStartNeeded = false;
-      let newEndNeeded = false;
-      while (crumb) {
-        const hidden = crumb.classList.contains('hidden');
-        if (!hidden) {
-          const collapsed = crumb.classList.contains('collapsed');
-          if (collapsedRun && collapsed) {
-            crumb.classList.add('hidden');
-            crumb.classList.remove('compact');
-            crumb.classList.remove('collapsed');
-
-            if (crumb.classList.contains('start')) {
-              crumb.classList.remove('start');
-              newStartNeeded = true;
-            }
-
-            if (crumb.classList.contains('end')) {
-              crumb.classList.remove('end');
-              newEndNeeded = true;
-            }
-
-            continue;
-          }
-
-          collapsedRun = collapsed;
-
-          if (newEndNeeded) {
-            newEndNeeded = false;
-            crumb.classList.add('end');
-          }
-        } else {
-          collapsedRun = true;
-        }
-        crumb = crumb.nextSibling;
-      }
-
-      if (newStartNeeded) {
-        crumb = crumbs.lastChild;
-        while (crumb) {
-          if (!crumb.classList.contains('hidden')) {
-            crumb.classList.add('start');
-            break;
-          }
-          crumb = crumb.previousSibling;
-        }
-      }
-    }
-
-    /**
-     * @param {!Element} crumb
-     */
-    function compact(crumb) {
-      if (crumb.classList.contains('hidden'))
-        return;
-      crumb.classList.add('compact');
-    }
-
-    /**
-     * @param {!Element} crumb
-     * @param {boolean=} dontCoalesce
-     */
-    function collapse(crumb, dontCoalesce) {
-      if (crumb.classList.contains('hidden'))
-        return;
-      crumb.classList.add('collapsed');
-      crumb.classList.remove('compact');
-      if (!dontCoalesce)
-        coalesceCollapsedCrumbs();
-    }
-
-    if (!focusedCrumb) {
-      // When not focused on a crumb we can be biased and collapse less important
-      // crumbs that the user might not care much about.
-
-      // Compact child crumbs.
-      if (makeCrumbsSmaller(compact, ChildSide))
-        return;
-
-      // Collapse child crumbs.
-      if (makeCrumbsSmaller(collapse, ChildSide))
-        return;
-    }
-
-    // Compact ancestor crumbs, or from both sides if focused.
-    if (makeCrumbsSmaller(compact, focusedCrumb ? BothSides : AncestorSide))
-      return;
-
-    // Collapse ancestor crumbs, or from both sides if focused.
-    if (makeCrumbsSmaller(collapse, focusedCrumb ? BothSides : AncestorSide))
-      return;
-
-    if (!selectedCrumb)
-      return;
-
-    // Compact the selected crumb.
-    compact(selectedCrumb);
-    if (crumbsAreSmallerThanContainer())
-      return;
-
-    // Collapse the selected crumb as a last resort. Pass true to prevent coalescing.
-    collapse(selectedCrumb, true);
-  }
-};
-
-/** @enum {symbol} */
-Elements.ElementsBreadcrumbs.Events = {
-  NodeSelected: Symbol('NodeSelected')
-};
diff --git a/front_end/elements/ElementsPanel.js b/front_end/elements/ElementsPanel.js
deleted file mode 100644
index 570f3b1..0000000
--- a/front_end/elements/ElementsPanel.js
+++ /dev/null
@@ -1,993 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {UI.Searchable}
- * @implements {SDK.SDKModelObserver<!SDK.DOMModel>}
- * @implements {UI.ViewLocationResolver}
- * @unrestricted
- */
-Elements.ElementsPanel = class extends UI.Panel {
-  constructor() {
-    super('elements');
-    this.registerRequiredCSS('elements/elementsPanel.css');
-
-    this._splitWidget = new UI.SplitWidget(true, true, 'elementsPanelSplitViewState', 325, 325);
-    this._splitWidget.addEventListener(
-        UI.SplitWidget.Events.SidebarSizeChanged, this._updateTreeOutlineVisibleWidth.bind(this));
-    this._splitWidget.show(this.element);
-
-    this._searchableView = new UI.SearchableView(this);
-    this._searchableView.setMinimumSize(25, 28);
-    this._searchableView.setPlaceholder(Common.UIString('Find by string, selector, or XPath'));
-    const stackElement = this._searchableView.element;
-
-    this._contentElement = createElement('div');
-    const crumbsContainer = createElement('div');
-    stackElement.appendChild(this._contentElement);
-    stackElement.appendChild(crumbsContainer);
-
-    this._splitWidget.setMainWidget(this._searchableView);
-    /** @type {?Elements.ElementsPanel._splitMode} */
-    this._splitMode = null;
-
-    this._contentElement.id = 'elements-content';
-    // FIXME: crbug.com/425984
-    if (Common.moduleSetting('domWordWrap').get())
-      this._contentElement.classList.add('elements-wrap');
-    Common.moduleSetting('domWordWrap').addChangeListener(this._domWordWrapSettingChanged.bind(this));
-
-    crumbsContainer.id = 'elements-crumbs';
-    this._breadcrumbs = new Elements.ElementsBreadcrumbs();
-    this._breadcrumbs.show(crumbsContainer);
-    this._breadcrumbs.addEventListener(Elements.ElementsBreadcrumbs.Events.NodeSelected, this._crumbNodeSelected, this);
-
-    this._stylesWidget = new Elements.StylesSidebarPane();
-    this._computedStyleWidget = new Elements.ComputedStyleWidget();
-    this._metricsWidget = new Elements.MetricsSidebarPane();
-
-    Common.moduleSetting('sidebarPosition').addChangeListener(this._updateSidebarPosition.bind(this));
-    this._updateSidebarPosition();
-
-    /** @type {!Array.<!Elements.ElementsTreeOutline>} */
-    this._treeOutlines = [];
-    /** @type {!Map<!Elements.ElementsTreeOutline, !Element>} */
-    this._treeOutlineHeaders = new Map();
-    SDK.targetManager.observeModels(SDK.DOMModel, this);
-    SDK.targetManager.addEventListener(
-        SDK.TargetManager.Events.NameChanged,
-        event => this._targetNameChanged(/** @type {!SDK.Target} */ (event.data)));
-    Common.moduleSetting('showUAShadowDOM').addChangeListener(this._showUAShadowDOMChanged.bind(this));
-    SDK.targetManager.addModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.DocumentUpdated, this._documentUpdatedEvent, this);
-    Extensions.extensionServer.addEventListener(
-        Extensions.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this);
-  }
-
-  /**
-   * @return {!Elements.ElementsPanel}
-   */
-  static instance() {
-    return /** @type {!Elements.ElementsPanel} */ (self.runtime.sharedInstance(Elements.ElementsPanel));
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} cssProperty
-   */
-  _revealProperty(cssProperty) {
-    return this.sidebarPaneView.showView(this._stylesViewToReveal).then(() => {
-      this._stylesWidget.revealProperty(/** @type {!SDK.CSSProperty} */ (cssProperty));
-    });
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   * @return {?UI.ViewLocation}
-   */
-  resolveLocation(locationName) {
-    return this.sidebarPaneView;
-  }
-
-  /**
-   * @param {?UI.Widget} widget
-   * @param {?UI.ToolbarToggle} toggle
-   */
-  showToolbarPane(widget, toggle) {
-    // TODO(luoe): remove this function once its providers have an alternative way to reveal their views.
-    this._stylesWidget.showToolbarPane(widget, toggle);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DOMModel} domModel
-   */
-  modelAdded(domModel) {
-    const parentModel = domModel.parentModel();
-    let treeOutline = parentModel ? Elements.ElementsTreeOutline.forDOMModel(parentModel) : null;
-    if (!treeOutline) {
-      treeOutline = new Elements.ElementsTreeOutline(true, true);
-      treeOutline.setWordWrap(Common.moduleSetting('domWordWrap').get());
-      treeOutline.addEventListener(
-          Elements.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
-      treeOutline.addEventListener(
-          Elements.ElementsTreeOutline.Events.ElementsTreeUpdated, this._updateBreadcrumbIfNeeded, this);
-      new Elements.ElementsTreeElementHighlighter(treeOutline);
-      this._treeOutlines.push(treeOutline);
-      if (domModel.target().parentTarget()) {
-        this._treeOutlineHeaders.set(treeOutline, createElementWithClass('div', 'elements-tree-header'));
-        this._targetNameChanged(domModel.target());
-      }
-    }
-    treeOutline.wireToDOMModel(domModel);
-
-    // Perform attach if necessary.
-    if (this.isShowing())
-      this.wasShown();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DOMModel} domModel
-   */
-  modelRemoved(domModel) {
-    const treeOutline = Elements.ElementsTreeOutline.forDOMModel(domModel);
-    treeOutline.unwireFromDOMModel(domModel);
-    if (domModel.parentModel())
-      return;
-    this._treeOutlines.remove(treeOutline);
-    const header = this._treeOutlineHeaders.get(treeOutline);
-    if (header)
-      header.remove();
-    this._treeOutlineHeaders.delete(treeOutline);
-    treeOutline.element.remove();
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  _targetNameChanged(target) {
-    const domModel = target.model(SDK.DOMModel);
-    if (!domModel)
-      return;
-    const treeOutline = Elements.ElementsTreeOutline.forDOMModel(domModel);
-    if (!treeOutline)
-      return;
-    const header = this._treeOutlineHeaders.get(treeOutline);
-    if (!header)
-      return;
-    header.removeChildren();
-    header.createChild('div', 'elements-tree-header-frame').textContent = Common.UIString('Frame');
-    header.appendChild(Components.Linkifier.linkifyURL(target.inspectedURL(), {text: target.name()}));
-  }
-
-  _updateTreeOutlineVisibleWidth() {
-    if (!this._treeOutlines.length)
-      return;
-
-    let width = this._splitWidget.element.offsetWidth;
-    if (this._splitWidget.isVertical())
-      width -= this._splitWidget.sidebarSize();
-    for (let i = 0; i < this._treeOutlines.length; ++i)
-      this._treeOutlines[i].setVisibleWidth(width);
-
-    this._breadcrumbs.updateSizes();
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (this._treeOutlines.length)
-      this._treeOutlines[0].focus();
-  }
-
-  /**
-   * @override
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Elements.ElementsPanel, this);
-
-    for (let i = 0; i < this._treeOutlines.length; ++i) {
-      const treeOutline = this._treeOutlines[i];
-      // Attach heavy component lazily
-      if (treeOutline.element.parentElement !== this._contentElement) {
-        const header = this._treeOutlineHeaders.get(treeOutline);
-        if (header)
-          this._contentElement.appendChild(header);
-        this._contentElement.appendChild(treeOutline.element);
-      }
-    }
-    super.wasShown();
-    this._breadcrumbs.update();
-
-    const domModels = SDK.targetManager.models(SDK.DOMModel);
-    for (const domModel of domModels) {
-      if (domModel.parentModel())
-        continue;
-      const treeOutline = Elements.ElementsTreeOutline.forDOMModel(domModel);
-      treeOutline.setVisible(true);
-
-      if (!treeOutline.rootDOMNode) {
-        if (domModel.existingDocument()) {
-          treeOutline.rootDOMNode = domModel.existingDocument();
-          this._documentUpdated(domModel);
-        } else {
-          domModel.requestDocument();
-        }
-      }
-    }
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    for (let i = 0; i < this._treeOutlines.length; ++i) {
-      const treeOutline = this._treeOutlines[i];
-      treeOutline.setVisible(false);
-      // Detach heavy component on hide
-      this._contentElement.removeChild(treeOutline.element);
-      const header = this._treeOutlineHeaders.get(treeOutline);
-      if (header)
-        this._contentElement.removeChild(header);
-    }
-    if (this._popoverHelper)
-      this._popoverHelper.hidePopover();
-    super.willHide();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this.element.window().requestAnimationFrame(this._updateSidebarPosition.bind(this));  // Do not force layout.
-    this._updateTreeOutlineVisibleWidth();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _selectedNodeChanged(event) {
-    const selectedNode = /** @type {?SDK.DOMNode} */ (event.data.node);
-    const focus = /** @type {boolean} */ (event.data.focus);
-    for (const treeOutline of this._treeOutlines) {
-      if (!selectedNode || Elements.ElementsTreeOutline.forDOMModel(selectedNode.domModel()) !== treeOutline)
-        treeOutline.selectDOMNode(null);
-    }
-
-    this._breadcrumbs.setSelectedNode(selectedNode);
-
-    UI.context.setFlavor(SDK.DOMNode, selectedNode);
-
-    if (!selectedNode)
-      return;
-    selectedNode.setAsInspectedNode();
-    if (focus) {
-      this._selectedNodeOnReset = selectedNode;
-      this._hasNonDefaultSelectedNode = true;
-    }
-
-    const executionContexts = selectedNode.domModel().runtimeModel().executionContexts();
-    const nodeFrameId = selectedNode.frameId();
-    for (const context of executionContexts) {
-      if (context.frameId === nodeFrameId) {
-        UI.context.setFlavor(SDK.ExecutionContext, context);
-        break;
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _documentUpdatedEvent(event) {
-    const domModel = /** @type {!SDK.DOMModel} */ (event.data);
-    this._documentUpdated(domModel);
-  }
-
-  /**
-   * @param {!SDK.DOMModel} domModel
-   */
-  _documentUpdated(domModel) {
-    this._searchableView.resetSearch();
-
-    if (!domModel.existingDocument()) {
-      if (this.isShowing())
-        domModel.requestDocument();
-      return;
-    }
-
-    this._hasNonDefaultSelectedNode = false;
-
-    if (this._omitDefaultSelection)
-      return;
-
-    const savedSelectedNodeOnReset = this._selectedNodeOnReset;
-    restoreNode.call(this, domModel, this._selectedNodeOnReset);
-
-    /**
-     * @param {!SDK.DOMModel} domModel
-     * @param {?SDK.DOMNode} staleNode
-     * @this {Elements.ElementsPanel}
-     */
-    async function restoreNode(domModel, staleNode) {
-      const nodePath = staleNode ? staleNode.path() : null;
-
-      const restoredNodeId = nodePath ? await domModel.pushNodeByPathToFrontend(nodePath) : null;
-
-      if (savedSelectedNodeOnReset !== this._selectedNodeOnReset)
-        return;
-      let node = restoredNodeId ? domModel.nodeForId(restoredNodeId) : null;
-      if (!node) {
-        const inspectedDocument = domModel.existingDocument();
-        node = inspectedDocument ? inspectedDocument.body || inspectedDocument.documentElement : null;
-      }
-      this._setDefaultSelectedNode(node);
-      this._lastSelectedNodeSelectedForTest();
-    }
-  }
-
-  _lastSelectedNodeSelectedForTest() {
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  _setDefaultSelectedNode(node) {
-    if (!node || this._hasNonDefaultSelectedNode || this._pendingNodeReveal)
-      return;
-    const treeOutline = Elements.ElementsTreeOutline.forDOMModel(node.domModel());
-    if (!treeOutline)
-      return;
-    this.selectDOMNode(node);
-    if (treeOutline.selectedTreeElement)
-      treeOutline.selectedTreeElement.expand();
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    delete this._searchConfig;
-    this._hideSearchHighlights();
-
-    this._searchableView.updateSearchMatchesCount(0);
-
-    delete this._currentSearchResultIndex;
-    delete this._searchResults;
-
-    SDK.DOMModel.cancelSearch();
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    const query = searchConfig.query;
-
-    const whitespaceTrimmedQuery = query.trim();
-    if (!whitespaceTrimmedQuery.length)
-      return;
-
-    if (!this._searchConfig || this._searchConfig.query !== query)
-      this.searchCanceled();
-    else
-      this._hideSearchHighlights();
-
-    this._searchConfig = searchConfig;
-
-    const showUAShadowDOM = Common.moduleSetting('showUAShadowDOM').get();
-    const domModels = SDK.targetManager.models(SDK.DOMModel);
-    const promises = domModels.map(domModel => domModel.performSearch(whitespaceTrimmedQuery, showUAShadowDOM));
-    Promise.all(promises).then(resultCountCallback.bind(this));
-
-    /**
-     * @param {!Array.<number>} resultCounts
-     * @this {Elements.ElementsPanel}
-     */
-    function resultCountCallback(resultCounts) {
-      /**
-       * @type {!Array.<{domModel: !SDK.DOMModel, index: number, node: (?SDK.DOMNode|undefined)}>}
-       */
-      this._searchResults = [];
-      for (let i = 0; i < resultCounts.length; ++i) {
-        const resultCount = resultCounts[i];
-        for (let j = 0; j < resultCount; ++j)
-          this._searchResults.push({domModel: domModels[i], index: j, node: undefined});
-      }
-      this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-      if (!this._searchResults.length)
-        return;
-      if (this._currentSearchResultIndex >= this._searchResults.length)
-        this._currentSearchResultIndex = undefined;
-
-      let index = this._currentSearchResultIndex;
-
-      if (shouldJump) {
-        if (this._currentSearchResultIndex === undefined)
-          index = jumpBackwards ? -1 : 0;
-        else
-          index = jumpBackwards ? index - 1 : index + 1;
-        this._jumpToSearchResult(index);
-      }
-    }
-  }
-
-  _domWordWrapSettingChanged(event) {
-    // FIXME: crbug.com/425984
-    this._contentElement.classList.toggle('elements-wrap', event.data);
-    for (let i = 0; i < this._treeOutlines.length; ++i)
-      this._treeOutlines[i].setWordWrap(/** @type {boolean} */ (event.data));
-  }
-
-  switchToAndFocus(node) {
-    // Reset search restore.
-    this._searchableView.cancelSearch();
-    UI.viewManager.showView('elements').then(() => this.selectDOMNode(node, true));
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    let link = event.target;
-    while (link && !link[Elements.ElementsTreeElement.HrefSymbol])
-      link = link.parentElementOrShadowHost();
-    if (!link)
-      return null;
-
-    return {
-      box: link.boxInWindow(),
-      show: async popover => {
-        const node = this.selectedDOMNode();
-        if (!node)
-          return false;
-        const preview = await BrowserComponents.ImagePreview.build(
-            node.domModel().target(), link[Elements.ElementsTreeElement.HrefSymbol], true);
-        if (preview)
-          popover.contentElement.appendChild(preview);
-        return !!preview;
-      }
-    };
-  }
-
-  _jumpToSearchResult(index) {
-    this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
-    this._highlightCurrentSearchResult();
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._searchResults)
-      return;
-    this.performSearch(this._searchConfig, true);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._searchResults)
-      return;
-    this.performSearch(this._searchConfig, true, true);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return false;
-  }
-
-  _highlightCurrentSearchResult() {
-    const index = this._currentSearchResultIndex;
-    const searchResults = this._searchResults;
-    const searchResult = searchResults[index];
-
-    this._searchableView.updateCurrentMatchIndex(index);
-    if (searchResult.node === null)
-      return;
-
-    if (typeof searchResult.node === 'undefined') {
-      // No data for slot, request it.
-      searchResult.domModel.searchResult(searchResult.index).then(node => {
-        searchResult.node = node;
-        this._highlightCurrentSearchResult();
-      });
-      return;
-    }
-
-    const treeElement = this._treeElementForNode(searchResult.node);
-    searchResult.node.scrollIntoView();
-    if (treeElement) {
-      treeElement.highlightSearchResults(this._searchConfig.query);
-      treeElement.reveal();
-      const matches = treeElement.listItemElement.getElementsByClassName(UI.highlightedSearchResultClassName);
-      if (matches.length)
-        matches[0].scrollIntoViewIfNeeded(false);
-    }
-  }
-
-  _hideSearchHighlights() {
-    if (!this._searchResults || !this._searchResults.length || this._currentSearchResultIndex === undefined)
-      return;
-    const searchResult = this._searchResults[this._currentSearchResultIndex];
-    if (!searchResult.node)
-      return;
-    const treeOutline = Elements.ElementsTreeOutline.forDOMModel(searchResult.node.domModel());
-    const treeElement = treeOutline.findTreeElement(searchResult.node);
-    if (treeElement)
-      treeElement.hideSearchHighlights();
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  selectedDOMNode() {
-    for (let i = 0; i < this._treeOutlines.length; ++i) {
-      const treeOutline = this._treeOutlines[i];
-      if (treeOutline.selectedDOMNode())
-        return treeOutline.selectedDOMNode();
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {boolean=} focus
-   */
-  selectDOMNode(node, focus) {
-    for (const treeOutline of this._treeOutlines) {
-      const outline = Elements.ElementsTreeOutline.forDOMModel(node.domModel());
-      if (outline === treeOutline)
-        treeOutline.selectDOMNode(node, focus);
-      else
-        treeOutline.selectDOMNode(null);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _updateBreadcrumbIfNeeded(event) {
-    const nodes = /** @type {!Array.<!SDK.DOMNode>} */ (event.data);
-    this._breadcrumbs.updateNodes(nodes);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _crumbNodeSelected(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    this.selectDOMNode(node, true);
-  }
-
-  /**
-   * @override
-   * @param {!KeyboardEvent} event
-   */
-  handleShortcut(event) {
-    if (this._treeOutlines.find(to => to.editing()))
-      return;
-
-    const treeOutline = this._treeOutlines.find(to => !!to.selectedDOMNode());
-    if (!treeOutline)
-      return;
-
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey &&
-        (event.key === 'Z' || event.key === 'z')) {  // Z key
-      SDK.domModelUndoStack.undo();
-      event.handled = true;
-    }
-
-    const isRedoKey = Host.isMac() ?
-        event.metaKey && event.shiftKey && (event.key === 'Z' || event.key === 'z') :  // Z key
-        event.ctrlKey && (event.key === 'Y' || event.key === 'y');                     // Y key
-    if (isRedoKey) {
-      SDK.domModelUndoStack.redo();
-      event.handled = true;
-    }
-
-    if (event.handled) {
-      this._stylesWidget.forceUpdate();
-      return;
-    }
-
-    treeOutline.handleShortcut(event);
-    if (event.handled)
-      return;
-
-    super.handleShortcut(event);
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   * @return {?Elements.ElementsTreeOutline}
-   */
-  _treeOutlineForNode(node) {
-    if (!node)
-      return null;
-    return Elements.ElementsTreeOutline.forDOMModel(node.domModel());
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {?Elements.ElementsTreeElement}
-   */
-  _treeElementForNode(node) {
-    const treeOutline = this._treeOutlineForNode(node);
-    return /** @type {?Elements.ElementsTreeElement} */ (treeOutline.findTreeElement(node));
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!SDK.DOMNode}
-   */
-  _leaveUserAgentShadowDOM(node) {
-    let userAgentShadowRoot;
-    while ((userAgentShadowRoot = node.ancestorUserAgentShadowRoot()) && userAgentShadowRoot.parentNode)
-      node = userAgentShadowRoot.parentNode;
-    return node;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {boolean} focus
-   * @return {!Promise}
-   */
-  revealAndSelectNode(node, focus) {
-    if (Elements.inspectElementModeController && Elements.inspectElementModeController.isInInspectElementMode())
-      Elements.inspectElementModeController.stopInspection();
-
-    this._omitDefaultSelection = true;
-
-    node = Common.moduleSetting('showUAShadowDOM').get() ? node : this._leaveUserAgentShadowDOM(node);
-    node.highlightForTwoSeconds();
-
-    return UI.viewManager.showView('elements', false, !focus).then(() => {
-      this.selectDOMNode(node, focus);
-      delete this._omitDefaultSelection;
-
-      if (!this._notFirstInspectElement) {
-        Elements.ElementsPanel._firstInspectElementNodeNameForTest = node.nodeName();
-        Elements.ElementsPanel._firstInspectElementCompletedForTest();
-        InspectorFrontendHost.inspectElementCompleted();
-      }
-      this._notFirstInspectElement = true;
-    });
-  }
-
-  _showUAShadowDOMChanged() {
-    for (let i = 0; i < this._treeOutlines.length; ++i)
-      this._treeOutlines[i].update();
-  }
-
-  _updateSidebarPosition() {
-    if (this.sidebarPaneView && this.sidebarPaneView.tabbedPane().shouldHideOnDetach())
-      return;  // We can't reparent extension iframes.
-
-    let splitMode;
-    const position = Common.moduleSetting('sidebarPosition').get();
-    if (position === 'right' || (position === 'auto' && UI.inspectorView.element.offsetWidth > 680))
-      splitMode = Elements.ElementsPanel._splitMode.Vertical;
-    else if (UI.inspectorView.element.offsetWidth > 415)
-      splitMode = Elements.ElementsPanel._splitMode.Horizontal;
-    else
-      splitMode = Elements.ElementsPanel._splitMode.Slim;
-
-    if (this.sidebarPaneView && splitMode === this._splitMode)
-      return;
-    this._splitMode = splitMode;
-
-    const extensionSidebarPanes = Extensions.extensionServer.sidebarPanes();
-    let lastSelectedTabId = null;
-    if (this.sidebarPaneView) {
-      lastSelectedTabId = this.sidebarPaneView.tabbedPane().selectedTabId;
-      this.sidebarPaneView.tabbedPane().detach();
-      this._splitWidget.uninstallResizer(this.sidebarPaneView.tabbedPane().headerElement());
-    }
-
-    this._splitWidget.setVertical(this._splitMode === Elements.ElementsPanel._splitMode.Vertical);
-    this.showToolbarPane(null /* widget */, null /* toggle */);
-
-    const matchedStylePanesWrapper = new UI.VBox();
-    matchedStylePanesWrapper.element.classList.add('style-panes-wrapper');
-    this._stylesWidget.show(matchedStylePanesWrapper.element);
-
-    const computedStylePanesWrapper = new UI.VBox();
-    computedStylePanesWrapper.element.classList.add('style-panes-wrapper');
-    this._computedStyleWidget.show(computedStylePanesWrapper.element);
-
-    /**
-     * @param {boolean} inComputedStyle
-     * @this {Elements.ElementsPanel}
-     */
-    function showMetrics(inComputedStyle) {
-      if (inComputedStyle)
-        this._metricsWidget.show(computedStylePanesWrapper.element, this._computedStyleWidget.element);
-      else
-        this._metricsWidget.show(matchedStylePanesWrapper.element);
-    }
-
-    /**
-     * @param {!Common.Event} event
-     * @this {Elements.ElementsPanel}
-     */
-    function tabSelected(event) {
-      const tabId = /** @type {string} */ (event.data.tabId);
-      if (tabId === Common.UIString('Computed'))
-        showMetrics.call(this, true);
-      else if (tabId === Common.UIString('Styles'))
-        showMetrics.call(this, false);
-    }
-
-    this.sidebarPaneView = UI.viewManager.createTabbedLocation(() => UI.viewManager.showView('elements'));
-    const tabbedPane = this.sidebarPaneView.tabbedPane();
-    if (this._popoverHelper)
-      this._popoverHelper.hidePopover();
-    this._popoverHelper = new UI.PopoverHelper(tabbedPane.element, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setHasPadding(true);
-    this._popoverHelper.setTimeout(0);
-
-    if (this._splitMode !== Elements.ElementsPanel._splitMode.Vertical)
-      this._splitWidget.installResizer(tabbedPane.headerElement());
-
-    const stylesView = new UI.SimpleView(Common.UIString('Styles'));
-    this.sidebarPaneView.appendView(stylesView);
-    if (splitMode === Elements.ElementsPanel._splitMode.Horizontal) {
-      // Styles and computed are merged into a single tab.
-      stylesView.element.classList.add('flex-auto');
-
-      const splitWidget = new UI.SplitWidget(true, true, 'stylesPaneSplitViewState', 215);
-      splitWidget.show(stylesView.element);
-      splitWidget.setMainWidget(matchedStylePanesWrapper);
-      splitWidget.setSidebarWidget(computedStylePanesWrapper);
-    } else {
-      // Styles and computed are in separate tabs.
-      stylesView.element.classList.add('flex-auto');
-      matchedStylePanesWrapper.show(stylesView.element);
-
-      const computedView = new UI.SimpleView(Common.UIString('Computed'));
-      computedView.element.classList.add('composite', 'fill');
-      computedStylePanesWrapper.show(computedView.element);
-
-      tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, tabSelected, this);
-      this.sidebarPaneView.appendView(computedView);
-    }
-    this._stylesViewToReveal = stylesView;
-
-    showMetrics.call(this, this._splitMode === Elements.ElementsPanel._splitMode.Horizontal);
-
-    this.sidebarPaneView.appendApplicableItems('elements-sidebar');
-    for (let i = 0; i < extensionSidebarPanes.length; ++i)
-      this._addExtensionSidebarPane(extensionSidebarPanes[i]);
-
-    if (lastSelectedTabId)
-      this.sidebarPaneView.tabbedPane().selectTab(lastSelectedTabId);
-
-    this._splitWidget.setSidebarWidget(this.sidebarPaneView.tabbedPane());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _extensionSidebarPaneAdded(event) {
-    const pane = /** @type {!Extensions.ExtensionSidebarPane} */ (event.data);
-    this._addExtensionSidebarPane(pane);
-  }
-
-  /**
-   * @param {!Extensions.ExtensionSidebarPane} pane
-   */
-  _addExtensionSidebarPane(pane) {
-    if (pane.panelName() === this.name)
-      this.sidebarPaneView.appendView(pane);
-  }
-};
-
-Elements.ElementsPanel._elementsSidebarViewTitleSymbol = Symbol('title');
-
-/** @enum {symbol} */
-Elements.ElementsPanel._splitMode = {
-  Vertical: Symbol('Vertical'),
-  Horizontal: Symbol('Horizontal'),
-  Slim: Symbol('Slim'),
-};
-
-// Sniffed in tests.
-Elements.ElementsPanel._firstInspectElementCompletedForTest = function() {};
-
-/**
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Elements.ElementsPanel.ContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} object
-   */
-  appendApplicableItems(event, contextMenu, object) {
-    if (!(object instanceof SDK.RemoteObject && (/** @type {!SDK.RemoteObject} */ (object)).isNode()) &&
-        !(object instanceof SDK.DOMNode) && !(object instanceof SDK.DeferredDOMNode))
-      return;
-
-    // Skip adding "Reveal..." menu item for our own tree outline.
-    if (Elements.ElementsPanel.instance().element.isAncestor(/** @type {!Node} */ (event.target)))
-      return;
-    const commandCallback = Common.Revealer.reveal.bind(Common.Revealer, object);
-    contextMenu.revealSection().appendItem(Common.UIString('Reveal in Elements panel'), commandCallback);
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Elements.ElementsPanel.DOMNodeRevealer = class {
-  /**
-   * @override
-   * @param {!Object} node
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  reveal(node, omitFocus) {
-    const panel = Elements.ElementsPanel.instance();
-    panel._pendingNodeReveal = true;
-
-    return new Promise(revealPromise);
-
-    /**
-     * @param {function(undefined)} resolve
-     * @param {function(!Error)} reject
-     */
-    function revealPromise(resolve, reject) {
-      if (node instanceof SDK.DOMNode) {
-        onNodeResolved(/** @type {!SDK.DOMNode} */ (node));
-      } else if (node instanceof SDK.DeferredDOMNode) {
-        (/** @type {!SDK.DeferredDOMNode} */ (node)).resolve(onNodeResolved);
-      } else if (node instanceof SDK.RemoteObject) {
-        const domModel = /** @type {!SDK.RemoteObject} */ (node).runtimeModel().target().model(SDK.DOMModel);
-        if (domModel)
-          domModel.pushObjectAsNodeToFrontend(node).then(onNodeResolved);
-        else
-          reject(new Error('Could not resolve a node to reveal.'));
-      } else {
-        reject(new Error('Can\'t reveal a non-node.'));
-        panel._pendingNodeReveal = false;
-      }
-
-      /**
-       * @param {?SDK.DOMNode} resolvedNode
-       */
-      function onNodeResolved(resolvedNode) {
-        panel._pendingNodeReveal = false;
-
-        if (resolvedNode) {
-          panel.revealAndSelectNode(resolvedNode, !omitFocus).then(resolve);
-          return;
-        }
-        reject(new Error('Could not resolve node to reveal.'));
-      }
-    }
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Elements.ElementsPanel.CSSPropertyRevealer = class {
-  /**
-   * @override
-   * @param {!Object} property
-   * @return {!Promise}
-   */
-  reveal(property) {
-    const panel = Elements.ElementsPanel.instance();
-    return panel._revealProperty(/** @type {!SDK.CSSProperty} */ (property));
-  }
-};
-
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Elements.ElementsActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const node = UI.context.flavor(SDK.DOMNode);
-    if (!node)
-      return true;
-    const treeOutline = Elements.ElementsTreeOutline.forDOMModel(node.domModel());
-    if (!treeOutline)
-      return true;
-
-    switch (actionId) {
-      case 'elements.hide-element':
-        treeOutline.toggleHideElement(node);
-        return true;
-      case 'elements.edit-as-html':
-        treeOutline.toggleEditAsHTML(node);
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @implements {Elements.MarkerDecorator}
- * @unrestricted
- */
-Elements.ElementsPanel.PseudoStateMarkerDecorator = class {
-  /**
-   * @override
-   * @param {!SDK.DOMNode} node
-   * @return {?{title: string, color: string}}
-   */
-  decorate(node) {
-    return {
-      color: 'orange',
-      title: Common.UIString('Element state: %s', ':' + node.domModel().cssModel().pseudoState(node).join(', :'))
-    };
-  }
-};
diff --git a/front_end/elements/ElementsSidebarPane.js b/front_end/elements/ElementsSidebarPane.js
deleted file mode 100644
index 5676b09..0000000
--- a/front_end/elements/ElementsSidebarPane.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.ElementsSidebarPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.element.classList.add('flex-none');
-    this._computedStyleModel = new Elements.ComputedStyleModel();
-    this._computedStyleModel.addEventListener(
-        Elements.ComputedStyleModel.Events.ComputedStyleChanged, this.onCSSModelChanged, this);
-
-    this._updateThrottler = new Common.Throttler(100);
-    this._updateWhenVisible = false;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._computedStyleModel.node();
-  }
-
-  /**
-   * @return {?SDK.CSSModel}
-   */
-  cssModel() {
-    return this._computedStyleModel.cssModel();
-  }
-
-  /**
-   * @protected
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    return Promise.resolve();
-  }
-
-  update() {
-    this._updateWhenVisible = !this.isShowing();
-    if (this._updateWhenVisible)
-      return;
-    this._updateThrottler.schedule(innerUpdate.bind(this));
-
-    /**
-     * @return {!Promise.<?>}
-     * @this {Elements.ElementsSidebarPane}
-     */
-    function innerUpdate() {
-      return this.isShowing() ? this.doUpdate() : Promise.resolve();
-    }
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    if (this._updateWhenVisible)
-      this.update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  onCSSModelChanged(event) {
-  }
-};
diff --git a/front_end/elements/ElementsTreeElement.js b/front_end/elements/ElementsTreeElement.js
deleted file mode 100644
index 70c10f3..0000000
--- a/front_end/elements/ElementsTreeElement.js
+++ /dev/null
@@ -1,1674 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Elements.ElementsTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {boolean=} elementCloseTag
-   */
-  constructor(node, elementCloseTag) {
-    // The title will be updated in onattach.
-    super();
-    this._node = node;
-
-    this._gutterContainer = this.listItemElement.createChild('div', 'gutter-container');
-    this._gutterContainer.addEventListener('click', this._showContextMenu.bind(this));
-    const gutterMenuIcon = UI.Icon.create('largeicon-menu', 'gutter-menu-icon');
-    this._gutterContainer.appendChild(gutterMenuIcon);
-    this._decorationsElement = this._gutterContainer.createChild('div', 'hidden');
-
-    this._elementCloseTag = elementCloseTag;
-
-    if (this._node.nodeType() === Node.ELEMENT_NODE && !elementCloseTag)
-      this._canAddAttributes = true;
-    this._searchQuery = null;
-    this._expandedChildrenLimit = Elements.ElementsTreeElement.InitialChildrenLimit;
-    this._decorationsThrottler = new Common.Throttler(100);
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   */
-  static animateOnDOMUpdate(treeElement) {
-    const tagName = treeElement.listItemElement.querySelector('.webkit-html-tag-name');
-    UI.runCSSAnimationOnce(tagName || treeElement.listItemElement, 'dom-update-highlight');
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Array<!SDK.DOMNode>}
-   */
-  static visibleShadowRoots(node) {
-    let roots = node.shadowRoots();
-    if (roots.length && !Common.moduleSetting('showUAShadowDOM').get())
-      roots = roots.filter(filter);
-
-    /**
-     * @param {!SDK.DOMNode} root
-     */
-    function filter(root) {
-      return root.shadowRootType() !== SDK.DOMNode.ShadowRootTypes.UserAgent;
-    }
-    return roots;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {boolean}
-   */
-  static canShowInlineText(node) {
-    if (node.contentDocument() || node.importedDocument() || node.templateContent() ||
-        Elements.ElementsTreeElement.visibleShadowRoots(node).length || node.hasPseudoElements())
-      return false;
-    if (node.nodeType() !== Node.ELEMENT_NODE)
-      return false;
-    if (!node.firstChild || node.firstChild !== node.lastChild || node.firstChild.nodeType() !== Node.TEXT_NODE)
-      return false;
-    const textChild = node.firstChild;
-    const maxInlineTextChildLength = 80;
-    if (textChild.nodeValue().length < maxInlineTextChildLength)
-      return true;
-    return false;
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!SDK.DOMNode} node
-   * @suppressGlobalPropertiesCheck
-   */
-  static populateForcedPseudoStateItems(contextMenu, node) {
-    const pseudoClasses = ['active', 'hover', 'focus', 'visited', 'focus-within'];
-    try {
-      document.querySelector(':focus-visible');  // Will throw if not supported
-      pseudoClasses.push('focus-visible');
-    } catch (e) {
-    }
-    const forcedPseudoState = node.domModel().cssModel().pseudoState(node);
-    const stateMenu = contextMenu.debugSection().appendSubMenuItem(Common.UIString('Force state'));
-    for (let i = 0; i < pseudoClasses.length; ++i) {
-      const pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
-      stateMenu.defaultSection().appendCheckboxItem(
-          ':' + pseudoClasses[i], setPseudoStateCallback.bind(null, pseudoClasses[i], !pseudoClassForced),
-          pseudoClassForced, false);
-    }
-
-    /**
-     * @param {string} pseudoState
-     * @param {boolean} enabled
-     */
-    function setPseudoStateCallback(pseudoState, enabled) {
-      node.domModel().cssModel().forcePseudoState(node, pseudoState, enabled);
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isClosingTag() {
-    return !!this._elementCloseTag;
-  }
-
-  /**
-   * @return {!SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEditing() {
-    return !!this._editing;
-  }
-
-  /**
-   * @param {string} searchQuery
-   */
-  highlightSearchResults(searchQuery) {
-    if (this._searchQuery !== searchQuery)
-      this._hideSearchHighlight();
-
-    this._searchQuery = searchQuery;
-    this._searchHighlightsVisible = true;
-    this.updateTitle(null, true);
-  }
-
-  hideSearchHighlights() {
-    delete this._searchHighlightsVisible;
-    this._hideSearchHighlight();
-  }
-
-  _hideSearchHighlight() {
-    if (!this._highlightResult)
-      return;
-
-    function updateEntryHide(entry) {
-      switch (entry.type) {
-        case 'added':
-          entry.node.remove();
-          break;
-        case 'changed':
-          entry.node.textContent = entry.oldText;
-          break;
-      }
-    }
-
-    for (let i = (this._highlightResult.length - 1); i >= 0; --i)
-      updateEntryHide(this._highlightResult[i]);
-
-    delete this._highlightResult;
-  }
-
-  /**
-   * @param {boolean} inClipboard
-   */
-  setInClipboard(inClipboard) {
-    if (this._inClipboard === inClipboard)
-      return;
-    this._inClipboard = inClipboard;
-    this.listItemElement.classList.toggle('in-clipboard', inClipboard);
-  }
-
-  get hovered() {
-    return this._hovered;
-  }
-
-  set hovered(x) {
-    if (this._hovered === x)
-      return;
-
-    this._hovered = x;
-
-    if (this.listItemElement) {
-      if (x) {
-        this._createSelection();
-        this.listItemElement.classList.add('hovered');
-      } else {
-        this.listItemElement.classList.remove('hovered');
-      }
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  expandedChildrenLimit() {
-    return this._expandedChildrenLimit;
-  }
-
-  /**
-   * @param {number} expandedChildrenLimit
-   */
-  setExpandedChildrenLimit(expandedChildrenLimit) {
-    this._expandedChildrenLimit = expandedChildrenLimit;
-  }
-
-  _createSelection() {
-    const listItemElement = this.listItemElement;
-    if (!listItemElement)
-      return;
-
-    if (!this.selectionElement) {
-      this.selectionElement = createElement('div');
-      this.selectionElement.className = 'selection fill';
-      this.selectionElement.style.setProperty('margin-left', (-this._computeLeftIndent()) + 'px');
-      listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
-    }
-  }
-
-  _createHint() {
-    if (this.listItemElement && !this._hintElement) {
-      this._hintElement = this.listItemElement.createChild('span', 'selected-hint');
-      this._hintElement.title = Common.UIString('Use $0 in the console to refer to this element.');
-    }
-  }
-
-  /**
-   * @override
-   */
-  onbind() {
-    if (!this._elementCloseTag)
-      this._node[this.treeOutline.treeElementSymbol()] = this;
-  }
-
-  /**
-   * @override
-   */
-  onunbind() {
-    if (this._node[this.treeOutline.treeElementSymbol()] === this)
-      this._node[this.treeOutline.treeElementSymbol()] = null;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    if (this._hovered) {
-      this._createSelection();
-      this.listItemElement.classList.add('hovered');
-    }
-
-    this.updateTitle();
-    this.listItemElement.draggable = true;
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    this.populated = true;
-    this.treeOutline.populateTreeElement(this);
-  }
-
-  /**
-   * @override
-   */
-  expandRecursively() {
-    this._node.getSubtree(-1, true).then(UI.TreeElement.prototype.expandRecursively.bind(this, Number.MAX_VALUE));
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    if (this._elementCloseTag)
-      return;
-
-    this.updateTitle();
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    if (this._elementCloseTag)
-      return;
-
-    this.updateTitle();
-  }
-
-  /**
-   * @override
-   * @param {boolean=} omitFocus
-   * @param {boolean=} selectedByUser
-   * @return {boolean}
-   */
-  select(omitFocus, selectedByUser) {
-    if (this._editing)
-      return false;
-    return super.select(omitFocus, selectedByUser);
-  }
-
-  /**
-   * @override
-   * @param {boolean=} selectedByUser
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    this.treeOutline.suppressRevealAndSelect = true;
-    this.treeOutline.selectDOMNode(this._node, selectedByUser);
-    if (selectedByUser) {
-      this._node.highlight();
-      Host.userMetrics.actionTaken(Host.UserMetrics.Action.ChangeInspectedNodeInElementsPanel);
-    }
-    this._createSelection();
-    this._createHint();
-    this.treeOutline.suppressRevealAndSelect = false;
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondelete() {
-    const startTagTreeElement = this.treeOutline.findTreeElement(this._node);
-    startTagTreeElement ? startTagTreeElement.remove() : this.remove();
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onenter() {
-    // On Enter or Return start editing the first attribute
-    // or create a new attribute on the selected element.
-    if (this._editing)
-      return false;
-
-    this._startEditing();
-
-    // prevent a newline from being immediately inserted
-    return true;
-  }
-
-  /**
-   * @override
-   */
-  selectOnMouseDown(event) {
-    super.selectOnMouseDown(event);
-
-    if (this._editing)
-      return;
-
-    // Prevent selecting the nearest word on double click.
-    if (event.detail >= 2)
-      event.preventDefault();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondblclick(event) {
-    if (this._editing || this._elementCloseTag)
-      return false;
-
-    if (this._startEditingTarget(/** @type {!Element} */ (event.target)))
-      return false;
-
-    if (this.isExpandable() && !this.expanded)
-      this.expand();
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasEditableNode() {
-    return !this._node.isShadowRoot() && !this._node.ancestorUserAgentShadowRoot();
-  }
-
-  _insertInLastAttributePosition(tag, node) {
-    if (tag.getElementsByClassName('webkit-html-attribute').length > 0) {
-      tag.insertBefore(node, tag.lastChild);
-    } else {
-      const nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
-      tag.textContent = '';
-      tag.createTextChild('<' + nodeName);
-      tag.appendChild(node);
-      tag.createTextChild('>');
-    }
-  }
-
-  /**
-   * @param {!Element} eventTarget
-   * @return {boolean}
-   */
-  _startEditingTarget(eventTarget) {
-    if (this.treeOutline.selectedDOMNode() !== this._node)
-      return false;
-
-    if (this._node.nodeType() !== Node.ELEMENT_NODE && this._node.nodeType() !== Node.TEXT_NODE)
-      return false;
-
-    const textNode = eventTarget.enclosingNodeOrSelfWithClass('webkit-html-text-node');
-    if (textNode)
-      return this._startEditingTextNode(textNode);
-
-    const attribute = eventTarget.enclosingNodeOrSelfWithClass('webkit-html-attribute');
-    if (attribute)
-      return this._startEditingAttribute(attribute, eventTarget);
-
-    const tagName = eventTarget.enclosingNodeOrSelfWithClass('webkit-html-tag-name');
-    if (tagName)
-      return this._startEditingTagName(tagName);
-
-    const newAttribute = eventTarget.enclosingNodeOrSelfWithClass('add-attribute');
-    if (newAttribute)
-      return this._addNewAttribute();
-
-    return false;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _showContextMenu(event) {
-    this.treeOutline.showContextMenu(this, event);
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Event} event
-   */
-  populateTagContextMenu(contextMenu, event) {
-    // Add attribute-related actions.
-    const treeElement = this._elementCloseTag ? this.treeOutline.findTreeElement(this._node) : this;
-    contextMenu.editSection().appendItem(
-        Common.UIString('Add attribute'), treeElement._addNewAttribute.bind(treeElement));
-
-    const attribute = event.target.enclosingNodeOrSelfWithClass('webkit-html-attribute');
-    const newAttribute = event.target.enclosingNodeOrSelfWithClass('add-attribute');
-    if (attribute && !newAttribute) {
-      contextMenu.editSection().appendItem(
-          Common.UIString('Edit attribute'), this._startEditingAttribute.bind(this, attribute, event.target));
-    }
-    this.populateNodeContextMenu(contextMenu);
-    Elements.ElementsTreeElement.populateForcedPseudoStateItems(contextMenu, treeElement.node());
-    this.populateScrollIntoView(contextMenu);
-    contextMenu.viewSection().appendItem(Common.UIString('Focus'), async () => {
-      await this._node.focus();
-    });
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  populateScrollIntoView(contextMenu) {
-    contextMenu.viewSection().appendItem(Common.UIString('Scroll into view'), () => this._node.scrollIntoView());
-  }
-
-  populateTextContextMenu(contextMenu, textNode) {
-    if (!this._editing) {
-      contextMenu.editSection().appendItem(
-          Common.UIString('Edit text'), this._startEditingTextNode.bind(this, textNode));
-    }
-    this.populateNodeContextMenu(contextMenu);
-  }
-
-  populateNodeContextMenu(contextMenu) {
-    // Add free-form node-related actions.
-    const isEditable = this.hasEditableNode();
-    if (isEditable && !this._editing)
-      contextMenu.editSection().appendItem(Common.UIString('Edit as HTML'), this._editAsHTML.bind(this));
-    const isShadowRoot = this._node.isShadowRoot();
-
-    // Place it here so that all "Copy"-ing items stick together.
-    const copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
-    const createShortcut = UI.KeyboardShortcut.shortcutToString;
-    const modifier = UI.KeyboardShortcut.Modifiers.CtrlOrMeta;
-    const treeOutline = this.treeOutline;
-    let menuItem;
-    let section;
-    if (!isShadowRoot) {
-      section = copyMenu.section();
-      menuItem = section.appendItem(
-          Common.UIString('Copy outerHTML'), treeOutline.performCopyOrCut.bind(treeOutline, false, this._node));
-      menuItem.setShortcut(createShortcut('V', modifier));
-    }
-    if (this._node.nodeType() === Node.ELEMENT_NODE)
-      section.appendItem(Common.UIString('Copy selector'), this._copyCSSPath.bind(this));
-    if (!isShadowRoot)
-      section.appendItem(Common.UIString('Copy XPath'), this._copyXPath.bind(this));
-    if (!isShadowRoot) {
-      menuItem = copyMenu.clipboardSection().appendItem(
-          Common.UIString('Cut element'), treeOutline.performCopyOrCut.bind(treeOutline, true, this._node),
-          !this.hasEditableNode());
-      menuItem.setShortcut(createShortcut('X', modifier));
-      menuItem = copyMenu.clipboardSection().appendItem(
-          Common.UIString('Copy element'), treeOutline.performCopyOrCut.bind(treeOutline, false, this._node));
-      menuItem.setShortcut(createShortcut('C', modifier));
-      menuItem = copyMenu.clipboardSection().appendItem(
-          Common.UIString('Paste element'), treeOutline.pasteNode.bind(treeOutline, this._node),
-          !treeOutline.canPaste(this._node));
-      menuItem.setShortcut(createShortcut('V', modifier));
-    }
-
-    menuItem = contextMenu.debugSection().appendCheckboxItem(
-        Common.UIString('Hide element'), treeOutline.toggleHideElement.bind(treeOutline, this._node),
-        treeOutline.isToggledToHidden(this._node));
-    menuItem.setShortcut(UI.shortcutRegistry.shortcutTitleForAction('elements.hide-element'));
-
-    if (isEditable)
-      contextMenu.editSection().appendItem(Common.UIString('Delete element'), this.remove.bind(this));
-
-    contextMenu.viewSection().appendItem(ls`Expand recursively`, this.expandRecursively.bind(this));
-    contextMenu.viewSection().appendItem(ls`Collapse children`, this.collapseChildren.bind(this));
-  }
-
-  _startEditing() {
-    if (this.treeOutline.selectedDOMNode() !== this._node)
-      return;
-
-    const listItem = this.listItemElement;
-
-    if (this._canAddAttributes) {
-      const attribute = listItem.getElementsByClassName('webkit-html-attribute')[0];
-      if (attribute) {
-        return this._startEditingAttribute(
-            attribute, attribute.getElementsByClassName('webkit-html-attribute-value')[0]);
-      }
-
-      return this._addNewAttribute();
-    }
-
-    if (this._node.nodeType() === Node.TEXT_NODE) {
-      const textNode = listItem.getElementsByClassName('webkit-html-text-node')[0];
-      if (textNode)
-        return this._startEditingTextNode(textNode);
-      return;
-    }
-  }
-
-  _addNewAttribute() {
-    // Cannot just convert the textual html into an element without
-    // a parent node. Use a temporary span container for the HTML.
-    const container = createElement('span');
-    this._buildAttributeDOM(container, ' ', '', null);
-    const attr = container.firstElementChild;
-    attr.style.marginLeft = '2px';   // overrides the .editing margin rule
-    attr.style.marginRight = '2px';  // overrides the .editing margin rule
-
-    const tag = this.listItemElement.getElementsByClassName('webkit-html-tag')[0];
-    this._insertInLastAttributePosition(tag, attr);
-    attr.scrollIntoViewIfNeeded(true);
-    return this._startEditingAttribute(attr, attr);
-  }
-
-  _triggerEditAttribute(attributeName) {
-    const attributeElements = this.listItemElement.getElementsByClassName('webkit-html-attribute-name');
-    for (let i = 0, len = attributeElements.length; i < len; ++i) {
-      if (attributeElements[i].textContent === attributeName) {
-        for (let elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
-          if (elem.nodeType !== Node.ELEMENT_NODE)
-            continue;
-
-          if (elem.classList.contains('webkit-html-attribute-value'))
-            return this._startEditingAttribute(elem.parentNode, elem);
-        }
-      }
-    }
-  }
-
-  _startEditingAttribute(attribute, elementForSelection) {
-    console.assert(this.listItemElement.isAncestor(attribute));
-
-    if (UI.isBeingEdited(attribute))
-      return true;
-
-    const attributeNameElement = attribute.getElementsByClassName('webkit-html-attribute-name')[0];
-    if (!attributeNameElement)
-      return false;
-
-    const attributeName = attributeNameElement.textContent;
-    const attributeValueElement = attribute.getElementsByClassName('webkit-html-attribute-value')[0];
-
-    // Make sure elementForSelection is not a child of attributeValueElement.
-    elementForSelection =
-        attributeValueElement.isAncestor(elementForSelection) ? attributeValueElement : elementForSelection;
-
-    function removeZeroWidthSpaceRecursive(node) {
-      if (node.nodeType === Node.TEXT_NODE) {
-        node.nodeValue = node.nodeValue.replace(/\u200B/g, '');
-        return;
-      }
-
-      if (node.nodeType !== Node.ELEMENT_NODE)
-        return;
-
-      for (let child = node.firstChild; child; child = child.nextSibling)
-        removeZeroWidthSpaceRecursive(child);
-    }
-
-    const attributeValue = attributeName && attributeValueElement ? this._node.getAttribute(attributeName) : undefined;
-    if (attributeValue !== undefined) {
-      attributeValueElement.setTextContentTruncatedIfNeeded(
-          attributeValue, Common.UIString('<value is too large to edit>'));
-    }
-
-    // Remove zero-width spaces that were added by nodeTitleInfo.
-    removeZeroWidthSpaceRecursive(attribute);
-
-    const config = new UI.InplaceEditor.Config(
-        this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
-
-    /**
-     * @param {!Event} event
-     * @return {string}
-     */
-    function postKeyDownFinishHandler(event) {
-      UI.handleElementValueModifications(event, attribute);
-      return '';
-    }
-
-    if (!attributeValueElement.textContent.asParsedURL())
-      config.setPostKeydownFinishHandler(postKeyDownFinishHandler);
-
-    this._editing = UI.InplaceEditor.startEditing(attribute, config);
-
-    this.listItemElement.getComponentSelection().selectAllChildren(elementForSelection);
-
-    return true;
-  }
-
-  /**
-   * @param {!Element} textNodeElement
-   */
-  _startEditingTextNode(textNodeElement) {
-    if (UI.isBeingEdited(textNodeElement))
-      return true;
-
-    let textNode = this._node;
-    // We only show text nodes inline in elements if the element only
-    // has a single child, and that child is a text node.
-    if (textNode.nodeType() === Node.ELEMENT_NODE && textNode.firstChild)
-      textNode = textNode.firstChild;
-
-    const container = textNodeElement.enclosingNodeOrSelfWithClass('webkit-html-text-node');
-    if (container)
-      container.textContent = textNode.nodeValue();  // Strip the CSS or JS highlighting if present.
-    const config = new UI.InplaceEditor.Config(
-        this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this));
-    this._editing = UI.InplaceEditor.startEditing(textNodeElement, config);
-    this.listItemElement.getComponentSelection().selectAllChildren(textNodeElement);
-
-    return true;
-  }
-
-  /**
-   * @param {!Element=} tagNameElement
-   */
-  _startEditingTagName(tagNameElement) {
-    if (!tagNameElement) {
-      tagNameElement = this.listItemElement.getElementsByClassName('webkit-html-tag-name')[0];
-      if (!tagNameElement)
-        return false;
-    }
-
-    const tagName = tagNameElement.textContent;
-    if (Elements.ElementsTreeElement.EditTagBlacklist.has(tagName.toLowerCase()))
-      return false;
-
-    if (UI.isBeingEdited(tagNameElement))
-      return true;
-
-    const closingTagElement = this._distinctClosingTagElement();
-
-    /**
-     * @param {!Event} event
-     */
-    function keyupListener(event) {
-      if (closingTagElement)
-        closingTagElement.textContent = '</' + tagNameElement.textContent + '>';
-    }
-
-    /**
-     * @param {!Event} event
-     */
-    const keydownListener = event => {
-      if (event.key !== ' ')
-        return;
-      this._editing.commit();
-      event.consume(true);
-    };
-
-    /**
-     * @param {!Element} element
-     * @param {string} newTagName
-     * @this {Elements.ElementsTreeElement}
-     */
-    function editingComitted(element, newTagName) {
-      tagNameElement.removeEventListener('keyup', keyupListener, false);
-      tagNameElement.removeEventListener('keydown', keydownListener, false);
-      this._tagNameEditingCommitted.apply(this, arguments);
-    }
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function editingCancelled() {
-      tagNameElement.removeEventListener('keyup', keyupListener, false);
-      tagNameElement.removeEventListener('keydown', keydownListener, false);
-      this._editingCancelled.apply(this, arguments);
-    }
-
-    tagNameElement.addEventListener('keyup', keyupListener, false);
-    tagNameElement.addEventListener('keydown', keydownListener, false);
-
-    const config = new UI.InplaceEditor.Config(editingComitted.bind(this), editingCancelled.bind(this), tagName);
-    this._editing = UI.InplaceEditor.startEditing(tagNameElement, config);
-    this.listItemElement.getComponentSelection().selectAllChildren(tagNameElement);
-    return true;
-  }
-
-  /**
-   * @param {function(string, string)} commitCallback
-   * @param {function()} disposeCallback
-   * @param {?string} maybeInitialValue
-   */
-  _startEditingAsHTML(commitCallback, disposeCallback, maybeInitialValue) {
-    if (maybeInitialValue === null)
-      return;
-    let initialValue = maybeInitialValue;  // To suppress a compiler warning.
-    if (this._editing)
-      return;
-
-    function consume(event) {
-      if (event.eventPhase === Event.AT_TARGET)
-        event.consume(true);
-    }
-
-    initialValue = this._convertWhitespaceToEntities(initialValue).text;
-
-    this._htmlEditElement = createElement('div');
-    this._htmlEditElement.className = 'source-code elements-tree-editor';
-
-    // Hide header items.
-    let child = this.listItemElement.firstChild;
-    while (child) {
-      child.style.display = 'none';
-      child = child.nextSibling;
-    }
-    // Hide children item.
-    if (this.childrenListElement)
-      this.childrenListElement.style.display = 'none';
-    // Append editor.
-    this.listItemElement.appendChild(this._htmlEditElement);
-    this.treeOutline.element.addEventListener('mousedown', consume, false);
-
-    self.runtime.extension(UI.TextEditorFactory).instance().then(gotFactory.bind(this));
-
-    /**
-     * @param {!UI.TextEditorFactory} factory
-     * @this {Elements.ElementsTreeElement}
-     */
-    function gotFactory(factory) {
-      const editor = factory.createEditor({
-        lineNumbers: false,
-        lineWrapping: Common.moduleSetting('domWordWrap').get(),
-        mimeType: 'text/html',
-        autoHeight: false,
-        padBottom: false
-      });
-      this._editing =
-          {commit: commit.bind(this), cancel: dispose.bind(this), editor: editor, resize: resize.bind(this)};
-      resize.call(this);
-
-      editor.widget().show(this._htmlEditElement);
-      editor.setText(initialValue);
-      editor.widget().focus();
-      editor.widget().element.addEventListener('blur', this._editing.commit, true);
-      editor.widget().element.addEventListener('keydown', keydown.bind(this), true);
-
-      this.treeOutline.setMultilineEditing(this._editing);
-    }
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function resize() {
-      this._htmlEditElement.style.width = this.treeOutline.visibleWidth() - this._computeLeftIndent() - 30 + 'px';
-      this._editing.editor.onResize();
-    }
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function commit() {
-      commitCallback(initialValue, this._editing.editor.text());
-      dispose.call(this);
-    }
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function dispose() {
-      this._editing.editor.widget().element.removeEventListener('blur', this._editing.commit, true);
-      this._editing.editor.widget().detach();
-      delete this._editing;
-
-      // Remove editor.
-      this.listItemElement.removeChild(this._htmlEditElement);
-      delete this._htmlEditElement;
-      // Unhide children item.
-      if (this.childrenListElement)
-        this.childrenListElement.style.removeProperty('display');
-      // Unhide header items.
-      let child = this.listItemElement.firstChild;
-      while (child) {
-        child.style.removeProperty('display');
-        child = child.nextSibling;
-      }
-
-      if (this.treeOutline) {
-        this.treeOutline.setMultilineEditing(null);
-        this.treeOutline.element.removeEventListener('mousedown', consume, false);
-        this.treeOutline.focus();
-      }
-
-      disposeCallback();
-    }
-
-    /**
-     * @param {!Event} event
-     * @this {!Elements.ElementsTreeElement}
-     */
-    function keydown(event) {
-      const isMetaOrCtrl = UI.KeyboardShortcut.eventHasCtrlOrMeta(/** @type {!KeyboardEvent} */ (event)) &&
-          !event.altKey && !event.shiftKey;
-      if (isEnterKey(event) && (isMetaOrCtrl || event.isMetaOrCtrlForTest)) {
-        event.consume(true);
-        this._editing.commit();
-      } else if (event.keyCode === UI.KeyboardShortcut.Keys.Esc.code || event.key === 'Escape') {
-        event.consume(true);
-        this._editing.cancel();
-      }
-    }
-  }
-
-  _attributeEditingCommitted(element, newText, oldText, attributeName, moveDirection) {
-    delete this._editing;
-
-    const treeOutline = this.treeOutline;
-
-    /**
-     * @param {?Protocol.Error=} error
-     * @this {Elements.ElementsTreeElement}
-     */
-    function moveToNextAttributeIfNeeded(error) {
-      if (error)
-        this._editingCancelled(element, attributeName);
-
-      if (!moveDirection)
-        return;
-
-      treeOutline.runPendingUpdates();
-      treeOutline.focus();
-
-      // Search for the attribute's position, and then decide where to move to.
-      const attributes = this._node.attributes();
-      for (let i = 0; i < attributes.length; ++i) {
-        if (attributes[i].name !== attributeName)
-          continue;
-
-        if (moveDirection === 'backward') {
-          if (i === 0)
-            this._startEditingTagName();
-          else
-            this._triggerEditAttribute(attributes[i - 1].name);
-        } else {
-          if (i === attributes.length - 1)
-            this._addNewAttribute();
-          else
-            this._triggerEditAttribute(attributes[i + 1].name);
-        }
-        return;
-      }
-
-      // Moving From the "New Attribute" position.
-      if (moveDirection === 'backward') {
-        if (newText === ' ') {
-          // Moving from "New Attribute" that was not edited
-          if (attributes.length > 0)
-            this._triggerEditAttribute(attributes[attributes.length - 1].name);
-        } else {
-          // Moving from "New Attribute" that holds new value
-          if (attributes.length > 1)
-            this._triggerEditAttribute(attributes[attributes.length - 2].name);
-        }
-      } else if (moveDirection === 'forward') {
-        if (!newText.isWhitespace())
-          this._addNewAttribute();
-        else
-          this._startEditingTagName();
-      }
-    }
-
-    if ((attributeName.trim() || newText.trim()) && oldText !== newText) {
-      this._node.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
-      return;
-    }
-
-    this.updateTitle();
-    moveToNextAttributeIfNeeded.call(this);
-  }
-
-  _tagNameEditingCommitted(element, newText, oldText, tagName, moveDirection) {
-    delete this._editing;
-    const self = this;
-
-    function cancel() {
-      const closingTagElement = self._distinctClosingTagElement();
-      if (closingTagElement)
-        closingTagElement.textContent = '</' + tagName + '>';
-
-      self._editingCancelled(element, tagName);
-      moveToNextAttributeIfNeeded.call(self);
-    }
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function moveToNextAttributeIfNeeded() {
-      if (moveDirection !== 'forward') {
-        this._addNewAttribute();
-        return;
-      }
-
-      const attributes = this._node.attributes();
-      if (attributes.length > 0)
-        this._triggerEditAttribute(attributes[0].name);
-      else
-        this._addNewAttribute();
-    }
-
-    newText = newText.trim();
-    if (newText === oldText) {
-      cancel();
-      return;
-    }
-
-    const treeOutline = this.treeOutline;
-    const wasExpanded = this.expanded;
-
-    this._node.setNodeName(newText, (error, newNode) => {
-      if (error || !newNode) {
-        cancel();
-        return;
-      }
-      const newTreeItem = treeOutline.selectNodeAfterEdit(wasExpanded, error, newNode);
-      moveToNextAttributeIfNeeded.call(newTreeItem);
-    });
-  }
-
-  /**
-   * @param {!SDK.DOMNode} textNode
-   * @param {!Element} element
-   * @param {string} newText
-   */
-  _textNodeEditingCommitted(textNode, element, newText) {
-    delete this._editing;
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function callback() {
-      this.updateTitle();
-    }
-    textNode.setNodeValue(newText, callback.bind(this));
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {*} context
-   */
-  _editingCancelled(element, context) {
-    delete this._editing;
-
-    // Need to restore attributes structure.
-    this.updateTitle();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _distinctClosingTagElement() {
-    // FIXME: Improve the Tree Element / Outline Abstraction to prevent crawling the DOM
-
-    // For an expanded element, it will be the last element with class "close"
-    // in the child element list.
-    if (this.expanded) {
-      const closers = this.childrenListElement.querySelectorAll('.close');
-      return closers[closers.length - 1];
-    }
-
-    // Remaining cases are single line non-expanded elements with a closing
-    // tag, or HTML elements without a closing tag (such as <br>). Return
-    // null in the case where there isn't a closing tag.
-    const tags = this.listItemElement.getElementsByClassName('webkit-html-tag');
-    return (tags.length === 1 ? null : tags[tags.length - 1]);
-  }
-
-  /**
-   * @param {?Elements.ElementsTreeOutline.UpdateRecord=} updateRecord
-   * @param {boolean=} onlySearchQueryChanged
-   */
-  updateTitle(updateRecord, onlySearchQueryChanged) {
-    // If we are editing, return early to prevent canceling the edit.
-    // After editing is committed updateTitle will be called.
-    if (this._editing)
-      return;
-
-    if (onlySearchQueryChanged) {
-      this._hideSearchHighlight();
-    } else {
-      const nodeInfo = this._nodeTitleInfo(updateRecord || null);
-      if (this._node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE && this._node.isInShadowTree() &&
-          this._node.shadowRootType()) {
-        this.childrenListElement.classList.add('shadow-root');
-        let depth = 4;
-        for (let node = this._node; depth && node; node = node.parentNode) {
-          if (node.nodeType() === Node.DOCUMENT_FRAGMENT_NODE)
-            depth--;
-        }
-        if (!depth)
-          this.childrenListElement.classList.add('shadow-root-deep');
-        else
-          this.childrenListElement.classList.add('shadow-root-depth-' + depth);
-      }
-      const highlightElement = createElement('span');
-      highlightElement.className = 'highlight';
-      highlightElement.appendChild(nodeInfo);
-      this.title = highlightElement;
-      this.updateDecorations();
-      this.listItemElement.insertBefore(this._gutterContainer, this.listItemElement.firstChild);
-      delete this._highlightResult;
-      delete this.selectionElement;
-      delete this._hintElement;
-      if (this.selected) {
-        this._createSelection();
-        this._createHint();
-      }
-    }
-
-    this._highlightSearchResults();
-  }
-
-  /**
-   * @return {number}
-   */
-  _computeLeftIndent() {
-    let treeElement = this.parent;
-    let depth = 0;
-    while (treeElement !== null) {
-      depth++;
-      treeElement = treeElement.parent;
-    }
-
-    /** Keep it in sync with elementsTreeOutline.css **/
-    return 12 * (depth - 2) + (this.isExpandable() ? 1 : 12);
-  }
-
-  updateDecorations() {
-    this._gutterContainer.style.left = (-this._computeLeftIndent()) + 'px';
-
-    if (this.isClosingTag())
-      return;
-
-    if (this._node.nodeType() !== Node.ELEMENT_NODE)
-      return;
-
-    this._decorationsThrottler.schedule(this._updateDecorationsInternal.bind(this));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _updateDecorationsInternal() {
-    if (!this.treeOutline)
-      return Promise.resolve();
-
-    const node = this._node;
-
-    if (!this.treeOutline._decoratorExtensions)
-      /** @type {!Array.<!Runtime.Extension>} */
-      this.treeOutline._decoratorExtensions = self.runtime.extensions(Elements.MarkerDecorator);
-
-    const markerToExtension = new Map();
-    for (let i = 0; i < this.treeOutline._decoratorExtensions.length; ++i) {
-      markerToExtension.set(
-          this.treeOutline._decoratorExtensions[i].descriptor()['marker'], this.treeOutline._decoratorExtensions[i]);
-    }
-
-    const promises = [];
-    const decorations = [];
-    const descendantDecorations = [];
-    node.traverseMarkers(visitor);
-
-    /**
-     * @param {!SDK.DOMNode} n
-     * @param {string} marker
-     */
-    function visitor(n, marker) {
-      const extension = markerToExtension.get(marker);
-      if (!extension)
-        return;
-      promises.push(extension.instance().then(collectDecoration.bind(null, n)));
-    }
-
-    /**
-     * @param {!SDK.DOMNode} n
-     * @param {!Elements.MarkerDecorator} decorator
-     */
-    function collectDecoration(n, decorator) {
-      const decoration = decorator.decorate(n);
-      if (!decoration)
-        return;
-      (n === node ? decorations : descendantDecorations).push(decoration);
-    }
-
-    return Promise.all(promises).then(updateDecorationsUI.bind(this));
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function updateDecorationsUI() {
-      this._decorationsElement.removeChildren();
-      this._decorationsElement.classList.add('hidden');
-      this._gutterContainer.classList.toggle('has-decorations', decorations.length || descendantDecorations.length);
-
-      if (!decorations.length && !descendantDecorations.length)
-        return;
-
-      const colors = new Set();
-      const titles = createElement('div');
-
-      for (const decoration of decorations) {
-        const titleElement = titles.createChild('div');
-        titleElement.textContent = decoration.title;
-        colors.add(decoration.color);
-      }
-      if (this.expanded && !decorations.length)
-        return;
-
-      const descendantColors = new Set();
-      if (descendantDecorations.length) {
-        let element = titles.createChild('div');
-        element.textContent = Common.UIString('Children:');
-        for (const decoration of descendantDecorations) {
-          element = titles.createChild('div');
-          element.style.marginLeft = '15px';
-          element.textContent = decoration.title;
-          descendantColors.add(decoration.color);
-        }
-      }
-
-      let offset = 0;
-      processColors.call(this, colors, 'elements-gutter-decoration');
-      if (!this.expanded)
-        processColors.call(this, descendantColors, 'elements-gutter-decoration elements-has-decorated-children');
-      UI.Tooltip.install(this._decorationsElement, titles);
-
-      /**
-       * @param {!Set<string>} colors
-       * @param {string} className
-       * @this {Elements.ElementsTreeElement}
-       */
-      function processColors(colors, className) {
-        for (const color of colors) {
-          const child = this._decorationsElement.createChild('div', className);
-          this._decorationsElement.classList.remove('hidden');
-          child.style.backgroundColor = color;
-          child.style.borderColor = color;
-          if (offset)
-            child.style.marginLeft = offset + 'px';
-          offset += 3;
-        }
-      }
-    }
-  }
-
-  /**
-   * @param {!Node} parentElement
-   * @param {string} name
-   * @param {string} value
-   * @param {?Elements.ElementsTreeOutline.UpdateRecord} updateRecord
-   * @param {boolean=} forceValue
-   * @param {!SDK.DOMNode=} node
-   */
-  _buildAttributeDOM(parentElement, name, value, updateRecord, forceValue, node) {
-    const closingPunctuationRegex = /[\/;:\)\]\}]/g;
-    let highlightIndex = 0;
-    let highlightCount;
-    let additionalHighlightOffset = 0;
-    let result;
-
-    /**
-     * @param {string} match
-     * @param {number} replaceOffset
-     * @return {string}
-     */
-    function replacer(match, replaceOffset) {
-      while (highlightIndex < highlightCount && result.entityRanges[highlightIndex].offset < replaceOffset) {
-        result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
-        ++highlightIndex;
-      }
-      additionalHighlightOffset += 1;
-      return match + '\u200B';
-    }
-
-    /**
-     * @param {!Element} element
-     * @param {string} value
-     * @this {Elements.ElementsTreeElement}
-     */
-    function setValueWithEntities(element, value) {
-      result = this._convertWhitespaceToEntities(value);
-      highlightCount = result.entityRanges.length;
-      value = result.text.replace(closingPunctuationRegex, replacer);
-      while (highlightIndex < highlightCount) {
-        result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
-        ++highlightIndex;
-      }
-      element.setTextContentTruncatedIfNeeded(value);
-      UI.highlightRangesWithStyleClass(element, result.entityRanges, 'webkit-html-entity-value');
-    }
-
-    const hasText = (forceValue || value.length > 0);
-    const attrSpanElement = parentElement.createChild('span', 'webkit-html-attribute');
-    const attrNameElement = attrSpanElement.createChild('span', 'webkit-html-attribute-name');
-    attrNameElement.textContent = name;
-
-    if (hasText)
-      attrSpanElement.createTextChild('=\u200B"');
-
-    const attrValueElement = attrSpanElement.createChild('span', 'webkit-html-attribute-value');
-
-    if (updateRecord && updateRecord.isAttributeModified(name))
-      UI.runCSSAnimationOnce(hasText ? attrValueElement : attrNameElement, 'dom-update-highlight');
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     * @param {string} value
-     * @return {!Element}
-     */
-    function linkifyValue(value) {
-      const rewrittenHref = node.resolveURL(value);
-      if (rewrittenHref === null) {
-        const span = createElement('span');
-        setValueWithEntities.call(this, span, value);
-        return span;
-      }
-      value = value.replace(closingPunctuationRegex, '$&\u200B');
-      if (value.startsWith('data:'))
-        value = value.trimMiddle(60);
-      const link = node.nodeName().toLowerCase() === 'a' ?
-          UI.XLink.create(rewrittenHref, value, '', true /* preventClick */) :
-          Components.Linkifier.linkifyURL(rewrittenHref, {text: value, preventClick: true});
-      link[Elements.ElementsTreeElement.HrefSymbol] = rewrittenHref;
-      return link;
-    }
-
-    const nodeName = node ? node.nodeName().toLowerCase() : '';
-    if (nodeName && (name === 'src' || name === 'href'))
-      attrValueElement.appendChild(linkifyValue.call(this, value));
-    else if ((nodeName === 'img' || nodeName === 'source') && name === 'srcset')
-      attrValueElement.appendChild(linkifySrcset.call(this, value));
-    else
-      setValueWithEntities.call(this, attrValueElement, value);
-
-    if (hasText)
-      attrSpanElement.createTextChild('"');
-
-    /**
-     * @param {string} value
-     * @return {!DocumentFragment}
-     * @this {!Elements.ElementsTreeElement}
-     */
-    function linkifySrcset(value) {
-      // Splitting normally on commas or spaces will break on valid srcsets "foo 1x,bar 2x" and "data:,foo 1x".
-      // 1) Let the index of the next space be `indexOfSpace`.
-      // 2a) If the character at `indexOfSpace - 1` is a comma, collect the preceding characters up to
-      //     `indexOfSpace - 1` as a URL and repeat step 1).
-      // 2b) Else, collect the preceding characters as a URL.
-      // 3) Collect the characters from `indexOfSpace` up to the next comma as the size descriptor and repeat step 1).
-      // https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute
-      const fragment = createDocumentFragment();
-      let i = 0;
-      while (value.length) {
-        if (i++ > 0)
-          fragment.createTextChild(' ');
-        value = value.trim();
-        // The url and descriptor may end with a separating comma.
-        let url = '';
-        let descriptor = '';
-        const indexOfSpace = value.search(/\s/);
-        if (indexOfSpace === -1) {
-          url = value;
-        } else if (indexOfSpace > 0 && value[indexOfSpace - 1] === ',') {
-          url = value.substring(0, indexOfSpace);
-        } else {
-          url = value.substring(0, indexOfSpace);
-          const indexOfComma = value.indexOf(',', indexOfSpace);
-          if (indexOfComma !== -1)
-            descriptor = value.substring(indexOfSpace, indexOfComma + 1);
-          else
-            descriptor = value.substring(indexOfSpace);
-        }
-
-        if (url) {
-          // Up to one trailing comma should be removed from `url`.
-          if (url.endsWith(',')) {
-            fragment.appendChild(linkifyValue.call(this, url.substring(0, url.length - 1)));
-            fragment.createTextChild(',');
-          } else {
-            fragment.appendChild(linkifyValue.call(this, url));
-          }
-        }
-        if (descriptor)
-          fragment.createTextChild(descriptor);
-        value = value.substring(url.length + descriptor.length);
-      }
-      return fragment;
-    }
-  }
-
-  /**
-   * @param {!Node} parentElement
-   * @param {string} pseudoElementName
-   */
-  _buildPseudoElementDOM(parentElement, pseudoElementName) {
-    const pseudoElement = parentElement.createChild('span', 'webkit-html-pseudo-element');
-    pseudoElement.textContent = '::' + pseudoElementName;
-    parentElement.createTextChild('\u200B');
-  }
-
-  /**
-   * @param {!Node} parentElement
-   * @param {string} tagName
-   * @param {boolean} isClosingTag
-   * @param {boolean} isDistinctTreeElement
-   * @param {?Elements.ElementsTreeOutline.UpdateRecord} updateRecord
-   */
-  _buildTagDOM(parentElement, tagName, isClosingTag, isDistinctTreeElement, updateRecord) {
-    const node = this._node;
-    const classes = ['webkit-html-tag'];
-    if (isClosingTag && isDistinctTreeElement)
-      classes.push('close');
-    const tagElement = parentElement.createChild('span', classes.join(' '));
-    tagElement.createTextChild('<');
-    const tagNameElement =
-        tagElement.createChild('span', isClosingTag ? 'webkit-html-close-tag-name' : 'webkit-html-tag-name');
-    tagNameElement.textContent = (isClosingTag ? '/' : '') + tagName;
-    if (!isClosingTag) {
-      if (node.hasAttributes()) {
-        const attributes = node.attributes();
-        for (let i = 0; i < attributes.length; ++i) {
-          const attr = attributes[i];
-          tagElement.createTextChild(' ');
-          this._buildAttributeDOM(tagElement, attr.name, attr.value, updateRecord, false, node);
-        }
-      }
-      if (updateRecord) {
-        let hasUpdates = updateRecord.hasRemovedAttributes() || updateRecord.hasRemovedChildren();
-        hasUpdates |= !this.expanded && updateRecord.hasChangedChildren();
-        if (hasUpdates)
-          UI.runCSSAnimationOnce(tagNameElement, 'dom-update-highlight');
-      }
-    }
-
-    tagElement.createTextChild('>');
-    parentElement.createTextChild('\u200B');
-  }
-
-  /**
-   * @param {string} text
-   * @return {!{text: string, entityRanges: !Array.<!TextUtils.SourceRange>}}
-   */
-  _convertWhitespaceToEntities(text) {
-    let result = '';
-    let lastIndexAfterEntity = 0;
-    const entityRanges = [];
-    const charToEntity = Elements.ElementsTreeOutline.MappedCharToEntity;
-    for (let i = 0, size = text.length; i < size; ++i) {
-      const char = text.charAt(i);
-      if (charToEntity[char]) {
-        result += text.substring(lastIndexAfterEntity, i);
-        const entityValue = '&' + charToEntity[char] + ';';
-        entityRanges.push({offset: result.length, length: entityValue.length});
-        result += entityValue;
-        lastIndexAfterEntity = i + 1;
-      }
-    }
-    if (result)
-      result += text.substring(lastIndexAfterEntity);
-    return {text: result || text, entityRanges: entityRanges};
-  }
-
-  /**
-   * @param {?Elements.ElementsTreeOutline.UpdateRecord} updateRecord
-   * @return {!DocumentFragment} result
-   */
-  _nodeTitleInfo(updateRecord) {
-    const node = this._node;
-    const titleDOM = createDocumentFragment();
-
-    switch (node.nodeType()) {
-      case Node.ATTRIBUTE_NODE:
-        this._buildAttributeDOM(
-            titleDOM, /** @type {string} */ (node.name), /** @type {string} */ (node.value), updateRecord, true);
-        break;
-
-      case Node.ELEMENT_NODE:
-        const pseudoType = node.pseudoType();
-        if (pseudoType) {
-          this._buildPseudoElementDOM(titleDOM, pseudoType);
-          break;
-        }
-
-        const tagName = node.nodeNameInCorrectCase();
-        if (this._elementCloseTag) {
-          this._buildTagDOM(titleDOM, tagName, true, true, updateRecord);
-          break;
-        }
-
-        this._buildTagDOM(titleDOM, tagName, false, false, updateRecord);
-
-        if (this.isExpandable()) {
-          if (!this.expanded) {
-            const textNodeElement = titleDOM.createChild('span', 'webkit-html-text-node bogus');
-            textNodeElement.textContent = '\u2026';
-            titleDOM.createTextChild('\u200B');
-            this._buildTagDOM(titleDOM, tagName, true, false, updateRecord);
-          }
-          break;
-        }
-
-        if (Elements.ElementsTreeElement.canShowInlineText(node)) {
-          const textNodeElement = titleDOM.createChild('span', 'webkit-html-text-node');
-          const result = this._convertWhitespaceToEntities(node.firstChild.nodeValue());
-          textNodeElement.textContent = result.text;
-          UI.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, 'webkit-html-entity-value');
-          titleDOM.createTextChild('\u200B');
-          this._buildTagDOM(titleDOM, tagName, true, false, updateRecord);
-          if (updateRecord && updateRecord.hasChangedChildren())
-            UI.runCSSAnimationOnce(textNodeElement, 'dom-update-highlight');
-          if (updateRecord && updateRecord.isCharDataModified())
-            UI.runCSSAnimationOnce(textNodeElement, 'dom-update-highlight');
-          break;
-        }
-
-        if (this.treeOutline.isXMLMimeType || !Elements.ElementsTreeElement.ForbiddenClosingTagElements.has(tagName))
-          this._buildTagDOM(titleDOM, tagName, true, false, updateRecord);
-        break;
-
-      case Node.TEXT_NODE:
-        if (node.parentNode && node.parentNode.nodeName().toLowerCase() === 'script') {
-          const newNode = titleDOM.createChild('span', 'webkit-html-text-node webkit-html-js-node');
-          const text = node.nodeValue();
-          newNode.textContent = text.startsWith('\n') ? text.substring(1) : text;
-
-          const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter('text/javascript', true);
-          javascriptSyntaxHighlighter.syntaxHighlightNode(newNode).then(updateSearchHighlight.bind(this));
-        } else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === 'style') {
-          const newNode = titleDOM.createChild('span', 'webkit-html-text-node webkit-html-css-node');
-          const text = node.nodeValue();
-          newNode.textContent = text.startsWith('\n') ? text.substring(1) : text;
-
-          const cssSyntaxHighlighter = new UI.SyntaxHighlighter('text/css', true);
-          cssSyntaxHighlighter.syntaxHighlightNode(newNode).then(updateSearchHighlight.bind(this));
-        } else {
-          titleDOM.createTextChild('"');
-          const textNodeElement = titleDOM.createChild('span', 'webkit-html-text-node');
-          const result = this._convertWhitespaceToEntities(node.nodeValue());
-          textNodeElement.textContent = result.text;
-          UI.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, 'webkit-html-entity-value');
-          titleDOM.createTextChild('"');
-          if (updateRecord && updateRecord.isCharDataModified())
-            UI.runCSSAnimationOnce(textNodeElement, 'dom-update-highlight');
-        }
-        break;
-
-      case Node.COMMENT_NODE:
-        const commentElement = titleDOM.createChild('span', 'webkit-html-comment');
-        commentElement.createTextChild('<!--' + node.nodeValue() + '-->');
-        break;
-
-      case Node.DOCUMENT_TYPE_NODE:
-        const docTypeElement = titleDOM.createChild('span', 'webkit-html-doctype');
-        docTypeElement.createTextChild('<!doctype ' + node.nodeName());
-        if (node.publicId) {
-          docTypeElement.createTextChild(' PUBLIC "' + node.publicId + '"');
-          if (node.systemId)
-            docTypeElement.createTextChild(' "' + node.systemId + '"');
-        } else if (node.systemId) {
-          docTypeElement.createTextChild(' SYSTEM "' + node.systemId + '"');
-        }
-
-        if (node.internalSubset)
-          docTypeElement.createTextChild(' [' + node.internalSubset + ']');
-
-        docTypeElement.createTextChild('>');
-        break;
-
-      case Node.CDATA_SECTION_NODE:
-        const cdataElement = titleDOM.createChild('span', 'webkit-html-text-node');
-        cdataElement.createTextChild('<![CDATA[' + node.nodeValue() + ']]>');
-        break;
-
-      case Node.DOCUMENT_FRAGMENT_NODE:
-        const fragmentElement = titleDOM.createChild('span', 'webkit-html-fragment');
-        fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
-        break;
-      default:
-        titleDOM.createTextChild(node.nodeNameInCorrectCase().collapseWhitespace());
-    }
-
-    /**
-     * @this {Elements.ElementsTreeElement}
-     */
-    function updateSearchHighlight() {
-      delete this._highlightResult;
-      this._highlightSearchResults();
-    }
-
-    return titleDOM;
-  }
-
-  remove() {
-    if (this._node.pseudoType())
-      return;
-    const parentElement = this.parent;
-    if (!parentElement)
-      return;
-
-    if (!this._node.parentNode || this._node.parentNode.nodeType() === Node.DOCUMENT_NODE)
-      return;
-    this._node.removeNode();
-  }
-
-  /**
-   * @param {function(boolean)=} callback
-   * @param {boolean=} startEditing
-   */
-  toggleEditAsHTML(callback, startEditing) {
-    if (this._editing && this._htmlEditElement) {
-      this._editing.commit();
-      return;
-    }
-
-    if (startEditing === false)
-      return;
-
-    /**
-     * @param {?Protocol.Error} error
-     */
-    function selectNode(error) {
-      if (callback)
-        callback(!error);
-    }
-
-    /**
-     * @param {string} initialValue
-     * @param {string} value
-     */
-    function commitChange(initialValue, value) {
-      if (initialValue !== value)
-        node.setOuterHTML(value, selectNode);
-    }
-
-    function disposeCallback() {
-      if (callback)
-        callback(false);
-    }
-
-    const node = this._node;
-    node.getOuterHTML().then(this._startEditingAsHTML.bind(this, commitChange, disposeCallback));
-  }
-
-  _copyCSSPath() {
-    InspectorFrontendHost.copyText(Elements.DOMPath.cssPath(this._node, true));
-  }
-
-  _copyXPath() {
-    InspectorFrontendHost.copyText(Elements.DOMPath.xPath(this._node, true));
-  }
-
-  _highlightSearchResults() {
-    if (!this._searchQuery || !this._searchHighlightsVisible)
-      return;
-    this._hideSearchHighlight();
-
-    const text = this.listItemElement.textContent;
-    const regexObject = createPlainTextSearchRegex(this._searchQuery, 'gi');
-
-    let match = regexObject.exec(text);
-    const matchRanges = [];
-    while (match) {
-      matchRanges.push(new TextUtils.SourceRange(match.index, match[0].length));
-      match = regexObject.exec(text);
-    }
-
-    // Fall back for XPath, etc. matches.
-    if (!matchRanges.length)
-      matchRanges.push(new TextUtils.SourceRange(0, text.length));
-
-    this._highlightResult = [];
-    UI.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult);
-  }
-
-  _editAsHTML() {
-    const promise = Common.Revealer.reveal(this.node());
-    promise.then(() => UI.actionRegistry.action('elements.edit-as-html').execute());
-  }
-};
-
-Elements.ElementsTreeElement.HrefSymbol = Symbol('ElementsTreeElement.Href');
-
-Elements.ElementsTreeElement.InitialChildrenLimit = 500;
-
-// A union of HTML4 and HTML5-Draft elements that explicitly
-// or implicitly (for HTML5) forbid the closing tag.
-Elements.ElementsTreeElement.ForbiddenClosingTagElements = new Set([
-  'area', 'base',  'basefont', 'br',   'canvas',   'col',  'command', 'embed',  'frame', 'hr',
-  'img',  'input', 'keygen',   'link', 'menuitem', 'meta', 'param',   'source', 'track', 'wbr'
-]);
-
-// These tags we do not allow editing their tag name.
-Elements.ElementsTreeElement.EditTagBlacklist = new Set(['html', 'head', 'body']);
-
-/** @typedef {{cancel: function(), commit: function(), resize: function(), editor:!UI.TextEditor}} */
-Elements.MultilineEditorController;
diff --git a/front_end/elements/ElementsTreeElementHighlighter.js b/front_end/elements/ElementsTreeElementHighlighter.js
deleted file mode 100644
index ab4d25d..0000000
--- a/front_end/elements/ElementsTreeElementHighlighter.js
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Elements.ElementsTreeElementHighlighter = class {
-  /**
-   * @param {!Elements.ElementsTreeOutline} treeOutline
-   */
-  constructor(treeOutline) {
-    this._throttler = new Common.Throttler(100);
-    this._treeOutline = treeOutline;
-    this._treeOutline.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._clearState, this);
-    this._treeOutline.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._clearState, this);
-    this._treeOutline.addEventListener(Elements.ElementsTreeOutline.Events.SelectedNodeChanged, this._clearState, this);
-    SDK.targetManager.addModelListener(
-        SDK.OverlayModel, SDK.OverlayModel.Events.HighlightNodeRequested, this._highlightNode, this);
-    SDK.targetManager.addModelListener(
-        SDK.OverlayModel, SDK.OverlayModel.Events.InspectModeWillBeToggled, this._clearState, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _highlightNode(event) {
-    if (!Common.moduleSetting('highlightNodeOnHoverInOverlay').get())
-      return;
-
-    const domNode = /** @type {!SDK.DOMNode} */ (event.data);
-
-    this._throttler.schedule(callback.bind(this));
-    this._pendingHighlightNode =
-        this._treeOutline === Elements.ElementsTreeOutline.forDOMModel(domNode.domModel()) ? domNode : null;
-
-    /**
-     * @this {Elements.ElementsTreeElementHighlighter}
-     */
-    function callback() {
-      this._highlightNodeInternal(this._pendingHighlightNode);
-      delete this._pendingHighlightNode;
-      return Promise.resolve();
-    }
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  _highlightNodeInternal(node) {
-    this._isModifyingTreeOutline = true;
-    let treeElement = null;
-
-    if (this._currentHighlightedElement) {
-      let currentTreeElement = this._currentHighlightedElement;
-      while (currentTreeElement !== this._alreadyExpandedParentElement) {
-        if (currentTreeElement.expanded)
-          currentTreeElement.collapse();
-
-        currentTreeElement = currentTreeElement.parent;
-      }
-    }
-
-    delete this._currentHighlightedElement;
-    delete this._alreadyExpandedParentElement;
-    if (node) {
-      let deepestExpandedParent = node;
-      const treeElementSymbol = this._treeOutline.treeElementSymbol();
-      while (deepestExpandedParent &&
-             (!deepestExpandedParent[treeElementSymbol] || !deepestExpandedParent[treeElementSymbol].expanded))
-        deepestExpandedParent = deepestExpandedParent.parentNode;
-
-      this._alreadyExpandedParentElement =
-          deepestExpandedParent ? deepestExpandedParent[treeElementSymbol] : this._treeOutline.rootElement();
-      treeElement = this._treeOutline.createTreeElementFor(node);
-    }
-
-    this._currentHighlightedElement = treeElement;
-    this._treeOutline.setHoverEffect(treeElement);
-    if (treeElement)
-      treeElement.reveal(true);
-
-    this._isModifyingTreeOutline = false;
-  }
-
-  _clearState() {
-    if (this._isModifyingTreeOutline)
-      return;
-
-    delete this._currentHighlightedElement;
-    delete this._alreadyExpandedParentElement;
-    delete this._pendingHighlightNode;
-  }
-};
diff --git a/front_end/elements/ElementsTreeOutline.js b/front_end/elements/ElementsTreeOutline.js
deleted file mode 100644
index cc0bd89..0000000
--- a/front_end/elements/ElementsTreeOutline.js
+++ /dev/null
@@ -1,1667 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Elements.ElementsTreeOutline = class extends UI.TreeOutline {
-  /**
-   * @param {boolean=} omitRootDOMNode
-   * @param {boolean=} selectEnabled
-   */
-  constructor(omitRootDOMNode, selectEnabled) {
-    super();
-
-    this._treeElementSymbol = Symbol('treeElement');
-    const shadowContainer = createElement('div');
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(shadowContainer, 'elements/elementsTreeOutline.css');
-    const outlineDisclosureElement = this._shadowRoot.createChild('div', 'elements-disclosure');
-
-    this._element = this.element;
-    this._element.classList.add('elements-tree-outline', 'source-code');
-    UI.ARIAUtils.setAccessibleName(this._element, Common.UIString('Page DOM'));
-    this._element.addEventListener('mousedown', this._onmousedown.bind(this), false);
-    this._element.addEventListener('mousemove', this._onmousemove.bind(this), false);
-    this._element.addEventListener('mouseleave', this._onmouseleave.bind(this), false);
-    this._element.addEventListener('dragstart', this._ondragstart.bind(this), false);
-    this._element.addEventListener('dragover', this._ondragover.bind(this), false);
-    this._element.addEventListener('dragleave', this._ondragleave.bind(this), false);
-    this._element.addEventListener('drop', this._ondrop.bind(this), false);
-    this._element.addEventListener('dragend', this._ondragend.bind(this), false);
-    this._element.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), false);
-    this._element.addEventListener('clipboard-beforecopy', this._onBeforeCopy.bind(this), false);
-    this._element.addEventListener('clipboard-copy', this._onCopyOrCut.bind(this, false), false);
-    this._element.addEventListener('clipboard-cut', this._onCopyOrCut.bind(this, true), false);
-    this._element.addEventListener('clipboard-paste', this._onPaste.bind(this), false);
-
-    outlineDisclosureElement.appendChild(this._element);
-    this.element = shadowContainer;
-
-    this._includeRootDOMNode = !omitRootDOMNode;
-    this._selectEnabled = selectEnabled;
-    /** @type {?SDK.DOMNode} */
-    this._rootDOMNode = null;
-    /** @type {?SDK.DOMNode} */
-    this._selectedDOMNode = null;
-
-    this._visible = false;
-
-    this._popoverHelper = new UI.PopoverHelper(this._element, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setHasPadding(true);
-    this._popoverHelper.setTimeout(0, 100);
-
-    /** @type {!Map<!SDK.DOMNode, !Elements.ElementsTreeOutline.UpdateRecord>} */
-    this._updateRecords = new Map();
-    /** @type {!Set<!Elements.ElementsTreeElement>} */
-    this._treeElementsBeingUpdated = new Set();
-
-    this._showHTMLCommentsSetting = Common.moduleSetting('showHTMLComments');
-    this._showHTMLCommentsSetting.addChangeListener(this._onShowHTMLCommentsChange.bind(this));
-  }
-
-  /**
-   * @param {!SDK.DOMModel} domModel
-   * @return {?Elements.ElementsTreeOutline}
-   */
-  static forDOMModel(domModel) {
-    return domModel[Elements.ElementsTreeOutline._treeOutlineSymbol] || null;
-  }
-
-  _onShowHTMLCommentsChange() {
-    const selectedNode = this.selectedDOMNode();
-    if (selectedNode && selectedNode.nodeType() === Node.COMMENT_NODE && !this._showHTMLCommentsSetting.get())
-      this.selectDOMNode(selectedNode.parentNode);
-    this.update();
-  }
-
-  /**
-   * @return {symbol}
-   */
-  treeElementSymbol() {
-    return this._treeElementSymbol;
-  }
-
-
-  /**
-   * @param {boolean} wrap
-   */
-  setWordWrap(wrap) {
-    this._element.classList.toggle('elements-tree-nowrap', !wrap);
-  }
-
-  /**
-   * @param {?Elements.MultilineEditorController} multilineEditing
-   */
-  setMultilineEditing(multilineEditing) {
-    this._multilineEditing = multilineEditing;
-  }
-
-  /**
-   * @return {number}
-   */
-  visibleWidth() {
-    return this._visibleWidth;
-  }
-
-  /**
-   * @param {number} width
-   */
-  setVisibleWidth(width) {
-    this._visibleWidth = width;
-    if (this._multilineEditing)
-      this._multilineEditing.resize();
-  }
-
-  /**
-   * @param {?Elements.ElementsTreeOutline.ClipboardData} data
-   */
-  _setClipboardData(data) {
-    if (this._clipboardNodeData) {
-      const treeElement = this.findTreeElement(this._clipboardNodeData.node);
-      if (treeElement)
-        treeElement.setInClipboard(false);
-      delete this._clipboardNodeData;
-    }
-
-    if (data) {
-      const treeElement = this.findTreeElement(data.node);
-      if (treeElement)
-        treeElement.setInClipboard(true);
-      this._clipboardNodeData = data;
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMNode} removedNode
-   */
-  resetClipboardIfNeeded(removedNode) {
-    if (this._clipboardNodeData && this._clipboardNodeData.node === removedNode)
-      this._setClipboardData(null);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onBeforeCopy(event) {
-    event.handled = true;
-  }
-
-  /**
-   * @param {boolean} isCut
-   * @param {!Event} event
-   */
-  _onCopyOrCut(isCut, event) {
-    this._setClipboardData(null);
-    const originalEvent = event['original'];
-
-    // Don't prevent the normal copy if the user has a selection.
-    if (originalEvent.target.hasSelection())
-      return;
-
-    // Do not interfere with text editing.
-    if (UI.isEditing())
-      return;
-
-    const targetNode = this.selectedDOMNode();
-    if (!targetNode)
-      return;
-
-    originalEvent.clipboardData.clearData();
-    event.handled = true;
-
-    this.performCopyOrCut(isCut, targetNode);
-  }
-
-  /**
-   * @param {boolean} isCut
-   * @param {?SDK.DOMNode} node
-   */
-  performCopyOrCut(isCut, node) {
-    if (isCut && (node.isShadowRoot() || node.ancestorUserAgentShadowRoot()))
-      return;
-
-    node.copyNode();
-    this._setClipboardData({node: node, isCut: isCut});
-  }
-
-  /**
-   * @param {!SDK.DOMNode} targetNode
-   * @return {boolean}
-   */
-  canPaste(targetNode) {
-    if (targetNode.isShadowRoot() || targetNode.ancestorUserAgentShadowRoot())
-      return false;
-
-    if (!this._clipboardNodeData)
-      return false;
-
-    const node = this._clipboardNodeData.node;
-    if (this._clipboardNodeData.isCut && (node === targetNode || node.isAncestor(targetNode)))
-      return false;
-
-    if (targetNode.domModel() !== node.domModel())
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} targetNode
-   */
-  pasteNode(targetNode) {
-    if (this.canPaste(targetNode))
-      this._performPaste(targetNode);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onPaste(event) {
-    // Do not interfere with text editing.
-    if (UI.isEditing())
-      return;
-
-    const targetNode = this.selectedDOMNode();
-    if (!targetNode || !this.canPaste(targetNode))
-      return;
-
-    event.handled = true;
-    this._performPaste(targetNode);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} targetNode
-   */
-  _performPaste(targetNode) {
-    if (this._clipboardNodeData.isCut) {
-      this._clipboardNodeData.node.moveTo(targetNode, null, expandCallback.bind(this));
-      this._setClipboardData(null);
-    } else {
-      this._clipboardNodeData.node.copyTo(targetNode, null, expandCallback.bind(this));
-    }
-
-    /**
-     * @param {?Protocol.Error} error
-     * @param {!Protocol.DOM.NodeId} nodeId
-     * @this {Elements.ElementsTreeOutline}
-     */
-    function expandCallback(error, nodeId) {
-      if (error)
-        return;
-      const pastedNode = targetNode.domModel().nodeForId(nodeId);
-      if (!pastedNode)
-        return;
-      this.selectDOMNode(pastedNode);
-    }
-  }
-
-  /**
-   * @param {boolean} visible
-   */
-  setVisible(visible) {
-    this._visible = visible;
-    if (!this._visible) {
-      this._popoverHelper.hidePopover();
-      if (this._multilineEditing)
-        this._multilineEditing.cancel();
-      return;
-    }
-
-    this.runPendingUpdates();
-    if (this._selectedDOMNode)
-      this._revealAndSelectNode(this._selectedDOMNode, false);
-  }
-
-  get rootDOMNode() {
-    return this._rootDOMNode;
-  }
-
-  set rootDOMNode(x) {
-    if (this._rootDOMNode === x)
-      return;
-
-    this._rootDOMNode = x;
-
-    this._isXMLMimeType = x && x.isXMLNode();
-
-    this.update();
-  }
-
-  get isXMLMimeType() {
-    return this._isXMLMimeType;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  selectedDOMNode() {
-    return this._selectedDOMNode;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   * @param {boolean=} focus
-   */
-  selectDOMNode(node, focus) {
-    if (this._selectedDOMNode === node) {
-      this._revealAndSelectNode(node, !focus);
-      return;
-    }
-
-    this._selectedDOMNode = node;
-    this._revealAndSelectNode(node, !focus);
-
-    // The _revealAndSelectNode() method might find a different element if there is inlined text,
-    // and the select() call would change the selectedDOMNode and reenter this setter. So to
-    // avoid calling _selectedNodeChanged() twice, first check if _selectedDOMNode is the same
-    // node as the one passed in.
-    if (this._selectedDOMNode === node)
-      this._selectedNodeChanged(!!focus);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  editing() {
-    const node = this.selectedDOMNode();
-    if (!node)
-      return false;
-    const treeElement = this.findTreeElement(node);
-    if (!treeElement)
-      return false;
-    return treeElement.isEditing() || false;
-  }
-
-  update() {
-    const selectedNode = this.selectedDOMNode();
-    this.removeChildren();
-    if (!this.rootDOMNode)
-      return;
-
-    if (this._includeRootDOMNode) {
-      const treeElement = this._createElementTreeElement(this.rootDOMNode);
-      this.appendChild(treeElement);
-    } else {
-      // FIXME: this could use findTreeElement to reuse a tree element if it already exists
-      const children = this._visibleChildren(this.rootDOMNode);
-      for (const child of children) {
-        const treeElement = this._createElementTreeElement(child);
-        this.appendChild(treeElement);
-      }
-    }
-
-    if (selectedNode)
-      this._revealAndSelectNode(selectedNode, true);
-  }
-
-  /**
-   * @param {boolean} focus
-   */
-  _selectedNodeChanged(focus) {
-    this.dispatchEventToListeners(
-        Elements.ElementsTreeOutline.Events.SelectedNodeChanged, {node: this._selectedDOMNode, focus: focus});
-  }
-
-  /**
-   * @param {!Array.<!SDK.DOMNode>} nodes
-   */
-  _fireElementsTreeUpdated(nodes) {
-    this.dispatchEventToListeners(Elements.ElementsTreeOutline.Events.ElementsTreeUpdated, nodes);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {?Elements.ElementsTreeElement}
-   */
-  findTreeElement(node) {
-    let treeElement = this._lookUpTreeElement(node);
-    if (!treeElement && node.nodeType() === Node.TEXT_NODE) {
-      // The text node might have been inlined if it was short, so try to find the parent element.
-      treeElement = this._lookUpTreeElement(node.parentNode);
-    }
-
-    return /** @type {?Elements.ElementsTreeElement} */ (treeElement);
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   * @return {?UI.TreeElement}
-   */
-  _lookUpTreeElement(node) {
-    if (!node)
-      return null;
-
-    const cachedElement = node[this._treeElementSymbol];
-    if (cachedElement)
-      return cachedElement;
-
-    // Walk up the parent pointers from the desired node
-    const ancestors = [];
-    let currentNode;
-    for (currentNode = node.parentNode; currentNode; currentNode = currentNode.parentNode) {
-      ancestors.push(currentNode);
-      if (currentNode[this._treeElementSymbol])  // stop climbing as soon as we hit
-        break;
-    }
-
-    if (!currentNode)
-      return null;
-
-    // Walk down to populate each ancestor's children, to fill in the tree and the cache.
-    for (let i = ancestors.length - 1; i >= 0; --i) {
-      const treeElement = ancestors[i][this._treeElementSymbol];
-      if (treeElement)
-        treeElement.onpopulate();  // fill the cache with the children of treeElement
-    }
-
-    return node[this._treeElementSymbol];
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {?Elements.ElementsTreeElement}
-   */
-  createTreeElementFor(node) {
-    let treeElement = this.findTreeElement(node);
-    if (treeElement)
-      return treeElement;
-    if (!node.parentNode)
-      return null;
-
-    treeElement = this.createTreeElementFor(node.parentNode);
-    return treeElement ? this._showChild(treeElement, node) : null;
-  }
-
-  set suppressRevealAndSelect(x) {
-    if (this._suppressRevealAndSelect === x)
-      return;
-    this._suppressRevealAndSelect = x;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   * @param {boolean} omitFocus
-   */
-  _revealAndSelectNode(node, omitFocus) {
-    if (this._suppressRevealAndSelect)
-      return;
-
-    if (!this._includeRootDOMNode && node === this.rootDOMNode && this.rootDOMNode)
-      node = this.rootDOMNode.firstChild;
-    if (!node)
-      return;
-    const treeElement = this.createTreeElementFor(node);
-    if (!treeElement)
-      return;
-
-    treeElement.revealAndSelect(omitFocus);
-  }
-
-  /**
-   * @return {?UI.TreeElement}
-   */
-  _treeElementFromEvent(event) {
-    const scrollContainer = this.element.parentElement;
-
-    // We choose this X coordinate based on the knowledge that our list
-    // items extend at least to the right edge of the outer <ol> container.
-    // In the no-word-wrap mode the outer <ol> may be wider than the tree container
-    // (and partially hidden), in which case we are left to use only its right boundary.
-    const x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36;
-
-    const y = event.pageY;
-
-    // Our list items have 1-pixel cracks between them vertically. We avoid
-    // the cracks by checking slightly above and slightly below the mouse
-    // and seeing if we hit the same element each time.
-    const elementUnderMouse = this.treeElementFromPoint(x, y);
-    const elementAboveMouse = this.treeElementFromPoint(x, y - 2);
-    let element;
-    if (elementUnderMouse === elementAboveMouse)
-      element = elementUnderMouse;
-    else
-      element = this.treeElementFromPoint(x, y + 2);
-
-    return element;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    let link = event.target;
-    while (link && !link[Elements.ElementsTreeElement.HrefSymbol])
-      link = link.parentElementOrShadowHost();
-    if (!link)
-      return null;
-
-    return {
-      box: link.boxInWindow(),
-      show: async popover => {
-        const listItem = link.enclosingNodeOrSelfWithNodeName('li');
-        const node = /** @type {!Elements.ElementsTreeElement} */ (listItem.treeElement).node();
-        const precomputedFeatures = await this._loadDimensionsForNode(node);
-        const preview = await BrowserComponents.ImagePreview.build(
-            node.domModel().target(), link[Elements.ElementsTreeElement.HrefSymbol], true, precomputedFeatures);
-        if (preview)
-          popover.contentElement.appendChild(preview);
-        return !!preview;
-      }
-    };
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise<!Object|undefined>}
-   */
-  async _loadDimensionsForNode(node) {
-    if (!node.nodeName() || node.nodeName().toLowerCase() !== 'img')
-      return;
-
-    const object = await node.resolveToObject('');
-
-    if (!object)
-      return;
-
-    const promise = object.callFunctionJSONPromise(features, undefined);
-    object.release();
-    return promise;
-
-    /**
-     * @return {!{offsetWidth: number, offsetHeight: number, naturalWidth: number, naturalHeight: number, currentSrc: (string|undefined)}}
-     * @suppressReceiverCheck
-     * @this {!Element}
-     */
-    function features() {
-      return {
-        offsetWidth: this.offsetWidth,
-        offsetHeight: this.offsetHeight,
-        naturalWidth: this.naturalWidth,
-        naturalHeight: this.naturalHeight,
-        currentSrc: this.currentSrc
-      };
-    }
-  }
-
-  _onmousedown(event) {
-    const element = this._treeElementFromEvent(event);
-
-    if (!element || element.isEventWithinDisclosureTriangle(event))
-      return;
-
-    element.select();
-  }
-
-  /**
-   * @param {?UI.TreeElement} treeElement
-   */
-  setHoverEffect(treeElement) {
-    if (this._previousHoveredElement === treeElement)
-      return;
-
-    if (this._previousHoveredElement) {
-      this._previousHoveredElement.hovered = false;
-      delete this._previousHoveredElement;
-    }
-
-    if (treeElement) {
-      treeElement.hovered = true;
-      this._previousHoveredElement = treeElement;
-    }
-  }
-
-  _onmousemove(event) {
-    const element = this._treeElementFromEvent(event);
-    if (element && this._previousHoveredElement === element)
-      return;
-
-    this.setHoverEffect(element);
-
-    if (element instanceof Elements.ElementsTreeElement) {
-      element.node().domModel().overlayModel().highlightDOMNodeWithConfig(
-          element.node().id, {mode: 'all', showInfo: !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)});
-      return;
-    }
-
-    if (element instanceof Elements.ElementsTreeOutline.ShortcutTreeElement) {
-      element.domModel().overlayModel().highlightDOMNodeWithConfig(
-          undefined, {mode: 'all', showInfo: !UI.KeyboardShortcut.eventHasCtrlOrMeta(event)}, element.backendNodeId());
-    }
-  }
-
-  _onmouseleave(event) {
-    this.setHoverEffect(null);
-    SDK.OverlayModel.hideDOMNodeHighlight();
-  }
-
-  _ondragstart(event) {
-    if (event.target.hasSelection())
-      return false;
-    if (event.target.nodeName === 'A')
-      return false;
-
-    const treeElement = this._validDragSourceOrTarget(this._treeElementFromEvent(event));
-    if (!treeElement)
-      return false;
-
-    if (treeElement.node().nodeName() === 'BODY' || treeElement.node().nodeName() === 'HEAD')
-      return false;
-
-    event.dataTransfer.setData('text/plain', treeElement.listItemElement.textContent.replace(/\u200b/g, ''));
-    event.dataTransfer.effectAllowed = 'copyMove';
-    this._treeElementBeingDragged = treeElement;
-
-    SDK.OverlayModel.hideDOMNodeHighlight();
-
-    return true;
-  }
-
-  _ondragover(event) {
-    if (!this._treeElementBeingDragged)
-      return false;
-
-    const treeElement = this._validDragSourceOrTarget(this._treeElementFromEvent(event));
-    if (!treeElement)
-      return false;
-
-    let node = treeElement.node();
-    while (node) {
-      if (node === this._treeElementBeingDragged._node)
-        return false;
-      node = node.parentNode;
-    }
-
-    treeElement.listItemElement.classList.add('elements-drag-over');
-    this._dragOverTreeElement = treeElement;
-    event.preventDefault();
-    event.dataTransfer.dropEffect = 'move';
-    return false;
-  }
-
-  _ondragleave(event) {
-    this._clearDragOverTreeElementMarker();
-    event.preventDefault();
-    return false;
-  }
-
-  /**
-   * @param {?UI.TreeElement} treeElement
-   * @return {?Elements.ElementsTreeElement}
-   */
-  _validDragSourceOrTarget(treeElement) {
-    if (!treeElement)
-      return null;
-
-    if (!(treeElement instanceof Elements.ElementsTreeElement))
-      return null;
-    const elementsTreeElement = /** @type {!Elements.ElementsTreeElement} */ (treeElement);
-
-    const node = elementsTreeElement.node();
-    if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
-      return null;
-
-    return elementsTreeElement;
-  }
-
-  _ondrop(event) {
-    event.preventDefault();
-    const treeElement = this._treeElementFromEvent(event);
-    if (treeElement instanceof Elements.ElementsTreeElement)
-      this._doMove(treeElement);
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   */
-  _doMove(treeElement) {
-    if (!this._treeElementBeingDragged)
-      return;
-
-    let parentNode;
-    let anchorNode;
-
-    if (treeElement.isClosingTag()) {
-      // Drop onto closing tag -> insert as last child.
-      parentNode = treeElement.node();
-    } else {
-      const dragTargetNode = treeElement.node();
-      parentNode = dragTargetNode.parentNode;
-      anchorNode = dragTargetNode;
-    }
-
-    const wasExpanded = this._treeElementBeingDragged.expanded;
-    this._treeElementBeingDragged._node.moveTo(
-        parentNode, anchorNode, this.selectNodeAfterEdit.bind(this, wasExpanded));
-
-    delete this._treeElementBeingDragged;
-  }
-
-  _ondragend(event) {
-    event.preventDefault();
-    this._clearDragOverTreeElementMarker();
-    delete this._treeElementBeingDragged;
-  }
-
-  _clearDragOverTreeElementMarker() {
-    if (this._dragOverTreeElement) {
-      this._dragOverTreeElement.listItemElement.classList.remove('elements-drag-over');
-      delete this._dragOverTreeElement;
-    }
-  }
-
-  _contextMenuEventFired(event) {
-    const treeElement = this._treeElementFromEvent(event);
-    if (treeElement instanceof Elements.ElementsTreeElement)
-      this.showContextMenu(treeElement, event);
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   * @param {!Event} event
-   */
-  showContextMenu(treeElement, event) {
-    if (UI.isEditing())
-      return;
-
-    const contextMenu = new UI.ContextMenu(event);
-    const isPseudoElement = !!treeElement.node().pseudoType();
-    const isTag = treeElement.node().nodeType() === Node.ELEMENT_NODE && !isPseudoElement;
-    let textNode = event.target.enclosingNodeOrSelfWithClass('webkit-html-text-node');
-    if (textNode && textNode.classList.contains('bogus'))
-      textNode = null;
-    const commentNode = event.target.enclosingNodeOrSelfWithClass('webkit-html-comment');
-    if (textNode)
-      treeElement.populateTextContextMenu(contextMenu, textNode);
-    else if (isTag)
-      treeElement.populateTagContextMenu(contextMenu, event);
-    else if (commentNode)
-      treeElement.populateNodeContextMenu(contextMenu);
-    else if (isPseudoElement)
-      treeElement.populateScrollIntoView(contextMenu);
-
-    contextMenu.appendApplicableItems(treeElement.node());
-    contextMenu.show();
-  }
-
-  runPendingUpdates() {
-    this._updateModifiedNodes();
-  }
-
-  handleShortcut(event) {
-    const node = this.selectedDOMNode();
-    if (!node)
-      return;
-    const treeElement = node[this._treeElementSymbol];
-    if (!treeElement)
-      return;
-
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) {
-      if (event.key === 'ArrowUp' && node.previousSibling) {
-        node.moveTo(node.parentNode, node.previousSibling, this.selectNodeAfterEdit.bind(this, treeElement.expanded));
-        event.handled = true;
-        return;
-      }
-      if (event.key === 'ArrowDown' && node.nextSibling) {
-        node.moveTo(
-            node.parentNode, node.nextSibling.nextSibling, this.selectNodeAfterEdit.bind(this, treeElement.expanded));
-        event.handled = true;
-        return;
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {boolean=} startEditing
-   * @param {function()=} callback
-   */
-  toggleEditAsHTML(node, startEditing, callback) {
-    const treeElement = node[this._treeElementSymbol];
-    if (!treeElement || !treeElement.hasEditableNode())
-      return;
-
-    if (node.pseudoType())
-      return;
-
-    const parentNode = node.parentNode;
-    const index = node.index;
-    const wasExpanded = treeElement.expanded;
-
-    treeElement.toggleEditAsHTML(editingFinished.bind(this), startEditing);
-
-    /**
-     * @this {Elements.ElementsTreeOutline}
-     * @param {boolean} success
-     */
-    function editingFinished(success) {
-      if (callback)
-        callback();
-      if (!success)
-        return;
-
-      // Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
-      this.runPendingUpdates();
-
-      const newNode = parentNode ? parentNode.children()[index] || parentNode : null;
-      if (!newNode)
-        return;
-
-      this.selectDOMNode(newNode, true);
-
-      if (wasExpanded) {
-        const newTreeItem = this.findTreeElement(newNode);
-        if (newTreeItem)
-          newTreeItem.expand();
-      }
-    }
-  }
-
-  /**
-   * @param {boolean} wasExpanded
-   * @param {?Protocol.Error} error
-   * @param {?SDK.DOMNode} newNode
-   * @return {?Elements.ElementsTreeElement} nodeId
-   */
-  selectNodeAfterEdit(wasExpanded, error, newNode) {
-    if (error)
-      return null;
-
-    // Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
-    this.runPendingUpdates();
-
-    if (!newNode)
-      return null;
-
-    this.selectDOMNode(newNode, true);
-
-    const newTreeItem = this.findTreeElement(newNode);
-    if (wasExpanded) {
-      if (newTreeItem)
-        newTreeItem.expand();
-    }
-    return newTreeItem;
-  }
-
-  /**
-   * Runs a script on the node's remote object that toggles a class name on
-   * the node and injects a stylesheet into the head of the node's document
-   * containing a rule to set "visibility: hidden" on the class and all it's
-   * ancestors.
-   *
-   * @param {!SDK.DOMNode} node
-   */
-  async toggleHideElement(node) {
-    const pseudoType = node.pseudoType();
-    const effectiveNode = pseudoType ? node.parentNode : node;
-    if (!effectiveNode)
-      return;
-
-    const hidden = node.marker('hidden-marker');
-    const object = await effectiveNode.resolveToObject('');
-
-    if (!object)
-      return;
-
-    const result = object.callFunction(toggleClassAndInjectStyleRule, [{value: pseudoType}, {value: !hidden}]);
-    object.release();
-    node.setMarker('hidden-marker', hidden ? null : true);
-    return result;
-
-    /**
-     * @param {?string} pseudoType
-     * @param {boolean} hidden
-     * @suppressGlobalPropertiesCheck
-     * @suppressReceiverCheck
-     * @this {!Element}
-     */
-    function toggleClassAndInjectStyleRule(pseudoType, hidden) {
-      const classNamePrefix = '__web-inspector-hide';
-      const classNameSuffix = '-shortcut__';
-      const styleTagId = '__web-inspector-hide-shortcut-style__';
-      const selectors = [];
-      selectors.push('.__web-inspector-hide-shortcut__');
-      selectors.push('.__web-inspector-hide-shortcut__ *');
-      selectors.push('.__web-inspector-hidebefore-shortcut__::before');
-      selectors.push('.__web-inspector-hideafter-shortcut__::after');
-      const selector = selectors.join(', ');
-      const ruleBody = '    visibility: hidden !important;';
-      const rule = '\n' + selector + '\n{\n' + ruleBody + '\n}\n';
-      const className = classNamePrefix + (pseudoType || '') + classNameSuffix;
-      this.classList.toggle(className, hidden);
-
-      let localRoot = this;
-      while (localRoot.parentNode)
-        localRoot = localRoot.parentNode;
-      if (localRoot.nodeType === Node.DOCUMENT_NODE)
-        localRoot = document.head;
-
-      let style = localRoot.querySelector('style#' + styleTagId);
-      if (style)
-        return;
-
-      style = document.createElement('style');
-      style.id = styleTagId;
-      style.type = 'text/css';
-      style.textContent = rule;
-
-      localRoot.appendChild(style);
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {boolean}
-   */
-  isToggledToHidden(node) {
-    return !!node.marker('hidden-marker');
-  }
-
-  _reset() {
-    this.rootDOMNode = null;
-    this.selectDOMNode(null, false);
-    this._popoverHelper.hidePopover();
-    delete this._clipboardNodeData;
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    this._updateRecords.clear();
-  }
-
-  /**
-   * @param {!SDK.DOMModel} domModel
-   */
-  wireToDOMModel(domModel) {
-    domModel[Elements.ElementsTreeOutline._treeOutlineSymbol] = this;
-    domModel.addEventListener(SDK.DOMModel.Events.MarkersChanged, this._markersChanged, this);
-    domModel.addEventListener(SDK.DOMModel.Events.NodeInserted, this._nodeInserted, this);
-    domModel.addEventListener(SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
-    domModel.addEventListener(SDK.DOMModel.Events.AttrModified, this._attributeModified, this);
-    domModel.addEventListener(SDK.DOMModel.Events.AttrRemoved, this._attributeRemoved, this);
-    domModel.addEventListener(SDK.DOMModel.Events.CharacterDataModified, this._characterDataModified, this);
-    domModel.addEventListener(SDK.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
-    domModel.addEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
-    domModel.addEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this._distributedNodesChanged, this);
-  }
-
-  /**
-   * @param {!SDK.DOMModel} domModel
-   */
-  unwireFromDOMModel(domModel) {
-    domModel.removeEventListener(SDK.DOMModel.Events.MarkersChanged, this._markersChanged, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.NodeInserted, this._nodeInserted, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.AttrModified, this._attributeModified, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.AttrRemoved, this._attributeRemoved, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.CharacterDataModified, this._characterDataModified, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
-    domModel.removeEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this._distributedNodesChanged, this);
-    delete domModel[Elements.ElementsTreeOutline._treeOutlineSymbol];
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Elements.ElementsTreeOutline.UpdateRecord}
-   */
-  _addUpdateRecord(node) {
-    let record = this._updateRecords.get(node);
-    if (!record) {
-      record = new Elements.ElementsTreeOutline.UpdateRecord();
-      this._updateRecords.set(node, record);
-    }
-    return record;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {?Elements.ElementsTreeOutline.UpdateRecord}
-   */
-  _updateRecordForHighlight(node) {
-    if (!this._visible)
-      return null;
-    return this._updateRecords.get(node) || null;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _documentUpdated(event) {
-    const domModel = /** @type {!SDK.DOMModel} */ (event.data);
-    this._reset();
-    if (domModel.existingDocument())
-      this.rootDOMNode = domModel.existingDocument();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _attributeModified(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data.node);
-    this._addUpdateRecord(node).attributeModified(event.data.name);
-    this._updateModifiedNodesSoon();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _attributeRemoved(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data.node);
-    this._addUpdateRecord(node).attributeRemoved(event.data.name);
-    this._updateModifiedNodesSoon();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _characterDataModified(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    this._addUpdateRecord(node).charDataModified();
-    // Text could be large and force us to render itself as the child in the tree outline.
-    if (node.parentNode && node.parentNode.firstChild === node.parentNode.lastChild)
-      this._addUpdateRecord(node.parentNode).childrenModified();
-    this._updateModifiedNodesSoon();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _nodeInserted(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    this._addUpdateRecord(/** @type {!SDK.DOMNode} */ (node.parentNode)).nodeInserted(node);
-    this._updateModifiedNodesSoon();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _nodeRemoved(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data.node);
-    const parentNode = /** @type {!SDK.DOMNode} */ (event.data.parent);
-    this.resetClipboardIfNeeded(node);
-    this._addUpdateRecord(parentNode).nodeRemoved(node);
-    this._updateModifiedNodesSoon();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _childNodeCountUpdated(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    this._addUpdateRecord(node).childrenModified();
-    this._updateModifiedNodesSoon();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _distributedNodesChanged(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    this._addUpdateRecord(node).childrenModified();
-    this._updateModifiedNodesSoon();
-  }
-
-  _updateModifiedNodesSoon() {
-    if (!this._updateRecords.size)
-      return;
-    if (this._updateModifiedNodesTimeout)
-      return;
-    this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
-  }
-
-  _updateModifiedNodes() {
-    if (this._updateModifiedNodesTimeout) {
-      clearTimeout(this._updateModifiedNodesTimeout);
-      delete this._updateModifiedNodesTimeout;
-    }
-
-    const updatedNodes = this._updateRecords.keysArray();
-    const hidePanelWhileUpdating = updatedNodes.length > 10;
-    let treeOutlineContainerElement;
-    let originalScrollTop;
-    if (hidePanelWhileUpdating) {
-      treeOutlineContainerElement = this.element.parentNode;
-      originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
-      this._element.classList.add('hidden');
-    }
-
-    if (this._rootDOMNode && this._updateRecords.get(this._rootDOMNode) &&
-        this._updateRecords.get(this._rootDOMNode).hasChangedChildren()) {
-      // Document's children have changed, perform total update.
-      this.update();
-    } else {
-      for (const node of this._updateRecords.keys()) {
-        if (this._updateRecords.get(node).hasChangedChildren())
-          this._updateModifiedParentNode(node);
-        else
-          this._updateModifiedNode(node);
-      }
-    }
-
-    if (hidePanelWhileUpdating) {
-      this._element.classList.remove('hidden');
-      if (originalScrollTop)
-        treeOutlineContainerElement.scrollTop = originalScrollTop;
-    }
-
-    this._updateRecords.clear();
-    this._fireElementsTreeUpdated(updatedNodes);
-  }
-
-  _updateModifiedNode(node) {
-    const treeElement = this.findTreeElement(node);
-    if (treeElement)
-      treeElement.updateTitle(this._updateRecordForHighlight(node));
-  }
-
-  _updateModifiedParentNode(node) {
-    const parentTreeElement = this.findTreeElement(node);
-    if (parentTreeElement) {
-      parentTreeElement.setExpandable(this._hasVisibleChildren(node));
-      parentTreeElement.updateTitle(this._updateRecordForHighlight(node));
-      if (parentTreeElement.populated)
-        this._updateChildren(parentTreeElement);
-    }
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   */
-  populateTreeElement(treeElement) {
-    if (treeElement.childCount() || !treeElement.isExpandable())
-      return;
-    treeElement.node().getChildNodes(() => this._updateModifiedParentNode(treeElement.node()));
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {boolean=} closingTag
-   * @return {!Elements.ElementsTreeElement}
-   */
-  _createElementTreeElement(node, closingTag) {
-    const treeElement = new Elements.ElementsTreeElement(node, closingTag);
-    treeElement.setExpandable(!closingTag && this._hasVisibleChildren(node));
-    if (node.nodeType() === Node.ELEMENT_NODE && node.parentNode && node.parentNode.nodeType() === Node.DOCUMENT_NODE &&
-        !node.parentNode.parentNode)
-      treeElement.setCollapsible(false);
-    treeElement.selectable = this._selectEnabled;
-    return treeElement;
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   * @param {!SDK.DOMNode} child
-   * @return {?Elements.ElementsTreeElement}
-   */
-  _showChild(treeElement, child) {
-    if (treeElement.isClosingTag())
-      return null;
-
-    const index = this._visibleChildren(treeElement.node()).indexOf(child);
-    if (index === -1)
-      return null;
-
-    if (index >= treeElement.expandedChildrenLimit())
-      this.setExpandedChildrenLimit(treeElement, index + 1);
-    return /** @type {!Elements.ElementsTreeElement} */ (treeElement.childAt(index));
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Array.<!SDK.DOMNode>} visibleChildren
-   */
-  _visibleChildren(node) {
-    let visibleChildren = Elements.ElementsTreeElement.visibleShadowRoots(node);
-
-    const contentDocument = node.contentDocument();
-    if (contentDocument)
-      visibleChildren.push(contentDocument);
-
-    const importedDocument = node.importedDocument();
-    if (importedDocument)
-      visibleChildren.push(importedDocument);
-
-    const templateContent = node.templateContent();
-    if (templateContent)
-      visibleChildren.push(templateContent);
-
-    const beforePseudoElement = node.beforePseudoElement();
-    if (beforePseudoElement)
-      visibleChildren.push(beforePseudoElement);
-
-    if (node.childNodeCount()) {
-      let children = node.children();
-      if (!this._showHTMLCommentsSetting.get())
-        children = children.filter(n => n.nodeType() !== Node.COMMENT_NODE);
-      visibleChildren = visibleChildren.concat(children);
-    }
-
-    const afterPseudoElement = node.afterPseudoElement();
-    if (afterPseudoElement)
-      visibleChildren.push(afterPseudoElement);
-
-    return visibleChildren;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {boolean}
-   */
-  _hasVisibleChildren(node) {
-    if (node.isIframe() && Runtime.experiments.isEnabled('oopifInlineDOM'))
-      return true;
-    if (node.contentDocument())
-      return true;
-    if (node.importedDocument())
-      return true;
-    if (node.templateContent())
-      return true;
-    if (Elements.ElementsTreeElement.visibleShadowRoots(node).length)
-      return true;
-    if (node.hasPseudoElements())
-      return true;
-    if (node.isInsertionPoint())
-      return true;
-    return !!node.childNodeCount() && !Elements.ElementsTreeElement.canShowInlineText(node);
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   */
-  _createExpandAllButtonTreeElement(treeElement) {
-    const button = UI.createTextButton('', handleLoadAllChildren.bind(this));
-    button.value = '';
-    const expandAllButtonElement = new UI.TreeElement(button);
-    expandAllButtonElement.selectable = false;
-    expandAllButtonElement.expandAllButton = true;
-    expandAllButtonElement.button = button;
-    return expandAllButtonElement;
-
-    /**
-     * @this {Elements.ElementsTreeOutline}
-     * @param {!Event} event
-     */
-    function handleLoadAllChildren(event) {
-      const visibleChildCount = this._visibleChildren(treeElement.node()).length;
-      this.setExpandedChildrenLimit(
-          treeElement, Math.max(
-                           visibleChildCount,
-                           treeElement.expandedChildrenLimit() + Elements.ElementsTreeElement.InitialChildrenLimit));
-      event.consume();
-    }
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   * @param {number} expandedChildrenLimit
-   */
-  setExpandedChildrenLimit(treeElement, expandedChildrenLimit) {
-    if (treeElement.expandedChildrenLimit() === expandedChildrenLimit)
-      return;
-
-    treeElement.setExpandedChildrenLimit(expandedChildrenLimit);
-    if (treeElement.treeOutline && !this._treeElementsBeingUpdated.has(treeElement))
-      this._updateModifiedParentNode(treeElement.node());
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   */
-  _updateChildren(treeElement) {
-    if (!treeElement.isExpandable()) {
-      const selectedTreeElement = treeElement.treeOutline.selectedTreeElement;
-      if (selectedTreeElement && selectedTreeElement.hasAncestor(treeElement))
-        treeElement.select(true);
-      treeElement.removeChildren();
-      return;
-    }
-
-    console.assert(!treeElement.isClosingTag());
-
-    this._innerUpdateChildren(treeElement);
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   * @param {!SDK.DOMNode} child
-   * @param {number} index
-   * @param {boolean=} closingTag
-   * @return {!Elements.ElementsTreeElement}
-   */
-  insertChildElement(treeElement, child, index, closingTag) {
-    const newElement = this._createElementTreeElement(child, closingTag);
-    treeElement.insertChild(newElement, index);
-    return newElement;
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   * @param {!Elements.ElementsTreeElement} child
-   * @param {number} targetIndex
-   */
-  _moveChild(treeElement, child, targetIndex) {
-    if (treeElement.indexOfChild(child) === targetIndex)
-      return;
-    const wasSelected = child.selected;
-    if (child.parent)
-      child.parent.removeChild(child);
-    treeElement.insertChild(child, targetIndex);
-    if (wasSelected)
-      child.select();
-  }
-
-  /**
-   * @param {!Elements.ElementsTreeElement} treeElement
-   */
-  _innerUpdateChildren(treeElement) {
-    if (this._treeElementsBeingUpdated.has(treeElement))
-      return;
-
-    this._treeElementsBeingUpdated.add(treeElement);
-
-    const node = treeElement.node();
-    const visibleChildren = this._visibleChildren(node);
-    const visibleChildrenSet = new Set(visibleChildren);
-
-    // Remove any tree elements that no longer have this node as their parent and save
-    // all existing elements that could be reused. This also removes closing tag element.
-    const existingTreeElements = new Map();
-    for (let i = treeElement.childCount() - 1; i >= 0; --i) {
-      const existingTreeElement = treeElement.childAt(i);
-      if (!(existingTreeElement instanceof Elements.ElementsTreeElement)) {
-        // Remove expand all button and shadow host toolbar.
-        treeElement.removeChildAtIndex(i);
-        continue;
-      }
-      const elementsTreeElement = /** @type {!Elements.ElementsTreeElement} */ (existingTreeElement);
-      const existingNode = elementsTreeElement.node();
-
-      if (visibleChildrenSet.has(existingNode)) {
-        existingTreeElements.set(existingNode, existingTreeElement);
-        continue;
-      }
-
-      treeElement.removeChildAtIndex(i);
-    }
-
-    for (let i = 0; i < visibleChildren.length && i < treeElement.expandedChildrenLimit(); ++i) {
-      const child = visibleChildren[i];
-      const existingTreeElement = existingTreeElements.get(child) || this.findTreeElement(child);
-      if (existingTreeElement && existingTreeElement !== treeElement) {
-        // If an existing element was found, just move it.
-        this._moveChild(treeElement, existingTreeElement, i);
-      } else {
-        // No existing element found, insert a new element.
-        const newElement = this.insertChildElement(treeElement, child, i);
-        if (this._updateRecordForHighlight(node) && treeElement.expanded)
-          Elements.ElementsTreeElement.animateOnDOMUpdate(newElement);
-        // If a node was inserted in the middle of existing list dynamically we might need to increase the limit.
-        if (treeElement.childCount() > treeElement.expandedChildrenLimit())
-          this.setExpandedChildrenLimit(treeElement, treeElement.expandedChildrenLimit() + 1);
-      }
-    }
-
-    // Update expand all button.
-    const expandedChildCount = treeElement.childCount();
-    if (visibleChildren.length > expandedChildCount) {
-      const targetButtonIndex = expandedChildCount;
-      if (!treeElement.expandAllButtonElement)
-        treeElement.expandAllButtonElement = this._createExpandAllButtonTreeElement(treeElement);
-      treeElement.insertChild(treeElement.expandAllButtonElement, targetButtonIndex);
-      treeElement.expandAllButtonElement.button.textContent =
-          Common.UIString('Show All Nodes (%d More)', visibleChildren.length - expandedChildCount);
-    } else if (treeElement.expandAllButtonElement) {
-      delete treeElement.expandAllButtonElement;
-    }
-
-    // Insert shortcuts to distrubuted children.
-    if (node.isInsertionPoint()) {
-      for (const distributedNode of node.distributedNodes())
-        treeElement.appendChild(new Elements.ElementsTreeOutline.ShortcutTreeElement(distributedNode));
-    }
-
-    // Insert close tag.
-    if (node.nodeType() === Node.ELEMENT_NODE && treeElement.isExpandable())
-      this.insertChildElement(treeElement, node, treeElement.childCount(), true);
-
-    this._treeElementsBeingUpdated.delete(treeElement);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _markersChanged(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data);
-    const treeElement = node[this._treeElementSymbol];
-    if (treeElement)
-      treeElement.updateDecorations();
-  }
-};
-
-Elements.ElementsTreeOutline._treeOutlineSymbol = Symbol('treeOutline');
-
-
-/** @typedef {{node: !SDK.DOMNode, isCut: boolean}} */
-Elements.ElementsTreeOutline.ClipboardData;
-
-/** @enum {symbol} */
-Elements.ElementsTreeOutline.Events = {
-  SelectedNodeChanged: Symbol('SelectedNodeChanged'),
-  ElementsTreeUpdated: Symbol('ElementsTreeUpdated')
-};
-
-/**
- * @const
- * @type {!Object.<string, string>}
- */
-Elements.ElementsTreeOutline.MappedCharToEntity = {
-  '\u00a0': 'nbsp',
-  '\u0093': '#147',  // <control>
-  '\u00ad': 'shy',
-  '\u2002': 'ensp',
-  '\u2003': 'emsp',
-  '\u2009': 'thinsp',
-  '\u200a': '#8202',  // Hairspace
-  '\u200b': '#8203',  // ZWSP
-  '\u200c': 'zwnj',
-  '\u200d': 'zwj',
-  '\u200e': 'lrm',
-  '\u200f': 'rlm',
-  '\u202a': '#8234',  // LRE
-  '\u202b': '#8235',  // RLE
-  '\u202c': '#8236',  // PDF
-  '\u202d': '#8237',  // LRO
-  '\u202e': '#8238',  // RLO
-  '\ufeff': '#65279'  // BOM
-};
-
-/**
- * @unrestricted
- */
-Elements.ElementsTreeOutline.UpdateRecord = class {
-  /**
-   * @param {string} attrName
-   */
-  attributeModified(attrName) {
-    if (this._removedAttributes && this._removedAttributes.has(attrName))
-      this._removedAttributes.delete(attrName);
-    if (!this._modifiedAttributes)
-      this._modifiedAttributes = /** @type {!Set.<string>} */ (new Set());
-    this._modifiedAttributes.add(attrName);
-  }
-
-  /**
-   * @param {string} attrName
-   */
-  attributeRemoved(attrName) {
-    if (this._modifiedAttributes && this._modifiedAttributes.has(attrName))
-      this._modifiedAttributes.delete(attrName);
-    if (!this._removedAttributes)
-      this._removedAttributes = /** @type {!Set.<string>} */ (new Set());
-    this._removedAttributes.add(attrName);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   */
-  nodeInserted(node) {
-    this._hasChangedChildren = true;
-  }
-
-  nodeRemoved(node) {
-    this._hasChangedChildren = true;
-    this._hasRemovedChildren = true;
-  }
-
-  charDataModified() {
-    this._charDataModified = true;
-  }
-
-  childrenModified() {
-    this._hasChangedChildren = true;
-  }
-
-  /**
-   * @param {string} attributeName
-   * @return {boolean}
-   */
-  isAttributeModified(attributeName) {
-    return this._modifiedAttributes && this._modifiedAttributes.has(attributeName);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasRemovedAttributes() {
-    return !!this._removedAttributes && !!this._removedAttributes.size;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isCharDataModified() {
-    return !!this._charDataModified;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasChangedChildren() {
-    return !!this._hasChangedChildren;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasRemovedChildren() {
-    return !!this._hasRemovedChildren;
-  }
-};
-
-/**
- * @implements {Common.Renderer}
- */
-Elements.ElementsTreeOutline.Renderer = class {
-  /**
-   * @override
-   * @param {!Object} object
-   * @return {!Promise.<?Node>}
-   */
-  render(object) {
-    return new Promise(renderPromise);
-
-    /**
-     * @param {function(!Element)} resolve
-     * @param {function(!Error)} reject
-     */
-    function renderPromise(resolve, reject) {
-      if (object instanceof SDK.DOMNode)
-        onNodeResolved(/** @type {!SDK.DOMNode} */ (object));
-      else if (object instanceof SDK.DeferredDOMNode)
-        (/** @type {!SDK.DeferredDOMNode} */ (object)).resolve(onNodeResolved);
-      else
-        reject(new Error('Can\'t reveal not a node.'));
-
-
-      /**
-       * @param {?SDK.DOMNode} node
-       */
-      function onNodeResolved(node) {
-        if (!node) {
-          reject(new Error('Could not resolve node.'));
-          return;
-        }
-        const treeOutline = new Elements.ElementsTreeOutline(false, false);
-        treeOutline.rootDOMNode = node;
-        if (!treeOutline.firstChild().isExpandable())
-          treeOutline._element.classList.add('single-node');
-        treeOutline.setVisible(true);
-        treeOutline.element.treeElementForTest = treeOutline.firstChild();
-        resolve(treeOutline.element);
-      }
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Elements.ElementsTreeOutline.ShortcutTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.DOMNodeShortcut} nodeShortcut
-   */
-  constructor(nodeShortcut) {
-    super('');
-    this.listItemElement.createChild('div', 'selection fill');
-    const title = this.listItemElement.createChild('span', 'elements-tree-shortcut-title');
-    let text = nodeShortcut.nodeName.toLowerCase();
-    if (nodeShortcut.nodeType === Node.ELEMENT_NODE)
-      text = '<' + text + '>';
-    title.textContent = '\u21AA ' + text;
-
-    const link = Elements.DOMLinkifier.linkifyDeferredNodeReference(nodeShortcut.deferredNode);
-    this.listItemElement.createTextChild(' ');
-    link.classList.add('elements-tree-shortcut-link');
-    link.textContent = Common.UIString('reveal');
-    this.listItemElement.appendChild(link);
-    this._nodeShortcut = nodeShortcut;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get hovered() {
-    return this._hovered;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set hovered(x) {
-    if (this._hovered === x)
-      return;
-    this._hovered = x;
-    this.listItemElement.classList.toggle('hovered', x);
-  }
-
-  /**
-   * @return {number}
-   */
-  backendNodeId() {
-    return this._nodeShortcut.deferredNode.backendNodeId();
-  }
-
-  /**
-   * @return {!SDK.DOMModel}
-   */
-  domModel() {
-    return this._nodeShortcut.deferredNode.domModel();
-  }
-
-  /**
-   * @override
-   * @param {boolean=} selectedByUser
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    if (!selectedByUser)
-      return true;
-    this._nodeShortcut.deferredNode.highlight();
-    this._nodeShortcut.deferredNode.resolve(resolved.bind(this));
-    /**
-     * @param {?SDK.DOMNode} node
-     * @this {Elements.ElementsTreeOutline.ShortcutTreeElement}
-     */
-    function resolved(node) {
-      if (node) {
-        this.treeOutline._selectedDOMNode = node;
-        this.treeOutline._selectedNodeChanged();
-      }
-    }
-    return true;
-  }
-};
diff --git a/front_end/elements/EventListenersWidget.js b/front_end/elements/EventListenersWidget.js
deleted file mode 100644
index 18adda6..0000000
--- a/front_end/elements/EventListenersWidget.js
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ToolbarItem.ItemsProvider}
- * @unrestricted
- */
-Elements.EventListenersWidget = class extends UI.ThrottledWidget {
-  constructor() {
-    super();
-    this._toolbarItems = [];
-
-    this._showForAncestorsSetting = Common.settings.moduleSetting('showEventListenersForAncestors');
-    this._showForAncestorsSetting.addChangeListener(this.update.bind(this));
-
-    this._dispatchFilterBySetting = Common.settings.createSetting(
-        'eventListenerDispatchFilterType', Elements.EventListenersWidget.DispatchFilterBy.All);
-    this._dispatchFilterBySetting.addChangeListener(this.update.bind(this));
-
-    this._showFrameworkListenersSetting = Common.settings.createSetting('showFrameowkrListeners', true);
-    this._showFrameworkListenersSetting.setTitle(Common.UIString('Framework listeners'));
-    this._showFrameworkListenersSetting.addChangeListener(this._showFrameworkListenersChanged.bind(this));
-    this._eventListenersView = new EventListeners.EventListenersView(this.update.bind(this));
-    this._eventListenersView.show(this.element);
-
-    const refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this.update.bind(this));
-    this._toolbarItems.push(refreshButton);
-    this._toolbarItems.push(new UI.ToolbarSettingCheckbox(
-        this._showForAncestorsSetting, Common.UIString('Show listeners on the ancestors'),
-        Common.UIString('Ancestors')));
-    const dispatchFilter = new UI.ToolbarComboBox(this._onDispatchFilterTypeChanged.bind(this));
-
-    /**
-     * @param {string} name
-     * @param {string} value
-     * @this {Elements.EventListenersWidget}
-     */
-    function addDispatchFilterOption(name, value) {
-      const option = dispatchFilter.createOption(name, '', value);
-      if (value === this._dispatchFilterBySetting.get())
-        dispatchFilter.select(option);
-    }
-    addDispatchFilterOption.call(this, Common.UIString('All'), Elements.EventListenersWidget.DispatchFilterBy.All);
-    addDispatchFilterOption.call(
-        this, Common.UIString('Passive'), Elements.EventListenersWidget.DispatchFilterBy.Passive);
-    addDispatchFilterOption.call(
-        this, Common.UIString('Blocking'), Elements.EventListenersWidget.DispatchFilterBy.Blocking);
-    dispatchFilter.setMaxWidth(200);
-    this._toolbarItems.push(dispatchFilter);
-    this._toolbarItems.push(new UI.ToolbarSettingCheckbox(
-        this._showFrameworkListenersSetting, Common.UIString('Resolve event listeners bound with framework')));
-
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this.update, this);
-    this.update();
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    if (this._lastRequestedNode) {
-      this._lastRequestedNode.domModel().runtimeModel().releaseObjectGroup(
-          Elements.EventListenersWidget._objectGroupName);
-      delete this._lastRequestedNode;
-    }
-    const node = UI.context.flavor(SDK.DOMNode);
-    if (!node) {
-      this._eventListenersView.reset();
-      this._eventListenersView.addEmptyHolderIfNeeded();
-      return Promise.resolve();
-    }
-    this._lastRequestedNode = node;
-    const selectedNodeOnly = !this._showForAncestorsSetting.get();
-    const promises = [];
-    promises.push(node.resolveToObject(Elements.EventListenersWidget._objectGroupName));
-    if (!selectedNodeOnly) {
-      let currentNode = node.parentNode;
-      while (currentNode) {
-        promises.push(currentNode.resolveToObject(Elements.EventListenersWidget._objectGroupName));
-        currentNode = currentNode.parentNode;
-      }
-      promises.push(this._windowObjectInNodeContext(node));
-    }
-    return Promise.all(promises)
-        .then(this._eventListenersView.addObjects.bind(this._eventListenersView))
-        .then(this._showFrameworkListenersChanged.bind(this));
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  toolbarItems() {
-    return this._toolbarItems;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDispatchFilterTypeChanged(event) {
-    this._dispatchFilterBySetting.set(event.target.value);
-  }
-
-  _showFrameworkListenersChanged() {
-    const dispatchFilter = this._dispatchFilterBySetting.get();
-    const showPassive = dispatchFilter === Elements.EventListenersWidget.DispatchFilterBy.All ||
-        dispatchFilter === Elements.EventListenersWidget.DispatchFilterBy.Passive;
-    const showBlocking = dispatchFilter === Elements.EventListenersWidget.DispatchFilterBy.All ||
-        dispatchFilter === Elements.EventListenersWidget.DispatchFilterBy.Blocking;
-    this._eventListenersView.showFrameworkListeners(
-        this._showFrameworkListenersSetting.get(), showPassive, showBlocking);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise<?SDK.RemoteObject>}
-   */
-  _windowObjectInNodeContext(node) {
-    const executionContexts = node.domModel().runtimeModel().executionContexts();
-    let context = null;
-    if (node.frameId()) {
-      for (let i = 0; i < executionContexts.length; ++i) {
-        const executionContext = executionContexts[i];
-        if (executionContext.frameId === node.frameId() && executionContext.isDefault)
-          context = executionContext;
-      }
-    } else {
-      context = executionContexts[0];
-    }
-    return context
-        .evaluate(
-            {
-              expression: 'self',
-              objectGroup: Elements.EventListenersWidget._objectGroupName,
-              includeCommandLineAPI: false,
-              silent: true,
-              returnByValue: false,
-              generatePreview: false
-            },
-            /* userGesture */ false,
-            /* awaitPromise */ false)
-        .then(result => result.object || null);
-  }
-
-  _eventListenersArrivedForTest() {
-  }
-};
-
-Elements.EventListenersWidget.DispatchFilterBy = {
-  All: 'All',
-  Blocking: 'Blocking',
-  Passive: 'Passive'
-};
-
-Elements.EventListenersWidget._objectGroupName = 'event-listeners-panel';
diff --git a/front_end/elements/InspectElementModeController.js b/front_end/elements/InspectElementModeController.js
deleted file mode 100644
index 7cbbe07..0000000
--- a/front_end/elements/InspectElementModeController.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {SDK.SDKModelObserver<!SDK.OverlayModel>}
- * @unrestricted
- */
-Elements.InspectElementModeController = class {
-  constructor() {
-    this._toggleSearchAction = UI.actionRegistry.action('elements.toggle-element-search');
-    this._mode = Protocol.Overlay.InspectMode.None;
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._suspendStateChanged, this);
-    SDK.targetManager.addModelListener(
-        SDK.OverlayModel, SDK.OverlayModel.Events.ScreenshotRequested,
-        () => this._setMode(Protocol.Overlay.InspectMode.None));
-    SDK.targetManager.observeModels(SDK.OverlayModel, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.OverlayModel} overlayModel
-   */
-  modelAdded(overlayModel) {
-    // When DevTools are opening in the inspect element mode, the first target comes in
-    // much later than the InspectorFrontendAPI.enterInspectElementMode event.
-    if (this._mode === Protocol.Overlay.InspectMode.None)
-      return;
-    overlayModel.setInspectMode(this._mode);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.OverlayModel} overlayModel
-   */
-  modelRemoved(overlayModel) {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInInspectElementMode() {
-    return this._mode === Protocol.Overlay.InspectMode.SearchForNode ||
-        this._mode === Protocol.Overlay.InspectMode.SearchForUAShadowDOM;
-  }
-
-  stopInspection() {
-    if (this._mode && this._mode !== Protocol.Overlay.InspectMode.None)
-      this._toggleInspectMode();
-  }
-
-  _toggleInspectMode() {
-    if (SDK.targetManager.allTargetsSuspended())
-      return;
-
-    let mode;
-    if (this.isInInspectElementMode()) {
-      mode = Protocol.Overlay.InspectMode.None;
-    } else {
-      mode = Common.moduleSetting('showUAShadowDOM').get() ? Protocol.Overlay.InspectMode.SearchForUAShadowDOM :
-                                                             Protocol.Overlay.InspectMode.SearchForNode;
-    }
-
-    this._setMode(mode);
-  }
-
-  /**
-   * @param {!Protocol.Overlay.InspectMode} mode
-   */
-  _setMode(mode) {
-    this._mode = mode;
-    for (const overlayModel of SDK.targetManager.models(SDK.OverlayModel))
-      overlayModel.setInspectMode(mode);
-    this._toggleSearchAction.setToggled(this.isInInspectElementMode());
-  }
-
-  _suspendStateChanged() {
-    if (!SDK.targetManager.allTargetsSuspended())
-      return;
-
-    this._mode = Protocol.Overlay.InspectMode.None;
-    this._toggleSearchAction.setToggled(false);
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Elements.InspectElementModeController.ToggleSearchActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    if (!Elements.inspectElementModeController)
-      return false;
-    Elements.inspectElementModeController._toggleInspectMode();
-    return true;
-  }
-};
-
-/** @type {?Elements.InspectElementModeController} */
-Elements.inspectElementModeController =
-    Runtime.queryParam('isSharedWorker') ? null : new Elements.InspectElementModeController();
diff --git a/front_end/elements/MarkerDecorator.js b/front_end/elements/MarkerDecorator.js
deleted file mode 100644
index 1b67e5d..0000000
--- a/front_end/elements/MarkerDecorator.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @interface
- */
-Elements.MarkerDecorator = function() {};
-
-Elements.MarkerDecorator.prototype = {
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {?{title: string, color: string}}
-   */
-  decorate(node) {}
-};
-
-/**
- * @implements {Elements.MarkerDecorator}
- * @unrestricted
- */
-Elements.GenericDecorator = class {
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  constructor(extension) {
-    this._title = Common.UIString(extension.title());
-    this._color = extension.descriptor()['color'];
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DOMNode} node
-   * @return {?{title: string, color: string}}
-   */
-  decorate(node) {
-    return {title: this._title, color: this._color};
-  }
-};
diff --git a/front_end/elements/MetricsSidebarPane.js b/front_end/elements/MetricsSidebarPane.js
deleted file mode 100644
index 01b0ee4..0000000
--- a/front_end/elements/MetricsSidebarPane.js
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Elements.MetricsSidebarPane = class extends Elements.ElementsSidebarPane {
-  constructor() {
-    super();
-    this.registerRequiredCSS('elements/metricsSidebarPane.css');
-
-    /** @type {?SDK.CSSStyleDeclaration} */
-    this._inlineStyle = null;
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    // "style" attribute might have changed. Update metrics unless they are being edited
-    // (if a CSS property is added, a StyleSheetChanged event is dispatched).
-    if (this._isEditingMetrics)
-      return Promise.resolve();
-
-    // FIXME: avoid updates of a collapsed pane.
-    const node = this.node();
-    const cssModel = this.cssModel();
-    if (!node || node.nodeType() !== Node.ELEMENT_NODE || !cssModel) {
-      this.contentElement.removeChildren();
-      return Promise.resolve();
-    }
-
-    /**
-     * @param {?Map.<string, string>} style
-     * @this {Elements.MetricsSidebarPane}
-     */
-    function callback(style) {
-      if (!style || this.node() !== node)
-        return;
-      this._updateMetrics(style);
-    }
-    /**
-     * @param {?SDK.CSSModel.InlineStyleResult} inlineStyleResult
-     * @this {Elements.MetricsSidebarPane}
-     */
-    function inlineStyleCallback(inlineStyleResult) {
-      if (inlineStyleResult && this.node() === node)
-        this._inlineStyle = inlineStyleResult.inlineStyle;
-    }
-
-    const promises = [
-      cssModel.computedStylePromise(node.id).then(callback.bind(this)),
-      cssModel.inlineStylesPromise(node.id).then(inlineStyleCallback.bind(this))
-    ];
-    return Promise.all(promises);
-  }
-
-  /**
-   * @override
-   */
-  onCSSModelChanged() {
-    this.update();
-  }
-
-  /**
-   * @param {!Map.<string, string>} style
-   * @param {string} propertyName
-   * @return {number}
-   */
-  _getPropertyValueAsPx(style, propertyName) {
-    return Number(style.get(propertyName).replace(/px$/, '') || 0);
-  }
-
-  /**
-   * @param {!Map.<string, string>} computedStyle
-   * @param {string} componentName
-   */
-  _getBox(computedStyle, componentName) {
-    const suffix = componentName === 'border' ? '-width' : '';
-    const left = this._getPropertyValueAsPx(computedStyle, componentName + '-left' + suffix);
-    const top = this._getPropertyValueAsPx(computedStyle, componentName + '-top' + suffix);
-    const right = this._getPropertyValueAsPx(computedStyle, componentName + '-right' + suffix);
-    const bottom = this._getPropertyValueAsPx(computedStyle, componentName + '-bottom' + suffix);
-    return {left: left, top: top, right: right, bottom: bottom};
-  }
-
-  /**
-   * @param {boolean} showHighlight
-   * @param {string} mode
-   * @param {!Event} event
-   */
-  _highlightDOMNode(showHighlight, mode, event) {
-    event.consume();
-    if (showHighlight && this.node()) {
-      if (this._highlightMode === mode)
-        return;
-      this._highlightMode = mode;
-      this.node().highlight(mode);
-    } else {
-      delete this._highlightMode;
-      SDK.OverlayModel.hideDOMNodeHighlight();
-    }
-
-    for (let i = 0; this._boxElements && i < this._boxElements.length; ++i) {
-      const element = this._boxElements[i];
-      if (!this.node() || mode === 'all' || element._name === mode)
-        element.style.backgroundColor = element._backgroundColor;
-      else
-        element.style.backgroundColor = '';
-    }
-  }
-
-  /**
-   * @param {!Map.<string, string>} style
-   */
-  _updateMetrics(style) {
-    // Updating with computed style.
-    const metricsElement = createElement('div');
-    metricsElement.className = 'metrics';
-    const self = this;
-
-    /**
-     * @param {!Map.<string, string>} style
-     * @param {string} name
-     * @param {string} side
-     * @param {string} suffix
-     * @this {Elements.MetricsSidebarPane}
-     */
-    function createBoxPartElement(style, name, side, suffix) {
-      const propertyName = (name !== 'position' ? name + '-' : '') + side + suffix;
-      let value = style.get(propertyName);
-      if (value === '' || (name !== 'position' && value === '0px'))
-        value = '\u2012';
-      else if (name === 'position' && value === 'auto')
-        value = '\u2012';
-      value = value.replace(/px$/, '');
-      value = Number.toFixedIfFloating(value);
-
-      const element = createElement('div');
-      element.className = side;
-      element.textContent = value;
-      element.addEventListener('dblclick', this.startEditing.bind(this, element, name, propertyName, style), false);
-      return element;
-    }
-
-    /**
-     * @param {!Map.<string, string>} style
-     * @return {string}
-     */
-    function getContentAreaWidthPx(style) {
-      let width = style.get('width').replace(/px$/, '');
-      if (!isNaN(width) && style.get('box-sizing') === 'border-box') {
-        const borderBox = self._getBox(style, 'border');
-        const paddingBox = self._getBox(style, 'padding');
-
-        width = width - borderBox.left - borderBox.right - paddingBox.left - paddingBox.right;
-      }
-
-      return Number.toFixedIfFloating(width.toString());
-    }
-
-    /**
-     * @param {!Map.<string, string>} style
-     * @return {string}
-     */
-    function getContentAreaHeightPx(style) {
-      let height = style.get('height').replace(/px$/, '');
-      if (!isNaN(height) && style.get('box-sizing') === 'border-box') {
-        const borderBox = self._getBox(style, 'border');
-        const paddingBox = self._getBox(style, 'padding');
-
-        height = height - borderBox.top - borderBox.bottom - paddingBox.top - paddingBox.bottom;
-      }
-
-      return Number.toFixedIfFloating(height.toString());
-    }
-
-    // Display types for which margin is ignored.
-    const noMarginDisplayType = {
-      'table-cell': true,
-      'table-column': true,
-      'table-column-group': true,
-      'table-footer-group': true,
-      'table-header-group': true,
-      'table-row': true,
-      'table-row-group': true
-    };
-
-    // Display types for which padding is ignored.
-    const noPaddingDisplayType = {
-      'table-column': true,
-      'table-column-group': true,
-      'table-footer-group': true,
-      'table-header-group': true,
-      'table-row': true,
-      'table-row-group': true
-    };
-
-    // Position types for which top, left, bottom and right are ignored.
-    const noPositionType = {'static': true};
-
-    const boxes = ['content', 'padding', 'border', 'margin', 'position'];
-    const boxColors = [
-      Common.Color.PageHighlight.Content, Common.Color.PageHighlight.Padding, Common.Color.PageHighlight.Border,
-      Common.Color.PageHighlight.Margin, Common.Color.fromRGBA([0, 0, 0, 0])
-    ];
-    const boxLabels = [
-      Common.UIString('content'), Common.UIString('padding'), Common.UIString('border'), Common.UIString('margin'),
-      Common.UIString('position')
-    ];
-    let previousBox = null;
-    this._boxElements = [];
-    for (let i = 0; i < boxes.length; ++i) {
-      const name = boxes[i];
-
-      if (name === 'margin' && noMarginDisplayType[style.get('display')])
-        continue;
-      if (name === 'padding' && noPaddingDisplayType[style.get('display')])
-        continue;
-      if (name === 'position' && noPositionType[style.get('position')])
-        continue;
-
-      const boxElement = createElement('div');
-      boxElement.className = name;
-      boxElement._backgroundColor = boxColors[i].asString(Common.Color.Format.RGBA);
-      boxElement._name = name;
-      boxElement.style.backgroundColor = boxElement._backgroundColor;
-      boxElement.addEventListener(
-          'mouseover', this._highlightDOMNode.bind(this, true, name === 'position' ? 'all' : name), false);
-      this._boxElements.push(boxElement);
-
-      if (name === 'content') {
-        const widthElement = createElement('span');
-        widthElement.textContent = getContentAreaWidthPx(style);
-        widthElement.addEventListener(
-            'dblclick', this.startEditing.bind(this, widthElement, 'width', 'width', style), false);
-
-        const heightElement = createElement('span');
-        heightElement.textContent = getContentAreaHeightPx(style);
-        heightElement.addEventListener(
-            'dblclick', this.startEditing.bind(this, heightElement, 'height', 'height', style), false);
-
-        boxElement.appendChild(widthElement);
-        boxElement.createTextChild(' \u00D7 ');
-        boxElement.appendChild(heightElement);
-      } else {
-        const suffix = (name === 'border' ? '-width' : '');
-
-        const labelElement = createElement('div');
-        labelElement.className = 'label';
-        labelElement.textContent = boxLabels[i];
-        boxElement.appendChild(labelElement);
-
-        boxElement.appendChild(createBoxPartElement.call(this, style, name, 'top', suffix));
-        boxElement.appendChild(createElement('br'));
-        boxElement.appendChild(createBoxPartElement.call(this, style, name, 'left', suffix));
-
-        if (previousBox)
-          boxElement.appendChild(previousBox);
-
-        boxElement.appendChild(createBoxPartElement.call(this, style, name, 'right', suffix));
-        boxElement.appendChild(createElement('br'));
-        boxElement.appendChild(createBoxPartElement.call(this, style, name, 'bottom', suffix));
-      }
-
-      previousBox = boxElement;
-    }
-
-    metricsElement.appendChild(previousBox);
-    metricsElement.addEventListener('mouseover', this._highlightDOMNode.bind(this, false, 'all'), false);
-    this.contentElement.removeChildren();
-    this.contentElement.appendChild(metricsElement);
-  }
-
-  /**
-   * @param {!Element} targetElement
-   * @param {string} box
-   * @param {string} styleProperty
-   * @param {!Map.<string, string>} computedStyle
-   */
-  startEditing(targetElement, box, styleProperty, computedStyle) {
-    if (UI.isBeingEdited(targetElement))
-      return;
-
-    const context = {box: box, styleProperty: styleProperty, computedStyle: computedStyle};
-    const boundKeyDown = this._handleKeyDown.bind(this, context, styleProperty);
-    context.keyDownHandler = boundKeyDown;
-    targetElement.addEventListener('keydown', boundKeyDown, false);
-
-    this._isEditingMetrics = true;
-
-    const config =
-        new UI.InplaceEditor.Config(this._editingCommitted.bind(this), this.editingCancelled.bind(this), context);
-    UI.InplaceEditor.startEditing(targetElement, config);
-
-    targetElement.getComponentSelection().selectAllChildren(targetElement);
-  }
-
-  _handleKeyDown(context, styleProperty, event) {
-    const element = event.currentTarget;
-
-    /**
-     * @param {string} originalValue
-     * @param {string} replacementString
-     * @this {Elements.MetricsSidebarPane}
-     */
-    function finishHandler(originalValue, replacementString) {
-      this._applyUserInput(element, replacementString, originalValue, context, false);
-    }
-
-    /**
-     * @param {string} prefix
-     * @param {number} number
-     * @param {string} suffix
-     * @return {string}
-     */
-    function customNumberHandler(prefix, number, suffix) {
-      if (styleProperty !== 'margin' && number < 0)
-        number = 0;
-      return prefix + number + suffix;
-    }
-
-    UI.handleElementValueModifications(event, element, finishHandler.bind(this), undefined, customNumberHandler);
-  }
-
-  editingEnded(element, context) {
-    delete this.originalPropertyData;
-    delete this.previousPropertyDataCandidate;
-    element.removeEventListener('keydown', context.keyDownHandler, false);
-    delete this._isEditingMetrics;
-  }
-
-  editingCancelled(element, context) {
-    if ('originalPropertyData' in this && this._inlineStyle) {
-      if (!this.originalPropertyData) {
-        // An added property, remove the last property in the style.
-        const pastLastSourcePropertyIndex = this._inlineStyle.pastLastSourcePropertyIndex();
-        if (pastLastSourcePropertyIndex)
-          this._inlineStyle.allProperties()[pastLastSourcePropertyIndex - 1].setText('', false);
-      } else {
-        this._inlineStyle.allProperties()[this.originalPropertyData.index].setText(
-            this.originalPropertyData.propertyText, false);
-      }
-    }
-    this.editingEnded(element, context);
-    this.update();
-  }
-
-  _applyUserInput(element, userInput, previousContent, context, commitEditor) {
-    if (!this._inlineStyle) {
-      // Element has no renderer.
-      return this.editingCancelled(element, context);  // nothing changed, so cancel
-    }
-
-    if (commitEditor && userInput === previousContent)
-      return this.editingCancelled(element, context);  // nothing changed, so cancel
-
-    if (context.box !== 'position' && (!userInput || userInput === '\u2012'))
-      userInput = '0px';
-    else if (context.box === 'position' && (!userInput || userInput === '\u2012'))
-      userInput = 'auto';
-
-    userInput = userInput.toLowerCase();
-    // Append a "px" unit if the user input was just a number.
-    if (/^\d+$/.test(userInput))
-      userInput += 'px';
-
-    const styleProperty = context.styleProperty;
-    const computedStyle = context.computedStyle;
-
-    if (computedStyle.get('box-sizing') === 'border-box' && (styleProperty === 'width' || styleProperty === 'height')) {
-      if (!userInput.match(/px$/)) {
-        Common.console.error(
-            'For elements with box-sizing: border-box, only absolute content area dimensions can be applied');
-        return;
-      }
-
-      const borderBox = this._getBox(computedStyle, 'border');
-      const paddingBox = this._getBox(computedStyle, 'padding');
-      let userValuePx = Number(userInput.replace(/px$/, ''));
-      if (isNaN(userValuePx))
-        return;
-      if (styleProperty === 'width')
-        userValuePx += borderBox.left + borderBox.right + paddingBox.left + paddingBox.right;
-      else
-        userValuePx += borderBox.top + borderBox.bottom + paddingBox.top + paddingBox.bottom;
-
-      userInput = userValuePx + 'px';
-    }
-
-    this.previousPropertyDataCandidate = null;
-
-    const allProperties = this._inlineStyle.allProperties();
-    for (let i = 0; i < allProperties.length; ++i) {
-      const property = allProperties[i];
-      if (property.name !== context.styleProperty || !property.activeInStyle())
-        continue;
-
-      this.previousPropertyDataCandidate = property;
-      property.setValue(userInput, commitEditor, true, callback.bind(this));
-      return;
-    }
-
-    this._inlineStyle.appendProperty(context.styleProperty, userInput, callback.bind(this));
-
-    /**
-     * @param {boolean} success
-     * @this {Elements.MetricsSidebarPane}
-     */
-    function callback(success) {
-      if (!success)
-        return;
-      if (!('originalPropertyData' in this))
-        this.originalPropertyData = this.previousPropertyDataCandidate;
-
-      if (typeof this._highlightMode !== 'undefined')
-        this.node().highlight(this._highlightMode);
-
-      if (commitEditor)
-        this.update();
-    }
-  }
-
-  _editingCommitted(element, userInput, previousContent, context) {
-    this.editingEnded(element, context);
-    this._applyUserInput(element, userInput, previousContent, context, true);
-  }
-};
diff --git a/front_end/elements/PlatformFontsWidget.js b/front_end/elements/PlatformFontsWidget.js
deleted file mode 100644
index 3bec7d9..0000000
--- a/front_end/elements/PlatformFontsWidget.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Elements.PlatformFontsWidget = class extends UI.ThrottledWidget {
-  /**
-   * @param {!Elements.ComputedStyleModel} sharedModel
-   */
-  constructor(sharedModel) {
-    super(true);
-    this.registerRequiredCSS('elements/platformFontsWidget.css');
-
-    this._sharedModel = sharedModel;
-    this._sharedModel.addEventListener(Elements.ComputedStyleModel.Events.ComputedStyleChanged, this.update, this);
-
-    this._sectionTitle = createElementWithClass('div', 'title');
-    this.contentElement.classList.add('platform-fonts');
-    this.contentElement.appendChild(this._sectionTitle);
-    this._sectionTitle.textContent = Common.UIString('Rendered Fonts');
-    this._fontStatsSection = this.contentElement.createChild('div', 'stats-section');
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    const cssModel = this._sharedModel.cssModel();
-    const node = this._sharedModel.node();
-    if (!node || !cssModel)
-      return Promise.resolve();
-
-    return cssModel.platformFontsPromise(node.id).then(this._refreshUI.bind(this, node));
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {?Array.<!Protocol.CSS.PlatformFontUsage>} platformFonts
-   */
-  _refreshUI(node, platformFonts) {
-    if (this._sharedModel.node() !== node)
-      return;
-
-    this._fontStatsSection.removeChildren();
-
-    const isEmptySection = !platformFonts || !platformFonts.length;
-    this._sectionTitle.classList.toggle('hidden', isEmptySection);
-    if (isEmptySection)
-      return;
-
-    platformFonts.sort(function(a, b) {
-      return b.glyphCount - a.glyphCount;
-    });
-    for (let i = 0; i < platformFonts.length; ++i) {
-      const fontStatElement = this._fontStatsSection.createChild('div', 'font-stats-item');
-
-      const fontNameElement = fontStatElement.createChild('span', 'font-name');
-      fontNameElement.textContent = platformFonts[i].familyName;
-
-      const fontDelimeterElement = fontStatElement.createChild('span', 'font-delimeter');
-      fontDelimeterElement.textContent = '\u2014';
-
-      const fontOrigin = fontStatElement.createChild('span');
-      fontOrigin.textContent =
-          platformFonts[i].isCustomFont ? Common.UIString('Network resource') : Common.UIString('Local file');
-
-      const fontUsageElement = fontStatElement.createChild('span', 'font-usage');
-      const usage = platformFonts[i].glyphCount;
-      fontUsageElement.textContent =
-          usage === 1 ? Common.UIString('(%d glyph)', usage) : Common.UIString('(%d glyphs)', usage);
-    }
-  }
-};
diff --git a/front_end/elements/PropertiesWidget.js b/front_end/elements/PropertiesWidget.js
deleted file mode 100644
index 1a480c6..0000000
--- a/front_end/elements/PropertiesWidget.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Elements.PropertiesWidget = class extends UI.ThrottledWidget {
-  constructor() {
-    super(true /* isWebComponent */);
-    this.registerRequiredCSS('elements/propertiesWidget.css');
-
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrModified, this._onNodeChange, this);
-    SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrRemoved, this._onNodeChange, this);
-    SDK.targetManager.addModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
-    SDK.targetManager.addModelListener(
-        SDK.DOMModel, SDK.DOMModel.Events.ChildNodeCountUpdated, this._onNodeChange, this);
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this._setNode, this);
-    this._node = UI.context.flavor(SDK.DOMNode);
-    this.update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _setNode(event) {
-    this._node = /** @type {?SDK.DOMNode} */ (event.data);
-    this.update();
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    if (this._lastRequestedNode) {
-      this._lastRequestedNode.domModel().runtimeModel().releaseObjectGroup(Elements.PropertiesWidget._objectGroupName);
-      delete this._lastRequestedNode;
-    }
-
-    if (!this._node) {
-      this.contentElement.removeChildren();
-      this.sections = [];
-      return Promise.resolve();
-    }
-
-    this._lastRequestedNode = this._node;
-    return this._node.resolveToObject(Elements.PropertiesWidget._objectGroupName).then(nodeResolved.bind(this));
-
-    /**
-     * @param {?SDK.RemoteObject} object
-     * @this {Elements.PropertiesWidget}
-     */
-    function nodeResolved(object) {
-      if (!object)
-        return;
-
-      /**
-       * @suppressReceiverCheck
-       * @this {*}
-       */
-      function protoList() {
-        let proto = this;
-        const result = {__proto__: null};
-        let counter = 1;
-        while (proto) {
-          result[counter++] = proto;
-          proto = proto.__proto__;
-        }
-        return result;
-      }
-      const promise = object.callFunctionPromise(protoList).then(nodePrototypesReady.bind(this));
-      object.release();
-      return promise;
-    }
-
-    /**
-     * @param {!{object: ?SDK.RemoteObject, wasThrown: (boolean|undefined)}} result
-     * @this {Elements.PropertiesWidget}
-     */
-    function nodePrototypesReady(result) {
-      if (!result.object || result.wasThrown)
-        return;
-
-      const promise = result.object.getOwnPropertiesPromise(false /* generatePreview */).then(fillSection.bind(this));
-      result.object.release();
-      return promise;
-    }
-
-    /**
-     * @param {!{properties: ?Array.<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>}} result
-     * @this {Elements.PropertiesWidget}
-     */
-    function fillSection(result) {
-      if (!result || !result.properties)
-        return;
-
-      const properties = result.properties;
-      const expanded = [];
-      const sections = this.sections || [];
-      for (let i = 0; i < sections.length; ++i)
-        expanded.push(sections[i].expanded);
-
-      this.contentElement.removeChildren();
-      this.sections = [];
-
-      // Get array of property user-friendly names.
-      for (let i = 0; i < properties.length; ++i) {
-        if (!parseInt(properties[i].name, 10))
-          continue;
-        const property = properties[i].value;
-        let title = property.description;
-        title = title.replace(/Prototype$/, '');
-        const section = new ObjectUI.ObjectPropertiesSection(property, title);
-        section.element.classList.add('properties-widget-section');
-        this.sections.push(section);
-        this.contentElement.appendChild(section.element);
-        if (expanded[this.sections.length - 1])
-          section.expand();
-        section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._propertyExpanded, this);
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _propertyExpanded(event) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.DOMPropertiesExpanded);
-    for (const section of this.sections)
-      section.removeEventListener(UI.TreeOutline.Events.ElementExpanded, this._propertyExpanded, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onNodeChange(event) {
-    if (!this._node)
-      return;
-    const data = event.data;
-    const node = /** @type {!SDK.DOMNode} */ (data instanceof SDK.DOMNode ? data : data.node);
-    if (this._node !== node)
-      return;
-    this.update();
-  }
-};
-
-Elements.PropertiesWidget._objectGroupName = 'properties-sidebar-pane';
diff --git a/front_end/elements/StylePropertyHighlighter.js b/front_end/elements/StylePropertyHighlighter.js
deleted file mode 100644
index 17839b4..0000000
--- a/front_end/elements/StylePropertyHighlighter.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Elements.StylePropertyHighlighter = class {
-  /**
-   * @param {!Elements.StylesSidebarPane} ssp
-   * @param {!SDK.CSSProperty} cssProperty
-   */
-  constructor(ssp, cssProperty) {
-    this._styleSidebarPane = ssp;
-    this._cssProperty = cssProperty;
-  }
-
-  perform() {
-    // Expand all shorthands.
-    for (const section of this._styleSidebarPane.allSections()) {
-      for (let treeElement = section.propertiesTreeOutline.firstChild(); treeElement;
-           treeElement = treeElement.nextSibling)
-        treeElement.onpopulate();
-    }
-    let highlightTreeElement = null;
-    for (const section of this._styleSidebarPane.allSections()) {
-      let treeElement = section.propertiesTreeOutline.firstChild();
-      while (treeElement && !highlightTreeElement) {
-        if (treeElement.property === this._cssProperty) {
-          highlightTreeElement = treeElement;
-          break;
-        }
-        treeElement = treeElement.traverseNextTreeElement(false, null, true);
-      }
-      if (highlightTreeElement)
-        break;
-    }
-
-    if (!highlightTreeElement)
-      return;
-
-    highlightTreeElement.parent.expand();
-    highlightTreeElement.listItemElement.scrollIntoViewIfNeeded();
-    highlightTreeElement.listItemElement.animate(
-        [
-          {offset: 0, backgroundColor: 'rgba(255, 255, 0, 0.2)'},
-          {offset: 0.1, backgroundColor: 'rgba(255, 255, 0, 0.7)'}, {offset: 1, backgroundColor: 'transparent'}
-        ],
-        {duration: 2000, easing: 'cubic-bezier(0, 0, 0.2, 1)'});
-  }
-};
diff --git a/front_end/elements/StylePropertyTreeElement.js b/front_end/elements/StylePropertyTreeElement.js
deleted file mode 100644
index 167949b..0000000
--- a/front_end/elements/StylePropertyTreeElement.js
+++ /dev/null
@@ -1,1018 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Elements.StylePropertyTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Elements.StylesSidebarPane} stylesPane
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {!SDK.CSSProperty} property
-   * @param {boolean} isShorthand
-   * @param {boolean} inherited
-   * @param {boolean} overloaded
-   * @param {boolean} newProperty
-   */
-  constructor(stylesPane, matchedStyles, property, isShorthand, inherited, overloaded, newProperty) {
-    // Pass an empty title, the title gets made later in onattach.
-    super('', isShorthand);
-    this._style = property.ownerStyle;
-    this._matchedStyles = matchedStyles;
-    this.property = property;
-    this._inherited = inherited;
-    this._overloaded = overloaded;
-    this.selectable = false;
-    this._parentPane = stylesPane;
-    this.isShorthand = isShorthand;
-    this._applyStyleThrottler = new Common.Throttler(0);
-    this._newProperty = newProperty;
-    if (this._newProperty)
-      this.listItemElement.textContent = '';
-    this._expandedDueToFilter = false;
-    this.valueElement = null;
-    this.nameElement = null;
-    this._expandElement = null;
-    this._originalPropertyText = '';
-    this._prompt = null;
-    this._propertyHasBeenEditedIncrementally = false;
-    this._lastComputedValue = null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _editable() {
-    return !!(this._style.styleSheetId && this._style.range);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  inherited() {
-    return this._inherited;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  overloaded() {
-    return this._overloaded;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  setOverloaded(x) {
-    if (x === this._overloaded)
-      return;
-    this._overloaded = x;
-    this._updateState();
-  }
-
-  get name() {
-    return this.property.name;
-  }
-
-  get value() {
-    return this.property.value;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _updateFilter() {
-    const regex = this._parentPane.filterRegex();
-    const matches = !!regex && (regex.test(this.property.name) || regex.test(this.property.value));
-    this.listItemElement.classList.toggle('filter-match', matches);
-
-    this.onpopulate();
-    let hasMatchingChildren = false;
-    for (let i = 0; i < this.childCount(); ++i)
-      hasMatchingChildren |= this.childAt(i)._updateFilter();
-
-    if (!regex) {
-      if (this._expandedDueToFilter)
-        this.collapse();
-      this._expandedDueToFilter = false;
-    } else if (hasMatchingChildren && !this.expanded) {
-      this.expand();
-      this._expandedDueToFilter = true;
-    } else if (!hasMatchingChildren && this.expanded && this._expandedDueToFilter) {
-      this.collapse();
-      this._expandedDueToFilter = false;
-    }
-    return matches;
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Node}
-   */
-  _processColor(text) {
-    // We can be called with valid non-color values of |text| (like 'none' from border style)
-    const color = Common.Color.parse(text);
-    if (!color)
-      return createTextNode(text);
-
-    if (!this._editable()) {
-      const swatch = InlineEditor.ColorSwatch.create();
-      swatch.setColor(color);
-      return swatch;
-    }
-
-    const swatchPopoverHelper = this._parentPane.swatchPopoverHelper();
-    const swatch = InlineEditor.ColorSwatch.create();
-    swatch.setColor(color);
-    swatch.setFormat(Common.Color.detectColorFormat(swatch.color()));
-    const swatchIcon = new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, swatch);
-
-    /**
-     * @param {?SDK.CSSModel.ContrastInfo} contrastInfo
-     */
-    function computedCallback(contrastInfo) {
-      swatchIcon.setContrastInfo(contrastInfo);
-    }
-
-    if (Runtime.experiments.isEnabled('colorContrastRatio') && this.property.name === 'color' &&
-        this._parentPane.cssModel() && this.node()) {
-      const cssModel = this._parentPane.cssModel();
-      cssModel.backgroundColorsPromise(this.node().id).then(computedCallback);
-    }
-
-    return swatch;
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Node}
-   */
-  _processVar(text) {
-    const computedValue = this._matchedStyles.computeValue(this._style, text);
-    if (!computedValue)
-      return createTextNode(text);
-    const color = Common.Color.parse(computedValue);
-    if (!color) {
-      const node = createElement('span');
-      node.textContent = text;
-      node.title = computedValue;
-      return node;
-    }
-    if (!this._editable()) {
-      const swatch = InlineEditor.ColorSwatch.create();
-      swatch.setText(text, computedValue);
-      swatch.setColor(color);
-      return swatch;
-    }
-
-    const swatchPopoverHelper = this._parentPane.swatchPopoverHelper();
-    const swatch = InlineEditor.ColorSwatch.create();
-    swatch.setColor(color);
-    swatch.setFormat(Common.Color.detectColorFormat(swatch.color()));
-    swatch.setText(text, computedValue);
-    new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, swatch);
-    return swatch;
-  }
-
-  /**
-   * @return {string}
-   */
-  renderedPropertyText() {
-    return this.nameElement.textContent + ': ' + this.valueElement.textContent;
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Node}
-   */
-  _processBezier(text) {
-    if (!this._editable() || !UI.Geometry.CubicBezier.parse(text))
-      return createTextNode(text);
-    const swatchPopoverHelper = this._parentPane.swatchPopoverHelper();
-    const swatch = InlineEditor.BezierSwatch.create();
-    swatch.setBezierText(text);
-    new Elements.BezierPopoverIcon(this, swatchPopoverHelper, swatch);
-    return swatch;
-  }
-
-  /**
-   * @param {string} propertyValue
-   * @param {string} propertyName
-   * @return {!Node}
-   */
-  _processShadow(propertyValue, propertyName) {
-    if (!this._editable())
-      return createTextNode(propertyValue);
-    let shadows;
-    if (propertyName === 'text-shadow')
-      shadows = InlineEditor.CSSShadowModel.parseTextShadow(propertyValue);
-    else
-      shadows = InlineEditor.CSSShadowModel.parseBoxShadow(propertyValue);
-    if (!shadows.length)
-      return createTextNode(propertyValue);
-    const container = createDocumentFragment();
-    const swatchPopoverHelper = this._parentPane.swatchPopoverHelper();
-    for (let i = 0; i < shadows.length; i++) {
-      if (i !== 0)
-        container.appendChild(createTextNode(', '));  // Add back commas and spaces between each shadow.
-      // TODO(flandy): editing the property value should use the original value with all spaces.
-      const cssShadowSwatch = InlineEditor.CSSShadowSwatch.create();
-      cssShadowSwatch.setCSSShadow(shadows[i]);
-      new Elements.ShadowSwatchPopoverHelper(this, swatchPopoverHelper, cssShadowSwatch);
-      const colorSwatch = cssShadowSwatch.colorSwatch();
-      if (colorSwatch)
-        new Elements.ColorSwatchPopoverIcon(this, swatchPopoverHelper, colorSwatch);
-      container.appendChild(cssShadowSwatch);
-    }
-    return container;
-  }
-
-  _updateState() {
-    if (!this.listItemElement)
-      return;
-
-    if (this._style.isPropertyImplicit(this.name))
-      this.listItemElement.classList.add('implicit');
-    else
-      this.listItemElement.classList.remove('implicit');
-
-    const hasIgnorableError =
-        !this.property.parsedOk && Elements.StylesSidebarPane.ignoreErrorsForProperty(this.property);
-    if (hasIgnorableError)
-      this.listItemElement.classList.add('has-ignorable-error');
-    else
-      this.listItemElement.classList.remove('has-ignorable-error');
-
-    if (this.inherited())
-      this.listItemElement.classList.add('inherited');
-    else
-      this.listItemElement.classList.remove('inherited');
-
-    if (this.overloaded())
-      this.listItemElement.classList.add('overloaded');
-    else
-      this.listItemElement.classList.remove('overloaded');
-
-    if (this.property.disabled)
-      this.listItemElement.classList.add('disabled');
-    else
-      this.listItemElement.classList.remove('disabled');
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._parentPane.node();
-  }
-
-  /**
-   * @return {!Elements.StylesSidebarPane}
-   */
-  parentPane() {
-    return this._parentPane;
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  section() {
-    return this.treeOutline && this.treeOutline.section;
-  }
-
-  _updatePane() {
-    const section = this.section();
-    if (section)
-      section.refreshUpdate(this);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _toggleEnabled(event) {
-    const disabled = !event.target.checked;
-    const oldStyleRange = this._style.range;
-    if (!oldStyleRange)
-      return;
-
-    /**
-     * @param {boolean} success
-     * @this {Elements.StylePropertyTreeElement}
-     */
-    function callback(success) {
-      this._parentPane.setUserOperation(false);
-
-      if (!success)
-        return;
-      this._matchedStyles.resetActiveProperties();
-      this._updatePane();
-      this.styleTextAppliedForTest();
-    }
-
-    event.consume();
-    this._parentPane.setUserOperation(true);
-    this.property.setDisabled(disabled).then(callback.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    // Only populate once and if this property is a shorthand.
-    if (this.childCount() || !this.isShorthand)
-      return;
-
-    const longhandProperties = this._style.longhandProperties(this.name);
-    for (let i = 0; i < longhandProperties.length; ++i) {
-      const name = longhandProperties[i].name;
-      let inherited = false;
-      let overloaded = false;
-
-      const section = this.section();
-      if (section) {
-        inherited = section.isPropertyInherited(name);
-        overloaded =
-            this._matchedStyles.propertyState(longhandProperties[i]) === SDK.CSSMatchedStyles.PropertyState.Overloaded;
-      }
-
-      const item = new Elements.StylePropertyTreeElement(
-          this._parentPane, this._matchedStyles, longhandProperties[i], false, inherited, overloaded, false);
-      this.appendChild(item);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.updateTitle();
-
-    this.listItemElement.addEventListener('mousedown', event => {
-      if (event.which === 1)
-        this._parentPane[Elements.StylePropertyTreeElement.ActiveSymbol] = this;
-    }, false);
-    this.listItemElement.addEventListener('mouseup', this._mouseUp.bind(this));
-    this.listItemElement.addEventListener('click', event => {
-      if (!event.target.hasSelection() && event.target !== this.listItemElement)
-        event.consume(true);
-    });
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    this._updateExpandElement();
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    this._updateExpandElement();
-  }
-
-  _updateExpandElement() {
-    if (!this._expandElement)
-      return;
-    if (this.expanded)
-      this._expandElement.setIconType('smallicon-triangle-down');
-    else
-      this._expandElement.setIconType('smallicon-triangle-right');
-  }
-
-  updateTitleIfComputedValueChanged() {
-    const computedValue = this._matchedStyles.computeValue(this.property.ownerStyle, this.property.value);
-    if (computedValue === this._lastComputedValue)
-      return;
-    this._lastComputedValue = computedValue;
-    this._innerUpdateTitle();
-  }
-
-  updateTitle() {
-    this._lastComputedValue = this._matchedStyles.computeValue(this.property.ownerStyle, this.property.value);
-    this._innerUpdateTitle();
-  }
-
-  _innerUpdateTitle() {
-    this._updateState();
-    if (this.isExpandable())
-      this._expandElement = UI.Icon.create('smallicon-triangle-right', 'expand-icon');
-    else
-      this._expandElement = null;
-
-    const propertyRenderer =
-        new Elements.StylesSidebarPropertyRenderer(this._style.parentRule, this.node(), this.name, this.value);
-    if (this.property.parsedOk) {
-      propertyRenderer.setVarHandler(this._processVar.bind(this));
-      propertyRenderer.setColorHandler(this._processColor.bind(this));
-      propertyRenderer.setBezierHandler(this._processBezier.bind(this));
-      propertyRenderer.setShadowHandler(this._processShadow.bind(this));
-    }
-
-    this.listItemElement.removeChildren();
-    this.nameElement = propertyRenderer.renderName();
-    if (this.property.name.startsWith('--'))
-      this.nameElement.title = this._matchedStyles.computeCSSVariable(this._style, this.property.name) || '';
-    this.valueElement = propertyRenderer.renderValue();
-    if (!this.treeOutline)
-      return;
-
-    const indent = Common.moduleSetting('textEditorIndent').get();
-    this.listItemElement.createChild('span', 'styles-clipboard-only')
-        .createTextChild(indent + (this.property.disabled ? '/* ' : ''));
-    this.listItemElement.appendChild(this.nameElement);
-    this.listItemElement.createTextChild(': ');
-    if (this._expandElement)
-      this.listItemElement.appendChild(this._expandElement);
-    this.listItemElement.appendChild(this.valueElement);
-    this.listItemElement.createTextChild(';');
-    if (this.property.disabled)
-      this.listItemElement.createChild('span', 'styles-clipboard-only').createTextChild(' */');
-
-    if (!this.property.parsedOk) {
-      // Avoid having longhands under an invalid shorthand.
-      this.listItemElement.classList.add('not-parsed-ok');
-
-      // Add a separate exclamation mark IMG element with a tooltip.
-      this.listItemElement.insertBefore(
-          Elements.StylesSidebarPane.createExclamationMark(this.property), this.listItemElement.firstChild);
-    }
-    if (!this.property.activeInStyle())
-      this.listItemElement.classList.add('inactive');
-    this._updateFilter();
-
-    if (this.property.parsedOk && this.section() && this.parent.root) {
-      const enabledCheckboxElement = createElement('input');
-      enabledCheckboxElement.className = 'enabled-button';
-      enabledCheckboxElement.type = 'checkbox';
-      enabledCheckboxElement.checked = !this.property.disabled;
-      enabledCheckboxElement.addEventListener('mousedown', event => event.consume(), false);
-      enabledCheckboxElement.addEventListener('click', this._toggleEnabled.bind(this), false);
-      this.listItemElement.insertBefore(enabledCheckboxElement, this.listItemElement.firstChild);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseUp(event) {
-    const activeTreeElement = this._parentPane[Elements.StylePropertyTreeElement.ActiveSymbol];
-    this._parentPane[Elements.StylePropertyTreeElement.ActiveSymbol] = null;
-    if (activeTreeElement !== this)
-      return;
-    if (this.listItemElement.hasSelection())
-      return;
-    if (UI.isBeingEdited(/** @type {!Node} */ (event.target)))
-      return;
-
-    event.consume(true);
-
-    if (event.target === this.listItemElement)
-      return;
-
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(/** @type {!MouseEvent} */ (event)) && this.section().navigable) {
-      this._navigateToSource(/** @type {!Element} */ (event.target));
-      return;
-    }
-
-    this.startEditing(/** @type {!Element} */ (event.target));
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {boolean=} omitFocus
-   */
-  _navigateToSource(element, omitFocus) {
-    if (!this.section().navigable)
-      return;
-    const propertyNameClicked = element === this.nameElement;
-    const uiLocation = Bindings.cssWorkspaceBinding.propertyUILocation(this.property, propertyNameClicked);
-    if (uiLocation)
-      Common.Revealer.reveal(uiLocation, omitFocus);
-  }
-
-  /**
-   * @param {?Element=} selectElement
-   */
-  startEditing(selectElement) {
-    // FIXME: we don't allow editing of longhand properties under a shorthand right now.
-    if (this.parent.isShorthand)
-      return;
-
-    if (this._expandElement && selectElement === this._expandElement)
-      return;
-
-    const section = this.section();
-    if (section && !section.editable)
-      return;
-
-    if (selectElement) {
-      selectElement = selectElement.enclosingNodeOrSelfWithClass('webkit-css-property') ||
-          selectElement.enclosingNodeOrSelfWithClass('value');
-    }
-    if (!selectElement)
-      selectElement = this.nameElement;
-
-    if (UI.isBeingEdited(selectElement))
-      return;
-
-    const isEditingName = selectElement === this.nameElement;
-    if (!isEditingName)
-      this.valueElement.textContent = restoreURLs(this.valueElement.textContent, this.value);
-
-    /**
-     * @param {string} fieldValue
-     * @param {string} modelValue
-     * @return {string}
-     */
-    function restoreURLs(fieldValue, modelValue) {
-      const urlRegex = /\b(url\([^)]*\))/g;
-      const splitFieldValue = fieldValue.split(urlRegex);
-      if (splitFieldValue.length === 1)
-        return fieldValue;
-      const modelUrlRegex = new RegExp(urlRegex);
-      for (let i = 1; i < splitFieldValue.length; i += 2) {
-        const match = modelUrlRegex.exec(modelValue);
-        if (match)
-          splitFieldValue[i] = match[0];
-      }
-      return splitFieldValue.join('');
-    }
-
-    /** @type {!Elements.StylePropertyTreeElement.Context} */
-    const context = {
-      expanded: this.expanded,
-      hasChildren: this.isExpandable(),
-      isEditingName: isEditingName,
-      previousContent: selectElement.textContent
-    };
-
-    // Lie about our children to prevent expanding on double click and to collapse shorthands.
-    this.setExpandable(false);
-
-    if (selectElement.parentElement)
-      selectElement.parentElement.classList.add('child-editing');
-    selectElement.textContent = selectElement.textContent;  // remove color swatch and the like
-
-    /**
-     * @param {!Elements.StylePropertyTreeElement.Context} context
-     * @param {!Event} event
-     * @this {Elements.StylePropertyTreeElement}
-     */
-    function pasteHandler(context, event) {
-      const data = event.clipboardData.getData('Text');
-      if (!data)
-        return;
-      const colonIdx = data.indexOf(':');
-      if (colonIdx < 0)
-        return;
-      const name = data.substring(0, colonIdx).trim();
-      const value = data.substring(colonIdx + 1).trim();
-
-      event.preventDefault();
-
-      if (!('originalName' in context)) {
-        context.originalName = this.nameElement.textContent;
-        context.originalValue = this.valueElement.textContent;
-      }
-      this.property.name = name;
-      this.property.value = value;
-      this.nameElement.textContent = name;
-      this.valueElement.textContent = value;
-      this.nameElement.normalize();
-      this.valueElement.normalize();
-
-      this._editingCommitted(event.target.textContent, context, 'forward');
-    }
-
-    /**
-     * @param {!Elements.StylePropertyTreeElement.Context} context
-     * @param {!Event} event
-     * @this {Elements.StylePropertyTreeElement}
-     */
-    function blurListener(context, event) {
-      let text = event.target.textContent;
-      if (!context.isEditingName)
-        text = this.value || text;
-      this._editingCommitted(text, context, '');
-    }
-
-    this._originalPropertyText = this.property.propertyText;
-
-    this._parentPane.setEditingStyle(true);
-    if (selectElement.parentElement)
-      selectElement.parentElement.scrollIntoViewIfNeeded(false);
-
-    let cssCompletions = [];
-    if (isEditingName) {
-      cssCompletions = SDK.cssMetadata().allProperties();
-      if (!this.node().isSVGNode())
-        cssCompletions = cssCompletions.filter(property => !SDK.cssMetadata().isSVGProperty(property));
-    } else {
-      cssCompletions = SDK.cssMetadata().propertyValues(this.nameElement.textContent);
-    }
-
-    const cssVariables = this._matchedStyles.availableCSSVariables(this.property.ownerStyle);
-    cssVariables.sort(String.naturalOrderComparator);
-
-    this._prompt = new Elements.StylesSidebarPane.CSSPropertyPrompt(cssCompletions, cssVariables, this, isEditingName);
-    this._prompt.setAutocompletionTimeout(0);
-    if (section)
-      section.startEditing();
-
-    // Do not live-edit "content" property of pseudo elements. crbug.com/433889
-    if (!isEditingName && (!this._parentPane.node().pseudoType() || this.name !== 'content'))
-      this._prompt.addEventListener(UI.TextPrompt.Events.TextChanged, this._applyFreeFlowStyleTextEdit.bind(this));
-
-    const proxyElement = this._prompt.attachAndStartEditing(selectElement, blurListener.bind(this, context));
-    this._navigateToSource(selectElement, true);
-
-    proxyElement.addEventListener('keydown', this._editingNameValueKeyDown.bind(this, context), false);
-    proxyElement.addEventListener('keypress', this._editingNameValueKeyPress.bind(this, context), false);
-    if (isEditingName)
-      proxyElement.addEventListener('paste', pasteHandler.bind(this, context), false);
-
-    selectElement.getComponentSelection().selectAllChildren(selectElement);
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement.Context} context
-   * @param {!Event} event
-   */
-  _editingNameValueKeyDown(context, event) {
-    if (event.handled)
-      return;
-
-    let result;
-
-    if (isEnterKey(event)) {
-      result = 'forward';
-    } else if (event.keyCode === UI.KeyboardShortcut.Keys.Esc.code || event.key === 'Escape') {
-      result = 'cancel';
-    } else if (
-        !context.isEditingName && this._newProperty && event.keyCode === UI.KeyboardShortcut.Keys.Backspace.code) {
-      // For a new property, when Backspace is pressed at the beginning of new property value, move back to the property name.
-      const selection = event.target.getComponentSelection();
-      if (selection.isCollapsed && !selection.focusOffset) {
-        event.preventDefault();
-        result = 'backward';
-      }
-    } else if (event.key === 'Tab') {
-      result = event.shiftKey ? 'backward' : 'forward';
-      event.preventDefault();
-    }
-
-    if (result) {
-      switch (result) {
-        case 'cancel':
-          this.editingCancelled(null, context);
-          break;
-        case 'forward':
-        case 'backward':
-          this._editingCommitted(event.target.textContent, context, result);
-          break;
-      }
-
-      event.consume();
-      return;
-    }
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement.Context} context
-   * @param {!Event} event
-   */
-  _editingNameValueKeyPress(context, event) {
-    /**
-     * @param {string} text
-     * @param {number} cursorPosition
-     * @return {boolean}
-     */
-    function shouldCommitValueSemicolon(text, cursorPosition) {
-      // FIXME: should this account for semicolons inside comments?
-      let openQuote = '';
-      for (let i = 0; i < cursorPosition; ++i) {
-        const ch = text[i];
-        if (ch === '\\' && openQuote !== '')
-          ++i;  // skip next character inside string
-        else if (!openQuote && (ch === '"' || ch === '\''))
-          openQuote = ch;
-        else if (openQuote === ch)
-          openQuote = '';
-      }
-      return !openQuote;
-    }
-
-    const keyChar = String.fromCharCode(event.charCode);
-    const isFieldInputTerminated =
-        (context.isEditingName ? keyChar === ':' :
-                                 keyChar === ';' &&
-                 shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset()));
-    if (isFieldInputTerminated) {
-      // Enter or colon (for name)/semicolon outside of string (for value).
-      event.consume(true);
-      this._editingCommitted(event.target.textContent, context, 'forward');
-      return;
-    }
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async _applyFreeFlowStyleTextEdit() {
-    const valueText = this._prompt.textWithCurrentSuggestion();
-    if (valueText.indexOf(';') === -1)
-      await this.applyStyleText(this.nameElement.textContent + ': ' + valueText, false);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  kickFreeFlowStyleEditForTest() {
-    return this._applyFreeFlowStyleTextEdit();
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement.Context} context
-   */
-  editingEnded(context) {
-    this.setExpandable(context.hasChildren);
-    if (context.expanded)
-      this.expand();
-    const editedElement = context.isEditingName ? this.nameElement : this.valueElement;
-    // The proxyElement has been deleted, no need to remove listener.
-    if (editedElement.parentElement)
-      editedElement.parentElement.classList.remove('child-editing');
-
-    this._parentPane.setEditingStyle(false);
-  }
-
-  /**
-   * @param {?Element} element
-   * @param {!Elements.StylePropertyTreeElement.Context} context
-   */
-  editingCancelled(element, context) {
-    this._removePrompt();
-    this._revertStyleUponEditingCanceled();
-    // This should happen last, as it clears the info necessary to restore the property value after [Page]Up/Down changes.
-    this.editingEnded(context);
-  }
-
-  _revertStyleUponEditingCanceled() {
-    if (this._propertyHasBeenEditedIncrementally) {
-      this.applyStyleText(this._originalPropertyText, false);
-      this._originalPropertyText = '';
-    } else if (this._newProperty) {
-      this.treeOutline.removeChild(this);
-    } else {
-      this.updateTitle();
-    }
-  }
-
-  /**
-   * @param {string} moveDirection
-   * @return {?Elements.StylePropertyTreeElement}
-   */
-  _findSibling(moveDirection) {
-    let target = this;
-    do
-      target = (moveDirection === 'forward' ? target.nextSibling : target.previousSibling);
-    while (target && target.inherited());
-
-    return target;
-  }
-
-  /**
-   * @param {string} userInput
-   * @param {!Elements.StylePropertyTreeElement.Context} context
-   * @param {string} moveDirection
-   */
-  async _editingCommitted(userInput, context, moveDirection) {
-    const hadFocus = this._parentPane.element.hasFocus();
-    this._removePrompt();
-    this.editingEnded(context);
-    const isEditingName = context.isEditingName;
-
-    // Determine where to move to before making changes
-    let createNewProperty, moveToSelector;
-    const isDataPasted = 'originalName' in context;
-    const isDirtyViaPaste = isDataPasted &&
-        (this.nameElement.textContent !== context.originalName ||
-         this.valueElement.textContent !== context.originalValue);
-    const isPropertySplitPaste =
-        isDataPasted && isEditingName && this.valueElement.textContent !== context.originalValue;
-    let moveTo = this;
-    const moveToOther = (isEditingName ^ (moveDirection === 'forward'));
-    const abandonNewProperty = this._newProperty && !userInput && (moveToOther || isEditingName);
-    if (moveDirection === 'forward' && (!isEditingName || isPropertySplitPaste) ||
-        moveDirection === 'backward' && isEditingName) {
-      moveTo = moveTo._findSibling(moveDirection);
-      if (!moveTo) {
-        if (moveDirection === 'forward' && (!this._newProperty || userInput))
-          createNewProperty = true;
-        else if (moveDirection === 'backward')
-          moveToSelector = true;
-      }
-    }
-
-    // Make the Changes and trigger the moveToNextCallback after updating.
-    let moveToIndex = moveTo && this.treeOutline ? this.treeOutline.rootElement().indexOfChild(moveTo) : -1;
-    const blankInput = userInput.isWhitespace();
-    const shouldCommitNewProperty = this._newProperty &&
-        (isPropertySplitPaste || moveToOther || (!moveDirection && !isEditingName) || (isEditingName && blankInput));
-    const section = /** @type {!Elements.StylePropertiesSection} */ (this.section());
-    if (((userInput !== context.previousContent || isDirtyViaPaste) && !this._newProperty) || shouldCommitNewProperty) {
-      if (hadFocus)
-        this._parentPane.element.focus();
-      let propertyText;
-      if (blankInput || (this._newProperty && this.valueElement.textContent.isWhitespace())) {
-        propertyText = '';
-      } else {
-        if (isEditingName)
-          propertyText = userInput + ': ' + this.property.value;
-        else
-          propertyText = this.property.name + ': ' + userInput;
-      }
-      await this.applyStyleText(propertyText, true);
-      moveToNextCallback.call(this, this._newProperty, !blankInput, section);
-    } else {
-      if (isEditingName)
-        this.property.name = userInput;
-      else
-        this.property.value = userInput;
-      if (!isDataPasted && !this._newProperty)
-        this.updateTitle();
-      moveToNextCallback.call(this, this._newProperty, false, section);
-    }
-
-    /**
-     * The Callback to start editing the next/previous property/selector.
-     * @param {boolean} alreadyNew
-     * @param {boolean} valueChanged
-     * @param {!Elements.StylePropertiesSection} section
-     * @this {Elements.StylePropertyTreeElement}
-     */
-    function moveToNextCallback(alreadyNew, valueChanged, section) {
-      if (!moveDirection)
-        return;
-
-      // User just tabbed through without changes.
-      if (moveTo && moveTo.parent) {
-        moveTo.startEditing(!isEditingName ? moveTo.nameElement : moveTo.valueElement);
-        return;
-      }
-
-      // User has made a change then tabbed, wiping all the original treeElements.
-      // Recalculate the new treeElement for the same property we were going to edit next.
-      if (moveTo && !moveTo.parent) {
-        const rootElement = section.propertiesTreeOutline.rootElement();
-        if (moveDirection === 'forward' && blankInput && !isEditingName)
-          --moveToIndex;
-        if (moveToIndex >= rootElement.childCount() && !this._newProperty) {
-          createNewProperty = true;
-        } else {
-          const treeElement = moveToIndex >= 0 ? rootElement.childAt(moveToIndex) : null;
-          if (treeElement) {
-            let elementToEdit =
-                !isEditingName || isPropertySplitPaste ? treeElement.nameElement : treeElement.valueElement;
-            if (alreadyNew && blankInput)
-              elementToEdit = moveDirection === 'forward' ? treeElement.nameElement : treeElement.valueElement;
-            treeElement.startEditing(elementToEdit);
-            return;
-          } else if (!alreadyNew) {
-            moveToSelector = true;
-          }
-        }
-      }
-
-      // Create a new attribute in this section (or move to next editable selector if possible).
-      if (createNewProperty) {
-        if (alreadyNew && !valueChanged && (isEditingName ^ (moveDirection === 'backward')))
-          return;
-
-        section.addNewBlankProperty().startEditing();
-        return;
-      }
-
-      if (abandonNewProperty) {
-        moveTo = this._findSibling(moveDirection);
-        const sectionToEdit = (moveTo || moveDirection === 'backward') ? section : section.nextEditableSibling();
-        if (sectionToEdit) {
-          if (sectionToEdit.style().parentRule)
-            sectionToEdit.startEditingSelector();
-          else
-            sectionToEdit.moveEditorFromSelector(moveDirection);
-        }
-        return;
-      }
-
-      if (moveToSelector) {
-        if (section.style().parentRule)
-          section.startEditingSelector();
-        else
-          section.moveEditorFromSelector(moveDirection);
-      }
-    }
-  }
-
-  _removePrompt() {
-    // BUG 53242. This cannot go into editingEnded(), as it should always happen first for any editing outcome.
-    if (this._prompt) {
-      this._prompt.detach();
-      this._prompt = null;
-    }
-    const section = this.section();
-    if (section)
-      section.stopEditing();
-  }
-
-  styleTextAppliedForTest() {
-  }
-
-  /**
-   * @param {string} styleText
-   * @param {boolean} majorChange
-   * @return {!Promise}
-   */
-  applyStyleText(styleText, majorChange) {
-    return this._applyStyleThrottler.schedule(this._innerApplyStyleText.bind(this, styleText, majorChange));
-  }
-
-  /**
-   * @param {string} styleText
-   * @param {boolean} majorChange
-   * @return {!Promise}
-   */
-  async _innerApplyStyleText(styleText, majorChange) {
-    if (!this.treeOutline)
-      return;
-
-    const oldStyleRange = this._style.range;
-    if (!oldStyleRange)
-      return;
-
-    styleText = styleText.replace(/\s/g, ' ').trim();  // Replace &nbsp; with whitespace.
-    if (!styleText.length && majorChange && this._newProperty && !this._propertyHasBeenEditedIncrementally) {
-      // The user deleted everything and never applied a new property value via Up/Down scrolling/live editing, so remove the tree element and update.
-      this.parent.removeChild(this);
-      return;
-    }
-
-    const currentNode = this._parentPane.node();
-    this._parentPane.setUserOperation(true);
-
-    // Append a ";" if the new text does not end in ";".
-    // FIXME: this does not handle trailing comments.
-    if (styleText.length && !/;\s*$/.test(styleText))
-      styleText += ';';
-    const overwriteProperty = !this._newProperty || this._propertyHasBeenEditedIncrementally;
-    let success = await this.property.setText(styleText, majorChange, overwriteProperty);
-    // Revert to the original text if applying the new text failed
-    if (this._propertyHasBeenEditedIncrementally && majorChange && !success) {
-      majorChange = false;
-      success = await this.property.setText(this._originalPropertyText, majorChange, overwriteProperty);
-    }
-    this._parentPane.setUserOperation(false);
-
-    if (!success) {
-      if (majorChange) {
-        // It did not apply, cancel editing.
-        if (this._newProperty)
-          this.treeOutline.removeChild(this);
-        else
-          this.updateTitle();
-      }
-      this.styleTextAppliedForTest();
-      return;
-    }
-
-    this._matchedStyles.resetActiveProperties();
-    this._propertyHasBeenEditedIncrementally = true;
-    this.property = this._style.propertyAt(this.property.index);
-
-    if (currentNode === this.node())
-      this._updatePane();
-
-    this.styleTextAppliedForTest();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondblclick() {
-    return true;  // handled
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  isEventWithinDisclosureTriangle(event) {
-    return event.target === this._expandElement;
-  }
-};
-
-/** @typedef {{expanded: boolean, hasChildren: boolean, isEditingName: boolean, previousContent: string}} */
-Elements.StylePropertyTreeElement.Context;
-Elements.StylePropertyTreeElement.ActiveSymbol = Symbol('ActiveSymbol');
diff --git a/front_end/elements/StylesSidebarPane.js b/front_end/elements/StylesSidebarPane.js
deleted file mode 100644
index 7e03c2f..0000000
--- a/front_end/elements/StylesSidebarPane.js
+++ /dev/null
@@ -1,2408 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Elements.StylesSidebarPane = class extends Elements.ElementsSidebarPane {
-  constructor() {
-    super();
-    this.setMinimumSize(96, 26);
-    this.registerRequiredCSS('elements/stylesSidebarPane.css');
-    this.element.tabIndex = -1;
-
-    Common.moduleSetting('colorFormat').addChangeListener(this.update.bind(this));
-    Common.moduleSetting('textEditorIndent').addChangeListener(this.update.bind(this));
-
-    /** @type {?UI.Widget} */
-    this._currentToolbarPane = null;
-    /** @type {?UI.Widget} */
-    this._animatedToolbarPane = null;
-    /** @type {?UI.Widget} */
-    this._pendingWidget = null;
-    /** @type {?UI.ToolbarToggle} */
-    this._pendingWidgetToggle = null;
-    this._toolbarPaneElement = this._createStylesSidebarToolbar();
-
-    this._sectionsContainer = this.contentElement.createChild('div');
-    UI.ARIAUtils.markAsTree(this._sectionsContainer);
-    this._sectionsContainer.addEventListener('keydown', this._sectionsContainerKeyDown.bind(this), false);
-    this._sectionsContainer.addEventListener('focusin', this._sectionsContainerFocusChanged.bind(this), false);
-    this._sectionsContainer.addEventListener('focusout', this._sectionsContainerFocusChanged.bind(this), false);
-
-    this._swatchPopoverHelper = new InlineEditor.SwatchPopoverHelper();
-    this._linkifier = new Components.Linkifier(Elements.StylesSidebarPane._maxLinkLength, /* useLinkDecorator */ true);
-    /** @type {?Elements.StylePropertyHighlighter} */
-    this._decorator = null;
-    this._userOperation = false;
-    this._isEditingStyle = false;
-    /** @type {?RegExp} */
-    this._filterRegex = null;
-
-    this.contentElement.classList.add('styles-pane');
-
-    /** @type {!Array<!Elements.SectionBlock>} */
-    this._sectionBlocks = [];
-    Elements.StylesSidebarPane._instance = this;
-    UI.context.addFlavorChangeListener(SDK.DOMNode, this.forceUpdate, this);
-    this.contentElement.addEventListener('copy', this._clipboardCopy.bind(this));
-    this._resizeThrottler = new Common.Throttler(100);
-  }
-
-  /**
-   * @return {!InlineEditor.SwatchPopoverHelper}
-   */
-  swatchPopoverHelper() {
-    return this._swatchPopoverHelper;
-  }
-
-  /**
-   * @param {boolean} userOperation
-   */
-  setUserOperation(userOperation) {
-    this._userOperation = userOperation;
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} property
-   * @return {!Element}
-   */
-  static createExclamationMark(property) {
-    const exclamationElement = createElement('label', 'dt-icon-label');
-    exclamationElement.className = 'exclamation-mark';
-    if (!Elements.StylesSidebarPane.ignoreErrorsForProperty(property))
-      exclamationElement.type = 'smallicon-warning';
-    exclamationElement.title = SDK.cssMetadata().isCSSPropertyName(property.name) ?
-        Common.UIString('Invalid property value') :
-        Common.UIString('Unknown property name');
-    return exclamationElement;
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} property
-   * @return {boolean}
-   */
-  static ignoreErrorsForProperty(property) {
-    /**
-     * @param {string} string
-     */
-    function hasUnknownVendorPrefix(string) {
-      return !string.startsWith('-webkit-') && /^[-_][\w\d]+-\w/.test(string);
-    }
-
-    const name = property.name.toLowerCase();
-
-    // IE hack.
-    if (name.charAt(0) === '_')
-      return true;
-
-    // IE has a different format for this.
-    if (name === 'filter')
-      return true;
-
-    // Common IE-specific property prefix.
-    if (name.startsWith('scrollbar-'))
-      return true;
-    if (hasUnknownVendorPrefix(name))
-      return true;
-
-    const value = property.value.toLowerCase();
-
-    // IE hack.
-    if (value.endsWith('\\9'))
-      return true;
-    if (hasUnknownVendorPrefix(value))
-      return true;
-
-    return false;
-  }
-
-  /**
-   * @param {string} placeholder
-   * @param {!Element} container
-   * @param {function(?RegExp)} filterCallback
-   * @param {string} activeClassName
-   * @return {!Element}
-   */
-  static createPropertyFilterElement(placeholder, container, filterCallback, activeClassName) {
-    const input = createElementWithClass('input');
-    input.placeholder = placeholder;
-
-    function searchHandler() {
-      const regex = input.value ? new RegExp(input.value.escapeForRegExp(), 'i') : null;
-      filterCallback(regex);
-      container.classList.toggle(activeClassName, !!input.value);
-    }
-    input.addEventListener('input', searchHandler, false);
-
-    /**
-     * @param {!Event} event
-     */
-    function keydownHandler(event) {
-      if (event.key !== 'Escape' || !input.value)
-        return;
-      event.consume(true);
-      input.value = '';
-      searchHandler();
-    }
-    input.addEventListener('keydown', keydownHandler, false);
-
-    input.setFilterValue = setFilterValue;
-
-    /**
-     * @param {string} value
-     */
-    function setFilterValue(value) {
-      input.value = value;
-      input.focus();
-      searchHandler();
-    }
-
-    return input;
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} cssProperty
-   */
-  revealProperty(cssProperty) {
-    this._decorator = new Elements.StylePropertyHighlighter(this, cssProperty);
-    this._decorator.perform();
-    this.update();
-  }
-
-  forceUpdate() {
-    this._swatchPopoverHelper.hide();
-    this._resetCache();
-    this.update();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _sectionsContainerKeyDown(event) {
-    const activeElement = this._sectionsContainer.ownerDocument.deepActiveElement();
-    if (!activeElement)
-      return;
-    const section = activeElement._section;
-    if (!section)
-      return;
-
-    switch (event.key) {
-      case 'ArrowUp':
-      case 'ArrowLeft':
-        const sectionToFocus = section.previousSibling() || section.lastSibling();
-        sectionToFocus.element.focus();
-        event.consume(true);
-        break;
-      case 'ArrowDown':
-      case 'ArrowRight': {
-        const sectionToFocus = section.nextSibling() || section.firstSibling();
-        sectionToFocus.element.focus();
-        event.consume(true);
-        break;
-      }
-      case 'Home':
-        section.firstSibling().element.focus();
-        event.consume(true);
-        break;
-      case 'End':
-        section.lastSibling().element.focus();
-        event.consume(true);
-        break;
-    }
-  }
-
-  _sectionsContainerFocusChanged() {
-    // When a styles section is focused, shift+tab should leave the section.
-    // Leaving tabIndex = 0 on the first element would cause it to be focused instead.
-    if (this._sectionBlocks[0] && this._sectionBlocks[0].sections[0])
-      this._sectionBlocks[0].sections[0].element.tabIndex = this._sectionsContainer.hasFocus() ? -1 : 0;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onAddButtonLongClick(event) {
-    const cssModel = this.cssModel();
-    if (!cssModel)
-      return;
-    const headers = cssModel.styleSheetHeaders().filter(styleSheetResourceHeader);
-
-    /** @type {!Array.<{text: string, handler: function()}>} */
-    const contextMenuDescriptors = [];
-    for (let i = 0; i < headers.length; ++i) {
-      const header = headers[i];
-      const handler = this._createNewRuleInStyleSheet.bind(this, header);
-      contextMenuDescriptors.push({text: Bindings.displayNameForURL(header.resourceURL()), handler: handler});
-    }
-
-    contextMenuDescriptors.sort(compareDescriptors);
-
-    const contextMenu = new UI.ContextMenu(event);
-    for (let i = 0; i < contextMenuDescriptors.length; ++i) {
-      const descriptor = contextMenuDescriptors[i];
-      contextMenu.defaultSection().appendItem(descriptor.text, descriptor.handler);
-    }
-    contextMenu.footerSection().appendItem(
-        'inspector-stylesheet', this._createNewRuleInViaInspectorStyleSheet.bind(this));
-    contextMenu.show();
-
-    /**
-     * @param {!{text: string, handler: function()}} descriptor1
-     * @param {!{text: string, handler: function()}} descriptor2
-     * @return {number}
-     */
-    function compareDescriptors(descriptor1, descriptor2) {
-      return String.naturalOrderComparator(descriptor1.text, descriptor2.text);
-    }
-
-    /**
-     * @param {!SDK.CSSStyleSheetHeader} header
-     * @return {boolean}
-     */
-    function styleSheetResourceHeader(header) {
-      return !header.isViaInspector() && !header.isInline && !!header.resourceURL();
-    }
-  }
-
-  /**
-   * @param {?RegExp} regex
-   */
-  _onFilterChanged(regex) {
-    this._filterRegex = regex;
-    this._updateFilter();
-  }
-
-  /**
-   * @param {!Elements.StylePropertiesSection} editedSection
-   * @param {!Elements.StylePropertyTreeElement=} editedTreeElement
-   */
-  _refreshUpdate(editedSection, editedTreeElement) {
-    if (editedTreeElement) {
-      for (const section of this.allSections()) {
-        if (section.isBlank)
-          continue;
-        section._updateVarFunctions(editedTreeElement);
-      }
-    }
-
-    if (this._isEditingStyle)
-      return;
-    const node = this.node();
-    if (!node)
-      return;
-
-    for (const section of this.allSections()) {
-      if (section.isBlank)
-        continue;
-      section.update(section === editedSection);
-    }
-
-    if (this._filterRegex)
-      this._updateFilter();
-    this._nodeStylesUpdatedForTest(node, false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    return this._fetchMatchedCascade().then(this._innerRebuildUpdate.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._resizeThrottler.schedule(this._innerResize.bind(this));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _innerResize() {
-    const width = this.contentElement.getBoundingClientRect().width + 'px';
-    this.allSections().forEach(section => section.propertiesTreeOutline.element.style.width = width);
-    return Promise.resolve();
-  }
-
-  _resetCache() {
-    if (this.cssModel())
-      this.cssModel().discardCachedMatchedCascade();
-  }
-
-  /**
-   * @return {!Promise.<?SDK.CSSMatchedStyles>}
-   */
-  _fetchMatchedCascade() {
-    const node = this.node();
-    if (!node || !this.cssModel())
-      return Promise.resolve(/** @type {?SDK.CSSMatchedStyles} */ (null));
-
-    return this.cssModel().cachedMatchedCascadeForNode(node).then(validateStyles.bind(this));
-
-    /**
-     * @param {?SDK.CSSMatchedStyles} matchedStyles
-     * @return {?SDK.CSSMatchedStyles}
-     * @this {Elements.StylesSidebarPane}
-     */
-    function validateStyles(matchedStyles) {
-      return matchedStyles && matchedStyles.node() === this.node() ? matchedStyles : null;
-    }
-  }
-
-  /**
-   * @param {boolean} editing
-   */
-  setEditingStyle(editing) {
-    if (this._isEditingStyle === editing)
-      return;
-    this.contentElement.classList.toggle('is-editing-style', editing);
-    this._isEditingStyle = editing;
-  }
-
-  /**
-   * @override
-   * @param {!Common.Event=} event
-   */
-  onCSSModelChanged(event) {
-    const edit = event && event.data ? /** @type {?SDK.CSSModel.Edit} */ (event.data.edit) : null;
-    if (edit) {
-      for (const section of this.allSections())
-        section._styleSheetEdited(edit);
-      return;
-    }
-
-    if (this._userOperation || this._isEditingStyle)
-      return;
-
-    this._resetCache();
-    this.update();
-  }
-
-  /**
-   * @return {number}
-   */
-  _focusedSectionIndex() {
-    let index = 0;
-    for (const block of this._sectionBlocks) {
-      for (const section of block.sections) {
-        if (section.element.hasFocus())
-          return index;
-        index++;
-      }
-    }
-    return -1;
-  }
-
-  /**
-   * @param {?SDK.CSSMatchedStyles} matchedStyles
-   * @return {!Promise}
-   */
-  async _innerRebuildUpdate(matchedStyles) {
-    const focusedIndex = this._focusedSectionIndex();
-
-    this._linkifier.reset();
-    this._sectionsContainer.removeChildren();
-    this._sectionBlocks = [];
-
-    const node = this.node();
-    if (!matchedStyles || !node)
-      return;
-
-    this._sectionBlocks =
-        await this._rebuildSectionsForMatchedStyleRules(/** @type {!SDK.CSSMatchedStyles} */ (matchedStyles));
-    let pseudoTypes = [];
-    const keys = matchedStyles.pseudoTypes();
-    if (keys.delete(Protocol.DOM.PseudoType.Before))
-      pseudoTypes.push(Protocol.DOM.PseudoType.Before);
-    pseudoTypes = pseudoTypes.concat(keys.valuesArray().sort());
-    for (const pseudoType of pseudoTypes) {
-      const block = Elements.SectionBlock.createPseudoTypeBlock(pseudoType);
-      for (const style of matchedStyles.pseudoStyles(pseudoType)) {
-        const section = new Elements.StylePropertiesSection(this, matchedStyles, style);
-        block.sections.push(section);
-      }
-      this._sectionBlocks.push(block);
-    }
-
-    for (const keyframesRule of matchedStyles.keyframes()) {
-      const block = Elements.SectionBlock.createKeyframesBlock(keyframesRule.name().text);
-      for (const keyframe of keyframesRule.keyframes())
-        block.sections.push(new Elements.KeyframePropertiesSection(this, matchedStyles, keyframe.style));
-      this._sectionBlocks.push(block);
-    }
-    let index = 0;
-    for (const block of this._sectionBlocks) {
-      const titleElement = block.titleElement();
-      if (titleElement)
-        this._sectionsContainer.appendChild(titleElement);
-      for (const section of block.sections) {
-        this._sectionsContainer.appendChild(section.element);
-        if (index === focusedIndex)
-          section.element.focus();
-        index++;
-      }
-    }
-    if (focusedIndex >= index)
-      this._sectionBlocks[0].sections[0].element.focus();
-
-    this._sectionsContainerFocusChanged();
-
-    if (this._filterRegex)
-      this._updateFilter();
-
-    this._nodeStylesUpdatedForTest(/** @type {!SDK.DOMNode} */ (node), true);
-    if (this._decorator) {
-      this._decorator.perform();
-      this._decorator = null;
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {boolean} rebuild
-   */
-  _nodeStylesUpdatedForTest(node, rebuild) {
-    // For sniffing in tests.
-  }
-
-  /**
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @return {!Promise<!Array.<!Elements.SectionBlock>>}
-   */
-  async _rebuildSectionsForMatchedStyleRules(matchedStyles) {
-    const blocks = [new Elements.SectionBlock(null)];
-    let lastParentNode = null;
-    for (const style of matchedStyles.nodeStyles()) {
-      const parentNode = matchedStyles.isInherited(style) ? matchedStyles.nodeForStyle(style) : null;
-      if (parentNode && parentNode !== lastParentNode) {
-        lastParentNode = parentNode;
-        const block = await Elements.SectionBlock._createInheritedNodeBlock(lastParentNode);
-        blocks.push(block);
-      }
-      const section = new Elements.StylePropertiesSection(this, matchedStyles, style);
-      blocks.peekLast().sections.push(section);
-    }
-    return blocks;
-  }
-
-  async _createNewRuleInViaInspectorStyleSheet() {
-    const cssModel = this.cssModel();
-    const node = this.node();
-    if (!cssModel || !node)
-      return;
-    this.setUserOperation(true);
-
-    const styleSheetHeader = await cssModel.requestViaInspectorStylesheet(/** @type {!SDK.DOMNode} */ (node));
-
-    this.setUserOperation(false);
-    await this._createNewRuleInStyleSheet(styleSheetHeader);
-  }
-
-  /**
-   * @param {?SDK.CSSStyleSheetHeader} styleSheetHeader
-   */
-  async _createNewRuleInStyleSheet(styleSheetHeader) {
-    if (!styleSheetHeader)
-      return;
-    const text = await styleSheetHeader.requestContent() || '';
-    const lines = text.split('\n');
-    const range = TextUtils.TextRange.createFromLocation(lines.length - 1, lines[lines.length - 1].length);
-    this._addBlankSection(this._sectionBlocks[0].sections[0], styleSheetHeader.id, range);
-  }
-
-  /**
-   * @param {!Elements.StylePropertiesSection} insertAfterSection
-   * @param {string} styleSheetId
-   * @param {!TextUtils.TextRange} ruleLocation
-   */
-  _addBlankSection(insertAfterSection, styleSheetId, ruleLocation) {
-    const node = this.node();
-    const blankSection = new Elements.BlankStylePropertiesSection(
-        this, insertAfterSection._matchedStyles, node ? node.simpleSelector() : '', styleSheetId, ruleLocation,
-        insertAfterSection._style);
-
-    this._sectionsContainer.insertBefore(blankSection.element, insertAfterSection.element.nextSibling);
-
-    for (const block of this._sectionBlocks) {
-      const index = block.sections.indexOf(insertAfterSection);
-      if (index === -1)
-        continue;
-      block.sections.splice(index + 1, 0, blankSection);
-      blankSection.startEditingSelector();
-    }
-  }
-
-  /**
-   * @param {!Elements.StylePropertiesSection} section
-   */
-  removeSection(section) {
-    for (const block of this._sectionBlocks) {
-      const index = block.sections.indexOf(section);
-      if (index === -1)
-        continue;
-      block.sections.splice(index, 1);
-      section.element.remove();
-    }
-  }
-
-  /**
-   * @return {?RegExp}
-   */
-  filterRegex() {
-    return this._filterRegex;
-  }
-
-  _updateFilter() {
-    for (const block of this._sectionBlocks)
-      block.updateFilter();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._swatchPopoverHelper.hide();
-    super.willHide();
-  }
-
-  /**
-   * @return {!Array<!Elements.StylePropertiesSection>}
-   */
-  allSections() {
-    let sections = [];
-    for (const block of this._sectionBlocks)
-      sections = sections.concat(block.sections);
-    return sections;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _clipboardCopy(event) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleCopied);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _createStylesSidebarToolbar() {
-    const container = this.contentElement.createChild('div', 'styles-sidebar-pane-toolbar-container');
-    const hbox = container.createChild('div', 'hbox styles-sidebar-pane-toolbar');
-    const filterContainerElement = hbox.createChild('div', 'styles-sidebar-pane-filter-box');
-    const filterInput = Elements.StylesSidebarPane.createPropertyFilterElement(
-        Common.UIString('Filter'), hbox, this._onFilterChanged.bind(this), 'styles-filter-engaged');
-    UI.ARIAUtils.setAccessibleName(filterInput, Common.UIString('Filter Styles'));
-    filterContainerElement.appendChild(filterInput);
-    const toolbar = new UI.Toolbar('styles-pane-toolbar', hbox);
-    toolbar.makeToggledGray();
-    toolbar.appendLocationItems('styles-sidebarpane-toolbar');
-    const toolbarPaneContainer = container.createChild('div', 'styles-sidebar-toolbar-pane-container');
-    const toolbarPaneContent = toolbarPaneContainer.createChild('div', 'styles-sidebar-toolbar-pane');
-
-    return toolbarPaneContent;
-  }
-
-  /**
-   * @param {?UI.Widget} widget
-   * @param {?UI.ToolbarToggle} toggle
-   */
-  showToolbarPane(widget, toggle) {
-    if (this._pendingWidgetToggle)
-      this._pendingWidgetToggle.setToggled(false);
-    this._pendingWidgetToggle = toggle;
-
-    if (this._animatedToolbarPane)
-      this._pendingWidget = widget;
-    else
-      this._startToolbarPaneAnimation(widget);
-
-    if (widget && toggle)
-      toggle.setToggled(true);
-  }
-
-  /**
-   * @param {?UI.Widget} widget
-   */
-  _startToolbarPaneAnimation(widget) {
-    if (widget === this._currentToolbarPane)
-      return;
-
-    if (widget && this._currentToolbarPane) {
-      this._currentToolbarPane.detach();
-      widget.show(this._toolbarPaneElement);
-      this._currentToolbarPane = widget;
-      this._currentToolbarPane.focus();
-      return;
-    }
-
-    this._animatedToolbarPane = widget;
-
-    if (this._currentToolbarPane)
-      this._toolbarPaneElement.style.animationName = 'styles-element-state-pane-slideout';
-    else if (widget)
-      this._toolbarPaneElement.style.animationName = 'styles-element-state-pane-slidein';
-
-    if (widget)
-      widget.show(this._toolbarPaneElement);
-
-    const listener = onAnimationEnd.bind(this);
-    this._toolbarPaneElement.addEventListener('animationend', listener, false);
-
-    /**
-     * @this {!Elements.StylesSidebarPane}
-     */
-    function onAnimationEnd() {
-      this._toolbarPaneElement.style.removeProperty('animation-name');
-      this._toolbarPaneElement.removeEventListener('animationend', listener, false);
-
-      if (this._currentToolbarPane)
-        this._currentToolbarPane.detach();
-
-      this._currentToolbarPane = this._animatedToolbarPane;
-      if (this._currentToolbarPane)
-        this._currentToolbarPane.focus();
-      this._animatedToolbarPane = null;
-
-      if (this._pendingWidget) {
-        this._startToolbarPaneAnimation(this._pendingWidget);
-        this._pendingWidget = null;
-      }
-    }
-  }
-};
-
-Elements.StylesSidebarPane._maxLinkLength = 30;
-
-Elements.SectionBlock = class {
-  /**
-   * @param {?Element} titleElement
-   */
-  constructor(titleElement) {
-    this._titleElement = titleElement;
-    this.sections = [];
-  }
-
-  /**
-   * @param {!Protocol.DOM.PseudoType} pseudoType
-   * @return {!Elements.SectionBlock}
-   */
-  static createPseudoTypeBlock(pseudoType) {
-    const separatorElement = createElement('div');
-    separatorElement.className = 'sidebar-separator';
-    separatorElement.textContent = Common.UIString('Pseudo ::%s element', pseudoType);
-    return new Elements.SectionBlock(separatorElement);
-  }
-
-  /**
-   * @param {string} keyframesName
-   * @return {!Elements.SectionBlock}
-   */
-  static createKeyframesBlock(keyframesName) {
-    const separatorElement = createElement('div');
-    separatorElement.className = 'sidebar-separator';
-    separatorElement.textContent = Common.UIString('@keyframes ' + keyframesName);
-    return new Elements.SectionBlock(separatorElement);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise<!Elements.SectionBlock>}
-   */
-  static async _createInheritedNodeBlock(node) {
-    const separatorElement = createElement('div');
-    separatorElement.className = 'sidebar-separator';
-    separatorElement.createTextChild(Common.UIString('Inherited from') + ' ');
-    const link = await Common.Linkifier.linkify(node);
-    separatorElement.appendChild(link);
-    return new Elements.SectionBlock(separatorElement);
-  }
-
-  updateFilter() {
-    let hasAnyVisibleSection = false;
-    for (const section of this.sections)
-      hasAnyVisibleSection |= section._updateFilter();
-    if (this._titleElement)
-      this._titleElement.classList.toggle('hidden', !hasAnyVisibleSection);
-  }
-
-  /**
-   * @return {?Element}
-   */
-  titleElement() {
-    return this._titleElement;
-  }
-};
-
-Elements.StylePropertiesSection = class {
-  /**
-   * @param {!Elements.StylesSidebarPane} parentPane
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {!SDK.CSSStyleDeclaration} style
-   */
-  constructor(parentPane, matchedStyles, style) {
-    this._parentPane = parentPane;
-    this._style = style;
-    this._matchedStyles = matchedStyles;
-    this.editable = !!(style.styleSheetId && style.range);
-    /** @type {?number} */
-    this._hoverTimer = null;
-    this._willCauseCancelEditing = false;
-    this._forceShowAll = false;
-    this._originalPropertiesCount = style.leadingProperties().length;
-
-    const rule = style.parentRule;
-    this.element = createElementWithClass('div', 'styles-section matched-styles monospace');
-    this.element.tabIndex = -1;
-    UI.ARIAUtils.markAsTreeitem(this.element);
-    this._editing = false;
-    this.element.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    this.element._section = this;
-    this._innerElement = this.element.createChild('div');
-
-    this._titleElement = this._innerElement.createChild('div', 'styles-section-title ' + (rule ? 'styles-selector' : ''));
-
-    this.propertiesTreeOutline = new UI.TreeOutlineInShadow();
-    this.propertiesTreeOutline.setFocusable(false);
-    this.propertiesTreeOutline.registerRequiredCSS('elements/stylesSectionTree.css');
-    this.propertiesTreeOutline.element.classList.add('style-properties', 'matched-styles', 'monospace');
-    this.propertiesTreeOutline.section = this;
-    this._innerElement.appendChild(this.propertiesTreeOutline.element);
-
-    this._showAllButton = UI.createTextButton('', this._showAllItems.bind(this), 'styles-show-all');
-    this._innerElement.appendChild(this._showAllButton);
-
-    const selectorContainer = createElement('div');
-    this._selectorElement = createElementWithClass('span', 'selector');
-    this._selectorElement.textContent = this._headerText();
-    selectorContainer.appendChild(this._selectorElement);
-    this._selectorElement.addEventListener('mouseenter', this._onMouseEnterSelector.bind(this), false);
-    this._selectorElement.addEventListener('mouseleave', this._onMouseOutSelector.bind(this), false);
-
-    const openBrace = createElement('span');
-    openBrace.textContent = ' {';
-    selectorContainer.appendChild(openBrace);
-    selectorContainer.addEventListener('mousedown', this._handleEmptySpaceMouseDown.bind(this), false);
-    selectorContainer.addEventListener('click', this._handleSelectorContainerClick.bind(this), false);
-
-    const closeBrace = this._innerElement.createChild('div', 'sidebar-pane-closing-brace');
-    closeBrace.textContent = '}';
-
-    this._createHoverMenuToolbar(closeBrace);
-
-    this._selectorElement.addEventListener('click', this._handleSelectorClick.bind(this), false);
-    this.element.addEventListener('mousedown', this._handleEmptySpaceMouseDown.bind(this), false);
-    this.element.addEventListener('click', this._handleEmptySpaceClick.bind(this), false);
-    this.element.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    this.element.addEventListener('mouseleave', this._setSectionHovered.bind(this, false), false);
-
-    if (rule) {
-      // Prevent editing the user agent and user rules.
-      if (rule.isUserAgent() || rule.isInjected()) {
-        this.editable = false;
-      } else {
-        // Check this is a real CSSRule, not a bogus object coming from Elements.BlankStylePropertiesSection.
-        if (rule.styleSheetId) {
-          const header = rule.cssModel().styleSheetHeaderForId(rule.styleSheetId);
-          this.navigable = !header.isAnonymousInlineStyleSheet();
-        }
-      }
-    }
-
-    this._mediaListElement = this._titleElement.createChild('div', 'media-list media-matches');
-    this._selectorRefElement = this._titleElement.createChild('div', 'styles-section-subtitle');
-    this._updateMediaList();
-    this._updateRuleOrigin();
-    this._titleElement.appendChild(selectorContainer);
-    this._selectorContainer = selectorContainer;
-
-    if (this.navigable)
-      this.element.classList.add('navigable');
-
-    if (!this.editable) {
-      this.element.classList.add('read-only');
-      this.propertiesTreeOutline.element.classList.add('read-only');
-    }
-
-    const throttler = new Common.Throttler(100);
-    this._scheduleHeightUpdate = () => throttler.schedule(this._manuallySetHeight.bind(this));
-
-    this._hoverableSelectorsMode = false;
-    this._markSelectorMatches();
-    this.onpopulate();
-  }
-
-  /**
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {!Components.Linkifier} linkifier
-   * @param {?SDK.CSSRule} rule
-   * @return {!Node}
-   */
-  static createRuleOriginNode(matchedStyles, linkifier, rule) {
-    if (!rule)
-      return createTextNode('');
-
-    let ruleLocation;
-    if (rule instanceof SDK.CSSStyleRule)
-      ruleLocation = rule.style.range;
-    else if (rule instanceof SDK.CSSKeyframeRule)
-      ruleLocation = rule.key().range;
-
-    const header = rule.styleSheetId ? matchedStyles.cssModel().styleSheetHeaderForId(rule.styleSheetId) : null;
-    if (ruleLocation && rule.styleSheetId && header && !header.isAnonymousInlineStyleSheet()) {
-      return Elements.StylePropertiesSection._linkifyRuleLocation(
-          matchedStyles.cssModel(), linkifier, rule.styleSheetId, ruleLocation);
-    }
-
-    if (rule.isUserAgent())
-      return createTextNode(Common.UIString('user agent stylesheet'));
-    if (rule.isInjected())
-      return createTextNode(Common.UIString('injected stylesheet'));
-    if (rule.isViaInspector())
-      return createTextNode(Common.UIString('via inspector'));
-
-    if (header && header.ownerNode) {
-      const link = Elements.DOMLinkifier.linkifyDeferredNodeReference(header.ownerNode);
-      link.textContent = '<style>…</style>';
-      return link;
-    }
-
-    return createTextNode('');
-  }
-
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Components.Linkifier} linkifier
-   * @param {string} styleSheetId
-   * @param {!TextUtils.TextRange} ruleLocation
-   * @return {!Node}
-   */
-  static _linkifyRuleLocation(cssModel, linkifier, styleSheetId, ruleLocation) {
-    const styleSheetHeader = cssModel.styleSheetHeaderForId(styleSheetId);
-    const lineNumber = styleSheetHeader.lineNumberInSource(ruleLocation.startLine);
-    const columnNumber = styleSheetHeader.columnNumberInSource(ruleLocation.startLine, ruleLocation.startColumn);
-    const matchingSelectorLocation = new SDK.CSSLocation(styleSheetHeader, lineNumber, columnNumber);
-    return linkifier.linkifyCSSLocation(matchingSelectorLocation);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (this._editing || !this.editable || event.altKey || event.ctrlKey || event.metaKey)
-      return;
-    switch (event.key) {
-      case 'Enter':
-      case ' ':
-        this._startEditingAtFirstPosition();
-        event.consume(true);
-        break;
-      default:
-        // Filter out non-printable key strokes.
-        if (event.key.length === 1)
-          this.addNewBlankProperty(0).startEditing();
-        break;
-    }
-  }
-
-  /**
-   * @param {boolean} isHovered
-   */
-  _setSectionHovered(isHovered) {
-    this.element.classList.toggle('styles-panel-hovered', isHovered);
-    this.propertiesTreeOutline.element.classList.toggle('styles-panel-hovered', isHovered);
-    if (this._hoverableSelectorsMode !== isHovered) {
-      this._hoverableSelectorsMode = isHovered;
-      this._markSelectorMatches();
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    const hasCtrlOrMeta = UI.KeyboardShortcut.eventHasCtrlOrMeta(/** @type {!MouseEvent} */ (event));
-    this._setSectionHovered(hasCtrlOrMeta);
-  }
-
-  /**
-   * @param {!Element} container
-   */
-  _createHoverMenuToolbar(container) {
-    if (!this.editable)
-      return;
-    const items = [];
-
-    const textShadowButton = new UI.ToolbarButton(Common.UIString('Add text-shadow'), 'largeicon-text-shadow');
-    textShadowButton.addEventListener(
-        UI.ToolbarButton.Events.Click, this._onInsertShadowPropertyClick.bind(this, 'text-shadow'));
-    textShadowButton.element.tabIndex = -1;
-    items.push(textShadowButton);
-
-    const boxShadowButton = new UI.ToolbarButton(Common.UIString('Add box-shadow'), 'largeicon-box-shadow');
-    boxShadowButton.addEventListener(
-        UI.ToolbarButton.Events.Click, this._onInsertShadowPropertyClick.bind(this, 'box-shadow'));
-    boxShadowButton.element.tabIndex = -1;
-    items.push(boxShadowButton);
-
-    const colorButton = new UI.ToolbarButton(Common.UIString('Add color'), 'largeicon-foreground-color');
-    colorButton.addEventListener(UI.ToolbarButton.Events.Click, this._onInsertColorPropertyClick, this);
-    colorButton.element.tabIndex = -1;
-    items.push(colorButton);
-
-    const backgroundButton =
-        new UI.ToolbarButton(Common.UIString('Add background-color'), 'largeicon-background-color');
-    backgroundButton.addEventListener(UI.ToolbarButton.Events.Click, this._onInsertBackgroundColorPropertyClick, this);
-    backgroundButton.element.tabIndex = -1;
-    items.push(backgroundButton);
-
-    let newRuleButton = null;
-    if (this._style.parentRule) {
-      newRuleButton = new UI.ToolbarButton(Common.UIString('Insert Style Rule Below'), 'largeicon-add');
-      newRuleButton.addEventListener(UI.ToolbarButton.Events.Click, this._onNewRuleClick, this);
-      newRuleButton.element.tabIndex = -1;
-      items.push(newRuleButton);
-    }
-
-    const sectionToolbar = new UI.Toolbar('sidebar-pane-section-toolbar', container);
-    for (let i = 0; i < items.length; ++i)
-      sectionToolbar.appendToolbarItem(items[i]);
-
-    const menuButton = new UI.ToolbarButton(Common.UIString('More tools\u2026'), 'largeicon-menu');
-    menuButton.element.tabIndex = -1;
-    sectionToolbar.appendToolbarItem(menuButton);
-    setItemsVisibility.call(this, items, false);
-    sectionToolbar.element.addEventListener('mouseenter', setItemsVisibility.bind(this, items, true));
-    sectionToolbar.element.addEventListener('mouseleave', setItemsVisibility.bind(this, items, false));
-    UI.ARIAUtils.markAsHidden(sectionToolbar.element);
-
-    /**
-     * @param {!Array<!UI.ToolbarButton>} items
-     * @param {boolean} value
-     * @this {Elements.StylePropertiesSection}
-     */
-    function setItemsVisibility(items, value) {
-      for (let i = 0; i < items.length; ++i)
-        items[i].setVisible(value);
-      menuButton.setVisible(!value);
-      if (this._isSASSStyle())
-        newRuleButton.setVisible(false);
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isSASSStyle() {
-    const header =
-        this._style.styleSheetId ? this._style.cssModel().styleSheetHeaderForId(this._style.styleSheetId) : null;
-    if (!header)
-      return false;
-    const sourceMap = header.cssModel().sourceMapManager().sourceMapForClient(header);
-    return sourceMap ? sourceMap.editable() : false;
-  }
-
-  /**
-   * @return {!SDK.CSSStyleDeclaration}
-   */
-  style() {
-    return this._style;
-  }
-
-  /**
-   * @return {string}
-   */
-  _headerText() {
-    const node = this._matchedStyles.nodeForStyle(this._style);
-    if (this._style.type === SDK.CSSStyleDeclaration.Type.Inline)
-      return this._matchedStyles.isInherited(this._style) ? Common.UIString('Style Attribute') : 'element.style';
-    if (this._style.type === SDK.CSSStyleDeclaration.Type.Attributes)
-      return node.nodeNameInCorrectCase() + '[' + Common.UIString('Attributes Style') + ']';
-    return this._style.parentRule.selectorText();
-  }
-
-  _onMouseOutSelector() {
-    if (this._hoverTimer)
-      clearTimeout(this._hoverTimer);
-    SDK.OverlayModel.hideDOMNodeHighlight();
-  }
-
-  _onMouseEnterSelector() {
-    if (this._hoverTimer)
-      clearTimeout(this._hoverTimer);
-    this._hoverTimer = setTimeout(this._highlight.bind(this), 300);
-  }
-
-  _highlight() {
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    const node = this._parentPane.node();
-    if (!node)
-      return;
-    const selectors = this._style.parentRule ? this._style.parentRule.selectorText() : undefined;
-    node.domModel().overlayModel().highlightDOMNodeWithConfig(
-        node.id, {mode: 'all', showInfo: undefined, selectors: selectors});
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  firstSibling() {
-    const parent = this.element.parentElement;
-    if (!parent)
-      return null;
-
-    let childElement = parent.firstChild;
-    while (childElement) {
-      if (childElement._section)
-        return childElement._section;
-      childElement = childElement.nextSibling;
-    }
-
-    return null;
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  lastSibling() {
-    const parent = this.element.parentElement;
-    if (!parent)
-      return null;
-
-    let childElement = parent.lastChild;
-    while (childElement) {
-      if (childElement._section)
-        return childElement._section;
-      childElement = childElement.previousSibling;
-    }
-
-    return null;
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  nextSibling() {
-    let curElement = this.element;
-    do
-      curElement = curElement.nextSibling;
-    while (curElement && !curElement._section);
-
-    return curElement ? curElement._section : null;
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  previousSibling() {
-    let curElement = this.element;
-    do
-      curElement = curElement.previousSibling;
-    while (curElement && !curElement._section);
-
-    return curElement ? curElement._section : null;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onNewRuleClick(event) {
-    event.data.consume();
-    const rule = this._style.parentRule;
-    const range = TextUtils.TextRange.createFromLocation(rule.style.range.endLine, rule.style.range.endColumn + 1);
-    this._parentPane._addBlankSection(this, /** @type {string} */ (rule.styleSheetId), range);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @param {!Common.Event} event
-   */
-  _onInsertShadowPropertyClick(propertyName, event) {
-    event.data.consume(true);
-    const treeElement = this.addNewBlankProperty();
-    treeElement.property.name = propertyName;
-    treeElement.property.value = '0 0 black';
-    treeElement.updateTitle();
-    const shadowSwatchPopoverHelper = Elements.ShadowSwatchPopoverHelper.forTreeElement(treeElement);
-    if (shadowSwatchPopoverHelper)
-      shadowSwatchPopoverHelper.showPopover();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onInsertColorPropertyClick(event) {
-    event.data.consume(true);
-    const treeElement = this.addNewBlankProperty();
-    treeElement.property.name = 'color';
-    treeElement.property.value = 'black';
-    treeElement.updateTitle();
-    const colorSwatch = Elements.ColorSwatchPopoverIcon.forTreeElement(treeElement);
-    if (colorSwatch)
-      colorSwatch.showPopover();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onInsertBackgroundColorPropertyClick(event) {
-    event.data.consume(true);
-    const treeElement = this.addNewBlankProperty();
-    treeElement.property.name = 'background-color';
-    treeElement.property.value = 'white';
-    treeElement.updateTitle();
-    const colorSwatch = Elements.ColorSwatchPopoverIcon.forTreeElement(treeElement);
-    if (colorSwatch)
-      colorSwatch.showPopover();
-  }
-
-  /**
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  _styleSheetEdited(edit) {
-    const rule = this._style.parentRule;
-    if (rule)
-      rule.rebase(edit);
-    else
-      this._style.rebase(edit);
-
-    this._updateMediaList();
-    this._updateRuleOrigin();
-  }
-
-  /**
-   * @param {!Array.<!SDK.CSSMedia>} mediaRules
-   */
-  _createMediaList(mediaRules) {
-    for (let i = mediaRules.length - 1; i >= 0; --i) {
-      const media = mediaRules[i];
-      // Don't display trivial non-print media types.
-      if (!media.text.includes('(') && media.text !== 'print')
-        continue;
-      const mediaDataElement = this._mediaListElement.createChild('div', 'media');
-      const mediaContainerElement = mediaDataElement.createChild('span');
-      const mediaTextElement = mediaContainerElement.createChild('span', 'media-text');
-      switch (media.source) {
-        case SDK.CSSMedia.Source.LINKED_SHEET:
-        case SDK.CSSMedia.Source.INLINE_SHEET:
-          mediaTextElement.textContent = 'media="' + media.text + '"';
-          break;
-        case SDK.CSSMedia.Source.MEDIA_RULE:
-          const decoration = mediaContainerElement.createChild('span');
-          mediaContainerElement.insertBefore(decoration, mediaTextElement);
-          decoration.textContent = '@media ';
-          mediaTextElement.textContent = media.text;
-          if (media.styleSheetId) {
-            mediaDataElement.classList.add('editable-media');
-            mediaTextElement.addEventListener(
-                'click', this._handleMediaRuleClick.bind(this, media, mediaTextElement), false);
-          }
-          break;
-        case SDK.CSSMedia.Source.IMPORT_RULE:
-          mediaTextElement.textContent = '@import ' + media.text;
-          break;
-      }
-    }
-  }
-
-  _updateMediaList() {
-    this._mediaListElement.removeChildren();
-    if (this._style.parentRule && this._style.parentRule instanceof SDK.CSSStyleRule)
-      this._createMediaList(this._style.parentRule.media);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isPropertyInherited(propertyName) {
-    if (this._matchedStyles.isInherited(this._style)) {
-      // While rendering inherited stylesheet, reverse meaning of this property.
-      // Render truly inherited properties with black, i.e. return them as non-inherited.
-      return !SDK.cssMetadata().isPropertyInherited(propertyName);
-    }
-    return false;
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  nextEditableSibling() {
-    let curSection = this;
-    do
-      curSection = curSection.nextSibling();
-    while (curSection && !curSection.editable);
-
-    if (!curSection) {
-      curSection = this.firstSibling();
-      while (curSection && !curSection.editable)
-        curSection = curSection.nextSibling();
-    }
-
-    return (curSection && curSection.editable) ? curSection : null;
-  }
-
-  /**
-   * @return {?Elements.StylePropertiesSection}
-   */
-  previousEditableSibling() {
-    let curSection = this;
-    do
-      curSection = curSection.previousSibling();
-    while (curSection && !curSection.editable);
-
-    if (!curSection) {
-      curSection = this.lastSibling();
-      while (curSection && !curSection.editable)
-        curSection = curSection.previousSibling();
-    }
-
-    return (curSection && curSection.editable) ? curSection : null;
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement} editedTreeElement
-   */
-  refreshUpdate(editedTreeElement) {
-    this._parentPane._refreshUpdate(this, editedTreeElement);
-  }
-
-  /**
-   * @param {!Elements.StylePropertyTreeElement} editedTreeElement
-   */
-  _updateVarFunctions(editedTreeElement) {
-    let child = this.propertiesTreeOutline.firstChild();
-    while (child) {
-      if (child !== editedTreeElement)
-        child.updateTitleIfComputedValueChanged();
-      child = child.traverseNextTreeElement(false /* skipUnrevealed */, null /* stayWithin */, true /* dontPopulate */);
-    }
-  }
-
-  /**
-   * @param {boolean} full
-   */
-  update(full) {
-    this._selectorElement.textContent = this._headerText();
-    this._markSelectorMatches();
-    if (full) {
-      this.onpopulate();
-    } else {
-      let child = this.propertiesTreeOutline.firstChild();
-      while (child) {
-        child.setOverloaded(this._isPropertyOverloaded(child.property));
-        child =
-            child.traverseNextTreeElement(false /* skipUnrevealed */, null /* stayWithin */, true /* dontPopulate */);
-      }
-    }
-  }
-
-  /**
-   * @param {!Event=} event
-   */
-  _showAllItems(event) {
-    if (event)
-      event.consume();
-    if (this._forceShowAll)
-      return;
-    this._forceShowAll = true;
-    this.onpopulate();
-  }
-
-  onpopulate() {
-    this.propertiesTreeOutline.removeChildren();
-    const style = this._style;
-    let count = 0;
-    const properties = style.leadingProperties();
-    const maxProperties =
-        Elements.StylePropertiesSection.MaxProperties + properties.length - this._originalPropertiesCount;
-
-    for (const property of properties) {
-      if (!this._forceShowAll && count >= maxProperties)
-        break;
-      count++;
-      const isShorthand = !!style.longhandProperties(property.name).length;
-      const inherited = this.isPropertyInherited(property.name);
-      const overloaded = this._isPropertyOverloaded(property);
-      const item = new Elements.StylePropertyTreeElement(
-          this._parentPane, this._matchedStyles, property, isShorthand, inherited, overloaded, false);
-      this.propertiesTreeOutline.appendChild(item);
-    }
-
-    if (count < properties.length) {
-      this._showAllButton.classList.remove('hidden');
-      this._showAllButton.textContent = ls`Show All Properties (${properties.length - count} more)`;
-    } else {
-      this._showAllButton.classList.add('hidden');
-    }
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} property
-   * @return {boolean}
-   */
-  _isPropertyOverloaded(property) {
-    return this._matchedStyles.propertyState(property) === SDK.CSSMatchedStyles.PropertyState.Overloaded;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _updateFilter() {
-    let hasMatchingChild = false;
-    this._showAllItems();
-    for (const child of this.propertiesTreeOutline.rootElement().children())
-      hasMatchingChild |= child._updateFilter();
-
-    const regex = this._parentPane.filterRegex();
-    const hideRule = !hasMatchingChild && !!regex && !regex.test(this.element.deepTextContent());
-    this.element.classList.toggle('hidden', hideRule);
-    if (!hideRule && this._style.parentRule)
-      this._markSelectorHighlights();
-    return !hideRule;
-  }
-
-  _markSelectorMatches() {
-    const rule = this._style.parentRule;
-    if (!rule)
-      return;
-
-    this._mediaListElement.classList.toggle('media-matches', this._matchedStyles.mediaMatches(this._style));
-
-    const selectorTexts = rule.selectors.map(selector => selector.text);
-    const matchingSelectorIndexes = this._matchedStyles.matchingSelectors(/** @type {!SDK.CSSStyleRule} */ (rule));
-    const matchingSelectors = /** @type {!Array<boolean>} */ (new Array(selectorTexts.length).fill(false));
-    for (const matchingIndex of matchingSelectorIndexes)
-      matchingSelectors[matchingIndex] = true;
-
-    if (this._parentPane._isEditingStyle)
-      return;
-
-    const fragment = this._hoverableSelectorsMode ? this._renderHoverableSelectors(selectorTexts, matchingSelectors) :
-                                                    this._renderSimplifiedSelectors(selectorTexts, matchingSelectors);
-    this._selectorElement.removeChildren();
-    this._selectorElement.appendChild(fragment);
-    this._markSelectorHighlights();
-  }
-
-  /**
-   * @param {!Array<string>} selectors
-   * @param {!Array<boolean>} matchingSelectors
-   * @return {!DocumentFragment}
-   */
-  _renderHoverableSelectors(selectors, matchingSelectors) {
-    const fragment = createDocumentFragment();
-    for (let i = 0; i < selectors.length; ++i) {
-      if (i)
-        fragment.createTextChild(', ');
-      fragment.appendChild(this._createSelectorElement(selectors[i], matchingSelectors[i], i));
-    }
-    return fragment;
-  }
-
-  /**
-   * @param {string} text
-   * @param {boolean} isMatching
-   * @param {number=} navigationIndex
-   * @return {!Element}
-   */
-  _createSelectorElement(text, isMatching, navigationIndex) {
-    const element = createElementWithClass('span', 'simple-selector');
-    element.classList.toggle('selector-matches', isMatching);
-    if (typeof navigationIndex === 'number')
-      element._selectorIndex = navigationIndex;
-    element.textContent = text;
-    return element;
-  }
-
-  /**
-   * @param {!Array<string>} selectors
-   * @param {!Array<boolean>} matchingSelectors
-   * @return {!DocumentFragment}
-   */
-  _renderSimplifiedSelectors(selectors, matchingSelectors) {
-    const fragment = createDocumentFragment();
-    let currentMatching = false;
-    let text = '';
-    for (let i = 0; i < selectors.length; ++i) {
-      if (currentMatching !== matchingSelectors[i] && text) {
-        fragment.appendChild(this._createSelectorElement(text, currentMatching));
-        text = '';
-      }
-      currentMatching = matchingSelectors[i];
-      text += selectors[i] + (i === selectors.length - 1 ? '' : ', ');
-    }
-    if (text)
-      fragment.appendChild(this._createSelectorElement(text, currentMatching));
-    return fragment;
-  }
-
-  _markSelectorHighlights() {
-    const selectors = this._selectorElement.getElementsByClassName('simple-selector');
-    const regex = this._parentPane.filterRegex();
-    for (let i = 0; i < selectors.length; ++i) {
-      const selectorMatchesFilter = !!regex && regex.test(selectors[i].textContent);
-      selectors[i].classList.toggle('filter-match', selectorMatchesFilter);
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _checkWillCancelEditing() {
-    const willCauseCancelEditing = this._willCauseCancelEditing;
-    this._willCauseCancelEditing = false;
-    return willCauseCancelEditing;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleSelectorContainerClick(event) {
-    if (this._checkWillCancelEditing() || !this.editable)
-      return;
-    if (event.target === this._selectorContainer) {
-      this.addNewBlankProperty(0).startEditing();
-      event.consume(true);
-    }
-  }
-
-  /**
-   * @param {number=} index
-   * @return {!Elements.StylePropertyTreeElement}
-   */
-  addNewBlankProperty(index = this.propertiesTreeOutline.rootElement().childCount()) {
-    const property = this._style.newBlankProperty(index);
-    const item = new Elements.StylePropertyTreeElement(
-        this._parentPane, this._matchedStyles, property, false, false, false, true);
-    this.propertiesTreeOutline.insertChild(item, property.index);
-    return item;
-  }
-
-  _handleEmptySpaceMouseDown() {
-    this._willCauseCancelEditing = this._parentPane._isEditingStyle;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleEmptySpaceClick(event) {
-    if (!this.editable || this.element.hasSelection() || this._checkWillCancelEditing())
-      return;
-
-    if (event.target.classList.contains('header') || this.element.classList.contains('read-only') ||
-        event.target.enclosingNodeOrSelfWithClass('media')) {
-      event.consume();
-      return;
-    }
-    const deepTarget = event.deepElementFromPoint();
-    if (deepTarget.treeElement)
-      this.addNewBlankProperty(deepTarget.treeElement.property.index + 1).startEditing();
-    else
-      this.addNewBlankProperty().startEditing();
-    event.consume(true);
-  }
-
-  /**
-   * @param {!SDK.CSSMedia} media
-   * @param {!Element} element
-   * @param {!Event} event
-   */
-  _handleMediaRuleClick(media, element, event) {
-    if (UI.isBeingEdited(element))
-      return;
-
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(/** @type {!MouseEvent} */ (event)) && this.navigable) {
-      const location = media.rawLocation();
-      if (!location) {
-        event.consume(true);
-        return;
-      }
-      const uiLocation = Bindings.cssWorkspaceBinding.rawLocationToUILocation(location);
-      if (uiLocation)
-        Common.Revealer.reveal(uiLocation);
-      event.consume(true);
-      return;
-    }
-
-    if (!this.editable || this._isSASSStyle())
-      return;
-
-    const config = new UI.InplaceEditor.Config(
-        this._editingMediaCommitted.bind(this, media), this._editingMediaCancelled.bind(this, element), undefined,
-        this._editingMediaBlurHandler.bind(this));
-    UI.InplaceEditor.startEditing(element, config);
-    this.startEditing();
-
-    element.getComponentSelection().selectAllChildren(element);
-    this._parentPane.setEditingStyle(true);
-    const parentMediaElement = element.enclosingNodeOrSelfWithClass('media');
-    parentMediaElement.classList.add('editing-media');
-
-    event.consume(true);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  _editingMediaFinished(element) {
-    this._parentPane.setEditingStyle(false);
-    const parentMediaElement = element.enclosingNodeOrSelfWithClass('media');
-    parentMediaElement.classList.remove('editing-media');
-    this.stopEditing();
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  _editingMediaCancelled(element) {
-    this._editingMediaFinished(element);
-    // Mark the selectors in group if necessary.
-    // This is overridden by BlankStylePropertiesSection.
-    this._markSelectorMatches();
-    element.getComponentSelection().collapse(element, 0);
-  }
-
-  /**
-   * @param {!Element} editor
-   * @param {!Event} blurEvent
-   * @return {boolean}
-   */
-  _editingMediaBlurHandler(editor, blurEvent) {
-    return true;
-  }
-
-  /**
-   * @param {!SDK.CSSMedia} media
-   * @param {!Element} element
-   * @param {string} newContent
-   * @param {string} oldContent
-   * @param {(!Elements.StylePropertyTreeElement.Context|undefined)} context
-   * @param {string} moveDirection
-   */
-  _editingMediaCommitted(media, element, newContent, oldContent, context, moveDirection) {
-    this._parentPane.setEditingStyle(false);
-    this._editingMediaFinished(element);
-
-    if (newContent)
-      newContent = newContent.trim();
-
-    /**
-     * @param {boolean} success
-     * @this {Elements.StylePropertiesSection}
-     */
-    function userCallback(success) {
-      if (success) {
-        this._matchedStyles.resetActiveProperties();
-        this._parentPane._refreshUpdate(this);
-      }
-      this._parentPane.setUserOperation(false);
-      this._editingMediaTextCommittedForTest();
-    }
-
-    // This gets deleted in finishOperation(), which is called both on success and failure.
-    this._parentPane.setUserOperation(true);
-    this._parentPane.cssModel().setMediaText(media.styleSheetId, media.range, newContent).then(userCallback.bind(this));
-  }
-
-  _editingMediaTextCommittedForTest() {
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleSelectorClick(event) {
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(/** @type {!MouseEvent} */ (event)) && this.navigable &&
-        event.target.classList.contains('simple-selector')) {
-      this._navigateToSelectorSource(event.target._selectorIndex, true);
-      event.consume(true);
-      return;
-    }
-    this._startEditingAtFirstPosition();
-    event.consume(true);
-  }
-
-  /**
-   * @param {number} index
-   * @param {boolean} focus
-   */
-  _navigateToSelectorSource(index, focus) {
-    const cssModel = this._parentPane.cssModel();
-    const rule = this._style.parentRule;
-    const header = cssModel.styleSheetHeaderForId(/** @type {string} */ (rule.styleSheetId));
-    if (!header)
-      return;
-    const rawLocation = new SDK.CSSLocation(header, rule.lineNumberInSource(index), rule.columnNumberInSource(index));
-    const uiLocation = Bindings.cssWorkspaceBinding.rawLocationToUILocation(rawLocation);
-    if (uiLocation)
-      Common.Revealer.reveal(uiLocation, !focus);
-  }
-
-  _startEditingAtFirstPosition() {
-    if (!this.editable || this._isSASSStyle())
-      return;
-
-    if (!this._style.parentRule) {
-      this.moveEditorFromSelector('forward');
-      return;
-    }
-
-    this.startEditingSelector();
-  }
-
-  startEditingSelector() {
-    const element = this._selectorElement;
-    if (UI.isBeingEdited(element))
-      return;
-
-    element.scrollIntoViewIfNeeded(false);
-    // Reset selector marks in group, and normalize whitespace.
-    element.textContent = element.textContent.replace(/\s+/g, ' ').trim();
-
-    const config =
-        new UI.InplaceEditor.Config(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this));
-    UI.InplaceEditor.startEditing(this._selectorElement, config);
-    this.startEditing();
-
-    element.getComponentSelection().selectAllChildren(element);
-    this._parentPane.setEditingStyle(true);
-    if (element.classList.contains('simple-selector'))
-      this._navigateToSelectorSource(0, false);
-  }
-
-  /**
-   * @param {string} moveDirection
-   */
-  moveEditorFromSelector(moveDirection) {
-    this._markSelectorMatches();
-
-    if (!moveDirection)
-      return;
-
-    if (moveDirection === 'forward') {
-      let firstChild = this.propertiesTreeOutline.firstChild();
-      while (firstChild && firstChild.inherited())
-        firstChild = firstChild.nextSibling;
-      if (!firstChild)
-        this.addNewBlankProperty().startEditing();
-      else
-        firstChild.startEditing(firstChild.nameElement);
-    } else {
-      const previousSection = this.previousEditableSibling();
-      if (!previousSection)
-        return;
-
-      previousSection.addNewBlankProperty().startEditing();
-    }
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} newContent
-   * @param {string} oldContent
-   * @param {(!Elements.StylePropertyTreeElement.Context|undefined)} context
-   * @param {string} moveDirection
-   */
-  editingSelectorCommitted(element, newContent, oldContent, context, moveDirection) {
-    this._editingSelectorEnded();
-    if (newContent)
-      newContent = newContent.trim();
-    if (newContent === oldContent) {
-      // Revert to a trimmed version of the selector if need be.
-      this._selectorElement.textContent = newContent;
-      this.moveEditorFromSelector(moveDirection);
-      return;
-    }
-    const rule = this._style.parentRule;
-    if (!rule)
-      return;
-
-    /**
-     * @this {Elements.StylePropertiesSection}
-     */
-    function headerTextCommitted() {
-      this._parentPane.setUserOperation(false);
-      this.moveEditorFromSelector(moveDirection);
-      this._editingSelectorCommittedForTest();
-    }
-
-    // This gets deleted in finishOperationAndMoveEditor(), which is called both on success and failure.
-    this._parentPane.setUserOperation(true);
-    this._setHeaderText(rule, newContent).then(headerTextCommitted.bind(this));
-  }
-
-  /**
-   * @param {!SDK.CSSRule} rule
-   * @param {string} newContent
-   * @return {!Promise}
-   */
-  _setHeaderText(rule, newContent) {
-    /**
-     * @param {!SDK.CSSStyleRule} rule
-     * @param {boolean} success
-     * @return {!Promise}
-     * @this {Elements.StylePropertiesSection}
-     */
-    function onSelectorsUpdated(rule, success) {
-      if (!success)
-        return Promise.resolve();
-      return this._matchedStyles.recomputeMatchingSelectors(rule).then(updateSourceRanges.bind(this, rule));
-    }
-
-    /**
-     * @param {!SDK.CSSStyleRule} rule
-     * @this {Elements.StylePropertiesSection}
-     */
-    function updateSourceRanges(rule) {
-      const doesAffectSelectedNode = this._matchedStyles.matchingSelectors(rule).length > 0;
-      this.propertiesTreeOutline.element.classList.toggle('no-affect', !doesAffectSelectedNode);
-      this._matchedStyles.resetActiveProperties();
-      this._parentPane._refreshUpdate(this);
-    }
-
-    console.assert(rule instanceof SDK.CSSStyleRule);
-    const oldSelectorRange = rule.selectorRange();
-    if (!oldSelectorRange)
-      return Promise.resolve();
-    return rule.setSelectorText(newContent)
-        .then(onSelectorsUpdated.bind(this, /** @type {!SDK.CSSStyleRule} */ (rule), oldSelectorRange));
-  }
-
-  _editingSelectorCommittedForTest() {
-  }
-
-  _updateRuleOrigin() {
-    this._selectorRefElement.removeChildren();
-    this._selectorRefElement.appendChild(Elements.StylePropertiesSection.createRuleOriginNode(
-        this._matchedStyles, this._parentPane._linkifier, this._style.parentRule));
-  }
-
-  _editingSelectorEnded() {
-    this._parentPane.setEditingStyle(false);
-    this.stopEditing();
-  }
-
-  editingSelectorCancelled() {
-    this._editingSelectorEnded();
-
-    // Mark the selectors in group if necessary.
-    // This is overridden by BlankStylePropertiesSection.
-    this._markSelectorMatches();
-  }
-
-  startEditing() {
-    this._manuallySetHeight();
-    this.element.addEventListener('input', this._scheduleHeightUpdate, true);
-    this._editing = true;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _manuallySetHeight() {
-    this.element.style.height = (this._innerElement.clientHeight + 1) + 'px';
-    this.element.style.contain = 'strict';
-    return Promise.resolve();
-  }
-
-  stopEditing() {
-    this.element.style.removeProperty('height');
-    this.element.style.removeProperty('contain');
-    this.element.removeEventListener('input', this._scheduleHeightUpdate, true);
-    this._editing = false;
-    if (this._parentPane.element === this._parentPane.element.ownerDocument.deepActiveElement())
-      this.element.focus();
-  }
-};
-
-Elements.BlankStylePropertiesSection = class extends Elements.StylePropertiesSection {
-  /**
-   * @param {!Elements.StylesSidebarPane} stylesPane
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {string} defaultSelectorText
-   * @param {string} styleSheetId
-   * @param {!TextUtils.TextRange} ruleLocation
-   * @param {!SDK.CSSStyleDeclaration} insertAfterStyle
-   */
-  constructor(stylesPane, matchedStyles, defaultSelectorText, styleSheetId, ruleLocation, insertAfterStyle) {
-    const cssModel = /** @type {!SDK.CSSModel} */ (stylesPane.cssModel());
-    const rule = SDK.CSSStyleRule.createDummyRule(cssModel, defaultSelectorText);
-    super(stylesPane, matchedStyles, rule.style);
-    this._normal = false;
-    this._ruleLocation = ruleLocation;
-    this._styleSheetId = styleSheetId;
-    this._selectorRefElement.removeChildren();
-    this._selectorRefElement.appendChild(Elements.StylePropertiesSection._linkifyRuleLocation(
-        cssModel, this._parentPane._linkifier, styleSheetId, this._actualRuleLocation()));
-    if (insertAfterStyle && insertAfterStyle.parentRule)
-      this._createMediaList(insertAfterStyle.parentRule.media);
-    this.element.classList.add('blank-section');
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  _actualRuleLocation() {
-    const prefix = this._rulePrefix();
-    const lines = prefix.split('\n');
-    const editRange = new TextUtils.TextRange(0, 0, lines.length - 1, lines.peekLast().length);
-    return this._ruleLocation.rebaseAfterTextEdit(TextUtils.TextRange.createFromLocation(0, 0), editRange);
-  }
-
-  /**
-   * @return {string}
-   */
-  _rulePrefix() {
-    return this._ruleLocation.startLine === 0 && this._ruleLocation.startColumn === 0 ? '' : '\n\n';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get isBlank() {
-    return !this._normal;
-  }
-
-  /**
-   * @override
-   * @param {!Element} element
-   * @param {string} newContent
-   * @param {string} oldContent
-   * @param {!Elements.StylePropertyTreeElement.Context|undefined} context
-   * @param {string} moveDirection
-   */
-  editingSelectorCommitted(element, newContent, oldContent, context, moveDirection) {
-    if (!this.isBlank) {
-      super.editingSelectorCommitted(element, newContent, oldContent, context, moveDirection);
-      return;
-    }
-
-    /**
-     * @param {?SDK.CSSStyleRule} newRule
-     * @return {!Promise}
-     * @this {Elements.BlankStylePropertiesSection}
-     */
-    function onRuleAdded(newRule) {
-      if (!newRule) {
-        this.editingSelectorCancelled();
-        this._editingSelectorCommittedForTest();
-        return Promise.resolve();
-      }
-      return this._matchedStyles.addNewRule(newRule, this._matchedStyles.node())
-          .then(onAddedToCascade.bind(this, newRule));
-    }
-
-    /**
-     * @param {!SDK.CSSStyleRule} newRule
-     * @this {Elements.BlankStylePropertiesSection}
-     */
-    function onAddedToCascade(newRule) {
-      const doesSelectorAffectSelectedNode = this._matchedStyles.matchingSelectors(newRule).length > 0;
-      this._makeNormal(newRule);
-
-      if (!doesSelectorAffectSelectedNode)
-        this.propertiesTreeOutline.element.classList.add('no-affect');
-
-      this._updateRuleOrigin();
-
-      this._parentPane.setUserOperation(false);
-      this._editingSelectorEnded();
-      if (this.element.parentElement)  // Might have been detached already.
-        this.moveEditorFromSelector(moveDirection);
-      this._markSelectorMatches();
-
-      this._editingSelectorCommittedForTest();
-    }
-
-    if (newContent)
-      newContent = newContent.trim();
-    this._parentPane.setUserOperation(true);
-
-    const cssModel = this._parentPane.cssModel();
-    const ruleText = this._rulePrefix() + newContent + ' {}';
-    cssModel.addRule(this._styleSheetId, ruleText, this._ruleLocation).then(onRuleAdded.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  editingSelectorCancelled() {
-    this._parentPane.setUserOperation(false);
-    if (!this.isBlank) {
-      super.editingSelectorCancelled();
-      return;
-    }
-
-    this._editingSelectorEnded();
-    this._parentPane.removeSection(this);
-  }
-
-  /**
-   * @param {!SDK.CSSRule} newRule
-   */
-  _makeNormal(newRule) {
-    this.element.classList.remove('blank-section');
-    this._style = newRule.style;
-    // FIXME: replace this instance by a normal Elements.StylePropertiesSection.
-    this._normal = true;
-  }
-};
-Elements.StylePropertiesSection.MaxProperties = 50;
-
-Elements.KeyframePropertiesSection = class extends Elements.StylePropertiesSection {
-  /**
-   * @param {!Elements.StylesSidebarPane} stylesPane
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {!SDK.CSSStyleDeclaration} style
-   */
-  constructor(stylesPane, matchedStyles, style) {
-    super(stylesPane, matchedStyles, style);
-    this._selectorElement.className = 'keyframe-key';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  _headerText() {
-    return this._style.parentRule.key().text;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSRule} rule
-   * @param {string} newContent
-   * @return {!Promise}
-   */
-  _setHeaderText(rule, newContent) {
-    /**
-     * @param {boolean} success
-     * @this {Elements.KeyframePropertiesSection}
-     */
-    function updateSourceRanges(success) {
-      if (!success)
-        return;
-      this._parentPane._refreshUpdate(this);
-    }
-
-    console.assert(rule instanceof SDK.CSSKeyframeRule);
-    const oldRange = rule.key().range;
-    if (!oldRange)
-      return Promise.resolve();
-    return rule.setKeyText(newContent).then(updateSourceRanges.bind(this));
-  }
-
-  /**
-   * @override
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isPropertyInherited(propertyName) {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSProperty} property
-   * @return {boolean}
-   */
-  _isPropertyOverloaded(property) {
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  _markSelectorHighlights() {
-  }
-
-  /**
-   * @override
-   */
-  _markSelectorMatches() {
-    this._selectorElement.textContent = this._style.parentRule.key().text;
-  }
-
-  /**
-   * @override
-   */
-  _highlight() {
-  }
-};
-
-Elements.StylesSidebarPane.CSSPropertyPrompt = class extends UI.TextPrompt {
-  /**
-   * @param {!Array<string>} cssCompletions
-   * @param {!Array<string>} cssVariables
-   * @param {!Elements.StylePropertyTreeElement} treeElement
-   * @param {boolean} isEditingName
-   */
-  constructor(cssCompletions, cssVariables, treeElement, isEditingName) {
-    // Use the same callback both for applyItemCallback and acceptItemCallback.
-    super();
-    this.initialize(this._buildPropertyCompletions.bind(this), UI.StyleValueDelimiters);
-    this._cssCompletions = cssCompletions;
-    this._cssVariables = cssVariables;
-    this._treeElement = treeElement;
-    this._isEditingName = isEditingName;
-
-    if (!isEditingName) {
-      this.disableDefaultSuggestionForEmptyInput();
-
-      // If a CSS value is being edited that has a numeric or hex substring, hint that precision modifier shortcuts are available.
-      if (treeElement && treeElement.valueElement) {
-        const cssValueText = treeElement.valueElement.textContent;
-        if (cssValueText.match(/#[\da-f]{3,6}$/i)) {
-          this.setTitle(Common.UIString(
-              'Increment/decrement with mousewheel or up/down keys. %s: R ±1, Shift: G ±1, Alt: B ±1',
-              Host.isMac() ? 'Cmd' : 'Ctrl'));
-        } else if (cssValueText.match(/\d+/)) {
-          this.setTitle(Common.UIString(
-              'Increment/decrement with mousewheel or up/down keys. %s: ±100, Shift: ±10, Alt: ±0.1',
-              Host.isMac() ? 'Cmd' : 'Ctrl'));
-        }
-      }
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  onKeyDown(event) {
-    switch (event.key) {
-      case 'ArrowUp':
-      case 'ArrowDown':
-      case 'PageUp':
-      case 'PageDown':
-        if (this._handleNameOrValueUpDown(event)) {
-          event.preventDefault();
-          return;
-        }
-        break;
-      case 'Enter':
-        // Accept any available autocompletions and advance to the next field.
-        if (this.textWithCurrentSuggestion() !== this.text()) {
-          this.tabKeyPressed();
-          return;
-        }
-        break;
-    }
-
-    super.onKeyDown(event);
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  onMouseWheel(event) {
-    if (this._handleNameOrValueUpDown(event)) {
-      event.consume(true);
-      return;
-    }
-    super.onMouseWheel(event);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  tabKeyPressed() {
-    this.acceptAutoComplete();
-
-    // Always tab to the next field.
-    return false;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _handleNameOrValueUpDown(event) {
-    /**
-     * @param {string} originalValue
-     * @param {string} replacementString
-     * @this {Elements.StylesSidebarPane.CSSPropertyPrompt}
-     */
-    function finishHandler(originalValue, replacementString) {
-      // Synthesize property text disregarding any comments, custom whitespace etc.
-      this._treeElement.applyStyleText(
-          this._treeElement.nameElement.textContent + ': ' + this._treeElement.valueElement.textContent, false);
-    }
-
-    /**
-     * @param {string} prefix
-     * @param {number} number
-     * @param {string} suffix
-     * @return {string}
-     * @this {Elements.StylesSidebarPane.CSSPropertyPrompt}
-     */
-    function customNumberHandler(prefix, number, suffix) {
-      if (number !== 0 && !suffix.length && SDK.cssMetadata().isLengthProperty(this._treeElement.property.name))
-        suffix = 'px';
-      return prefix + number + suffix;
-    }
-
-    // Handle numeric value increment/decrement only at this point.
-    if (!this._isEditingName && this._treeElement.valueElement &&
-        UI.handleElementValueModifications(
-            event, this._treeElement.valueElement, finishHandler.bind(this), this._isValueSuggestion.bind(this),
-            customNumberHandler.bind(this)))
-      return true;
-
-    return false;
-  }
-
-  /**
-   * @param {string} word
-   * @return {boolean}
-   */
-  _isValueSuggestion(word) {
-    if (!word)
-      return false;
-    word = word.toLowerCase();
-    return this._cssCompletions.indexOf(word) !== -1 || word.startsWith('--');
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} query
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  _buildPropertyCompletions(expression, query, force) {
-    const lowerQuery = query.toLowerCase();
-    const editingVariable = !this._isEditingName && expression.trim().endsWith('var(');
-    if (!query && !force && !editingVariable && (this._isEditingName || expression))
-      return Promise.resolve([]);
-
-    const prefixResults = [];
-    const anywhereResults = [];
-    if (!editingVariable)
-      this._cssCompletions.forEach(filterCompletions.bind(this));
-    if (this._isEditingName || editingVariable)
-      this._cssVariables.forEach(filterCompletions.bind(this));
-
-    const results = prefixResults.concat(anywhereResults);
-    if (!this._isEditingName && !results.length && query.length > 1 && '!important'.startsWith(lowerQuery))
-      results.push({text: '!important'});
-    const userEnteredText = query.replace('-', '');
-    if (userEnteredText && (userEnteredText === userEnteredText.toUpperCase())) {
-      for (let i = 0; i < results.length; ++i) {
-        if (!results[i].text.startsWith('--'))
-          results[i].text = results[i].text.toUpperCase();
-      }
-    }
-    if (editingVariable)
-      results.forEach(result => result.text += ')');
-    return Promise.resolve(results);
-
-    /**
-     * @param {string} completion
-     * @this {Elements.StylesSidebarPane.CSSPropertyPrompt}
-     */
-    function filterCompletions(completion) {
-      const index = completion.toLowerCase().indexOf(lowerQuery);
-      if (index === 0) {
-        const priority = this._isEditingName ? SDK.cssMetadata().propertyUsageWeight(completion) : 1;
-        prefixResults.push({text: completion, priority: priority});
-      } else if (index > -1) {
-        anywhereResults.push({text: completion});
-      }
-    }
-  }
-};
-
-Elements.StylesSidebarPropertyRenderer = class {
-  /**
-   * @param {?SDK.CSSRule} rule
-   * @param {?SDK.DOMNode} node
-   * @param {string} name
-   * @param {string} value
-   */
-  constructor(rule, node, name, value) {
-    this._rule = rule;
-    this._node = node;
-    this._propertyName = name;
-    this._propertyValue = value;
-    /** @type {?function(string):!Node} */
-    this._colorHandler = null;
-    /** @type {?function(string):!Node} */
-    this._bezierHandler = null;
-    /** @type {?function(string, string):!Node} */
-    this._shadowHandler = null;
-    /** @type {?function(string):!Node} */
-    this._varHandler = createTextNode;
-  }
-
-  /**
-   * @param {function(string):!Node} handler
-   */
-  setColorHandler(handler) {
-    this._colorHandler = handler;
-  }
-
-  /**
-   * @param {function(string):!Node} handler
-   */
-  setBezierHandler(handler) {
-    this._bezierHandler = handler;
-  }
-
-  /**
-   * @param {function(string, string):!Node} handler
-   */
-  setShadowHandler(handler) {
-    this._shadowHandler = handler;
-  }
-
-  /**
-   * @param {function(string):!Node} handler
-   */
-  setVarHandler(handler) {
-    this._varHandler = handler;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  renderName() {
-    const nameElement = createElement('span');
-    nameElement.className = 'webkit-css-property';
-    nameElement.textContent = this._propertyName;
-    nameElement.normalize();
-    return nameElement;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  renderValue() {
-    const valueElement = createElement('span');
-    valueElement.className = 'value';
-    if (!this._propertyValue)
-      return valueElement;
-
-    if (this._shadowHandler && (this._propertyName === 'box-shadow' || this._propertyName === 'text-shadow' ||
-                                this._propertyName === '-webkit-box-shadow') &&
-        !SDK.CSSMetadata.VariableRegex.test(this._propertyValue)) {
-      valueElement.appendChild(this._shadowHandler(this._propertyValue, this._propertyName));
-      valueElement.normalize();
-      return valueElement;
-    }
-
-    const regexes = [SDK.CSSMetadata.VariableRegex, SDK.CSSMetadata.URLRegex];
-    const processors = [this._varHandler, this._processURL.bind(this)];
-    if (this._bezierHandler && SDK.cssMetadata().isBezierAwareProperty(this._propertyName)) {
-      regexes.push(UI.Geometry.CubicBezier.Regex);
-      processors.push(this._bezierHandler);
-    }
-    if (this._colorHandler && SDK.cssMetadata().isColorAwareProperty(this._propertyName)) {
-      regexes.push(Common.Color.Regex);
-      processors.push(this._colorHandler);
-    }
-    const results = TextUtils.TextUtils.splitStringByRegexes(this._propertyValue, regexes);
-    for (let i = 0; i < results.length; i++) {
-      const result = results[i];
-      const processor = result.regexIndex === -1 ? createTextNode : processors[result.regexIndex];
-      valueElement.appendChild(processor(result.value));
-    }
-    valueElement.normalize();
-    return valueElement;
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Node}
-   */
-  _processURL(text) {
-    // Strip "url(" and ")" along with whitespace.
-    let url = text.substring(4, text.length - 1).trim();
-    const isQuoted = /^'.*'$/.test(url) || /^".*"$/.test(url);
-    if (isQuoted)
-      url = url.substring(1, url.length - 1);
-    const container = createDocumentFragment();
-    container.createTextChild('url(');
-    let hrefUrl = null;
-    if (this._rule && this._rule.resourceURL())
-      hrefUrl = Common.ParsedURL.completeURL(this._rule.resourceURL(), url);
-    else if (this._node)
-      hrefUrl = this._node.resolveURL(url);
-    container.appendChild(Components.Linkifier.linkifyURL(hrefUrl || url, {text: url, preventClick: true}));
-    container.createTextChild(')');
-    return container;
-  }
-};
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- */
-Elements.StylesSidebarPane.ButtonProvider = class {
-  constructor() {
-    this._button = new UI.ToolbarButton(Common.UIString('New Style Rule'), 'largeicon-add');
-    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._clicked, this);
-    const longclickTriangle = UI.Icon.create('largeicon-longclick-triangle', 'long-click-glyph');
-    this._button.element.appendChild(longclickTriangle);
-
-    new UI.LongClickController(this._button.element, this._longClicked.bind(this));
-    UI.context.addFlavorChangeListener(SDK.DOMNode, onNodeChanged.bind(this));
-    onNodeChanged.call(this);
-
-    /**
-     * @this {Elements.StylesSidebarPane.ButtonProvider}
-     */
-    function onNodeChanged() {
-      let node = UI.context.flavor(SDK.DOMNode);
-      node = node ? node.enclosingElementOrSelf() : null;
-      this._button.setEnabled(!!node);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _clicked(event) {
-    Elements.StylesSidebarPane._instance._createNewRuleInViaInspectorStyleSheet();
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _longClicked(e) {
-    Elements.StylesSidebarPane._instance._onAddButtonLongClick(e);
-  }
-
-  /**
-   * @override
-   * @return {!UI.ToolbarItem}
-   */
-  item() {
-    return this._button;
-  }
-};
diff --git a/front_end/elements/breadcrumbs.css b/front_end/elements/breadcrumbs.css
deleted file mode 100644
index 4959665..0000000
--- a/front_end/elements/breadcrumbs.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.crumbs {
-    display: inline-block;
-    pointer-events: auto;
-    cursor: default;
-    white-space: nowrap;
-}
-
-.crumbs .crumb {
-    display: inline-block;
-    padding: 0 7px;
-    line-height: 23px;
-    white-space: nowrap;
-}
-
-.crumbs .crumb.collapsed > * {
-    display: none;
-}
-
-.crumbs .crumb.collapsed::before {
-    content: "\2026";
-    font-weight: bold;
-}
-
-.crumbs .crumb.compact .extra {
-    display: none;
-}
-
-.crumb.selected, .crumb:hover {
-    background-color: var(--toolbar-bg-color);
-}
-
-.crumb:not(.selected) .node-label-name {
-    color: var(--dom-tag-name-color);
-}
-
-.crumb:not(.selected) .node-label-class {
-    color: var(--dom-attribute-name-color);
-}
diff --git a/front_end/elements/classesPaneWidget.css b/front_end/elements/classesPaneWidget.css
deleted file mode 100644
index ee810fe..0000000
--- a/front_end/elements/classesPaneWidget.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.styles-element-classes-pane {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: 1px solid rgb(189, 189, 189);
-    padding: 6px 2px 2px;
-}
-
-.styles-element-classes-container {
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: flex-start;
-}
-
-.styles-element-classes-pane label {
-    margin-right: 15px;
-}
-
-.styles-element-classes-pane .title-container {
-    padding-bottom: 2px;
-}
-
-.styles-element-classes-pane .new-class-input {
-    padding-left: 3px;
-    padding-right: 3px;
-    overflow: hidden;
-    border: 1px solid #ddd;
-    line-height: 15px;
-    margin-left: 3px;
-    width: calc(100% - 7px);
-    background-color: #fff;
-    cursor: text;
-}
diff --git a/front_end/elements/computedStyleSidebarPane.css b/front_end/elements/computedStyleSidebarPane.css
deleted file mode 100644
index d6055ad..0000000
--- a/front_end/elements/computedStyleSidebarPane.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.computed-properties {
-    -webkit-user-select: text;
-    flex-shrink: 0;
-}
-
-.styles-sidebar-pane-toolbar {
-    border-bottom: 1px solid #eee;
-    flex-shrink: 0;
-}
-
-.styles-sidebar-pane-filter-box {
-    flex: auto;
-    display: flex;
-}
-
-.styles-sidebar-pane-filter-box > input {
-    outline: none !important;
-    border: none;
-    width: 100%;
-    background: transparent;
-    margin-left: 4px;
-}
-
-.styles-filter-engaged {
-    background-color: rgba(255, 255, 0, 0.5);
-}
-
-:host-context(.-theme-with-dark-background) .styles-filter-engaged {
-    background-color: hsla(133, 100%, 30%, 0.5);
-}
diff --git a/front_end/elements/computedStyleWidgetTree.css b/front_end/elements/computedStyleWidgetTree.css
deleted file mode 100644
index f33a4ae..0000000
--- a/front_end/elements/computedStyleWidgetTree.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.computed-style-property {
-    display: flex;
-    overflow: hidden;
-    flex: auto;
-}
-
-.computed-style-property .property-name {
-    min-width: 5em;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    flex-shrink: 1;
-    flex-basis: 16em;
-    flex-grow: 1;
-}
-
-.computed-style-property .property-value {
-    margin-left: 2em;
-    position: relative;
-    display: flex;
-    flex-shrink: 0;
-    flex-basis: 5em;
-    flex-grow: 10;
-}
-
-.computed-style-property .property-value-text {
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.tree-outline li:hover .goto-source-icon {
-    display: block;
-    margin-top: -2px;
-}
-
-.goto-source-icon {
-    background-color: #5a5a5a;
-    display: none;
-    position: absolute;
-    left: -16px;
-}
-
-.goto-source-icon:hover {
-    background-color: #333;
-}
-
-.computed-style-property-inherited {
-    opacity: 0.5;
-}
-
-.trace-link {
-    user-select: none;
-    float: right;
-    padding-left: 1em;
-    position: relative;
-    z-index: 1;
-}
-
-.property-trace {
-    text-overflow: ellipsis;
-    overflow: hidden;
-    flex-grow: 1;
-}
-
-.property-trace-selector {
-    color: gray;
-    padding-left: 2em;
-}
-
-.property-trace-value {
-    position: relative;
-    display: inline-block;
-    margin-left: 2em;
-}
-
-.property-trace-inactive .property-trace-value::before {
-    position: absolute;
-    content: ".";
-    border-bottom: 1px solid rgba(0, 0, 0, 0.35);
-    top: 0;
-    bottom: 5px;
-    left: 0;
-    right: 0;
-}
-
-.tree-outline li.odd-row {
-    position: relative;
-    background-color: #F5F5F5;
-}
-
-.tree-outline, .tree-outline ol {
-    padding-left: 0;
-}
-
-.tree-outline li:hover {
-    background-color: rgb(235, 242, 252);
-    cursor: pointer;
-}
-
-.tree-outline li::before {
-    margin-left: 4px;
-}
-
-.delimeter {
-    color: transparent;
-}
-
-.delimeter::selection {
-    color: transparent;
-}
diff --git a/front_end/elements/domLinkifier.css b/front_end/elements/domLinkifier.css
deleted file mode 100644
index 30aada8..0000000
--- a/front_end/elements/domLinkifier.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-  display: inline;
-}
-
-.node-link {
-    cursor: pointer;
-    display: inline;
-    pointer-events: auto;
-}
-
-.node-label-name {
-    color: rgb(136, 18, 128);
-}
-
-.node-label-class, .node-label-pseudo {
-    color: rgb(153, 69, 0);
-}
diff --git a/front_end/elements/elementStatePaneWidget.css b/front_end/elements/elementStatePaneWidget.css
deleted file mode 100644
index e018179..0000000
--- a/front_end/elements/elementStatePaneWidget.css
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.styles-element-state-pane {
-    overflow: hidden;
-    padding-left: 2px;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: 1px solid rgb(189, 189, 189);
-    margin-top: 0;
-    padding-bottom: 2px;
-}
-
-.styles-element-state-pane > div {
-    margin: 8px 4px 6px;
-}
-
-.styles-element-state-pane > table {
-    width: 100%;
-    border-spacing: 0;
-}
-
-.styles-element-state-pane td {
-    padding: 0;
-}
diff --git a/front_end/elements/elementsPanel.css b/front_end/elements/elementsPanel.css
deleted file mode 100644
index 7029b23..0000000
--- a/front_end/elements/elementsPanel.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#elements-content {
-    flex: 1 1;
-    overflow: auto;
-    padding: 2px 0 0 0;
-}
-
-#elements-content:not(.elements-wrap) > div {
-    display: inline-block;
-    min-width: 100%;
-}
-
-#elements-content.elements-wrap {
-    overflow-x: hidden;
-}
-
-#elements-crumbs {
-    flex: 0 0 23px;
-    background-color: white;
-    border-top: 1px solid var(--divider-color);
-    overflow: hidden;
-    width: 100%;
-}
-
-.style-panes-wrapper {
-    overflow: auto;
-}
-
-.style-panes-wrapper > div:not(:first-child) {
-    border-top: 1px solid var(--divider-color);
-}
-
-.elements-tree-header {
-    height: 24px;
-    border-top: 1px solid var(--divider-color);
-    border-bottom: 1px solid var(--divider-color);
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-}
-
-.elements-tree-header-frame {
-    margin-left: 6px;
-    margin-right: 6px;
-    flex: none;
-}
diff --git a/front_end/elements/elementsTreeOutline.css b/front_end/elements/elementsTreeOutline.css
deleted file mode 100644
index c57ea71..0000000
--- a/front_end/elements/elementsTreeOutline.css
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.elements-disclosure {
-    width: 100%;
-    display: inline-block;
-    line-height: normal;
-}
-
-.elements-disclosure li {
-    /** Keep margin-left & padding-left in sync with ElementsTreeElements.updateDecorators **/
-    padding: 0 0 0 14px;
-    margin-top: 1px;
-    margin-left: -2px;
-    word-wrap: break-word;
-    position: relative;
-    min-height: 15px;
-    line-height: 15px;
-}
-
-.elements-disclosure li.parent {
-    /** Keep it in sync with ElementsTreeElements.updateDecorators **/
-    margin-left: -13px;
-}
-
-.elements-disclosure li .selected-hint:before {
-    font-style: italic;
-    content: " == $0";
-    opacity: 0;
-    position: absolute;
-    white-space: pre;
-}
-
-.elements-disclosure li.selected .selected-hint:before {
-    opacity: 0.6;
-    color: var(--selection-inactive-fg-color);
-}
-
-.elements-disclosure li.selected:focus .selected-hint:before {
-    color: var(--selection-fg-color);
-}
-
-.elements-disclosure li.parent::before {
-    box-sizing: border-box;
-}
-
-.elements-disclosure li.parent::before {
-    -webkit-user-select: none;
-    -webkit-mask-image: url(Images/treeoutlineTriangles.png);
-    -webkit-mask-size: 32px 24px;
-    content: '\00a0\00a0';
-    color: transparent;
-    text-shadow: none;
-    margin-right: -3px;
-}
-
-.elements-disclosure li.always-parent::before {
-    visibility: hidden;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-.elements-disclosure li.parent::before {
-    -webkit-mask-image: url(Images/treeoutlineTriangles_2x.png);
-}
-} /* media */
-
-.elements-disclosure li.parent::before {
-    -webkit-mask-position: 0 0;
-    background-color: #727272;
-}
-
-.elements-disclosure li .selection {
-    display: none;
-    z-index: -1;
-}
-
-.elements-disclosure li.hovered:not(.selected) .selection {
-    display: block;
-    left: 3px;
-    right: 3px;
-    background-color: rgba(56, 121, 217, 0.1);
-    border-radius: 5px;
-}
-
-.elements-disclosure li.parent.expanded::before {
-    -webkit-mask-position: -16px 0;
-}
-
-.elements-disclosure li.selected .selection {
-    display: block;
-    background-color: var(--selection-inactive-bg-color);
-}
-
-.elements-disclosure ol {
-    list-style-type: none;
-    /** Keep it in sync with ElementsTreeElements.updateDecorators **/
-    -webkit-padding-start: 12px;
-    margin: 0;
-}
-
-.elements-disclosure ol.children {
-    display: none;
-}
-
-.elements-disclosure ol.children.expanded {
-    display: block;
-}
-
-.elements-disclosure li .webkit-html-tag.close {
-    margin-left: -12px;
-}
-
-.elements-disclosure > ol {
-    position: relative;
-    margin: 0;
-    cursor: default;
-    min-width: 100%;
-    min-height: 100%;
-    padding-left: 2px;
-}
-
-.elements-disclosure ol li.selected:focus {
-    color: var(--selection-fg-color);
-}
-
-.elements-disclosure ol li.parent.selected:focus::before {
-    background-color: var(--selection-fg-color);
-}
-
-.elements-disclosure ol li.selected:focus * {
-    color: inherit;
-}
-
-.elements-disclosure ol li.selected:focus .selection {
-    background-color: var(--selection-bg-color);
-}
-
-.elements-tree-outline ol.shadow-root-depth-4 {
-    background-color: rgba(0, 0, 0, 0.04);
-}
-
-.elements-tree-outline ol.shadow-root-depth-3 {
-    background-color: rgba(0, 0, 0, 0.03);
-}
-
-.elements-tree-outline ol.shadow-root-depth-2 {
-    background-color: rgba(0, 0, 0, 0.02);
-}
-
-.elements-tree-outline ol.shadow-root-depth-1 {
-    background-color: rgba(0, 0, 0, 0.01);
-}
-
-.elements-tree-outline ol.shadow-root-deep {
-    background-color: transparent;
-}
-
-.elements-tree-editor {
-    box-shadow: var(--drop-shadow);
-    margin-right: 4px;
-}
-
-.elements-disclosure li.elements-drag-over .selection {
-    display: block;
-    margin-top: -2px;
-    border-top: 2px solid var(--selection-bg-color);
-}
-
-.elements-disclosure li.in-clipboard .highlight {
-    outline: 1px dotted darkgrey;
-}
-
-.CodeMirror {
-    background-color: white;
-    height: 300px !important;
-}
-
-.CodeMirror-lines {
-    padding: 0;
-}
-
-.CodeMirror pre {
-    padding: 0;
-}
-
-button, input, select {
-  font-family: inherit;
-  font-size: inherit;
-}
-
-.editing {
-    box-shadow: var(--drop-shadow);
-    background-color: white;
-    text-overflow: clip !important;
-    padding-left: 2px;
-    margin-left: -2px;
-    padding-right: 2px;
-    margin-right: -2px;
-    margin-bottom: -1px;
-    padding-bottom: 1px;
-    opacity: 1.0 !important;
-}
-
-.editing,
-.editing * {
-    color: #222 !important;
-    text-decoration: none !important;
-}
-
-.editing br {
-    display: none;
-}
-
-.elements-gutter-decoration {
-    position: absolute;
-    left: 2px;
-    margin-top: 2px;
-    height: 9px;
-    width: 9px;
-    border-radius: 5px;
-    border: 1px solid orange;
-    background-color: orange;
-    cursor: pointer;
-}
-
-.elements-gutter-decoration.elements-has-decorated-children {
-    opacity: 0.5;
-}
-
-.add-attribute {
-    margin-left: 1px;
-    margin-right: 1px;
-    white-space: nowrap;
-}
-
-.elements-tree-nowrap, .elements-tree-nowrap .li {
-    white-space: pre !important;
-}
-
-.elements-disclosure .elements-tree-nowrap li {
-    word-wrap: normal;
-}
-
-/* DOM update highlight */
-@-webkit-keyframes dom-update-highlight-animation {
-    from {
-        background-color: rgb(158, 54, 153);
-        color: white;
-    }
-    80% {
-        background-color: rgb(245, 219, 244);
-        color: inherit;
-    }
-    to {
-        background-color: inherit;
-    }
-}
-
-@-webkit-keyframes dom-update-highlight-animation-dark {
-    from {
-        background-color: rgb(158, 54, 153);
-        color: white;
-    }
-    80% {
-        background-color: #333;
-        color: inherit;
-    }
-    to {
-        background-color: inherit;
-    }
-}
-
-.dom-update-highlight {
-    -webkit-animation: dom-update-highlight-animation 1.4s 1 cubic-bezier(0, 0, 0.2, 1);
-    border-radius: 2px;
-}
-
-:host-context(.-theme-with-dark-background) .dom-update-highlight {
-    -webkit-animation: dom-update-highlight-animation-dark 1.4s 1 cubic-bezier(0, 0, 0.2, 1);
-}
-
-.elements-disclosure.single-node li {
-    padding-left: 2px;
-}
-
-.elements-tree-shortcut-title {
-    color: rgb(87, 87, 87);
-}
-
-ol:hover > li > .elements-tree-shortcut-link {
-    display: initial;
-}
-
-.elements-tree-shortcut-link {
-    color: rgb(87, 87, 87);
-    display: none;
-}
-
-ol li.selected:focus .webkit-html-tag-name,
-ol li.selected:focus .webkit-html-close-tag-name,
-ol li.selected:focus .webkit-html-attribute-value,
-ol li.selected:focus .devtools-link {
-    color: var(--selection-fg-color);
-}
-
-.elements-disclosure .gutter-container {
-    position: absolute;
-    top: 0;
-    left: 0;
-    cursor: pointer;
-    width: 15px;
-    height: 15px;
-}
-
-.gutter-menu-icon {
-    display: none;
-    transform: rotate(-90deg) scale(0.8);
-    background-color: white;
-    position: relative;
-    left: -7px;
-    top: -3px;
-}
-
-.elements-disclosure li.selected .gutter-container:not(.has-decorations) .gutter-menu-icon {
-    display: block;
-}
-
-/** Guide line */
-li.selected {
-    z-index: 0;
-}
-
-li.hovered:not(.always-parent) + ol.children, .elements-tree-outline ol.shadow-root, li.selected:not(.always-parent) + ol.children {
-    margin-left: 5px;
-    -webkit-padding-start: 6px;
-    border-width: 1px;
-    border-left-style: solid;
-}
-
-li.hovered:not(.always-parent) + ol.children:not(.shadow-root) {
-    border-color: hsla(0,0%,0%,0.1);
-}
-
-.elements-tree-outline ol.shadow-root {
-    border-color: hsla(0,0%,80%,1);
-}
-
-li.selected:not(.always-parent) + ol.children {
-    border-color: hsla(216,68%,80%,1) !important;
-}
diff --git a/front_end/elements/metricsSidebarPane.css b/front_end/elements/metricsSidebarPane.css
deleted file mode 100644
index 9f9266b..0000000
--- a/front_end/elements/metricsSidebarPane.css
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.metrics {
-    padding: 8px;
-    font-size: 10px;
-    text-align: center;
-    white-space: nowrap;
-    min-height: var(--metrics-height);
-    display: flex;
-    flex-direction: column;
-    -webkit-align-items: center;
-    -webkit-justify-content: center;
-}
-
-:host {
-    --metrics-height: 190px;
-    height: var(--metrics-height);
-    contain: strict;
-}
-
-:host-context(.-theme-with-dark-background) .metrics {
-    color: #222;
-}
-
-:host-context(.-theme-with-dark-background) .metrics > div:hover {
-    color: #ccc;
-}
-
-.metrics .label {
-    position: absolute;
-    font-size: 10px;
-    margin-left: 3px;
-    padding-left: 2px;
-    padding-right: 2px;
-}
-
-.metrics .position {
-    border: 1px rgb(66%, 66%, 66%) dotted;
-    background-color: white;
-    display: inline-block;
-    text-align: center;
-    padding: 3px;
-    margin: 3px;
-}
-
-.metrics .margin {
-    border: 1px dashed;
-    background-color: white;
-    display: inline-block;
-    text-align: center;
-    vertical-align: middle;
-    padding: 3px;
-    margin: 3px;
-}
-
-.metrics .border {
-    border: 1px black solid;
-    background-color: white;
-    display: inline-block;
-    text-align: center;
-    vertical-align: middle;
-    padding: 3px;
-    margin: 3px;
-}
-
-.metrics .padding {
-    border: 1px grey dashed;
-    background-color: white;
-    display: inline-block;
-    text-align: center;
-    vertical-align: middle;
-    padding: 3px;
-    margin: 3px;
-}
-
-.metrics .content {
-    position: static;
-    border: 1px gray solid;
-    background-color: white;
-    display: inline-block;
-    text-align: center;
-    vertical-align: middle;
-    padding: 3px;
-    margin: 3px;
-    min-width: 80px;
-    overflow: visible;
-}
-
-.metrics .content span {
-    display: inline-block;
-}
-
-.metrics .editing {
-    position: relative;
-    z-index: 100;
-    cursor: text;
-}
-
-.metrics .left {
-    display: inline-block;
-    vertical-align: middle;
-}
-
-.metrics .right {
-    display: inline-block;
-    vertical-align: middle;
-}
-
-.metrics .top {
-    display: inline-block;
-}
-
-.metrics .bottom {
-    display: inline-block;
-}
diff --git a/front_end/elements/module.json b/front_end/elements/module.json
deleted file mode 100644
index f789cec..0000000
--- a/front_end/elements/module.json
+++ /dev/null
@@ -1,301 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "elements",
-            "title": "Elements",
-            "order": 10,
-            "className": "Elements.ElementsPanel"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "SDK.RemoteObject",
-                "SDK.DOMNode",
-                "SDK.DeferredDOMNode"
-            ],
-            "className": "Elements.ElementsPanel.ContextMenuProvider"
-        },
-        {
-            "type": "@Common.Renderer",
-            "contextTypes": [
-                "SDK.DOMNode",
-                "SDK.DeferredDOMNode"
-            ],
-            "className": "Elements.ElementsTreeOutline.Renderer"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "SDK.DOMNode",
-                "SDK.DeferredDOMNode",
-                "SDK.RemoteObject"
-            ],
-            "destination": "Elements panel",
-            "className": "Elements.ElementsPanel.DOMNodeRevealer"
-        },
-        {
-            "type": "@Common.Linkifier",
-            "contextTypes": [
-                "SDK.DOMNode",
-                "SDK.DeferredDOMNode"
-            ],
-            "className": "Elements.DOMLinkifier.Linkifier"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "SDK.CSSProperty"
-            ],
-            "destination": "styles sidebar",
-            "className": "Elements.ElementsPanel.CSSPropertyRevealer"
-        },
-        {
-            "type": "setting",
-            "category": "Elements",
-            "order": 0,
-            "title": "Color format:",
-            "settingName": "colorFormat",
-            "settingType": "enum",
-            "defaultValue": "original",
-            "options": [
-                {
-                    "title": "Set color format as authored",
-                    "text": "As authored",
-                    "value": "original"
-                },
-                {
-                    "title": "Set color format to HEX",
-                    "text": "HEX: #dac0de",
-                    "value": "hex",
-                    "raw": true
-                },
-                {
-                    "title": "Set color format to RGB",
-                    "text": "RGB: rgb(128, 255, 255)",
-                    "value": "rgb",
-                    "raw": true
-                },
-                {
-                    "title": "Set color format to HSL",
-                    "text": "HSL: hsl(300, 80%, 90%)",
-                    "value": "hsl",
-                    "raw": true
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Elements",
-            "order": 1,
-            "title": "Show user agent shadow DOM",
-            "settingName": "showUAShadowDOM",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Elements",
-            "order": 2,
-            "title": "Word wrap",
-            "settingName": "domWordWrap",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable DOM word wrap"
-                },
-                {
-                    "value": false,
-                    "title": "Disable DOM word wrap"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Elements",
-            "order": 3,
-            "title": "Show HTML comments",
-            "settingName": "showHTMLComments",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show HTML comments"
-                },
-                {
-                    "value": false,
-                    "title": "Hide HTML comments"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Elements",
-            "order": 4,
-            "title": "Reveal DOM node on hover",
-            "settingName": "highlightNodeOnHoverInOverlay",
-            "settingType": "boolean",
-            "defaultValue": true
-        },
-        {
-            "type": "setting",
-            "settingName": "showEventListenersForAncestors",
-            "settingType": "boolean",
-            "defaultValue": true
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "Elements.ElementStatePaneWidget.ButtonProvider",
-            "order": 1,
-            "location": "styles-sidebarpane-toolbar"
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "Elements.ClassesPaneWidget.ButtonProvider",
-            "order": 2,
-            "location": "styles-sidebarpane-toolbar"
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "Elements.StylesSidebarPane.ButtonProvider",
-            "order": 100,
-            "location": "styles-sidebarpane-toolbar"
-        },
-        {
-            "type": "action",
-            "actionId": "elements.hide-element",
-            "contextTypes": [
-                "Elements.ElementsPanel"
-            ],
-            "className": "Elements.ElementsActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "H"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "elements.edit-as-html",
-            "contextTypes": [
-                "Elements.ElementsPanel"
-            ],
-            "className": "Elements.ElementsActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "F2"
-                }
-            ]
-        },
-        {
-            "type": "@Elements.MarkerDecorator",
-            "className": "Elements.ElementsPanel.PseudoStateMarkerDecorator",
-            "marker": "pseudo-state-marker"
-        },
-        {
-            "type": "@Elements.MarkerDecorator",
-            "factoryName": "Elements.GenericDecorator",
-            "marker": "hidden-marker",
-            "title": "Element is hidden",
-            "color": "#555"
-        },
-        {
-            "type": "action",
-            "actionId": "elements.toggle-element-search",
-            "className": "Elements.InspectElementModeController.ToggleSearchActionDelegate",
-            "title": "Select an element in the page to inspect it",
-            "iconClass": "largeicon-node-search",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Shift+C"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Shift+C"
-                }
-            ]
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "actionId": "elements.toggle-element-search",
-            "location": "main-toolbar-left",
-            "order": 0
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "elements-sidebar",
-            "category": "Elements",
-            "className": "Elements.ElementsPanel"
-        },
-        {
-            "type": "view",
-            "location": "elements-sidebar",
-            "id": "elements.eventListeners",
-            "title": "Event Listeners",
-            "order": 5,
-            "hasToolbar": true,
-            "persistence": "permanent",
-            "className": "Elements.EventListenersWidget"
-        },
-        {
-            "type": "view",
-            "location": "elements-sidebar",
-            "id": "elements.domProperties",
-            "title": "Properties",
-            "order": 7,
-            "persistence": "permanent",
-            "className": "Elements.PropertiesWidget"
-        }
-    ],
-    "dependencies": [
-        "browser_components",
-        "extensions",
-        "inline_editor",
-        "color_picker",
-        "event_listeners"
-    ],
-    "scripts": [
-        "InspectElementModeController.js",
-        "ColorSwatchPopoverIcon.js",
-        "ComputedStyleModel.js",
-        "DOMLinkifier.js",
-        "DOMPath.js",
-        "ElementsBreadcrumbs.js",
-        "ElementsSidebarPane.js",
-        "ElementsTreeElement.js",
-        "ElementsTreeOutline.js",
-        "EventListenersWidget.js",
-        "MarkerDecorator.js",
-        "MetricsSidebarPane.js",
-        "PlatformFontsWidget.js",
-        "PropertiesWidget.js",
-        "StylePropertyHighlighter.js",
-        "StylesSidebarPane.js",
-        "StylePropertyTreeElement.js",
-        "ComputedStyleWidget.js",
-        "ElementsPanel.js",
-        "ClassesPaneWidget.js",
-        "ElementStatePaneWidget.js",
-        "ElementsTreeElementHighlighter.js"
-    ],
-    "resources": [
-        "breadcrumbs.css",
-        "classesPaneWidget.css",
-        "computedStyleSidebarPane.css",
-        "computedStyleWidgetTree.css",
-        "domLinkifier.css",
-        "elementsPanel.css",
-        "elementStatePaneWidget.css",
-        "elementsTreeOutline.css",
-        "metricsSidebarPane.css",
-        "platformFontsWidget.css",
-        "propertiesWidget.css",
-        "stylesSectionTree.css",
-        "stylesSidebarPane.css"
-    ]
-}
diff --git a/front_end/elements/platformFontsWidget.css b/front_end/elements/platformFontsWidget.css
deleted file mode 100644
index a9b99c5..0000000
--- a/front_end/elements/platformFontsWidget.css
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    -webkit-user-select: text;
-}
-
-.platform-fonts {
-    flex-shrink: 0;
-}
-
-.font-name {
-    font-weight: bold;
-}
-
-.font-usage {
-    color: #888;
-    padding-left: 3px;
-}
-
-.title {
-    padding: 0 5px;
-    border-top: 1px solid;
-    border-bottom: 1px solid;
-    border-color: #ddd;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    height: 24px;
-    background-color: #f1f1f1;
-    display: flex;
-    align-items: center;
-}
-
-.stats-section {
-    margin: 5px 0;
-}
-
-.font-stats-item {
-    padding-left: 1em;
-}
-
-.font-stats-item .font-delimeter {
-    margin: 0 1ex 0 1ex;
-}
-
diff --git a/front_end/elements/propertiesWidget.css b/front_end/elements/propertiesWidget.css
deleted file mode 100644
index e4803b3..0000000
--- a/front_end/elements/propertiesWidget.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (c) 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.properties-widget-section {
-    padding: 2px 0px 2px 5px;
-    flex: none;
-}
diff --git a/front_end/elements/stylesSectionTree.css b/front_end/elements/stylesSectionTree.css
deleted file mode 100644
index 43bd7e0..0000000
--- a/front_end/elements/stylesSectionTree.css
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tree-outline {
-    padding: 0;
-}
-
-.tree-outline li.not-parsed-ok {
-    margin-left: 0;
-}
-
-.tree-outline li.filter-match {
-    background-color: rgba(255, 255, 0, 0.5);
-}
-
-:host-context(.-theme-with-dark-background) .tree-outline li.filter-match {
-    background-color: hsla(133, 100%, 30%, 0.5);
-}
-
-.tree-outline li.overloaded.filter-match {
-    background-color: rgba(255, 255, 0, 0.25);
-}
-
-:host-context(.-theme-with-dark-background) .tree-outline li.overloaded.filter-match {
-    background-color: hsla(133, 100%, 30%, 0.25);
-}
-
-.tree-outline li.not-parsed-ok .exclamation-mark {
-    display: inline-block;
-    position: relative;
-    width: 11px;
-    height: 10px;
-    margin: 0 7px 0 0;
-    top: 1px;
-    left: -36px; /* outdent to compensate for the top-level property indent */
-    -webkit-user-select: none;
-    cursor: default;
-    z-index: 1;
-}
-
-.tree-outline li {
-    margin-left: 12px;
-    padding-left: 22px;
-    white-space: normal;
-    text-overflow: ellipsis;
-    cursor: auto;
-    display: block;
-}
-
-.tree-outline li::before {
-    display: none;
-}
-
-.tree-outline li .webkit-css-property {
-    margin-left: -22px; /* outdent the first line of longhand properties (in an expanded shorthand) to compensate for the "padding-left" shift in .tree-outline li */
-}
-
-.tree-outline > li {
-    padding-left: 38px;
-    clear: both;
-    min-height: 14px;
-}
-
-.tree-outline > li .webkit-css-property {
-    margin-left: -38px; /* outdent the first line of the top-level properties to compensate for the "padding-left" shift in .tree-outline > li */
-}
-
-.tree-outline > li.child-editing {
-    padding-left: 8px;
-}
-
-.tree-outline > li.child-editing .text-prompt {
-    white-space: pre-wrap;
-}
-
-.tree-outline > li.child-editing .webkit-css-property {
-    margin-left: 0;
-}
-
-.tree-outline li.child-editing {
-    word-wrap: break-word !important;
-    white-space: normal !important;
-    padding-left: 0;
-}
-
-ol:not(.tree-outline) {
-    display: none;
-    margin: 0;
-    -webkit-padding-start: 12px;
-    list-style: none;
-}
-
-ol.expanded {
-    display: block;
-}
-
-.tree-outline li .info {
-    padding-top: 4px;
-    padding-bottom: 3px;
-}
-
-.enabled-button {
-    visibility: hidden;
-    float: left;
-    font-size: 10px;
-    margin: 0;
-    vertical-align: top;
-    position: relative;
-    z-index: 1;
-    width: 18px;
-    left: -40px; /* original -2px + (-38px) to compensate for the first line outdent */
-    top: 1px;
-    height: 13px;
-}
-
-.tree-outline li.editing .enabled-button {
-    display: none !important;
-}
-
-.overloaded:not(.has-ignorable-error),
-.inactive,
-.disabled,
-.not-parsed-ok:not(.has-ignorable-error) {
-    text-decoration: line-through;
-}
-
-.has-ignorable-error .webkit-css-property {
-    color: inherit;
-}
-
-.implicit,
-.inherited {
-    opacity: 0.5;
-}
-
-.has-ignorable-error {
-    color: gray;
-}
-
-.tree-outline li.editing {
-    margin-left: 10px;
-    text-overflow: clip;
-}
-
-.tree-outline li.editing-sub-part {
-    padding: 3px 6px 8px 18px;
-    margin: -1px -6px -8px -6px;
-    text-overflow: clip;
-}
-
-:host-context(.no-affect) .tree-outline li {
-    opacity: 0.5;
-}
-
-:host-context(.no-affect) .tree-outline li.editing {
-    opacity: 1.0;
-}
-
-:host-context(.styles-panel-hovered:not(.read-only)) .webkit-css-property:hover,
-:host-context(.styles-panel-hovered:not(.read-only)) .value:hover {
-    text-decoration: underline;
-    cursor: default;
-}
-
-.styles-clipboard-only {
-    display: inline-block;
-    width: 0;
-    opacity: 0;
-    pointer-events: none;
-    white-space: pre;
-}
-
-.tree-outline li.child-editing .styles-clipboard-only {
-    display: none;
-}
-
-/* Matched styles */
-
-:host-context(.matched-styles) .tree-outline li {
-    margin-left: 0 !important;
-}
-
-.expand-icon {
-    -webkit-user-select: none;
-    margin-left: -6px;
-    margin-right: 2px;
-    margin-bottom: -2px;
-}
-
-.tree-outline li:not(.parent) .expand-icon {
-    display: none;
-}
-
-:host-context(.matched-styles:not(.read-only):hover) .enabled-button {
-    visibility: visible;
-}
-
-:host-context(.matched-styles:not(.read-only)) .tree-outline li.disabled .enabled-button {
-    visibility: visible;
-}
-
-:host-context(.matched-styles) ol.expanded {
-    margin-left: 16px;
-}
diff --git a/front_end/elements/stylesSidebarPane.css b/front_end/elements/stylesSidebarPane.css
deleted file mode 100644
index a4f3b7c..0000000
--- a/front_end/elements/stylesSidebarPane.css
+++ /dev/null
@@ -1,231 +0,0 @@
-/**
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.styles-section {
-    min-height: 18px;
-    white-space: nowrap;
-    -webkit-user-select: text;
-    border-bottom: 1px solid var(--divider-color);
-    position: relative;
-    overflow: hidden;
-}
-
-.styles-section > div {
-    padding: 2px 2px 4px 4px;
-}
-
-.styles-section:last-child {
-    border-bottom: none;
-}
-
-.styles-section.read-only {
-    background-color: #fafafa;
-    font-style: italic;
-}
-
-.styles-section[data-keyboard-focus="true"]:focus {
-    background-color: hsl(214, 67%, 95%);
-}
-
-.styles-section.read-only[data-keyboard-focus="true"]:focus {
-    background-color: hsl(215, 25%, 91%);
-}
-
-.styles-filter-engaged,
-.styles-section .simple-selector.filter-match {
-    background-color: rgba(255, 255, 0, 0.5);
-}
-
-:host-context(.-theme-with-dark-background) .styles-filter-engaged,
-:host-context(.-theme-with-dark-background) .styles-section .simple-selector.filter-match {
-    background-color: hsla(133, 100%, 30%, 0.5);
-}
-
-.sidebar-pane-closing-brace {
-    clear: both;
-}
-
-.styles-section-title {
-    background-origin: padding;
-    background-clip: padding;
-    word-wrap: break-word;
-    white-space: normal;
-}
-
-.styles-section-title .media-list {
-    color: #888;
-}
-
-.styles-section-title .media-list.media-matches .media.editable-media {
-    color: #222;
-}
-
-.styles-section-title .media:not(.editing-media),
-.styles-section-title .media:not(.editing-media) .subtitle {
-    overflow: hidden;
-}
-
-.styles-section-title .media .subtitle {
-    float: right;
-    color: rgb(85, 85, 85);
-}
-
-.styles-section-subtitle {
-    color: rgb(85, 85, 85);
-    float: right;
-    margin-left: 5px;
-    max-width: 100%;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-    height: 15px;
-    margin-bottom: -1px;
-}
-
-.styles-section .styles-section-subtitle .devtools-link {
-    color: inherit;
-}
-
-.styles-section .selector {
-    color: #888;
-}
-
-.styles-section .simple-selector.selector-matches, .styles-section.keyframe-key {
-    color: #222;
-}
-
-.styles-section .devtools-link {
-    user-select: none;
-}
-
-.styles-section .style-properties {
-    margin: 0;
-    padding: 2px 4px 0 0;
-    list-style: none;
-    clear: both;
-    display: flex;
-}
-
-.styles-section.matched-styles .style-properties {
-    padding-left: 0;
-}
-
-@keyframes styles-element-state-pane-slidein {
-    from {
-        margin-top: -60px;
-    }
-    to {
-        margin-top: 0px;
-    }
-}
-
-@keyframes styles-element-state-pane-slideout {
-    from {
-        margin-top: 0px;
-    }
-    to {
-        margin-top: -60px;
-    }
-}
-
-.styles-sidebar-toolbar-pane {
-    position: relative;
-    animation-duration: 0.1s;
-    animation-direction: normal;
-}
-
-.styles-sidebar-toolbar-pane-container {
-    position: relative;
-    overflow: hidden;
-    flex-shrink: 0;
-}
-
-.styles-selector {
-    cursor: text;
-}
-
-.styles-sidebar-pane-toolbar-container {
-    flex-shrink: 0;
-    overflow: hidden;
-    position: sticky;
-    top: 0;
-    background-color: var(--toolbar-bg-color);
-    z-index: 1;
-}
-
-.styles-sidebar-pane-toolbar {
-    border-bottom: 1px solid #eee;
-    flex-shrink: 0;
-}
-
-.styles-sidebar-pane-filter-box {
-    flex: auto;
-    display: flex;
-}
-
-.styles-sidebar-pane-filter-box > input {
-    outline: none !important;
-    border: none;
-    width: 100%;
-    background: white;
-    padding-left: 4px;
-    margin: 3px;
-}
-
-.styles-sidebar-pane-filter-box > input:hover {
-    box-shadow: var(--focus-ring-inactive-shadow);
-}
-
-.styles-sidebar-pane-filter-box > input:focus {
-    box-shadow: var(--focus-ring-active-shadow);
-}
-
-.styles-section.styles-panel-hovered:not(.read-only) span.simple-selector:hover,
-.styles-section.styles-panel-hovered:not(.read-only) .media-text :hover{
-    text-decoration: underline;
-    cursor: default;
-}
-
-.sidebar-separator {
-    background-color: var(--toolbar-bg-color);
-    padding: 0 5px;
-    border-bottom: 1px solid var(--divider-color);
-    color: rgb(50, 50, 50);
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    line-height: 22px;
-}
-
-.sidebar-separator > span.monospace {
-    background: rgb(255, 255, 255);
-    padding: 1px 3px;
-    border: 1px solid var(--divider-color);
-}
-
-.sidebar-pane-section-toolbar {
-    position: absolute;
-    right: 0;
-    bottom: 0;
-    visibility: hidden;
-    background-color: rgba(255, 255, 255, 0.9);
-    z-index: 0;
-}
-
-.styles-section[data-keyboard-focus="true"]:focus .sidebar-pane-section-toolbar {
-    background-color: hsla(214, 67%, 95%, 0.9);
-}
-
-.styles-pane:not(.is-editing-style) .styles-section.matched-styles:not(.read-only):hover .sidebar-pane-section-toolbar {
-    visibility: visible;
-}
-
-.styles-show-all {
-    margin-left: 16px;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    max-width: -webkit-fill-available;
-}
diff --git a/front_end/elements_test_runner/EditDOMTestRunner.js b/front_end/elements_test_runner/EditDOMTestRunner.js
deleted file mode 100644
index 56efb45..0000000
--- a/front_end/elements_test_runner/EditDOMTestRunner.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ElementsTestRunner.doAddAttribute = function(testName, dataNodeId, attributeText, next) {
-  ElementsTestRunner.domActionTestForNodeId(testName, dataNodeId, testBody, next);
-
-  function testBody(node, done) {
-    ElementsTestRunner.editNodePart(node, 'webkit-html-attribute');
-    eventSender.keyDown('Tab');
-    TestRunner.deprecatedRunAfterPendingDispatches(testContinuation);
-
-    function testContinuation() {
-      const editorElement = UI.panels.elements._treeOutlines[0]._shadowRoot.getSelection().anchorNode.parentElement;
-      editorElement.textContent = attributeText;
-      editorElement.dispatchEvent(TestRunner.createKeyEvent('Enter'));
-      TestRunner.addSniffer(Elements.ElementsTreeOutline.prototype, '_updateModifiedNodes', done);
-    }
-  }
-};
-
-ElementsTestRunner.domActionTestForNodeId = function(testName, dataNodeId, testBody, next) {
-  function callback(testNode, continuation) {
-    ElementsTestRunner.selectNodeWithId(dataNodeId, continuation);
-  }
-
-  ElementsTestRunner.domActionTest(testName, callback, testBody, next);
-};
-
-ElementsTestRunner.domActionTest = function(testName, dataNodeSelectionCallback, testBody, next) {
-  const testNode = ElementsTestRunner.expandedNodeWithId(testName);
-  TestRunner.addResult('==== before ====');
-  ElementsTestRunner.dumpElementsTree(testNode);
-  dataNodeSelectionCallback(testNode, step0);
-
-  function step0(node) {
-    TestRunner.deprecatedRunAfterPendingDispatches(step1.bind(null, node));
-  }
-
-  function step1(node) {
-    testBody(node, step2);
-  }
-
-  function step2() {
-    TestRunner.addResult('==== after ====');
-    ElementsTestRunner.dumpElementsTree(testNode);
-    next();
-  }
-};
-
-ElementsTestRunner.editNodePart = function(node, className) {
-  const treeElement = ElementsTestRunner.firstElementsTreeOutline().findTreeElement(node);
-  let textElement = treeElement.listItemElement.getElementsByClassName(className)[0];
-
-  if (!textElement && treeElement.childrenListElement)
-    textElement = treeElement.childrenListElement.getElementsByClassName(className)[0];
-
-  treeElement._startEditingTarget(textElement);
-  return textElement;
-};
-
-ElementsTestRunner.editNodePartAndRun = function(node, className, newValue, step2, useSniffer) {
-  const editorElement = ElementsTestRunner.editNodePart(node, className);
-  editorElement.textContent = newValue;
-  editorElement.dispatchEvent(TestRunner.createKeyEvent('Enter'));
-
-  if (useSniffer)
-    TestRunner.addSniffer(Elements.ElementsTreeOutline.prototype, '_updateModifiedNodes', step2);
-  else
-    TestRunner.deprecatedRunAfterPendingDispatches(step2);
-};
diff --git a/front_end/elements_test_runner/ElementsPanelShadowSelectionOnRefreshTestRunner.js b/front_end/elements_test_runner/ElementsPanelShadowSelectionOnRefreshTestRunner.js
deleted file mode 100644
index 335966c..0000000
--- a/front_end/elements_test_runner/ElementsPanelShadowSelectionOnRefreshTestRunner.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ElementsTestRunner.selectReloadAndDump = function(next, node) {
-  ElementsTestRunner.selectNode(node).then(onSelected);
-  let reloaded = false;
-  let selected = false;
-
-  function onSelected() {
-    TestRunner.reloadPage(onReloaded);
-    TestRunner.addSniffer(Elements.ElementsPanel.prototype, '_lastSelectedNodeSelectedForTest', onReSelected);
-  }
-
-  function onReloaded() {
-    reloaded = true;
-    maybeDumpSelectedNode();
-  }
-
-  function onReSelected() {
-    selected = true;
-    maybeDumpSelectedNode();
-  }
-
-  function maybeDumpSelectedNode() {
-    if (!reloaded || !selected)
-      return;
-
-    const selectedElement = ElementsTestRunner.firstElementsTreeOutline().selectedTreeElement;
-    const nodeName = (selectedElement ? selectedElement.node().nodeNameInCorrectCase() : 'null');
-    TestRunner.addResult('Selected node: \'' + nodeName + '\'');
-    next();
-  }
-};
diff --git a/front_end/elements_test_runner/ElementsTestRunner.js b/front_end/elements_test_runner/ElementsTestRunner.js
deleted file mode 100644
index d84c10f..0000000
--- a/front_end/elements_test_runner/ElementsTestRunner.js
+++ /dev/null
@@ -1,1116 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-/**
- * @param {string} idValue
- * @param {!Function} callback
- */
-ElementsTestRunner.selectNodeWithId = function(idValue, callback) {
-  callback = TestRunner.safeWrap(callback);
-  function onNodeFound(node) {
-    ElementsTestRunner.selectNode(node).then(callback.bind(null, node));
-  }
-  ElementsTestRunner.nodeWithId(idValue, onNodeFound);
-};
-
-/**
- * @param {!Object} node
- * @return {!Promise.<undefined>}
- */
-ElementsTestRunner.selectNode = function(node) {
-  return Common.Revealer.reveal(node);
-};
-
-/**
- * @param {string} idValue
- * @param {!Function} callback
- */
-ElementsTestRunner.nodeWithId = function(idValue, callback) {
-  ElementsTestRunner.findNode(node => node.getAttribute('id') === idValue, callback);
-};
-
-/**
- * @param {function(!Element): boolean} matchFunction
- * @param {!Function} callback
- */
-ElementsTestRunner.findNode = async function(matchFunction, callback) {
-  callback = TestRunner.safeWrap(callback);
-  let result = null;
-  let pendingRequests = 0;
-  async function processChildren(node) {
-    try {
-      if (result)
-        return;
-
-      if (node._childDocumentPromiseForTesting)
-        await node._childDocumentPromiseForTesting;
-
-      const pseudoElementsMap = node.pseudoElements();
-      const pseudoElements = pseudoElementsMap ? pseudoElementsMap.valuesArray() : [];
-      const children = (node.children() || []).concat(node.shadowRoots()).concat(pseudoElements);
-      if (node.templateContent())
-        children.push(node.templateContent());
-      else if (node.contentDocument())
-        children.push(node.contentDocument());
-      else if (node.importedDocument())
-        children.push(node.importedDocument());
-
-      for (let i = 0; i < children.length; ++i) {
-        const childNode = children[i];
-        if (matchFunction(childNode)) {
-          result = childNode;
-          callback(result);
-          return;
-        }
-        pendingRequests++;
-        childNode.getChildNodes(processChildren.bind(null, childNode));
-      }
-    } finally {
-      pendingRequests--;
-    }
-
-    if (!result && !pendingRequests)
-      callback(null);
-  }
-
-  const doc = TestRunner.domModel.existingDocument() || await TestRunner.domModel.requestDocument();
-  pendingRequests++;
-  doc.getChildNodes(processChildren.bind(null, doc));
-};
-
-/**
- * @param {!EventListeners.EventListenersView} eventListenersView
- * @param {function():void} callback
- * @param {boolean=} force
- */
-ElementsTestRunner.expandAndDumpEventListeners = function(eventListenersView, callback, force) {
-  function listenersArrived() {
-    const listenerTypes = eventListenersView._treeOutline.rootElement().children();
-    for (let i = 0; i < listenerTypes.length; ++i) {
-      listenerTypes[i].expand();
-      const listenerItems = listenerTypes[i].children();
-      for (let j = 0; j < listenerItems.length; ++j)
-        listenerItems[j].expand();
-    }
-    TestRunner.deprecatedRunAfterPendingDispatches(objectsExpanded);
-  }
-
-  function objectsExpanded() {
-    const listenerTypes = eventListenersView._treeOutline.rootElement().children();
-    for (let i = 0; i < listenerTypes.length; ++i) {
-      if (!listenerTypes[i].children().length)
-        continue;
-      const eventType = listenerTypes[i]._title;
-      TestRunner.addResult('');
-      TestRunner.addResult('======== ' + eventType + ' ========');
-      const listenerItems = listenerTypes[i].children();
-      for (let j = 0; j < listenerItems.length; ++j) {
-        TestRunner.addResult('== ' + listenerItems[j].eventListener().origin());
-        TestRunner.dumpObjectPropertyTreeElement(listenerItems[j]);
-      }
-    }
-    callback();
-  }
-
-  if (force) {
-    listenersArrived();
-  } else {
-    TestRunner.addSniffer(
-        EventListeners.EventListenersView.prototype, '_eventListenersArrivedForTest', listenersArrived);
-  }
-};
-
-ElementsTestRunner.inlineStyleSection = function() {
-  return UI.panels.elements._stylesWidget._sectionBlocks[0].sections[0];
-};
-
-ElementsTestRunner.computedStyleWidget = function() {
-  return UI.panels.elements._computedStyleWidget;
-};
-
-ElementsTestRunner.dumpComputedStyle = function(doNotAutoExpand) {
-  const computed = ElementsTestRunner.computedStyleWidget();
-  const treeOutline = computed._propertiesOutline;
-  const children = treeOutline.rootElement().children();
-
-  for (const treeElement of children) {
-    const property = treeElement[Elements.ComputedStyleWidget._propertySymbol];
-
-    if (property.name === 'width' || property.name === 'height')
-      continue;
-
-    let dumpText = '';
-    dumpText += treeElement.title.querySelector('.property-name').textContent;
-    dumpText += ' ';
-    dumpText += treeElement.title.querySelector('.property-value').textContent;
-    TestRunner.addResult(dumpText);
-
-    if (doNotAutoExpand && !treeElement.expanded)
-      continue;
-
-    for (const trace of treeElement.children()) {
-      const title = trace.title;
-      let dumpText = '';
-
-      if (trace.title.classList.contains('property-trace-inactive'))
-        dumpText += 'OVERLOADED ';
-
-      dumpText += title.querySelector('.property-trace-value').textContent;
-      dumpText += ' - ';
-      dumpText += title.querySelector('.property-trace-selector').textContent;
-      const link = title.querySelector('.trace-link');
-
-      if (link)
-        dumpText += ' ' + extractLinkText(link);
-
-      TestRunner.addResult('    ' + dumpText);
-    }
-  }
-};
-
-ElementsTestRunner.findComputedPropertyWithName = function(name) {
-  const computed = ElementsTestRunner.computedStyleWidget();
-  const treeOutline = computed._propertiesOutline;
-  const children = treeOutline.rootElement().children();
-
-  for (const treeElement of children) {
-    const property = treeElement[Elements.ComputedStyleWidget._propertySymbol];
-
-    if (property.name === name)
-      return treeElement;
-  }
-
-  return null;
-};
-
-ElementsTestRunner.firstMatchedStyleSection = function() {
-  return UI.panels.elements._stylesWidget._sectionBlocks[0].sections[1];
-};
-
-ElementsTestRunner.firstMediaTextElementInSection = function(section) {
-  return section.element.querySelector('.media-text');
-};
-
-ElementsTestRunner.querySelector = async function(selector, callback) {
-  const doc = await TestRunner.domModel.requestDocument();
-  const nodeId = await TestRunner.domModel.querySelector(doc.id, selector);
-  callback(TestRunner.domModel.nodeForId(nodeId));
-};
-
-ElementsTestRunner.shadowRootByHostId = function(idValue, callback) {
-  function shadowRootMatches(node) {
-    return node.isShadowRoot() && node.parentNode.getAttribute('id') === idValue;
-  }
-
-  ElementsTestRunner.findNode(shadowRootMatches, callback);
-};
-
-ElementsTestRunner.nodeWithClass = function(classValue, callback) {
-  function nodeClassMatches(node) {
-    const classAttr = node.getAttribute('class');
-    return classAttr && classAttr.indexOf(classValue) > -1;
-  }
-
-  ElementsTestRunner.findNode(nodeClassMatches, callback);
-};
-
-ElementsTestRunner.expandedNodeWithId = function(idValue) {
-  let result;
-  ElementsTestRunner.nodeWithId(idValue, node => result = node);
-  return result;
-};
-
-function waitForStylesRebuild(matchFunction, callback, requireRebuild) {
-  (function sniff(node, rebuild) {
-    if ((rebuild || !requireRebuild) && node && matchFunction(node)) {
-      callback();
-      return;
-    }
-
-    TestRunner.addSniffer(Elements.StylesSidebarPane.prototype, '_nodeStylesUpdatedForTest', sniff);
-  })(null);
-}
-
-ElementsTestRunner.waitForStyles = function(idValue, callback, requireRebuild) {
-  callback = TestRunner.safeWrap(callback);
-
-  function nodeWithId(node) {
-    return node.getAttribute('id') === idValue;
-  }
-
-  waitForStylesRebuild(nodeWithId, callback, requireRebuild);
-};
-
-ElementsTestRunner.waitForStyleCommitted = function(next) {
-  TestRunner.addSniffer(Elements.StylePropertyTreeElement.prototype, '_editingCommitted', (...args) => {
-    Promise.all(args).then(next);
-  });
-};
-
-ElementsTestRunner.waitForStylesForClass = function(classValue, callback, requireRebuild) {
-  callback = TestRunner.safeWrap(callback);
-
-  function nodeWithClass(node) {
-    const classAttr = node.getAttribute('class');
-    return classAttr && classAttr.indexOf(classValue) > -1;
-  }
-
-  waitForStylesRebuild(nodeWithClass, callback, requireRebuild);
-};
-
-ElementsTestRunner.waitForSelectorCommitted = function(callback) {
-  TestRunner.addSniffer(Elements.StylePropertiesSection.prototype, '_editingSelectorCommittedForTest', callback);
-};
-
-ElementsTestRunner.waitForMediaTextCommitted = function(callback) {
-  TestRunner.addSniffer(Elements.StylePropertiesSection.prototype, '_editingMediaTextCommittedForTest', callback);
-};
-
-ElementsTestRunner.waitForStyleApplied = function(callback) {
-  TestRunner.addSniffer(Elements.StylePropertyTreeElement.prototype, 'styleTextAppliedForTest', callback);
-};
-
-ElementsTestRunner.waitForStyleAppliedPromise = function() {
-  return new Promise(resolve => ElementsTestRunner.waitForStyleApplied(resolve));
-};
-
-ElementsTestRunner.selectNodeAndWaitForStyles = function(idValue, callback) {
-  callback = TestRunner.safeWrap(callback);
-  let targetNode;
-  ElementsTestRunner.waitForStyles(idValue, stylesUpdated, true);
-  ElementsTestRunner.selectNodeWithId(idValue, nodeSelected);
-
-  function nodeSelected(node) {
-    targetNode = node;
-  }
-
-  function stylesUpdated() {
-    callback(targetNode);
-  }
-};
-
-ElementsTestRunner.selectNodeAndWaitForStylesPromise = function(idValue) {
-  return new Promise(x => ElementsTestRunner.selectNodeAndWaitForStyles(idValue, x));
-};
-
-ElementsTestRunner.selectPseudoElementAndWaitForStyles = function(parentId, pseudoType, callback) {
-  callback = TestRunner.safeWrap(callback);
-  let targetNode;
-  waitForStylesRebuild(isPseudoElement, stylesUpdated, true);
-  ElementsTestRunner.findNode(isPseudoElement, nodeFound);
-
-  function nodeFound(node) {
-    targetNode = node;
-    Common.Revealer.reveal(node);
-  }
-
-  function stylesUpdated() {
-    callback(targetNode);
-  }
-
-  function isPseudoElement(node) {
-    return node.parentNode && node.parentNode.getAttribute('id') === parentId && node.pseudoType() === pseudoType;
-  }
-};
-
-ElementsTestRunner.selectNodeAndWaitForStylesWithComputed = function(idValue, callback) {
-  callback = TestRunner.safeWrap(callback);
-  ElementsTestRunner.selectNodeAndWaitForStyles(idValue, onSidebarRendered);
-
-  function onSidebarRendered(node) {
-    ElementsTestRunner.computedStyleWidget().doUpdate().then(callback.bind(null, node));
-  }
-};
-
-ElementsTestRunner.firstElementsTreeOutline = function() {
-  return UI.panels.elements._treeOutlines[0];
-};
-
-ElementsTestRunner.filterMatchedStyles = function(text) {
-  const regex = (text ? new RegExp(text, 'i') : null);
-  TestRunner.addResult('Filtering styles by: ' + text);
-  UI.panels.elements._stylesWidget._onFilterChanged(regex);
-};
-
-ElementsTestRunner.dumpRenderedMatchedStyles = function() {
-  const sectionBlocks = UI.panels.elements._stylesWidget._sectionBlocks;
-
-  for (const block of sectionBlocks) {
-    for (const section of block.sections) {
-      if (section.element.classList.contains('hidden'))
-        continue;
-
-      dumpRenderedSection(section);
-    }
-  }
-
-  function dumpRenderedSection(section) {
-    TestRunner.addResult(section._selectorElement.textContent + ' {');
-    const rootElement = section.propertiesTreeOutline.rootElement();
-
-    for (let i = 0; i < rootElement.childCount(); ++i)
-      dumpRenderedProperty(rootElement.childAt(i));
-
-    TestRunner.addResult('}');
-  }
-
-  function dumpRenderedProperty(property) {
-    let text = new Array(4).join(' ');
-    text += property.nameElement.textContent;
-    text += ':';
-
-    if (property.isExpandable())
-      text += (property.expanded ? 'v' : '>');
-    else
-      text += ' ';
-
-    text += property.valueElement.textContent;
-
-    if (property.listItemElement.classList.contains('filter-match'))
-      text = 'F' + text.substring(1);
-
-    TestRunner.addResult(text);
-
-    if (!property.expanded)
-      return;
-
-    const indent = new Array(8).join(' ');
-
-    for (let i = 0; i < property.childCount(); ++i) {
-      const childProperty = property.childAt(i);
-      let text = indent;
-      text += String.sprintf('%s: %s', childProperty.nameElement.textContent, childProperty.valueElement.textContent);
-
-      if (childProperty.listItemElement.classList.contains('filter-match'))
-        text = 'F' + text.substring(1);
-
-      TestRunner.addResult(text);
-    }
-  }
-};
-
-ElementsTestRunner.dumpSelectedElementStyles = function(
-    excludeComputed, excludeMatched, omitLonghands, includeSelectorGroupMarks) {
-  const sectionBlocks = UI.panels.elements._stylesWidget._sectionBlocks;
-
-  if (!excludeComputed)
-    ElementsTestRunner.dumpComputedStyle();
-
-  for (const block of sectionBlocks) {
-    for (const section of block.sections) {
-      if (section.style().parentRule && excludeMatched)
-        continue;
-
-      if (section.element.previousSibling && section.element.previousSibling.className === 'sidebar-separator') {
-        let nodeDescription = '';
-
-        if (section.element.previousSibling.firstElementChild)
-          nodeDescription = section.element.previousSibling.firstElementChild.shadowRoot.lastChild.textContent;
-
-        TestRunner.addResult('======== ' + section.element.previousSibling.textContent + nodeDescription + ' ========');
-      }
-
-      printStyleSection(section, omitLonghands, includeSelectorGroupMarks);
-    }
-  }
-};
-
-function printStyleSection(section, omitLonghands, includeSelectorGroupMarks) {
-  if (!section)
-    return;
-
-  TestRunner.addResult(
-      '[expanded] ' + ((section.propertiesTreeOutline.element.classList.contains('no-affect') ? '[no-affect] ' : '')));
-  const medias = section._titleElement.querySelectorAll('.media-list .media');
-
-  for (let i = 0; i < medias.length; ++i) {
-    const media = medias[i];
-    TestRunner.addResult(media.textContent);
-  }
-
-  const selector =
-      section._titleElement.querySelector('.selector') || section._titleElement.querySelector('.keyframe-key');
-  let selectorText = (includeSelectorGroupMarks ? buildMarkedSelectors(selector) : selector.textContent);
-  selectorText += selector.nextSibling.textContent;
-  const anchor = section._titleElement.querySelector('.styles-section-subtitle');
-
-  if (anchor) {
-    const anchorText = extractLinkText(anchor);
-    selectorText += String.sprintf(' (%s)', anchorText);
-  }
-
-  TestRunner.addResult(selectorText);
-  ElementsTestRunner.dumpStyleTreeOutline(section.propertiesTreeOutline, (omitLonghands ? 1 : 2));
-  if (!section._showAllButton.classList.contains('hidden'))
-    TestRunner.addResult(section._showAllButton.textContent);
-  TestRunner.addResult('');
-}
-
-function extractLinkText(element) {
-  const anchor = element.querySelector('.devtools-link');
-
-  if (!anchor)
-    return element.textContent;
-
-  const anchorText = anchor.textContent;
-  const info = Components.Linkifier._linkInfo(anchor);
-  const uiLocation = info && info.uiLocation;
-  const anchorTarget =
-      (uiLocation ?
-           uiLocation.uiSourceCode.name() + ':' + (uiLocation.lineNumber + 1) + ':' + (uiLocation.columnNumber + 1) :
-           '');
-  return anchorText + ' -> ' + anchorTarget;
-}
-
-function buildMarkedSelectors(element) {
-  let result = '';
-
-  for (let node = element.firstChild; node; node = node.nextSibling) {
-    if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('selector-matches'))
-      result += '[$' + node.textContent + '$]';
-    else
-      result += node.textContent;
-  }
-
-  return result;
-}
-
-ElementsTestRunner.toggleStyleProperty = function(propertyName, checked) {
-  const treeItem = ElementsTestRunner.getElementStylePropertyTreeItem(propertyName);
-
-  treeItem._toggleEnabled({
-    target: {checked: checked},
-
-    consume: function() {}
-  });
-};
-
-ElementsTestRunner.toggleMatchedStyleProperty = function(propertyName, checked) {
-  const treeItem = ElementsTestRunner.getMatchedStylePropertyTreeItem(propertyName);
-
-  treeItem._toggleEnabled({
-    target: {checked: checked},
-
-    consume: function() {}
-  });
-};
-
-ElementsTestRunner.eventListenersWidget = function() {
-  UI.viewManager.showView('elements.eventListeners');
-  return self.runtime.sharedInstance(Elements.EventListenersWidget);
-};
-
-ElementsTestRunner.showEventListenersWidget = function() {
-  return UI.viewManager.showView('elements.eventListeners');
-};
-
-ElementsTestRunner.expandAndDumpSelectedElementEventListeners = function(callback, force) {
-  ElementsTestRunner.expandAndDumpEventListeners(
-      ElementsTestRunner.eventListenersWidget()._eventListenersView, callback, force);
-};
-
-ElementsTestRunner.removeFirstEventListener = function() {
-  const treeOutline = ElementsTestRunner.eventListenersWidget()._eventListenersView._treeOutline;
-  const listenerTypes = treeOutline.rootElement().children();
-
-  for (let i = 0; i < listenerTypes.length; i++) {
-    const listeners = listenerTypes[i].children();
-
-    if (listeners.length && !listenerTypes[i].hidden) {
-      listeners[0].eventListener().remove();
-      listeners[0]._removeListenerBar();
-      break;
-    }
-  }
-};
-
-ElementsTestRunner.dumpObjectPropertySectionDeep = function(section) {
-  function domNodeToString(node) {
-    if (node)
-      return '\'' + node.textContent + '\'';
-    else
-      return 'null';
-  }
-
-  function dumpTreeElementRecursively(treeElement, prefix) {
-    if ('nameElement' in treeElement) {
-      TestRunner.addResult(
-          prefix + domNodeToString(treeElement.nameElement) + ' => ' + domNodeToString(treeElement.valueElement));
-    } else {
-      TestRunner.addResult(prefix + treeElement.title);
-    }
-
-    for (let i = 0; i < treeElement.childCount(); i++)
-      dumpTreeElementRecursively(treeElement.childAt(i), prefix + '    ');
-  }
-
-  const childNodes = section.propertiesTreeOutline.rootElement().children();
-
-  for (let i = 0; i < childNodes.length; i++)
-    dumpTreeElementRecursively(childNodes[i], '');
-
-};
-
-ElementsTestRunner.getElementStylePropertyTreeItem = function(propertyName) {
-  return ElementsTestRunner.getFirstPropertyTreeItemForSection(ElementsTestRunner.inlineStyleSection(), propertyName);
-};
-
-ElementsTestRunner.getMatchedStylePropertyTreeItem = function(propertyName) {
-  const sectionBlocks = UI.panels.elements._stylesWidget._sectionBlocks;
-
-  for (const block of sectionBlocks) {
-    for (const section of block.sections) {
-      const treeItem = ElementsTestRunner.getFirstPropertyTreeItemForSection(section, propertyName);
-
-      if (treeItem)
-        return treeItem;
-    }
-  }
-
-  return null;
-};
-
-ElementsTestRunner.getFirstPropertyTreeItemForSection = function(section, propertyName) {
-  const outline = section.propertiesTreeOutline.rootElement();
-
-  for (let i = 0; i < outline.childCount(); ++i) {
-    const treeItem = outline.childAt(i);
-
-    if (treeItem.name === propertyName)
-      return treeItem;
-  }
-
-  return null;
-};
-
-ElementsTestRunner.dumpStyleTreeOutline = function(treeItem, depth) {
-  const children = treeItem.rootElement().children();
-
-  for (let i = 0; i < children.length; ++i)
-    ElementsTestRunner.dumpStyleTreeItem(children[i], '', depth || 2);
-};
-
-ElementsTestRunner.dumpStyleTreeItem = function(treeItem, prefix, depth) {
-  if (treeItem.listItemElement.textContent.indexOf(' width:') !== -1 ||
-      treeItem.listItemElement.textContent.indexOf(' height:') !== -1)
-    return;
-
-  if (treeItem.listItemElement.classList.contains('inherited'))
-    return;
-
-  let typePrefix = '';
-
-  if (treeItem.listItemElement.classList.contains('overloaded') ||
-      treeItem.listItemElement.classList.contains('inactive') ||
-      treeItem.listItemElement.classList.contains('not-parsed-ok'))
-    typePrefix += '/-- overloaded --/ ';
-
-  if (treeItem.listItemElement.classList.contains('disabled'))
-    typePrefix += '/-- disabled --/ ';
-
-  const textContent = treeItem.listItemElement.textContent;
-  TestRunner.addResult(prefix + typePrefix + textContent);
-
-  if (--depth) {
-    treeItem.expand();
-    const children = treeItem.children();
-
-    for (let i = 0; children && i < children.length; ++i)
-      ElementsTestRunner.dumpStyleTreeItem(children[i], prefix + '    ', depth);
-  }
-};
-
-ElementsTestRunner.dumpElementsTree = function(rootNode, depth, resultsArray) {
-  function beautify(element) {
-    return element.innerText.replace(/\u200b/g, '').replace(/\n/g, '\\n').trim();
-  }
-
-  function dumpMap(name, map) {
-    const result = [];
-
-    for (const id of map.keys())
-      result.push(id + '=' + map.get(id));
-
-    if (!result.length)
-      return '';
-
-    return name + ':[' + result.join(',') + ']';
-  }
-
-  function markersDataDump(treeItem) {
-    if (treeItem._elementCloseTag)
-      return '';
-
-    let markers = '';
-    const node = treeItem._node;
-
-    if (node) {
-      markers += dumpMap('markers', node._markers);
-      const dump = (node._subtreeMarkerCount ? 'subtreeMarkerCount:' + node._subtreeMarkerCount : '');
-
-      if (dump) {
-        if (markers)
-          markers += ', ';
-
-        markers += dump;
-      }
-
-      if (markers)
-        markers = ' [' + markers + ']';
-    }
-
-    return markers;
-  }
-
-  function print(treeItem, prefix, depth) {
-    if (!treeItem.root) {
-      let expander;
-
-      if (treeItem.isExpandable()) {
-        if (treeItem.expanded)
-          expander = '- ';
-        else
-          expander = '+ ';
-      } else {
-        expander = '  ';
-      }
-
-      const markers = markersDataDump(treeItem);
-      let value = prefix + expander + beautify(treeItem.listItemElement) + markers;
-
-      if (treeItem.shadowHostToolbar) {
-        value = prefix + expander + 'shadow-root ';
-
-        for (let i = 0; i < treeItem.shadowHostToolbar.children.length; ++i) {
-          const button = treeItem.shadowHostToolbar.children[i];
-          const toggled = button.disabled;
-          const name = ((toggled ? '<' : '')) + button.textContent + ((toggled ? '>' : ''));
-          value += name + ' ';
-        }
-      }
-
-      if (resultsArray)
-        resultsArray.push(value);
-      else
-        TestRunner.addResult(value);
-    }
-
-    if (!treeItem.expanded)
-      return;
-
-    const children = treeItem.children();
-    const newPrefix = (treeItem.root ? '' : prefix + '    ');
-
-    for (let i = 0; depth && children && i < children.length; ++i) {
-      if (!children[i]._elementCloseTag)
-        print(children[i], newPrefix, depth - 1);
-      else
-        print(children[i], prefix, depth);
-    }
-  }
-
-  const treeOutline = ElementsTestRunner.firstElementsTreeOutline();
-  treeOutline.runPendingUpdates();
-  print((rootNode ? treeOutline.findTreeElement(rootNode) : treeOutline.rootElement()), '', depth || 10000);
-};
-
-ElementsTestRunner.dumpDOMUpdateHighlights = function(rootNode, callback, depth) {
-  let hasHighlights = false;
-  TestRunner.addSniffer(Elements.ElementsTreeOutline.prototype, '_updateModifiedNodes', didUpdate);
-
-  function didUpdate() {
-    const treeOutline = ElementsTestRunner.firstElementsTreeOutline();
-    print((rootNode ? treeOutline.findTreeElement(rootNode) : treeOutline.rootElement()), '', depth || 10000);
-
-    if (!hasHighlights)
-      TestRunner.addResult('<No highlights>');
-
-    if (callback)
-      callback();
-  }
-
-  function print(treeItem, prefix, depth) {
-    if (!treeItem.root) {
-      const elementXPath = Elements.DOMPath.xPath(treeItem.node(), true);
-      const highlightedElements = treeItem.listItemElement.querySelectorAll('.dom-update-highlight');
-
-      for (let i = 0; i < highlightedElements.length; ++i) {
-        const element = highlightedElements[i];
-        const classList = element.classList;
-        let xpath = elementXPath;
-
-        if (classList.contains('webkit-html-attribute-name')) {
-          xpath += '/@' + element.textContent + ' (empty)';
-        } else if (classList.contains('webkit-html-attribute-value')) {
-          name = element.parentElement.querySelector('.webkit-html-attribute-name').textContent;
-          xpath += '/@' + name + ' ' + element.textContent;
-        } else if (classList.contains('webkit-html-text-node')) {
-          xpath += '/text() "' + element.textContent + '"';
-        }
-
-        TestRunner.addResult(prefix + xpath);
-        hasHighlights = true;
-      }
-    }
-
-    if (!treeItem.expanded)
-      return;
-
-    const children = treeItem.children();
-    const newPrefix = (treeItem.root ? '' : prefix + '    ');
-
-    for (let i = 0; depth && children && i < children.length; ++i) {
-      if (!children[i]._elementCloseTag)
-        print(children[i], newPrefix, depth - 1);
-    }
-  }
-};
-
-ElementsTestRunner.expandElementsTree = function(callback) {
-  let expandedSomething = false;
-  callback = TestRunner.safeWrap(callback);
-
-  function expand(treeItem) {
-    const children = treeItem.children();
-
-    for (let i = 0; children && i < children.length; ++i) {
-      const child = children[i];
-
-      if (child.isExpandable() && !child.expanded) {
-        child.expand();
-        expandedSomething = true;
-      }
-
-      expand(child);
-    }
-  }
-
-  function onAllNodesAvailable() {
-    ElementsTestRunner.firstElementsTreeOutline().runPendingUpdates();
-    expand(ElementsTestRunner.firstElementsTreeOutline().rootElement());
-    setTimeout(callback.bind(null, expandedSomething));
-  }
-
-  ElementsTestRunner.findNode(function() {
-    return false;
-  }, onAllNodesAvailable);
-};
-
-ElementsTestRunner.expandAndDump = function() {
-  TestRunner.addResult('\nDump tree');
-  let callback;
-  const result = new Promise(f => callback = f);
-  ElementsTestRunner.expandElementsTree(() => {
-    ElementsTestRunner.dumpElementsTree();
-    callback();
-  });
-  return result;
-};
-
-ElementsTestRunner.dumpDOMAgentTree = function(node) {
-  if (!TestRunner.domModel._document)
-    return;
-
-  function dump(node, prefix) {
-    TestRunner.addResult(prefix + node.nodeName());
-    prefix = prefix + '    ';
-
-    if (node.templateContent())
-      dump(node.templateContent(), prefix);
-
-    if (node.contentDocument())
-      dump(node.contentDocument(), prefix);
-
-    if (node.importedDocument())
-      dump(node.importedDocument(), prefix);
-
-    const shadowRoots = node.shadowRoots();
-
-    for (let i = 0; i < shadowRoots.length; ++i)
-      dump(shadowRoots[i], prefix);
-
-    const children = node.children();
-
-    for (let i = 0; children && i < children.length; ++i)
-      dump(children[i], prefix);
-  }
-
-  dump(node, '');
-};
-
-ElementsTestRunner.rangeText = function(range) {
-  if (!range)
-    return '[undefined-undefined]';
-
-  return '[' + range.startLine + ':' + range.startColumn + '-' + range.endLine + ':' + range.endColumn + ']';
-};
-
-ElementsTestRunner.generateUndoTest = function(testBody) {
-  function result(next) {
-    const testNode = ElementsTestRunner.expandedNodeWithId(/function\s([^(]*)/.exec(testBody)[1]);
-    TestRunner.addResult('Initial:');
-    ElementsTestRunner.dumpElementsTree(testNode);
-    testBody(undo);
-
-    function undo() {
-      TestRunner.addResult('Post-action:');
-      ElementsTestRunner.dumpElementsTree(testNode);
-      ElementsTestRunner.expandElementsTree(expandedCallback);
-
-      function expandedCallback(expandedSomething) {
-        if (expandedSomething) {
-          TestRunner.addResult('== Expanded: ==');
-          ElementsTestRunner.dumpElementsTree(testNode);
-        }
-
-        SDK.domModelUndoStack.undo().then(redo);
-      }
-    }
-
-    function redo() {
-      TestRunner.addResult('Post-undo (initial):');
-      ElementsTestRunner.dumpElementsTree(testNode);
-      ElementsTestRunner.expandElementsTree(expandedCallback);
-
-      function expandedCallback(expandedSomething) {
-        if (expandedSomething) {
-          TestRunner.addResult('== Expanded: ==');
-          ElementsTestRunner.dumpElementsTree(testNode);
-        }
-
-        SDK.domModelUndoStack.redo().then(done);
-      }
-    }
-
-    function done() {
-      TestRunner.addResult('Post-redo (action):');
-      ElementsTestRunner.dumpElementsTree(testNode);
-      ElementsTestRunner.expandElementsTree(expandedCallback);
-
-      function expandedCallback(expandedSomething) {
-        if (expandedSomething) {
-          TestRunner.addResult('== Expanded: ==');
-          ElementsTestRunner.dumpElementsTree(testNode);
-        }
-
-        next();
-      }
-    }
-  }
-
-  result.toString = function() {
-    return testBody.toString();
-  };
-
-  return result;
-};
-
-const indent = '    ';
-
-ElementsTestRunner.dumpRulesArray = function(rules, currentIndent) {
-  if (!rules)
-    return;
-
-  currentIndent = currentIndent || '';
-
-  for (let i = 0; i < rules.length; ++i)
-    ElementsTestRunner.dumpRule(rules[i], currentIndent);
-};
-
-ElementsTestRunner.dumpRuleMatchesArray = function(matches, currentIndent) {
-  if (!matches)
-    return;
-
-  currentIndent = currentIndent || '';
-
-  for (let i = 0; i < matches.length; ++i)
-    ElementsTestRunner.dumpRule(matches[i].rule, currentIndent);
-};
-
-ElementsTestRunner.dumpRule = function(rule, currentIndent) {
-  function selectorRange() {
-    const selectors = rule.selectorList.selectors;
-
-    if (!selectors || !selectors[0].range)
-      return '';
-
-    const ranges = [];
-
-    for (let i = 0; i < selectors.length; ++i) {
-      const range = selectors[i].range;
-      ranges.push(range.startLine + ':' + range.startColumn + '-' + range.endLine + ':' + range.endColumn);
-    }
-
-    return ', ' + ranges.join('; ');
-  }
-
-  currentIndent = currentIndent || '';
-
-  if (!rule.type || rule.type === 'style') {
-    TestRunner.addResult(currentIndent + rule.selectorList.text + ': [' + rule.origin + selectorRange() + '] {');
-    ElementsTestRunner.dumpStyle(rule.style, currentIndent + indent);
-    TestRunner.addResult(currentIndent + '}');
-    return;
-  }
-
-  if (rule.type === 'media') {
-    TestRunner.addResult(currentIndent + '@media ' + rule.mediaText + ' {');
-    ElementsTestRunner.dumpRulesArray(rule.childRules, currentIndent + indent);
-    TestRunner.addResult(currentIndent + '}');
-    return;
-  }
-
-  if (rule.type === 'import') {
-    TestRunner.addResult(
-        currentIndent + '@import: header=' + ElementsTestRunner.rangeText(rule.headerRange) +
-        ', body=' + ElementsTestRunner.rangeText(rule.bodyRange));
-
-    return;
-  }
-
-  if (rule.type === 'page' || rule.type === 'font-face') {
-    if (rule.type === 'page') {
-      TestRunner.addResult(currentIndent + rule.selectorList.text + ' {');
-    } else {
-      TestRunner.addResult(
-          currentIndent + '@' + rule.type + ' ' + ((rule.selectorList.text ? rule.selectorList.text + ' ' : '')) + '{');
-    }
-
-    ElementsTestRunner.dumpStyle(rule.style, currentIndent + indent);
-    TestRunner.addResult(currentIndent + '}');
-    return;
-  }
-
-  if (rule.type === 'charset') {
-    TestRunner.addResult('@charset');
-    return;
-  }
-
-  TestRunner.addResult(
-      currentIndent + '[UNKNOWN RULE]: header=' + ElementsTestRunner.rangeText(rule.headerRange) +
-      ', body=' + ElementsTestRunner.rangeText(rule.bodyRange));
-};
-
-ElementsTestRunner.dumpStyle = function(style, currentIndent) {
-  currentIndent = currentIndent || '';
-
-  if (!style) {
-    TestRunner.addResult(currentIndent + '[NO STYLE]');
-    return;
-  }
-
-  for (let i = 0; i < style.cssProperties.length; ++i) {
-    const property = style.cssProperties[i];
-
-    if (!property.disabled) {
-      TestRunner.addResult(
-          currentIndent + '[\'' + property.name + '\':\'' + property.value + '\'' +
-          ((property.important ? ' is-important' : '')) + (('parsedOk' in property ? ' non-parsed' : '')) + '] @' +
-          ElementsTestRunner.rangeText(property.range) + ' ');
-    } else {
-      TestRunner.addResult(currentIndent + '[text=\'' + property.text + '\'] disabled');
-    }
-  }
-};
-
-ElementsTestRunner.dumpCSSStyleDeclaration = function(style, currentIndent) {
-  currentIndent = currentIndent || '';
-
-  if (!style) {
-    TestRunner.addResult(currentIndent + '[NO STYLE]');
-    return;
-  }
-
-  const properties = style.allProperties();
-
-  for (let i = 0; i < properties.length; ++i) {
-    const property = properties[i];
-
-    if (!property.disabled) {
-      TestRunner.addResult(
-          currentIndent + '[\'' + property.name + '\':\'' + property.value + '\'' +
-          ((property.important ? ' is-important' : '')) + ((!property['parsedOk'] ? ' non-parsed' : '')) + '] @' +
-          ElementsTestRunner.rangeText(property.range) + ' ');
-    } else {
-      TestRunner.addResult(currentIndent + '[text=\'' + property.text + '\'] disabled');
-    }
-  }
-};
-
-ElementsTestRunner.dumpBreadcrumb = function(message) {
-  if (message)
-    TestRunner.addResult(message + ':');
-
-  const result = [];
-  const crumbs = UI.panels.elements._breadcrumbs.crumbsElement;
-  let crumb = crumbs.lastChild;
-
-  while (crumb) {
-    result.unshift(crumb.textContent);
-    crumb = crumb.previousSibling;
-  }
-
-  TestRunner.addResult(result.join(' > '));
-};
-
-ElementsTestRunner.matchingSelectors = function(matchedStyles, rule) {
-  const selectors = [];
-  const matchingSelectors = matchedStyles.matchingSelectors(rule);
-
-  for (let i = 0; i < matchingSelectors.length; ++i)
-    selectors.push(rule.selectors[matchingSelectors[i]].text);
-
-  return '[' + selectors.join(', ') + ']';
-};
-
-ElementsTestRunner.addNewRuleInStyleSheet = function(styleSheetHeader, selector, callback) {
-  TestRunner.addSniffer(
-      Elements.StylesSidebarPane.prototype, '_addBlankSection', onBlankSection.bind(null, selector, callback));
-  UI.panels.elements._stylesWidget._createNewRuleInStyleSheet(styleSheetHeader);
-};
-
-ElementsTestRunner.addNewRule = function(selector, callback) {
-  UI.panels.elements._stylesWidget.contentElement.querySelector('.styles-pane-toolbar')
-      .shadowRoot.querySelector('.largeicon-add')
-      .click();
-  TestRunner.addSniffer(
-      Elements.StylesSidebarPane.prototype, '_addBlankSection', onBlankSection.bind(null, selector, callback));
-};
-
-function onBlankSection(selector, callback) {
-  const section = ElementsTestRunner.firstMatchedStyleSection();
-
-  if (typeof selector === 'string')
-    section._selectorElement.textContent = selector;
-
-  section._selectorElement.dispatchEvent(TestRunner.createKeyEvent('Enter'));
-  ElementsTestRunner.waitForSelectorCommitted(callback.bind(null, section));
-}
-
-ElementsTestRunner.dumpInspectorHighlightJSON = function(idValue, callback) {
-  ElementsTestRunner.nodeWithId(idValue, nodeResolved);
-
-  async function nodeResolved(node) {
-    const result = await TestRunner.OverlayAgent.getHighlightObjectForTest(node.id);
-    TestRunner.addResult(idValue + JSON.stringify(result, null, 2));
-    callback();
-  }
-};
-
-ElementsTestRunner.waitForAnimationAdded = function(callback) {
-  TestRunner.addSniffer(Animation.AnimationTimeline.prototype, '_addAnimationGroup', callback);
-};
-
-ElementsTestRunner.dumpAnimationTimeline = function(timeline) {
-  for (const ui of timeline._uiAnimations) {
-    TestRunner.addResult(ui.animation().type());
-    TestRunner.addResult(ui._nameElement.innerHTML);
-    TestRunner.addResult(ui._svg.innerHTML);
-  }
-};
diff --git a/front_end/elements_test_runner/SetOuterHTMLTestRunner.js b/front_end/elements_test_runner/SetOuterHTMLTestRunner.js
deleted file mode 100644
index 485eba4..0000000
--- a/front_end/elements_test_runner/SetOuterHTMLTestRunner.js
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-ElementsTestRunner.events = [];
-ElementsTestRunner.containerId;
-
-ElementsTestRunner.setUpTestSuite = function(next) {
-  ElementsTestRunner.expandElementsTree(step1);
-
-  function step1() {
-    ElementsTestRunner.selectNodeWithId('container', step2);
-  }
-
-  function step2(node) {
-    ElementsTestRunner.containerId = node.id;
-    TestRunner.DOMAgent.getOuterHTML(ElementsTestRunner.containerId).then(step3);
-  }
-
-  function step3(text) {
-    ElementsTestRunner.containerText = text;
-
-    for (const key in SDK.DOMModel.Events) {
-      const eventName = SDK.DOMModel.Events[key];
-
-      if (eventName === SDK.DOMModel.Events.MarkersChanged || eventName === SDK.DOMModel.Events.DOMMutated)
-        continue;
-
-      TestRunner.domModel.addEventListener(
-          eventName, ElementsTestRunner.recordEvent.bind(ElementsTestRunner, eventName));
-    }
-
-    next();
-  }
-};
-
-ElementsTestRunner.recordEvent = function(eventName, event) {
-  if (!event.data)
-    return;
-
-  const node = event.data.node || event.data;
-  const parent = event.data.parent;
-
-  for (let currentNode = parent || node; currentNode; currentNode = currentNode.parentNode) {
-    if (currentNode.getAttribute('id') === 'output')
-      return;
-  }
-
-  ElementsTestRunner.events.push('Event ' + eventName.toString() + ': ' + node.nodeName());
-};
-
-ElementsTestRunner.patchOuterHTML = function(pattern, replacement, next) {
-  TestRunner.addResult('Replacing \'' + pattern + '\' with \'' + replacement + '\'\n');
-  ElementsTestRunner.setOuterHTML(ElementsTestRunner.containerText.replace(pattern, replacement), next);
-};
-
-ElementsTestRunner.patchOuterHTMLUseUndo = function(pattern, replacement, next) {
-  TestRunner.addResult('Replacing \'' + pattern + '\' with \'' + replacement + '\'\n');
-  ElementsTestRunner.setOuterHTMLUseUndo(ElementsTestRunner.containerText.replace(pattern, replacement), next);
-};
-
-ElementsTestRunner.setOuterHTML = function(newText, next) {
-  ElementsTestRunner.innerSetOuterHTML(newText, false, bringBack);
-
-  function bringBack() {
-    TestRunner.addResult('\nBringing things back\n');
-    ElementsTestRunner.innerSetOuterHTML(ElementsTestRunner.containerText, true, next);
-  }
-};
-
-ElementsTestRunner.setOuterHTMLUseUndo = function(newText, next) {
-  ElementsTestRunner.innerSetOuterHTML(newText, false, bringBack);
-
-  async function bringBack() {
-    TestRunner.addResult('\nBringing things back\n');
-    await SDK.domModelUndoStack.undo();
-    ElementsTestRunner._dumpOuterHTML(true, next);
-  }
-};
-
-ElementsTestRunner.innerSetOuterHTML = async function(newText, last, next) {
-  await TestRunner.DOMAgent.setOuterHTML(ElementsTestRunner.containerId, newText);
-  TestRunner.domModel.markUndoableState();
-  ElementsTestRunner._dumpOuterHTML(last, next);
-};
-
-ElementsTestRunner._dumpOuterHTML = async function(last, next) {
-  const result = await TestRunner.RuntimeAgent.evaluate('document.getElementById("identity").wrapperIdentity');
-  TestRunner.addResult('Wrapper identity: ' + result.value);
-  ElementsTestRunner.events.sort();
-
-  for (let i = 0; i < ElementsTestRunner.events.length; ++i)
-    TestRunner.addResult(ElementsTestRunner.events[i]);
-
-  ElementsTestRunner.events = [];
-  const text = await TestRunner.DOMAgent.getOuterHTML(ElementsTestRunner.containerId);
-  TestRunner.addResult('==========8<==========');
-  TestRunner.addResult(text);
-  TestRunner.addResult('==========>8==========');
-
-  if (last)
-    TestRunner.addResult('\n\n\n');
-
-  next();
-};
diff --git a/front_end/elements_test_runner/StylesUpdateLinksTestRunner.js b/front_end/elements_test_runner/StylesUpdateLinksTestRunner.js
deleted file mode 100644
index 7e7e946..0000000
--- a/front_end/elements_test_runner/StylesUpdateLinksTestRunner.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-function flattenRuleRanges(rule) {
-  const ranges = [];
-  const medias = rule.media || [];
-
-  for (let i = 0; i < medias.length; ++i) {
-    const media = medias[i];
-
-    if (!media.range)
-      continue;
-
-    ranges.push({range: media.range, name: 'media #' + i});
-  }
-
-  for (let i = 0; i < rule.selectors.length; ++i) {
-    const selector = rule.selectors[i];
-
-    if (!selector.range)
-      continue;
-
-    ranges.push({range: selector.range, name: 'selector #' + i});
-  }
-
-  if (rule.style.range)
-    ranges.push({range: rule.style.range, name: 'style range'});
-
-
-  const properties = rule.style.allProperties();
-
-  for (let i = 0; i < properties.length; ++i) {
-    const property = properties[i];
-
-    if (!property.range)
-      continue;
-
-    ranges.push({range: property.range, name: 'property >>' + property.text + '<<'});
-  }
-
-  return ranges;
-}
-
-function compareRuleRanges(lazyRule, originalRule) {
-  if (lazyRule.selectorText !== originalRule.selectorText) {
-    TestRunner.addResult(
-        'Error: rule selectors are not equal: ' + lazyRule.selectorText + ' != ' + originalRule.selectorText);
-    return false;
-  }
-
-  const flattenLazy = flattenRuleRanges(lazyRule);
-  const flattenOriginal = flattenRuleRanges(originalRule);
-
-  if (flattenLazy.length !== flattenOriginal.length) {
-    TestRunner.addResult(
-        'Error: rule range amount is not equal: ' + flattenLazy.length + ' != ' + flattenOriginal.length);
-    return false;
-  }
-
-  for (let i = 0; i < flattenLazy.length; ++i) {
-    const lazyRange = flattenLazy[i];
-    const originalRange = flattenOriginal[i];
-
-    if (lazyRange.name !== originalRange.name) {
-      TestRunner.addResult('Error: rule names are not equal: ' + lazyRange.name + ' != ' + originalRange.name);
-      return false;
-    }
-
-    if (!lazyRange.range.equal(originalRange.range)) {
-      TestRunner.addResult(
-          'Error: ranges \'' + lazyRange.name + '\' are not equal: ' + lazyRange.range.toString() +
-          ' != ' + originalRange.range.toString());
-
-      return false;
-    }
-  }
-
-  TestRunner.addResult(flattenLazy.length + ' rule ranges are equal.');
-  return true;
-}
-
-ElementsTestRunner.validateRuleRanges = function(selector, rules, callback) {
-  ElementsTestRunner.selectNodeAndWaitForStyles('other', onOtherSelected);
-
-  function onOtherSelected() {
-    ElementsTestRunner.selectNodeAndWaitForStyles(selector, onContainerSelected);
-  }
-
-  function onContainerSelected() {
-    const fetchedRules = ElementsTestRunner.getMatchedRules();
-
-    if (fetchedRules.length !== rules.length) {
-      TestRunner.addResult(String.sprintf(
-          'Error: rules sizes are not equal! Expected: %d, actual: %d', fetchedRules.length, rules.length));
-      TestRunner.completeTest();
-      return;
-    }
-
-    for (let i = 0; i < fetchedRules.length; ++i) {
-      if (!compareRuleRanges(rules[i], fetchedRules[i])) {
-        TestRunner.completeTest();
-        return;
-      }
-    }
-
-    callback();
-  }
-};
-
-ElementsTestRunner.getMatchedRules = function() {
-  const rules = [];
-
-  for (const block of UI.panels.elements._stylesWidget._sectionBlocks) {
-    for (const section of block.sections) {
-      const rule = section.style().parentRule;
-
-      if (rule)
-        rules.push(rule);
-    }
-  }
-
-  return rules;
-};
diff --git a/front_end/elements_test_runner/module.json b/front_end/elements_test_runner/module.json
deleted file mode 100644
index 1126bff..0000000
--- a/front_end/elements_test_runner/module.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "elements",
-    "event_listeners",
-    "animation"
-  ],
-  "scripts": [
-    "ElementsTestRunner.js",
-    "EditDOMTestRunner.js",
-    "SetOuterHTMLTestRunner.js",
-    "ElementsPanelShadowSelectionOnRefreshTestRunner.js",
-    "StylesUpdateLinksTestRunner.js"
-  ],
-  "skip_compilation": [
-    "ElementsTestRunner.js",
-    "EditDOMTestRunner.js",
-    "SetOuterHTMLTestRunner.js",
-    "ElementsPanelShadowSelectionOnRefreshTestRunner.js",
-    "StylesUpdateLinksTestRunner.js"
-  ]
-}
diff --git a/front_end/emulated_devices/Nexus5X-landscape.svg b/front_end/emulated_devices/Nexus5X-landscape.svg
deleted file mode 100644
index 21f12a9..0000000
--- a/front_end/emulated_devices/Nexus5X-landscape.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" height="452.43" width="917.68" version="1.1" viewBox="0 0 917.67529 452.43137">
- <title id="title4">Nexus 5X</title>
- <g id="Nexus5X" fill="none" transform="matrix(0,-1,1,0,0.00325073,452.4346)">
-  <g id="g3004">
-   <rect id="Rectangle-path" opacity="0.7" rx="58.668" height="917.67" width="448.66" y="-0.003241" x="0.0032328" fill="#656565"/>
-   <path id="Shape" opacity="0.7" fill="#000" d="m3.7818,62.449c0-32.627,26.251-59.049,58.668-59.049h324.16c32.317,0,58.668,26.522,58.668,59.049v791.26c0,32.527-26.351,59.049-58.668,59.049h-324.16c-32.416,0-58.668-26.522-58.668-59.049v-791.36,0.10008z"/>
-   <rect id="rect12" rx="58.668" height="906.16" width="435.73" y="7.2028" x="6.8644" fill="#2b292b"/>
-   <path id="path14" fill="#656364" d="m448.66,238.4,3.7786,0,0,62.552-3.7786,0,0-62.552zm0,125.1,2.6848,0,0,137.32-2.8837,0,0.19888-137.32z"/>
-   <g id="Group" transform="matrix(0.99436709,0,0,1.0008385,75.575131,30.021912)">
-    <path id="path17" opacity="0.6" fill="#373737" d="m9.2,18c5,0,8.8-3.8,8.8-8.7,0-4.8-4-8.7-8.8-8.7s-8.7,4-8.7,8.7c0,5,4,8.8,8.7,8.8v-0.1z"/>
-    <circle id="Oval" d="M 14.2,9.3000002 C 14.2,12.061424 11.961424,14.3 9.1999998,14.3 c -2.7614237,0 -5,-2.238576 -5,-4.9999998 0,-2.7614238 2.2385763,-5 5,-5 2.7614242,0 5.0000002,2.2385762 5.0000002,5 z" cx="9.2" cy="9.3" r="5" fill="#160f26"/>
-   </g>
-   <path id="path20" opacity="0.5" fill="#171717" d="m19.221,88.066,412,0,0,732-412,0,0-732z"/>
-   <rect id="rect22" opacity="0.3" rx="6.9606" height="14.512" width="163.28" stroke="#393939" y="872.03" x="142.5" stroke-width="1.9952" fill="#0d0b0b"/>
-   <rect id="rect24" opacity="0.3" rx="6.9606" height="14.512" width="163.28" stroke="#393939" y="32.524" x="142.5" stroke-width="1.9952" fill="#0d0b0b"/>
-  </g>
- </g>
-</svg>
diff --git a/front_end/emulated_devices/Nexus5X-portrait.svg b/front_end/emulated_devices/Nexus5X-portrait.svg
deleted file mode 100644
index d01d91e..0000000
--- a/front_end/emulated_devices/Nexus5X-portrait.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" height="917.67" width="452.43" version="1.1" viewBox="0 0 452.43051 917.66962">
- <title id="title4">Nexus 5X</title>
- <g id="Nexus5X" fill="none" transform="translate(0,0.6696167)">
-  <g id="g3016">
-   <rect id="Rectangle-path" opacity="0.7" rx="58.667" height="917.67" width="448.65" y="-0.66962" x="-1.1102E-16" fill="#656565"/>
-   <path id="Shape" opacity="0.7" fill="#000" d="m3.7785,61.786c0-32.627,26.251-59.05,58.667-59.05h324.16c32.316,0,58.667,26.522,58.667,59.05v791.26c0,32.527-26.35,59.05-58.667,59.05h-324.16c-32.416,0-58.667-26.522-58.667-59.05v-791.36,0.10008z"/>
-   <rect id="rect12" rx="58.667" height="906.16" width="435.73" y="6.5397" x="6.861" fill="#2b292b"/>
-   <path id="path14" fill="#656364" d="m448.65,237.73,3.7785,0,0,62.552-3.7785,0,0-62.552zm0,125.1,2.6848,0,0,137.32-2.8836,0,0.19887-137.32z"/>
-   <g id="Group" transform="matrix(0.9943528,0,0,1.0008394,75.570813,29.35881)">
-    <path id="path17" opacity="0.6" fill="#373737" d="m9.2,18c5,0,8.8-3.8,8.8-8.7,0-4.8-4-8.7-8.8-8.7s-8.7,4-8.7,8.7c0,5,4,8.8,8.7,8.8v-0.1z"/>
-    <circle id="Oval" d="M 14.2,9.3000002 C 14.2,12.061424 11.961424,14.3 9.1999998,14.3 c -2.7614237,0 -5,-2.238576 -5,-4.9999998 0,-2.7614238 2.2385763,-5 5,-5 2.7614242,0 5.0000002,2.2385762 5.0000002,5 z" cx="9.2" cy="9.3" r="5" fill="#160f26"/>
-   </g>
-   <path id="path20" opacity="0.5" fill="#171717" d="m20.218,87.4,412,0,0,732-412,0,0-732z"/>
-   <rect id="rect22" opacity="0.3" rx="6.9605" height="14.512" width="163.27" stroke="#393939" y="871.36" x="142.49" stroke-width="1.9952" fill="#0d0b0b"/>
-   <rect id="rect24" opacity="0.3" rx="6.9605" height="14.512" width="163.27" stroke="#393939" y="31.861" x="142.49" stroke-width="1.9952" fill="#0d0b0b"/>
-  </g>
- </g>
-</svg>
diff --git a/front_end/emulated_devices/Nexus6P-landscape.svg b/front_end/emulated_devices/Nexus6P-landscape.svg
deleted file mode 100644
index ad485f7..0000000
--- a/front_end/emulated_devices/Nexus6P-landscape.svg
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" height="445.18" width="914.43" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 914.42999 445.18448">
- <title id="title4">Nexus 6P</title>
- <defs id="defs6">
-  <linearGradient id="linearGradient-2" y1="0.38635" x2="0.966" x1="0.042" y2="0.61863">
-   <stop id="stop14" stop-color="#3A3A3A" offset="0"/>
-   <stop id="stop16" stop-color="#181818" offset="1"/>
-  </linearGradient>
-  <linearGradient id="linearGradient3047" y2="418.38" xlink:href="#linearGradient-2" gradientUnits="userSpaceOnUse" x2="653.3" gradientTransform="scale(0.69792557,1.4328175)" y1="261.28" x1="28.404"/>
- </defs>
- <g id="Page-1" fill="none" transform="matrix(0.99391592,0,0,0.9822732,-3.2567387,-26.310581)">
-  <g id="g3051">
-   <g id="b-link" fill="url(#linearGradient3047)" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)">
-    <rect id="b" rx="60" height="969" width="472" y="0" x="0" fill="url(#linearGradient3047)"/>
-   </g>
-   <g id="g22" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)">
-    <rect id="rect24" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="g26" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)">
-    <rect id="rect28" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="g30" stroke-width="7" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)" stroke="#1e1e1e">
-    <rect id="rect32" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="g34" stroke-width="5" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)" stroke="#616161">
-    <rect id="rect36" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="g38" stroke-width="3" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)" stroke="#1e1e1e">
-    <rect id="rect40" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="g42" stroke-width="2" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)" stroke="#b4b4b4">
-    <rect id="rect44" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="g46" transform="matrix(0,-0.94516303,0.94267555,0,6.5696201,476.68946)" stroke="#8a8a8a">
-    <rect id="rect48" rx="60" height="969" width="472" y="0" x="0"/>
-   </g>
-   <g id="Group" fill="#444445" transform="matrix(0,-0.94516303,0.94267555,0,307.28312,30.572506)">
-    <path id="Shape" d="m0,0,2,0c1,0,2,1,2,2v56c0,1-1,2-2,2h-2v-60z"/>
-    <path id="path52" d="m0,97,2,0c1,0,2,1,2,2v116c0,1-1,2-2,2h-2v-120z"/>
-   </g>
-   <path id="path54" fill="#171717" d="m98.668,463.1,0-419.44,736.32,0,0,419.44-736.32,0z"/>
-   <rect id="Rectangle-path" opacity="0.4" rx="7.5613" transform="matrix(0,-1,1,0,0,0)" height="13.197" width="159.73" stroke="#141414" y="44.277" x="-334.92" stroke-width="2.8318" fill="#1e1e1e"/>
-   <rect id="rect57" rx="7.5613" transform="matrix(0,-1,1,0,0,0)" height="13.197" width="159.73" stroke="#141414" y="874.77" x="-334.92" stroke-width="2.8318" fill="#101010"/>
-   <g id="g59" transform="matrix(0,-0.94516303,0.94267555,0,41.448616,396.3506)">
-    <path id="path61" opacity="0.6" d="m9.2,18c5,0,8.8-3.8,8.8-8.7,0-4.8-4-8.7-8.8-8.7s-8.7,4-8.7,8.7c0,5,4,8.8,8.7,8.8v-0.1z" stroke="#2f2f2f" fill="#323232"/>
-    <circle id="Oval" d="M 14.2,9.3000002 C 14.2,12.061424 11.961424,14.3 9.1999998,14.3 c -2.7614237,0 -5,-2.238576 -5,-4.9999998 0,-2.7614238 2.2385763,-5 5,-5 2.7614242,0 5.0000002,2.2385762 5.0000002,5 z" cx="9.2" cy="9.3" r="5" fill="#160f26"/>
-   </g>
-  </g>
- </g>
-</svg>
diff --git a/front_end/emulated_devices/Nexus6P-portrait.svg b/front_end/emulated_devices/Nexus6P-portrait.svg
deleted file mode 100644
index ffd8cff..0000000
--- a/front_end/emulated_devices/Nexus6P-portrait.svg
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" height="914.47" width="445.17" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 445.17206 914.46722">
- <title id="title4">Nexus 6P</title>
- <defs id="defs6">
-  <linearGradient id="linearGradient-2" y1="0.38635" x2="0.966" x1="0.042" y2="0.61863">
-   <stop id="stop14" stop-color="#3A3A3A" offset="0"/>
-   <stop id="stop16" stop-color="#181818" offset="1"/>
-  </linearGradient>
-  <linearGradient id="linearGradient3050" y2="418.38" xlink:href="#linearGradient-2" gradientUnits="userSpaceOnUse" x2="653.3" gradientTransform="scale(0.69792557,1.4328175)" y1="261.28" x1="28.404"/>
- </defs>
- <g id="Page-1" fill="none" transform="translate(-0.01713988,-62.547364)">
-  <g id="Nexus6P" transform="translate(4,4)">
-   <g id="g3088">
-    <g id="g3052">
-     <g id="b-link" fill="url(#linearGradient3050)" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="b" rx="60" height="969" width="472" y="0" x="0" fill="url(#linearGradient3050)"/>
-     </g>
-     <g id="g22" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect24" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="g26" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect28" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="g30" stroke-width="7" stroke="#1e1e1e" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect32" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="g34" stroke-width="5" stroke="#616161" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect36" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="g38" stroke-width="3" stroke="#1e1e1e" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect40" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="g42" stroke-width="2" stroke="#b4b4b4" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect44" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="g46" stroke="#8a8a8a" transform="matrix(0.92840894,0,0,0.93695416,-0.71850895,61.841656)">
-      <rect id="rect48" rx="60" height="969" width="472" y="0" x="0"/>
-     </g>
-     <g id="Group" fill="#444445" transform="matrix(0.92840894,0,0,0.93695416,437.4905,360.73005)">
-      <path id="Shape" d="m0,0,2,0c1,0,2,1,2,2v56c0,1-1,2-2,2h-2v-60z"/>
-      <path id="path52" d="m0,97,2,0c1,0,2,1,2,2v116c0,1-1,2-2,2h-2v-120z"/>
-     </g>
-     <path id="path54" fill="#171717" d="m12.632,152.66,412,0,0,732-412,0,0-732z"/>
-     <rect id="Rectangle-path" opacity="0.4" rx="7.4273" height="13.117" width="156.9" stroke="#141414" y="99.32" x="138.54" stroke-width="2.798" fill="#1e1e1e"/>
-     <rect id="rect57" rx="7.4273" height="13.117" width="156.9" stroke="#141414" y="924.78" x="138.54" stroke-width="2.798" fill="#101010"/>
-     <g id="g59" transform="matrix(0.92840894,0,0,0.93695416,78.196251,96.50896)">
-      <path id="path61" opacity="0.6" d="m9.2,18c5,0,8.8-3.8,8.8-8.7,0-4.8-4-8.7-8.8-8.7s-8.7,4-8.7,8.7c0,5,4,8.8,8.7,8.8v-0.1z" stroke="#2f2f2f" fill="#323232"/>
-      <circle id="Oval" d="M 14.2,9.3000002 C 14.2,12.061424 11.961424,14.3 9.1999998,14.3 c -2.7614237,0 -5,-2.238576 -5,-4.9999998 0,-2.7614238 2.2385763,-5 5,-5 2.7614242,0 5.0000002,2.2385762 5.0000002,5 z" cx="9.2" cy="9.3" r="5" fill="#160f26"/>
-     </g>
-    </g>
-   </g>
-  </g>
- </g>
-</svg>
diff --git a/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png b/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png
deleted file mode 100644
index acdff22..0000000
--- a/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png b/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png
deleted file mode 100644
index a99d861..0000000
--- a/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png b/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png
deleted file mode 100644
index 97a8abc..0000000
--- a/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png b/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png
deleted file mode 100644
index dc153bd..0000000
--- a/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png b/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png
deleted file mode 100644
index b247779..0000000
--- a/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png b/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png
deleted file mode 100644
index a25f646..0000000
--- a/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png b/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png
deleted file mode 100644
index ecc5008..0000000
--- a/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png b/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png
deleted file mode 100644
index 70370bc..0000000
--- a/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png b/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png
deleted file mode 100644
index a9ba4aa..0000000
--- a/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png b/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png
deleted file mode 100644
index 7ed56fe..0000000
--- a/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png b/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png
deleted file mode 100644
index add3708..0000000
--- a/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png b/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png
deleted file mode 100644
index fc3c3d2..0000000
--- a/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png b/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png
deleted file mode 100644
index bf4c0d2..0000000
--- a/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png b/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png
deleted file mode 100644
index ba0ed57..0000000
--- a/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png b/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png
deleted file mode 100644
index cd6e627..0000000
--- a/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png b/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png
deleted file mode 100644
index d447c70..0000000
--- a/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png b/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png
deleted file mode 100644
index 187f1e9..0000000
--- a/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png b/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png
deleted file mode 100644
index d93dfa5..0000000
--- a/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png b/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png
deleted file mode 100644
index bbc14d2..0000000
--- a/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png b/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png
deleted file mode 100644
index 70e0a96..0000000
--- a/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png b/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png
deleted file mode 100644
index 86789f4..0000000
--- a/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png b/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png
deleted file mode 100644
index 039282d..0000000
--- a/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png b/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png
deleted file mode 100644
index 845b887..0000000
--- a/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png b/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png
deleted file mode 100644
index 2c21972..0000000
--- a/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png
+++ /dev/null
Binary files differ
diff --git a/front_end/emulated_devices/iPad-landscape.svg b/front_end/emulated_devices/iPad-landscape.svg
deleted file mode 100644
index 1158fe4..0000000
--- a/front_end/emulated_devices/iPad-landscape.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="1252px" height="876px" viewBox="0 0 1252 876" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPad</title>
-    <defs>
-        <linearGradient x1="53.4074186%" y1="42.8551228%" x2="44.5013504%" y2="61.5298471%" id="linearGradient-1">
-            <stop stop-color="#3A3E3A" offset="8.86%"></stop>
-            <stop stop-color="#2E332E" offset="34.31%"></stop>
-            <stop stop-color="#C0C1C2" offset="36%"></stop>
-            <stop stop-color="#3C3F3E" offset="51.34%"></stop>
-            <stop stop-color="#4B4E4B" offset="64.16%"></stop>
-        </linearGradient>
-        <radialGradient cx="49.7525149%" cy="45.0260324%" fx="49.7525149%" fy="45.0260324%" r="43.1038484%" id="radialGradient-2">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="82.84%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="97.66%"></stop>
-        </radialGradient>
-        <linearGradient x1="1.85026396%" y1="102.188703%" x2="61.1786193%" y2="37.8836394%" id="linearGradient-3">
-            <stop stop-color="#595C64" offset="0%"></stop>
-            <stop stop-color="#3C414A" offset="64.45%"></stop>
-        </linearGradient>
-        <linearGradient x1="86.3892857%" y1="91.8876786%" x2="14.0435714%" y2="8.62178571%" id="linearGradient-4">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="50.4141972%" cy="57.1536365%" fx="50.4141972%" fy="57.1536365%" r="32.0253807%" id="radialGradient-5">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.7237505%" cy="96.413995%" fx="47.7237505%" fy="96.413995%" r="61.371517%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.7767573%" cy="24.0727573%" fx="50.7767573%" fy="24.0727573%" r="36.758427%" id="radialGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="49.241206%" y1="6.83%" x2="49.241206%" y2="97.95%" id="linearGradient-8">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="ipad-landscape">
-            <g id="Group">
-                <g>
-                    <path d="M1251.72,61.92 L1251.72,814.08 C1251.72,847.76 1224.42,875.06 1190.74,875.06 L61.26,875.06 C27.58,875.06 0.28,847.76 0.28,814.08 L0.28,61.92 C0.28,28.24 27.58,0.94 61.26,0.94 L1190.74,0.94 C1224.42,0.94 1251.72,28.24 1251.72,61.92 L1251.72,61.92 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                    <path d="M1251.72,61.92 L1251.72,814.08 C1251.72,847.76 1224.42,875.06 1190.74,875.06 L61.26,875.06 C27.58,875.06 0.28,847.76 0.28,814.08 L0.28,61.92 C0.28,28.24 27.58,0.94 61.26,0.94 L1190.74,0.94 C1224.42,0.94 1251.72,28.24 1251.72,61.92 L1251.72,61.92 Z" id="Shape" fill="url(#radialGradient-2)"></path>
-                    <path d="M1245.39,814.08 C1245.39,844.22 1220.87,868.73 1190.74,868.73 L61.26,868.73 C31.12,868.73 6.61,844.21 6.61,814.08 L6.61,61.92 C6.61,31.78 31.13,7.27 61.26,7.27 L1190.74,7.27 C1220.88,7.27 1245.39,31.79 1245.39,61.92 L1245.39,814.08 L1245.39,814.08 Z" id="Shape" fill="url(#linearGradient-3)"></path>
-                    <path d="M1242.74,814.08 C1242.74,842.75 1219.41,866.08 1190.74,866.08 L61.26,866.08 C32.59,866.08 9.26,842.75 9.26,814.08 L9.26,61.92 C9.26,33.25 32.59,9.92 61.26,9.92 L1190.74,9.92 C1219.41,9.92 1242.74,33.25 1242.74,61.92 L1242.74,814.08 L1242.74,814.08 Z" id="Shape" fill="#232323"></path>
-                    <path d="M1194.12,409.1 C1178.66,409.1 1166.12,421.64 1166.12,437.1 C1166.12,452.56 1178.66,465.1 1194.12,465.1 C1209.58,465.1 1222.12,452.56 1222.12,437.1 C1222.12,421.64 1209.58,409.1 1194.12,409.1 L1194.12,409.1 Z M1194.12,462.54 C1180.07,462.54 1168.68,451.15 1168.68,437.1 C1168.68,423.05 1180.07,411.66 1194.12,411.66 C1208.17,411.66 1219.56,423.05 1219.56,437.1 C1219.56,451.15 1208.17,462.54 1194.12,462.54 L1194.12,462.54 Z" id="Shape" fill="url(#linearGradient-4)"></path>
-                    <g transform="translate(61.000000, 429.000000)">
-                        <circle id="Oval" fill="#5D5D5F" cx="8.21" cy="8.29" r="7.88"></circle>
-                        <circle id="Oval" fill="url(#radialGradient-5)" cx="8.21" cy="8.29" r="7.88"></circle>
-                        <circle id="Oval" fill="#1B1A1F" cx="8.21" cy="8.29" r="4.42"></circle>
-                        <circle id="Oval" fill="#36284C" cx="8.21" cy="8.29" r="3.23"></circle>
-                        <circle id="Oval" fill="url(#radialGradient-6)" cx="8.21" cy="8.29" r="3.23"></circle>
-                        <g transform="translate(6.000000, 6.000000)" id="Oval">
-                            <circle fill="#141414" opacity="0.5" cx="2.21" cy="2.29" r="1.78"></circle>
-                            <circle fill="url(#radialGradient-7)" cx="2.21" cy="2.29" r="1.78"></circle>
-                        </g>
-                        <path d="M8.21,6.96 C7.82,6.96 7.47,7.14 7.23,7.41 L7.65,7.83 C7.79,7.66 7.99,7.55 8.22,7.55 C8.46,7.55 8.66,7.67 8.8,7.84 L9.22,7.42 C8.96,7.15 8.61,6.96 8.21,6.96 L8.21,6.96 Z" id="Shape" fill="url(#linearGradient-8)"></path>
-                    </g>
-                </g>
-                <rect id="Rectangle-path" fill="#000000" x="111.65" y="55.54" width="1024" height="768"></rect>
-            </g>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPad-portrait.svg b/front_end/emulated_devices/iPad-portrait.svg
deleted file mode 100644
index 8738db5..0000000
--- a/front_end/emulated_devices/iPad-portrait.svg
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="875px" height="1253px" viewBox="0 0 875 1253" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPad</title>
-    <defs>
-        <linearGradient x1="56.85224%" y1="46.7616506%" x2="38.1241363%" y2="55.612846%" id="linearGradient-1">
-            <stop stop-color="#3A3E3A" offset="8.86%"></stop>
-            <stop stop-color="#2E332E" offset="34.31%"></stop>
-            <stop stop-color="#C0C1C2" offset="36%"></stop>
-            <stop stop-color="#3C3F3E" offset="51.34%"></stop>
-            <stop stop-color="#4B4E4B" offset="64.16%"></stop>
-        </linearGradient>
-        <radialGradient cx="50.1721031%" cy="47.1220327%" fx="50.1721031%" fy="47.1220327%" r="68.0316204%" id="radialGradient-2">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="82.84%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="97.66%"></stop>
-        </radialGradient>
-        <linearGradient x1="-2.18858682%" y1="1.85033783%" x2="62.1164651%" y2="61.1782223%" id="linearGradient-3">
-            <stop stop-color="#595C64" offset="0%"></stop>
-            <stop stop-color="#3C414A" offset="64.45%"></stop>
-        </linearGradient>
-        <linearGradient x1="86.395%" y1="91.8842857%" x2="14.0494643%" y2="8.61857143%" id="linearGradient-4">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="-22.8991955%" y1="27.2682893%" x2="39.640603%" y2="46.0089814%" id="linearGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="50.4203886%" cy="57.0974914%" fx="50.4203886%" fy="57.0974914%" r="32.0253807%" id="radialGradient-6">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.731605%" cy="96.2770217%" fx="47.731605%" fy="96.2770217%" r="61.371517%" id="radialGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.7910101%" cy="23.832973%" fx="50.7910101%" fy="23.832973%" r="36.758427%" id="radialGradient-8">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="49.281407%" y1="6.96%" x2="49.281407%" y2="98.07%" id="linearGradient-9">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="ipad-portrait">
-            <g id="Group">
-                <path d="M813.32,1252.09 L61.16,1252.09 C27.48,1252.09 0.18,1224.79 0.18,1191.11 L0.18,61.63 C0.18,27.95 27.48,0.65 61.16,0.65 L813.32,0.65 C847,0.65 874.3,27.95 874.3,61.63 L874.3,1191.11 C874.3,1224.79 847,1252.09 813.32,1252.09 L813.32,1252.09 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                <path d="M61.16,1252.09 C27.48,1252.09 0.18,1224.79 0.18,1191.11 L0.18,61.63 C0.18,27.95 27.48,0.65 61.16,0.65 L813.32,0.65 C847,0.65 874.3,27.95 874.3,61.63 L874.3,1191.11 C874.3,1224.79 847,1252.09 813.32,1252.09 L61.16,1252.09 Z" id="Shape" fill="url(#radialGradient-2)"></path>
-                <path d="M61.16,1245.77 C31.02,1245.77 6.51,1221.25 6.51,1191.12 L6.51,61.63 C6.51,31.49 31.03,6.98 61.16,6.98 L813.32,6.98 C843.46,6.98 867.97,31.5 867.97,61.63 L867.97,1191.11 C867.97,1221.25 843.45,1245.76 813.32,1245.76 L61.16,1245.76 L61.16,1245.77 Z" id="Shape" fill="url(#linearGradient-3)"></path>
-                <path d="M61.16,1243.11 C32.49,1243.11 9.16,1219.78 9.16,1191.11 L9.16,61.63 C9.16,32.96 32.49,9.63 61.16,9.63 L813.32,9.63 C841.99,9.63 865.32,32.96 865.32,61.63 L865.32,1191.11 C865.32,1219.78 841.99,1243.11 813.32,1243.11 L61.16,1243.11 L61.16,1243.11 Z" id="Shape" fill="#232323"></path>
-                <path d="M438.14,1166.49 C422.68,1166.49 410.14,1179.03 410.14,1194.49 C410.14,1209.95 422.68,1222.49 438.14,1222.49 C453.6,1222.49 466.14,1209.95 466.14,1194.49 C466.14,1179.03 453.6,1166.49 438.14,1166.49 L438.14,1166.49 Z M438.14,1219.93 C424.09,1219.93 412.7,1208.54 412.7,1194.49 C412.7,1180.44 424.09,1169.05 438.14,1169.05 C452.19,1169.05 463.58,1180.44 463.58,1194.49 C463.58,1208.54 452.19,1219.93 438.14,1219.93 L438.14,1219.93 Z" id="Shape" fill="url(#linearGradient-4)"></path>
-                <path d="M59.24,8.19 C31.62,8.19 9.15,30.66 9.15,58.28 L9.15,1190.65 C9.15,1218.27 31.62,1240.74 59.24,1240.74 L105.77,1240.74 L620.73,8.19 L59.24,8.19 L59.24,8.19 Z" id="Shape" fill="url(#linearGradient-5)"></path>
-                <g transform="translate(430.000000, 61.000000)">
-                    <circle id="Oval" fill="#5D5D5F" cx="7.95" cy="8.58" r="7.88"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-6)" cx="7.95" cy="8.58" r="7.88"></circle>
-                    <circle id="Oval" fill="#1B1A1F" cx="7.95" cy="8.58" r="4.42"></circle>
-                    <circle id="Oval" fill="#36284C" cx="7.95" cy="8.58" r="3.23"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-7)" cx="7.95" cy="8.58" r="3.23"></circle>
-                    <g transform="translate(6.000000, 6.000000)" id="Oval">
-                        <circle fill="#141414" opacity="0.5" cx="1.95" cy="2.58" r="1.78"></circle>
-                        <circle fill="url(#radialGradient-8)" cx="1.95" cy="2.58" r="1.78"></circle>
-                    </g>
-                    <path d="M7.95,7.24 C7.56,7.24 7.21,7.42 6.97,7.69 L7.39,8.11 C7.53,7.94 7.73,7.83 7.96,7.83 C8.2,7.83 8.4,7.95 8.54,8.12 L8.96,7.7 C8.7,7.43 8.35,7.24 7.95,7.24 L7.95,7.24 Z" id="Shape" fill="url(#linearGradient-9)"></path>
-                </g>
-            </g>
-            <rect id="Rectangle-path" fill="#000000" x="52" y="114" width="768" height="1024"></rect>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPhone5-landscape.svg b/front_end/emulated_devices/iPhone5-landscape.svg
deleted file mode 100644
index 614e37b..0000000
--- a/front_end/emulated_devices/iPhone5-landscape.svg
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="796px" height="374px" viewBox="0 0 796 374" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPhone 5</title>
-    <defs>
-        <linearGradient x1="48.0821303%" y1="41.0365444%" x2="53.4014207%" y2="65.8954597%" id="linearGradient-1">
-            <stop stop-color="#3A3E3A" offset="8.86%"></stop>
-            <stop stop-color="#2E332E" offset="34.31%"></stop>
-            <stop stop-color="#C0C1C2" offset="36%"></stop>
-            <stop stop-color="#3C3F3E" offset="51.34%"></stop>
-            <stop stop-color="#4B4E4B" offset="64.16%"></stop>
-        </linearGradient>
-        <linearGradient x1="8.33127764%" y1="117.999363%" x2="59.674224%" y2="34.2134349%" id="linearGradient-2">
-            <stop stop-color="#787A81" offset="0%"></stop>
-            <stop stop-color="#50555D" offset="63.53%"></stop>
-        </linearGradient>
-        <linearGradient x1="86.386465%" y1="91.8797771%" x2="14.0433121%" y2="8.61671975%" id="linearGradient-3">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="50.420845%" cy="57.0979235%" fx="50.420845%" fy="57.0979235%" r="32.026875%" id="radialGradient-4">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.7374598%" cy="96.2677037%" fx="47.7374598%" fy="96.2677037%" r="61.3597561%" id="radialGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.7992656%" cy="23.7186867%" fx="50.7992656%" fy="23.7186867%" r="36.9055556%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="50.3015075%" y1="7%" x2="50.3015075%" y2="99.53%" id="linearGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-8" d="M8.84,4.95 L8.84,59.57 C8.84,61.94 6.92,63.86 4.55,63.86 L4.55,63.86 C2.18,63.86 0.26,61.94 0.26,59.57 L0.26,4.95 C0.26,2.58 2.18,0.66 4.55,0.66 L4.55,0.66 C6.92,0.67 8.84,2.59 8.84,4.95 L8.84,4.95 Z"></path>
-        <linearGradient x1="100.590671%" y1="50.3945599%" x2="0.664279091%" y2="50.3945599%" id="linearGradient-10">
-            <stop stop-color="#2E2E31" offset="0%"></stop>
-            <stop stop-color="#616161" offset="24.48%"></stop>
-            <stop stop-color="#858585" offset="81.37%"></stop>
-            <stop stop-color="#2E2E31" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-11" d="M8.84,4.95 L8.84,59.57 C8.84,61.94 6.92,63.86 4.55,63.86 L4.55,63.86 C2.18,63.86 0.26,61.94 0.26,59.57 L0.26,4.95 C0.26,2.58 2.18,0.66 4.55,0.66 L4.55,0.66 C6.92,0.67 8.84,2.59 8.84,4.95 L8.84,4.95 Z"></path>
-        <path id="path-13" d="M8.84,4.95 L8.84,59.57 C8.84,61.94 6.92,63.86 4.55,63.86 L4.55,63.86 C2.18,63.86 0.26,61.94 0.26,59.57 L0.26,4.95 C0.26,2.58 2.18,0.66 4.55,0.66 L4.55,0.66 C6.92,0.67 8.84,2.59 8.84,4.95 L8.84,4.95 Z"></path>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="iphone5-landscape">
-            <g id="Group">
-                <path d="M141.69,367.74 L141.69,371.47 C141.69,372.49 140.86,373.31 139.85,373.31 L109.29,373.31 C108.27,373.31 107.45,372.48 107.45,371.47 L107.45,367.74 L141.69,367.74 L141.69,367.74 Z" id="Shape" fill="#808086"></path>
-                <path d="M6.33,129.47 L2.6,129.47 C1.58,129.47 0.76,128.64 0.76,127.63 L0.76,72.05 C0.76,71.03 1.59,70.21 2.6,70.21 L6.33,70.21 L6.33,129.47 L6.33,129.47 Z" id="Shape" fill="#808086"></path>
-                <path d="M183.02,373.12 C181.99,373.12 181.16,372.29 181.16,371.26 L181.16,367.54 L209.26,367.54 L209.26,371.26 C209.26,372.29 208.43,373.12 207.4,373.12 L183.02,373.12 L183.02,373.12 Z" id="Shape" fill="#808086"></path>
-                <path d="M249.35,373.12 C248.32,373.12 247.49,372.29 247.49,371.26 L247.49,367.54 L275.59,367.54 L275.59,371.26 C275.59,372.29 274.76,373.12 273.73,373.12 L249.35,373.12 L249.35,373.12 Z" id="Shape" fill="#808086"></path>
-                <path d="M795.24,313.26 C795.24,344.45 769.86,369.83 738.67,369.83 L62.09,369.83 C30.9,369.83 5.52,344.45 5.52,313.26 L5.52,57.26 C5.52,26.07 30.9,0.69 62.09,0.69 L738.67,0.69 C769.86,0.69 795.24,26.07 795.24,57.26 L795.24,313.26 L795.24,313.26 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                <path d="M791.17,313.26 C791.17,342.21 767.62,365.76 738.67,365.76 L62.09,365.76 C33.14,365.76 9.59,342.21 9.59,313.26 L9.59,57.26 C9.59,28.31 33.14,4.76 62.09,4.76 L738.67,4.76 C767.62,4.76 791.17,28.31 791.17,57.26 L791.17,313.26 L791.17,313.26 Z" id="Shape" fill="url(#linearGradient-2)"></path>
-                <rect id="Rectangle-path" fill="#2E2E2E" x="72.56" y="363.15" width="6" height="6.69"></rect>
-                <rect id="Rectangle-path" fill="#1F1F1F" x="72.56" y="0.69" width="6" height="6.74"></rect>
-                <rect id="Rectangle-path" fill="#2E2E2E" x="721.76" y="363.15" width="6" height="6.69"></rect>
-                <rect id="Rectangle-path" fill="#1F1F1F" x="721.76" y="0.69" width="6" height="6.74"></rect>
-                <path d="M788.62,313.26 C788.62,340.8 766.21,363.21 738.67,363.21 L62.09,363.21 C34.55,363.21 12.14,340.8 12.14,313.26 L12.14,57.26 C12.14,29.72 34.55,7.31 62.09,7.31 L738.67,7.31 C766.21,7.31 788.62,29.72 788.62,57.26 L788.62,313.26 L788.62,313.26 Z" id="Shape" fill="#232323"></path>
-                <path d="M739.1,153.87 C721.76,153.87 707.7,167.93 707.7,185.27 C707.7,202.61 721.76,216.67 739.1,216.67 C756.44,216.67 770.5,202.61 770.5,185.27 C770.5,167.93 756.44,153.87 739.1,153.87 L739.1,153.87 Z M739.1,213.79 C723.35,213.79 710.57,201.02 710.57,185.26 C710.57,169.5 723.34,156.73 739.1,156.73 C754.86,156.73 767.63,169.5 767.63,185.26 C767.63,201.02 754.85,213.79 739.1,213.79 L739.1,213.79 Z" id="Shape" fill="url(#linearGradient-3)"></path>
-                <g transform="translate(37.000000, 177.000000)">
-                    <circle id="Oval" fill="#5D5D5F" cx="8.04" cy="8.27" r="8"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-4)" cx="8.04" cy="8.27" r="8"></circle>
-                    <circle id="Oval" fill="#1B1A1F" cx="8.04" cy="8.27" r="4.48"></circle>
-                    <circle id="Oval" fill="#36284C" cx="8.04" cy="8.27" r="3.28"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-5)" cx="8.04" cy="8.27" r="3.28"></circle>
-                    <g transform="translate(6.000000, 6.000000)" id="Oval">
-                        <circle fill="#141414" opacity="0.5" cx="2.04" cy="2.27" r="1.8"></circle>
-                        <circle fill="url(#radialGradient-6)" cx="2.04" cy="2.27" r="1.8"></circle>
-                    </g>
-                    <path d="M8.04,6.91 C7.64,6.91 7.29,7.09 7.04,7.37 L7.46,7.79 C7.6,7.62 7.8,7.51 8.03,7.51 C8.27,7.51 8.47,7.63 8.61,7.81 L9.03,7.39 C8.8,7.1 8.44,6.91 8.04,6.91 L8.04,6.91 Z" id="Shape" fill="url(#linearGradient-7)"></path>
-                </g>
-                <g transform="translate(69.000000, 153.000000)" id="Clipped">
-                    <g>
-                        <mask id="mask-9" fill="white">
-                            <use xlink:href="#path-8"></use>
-                        </mask>
-                        <g id="SVGID_8_"></g>
-                        <path d="M8.84,2.95 L8.84,61.57 C8.84,63.94 6.92,65.86 4.55,65.86 L4.55,65.86 C2.18,65.86 0.26,63.94 0.26,61.57 L0.26,2.95 C0.26,0.58 2.18,-1.34 4.55,-1.34 L4.55,-1.34 C6.92,-1.34 8.84,0.58 8.84,2.95 L8.84,2.95 Z" id="Shape" fill="url(#linearGradient-10)" opacity="0.8" mask="url(#mask-9)"></path>
-                    </g>
-                    <g>
-                        <mask id="mask-12" fill="white">
-                            <use xlink:href="#path-11"></use>
-                        </mask>
-                        <g id="SVGID_8_"></g>
-                        <path d="M0.15,64.45 L0.15,65.92 L1.62,65.92 L1.62,64.45 L0.15,64.45 L0.15,64.45 Z M0.15,61.52 L0.15,62.99 L1.62,62.99 L1.62,61.52 L0.15,61.52 L0.15,61.52 Z M0.15,58.58 L0.15,60.05 L1.62,60.05 L1.62,58.58 L0.15,58.58 L0.15,58.58 Z M0.15,55.65 L0.15,57.12 L1.62,57.12 L1.62,55.65 L0.15,55.65 L0.15,55.65 Z M0.15,52.71 L0.15,54.18 L1.62,54.18 L1.62,52.71 L0.15,52.71 L0.15,52.71 Z M0.15,49.78 L0.15,51.25 L1.62,51.25 L1.62,49.78 L0.15,49.78 L0.15,49.78 Z M0.15,46.84 L0.15,48.31 L1.62,48.31 L1.62,46.84 L0.15,46.84 L0.15,46.84 Z M0.15,43.91 L0.15,45.38 L1.62,45.38 L1.62,43.91 L0.15,43.91 L0.15,43.91 Z M0.15,40.97 L0.15,42.44 L1.62,42.44 L1.62,40.97 L0.15,40.97 L0.15,40.97 Z M0.15,38.04 L0.15,39.51 L1.62,39.51 L1.62,38.04 L0.15,38.04 L0.15,38.04 Z M0.15,35.1 L0.15,36.57 L1.62,36.57 L1.62,35.1 L0.15,35.1 L0.15,35.1 Z M0.15,32.17 L0.15,33.64 L1.62,33.64 L1.62,32.17 L0.15,32.17 L0.15,32.17 Z M0.15,29.23 L0.15,30.7 L1.62,30.7 L1.62,29.23 L0.15,29.23 L0.15,29.23 Z M0.15,26.3 L0.15,27.77 L1.62,27.77 L1.62,26.3 L0.15,26.3 L0.15,26.3 Z M0.15,23.36 L0.15,24.83 L1.62,24.83 L1.62,23.36 L0.15,23.36 L0.15,23.36 Z M0.15,20.43 L0.15,21.9 L1.62,21.9 L1.62,20.43 L0.15,20.43 L0.15,20.43 Z M0.15,17.49 L0.15,18.96 L1.62,18.96 L1.62,17.49 L0.15,17.49 L0.15,17.49 Z M0.15,14.56 L0.15,16.03 L1.62,16.03 L1.62,14.56 L0.15,14.56 L0.15,14.56 Z M0.15,11.62 L0.15,13.09 L1.62,13.09 L1.62,11.62 L0.15,11.62 L0.15,11.62 Z M0.15,8.69 L0.15,10.16 L1.62,10.16 L1.62,8.69 L0.15,8.69 L0.15,8.69 Z M0.15,5.75 L0.15,7.22 L1.62,7.22 L1.62,5.75 L0.15,5.75 L0.15,5.75 Z M0.15,2.82 L0.15,4.29 L1.62,4.29 L1.62,2.82 L0.15,2.82 L0.15,2.82 Z M0.15,-0.12 L0.15,1.35 L1.62,1.35 L1.62,-0.12 L0.15,-0.12 L0.15,-0.12 Z M1.62,62.98 L1.62,64.45 L3.09,64.45 L3.09,62.98 L1.62,62.98 L1.62,62.98 Z M1.62,60.05 L1.62,61.52 L3.09,61.52 L3.09,60.05 L1.62,60.05 L1.62,60.05 Z M1.62,57.11 L1.62,58.58 L3.09,58.58 L3.09,57.11 L1.62,57.11 L1.62,57.11 Z M1.62,54.18 L1.62,55.65 L3.09,55.65 L3.09,54.18 L1.62,54.18 L1.62,54.18 Z M1.62,51.24 L1.62,52.71 L3.09,52.71 L3.09,51.24 L1.62,51.24 L1.62,51.24 Z M1.62,48.31 L1.62,49.78 L3.09,49.78 L3.09,48.31 L1.62,48.31 L1.62,48.31 Z M1.62,45.37 L1.62,46.84 L3.09,46.84 L3.09,45.37 L1.62,45.37 L1.62,45.37 Z M1.62,42.44 L1.62,43.91 L3.09,43.91 L3.09,42.44 L1.62,42.44 L1.62,42.44 Z M1.62,39.5 L1.62,40.97 L3.09,40.97 L3.09,39.5 L1.62,39.5 L1.62,39.5 Z M1.62,36.57 L1.62,38.04 L3.09,38.04 L3.09,36.57 L1.62,36.57 L1.62,36.57 Z M1.62,33.63 L1.62,35.1 L3.09,35.1 L3.09,33.63 L1.62,33.63 L1.62,33.63 Z M1.62,30.7 L1.62,32.17 L3.09,32.17 L3.09,30.7 L1.62,30.7 L1.62,30.7 Z M1.62,27.76 L1.62,29.23 L3.09,29.23 L3.09,27.76 L1.62,27.76 L1.62,27.76 Z M1.62,24.83 L1.62,26.3 L3.09,26.3 L3.09,24.83 L1.62,24.83 L1.62,24.83 Z M1.62,21.89 L1.62,23.36 L3.09,23.36 L3.09,21.89 L1.62,21.89 L1.62,21.89 Z M1.62,18.96 L1.62,20.43 L3.09,20.43 L3.09,18.96 L1.62,18.96 L1.62,18.96 Z M1.62,16.02 L1.62,17.49 L3.09,17.49 L3.09,16.02 L1.62,16.02 L1.62,16.02 Z M1.62,13.09 L1.62,14.56 L3.09,14.56 L3.09,13.09 L1.62,13.09 L1.62,13.09 Z M1.62,10.15 L1.62,11.62 L3.09,11.62 L3.09,10.15 L1.62,10.15 L1.62,10.15 Z M1.62,7.22 L1.62,8.69 L3.09,8.69 L3.09,7.22 L1.62,7.22 L1.62,7.22 Z M1.62,4.28 L1.62,5.75 L3.09,5.75 L3.09,4.28 L1.62,4.28 L1.62,4.28 Z M1.62,1.35 L1.62,2.82 L3.09,2.82 L3.09,1.35 L1.62,1.35 L1.62,1.35 Z M1.62,-1.59 L1.62,-0.12 L3.09,-0.12 L3.09,-1.59 L1.62,-1.59 L1.62,-1.59 Z M3.09,64.45 L3.09,65.92 L4.56,65.92 L4.56,64.45 L3.09,64.45 L3.09,64.45 Z M3.09,61.52 L3.09,62.99 L4.56,62.99 L4.56,61.52 L3.09,61.52 L3.09,61.52 Z M3.09,58.58 L3.09,60.05 L4.56,60.05 L4.56,58.58 L3.09,58.58 L3.09,58.58 Z M3.09,55.65 L3.09,57.12 L4.56,57.12 L4.56,55.65 L3.09,55.65 L3.09,55.65 Z M3.09,52.71 L3.09,54.18 L4.56,54.18 L4.56,52.71 L3.09,52.71 L3.09,52.71 Z M3.09,49.78 L3.09,51.25 L4.56,51.25 L4.56,49.78 L3.09,49.78 L3.09,49.78 Z M3.09,46.84 L3.09,48.31 L4.56,48.31 L4.56,46.84 L3.09,46.84 L3.09,46.84 Z M3.09,43.91 L3.09,45.38 L4.56,45.38 L4.56,43.91 L3.09,43.91 L3.09,43.91 Z M3.09,40.97 L3.09,42.44 L4.56,42.44 L4.56,40.97 L3.09,40.97 L3.09,40.97 Z M3.09,38.04 L3.09,39.51 L4.56,39.51 L4.56,38.04 L3.09,38.04 L3.09,38.04 Z M3.09,35.1 L3.09,36.57 L4.56,36.57 L4.56,35.1 L3.09,35.1 L3.09,35.1 Z M3.09,32.17 L3.09,33.64 L4.56,33.64 L4.56,32.17 L3.09,32.17 L3.09,32.17 Z M3.09,29.23 L3.09,30.7 L4.56,30.7 L4.56,29.23 L3.09,29.23 L3.09,29.23 Z M3.09,26.3 L3.09,27.77 L4.56,27.77 L4.56,26.3 L3.09,26.3 L3.09,26.3 Z M3.09,23.36 L3.09,24.83 L4.56,24.83 L4.56,23.36 L3.09,23.36 L3.09,23.36 Z M3.09,20.43 L3.09,21.9 L4.56,21.9 L4.56,20.43 L3.09,20.43 L3.09,20.43 Z M3.09,17.49 L3.09,18.96 L4.56,18.96 L4.56,17.49 L3.09,17.49 L3.09,17.49 Z M3.09,14.56 L3.09,16.03 L4.56,16.03 L4.56,14.56 L3.09,14.56 L3.09,14.56 Z M3.09,11.62 L3.09,13.09 L4.56,13.09 L4.56,11.62 L3.09,11.62 L3.09,11.62 Z M3.09,8.69 L3.09,10.16 L4.56,10.16 L4.56,8.69 L3.09,8.69 L3.09,8.69 Z M3.09,5.75 L3.09,7.22 L4.56,7.22 L4.56,5.75 L3.09,5.75 L3.09,5.75 Z M3.09,2.82 L3.09,4.29 L4.56,4.29 L4.56,2.82 L3.09,2.82 L3.09,2.82 Z M3.09,-0.12 L3.09,1.35 L4.56,1.35 L4.56,-0.12 L3.09,-0.12 L3.09,-0.12 Z M4.56,62.98 L4.56,64.45 L6.03,64.45 L6.03,62.98 L4.56,62.98 L4.56,62.98 Z M4.56,60.05 L4.56,61.52 L6.03,61.52 L6.03,60.05 L4.56,60.05 L4.56,60.05 Z M4.56,57.11 L4.56,58.58 L6.03,58.58 L6.03,57.11 L4.56,57.11 L4.56,57.11 Z M4.56,54.18 L4.56,55.65 L6.03,55.65 L6.03,54.18 L4.56,54.18 L4.56,54.18 Z M4.56,51.24 L4.56,52.71 L6.03,52.71 L6.03,51.24 L4.56,51.24 L4.56,51.24 Z M4.56,48.31 L4.56,49.78 L6.03,49.78 L6.03,48.31 L4.56,48.31 L4.56,48.31 Z M4.56,45.37 L4.56,46.84 L6.03,46.84 L6.03,45.37 L4.56,45.37 L4.56,45.37 Z M4.56,42.44 L4.56,43.91 L6.03,43.91 L6.03,42.44 L4.56,42.44 L4.56,42.44 Z M4.56,39.5 L4.56,40.97 L6.03,40.97 L6.03,39.5 L4.56,39.5 L4.56,39.5 Z M4.56,36.57 L4.56,38.04 L6.03,38.04 L6.03,36.57 L4.56,36.57 L4.56,36.57 Z M4.56,33.63 L4.56,35.1 L6.03,35.1 L6.03,33.63 L4.56,33.63 L4.56,33.63 Z M4.56,30.7 L4.56,32.17 L6.03,32.17 L6.03,30.7 L4.56,30.7 L4.56,30.7 Z M4.56,27.76 L4.56,29.23 L6.03,29.23 L6.03,27.76 L4.56,27.76 L4.56,27.76 Z M4.56,24.83 L4.56,26.3 L6.03,26.3 L6.03,24.83 L4.56,24.83 L4.56,24.83 Z M4.56,21.89 L4.56,23.36 L6.03,23.36 L6.03,21.89 L4.56,21.89 L4.56,21.89 Z M4.56,18.96 L4.56,20.43 L6.03,20.43 L6.03,18.96 L4.56,18.96 L4.56,18.96 Z M4.56,16.02 L4.56,17.49 L6.03,17.49 L6.03,16.02 L4.56,16.02 L4.56,16.02 Z M4.56,13.09 L4.56,14.56 L6.03,14.56 L6.03,13.09 L4.56,13.09 L4.56,13.09 Z M4.56,10.15 L4.56,11.62 L6.03,11.62 L6.03,10.15 L4.56,10.15 L4.56,10.15 Z M4.56,7.22 L4.56,8.69 L6.03,8.69 L6.03,7.22 L4.56,7.22 L4.56,7.22 Z M4.56,4.28 L4.56,5.75 L6.03,5.75 L6.03,4.28 L4.56,4.28 L4.56,4.28 Z M4.56,1.35 L4.56,2.82 L6.03,2.82 L6.03,1.35 L4.56,1.35 L4.56,1.35 Z M4.56,-1.59 L4.56,-0.12 L6.03,-0.12 L6.03,-1.59 L4.56,-1.59 L4.56,-1.59 Z M6.02,64.45 L6.02,65.92 L7.49,65.92 L7.49,64.45 L6.02,64.45 L6.02,64.45 Z M6.02,61.52 L6.02,62.99 L7.49,62.99 L7.49,61.52 L6.02,61.52 L6.02,61.52 Z M6.02,58.58 L6.02,60.05 L7.49,60.05 L7.49,58.58 L6.02,58.58 L6.02,58.58 Z M6.02,55.65 L6.02,57.12 L7.49,57.12 L7.49,55.65 L6.02,55.65 L6.02,55.65 Z M6.02,52.71 L6.02,54.18 L7.49,54.18 L7.49,52.71 L6.02,52.71 L6.02,52.71 Z M6.02,49.78 L6.02,51.25 L7.49,51.25 L7.49,49.78 L6.02,49.78 L6.02,49.78 Z M6.02,46.84 L6.02,48.31 L7.49,48.31 L7.49,46.84 L6.02,46.84 L6.02,46.84 Z M6.02,43.91 L6.02,45.38 L7.49,45.38 L7.49,43.91 L6.02,43.91 L6.02,43.91 Z M6.02,40.97 L6.02,42.44 L7.49,42.44 L7.49,40.97 L6.02,40.97 L6.02,40.97 Z M6.02,38.04 L6.02,39.51 L7.49,39.51 L7.49,38.04 L6.02,38.04 L6.02,38.04 Z M6.02,35.1 L6.02,36.57 L7.49,36.57 L7.49,35.1 L6.02,35.1 L6.02,35.1 Z M6.02,32.17 L6.02,33.64 L7.49,33.64 L7.49,32.17 L6.02,32.17 L6.02,32.17 Z M6.02,29.23 L6.02,30.7 L7.49,30.7 L7.49,29.23 L6.02,29.23 L6.02,29.23 Z M6.02,26.3 L6.02,27.77 L7.49,27.77 L7.49,26.3 L6.02,26.3 L6.02,26.3 Z M6.02,23.36 L6.02,24.83 L7.49,24.83 L7.49,23.36 L6.02,23.36 L6.02,23.36 Z M6.02,20.43 L6.02,21.9 L7.49,21.9 L7.49,20.43 L6.02,20.43 L6.02,20.43 Z M6.02,17.49 L6.02,18.96 L7.49,18.96 L7.49,17.49 L6.02,17.49 L6.02,17.49 Z M6.02,14.56 L6.02,16.03 L7.49,16.03 L7.49,14.56 L6.02,14.56 L6.02,14.56 Z M6.02,11.62 L6.02,13.09 L7.49,13.09 L7.49,11.62 L6.02,11.62 L6.02,11.62 Z M6.02,8.69 L6.02,10.16 L7.49,10.16 L7.49,8.69 L6.02,8.69 L6.02,8.69 Z M6.02,5.75 L6.02,7.22 L7.49,7.22 L7.49,5.75 L6.02,5.75 L6.02,5.75 Z M6.02,2.82 L6.02,4.29 L7.49,4.29 L7.49,2.82 L6.02,2.82 L6.02,2.82 Z M6.02,-0.12 L6.02,1.35 L7.49,1.35 L7.49,-0.12 L6.02,-0.12 L6.02,-0.12 Z M7.49,62.98 L7.49,64.45 L8.96,64.45 L8.96,62.98 L7.49,62.98 L7.49,62.98 Z M7.49,60.05 L7.49,61.52 L8.96,61.52 L8.96,60.05 L7.49,60.05 L7.49,60.05 Z M7.49,57.11 L7.49,58.58 L8.96,58.58 L8.96,57.11 L7.49,57.11 L7.49,57.11 Z M7.49,54.18 L7.49,55.65 L8.96,55.65 L8.96,54.18 L7.49,54.18 L7.49,54.18 Z M7.49,51.24 L7.49,52.71 L8.96,52.71 L8.96,51.24 L7.49,51.24 L7.49,51.24 Z M7.49,48.31 L7.49,49.78 L8.96,49.78 L8.96,48.31 L7.49,48.31 L7.49,48.31 Z M7.49,45.37 L7.49,46.84 L8.96,46.84 L8.96,45.37 L7.49,45.37 L7.49,45.37 Z M7.49,42.44 L7.49,43.91 L8.96,43.91 L8.96,42.44 L7.49,42.44 L7.49,42.44 Z M7.49,39.5 L7.49,40.97 L8.96,40.97 L8.96,39.5 L7.49,39.5 L7.49,39.5 Z M7.49,36.57 L7.49,38.04 L8.96,38.04 L8.96,36.57 L7.49,36.57 L7.49,36.57 Z M7.49,33.63 L7.49,35.1 L8.96,35.1 L8.96,33.63 L7.49,33.63 L7.49,33.63 Z M7.49,30.7 L7.49,32.17 L8.96,32.17 L8.96,30.7 L7.49,30.7 L7.49,30.7 Z M7.49,27.76 L7.49,29.23 L8.96,29.23 L8.96,27.76 L7.49,27.76 L7.49,27.76 Z M7.49,24.83 L7.49,26.3 L8.96,26.3 L8.96,24.83 L7.49,24.83 L7.49,24.83 Z M7.49,21.89 L7.49,23.36 L8.96,23.36 L8.96,21.89 L7.49,21.89 L7.49,21.89 Z M7.49,18.96 L7.49,20.43 L8.96,20.43 L8.96,18.96 L7.49,18.96 L7.49,18.96 Z M7.49,16.02 L7.49,17.49 L8.96,17.49 L8.96,16.02 L7.49,16.02 L7.49,16.02 Z M7.49,13.09 L7.49,14.56 L8.96,14.56 L8.96,13.09 L7.49,13.09 L7.49,13.09 Z M7.49,10.15 L7.49,11.62 L8.96,11.62 L8.96,10.15 L7.49,10.15 L7.49,10.15 Z M7.49,7.22 L7.49,8.69 L8.96,8.69 L8.96,7.22 L7.49,7.22 L7.49,7.22 Z M7.49,4.28 L7.49,5.75 L8.96,5.75 L8.96,4.28 L7.49,4.28 L7.49,4.28 Z M7.49,1.35 L7.49,2.82 L8.96,2.82 L8.96,1.35 L7.49,1.35 L7.49,1.35 Z M7.49,-1.59 L7.49,-0.12 L8.96,-0.12 L8.96,-1.59 L7.49,-1.59 L7.49,-1.59 Z" id="Shape" fill="#2E2E2E" mask="url(#mask-12)"></path>
-                    </g>
-                    <g>
-                        <mask id="mask-14" fill="white">
-                            <use xlink:href="#path-13"></use>
-                        </mask>
-                        <g id="SVGID_8_"></g>
-                        <path d="M-0.09,2.54 L-0.09,61.98 C-0.09,64.38 1.99,66.33 4.56,66.33 C7.13,66.33 9.21,64.38 9.21,61.98 L9.21,2.54 C9.21,0.14 7.13,-1.81 4.56,-1.81 C1.99,-1.81 -0.09,0.14 -0.09,2.54 L-0.09,2.54 Z M7.75,2.95 L7.75,61.57 C7.75,63.33 6.32,64.77 4.55,64.77 C2.78,64.77 1.35,63.34 1.35,61.57 L1.35,2.95 C1.35,1.19 2.78,-0.25 4.55,-0.25 C6.32,-0.25 7.75,1.19 7.75,2.95 L7.75,2.95 Z" id="Shape" fill="#000000" opacity="0.2" mask="url(#mask-14)"></path>
-                    </g>
-                </g>
-                <rect id="Rectangle-path" fill="#000000" x="114.62" y="25.28" width="568" height="320"></rect>
-            </g>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPhone5-portrait.svg b/front_end/emulated_devices/iPhone5-portrait.svg
deleted file mode 100644
index ab22302..0000000
--- a/front_end/emulated_devices/iPhone5-portrait.svg
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="374px" height="795px" viewBox="0 0 374 795" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPhone 5</title>
-    <defs>
-        <linearGradient x1="58.9659534%" y1="48.080666%" x2="34.111078%" y2="53.3994176%" id="linearGradient-1">
-            <stop stop-color="#3A3E3A" offset="8.860001%"></stop>
-            <stop stop-color="#2E332E" offset="34.31%"></stop>
-            <stop stop-color="#C0C1C2" offset="36%"></stop>
-            <stop stop-color="#3C3F3E" offset="51.34%"></stop>
-            <stop stop-color="#4B4E4B" offset="64.16%"></stop>
-        </linearGradient>
-        <linearGradient x1="-17.9960388%" y1="8.33030962%" x2="65.7898338%" y2="59.671955%" id="linearGradient-2">
-            <stop stop-color="#787A81" offset="0%"></stop>
-            <stop stop-color="#50555D" offset="63.53%"></stop>
-        </linearGradient>
-        <linearGradient x1="86.4058917%" y1="91.8829618%" x2="14.0627389%" y2="8.61990446%" id="linearGradient-3">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="50.490424%" cy="57.371957%" fx="50.490424%" fy="57.371957%" r="32.026875%" id="radialGradient-4">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.9198485%" cy="96.651617%" fx="47.9198485%" fy="96.651617%" r="60.9878788%" id="radialGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="51.1128422%" cy="24.9366133%" fx="51.1128422%" fy="24.9366133%" r="36.9055556%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="50.25%" y1="5.34%" x2="50.25%" y2="97.86%" id="linearGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="-13.4283698%" y1="16.8838122%" x2="28.9472124%" y2="39.0002762%" id="linearGradient-8">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="50.0148322%" y1="100.475178%" x2="50.0148322%" y2="0.707893372%" id="linearGradient-9">
-            <stop stop-color="#2E2E31" offset="0%"></stop>
-            <stop stop-color="#616161" offset="24.48%"></stop>
-            <stop stop-color="#858585" offset="81.37%"></stop>
-            <stop stop-color="#2E2E31" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="iphone5-portrait">
-            <g id="Group">
-                <path d="M6.1,141.1 L2.4,141.1 C1.4,141.1 0.6,140.3 0.6,139.3 L0.6,108.7 C0.6,107.7 1.4,106.9 2.4,106.9 L6.1,106.9 L6.1,141.1 L6.1,141.1 L6.1,141.1 Z" id="Shape" fill="#808086"></path>
-                <path d="M244.4,5.7 L244.4,2 C244.4,1 245.2,0.2 246.2,0.2 L301.8,0.2 C302.8,0.2 303.6,1 303.6,2 L303.6,5.7 L244.4,5.7 L244.4,5.7 Z" id="Shape" fill="#808086"></path>
-                <path d="M0.8,182.4 C0.8,181.4 1.6,180.5 2.7,180.5 L6.4,180.5 L6.4,208.6 L2.7,208.6 C1.7,208.6 0.8,207.8 0.8,206.7 L0.8,182.4 L0.8,182.4 L0.8,182.4 Z" id="Shape" fill="#808086"></path>
-                <path d="M0.8,248.8 C0.8,247.8 1.6,246.9 2.7,246.9 L6.4,246.9 L6.4,275 L2.7,275 C1.7,275 0.8,274.2 0.8,273.1 L0.8,248.8 L0.8,248.8 L0.8,248.8 Z" id="Shape" fill="#808086"></path>
-                <path d="M60.6,794.7 C29.4,794.7 4,769.3 4,738.1 L4,61.5 C4,30.3 29.4,4.9 60.6,4.9 L316.6,4.9 C347.8,4.9 373.2,30.3 373.2,61.5 L373.2,738.1 C373.2,769.3 347.8,794.7 316.6,794.7 L60.6,794.7 L60.6,794.7 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                <path d="M60.6,790.6 C31.7,790.6 8.1,767.1 8.1,738.1 L8.1,61.5 C8.1,32.5 31.7,9 60.6,9 L316.6,9 C345.6,9 369.1,32.5 369.1,61.5 L369.1,738.1 C369.1,767.1 345.6,790.6 316.6,790.6 L60.6,790.6 L60.6,790.6 L60.6,790.6 Z" id="Shape" fill="url(#linearGradient-2)"></path>
-                <rect id="Rectangle-path" fill="#2E2E2E" x="4" y="72" width="6.7" height="6"></rect>
-                <rect id="Rectangle-path" fill="#1F1F1F" x="366.5" y="72" width="6.7" height="6"></rect>
-                <rect id="Rectangle-path" fill="#2E2E2E" x="4" y="721.2" width="6.7" height="6"></rect>
-                <rect id="Rectangle-path" fill="#1F1F1F" x="366.5" y="721.2" width="6.7" height="6"></rect>
-                <path d="M60.6,788 C33.1,788 10.7,765.6 10.7,738 L10.7,61.5 C10.7,34 33.1,11.5 60.6,11.5 L316.6,11.5 C344.1,11.5 366.6,33.9 366.6,61.5 L366.6,738.1 C366.6,765.6 344.2,788.1 316.6,788.1 L60.6,788 L60.6,788 L60.6,788 Z" id="Shape" fill="#232323"></path>
-                <path d="M188.6,707.1 C171.3,707.1 157.2,721.2 157.2,738.5 C157.2,755.8 171.3,769.9 188.6,769.9 C205.9,769.9 220,755.8 220,738.5 C220,721.2 205.9,707.1 188.6,707.1 L188.6,707.1 Z M188.6,767 C172.8,767 160.1,754.2 160.1,738.5 C160.1,722.7 172.9,710 188.6,710 C204.3,710 217.1,722.8 217.1,738.5 C217.1,754.2 204.4,767 188.6,767 L188.6,767 Z" id="Shape" fill="url(#linearGradient-3)"></path>
-                <g transform="translate(180.000000, 36.000000)">
-                    <circle id="Oval" fill="#5D5D5F" cx="8.6" cy="8.4" r="8"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-4)" cx="8.6" cy="8.4" r="8"></circle>
-                    <circle id="Oval" fill="#1B1A1F" cx="8.6" cy="8.4" r="4.5"></circle>
-                    <circle id="Oval" fill="#36284C" cx="8.6" cy="8.4" r="3.3"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-5)" cx="8.6" cy="8.4" r="3.3"></circle>
-                    <g transform="translate(6.000000, 6.000000)" id="Oval">
-                        <circle fill="#141414" opacity="0.5" cx="2.6" cy="2.4" r="1.8"></circle>
-                        <circle fill="url(#radialGradient-6)" cx="2.6" cy="2.4" r="1.8"></circle>
-                    </g>
-                    <path d="M8.6,7.1 C8.2,7.1 7.8,7.3 7.6,7.6 L8,8 C8.1,7.8 8.3,7.7 8.6,7.7 C8.8,7.7 9,7.8 9.2,8 L9.6,7.6 C9.4,7.3 9,7.1 8.6,7.1 L8.6,7.1 Z" id="Shape" fill="url(#linearGradient-7)"></path>
-                </g>
-                <path d="M60.6,11.6 C33.1,11.6 10.7,34 10.7,61.6 L10.7,554.6 L294.1,11.6 L60.6,11.6 L60.6,11.6 Z" id="Shape" fill="url(#linearGradient-8)"></path>
-                <g transform="translate(154.000000, 68.000000)" id="Shape">
-                    <path d="M63.9,9.2 L5.3,9.2 C2.9,9.2 1,7.3 1,4.9 L1,4.9 C1,2.5 2.9,0.6 5.3,0.6 L63.9,0.6 C66.3,0.6 68.2,2.5 68.2,4.9 L68.2,4.9 C68.2,7.3 66.3,9.2 63.9,9.2 L63.9,9.2 Z" fill="url(#linearGradient-9)" opacity="0.8"></path>
-                    <path d="M2.4,0.6 L0.9,0.6 L0.9,2 L2.4,2 L2.4,0.6 L2.4,0.6 Z M5.4,0.6 L3.9,0.6 L3.9,2 L5.4,2 L5.4,0.6 L5.4,0.6 Z M8.3,0.6 L6.8,0.6 L6.8,2 L8.3,2 L8.3,0.6 L8.3,0.6 Z M11.2,0.6 L9.7,0.6 L9.7,2 L11.2,2 L11.2,0.6 L11.2,0.6 Z M14.2,0.6 L12.7,0.6 L12.7,2 L14.2,2 L14.2,0.6 L14.2,0.6 Z M17.1,0.6 L15.6,0.6 L15.6,2 L17.1,2 L17.1,0.6 L17.1,0.6 Z M20,0.6 L18.5,0.6 L18.5,2 L20,2 L20,0.6 L20,0.6 Z M23,0.6 L21.5,0.6 L21.5,2 L23,2 L23,0.6 L23,0.6 Z M25.9,0.6 L24.4,0.6 L24.4,2 L25.9,2 L25.9,0.6 L25.9,0.6 Z M28.8,0.6 L27.3,0.6 L27.3,2 L28.8,2 L28.8,0.6 L28.8,0.6 Z M31.8,0.6 L30.3,0.6 L30.3,2 L31.8,2 L31.8,0.6 L31.8,0.6 Z M34.7,0.6 L33.2,0.6 L33.2,2 L34.7,2 L34.7,0.6 L34.7,0.6 Z M37.6,0.6 L36.1,0.6 L36.1,2 L37.6,2 L37.6,0.6 L37.6,0.6 Z M40.6,0.6 L39.1,0.6 L39.1,2 L40.6,2 L40.6,0.6 L40.6,0.6 Z M43.5,0.6 L42,0.6 L42,2 L43.5,2 L43.5,0.6 L43.5,0.6 Z M46.4,0.6 L45,0.6 L45,2 L46.5,2 L46.5,0.6 L46.4,0.6 Z M49.4,0.6 L47.9,0.6 L47.9,2 L49.4,2 L49.4,0.6 L49.4,0.6 Z M52.3,0.6 L50.8,0.6 L50.8,2 L52.3,2 L52.3,0.6 L52.3,0.6 Z M55.2,0.6 L53.7,0.6 L53.7,2 L55.2,2 L55.2,0.6 L55.2,0.6 Z M58.2,0.6 L56.7,0.6 L56.7,2 L58.2,2 L58.2,0.6 L58.2,0.6 Z M61.1,0.6 L59.6,0.6 L59.6,2 L61.1,2 L61.1,0.6 L61.1,0.6 Z M64.1,0.6 L62.6,0.6 L62.6,2 L64.1,2 L64.1,0.6 L64.1,0.6 Z M67,0.6 L65.5,0.6 L65.5,2 L67,2 L67,0.6 L67,0.6 Z M3.9,2 L2.4,2 L2.4,3.5 L3.9,3.5 L3.9,2 L3.9,2 Z M6.8,2 L5.3,2 L5.3,3.5 L6.8,3.5 L6.8,2 L6.8,2 Z M9.8,2 L8.3,2 L8.3,3.5 L9.8,3.5 L9.8,2 L9.8,2 Z M12.7,2 L11.2,2 L11.2,3.5 L12.7,3.5 L12.7,2 L12.7,2 Z M15.6,2 L14.1,2 L14.1,3.5 L15.6,3.5 L15.6,2 L15.6,2 Z M18.6,2 L17.1,2 L17.1,3.5 L18.6,3.5 L18.6,2 L18.6,2 Z M21.5,2 L20,2 L20,3.5 L21.5,3.5 L21.5,2 L21.5,2 Z M24.4,2 L23,2 L23,3.5 L24.5,3.5 L24.5,2 L24.4,2 Z M27.4,2 L25.9,2 L25.9,3.5 L27.4,3.5 L27.4,2 L27.4,2 Z M30.3,2 L28.8,2 L28.8,3.5 L30.3,3.5 L30.3,2 L30.3,2 Z M33.2,2 L31.7,2 L31.7,3.5 L33.2,3.5 L33.2,2 L33.2,2 Z M36.2,2 L34.7,2 L34.7,3.5 L36.2,3.5 L36.2,2 L36.2,2 Z M39.1,2 L37.6,2 L37.6,3.5 L39.1,3.5 L39.1,2 L39.1,2 Z M42,2 L40.5,2 L40.5,3.5 L42,3.5 L42,2 L42,2 Z M45,2 L43.5,2 L43.5,3.5 L45,3.5 L45,2 L45,2 Z M47.9,2 L46.4,2 L46.4,3.5 L47.9,3.5 L47.9,2 L47.9,2 Z M50.9,2 L49.4,2 L49.4,3.5 L50.9,3.5 L50.9,2 L50.9,2 Z M53.8,2 L52.3,2 L52.3,3.5 L53.8,3.5 L53.8,2 L53.8,2 Z M56.7,2 L55.2,2 L55.2,3.5 L56.7,3.5 L56.7,2 L56.7,2 Z M59.6,2 L58.1,2 L58.1,3.5 L59.6,3.5 L59.6,2 L59.6,2 Z M62.6,2 L61.1,2 L61.1,3.5 L62.6,3.5 L62.6,2 L62.6,2 Z M65.5,2 L64,2 L64,3.5 L65.5,3.5 L65.5,2 L65.5,2 Z M68.5,2 L67,2 L67,3.5 L68.5,3.5 L68.5,2 L68.5,2 Z M2.4,3.5 L0.9,3.5 L0.9,5 L2.4,5 L2.4,3.5 L2.4,3.5 Z M5.4,3.5 L3.9,3.5 L3.9,5 L5.4,5 L5.4,3.5 L5.4,3.5 Z M8.3,3.5 L6.8,3.5 L6.8,5 L8.3,5 L8.3,3.5 L8.3,3.5 Z M11.2,3.5 L9.7,3.5 L9.7,5 L11.2,5 L11.2,3.5 L11.2,3.5 Z M14.2,3.5 L12.7,3.5 L12.7,5 L14.2,5 L14.2,3.5 L14.2,3.5 Z M17.1,3.5 L15.6,3.5 L15.6,5 L17.1,5 L17.1,3.5 L17.1,3.5 Z M20,3.5 L18.5,3.5 L18.5,5 L20,5 L20,3.5 L20,3.5 Z M23,3.5 L21.5,3.5 L21.5,5 L23,5 L23,3.5 L23,3.5 Z M25.9,3.5 L24.4,3.5 L24.4,5 L25.9,5 L25.9,3.5 L25.9,3.5 Z M28.8,3.5 L27.3,3.5 L27.3,5 L28.8,5 L28.8,3.5 L28.8,3.5 Z M31.8,3.5 L30.3,3.5 L30.3,5 L31.8,5 L31.8,3.5 L31.8,3.5 Z M34.7,3.5 L33.2,3.5 L33.2,5 L34.7,5 L34.7,3.5 L34.7,3.5 Z M37.6,3.5 L36.1,3.5 L36.1,5 L37.6,5 L37.6,3.5 L37.6,3.5 Z M40.6,3.5 L39.1,3.5 L39.1,5 L40.6,5 L40.6,3.5 L40.6,3.5 Z M43.5,3.5 L42,3.5 L42,5 L43.5,5 L43.5,3.5 L43.5,3.5 Z M46.4,3.5 L45,3.5 L45,5 L46.5,5 L46.5,3.5 L46.4,3.5 Z M49.4,3.5 L47.9,3.5 L47.9,5 L49.4,5 L49.4,3.5 L49.4,3.5 Z M52.3,3.5 L50.8,3.5 L50.8,5 L52.3,5 L52.3,3.5 L52.3,3.5 Z M55.2,3.5 L53.7,3.5 L53.7,5 L55.2,5 L55.2,3.5 L55.2,3.5 Z M58.2,3.5 L56.7,3.5 L56.7,5 L58.2,5 L58.2,3.5 L58.2,3.5 Z M61.1,3.5 L59.6,3.5 L59.6,5 L61.1,5 L61.1,3.5 L61.1,3.5 Z M64.1,3.5 L62.6,3.5 L62.6,5 L64.1,5 L64.1,3.5 L64.1,3.5 Z M67,3.5 L65.5,3.5 L65.5,5 L67,5 L67,3.5 L67,3.5 Z M3.9,5 L2.4,5 L2.4,6.5 L3.9,6.5 L3.9,5 L3.9,5 Z M6.8,5 L5.3,5 L5.3,6.5 L6.8,6.5 L6.8,5 L6.8,5 Z M9.8,5 L8.3,5 L8.3,6.5 L9.8,6.5 L9.8,5 L9.8,5 Z M12.7,5 L11.2,5 L11.2,6.5 L12.7,6.5 L12.7,5 L12.7,5 Z M15.6,5 L14.1,5 L14.1,6.5 L15.6,6.5 L15.6,5 L15.6,5 Z M18.6,5 L17.1,5 L17.1,6.5 L18.6,6.5 L18.6,5 L18.6,5 Z M21.5,5 L20,5 L20,6.5 L21.5,6.5 L21.5,5 L21.5,5 Z M24.4,5 L23,5 L23,6.5 L24.5,6.5 L24.5,5 L24.4,5 Z M27.4,5 L25.9,5 L25.9,6.5 L27.4,6.5 L27.4,5 L27.4,5 Z M30.3,5 L28.8,5 L28.8,6.5 L30.3,6.5 L30.3,5 L30.3,5 Z M33.2,5 L31.7,5 L31.7,6.5 L33.2,6.5 L33.2,5 L33.2,5 Z M36.2,5 L34.7,5 L34.7,6.5 L36.2,6.5 L36.2,5 L36.2,5 Z M39.1,5 L37.6,5 L37.6,6.5 L39.1,6.5 L39.1,5 L39.1,5 Z M42,5 L40.5,5 L40.5,6.5 L42,6.5 L42,5 L42,5 Z M45,5 L43.5,5 L43.5,6.5 L45,6.5 L45,5 L45,5 Z M47.9,5 L46.4,5 L46.4,6.5 L47.9,6.5 L47.9,5 L47.9,5 Z M50.9,5 L49.4,5 L49.4,6.5 L50.9,6.5 L50.9,5 L50.9,5 Z M53.8,5 L52.3,5 L52.3,6.5 L53.8,6.5 L53.8,5 L53.8,5 Z M56.7,5 L55.2,5 L55.2,6.5 L56.7,6.5 L56.7,5 L56.7,5 Z M59.6,5 L58.1,5 L58.1,6.5 L59.6,6.5 L59.6,5 L59.6,5 Z M62.6,5 L61.1,5 L61.1,6.5 L62.6,6.5 L62.6,5 L62.6,5 Z M65.5,5 L64,5 L64,6.5 L65.5,6.5 L65.5,5 L65.5,5 Z M68.5,5 L67,5 L67,6.5 L68.5,6.5 L68.5,5 L68.5,5 Z M2.4,6.4 L0.9,6.4 L0.9,7.9 L2.4,7.9 L2.4,6.4 L2.4,6.4 Z M5.4,6.4 L3.9,6.4 L3.9,7.9 L5.4,7.9 L5.4,6.4 L5.4,6.4 Z M8.3,6.4 L6.8,6.4 L6.8,7.9 L8.3,7.9 L8.3,6.4 L8.3,6.4 Z M11.2,6.4 L9.7,6.4 L9.7,7.9 L11.2,7.9 L11.2,6.4 L11.2,6.4 Z M14.2,6.4 L12.7,6.4 L12.7,7.9 L14.2,7.9 L14.2,6.4 L14.2,6.4 Z M17.1,6.4 L15.6,6.4 L15.6,7.9 L17.1,7.9 L17.1,6.4 L17.1,6.4 Z M20,6.4 L18.5,6.4 L18.5,7.9 L20,7.9 L20,6.4 L20,6.4 Z M23,6.4 L21.5,6.4 L21.5,7.9 L23,7.9 L23,6.4 L23,6.4 Z M25.9,6.4 L24.4,6.4 L24.4,7.9 L25.9,7.9 L25.9,6.4 L25.9,6.4 Z M28.8,6.4 L27.3,6.4 L27.3,7.9 L28.8,7.9 L28.8,6.4 L28.8,6.4 Z M31.8,6.4 L30.3,6.4 L30.3,7.9 L31.8,7.9 L31.8,6.4 L31.8,6.4 Z M34.7,6.4 L33.2,6.4 L33.2,7.9 L34.7,7.9 L34.7,6.4 L34.7,6.4 Z M37.6,6.4 L36.1,6.4 L36.1,7.9 L37.6,7.9 L37.6,6.4 L37.6,6.4 Z M40.6,6.4 L39.1,6.4 L39.1,7.9 L40.6,7.9 L40.6,6.4 L40.6,6.4 Z M43.5,6.4 L42,6.4 L42,7.9 L43.5,7.9 L43.5,6.4 L43.5,6.4 Z M46.4,6.4 L45,6.4 L45,7.9 L46.5,7.9 L46.5,6.4 L46.4,6.4 Z M49.4,6.4 L47.9,6.4 L47.9,7.9 L49.4,7.9 L49.4,6.4 L49.4,6.4 Z M52.3,6.4 L50.8,6.4 L50.8,7.9 L52.3,7.9 L52.3,6.4 L52.3,6.4 Z M55.2,6.4 L53.7,6.4 L53.7,7.9 L55.2,7.9 L55.2,6.4 L55.2,6.4 Z M58.2,6.4 L56.7,6.4 L56.7,7.9 L58.2,7.9 L58.2,6.4 L58.2,6.4 Z M61.1,6.4 L59.6,6.4 L59.6,7.9 L61.1,7.9 L61.1,6.4 L61.1,6.4 Z M64.1,6.4 L62.6,6.4 L62.6,7.9 L64.1,7.9 L64.1,6.4 L64.1,6.4 Z M67,6.4 L65.5,6.4 L65.5,7.9 L67,7.9 L67,6.4 L67,6.4 Z M3.9,7.9 L2.4,7.9 L2.4,9.4 L3.9,9.4 L3.9,7.9 L3.9,7.9 Z M6.8,7.9 L5.3,7.9 L5.3,9.4 L6.8,9.4 L6.8,7.9 L6.8,7.9 Z M9.8,7.9 L8.3,7.9 L8.3,9.4 L9.8,9.4 L9.8,7.9 L9.8,7.9 Z M12.7,7.9 L11.2,7.9 L11.2,9.4 L12.7,9.4 L12.7,7.9 L12.7,7.9 Z M15.6,7.9 L14.1,7.9 L14.1,9.4 L15.6,9.4 L15.6,7.9 L15.6,7.9 Z M18.6,7.9 L17.1,7.9 L17.1,9.4 L18.6,9.4 L18.6,7.9 L18.6,7.9 Z M21.5,7.9 L20,7.9 L20,9.4 L21.5,9.4 L21.5,7.9 L21.5,7.9 Z M24.4,7.9 L23,7.9 L23,9.4 L24.5,9.4 L24.5,7.9 L24.4,7.9 Z M27.4,7.9 L25.9,7.9 L25.9,9.4 L27.4,9.4 L27.4,7.9 L27.4,7.9 Z M30.3,7.9 L28.8,7.9 L28.8,9.4 L30.3,9.4 L30.3,7.9 L30.3,7.9 Z M33.2,7.9 L31.7,7.9 L31.7,9.4 L33.2,9.4 L33.2,7.9 L33.2,7.9 Z M36.2,7.9 L34.7,7.9 L34.7,9.4 L36.2,9.4 L36.2,7.9 L36.2,7.9 Z M39.1,7.9 L37.6,7.9 L37.6,9.4 L39.1,9.4 L39.1,7.9 L39.1,7.9 Z M42,7.9 L40.5,7.9 L40.5,9.4 L42,9.4 L42,7.9 L42,7.9 Z M45,7.9 L43.5,7.9 L43.5,9.4 L45,9.4 L45,7.9 L45,7.9 Z M47.9,7.9 L46.4,7.9 L46.4,9.4 L47.9,9.4 L47.9,7.9 L47.9,7.9 Z M50.9,7.9 L49.4,7.9 L49.4,9.4 L50.9,9.4 L50.9,7.9 L50.9,7.9 Z M53.8,7.9 L52.3,7.9 L52.3,9.4 L53.8,9.4 L53.8,7.9 L53.8,7.9 Z M56.7,7.9 L55.2,7.9 L55.2,9.4 L56.7,9.4 L56.7,7.9 L56.7,7.9 Z M59.6,7.9 L58.1,7.9 L58.1,9.4 L59.6,9.4 L59.6,7.9 L59.6,7.9 Z M62.6,7.9 L61.1,7.9 L61.1,9.4 L62.6,9.4 L62.6,7.9 L62.6,7.9 Z M65.5,7.9 L64,7.9 L64,9.4 L65.5,9.4 L65.5,7.9 L65.5,7.9 Z M68.5,7.9 L67,7.9 L67,9.4 L68.5,9.4 L68.5,7.9 L68.5,7.9 Z" fill="#2E2E2E"></path>
-                    <path d="M64.3,0.3 L4.9,0.3 C2.5,0.3 0.5,2.4 0.5,5 C0.5,7.6 2.4,9.7 4.9,9.7 L64.3,9.7 C66.7,9.7 68.7,7.6 68.7,5 C68.7,2.4 66.7,0.3 64.3,0.3 L64.3,0.3 Z M63.9,8.2 L5.3,8.2 C3.5,8.2 2.1,6.8 2.1,5 C2.1,3.2 3.5,1.8 5.3,1.8 L63.9,1.8 C65.7,1.8 67.1,3.2 67.1,5 C67.1,6.8 65.7,8.2 63.9,8.2 L63.9,8.2 Z" fill="#000000" opacity="0.2"></path>
-                </g>
-            </g>
-            <rect id="Rectangle-path" x="28.5" y="114.7" width="320" height="568"></rect>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPhone6-landscape.svg b/front_end/emulated_devices/iPhone6-landscape.svg
deleted file mode 100644
index e31a3ad..0000000
--- a/front_end/emulated_devices/iPhone6-landscape.svg
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="877px" height="431px" viewBox="0 0 877 431" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPhone 6</title>
-    <defs>
-        <linearGradient x1="0.0488611431%" y1="49.9939431%" x2="100.048698%" y2="49.9939431%" id="linearGradient-1">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="11.69%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="87.64%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="4.88777959%" y1="-1.77197921%" x2="92.2732759%" y2="98.5008115%" id="linearGradient-2">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.05" offset="13.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.02" offset="88.31%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="49.8666667%" cy="50.0666667%" fx="49.8666667%" fy="50.0666667%" r="50.3333333%" id="radialGradient-3">
-            <stop stop-color="#5D5D5F" offset="0%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.2859018%" cy="57.2416319%" fx="50.2859018%" fy="57.2416319%" r="50.3093333%" id="radialGradient-4">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.3819749%" cy="96.2966269%" fx="47.3819749%" fy="96.2966269%" r="95.1905405%" id="radialGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.1335915%" cy="23.9526238%" fx="50.1335915%" fy="23.9526238%" r="58.1475%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="46.7389949%" y1="7.21719595%" x2="46.7408363%" y2="111.047196%" id="linearGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-8" d="M8.7,5.1 L8.7,63.7 C8.7,66.1 6.8,68 4.4,68 L4.4,68 C2,68 0.1,66.1 0.1,63.7 L0.1,5.1 C0.1,2.7 2,0.8 4.4,0.8 L4.4,0.8 C6.8,0.8 8.7,2.7 8.7,5.1 L8.7,5.1 Z"></path>
-        <linearGradient x1="100.754874%" y1="49.9921131%" x2="0.987588915%" y2="49.9921131%" id="linearGradient-10">
-            <stop stop-color="#2E2E31" offset="0%"></stop>
-            <stop stop-color="#616161" offset="24.48%"></stop>
-            <stop stop-color="#858585" offset="81.37%"></stop>
-            <stop stop-color="#2E2E31" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-11" d="M8.7,5.1 L8.7,63.7 C8.7,66.1 6.8,68 4.4,68 L4.4,68 C2,68 0.1,66.1 0.1,63.7 L0.1,5.1 C0.1,2.7 2,0.8 4.4,0.8 L4.4,0.8 C6.8,0.8 8.7,2.7 8.7,5.1 L8.7,5.1 Z"></path>
-        <path id="path-13" d="M8.7,5.1 L8.7,63.7 C8.7,66.1 6.8,68 4.4,68 L4.4,68 C2,68 0.1,66.1 0.1,63.7 L0.1,5.1 C0.1,2.7 2,0.8 4.4,0.8 L4.4,0.8 C6.8,0.8 8.7,2.7 8.7,5.1 L8.7,5.1 Z"></path>
-        <linearGradient x1="86.3832317%" y1="92.0344512%" x2="13.9727134%" y2="8.69390244%" id="linearGradient-15">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="iphone6-landscape">
-            <g id="Group">
-                <g>
-                    <path d="M145.2,424.8 L145.2,428.5 C145.2,429.5 144.4,430.4 143.3,430.4 L113.3,430.4 C112.3,430.4 111.4,429.6 111.4,428.5 L111.4,424.8 L145.2,424.8 L145.2,424.8 Z" id="Shape" fill="#808086"></path>
-                    <path d="M190.5,430.4 C189.5,430.4 188.6,429.6 188.6,428.5 L188.6,424.8 L249.7,424.8 L249.7,428.5 C249.7,429.5 248.9,430.4 247.8,430.4" id="Shape" fill="#808086"></path>
-                    <path d="M188,6.2 L188,2.5 C188,1.5 188.8,0.6 189.9,0.6 L247.3,0.6 C248.3,0.6 249.2,1.4 249.2,2.5 L249.2,6.2 L188,6.2 L188,6.2 Z" id="Shape" fill="#818187"></path>
-                    <path d="M329.5,424.8 L329.5,428.5 C329.5,429.5 328.7,430.4 327.6,430.4 L270.2,430.4 C269.2,430.4 268.3,429.6 268.3,428.5 L268.3,424.8 L329.5,424.8 L329.5,424.8 Z" id="Shape" fill="#808086"></path>
-                    <path d="M65.7,427.9 C29.9,427.9 0.8,398.8 0.8,363 L0.8,68.5 C0.8,32.7 29.9,3.6 65.7,3.6 L811.4,3.6 C847.2,3.6 876.3,32.7 876.3,68.5 L876.3,363 C876.3,398.8 847.2,427.9 811.4,427.9 L65.7,427.9 L65.7,427.9 Z" id="Shape" stroke="#666666" fill="#B2B2B2"></path>
-                    <path d="M871.1,363.2 C871.1,379.1 864.9,394.1 853.6,405.3 C842.4,416.5 827.4,422.8 811.5,422.8 L65.5,422.8 C49.6,422.8 34.6,416.6 23.4,405.3 C12.2,394.1 5.9,379.1 5.9,363.2 L5.9,68.4 C5.9,52.5 12.1,37.5 23.4,26.3 C34.6,15 49.6,8.8 65.5,8.8 L811.5,8.8 C827.4,8.8 842.4,15 853.6,26.3 C864.8,37.5 871.1,52.5 871.1,68.4 L871.1,363.2 L871.1,363.2 L871.1,363.2 Z" id="Shape" fill="#404040"></path>
-                    <path d="M871.3,68.5 L871.3,363 C871.3,396.1 844.5,422.9 811.4,422.9 L65.7,422.9 C32.6,422.9 5.8,396.1 5.8,363 L5.8,68.5 C5.8,35.4 32.6,8.6 65.7,8.6 L811.4,8.6 C844.4,8.6 871.3,35.4 871.3,68.5 L871.3,68.5 Z" id="Shape" fill="#262626"></path>
-                    <path d="M5.7,68.4 L5.7,363.2 C5.7,396.2 32.5,423 65.5,423 L67.1,423 C34.1,423 7.3,396.2 7.3,363.2 L7.3,68.4 C7.3,35.4 34.1,8.6 67.1,8.6 L65.5,8.6 C32.5,8.6 5.7,35.4 5.7,68.4 L5.7,68.4 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                    <path d="M9.3,68.4 L9.3,363.2 C9.3,394.2 34.5,419.4 65.5,419.4 L811.5,419.4 C842.5,419.4 867.7,394.2 867.7,363.2 L867.7,68.4 C867.7,37.4 842.5,12.2 811.5,12.2 L65.5,12.2 C34.5,12.1 9.3,37.4 9.3,68.4 L9.3,68.4 Z M811.5,18.2 C839.2,18.2 861.7,40.7 861.7,68.4 L861.7,363.2 C861.7,390.9 839.2,413.4 811.5,413.4 L65.5,413.4 C37.8,413.4 15.3,390.9 15.3,363.2 L15.3,68.4 C15.3,40.7 37.8,18.2 65.5,18.2 L811.5,18.2 L811.5,18.2 Z" id="Shape" fill="url(#linearGradient-2)"></path>
-                    <g transform="translate(47.000000, 276.000000)">
-                        <circle id="Oval" fill="url(#radialGradient-3)" cx="7.7" cy="7.7" r="7.5"></circle>
-                        <circle id="Oval" fill="url(#radialGradient-4)" opacity="0.8" cx="7.7" cy="7.7" r="7.5"></circle>
-                        <circle id="Oval" fill="#1B1A1F" cx="7.7" cy="7.7" r="5"></circle>
-                        <circle id="Oval" fill="#36284C" cx="7.7" cy="7.7" r="3.7"></circle>
-                        <circle id="Oval" fill="url(#radialGradient-5)" cx="7.7" cy="7.7" r="3.7"></circle>
-                        <g transform="translate(5.000000, 5.000000)" id="Shape">
-                            <path d="M4.7,2.7 C4.7,3.8 3.8,4.7 2.7,4.7 C1.6,4.7 0.7,3.8 0.7,2.7 C0.7,1.6 1.6,0.7 2.7,0.7 C3.8,0.7 4.7,1.6 4.7,2.7 L4.7,2.7 Z" fill="#141414" opacity="0.5"></path>
-                            <path d="M4.7,2.7 C4.7,3.8 3.8,4.7 2.7,4.7 C1.6,4.7 0.7,3.8 0.7,2.7 C0.7,1.6 1.6,0.7 2.7,0.7 C3.8,0.7 4.7,1.6 4.7,2.7 L4.7,2.7 Z" fill="url(#radialGradient-6)"></path>
-                        </g>
-                        <path d="M7.7,6.2 C7.2,6.2 6.9,6.4 6.6,6.7 L7.1,7.2 C7.3,7 7.5,6.9 7.7,6.9 C8,6.9 8.2,7 8.4,7.2 L8.9,6.7 C8.5,6.4 8.1,6.2 7.7,6.2 L7.7,6.2 Z" id="Shape" fill="url(#linearGradient-7)"></path>
-                    </g>
-                    <g transform="translate(51.000000, 181.000000)" id="Clipped">
-                        <g>
-                            <mask id="mask-9" fill="white">
-                                <use xlink:href="#path-8"></use>
-                            </mask>
-                            <g id="SVGID_8_"></g>
-                            <path d="M8.7,5.1 L8.7,63.7 C8.7,66.1 6.8,68 4.4,68 L4.4,68 C2,68 0.1,66.1 0.1,63.7 L0.1,5.1 C0.1,2.7 2,0.8 4.4,0.8 L4.4,0.8 C6.8,0.8 8.7,2.7 8.7,5.1 L8.7,5.1 Z" id="Shape" fill="url(#linearGradient-10)" opacity="0.8" mask="url(#mask-9)"></path>
-                        </g>
-                        <g>
-                            <mask id="mask-12" fill="white">
-                                <use xlink:href="#path-11"></use>
-                            </mask>
-                            <g id="SVGID_11_"></g>
-                            <path d="M-0.2,4.7 L-0.2,64.1 C-0.2,66.5 1.9,68.5 4.5,68.5 C7.1,68.5 9.1,66.6 9.1,64.1 L9.1,4.7 C9.1,2.3 7,0.3 4.4,0.3 C1.8,0.3 -0.2,2.3 -0.2,4.7 L-0.2,4.7 Z M7.6,5.1 L7.6,63.7 C7.6,65.5 6.2,66.9 4.4,66.9 C2.6,66.9 1.2,65.5 1.2,63.7 L1.2,5.1 C1.2,3.3 2.6,1.9 4.4,1.9 C6.2,1.9 7.6,3.3 7.6,5.1 L7.6,5.1 Z" id="Shape" fill="#000000" opacity="0.2" mask="url(#mask-12)"></path>
-                        </g>
-                        <g>
-                            <mask id="mask-14" fill="white">
-                                <use xlink:href="#path-13"></use>
-                            </mask>
-                            <g id="SVGID_13_"></g>
-                            <path d="M0,66.7 L0,68.2 L1.5,68.2 L1.5,66.7 L0,66.7 L0,66.7 Z M0,63.8 L0,65.3 L1.5,65.3 L1.5,63.8 L0,63.8 L0,63.8 Z M0,60.8 L0,62.3 L1.5,62.3 L1.5,60.8 L0,60.8 L0,60.8 Z M0,57.9 L0,59.4 L1.5,59.4 L1.5,57.9 L0,57.9 L0,57.9 Z M0,54.9 L0,56.4 L1.5,56.4 L1.5,54.9 L0,54.9 L0,54.9 Z M0,52 L0,53.5 L1.5,53.5 L1.5,52 L0,52 L0,52 Z M0,49.1 L0,50.6 L1.5,50.6 L1.5,49.1 L0,49.1 L0,49.1 Z M0,46.1 L0,47.6 L1.5,47.6 L1.5,46.1 L0,46.1 L0,46.1 Z M0,43.2 L0,44.7 L1.5,44.7 L1.5,43.2 L0,43.2 L0,43.2 Z M0,40.3 L0,41.8 L1.5,41.8 L1.5,40.3 L0,40.3 L0,40.3 Z M0,37.3 L0,38.8 L1.5,38.8 L1.5,37.3 L0,37.3 L0,37.3 Z M0,34.4 L0,35.9 L1.5,35.9 L1.5,34.4 L0,34.4 L0,34.4 Z M0,31.5 L0,33 L1.5,33 L1.5,31.5 L0,31.5 L0,31.5 Z M0,28.5 L0,30 L1.5,30 L1.5,28.5 L0,28.5 L0,28.5 Z M0,25.6 L0,27.1 L1.5,27.1 L1.5,25.6 L0,25.6 L0,25.6 Z M0,22.6 L0,24.1 L1.5,24.1 L1.5,22.6 L0,22.6 L0,22.6 Z M0,19.7 L0,21.2 L1.5,21.2 L1.5,19.7 L0,19.7 L0,19.7 Z M0,16.8 L0,18.3 L1.5,18.3 L1.5,16.8 L0,16.8 L0,16.8 Z M0,13.9 L0,15.4 L1.5,15.4 L1.5,13.9 L0,13.9 L0,13.9 Z M0,10.9 L0,12.4 L1.5,12.4 L1.5,10.9 L0,10.9 L0,10.9 Z M0,8 L0,9.5 L1.5,9.5 L1.5,8 L0,8 L0,8 Z M0,5 L0,6.5 L1.5,6.5 L1.5,5 L0,5 L0,5 Z M0,2.1 L0,3.6 L1.5,3.6 L1.5,2.1 L0,2.1 L0,2.1 Z M1.5,65.2 L1.5,66.7 L3,66.7 L3,65.2 L1.5,65.2 L1.5,65.2 Z M1.5,62.3 L1.5,63.8 L3,63.8 L3,62.3 L1.5,62.3 L1.5,62.3 Z M1.5,59.3 L1.5,60.8 L3,60.8 L3,59.3 L1.5,59.3 L1.5,59.3 Z M1.5,56.4 L1.5,57.9 L3,57.9 L3,56.4 L1.5,56.4 L1.5,56.4 Z M1.5,53.5 L1.5,55 L3,55 L3,53.5 L1.5,53.5 L1.5,53.5 Z M1.5,50.5 L1.5,52 L3,52 L3,50.5 L1.5,50.5 L1.5,50.5 L1.5,50.5 Z M1.5,47.6 L1.5,49.1 L3,49.1 L3,47.6 L1.5,47.6 L1.5,47.6 Z M1.5,44.7 L1.5,46.2 L3,46.2 L3,44.7 L1.5,44.7 L1.5,44.7 Z M1.5,41.7 L1.5,43.2 L3,43.2 L3,41.7 L1.5,41.7 L1.5,41.7 Z M1.5,38.8 L1.5,40.3 L3,40.3 L3,38.8 L1.5,38.8 L1.5,38.8 Z M1.5,35.9 L1.5,37.4 L3,37.4 L3,35.9 L1.5,35.9 L1.5,35.9 Z M1.5,32.9 L1.5,34.4 L3,34.4 L3,32.9 L1.5,32.9 L1.5,32.9 Z M1.5,30 L1.5,31.5 L3,31.5 L3,30 L1.5,30 L1.5,30 Z M1.5,27.1 L1.5,28.6 L3,28.6 L3,27.1 L1.5,27.1 L1.5,27.1 Z M1.5,24.1 L1.5,25.6 L3,25.6 L3,24.1 L1.5,24.1 L1.5,24.1 Z M1.5,21.2 L1.5,22.7 L3,22.7 L3,21.2 L1.5,21.2 L1.5,21.2 Z M1.5,18.2 L1.5,19.7 L3,19.7 L3,18.2 L1.5,18.2 L1.5,18.2 Z M1.5,15.3 L1.5,16.8 L3,16.8 L3,15.3 L1.5,15.3 L1.5,15.3 Z M1.5,12.4 L1.5,13.9 L3,13.9 L3,12.4 L1.5,12.4 L1.5,12.4 Z M1.5,9.4 L1.5,10.9 L3,10.9 L3,9.4 L1.5,9.4 L1.5,9.4 Z M1.5,6.5 L1.5,8 L3,8 L3,6.5 L1.5,6.5 L1.5,6.5 Z M1.5,3.6 L1.5,5.1 L3,5.1 L3,3.6 L1.5,3.6 L1.5,3.6 Z M1.5,0.6 L1.5,2.1 L3,2.1 L3,0.6 L1.5,0.6 L1.5,0.6 Z M3,66.7 L3,68.2 L4.5,68.2 L4.5,66.7 L3,66.7 L3,66.7 Z M3,63.8 L3,65.3 L4.5,65.3 L4.5,63.8 L3,63.8 L3,63.8 Z M3,60.8 L3,62.3 L4.5,62.3 L4.5,60.8 L3,60.8 L3,60.8 Z M3,57.9 L3,59.4 L4.5,59.4 L4.5,57.9 L3,57.9 L3,57.9 Z M3,54.9 L3,56.4 L4.5,56.4 L4.5,54.9 L3,54.9 L3,54.9 Z M3,52 L3,53.5 L4.5,53.5 L4.5,52 L3,52 L3,52 Z M3,49.1 L3,50.6 L4.5,50.6 L4.5,49.1 L3,49.1 L3,49.1 Z M3,46.1 L3,47.6 L4.5,47.6 L4.5,46.1 L3,46.1 L3,46.1 Z M3,43.2 L3,44.7 L4.5,44.7 L4.5,43.2 L3,43.2 L3,43.2 Z M3,40.3 L3,41.8 L4.5,41.8 L4.5,40.3 L3,40.3 L3,40.3 Z M3,37.3 L3,38.8 L4.5,38.8 L4.5,37.3 L3,37.3 L3,37.3 Z M3,34.4 L3,35.9 L4.5,35.9 L4.5,34.4 L3,34.4 L3,34.4 Z M3,31.5 L3,33 L4.5,33 L4.5,31.5 L3,31.5 L3,31.5 Z M3,28.5 L3,30 L4.5,30 L4.5,28.5 L3,28.5 L3,28.5 Z M3,25.6 L3,27.1 L4.5,27.1 L4.5,25.6 L3,25.6 L3,25.6 Z M3,22.6 L3,24.1 L4.5,24.1 L4.5,22.6 L3,22.6 L3,22.6 Z M3,19.7 L3,21.2 L4.5,21.2 L4.5,19.7 L3,19.7 L3,19.7 Z M3,16.8 L3,18.3 L4.5,18.3 L4.5,16.8 L3,16.8 L3,16.8 Z M3,13.9 L3,15.4 L4.5,15.4 L4.5,13.9 L3,13.9 L3,13.9 Z M3,10.9 L3,12.4 L4.5,12.4 L4.5,10.9 L3,10.9 L3,10.9 Z M3,8 L3,9.5 L4.5,9.5 L4.5,8 L3,8 L3,8 Z M3,5 L3,6.5 L4.5,6.5 L4.5,5 L3,5 L3,5 Z M3,2.1 L3,3.6 L4.5,3.6 L4.5,2.1 L3,2.1 L3,2.1 Z M4.4,65.2 L4.4,66.7 L5.9,66.7 L5.9,65.2 L4.4,65.2 L4.4,65.2 Z M4.4,62.3 L4.4,63.8 L5.9,63.8 L5.9,62.3 L4.4,62.3 L4.4,62.3 Z M4.4,59.3 L4.4,60.8 L5.9,60.8 L5.9,59.3 L4.4,59.3 L4.4,59.3 Z M4.4,56.4 L4.4,57.9 L5.9,57.9 L5.9,56.4 L4.4,56.4 L4.4,56.4 Z M4.4,53.5 L4.4,55 L5.9,55 L5.9,53.5 L4.4,53.5 L4.4,53.5 Z M4.4,50.5 L4.4,52 L5.9,52 L5.9,50.5 L4.4,50.5 L4.4,50.5 L4.4,50.5 Z M4.4,47.6 L4.4,49.1 L5.9,49.1 L5.9,47.6 L4.4,47.6 L4.4,47.6 Z M4.4,44.7 L4.4,46.2 L5.9,46.2 L5.9,44.7 L4.4,44.7 L4.4,44.7 Z M4.4,41.7 L4.4,43.2 L5.9,43.2 L5.9,41.7 L4.4,41.7 L4.4,41.7 Z M4.4,38.8 L4.4,40.3 L5.9,40.3 L5.9,38.8 L4.4,38.8 L4.4,38.8 Z M4.4,35.9 L4.4,37.4 L5.9,37.4 L5.9,35.9 L4.4,35.9 L4.4,35.9 Z M4.4,32.9 L4.4,34.4 L5.9,34.4 L5.9,32.9 L4.4,32.9 L4.4,32.9 Z M4.4,30 L4.4,31.5 L5.9,31.5 L5.9,30 L4.4,30 L4.4,30 Z M4.4,27.1 L4.4,28.6 L5.9,28.6 L5.9,27.1 L4.4,27.1 L4.4,27.1 Z M4.4,24.1 L4.4,25.6 L5.9,25.6 L5.9,24.1 L4.4,24.1 L4.4,24.1 Z M4.4,21.2 L4.4,22.7 L5.9,22.7 L5.9,21.2 L4.4,21.2 L4.4,21.2 Z M4.4,18.2 L4.4,19.7 L5.9,19.7 L5.9,18.2 L4.4,18.2 L4.4,18.2 Z M4.4,15.3 L4.4,16.8 L5.9,16.8 L5.9,15.3 L4.4,15.3 L4.4,15.3 Z M4.4,12.4 L4.4,13.9 L5.9,13.9 L5.9,12.4 L4.4,12.4 L4.4,12.4 Z M4.4,9.4 L4.4,10.9 L5.9,10.9 L5.9,9.4 L4.4,9.4 L4.4,9.4 Z M4.4,6.5 L4.4,8 L5.9,8 L5.9,6.5 L4.4,6.5 L4.4,6.5 Z M4.4,3.6 L4.4,5.1 L5.9,5.1 L5.9,3.6 L4.4,3.6 L4.4,3.6 Z M4.4,0.6 L4.4,2.1 L5.9,2.1 L5.9,0.6 L4.4,0.6 L4.4,0.6 Z M5.9,66.7 L5.9,68.2 L7.4,68.2 L7.4,66.7 L5.9,66.7 L5.9,66.7 Z M5.9,63.8 L5.9,65.3 L7.4,65.3 L7.4,63.8 L5.9,63.8 L5.9,63.8 Z M5.9,60.8 L5.9,62.3 L7.4,62.3 L7.4,60.8 L5.9,60.8 L5.9,60.8 Z M5.9,57.9 L5.9,59.4 L7.4,59.4 L7.4,57.9 L5.9,57.9 L5.9,57.9 Z M5.9,54.9 L5.9,56.4 L7.4,56.4 L7.4,54.9 L5.9,54.9 L5.9,54.9 Z M5.9,52 L5.9,53.5 L7.4,53.5 L7.4,52 L5.9,52 L5.9,52 Z M5.9,49.1 L5.9,50.6 L7.4,50.6 L7.4,49.1 L5.9,49.1 L5.9,49.1 Z M5.9,46.1 L5.9,47.6 L7.4,47.6 L7.4,46.1 L5.9,46.1 L5.9,46.1 Z M5.9,43.2 L5.9,44.7 L7.4,44.7 L7.4,43.2 L5.9,43.2 L5.9,43.2 Z M5.9,40.3 L5.9,41.8 L7.4,41.8 L7.4,40.3 L5.9,40.3 L5.9,40.3 Z M5.9,37.3 L5.9,38.8 L7.4,38.8 L7.4,37.3 L5.9,37.3 L5.9,37.3 Z M5.9,34.4 L5.9,35.9 L7.4,35.9 L7.4,34.4 L5.9,34.4 L5.9,34.4 Z M5.9,31.5 L5.9,33 L7.4,33 L7.4,31.5 L5.9,31.5 L5.9,31.5 Z M5.9,28.5 L5.9,30 L7.4,30 L7.4,28.5 L5.9,28.5 L5.9,28.5 Z M5.9,25.6 L5.9,27.1 L7.4,27.1 L7.4,25.6 L5.9,25.6 L5.9,25.6 Z M5.9,22.6 L5.9,24.1 L7.4,24.1 L7.4,22.6 L5.9,22.6 L5.9,22.6 Z M5.9,19.7 L5.9,21.2 L7.4,21.2 L7.4,19.7 L5.9,19.7 L5.9,19.7 Z M5.9,16.8 L5.9,18.3 L7.4,18.3 L7.4,16.8 L5.9,16.8 L5.9,16.8 Z M5.9,13.9 L5.9,15.4 L7.4,15.4 L7.4,13.9 L5.9,13.9 L5.9,13.9 Z M5.9,10.9 L5.9,12.4 L7.4,12.4 L7.4,10.9 L5.9,10.9 L5.9,10.9 Z M5.9,8 L5.9,9.5 L7.4,9.5 L7.4,8 L5.9,8 L5.9,8 Z M5.9,5 L5.9,6.5 L7.4,6.5 L7.4,5 L5.9,5 L5.9,5 Z M5.9,2.1 L5.9,3.6 L7.4,3.6 L7.4,2.1 L5.9,2.1 L5.9,2.1 Z M7.3,65.2 L7.3,66.7 L8.8,66.7 L8.8,65.2 L7.3,65.2 L7.3,65.2 Z M7.3,62.3 L7.3,63.8 L8.8,63.8 L8.8,62.3 L7.3,62.3 L7.3,62.3 Z M7.3,59.3 L7.3,60.8 L8.8,60.8 L8.8,59.3 L7.3,59.3 L7.3,59.3 Z M7.3,56.4 L7.3,57.9 L8.8,57.9 L8.8,56.4 L7.3,56.4 L7.3,56.4 Z M7.3,53.5 L7.3,55 L8.8,55 L8.8,53.5 L7.3,53.5 L7.3,53.5 Z M7.3,50.5 L7.3,52 L8.8,52 L8.8,50.5 L7.3,50.5 L7.3,50.5 L7.3,50.5 Z M7.3,47.6 L7.3,49.1 L8.8,49.1 L8.8,47.6 L7.3,47.6 L7.3,47.6 Z M7.3,44.7 L7.3,46.2 L8.8,46.2 L8.8,44.7 L7.3,44.7 L7.3,44.7 Z M7.3,41.7 L7.3,43.2 L8.8,43.2 L8.8,41.7 L7.3,41.7 L7.3,41.7 Z M7.3,38.8 L7.3,40.3 L8.8,40.3 L8.8,38.8 L7.3,38.8 L7.3,38.8 Z M7.3,35.9 L7.3,37.4 L8.8,37.4 L8.8,35.9 L7.3,35.9 L7.3,35.9 Z M7.3,32.9 L7.3,34.4 L8.8,34.4 L8.8,32.9 L7.3,32.9 L7.3,32.9 Z M7.3,30 L7.3,31.5 L8.8,31.5 L8.8,30 L7.3,30 L7.3,30 Z M7.3,27.1 L7.3,28.6 L8.8,28.6 L8.8,27.1 L7.3,27.1 L7.3,27.1 Z M7.3,24.1 L7.3,25.6 L8.8,25.6 L8.8,24.1 L7.3,24.1 L7.3,24.1 Z M7.3,21.2 L7.3,22.7 L8.8,22.7 L8.8,21.2 L7.3,21.2 L7.3,21.2 Z M7.3,18.2 L7.3,19.7 L8.8,19.7 L8.8,18.2 L7.3,18.2 L7.3,18.2 Z M7.3,15.3 L7.3,16.8 L8.8,16.8 L8.8,15.3 L7.3,15.3 L7.3,15.3 Z M7.3,12.4 L7.3,13.9 L8.8,13.9 L8.8,12.4 L7.3,12.4 L7.3,12.4 Z M7.3,9.4 L7.3,10.9 L8.8,10.9 L8.8,9.4 L7.3,9.4 L7.3,9.4 Z M7.3,6.5 L7.3,8 L8.8,8 L8.8,6.5 L7.3,6.5 L7.3,6.5 Z M7.3,3.6 L7.3,5.1 L8.8,5.1 L8.8,3.6 L7.3,3.6 L7.3,3.6 Z M7.3,0.6 L7.3,2.1 L8.8,2.1 L8.8,0.6 L7.3,0.6 L7.3,0.6 Z" id="Shape" fill="#2E2E2E" mask="url(#mask-14)"></path>
-                        </g>
-                    </g>
-                    <path d="M820.9,182.9 C802.8,182.9 788.1,197.6 788.1,215.7 C788.1,233.8 802.8,248.5 820.9,248.5 C839,248.5 853.7,233.8 853.7,215.7 C853.7,197.6 839,182.9 820.9,182.9 L820.9,182.9 Z M820.9,245.6 C804.4,245.6 791.1,232.2 791.1,215.8 C791.1,199.4 804.4,186 820.9,186 C837.4,186 850.7,199.4 850.7,215.8 C850.7,232.2 837.3,245.6 820.9,245.6 L820.9,245.6 Z" id="Shape" fill="url(#linearGradient-15)"></path>
-                </g>
-                <rect id="Rectangle-path" fill="#000000" x="106" y="28" width="667" height="375"></rect>
-            </g>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPhone6-portrait.svg b/front_end/emulated_devices/iPhone6-portrait.svg
deleted file mode 100644
index 581c334..0000000
--- a/front_end/emulated_devices/iPhone6-portrait.svg
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="431px" height="877px" viewBox="0 0 431 877" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPhone 6</title>
-    <defs>
-        <linearGradient x1="49.9843147%" y1="-0.0652528548%" x2="49.9843147%" y2="100.081566%" id="linearGradient-1">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="11.69%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="87.64%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="-28.7505648%" y1="28.4302458%" x2="128.768345%" y2="71.576267%" id="linearGradient-2">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.05" offset="13.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.02" offset="88.31%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="50.0657895%" cy="50%" fx="50.0657895%" fy="50%" r="49.6710526%" id="radialGradient-3">
-            <stop stop-color="#5D5D5F" offset="0%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.5113431%" cy="57.0965797%" fx="50.5113431%" fy="57.0965797%" r="49.6414474%" id="radialGradient-4">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.8584278%" cy="96.1408161%" fx="47.8584278%" fy="96.1408161%" r="95.1797297%" id="radialGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="51.01503%" cy="23.676875%" fx="51.01503%" fy="23.676875%" r="58.14%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="48.2624993%" y1="6.12081973%" x2="48.2643405%" y2="109.94082%" id="linearGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-8" d="M63.8,8.9 L5.2,8.9 C2.8,8.9 0.9,7 0.9,4.6 L0.9,4.6 C0.9,2.2 2.8,0.3 5.2,0.3 L63.8,0.3 C66.2,0.3 68.1,2.2 68.1,4.6 L68.1,4.6 C68.1,7 66.2,8.9 63.8,8.9 L63.8,8.9 Z"></path>
-        <linearGradient x1="50.0297245%" y1="100.349273%" x2="50.0297245%" y2="0.581987558%" id="linearGradient-10">
-            <stop stop-color="#2E2E31" offset="0%"></stop>
-            <stop stop-color="#616161" offset="24.48%"></stop>
-            <stop stop-color="#858585" offset="81.37%"></stop>
-            <stop stop-color="#2E2E31" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-11" d="M63.8,8.9 L5.2,8.9 C2.8,8.9 0.9,7 0.9,4.6 L0.9,4.6 C0.9,2.2 2.8,0.3 5.2,0.3 L63.8,0.3 C66.2,0.3 68.1,2.2 68.1,4.6 L68.1,4.6 C68.1,7 66.2,8.9 63.8,8.9 L63.8,8.9 Z"></path>
-        <path id="path-13" d="M63.8,8.9 L5.2,8.9 C2.8,8.9 0.9,7 0.9,4.6 L0.9,4.6 C0.9,2.2 2.8,0.3 5.2,0.3 L63.8,0.3 C66.2,0.3 68.1,2.2 68.1,4.6 L68.1,4.6 C68.1,7 66.2,8.9 63.8,8.9 L63.8,8.9 Z"></path>
-        <linearGradient x1="86.3503805%" y1="91.9339939%" x2="14.0585997%" y2="8.60320122%" id="linearGradient-15">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="-34.1719072%" y1="-2.09287997%" x2="28.847616%" y2="36.9142223%" id="linearGradient-16">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="iphone6-portrait" transform="translate(0.000000, 1.000000)">
-            <g id="Group">
-                <path d="M6,144.5 L2.2,144.5 C1.2,144.5 0.3,143.7 0.3,142.6 L0.3,112.6 C0.3,111.6 1.1,110.7 2.2,110.7 L6,110.7 L6,144.5 L6,144.5 Z" id="Shape" fill="#808086"></path>
-                <path d="M0.6,189.7 C0.6,188.7 1.4,187.8 2.5,187.8 L6.2,187.8 L6.2,249 L2.4,249 C1.4,249 0.5,248.2 0.5,247.1" id="Shape" fill="#808086"></path>
-                <path d="M424.7,187.2 L428.4,187.2 C429.4,187.2 430.3,188 430.3,189.1 L430.3,246.5 C430.3,247.5 429.5,248.4 428.4,248.4 L424.7,248.4 L424.7,187.2 L424.7,187.2 Z" id="Shape" fill="#818187"></path>
-                <path d="M6.2,328.7 L2.4,328.7 C1.4,328.7 0.5,327.9 0.5,326.8 L0.5,269.4 C0.5,268.4 1.3,267.5 2.4,267.5 L6.1,267.5 L6.1,328.7 L6.2,328.7 Z" id="Shape" fill="#808086"></path>
-                <path d="M67.7,870.2 C51.8,870.2 36.8,864 25.6,852.7 C14.4,841.4 8.1,826.5 8.1,810.6 L8.1,64.7 C8.1,48.8 14.3,33.8 25.6,22.6 C36.9,11.4 51.8,5.1 67.7,5.1 L362.5,5.1 C378.4,5.1 393.4,11.3 404.6,22.6 C415.8,33.9 422.1,48.8 422.1,64.7 L422.1,810.6 C422.1,826.5 415.9,841.5 404.6,852.7 C393.3,863.9 378.4,870.2 362.5,870.2 L67.7,870.2 L67.7,870.2 L67.7,870.2 Z" id="Shape" fill="#404040"></path>
-                <g transform="translate(3.000000, 0.000000)" id="Shape">
-                    <path d="M64.9,875.4 C29.1,875.4 0,846.3 0,810.5 L0,64.9 C0,29.1 29.1,0 64.9,0 L359.3,0 C395.1,0 424.2,29.1 424.2,64.9 L424.2,810.5 C424.2,846.3 395.1,875.4 359.3,875.4 L64.9,875.4 L64.9,875.4 L64.9,875.4 Z" stroke-opacity="0.5" stroke="#666666" fill="#B2B2B2"></path>
-                    <path d="M359.4,870.4 L64.9,870.4 C31.8,870.4 5,843.6 5,810.5 L5,64.9 C5,31.8 31.8,5 64.9,5 L359.3,5 C392.4,5 419.2,31.8 419.2,64.9 L419.2,810.5 C419.3,843.6 392.5,870.4 359.4,870.4 L359.4,870.4 Z" fill="#262626"></path>
-                </g>
-                <path d="M362.5,5 L67.7,5 C34.7,5 8,31.7 8,64.7 L8,66.3 C8,33.3 34.8,6.5 67.8,6.5 L362.6,6.5 C395.6,6.5 422.4,33.3 422.4,66.3 L422.4,64.7 C422.3,31.7 395.5,5 362.5,5 L362.5,5 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                <path d="M362.5,8.5 L67.7,8.5 C36.7,8.5 11.5,33.7 11.5,64.7 L11.5,810.6 C11.5,841.6 36.7,866.8 67.7,866.8 L362.5,866.8 C393.5,866.8 418.7,841.6 418.7,810.6 L418.7,64.7 C418.7,33.7 393.5,8.5 362.5,8.5 L362.5,8.5 Z M412.7,810.7 C412.7,838.4 390.2,860.9 362.5,860.9 L67.7,860.9 C40,860.9 17.5,838.4 17.5,810.7 L17.5,64.7 C17.5,37 40,14.5 67.7,14.5 L362.5,14.5 C390.2,14.5 412.7,37 412.7,64.7 L412.7,810.7 L412.7,810.7 Z" id="Shape" fill="url(#linearGradient-2)"></path>
-                <g transform="translate(139.000000, 46.000000)">
-                    <circle id="Oval" fill="url(#radialGradient-3)" cx="8.2" cy="7.9" r="7.6"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-4)" opacity="0.8" cx="8.2" cy="7.9" r="7.6"></circle>
-                    <circle id="Oval" fill="#1B1A1F" cx="8.2" cy="7.9" r="5"></circle>
-                    <circle id="Oval" fill="#36284C" cx="8.2" cy="7.9" r="3.7"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-5)" cx="8.2" cy="7.9" r="3.7"></circle>
-                    <g transform="translate(6.000000, 5.000000)" id="Shape">
-                        <path d="M4.2,2.9 C4.2,4 3.3,4.9 2.2,4.9 C1.1,4.9 0.2,4 0.2,2.9 C0.2,1.8 1.1,0.9 2.2,0.9 C3.3,0.9 4.2,1.8 4.2,2.9 L4.2,2.9 Z" fill="#141414" opacity="0.5"></path>
-                        <path d="M4.2,2.9 C4.2,4 3.3,4.9 2.2,4.9 C1.1,4.9 0.2,4 0.2,2.9 C0.2,1.8 1.1,0.9 2.2,0.9 C3.3,0.9 4.2,1.8 4.2,2.9 L4.2,2.9 Z" fill="url(#radialGradient-6)"></path>
-                    </g>
-                    <path d="M8.2,6.4 C7.8,6.4 7.4,6.6 7.1,6.9 L7.6,7.4 C7.8,7.2 8,7.1 8.2,7.1 C8.5,7.1 8.7,7.2 8.9,7.4 L9.4,6.9 C9.1,6.6 8.7,6.4 8.2,6.4 L8.2,6.4 Z" id="Shape" fill="url(#linearGradient-7)"></path>
-                </g>
-                <g transform="translate(181.000000, 50.000000)" id="Clipped">
-                    <g>
-                        <mask id="mask-9" fill="white">
-                            <use xlink:href="#path-8"></use>
-                        </mask>
-                        <g id="SVGID_8_"></g>
-                        <path d="M63.8,8.9 L5.2,8.9 C2.8,8.9 0.9,7 0.9,4.6 L0.9,4.6 C0.9,2.2 2.8,0.3 5.2,0.3 L63.8,0.3 C66.2,0.3 68.1,2.2 68.1,4.6 L68.1,4.6 C68.1,7 66.2,8.9 63.8,8.9 L63.8,8.9 Z" id="Shape" fill="url(#linearGradient-10)" opacity="0.8" mask="url(#mask-9)"></path>
-                    </g>
-                    <g>
-                        <mask id="mask-12" fill="white">
-                            <use xlink:href="#path-11"></use>
-                        </mask>
-                        <g id="SVGID_11_"></g>
-                        <path d="M2.3,0.2 L0.8,0.2 L0.8,1.7 L2.3,1.7 L2.3,0.2 L2.3,0.2 Z M5.3,0.2 L3.8,0.2 L3.8,1.7 L5.3,1.7 L5.3,0.2 L5.3,0.2 Z M8.2,0.2 L6.7,0.2 L6.7,1.7 L8.2,1.7 L8.2,0.2 L8.2,0.2 Z M11.1,0.2 L9.6,0.2 L9.6,1.7 L11.1,1.7 L11.1,0.2 L11.1,0.2 Z M14.1,0.2 L12.6,0.2 L12.6,1.7 L14.1,1.7 L14.1,0.2 L14.1,0.2 Z M17,0.2 L15.5,0.2 L15.5,1.7 L17,1.7 L17,0.2 L17,0.2 Z M19.9,0.2 L18.4,0.2 L18.4,1.7 L19.9,1.7 L19.9,0.2 L19.9,0.2 Z M22.9,0.2 L21.4,0.2 L21.4,1.7 L22.9,1.7 L22.9,0.2 L22.9,0.2 Z M25.8,0.2 L24.3,0.2 L24.3,1.7 L25.8,1.7 L25.8,0.2 L25.8,0.2 Z M28.8,0.2 L27.3,0.2 L27.3,1.7 L28.8,1.7 L28.8,0.2 L28.8,0.2 Z M31.7,0.2 L30.2,0.2 L30.2,1.7 L31.7,1.7 L31.7,0.2 L31.7,0.2 Z M34.6,0.2 L33.1,0.2 L33.1,1.7 L34.6,1.7 L34.6,0.2 L34.6,0.2 Z M37.6,0.2 L36.1,0.2 L36.1,1.7 L37.6,1.7 L37.6,0.2 L37.6,0.2 Z M40.5,0.2 L39,0.2 L39,1.7 L40.5,1.7 L40.5,0.2 L40.5,0.2 Z M43.4,0.2 L41.9,0.2 L41.9,1.7 L43.4,1.7 L43.4,0.2 L43.4,0.2 Z M46.4,0.2 L44.9,0.2 L44.9,1.7 L46.4,1.7 L46.4,0.2 L46.4,0.2 Z M49.3,0.2 L47.8,0.2 L47.8,1.7 L49.3,1.7 L49.3,0.2 L49.3,0.2 Z M52.2,0.2 L50.7,0.2 L50.7,1.7 L52.2,1.7 L52.2,0.2 L52.2,0.2 Z M55.2,0.2 L53.7,0.2 L53.7,1.7 L55.2,1.7 L55.2,0.2 L55.2,0.2 Z M58.1,0.2 L56.6,0.2 L56.6,1.7 L58.1,1.7 L58.1,0.2 L58.1,0.2 Z M61,0.2 L59.5,0.2 L59.5,1.7 L61,1.7 L61,0.2 L61,0.2 Z M64,0.2 L62.5,0.2 L62.5,1.7 L64,1.7 L64,0.2 L64,0.2 Z M66.9,0.2 L65.4,0.2 L65.4,1.7 L66.9,1.7 L66.9,0.2 L66.9,0.2 Z M3.8,1.7 L2.3,1.7 L2.3,3.2 L3.8,3.2 L3.8,1.7 L3.8,1.7 Z M6.7,1.7 L5.2,1.7 L5.2,3.2 L6.7,3.2 L6.7,1.7 L6.7,1.7 Z M9.7,1.7 L8.2,1.7 L8.2,3.2 L9.7,3.2 L9.7,1.7 L9.7,1.7 Z M12.6,1.7 L11.1,1.7 L11.1,3.2 L12.6,3.2 L12.6,1.7 L12.6,1.7 Z M15.5,1.7 L14,1.7 L14,3.2 L15.5,3.2 L15.5,1.7 L15.5,1.7 Z M18.5,1.7 L17,1.7 L17,3.2 L18.5,3.2 L18.5,1.7 L18.5,1.7 Z M21.4,1.7 L19.9,1.7 L19.9,3.2 L21.4,3.2 L21.4,1.7 L21.4,1.7 Z M24.3,1.7 L22.8,1.7 L22.8,3.2 L24.3,3.2 L24.3,1.7 L24.3,1.7 Z M27.3,1.7 L25.8,1.7 L25.8,3.2 L27.3,3.2 L27.3,1.7 L27.3,1.7 Z M30.2,1.7 L28.7,1.7 L28.7,3.2 L30.2,3.2 L30.2,1.7 L30.2,1.7 Z M33.1,1.7 L31.6,1.7 L31.6,3.2 L33.1,3.2 L33.1,1.7 L33.1,1.7 Z M36.1,1.7 L34.6,1.7 L34.6,3.2 L36.1,3.2 L36.1,1.7 L36.1,1.7 Z M39,1.7 L37.5,1.7 L37.5,3.2 L39,3.2 L39,1.7 L39,1.7 Z M41.9,1.7 L40.4,1.7 L40.4,3.2 L41.9,3.2 L41.9,1.7 L41.9,1.7 Z M44.9,1.7 L43.4,1.7 L43.4,3.2 L44.9,3.2 L44.9,1.7 L44.9,1.7 Z M47.8,1.7 L46.3,1.7 L46.3,3.2 L47.8,3.2 L47.8,1.7 L47.8,1.7 Z M50.8,1.7 L49.3,1.7 L49.3,3.2 L50.8,3.2 L50.8,1.7 L50.8,1.7 Z M53.7,1.7 L52.2,1.7 L52.2,3.2 L53.7,3.2 L53.7,1.7 L53.7,1.7 Z M56.6,1.7 L55.1,1.7 L55.1,3.2 L56.6,3.2 L56.6,1.7 L56.6,1.7 Z M59.6,1.7 L58.1,1.7 L58.1,3.2 L59.6,3.2 L59.6,1.7 L59.6,1.7 Z M62.5,1.7 L61,1.7 L61,3.2 L62.5,3.2 L62.5,1.7 L62.5,1.7 Z M65.4,1.7 L64,1.7 L64,3.2 L65.5,3.2 L65.5,1.7 L65.4,1.7 Z M68.4,1.7 L66.9,1.7 L66.9,3.2 L68.4,3.2 L68.4,1.7 L68.4,1.7 Z M2.3,3.2 L0.8,3.2 L0.8,4.7 L2.3,4.7 L2.3,3.2 L2.3,3.2 Z M5.3,3.2 L3.8,3.2 L3.8,4.7 L5.3,4.7 L5.3,3.2 L5.3,3.2 Z M8.2,3.2 L6.7,3.2 L6.7,4.7 L8.2,4.7 L8.2,3.2 L8.2,3.2 Z M11.1,3.2 L9.6,3.2 L9.6,4.7 L11.1,4.7 L11.1,3.2 L11.1,3.2 Z M14.1,3.2 L12.6,3.2 L12.6,4.7 L14.1,4.7 L14.1,3.2 L14.1,3.2 Z M17,3.2 L15.5,3.2 L15.5,4.7 L17,4.7 L17,3.2 L17,3.2 Z M19.9,3.2 L18.4,3.2 L18.4,4.7 L19.9,4.7 L19.9,3.2 L19.9,3.2 Z M22.9,3.2 L21.4,3.2 L21.4,4.7 L22.9,4.7 L22.9,3.2 L22.9,3.2 Z M25.8,3.2 L24.3,3.2 L24.3,4.7 L25.8,4.7 L25.8,3.2 L25.8,3.2 Z M28.8,3.2 L27.3,3.2 L27.3,4.7 L28.8,4.7 L28.8,3.2 L28.8,3.2 Z M31.7,3.2 L30.2,3.2 L30.2,4.7 L31.7,4.7 L31.7,3.2 L31.7,3.2 Z M34.6,3.2 L33.1,3.2 L33.1,4.7 L34.6,4.7 L34.6,3.2 L34.6,3.2 Z M37.6,3.2 L36.1,3.2 L36.1,4.7 L37.6,4.7 L37.6,3.2 L37.6,3.2 Z M40.5,3.2 L39,3.2 L39,4.7 L40.5,4.7 L40.5,3.2 L40.5,3.2 Z M43.4,3.2 L41.9,3.2 L41.9,4.7 L43.4,4.7 L43.4,3.2 L43.4,3.2 Z M46.4,3.2 L44.9,3.2 L44.9,4.7 L46.4,4.7 L46.4,3.2 L46.4,3.2 Z M49.3,3.2 L47.8,3.2 L47.8,4.7 L49.3,4.7 L49.3,3.2 L49.3,3.2 Z M52.2,3.2 L50.7,3.2 L50.7,4.7 L52.2,4.7 L52.2,3.2 L52.2,3.2 Z M55.2,3.2 L53.7,3.2 L53.7,4.7 L55.2,4.7 L55.2,3.2 L55.2,3.2 Z M58.1,3.2 L56.6,3.2 L56.6,4.7 L58.1,4.7 L58.1,3.2 L58.1,3.2 Z M61,3.2 L59.5,3.2 L59.5,4.7 L61,4.7 L61,3.2 L61,3.2 Z M64,3.2 L62.5,3.2 L62.5,4.7 L64,4.7 L64,3.2 L64,3.2 Z M66.9,3.2 L65.4,3.2 L65.4,4.7 L66.9,4.7 L66.9,3.2 L66.9,3.2 Z M3.8,4.7 L2.3,4.7 L2.3,6.2 L3.8,6.2 L3.8,4.7 L3.8,4.7 Z M6.7,4.7 L5.2,4.7 L5.2,6.2 L6.7,6.2 L6.7,4.7 L6.7,4.7 Z M9.7,4.7 L8.2,4.7 L8.2,6.2 L9.7,6.2 L9.7,4.7 L9.7,4.7 Z M12.6,4.7 L11.1,4.7 L11.1,6.2 L12.6,6.2 L12.6,4.7 L12.6,4.7 Z M15.5,4.7 L14,4.7 L14,6.2 L15.5,6.2 L15.5,4.7 L15.5,4.7 Z M18.5,4.7 L17,4.7 L17,6.2 L18.5,6.2 L18.5,4.7 L18.5,4.7 Z M21.4,4.7 L19.9,4.7 L19.9,6.2 L21.4,6.2 L21.4,4.7 L21.4,4.7 Z M24.3,4.7 L22.8,4.7 L22.8,6.2 L24.3,6.2 L24.3,4.7 L24.3,4.7 Z M27.3,4.7 L25.8,4.7 L25.8,6.2 L27.3,6.2 L27.3,4.7 L27.3,4.7 Z M30.2,4.7 L28.7,4.7 L28.7,6.2 L30.2,6.2 L30.2,4.7 L30.2,4.7 Z M33.1,4.7 L31.6,4.7 L31.6,6.2 L33.1,6.2 L33.1,4.7 L33.1,4.7 Z M36.1,4.7 L34.6,4.7 L34.6,6.2 L36.1,6.2 L36.1,4.7 L36.1,4.7 Z M39,4.7 L37.5,4.7 L37.5,6.2 L39,6.2 L39,4.7 L39,4.7 Z M41.9,4.7 L40.4,4.7 L40.4,6.2 L41.9,6.2 L41.9,4.7 L41.9,4.7 Z M44.9,4.7 L43.4,4.7 L43.4,6.2 L44.9,6.2 L44.9,4.7 L44.9,4.7 Z M47.8,4.7 L46.3,4.7 L46.3,6.2 L47.8,6.2 L47.8,4.7 L47.8,4.7 Z M50.8,4.7 L49.3,4.7 L49.3,6.2 L50.8,6.2 L50.8,4.7 L50.8,4.7 Z M53.7,4.7 L52.2,4.7 L52.2,6.2 L53.7,6.2 L53.7,4.7 L53.7,4.7 Z M56.6,4.7 L55.1,4.7 L55.1,6.2 L56.6,6.2 L56.6,4.7 L56.6,4.7 Z M59.6,4.7 L58.1,4.7 L58.1,6.2 L59.6,6.2 L59.6,4.7 L59.6,4.7 Z M62.5,4.7 L61,4.7 L61,6.2 L62.5,6.2 L62.5,4.7 L62.5,4.7 Z M65.4,4.7 L64,4.7 L64,6.2 L65.5,6.2 L65.5,4.7 L65.4,4.7 Z M68.4,4.7 L66.9,4.7 L66.9,6.2 L68.4,6.2 L68.4,4.7 L68.4,4.7 Z M2.3,6.1 L0.8,6.1 L0.8,7.6 L2.3,7.6 L2.3,6.1 L2.3,6.1 Z M5.3,6.1 L3.8,6.1 L3.8,7.6 L5.3,7.6 L5.3,6.1 L5.3,6.1 Z M8.2,6.1 L6.7,6.1 L6.7,7.6 L8.2,7.6 L8.2,6.1 L8.2,6.1 Z M11.1,6.1 L9.6,6.1 L9.6,7.6 L11.1,7.6 L11.1,6.1 L11.1,6.1 Z M14.1,6.1 L12.6,6.1 L12.6,7.6 L14.1,7.6 L14.1,6.1 L14.1,6.1 Z M17,6.1 L15.5,6.1 L15.5,7.6 L17,7.6 L17,6.1 L17,6.1 Z M19.9,6.1 L18.4,6.1 L18.4,7.6 L19.9,7.6 L19.9,6.1 L19.9,6.1 Z M22.9,6.1 L21.4,6.1 L21.4,7.6 L22.9,7.6 L22.9,6.1 L22.9,6.1 Z M25.8,6.1 L24.3,6.1 L24.3,7.6 L25.8,7.6 L25.8,6.1 L25.8,6.1 Z M28.8,6.1 L27.3,6.1 L27.3,7.6 L28.8,7.6 L28.8,6.1 L28.8,6.1 Z M31.7,6.1 L30.2,6.1 L30.2,7.6 L31.7,7.6 L31.7,6.1 L31.7,6.1 Z M34.6,6.1 L33.1,6.1 L33.1,7.6 L34.6,7.6 L34.6,6.1 L34.6,6.1 Z M37.6,6.1 L36.1,6.1 L36.1,7.6 L37.6,7.6 L37.6,6.1 L37.6,6.1 Z M40.5,6.1 L39,6.1 L39,7.6 L40.5,7.6 L40.5,6.1 L40.5,6.1 Z M43.4,6.1 L41.9,6.1 L41.9,7.6 L43.4,7.6 L43.4,6.1 L43.4,6.1 Z M46.4,6.1 L44.9,6.1 L44.9,7.6 L46.4,7.6 L46.4,6.1 L46.4,6.1 Z M49.3,6.1 L47.8,6.1 L47.8,7.6 L49.3,7.6 L49.3,6.1 L49.3,6.1 Z M52.2,6.1 L50.7,6.1 L50.7,7.6 L52.2,7.6 L52.2,6.1 L52.2,6.1 Z M55.2,6.1 L53.7,6.1 L53.7,7.6 L55.2,7.6 L55.2,6.1 L55.2,6.1 Z M58.1,6.1 L56.6,6.1 L56.6,7.6 L58.1,7.6 L58.1,6.1 L58.1,6.1 Z M61,6.1 L59.5,6.1 L59.5,7.6 L61,7.6 L61,6.1 L61,6.1 Z M64,6.1 L62.5,6.1 L62.5,7.6 L64,7.6 L64,6.1 L64,6.1 Z M66.9,6.1 L65.4,6.1 L65.4,7.6 L66.9,7.6 L66.9,6.1 L66.9,6.1 Z M3.8,7.6 L2.3,7.6 L2.3,9.1 L3.8,9.1 L3.8,7.6 L3.8,7.6 Z M6.7,7.6 L5.2,7.6 L5.2,9.1 L6.7,9.1 L6.7,7.6 L6.7,7.6 Z M9.7,7.6 L8.2,7.6 L8.2,9.1 L9.7,9.1 L9.7,7.6 L9.7,7.6 Z M12.6,7.6 L11.1,7.6 L11.1,9.1 L12.6,9.1 L12.6,7.6 L12.6,7.6 Z M15.5,7.6 L14,7.6 L14,9.1 L15.5,9.1 L15.5,7.6 L15.5,7.6 Z M18.5,7.6 L17,7.6 L17,9.1 L18.5,9.1 L18.5,7.6 L18.5,7.6 Z M21.4,7.6 L19.9,7.6 L19.9,9.1 L21.4,9.1 L21.4,7.6 L21.4,7.6 Z M24.3,7.6 L22.8,7.6 L22.8,9.1 L24.3,9.1 L24.3,7.6 L24.3,7.6 Z M27.3,7.6 L25.8,7.6 L25.8,9.1 L27.3,9.1 L27.3,7.6 L27.3,7.6 Z M30.2,7.6 L28.7,7.6 L28.7,9.1 L30.2,9.1 L30.2,7.6 L30.2,7.6 Z M33.1,7.6 L31.6,7.6 L31.6,9.1 L33.1,9.1 L33.1,7.6 L33.1,7.6 Z M36.1,7.6 L34.6,7.6 L34.6,9.1 L36.1,9.1 L36.1,7.6 L36.1,7.6 Z M39,7.6 L37.5,7.6 L37.5,9.1 L39,9.1 L39,7.6 L39,7.6 Z M41.9,7.6 L40.4,7.6 L40.4,9.1 L41.9,9.1 L41.9,7.6 L41.9,7.6 Z M44.9,7.6 L43.4,7.6 L43.4,9.1 L44.9,9.1 L44.9,7.6 L44.9,7.6 Z M47.8,7.6 L46.3,7.6 L46.3,9.1 L47.8,9.1 L47.8,7.6 L47.8,7.6 Z M50.8,7.6 L49.3,7.6 L49.3,9.1 L50.8,9.1 L50.8,7.6 L50.8,7.6 Z M53.7,7.6 L52.2,7.6 L52.2,9.1 L53.7,9.1 L53.7,7.6 L53.7,7.6 Z M56.6,7.6 L55.1,7.6 L55.1,9.1 L56.6,9.1 L56.6,7.6 L56.6,7.6 Z M59.6,7.6 L58.1,7.6 L58.1,9.1 L59.6,9.1 L59.6,7.6 L59.6,7.6 Z M62.5,7.6 L61,7.6 L61,9.1 L62.5,9.1 L62.5,7.6 L62.5,7.6 Z M65.4,7.6 L64,7.6 L64,9.1 L65.5,9.1 L65.5,7.6 L65.4,7.6 Z M68.4,7.6 L66.9,7.6 L66.9,9.1 L68.4,9.1 L68.4,7.6 L68.4,7.6 Z" id="Shape" fill="#2E2E2E" mask="url(#mask-12)"></path>
-                    </g>
-                    <g>
-                        <mask id="mask-14" fill="white">
-                            <use xlink:href="#path-13"></use>
-                        </mask>
-                        <g id="SVGID_13_"></g>
-                        <path d="M64.2,0 L4.8,0 C2.4,0 0.4,2.1 0.4,4.7 C0.4,7.3 2.3,9.4 4.8,9.4 L64.2,9.4 C66.6,9.4 68.5,7.3 68.5,4.7 C68.5,2.1 66.6,0 64.2,0 L64.2,0 Z M63.8,7.8 L5.2,7.8 C3.4,7.8 2,6.4 2,4.6 C2,2.8 3.4,1.4 5.2,1.4 L63.8,1.4 C65.6,1.4 67,2.8 67,4.6 C67,6.4 65.6,7.8 63.8,7.8 L63.8,7.8 Z" id="Shape" fill="#000000" opacity="0.2" mask="url(#mask-14)"></path>
-                    </g>
-                </g>
-                <path d="M215.1,787.2 C197,787.2 182.3,801.9 182.3,820 C182.3,838.1 197,852.8 215.1,852.8 C233.2,852.8 248,838.1 248,820 C248,801.9 233.3,787.2 215.1,787.2 L215.1,787.2 Z M215.1,849.8 C198.6,849.8 185.3,836.5 185.3,820 C185.3,803.5 198.7,790.2 215.1,790.2 C231.5,790.2 245,803.5 245,820 C245,836.5 231.6,849.8 215.1,849.8 L215.1,849.8 Z" id="Shape" fill="url(#linearGradient-15)"></path>
-                <path d="M70.3,8.5 C38.2,8.5 12.2,34.5 12.2,66.6 L12.2,571.7 L322.6,8.5 L70.3,8.5 L70.3,8.5 Z" id="Shape" fill="url(#linearGradient-16)"></path>
-            </g>
-            <rect id="Rectangle-path" fill="#000000" x="27" y="105" width="375" height="667"></rect>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPhone6Plus-landscape.svg b/front_end/emulated_devices/iPhone6Plus-landscape.svg
deleted file mode 100644
index 35de751..0000000
--- a/front_end/emulated_devices/iPhone6Plus-landscape.svg
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="956px" height="470px" viewBox="0 0 956 470" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPhone 6 Plus</title>
-    <defs>
-        <linearGradient x1="-0.00325805225%" y1="49.9995377%" x2="99.9938099%" y2="49.9995377%" id="linearGradient-1">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="11.69%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="87.64%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="28.2585006%" y1="128.845717%" x2="71.7414993%" y2="-28.8467008%" id="linearGradient-2">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.05" offset="13.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.02" offset="88.31%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="49.9966887%" cy="50.018543%" fx="49.9966887%" fy="50.018543%" r="49.9807947%" id="radialGradient-3">
-            <stop stop-color="#5D5D5F" offset="0%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.4421581%" cy="57.1386068%" fx="50.4421581%" fy="57.1386068%" r="49.9701987%" id="radialGradient-4">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.5719202%" cy="96.4177227%" fx="47.5719202%" fy="96.4177227%" r="95.6970109%" id="radialGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.5042293%" cy="23.9851238%" fx="50.5042293%" fy="23.9851238%" r="57.5643564%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="49.5644397%" y1="8.31811466%" x2="49.56633%" y2="112.128115%" id="linearGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-8" d="M9.22,4.58 L9.22,63.2 C9.22,65.57 7.3,67.49 4.93,67.49 L4.93,67.49 C2.56,67.49 0.64,65.57 0.64,63.2 L0.64,4.58 C0.64,2.21 2.56,0.29 4.93,0.29 L4.93,0.29 C7.3,0.3 9.22,2.22 9.22,4.58 L9.22,4.58 Z"></path>
-        <linearGradient x1="101.420118%" y1="50.1973043%" x2="1.49257867%" y2="50.1973043%" id="linearGradient-10">
-            <stop stop-color="#2E2E31" offset="0%"></stop>
-            <stop stop-color="#616161" offset="24.48%"></stop>
-            <stop stop-color="#858585" offset="81.37%"></stop>
-            <stop stop-color="#2E2E31" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-11" d="M9.22,4.58 L9.22,63.2 C9.22,65.57 7.3,67.49 4.93,67.49 L4.93,67.49 C2.56,67.49 0.64,65.57 0.64,63.2 L0.64,4.58 C0.64,2.21 2.56,0.29 4.93,0.29 L4.93,0.29 C7.3,0.3 9.22,2.22 9.22,4.58 L9.22,4.58 Z"></path>
-        <path id="path-13" d="M9.22,4.58 L9.22,63.2 C9.22,65.57 7.3,67.49 4.93,67.49 L4.93,67.49 C2.56,67.49 0.64,65.57 0.64,63.2 L0.64,4.58 C0.64,2.21 2.56,0.29 4.93,0.29 L4.93,0.29 C7.3,0.3 9.22,2.22 9.22,4.58 L9.22,4.58 Z"></path>
-        <linearGradient x1="91.876637%" y1="13.615443%" x2="8.6218396%" y2="85.9514161%" id="linearGradient-15">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="5.94928391%" y1="2.26524773%" x2="44.6162595%" y2="41.2217771%" id="linearGradient-16">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="iphone6plus-landscape" transform="translate(1.000000, 0.000000)">
-            <g id="Group">
-                <g>
-                    <g>
-                        <path d="M144.74,464.27 L144.74,467.99 C144.74,469.02 143.91,469.85 142.88,469.85 L112.92,469.85 C111.89,469.85 111.06,469.02 111.06,467.99 L111.06,464.27 L144.74,464.27 L144.74,464.27 Z" id="Shape" fill="#808086"></path>
-                        <path d="M187.97,469.85 C186.94,469.85 186.11,469.02 186.11,467.99 L186.11,464.27 L247.24,464.27 L247.24,467.99 C247.24,469.02 246.41,469.85 245.38,469.85" id="Shape" fill="#808086"></path>
-                        <path d="M262.73,469.85 C261.7,469.85 260.87,469.02 260.87,467.99 L260.87,464.27 L322,464.27 L322,467.99 C322,469.02 321.17,469.85 320.14,469.85" id="Shape" fill="#808086"></path>
-                        <path d="M187.47,5.73 L187.47,2.01 C187.47,0.98 188.3,0.15 189.33,0.15 L246.74,0.15 C247.77,0.15 248.6,0.98 248.6,2.01 L248.6,5.73 L187.47,5.73 L187.47,5.73 Z" id="Shape" fill="#818187"></path>
-                        <path d="M65.18,467.44 C29.37,467.44 0.24,438.31 0.24,402.51 L0.24,68.05 C0.24,32.24 29.37,3.11 65.18,3.11 L888.81,3.11 C924.62,3.11 953.75,32.24 953.75,68.05 L953.75,402.5 C953.75,438.31 924.62,467.43 888.81,467.43 L65.18,467.43 L65.18,467.44 Z" id="Shape" stroke-opacity="0.5" stroke="#666666" fill="#B2B2B2"></path>
-                        <path d="M948.57,402.69 C948.57,418.6 942.37,433.56 931.12,444.81 C919.87,456.06 904.91,462.26 889,462.26 L65,462.26 C49.09,462.26 34.13,456.06 22.88,444.81 C11.63,433.56 5.43,418.6 5.43,402.69 L5.43,67.86 C5.43,51.95 11.63,36.99 22.88,25.74 C34.13,14.49 49.09,8.29 65,8.29 L889,8.29 C904.91,8.29 919.87,14.49 931.12,25.74 C942.37,36.99 948.57,51.95 948.57,67.86 L948.57,402.69 L948.57,402.69 Z" id="Shape" fill="#404040"></path>
-                        <path d="M948.75,68.05 L948.75,402.5 C948.75,435.6 921.92,462.44 888.81,462.44 L65.18,462.44 C32.08,462.44 5.24,435.61 5.24,402.5 L5.24,68.05 C5.24,34.95 32.07,8.11 65.18,8.11 L888.81,8.11 C921.92,8.11 948.75,34.94 948.75,68.05 L948.75,68.05 Z" id="Shape" fill="#262626"></path>
-                        <path d="M5.25,67.86 L5.25,402.69 C5.25,435.69 32,462.44 65,462.44 L66.64,462.44 C33.64,462.44 6.89,435.69 6.89,402.69 L6.89,67.86 C6.89,34.86 33.64,8.11 66.64,8.11 L65,8.11 C32,8.11 5.25,34.86 5.25,67.86 L5.25,67.86 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                        <path d="M8.8,67.86 L8.8,402.69 C8.8,433.68 34.01,458.89 65,458.89 L889,458.89 C919.99,458.89 945.2,433.68 945.2,402.69 L945.2,67.86 C945.2,36.87 919.99,11.66 889,11.66 L65,11.66 C34.01,11.66 8.8,36.87 8.8,67.86 L8.8,67.86 Z M889,17.66 C916.68,17.66 939.2,40.18 939.2,67.86 L939.2,402.69 C939.2,430.37 916.68,452.89 889,452.89 L65,452.89 C37.32,452.89 14.8,430.37 14.8,402.69 L14.8,67.86 C14.8,40.18 37.32,17.66 65,17.66 L889,17.66 L889,17.66 Z" id="Shape" fill="url(#linearGradient-2)"></path>
-                        <g transform="translate(46.000000, 295.000000)">
-                            <circle id="Oval" fill="url(#radialGradient-3)" cx="8.19" cy="8.2" r="7.55"></circle>
-                            <circle id="Oval" fill="url(#radialGradient-4)" opacity="0.8" cx="8.19" cy="8.2" r="7.55"></circle>
-                            <circle id="Oval" fill="#1B1A1F" cx="8.19" cy="8.2" r="5.03"></circle>
-                            <circle id="Oval" fill="#36284C" cx="8.19" cy="8.2" r="3.68"></circle>
-                            <circle id="Oval" fill="url(#radialGradient-5)" cx="8.19" cy="8.2" r="3.68"></circle>
-                            <g transform="translate(6.000000, 6.000000)" id="Shape">
-                                <path d="M4.21,2.2 C4.21,3.32 3.3,4.22 2.19,4.22 C1.07,4.22 0.17,3.31 0.17,2.2 C0.17,1.08 1.08,0.18 2.19,0.18 C3.31,0.18 4.21,1.09 4.21,2.2 L4.21,2.2 Z" fill="#141414" opacity="0.5"></path>
-                                <path d="M4.21,2.2 C4.21,3.32 3.3,4.22 2.19,4.22 C1.07,4.22 0.17,3.31 0.17,2.2 C0.17,1.08 1.08,0.18 2.19,0.18 C3.31,0.18 4.21,1.09 4.21,2.2 L4.21,2.2 Z" fill="url(#radialGradient-6)"></path>
-                            </g>
-                            <path d="M8.19,6.68 C7.74,6.68 7.35,6.88 7.07,7.19 L7.54,7.66 C7.7,7.47 7.92,7.35 8.18,7.35 C8.45,7.35 8.68,7.49 8.84,7.68 L9.31,7.2 C9.04,6.9 8.65,6.68 8.19,6.68 L8.19,6.68 Z" id="Shape" fill="url(#linearGradient-7)"></path>
-                        </g>
-                        <g transform="translate(50.000000, 201.000000)" id="Clipped">
-                            <g>
-                                <mask id="mask-9" fill="white">
-                                    <use xlink:href="#path-8"></use>
-                                </mask>
-                                <g id="SVGID_8_"></g>
-                                <path d="M9.22,4.58 L9.22,63.2 C9.22,65.57 7.3,67.49 4.93,67.49 L4.93,67.49 C2.56,67.49 0.64,65.57 0.64,63.2 L0.64,4.58 C0.64,2.21 2.56,0.29 4.93,0.29 L4.93,0.29 C7.3,0.3 9.22,2.22 9.22,4.58 L9.22,4.58 Z" id="Shape" fill="url(#linearGradient-10)" opacity="0.8" mask="url(#mask-9)"></path>
-                            </g>
-                            <g>
-                                <mask id="mask-12" fill="white">
-                                    <use xlink:href="#path-11"></use>
-                                </mask>
-                                <g id="SVGID_8_"></g>
-                                <path d="M0.53,66.08 L0.53,67.55 L2,67.55 L2,66.08 L0.53,66.08 L0.53,66.08 Z M0.53,63.15 L0.53,64.62 L2,64.62 L2,63.15 L0.53,63.15 L0.53,63.15 Z M0.53,60.21 L0.53,61.68 L2,61.68 L2,60.21 L0.53,60.21 L0.53,60.21 Z M0.53,57.28 L0.53,58.75 L2,58.75 L2,57.28 L0.53,57.28 L0.53,57.28 Z M0.53,54.34 L0.53,55.81 L2,55.81 L2,54.34 L0.53,54.34 L0.53,54.34 Z M0.53,51.41 L0.53,52.88 L2,52.88 L2,51.41 L0.53,51.41 L0.53,51.41 Z M0.53,48.47 L0.53,49.94 L2,49.94 L2,48.47 L0.53,48.47 L0.53,48.47 Z M0.53,45.54 L0.53,47.01 L2,47.01 L2,45.54 L0.53,45.54 L0.53,45.54 Z M0.53,42.6 L0.53,44.07 L2,44.07 L2,42.6 L0.53,42.6 L0.53,42.6 Z M0.53,39.67 L0.53,41.14 L2,41.14 L2,39.67 L0.53,39.67 L0.53,39.67 Z M0.53,36.73 L0.53,38.2 L2,38.2 L2,36.73 L0.53,36.73 L0.53,36.73 Z M0.53,33.8 L0.53,35.27 L2,35.27 L2,33.8 L0.53,33.8 L0.53,33.8 Z M0.53,30.86 L0.53,32.33 L2,32.33 L2,30.86 L0.53,30.86 L0.53,30.86 Z M0.53,27.93 L0.53,29.4 L2,29.4 L2,27.93 L0.53,27.93 L0.53,27.93 Z M0.53,24.99 L0.53,26.46 L2,26.46 L2,24.99 L0.53,24.99 L0.53,24.99 Z M0.53,22.06 L0.53,23.53 L2,23.53 L2,22.06 L0.53,22.06 L0.53,22.06 Z M0.53,19.12 L0.53,20.59 L2,20.59 L2,19.12 L0.53,19.12 L0.53,19.12 Z M0.53,16.19 L0.53,17.66 L2,17.66 L2,16.19 L0.53,16.19 L0.53,16.19 Z M0.53,13.25 L0.53,14.72 L2,14.72 L2,13.25 L0.53,13.25 L0.53,13.25 Z M0.53,10.32 L0.53,11.79 L2,11.79 L2,10.32 L0.53,10.32 L0.53,10.32 Z M0.53,7.38 L0.53,8.85 L2,8.85 L2,7.38 L0.53,7.38 L0.53,7.38 Z M0.53,4.45 L0.53,5.92 L2,5.92 L2,4.45 L0.53,4.45 L0.53,4.45 Z M0.53,1.51 L0.53,2.98 L2,2.98 L2,1.51 L0.53,1.51 L0.53,1.51 Z M2,64.61 L2,66.08 L3.47,66.08 L3.47,64.61 L2,64.61 L2,64.61 Z M2,61.68 L2,63.15 L3.47,63.15 L3.47,61.68 L2,61.68 L2,61.68 Z M2,58.74 L2,60.21 L3.47,60.21 L3.47,58.74 L2,58.74 L2,58.74 Z M2,55.81 L2,57.28 L3.47,57.28 L3.47,55.81 L2,55.81 L2,55.81 Z M2,52.87 L2,54.34 L3.47,54.34 L3.47,52.87 L2,52.87 L2,52.87 Z M2,49.94 L2,51.41 L3.47,51.41 L3.47,49.94 L2,49.94 L2,49.94 Z M2,47.01 L2,48.48 L3.47,48.48 L3.47,47.01 L2,47.01 L2,47.01 Z M2,44.07 L2,45.54 L3.47,45.54 L3.47,44.07 L2,44.07 L2,44.07 Z M2,41.14 L2,42.61 L3.47,42.61 L3.47,41.14 L2,41.14 L2,41.14 Z M2,38.2 L2,39.67 L3.47,39.67 L3.47,38.2 L2,38.2 L2,38.2 Z M2,35.27 L2,36.74 L3.47,36.74 L3.47,35.27 L2,35.27 L2,35.27 Z M2,32.33 L2,33.8 L3.47,33.8 L3.47,32.33 L2,32.33 L2,32.33 Z M2,29.4 L2,30.87 L3.47,30.87 L3.47,29.4 L2,29.4 L2,29.4 Z M2,26.46 L2,27.93 L3.47,27.93 L3.47,26.46 L2,26.46 L2,26.46 Z M2,23.53 L2,25 L3.47,25 L3.47,23.53 L2,23.53 L2,23.53 Z M2,20.59 L2,22.06 L3.47,22.06 L3.47,20.59 L2,20.59 L2,20.59 Z M2,17.66 L2,19.13 L3.47,19.13 L3.47,17.66 L2,17.66 L2,17.66 Z M2,14.72 L2,16.19 L3.47,16.19 L3.47,14.72 L2,14.72 L2,14.72 Z M2,11.79 L2,13.26 L3.47,13.26 L3.47,11.79 L2,11.79 L2,11.79 Z M2,8.85 L2,10.32 L3.47,10.32 L3.47,8.85 L2,8.85 L2,8.85 Z M2,5.92 L2,7.39 L3.47,7.39 L3.47,5.92 L2,5.92 L2,5.92 Z M2,2.98 L2,4.45 L3.47,4.45 L3.47,2.98 L2,2.98 L2,2.98 Z M2,0.05 L2,1.52 L3.47,1.52 L3.47,0.05 L2,0.05 L2,0.05 Z M3.46,66.08 L3.46,67.55 L4.93,67.55 L4.93,66.08 L3.46,66.08 L3.46,66.08 Z M3.46,63.15 L3.46,64.62 L4.93,64.62 L4.93,63.15 L3.46,63.15 L3.46,63.15 Z M3.46,60.21 L3.46,61.68 L4.93,61.68 L4.93,60.21 L3.46,60.21 L3.46,60.21 Z M3.46,57.28 L3.46,58.75 L4.93,58.75 L4.93,57.28 L3.46,57.28 L3.46,57.28 Z M3.46,54.34 L3.46,55.81 L4.93,55.81 L4.93,54.34 L3.46,54.34 L3.46,54.34 Z M3.46,51.41 L3.46,52.88 L4.93,52.88 L4.93,51.41 L3.46,51.41 L3.46,51.41 Z M3.46,48.47 L3.46,49.94 L4.93,49.94 L4.93,48.47 L3.46,48.47 L3.46,48.47 Z M3.46,45.54 L3.46,47.01 L4.93,47.01 L4.93,45.54 L3.46,45.54 L3.46,45.54 Z M3.46,42.6 L3.46,44.07 L4.93,44.07 L4.93,42.6 L3.46,42.6 L3.46,42.6 Z M3.46,39.67 L3.46,41.14 L4.93,41.14 L4.93,39.67 L3.46,39.67 L3.46,39.67 Z M3.46,36.73 L3.46,38.2 L4.93,38.2 L4.93,36.73 L3.46,36.73 L3.46,36.73 Z M3.46,33.8 L3.46,35.27 L4.93,35.27 L4.93,33.8 L3.46,33.8 L3.46,33.8 Z M3.46,30.86 L3.46,32.33 L4.93,32.33 L4.93,30.86 L3.46,30.86 L3.46,30.86 Z M3.46,27.93 L3.46,29.4 L4.93,29.4 L4.93,27.93 L3.46,27.93 L3.46,27.93 Z M3.46,24.99 L3.46,26.46 L4.93,26.46 L4.93,24.99 L3.46,24.99 L3.46,24.99 Z M3.46,22.06 L3.46,23.53 L4.93,23.53 L4.93,22.06 L3.46,22.06 L3.46,22.06 Z M3.46,19.12 L3.46,20.59 L4.93,20.59 L4.93,19.12 L3.46,19.12 L3.46,19.12 Z M3.46,16.19 L3.46,17.66 L4.93,17.66 L4.93,16.19 L3.46,16.19 L3.46,16.19 Z M3.46,13.25 L3.46,14.72 L4.93,14.72 L4.93,13.25 L3.46,13.25 L3.46,13.25 Z M3.46,10.32 L3.46,11.79 L4.93,11.79 L4.93,10.32 L3.46,10.32 L3.46,10.32 Z M3.46,7.38 L3.46,8.85 L4.93,8.85 L4.93,7.38 L3.46,7.38 L3.46,7.38 Z M3.46,4.45 L3.46,5.92 L4.93,5.92 L4.93,4.45 L3.46,4.45 L3.46,4.45 Z M3.46,1.51 L3.46,2.98 L4.93,2.98 L4.93,1.51 L3.46,1.51 L3.46,1.51 Z M4.93,64.61 L4.93,66.08 L6.4,66.08 L6.4,64.61 L4.93,64.61 L4.93,64.61 Z M4.93,61.68 L4.93,63.15 L6.4,63.15 L6.4,61.68 L4.93,61.68 L4.93,61.68 Z M4.93,58.74 L4.93,60.21 L6.4,60.21 L6.4,58.74 L4.93,58.74 L4.93,58.74 Z M4.93,55.81 L4.93,57.28 L6.4,57.28 L6.4,55.81 L4.93,55.81 L4.93,55.81 Z M4.93,52.87 L4.93,54.34 L6.4,54.34 L6.4,52.87 L4.93,52.87 L4.93,52.87 Z M4.93,49.94 L4.93,51.41 L6.4,51.41 L6.4,49.94 L4.93,49.94 L4.93,49.94 Z M4.93,47.01 L4.93,48.48 L6.4,48.48 L6.4,47.01 L4.93,47.01 L4.93,47.01 Z M4.93,44.07 L4.93,45.54 L6.4,45.54 L6.4,44.07 L4.93,44.07 L4.93,44.07 Z M4.93,41.14 L4.93,42.61 L6.4,42.61 L6.4,41.14 L4.93,41.14 L4.93,41.14 Z M4.93,38.2 L4.93,39.67 L6.4,39.67 L6.4,38.2 L4.93,38.2 L4.93,38.2 Z M4.93,35.27 L4.93,36.74 L6.4,36.74 L6.4,35.27 L4.93,35.27 L4.93,35.27 Z M4.93,32.33 L4.93,33.8 L6.4,33.8 L6.4,32.33 L4.93,32.33 L4.93,32.33 Z M4.93,29.4 L4.93,30.87 L6.4,30.87 L6.4,29.4 L4.93,29.4 L4.93,29.4 Z M4.93,26.46 L4.93,27.93 L6.4,27.93 L6.4,26.46 L4.93,26.46 L4.93,26.46 Z M4.93,23.53 L4.93,25 L6.4,25 L6.4,23.53 L4.93,23.53 L4.93,23.53 Z M4.93,20.59 L4.93,22.06 L6.4,22.06 L6.4,20.59 L4.93,20.59 L4.93,20.59 Z M4.93,17.66 L4.93,19.13 L6.4,19.13 L6.4,17.66 L4.93,17.66 L4.93,17.66 Z M4.93,14.72 L4.93,16.19 L6.4,16.19 L6.4,14.72 L4.93,14.72 L4.93,14.72 Z M4.93,11.79 L4.93,13.26 L6.4,13.26 L6.4,11.79 L4.93,11.79 L4.93,11.79 Z M4.93,8.85 L4.93,10.32 L6.4,10.32 L6.4,8.85 L4.93,8.85 L4.93,8.85 Z M4.93,5.92 L4.93,7.39 L6.4,7.39 L6.4,5.92 L4.93,5.92 L4.93,5.92 Z M4.93,2.98 L4.93,4.45 L6.4,4.45 L6.4,2.98 L4.93,2.98 L4.93,2.98 Z M4.93,0.05 L4.93,1.52 L6.4,1.52 L6.4,0.05 L4.93,0.05 L4.93,0.05 Z M6.4,66.08 L6.4,67.55 L7.87,67.55 L7.87,66.08 L6.4,66.08 L6.4,66.08 Z M6.4,63.15 L6.4,64.62 L7.87,64.62 L7.87,63.15 L6.4,63.15 L6.4,63.15 Z M6.4,60.21 L6.4,61.68 L7.87,61.68 L7.87,60.21 L6.4,60.21 L6.4,60.21 Z M6.4,57.28 L6.4,58.75 L7.87,58.75 L7.87,57.28 L6.4,57.28 L6.4,57.28 Z M6.4,54.34 L6.4,55.81 L7.87,55.81 L7.87,54.34 L6.4,54.34 L6.4,54.34 Z M6.4,51.41 L6.4,52.88 L7.87,52.88 L7.87,51.41 L6.4,51.41 L6.4,51.41 Z M6.4,48.47 L6.4,49.94 L7.87,49.94 L7.87,48.47 L6.4,48.47 L6.4,48.47 Z M6.4,45.54 L6.4,47.01 L7.87,47.01 L7.87,45.54 L6.4,45.54 L6.4,45.54 Z M6.4,42.6 L6.4,44.07 L7.87,44.07 L7.87,42.6 L6.4,42.6 L6.4,42.6 Z M6.4,39.67 L6.4,41.14 L7.87,41.14 L7.87,39.67 L6.4,39.67 L6.4,39.67 Z M6.4,36.73 L6.4,38.2 L7.87,38.2 L7.87,36.73 L6.4,36.73 L6.4,36.73 Z M6.4,33.8 L6.4,35.27 L7.87,35.27 L7.87,33.8 L6.4,33.8 L6.4,33.8 Z M6.4,30.86 L6.4,32.33 L7.87,32.33 L7.87,30.86 L6.4,30.86 L6.4,30.86 Z M6.4,27.93 L6.4,29.4 L7.87,29.4 L7.87,27.93 L6.4,27.93 L6.4,27.93 Z M6.4,24.99 L6.4,26.46 L7.87,26.46 L7.87,24.99 L6.4,24.99 L6.4,24.99 Z M6.4,22.06 L6.4,23.53 L7.87,23.53 L7.87,22.06 L6.4,22.06 L6.4,22.06 Z M6.4,19.12 L6.4,20.59 L7.87,20.59 L7.87,19.12 L6.4,19.12 L6.4,19.12 Z M6.4,16.19 L6.4,17.66 L7.87,17.66 L7.87,16.19 L6.4,16.19 L6.4,16.19 Z M6.4,13.25 L6.4,14.72 L7.87,14.72 L7.87,13.25 L6.4,13.25 L6.4,13.25 Z M6.4,10.32 L6.4,11.79 L7.87,11.79 L7.87,10.32 L6.4,10.32 L6.4,10.32 Z M6.4,7.38 L6.4,8.85 L7.87,8.85 L7.87,7.38 L6.4,7.38 L6.4,7.38 Z M6.4,4.45 L6.4,5.92 L7.87,5.92 L7.87,4.45 L6.4,4.45 L6.4,4.45 Z M6.4,1.51 L6.4,2.98 L7.87,2.98 L7.87,1.51 L6.4,1.51 L6.4,1.51 Z M7.87,64.61 L7.87,66.08 L9.34,66.08 L9.34,64.61 L7.87,64.61 L7.87,64.61 Z M7.87,61.68 L7.87,63.15 L9.34,63.15 L9.34,61.68 L7.87,61.68 L7.87,61.68 Z M7.87,58.74 L7.87,60.21 L9.34,60.21 L9.34,58.74 L7.87,58.74 L7.87,58.74 Z M7.87,55.81 L7.87,57.28 L9.34,57.28 L9.34,55.81 L7.87,55.81 L7.87,55.81 Z M7.87,52.87 L7.87,54.34 L9.34,54.34 L9.34,52.87 L7.87,52.87 L7.87,52.87 Z M7.87,49.94 L7.87,51.41 L9.34,51.41 L9.34,49.94 L7.87,49.94 L7.87,49.94 Z M7.87,47.01 L7.87,48.48 L9.34,48.48 L9.34,47.01 L7.87,47.01 L7.87,47.01 Z M7.87,44.07 L7.87,45.54 L9.34,45.54 L9.34,44.07 L7.87,44.07 L7.87,44.07 Z M7.87,41.14 L7.87,42.61 L9.34,42.61 L9.34,41.14 L7.87,41.14 L7.87,41.14 Z M7.87,38.2 L7.87,39.67 L9.34,39.67 L9.34,38.2 L7.87,38.2 L7.87,38.2 Z M7.87,35.27 L7.87,36.74 L9.34,36.74 L9.34,35.27 L7.87,35.27 L7.87,35.27 Z M7.87,32.33 L7.87,33.8 L9.34,33.8 L9.34,32.33 L7.87,32.33 L7.87,32.33 Z M7.87,29.4 L7.87,30.87 L9.34,30.87 L9.34,29.4 L7.87,29.4 L7.87,29.4 Z M7.87,26.46 L7.87,27.93 L9.34,27.93 L9.34,26.46 L7.87,26.46 L7.87,26.46 Z M7.87,23.53 L7.87,25 L9.34,25 L9.34,23.53 L7.87,23.53 L7.87,23.53 Z M7.87,20.59 L7.87,22.06 L9.34,22.06 L9.34,20.59 L7.87,20.59 L7.87,20.59 Z M7.87,17.66 L7.87,19.13 L9.34,19.13 L9.34,17.66 L7.87,17.66 L7.87,17.66 Z M7.87,14.72 L7.87,16.19 L9.34,16.19 L9.34,14.72 L7.87,14.72 L7.87,14.72 Z M7.87,11.79 L7.87,13.26 L9.34,13.26 L9.34,11.79 L7.87,11.79 L7.87,11.79 Z M7.87,8.85 L7.87,10.32 L9.34,10.32 L9.34,8.85 L7.87,8.85 L7.87,8.85 Z M7.87,5.92 L7.87,7.39 L9.34,7.39 L9.34,5.92 L7.87,5.92 L7.87,5.92 Z M7.87,2.98 L7.87,4.45 L9.34,4.45 L9.34,2.98 L7.87,2.98 L7.87,2.98 Z M7.87,0.05 L7.87,1.52 L9.34,1.52 L9.34,0.05 L7.87,0.05 L7.87,0.05 Z" id="Shape" fill="#2E2E2E" mask="url(#mask-12)"></path>
-                            </g>
-                            <g>
-                                <mask id="mask-14" fill="white">
-                                    <use xlink:href="#path-13"></use>
-                                </mask>
-                                <g id="SVGID_8_"></g>
-                                <path d="M0.29,4.17 L0.29,63.61 C0.29,66.01 2.37,67.96 4.94,67.96 C7.51,67.96 9.59,66.01 9.59,63.61 L9.59,4.17 C9.59,1.77 7.51,-0.18 4.94,-0.18 C2.37,-0.18 0.29,1.77 0.29,4.17 L0.29,4.17 Z M8.13,4.58 L8.13,63.2 C8.13,64.96 6.7,66.4 4.93,66.4 C3.16,66.4 1.73,64.97 1.73,63.2 L1.73,4.58 C1.73,2.82 3.16,1.38 4.93,1.38 C6.7,1.38 8.13,2.82 8.13,4.58 L8.13,4.58 Z" id="Shape" fill="#000000" opacity="0.2" mask="url(#mask-14)"></path>
-                            </g>
-                        </g>
-                        <path d="M865.53,235.27 C865.53,253.4 880.23,268.1 898.36,268.1 C916.49,268.1 931.19,253.4 931.19,235.27 C931.19,217.14 916.49,202.44 898.36,202.44 C880.23,202.45 865.53,217.14 865.53,235.27 L865.53,235.27 Z M928.18,235.27 C928.18,251.74 914.83,265.09 898.36,265.09 C881.89,265.09 868.54,251.74 868.54,235.27 C868.54,218.8 881.89,205.45 898.36,205.45 C914.83,205.45 928.18,218.8 928.18,235.27 L928.18,235.27 Z" id="Shape" fill="url(#linearGradient-15)"></path>
-                    </g>
-                    <path d="M65.18,8.11 C32.08,8.11 5.24,34.94 5.24,68.05 L5.24,402.5 C5.24,435.6 32.07,462.44 65.18,462.44 L334.64,462.44 L598.74,8.11 L65.18,8.11 L65.18,8.11 Z" id="Shape" fill="url(#linearGradient-16)"></path>
-                </g>
-                <rect id="Rectangle-path" fill="#000000" x="108.69" y="28.81" width="736" height="414"></rect>
-            </g>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/iPhone6Plus-portrait.svg b/front_end/emulated_devices/iPhone6Plus-portrait.svg
deleted file mode 100644
index 683309f..0000000
--- a/front_end/emulated_devices/iPhone6Plus-portrait.svg
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="470px" height="954px" viewBox="0 0 470 954" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <title>iPhone 6 Plus</title>
-    <defs>
-        <linearGradient x1="50.0004402%" y1="-0.00765597003%" x2="50.0004402%" y2="99.9887604%" id="linearGradient-1">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="11.69%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="87.64%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="-28.8457617%" y1="28.2592375%" x2="128.846656%" y2="71.7422576%" id="linearGradient-2">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.05" offset="13.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.02" offset="88.31%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="100%"></stop>
-        </linearGradient>
-        <radialGradient cx="49.981457%" cy="49.9768212%" fx="49.981457%" fy="49.9768212%" r="49.9807947%" id="radialGradient-3">
-            <stop stop-color="#5D5D5F" offset="0%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.426664%" cy="57.0966105%" fx="50.426664%" fy="57.0966105%" r="49.9701987%" id="radialGradient-4">
-            <stop stop-color="#000000" stop-opacity="0" offset="0%"></stop>
-            <stop stop-color="#020202" stop-opacity="0.4119" offset="51.49%"></stop>
-            <stop stop-color="#090909" stop-opacity="0.5603" offset="70.03%"></stop>
-            <stop stop-color="#141414" stop-opacity="0.666" offset="83.25%"></stop>
-            <stop stop-color="#252525" stop-opacity="0.7509" offset="93.87%"></stop>
-            <stop stop-color="#333333" stop-opacity="0.8" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="47.6564342%" cy="96.2967075%" fx="47.6564342%" fy="96.2967075%" r="95.6970109%" id="radialGradient-5">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <radialGradient cx="50.6606714%" cy="23.7662009%" fx="50.6606714%" fy="23.7662009%" r="57.5643564%" id="radialGradient-6">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="0%"></stop>
-            <stop stop-color="#000000" stop-opacity="0" offset="100%"></stop>
-        </radialGradient>
-        <linearGradient x1="49.8466941%" y1="7.41101415%" x2="49.8485846%" y2="111.231014%" id="linearGradient-7">
-            <stop stop-color="#FFFFFF" stop-opacity="0.6" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.1" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-8" d="M63.42,9.02 L4.8,9.02 C2.43,9.02 0.51,7.1 0.51,4.73 L0.51,4.73 C0.51,2.36 2.43,0.44 4.8,0.44 L63.42,0.44 C65.79,0.44 67.71,2.36 67.71,4.73 L67.71,4.73 C67.7,7.1 65.78,9.02 63.42,9.02 L63.42,9.02 Z"></path>
-        <linearGradient x1="50.0105141%" y1="99.9084218%" x2="50.0105141%" y2="-0.0179701632%" id="linearGradient-10">
-            <stop stop-color="#2E2E31" offset="0%"></stop>
-            <stop stop-color="#616161" offset="24.48%"></stop>
-            <stop stop-color="#858585" offset="81.37%"></stop>
-            <stop stop-color="#2E2E31" offset="100%"></stop>
-        </linearGradient>
-        <path id="path-11" d="M63.42,9.02 L4.8,9.02 C2.43,9.02 0.51,7.1 0.51,4.73 L0.51,4.73 C0.51,2.36 2.43,0.44 4.8,0.44 L63.42,0.44 C65.79,0.44 67.71,2.36 67.71,4.73 L67.71,4.73 C67.7,7.1 65.78,9.02 63.42,9.02 L63.42,9.02 Z"></path>
-        <path id="path-13" d="M63.42,9.02 L4.8,9.02 C2.43,9.02 0.51,7.1 0.51,4.73 L0.51,4.73 C0.51,2.36 2.43,0.44 4.8,0.44 L63.42,0.44 C65.79,0.44 67.71,2.36 67.71,4.73 L67.71,4.73 C67.7,7.1 65.78,9.02 63.42,9.02 L63.42,9.02 Z"></path>
-        <linearGradient x1="86.3842522%" y1="91.8719159%" x2="14.0484313%" y2="8.61742309%" id="linearGradient-15">
-            <stop stop-color="#FFFFFF" stop-opacity="0.3" offset="14.7%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="40.73%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.00509108" offset="74.45%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0.2" offset="100%"></stop>
-        </linearGradient>
-        <linearGradient x1="-34.1635743%" y1="-2.09409175%" x2="28.8478289%" y2="36.9074705%" id="linearGradient-16">
-            <stop stop-color="#FFFFFF" stop-opacity="0.15" offset="0%"></stop>
-            <stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
-        </linearGradient>
-    </defs>
-    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="iphone6plus-portrait">
-            <g id="Group">
-                <path d="M5.73,144.54 L2.01,144.54 C0.98,144.54 0.15,143.71 0.15,142.68 L0.15,112.72 C0.15,111.69 0.98,110.86 2.01,110.86 L5.73,110.86 L5.73,144.54 L5.73,144.54 Z" id="Shape" fill="#808086"></path>
-                <path d="M0.15,187.77 C0.15,186.74 0.98,185.91 2.01,185.91 L5.73,185.91 L5.73,247.04 L2.01,247.04 C0.98,247.04 0.15,246.21 0.15,245.18" id="Shape" fill="#808086"></path>
-                <path d="M0.15,262.53 C0.15,261.5 0.98,260.67 2.01,260.67 L5.73,260.67 L5.73,321.8 L2.01,321.8 C0.98,321.8 0.15,320.97 0.15,319.94" id="Shape" fill="#808086"></path>
-                <path d="M464.27,187.27 L467.99,187.27 C469.02,187.27 469.85,188.1 469.85,189.13 L469.85,246.54 C469.85,247.57 469.02,248.4 467.99,248.4 L464.27,248.4 L464.27,187.27 L464.27,187.27 Z" id="Shape" fill="#818187"></path>
-                <g transform="translate(2.000000, 0.000000)" id="Shape">
-                    <path d="M65.5,953.05 C29.97,953.05 1.06,924.14 1.06,888.61 L1.06,64.98 C1.06,29.45 29.97,0.54 65.5,0.54 L399.96,0.54 C435.49,0.54 464.39,29.45 464.39,64.98 L464.39,888.61 C464.39,924.14 435.48,953.05 399.96,953.05 L65.5,953.05 L65.5,953.05 Z" fill="#B2B2B2"></path>
-                    <path d="M399.96,1.05 C435.21,1.05 463.89,29.73 463.89,64.99 L463.89,888.62 C463.89,923.87 435.21,952.56 399.96,952.56 L65.5,952.56 C30.25,952.56 1.56,923.88 1.56,888.62 L1.56,64.98 C1.56,29.73 30.24,1.04 65.5,1.04 L399.96,1.04 L399.96,1.05 Z M399.96,0.05 L65.5,0.05 C29.69,0.05 0.56,29.18 0.56,64.99 L0.56,888.62 C0.56,924.43 29.69,953.56 65.5,953.56 L399.96,953.56 C435.76,953.56 464.89,924.43 464.89,888.62 L464.89,64.98 C464.89,29.18 435.76,0.05 399.96,0.05 L399.96,0.05 L399.96,0.05 Z" fill="#666666"></path>
-                </g>
-                <path d="M401.95,948.55 L67.5,948.55 C34.4,948.55 7.56,921.72 7.56,888.61 L7.56,64.98 C7.56,31.88 34.39,5.04 67.5,5.04 L401.96,5.04 C435.06,5.04 461.9,31.87 461.9,64.98 L461.9,888.61 C461.89,921.71 435.06,948.55 401.95,948.55 L401.95,948.55 Z" id="Shape" fill="#262626"></path>
-                <path d="M402.14,5.05 L67.31,5.05 C34.31,5.05 7.56,31.8 7.56,64.8 L7.56,66.44 C7.56,33.44 34.31,6.69 67.31,6.69 L402.14,6.69 C435.14,6.69 461.89,33.44 461.89,66.44 L461.89,64.8 C461.89,31.8 435.14,5.05 402.14,5.05 L402.14,5.05 Z" id="Shape" fill="url(#linearGradient-1)"></path>
-                <path d="M402.14,8.59 L67.31,8.59 C36.32,8.59 11.11,33.8 11.11,64.79 L11.11,888.79 C11.11,919.78 36.32,944.99 67.31,944.99 L402.14,944.99 C433.13,944.99 458.34,919.78 458.34,888.79 L458.34,64.79 C458.34,33.81 433.13,8.59 402.14,8.59 L402.14,8.59 Z M452.34,888.8 C452.34,916.48 429.82,939 402.14,939 L67.31,939 C39.63,939 17.11,916.48 17.11,888.8 L17.11,64.8 C17.11,37.12 39.63,14.6 67.31,14.6 L402.14,14.6 C429.82,14.6 452.34,37.12 452.34,64.8 L452.34,888.8 L452.34,888.8 Z" id="Shape" fill="url(#linearGradient-2)"></path>
-                <g transform="translate(159.000000, 46.000000)">
-                    <circle id="Oval" fill="url(#radialGradient-3)" cx="7.8" cy="7.99" r="7.55"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-4)" opacity="0.8" cx="7.8" cy="7.99" r="7.55"></circle>
-                    <circle id="Oval" fill="#1B1A1F" cx="7.8" cy="7.99" r="5.03"></circle>
-                    <circle id="Oval" fill="#36284C" cx="7.8" cy="7.99" r="3.68"></circle>
-                    <circle id="Oval" fill="url(#radialGradient-5)" cx="7.8" cy="7.99" r="3.68"></circle>
-                    <g transform="translate(5.000000, 5.000000)" id="Shape">
-                        <path d="M4.82,2.99 C4.82,4.11 3.91,5.01 2.8,5.01 C1.68,5.01 0.78,4.1 0.78,2.99 C0.78,1.87 1.69,0.97 2.8,0.97 C3.91,0.96 4.82,1.87 4.82,2.99 L4.82,2.99 Z" fill="#141414" opacity="0.5"></path>
-                        <path d="M4.82,2.99 C4.82,4.11 3.91,5.01 2.8,5.01 C1.68,5.01 0.78,4.1 0.78,2.99 C0.78,1.87 1.69,0.97 2.8,0.97 C3.91,0.96 4.82,1.87 4.82,2.99 L4.82,2.99 Z" fill="url(#radialGradient-6)"></path>
-                    </g>
-                    <path d="M7.8,6.47 C7.35,6.47 6.96,6.67 6.68,6.98 L7.15,7.45 C7.31,7.26 7.53,7.14 7.79,7.14 C8.06,7.14 8.29,7.28 8.45,7.47 L8.92,6.99 C8.65,6.68 8.25,6.47 7.8,6.47 L7.8,6.47 Z" id="Shape" fill="url(#linearGradient-7)"></path>
-                </g>
-                <g transform="translate(201.000000, 50.000000)" id="Clipped">
-                    <g>
-                        <mask id="mask-9" fill="white">
-                            <use xlink:href="#path-8"></use>
-                        </mask>
-                        <g id="SVGID_9_"></g>
-                        <path d="M63.42,9.02 L4.8,9.02 C2.43,9.02 0.51,7.1 0.51,4.73 L0.51,4.73 C0.51,2.36 2.43,0.44 4.8,0.44 L63.42,0.44 C65.79,0.44 67.71,2.36 67.71,4.73 L67.71,4.73 C67.7,7.1 65.78,9.02 63.42,9.02 L63.42,9.02 Z" id="Shape" fill="url(#linearGradient-10)" opacity="0.8" mask="url(#mask-9)"></path>
-                    </g>
-                    <g>
-                        <mask id="mask-12" fill="white">
-                            <use xlink:href="#path-11"></use>
-                        </mask>
-                        <g id="SVGID_9_"></g>
-                        <path d="M1.92,0.33 L0.45,0.33 L0.45,1.8 L1.92,1.8 L1.92,0.33 L1.92,0.33 Z M4.85,0.33 L3.38,0.33 L3.38,1.8 L4.85,1.8 L4.85,0.33 L4.85,0.33 Z M7.79,0.33 L6.32,0.33 L6.32,1.8 L7.79,1.8 L7.79,0.33 L7.79,0.33 Z M10.72,0.33 L9.25,0.33 L9.25,1.8 L10.72,1.8 L10.72,0.33 L10.72,0.33 Z M13.66,0.33 L12.19,0.33 L12.19,1.8 L13.66,1.8 L13.66,0.33 L13.66,0.33 Z M16.59,0.33 L15.12,0.33 L15.12,1.8 L16.59,1.8 L16.59,0.33 L16.59,0.33 Z M19.53,0.33 L18.06,0.33 L18.06,1.8 L19.53,1.8 L19.53,0.33 L19.53,0.33 Z M22.46,0.33 L20.99,0.33 L20.99,1.8 L22.46,1.8 L22.46,0.33 L22.46,0.33 Z M25.4,0.33 L23.93,0.33 L23.93,1.8 L25.4,1.8 L25.4,0.33 L25.4,0.33 Z M28.33,0.33 L26.86,0.33 L26.86,1.8 L28.33,1.8 L28.33,0.33 L28.33,0.33 Z M31.27,0.33 L29.8,0.33 L29.8,1.8 L31.27,1.8 L31.27,0.33 L31.27,0.33 Z M34.2,0.33 L32.73,0.33 L32.73,1.8 L34.2,1.8 L34.2,0.33 L34.2,0.33 Z M37.14,0.33 L35.67,0.33 L35.67,1.8 L37.14,1.8 L37.14,0.33 L37.14,0.33 Z M40.07,0.33 L38.6,0.33 L38.6,1.8 L40.07,1.8 L40.07,0.33 L40.07,0.33 Z M43.01,0.33 L41.54,0.33 L41.54,1.8 L43.01,1.8 L43.01,0.33 L43.01,0.33 Z M45.94,0.33 L44.47,0.33 L44.47,1.8 L45.94,1.8 L45.94,0.33 L45.94,0.33 Z M48.88,0.33 L47.41,0.33 L47.41,1.8 L48.88,1.8 L48.88,0.33 L48.88,0.33 Z M51.81,0.33 L50.34,0.33 L50.34,1.8 L51.81,1.8 L51.81,0.33 L51.81,0.33 Z M54.75,0.33 L53.28,0.33 L53.28,1.8 L54.75,1.8 L54.75,0.33 L54.75,0.33 Z M57.68,0.33 L56.21,0.33 L56.21,1.8 L57.68,1.8 L57.68,0.33 L57.68,0.33 Z M60.62,0.33 L59.15,0.33 L59.15,1.8 L60.62,1.8 L60.62,0.33 L60.62,0.33 Z M63.55,0.33 L62.08,0.33 L62.08,1.8 L63.55,1.8 L63.55,0.33 L63.55,0.33 Z M66.49,0.33 L65.02,0.33 L65.02,1.8 L66.49,1.8 L66.49,0.33 L66.49,0.33 Z M3.39,1.79 L1.92,1.79 L1.92,3.26 L3.39,3.26 L3.39,1.79 L3.39,1.79 Z M6.32,1.79 L4.85,1.79 L4.85,3.26 L6.32,3.26 L6.32,1.79 L6.32,1.79 Z M9.26,1.79 L7.79,1.79 L7.79,3.26 L9.26,3.26 L9.26,1.79 L9.26,1.79 Z M12.19,1.79 L10.72,1.79 L10.72,3.26 L12.19,3.26 L12.19,1.79 L12.19,1.79 Z M15.13,1.79 L13.66,1.79 L13.66,3.26 L15.13,3.26 L15.13,1.79 L15.13,1.79 Z M18.06,1.79 L16.59,1.79 L16.59,3.26 L18.06,3.26 L18.06,1.79 L18.06,1.79 Z M20.99,1.79 L19.52,1.79 L19.52,3.26 L20.99,3.26 L20.99,1.79 L20.99,1.79 Z M23.93,1.79 L22.46,1.79 L22.46,3.26 L23.93,3.26 L23.93,1.79 L23.93,1.79 Z M26.86,1.79 L25.39,1.79 L25.39,3.26 L26.86,3.26 L26.86,1.79 L26.86,1.79 Z M29.8,1.79 L28.33,1.79 L28.33,3.26 L29.8,3.26 L29.8,1.79 L29.8,1.79 Z M32.73,1.79 L31.26,1.79 L31.26,3.26 L32.73,3.26 L32.73,1.79 L32.73,1.79 Z M35.67,1.79 L34.2,1.79 L34.2,3.26 L35.67,3.26 L35.67,1.79 L35.67,1.79 Z M38.6,1.79 L37.13,1.79 L37.13,3.26 L38.6,3.26 L38.6,1.79 L38.6,1.79 Z M41.54,1.79 L40.07,1.79 L40.07,3.26 L41.54,3.26 L41.54,1.79 L41.54,1.79 Z M44.47,1.79 L43,1.79 L43,3.26 L44.47,3.26 L44.47,1.79 L44.47,1.79 Z M47.41,1.79 L45.94,1.79 L45.94,3.26 L47.41,3.26 L47.41,1.79 L47.41,1.79 Z M50.34,1.79 L48.87,1.79 L48.87,3.26 L50.34,3.26 L50.34,1.79 L50.34,1.79 Z M53.28,1.79 L51.81,1.79 L51.81,3.26 L53.28,3.26 L53.28,1.79 L53.28,1.79 Z M56.21,1.79 L54.74,1.79 L54.74,3.26 L56.21,3.26 L56.21,1.79 L56.21,1.79 Z M59.15,1.79 L57.68,1.79 L57.68,3.26 L59.15,3.26 L59.15,1.79 L59.15,1.79 Z M62.08,1.79 L60.61,1.79 L60.61,3.26 L62.08,3.26 L62.08,1.79 L62.08,1.79 Z M65.02,1.79 L63.55,1.79 L63.55,3.26 L65.02,3.26 L65.02,1.79 L65.02,1.79 Z M67.95,1.79 L66.48,1.79 L66.48,3.26 L67.95,3.26 L67.95,1.79 L67.95,1.79 Z M1.92,3.26 L0.45,3.26 L0.45,4.73 L1.92,4.73 L1.92,3.26 L1.92,3.26 Z M4.85,3.26 L3.38,3.26 L3.38,4.73 L4.85,4.73 L4.85,3.26 L4.85,3.26 Z M7.79,3.26 L6.32,3.26 L6.32,4.73 L7.79,4.73 L7.79,3.26 L7.79,3.26 Z M10.72,3.26 L9.25,3.26 L9.25,4.73 L10.72,4.73 L10.72,3.26 L10.72,3.26 Z M13.66,3.26 L12.19,3.26 L12.19,4.73 L13.66,4.73 L13.66,3.26 L13.66,3.26 Z M16.59,3.26 L15.12,3.26 L15.12,4.73 L16.59,4.73 L16.59,3.26 L16.59,3.26 Z M19.53,3.26 L18.06,3.26 L18.06,4.73 L19.53,4.73 L19.53,3.26 L19.53,3.26 Z M22.46,3.26 L20.99,3.26 L20.99,4.73 L22.46,4.73 L22.46,3.26 L22.46,3.26 Z M25.4,3.26 L23.93,3.26 L23.93,4.73 L25.4,4.73 L25.4,3.26 L25.4,3.26 Z M28.33,3.26 L26.86,3.26 L26.86,4.73 L28.33,4.73 L28.33,3.26 L28.33,3.26 Z M31.27,3.26 L29.8,3.26 L29.8,4.73 L31.27,4.73 L31.27,3.26 L31.27,3.26 Z M34.2,3.26 L32.73,3.26 L32.73,4.73 L34.2,4.73 L34.2,3.26 L34.2,3.26 Z M37.14,3.26 L35.67,3.26 L35.67,4.73 L37.14,4.73 L37.14,3.26 L37.14,3.26 Z M40.07,3.26 L38.6,3.26 L38.6,4.73 L40.07,4.73 L40.07,3.26 L40.07,3.26 Z M43.01,3.26 L41.54,3.26 L41.54,4.73 L43.01,4.73 L43.01,3.26 L43.01,3.26 Z M45.94,3.26 L44.47,3.26 L44.47,4.73 L45.94,4.73 L45.94,3.26 L45.94,3.26 Z M48.88,3.26 L47.41,3.26 L47.41,4.73 L48.88,4.73 L48.88,3.26 L48.88,3.26 Z M51.81,3.26 L50.34,3.26 L50.34,4.73 L51.81,4.73 L51.81,3.26 L51.81,3.26 Z M54.75,3.26 L53.28,3.26 L53.28,4.73 L54.75,4.73 L54.75,3.26 L54.75,3.26 Z M57.68,3.26 L56.21,3.26 L56.21,4.73 L57.68,4.73 L57.68,3.26 L57.68,3.26 Z M60.62,3.26 L59.15,3.26 L59.15,4.73 L60.62,4.73 L60.62,3.26 L60.62,3.26 Z M63.55,3.26 L62.08,3.26 L62.08,4.73 L63.55,4.73 L63.55,3.26 L63.55,3.26 Z M66.49,3.26 L65.02,3.26 L65.02,4.73 L66.49,4.73 L66.49,3.26 L66.49,3.26 Z M3.39,4.73 L1.92,4.73 L1.92,6.2 L3.39,6.2 L3.39,4.73 L3.39,4.73 Z M6.32,4.73 L4.85,4.73 L4.85,6.2 L6.32,6.2 L6.32,4.73 L6.32,4.73 Z M9.26,4.73 L7.79,4.73 L7.79,6.2 L9.26,6.2 L9.26,4.73 L9.26,4.73 Z M12.19,4.73 L10.72,4.73 L10.72,6.2 L12.19,6.2 L12.19,4.73 L12.19,4.73 Z M15.13,4.73 L13.66,4.73 L13.66,6.2 L15.13,6.2 L15.13,4.73 L15.13,4.73 Z M18.06,4.73 L16.59,4.73 L16.59,6.2 L18.06,6.2 L18.06,4.73 L18.06,4.73 Z M20.99,4.73 L19.52,4.73 L19.52,6.2 L20.99,6.2 L20.99,4.73 L20.99,4.73 Z M23.93,4.73 L22.46,4.73 L22.46,6.2 L23.93,6.2 L23.93,4.73 L23.93,4.73 Z M26.86,4.73 L25.39,4.73 L25.39,6.2 L26.86,6.2 L26.86,4.73 L26.86,4.73 Z M29.8,4.73 L28.33,4.73 L28.33,6.2 L29.8,6.2 L29.8,4.73 L29.8,4.73 Z M32.73,4.73 L31.26,4.73 L31.26,6.2 L32.73,6.2 L32.73,4.73 L32.73,4.73 Z M35.67,4.73 L34.2,4.73 L34.2,6.2 L35.67,6.2 L35.67,4.73 L35.67,4.73 Z M38.6,4.73 L37.13,4.73 L37.13,6.2 L38.6,6.2 L38.6,4.73 L38.6,4.73 Z M41.54,4.73 L40.07,4.73 L40.07,6.2 L41.54,6.2 L41.54,4.73 L41.54,4.73 Z M44.47,4.73 L43,4.73 L43,6.2 L44.47,6.2 L44.47,4.73 L44.47,4.73 Z M47.41,4.73 L45.94,4.73 L45.94,6.2 L47.41,6.2 L47.41,4.73 L47.41,4.73 Z M50.34,4.73 L48.87,4.73 L48.87,6.2 L50.34,6.2 L50.34,4.73 L50.34,4.73 Z M53.28,4.73 L51.81,4.73 L51.81,6.2 L53.28,6.2 L53.28,4.73 L53.28,4.73 Z M56.21,4.73 L54.74,4.73 L54.74,6.2 L56.21,6.2 L56.21,4.73 L56.21,4.73 Z M59.15,4.73 L57.68,4.73 L57.68,6.2 L59.15,6.2 L59.15,4.73 L59.15,4.73 Z M62.08,4.73 L60.61,4.73 L60.61,6.2 L62.08,6.2 L62.08,4.73 L62.08,4.73 Z M65.02,4.73 L63.55,4.73 L63.55,6.2 L65.02,6.2 L65.02,4.73 L65.02,4.73 Z M67.95,4.73 L66.48,4.73 L66.48,6.2 L67.95,6.2 L67.95,4.73 L67.95,4.73 Z M1.92,6.2 L0.45,6.2 L0.45,7.67 L1.92,7.67 L1.92,6.2 L1.92,6.2 Z M4.85,6.2 L3.38,6.2 L3.38,7.67 L4.85,7.67 L4.85,6.2 L4.85,6.2 Z M7.79,6.2 L6.32,6.2 L6.32,7.67 L7.79,7.67 L7.79,6.2 L7.79,6.2 Z M10.72,6.2 L9.25,6.2 L9.25,7.67 L10.72,7.67 L10.72,6.2 L10.72,6.2 Z M13.66,6.2 L12.19,6.2 L12.19,7.67 L13.66,7.67 L13.66,6.2 L13.66,6.2 Z M16.59,6.2 L15.12,6.2 L15.12,7.67 L16.59,7.67 L16.59,6.2 L16.59,6.2 Z M19.53,6.2 L18.06,6.2 L18.06,7.67 L19.53,7.67 L19.53,6.2 L19.53,6.2 Z M22.46,6.2 L20.99,6.2 L20.99,7.67 L22.46,7.67 L22.46,6.2 L22.46,6.2 Z M25.4,6.2 L23.93,6.2 L23.93,7.67 L25.4,7.67 L25.4,6.2 L25.4,6.2 Z M28.33,6.2 L26.86,6.2 L26.86,7.67 L28.33,7.67 L28.33,6.2 L28.33,6.2 Z M31.27,6.2 L29.8,6.2 L29.8,7.67 L31.27,7.67 L31.27,6.2 L31.27,6.2 Z M34.2,6.2 L32.73,6.2 L32.73,7.67 L34.2,7.67 L34.2,6.2 L34.2,6.2 Z M37.14,6.2 L35.67,6.2 L35.67,7.67 L37.14,7.67 L37.14,6.2 L37.14,6.2 Z M40.07,6.2 L38.6,6.2 L38.6,7.67 L40.07,7.67 L40.07,6.2 L40.07,6.2 Z M43.01,6.2 L41.54,6.2 L41.54,7.67 L43.01,7.67 L43.01,6.2 L43.01,6.2 Z M45.94,6.2 L44.47,6.2 L44.47,7.67 L45.94,7.67 L45.94,6.2 L45.94,6.2 Z M48.88,6.2 L47.41,6.2 L47.41,7.67 L48.88,7.67 L48.88,6.2 L48.88,6.2 Z M51.81,6.2 L50.34,6.2 L50.34,7.67 L51.81,7.67 L51.81,6.2 L51.81,6.2 Z M54.75,6.2 L53.28,6.2 L53.28,7.67 L54.75,7.67 L54.75,6.2 L54.75,6.2 Z M57.68,6.2 L56.21,6.2 L56.21,7.67 L57.68,7.67 L57.68,6.2 L57.68,6.2 Z M60.62,6.2 L59.15,6.2 L59.15,7.67 L60.62,7.67 L60.62,6.2 L60.62,6.2 Z M63.55,6.2 L62.08,6.2 L62.08,7.67 L63.55,7.67 L63.55,6.2 L63.55,6.2 Z M66.49,6.2 L65.02,6.2 L65.02,7.67 L66.49,7.67 L66.49,6.2 L66.49,6.2 Z M3.39,7.66 L1.92,7.66 L1.92,9.13 L3.39,9.13 L3.39,7.66 L3.39,7.66 Z M6.32,7.66 L4.85,7.66 L4.85,9.13 L6.32,9.13 L6.32,7.66 L6.32,7.66 Z M9.26,7.66 L7.79,7.66 L7.79,9.13 L9.26,9.13 L9.26,7.66 L9.26,7.66 Z M12.19,7.66 L10.72,7.66 L10.72,9.13 L12.19,9.13 L12.19,7.66 L12.19,7.66 Z M15.13,7.66 L13.66,7.66 L13.66,9.13 L15.13,9.13 L15.13,7.66 L15.13,7.66 Z M18.06,7.66 L16.59,7.66 L16.59,9.13 L18.06,9.13 L18.06,7.66 L18.06,7.66 Z M20.99,7.66 L19.52,7.66 L19.52,9.13 L20.99,9.13 L20.99,7.66 L20.99,7.66 Z M23.93,7.66 L22.46,7.66 L22.46,9.13 L23.93,9.13 L23.93,7.66 L23.93,7.66 Z M26.86,7.66 L25.39,7.66 L25.39,9.13 L26.86,9.13 L26.86,7.66 L26.86,7.66 Z M29.8,7.66 L28.33,7.66 L28.33,9.13 L29.8,9.13 L29.8,7.66 L29.8,7.66 Z M32.73,7.66 L31.26,7.66 L31.26,9.13 L32.73,9.13 L32.73,7.66 L32.73,7.66 Z M35.67,7.66 L34.2,7.66 L34.2,9.13 L35.67,9.13 L35.67,7.66 L35.67,7.66 Z M38.6,7.66 L37.13,7.66 L37.13,9.13 L38.6,9.13 L38.6,7.66 L38.6,7.66 Z M41.54,7.66 L40.07,7.66 L40.07,9.13 L41.54,9.13 L41.54,7.66 L41.54,7.66 Z M44.47,7.66 L43,7.66 L43,9.13 L44.47,9.13 L44.47,7.66 L44.47,7.66 Z M47.41,7.66 L45.94,7.66 L45.94,9.13 L47.41,9.13 L47.41,7.66 L47.41,7.66 Z M50.34,7.66 L48.87,7.66 L48.87,9.13 L50.34,9.13 L50.34,7.66 L50.34,7.66 Z M53.28,7.66 L51.81,7.66 L51.81,9.13 L53.28,9.13 L53.28,7.66 L53.28,7.66 Z M56.21,7.66 L54.74,7.66 L54.74,9.13 L56.21,9.13 L56.21,7.66 L56.21,7.66 Z M59.15,7.66 L57.68,7.66 L57.68,9.13 L59.15,9.13 L59.15,7.66 L59.15,7.66 Z M62.08,7.66 L60.61,7.66 L60.61,9.13 L62.08,9.13 L62.08,7.66 L62.08,7.66 Z M65.02,7.66 L63.55,7.66 L63.55,9.13 L65.02,9.13 L65.02,7.66 L65.02,7.66 Z M67.95,7.66 L66.48,7.66 L66.48,9.13 L67.95,9.13 L67.95,7.66 L67.95,7.66 Z" id="Shape" fill="#2E2E2E" mask="url(#mask-12)"></path>
-                    </g>
-                    <g>
-                        <mask id="mask-14" fill="white">
-                            <use xlink:href="#path-13"></use>
-                        </mask>
-                        <g id="SVGID_9_"></g>
-                        <path d="M63.83,0.08 L4.39,0.08 C1.99,0.08 0.04,2.16 0.04,4.73 C0.04,7.3 1.99,9.38 4.39,9.38 L63.83,9.38 C66.23,9.38 68.18,7.3 68.18,4.73 C68.18,2.16 66.23,0.08 63.83,0.08 L63.83,0.08 Z M63.42,7.92 L4.8,7.92 C3.04,7.92 1.6,6.49 1.6,4.72 C1.6,2.95 3.03,1.52 4.8,1.52 L63.42,1.52 C65.18,1.52 66.62,2.95 66.62,4.72 C66.62,6.49 65.18,7.92 63.42,7.92 L63.42,7.92 Z" id="Shape" fill="#000000" opacity="0.2" mask="url(#mask-14)"></path>
-                    </g>
-                </g>
-                <path d="M234.73,865.33 C216.6,865.33 201.9,880.03 201.9,898.16 C201.9,916.29 216.6,930.99 234.73,930.99 C252.86,930.99 267.56,916.29 267.56,898.16 C267.56,880.03 252.86,865.33 234.73,865.33 L234.73,865.33 Z M234.73,927.98 C218.26,927.98 204.91,914.63 204.91,898.16 C204.91,881.69 218.26,868.34 234.73,868.34 C251.2,868.34 264.55,881.69 264.55,898.16 C264.55,914.62 251.2,927.98 234.73,927.98 L234.73,927.98 Z" id="Shape" fill="url(#linearGradient-15)"></path>
-                <path d="M69.89,8.59 C37.79,8.59 11.76,34.62 11.76,66.72 L11.76,571.87 L322.2,8.59 L69.89,8.59 L69.89,8.59 Z" id="Shape" fill="url(#linearGradient-16)"></path>
-            </g>
-            <rect id="Rectangle-path" fill="#000000" x="26" y="107" width="414" height="736"></rect>
-        </g>
-    </g>
-</svg>
diff --git a/front_end/emulated_devices/module.json b/front_end/emulated_devices/module.json
deleted file mode 100644
index f43a66b..0000000
--- a/front_end/emulated_devices/module.json
+++ /dev/null
@@ -1,1250 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "iPhone 4" ,
-                "screen": {
-                    "horizontal": {
-                        "width": 480,
-                        "height": 320
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 320,
-                        "height": 480
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 30,
-            "device": {
-                "show-by-default": true,
-                "title": "iPhone 5/SE",
-                "screen": {
-                    "horizontal": {
-                        "outline" : {
-                            "image": "@url(iPhone5-landscape.svg)",
-                            "insets" : { "left": 115, "top": 25, "right": 115, "bottom": 28 }
-                        },
-                        "width": 568,
-                        "height": 320
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "outline" : {
-                            "image": "@url(iPhone5-portrait.svg)",
-                            "insets" : { "left": 29, "top": 105, "right": 25, "bottom": 111 }
-                        },
-                        "width": 320,
-                        "height": 568
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 31,
-            "device": {
-                "show-by-default": true,
-                "title": "iPhone 6/7/8",
-                "screen": {
-                    "horizontal": {
-                        "outline" : {
-                            "image": "@url(iPhone6-landscape.svg)",
-                            "insets" : { "left": 106, "top": 28, "right": 106, "bottom": 28 }
-                        },
-                        "width": 667,
-                        "height": 375
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "outline" : {
-                            "image": "@url(iPhone6-portrait.svg)",
-                            "insets" : { "left": 28, "top": 105, "right": 28, "bottom": 105 }
-                        },
-                        "width": 375,
-                        "height": 667
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 32,
-            "device": {
-                "show-by-default": true,
-                "title": "iPhone 6/7/8 Plus",
-                "screen": {
-                    "horizontal": {
-                        "outline" : {
-                            "image": "@url(iPhone6Plus-landscape.svg)",
-                            "insets" : { "left": 109, "top": 29, "right": 109, "bottom": 27 }
-                        },
-                        "width": 736,
-                        "height": 414
-                    },
-                    "device-pixel-ratio": 3,
-                    "vertical": {
-                        "outline" : {
-                            "image": "@url(iPhone6Plus-portrait.svg)",
-                            "insets" : { "left": 26, "top": 107, "right": 30, "bottom": 111 }
-                        },
-                        "width": 414,
-                        "height": 736
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 33,
-            "device": {
-                "show-by-default": true,
-                "title": "iPhone X",
-                "screen": {
-                    "horizontal": {
-                        "width": 812,
-                        "height": 375
-                    },
-                    "device-pixel-ratio": 3,
-                    "vertical": {
-                        "width": 375,
-                        "height": 812
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "BlackBerry Z30",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nexus 4",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 384
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 384,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "title": "Nexus 5",
-                "type": "phone",
-                "user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "show-by-default": false,
-                "screen": {
-                    "device-pixel-ratio": 3,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    },
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    }
-                },
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 25, "right": 0, "bottom": 48 },
-                        "image": "@url(google-nexus-5-vertical-default-1x.png) 1x, @url(google-nexus-5-vertical-default-2x.png) 2x"
-                    },
-                    {
-                        "title": "navigation bar",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 80, "right": 0, "bottom": 48 },
-                        "image": "@url(google-nexus-5-vertical-navigation-1x.png) 1x, @url(google-nexus-5-vertical-navigation-2x.png) 2x"
-                    },
-                    {
-                        "title": "keyboard",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 80, "right": 0, "bottom": 312 },
-                        "image": "@url(google-nexus-5-vertical-keyboard-1x.png) 1x, @url(google-nexus-5-vertical-keyboard-2x.png) 2x"
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 25, "right": 42, "bottom": 0 },
-                        "image": "@url(google-nexus-5-horizontal-default-1x.png) 1x, @url(google-nexus-5-horizontal-default-2x.png) 2x"
-                    },
-                    {
-                        "title": "navigation bar",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 80, "right": 42, "bottom": 0 },
-                        "image": "@url(google-nexus-5-horizontal-navigation-1x.png) 1x, @url(google-nexus-5-horizontal-navigation-2x.png) 2x"
-                    },
-                    {
-                        "title": "keyboard",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 80, "right": 42, "bottom": 202 },
-                        "image": "@url(google-nexus-5-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5-horizontal-keyboard-2x.png) 2x"
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "title": "Nexus 5X",
-                "type": "phone",
-                "user-agent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "show-by-default": false,
-                "screen": {
-                    "device-pixel-ratio": 2.625,
-                    "vertical": {
-                        "outline" : {
-                            "image": "@url(Nexus5X-portrait.svg)",
-                            "insets" : { "left": 18, "top": 88, "right": 22, "bottom": 98 }
-                        },
-                        "width": 412,
-                        "height": 732
-                    },
-                    "horizontal": {
-                        "outline" : {
-                            "image": "@url(Nexus5X-landscape.svg)",
-                            "insets" : { "left": 88, "top": 21, "right": 98, "bottom": 19 }
-                        },
-                        "width": 732,
-                        "height": 412
-                    }
-                },
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 24, "right": 0, "bottom": 48 },
-                        "image": "@url(google-nexus-5x-vertical-default-1x.png) 1x, @url(google-nexus-5x-vertical-default-2x.png) 2x"
-                    },
-                    {
-                        "title": "navigation bar",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 80, "right": 0, "bottom": 48 },
-                        "image": "@url(google-nexus-5x-vertical-navigation-1x.png) 1x, @url(google-nexus-5x-vertical-navigation-2x.png) 2x"
-                    },
-                    {
-                        "title": "keyboard",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 80, "right": 0, "bottom": 342 },
-                        "image": "@url(google-nexus-5x-vertical-keyboard-1x.png) 1x, @url(google-nexus-5x-vertical-keyboard-2x.png) 2x"
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 24, "right": 48, "bottom": 0 },
-                        "image": "@url(google-nexus-5x-horizontal-default-1x.png) 1x, @url(google-nexus-5x-horizontal-default-2x.png) 2x"
-                    },
-                    {
-                        "title": "navigation bar",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 80, "right": 48, "bottom": 0 },
-                        "image": "@url(google-nexus-5x-horizontal-navigation-1x.png) 1x, @url(google-nexus-5x-horizontal-navigation-2x.png) 2x"
-                    },
-                    {
-                        "title": "keyboard",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 80, "right": 48, "bottom": 222 },
-                        "image": "@url(google-nexus-5x-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5x-horizontal-keyboard-2x.png) 2x"
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nexus 6",
-                "screen": {
-                    "horizontal": {
-                        "width": 732,
-                        "height": 412
-                    },
-                    "device-pixel-ratio": 3.5,
-                    "vertical": {
-                        "width": 412,
-                        "height": 732
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nexus 6P",
-                "screen": {
-                    "horizontal": {
-                        "outline" : {
-                            "image": "@url(Nexus6P-landscape.svg)",
-                            "insets" : { "left": 94, "top": 17, "right": 88, "bottom": 17 }
-                        },
-                        "width": 732,
-                        "height": 412
-                    },
-                    "device-pixel-ratio": 3.5,
-                    "vertical": {
-                        "outline" : {
-                            "image": "@url(Nexus6P-portrait.svg)",
-                            "insets" : { "left": 16, "top": 94, "right": 16, "bottom": 88 }
-                        },
-                        "width": 412,
-                        "height": 732
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 20,
-            "device": {
-                "show-by-default": true,
-                "title": "Pixel 2",
-                "screen": {
-                    "horizontal": {
-                        "width": 731,
-                        "height": 411
-                    },
-                    "device-pixel-ratio": 2.625,
-                    "vertical": {
-                        "width": 411,
-                        "height": 731
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 21,
-            "device": {
-                "show-by-default": true,
-                "title": "Pixel 2 XL",
-                "screen": {
-                    "horizontal": {
-                        "width": 823,
-                        "height": 411
-                    },
-                    "device-pixel-ratio": 3.5,
-                    "vertical": {
-                        "width": 411,
-                        "height": 823
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "LG Optimus L70",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 384
-                    },
-                    "device-pixel-ratio": 1.25,
-                    "vertical": {
-                        "width": 384,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nokia N9",
-                "screen": {
-                    "horizontal": {
-                        "width": 854,
-                        "height": 480
-                    },
-                    "device-pixel-ratio": 1,
-                    "vertical": {
-                        "width": 480,
-                        "height": 854
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nokia Lumia 520",
-                "screen": {
-                    "horizontal": {
-                        "width": 533,
-                        "height": 320
-                    },
-                    "device-pixel-ratio": 1.5,
-                    "vertical": {
-                        "width": 320,
-                        "height": 533
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Microsoft Lumia 550",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 640,
-                        "height": 360
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Microsoft Lumia 950",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 4,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Galaxy S III",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 10,
-            "device": {
-                "show-by-default": true,
-                "title": "Galaxy S5",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 3,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Kindle Fire HDX",
-                "screen": {
-                    "horizontal": {
-                        "width": 1280,
-                        "height": 800
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 800,
-                        "height": 1280
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "iPad Mini",
-                "screen": {
-                    "horizontal": {
-                        "width": 1024,
-                        "height": 768
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 768,
-                        "height": 1024
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 40,
-            "device": {
-                "show-by-default": true,
-                "title": "iPad",
-                "screen": {
-                    "horizontal": {
-                        "outline" : {
-                            "image": "@url(iPad-landscape.svg)",
-                            "insets" : { "left": 112, "top": 56, "right": 116, "bottom": 52 }
-                        },
-                        "width": 1024,
-                        "height": 768
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "outline" : {
-                            "image": "@url(iPad-portrait.svg)",
-                            "insets" : { "left": 52, "top": 114, "right": 55, "bottom": 114 }
-                        },
-                        "width": 768,
-                        "height": 1024
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "order": 41,
-            "device": {
-                "show-by-default": true,
-                "title": "iPad Pro",
-                "screen": {
-                    "horizontal": {
-                        "width": 1366,
-                        "height": 1024
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 1024,
-                        "height": 1366
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Blackberry PlayBook",
-                "screen": {
-                    "horizontal": {
-                        "width": 1024,
-                        "height": 600
-                    },
-                    "device-pixel-ratio": 1,
-                    "vertical": {
-                        "width": 600,
-                        "height": 1024
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nexus 10",
-                "screen": {
-                    "horizontal": {
-                        "width": 1280,
-                        "height": 800
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 800,
-                        "height": 1280
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Nexus 7",
-                "screen": {
-                    "horizontal": {
-                        "width": 960,
-                        "height": 600
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 600,
-                        "height": 960
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36",
-                "type": "tablet",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Galaxy Note 3",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 3,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Galaxy Note II",
-                "screen": {
-                    "horizontal": {
-                        "width": 640,
-                        "height": 360
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 360,
-                        "height": 640
-                    }
-                },
-                "capabilities": [
-                    "touch",
-                    "mobile"
-                ],
-                "user-agent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
-                "type": "phone",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "vertical",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    },
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Laptop with touch",
-                "screen": {
-                    "horizontal": {
-                        "width": 1280,
-                        "height": 950
-                    },
-                    "device-pixel-ratio": 1,
-                    "vertical": {
-                        "width": 950,
-                        "height": 1280
-                    }
-                },
-                "capabilities": [
-                    "touch"
-                ],
-                "user-agent": "",
-                "type": "notebook",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Laptop with HiDPI screen",
-                "screen": {
-                    "horizontal": {
-                        "width": 1440,
-                        "height": 900
-                    },
-                    "device-pixel-ratio": 2,
-                    "vertical": {
-                        "width": 900,
-                        "height": 1440
-                    }
-                },
-                "capabilities": [],
-                "user-agent": "",
-                "type": "notebook",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        },
-        {
-            "type": "emulated-device",
-            "device": {
-                "show-by-default": false,
-                "title": "Laptop with MDPI screen",
-                "screen": {
-                    "horizontal": {
-                        "width": 1280,
-                        "height": 800
-                    },
-                    "device-pixel-ratio": 1,
-                    "vertical": {
-                        "width": 800,
-                        "height": 1280
-                    }
-                },
-                "capabilities": [],
-                "user-agent": "",
-                "type": "notebook",
-                "modes": [
-                    {
-                        "title": "default",
-                        "orientation": "horizontal",
-                        "insets": { "left": 0, "top": 0, "right": 0, "bottom": 0 }
-                    }
-                ]
-            }
-        }
-    ],
-    "dependencies": [
-        "emulation"
-    ],
-    "scripts": [
-    ],
-    "resources": [
-    ]
-}
diff --git a/front_end/emulation/AdvancedApp.js b/front_end/emulation/AdvancedApp.js
deleted file mode 100644
index 80754b5..0000000
--- a/front_end/emulation/AdvancedApp.js
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Common.App}
- * @unrestricted
- */
-Emulation.AdvancedApp = class {
-  constructor() {
-    Components.dockController.addEventListener(
-        Components.DockController.Events.BeforeDockSideChanged, this._openToolboxWindow, this);
-  }
-
-  /**
-   * @return {!Emulation.AdvancedApp}
-   */
-  static _instance() {
-    if (!Emulation.AdvancedApp._appInstance)
-      Emulation.AdvancedApp._appInstance = new Emulation.AdvancedApp();
-    return Emulation.AdvancedApp._appInstance;
-  }
-
-  /**
-   * @override
-   * @param {!Document} document
-   */
-  presentUI(document) {
-    const rootView = new UI.RootView();
-
-    this._rootSplitWidget = new UI.SplitWidget(false, true, 'InspectorView.splitViewState', 555, 300, true);
-    this._rootSplitWidget.show(rootView.element);
-    this._rootSplitWidget.setSidebarWidget(UI.inspectorView);
-    this._rootSplitWidget.setDefaultFocusedChild(UI.inspectorView);
-    UI.inspectorView.setOwnerSplit(this._rootSplitWidget);
-
-    this._inspectedPagePlaceholder = Emulation.InspectedPagePlaceholder.instance();
-    this._inspectedPagePlaceholder.addEventListener(
-        Emulation.InspectedPagePlaceholder.Events.Update, this._onSetInspectedPageBounds.bind(this), this);
-    this._deviceModeView = new Emulation.DeviceModeWrapper(this._inspectedPagePlaceholder);
-
-    Components.dockController.addEventListener(
-        Components.DockController.Events.BeforeDockSideChanged, this._onBeforeDockSideChange, this);
-    Components.dockController.addEventListener(
-        Components.DockController.Events.DockSideChanged, this._onDockSideChange, this);
-    Components.dockController.addEventListener(
-        Components.DockController.Events.AfterDockSideChanged, this._onAfterDockSideChange, this);
-    this._onDockSideChange();
-
-    console.timeStamp('AdvancedApp.attachToBody');
-    rootView.attachToDocument(document);
-    rootView.focus();
-    this._inspectedPagePlaceholder.update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _openToolboxWindow(event) {
-    if (/** @type {string} */ (event.data.to) !== Components.DockController.State.Undocked)
-      return;
-
-    if (this._toolboxWindow)
-      return;
-
-    const url = window.location.href.replace('devtools_app.html', 'toolbox.html');
-    this._toolboxWindow = window.open(url, undefined);
-  }
-
-  /**
-   * @param {!Document} toolboxDocument
-   */
-  toolboxLoaded(toolboxDocument) {
-    UI.initializeUIUtils(toolboxDocument, Common.settings.createSetting('uiTheme', 'default'));
-    UI.installComponentRootStyles(/** @type {!Element} */ (toolboxDocument.body));
-    UI.ContextMenu.installHandler(toolboxDocument);
-    UI.Tooltip.installHandler(toolboxDocument);
-
-    this._toolboxRootView = new UI.RootView();
-    this._toolboxRootView.attachToDocument(toolboxDocument);
-
-    this._updateDeviceModeView();
-  }
-
-  _updateDeviceModeView() {
-    if (this._isDocked())
-      this._rootSplitWidget.setMainWidget(this._deviceModeView);
-    else if (this._toolboxRootView)
-      this._deviceModeView.show(this._toolboxRootView.element);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onBeforeDockSideChange(event) {
-    if (/** @type {string} */ (event.data.to) === Components.DockController.State.Undocked && this._toolboxRootView) {
-      // Hide inspectorView and force layout to mimic the undocked state.
-      this._rootSplitWidget.hideSidebar();
-      this._inspectedPagePlaceholder.update();
-    }
-
-    this._changingDockSide = true;
-  }
-
-  /**
-   * @param {!Common.Event=} event
-   */
-  _onDockSideChange(event) {
-    this._updateDeviceModeView();
-
-    const toDockSide = event ? /** @type {string} */ (event.data.to) : Components.dockController.dockSide();
-    if (toDockSide === Components.DockController.State.Undocked) {
-      this._updateForUndocked();
-    } else if (
-        this._toolboxRootView && event &&
-        /** @type {string} */ (event.data.from) === Components.DockController.State.Undocked) {
-      // Don't update yet for smooth transition.
-      this._rootSplitWidget.hideSidebar();
-    } else {
-      this._updateForDocked(toDockSide);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onAfterDockSideChange(event) {
-    // We may get here on the first dock side change while loading without BeforeDockSideChange.
-    if (!this._changingDockSide)
-      return;
-    if (/** @type {string} */ (event.data.from) === Components.DockController.State.Undocked) {
-      // Restore docked layout in case of smooth transition.
-      this._updateForDocked(/** @type {string} */ (event.data.to));
-    }
-    this._changingDockSide = false;
-    this._inspectedPagePlaceholder.update();
-  }
-
-  /**
-   * @param {string} dockSide
-   */
-  _updateForDocked(dockSide) {
-    this._rootSplitWidget.resizerElement().style.transform =
-        dockSide === Components.DockController.State.DockedToRight ?
-        'translateX(2px)' :
-        dockSide === Components.DockController.State.DockedToLeft ? 'translateX(-2px)' : '';
-    this._rootSplitWidget.setVertical(
-        dockSide === Components.DockController.State.DockedToRight ||
-        dockSide === Components.DockController.State.DockedToLeft);
-    this._rootSplitWidget.setSecondIsSidebar(
-        dockSide === Components.DockController.State.DockedToRight ||
-        dockSide === Components.DockController.State.DockedToBottom);
-    this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), true);
-    this._rootSplitWidget.toggleResizer(
-        UI.inspectorView.topResizerElement(), dockSide === Components.DockController.State.DockedToBottom);
-    this._rootSplitWidget.showBoth();
-  }
-
-  _updateForUndocked() {
-    this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(), false);
-    this._rootSplitWidget.toggleResizer(UI.inspectorView.topResizerElement(), false);
-    this._rootSplitWidget.hideMain();
-  }
-
-  _isDocked() {
-    return Components.dockController.dockSide() !== Components.DockController.State.Undocked;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onSetInspectedPageBounds(event) {
-    if (this._changingDockSide)
-      return;
-    const window = this._inspectedPagePlaceholder.element.window();
-    if (!window.innerWidth || !window.innerHeight)
-      return;
-    if (!this._inspectedPagePlaceholder.isShowing())
-      return;
-    const bounds = /** @type {{x: number, y: number, width: number, height: number}} */ (event.data);
-    console.timeStamp('AdvancedApp.setInspectedPageBounds');
-    InspectorFrontendHost.setInspectedPageBounds(bounds);
-  }
-};
-
-/** @type {!Emulation.AdvancedApp} */
-Emulation.AdvancedApp._appInstance;
-
-
-/**
- * @implements {Common.AppProvider}
- * @unrestricted
- */
-Emulation.AdvancedAppProvider = class {
-  /**
-   * @override
-   * @return {!Common.App}
-   */
-  createApp() {
-    return Emulation.AdvancedApp._instance();
-  }
-};
diff --git a/front_end/emulation/DeviceModeModel.js b/front_end/emulation/DeviceModeModel.js
deleted file mode 100644
index b84a8c6..0000000
--- a/front_end/emulation/DeviceModeModel.js
+++ /dev/null
@@ -1,727 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!SDK.EmulationModel>}
- * @extends {Common.Object}
- * @unrestricted
- */
-Emulation.DeviceModeModel = class extends Common.Object {
-  constructor() {
-    super();
-    this._screenRect = new UI.Rect(0, 0, 1, 1);
-    this._visiblePageRect = new UI.Rect(0, 0, 1, 1);
-    this._availableSize = new UI.Size(1, 1);
-    this._preferredSize = new UI.Size(1, 1);
-    this._initialized = false;
-    this._appliedDeviceSize = new UI.Size(1, 1);
-    this._appliedDeviceScaleFactor = window.devicePixelRatio;
-    this._appliedUserAgentType = Emulation.DeviceModeModel.UA.Desktop;
-
-    this._scaleSetting = Common.settings.createSetting('emulation.deviceScale', 1);
-    // We've used to allow zero before.
-    if (!this._scaleSetting.get())
-      this._scaleSetting.set(1);
-    this._scaleSetting.addChangeListener(this._scaleSettingChanged, this);
-
-    this._widthSetting = Common.settings.createSetting('emulation.deviceWidth', 400);
-    if (this._widthSetting.get() < Emulation.DeviceModeModel.MinDeviceSize)
-      this._widthSetting.set(Emulation.DeviceModeModel.MinDeviceSize);
-    if (this._widthSetting.get() > Emulation.DeviceModeModel.MaxDeviceSize)
-      this._widthSetting.set(Emulation.DeviceModeModel.MaxDeviceSize);
-    this._widthSetting.addChangeListener(this._widthSettingChanged, this);
-
-    this._heightSetting = Common.settings.createSetting('emulation.deviceHeight', 0);
-    if (this._heightSetting.get() && this._heightSetting.get() < Emulation.DeviceModeModel.MinDeviceSize)
-      this._heightSetting.set(Emulation.DeviceModeModel.MinDeviceSize);
-    if (this._heightSetting.get() > Emulation.DeviceModeModel.MaxDeviceSize)
-      this._heightSetting.set(Emulation.DeviceModeModel.MaxDeviceSize);
-    this._heightSetting.addChangeListener(this._heightSettingChanged, this);
-
-    this._uaSetting = Common.settings.createSetting('emulation.deviceUA', Emulation.DeviceModeModel.UA.Mobile);
-    this._uaSetting.addChangeListener(this._uaSettingChanged, this);
-    this._deviceScaleFactorSetting = Common.settings.createSetting('emulation.deviceScaleFactor', 0);
-    this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSettingChanged, this);
-
-    this._deviceOutlineSetting = Common.settings.moduleSetting('emulation.showDeviceOutline');
-    this._deviceOutlineSetting.addChangeListener(this._deviceOutlineSettingChanged, this);
-
-    this._toolbarControlsEnabledSetting =
-        Common.settings.createSetting('emulation.toolbarControlsEnabled', true, Common.SettingStorageType.Session);
-
-    /** @type {!Emulation.DeviceModeModel.Type} */
-    this._type = Emulation.DeviceModeModel.Type.None;
-    /** @type {?Emulation.EmulatedDevice} */
-    this._device = null;
-    /** @type {?Emulation.EmulatedDevice.Mode} */
-    this._mode = null;
-    /** @type {number} */
-    this._fitScale = 1;
-    this._touchEnabled = false;
-    this._touchMobile = false;
-
-    /** @type {?SDK.EmulationModel} */
-    this._emulationModel = null;
-    /** @type {?function()} */
-    this._onModelAvailable = null;
-    SDK.targetManager.observeModels(SDK.EmulationModel, this);
-  }
-
-  /**
-   * @param {string} value
-   * @return {boolean}
-   */
-  static deviceSizeValidator(value) {
-    if (/^[\d]+$/.test(value) && value >= Emulation.DeviceModeModel.MinDeviceSize &&
-        value <= Emulation.DeviceModeModel.MaxDeviceSize)
-      return true;
-    return false;
-  }
-
-  /**
-   * @param {string} value
-   * @return {boolean}
-   */
-  static deviceScaleFactorValidator(value) {
-    if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10))
-      return true;
-    return false;
-  }
-
-  /**
-   * @param {!UI.Size} availableSize
-   * @param {!UI.Size} preferredSize
-   */
-  setAvailableSize(availableSize, preferredSize) {
-    this._availableSize = availableSize;
-    this._preferredSize = preferredSize;
-    this._initialized = true;
-    this._calculateAndEmulate(false);
-  }
-
-  /**
-   * @param {!Emulation.DeviceModeModel.Type} type
-   * @param {?Emulation.EmulatedDevice} device
-   * @param {?Emulation.EmulatedDevice.Mode} mode
-   * @param {number=} scale
-   */
-  emulate(type, device, mode, scale) {
-    const resetPageScaleFactor = this._type !== type || this._device !== device || this._mode !== mode;
-    this._type = type;
-
-    if (type === Emulation.DeviceModeModel.Type.Device) {
-      console.assert(device && mode, 'Must pass device and mode for device emulation');
-      this._mode = mode;
-      this._device = device;
-      if (this._initialized) {
-        const orientation = device.orientationByName(mode.orientation);
-        this._scaleSetting.set(
-            scale ||
-            this._calculateFitScale(
-                orientation.width, orientation.height, this._currentOutline(), this._currentInsets()));
-      }
-    } else {
-      this._device = null;
-      this._mode = null;
-    }
-
-    if (type !== Emulation.DeviceModeModel.Type.None)
-      Host.userMetrics.actionTaken(Host.UserMetrics.Action.DeviceModeEnabled);
-    this._calculateAndEmulate(resetPageScaleFactor);
-  }
-
-  /**
-   * @param {number} width
-   */
-  setWidth(width) {
-    const max = Math.min(Emulation.DeviceModeModel.MaxDeviceSize, this._preferredScaledWidth());
-    width = Math.max(Math.min(width, max), 1);
-    this._widthSetting.set(width);
-  }
-
-  /**
-   * @param {number} width
-   */
-  setWidthAndScaleToFit(width) {
-    width = Math.max(Math.min(width, Emulation.DeviceModeModel.MaxDeviceSize), 1);
-    this._scaleSetting.set(this._calculateFitScale(width, this._heightSetting.get()));
-    this._widthSetting.set(width);
-  }
-
-  /**
-   * @param {number} height
-   */
-  setHeight(height) {
-    const max = Math.min(Emulation.DeviceModeModel.MaxDeviceSize, this._preferredScaledHeight());
-    height = Math.max(Math.min(height, max), 0);
-    if (height === this._preferredScaledHeight())
-      height = 0;
-    this._heightSetting.set(height);
-  }
-
-  /**
-   * @param {number} height
-   */
-  setHeightAndScaleToFit(height) {
-    height = Math.max(Math.min(height, Emulation.DeviceModeModel.MaxDeviceSize), 0);
-    this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(), height));
-    this._heightSetting.set(height);
-  }
-
-  /**
-   * @param {number} scale
-   */
-  setScale(scale) {
-    this._scaleSetting.set(scale);
-  }
-
-  /**
-   * @return {?Emulation.EmulatedDevice}
-   */
-  device() {
-    return this._device;
-  }
-
-  /**
-   * @return {?Emulation.EmulatedDevice.Mode}
-   */
-  mode() {
-    return this._mode;
-  }
-
-  /**
-   * @return {!Emulation.DeviceModeModel.Type}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {string}
-   */
-  screenImage() {
-    return (this._device && this._mode) ? this._device.modeImage(this._mode) : '';
-  }
-
-  /**
-   * @return {string}
-   */
-  outlineImage() {
-    return (this._device && this._mode && this._deviceOutlineSetting.get()) ? this._device.outlineImage(this._mode) :
-                                                                              '';
-  }
-
-  /**
-   * @return {!UI.Rect}
-   */
-  outlineRect() {
-    return this._outlineRect;
-  }
-
-  /**
-   * @return {!UI.Rect}
-   */
-  screenRect() {
-    return this._screenRect;
-  }
-
-  /**
-   * @return {!UI.Rect}
-   */
-  visiblePageRect() {
-    return this._visiblePageRect;
-  }
-
-  /**
-   * @return {number}
-   */
-  scale() {
-    return this._scale;
-  }
-
-  /**
-   * @return {number}
-   */
-  fitScale() {
-    return this._fitScale;
-  }
-
-  /**
-   * @return {!UI.Size}
-   */
-  appliedDeviceSize() {
-    return this._appliedDeviceSize;
-  }
-
-  /**
-   * @return {number}
-   */
-  appliedDeviceScaleFactor() {
-    return this._appliedDeviceScaleFactor;
-  }
-
-  /**
-   * @return {!Emulation.DeviceModeModel.UA}
-   */
-  appliedUserAgentType() {
-    return this._appliedUserAgentType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isFullHeight() {
-    return !this._heightSetting.get();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isMobile() {
-    switch (this._type) {
-      case Emulation.DeviceModeModel.Type.Device:
-        return this._device.mobile();
-      case Emulation.DeviceModeModel.Type.None:
-        return false;
-      case Emulation.DeviceModeModel.Type.Responsive:
-        return this._uaSetting.get() === Emulation.DeviceModeModel.UA.Mobile ||
-            this._uaSetting.get() === Emulation.DeviceModeModel.UA.MobileNoTouch;
-    }
-    return false;
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  enabledSetting() {
-    return Common.settings.createSetting('emulation.showDeviceMode', false);
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  scaleSetting() {
-    return this._scaleSetting;
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  uaSetting() {
-    return this._uaSetting;
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  deviceScaleFactorSetting() {
-    return this._deviceScaleFactorSetting;
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  deviceOutlineSetting() {
-    return this._deviceOutlineSetting;
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  toolbarControlsEnabledSetting() {
-    return this._toolbarControlsEnabledSetting;
-  }
-
-  reset() {
-    this._deviceScaleFactorSetting.set(0);
-    this._scaleSetting.set(1);
-    this.setWidth(400);
-    this.setHeight(0);
-    this._uaSetting.set(Emulation.DeviceModeModel.UA.Mobile);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.EmulationModel} emulationModel
-   */
-  modelAdded(emulationModel) {
-    if (!this._emulationModel && emulationModel.supportsDeviceEmulation()) {
-      this._emulationModel = emulationModel;
-      if (this._onModelAvailable) {
-        const callback = this._onModelAvailable;
-        this._onModelAvailable = null;
-        callback();
-      }
-    } else {
-      emulationModel.emulateTouch(this._touchEnabled, this._touchMobile);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!SDK.EmulationModel} emulationModel
-   */
-  modelRemoved(emulationModel) {
-    if (this._emulationModel === emulationModel)
-      this._emulationModel = null;
-  }
-
-  /**
-   * @return {?string}
-   */
-  inspectedURL() {
-    return this._emulationModel ? this._emulationModel.target().inspectedURL() : null;
-  }
-
-  _scaleSettingChanged() {
-    this._calculateAndEmulate(false);
-  }
-
-  _widthSettingChanged() {
-    this._calculateAndEmulate(false);
-  }
-
-  _heightSettingChanged() {
-    this._calculateAndEmulate(false);
-  }
-
-  _uaSettingChanged() {
-    this._calculateAndEmulate(true);
-  }
-
-  _deviceScaleFactorSettingChanged() {
-    this._calculateAndEmulate(false);
-  }
-
-  _deviceOutlineSettingChanged() {
-    this._calculateAndEmulate(false);
-  }
-
-  /**
-   * @return {number}
-   */
-  _preferredScaledWidth() {
-    return Math.floor(this._preferredSize.width / (this._scaleSetting.get() || 1));
-  }
-
-  /**
-   * @return {number}
-   */
-  _preferredScaledHeight() {
-    return Math.floor(this._preferredSize.height / (this._scaleSetting.get() || 1));
-  }
-
-  /**
-   * @return {!UI.Insets}
-   */
-  _currentOutline() {
-    let outline = new UI.Insets(0, 0, 0, 0);
-    if (this._type !== Emulation.DeviceModeModel.Type.Device)
-      return outline;
-    const orientation = this._device.orientationByName(this._mode.orientation);
-    if (this._deviceOutlineSetting.get())
-      outline = orientation.outlineInsets || outline;
-    return outline;
-  }
-
-  /**
-   * @return {!UI.Insets}
-   */
-  _currentInsets() {
-    if (this._type !== Emulation.DeviceModeModel.Type.Device)
-      return new UI.Insets(0, 0, 0, 0);
-    return this._mode.insets;
-  }
-
-  /**
-   * @param {boolean} resetPageScaleFactor
-   */
-  _calculateAndEmulate(resetPageScaleFactor) {
-    if (!this._emulationModel)
-      this._onModelAvailable = this._calculateAndEmulate.bind(this, resetPageScaleFactor);
-    const mobile = this._isMobile();
-    if (this._type === Emulation.DeviceModeModel.Type.Device) {
-      const orientation = this._device.orientationByName(this._mode.orientation);
-      const outline = this._currentOutline();
-      const insets = this._currentInsets();
-      this._fitScale = this._calculateFitScale(orientation.width, orientation.height, outline, insets);
-      if (mobile) {
-        this._appliedUserAgentType =
-            this._device.touch() ? Emulation.DeviceModeModel.UA.Mobile : Emulation.DeviceModeModel.UA.MobileNoTouch;
-      } else {
-        this._appliedUserAgentType =
-            this._device.touch() ? Emulation.DeviceModeModel.UA.DesktopTouch : Emulation.DeviceModeModel.UA.Desktop;
-      }
-      this._applyDeviceMetrics(
-          new UI.Size(orientation.width, orientation.height), insets, outline, this._scaleSetting.get(),
-          this._device.deviceScaleFactor, mobile, this._mode.orientation === Emulation.EmulatedDevice.Horizontal ?
-              Protocol.Emulation.ScreenOrientationType.LandscapePrimary :
-              Protocol.Emulation.ScreenOrientationType.PortraitPrimary,
-          resetPageScaleFactor);
-      this._applyUserAgent(this._device.userAgent);
-      this._applyTouch(this._device.touch(), mobile);
-    } else if (this._type === Emulation.DeviceModeModel.Type.None) {
-      this._fitScale = this._calculateFitScale(this._availableSize.width, this._availableSize.height);
-      this._appliedUserAgentType = Emulation.DeviceModeModel.UA.Desktop;
-      this._applyDeviceMetrics(
-          this._availableSize, new UI.Insets(0, 0, 0, 0), new UI.Insets(0, 0, 0, 0), 1, 0, mobile, null,
-          resetPageScaleFactor);
-      this._applyUserAgent('');
-      this._applyTouch(false, false);
-    } else if (this._type === Emulation.DeviceModeModel.Type.Responsive) {
-      let screenWidth = this._widthSetting.get();
-      if (!screenWidth || screenWidth > this._preferredScaledWidth())
-        screenWidth = this._preferredScaledWidth();
-      let screenHeight = this._heightSetting.get();
-      if (!screenHeight || screenHeight > this._preferredScaledHeight())
-        screenHeight = this._preferredScaledHeight();
-      const defaultDeviceScaleFactor = mobile ? Emulation.DeviceModeModel.defaultMobileScaleFactor : 0;
-      this._fitScale = this._calculateFitScale(this._widthSetting.get(), this._heightSetting.get());
-      this._appliedUserAgentType = this._uaSetting.get();
-      this._applyDeviceMetrics(
-          new UI.Size(screenWidth, screenHeight), new UI.Insets(0, 0, 0, 0), new UI.Insets(0, 0, 0, 0),
-          this._scaleSetting.get(), this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
-          screenHeight >= screenWidth ? Protocol.Emulation.ScreenOrientationType.PortraitPrimary :
-                                        Protocol.Emulation.ScreenOrientationType.LandscapePrimary,
-          resetPageScaleFactor);
-      this._applyUserAgent(mobile ? Emulation.DeviceModeModel._defaultMobileUserAgent : '');
-      this._applyTouch(
-          this._uaSetting.get() === Emulation.DeviceModeModel.UA.DesktopTouch ||
-              this._uaSetting.get() === Emulation.DeviceModeModel.UA.Mobile,
-          this._uaSetting.get() === Emulation.DeviceModeModel.UA.Mobile);
-    }
-    const overlayModel = this._emulationModel ? this._emulationModel.overlayModel() : null;
-    if (overlayModel)
-      overlayModel.setShowViewportSizeOnResize(this._type === Emulation.DeviceModeModel.Type.None);
-    this.dispatchEventToListeners(Emulation.DeviceModeModel.Events.Updated);
-  }
-
-  /**
-   * @param {number} screenWidth
-   * @param {number} screenHeight
-   * @param {!UI.Insets=} outline
-   * @param {!UI.Insets=} insets
-   * @return {number}
-   */
-  _calculateFitScale(screenWidth, screenHeight, outline, insets) {
-    const outlineWidth = outline ? outline.left + outline.right : 0;
-    const outlineHeight = outline ? outline.top + outline.bottom : 0;
-    const insetsWidth = insets ? insets.left + insets.right : 0;
-    const insetsHeight = insets ? insets.top + insets.bottom : 0;
-    let scale = Math.min(
-        screenWidth ? this._preferredSize.width / (screenWidth + outlineWidth) : 1,
-        screenHeight ? this._preferredSize.height / (screenHeight + outlineHeight) : 1);
-    scale = Math.min(Math.floor(scale * 100), 100);
-
-    let sharpScale = scale;
-    while (sharpScale > scale * 0.7) {
-      let sharp = true;
-      if (screenWidth)
-        sharp = sharp && Number.isInteger((screenWidth - insetsWidth) * sharpScale / 100);
-      if (screenHeight)
-        sharp = sharp && Number.isInteger((screenHeight - insetsHeight) * sharpScale / 100);
-      if (sharp)
-        return sharpScale / 100;
-      sharpScale -= 1;
-    }
-    return scale / 100;
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  setSizeAndScaleToFit(width, height) {
-    this._scaleSetting.set(this._calculateFitScale(width, height));
-    this.setWidth(width);
-    this.setHeight(height);
-  }
-
-  /**
-   * @param {string} userAgent
-   */
-  _applyUserAgent(userAgent) {
-    SDK.multitargetNetworkManager.setUserAgentOverride(userAgent);
-  }
-
-  /**
-   * @param {!UI.Size} screenSize
-   * @param {!UI.Insets} insets
-   * @param {!UI.Insets} outline
-   * @param {number} scale
-   * @param {number} deviceScaleFactor
-   * @param {boolean} mobile
-   * @param {?Protocol.Emulation.ScreenOrientationType} screenOrientation
-   * @param {boolean} resetPageScaleFactor
-   */
-  _applyDeviceMetrics(
-      screenSize,
-      insets,
-      outline,
-      scale,
-      deviceScaleFactor,
-      mobile,
-      screenOrientation,
-      resetPageScaleFactor) {
-    screenSize.width = Math.max(1, Math.floor(screenSize.width));
-    screenSize.height = Math.max(1, Math.floor(screenSize.height));
-
-    let pageWidth = screenSize.width - insets.left - insets.right;
-    let pageHeight = screenSize.height - insets.top - insets.bottom;
-    this._emulatedPageSize = new UI.Size(pageWidth, pageHeight);
-
-    const positionX = insets.left;
-    const positionY = insets.top;
-    const screenOrientationAngle =
-        screenOrientation === Protocol.Emulation.ScreenOrientationType.LandscapePrimary ? 90 : 0;
-
-    this._appliedDeviceSize = screenSize;
-    this._appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
-    this._screenRect = new UI.Rect(
-        Math.max(0, (this._availableSize.width - screenSize.width * scale) / 2), outline.top * scale,
-        screenSize.width * scale, screenSize.height * scale);
-    this._outlineRect = new UI.Rect(
-        this._screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale,
-        (outline.top + screenSize.height + outline.bottom) * scale);
-    this._visiblePageRect = new UI.Rect(
-        positionX * scale, positionY * scale,
-        Math.min(pageWidth * scale, this._availableSize.width - this._screenRect.left - positionX * scale),
-        Math.min(pageHeight * scale, this._availableSize.height - this._screenRect.top - positionY * scale));
-    this._scale = scale;
-
-    if (scale === 1 && this._availableSize.width >= screenSize.width &&
-        this._availableSize.height >= screenSize.height) {
-      // When we have enough space, no page size override is required. This will speed things up and remove lag.
-      pageWidth = 0;
-      pageHeight = 0;
-    }
-    if (this._visiblePageRect.width === pageWidth * scale && this._visiblePageRect.height === pageHeight * scale &&
-        Number.isInteger(pageWidth * scale) && Number.isInteger(pageHeight * scale)) {
-      // When we only have to apply scale, do not resize the page. This will speed things up and remove lag.
-      pageWidth = 0;
-      pageHeight = 0;
-    }
-
-    if (!this._emulationModel)
-      return;
-
-    if (resetPageScaleFactor)
-      this._emulationModel.resetPageScaleFactor();
-    if (pageWidth || pageHeight || mobile || deviceScaleFactor || scale !== 1 || screenOrientation) {
-      const metrics = {
-        width: pageWidth,
-        height: pageHeight,
-        deviceScaleFactor: deviceScaleFactor,
-        mobile: mobile,
-        scale: scale,
-        screenWidth: screenSize.width,
-        screenHeight: screenSize.height,
-        positionX: positionX,
-        positionY: positionY,
-        dontSetVisibleSize: true
-      };
-      if (screenOrientation)
-        metrics.screenOrientation = {type: screenOrientation, angle: screenOrientationAngle};
-      this._emulationModel.emulateDevice(metrics);
-    } else {
-      this._emulationModel.emulateDevice(null);
-    }
-  }
-
-  /**
-   * @param {boolean} fullSize
-   * @param {!Protocol.Page.Viewport=} clip
-   * @return {!Promise<?string>}
-   */
-  async captureScreenshot(fullSize, clip) {
-    const screenCaptureModel =
-        this._emulationModel ? this._emulationModel.target().model(SDK.ScreenCaptureModel) : null;
-    if (!screenCaptureModel)
-      return null;
-
-    const overlayModel = this._emulationModel ? this._emulationModel.overlayModel() : null;
-    if (overlayModel)
-      overlayModel.setShowViewportSizeOnResize(false);
-
-    // Emulate full size device if necessary.
-    let deviceMetrics;
-    if (fullSize) {
-      const metrics = await screenCaptureModel.fetchLayoutMetrics();
-      if (!metrics)
-        return null;
-      deviceMetrics = {
-        width: Math.floor(metrics.contentWidth),
-        height: Math.floor(metrics.contentHeight),
-        deviceScaleFactor: this._appliedDeviceScaleFactor,
-        mobile: this._isMobile(),
-      };
-      clip = {x: 0, y: 0, width: deviceMetrics.width, height: deviceMetrics.height, scale: 1};
-
-      if (this._device) {
-        const screenOrientation = this._mode.orientation === Emulation.EmulatedDevice.Horizontal ?
-            Protocol.Emulation.ScreenOrientationType.LandscapePrimary :
-            Protocol.Emulation.ScreenOrientationType.PortraitPrimary;
-        const screenOrientationAngle =
-            screenOrientation === Protocol.Emulation.ScreenOrientationType.LandscapePrimary ? 90 : 0;
-        deviceMetrics.screenOrientation = {type: screenOrientation, angle: screenOrientationAngle};
-      }
-      await this._emulationModel.resetPageScaleFactor();
-      await this._emulationModel.emulateDevice(deviceMetrics);
-    }
-    const screenshot = await screenCaptureModel.captureScreenshot('png', 100, clip);
-    if (fullSize) {
-      if (this._device) {
-        const orientation = this._device.orientationByName(this._mode.orientation);
-        deviceMetrics.width = orientation.width;
-        deviceMetrics.height = orientation.height;
-      } else {
-        deviceMetrics.width = 0;
-        deviceMetrics.height = 0;
-      }
-      await this._emulationModel.emulateDevice(deviceMetrics);
-    }
-    this._calculateAndEmulate(false);
-    return screenshot;
-  }
-
-  /**
-   * @param {boolean} touchEnabled
-   * @param {boolean} mobile
-   */
-  _applyTouch(touchEnabled, mobile) {
-    this._touchEnabled = touchEnabled;
-    this._touchMobile = mobile;
-    for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-      emulationModel.emulateTouch(touchEnabled, mobile);
-  }
-};
-
-/** @enum {string} */
-Emulation.DeviceModeModel.Events = {
-  Updated: 'Updated'
-};
-
-/** @enum {string} */
-Emulation.DeviceModeModel.Type = {
-  None: 'None',
-  Responsive: 'Responsive',
-  Device: 'Device'
-};
-
-/** @enum {string} */
-Emulation.DeviceModeModel.UA = {
-  Mobile: Common.UIString('Mobile'),
-  MobileNoTouch: Common.UIString('Mobile (no touch)'),
-  Desktop: Common.UIString('Desktop'),
-  DesktopTouch: Common.UIString('Desktop (touch)')
-};
-
-Emulation.DeviceModeModel.MinDeviceSize = 50;
-Emulation.DeviceModeModel.MaxDeviceSize = 9999;
-
-
-Emulation.DeviceModeModel._defaultMobileUserAgent =
-    'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';
-Emulation.DeviceModeModel._defaultMobileUserAgent =
-    SDK.MultitargetNetworkManager.patchUserAgentWithChromeVersion(Emulation.DeviceModeModel._defaultMobileUserAgent);
-Emulation.DeviceModeModel.defaultMobileScaleFactor = 2;
diff --git a/front_end/emulation/DeviceModeToolbar.js b/front_end/emulation/DeviceModeToolbar.js
deleted file mode 100644
index 5656330..0000000
--- a/front_end/emulation/DeviceModeToolbar.js
+++ /dev/null
@@ -1,609 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Emulation.DeviceModeToolbar = class {
-  /**
-   * @param {!Emulation.DeviceModeModel} model
-   * @param {!Common.Setting} showMediaInspectorSetting
-   * @param {!Common.Setting} showRulersSetting
-   */
-  constructor(model, showMediaInspectorSetting, showRulersSetting) {
-    this._model = model;
-    this._showMediaInspectorSetting = showMediaInspectorSetting;
-    this._showRulersSetting = showRulersSetting;
-
-    this._deviceOutlineSetting = this._model.deviceOutlineSetting();
-    this._showDeviceScaleFactorSetting = Common.settings.createSetting('emulation.showDeviceScaleFactor', false);
-    this._showDeviceScaleFactorSetting.addChangeListener(this._updateDeviceScaleFactorVisibility, this);
-
-    this._showUserAgentTypeSetting = Common.settings.createSetting('emulation.showUserAgentType', false);
-    this._showUserAgentTypeSetting.addChangeListener(this._updateUserAgentTypeVisibility, this);
-
-    this._autoAdjustScaleSetting = Common.settings.createSetting('emulation.autoAdjustScale', true);
-
-    /** @type {!Map<!Emulation.EmulatedDevice, !Emulation.EmulatedDevice.Mode>} */
-    this._lastMode = new Map();
-
-    this._element = createElementWithClass('div', 'device-mode-toolbar');
-
-    const leftContainer = this._element.createChild('div', 'device-mode-toolbar-spacer');
-    leftContainer.createChild('div', 'device-mode-toolbar-spacer');
-    const leftToolbar = new UI.Toolbar('', leftContainer);
-    leftToolbar.makeWrappable();
-    this._fillLeftToolbar(leftToolbar);
-
-    const mainToolbar = new UI.Toolbar('', this._element);
-    mainToolbar.makeWrappable();
-    this._fillMainToolbar(mainToolbar);
-
-    const rightContainer = this._element.createChild('div', 'device-mode-toolbar-spacer');
-    const rightToolbar = new UI.Toolbar('device-mode-toolbar-fixed-size', rightContainer);
-    rightToolbar.makeWrappable();
-    this._fillRightToolbar(rightToolbar);
-    const modeToolbar = new UI.Toolbar('device-mode-toolbar-fixed-size', rightContainer);
-    modeToolbar.makeWrappable();
-    this._fillModeToolbar(modeToolbar);
-    rightContainer.createChild('div', 'device-mode-toolbar-spacer');
-    const optionsToolbar = new UI.Toolbar('device-mode-toolbar-options', rightContainer);
-    optionsToolbar.makeWrappable(true);
-    this._fillOptionsToolbar(optionsToolbar);
-
-    this._emulatedDevicesList = Emulation.EmulatedDevicesList.instance();
-    this._emulatedDevicesList.addEventListener(
-        Emulation.EmulatedDevicesList.Events.CustomDevicesUpdated, this._deviceListChanged, this);
-    this._emulatedDevicesList.addEventListener(
-        Emulation.EmulatedDevicesList.Events.StandardDevicesUpdated, this._deviceListChanged, this);
-
-    this._persistenceSetting =
-        Common.settings.createSetting('emulation.deviceModeValue', {device: '', orientation: '', mode: ''});
-
-    this._model.toolbarControlsEnabledSetting().addChangeListener(updateToolbarsEnabled);
-    updateToolbarsEnabled();
-
-    function updateToolbarsEnabled() {
-      const enabled = model.toolbarControlsEnabledSetting().get();
-      leftToolbar.setEnabled(enabled);
-      mainToolbar.setEnabled(enabled);
-      rightToolbar.setEnabled(enabled);
-      modeToolbar.setEnabled(enabled);
-      optionsToolbar.setEnabled(enabled);
-    }
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   */
-  _fillLeftToolbar(toolbar) {
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
-    this._deviceSelectItem = new UI.ToolbarMenuButton(this._appendDeviceMenuItems.bind(this));
-    this._deviceSelectItem.setGlyph('');
-    this._deviceSelectItem.turnIntoSelect(95);
-    this._deviceSelectItem.setDarkText();
-    toolbar.appendToolbarItem(this._deviceSelectItem);
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   */
-  _fillMainToolbar(toolbar) {
-    const widthInput = UI.createInput('device-mode-size-input', 'text');
-    widthInput.maxLength = 4;
-    widthInput.title = Common.UIString('Width');
-    this._updateWidthInput =
-        UI.bindInput(widthInput, this._applyWidth.bind(this), Emulation.DeviceModeModel.deviceSizeValidator, true);
-    this._widthInput = widthInput;
-    this._widthItem = this._wrapToolbarItem(widthInput);
-    toolbar.appendToolbarItem(this._widthItem);
-
-    const xElement = createElementWithClass('div', 'device-mode-x');
-    xElement.textContent = '\u00D7';
-    this._xItem = this._wrapToolbarItem(xElement);
-    toolbar.appendToolbarItem(this._xItem);
-
-    const heightInput = UI.createInput('device-mode-size-input', 'text');
-    heightInput.maxLength = 4;
-    heightInput.title = Common.UIString('Height (leave empty for full)');
-    this._updateHeightInput = UI.bindInput(heightInput, this._applyHeight.bind(this), validateHeight, true);
-    this._heightInput = heightInput;
-    this._heightItem = this._wrapToolbarItem(heightInput);
-    toolbar.appendToolbarItem(this._heightItem);
-
-    /**
-     * @param {string} value
-     * @return {boolean}
-     */
-    function validateHeight(value) {
-      return !value || Emulation.DeviceModeModel.deviceSizeValidator(value);
-    }
-  }
-
-  /**
-   * @param {string} value
-   */
-  _applyWidth(value) {
-    const width = value ? Number(value) : 0;
-    this._model.setWidthAndScaleToFit(width);
-  }
-
-  /**
-   * @param {string} value
-   */
-  _applyHeight(value) {
-    const height = value ? Number(value) : 0;
-    this._model.setHeightAndScaleToFit(height);
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   */
-  _fillRightToolbar(toolbar) {
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
-    this._scaleItem = new UI.ToolbarMenuButton(this._appendScaleMenuItems.bind(this));
-    this._scaleItem.setTitle(Common.UIString('Zoom'));
-    this._scaleItem.setGlyph('');
-    this._scaleItem.turnIntoSelect();
-    this._scaleItem.setDarkText();
-    toolbar.appendToolbarItem(this._scaleItem);
-
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
-    this._deviceScaleItem = new UI.ToolbarMenuButton(this._appendDeviceScaleMenuItems.bind(this));
-    this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());
-    this._deviceScaleItem.setTitle(Common.UIString('Device pixel ratio'));
-    this._deviceScaleItem.setGlyph('');
-    this._deviceScaleItem.turnIntoSelect();
-    this._deviceScaleItem.setDarkText();
-    toolbar.appendToolbarItem(this._deviceScaleItem);
-
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
-    this._uaItem = new UI.ToolbarMenuButton(this._appendUserAgentMenuItems.bind(this));
-    this._uaItem.setVisible(this._showUserAgentTypeSetting.get());
-    this._uaItem.setTitle(Common.UIString('Device type'));
-    this._uaItem.setGlyph('');
-    this._uaItem.turnIntoSelect();
-    this._uaItem.setDarkText();
-    toolbar.appendToolbarItem(this._uaItem);
-
-    this._throttlingConditionsItem = MobileThrottling.throttlingManager().createMobileThrottlingButton();
-    toolbar.appendToolbarItem(this._throttlingConditionsItem);
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   */
-  _fillModeToolbar(toolbar) {
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
-    this._modeButton = new UI.ToolbarButton('', 'largeicon-rotate-screen');
-    this._modeButton.addEventListener(UI.ToolbarButton.Events.Click, this._modeMenuClicked, this);
-    toolbar.appendToolbarItem(this._modeButton);
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   */
-  _fillOptionsToolbar(toolbar) {
-    const moreOptionsButton = new UI.ToolbarMenuButton(this._appendOptionsMenuItems.bind(this));
-    moreOptionsButton.setTitle(Common.UIString('More options'));
-    toolbar.appendToolbarItem(moreOptionsButton);
-
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _appendScaleMenuItems(contextMenu) {
-    if (this._model.type() === Emulation.DeviceModeModel.Type.Device) {
-      contextMenu.footerSection().appendItem(
-          Common.UIString('Fit to window (%.0f%%)', this._model.fitScale() * 100),
-          this._onScaleMenuChanged.bind(this, this._model.fitScale()), false);
-    }
-    contextMenu.footerSection().appendCheckboxItem(
-        ls`Auto-adjust zoom`, this._onAutoAdjustScaleChanged.bind(this), this._autoAdjustScaleSetting.get());
-    const boundAppendScaleItem = appendScaleItem.bind(this);
-    boundAppendScaleItem(Common.UIString('50%'), 0.5);
-    boundAppendScaleItem(Common.UIString('75%'), 0.75);
-    boundAppendScaleItem(Common.UIString('100%'), 1);
-    boundAppendScaleItem(Common.UIString('125%'), 1.25);
-    boundAppendScaleItem(Common.UIString('150%'), 1.5);
-
-    /**
-     * @param {string} title
-     * @param {number} value
-     * @this {!Emulation.DeviceModeToolbar}
-     */
-    function appendScaleItem(title, value) {
-      contextMenu.defaultSection().appendCheckboxItem(
-          title, this._onScaleMenuChanged.bind(this, value), this._model.scaleSetting().get() === value, false);
-    }
-  }
-
-  /**
-   * @param {number} value
-   */
-  _onScaleMenuChanged(value) {
-    this._model.scaleSetting().set(value);
-  }
-
-  _onAutoAdjustScaleChanged() {
-    this._autoAdjustScaleSetting.set(!this._autoAdjustScaleSetting.get());
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _appendDeviceScaleMenuItems(contextMenu) {
-    const deviceScaleFactorSetting = this._model.deviceScaleFactorSetting();
-    const defaultValue = this._model.uaSetting().get() === Emulation.DeviceModeModel.UA.Mobile ||
-            this._model.uaSetting().get() === Emulation.DeviceModeModel.UA.MobileNoTouch ?
-        Emulation.DeviceModeModel.defaultMobileScaleFactor :
-        window.devicePixelRatio;
-    appendDeviceScaleFactorItem(contextMenu.headerSection(), Common.UIString('Default: %.1f', defaultValue), 0);
-    appendDeviceScaleFactorItem(contextMenu.defaultSection(), Common.UIString('1'), 1);
-    appendDeviceScaleFactorItem(contextMenu.defaultSection(), Common.UIString('2'), 2);
-    appendDeviceScaleFactorItem(contextMenu.defaultSection(), Common.UIString('3'), 3);
-
-    /**
-     * @param {!UI.ContextMenuSection} section
-     * @param {string} title
-     * @param {number} value
-     */
-    function appendDeviceScaleFactorItem(section, title, value) {
-      section.appendCheckboxItem(
-          title, deviceScaleFactorSetting.set.bind(deviceScaleFactorSetting, value),
-          deviceScaleFactorSetting.get() === value);
-    }
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _appendUserAgentMenuItems(contextMenu) {
-    const uaSetting = this._model.uaSetting();
-    appendUAItem(Emulation.DeviceModeModel.UA.Mobile, Emulation.DeviceModeModel.UA.Mobile);
-    appendUAItem(Emulation.DeviceModeModel.UA.MobileNoTouch, Emulation.DeviceModeModel.UA.MobileNoTouch);
-    appendUAItem(Emulation.DeviceModeModel.UA.Desktop, Emulation.DeviceModeModel.UA.Desktop);
-    appendUAItem(Emulation.DeviceModeModel.UA.DesktopTouch, Emulation.DeviceModeModel.UA.DesktopTouch);
-
-    /**
-     * @param {string} title
-     * @param {!Emulation.DeviceModeModel.UA} value
-     */
-    function appendUAItem(title, value) {
-      contextMenu.defaultSection().appendCheckboxItem(
-          title, uaSetting.set.bind(uaSetting, value), uaSetting.get() === value);
-    }
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _appendOptionsMenuItems(contextMenu) {
-    const model = this._model;
-    appendToggleItem(
-        contextMenu.headerSection(), this._deviceOutlineSetting, Common.UIString('Hide device frame'),
-        Common.UIString('Show device frame'), model.type() !== Emulation.DeviceModeModel.Type.Device);
-    appendToggleItem(
-        contextMenu.headerSection(), this._showMediaInspectorSetting, Common.UIString('Hide media queries'),
-        Common.UIString('Show media queries'));
-    appendToggleItem(
-        contextMenu.headerSection(), this._showRulersSetting, Common.UIString('Hide rulers'),
-        Common.UIString('Show rulers'));
-    appendToggleItem(
-        contextMenu.defaultSection(), this._showDeviceScaleFactorSetting, Common.UIString('Remove device pixel ratio'),
-        Common.UIString('Add device pixel ratio'));
-    appendToggleItem(
-        contextMenu.defaultSection(), this._showUserAgentTypeSetting, Common.UIString('Remove device type'),
-        Common.UIString('Add device type'));
-    contextMenu.appendItemsAtLocation('deviceModeMenu');
-    contextMenu.footerSection().appendItem(Common.UIString('Reset to defaults'), this._reset.bind(this));
-
-    /**
-     * @param {!UI.ContextMenuSection} section
-     * @param {!Common.Setting} setting
-     * @param {string} title1
-     * @param {string} title2
-     * @param {boolean=} disabled
-     */
-    function appendToggleItem(section, setting, title1, title2, disabled) {
-      if (typeof disabled === 'undefined')
-        disabled = model.type() === Emulation.DeviceModeModel.Type.None;
-      section.appendItem(setting.get() ? title1 : title2, setting.set.bind(setting, !setting.get()), disabled);
-    }
-  }
-
-  _reset() {
-    this._deviceOutlineSetting.set(false);
-    this._showDeviceScaleFactorSetting.set(false);
-    this._showUserAgentTypeSetting.set(false);
-    this._showMediaInspectorSetting.set(false);
-    this._showRulersSetting.set(false);
-    this._model.reset();
-  }
-
-  /**
-   * @param {!Element} element
-   * @return {!UI.ToolbarItem}
-   */
-  _wrapToolbarItem(element) {
-    const container = createElement('div');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(container, 'emulation/deviceModeToolbar.css');
-    shadowRoot.appendChild(element);
-    return new UI.ToolbarItem(container);
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice} device
-   */
-  _emulateDevice(device) {
-    const scale = this._autoAdjustScaleSetting.get() ? undefined : this._model.scaleSetting().get();
-    this._model.emulate(
-        Emulation.DeviceModeModel.Type.Device, device, this._lastMode.get(device) || device.modes[0], scale);
-  }
-
-  _switchToResponsive() {
-    this._model.emulate(Emulation.DeviceModeModel.Type.Responsive, null, null);
-  }
-
-  /**
-   * @param {!Array<!Emulation.EmulatedDevice>} devices
-   * @return {!Array<!Emulation.EmulatedDevice>}
-   */
-  _filterDevices(devices) {
-    devices = devices.filter(function(d) {
-      return d.show();
-    });
-    devices.sort(Emulation.EmulatedDevice.deviceComparator);
-    return devices;
-  }
-
-  /**
-   * @return {!Array<!Emulation.EmulatedDevice>}
-   */
-  _standardDevices() {
-    return this._filterDevices(this._emulatedDevicesList.standard());
-  }
-
-  /**
-   * @return {!Array<!Emulation.EmulatedDevice>}
-   */
-  _customDevices() {
-    return this._filterDevices(this._emulatedDevicesList.custom());
-  }
-
-  /**
-   * @return {!Array<!Emulation.EmulatedDevice>}
-   */
-  _allDevices() {
-    return this._standardDevices().concat(this._customDevices());
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _appendDeviceMenuItems(contextMenu) {
-    contextMenu.headerSection().appendCheckboxItem(
-        Common.UIString('Responsive'), this._switchToResponsive.bind(this),
-        this._model.type() === Emulation.DeviceModeModel.Type.Responsive, false);
-    appendGroup.call(this, this._standardDevices());
-    appendGroup.call(this, this._customDevices());
-    contextMenu.footerSection().appendItem(
-        Common.UIString('Edit\u2026'), this._emulatedDevicesList.revealCustomSetting.bind(this._emulatedDevicesList),
-        false);
-
-    /**
-     * @param {!Array<!Emulation.EmulatedDevice>} devices
-     * @this {Emulation.DeviceModeToolbar}
-     */
-    function appendGroup(devices) {
-      if (!devices.length)
-        return;
-      const section = contextMenu.section();
-      for (const device of devices) {
-        section.appendCheckboxItem(
-            device.title, this._emulateDevice.bind(this, device), this._model.device() === device, false);
-      }
-    }
-  }
-
-  /**
-   * @this {Emulation.DeviceModeToolbar}
-   */
-  _deviceListChanged() {
-    const device = this._model.device();
-    if (!device)
-      return;
-
-    const devices = this._allDevices();
-    if (devices.indexOf(device) === -1) {
-      if (devices.length)
-        this._emulateDevice(devices[0]);
-      else
-        this._model.emulate(Emulation.DeviceModeModel.Type.Responsive, null, null);
-    }
-  }
-
-  _updateDeviceScaleFactorVisibility() {
-    this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());
-  }
-
-  _updateUserAgentTypeVisibility() {
-    this._uaItem.setVisible(this._showUserAgentTypeSetting.get());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _modeMenuClicked(event) {
-    const device = this._model.device();
-    const model = this._model;
-    const autoAdjustScaleSetting = this._autoAdjustScaleSetting;
-
-    if (model.type() === Emulation.DeviceModeModel.Type.Responsive) {
-      const appliedSize = model.appliedDeviceSize();
-      if (autoAdjustScaleSetting.get()) {
-        model.setSizeAndScaleToFit(appliedSize.height, appliedSize.width);
-      } else {
-        model.setWidth(appliedSize.height);
-        model.setHeight(appliedSize.width);
-      }
-      return;
-    }
-
-    if (device.modes.length === 2 && device.modes[0].orientation !== device.modes[1].orientation) {
-      const scale = autoAdjustScaleSetting.get() ? undefined : model.scaleSetting().get();
-      model.emulate(
-          model.type(), model.device(), model.mode() === device.modes[0] ? device.modes[1] : device.modes[0], scale);
-      return;
-    }
-
-    const contextMenu = new UI.ContextMenu(
-        /** @type {!Event} */ (event.data), false, this._modeButton.element.totalOffsetLeft(),
-        this._modeButton.element.totalOffsetTop() + this._modeButton.element.offsetHeight);
-    addOrientation(Emulation.EmulatedDevice.Vertical, Common.UIString('Portrait'));
-    addOrientation(Emulation.EmulatedDevice.Horizontal, Common.UIString('Landscape'));
-    contextMenu.show();
-
-    /**
-     * @param {string} orientation
-     * @param {string} title
-     */
-    function addOrientation(orientation, title) {
-      const modes = device.modesForOrientation(orientation);
-      if (!modes.length)
-        return;
-      if (modes.length === 1) {
-        addMode(modes[0], title);
-      } else {
-        for (let index = 0; index < modes.length; index++)
-          addMode(modes[index], title + ' \u2013 ' + modes[index].title);
-      }
-    }
-
-    /**
-     * @param {!Emulation.EmulatedDevice.Mode} mode
-     * @param {string} title
-     */
-    function addMode(mode, title) {
-      contextMenu.defaultSection().appendCheckboxItem(title, applyMode.bind(null, mode), model.mode() === mode, false);
-    }
-
-    /**
-     * @param {!Emulation.EmulatedDevice.Mode} mode
-     */
-    function applyMode(mode) {
-      const scale = autoAdjustScaleSetting.get() ? undefined : model.scaleSetting().get();
-      model.emulate(model.type(), model.device(), mode, scale);
-    }
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  update() {
-    if (this._model.type() !== this._cachedModelType) {
-      this._cachedModelType = this._model.type();
-      this._widthInput.disabled = this._model.type() !== Emulation.DeviceModeModel.Type.Responsive;
-      this._heightInput.disabled = this._model.type() !== Emulation.DeviceModeModel.Type.Responsive;
-      this._deviceScaleItem.setEnabled(this._model.type() === Emulation.DeviceModeModel.Type.Responsive);
-      this._uaItem.setEnabled(this._model.type() === Emulation.DeviceModeModel.Type.Responsive);
-    }
-
-    const size = this._model.appliedDeviceSize();
-    this._updateHeightInput(
-        this._model.type() === Emulation.DeviceModeModel.Type.Responsive && this._model.isFullHeight() ?
-            '' :
-            String(size.height));
-    this._updateWidthInput(String(size.width));
-    this._heightInput.placeholder = size.height;
-
-    if (this._model.scale() !== this._cachedScale) {
-      this._scaleItem.setText(Common.UIString('%.0f%%', this._model.scale() * 100));
-      this._cachedScale = this._model.scale();
-    }
-
-    const deviceScale = this._model.appliedDeviceScaleFactor();
-    if (deviceScale !== this._cachedDeviceScale) {
-      this._deviceScaleItem.setText(Common.UIString('DPR: %.1f', deviceScale));
-      this._cachedDeviceScale = deviceScale;
-    }
-
-    const uaType = this._model.appliedUserAgentType();
-    if (uaType !== this._cachedUaType) {
-      this._uaItem.setText(uaType);
-      this._cachedUaType = uaType;
-    }
-
-    let deviceItemTitle = Common.UIString('None');
-    if (this._model.type() === Emulation.DeviceModeModel.Type.Responsive)
-      deviceItemTitle = Common.UIString('Responsive');
-    if (this._model.type() === Emulation.DeviceModeModel.Type.Device)
-      deviceItemTitle = this._model.device().title;
-    this._deviceSelectItem.setText(deviceItemTitle);
-
-    if (this._model.device() !== this._cachedModelDevice) {
-      const device = this._model.device();
-      if (device) {
-        const modeCount = device ? device.modes.length : 0;
-        this._modeButton.setEnabled(modeCount >= 2);
-        this._modeButton.setTitle(modeCount === 2 ? Common.UIString('Rotate') : Common.UIString('Screen options'));
-      } else if (this._model.type() === Emulation.DeviceModeModel.Type.Responsive) {
-        this._modeButton.setEnabled(true);
-        this._modeButton.setTitle(Common.UIString('Rotate'));
-      } else {
-        this._modeButton.setEnabled(false);
-      }
-      this._cachedModelDevice = device;
-    }
-
-    if (this._model.type() === Emulation.DeviceModeModel.Type.Device) {
-      this._lastMode.set(
-          /** @type {!Emulation.EmulatedDevice} */ (this._model.device()),
-          /** @type {!Emulation.EmulatedDevice.Mode} */ (this._model.mode()));
-    }
-
-    if (this._model.mode() !== this._cachedModelMode && this._model.type() !== Emulation.DeviceModeModel.Type.None) {
-      this._cachedModelMode = this._model.mode();
-      const value = this._persistenceSetting.get();
-      if (this._model.device()) {
-        value.device = this._model.device().title;
-        value.orientation = this._model.mode() ? this._model.mode().orientation : '';
-        value.mode = this._model.mode() ? this._model.mode().title : '';
-      } else {
-        value.device = '';
-        value.orientation = '';
-        value.mode = '';
-      }
-      this._persistenceSetting.set(value);
-    }
-  }
-
-  restore() {
-    for (const device of this._allDevices()) {
-      if (device.title === this._persistenceSetting.get().device) {
-        for (const mode of device.modes) {
-          if (mode.orientation === this._persistenceSetting.get().orientation &&
-              mode.title === this._persistenceSetting.get().mode) {
-            this._lastMode.set(device, mode);
-            this._emulateDevice(device);
-            return;
-          }
-        }
-      }
-    }
-
-    this._model.emulate(Emulation.DeviceModeModel.Type.Responsive, null, null);
-  }
-};
diff --git a/front_end/emulation/DeviceModeView.js b/front_end/emulation/DeviceModeView.js
deleted file mode 100644
index e77cf26..0000000
--- a/front_end/emulation/DeviceModeView.js
+++ /dev/null
@@ -1,587 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Emulation.DeviceModeView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.setMinimumSize(150, 150);
-    this.element.classList.add('device-mode-view');
-    this.registerRequiredCSS('emulation/deviceModeView.css');
-    UI.Tooltip.addNativeOverrideContainer(this.contentElement);
-
-    this._model = self.singleton(Emulation.DeviceModeModel);
-    this._model.addEventListener(Emulation.DeviceModeModel.Events.Updated, this._updateUI, this);
-    this._mediaInspector = new Emulation.MediaQueryInspector(
-        () => this._model.appliedDeviceSize().width, this._model.setWidth.bind(this._model));
-    this._showMediaInspectorSetting = Common.settings.moduleSetting('showMediaQueryInspector');
-    this._showMediaInspectorSetting.addChangeListener(this._updateUI, this);
-    this._showRulersSetting = Common.settings.moduleSetting('emulation.showRulers');
-    this._showRulersSetting.addChangeListener(this._updateUI, this);
-
-    this._topRuler = new Emulation.DeviceModeView.Ruler(true, this._model.setWidthAndScaleToFit.bind(this._model));
-    this._topRuler.element.classList.add('device-mode-ruler-top');
-    this._leftRuler = new Emulation.DeviceModeView.Ruler(false, this._model.setHeightAndScaleToFit.bind(this._model));
-    this._leftRuler.element.classList.add('device-mode-ruler-left');
-    this._createUI();
-    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this._zoomChanged, this);
-  }
-
-  _createUI() {
-    this._toolbar =
-        new Emulation.DeviceModeToolbar(this._model, this._showMediaInspectorSetting, this._showRulersSetting);
-    this.contentElement.appendChild(this._toolbar.element());
-
-    this._contentClip = this.contentElement.createChild('div', 'device-mode-content-clip vbox');
-    this._responsivePresetsContainer = this._contentClip.createChild('div', 'device-mode-presets-container');
-    this._populatePresetsContainer();
-    this._mediaInspectorContainer = this._contentClip.createChild('div', 'device-mode-media-container');
-    this._contentArea = this._contentClip.createChild('div', 'device-mode-content-area');
-
-    this._outlineImage = this._contentArea.createChild('img', 'device-mode-outline-image hidden fill');
-    this._outlineImage.addEventListener('load', this._onImageLoaded.bind(this, this._outlineImage, true), false);
-    this._outlineImage.addEventListener('error', this._onImageLoaded.bind(this, this._outlineImage, false), false);
-
-    this._screenArea = this._contentArea.createChild('div', 'device-mode-screen-area');
-    this._screenImage = this._screenArea.createChild('img', 'device-mode-screen-image hidden');
-    this._screenImage.addEventListener('load', this._onImageLoaded.bind(this, this._screenImage, true), false);
-    this._screenImage.addEventListener('error', this._onImageLoaded.bind(this, this._screenImage, false), false);
-
-    this._bottomRightResizerElement =
-        this._screenArea.createChild('div', 'device-mode-resizer device-mode-bottom-right-resizer');
-    this._bottomRightResizerElement.createChild('div', '');
-    this._createResizer(this._bottomRightResizerElement, 2, 1);
-
-    this._bottomLeftResizerElement =
-        this._screenArea.createChild('div', 'device-mode-resizer device-mode-bottom-left-resizer');
-    this._bottomLeftResizerElement.createChild('div', '');
-    this._createResizer(this._bottomLeftResizerElement, -2, 1);
-
-    this._rightResizerElement = this._screenArea.createChild('div', 'device-mode-resizer device-mode-right-resizer');
-    this._rightResizerElement.createChild('div', '');
-    this._createResizer(this._rightResizerElement, 2, 0);
-
-    this._leftResizerElement = this._screenArea.createChild('div', 'device-mode-resizer device-mode-left-resizer');
-    this._leftResizerElement.createChild('div', '');
-    this._createResizer(this._leftResizerElement, -2, 0);
-
-    this._bottomResizerElement = this._screenArea.createChild('div', 'device-mode-resizer device-mode-bottom-resizer');
-    this._bottomResizerElement.createChild('div', '');
-    this._createResizer(this._bottomResizerElement, 0, 1);
-    this._bottomResizerElement.addEventListener('dblclick', this._model.setHeight.bind(this._model, 0), false);
-    this._bottomResizerElement.title = Common.UIString('Double-click for full height');
-
-    this._pageArea = this._screenArea.createChild('div', 'device-mode-page-area');
-    this._pageArea.createChild('content');
-  }
-
-  _populatePresetsContainer() {
-    const sizes = [320, 375, 425, 768, 1024, 1440, 2560];
-    const titles = [
-      Common.UIString('Mobile S'), Common.UIString('Mobile M'), Common.UIString('Mobile L'), Common.UIString('Tablet'),
-      Common.UIString('Laptop'), Common.UIString('Laptop L'), Common.UIString('4K')
-    ];
-    this._presetBlocks = [];
-    const inner = this._responsivePresetsContainer.createChild('div', 'device-mode-presets-container-inner');
-    for (let i = sizes.length - 1; i >= 0; --i) {
-      const outer = inner.createChild('div', 'fill device-mode-preset-bar-outer');
-      const block = outer.createChild('div', 'device-mode-preset-bar');
-      block.createChild('span').textContent = titles[i] + ' \u2013 ' + sizes[i] + 'px';
-      block.addEventListener('click', applySize.bind(this, sizes[i]), false);
-      block.__width = sizes[i];
-      this._presetBlocks.push(block);
-    }
-
-    /**
-     * @param {number} width
-     * @param {!Event} e
-     * @this {Emulation.DeviceModeView}
-     */
-    function applySize(width, e) {
-      this._model.emulate(Emulation.DeviceModeModel.Type.Responsive, null, null);
-      this._model.setWidthAndScaleToFit(width);
-      e.consume();
-    }
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {number} widthFactor
-   * @param {number} heightFactor
-   * @return {!UI.ResizerWidget}
-   */
-  _createResizer(element, widthFactor, heightFactor) {
-    const resizer = new UI.ResizerWidget();
-    resizer.addElement(element);
-    let cursor = widthFactor ? 'ew-resize' : 'ns-resize';
-    if (widthFactor * heightFactor > 0)
-      cursor = 'nwse-resize';
-    if (widthFactor * heightFactor < 0)
-      cursor = 'nesw-resize';
-    resizer.setCursor(cursor);
-    resizer.addEventListener(UI.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
-    resizer.addEventListener(
-        UI.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate.bind(this, widthFactor, heightFactor));
-    resizer.addEventListener(UI.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
-    return resizer;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onResizeStart(event) {
-    this._slowPositionStart = null;
-    /** @type {!UI.Size} */
-    this._resizeStart = this._model.screenRect().size();
-  }
-
-  /**
-   * @param {number} widthFactor
-   * @param {number} heightFactor
-   * @param {!Common.Event} event
-   */
-  _onResizeUpdate(widthFactor, heightFactor, event) {
-    if (event.data.shiftKey !== !!this._slowPositionStart)
-      this._slowPositionStart = event.data.shiftKey ? {x: event.data.currentX, y: event.data.currentY} : null;
-
-    let cssOffsetX = event.data.currentX - event.data.startX;
-    let cssOffsetY = event.data.currentY - event.data.startY;
-    if (this._slowPositionStart) {
-      cssOffsetX =
-          (event.data.currentX - this._slowPositionStart.x) / 10 + this._slowPositionStart.x - event.data.startX;
-      cssOffsetY =
-          (event.data.currentY - this._slowPositionStart.y) / 10 + this._slowPositionStart.y - event.data.startY;
-    }
-
-    if (widthFactor) {
-      const dipOffsetX = cssOffsetX * UI.zoomManager.zoomFactor();
-      let newWidth = this._resizeStart.width + dipOffsetX * widthFactor;
-      newWidth = Math.round(newWidth / this._model.scale());
-      if (newWidth >= Emulation.DeviceModeModel.MinDeviceSize && newWidth <= Emulation.DeviceModeModel.MaxDeviceSize)
-        this._model.setWidth(newWidth);
-    }
-
-    if (heightFactor) {
-      const dipOffsetY = cssOffsetY * UI.zoomManager.zoomFactor();
-      let newHeight = this._resizeStart.height + dipOffsetY * heightFactor;
-      newHeight = Math.round(newHeight / this._model.scale());
-      if (newHeight >= Emulation.DeviceModeModel.MinDeviceSize && newHeight <= Emulation.DeviceModeModel.MaxDeviceSize)
-        this._model.setHeight(newHeight);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onResizeEnd(event) {
-    delete this._resizeStart;
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ResizedViewInResponsiveMode);
-  }
-
-  _updateUI() {
-    /**
-     * @param {!Element} element
-     * @param {!UI.Rect} rect
-     */
-    function applyRect(element, rect) {
-      element.style.left = rect.left + 'px';
-      element.style.top = rect.top + 'px';
-      element.style.width = rect.width + 'px';
-      element.style.height = rect.height + 'px';
-    }
-
-    if (!this.isShowing())
-      return;
-
-    const zoomFactor = UI.zoomManager.zoomFactor();
-    let callDoResize = false;
-    const showRulers = this._showRulersSetting.get() && this._model.type() !== Emulation.DeviceModeModel.Type.None;
-    let contentAreaResized = false;
-    let updateRulers = false;
-
-    const cssScreenRect = this._model.screenRect().scale(1 / zoomFactor);
-    if (!cssScreenRect.isEqual(this._cachedCssScreenRect)) {
-      applyRect(this._screenArea, cssScreenRect);
-      updateRulers = true;
-      callDoResize = true;
-      this._cachedCssScreenRect = cssScreenRect;
-    }
-
-    const cssVisiblePageRect = this._model.visiblePageRect().scale(1 / zoomFactor);
-    if (!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)) {
-      applyRect(this._pageArea, cssVisiblePageRect);
-      callDoResize = true;
-      this._cachedCssVisiblePageRect = cssVisiblePageRect;
-    }
-
-    const outlineRect = this._model.outlineRect().scale(1 / zoomFactor);
-    if (!outlineRect.isEqual(this._cachedOutlineRect)) {
-      applyRect(this._outlineImage, outlineRect);
-      callDoResize = true;
-      this._cachedOutlineRect = outlineRect;
-    }
-    this._contentClip.classList.toggle('device-mode-outline-visible', !!this._model.outlineImage());
-
-    const resizable = this._model.type() === Emulation.DeviceModeModel.Type.Responsive;
-    if (resizable !== this._cachedResizable) {
-      this._rightResizerElement.classList.toggle('hidden', !resizable);
-      this._leftResizerElement.classList.toggle('hidden', !resizable);
-      this._bottomResizerElement.classList.toggle('hidden', !resizable);
-      this._bottomRightResizerElement.classList.toggle('hidden', !resizable);
-      this._bottomLeftResizerElement.classList.toggle('hidden', !resizable);
-      this._cachedResizable = resizable;
-    }
-
-    const mediaInspectorVisible =
-        this._showMediaInspectorSetting.get() && this._model.type() !== Emulation.DeviceModeModel.Type.None;
-    if (mediaInspectorVisible !== this._cachedMediaInspectorVisible) {
-      if (mediaInspectorVisible)
-        this._mediaInspector.show(this._mediaInspectorContainer);
-      else
-        this._mediaInspector.detach();
-      contentAreaResized = true;
-      callDoResize = true;
-      this._cachedMediaInspectorVisible = mediaInspectorVisible;
-    }
-
-    if (showRulers !== this._cachedShowRulers) {
-      this._contentClip.classList.toggle('device-mode-rulers-visible', showRulers);
-      if (showRulers) {
-        this._topRuler.show(this._contentArea);
-        this._leftRuler.show(this._contentArea);
-      } else {
-        this._topRuler.detach();
-        this._leftRuler.detach();
-      }
-      contentAreaResized = true;
-      callDoResize = true;
-      this._cachedShowRulers = showRulers;
-    }
-
-    if (this._model.scale() !== this._cachedScale) {
-      updateRulers = true;
-      callDoResize = true;
-      for (const block of this._presetBlocks)
-        block.style.width = block.__width * this._model.scale() + 'px';
-      this._cachedScale = this._model.scale();
-    }
-
-    this._toolbar.update();
-    this._loadImage(this._screenImage, this._model.screenImage());
-    this._loadImage(this._outlineImage, this._model.outlineImage());
-    this._mediaInspector.setAxisTransform(this._model.scale());
-    if (callDoResize)
-      this.doResize();
-    if (updateRulers) {
-      this._topRuler.render(this._model.scale());
-      this._leftRuler.render(this._model.scale());
-      this._topRuler.element.positionAt(
-          this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0,
-          this._cachedCssScreenRect ? this._cachedCssScreenRect.top : 0);
-      this._leftRuler.element.positionAt(
-          this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0,
-          this._cachedCssScreenRect ? this._cachedCssScreenRect.top : 0);
-    }
-    if (contentAreaResized)
-      this._contentAreaResized();
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} srcset
-   */
-  _loadImage(element, srcset) {
-    if (element.getAttribute('srcset') === srcset)
-      return;
-    element.setAttribute('srcset', srcset);
-    if (!srcset)
-      element.classList.toggle('hidden', true);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {boolean} success
-   */
-  _onImageLoaded(element, success) {
-    element.classList.toggle('hidden', !success);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  setNonEmulatedAvailableSize(element) {
-    if (this._model.type() !== Emulation.DeviceModeModel.Type.None)
-      return;
-    const zoomFactor = UI.zoomManager.zoomFactor();
-    const rect = element.getBoundingClientRect();
-    const availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
-    this._model.setAvailableSize(availableSize, availableSize);
-  }
-
-  _contentAreaResized() {
-    const zoomFactor = UI.zoomManager.zoomFactor();
-    const rect = this._contentArea.getBoundingClientRect();
-    const availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
-    const preferredSize = new UI.Size(
-        Math.max((rect.width - 2 * this._handleWidth) * zoomFactor, 1),
-        Math.max((rect.height - this._handleHeight) * zoomFactor, 1));
-    this._model.setAvailableSize(availableSize, preferredSize);
-  }
-
-  _measureHandles() {
-    const hidden = this._rightResizerElement.classList.contains('hidden');
-    this._rightResizerElement.classList.toggle('hidden', false);
-    this._bottomResizerElement.classList.toggle('hidden', false);
-    this._handleWidth = this._rightResizerElement.offsetWidth;
-    this._handleHeight = this._bottomResizerElement.offsetHeight;
-    this._rightResizerElement.classList.toggle('hidden', hidden);
-    this._bottomResizerElement.classList.toggle('hidden', hidden);
-  }
-
-  _zoomChanged() {
-    delete this._handleWidth;
-    delete this._handleHeight;
-    if (this.isShowing()) {
-      this._measureHandles();
-      this._contentAreaResized();
-    }
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this.isShowing())
-      this._contentAreaResized();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._measureHandles();
-    this._toolbar.restore();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._model.emulate(Emulation.DeviceModeModel.Type.None, null, null);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async captureScreenshot() {
-    SDK.OverlayModel.muteHighlight();
-    const screenshot = await this._model.captureScreenshot(false);
-    SDK.OverlayModel.unmuteHighlight();
-    if (screenshot === null)
-      return;
-
-    const pageImage = new Image();
-    pageImage.src = 'data:image/png;base64,' + screenshot;
-    pageImage.onload = async () => {
-      const scale = pageImage.naturalWidth / this._model.screenRect().width;
-      const outlineRect = this._model.outlineRect().scale(scale);
-      const screenRect = this._model.screenRect().scale(scale);
-      const visiblePageRect = this._model.visiblePageRect().scale(scale);
-      const contentLeft = screenRect.left + visiblePageRect.left - outlineRect.left;
-      const contentTop = screenRect.top + visiblePageRect.top - outlineRect.top;
-
-      const canvas = createElement('canvas');
-      canvas.width = Math.floor(outlineRect.width);
-      canvas.height = Math.floor(outlineRect.height);
-      const ctx = canvas.getContext('2d');
-      ctx.imageSmoothingEnabled = false;
-
-      if (this._model.outlineImage())
-        await this._paintImage(ctx, this._model.outlineImage(), outlineRect.relativeTo(outlineRect));
-      if (this._model.screenImage())
-        await this._paintImage(ctx, this._model.screenImage(), screenRect.relativeTo(outlineRect));
-      ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
-      this._saveScreenshot(canvas);
-    };
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async captureFullSizeScreenshot() {
-    SDK.OverlayModel.muteHighlight();
-    const screenshot = await this._model.captureScreenshot(true);
-    SDK.OverlayModel.unmuteHighlight();
-    if (screenshot === null)
-      return;
-    return this._saveScreenshotBase64(screenshot);
-  }
-
-  /**
-   * @param {!Protocol.Page.Viewport=} clip
-   * @return {!Promise}
-   */
-  async captureAreaScreenshot(clip) {
-    SDK.OverlayModel.muteHighlight();
-    const screenshot = await this._model.captureScreenshot(false, clip);
-    SDK.OverlayModel.unmuteHighlight();
-    if (screenshot === null)
-      return;
-    return this._saveScreenshotBase64(screenshot);
-  }
-
-  /**
-   * @param {string} screenshot
-   */
-  _saveScreenshotBase64(screenshot) {
-    const pageImage = new Image();
-    pageImage.src = 'data:image/png;base64,' + screenshot;
-    pageImage.onload = () => {
-      const canvas = createElement('canvas');
-      canvas.width = pageImage.naturalWidth;
-      canvas.height = pageImage.naturalHeight;
-      const ctx = canvas.getContext('2d');
-      ctx.imageSmoothingEnabled = false;
-      ctx.drawImage(pageImage, 0, 0);
-      this._saveScreenshot(canvas);
-    };
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} ctx
-   * @param {string} src
-   * @param {!UI.Rect} rect
-   * @return {!Promise}
-   */
-  _paintImage(ctx, src, rect) {
-    return new Promise(fulfill => {
-      const image = new Image();
-      image.crossOrigin = 'Anonymous';
-      image.srcset = src;
-      image.onerror = fulfill;
-      image.onload = () => {
-        ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height);
-        fulfill();
-      };
-    });
-  }
-
-  /**
-   * @param {!Element} canvas
-   */
-  _saveScreenshot(canvas) {
-    const url = this._model.inspectedURL();
-    let fileName = url ? url.trimURL().removeURLFragment() : '';
-    if (this._model.type() === Emulation.DeviceModeModel.Type.Device)
-      fileName += Common.UIString('(%s)', this._model.device().title);
-    const link = createElement('a');
-    link.download = fileName + '.png';
-    canvas.toBlob(blob => {
-      link.href = URL.createObjectURL(blob);
-      link.click();
-    });
-  }
-};
-
-/**
- * @unrestricted
- */
-Emulation.DeviceModeView.Ruler = class extends UI.VBox {
-  /**
-   * @param {boolean} horizontal
-   * @param {function(number)} applyCallback
-   */
-  constructor(horizontal, applyCallback) {
-    super();
-    this.element.classList.add('device-mode-ruler');
-    this._contentElement =
-        this.element.createChild('div', 'device-mode-ruler-content').createChild('div', 'device-mode-ruler-inner');
-    this._horizontal = horizontal;
-    this._scale = 1;
-    this._count = 0;
-    this._throttler = new Common.Throttler(0);
-    this._applyCallback = applyCallback;
-  }
-
-  /**
-   * @param {number} scale
-   */
-  render(scale) {
-    this._scale = scale;
-    this._throttler.schedule(this._update.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._throttler.schedule(this._update.bind(this));
-  }
-
-  /**
-   * @return {!Promise.<?>}
-   */
-  _update() {
-    const zoomFactor = UI.zoomManager.zoomFactor();
-    const size = this._horizontal ? this._contentElement.offsetWidth : this._contentElement.offsetHeight;
-
-    if (this._scale !== this._renderedScale || zoomFactor !== this._renderedZoomFactor) {
-      this._contentElement.removeChildren();
-      this._count = 0;
-      this._renderedScale = this._scale;
-      this._renderedZoomFactor = zoomFactor;
-    }
-
-    const dipSize = size * zoomFactor / this._scale;
-    const count = Math.ceil(dipSize / 5);
-    let step = 1;
-    if (this._scale < 0.8)
-      step = 2;
-    if (this._scale < 0.6)
-      step = 4;
-    if (this._scale < 0.4)
-      step = 8;
-    if (this._scale < 0.2)
-      step = 16;
-    if (this._scale < 0.1)
-      step = 32;
-
-    for (let i = count; i < this._count; i++) {
-      if (!(i % step))
-        this._contentElement.lastChild.remove();
-    }
-
-    for (let i = this._count; i < count; i++) {
-      if (i % step)
-        continue;
-      const marker = this._contentElement.createChild('div', 'device-mode-ruler-marker');
-      if (i) {
-        if (this._horizontal)
-          marker.style.left = (5 * i) * this._scale / zoomFactor + 'px';
-        else
-          marker.style.top = (5 * i) * this._scale / zoomFactor + 'px';
-        if (!(i % 20)) {
-          const text = marker.createChild('div', 'device-mode-ruler-text');
-          text.textContent = i * 5;
-          text.addEventListener('click', this._onMarkerClick.bind(this, i * 5), false);
-        }
-      }
-      if (!(i % 10))
-        marker.classList.add('device-mode-ruler-marker-large');
-      else if (!(i % 5))
-        marker.classList.add('device-mode-ruler-marker-medium');
-    }
-
-    this._count = count;
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {number} size
-   */
-  _onMarkerClick(size) {
-    this._applyCallback.call(null, size);
-  }
-};
diff --git a/front_end/emulation/DeviceModeWrapper.js b/front_end/emulation/DeviceModeWrapper.js
deleted file mode 100644
index e81cc74..0000000
--- a/front_end/emulation/DeviceModeWrapper.js
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Emulation.DeviceModeWrapper = class extends UI.VBox {
-  /**
-   * @param {!Emulation.InspectedPagePlaceholder} inspectedPagePlaceholder
-   */
-  constructor(inspectedPagePlaceholder) {
-    super();
-    Emulation.DeviceModeView._wrapperInstance = this;
-    this._inspectedPagePlaceholder = inspectedPagePlaceholder;
-    /** @type {?Emulation.DeviceModeView} */
-    this._deviceModeView = null;
-    this._toggleDeviceModeAction = UI.actionRegistry.action('emulation.toggle-device-mode');
-    const model = self.singleton(Emulation.DeviceModeModel);
-    this._showDeviceModeSetting = model.enabledSetting();
-    this._showDeviceModeSetting.setRequiresUserAction(!!Runtime.queryParam('hasOtherClients'));
-    this._showDeviceModeSetting.addChangeListener(this._update.bind(this, false));
-    SDK.targetManager.addModelListener(
-        SDK.OverlayModel, SDK.OverlayModel.Events.ScreenshotRequested, this._screenshotRequestedFromOverlay, this);
-    this._update(true);
-  }
-
-  _toggleDeviceMode() {
-    this._showDeviceModeSetting.set(!this._showDeviceModeSetting.get());
-  }
-
-  /**
-   * @param {boolean=} fullSize
-   * @param {!Protocol.Page.Viewport=} clip
-   * @return {boolean}
-   */
-  _captureScreenshot(fullSize, clip) {
-    if (!this._deviceModeView)
-      this._deviceModeView = new Emulation.DeviceModeView();
-    this._deviceModeView.setNonEmulatedAvailableSize(this._inspectedPagePlaceholder.element);
-    if (fullSize)
-      this._deviceModeView.captureFullSizeScreenshot();
-    else if (clip)
-      this._deviceModeView.captureAreaScreenshot(clip);
-    else
-      this._deviceModeView.captureScreenshot();
-    return true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _screenshotRequestedFromOverlay(event) {
-    const clip = /** @type {!Protocol.Page.Viewport} */ (event.data);
-    this._captureScreenshot(false, clip);
-  }
-
-  /**
-   * @param {boolean} force
-   */
-  _update(force) {
-    this._toggleDeviceModeAction.setToggled(this._showDeviceModeSetting.get());
-    if (!force) {
-      const showing = this._deviceModeView && this._deviceModeView.isShowing();
-      if (this._showDeviceModeSetting.get() === showing)
-        return;
-    }
-
-    if (this._showDeviceModeSetting.get()) {
-      if (!this._deviceModeView)
-        this._deviceModeView = new Emulation.DeviceModeView();
-      this._deviceModeView.show(this.element);
-      this._inspectedPagePlaceholder.clearMinimumSize();
-      this._inspectedPagePlaceholder.show(this._deviceModeView.element);
-    } else {
-      if (this._deviceModeView)
-        this._deviceModeView.detach();
-      this._inspectedPagePlaceholder.restoreMinimumSize();
-      this._inspectedPagePlaceholder.show(this.element);
-    }
-  }
-};
-
-/** @type {!Emulation.DeviceModeWrapper} */
-Emulation.DeviceModeView._wrapperInstance;
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Emulation.DeviceModeWrapper.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    if (Emulation.DeviceModeView._wrapperInstance) {
-      switch (actionId) {
-        case 'emulation.capture-screenshot':
-          return Emulation.DeviceModeView._wrapperInstance._captureScreenshot();
-
-        case 'emulation.capture-node-screenshot': {
-          const node = UI.context.flavor(SDK.DOMNode);
-          if (!node)
-            return true;
-          async function captureClip() {
-            const object = await node.resolveToObject();
-            const result = await object.callFunctionPromise(function() {
-              const rect = this.getBoundingClientRect();
-              const docRect = this.ownerDocument.documentElement.getBoundingClientRect();
-              return JSON.stringify({
-                x: rect.left - docRect.left,
-                y: rect.top - docRect.top,
-                width: rect.width,
-                height: rect.height,
-                scale: 1
-              });
-            });
-            const clip = /** @type {!Protocol.Page.Viewport} */ (JSON.parse(result.object.value));
-            Emulation.DeviceModeView._wrapperInstance._captureScreenshot(false, clip);
-          }
-          captureClip();
-          return true;
-        }
-
-        case 'emulation.capture-full-height-screenshot':
-          return Emulation.DeviceModeView._wrapperInstance._captureScreenshot(true);
-
-        case 'emulation.toggle-device-mode':
-          Emulation.DeviceModeView._wrapperInstance._toggleDeviceMode();
-          return true;
-      }
-    }
-    return false;
-  }
-};
diff --git a/front_end/emulation/DevicesSettingsTab.js b/front_end/emulation/DevicesSettingsTab.js
deleted file mode 100644
index 0b63f7d..0000000
--- a/front_end/emulation/DevicesSettingsTab.js
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.ListWidget.Delegate}
- * @unrestricted
- */
-Emulation.DevicesSettingsTab = class extends UI.VBox {
-  constructor() {
-    super();
-    this.element.classList.add('settings-tab-container');
-    this.element.classList.add('devices-settings-tab');
-    this.registerRequiredCSS('emulation/devicesSettingsTab.css');
-
-    const header = this.element.createChild('header');
-    header.createChild('h3').createTextChild(Common.UIString('Emulated Devices'));
-    this.containerElement = this.element.createChild('div', 'settings-container-wrapper')
-                                .createChild('div', 'settings-tab settings-content settings-container');
-
-    const buttonsRow = this.containerElement.createChild('div', 'devices-button-row');
-    this._addCustomButton =
-        UI.createTextButton(Common.UIString('Add custom device...'), this._addCustomDevice.bind(this));
-    buttonsRow.appendChild(this._addCustomButton);
-
-    this._list = new UI.ListWidget(this);
-    this._list.registerRequiredCSS('emulation/devicesSettingsTab.css');
-    this._list.element.classList.add('devices-list');
-    this._list.show(this.containerElement);
-
-    this._muteUpdate = false;
-    this._emulatedDevicesList = Emulation.EmulatedDevicesList.instance();
-    this._emulatedDevicesList.addEventListener(
-        Emulation.EmulatedDevicesList.Events.CustomDevicesUpdated, this._devicesUpdated, this);
-    this._emulatedDevicesList.addEventListener(
-        Emulation.EmulatedDevicesList.Events.StandardDevicesUpdated, this._devicesUpdated, this);
-
-    this.setDefaultFocusedElement(this._addCustomButton);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._devicesUpdated();
-  }
-
-  _devicesUpdated() {
-    if (this._muteUpdate)
-      return;
-
-    this._list.clear();
-
-    let devices = this._emulatedDevicesList.custom().slice();
-    for (let i = 0; i < devices.length; ++i)
-      this._list.appendItem(devices[i], true);
-
-    this._list.appendSeparator();
-
-    devices = this._emulatedDevicesList.standard().slice();
-    devices.sort(Emulation.EmulatedDevice.deviceComparator);
-    for (let i = 0; i < devices.length; ++i)
-      this._list.appendItem(devices[i], false);
-  }
-
-  /**
-   * @param {boolean} custom
-   */
-  _muteAndSaveDeviceList(custom) {
-    this._muteUpdate = true;
-    if (custom)
-      this._emulatedDevicesList.saveCustomDevices();
-    else
-      this._emulatedDevicesList.saveStandardDevices();
-    this._muteUpdate = false;
-  }
-
-  _addCustomDevice() {
-    const device = new Emulation.EmulatedDevice();
-    device.deviceScaleFactor = 0;
-    device.horizontal.width = 700;
-    device.horizontal.height = 400;
-    device.vertical.width = 400;
-    device.vertical.height = 700;
-    this._list.addNewItem(this._emulatedDevicesList.custom().length, device);
-  }
-
-  /**
-   * @param {number} value
-   * @return {string}
-   */
-  _toNumericInputValue(value) {
-    return value ? String(value) : '';
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(item, editable) {
-    const device = /** @type {!Emulation.EmulatedDevice} */ (item);
-    const element = createElementWithClass('div', 'devices-list-item');
-    const checkbox = element.createChild('input', 'devices-list-checkbox');
-    checkbox.type = 'checkbox';
-    checkbox.checked = device.show();
-    checkbox.addEventListener('click', event => event.consume(), false);
-    element.createChild('div', 'devices-list-title').textContent = device.title;
-    element.addEventListener('click', onItemClicked.bind(this), false);
-    return element;
-
-    /**
-     * @param {!Event} event
-     * @this {Emulation.DevicesSettingsTab}
-     */
-    function onItemClicked(event) {
-      const show = !checkbox.checked;
-      device.setShow(show);
-      this._muteAndSaveDeviceList(editable);
-      checkbox.checked = show;
-      event.consume();
-    }
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {number} index
-   */
-  removeItemRequested(item, index) {
-    this._emulatedDevicesList.removeCustomDevice(/** @type {!Emulation.EmulatedDevice} */ (item));
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {
-    const device = /** @type {!Emulation.EmulatedDevice} */ (item);
-    device.title = editor.control('title').value.trim();
-    device.vertical.width = editor.control('width').value ? parseInt(editor.control('width').value, 10) : 0;
-    device.vertical.height = editor.control('height').value ? parseInt(editor.control('height').value, 10) : 0;
-    device.horizontal.width = device.vertical.height;
-    device.horizontal.height = device.vertical.width;
-    device.deviceScaleFactor = editor.control('scale').value ? parseFloat(editor.control('scale').value) : 0;
-    device.userAgent = editor.control('user-agent').value;
-    device.modes = [];
-    device.modes.push(
-        {title: '', orientation: Emulation.EmulatedDevice.Vertical, insets: new UI.Insets(0, 0, 0, 0), image: null});
-    device.modes.push(
-        {title: '', orientation: Emulation.EmulatedDevice.Horizontal, insets: new UI.Insets(0, 0, 0, 0), image: null});
-    device.capabilities = [];
-    const uaType = editor.control('ua-type').value;
-    if (uaType === Emulation.DeviceModeModel.UA.Mobile || uaType === Emulation.DeviceModeModel.UA.MobileNoTouch)
-      device.capabilities.push(Emulation.EmulatedDevice.Capability.Mobile);
-    if (uaType === Emulation.DeviceModeModel.UA.Mobile || uaType === Emulation.DeviceModeModel.UA.DesktopTouch)
-      device.capabilities.push(Emulation.EmulatedDevice.Capability.Touch);
-    if (isNew)
-      this._emulatedDevicesList.addCustomDevice(device);
-    else
-      this._emulatedDevicesList.saveCustomDevices();
-    this._addCustomButton.scrollIntoViewIfNeeded();
-    this._addCustomButton.focus();
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(item) {
-    const device = /** @type {!Emulation.EmulatedDevice} */ (item);
-    const editor = this._createEditor();
-    editor.control('title').value = device.title;
-    editor.control('width').value = this._toNumericInputValue(device.vertical.width);
-    editor.control('height').value = this._toNumericInputValue(device.vertical.height);
-    editor.control('scale').value = this._toNumericInputValue(device.deviceScaleFactor);
-    editor.control('user-agent').value = device.userAgent;
-    let uaType;
-    if (device.mobile())
-      uaType = device.touch() ? Emulation.DeviceModeModel.UA.Mobile : Emulation.DeviceModeModel.UA.MobileNoTouch;
-    else
-      uaType = device.touch() ? Emulation.DeviceModeModel.UA.DesktopTouch : Emulation.DeviceModeModel.UA.Desktop;
-    editor.control('ua-type').value = uaType;
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._editor = editor;
-    const content = editor.contentElement();
-
-    const fields = content.createChild('div', 'devices-edit-fields');
-    fields.createChild('div', 'hbox')
-        .appendChild(editor.createInput('title', 'text', Common.UIString('Device name'), titleValidator));
-    const screen = fields.createChild('div', 'hbox');
-    screen.appendChild(editor.createInput('width', 'text', Common.UIString('Width'), sizeValidator));
-    screen.appendChild(editor.createInput('height', 'text', Common.UIString('height'), sizeValidator));
-    const dpr = editor.createInput('scale', 'text', Common.UIString('Device pixel ratio'), scaleValidator);
-    dpr.classList.add('device-edit-fixed');
-    screen.appendChild(dpr);
-    const ua = fields.createChild('div', 'hbox');
-    ua.appendChild(editor.createInput('user-agent', 'text', Common.UIString('User agent string'), () => true));
-    const uaType = editor.createSelect(
-        'ua-type',
-        [
-          Emulation.DeviceModeModel.UA.Mobile, Emulation.DeviceModeModel.UA.MobileNoTouch,
-          Emulation.DeviceModeModel.UA.Desktop, Emulation.DeviceModeModel.UA.DesktopTouch
-        ],
-        () => true);
-    uaType.classList.add('device-edit-fixed');
-    ua.appendChild(uaType);
-
-    return editor;
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function titleValidator(item, index, input) {
-      const value = input.value.trim();
-      return value.length > 0 && value.length < 50;
-    }
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function sizeValidator(item, index, input) {
-      return Emulation.DeviceModeModel.deviceSizeValidator(input.value);
-    }
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function scaleValidator(item, index, input) {
-      return Emulation.DeviceModeModel.deviceScaleFactorValidator(input.value);
-    }
-  }
-};
diff --git a/front_end/emulation/EmulatedDevices.js b/front_end/emulation/EmulatedDevices.js
deleted file mode 100644
index 732abc9..0000000
--- a/front_end/emulation/EmulatedDevices.js
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Emulation.EmulatedDevice = class {
-  constructor() {
-    /** @type {string} */
-    this.title = '';
-    /** @type {string} */
-    this.type = Emulation.EmulatedDevice.Type.Unknown;
-    /** @type {!Emulation.EmulatedDevice.Orientation} */
-    this.vertical = {width: 0, height: 0, outlineInsets: null, outlineImage: null};
-    /** @type {!Emulation.EmulatedDevice.Orientation} */
-    this.horizontal = {width: 0, height: 0, outlineInsets: null, outlineImage: null};
-    /** @type {number} */
-    this.deviceScaleFactor = 1;
-    /** @type {!Array.<string>} */
-    this.capabilities = [Emulation.EmulatedDevice.Capability.Touch, Emulation.EmulatedDevice.Capability.Mobile];
-    /** @type {string} */
-    this.userAgent = '';
-    /** @type {!Array.<!Emulation.EmulatedDevice.Mode>} */
-    this.modes = [];
-
-    /** @type {string} */
-    this._show = Emulation.EmulatedDevice._Show.Default;
-    /** @type {boolean} */
-    this._showByDefault = true;
-
-    /** @type {?Runtime.Extension} */
-    this._extension = null;
-  }
-
-  /**
-   * @param {*} json
-   * @return {?Emulation.EmulatedDevice}
-   */
-  static fromJSONV1(json) {
-    try {
-      /**
-       * @param {*} object
-       * @param {string} key
-       * @param {string} type
-       * @param {*=} defaultValue
-       * @return {*}
-       */
-      function parseValue(object, key, type, defaultValue) {
-        if (typeof object !== 'object' || object === null || !object.hasOwnProperty(key)) {
-          if (typeof defaultValue !== 'undefined')
-            return defaultValue;
-          throw new Error('Emulated device is missing required property \'' + key + '\'');
-        }
-        const value = object[key];
-        if (typeof value !== type || value === null)
-          throw new Error('Emulated device property \'' + key + '\' has wrong type \'' + typeof value + '\'');
-        return value;
-      }
-
-      /**
-       * @param {*} object
-       * @param {string} key
-       * @return {number}
-       */
-      function parseIntValue(object, key) {
-        const value = /** @type {number} */ (parseValue(object, key, 'number'));
-        if (value !== Math.abs(value))
-          throw new Error('Emulated device value \'' + key + '\' must be integer');
-        return value;
-      }
-
-      /**
-       * @param {*} json
-       * @return {!UI.Insets}
-       */
-      function parseInsets(json) {
-        return new UI.Insets(
-            parseIntValue(json, 'left'), parseIntValue(json, 'top'), parseIntValue(json, 'right'),
-            parseIntValue(json, 'bottom'));
-      }
-
-      /**
-       * @param {*} json
-       * @return {!Emulation.EmulatedDevice.Orientation}
-       */
-      function parseOrientation(json) {
-        const result = {};
-
-        result.width = parseIntValue(json, 'width');
-        if (result.width < 0 || result.width > Emulation.DeviceModeModel.MaxDeviceSize ||
-            result.width < Emulation.DeviceModeModel.MinDeviceSize)
-          throw new Error('Emulated device has wrong width: ' + result.width);
-
-        result.height = parseIntValue(json, 'height');
-        if (result.height < 0 || result.height > Emulation.DeviceModeModel.MaxDeviceSize ||
-            result.height < Emulation.DeviceModeModel.MinDeviceSize)
-          throw new Error('Emulated device has wrong height: ' + result.height);
-
-        const outlineInsets = parseValue(json['outline'], 'insets', 'object', null);
-        if (outlineInsets) {
-          result.outlineInsets = parseInsets(outlineInsets);
-          if (result.outlineInsets.left < 0 || result.outlineInsets.top < 0)
-            throw new Error('Emulated device has wrong outline insets');
-          result.outlineImage = /** @type {string} */ (parseValue(json['outline'], 'image', 'string'));
-        }
-        return /** @type {!Emulation.EmulatedDevice.Orientation} */ (result);
-      }
-
-      const result = new Emulation.EmulatedDevice();
-      result.title = /** @type {string} */ (parseValue(json, 'title', 'string'));
-      result.type = /** @type {string} */ (parseValue(json, 'type', 'string'));
-      const rawUserAgent = /** @type {string} */ (parseValue(json, 'user-agent', 'string'));
-      result.userAgent = SDK.MultitargetNetworkManager.patchUserAgentWithChromeVersion(rawUserAgent);
-
-      const capabilities = parseValue(json, 'capabilities', 'object', []);
-      if (!Array.isArray(capabilities))
-        throw new Error('Emulated device capabilities must be an array');
-      result.capabilities = [];
-      for (let i = 0; i < capabilities.length; ++i) {
-        if (typeof capabilities[i] !== 'string')
-          throw new Error('Emulated device capability must be a string');
-        result.capabilities.push(capabilities[i]);
-      }
-
-      result.deviceScaleFactor = /** @type {number} */ (parseValue(json['screen'], 'device-pixel-ratio', 'number'));
-      if (result.deviceScaleFactor < 0 || result.deviceScaleFactor > 100)
-        throw new Error('Emulated device has wrong deviceScaleFactor: ' + result.deviceScaleFactor);
-
-      result.vertical = parseOrientation(parseValue(json['screen'], 'vertical', 'object'));
-      result.horizontal = parseOrientation(parseValue(json['screen'], 'horizontal', 'object'));
-
-      const modes = parseValue(json, 'modes', 'object', []);
-      if (!Array.isArray(modes))
-        throw new Error('Emulated device modes must be an array');
-      result.modes = [];
-      for (let i = 0; i < modes.length; ++i) {
-        const mode = {};
-        mode.title = /** @type {string} */ (parseValue(modes[i], 'title', 'string'));
-        mode.orientation = /** @type {string} */ (parseValue(modes[i], 'orientation', 'string'));
-        if (mode.orientation !== Emulation.EmulatedDevice.Vertical &&
-            mode.orientation !== Emulation.EmulatedDevice.Horizontal)
-          throw new Error('Emulated device mode has wrong orientation \'' + mode.orientation + '\'');
-        const orientation = result.orientationByName(mode.orientation);
-        mode.insets = parseInsets(parseValue(modes[i], 'insets', 'object'));
-        if (mode.insets.top < 0 || mode.insets.left < 0 || mode.insets.right < 0 || mode.insets.bottom < 0 ||
-            mode.insets.top + mode.insets.bottom > orientation.height ||
-            mode.insets.left + mode.insets.right > orientation.width)
-          throw new Error('Emulated device mode \'' + mode.title + '\'has wrong mode insets');
-
-        mode.image = /** @type {string} */ (parseValue(modes[i], 'image', 'string', null));
-        result.modes.push(mode);
-      }
-
-      result._showByDefault = /** @type {boolean} */ (parseValue(json, 'show-by-default', 'boolean', undefined));
-      result._show =
-          /** @type {string} */ (parseValue(json, 'show', 'string', Emulation.EmulatedDevice._Show.Default));
-
-      return result;
-    } catch (e) {
-      return null;
-    }
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice} device1
-   * @param {!Emulation.EmulatedDevice} device2
-   * @return {number}
-   */
-  static deviceComparator(device1, device2) {
-    const order1 = (device1._extension && device1._extension.descriptor()['order']) || -1;
-    const order2 = (device2._extension && device2._extension.descriptor()['order']) || -1;
-    if (order1 > order2)
-      return 1;
-    if (order2 > order1)
-      return -1;
-    return device1.title < device2.title ? -1 : (device1.title > device2.title ? 1 : 0);
-  }
-
-  /**
-   * @return {?Runtime.Extension}
-   */
-  extension() {
-    return this._extension;
-  }
-
-  /**
-   * @param {?Runtime.Extension} extension
-   */
-  setExtension(extension) {
-    this._extension = extension;
-  }
-
-  /**
-   * @param {string} orientation
-   * @return {!Array.<!Emulation.EmulatedDevice.Mode>}
-   */
-  modesForOrientation(orientation) {
-    const result = [];
-    for (let index = 0; index < this.modes.length; index++) {
-      if (this.modes[index].orientation === orientation)
-        result.push(this.modes[index]);
-    }
-    return result;
-  }
-
-  /**
-   * @return {*}
-   */
-  _toJSON() {
-    const json = {};
-    json['title'] = this.title;
-    json['type'] = this.type;
-    json['user-agent'] = this.userAgent;
-    json['capabilities'] = this.capabilities;
-
-    json['screen'] = {};
-    json['screen']['device-pixel-ratio'] = this.deviceScaleFactor;
-    json['screen']['vertical'] = this._orientationToJSON(this.vertical);
-    json['screen']['horizontal'] = this._orientationToJSON(this.horizontal);
-
-    json['modes'] = [];
-    for (let i = 0; i < this.modes.length; ++i) {
-      const mode = {};
-      mode['title'] = this.modes[i].title;
-      mode['orientation'] = this.modes[i].orientation;
-      mode['insets'] = {};
-      mode['insets']['left'] = this.modes[i].insets.left;
-      mode['insets']['top'] = this.modes[i].insets.top;
-      mode['insets']['right'] = this.modes[i].insets.right;
-      mode['insets']['bottom'] = this.modes[i].insets.bottom;
-      if (this.modes[i].image)
-        mode['image'] = this.modes[i].image;
-      json['modes'].push(mode);
-    }
-
-    json['show-by-default'] = this._showByDefault;
-    json['show'] = this._show;
-
-    return json;
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice.Orientation} orientation
-   * @return {*}
-   */
-  _orientationToJSON(orientation) {
-    const json = {};
-    json['width'] = orientation.width;
-    json['height'] = orientation.height;
-    if (orientation.outlineInsets) {
-      json['outline'] = {};
-      json['outline']['insets'] = {};
-      json['outline']['insets']['left'] = orientation.outlineInsets.left;
-      json['outline']['insets']['top'] = orientation.outlineInsets.top;
-      json['outline']['insets']['right'] = orientation.outlineInsets.right;
-      json['outline']['insets']['bottom'] = orientation.outlineInsets.bottom;
-      json['outline']['image'] = orientation.outlineImage;
-    }
-    return json;
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice.Mode} mode
-   * @return {string}
-   */
-  modeImage(mode) {
-    if (!mode.image)
-      return '';
-    if (!this._extension)
-      return mode.image;
-    return this._extension.module().substituteURL(mode.image);
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice.Mode} mode
-   * @return {string}
-   */
-  outlineImage(mode) {
-    const orientation = this.orientationByName(mode.orientation);
-    if (!orientation.outlineImage)
-      return '';
-    if (!this._extension)
-      return orientation.outlineImage;
-    return this._extension.module().substituteURL(orientation.outlineImage);
-  }
-
-  /**
-   * @param {string} name
-   * @return {!Emulation.EmulatedDevice.Orientation}
-   */
-  orientationByName(name) {
-    return name === Emulation.EmulatedDevice.Vertical ? this.vertical : this.horizontal;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  show() {
-    if (this._show === Emulation.EmulatedDevice._Show.Default)
-      return this._showByDefault;
-    return this._show === Emulation.EmulatedDevice._Show.Always;
-  }
-
-  /**
-   * @param {boolean} show
-   */
-  setShow(show) {
-    this._show = show ? Emulation.EmulatedDevice._Show.Always : Emulation.EmulatedDevice._Show.Never;
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice} other
-   */
-  copyShowFrom(other) {
-    this._show = other._show;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  touch() {
-    return this.capabilities.indexOf(Emulation.EmulatedDevice.Capability.Touch) !== -1;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  mobile() {
-    return this.capabilities.indexOf(Emulation.EmulatedDevice.Capability.Mobile) !== -1;
-  }
-};
-
-/** @typedef {!{title: string, orientation: string, insets: !UI.Insets, image: ?string}} */
-Emulation.EmulatedDevice.Mode;
-
-/** @typedef {!{width: number, height: number, outlineInsets: ?UI.Insets, outlineImage: ?string}} */
-Emulation.EmulatedDevice.Orientation;
-
-Emulation.EmulatedDevice.Horizontal = 'horizontal';
-Emulation.EmulatedDevice.Vertical = 'vertical';
-
-Emulation.EmulatedDevice.Type = {
-  Phone: 'phone',
-  Tablet: 'tablet',
-  Notebook: 'notebook',
-  Desktop: 'desktop',
-  Unknown: 'unknown'
-};
-
-Emulation.EmulatedDevice.Capability = {
-  Touch: 'touch',
-  Mobile: 'mobile'
-};
-
-Emulation.EmulatedDevice._Show = {
-  Always: 'Always',
-  Default: 'Default',
-  Never: 'Never'
-};
-
-
-/**
- * @unrestricted
- */
-Emulation.EmulatedDevicesList = class extends Common.Object {
-  constructor() {
-    super();
-
-    /** @type {!Common.Setting} */
-    this._standardSetting = Common.settings.createSetting('standardEmulatedDeviceList', []);
-    /** @type {!Array.<!Emulation.EmulatedDevice>} */
-    this._standard = [];
-    this._listFromJSONV1(this._standardSetting.get(), this._standard);
-    this._updateStandardDevices();
-
-    /** @type {!Common.Setting} */
-    this._customSetting = Common.settings.createSetting('customEmulatedDeviceList', []);
-    /** @type {!Array.<!Emulation.EmulatedDevice>} */
-    this._custom = [];
-    if (!this._listFromJSONV1(this._customSetting.get(), this._custom))
-      this.saveCustomDevices();
-  }
-
-  /**
-   * @return {!Emulation.EmulatedDevicesList}
-   */
-  static instance() {
-    if (!Emulation.EmulatedDevicesList._instance)
-      Emulation.EmulatedDevicesList._instance = new Emulation.EmulatedDevicesList();
-    return /** @type {!Emulation.EmulatedDevicesList} */ (Emulation.EmulatedDevicesList._instance);
-  }
-
-  _updateStandardDevices() {
-    const devices = [];
-    const extensions = self.runtime.extensions('emulated-device');
-    for (let i = 0; i < extensions.length; ++i) {
-      const device = Emulation.EmulatedDevice.fromJSONV1(extensions[i].descriptor()['device']);
-      device.setExtension(extensions[i]);
-      devices.push(device);
-    }
-    this._copyShowValues(this._standard, devices);
-    this._standard = devices;
-    this.saveStandardDevices();
-  }
-
-  /**
-   * @param {!Array.<*>} jsonArray
-   * @param {!Array.<!Emulation.EmulatedDevice>} result
-   * @return {boolean}
-   */
-  _listFromJSONV1(jsonArray, result) {
-    if (!Array.isArray(jsonArray))
-      return false;
-    let success = true;
-    for (let i = 0; i < jsonArray.length; ++i) {
-      const device = Emulation.EmulatedDevice.fromJSONV1(jsonArray[i]);
-      if (device) {
-        result.push(device);
-        if (!device.modes.length) {
-          device.modes.push({
-            title: '',
-            orientation: Emulation.EmulatedDevice.Horizontal,
-            insets: new UI.Insets(0, 0, 0, 0),
-            image: null
-          });
-          device.modes.push({
-            title: '',
-            orientation: Emulation.EmulatedDevice.Vertical,
-            insets: new UI.Insets(0, 0, 0, 0),
-            image: null
-          });
-        }
-      } else {
-        success = false;
-      }
-    }
-    return success;
-  }
-
-  /**
-   * @return {!Array.<!Emulation.EmulatedDevice>}
-   */
-  standard() {
-    return this._standard;
-  }
-
-  /**
-   * @return {!Array.<!Emulation.EmulatedDevice>}
-   */
-  custom() {
-    return this._custom;
-  }
-
-  revealCustomSetting() {
-    Common.Revealer.reveal(this._customSetting);
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice} device
-   */
-  addCustomDevice(device) {
-    this._custom.push(device);
-    this.saveCustomDevices();
-  }
-
-  /**
-   * @param {!Emulation.EmulatedDevice} device
-   */
-  removeCustomDevice(device) {
-    this._custom.remove(device);
-    this.saveCustomDevices();
-  }
-
-  saveCustomDevices() {
-    const json = this._custom.map(/** @param {!Emulation.EmulatedDevice} device */ function(device) {
-      return device._toJSON();
-    });
-    this._customSetting.set(json);
-    this.dispatchEventToListeners(Emulation.EmulatedDevicesList.Events.CustomDevicesUpdated);
-  }
-
-  saveStandardDevices() {
-    const json = this._standard.map(/** @param {!Emulation.EmulatedDevice} device */ function(device) {
-      return device._toJSON();
-    });
-    this._standardSetting.set(json);
-    this.dispatchEventToListeners(Emulation.EmulatedDevicesList.Events.StandardDevicesUpdated);
-  }
-
-  /**
-   * @param {!Array.<!Emulation.EmulatedDevice>} from
-   * @param {!Array.<!Emulation.EmulatedDevice>} to
-   */
-  _copyShowValues(from, to) {
-    const deviceById = new Map();
-    for (let i = 0; i < from.length; ++i)
-      deviceById.set(from[i].title, from[i]);
-
-    for (let i = 0; i < to.length; ++i) {
-      const title = to[i].title;
-      if (deviceById.has(title))
-        to[i].copyShowFrom(/** @type {!Emulation.EmulatedDevice} */ (deviceById.get(title)));
-    }
-  }
-};
-
-/** @enum {symbol} */
-Emulation.EmulatedDevicesList.Events = {
-  CustomDevicesUpdated: Symbol('CustomDevicesUpdated'),
-  StandardDevicesUpdated: Symbol('StandardDevicesUpdated')
-};
-
-/** @type {?Emulation.EmulatedDevicesList} */
-Emulation.EmulatedDevicesList._instance;
diff --git a/front_end/emulation/InspectedPagePlaceholder.js b/front_end/emulation/InspectedPagePlaceholder.js
deleted file mode 100644
index d9f1787..0000000
--- a/front_end/emulation/InspectedPagePlaceholder.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Emulation.InspectedPagePlaceholder = class extends UI.Widget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('emulation/inspectedPagePlaceholder.css');
-    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this.onResize, this);
-    this.restoreMinimumSize();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._updateId)
-      this.element.window().cancelAnimationFrame(this._updateId);
-    this._updateId = this.element.window().requestAnimationFrame(this.update.bind(this, false));
-  }
-
-  restoreMinimumSize() {
-    this.setMinimumSize(150, 150);
-  }
-
-  clearMinimumSize() {
-    this.setMinimumSize(1, 1);
-  }
-
-  _dipPageRect() {
-    const zoomFactor = UI.zoomManager.zoomFactor();
-    const rect = this.element.getBoundingClientRect();
-    const bodyRect = this.element.ownerDocument.body.getBoundingClientRect();
-
-    const left = Math.max(rect.left * zoomFactor, bodyRect.left * zoomFactor);
-    const top = Math.max(rect.top * zoomFactor, bodyRect.top * zoomFactor);
-    const bottom = Math.min(rect.bottom * zoomFactor, bodyRect.bottom * zoomFactor);
-    const right = Math.min(rect.right * zoomFactor, bodyRect.right * zoomFactor);
-
-    return {x: left, y: top, width: right - left, height: bottom - top};
-  }
-
-  /**
-   * @param {boolean=} force
-   */
-  update(force) {
-    delete this._updateId;
-    const rect = this._dipPageRect();
-    const bounds = {
-      x: Math.round(rect.x),
-      y: Math.round(rect.y),
-      height: Math.max(1, Math.round(rect.height)),
-      width: Math.max(1, Math.round(rect.width)),
-    };
-    if (force) {
-      // Short term fix for Lighthouse interop.
-      --bounds.height;
-      this.dispatchEventToListeners(Emulation.InspectedPagePlaceholder.Events.Update, bounds);
-      ++bounds.height;
-    }
-    this.dispatchEventToListeners(Emulation.InspectedPagePlaceholder.Events.Update, bounds);
-  }
-};
-
-/**
- * @return {!Emulation.InspectedPagePlaceholder}
- */
-Emulation.InspectedPagePlaceholder.instance = function() {
-  return self.singleton(Emulation.InspectedPagePlaceholder);
-};
-
-/** @enum {symbol} */
-Emulation.InspectedPagePlaceholder.Events = {
-  Update: Symbol('Update')
-};
diff --git a/front_end/emulation/MediaQueryInspector.js b/front_end/emulation/MediaQueryInspector.js
deleted file mode 100644
index 04f62da..0000000
--- a/front_end/emulation/MediaQueryInspector.js
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!SDK.CSSModel>}
- * @unrestricted
- */
-Emulation.MediaQueryInspector = class extends UI.Widget {
-  /**
-   * @param {function():number} getWidthCallback
-   * @param {function(number)} setWidthCallback
-   */
-  constructor(getWidthCallback, setWidthCallback) {
-    super(true);
-    this.registerRequiredCSS('emulation/mediaQueryInspector.css');
-    this.contentElement.classList.add('media-inspector-view');
-    this.contentElement.addEventListener('click', this._onMediaQueryClicked.bind(this), false);
-    this.contentElement.addEventListener('contextmenu', this._onContextMenu.bind(this), false);
-    this._mediaThrottler = new Common.Throttler(0);
-
-    this._getWidthCallback = getWidthCallback;
-    this._setWidthCallback = setWidthCallback;
-    this._scale = 1;
-
-    SDK.targetManager.observeModels(SDK.CSSModel, this);
-    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this._renderMediaQueries.bind(this), this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSModel} cssModel
-   */
-  modelAdded(cssModel) {
-    // FIXME: adapt this to multiple targets.
-    if (this._cssModel)
-      return;
-    this._cssModel = cssModel;
-    this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._scheduleMediaQueriesUpdate, this);
-    this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this._scheduleMediaQueriesUpdate, this);
-    this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._scheduleMediaQueriesUpdate, this);
-    this._cssModel.addEventListener(
-        SDK.CSSModel.Events.MediaQueryResultChanged, this._scheduleMediaQueriesUpdate, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSModel} cssModel
-   */
-  modelRemoved(cssModel) {
-    if (cssModel !== this._cssModel)
-      return;
-    this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._scheduleMediaQueriesUpdate, this);
-    this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetRemoved, this._scheduleMediaQueriesUpdate, this);
-    this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetChanged, this._scheduleMediaQueriesUpdate, this);
-    this._cssModel.removeEventListener(
-        SDK.CSSModel.Events.MediaQueryResultChanged, this._scheduleMediaQueriesUpdate, this);
-    delete this._cssModel;
-  }
-
-  /**
-   * @param {number} scale
-   */
-  setAxisTransform(scale) {
-    if (Math.abs(this._scale - scale) < 1e-8)
-      return;
-    this._scale = scale;
-    this._renderMediaQueries();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMediaQueryClicked(event) {
-    const mediaQueryMarker = event.target.enclosingNodeOrSelfWithClass('media-inspector-bar');
-    if (!mediaQueryMarker)
-      return;
-
-    const model = mediaQueryMarker._model;
-    if (model.section() === Emulation.MediaQueryInspector.Section.Max) {
-      this._setWidthCallback(model.maxWidthExpression().computedLength());
-      return;
-    }
-    if (model.section() === Emulation.MediaQueryInspector.Section.Min) {
-      this._setWidthCallback(model.minWidthExpression().computedLength());
-      return;
-    }
-    const currentWidth = this._getWidthCallback();
-    if (currentWidth !== model.minWidthExpression().computedLength())
-      this._setWidthCallback(model.minWidthExpression().computedLength());
-    else
-      this._setWidthCallback(model.maxWidthExpression().computedLength());
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onContextMenu(event) {
-    if (!this._cssModel || !this._cssModel.isEnabled())
-      return;
-
-    const mediaQueryMarker = event.target.enclosingNodeOrSelfWithClass('media-inspector-bar');
-    if (!mediaQueryMarker)
-      return;
-
-    const locations = mediaQueryMarker._locations;
-    const uiLocations = new Map();
-    for (let i = 0; i < locations.length; ++i) {
-      const uiLocation = Bindings.cssWorkspaceBinding.rawLocationToUILocation(locations[i]);
-      if (!uiLocation)
-        continue;
-      const descriptor = String.sprintf(
-          '%s:%d:%d', uiLocation.uiSourceCode.url(), uiLocation.lineNumber + 1, uiLocation.columnNumber + 1);
-      uiLocations.set(descriptor, uiLocation);
-    }
-
-    const contextMenuItems = uiLocations.keysArray().sort();
-    const contextMenu = new UI.ContextMenu(event);
-    const subMenuItem = contextMenu.defaultSection().appendSubMenuItem(Common.UIString('Reveal in source code'));
-    for (let i = 0; i < contextMenuItems.length; ++i) {
-      const title = contextMenuItems[i];
-      subMenuItem.defaultSection().appendItem(
-          title, this._revealSourceLocation.bind(this, /** @type {!Workspace.UILocation} */ (uiLocations.get(title))));
-    }
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Workspace.UILocation} location
-   */
-  _revealSourceLocation(location) {
-    Common.Revealer.reveal(location);
-  }
-
-  _scheduleMediaQueriesUpdate() {
-    if (!this.isShowing())
-      return;
-    this._mediaThrottler.schedule(this._refetchMediaQueries.bind(this));
-  }
-
-  _refetchMediaQueries() {
-    if (!this.isShowing() || !this._cssModel)
-      return Promise.resolve();
-
-    return this._cssModel.mediaQueriesPromise().then(this._rebuildMediaQueries.bind(this));
-  }
-
-  /**
-   * @param {!Array.<!Emulation.MediaQueryInspector.MediaQueryUIModel>} models
-   * @return {!Array.<!Emulation.MediaQueryInspector.MediaQueryUIModel>}
-   */
-  _squashAdjacentEqual(models) {
-    const filtered = [];
-    for (let i = 0; i < models.length; ++i) {
-      const last = filtered.peekLast();
-      if (!last || !last.equals(models[i]))
-        filtered.push(models[i]);
-    }
-    return filtered;
-  }
-
-  /**
-   * @param {!Array.<!SDK.CSSMedia>} cssMedias
-   */
-  _rebuildMediaQueries(cssMedias) {
-    let queryModels = [];
-    for (let i = 0; i < cssMedias.length; ++i) {
-      const cssMedia = cssMedias[i];
-      if (!cssMedia.mediaList)
-        continue;
-      for (let j = 0; j < cssMedia.mediaList.length; ++j) {
-        const mediaQuery = cssMedia.mediaList[j];
-        const queryModel = Emulation.MediaQueryInspector.MediaQueryUIModel.createFromMediaQuery(cssMedia, mediaQuery);
-        if (queryModel && queryModel.rawLocation())
-          queryModels.push(queryModel);
-      }
-    }
-    queryModels.sort(compareModels);
-    queryModels = this._squashAdjacentEqual(queryModels);
-
-    let allEqual = this._cachedQueryModels && this._cachedQueryModels.length === queryModels.length;
-    for (let i = 0; allEqual && i < queryModels.length; ++i)
-      allEqual = allEqual && this._cachedQueryModels[i].equals(queryModels[i]);
-    if (allEqual)
-      return;
-    this._cachedQueryModels = queryModels;
-    this._renderMediaQueries();
-
-    /**
-     * @param {!Emulation.MediaQueryInspector.MediaQueryUIModel} model1
-     * @param {!Emulation.MediaQueryInspector.MediaQueryUIModel} model2
-     * @return {number}
-     */
-    function compareModels(model1, model2) {
-      return model1.compareTo(model2);
-    }
-  }
-
-  _renderMediaQueries() {
-    if (!this._cachedQueryModels || !this.isShowing())
-      return;
-
-    const markers = [];
-    let lastMarker = null;
-    for (let i = 0; i < this._cachedQueryModels.length; ++i) {
-      const model = this._cachedQueryModels[i];
-      if (lastMarker && lastMarker.model.dimensionsEqual(model)) {
-        lastMarker.locations.push(model.rawLocation());
-        lastMarker.active = lastMarker.active || model.active();
-      } else {
-        lastMarker = {active: model.active(), model: model, locations: [model.rawLocation()]};
-        markers.push(lastMarker);
-      }
-    }
-
-    this.contentElement.removeChildren();
-
-    let container = null;
-    for (let i = 0; i < markers.length; ++i) {
-      if (!i || markers[i].model.section() !== markers[i - 1].model.section())
-        container = this.contentElement.createChild('div', 'media-inspector-marker-container');
-      const marker = markers[i];
-      const bar = this._createElementFromMediaQueryModel(marker.model);
-      bar._model = marker.model;
-      bar._locations = marker.locations;
-      bar.classList.toggle('media-inspector-marker-inactive', !marker.active);
-      container.appendChild(bar);
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  _zoomFactor() {
-    return UI.zoomManager.zoomFactor() / this._scale;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._scheduleMediaQueriesUpdate();
-  }
-
-  /**
-   * @param {!Emulation.MediaQueryInspector.MediaQueryUIModel} model
-   * @return {!Element}
-   */
-  _createElementFromMediaQueryModel(model) {
-    const zoomFactor = this._zoomFactor();
-    const minWidthValue = model.minWidthExpression() ? model.minWidthExpression().computedLength() / zoomFactor : 0;
-    const maxWidthValue = model.maxWidthExpression() ? model.maxWidthExpression().computedLength() / zoomFactor : 0;
-    const result = createElementWithClass('div', 'media-inspector-bar');
-
-    if (model.section() === Emulation.MediaQueryInspector.Section.Max) {
-      result.createChild('div', 'media-inspector-marker-spacer');
-      const markerElement = result.createChild('div', 'media-inspector-marker media-inspector-marker-max-width');
-      markerElement.style.width = maxWidthValue + 'px';
-      markerElement.title = model.mediaText();
-      appendLabel(markerElement, model.maxWidthExpression(), false, false);
-      appendLabel(markerElement, model.maxWidthExpression(), true, true);
-      result.createChild('div', 'media-inspector-marker-spacer');
-    }
-
-    if (model.section() === Emulation.MediaQueryInspector.Section.MinMax) {
-      result.createChild('div', 'media-inspector-marker-spacer');
-      const leftElement = result.createChild('div', 'media-inspector-marker media-inspector-marker-min-max-width');
-      leftElement.style.width = (maxWidthValue - minWidthValue) * 0.5 + 'px';
-      leftElement.title = model.mediaText();
-      appendLabel(leftElement, model.minWidthExpression(), true, false);
-      appendLabel(leftElement, model.maxWidthExpression(), false, true);
-      result.createChild('div', 'media-inspector-marker-spacer').style.flex = '0 0 ' + minWidthValue + 'px';
-      const rightElement = result.createChild('div', 'media-inspector-marker media-inspector-marker-min-max-width');
-      rightElement.style.width = (maxWidthValue - minWidthValue) * 0.5 + 'px';
-      rightElement.title = model.mediaText();
-      appendLabel(rightElement, model.minWidthExpression(), true, false);
-      appendLabel(rightElement, model.maxWidthExpression(), false, true);
-      result.createChild('div', 'media-inspector-marker-spacer');
-    }
-
-    if (model.section() === Emulation.MediaQueryInspector.Section.Min) {
-      const leftElement = result.createChild(
-          'div', 'media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-left');
-      leftElement.title = model.mediaText();
-      appendLabel(leftElement, model.minWidthExpression(), false, false);
-      result.createChild('div', 'media-inspector-marker-spacer').style.flex = '0 0 ' + minWidthValue + 'px';
-      const rightElement = result.createChild(
-          'div', 'media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-right');
-      rightElement.title = model.mediaText();
-      appendLabel(rightElement, model.minWidthExpression(), true, true);
-    }
-
-    function appendLabel(marker, expression, atLeft, leftAlign) {
-      marker
-          .createChild(
-              'div',
-              'media-inspector-marker-label-container ' + (atLeft ? 'media-inspector-marker-label-container-left' :
-                                                                    'media-inspector-marker-label-container-right'))
-          .createChild(
-              'span', 'media-inspector-marker-label ' +
-                  (leftAlign ? 'media-inspector-label-left' : 'media-inspector-label-right'))
-          .textContent = expression.value() + expression.unit();
-    }
-
-    return result;
-  }
-};
-
-/**
- * @enum {number}
- */
-Emulation.MediaQueryInspector.Section = {
-  Max: 0,
-  MinMax: 1,
-  Min: 2
-};
-
-/**
- * @unrestricted
- */
-Emulation.MediaQueryInspector.MediaQueryUIModel = class {
-  /**
-   * @param {!SDK.CSSMedia} cssMedia
-   * @param {?SDK.CSSMediaQueryExpression} minWidthExpression
-   * @param {?SDK.CSSMediaQueryExpression} maxWidthExpression
-   * @param {boolean} active
-   */
-  constructor(cssMedia, minWidthExpression, maxWidthExpression, active) {
-    this._cssMedia = cssMedia;
-    this._minWidthExpression = minWidthExpression;
-    this._maxWidthExpression = maxWidthExpression;
-    this._active = active;
-    if (maxWidthExpression && !minWidthExpression)
-      this._section = Emulation.MediaQueryInspector.Section.Max;
-    else if (minWidthExpression && maxWidthExpression)
-      this._section = Emulation.MediaQueryInspector.Section.MinMax;
-    else
-      this._section = Emulation.MediaQueryInspector.Section.Min;
-  }
-
-  /**
-   * @param {!SDK.CSSMedia} cssMedia
-   * @param {!SDK.CSSMediaQuery} mediaQuery
-   * @return {?Emulation.MediaQueryInspector.MediaQueryUIModel}
-   */
-  static createFromMediaQuery(cssMedia, mediaQuery) {
-    let maxWidthExpression = null;
-    let maxWidthPixels = Number.MAX_VALUE;
-    let minWidthExpression = null;
-    let minWidthPixels = Number.MIN_VALUE;
-    const expressions = mediaQuery.expressions();
-    for (let i = 0; i < expressions.length; ++i) {
-      const expression = expressions[i];
-      const feature = expression.feature();
-      if (feature.indexOf('width') === -1)
-        continue;
-      const pixels = expression.computedLength();
-      if (feature.startsWith('max-') && pixels < maxWidthPixels) {
-        maxWidthExpression = expression;
-        maxWidthPixels = pixels;
-      } else if (feature.startsWith('min-') && pixels > minWidthPixels) {
-        minWidthExpression = expression;
-        minWidthPixels = pixels;
-      }
-    }
-    if (minWidthPixels > maxWidthPixels || (!maxWidthExpression && !minWidthExpression))
-      return null;
-
-    return new Emulation.MediaQueryInspector.MediaQueryUIModel(
-        cssMedia, minWidthExpression, maxWidthExpression, mediaQuery.active());
-  }
-
-  /**
-   * @param {!Emulation.MediaQueryInspector.MediaQueryUIModel} other
-   * @return {boolean}
-   */
-  equals(other) {
-    return this.compareTo(other) === 0;
-  }
-
-  /**
-   * @param {!Emulation.MediaQueryInspector.MediaQueryUIModel} other
-   * @return {boolean}
-   */
-  dimensionsEqual(other) {
-    return this.section() === other.section() &&
-        (!this.minWidthExpression() ||
-         (this.minWidthExpression().computedLength() === other.minWidthExpression().computedLength())) &&
-        (!this.maxWidthExpression() ||
-         (this.maxWidthExpression().computedLength() === other.maxWidthExpression().computedLength()));
-  }
-
-  /**
-   * @param {!Emulation.MediaQueryInspector.MediaQueryUIModel} other
-   * @return {number}
-   */
-  compareTo(other) {
-    if (this.section() !== other.section())
-      return this.section() - other.section();
-    if (this.dimensionsEqual(other)) {
-      const myLocation = this.rawLocation();
-      const otherLocation = other.rawLocation();
-      if (!myLocation && !otherLocation)
-        return this.mediaText().compareTo(other.mediaText());
-      if (myLocation && !otherLocation)
-        return 1;
-      if (!myLocation && otherLocation)
-        return -1;
-      if (this.active() !== other.active())
-        return this.active() ? -1 : 1;
-      return myLocation.url.compareTo(otherLocation.url) || myLocation.lineNumber - otherLocation.lineNumber ||
-          myLocation.columnNumber - otherLocation.columnNumber;
-    }
-    if (this.section() === Emulation.MediaQueryInspector.Section.Max)
-      return other.maxWidthExpression().computedLength() - this.maxWidthExpression().computedLength();
-    if (this.section() === Emulation.MediaQueryInspector.Section.Min)
-      return this.minWidthExpression().computedLength() - other.minWidthExpression().computedLength();
-    return this.minWidthExpression().computedLength() - other.minWidthExpression().computedLength() ||
-        other.maxWidthExpression().computedLength() - this.maxWidthExpression().computedLength();
-  }
-
-  /**
-   * @return {!Emulation.MediaQueryInspector.Section}
-   */
-  section() {
-    return this._section;
-  }
-
-  /**
-   * @return {string}
-   */
-  mediaText() {
-    return this._cssMedia.text;
-  }
-
-  /**
-   * @return {?SDK.CSSLocation}
-   */
-  rawLocation() {
-    if (!this._rawLocation)
-      this._rawLocation = this._cssMedia.rawLocation();
-    return this._rawLocation;
-  }
-
-  /**
-   * @return {?SDK.CSSMediaQueryExpression}
-   */
-  minWidthExpression() {
-    return this._minWidthExpression;
-  }
-
-  /**
-   * @return {?SDK.CSSMediaQueryExpression}
-   */
-  maxWidthExpression() {
-    return this._maxWidthExpression;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  active() {
-    return this._active;
-  }
-};
diff --git a/front_end/emulation/SensorsView.js b/front_end/emulation/SensorsView.js
deleted file mode 100644
index 9bb1e55..0000000
--- a/front_end/emulation/SensorsView.js
+++ /dev/null
@@ -1,525 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Emulation.SensorsView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('emulation/sensors.css');
-    this.contentElement.classList.add('sensors-view');
-
-    this._geolocationSetting = Common.settings.createSetting('emulation.geolocationOverride', '');
-    this._geolocation = SDK.EmulationModel.Geolocation.parseSetting(this._geolocationSetting.get());
-    this._geolocationOverrideEnabled = false;
-    this._createGeolocationSection(this._geolocation);
-
-    this.contentElement.createChild('div').classList.add('panel-section-separator');
-
-    this._deviceOrientationSetting = Common.settings.createSetting('emulation.deviceOrientationOverride', '');
-    this._deviceOrientation = SDK.EmulationModel.DeviceOrientation.parseSetting(this._deviceOrientationSetting.get());
-    this._deviceOrientationOverrideEnabled = false;
-    this._createDeviceOrientationSection();
-
-    this.contentElement.createChild('div').classList.add('panel-section-separator');
-
-    this._appendTouchControl();
-  }
-
-  /**
-   * @return {!Emulation.SensorsView}
-   */
-  static instance() {
-    if (!Emulation.SensorsView._instanceObject)
-      Emulation.SensorsView._instanceObject = new Emulation.SensorsView();
-    return Emulation.SensorsView._instanceObject;
-  }
-
-  /**
-   * @param {!SDK.EmulationModel.Geolocation} geolocation
-   */
-  _createGeolocationSection(geolocation) {
-    const geogroup = this.contentElement.createChild('section', 'sensors-group');
-    geogroup.createChild('div', 'sensors-group-title').textContent = Common.UIString('Geolocation');
-    const fields = geogroup.createChild('div', 'geo-fields');
-
-    const noOverrideOption = {
-      title: Common.UIString('No override'),
-      location: Emulation.SensorsView.NonPresetOptions.NoOverride
-    };
-    const customLocationOption = {
-      title: Common.UIString('Custom location...'),
-      location: Emulation.SensorsView.NonPresetOptions.Custom
-    };
-    this._locationSelectElement = this.contentElement.createChild('select', 'chrome-select');
-    this._locationSelectElement.appendChild(new Option(noOverrideOption.title, noOverrideOption.location));
-    this._locationSelectElement.appendChild(new Option(customLocationOption.title, customLocationOption.location));
-
-    const locationGroups = Emulation.SensorsView.PresetLocations;
-    for (let i = 0; i < locationGroups.length; ++i) {
-      const group = locationGroups[i].value;
-      const groupElement = this._locationSelectElement.createChild('optgroup');
-      groupElement.label = locationGroups[i].title;
-      for (let j = 0; j < group.length; ++j)
-        groupElement.appendChild(new Option(group[j].title, group[j].location));
-    }
-    this._locationSelectElement.selectedIndex = 0;
-    fields.appendChild(this._locationSelectElement);
-    this._locationSelectElement.addEventListener('change', this._geolocationSelectChanged.bind(this));
-
-    // Validated input fieldset.
-    this._fieldsetElement = fields.createChild('fieldset');
-    this._fieldsetElement.disabled = !this._geolocationOverrideEnabled;
-    this._fieldsetElement.id = 'geolocation-override-section';
-
-    const latitudeGroup = this._fieldsetElement.createChild('div', 'latlong-group');
-    const longitudeGroup = this._fieldsetElement.createChild('div', 'latlong-group');
-
-    this._latitudeInput = UI.createInput('', 'number');
-    latitudeGroup.appendChild(this._latitudeInput);
-    this._latitudeInput.setAttribute('step', 'any');
-    this._latitudeInput.value = 0;
-    this._latitudeSetter = UI.bindInput(
-        this._latitudeInput, this._applyGeolocationUserInput.bind(this),
-        SDK.EmulationModel.Geolocation.latitudeValidator, true, 0.1);
-    this._latitudeSetter(String(geolocation.latitude));
-
-    this._longitudeInput = UI.createInput('', 'number');
-    longitudeGroup.appendChild(this._longitudeInput);
-    this._longitudeInput.setAttribute('step', 'any');
-    this._longitudeInput.value = 0;
-    this._longitudeSetter = UI.bindInput(
-        this._longitudeInput, this._applyGeolocationUserInput.bind(this),
-        SDK.EmulationModel.Geolocation.longitudeValidator, true, 0.1);
-    this._longitudeSetter(String(geolocation.longitude));
-
-    const cmdOrCtrl = Host.isMac() ? '\u2318' : 'Ctrl';
-    const modifierKeyMessage = ls`Adjust with mousewheel or up/down keys. ${cmdOrCtrl}: ±10, Shift: ±1, Alt: ±0.01`;
-    this._latitudeInput.title = modifierKeyMessage;
-    this._longitudeInput.title = modifierKeyMessage;
-
-    latitudeGroup.createChild('div', 'latlong-title').textContent = Common.UIString('Latitude');
-    longitudeGroup.createChild('div', 'latlong-title').textContent = Common.UIString('Longitude');
-  }
-
-  _geolocationSelectChanged() {
-    this._fieldsetElement.disabled = false;
-    const value = this._locationSelectElement.options[this._locationSelectElement.selectedIndex].value;
-    if (value === Emulation.SensorsView.NonPresetOptions.NoOverride) {
-      this._geolocationOverrideEnabled = false;
-      this._fieldsetElement.disabled = true;
-    } else if (value === Emulation.SensorsView.NonPresetOptions.Custom) {
-      this._geolocationOverrideEnabled = true;
-    } else if (value === Emulation.SensorsView.NonPresetOptions.Unavailable) {
-      this._geolocationOverrideEnabled = true;
-      this._geolocation = new SDK.EmulationModel.Geolocation(0, 0, true);
-    } else {
-      this._geolocationOverrideEnabled = true;
-      const coordinates = JSON.parse(value);
-      this._geolocation = new SDK.EmulationModel.Geolocation(coordinates[0], coordinates[1], false);
-      this._latitudeSetter(coordinates[0]);
-      this._longitudeSetter(coordinates[1]);
-    }
-
-    this._applyGeolocation();
-    if (value === Emulation.SensorsView.NonPresetOptions.Custom)
-      this._latitudeInput.focus();
-  }
-
-  _applyGeolocationUserInput() {
-    const geolocation = SDK.EmulationModel.Geolocation.parseUserInput(
-        this._latitudeInput.value.trim(), this._longitudeInput.value.trim(), '');
-    if (!geolocation)
-      return;
-
-    this._setSelectElementLabel(this._locationSelectElement, Emulation.SensorsView.NonPresetOptions.Custom);
-    this._geolocation = geolocation;
-    this._applyGeolocation();
-  }
-
-  _applyGeolocation() {
-    if (this._geolocationOverrideEnabled)
-      this._geolocationSetting.set(this._geolocation.toSetting());
-    for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-      emulationModel.emulateGeolocation(this._geolocationOverrideEnabled ? this._geolocation : null);
-  }
-
-  _createDeviceOrientationSection() {
-    const orientationGroup = this.contentElement.createChild('section', 'sensors-group');
-    orientationGroup.createChild('div', 'sensors-group-title').textContent = Common.UIString('Orientation');
-    const orientationContent = orientationGroup.createChild('div', 'orientation-content');
-    const fields = orientationContent.createChild('div', 'orientation-fields');
-
-    const orientationOffOption = {
-      title: Common.UIString('Off'),
-      orientation: Emulation.SensorsView.NonPresetOptions.NoOverride
-    };
-    const customOrientationOption = {
-      title: Common.UIString('Custom orientation...'),
-      orientation: Emulation.SensorsView.NonPresetOptions.Custom
-    };
-    this._orientationSelectElement = this.contentElement.createChild('select', 'chrome-select');
-    this._orientationSelectElement.appendChild(
-        new Option(orientationOffOption.title, orientationOffOption.orientation));
-    this._orientationSelectElement.appendChild(
-        new Option(customOrientationOption.title, customOrientationOption.orientation));
-
-    const orientationGroups = Emulation.SensorsView.PresetOrientations;
-    for (let i = 0; i < orientationGroups.length; ++i) {
-      const groupElement = this._orientationSelectElement.createChild('optgroup');
-      groupElement.label = orientationGroups[i].title;
-      const group = orientationGroups[i].value;
-      for (let j = 0; j < group.length; ++j)
-        groupElement.appendChild(new Option(group[j].title, group[j].orientation));
-    }
-    this._orientationSelectElement.selectedIndex = 0;
-    fields.appendChild(this._orientationSelectElement);
-    this._orientationSelectElement.addEventListener('change', this._orientationSelectChanged.bind(this));
-
-    this._deviceOrientationFieldset = this._createDeviceOrientationOverrideElement(this._deviceOrientation);
-
-    this._stageElement = orientationContent.createChild('div', 'orientation-stage');
-    this._stageElement.title = Common.UIString('Shift+drag horizontally to rotate around the y-axis');
-    this._orientationLayer = this._stageElement.createChild('div', 'orientation-layer');
-    this._boxElement = this._orientationLayer.createChild('section', 'orientation-box orientation-element');
-
-    this._boxElement.createChild('section', 'orientation-front orientation-element');
-    this._boxElement.createChild('section', 'orientation-top orientation-element');
-    this._boxElement.createChild('section', 'orientation-back orientation-element');
-    this._boxElement.createChild('section', 'orientation-left orientation-element');
-    this._boxElement.createChild('section', 'orientation-right orientation-element');
-    this._boxElement.createChild('section', 'orientation-bottom orientation-element');
-
-    UI.installDragHandle(
-        this._stageElement, this._onBoxDragStart.bind(this), this._onBoxDrag.bind(this), null, '-webkit-grabbing',
-        '-webkit-grab');
-
-    fields.appendChild(this._deviceOrientationFieldset);
-    this._enableOrientationFields(true);
-    this._setBoxOrientation(this._deviceOrientation, false);
-  }
-
-  /**
-   * @param {?boolean} disable
-   */
-  _enableOrientationFields(disable) {
-    if (disable) {
-      this._deviceOrientationFieldset.disabled = true;
-      this._stageElement.classList.add('disabled');
-    } else {
-      this._deviceOrientationFieldset.disabled = false;
-      this._stageElement.classList.remove('disabled');
-    }
-  }
-
-  _orientationSelectChanged() {
-    const value = this._orientationSelectElement.options[this._orientationSelectElement.selectedIndex].value;
-    this._enableOrientationFields(false);
-
-    if (value === Emulation.SensorsView.NonPresetOptions.NoOverride) {
-      this._deviceOrientationOverrideEnabled = false;
-      this._enableOrientationFields(true);
-    } else if (value === Emulation.SensorsView.NonPresetOptions.Custom) {
-      this._deviceOrientationOverrideEnabled = true;
-      this._alphaElement.focus();
-    } else {
-      const parsedValue = JSON.parse(value);
-      this._deviceOrientationOverrideEnabled = true;
-      this._deviceOrientation =
-          new SDK.EmulationModel.DeviceOrientation(parsedValue[0], parsedValue[1], parsedValue[2]);
-      this._setDeviceOrientation(
-          this._deviceOrientation, Emulation.SensorsView.DeviceOrientationModificationSource.SelectPreset);
-    }
-  }
-
-  _applyDeviceOrientation() {
-    if (this._deviceOrientationOverrideEnabled)
-      this._deviceOrientationSetting.set(this._deviceOrientation.toSetting());
-    for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-      emulationModel.emulateDeviceOrientation(this._deviceOrientationOverrideEnabled ? this._deviceOrientation : null);
-  }
-
-  /**
-   * @param {!Element} selectElement
-   * @param {string} labelValue
-   */
-  _setSelectElementLabel(selectElement, labelValue) {
-    const optionValues = Array.prototype.map.call(selectElement.options, x => x.value);
-    selectElement.selectedIndex = optionValues.indexOf(labelValue);
-  }
-
-  _applyDeviceOrientationUserInput() {
-    this._setDeviceOrientation(
-        SDK.EmulationModel.DeviceOrientation.parseUserInput(
-            this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()),
-        Emulation.SensorsView.DeviceOrientationModificationSource.UserInput);
-    this._setSelectElementLabel(this._orientationSelectElement, Emulation.SensorsView.NonPresetOptions.Custom);
-  }
-
-  _resetDeviceOrientation() {
-    this._setDeviceOrientation(
-        new SDK.EmulationModel.DeviceOrientation(0, 90, 0),
-        Emulation.SensorsView.DeviceOrientationModificationSource.ResetButton);
-    this._setSelectElementLabel(this._orientationSelectElement, '[0, 90, 0]');
-  }
-
-  /**
-   * @param {?SDK.EmulationModel.DeviceOrientation} deviceOrientation
-   * @param {!Emulation.SensorsView.DeviceOrientationModificationSource} modificationSource
-   */
-  _setDeviceOrientation(deviceOrientation, modificationSource) {
-    if (!deviceOrientation)
-      return;
-
-    /**
-     * @param {number} angle
-     * @return {number}
-     */
-    function roundAngle(angle) {
-      return Math.round(angle * 10000) / 10000;
-    }
-
-    if (modificationSource !== Emulation.SensorsView.DeviceOrientationModificationSource.UserInput) {
-      this._alphaSetter(roundAngle(deviceOrientation.alpha));
-      this._betaSetter(roundAngle(deviceOrientation.beta));
-      this._gammaSetter(roundAngle(deviceOrientation.gamma));
-    }
-
-    const animate = modificationSource !== Emulation.SensorsView.DeviceOrientationModificationSource.UserDrag;
-    this._setBoxOrientation(deviceOrientation, animate);
-
-    this._deviceOrientation = deviceOrientation;
-    this._applyDeviceOrientation();
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Element} input
-   * @param {string} label
-   * @return {function(string)}
-   */
-  _createAxisInput(parentElement, input, label) {
-    const div = parentElement.createChild('div', 'orientation-axis-input-container');
-    div.appendChild(input);
-    div.createTextChild(label);
-    input.type = 'number';
-    return UI.bindInput(
-        input, this._applyDeviceOrientationUserInput.bind(this), SDK.EmulationModel.DeviceOrientation.validator, true);
-  }
-
-  /**
-   * @param {!SDK.EmulationModel.DeviceOrientation} deviceOrientation
-   * @return {!Element}
-   */
-  _createDeviceOrientationOverrideElement(deviceOrientation) {
-    const fieldsetElement = createElement('fieldset');
-    fieldsetElement.classList.add('device-orientation-override-section');
-    const cellElement = fieldsetElement.createChild('td', 'orientation-inputs-cell');
-
-    this._alphaElement = UI.createInput();
-    this._alphaElement.setAttribute('step', 'any');
-    this._alphaSetter = this._createAxisInput(cellElement, this._alphaElement, Common.UIString('\u03B1 (alpha)'));
-    this._alphaSetter(String(deviceOrientation.alpha));
-
-    this._betaElement = UI.createInput();
-    this._betaElement.setAttribute('step', 'any');
-    this._betaSetter = this._createAxisInput(cellElement, this._betaElement, Common.UIString('\u03B2 (beta)'));
-    this._betaSetter(String(deviceOrientation.beta));
-
-    this._gammaElement = UI.createInput();
-    this._gammaElement.setAttribute('step', 'any');
-    this._gammaSetter = this._createAxisInput(cellElement, this._gammaElement, Common.UIString('\u03B3 (gamma)'));
-    this._gammaSetter(String(deviceOrientation.gamma));
-
-    cellElement.appendChild(UI.createTextButton(
-        Common.UIString('Reset'), this._resetDeviceOrientation.bind(this), 'orientation-reset-button'));
-    return fieldsetElement;
-  }
-
-  /**
-   * @param {!SDK.EmulationModel.DeviceOrientation} deviceOrientation
-   * @param {boolean} animate
-   */
-  _setBoxOrientation(deviceOrientation, animate) {
-    if (animate)
-      this._stageElement.classList.add('is-animating');
-    else
-      this._stageElement.classList.remove('is-animating');
-
-    // The CSS transform should not depend on matrix3d, which does not interpolate well.
-    const matrix = new WebKitCSSMatrix();
-    this._boxMatrix = matrix.rotate(-deviceOrientation.beta, deviceOrientation.gamma, -deviceOrientation.alpha);
-    const eulerAngles =
-        new UI.Geometry.EulerAngles(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
-    this._orientationLayer.style.transform = eulerAngles.toRotate3DString();
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _onBoxDrag(event) {
-    const mouseMoveVector = this._calculateRadiusVector(event.x, event.y);
-    if (!mouseMoveVector)
-      return true;
-
-    event.consume(true);
-    let axis, angle;
-    if (event.shiftKey) {
-      axis = new UI.Geometry.Vector(0, 0, -1);
-      angle = (this._mouseDownVector.x - mouseMoveVector.x) * Emulation.SensorsView.ShiftDragOrientationSpeed;
-    } else {
-      axis = UI.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
-      angle = UI.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
-    }
-
-    // The mouse movement vectors occur in the screen space, which is offset by 90 degrees from
-    // the actual device orientation.
-    let currentMatrix = new WebKitCSSMatrix();
-    currentMatrix = currentMatrix.rotate(-90, 0, 0)
-                        .rotateAxisAngle(axis.x, axis.y, axis.z, angle)
-                        .rotate(90, 0, 0)
-                        .multiply(this._originalBoxMatrix);
-
-    const eulerAngles = UI.Geometry.EulerAngles.fromRotationMatrix(currentMatrix);
-    const newOrientation =
-        new SDK.EmulationModel.DeviceOrientation(-eulerAngles.alpha, -eulerAngles.beta, eulerAngles.gamma);
-    this._setDeviceOrientation(newOrientation, Emulation.SensorsView.DeviceOrientationModificationSource.UserDrag);
-    this._setSelectElementLabel(this._orientationSelectElement, Emulation.SensorsView.NonPresetOptions.Custom);
-    return false;
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _onBoxDragStart(event) {
-    if (!this._deviceOrientationOverrideEnabled)
-      return false;
-
-    this._mouseDownVector = this._calculateRadiusVector(event.x, event.y);
-    this._originalBoxMatrix = this._boxMatrix;
-
-    if (!this._mouseDownVector)
-      return false;
-
-    event.consume(true);
-    return true;
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @return {?UI.Geometry.Vector}
-   */
-  _calculateRadiusVector(x, y) {
-    const rect = this._stageElement.getBoundingClientRect();
-    const radius = Math.max(rect.width, rect.height) / 2;
-    const sphereX = (x - rect.left - rect.width / 2) / radius;
-    const sphereY = (y - rect.top - rect.height / 2) / radius;
-    const sqrSum = sphereX * sphereX + sphereY * sphereY;
-    if (sqrSum > 0.5)
-      return new UI.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
-
-    return new UI.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
-  }
-
-  _appendTouchControl() {
-    const groupElement = this.contentElement.createChild('div', 'sensors-group');
-    const title = groupElement.createChild('div', 'sensors-group-title');
-    const fieldsElement = groupElement.createChild('div', 'sensors-group-fields');
-
-    title.textContent = Common.UIString('Touch');
-    const select = fieldsElement.createChild('select', 'chrome-select');
-    select.appendChild(new Option(Common.UIString('Device-based'), 'auto'));
-    select.appendChild(new Option(Common.UIString('Force enabled'), 'enabled'));
-    select.addEventListener('change', applyTouch, false);
-
-    const reloadWarning = groupElement.createChild('div', 'reload-warning hidden');
-    reloadWarning.textContent = Common.UIString('*Requires reload');
-
-    function applyTouch() {
-      for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-        emulationModel.overrideEmulateTouch(select.value === 'enabled');
-      reloadWarning.classList.remove('hidden');
-      const resourceTreeModel = SDK.targetManager.models(SDK.ResourceTreeModel)[0];
-      if (resourceTreeModel) {
-        resourceTreeModel.once(SDK.ResourceTreeModel.Events.MainFrameNavigated)
-            .then(() => reloadWarning.classList.add('hidden'));
-      }
-    }
-  }
-};
-
-/** @enum {string} */
-Emulation.SensorsView.DeviceOrientationModificationSource = {
-  UserInput: 'userInput',
-  UserDrag: 'userDrag',
-  ResetButton: 'resetButton',
-  SelectPreset: 'selectPreset'
-};
-
-/** {string} */
-Emulation.SensorsView.NonPresetOptions = {
-  'NoOverride': 'noOverride',
-  'Custom': 'custom',
-  'Unavailable': 'unavailable'
-};
-
-/** @type {!Array.<{title: string, value: !Array.<{title: string, location: string}>}>} */
-Emulation.SensorsView.PresetLocations = [
-  {
-    title: 'Presets',
-    value: [
-      {title: Common.UIString('Berlin'), location: '[52.520007, 13.404954]'},
-      {title: Common.UIString('London'), location: '[51.507351, -0.127758]'},
-      {title: Common.UIString('Moscow'), location: '[55.755826, 37.617300]'},
-      {title: Common.UIString('Mountain View'), location: '[37.386052, -122.083851]'},
-      {title: Common.UIString('Mumbai'), location: '[19.075984, 72.877656]'},
-      {title: Common.UIString('San Francisco'), location: '[37.774929, -122.419416]'},
-      {title: Common.UIString('Shanghai'), location: '[31.230416, 121.473701]'},
-      {title: Common.UIString('São Paulo'), location: '[-23.550520, -46.633309]'},
-      {title: Common.UIString('Tokyo'), location: '[35.689487, 139.691706]'},
-    ]
-  },
-  {
-    title: 'Error',
-    value: [
-      {title: Common.UIString('Location unavailable'), location: Emulation.SensorsView.NonPresetOptions.Unavailable}
-    ]
-  }
-];
-
-/** @type {!Array.<{title: string, value: !Array.<{title: string, orientation: string}>}>} */
-Emulation.SensorsView.PresetOrientations = [{
-  title: 'Presets',
-  value: [
-    {title: Common.UIString('Portrait'), orientation: '[0, 90, 0]'},
-    {title: Common.UIString('Portrait upside down'), orientation: '[180, -90, 0]'},
-    {title: Common.UIString('Landscape left'), orientation: '[0, 90, -90]'},
-    {title: Common.UIString('Landscape right'), orientation: '[0, 90, 90]'},
-    {title: Common.UIString('Display up'), orientation: '[0, 0, 0]'},
-    {title: Common.UIString('Display down'), orientation: '[0, 180, 0]'}
-  ]
-}];
-
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Emulation.SensorsView.ShowActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    UI.viewManager.showView('sensors');
-    return true;
-  }
-};
-
-Emulation.SensorsView.ShiftDragOrientationSpeed = 16;
diff --git a/front_end/emulation/deviceModeToolbar.css b/front_end/emulation/deviceModeToolbar.css
deleted file mode 100644
index a7cb71f..0000000
--- a/front_end/emulation/deviceModeToolbar.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.device-mode-size-input {
-    width: 41px;
-    max-height: 18px;
-    margin: 0 2px;
-    text-align: center;
-}
-
-.device-mode-size-input:focus::-webkit-input-placeholder {
-    color: transparent;
-}
-
-.device-mode-size-input:disabled {
-    background: transparent;
-    -webkit-user-select: none;
-    opacity: 0.6;
-}
-
-.device-mode-x {
-    margin: 0 1px;
-    font-size: 16px;
-}
-
-.device-mode-empty-toolbar-element {
-    width: 0;
-}
diff --git a/front_end/emulation/deviceModeView.css b/front_end/emulation/deviceModeView.css
deleted file mode 100644
index b542d72..0000000
--- a/front_end/emulation/deviceModeView.css
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    overflow: hidden;
-    align-items: stretch;
-    flex: auto;
-    background-color: hsl(0, 0%, 98%);
-}
-
-.device-mode-toolbar {
-    flex: none;
-    background-color: hsl(0, 0%, 98%);
-    border-bottom: 1px solid #ccc;
-    display: flex;
-    flex-direction: row;
-    align-items: stretch;
-}
-
-.device-mode-toolbar .toolbar {
-    overflow: hidden;
-    flex: 0 100000 auto;
-    padding: 0 5px;
-}
-
-.device-mode-toolbar .toolbar.device-mode-toolbar-fixed-size {
-    flex: 0 1 auto;
-}
-
-.device-mode-toolbar-options.toolbar {
-    position: sticky;
-    right: 0;
-    flex: none;
-}
-
-.device-mode-toolbar-spacer {
-    flex: 1 1 0;
-    display: flex;
-    flex-direction: row;
-    overflow: hidden;
-}
-
-.device-mode-content-clip {
-    overflow: hidden;
-    flex: auto;
-}
-
-.device-mode-media-container {
-    flex: none;
-    overflow: hidden;
-    box-shadow: inset 0 -1px #ccc;
-}
-
-.device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-media-container {
-    margin-bottom: 20px;
-}
-
-.device-mode-presets-container {
-    flex: 0 0 20px;
-    display: flex;
-}
-
-.device-mode-presets-container-inner {
-    flex: auto;
-    justify-content: center;
-    position: relative;
-    background-color: hsl(0, 0%, 90%);
-    border: 2px solid hsl(0, 0%, 98%);
-    border-bottom: 2px solid hsl(0, 0%, 98%);
- }
-
-.device-mode-presets-container:hover {
-    transition: opacity 0.1s;
-    transition-delay: 50ms;
-    opacity: 1;
-}
-
-.device-mode-preset-bar-outer {
-    pointer-events: none;
-    display: flex;
-    justify-content: center;
-}
-
-.device-mode-preset-bar {
-    border-left: 2px solid hsl(0, 0%, 98%);
-    border-right: 2px solid hsl(0, 0%, 98%);
-    pointer-events: auto;
-    text-align: center;
-    flex: none;
-    cursor: pointer;
-    color: #5A5A5A;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    white-space: nowrap;
-    margin-bottom: 1px;
-}
-
-.device-mode-preset-bar:hover {
-    transition: background-color 0.1s;
-    transition-delay: 50ms;
-    background-color: #d6d6d6;
-}
-
-.device-mode-preset-bar > span {
-    visibility: hidden;
-}
-
-.device-mode-preset-bar:hover > span {
-    transition: visibility 0.1s;
-    transition-delay: 50ms;
-    visibility: visible;
-}
-
-.device-mode-content-area {
-    flex: auto;
-    position: relative;
-    margin: 0;
-}
-
-.device-mode-screen-area {
-    position: absolute;
-    left: 0;
-    right: 0;
-    width: 0;
-    height: 0;
-    background-color: #171717;
-}
-
-.device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-screen-area {
-    box-shadow: hsl(240, 3%, 84%) 0 0 0 0.5px, hsla(0, 0%, 80%, 0.4) 0 0 20px;
-}
-
-.device-mode-screen-image {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-    height: 100%;
-}
-
-.device-mode-resizer {
-    position: absolute;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    overflow: hidden;
-    transition: background-color 0.1s ease, opacity 0.1s ease;
-}
-
-.device-mode-resizer:hover {
-    background-color: hsla(0, 0%, 0%, 0.1);
-    opacity: 1;
-}
-
-.device-mode-resizer > div {
-    pointer-events: none;
-}
-
-.device-mode-right-resizer {
-    top: 0;
-    bottom: -1px;
-    right: -20px;
-    width: 20px;
-}
-
-.device-mode-left-resizer {
-    top: 0;
-    bottom: -1px;
-    left: -20px;
-    width: 20px;
-    opacity: 0;
-}
-
-.device-mode-bottom-resizer {
-    left: 0;
-    right: -1px;
-    bottom: -20px;
-    height: 20px;
-}
-
-.device-mode-bottom-right-resizer {
-    left: 0;
-    top: 0;
-    right: -20px;
-    bottom: -20px;
-    background-color: hsla(0, 0%, 0%, 0.02);
-}
-
-.device-mode-bottom-left-resizer {
-    left: -20px;
-    top: 0;
-    right: 0;
-    bottom: -20px;
-    opacity: 0;
-}
-
-.device-mode-right-resizer > div {
-    content: url(Images/resizeHorizontal.png);
-    width: 6px;
-    height: 26px;
-}
-
-.device-mode-left-resizer > div {
-    content: url(Images/resizeHorizontal.png);
-    width: 6px;
-    height: 26px;
-}
-
-.device-mode-bottom-resizer > div {
-    content: url(Images/resizeVertical.png);
-    margin-bottom: -2px;
-    width: 26px;
-    height: 6px;
-}
-
-.device-mode-bottom-right-resizer > div {
-    position: absolute;
-    bottom: 3px;
-    right: 3px;
-    width: 13px;
-    height: 13px;
-    content: url(Images/resizeDiagonal.png);
-}
-
-.device-mode-bottom-left-resizer > div {
-    position: absolute;
-    bottom: 3px;
-    left: 3px;
-    width: 13px;
-    height: 13px;
-    content: url(Images/resizeDiagonal.png);
-    transform: rotate(90deg);
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-    .device-mode-right-resizer > div {
-        content: url(Images/resizeHorizontal_2x.png);
-    }
-
-    .device-mode-left-resizer > div {
-        content: url(Images/resizeHorizontal_2x.png);
-    }
-
-    .device-mode-bottom-resizer > div {
-        content: url(Images/resizeVertical_2x.png);
-    }
-
-    .device-mode-bottom-right-resizer > div {
-        content: url(Images/resizeDiagonal_2x.png);
-    }
-
-    .device-mode-bottom-left-resizer > div {
-        content: url(Images/resizeDiagonal_2x.png);
-    }
-} /* media */
-
-.device-mode-page-area {
-    position: absolute;
-    left: 0;
-    right: 0;
-    width: 0;
-    height: 0;
-    display: flex;
-    background-color: #fcfcfc;
-}
-
-.device-mode-ruler {
-    position: absolute;
-    overflow: visible;
-}
-
-.device-mode-ruler-top {
-    height: 20px;
-    right: 0;
-}
-
-.device-mode-ruler-left {
-    width: 20px;
-    bottom: 0;
-}
-
-.device-mode-ruler-content {
-    pointer-events: none;
-    position: absolute;
-    left: -20px;
-    top: -20px;
-}
-
-.device-mode-ruler-top .device-mode-ruler-content {
-    border-top: 1px solid transparent;
-    right: 0;
-    bottom: 20px;
-    background-color: hsla(0, 0%, 98%, 0.9);
-}
-
-.device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-top .device-mode-ruler-content {
-    border-top: 1px solid hsl(0, 0%, 50%);
-}
-
-.device-mode-ruler-left .device-mode-ruler-content {
-    border-left: 1px solid transparent;
-    border-top: 1px solid transparent;
-    right: 20px;
-    bottom: 0;
-}
-
-.device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-left .device-mode-ruler-content {
-    border-left: 1px solid hsl(0, 0%, 50%);
-    border-top: 1px solid hsl(0, 0%, 50%);
-}
-
-.device-mode-ruler-inner {
-    position: absolute;
-}
-
-.device-mode-ruler-top .device-mode-ruler-inner {
-    top: 0;
-    bottom: 0;
-    left: 20px;
-    right: 0;
-    border-bottom: 1px solid hsl(0, 0%, 50%);
-}
-
-.device-mode-ruler-left .device-mode-ruler-inner {
-    left: 0;
-    right: 0;
-    top: 19px;
-    bottom: 0;
-    border-right: 1px solid hsl(0, 0%, 50%);
-    background-color: hsla(0, 0%, 98%, 0.9);
-}
-
-.device-mode-ruler-marker {
-    position: absolute;
-}
-
-.device-mode-ruler-top .device-mode-ruler-marker {
-    width: 0;
-    height: 5px;
-    bottom: 0;
-    border-right: 1px solid hsl(0, 0%, 50%);
-    margin-right: -1px;
-}
-
-.device-mode-ruler-top .device-mode-ruler-marker.device-mode-ruler-marker-medium {
-    height: 10px;
-}
-
-.device-mode-ruler-top .device-mode-ruler-marker.device-mode-ruler-marker-large {
-    height: 15px;
-}
-
-.device-mode-ruler-left .device-mode-ruler-marker {
-    height: 0;
-    width: 5px;
-    right: 0;
-    border-bottom: 1px solid hsl(0, 0%, 50%);
-    margin-bottom: -1px;
-}
-
-.device-mode-ruler-left .device-mode-ruler-marker.device-mode-ruler-marker-medium {
-    width: 10px;
-}
-
-.device-mode-ruler-left .device-mode-ruler-marker.device-mode-ruler-marker-large {
-    width: 15px;
-}
-
-.device-mode-ruler-text {
-    color: hsl(0, 0%, 50%);
-    position: relative;
-    pointer-events: auto;
-}
-
-.device-mode-ruler-text:hover {
-    color: hsl(0, 0%, 10%);
-}
-
-.device-mode-ruler-top .device-mode-ruler-text {
-    left: 2px;
-    top: -2px;
-}
-
-.device-mode-ruler-left .device-mode-ruler-text {
-    left: -4px;
-    top: -15px;
-    transform: rotate(270deg);
-}
diff --git a/front_end/emulation/devicesSettingsTab.css b/front_end/emulation/devicesSettingsTab.css
deleted file mode 100644
index 68d2e3f..0000000
--- a/front_end/emulation/devicesSettingsTab.css
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.devices-settings-tab .settings-tab.settings-content {
-    display: flex;
-    flex-direction: column;
-    align-items: flex-start;
-    height: 100%;
-    margin: 0;
-}
-
-.devices-settings-tab .devices-title {
-    font-size: 120%;
-    color: #222;
-    flex: none;
-}
-
-.devices-settings-tab .devices-button-row {
-    flex: none;
-    display: flex;
-}
-
-.devices-settings-tab .devices-button-row button {
-    margin-right: 10px;
-    min-width: 120px;
-    flex: none;
-}
-
-.devices-settings-tab .devices-list {
-    width: 350px;
-    margin-top: 10px;
-}
-
-.devices-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    flex: auto 1 1;
-    cursor: pointer;
-}
-
-.devices-list-checkbox {
-    height: 12px;
-    width: 12px;
-    margin: 3px 5px 2px 2px;
-    flex: none;
-    pointer-events: none;
-}
-
-.devices-list-checkbox:focus {
-    outline: auto 5px -webkit-focus-ring-color;
-}
-
-.devices-list-title {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    flex: auto;
-    -webkit-user-select: none;
-    color: #222;
-}
-
-.devices-edit-fields {
-    flex: auto;
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-    margin-bottom: 5px;
-}
-
-.devices-edit-fields input {
-    flex: auto;
-    margin: 8px 5px 0 5px;
-}
-
-.devices-edit-fields .device-edit-fixed {
-    flex: 0 0 140px;
-}
-
-.devices-edit-fields select {
-    margin: 8px 5px 0 5px;
-}
diff --git a/front_end/emulation/inspectedPagePlaceholder.css b/front_end/emulation/inspectedPagePlaceholder.css
deleted file mode 100644
index b5c4a93..0000000
--- a/front_end/emulation/inspectedPagePlaceholder.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    background-color: white;
-}
diff --git a/front_end/emulation/mediaQueryInspector.css b/front_end/emulation/mediaQueryInspector.css
deleted file mode 100644
index 7e96b7c..0000000
--- a/front_end/emulation/mediaQueryInspector.css
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Media query bars */
-
-.media-inspector-view {
-    height: 50px;
-}
-
-.media-inspector-marker-container {
-    height: 14px;
-    margin: 2px 0;
-    position: relative;
-}
-
-.media-inspector-bar {
-    display: flex;
-    flex-direction: row;
-    align-items: stretch;
-    pointer-events: none;
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-}
-
-.media-inspector-marker {
-    flex: none;
-    pointer-events: auto;
-    margin: 1px 0;
-    white-space: nowrap;
-    z-index: auto;
-    position: relative;
-}
-
-.media-inspector-marker-spacer {
-    flex: auto;
-}
-
-.media-inspector-marker:hover {
-    margin: -1px 0;
-    opacity: 1;
-}
-
-.media-inspector-marker-max-width {
-    background-color: hsl(207, 90%, 77%);
-    border-right: 2px solid hsl(207, 90%, 61%);
-    border-left: 2px solid hsl(207, 90%, 61%);
-}
-
-.media-inspector-marker-inactive .media-inspector-marker-max-width:not(:hover) {
-    background-color: hsl(199, 94%, 94%);
-}
-
-.media-inspector-marker-min-max-width {
-    background-color: hsl(88, 50%, 76%);
-    border-left: 2px solid #689F38;
-    border-right: 2px solid hsl(92, 48%, 42%);
-}
-
-.media-inspector-marker-inactive .media-inspector-marker-min-max-width:not(:hover) {
-    background-color: hsl(125, 39%, 94%);
-}
-
-.media-inspector-marker-min-max-width:hover {
-    z-index: 1;
-}
-
-.media-inspector-marker-min-width {
-    background-color: hsl(36, 100%, 75%);
-    flex: auto;
-}
-
-.media-inspector-marker-inactive .media-inspector-marker-min-width:not(:hover) {
-    background-color: hsl(37, 100%, 94%);
-}
-
-.media-inspector-marker-min-width-right {
-    border-left: 2px solid hsl(30, 100%, 48%);
-}
-
-.media-inspector-marker-min-width-left {
-    border-right: 2px solid hsl(30, 100%, 48%);
-}
-
-/* Media query labels */
-
-.media-inspector-marker:not(:hover) .media-inspector-marker-label-container {
-    display: none;
-}
-
-.media-inspector-marker-label-container {
-    position: absolute;
-    z-index: 1;
-}
-
-.media-inspector-marker-label-container-left {
-    left: -2px;
-}
-
-.media-inspector-marker-label-container-right {
-    right: -2px;
-}
-
-.media-inspector-marker-label {
-    color: #222;
-    position: absolute;
-    top: 1px;
-    bottom: 0;
-    font-size: 12px;
-    pointer-events: none;
-}
-
-.media-inspector-label-right {
-    right: 4px;
-}
-
-.media-inspector-label-left {
-    left: 4px;
-}
diff --git a/front_end/emulation/module.json b/front_end/emulation/module.json
deleted file mode 100644
index f39ff9a..0000000
--- a/front_end/emulation/module.json
+++ /dev/null
@@ -1,181 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@Common.AppProvider",
-            "condition": "can_dock",
-            "className": "Emulation.AdvancedAppProvider",
-            "order": 0
-        },
-        {
-            "type": "action",
-            "category": "Mobile",
-            "actionId": "emulation.toggle-device-mode",
-            "className": "Emulation.DeviceModeWrapper.ActionDelegate",
-            "condition": "can_dock",
-            "title": "Toggle device toolbar",
-            "iconClass": "largeicon-phone",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Shift+Ctrl+M"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Shift+Meta+M"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "emulation.capture-screenshot",
-            "category": "Mobile",
-            "className": "Emulation.DeviceModeWrapper.ActionDelegate",
-            "title": "Capture screenshot",
-            "tags": "device"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "deviceModeMenu/tools",
-            "order": 12,
-            "actionId": "emulation.capture-screenshot"
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "actionId": "emulation.toggle-device-mode",
-            "condition": "can_dock",
-            "location": "main-toolbar-left",
-            "order": 1
-        },
-        {
-            "type": "action",
-            "actionId": "emulation.capture-full-height-screenshot",
-            "category": "Mobile",
-            "className": "Emulation.DeviceModeWrapper.ActionDelegate",
-            "title": "Capture full size screenshot",
-            "tags": "device"
-        },
-        {
-            "type": "action",
-            "actionId": "emulation.capture-node-screenshot",
-            "category": "Mobile",
-            "className": "Emulation.DeviceModeWrapper.ActionDelegate",
-            "title": "Capture node screenshot",
-            "tags": "device"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "deviceModeMenu/tools",
-            "order": 13,
-            "actionId": "emulation.capture-full-height-screenshot"
-        },
-        {
-            "type": "setting",
-            "category": "Mobile",
-            "settingName": "showMediaQueryInspector",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show media queries"
-                },
-                {
-                    "value": false,
-                    "title": "Hide media queries"
-                }
-            ],
-            "tags": "device"
-        },
-        {
-            "type": "setting",
-            "category": "Mobile",
-            "settingName": "emulation.showRulers",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show rulers"
-                },
-                {
-                    "value": false,
-                    "title": "Hide rulers"
-                }
-            ],
-            "tags": "device"
-        },
-        {
-            "type": "setting",
-            "category": "Mobile",
-            "settingName": "emulation.showDeviceOutline",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show device frame"
-                },
-                {
-                    "value": false,
-                    "title": "Hide device frame"
-                }
-            ],
-            "tags": "device"
-        },
-        {
-            "type": "view",
-            "location": "settings-view",
-            "id": "devices",
-            "title": "Devices",
-            "order": 30,
-            "className": "Emulation.DevicesSettingsTab",
-            "settings": [
-                "standardEmulatedDeviceList",
-                "customEmulatedDeviceList"
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "emulation.show-sensors",
-            "title": "Sensors",
-            "className": "Emulation.SensorsView.ShowActionDelegate"
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "sensors",
-            "title": "Sensors",
-            "persistence": "closeable",
-            "order": 100,
-            "className": "Emulation.SensorsView",
-            "tags": "geolocation, accelerometer, device orientation"
-        }
-    ],
-    "dependencies": [
-        "bindings",
-        "components",
-        "platform",
-        "ui",
-        "mobile_throttling"
-    ],
-    "scripts": [
-        "AdvancedApp.js",
-        "EmulatedDevices.js",
-        "DevicesSettingsTab.js",
-        "InspectedPagePlaceholder.js",
-        "MediaQueryInspector.js",
-        "SensorsView.js",
-        "DeviceModeModel.js",
-        "DeviceModeToolbar.js",
-        "DeviceModeView.js",
-        "DeviceModeWrapper.js"
-    ],
-    "resources": [
-        "devicesSettingsTab.css",
-        "deviceModeToolbar.css",
-        "deviceModeView.css",
-        "inspectedPagePlaceholder.css",
-        "mediaQueryInspector.css",
-        "sensors.css"
-    ]
-}
diff --git a/front_end/emulation/sensors.css b/front_end/emulation/sensors.css
deleted file mode 100644
index 03c1311..0000000
--- a/front_end/emulation/sensors.css
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.sensors-view {
-    padding: 12px;
-    display: block;
-}
-
-.sensors-view label {
-    margin-bottom: 10px;
-}
-
-.sensors-view input {
-    width: 100%;
-    max-width: 100px;
-    margin: -5px 10px 0px 0px;
-    text-align: end;
-}
-
-.sensors-view input[readonly] {
-    background-color: rgb(235, 235, 228);
-}
-
-.sensors-view fieldset {
-    border: none;
-    padding: 10px 0px;
-    margin-left: 0;
-    flex: 0 0 auto;
-    margin: 0;
-}
-
-.sensors-view fieldset[disabled] {
-    opacity: 0.5;
-}
-
-.sensors-view .field-error-message {
-    display: none;
-}
-
-.sensors-view input:focus::-webkit-input-placeholder {
-    color: transparent !important;
-}
-
-.sensors-view .chrome-select {
-    width: 200px;
-}
-
-.sensors-group-title {
-    width: 80px;
-    line-height: 24px;
-}
-
-.sensors-group {
-    display: flex;
-    flex-wrap: wrap;
-    margin-bottom: 10px;
-}
-
-.geo-fields {
-    flex: 2 0 200px;
-}
-
-.latlong-group {
-    display: flex;
-    margin-bottom: 10px;
-}
-
-.latlong-title {
-    width: 70px;
-}
-
-/* Device Orientation */
-
-.orientation-content {
-    display: flex;
-    flex-wrap: wrap;
-}
-
-.orientation-fields {
-    margin-right: 10px;
-}
-
-.orientation-stage {
-    -webkit-perspective: 700px;
-    -webkit-perspective-origin: 50% 50%;
-    width: 160px;
-    height: 150px;
-    background: linear-gradient(#E1F5FE 0%, #E1F5FE 64%, #b0Ebf3 64%, #DEF6F9 100%);
-    transition: 0.2s ease opacity, 0.2s ease -webkit-filter;
-    overflow: hidden;
-    margin-bottom: 10px;
-}
-
-.orientation-stage.disabled {
-    -webkit-filter: grayscale();
-    opacity: 0.5;
-    cursor: default !important;
-}
-
-.orientation-element,
-.orientation-element::before,
-.orientation-element::after
-{
-    position: absolute;
-    box-sizing: border-box;
-    transform-style: preserve-3d;
-    background: no-repeat;
-    background-size: cover;
-    backface-visibility: hidden;
-}
-
-.orientation-box {
-    width: 66px;
-    height: 122px;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    margin: auto;
-    transform: rotate3d(1, 0, 0, 90deg);
-}
-
-.orientation-box.is-animating, .is-animating .orientation-layer {
-    transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
-}
-
-.orientation-layer {
-    width: 100%;
-    height: 100%;
-    transform-style: preserve-3d;
-}
-
-.orientation-front,
-.orientation-back
-{
-    width: 66px;
-    height: 122px;
-    border-radius: 8px;
-}
-
-.orientation-front {
-    background-image: url(Images/accelerometer-front.png);
-}
-
-.orientation-back {
-    transform: rotateY(180deg) translateZ(12px);
-    background-image: url(Images/accelerometer-back.png);
-}
-
-
-.orientation-left,
-.orientation-right {
-    width: 12px;
-    height: 106px;
-    top: 8px;
-    background-position: center center;
-}
-
-.orientation-left {
-    left: -12px;
-    transform-origin: right center;
-    transform: rotateY(-90deg);
-    background-image: url(Images/accelerometer-left.png);
-}
-
-
-.orientation-right {
-    right: -12px;
-    transform-origin: left center;
-    transform: rotateY(90deg);
-    background-image: url(Images/accelerometer-right.png);
-}
-
-.orientation-left::before,
-.orientation-left::after,
-.orientation-right::before,
-.orientation-right::after
-{
-    content: '';
-    width: 12px;
-    height: 6px;
-}
-
-.orientation-left::before,
-.orientation-left::after
-{
-    background-image: url(Images/accelerometer-left.png);
-}
-
-.orientation-right::before,
-.orientation-right::after
-{
-    background-image: url(Images/accelerometer-right.png);
-}
-
-.orientation-left::before,
-.orientation-right::before {
-    top: -6px;
-    transform-origin: center bottom;
-    transform: rotateX(26deg);
-    background-position: center top;
-}
-
-.orientation-left::after,
-.orientation-right::after {
-    bottom: -6px;
-    transform-origin: center top;
-    transform: rotateX(-25deg);
-    background-position: center bottom;
-}
-
-.orientation-top,
-.orientation-bottom {
-    width: 50px;
-    height: 12px;
-    left: 8px;
-    background-position: center center;
-}
-
-.orientation-top {
-    top: -12px;
-    transform-origin: center bottom;
-    transform: rotateX(90deg);
-    background-image: url(Images/accelerometer-top.png);
-}
-
-
-.orientation-bottom {
-    bottom: -12px;
-    transform-origin: center top;
-    transform: rotateX(-90deg);
-    background-image: url(Images/accelerometer-bottom.png);
-}
-
-
-.orientation-top::before,
-.orientation-top::after,
-.orientation-bottom::before,
-.orientation-bottom::after
-{
-    content: '';
-    width: 8px;
-    height: 12px;
-}
-
-.orientation-top::before,
-.orientation-top::after
-{
-    background-image: url(Images/accelerometer-top.png);
-}
-
-.orientation-bottom::before,
-.orientation-bottom::after
-{
-    background-image: url(Images/accelerometer-bottom.png);
-}
-
-.orientation-top::before,
-.orientation-bottom::before {
-    left: -6px;
-    transform-origin: right center;
-    transform: rotateY(-26deg);
-    background-position: left center;
-}
-
-.orientation-top::after,
-.orientation-bottom::after {
-    right: -6px;
-    transform-origin: left center;
-    transform: rotateY(26deg);
-    background-position: right center;
-}
-
-.orientation-axis-input-container {
-    margin-bottom: 10px;
-}
-
-.orientation-axis-input-container input {
-    max-width: 100px;
-}
-
-.orientation-reset-button {
-    min-width: 80px;
-}
-
-fieldset.device-orientation-override-section {
-    margin: 0;
-    display: flex;
-}
-
-.touch-label {
-    margin-top: 10px;
-}
-
-.touch-label select {
-    margin-left: 10px;
-}
-
-.panel-section-separator {
-    height: 2px;
-    margin-bottom: 12px;
-    background: #f1f1f1;
-}
-
-.reload-warning {
-    align-self: center;
-    margin-left: 10px;
-}
diff --git a/front_end/event_listeners/EventListenersUtils.js b/front_end/event_listeners/EventListenersUtils.js
deleted file mode 100644
index 999c7b1..0000000
--- a/front_end/event_listeners/EventListenersUtils.js
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/** @typedef {{eventListeners:!Array<!SDK.EventListener>, internalHandlers:?SDK.RemoteArray}} */
-EventListeners.FrameworkEventListenersObject;
-
-/** @typedef {{type: string, useCapture: boolean, passive: boolean, once: boolean, handler: function()}} */
-EventListeners.EventListenerObjectInInspectedPage;
-
-/**
- * @param {!SDK.RemoteObject} object
- * @return {!Promise<!EventListeners.FrameworkEventListenersObject>}
- */
-EventListeners.frameworkEventListeners = function(object) {
-  const domDebuggerModel = object.runtimeModel().target().model(SDK.DOMDebuggerModel);
-  if (!domDebuggerModel) {
-    // TODO(kozyatinskiy): figure out how this should work for |window|.
-    return Promise.resolve(
-        /** @type {!EventListeners.FrameworkEventListenersObject} */ ({eventListeners: [], internalHandlers: null}));
-  }
-
-  const listenersResult = /** @type {!EventListeners.FrameworkEventListenersObject} */ ({eventListeners: []});
-  return object.callFunctionPromise(frameworkEventListeners, undefined)
-      .then(assertCallFunctionResult)
-      .then(getOwnProperties)
-      .then(createEventListeners)
-      .then(returnResult)
-      .catchException(listenersResult);
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @return {!Promise<!{properties: ?Array.<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>}>}
-   */
-  function getOwnProperties(object) {
-    return object.getOwnPropertiesPromise(false /* generatePreview */);
-  }
-
-  /**
-   * @param {!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array<!SDK.RemoteObjectProperty>}} result
-   * @return {!Promise<undefined>}
-   */
-  function createEventListeners(result) {
-    if (!result.properties)
-      throw new Error('Object properties is empty');
-    const promises = [];
-    for (const property of result.properties) {
-      if (property.name === 'eventListeners' && property.value)
-        promises.push(convertToEventListeners(property.value).then(storeEventListeners));
-      if (property.name === 'internalHandlers' && property.value)
-        promises.push(convertToInternalHandlers(property.value).then(storeInternalHandlers));
-      if (property.name === 'errorString' && property.value)
-        printErrorString(property.value);
-    }
-    return /** @type {!Promise<undefined>} */ (Promise.all(promises));
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} pageEventListenersObject
-   * @return {!Promise<!Array<!SDK.EventListener>>}
-   */
-  function convertToEventListeners(pageEventListenersObject) {
-    return SDK.RemoteArray.objectAsArray(pageEventListenersObject).map(toEventListener).then(filterOutEmptyObjects);
-
-    /**
-     * @param {!SDK.RemoteObject} listenerObject
-     * @return {!Promise<?SDK.EventListener>}
-     */
-    function toEventListener(listenerObject) {
-      /** @type {string} */
-      let type;
-      /** @type {boolean} */
-      let useCapture;
-      /** @type {boolean} */
-      let passive;
-      /** @type {boolean} */
-      let once;
-      /** @type {?SDK.RemoteObject} */
-      let handler = null;
-      /** @type {?SDK.RemoteObject} */
-      let originalHandler = null;
-      /** @type {?SDK.DebuggerModel.Location} */
-      let location = null;
-      /** @type {?SDK.RemoteObject} */
-      let removeFunctionObject = null;
-
-      const promises = [];
-      promises.push(
-          listenerObject.callFunctionJSONPromise(truncatePageEventListener, undefined).then(storeTruncatedListener));
-
-      /**
-       * @suppressReceiverCheck
-       * @this {EventListeners.EventListenerObjectInInspectedPage}
-       * @return {!{type:string, useCapture:boolean, passive:boolean, once:boolean}}
-       */
-      function truncatePageEventListener() {
-        return {type: this.type, useCapture: this.useCapture, passive: this.passive, once: this.once};
-      }
-
-      /**
-       * @param {!{type:string, useCapture: boolean, passive: boolean, once: boolean}} truncatedListener
-       */
-      function storeTruncatedListener(truncatedListener) {
-        type = truncatedListener.type;
-        useCapture = truncatedListener.useCapture;
-        passive = truncatedListener.passive;
-        once = truncatedListener.once;
-      }
-
-      promises.push(listenerObject.callFunctionPromise(handlerFunction)
-                        .then(assertCallFunctionResult)
-                        .then(storeOriginalHandler)
-                        .then(toTargetFunction)
-                        .then(storeFunctionWithDetails));
-
-      /**
-       * @suppressReceiverCheck
-       * @return {function()}
-       * @this {EventListeners.EventListenerObjectInInspectedPage}
-       */
-      function handlerFunction() {
-        return this.handler;
-      }
-
-      /**
-       * @param {!SDK.RemoteObject} functionObject
-       * @return {!SDK.RemoteObject}
-       */
-      function storeOriginalHandler(functionObject) {
-        originalHandler = functionObject;
-        return originalHandler;
-      }
-
-      /**
-       * @param {!SDK.RemoteObject} functionObject
-       * @return {!Promise<undefined>}
-       */
-      function storeFunctionWithDetails(functionObject) {
-        handler = functionObject;
-        return /** @type {!Promise<undefined>} */ (
-            functionObject.debuggerModel().functionDetailsPromise(functionObject).then(storeFunctionDetails));
-      }
-
-      /**
-       * @param {?SDK.DebuggerModel.FunctionDetails} functionDetails
-       */
-      function storeFunctionDetails(functionDetails) {
-        location = functionDetails ? functionDetails.location : null;
-      }
-
-      promises.push(listenerObject.callFunctionPromise(getRemoveFunction)
-                        .then(assertCallFunctionResult)
-                        .then(storeRemoveFunction));
-
-      /**
-       * @suppressReceiverCheck
-       * @return {function()}
-       * @this {EventListeners.EventListenerObjectInInspectedPage}
-       */
-      function getRemoveFunction() {
-        return this.remove;
-      }
-
-      /**
-       * @param {!SDK.RemoteObject} functionObject
-       */
-      function storeRemoveFunction(functionObject) {
-        if (functionObject.type !== 'function')
-          return;
-        removeFunctionObject = functionObject;
-      }
-
-      return Promise.all(promises).then(createEventListener).catchException(/** @type {?SDK.EventListener} */ (null));
-
-      /**
-       * @return {!SDK.EventListener}
-       */
-      function createEventListener() {
-        if (!location)
-          throw new Error('Empty event listener\'s location');
-        return new SDK.EventListener(
-            /** @type {!SDK.DOMDebuggerModel} */ (domDebuggerModel), object, type, useCapture, passive, once, handler,
-            originalHandler, location, removeFunctionObject, SDK.EventListener.Origin.FrameworkUser);
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} pageInternalHandlersObject
-   * @return {!Promise<!SDK.RemoteArray>}
-   */
-  function convertToInternalHandlers(pageInternalHandlersObject) {
-    return SDK.RemoteArray.objectAsArray(pageInternalHandlersObject)
-        .map(toTargetFunction)
-        .then(SDK.RemoteArray.createFromRemoteObjects);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} functionObject
-   * @return {!Promise<!SDK.RemoteObject>}
-   */
-  function toTargetFunction(functionObject) {
-    return SDK.RemoteFunction.objectAsFunction(functionObject).targetFunction();
-  }
-
-  /**
-   * @param {!Array<!SDK.EventListener>} eventListeners
-   */
-  function storeEventListeners(eventListeners) {
-    listenersResult.eventListeners = eventListeners;
-  }
-
-  /**
-   * @param {!SDK.RemoteArray} internalHandlers
-   */
-  function storeInternalHandlers(internalHandlers) {
-    listenersResult.internalHandlers = internalHandlers;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} errorString
-   */
-  function printErrorString(errorString) {
-    Common.console.error(String(errorString.value));
-  }
-
-  /**
-   * @return {!EventListeners.FrameworkEventListenersObject}
-   */
-  function returnResult() {
-    return listenersResult;
-  }
-
-  /**
-   * @param {!SDK.CallFunctionResult} result
-   * @return {!SDK.RemoteObject}
-   */
-  function assertCallFunctionResult(result) {
-    if (result.wasThrown || !result.object)
-      throw new Error('Exception in callFunction or empty result');
-    return result.object;
-  }
-
-  /**
-   * @param {!Array<?T>} objects
-   * @return {!Array<!T>}
-   * @template T
-   */
-  function filterOutEmptyObjects(objects) {
-    return objects.filter(filterOutEmpty);
-
-    /**
-     * @param {?T} object
-     * @return {boolean}
-     * @template T
-     */
-    function filterOutEmpty(object) {
-      return !!object;
-    }
-  }
-
-  /*
-    frameworkEventListeners fetcher functions should produce following output:
-        {
-          // framework event listeners
-          "eventListeners": [
-            {
-              "handler": function(),
-              "useCapture": true,
-              "passive": false,
-              "once": false,
-              "type": "change",
-              "remove": function(type, handler, useCapture, passive)
-            },
-            ...
-          ],
-          // internal framework event handlers
-          "internalHandlers": [
-            function(),
-            function(),
-            ...
-          ]
-        }
-    */
-  /**
-   * @suppressReceiverCheck
-   * @return {!{eventListeners:!Array<!EventListeners.EventListenerObjectInInspectedPage>, internalHandlers:?Array<function()>}}
-   * @this {Object}
-   */
-  function frameworkEventListeners() {
-    const errorLines = [];
-    let eventListeners = [];
-    let internalHandlers = [];
-    let fetchers = [jQueryFetcher];
-    try {
-      if (self.devtoolsFrameworkEventListeners && isArrayLike(self.devtoolsFrameworkEventListeners))
-        fetchers = fetchers.concat(self.devtoolsFrameworkEventListeners);
-    } catch (e) {
-      errorLines.push('devtoolsFrameworkEventListeners call produced error: ' + toString(e));
-    }
-
-    for (let i = 0; i < fetchers.length; ++i) {
-      try {
-        const fetcherResult = fetchers[i](this);
-        if (fetcherResult.eventListeners && isArrayLike(fetcherResult.eventListeners)) {
-          eventListeners =
-              eventListeners.concat(fetcherResult.eventListeners.map(checkEventListener).filter(nonEmptyObject));
-        }
-        if (fetcherResult.internalHandlers && isArrayLike(fetcherResult.internalHandlers)) {
-          internalHandlers =
-              internalHandlers.concat(fetcherResult.internalHandlers.map(checkInternalHandler).filter(nonEmptyObject));
-        }
-      } catch (e) {
-        errorLines.push('fetcher call produced error: ' + toString(e));
-      }
-    }
-    const result = {eventListeners: eventListeners};
-    if (internalHandlers.length)
-      result.internalHandlers = internalHandlers;
-    if (errorLines.length) {
-      let errorString = 'Framework Event Listeners API Errors:\n\t' + errorLines.join('\n\t');
-      errorString = errorString.substr(0, errorString.length - 1);
-      result.errorString = errorString;
-    }
-    return result;
-
-    /**
-     * @param {?Object} obj
-     * @return {boolean}
-     */
-    function isArrayLike(obj) {
-      if (!obj || typeof obj !== 'object')
-        return false;
-      try {
-        if (typeof obj.splice === 'function') {
-          const len = obj.length;
-          return typeof len === 'number' && (len >>> 0 === len && (len > 0 || 1 / len > 0));
-        }
-      } catch (e) {
-      }
-      return false;
-    }
-
-    /**
-     * @param {*} eventListener
-     * @return {?EventListeners.EventListenerObjectInInspectedPage}
-     */
-    function checkEventListener(eventListener) {
-      try {
-        let errorString = '';
-        if (!eventListener)
-          errorString += 'empty event listener, ';
-        const type = eventListener.type;
-        if (!type || (typeof type !== 'string'))
-          errorString += 'event listener\'s type isn\'t string or empty, ';
-        const useCapture = eventListener.useCapture;
-        if (typeof useCapture !== 'boolean')
-          errorString += 'event listener\'s useCapture isn\'t boolean or undefined, ';
-        const passive = eventListener.passive;
-        if (typeof passive !== 'boolean')
-          errorString += 'event listener\'s passive isn\'t boolean or undefined, ';
-        const once = eventListener.once;
-        if (typeof once !== 'boolean')
-          errorString += 'event listener\'s once isn\'t boolean or undefined, ';
-        const handler = eventListener.handler;
-        if (!handler || (typeof handler !== 'function'))
-          errorString += 'event listener\'s handler isn\'t a function or empty, ';
-        const remove = eventListener.remove;
-        if (remove && (typeof remove !== 'function'))
-          errorString += 'event listener\'s remove isn\'t a function, ';
-        if (!errorString) {
-          return {type: type, useCapture: useCapture, passive: passive, once: once, handler: handler, remove: remove};
-        } else {
-          errorLines.push(errorString.substr(0, errorString.length - 2));
-          return null;
-        }
-      } catch (e) {
-        errorLines.push(toString(e));
-        return null;
-      }
-    }
-
-    /**
-     * @param {*} handler
-     * @return {function()|null}
-     */
-    function checkInternalHandler(handler) {
-      if (handler && (typeof handler === 'function'))
-        return handler;
-      errorLines.push('internal handler isn\'t a function or empty');
-      return null;
-    }
-
-    /**
-     * @param {*} obj
-     * @return {string}
-     * @suppress {uselessCode}
-     */
-    function toString(obj) {
-      try {
-        return '' + obj;
-      } catch (e) {
-        return '<error>';
-      }
-    }
-
-    /**
-     * @param {*} obj
-     * @return {boolean}
-     */
-    function nonEmptyObject(obj) {
-      return !!obj;
-    }
-
-    function jQueryFetcher(node) {
-      if (!node || !(node instanceof Node))
-        return {eventListeners: []};
-      const jQuery = /** @type {?{fn,data,_data}}*/ (window['jQuery']);
-      if (!jQuery || !jQuery.fn)
-        return {eventListeners: []};
-      const jQueryFunction = /** @type {function(!Node)} */ (jQuery);
-      const data = jQuery._data || jQuery.data;
-
-      const eventListeners = [];
-      const internalHandlers = [];
-
-      if (typeof data === 'function') {
-        const events = data(node, 'events');
-        for (const type in events) {
-          for (const key in events[type]) {
-            const frameworkListener = events[type][key];
-            if (typeof frameworkListener === 'object' || typeof frameworkListener === 'function') {
-              const listener = {
-                handler: frameworkListener.handler || frameworkListener,
-                useCapture: true,
-                passive: false,
-                once: false,
-                type: type
-              };
-              listener.remove = jQueryRemove.bind(node, frameworkListener.selector);
-              eventListeners.push(listener);
-            }
-          }
-        }
-        const nodeData = data(node);
-        if (nodeData && typeof nodeData.handle === 'function')
-          internalHandlers.push(nodeData.handle);
-      }
-      const entry = jQueryFunction(node)[0];
-      if (entry) {
-        const entryEvents = entry['$events'];
-        for (const type in entryEvents) {
-          const events = entryEvents[type];
-          for (const key in events) {
-            if (typeof events[key] === 'function') {
-              const listener = {handler: events[key], useCapture: true, passive: false, once: false, type: type};
-              // We don't support removing for old version < 1.4 of jQuery because it doesn't provide API for getting "selector".
-              eventListeners.push(listener);
-            }
-          }
-        }
-        if (entry && entry['$handle'])
-          internalHandlers.push(entry['$handle']);
-      }
-      return {eventListeners: eventListeners, internalHandlers: internalHandlers};
-    }
-
-    /**
-     * @param {string} selector
-     * @param {string} type
-     * @param {function()} handler
-     * @this {?Object}
-     */
-    function jQueryRemove(selector, type, handler) {
-      if (!this || !(this instanceof Node))
-        return;
-      const node = /** @type {!Node} */ (this);
-      const jQuery = /** @type {?{fn,data,_data}}*/ (window['jQuery']);
-      if (!jQuery || !jQuery.fn)
-        return;
-      const jQueryFunction = /** @type {function(!Node)} */ (jQuery);
-      jQueryFunction(node).off(type, selector, handler);
-    }
-  }
-};
diff --git a/front_end/event_listeners/EventListenersView.js b/front_end/event_listeners/EventListenersView.js
deleted file mode 100644
index f3fe2b5..0000000
--- a/front_end/event_listeners/EventListenersView.js
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @typedef {Array<{object: !SDK.RemoteObject, eventListeners: ?Array<!SDK.EventListener>, frameworkEventListeners: ?{eventListeners: ?Array<!SDK.EventListener>, internalHandlers: ?SDK.RemoteArray}, isInternal: ?Array<boolean>}>}
- */
-EventListeners.EventListenersResult;
-
-/**
- * @unrestricted
- */
-EventListeners.EventListenersView = class extends UI.VBox {
-  /**
-   * @param {function()} changeCallback
-   */
-  constructor(changeCallback) {
-    super();
-    this._changeCallback = changeCallback;
-    this._treeOutline = new UI.TreeOutlineInShadow();
-    this._treeOutline.hideOverflow();
-    this._treeOutline.registerRequiredCSS('object_ui/objectValue.css');
-    this._treeOutline.registerRequiredCSS('event_listeners/eventListenersView.css');
-    this._treeOutline.setComparator(EventListeners.EventListenersTreeElement.comparator);
-    this._treeOutline.element.classList.add('monospace');
-    this.element.appendChild(this._treeOutline.element);
-    this._emptyHolder = createElementWithClass('div', 'gray-info-message');
-    this._emptyHolder.textContent = Common.UIString('No event listeners');
-    this._linkifier = new Components.Linkifier();
-    /** @type {!Map<string, !EventListeners.EventListenersTreeElement>} */
-    this._treeItemMap = new Map();
-  }
-
-  /**
-   * @param {!Array<?SDK.RemoteObject>} objects
-   * @return {!Promise<undefined>}
-   */
-  async addObjects(objects) {
-    this.reset();
-    await Promise.all(objects.map(obj => obj ? this._addObject(obj) : Promise.resolve()));
-    this.addEmptyHolderIfNeeded();
-    this._eventListenersArrivedForTest();
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @return {!Promise<undefined>}
-   */
-  _addObject(object) {
-    /** @type {!Array<!SDK.EventListener>} */
-    let eventListeners;
-    /** @type {?EventListeners.FrameworkEventListenersObject}*/
-    let frameworkEventListenersObject = null;
-
-    const promises = [];
-    const domDebuggerModel = object.runtimeModel().target().model(SDK.DOMDebuggerModel);
-    // TODO(kozyatinskiy): figure out how this should work for |window| when there is no DOMDebugger.
-    if (domDebuggerModel)
-      promises.push(domDebuggerModel.eventListeners(object).then(storeEventListeners));
-    promises.push(EventListeners.frameworkEventListeners(object).then(storeFrameworkEventListenersObject));
-    return Promise.all(promises).then(markInternalEventListeners).then(addEventListeners.bind(this));
-
-    /**
-     * @param {!Array<!SDK.EventListener>} result
-     */
-    function storeEventListeners(result) {
-      eventListeners = result;
-    }
-
-    /**
-     * @param {?EventListeners.FrameworkEventListenersObject} result
-     */
-    function storeFrameworkEventListenersObject(result) {
-      frameworkEventListenersObject = result;
-    }
-
-    /**
-     * @return {!Promise<undefined>}
-     */
-    function markInternalEventListeners() {
-      if (!frameworkEventListenersObject.internalHandlers)
-        return Promise.resolve(undefined);
-      return frameworkEventListenersObject.internalHandlers.object()
-          .callFunctionJSONPromise(isInternalEventListener, eventListeners.map(handlerArgument))
-          .then(setIsInternal);
-
-      /**
-       * @param {!SDK.EventListener} listener
-       * @return {!Protocol.Runtime.CallArgument}
-       */
-      function handlerArgument(listener) {
-        return SDK.RemoteObject.toCallArgument(listener.handler());
-      }
-
-      /**
-       * @suppressReceiverCheck
-       * @return {!Array<boolean>}
-       * @this {Array<*>}
-       */
-      function isInternalEventListener() {
-        const isInternal = [];
-        const internalHandlersSet = new Set(this);
-        for (const handler of arguments)
-          isInternal.push(internalHandlersSet.has(handler));
-        return isInternal;
-      }
-
-      /**
-       * @param {!Array<boolean>} isInternal
-       */
-      function setIsInternal(isInternal) {
-        for (let i = 0; i < eventListeners.length; ++i) {
-          if (isInternal[i])
-            eventListeners[i].markAsFramework();
-        }
-      }
-    }
-
-    /**
-     * @this {EventListeners.EventListenersView}
-     */
-    function addEventListeners() {
-      this._addObjectEventListeners(object, eventListeners);
-      this._addObjectEventListeners(object, frameworkEventListenersObject.eventListeners);
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {?Array<!SDK.EventListener>} eventListeners
-   */
-  _addObjectEventListeners(object, eventListeners) {
-    if (!eventListeners)
-      return;
-    for (const eventListener of eventListeners) {
-      const treeItem = this._getOrCreateTreeElementForType(eventListener.type());
-      treeItem.addObjectEventListener(eventListener, object);
-    }
-  }
-
-  /**
-   * @param {boolean} showFramework
-   * @param {boolean} showPassive
-   * @param {boolean} showBlocking
-   */
-  showFrameworkListeners(showFramework, showPassive, showBlocking) {
-    const eventTypes = this._treeOutline.rootElement().children();
-    for (const eventType of eventTypes) {
-      let hiddenEventType = true;
-      for (const listenerElement of eventType.children()) {
-        const listenerOrigin = listenerElement.eventListener().origin();
-        let hidden = false;
-        if (listenerOrigin === SDK.EventListener.Origin.FrameworkUser && !showFramework)
-          hidden = true;
-        if (listenerOrigin === SDK.EventListener.Origin.Framework && showFramework)
-          hidden = true;
-        if (!showPassive && listenerElement.eventListener().passive())
-          hidden = true;
-        if (!showBlocking && !listenerElement.eventListener().passive())
-          hidden = true;
-        listenerElement.hidden = hidden;
-        hiddenEventType = hiddenEventType && hidden;
-      }
-      eventType.hidden = hiddenEventType;
-    }
-  }
-
-  /**
-   * @param {string} type
-   * @return {!EventListeners.EventListenersTreeElement}
-   */
-  _getOrCreateTreeElementForType(type) {
-    let treeItem = this._treeItemMap.get(type);
-    if (!treeItem) {
-      treeItem = new EventListeners.EventListenersTreeElement(type, this._linkifier, this._changeCallback);
-      this._treeItemMap.set(type, treeItem);
-      treeItem.hidden = true;
-      this._treeOutline.appendChild(treeItem);
-    }
-    this._emptyHolder.remove();
-    return treeItem;
-  }
-
-  addEmptyHolderIfNeeded() {
-    let allHidden = true;
-    for (const eventType of this._treeOutline.rootElement().children()) {
-      eventType.hidden = !eventType.firstChild();
-      allHidden = allHidden && eventType.hidden;
-    }
-    if (allHidden && !this._emptyHolder.parentNode)
-      this.element.appendChild(this._emptyHolder);
-  }
-
-  reset() {
-    const eventTypes = this._treeOutline.rootElement().children();
-    for (const eventType of eventTypes)
-      eventType.removeChildren();
-    this._linkifier.reset();
-  }
-
-  _eventListenersArrivedForTest() {
-  }
-};
-
-/**
- * @unrestricted
- */
-EventListeners.EventListenersTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {string} type
-   * @param {!Components.Linkifier} linkifier
-   * @param {function()} changeCallback
-   */
-  constructor(type, linkifier, changeCallback) {
-    super(type);
-    this.toggleOnClick = true;
-    this.selectable = false;
-    this._linkifier = linkifier;
-    this._changeCallback = changeCallback;
-  }
-
-  /**
-   * @param {!UI.TreeElement} element1
-   * @param {!UI.TreeElement} element2
-   * @return {number}
-   */
-  static comparator(element1, element2) {
-    if (element1.title === element2.title)
-      return 0;
-    return element1.title > element2.title ? 1 : -1;
-  }
-
-  /**
-   * @param {!SDK.EventListener} eventListener
-   * @param {!SDK.RemoteObject} object
-   */
-  addObjectEventListener(eventListener, object) {
-    const treeElement =
-        new EventListeners.ObjectEventListenerBar(eventListener, object, this._linkifier, this._changeCallback);
-    this.appendChild(/** @type {!UI.TreeElement} */ (treeElement));
-  }
-};
-
-
-/**
- * @unrestricted
- */
-EventListeners.ObjectEventListenerBar = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.EventListener} eventListener
-   * @param {!SDK.RemoteObject} object
-   * @param {!Components.Linkifier} linkifier
-   * @param {function()} changeCallback
-   */
-  constructor(eventListener, object, linkifier, changeCallback) {
-    super('', true);
-    this._eventListener = eventListener;
-    this.editable = false;
-    this.selectable = false;
-    this._setTitle(object, linkifier);
-    this._changeCallback = changeCallback;
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    const properties = [];
-    const eventListener = this._eventListener;
-    const runtimeModel = eventListener.domDebuggerModel().runtimeModel();
-    properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue('useCapture', eventListener.useCapture()));
-    properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue('passive', eventListener.passive()));
-    properties.push(runtimeModel.createRemotePropertyFromPrimitiveValue('once', eventListener.once()));
-    if (typeof eventListener.handler() !== 'undefined')
-      properties.push(new SDK.RemoteObjectProperty('handler', eventListener.handler()));
-    ObjectUI.ObjectPropertyTreeElement.populateWithProperties(this, properties, [], true, null);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {!Components.Linkifier} linkifier
-   */
-  _setTitle(object, linkifier) {
-    const title = this.listItemElement.createChild('span');
-    const subtitle = this.listItemElement.createChild('span', 'event-listener-tree-subtitle');
-    subtitle.appendChild(linkifier.linkifyRawLocation(this._eventListener.location(), this._eventListener.sourceURL()));
-
-    title.appendChild(
-        ObjectUI.ObjectPropertiesSection.createValueElement(object, false /* wasThrown */, false /* showPreview */));
-
-    if (this._eventListener.canRemove()) {
-      const deleteButton = title.createChild('span', 'event-listener-button');
-      deleteButton.textContent = Common.UIString('Remove');
-      deleteButton.title = Common.UIString('Delete event listener');
-      deleteButton.addEventListener('click', removeListener.bind(this), false);
-      title.appendChild(deleteButton);
-    }
-
-    if (this._eventListener.isScrollBlockingType() && this._eventListener.canTogglePassive()) {
-      const passiveButton = title.createChild('span', 'event-listener-button');
-      passiveButton.textContent = Common.UIString('Toggle Passive');
-      passiveButton.title = Common.UIString('Toggle whether event listener is passive or blocking');
-      passiveButton.addEventListener('click', togglePassiveListener.bind(this), false);
-      title.appendChild(passiveButton);
-    }
-
-    /**
-     * @param {!Event} event
-     * @this {EventListeners.ObjectEventListenerBar}
-     */
-    function removeListener(event) {
-      event.consume();
-      this._removeListenerBar();
-      this._eventListener.remove();
-    }
-
-    /**
-     * @param {!Event} event
-     * @this {EventListeners.ObjectEventListenerBar}
-     */
-    function togglePassiveListener(event) {
-      event.consume();
-      this._eventListener.togglePassive().then(this._changeCallback());
-    }
-  }
-
-  _removeListenerBar() {
-    const parent = this.parent;
-    parent.removeChild(this);
-    if (!parent.childCount())
-      parent.collapse();
-    let allHidden = true;
-    for (let i = 0; i < parent.childCount(); ++i) {
-      if (!parent.childAt(i).hidden)
-        allHidden = false;
-    }
-    parent.hidden = allHidden;
-  }
-
-  /**
-   * @return {!SDK.EventListener}
-   */
-  eventListener() {
-    return this._eventListener;
-  }
-};
diff --git a/front_end/event_listeners/eventListenersView.css b/front_end/event_listeners/eventListenersView.css
deleted file mode 100644
index 4db4d89..0000000
--- a/front_end/event_listeners/eventListenersView.css
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tree-outline-disclosure li {
-    padding: 2px 0 0 5px;
-    overflow: hidden;
-    display: list-item;
-    min-height: 17px;
-}
-
-.tree-outline-disclosure > li {
-    border-top: 1px solid #f0f0f0;
-}
-
-.tree-outline-disclosure > li:first-of-type {
-    border-top: none;
-}
-
-.tree-outline-disclosure {
-    padding-left: 0 !important;
-    padding-right: 3px;
-}
-
-.tree-outline-disclosure li.parent::before {
-    top: 0 !important;
-}
-
-.tree-outline-disclosure .name {
-    color: rgb(136, 19, 145);
-}
-
-.event-listener-tree-subtitle {
-    float: right;
-    margin-left: 5px;
-}
-
-.event-listener-button {
-    padding: 0 3px;
-    background-color: #f2f2f2;
-    border-radius: 3px;
-    border: 1px solid #c3c3c3;
-    margin-left: 10px;
-    display: none;
-    cursor: pointer;
-}
-
-.event-listener-button:hover {
-    background-color: #e0e0e0;
-}
-
-.tree-outline-disclosure li:hover .event-listener-button {
-    display: inline;
-}
diff --git a/front_end/event_listeners/module.json b/front_end/event_listeners/module.json
deleted file mode 100644
index 5267296..0000000
--- a/front_end/event_listeners/module.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "dependencies": [
-        "ui",
-        "common",
-        "components",
-        "sdk",
-        "object_ui"
-    ],
-    "scripts": [
-        "EventListenersView.js",
-        "EventListenersUtils.js"
-    ],
-    "resources": [
-        "eventListenersView.css"
-    ]
-}
diff --git a/front_end/extensions/ExtensionAPI.js b/front_end/extensions/ExtensionAPI.js
deleted file mode 100644
index d4a2f35..0000000
--- a/front_end/extensions/ExtensionAPI.js
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* eslint-disable indent */
-
-function defineCommonExtensionSymbols(apiPrivate) {
-  if (!apiPrivate.panels)
-    apiPrivate.panels = {};
-  apiPrivate.panels.SearchAction = {
-    CancelSearch: 'cancelSearch',
-    PerformSearch: 'performSearch',
-    NextSearchResult: 'nextSearchResult',
-    PreviousSearchResult: 'previousSearchResult'
-  };
-
-  /** @enum {string} */
-  apiPrivate.Events = {
-    ButtonClicked: 'button-clicked-',
-    PanelObjectSelected: 'panel-objectSelected-',
-    NetworkRequestFinished: 'network-request-finished',
-    OpenResource: 'open-resource',
-    PanelSearch: 'panel-search-',
-    RecordingStarted: 'trace-recording-started-',
-    RecordingStopped: 'trace-recording-stopped-',
-    ResourceAdded: 'resource-added',
-    ResourceContentCommitted: 'resource-content-committed',
-    ViewShown: 'view-shown-',
-    ViewHidden: 'view-hidden-'
-  };
-
-  /** @enum {string} */
-  apiPrivate.Commands = {
-    AddRequestHeaders: 'addRequestHeaders',
-    AddTraceProvider: 'addTraceProvider',
-    ApplyStyleSheet: 'applyStyleSheet',
-    CompleteTraceSession: 'completeTraceSession',
-    CreatePanel: 'createPanel',
-    CreateSidebarPane: 'createSidebarPane',
-    CreateToolbarButton: 'createToolbarButton',
-    EvaluateOnInspectedPage: 'evaluateOnInspectedPage',
-    ForwardKeyboardEvent: '_forwardKeyboardEvent',
-    GetHAR: 'getHAR',
-    GetPageResources: 'getPageResources',
-    GetRequestContent: 'getRequestContent',
-    GetResourceContent: 'getResourceContent',
-    InspectedURLChanged: 'inspectedURLChanged',
-    OpenResource: 'openResource',
-    Reload: 'Reload',
-    Subscribe: 'subscribe',
-    SetOpenResourceHandler: 'setOpenResourceHandler',
-    SetResourceContent: 'setResourceContent',
-    SetSidebarContent: 'setSidebarContent',
-    SetSidebarHeight: 'setSidebarHeight',
-    SetSidebarPage: 'setSidebarPage',
-    ShowPanel: 'showPanel',
-    Unsubscribe: 'unsubscribe',
-    UpdateButton: 'updateButton'
-  };
-}
-
-/**
- * @param {!ExtensionDescriptor} extensionInfo
- * @param {string} inspectedTabId
- * @param {string} themeName
- * @param {number} injectedScriptId
- * @param {function(!Object, !Object)} testHook
- * @suppressGlobalPropertiesCheck
- */
-function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook, injectedScriptId) {
-  const chrome = window.chrome || {};
-  const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
-  if (devtools_descriptor)
-    return;
-
-  const apiPrivate = {};
-
-  defineCommonExtensionSymbols(apiPrivate);
-
-  const commands = apiPrivate.Commands;
-  const events = apiPrivate.Events;
-  let userAction = false;
-
-  // Here and below, all constructors are private to API implementation.
-  // For a public type Foo, if internal fields are present, these are on
-  // a private FooImpl type, an instance of FooImpl is used in a closure
-  // by Foo consutrctor to re-bind publicly exported members to an instance
-  // of Foo.
-
-  /**
-   * @constructor
-   */
-  function EventSinkImpl(type, customDispatch) {
-    this._type = type;
-    this._listeners = [];
-    this._customDispatch = customDispatch;
-  }
-
-  EventSinkImpl.prototype = {
-    addListener: function(callback) {
-      if (typeof callback !== 'function')
-        throw 'addListener: callback is not a function';
-      if (this._listeners.length === 0)
-        extensionServer.sendRequest({command: commands.Subscribe, type: this._type});
-      this._listeners.push(callback);
-      extensionServer.registerHandler('notify-' + this._type, this._dispatch.bind(this));
-    },
-
-    removeListener: function(callback) {
-      const listeners = this._listeners;
-
-      for (let i = 0; i < listeners.length; ++i) {
-        if (listeners[i] === callback) {
-          listeners.splice(i, 1);
-          break;
-        }
-      }
-      if (this._listeners.length === 0)
-        extensionServer.sendRequest({command: commands.Unsubscribe, type: this._type});
-    },
-
-    /**
-     * @param {...} vararg
-     */
-    _fire: function(vararg) {
-      const listeners = this._listeners.slice();
-      for (let i = 0; i < listeners.length; ++i)
-        listeners[i].apply(null, arguments);
-    },
-
-    _dispatch: function(request) {
-      if (this._customDispatch)
-        this._customDispatch.call(this, request);
-      else
-        this._fire.apply(this, request.arguments);
-    }
-  };
-
-  /**
-   * @constructor
-   */
-  function InspectorExtensionAPI() {
-    this.inspectedWindow = new InspectedWindow();
-    this.panels = new Panels();
-    this.network = new Network();
-    this.timeline = new Timeline();
-    defineDeprecatedProperty(this, 'webInspector', 'resources', 'network');
-  }
-
-  /**
-   * @constructor
-   */
-  function Network() {
-    /**
-     * @this {EventSinkImpl}
-     */
-    function dispatchRequestEvent(message) {
-      const request = message.arguments[1];
-      request.__proto__ = new Request(message.arguments[0]);
-      this._fire(request);
-    }
-    this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
-    defineDeprecatedProperty(this, 'network', 'onFinished', 'onRequestFinished');
-    this.onNavigated = new EventSink(events.InspectedURLChanged);
-  }
-
-  Network.prototype = {
-    getHAR: function(callback) {
-      function callbackWrapper(result) {
-        const entries = (result && result.entries) || [];
-        for (let i = 0; i < entries.length; ++i) {
-          entries[i].__proto__ = new Request(entries[i]._requestId);
-          delete entries[i]._requestId;
-        }
-        callback(result);
-      }
-      extensionServer.sendRequest({command: commands.GetHAR}, callback && callbackWrapper);
-    },
-
-    addRequestHeaders: function(headers) {
-      extensionServer.sendRequest(
-          {command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname});
-    }
-  };
-
-  /**
-   * @constructor
-   */
-  function RequestImpl(id) {
-    this._id = id;
-  }
-
-  RequestImpl.prototype = {
-    getContent: function(callback) {
-      function callbackWrapper(response) {
-        callback(response.content, response.encoding);
-      }
-      extensionServer.sendRequest({command: commands.GetRequestContent, id: this._id}, callback && callbackWrapper);
-    }
-  };
-
-  /**
-   * @constructor
-   */
-  function Panels() {
-    const panels = {
-      elements: new ElementsPanel(),
-      sources: new SourcesPanel(),
-    };
-
-    function panelGetter(name) {
-      return panels[name];
-    }
-    for (const panel in panels)
-      this.__defineGetter__(panel, panelGetter.bind(null, panel));
-    this.applyStyleSheet = function(styleSheet) {
-      extensionServer.sendRequest({command: commands.ApplyStyleSheet, styleSheet: styleSheet});
-    };
-  }
-
-  Panels.prototype = {
-    create: function(title, icon, page, callback) {
-      const id = 'extension-panel-' + extensionServer.nextObjectId();
-      const request = {command: commands.CreatePanel, id: id, title: title, icon: icon, page: page};
-      extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
-    },
-
-    setOpenResourceHandler: function(callback) {
-      const hadHandler = extensionServer.hasHandler(events.OpenResource);
-
-      function callbackWrapper(message) {
-        // Allow the panel to show itself when handling the event.
-        userAction = true;
-        try {
-          callback.call(null, new Resource(message.resource), message.lineNumber);
-        } finally {
-          userAction = false;
-        }
-      }
-
-      if (!callback)
-        extensionServer.unregisterHandler(events.OpenResource);
-      else
-        extensionServer.registerHandler(events.OpenResource, callbackWrapper);
-
-      // Only send command if we either removed an existing handler or added handler and had none before.
-      if (hadHandler === !callback)
-        extensionServer.sendRequest({command: commands.SetOpenResourceHandler, 'handlerPresent': !!callback});
-    },
-
-    openResource: function(url, lineNumber, callback) {
-      extensionServer.sendRequest({command: commands.OpenResource, 'url': url, 'lineNumber': lineNumber}, callback);
-    },
-
-    get SearchAction() {
-      return apiPrivate.panels.SearchAction;
-    }
-  };
-
-  /**
-   * @constructor
-   */
-  function ExtensionViewImpl(id) {
-    this._id = id;
-
-    /**
-     * @this {EventSinkImpl}
-     */
-    function dispatchShowEvent(message) {
-      const frameIndex = message.arguments[0];
-      if (typeof frameIndex === 'number')
-        this._fire(window.parent.frames[frameIndex]);
-      else
-        this._fire();
-    }
-
-    if (id) {
-      this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
-      this.onHidden = new EventSink(events.ViewHidden + id);
-    }
-  }
-
-  /**
-   * @constructor
-   * @extends {ExtensionViewImpl}
-   * @param {string} hostPanelName
-   */
-  function PanelWithSidebarImpl(hostPanelName) {
-    ExtensionViewImpl.call(this, null);
-    this._hostPanelName = hostPanelName;
-    this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPanelName);
-  }
-
-  PanelWithSidebarImpl.prototype = {
-    createSidebarPane: function(title, callback) {
-      const id = 'extension-sidebar-' + extensionServer.nextObjectId();
-      const request = {command: commands.CreateSidebarPane, panel: this._hostPanelName, id: id, title: title};
-      function callbackWrapper() {
-        callback(new ExtensionSidebarPane(id));
-      }
-      extensionServer.sendRequest(request, callback && callbackWrapper);
-    },
-
-    __proto__: ExtensionViewImpl.prototype
-  };
-
-  function declareInterfaceClass(implConstructor) {
-    return function() {
-      const impl = {__proto__: implConstructor.prototype};
-      implConstructor.apply(impl, arguments);
-      populateInterfaceClass(this, impl);
-    };
-  }
-
-  function defineDeprecatedProperty(object, className, oldName, newName) {
-    let warningGiven = false;
-    function getter() {
-      if (!warningGiven) {
-        console.warn(className + '.' + oldName + ' is deprecated. Use ' + className + '.' + newName + ' instead');
-        warningGiven = true;
-      }
-      return object[newName];
-    }
-    object.__defineGetter__(oldName, getter);
-  }
-
-  function extractCallbackArgument(args) {
-    const lastArgument = args[args.length - 1];
-    return typeof lastArgument === 'function' ? lastArgument : undefined;
-  }
-
-  const Button = declareInterfaceClass(ButtonImpl);
-  const EventSink = declareInterfaceClass(EventSinkImpl);
-  const ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
-  const ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
-  const PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
-  const Request = declareInterfaceClass(RequestImpl);
-  const Resource = declareInterfaceClass(ResourceImpl);
-  const TraceSession = declareInterfaceClass(TraceSessionImpl);
-
-  /**
-   * @constructor
-   * @extends {PanelWithSidebar}
-   */
-  function ElementsPanel() {
-    PanelWithSidebar.call(this, 'elements');
-  }
-
-  ElementsPanel.prototype = {__proto__: PanelWithSidebar.prototype};
-
-  /**
-   * @constructor
-   * @extends {PanelWithSidebar}
-   */
-  function SourcesPanel() {
-    PanelWithSidebar.call(this, 'sources');
-  }
-
-  SourcesPanel.prototype = {__proto__: PanelWithSidebar.prototype};
-
-  /**
-   * @constructor
-   * @extends {ExtensionViewImpl}
-   */
-  function ExtensionPanelImpl(id) {
-    ExtensionViewImpl.call(this, id);
-    this.onSearch = new EventSink(events.PanelSearch + id);
-  }
-
-  ExtensionPanelImpl.prototype = {
-    /**
-     * @return {!Object}
-     */
-    createStatusBarButton: function(iconPath, tooltipText, disabled) {
-      const id = 'button-' + extensionServer.nextObjectId();
-      const request = {
-        command: commands.CreateToolbarButton,
-        panel: this._id,
-        id: id,
-        icon: iconPath,
-        tooltip: tooltipText,
-        disabled: !!disabled
-      };
-      extensionServer.sendRequest(request);
-      return new Button(id);
-    },
-
-    show: function() {
-      if (!userAction)
-        return;
-
-      const request = {command: commands.ShowPanel, id: this._id};
-      extensionServer.sendRequest(request);
-    },
-
-    __proto__: ExtensionViewImpl.prototype
-  };
-
-  /**
-   * @constructor
-   * @extends {ExtensionViewImpl}
-   */
-  function ExtensionSidebarPaneImpl(id) {
-    ExtensionViewImpl.call(this, id);
-  }
-
-  ExtensionSidebarPaneImpl.prototype = {
-    setHeight: function(height) {
-      extensionServer.sendRequest({command: commands.SetSidebarHeight, id: this._id, height: height});
-    },
-
-    setExpression: function(expression, rootTitle, evaluateOptions) {
-      const request = {
-        command: commands.SetSidebarContent,
-        id: this._id,
-        expression: expression,
-        rootTitle: rootTitle,
-        evaluateOnPage: true,
-      };
-      if (typeof evaluateOptions === 'object')
-        request.evaluateOptions = evaluateOptions;
-      extensionServer.sendRequest(request, extractCallbackArgument(arguments));
-    },
-
-    setObject: function(jsonObject, rootTitle, callback) {
-      extensionServer.sendRequest(
-          {command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle}, callback);
-    },
-
-    setPage: function(page) {
-      extensionServer.sendRequest({command: commands.SetSidebarPage, id: this._id, page: page});
-    },
-
-    __proto__: ExtensionViewImpl.prototype
-  };
-
-  /**
-   * @constructor
-   */
-  function ButtonImpl(id) {
-    this._id = id;
-    this.onClicked = new EventSink(events.ButtonClicked + id);
-  }
-
-  ButtonImpl.prototype = {
-    update: function(iconPath, tooltipText, disabled) {
-      const request =
-          {command: commands.UpdateButton, id: this._id, icon: iconPath, tooltip: tooltipText, disabled: !!disabled};
-      extensionServer.sendRequest(request);
-    }
-  };
-
-  /**
-   * @constructor
-   */
-  function Timeline() {
-  }
-
-  Timeline.prototype = {
-    /**
-     * @param {string} categoryName
-     * @param {string} categoryTooltip
-     * @return {!TraceProvider}
-     */
-    addTraceProvider: function(categoryName, categoryTooltip) {
-      const id = 'extension-trace-provider-' + extensionServer.nextObjectId();
-      extensionServer.sendRequest(
-          {command: commands.AddTraceProvider, id: id, categoryName: categoryName, categoryTooltip: categoryTooltip});
-      return new TraceProvider(id);
-    }
-  };
-
-  /**
-   * @constructor
-   * @param {string} id
-   */
-  function TraceSessionImpl(id) {
-    this._id = id;
-  }
-
-  TraceSessionImpl.prototype = {
-    /**
-     * @param {string=} url
-     * @param {number=} timeOffset
-     */
-    complete: function(url, timeOffset) {
-      const request =
-          {command: commands.CompleteTraceSession, id: this._id, url: url || '', timeOffset: timeOffset || 0};
-      extensionServer.sendRequest(request);
-    }
-  };
-
-  /**
-   * @constructor
-   * @param {string} id
-   */
-  function TraceProvider(id) {
-    /**
-     * @this {EventSinkImpl}
-     */
-    function dispatchRecordingStarted(message) {
-      const sessionId = message.arguments[0];
-      this._fire(new TraceSession(sessionId));
-    }
-
-    this.onRecordingStarted = new EventSink(events.RecordingStarted + id, dispatchRecordingStarted);
-    this.onRecordingStopped = new EventSink(events.RecordingStopped + id);
-  }
-
-  /**
-   * @constructor
-   */
-  function InspectedWindow() {
-    /**
-     * @this {EventSinkImpl}
-     */
-    function dispatchResourceEvent(message) {
-      this._fire(new Resource(message.arguments[0]));
-    }
-
-    /**
-     * @this {EventSinkImpl}
-     */
-    function dispatchResourceContentEvent(message) {
-      this._fire(new Resource(message.arguments[0]), message.arguments[1]);
-    }
-
-    this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
-    this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
-  }
-
-  InspectedWindow.prototype = {
-    reload: function(optionsOrUserAgent) {
-      let options = null;
-      if (typeof optionsOrUserAgent === 'object') {
-        options = optionsOrUserAgent;
-      } else if (typeof optionsOrUserAgent === 'string') {
-        options = {userAgent: optionsOrUserAgent};
-        console.warn(
-            'Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. ' +
-            'Use inspectedWindow.reload({ userAgent: value}) instead.');
-      }
-      extensionServer.sendRequest({command: commands.Reload, options: options});
-    },
-
-    /**
-     * @return {?Object}
-     */
-    eval: function(expression, evaluateOptions) {
-      const callback = extractCallbackArgument(arguments);
-      function callbackWrapper(result) {
-        if (result.isError || result.isException)
-          callback(undefined, result);
-        else
-          callback(result.value);
-      }
-      const request = {command: commands.EvaluateOnInspectedPage, expression: expression};
-      if (typeof evaluateOptions === 'object')
-        request.evaluateOptions = evaluateOptions;
-      extensionServer.sendRequest(request, callback && callbackWrapper);
-      return null;
-    },
-
-    getResources: function(callback) {
-      function wrapResource(resourceData) {
-        return new Resource(resourceData);
-      }
-      function callbackWrapper(resources) {
-        callback(resources.map(wrapResource));
-      }
-      extensionServer.sendRequest({command: commands.GetPageResources}, callback && callbackWrapper);
-    }
-  };
-
-  /**
-   * @constructor
-   */
-  function ResourceImpl(resourceData) {
-    this._url = resourceData.url;
-    this._type = resourceData.type;
-  }
-
-  ResourceImpl.prototype = {
-    get url() {
-      return this._url;
-    },
-
-    get type() {
-      return this._type;
-    },
-
-    getContent: function(callback) {
-      function callbackWrapper(response) {
-        callback(response.content, response.encoding);
-      }
-
-      extensionServer.sendRequest({command: commands.GetResourceContent, url: this._url}, callback && callbackWrapper);
-    },
-
-    setContent: function(content, commit, callback) {
-      extensionServer.sendRequest(
-          {command: commands.SetResourceContent, url: this._url, content: content, commit: commit}, callback);
-    }
-  };
-
-  function getTabId() {
-    return inspectedTabId;
-  }
-
-  let keyboardEventRequestQueue = [];
-  let forwardTimer = null;
-
-  function forwardKeyboardEvent(event) {
-    // We only care about global hotkeys, not about random text
-    if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.key) && event.key !== 'Escape')
-      return;
-    const requestPayload = {
-      eventType: event.type,
-      ctrlKey: event.ctrlKey,
-      altKey: event.altKey,
-      metaKey: event.metaKey,
-      keyIdentifier: event.keyIdentifier,
-      key: event.key,
-      code: event.code,
-      location: event.location,
-      keyCode: event.keyCode
-    };
-    keyboardEventRequestQueue.push(requestPayload);
-    if (!forwardTimer)
-      forwardTimer = setTimeout(forwardEventQueue, 0);
-  }
-
-  function forwardEventQueue() {
-    forwardTimer = null;
-    const request = {command: commands.ForwardKeyboardEvent, entries: keyboardEventRequestQueue};
-    extensionServer.sendRequest(request);
-    keyboardEventRequestQueue = [];
-  }
-
-  document.addEventListener('keydown', forwardKeyboardEvent, false);
-  document.addEventListener('keypress', forwardKeyboardEvent, false);
-
-  /**
-   * @constructor
-   */
-  function ExtensionServerClient() {
-    this._callbacks = {};
-    this._handlers = {};
-    this._lastRequestId = 0;
-    this._lastObjectId = 0;
-
-    this.registerHandler('callback', this._onCallback.bind(this));
-
-    const channel = new MessageChannel();
-    this._port = channel.port1;
-    this._port.addEventListener('message', this._onMessage.bind(this), false);
-    this._port.start();
-
-    window.parent.postMessage('registerExtension', '*', [channel.port2]);
-  }
-
-  ExtensionServerClient.prototype = {
-    /**
-     * @param {!Object} message
-     * @param {function()=} callback
-     */
-    sendRequest: function(message, callback) {
-      if (typeof callback === 'function')
-        message.requestId = this._registerCallback(callback);
-      this._port.postMessage(message);
-    },
-
-    /**
-     * @return {boolean}
-     */
-    hasHandler: function(command) {
-      return !!this._handlers[command];
-    },
-
-    registerHandler: function(command, handler) {
-      this._handlers[command] = handler;
-    },
-
-    unregisterHandler: function(command) {
-      delete this._handlers[command];
-    },
-
-    /**
-     * @return {string}
-     */
-    nextObjectId: function() {
-      return injectedScriptId.toString() + '_' + ++this._lastObjectId;
-    },
-
-    _registerCallback: function(callback) {
-      const id = ++this._lastRequestId;
-      this._callbacks[id] = callback;
-      return id;
-    },
-
-    _onCallback: function(request) {
-      if (request.requestId in this._callbacks) {
-        const callback = this._callbacks[request.requestId];
-        delete this._callbacks[request.requestId];
-        callback(request.result);
-      }
-    },
-
-    _onMessage: function(event) {
-      const request = event.data;
-      const handler = this._handlers[request.command];
-      if (handler)
-        handler.call(this, request);
-    }
-  };
-
-  function populateInterfaceClass(interfaze, implementation) {
-    for (const member in implementation) {
-      if (member.charAt(0) === '_')
-        continue;
-      let descriptor = null;
-      // Traverse prototype chain until we find the owner.
-      for (let owner = implementation; owner && !descriptor; owner = owner.__proto__)
-        descriptor = Object.getOwnPropertyDescriptor(owner, member);
-      if (!descriptor)
-        continue;
-      if (typeof descriptor.value === 'function')
-        interfaze[member] = descriptor.value.bind(implementation);
-      else if (typeof descriptor.get === 'function')
-        interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
-      else
-        Object.defineProperty(interfaze, member, descriptor);
-    }
-  }
-
-  const extensionServer = new ExtensionServerClient();
-  const coreAPI = new InspectorExtensionAPI();
-
-  Object.defineProperty(chrome, 'devtools', {value: {}, enumerable: true});
-
-  // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
-  chrome.devtools.inspectedWindow = {};
-  chrome.devtools.inspectedWindow.__defineGetter__('tabId', getTabId);
-  chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
-  chrome.devtools.network = coreAPI.network;
-  chrome.devtools.panels = coreAPI.panels;
-  chrome.devtools.panels.themeName = themeName;
-
-  // default to expose experimental APIs for now.
-  if (extensionInfo.exposeExperimentalAPIs !== false) {
-    chrome.experimental = chrome.experimental || {};
-    chrome.experimental.devtools = chrome.experimental.devtools || {};
-
-    const properties = Object.getOwnPropertyNames(coreAPI);
-    for (let i = 0; i < properties.length; ++i) {
-      const descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
-      if (descriptor)
-        Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
-    }
-    chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
-  }
-
-  if (extensionInfo.exposeWebInspectorNamespace)
-    window.webInspector = coreAPI;
-  testHook(extensionServer, coreAPI);
-}
-
-/**
- * @param {!ExtensionDescriptor} extensionInfo
- * @param {string} inspectedTabId
- * @param {string} themeName
- * @param {function(!Object, !Object)|undefined} testHook
- * @return {string}
- */
-function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeName, testHook) {
-  const argumentsJSON = [extensionInfo, inspectedTabId || null, themeName].map(_ => JSON.stringify(_)).join(',');
-  if (!testHook)
-    testHook = () => {};
-  return '(function(injectedScriptId){ ' + defineCommonExtensionSymbols.toString() + ';' +
-      '(' + injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
-      '})';
-}
diff --git a/front_end/extensions/ExtensionPanel.js b/front_end/extensions/ExtensionPanel.js
deleted file mode 100644
index 1f1a885..0000000
--- a/front_end/extensions/ExtensionPanel.js
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Extensions.ExtensionPanel = class extends UI.Panel {
-  /**
-   * @param {!Extensions.ExtensionServer} server
-   * @param {string} panelName
-   * @param {string} id
-   * @param {string} pageURL
-   */
-  constructor(server, panelName, id, pageURL) {
-    super(panelName);
-    this._server = server;
-    this._id = id;
-    this.setHideOnDetach();
-    this._panelToolbar = new UI.Toolbar('hidden', this.element);
-
-    this._searchableView = new UI.SearchableView(this);
-    this._searchableView.show(this.element);
-
-    const extensionView = new Extensions.ExtensionView(server, this._id, pageURL, 'extension');
-    extensionView.show(this._searchableView.element);
-  }
-
-  /**
-   * @param {!UI.ToolbarItem} item
-   */
-  addToolbarItem(item) {
-    this._panelToolbar.element.classList.remove('hidden');
-    this._panelToolbar.appendToolbarItem(item);
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._server.notifySearchAction(this._id, Extensions.extensionAPI.panels.SearchAction.CancelSearch);
-    this._searchableView.updateSearchMatchesCount(0);
-  }
-
-  /**
-   * @override
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    const query = searchConfig.query;
-    this._server.notifySearchAction(this._id, Extensions.extensionAPI.panels.SearchAction.PerformSearch, query);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    this._server.notifySearchAction(this._id, Extensions.extensionAPI.panels.SearchAction.NextSearchResult);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    this._server.notifySearchAction(this._id, Extensions.extensionAPI.panels.SearchAction.PreviousSearchResult);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionButton = class {
-  /**
-   * @param {!Extensions.ExtensionServer} server
-   * @param {string} id
-   * @param {string} iconURL
-   * @param {string=} tooltip
-   * @param {boolean=} disabled
-   */
-  constructor(server, id, iconURL, tooltip, disabled) {
-    this._id = id;
-
-    this._toolbarButton = new UI.ToolbarButton('', '');
-    this._toolbarButton.addEventListener(
-        UI.ToolbarButton.Events.Click, server.notifyButtonClicked.bind(server, this._id));
-    this.update(iconURL, tooltip, disabled);
-  }
-
-  /**
-   * @param {string} iconURL
-   * @param {string=} tooltip
-   * @param {boolean=} disabled
-   */
-  update(iconURL, tooltip, disabled) {
-    if (typeof iconURL === 'string')
-      this._toolbarButton.setBackgroundImage(iconURL);
-    if (typeof tooltip === 'string')
-      this._toolbarButton.setTitle(tooltip);
-    if (typeof disabled === 'boolean')
-      this._toolbarButton.setEnabled(!disabled);
-  }
-
-  /**
-   * @return {!UI.ToolbarButton}
-   */
-  toolbarButton() {
-    return this._toolbarButton;
-  }
-};
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionSidebarPane = class extends UI.SimpleView {
-  /**
-   * @param {!Extensions.ExtensionServer} server
-   * @param {string} panelName
-   * @param {string} title
-   * @param {string} id
-   */
-  constructor(server, panelName, title, id) {
-    super(title);
-    this.element.classList.add('fill');
-    this._panelName = panelName;
-    this._server = server;
-    this._id = id;
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  panelName() {
-    return this._panelName;
-  }
-
-  /**
-   * @param {!Object} object
-   * @param {string} title
-   * @param {function(?string=)} callback
-   */
-  setObject(object, title, callback) {
-    this._createObjectPropertiesView();
-    this._setObject(SDK.RemoteObject.fromLocalObject(object), title, callback);
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} title
-   * @param {!Object} evaluateOptions
-   * @param {string} securityOrigin
-   * @param {function(?string=)} callback
-   */
-  setExpression(expression, title, evaluateOptions, securityOrigin, callback) {
-    this._createObjectPropertiesView();
-    this._server.evaluate(
-        expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
-  }
-
-  /**
-   * @param {string} url
-   */
-  setPage(url) {
-    if (this._objectPropertiesView) {
-      this._objectPropertiesView.detach();
-      delete this._objectPropertiesView;
-    }
-    if (this._extensionView)
-      this._extensionView.detach(true);
-
-    this._extensionView = new Extensions.ExtensionView(this._server, this._id, url, 'extension fill');
-    this._extensionView.show(this.element);
-
-    if (!this.element.style.height)
-      this.setHeight('150px');
-  }
-
-  /**
-   * @param {string} height
-   */
-  setHeight(height) {
-    this.element.style.height = height;
-  }
-
-  /**
-   * @param {string} title
-   * @param {function(?string=)} callback
-   * @param {?Protocol.Error} error
-   * @param {?SDK.RemoteObject} result
-   * @param {boolean=} wasThrown
-   */
-  _onEvaluate(title, callback, error, result, wasThrown) {
-    if (error || !result)
-      callback(error.toString());
-    else
-      this._setObject(result, title, callback);
-  }
-
-  _createObjectPropertiesView() {
-    if (this._objectPropertiesView)
-      return;
-    if (this._extensionView) {
-      this._extensionView.detach(true);
-      delete this._extensionView;
-    }
-    this._objectPropertiesView = new Extensions.ExtensionNotifierView(this._server, this._id);
-    this._objectPropertiesView.show(this.element);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {string} title
-   * @param {function(?string=)} callback
-   */
-  _setObject(object, title, callback) {
-    // This may only happen if setPage() was called while we were evaluating the expression.
-    if (!this._objectPropertiesView) {
-      callback('operation cancelled');
-      return;
-    }
-    this._objectPropertiesView.element.removeChildren();
-    Common.Renderer
-        .render(object, {
-          title: title,
-          expanded: true,
-          editable: false,
-        })
-        .then(element => {
-          this._objectPropertiesView.element.appendChild(element);
-          callback();
-        });
-  }
-};
diff --git a/front_end/extensions/ExtensionRegistryStub.js b/front_end/extensions/ExtensionRegistryStub.js
deleted file mode 100644
index 54c1824..0000000
--- a/front_end/extensions/ExtensionRegistryStub.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-if (!window.InspectorExtensionRegistry) {
-  /**
-   * @unrestricted
-   */
-  Extensions.InspectorExtensionRegistryStub = class {
-    getExtensionsAsync() {
-    }
-  };
-
-  self.InspectorExtensionRegistry = new Extensions.InspectorExtensionRegistryStub();
-}
diff --git a/front_end/extensions/ExtensionServer.js b/front_end/extensions/ExtensionServer.js
deleted file mode 100644
index cb93140..0000000
--- a/front_end/extensions/ExtensionServer.js
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionServer = class extends Common.Object {
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  constructor() {
-    super();
-    this._clientObjects = {};
-    this._handlers = {};
-    this._subscribers = {};
-    this._subscriptionStartHandlers = {};
-    this._subscriptionStopHandlers = {};
-    this._extraHeaders = {};
-    this._requests = {};
-    this._lastRequestId = 0;
-    this._registeredExtensions = {};
-    this._status = new Extensions.ExtensionStatus();
-    /** @type {!Array<!Extensions.ExtensionSidebarPane>} */
-    this._sidebarPanes = [];
-    /** @type {!Array<!Extensions.ExtensionTraceProvider>} */
-    this._traceProviders = [];
-    /** @type {!Map<string, !Extensions.TracingSession>} */
-    this._traceSessions = new Map();
-
-    const commands = Extensions.extensionAPI.Commands;
-
-    this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
-    this._registerHandler(commands.AddTraceProvider, this._onAddTraceProvider.bind(this));
-    this._registerHandler(commands.ApplyStyleSheet, this._onApplyStyleSheet.bind(this));
-    this._registerHandler(commands.CompleteTraceSession, this._onCompleteTraceSession.bind(this));
-    this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
-    this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
-    this._registerHandler(commands.CreateToolbarButton, this._onCreateToolbarButton.bind(this));
-    this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
-    this._registerHandler(commands.ForwardKeyboardEvent, this._onForwardKeyboardEvent.bind(this));
-    this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
-    this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
-    this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
-    this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
-    this._registerHandler(commands.Reload, this._onReload.bind(this));
-    this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
-    this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
-    this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
-    this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
-    this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
-    this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
-    this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
-    this._registerHandler(commands.OpenResource, this._onOpenResource.bind(this));
-    this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
-    this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
-    window.addEventListener('message', this._onWindowMessage.bind(this), false);  // Only for main window.
-
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.AddExtensions, this._addExtensions, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this);
-
-    this._initExtensions();
-  }
-
-  initializeExtensions() {
-    this._initializeCommandIssued = true;
-    if (this._pendingExtensionInfos) {
-      this._pendingExtensionInfos.forEach(this._addExtension, this);
-      delete this._pendingExtensionInfos;
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasExtensions() {
-    return !!Object.keys(this._registeredExtensions).length;
-  }
-
-  /**
-   * @param {string} panelId
-   * @param {string} action
-   * @param {string=} searchString
-   */
-  notifySearchAction(panelId, action, searchString) {
-    this._postNotification(Extensions.extensionAPI.Events.PanelSearch + panelId, action, searchString);
-  }
-
-  /**
-   * @param {string} identifier
-   * @param {number=} frameIndex
-   */
-  notifyViewShown(identifier, frameIndex) {
-    this._postNotification(Extensions.extensionAPI.Events.ViewShown + identifier, frameIndex);
-  }
-
-  /**
-   * @param {string} identifier
-   */
-  notifyViewHidden(identifier) {
-    this._postNotification(Extensions.extensionAPI.Events.ViewHidden + identifier);
-  }
-
-  /**
-   * @param {string} identifier
-   */
-  notifyButtonClicked(identifier) {
-    this._postNotification(Extensions.extensionAPI.Events.ButtonClicked + identifier);
-  }
-
-  _inspectedURLChanged(event) {
-    if (event.data !== SDK.targetManager.mainTarget())
-      return;
-    this._requests = {};
-    const url = event.data.inspectedURL();
-    this._postNotification(Extensions.extensionAPI.Events.InspectedURLChanged, url);
-  }
-
-  /**
-   * @param {string} providerId
-   * @param {string} sessionId
-   * @param {!Extensions.TracingSession} session
-   */
-  startTraceRecording(providerId, sessionId, session) {
-    this._traceSessions.set(sessionId, session);
-    this._postNotification('trace-recording-started-' + providerId, sessionId);
-  }
-
-  /**
-   * @param {string} providerId
-   */
-  stopTraceRecording(providerId) {
-    this._postNotification('trace-recording-stopped-' + providerId);
-  }
-
-  /**
-   * @param {string} type
-   * @return {boolean}
-   */
-  hasSubscribers(type) {
-    return !!this._subscribers[type];
-  }
-
-  /**
-   * @param {string} type
-   * @param {...*} vararg
-   */
-  _postNotification(type, vararg) {
-    const subscribers = this._subscribers[type];
-    if (!subscribers)
-      return;
-    const message = {command: 'notify-' + type, arguments: Array.prototype.slice.call(arguments, 1)};
-    for (let i = 0; i < subscribers.length; ++i)
-      subscribers[i].postMessage(message);
-  }
-
-  _onSubscribe(message, port) {
-    const subscribers = this._subscribers[message.type];
-    if (subscribers) {
-      subscribers.push(port);
-    } else {
-      this._subscribers[message.type] = [port];
-      if (this._subscriptionStartHandlers[message.type])
-        this._subscriptionStartHandlers[message.type]();
-    }
-  }
-
-  _onUnsubscribe(message, port) {
-    const subscribers = this._subscribers[message.type];
-    if (!subscribers)
-      return;
-    subscribers.remove(port);
-    if (!subscribers.length) {
-      delete this._subscribers[message.type];
-      if (this._subscriptionStopHandlers[message.type])
-        this._subscriptionStopHandlers[message.type]();
-    }
-  }
-
-  _onAddRequestHeaders(message) {
-    const id = message.extensionId;
-    if (typeof id !== 'string')
-      return this._status.E_BADARGTYPE('extensionId', typeof id, 'string');
-    let extensionHeaders = this._extraHeaders[id];
-    if (!extensionHeaders) {
-      extensionHeaders = {};
-      this._extraHeaders[id] = extensionHeaders;
-    }
-    for (const name in message.headers)
-      extensionHeaders[name] = message.headers[name];
-    const allHeaders = /** @type {!Protocol.Network.Headers} */ ({});
-    for (const extension in this._extraHeaders) {
-      const headers = this._extraHeaders[extension];
-      for (const name in headers) {
-        if (typeof headers[name] === 'string')
-          allHeaders[name] = headers[name];
-      }
-    }
-
-    SDK.multitargetNetworkManager.setExtraHTTPHeaders(allHeaders);
-  }
-
-  /**
-   * @param {*} message
-   * @suppressGlobalPropertiesCheck
-   */
-  _onApplyStyleSheet(message) {
-    if (!Runtime.experiments.isEnabled('applyCustomStylesheet'))
-      return;
-    const styleSheet = createElement('style');
-    styleSheet.textContent = message.styleSheet;
-    document.head.appendChild(styleSheet);
-
-    UI.themeSupport.addCustomStylesheet(message.styleSheet);
-    // Add to all the shadow roots that have already been created
-    for (let node = document.body; node; node = node.traverseNextNode(document.body)) {
-      if (node instanceof ShadowRoot)
-        UI.themeSupport.injectCustomStyleSheets(node);
-    }
-  }
-
-  _onCreatePanel(message, port) {
-    const id = message.id;
-    // The ids are generated on the client API side and must be unique, so the check below
-    // shouldn't be hit unless someone is bypassing the API.
-    if (id in this._clientObjects || UI.inspectorView.hasPanel(id))
-      return this._status.E_EXISTS(id);
-
-    const page = this._expandResourcePath(port._extensionOrigin, message.page);
-    let persistentId = port._extensionOrigin + message.title;
-    persistentId = persistentId.replace(/\s/g, '');
-    const panelView = new Extensions.ExtensionServerPanelView(
-        persistentId, message.title, new Extensions.ExtensionPanel(this, persistentId, id, page));
-    this._clientObjects[id] = panelView;
-    UI.inspectorView.addPanel(panelView);
-    return this._status.OK();
-  }
-
-  _onShowPanel(message) {
-    let panelViewId = message.id;
-    const panelView = this._clientObjects[message.id];
-    if (panelView && panelView instanceof Extensions.ExtensionServerPanelView)
-      panelViewId = panelView.viewId();
-    UI.inspectorView.showPanel(panelViewId);
-  }
-
-  _onCreateToolbarButton(message, port) {
-    const panelView = this._clientObjects[message.panel];
-    if (!panelView || !(panelView instanceof Extensions.ExtensionServerPanelView))
-      return this._status.E_NOTFOUND(message.panel);
-    const button = new Extensions.ExtensionButton(
-        this, message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip,
-        message.disabled);
-    this._clientObjects[message.id] = button;
-
-    panelView.widget().then(appendButton);
-
-    /**
-     * @param {!UI.Widget} panel
-     */
-    function appendButton(panel) {
-      /** @type {!Extensions.ExtensionPanel} panel*/ (panel).addToolbarItem(button.toolbarButton());
-    }
-
-    return this._status.OK();
-  }
-
-  _onUpdateButton(message, port) {
-    const button = this._clientObjects[message.id];
-    if (!button || !(button instanceof Extensions.ExtensionButton))
-      return this._status.E_NOTFOUND(message.id);
-    button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
-    return this._status.OK();
-  }
-
-  /**
-   * @param {!Object} message
-   */
-  _onCompleteTraceSession(message) {
-    const session = this._traceSessions.get(message.id);
-    if (!session)
-      return this._status.E_NOTFOUND(message.id);
-    this._traceSessions.delete(message.id);
-    session.complete(message.url, message.timeOffset);
-  }
-
-  _onCreateSidebarPane(message) {
-    if (message.panel !== 'elements' && message.panel !== 'sources')
-      return this._status.E_NOTFOUND(message.panel);
-    const id = message.id;
-    const sidebar = new Extensions.ExtensionSidebarPane(this, message.panel, message.title, id);
-    this._sidebarPanes.push(sidebar);
-    this._clientObjects[id] = sidebar;
-    this.dispatchEventToListeners(Extensions.ExtensionServer.Events.SidebarPaneAdded, sidebar);
-
-    return this._status.OK();
-  }
-
-  /**
-   * @return {!Array.<!Extensions.ExtensionSidebarPane>}
-   */
-  sidebarPanes() {
-    return this._sidebarPanes;
-  }
-
-  _onSetSidebarHeight(message) {
-    const sidebar = this._clientObjects[message.id];
-    if (!sidebar)
-      return this._status.E_NOTFOUND(message.id);
-    sidebar.setHeight(message.height);
-    return this._status.OK();
-  }
-
-  _onSetSidebarContent(message, port) {
-    const sidebar = this._clientObjects[message.id];
-    if (!sidebar)
-      return this._status.E_NOTFOUND(message.id);
-
-    /**
-     * @this {Extensions.ExtensionServer}
-     */
-    function callback(error) {
-      const result = error ? this._status.E_FAILED(error) : this._status.OK();
-      this._dispatchCallback(message.requestId, port, result);
-    }
-    if (message.evaluateOnPage) {
-      return sidebar.setExpression(
-          message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
-    }
-    sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
-  }
-
-  _onSetSidebarPage(message, port) {
-    const sidebar = this._clientObjects[message.id];
-    if (!sidebar)
-      return this._status.E_NOTFOUND(message.id);
-    sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
-  }
-
-  _onOpenResource(message) {
-    const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(message.url);
-    if (uiSourceCode) {
-      Common.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, 0));
-      return this._status.OK();
-    }
-
-    const resource = Bindings.resourceForURL(message.url);
-    if (resource) {
-      Common.Revealer.reveal(resource);
-      return this._status.OK();
-    }
-
-    const request = BrowserSDK.networkLog.requestForURL(message.url);
-    if (request) {
-      Common.Revealer.reveal(request);
-      return this._status.OK();
-    }
-
-    return this._status.E_NOTFOUND(message.url);
-  }
-
-  _onSetOpenResourceHandler(message, port) {
-    const name = this._registeredExtensions[port._extensionOrigin].name || ('Extension ' + port._extensionOrigin);
-    if (message.handlerPresent)
-      Components.Linkifier.registerLinkHandler(name, this._handleOpenURL.bind(this, port));
-    else
-      Components.Linkifier.unregisterLinkHandler(name);
-  }
-
-  _handleOpenURL(port, contentProvider, lineNumber) {
-    port.postMessage(
-        {command: 'open-resource', resource: this._makeResource(contentProvider), lineNumber: lineNumber + 1});
-  }
-
-  _onReload(message) {
-    const options = /** @type {!ExtensionReloadOptions} */ (message.options || {});
-
-    SDK.multitargetNetworkManager.setUserAgentOverride(typeof options.userAgent === 'string' ? options.userAgent : '');
-    let injectedScript;
-    if (options.injectedScript)
-      injectedScript = '(function(){' + options.injectedScript + '})()';
-    SDK.ResourceTreeModel.reloadAllPages(!!options.ignoreCache, injectedScript);
-    return this._status.OK();
-  }
-
-  _onEvaluateOnInspectedPage(message, port) {
-    /**
-     * @param {?Protocol.Error} error
-     * @param {?SDK.RemoteObject} object
-     * @param {boolean} wasThrown
-     * @this {Extensions.ExtensionServer}
-     */
-    function callback(error, object, wasThrown) {
-      let result;
-      if (error || !object)
-        result = this._status.E_PROTOCOLERROR(error.toString());
-      else if (wasThrown)
-        result = {isException: true, value: object.description};
-      else
-        result = {value: object.value};
-
-      this._dispatchCallback(message.requestId, port, result);
-    }
-    return this.evaluate(
-        message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
-  }
-
-  async _onGetHAR() {
-    const requests = BrowserSDK.networkLog.requests();
-    const harLog = await BrowserSDK.HARLog.build(requests);
-    for (let i = 0; i < harLog.entries.length; ++i)
-      harLog.entries[i]._requestId = this._requestId(requests[i]);
-    return harLog;
-  }
-
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   */
-  _makeResource(contentProvider) {
-    return {url: contentProvider.contentURL(), type: contentProvider.contentType().name()};
-  }
-
-  /**
-   * @return {!Array<!Common.ContentProvider>}
-   */
-  _onGetPageResources() {
-    /** @type {!Map<string, !Common.ContentProvider>} */
-    const resources = new Map();
-
-    /**
-     * @this {Extensions.ExtensionServer}
-     */
-    function pushResourceData(contentProvider) {
-      if (!resources.has(contentProvider.contentURL()))
-        resources.set(contentProvider.contentURL(), this._makeResource(contentProvider));
-    }
-    let uiSourceCodes = Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.Network);
-    uiSourceCodes =
-        uiSourceCodes.concat(Workspace.workspace.uiSourceCodesForProjectType(Workspace.projectTypes.ContentScripts));
-    uiSourceCodes.forEach(pushResourceData.bind(this));
-    for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel))
-      resourceTreeModel.forAllResources(pushResourceData.bind(this));
-    return resources.valuesArray();
-  }
-
-  /**
-   * @param {!Common.ContentProvider} contentProvider
-   * @param {!Object} message
-   * @param {!MessagePort} port
-   */
-  async _getResourceContent(contentProvider, message, port) {
-    const content = await contentProvider.requestContent();
-    const encoded = await contentProvider.contentEncoded();
-    this._dispatchCallback(message.requestId, port, {encoding: encoded ? 'base64' : '', content: content});
-  }
-
-  _onGetRequestContent(message, port) {
-    const request = this._requestById(message.id);
-    if (!request)
-      return this._status.E_NOTFOUND(message.id);
-    this._getResourceContent(request, message, port);
-  }
-
-  _onGetResourceContent(message, port) {
-    const url = /** @type {string} */ (message.url);
-    const contentProvider = Workspace.workspace.uiSourceCodeForURL(url) || Bindings.resourceForURL(url);
-    if (!contentProvider)
-      return this._status.E_NOTFOUND(url);
-    this._getResourceContent(contentProvider, message, port);
-  }
-
-  _onSetResourceContent(message, port) {
-    /**
-     * @param {?Protocol.Error} error
-     * @this {Extensions.ExtensionServer}
-     */
-    function callbackWrapper(error) {
-      const response = error ? this._status.E_FAILED(error) : this._status.OK();
-      this._dispatchCallback(message.requestId, port, response);
-    }
-
-    const url = /** @type {string} */ (message.url);
-    const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
-    if (!uiSourceCode || !uiSourceCode.contentType().isDocumentOrScriptOrStyleSheet()) {
-      const resource = SDK.ResourceTreeModel.resourceForURL(url);
-      if (!resource)
-        return this._status.E_NOTFOUND(url);
-      return this._status.E_NOTSUPPORTED('Resource is not editable');
-    }
-    uiSourceCode.setWorkingCopy(message.content);
-    if (message.commit)
-      uiSourceCode.commitWorkingCopy();
-    callbackWrapper.call(this, null);
-  }
-
-  _requestId(request) {
-    if (!request._extensionRequestId) {
-      request._extensionRequestId = ++this._lastRequestId;
-      this._requests[request._extensionRequestId] = request;
-    }
-    return request._extensionRequestId;
-  }
-
-  _requestById(id) {
-    return this._requests[id];
-  }
-
-  /**
-   * @param {!Object} message
-   * @param {!MessagePort} port
-   */
-  _onAddTraceProvider(message, port) {
-    const provider = new Extensions.ExtensionTraceProvider(
-        port._extensionOrigin, message.id, message.categoryName, message.categoryTooltip);
-    this._clientObjects[message.id] = provider;
-    this._traceProviders.push(provider);
-    this.dispatchEventToListeners(Extensions.ExtensionServer.Events.TraceProviderAdded, provider);
-  }
-
-  /**
-   * @return {!Array<!Extensions.ExtensionTraceProvider>}
-   */
-  traceProviders() {
-    return this._traceProviders;
-  }
-
-  _onForwardKeyboardEvent(message) {
-    message.entries.forEach(handleEventEntry);
-
-    /**
-     * @param {*} entry
-     * @suppressGlobalPropertiesCheck
-     */
-    function handleEventEntry(entry) {
-      if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.key) && entry.key !== 'Escape')
-        return;
-      // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
-      // and initKeyboardEvent methods and overriding these in externs.js does not have effect.
-      const event = new window.KeyboardEvent(entry.eventType, {
-        key: entry.key,
-        code: entry.code,
-        keyCode: entry.keyCode,
-        location: entry.location,
-        ctrlKey: entry.ctrlKey,
-        altKey: entry.altKey,
-        shiftKey: entry.shiftKey,
-        metaKey: entry.metaKey
-      });
-      event.__keyCode = keyCodeForEntry(entry);
-      document.dispatchEvent(event);
-    }
-
-    function keyCodeForEntry(entry) {
-      let keyCode = entry.keyCode;
-      if (!keyCode) {
-        // This is required only for synthetic events (e.g. dispatched in tests).
-        if (entry.key === 'Escape')
-          keyCode = 27;
-      }
-      return keyCode || 0;
-    }
-  }
-
-  _dispatchCallback(requestId, port, result) {
-    if (requestId)
-      port.postMessage({command: 'callback', requestId: requestId, result: result});
-  }
-
-  _initExtensions() {
-    this._registerAutosubscriptionHandler(
-        Extensions.extensionAPI.Events.ResourceAdded, Workspace.workspace, Workspace.Workspace.Events.UISourceCodeAdded,
-        this._notifyResourceAdded);
-    this._registerAutosubscriptionTargetManagerHandler(
-        Extensions.extensionAPI.Events.NetworkRequestFinished, SDK.NetworkManager,
-        SDK.NetworkManager.Events.RequestFinished, this._notifyRequestFinished);
-
-    /**
-     * @this {Extensions.ExtensionServer}
-     */
-    function onElementsSubscriptionStarted() {
-      UI.context.addFlavorChangeListener(SDK.DOMNode, this._notifyElementsSelectionChanged, this);
-    }
-
-    /**
-     * @this {Extensions.ExtensionServer}
-     */
-    function onElementsSubscriptionStopped() {
-      UI.context.removeFlavorChangeListener(SDK.DOMNode, this._notifyElementsSelectionChanged, this);
-    }
-
-    this._registerSubscriptionHandler(
-        Extensions.extensionAPI.Events.PanelObjectSelected + 'elements', onElementsSubscriptionStarted.bind(this),
-        onElementsSubscriptionStopped.bind(this));
-    this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);
-
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
-
-    self.InspectorExtensionRegistry.getExtensionsAsync();
-  }
-
-  _notifyResourceAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._postNotification(Extensions.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
-  }
-
-  _notifyUISourceCodeContentCommitted(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    const content = /** @type {string} */ (event.data.content);
-    this._postNotification(
-        Extensions.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
-  }
-
-  async _notifyRequestFinished(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    const entry = await BrowserSDK.HAREntry.build(request);
-    this._postNotification(Extensions.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), entry);
-  }
-
-  _notifyElementsSelectionChanged() {
-    this._postNotification(Extensions.extensionAPI.Events.PanelObjectSelected + 'elements');
-  }
-
-  /**
-   * @param {string} url
-   * @param {!TextUtils.TextRange} range
-   */
-  sourceSelectionChanged(url, range) {
-    this._postNotification(Extensions.extensionAPI.Events.PanelObjectSelected + 'sources', {
-      startLine: range.startLine,
-      startColumn: range.startColumn,
-      endLine: range.endLine,
-      endColumn: range.endColumn,
-      url: url,
-    });
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _addExtensions(event) {
-    if (Extensions.extensionServer._overridePlatformExtensionAPIForTest)
-      window.buildPlatformExtensionAPI = Extensions.extensionServer._overridePlatformExtensionAPIForTest;
-
-    const extensionInfos = /** @type {!Array.<!ExtensionDescriptor>} */ (event.data);
-    if (this._initializeCommandIssued)
-      extensionInfos.forEach(this._addExtension, this);
-    else
-      this._pendingExtensionInfos = extensionInfos;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _setInspectedTabId(event) {
-    this._inspectedTabId = /** @type {string} */ (event.data);
-  }
-
-  /**
-   * @param {!ExtensionDescriptor} extensionInfo
-   * @suppressGlobalPropertiesCheck
-   */
-  _addExtension(extensionInfo) {
-    const urlOriginRegExp = new RegExp('([^:]+:\/\/[^/]*)\/');  // Can't use regexp literal here, MinJS chokes on it.
-    const startPage = extensionInfo.startPage;
-    const name = extensionInfo.name;
-
-    try {
-      const originMatch = urlOriginRegExp.exec(startPage);
-      if (!originMatch) {
-        console.error('Skipping extension with invalid URL: ' + startPage);
-        return false;
-      }
-      const extensionOrigin = originMatch[1];
-      if (!this._registeredExtensions[extensionOrigin]) {
-        // See ExtensionAPI.js for details.
-        const injectedAPI = buildExtensionAPIInjectedScript(
-            extensionInfo, this._inspectedTabId, UI.themeSupport.themeName(),
-            Extensions.extensionServer['_extensionAPITestHook']);
-        InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI);
-        this._registeredExtensions[extensionOrigin] = {name: name};
-      }
-      const iframe = createElement('iframe');
-      iframe.src = startPage;
-      iframe.style.display = 'none';
-      document.body.appendChild(iframe);  // Only for main window.
-    } catch (e) {
-      console.error('Failed to initialize extension ' + startPage + ':' + e);
-      return false;
-    }
-    return true;
-  }
-
-  _registerExtension(origin, port) {
-    if (!this._registeredExtensions.hasOwnProperty(origin)) {
-      if (origin !== window.location.origin)  // Just ignore inspector frames.
-        console.error('Ignoring unauthorized client request from ' + origin);
-      return;
-    }
-    port._extensionOrigin = origin;
-    port.addEventListener('message', this._onmessage.bind(this), false);
-    port.start();
-  }
-
-  _onWindowMessage(event) {
-    if (event.data === 'registerExtension')
-      this._registerExtension(event.origin, event.ports[0]);
-  }
-
-  async _onmessage(event) {
-    const message = event.data;
-    let result;
-
-    if (message.command in this._handlers)
-      result = await this._handlers[message.command](message, event.target);
-    else
-      result = this._status.E_NOTSUPPORTED(message.command);
-
-    if (result && message.requestId)
-      this._dispatchCallback(message.requestId, event.target, result);
-  }
-
-  _registerHandler(command, callback) {
-    console.assert(command);
-    this._handlers[command] = callback;
-  }
-
-  _registerSubscriptionHandler(eventTopic, onSubscribeFirst, onUnsubscribeLast) {
-    this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
-    this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
-  }
-
-  /**
-   * @param {string} eventTopic
-   * @param {!Object} eventTarget
-   * @param {string} frontendEventType
-   * @param {function(!Common.Event)} handler
-   */
-  _registerAutosubscriptionHandler(eventTopic, eventTarget, frontendEventType, handler) {
-    this._registerSubscriptionHandler(
-        eventTopic, eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
-        eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
-  }
-
-  /**
-   * @param {string} eventTopic
-   * @param {!Function} modelClass
-   * @param {string} frontendEventType
-   * @param {function(!Common.Event)} handler
-   */
-  _registerAutosubscriptionTargetManagerHandler(eventTopic, modelClass, frontendEventType, handler) {
-    this._registerSubscriptionHandler(
-        eventTopic,
-        SDK.targetManager.addModelListener.bind(SDK.targetManager, modelClass, frontendEventType, handler, this),
-        SDK.targetManager.removeModelListener.bind(SDK.targetManager, modelClass, frontendEventType, handler, this));
-  }
-
-  _registerResourceContentCommittedHandler(handler) {
-    /**
-     * @this {Extensions.ExtensionServer}
-     */
-    function addFirstEventListener() {
-      Workspace.workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
-      Workspace.workspace.setHasResourceContentTrackingExtensions(true);
-    }
-
-    /**
-     * @this {Extensions.ExtensionServer}
-     */
-    function removeLastEventListener() {
-      Workspace.workspace.setHasResourceContentTrackingExtensions(false);
-      Workspace.workspace.removeEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
-    }
-
-    this._registerSubscriptionHandler(
-        Extensions.extensionAPI.Events.ResourceContentCommitted, addFirstEventListener.bind(this),
-        removeLastEventListener.bind(this));
-  }
-
-  _expandResourcePath(extensionPath, resourcePath) {
-    if (!resourcePath)
-      return;
-    return extensionPath + this._normalizePath(resourcePath);
-  }
-
-  _normalizePath(path) {
-    const source = path.split('/');
-    const result = [];
-
-    for (let i = 0; i < source.length; ++i) {
-      if (source[i] === '.')
-        continue;
-      // Ignore empty path components resulting from //, as well as a leading and traling slashes.
-      if (source[i] === '')
-        continue;
-      if (source[i] === '..')
-        result.pop();
-      else
-        result.push(source[i]);
-    }
-    return '/' + result.join('/');
-  }
-
-  /**
-   * @param {string} expression
-   * @param {boolean} exposeCommandLineAPI
-   * @param {boolean} returnByValue
-   * @param {?Object} options
-   * @param {string} securityOrigin
-   * @param {function(?string, ?SDK.RemoteObject, boolean)} callback
-   * @return {!Extensions.ExtensionStatus.Record|undefined}
-   */
-  evaluate(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) {
-    let context;
-
-    /**
-     * @param {string} url
-     * @return {boolean}
-     */
-    function resolveURLToFrame(url) {
-      let found;
-      function hasMatchingURL(frame) {
-        found = (frame.url === url) ? frame : null;
-        return found;
-      }
-      SDK.ResourceTreeModel.frames().some(hasMatchingURL);
-      return found;
-    }
-
-    options = options || {};
-    let frame;
-    if (options.frameURL) {
-      frame = resolveURLToFrame(options.frameURL);
-    } else {
-      const target = SDK.targetManager.mainTarget();
-      const resourceTreeModel = target && target.model(SDK.ResourceTreeModel);
-      frame = resourceTreeModel && resourceTreeModel.mainFrame;
-    }
-    if (!frame) {
-      if (options.frameURL)
-        console.warn('evaluate: there is no frame with URL ' + options.frameURL);
-      else
-        console.warn('evaluate: the main frame is not yet available');
-      return this._status.E_NOTFOUND(options.frameURL || '<top>');
-    }
-
-    let contextSecurityOrigin;
-    if (options.useContentScriptContext)
-      contextSecurityOrigin = securityOrigin;
-    else if (options.scriptExecutionContext)
-      contextSecurityOrigin = options.scriptExecutionContext;
-
-    const runtimeModel = frame.resourceTreeModel().target().model(SDK.RuntimeModel);
-    const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
-    if (contextSecurityOrigin) {
-      for (let i = 0; i < executionContexts.length; ++i) {
-        const executionContext = executionContexts[i];
-        if (executionContext.frameId === frame.id && executionContext.origin === contextSecurityOrigin &&
-            !executionContext.isDefault)
-          context = executionContext;
-      }
-      if (!context) {
-        console.warn('The JavaScript context ' + contextSecurityOrigin + ' was not found in the frame ' + frame.url);
-        return this._status.E_NOTFOUND(contextSecurityOrigin);
-      }
-    } else {
-      for (let i = 0; i < executionContexts.length; ++i) {
-        const executionContext = executionContexts[i];
-        if (executionContext.frameId === frame.id && executionContext.isDefault)
-          context = executionContext;
-      }
-      if (!context)
-        return this._status.E_FAILED(frame.url + ' has no execution context');
-    }
-
-    context
-        .evaluate(
-            {
-              expression: expression,
-              objectGroup: 'extension',
-              includeCommandLineAPI: exposeCommandLineAPI,
-              silent: true,
-              returnByValue: returnByValue,
-              generatePreview: false
-            },
-            /* userGesture */ false, /* awaitPromise */ false)
-        .then(onEvaluate);
-
-    /**
-     * @param {!SDK.RuntimeModel.EvaluationResult} result
-     */
-    function onEvaluate(result) {
-      if (result.error) {
-        callback(result.error, null, false);
-        return;
-      }
-      callback(null, result.object || null, !!result.exceptionDetails);
-    }
-  }
-};
-
-/** @enum {symbol} */
-Extensions.ExtensionServer.Events = {
-  SidebarPaneAdded: Symbol('SidebarPaneAdded'),
-  TraceProviderAdded: Symbol('TraceProviderAdded')
-};
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionServerPanelView = class extends UI.SimpleView {
-  /**
-   * @param {string} name
-   * @param {string} title
-   * @param {!UI.Panel} panel
-   */
-  constructor(name, title, panel) {
-    super(title);
-    this._name = name;
-    this._panel = panel;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  viewId() {
-    return this._name;
-  }
-
-  /**
-   * @override
-   * @return {!Promise.<!UI.Widget>}
-   */
-  widget() {
-    return /** @type {!Promise.<!UI.Widget>} */ (Promise.resolve(this._panel));
-  }
-};
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionStatus = class {
-  constructor() {
-    /**
-     * @param {string} code
-     * @param {string} description
-     * @return {!Extensions.ExtensionStatus.Record}
-     */
-    function makeStatus(code, description) {
-      const details = Array.prototype.slice.call(arguments, 2);
-      const status = {code: code, description: description, details: details};
-      if (code !== 'OK') {
-        status.isError = true;
-        console.error('Extension server error: ' + String.vsprintf(description, details));
-      }
-      return status;
-    }
-
-    this.OK = makeStatus.bind(null, 'OK', 'OK');
-    this.E_EXISTS = makeStatus.bind(null, 'E_EXISTS', 'Object already exists: %s');
-    this.E_BADARG = makeStatus.bind(null, 'E_BADARG', 'Invalid argument %s: %s');
-    this.E_BADARGTYPE = makeStatus.bind(null, 'E_BADARGTYPE', 'Invalid type for argument %s: got %s, expected %s');
-    this.E_NOTFOUND = makeStatus.bind(null, 'E_NOTFOUND', 'Object not found: %s');
-    this.E_NOTSUPPORTED = makeStatus.bind(null, 'E_NOTSUPPORTED', 'Object does not support requested operation: %s');
-    this.E_PROTOCOLERROR = makeStatus.bind(null, 'E_PROTOCOLERROR', 'Inspector protocol error: %s');
-    this.E_FAILED = makeStatus.bind(null, 'E_FAILED', 'Operation failed: %s');
-  }
-};
-
-/**
- * @typedef {{code: string, description: string, details: !Array.<*>}}
- */
-Extensions.ExtensionStatus.Record;
-
-Extensions.extensionAPI = {};
-defineCommonExtensionSymbols(Extensions.extensionAPI);
-
-/** @type {!Extensions.ExtensionServer} */
-Extensions.extensionServer;
diff --git a/front_end/extensions/ExtensionTraceProvider.js b/front_end/extensions/ExtensionTraceProvider.js
deleted file mode 100644
index db77fa9..0000000
--- a/front_end/extensions/ExtensionTraceProvider.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionTraceProvider = class {
-  /**
-   * @param {string} extensionOrigin
-   * @param {string} id
-   * @param {string} categoryName
-   * @param {string} categoryTooltip
-   */
-  constructor(extensionOrigin, id, categoryName, categoryTooltip) {
-    this._extensionOrigin = extensionOrigin;
-    this._id = id;
-    this._categoryName = categoryName;
-    this._categoryTooltip = categoryTooltip;
-  }
-
-  /**
-   * @param {!Extensions.TracingSession} session
-   */
-  start(session) {
-    const sessionId = String(++Extensions.ExtensionTraceProvider._lastSessionId);
-    Extensions.extensionServer.startTraceRecording(this._id, sessionId, session);
-  }
-
-  stop() {
-    Extensions.extensionServer.stopTraceRecording(this._id);
-  }
-
-  /**
-   * @return {string}
-   */
-  shortDisplayName() {
-    return this._categoryName;
-  }
-
-  /**
-   * @return {string}
-   */
-  longDisplayName() {
-    return this._categoryTooltip;
-  }
-
-  /**
-   * @return {string}
-   */
-  persistentIdentifier() {
-    return `${this._extensionOrigin}/${this._categoryName}`;
-  }
-};
-
-Extensions.ExtensionTraceProvider._lastSessionId = 0;
-
-/**
- * @interface
- */
-Extensions.TracingSession = function() {};
-
-Extensions.TracingSession.prototype = {
-  /**
-   * @param {string} url
-   * @param {number} timeOffsetMicroseconds
-   */
-  complete: function(url, timeOffsetMicroseconds) {}
-};
diff --git a/front_end/extensions/ExtensionView.js b/front_end/extensions/ExtensionView.js
deleted file mode 100644
index 5ce50e1..0000000
--- a/front_end/extensions/ExtensionView.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionView = class extends UI.Widget {
-  /**
-   * @param {!Extensions.ExtensionServer} server
-   * @param {string} id
-   * @param {string} src
-   * @param {string} className
-   */
-  constructor(server, id, src, className) {
-    super();
-    this.setHideOnDetach();
-    this.element.className = 'vbox flex-auto';  // Override
-
-    this._server = server;
-    this._id = id;
-    this._iframe = createElement('iframe');
-    this._iframe.addEventListener('load', this._onLoad.bind(this), false);
-    this._iframe.src = src;
-    this._iframe.className = className;
-    this.setDefaultFocusedElement(this._iframe);
-
-    this.element.appendChild(this._iframe);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (typeof this._frameIndex === 'number')
-      this._server.notifyViewShown(this._id, this._frameIndex);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    if (typeof this._frameIndex === 'number')
-      this._server.notifyViewHidden(this._id);
-  }
-
-  _onLoad() {
-    const frames = /** @type {!Array.<!Window>} */ (window.frames);
-    this._frameIndex = Array.prototype.indexOf.call(frames, this._iframe.contentWindow);
-    if (this.isShowing())
-      this._server.notifyViewShown(this._id, this._frameIndex);
-  }
-};
-
-/**
- * @unrestricted
- */
-Extensions.ExtensionNotifierView = class extends UI.VBox {
-  /**
-   * @param {!Extensions.ExtensionServer} server
-   * @param {string} id
-   */
-  constructor(server, id) {
-    super();
-
-    this._server = server;
-    this._id = id;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._server.notifyViewShown(this._id);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._server.notifyViewHidden(this._id);
-  }
-};
diff --git a/front_end/extensions/module.json b/front_end/extensions/module.json
deleted file mode 100644
index 99337be..0000000
--- a/front_end/extensions/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "dependencies": [
-        "components",
-        "browser_sdk",
-        "common"
-    ],
-    "scripts": [
-        "ExtensionAPI.js",
-        "ExtensionRegistryStub.js",
-        "ExtensionTraceProvider.js",
-        "ExtensionServer.js",
-        "ExtensionPanel.js",
-        "ExtensionView.js"
-    ]
-}
diff --git a/front_end/extensions_test_runner/ExtensionsNetworkTestRunner.js b/front_end/extensions_test_runner/ExtensionsNetworkTestRunner.js
deleted file mode 100644
index 5b96920..0000000
--- a/front_end/extensions_test_runner/ExtensionsNetworkTestRunner.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-function extension_getRequestByUrl(urls, callback) {
-  function onHAR(response) {
-    const entries = response.entries;
-
-    for (let i = 0; i < entries.length; ++i) {
-      for (let url = 0; url < urls.length; ++url) {
-        if (urls[url].test(entries[i].request.url)) {
-          callback(entries[i]);
-          return;
-        }
-      }
-    }
-
-    output('no item found');
-    callback(null);
-  }
-
-  webInspector.network.getHAR(onHAR);
-}
diff --git a/front_end/extensions_test_runner/ExtensionsTestRunner.js b/front_end/extensions_test_runner/ExtensionsTestRunner.js
deleted file mode 100644
index 0daa82d..0000000
--- a/front_end/extensions_test_runner/ExtensionsTestRunner.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-const extensionsHost = 'devtools-extensions.oopif.test';
-const extensionsOrigin = `http://${extensionsHost}:8000`;
-Extensions.extensionServer._registerHandler('evaluateForTestInFrontEnd', onEvaluate);
-
-Extensions.extensionServer._extensionAPITestHook = function(extensionServerClient, coreAPI) {
-  window.webInspector = coreAPI;
-  window._extensionServerForTests = extensionServerClient;
-  coreAPI.panels.themeName = 'themeNameForTest';
-};
-
-ExtensionsTestRunner._replyToExtension = function(requestId, port) {
-  Extensions.extensionServer._dispatchCallback(requestId, port);
-};
-
-function onEvaluate(message, port) {
-  // Note: reply(...) is actually used in eval strings
-  // eslint-disable-next-line no-unused-vars
-  function reply(param) {
-    Extensions.extensionServer._dispatchCallback(message.requestId, port, param);
-  }
-
-  try {
-    eval(message.expression);
-  } catch (e) {
-    TestRunner.addResult('Exception while running: ' + message.expression + '\n' + (e.stack || e));
-    TestRunner.completeTest();
-  }
-}
-
-ExtensionsTestRunner.showPanel = function(panelId) {
-  if (panelId === 'extension')
-    panelId = UI.inspectorView._tabbedPane._tabs[UI.inspectorView._tabbedPane._tabs.length - 1].id;
-  return UI.inspectorView.showPanel(panelId);
-};
-
-ExtensionsTestRunner.evaluateInExtension = function(code) {
-  ExtensionsTestRunner._codeToEvaluateBeforeTests = code;
-};
-
-ExtensionsTestRunner.runExtensionTests = async function(tests) {
-  const result = await TestRunner.RuntimeAgent.evaluate('location.href', 'console', false);
-
-  if (!result)
-    return;
-
-  ExtensionsTestRunner._pendingTests = (ExtensionsTestRunner._codeToEvaluateBeforeTests || '') + tests.join('\n');
-  const pageURL = result.value;
-  let extensionURL = pageURL.replace(/^(https?:\/\/[^\/]*\/).*$/, '$1') + 'devtools/resources/extension-main.html';
-  extensionURL = extensionURL.replace('127.0.0.1', extensionsHost);
-
-  InspectorFrontendAPI.addExtensions(
-      [{startPage: extensionURL, name: 'test extension', exposeWebInspectorNamespace: true}]);
-
-  Extensions.extensionServer.initializeExtensions();
-};
-
-(function disableLogging() {
-  // Suppress console warnings from ExtensionServer.js
-  console.warn = () => undefined;
-})();
diff --git a/front_end/extensions_test_runner/module.json b/front_end/extensions_test_runner/module.json
deleted file mode 100644
index 36c6e48..0000000
--- a/front_end/extensions_test_runner/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "extensions"
-  ],
-  "scripts": [
-    "ExtensionsNetworkTestRunner.js",
-    "ExtensionsTestRunner.js"
-  ],
-  "skip_compilation": [
-    "ExtensionsNetworkTestRunner.js",
-    "ExtensionsTestRunner.js"
-  ]
-}
diff --git a/front_end/externs.js b/front_end/externs.js
deleted file mode 100644
index 54fe8f8..0000000
--- a/front_end/externs.js
+++ /dev/null
@@ -1,835 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// WebKit Web Facing API
-
-/**
- * @param {!Object} object
- * @param {!Function} callback
- */
-Object.observe = function(object, callback) {};
-
-/** @type {boolean} */
-Event.prototype.isMetaOrCtrlForTest;
-
-/** @type {string} */
-Event.prototype.code;
-
-/**
- * TODO(luoe): MouseEvent properties movementX and movementY from the
- * PointerLock API are not yet standard. Once they are included in
- * Closure Compiler, these custom externs can be removed.
- */
-/** @type {number} */
-MouseEvent.prototype.movementX;
-
-/** @type {number} */
-MouseEvent.prototype.movementY;
-
-/**
- * @type {number}
- */
-KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
-
-/**
- * @param {!T} value
- * @param {boolean=} onlyFirst
- * @this {Array.<T>}
- * @template T
- */
-Array.prototype.remove = function(value, onlyFirst) {};
-/**
- * @param {!Array.<!T>} array
- * @this {Array.<!T>}
- * @template T
- */
-Array.prototype.pushAll = function(array) {};
-/**
- * @return {!Object.<string, boolean>}
- * @this {Array.<T>}
- * @template T
- */
-Array.prototype.keySet = function() {};
-/**
- * @param {number} index
- * @return {!Array.<!T>}
- * @this {Array.<T>}
- * @template T
- */
-Array.prototype.rotate = function(index) {};
-/**
- * @this {Array.<number>}
- */
-Array.prototype.sortNumbers = function() {};
-/**
- * @param {!S} object
- * @param {function(!S,!T):number=} comparator
- * @param {number=} left
- * @param {number=} right
- * @return {number}
- * @this {Array.<T>}
- * @template S
- */
-Array.prototype.lowerBound = function(object, comparator, left, right) {};
-/**
- * @param {!S} object
- * @param {function(!S,!T):number=} comparator
- * @param {number=} left
- * @param {number=} right
- * @return {number}
- * @this {Array.<T>}
- * @template S
- */
-Array.prototype.upperBound = function(object, comparator, left, right) {};
-/**
- * @param {!S} value
- * @param {function(!S,!T):number} comparator
- * @return {number}
- * @this {Array.<T>}
- * @template S
- */
-Array.prototype.binaryIndexOf = function(value, comparator) {};
-/**
- * @param {function(number, number): number} comparator
- * @param {number} leftBound
- * @param {number} rightBound
- * @param {number} sortWindowLeft
- * @param {number} sortWindowRight
- * @return {!Array.<number>}
- * @this {Array.<number>}
- */
-Array.prototype.sortRange = function(comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight) {};
-
-/**
- * @param {function(!T,!T): number=} comparator
- * @return {!Array.<T>}
- * @this {Array.<T>}
- * @template T
- */
-Array.prototype.stableSort = function(comparator) {};
-
-/**
- * @this {Array.<number>}
- * @param {function(number,number):boolean} comparator
- * @param {number} left
- * @param {number} right
- * @param {number} pivotIndex
- * @return {number}
- */
-Array.prototype.partition = function(comparator, left, right, pivotIndex) {};
-
-/**
- * @this {Array.<number>}
- * @param {number} k
- * @param {function(number,number):boolean=} comparator
- * @return {number}
- */
-Array.prototype.qselect = function(k, comparator) {};
-
-/**
- * @param {string} field
- * @return {!Array.<!T>}
- * @this {Array.<!Object.<string,T>>}
- * @template T
- */
-Array.prototype.select = function(field) {};
-
-/**
- * @return {!T|undefined}
- * @this {Array.<T>}
- * @template T
- */
-Array.prototype.peekLast = function() {};
-
-/**
- * @param {!Array.<T>} array
- * @param {function(T,T):number} comparator
- * @return {!Array.<T>}
- * @this {!Array.<T>}
- * @template T
- */
-Array.prototype.intersectOrdered = function(array, comparator) {};
-
-/**
- * @param {!Array.<T>} array
- * @param {function(T,T):number} comparator
- * @return {!Array.<T>}
- * @this {!Array.<T>}
- * @template T
- */
-Array.prototype.mergeOrdered = function(array, comparator) {};
-
-/**
- * @param {number} object
- * @param {function(number, number):number=} comparator
- * @param {number=} left
- * @param {number=} right
- * @return {number}
- */
-Int32Array.prototype.lowerBound = function(object, comparator, left, right) {};
-
-// TODO(luoe): remove these BigInt types once closure supports them.
-/**
- * @param {number|string} value
- */
-const BigInt = function(value) {};
-
-/** @typedef {*} */
-const bigint = null;
-
-// File System API
-/**
- * @constructor
- */
-function DOMFileSystem() {
-}
-
-/**
- * @type {DirectoryEntry}
- */
-DOMFileSystem.prototype.root = null;
-
-/**
- * @type {*}
- */
-window.domAutomationController;
-
-const DevToolsHost = function() {};
-
-/** @typedef {{type:string, id:(number|undefined),
-              label:(string|undefined), enabled:(boolean|undefined), checked:(boolean|undefined),
-              subItems:(!Array.<!DevToolsHost.ContextMenuDescriptor>|undefined)}} */
-DevToolsHost.ContextMenuDescriptor;
-
-/**
- * @return {number}
- */
-DevToolsHost.zoomFactor = function() {};
-
-/**
- * @param {string} text
- */
-DevToolsHost.copyText = function(text) {};
-
-/**
- * @return {string}
- */
-DevToolsHost.platform = function() {};
-
-/**
- * @param {number} x
- * @param {number} y
- * @param {!Array.<!DevToolsHost.ContextMenuDescriptor>} items
- * @param {!Document} document
- */
-DevToolsHost.showContextMenuAtPoint = function(x, y, items, document) {};
-
-/**
- * @param {string} message
- */
-DevToolsHost.sendMessageToEmbedder = function(message) {};
-
-/**
- * @return {string}
- */
-DevToolsHost.getSelectionBackgroundColor = function() {};
-
-/**
- * @return {string}
- */
-DevToolsHost.getSelectionForegroundColor = function() {};
-
-/**
- * @return {string}
- */
-DevToolsHost.getInactiveSelectionBackgroundColor = function() {};
-
-/**
- * @return {string}
- */
-DevToolsHost.getInactiveSelectionForegroundColor = function() {};
-
-/**
- * @return {boolean}
- */
-DevToolsHost.isHostedMode = function() {};
-
-/**
- * @param {string} fileSystemId
- * @param {string} registeredName
- * @return {?DOMFileSystem}
- */
-DevToolsHost.isolatedFileSystem = function(fileSystemId, registeredName) {};
-
-/**
- * @param {!FileSystem} fileSystem
- */
-DevToolsHost.upgradeDraggedFileSystemPermissions = function(fileSystem) {};
-
-/** Extensions API */
-
-/** @constructor */
-function EventSink() {
-}
-/** @constructor */
-function ExtensionSidebarPane() {
-}
-/** @constructor */
-function Panel() {
-}
-/** @constructor */
-function PanelWithSidebar() {
-}
-/** @constructor */
-function Resource() {
-}
-
-let extensionServer;
-
-/**
- * @constructor
- */
-function ExtensionDescriptor() {
-  this.startPage = '';
-  this.name = '';
-  this.exposeExperimentalAPIs = false;
-}
-
-/**
- * @constructor
- */
-function ExtensionReloadOptions() {
-  this.ignoreCache = false;
-  this.injectedScript = '';
-  this.userAgent = '';
-}
-
-const Adb = {};
-/** @typedef {{id: string, name: string, url: string, attached: boolean}} */
-Adb.Page;
-/** @typedef {{id: string, adbBrowserChromeVersion: string, compatibleVersion: boolean, adbBrowserName: string, source: string, adbBrowserVersion: string, pages: !Array<!Adb.Page>}} */
-Adb.Browser;
-/** @typedef {{id: string, adbModel: string, adbSerial: string, browsers: !Array.<!Adb.Browser>, adbPortStatus: !Array.<number>, adbConnected: boolean}} */
-Adb.Device;
-/** @typedef {!Object.<string, string>} */
-Adb.PortForwardingConfig;
-/** @typedef {!{port: string, address: string}} */
-Adb.PortForwardingRule;
-/** @typedef {{ports: !Object<string, number>, browserId: string}} */
-Adb.DevicePortForwardingStatus;
-/** @typedef {!Object<string, !Adb.DevicePortForwardingStatus>} */
-Adb.PortForwardingStatus;
-/** @typedef {!Array<string>} */
-Adb.NetworkDiscoveryConfig;
-/**
- * @typedef {!{
- *   discoverUsbDevices: boolean,
- *   portForwardingEnabled: boolean,
- *   portForwardingConfig: !Adb.PortForwardingConfig,
- *   networkDiscoveryEnabled: boolean,
- *   networkDiscoveryConfig: !Adb.NetworkDiscoveryConfig
- * }}
- */
-Adb.Config;
-
-/** @const */
-const module = {};
-
-/**
- * @constructor
- */
-function diff_match_patch() {
-}
-
-diff_match_patch.prototype = {
-  /**
-   * @param {string} text1
-   * @param {string} text2
-   * @return {!Array.<!{0: number, 1: string}>}
-   */
-  diff_main: function(text1, text2) {},
-
-  /**
-   * @param {!Array.<!{0: number, 1: string}>} diff
-   */
-  diff_cleanupSemantic(diff) {}
-};
-
-/** @constructor */
-const Doc = function() {};
-Doc.prototype = {
-  /** @type {number} */
-  scrollLeft: 0,
-  /** @type {number} */
-  scrollTop: 0
-};
-
-/** @constructor */
-const CodeMirror = function(element, config) {};
-CodeMirror.on = function(obj, type, handler) {};
-CodeMirror.prototype = {
-  /** @type {!Doc} */
-  doc: null,
-  addKeyMap: function(map) {},
-  addLineClass: function(handle, where, cls) {},
-  /**
-   * @param {?Object=} options
-   * @return {!CodeMirror.LineWidget}
-   */
-  addLineWidget: function(handle, node, options) {},
-  /**
-   * @param {string|!Object} spec
-   * @param {!Object=} options
-   */
-  addOverlay: function(spec, options) {},
-  addWidget: function(pos, node, scroll, vert, horiz) {},
-  charCoords: function(pos, mode) {},
-  clearGutter: function(gutterID) {},
-  clearHistory: function() {},
-  clipPos: function(pos) {},
-  /** @param {string=} mode */
-  coordsChar: function(coords, mode) {},
-  /** @param {string=} mode */
-  cursorCoords: function(start, mode) {},
-  defaultCharWidth: function() {},
-  defaultTextHeight: function() {},
-  deleteH: function(dir, unit) {},
-  /**
-   * @param {*=} to
-   * @param {*=} op
-   */
-  eachLine: function(from, to, op) {},
-  execCommand: function(cmd) {},
-  extendSelection: function(from, to) {},
-  findMarks: function(from, to) {},
-  findMarksAt: function(pos) {},
-  /**
-   * @param {!CodeMirror.Pos} from
-   * @param {boolean=} strict
-   * @param {Object=} config
-   */
-  findMatchingBracket: function(from, strict, config) {},
-  findPosH: function(from, amount, unit, visually) {},
-  findPosV: function(from, amount, unit, goalColumn) {},
-  firstLine: function() {},
-  focus: function() {},
-  getAllMarks: function() {},
-  /** @param {string=} start */
-  getCursor: function(start) {},
-  getDoc: function() {},
-  getGutterElement: function() {},
-  getHistory: function() {},
-  getInputField: function() {},
-  getLine: function(line) {},
-  /**
-   * @return {!{wrapClass: string, height: number}}
-   */
-  getLineHandle: function(line) {},
-  getLineNumber: function(line) {},
-  /**
-   * @return {!{token: function(CodeMirror.StringStream, Object):string}}
-   */
-  getMode: function() {},
-  getOption: function(option) {},
-  /** @param {*=} lineSep */
-  getRange: function(from, to, lineSep) {},
-  /**
-   * @return {!{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}}
-   */
-  getScrollInfo: function() {},
-  getScrollerElement: function() {},
-  getSelection: function() {},
-  getSelections: function() {},
-  getStateAfter: function(line) {},
-  getTokenAt: function(pos) {},
-  /** @param {*=} lineSep */
-  getValue: function(lineSep) {},
-  getViewport: function() {},
-  getWrapperElement: function() {},
-  hasFocus: function() {},
-  historySize: function() {},
-  indentLine: function(n, dir, aggressive) {},
-  indentSelection: function(how) {},
-  indexFromPos: function(coords) {},
-  isClean: function() {},
-  iterLinkedDocs: function(f) {},
-  lastLine: function() {},
-  lineCount: function() {},
-  lineInfo: function(line) {},
-  /**
-   * @param {number} height
-   * @param {string=} mode
-   */
-  lineAtHeight: function(height, mode) {},
-  linkedDoc: function(options) {},
-  listSelections: function() {},
-  markClean: function() {},
-  markText: function(from, to, options) {},
-  moveH: function(dir, unit) {},
-  moveV: function(dir, unit) {},
-  off: function(type, f) {},
-  on: function(type, f) {},
-  operation: function(f) {},
-  posFromIndex: function(off) {},
-  redo: function() {},
-  refresh: function() {},
-  removeKeyMap: function(map) {},
-  removeLine: function(line) {},
-  removeLineClass: function(handle, where, cls) {},
-  removeLineWidget: function(widget) {},
-  removeOverlay: function(spec) {},
-  /** @param {*=} origin */
-  replaceRange: function(code, from, to, origin) {},
-  /**
-   * @param {string} replacement
-   * @param {string=} select
-   */
-  replaceSelection: function(replacement, select) {},
-  /**
-   * @param {!Array.<string>} textPerSelection
-   */
-  replaceSelections: function(textPerSelection) {},
-  /** @param {*=} margin */
-  scrollIntoView: function(pos, margin) {},
-  scrollTo: function(x, y) {},
-  setBookmark: function(pos, options) {},
-  setCursor: function(line, ch, extend) {},
-  setExtending: function(val) {},
-  setGutterMarker: function(line, gutterID, value) {},
-  setHistory: function(histData) {},
-  setLine: function(line, text) {},
-  setOption: function(option, value) {},
-  setSelection: function(anchor, head) {},
-  /**
-   * @param {number=} primaryIndex
-   * @param {?Object=} config
-   */
-  setSelections: function(selections, primaryIndex, config) {},
-  setSize: function(width, height) {},
-  setValue: function(code) {},
-  somethingSelected: function() {},
-  swapDoc: function(doc) {},
-  undo: function() {},
-  unlinkDoc: function(other) {}
-};
-/** @type {!{cursorDiv: Element, lineSpace: Element}} */
-CodeMirror.prototype.display;
-/** @type {!{mode: string}} */
-CodeMirror.prototype.options;
-/** @type {!Object} */
-CodeMirror.Pass;
-CodeMirror.showHint = function(codeMirror, hintintFunction) {};
-CodeMirror.commands = {};
-CodeMirror.modes = {};
-CodeMirror.mimeModes = {};
-CodeMirror.getMode = function(options, spec) {};
-CodeMirror.overlayMode = function(mode1, mode2, squashSpans) {};
-CodeMirror.defineMode = function(modeName, modeConstructor) {};
-CodeMirror.startState = function(mode) {};
-CodeMirror.copyState = function(mode, state) {};
-
-/** @typedef {{canceled: boolean, from: !CodeMirror.Pos, to: !CodeMirror.Pos, text: string, origin: string, cancel: function()}} */
-CodeMirror.BeforeChangeObject;
-
-/** @typedef {{from: !CodeMirror.Pos, to: !CodeMirror.Pos, origin: string, text: !Array.<string>, removed: !Array.<string>}} */
-CodeMirror.ChangeObject;
-
-/** @constructor */
-CodeMirror.Pos = function(line, ch) {};
-/** @type {number} */
-CodeMirror.Pos.prototype.line;
-/** @type {number} */
-CodeMirror.Pos.prototype.ch;
-
-/**
- * @param {!CodeMirror.Pos} pos1
- * @param {!CodeMirror.Pos} pos2
- * @return {number}
- */
-CodeMirror.cmpPos = function(pos1, pos2) {};
-
-/** @constructor */
-CodeMirror.StringStream = function(line) {
-  this.pos = 0;
-  this.start = 0;
-};
-CodeMirror.StringStream.prototype = {
-  backUp: function(n) {},
-  column: function() {},
-  current: function() {},
-  eat: function(match) {},
-  eatSpace: function() {},
-  eatWhile: function(match) {},
-  eol: function() {},
-  indentation: function() {},
-  /**
-   * @param {!RegExp|string} pattern
-   * @param {boolean=} consume
-   * @param {boolean=} caseInsensitive
-   */
-  match: function(pattern, consume, caseInsensitive) {},
-  next: function() {},
-  peek: function() {},
-  skipTo: function(ch) {},
-  skipToEnd: function() {},
-  sol: function() {}
-};
-
-/** @constructor */
-CodeMirror.TextMarker = function(doc, type) {};
-CodeMirror.TextMarker.prototype = {
-  clear: function() {},
-  find: function() {},
-  changed: function() {}
-};
-
-/** @constructor */
-CodeMirror.LineWidget = function() {};
-CodeMirror.LineWidget.prototype = {
-  clear: function() {}
-};
-
-/** @type {Object.<string, !Object.<string, string>>} */
-CodeMirror.keyMap;
-
-/** @type {{scrollLeft: number, scrollTop: number}} */
-CodeMirror.doc;
-
-/**
- * @param {string} mime
- * @param {string} mode
- */
-CodeMirror.defineMIME = function(mime, mode) {};
-
-/** @type {boolean} */
-window.dispatchStandaloneTestRunnerMessages;
-
-/**
- * @param {Array.<Object>} keyframes
- * @param {number|Object} timing
- * @return {Object}
- */
-Element.prototype.animate = function(keyframes, timing) {};
-
-/**
- * @param {...!Node} nodes
- * @return {undefined}
- * @see https://dom.spec.whatwg.org/#dom-parentnode-prepend
- */
-Element.prototype.prepend = function(nodes) {};
-
-/**
- * @override
- * @param {string} type
- * @param {(!EventListener|!function (!Event): (boolean|undefined)|null)} listener
- * @param {(boolean|!{capture: (boolean|undefined), once: (boolean|undefined), passive: (boolean|undefined)})=} options
- * @this {EventTarget}
- */
-Element.prototype.addEventListener = function(type, listener, options) {};
-
-/**
- * @override
- * @param {string} type
- * @param {(!EventListener|!function (!Event): (boolean|undefined)|null)} listener
- * @param {(boolean|!{capture: (boolean|undefined), once: (boolean|undefined), passive: (boolean|undefined)})=} options
- * @this {EventTarget}
- */
-Element.prototype.removeEventListener = function(type, listener, options) {};
-
-const acorn = {
-  /**
-   * @param {string} text
-   * @param {Object.<string, boolean>} options
-   * @return {!ESTree.Node}
-   */
-  parse: function(text, options) {},
-
-  /**
-   * @param {string} text
-   * @param {Object.<string, boolean>} options
-   * @return {!ESTree.Node}
-   */
-  parse_dammit: function(text, options) {},
-
-  /**
-   * @param {string} text
-   * @param {Object.<string, boolean>} options
-   * @return {!Acorn.Tokenizer}
-   */
-  tokenizer: function(text, options) {},
-
-  tokTypes: {
-    _true: new Acorn.TokenType(),
-    _false: new Acorn.TokenType(),
-    _null: new Acorn.TokenType(),
-    num: new Acorn.TokenType(),
-    regexp: new Acorn.TokenType(),
-    string: new Acorn.TokenType(),
-    name: new Acorn.TokenType(),
-    eof: new Acorn.TokenType()
-  }
-};
-
-const Acorn = {};
-/**
- * @constructor
- */
-Acorn.Tokenizer = function() {
-  /** @type {function():!Acorn.Token} */
-  this.getToken;
-};
-
-/**
- * @constructor
- */
-Acorn.TokenType = function() {
-  /** @type {string} */
-  this.label;
-  /** @type {(string|undefined)} */
-  this.keyword;
-};
-
-/**
- * @typedef {{type: !Acorn.TokenType, value: string, start: number, end: number}}
- */
-Acorn.Token;
-
-/**
- * @typedef {{type: string, value: string, start: number, end: number}}
- */
-Acorn.Comment;
-
-/**
- * @typedef {(!Acorn.Token|!Acorn.Comment)}
- */
-Acorn.TokenOrComment;
-
-const ESTree = {};
-
-/**
- * @constructor
- */
-ESTree.Node = function() {
-  /** @type {number} */
-  this.start;
-  /** @type {number} */
-  this.end;
-  /** @type {string} */
-  this.type;
-  /** @type {(!ESTree.Node|undefined)} */
-  this.body;
-  /** @type {(!Array.<!ESTree.Node>|undefined)} */
-  this.declarations;
-  /** @type {(!Array.<!ESTree.Node>|undefined)} */
-  this.properties;
-  /** @type {(!ESTree.Node|undefined)} */
-  this.init;
-  /** @type {(!Array.<!ESTree.Node>|undefined)} */
-  this.params;
-  /** @type {(string|undefined)} */
-  this.name;
-  /** @type {(?ESTree.Node|undefined)} */
-  this.id;
-  /** @type {(number|undefined)} */
-  this.length;
-  /** @type {(?ESTree.Node|undefined)} */
-  this.argument;
-  /** @type {(string|undefined)} */
-  this.operator;
-  /** @type {(!ESTree.Node|undefined)} */
-  this.right;
-  /** @type {(!ESTree.Node|undefined)} */
-  this.left;
-  /** @type {(string|undefined)} */
-  this.kind;
-  /** @type {(!ESTree.Node|undefined)} */
-  this.property;
-  /** @type {(!ESTree.Node|undefined)} */
-  this.object;
-  /** @type {(string|undefined)} */
-  this.raw;
-  /** @type {(boolean|undefined)} */
-  this.computed;
-};
-
-/**
- * @extends {ESTree.Node}
- * @constructor
- */
-ESTree.TemplateLiteralNode = function() {
-  /** @type {!Array.<!ESTree.Node>} */
-  this.quasis;
-  /** @type {!Array.<!ESTree.Node>} */
-  this.expressions;
-};
-
-/**
- * @type {string}
- * @see http://heycam.github.io/webidl/#es-DOMException-prototype-object
- * TODO(jsbell): DOMException should be a subclass of Error.
- */
-DOMException.prototype.message;
-/** @type {number} */
-DOMException.ABORT_ERR;
-
-/**
- * @constructor
- * @param {!Object} params
- */
-const Terminal = function(params) {};
-
-Terminal.prototype = {
-  fit: function() {},
-  linkify: function() {},
-  /** @param {!Element} element */
-  open: function(element) {},
-  /** @param {string} eventName * @param {!Function} handler */
-  on: function(eventName, handler) {}
-};
-
-/**
- * @param {string} context
- * @return {!Console}
- */
-Console.prototype.context = function(context) {};
-
-
-/**
- * @param {!Array<string>|string} strings
- * @param {...*} vararg
- * @return {string}
- */
-const ls = function(strings, vararg) {};
-
-/**
- * @constructor
- * @param {function(!Array<*>)} callback
- */
-const ResizeObserver = function(callback) {};
diff --git a/front_end/formatter/FormatterWorkerPool.js b/front_end/formatter/FormatterWorkerPool.js
deleted file mode 100644
index c63d32f..0000000
--- a/front_end/formatter/FormatterWorkerPool.js
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Formatter.FormatterWorkerPool = class {
-  constructor() {
-    this._taskQueue = [];
-    /** @type {!Map<!Common.Worker, ?Formatter.FormatterWorkerPool.Task>} */
-    this._workerTasks = new Map();
-  }
-
-  /**
-   * @return {!Common.Worker}
-   */
-  _createWorker() {
-    const worker = new Common.Worker('formatter_worker');
-    worker.onmessage = this._onWorkerMessage.bind(this, worker);
-    worker.onerror = this._onWorkerError.bind(this, worker);
-    return worker;
-  }
-
-  _processNextTask() {
-    if (!this._taskQueue.length)
-      return;
-
-    let freeWorker = this._workerTasks.keysArray().find(worker => !this._workerTasks.get(worker));
-    if (!freeWorker && this._workerTasks.size < Formatter.FormatterWorkerPool.MaxWorkers)
-      freeWorker = this._createWorker();
-    if (!freeWorker)
-      return;
-
-    const task = this._taskQueue.shift();
-    this._workerTasks.set(freeWorker, task);
-    freeWorker.postMessage({method: task.method, params: task.params});
-  }
-
-  /**
-   * @param {!Common.Worker} worker
-   * @param {!MessageEvent} event
-   */
-  _onWorkerMessage(worker, event) {
-    const task = this._workerTasks.get(worker);
-    if (task.isChunked && event.data && !event.data['isLastChunk']) {
-      task.callback(event.data);
-      return;
-    }
-
-    this._workerTasks.set(worker, null);
-    this._processNextTask();
-    task.callback(event.data ? event.data : null);
-  }
-
-  /**
-   * @param {!Common.Worker} worker
-   * @param {!Event} event
-   */
-  _onWorkerError(worker, event) {
-    console.error(event);
-    const task = this._workerTasks.get(worker);
-    worker.terminate();
-    this._workerTasks.delete(worker);
-
-    const newWorker = this._createWorker();
-    this._workerTasks.set(newWorker, null);
-    this._processNextTask();
-    task.callback(null);
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {!Object<string, string>} params
-   * @param {function(boolean, *)} callback
-   */
-  _runChunkedTask(methodName, params, callback) {
-    const task = new Formatter.FormatterWorkerPool.Task(methodName, params, onData, true);
-    this._taskQueue.push(task);
-    this._processNextTask();
-
-    /**
-     * @param {?Object} data
-     */
-    function onData(data) {
-      if (!data) {
-        callback(true, null);
-        return;
-      }
-      const isLastChunk = !!data['isLastChunk'];
-      const chunk = data['chunk'];
-      callback(isLastChunk, chunk);
-    }
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {!Object<string, string>} params
-   * @return {!Promise<*>}
-   */
-  _runTask(methodName, params) {
-    let callback;
-    const promise = new Promise(fulfill => callback = fulfill);
-    const task = new Formatter.FormatterWorkerPool.Task(methodName, params, callback, false);
-    this._taskQueue.push(task);
-    this._processNextTask();
-    return promise;
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Promise<*>}
-   */
-  parseJSONRelaxed(content) {
-    return this._runTask('parseJSONRelaxed', {content: content});
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Promise<!Array<!Formatter.FormatterWorkerPool.SCSSRule>>}
-   */
-  parseSCSS(content) {
-    return this._runTask('parseSCSS', {content: content}).then(rules => rules || []);
-  }
-
-  /**
-   * @param {string} mimeType
-   * @param {string} content
-   * @param {string} indentString
-   * @return {!Promise<!Formatter.FormatterWorkerPool.FormatResult>}
-   */
-  format(mimeType, content, indentString) {
-    const parameters = {mimeType: mimeType, content: content, indentString: indentString};
-    return /** @type {!Promise<!Formatter.FormatterWorkerPool.FormatResult>} */ (this._runTask('format', parameters));
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Promise<!Array<!{name: string, offset: number}>>}
-   */
-  javaScriptIdentifiers(content) {
-    return this._runTask('javaScriptIdentifiers', {content: content}).then(ids => ids || []);
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Promise<string>}
-   */
-  evaluatableJavaScriptSubstring(content) {
-    return this._runTask('evaluatableJavaScriptSubstring', {content: content}).then(text => text || '');
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Promise<string>}
-   */
-  preprocessTopLevelAwaitExpressions(content) {
-    return this._runTask('preprocessTopLevelAwaitExpressions', {content: content}).then(text => text || '');
-  }
-
-  /**
-   * @param {string} content
-   * @param {function(boolean, !Array<!Formatter.FormatterWorkerPool.CSSRule>)} callback
-   */
-  parseCSS(content, callback) {
-    this._runChunkedTask('parseCSS', {content: content}, onDataChunk);
-
-    /**
-     * @param {boolean} isLastChunk
-     * @param {*} data
-     */
-    function onDataChunk(isLastChunk, data) {
-      const rules = /** @type {!Array<!Formatter.FormatterWorkerPool.CSSRule>} */ (data || []);
-      callback(isLastChunk, rules);
-    }
-  }
-
-  /**
-   * @param {string} content
-   * @param {function(boolean, !Array<!Formatter.FormatterWorkerPool.JSOutlineItem>)} callback
-   */
-  javaScriptOutline(content, callback) {
-    this._runChunkedTask('javaScriptOutline', {content: content}, onDataChunk);
-
-    /**
-     * @param {boolean} isLastChunk
-     * @param {*} data
-     */
-    function onDataChunk(isLastChunk, data) {
-      const items = /** @type {!Array.<!Formatter.FormatterWorkerPool.JSOutlineItem>} */ (data || []);
-      callback(isLastChunk, items);
-    }
-  }
-
-  /**
-   * @param {string} content
-   * @param {string} mimeType
-   * @param {function(boolean, !Array<!Formatter.FormatterWorkerPool.OutlineItem>)} callback
-   * @return {boolean}
-   */
-  outlineForMimetype(content, mimeType, callback) {
-    switch (mimeType) {
-      case 'text/html':
-      case 'text/javascript':
-        this.javaScriptOutline(content, javaScriptCallback);
-        return true;
-      case 'text/css':
-        this.parseCSS(content, cssCallback);
-        return true;
-    }
-    return false;
-
-    /**
-     * @param {boolean} isLastChunk
-     * @param {!Array<!Formatter.FormatterWorkerPool.JSOutlineItem>} items
-     */
-    function javaScriptCallback(isLastChunk, items) {
-      callback(
-          isLastChunk,
-          items.map(item => ({line: item.line, column: item.column, title: item.name, subtitle: item.arguments})));
-    }
-
-    /**
-     * @param {boolean} isLastChunk
-     * @param {!Array<!Formatter.FormatterWorkerPool.CSSRule>} rules
-     */
-    function cssCallback(isLastChunk, rules) {
-      callback(
-          isLastChunk,
-          rules.map(
-              rule => ({line: rule.lineNumber, column: rule.columnNumber, title: rule.selectorText || rule.atRule})));
-    }
-  }
-};
-
-Formatter.FormatterWorkerPool.MaxWorkers = 2;
-
-/**
- * @unrestricted
- */
-Formatter.FormatterWorkerPool.Task = class {
-  /**
-   * @param {string} method
-   * @param {!Object<string, string>} params
-   * @param {function(?MessageEvent)} callback
-   * @param {boolean=} isChunked
-   */
-  constructor(method, params, callback, isChunked) {
-    this.method = method;
-    this.params = params;
-    this.callback = callback;
-    this.isChunked = isChunked;
-  }
-};
-
-Formatter.FormatterWorkerPool.FormatResult = class {
-  constructor() {
-    /** @type {string} */
-    this.content;
-    /** @type {!Formatter.FormatterWorkerPool.FormatMapping} */
-    this.mapping;
-  }
-};
-
-/** @typedef {{original: !Array<number>, formatted: !Array<number>}} */
-Formatter.FormatterWorkerPool.FormatMapping;
-
-/** @typedef {{line: number, column: number, title: string, subtitle: (string|undefined) }} */
-Formatter.FormatterWorkerPool.OutlineItem;
-
-Formatter.FormatterWorkerPool.JSOutlineItem = class {
-  constructor() {
-    /** @type {string} */
-    this.name;
-    /** @type {(string|undefined)} */
-    this.arguments;
-    /** @type {number} */
-    this.line;
-    /** @type {number} */
-    this.column;
-  }
-};
-
-/**
- * @typedef {{startLine: number, startColumn: number, endLine: number, endColumn: number}}
- */
-Formatter.FormatterWorkerPool.TextRange;
-
-Formatter.FormatterWorkerPool.CSSProperty = class {
-  constructor() {
-    /** @type {string} */
-    this.name;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.nameRange;
-    /** @type {string} */
-    this.value;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.valueRange;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.range;
-    /** @type {(boolean|undefined)} */
-    this.disabled;
-  }
-};
-
-Formatter.FormatterWorkerPool.CSSStyleRule = class {
-  constructor() {
-    /** @type {string} */
-    this.selectorText;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.styleRange;
-    /** @type {number} */
-    this.lineNumber;
-    /** @type {number} */
-    this.columnNumber;
-    /** @type {!Array.<!Formatter.FormatterWorkerPool.CSSProperty>} */
-    this.properties;
-  }
-};
-
-/**
- * @typedef {{atRule: string, lineNumber: number, columnNumber: number}}
- */
-Formatter.FormatterWorkerPool.CSSAtRule;
-
-/**
- * @typedef {(Formatter.FormatterWorkerPool.CSSStyleRule|Formatter.FormatterWorkerPool.CSSAtRule)}
- */
-Formatter.FormatterWorkerPool.CSSRule;
-
-Formatter.FormatterWorkerPool.SCSSProperty = class {
-  constructor() {
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.range;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.name;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.value;
-    /** @type {boolean} */
-    this.disabled;
-  }
-};
-
-Formatter.FormatterWorkerPool.SCSSRule = class {
-  constructor() {
-    /** @type {!Array<!Formatter.FormatterWorkerPool.TextRange>} */
-    this.selectors;
-    /** @type {!Array<!Formatter.FormatterWorkerPool.SCSSProperty>} */
-    this.properties;
-    /** @type {!Formatter.FormatterWorkerPool.TextRange} */
-    this.styleRange;
-  }
-};
-
-/**
- * @return {!Formatter.FormatterWorkerPool}
- */
-Formatter.formatterWorkerPool = function() {
-  if (!Formatter._formatterWorkerPool)
-    Formatter._formatterWorkerPool = new Formatter.FormatterWorkerPool();
-  return Formatter._formatterWorkerPool;
-};
diff --git a/front_end/formatter/ScriptFormatter.js b/front_end/formatter/ScriptFormatter.js
deleted file mode 100644
index 1062785..0000000
--- a/front_end/formatter/ScriptFormatter.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-Formatter.Formatter = function() {};
-
-/**
- * @param {!Common.ResourceType} contentType
- * @param {string} mimeType
- * @param {string} content
- * @param {function(string, !Formatter.FormatterSourceMapping)} callback
- */
-Formatter.Formatter.format = function(contentType, mimeType, content, callback) {
-  if (contentType.isDocumentOrScriptOrStyleSheet())
-    new Formatter.ScriptFormatter(mimeType, content, callback);
-  else
-    new Formatter.ScriptIdentityFormatter(mimeType, content, callback);
-};
-
-/**
- * @param {!Array<number>} lineEndings
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @return {number}
- */
-Formatter.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber) {
-  const position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0;
-  return position + columnNumber;
-};
-
-/**
- * @param {!Array<number>} lineEndings
- * @param {number} position
- * @return {!Array<number>}
- */
-Formatter.Formatter.positionToLocation = function(lineEndings, position) {
-  const lineNumber = lineEndings.upperBound(position - 1);
-  let columnNumber;
-  if (!lineNumber)
-    columnNumber = position;
-  else
-    columnNumber = position - lineEndings[lineNumber - 1] - 1;
-  return [lineNumber, columnNumber];
-};
-
-/**
- * @implements {Formatter.Formatter}
- * @unrestricted
- */
-Formatter.ScriptFormatter = class {
-  /**
-   * @param {string} mimeType
-   * @param {string} content
-   * @param {function(string, !Formatter.FormatterSourceMapping)} callback
-   */
-  constructor(mimeType, content, callback) {
-    content = content.replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '');
-    this._callback = callback;
-    this._originalContent = content;
-
-    Formatter.formatterWorkerPool()
-        .format(mimeType, content, Common.moduleSetting('textEditorIndent').get())
-        .then(this._didFormatContent.bind(this));
-  }
-
-  /**
-   * @param {!Formatter.FormatterWorkerPool.FormatResult} formatResult
-   */
-  _didFormatContent(formatResult) {
-    const sourceMapping = new Formatter.FormatterSourceMappingImpl(
-        this._originalContent.computeLineEndings(), formatResult.content.computeLineEndings(), formatResult.mapping);
-    this._callback(formatResult.content, sourceMapping);
-  }
-};
-
-/**
- * @implements {Formatter.Formatter}
- * @unrestricted
- */
-Formatter.ScriptIdentityFormatter = class {
-  /**
-   * @param {string} mimeType
-   * @param {string} content
-   * @param {function(string, !Formatter.FormatterSourceMapping)} callback
-   */
-  constructor(mimeType, content, callback) {
-    callback(content, new Formatter.IdentityFormatterSourceMapping());
-  }
-};
-
-/**
- * @interface
- */
-Formatter.FormatterSourceMapping = function() {};
-
-Formatter.FormatterSourceMapping.prototype = {
-  /**
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Array.<number>}
-   */
-  originalToFormatted(lineNumber, columnNumber) {},
-
-  /**
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Array.<number>}
-   */
-  formattedToOriginal(lineNumber, columnNumber) {}
-};
-
-/**
- * @implements {Formatter.FormatterSourceMapping}
- * @unrestricted
- */
-Formatter.IdentityFormatterSourceMapping = class {
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Array.<number>}
-   */
-  originalToFormatted(lineNumber, columnNumber) {
-    return [lineNumber, columnNumber || 0];
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Array.<number>}
-   */
-  formattedToOriginal(lineNumber, columnNumber) {
-    return [lineNumber, columnNumber || 0];
-  }
-};
-
-/**
- * @implements {Formatter.FormatterSourceMapping}
- * @unrestricted
- */
-Formatter.FormatterSourceMappingImpl = class {
-  /**
-   * @param {!Array.<number>} originalLineEndings
-   * @param {!Array.<number>} formattedLineEndings
-   * @param {!Formatter.FormatterWorkerPool.FormatMapping} mapping
-   */
-  constructor(originalLineEndings, formattedLineEndings, mapping) {
-    this._originalLineEndings = originalLineEndings;
-    this._formattedLineEndings = formattedLineEndings;
-    this._mapping = mapping;
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Array.<number>}
-   */
-  originalToFormatted(lineNumber, columnNumber) {
-    const originalPosition =
-        Formatter.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0);
-    const formattedPosition =
-        this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0);
-    return Formatter.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition);
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Array.<number>}
-   */
-  formattedToOriginal(lineNumber, columnNumber) {
-    const formattedPosition =
-        Formatter.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0);
-    const originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
-    return Formatter.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0);
-  }
-
-  /**
-   * @param {!Array.<number>} positions1
-   * @param {!Array.<number>} positions2
-   * @param {number} position
-   * @return {number}
-   */
-  _convertPosition(positions1, positions2, position) {
-    const index = positions1.upperBound(position) - 1;
-    let convertedPosition = positions2[index] + position - positions1[index];
-    if (index < positions2.length - 1 && convertedPosition > positions2[index + 1])
-      convertedPosition = positions2[index + 1];
-    return convertedPosition;
-  }
-};
diff --git a/front_end/formatter/module.json b/front_end/formatter/module.json
deleted file mode 100644
index fb490c5..0000000
--- a/front_end/formatter/module.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "dependencies": [
-        "common"
-    ],
-    "scripts": [
-        "FormatterWorkerPool.js",
-        "ScriptFormatter.js"
-    ]
-}
diff --git a/front_end/formatter_worker.js b/front_end/formatter_worker.js
deleted file mode 100644
index 644ad39..0000000
--- a/front_end/formatter_worker.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// Release build has Runtime.js bundled.
-if (!self.Runtime)
-  self.importScripts('Runtime.js');
-Runtime.startWorker('formatter_worker');
diff --git a/front_end/formatter_worker.json b/front_end/formatter_worker.json
deleted file mode 100644
index 6d9555e..0000000
--- a/front_end/formatter_worker.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "modules": [
-    { "name": "platform", "type": "autostart" },
-    { "name": "text_utils", "type": "autostart" },
-    { "name": "cm_headless", "type": "autostart" },
-    { "name": "formatter_worker", "type": "autostart" }
-  ]
-}
diff --git a/front_end/formatter_worker/AcornTokenizer.js b/front_end/formatter_worker/AcornTokenizer.js
deleted file mode 100644
index 5121188..0000000
--- a/front_end/formatter_worker/AcornTokenizer.js
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-FormatterWorker.AcornTokenizer = class {
-  /**
-   * @param {string} content
-   */
-  constructor(content) {
-    this._content = content;
-    this._comments = [];
-    this._tokenizer = acorn.tokenizer(this._content, {ecmaVersion: 8, onComment: this._comments});
-    this._textCursor = new TextUtils.TextCursor(this._content.computeLineEndings());
-    this._tokenLineStart = 0;
-    this._tokenLineEnd = 0;
-    this._nextTokenInternal();
-  }
-
-  /**
-   * @param {!Acorn.TokenOrComment} token
-   * @param {string=} values
-   * @return {boolean}
-   */
-  static punctuator(token, values) {
-    return token.type !== acorn.tokTypes.num && token.type !== acorn.tokTypes.regexp &&
-        token.type !== acorn.tokTypes.string && token.type !== acorn.tokTypes.name && !token.type.keyword &&
-        (!values || (token.type.label.length === 1 && values.indexOf(token.type.label) !== -1));
-  }
-
-  /**
-   * @param {!Acorn.TokenOrComment} token
-   * @param {string=} keyword
-   * @return {boolean}
-   */
-  static keyword(token, keyword) {
-    return !!token.type.keyword && token.type !== acorn.tokTypes['_true'] && token.type !== acorn.tokTypes['_false'] &&
-        token.type !== acorn.tokTypes['_null'] && (!keyword || token.type.keyword === keyword);
-  }
-
-  /**
-   * @param {!Acorn.TokenOrComment} token
-   * @param {string=} identifier
-   * @return {boolean}
-   */
-  static identifier(token, identifier) {
-    return token.type === acorn.tokTypes.name && (!identifier || token.value === identifier);
-  }
-
-  /**
-   * @param {!Acorn.TokenOrComment} token
-   * @return {boolean}
-   */
-  static lineComment(token) {
-    return token.type === 'Line';
-  }
-
-  /**
-   * @param {!Acorn.TokenOrComment} token
-   * @return {boolean}
-   */
-  static blockComment(token) {
-    return token.type === 'Block';
-  }
-
-  /**
-   * @return {!Acorn.TokenOrComment}
-   */
-  _nextTokenInternal() {
-    if (this._comments.length)
-      return this._comments.shift();
-    const token = this._bufferedToken;
-
-    this._bufferedToken = this._tokenizer.getToken();
-    return token;
-  }
-
-  /**
-   * @return {?Acorn.TokenOrComment}
-   */
-  nextToken() {
-    const token = this._nextTokenInternal();
-    if (token.type === acorn.tokTypes.eof)
-      return null;
-
-    this._textCursor.advance(token.start);
-    this._tokenLineStart = this._textCursor.lineNumber();
-    this._tokenColumnStart = this._textCursor.columnNumber();
-
-    this._textCursor.advance(token.end);
-    this._tokenLineEnd = this._textCursor.lineNumber();
-    return token;
-  }
-
-  /**
-   * @return {?Acorn.TokenOrComment}
-   */
-  peekToken() {
-    if (this._comments.length)
-      return this._comments[0];
-    return this._bufferedToken.type !== acorn.tokTypes.eof ? this._bufferedToken : null;
-  }
-
-  /**
-   * @return {number}
-   */
-  tokenLineStart() {
-    return this._tokenLineStart;
-  }
-
-  /**
-   * @return {number}
-   */
-  tokenLineEnd() {
-    return this._tokenLineEnd;
-  }
-
-  /**
-   * @return {number}
-   */
-  tokenColumnStart() {
-    return this._tokenColumnStart;
-  }
-};
diff --git a/front_end/formatter_worker/CSSFormatter.js b/front_end/formatter_worker/CSSFormatter.js
deleted file mode 100644
index 194da08..0000000
--- a/front_end/formatter_worker/CSSFormatter.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-FormatterWorker.CSSFormatter = class {
-  /**
-   * @param {!FormatterWorker.FormattedContentBuilder} builder
-   */
-  constructor(builder) {
-    this._builder = builder;
-  }
-
-  /**
-   * @param {string} text
-   * @param {!Array.<number>} lineEndings
-   * @param {number} fromOffset
-   * @param {number} toOffset
-   */
-  format(text, lineEndings, fromOffset, toOffset) {
-    this._lineEndings = lineEndings;
-    this._fromOffset = fromOffset;
-    this._toOffset = toOffset;
-    this._lastLine = -1;
-    this._state = {};
-    const tokenize = FormatterWorker.createTokenizer('text/css');
-    const oldEnforce = this._builder.setEnforceSpaceBetweenWords(false);
-    tokenize(text.substring(this._fromOffset, this._toOffset), this._tokenCallback.bind(this));
-    this._builder.setEnforceSpaceBetweenWords(oldEnforce);
-  }
-
-  /**
-   * @param {string} token
-   * @param {?string} type
-   * @param {number} startPosition
-   */
-  _tokenCallback(token, type, startPosition) {
-    startPosition += this._fromOffset;
-    const startLine = this._lineEndings.lowerBound(startPosition);
-    if (startLine !== this._lastLine)
-      this._state.eatWhitespace = true;
-    if (/^property/.test(type) && !this._state.inPropertyValue)
-      this._state.seenProperty = true;
-    this._lastLine = startLine;
-    const isWhitespace = /^\s+$/.test(token);
-    if (isWhitespace) {
-      if (!this._state.eatWhitespace)
-        this._builder.addSoftSpace();
-      return;
-    }
-    this._state.eatWhitespace = false;
-    if (token === '\n')
-      return;
-
-    if (token !== '}') {
-      if (this._state.afterClosingBrace)
-        this._builder.addNewLine(true);
-      this._state.afterClosingBrace = false;
-    }
-    if (token === '}') {
-      if (this._state.inPropertyValue)
-        this._builder.addNewLine();
-      this._builder.decreaseNestingLevel();
-      this._state.afterClosingBrace = true;
-      this._state.inPropertyValue = false;
-    } else if (token === ':' && !this._state.inPropertyValue && this._state.seenProperty) {
-      this._builder.addToken(token, startPosition);
-      this._builder.addSoftSpace();
-      this._state.eatWhitespace = true;
-      this._state.inPropertyValue = true;
-      this._state.seenProperty = false;
-      return;
-    } else if (token === '{') {
-      this._builder.addSoftSpace();
-      this._builder.addToken(token, startPosition);
-      this._builder.addNewLine();
-      this._builder.increaseNestingLevel();
-      return;
-    }
-
-    this._builder.addToken(token, startPosition);
-
-    if (type === 'comment' && !this._state.inPropertyValue && !this._state.seenProperty)
-      this._builder.addNewLine();
-    if (token === ';' && this._state.inPropertyValue) {
-      this._state.inPropertyValue = false;
-      this._builder.addNewLine();
-    } else if (token === '}') {
-      this._builder.addNewLine();
-    }
-  }
-};
diff --git a/front_end/formatter_worker/CSSRuleParser.js b/front_end/formatter_worker/CSSRuleParser.js
deleted file mode 100644
index b2c4c54..0000000
--- a/front_end/formatter_worker/CSSRuleParser.js
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-FormatterWorker.CSSParserStates = {
-  Initial: 'Initial',
-  Selector: 'Selector',
-  Style: 'Style',
-  PropertyName: 'PropertyName',
-  PropertyValue: 'PropertyValue',
-  AtRule: 'AtRule'
-};
-
-/**
- * @param {string} text
- */
-FormatterWorker.parseCSS = function(text) {
-  FormatterWorker._innerParseCSS(text, postMessage);
-};
-
-/**
- * @param {string} text
- * @param {function(*)} chunkCallback
- */
-FormatterWorker._innerParseCSS = function(text, chunkCallback) {
-  const chunkSize = 100000;  // characters per data chunk
-  const lines = text.split('\n');
-  let rules = [];
-  let processedChunkCharacters = 0;
-
-  let state = FormatterWorker.CSSParserStates.Initial;
-  let rule;
-  let property;
-  const UndefTokenType = new Set();
-
-  let disabledRules = [];
-  function disabledRulesCallback(chunk) {
-    disabledRules = disabledRules.concat(chunk.chunk);
-  }
-
-  /**
-   * @param {string} tokenValue
-   * @param {?string} tokenTypes
-   * @param {number} column
-   * @param {number} newColumn
-   */
-  function processToken(tokenValue, tokenTypes, column, newColumn) {
-    const tokenType = tokenTypes ? new Set(tokenTypes.split(' ')) : UndefTokenType;
-    switch (state) {
-      case FormatterWorker.CSSParserStates.Initial:
-        if (tokenType.has('qualifier') || tokenType.has('builtin') || tokenType.has('tag')) {
-          rule = {
-            selectorText: tokenValue,
-            lineNumber: lineNumber,
-            columnNumber: column,
-            properties: [],
-          };
-          state = FormatterWorker.CSSParserStates.Selector;
-        } else if (tokenType.has('def')) {
-          rule = {
-            atRule: tokenValue,
-            lineNumber: lineNumber,
-            columnNumber: column,
-          };
-          state = FormatterWorker.CSSParserStates.AtRule;
-        }
-        break;
-      case FormatterWorker.CSSParserStates.Selector:
-        if (tokenValue === '{' && tokenType === UndefTokenType) {
-          rule.selectorText = rule.selectorText.trim();
-          rule.styleRange = createRange(lineNumber, newColumn);
-          state = FormatterWorker.CSSParserStates.Style;
-        } else {
-          rule.selectorText += tokenValue;
-        }
-        break;
-      case FormatterWorker.CSSParserStates.AtRule:
-        if ((tokenValue === ';' || tokenValue === '{') && tokenType === UndefTokenType) {
-          rule.atRule = rule.atRule.trim();
-          rules.push(rule);
-          state = FormatterWorker.CSSParserStates.Initial;
-        } else {
-          rule.atRule += tokenValue;
-        }
-        break;
-      case FormatterWorker.CSSParserStates.Style:
-        if (tokenType.has('meta') || tokenType.has('property')) {
-          property = {
-            name: tokenValue,
-            value: '',
-            range: createRange(lineNumber, column),
-            nameRange: createRange(lineNumber, column)
-          };
-          state = FormatterWorker.CSSParserStates.PropertyName;
-        } else if (tokenValue === '}' && tokenType === UndefTokenType) {
-          rule.styleRange.endLine = lineNumber;
-          rule.styleRange.endColumn = column;
-          rules.push(rule);
-          state = FormatterWorker.CSSParserStates.Initial;
-        } else if (tokenType.has('comment')) {
-          // The |processToken| is called per-line, so no token spans more than one line.
-          // Support only a one-line comments.
-          if (tokenValue.substring(0, 2) !== '/*' || tokenValue.substring(tokenValue.length - 2) !== '*/')
-            break;
-          const uncommentedText = tokenValue.substring(2, tokenValue.length - 2);
-          const fakeRule = 'a{\n' + uncommentedText + '}';
-          disabledRules = [];
-          FormatterWorker._innerParseCSS(fakeRule, disabledRulesCallback);
-          if (disabledRules.length === 1 && disabledRules[0].properties.length === 1) {
-            const disabledProperty = disabledRules[0].properties[0];
-            disabledProperty.disabled = true;
-            disabledProperty.range = createRange(lineNumber, column);
-            disabledProperty.range.endColumn = newColumn;
-            const lineOffset = lineNumber - 1;
-            const columnOffset = column + 2;
-            disabledProperty.nameRange.startLine += lineOffset;
-            disabledProperty.nameRange.startColumn += columnOffset;
-            disabledProperty.nameRange.endLine += lineOffset;
-            disabledProperty.nameRange.endColumn += columnOffset;
-            disabledProperty.valueRange.startLine += lineOffset;
-            disabledProperty.valueRange.startColumn += columnOffset;
-            disabledProperty.valueRange.endLine += lineOffset;
-            disabledProperty.valueRange.endColumn += columnOffset;
-            rule.properties.push(disabledProperty);
-          }
-        }
-        break;
-      case FormatterWorker.CSSParserStates.PropertyName:
-        if (tokenValue === ':' && tokenType === UndefTokenType) {
-          property.name = property.name;
-          property.nameRange.endLine = lineNumber;
-          property.nameRange.endColumn = column;
-          property.valueRange = createRange(lineNumber, newColumn);
-          state = FormatterWorker.CSSParserStates.PropertyValue;
-        } else if (tokenType.has('property')) {
-          property.name += tokenValue;
-        }
-        break;
-      case FormatterWorker.CSSParserStates.PropertyValue:
-        if ((tokenValue === ';' || tokenValue === '}') && tokenType === UndefTokenType) {
-          property.value = property.value;
-          property.valueRange.endLine = lineNumber;
-          property.valueRange.endColumn = column;
-          property.range.endLine = lineNumber;
-          property.range.endColumn = tokenValue === ';' ? newColumn : column;
-          rule.properties.push(property);
-          if (tokenValue === '}') {
-            rule.styleRange.endLine = lineNumber;
-            rule.styleRange.endColumn = column;
-            rules.push(rule);
-            state = FormatterWorker.CSSParserStates.Initial;
-          } else {
-            state = FormatterWorker.CSSParserStates.Style;
-          }
-        } else if (!tokenType.has('comment')) {
-          property.value += tokenValue;
-        }
-        break;
-      default:
-        console.assert(false, 'Unknown CSS parser state.');
-    }
-    processedChunkCharacters += newColumn - column;
-    if (processedChunkCharacters > chunkSize) {
-      chunkCallback({chunk: rules, isLastChunk: false});
-      rules = [];
-      processedChunkCharacters = 0;
-    }
-  }
-  const tokenizer = FormatterWorker.createTokenizer('text/css');
-  let lineNumber;
-  for (lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
-    const line = lines[lineNumber];
-    tokenizer(line, processToken);
-    processToken('\n', null, line.length, line.length + 1);
-  }
-  chunkCallback({chunk: rules, isLastChunk: true});
-
-  /**
-   * @return {!{startLine: number, startColumn: number, endLine: number, endColumn: number}}
-   */
-  function createRange(lineNumber, columnNumber) {
-    return {startLine: lineNumber, startColumn: columnNumber, endLine: lineNumber, endColumn: columnNumber};
-  }
-};
diff --git a/front_end/formatter_worker/ESTreeWalker.js b/front_end/formatter_worker/ESTreeWalker.js
deleted file mode 100644
index b33d334..0000000
--- a/front_end/formatter_worker/ESTreeWalker.js
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-FormatterWorker.ESTreeWalker = class {
-  /**
-   * @param {function(!ESTree.Node):(!Object|undefined)} beforeVisit
-   * @param {function(!ESTree.Node)=} afterVisit
-   */
-  constructor(beforeVisit, afterVisit) {
-    this._beforeVisit = beforeVisit;
-    this._afterVisit = afterVisit || new Function();
-    this._walkNulls = false;
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setWalkNulls(value) {
-    this._walkNulls = value;
-  }
-
-  /**
-   * @param {!ESTree.Node} ast
-   */
-  walk(ast) {
-    this._innerWalk(ast, null);
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @param {?ESTree.Node} parent
-   */
-  _innerWalk(node, parent) {
-    if (!node && parent && this._walkNulls) {
-      const result = /** @type {!Object} */ ({raw: 'null', value: null});
-      result.type = 'Literal';
-      node = /** @type {!ESTree.Node} */ (result);
-    }
-
-    if (!node)
-      return;
-    node.parent = parent;
-
-    if (this._beforeVisit.call(null, node) === FormatterWorker.ESTreeWalker.SkipSubtree) {
-      this._afterVisit.call(null, node);
-      return;
-    }
-
-    const walkOrder = FormatterWorker.ESTreeWalker._walkOrder[node.type];
-    if (!walkOrder) {
-      console.error('Walk order not defined for ' + node.type);
-      return;
-    }
-
-    if (node.type === 'TemplateLiteral') {
-      const templateLiteral = /** @type {!ESTree.TemplateLiteralNode} */ (node);
-      const expressionsLength = templateLiteral.expressions.length;
-      for (let i = 0; i < expressionsLength; ++i) {
-        this._innerWalk(templateLiteral.quasis[i], templateLiteral);
-        this._innerWalk(templateLiteral.expressions[i], templateLiteral);
-      }
-      this._innerWalk(templateLiteral.quasis[expressionsLength], templateLiteral);
-    } else {
-      for (let i = 0; i < walkOrder.length; ++i) {
-        const entity = node[walkOrder[i]];
-        if (Array.isArray(entity))
-          this._walkArray(entity, node);
-        else
-          this._innerWalk(entity, node);
-      }
-    }
-
-    this._afterVisit.call(null, node);
-  }
-
-  /**
-   * @param {!Array.<!ESTree.Node>} nodeArray
-   * @param {?ESTree.Node} parentNode
-   */
-  _walkArray(nodeArray, parentNode) {
-    for (let i = 0; i < nodeArray.length; ++i)
-      this._innerWalk(nodeArray[i], parentNode);
-  }
-};
-
-/** @typedef {!Object} FormatterWorker.ESTreeWalker.SkipSubtree */
-FormatterWorker.ESTreeWalker.SkipSubtree = {};
-
-/** @enum {!Array.<string>} */
-FormatterWorker.ESTreeWalker._walkOrder = {
-  'AwaitExpression': ['arguments'],
-  'ArrayExpression': ['elements'],
-  'ArrayPattern': ['elements'],
-  'ArrowFunctionExpression': ['params', 'body'],
-  'AssignmentExpression': ['left', 'right'],
-  'BinaryExpression': ['left', 'right'],
-  'BlockStatement': ['body'],
-  'BreakStatement': ['label'],
-  'CallExpression': ['callee', 'arguments'],
-  'CatchClause': ['param', 'body'],
-  'ClassBody': ['body'],
-  'ClassDeclaration': ['id', 'superClass', 'body'],
-  'ClassExpression': ['id', 'superClass', 'body'],
-  'ConditionalExpression': ['test', 'consequent', 'alternate'],
-  'ContinueStatement': ['label'],
-  'DebuggerStatement': [],
-  'DoWhileStatement': ['body', 'test'],
-  'EmptyStatement': [],
-  'ExpressionStatement': ['expression'],
-  'ForInStatement': ['left', 'right', 'body'],
-  'ForOfStatement': ['left', 'right', 'body'],
-  'ForStatement': ['init', 'test', 'update', 'body'],
-  'FunctionDeclaration': ['id', 'params', 'body'],
-  'FunctionExpression': ['id', 'params', 'body'],
-  'Identifier': [],
-  'IfStatement': ['test', 'consequent', 'alternate'],
-  'LabeledStatement': ['label', 'body'],
-  'Literal': [],
-  'LogicalExpression': ['left', 'right'],
-  'MemberExpression': ['object', 'property'],
-  'MethodDefinition': ['key', 'value'],
-  'NewExpression': ['callee', 'arguments'],
-  'ObjectExpression': ['properties'],
-  'ObjectPattern': ['properties'],
-  'ParenthesizedExpression': ['expression'],
-  'Program': ['body'],
-  'Property': ['key', 'value'],
-  'ReturnStatement': ['argument'],
-  'SequenceExpression': ['expressions'],
-  'Super': [],
-  'SwitchCase': ['test', 'consequent'],
-  'SwitchStatement': ['discriminant', 'cases'],
-  'TaggedTemplateExpression': ['tag', 'quasi'],
-  'TemplateElement': [],
-  'TemplateLiteral': ['quasis', 'expressions'],
-  'ThisExpression': [],
-  'ThrowStatement': ['argument'],
-  'TryStatement': ['block', 'handler', 'finalizer'],
-  'UnaryExpression': ['argument'],
-  'UpdateExpression': ['argument'],
-  'VariableDeclaration': ['declarations'],
-  'VariableDeclarator': ['id', 'init'],
-  'WhileStatement': ['test', 'body'],
-  'WithStatement': ['object', 'body'],
-  'YieldExpression': ['argument']
-};
diff --git a/front_end/formatter_worker/FormattedContentBuilder.js b/front_end/formatter_worker/FormattedContentBuilder.js
deleted file mode 100644
index 4a2feb2..0000000
--- a/front_end/formatter_worker/FormattedContentBuilder.js
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-FormatterWorker.FormattedContentBuilder = class {
-  /**
-   * @param {string} indentString
-   */
-  constructor(indentString) {
-    this._lastOriginalPosition = 0;
-
-    this._formattedContent = [];
-    this._formattedContentLength = 0;
-    this._lastFormattedPosition = 0;
-
-    /** @type {!{original: !Array.<number>, formatted: !Array.<number>}} */
-    this._mapping = {original: [0], formatted: [0]};
-
-    this._nestingLevel = 0;
-    this._indentString = indentString;
-    /** @type {!Map<number, string>} */
-    this._cachedIndents = new Map();
-
-    this._newLines = 0;
-    this._softSpace = false;
-    this._hardSpaces = 0;
-    this._enforceSpaceBetweenWords = true;
-  }
-
-  /**
-   * @param {boolean} value
-   * @return {boolean}
-   */
-  setEnforceSpaceBetweenWords(value) {
-    const oldValue = this._enforceSpaceBetweenWords;
-    this._enforceSpaceBetweenWords = value;
-    return oldValue;
-  }
-
-  /**
-   * @param {string} token
-   * @param {number} offset
-   */
-  addToken(token, offset) {
-    const last = this._formattedContent.peekLast();
-    if (this._enforceSpaceBetweenWords && last && /\w/.test(last[last.length - 1]) && /\w/.test(token))
-      this.addSoftSpace();
-
-    this._appendFormatting();
-
-    // Insert token.
-    this._addMappingIfNeeded(offset);
-    this._addText(token);
-  }
-
-  addSoftSpace() {
-    if (!this._hardSpaces)
-      this._softSpace = true;
-  }
-
-  addHardSpace() {
-    this._softSpace = false;
-    ++this._hardSpaces;
-  }
-
-  /**
-   * @param {boolean=} noSquash
-   */
-  addNewLine(noSquash) {
-    // Avoid leading newlines.
-    if (!this._formattedContentLength)
-      return;
-    if (noSquash)
-      ++this._newLines;
-    else
-      this._newLines = this._newLines || 1;
-  }
-
-  increaseNestingLevel() {
-    this._nestingLevel += 1;
-  }
-
-  decreaseNestingLevel() {
-    if (this._nestingLevel > 0)
-      this._nestingLevel -= 1;
-  }
-
-  _appendFormatting() {
-    if (this._newLines) {
-      for (let i = 0; i < this._newLines; ++i)
-        this._addText('\n');
-      this._addText(this._indent());
-    } else if (this._softSpace) {
-      this._addText(' ');
-    }
-    if (this._hardSpaces) {
-      for (let i = 0; i < this._hardSpaces; ++i)
-        this._addText(' ');
-    }
-    this._newLines = 0;
-    this._softSpace = false;
-    this._hardSpaces = 0;
-  }
-
-  /**
-   * @return {string}
-   */
-  content() {
-    return this._formattedContent.join('') + (this._newLines ? '\n' : '');
-  }
-
-  /**
-   * @return {!{original: !Array.<number>, formatted: !Array.<number>}}
-   */
-  mapping() {
-    return this._mapping;
-  }
-
-  /**
-   * @return {string}
-   */
-  _indent() {
-    const cachedValue = this._cachedIndents.get(this._nestingLevel);
-    if (cachedValue)
-      return cachedValue;
-
-    let fullIndent = '';
-    for (let i = 0; i < this._nestingLevel; ++i)
-      fullIndent += this._indentString;
-
-    // Cache a maximum of 20 nesting level indents.
-    if (this._nestingLevel <= 20)
-      this._cachedIndents.set(this._nestingLevel, fullIndent);
-    return fullIndent;
-  }
-
-  /**
-   * @param {string} text
-   */
-  _addText(text) {
-    this._formattedContent.push(text);
-    this._formattedContentLength += text.length;
-  }
-
-  /**
-   * @param {number} originalPosition
-   */
-  _addMappingIfNeeded(originalPosition) {
-    if (originalPosition - this._lastOriginalPosition === this._formattedContentLength - this._lastFormattedPosition)
-      return;
-    this._mapping.original.push(originalPosition);
-    this._lastOriginalPosition = originalPosition;
-    this._mapping.formatted.push(this._formattedContentLength);
-    this._lastFormattedPosition = this._formattedContentLength;
-  }
-};
diff --git a/front_end/formatter_worker/FormatterWorker.js b/front_end/formatter_worker/FormatterWorker.js
deleted file mode 100644
index 8463752..0000000
--- a/front_end/formatter_worker/FormatterWorker.js
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @param {string} mimeType
- * @return {function(string, function(string, ?string, number, number):(!Object|undefined))}
- */
-FormatterWorker.createTokenizer = function(mimeType) {
-  const mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
-  const state = CodeMirror.startState(mode);
-  /**
-   * @param {string} line
-   * @param {function(string, ?string, number, number):?} callback
-   */
-  function tokenize(line, callback) {
-    const stream = new CodeMirror.StringStream(line);
-    while (!stream.eol()) {
-      const style = mode.token(stream, state);
-      const value = stream.current();
-      if (callback(value, style, stream.start, stream.start + value.length) === FormatterWorker.AbortTokenization)
-        return;
-      stream.start = stream.pos;
-    }
-  }
-  return tokenize;
-};
-
-FormatterWorker.AbortTokenization = {};
-
-self.onmessage = function(event) {
-  const method = /** @type {string} */ (event.data.method);
-  const params = /** @type !{indentString: string, content: string, mimeType: string} */ (event.data.params);
-  if (!method)
-    return;
-
-  switch (method) {
-    case 'format':
-      FormatterWorker.format(params.mimeType, params.content, params.indentString);
-      break;
-    case 'parseCSS':
-      FormatterWorker.parseCSS(params.content);
-      break;
-    case 'parseSCSS':
-      FormatterWorker.FormatterWorkerContentParser.parse(params.content, 'text/x-scss');
-      break;
-    case 'javaScriptOutline':
-      FormatterWorker.javaScriptOutline(params.content);
-      break;
-    case 'javaScriptIdentifiers':
-      FormatterWorker.javaScriptIdentifiers(params.content);
-      break;
-    case 'evaluatableJavaScriptSubstring':
-      FormatterWorker.evaluatableJavaScriptSubstring(params.content);
-      break;
-    case 'parseJSONRelaxed':
-      FormatterWorker.parseJSONRelaxed(params.content);
-      break;
-    case 'preprocessTopLevelAwaitExpressions':
-      FormatterWorker.preprocessTopLevelAwaitExpressions(params.content);
-      break;
-    default:
-      console.error('Unsupport method name: ' + method);
-  }
-};
-
-/**
- * @param {string} content
- */
-FormatterWorker.parseJSONRelaxed = function(content) {
-  postMessage(FormatterWorker.RelaxedJSONParser.parse(content));
-};
-
-/**
- * @param {string} content
- */
-FormatterWorker.evaluatableJavaScriptSubstring = function(content) {
-  const tokenizer = acorn.tokenizer(content, {ecmaVersion: 9});
-  let result = '';
-  try {
-    let token = tokenizer.getToken();
-    while (token.type !== acorn.tokTypes.eof && FormatterWorker.AcornTokenizer.punctuator(token))
-      token = tokenizer.getToken();
-
-    const startIndex = token.start;
-    let endIndex = token.end;
-    let openBracketsCounter = 0;
-    while (token.type !== acorn.tokTypes.eof) {
-      const isIdentifier = FormatterWorker.AcornTokenizer.identifier(token);
-      const isThis = FormatterWorker.AcornTokenizer.keyword(token, 'this');
-      const isString = token.type === acorn.tokTypes.string;
-      if (!isThis && !isIdentifier && !isString)
-        break;
-
-      endIndex = token.end;
-      token = tokenizer.getToken();
-      while (FormatterWorker.AcornTokenizer.punctuator(token, '.[]')) {
-        if (FormatterWorker.AcornTokenizer.punctuator(token, '['))
-          openBracketsCounter++;
-
-        if (FormatterWorker.AcornTokenizer.punctuator(token, ']')) {
-          endIndex = openBracketsCounter > 0 ? token.end : endIndex;
-          openBracketsCounter--;
-        }
-
-        token = tokenizer.getToken();
-      }
-    }
-    result = content.substring(startIndex, endIndex);
-  } catch (e) {
-    console.error(e);
-  }
-  postMessage(result);
-};
-
-/**
- * @param {string} content
- */
-FormatterWorker.preprocessTopLevelAwaitExpressions = function(content) {
-  let wrapped = '(async () => {' + content + '})()';
-  const root = acorn.parse(wrapped, {ecmaVersion: 9});
-  const body = root.body[0].expression.callee.body;
-  const changes = [];
-  let containsAwait = false;
-  let containsReturn = false;
-  class Visitor {
-    ClassDeclaration(node) {
-      if (node.parent === body)
-        changes.push({text: node.id.name + '=', start: node.start, end: node.start});
-    }
-    FunctionDeclaration(node) {
-      changes.push({text: node.id.name + '=', start: node.start, end: node.start});
-      return FormatterWorker.ESTreeWalker.SkipSubtree;
-    }
-    FunctionExpression(node) {
-      return FormatterWorker.ESTreeWalker.SkipSubtree;
-    }
-    ArrowFunctionExpression(node) {
-      return FormatterWorker.ESTreeWalker.SkipSubtree;
-    }
-    MethodDefinition(node) {
-      return FormatterWorker.ESTreeWalker.SkipSubtree;
-    }
-    AwaitExpression(node) {
-      containsAwait = true;
-    }
-    ReturnStatement(node) {
-      containsReturn = true;
-    }
-    VariableDeclaration(node) {
-      if (node.kind !== 'var' && node.parent !== body)
-        return;
-      const onlyOneDeclaration = node.declarations.length === 1;
-      changes.push(
-          {text: onlyOneDeclaration ? 'void' : 'void (', start: node.start, end: node.start + node.kind.length});
-      for (const declaration of node.declarations) {
-        if (!declaration.init) {
-          changes.push({text: '(', start: declaration.start, end: declaration.start});
-          changes.push({text: '=undefined)', start: declaration.end, end: declaration.end});
-          continue;
-        }
-        changes.push({text: '(', start: declaration.start, end: declaration.start});
-        changes.push({text: ')', start: declaration.end, end: declaration.end});
-      }
-      if (!onlyOneDeclaration) {
-        const last = node.declarations.peekLast();
-        changes.push({text: ')', start: last.end, end: last.end});
-      }
-    }
-  }
-  const walker = new FormatterWorker.ESTreeWalker(visit.bind(new Visitor()));
-  walker.walk(body);
-  /**
-   * @param {!ESTree.Node} node
-   * @this {Object}
-   */
-  function visit(node) {
-    if (node.type in this)
-      return this[node.type](node);
-  }
-  // Top-level return is not allowed.
-  if (!containsAwait || containsReturn) {
-    postMessage('');
-    return;
-  }
-  const last = body.body[body.body.length - 1];
-  if (last.type === 'ExpressionStatement') {
-    changes.push({text: 'return (', start: last.start, end: last.start});
-    if (wrapped[last.end - 1] !== ';')
-      changes.push({text: ')', start: last.end, end: last.end});
-    else
-      changes.push({text: ')', start: last.end - 1, end: last.end - 1});
-  }
-  while (changes.length) {
-    const change = changes.pop();
-    wrapped = wrapped.substr(0, change.start) + change.text + wrapped.substr(change.end);
-  }
-  postMessage(wrapped);
-};
-
-/**
- * @param {string} content
- */
-FormatterWorker.javaScriptIdentifiers = function(content) {
-  const root = acorn.parse(content, {ranges: false, ecmaVersion: 9});
-
-  /** @type {!Array<!ESTree.Node>} */
-  const identifiers = [];
-  const walker = new FormatterWorker.ESTreeWalker(beforeVisit);
-
-  /**
-   * @param {!ESTree.Node} node
-   * @return {boolean}
-   */
-  function isFunction(node) {
-    return node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' ||
-        node.type === 'ArrowFunctionExpression';
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   */
-  function beforeVisit(node) {
-    if (isFunction(node)) {
-      if (node.id)
-        identifiers.push(node.id);
-      return FormatterWorker.ESTreeWalker.SkipSubtree;
-    }
-
-    if (node.type !== 'Identifier')
-      return;
-
-    if (node.parent && node.parent.type === 'MemberExpression' && node.parent.property === node &&
-        !node.parent.computed)
-      return;
-    identifiers.push(node);
-  }
-
-  if (!root || root.type !== 'Program' || root.body.length !== 1 || !isFunction(root.body[0])) {
-    postMessage([]);
-    return;
-  }
-
-  const functionNode = root.body[0];
-  for (const param of functionNode.params)
-    walker.walk(param);
-  walker.walk(functionNode.body);
-  const reduced = identifiers.map(id => ({name: id.name, offset: id.start}));
-  postMessage(reduced);
-};
-
-/**
- * @param {string} mimeType
- * @param {string} text
- * @param {string=} indentString
- */
-FormatterWorker.format = function(mimeType, text, indentString) {
-  // Default to a 4-space indent.
-  indentString = indentString || '    ';
-  const result = {};
-  const builder = new FormatterWorker.FormattedContentBuilder(indentString);
-  const lineEndings = text.computeLineEndings();
-  try {
-    switch (mimeType) {
-      case 'text/html': {
-        const formatter = new FormatterWorker.HTMLFormatter(builder);
-        formatter.format(text, lineEndings);
-        break;
-      }
-      case 'text/css': {
-        const formatter = new FormatterWorker.CSSFormatter(builder);
-        formatter.format(text, lineEndings, 0, text.length);
-        break;
-      }
-      case 'text/javascript': {
-        const formatter = new FormatterWorker.JavaScriptFormatter(builder);
-        formatter.format(text, lineEndings, 0, text.length);
-        break;
-      }
-      default: {
-        const formatter = new FormatterWorker.IdentityFormatter(builder);
-        formatter.format(text, lineEndings, 0, text.length);
-      }
-    }
-    result.mapping = builder.mapping();
-    result.content = builder.content();
-  } catch (e) {
-    console.error(e);
-    result.mapping = {original: [0], formatted: [0]};
-    result.content = text;
-  }
-  postMessage(result);
-};
-
-/**
- * @interface
- */
-FormatterWorker.FormatterWorkerContentParser = function() {};
-
-FormatterWorker.FormatterWorkerContentParser.prototype = {
-  /**
-   * @param {string} content
-   * @return {!Object}
-   */
-  parse(content) {}
-};
-
-/**
- * @param {string} content
- * @param {string} mimeType
- */
-FormatterWorker.FormatterWorkerContentParser.parse = function(content, mimeType) {
-  const extension = self.runtime.extensions(FormatterWorker.FormatterWorkerContentParser).find(findExtension);
-  console.assert(extension);
-  extension.instance().then(instance => instance.parse(content)).catchException(null).then(postMessage);
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @return {boolean}
-   */
-  function findExtension(extension) {
-    return extension.descriptor()['mimeType'] === mimeType;
-  }
-};
-
-(function disableLoggingForTest() {
-  if (Runtime.queryParam('test'))
-    console.error = () => undefined;
-})();
diff --git a/front_end/formatter_worker/HTMLFormatter.js b/front_end/formatter_worker/HTMLFormatter.js
deleted file mode 100644
index a8d8fc7..0000000
--- a/front_end/formatter_worker/HTMLFormatter.js
+++ /dev/null
@@ -1,452 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-FormatterWorker.HTMLFormatter = class {
-  /**
-   * @param {!FormatterWorker.FormattedContentBuilder} builder
-   */
-  constructor(builder) {
-    this._builder = builder;
-    this._jsFormatter = new FormatterWorker.JavaScriptFormatter(builder);
-    this._cssFormatter = new FormatterWorker.CSSFormatter(builder);
-  }
-
-  /**
-   * @param {string} text
-   * @param {!Array<number>} lineEndings
-   */
-  format(text, lineEndings) {
-    this._text = text;
-    this._lineEndings = lineEndings;
-    this._model = new FormatterWorker.HTMLModel(text);
-    this._walk(this._model.document());
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   * @param {number} offset
-   */
-  _formatTokensTill(element, offset) {
-    while (this._model.peekToken() && this._model.peekToken().startOffset < offset) {
-      const token = this._model.nextToken();
-      this._formatToken(element, token);
-    }
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   */
-  _walk(element) {
-    if (element.parent)
-      this._formatTokensTill(element.parent, element.openTag.startOffset);
-    this._beforeOpenTag(element);
-    this._formatTokensTill(element, element.openTag.endOffset);
-    this._afterOpenTag(element);
-    for (let i = 0; i < element.children.length; ++i)
-      this._walk(element.children[i]);
-
-    this._formatTokensTill(element, element.closeTag.startOffset);
-    this._beforeCloseTag(element);
-    this._formatTokensTill(element, element.closeTag.endOffset);
-    this._afterCloseTag(element);
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   */
-  _beforeOpenTag(element) {
-    if (!element.children.length || element === this._model.document())
-      return;
-    this._builder.addNewLine();
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   */
-  _afterOpenTag(element) {
-    if (!element.children.length || element === this._model.document())
-      return;
-    this._builder.increaseNestingLevel();
-    this._builder.addNewLine();
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   */
-  _beforeCloseTag(element) {
-    if (!element.children.length || element === this._model.document())
-      return;
-    this._builder.decreaseNestingLevel();
-    this._builder.addNewLine();
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   */
-  _afterCloseTag(element) {
-    this._builder.addNewLine();
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Element} element
-   * @param {!FormatterWorker.HTMLModel.Token} token
-   */
-  _formatToken(element, token) {
-    if (token.value.isWhitespace())
-      return;
-    if (token.type.has('comment') || token.type.has('meta')) {
-      this._builder.addNewLine();
-      this._builder.addToken(token.value.trim(), token.startOffset);
-      this._builder.addNewLine();
-      return;
-    }
-
-    const isBodyToken =
-        element.openTag.endOffset <= token.startOffset && token.startOffset < element.closeTag.startOffset;
-    if (isBodyToken && element.name === 'style') {
-      this._builder.addNewLine();
-      this._builder.increaseNestingLevel();
-      this._cssFormatter.format(this._text, this._lineEndings, token.startOffset, token.endOffset);
-      this._builder.decreaseNestingLevel();
-      return;
-    }
-    if (isBodyToken && element.name === 'script') {
-      this._builder.addNewLine();
-      this._builder.increaseNestingLevel();
-      const mimeType =
-          element.openTag.attributes.has('type') ? element.openTag.attributes.get('type').toLowerCase() : null;
-      if (!mimeType || FormatterWorker.HTMLFormatter.SupportedJavaScriptMimeTypes.has(mimeType)) {
-        this._jsFormatter.format(this._text, this._lineEndings, token.startOffset, token.endOffset);
-      } else {
-        this._builder.addToken(token.value, token.startOffset);
-        this._builder.addNewLine();
-      }
-      this._builder.decreaseNestingLevel();
-      return;
-    }
-
-    if (!isBodyToken && token.type.has('attribute'))
-      this._builder.addSoftSpace();
-
-    this._builder.addToken(token.value, token.startOffset);
-  }
-};
-
-FormatterWorker.HTMLFormatter.SupportedJavaScriptMimeTypes =
-    new Set(['text/javascript', 'text/ecmascript', 'application/javascript', 'application/ecmascript']);
-
-/**
- * @unrestricted
- */
-FormatterWorker.HTMLModel = class {
-  /**
-   * @param {string} text
-   */
-  constructor(text) {
-    this._state = FormatterWorker.HTMLModel.ParseState.Initial;
-    this._document = new FormatterWorker.HTMLModel.Element('document');
-    this._document.openTag = new FormatterWorker.HTMLModel.Tag('document', 0, 0, new Map(), true, false);
-    this._document.closeTag =
-        new FormatterWorker.HTMLModel.Tag('document', text.length, text.length, new Map(), false, false);
-
-    this._stack = [this._document];
-
-    this._tokens = [];
-    this._tokenIndex = 0;
-    this._build(text);
-  }
-
-  /**
-   * @param {string} text
-   */
-  _build(text) {
-    const tokenizer = FormatterWorker.createTokenizer('text/html');
-    let lastOffset = 0;
-    const lowerCaseText = text.toLowerCase();
-
-    while (true) {
-      tokenizer(text.substring(lastOffset), processToken.bind(this, lastOffset));
-      if (lastOffset >= text.length)
-        break;
-      const element = this._stack.peekLast();
-      lastOffset = lowerCaseText.indexOf('</' + element.name, lastOffset);
-      if (lastOffset === -1)
-        lastOffset = text.length;
-      const tokenStart = element.openTag.endOffset;
-      const tokenEnd = lastOffset;
-      const tokenValue = text.substring(tokenStart, tokenEnd);
-      this._tokens.push(new FormatterWorker.HTMLModel.Token(tokenValue, new Set(), tokenStart, tokenEnd));
-    }
-
-    while (this._stack.length > 1) {
-      const element = this._stack.peekLast();
-      this._popElement(
-          new FormatterWorker.HTMLModel.Tag(element.name, text.length, text.length, new Map(), false, false));
-    }
-
-    /**
-     * @param {number} baseOffset
-     * @param {string} tokenValue
-     * @param {?string} type
-     * @param {number} tokenStart
-     * @param {number} tokenEnd
-     * @return {(!Object|undefined)}
-     * @this {FormatterWorker.HTMLModel}
-     */
-    function processToken(baseOffset, tokenValue, type, tokenStart, tokenEnd) {
-      tokenStart += baseOffset;
-      tokenEnd += baseOffset;
-      lastOffset = tokenEnd;
-
-      const tokenType = type ? new Set(type.split(' ')) : new Set();
-      const token = new FormatterWorker.HTMLModel.Token(tokenValue, tokenType, tokenStart, tokenEnd);
-      this._tokens.push(token);
-      this._updateDOM(token);
-
-      const element = this._stack.peekLast();
-      if (element && (element.name === 'script' || element.name === 'style') &&
-          element.openTag.endOffset === lastOffset)
-        return FormatterWorker.AbortTokenization;
-    }
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Token} token
-   */
-  _updateDOM(token) {
-    const S = FormatterWorker.HTMLModel.ParseState;
-    const value = token.value;
-    const type = token.type;
-    switch (this._state) {
-      case S.Initial:
-        if (type.has('bracket') && (value === '<' || value === '</')) {
-          this._onStartTag(token);
-          this._state = S.Tag;
-        }
-        return;
-      case S.Tag:
-        if (type.has('tag') && !type.has('bracket')) {
-          this._tagName = value.trim().toLowerCase();
-        } else if (type.has('attribute')) {
-          this._attributeName = value.trim().toLowerCase();
-          this._attributes.set(this._attributeName, '');
-          this._state = S.AttributeName;
-        } else if (type.has('bracket') && (value === '>' || value === '/>')) {
-          this._onEndTag(token);
-          this._state = S.Initial;
-        }
-        return;
-      case S.AttributeName:
-        if (!type.size && value === '=') {
-          this._state = S.AttributeValue;
-        } else if (type.has('bracket') && (value === '>' || value === '/>')) {
-          this._onEndTag(token);
-          this._state = S.Initial;
-        }
-        return;
-      case S.AttributeValue:
-        if (type.has('string')) {
-          this._attributes.set(this._attributeName, value);
-          this._state = S.Tag;
-        } else if (type.has('bracket') && (value === '>' || value === '/>')) {
-          this._onEndTag(token);
-          this._state = S.Initial;
-        }
-        return;
-    }
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Token} token
-   */
-  _onStartTag(token) {
-    this._tagName = '';
-    this._tagStartOffset = token.startOffset;
-    this._tagEndOffset = null;
-    this._attributes = new Map();
-    this._attributeName = '';
-    this._isOpenTag = token.value === '<';
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Token} token
-   */
-  _onEndTag(token) {
-    this._tagEndOffset = token.endOffset;
-    const selfClosingTag = token.value === '/>' || FormatterWorker.HTMLModel.SelfClosingTags.has(this._tagName);
-    const tag = new FormatterWorker.HTMLModel.Tag(
-        this._tagName, this._tagStartOffset, this._tagEndOffset, this._attributes, this._isOpenTag, selfClosingTag);
-    this._onTagComplete(tag);
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Tag} tag
-   */
-  _onTagComplete(tag) {
-    if (tag.isOpenTag) {
-      const topElement = this._stack.peekLast();
-      if (topElement !== this._document && topElement.openTag.selfClosingTag)
-        this._popElement(autocloseTag(topElement, topElement.openTag.endOffset));
-      else if (
-          (topElement.name in FormatterWorker.HTMLModel.AutoClosingTags) &&
-          FormatterWorker.HTMLModel.AutoClosingTags[topElement.name].has(tag.name))
-        this._popElement(autocloseTag(topElement, tag.startOffset));
-      this._pushElement(tag);
-      return;
-    }
-
-    while (this._stack.length > 1 && this._stack.peekLast().name !== tag.name)
-      this._popElement(autocloseTag(this._stack.peekLast(), tag.startOffset));
-    if (this._stack.length === 1)
-      return;
-    this._popElement(tag);
-
-    /**
-     * @param {!FormatterWorker.HTMLModel.Element} element
-     * @param {number} offset
-     * @return {!FormatterWorker.HTMLModel.Tag}
-     */
-    function autocloseTag(element, offset) {
-      return new FormatterWorker.HTMLModel.Tag(element.name, offset, offset, new Map(), false, false);
-    }
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Tag} closeTag
-   */
-  _popElement(closeTag) {
-    const element = this._stack.pop();
-    element.closeTag = closeTag;
-  }
-
-  /**
-   * @param {!FormatterWorker.HTMLModel.Tag} openTag
-   */
-  _pushElement(openTag) {
-    const topElement = this._stack.peekLast();
-    const newElement = new FormatterWorker.HTMLModel.Element(openTag.name);
-    newElement.parent = topElement;
-    topElement.children.push(newElement);
-    newElement.openTag = openTag;
-    this._stack.push(newElement);
-  }
-
-  /**
-   * @return {?FormatterWorker.HTMLModel.Token}
-   */
-  peekToken() {
-    return this._tokenIndex < this._tokens.length ? this._tokens[this._tokenIndex] : null;
-  }
-
-  /**
-   * @return {?FormatterWorker.HTMLModel.Token}
-   */
-  nextToken() {
-    return this._tokens[this._tokenIndex++];
-  }
-
-  /**
-   * @return {!FormatterWorker.HTMLModel.Element}
-   */
-  document() {
-    return this._document;
-  }
-};
-
-FormatterWorker.HTMLModel.SelfClosingTags = new Set([
-  'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source',
-  'track', 'wbr'
-]);
-
-// @see https://www.w3.org/TR/html/syntax.html 8.1.2.4 Optional tags
-FormatterWorker.HTMLModel.AutoClosingTags = {
-  'head': new Set(['body']),
-  'li': new Set(['li']),
-  'dt': new Set(['dt', 'dd']),
-  'dd': new Set(['dt', 'dd']),
-  'p': new Set([
-    'address', 'article', 'aside', 'blockquote', 'div', 'dl',      'fieldset', 'footer', 'form',
-    'h1',      'h2',      'h3',    'h4',         'h5',  'h6',      'header',   'hgroup', 'hr',
-    'main',    'nav',     'ol',    'p',          'pre', 'section', 'table',    'ul'
-  ]),
-  'rb': new Set(['rb', 'rt', 'rtc', 'rp']),
-  'rt': new Set(['rb', 'rt', 'rtc', 'rp']),
-  'rtc': new Set(['rb', 'rtc', 'rp']),
-  'rp': new Set(['rb', 'rt', 'rtc', 'rp']),
-  'optgroup': new Set(['optgroup']),
-  'option': new Set(['option', 'optgroup']),
-  'colgroup': new Set(['colgroup']),
-  'thead': new Set(['tbody', 'tfoot']),
-  'tbody': new Set(['tbody', 'tfoot']),
-  'tfoot': new Set(['tbody']),
-  'tr': new Set(['tr']),
-  'td': new Set(['td', 'th']),
-  'th': new Set(['td', 'th']),
-};
-
-/** @enum {string} */
-FormatterWorker.HTMLModel.ParseState = {
-  Initial: 'Initial',
-  Tag: 'Tag',
-  AttributeName: 'AttributeName',
-  AttributeValue: 'AttributeValue'
-};
-
-/**
- * @unrestricted
- */
-FormatterWorker.HTMLModel.Token = class {
-  /**
-   * @param {string} value
-   * @param {!Set<string>} type
-   * @param {number} startOffset
-   * @param {number} endOffset
-   */
-  constructor(value, type, startOffset, endOffset) {
-    this.value = value;
-    this.type = type;
-    this.startOffset = startOffset;
-    this.endOffset = endOffset;
-  }
-};
-
-/**
- * @unrestricted
- */
-FormatterWorker.HTMLModel.Tag = class {
-  /**
-   * @param {string} name
-   * @param {number} startOffset
-   * @param {number} endOffset
-   * @param {!Map<string, string>} attributes
-   * @param {boolean} isOpenTag
-   * @param {boolean} selfClosingTag
-   */
-  constructor(name, startOffset, endOffset, attributes, isOpenTag, selfClosingTag) {
-    this.name = name;
-    this.startOffset = startOffset;
-    this.endOffset = endOffset;
-    this.attributes = attributes;
-    this.isOpenTag = isOpenTag;
-    this.selfClosingTag = selfClosingTag;
-  }
-};
-
-/**
- * @unrestricted
- */
-FormatterWorker.HTMLModel.Element = class {
-  /**
-   * @param {string} name
-   */
-  constructor(name) {
-    this.name = name;
-    this.children = [];
-    this.parent = null;
-    this.openTag = null;
-    this.closeTag = null;
-  }
-};
diff --git a/front_end/formatter_worker/IdentityFormatter.js b/front_end/formatter_worker/IdentityFormatter.js
deleted file mode 100644
index cc99fc2..0000000
--- a/front_end/formatter_worker/IdentityFormatter.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-FormatterWorker.IdentityFormatter = class {
-  /**
-   * @param {!FormatterWorker.FormattedContentBuilder} builder
-   */
-  constructor(builder) {
-    this._builder = builder;
-  }
-
-  /**
-   * @param {string} text
-   * @param {!Array<number>} lineEndings
-   * @param {number} fromOffset
-   * @param {number} toOffset
-   */
-  format(text, lineEndings, fromOffset, toOffset) {
-    const content = text.substring(fromOffset, toOffset);
-    this._builder.addToken(content, fromOffset);
-  }
-};
diff --git a/front_end/formatter_worker/JavaScriptFormatter.js b/front_end/formatter_worker/JavaScriptFormatter.js
deleted file mode 100644
index b702a6d..0000000
--- a/front_end/formatter_worker/JavaScriptFormatter.js
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-FormatterWorker.JavaScriptFormatter = class {
-  /**
-   * @param {!FormatterWorker.FormattedContentBuilder} builder
-   */
-  constructor(builder) {
-    this._builder = builder;
-  }
-
-  /**
-   * @param {string} text
-   * @param {!Array<number>} lineEndings
-   * @param {number} fromOffset
-   * @param {number} toOffset
-   */
-  format(text, lineEndings, fromOffset, toOffset) {
-    this._fromOffset = fromOffset;
-    this._toOffset = toOffset;
-    this._content = text.substring(this._fromOffset, this._toOffset);
-    this._lastLineNumber = 0;
-    this._tokenizer = new FormatterWorker.AcornTokenizer(this._content);
-    const ast = acorn.parse(this._content, {ranges: false, ecmaVersion: 8, preserveParens: true});
-    const walker = new FormatterWorker.ESTreeWalker(this._beforeVisit.bind(this), this._afterVisit.bind(this));
-    walker.walk(ast);
-  }
-
-  /**
-   * @param {?Acorn.TokenOrComment} token
-   * @param {string} format
-   */
-  _push(token, format) {
-    for (let i = 0; i < format.length; ++i) {
-      if (format[i] === 's') {
-        this._builder.addSoftSpace();
-      } else if (format[i] === 'S') {
-        this._builder.addHardSpace();
-      } else if (format[i] === 'n') {
-        this._builder.addNewLine();
-      } else if (format[i] === '>') {
-        this._builder.increaseNestingLevel();
-      } else if (format[i] === '<') {
-        this._builder.decreaseNestingLevel();
-      } else if (format[i] === 't') {
-        if (this._tokenizer.tokenLineStart() - this._lastLineNumber > 1)
-          this._builder.addNewLine(true);
-        this._lastLineNumber = this._tokenizer.tokenLineEnd();
-        this._builder.addToken(this._content.substring(token.start, token.end), this._fromOffset + token.start);
-      }
-    }
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   */
-  _beforeVisit(node) {
-    if (!node.parent)
-      return;
-    while (this._tokenizer.peekToken() && this._tokenizer.peekToken().start < node.start) {
-      const token = /** @type {!Acorn.TokenOrComment} */ (this._tokenizer.nextToken());
-      const format = this._formatToken(node.parent, token);
-      this._push(token, format);
-    }
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   */
-  _afterVisit(node) {
-    while (this._tokenizer.peekToken() && this._tokenizer.peekToken().start < node.end) {
-      const token = /** @type {!Acorn.TokenOrComment} */ (this._tokenizer.nextToken());
-      const format = this._formatToken(node, token);
-      this._push(token, format);
-    }
-    this._push(null, this._finishNode(node));
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @return {boolean}
-   */
-  _inForLoopHeader(node) {
-    const parent = node.parent;
-    if (!parent)
-      return false;
-    if (parent.type === 'ForStatement')
-      return node === parent.init || node === parent.test || node === parent.update;
-    if (parent.type === 'ForInStatement' || parent.type === 'ForOfStatement')
-      return node === parent.left || parent.right;
-    return false;
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @param {!Acorn.TokenOrComment} token
-   * @return {string}
-   */
-  _formatToken(node, token) {
-    const AT = FormatterWorker.AcornTokenizer;
-    if (AT.lineComment(token))
-      return 'tn';
-    if (AT.blockComment(token))
-      return 'tn';
-    if (node.type === 'ContinueStatement' || node.type === 'BreakStatement') {
-      return node.label && AT.keyword(token) ? 'ts' : 't';
-    } else if (node.type === 'Identifier') {
-      return 't';
-    } else if (node.type === 'ReturnStatement') {
-      if (AT.punctuator(token, ';'))
-        return 't';
-      return node.argument ? 'ts' : 't';
-    } else if (node.type === 'Property') {
-      if (AT.punctuator(token, ':'))
-        return 'ts';
-      return 't';
-    } else if (node.type === 'ArrayExpression') {
-      if (AT.punctuator(token, ','))
-        return 'ts';
-      return 't';
-    } else if (node.type === 'LabeledStatement') {
-      if (AT.punctuator(token, ':'))
-        return 'ts';
-    } else if (
-        node.type === 'LogicalExpression' || node.type === 'AssignmentExpression' || node.type === 'BinaryExpression') {
-      if (AT.punctuator(token) && !AT.punctuator(token, '()'))
-        return 'sts';
-    } else if (node.type === 'ConditionalExpression') {
-      if (AT.punctuator(token, '?:'))
-        return 'sts';
-    } else if (node.type === 'VariableDeclarator') {
-      if (AT.punctuator(token, '='))
-        return 'sts';
-    } else if (node.type === 'ObjectPattern') {
-      if (node.parent && node.parent.type === 'VariableDeclarator' && AT.punctuator(token, '{'))
-        return 'st';
-      if (AT.punctuator(token, ','))
-        return 'ts';
-    } else if (node.type === 'FunctionDeclaration') {
-      if (AT.punctuator(token, ',)'))
-        return 'ts';
-    } else if (node.type === 'FunctionExpression') {
-      if (AT.punctuator(token, ',)'))
-        return 'ts';
-      if (AT.keyword(token, 'function'))
-        return node.id ? 'ts' : 't';
-    } else if (node.type === 'WithStatement') {
-      if (AT.punctuator(token, ')'))
-        return node.body && node.body.type === 'BlockStatement' ? 'ts' : 'tn>';
-    } else if (node.type === 'SwitchStatement') {
-      if (AT.punctuator(token, '{'))
-        return 'tn>';
-      if (AT.punctuator(token, '}'))
-        return 'n<tn';
-      if (AT.punctuator(token, ')'))
-        return 'ts';
-    } else if (node.type === 'SwitchCase') {
-      if (AT.keyword(token, 'case'))
-        return 'n<ts';
-      if (AT.keyword(token, 'default'))
-        return 'n<t';
-      if (AT.punctuator(token, ':'))
-        return 'tn>';
-    } else if (node.type === 'VariableDeclaration') {
-      if (AT.punctuator(token, ',')) {
-        let allVariablesInitialized = true;
-        const declarations = /** @type {!Array.<!ESTree.Node>} */ (node.declarations);
-        for (let i = 0; i < declarations.length; ++i)
-          allVariablesInitialized = allVariablesInitialized && !!declarations[i].init;
-        return !this._inForLoopHeader(node) && allVariablesInitialized ? 'nSSts' : 'ts';
-      }
-    } else if (node.type === 'BlockStatement') {
-      if (AT.punctuator(token, '{'))
-        return node.body.length ? 'tn>' : 't';
-      if (AT.punctuator(token, '}'))
-        return node.body.length ? 'n<t' : 't';
-    } else if (node.type === 'CatchClause') {
-      if (AT.punctuator(token, ')'))
-        return 'ts';
-    } else if (node.type === 'ObjectExpression') {
-      if (!node.properties.length)
-        return 't';
-      if (AT.punctuator(token, '{'))
-        return 'tn>';
-      if (AT.punctuator(token, '}'))
-        return 'n<t';
-      if (AT.punctuator(token, ','))
-        return 'tn';
-    } else if (node.type === 'IfStatement') {
-      if (AT.punctuator(token, ')'))
-        return node.consequent && node.consequent.type === 'BlockStatement' ? 'ts' : 'tn>';
-
-      if (AT.keyword(token, 'else')) {
-        const preFormat = node.consequent && node.consequent.type === 'BlockStatement' ? 'st' : 'n<t';
-        let postFormat = 'n>';
-        if (node.alternate && (node.alternate.type === 'BlockStatement' || node.alternate.type === 'IfStatement'))
-          postFormat = 's';
-        return preFormat + postFormat;
-      }
-    } else if (node.type === 'CallExpression') {
-      if (AT.punctuator(token, ','))
-        return 'ts';
-    } else if (node.type === 'SequenceExpression' && AT.punctuator(token, ',')) {
-      return node.parent && node.parent.type === 'SwitchCase' ? 'ts' : 'tn';
-    } else if (node.type === 'ForStatement' || node.type === 'ForOfStatement' || node.type === 'ForInStatement') {
-      if (AT.punctuator(token, ';'))
-        return 'ts';
-      if (AT.keyword(token, 'in') || AT.identifier(token, 'of'))
-        return 'sts';
-
-      if (AT.punctuator(token, ')'))
-        return node.body && node.body.type === 'BlockStatement' ? 'ts' : 'tn>';
-    } else if (node.type === 'WhileStatement') {
-      if (AT.punctuator(token, ')'))
-        return node.body && node.body.type === 'BlockStatement' ? 'ts' : 'tn>';
-    } else if (node.type === 'DoWhileStatement') {
-      const blockBody = node.body && node.body.type === 'BlockStatement';
-      if (AT.keyword(token, 'do'))
-        return blockBody ? 'ts' : 'tn>';
-      if (AT.keyword(token, 'while'))
-        return blockBody ? 'sts' : 'n<ts';
-    } else if (node.type === 'ClassBody') {
-      if (AT.punctuator(token, '{'))
-        return 'stn>';
-      if (AT.punctuator(token, '}'))
-        return '<ntn';
-      return 't';
-    } else if (node.type === 'YieldExpression') {
-      return 't';
-    } else if (node.type === 'Super') {
-      return 't';
-    }
-    return AT.keyword(token) && !AT.keyword(token, 'this') ? 'ts' : 't';
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @return {string}
-   */
-  _finishNode(node) {
-    if (node.type === 'WithStatement') {
-      if (node.body && node.body.type !== 'BlockStatement')
-        return 'n<';
-    } else if (node.type === 'VariableDeclaration') {
-      if (!this._inForLoopHeader(node))
-        return 'n';
-    } else if (node.type === 'ForStatement' || node.type === 'ForOfStatement' || node.type === 'ForInStatement') {
-      if (node.body && node.body.type !== 'BlockStatement')
-        return 'n<';
-    } else if (node.type === 'BlockStatement') {
-      if (node.parent && node.parent.type === 'IfStatement' && node.parent.alternate && node.parent.consequent === node)
-        return '';
-      if (node.parent && node.parent.type === 'FunctionExpression' && node.parent.parent &&
-          node.parent.parent.type === 'Property')
-        return '';
-      if (node.parent && node.parent.type === 'FunctionExpression' && node.parent.parent &&
-          node.parent.parent.type === 'VariableDeclarator')
-        return '';
-      if (node.parent && node.parent.type === 'FunctionExpression' && node.parent.parent &&
-          node.parent.parent.type === 'CallExpression')
-        return '';
-      if (node.parent && node.parent.type === 'DoWhileStatement')
-        return '';
-      if (node.parent && node.parent.type === 'TryStatement' && node.parent.block === node)
-        return 's';
-      if (node.parent && node.parent.type === 'CatchClause' && node.parent.parent.finalizer)
-        return 's';
-      return 'n';
-    } else if (node.type === 'WhileStatement') {
-      if (node.body && node.body.type !== 'BlockStatement')
-        return 'n<';
-    } else if (node.type === 'IfStatement') {
-      if (node.alternate) {
-        if (node.alternate.type !== 'BlockStatement' && node.alternate.type !== 'IfStatement')
-          return '<';
-      } else if (node.consequent) {
-        if (node.consequent.type !== 'BlockStatement')
-          return '<';
-      }
-    } else if (
-        node.type === 'BreakStatement' || node.type === 'ContinueStatement' || node.type === 'ThrowStatement' ||
-        node.type === 'ReturnStatement' || node.type === 'ExpressionStatement') {
-      return 'n';
-    }
-    return '';
-  }
-};
diff --git a/front_end/formatter_worker/JavaScriptOutline.js b/front_end/formatter_worker/JavaScriptOutline.js
deleted file mode 100644
index 7648a92..0000000
--- a/front_end/formatter_worker/JavaScriptOutline.js
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @param {string} content
- */
-FormatterWorker.javaScriptOutline = function(content) {
-  const chunkSize = 100000;
-  let outlineChunk = [];
-  let lastReportedOffset = 0;
-
-  let ast;
-  try {
-    ast = acorn.parse(content, {ranges: false, ecmaVersion: 8});
-  } catch (e) {
-    ast = acorn.parse_dammit(content, {ranges: false, ecmaVersion: 8});
-  }
-
-  const textCursor = new TextUtils.TextCursor(content.computeLineEndings());
-  const walker = new FormatterWorker.ESTreeWalker(beforeVisit);
-  walker.walk(ast);
-  postMessage({chunk: outlineChunk, isLastChunk: true});
-
-  /**
-   * @param {!ESTree.Node} node
-   */
-  function beforeVisit(node) {
-    if (node.type === 'ClassDeclaration') {
-      reportClass(/** @type {!ESTree.Node} */ (node.id));
-    } else if (node.type === 'VariableDeclarator' && isClassNode(node.init)) {
-      reportClass(/** @type {!ESTree.Node} */ (node.id));
-    } else if (node.type === 'AssignmentExpression' && isNameNode(node.left) && isClassNode(node.right)) {
-      reportClass(/** @type {!ESTree.Node} */ (node.left));
-    } else if (node.type === 'Property' && isNameNode(node.key) && isClassNode(node.value)) {
-      reportClass(/** @type {!ESTree.Node} */ (node.key));
-    } else if (node.type === 'FunctionDeclaration') {
-      reportFunction(/** @type {!ESTree.Node} */ (node.id), node);
-    } else if (node.type === 'VariableDeclarator' && isFunctionNode(node.init)) {
-      reportFunction(/** @type {!ESTree.Node} */ (node.id), /** @type {!ESTree.Node} */ (node.init));
-    } else if (node.type === 'AssignmentExpression' && isNameNode(node.left) && isFunctionNode(node.right)) {
-      reportFunction(/** @type {!ESTree.Node} */ (node.left), /** @type {!ESTree.Node} */ (node.right));
-    } else if (
-        (node.type === 'MethodDefinition' || node.type === 'Property') && isNameNode(node.key) &&
-        isFunctionNode(node.value)) {
-      const namePrefix = [];
-      if (node.kind === 'get' || node.kind === 'set')
-        namePrefix.push(node.kind);
-      if (node.static)
-        namePrefix.push('static');
-      reportFunction(node.key, node.value, namePrefix.join(' '));
-    }
-  }
-
-  /**
-   * @param {!ESTree.Node} nameNode
-   */
-  function reportClass(nameNode) {
-    const name = 'class ' + stringifyNameNode(nameNode);
-    textCursor.advance(nameNode.start);
-    addOutlineItem({
-      name: name,
-      line: textCursor.lineNumber(),
-      column: textCursor.columnNumber(),
-    });
-  }
-
-  /**
-   * @param {!ESTree.Node} nameNode
-   * @param {!ESTree.Node} functionNode
-   * @param {string=} namePrefix
-   */
-  function reportFunction(nameNode, functionNode, namePrefix) {
-    let name = stringifyNameNode(nameNode);
-    if (functionNode.generator)
-      name = '*' + name;
-    if (namePrefix)
-      name = namePrefix + ' ' + name;
-    if (functionNode.async)
-      name = 'async ' + name;
-
-    textCursor.advance(nameNode.start);
-    addOutlineItem({
-      name: name,
-      line: textCursor.lineNumber(),
-      column: textCursor.columnNumber(),
-      arguments: stringifyArguments(/** @type {!Array<!ESTree.Node>} */ (functionNode.params))
-    });
-  }
-
-  /**
-   * @param {(!ESTree.Node|undefined)} node
-   * @return {boolean}
-   */
-  function isNameNode(node) {
-    if (!node)
-      return false;
-    if (node.type === 'MemberExpression')
-      return !node.computed && node.property.type === 'Identifier';
-    return node.type === 'Identifier';
-  }
-
-  /**
-   * @param {(!ESTree.Node|undefined)} node
-   * @return {boolean}
-   */
-  function isFunctionNode(node) {
-    if (!node)
-      return false;
-    return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';
-  }
-
-  /**
-   * @param {(!ESTree.Node|undefined)} node
-   * @return {boolean}
-   */
-  function isClassNode(node) {
-    return !!node && node.type === 'ClassExpression';
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @return {string}
-   */
-  function stringifyNameNode(node) {
-    if (node.type === 'MemberExpression')
-      node = /** @type {!ESTree.Node} */ (node.property);
-    console.assert(node.type === 'Identifier', 'Cannot extract identifier from unknown type: ' + node.type);
-    return /** @type {string} */ (node.name);
-  }
-
-  /**
-   * @param {!Array<!ESTree.Node>} params
-   * @return {string}
-   */
-  function stringifyArguments(params) {
-    const result = [];
-    for (const param of params) {
-      if (param.type === 'Identifier')
-        result.push(param.name);
-      else if (param.type === 'RestElement' && param.argument.type === 'Identifier')
-        result.push('...' + param.argument.name);
-      else
-        console.error('Error: unexpected function parameter type: ' + param.type);
-    }
-    return '(' + result.join(', ') + ')';
-  }
-
-  /**
-   * @param {{name: string, line: number, column: number, arguments: (string|undefined)}} item
-   */
-  function addOutlineItem(item) {
-    outlineChunk.push(item);
-    if (textCursor.offset() - lastReportedOffset < chunkSize)
-      return;
-    postMessage({chunk: outlineChunk, isLastChunk: false});
-    outlineChunk = [];
-    lastReportedOffset = textCursor.offset();
-  }
-};
diff --git a/front_end/formatter_worker/RelaxedJSONParser.js b/front_end/formatter_worker/RelaxedJSONParser.js
deleted file mode 100644
index cf08019..0000000
--- a/front_end/formatter_worker/RelaxedJSONParser.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-FormatterWorker.RelaxedJSONParser = {};
-
-/** @enum {string} */
-FormatterWorker.RelaxedJSONParser.States = {
-  ExpectKey: 'ExpectKey',
-  ExpectValue: 'ExpectValue'
-};
-
-/** @enum {*} */
-FormatterWorker.RelaxedJSONParser.Keywords = {
-  'NaN': NaN,
-  'true': true,
-  'false': false,
-  'Infinity': Infinity,
-  'undefined': undefined,
-  'null': null
-};
-
-/**
- * @param {string} content
- * @return {*}
- */
-FormatterWorker.RelaxedJSONParser.parse = function(content) {
-  const Keywords = FormatterWorker.RelaxedJSONParser.Keywords;
-  const States = FormatterWorker.RelaxedJSONParser.States;
-  content = '(' + content + ')';
-
-  let root;
-  try {
-    root = acorn.parse(content, {});
-  } catch (e) {
-    return null;
-  }
-
-  const walker = new FormatterWorker.ESTreeWalker(beforeVisit, afterVisit);
-
-  const rootTip = [];
-
-  /** @type {!Array.<!FormatterWorker.RelaxedJSONParser.Context>} */
-  const stack = [];
-
-  let stackData = /** @type {!FormatterWorker.RelaxedJSONParser.Context} */ (
-      {key: 0, tip: rootTip, state: States.ExpectValue, parentIsArray: true});
-
-  walker.setWalkNulls(true);
-  let hasExpression = false;
-
-  walker.walk(root);
-
-  if (hasExpression)
-    return null;
-  return rootTip.length ? rootTip[0] : null;
-
-  /**
-   * @param {!FormatterWorker.RelaxedJSONParser.Context} newStack
-   */
-  function pushStack(newStack) {
-    stack.push(stackData);
-    stackData = newStack;
-  }
-
-  function popStack() {
-    stackData = stack.pop();
-  }
-
-  /**
-   * @param {*} value
-   */
-  function applyValue(value) {
-    stackData.tip[stackData.key] = value;
-    if (stackData.parentIsArray)
-      stackData.key++;
-    else
-      stackData.state = null;
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @return {!Object|undefined}
-   */
-  function beforeVisit(node) {
-    switch (node.type) {
-      case 'ObjectExpression': {
-        const newTip = {};
-        applyValue(newTip);
-
-        pushStack(/** @type {!FormatterWorker.RelaxedJSONParser.Context} */ (
-            {key: null, tip: newTip, state: null, parentIsArray: false}));
-        break;
-      }
-      case 'ArrayExpression': {
-        const newTip = [];
-        applyValue(newTip);
-
-        pushStack(/** @type {!FormatterWorker.RelaxedJSONParser.Context} */ (
-            {key: 0, tip: newTip, state: States.ExpectValue, parentIsArray: true}));
-        break;
-      }
-      case 'Property':
-        stackData.state = States.ExpectKey;
-        break;
-      case 'Literal':
-        if (stackData.state === States.ExpectKey) {
-          stackData.key = node.value;
-          stackData.state = States.ExpectValue;
-        } else if (stackData.state === States.ExpectValue) {
-          applyValue(extractValue(node));
-          return FormatterWorker.ESTreeWalker.SkipSubtree;
-        }
-        break;
-      case 'Identifier':
-        if (stackData.state === States.ExpectKey) {
-          stackData.key = /** @type {string} */ (node.name);
-          stackData.state = States.ExpectValue;
-        } else if (stackData.state === States.ExpectValue) {
-          applyValue(extractValue(node));
-          return FormatterWorker.ESTreeWalker.SkipSubtree;
-        }
-        break;
-      case 'UnaryExpression':
-        if (stackData.state === States.ExpectValue) {
-          applyValue(extractValue(node));
-          return FormatterWorker.ESTreeWalker.SkipSubtree;
-        }
-        break;
-      case 'Program':
-      case 'ExpressionStatement':
-        break;
-      default:
-        if (stackData.state === States.ExpectValue)
-          applyValue(extractValue(node));
-        return FormatterWorker.ESTreeWalker.SkipSubtree;
-    }
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   */
-  function afterVisit(node) {
-    if (node.type === 'ObjectExpression' || node.type === 'ArrayExpression')
-      popStack();
-  }
-
-  /**
-   * @param {!ESTree.Node} node
-   * @return {*}
-   */
-  function extractValue(node) {
-    let isNegative = false;
-    const originalNode = node;
-    let value;
-    if (node.type === 'UnaryExpression' && (node.operator === '-' || node.operator === '+')) {
-      if (node.operator === '-')
-        isNegative = true;
-      node = /** @type {!ESTree.Node} */ (node.argument);
-    }
-
-    if (node.type === 'Literal') {
-      value = node.value;
-    } else if (node.type === 'Identifier' && Keywords.hasOwnProperty(node.name)) {
-      value = Keywords[node.name];
-    } else {
-      hasExpression = true;
-      return content.substring(originalNode.start, originalNode.end);
-    }
-
-    if (isNegative) {
-      if (typeof value !== 'number') {
-        hasExpression = true;
-        return content.substring(originalNode.start, originalNode.end);
-      }
-      value = -(value);
-    }
-    return value;
-  }
-};
-
-/**
- * @typedef {!{key: (number|string), tip: (!Array|!Object), state: ?FormatterWorker.RelaxedJSONParser.States, parentIsArray: boolean}}
- */
-FormatterWorker.RelaxedJSONParser.Context;
diff --git a/front_end/formatter_worker/acorn/AUTHORS b/front_end/formatter_worker/acorn/AUTHORS
deleted file mode 100644
index 86c8d9b..0000000
--- a/front_end/formatter_worker/acorn/AUTHORS
+++ /dev/null
@@ -1,75 +0,0 @@
-List of Acorn contributors. Updated before every release.
-
-Adrian Heine
-Adrian Rakovsky
-Alistair Braidwood
-Amila Welihinda
-Andres Suarez
-Angelo
-Aparajita Fishman
-Arian Stolwijk
-Artem Govorov
-Boopesh Mahendran
-Bradley Heinz
-Brandon Mills
-Charles Hughes
-Charmander
-Conrad Irwin
-Daniel Tschinder
-David Bonnet
-Domenico Matteo
-ehmicky
-Felix Maier
-Forbes Lindesay
-Gilad Peleg
-impinball
-Ingvar Stepanyan
-Jackson Ray Hamilton
-Jesse McCarthy
-Jiaxing Wang
-Joel Kemp
-Johannes Herr
-John-David Dalton
-Jordan Klassen
-Jürg Lehni
-Kai Cataldo
-keeyipchan
-Keheliya Gallaba
-Kevin Irish
-Kevin Kwok
-krator
-laosb
-Marek
-Marijn Haverbeke
-Martin Carlberg
-Mat Garcia
-Mathias Bynens
-Mathieu 'p01' Henri
-Matthew Bastien
-Max Schaefer
-Max Zerzouri
-Mihai Bazon
-Mike Rennie
-naoh
-Nicholas C. Zakas
-Nick Fitzgerald
-Olivier Thomann
-Oskar Schöldström
-Paul Harper
-Peter Rust
-PlNG
-Prayag Verma
-ReadmeCritic
-r-e-d
-Richard Gibson
-Rich Harris
-Sebastian McKenzie
-Shahar Soel
-Sheel Bedi
-Simen Bekkhus
-Teddy Katz
-Timothy Gu
-Toru Nagashima
-Victor Homyakov
-Wexpo Lyu
-zsjforcn
diff --git a/front_end/formatter_worker/acorn/LICENSE b/front_end/formatter_worker/acorn/LICENSE
deleted file mode 100644
index 2c0632b..0000000
--- a/front_end/formatter_worker/acorn/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2012-2018 by various contributors (see AUTHORS)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/front_end/formatter_worker/acorn/acorn.js b/front_end/formatter_worker/acorn/acorn.js
deleted file mode 100644
index b8e0efe..0000000
--- a/front_end/formatter_worker/acorn/acorn.js
+++ /dev/null
@@ -1,5337 +0,0 @@
-// clang-format off
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
-  typeof define === 'function' && define.amd ? define(['exports'], factory) :
-  (factory((global.acorn = {})));
-}(this, (function (exports) { 'use strict';
-
-// Reserved word lists for various dialects of the language
-
-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"
-};
-
-// 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 + " const class extends export import super"
-};
-
-var keywordRelationalOperator = /^in(stanceof)?$/;
-
-// ## 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 = "\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\u0860-\u086a\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\u09fc\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-\u312e\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fea\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\u0afa-\u0aff\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\u0d00-\u0d03\u0d3b\u0d3c\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\u1cf7-\u1cf9\u1dc0-\u1df9\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 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,14,29,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,257,0,11,39,8,0,22,0,12,39,3,3,55,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,698,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,1,31,6124,20,754,9486,286,82,395,2309,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,15,7472,3104,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,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,19719,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 }
-    pos += set[i + 1];
-    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)
-}
-
-// 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)
-}
-
-// ## 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).
-//
-// 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).
-//
-// `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)
-}
-
-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
-}
-
-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 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) {
-  this.start = start;
-  this.end = end;
-  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.
-
-function getLineInfo(input, offset) {
-  for (var line = 1, cur = 0;;) {
-    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)
-    }
-  }
-}
-
-// 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, 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
-  // trailing commas.
-  onTrailingComma: null,
-  // By default, reserved words are only enforced if ecmaVersion >= 5.
-  // Set `allowReserved` to a boolean value to explicitly turn this on
-  // an off. When this option has the value "never", reserved words
-  // and keywords can also not be used as property names.
-  allowReserved: null,
-  // When enabled, a return at the top level is not considered an
-  // error.
-  allowReturnOutsideFunction: false,
-  // When enabled, import/export statements are not constrained to
-  // appearing at the top of the program.
-  allowImportExportEverywhere: false,
-  // When enabled, hashbang directive in the beginning of file
-  // is allowed and treated as a line comment.
-  allowHashBang: false,
-  // When `locations` is on, `loc` properties holding objects with
-  // `start` and `end` properties in `{line, column}` form (with
-  // line being 1-based and column 0-based) will be attached to the
-  // nodes.
-  locations: false,
-  // A function can be passed as `onToken` option, which will
-  // cause Acorn to call that function with object in the same
-  // format as tokens returned from `tokenizer().getToken()`. Note
-  // that you are not allowed to call the parser from the
-  // callback—that will corrupt its internal state.
-  onToken: null,
-  // A function can be passed as `onComment` option, which will
-  // cause Acorn to call that function with `(block, text, start,
-  // end)` parameters whenever a comment is skipped. `block` is a
-  // boolean indicating whether this is a block (`/* */`) comment,
-  // `text` is the content of the comment, and `start` and `end` are
-  // character offsets that denote the start and end of the comment.
-  // When the `locations` option is on, two more parameters are
-  // passed, the full `{line, column}` locations of the start and
-  // end of the comments. Note that you are not allowed to call the
-  // parser from the callback—that will corrupt its internal state.
-  onComment: null,
-  // Nodes have their start and end characters offsets recorded in
-  // `start` and `end` properties (directly on the node, rather than
-  // the `loc` object, which holds line/column data. To also add a
-  // [semi-standardized][range] `range` property holding a `[start,
-  // end]` array with the same numbers, set the `ranges` option to
-  // `true`.
-  //
-  // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
-  ranges: false,
-  // It is possible to parse multiple files into a single AST by
-  // passing the tree produced by parsing the first file as
-  // `program` option in subsequent parses. This will add the
-  // toplevel forms of the parsed file to the `Program` (top) node
-  // of an existing parse tree.
-  program: null,
-  // When `locations` is on, you can pass this to record the source
-  // file in every node's `loc` object.
-  sourceFile: null,
-  // This value, if given, is stored in every node, whether
-  // `locations` is on or off.
-  directSourceFile: null,
-  // When enabled, parenthesized expressions are represented by
-  // (non-standard) ParenthesizedExpression nodes
-  preserveParens: false,
-  plugins: {}
-};
-
-// Interpret and default an options object
-
-function getOptions(opts) {
-  var 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) {
-    var comment = {
-      type: block ? "Block" : "Line",
-      value: text,
-      start: start,
-      end: 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, "|") + ")$")
-}
-
-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();
-
-  // For RegExp validation
-  this.regexpState = null;
-};
-
-// 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
-
-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) {
-  if (this.type === type) {
-    this.next();
-    return true
-  } else {
-    return false
-  }
-};
-
-// Tests whether parsed token is a contextual keyword.
-
-pp.isContextual = function(name) {
-  return this.type === types.name && this.value === name && !this.containsEsc
-};
-
-// Consumes contextual keyword if possible.
-
-pp.eatContextual = function(name) {
-  if (!this.isContextual(name)) { return false }
-  this.next();
-  return true
-};
-
-// Asserts that following token is given contextual keyword.
-
-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 === 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
-  }
-};
-
-// 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(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); }
-    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) {
-  this.eat(type) || this.unexpected();
-};
-
-// Raise an unexpected token error.
-
-pp.unexpected = function(pos) {
-  this.raise(pos != null ? pos : this.start, "Unexpected token");
-};
-
-function DestructuringErrors() {
-  this.shorthandAssign =
-  this.trailingComma =
-  this.parenthesizedAssign =
-  this.parenthesizedBind =
-  this.doubleProto =
-    -1;
-}
-
-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) {
-  if (!refDestructuringErrors) { return false }
-  var shorthandAssign = refDestructuringErrors.shorthandAssign;
-  var doubleProto = refDestructuringErrors.doubleProto;
-  if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
-  if (shorthandAssign >= 0)
-    { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
-  if (doubleProto >= 0)
-    { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
-};
-
-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$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);
-  }
-  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"};
-var switchLabel = {kind: "switch"};
-
-pp$1.isLet = function() {
-  if (this.options.ecmaVersion < 6 || !this.isContextual("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 (!keywordRelationalOperator.test(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.options.ecmaVersion < 8 || !this.isContextual("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$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 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:
-    if (this.isAsyncFunction()) {
-      if (!declaration) { this.unexpected(); }
-      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(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.
-  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$1.parseDebuggerStatement = function(node) {
-  this.next();
-  this.semicolon();
-  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(types._while);
-  node.test = this.parseParenExpression();
-  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$1.parseForStatement = function(node) {
-  this.next();
-  var awaitAt = (this.options.ecmaVersion >= 9 && this.inAsync && this.eatContextual("await")) ? this.lastTokStart : -1;
-  this.labels.push(loopLabel);
-  this.enterLexicalScope();
-  this.expect(types.parenL);
-  if (this.type === types.semi) {
-    if (awaitAt > -1) { this.unexpected(awaitAt); }
-    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$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)) {
-      if (this.options.ecmaVersion >= 9) {
-        if (this.type === types._in) {
-          if (awaitAt > -1) { this.unexpected(awaitAt); }
-        } else { node.await = awaitAt > -1; }
-      }
-      return this.parseForIn(node, init$1)
-    }
-    if (awaitAt > -1) { this.unexpected(awaitAt); }
-    return this.parseFor(node, init$1)
-  }
-  var refDestructuringErrors = new DestructuringErrors;
-  var init = this.parseExpression(true, refDestructuringErrors);
-  if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
-    if (this.options.ecmaVersion >= 9) {
-      if (this.type === types._in) {
-        if (awaitAt > -1) { this.unexpected(awaitAt); }
-      } else { node.await = awaitAt > -1; }
-    }
-    this.toAssignable(init, false, refDestructuringErrors);
-    this.checkLVal(init);
-    return this.parseForIn(node, init)
-  } else {
-    this.checkExpressionErrors(refDestructuringErrors, true);
-  }
-  if (awaitAt > -1) { this.unexpected(awaitAt); }
-  return this.parseFor(node, init)
-};
-
-pp$1.parseFunctionStatement = function(node, isAsync) {
-  this.next();
-  return this.parseFunction(node, true, false, isAsync)
-};
-
-pp$1.parseIfStatement = function(node) {
-  this.next();
-  node.test = this.parseParenExpression();
-  // allow function declarations in branches, but only in non-strict mode
-  node.consequent = this.parseStatement(!this.strict && this.type == types._function);
-  node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type == types._function) : 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(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(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.
-
-  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$1.next();
-      if (isCase) {
-        cur.test = this$1.parseExpression();
-      } else {
-        if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); }
-        sawDefault = true;
-        cur.test = null;
-      }
-      this$1.expect(types.colon);
-    } else {
-      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$1.parseThrowStatement = function(node) {
-  this.next();
-  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")
-};
-
-// Reused empty array added for node fields that are always empty.
-
-var empty = [];
-
-pp$1.parseTryStatement = function(node) {
-  this.next();
-  node.block = this.parseBlock();
-  node.handler = null;
-  if (this.type === types._catch) {
-    var clause = this.startNode();
-    this.next();
-    this.expect(types.parenL);
-    clause.param = this.parseBindingAtom();
-    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(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$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$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$1.parseEmptyStatement = function(node) {
-  this.next();
-  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$1 = this$1.labels[i];
-    if (label$1.statementStart == node.start) {
-      // Update information about previous labels on this node
-      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$1.parseExpressionStatement = function(node, expr) {
-  node.expression = expr;
-  this.semicolon();
-  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$1.parseBlock = function(createNewLexicalScope) {
-  var this$1 = this;
-  if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
-
-  var node = this.startNode();
-  node.body = [];
-  this.expect(types.braceL);
-  if (createNewLexicalScope) {
-    this.enterLexicalScope();
-  }
-  while (!this.eat(types.braceR)) {
-    var stmt = this$1.parseStatement(true);
-    node.body.push(stmt);
-  }
-  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$1.parseFor = function(node, init) {
-  node.init = init;
-  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")
-};
-
-// Parse a `for`/`in` and `for`/`of` loop, which are almost
-// same from parser's perspective.
-
-pp$1.parseForIn = function(node, init) {
-  var type = this.type === types._in ? "ForInStatement" : "ForOfStatement";
-  this.next();
-  if (type == "ForInStatement") {
-    if (init.type === "AssignmentPattern" ||
-      (init.type === "VariableDeclaration" && init.declarations[0].init != null &&
-       (this.strict || init.declarations[0].id.type !== "Identifier")))
-      { this.raise(init.start, "Invalid assignment in for-in loop head"); }
-  }
-  node.left = init;
-  node.right = type == "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign();
-  this.expect(types.parenR);
-  this.exitLexicalScope();
-  node.body = this.parseStatement(false);
-  this.labels.pop();
-  return this.finishNode(node, type)
-};
-
-// Parse a list of variable declarations.
-
-pp$1.parseVar = function(node, isFor, kind) {
-  var this$1 = this;
-
-  node.declarations = [];
-  node.kind = kind;
-  for (;;) {
-    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$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$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {
-  this.initFunction(node);
-  if (this.options.ecmaVersion >= 9 || 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);
-
-  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$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(types.braceL);
-  while (!this.eat(types.braceR)) {
-    var member = this$1.parseClassMember(classBody);
-    if (member && member.type === "MethodDefinition" && member.kind === "constructor") {
-      if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); }
-      hadConstructor = true;
-    }
-  }
-  node.body = this.finishNode(classBody, "ClassBody");
-  return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
-};
-
-pp$1.parseClassMember = function(classBody) {
-  var this$1 = this;
-
-  if (this.eat(types.semi)) { return null }
-
-  var method = this.startNode();
-  var tryContextual = function (k, noLineBreak) {
-    if ( noLineBreak === void 0 ) noLineBreak = false;
-
-    var start = this$1.start, startLoc = this$1.startLoc;
-    if (!this$1.eatContextual(k)) { return false }
-    if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
-    if (method.key) { this$1.unexpected(); }
-    method.computed = false;
-    method.key = this$1.startNodeAt(start, startLoc);
-    method.key.name = k;
-    this$1.finishNode(method.key, "Identifier");
-    return false
-  };
-
-  method.kind = "method";
-  method.static = tryContextual("static");
-  var isGenerator = this.eat(types.star);
-  var isAsync = false;
-  if (!isGenerator) {
-    if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
-      isAsync = true;
-      isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
-    } else if (tryContextual("get")) {
-      method.kind = "get";
-    } else if (tryContextual("set")) {
-      method.kind = "set";
-    }
-  }
-  if (!method.key) { this.parsePropertyName(method); }
-  var key = method.key;
-  if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
-      key.type === "Literal" && key.value === "constructor")) {
-    if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
-    if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
-    if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
-    method.kind = "constructor";
-  } else if (method.static && key.type === "Identifier" && key.name === "prototype") {
-    this.raise(key.start, "Classes may not have a static property named prototype");
-  }
-  this.parseClassMethod(classBody, method, isGenerator, isAsync);
-  if (method.kind === "get" && method.value.params.length !== 0)
-    { this.raiseRecoverable(method.value.start, "getter should have no params"); }
-  if (method.kind === "set" && method.value.params.length !== 1)
-    { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
-  if (method.kind === "set" && method.value.params[0].type === "RestElement")
-    { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
-  return method
-};
-
-pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {
-  method.value = this.parseMethod(isGenerator, isAsync);
-  classBody.body.push(this.finishNode(method, "MethodDefinition"));
-};
-
-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$1.parseExport = function(node, exports) {
-  var this$1 = this;
-
-  this.next();
-  // export * from '...'
-  if (this.eat(types.star)) {
-    this.expectContextual("from");
-    if (this.type !== types.string) { this.unexpected(); }
-    node.source = this.parseExprAtom();
-    this.semicolon();
-    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 '...']
-    node.declaration = null;
-    node.specifiers = this.parseExportSpecifiers(exports);
-    if (this.eatContextual("from")) {
-      if (this.type !== types.string) { this.unexpected(); }
-      node.source = this.parseExprAtom();
-    } else {
-      // check for keywords used as local names
-      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$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);
-      } }
-  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 == "Property")
-    { this.checkPatternExport(exports, pat.value); }
-  else if (type == "AssignmentPattern")
-    { this.checkPatternExport(exports, pat.left); }
-  else if (type == "RestElement")
-    { this.checkPatternExport(exports, pat.argument); }
-  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$1.parseExportSpecifiers = function(exports) {
-  var this$1 = this;
-
-  var nodes = [], first = true;
-  // export { x, y as z } [from '...']
-  this.expect(types.braceL);
-  while (!this.eat(types.braceR)) {
-    if (!first) {
-      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$1.parseImport = function(node) {
-  this.next();
-  // import '...'
-  if (this.type === types.string) {
-    node.specifiers = empty;
-    node.source = this.parseExprAtom();
-  } else {
-    node.specifiers = this.parseImportSpecifiers();
-    this.expectContextual("from");
-    node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
-  }
-  this.semicolon();
-  return this.finishNode(node, "ImportDeclaration")
-};
-
-// Parses a comma-separated list of module imports.
-
-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, "let");
-    nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
-    if (!this.eat(types.comma)) { return nodes }
-  }
-  if (this.type === types.star) {
-    var node$1 = this.startNode();
-    this.next();
-    this.expectContextual("as");
-    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$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, refDestructuringErrors) {
-  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":
-    case "RestElement":
-      break
-
-    case "ObjectExpression":
-      node.type = "ObjectPattern";
-      if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
-      for (var i = 0, list = node.properties; i < list.length; i += 1) {
-        var prop = list[i];
-
-      this$1.toAssignable(prop, isBinding);
-        // Early error:
-        //   AssignmentRestProperty[Yield, Await] :
-        //     `...` DestructuringAssignmentTarget[Yield, Await]
-        //
-        //   It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
-        if (
-          prop.type === "RestElement" &&
-          (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
-        ) {
-          this$1.raise(prop.argument.start, "Unexpected token");
-        }
-      }
-      break
-
-    case "Property":
-      // AssignmentProperty has type == "Property"
-      if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
-      this.toAssignable(node.value, isBinding);
-      break
-
-    case "ArrayExpression":
-      node.type = "ArrayPattern";
-      if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
-      this.toAssignableList(node.elements, isBinding);
-      break
-
-    case "SpreadElement":
-      node.type = "RestElement";
-      this.toAssignable(node.argument, isBinding);
-      if (node.argument.type === "AssignmentPattern")
-        { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
-      break
-
-    case "AssignmentExpression":
-      if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
-      node.type = "AssignmentPattern";
-      delete node.operator;
-      this.toAssignable(node.left, isBinding);
-      // falls through to AssignmentPattern
-
-    case "AssignmentPattern":
-      break
-
-    case "ParenthesizedExpression":
-      this.toAssignable(node.expression, isBinding);
-      break
-
-    case "MemberExpression":
-      if (!isBinding) { break }
-
-    default:
-      this.raise(node.start, "Assigning to rvalue");
-    }
-  } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
-  return node
-};
-
-// Convert list of expression atoms to binding list.
-
-pp$2.toAssignableList = function(exprList, isBinding) {
-  var this$1 = this;
-
-  var end = exprList.length;
-  for (var i = 0; i < end; i++) {
-    var elt = exprList[i];
-    if (elt) { this$1.toAssignable(elt, isBinding); }
-  }
-  if (end) {
-    var last = exprList[end - 1];
-    if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
-      { this.unexpected(last.argument.start); }
-  }
-  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, "Binding 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, bindingType, checkClashes);
-  }
-    break
-
-  case "Property":
-    // AssignmentProperty has type == "Property"
-    this.checkLVal(expr.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, refDestructuringErrors) {
-  if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
-    { return }
-  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) {
-        if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; }
-        // Backwards-compat kludge. Can be removed in version 6.0
-        else { 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) {
-    var node = this.startNodeAt(startPos, startLoc);
-    node.operator = this.value;
-    node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;
-    if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }
-    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() && this.input.slice(base.start, base.end) === "async";
-  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, containsEsc = this.containsEsc;
-    var id = this.parseIdent(this.type !== types.name);
-    if (this.options.ecmaVersion >= 8 && !containsEsc && 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 && !containsEsc) {
-        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;
-    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 {
-        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();
-      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;
-    var containsEsc = this.containsEsc;
-    node.property = this.parseIdent(true);
-    if (node.property.name !== "target" || containsEsc)
-      { 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 || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&
-    !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);
-    if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); }
-    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 >= 9 && this.eat(types.ellipsis)) {
-    if (isPattern) {
-      prop.argument = this.parseIdent(false);
-      if (this.type === types.comma) {
-        this.raise(this.start, "Comma is not permitted after the rest element");
-      }
-      return this.finishNode(prop, "RestElement")
-    }
-    // To disallow parenthesized identifier via `this.toAssignable()`.
-    if (this.type === types.parenL && refDestructuringErrors) {
-      if (refDestructuringErrors.parenthesizedAssign < 0) {
-        refDestructuringErrors.parenthesizedAssign = this.start;
-      }
-      if (refDestructuringErrors.parenthesizedBind < 0) {
-        refDestructuringErrors.parenthesizedBind = this.start;
-      }
-    }
-    // Parse argument.
-    prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
-    // To disallow trailing comma via `this.toAssignable()`.
-    if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
-      refDestructuringErrors.trailingComma = this.start;
-    }
-    // Finish
-    return this.finishNode(prop, "SpreadElement")
-  }
-  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); }
-  }
-  var containsEsc = this.containsEsc;
-  this.parsePropertyName(prop);
-  if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
-    isAsync = true;
-    isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
-    this.parsePropertyName(prop, refDestructuringErrors);
-  } else {
-    isAsync = false;
-  }
-  this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
-  return this.finishNode(prop, "Property")
-};
-
-pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
-  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 && !containsEsc &&
-             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)) {
-    if (!this.inAsync && name === "await")
-      { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); }
-    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/acornjs/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
-
-var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
-  this.token = token;
-  this.isExpr = !!isExpr;
-  this.preserveSpace = !!preserveSpace;
-  this.override = override;
-  this.generator = !!generator;
-};
-
-var types$1 = {
-  b_stat: new TokContext("{", false),
-  b_expr: 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.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
-
-types.parenR.updateContext = types.braceR.updateContext = function() {
-  if (this.context.length == 1) {
-    this.exprAllowed = true;
-    return
-  }
-  var out = this.context.pop();
-  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;
-};
-
-types.dollarBraceL.updateContext = function() {
-  this.context.push(types$1.b_tmpl);
-  this.exprAllowed = true;
-};
-
-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;
-};
-
-types.incDec.updateContext = function() {
-  // tokExprAllowed stays unchanged
-};
-
-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;
-};
-
-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;
-};
-
-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;
-};
-
-var data = {
-  "$LONE": [
-    "ASCII",
-    "ASCII_Hex_Digit",
-    "AHex",
-    "Alphabetic",
-    "Alpha",
-    "Any",
-    "Assigned",
-    "Bidi_Control",
-    "Bidi_C",
-    "Bidi_Mirrored",
-    "Bidi_M",
-    "Case_Ignorable",
-    "CI",
-    "Cased",
-    "Changes_When_Casefolded",
-    "CWCF",
-    "Changes_When_Casemapped",
-    "CWCM",
-    "Changes_When_Lowercased",
-    "CWL",
-    "Changes_When_NFKC_Casefolded",
-    "CWKCF",
-    "Changes_When_Titlecased",
-    "CWT",
-    "Changes_When_Uppercased",
-    "CWU",
-    "Dash",
-    "Default_Ignorable_Code_Point",
-    "DI",
-    "Deprecated",
-    "Dep",
-    "Diacritic",
-    "Dia",
-    "Emoji",
-    "Emoji_Component",
-    "Emoji_Modifier",
-    "Emoji_Modifier_Base",
-    "Emoji_Presentation",
-    "Extender",
-    "Ext",
-    "Grapheme_Base",
-    "Gr_Base",
-    "Grapheme_Extend",
-    "Gr_Ext",
-    "Hex_Digit",
-    "Hex",
-    "IDS_Binary_Operator",
-    "IDSB",
-    "IDS_Trinary_Operator",
-    "IDST",
-    "ID_Continue",
-    "IDC",
-    "ID_Start",
-    "IDS",
-    "Ideographic",
-    "Ideo",
-    "Join_Control",
-    "Join_C",
-    "Logical_Order_Exception",
-    "LOE",
-    "Lowercase",
-    "Lower",
-    "Math",
-    "Noncharacter_Code_Point",
-    "NChar",
-    "Pattern_Syntax",
-    "Pat_Syn",
-    "Pattern_White_Space",
-    "Pat_WS",
-    "Quotation_Mark",
-    "QMark",
-    "Radical",
-    "Regional_Indicator",
-    "RI",
-    "Sentence_Terminal",
-    "STerm",
-    "Soft_Dotted",
-    "SD",
-    "Terminal_Punctuation",
-    "Term",
-    "Unified_Ideograph",
-    "UIdeo",
-    "Uppercase",
-    "Upper",
-    "Variation_Selector",
-    "VS",
-    "White_Space",
-    "space",
-    "XID_Continue",
-    "XIDC",
-    "XID_Start",
-    "XIDS"
-  ],
-  "General_Category": [
-    "Cased_Letter",
-    "LC",
-    "Close_Punctuation",
-    "Pe",
-    "Connector_Punctuation",
-    "Pc",
-    "Control",
-    "Cc",
-    "cntrl",
-    "Currency_Symbol",
-    "Sc",
-    "Dash_Punctuation",
-    "Pd",
-    "Decimal_Number",
-    "Nd",
-    "digit",
-    "Enclosing_Mark",
-    "Me",
-    "Final_Punctuation",
-    "Pf",
-    "Format",
-    "Cf",
-    "Initial_Punctuation",
-    "Pi",
-    "Letter",
-    "L",
-    "Letter_Number",
-    "Nl",
-    "Line_Separator",
-    "Zl",
-    "Lowercase_Letter",
-    "Ll",
-    "Mark",
-    "M",
-    "Combining_Mark",
-    "Math_Symbol",
-    "Sm",
-    "Modifier_Letter",
-    "Lm",
-    "Modifier_Symbol",
-    "Sk",
-    "Nonspacing_Mark",
-    "Mn",
-    "Number",
-    "N",
-    "Open_Punctuation",
-    "Ps",
-    "Other",
-    "C",
-    "Other_Letter",
-    "Lo",
-    "Other_Number",
-    "No",
-    "Other_Punctuation",
-    "Po",
-    "Other_Symbol",
-    "So",
-    "Paragraph_Separator",
-    "Zp",
-    "Private_Use",
-    "Co",
-    "Punctuation",
-    "P",
-    "punct",
-    "Separator",
-    "Z",
-    "Space_Separator",
-    "Zs",
-    "Spacing_Mark",
-    "Mc",
-    "Surrogate",
-    "Cs",
-    "Symbol",
-    "S",
-    "Titlecase_Letter",
-    "Lt",
-    "Unassigned",
-    "Cn",
-    "Uppercase_Letter",
-    "Lu"
-  ],
-  "Script": [
-    "Adlam",
-    "Adlm",
-    "Ahom",
-    "Anatolian_Hieroglyphs",
-    "Hluw",
-    "Arabic",
-    "Arab",
-    "Armenian",
-    "Armn",
-    "Avestan",
-    "Avst",
-    "Balinese",
-    "Bali",
-    "Bamum",
-    "Bamu",
-    "Bassa_Vah",
-    "Bass",
-    "Batak",
-    "Batk",
-    "Bengali",
-    "Beng",
-    "Bhaiksuki",
-    "Bhks",
-    "Bopomofo",
-    "Bopo",
-    "Brahmi",
-    "Brah",
-    "Braille",
-    "Brai",
-    "Buginese",
-    "Bugi",
-    "Buhid",
-    "Buhd",
-    "Canadian_Aboriginal",
-    "Cans",
-    "Carian",
-    "Cari",
-    "Caucasian_Albanian",
-    "Aghb",
-    "Chakma",
-    "Cakm",
-    "Cham",
-    "Cherokee",
-    "Cher",
-    "Common",
-    "Zyyy",
-    "Coptic",
-    "Copt",
-    "Qaac",
-    "Cuneiform",
-    "Xsux",
-    "Cypriot",
-    "Cprt",
-    "Cyrillic",
-    "Cyrl",
-    "Deseret",
-    "Dsrt",
-    "Devanagari",
-    "Deva",
-    "Duployan",
-    "Dupl",
-    "Egyptian_Hieroglyphs",
-    "Egyp",
-    "Elbasan",
-    "Elba",
-    "Ethiopic",
-    "Ethi",
-    "Georgian",
-    "Geor",
-    "Glagolitic",
-    "Glag",
-    "Gothic",
-    "Goth",
-    "Grantha",
-    "Gran",
-    "Greek",
-    "Grek",
-    "Gujarati",
-    "Gujr",
-    "Gurmukhi",
-    "Guru",
-    "Han",
-    "Hani",
-    "Hangul",
-    "Hang",
-    "Hanunoo",
-    "Hano",
-    "Hatran",
-    "Hatr",
-    "Hebrew",
-    "Hebr",
-    "Hiragana",
-    "Hira",
-    "Imperial_Aramaic",
-    "Armi",
-    "Inherited",
-    "Zinh",
-    "Qaai",
-    "Inscriptional_Pahlavi",
-    "Phli",
-    "Inscriptional_Parthian",
-    "Prti",
-    "Javanese",
-    "Java",
-    "Kaithi",
-    "Kthi",
-    "Kannada",
-    "Knda",
-    "Katakana",
-    "Kana",
-    "Kayah_Li",
-    "Kali",
-    "Kharoshthi",
-    "Khar",
-    "Khmer",
-    "Khmr",
-    "Khojki",
-    "Khoj",
-    "Khudawadi",
-    "Sind",
-    "Lao",
-    "Laoo",
-    "Latin",
-    "Latn",
-    "Lepcha",
-    "Lepc",
-    "Limbu",
-    "Limb",
-    "Linear_A",
-    "Lina",
-    "Linear_B",
-    "Linb",
-    "Lisu",
-    "Lycian",
-    "Lyci",
-    "Lydian",
-    "Lydi",
-    "Mahajani",
-    "Mahj",
-    "Malayalam",
-    "Mlym",
-    "Mandaic",
-    "Mand",
-    "Manichaean",
-    "Mani",
-    "Marchen",
-    "Marc",
-    "Masaram_Gondi",
-    "Gonm",
-    "Meetei_Mayek",
-    "Mtei",
-    "Mende_Kikakui",
-    "Mend",
-    "Meroitic_Cursive",
-    "Merc",
-    "Meroitic_Hieroglyphs",
-    "Mero",
-    "Miao",
-    "Plrd",
-    "Modi",
-    "Mongolian",
-    "Mong",
-    "Mro",
-    "Mroo",
-    "Multani",
-    "Mult",
-    "Myanmar",
-    "Mymr",
-    "Nabataean",
-    "Nbat",
-    "New_Tai_Lue",
-    "Talu",
-    "Newa",
-    "Nko",
-    "Nkoo",
-    "Nushu",
-    "Nshu",
-    "Ogham",
-    "Ogam",
-    "Ol_Chiki",
-    "Olck",
-    "Old_Hungarian",
-    "Hung",
-    "Old_Italic",
-    "Ital",
-    "Old_North_Arabian",
-    "Narb",
-    "Old_Permic",
-    "Perm",
-    "Old_Persian",
-    "Xpeo",
-    "Old_South_Arabian",
-    "Sarb",
-    "Old_Turkic",
-    "Orkh",
-    "Oriya",
-    "Orya",
-    "Osage",
-    "Osge",
-    "Osmanya",
-    "Osma",
-    "Pahawh_Hmong",
-    "Hmng",
-    "Palmyrene",
-    "Palm",
-    "Pau_Cin_Hau",
-    "Pauc",
-    "Phags_Pa",
-    "Phag",
-    "Phoenician",
-    "Phnx",
-    "Psalter_Pahlavi",
-    "Phlp",
-    "Rejang",
-    "Rjng",
-    "Runic",
-    "Runr",
-    "Samaritan",
-    "Samr",
-    "Saurashtra",
-    "Saur",
-    "Sharada",
-    "Shrd",
-    "Shavian",
-    "Shaw",
-    "Siddham",
-    "Sidd",
-    "SignWriting",
-    "Sgnw",
-    "Sinhala",
-    "Sinh",
-    "Sora_Sompeng",
-    "Sora",
-    "Soyombo",
-    "Soyo",
-    "Sundanese",
-    "Sund",
-    "Syloti_Nagri",
-    "Sylo",
-    "Syriac",
-    "Syrc",
-    "Tagalog",
-    "Tglg",
-    "Tagbanwa",
-    "Tagb",
-    "Tai_Le",
-    "Tale",
-    "Tai_Tham",
-    "Lana",
-    "Tai_Viet",
-    "Tavt",
-    "Takri",
-    "Takr",
-    "Tamil",
-    "Taml",
-    "Tangut",
-    "Tang",
-    "Telugu",
-    "Telu",
-    "Thaana",
-    "Thaa",
-    "Thai",
-    "Tibetan",
-    "Tibt",
-    "Tifinagh",
-    "Tfng",
-    "Tirhuta",
-    "Tirh",
-    "Ugaritic",
-    "Ugar",
-    "Vai",
-    "Vaii",
-    "Warang_Citi",
-    "Wara",
-    "Yi",
-    "Yiii",
-    "Zanabazar_Square",
-    "Zanb"
-  ]
-};
-Array.prototype.push.apply(data.$LONE, data.General_Category);
-data.gc = data.General_Category;
-data.sc = data.Script_Extensions = data.scx = data.Script;
-
-var pp$9 = Parser.prototype;
-
-var RegExpValidationState = function RegExpValidationState(parser) {
-  this.parser = parser;
-  this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
-  this.source = "";
-  this.flags = "";
-  this.start = 0;
-  this.switchU = false;
-  this.switchN = false;
-  this.pos = 0;
-  this.lastIntValue = 0;
-  this.lastStringValue = "";
-  this.lastAssertionIsQuantifiable = false;
-  this.numCapturingParens = 0;
-  this.maxBackReference = 0;
-  this.groupNames = [];
-  this.backReferenceNames = [];
-};
-
-RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
-  var unicode = flags.indexOf("u") !== -1;
-  this.start = start | 0;
-  this.source = pattern + "";
-  this.flags = flags;
-  this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
-  this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
-};
-
-RegExpValidationState.prototype.raise = function raise (message) {
-  this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
-};
-
-// If u flag is given, this returns the code point at the index (it combines a surrogate pair).
-// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
-RegExpValidationState.prototype.at = function at (i) {
-  var s = this.source;
-  var l = s.length;
-  if (i >= l) {
-    return -1
-  }
-  var c = s.charCodeAt(i);
-  if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
-    return c
-  }
-  return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00
-};
-
-RegExpValidationState.prototype.nextIndex = function nextIndex (i) {
-  var s = this.source;
-  var l = s.length;
-  if (i >= l) {
-    return l
-  }
-  var c = s.charCodeAt(i);
-  if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
-    return i + 1
-  }
-  return i + 2
-};
-
-RegExpValidationState.prototype.current = function current () {
-  return this.at(this.pos)
-};
-
-RegExpValidationState.prototype.lookahead = function lookahead () {
-  return this.at(this.nextIndex(this.pos))
-};
-
-RegExpValidationState.prototype.advance = function advance () {
-  this.pos = this.nextIndex(this.pos);
-};
-
-RegExpValidationState.prototype.eat = function eat (ch) {
-  if (this.current() === ch) {
-    this.advance();
-    return true
-  }
-  return false
-};
-
-function codePointToString$1(ch) {
-  if (ch <= 0xFFFF) { return String.fromCharCode(ch) }
-  ch -= 0x10000;
-  return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
-}
-
-/**
- * Validate the flags part of a given RegExpLiteral.
- *
- * @param {RegExpValidationState} state The state to validate RegExp.
- * @returns {void}
- */
-pp$9.validateRegExpFlags = function(state) {
-  var this$1 = this;
-
-  var validFlags = state.validFlags;
-  var flags = state.flags;
-
-  for (var i = 0; i < flags.length; i++) {
-    var flag = flags.charAt(i);
-    if (validFlags.indexOf(flag) == -1) {
-      this$1.raise(state.start, "Invalid regular expression flag");
-    }
-    if (flags.indexOf(flag, i + 1) > -1) {
-      this$1.raise(state.start, "Duplicate regular expression flag");
-    }
-  }
-};
-
-/**
- * Validate the pattern part of a given RegExpLiteral.
- *
- * @param {RegExpValidationState} state The state to validate RegExp.
- * @returns {void}
- */
-pp$9.validateRegExpPattern = function(state) {
-  this.regexp_pattern(state);
-
-  // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
-  // parsing contains a |GroupName|, reparse with the goal symbol
-  // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
-  // exception if _P_ did not conform to the grammar, if any elements of _P_
-  // were not matched by the parse, or if any Early Error conditions exist.
-  if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
-    state.switchN = true;
-    this.regexp_pattern(state);
-  }
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
-pp$9.regexp_pattern = function(state) {
-  state.pos = 0;
-  state.lastIntValue = 0;
-  state.lastStringValue = "";
-  state.lastAssertionIsQuantifiable = false;
-  state.numCapturingParens = 0;
-  state.maxBackReference = 0;
-  state.groupNames.length = 0;
-  state.backReferenceNames.length = 0;
-
-  this.regexp_disjunction(state);
-
-  if (state.pos !== state.source.length) {
-    // Make the same messages as V8.
-    if (state.eat(0x29 /* ) */)) {
-      state.raise("Unmatched ')'");
-    }
-    if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {
-      state.raise("Lone quantifier brackets");
-    }
-  }
-  if (state.maxBackReference > state.numCapturingParens) {
-    state.raise("Invalid escape");
-  }
-  for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
-    var name = list[i];
-
-    if (state.groupNames.indexOf(name) === -1) {
-      state.raise("Invalid named capture referenced");
-    }
-  }
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
-pp$9.regexp_disjunction = function(state) {
-  var this$1 = this;
-
-  this.regexp_alternative(state);
-  while (state.eat(0x7C /* | */)) {
-    this$1.regexp_alternative(state);
-  }
-
-  // Make the same message as V8.
-  if (this.regexp_eatQuantifier(state, true)) {
-    state.raise("Nothing to repeat");
-  }
-  if (state.eat(0x7B /* { */)) {
-    state.raise("Lone quantifier brackets");
-  }
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
-pp$9.regexp_alternative = function(state) {
-  while (state.pos < state.source.length && this.regexp_eatTerm(state))
-    {  }
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
-pp$9.regexp_eatTerm = function(state) {
-  if (this.regexp_eatAssertion(state)) {
-    // Handle `QuantifiableAssertion Quantifier` alternative.
-    // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
-    // is a QuantifiableAssertion.
-    if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
-      // Make the same message as V8.
-      if (state.switchU) {
-        state.raise("Invalid quantifier");
-      }
-    }
-    return true
-  }
-
-  if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
-    this.regexp_eatQuantifier(state);
-    return true
-  }
-
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
-pp$9.regexp_eatAssertion = function(state) {
-  var start = state.pos;
-  state.lastAssertionIsQuantifiable = false;
-
-  // ^, $
-  if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
-    return true
-  }
-
-  // \b \B
-  if (state.eat(0x5C /* \ */)) {
-    if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
-      return true
-    }
-    state.pos = start;
-  }
-
-  // Lookahead / Lookbehind
-  if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
-    var lookbehind = false;
-    if (this.options.ecmaVersion >= 9) {
-      lookbehind = state.eat(0x3C /* < */);
-    }
-    if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
-      this.regexp_disjunction(state);
-      if (!state.eat(0x29 /* ) */)) {
-        state.raise("Unterminated group");
-      }
-      state.lastAssertionIsQuantifiable = !lookbehind;
-      return true
-    }
-  }
-
-  state.pos = start;
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
-pp$9.regexp_eatQuantifier = function(state, noError) {
-  if ( noError === void 0 ) noError = false;
-
-  if (this.regexp_eatQuantifierPrefix(state, noError)) {
-    state.eat(0x3F /* ? */);
-    return true
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
-pp$9.regexp_eatQuantifierPrefix = function(state, noError) {
-  return (
-    state.eat(0x2A /* * */) ||
-    state.eat(0x2B /* + */) ||
-    state.eat(0x3F /* ? */) ||
-    this.regexp_eatBracedQuantifier(state, noError)
-  )
-};
-pp$9.regexp_eatBracedQuantifier = function(state, noError) {
-  var start = state.pos;
-  if (state.eat(0x7B /* { */)) {
-    var min = 0, max = -1;
-    if (this.regexp_eatDecimalDigits(state)) {
-      min = state.lastIntValue;
-      if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
-        max = state.lastIntValue;
-      }
-      if (state.eat(0x7D /* } */)) {
-        // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
-        if (max !== -1 && max < min && !noError) {
-          state.raise("numbers out of order in {} quantifier");
-        }
-        return true
-      }
-    }
-    if (state.switchU && !noError) {
-      state.raise("Incomplete quantifier");
-    }
-    state.pos = start;
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
-pp$9.regexp_eatAtom = function(state) {
-  return (
-    this.regexp_eatPatternCharacters(state) ||
-    state.eat(0x2E /* . */) ||
-    this.regexp_eatReverseSolidusAtomEscape(state) ||
-    this.regexp_eatCharacterClass(state) ||
-    this.regexp_eatUncapturingGroup(state) ||
-    this.regexp_eatCapturingGroup(state)
-  )
-};
-pp$9.regexp_eatReverseSolidusAtomEscape = function(state) {
-  var start = state.pos;
-  if (state.eat(0x5C /* \ */)) {
-    if (this.regexp_eatAtomEscape(state)) {
-      return true
-    }
-    state.pos = start;
-  }
-  return false
-};
-pp$9.regexp_eatUncapturingGroup = function(state) {
-  var start = state.pos;
-  if (state.eat(0x28 /* ( */)) {
-    if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
-      this.regexp_disjunction(state);
-      if (state.eat(0x29 /* ) */)) {
-        return true
-      }
-      state.raise("Unterminated group");
-    }
-    state.pos = start;
-  }
-  return false
-};
-pp$9.regexp_eatCapturingGroup = function(state) {
-  if (state.eat(0x28 /* ( */)) {
-    if (this.options.ecmaVersion >= 9) {
-      this.regexp_groupSpecifier(state);
-    } else if (state.current() === 0x3F /* ? */) {
-      state.raise("Invalid group");
-    }
-    this.regexp_disjunction(state);
-    if (state.eat(0x29 /* ) */)) {
-      state.numCapturingParens += 1;
-      return true
-    }
-    state.raise("Unterminated group");
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
-pp$9.regexp_eatExtendedAtom = function(state) {
-  return (
-    state.eat(0x2E /* . */) ||
-    this.regexp_eatReverseSolidusAtomEscape(state) ||
-    this.regexp_eatCharacterClass(state) ||
-    this.regexp_eatUncapturingGroup(state) ||
-    this.regexp_eatCapturingGroup(state) ||
-    this.regexp_eatInvalidBracedQuantifier(state) ||
-    this.regexp_eatExtendedPatternCharacter(state)
-  )
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
-pp$9.regexp_eatInvalidBracedQuantifier = function(state) {
-  if (this.regexp_eatBracedQuantifier(state, true)) {
-    state.raise("Nothing to repeat");
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
-pp$9.regexp_eatSyntaxCharacter = function(state) {
-  var ch = state.current();
-  if (isSyntaxCharacter(ch)) {
-    state.lastIntValue = ch;
-    state.advance();
-    return true
-  }
-  return false
-};
-function isSyntaxCharacter(ch) {
-  return (
-    ch === 0x24 /* $ */ ||
-    ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
-    ch === 0x2E /* . */ ||
-    ch === 0x3F /* ? */ ||
-    ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
-    ch >= 0x7B /* { */ && ch <= 0x7D /* } */
-  )
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
-// But eat eager.
-pp$9.regexp_eatPatternCharacters = function(state) {
-  var start = state.pos;
-  var ch = 0;
-  while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
-    state.advance();
-  }
-  return state.pos !== start
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
-pp$9.regexp_eatExtendedPatternCharacter = function(state) {
-  var ch = state.current();
-  if (
-    ch !== -1 &&
-    ch !== 0x24 /* $ */ &&
-    !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
-    ch !== 0x2E /* . */ &&
-    ch !== 0x3F /* ? */ &&
-    ch !== 0x5B /* [ */ &&
-    ch !== 0x5E /* ^ */ &&
-    ch !== 0x7C /* | */
-  ) {
-    state.advance();
-    return true
-  }
-  return false
-};
-
-// GroupSpecifier[U] ::
-//   [empty]
-//   `?` GroupName[?U]
-pp$9.regexp_groupSpecifier = function(state) {
-  if (state.eat(0x3F /* ? */)) {
-    if (this.regexp_eatGroupName(state)) {
-      if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
-        state.raise("Duplicate capture group name");
-      }
-      state.groupNames.push(state.lastStringValue);
-      return
-    }
-    state.raise("Invalid group");
-  }
-};
-
-// GroupName[U] ::
-//   `<` RegExpIdentifierName[?U] `>`
-// Note: this updates `state.lastStringValue` property with the eaten name.
-pp$9.regexp_eatGroupName = function(state) {
-  state.lastStringValue = "";
-  if (state.eat(0x3C /* < */)) {
-    if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
-      return true
-    }
-    state.raise("Invalid capture group name");
-  }
-  return false
-};
-
-// RegExpIdentifierName[U] ::
-//   RegExpIdentifierStart[?U]
-//   RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
-// Note: this updates `state.lastStringValue` property with the eaten name.
-pp$9.regexp_eatRegExpIdentifierName = function(state) {
-  state.lastStringValue = "";
-  if (this.regexp_eatRegExpIdentifierStart(state)) {
-    state.lastStringValue += codePointToString$1(state.lastIntValue);
-    while (this.regexp_eatRegExpIdentifierPart(state)) {
-      state.lastStringValue += codePointToString$1(state.lastIntValue);
-    }
-    return true
-  }
-  return false
-};
-
-// RegExpIdentifierStart[U] ::
-//   UnicodeIDStart
-//   `$`
-//   `_`
-//   `\` RegExpUnicodeEscapeSequence[?U]
-pp$9.regexp_eatRegExpIdentifierStart = function(state) {
-  var start = state.pos;
-  var ch = state.current();
-  state.advance();
-
-  if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
-    ch = state.lastIntValue;
-  }
-  if (isRegExpIdentifierStart(ch)) {
-    state.lastIntValue = ch;
-    return true
-  }
-
-  state.pos = start;
-  return false
-};
-function isRegExpIdentifierStart(ch) {
-  return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
-}
-
-// RegExpIdentifierPart[U] ::
-//   UnicodeIDContinue
-//   `$`
-//   `_`
-//   `\` RegExpUnicodeEscapeSequence[?U]
-//   <ZWNJ>
-//   <ZWJ>
-pp$9.regexp_eatRegExpIdentifierPart = function(state) {
-  var start = state.pos;
-  var ch = state.current();
-  state.advance();
-
-  if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
-    ch = state.lastIntValue;
-  }
-  if (isRegExpIdentifierPart(ch)) {
-    state.lastIntValue = ch;
-    return true
-  }
-
-  state.pos = start;
-  return false
-};
-function isRegExpIdentifierPart(ch) {
-  return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
-pp$9.regexp_eatAtomEscape = function(state) {
-  if (
-    this.regexp_eatBackReference(state) ||
-    this.regexp_eatCharacterClassEscape(state) ||
-    this.regexp_eatCharacterEscape(state) ||
-    (state.switchN && this.regexp_eatKGroupName(state))
-  ) {
-    return true
-  }
-  if (state.switchU) {
-    // Make the same message as V8.
-    if (state.current() === 0x63 /* c */) {
-      state.raise("Invalid unicode escape");
-    }
-    state.raise("Invalid escape");
-  }
-  return false
-};
-pp$9.regexp_eatBackReference = function(state) {
-  var start = state.pos;
-  if (this.regexp_eatDecimalEscape(state)) {
-    var n = state.lastIntValue;
-    if (state.switchU) {
-      // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
-      if (n > state.maxBackReference) {
-        state.maxBackReference = n;
-      }
-      return true
-    }
-    if (n <= state.numCapturingParens) {
-      return true
-    }
-    state.pos = start;
-  }
-  return false
-};
-pp$9.regexp_eatKGroupName = function(state) {
-  if (state.eat(0x6B /* k */)) {
-    if (this.regexp_eatGroupName(state)) {
-      state.backReferenceNames.push(state.lastStringValue);
-      return true
-    }
-    state.raise("Invalid named reference");
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
-pp$9.regexp_eatCharacterEscape = function(state) {
-  return (
-    this.regexp_eatControlEscape(state) ||
-    this.regexp_eatCControlLetter(state) ||
-    this.regexp_eatZero(state) ||
-    this.regexp_eatHexEscapeSequence(state) ||
-    this.regexp_eatRegExpUnicodeEscapeSequence(state) ||
-    (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
-    this.regexp_eatIdentityEscape(state)
-  )
-};
-pp$9.regexp_eatCControlLetter = function(state) {
-  var start = state.pos;
-  if (state.eat(0x63 /* c */)) {
-    if (this.regexp_eatControlLetter(state)) {
-      return true
-    }
-    state.pos = start;
-  }
-  return false
-};
-pp$9.regexp_eatZero = function(state) {
-  if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
-    state.lastIntValue = 0;
-    state.advance();
-    return true
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
-pp$9.regexp_eatControlEscape = function(state) {
-  var ch = state.current();
-  if (ch === 0x74 /* t */) {
-    state.lastIntValue = 0x09; /* \t */
-    state.advance();
-    return true
-  }
-  if (ch === 0x6E /* n */) {
-    state.lastIntValue = 0x0A; /* \n */
-    state.advance();
-    return true
-  }
-  if (ch === 0x76 /* v */) {
-    state.lastIntValue = 0x0B; /* \v */
-    state.advance();
-    return true
-  }
-  if (ch === 0x66 /* f */) {
-    state.lastIntValue = 0x0C; /* \f */
-    state.advance();
-    return true
-  }
-  if (ch === 0x72 /* r */) {
-    state.lastIntValue = 0x0D; /* \r */
-    state.advance();
-    return true
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
-pp$9.regexp_eatControlLetter = function(state) {
-  var ch = state.current();
-  if (isControlLetter(ch)) {
-    state.lastIntValue = ch % 0x20;
-    state.advance();
-    return true
-  }
-  return false
-};
-function isControlLetter(ch) {
-  return (
-    (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
-    (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
-  )
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
-pp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) {
-  var start = state.pos;
-
-  if (state.eat(0x75 /* u */)) {
-    if (this.regexp_eatFixedHexDigits(state, 4)) {
-      var lead = state.lastIntValue;
-      if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {
-        var leadSurrogateEnd = state.pos;
-        if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
-          var trail = state.lastIntValue;
-          if (trail >= 0xDC00 && trail <= 0xDFFF) {
-            state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
-            return true
-          }
-        }
-        state.pos = leadSurrogateEnd;
-        state.lastIntValue = lead;
-      }
-      return true
-    }
-    if (
-      state.switchU &&
-      state.eat(0x7B /* { */) &&
-      this.regexp_eatHexDigits(state) &&
-      state.eat(0x7D /* } */) &&
-      isValidUnicode(state.lastIntValue)
-    ) {
-      return true
-    }
-    if (state.switchU) {
-      state.raise("Invalid unicode escape");
-    }
-    state.pos = start;
-  }
-
-  return false
-};
-function isValidUnicode(ch) {
-  return ch >= 0 && ch <= 0x10FFFF
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
-pp$9.regexp_eatIdentityEscape = function(state) {
-  if (state.switchU) {
-    if (this.regexp_eatSyntaxCharacter(state)) {
-      return true
-    }
-    if (state.eat(0x2F /* / */)) {
-      state.lastIntValue = 0x2F; /* / */
-      return true
-    }
-    return false
-  }
-
-  var ch = state.current();
-  if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
-    state.lastIntValue = ch;
-    state.advance();
-    return true
-  }
-
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
-pp$9.regexp_eatDecimalEscape = function(state) {
-  state.lastIntValue = 0;
-  var ch = state.current();
-  if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
-    do {
-      state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
-      state.advance();
-    } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
-    return true
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
-pp$9.regexp_eatCharacterClassEscape = function(state) {
-  var ch = state.current();
-
-  if (isCharacterClassEscape(ch)) {
-    state.lastIntValue = -1;
-    state.advance();
-    return true
-  }
-
-  if (
-    state.switchU &&
-    this.options.ecmaVersion >= 9 &&
-    (ch === 0x50 /* P */ || ch === 0x70 /* p */)
-  ) {
-    state.lastIntValue = -1;
-    state.advance();
-    if (
-      state.eat(0x7B /* { */) &&
-      this.regexp_eatUnicodePropertyValueExpression(state) &&
-      state.eat(0x7D /* } */)
-    ) {
-      return true
-    }
-    state.raise("Invalid property name");
-  }
-
-  return false
-};
-function isCharacterClassEscape(ch) {
-  return (
-    ch === 0x64 /* d */ ||
-    ch === 0x44 /* D */ ||
-    ch === 0x73 /* s */ ||
-    ch === 0x53 /* S */ ||
-    ch === 0x77 /* w */ ||
-    ch === 0x57 /* W */
-  )
-}
-
-// UnicodePropertyValueExpression ::
-//   UnicodePropertyName `=` UnicodePropertyValue
-//   LoneUnicodePropertyNameOrValue
-pp$9.regexp_eatUnicodePropertyValueExpression = function(state) {
-  var start = state.pos;
-
-  // UnicodePropertyName `=` UnicodePropertyValue
-  if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
-    var name = state.lastStringValue;
-    if (this.regexp_eatUnicodePropertyValue(state)) {
-      var value = state.lastStringValue;
-      this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
-      return true
-    }
-  }
-  state.pos = start;
-
-  // LoneUnicodePropertyNameOrValue
-  if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
-    var nameOrValue = state.lastStringValue;
-    this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
-    return true
-  }
-  return false
-};
-pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
-  if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) {
-    state.raise("Invalid property name");
-  }
-};
-pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
-  if (data.$LONE.indexOf(nameOrValue) === -1) {
-    state.raise("Invalid property name");
-  }
-};
-
-// UnicodePropertyName ::
-//   UnicodePropertyNameCharacters
-pp$9.regexp_eatUnicodePropertyName = function(state) {
-  var ch = 0;
-  state.lastStringValue = "";
-  while (isUnicodePropertyNameCharacter(ch = state.current())) {
-    state.lastStringValue += codePointToString$1(ch);
-    state.advance();
-  }
-  return state.lastStringValue !== ""
-};
-function isUnicodePropertyNameCharacter(ch) {
-  return isControlLetter(ch) || ch === 0x5F /* _ */
-}
-
-// UnicodePropertyValue ::
-//   UnicodePropertyValueCharacters
-pp$9.regexp_eatUnicodePropertyValue = function(state) {
-  var ch = 0;
-  state.lastStringValue = "";
-  while (isUnicodePropertyValueCharacter(ch = state.current())) {
-    state.lastStringValue += codePointToString$1(ch);
-    state.advance();
-  }
-  return state.lastStringValue !== ""
-};
-function isUnicodePropertyValueCharacter(ch) {
-  return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
-}
-
-// LoneUnicodePropertyNameOrValue ::
-//   UnicodePropertyValueCharacters
-pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
-  return this.regexp_eatUnicodePropertyValue(state)
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
-pp$9.regexp_eatCharacterClass = function(state) {
-  if (state.eat(0x5B /* [ */)) {
-    state.eat(0x5E /* ^ */);
-    this.regexp_classRanges(state);
-    if (state.eat(0x5D /* [ */)) {
-      return true
-    }
-    // Unreachable since it threw "unterminated regular expression" error before.
-    state.raise("Unterminated character class");
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
-// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
-// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
-pp$9.regexp_classRanges = function(state) {
-  var this$1 = this;
-
-  while (this.regexp_eatClassAtom(state)) {
-    var left = state.lastIntValue;
-    if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) {
-      var right = state.lastIntValue;
-      if (state.switchU && (left === -1 || right === -1)) {
-        state.raise("Invalid character class");
-      }
-      if (left !== -1 && right !== -1 && left > right) {
-        state.raise("Range out of order in character class");
-      }
-    }
-  }
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
-// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
-pp$9.regexp_eatClassAtom = function(state) {
-  var start = state.pos;
-
-  if (state.eat(0x5C /* \ */)) {
-    if (this.regexp_eatClassEscape(state)) {
-      return true
-    }
-    if (state.switchU) {
-      // Make the same message as V8.
-      var ch$1 = state.current();
-      if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
-        state.raise("Invalid class escape");
-      }
-      state.raise("Invalid escape");
-    }
-    state.pos = start;
-  }
-
-  var ch = state.current();
-  if (ch !== 0x5D /* [ */) {
-    state.lastIntValue = ch;
-    state.advance();
-    return true
-  }
-
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
-pp$9.regexp_eatClassEscape = function(state) {
-  var start = state.pos;
-
-  if (state.eat(0x62 /* b */)) {
-    state.lastIntValue = 0x08; /* <BS> */
-    return true
-  }
-
-  if (state.switchU && state.eat(0x2D /* - */)) {
-    state.lastIntValue = 0x2D; /* - */
-    return true
-  }
-
-  if (!state.switchU && state.eat(0x63 /* c */)) {
-    if (this.regexp_eatClassControlLetter(state)) {
-      return true
-    }
-    state.pos = start;
-  }
-
-  return (
-    this.regexp_eatCharacterClassEscape(state) ||
-    this.regexp_eatCharacterEscape(state)
-  )
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
-pp$9.regexp_eatClassControlLetter = function(state) {
-  var ch = state.current();
-  if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
-    state.lastIntValue = ch % 0x20;
-    state.advance();
-    return true
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
-pp$9.regexp_eatHexEscapeSequence = function(state) {
-  var start = state.pos;
-  if (state.eat(0x78 /* x */)) {
-    if (this.regexp_eatFixedHexDigits(state, 2)) {
-      return true
-    }
-    if (state.switchU) {
-      state.raise("Invalid escape");
-    }
-    state.pos = start;
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
-pp$9.regexp_eatDecimalDigits = function(state) {
-  var start = state.pos;
-  var ch = 0;
-  state.lastIntValue = 0;
-  while (isDecimalDigit(ch = state.current())) {
-    state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
-    state.advance();
-  }
-  return state.pos !== start
-};
-function isDecimalDigit(ch) {
-  return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
-pp$9.regexp_eatHexDigits = function(state) {
-  var start = state.pos;
-  var ch = 0;
-  state.lastIntValue = 0;
-  while (isHexDigit(ch = state.current())) {
-    state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
-    state.advance();
-  }
-  return state.pos !== start
-};
-function isHexDigit(ch) {
-  return (
-    (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
-    (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
-    (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
-  )
-}
-function hexToInt(ch) {
-  if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
-    return 10 + (ch - 0x41 /* A */)
-  }
-  if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
-    return 10 + (ch - 0x61 /* a */)
-  }
-  return ch - 0x30 /* 0 */
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
-// Allows only 0-377(octal) i.e. 0-255(decimal).
-pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) {
-  if (this.regexp_eatOctalDigit(state)) {
-    var n1 = state.lastIntValue;
-    if (this.regexp_eatOctalDigit(state)) {
-      var n2 = state.lastIntValue;
-      if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
-        state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
-      } else {
-        state.lastIntValue = n1 * 8 + n2;
-      }
-    } else {
-      state.lastIntValue = n1;
-    }
-    return true
-  }
-  return false
-};
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
-pp$9.regexp_eatOctalDigit = function(state) {
-  var ch = state.current();
-  if (isOctalDigit(ch)) {
-    state.lastIntValue = ch - 0x30; /* 0 */
-    state.advance();
-    return true
-  }
-  state.lastIntValue = 0;
-  return false
-};
-function isOctalDigit(ch) {
-  return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
-}
-
-// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
-// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
-// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
-pp$9.regexp_eatFixedHexDigits = function(state, length) {
-  var start = state.pos;
-  state.lastIntValue = 0;
-  for (var i = 0; i < length; ++i) {
-    var ch = state.current();
-    if (!isHexDigit(ch)) {
-      state.pos = start;
-      return false
-    }
-    state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
-    state.advance();
-  }
-  return true
-};
-
-// 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) {
-  this.type = p.type;
-  this.value = p.value;
-  this.start = p.start;
-  this.end = 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
-
-var pp$8 = Parser.prototype;
-
-// Move to the next token
-
-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$8.getToken = function() {
-  this.next();
-  return new Token(this)
-};
-
-// If we're in an ES6 environment, make parsers iterable
-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$8.curContext = function() {
-  return this.context[this.context.length - 1]
-};
-
-// Read a single token, updating the parser object's token-related
-// properties.
-
-pp$8.nextToken = function() {
-  var curContext = this.curContext();
-  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(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 (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 }
-  var next = this.input.charCodeAt(this.pos + 1);
-  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"); }
-  this.pos = end + 2;
-  if (this.options.locations) {
-    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 && !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$8.skipSpace = function() {
-  var this$1 = this;
-
-  loop: while (this.pos < this.input.length) {
-    var ch = this$1.input.charCodeAt(this$1.pos);
-    switch (ch) {
-    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:
-        this$1.skipLineComment(2);
-        break
-      default:
-        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$8.finishToken = function(type, val) {
-  this.end = this.pos;
-  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$8.readToken_dot = function() {
-  var next = this.input.charCodeAt(this.pos + 1);
-  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 '.'
-    this.pos += 3;
-    return this.finishToken(types.ellipsis)
-  } else {
-    ++this.pos;
-    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(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);
-  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 ? 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(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.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(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(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 = 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(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(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()
-
-  // Punctuation tokens.
-  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)
-
-  // Quotes produce strings.
-  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_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$8.finishOp = function(type, size) {
-  var str = this.input.slice(this.pos, this.pos + size);
-  this.pos += size;
-  return this.finishToken(type, str)
-};
-
-pp$8.readRegexp = function() {
-  var this$1 = this;
-
-  var escaped, inClass, start = this.pos;
-  for (;;) {
-    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 }
-      escaped = ch === "\\";
-    } else { escaped = false; }
-    ++this$1.pos;
-  }
-  var pattern = this.input.slice(start, this.pos);
-  ++this.pos;
-  var flagsStart = this.pos;
-  var flags = this.readWord1();
-  if (this.containsEsc) { this.unexpected(flagsStart); }
-
-  // Validate pattern
-  var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
-  state.reset(start, pattern, flags);
-  this.validateRegExpFlags(state);
-  this.validateRegExpPattern(state);
-
-  // Create Literal#value property value.
-  var value = null;
-  try {
-    value = new RegExp(pattern, flags);
-  } catch (e) {
-    // ESTree requires null if it failed to instantiate RegExp object.
-    // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
-  }
-
-  return this.finishToken(types.regexp, {pattern: pattern, flags: flags, 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$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$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$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 (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$8.readNumber = function(startsWithDot) {
-  var start = this.pos;
-  if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); }
-  var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
-  if (octal && this.strict) { this.raise(start, "Invalid number"); }
-  if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
-  var next = this.input.charCodeAt(this.pos);
-  if (next === 46 && !octal) { // '.'
-    ++this.pos;
-    this.readInt(10);
-    next = this.input.charCodeAt(this.pos);
-  }
-  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 (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
-
-  var str = this.input.slice(start, this.pos);
-  var val = octal ? parseInt(str, 8) : parseFloat(str);
-  return this.finishToken(types.num, val)
-};
-
-// Read a string value, interpreting backslash-escapes.
-
-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);
-    ++this.pos;
-    if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
-  } else {
-    code = this.readHexChar(4);
-  }
-  return code
-};
-
-function codePointToString(code) {
-  // UTF-16 Decoding
-  if (code <= 0xFFFF) { return String.fromCharCode(code) }
-  code -= 0x10000;
-  return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
-}
-
-pp$8.readString = function(quote) {
-  var this$1 = this;
-
-  var out = "", chunkStart = ++this.pos;
-  for (;;) {
-    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 (isNewLine(ch)) { this$1.raise(this$1.start, "Unterminated string constant"); }
-      ++this$1.pos;
-    }
-  }
-  out += this.input.slice(chunkStart, this.pos++);
-  return this.finishToken(types.string, out)
-};
-
-// Reads template string tokens.
-
-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$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$1.pos += 2;
-          return this$1.finishToken(types.dollarBraceL)
-        } else {
-          ++this$1.pos;
-          return this$1.finishToken(types.backQuote)
-        }
-      }
-      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$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;
-      }
-      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
-      }
-    // 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$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; }
-    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);
-      }
-      this.pos += octalStr.length - 1;
-      ch = this.input.charCodeAt(this.pos);
-      if ((octalStr !== "0" || ch == 56 || ch == 57) && (this.strict || inTemplate)) {
-        this.invalidStringToken(
-          this.pos - 1 - octalStr.length,
-          inTemplate
-            ? "Octal literal in template string"
-            : "Octal literal in strict mode"
-        );
-      }
-      return String.fromCharCode(octal)
-    }
-    return String.fromCharCode(ch)
-  }
-};
-
-// Used to read character escape sequences ('\x', '\u', '\U').
-
-pp$8.readHexChar = function(len) {
-  var codePos = this.pos;
-  var n = this.readInt(16, len);
-  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$8.readWord1 = function() {
-  var this$1 = this;
-
-  this.containsEsc = false;
-  var word = "", first = true, chunkStart = this.pos;
-  var astral = this.options.ecmaVersion >= 6;
-  while (this.pos < this.input.length) {
-    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$1.pos;
-    } else {
-      break
-    }
-    first = false;
-  }
-  return word + this.input.slice(chunkStart, this.pos)
-};
-
-// Read an identifier or keyword token. Will check for reserved
-// words when necessary.
-
-pp$8.readWord = function() {
-  var word = this.readWord1();
-  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.
-//
-// 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/acornjs/acorn.git
-//
-// Please use the [github bug tracker][ghbt] to report issues.
-//
-// [ghbt]: https://github.com/acornjs/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.5.3";
-
-// 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()
-}
-
-// 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;
-}
-
-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;
-exports.lineBreak = lineBreak;
-exports.lineBreakG = lineBreakG;
-exports.nonASCIIwhitespace = nonASCIIwhitespace;
-
-Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
diff --git a/front_end/formatter_worker/acorn/acorn_loose.js b/front_end/formatter_worker/acorn/acorn_loose.js
deleted file mode 100644
index 6f372da..0000000
--- a/front_end/formatter_worker/acorn/acorn_loose.js
+++ /dev/null
@@ -1,1378 +0,0 @@
-// clang-format off
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./acorn')) :
-  typeof define === 'function' && define.amd ? define(['exports', './acorn'], factory) :
-  (factory((global.acorn = global.acorn || {}, global.acorn.loose = global.acorn.loose || {}),global.acorn));
-}(this, (function (exports,__acorn) { 'use strict';
-
-// Registered plugins
-var pluginsLoose = {}
-
-var LooseParser = function LooseParser(input, options) {
-  if ( options === void 0 ) options = {};
-
-  this.toks = __acorn.tokenizer(input, options)
-  this.options = this.toks.options
-  this.input = this.toks.input
-  this.tok = this.last = {type: __acorn.tokTypes.eof, start: 0, end: 0}
-  if (this.options.locations) {
-    var here = this.toks.curPosition()
-    this.tok.loc = new __acorn.SourceLocation(this.toks, here, here)
-  }
-  this.ahead = [] // Tokens ahead
-  this.context = [] // Indentation contexted
-  this.curIndent = 0
-  this.curLineStart = 0
-  this.nextLineStart = this.lineEnd(this.curLineStart) + 1
-  this.inAsync = false
-  // Load plugins
-  this.options.pluginsLoose = options.pluginsLoose || {}
-  this.loadPlugins(this.options.pluginsLoose)
-};
-
-LooseParser.prototype.startNode = function startNode () {
-  return new __acorn.Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null)
-};
-
-LooseParser.prototype.storeCurrentPos = function storeCurrentPos () {
-  return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start
-};
-
-LooseParser.prototype.startNodeAt = function startNodeAt (pos) {
-  if (this.options.locations) {
-    return new __acorn.Node(this.toks, pos[0], pos[1])
-  } else {
-    return new __acorn.Node(this.toks, pos)
-  }
-};
-
-LooseParser.prototype.finishNode = function finishNode (node, type) {
-  node.type = type
-  node.end = this.last.end
-  if (this.options.locations)
-    node.loc.end = this.last.loc.end
-  if (this.options.ranges)
-    node.range[1] = this.last.end
-  return node
-};
-
-LooseParser.prototype.dummyNode = function dummyNode (type) {
-  var dummy = this.startNode()
-  dummy.type = type
-  dummy.end = dummy.start
-  if (this.options.locations)
-    dummy.loc.end = dummy.loc.start
-  if (this.options.ranges)
-    dummy.range[1] = dummy.start
-  this.last = {type: __acorn.tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc}
-  return dummy
-};
-
-LooseParser.prototype.dummyIdent = function dummyIdent () {
-  var dummy = this.dummyNode("Identifier")
-  dummy.name = "✖"
-  return dummy
-};
-
-LooseParser.prototype.dummyString = function dummyString () {
-  var dummy = this.dummyNode("Literal")
-  dummy.value = dummy.raw = "✖"
-  return dummy
-};
-
-LooseParser.prototype.eat = function eat (type) {
-  if (this.tok.type === type) {
-    this.next()
-    return true
-  } else {
-    return false
-  }
-};
-
-LooseParser.prototype.isContextual = function isContextual (name) {
-  return this.tok.type === __acorn.tokTypes.name && this.tok.value === name
-};
-
-LooseParser.prototype.eatContextual = function eatContextual (name) {
-  return this.tok.value === name && this.eat(__acorn.tokTypes.name)
-};
-
-LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon () {
-  return this.tok.type === __acorn.tokTypes.eof || this.tok.type === __acorn.tokTypes.braceR ||
-    __acorn.lineBreak.test(this.input.slice(this.last.end, this.tok.start))
-};
-
-LooseParser.prototype.semicolon = function semicolon () {
-  return this.eat(__acorn.tokTypes.semi)
-};
-
-LooseParser.prototype.expect = function expect (type) {
-    var this$1 = this;
-
-  if (this.eat(type)) return true
-  for (var i = 1; i <= 2; i++) {
-    if (this$1.lookAhead(i).type == type) {
-      for (var j = 0; j < i; j++) this$1.next()
-      return true
-    }
-  }
-};
-
-LooseParser.prototype.pushCx = function pushCx () {
-  this.context.push(this.curIndent)
-};
-
-LooseParser.prototype.popCx = function popCx () {
-  this.curIndent = this.context.pop()
-};
-
-LooseParser.prototype.lineEnd = function lineEnd (pos) {
-  while (pos < this.input.length && !__acorn.isNewLine(this.input.charCodeAt(pos))) ++pos
-  return pos
-};
-
-LooseParser.prototype.indentationAfter = function indentationAfter (pos) {
-    var this$1 = this;
-
-  for (var count = 0;; ++pos) {
-    var ch = this$1.input.charCodeAt(pos)
-    if (ch === 32) ++count
-    else if (ch === 9) count += this$1.options.tabSize
-    else return count
-  }
-};
-
-LooseParser.prototype.closes = function closes (closeTok, indent, line, blockHeuristic) {
-  if (this.tok.type === closeTok || this.tok.type === __acorn.tokTypes.eof) return true
-  return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() &&
-    (!blockHeuristic || this.nextLineStart >= this.input.length ||
-     this.indentationAfter(this.nextLineStart) < indent)
-};
-
-LooseParser.prototype.tokenStartsLine = function tokenStartsLine () {
-    var this$1 = this;
-
-  for (var p = this.tok.start - 1; p >= this.curLineStart; --p) {
-    var ch = this$1.input.charCodeAt(p)
-    if (ch !== 9 && ch !== 32) return false
-  }
-  return true
-};
-
-LooseParser.prototype.extend = function extend (name, f) {
-  this[name] = f(this[name])
-};
-
-LooseParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {
-    var this$1 = this;
-
-  for (var name in pluginConfigs) {
-    var plugin = pluginsLoose[name]
-    if (!plugin) throw new Error("Plugin '" + name + "' not found")
-    plugin(this$1, pluginConfigs[name])
-  }
-};
-
-var lp = LooseParser.prototype
-
-function isSpace(ch) {
-  return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || __acorn.isNewLine(ch)
-}
-
-lp.next = function() {
-  var this$1 = this;
-
-  this.last = this.tok
-  if (this.ahead.length)
-    this.tok = this.ahead.shift()
-  else
-    this.tok = this.readToken()
-
-  if (this.tok.start >= this.nextLineStart) {
-    while (this.tok.start >= this.nextLineStart) {
-      this$1.curLineStart = this$1.nextLineStart
-      this$1.nextLineStart = this$1.lineEnd(this$1.curLineStart) + 1
-    }
-    this.curIndent = this.indentationAfter(this.curLineStart)
-  }
-}
-
-lp.readToken = function() {
-  var this$1 = this;
-
-  for (;;) {
-    try {
-      this$1.toks.next()
-      if (this$1.toks.type === __acorn.tokTypes.dot &&
-          this$1.input.substr(this$1.toks.end, 1) === "." &&
-          this$1.options.ecmaVersion >= 6) {
-        this$1.toks.end++
-        this$1.toks.type = __acorn.tokTypes.ellipsis
-      }
-      return new __acorn.Token(this$1.toks)
-    } catch (e) {
-      if (!(e instanceof SyntaxError)) throw e
-
-      // Try to skip some text, based on the error message, and then continue
-      var msg = e.message, pos = e.raisedAt, replace = true
-      if (/unterminated/i.test(msg)) {
-        pos = this$1.lineEnd(e.pos + 1)
-        if (/string/.test(msg)) {
-          replace = {start: e.pos, end: pos, type: __acorn.tokTypes.string, value: this$1.input.slice(e.pos + 1, pos)}
-        } else if (/regular expr/i.test(msg)) {
-          var re = this$1.input.slice(e.pos, pos)
-          try { re = new RegExp(re) } catch (e) { /* ignore compilation error due to new syntax */ }
-          replace = {start: e.pos, end: pos, type: __acorn.tokTypes.regexp, value: re}
-        } else if (/template/.test(msg)) {
-          replace = {
-            start: e.pos,
-            end: pos,
-            type: __acorn.tokTypes.template,
-            value: this$1.input.slice(e.pos, pos)
-          }
-        } else {
-          replace = false
-        }
-      } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) {
-        while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos
-      } else if (/character escape|expected hexadecimal/i.test(msg)) {
-        while (pos < this.input.length) {
-          var ch = this$1.input.charCodeAt(pos++)
-          if (ch === 34 || ch === 39 || __acorn.isNewLine(ch)) break
-        }
-      } else if (/unexpected character/i.test(msg)) {
-        pos++
-        replace = false
-      } else if (/regular expression/i.test(msg)) {
-        replace = true
-      } else {
-        throw e
-      }
-      this$1.resetTo(pos)
-      if (replace === true) replace = {start: pos, end: pos, type: __acorn.tokTypes.name, value: "✖"}
-      if (replace) {
-        if (this$1.options.locations)
-          replace.loc = new __acorn.SourceLocation(
-            this$1.toks,
-            __acorn.getLineInfo(this$1.input, replace.start),
-            __acorn.getLineInfo(this$1.input, replace.end))
-        return replace
-      }
-    }
-  }
-}
-
-lp.resetTo = function(pos) {
-  var this$1 = this;
-
-  this.toks.pos = pos
-  var ch = this.input.charAt(pos - 1)
-  this.toks.exprAllowed = !ch || /[[{(,;:?/*=+\-~!|&%^<>]/.test(ch) ||
-    /[enwfd]/.test(ch) &&
-    /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos))
-
-  if (this.options.locations) {
-    this.toks.curLine = 1
-    this.toks.lineStart = __acorn.lineBreakG.lastIndex = 0
-    var match
-    while ((match = __acorn.lineBreakG.exec(this.input)) && match.index < pos) {
-      ++this$1.toks.curLine
-      this$1.toks.lineStart = match.index + match[0].length
-    }
-  }
-}
-
-lp.lookAhead = function(n) {
-  var this$1 = this;
-
-  while (n > this.ahead.length)
-    this$1.ahead.push(this$1.readToken())
-  return this.ahead[n - 1]
-}
-
-function isDummy(node) { return node.name == "✖" }
-
-var lp$1 = LooseParser.prototype
-
-lp$1.parseTopLevel = function() {
-  var this$1 = this;
-
-  var node = this.startNodeAt(this.options.locations ? [0, __acorn.getLineInfo(this.input, 0)] : 0)
-  node.body = []
-  while (this.tok.type !== __acorn.tokTypes.eof) node.body.push(this$1.parseStatement())
-  this.last = this.tok
-  if (this.options.ecmaVersion >= 6) {
-    node.sourceType = this.options.sourceType
-  }
-  return this.finishNode(node, "Program")
-}
-
-lp$1.parseStatement = function() {
-  var this$1 = this;
-
-  var starttype = this.tok.type, node = this.startNode(), kind
-
-  if (this.toks.isLet()) {
-    starttype = __acorn.tokTypes._var
-    kind = "let"
-  }
-
-  switch (starttype) {
-  case __acorn.tokTypes._break: case __acorn.tokTypes._continue:
-    this.next()
-    var isBreak = starttype === __acorn.tokTypes._break
-    if (this.semicolon() || this.canInsertSemicolon()) {
-      node.label = null
-    } else {
-      node.label = this.tok.type === __acorn.tokTypes.name ? this.parseIdent() : null
-      this.semicolon()
-    }
-    return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
-
-  case __acorn.tokTypes._debugger:
-    this.next()
-    this.semicolon()
-    return this.finishNode(node, "DebuggerStatement")
-
-  case __acorn.tokTypes._do:
-    this.next()
-    node.body = this.parseStatement()
-    node.test = this.eat(__acorn.tokTypes._while) ? this.parseParenExpression() : this.dummyIdent()
-    this.semicolon()
-    return this.finishNode(node, "DoWhileStatement")
-
-  case __acorn.tokTypes._for:
-    this.next()
-    this.pushCx()
-    this.expect(__acorn.tokTypes.parenL)
-    if (this.tok.type === __acorn.tokTypes.semi) return this.parseFor(node, null)
-    var isLet = this.toks.isLet()
-    if (isLet || this.tok.type === __acorn.tokTypes._var || this.tok.type === __acorn.tokTypes._const) {
-      var init$1 = this.parseVar(true, isLet ? "let" : this.tok.value)
-      if (init$1.declarations.length === 1 && (this.tok.type === __acorn.tokTypes._in || this.isContextual("of"))) {
-        return this.parseForIn(node, init$1)
-      }
-      return this.parseFor(node, init$1)
-    }
-    var init = this.parseExpression(true)
-    if (this.tok.type === __acorn.tokTypes._in || this.isContextual("of"))
-      return this.parseForIn(node, this.toAssignable(init))
-    return this.parseFor(node, init)
-
-  case __acorn.tokTypes._function:
-    this.next()
-    return this.parseFunction(node, true)
-
-  case __acorn.tokTypes._if:
-    this.next()
-    node.test = this.parseParenExpression()
-    node.consequent = this.parseStatement()
-    node.alternate = this.eat(__acorn.tokTypes._else) ? this.parseStatement() : null
-    return this.finishNode(node, "IfStatement")
-
-  case __acorn.tokTypes._return:
-    this.next()
-    if (this.eat(__acorn.tokTypes.semi) || this.canInsertSemicolon()) node.argument = null
-    else { node.argument = this.parseExpression(); this.semicolon() }
-    return this.finishNode(node, "ReturnStatement")
-
-  case __acorn.tokTypes._switch:
-    var blockIndent = this.curIndent, line = this.curLineStart
-    this.next()
-    node.discriminant = this.parseParenExpression()
-    node.cases = []
-    this.pushCx()
-    this.expect(__acorn.tokTypes.braceL)
-
-    var cur
-    while (!this.closes(__acorn.tokTypes.braceR, blockIndent, line, true)) {
-      if (this$1.tok.type === __acorn.tokTypes._case || this$1.tok.type === __acorn.tokTypes._default) {
-        var isCase = this$1.tok.type === __acorn.tokTypes._case
-        if (cur) this$1.finishNode(cur, "SwitchCase")
-        node.cases.push(cur = this$1.startNode())
-        cur.consequent = []
-        this$1.next()
-        if (isCase) cur.test = this$1.parseExpression()
-        else cur.test = null
-        this$1.expect(__acorn.tokTypes.colon)
-      } else {
-        if (!cur) {
-          node.cases.push(cur = this$1.startNode())
-          cur.consequent = []
-          cur.test = null
-        }
-        cur.consequent.push(this$1.parseStatement())
-      }
-    }
-    if (cur) this.finishNode(cur, "SwitchCase")
-    this.popCx()
-    this.eat(__acorn.tokTypes.braceR)
-    return this.finishNode(node, "SwitchStatement")
-
-  case __acorn.tokTypes._throw:
-    this.next()
-    node.argument = this.parseExpression()
-    this.semicolon()
-    return this.finishNode(node, "ThrowStatement")
-
-  case __acorn.tokTypes._try:
-    this.next()
-    node.block = this.parseBlock()
-    node.handler = null
-    if (this.tok.type === __acorn.tokTypes._catch) {
-      var clause = this.startNode()
-      this.next()
-      this.expect(__acorn.tokTypes.parenL)
-      clause.param = this.toAssignable(this.parseExprAtom(), true)
-      this.expect(__acorn.tokTypes.parenR)
-      clause.body = this.parseBlock()
-      node.handler = this.finishNode(clause, "CatchClause")
-    }
-    node.finalizer = this.eat(__acorn.tokTypes._finally) ? this.parseBlock() : null
-    if (!node.handler && !node.finalizer) return node.block
-    return this.finishNode(node, "TryStatement")
-
-  case __acorn.tokTypes._var:
-  case __acorn.tokTypes._const:
-    return this.parseVar(false, kind || this.tok.value)
-
-  case __acorn.tokTypes._while:
-    this.next()
-    node.test = this.parseParenExpression()
-    node.body = this.parseStatement()
-    return this.finishNode(node, "WhileStatement")
-
-  case __acorn.tokTypes._with:
-    this.next()
-    node.object = this.parseParenExpression()
-    node.body = this.parseStatement()
-    return this.finishNode(node, "WithStatement")
-
-  case __acorn.tokTypes.braceL:
-    return this.parseBlock()
-
-  case __acorn.tokTypes.semi:
-    this.next()
-    return this.finishNode(node, "EmptyStatement")
-
-  case __acorn.tokTypes._class:
-    return this.parseClass(true)
-
-  case __acorn.tokTypes._import:
-    return this.parseImport()
-
-  case __acorn.tokTypes._export:
-    return this.parseExport()
-
-  default:
-    if (this.toks.isAsyncFunction()) {
-      this.next()
-      this.next()
-      return this.parseFunction(node, true, true)
-    }
-    var expr = this.parseExpression()
-    if (isDummy(expr)) {
-      this.next()
-      if (this.tok.type === __acorn.tokTypes.eof) return this.finishNode(node, "EmptyStatement")
-      return this.parseStatement()
-    } else if (starttype === __acorn.tokTypes.name && expr.type === "Identifier" && this.eat(__acorn.tokTypes.colon)) {
-      node.body = this.parseStatement()
-      node.label = expr
-      return this.finishNode(node, "LabeledStatement")
-    } else {
-      node.expression = expr
-      this.semicolon()
-      return this.finishNode(node, "ExpressionStatement")
-    }
-  }
-}
-
-lp$1.parseBlock = function() {
-  var this$1 = this;
-
-  var node = this.startNode()
-  this.pushCx()
-  this.expect(__acorn.tokTypes.braceL)
-  var blockIndent = this.curIndent, line = this.curLineStart
-  node.body = []
-  while (!this.closes(__acorn.tokTypes.braceR, blockIndent, line, true))
-    node.body.push(this$1.parseStatement())
-  this.popCx()
-  this.eat(__acorn.tokTypes.braceR)
-  return this.finishNode(node, "BlockStatement")
-}
-
-lp$1.parseFor = function(node, init) {
-  node.init = init
-  node.test = node.update = null
-  if (this.eat(__acorn.tokTypes.semi) && this.tok.type !== __acorn.tokTypes.semi) node.test = this.parseExpression()
-  if (this.eat(__acorn.tokTypes.semi) && this.tok.type !== __acorn.tokTypes.parenR) node.update = this.parseExpression()
-  this.popCx()
-  this.expect(__acorn.tokTypes.parenR)
-  node.body = this.parseStatement()
-  return this.finishNode(node, "ForStatement")
-}
-
-lp$1.parseForIn = function(node, init) {
-  var type = this.tok.type === __acorn.tokTypes._in ? "ForInStatement" : "ForOfStatement"
-  this.next()
-  node.left = init
-  node.right = this.parseExpression()
-  this.popCx()
-  this.expect(__acorn.tokTypes.parenR)
-  node.body = this.parseStatement()
-  return this.finishNode(node, type)
-}
-
-lp$1.parseVar = function(noIn, kind) {
-  var this$1 = this;
-
-  var node = this.startNode()
-  node.kind = kind
-  this.next()
-  node.declarations = []
-  do {
-    var decl = this$1.startNode()
-    decl.id = this$1.options.ecmaVersion >= 6 ? this$1.toAssignable(this$1.parseExprAtom(), true) : this$1.parseIdent()
-    decl.init = this$1.eat(__acorn.tokTypes.eq) ? this$1.parseMaybeAssign(noIn) : null
-    node.declarations.push(this$1.finishNode(decl, "VariableDeclarator"))
-  } while (this.eat(__acorn.tokTypes.comma))
-  if (!node.declarations.length) {
-    var decl$1 = this.startNode()
-    decl$1.id = this.dummyIdent()
-    node.declarations.push(this.finishNode(decl$1, "VariableDeclarator"))
-  }
-  if (!noIn) this.semicolon()
-  return this.finishNode(node, "VariableDeclaration")
-}
-
-lp$1.parseClass = function(isStatement) {
-  var this$1 = this;
-
-  var node = this.startNode()
-  this.next()
-  if (this.tok.type === __acorn.tokTypes.name) node.id = this.parseIdent()
-  else if (isStatement === true) node.id = this.dummyIdent()
-  else node.id = null
-  node.superClass = this.eat(__acorn.tokTypes._extends) ? this.parseExpression() : null
-  node.body = this.startNode()
-  node.body.body = []
-  this.pushCx()
-  var indent = this.curIndent + 1, line = this.curLineStart
-  this.eat(__acorn.tokTypes.braceL)
-  if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart }
-  while (!this.closes(__acorn.tokTypes.braceR, indent, line)) {
-    if (this$1.semicolon()) continue
-    var method = this$1.startNode(), isGenerator, isAsync
-    if (this$1.options.ecmaVersion >= 6) {
-      method.static = false
-      isGenerator = this$1.eat(__acorn.tokTypes.star)
-    }
-    this$1.parsePropertyName(method)
-    if (isDummy(method.key)) { if (isDummy(this$1.parseMaybeAssign())) this$1.next(); this$1.eat(__acorn.tokTypes.comma); continue }
-    if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" &&
-        (this$1.tok.type != __acorn.tokTypes.parenL && this$1.tok.type != __acorn.tokTypes.braceL)) {
-      method.static = true
-      isGenerator = this$1.eat(__acorn.tokTypes.star)
-      this$1.parsePropertyName(method)
-    } else {
-      method.static = false
-    }
-    if (!method.computed &&
-        method.key.type === "Identifier" && method.key.name === "async" && this$1.tok.type !== __acorn.tokTypes.parenL &&
-        !this$1.canInsertSemicolon()) {
-      this$1.parsePropertyName(method)
-      isAsync = true
-    } else {
-      isAsync = false
-    }
-    if (this$1.options.ecmaVersion >= 5 && method.key.type === "Identifier" &&
-        !method.computed && (method.key.name === "get" || method.key.name === "set") &&
-        this$1.tok.type !== __acorn.tokTypes.parenL && this$1.tok.type !== __acorn.tokTypes.braceL) {
-      method.kind = method.key.name
-      this$1.parsePropertyName(method)
-      method.value = this$1.parseMethod(false)
-    } else {
-      if (!method.computed && !method.static && !isGenerator && !isAsync && (
-        method.key.type === "Identifier" && method.key.name === "constructor" ||
-          method.key.type === "Literal" && method.key.value === "constructor")) {
-        method.kind = "constructor"
-      } else {
-        method.kind = "method"
-      }
-      method.value = this$1.parseMethod(isGenerator, isAsync)
-    }
-    node.body.body.push(this$1.finishNode(method, "MethodDefinition"))
-  }
-  this.popCx()
-  if (!this.eat(__acorn.tokTypes.braceR)) {
-    // If there is no closing brace, make the node span to the start
-    // of the next token (this is useful for Tern)
-    this.last.end = this.tok.start
-    if (this.options.locations) this.last.loc.end = this.tok.loc.start
-  }
-  this.semicolon()
-  this.finishNode(node.body, "ClassBody")
-  return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
-}
-
-lp$1.parseFunction = function(node, isStatement, isAsync) {
-  var oldInAsync = this.inAsync
-  this.initFunction(node)
-  if (this.options.ecmaVersion >= 6) {
-    node.generator = this.eat(__acorn.tokTypes.star)
-  }
-  if (this.options.ecmaVersion >= 8) {
-    node.async = !!isAsync
-  }
-  if (this.tok.type === __acorn.tokTypes.name) node.id = this.parseIdent()
-  else if (isStatement === true) node.id = this.dummyIdent()
-  this.inAsync = node.async
-  node.params = this.parseFunctionParams()
-  node.body = this.parseBlock()
-  this.inAsync = oldInAsync
-  return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
-}
-
-lp$1.parseExport = function() {
-  var node = this.startNode()
-  this.next()
-  if (this.eat(__acorn.tokTypes.star)) {
-    node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString()
-    return this.finishNode(node, "ExportAllDeclaration")
-  }
-  if (this.eat(__acorn.tokTypes._default)) {
-    // export default (function foo() {}) // This is FunctionExpression.
-    var isAsync
-    if (this.tok.type === __acorn.tokTypes._function || (isAsync = this.toks.isAsyncFunction())) {
-      var fNode = this.startNode()
-      this.next()
-      if (isAsync) this.next()
-      node.declaration = this.parseFunction(fNode, "nullableID", isAsync)
-    } else if (this.tok.type === __acorn.tokTypes._class) {
-      node.declaration = this.parseClass("nullableID")
-    } else {
-      node.declaration = this.parseMaybeAssign()
-      this.semicolon()
-    }
-    return this.finishNode(node, "ExportDefaultDeclaration")
-  }
-  if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) {
-    node.declaration = this.parseStatement()
-    node.specifiers = []
-    node.source = null
-  } else {
-    node.declaration = null
-    node.specifiers = this.parseExportSpecifierList()
-    node.source = this.eatContextual("from") ? this.parseExprAtom() : null
-    this.semicolon()
-  }
-  return this.finishNode(node, "ExportNamedDeclaration")
-}
-
-lp$1.parseImport = function() {
-  var node = this.startNode()
-  this.next()
-  if (this.tok.type === __acorn.tokTypes.string) {
-    node.specifiers = []
-    node.source = this.parseExprAtom()
-    node.kind = ""
-  } else {
-    var elt
-    if (this.tok.type === __acorn.tokTypes.name && this.tok.value !== "from") {
-      elt = this.startNode()
-      elt.local = this.parseIdent()
-      this.finishNode(elt, "ImportDefaultSpecifier")
-      this.eat(__acorn.tokTypes.comma)
-    }
-    node.specifiers = this.parseImportSpecifierList()
-    node.source = this.eatContextual("from") && this.tok.type == __acorn.tokTypes.string ? this.parseExprAtom() : this.dummyString()
-    if (elt) node.specifiers.unshift(elt)
-  }
-  this.semicolon()
-  return this.finishNode(node, "ImportDeclaration")
-}
-
-lp$1.parseImportSpecifierList = function() {
-  var this$1 = this;
-
-  var elts = []
-  if (this.tok.type === __acorn.tokTypes.star) {
-    var elt = this.startNode()
-    this.next()
-    elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent()
-    elts.push(this.finishNode(elt, "ImportNamespaceSpecifier"))
-  } else {
-    var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart
-    this.pushCx()
-    this.eat(__acorn.tokTypes.braceL)
-    if (this.curLineStart > continuedLine) continuedLine = this.curLineStart
-    while (!this.closes(__acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
-      var elt$1 = this$1.startNode()
-      if (this$1.eat(__acorn.tokTypes.star)) {
-        elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : this$1.dummyIdent()
-        this$1.finishNode(elt$1, "ImportNamespaceSpecifier")
-      } else {
-        if (this$1.isContextual("from")) break
-        elt$1.imported = this$1.parseIdent()
-        if (isDummy(elt$1.imported)) break
-        elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : elt$1.imported
-        this$1.finishNode(elt$1, "ImportSpecifier")
-      }
-      elts.push(elt$1)
-      this$1.eat(__acorn.tokTypes.comma)
-    }
-    this.eat(__acorn.tokTypes.braceR)
-    this.popCx()
-  }
-  return elts
-}
-
-lp$1.parseExportSpecifierList = function() {
-  var this$1 = this;
-
-  var elts = []
-  var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart
-  this.pushCx()
-  this.eat(__acorn.tokTypes.braceL)
-  if (this.curLineStart > continuedLine) continuedLine = this.curLineStart
-  while (!this.closes(__acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
-    if (this$1.isContextual("from")) break
-    var elt = this$1.startNode()
-    elt.local = this$1.parseIdent()
-    if (isDummy(elt.local)) break
-    elt.exported = this$1.eatContextual("as") ? this$1.parseIdent() : elt.local
-    this$1.finishNode(elt, "ExportSpecifier")
-    elts.push(elt)
-    this$1.eat(__acorn.tokTypes.comma)
-  }
-  this.eat(__acorn.tokTypes.braceR)
-  this.popCx()
-  return elts
-}
-
-var lp$2 = LooseParser.prototype
-
-lp$2.checkLVal = function(expr) {
-  if (!expr) return expr
-  switch (expr.type) {
-  case "Identifier":
-  case "MemberExpression":
-    return expr
-
-  case "ParenthesizedExpression":
-    expr.expression = this.checkLVal(expr.expression)
-    return expr
-
-  default:
-    return this.dummyIdent()
-  }
-}
-
-lp$2.parseExpression = function(noIn) {
-  var this$1 = this;
-
-  var start = this.storeCurrentPos()
-  var expr = this.parseMaybeAssign(noIn)
-  if (this.tok.type === __acorn.tokTypes.comma) {
-    var node = this.startNodeAt(start)
-    node.expressions = [expr]
-    while (this.eat(__acorn.tokTypes.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn))
-    return this.finishNode(node, "SequenceExpression")
-  }
-  return expr
-}
-
-lp$2.parseParenExpression = function() {
-  this.pushCx()
-  this.expect(__acorn.tokTypes.parenL)
-  var val = this.parseExpression()
-  this.popCx()
-  this.expect(__acorn.tokTypes.parenR)
-  return val
-}
-
-lp$2.parseMaybeAssign = function(noIn) {
-  if (this.toks.isContextual("yield")) {
-    var node = this.startNode()
-    this.next()
-    if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type != __acorn.tokTypes.star && !this.tok.type.startsExpr)) {
-      node.delegate = false
-      node.argument = null
-    } else {
-      node.delegate = this.eat(__acorn.tokTypes.star)
-      node.argument = this.parseMaybeAssign()
-    }
-    return this.finishNode(node, "YieldExpression")
-  }
-
-  var start = this.storeCurrentPos()
-  var left = this.parseMaybeConditional(noIn)
-  if (this.tok.type.isAssign) {
-    var node$1 = this.startNodeAt(start)
-    node$1.operator = this.tok.value
-    node$1.left = this.tok.type === __acorn.tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left)
-    this.next()
-    node$1.right = this.parseMaybeAssign(noIn)
-    return this.finishNode(node$1, "AssignmentExpression")
-  }
-  return left
-}
-
-lp$2.parseMaybeConditional = function(noIn) {
-  var start = this.storeCurrentPos()
-  var expr = this.parseExprOps(noIn)
-  if (this.eat(__acorn.tokTypes.question)) {
-    var node = this.startNodeAt(start)
-    node.test = expr
-    node.consequent = this.parseMaybeAssign()
-    node.alternate = this.expect(__acorn.tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent()
-    return this.finishNode(node, "ConditionalExpression")
-  }
-  return expr
-}
-
-lp$2.parseExprOps = function(noIn) {
-  var start = this.storeCurrentPos()
-  var indent = this.curIndent, line = this.curLineStart
-  return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line)
-}
-
-lp$2.parseExprOp = function(left, start, minPrec, noIn, indent, line) {
-  if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left
-  var prec = this.tok.type.binop
-  if (prec != null && (!noIn || this.tok.type !== __acorn.tokTypes._in)) {
-    if (prec > minPrec) {
-      var node = this.startNodeAt(start)
-      node.left = left
-      node.operator = this.tok.value
-      this.next()
-      if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) {
-        node.right = this.dummyIdent()
-      } else {
-        var rightStart = this.storeCurrentPos()
-        node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line)
-      }
-      this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression")
-      return this.parseExprOp(node, start, minPrec, noIn, indent, line)
-    }
-  }
-  return left
-}
-
-lp$2.parseMaybeUnary = function(sawUnary) {
-  var this$1 = this;
-
-  var start = this.storeCurrentPos(), expr
-  if (this.options.ecmaVersion >= 8 && this.inAsync && this.toks.isContextual("await")) {
-    expr = this.parseAwait()
-    sawUnary = true
-  } else if (this.tok.type.prefix) {
-    var node = this.startNode(), update = this.tok.type === __acorn.tokTypes.incDec
-    if (!update) sawUnary = true
-    node.operator = this.tok.value
-    node.prefix = true
-    this.next()
-    node.argument = this.parseMaybeUnary(true)
-    if (update) node.argument = this.checkLVal(node.argument)
-    expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression")
-  } else if (this.tok.type === __acorn.tokTypes.ellipsis) {
-    var node$1 = this.startNode()
-    this.next()
-    node$1.argument = this.parseMaybeUnary(sawUnary)
-    expr = this.finishNode(node$1, "SpreadElement")
-  } else {
-    expr = this.parseExprSubscripts()
-    while (this.tok.type.postfix && !this.canInsertSemicolon()) {
-      var node$2 = this$1.startNodeAt(start)
-      node$2.operator = this$1.tok.value
-      node$2.prefix = false
-      node$2.argument = this$1.checkLVal(expr)
-      this$1.next()
-      expr = this$1.finishNode(node$2, "UpdateExpression")
-    }
-  }
-
-  if (!sawUnary && this.eat(__acorn.tokTypes.starstar)) {
-    var node$3 = this.startNodeAt(start)
-    node$3.operator = "**"
-    node$3.left = expr
-    node$3.right = this.parseMaybeUnary(false)
-    return this.finishNode(node$3, "BinaryExpression")
-  }
-
-  return expr
-}
-
-lp$2.parseExprSubscripts = function() {
-  var start = this.storeCurrentPos()
-  return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart)
-}
-
-lp$2.parseSubscripts = function(base, start, noCalls, startIndent, line) {
-  var this$1 = this;
-
-  for (;;) {
-    if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine()) {
-      if (this$1.tok.type == __acorn.tokTypes.dot && this$1.curIndent == startIndent)
-        --startIndent
-      else
-        return base
-    }
-
-    var maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this$1.canInsertSemicolon()
-
-    if (this$1.eat(__acorn.tokTypes.dot)) {
-      var node = this$1.startNodeAt(start)
-      node.object = base
-      if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine())
-        node.property = this$1.dummyIdent()
-      else
-        node.property = this$1.parsePropertyAccessor() || this$1.dummyIdent()
-      node.computed = false
-      base = this$1.finishNode(node, "MemberExpression")
-    } else if (this$1.tok.type == __acorn.tokTypes.bracketL) {
-      this$1.pushCx()
-      this$1.next()
-      var node$1 = this$1.startNodeAt(start)
-      node$1.object = base
-      node$1.property = this$1.parseExpression()
-      node$1.computed = true
-      this$1.popCx()
-      this$1.expect(__acorn.tokTypes.bracketR)
-      base = this$1.finishNode(node$1, "MemberExpression")
-    } else if (!noCalls && this$1.tok.type == __acorn.tokTypes.parenL) {
-      var exprList = this$1.parseExprList(__acorn.tokTypes.parenR)
-      if (maybeAsyncArrow && this$1.eat(__acorn.tokTypes.arrow))
-        return this$1.parseArrowExpression(this$1.startNodeAt(start), exprList, true)
-      var node$2 = this$1.startNodeAt(start)
-      node$2.callee = base
-      node$2.arguments = exprList
-      base = this$1.finishNode(node$2, "CallExpression")
-    } else if (this$1.tok.type == __acorn.tokTypes.backQuote) {
-      var node$3 = this$1.startNodeAt(start)
-      node$3.tag = base
-      node$3.quasi = this$1.parseTemplate()
-      base = this$1.finishNode(node$3, "TaggedTemplateExpression")
-    } else {
-      return base
-    }
-  }
-}
-
-lp$2.parseExprAtom = function() {
-  var node
-  switch (this.tok.type) {
-  case __acorn.tokTypes._this:
-  case __acorn.tokTypes._super:
-    var type = this.tok.type === __acorn.tokTypes._this ? "ThisExpression" : "Super"
-    node = this.startNode()
-    this.next()
-    return this.finishNode(node, type)
-
-  case __acorn.tokTypes.name:
-    var start = this.storeCurrentPos()
-    var id = this.parseIdent()
-    var isAsync = false
-    if (id.name === "async" && !this.canInsertSemicolon()) {
-      if (this.eat(__acorn.tokTypes._function))
-        return this.parseFunction(this.startNodeAt(start), false, true)
-      if (this.tok.type === __acorn.tokTypes.name) {
-        id = this.parseIdent()
-        isAsync = true
-      }
-    }
-    return this.eat(__acorn.tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id
-
-  case __acorn.tokTypes.regexp:
-    node = this.startNode()
-    var val = this.tok.value
-    node.regex = {pattern: val.pattern, flags: val.flags}
-    node.value = val.value
-    node.raw = this.input.slice(this.tok.start, this.tok.end)
-    this.next()
-    return this.finishNode(node, "Literal")
-
-  case __acorn.tokTypes.num: case __acorn.tokTypes.string:
-    node = this.startNode()
-    node.value = this.tok.value
-    node.raw = this.input.slice(this.tok.start, this.tok.end)
-    this.next()
-    return this.finishNode(node, "Literal")
-
-  case __acorn.tokTypes._null: case __acorn.tokTypes._true: case __acorn.tokTypes._false:
-    node = this.startNode()
-    node.value = this.tok.type === __acorn.tokTypes._null ? null : this.tok.type === __acorn.tokTypes._true
-    node.raw = this.tok.type.keyword
-    this.next()
-    return this.finishNode(node, "Literal")
-
-  case __acorn.tokTypes.parenL:
-    var parenStart = this.storeCurrentPos()
-    this.next()
-    var inner = this.parseExpression()
-    this.expect(__acorn.tokTypes.parenR)
-    if (this.eat(__acorn.tokTypes.arrow)) {
-      // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy.
-      var params = inner.expressions || [inner]
-      if (params.length && isDummy(params[params.length - 1]))
-        params.pop()
-      return this.parseArrowExpression(this.startNodeAt(parenStart), params)
-    }
-    if (this.options.preserveParens) {
-      var par = this.startNodeAt(parenStart)
-      par.expression = inner
-      inner = this.finishNode(par, "ParenthesizedExpression")
-    }
-    return inner
-
-  case __acorn.tokTypes.bracketL:
-    node = this.startNode()
-    node.elements = this.parseExprList(__acorn.tokTypes.bracketR, true)
-    return this.finishNode(node, "ArrayExpression")
-
-  case __acorn.tokTypes.braceL:
-    return this.parseObj()
-
-  case __acorn.tokTypes._class:
-    return this.parseClass(false)
-
-  case __acorn.tokTypes._function:
-    node = this.startNode()
-    this.next()
-    return this.parseFunction(node, false)
-
-  case __acorn.tokTypes._new:
-    return this.parseNew()
-
-  case __acorn.tokTypes.backQuote:
-    return this.parseTemplate()
-
-  default:
-    return this.dummyIdent()
-  }
-}
-
-lp$2.parseNew = function() {
-  var node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart
-  var meta = this.parseIdent(true)
-  if (this.options.ecmaVersion >= 6 && this.eat(__acorn.tokTypes.dot)) {
-    node.meta = meta
-    node.property = this.parseIdent(true)
-    return this.finishNode(node, "MetaProperty")
-  }
-  var start = this.storeCurrentPos()
-  node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line)
-  if (this.tok.type == __acorn.tokTypes.parenL) {
-    node.arguments = this.parseExprList(__acorn.tokTypes.parenR)
-  } else {
-    node.arguments = []
-  }
-  return this.finishNode(node, "NewExpression")
-}
-
-lp$2.parseTemplateElement = function() {
-  var elem = this.startNode()
-  elem.value = {
-    raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, "\n"),
-    cooked: this.tok.value
-  }
-  this.next()
-  elem.tail = this.tok.type === __acorn.tokTypes.backQuote
-  return this.finishNode(elem, "TemplateElement")
-}
-
-lp$2.parseTemplate = function() {
-  var this$1 = this;
-
-  var node = this.startNode()
-  this.next()
-  node.expressions = []
-  var curElt = this.parseTemplateElement()
-  node.quasis = [curElt]
-  while (!curElt.tail) {
-    this$1.next()
-    node.expressions.push(this$1.parseExpression())
-    if (this$1.expect(__acorn.tokTypes.braceR)) {
-      curElt = this$1.parseTemplateElement()
-    } else {
-      curElt = this$1.startNode()
-      curElt.value = {cooked: "", raw: ""}
-      curElt.tail = true
-      this$1.finishNode(curElt, "TemplateElement")
-    }
-    node.quasis.push(curElt)
-  }
-  this.expect(__acorn.tokTypes.backQuote)
-  return this.finishNode(node, "TemplateLiteral")
-}
-
-lp$2.parseObj = function() {
-  var this$1 = this;
-
-  var node = this.startNode()
-  node.properties = []
-  this.pushCx()
-  var indent = this.curIndent + 1, line = this.curLineStart
-  this.eat(__acorn.tokTypes.braceL)
-  if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart }
-  while (!this.closes(__acorn.tokTypes.braceR, indent, line)) {
-    var prop = this$1.startNode(), isGenerator, isAsync, start
-    if (this$1.options.ecmaVersion >= 6) {
-      start = this$1.storeCurrentPos()
-      prop.method = false
-      prop.shorthand = false
-      isGenerator = this$1.eat(__acorn.tokTypes.star)
-    }
-    this$1.parsePropertyName(prop)
-    if (!prop.computed &&
-        prop.key.type === "Identifier" && prop.key.name === "async" && this$1.tok.type !== __acorn.tokTypes.parenL &&
-        this$1.tok.type !== __acorn.tokTypes.colon && !this$1.canInsertSemicolon()) {
-      this$1.parsePropertyName(prop)
-      isAsync = true
-    } else {
-      isAsync = false
-    }
-    if (isDummy(prop.key)) { if (isDummy(this$1.parseMaybeAssign())) this$1.next(); this$1.eat(__acorn.tokTypes.comma); continue }
-    if (this$1.eat(__acorn.tokTypes.colon)) {
-      prop.kind = "init"
-      prop.value = this$1.parseMaybeAssign()
-    } else if (this$1.options.ecmaVersion >= 6 && (this$1.tok.type === __acorn.tokTypes.parenL || this$1.tok.type === __acorn.tokTypes.braceL)) {
-      prop.kind = "init"
-      prop.method = true
-      prop.value = this$1.parseMethod(isGenerator, isAsync)
-    } else if (this$1.options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
-               !prop.computed && (prop.key.name === "get" || prop.key.name === "set") &&
-               (this$1.tok.type != __acorn.tokTypes.comma && this$1.tok.type != __acorn.tokTypes.braceR)) {
-      prop.kind = prop.key.name
-      this$1.parsePropertyName(prop)
-      prop.value = this$1.parseMethod(false)
-    } else {
-      prop.kind = "init"
-      if (this$1.options.ecmaVersion >= 6) {
-        if (this$1.eat(__acorn.tokTypes.eq)) {
-          var assign = this$1.startNodeAt(start)
-          assign.operator = "="
-          assign.left = prop.key
-          assign.right = this$1.parseMaybeAssign()
-          prop.value = this$1.finishNode(assign, "AssignmentExpression")
-        } else {
-          prop.value = prop.key
-        }
-      } else {
-        prop.value = this$1.dummyIdent()
-      }
-      prop.shorthand = true
-    }
-    node.properties.push(this$1.finishNode(prop, "Property"))
-    this$1.eat(__acorn.tokTypes.comma)
-  }
-  this.popCx()
-  if (!this.eat(__acorn.tokTypes.braceR)) {
-    // If there is no closing brace, make the node span to the start
-    // of the next token (this is useful for Tern)
-    this.last.end = this.tok.start
-    if (this.options.locations) this.last.loc.end = this.tok.loc.start
-  }
-  return this.finishNode(node, "ObjectExpression")
-}
-
-lp$2.parsePropertyName = function(prop) {
-  if (this.options.ecmaVersion >= 6) {
-    if (this.eat(__acorn.tokTypes.bracketL)) {
-      prop.computed = true
-      prop.key = this.parseExpression()
-      this.expect(__acorn.tokTypes.bracketR)
-      return
-    } else {
-      prop.computed = false
-    }
-  }
-  var key = (this.tok.type === __acorn.tokTypes.num || this.tok.type === __acorn.tokTypes.string) ? this.parseExprAtom() : this.parseIdent()
-  prop.key = key || this.dummyIdent()
-}
-
-lp$2.parsePropertyAccessor = function() {
-  if (this.tok.type === __acorn.tokTypes.name || this.tok.type.keyword) return this.parseIdent()
-}
-
-lp$2.parseIdent = function() {
-  var name = this.tok.type === __acorn.tokTypes.name ? this.tok.value : this.tok.type.keyword
-  if (!name) return this.dummyIdent()
-  var node = this.startNode()
-  this.next()
-  node.name = name
-  return this.finishNode(node, "Identifier")
-}
-
-lp$2.initFunction = function(node) {
-  node.id = null
-  node.params = []
-  if (this.options.ecmaVersion >= 6) {
-    node.generator = false
-    node.expression = false
-  }
-  if (this.options.ecmaVersion >= 8)
-    node.async = false
-}
-
-// Convert existing expression atom to assignable pattern
-// if possible.
-
-lp$2.toAssignable = function(node, binding) {
-  var this$1 = this;
-
-  if (!node || node.type == "Identifier" || (node.type == "MemberExpression" && !binding)) {
-    // Okay
-  } else if (node.type == "ParenthesizedExpression") {
-    node.expression = this.toAssignable(node.expression, binding)
-  } else if (this.options.ecmaVersion < 6) {
-    return this.dummyIdent()
-  } else if (node.type == "ObjectExpression") {
-    node.type = "ObjectPattern"
-    var props = node.properties
-    for (var i = 0; i < props.length; i++)
-      props[i].value = this$1.toAssignable(props[i].value, binding)
-  } else if (node.type == "ArrayExpression") {
-    node.type = "ArrayPattern"
-    this.toAssignableList(node.elements, binding)
-  } else if (node.type == "SpreadElement") {
-    node.type = "RestElement"
-    node.argument = this.toAssignable(node.argument, binding)
-  } else if (node.type == "AssignmentExpression") {
-    node.type = "AssignmentPattern"
-    delete node.operator
-  } else {
-    return this.dummyIdent()
-  }
-  return node
-}
-
-lp$2.toAssignableList = function(exprList, binding) {
-  var this$1 = this;
-
-  for (var i = 0; i < exprList.length; i++)
-    exprList[i] = this$1.toAssignable(exprList[i], binding)
-  return exprList
-}
-
-lp$2.parseFunctionParams = function(params) {
-  params = this.parseExprList(__acorn.tokTypes.parenR)
-  return this.toAssignableList(params, true)
-}
-
-lp$2.parseMethod = function(isGenerator, isAsync) {
-  var node = this.startNode(), oldInAsync = this.inAsync
-  this.initFunction(node)
-  if (this.options.ecmaVersion >= 6)
-    node.generator = !!isGenerator
-  if (this.options.ecmaVersion >= 8)
-    node.async = !!isAsync
-  this.inAsync = node.async
-  node.params = this.parseFunctionParams()
-  node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== __acorn.tokTypes.braceL
-  node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock()
-  this.inAsync = oldInAsync
-  return this.finishNode(node, "FunctionExpression")
-}
-
-lp$2.parseArrowExpression = function(node, params, isAsync) {
-  var oldInAsync = this.inAsync
-  this.initFunction(node)
-  if (this.options.ecmaVersion >= 8)
-    node.async = !!isAsync
-  this.inAsync = node.async
-  node.params = this.toAssignableList(params, true)
-  node.expression = this.tok.type !== __acorn.tokTypes.braceL
-  node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock()
-  this.inAsync = oldInAsync
-  return this.finishNode(node, "ArrowFunctionExpression")
-}
-
-lp$2.parseExprList = function(close, allowEmpty) {
-  var this$1 = this;
-
-  this.pushCx()
-  var indent = this.curIndent, line = this.curLineStart, elts = []
-  this.next() // Opening bracket
-  while (!this.closes(close, indent + 1, line)) {
-    if (this$1.eat(__acorn.tokTypes.comma)) {
-      elts.push(allowEmpty ? null : this$1.dummyIdent())
-      continue
-    }
-    var elt = this$1.parseMaybeAssign()
-    if (isDummy(elt)) {
-      if (this$1.closes(close, indent, line)) break
-      this$1.next()
-    } else {
-      elts.push(elt)
-    }
-    this$1.eat(__acorn.tokTypes.comma)
-  }
-  this.popCx()
-  if (!this.eat(close)) {
-    // If there is no closing brace, make the node span to the start
-    // of the next token (this is useful for Tern)
-    this.last.end = this.tok.start
-    if (this.options.locations) this.last.loc.end = this.tok.loc.start
-  }
-  return elts
-}
-
-lp$2.parseAwait = function() {
-  var node = this.startNode()
-  this.next()
-  node.argument = this.parseMaybeUnary()
-  return this.finishNode(node, "AwaitExpression")
-}
-
-// Acorn: Loose parser
-//
-// This module provides an alternative parser (`parse_dammit`) that
-// exposes that same interface as `parse`, but will try to parse
-// anything as JavaScript, repairing syntax error the best it can.
-// There are circumstances in which it will raise an error and give
-// up, but they are very rare. The resulting AST will be a mostly
-// valid JavaScript AST (as per the [Mozilla parser API][api], except
-// that:
-//
-// - Return outside functions is allowed
-//
-// - Label consistency (no conflicts, break only to existing labels)
-//   is not enforced.
-//
-// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever
-//   the parser got too confused to return anything meaningful.
-//
-// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
-//
-// The expected use for this is to *first* try `acorn.parse`, and only
-// if that fails switch to `parse_dammit`. The loose parser might
-// parse badly indented code incorrectly, so **don't** use it as
-// your default parser.
-//
-// Quite a lot of acorn.js is duplicated here. The alternative was to
-// add a *lot* of extra cruft to that file, making it less readable
-// and slower. Copying and editing the code allowed me to make
-// invasive changes and simplifications without creating a complicated
-// tangle.
-
-__acorn.defaultOptions.tabSize = 4
-
-// eslint-disable-next-line camelcase
-function parse_dammit(input, options) {
-  var p = new LooseParser(input, options)
-  p.next()
-  return p.parseTopLevel()
-}
-
-__acorn.addLooseExports(parse_dammit, LooseParser, pluginsLoose)
-
-exports.parse_dammit = parse_dammit;
-exports.LooseParser = LooseParser;
-exports.pluginsLoose = pluginsLoose;
-
-Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
-// clang-format on
diff --git a/front_end/formatter_worker/module.json b/front_end/formatter_worker/module.json
deleted file mode 100644
index c7cc03b..0000000
--- a/front_end/formatter_worker/module.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-    "dependencies": [
-        "platform",
-        "text_utils",
-        "cm_headless"
-    ],
-    "scripts": [
-        "../cm_web_modes/css.js",
-        "../cm_web_modes/xml.js",
-        "ESTreeWalker.js",
-        "FormatterWorker.js",
-        "acorn/acorn.js",
-        "acorn/acorn_loose.js",
-        "CSSFormatter.js",
-        "AcornTokenizer.js",
-        "JavaScriptFormatter.js",
-        "FormattedContentBuilder.js",
-        "CSSRuleParser.js",
-        "HTMLFormatter.js",
-        "IdentityFormatter.js",
-        "JavaScriptOutline.js",
-        "RelaxedJSONParser.js"
-    ],
-    "skip_compilation": [
-        "acorn/acorn.js",
-        "acorn/acorn_loose.js",
-        "../cm_web_modes/css.js",
-        "../cm_web_modes/xml.js"
-    ]
-}
diff --git a/front_end/har_importer/HARFormat.js b/front_end/har_importer/HARFormat.js
deleted file mode 100644
index 9f0a372..0000000
--- a/front_end/har_importer/HARFormat.js
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-HARImporter.HARBase = class {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    if (!data || typeof data !== 'object')
-      throw 'First parameter is expected to be an object';
-  }
-
-  /**
-   * @param {*} data
-   * @return {!Date}
-   */
-  static _safeDate(data) {
-    const date = new Date(data);
-    if (!Number.isNaN(date.getTime()))
-      return date;
-    throw 'Invalid date format';
-  }
-
-  /**
-   * @param {*} data
-   * @return {number}
-   */
-  static _safeNumber(data) {
-    const result = Number(data);
-    if (!Number.isNaN(result))
-      return result;
-    throw 'Casting to number results in NaN';
-  }
-
-  /**
-   * @param {*} data
-   * @return {number|undefined}
-   */
-  static _optionalNumber(data) {
-    return data !== undefined ? HARImporter.HARBase._safeNumber(data) : undefined;
-  }
-
-  /**
-   * @param {*} data
-   * @return {string|undefined}
-   */
-  static _optionalString(data) {
-    return data !== undefined ? String(data) : undefined;
-  }
-
-  /**
-   * @param {string} name
-   * @return {string|undefined}
-   */
-  customAsString(name) {
-    // Har specification says starting with '_' is a custom property, but closure uses '_' as a private property.
-    const value = /** @type {!Object} */ (this)['_' + name];
-    return value !== undefined ? String(value) : undefined;
-  }
-
-  /**
-   * @param {string} name
-   * @return {number|undefined}
-   */
-  customAsNumber(name) {
-    // Har specification says starting with '_' is a custom property, but closure uses '_' as a private property.
-    let value = /** @type {!Object} */ (this)['_' + name];
-    if (value === undefined)
-      return;
-    value = Number(value);
-    if (Number.isNaN(value))
-      return;
-    return value;
-  }
-};
-
-// Using any of these classes may throw.
-HARImporter.HARRoot = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.log = new HARImporter.HARLog(data['log']);
-  }
-};
-
-HARImporter.HARLog = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.version = String(data['version']);
-    this.creator = new HARImporter.HARCreator(data['creator']);
-    this.browser = data['browser'] ? new HARImporter.HARCreator(data['browser']) : undefined;
-    this.pages = Array.isArray(data['pages']) ? data['pages'].map(page => new HARImporter.HARPage(page)) : [];
-    if (!Array.isArray(data['entries']))
-      throw 'log.entries is expected to be an array';
-    this.entries = data['entries'].map(entry => new HARImporter.HAREntry(entry));
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARCreator = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.name = String(data['name']);
-    this.version = String(data['version']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARPage = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.startedDateTime = HARImporter.HARBase._safeDate(data['startedDateTime']);
-    this.id = String(data['id']);
-    this.title = String(data['title']);
-    this.pageTimings = new HARImporter.HARPageTimings(data['pageTimings']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARPageTimings = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.onContentLoad = HARImporter.HARBase._optionalNumber(data['onContentLoad']);
-    this.onLoad = HARImporter.HARBase._optionalNumber(data['onLoad']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HAREntry = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.pageref = HARImporter.HARBase._optionalString(data['pageref']);
-    this.startedDateTime = HARImporter.HARBase._safeDate(data['startedDateTime']);
-    this.time = HARImporter.HARBase._safeNumber(data['time']);
-    this.request = new HARImporter.HARRequest(data['request']);
-    this.response = new HARImporter.HARResponse(data['response']);
-    this.cache = {};  // Not yet implemented.
-    this.timings = new HARImporter.HARTimings(data['timings']);
-    this.serverIPAddress = HARImporter.HARBase._optionalString(data['serverIPAddress']);
-    this.connection = HARImporter.HARBase._optionalString(data['connection']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-
-    // Chrome specific.
-    this._fromCache = HARImporter.HARBase._optionalString(data['_fromCache']);
-  }
-};
-
-HARImporter.HARRequest = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.method = String(data['method']);
-    this.url = String(data['url']);
-    this.httpVersion = String(data['httpVersion']);
-    this.cookies =
-        Array.isArray(data['cookies']) ? data['cookies'].map(cookie => new HARImporter.HARCookie(cookie)) : [];
-    this.headers =
-        Array.isArray(data['headers']) ? data['headers'].map(header => new HARImporter.HARHeader(header)) : [];
-    this.queryString =
-        Array.isArray(data['queryString']) ? data['queryString'].map(qs => new HARImporter.HARQueryString(qs)) : [];
-    this.postData = data['postData'] ? new HARImporter.HARPostData(data['postData']) : undefined;
-    this.headersSize = HARImporter.HARBase._safeNumber(data['headersSize']);
-    this.bodySize = HARImporter.HARBase._safeNumber(data['bodySize']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARResponse = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.status = HARImporter.HARBase._safeNumber(data['status']);
-    this.statusText = String(data['statusText']);
-    this.httpVersion = String(data['httpVersion']);
-    this.cookies =
-        Array.isArray(data['cookies']) ? data['cookies'].map(cookie => new HARImporter.HARCookie(cookie)) : [];
-    this.headers =
-        Array.isArray(data['headers']) ? data['headers'].map(header => new HARImporter.HARHeader(header)) : [];
-    this.content = new HARImporter.HARContent(data['content']);
-    this.redirectURL = String(data['redirectURL']);
-    this.headersSize = HARImporter.HARBase._safeNumber(data['headersSize']);
-    this.bodySize = HARImporter.HARBase._safeNumber(data['bodySize']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-
-    // Chrome specific.
-    this._transferSize = HARImporter.HARBase._optionalNumber(data['_transferSize']);
-    this._error = HARImporter.HARBase._optionalString(data['_error']);
-  }
-};
-
-HARImporter.HARCookie = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.name = String(data['name']);
-    this.value = String(data['value']);
-    this.path = HARImporter.HARBase._optionalString(data['path']);
-    this.domain = HARImporter.HARBase._optionalString(data['domain']);
-    this.expires = data['expires'] ? HARImporter.HARBase._safeDate(data['expires']) : undefined;
-    this.httpOnly = data['httpOnly'] !== undefined ? !!data['httpOnly'] : undefined;
-    this.secure = data['secure'] !== undefined ? !!data['secure'] : undefined;
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARHeader = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.name = String(data['name']);
-    this.value = String(data['value']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARQueryString = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.name = String(data['name']);
-    this.value = String(data['value']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARPostData = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.mimeType = String(data['mimeType']);
-    this.params = Array.isArray(data['params']) ? data['params'].map(param => new HARImporter.HARParam(param)) : [];
-    this.text = String(data['text']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARParam = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.name = String(data['name']);
-    this.value = HARImporter.HARBase._optionalString(data['value']);
-    this.fileName = HARImporter.HARBase._optionalString(data['fileName']);
-    this.contentType = HARImporter.HARBase._optionalString(data['contentType']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARContent = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.size = HARImporter.HARBase._safeNumber(data['size']);
-    this.compression = HARImporter.HARBase._optionalNumber(data['compression']);
-    this.mimeType = String(data['mimeType']);
-    this.text = HARImporter.HARBase._optionalString(data['text']);
-    this.encoding = HARImporter.HARBase._optionalString(data['encoding']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-  }
-};
-
-HARImporter.HARTimings = class extends HARImporter.HARBase {
-  /**
-   * @param {*} data
-   */
-  constructor(data) {
-    super(data);
-    this.blocked = HARImporter.HARBase._optionalNumber(data['blocked']);
-    this.dns = HARImporter.HARBase._optionalNumber(data['dns']);
-    this.connect = HARImporter.HARBase._optionalNumber(data['connect']);
-    this.send = HARImporter.HARBase._safeNumber(data['send']);
-    this.wait = HARImporter.HARBase._safeNumber(data['wait']);
-    this.receive = HARImporter.HARBase._safeNumber(data['receive']);
-    this.ssl = HARImporter.HARBase._optionalNumber(data['ssl']);
-    this.comment = HARImporter.HARBase._optionalString(data['comment']);
-
-    // Chrome specific.
-    this._blocked_queueing = HARImporter.HARBase._optionalNumber(data['_blocked_queueing']);
-    this._blocked_proxy = HARImporter.HARBase._optionalNumber(data['_blocked_proxy']);
-  }
-};
diff --git a/front_end/har_importer/HARImporter.js b/front_end/har_importer/HARImporter.js
deleted file mode 100644
index 260f476..0000000
--- a/front_end/har_importer/HARImporter.js
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-HARImporter.Importer = class {
-  /**
-   * @param {!HARImporter.HARLog} log
-   * @return {!Array<!SDK.NetworkRequest>}
-   */
-  static requestsFromHARLog(log) {
-    /** @type {!Map<string, !HARImporter.HARPage>} */
-    const pages = new Map();
-    for (const page of log.pages)
-      pages.set(page.id, page);
-
-    log.entries.sort((a, b) => a.startedDateTime - b.startedDateTime);
-
-    /** @type {!Map<string, !BrowserSDK.PageLoad>} */
-    const pageLoads = new Map();
-    /** @type {!Array<!SDK.NetworkRequest>} */
-    const requests = [];
-    for (const entry of log.entries) {
-      let pageLoad = pageLoads.get(entry.pageref);
-      const documentURL = pageLoad ? pageLoad.mainRequest.url() : entry.request.url;
-      const request = new SDK.NetworkRequest('har-' + requests.length, entry.request.url, documentURL, '', '', null);
-      const page = pages.get(entry.pageref);
-      if (!pageLoad && page) {
-        pageLoad = HARImporter.Importer._buildPageLoad(page, request);
-        pageLoads.set(entry.pageref, pageLoad);
-      }
-      HARImporter.Importer._fillRequestFromHAREntry(request, entry, pageLoad);
-      if (pageLoad)
-        pageLoad.bindRequest(request);
-      requests.push(request);
-    }
-    return requests;
-  }
-
-  /**
-   * @param {!HARImporter.HARPage} page
-   * @param {!SDK.NetworkRequest} mainRequest
-   * @return {!BrowserSDK.PageLoad}
-   */
-  static _buildPageLoad(page, mainRequest) {
-    const pageLoad = new BrowserSDK.PageLoad(mainRequest);
-    pageLoad.startTime = page.startedDateTime;
-    pageLoad.contentLoadTime = page.pageTimings.onContentLoad * 1000;
-    pageLoad.loadTime = page.pageTimings.onLoad * 1000;
-    return pageLoad;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {!HARImporter.HAREntry} entry
-   * @param {?BrowserSDK.PageLoad} pageLoad
-   */
-  static _fillRequestFromHAREntry(request, entry, pageLoad) {
-    // Request data.
-    if (entry.request.postData)
-      request.setRequestFormData(true, entry.request.postData.text);
-    else
-      request.setRequestFormData(false, null);
-    request.connectionId = entry.connection || '';
-    request.requestMethod = entry.request.method;
-    request.setRequestHeaders(entry.request.headers);
-
-    // Response data.
-    if (entry.response.content.mimeType && entry.response.content.mimeType !== 'x-unknown')
-      request.mimeType = entry.response.content.mimeType;
-    request.responseHeaders = entry.response.headers;
-    request.statusCode = entry.response.status;
-    request.statusText = entry.response.statusText;
-    let protocol = entry.response.httpVersion.toLowerCase();
-    if (protocol === 'http/2.0')
-      protocol = 'h2';
-    request.protocol = protocol.replace(/^http\/2\.0?\+quic/, 'http/2+quic');
-
-    // Timing data.
-    const issueTime = entry.startedDateTime.getTime() / 1000;
-    request.setIssueTime(issueTime, issueTime);
-
-    // Content data.
-    const contentSize = entry.response.content.size > 0 ? entry.response.content.size : 0;
-    const headersSize = entry.response.headersSize > 0 ? entry.response.headersSize : 0;
-    const bodySize = entry.response.bodySize > 0 ? entry.response.bodySize : 0;
-    request.resourceSize = contentSize || (headersSize + bodySize);
-    let transferSize = entry.response.customAsNumber('transferSize');
-    if (transferSize === undefined)
-      transferSize = entry.response.headersSize + entry.response.bodySize;
-    request.setTransferSize(transferSize >= 0 ? transferSize : 0);
-
-    const fromCache = entry.customAsString('fromCache');
-    if (fromCache === 'memory')
-      request.setFromMemoryCache();
-    else if (fromCache === 'disk')
-      request.setFromDiskCache();
-
-    const contentData = {error: null, content: null, encoded: entry.response.content.encoding === 'base64'};
-    if (entry.response.content.text !== undefined)
-      contentData.content = entry.response.content.text;
-    request.setContentDataProvider(async () => contentData);
-
-    // Timing data.
-    HARImporter.Importer._setupTiming(request, issueTime, entry.time, entry.timings);
-
-    // Meta data.
-    request.setRemoteAddress(entry.serverIPAddress || '', 80);  // Har does not support port numbers.
-    let resourceType = (pageLoad && pageLoad.mainRequest === request) ?
-        Common.resourceTypes.Document :
-        Common.ResourceType.fromMimeType(entry.response.content.mimeType);
-    if (!resourceType)
-      resourceType = Common.ResourceType.fromURL(entry.request.url) || Common.resourceTypes.Other;
-    request.setResourceType(resourceType);
-
-    request.finished = true;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {number} issueTime
-   * @param {number} entryTotalDuration
-   * @param {!HARImporter.HARTimings} timings
-   */
-  static _setupTiming(request, issueTime, entryTotalDuration, timings) {
-    /**
-     * @param {number|undefined} timing
-     * @return {number}
-     */
-    function accumulateTime(timing) {
-      if (timing === undefined || timing < 0)
-        return -1;
-      lastEntry += timing;
-      return lastEntry;
-    }
-    let lastEntry = timings.blocked >= 0 ? timings.blocked : 0;
-
-    const proxy = timings.customAsNumber('blocked_proxy') || -1;
-    const queueing = timings.customAsNumber('blocked_queueing') || -1;
-
-    // SSL is part of connect for both HAR and Chrome's format so subtract it here.
-    const ssl = timings.ssl >= 0 ? timings.ssl : 0;
-    if (timings.connect > 0)
-      timings.connect -= ssl;
-    const timing = {
-      proxyStart: proxy > 0 ? lastEntry - proxy : -1,
-      proxyEnd: proxy > 0 ? lastEntry : -1,
-      requestTime: issueTime + (queueing > 0 ? queueing : 0) / 1000,
-      dnsStart: timings.dns >= 0 ? lastEntry : -1,
-      dnsEnd: accumulateTime(timings.dns),
-
-      // Add ssl to end time without modifying lastEntry (see comment above).
-      connectStart: timings.connect >= 0 ? lastEntry : -1,
-      connectEnd: accumulateTime(timings.connect) + ssl,
-
-      // Now update lastEntry to add ssl timing back in (see comment above).
-      sslStart: timings.ssl >= 0 ? lastEntry : -1,
-      sslEnd: accumulateTime(timings.ssl),
-
-      workerStart: -1,
-      workerReady: -1,
-      sendStart: timings.send >= 0 ? lastEntry : -1,
-      sendEnd: accumulateTime(timings.send),
-      pushStart: 0,
-      pushEnd: 0,
-      receiveHeadersEnd: accumulateTime(timings.wait)
-    };
-    accumulateTime(timings.receive);
-
-    request.timing = timing;
-    request.endTime = issueTime + Math.max(entryTotalDuration, lastEntry) / 1000;
-  }
-};
diff --git a/front_end/har_importer/module.json b/front_end/har_importer/module.json
deleted file mode 100644
index 81b0ba8..0000000
--- a/front_end/har_importer/module.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "dependencies": [
-        "common",
-        "browser_sdk"
-    ],
-    "scripts": [
-        "HARFormat.js",
-        "HARImporter.js"
-    ]
-}
diff --git a/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js b/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js
deleted file mode 100644
index f6e224e..0000000
--- a/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js
+++ /dev/null
@@ -1,684 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
-  HeapProfilerTestRunner.createJSHeapSnapshotMockObject = function() {
-    return {
-      _rootNodeIndex: 0,
-      _nodeTypeOffset: 0,
-      _nodeNameOffset: 1,
-      _nodeEdgeCountOffset: 2,
-      _nodeFieldCount: 3,
-      _edgeFieldsCount: 3,
-      _edgeTypeOffset: 0,
-      _edgeNameOffset: 1,
-      _edgeToNodeOffset: 2,
-      _nodeTypes: ['hidden', 'object'],
-      _edgeTypes: ['element', 'property', 'shortcut'],
-      _edgeShortcutType: -1,
-      _edgeHiddenType: -1,
-      _edgeElementType: 0,
-      _realNodesLength: 18,
-      nodes: new Uint32Array([0, 0, 2, 1, 1, 2, 1, 2, 2, 1, 3, 1, 1, 4, 0, 1, 5, 0]),
-      containmentEdges: new Uint32Array([2, 6, 3, 1, 7, 6, 0, 1, 6, 1, 8, 9, 1, 9, 9, 1, 10, 12, 1, 11, 15]),
-      strings: ['', 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'ac', 'bc', 'bd', 'ce'],
-      _firstEdgeIndexes: new Uint32Array([0, 6, 12, 18, 21, 21, 21]),
-      createNode: HeapSnapshotWorker.JSHeapSnapshot.prototype.createNode,
-      createEdge: HeapSnapshotWorker.JSHeapSnapshot.prototype.createEdge,
-      createRetainingEdge: HeapSnapshotWorker.JSHeapSnapshot.prototype.createRetainingEdge
-    };
-  };
-
-  HeapProfilerTestRunner.createHeapSnapshotMockRaw = function() {
-    return {
-      snapshot: {
-        meta: {
-          node_fields: ['type', 'name', 'id', 'self_size', 'retained_size', 'dominator', 'edge_count'],
-          node_types: [['hidden', 'object'], '', '', '', '', '', ''],
-          edge_fields: ['type', 'name_or_index', 'to_node'],
-          edge_types: [['element', 'property', 'shortcut'], '', '']
-        },
-
-        node_count: 6,
-        edge_count: 7
-      },
-
-      nodes: [
-        0, 0, 1, 0, 20, 0, 2, 1, 1, 2, 2, 2, 0,  2, 1, 2, 3, 3, 8, 0,  2,
-        1, 3, 4, 4, 10, 0, 1, 1, 4, 5, 5, 5, 14, 0, 1, 5, 6, 6, 6, 21, 0
-      ],
-
-      edges: [1, 6, 7, 1, 7, 14, 0, 1, 14, 1, 8, 21, 1, 9, 21, 1, 10, 28, 1, 11, 35],
-      strings: ['', 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'ac', 'bc', 'bd', 'ce']
-    };
-  };
-
-  HeapProfilerTestRunner._postprocessHeapSnapshotMock = function(mock) {
-    mock.nodes = new Uint32Array(mock.nodes);
-    mock.edges = new Uint32Array(mock.edges);
-    return mock;
-  };
-
-  HeapProfilerTestRunner.createHeapSnapshotMock = function() {
-    return HeapProfilerTestRunner._postprocessHeapSnapshotMock(HeapProfilerTestRunner.createHeapSnapshotMockRaw());
-  };
-
-  HeapProfilerTestRunner.createHeapSnapshotMockWithDOM = function() {
-    return HeapProfilerTestRunner._postprocessHeapSnapshotMock({
-      snapshot: {
-        meta: {
-          node_fields: ['type', 'name', 'id', 'edge_count'],
-          node_types: [['hidden', 'object', 'synthetic'], '', '', ''],
-          edge_fields: ['type', 'name_or_index', 'to_node'],
-          edge_types: [['element', 'hidden', 'internal'], '', '']
-        },
-
-        node_count: 13,
-        edge_count: 13
-      },
-
-      nodes: [
-        2, 0, 1, 4, 1, 11, 2, 2, 1, 11, 3, 3, 2,  5, 4, 0, 2,  6, 5, 1,  1,  1, 6, 0, 1,  2,
-        7, 1, 1, 4, 8, 2,  1, 8, 9, 0,  1, 7, 10, 0, 1, 3, 11, 0, 1, 10, 12, 0, 1, 9, 13, 0
-      ],
-
-      edges: [
-        0,  1, 4, 0,  2, 8, 0,  3, 12, 0,  4, 16, 0,  1, 20, 0,  2, 24, 0, 1,
-        24, 0, 2, 28, 1, 3, 32, 0, 1,  36, 0, 1,  40, 2, 12, 44, 2, 1,  48
-      ],
-
-      strings: ['', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'M', 'N', 'Window', 'native']
-    });
-  };
-
-  HeapProfilerTestRunner.HeapNode = function(name, selfSize, type, id) {
-    this._type = type || HeapProfilerTestRunner.HeapNode.Type.object;
-    this._name = name;
-    this._selfSize = selfSize || 0;
-    this._builder = null;
-    this._edges = {};
-    this._edgesCount = 0;
-    this._id = id;
-  };
-
-  HeapProfilerTestRunner.HeapNode.Type = {
-    'hidden': 'hidden',
-    'array': 'array',
-    'string': 'string',
-    'object': 'object',
-    'code': 'code',
-    'closure': 'closure',
-    'regexp': 'regexp',
-    'number': 'number',
-    'native': 'native',
-    'synthetic': 'synthetic',
-    'bigint': 'bigint'
-  };
-
-  HeapProfilerTestRunner.HeapNode.prototype = {
-    linkNode: function(node, type, nameOrIndex) {
-      if (!this._builder)
-        throw new Error('parent node is not connected to a snapshot');
-
-      if (!node._builder)
-        node._setBuilder(this._builder);
-
-      if (nameOrIndex === undefined)
-        nameOrIndex = this._edgesCount;
-
-      ++this._edgesCount;
-
-      if (nameOrIndex in this._edges) {
-        throw new Error(
-            'Can\'t add edge with the same nameOrIndex. nameOrIndex: ' + nameOrIndex +
-            ' oldNodeName: ' + this._edges[nameOrIndex]._name + ' newNodeName: ' + node._name);
-      }
-
-      this._edges[nameOrIndex] = new HeapProfilerTestRunner.HeapEdge(node, type, nameOrIndex);
-    },
-
-    _setBuilder: function(builder) {
-      if (this._builder)
-        throw new Error('node reusing is prohibited');
-
-      this._builder = builder;
-      this._ordinal = this._builder._registerNode(this);
-    },
-
-    _serialize: function(rawSnapshot) {
-      rawSnapshot.nodes.push(this._builder.lookupNodeType(this._type));
-      rawSnapshot.nodes.push(this._builder.lookupOrAddString(this._name));
-      rawSnapshot.nodes.push(this._id || this._ordinal * 2 + 1);
-      rawSnapshot.nodes.push(this._selfSize);
-      rawSnapshot.nodes.push(0);
-      rawSnapshot.nodes.push(0);
-      rawSnapshot.nodes.push(Object.keys(this._edges).length);
-
-      for (const i in this._edges)
-        this._edges[i]._serialize(rawSnapshot);
-    }
-  };
-
-  HeapProfilerTestRunner.HeapEdge = function(targetNode, type, nameOrIndex) {
-    this._targetNode = targetNode;
-    this._type = type;
-    this._nameOrIndex = nameOrIndex;
-  };
-
-  HeapProfilerTestRunner.HeapEdge.prototype = {
-    _serialize: function(rawSnapshot) {
-      if (!this._targetNode._builder)
-        throw new Error('Inconsistent state of node: ' + this._name + ' no builder assigned');
-
-      const builder = this._targetNode._builder;
-      rawSnapshot.edges.push(builder.lookupEdgeType(this._type));
-      rawSnapshot.edges.push(
-          (typeof this._nameOrIndex === 'string' ? builder.lookupOrAddString(this._nameOrIndex) : this._nameOrIndex));
-      rawSnapshot.edges.push(this._targetNode._ordinal * builder.nodeFieldsCount);
-    }
-  };
-
-  HeapProfilerTestRunner.HeapEdge.Type = {
-    'context': 'context',
-    'element': 'element',
-    'property': 'property',
-    'internal': 'internal',
-    'hidden': 'hidden',
-    'shortcut': 'shortcut',
-    'weak': 'weak'
-  };
-
-  HeapProfilerTestRunner.HeapSnapshotBuilder = function() {
-    this._nodes = [];
-    this._string2id = {};
-    this._strings = [];
-    this.nodeFieldsCount = 7;
-    this._nodeTypesMap = {};
-    this._nodeTypesArray = [];
-
-    for (const nodeType in HeapProfilerTestRunner.HeapNode.Type) {
-      this._nodeTypesMap[nodeType] = this._nodeTypesArray.length;
-      this._nodeTypesArray.push(nodeType);
-    }
-
-    this._edgeTypesMap = {};
-    this._edgeTypesArray = [];
-
-    for (const edgeType in HeapProfilerTestRunner.HeapEdge.Type) {
-      this._edgeTypesMap[edgeType] = this._edgeTypesArray.length;
-      this._edgeTypesArray.push(edgeType);
-    }
-
-    this.rootNode = new HeapProfilerTestRunner.HeapNode('root', 0, 'object');
-    this.rootNode._setBuilder(this);
-  };
-
-  HeapProfilerTestRunner.HeapSnapshotBuilder.prototype = {
-    generateSnapshot: function() {
-      const rawSnapshot = {
-        'snapshot': {
-          'meta': {
-            'node_fields': ['type', 'name', 'id', 'self_size', 'retained_size', 'dominator', 'edge_count'],
-            'node_types': [this._nodeTypesArray, 'string', 'number', 'number', 'number', 'number', 'number'],
-            'edge_fields': ['type', 'name_or_index', 'to_node'],
-            'edge_types': [this._edgeTypesArray, 'string_or_number', 'node']
-          }
-        },
-
-        'nodes': [],
-        'edges': [],
-        'strings': []
-      };
-
-      for (let i = 0; i < this._nodes.length; ++i)
-        this._nodes[i]._serialize(rawSnapshot);
-
-      rawSnapshot.strings = this._strings.slice();
-      const meta = rawSnapshot.snapshot.meta;
-      rawSnapshot.snapshot.edge_count = rawSnapshot.edges.length / meta.edge_fields.length;
-      rawSnapshot.snapshot.node_count = rawSnapshot.nodes.length / meta.node_fields.length;
-      return rawSnapshot;
-    },
-
-    createJSHeapSnapshot: function() {
-      const parsedSnapshot = HeapProfilerTestRunner._postprocessHeapSnapshotMock(this.generateSnapshot());
-      return new HeapSnapshotWorker.JSHeapSnapshot(parsedSnapshot, new HeapSnapshotWorker.HeapSnapshotProgress());
-    },
-
-    _registerNode: function(node) {
-      this._nodes.push(node);
-      return this._nodes.length - 1;
-    },
-
-    lookupNodeType: function(typeName) {
-      if (typeName === undefined)
-        throw new Error('wrong node type: ' + typeName);
-
-      if (!(typeName in this._nodeTypesMap))
-        throw new Error('wrong node type name: ' + typeName);
-
-      return this._nodeTypesMap[typeName];
-    },
-
-    lookupEdgeType: function(typeName) {
-      if (!(typeName in this._edgeTypesMap))
-        throw new Error('wrong edge type name: ' + typeName);
-
-      return this._edgeTypesMap[typeName];
-    },
-
-    lookupOrAddString: function(string) {
-      if (string in this._string2id)
-        return this._string2id[string];
-
-      this._string2id[string] = this._strings.length;
-      this._strings.push(string);
-      return this._strings.length - 1;
-    }
-  };
-
-  HeapProfilerTestRunner.createHeapSnapshot = function(instanceCount, firstId) {
-    let seed = 881669;
-
-    function pseudoRandom(limit) {
-      seed = seed * 355109 + 153763 >> 2 & 65535;
-      return seed % limit;
-    }
-
-    const builder = new HeapProfilerTestRunner.HeapSnapshotBuilder();
-    const rootNode = builder.rootNode;
-    const gcRootsNode =
-        new HeapProfilerTestRunner.HeapNode('(GC roots)', 0, HeapProfilerTestRunner.HeapNode.Type.synthetic);
-    rootNode.linkNode(gcRootsNode, HeapProfilerTestRunner.HeapEdge.Type.element);
-    const windowNode = new HeapProfilerTestRunner.HeapNode('Window', 20);
-    rootNode.linkNode(windowNode, HeapProfilerTestRunner.HeapEdge.Type.shortcut);
-    gcRootsNode.linkNode(windowNode, HeapProfilerTestRunner.HeapEdge.Type.element);
-
-    for (let i = 0; i < instanceCount; ++i) {
-      const sizeOfB = pseudoRandom(20) + 1;
-      const nodeB = new HeapProfilerTestRunner.HeapNode('B', sizeOfB, undefined, firstId++);
-      windowNode.linkNode(nodeB, HeapProfilerTestRunner.HeapEdge.Type.element);
-      const sizeOfA = pseudoRandom(50) + 1;
-      const nodeA = new HeapProfilerTestRunner.HeapNode('A', sizeOfA, undefined, firstId++);
-      nodeB.linkNode(nodeA, HeapProfilerTestRunner.HeapEdge.Type.property, 'a');
-      nodeA.linkNode(nodeA, HeapProfilerTestRunner.HeapEdge.Type.property, 'a');
-    }
-
-    return builder.generateSnapshot();
-  };
-};
-
-HeapProfilerTestRunner.createHeapSnapshotMockFactories();
-
-HeapProfilerTestRunner.startProfilerTest = function(callback) {
-  TestRunner.addResult('Profiler was enabled.');
-  HeapProfilerTestRunner._panelReset = TestRunner.override(UI.panels.heap_profiler, '_reset', function() {}, true);
-  TestRunner.addSniffer(UI.panels.heap_profiler, '_addProfileHeader', HeapProfilerTestRunner._profileHeaderAdded, true);
-  TestRunner.addSniffer(Profiler.ProfileView.prototype, 'refresh', HeapProfilerTestRunner._profileViewRefresh, true);
-  TestRunner.addSniffer(Profiler.HeapSnapshotView.prototype, 'show', HeapProfilerTestRunner._snapshotViewShown, true);
-
-  Profiler.HeapSnapshotContainmentDataGrid.prototype.defaultPopulateCount = function() {
-    return 10;
-  };
-
-  Profiler.HeapSnapshotConstructorsDataGrid.prototype.defaultPopulateCount = function() {
-    return 10;
-  };
-
-  Profiler.HeapSnapshotDiffDataGrid.prototype.defaultPopulateCount = function() {
-    return 5;
-  };
-
-  TestRunner.addResult('Detailed heap profiles were enabled.');
-  TestRunner.safeWrap(callback)();
-};
-
-HeapProfilerTestRunner.completeProfilerTest = function() {
-  TestRunner.addResult('');
-  TestRunner.addResult('Profiler was disabled.');
-  TestRunner.completeTest();
-};
-
-HeapProfilerTestRunner.runHeapSnapshotTestSuite = function(testSuite) {
-  const testSuiteTests = testSuite.slice();
-  let completeTestStack;
-
-  function runner() {
-    if (!testSuiteTests.length) {
-      if (completeTestStack)
-        TestRunner.addResult('FAIL: test already completed at ' + completeTestStack);
-
-      HeapProfilerTestRunner.completeProfilerTest();
-      completeTestStack = new Error().stack;
-      return;
-    }
-
-    const nextTest = testSuiteTests.shift();
-    TestRunner.addResult('');
-    TestRunner.addResult(
-        'Running: ' +
-        /function\s([^(]*)/.exec(nextTest)[1]);
-    HeapProfilerTestRunner._panelReset.call(UI.panels.heap_profiler);
-    TestRunner.safeWrap(nextTest)(runner, runner);
-  }
-
-  HeapProfilerTestRunner.startProfilerTest(runner);
-};
-
-HeapProfilerTestRunner.assertColumnContentsEqual = function(reference, actual) {
-  const length = Math.min(reference.length, actual.length);
-
-  for (let i = 0; i < length; ++i)
-    TestRunner.assertEquals(reference[i], actual[i], 'row ' + i);
-
-  if (reference.length > length)
-    TestRunner.addResult('extra rows in reference array:\n' + reference.slice(length).join('\n'));
-  else if (actual.length > length)
-    TestRunner.addResult('extra rows in actual array:\n' + actual.slice(length).join('\n'));
-};
-
-HeapProfilerTestRunner.checkArrayIsSorted = function(contents, sortType, sortOrder) {
-  function simpleComparator(a, b) {
-    return (a < b ? -1 : (a > b ? 1 : 0));
-  }
-
-  function parseSize(size) {
-    return parseInt(size.replace(/[\xa0,]/g, ''), 10);
-  }
-
-  const extractor = {
-    text: function(data) {
-      data;
-    },
-
-    number: function(data) {
-      return parseInt(data, 10);
-    },
-
-    size: parseSize,
-
-    name: function(data) {
-      return data;
-    },
-
-    id: function(data) {
-      return parseInt(data, 10);
-    }
-  }[sortType];
-
-  if (!extractor) {
-    TestRunner.addResult('Invalid sort type: ' + sortType);
-    return;
-  }
-
-  let acceptableComparisonResult;
-
-  if (sortOrder === DataGrid.DataGrid.Order.Ascending) {
-    acceptableComparisonResult = -1;
-  } else if (sortOrder === DataGrid.DataGrid.Order.Descending) {
-    acceptableComparisonResult = 1;
-  } else {
-    TestRunner.addResult('Invalid sort order: ' + sortOrder);
-    return;
-  }
-
-  for (let i = 0; i < contents.length - 1; ++i) {
-    const a = extractor(contents[i]);
-    const b = extractor(contents[i + 1]);
-    const result = simpleComparator(a, b);
-
-    if (result !== 0 && result !== acceptableComparisonResult) {
-      TestRunner.addResult(
-          'Elements ' + i + ' and ' + (i + 1) + ' are out of order: ' + a + ' ' + b + ' (' + sortOrder + ')');
-    }
-  }
-};
-
-HeapProfilerTestRunner.clickColumn = function(column, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const cell = this._currentGrid()._headerTableHeaders[column.id];
-
-  const event = {
-    target: {
-      enclosingNodeOrSelfWithNodeName: function() {
-        return cell;
-      }
-    }
-  };
-
-  function sortingComplete() {
-    HeapProfilerTestRunner._currentGrid().removeEventListener(
-        Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, this);
-    TestRunner.assertEquals(column.id, this._currentGrid().sortColumnId(), 'unexpected sorting');
-    column.sort = this._currentGrid().sortOrder();
-
-    function callCallback() {
-      callback(column);
-    }
-
-    setTimeout(callCallback, 0);
-  }
-
-  HeapProfilerTestRunner._currentGrid().addEventListener(
-      Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, this);
-  this._currentGrid()._clickInHeaderCell(event);
-};
-
-HeapProfilerTestRunner.clickRowAndGetRetainers = function(row, callback) {
-  callback = TestRunner.safeWrap(callback);
-
-  const event = {
-    target: {
-      enclosingNodeOrSelfWithNodeName: function() {
-        return row._element;
-      },
-
-      selectedNode: row
-    }
-  };
-
-  this._currentGrid()._mouseDownInDataTable(event);
-  const rootNode = HeapProfilerTestRunner.currentProfileView()._retainmentDataGrid.rootNode();
-  rootNode.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(() => callback(rootNode));
-};
-
-HeapProfilerTestRunner.clickShowMoreButton = function(buttonName, row, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const parent = row.parent;
-  parent.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(() => setTimeout(() => callback(parent), 0));
-  row[buttonName].click();
-};
-
-HeapProfilerTestRunner.columnContents = function(column, row) {
-  this._currentGrid().updateVisibleNodes();
-  const columnOrdinal = HeapProfilerTestRunner.viewColumns().indexOf(column);
-  const result = [];
-  const parent = row || this._currentGrid().rootNode();
-
-  for (let node = parent.children[0]; node; node = node.traverseNextNode(true, parent, true)) {
-    if (!node.selectable)
-      continue;
-
-    let content = node.element().children[columnOrdinal];
-
-    if (content.firstElementChild)
-      content = content.firstElementChild;
-
-    result.push(content.textContent);
-  }
-
-  return result;
-};
-
-HeapProfilerTestRunner.countDataRows = function(row, filter) {
-  let result = 0;
-
-  filter = filter || function(node) {
-    return node.selectable;
-  };
-
-  for (let node = row.children[0]; node; node = node.traverseNextNode(true, row, true)) {
-    if (filter(node))
-      ++result;
-  }
-
-  return result;
-};
-
-HeapProfilerTestRunner.expandRow = function(row, callback) {
-  callback = TestRunner.safeWrap(callback);
-  row.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete).then(() => setTimeout(() => callback(row), 0));
-
-  (function expand() {
-    if (row.hasChildren())
-      row.expand();
-    else
-      setTimeout(expand, 0);
-  })();
-};
-
-HeapProfilerTestRunner.findAndExpandGCRoots = function(callback) {
-  HeapProfilerTestRunner.findAndExpandRow('(GC roots)', callback);
-};
-
-HeapProfilerTestRunner.findAndExpandWindow = function(callback) {
-  HeapProfilerTestRunner.findAndExpandRow('Window', callback);
-};
-
-HeapProfilerTestRunner.findAndExpandRow = function(name, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const row = HeapProfilerTestRunner.findRow(name);
-  TestRunner.assertEquals(true, !!row, '"' + name + '" row');
-  HeapProfilerTestRunner.expandRow(row, callback);
-};
-
-HeapProfilerTestRunner.findButtonsNode = function(row, startNode) {
-  for (let node = startNode || row.children[0]; node; node = node.traverseNextNode(true, row, true)) {
-    if (!node.selectable && node.showNext)
-      return node;
-  }
-
-  return null;
-};
-
-HeapProfilerTestRunner.findRow = function(name, parent) {
-  function matcher(x) {
-    return x._name === name;
-  }
-
-  return HeapProfilerTestRunner.findMatchingRow(matcher, parent);
-};
-
-HeapProfilerTestRunner.findMatchingRow = function(matcher, parent) {
-  parent = parent || this._currentGrid().rootNode();
-
-  for (let node = parent.children[0]; node; node = node.traverseNextNode(true, parent, true)) {
-    if (matcher(node))
-      return node;
-  }
-
-  return null;
-};
-
-HeapProfilerTestRunner.switchToView = function(title, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const view = UI.panels.heap_profiler.visibleView;
-  view._changePerspectiveAndWait(title).then(callback);
-  HeapProfilerTestRunner._currentGrid().scrollContainer.style.height = '10000px';
-};
-
-HeapProfilerTestRunner.takeAndOpenSnapshot = async function(generator, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const snapshot = generator();
-  const profileType = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType;
-
-  function pushGeneratedSnapshot(reportProgress) {
-    if (reportProgress) {
-      profileType._reportHeapSnapshotProgress({data: {done: 50, total: 100, finished: false}});
-      profileType._reportHeapSnapshotProgress({data: {done: 100, total: 100, finished: true}});
-    }
-    snapshot.snapshot.typeId = 'HEAP';
-    profileType._addHeapSnapshotChunk({data: JSON.stringify(snapshot)});
-    return Promise.resolve();
-  }
-
-  HeapProfilerTestRunner._takeAndOpenSnapshotCallback = callback;
-  TestRunner.override(TestRunner.HeapProfilerAgent, 'takeHeapSnapshot', pushGeneratedSnapshot);
-  if (!UI.context.flavor(SDK.HeapProfilerModel))
-    await new Promise(resolve => UI.context.addFlavorChangeListener(SDK.HeapProfilerModel, resolve));
-  profileType._takeHeapSnapshot();
-};
-
-HeapProfilerTestRunner.viewColumns = function() {
-  return HeapProfilerTestRunner._currentGrid()._columnsArray;
-};
-
-HeapProfilerTestRunner.currentProfileView = function() {
-  return UI.panels.heap_profiler.visibleView;
-};
-
-HeapProfilerTestRunner._currentGrid = function() {
-  return this.currentProfileView()._dataGrid;
-};
-
-HeapProfilerTestRunner._snapshotViewShown = function() {
-  if (HeapProfilerTestRunner._takeAndOpenSnapshotCallback) {
-    const callback = HeapProfilerTestRunner._takeAndOpenSnapshotCallback;
-    HeapProfilerTestRunner._takeAndOpenSnapshotCallback = null;
-    const dataGrid = this._dataGrid;
-
-    function sortingComplete() {
-      dataGrid.removeEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, null);
-      callback();
-    }
-
-    dataGrid.addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, sortingComplete, null);
-  }
-};
-
-HeapProfilerTestRunner.showProfileWhenAdded = function(title) {
-  HeapProfilerTestRunner._showProfileWhenAdded = title;
-  return new Promise(resolve => HeapProfilerTestRunner._waitUntilProfileViewIsShown(title, resolve));
-};
-
-HeapProfilerTestRunner._profileHeaderAdded = function(profile) {
-  if (HeapProfilerTestRunner._showProfileWhenAdded === profile.title)
-    UI.panels.heap_profiler.showProfile(profile);
-};
-
-HeapProfilerTestRunner._waitUntilProfileViewIsShown = function(title, callback) {
-  callback = TestRunner.safeWrap(callback);
-  const profilesPanel = UI.panels.heap_profiler;
-
-  if (profilesPanel.visibleView && profilesPanel.visibleView.profile &&
-      profilesPanel.visibleView._profileHeader.title === title)
-    callback(profilesPanel.visibleView);
-  else
-    HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback = {title: title, callback: callback};
-
-};
-
-HeapProfilerTestRunner._profileViewRefresh = function() {
-  if (HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback &&
-      HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback.title === this._profileHeader.title) {
-    const callback = HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback;
-    delete HeapProfilerTestRunner._waitUntilProfileViewIsShownCallback;
-    callback.callback(this);
-  }
-};
-
-HeapProfilerTestRunner.startSamplingHeapProfiler = async function() {
-  if (!UI.context.flavor(SDK.HeapProfilerModel))
-    await new Promise(resolve => UI.context.addFlavorChangeListener(SDK.HeapProfilerModel, resolve));
-  Profiler.SamplingHeapProfileType.instance.startRecordingProfile();
-};
-
-HeapProfilerTestRunner.stopSamplingHeapProfiler = function() {
-  Profiler.SamplingHeapProfileType.instance.stopRecordingProfile();
-};
diff --git a/front_end/heap_profiler_test_runner/module.json b/front_end/heap_profiler_test_runner/module.json
deleted file mode 100644
index 0b2f64d..0000000
--- a/front_end/heap_profiler_test_runner/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "dependencies": [
-        "heap_snapshot_worker",
-        "test_runner",
-        "profiler",
-        "data_grid"
-    ],
-    "scripts": [
-        "HeapProfilerTestRunner.js"
-    ],
-    "skip_compilation": [
-        "HeapProfilerTestRunner.js"
-    ]
-}
diff --git a/front_end/heap_snapshot_model/HeapSnapshotModel.js b/front_end/heap_snapshot_model/HeapSnapshotModel.js
deleted file mode 100644
index 02d0cf9..0000000
--- a/front_end/heap_snapshot_model/HeapSnapshotModel.js
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-HeapSnapshotModel.HeapSnapshotProgressEvent = {
-  Update: 'ProgressUpdate',
-  BrokenSnapshot: 'BrokenSnapshot'
-};
-
-HeapSnapshotModel.baseSystemDistance = 100000000;
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.AllocationNodeCallers = class {
-  /**
-   * @param {!Array.<!HeapSnapshotModel.SerializedAllocationNode>} nodesWithSingleCaller
-   * @param {!Array.<!HeapSnapshotModel.SerializedAllocationNode>} branchingCallers
-   */
-  constructor(nodesWithSingleCaller, branchingCallers) {
-    /** @type {!Array.<!HeapSnapshotModel.SerializedAllocationNode>} */
-    this.nodesWithSingleCaller = nodesWithSingleCaller;
-    /** @type {!Array.<!HeapSnapshotModel.SerializedAllocationNode>} */
-    this.branchingCallers = branchingCallers;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.SerializedAllocationNode = class {
-  /**
-   * @param {number} nodeId
-   * @param {string} functionName
-   * @param {string} scriptName
-   * @param {number} scriptId
-   * @param {number} line
-   * @param {number} column
-   * @param {number} count
-   * @param {number} size
-   * @param {number} liveCount
-   * @param {number} liveSize
-   * @param {boolean} hasChildren
-   */
-  constructor(nodeId, functionName, scriptName, scriptId, line, column, count, size, liveCount, liveSize, hasChildren) {
-    /** @type {number} */
-    this.id = nodeId;
-    /** @type {string} */
-    this.name = functionName;
-    /** @type {string} */
-    this.scriptName = scriptName;
-    /** @type {number} */
-    this.scriptId = scriptId;
-    /** @type {number} */
-    this.line = line;
-    /** @type {number} */
-    this.column = column;
-    /** @type {number} */
-    this.count = count;
-    /** @type {number} */
-    this.size = size;
-    /** @type {number} */
-    this.liveCount = liveCount;
-    /** @type {number} */
-    this.liveSize = liveSize;
-    /** @type {boolean} */
-    this.hasChildren = hasChildren;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.AllocationStackFrame = class {
-  /**
-   * @param {string} functionName
-   * @param {string} scriptName
-   * @param {number} scriptId
-   * @param {number} line
-   * @param {number} column
-   */
-  constructor(functionName, scriptName, scriptId, line, column) {
-    /** @type {string} */
-    this.functionName = functionName;
-    /** @type {string} */
-    this.scriptName = scriptName;
-    /** @type {number} */
-    this.scriptId = scriptId;
-    /** @type {number} */
-    this.line = line;
-    /** @type {number} */
-    this.column = column;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.Node = class {
-  /**
-   * @param {number} id
-   * @param {string} name
-   * @param {number} distance
-   * @param {number} nodeIndex
-   * @param {number} retainedSize
-   * @param {number} selfSize
-   * @param {string} type
-   */
-  constructor(id, name, distance, nodeIndex, retainedSize, selfSize, type) {
-    this.id = id;
-    this.name = name;
-    this.distance = distance;
-    this.nodeIndex = nodeIndex;
-    this.retainedSize = retainedSize;
-    this.selfSize = selfSize;
-    this.type = type;
-
-    this.canBeQueried = false;
-    this.detachedDOMTreeNode = false;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.Edge = class {
-  /**
-   * @param {string} name
-   * @param {!HeapSnapshotModel.Node} node
-   * @param {string} type
-   * @param {number} edgeIndex
-   */
-  constructor(name, node, type, edgeIndex) {
-    this.name = name;
-    this.node = node;
-    this.type = type;
-    this.edgeIndex = edgeIndex;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.Aggregate = class {
-  constructor() {
-    /** @type {number} */
-    this.count;
-    /** @type {number} */
-    this.distance;
-    /** @type {number} */
-    this.self;
-    /** @type {number} */
-    this.maxRet;
-    /** @type {number} */
-    this.type;
-    /** @type {string} */
-    this.name;
-    /** @type {!Array.<number>} */
-    this.idxs;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.AggregateForDiff = class {
-  constructor() {
-    /** @type {!Array.<number>} */
-    this.indexes = [];
-    /** @type {!Array.<string>} */
-    this.ids = [];
-    /** @type {!Array.<number>} */
-    this.selfSizes = [];
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.Diff = class {
-  constructor() {
-    /** @type {number} */
-    this.addedCount = 0;
-    /** @type {number} */
-    this.removedCount = 0;
-    /** @type {number} */
-    this.addedSize = 0;
-    /** @type {number} */
-    this.removedSize = 0;
-    /** @type {!Array.<number>} */
-    this.deletedIndexes = [];
-    /** @type {!Array.<number>} */
-    this.addedIndexes = [];
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.DiffForClass = class {
-  constructor() {
-    /** @type {number} */
-    this.addedCount;
-    /** @type {number} */
-    this.removedCount;
-    /** @type {number} */
-    this.addedSize;
-    /** @type {number} */
-    this.removedSize;
-    /** @type {!Array.<number>} */
-    this.deletedIndexes;
-    /** @type {!Array.<number>} */
-    this.addedIndexes;
-
-    /** @type {number} */
-    this.countDelta;
-    /** @type {number} */
-    this.sizeDelta;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.ComparatorConfig = class {
-  constructor() {
-    /** @type {string} */
-    this.fieldName1;
-    /** @type {boolean} */
-    this.ascending1;
-    /** @type {string} */
-    this.fieldName2;
-    /** @type {boolean} */
-    this.ascending2;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.WorkerCommand = class {
-  constructor() {
-    /** @type {number} */
-    this.callId;
-    /** @type {string} */
-    this.disposition;
-    /** @type {number} */
-    this.objectId;
-    /** @type {number} */
-    this.newObjectId;
-    /** @type {string} */
-    this.methodName;
-    /** @type {!Array.<*>} */
-    this.methodArguments;
-    /** @type {string} */
-    this.source;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.ItemsRange = class {
-  /**
-   * @param {number} startPosition
-   * @param {number} endPosition
-   * @param {number} totalLength
-   * @param {!Array.<*>} items
-   */
-  constructor(startPosition, endPosition, totalLength, items) {
-    /** @type {number} */
-    this.startPosition = startPosition;
-    /** @type {number} */
-    this.endPosition = endPosition;
-    /** @type {number} */
-    this.totalLength = totalLength;
-    /** @type {!Array.<*>} */
-    this.items = items;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.StaticData = class {
-  /**
-   * @param {number} nodeCount
-   * @param {number} rootNodeIndex
-   * @param {number} totalSize
-   * @param {number} maxJSObjectId
-   */
-  constructor(nodeCount, rootNodeIndex, totalSize, maxJSObjectId) {
-    /** @type {number} */
-    this.nodeCount = nodeCount;
-    /** @type {number} */
-    this.rootNodeIndex = rootNodeIndex;
-    /** @type {number} */
-    this.totalSize = totalSize;
-    /** @type {number} */
-    this.maxJSObjectId = maxJSObjectId;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.Statistics = class {
-  constructor() {
-    /** @type {number} */
-    this.total;
-    /** @type {number} */
-    this.v8heap;
-    /** @type {number} */
-    this.native;
-    /** @type {number} */
-    this.code;
-    /** @type {number} */
-    this.jsArrays;
-    /** @type {number} */
-    this.strings;
-    /** @type {number} */
-    this.system;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.NodeFilter = class {
-  /**
-   * @param {number=} minNodeId
-   * @param {number=} maxNodeId
-   */
-  constructor(minNodeId, maxNodeId) {
-    /** @type {number|undefined} */
-    this.minNodeId = minNodeId;
-    /** @type {number|undefined} */
-    this.maxNodeId = maxNodeId;
-    /** @type {number|undefined} */
-    this.allocationNodeId;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.NodeFilter} o
-   * @return {boolean}
-   */
-  equals(o) {
-    return this.minNodeId === o.minNodeId && this.maxNodeId === o.maxNodeId &&
-        this.allocationNodeId === o.allocationNodeId;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.SearchConfig = class {
-  /**
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @param {boolean} shouldJump
-   * @param {boolean} jumpBackward
-   */
-  constructor(query, caseSensitive, isRegex, shouldJump, jumpBackward) {
-    this.query = query;
-    this.caseSensitive = caseSensitive;
-    this.isRegex = isRegex;
-    this.shouldJump = shouldJump;
-    this.jumpBackward = jumpBackward;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotModel.Samples = class {
-  /**
-   * @param {!Array.<number>} timestamps
-   * @param {!Array.<number>} lastAssignedIds
-   * @param {!Array.<number>} sizes
-   */
-  constructor(timestamps, lastAssignedIds, sizes) {
-    this.timestamps = timestamps;
-    this.lastAssignedIds = lastAssignedIds;
-    this.sizes = sizes;
-  }
-};
diff --git a/front_end/heap_snapshot_model/module.json b/front_end/heap_snapshot_model/module.json
deleted file mode 100644
index 1685301..0000000
--- a/front_end/heap_snapshot_model/module.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "dependencies": [],
-    "scripts": [
-        "HeapSnapshotModel.js"
-    ]
-}
diff --git a/front_end/heap_snapshot_worker.js b/front_end/heap_snapshot_worker.js
deleted file mode 100644
index 44b9b2e..0000000
--- a/front_end/heap_snapshot_worker.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// Release build has Runtime.js bundled.
-if (!self.Runtime)
-  self.importScripts('Runtime.js');
-Runtime.startWorker('heap_snapshot_worker');
diff --git a/front_end/heap_snapshot_worker.json b/front_end/heap_snapshot_worker.json
deleted file mode 100644
index 29ac6aa..0000000
--- a/front_end/heap_snapshot_worker.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "modules": [
-    { "name": "heap_snapshot_worker", "type": "autostart" },
-    { "name": "heap_snapshot_model", "type": "autostart" },
-    { "name": "platform", "type": "autostart" },
-    { "name": "text_utils", "type": "autostart" },
-    { "name": "common", "type": "autostart" }
-  ]
-}
diff --git a/front_end/heap_snapshot_worker/AllocationProfile.js b/front_end/heap_snapshot_worker/AllocationProfile.js
deleted file mode 100644
index dcb9c9c..0000000
--- a/front_end/heap_snapshot_worker/AllocationProfile.js
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.AllocationProfile = class {
-  constructor(profile, liveObjectStats) {
-    this._strings = profile.strings;
-    this._liveObjectStats = liveObjectStats;
-
-    this._nextNodeId = 1;
-    this._functionInfos = [];
-    this._idToNode = {};
-    this._idToTopDownNode = {};
-    this._collapsedTopNodeIdToFunctionInfo = {};
-
-    this._traceTops = null;
-
-    this._buildFunctionAllocationInfos(profile);
-    this._traceTree = this._buildAllocationTree(profile, liveObjectStats);
-  }
-
-  _buildFunctionAllocationInfos(profile) {
-    const strings = this._strings;
-
-    const functionInfoFields = profile.snapshot.meta.trace_function_info_fields;
-    const functionNameOffset = functionInfoFields.indexOf('name');
-    const scriptNameOffset = functionInfoFields.indexOf('script_name');
-    const scriptIdOffset = functionInfoFields.indexOf('script_id');
-    const lineOffset = functionInfoFields.indexOf('line');
-    const columnOffset = functionInfoFields.indexOf('column');
-    const functionInfoFieldCount = functionInfoFields.length;
-
-    const rawInfos = profile.trace_function_infos;
-    const infoLength = rawInfos.length;
-    const functionInfos = this._functionInfos = new Array(infoLength / functionInfoFieldCount);
-    let index = 0;
-    for (let i = 0; i < infoLength; i += functionInfoFieldCount) {
-      functionInfos[index++] = new HeapSnapshotWorker.FunctionAllocationInfo(
-          strings[rawInfos[i + functionNameOffset]], strings[rawInfos[i + scriptNameOffset]],
-          rawInfos[i + scriptIdOffset], rawInfos[i + lineOffset], rawInfos[i + columnOffset]);
-    }
-  }
-
-  _buildAllocationTree(profile, liveObjectStats) {
-    const traceTreeRaw = profile.trace_tree;
-    const functionInfos = this._functionInfos;
-    const idToTopDownNode = this._idToTopDownNode;
-
-    const traceNodeFields = profile.snapshot.meta.trace_node_fields;
-    const nodeIdOffset = traceNodeFields.indexOf('id');
-    const functionInfoIndexOffset = traceNodeFields.indexOf('function_info_index');
-    const allocationCountOffset = traceNodeFields.indexOf('count');
-    const allocationSizeOffset = traceNodeFields.indexOf('size');
-    const childrenOffset = traceNodeFields.indexOf('children');
-    const nodeFieldCount = traceNodeFields.length;
-
-    function traverseNode(rawNodeArray, nodeOffset, parent) {
-      const functionInfo = functionInfos[rawNodeArray[nodeOffset + functionInfoIndexOffset]];
-      const id = rawNodeArray[nodeOffset + nodeIdOffset];
-      const stats = liveObjectStats[id];
-      const liveCount = stats ? stats.count : 0;
-      const liveSize = stats ? stats.size : 0;
-      const result = new HeapSnapshotWorker.TopDownAllocationNode(
-          id, functionInfo, rawNodeArray[nodeOffset + allocationCountOffset],
-          rawNodeArray[nodeOffset + allocationSizeOffset], liveCount, liveSize, parent);
-      idToTopDownNode[id] = result;
-      functionInfo.addTraceTopNode(result);
-
-      const rawChildren = rawNodeArray[nodeOffset + childrenOffset];
-      for (let i = 0; i < rawChildren.length; i += nodeFieldCount)
-        result.children.push(traverseNode(rawChildren, i, result));
-
-      return result;
-    }
-
-    return traverseNode(traceTreeRaw, 0, null);
-  }
-
-  /**
-   * @return {!Array.<!HeapSnapshotModel.SerializedAllocationNode>}
-   */
-  serializeTraceTops() {
-    if (this._traceTops)
-      return this._traceTops;
-    const result = this._traceTops = [];
-    const functionInfos = this._functionInfos;
-    for (let i = 0; i < functionInfos.length; i++) {
-      const info = functionInfos[i];
-      if (info.totalCount === 0)
-        continue;
-      const nodeId = this._nextNodeId++;
-      const isRoot = i === 0;
-      result.push(this._serializeNode(
-          nodeId, info, info.totalCount, info.totalSize, info.totalLiveCount, info.totalLiveSize, !isRoot));
-      this._collapsedTopNodeIdToFunctionInfo[nodeId] = info;
-    }
-    result.sort(function(a, b) {
-      return b.size - a.size;
-    });
-    return result;
-  }
-
-  /**
-   * @param {number} nodeId
-   * @return {!HeapSnapshotModel.AllocationNodeCallers}
-   */
-  serializeCallers(nodeId) {
-    let node = this._ensureBottomUpNode(nodeId);
-    const nodesWithSingleCaller = [];
-    while (node.callers().length === 1) {
-      node = node.callers()[0];
-      nodesWithSingleCaller.push(this._serializeCaller(node));
-    }
-
-    const branchingCallers = [];
-    const callers = node.callers();
-    for (let i = 0; i < callers.length; i++)
-      branchingCallers.push(this._serializeCaller(callers[i]));
-
-    return new HeapSnapshotModel.AllocationNodeCallers(nodesWithSingleCaller, branchingCallers);
-  }
-
-  /**
-   * @param {number} traceNodeId
-   * @return {!Array.<!HeapSnapshotModel.AllocationStackFrame>}
-   */
-  serializeAllocationStack(traceNodeId) {
-    let node = this._idToTopDownNode[traceNodeId];
-    const result = [];
-    while (node) {
-      const functionInfo = node.functionInfo;
-      result.push(new HeapSnapshotModel.AllocationStackFrame(
-          functionInfo.functionName, functionInfo.scriptName, functionInfo.scriptId, functionInfo.line,
-          functionInfo.column));
-      node = node.parent;
-    }
-    return result;
-  }
-
-  /**
-   * @param {number} allocationNodeId
-   * @return {!Array.<number>}
-   */
-  traceIds(allocationNodeId) {
-    return this._ensureBottomUpNode(allocationNodeId).traceTopIds;
-  }
-
-  /**
-   * @param {number} nodeId
-   * @return {!HeapSnapshotWorker.BottomUpAllocationNode}
-   */
-  _ensureBottomUpNode(nodeId) {
-    let node = this._idToNode[nodeId];
-    if (!node) {
-      const functionInfo = this._collapsedTopNodeIdToFunctionInfo[nodeId];
-      node = functionInfo.bottomUpRoot();
-      delete this._collapsedTopNodeIdToFunctionInfo[nodeId];
-      this._idToNode[nodeId] = node;
-    }
-    return node;
-  }
-
-  /**
-   * @param {!HeapSnapshotWorker.BottomUpAllocationNode} node
-   * @return {!HeapSnapshotModel.SerializedAllocationNode}
-   */
-  _serializeCaller(node) {
-    const callerId = this._nextNodeId++;
-    this._idToNode[callerId] = node;
-    return this._serializeNode(
-        callerId, node.functionInfo, node.allocationCount, node.allocationSize, node.liveCount, node.liveSize,
-        node.hasCallers());
-  }
-
-  /**
-   * @param {number} nodeId
-   * @param {!HeapSnapshotWorker.FunctionAllocationInfo} functionInfo
-   * @param {number} count
-   * @param {number} size
-   * @param {number} liveCount
-   * @param {number} liveSize
-   * @param {boolean} hasChildren
-   * @return {!HeapSnapshotModel.SerializedAllocationNode}
-   */
-  _serializeNode(nodeId, functionInfo, count, size, liveCount, liveSize, hasChildren) {
-    return new HeapSnapshotModel.SerializedAllocationNode(
-        nodeId, functionInfo.functionName, functionInfo.scriptName, functionInfo.scriptId, functionInfo.line,
-        functionInfo.column, count, size, liveCount, liveSize, hasChildren);
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.TopDownAllocationNode = class {
-  /**
-   * @param {number} id
-   * @param {!HeapSnapshotWorker.FunctionAllocationInfo} functionInfo
-   * @param {number} count
-   * @param {number} size
-   * @param {number} liveCount
-   * @param {number} liveSize
-   * @param {?HeapSnapshotWorker.TopDownAllocationNode} parent
-   */
-  constructor(id, functionInfo, count, size, liveCount, liveSize, parent) {
-    this.id = id;
-    this.functionInfo = functionInfo;
-    this.allocationCount = count;
-    this.allocationSize = size;
-    this.liveCount = liveCount;
-    this.liveSize = liveSize;
-    this.parent = parent;
-    this.children = [];
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.BottomUpAllocationNode = class {
-  /**
-   * @param {!HeapSnapshotWorker.FunctionAllocationInfo} functionInfo
-   */
-  constructor(functionInfo) {
-    this.functionInfo = functionInfo;
-    this.allocationCount = 0;
-    this.allocationSize = 0;
-    this.liveCount = 0;
-    this.liveSize = 0;
-    this.traceTopIds = [];
-    this._callers = [];
-  }
-
-  /**
-   * @param {!HeapSnapshotWorker.TopDownAllocationNode} traceNode
-   * @return {!HeapSnapshotWorker.BottomUpAllocationNode}
-   */
-  addCaller(traceNode) {
-    const functionInfo = traceNode.functionInfo;
-    let result;
-    for (let i = 0; i < this._callers.length; i++) {
-      const caller = this._callers[i];
-      if (caller.functionInfo === functionInfo) {
-        result = caller;
-        break;
-      }
-    }
-    if (!result) {
-      result = new HeapSnapshotWorker.BottomUpAllocationNode(functionInfo);
-      this._callers.push(result);
-    }
-    return result;
-  }
-
-  /**
-   * @return {!Array.<!HeapSnapshotWorker.BottomUpAllocationNode>}
-   */
-  callers() {
-    return this._callers;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasCallers() {
-    return this._callers.length > 0;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.FunctionAllocationInfo = class {
-  /**
-   * @param {string} functionName
-   * @param {string} scriptName
-   * @param {number} scriptId
-   * @param {number} line
-   * @param {number} column
-   */
-  constructor(functionName, scriptName, scriptId, line, column) {
-    this.functionName = functionName;
-    this.scriptName = scriptName;
-    this.scriptId = scriptId;
-    this.line = line;
-    this.column = column;
-    this.totalCount = 0;
-    this.totalSize = 0;
-    this.totalLiveCount = 0;
-    this.totalLiveSize = 0;
-    this._traceTops = [];
-  }
-
-  /**
-   * @param {!HeapSnapshotWorker.TopDownAllocationNode} node
-   */
-  addTraceTopNode(node) {
-    if (node.allocationCount === 0)
-      return;
-    this._traceTops.push(node);
-    this.totalCount += node.allocationCount;
-    this.totalSize += node.allocationSize;
-    this.totalLiveCount += node.liveCount;
-    this.totalLiveSize += node.liveSize;
-  }
-
-  /**
-   * @return {?HeapSnapshotWorker.BottomUpAllocationNode}
-   */
-  bottomUpRoot() {
-    if (!this._traceTops.length)
-      return null;
-    if (!this._bottomUpTree)
-      this._buildAllocationTraceTree();
-    return this._bottomUpTree;
-  }
-
-  _buildAllocationTraceTree() {
-    this._bottomUpTree = new HeapSnapshotWorker.BottomUpAllocationNode(this);
-
-    for (let i = 0; i < this._traceTops.length; i++) {
-      let node = this._traceTops[i];
-      let bottomUpNode = this._bottomUpTree;
-      const count = node.allocationCount;
-      const size = node.allocationSize;
-      const liveCount = node.liveCount;
-      const liveSize = node.liveSize;
-      const traceId = node.id;
-      while (true) {
-        bottomUpNode.allocationCount += count;
-        bottomUpNode.allocationSize += size;
-        bottomUpNode.liveCount += liveCount;
-        bottomUpNode.liveSize += liveSize;
-        bottomUpNode.traceTopIds.push(traceId);
-        node = node.parent;
-        if (node === null)
-          break;
-
-        bottomUpNode = bottomUpNode.addCaller(node);
-      }
-    }
-  }
-};
diff --git a/front_end/heap_snapshot_worker/HeapSnapshot.js b/front_end/heap_snapshot_worker/HeapSnapshot.js
deleted file mode 100644
index e710051..0000000
--- a/front_end/heap_snapshot_worker/HeapSnapshot.js
+++ /dev/null
@@ -1,3216 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-HeapSnapshotWorker.HeapSnapshotItem = function() {};
-
-HeapSnapshotWorker.HeapSnapshotItem.prototype = {
-  /**
-   * @return {number}
-   */
-  itemIndex() {},
-
-  /**
-   * @return {!Object}
-   */
-  serialize() {}
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItem}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotEdge = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   * @param {number=} edgeIndex
-   */
-  constructor(snapshot, edgeIndex) {
-    this._snapshot = snapshot;
-    this._edges = snapshot.containmentEdges;
-    this.edgeIndex = edgeIndex || 0;
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdge}
-   */
-  clone() {
-    return new HeapSnapshotWorker.HeapSnapshotEdge(this._snapshot, this.edgeIndex);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasStringName() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotNode}
-   */
-  node() {
-    return this._snapshot.createNode(this.nodeIndex());
-  }
-
-  /**
-   * @return {number}
-   */
-  nodeIndex() {
-    return this._edges[this.edgeIndex + this._snapshot._edgeToNodeOffset];
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return 'HeapSnapshotEdge: ' + this.name();
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._snapshot._edgeTypes[this.rawType()];
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemIndex() {
-    return this.edgeIndex;
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotModel.Edge}
-   */
-  serialize() {
-    return new HeapSnapshotModel.Edge(this.name(), this.node().serialize(), this.type(), this.edgeIndex);
-  }
-
-  /**
-   * @protected
-   * @return {number}
-   */
-  rawType() {
-    return this._edges[this.edgeIndex + this._snapshot._edgeTypeOffset];
-  }
-};
-
-/**
- * @interface
- */
-HeapSnapshotWorker.HeapSnapshotItemIterator = function() {};
-
-HeapSnapshotWorker.HeapSnapshotItemIterator.prototype = {
-  /**
-   * @return {boolean}
-   */
-  hasNext() {},
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotItem}
-   */
-  item() {},
-
-  next() {}
-};
-
-/**
- * @interface
- */
-HeapSnapshotWorker.HeapSnapshotItemIndexProvider = function() {};
-
-HeapSnapshotWorker.HeapSnapshotItemIndexProvider.prototype = {
-  /**
-   * @param {number} newIndex
-   * @return {!HeapSnapshotWorker.HeapSnapshotItem}
-   */
-  itemForIndex(newIndex) {},
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIndexProvider}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotNodeIndexProvider = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   */
-  constructor(snapshot) {
-    this._node = snapshot.createNode();
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {!HeapSnapshotWorker.HeapSnapshotNode}
-   */
-  itemForIndex(index) {
-    this._node.nodeIndex = index;
-    return this._node;
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIndexProvider}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotEdgeIndexProvider = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   */
-  constructor(snapshot) {
-    this._edge = snapshot.createEdge(0);
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdge}
-   */
-  itemForIndex(index) {
-    this._edge.edgeIndex = index;
-    return this._edge;
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIndexProvider}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotRetainerEdgeIndexProvider = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   */
-  constructor(snapshot) {
-    this._retainerEdge = snapshot.createRetainingEdge(0);
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {!HeapSnapshotWorker.HeapSnapshotRetainerEdge}
-   */
-  itemForIndex(index) {
-    this._retainerEdge.setRetainerIndex(index);
-    return this._retainerEdge;
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIterator}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotEdgeIterator = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-   */
-  constructor(node) {
-    this._sourceNode = node;
-    this.edge = node._snapshot.createEdge(node.edgeIndexesStart());
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasNext() {
-    return this.edge.edgeIndex < this._sourceNode.edgeIndexesEnd();
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdge}
-   */
-  item() {
-    return this.edge;
-  }
-
-  /**
-   * @override
-   */
-  next() {
-    this.edge.edgeIndex += this.edge._snapshot._edgeFieldsCount;
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItem}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotRetainerEdge = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   * @param {number} retainerIndex
-   */
-  constructor(snapshot, retainerIndex) {
-    this._snapshot = snapshot;
-    this.setRetainerIndex(retainerIndex);
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotRetainerEdge}
-   */
-  clone() {
-    return new HeapSnapshotWorker.HeapSnapshotRetainerEdge(this._snapshot, this.retainerIndex());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasStringName() {
-    return this._edge().hasStringName();
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._edge().name();
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotNode}
-   */
-  node() {
-    return this._node();
-  }
-
-  /**
-   * @return {number}
-   */
-  nodeIndex() {
-    return this._retainingNodeIndex;
-  }
-
-  /**
-   * @return {number}
-   */
-  retainerIndex() {
-    return this._retainerIndex;
-  }
-
-  /**
-   * @param {number} retainerIndex
-   */
-  setRetainerIndex(retainerIndex) {
-    if (retainerIndex === this._retainerIndex)
-      return;
-    this._retainerIndex = retainerIndex;
-    this._globalEdgeIndex = this._snapshot._retainingEdges[retainerIndex];
-    this._retainingNodeIndex = this._snapshot._retainingNodes[retainerIndex];
-    this._edgeInstance = null;
-    this._nodeInstance = null;
-  }
-
-  /**
-   * @param {number} edgeIndex
-   */
-  set edgeIndex(edgeIndex) {
-    this.setRetainerIndex(edgeIndex);
-  }
-
-  _node() {
-    if (!this._nodeInstance)
-      this._nodeInstance = this._snapshot.createNode(this._retainingNodeIndex);
-    return this._nodeInstance;
-  }
-
-  _edge() {
-    if (!this._edgeInstance)
-      this._edgeInstance = this._snapshot.createEdge(this._globalEdgeIndex);
-    return this._edgeInstance;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return this._edge().toString();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemIndex() {
-    return this._retainerIndex;
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotModel.Edge}
-   */
-  serialize() {
-    return new HeapSnapshotModel.Edge(this.name(), this.node().serialize(), this.type(), this._globalEdgeIndex);
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._edge().type();
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIterator}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotRetainerEdgeIterator = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} retainedNode
-   */
-  constructor(retainedNode) {
-    const snapshot = retainedNode._snapshot;
-    const retainedNodeOrdinal = retainedNode.ordinal();
-    const retainerIndex = snapshot._firstRetainerIndex[retainedNodeOrdinal];
-    this._retainersEnd = snapshot._firstRetainerIndex[retainedNodeOrdinal + 1];
-    this.retainer = snapshot.createRetainingEdge(retainerIndex);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasNext() {
-    return this.retainer.retainerIndex() < this._retainersEnd;
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.HeapSnapshotRetainerEdge}
-   */
-  item() {
-    return this.retainer;
-  }
-
-  /**
-   * @override
-   */
-  next() {
-    this.retainer.setRetainerIndex(this.retainer.retainerIndex() + 1);
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItem}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotNode = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   * @param {number=} nodeIndex
-   */
-  constructor(snapshot, nodeIndex) {
-    this._snapshot = snapshot;
-    this.nodeIndex = nodeIndex || 0;
-  }
-
-  /**
-   * @return {number}
-   */
-  distance() {
-    return this._snapshot._nodeDistances[this.nodeIndex / this._snapshot._nodeFieldCount];
-  }
-
-  /**
-   * @return {string}
-   */
-  className() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {number}
-   */
-  classIndex() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {number}
-   */
-  dominatorIndex() {
-    const nodeFieldCount = this._snapshot._nodeFieldCount;
-    return this._snapshot._dominatorsTree[this.nodeIndex / this._snapshot._nodeFieldCount] * nodeFieldCount;
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdgeIterator}
-   */
-  edges() {
-    return new HeapSnapshotWorker.HeapSnapshotEdgeIterator(this);
-  }
-
-  /**
-   * @return {number}
-   */
-  edgesCount() {
-    return (this.edgeIndexesEnd() - this.edgeIndexesStart()) / this._snapshot._edgeFieldsCount;
-  }
-
-  /**
-   * @return {number}
-   */
-  id() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRoot() {
-    return this.nodeIndex === this._snapshot._rootNodeIndex;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._snapshot.strings[this._name()];
-  }
-
-  /**
-   * @return {number}
-   */
-  retainedSize() {
-    return this._snapshot._retainedSizes[this.ordinal()];
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotRetainerEdgeIterator}
-   */
-  retainers() {
-    return new HeapSnapshotWorker.HeapSnapshotRetainerEdgeIterator(this);
-  }
-
-  /**
-   * @return {number}
-   */
-  retainersCount() {
-    const snapshot = this._snapshot;
-    const ordinal = this.ordinal();
-    return snapshot._firstRetainerIndex[ordinal + 1] - snapshot._firstRetainerIndex[ordinal];
-  }
-
-  /**
-   * @return {number}
-   */
-  selfSize() {
-    const snapshot = this._snapshot;
-    return snapshot.nodes[this.nodeIndex + snapshot._nodeSelfSizeOffset];
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._snapshot._nodeTypes[this.rawType()];
-  }
-
-  /**
-   * @return {number}
-   */
-  traceNodeId() {
-    const snapshot = this._snapshot;
-    return snapshot.nodes[this.nodeIndex + snapshot._nodeTraceNodeIdOffset];
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemIndex() {
-    return this.nodeIndex;
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotModel.Node}
-   */
-  serialize() {
-    return new HeapSnapshotModel.Node(
-        this.id(), this.name(), this.distance(), this.nodeIndex, this.retainedSize(), this.selfSize(), this.type());
-  }
-
-  /**
-   * @return {number}
-   */
-  _name() {
-    const snapshot = this._snapshot;
-    return snapshot.nodes[this.nodeIndex + snapshot._nodeNameOffset];
-  }
-
-  /**
-   * @return {number}
-   */
-  edgeIndexesStart() {
-    return this._snapshot._firstEdgeIndexes[this.ordinal()];
-  }
-
-  /**
-   * @return {number}
-   */
-  edgeIndexesEnd() {
-    return this._snapshot._firstEdgeIndexes[this.ordinal() + 1];
-  }
-
-  /**
-   * @return {number}
-   */
-  ordinal() {
-    return this.nodeIndex / this._snapshot._nodeFieldCount;
-  }
-
-  /**
-   * @return {number}
-   */
-  _nextNodeIndex() {
-    return this.nodeIndex + this._snapshot._nodeFieldCount;
-  }
-
-  /**
-   * @protected
-   * @return {number}
-   */
-  rawType() {
-    const snapshot = this._snapshot;
-    return snapshot.nodes[this.nodeIndex + snapshot._nodeTypeOffset];
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIterator}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotNodeIterator = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-   */
-  constructor(node) {
-    this.node = node;
-    this._nodesLength = node._snapshot.nodes.length;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasNext() {
-    return this.node.nodeIndex < this._nodesLength;
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.HeapSnapshotNode}
-   */
-  item() {
-    return this.node;
-  }
-
-  /**
-   * @override
-   */
-  next() {
-    this.node.nodeIndex = this.node._nextNodeIndex();
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIterator}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotIndexRangeIterator = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotItemIndexProvider} itemProvider
-   * @param {!Array.<number>|!Uint32Array} indexes
-   */
-  constructor(itemProvider, indexes) {
-    this._itemProvider = itemProvider;
-    this._indexes = indexes;
-    this._position = 0;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasNext() {
-    return this._position < this._indexes.length;
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.HeapSnapshotItem}
-   */
-  item() {
-    const index = this._indexes[this._position];
-    return this._itemProvider.itemForIndex(index);
-  }
-
-  /**
-   * @override
-   */
-  next() {
-    ++this._position;
-  }
-};
-
-/**
- * @implements {HeapSnapshotWorker.HeapSnapshotItemIterator}
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotFilteredIterator = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotItemIterator} iterator
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotItem):boolean=} filter
-   */
-  constructor(iterator, filter) {
-    this._iterator = iterator;
-    this._filter = filter;
-    this._skipFilteredItems();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasNext() {
-    return this._iterator.hasNext();
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.HeapSnapshotItem}
-   */
-  item() {
-    return this._iterator.item();
-  }
-
-  /**
-   * @override
-   */
-  next() {
-    this._iterator.next();
-    this._skipFilteredItems();
-  }
-
-  _skipFilteredItems() {
-    while (this._iterator.hasNext() && !this._filter(this._iterator.item()))
-      this._iterator.next();
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotProgress = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotWorkerDispatcher=} dispatcher
-   */
-  constructor(dispatcher) {
-    this._dispatcher = dispatcher;
-  }
-
-  /**
-   * @param {string} status
-   */
-  updateStatus(status) {
-    this._sendUpdateEvent(Common.UIString(status));
-  }
-
-  /**
-   * @param {string} title
-   * @param {number} value
-   * @param {number} total
-   */
-  updateProgress(title, value, total) {
-    const percentValue = ((total ? (value / total) : 0) * 100).toFixed(0);
-    this._sendUpdateEvent(Common.UIString(title, percentValue));
-  }
-
-  /**
-   * @param {string} error
-   */
-  reportProblem(error) {
-    // May be undefined in tests.
-    if (this._dispatcher)
-      this._dispatcher.sendEvent(HeapSnapshotModel.HeapSnapshotProgressEvent.BrokenSnapshot, error);
-  }
-
-  /**
-   * @param {string} text
-   */
-  _sendUpdateEvent(text) {
-    // May be undefined in tests.
-    if (this._dispatcher)
-      this._dispatcher.sendEvent(HeapSnapshotModel.HeapSnapshotProgressEvent.Update, text);
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotProblemReport = class {
-  /**
-   * @param {string} title
-   */
-  constructor(title) {
-    this._errors = [title];
-  }
-
-  /**
-   * @param {string} error
-   */
-  addError(error) {
-    if (this._errors.length > 100)
-      return;
-    this._errors.push(error);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return this._errors.join('\n  ');
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshot = class {
-  /**
-   * @param {!Object} profile
-   * @param {!HeapSnapshotWorker.HeapSnapshotProgress} progress
-   */
-  constructor(profile, progress) {
-    /** @type {!Uint32Array} */
-    this.nodes = profile.nodes;
-    /** @type {!Uint32Array} */
-    this.containmentEdges = profile.edges;
-    /** @type {!HeapSnapshotMetainfo} */
-    this._metaNode = profile.snapshot.meta;
-    /** @type {!Array.<number>} */
-    this._rawSamples = profile.samples;
-    /** @type {?HeapSnapshotModel.Samples} */
-    this._samples = null;
-    /** @type {!Array.<string>} */
-    this.strings = profile.strings;
-    this._progress = progress;
-
-    this._noDistance = -5;
-    this._rootNodeIndex = 0;
-    if (profile.snapshot.root_index)
-      this._rootNodeIndex = profile.snapshot.root_index;
-
-    this._snapshotDiffs = {};
-    this._aggregatesForDiff = null;
-    this._aggregates = {};
-    this._aggregatesSortedFlags = {};
-    this._profile = profile;
-  }
-
-  /**
-   * @protected
-   */
-  initialize() {
-    const meta = this._metaNode;
-
-    this._nodeTypeOffset = meta.node_fields.indexOf('type');
-    this._nodeNameOffset = meta.node_fields.indexOf('name');
-    this._nodeIdOffset = meta.node_fields.indexOf('id');
-    this._nodeSelfSizeOffset = meta.node_fields.indexOf('self_size');
-    this._nodeEdgeCountOffset = meta.node_fields.indexOf('edge_count');
-    this._nodeTraceNodeIdOffset = meta.node_fields.indexOf('trace_node_id');
-    this._nodeFieldCount = meta.node_fields.length;
-
-    this._nodeTypes = meta.node_types[this._nodeTypeOffset];
-    this._nodeArrayType = this._nodeTypes.indexOf('array');
-    this._nodeHiddenType = this._nodeTypes.indexOf('hidden');
-    this._nodeObjectType = this._nodeTypes.indexOf('object');
-    this._nodeNativeType = this._nodeTypes.indexOf('native');
-    this._nodeConsStringType = this._nodeTypes.indexOf('concatenated string');
-    this._nodeSlicedStringType = this._nodeTypes.indexOf('sliced string');
-    this._nodeCodeType = this._nodeTypes.indexOf('code');
-    this._nodeSyntheticType = this._nodeTypes.indexOf('synthetic');
-
-    this._edgeFieldsCount = meta.edge_fields.length;
-    this._edgeTypeOffset = meta.edge_fields.indexOf('type');
-    this._edgeNameOffset = meta.edge_fields.indexOf('name_or_index');
-    this._edgeToNodeOffset = meta.edge_fields.indexOf('to_node');
-
-    this._edgeTypes = meta.edge_types[this._edgeTypeOffset];
-    this._edgeTypes.push('invisible');
-    this._edgeElementType = this._edgeTypes.indexOf('element');
-    this._edgeHiddenType = this._edgeTypes.indexOf('hidden');
-    this._edgeInternalType = this._edgeTypes.indexOf('internal');
-    this._edgeShortcutType = this._edgeTypes.indexOf('shortcut');
-    this._edgeWeakType = this._edgeTypes.indexOf('weak');
-    this._edgeInvisibleType = this._edgeTypes.indexOf('invisible');
-
-    this.nodeCount = this.nodes.length / this._nodeFieldCount;
-    this._edgeCount = this.containmentEdges.length / this._edgeFieldsCount;
-
-    this._retainedSizes = new Float64Array(this.nodeCount);
-    this._firstEdgeIndexes = new Uint32Array(this.nodeCount + 1);
-    this._retainingNodes = new Uint32Array(this._edgeCount);
-    this._retainingEdges = new Uint32Array(this._edgeCount);
-    this._firstRetainerIndex = new Uint32Array(this.nodeCount + 1);
-    this._nodeDistances = new Int32Array(this.nodeCount);
-    this._firstDominatedNodeIndex = new Uint32Array(this.nodeCount + 1);
-    this._dominatedNodes = new Uint32Array(this.nodeCount - 1);
-
-    this._progress.updateStatus('Building edge indexes\u2026');
-    this._buildEdgeIndexes();
-    this._progress.updateStatus('Building retainers\u2026');
-    this._buildRetainers();
-    this._progress.updateStatus('Calculating node flags\u2026');
-    this.calculateFlags();
-    this._progress.updateStatus('Calculating distances\u2026');
-    this.calculateDistances();
-    this._progress.updateStatus('Building postorder index\u2026');
-    const result = this._buildPostOrderIndex();
-    // Actually it is array that maps node ordinal number to dominator node ordinal number.
-    this._progress.updateStatus('Building dominator tree\u2026');
-    this._dominatorsTree =
-        this._buildDominatorTree(result.postOrderIndex2NodeOrdinal, result.nodeOrdinal2PostOrderIndex);
-    this._progress.updateStatus('Calculating retained sizes\u2026');
-    this._calculateRetainedSizes(result.postOrderIndex2NodeOrdinal);
-    this._progress.updateStatus('Building dominated nodes\u2026');
-    this._buildDominatedNodes();
-    this._progress.updateStatus('Calculating statistics\u2026');
-    this.calculateStatistics();
-    this._progress.updateStatus('Calculating samples\u2026');
-    this._buildSamples();
-    this._progress.updateStatus('Finished processing.');
-
-    if (this._profile.snapshot.trace_function_count) {
-      this._progress.updateStatus('Building allocation statistics\u2026');
-      const nodes = this.nodes;
-      const nodesLength = nodes.length;
-      const nodeFieldCount = this._nodeFieldCount;
-      const node = this.rootNode();
-      const liveObjects = {};
-      for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
-        node.nodeIndex = nodeIndex;
-        const traceNodeId = node.traceNodeId();
-        let stats = liveObjects[traceNodeId];
-        if (!stats)
-          liveObjects[traceNodeId] = stats = {count: 0, size: 0, ids: []};
-        stats.count++;
-        stats.size += node.selfSize();
-        stats.ids.push(node.id());
-      }
-      this._allocationProfile = new HeapSnapshotWorker.AllocationProfile(this._profile, liveObjects);
-      this._progress.updateStatus('Done');
-    }
-  }
-
-  _buildEdgeIndexes() {
-    const nodes = this.nodes;
-    const nodeCount = this.nodeCount;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-    const nodeFieldCount = this._nodeFieldCount;
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const nodeEdgeCountOffset = this._nodeEdgeCountOffset;
-    firstEdgeIndexes[nodeCount] = this.containmentEdges.length;
-    for (let nodeOrdinal = 0, edgeIndex = 0; nodeOrdinal < nodeCount; ++nodeOrdinal) {
-      firstEdgeIndexes[nodeOrdinal] = edgeIndex;
-      edgeIndex += nodes[nodeOrdinal * nodeFieldCount + nodeEdgeCountOffset] * edgeFieldsCount;
-    }
-  }
-
-  _buildRetainers() {
-    const retainingNodes = this._retainingNodes;
-    const retainingEdges = this._retainingEdges;
-    // Index of the first retainer in the _retainingNodes and _retainingEdges
-    // arrays. Addressed by retained node index.
-    const firstRetainerIndex = this._firstRetainerIndex;
-
-    const containmentEdges = this.containmentEdges;
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const nodeFieldCount = this._nodeFieldCount;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-    const nodeCount = this.nodeCount;
-
-    for (let toNodeFieldIndex = edgeToNodeOffset, l = containmentEdges.length; toNodeFieldIndex < l;
-         toNodeFieldIndex += edgeFieldsCount) {
-      const toNodeIndex = containmentEdges[toNodeFieldIndex];
-      if (toNodeIndex % nodeFieldCount)
-        throw new Error('Invalid toNodeIndex ' + toNodeIndex);
-      ++firstRetainerIndex[toNodeIndex / nodeFieldCount];
-    }
-    for (let i = 0, firstUnusedRetainerSlot = 0; i < nodeCount; i++) {
-      const retainersCount = firstRetainerIndex[i];
-      firstRetainerIndex[i] = firstUnusedRetainerSlot;
-      retainingNodes[firstUnusedRetainerSlot] = retainersCount;
-      firstUnusedRetainerSlot += retainersCount;
-    }
-    firstRetainerIndex[nodeCount] = retainingNodes.length;
-
-    let nextNodeFirstEdgeIndex = firstEdgeIndexes[0];
-    for (let srcNodeOrdinal = 0; srcNodeOrdinal < nodeCount; ++srcNodeOrdinal) {
-      const firstEdgeIndex = nextNodeFirstEdgeIndex;
-      nextNodeFirstEdgeIndex = firstEdgeIndexes[srcNodeOrdinal + 1];
-      const srcNodeIndex = srcNodeOrdinal * nodeFieldCount;
-      for (let edgeIndex = firstEdgeIndex; edgeIndex < nextNodeFirstEdgeIndex; edgeIndex += edgeFieldsCount) {
-        const toNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-        if (toNodeIndex % nodeFieldCount)
-          throw new Error('Invalid toNodeIndex ' + toNodeIndex);
-        const firstRetainerSlotIndex = firstRetainerIndex[toNodeIndex / nodeFieldCount];
-        const nextUnusedRetainerSlotIndex = firstRetainerSlotIndex + (--retainingNodes[firstRetainerSlotIndex]);
-        retainingNodes[nextUnusedRetainerSlotIndex] = srcNodeIndex;
-        retainingEdges[nextUnusedRetainerSlotIndex] = edgeIndex;
-      }
-    }
-  }
-
-  /**
-   * @param {number=} nodeIndex
-   */
-  createNode(nodeIndex) {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @param {number} edgeIndex
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotEdge}
-   */
-  createEdge(edgeIndex) {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @param {number} retainerIndex
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotRetainerEdge}
-   */
-  createRetainingEdge(retainerIndex) {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotNodeIterator}
-   */
-  _allNodes() {
-    return new HeapSnapshotWorker.HeapSnapshotNodeIterator(this.rootNode());
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.HeapSnapshotNode}
-   */
-  rootNode() {
-    return this.createNode(this._rootNodeIndex);
-  }
-
-  /**
-   * @return {number}
-   */
-  get rootNodeIndex() {
-    return this._rootNodeIndex;
-  }
-
-  /**
-   * @return {number}
-   */
-  get totalSize() {
-    return this.rootNode().retainedSize();
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {number}
-   */
-  _getDominatedIndex(nodeIndex) {
-    if (nodeIndex % this._nodeFieldCount)
-      throw new Error('Invalid nodeIndex: ' + nodeIndex);
-    return this._firstDominatedNodeIndex[nodeIndex / this._nodeFieldCount];
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   * @return {undefined|function(!HeapSnapshotWorker.HeapSnapshotNode):boolean}
-   */
-  _createFilter(nodeFilter) {
-    const minNodeId = nodeFilter.minNodeId;
-    const maxNodeId = nodeFilter.maxNodeId;
-    const allocationNodeId = nodeFilter.allocationNodeId;
-    let filter;
-    if (typeof allocationNodeId === 'number') {
-      filter = this._createAllocationStackFilter(allocationNodeId);
-      filter.key = 'AllocationNodeId: ' + allocationNodeId;
-    } else if (typeof minNodeId === 'number' && typeof maxNodeId === 'number') {
-      filter = this._createNodeIdFilter(minNodeId, maxNodeId);
-      filter.key = 'NodeIdRange: ' + minNodeId + '..' + maxNodeId;
-    }
-    return filter;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.SearchConfig} searchConfig
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   * @return {!Array.<number>}
-   */
-  search(searchConfig, nodeFilter) {
-    const query = searchConfig.query;
-
-    function filterString(matchedStringIndexes, string, index) {
-      if (string.indexOf(query) !== -1)
-        matchedStringIndexes.add(index);
-      return matchedStringIndexes;
-    }
-
-    const regexp = searchConfig.isRegex ? new RegExp(query) : createPlainTextSearchRegex(query, 'i');
-    function filterRegexp(matchedStringIndexes, string, index) {
-      if (regexp.test(string))
-        matchedStringIndexes.add(index);
-      return matchedStringIndexes;
-    }
-
-    const stringFilter = (searchConfig.isRegex || !searchConfig.caseSensitive) ? filterRegexp : filterString;
-    const stringIndexes = this.strings.reduce(stringFilter, new Set());
-
-    if (!stringIndexes.size)
-      return [];
-
-    const filter = this._createFilter(nodeFilter);
-    const nodeIds = [];
-    const nodesLength = this.nodes.length;
-    const nodes = this.nodes;
-    const nodeNameOffset = this._nodeNameOffset;
-    const nodeIdOffset = this._nodeIdOffset;
-    const nodeFieldCount = this._nodeFieldCount;
-    const node = this.rootNode();
-
-    for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
-      node.nodeIndex = nodeIndex;
-      if (filter && !filter(node))
-        continue;
-      if (stringIndexes.has(nodes[nodeIndex + nodeNameOffset]))
-        nodeIds.push(nodes[nodeIndex + nodeIdOffset]);
-    }
-    return nodeIds;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   * @return {!Object.<string, !HeapSnapshotModel.Aggregate>}
-   */
-  aggregatesWithFilter(nodeFilter) {
-    const filter = this._createFilter(nodeFilter);
-    const key = filter ? filter.key : 'allObjects';
-    return this.aggregates(false, key, filter);
-  }
-
-  /**
-   * @param {number} minNodeId
-   * @param {number} maxNodeId
-   * @return {function(!HeapSnapshotWorker.HeapSnapshotNode):boolean}
-   */
-  _createNodeIdFilter(minNodeId, maxNodeId) {
-    /**
-     * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-     * @return {boolean}
-     */
-    function nodeIdFilter(node) {
-      const id = node.id();
-      return id > minNodeId && id <= maxNodeId;
-    }
-    return nodeIdFilter;
-  }
-
-  /**
-   * @param {number} bottomUpAllocationNodeId
-   * @return {function(!HeapSnapshotWorker.HeapSnapshotNode):boolean|undefined}
-   */
-  _createAllocationStackFilter(bottomUpAllocationNodeId) {
-    const traceIds = this._allocationProfile.traceIds(bottomUpAllocationNodeId);
-    if (!traceIds.length)
-      return undefined;
-    const set = {};
-    for (let i = 0; i < traceIds.length; i++)
-      set[traceIds[i]] = true;
-    /**
-     * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-     * @return {boolean}
-     */
-    function traceIdFilter(node) {
-      return !!set[node.traceNodeId()];
-    }
-    return traceIdFilter;
-  }
-
-  /**
-   * @param {boolean} sortedIndexes
-   * @param {string=} key
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode):boolean=} filter
-   * @return {!Object.<string, !HeapSnapshotModel.Aggregate>}
-   */
-  aggregates(sortedIndexes, key, filter) {
-    let aggregatesByClassName = key && this._aggregates[key];
-    if (!aggregatesByClassName) {
-      const aggregates = this._buildAggregates(filter);
-      this._calculateClassesRetainedSize(aggregates.aggregatesByClassIndex, filter);
-      aggregatesByClassName = aggregates.aggregatesByClassName;
-      if (key)
-        this._aggregates[key] = aggregatesByClassName;
-    }
-
-    if (sortedIndexes && (!key || !this._aggregatesSortedFlags[key])) {
-      this._sortAggregateIndexes(aggregatesByClassName);
-      if (key)
-        this._aggregatesSortedFlags[key] = sortedIndexes;
-    }
-    return aggregatesByClassName;
-  }
-
-  /**
-   * @return {!Array.<!HeapSnapshotModel.SerializedAllocationNode>}
-   */
-  allocationTracesTops() {
-    return this._allocationProfile.serializeTraceTops();
-  }
-
-  /**
-   * @param {number} nodeId
-   * @return {!HeapSnapshotModel.AllocationNodeCallers}
-   */
-  allocationNodeCallers(nodeId) {
-    return this._allocationProfile.serializeCallers(nodeId);
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {?Array.<!HeapSnapshotModel.AllocationStackFrame>}
-   */
-  allocationStack(nodeIndex) {
-    const node = this.createNode(nodeIndex);
-    const allocationNodeId = node.traceNodeId();
-    if (!allocationNodeId)
-      return null;
-    return this._allocationProfile.serializeAllocationStack(allocationNodeId);
-  }
-
-  /**
-   * @return {!Object.<string, !HeapSnapshotModel.AggregateForDiff>}
-   */
-  aggregatesForDiff() {
-    if (this._aggregatesForDiff)
-      return this._aggregatesForDiff;
-
-    const aggregatesByClassName = this.aggregates(true, 'allObjects');
-    this._aggregatesForDiff = {};
-
-    const node = this.createNode();
-    for (const className in aggregatesByClassName) {
-      const aggregate = aggregatesByClassName[className];
-      const indexes = aggregate.idxs;
-      const ids = new Array(indexes.length);
-      const selfSizes = new Array(indexes.length);
-      for (let i = 0; i < indexes.length; i++) {
-        node.nodeIndex = indexes[i];
-        ids[i] = node.id();
-        selfSizes[i] = node.selfSize();
-      }
-
-      this._aggregatesForDiff[className] = {indexes: indexes, ids: ids, selfSizes: selfSizes};
-    }
-    return this._aggregatesForDiff;
-  }
-
-  /**
-   * @protected
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-   * @return {boolean}
-   */
-  isUserRoot(node) {
-    return true;
-  }
-
-  /**
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode)} action
-   * @param {boolean=} userRootsOnly
-   */
-  forEachRoot(action, userRootsOnly) {
-    for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
-      const node = iter.edge.node();
-      if (!userRootsOnly || this.isUserRoot(node))
-        action(node);
-    }
-  }
-
-  /**
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode,!HeapSnapshotWorker.HeapSnapshotEdge):boolean=} filter
-   */
-  calculateDistances(filter) {
-    const nodeCount = this.nodeCount;
-    const distances = this._nodeDistances;
-    const noDistance = this._noDistance;
-    for (let i = 0; i < nodeCount; ++i)
-      distances[i] = noDistance;
-
-    const nodesToVisit = new Uint32Array(this.nodeCount);
-    let nodesToVisitLength = 0;
-
-    /**
-     * @param {number} distance
-     * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-     */
-    function enqueueNode(distance, node) {
-      const ordinal = node.ordinal();
-      if (distances[ordinal] !== noDistance)
-        return;
-      distances[ordinal] = distance;
-      nodesToVisit[nodesToVisitLength++] = node.nodeIndex;
-    }
-
-    this.forEachRoot(enqueueNode.bind(null, 1), true);
-    this._bfs(nodesToVisit, nodesToVisitLength, distances, filter);
-
-    // bfs for the rest of objects
-    nodesToVisitLength = 0;
-    this.forEachRoot(enqueueNode.bind(null, HeapSnapshotModel.baseSystemDistance), false);
-    this._bfs(nodesToVisit, nodesToVisitLength, distances, filter);
-  }
-
-  /**
-   * @param {!Uint32Array} nodesToVisit
-   * @param {number} nodesToVisitLength
-   * @param {!Int32Array} distances
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode,!HeapSnapshotWorker.HeapSnapshotEdge):boolean=} filter
-   */
-  _bfs(nodesToVisit, nodesToVisitLength, distances, filter) {
-    // Preload fields into local variables for better performance.
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const nodeFieldCount = this._nodeFieldCount;
-    const containmentEdges = this.containmentEdges;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const nodeCount = this.nodeCount;
-    const edgeWeakType = this._edgeWeakType;
-    const noDistance = this._noDistance;
-
-    let index = 0;
-    const edge = this.createEdge(0);
-    const node = this.createNode(0);
-    while (index < nodesToVisitLength) {
-      const nodeIndex = nodesToVisit[index++];  // shift generates too much garbage.
-      const nodeOrdinal = nodeIndex / nodeFieldCount;
-      const distance = distances[nodeOrdinal] + 1;
-      const firstEdgeIndex = firstEdgeIndexes[nodeOrdinal];
-      const edgesEnd = firstEdgeIndexes[nodeOrdinal + 1];
-      node.nodeIndex = nodeIndex;
-      for (let edgeIndex = firstEdgeIndex; edgeIndex < edgesEnd; edgeIndex += edgeFieldsCount) {
-        const edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
-        if (edgeType === edgeWeakType)
-          continue;
-        const childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-        const childNodeOrdinal = childNodeIndex / nodeFieldCount;
-        if (distances[childNodeOrdinal] !== noDistance)
-          continue;
-        edge.edgeIndex = edgeIndex;
-        if (filter && !filter(node, edge))
-          continue;
-        distances[childNodeOrdinal] = distance;
-        nodesToVisit[nodesToVisitLength++] = childNodeIndex;
-      }
-    }
-    if (nodesToVisitLength > nodeCount) {
-      throw new Error(
-          'BFS failed. Nodes to visit (' + nodesToVisitLength + ') is more than nodes count (' + nodeCount + ')');
-    }
-  }
-
-  /**
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode):boolean=} filter
-   * @return {!{aggregatesByClassName: !Object<string, !HeapSnapshotWorker.HeapSnapshot.AggregatedInfo>,
-   *     aggregatesByClassIndex: !Object<number, !HeapSnapshotWorker.HeapSnapshot.AggregatedInfo>}}
-   */
-  _buildAggregates(filter) {
-    const aggregates = {};
-    const aggregatesByClassName = {};
-    const classIndexes = [];
-    const nodes = this.nodes;
-    const nodesLength = nodes.length;
-    const nodeNativeType = this._nodeNativeType;
-    const nodeFieldCount = this._nodeFieldCount;
-    const selfSizeOffset = this._nodeSelfSizeOffset;
-    const nodeTypeOffset = this._nodeTypeOffset;
-    const node = this.rootNode();
-    const nodeDistances = this._nodeDistances;
-
-    for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
-      node.nodeIndex = nodeIndex;
-      if (filter && !filter(node))
-        continue;
-      const selfSize = nodes[nodeIndex + selfSizeOffset];
-      if (!selfSize && nodes[nodeIndex + nodeTypeOffset] !== nodeNativeType)
-        continue;
-      const classIndex = node.classIndex();
-      const nodeOrdinal = nodeIndex / nodeFieldCount;
-      const distance = nodeDistances[nodeOrdinal];
-      if (!(classIndex in aggregates)) {
-        const nodeType = node.type();
-        const nameMatters = nodeType === 'object' || nodeType === 'native';
-        const value = {
-          count: 1,
-          distance: distance,
-          self: selfSize,
-          maxRet: 0,
-          type: nodeType,
-          name: nameMatters ? node.name() : null,
-          idxs: [nodeIndex]
-        };
-        aggregates[classIndex] = value;
-        classIndexes.push(classIndex);
-        aggregatesByClassName[node.className()] = value;
-      } else {
-        const clss = aggregates[classIndex];
-        clss.distance = Math.min(clss.distance, distance);
-        ++clss.count;
-        clss.self += selfSize;
-        clss.idxs.push(nodeIndex);
-      }
-    }
-
-    // Shave off provisionally allocated space.
-    for (let i = 0, l = classIndexes.length; i < l; ++i) {
-      const classIndex = classIndexes[i];
-      aggregates[classIndex].idxs = aggregates[classIndex].idxs.slice();
-    }
-    return {aggregatesByClassName: aggregatesByClassName, aggregatesByClassIndex: aggregates};
-  }
-
-  /**
-   * @param {!Object<number, !HeapSnapshotWorker.HeapSnapshot.AggregatedInfo>} aggregates
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode):boolean=} filter
-   */
-  _calculateClassesRetainedSize(aggregates, filter) {
-    const rootNodeIndex = this._rootNodeIndex;
-    const node = this.createNode(rootNodeIndex);
-    const list = [rootNodeIndex];
-    const sizes = [-1];
-    const classes = [];
-    const seenClassNameIndexes = {};
-    const nodeFieldCount = this._nodeFieldCount;
-    const nodeTypeOffset = this._nodeTypeOffset;
-    const nodeNativeType = this._nodeNativeType;
-    const dominatedNodes = this._dominatedNodes;
-    const nodes = this.nodes;
-    const firstDominatedNodeIndex = this._firstDominatedNodeIndex;
-
-    while (list.length) {
-      const nodeIndex = list.pop();
-      node.nodeIndex = nodeIndex;
-      let classIndex = node.classIndex();
-      const seen = !!seenClassNameIndexes[classIndex];
-      const nodeOrdinal = nodeIndex / nodeFieldCount;
-      const dominatedIndexFrom = firstDominatedNodeIndex[nodeOrdinal];
-      const dominatedIndexTo = firstDominatedNodeIndex[nodeOrdinal + 1];
-
-      if (!seen && (!filter || filter(node)) &&
-          (node.selfSize() || nodes[nodeIndex + nodeTypeOffset] === nodeNativeType)) {
-        aggregates[classIndex].maxRet += node.retainedSize();
-        if (dominatedIndexFrom !== dominatedIndexTo) {
-          seenClassNameIndexes[classIndex] = true;
-          sizes.push(list.length);
-          classes.push(classIndex);
-        }
-      }
-      for (let i = dominatedIndexFrom; i < dominatedIndexTo; i++)
-        list.push(dominatedNodes[i]);
-
-      const l = list.length;
-      while (sizes[sizes.length - 1] === l) {
-        sizes.pop();
-        classIndex = classes.pop();
-        seenClassNameIndexes[classIndex] = false;
-      }
-    }
-  }
-
-  /**
-   * @param {!{aggregatesByClassName: !Object<string, !HeapSnapshotWorker.HeapSnapshot.AggregatedInfo>, aggregatesByClassIndex: !Object<number, !HeapSnapshotWorker.HeapSnapshot.AggregatedInfo>}} aggregates
-   */
-  _sortAggregateIndexes(aggregates) {
-    const nodeA = this.createNode();
-    const nodeB = this.createNode();
-    for (const clss in aggregates) {
-      aggregates[clss].idxs.sort((idxA, idxB) => {
-        nodeA.nodeIndex = idxA;
-        nodeB.nodeIndex = idxB;
-        return nodeA.id() < nodeB.id() ? -1 : 1;
-      });
-    }
-  }
-
-  /**
-   * The function checks is the edge should be considered during building
-   * postorder iterator and dominator tree.
-   *
-   * @param {number} nodeIndex
-   * @param {number} edgeType
-   * @return {boolean}
-   */
-  _isEssentialEdge(nodeIndex, edgeType) {
-    // Shortcuts at the root node have special meaning of marking user global objects.
-    return edgeType !== this._edgeWeakType &&
-        (edgeType !== this._edgeShortcutType || nodeIndex === this._rootNodeIndex);
-  }
-
-  _buildPostOrderIndex() {
-    const nodeFieldCount = this._nodeFieldCount;
-    const nodeCount = this.nodeCount;
-    const rootNodeOrdinal = this._rootNodeIndex / nodeFieldCount;
-
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-    const containmentEdges = this.containmentEdges;
-
-    const mapAndFlag = this.userObjectsMapAndFlag();
-    const flags = mapAndFlag ? mapAndFlag.map : null;
-    const flag = mapAndFlag ? mapAndFlag.flag : 0;
-
-    const stackNodes = new Uint32Array(nodeCount);
-    const stackCurrentEdge = new Uint32Array(nodeCount);
-    const postOrderIndex2NodeOrdinal = new Uint32Array(nodeCount);
-    const nodeOrdinal2PostOrderIndex = new Uint32Array(nodeCount);
-    const visited = new Uint8Array(nodeCount);
-    let postOrderIndex = 0;
-
-    let stackTop = 0;
-    stackNodes[0] = rootNodeOrdinal;
-    stackCurrentEdge[0] = firstEdgeIndexes[rootNodeOrdinal];
-    visited[rootNodeOrdinal] = 1;
-
-    let iteration = 0;
-    while (true) {
-      ++iteration;
-      while (stackTop >= 0) {
-        const nodeOrdinal = stackNodes[stackTop];
-        const edgeIndex = stackCurrentEdge[stackTop];
-        const edgesEnd = firstEdgeIndexes[nodeOrdinal + 1];
-
-        if (edgeIndex < edgesEnd) {
-          stackCurrentEdge[stackTop] += edgeFieldsCount;
-          const edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
-          if (!this._isEssentialEdge(nodeOrdinal * nodeFieldCount, edgeType))
-            continue;
-          const childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-          const childNodeOrdinal = childNodeIndex / nodeFieldCount;
-          if (visited[childNodeOrdinal])
-            continue;
-          const nodeFlag = !flags || (flags[nodeOrdinal] & flag);
-          const childNodeFlag = !flags || (flags[childNodeOrdinal] & flag);
-          // We are skipping the edges from non-page-owned nodes to page-owned nodes.
-          // Otherwise the dominators for the objects that also were retained by debugger would be affected.
-          if (nodeOrdinal !== rootNodeOrdinal && childNodeFlag && !nodeFlag)
-            continue;
-          ++stackTop;
-          stackNodes[stackTop] = childNodeOrdinal;
-          stackCurrentEdge[stackTop] = firstEdgeIndexes[childNodeOrdinal];
-          visited[childNodeOrdinal] = 1;
-        } else {
-          // Done with all the node children
-          nodeOrdinal2PostOrderIndex[nodeOrdinal] = postOrderIndex;
-          postOrderIndex2NodeOrdinal[postOrderIndex++] = nodeOrdinal;
-          --stackTop;
-        }
-      }
-
-      if (postOrderIndex === nodeCount || iteration > 1)
-        break;
-      const errors = new HeapSnapshotWorker.HeapSnapshotProblemReport(
-          `Heap snapshot: ${
-                            nodeCount - postOrderIndex
-                          } nodes are unreachable from the root. Following nodes have only weak retainers:`);
-      const dumpNode = this.rootNode();
-      // Remove root from the result (last node in the array) and put it at the bottom of the stack so that it is
-      // visited after all orphan nodes and their subgraphs.
-      --postOrderIndex;
-      stackTop = 0;
-      stackNodes[0] = rootNodeOrdinal;
-      stackCurrentEdge[0] = firstEdgeIndexes[rootNodeOrdinal + 1];  // no need to reiterate its edges
-      for (let i = 0; i < nodeCount; ++i) {
-        if (visited[i] || !this._hasOnlyWeakRetainers(i))
-          continue;
-
-        // Add all nodes that have only weak retainers to traverse their subgraphs.
-        stackNodes[++stackTop] = i;
-        stackCurrentEdge[stackTop] = firstEdgeIndexes[i];
-        visited[i] = 1;
-
-        dumpNode.nodeIndex = i * nodeFieldCount;
-        const retainers = [];
-        for (let it = dumpNode.retainers(); it.hasNext(); it.next())
-          retainers.push(`${it.item().node().name()}@${it.item().node().id()}.${it.item().name()}`);
-        errors.addError(`${dumpNode.name()} @${dumpNode.id()}  weak retainers: ${retainers.join(', ')}`);
-      }
-      console.warn(errors.toString());
-    }
-
-    // If we already processed all orphan nodes that have only weak retainers and still have some orphans...
-    if (postOrderIndex !== nodeCount) {
-      const errors = new HeapSnapshotWorker.HeapSnapshotProblemReport(
-          'Still found ' + (nodeCount - postOrderIndex) + ' unreachable nodes in heap snapshot:');
-      const dumpNode = this.rootNode();
-      // Remove root from the result (last node in the array) and put it at the bottom of the stack so that it is
-      // visited after all orphan nodes and their subgraphs.
-      --postOrderIndex;
-      for (let i = 0; i < nodeCount; ++i) {
-        if (visited[i])
-          continue;
-        dumpNode.nodeIndex = i * nodeFieldCount;
-        errors.addError(dumpNode.name() + ' @' + dumpNode.id());
-        // Fix it by giving the node a postorder index anyway.
-        nodeOrdinal2PostOrderIndex[i] = postOrderIndex;
-        postOrderIndex2NodeOrdinal[postOrderIndex++] = i;
-      }
-      nodeOrdinal2PostOrderIndex[rootNodeOrdinal] = postOrderIndex;
-      postOrderIndex2NodeOrdinal[postOrderIndex++] = rootNodeOrdinal;
-      console.warn(errors.toString());
-    }
-
-    return {
-      postOrderIndex2NodeOrdinal: postOrderIndex2NodeOrdinal,
-      nodeOrdinal2PostOrderIndex: nodeOrdinal2PostOrderIndex
-    };
-  }
-
-  /**
-   * @param {number} nodeOrdinal
-   * @return {boolean}
-   */
-  _hasOnlyWeakRetainers(nodeOrdinal) {
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const edgeWeakType = this._edgeWeakType;
-    const edgeShortcutType = this._edgeShortcutType;
-    const containmentEdges = this.containmentEdges;
-    const retainingEdges = this._retainingEdges;
-    const beginRetainerIndex = this._firstRetainerIndex[nodeOrdinal];
-    const endRetainerIndex = this._firstRetainerIndex[nodeOrdinal + 1];
-    for (let retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) {
-      const retainerEdgeIndex = retainingEdges[retainerIndex];
-      const retainerEdgeType = containmentEdges[retainerEdgeIndex + edgeTypeOffset];
-      if (retainerEdgeType !== edgeWeakType && retainerEdgeType !== edgeShortcutType)
-        return false;
-    }
-    return true;
-  }
-
-  // The algorithm is based on the article:
-  // K. Cooper, T. Harvey and K. Kennedy "A Simple, Fast Dominance Algorithm"
-  // Softw. Pract. Exper. 4 (2001), pp. 1-10.
-  /**
-   * @param {!Array.<number>} postOrderIndex2NodeOrdinal
-   * @param {!Array.<number>} nodeOrdinal2PostOrderIndex
-   */
-  _buildDominatorTree(postOrderIndex2NodeOrdinal, nodeOrdinal2PostOrderIndex) {
-    const nodeFieldCount = this._nodeFieldCount;
-    const firstRetainerIndex = this._firstRetainerIndex;
-    const retainingNodes = this._retainingNodes;
-    const retainingEdges = this._retainingEdges;
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-    const containmentEdges = this.containmentEdges;
-    const rootNodeIndex = this._rootNodeIndex;
-
-    const mapAndFlag = this.userObjectsMapAndFlag();
-    const flags = mapAndFlag ? mapAndFlag.map : null;
-    const flag = mapAndFlag ? mapAndFlag.flag : 0;
-
-    const nodesCount = postOrderIndex2NodeOrdinal.length;
-    const rootPostOrderedIndex = nodesCount - 1;
-    const noEntry = nodesCount;
-    const dominators = new Uint32Array(nodesCount);
-    for (let i = 0; i < rootPostOrderedIndex; ++i)
-      dominators[i] = noEntry;
-    dominators[rootPostOrderedIndex] = rootPostOrderedIndex;
-
-    // The affected array is used to mark entries which dominators
-    // have to be racalculated because of changes in their retainers.
-    const affected = new Uint8Array(nodesCount);
-    let nodeOrdinal;
-
-    {  // Mark the root direct children as affected.
-      nodeOrdinal = this._rootNodeIndex / nodeFieldCount;
-      const endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
-      for (let edgeIndex = firstEdgeIndexes[nodeOrdinal]; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
-        const edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
-        if (!this._isEssentialEdge(this._rootNodeIndex, edgeType))
-          continue;
-        const childNodeOrdinal = containmentEdges[edgeIndex + edgeToNodeOffset] / nodeFieldCount;
-        affected[nodeOrdinal2PostOrderIndex[childNodeOrdinal]] = 1;
-      }
-    }
-
-    let changed = true;
-    while (changed) {
-      changed = false;
-      for (let postOrderIndex = rootPostOrderedIndex - 1; postOrderIndex >= 0; --postOrderIndex) {
-        if (affected[postOrderIndex] === 0)
-          continue;
-        affected[postOrderIndex] = 0;
-        // If dominator of the entry has already been set to root,
-        // then it can't propagate any further.
-        if (dominators[postOrderIndex] === rootPostOrderedIndex)
-          continue;
-        nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex];
-        const nodeFlag = !flags || (flags[nodeOrdinal] & flag);
-        let newDominatorIndex = noEntry;
-        const beginRetainerIndex = firstRetainerIndex[nodeOrdinal];
-        const endRetainerIndex = firstRetainerIndex[nodeOrdinal + 1];
-        let orphanNode = true;
-        for (let retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) {
-          const retainerEdgeIndex = retainingEdges[retainerIndex];
-          const retainerEdgeType = containmentEdges[retainerEdgeIndex + edgeTypeOffset];
-          const retainerNodeIndex = retainingNodes[retainerIndex];
-          if (!this._isEssentialEdge(retainerNodeIndex, retainerEdgeType))
-            continue;
-          orphanNode = false;
-          const retainerNodeOrdinal = retainerNodeIndex / nodeFieldCount;
-          const retainerNodeFlag = !flags || (flags[retainerNodeOrdinal] & flag);
-          // We are skipping the edges from non-page-owned nodes to page-owned nodes.
-          // Otherwise the dominators for the objects that also were retained by debugger would be affected.
-          if (retainerNodeIndex !== rootNodeIndex && nodeFlag && !retainerNodeFlag)
-            continue;
-          let retanerPostOrderIndex = nodeOrdinal2PostOrderIndex[retainerNodeOrdinal];
-          if (dominators[retanerPostOrderIndex] !== noEntry) {
-            if (newDominatorIndex === noEntry) {
-              newDominatorIndex = retanerPostOrderIndex;
-            } else {
-              while (retanerPostOrderIndex !== newDominatorIndex) {
-                while (retanerPostOrderIndex < newDominatorIndex)
-                  retanerPostOrderIndex = dominators[retanerPostOrderIndex];
-                while (newDominatorIndex < retanerPostOrderIndex)
-                  newDominatorIndex = dominators[newDominatorIndex];
-              }
-            }
-            // If idom has already reached the root, it doesn't make sense
-            // to check other retainers.
-            if (newDominatorIndex === rootPostOrderedIndex)
-              break;
-          }
-        }
-        // Make root dominator of orphans.
-        if (orphanNode)
-          newDominatorIndex = rootPostOrderedIndex;
-        if (newDominatorIndex !== noEntry && dominators[postOrderIndex] !== newDominatorIndex) {
-          dominators[postOrderIndex] = newDominatorIndex;
-          changed = true;
-          nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex];
-          const beginEdgeToNodeFieldIndex = firstEdgeIndexes[nodeOrdinal] + edgeToNodeOffset;
-          const endEdgeToNodeFieldIndex = firstEdgeIndexes[nodeOrdinal + 1];
-          for (let toNodeFieldIndex = beginEdgeToNodeFieldIndex; toNodeFieldIndex < endEdgeToNodeFieldIndex;
-               toNodeFieldIndex += edgeFieldsCount) {
-            const childNodeOrdinal = containmentEdges[toNodeFieldIndex] / nodeFieldCount;
-            affected[nodeOrdinal2PostOrderIndex[childNodeOrdinal]] = 1;
-          }
-        }
-      }
-    }
-
-    const dominatorsTree = new Uint32Array(nodesCount);
-    for (let postOrderIndex = 0, l = dominators.length; postOrderIndex < l; ++postOrderIndex) {
-      nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex];
-      dominatorsTree[nodeOrdinal] = postOrderIndex2NodeOrdinal[dominators[postOrderIndex]];
-    }
-    return dominatorsTree;
-  }
-
-  /**
-   * @param {!Array<number>} postOrderIndex2NodeOrdinal
-   */
-  _calculateRetainedSizes(postOrderIndex2NodeOrdinal) {
-    const nodeCount = this.nodeCount;
-    const nodes = this.nodes;
-    const nodeSelfSizeOffset = this._nodeSelfSizeOffset;
-    const nodeFieldCount = this._nodeFieldCount;
-    const dominatorsTree = this._dominatorsTree;
-    const retainedSizes = this._retainedSizes;
-
-    for (let nodeOrdinal = 0; nodeOrdinal < nodeCount; ++nodeOrdinal)
-      retainedSizes[nodeOrdinal] = nodes[nodeOrdinal * nodeFieldCount + nodeSelfSizeOffset];
-
-    // Propagate retained sizes for each node excluding root.
-    for (let postOrderIndex = 0; postOrderIndex < nodeCount - 1; ++postOrderIndex) {
-      const nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex];
-      const dominatorOrdinal = dominatorsTree[nodeOrdinal];
-      retainedSizes[dominatorOrdinal] += retainedSizes[nodeOrdinal];
-    }
-  }
-
-  _buildDominatedNodes() {
-    // Builds up two arrays:
-    //  - "dominatedNodes" is a continuous array, where each node owns an
-    //    interval (can be empty) with corresponding dominated nodes.
-    //  - "indexArray" is an array of indexes in the "dominatedNodes"
-    //    with the same positions as in the _nodeIndex.
-    const indexArray = this._firstDominatedNodeIndex;
-    // All nodes except the root have dominators.
-    const dominatedNodes = this._dominatedNodes;
-
-    // Count the number of dominated nodes for each node. Skip the root (node at
-    // index 0) as it is the only node that dominates itself.
-    const nodeFieldCount = this._nodeFieldCount;
-    const dominatorsTree = this._dominatorsTree;
-
-    let fromNodeOrdinal = 0;
-    let toNodeOrdinal = this.nodeCount;
-    const rootNodeOrdinal = this._rootNodeIndex / nodeFieldCount;
-    if (rootNodeOrdinal === fromNodeOrdinal)
-      fromNodeOrdinal = 1;
-    else if (rootNodeOrdinal === toNodeOrdinal - 1)
-      toNodeOrdinal = toNodeOrdinal - 1;
-    else
-      throw new Error('Root node is expected to be either first or last');
-    for (let nodeOrdinal = fromNodeOrdinal; nodeOrdinal < toNodeOrdinal; ++nodeOrdinal)
-      ++indexArray[dominatorsTree[nodeOrdinal]];
-    // Put in the first slot of each dominatedNodes slice the count of entries
-    // that will be filled.
-    let firstDominatedNodeIndex = 0;
-    for (let i = 0, l = this.nodeCount; i < l; ++i) {
-      const dominatedCount = dominatedNodes[firstDominatedNodeIndex] = indexArray[i];
-      indexArray[i] = firstDominatedNodeIndex;
-      firstDominatedNodeIndex += dominatedCount;
-    }
-    indexArray[this.nodeCount] = dominatedNodes.length;
-    // Fill up the dominatedNodes array with indexes of dominated nodes. Skip the root (node at
-    // index 0) as it is the only node that dominates itself.
-    for (let nodeOrdinal = fromNodeOrdinal; nodeOrdinal < toNodeOrdinal; ++nodeOrdinal) {
-      const dominatorOrdinal = dominatorsTree[nodeOrdinal];
-      let dominatedRefIndex = indexArray[dominatorOrdinal];
-      dominatedRefIndex += (--dominatedNodes[dominatedRefIndex]);
-      dominatedNodes[dominatedRefIndex] = nodeOrdinal * nodeFieldCount;
-    }
-  }
-
-  _buildSamples() {
-    const samples = this._rawSamples;
-    if (!samples || !samples.length)
-      return;
-    const sampleCount = samples.length / 2;
-    const sizeForRange = new Array(sampleCount);
-    const timestamps = new Array(sampleCount);
-    const lastAssignedIds = new Array(sampleCount);
-
-    const timestampOffset = this._metaNode.sample_fields.indexOf('timestamp_us');
-    const lastAssignedIdOffset = this._metaNode.sample_fields.indexOf('last_assigned_id');
-    for (let i = 0; i < sampleCount; i++) {
-      sizeForRange[i] = 0;
-      timestamps[i] = (samples[2 * i + timestampOffset]) / 1000;
-      lastAssignedIds[i] = samples[2 * i + lastAssignedIdOffset];
-    }
-
-    const nodes = this.nodes;
-    const nodesLength = nodes.length;
-    const nodeFieldCount = this._nodeFieldCount;
-    const node = this.rootNode();
-    for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
-      node.nodeIndex = nodeIndex;
-
-      const nodeId = node.id();
-      // JS objects have odd ids, skip native objects.
-      if (nodeId % 2 === 0)
-        continue;
-      const rangeIndex = lastAssignedIds.lowerBound(nodeId);
-      if (rangeIndex === sampleCount) {
-        // TODO: make heap profiler not allocate while taking snapshot
-        continue;
-      }
-      sizeForRange[rangeIndex] += node.selfSize();
-    }
-    this._samples = new HeapSnapshotModel.Samples(timestamps, lastAssignedIds, sizeForRange);
-  }
-
-  /**
-   * @return {?HeapSnapshotModel.Samples}
-   */
-  getSamples() {
-    return this._samples;
-  }
-
-  /**
-   * @protected
-   */
-  calculateFlags() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @protected
-   */
-  calculateStatistics() {
-    throw new Error('Not implemented');
-  }
-
-  userObjectsMapAndFlag() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @param {string} baseSnapshotId
-   * @param {!Object.<string, !HeapSnapshotModel.AggregateForDiff>} baseSnapshotAggregates
-   * @return {!Object.<string, !HeapSnapshotModel.Diff>}
-   */
-  calculateSnapshotDiff(baseSnapshotId, baseSnapshotAggregates) {
-    let snapshotDiff = this._snapshotDiffs[baseSnapshotId];
-    if (snapshotDiff)
-      return snapshotDiff;
-    snapshotDiff = {};
-
-    const aggregates = this.aggregates(true, 'allObjects');
-    for (const className in baseSnapshotAggregates) {
-      const baseAggregate = baseSnapshotAggregates[className];
-      const diff = this._calculateDiffForClass(baseAggregate, aggregates[className]);
-      if (diff)
-        snapshotDiff[className] = diff;
-    }
-    const emptyBaseAggregate = new HeapSnapshotModel.AggregateForDiff();
-    for (const className in aggregates) {
-      if (className in baseSnapshotAggregates)
-        continue;
-      snapshotDiff[className] = this._calculateDiffForClass(emptyBaseAggregate, aggregates[className]);
-    }
-
-    this._snapshotDiffs[baseSnapshotId] = snapshotDiff;
-    return snapshotDiff;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.AggregateForDiff} baseAggregate
-   * @param {!HeapSnapshotModel.Aggregate} aggregate
-   * @return {?HeapSnapshotModel.Diff}
-   */
-  _calculateDiffForClass(baseAggregate, aggregate) {
-    const baseIds = baseAggregate.ids;
-    const baseIndexes = baseAggregate.indexes;
-    const baseSelfSizes = baseAggregate.selfSizes;
-
-    const indexes = aggregate ? aggregate.idxs : [];
-
-    let i = 0;
-    let j = 0;
-    const l = baseIds.length;
-    const m = indexes.length;
-    const diff = new HeapSnapshotModel.Diff();
-
-    const nodeB = this.createNode(indexes[j]);
-    while (i < l && j < m) {
-      const nodeAId = baseIds[i];
-      if (nodeAId < nodeB.id()) {
-        diff.deletedIndexes.push(baseIndexes[i]);
-        diff.removedCount++;
-        diff.removedSize += baseSelfSizes[i];
-        ++i;
-      } else if (
-          nodeAId >
-          nodeB.id()) {  // Native nodes(e.g. dom groups) may have ids less than max JS object id in the base snapshot
-        diff.addedIndexes.push(indexes[j]);
-        diff.addedCount++;
-        diff.addedSize += nodeB.selfSize();
-        nodeB.nodeIndex = indexes[++j];
-      } else {  // nodeAId === nodeB.id()
-        ++i;
-        nodeB.nodeIndex = indexes[++j];
-      }
-    }
-    while (i < l) {
-      diff.deletedIndexes.push(baseIndexes[i]);
-      diff.removedCount++;
-      diff.removedSize += baseSelfSizes[i];
-      ++i;
-    }
-    while (j < m) {
-      diff.addedIndexes.push(indexes[j]);
-      diff.addedCount++;
-      diff.addedSize += nodeB.selfSize();
-      nodeB.nodeIndex = indexes[++j];
-    }
-    diff.countDelta = diff.addedCount - diff.removedCount;
-    diff.sizeDelta = diff.addedSize - diff.removedSize;
-    if (!diff.addedCount && !diff.removedCount)
-      return null;
-    return diff;
-  }
-
-  _nodeForSnapshotObjectId(snapshotObjectId) {
-    for (let it = this._allNodes(); it.hasNext(); it.next()) {
-      if (it.node.id() === snapshotObjectId)
-        return it.node;
-    }
-    return null;
-  }
-
-  /**
-   * @param {string} snapshotObjectId
-   * @return {?string}
-   */
-  nodeClassName(snapshotObjectId) {
-    const node = this._nodeForSnapshotObjectId(snapshotObjectId);
-    if (node)
-      return node.className();
-    return null;
-  }
-
-  /**
-   * @param {string} name
-   * @return {!Array.<number>}
-   */
-  idsOfObjectsWithName(name) {
-    const ids = [];
-    for (let it = this._allNodes(); it.hasNext(); it.next()) {
-      if (it.item().name() === name)
-        ids.push(it.item().id());
-    }
-    return ids;
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdgesProvider}
-   */
-  createEdgesProvider(nodeIndex) {
-    const node = this.createNode(nodeIndex);
-    const filter = this.containmentEdgesFilter();
-    const indexProvider = new HeapSnapshotWorker.HeapSnapshotEdgeIndexProvider(this);
-    return new HeapSnapshotWorker.HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @param {?function(!HeapSnapshotWorker.HeapSnapshotEdge):boolean} filter
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdgesProvider}
-   */
-  createEdgesProviderForTest(nodeIndex, filter) {
-    const node = this.createNode(nodeIndex);
-    const indexProvider = new HeapSnapshotWorker.HeapSnapshotEdgeIndexProvider(this);
-    return new HeapSnapshotWorker.HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
-  }
-
-  /**
-   * @return {?function(!HeapSnapshotWorker.HeapSnapshotEdge):boolean}
-   */
-  retainingEdgesFilter() {
-    return null;
-  }
-
-  /**
-   * @return {?function(!HeapSnapshotWorker.HeapSnapshotEdge):boolean}
-   */
-  containmentEdgesFilter() {
-    return null;
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {!HeapSnapshotWorker.HeapSnapshotEdgesProvider}
-   */
-  createRetainingEdgesProvider(nodeIndex) {
-    const node = this.createNode(nodeIndex);
-    const filter = this.retainingEdgesFilter();
-    const indexProvider = new HeapSnapshotWorker.HeapSnapshotRetainerEdgeIndexProvider(this);
-    return new HeapSnapshotWorker.HeapSnapshotEdgesProvider(this, filter, node.retainers(), indexProvider);
-  }
-
-  /**
-   * @param {string} baseSnapshotId
-   * @param {string} className
-   * @return {!HeapSnapshotWorker.HeapSnapshotNodesProvider}
-   */
-  createAddedNodesProvider(baseSnapshotId, className) {
-    const snapshotDiff = this._snapshotDiffs[baseSnapshotId];
-    const diffForClass = snapshotDiff[className];
-    return new HeapSnapshotWorker.HeapSnapshotNodesProvider(this, diffForClass.addedIndexes);
-  }
-
-  /**
-   * @param {!Array.<number>} nodeIndexes
-   * @return {!HeapSnapshotWorker.HeapSnapshotNodesProvider}
-   */
-  createDeletedNodesProvider(nodeIndexes) {
-    return new HeapSnapshotWorker.HeapSnapshotNodesProvider(this, nodeIndexes);
-  }
-
-  /**
-   * @param {string} className
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   * @return {!HeapSnapshotWorker.HeapSnapshotNodesProvider}
-   */
-  createNodesProviderForClass(className, nodeFilter) {
-    return new HeapSnapshotWorker.HeapSnapshotNodesProvider(
-        this, this.aggregatesWithFilter(nodeFilter)[className].idxs);
-  }
-
-  /**
-   * @return {number}
-   */
-  _maxJsNodeId() {
-    const nodeFieldCount = this._nodeFieldCount;
-    const nodes = this.nodes;
-    const nodesLength = nodes.length;
-    let id = 0;
-    for (let nodeIndex = this._nodeIdOffset; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
-      const nextId = nodes[nodeIndex];
-      // JS objects have odd ids, skip native objects.
-      if (nextId % 2 === 0)
-        continue;
-      if (id < nextId)
-        id = nextId;
-    }
-    return id;
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.StaticData}
-   */
-  updateStaticData() {
-    return new HeapSnapshotModel.StaticData(this.nodeCount, this._rootNodeIndex, this.totalSize, this._maxJsNodeId());
-  }
-};
-
-/**
- * @typedef {!{
- *   count: number,
- *   distance: number,
- *   self: number,
- *   maxRet: number,
- *   name: ?string,
- *   idxs: !Array<number>
- * }}
- */
-HeapSnapshotWorker.HeapSnapshot.AggregatedInfo;
-
-/**
- * @unrestricted
- */
-const HeapSnapshotMetainfo = class {
-  constructor() {
-    // New format.
-    this.node_fields = [];
-    this.node_types = [];
-    this.edge_fields = [];
-    this.edge_types = [];
-    this.trace_function_info_fields = [];
-    this.trace_node_fields = [];
-    this.sample_fields = [];
-    this.type_strings = {};
-  }
-};
-
-/**
- * @unrestricted
- */
-const HeapSnapshotHeader = class {
-  constructor() {
-    // New format.
-    this.title = '';
-    this.meta = new HeapSnapshotMetainfo();
-    this.node_count = 0;
-    this.edge_count = 0;
-    this.trace_function_count = 0;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotItemProvider = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotItemIterator} iterator
-   * @param {!HeapSnapshotWorker.HeapSnapshotItemIndexProvider} indexProvider
-   */
-  constructor(iterator, indexProvider) {
-    this._iterator = iterator;
-    this._indexProvider = indexProvider;
-    this._isEmpty = !iterator.hasNext();
-    /** @type {?Array.<number>} */
-    this._iterationOrder = null;
-    this._currentComparator = null;
-    this._sortedPrefixLength = 0;
-    this._sortedSuffixLength = 0;
-  }
-
-  _createIterationOrder() {
-    if (this._iterationOrder)
-      return;
-    this._iterationOrder = [];
-    for (let iterator = this._iterator; iterator.hasNext(); iterator.next())
-      this._iterationOrder.push(iterator.item().itemIndex());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEmpty() {
-    return this._isEmpty;
-  }
-
-  /**
-   * @param {number} begin
-   * @param {number} end
-   * @return {!HeapSnapshotModel.ItemsRange}
-   */
-  serializeItemsRange(begin, end) {
-    this._createIterationOrder();
-    if (begin > end)
-      throw new Error('Start position > end position: ' + begin + ' > ' + end);
-    if (end > this._iterationOrder.length)
-      end = this._iterationOrder.length;
-    if (this._sortedPrefixLength < end && begin < this._iterationOrder.length - this._sortedSuffixLength) {
-      this.sort(
-          this._currentComparator, this._sortedPrefixLength, this._iterationOrder.length - 1 - this._sortedSuffixLength,
-          begin, end - 1);
-      if (begin <= this._sortedPrefixLength)
-        this._sortedPrefixLength = end;
-      if (end >= this._iterationOrder.length - this._sortedSuffixLength)
-        this._sortedSuffixLength = this._iterationOrder.length - begin;
-    }
-    let position = begin;
-    const count = end - begin;
-    const result = new Array(count);
-    for (let i = 0; i < count; ++i) {
-      const itemIndex = this._iterationOrder[position++];
-      const item = this._indexProvider.itemForIndex(itemIndex);
-      result[i] = item.serialize();
-    }
-    return new HeapSnapshotModel.ItemsRange(begin, end, this._iterationOrder.length, result);
-  }
-
-  sortAndRewind(comparator) {
-    this._currentComparator = comparator;
-    this._sortedPrefixLength = 0;
-    this._sortedSuffixLength = 0;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotEdgesProvider = class extends HeapSnapshotWorker.HeapSnapshotItemProvider {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   * @param {?function(!HeapSnapshotWorker.HeapSnapshotEdge):boolean} filter
-   * @param {!HeapSnapshotWorker.HeapSnapshotEdgeIterator} edgesIter
-   * @param {!HeapSnapshotWorker.HeapSnapshotItemIndexProvider} indexProvider
-   */
-  constructor(snapshot, filter, edgesIter, indexProvider) {
-    const iter = filter ?
-        new HeapSnapshotWorker.HeapSnapshotFilteredIterator(
-            edgesIter, /** @type {function(!HeapSnapshotWorker.HeapSnapshotItem):boolean} */ (filter)) :
-        edgesIter;
-    super(iter, indexProvider);
-    this.snapshot = snapshot;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.ComparatorConfig} comparator
-   * @param {number} leftBound
-   * @param {number} rightBound
-   * @param {number} windowLeft
-   * @param {number} windowRight
-   */
-  sort(comparator, leftBound, rightBound, windowLeft, windowRight) {
-    const fieldName1 = comparator.fieldName1;
-    const fieldName2 = comparator.fieldName2;
-    const ascending1 = comparator.ascending1;
-    const ascending2 = comparator.ascending2;
-
-    const edgeA = this._iterator.item().clone();
-    const edgeB = edgeA.clone();
-    const nodeA = this.snapshot.createNode();
-    const nodeB = this.snapshot.createNode();
-
-    function compareEdgeFieldName(ascending, indexA, indexB) {
-      edgeA.edgeIndex = indexA;
-      edgeB.edgeIndex = indexB;
-      if (edgeB.name() === '__proto__')
-        return -1;
-      if (edgeA.name() === '__proto__')
-        return 1;
-      const result = edgeA.hasStringName() === edgeB.hasStringName() ?
-          (edgeA.name() < edgeB.name() ? -1 : (edgeA.name() > edgeB.name() ? 1 : 0)) :
-          (edgeA.hasStringName() ? -1 : 1);
-      return ascending ? result : -result;
-    }
-
-    function compareNodeField(fieldName, ascending, indexA, indexB) {
-      edgeA.edgeIndex = indexA;
-      nodeA.nodeIndex = edgeA.nodeIndex();
-      const valueA = nodeA[fieldName]();
-
-      edgeB.edgeIndex = indexB;
-      nodeB.nodeIndex = edgeB.nodeIndex();
-      const valueB = nodeB[fieldName]();
-
-      const result = valueA < valueB ? -1 : (valueA > valueB ? 1 : 0);
-      return ascending ? result : -result;
-    }
-
-    function compareEdgeAndNode(indexA, indexB) {
-      let result = compareEdgeFieldName(ascending1, indexA, indexB);
-      if (result === 0)
-        result = compareNodeField(fieldName2, ascending2, indexA, indexB);
-      if (result === 0)
-        return indexA - indexB;
-      return result;
-    }
-
-    function compareNodeAndEdge(indexA, indexB) {
-      let result = compareNodeField(fieldName1, ascending1, indexA, indexB);
-      if (result === 0)
-        result = compareEdgeFieldName(ascending2, indexA, indexB);
-      if (result === 0)
-        return indexA - indexB;
-      return result;
-    }
-
-    function compareNodeAndNode(indexA, indexB) {
-      let result = compareNodeField(fieldName1, ascending1, indexA, indexB);
-      if (result === 0)
-        result = compareNodeField(fieldName2, ascending2, indexA, indexB);
-      if (result === 0)
-        return indexA - indexB;
-      return result;
-    }
-
-    if (fieldName1 === '!edgeName')
-      this._iterationOrder.sortRange(compareEdgeAndNode, leftBound, rightBound, windowLeft, windowRight);
-    else if (fieldName2 === '!edgeName')
-      this._iterationOrder.sortRange(compareNodeAndEdge, leftBound, rightBound, windowLeft, windowRight);
-    else
-      this._iterationOrder.sortRange(compareNodeAndNode, leftBound, rightBound, windowLeft, windowRight);
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotNodesProvider = class extends HeapSnapshotWorker.HeapSnapshotItemProvider {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshot} snapshot
-   * @param {!Array<number>|!Uint32Array} nodeIndexes
-   */
-  constructor(snapshot, nodeIndexes) {
-    const indexProvider = new HeapSnapshotWorker.HeapSnapshotNodeIndexProvider(snapshot);
-    const it = new HeapSnapshotWorker.HeapSnapshotIndexRangeIterator(indexProvider, nodeIndexes);
-    super(it, indexProvider);
-    this.snapshot = snapshot;
-  }
-
-  /**
-   * @param {string} snapshotObjectId
-   * @return {number}
-   */
-  nodePosition(snapshotObjectId) {
-    this._createIterationOrder();
-    const node = this.snapshot.createNode();
-    let i = 0;
-    for (; i < this._iterationOrder.length; i++) {
-      node.nodeIndex = this._iterationOrder[i];
-      if (node.id() === snapshotObjectId)
-        break;
-    }
-    if (i === this._iterationOrder.length)
-      return -1;
-    const targetNodeIndex = this._iterationOrder[i];
-    let smallerCount = 0;
-    const compare = this._buildCompareFunction(this._currentComparator);
-    for (let i = 0; i < this._iterationOrder.length; i++) {
-      if (compare(this._iterationOrder[i], targetNodeIndex) < 0)
-        ++smallerCount;
-    }
-    return smallerCount;
-  }
-
-  /**
-   * @return {function(number,number):number}
-   */
-  _buildCompareFunction(comparator) {
-    const nodeA = this.snapshot.createNode();
-    const nodeB = this.snapshot.createNode();
-    const fieldAccessor1 = nodeA[comparator.fieldName1];
-    const fieldAccessor2 = nodeA[comparator.fieldName2];
-    const ascending1 = comparator.ascending1 ? 1 : -1;
-    const ascending2 = comparator.ascending2 ? 1 : -1;
-
-    /**
-     * @param {function():*} fieldAccessor
-     * @param {number} ascending
-     * @return {number}
-     */
-    function sortByNodeField(fieldAccessor, ascending) {
-      const valueA = fieldAccessor.call(nodeA);
-      const valueB = fieldAccessor.call(nodeB);
-      return valueA < valueB ? -ascending : (valueA > valueB ? ascending : 0);
-    }
-
-    /**
-     * @param {number} indexA
-     * @param {number} indexB
-     * @return {number}
-     */
-    function sortByComparator(indexA, indexB) {
-      nodeA.nodeIndex = indexA;
-      nodeB.nodeIndex = indexB;
-      let result = sortByNodeField(fieldAccessor1, ascending1);
-      if (result === 0)
-        result = sortByNodeField(fieldAccessor2, ascending2);
-      return result || indexA - indexB;
-    }
-
-    return sortByComparator;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.ComparatorConfig} comparator
-   * @param {number} leftBound
-   * @param {number} rightBound
-   * @param {number} windowLeft
-   * @param {number} windowRight
-   */
-  sort(comparator, leftBound, rightBound, windowLeft, windowRight) {
-    this._iterationOrder.sortRange(
-        this._buildCompareFunction(comparator), leftBound, rightBound, windowLeft, windowRight);
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.JSHeapSnapshot = class extends HeapSnapshotWorker.HeapSnapshot {
-  /**
-   * @param {!Object} profile
-   * @param {!HeapSnapshotWorker.HeapSnapshotProgress} progress
-   */
-  constructor(profile, progress) {
-    super(profile, progress);
-    this._nodeFlags = {
-      // bit flags
-      canBeQueried: 1,
-      detachedDOMTreeNode: 2,
-      pageObject: 4  // The idea is to track separately the objects owned by the page and the objects owned by debugger.
-    };
-    this._lazyStringCache = {};
-    this.initialize();
-  }
-
-  /**
-   * @override
-   * @param {number=} nodeIndex
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotNode}
-   */
-  createNode(nodeIndex) {
-    return new HeapSnapshotWorker.JSHeapSnapshotNode(this, nodeIndex === undefined ? -1 : nodeIndex);
-  }
-
-  /**
-   * @override
-   * @param {number} edgeIndex
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotEdge}
-   */
-  createEdge(edgeIndex) {
-    return new HeapSnapshotWorker.JSHeapSnapshotEdge(this, edgeIndex);
-  }
-
-  /**
-   * @override
-   * @param {number} retainerIndex
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotRetainerEdge}
-   */
-  createRetainingEdge(retainerIndex) {
-    return new HeapSnapshotWorker.JSHeapSnapshotRetainerEdge(this, retainerIndex);
-  }
-
-  /**
-   * @override
-   * @return {function(!HeapSnapshotWorker.HeapSnapshotEdge):boolean}
-   */
-  containmentEdgesFilter() {
-    return edge => !edge.isInvisible();
-  }
-
-  /**
-   * @override
-   * @return {function(!HeapSnapshotWorker.HeapSnapshotEdge):boolean}
-   */
-  retainingEdgesFilter() {
-    const containmentEdgesFilter = this.containmentEdgesFilter();
-    function filter(edge) {
-      return containmentEdgesFilter(edge) && !edge.node().isRoot() && !edge.isWeak();
-    }
-    return filter;
-  }
-
-  /**
-   * @override
-   */
-  calculateFlags() {
-    this._flags = new Uint32Array(this.nodeCount);
-    this._markDetachedDOMTreeNodes();
-    this._markQueriableHeapObjects();
-    this._markPageOwnedNodes();
-  }
-
-  /**
-   * @override
-   */
-  calculateDistances() {
-    /**
-     * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-     * @param {!HeapSnapshotWorker.HeapSnapshotEdge} edge
-     * @return {boolean}
-     */
-    function filter(node, edge) {
-      if (node.isHidden())
-        return edge.name() !== 'sloppy_function_map' || node.rawName() !== 'system / NativeContext';
-      if (node.isArray()) {
-        // DescriptorArrays are fixed arrays used to hold instance descriptors.
-        // The format of the these objects is:
-        //   [0]: Number of descriptors
-        //   [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
-        //          [0]: pointer to fixed array with enum cache
-        //          [1]: either Smi(0) or pointer to fixed array with indices
-        //   [i*3+2]: i-th key
-        //   [i*3+3]: i-th type
-        //   [i*3+4]: i-th descriptor
-        // As long as maps may share descriptor arrays some of the descriptor
-        // links may not be valid for all the maps. We just skip
-        // all the descriptor links when calculating distances.
-        // For more details see http://crbug.com/413608
-        if (node.rawName() !== '(map descriptors)')
-          return true;
-        const index = edge.name();
-        return index < 2 || (index % 3) !== 1;
-      }
-      return true;
-    }
-    super.calculateDistances(filter);
-  }
-
-  /**
-   * @override
-   * @protected
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-   * @return {boolean}
-   */
-  isUserRoot(node) {
-    return node.isUserRoot() || node.isDocumentDOMTreesRoot();
-  }
-
-  /**
-   * @override
-   * @param {function(!HeapSnapshotWorker.HeapSnapshotNode)} action
-   * @param {boolean=} userRootsOnly
-   */
-  forEachRoot(action, userRootsOnly) {
-    /**
-     * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-     * @param {string} name
-     * @return {?HeapSnapshotWorker.HeapSnapshotNode}
-     */
-    function getChildNodeByName(node, name) {
-      for (let iter = node.edges(); iter.hasNext(); iter.next()) {
-        const child = iter.edge.node();
-        if (child.name() === name)
-          return child;
-      }
-      return null;
-    }
-
-    const visitedNodes = {};
-    /**
-     * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-     */
-    function doAction(node) {
-      const ordinal = node.ordinal();
-      if (!visitedNodes[ordinal]) {
-        action(node);
-        visitedNodes[ordinal] = true;
-      }
-    }
-
-    const gcRoots = getChildNodeByName(this.rootNode(), '(GC roots)');
-    if (!gcRoots)
-      return;
-
-    if (userRootsOnly) {
-      for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
-        const node = iter.edge.node();
-        if (this.isUserRoot(node))
-          doAction(node);
-      }
-    } else {
-      for (let iter = gcRoots.edges(); iter.hasNext(); iter.next()) {
-        const subRoot = iter.edge.node();
-        for (let iter2 = subRoot.edges(); iter2.hasNext(); iter2.next())
-          doAction(iter2.edge.node());
-        doAction(subRoot);
-      }
-      for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next())
-        doAction(iter.edge.node());
-    }
-  }
-
-  /**
-   * @override
-   * @return {?{map: !Uint32Array, flag: number}}
-   */
-  userObjectsMapAndFlag() {
-    return {map: this._flags, flag: this._nodeFlags.pageObject};
-  }
-
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-   * @return {number}
-   */
-  _flagsOfNode(node) {
-    return this._flags[node.nodeIndex / this._nodeFieldCount];
-  }
-
-  _markDetachedDOMTreeNodes() {
-    const nodes = this.nodes;
-    const nodesLength = nodes.length;
-    const nodeFieldCount = this._nodeFieldCount;
-    const nodeNativeType = this._nodeNativeType;
-    const nodeTypeOffset = this._nodeTypeOffset;
-    const flag = this._nodeFlags.detachedDOMTreeNode;
-    const node = this.rootNode();
-    for (let nodeIndex = 0, ordinal = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount, ordinal++) {
-      const nodeType = nodes[nodeIndex + nodeTypeOffset];
-      if (nodeType !== nodeNativeType)
-        continue;
-      node.nodeIndex = nodeIndex;
-      if (node.name().startsWith('Detached '))
-        this._flags[ordinal] |= flag;
-    }
-  }
-
-  _markQueriableHeapObjects() {
-    // Allow runtime properties query for objects accessible from Window objects
-    // via regular properties, and for DOM wrappers. Trying to access random objects
-    // can cause a crash due to insonsistent state of internal properties of wrappers.
-    const flag = this._nodeFlags.canBeQueried;
-    const hiddenEdgeType = this._edgeHiddenType;
-    const internalEdgeType = this._edgeInternalType;
-    const invisibleEdgeType = this._edgeInvisibleType;
-    const weakEdgeType = this._edgeWeakType;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const containmentEdges = this.containmentEdges;
-    const nodeFieldCount = this._nodeFieldCount;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-
-    const flags = this._flags;
-    const list = [];
-
-    for (let iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
-      if (iter.edge.node().isUserRoot())
-        list.push(iter.edge.node().nodeIndex / nodeFieldCount);
-    }
-
-    while (list.length) {
-      const nodeOrdinal = list.pop();
-      if (flags[nodeOrdinal] & flag)
-        continue;
-      flags[nodeOrdinal] |= flag;
-      const beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
-      const endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
-      for (let edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
-        const childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-        const childNodeOrdinal = childNodeIndex / nodeFieldCount;
-        if (flags[childNodeOrdinal] & flag)
-          continue;
-        const type = containmentEdges[edgeIndex + edgeTypeOffset];
-        if (type === hiddenEdgeType || type === invisibleEdgeType || type === internalEdgeType || type === weakEdgeType)
-          continue;
-        list.push(childNodeOrdinal);
-      }
-    }
-  }
-
-  _markPageOwnedNodes() {
-    const edgeShortcutType = this._edgeShortcutType;
-    const edgeElementType = this._edgeElementType;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const edgeWeakType = this._edgeWeakType;
-    const firstEdgeIndexes = this._firstEdgeIndexes;
-    const containmentEdges = this.containmentEdges;
-    const nodeFieldCount = this._nodeFieldCount;
-    const nodesCount = this.nodeCount;
-
-    const flags = this._flags;
-    const pageObjectFlag = this._nodeFlags.pageObject;
-
-    const nodesToVisit = new Uint32Array(nodesCount);
-    let nodesToVisitLength = 0;
-
-    const rootNodeOrdinal = this._rootNodeIndex / nodeFieldCount;
-    const node = this.rootNode();
-
-    // Populate the entry points. They are Window objects and DOM Tree Roots.
-    for (let edgeIndex = firstEdgeIndexes[rootNodeOrdinal], endEdgeIndex = firstEdgeIndexes[rootNodeOrdinal + 1];
-         edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
-      const edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
-      const nodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-      if (edgeType === edgeElementType) {
-        node.nodeIndex = nodeIndex;
-        if (!node.isDocumentDOMTreesRoot())
-          continue;
-      } else if (edgeType !== edgeShortcutType) {
-        continue;
-      }
-      const nodeOrdinal = nodeIndex / nodeFieldCount;
-      nodesToVisit[nodesToVisitLength++] = nodeOrdinal;
-      flags[nodeOrdinal] |= pageObjectFlag;
-    }
-
-    // Mark everything reachable with the pageObject flag.
-    while (nodesToVisitLength) {
-      const nodeOrdinal = nodesToVisit[--nodesToVisitLength];
-      const beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
-      const endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
-      for (let edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
-        const childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-        const childNodeOrdinal = childNodeIndex / nodeFieldCount;
-        if (flags[childNodeOrdinal] & pageObjectFlag)
-          continue;
-        const type = containmentEdges[edgeIndex + edgeTypeOffset];
-        if (type === edgeWeakType)
-          continue;
-        nodesToVisit[nodesToVisitLength++] = childNodeOrdinal;
-        flags[childNodeOrdinal] |= pageObjectFlag;
-      }
-    }
-  }
-
-  /**
-   * @override
-   */
-  calculateStatistics() {
-    const nodeFieldCount = this._nodeFieldCount;
-    const nodes = this.nodes;
-    const nodesLength = nodes.length;
-    const nodeTypeOffset = this._nodeTypeOffset;
-    const nodeSizeOffset = this._nodeSelfSizeOffset;
-    const nodeNativeType = this._nodeNativeType;
-    const nodeCodeType = this._nodeCodeType;
-    const nodeConsStringType = this._nodeConsStringType;
-    const nodeSlicedStringType = this._nodeSlicedStringType;
-    const distances = this._nodeDistances;
-    let sizeNative = 0;
-    let sizeCode = 0;
-    let sizeStrings = 0;
-    let sizeJSArrays = 0;
-    let sizeSystem = 0;
-    const node = this.rootNode();
-    for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
-      const nodeSize = nodes[nodeIndex + nodeSizeOffset];
-      const ordinal = nodeIndex / nodeFieldCount;
-      if (distances[ordinal] >= HeapSnapshotModel.baseSystemDistance) {
-        sizeSystem += nodeSize;
-        continue;
-      }
-      const nodeType = nodes[nodeIndex + nodeTypeOffset];
-      node.nodeIndex = nodeIndex;
-      if (nodeType === nodeNativeType)
-        sizeNative += nodeSize;
-      else if (nodeType === nodeCodeType)
-        sizeCode += nodeSize;
-      else if (nodeType === nodeConsStringType || nodeType === nodeSlicedStringType || node.type() === 'string')
-        sizeStrings += nodeSize;
-      else if (node.name() === 'Array')
-        sizeJSArrays += this._calculateArraySize(node);
-    }
-    this._statistics = new HeapSnapshotModel.Statistics();
-    this._statistics.total = this.totalSize;
-    this._statistics.v8heap = this.totalSize - sizeNative;
-    this._statistics.native = sizeNative;
-    this._statistics.code = sizeCode;
-    this._statistics.jsArrays = sizeJSArrays;
-    this._statistics.strings = sizeStrings;
-    this._statistics.system = sizeSystem;
-  }
-
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotNode} node
-   * @return {number}
-   */
-  _calculateArraySize(node) {
-    let size = node.selfSize();
-    const beginEdgeIndex = node.edgeIndexesStart();
-    const endEdgeIndex = node.edgeIndexesEnd();
-    const containmentEdges = this.containmentEdges;
-    const strings = this.strings;
-    const edgeToNodeOffset = this._edgeToNodeOffset;
-    const edgeTypeOffset = this._edgeTypeOffset;
-    const edgeNameOffset = this._edgeNameOffset;
-    const edgeFieldsCount = this._edgeFieldsCount;
-    const edgeInternalType = this._edgeInternalType;
-    for (let edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
-      const edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
-      if (edgeType !== edgeInternalType)
-        continue;
-      const edgeName = strings[containmentEdges[edgeIndex + edgeNameOffset]];
-      if (edgeName !== 'elements')
-        continue;
-      const elementsNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
-      node.nodeIndex = elementsNodeIndex;
-      if (node.retainersCount() === 1)
-        size += node.selfSize();
-      break;
-    }
-    return size;
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.Statistics}
-   */
-  getStatistics() {
-    return this._statistics;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.JSHeapSnapshotNode = class extends HeapSnapshotWorker.HeapSnapshotNode {
-  /**
-   * @param {!HeapSnapshotWorker.JSHeapSnapshot} snapshot
-   * @param {number=} nodeIndex
-   */
-  constructor(snapshot, nodeIndex) {
-    super(snapshot, nodeIndex);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canBeQueried() {
-    const flags = this._snapshot._flagsOfNode(this);
-    return !!(flags & this._snapshot._nodeFlags.canBeQueried);
-  }
-
-  /**
-   * @return {string}
-   */
-  rawName() {
-    return super.name();
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  name() {
-    const snapshot = this._snapshot;
-    if (this.rawType() === snapshot._nodeConsStringType) {
-      let string = snapshot._lazyStringCache[this.nodeIndex];
-      if (typeof string === 'undefined') {
-        string = this._consStringName();
-        snapshot._lazyStringCache[this.nodeIndex] = string;
-      }
-      return string;
-    }
-    return this.rawName();
-  }
-
-  /**
-   * @return {string}
-   */
-  _consStringName() {
-    const snapshot = this._snapshot;
-    const consStringType = snapshot._nodeConsStringType;
-    const edgeInternalType = snapshot._edgeInternalType;
-    const edgeFieldsCount = snapshot._edgeFieldsCount;
-    const edgeToNodeOffset = snapshot._edgeToNodeOffset;
-    const edgeTypeOffset = snapshot._edgeTypeOffset;
-    const edgeNameOffset = snapshot._edgeNameOffset;
-    const strings = snapshot.strings;
-    const edges = snapshot.containmentEdges;
-    const firstEdgeIndexes = snapshot._firstEdgeIndexes;
-    const nodeFieldCount = snapshot._nodeFieldCount;
-    const nodeTypeOffset = snapshot._nodeTypeOffset;
-    const nodeNameOffset = snapshot._nodeNameOffset;
-    const nodes = snapshot.nodes;
-    const nodesStack = [];
-    nodesStack.push(this.nodeIndex);
-    let name = '';
-
-    while (nodesStack.length && name.length < 1024) {
-      const nodeIndex = nodesStack.pop();
-      if (nodes[nodeIndex + nodeTypeOffset] !== consStringType) {
-        name += strings[nodes[nodeIndex + nodeNameOffset]];
-        continue;
-      }
-      const nodeOrdinal = nodeIndex / nodeFieldCount;
-      const beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
-      const endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
-      let firstNodeIndex = 0;
-      let secondNodeIndex = 0;
-      for (let edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex && (!firstNodeIndex || !secondNodeIndex);
-           edgeIndex += edgeFieldsCount) {
-        const edgeType = edges[edgeIndex + edgeTypeOffset];
-        if (edgeType === edgeInternalType) {
-          const edgeName = strings[edges[edgeIndex + edgeNameOffset]];
-          if (edgeName === 'first')
-            firstNodeIndex = edges[edgeIndex + edgeToNodeOffset];
-          else if (edgeName === 'second')
-            secondNodeIndex = edges[edgeIndex + edgeToNodeOffset];
-        }
-      }
-      nodesStack.push(secondNodeIndex);
-      nodesStack.push(firstNodeIndex);
-    }
-    return name;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  className() {
-    const type = this.type();
-    switch (type) {
-      case 'hidden':
-        return '(system)';
-      case 'object':
-      case 'native':
-        return this.name();
-      case 'code':
-        return '(compiled code)';
-      default:
-        return '(' + type + ')';
-    }
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  classIndex() {
-    const snapshot = this._snapshot;
-    const nodes = snapshot.nodes;
-    const type = nodes[this.nodeIndex + snapshot._nodeTypeOffset];
-    if (type === snapshot._nodeObjectType || type === snapshot._nodeNativeType)
-      return nodes[this.nodeIndex + snapshot._nodeNameOffset];
-    return -1 - type;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  id() {
-    const snapshot = this._snapshot;
-    return snapshot.nodes[this.nodeIndex + snapshot._nodeIdOffset];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isHidden() {
-    return this.rawType() === this._snapshot._nodeHiddenType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isArray() {
-    return this.rawType() === this._snapshot._nodeArrayType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isSynthetic() {
-    return this.rawType() === this._snapshot._nodeSyntheticType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isUserRoot() {
-    return !this.isSynthetic();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDocumentDOMTreesRoot() {
-    return this.isSynthetic() && this.name() === '(Document DOM trees)';
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotModel.Node}
-   */
-  serialize() {
-    const result = super.serialize();
-    const flags = this._snapshot._flagsOfNode(this);
-    if (flags & this._snapshot._nodeFlags.canBeQueried)
-      result.canBeQueried = true;
-    if (flags & this._snapshot._nodeFlags.detachedDOMTreeNode)
-      result.detachedDOMTreeNode = true;
-    return result;
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.JSHeapSnapshotEdge = class extends HeapSnapshotWorker.HeapSnapshotEdge {
-  /**
-   * @param {!HeapSnapshotWorker.JSHeapSnapshot} snapshot
-   * @param {number=} edgeIndex
-   */
-  constructor(snapshot, edgeIndex) {
-    super(snapshot, edgeIndex);
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotEdge}
-   */
-  clone() {
-    const snapshot = /** @type {!HeapSnapshotWorker.JSHeapSnapshot} */ (this._snapshot);
-    return new HeapSnapshotWorker.JSHeapSnapshotEdge(snapshot, this.edgeIndex);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasStringName() {
-    if (!this.isShortcut())
-      return this._hasStringName();
-    return isNaN(parseInt(this._name(), 10));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isElement() {
-    return this.rawType() === this._snapshot._edgeElementType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isHidden() {
-    return this.rawType() === this._snapshot._edgeHiddenType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isWeak() {
-    return this.rawType() === this._snapshot._edgeWeakType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInternal() {
-    return this.rawType() === this._snapshot._edgeInternalType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInvisible() {
-    return this.rawType() === this._snapshot._edgeInvisibleType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShortcut() {
-    return this.rawType() === this._snapshot._edgeShortcutType;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  name() {
-    const name = this._name();
-    if (!this.isShortcut())
-      return String(name);
-    const numName = parseInt(name, 10);
-    return String(isNaN(numName) ? name : numName);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    const name = this.name();
-    switch (this.type()) {
-      case 'context':
-        return '->' + name;
-      case 'element':
-        return '[' + name + ']';
-      case 'weak':
-        return '[[' + name + ']]';
-      case 'property':
-        return name.indexOf(' ') === -1 ? '.' + name : '["' + name + '"]';
-      case 'shortcut':
-        if (typeof name === 'string')
-          return name.indexOf(' ') === -1 ? '.' + name : '["' + name + '"]';
-        else
-          return '[' + name + ']';
-      case 'internal':
-      case 'hidden':
-      case 'invisible':
-        return '{' + name + '}';
-    }
-    return '?' + name + '?';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _hasStringName() {
-    const type = this.rawType();
-    const snapshot = this._snapshot;
-    return type !== snapshot._edgeElementType && type !== snapshot._edgeHiddenType;
-  }
-
-  /**
-   * @return {string|number}
-   */
-  _name() {
-    return this._hasStringName() ? this._snapshot.strings[this._nameOrIndex()] : this._nameOrIndex();
-  }
-
-  /**
-   * @return {number}
-   */
-  _nameOrIndex() {
-    return this._edges[this.edgeIndex + this._snapshot._edgeNameOffset];
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  rawType() {
-    return this._edges[this.edgeIndex + this._snapshot._edgeTypeOffset];
-  }
-};
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.JSHeapSnapshotRetainerEdge = class extends HeapSnapshotWorker.HeapSnapshotRetainerEdge {
-  /**
-   * @param {!HeapSnapshotWorker.JSHeapSnapshot} snapshot
-   * @param {number} retainerIndex
-   */
-  constructor(snapshot, retainerIndex) {
-    super(snapshot, retainerIndex);
-  }
-
-  /**
-   * @override
-   * @return {!HeapSnapshotWorker.JSHeapSnapshotRetainerEdge}
-   */
-  clone() {
-    const snapshot = /** @type {!HeapSnapshotWorker.JSHeapSnapshot} */ (this._snapshot);
-    return new HeapSnapshotWorker.JSHeapSnapshotRetainerEdge(snapshot, this.retainerIndex());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isHidden() {
-    return this._edge().isHidden();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInternal() {
-    return this._edge().isInternal();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInvisible() {
-    return this._edge().isInvisible();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShortcut() {
-    return this._edge().isShortcut();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isWeak() {
-    return this._edge().isWeak();
-  }
-};
-
-(function disableLoggingForTest() {
-  // Runtime doesn't exist because this file is loaded as a one-off
-  // file in some inspector-protocol tests.
-  if (self.Runtime && Runtime.queryParam('test'))
-    console.warn = () => undefined;
-})();
diff --git a/front_end/heap_snapshot_worker/HeapSnapshotLoader.js b/front_end/heap_snapshot_worker/HeapSnapshotLoader.js
deleted file mode 100644
index 6c0abf3..0000000
--- a/front_end/heap_snapshot_worker/HeapSnapshotLoader.js
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotLoader = class {
-  /**
-   * @param {!HeapSnapshotWorker.HeapSnapshotWorkerDispatcher} dispatcher
-   */
-  constructor(dispatcher) {
-    this._reset();
-    this._progress = new HeapSnapshotWorker.HeapSnapshotProgress(dispatcher);
-  }
-
-  dispose() {
-    this._reset();
-  }
-
-  _reset() {
-    this._json = '';
-    this._state = 'find-snapshot-info';
-    this._snapshot = {};
-  }
-
-  close() {
-    if (this._json)
-      this._parseStringsArray();
-  }
-
-  /**
-   * @return {!HeapSnapshotWorker.JSHeapSnapshot}
-   */
-  buildSnapshot() {
-    this._progress.updateStatus('Processing snapshot\u2026');
-    const result = new HeapSnapshotWorker.JSHeapSnapshot(this._snapshot, this._progress);
-    this._reset();
-    return result;
-  }
-
-  _parseUintArray() {
-    let index = 0;
-    const char0 = '0'.charCodeAt(0);
-    const char9 = '9'.charCodeAt(0);
-    const closingBracket = ']'.charCodeAt(0);
-    const length = this._json.length;
-    while (true) {
-      while (index < length) {
-        const code = this._json.charCodeAt(index);
-        if (char0 <= code && code <= char9) {
-          break;
-        } else if (code === closingBracket) {
-          this._json = this._json.slice(index + 1);
-          return false;
-        }
-        ++index;
-      }
-      if (index === length) {
-        this._json = '';
-        return true;
-      }
-      let nextNumber = 0;
-      const startIndex = index;
-      while (index < length) {
-        const code = this._json.charCodeAt(index);
-        if (char0 > code || code > char9)
-          break;
-        nextNumber *= 10;
-        nextNumber += (code - char0);
-        ++index;
-      }
-      if (index === length) {
-        this._json = this._json.slice(startIndex);
-        return true;
-      }
-      this._array[this._arrayIndex++] = nextNumber;
-    }
-  }
-
-  _parseStringsArray() {
-    this._progress.updateStatus('Parsing strings\u2026');
-    const closingBracketIndex = this._json.lastIndexOf(']');
-    if (closingBracketIndex === -1)
-      throw new Error('Incomplete JSON');
-    this._json = this._json.slice(0, closingBracketIndex + 1);
-    this._snapshot.strings = JSON.parse(this._json);
-  }
-
-  /**
-   * @param {string} chunk
-   */
-  write(chunk) {
-    if (this._json !== null)
-      this._json += chunk;
-    while (true) {
-      switch (this._state) {
-        case 'find-snapshot-info': {
-          const snapshotToken = '"snapshot"';
-          const snapshotTokenIndex = this._json.indexOf(snapshotToken);
-          if (snapshotTokenIndex === -1)
-            throw new Error('Snapshot token not found');
-
-          const json = this._json.slice(snapshotTokenIndex + snapshotToken.length + 1);
-          this._state = 'parse-snapshot-info';
-          this._progress.updateStatus('Loading snapshot info\u2026');
-          this._json = null;  // tokenizer takes over input.
-          this._jsonTokenizer = new TextUtils.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this));
-          // Fall through with adjusted payload.
-          chunk = json;
-        }
-        case 'parse-snapshot-info': {
-          this._jsonTokenizer.write(chunk);
-          if (this._jsonTokenizer)
-            return;  // no remainder to process.
-          break;
-        }
-        case 'find-nodes': {
-          const nodesToken = '"nodes"';
-          const nodesTokenIndex = this._json.indexOf(nodesToken);
-          if (nodesTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.indexOf('[', nodesTokenIndex);
-          if (bracketIndex === -1)
-            return;
-          this._json = this._json.slice(bracketIndex + 1);
-          const node_fields_count = this._snapshot.snapshot.meta.node_fields.length;
-          const nodes_length = this._snapshot.snapshot.node_count * node_fields_count;
-          this._array = new Uint32Array(nodes_length);
-          this._arrayIndex = 0;
-          this._state = 'parse-nodes';
-          break;
-        }
-        case 'parse-nodes': {
-          const hasMoreData = this._parseUintArray();
-          this._progress.updateProgress('Loading nodes\u2026 %d%%', this._arrayIndex, this._array.length);
-          if (hasMoreData)
-            return;
-          this._snapshot.nodes = this._array;
-          this._state = 'find-edges';
-          this._array = null;
-          break;
-        }
-        case 'find-edges': {
-          const edgesToken = '"edges"';
-          const edgesTokenIndex = this._json.indexOf(edgesToken);
-          if (edgesTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.indexOf('[', edgesTokenIndex);
-          if (bracketIndex === -1)
-            return;
-          this._json = this._json.slice(bracketIndex + 1);
-          const edge_fields_count = this._snapshot.snapshot.meta.edge_fields.length;
-          const edges_length = this._snapshot.snapshot.edge_count * edge_fields_count;
-          this._array = new Uint32Array(edges_length);
-          this._arrayIndex = 0;
-          this._state = 'parse-edges';
-          break;
-        }
-        case 'parse-edges': {
-          const hasMoreData = this._parseUintArray();
-          this._progress.updateProgress('Loading edges\u2026 %d%%', this._arrayIndex, this._array.length);
-          if (hasMoreData)
-            return;
-          this._snapshot.edges = this._array;
-          this._array = null;
-          // If there is allocation info parse it, otherwise jump straight to strings.
-          if (this._snapshot.snapshot.trace_function_count) {
-            this._state = 'find-trace-function-infos';
-            this._progress.updateStatus('Loading allocation traces\u2026');
-          } else if (this._snapshot.snapshot.meta.sample_fields) {
-            this._state = 'find-samples';
-            this._progress.updateStatus('Loading samples\u2026');
-          } else {
-            this._state = 'find-strings';
-          }
-          break;
-        }
-        case 'find-trace-function-infos': {
-          const tracesToken = '"trace_function_infos"';
-          const tracesTokenIndex = this._json.indexOf(tracesToken);
-          if (tracesTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.indexOf('[', tracesTokenIndex);
-          if (bracketIndex === -1)
-            return;
-          this._json = this._json.slice(bracketIndex + 1);
-
-          const trace_function_info_field_count = this._snapshot.snapshot.meta.trace_function_info_fields.length;
-          const trace_function_info_length =
-              this._snapshot.snapshot.trace_function_count * trace_function_info_field_count;
-          this._array = new Uint32Array(trace_function_info_length);
-          this._arrayIndex = 0;
-          this._state = 'parse-trace-function-infos';
-          break;
-        }
-        case 'parse-trace-function-infos': {
-          if (this._parseUintArray())
-            return;
-          this._snapshot.trace_function_infos = this._array;
-          this._array = null;
-          this._state = 'find-trace-tree';
-          break;
-        }
-        case 'find-trace-tree': {
-          const tracesToken = '"trace_tree"';
-          const tracesTokenIndex = this._json.indexOf(tracesToken);
-          if (tracesTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.indexOf('[', tracesTokenIndex);
-          if (bracketIndex === -1)
-            return;
-          this._json = this._json.slice(bracketIndex);
-          this._state = 'parse-trace-tree';
-          break;
-        }
-        case 'parse-trace-tree': {
-          // If there is samples array parse it, otherwise jump straight to strings.
-          const nextToken = this._snapshot.snapshot.meta.sample_fields ? '"samples"' : '"strings"';
-          const nextTokenIndex = this._json.indexOf(nextToken);
-          if (nextTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.lastIndexOf(']', nextTokenIndex);
-          this._snapshot.trace_tree = JSON.parse(this._json.substring(0, bracketIndex + 1));
-          this._json = this._json.slice(bracketIndex + 1);
-          if (this._snapshot.snapshot.meta.sample_fields) {
-            this._state = 'find-samples';
-            this._progress.updateStatus('Loading samples\u2026');
-          } else {
-            this._state = 'find-strings';
-            this._progress.updateStatus('Loading strings\u2026');
-          }
-          break;
-        }
-        case 'find-samples': {
-          const samplesToken = '"samples"';
-          const samplesTokenIndex = this._json.indexOf(samplesToken);
-          if (samplesTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.indexOf('[', samplesTokenIndex);
-          if (bracketIndex === -1)
-            return;
-          this._json = this._json.slice(bracketIndex + 1);
-          this._array = [];
-          this._arrayIndex = 0;
-          this._state = 'parse-samples';
-          break;
-        }
-        case 'parse-samples': {
-          if (this._parseUintArray())
-            return;
-          this._snapshot.samples = this._array;
-          this._array = null;
-          this._state = 'find-strings';
-          this._progress.updateStatus('Loading strings\u2026');
-          break;
-        }
-        case 'find-strings': {
-          const stringsToken = '"strings"';
-          const stringsTokenIndex = this._json.indexOf(stringsToken);
-          if (stringsTokenIndex === -1)
-            return;
-          const bracketIndex = this._json.indexOf('[', stringsTokenIndex);
-          if (bracketIndex === -1)
-            return;
-          this._json = this._json.slice(bracketIndex);
-          this._state = 'accumulate-strings';
-          break;
-        }
-        case 'accumulate-strings':
-          return;
-      }
-    }
-  }
-
-  /**
-   * @param {string} data
-   */
-  _writeBalancedJSON(data) {
-    this._json = this._jsonTokenizer.remainder();  // tokenizer releases input.
-    this._jsonTokenizer = null;
-    this._state = 'find-nodes';
-    this._snapshot.snapshot = /** @type {!HeapSnapshotHeader} */ (JSON.parse(data));
-  }
-};
diff --git a/front_end/heap_snapshot_worker/HeapSnapshotWorker.js b/front_end/heap_snapshot_worker/HeapSnapshotWorker.js
deleted file mode 100644
index 159729f..0000000
--- a/front_end/heap_snapshot_worker/HeapSnapshotWorker.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-function postMessageWrapper(message) {
-  postMessage(message);
-}
-
-const dispatcher = new HeapSnapshotWorker.HeapSnapshotWorkerDispatcher(this, postMessageWrapper);
-
-/**
- * @param {function(!Event)} listener
- * @suppressGlobalPropertiesCheck
- */
-function installMessageEventListener(listener) {
-  self.addEventListener('message', listener, false);
-}
-
-installMessageEventListener(dispatcher.dispatchMessage.bind(dispatcher));
diff --git a/front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js b/front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
deleted file mode 100644
index 2eb6186..0000000
--- a/front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-HeapSnapshotWorker.HeapSnapshotWorkerDispatcher = class {
-  constructor(globalObject, postMessage) {
-    this._objects = [];
-    this._global = globalObject;
-    this._postMessage = postMessage;
-  }
-
-  _findFunction(name) {
-    const path = name.split('.');
-    let result = this._global;
-    for (let i = 0; i < path.length; ++i)
-      result = result[path[i]];
-    return result;
-  }
-
-  /**
-   * @param {string} name
-   * @param {*} data
-   */
-  sendEvent(name, data) {
-    this._postMessage({eventName: name, data: data});
-  }
-
-  dispatchMessage(event) {
-    const data = /** @type {!HeapSnapshotModel.WorkerCommand } */ (event.data);
-    const response = {callId: data.callId};
-    try {
-      switch (data.disposition) {
-        case 'create':
-          const constructorFunction = this._findFunction(data.methodName);
-          this._objects[data.objectId] = new constructorFunction(this);
-          break;
-        case 'dispose':
-          delete this._objects[data.objectId];
-          break;
-        case 'getter': {
-          const object = this._objects[data.objectId];
-          const result = object[data.methodName];
-          response.result = result;
-          break;
-        }
-        case 'factory': {
-          const object = this._objects[data.objectId];
-          const result = object[data.methodName].apply(object, data.methodArguments);
-          if (result)
-            this._objects[data.newObjectId] = result;
-          response.result = !!result;
-          break;
-        }
-        case 'method': {
-          const object = this._objects[data.objectId];
-          response.result = object[data.methodName].apply(object, data.methodArguments);
-          break;
-        }
-        case 'evaluateForTest':
-          try {
-            response.result = self.eval(data.source);
-          } catch (e) {
-            response.result = e.toString();
-          }
-          break;
-      }
-    } catch (e) {
-      response.error = e.toString();
-      response.errorCallStack = e.stack;
-      if (data.methodName)
-        response.errorMethodName = data.methodName;
-    }
-    this._postMessage(response);
-  }
-};
diff --git a/front_end/heap_snapshot_worker/module.json b/front_end/heap_snapshot_worker/module.json
deleted file mode 100644
index 74dfd91..0000000
--- a/front_end/heap_snapshot_worker/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "scripts": [
-        "AllocationProfile.js",
-        "HeapSnapshot.js",
-        "HeapSnapshotLoader.js",
-        "HeapSnapshotWorkerDispatcher.js",
-        "HeapSnapshotWorker.js"
-    ],
-    "dependencies": [
-        "heap_snapshot_model",
-        "platform",
-        "common"
-    ]
-}
diff --git a/front_end/help/Help.js b/front_end/help/Help.js
deleted file mode 100644
index 38e2ca0..0000000
--- a/front_end/help/Help.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @return {!Help.ReleaseNote}
- */
-Help.latestReleaseNote = function() {
-  if (!Help._latestReleaseNote) {
-    /** @type {!Help.ReleaseNote} */
-    Help._latestReleaseNote = Help.releaseNoteText.reduce((acc, note) => note.version > acc.version ? note : acc);
-  }
-  return Help._latestReleaseNote;
-};
-
-Help._showReleaseNoteIfNeeded = function() {
-  Help._innerShowReleaseNoteIfNeeded(
-      Help._releaseNoteVersionSetting.get(), Help.latestReleaseNote().version,
-      Common.settings.moduleSetting('help.show-release-note').get());
-};
-
-/**
- * @param {number} lastSeenVersion
- * @param {number} latestVersion
- * @param {boolean} showReleaseNote
- */
-Help._innerShowReleaseNoteIfNeeded = function(lastSeenVersion, latestVersion, showReleaseNote) {
-  if (!lastSeenVersion) {
-    Help._releaseNoteVersionSetting.set(latestVersion);
-    return;
-  }
-  if (!showReleaseNote)
-    return;
-  if (lastSeenVersion >= latestVersion)
-    return;
-  Help._releaseNoteVersionSetting.set(latestVersion);
-  UI.viewManager.showView(Help.releaseNoteViewId, true);
-};
-
-/**
- * @const
- * @type {string}
- */
-Help.releaseNoteViewId = 'release-note';
-
-/** @typedef {!{title: string, subtitle: string, link: string}} */
-Help.ReleaseNoteHighlight;
-
-/**
- * @typedef {!{version: number, header: string, highlights: !Array<!Help.ReleaseNoteHighlight>,
- *    link: string}}
- */
-Help.ReleaseNote;
-
-/**
- * @implements {Common.Runnable}
- */
-Help.HelpLateInitialization = class {
-  /**
-   * @override
-   */
-  run() {
-    Help._showReleaseNoteIfNeeded();
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Help.ReleaseNotesActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    InspectorFrontendHost.openInNewTab(Help.latestReleaseNote().link);
-    return true;
-  }
-};
-
-/** @type {!Common.Setting} */
-Help._releaseNoteVersionSetting = Common.settings.createSetting('releaseNoteVersionSeen', 0);
diff --git a/front_end/help/ReleaseNoteText.js b/front_end/help/ReleaseNoteText.js
deleted file mode 100644
index 9ede40f..0000000
--- a/front_end/help/ReleaseNoteText.js
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// NOTE: need to be careful about adding release notes early otherwise it'll
-// be shown in Canary (e.g. make sure the release notes are accurate).
-// https://github.com/ChromeDevTools/devtools-frontend/wiki/Release-Notes
-
-const continueToHereShortcut = Host.isMac() ? 'Command' : 'Control';
-const commandMenuShortcut = Host.isMac() ? 'Command + Shift + P' : 'Control + Shift + P';
-
-/** @type {!Array<!Help.ReleaseNote>} */
-Help.releaseNoteText = [
-  {
-    version: 9,
-    header: 'Highlights from the Chrome 66 update',
-    highlights: [
-      {
-        title: 'Pretty-printing in the Preview and Response tabs',
-        subtitle: 'The Preview tab now pretty-prints by default, and you can force ' +
-            'pretty-printing in the Response tab via the new Format button.',
-        link: 'https://developers.google.com/web/updates/2018/02/devtools#pretty-printing',
-      },
-      {
-        title: 'Previewing HTML content in the Preview tab',
-        subtitle: 'The Preview tab now always does a basic rendering of HTML content.',
-        link: 'https://developers.google.com/web/updates/2018/02/devtools#previews',
-      },
-      {
-        title: 'Local Overrides with styles defined in HTML',
-        subtitle: 'Local Overrides now works with styles defined in HTML, with one exception.',
-        link: 'https://developers.google.com/web/updates/2018/02/devtools#overrides',
-      },
-      {
-        title: 'Blackboxing in the Initiator column',
-        subtitle: 'Hide framework scripts in order to see the app code that caused a request.',
-        link: 'https://developers.google.com/web/updates/2018/02/devtools#blackboxing',
-      },
-    ],
-    link: 'https://developers.google.com/web/updates/2018/02/devtools',
-  },
-  {
-    version: 8,
-    header: 'Highlights from the Chrome 65 update',
-    highlights: [
-      {
-        title: 'Local overrides',
-        subtitle: 'Override network requests and serve local resources instead.',
-        link: 'https://developers.google.com/web/updates/2018/01/devtools#overrides',
-      },
-      {
-        title: 'Changes tab',
-        subtitle: 'Track changes that you make locally in DevTools via the Changes tab.',
-        link: 'https://developers.google.com/web/updates/2018/01/devtools#changes',
-      },
-      {
-        title: 'New accessibility tools',
-        subtitle: 'Inspect the accessibility properties and contrast ratio of elements.',
-        link: 'https://developers.google.com/web/updates/2018/01/devtools#a11y',
-      },
-      {
-        title: 'New audits',
-        subtitle: 'New performance audits, a whole new category of SEO audits, and more.',
-        link: 'https://developers.google.com/web/updates/2018/01/devtools#audits',
-      },
-      {
-        title: 'Code stepping updates',
-        subtitle: 'Reliably step into web worker and asynchronous code.',
-        link: 'https://developers.google.com/web/updates/2018/01/devtools#stepping',
-      },
-      {
-        title: 'Multiple recordings in the Performance panel',
-        subtitle: 'Temporarily save up to 5 recordings.',
-        link: 'https://developers.google.com/web/updates/2018/01/devtools#recordings',
-      },
-    ],
-    link: 'https://developers.google.com/web/updates/2018/01/devtools',
-  },
-  {
-    version: 7,
-    header: 'Highlights from the Chrome 64 update',
-    highlights: [
-      {
-        title: 'Performance monitor',
-        subtitle: 'Get a real-time view of various performance metrics.',
-        link: 'https://developers.google.com/web/updates/2017/11/devtools-release-notes#perf-monitor',
-      },
-      {
-        title: 'Console sidebar',
-        subtitle: 'Reduce console noise and focus on the messages that are important to you.',
-        link: 'https://developers.google.com/web/updates/2017/11/devtools-release-notes#console-sidebar',
-      },
-      {
-        title: 'Group similar console messages',
-        subtitle: 'The Console now groups similar messages by default.',
-        link: 'https://developers.google.com/web/updates/2017/11/devtools-release-notes#group-similar',
-      },
-    ],
-    link: 'https://developers.google.com/web/updates/2017/11/devtools-release-notes',
-  },
-  {
-    version: 6,
-    header: 'Highlights from the Chrome 63 update',
-    highlights: [
-      {
-        title: 'Multi-client remote debugging',
-        subtitle: 'Use DevTools while debugging your app from an IDE or testing framework.',
-        link: 'https://developers.google.com/web/updates/2017/10/devtools-release-notes#multi-client',
-      },
-      {
-        title: 'Workspaces 2.0',
-        subtitle: 'Save changes made in DevTools to disk, now with more helpful UI and better auto-mapping.',
-        link: 'https://developers.google.com/web/updates/2017/10/devtools-release-notes#workspaces',
-      },
-      {
-        title: 'Four new audits',
-        subtitle:
-            'Including "Appropriate aspect ratios for images", "Avoid JS libraries with known vulnerabilities", and more.',
-        link: 'https://developers.google.com/web/updates/2017/10/devtools-release-notes#audits',
-      },
-      {
-        title: 'Custom push notifications',
-        subtitle: 'Simulate push notifications with custom data.',
-        link: 'https://developers.google.com/web/updates/2017/10/devtools-release-notes#push',
-      },
-      {
-        title: 'Custom background sync events',
-        subtitle: 'Trigger background sync events with custom tags.',
-        link: 'https://developers.google.com/web/updates/2017/10/devtools-release-notes#sync',
-      },
-    ],
-    link: 'https://developers.google.com/web/updates/2017/10/devtools-release-notes',
-  },
-  {
-    version: 5,
-    header: 'Highlights from the Chrome 62 update',
-    highlights: [
-      {
-        title: 'Top-level await operators in the Console',
-        subtitle: 'Use await to conveniently experiment with asynchronous functions in the Console.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#await',
-      },
-      {
-        title: 'New screenshot workflows',
-        subtitle: 'Take screenshots of a portion of the viewport, or of specific HTML nodes.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#screenshots',
-      },
-      {
-        title: 'CSS Grid highlighting',
-        subtitle: 'Hover over an element to see the CSS Grid that\'s affecting it.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#css-grid-highlighting',
-      },
-      {
-        title: 'A new Console API for querying objects',
-        subtitle: 'Call queryObjects(Constructor) to get an array of objects instantiated with that constructor.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#query-objects',
-      },
-      {
-        title: 'New Console filters',
-        subtitle: 'Filter out logging noise with the new negative and URL filters.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#console-filters',
-      },
-      {
-        title: 'HAR imports in the Network panel',
-        subtitle: 'Drag-and-drop a HAR file to analyze a previous network recording.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#har-imports',
-      },
-      {
-        title: 'Previewable cache resources in the Application panel',
-        subtitle: 'Click a row in a Cache Storage table to see a preview of that resource.',
-        link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes#cache-preview',
-      }
-    ],
-    link: 'https://developers.google.com/web/updates/2017/08/devtools-release-notes',
-  },
-  {
-    version: 4,
-    header: 'Highlights from the Chrome 61 update',
-    highlights: [
-      {
-        title: 'Mobile device throttling',
-        subtitle: 'Simulate a mobile device\'s CPU and network throttling from Device Mode.',
-        link: 'https://developers.google.com/web/updates/2017/07/devtools-release-notes#throttling',
-      },
-      {
-        title: 'Storage usage',
-        subtitle: 'See how much storage (IndexedDB, local, session, cache, etc.) an origin is using.',
-        link: 'https://developers.google.com/web/updates/2017/07/devtools-release-notes#storage',
-      },
-      {
-        title: 'Cache timestamps',
-        subtitle: 'View when a service worker cached a response.',
-        link: 'https://developers.google.com/web/updates/2017/07/devtools-release-notes#time-cached',
-      },
-      {
-        title: 'ES6 Modules support',
-        subtitle: 'Debug ES6 Modules natively from the Sources panel.',
-        link: 'https://developers.google.com/web/updates/2017/07/devtools-release-notes#modules',
-      }
-    ],
-    link: 'https://developers.google.com/web/updates/2017/07/devtools-release-notes',
-  },
-  {
-    version: 3,
-    header: 'Highlights from the Chrome 60 update',
-    highlights: [
-      {
-        title: 'New Audits panel, powered by Lighthouse',
-        subtitle:
-            'Find out whether your site qualifies as a Progressive Web App, measure the accessibility and performance of a page, and discover best practices.',
-        link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes#lighthouse',
-      },
-      {
-        title: 'Third-party badges',
-        subtitle:
-            'See what third-party entities are logging to the Console, making network requests, and causing work during performance recordings.',
-        link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes#badges',
-      },
-      {
-        title: 'New "Continue to Here" gesture',
-        subtitle: 'While paused on a line of code, hold ' + continueToHereShortcut +
-            ' and then click to continue to another line of code.',
-        link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes#continue',
-      },
-      {
-        title: 'Step into async',
-        subtitle: 'Predictably step into a promise resolution or other asynchronous code with a single gesture.',
-        link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes#step-into-async',
-      },
-      {
-        title: 'More informative object previews',
-        subtitle: 'Get a better idea of the contents of objects when logging them to the Console.',
-        link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes#object-previews',
-      },
-      {
-        title: 'Real-time Coverage tab updates',
-        subtitle: 'See what code is being used in real-time.',
-        link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes#coverage',
-      }
-    ],
-    link: 'https://developers.google.com/web/updates/2017/05/devtools-release-notes',
-  },
-  {
-    version: 2,
-    header: 'Highlights from Chrome 59 update',
-    highlights: [
-      {
-        title: 'CSS and JS code coverage',
-        subtitle: 'Find unused CSS and JS with the new Coverage drawer.',
-        link: 'https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage',
-      },
-      {
-        title: 'Full-page screenshots',
-        subtitle: 'Take a screenshot of the entire page, from the top of the viewport to the bottom.',
-        link: 'https://developers.google.com/web/updates/2017/04/devtools-release-notes#screenshots',
-      },
-      {
-        title: 'Block requests',
-        subtitle: 'Manually disable individual requests in the Network panel.',
-        link: 'https://developers.google.com/web/updates/2017/04/devtools-release-notes#block-requests',
-      },
-      {
-        title: 'Step over async await',
-        subtitle: 'Step through async functions predictably.',
-        link: 'https://developers.google.com/web/updates/2017/04/devtools-release-notes#async',
-      },
-      {
-        title: 'Unified Command Menu',
-        subtitle: 'Execute commands and open files from the newly-unified Command Menu (' + commandMenuShortcut + ').',
-        link: 'https://developers.google.com/web/updates/2017/04/devtools-release-notes#command-menu',
-      }
-    ],
-    link: 'https://developers.google.com/web/updates/2017/04/devtools-release-notes',
-  },
-  {
-    version: 1,
-    header: 'Highlights from Chrome 58 update',
-    highlights: [
-      {
-        title: 'New Performance and Memory panels',
-        subtitle: 'Head to Performance for JavaScript profiling',
-        link: 'https://developers.google.com/web/updates/2017/03/devtools-release-notes#performance-panel',
-      },
-      {
-        title: 'Editable cookies',
-        subtitle: 'You can edit any existing cookies and create new ones in the Application panel',
-        link: 'https://developers.google.com/web/updates/2017/03/devtools-release-notes#cookies',
-      },
-      {
-        title: 'Console filtering & settings',
-        subtitle: 'Use the text filter or click the Console settings icon to touch up your preferences',
-        link: 'https://developers.google.com/web/updates/2017/03/devtools-release-notes#console',
-      },
-      {
-        title: 'Debugger catches out-of-memory errors',
-        subtitle: 'See the stack or grab a heap snapshot to see why the app may crash',
-        link: 'https://developers.google.com/web/updates/2017/03/devtools-release-notes#out-of-memory-breakpoints',
-      },
-    ],
-    link: 'https://developers.google.com/web/updates/2017/03/devtools-release-notes',
-  }
-];
diff --git a/front_end/help/ReleaseNoteView.js b/front_end/help/ReleaseNoteView.js
deleted file mode 100644
index 41eb8db..0000000
--- a/front_end/help/ReleaseNoteView.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Help.ReleaseNoteView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('help/releaseNote.css');
-    const releaseNoteElement = this._createReleaseNoteElement(Help.latestReleaseNote());
-    const topSection = this.contentElement.createChild('div', 'release-note-top-section');
-    topSection.textContent = Common.UIString(Help.latestReleaseNote().header);
-    this.contentElement.appendChild(releaseNoteElement);
-  }
-
-  /**
-   * @param {!Help.ReleaseNote} releaseNote
-   * @return {!Element}
-   */
-  _createReleaseNoteElement(releaseNote) {
-    const hbox = createElementWithClass('div', 'hbox');
-    const container = hbox.createChild('div', 'release-note-container');
-    const contentContainer = container.createChild('ul');
-    for (const highlight of releaseNote.highlights) {
-      const listItem = contentContainer.createChild('li');
-      const title = UI.XLink.create(highlight.link, highlight.title + ' ', 'release-note-title');
-      title.title = '';
-      listItem.appendChild(title);
-      const subtitle = UI.XLink.create(highlight.link, highlight.subtitle + ' ', 'release-note-subtitle');
-      subtitle.title = '';
-      listItem.appendChild(subtitle);
-    }
-
-    const actionContainer = container.createChild('div', 'release-note-action-container');
-    actionContainer.appendChild(UI.createTextButton(Common.UIString('Learn more'), event => {
-      event.consume(true);
-      InspectorFrontendHost.openInNewTab(releaseNote.link);
-    }));
-    actionContainer.appendChild(UI.createTextButton(Common.UIString('Close'), event => {
-      event.consume(true);
-      UI.inspectorView.closeDrawerTab(Help.releaseNoteViewId, true);
-    }, 'close-release-note'));
-
-    const imageLink = UI.XLink.create(releaseNote.link, ' ');
-    imageLink.classList.add('release-note-image');
-    imageLink.title = '';
-    hbox.appendChild(imageLink);
-    const image = imageLink.createChild('img');
-    image.src = 'Images/whatsnew.png';
-    return hbox;
-  }
-};
diff --git a/front_end/help/module.json b/front_end/help/module.json
deleted file mode 100644
index 1c98901..0000000
--- a/front_end/help/module.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
-  "extensions": [
-    {
-      "type": "view",
-      "location": "drawer-view",
-      "id": "release-note",
-      "title": "What's New",
-      "persistence": "closeable",
-      "order": 1,
-      "className": "Help.ReleaseNoteView"
-    },
-    {
-      "type": "setting",
-      "category": "Appearance",
-      "title": "Show What's New after each update",
-      "settingName": "help.show-release-note",
-      "settingType": "boolean",
-      "defaultValue": true,
-      "options": [
-        {
-          "value": true,
-          "title": "Show What's New after each update"
-        },
-        {
-          "value": false,
-          "title": "Do not show What's New after each update"
-        }
-      ]
-    },
-    {
-      "type": "action",
-      "category": "Help",
-      "actionId": "help.release-notes",
-      "title": "Release notes",
-      "className": "Help.ReleaseNotesActionDelegate"
-    },
-    {
-      "type": "context-menu-item",
-      "location": "mainMenuHelp/default",
-      "actionId": "help.release-notes",
-      "order": 10
-    },
-    {
-      "type": "late-initialization",
-      "className": "Help.HelpLateInitialization"
-    }
-  ],
-  "dependencies": [
-    "ui",
-    "host"
-  ],
-  "scripts": [
-    "Help.js",
-    "ReleaseNoteView.js",
-    "ReleaseNoteText.js"
-  ],
-  "resources": [
-    "releaseNote.css"
-  ]
-}
diff --git a/front_end/help/releaseNote.css b/front_end/help/releaseNote.css
deleted file mode 100644
index d0999de..0000000
--- a/front_end/help/releaseNote.css
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-}
-
-.hbox {
-    overflow-y: auto;
-    overflow-x: hidden;
-}
-
-.release-note-top-section {
-    height: 27px;
-    line-height: 27px;
-    padding: 0 15px;
-    flex: none;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-
-:host-context(.-theme-with-dark-background) .release-note-top-section {
-    color: white;
-}
-
-.release-note-container {
-    display: flex;
-    flex-direction: column;
-}
-
-.release-note-container ul {
-    display: flex;
-    padding: 10px 16px;
-    flex-direction: column;
-    flex: none;
-    margin: 4px 12px 0 2px;
-    max-width: 600px;
-}
-
-.release-note-container li {
-    display: flex;
-    flex-direction:column;
-    flex: none;
-    line-height: 24px;
-    font-size: 14px;
-}
-
-
-.release-note-container li:hover {
-    color: #039be5;
-}
-
-.release-note-title,
-.release-note-subtitle {
-    color: inherit;
-    text-decoration: none;
-}
-
-.release-note-subtitle {
-    font-size: 13px;
-    line-height: 13px;
-    padding-bottom: 8px;
-}
-
-.release-note-container li:not(:hover) .release-note-subtitle {
-    color: #999;
-}
-
-.release-note-action-container > button {
-    margin: 10px 0 20px 20px;
-    color: #757575;
-}
-
-.release-note-action-container {
-    flex: none;
-}
-
-.release-note-image {
-    flex-shrink: 2;
-}
-
-img {
-    margin: 20px;
-    width: 260px;
-    height: 200px;
-    flex: none;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, .3);
-}
-
-img:hover {
-    box-shadow: 0 2px 4px rgba(0, 0, 0, .5);
-}
diff --git a/front_end/host/InspectorFrontendHost.js b/front_end/host/InspectorFrontendHost.js
deleted file mode 100644
index 22139d7..0000000
--- a/front_end/host/InspectorFrontendHost.js
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {InspectorFrontendHostAPI}
- * @unrestricted
- */
-Host.InspectorFrontendHostStub = class {
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  constructor() {
-    /**
-     * @param {!Event} event
-     */
-    function stopEventPropagation(event) {
-      // Let browser handle Ctrl+/Ctrl- shortcuts in hosted mode.
-      const zoomModifier = Host.isMac() ? event.metaKey : event.ctrlKey;
-      if (zoomModifier && (event.keyCode === 187 || event.keyCode === 189))
-        event.stopPropagation();
-    }
-    document.addEventListener('keydown', stopEventPropagation, true);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  getSelectionBackgroundColor() {
-    return '#6e86ff';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  getSelectionForegroundColor() {
-    return '#ffffff';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  getInactiveSelectionBackgroundColor() {
-    return '#c9c8c8';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  getInactiveSelectionForegroundColor() {
-    return '#323232';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  platform() {
-    let match = navigator.userAgent.match(/Windows NT/);
-    if (match)
-      return 'windows';
-    match = navigator.userAgent.match(/Mac OS X/);
-    if (match)
-      return 'mac';
-    return 'linux';
-  }
-
-  /**
-   * @override
-   */
-  loadCompleted() {
-  }
-
-  /**
-   * @override
-   */
-  bringToFront() {
-    this._windowVisible = true;
-  }
-
-  /**
-   * @override
-   */
-  closeWindow() {
-    this._windowVisible = false;
-  }
-
-  /**
-   * @override
-   * @param {boolean} isDocked
-   * @param {function()} callback
-   */
-  setIsDocked(isDocked, callback) {
-    setTimeout(callback, 0);
-  }
-
-  /**
-   * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
-   * @override
-   * @param {{x: number, y: number, width: number, height: number}} bounds
-   */
-  setInspectedPageBounds(bounds) {
-  }
-
-  /**
-   * @override
-   */
-  inspectElementCompleted() {
-  }
-
-  /**
-   * @override
-   * @param {string} origin
-   * @param {string} script
-   */
-  setInjectedScriptForOrigin(origin, script) {
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @suppressGlobalPropertiesCheck
-   */
-  inspectedURLChanged(url) {
-    document.title = Common.UIString('DevTools - %s', url.replace(/^https?:\/\//, ''));
-  }
-
-  /**
-   * @override
-   * @param {string} text
-   */
-  copyText(text) {
-    Common.console.error('Clipboard is not enabled in hosted mode. Please inspect using chrome://inspect');
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   */
-  openInNewTab(url) {
-    window.open(url, '_blank');
-  }
-
-  /**
-   * @override
-   * @param {string} fileSystemPath
-   */
-  showItemInFolder(fileSystemPath) {
-    Common.console.error('Show item in folder is not enabled in hosted mode. Please inspect using chrome://inspect');
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} content
-   * @param {boolean} forceSaveAs
-   */
-  save(url, content, forceSaveAs) {
-    Common.console.error('Saving files is not enabled in hosted mode. Please inspect using chrome://inspect');
-    this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.CanceledSaveURL, url);
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} content
-   */
-  append(url, content) {
-    Common.console.error('Saving files is not enabled in hosted mode. Please inspect using chrome://inspect');
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   */
-  sendMessageToBackend(message) {
-  }
-
-  /**
-   * @override
-   * @param {string} actionName
-   * @param {number} actionCode
-   * @param {number} bucketSize
-   */
-  recordEnumeratedHistogram(actionName, actionCode, bucketSize) {
-  }
-
-  /**
-   * @override
-   */
-  requestFileSystems() {
-    this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemsLoaded, []);
-  }
-
-  /**
-   * @override
-   * @param {string=} type
-   */
-  addFileSystem(type) {
-  }
-
-  /**
-   * @override
-   * @param {string} fileSystemPath
-   */
-  removeFileSystem(fileSystemPath) {
-  }
-
-  /**
-   * @override
-   * @param {string} fileSystemId
-   * @param {string} registeredName
-   * @return {?DOMFileSystem}
-   */
-  isolatedFileSystem(fileSystemId, registeredName) {
-    return null;
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} headers
-   * @param {number} streamId
-   * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback
-   */
-  loadNetworkResource(url, headers, streamId, callback) {
-    Runtime.loadResourcePromise(url)
-        .then(function(text) {
-          Host.ResourceLoader.streamWrite(streamId, text);
-          callback({statusCode: 200});
-        })
-        .catch(function() {
-          callback({statusCode: 404});
-        });
-  }
-
-  /**
-   * @override
-   * @param {function(!Object<string, string>)} callback
-   */
-  getPreferences(callback) {
-    const prefs = {};
-    for (const name in window.localStorage)
-      prefs[name] = window.localStorage[name];
-    callback(prefs);
-  }
-
-  /**
-   * @override
-   * @param {string} name
-   * @param {string} value
-   */
-  setPreference(name, value) {
-    window.localStorage[name] = value;
-  }
-
-  /**
-   * @override
-   * @param {string} name
-   */
-  removePreference(name) {
-    delete window.localStorage[name];
-  }
-
-  /**
-   * @override
-   */
-  clearPreferences() {
-    window.localStorage.clear();
-  }
-
-  /**
-   * @override
-   * @param {!FileSystem} fileSystem
-   */
-  upgradeDraggedFileSystemPermissions(fileSystem) {
-  }
-
-  /**
-   * @override
-   * @param {number} requestId
-   * @param {string} fileSystemPath
-   * @param {string} excludedFolders
-   */
-  indexPath(requestId, fileSystemPath, excludedFolders) {
-  }
-
-  /**
-   * @override
-   * @param {number} requestId
-   */
-  stopIndexing(requestId) {
-  }
-
-  /**
-   * @override
-   * @param {number} requestId
-   * @param {string} fileSystemPath
-   * @param {string} query
-   */
-  searchInPath(requestId, fileSystemPath, query) {
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zoomFactor() {
-    return 1;
-  }
-
-  /**
-   * @override
-   */
-  zoomIn() {
-  }
-
-  /**
-   * @override
-   */
-  zoomOut() {
-  }
-
-  /**
-   * @override
-   */
-  resetZoom() {
-  }
-
-  /**
-   * @override
-   * @param {string} shortcuts
-   */
-  setWhitelistedShortcuts(shortcuts) {
-  }
-
-  /**
-   * @override
-   * @param {boolean} active
-   */
-  setEyeDropperActive(active) {
-  }
-
-  /**
-   * @param {!Array<string>} certChain
-   * @override
-   */
-  showCertificateViewer(certChain) {
-  }
-
-  /**
-   * @override
-   * @param {function()} callback
-   */
-  reattach(callback) {
-  }
-
-  /**
-   * @override
-   */
-  readyForTest() {
-  }
-
-  /**
-   * @override
-   */
-  connectionReady() {
-  }
-
-  /**
-   * @override
-   * @param {boolean} value
-   */
-  setOpenNewWindowForPopups(value) {
-  }
-
-  /**
-   * @override
-   * @param {!Adb.Config} config
-   */
-  setDevicesDiscoveryConfig(config) {
-  }
-
-  /**
-   * @override
-   * @param {boolean} enabled
-   */
-  setDevicesUpdatesEnabled(enabled) {
-  }
-
-  /**
-   * @override
-   * @param {string} pageId
-   * @param {string} action
-   */
-  performActionOnRemotePage(pageId, action) {
-  }
-
-  /**
-   * @override
-   * @param {string} browserId
-   * @param {string} url
-   */
-  openRemotePage(browserId, url) {
-  }
-
-  /**
-   * @override
-   */
-  openNodeFrontend() {
-  }
-
-  /**
-   * @override
-   * @param {number} x
-   * @param {number} y
-   * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
-   * @param {!Document} document
-   */
-  showContextMenuAtPoint(x, y, items, document) {
-    throw 'Soft context menu should be used';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isHostedMode() {
-    return true;
-  }
-};
-
-/**
- * @unrestricted
- */
-Host.InspectorFrontendAPIImpl = class {
-  constructor() {
-    this._debugFrontend =
-        !!Runtime.queryParam('debugFrontend') || (window['InspectorTest'] && window['InspectorTest']['debugTest']);
-
-    const descriptors = InspectorFrontendHostAPI.EventDescriptors;
-    for (let i = 0; i < descriptors.length; ++i)
-      this[descriptors[i][1]] = this._dispatch.bind(this, descriptors[i][0], descriptors[i][2], descriptors[i][3]);
-  }
-
-  /**
-   * @param {symbol} name
-   * @param {!Array.<string>} signature
-   * @param {boolean} runOnceLoaded
-   */
-  _dispatch(name, signature, runOnceLoaded) {
-    const params = Array.prototype.slice.call(arguments, 3);
-
-    if (this._debugFrontend)
-      setImmediate(innerDispatch);
-    else
-      innerDispatch();
-
-    function innerDispatch() {
-      // Single argument methods get dispatched with the param.
-      if (signature.length < 2) {
-        try {
-          InspectorFrontendHost.events.dispatchEventToListeners(name, params[0]);
-        } catch (e) {
-          console.error(e + ' ' + e.stack);
-        }
-        return;
-      }
-      const data = {};
-      for (let i = 0; i < signature.length; ++i)
-        data[signature[i]] = params[i];
-      try {
-        InspectorFrontendHost.events.dispatchEventToListeners(name, data);
-      } catch (e) {
-        console.error(e + ' ' + e.stack);
-      }
-    }
-  }
-
-  /**
-   * @param {number} id
-   * @param {string} chunk
-   */
-  streamWrite(id, chunk) {
-    Host.ResourceLoader.streamWrite(id, chunk);
-  }
-};
-
-/**
- * @type {!InspectorFrontendHostAPI}
- */
-let InspectorFrontendHost = window.InspectorFrontendHost || null;
-window.InspectorFrontendHost = InspectorFrontendHost;
-(function() {
-
-  function initializeInspectorFrontendHost() {
-    let proto;
-    if (!InspectorFrontendHost) {
-      // Instantiate stub for web-hosted mode if necessary.
-      window.InspectorFrontendHost = InspectorFrontendHost = new Host.InspectorFrontendHostStub();
-    } else {
-      // Otherwise add stubs for missing methods that are declared in the interface.
-      proto = Host.InspectorFrontendHostStub.prototype;
-      for (const name in proto) {
-        const value = proto[name];
-        if (typeof value !== 'function' || InspectorFrontendHost[name])
-          continue;
-
-        InspectorFrontendHost[name] = stub.bind(null, name);
-      }
-    }
-
-    /**
-     * @param {string} name
-     * @return {?}
-     */
-    function stub(name) {
-      console.error('Incompatible embedder: method InspectorFrontendHost.' + name + ' is missing. Using stub instead.');
-      const args = Array.prototype.slice.call(arguments, 1);
-      return proto[name].apply(InspectorFrontendHost, args);
-    }
-
-    // Attach the events object.
-    InspectorFrontendHost.events = new Common.Object();
-  }
-
-  // FIXME: This file is included into both apps, since the devtools_app needs the InspectorFrontendHostAPI only,
-  // so the host instance should not initialized there.
-  initializeInspectorFrontendHost();
-  window.InspectorFrontendAPI = new Host.InspectorFrontendAPIImpl();
-})();
-
-/**
- * @type {!Common.EventTarget}
- */
-InspectorFrontendHost.events;
-
-/**
- * @param {!Object<string, string>=} prefs
- * @return {boolean}
- */
-Host.isUnderTest = function(prefs) {
-  // Integration tests rely on test queryParam.
-  if (Runtime.queryParam('test'))
-    return true;
-  // Browser tests rely on prefs.
-  if (prefs)
-    return prefs['isUnderTest'] === 'true';
-  return Common.settings && Common.settings.createSetting('isUnderTest', false).get();
-};
diff --git a/front_end/host/InspectorFrontendHostAPI.js b/front_end/host/InspectorFrontendHostAPI.js
deleted file mode 100644
index 6c0bc59..0000000
--- a/front_end/host/InspectorFrontendHostAPI.js
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/** @interface */
-function InspectorFrontendHostAPI() {
-}
-window.InspectorFrontendHostAPI = InspectorFrontendHostAPI;
-/** @typedef
-{{
-    type: string,
-    id: (number|undefined),
-    label: (string|undefined),
-    enabled: (boolean|undefined),
-    checked: (boolean|undefined),
-    subItems: (!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>|undefined)
-}} */
-InspectorFrontendHostAPI.ContextMenuDescriptor;
-
-/** @typedef
-{{
-    statusCode: number,
-    headers: (!Object.<string, string>|undefined)
-}} */
-InspectorFrontendHostAPI.LoadNetworkResourceResult;
-
-/** @enum {symbol} */
-InspectorFrontendHostAPI.Events = {
-  AddExtensions: Symbol('addExtensions'),
-  AppendedToURL: Symbol('appendedToURL'),
-  CanceledSaveURL: Symbol('canceledSaveURL'),
-  ContextMenuCleared: Symbol('contextMenuCleared'),
-  ContextMenuItemSelected: Symbol('contextMenuItemSelected'),
-  DeviceCountUpdated: Symbol('deviceCountUpdated'),
-  DevicesDiscoveryConfigChanged: Symbol('devicesDiscoveryConfigChanged'),
-  DevicesPortForwardingStatusChanged: Symbol('devicesPortForwardingStatusChanged'),
-  DevicesUpdated: Symbol('devicesUpdated'),
-  DispatchMessage: Symbol('dispatchMessage'),
-  DispatchMessageChunk: Symbol('dispatchMessageChunk'),
-  EnterInspectElementMode: Symbol('enterInspectElementMode'),
-  EyeDropperPickedColor: Symbol('eyeDropperPickedColor'),
-  FileSystemsLoaded: Symbol('fileSystemsLoaded'),
-  FileSystemRemoved: Symbol('fileSystemRemoved'),
-  FileSystemAdded: Symbol('fileSystemAdded'),
-  FileSystemFilesChangedAddedRemoved: Symbol('FileSystemFilesChangedAddedRemoved'),
-  IndexingTotalWorkCalculated: Symbol('indexingTotalWorkCalculated'),
-  IndexingWorked: Symbol('indexingWorked'),
-  IndexingDone: Symbol('indexingDone'),
-  KeyEventUnhandled: Symbol('keyEventUnhandled'),
-  ReloadInspectedPage: Symbol('reloadInspectedPage'),
-  RevealSourceLine: Symbol('revealSourceLine'),
-  SavedURL: Symbol('savedURL'),
-  SearchCompleted: Symbol('searchCompleted'),
-  SetInspectedTabId: Symbol('setInspectedTabId'),
-  SetUseSoftMenu: Symbol('setUseSoftMenu'),
-  ShowPanel: Symbol('showPanel')
-};
-
-InspectorFrontendHostAPI.EventDescriptors = [
-  [InspectorFrontendHostAPI.Events.AddExtensions, 'addExtensions', ['extensions']],
-  [InspectorFrontendHostAPI.Events.AppendedToURL, 'appendedToURL', ['url']],
-  [InspectorFrontendHostAPI.Events.CanceledSaveURL, 'canceledSaveURL', ['url']],
-  [InspectorFrontendHostAPI.Events.ContextMenuCleared, 'contextMenuCleared', []],
-  [InspectorFrontendHostAPI.Events.ContextMenuItemSelected, 'contextMenuItemSelected', ['id']],
-  [InspectorFrontendHostAPI.Events.DeviceCountUpdated, 'deviceCountUpdated', ['count']],
-  [InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, 'devicesDiscoveryConfigChanged', ['config']],
-  [
-    InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, 'devicesPortForwardingStatusChanged', ['status']
-  ],
-  [InspectorFrontendHostAPI.Events.DevicesUpdated, 'devicesUpdated', ['devices']],
-  [InspectorFrontendHostAPI.Events.DispatchMessage, 'dispatchMessage', ['messageObject']],
-  [InspectorFrontendHostAPI.Events.DispatchMessageChunk, 'dispatchMessageChunk', ['messageChunk', 'messageSize']],
-  [InspectorFrontendHostAPI.Events.EnterInspectElementMode, 'enterInspectElementMode', []],
-  [InspectorFrontendHostAPI.Events.EyeDropperPickedColor, 'eyeDropperPickedColor', ['color']],
-  [InspectorFrontendHostAPI.Events.FileSystemsLoaded, 'fileSystemsLoaded', ['fileSystems']],
-  [InspectorFrontendHostAPI.Events.FileSystemRemoved, 'fileSystemRemoved', ['fileSystemPath']],
-  [InspectorFrontendHostAPI.Events.FileSystemAdded, 'fileSystemAdded', ['errorMessage', 'fileSystem']],
-  [
-    InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, 'fileSystemFilesChangedAddedRemoved',
-    ['changed', 'added', 'removed']
-  ],
-  [
-    InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, 'indexingTotalWorkCalculated',
-    ['requestId', 'fileSystemPath', 'totalWork']
-  ],
-  [InspectorFrontendHostAPI.Events.IndexingWorked, 'indexingWorked', ['requestId', 'fileSystemPath', 'worked']],
-  [InspectorFrontendHostAPI.Events.IndexingDone, 'indexingDone', ['requestId', 'fileSystemPath']],
-  [InspectorFrontendHostAPI.Events.KeyEventUnhandled, 'keyEventUnhandled', ['event']],
-  [InspectorFrontendHostAPI.Events.ReloadInspectedPage, 'reloadInspectedPage', ['hard']],
-  [InspectorFrontendHostAPI.Events.RevealSourceLine, 'revealSourceLine', ['url', 'lineNumber', 'columnNumber']],
-  [InspectorFrontendHostAPI.Events.SavedURL, 'savedURL', ['url', 'fileSystemPath']],
-  [InspectorFrontendHostAPI.Events.SearchCompleted, 'searchCompleted', ['requestId', 'fileSystemPath', 'files']],
-  [InspectorFrontendHostAPI.Events.SetInspectedTabId, 'setInspectedTabId', ['tabId']],
-  [InspectorFrontendHostAPI.Events.SetUseSoftMenu, 'setUseSoftMenu', ['useSoftMenu']],
-  [InspectorFrontendHostAPI.Events.ShowPanel, 'showPanel', ['panelName']]
-];
-
-InspectorFrontendHostAPI.prototype = {
-  /**
-   * @param {string=} type
-   */
-  addFileSystem(type) {},
-
-  /**
-   * @param {string} url
-   * @param {string} content
-   */
-  append(url, content) {},
-
-  loadCompleted() {},
-
-  /**
-   * @param {number} requestId
-   * @param {string} fileSystemPath
-   * @param {string} excludedFolders
-   */
-  indexPath(requestId, fileSystemPath, excludedFolders) {},
-
-  /**
-   * @return {string}
-   */
-  getSelectionBackgroundColor() {},
-
-  /**
-   * @return {string}
-   */
-  getSelectionForegroundColor() {},
-
-  /**
-   * @return {string}
-   */
-  getInactiveSelectionBackgroundColor() {},
-
-  /**
-   * @return {string}
-   */
-  getInactiveSelectionForegroundColor() {},
-
-  /**
-   * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
-   * @param {{x: number, y: number, width: number, height: number}} bounds
-   */
-  setInspectedPageBounds(bounds) {},
-
-  /**
-   * @param {!Array<string>} certChain
-   */
-  showCertificateViewer(certChain) {},
-
-  /**
-   * @param {string} shortcuts
-   */
-  setWhitelistedShortcuts(shortcuts) {},
-
-  /**
-   * @param {boolean} active
-   */
-  setEyeDropperActive(active) {},
-
-  inspectElementCompleted() {},
-
-  /**
-   * @param {string} url
-   */
-  openInNewTab(url) {},
-
-  /**
-   * @param {string} fileSystemPath
-   */
-  showItemInFolder(fileSystemPath) {},
-
-  /**
-   * @param {string} fileSystemPath
-   */
-  removeFileSystem(fileSystemPath) {},
-
-  requestFileSystems() {},
-
-  /**
-   * @param {string} url
-   * @param {string} content
-   * @param {boolean} forceSaveAs
-   */
-  save(url, content, forceSaveAs) {},
-
-  /**
-   * @param {number} requestId
-   * @param {string} fileSystemPath
-   * @param {string} query
-   */
-  searchInPath(requestId, fileSystemPath, query) {},
-
-  /**
-   * @param {number} requestId
-   */
-  stopIndexing(requestId) {},
-
-  bringToFront() {},
-
-  closeWindow() {},
-
-  copyText(text) {},
-
-  /**
-   * @param {string} url
-   */
-  inspectedURLChanged(url) {},
-
-  /**
-   * @param {string} fileSystemId
-   * @param {string} registeredName
-   * @return {?DOMFileSystem}
-   */
-  isolatedFileSystem(fileSystemId, registeredName) {},
-
-  /**
-   * @param {string} url
-   * @param {string} headers
-   * @param {number} streamId
-   * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback
-   */
-  loadNetworkResource(url, headers, streamId, callback) {},
-
-  /**
-   * @param {function(!Object<string, string>)} callback
-   */
-  getPreferences(callback) {},
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   */
-  setPreference(name, value) {},
-
-  /**
-   * @param {string} name
-   */
-  removePreference(name) {},
-
-  clearPreferences() {},
-
-  /**
-   * @param {!FileSystem} fileSystem
-   */
-  upgradeDraggedFileSystemPermissions(fileSystem) {},
-
-  /**
-   * @return {string}
-   */
-  platform() {},
-
-  /**
-   * @param {string} actionName
-   * @param {number} actionCode
-   * @param {number} bucketSize
-   */
-  recordEnumeratedHistogram(actionName, actionCode, bucketSize) {},
-
-  /**
-   * @param {string} message
-   */
-  sendMessageToBackend(message) {},
-
-  /**
-   * @param {!Adb.Config} config
-   */
-  setDevicesDiscoveryConfig(config) {},
-
-  /**
-   * @param {boolean} enabled
-   */
-  setDevicesUpdatesEnabled(enabled) {},
-
-  /**
-   * @param {string} pageId
-   * @param {string} action
-   */
-  performActionOnRemotePage(pageId, action) {},
-
-  /**
-   * @param {string} browserId
-   * @param {string} url
-   */
-  openRemotePage(browserId, url) {},
-
-  openNodeFrontend() {},
-
-  /**
-   * @param {string} origin
-   * @param {string} script
-   */
-  setInjectedScriptForOrigin(origin, script) {},
-
-  /**
-   * @param {boolean} isDocked
-   * @param {function()} callback
-   */
-  setIsDocked(isDocked, callback) {},
-
-  /**
-   * @return {number}
-   */
-  zoomFactor() {},
-
-  zoomIn() {},
-
-  zoomOut() {},
-
-  resetZoom() {},
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
-   * @param {!Document} document
-   */
-  showContextMenuAtPoint(x, y, items, document) {},
-
-  /**
-   * @param {function()} callback
-   */
-  reattach(callback) {},
-
-  readyForTest() {},
-
-  connectionReady() {},
-
-  /**
-   * @param {boolean} value
-   */
-  setOpenNewWindowForPopups(value) {},
-
-  /**
-   * @return {boolean}
-   */
-  isHostedMode() {}
-};
diff --git a/front_end/host/Platform.js b/front_end/host/Platform.js
deleted file mode 100644
index 427b307..0000000
--- a/front_end/host/Platform.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @return {string}
- */
-Host.platform = function() {
-  if (!Host._platform)
-    Host._platform = InspectorFrontendHost.platform();
-  return Host._platform;
-};
-
-/**
- * @return {boolean}
- */
-Host.isMac = function() {
-  if (typeof Host._isMac === 'undefined')
-    Host._isMac = Host.platform() === 'mac';
-
-  return Host._isMac;
-};
-
-/**
- * @return {boolean}
- */
-Host.isWin = function() {
-  if (typeof Host._isWin === 'undefined')
-    Host._isWin = Host.platform() === 'windows';
-
-  return Host._isWin;
-};
-
-/**
- * @return {boolean}
- */
-Host.isCustomDevtoolsFrontend = function() {
-  if (typeof Host._isCustomDevtoolsFronend === 'undefined')
-    Host._isCustomDevtoolsFronend = window.location.toString().startsWith('chrome-devtools://devtools/custom/');
-  return Host._isCustomDevtoolsFronend;
-};
-
-/**
- * @return {string}
- */
-Host.fontFamily = function() {
-  if (Host._fontFamily)
-    return Host._fontFamily;
-  switch (Host.platform()) {
-    case 'linux':
-      Host._fontFamily = 'Roboto, Ubuntu, Arial, sans-serif';
-      break;
-    case 'mac':
-      Host._fontFamily = '\'Lucida Grande\', sans-serif';
-      break;
-    case 'windows':
-      Host._fontFamily = '\'Segoe UI\', Tahoma, sans-serif';
-      break;
-  }
-  return Host._fontFamily;
-};
diff --git a/front_end/host/ResourceLoader.js b/front_end/host/ResourceLoader.js
deleted file mode 100644
index c382ec0..0000000
--- a/front_end/host/ResourceLoader.js
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Host.ResourceLoader = {};
-
-Host.ResourceLoader._lastStreamId = 0;
-/** @type {!Object.<number, !Common.OutputStream>} */
-Host.ResourceLoader._boundStreams = {};
-
-/**
- * @param {!Common.OutputStream} stream
- * @return {number}
- */
-Host.ResourceLoader._bindOutputStream = function(stream) {
-  Host.ResourceLoader._boundStreams[++Host.ResourceLoader._lastStreamId] = stream;
-  return Host.ResourceLoader._lastStreamId;
-};
-
-/**
- * @param {number} id
- */
-Host.ResourceLoader._discardOutputStream = function(id) {
-  Host.ResourceLoader._boundStreams[id].close();
-  delete Host.ResourceLoader._boundStreams[id];
-};
-
-/**
- * @param {number} id
- * @param {string} chunk
- */
-Host.ResourceLoader.streamWrite = function(id, chunk) {
-  Host.ResourceLoader._boundStreams[id].write(chunk);
-};
-
-/**
- * @param {string} url
- * @param {?Object.<string, string>} headers
- * @param {function(number, !Object.<string, string>, string)} callback
- */
-Host.ResourceLoader.load = function(url, headers, callback) {
-  const stream = new Common.StringOutputStream();
-  Host.ResourceLoader.loadAsStream(url, headers, stream, mycallback);
-
-  /**
-   * @param {number} statusCode
-   * @param {!Object.<string, string>} headers
-   */
-  function mycallback(statusCode, headers) {
-    callback(statusCode, headers, stream.data());
-  }
-};
-
-/**
- * @param {string} url
- * @param {?Object.<string, string>} headers
- * @param {!Common.OutputStream} stream
- * @param {function(number, !Object.<string, string>)=} callback
- */
-Host.ResourceLoader.loadAsStream = function(url, headers, stream, callback) {
-  const streamId = Host.ResourceLoader._bindOutputStream(stream);
-  const parsedURL = new Common.ParsedURL(url);
-  if (parsedURL.isDataURL()) {
-    loadXHR(url).then(dataURLDecodeSuccessful).catch(dataURLDecodeFailed);
-    return;
-  }
-
-  const rawHeaders = [];
-  if (headers) {
-    for (const key in headers)
-      rawHeaders.push(key + ': ' + headers[key]);
-  }
-  InspectorFrontendHost.loadNetworkResource(url, rawHeaders.join('\r\n'), streamId, finishedCallback);
-
-  /**
-   * @param {!InspectorFrontendHostAPI.LoadNetworkResourceResult} response
-   */
-  function finishedCallback(response) {
-    if (callback)
-      callback(response.statusCode, response.headers || {});
-    Host.ResourceLoader._discardOutputStream(streamId);
-  }
-
-  /**
-   * @param {string} text
-   */
-  function dataURLDecodeSuccessful(text) {
-    Host.ResourceLoader.streamWrite(streamId, text);
-    finishedCallback(/** @type {!InspectorFrontendHostAPI.LoadNetworkResourceResult} */ ({statusCode: 200}));
-  }
-
-  function dataURLDecodeFailed() {
-    finishedCallback(/** @type {!InspectorFrontendHostAPI.LoadNetworkResourceResult} */ ({statusCode: 404}));
-  }
-};
diff --git a/front_end/host/UserMetrics.js b/front_end/host/UserMetrics.js
deleted file mode 100644
index 997cbfe..0000000
--- a/front_end/host/UserMetrics.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Host.UserMetrics = class {
-  /**
-   * @param {string} panelName
-   */
-  panelShown(panelName) {
-    const code = Host.UserMetrics._PanelCodes[panelName] || 0;
-    const size = Object.keys(Host.UserMetrics._PanelCodes).length + 1;
-    InspectorFrontendHost.recordEnumeratedHistogram('DevTools.PanelShown', code, size);
-  }
-
-  /**
-   * @param {string} drawerId
-   */
-  drawerShown(drawerId) {
-    this.panelShown('drawer-' + drawerId);
-  }
-
-  /**
-   * @param {!Host.UserMetrics.Action} action
-   */
-  actionTaken(action) {
-    const size = Object.keys(Host.UserMetrics.Action).length + 1;
-    InspectorFrontendHost.recordEnumeratedHistogram('DevTools.ActionTaken', action, size);
-  }
-};
-
-// Codes below are used to collect UMA histograms in the Chromium port.
-// Do not change the values below, additional actions are needed on the Chromium side
-// in order to add more codes.
-
-/** @enum {number} */
-Host.UserMetrics.Action = {
-  WindowDocked: 1,
-  WindowUndocked: 2,
-  ScriptsBreakpointSet: 3,
-  TimelineStarted: 4,
-  ProfilesCPUProfileTaken: 5,
-  ProfilesHeapProfileTaken: 6,
-  AuditsStarted: 7,
-  ConsoleEvaluated: 8,
-  FileSavedInWorkspace: 9,
-  DeviceModeEnabled: 10,
-  AnimationsPlaybackRateChanged: 11,
-  RevisionApplied: 12,
-  FileSystemDirectoryContentReceived: 13,
-  StyleRuleEdited: 14,
-  CommandEvaluatedInConsolePanel: 15,
-  DOMPropertiesExpanded: 16,
-  ResizedViewInResponsiveMode: 17,
-  TimelinePageReloadStarted: 18,
-  ConnectToNodeJSFromFrontend: 19,
-  ConnectToNodeJSDirectly: 20,
-  CpuThrottlingEnabled: 21,
-  CpuProfileNodeFocused: 22,
-  CpuProfileNodeExcluded: 23,
-  SelectFileFromFilePicker: 24,
-  SelectCommandFromCommandMenu: 25,
-  ChangeInspectedNodeInElementsPanel: 26,
-  StyleRuleCopied: 27,
-  CoverageStarted: 28,
-  Audits2Started: 29,
-  Audits2Finished: 30,
-  ShowedThirdPartyBadges: 31,
-};
-
-Host.UserMetrics._PanelCodes = {
-  elements: 1,
-  resources: 2,
-  network: 3,
-  sources: 4,
-  timeline: 5,
-  heap_profiler: 6,
-  audits: 7,
-  console: 8,
-  layers: 9,
-  'drawer-console-view': 10,
-  'drawer-animations': 11,
-  'drawer-network.config': 12,
-  'drawer-rendering': 13,
-  'drawer-sensors': 14,
-  'drawer-sources.search': 15,
-  security: 16,
-  js_profiler: 17,
-  audits2: 18,
-};
-
-/** @type {!Host.UserMetrics} */
-Host.userMetrics = new Host.UserMetrics();
diff --git a/front_end/host/module.json b/front_end/host/module.json
deleted file mode 100644
index 62febc3..0000000
--- a/front_end/host/module.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "dependencies": [
-        "common",
-        "platform"
-    ],
-    "scripts": [
-        "InspectorFrontendHostAPI.js",
-        "InspectorFrontendHost.js",
-        "Platform.js",
-        "ResourceLoader.js",
-        "UserMetrics.js"
-    ]
-}
diff --git a/front_end/inline_editor/BezierEditor.js b/front_end/inline_editor/BezierEditor.js
deleted file mode 100644
index 05f0663..0000000
--- a/front_end/inline_editor/BezierEditor.js
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-InlineEditor.BezierEditor = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('inline_editor/bezierEditor.css');
-    this.contentElement.tabIndex = 0;
-    this.setDefaultFocusedElement(this.contentElement);
-
-    // Preview UI
-    this._previewElement = this.contentElement.createChild('div', 'bezier-preview-container');
-    this._previewElement.createChild('div', 'bezier-preview-animation');
-    this._previewElement.addEventListener('click', this._startPreviewAnimation.bind(this));
-    this._previewOnion = this.contentElement.createChild('div', 'bezier-preview-onion');
-    this._previewOnion.addEventListener('click', this._startPreviewAnimation.bind(this));
-
-    this._outerContainer = this.contentElement.createChild('div', 'bezier-container');
-
-    // Presets UI
-    this._presetsContainer = this._outerContainer.createChild('div', 'bezier-presets');
-    this._presetUI = new InlineEditor.BezierUI(40, 40, 0, 2, false);
-    this._presetCategories = [];
-    for (let i = 0; i < InlineEditor.BezierEditor.Presets.length; i++) {
-      this._presetCategories[i] = this._createCategory(InlineEditor.BezierEditor.Presets[i]);
-      this._presetsContainer.appendChild(this._presetCategories[i].icon);
-    }
-
-    // Curve UI
-    this._curveUI = new InlineEditor.BezierUI(150, 250, 50, 7, true);
-    this._curve = this._outerContainer.createSVGChild('svg', 'bezier-curve');
-    UI.installDragHandle(
-        this._curve, this._dragStart.bind(this), this._dragMove.bind(this), this._dragEnd.bind(this), 'default');
-
-    this._header = this.contentElement.createChild('div', 'bezier-header');
-    const minus = this._createPresetModifyIcon(this._header, 'bezier-preset-minus', 'M 12 6 L 8 10 L 12 14');
-    const plus = this._createPresetModifyIcon(this._header, 'bezier-preset-plus', 'M 8 6 L 12 10 L 8 14');
-    minus.addEventListener('click', this._presetModifyClicked.bind(this, false));
-    plus.addEventListener('click', this._presetModifyClicked.bind(this, true));
-    this._label = this._header.createChild('span', 'source-code bezier-display-value');
-  }
-
-  /**
-   * @param {?UI.Geometry.CubicBezier} bezier
-   */
-  setBezier(bezier) {
-    if (!bezier)
-      return;
-    this._bezier = bezier;
-    this._updateUI();
-  }
-
-  /**
-   * @return {!UI.Geometry.CubicBezier}
-   */
-  bezier() {
-    return this._bezier;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._unselectPresets();
-    // Check if bezier matches a preset
-    for (const category of this._presetCategories) {
-      for (let i = 0; i < category.presets.length; i++) {
-        if (this._bezier.asCSSText() === category.presets[i].value) {
-          category.presetIndex = i;
-          this._presetCategorySelected(category);
-        }
-      }
-    }
-
-    this._updateUI();
-    this._startPreviewAnimation();
-  }
-
-  _onchange() {
-    this._updateUI();
-    this.dispatchEventToListeners(InlineEditor.BezierEditor.Events.BezierChanged, this._bezier.asCSSText());
-  }
-
-  _updateUI() {
-    const labelText = this._selectedCategory ? this._selectedCategory.presets[this._selectedCategory.presetIndex].name :
-                                               this._bezier.asCSSText().replace(/\s(-\d\.\d)/g, '$1');
-    this._label.textContent = Common.UIString(labelText);
-    this._curveUI.drawCurve(this._bezier, this._curve);
-    this._previewOnion.removeChildren();
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _dragStart(event) {
-    this._mouseDownPosition = new UI.Geometry.Point(event.x, event.y);
-    const ui = this._curveUI;
-    this._controlPosition = new UI.Geometry.Point(
-        Number.constrain((event.offsetX - ui.radius) / ui.curveWidth(), 0, 1),
-        (ui.curveHeight() + ui.marginTop + ui.radius - event.offsetY) / ui.curveHeight());
-
-    const firstControlPointIsCloser = this._controlPosition.distanceTo(this._bezier.controlPoints[0]) <
-        this._controlPosition.distanceTo(this._bezier.controlPoints[1]);
-    this._selectedPoint = firstControlPointIsCloser ? 0 : 1;
-
-    this._bezier.controlPoints[this._selectedPoint] = this._controlPosition;
-    this._unselectPresets();
-    this._onchange();
-
-    event.consume(true);
-    return true;
-  }
-
-  /**
-   * @param {number} mouseX
-   * @param {number} mouseY
-   */
-  _updateControlPosition(mouseX, mouseY) {
-    const deltaX = (mouseX - this._mouseDownPosition.x) / this._curveUI.curveWidth();
-    const deltaY = (mouseY - this._mouseDownPosition.y) / this._curveUI.curveHeight();
-    const newPosition = new UI.Geometry.Point(
-        Number.constrain(this._controlPosition.x + deltaX, 0, 1), this._controlPosition.y - deltaY);
-    this._bezier.controlPoints[this._selectedPoint] = newPosition;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _dragMove(event) {
-    this._updateControlPosition(event.x, event.y);
-    this._onchange();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _dragEnd(event) {
-    this._updateControlPosition(event.x, event.y);
-    this._onchange();
-    this._startPreviewAnimation();
-  }
-
-  /**
-   * @param {!Array<{name: string, value: string}>} presetGroup
-   * @return {!InlineEditor.BezierEditor.PresetCategory}
-   */
-  _createCategory(presetGroup) {
-    const presetElement = createElementWithClass('div', 'bezier-preset-category');
-    const iconElement = presetElement.createSVGChild('svg', 'bezier-preset monospace');
-    const category = {presets: presetGroup, presetIndex: 0, icon: presetElement};
-    this._presetUI.drawCurve(UI.Geometry.CubicBezier.parse(category.presets[0].value), iconElement);
-    iconElement.addEventListener('click', this._presetCategorySelected.bind(this, category));
-    return category;
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {string} className
-   * @param {string} drawPath
-   * @return {!Element}
-   */
-  _createPresetModifyIcon(parentElement, className, drawPath) {
-    const icon = parentElement.createSVGChild('svg', 'bezier-preset-modify ' + className);
-    icon.setAttribute('width', 20);
-    icon.setAttribute('height', 20);
-    const path = icon.createSVGChild('path');
-    path.setAttribute('d', drawPath);
-    return icon;
-  }
-
-  _unselectPresets() {
-    for (const category of this._presetCategories)
-      category.icon.classList.remove('bezier-preset-selected');
-    delete this._selectedCategory;
-    this._header.classList.remove('bezier-header-active');
-  }
-
-  /**
-   * @param {!InlineEditor.BezierEditor.PresetCategory} category
-   * @param {!Event=} event
-   */
-  _presetCategorySelected(category, event) {
-    if (this._selectedCategory === category)
-      return;
-    this._unselectPresets();
-    this._header.classList.add('bezier-header-active');
-    this._selectedCategory = category;
-    this._selectedCategory.icon.classList.add('bezier-preset-selected');
-    this.setBezier(UI.Geometry.CubicBezier.parse(category.presets[category.presetIndex].value));
-    this._onchange();
-    this._startPreviewAnimation();
-    if (event)
-      event.consume(true);
-  }
-
-  /**
-   * @param {boolean} intensify
-   * @param {!Event} event
-   */
-  _presetModifyClicked(intensify, event) {
-    if (!this._selectedCategory)
-      return;
-
-    const length = this._selectedCategory.presets.length;
-    this._selectedCategory.presetIndex = (this._selectedCategory.presetIndex + (intensify ? 1 : -1) + length) % length;
-    this.setBezier(
-        UI.Geometry.CubicBezier.parse(this._selectedCategory.presets[this._selectedCategory.presetIndex].value));
-    this._onchange();
-    this._startPreviewAnimation();
-  }
-
-  _startPreviewAnimation() {
-    if (this._previewAnimation)
-      this._previewAnimation.cancel();
-
-    const animationDuration = 1600;
-    const numberOnionSlices = 20;
-
-    const keyframes = [
-      {offset: 0, transform: 'translateX(0px)', easing: this._bezier.asCSSText(), opacity: 1},
-      {offset: 0.9, transform: 'translateX(218px)', opacity: 1},
-      {offset: 1, transform: 'translateX(218px)', opacity: 0}
-    ];
-    this._previewAnimation = this._previewElement.animate(keyframes, animationDuration);
-    this._previewOnion.removeChildren();
-    for (let i = 0; i <= numberOnionSlices; i++) {
-      const slice = this._previewOnion.createChild('div', 'bezier-preview-animation');
-      const player = slice.animate(
-          [{transform: 'translateX(0px)', easing: this._bezier.asCSSText()}, {transform: 'translateX(218px)'}],
-          {duration: animationDuration, fill: 'forwards'});
-      player.pause();
-      player.currentTime = animationDuration * i / numberOnionSlices;
-    }
-  }
-};
-
-/** @enum {symbol} */
-InlineEditor.BezierEditor.Events = {
-  BezierChanged: Symbol('BezierChanged')
-};
-
-InlineEditor.BezierEditor.Presets = [
-  [
-    {name: 'ease-in-out', value: 'ease-in-out'}, {name: 'In Out · Sine', value: 'cubic-bezier(0.45, 0.05, 0.55, 0.95)'},
-    {name: 'In Out · Quadratic', value: 'cubic-bezier(0.46, 0.03, 0.52, 0.96)'},
-    {name: 'In Out · Cubic', value: 'cubic-bezier(0.65, 0.05, 0.36, 1)'},
-    {name: 'Fast Out, Slow In', value: 'cubic-bezier(0.4, 0, 0.2, 1)'},
-    {name: 'In Out · Back', value: 'cubic-bezier(0.68, -0.55, 0.27, 1.55)'}
-  ],
-  [
-    {name: 'Fast Out, Linear In', value: 'cubic-bezier(0.4, 0, 1, 1)'}, {name: 'ease-in', value: 'ease-in'},
-    {name: 'In · Sine', value: 'cubic-bezier(0.47, 0, 0.75, 0.72)'},
-    {name: 'In · Quadratic', value: 'cubic-bezier(0.55, 0.09, 0.68, 0.53)'},
-    {name: 'In · Cubic', value: 'cubic-bezier(0.55, 0.06, 0.68, 0.19)'},
-    {name: 'In · Back', value: 'cubic-bezier(0.6, -0.28, 0.74, 0.05)'}
-  ],
-  [
-    {name: 'ease-out', value: 'ease-out'}, {name: 'Out · Sine', value: 'cubic-bezier(0.39, 0.58, 0.57, 1)'},
-    {name: 'Out · Quadratic', value: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'},
-    {name: 'Out · Cubic', value: 'cubic-bezier(0.22, 0.61, 0.36, 1)'},
-    {name: 'Linear Out, Slow In', value: 'cubic-bezier(0, 0, 0.2, 1)'},
-    {name: 'Out · Back', value: 'cubic-bezier(0.18, 0.89, 0.32, 1.28)'}
-  ]
-];
-
-/** @typedef {{presets: !Array.<{name: string, value: string}>, icon: !Element, presetIndex: number}} */
-InlineEditor.BezierEditor.PresetCategory;
diff --git a/front_end/inline_editor/BezierUI.js b/front_end/inline_editor/BezierUI.js
deleted file mode 100644
index f5c88ca..0000000
--- a/front_end/inline_editor/BezierUI.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-InlineEditor.BezierUI = class {
-  /**
-   * @param {number} width
-   * @param {number} height
-   * @param {number} marginTop
-   * @param {number} controlPointRadius
-   * @param {boolean} linearLine
-   */
-  constructor(width, height, marginTop, controlPointRadius, linearLine) {
-    this.width = width;
-    this.height = height;
-    this.marginTop = marginTop;
-    this.radius = controlPointRadius;
-    this.linearLine = linearLine;
-  }
-
-  /**
-   * @param {!UI.Geometry.CubicBezier} bezier
-   * @param {!Element} path
-   * @param {number} width
-   */
-  static drawVelocityChart(bezier, path, width) {
-    const height = InlineEditor.BezierUI.Height;
-    let pathBuilder = ['M', 0, height];
-    /** @const */ const sampleSize = 1 / 40;
-
-    let prev = bezier.evaluateAt(0);
-    for (let t = sampleSize; t < 1 + sampleSize; t += sampleSize) {
-      const current = bezier.evaluateAt(t);
-      let slope = (current.y - prev.y) / (current.x - prev.x);
-      const weightedX = prev.x * (1 - t) + current.x * t;
-      slope = Math.tanh(slope / 1.5);  // Normalise slope
-      pathBuilder = pathBuilder.concat(['L', (weightedX * width).toFixed(2), (height - slope * height).toFixed(2)]);
-      prev = current;
-    }
-    pathBuilder = pathBuilder.concat(['L', width.toFixed(2), height, 'Z']);
-    path.setAttribute('d', pathBuilder.join(' '));
-  }
-
-  /**
-   * @return {number}
-   */
-  curveWidth() {
-    return this.width - this.radius * 2;
-  }
-
-  /**
-   * @return {number}
-   */
-  curveHeight() {
-    return this.height - this.radius * 2 - this.marginTop * 2;
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {string} className
-   * @param {number} x1
-   * @param {number} y1
-   * @param {number} x2
-   * @param {number} y2
-   */
-  _drawLine(parentElement, className, x1, y1, x2, y2) {
-    const line = parentElement.createSVGChild('line', className);
-    line.setAttribute('x1', x1 + this.radius);
-    line.setAttribute('y1', y1 + this.radius + this.marginTop);
-    line.setAttribute('x2', x2 + this.radius);
-    line.setAttribute('y2', y2 + this.radius + this.marginTop);
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {number} startX
-   * @param {number} startY
-   * @param {number} controlX
-   * @param {number} controlY
-   */
-  _drawControlPoints(parentElement, startX, startY, controlX, controlY) {
-    this._drawLine(parentElement, 'bezier-control-line', startX, startY, controlX, controlY);
-    const circle = parentElement.createSVGChild('circle', 'bezier-control-circle');
-    circle.setAttribute('cx', controlX + this.radius);
-    circle.setAttribute('cy', controlY + this.radius + this.marginTop);
-    circle.setAttribute('r', this.radius);
-  }
-
-  /**
-   * @param {?UI.Geometry.CubicBezier} bezier
-   * @param {!Element} svg
-   */
-  drawCurve(bezier, svg) {
-    if (!bezier)
-      return;
-    const width = this.curveWidth();
-    const height = this.curveHeight();
-    svg.setAttribute('width', this.width);
-    svg.setAttribute('height', this.height);
-    svg.removeChildren();
-    const group = svg.createSVGChild('g');
-
-    if (this.linearLine)
-      this._drawLine(group, 'linear-line', 0, height, width, 0);
-
-    const curve = group.createSVGChild('path', 'bezier-path');
-    const curvePoints = [
-      new UI.Geometry.Point(
-          bezier.controlPoints[0].x * width + this.radius,
-          (1 - bezier.controlPoints[0].y) * height + this.radius + this.marginTop),
-      new UI.Geometry.Point(
-          bezier.controlPoints[1].x * width + this.radius,
-          (1 - bezier.controlPoints[1].y) * height + this.radius + this.marginTop),
-      new UI.Geometry.Point(width + this.radius, this.marginTop + this.radius)
-    ];
-    curve.setAttribute(
-        'd', 'M' + this.radius + ',' + (height + this.radius + this.marginTop) + ' C' + curvePoints.join(' '));
-
-    this._drawControlPoints(
-        group, 0, height, bezier.controlPoints[0].x * width, (1 - bezier.controlPoints[0].y) * height);
-    this._drawControlPoints(
-        group, width, 0, bezier.controlPoints[1].x * width, (1 - bezier.controlPoints[1].y) * height);
-  }
-};
-
-InlineEditor.BezierUI.Height = 26;
diff --git a/front_end/inline_editor/CSSShadowEditor.js b/front_end/inline_editor/CSSShadowEditor.js
deleted file mode 100644
index ddaa9f8..0000000
--- a/front_end/inline_editor/CSSShadowEditor.js
+++ /dev/null
@@ -1,434 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-InlineEditor.CSSShadowEditor = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('inline_editor/cssShadowEditor.css');
-    this.contentElement.tabIndex = 0;
-    this.setDefaultFocusedElement(this.contentElement);
-
-    this._typeField = this.contentElement.createChild('div', 'shadow-editor-field shadow-editor-flex-field');
-    this._typeField.createChild('label', 'shadow-editor-label').textContent = Common.UIString('Type');
-    this._outsetButton = this._typeField.createChild('button', 'shadow-editor-button-left');
-    this._outsetButton.textContent = Common.UIString('Outset');
-    this._outsetButton.addEventListener('click', this._onButtonClick.bind(this), false);
-    this._insetButton = this._typeField.createChild('button', 'shadow-editor-button-right');
-    this._insetButton.textContent = Common.UIString('Inset');
-    this._insetButton.addEventListener('click', this._onButtonClick.bind(this), false);
-
-    const xField = this.contentElement.createChild('div', 'shadow-editor-field');
-    this._xInput = this._createTextInput(xField, Common.UIString('X offset'));
-    const yField = this.contentElement.createChild('div', 'shadow-editor-field');
-    this._yInput = this._createTextInput(yField, Common.UIString('Y offset'));
-    this._xySlider = xField.createChild('canvas', 'shadow-editor-2D-slider');
-    this._xySlider.width = InlineEditor.CSSShadowEditor.canvasSize;
-    this._xySlider.height = InlineEditor.CSSShadowEditor.canvasSize;
-    this._xySlider.tabIndex = -1;
-    this._halfCanvasSize = InlineEditor.CSSShadowEditor.canvasSize / 2;
-    this._innerCanvasSize = this._halfCanvasSize - InlineEditor.CSSShadowEditor.sliderThumbRadius;
-    UI.installDragHandle(this._xySlider, this._dragStart.bind(this), this._dragMove.bind(this), null, 'default');
-    this._xySlider.addEventListener('keydown', this._onCanvasArrowKey.bind(this), false);
-    this._xySlider.addEventListener('blur', this._onCanvasBlur.bind(this), false);
-
-    const blurField =
-        this.contentElement.createChild('div', 'shadow-editor-field shadow-editor-flex-field shadow-editor-blur-field');
-    this._blurInput = this._createTextInput(blurField, Common.UIString('Blur'));
-    this._blurSlider = this._createSlider(blurField);
-
-    this._spreadField = this.contentElement.createChild('div', 'shadow-editor-field shadow-editor-flex-field');
-    this._spreadInput = this._createTextInput(this._spreadField, Common.UIString('Spread'));
-    this._spreadSlider = this._createSlider(this._spreadField);
-  }
-
-  /**
-   * @param {!Element} field
-   * @param {string} propertyName
-   * @return {!Element}
-   */
-  _createTextInput(field, propertyName) {
-    const label = field.createChild('label', 'shadow-editor-label');
-    label.textContent = propertyName;
-    label.setAttribute('for', propertyName);
-    const textInput = UI.createInput('shadow-editor-text-input', 'text');
-    field.appendChild(textInput);
-    textInput.id = propertyName;
-    textInput.addEventListener('keydown', this._handleValueModification.bind(this), false);
-    textInput.addEventListener('mousewheel', this._handleValueModification.bind(this), false);
-    textInput.addEventListener('input', this._onTextInput.bind(this), false);
-    textInput.addEventListener('blur', this._onTextBlur.bind(this), false);
-    return textInput;
-  }
-
-  /**
-   * @param {!Element} field
-   * @return {!Element}
-   */
-  _createSlider(field) {
-    const slider = UI.createSliderLabel(0, InlineEditor.CSSShadowEditor.maxRange, -1);
-    slider.addEventListener('input', this._onSliderInput.bind(this), false);
-    field.appendChild(slider);
-    return slider;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._updateUI();
-  }
-
-  /**
-   * @param {!InlineEditor.CSSShadowModel} model
-   */
-  setModel(model) {
-    this._model = model;
-    this._typeField.hidden = !model.isBoxShadow();
-    this._spreadField.hidden = !model.isBoxShadow();
-    this._updateUI();
-  }
-
-  _updateUI() {
-    this._updateButtons();
-    this._xInput.value = this._model.offsetX().asCSSText();
-    this._yInput.value = this._model.offsetY().asCSSText();
-    this._blurInput.value = this._model.blurRadius().asCSSText();
-    this._spreadInput.value = this._model.spreadRadius().asCSSText();
-    this._blurSlider.value = this._model.blurRadius().amount;
-    this._spreadSlider.value = this._model.spreadRadius().amount;
-    this._updateCanvas(false);
-  }
-
-  _updateButtons() {
-    this._insetButton.classList.toggle('enabled', this._model.inset());
-    this._outsetButton.classList.toggle('enabled', !this._model.inset());
-  }
-
-  /**
-   * @param {boolean} drawFocus
-   */
-  _updateCanvas(drawFocus) {
-    const context = this._xySlider.getContext('2d');
-    context.clearRect(0, 0, this._xySlider.width, this._xySlider.height);
-
-    // Draw dashed axes.
-    context.save();
-    context.setLineDash([1, 1]);
-    context.strokeStyle = 'rgba(210, 210, 210, 0.8)';
-    context.beginPath();
-    context.moveTo(this._halfCanvasSize, 0);
-    context.lineTo(this._halfCanvasSize, InlineEditor.CSSShadowEditor.canvasSize);
-    context.moveTo(0, this._halfCanvasSize);
-    context.lineTo(InlineEditor.CSSShadowEditor.canvasSize, this._halfCanvasSize);
-    context.stroke();
-    context.restore();
-
-    const thumbPoint = this._sliderThumbPosition();
-    // Draw 2D slider line.
-    context.save();
-    context.translate(this._halfCanvasSize, this._halfCanvasSize);
-    context.lineWidth = 2;
-    context.strokeStyle = 'rgba(130, 130, 130, 0.75)';
-    context.beginPath();
-    context.moveTo(0, 0);
-    context.lineTo(thumbPoint.x, thumbPoint.y);
-    context.stroke();
-    // Draw 2D slider thumb.
-    if (drawFocus) {
-      context.beginPath();
-      context.fillStyle = 'rgba(66, 133, 244, 0.4)';
-      context.arc(thumbPoint.x, thumbPoint.y, InlineEditor.CSSShadowEditor.sliderThumbRadius + 2, 0, 2 * Math.PI);
-      context.fill();
-    }
-    context.beginPath();
-    context.fillStyle = '#4285F4';
-    context.arc(thumbPoint.x, thumbPoint.y, InlineEditor.CSSShadowEditor.sliderThumbRadius, 0, 2 * Math.PI);
-    context.fill();
-    context.restore();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onButtonClick(event) {
-    const insetClicked = (event.currentTarget === this._insetButton);
-    if (insetClicked && this._model.inset() || !insetClicked && !this._model.inset())
-      return;
-    this._model.setInset(insetClicked);
-    this._updateButtons();
-    this.dispatchEventToListeners(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._model);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleValueModification(event) {
-    const modifiedValue = UI.createReplacementString(event.currentTarget.value, event, customNumberHandler);
-    if (!modifiedValue)
-      return;
-    const length = InlineEditor.CSSLength.parse(modifiedValue);
-    if (!length)
-      return;
-    if (event.currentTarget === this._blurInput && length.amount < 0)
-      length.amount = 0;
-    event.currentTarget.value = length.asCSSText();
-    event.currentTarget.selectionStart = 0;
-    event.currentTarget.selectionEnd = event.currentTarget.value.length;
-    this._onTextInput(event);
-    event.consume(true);
-
-    /**
-     * @param {string} prefix
-     * @param {number} number
-     * @param {string} suffix
-     * @return {string}
-     */
-    function customNumberHandler(prefix, number, suffix) {
-      if (!suffix.length)
-        suffix = InlineEditor.CSSShadowEditor.defaultUnit;
-      return prefix + number + suffix;
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onTextInput(event) {
-    this._changedElement = event.currentTarget;
-    this._changedElement.classList.remove('invalid');
-    const length = InlineEditor.CSSLength.parse(event.currentTarget.value);
-    if (!length || event.currentTarget === this._blurInput && length.amount < 0)
-      return;
-    if (event.currentTarget === this._xInput) {
-      this._model.setOffsetX(length);
-      this._updateCanvas(false);
-    } else if (event.currentTarget === this._yInput) {
-      this._model.setOffsetY(length);
-      this._updateCanvas(false);
-    } else if (event.currentTarget === this._blurInput) {
-      this._model.setBlurRadius(length);
-      this._blurSlider.value = length.amount;
-    } else if (event.currentTarget === this._spreadInput) {
-      this._model.setSpreadRadius(length);
-      this._spreadSlider.value = length.amount;
-    }
-    this.dispatchEventToListeners(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._model);
-  }
-
-  _onTextBlur() {
-    if (!this._changedElement)
-      return;
-    let length = !this._changedElement.value.trim() ? InlineEditor.CSSLength.zero() :
-                                                      InlineEditor.CSSLength.parse(this._changedElement.value);
-    if (!length)
-      length = InlineEditor.CSSLength.parse(this._changedElement.value + InlineEditor.CSSShadowEditor.defaultUnit);
-    if (!length) {
-      this._changedElement.classList.add('invalid');
-      this._changedElement = null;
-      return;
-    }
-    if (this._changedElement === this._xInput) {
-      this._model.setOffsetX(length);
-      this._xInput.value = length.asCSSText();
-      this._updateCanvas(false);
-    } else if (this._changedElement === this._yInput) {
-      this._model.setOffsetY(length);
-      this._yInput.value = length.asCSSText();
-      this._updateCanvas(false);
-    } else if (this._changedElement === this._blurInput) {
-      if (length.amount < 0)
-        length = InlineEditor.CSSLength.zero();
-      this._model.setBlurRadius(length);
-      this._blurInput.value = length.asCSSText();
-      this._blurSlider.value = length.amount;
-    } else if (this._changedElement === this._spreadInput) {
-      this._model.setSpreadRadius(length);
-      this._spreadInput.value = length.asCSSText();
-      this._spreadSlider.value = length.amount;
-    }
-    this._changedElement = null;
-    this.dispatchEventToListeners(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._model);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onSliderInput(event) {
-    if (event.currentTarget === this._blurSlider) {
-      this._model.setBlurRadius(new InlineEditor.CSSLength(
-          this._blurSlider.value, this._model.blurRadius().unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      this._blurInput.value = this._model.blurRadius().asCSSText();
-      this._blurInput.classList.remove('invalid');
-    } else if (event.currentTarget === this._spreadSlider) {
-      this._model.setSpreadRadius(new InlineEditor.CSSLength(
-          this._spreadSlider.value, this._model.spreadRadius().unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      this._spreadInput.value = this._model.spreadRadius().asCSSText();
-      this._spreadInput.classList.remove('invalid');
-    }
-    this.dispatchEventToListeners(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._model);
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _dragStart(event) {
-    this._xySlider.focus();
-    this._updateCanvas(true);
-    this._canvasOrigin = new UI.Geometry.Point(
-        this._xySlider.totalOffsetLeft() + this._halfCanvasSize,
-        this._xySlider.totalOffsetTop() + this._halfCanvasSize);
-    const clickedPoint = new UI.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
-    const thumbPoint = this._sliderThumbPosition();
-    if (clickedPoint.distanceTo(thumbPoint) >= InlineEditor.CSSShadowEditor.sliderThumbRadius)
-      this._dragMove(event);
-    return true;
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _dragMove(event) {
-    let point = new UI.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
-    if (event.shiftKey)
-      point = this._snapToClosestDirection(point);
-    const constrainedPoint = this._constrainPoint(point, this._innerCanvasSize);
-    const newX = Math.round((constrainedPoint.x / this._innerCanvasSize) * InlineEditor.CSSShadowEditor.maxRange);
-    const newY = Math.round((constrainedPoint.y / this._innerCanvasSize) * InlineEditor.CSSShadowEditor.maxRange);
-
-    if (event.shiftKey) {
-      this._model.setOffsetX(
-          new InlineEditor.CSSLength(newX, this._model.offsetX().unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      this._model.setOffsetY(
-          new InlineEditor.CSSLength(newY, this._model.offsetY().unit || InlineEditor.CSSShadowEditor.defaultUnit));
-    } else {
-      if (!event.altKey) {
-        this._model.setOffsetX(
-            new InlineEditor.CSSLength(newX, this._model.offsetX().unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      }
-      if (!UI.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
-        this._model.setOffsetY(
-            new InlineEditor.CSSLength(newY, this._model.offsetY().unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      }
-    }
-    this._xInput.value = this._model.offsetX().asCSSText();
-    this._yInput.value = this._model.offsetY().asCSSText();
-    this._xInput.classList.remove('invalid');
-    this._yInput.classList.remove('invalid');
-    this._updateCanvas(true);
-    this.dispatchEventToListeners(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._model);
-  }
-
-  _onCanvasBlur() {
-    this._updateCanvas(false);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onCanvasArrowKey(event) {
-    let shiftX = 0;
-    let shiftY = 0;
-    if (event.key === 'ArrowRight')
-      shiftX = 1;
-    else if (event.key === 'ArrowLeft')
-      shiftX = -1;
-    else if (event.key === 'ArrowUp')
-      shiftY = -1;
-    else if (event.key === 'ArrowDown')
-      shiftY = 1;
-
-    if (!shiftX && !shiftY)
-      return;
-    event.consume(true);
-
-    if (shiftX) {
-      const offsetX = this._model.offsetX();
-      const newAmount = Number.constrain(
-          offsetX.amount + shiftX, -InlineEditor.CSSShadowEditor.maxRange, InlineEditor.CSSShadowEditor.maxRange);
-      if (newAmount === offsetX.amount)
-        return;
-      this._model.setOffsetX(
-          new InlineEditor.CSSLength(newAmount, offsetX.unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      this._xInput.value = this._model.offsetX().asCSSText();
-      this._xInput.classList.remove('invalid');
-    }
-    if (shiftY) {
-      const offsetY = this._model.offsetY();
-      const newAmount = Number.constrain(
-          offsetY.amount + shiftY, -InlineEditor.CSSShadowEditor.maxRange, InlineEditor.CSSShadowEditor.maxRange);
-      if (newAmount === offsetY.amount)
-        return;
-      this._model.setOffsetY(
-          new InlineEditor.CSSLength(newAmount, offsetY.unit || InlineEditor.CSSShadowEditor.defaultUnit));
-      this._yInput.value = this._model.offsetY().asCSSText();
-      this._yInput.classList.remove('invalid');
-    }
-    this._updateCanvas(true);
-    this.dispatchEventToListeners(InlineEditor.CSSShadowEditor.Events.ShadowChanged, this._model);
-  }
-
-  /**
-   * @param {!UI.Geometry.Point} point
-   * @param {number} max
-   * @return {!UI.Geometry.Point}
-   */
-  _constrainPoint(point, max) {
-    if (Math.abs(point.x) <= max && Math.abs(point.y) <= max)
-      return new UI.Geometry.Point(point.x, point.y);
-    return point.scale(max / Math.max(Math.abs(point.x), Math.abs(point.y)));
-  }
-
-  /**
-   * @param {!UI.Geometry.Point} point
-   * @return {!UI.Geometry.Point}
-   */
-  _snapToClosestDirection(point) {
-    let minDistance = Number.MAX_VALUE;
-    let closestPoint = point;
-
-    const directions = [
-      new UI.Geometry.Point(0, -1),  // North
-      new UI.Geometry.Point(1, -1),  // Northeast
-      new UI.Geometry.Point(1, 0),   // East
-      new UI.Geometry.Point(1, 1)    // Southeast
-    ];
-
-    for (const direction of directions) {
-      const projection = point.projectOn(direction);
-      const distance = point.distanceTo(projection);
-      if (distance < minDistance) {
-        minDistance = distance;
-        closestPoint = projection;
-      }
-    }
-
-    return closestPoint;
-  }
-
-  /**
-   * @return {!UI.Geometry.Point}
-   */
-  _sliderThumbPosition() {
-    const x = (this._model.offsetX().amount / InlineEditor.CSSShadowEditor.maxRange) * this._innerCanvasSize;
-    const y = (this._model.offsetY().amount / InlineEditor.CSSShadowEditor.maxRange) * this._innerCanvasSize;
-    return this._constrainPoint(new UI.Geometry.Point(x, y), this._innerCanvasSize);
-  }
-};
-
-/** @enum {symbol} */
-InlineEditor.CSSShadowEditor.Events = {
-  ShadowChanged: Symbol('ShadowChanged')
-};
-
-/** @type {number} */
-InlineEditor.CSSShadowEditor.maxRange = 20;
-/** @type {string} */
-InlineEditor.CSSShadowEditor.defaultUnit = 'px';
-/** @type {number} */
-InlineEditor.CSSShadowEditor.sliderThumbRadius = 6;
-/** @type {number} */
-InlineEditor.CSSShadowEditor.canvasSize = 88;
diff --git a/front_end/inline_editor/CSSShadowModel.js b/front_end/inline_editor/CSSShadowModel.js
deleted file mode 100644
index bebe2d1..0000000
--- a/front_end/inline_editor/CSSShadowModel.js
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-InlineEditor.CSSShadowModel = class {
-  /**
-   * @param {boolean} isBoxShadow
-   */
-  constructor(isBoxShadow) {
-    this._isBoxShadow = isBoxShadow;
-    this._inset = false;
-    this._offsetX = InlineEditor.CSSLength.zero();
-    this._offsetY = InlineEditor.CSSLength.zero();
-    this._blurRadius = InlineEditor.CSSLength.zero();
-    this._spreadRadius = InlineEditor.CSSLength.zero();
-    this._color = /** @type {!Common.Color} */ (Common.Color.parse('black'));
-    this._format = [InlineEditor.CSSShadowModel._Part.OffsetX, InlineEditor.CSSShadowModel._Part.OffsetY];
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Array<!InlineEditor.CSSShadowModel>}
-   */
-  static parseTextShadow(text) {
-    return InlineEditor.CSSShadowModel._parseShadow(text, false);
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Array<!InlineEditor.CSSShadowModel>}
-   */
-  static parseBoxShadow(text) {
-    return InlineEditor.CSSShadowModel._parseShadow(text, true);
-  }
-
-  /**
-   * @param {string} text
-   * @param {boolean} isBoxShadow
-   * @return {!Array<!InlineEditor.CSSShadowModel>}
-   */
-  static _parseShadow(text, isBoxShadow) {
-    const shadowTexts = [];
-    // Split by commas that aren't inside of color values to get the individual shadow values.
-    const splits = TextUtils.TextUtils.splitStringByRegexes(text, [Common.Color.Regex, /,/g]);
-    let currentIndex = 0;
-    for (let i = 0; i < splits.length; i++) {
-      if (splits[i].regexIndex === 1) {
-        const comma = splits[i];
-        shadowTexts.push(text.substring(currentIndex, comma.position));
-        currentIndex = comma.position + 1;
-      }
-    }
-    shadowTexts.push(text.substring(currentIndex, text.length));
-
-    const shadows = [];
-    for (let i = 0; i < shadowTexts.length; i++) {
-      const shadow = new InlineEditor.CSSShadowModel(isBoxShadow);
-      shadow._format = [];
-      let nextPartAllowed = true;
-      const regexes = [/inset/gi, Common.Color.Regex, InlineEditor.CSSLength.Regex];
-      const results = TextUtils.TextUtils.splitStringByRegexes(shadowTexts[i], regexes);
-      for (let j = 0; j < results.length; j++) {
-        const result = results[j];
-        if (result.regexIndex === -1) {
-          // Don't allow anything other than inset, color, length values, and whitespace.
-          if (/\S/.test(result.value))
-            return [];
-          // All parts must be separated by whitespace.
-          nextPartAllowed = true;
-        } else {
-          if (!nextPartAllowed)
-            return [];
-          nextPartAllowed = false;
-
-          if (result.regexIndex === 0) {
-            shadow._inset = true;
-            shadow._format.push(InlineEditor.CSSShadowModel._Part.Inset);
-          } else if (result.regexIndex === 1) {
-            const color = Common.Color.parse(result.value);
-            if (!color)
-              return [];
-            shadow._color = color;
-            shadow._format.push(InlineEditor.CSSShadowModel._Part.Color);
-          } else if (result.regexIndex === 2) {
-            const length = InlineEditor.CSSLength.parse(result.value);
-            if (!length)
-              return [];
-            const previousPart = shadow._format.length > 0 ? shadow._format[shadow._format.length - 1] : '';
-            if (previousPart === InlineEditor.CSSShadowModel._Part.OffsetX) {
-              shadow._offsetY = length;
-              shadow._format.push(InlineEditor.CSSShadowModel._Part.OffsetY);
-            } else if (previousPart === InlineEditor.CSSShadowModel._Part.OffsetY) {
-              shadow._blurRadius = length;
-              shadow._format.push(InlineEditor.CSSShadowModel._Part.BlurRadius);
-            } else if (previousPart === InlineEditor.CSSShadowModel._Part.BlurRadius) {
-              shadow._spreadRadius = length;
-              shadow._format.push(InlineEditor.CSSShadowModel._Part.SpreadRadius);
-            } else {
-              shadow._offsetX = length;
-              shadow._format.push(InlineEditor.CSSShadowModel._Part.OffsetX);
-            }
-          }
-        }
-      }
-      if (invalidCount(shadow, InlineEditor.CSSShadowModel._Part.OffsetX, 1, 1) ||
-          invalidCount(shadow, InlineEditor.CSSShadowModel._Part.OffsetY, 1, 1) ||
-          invalidCount(shadow, InlineEditor.CSSShadowModel._Part.Color, 0, 1) ||
-          invalidCount(shadow, InlineEditor.CSSShadowModel._Part.BlurRadius, 0, 1) ||
-          invalidCount(shadow, InlineEditor.CSSShadowModel._Part.Inset, 0, isBoxShadow ? 1 : 0) ||
-          invalidCount(shadow, InlineEditor.CSSShadowModel._Part.SpreadRadius, 0, isBoxShadow ? 1 : 0))
-        return [];
-      shadows.push(shadow);
-    }
-    return shadows;
-
-    /**
-     * @param {!InlineEditor.CSSShadowModel} shadow
-     * @param {string} part
-     * @param {number} min
-     * @param {number} max
-     * @return {boolean}
-     */
-    function invalidCount(shadow, part, min, max) {
-      let count = 0;
-      for (let i = 0; i < shadow._format.length; i++) {
-        if (shadow._format[i] === part)
-          count++;
-      }
-      return count < min || count > max;
-    }
-  }
-
-  /**
-   * @param {boolean} inset
-   */
-  setInset(inset) {
-    this._inset = inset;
-    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.Inset) === -1)
-      this._format.unshift(InlineEditor.CSSShadowModel._Part.Inset);
-  }
-
-  /**
-   * @param {!InlineEditor.CSSLength} offsetX
-   */
-  setOffsetX(offsetX) {
-    this._offsetX = offsetX;
-  }
-
-  /**
-   * @param {!InlineEditor.CSSLength} offsetY
-   */
-  setOffsetY(offsetY) {
-    this._offsetY = offsetY;
-  }
-
-  /**
-   * @param {!InlineEditor.CSSLength} blurRadius
-   */
-  setBlurRadius(blurRadius) {
-    this._blurRadius = blurRadius;
-    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.BlurRadius) === -1) {
-      const yIndex = this._format.indexOf(InlineEditor.CSSShadowModel._Part.OffsetY);
-      this._format.splice(yIndex + 1, 0, InlineEditor.CSSShadowModel._Part.BlurRadius);
-    }
-  }
-
-  /**
-   * @param {!InlineEditor.CSSLength} spreadRadius
-   */
-  setSpreadRadius(spreadRadius) {
-    this._spreadRadius = spreadRadius;
-    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.SpreadRadius) === -1) {
-      this.setBlurRadius(this._blurRadius);
-      const blurIndex = this._format.indexOf(InlineEditor.CSSShadowModel._Part.BlurRadius);
-      this._format.splice(blurIndex + 1, 0, InlineEditor.CSSShadowModel._Part.SpreadRadius);
-    }
-  }
-
-  /**
-   * @param {!Common.Color} color
-   */
-  setColor(color) {
-    this._color = color;
-    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.Color) === -1)
-      this._format.push(InlineEditor.CSSShadowModel._Part.Color);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isBoxShadow() {
-    return this._isBoxShadow;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  inset() {
-    return this._inset;
-  }
-
-  /**
-   * @return {!InlineEditor.CSSLength}
-   */
-  offsetX() {
-    return this._offsetX;
-  }
-
-  /**
-   * @return {!InlineEditor.CSSLength}
-   */
-  offsetY() {
-    return this._offsetY;
-  }
-
-  /**
-   * @return {!InlineEditor.CSSLength}
-   */
-  blurRadius() {
-    return this._blurRadius;
-  }
-
-  /**
-   * @return {!InlineEditor.CSSLength}
-   */
-  spreadRadius() {
-    return this._spreadRadius;
-  }
-
-  /**
-   * @return {!Common.Color}
-   */
-  color() {
-    return this._color;
-  }
-
-  /**
-   * @return {string}
-   */
-  asCSSText() {
-    const parts = [];
-    for (let i = 0; i < this._format.length; i++) {
-      const part = this._format[i];
-      if (part === InlineEditor.CSSShadowModel._Part.Inset && this._inset)
-        parts.push('inset');
-      else if (part === InlineEditor.CSSShadowModel._Part.OffsetX)
-        parts.push(this._offsetX.asCSSText());
-      else if (part === InlineEditor.CSSShadowModel._Part.OffsetY)
-        parts.push(this._offsetY.asCSSText());
-      else if (part === InlineEditor.CSSShadowModel._Part.BlurRadius)
-        parts.push(this._blurRadius.asCSSText());
-      else if (part === InlineEditor.CSSShadowModel._Part.SpreadRadius)
-        parts.push(this._spreadRadius.asCSSText());
-      else if (part === InlineEditor.CSSShadowModel._Part.Color)
-        parts.push(this._color.asString(this._color.format()));
-    }
-    return parts.join(' ');
-  }
-};
-
-/**
- * @enum {string}
- */
-InlineEditor.CSSShadowModel._Part = {
-  Inset: 'I',
-  OffsetX: 'X',
-  OffsetY: 'Y',
-  BlurRadius: 'B',
-  SpreadRadius: 'S',
-  Color: 'C'
-};
-
-
-/**
- * @unrestricted
- */
-InlineEditor.CSSLength = class {
-  /**
-   * @param {number} amount
-   * @param {string} unit
-   */
-  constructor(amount, unit) {
-    this.amount = amount;
-    this.unit = unit;
-  }
-
-  /**
-   * @param {string} text
-   * @return {?InlineEditor.CSSLength}
-   */
-  static parse(text) {
-    const lengthRegex = new RegExp('^(?:' + InlineEditor.CSSLength.Regex.source + ')$', 'i');
-    const match = text.match(lengthRegex);
-    if (!match)
-      return null;
-    if (match.length > 2 && match[2])
-      return new InlineEditor.CSSLength(parseFloat(match[1]), match[2]);
-    return InlineEditor.CSSLength.zero();
-  }
-
-  /**
-   * @return {!InlineEditor.CSSLength}
-   */
-  static zero() {
-    return new InlineEditor.CSSLength(0, '');
-  }
-
-  /**
-   * @return {string}
-   */
-  asCSSText() {
-    return this.amount + this.unit;
-  }
-};
-
-/** @type {!RegExp} */
-InlineEditor.CSSLength.Regex = (function() {
-  const number = '([+-]?(?:[0-9]*[.])?[0-9]+(?:[eE][+-]?[0-9]+)?)';
-  const unit = '(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)';
-  const zero = '[+-]?(?:0*[.])?0+(?:[eE][+-]?[0-9]+)?';
-  return new RegExp(number + unit + '|' + zero, 'gi');
-})();
diff --git a/front_end/inline_editor/ColorSwatch.js b/front_end/inline_editor/ColorSwatch.js
deleted file mode 100644
index 8a5a866..0000000
--- a/front_end/inline_editor/ColorSwatch.js
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-InlineEditor.ColorSwatch = class extends HTMLSpanElement {
-  constructor() {
-    super();
-  }
-
-  /**
-   * @return {!InlineEditor.ColorSwatch}
-   */
-  static create() {
-    if (!InlineEditor.ColorSwatch._constructor) {
-      InlineEditor.ColorSwatch._constructor =
-          UI.registerCustomElement('span', 'color-swatch', InlineEditor.ColorSwatch.prototype);
-    }
-
-    return /** @type {!InlineEditor.ColorSwatch} */ (new InlineEditor.ColorSwatch._constructor());
-  }
-
-  /**
-   * @param {!Common.Color} color
-   * @param {string} curFormat
-   */
-  static _nextColorFormat(color, curFormat) {
-    // The format loop is as follows:
-    // * original
-    // * rgb(a)
-    // * hsl(a)
-    // * nickname (if the color has a nickname)
-    // * shorthex (if has short hex)
-    // * hex
-    const cf = Common.Color.Format;
-
-    switch (curFormat) {
-      case cf.Original:
-        return !color.hasAlpha() ? cf.RGB : cf.RGBA;
-
-      case cf.RGB:
-      case cf.RGBA:
-        return !color.hasAlpha() ? cf.HSL : cf.HSLA;
-
-      case cf.HSL:
-      case cf.HSLA:
-        if (color.nickname())
-          return cf.Nickname;
-        return color.detectHEXFormat();
-
-      case cf.ShortHEX:
-        return cf.HEX;
-
-      case cf.ShortHEXA:
-        return cf.HEXA;
-
-      case cf.HEXA:
-      case cf.HEX:
-        return cf.Original;
-
-      case cf.Nickname:
-        return color.detectHEXFormat();
-
-      default:
-        return cf.RGBA;
-    }
-  }
-
-  /**
-   * @return {!Common.Color} color
-   */
-  color() {
-    return this._color;
-  }
-
-  /**
-   * @param {!Common.Color} color
-   */
-  setColor(color) {
-    this._color = color;
-    this._format = this._color.format();
-    const colorString = /** @type {string} */ (this._color.asString(this._format));
-    this.setText(colorString);
-    this._swatchInner.style.backgroundColor = colorString;
-  }
-
-  /**
-   * @param {boolean} hide
-   */
-  hideText(hide) {
-    this._colorValueElement.hidden = hide;
-  }
-
-  /**
-   * @param {string} text
-   * @param {string=} tooltip
-   */
-  setText(text, tooltip) {
-    this._colorValueElement.textContent = text;
-    this._colorValueElement.title = tooltip;
-  }
-
-  /**
-   * @return {!Common.Color.Format}
-   */
-  format() {
-    return this._format;
-  }
-
-  /**
-   * @param {!Common.Color.Format} format
-   */
-  setFormat(format) {
-    this._format = format;
-    this.setText(this._color.asString(this._format));
-  }
-
-  toggleNextFormat() {
-    let currentValue;
-    do {
-      this._format = InlineEditor.ColorSwatch._nextColorFormat(this._color, this._format);
-      currentValue = this._color.asString(this._format);
-    } while (currentValue === this._colorValueElement.textContent);
-    this.setText(currentValue);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  iconElement() {
-    return this._iconElement;
-  }
-
-  /**
-   * @override
-   */
-  createdCallback() {
-    const root = UI.createShadowRootWithCoreStyles(this, 'inline_editor/colorSwatch.css');
-
-    this._iconElement = root.createChild('span', 'color-swatch');
-    this._iconElement.title = Common.UIString('Shift-click to change color format');
-    this._swatchInner = this._iconElement.createChild('span', 'color-swatch-inner');
-    this._swatchInner.addEventListener('dblclick', e => e.consume(), false);
-    this._swatchInner.addEventListener('mousedown', e => e.consume(), false);
-    this._swatchInner.addEventListener('click', this._handleClick.bind(this), true);
-
-    root.createChild('content');
-    this._colorValueElement = this.createChild('span');
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleClick(event) {
-    if (!event.shiftKey)
-      return;
-    event.target.parentNode.parentNode.host.toggleNextFormat();
-    event.consume(true);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-InlineEditor.BezierSwatch = class extends HTMLSpanElement {
-  constructor() {
-    super();
-  }
-
-  /**
-   * @return {!InlineEditor.BezierSwatch}
-   */
-  static create() {
-    if (!InlineEditor.BezierSwatch._constructor) {
-      InlineEditor.BezierSwatch._constructor =
-          UI.registerCustomElement('span', 'bezier-swatch', InlineEditor.BezierSwatch.prototype);
-    }
-
-    return /** @type {!InlineEditor.BezierSwatch} */ (new InlineEditor.BezierSwatch._constructor());
-  }
-
-  /**
-   * @return {string}
-   */
-  bezierText() {
-    return this._textElement.textContent;
-  }
-
-  /**
-   * @param {string} text
-   */
-  setBezierText(text) {
-    this._textElement.textContent = text;
-  }
-
-  /**
-   * @param {boolean} hide
-   */
-  hideText(hide) {
-    this._textElement.hidden = hide;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  iconElement() {
-    return this._iconElement;
-  }
-
-  /**
-   * @override
-   */
-  createdCallback() {
-    const root = UI.createShadowRootWithCoreStyles(this, 'inline_editor/bezierSwatch.css');
-    this._iconElement = UI.Icon.create('smallicon-bezier', 'bezier-swatch-icon');
-    root.appendChild(this._iconElement);
-    this._textElement = this.createChild('span');
-    root.createChild('content');
-  }
-};
-
-
-/**
- * @unrestricted
- */
-InlineEditor.CSSShadowSwatch = class extends HTMLSpanElement {
-  constructor() {
-    super();
-  }
-
-  /**
-   * @return {!InlineEditor.CSSShadowSwatch}
-   */
-  static create() {
-    if (!InlineEditor.CSSShadowSwatch._constructor) {
-      InlineEditor.CSSShadowSwatch._constructor =
-          UI.registerCustomElement('span', 'css-shadow-swatch', InlineEditor.CSSShadowSwatch.prototype);
-    }
-
-    return /** @type {!InlineEditor.CSSShadowSwatch} */ (new InlineEditor.CSSShadowSwatch._constructor());
-  }
-
-  /**
-   * @return {!InlineEditor.CSSShadowModel} cssShadowModel
-   */
-  model() {
-    return this._model;
-  }
-
-  /**
-   * @param {!InlineEditor.CSSShadowModel} model
-   */
-  setCSSShadow(model) {
-    this._model = model;
-    this._contentElement.removeChildren();
-    const results = TextUtils.TextUtils.splitStringByRegexes(model.asCSSText(), [/inset/g, Common.Color.Regex]);
-    for (let i = 0; i < results.length; i++) {
-      const result = results[i];
-      if (result.regexIndex === 1) {
-        if (!this._colorSwatch)
-          this._colorSwatch = InlineEditor.ColorSwatch.create();
-        this._colorSwatch.setColor(model.color());
-        this._contentElement.appendChild(this._colorSwatch);
-      } else {
-        this._contentElement.appendChild(createTextNode(result.value));
-      }
-    }
-  }
-
-  /**
-   * @param {boolean} hide
-   */
-  hideText(hide) {
-    this._contentElement.hidden = hide;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  iconElement() {
-    return this._iconElement;
-  }
-
-  /**
-   * @return {?InlineEditor.ColorSwatch}
-   */
-  colorSwatch() {
-    return this._colorSwatch;
-  }
-
-  /**
-   * @override
-   */
-  createdCallback() {
-    const root = UI.createShadowRootWithCoreStyles(this, 'inline_editor/cssShadowSwatch.css');
-    this._iconElement = UI.Icon.create('smallicon-shadow', 'shadow-swatch-icon');
-    root.appendChild(this._iconElement);
-    root.createChild('content');
-    this._contentElement = this.createChild('span');
-  }
-};
diff --git a/front_end/inline_editor/SwatchPopoverHelper.js b/front_end/inline_editor/SwatchPopoverHelper.js
deleted file mode 100644
index 6884864..0000000
--- a/front_end/inline_editor/SwatchPopoverHelper.js
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-InlineEditor.SwatchPopoverHelper = class extends Common.Object {
-  constructor() {
-    super();
-    this._popover = new UI.GlassPane();
-    this._popover.registerRequiredCSS('inline_editor/swatchPopover.css');
-    this._popover.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    this._popover.setMarginBehavior(UI.GlassPane.MarginBehavior.Arrow);
-    this._popover.element.addEventListener('mousedown', e => e.consume(), false);
-
-    this._hideProxy = this.hide.bind(this, true);
-    this._boundOnKeyDown = this._onKeyDown.bind(this);
-    this._boundFocusOut = this._onFocusOut.bind(this);
-    this._isHidden = true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onFocusOut(event) {
-    if (!event.relatedTarget || event.relatedTarget.isSelfOrDescendant(this._view.contentElement))
-      return;
-    this._hideProxy();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShowing() {
-    return this._popover.isShowing();
-  }
-
-  /**
-   * @param {!UI.Widget} view
-   * @param {!Element} anchorElement
-   * @param {function(boolean)=} hiddenCallback
-   */
-  show(view, anchorElement, hiddenCallback) {
-    if (this._popover.isShowing()) {
-      if (this._anchorElement === anchorElement)
-        return;
-
-      // Reopen the picker for another anchor element.
-      this.hide(true);
-    }
-
-    delete this._isHidden;
-    this._anchorElement = anchorElement;
-    this._view = view;
-    this._hiddenCallback = hiddenCallback;
-    this.reposition();
-    view.focus();
-
-    const document = this._popover.element.ownerDocument;
-    document.addEventListener('mousedown', this._hideProxy, false);
-    document.defaultView.addEventListener('resize', this._hideProxy, false);
-    this._view.contentElement.addEventListener('keydown', this._boundOnKeyDown, false);
-  }
-
-  reposition() {
-    // Unbind "blur" listener to avoid reenterability: |popover.show()| will hide the popover and trigger it synchronously.
-    this._view.contentElement.removeEventListener('focusout', this._boundFocusOut, false);
-    this._view.show(this._popover.contentElement);
-    this._popover.setContentAnchorBox(this._anchorElement.boxInWindow());
-    this._popover.show(this._anchorElement.ownerDocument);
-    this._view.contentElement.addEventListener('focusout', this._boundFocusOut, false);
-    if (!this._focusRestorer)
-      this._focusRestorer = new UI.WidgetFocusRestorer(this._view);
-  }
-
-  /**
-   * @param {boolean=} commitEdit
-   */
-  hide(commitEdit) {
-    if (this._isHidden)
-      return;
-    const document = this._popover.element.ownerDocument;
-    this._isHidden = true;
-    this._popover.hide();
-
-    document.removeEventListener('mousedown', this._hideProxy, false);
-    document.defaultView.removeEventListener('resize', this._hideProxy, false);
-
-    if (this._hiddenCallback)
-      this._hiddenCallback.call(null, !!commitEdit);
-
-    this._focusRestorer.restore();
-    delete this._anchorElement;
-    if (this._view) {
-      this._view.detach();
-      this._view.contentElement.removeEventListener('keydown', this._boundOnKeyDown, false);
-      this._view.contentElement.removeEventListener('focusout', this._boundFocusOut, false);
-      delete this._view;
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (event.key === 'Enter') {
-      this.hide(true);
-      event.consume(true);
-      return;
-    }
-    if (event.key === 'Escape') {
-      this.hide(false);
-      event.consume(true);
-    }
-  }
-};
diff --git a/front_end/inline_editor/bezierEditor.css b/front_end/inline_editor/bezierEditor.css
deleted file mode 100644
index aaa472a..0000000
--- a/front_end/inline_editor/bezierEditor.css
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    width: 270px;
-    height: 350px;
-    -webkit-user-select: none;
-    padding: 16px;
-    overflow: hidden;
-}
-
-.bezier-preset-selected > svg {
-    background-color: var(--selection-bg-color);
-}
-
-.bezier-preset-label {
-    font-size: 10px;
-}
-
-.bezier-preset {
-    width: 50px;
-    height: 50px;
-    padding: 5px;
-    margin: auto;
-    background-color: #f5f5f5;
-    border-radius: 3px;
-}
-
-.bezier-preset line.bezier-control-line {
-    stroke: #666;
-    stroke-width: 1;
-    stroke-linecap: round;
-    fill: none;
-}
-
-.bezier-preset circle.bezier-control-circle {
-    fill: #666;
-}
-
-.bezier-preset path.bezier-path {
-    stroke: black;
-    stroke-width: 2;
-    stroke-linecap: round;
-    fill: none;
-}
-
-.bezier-preset-selected path.bezier-path, .bezier-preset-selected line.bezier-control-line {
-    stroke: white;
-}
-
-.bezier-preset-selected circle.bezier-control-circle {
-    fill: white;
-}
-
-.bezier-curve line.linear-line {
-    stroke: #eee;
-    stroke-width: 2;
-    stroke-linecap: round;
-    fill: none;
-}
-
-.bezier-curve line.bezier-control-line {
-    stroke: #9C27B0;
-    stroke-width: 2;
-    stroke-linecap: round;
-    fill: none;
-    opacity: 0.6;
-}
-
-.bezier-curve circle.bezier-control-circle {
-    fill: #9C27B0;
-    cursor: pointer;
-}
-
-.bezier-curve path.bezier-path {
-    stroke: black;
-    stroke-width: 3;
-    stroke-linecap: round;
-    fill: none;
-}
-
-.bezier-preview-container {
-    position: relative;
-    background-color: white;
-    overflow: hidden;
-    border-radius: 20px;
-    width: 200%;
-    height: 20px;
-    z-index: 2;
-    flex-shrink: 0;
-    opacity: 0;
-}
-
-.bezier-preview-animation {
-    background-color: #9C27B0;
-    width: 20px;
-    height: 20px;
-    border-radius: 20px;
-    position: absolute;
-}
-
-.bezier-preview-onion {
-    margin-top: -20px;
-    position: relative;
-    z-index: 1;
-}
-
-.bezier-preview-onion > .bezier-preview-animation {
-    opacity: 0.1;
-}
-
-svg.bezier-preset-modify {
-    background-color: #f5f5f5;
-    border-radius: 35px;
-    display: inline-block;
-    visibility: hidden;
-    transition: transform 100ms cubic-bezier(0.4, 0, 0.2, 1);
-    cursor: pointer;
-    position: absolute;
-}
-
-svg.bezier-preset-modify:hover, .bezier-preset:hover {
-    background-color: #999;
-}
-
-.bezier-preset-selected .bezier-preset:hover {
-    background-color: var(--selection-bg-color);
-}
-
-.bezier-preset-modify path {
-    stroke-width: 2;
-    stroke: black;
-    fill: none;
-}
-
-.bezier-preset-selected .bezier-preset-modify {
-    opacity: 1;
-}
-
-.bezier-preset-category {
-    width: 50px;
-    margin: 20px 0;
-    cursor: pointer;
-    transition: transform 100ms cubic-bezier(0.4, 0, 0.2, 1);
-}
-
-span.bezier-display-value {
-    width: 100%;
-    -webkit-user-select: text;
-    display: block;
-    text-align: center;
-    line-height: 20px;
-    height: 20px;
-    cursor: text;
-    white-space: nowrap !important;
-}
-
-.bezier-container {
-    display: flex;
-    margin-top: 38px;
-}
-
-svg.bezier-curve {
-    margin-left: 32px;
-    margin-top: -8px;
-}
-
-svg.bezier-preset-modify.bezier-preset-plus {
-    right: 0;
-}
-
-.bezier-header {
-    margin-top: 16px;
-}
-
-svg.bezier-preset-modify:active,
-.-theme-selection-color {
-    transform: scale(1.1);
-    background-color: var(--selection-bg-color);
-}
-
-.bezier-preset-category:active {
-    transform: scale(1.05);
-}
-
-.bezier-header-active > svg.bezier-preset-modify {
-    visibility: visible;
-}
-
-.bezier-preset-modify:active path {
-    stroke: white;
-}
diff --git a/front_end/inline_editor/bezierSwatch.css b/front_end/inline_editor/bezierSwatch.css
deleted file mode 100644
index dbe25d9..0000000
--- a/front_end/inline_editor/bezierSwatch.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    white-space: nowrap;
-}
-
-.bezier-swatch-icon {
-    position: relative;
-    margin-left: 1px;
-    margin-right: 2px;
-    top: 1px;
-    -webkit-user-select: none;
-    line-height: 10px;
-    background-color: #9C27B0;
-    cursor: default;
-}
-
-.bezier-swatch-icon:hover {
-    background-color: #800080;
-}
diff --git a/front_end/inline_editor/colorSwatch.css b/front_end/inline_editor/colorSwatch.css
deleted file mode 100644
index 9f04d73..0000000
--- a/front_end/inline_editor/colorSwatch.css
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    white-space: nowrap;
-}
-
-.color-swatch {
-    position: relative;
-    margin-left: 1px;
-    margin-right: 2px;
-    width: 10px;
-    height: 10px;
-    top: 1px;
-    display: inline-block;
-    -webkit-user-select: none;
-    background-image: url(Images/checker.png);
-    line-height: 10px;
-}
-
-.color-swatch-inner {
-    width: 100%;
-    height: 100%;
-    display: inline-block;
-    border: 1px solid rgba(128, 128, 128, 0.6);
-    cursor: default;
-}
-
-.color-swatch-inner:hover {
-    border: 1px solid rgba(64, 64, 64, 0.8);
-}
-
diff --git a/front_end/inline_editor/cssShadowEditor.css b/front_end/inline_editor/cssShadowEditor.css
deleted file mode 100644
index 1c849b8..0000000
--- a/front_end/inline_editor/cssShadowEditor.css
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    -webkit-user-select: none;
-    padding: 4px 12px 12px 12px;
-}
-
-.shadow-editor-field:last-of-type {
-    margin-bottom: 8px;
-}
-
-.shadow-editor-field {
-    height: 24px;
-    margin-top: 8px;
-    font-size: 12px;
-    flex-shrink: 0;
-}
-
-.shadow-editor-flex-field {
-    display: flex;
-    align-items: center;
-    flex-direction: row;
-}
-
-.shadow-editor-field.shadow-editor-blur-field {
-    margin-top: 40px;
-}
-
-.shadow-editor-2D-slider {
-    position: absolute;
-    height: 88px;
-    width: 88px;
-    border: 1px solid rgba(0, 0, 0, 0.14);
-    border-radius: 2px;
-}
-
-.shadow-editor-label {
-    display: inline-block;
-    width: 52px;
-    height: 24px;
-    line-height: 24px;
-    margin-right: 8px;
-    text-align: right;
-}
-
-.shadow-editor-button-left, .shadow-editor-button-right {
-    width: 74px;
-    height: 24px;
-    padding: 3px 7px;
-    line-height: 16px;
-    border: 1px solid rgba(0, 0, 0, 0.14);
-    background-color: #ffffff;
-    text-align: center;
-    font-weight: 500;
-}
-
-.shadow-editor-button-left {
-    border-radius: 2px 0 0 2px;
-}
-
-.shadow-editor-button-right {
-    border-radius: 0 2px 2px 0;
-    border-left-width: 0;
-}
-
-.shadow-editor-button-left:hover, .shadow-editor-button-right:hover {
-    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-}
-
-.shadow-editor-button-left:focus, .shadow-editor-button-right:focus {
-    background-color: #eeeeee;
-}
-
-.shadow-editor-button-left.enabled, .shadow-editor-button-right.enabled, -theme-preserve {
-    background-color: #4285F4;
-    color: #ffffff;
-}
-
-.shadow-editor-button-left.enabled:focus, .shadow-editor-button-right.enabled:focus, -theme-preserve  {
-    background-color: #3B78E7;
-}
-
-.shadow-editor-text-input {
-    width: 52px;
-    margin-right: 8px;
-    text-align: right;
-}
diff --git a/front_end/inline_editor/cssShadowSwatch.css b/front_end/inline_editor/cssShadowSwatch.css
deleted file mode 100644
index 4c68f60..0000000
--- a/front_end/inline_editor/cssShadowSwatch.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    white-space: nowrap;
-}
-
-.shadow-swatch-icon {
-    position: relative;
-    margin-left: 1px;
-    margin-right: 2px;
-    top: 1px;
-    -webkit-user-select: none;
-    line-height: 10px;
-    background-color: #9C27B0;
-}
-
-.shadow-swatch-icon:hover {
-    background-color: #800080;
-}
diff --git a/front_end/inline_editor/module.json b/front_end/inline_editor/module.json
deleted file mode 100644
index 00185f7..0000000
--- a/front_end/inline_editor/module.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    "dependencies": [
-        "ui"
-    ],
-    "scripts": [
-        "BezierEditor.js",
-        "BezierUI.js",
-        "ColorSwatch.js",
-        "CSSShadowEditor.js",
-        "SwatchPopoverHelper.js",
-        "CSSShadowModel.js"
-    ],
-    "resources": [
-        "bezierEditor.css",
-        "colorSwatch.css",
-        "bezierSwatch.css",
-        "cssShadowSwatch.css",
-        "cssShadowEditor.css",
-        "swatchPopover.css"
-    ]
-}
diff --git a/front_end/inline_editor/swatchPopover.css b/front_end/inline_editor/swatchPopover.css
deleted file mode 100644
index a5cc6b4..0000000
--- a/front_end/inline_editor/swatchPopover.css
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.widget {
-    display: flex;
-    background: white;
-    box-shadow: var(--drop-shadow);
-    border-radius: 2px;
-    overflow: auto;
-    -webkit-user-select: text;
-    line-height: 11px;
-}
diff --git a/front_end/inspector.html b/front_end/inspector.html
deleted file mode 100644
index 26ea659..0000000
--- a/front_end/inspector.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <meta name="referrer" content="no-referrer">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="inspector.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/inspector.js b/front_end/inspector.js
deleted file mode 100644
index c690b32..0000000
--- a/front_end/inspector.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Runtime.startApplication('inspector');
diff --git a/front_end/inspector.json b/front_end/inspector.json
deleted file mode 100644
index dc2149a..0000000
--- a/front_end/inspector.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "modules" : [
-    { "name": "screencast", "type": "autostart" }
-  ],
-  "extends": "devtools_app",
-  "has_html": true
-}
diff --git a/front_end/inspector_main/InspectorMain.js b/front_end/inspector_main/InspectorMain.js
deleted file mode 100644
index 3fe346c..0000000
--- a/front_end/inspector_main/InspectorMain.js
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.Runnable}
- */
-InspectorMain.InspectorMain = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!Protocol.InspectorBackend.Connection} */
-    this._mainConnection;
-  }
-
-  /**
-   * @override
-   */
-  run() {
-    this._connectAndCreateMainTarget();
-    InspectorFrontendHost.connectionReady();
-
-    new InspectorMain.InspectedNodeRevealer();
-    new InspectorMain.SourcesPanelIndicator();
-    new InspectorMain.BackendSettingsSync();
-    new MobileThrottling.NetworkPanelIndicator();
-
-    InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ReloadInspectedPage, event => {
-      const hard = /** @type {boolean} */ (event.data);
-      SDK.ResourceTreeModel.reloadAllPages(hard);
-    });
-  }
-
-  _connectAndCreateMainTarget() {
-    const target = SDK.targetManager.createTarget(
-        'main', Common.UIString('Main'), this._capabilitiesForMainTarget(), this._createMainConnection.bind(this),
-        null);
-    target.runtimeAgent().runIfWaitingForDebugger();
-  }
-
-  /**
-   * @return {number}
-   */
-  _capabilitiesForMainTarget() {
-    return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.DeviceEmulation |
-        SDK.Target.Capability.Emulation | SDK.Target.Capability.Input | SDK.Target.Capability.JS |
-        SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.ScreenCapture |
-        SDK.Target.Capability.Security | SDK.Target.Capability.Target | SDK.Target.Capability.Tracing;
-  }
-
-  /**
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   * @return {!Protocol.InspectorBackend.Connection}
-   */
-  _createMainConnection(params) {
-    this._mainConnection =
-        SDK.createMainConnection(params, () => Components.TargetDetachedDialog.webSocketConnectionLost());
-    return this._mainConnection;
-  }
-
-  /**
-   * @param {function(string)} onMessage
-   * @return {!Promise<!Protocol.InspectorBackend.Connection>}
-   */
-  _interceptMainConnection(onMessage) {
-    const params = {onMessage: onMessage, onDisconnect: this._connectAndCreateMainTarget.bind(this)};
-    return this._mainConnection.disconnect().then(this._createMainConnection.bind(this, params));
-  }
-};
-
-/**
- * @param {function(string)} onMessage
- * @return {!Promise<!Protocol.InspectorBackend.Connection>}
- */
-InspectorMain.interceptMainConnection = function(onMessage) {
-  return self.runtime.sharedInstance(InspectorMain.InspectorMain)._interceptMainConnection(onMessage);
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-InspectorMain.ReloadActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    switch (actionId) {
-      case 'inspector_main.reload':
-        SDK.ResourceTreeModel.reloadAllPages(false);
-        return true;
-      case 'inspector_main.hard-reload':
-        SDK.ResourceTreeModel.reloadAllPages(true);
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-InspectorMain.FocusDebuggeeActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    SDK.targetManager.mainTarget().pageAgent().bringToFront();
-    return true;
-  }
-};
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- */
-InspectorMain.NodeIndicator = class {
-  constructor() {
-    const element = createElement('div');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'inspector_main/nodeIcon.css');
-    this._element = shadowRoot.createChild('div', 'node-icon');
-    element.addEventListener('click', () => InspectorFrontendHost.openNodeFrontend(), false);
-    this._button = new UI.ToolbarItem(element);
-    this._button.setTitle(Common.UIString('Open dedicated DevTools for Node.js'));
-    SDK.targetManager.addEventListener(
-        SDK.TargetManager.Events.AvailableTargetsChanged,
-        event => this._update(/** @type {!Array<!Protocol.Target.TargetInfo>} */ (event.data)));
-    this._button.setVisible(false);
-    this._update([]);
-  }
-
-  /**
-   * @param {!Array<!Protocol.Target.TargetInfo>} targetInfos
-   */
-  _update(targetInfos) {
-    const hasNode = !!targetInfos.find(target => target.type === 'node' && !target.attached);
-    this._element.classList.toggle('inactive', !hasNode);
-    if (hasNode)
-      this._button.setVisible(true);
-  }
-
-  /**
-   * @override
-   * @return {?UI.ToolbarItem}
-   */
-  item() {
-    return this._button;
-  }
-};
-
-/**
- * @unrestricted
- */
-InspectorMain.SourcesPanelIndicator = class {
-  constructor() {
-    Common.moduleSetting('javaScriptDisabled').addChangeListener(javaScriptDisabledChanged);
-    javaScriptDisabledChanged();
-
-    function javaScriptDisabledChanged() {
-      let icon = null;
-      const javaScriptDisabled = Common.moduleSetting('javaScriptDisabled').get();
-      if (javaScriptDisabled) {
-        icon = UI.Icon.create('smallicon-warning');
-        icon.title = Common.UIString('JavaScript is disabled');
-      }
-      UI.inspectorView.setPanelIcon('sources', icon);
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-InspectorMain.InspectedNodeRevealer = class {
-  constructor() {
-    SDK.targetManager.addModelListener(
-        SDK.OverlayModel, SDK.OverlayModel.Events.InspectNodeRequested, this._inspectNode, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _inspectNode(event) {
-    const deferredNode = /** @type {!SDK.DeferredDOMNode} */ (event.data);
-    Common.Revealer.reveal(deferredNode);
-  }
-};
-
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-InspectorMain.BackendSettingsSync = class {
-  constructor() {
-    this._autoAttachSetting = Common.settings.moduleSetting('autoAttachToCreatedPages');
-    this._autoAttachSetting.addChangeListener(this._updateAutoAttach, this);
-    this._updateAutoAttach();
-
-    this._adBlockEnabledSetting = Common.settings.moduleSetting('network.adBlockingEnabled');
-    this._adBlockEnabledSetting.addChangeListener(this._update, this);
-
-    SDK.targetManager.observeTargets(this, SDK.Target.Capability.Browser);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  _updateTarget(target) {
-    if (!target.parentTarget())
-      target.pageAgent().setAdBlockingEnabled(this._adBlockEnabledSetting.get());
-  }
-
-  _updateAutoAttach() {
-    InspectorFrontendHost.setOpenNewWindowForPopups(this._autoAttachSetting.get());
-  }
-
-  _update() {
-    SDK.targetManager.targets(SDK.Target.Capability.Browser).forEach(this._updateTarget, this);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @override
-   */
-  targetAdded(target) {
-    this._updateTarget(target);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @override
-   */
-  targetRemoved(target) {
-  }
-};
-
-SDK.ChildTargetManager.install();
diff --git a/front_end/inspector_main/RenderingOptions.js b/front_end/inspector_main/RenderingOptions.js
deleted file mode 100644
index 5e7700f..0000000
--- a/front_end/inspector_main/RenderingOptions.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-InspectorMain.RenderingOptionsView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('inspector_main/renderingOptions.css');
-
-    this._appendCheckbox(
-        Common.UIString('Paint flashing'),
-        Common.UIString('Highlights areas of the page (green) that need to be repainted'),
-        Common.moduleSetting('showPaintRects'));
-    this._appendCheckbox(
-        Common.UIString('Layer borders'), Common.UIString('Shows layer borders (orange/olive) and tiles (cyan)'),
-        Common.moduleSetting('showDebugBorders'));
-    this._appendCheckbox(
-        Common.UIString('FPS meter'),
-        Common.UIString('Plots frames per second, frame rate distribution, and GPU memory'),
-        Common.moduleSetting('showFPSCounter'));
-    this._appendCheckbox(
-        Common.UIString('Scrolling performance issues'),
-        Common.UIString(
-            'Highlights elements (teal) that can slow down scrolling, including touch & wheel event handlers and other main-thread scrolling situations.'),
-        Common.moduleSetting('showScrollBottleneckRects'));
-    this.contentElement.createChild('div').classList.add('panel-section-separator');
-
-    const mediaSetting = Common.moduleSetting('emulatedCSSMedia');
-    const mediaSelect = UI.SettingsUI.createControlForSetting(mediaSetting);
-    if (mediaSelect) {
-      const mediaRow = this.contentElement.createChild('span', 'media-row');
-      mediaRow.createChild('label').textContent = Common.UIString('Emulate CSS media');
-      mediaRow.createChild('p').textContent = Common.UIString('Forces media type for testing print and screen styles');
-      mediaRow.appendChild(mediaSelect);
-    }
-  }
-
-  /**
-   * @param {string} label
-   * @param {string} subtitle
-   * @param {!Common.Setting} setting
-   */
-  _appendCheckbox(label, subtitle, setting) {
-    const checkboxLabel = UI.CheckboxLabel.create(label, false, subtitle);
-    UI.SettingsUI.bindCheckbox(checkboxLabel.checkboxElement, setting);
-    this.contentElement.appendChild(checkboxLabel);
-  }
-};
diff --git a/front_end/inspector_main/RequestAppBannerActionDelegate.js b/front_end/inspector_main/RequestAppBannerActionDelegate.js
deleted file mode 100644
index 8792584..0000000
--- a/front_end/inspector_main/RequestAppBannerActionDelegate.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-InspectorMain.RequestAppBannerActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const target = SDK.targetManager.mainTarget();
-    if (target && target.hasBrowserCapability()) {
-      target.pageAgent().requestAppBanner();
-      Common.console.show();
-    }
-    return true;
-  }
-};
diff --git a/front_end/inspector_main/module.json b/front_end/inspector_main/module.json
deleted file mode 100644
index 24aa03b..0000000
--- a/front_end/inspector_main/module.json
+++ /dev/null
@@ -1,132 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "early-initialization",
-            "className": "InspectorMain.InspectorMain"
-        },
-        {
-            "type": "action",
-            "category": "Navigation",
-            "actionId": "inspector_main.reload",
-            "className": "InspectorMain.ReloadActionDelegate",
-            "iconClass": "largeicon-refresh",
-            "title": "Reload page",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "F5 Ctrl+R"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+R"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Navigation",
-            "actionId": "inspector_main.hard-reload",
-            "className": "InspectorMain.ReloadActionDelegate",
-            "title": "Hard reload page",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Shift+F5 Ctrl+F5 Ctrl+Shift+F5 Shift+Ctrl+R"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Shift+Meta+R"
-                }
-            ]
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "InspectorMain.NodeIndicator",
-            "order": 2,
-            "location": "main-toolbar-left"
-        },
-        {
-            "type": "setting",
-            "category": "Network",
-            "title": "Force ad blocking on this site",
-            "settingName": "network.adBlockingEnabled",
-            "settingType": "boolean",
-            "storageType": "session",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Block ads on this site"
-                },
-                {
-                    "value": false,
-                    "title": "Show ads on this site, if allowed"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "DevTools",
-            "title": "Auto-open DevTools for popups",
-            "settingName": "autoAttachToCreatedPages",
-            "settingType": "boolean",
-            "order": 2,
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Auto-open DevTools for popups"
-                },
-                {
-                    "value": false,
-                    "title": "Do not auto-open DevTools for popups"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Appearance",
-            "title": "Don't show Chrome Data Saver warning",
-            "settingName": "disableDataSaverInfobar",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Appearance",
-            "title": "Disable paused state overlay",
-            "settingName": "disablePausedStateOverlay",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "rendering",
-            "title": "Rendering",
-            "persistence": "closeable",
-            "order": 50,
-            "className": "InspectorMain.RenderingOptionsView"
-        },
-        {
-            "type": "action",
-            "category": "Mobile",
-            "actionId": "components.request-app-banner",
-            "className": "InspectorMain.RequestAppBannerActionDelegate",
-            "title": "Add to homescreen"
-        }
-    ],
-    "dependencies": [
-        "components",
-        "mobile_throttling"
-    ],
-    "scripts": [
-        "RenderingOptions.js",
-        "RequestAppBannerActionDelegate.js",
-        "InspectorMain.js"
-    ],
-    "resources": [
-        "nodeIcon.css",
-        "renderingOptions.css"
-    ]
-}
diff --git a/front_end/inspector_main/nodeIcon.css b/front_end/inspector_main/nodeIcon.css
deleted file mode 100644
index 326247d..0000000
--- a/front_end/inspector_main/nodeIcon.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.node-icon {
-    width: 28px;
-    height: 26px;
-    background-image: url(Images/nodeIcon.png);
-    background-size: 17px 17px;
-    background-repeat: no-repeat;
-    background-position: center;
-    opacity: 0.8;
-}
-
-.node-icon:hover {
-    opacity: 1.0;
-}
-
-.node-icon.inactive {
-    filter: grayscale(100%);
-}
diff --git a/front_end/inspector_main/renderingOptions.css b/front_end/inspector_main/renderingOptions.css
deleted file mode 100644
index 77eeb51..0000000
--- a/front_end/inspector_main/renderingOptions.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    padding: 12px;
- }
-
-label {
-    margin: 0px 0px 10px 0px;
-    flex: none;
-}
-
-.media-row {
-    margin-left: 22px;
-    flex: none;
-}
-
-.media-row p {
-    margin-top: 0;
-    color: gray;
-}
-
-.panel-section-separator {
-    height: 1px;
-    margin-bottom: 10px;
-    background: #f0f0f0;
-    flex: none;
-}
diff --git a/front_end/integration_test_runner.html b/front_end/integration_test_runner.html
deleted file mode 100644
index 780a48a..0000000
--- a/front_end/integration_test_runner.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!--
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="integration_test_runner.js"></script>
-</head>
-<body id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/integration_test_runner.js b/front_end/integration_test_runner.js
deleted file mode 100644
index 3eddfa0..0000000
--- a/front_end/integration_test_runner.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-if (self.testRunner) {
-  testRunner.dumpAsText();
-  testRunner.waitUntilDone();
-}
-
-Runtime.startApplication('integration_test_runner');
diff --git a/front_end/integration_test_runner.json b/front_end/integration_test_runner.json
deleted file mode 100644
index 0d10106..0000000
--- a/front_end/integration_test_runner.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "modules" : [
-    { "name": "test_runner", "type": "autostart" },
-
-    { "name": "heap_snapshot_worker" },
-
-    { "name": "accessibility_test_runner" },
-    { "name": "application_test_runner" },
-    { "name": "audits2_test_runner" },
-    { "name": "bindings_test_runner" },
-    { "name": "console_test_runner" },
-    { "name": "coverage_test_runner" },
-    { "name": "cpu_profiler_test_runner" },
-    { "name": "data_grid_test_runner" },
-    { "name": "device_mode_test_runner" },
-    { "name": "elements_test_runner" },
-    { "name": "extensions_test_runner" },
-    { "name": "heap_profiler_test_runner" },
-    { "name": "layers_test_runner" },
-    { "name": "network_test_runner" },
-    { "name": "performance_test_runner" },
-    { "name": "sdk_test_runner" },
-    { "name": "security_test_runner" },
-    { "name": "sources_test_runner" }
-  ],
-  "extends": "devtools_app",
-  "has_html": true
-}
diff --git a/front_end/js_app.html b/front_end/js_app.html
deleted file mode 100644
index dff8942..0000000
--- a/front_end/js_app.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <meta name="referrer" content="no-referrer">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="js_app.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/js_app.js b/front_end/js_app.js
deleted file mode 100644
index 11427a0..0000000
--- a/front_end/js_app.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Runtime.startApplication('js_app');
diff --git a/front_end/js_app.json b/front_end/js_app.json
deleted file mode 100644
index 3e9deed..0000000
--- a/front_end/js_app.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "modules" : [
-    { "name": "js_main", "type": "autostart" },
-    { "name": "js_profiler" }
-  ],
-  "extends": "shell",
-  "has_html": true
-}
diff --git a/front_end/js_main/JsMain.js b/front_end/js_main/JsMain.js
deleted file mode 100644
index 8b99080..0000000
--- a/front_end/js_main/JsMain.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.Runnable}
- */
-JsMain.JsMain = class extends Common.Object {
-  /**
-   * @override
-   */
-  run() {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConnectToNodeJSDirectly);
-    const target = SDK.targetManager.createTarget(
-        'main', Common.UIString('Main'), SDK.Target.Capability.JS, this._createMainConnection.bind(this), null);
-    target.runtimeAgent().runIfWaitingForDebugger();
-    InspectorFrontendHost.connectionReady();
-  }
-
-  /**
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   * @return {!Protocol.InspectorBackend.Connection}
-   */
-  _createMainConnection(params) {
-    return SDK.createMainConnection(params, () => Components.TargetDetachedDialog.webSocketConnectionLost());
-  }
-};
diff --git a/front_end/js_main/module.json b/front_end/js_main/module.json
deleted file mode 100644
index 5ea75e6..0000000
--- a/front_end/js_main/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "early-initialization",
-            "className": "JsMain.JsMain"
-        }
-    ],
-    "dependencies": [
-        "components"
-    ],
-    "scripts": [
-        "JsMain.js"
-    ]
-}
diff --git a/front_end/js_profiler/module.json b/front_end/js_profiler/module.json
deleted file mode 100644
index fb09219..0000000
--- a/front_end/js_profiler/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "js_profiler",
-            "title": "Profiler",
-            "order": 65,
-            "className": "Profiler.JSProfilerPanel"
-        }
-    ],
-    "dependencies": [
-        "profiler"
-    ]
-}
diff --git a/front_end/jsconfig.json b/front_end/jsconfig.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/front_end/jsconfig.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/front_end/layer_viewer/LayerDetailsView.js b/front_end/layer_viewer/LayerDetailsView.js
deleted file mode 100644
index 8daae62..0000000
--- a/front_end/layer_viewer/LayerDetailsView.js
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {LayerViewer.LayerView}
- * @unrestricted
- */
-LayerViewer.LayerDetailsView = class extends UI.Widget {
-  /**
-   * @param {!LayerViewer.LayerViewHost} layerViewHost
-   */
-  constructor(layerViewHost) {
-    super(true);
-    this.registerRequiredCSS('layer_viewer/layerDetailsView.css');
-    this._layerViewHost = layerViewHost;
-    this._layerViewHost.registerView(this);
-    this._emptyWidget = new UI.EmptyWidget(Common.UIString('Select a layer to see its details'));
-    this._buildContent();
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   * @override
-   */
-  hoverObject(selection) {
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   * @override
-   */
-  selectObject(selection) {
-    this._selection = selection;
-    if (this.isShowing())
-      this.update();
-  }
-
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   * @override
-   */
-  setLayerTree(layerTree) {
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this.update();
-  }
-
-  /**
-   * @param {number} index
-   * @param {!Event} event
-   */
-  _onScrollRectClicked(index, event) {
-    if (event.which !== 1)
-      return;
-    this._layerViewHost.selectObject(new LayerViewer.LayerView.ScrollRectSelection(this._selection.layer(), index));
-  }
-
-  _onPaintProfilerButtonClicked() {
-    if (this._selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot || this._selection.layer())
-      this.dispatchEventToListeners(LayerViewer.LayerDetailsView.Events.PaintProfilerRequested, this._selection);
-  }
-
-  /**
-   * @param {!Protocol.LayerTree.ScrollRect} scrollRect
-   * @param {number} index
-   */
-  _createScrollRectElement(scrollRect, index) {
-    if (index)
-      this._scrollRectsCell.createTextChild(', ');
-    const element = this._scrollRectsCell.createChild('span', 'scroll-rect');
-    if (this._selection.scrollRectIndex === index)
-      element.classList.add('active');
-    element.textContent = Common.UIString(
-        '%s %d × %d (at %d, %d)', LayerViewer.LayerDetailsView._slowScrollRectNames.get(scrollRect.type),
-        scrollRect.rect.x, scrollRect.rect.y, scrollRect.rect.width, scrollRect.rect.height);
-    element.addEventListener('click', this._onScrollRectClicked.bind(this, index), false);
-  }
-
-  /**
-   * @param {string} title
-   * @param {?SDK.Layer} layer
-   * @return {string}
-   */
-  _formatStickyAncestorLayer(title, layer) {
-    if (!layer)
-      return '';
-
-    const node = layer.nodeForSelfOrAncestor();
-    const name = node ? node.simpleSelector() : Common.UIString('<unnamed>');
-    return Common.UIString('%s: %s (%s)', title, name, layer.id());
-  }
-
-  /**
-   * @param {string} title
-   * @param {?SDK.Layer} layer
-   */
-  _createStickyAncestorChild(title, layer) {
-    if (!layer)
-      return;
-
-    this._stickyPositionConstraintCell.createTextChild(', ');
-    const child = this._stickyPositionConstraintCell.createChild('span');
-    child.textContent = this._formatStickyAncestorLayer(title, layer);
-  }
-
-  /**
-   * @param {?SDK.Layer.StickyPositionConstraint} constraint
-   */
-  _populateStickyPositionConstraintCell(constraint) {
-    this._stickyPositionConstraintCell.removeChildren();
-    if (!constraint)
-      return;
-
-    const stickyBoxRect = constraint.stickyBoxRect();
-    const stickyBoxRectElement = this._stickyPositionConstraintCell.createChild('span');
-    stickyBoxRectElement.textContent = Common.UIString(
-        'Sticky Box %d × %d (at %d, %d)', stickyBoxRect.width, stickyBoxRect.height, stickyBoxRect.x, stickyBoxRect.y);
-
-    this._stickyPositionConstraintCell.createTextChild(', ');
-
-    const containingBlockRect = constraint.containingBlockRect();
-    const containingBlockRectElement = this._stickyPositionConstraintCell.createChild('span');
-    containingBlockRectElement.textContent = Common.UIString(
-        'Containing Block %d × %d (at %d, %d)', containingBlockRect.width, containingBlockRect.height,
-        containingBlockRect.x, containingBlockRect.y);
-
-    this._createStickyAncestorChild(
-        Common.UIString('Nearest Layer Shifting Sticky Box'), constraint.nearestLayerShiftingStickyBox());
-    this._createStickyAncestorChild(
-        Common.UIString('Nearest Layer Shifting Containing Block'), constraint.nearestLayerShiftingContainingBlock());
-  }
-
-  update() {
-    const layer = this._selection && this._selection.layer();
-    if (!layer) {
-      this._tableElement.remove();
-      this._paintProfilerButton.remove();
-      this._emptyWidget.show(this.contentElement);
-      return;
-    }
-    this._emptyWidget.detach();
-    this.contentElement.appendChild(this._tableElement);
-    this.contentElement.appendChild(this._paintProfilerButton);
-    this._sizeCell.textContent =
-        Common.UIString('%d × %d (at %d,%d)', layer.width(), layer.height(), layer.offsetX(), layer.offsetY());
-    this._paintCountCell.parentElement.classList.toggle('hidden', !layer.paintCount());
-    this._paintCountCell.textContent = layer.paintCount();
-    this._memoryEstimateCell.textContent = Number.bytesToString(layer.gpuMemoryUsage());
-    layer.requestCompositingReasons().then(this._updateCompositingReasons.bind(this));
-    this._scrollRectsCell.removeChildren();
-    layer.scrollRects().forEach(this._createScrollRectElement.bind(this));
-    this._populateStickyPositionConstraintCell(layer.stickyPositionConstraint());
-    const snapshot = this._selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot ?
-        /** @type {!LayerViewer.LayerView.SnapshotSelection} */ (this._selection).snapshot() :
-        null;
-    this._paintProfilerButton.classList.toggle('hidden', !snapshot);
-  }
-
-  _buildContent() {
-    this._tableElement = this.contentElement.createChild('table');
-    this._tbodyElement = this._tableElement.createChild('tbody');
-    this._sizeCell = this._createRow(Common.UIString('Size'));
-    this._compositingReasonsCell = this._createRow(Common.UIString('Compositing Reasons'));
-    this._memoryEstimateCell = this._createRow(Common.UIString('Memory estimate'));
-    this._paintCountCell = this._createRow(Common.UIString('Paint count'));
-    this._scrollRectsCell = this._createRow(Common.UIString('Slow scroll regions'));
-    this._stickyPositionConstraintCell = this._createRow(Common.UIString('Sticky position constraint'));
-    this._paintProfilerButton = this.contentElement.createChild('a', 'hidden link');
-    this._paintProfilerButton.textContent = Common.UIString('Paint Profiler');
-    this._paintProfilerButton.addEventListener('click', this._onPaintProfilerButtonClicked.bind(this));
-  }
-
-  /**
-   * @param {string} title
-   */
-  _createRow(title) {
-    const tr = this._tbodyElement.createChild('tr');
-    const titleCell = tr.createChild('td');
-    titleCell.textContent = title;
-    return tr.createChild('td');
-  }
-
-  /**
-   * @param {!Array.<string>} compositingReasons
-   */
-  _updateCompositingReasons(compositingReasons) {
-    if (!compositingReasons || !compositingReasons.length) {
-      this._compositingReasonsCell.textContent = 'n/a';
-      return;
-    }
-    this._compositingReasonsCell.removeChildren();
-    const list = this._compositingReasonsCell.createChild('ul');
-    for (let i = 0; i < compositingReasons.length; ++i) {
-      let text = LayerViewer.LayerDetailsView.CompositingReasonDetail[compositingReasons[i]] || compositingReasons[i];
-      // If the text is more than one word but does not terminate with period, add the period.
-      if (/\s.*[^.]$/.test(text))
-        text += '.';
-      list.createChild('li').textContent = text;
-    }
-  }
-};
-
-/**
- * @enum {string}
- */
-/** @enum {symbol} */
-LayerViewer.LayerDetailsView.Events = {
-  PaintProfilerRequested: Symbol('PaintProfilerRequested')
-};
-
-/**
- * @type {!Object.<string, string>}
- */
-LayerViewer.LayerDetailsView.CompositingReasonDetail = {
-  'transform3D': Common.UIString('Composition due to association with an element with a CSS 3D transform.'),
-  'video': Common.UIString('Composition due to association with a <video> element.'),
-  'canvas': Common.UIString('Composition due to the element being a <canvas> element.'),
-  'plugin': Common.UIString('Composition due to association with a plugin.'),
-  'iFrame': Common.UIString('Composition due to association with an <iframe> element.'),
-  'backfaceVisibilityHidden':
-      Common.UIString('Composition due to association with an element with a "backface-visibility: hidden" style.'),
-  'animation': Common.UIString('Composition due to association with an animated element.'),
-  'filters': Common.UIString('Composition due to association with an element with CSS filters applied.'),
-  'scrollDependentPosition': Common.UIString(
-      'Composition due to association with an element with a "position: fixed" or "position: sticky" style.'),
-  'overflowScrollingTouch':
-      Common.UIString('Composition due to association with an element with a "overflow-scrolling: touch" style.'),
-  'blending':
-      Common.UIString('Composition due to association with an element that has blend mode other than "normal".'),
-  'assumedOverlap':
-      Common.UIString('Composition due to association with an element that may overlap other composited elements.'),
-  'overlap': Common.UIString('Composition due to association with an element overlapping other composited elements.'),
-  'negativeZIndexChildren':
-      Common.UIString('Composition due to association with an element with descendants that have a negative z-index.'),
-  'transformWithCompositedDescendants':
-      Common.UIString('Composition due to association with an element with composited descendants.'),
-  'opacityWithCompositedDescendants': Common.UIString(
-      'Composition due to association with an element with opacity applied and composited descendants.'),
-  'maskWithCompositedDescendants':
-      Common.UIString('Composition due to association with a masked element and composited descendants.'),
-  'reflectionWithCompositedDescendants':
-      Common.UIString('Composition due to association with an element with a reflection and composited descendants.'),
-  'filterWithCompositedDescendants': Common.UIString(
-      'Composition due to association with an element with CSS filters applied and composited descendants.'),
-  'blendingWithCompositedDescendants': Common.UIString(
-      'Composition due to association with an element with CSS blending applied and composited descendants.'),
-  'clipsCompositingDescendants':
-      Common.UIString('Composition due to association with an element clipping compositing descendants.'),
-  'perspective': Common.UIString('Composition due to association with an element with perspective applied.'),
-  'preserve3D':
-      Common.UIString('Composition due to association with an element with a "transform-style: preserve-3d" style.'),
-  'root': Common.UIString('Root layer.'),
-  'layerForClip': Common.UIString('Layer for clip.'),
-  'layerForScrollbar': Common.UIString('Layer for scrollbar.'),
-  'layerForScrollingContainer': Common.UIString('Layer for scrolling container.'),
-  'layerForForeground': Common.UIString('Layer for foreground.'),
-  'layerForBackground': Common.UIString('Layer for background.'),
-  'layerForMask': Common.UIString('Layer for mask.'),
-  'layerForVideoOverlay': Common.UIString('Layer for video overlay.'),
-};
-
-LayerViewer.LayerDetailsView._slowScrollRectNames = new Map([
-  [SDK.Layer.ScrollRectType.NonFastScrollable, Common.UIString('Non fast scrollable')],
-  [SDK.Layer.ScrollRectType.TouchEventHandler, Common.UIString('Touch event handler')],
-  [SDK.Layer.ScrollRectType.WheelEventHandler, Common.UIString('Wheel event handler')],
-  [SDK.Layer.ScrollRectType.RepaintsOnScroll, Common.UIString('Repaints on scroll')]
-]);
diff --git a/front_end/layer_viewer/LayerTreeOutline.js b/front_end/layer_viewer/LayerTreeOutline.js
deleted file mode 100644
index 94c19cc..0000000
--- a/front_end/layer_viewer/LayerTreeOutline.js
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {LayerViewer.LayerView}
- * @unrestricted
- */
-LayerViewer.LayerTreeOutline = class extends Common.Object {
-  /**
-   * @param {!LayerViewer.LayerViewHost} layerViewHost
-   */
-  constructor(layerViewHost) {
-    super();
-    this._layerViewHost = layerViewHost;
-    this._layerViewHost.registerView(this);
-
-    this._treeOutline = new UI.TreeOutlineInShadow();
-    this._treeOutline.element.classList.add('layer-tree', 'overflow-auto');
-    this._treeOutline.element.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    this._treeOutline.element.addEventListener('mouseout', this._onMouseMove.bind(this), false);
-    this._treeOutline.element.addEventListener('contextmenu', this._onContextMenu.bind(this), true);
-
-    this._lastHoveredNode = null;
-    this.element = this._treeOutline.element;
-    this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update, this);
-  }
-
-  focus() {
-    this._treeOutline.focus();
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   * @override
-   */
-  selectObject(selection) {
-    this.hoverObject(null);
-    const layer = selection && selection.layer();
-    const node = layer && layer[LayerViewer.LayerTreeElement._symbol];
-    if (node)
-      node.revealAndSelect(true);
-    else if (this._treeOutline.selectedTreeElement)
-      this._treeOutline.selectedTreeElement.deselect();
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   * @override
-   */
-  hoverObject(selection) {
-    const layer = selection && selection.layer();
-    const node = layer && layer[LayerViewer.LayerTreeElement._symbol];
-    if (node === this._lastHoveredNode)
-      return;
-    if (this._lastHoveredNode)
-      this._lastHoveredNode.setHovered(false);
-    if (node)
-      node.setHovered(true);
-    this._lastHoveredNode = node;
-  }
-
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   * @override
-   */
-  setLayerTree(layerTree) {
-    this._layerTree = layerTree;
-    this._update();
-  }
-
-  _update() {
-    const showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
-    const seenLayers = new Map();
-    let root = null;
-    if (this._layerTree) {
-      if (!showInternalLayers)
-        root = this._layerTree.contentRoot();
-      if (!root)
-        root = this._layerTree.root();
-    }
-
-    /**
-     * @param {!SDK.Layer} layer
-     * @this {LayerViewer.LayerTreeOutline}
-     */
-    function updateLayer(layer) {
-      if (!layer.drawsContent() && !showInternalLayers)
-        return;
-      if (seenLayers.get(layer))
-        console.assert(false, 'Duplicate layer: ' + layer.id());
-      seenLayers.set(layer, true);
-      let node = layer[LayerViewer.LayerTreeElement._symbol];
-      let parentLayer = layer.parent();
-      // Skip till nearest visible ancestor.
-      while (parentLayer && parentLayer !== root && !parentLayer.drawsContent() && !showInternalLayers)
-        parentLayer = parentLayer.parent();
-      const parent =
-          layer === root ? this._treeOutline.rootElement() : parentLayer[LayerViewer.LayerTreeElement._symbol];
-      if (!parent) {
-        console.assert(false, 'Parent is not in the tree');
-        return;
-      }
-      if (!node) {
-        node = new LayerViewer.LayerTreeElement(this, layer);
-        parent.appendChild(node);
-        // Expand all new non-content layers to expose content layers better.
-        if (!layer.drawsContent())
-          node.expand();
-      } else {
-        if (node.parent !== parent) {
-          const oldSelection = this._treeOutline.selectedTreeElement;
-          if (node.parent)
-            node.parent.removeChild(node);
-          parent.appendChild(node);
-          if (oldSelection !== this._treeOutline.selectedTreeElement)
-            oldSelection.select();
-        }
-        node._update();
-      }
-    }
-    if (root)
-      this._layerTree.forEachLayer(updateLayer.bind(this), root);
-    // Cleanup layers that don't exist anymore from tree.
-    const rootElement = this._treeOutline.rootElement();
-    for (let node = rootElement.firstChild(); node && !node.root;) {
-      if (seenLayers.get(node._layer)) {
-        node = node.traverseNextTreeElement(false);
-      } else {
-        const nextNode = node.nextSibling || node.parent;
-        node.parent.removeChild(node);
-        if (node === this._lastHoveredNode)
-          this._lastHoveredNode = null;
-        node = nextNode;
-      }
-    }
-    if (!this._treeOutline.selectedTreeElement) {
-      const elementToSelect = this._layerTree.contentRoot() || this._layerTree.root();
-      if (elementToSelect)
-        elementToSelect[LayerViewer.LayerTreeElement._symbol].revealAndSelect(true);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    const node = this._treeOutline.treeElementFromEvent(event);
-    if (node === this._lastHoveredNode)
-      return;
-    this._layerViewHost.hoverObject(this._selectionForNode(node));
-  }
-
-  /**
-   * @param {!LayerViewer.LayerTreeElement} node
-   */
-  _selectedNodeChanged(node) {
-    this._layerViewHost.selectObject(this._selectionForNode(node));
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onContextMenu(event) {
-    const selection = this._selectionForNode(this._treeOutline.treeElementFromEvent(event));
-    const contextMenu = new UI.ContextMenu(event);
-    this._layerViewHost.showContextMenu(contextMenu, selection);
-  }
-
-  /**
-   * @param {?UI.TreeElement} node
-   * @return {?LayerViewer.LayerView.Selection}
-   */
-  _selectionForNode(node) {
-    return node && node._layer ? new LayerViewer.LayerView.LayerSelection(node._layer) : null;
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!LayerViewer.LayerTreeOutline} tree
-   * @param {!SDK.Layer} layer
-   */
-  constructor(tree, layer) {
-    super();
-    this._treeOutline = tree;
-    this._layer = layer;
-    this._layer[LayerViewer.LayerTreeElement._symbol] = this;
-    this._update();
-  }
-
-  _update() {
-    const node = this._layer.nodeForSelfOrAncestor();
-    const title = createDocumentFragment();
-    title.createTextChild(node ? node.simpleSelector() : '#' + this._layer.id());
-    const details = title.createChild('span', 'dimmed');
-    details.textContent = Common.UIString(' (%d × %d)', this._layer.width(), this._layer.height());
-    this.title = title;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect() {
-    this._treeOutline._selectedNodeChanged(this);
-    return false;
-  }
-
-  /**
-   * @param {boolean} hovered
-   */
-  setHovered(hovered) {
-    this.listItemElement.classList.toggle('hovered', hovered);
-  }
-};
-
-LayerViewer.LayerTreeElement._symbol = Symbol('layer');
diff --git a/front_end/layer_viewer/LayerViewHost.js b/front_end/layer_viewer/LayerViewHost.js
deleted file mode 100644
index 6aa3ee7..0000000
--- a/front_end/layer_viewer/LayerViewHost.js
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-/**
- * @interface
- */
-LayerViewer.LayerView = function() {};
-
-LayerViewer.LayerView.prototype = {
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   */
-  hoverObject(selection) {},
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   */
-  selectObject(selection) {},
-
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   */
-  setLayerTree(layerTree) {}
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerView.Selection = class {
-  /**
-   * @param {!LayerViewer.LayerView.Selection.Type} type
-   * @param {!SDK.Layer} layer
-   */
-  constructor(type, layer) {
-    this._type = type;
-    this._layer = layer;
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} a
-   * @param {?LayerViewer.LayerView.Selection} b
-   * @return {boolean}
-   */
-  static isEqual(a, b) {
-    return a && b ? a._isEqual(b) : a === b;
-  }
-
-  /**
-   * @return {!LayerViewer.LayerView.Selection.Type}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {!SDK.Layer}
-   */
-  layer() {
-    return this._layer;
-  }
-
-  /**
-   * @param {!LayerViewer.LayerView.Selection} other
-   * @return {boolean}
-   */
-  _isEqual(other) {
-    return false;
-  }
-};
-
-/**
- * @enum {symbol}
- */
-LayerViewer.LayerView.Selection.Type = {
-  Layer: Symbol('Layer'),
-  ScrollRect: Symbol('ScrollRect'),
-  Snapshot: Symbol('Snapshot')
-};
-
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerView.LayerSelection = class extends LayerViewer.LayerView.Selection {
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  constructor(layer) {
-    console.assert(layer, 'LayerSelection with empty layer');
-    super(LayerViewer.LayerView.Selection.Type.Layer, layer);
-  }
-
-  /**
-   * @override
-   * @param {!LayerViewer.LayerView.Selection} other
-   * @return {boolean}
-   */
-  _isEqual(other) {
-    return other._type === LayerViewer.LayerView.Selection.Type.Layer && other.layer().id() === this.layer().id();
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerView.ScrollRectSelection = class extends LayerViewer.LayerView.Selection {
-  /**
-   * @param {!SDK.Layer} layer
-   * @param {number} scrollRectIndex
-   */
-  constructor(layer, scrollRectIndex) {
-    super(LayerViewer.LayerView.Selection.Type.ScrollRect, layer);
-    this.scrollRectIndex = scrollRectIndex;
-  }
-
-  /**
-   * @override
-   * @param {!LayerViewer.LayerView.Selection} other
-   * @return {boolean}
-   */
-  _isEqual(other) {
-    return other._type === LayerViewer.LayerView.Selection.Type.ScrollRect &&
-        this.layer().id() === other.layer().id() && this.scrollRectIndex === other.scrollRectIndex;
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerView.SnapshotSelection = class extends LayerViewer.LayerView.Selection {
-  /**
-   * @param {!SDK.Layer} layer
-   * @param {!SDK.SnapshotWithRect} snapshot
-   */
-  constructor(layer, snapshot) {
-    super(LayerViewer.LayerView.Selection.Type.Snapshot, layer);
-    this._snapshot = snapshot;
-  }
-
-  /**
-   * @override
-   * @param {!LayerViewer.LayerView.Selection} other
-   * @return {boolean}
-   */
-  _isEqual(other) {
-    return other._type === LayerViewer.LayerView.Selection.Type.Snapshot && this.layer().id() === other.layer().id() &&
-        this._snapshot === other._snapshot;
-  }
-
-  /**
-   * @return {!SDK.SnapshotWithRect}
-   */
-  snapshot() {
-    return this._snapshot;
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerViewHost = class {
-  constructor() {
-    /** @type {!Array.<!LayerViewer.LayerView>} */
-    this._views = [];
-    this._selectedObject = null;
-    this._hoveredObject = null;
-    this._showInternalLayersSetting = Common.settings.createSetting('layersShowInternalLayers', false);
-  }
-
-  /**
-   * @param {!LayerViewer.LayerView} layerView
-   */
-  registerView(layerView) {
-    this._views.push(layerView);
-  }
-
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   */
-  setLayerTree(layerTree) {
-    this._target = layerTree.target();
-    const selectedLayer = this._selectedObject && this._selectedObject.layer();
-    if (selectedLayer && (!layerTree || !layerTree.layerById(selectedLayer.id())))
-      this.selectObject(null);
-    const hoveredLayer = this._hoveredObject && this._hoveredObject.layer();
-    if (hoveredLayer && (!layerTree || !layerTree.layerById(hoveredLayer.id())))
-      this.hoverObject(null);
-    for (const view of this._views)
-      view.setLayerTree(layerTree);
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   */
-  hoverObject(selection) {
-    if (LayerViewer.LayerView.Selection.isEqual(this._hoveredObject, selection))
-      return;
-    this._hoveredObject = selection;
-    const layer = selection && selection.layer();
-    this._toggleNodeHighlight(layer ? layer.nodeForSelfOrAncestor() : null);
-    for (const view of this._views)
-      view.hoverObject(selection);
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   */
-  selectObject(selection) {
-    if (LayerViewer.LayerView.Selection.isEqual(this._selectedObject, selection))
-      return;
-    this._selectedObject = selection;
-    for (const view of this._views)
-      view.selectObject(selection);
-  }
-
-  /**
-   * @return {?LayerViewer.LayerView.Selection}
-   */
-  selection() {
-    return this._selectedObject;
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {?LayerViewer.LayerView.Selection} selection
-   */
-  showContextMenu(contextMenu, selection) {
-    contextMenu.defaultSection().appendCheckboxItem(
-        Common.UIString('Show internal layers'), this._toggleShowInternalLayers.bind(this),
-        this._showInternalLayersSetting.get());
-    const node = selection && selection.layer() && selection.layer().nodeForSelfOrAncestor();
-    if (node)
-      contextMenu.appendApplicableItems(node);
-    contextMenu.show();
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  showInternalLayersSetting() {
-    return this._showInternalLayersSetting;
-  }
-
-  _toggleShowInternalLayers() {
-    this._showInternalLayersSetting.set(!this._showInternalLayersSetting.get());
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  _toggleNodeHighlight(node) {
-    if (node) {
-      node.highlightForTwoSeconds();
-      return;
-    }
-    SDK.OverlayModel.hideDOMNodeHighlight();
-  }
-};
diff --git a/front_end/layer_viewer/Layers3DView.js b/front_end/layer_viewer/Layers3DView.js
deleted file mode 100644
index 779e227..0000000
--- a/front_end/layer_viewer/Layers3DView.js
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {LayerViewer.LayerView}
- * @unrestricted
- */
-LayerViewer.Layers3DView = class extends UI.VBox {
-  /**
-   * @param {!LayerViewer.LayerViewHost} layerViewHost
-   */
-  constructor(layerViewHost) {
-    super(true);
-    this.registerRequiredCSS('layer_viewer/layers3DView.css');
-    this.contentElement.classList.add('layers-3d-view');
-    this._failBanner = new UI.VBox();
-    this._failBanner.element.classList.add('full-widget-dimmed-banner');
-    this._failBanner.element.createTextChild(Common.UIString('Layer information is not yet available.'));
-
-    this._layerViewHost = layerViewHost;
-    this._layerViewHost.registerView(this);
-
-    this._transformController = new LayerViewer.TransformController(this.contentElement);
-    this._transformController.addEventListener(
-        LayerViewer.TransformController.Events.TransformChanged, this._update, this);
-    this._initToolbar();
-
-    this._canvasElement = this.contentElement.createChild('canvas');
-    this._canvasElement.tabIndex = 0;
-    this._canvasElement.addEventListener('dblclick', this._onDoubleClick.bind(this), false);
-    this._canvasElement.addEventListener('mousedown', this._onMouseDown.bind(this), false);
-    this._canvasElement.addEventListener('mouseup', this._onMouseUp.bind(this), false);
-    this._canvasElement.addEventListener('mouseleave', this._onMouseMove.bind(this), false);
-    this._canvasElement.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    this._canvasElement.addEventListener('contextmenu', this._onContextMenu.bind(this), false);
-
-    this._lastSelection = {};
-    this._layerTree = null;
-
-    this._textureManager = new LayerViewer.LayerTextureManager(this._update.bind(this));
-
-    /** @type Array.<!WebGLTexture|undefined> */
-    this._chromeTextures = [];
-    this._rects = [];
-
-    this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update, this);
-  }
-
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   * @override
-   */
-  setLayerTree(layerTree) {
-    this._layerTree = layerTree;
-    this._layerTexture = null;
-    delete this._oldTextureScale;
-    if (this._showPaints())
-      this._textureManager.setLayerTree(layerTree);
-    this._update();
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @param {string=} imageURL
-   */
-  showImageForLayer(layer, imageURL) {
-    if (!imageURL) {
-      this._layerTexture = null;
-      this._update();
-      return;
-    }
-    UI.loadImage(imageURL).then(image => {
-      const texture = image && LayerViewer.LayerTextureManager._createTextureForImage(this._gl, image);
-      this._layerTexture = texture ? {layer: layer, texture: texture} : null;
-      this._update();
-    });
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._resizeCanvas();
-    this._update();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._textureManager.suspend();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._textureManager.resume();
-    if (!this._needsUpdate)
-      return;
-    this._resizeCanvas();
-    this._update();
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  updateLayerSnapshot(layer) {
-    this._textureManager.layerNeedsUpdate(layer);
-  }
-
-  /**
-   * @param {!LayerViewer.Layers3DView.OutlineType} type
-   * @param {?LayerViewer.LayerView.Selection} selection
-   */
-  _setOutline(type, selection) {
-    this._lastSelection[type] = selection;
-    this._update();
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   * @override
-   */
-  hoverObject(selection) {
-    this._setOutline(LayerViewer.Layers3DView.OutlineType.Hovered, selection);
-  }
-
-  /**
-   * @param {?LayerViewer.LayerView.Selection} selection
-   * @override
-   */
-  selectObject(selection) {
-    this._setOutline(LayerViewer.Layers3DView.OutlineType.Hovered, null);
-    this._setOutline(LayerViewer.Layers3DView.OutlineType.Selected, selection);
-  }
-
-  /**
-   * @param {!LayerViewer.LayerView.Selection} selection
-   * @return {!Promise<?SDK.SnapshotWithRect>}
-   */
-  snapshotForSelection(selection) {
-    if (selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot) {
-      const snapshotWithRect = /** @type {!LayerViewer.LayerView.SnapshotSelection} */ (selection).snapshot();
-      snapshotWithRect.snapshot.addReference();
-      return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(snapshotWithRect));
-    }
-    if (selection.layer()) {
-      const promise = selection.layer().snapshots()[0];
-      if (promise)
-        return promise;
-    }
-    return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(null));
-  }
-
-  /**
-   * @param {!Element} canvas
-   * @return {?WebGLRenderingContext}
-   */
-  _initGL(canvas) {
-    const gl = canvas.getContext('webgl');
-    if (!gl)
-      return null;
-    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
-    gl.enable(gl.BLEND);
-    gl.clearColor(0.0, 0.0, 0.0, 0.0);
-    gl.enable(gl.DEPTH_TEST);
-    return gl;
-  }
-
-  /**
-   * @param {!Object} type
-   * @param {string} script
-   */
-  _createShader(type, script) {
-    const shader = this._gl.createShader(type);
-    this._gl.shaderSource(shader, script);
-    this._gl.compileShader(shader);
-    this._gl.attachShader(this._shaderProgram, shader);
-  }
-
-  _initShaders() {
-    this._shaderProgram = this._gl.createProgram();
-    this._createShader(this._gl.FRAGMENT_SHADER, LayerViewer.Layers3DView.FragmentShader);
-    this._createShader(this._gl.VERTEX_SHADER, LayerViewer.Layers3DView.VertexShader);
-    this._gl.linkProgram(this._shaderProgram);
-    this._gl.useProgram(this._shaderProgram);
-
-    this._shaderProgram.vertexPositionAttribute = this._gl.getAttribLocation(this._shaderProgram, 'aVertexPosition');
-    this._gl.enableVertexAttribArray(this._shaderProgram.vertexPositionAttribute);
-    this._shaderProgram.vertexColorAttribute = this._gl.getAttribLocation(this._shaderProgram, 'aVertexColor');
-    this._gl.enableVertexAttribArray(this._shaderProgram.vertexColorAttribute);
-    this._shaderProgram.textureCoordAttribute = this._gl.getAttribLocation(this._shaderProgram, 'aTextureCoord');
-    this._gl.enableVertexAttribArray(this._shaderProgram.textureCoordAttribute);
-
-    this._shaderProgram.pMatrixUniform = this._gl.getUniformLocation(this._shaderProgram, 'uPMatrix');
-    this._shaderProgram.samplerUniform = this._gl.getUniformLocation(this._shaderProgram, 'uSampler');
-  }
-
-  _resizeCanvas() {
-    this._canvasElement.width = this._canvasElement.offsetWidth * window.devicePixelRatio;
-    this._canvasElement.height = this._canvasElement.offsetHeight * window.devicePixelRatio;
-  }
-
-  _updateTransformAndConstraints() {
-    const paddingFraction = 0.1;
-    const viewport = this._layerTree.viewportSize();
-    const baseWidth = viewport ? viewport.width : this._dimensionsForAutoscale.width;
-    const baseHeight = viewport ? viewport.height : this._dimensionsForAutoscale.height;
-    const canvasWidth = this._canvasElement.width;
-    const canvasHeight = this._canvasElement.height;
-    const paddingX = canvasWidth * paddingFraction;
-    const paddingY = canvasHeight * paddingFraction;
-    const scaleX = (canvasWidth - 2 * paddingX) / baseWidth;
-    const scaleY = (canvasHeight - 2 * paddingY) / baseHeight;
-    const viewScale = Math.min(scaleX, scaleY);
-    const minScaleConstraint =
-        Math.min(baseWidth / this._dimensionsForAutoscale.width, baseHeight / this._dimensionsForAutoscale.width) / 2;
-    this._transformController.setScaleConstraints(
-        minScaleConstraint,
-        10 / viewScale);  // 1/viewScale is 1:1 in terms of pixels, so allow zooming to 10x of native size
-    const scale = this._transformController.scale();
-    const rotateX = this._transformController.rotateX();
-    const rotateY = this._transformController.rotateY();
-
-    this._scale = scale * viewScale;
-    const textureScale = Number.constrain(this._scale, 0.1, 1);
-    if (textureScale !== this._oldTextureScale) {
-      this._oldTextureScale = textureScale;
-      this._textureManager.setScale(textureScale);
-      this.dispatchEventToListeners(LayerViewer.Layers3DView.Events.ScaleChanged, textureScale);
-    }
-    const scaleAndRotationMatrix = new WebKitCSSMatrix()
-                                       .scale(scale, scale, scale)
-                                       .translate(canvasWidth / 2, canvasHeight / 2, 0)
-                                       .rotate(rotateX, rotateY, 0)
-                                       .scale(viewScale, viewScale, viewScale)
-                                       .translate(-baseWidth / 2, -baseHeight / 2, 0);
-
-    let bounds;
-    for (let i = 0; i < this._rects.length; ++i)
-      bounds = UI.Geometry.boundsForTransformedPoints(scaleAndRotationMatrix, this._rects[i].vertices, bounds);
-
-    this._transformController.clampOffsets(
-        (paddingX - bounds.maxX) / window.devicePixelRatio,
-        (canvasWidth - paddingX - bounds.minX) / window.devicePixelRatio,
-        (paddingY - bounds.maxY) / window.devicePixelRatio,
-        (canvasHeight - paddingY - bounds.minY) / window.devicePixelRatio);
-    const offsetX = this._transformController.offsetX() * window.devicePixelRatio;
-    const offsetY = this._transformController.offsetY() * window.devicePixelRatio;
-    // Multiply to translation matrix on the right rather than translate (which would implicitly multiply on the left).
-    this._projectionMatrix = new WebKitCSSMatrix().translate(offsetX, offsetY, 0).multiply(scaleAndRotationMatrix);
-
-    const glProjectionMatrix = new WebKitCSSMatrix()
-                                   .scale(1, -1, -1)
-                                   .translate(-1, -1, 0)
-                                   .scale(2 / this._canvasElement.width, 2 / this._canvasElement.height, 1 / 1000000)
-                                   .multiply(this._projectionMatrix);
-    this._gl.uniformMatrix4fv(this._shaderProgram.pMatrixUniform, false, this._arrayFromMatrix(glProjectionMatrix));
-  }
-
-  /**
-   * @param {!CSSMatrix} m
-   * @return {!Float32Array}
-   */
-  _arrayFromMatrix(m) {
-    return new Float32Array([
-      m.m11, m.m12, m.m13, m.m14, m.m21, m.m22, m.m23, m.m24, m.m31, m.m32, m.m33, m.m34, m.m41, m.m42, m.m43, m.m44
-    ]);
-  }
-
-  _initWhiteTexture() {
-    this._whiteTexture = this._gl.createTexture();
-    this._gl.bindTexture(this._gl.TEXTURE_2D, this._whiteTexture);
-    const whitePixel = new Uint8Array([255, 255, 255, 255]);
-    this._gl.texImage2D(
-        this._gl.TEXTURE_2D, 0, this._gl.RGBA, 1, 1, 0, this._gl.RGBA, this._gl.UNSIGNED_BYTE, whitePixel);
-  }
-
-  _initChromeTextures() {
-    /**
-     * @this {LayerViewer.Layers3DView}
-     * @param {!LayerViewer.Layers3DView.ChromeTexture} index
-     * @param {string} url
-     */
-    function loadChromeTexture(index, url) {
-      UI.loadImage(url).then(image => {
-        this._chromeTextures[index] =
-            image && LayerViewer.LayerTextureManager._createTextureForImage(this._gl, image) || undefined;
-      });
-    }
-    loadChromeTexture.call(this, LayerViewer.Layers3DView.ChromeTexture.Left, 'Images/chromeLeft.png');
-    loadChromeTexture.call(this, LayerViewer.Layers3DView.ChromeTexture.Middle, 'Images/chromeMiddle.png');
-    loadChromeTexture.call(this, LayerViewer.Layers3DView.ChromeTexture.Right, 'Images/chromeRight.png');
-  }
-
-  /**
-   * @return {?WebGLRenderingContext}
-   */
-  _initGLIfNecessary() {
-    if (this._gl)
-      return this._gl;
-    this._gl = this._initGL(this._canvasElement);
-    if (!this._gl)
-      return null;
-    this._initShaders();
-    this._initWhiteTexture();
-    this._initChromeTextures();
-    this._textureManager.setContext(this._gl);
-    return this._gl;
-  }
-
-  _calculateDepthsAndVisibility() {
-    this._depthByLayerId = {};
-    let depth = 0;
-    const showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
-    const root =
-        showInternalLayers ? this._layerTree.root() : (this._layerTree.contentRoot() || this._layerTree.root());
-    const queue = [root];
-    this._depthByLayerId[root.id()] = 0;
-    /** @type {!Set<!SDK.Layer>} */
-    this._visibleLayers = new Set();
-    while (queue.length > 0) {
-      const layer = queue.shift();
-      if (showInternalLayers || layer.drawsContent())
-        this._visibleLayers.add(layer);
-      const children = layer.children();
-      for (let i = 0; i < children.length; ++i) {
-        this._depthByLayerId[children[i].id()] = ++depth;
-        queue.push(children[i]);
-      }
-    }
-    this._maxDepth = depth;
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @return {number}
-   */
-  _depthForLayer(layer) {
-    return this._depthByLayerId[layer.id()] * LayerViewer.Layers3DView.LayerSpacing;
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @param {number} index
-   * @return {number}
-   */
-  _calculateScrollRectDepth(layer, index) {
-    return this._depthForLayer(layer) + index * LayerViewer.Layers3DView.ScrollRectSpacing + 1;
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  _updateDimensionsForAutoscale(layer) {
-    // We don't want to be precise, but rather pick something least affected by
-    // animationtransforms, so that we don't change scale too often. So let's
-    // disregard transforms, scrolling and relative layer positioning and choose
-    // the largest dimensions of all layers.
-    this._dimensionsForAutoscale.width = Math.max(layer.width(), this._dimensionsForAutoscale.width);
-    this._dimensionsForAutoscale.height = Math.max(layer.height(), this._dimensionsForAutoscale.height);
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  _calculateLayerRect(layer) {
-    if (!this._visibleLayers.has(layer))
-      return;
-    const selection = new LayerViewer.LayerView.LayerSelection(layer);
-    const rect = new LayerViewer.Layers3DView.Rectangle(selection);
-    rect.setVertices(layer.quad(), this._depthForLayer(layer));
-    this._appendRect(rect);
-    this._updateDimensionsForAutoscale(layer);
-  }
-
-  /**
-   * @param {!LayerViewer.Layers3DView.Rectangle} rect
-   */
-  _appendRect(rect) {
-    const selection = rect.relatedObject;
-    const isSelected = LayerViewer.LayerView.Selection.isEqual(
-        this._lastSelection[LayerViewer.Layers3DView.OutlineType.Selected], selection);
-    const isHovered = LayerViewer.LayerView.Selection.isEqual(
-        this._lastSelection[LayerViewer.Layers3DView.OutlineType.Hovered], selection);
-    if (isSelected) {
-      rect.borderColor = LayerViewer.Layers3DView.SelectedBorderColor;
-    } else if (isHovered) {
-      rect.borderColor = LayerViewer.Layers3DView.HoveredBorderColor;
-      const fillColor = rect.fillColor || [255, 255, 255, 1];
-      const maskColor = LayerViewer.Layers3DView.HoveredImageMaskColor;
-      rect.fillColor = [
-        fillColor[0] * maskColor[0] / 255, fillColor[1] * maskColor[1] / 255, fillColor[2] * maskColor[2] / 255,
-        fillColor[3] * maskColor[3]
-      ];
-    } else {
-      rect.borderColor = LayerViewer.Layers3DView.BorderColor;
-    }
-    rect.lineWidth = isSelected ? LayerViewer.Layers3DView.SelectedBorderWidth : LayerViewer.Layers3DView.BorderWidth;
-    this._rects.push(rect);
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  _calculateLayerScrollRects(layer) {
-    const scrollRects = layer.scrollRects();
-    for (let i = 0; i < scrollRects.length; ++i) {
-      const selection = new LayerViewer.LayerView.ScrollRectSelection(layer, i);
-      const rect = new LayerViewer.Layers3DView.Rectangle(selection);
-      rect.calculateVerticesFromRect(layer, scrollRects[i].rect, this._calculateScrollRectDepth(layer, i));
-      rect.fillColor = LayerViewer.Layers3DView.ScrollRectBackgroundColor;
-      this._appendRect(rect);
-    }
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  _calculateLayerTileRects(layer) {
-    const tiles = this._textureManager.tilesForLayer(layer);
-    for (let i = 0; i < tiles.length; ++i) {
-      const tile = tiles[i];
-      if (!tile.texture)
-        continue;
-      const selection = new LayerViewer.LayerView.SnapshotSelection(layer, {rect: tile.rect, snapshot: tile.snapshot});
-      const rect = new LayerViewer.Layers3DView.Rectangle(selection);
-      rect.calculateVerticesFromRect(layer, tile.rect, this._depthForLayer(layer) + 1);
-      rect.texture = tile.texture;
-      this._appendRect(rect);
-    }
-  }
-
-  _calculateRects() {
-    this._rects = [];
-    this._dimensionsForAutoscale = {width: 0, height: 0};
-    this._layerTree.forEachLayer(this._calculateLayerRect.bind(this));
-
-    if (this._showSlowScrollRectsSetting.get())
-      this._layerTree.forEachLayer(this._calculateLayerScrollRects.bind(this));
-
-    if (this._layerTexture && this._visibleLayers.has(this._layerTexture.layer)) {
-      const layer = this._layerTexture.layer;
-      const selection = new LayerViewer.LayerView.LayerSelection(layer);
-      const rect = new LayerViewer.Layers3DView.Rectangle(selection);
-      rect.setVertices(layer.quad(), this._depthForLayer(layer));
-      rect.texture = this._layerTexture.texture;
-      this._appendRect(rect);
-    } else if (this._showPaints()) {
-      this._layerTree.forEachLayer(this._calculateLayerTileRects.bind(this));
-    }
-  }
-
-  /**
-   * @param {!Array.<number>} color
-   * @return {!Array.<number>}
-   */
-  _makeColorsArray(color) {
-    let colors = [];
-    const normalizedColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3]];
-    for (let i = 0; i < 4; i++)
-      colors = colors.concat(normalizedColor);
-    return colors;
-  }
-
-  /**
-   * @param {!Object} attribute
-   * @param {!Array.<number>} array
-   * @param {number} length
-   */
-  _setVertexAttribute(attribute, array, length) {
-    const gl = this._gl;
-    const buffer = gl.createBuffer();
-    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
-    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(array), gl.STATIC_DRAW);
-    gl.vertexAttribPointer(attribute, length, gl.FLOAT, false, 0, 0);
-  }
-
-  /**
-   * @param {!Array.<number>} vertices
-   * @param {number} mode
-   * @param {!Array.<number>=} color
-   * @param {!Object=} texture
-   */
-  _drawRectangle(vertices, mode, color, texture) {
-    const gl = this._gl;
-    const white = [255, 255, 255, 1];
-    color = color || white;
-    this._setVertexAttribute(this._shaderProgram.vertexPositionAttribute, vertices, 3);
-    this._setVertexAttribute(this._shaderProgram.textureCoordAttribute, [0, 1, 1, 1, 1, 0, 0, 0], 2);
-    this._setVertexAttribute(this._shaderProgram.vertexColorAttribute, this._makeColorsArray(color), color.length);
-
-    if (texture) {
-      gl.activeTexture(gl.TEXTURE0);
-      gl.bindTexture(gl.TEXTURE_2D, texture);
-      gl.uniform1i(this._shaderProgram.samplerUniform, 0);
-    } else {
-      gl.bindTexture(gl.TEXTURE_2D, this._whiteTexture);
-    }
-
-    const numberOfVertices = vertices.length / 3;
-    gl.drawArrays(mode, 0, numberOfVertices);
-  }
-
-  /**
-   * @param {!Array.<number>} vertices
-   * @param {!WebGLTexture} texture
-   * @param {!Array.<number>=} color
-   */
-  _drawTexture(vertices, texture, color) {
-    this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, color, texture);
-  }
-
-  _drawViewportAndChrome() {
-    const viewport = this._layerTree.viewportSize();
-    if (!viewport)
-      return;
-
-    const drawChrome = !Common.moduleSetting('frameViewerHideChromeWindow').get() && this._chromeTextures.length >= 3 &&
-        this._chromeTextures.indexOf(undefined) < 0;
-    const z = (this._maxDepth + 1) * LayerViewer.Layers3DView.LayerSpacing;
-    const borderWidth = Math.ceil(LayerViewer.Layers3DView.ViewportBorderWidth * this._scale);
-    let vertices = [viewport.width, 0, z, viewport.width, viewport.height, z, 0, viewport.height, z, 0, 0, z];
-    this._gl.lineWidth(borderWidth);
-    this._drawRectangle(
-        vertices, drawChrome ? this._gl.LINE_STRIP : this._gl.LINE_LOOP, LayerViewer.Layers3DView.ViewportBorderColor);
-
-    if (!drawChrome)
-      return;
-
-    const borderAdjustment = LayerViewer.Layers3DView.ViewportBorderWidth / 2;
-    const viewportWidth = this._layerTree.viewportSize().width + 2 * borderAdjustment;
-    const chromeHeight = this._chromeTextures[0].image.naturalHeight;
-    const middleFragmentWidth =
-        viewportWidth - this._chromeTextures[0].image.naturalWidth - this._chromeTextures[2].image.naturalWidth;
-    let x = -borderAdjustment;
-    const y = -chromeHeight;
-    for (let i = 0; i < this._chromeTextures.length; ++i) {
-      const width = i === LayerViewer.Layers3DView.ChromeTexture.Middle ? middleFragmentWidth :
-                                                                          this._chromeTextures[i].image.naturalWidth;
-      if (width < 0 || x + width > viewportWidth)
-        break;
-      vertices = [x, y, z, x + width, y, z, x + width, y + chromeHeight, z, x, y + chromeHeight, z];
-      this._drawTexture(vertices, /** @type {!WebGLTexture} */ (this._chromeTextures[i]));
-      x += width;
-    }
-  }
-
-  /**
-   * @param {!LayerViewer.Layers3DView.Rectangle} rect
-   */
-  _drawViewRect(rect) {
-    const vertices = rect.vertices;
-    if (rect.texture)
-      this._drawTexture(vertices, rect.texture, rect.fillColor || undefined);
-    else if (rect.fillColor)
-      this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, rect.fillColor);
-    this._gl.lineWidth(rect.lineWidth);
-    if (rect.borderColor)
-      this._drawRectangle(vertices, this._gl.LINE_LOOP, rect.borderColor);
-  }
-
-  _update() {
-    if (!this.isShowing()) {
-      this._needsUpdate = true;
-      return;
-    }
-    if (!this._layerTree || !this._layerTree.root()) {
-      this._failBanner.show(this.contentElement);
-      return;
-    }
-    const gl = this._initGLIfNecessary();
-    if (!gl) {
-      this._failBanner.element.removeChildren();
-      this._failBanner.element.appendChild(this._webglDisabledBanner());
-      this._failBanner.show(this.contentElement);
-      return;
-    }
-    this._failBanner.detach();
-    this._gl.viewportWidth = this._canvasElement.width;
-    this._gl.viewportHeight = this._canvasElement.height;
-
-    this._calculateDepthsAndVisibility();
-    this._calculateRects();
-    this._updateTransformAndConstraints();
-
-    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
-    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
-    this._rects.forEach(this._drawViewRect.bind(this));
-    this._drawViewportAndChrome();
-  }
-
-  /**
-   * @return {!Node}
-   */
-  _webglDisabledBanner() {
-    const fragment = this.contentElement.ownerDocument.createDocumentFragment();
-    fragment.createChild('div').textContent = Common.UIString('Can\'t display layers,');
-    fragment.createChild('div').textContent = Common.UIString('WebGL support is disabled in your browser.');
-    fragment.appendChild(UI.formatLocalized('Check %s for possible reasons.', [UI.XLink.create('about:gpu')]));
-    return fragment;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?LayerViewer.LayerView.Selection}
-   */
-  _selectionFromEventPoint(event) {
-    if (!this._layerTree)
-      return null;
-    let closestIntersectionPoint = Infinity;
-    let closestObject = null;
-    const projectionMatrix =
-        new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0).multiply(this._projectionMatrix);
-    const x0 = (event.clientX - this._canvasElement.totalOffsetLeft()) * window.devicePixelRatio;
-    const y0 = -(event.clientY - this._canvasElement.totalOffsetTop()) * window.devicePixelRatio;
-
-    /**
-     * @param {!LayerViewer.Layers3DView.Rectangle} rect
-     */
-    function checkIntersection(rect) {
-      if (!rect.relatedObject)
-        return;
-      const t = rect.intersectWithLine(projectionMatrix, x0, y0);
-      if (t < closestIntersectionPoint) {
-        closestIntersectionPoint = t;
-        closestObject = rect.relatedObject;
-      }
-    }
-
-    this._rects.forEach(checkIntersection);
-    return closestObject;
-  }
-
-  /**
-   * @param {string} caption
-   * @param {string} name
-   * @param {boolean} value
-   * @param {!UI.Toolbar} toolbar
-   * @return {!Common.Setting}
-   */
-  _createVisibilitySetting(caption, name, value, toolbar) {
-    const setting = Common.settings.createSetting(name, value);
-    setting.setTitle(Common.UIString(caption));
-    setting.addChangeListener(this._update, this);
-    toolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(setting));
-    return setting;
-  }
-
-  _initToolbar() {
-    this._panelToolbar = this._transformController.toolbar();
-    this.contentElement.appendChild(this._panelToolbar.element);
-    this._showSlowScrollRectsSetting =
-        this._createVisibilitySetting('Slow scroll rects', 'frameViewerShowSlowScrollRects', true, this._panelToolbar);
-    this._showPaintsSetting =
-        this._createVisibilitySetting('Paints', 'frameViewerShowPaints', true, this._panelToolbar);
-    this._showPaintsSetting.addChangeListener(this._updatePaints, this);
-    Common.moduleSetting('frameViewerHideChromeWindow').addChangeListener(this._update, this);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onContextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(
-        Common.UIString('Reset View'), this._transformController.resetAndNotify.bind(this._transformController), false);
-    const selection = this._selectionFromEventPoint(event);
-    if (selection && selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot) {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString('Show Paint Profiler'),
-          this.dispatchEventToListeners.bind(this, LayerViewer.Layers3DView.Events.PaintProfilerRequested, selection),
-          false);
-    }
-    this._layerViewHost.showContextMenu(contextMenu, selection);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    if (event.which)
-      return;
-    this._layerViewHost.hoverObject(this._selectionFromEventPoint(event));
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseDown(event) {
-    this._mouseDownX = event.clientX;
-    this._mouseDownY = event.clientY;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseUp(event) {
-    const maxDistanceInPixels = 6;
-    if (this._mouseDownX && Math.abs(event.clientX - this._mouseDownX) < maxDistanceInPixels &&
-        Math.abs(event.clientY - this._mouseDownY) < maxDistanceInPixels)
-      this._layerViewHost.selectObject(this._selectionFromEventPoint(event));
-    delete this._mouseDownX;
-    delete this._mouseDownY;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDoubleClick(event) {
-    const selection = this._selectionFromEventPoint(event);
-    if (selection && (selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot || selection.layer()))
-      this.dispatchEventToListeners(LayerViewer.Layers3DView.Events.PaintProfilerRequested, selection);
-    event.stopPropagation();
-  }
-
-  _updatePaints() {
-    if (this._showPaints()) {
-      this._textureManager.setLayerTree(this._layerTree);
-      this._textureManager.forceUpdate();
-    } else {
-      this._textureManager.reset();
-    }
-    this._update();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _showPaints() {
-    return this._showPaintsSetting.get();
-  }
-};
-
-/** @typedef {{borderColor: !Array<number>, borderWidth: number}} */
-LayerViewer.Layers3DView.LayerStyle;
-
-/**
- * @enum {string}
- */
-LayerViewer.Layers3DView.OutlineType = {
-  Hovered: 'hovered',
-  Selected: 'selected'
-};
-
-/**
- * @enum {string}
- */
-/** @enum {symbol} */
-LayerViewer.Layers3DView.Events = {
-  PaintProfilerRequested: Symbol('PaintProfilerRequested'),
-  ScaleChanged: Symbol('ScaleChanged')
-};
-
-/**
- * @enum {number}
- */
-LayerViewer.Layers3DView.ChromeTexture = {
-  Left: 0,
-  Middle: 1,
-  Right: 2
-};
-
-/**
- * @enum {string}
- */
-LayerViewer.Layers3DView.ScrollRectTitles = {
-  RepaintsOnScroll: Common.UIString('repaints on scroll'),
-  TouchEventHandler: Common.UIString('touch event listener'),
-  WheelEventHandler: Common.UIString('mousewheel event listener')
-};
-
-LayerViewer.Layers3DView.FragmentShader = '' +
-    'precision mediump float;\n' +
-    'varying vec4 vColor;\n' +
-    'varying vec2 vTextureCoord;\n' +
-    'uniform sampler2D uSampler;\n' +
-    'void main(void)\n' +
-    '{\n' +
-    '    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\n' +
-    '}';
-
-LayerViewer.Layers3DView.VertexShader = '' +
-    'attribute vec3 aVertexPosition;\n' +
-    'attribute vec2 aTextureCoord;\n' +
-    'attribute vec4 aVertexColor;\n' +
-    'uniform mat4 uPMatrix;\n' +
-    'varying vec2 vTextureCoord;\n' +
-    'varying vec4 vColor;\n' +
-    'void main(void)\n' +
-    '{\n' +
-    'gl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\n' +
-    'vColor = aVertexColor;\n' +
-    'vTextureCoord = aTextureCoord;\n' +
-    '}';
-
-LayerViewer.Layers3DView.HoveredBorderColor = [0, 0, 255, 1];
-LayerViewer.Layers3DView.SelectedBorderColor = [0, 255, 0, 1];
-LayerViewer.Layers3DView.BorderColor = [0, 0, 0, 1];
-LayerViewer.Layers3DView.ViewportBorderColor = [160, 160, 160, 1];
-LayerViewer.Layers3DView.ScrollRectBackgroundColor = [178, 100, 100, 0.6];
-LayerViewer.Layers3DView.HoveredImageMaskColor = [200, 200, 255, 1];
-LayerViewer.Layers3DView.BorderWidth = 1;
-LayerViewer.Layers3DView.SelectedBorderWidth = 2;
-LayerViewer.Layers3DView.ViewportBorderWidth = 3;
-
-LayerViewer.Layers3DView.LayerSpacing = 20;
-LayerViewer.Layers3DView.ScrollRectSpacing = 4;
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerTextureManager = class {
-  /**
-   * @param {function()} textureUpdatedCallback
-   */
-  constructor(textureUpdatedCallback) {
-    this._textureUpdatedCallback = textureUpdatedCallback;
-    this._throttler = new Common.Throttler(0);
-    this._scale = 0;
-    this._active = false;
-    this.reset();
-  }
-
-  /**
-   * @param {!Image} image
-   * @param {!WebGLRenderingContext} gl
-   * @return {!WebGLTexture} texture
-   */
-  static _createTextureForImage(gl, image) {
-    const texture = gl.createTexture();
-    texture.image = image;
-    gl.bindTexture(gl.TEXTURE_2D, texture);
-    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
-    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-    gl.bindTexture(gl.TEXTURE_2D, null);
-    return texture;
-  }
-
-  reset() {
-    if (this._tilesByLayer)
-      this.setLayerTree(null);
-
-    /** @type {!Map<!SDK.Layer, !Array<!LayerViewer.LayerTextureManager.Tile>>} */
-    this._tilesByLayer = new Map();
-    /** @type {!Array<!SDK.Layer>} */
-    this._queue = [];
-  }
-
-  /**
-   * @param {!WebGLRenderingContext} glContext
-   */
-  setContext(glContext) {
-    this._gl = glContext;
-    if (this._scale)
-      this._updateTextures();
-  }
-
-  suspend() {
-    this._active = false;
-  }
-
-  resume() {
-    this._active = true;
-    if (this._queue.length)
-      this._update();
-  }
-
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   */
-  setLayerTree(layerTree) {
-    const newLayers = new Set();
-    const oldLayers = Array.from(this._tilesByLayer.keys());
-    if (layerTree) {
-      layerTree.forEachLayer(layer => {
-        if (!layer.drawsContent())
-          return;
-        newLayers.add(layer);
-        if (!this._tilesByLayer.has(layer)) {
-          this._tilesByLayer.set(layer, []);
-          this.layerNeedsUpdate(layer);
-        }
-      });
-    }
-    if (!oldLayers.length)
-      this.forceUpdate();
-    for (const layer of oldLayers) {
-      if (newLayers.has(layer))
-        continue;
-      this._tilesByLayer.get(layer).forEach(tile => tile.dispose());
-      this._tilesByLayer.delete(layer);
-    }
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @param {!Array<!SDK.SnapshotWithRect>} snapshots
-   * @return {!Promise}
-   */
-  _setSnapshotsForLayer(layer, snapshots) {
-    const oldSnapshotsToTiles = new Map((this._tilesByLayer.get(layer) || []).map(tile => [tile.snapshot, tile]));
-    const newTiles = [];
-    const reusedTiles = [];
-    for (const snapshot of snapshots) {
-      const oldTile = oldSnapshotsToTiles.get(snapshot);
-      if (oldTile) {
-        reusedTiles.push(oldTile);
-        oldSnapshotsToTiles.delete(oldTile);
-      } else {
-        newTiles.push(new LayerViewer.LayerTextureManager.Tile(snapshot));
-      }
-    }
-    this._tilesByLayer.set(layer, reusedTiles.concat(newTiles));
-    for (const tile of oldSnapshotsToTiles.values())
-      tile.dispose();
-    if (!this._gl || !this._scale)
-      return Promise.resolve();
-    return Promise.all(newTiles.map(tile => tile.update(this._gl, this._scale))).then(this._textureUpdatedCallback);
-  }
-
-  /**
-   * @param {number} scale
-   */
-  setScale(scale) {
-    if (this._scale && this._scale >= scale)
-      return;
-    this._scale = scale;
-    this._updateTextures();
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @return {!Array<!LayerViewer.LayerTextureManager.Tile>}
-   */
-  tilesForLayer(layer) {
-    return this._tilesByLayer.get(layer) || [];
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   */
-  layerNeedsUpdate(layer) {
-    if (this._queue.indexOf(layer) < 0)
-      this._queue.push(layer);
-    if (this._active)
-      this._throttler.schedule(this._update.bind(this));
-  }
-
-  forceUpdate() {
-    this._queue.forEach(layer => this._updateLayer(layer));
-    this._queue = [];
-    this._update();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _update() {
-    const layer = this._queue.shift();
-    if (!layer)
-      return Promise.resolve();
-    if (this._queue.length)
-      this._throttler.schedule(this._update.bind(this));
-    return this._updateLayer(layer);
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @return {!Promise}
-   */
-  _updateLayer(layer) {
-    return Promise.all(layer.snapshots())
-        .then(snapshots => this._setSnapshotsForLayer(layer, snapshots.filter(snapshot => !!snapshot)));
-  }
-
-  _updateTextures() {
-    if (!this._gl)
-      return;
-    if (!this._scale)
-      return;
-
-    for (const tiles of this._tilesByLayer.values()) {
-      for (const tile of tiles) {
-        const promise = tile.updateScale(this._gl, this._scale);
-        if (promise)
-          promise.then(this._textureUpdatedCallback);
-      }
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.Layers3DView.Rectangle = class {
-  /**
-   * @param {?LayerViewer.LayerView.Selection} relatedObject
-   */
-  constructor(relatedObject) {
-    this.relatedObject = relatedObject;
-    /** @type {number} */
-    this.lineWidth = 1;
-    /** @type {?Array.<number>} */
-    this.borderColor = null;
-    /** @type {?Array.<number>} */
-    this.fillColor = null;
-    /** @type {?WebGLTexture} */
-    this.texture = null;
-  }
-
-  /**
-   * @param {!Array.<number>} quad
-   * @param {number} z
-   */
-  setVertices(quad, z) {
-    this.vertices = [quad[0], quad[1], z, quad[2], quad[3], z, quad[4], quad[5], z, quad[6], quad[7], z];
-  }
-
-  /**
-   * Finds coordinates of point on layer quad, having offsets (ratioX * width) and (ratioY * height)
-   * from the left corner of the initial layer rect, where width and heigth are layer bounds.
-   * @param {!Array.<number>} quad
-   * @param {number} ratioX
-   * @param {number} ratioY
-   * @return {!Array.<number>}
-   */
-  _calculatePointOnQuad(quad, ratioX, ratioY) {
-    const x0 = quad[0];
-    const y0 = quad[1];
-    const x1 = quad[2];
-    const y1 = quad[3];
-    const x2 = quad[4];
-    const y2 = quad[5];
-    const x3 = quad[6];
-    const y3 = quad[7];
-    // Point on the first quad side clockwise
-    const firstSidePointX = x0 + ratioX * (x1 - x0);
-    const firstSidePointY = y0 + ratioX * (y1 - y0);
-    // Point on the third quad side clockwise
-    const thirdSidePointX = x3 + ratioX * (x2 - x3);
-    const thirdSidePointY = y3 + ratioX * (y2 - y3);
-    const x = firstSidePointX + ratioY * (thirdSidePointX - firstSidePointX);
-    const y = firstSidePointY + ratioY * (thirdSidePointY - firstSidePointY);
-    return [x, y];
-  }
-
-  /**
-   * @param {!SDK.Layer} layer
-   * @param {!Protocol.DOM.Rect} rect
-   * @param {number} z
-   */
-  calculateVerticesFromRect(layer, rect, z) {
-    const quad = layer.quad();
-    const rx1 = rect.x / layer.width();
-    const rx2 = (rect.x + rect.width) / layer.width();
-    const ry1 = rect.y / layer.height();
-    const ry2 = (rect.y + rect.height) / layer.height();
-    const rectQuad = this._calculatePointOnQuad(quad, rx1, ry1)
-                         .concat(this._calculatePointOnQuad(quad, rx2, ry1))
-                         .concat(this._calculatePointOnQuad(quad, rx2, ry2))
-                         .concat(this._calculatePointOnQuad(quad, rx1, ry2));
-    this.setVertices(rectQuad, z);
-  }
-
-  /**
-   * Intersects quad with given transform matrix and line l(t) = (x0, y0, t)
-   * @param {!CSSMatrix} matrix
-   * @param {number} x0
-   * @param {number} y0
-   * @return {(number|undefined)}
-   */
-  intersectWithLine(matrix, x0, y0) {
-    let i;
-    // Vertices of the quad with transform matrix applied
-    const points = [];
-    for (i = 0; i < 4; ++i) {
-      points[i] = UI.Geometry.multiplyVectorByMatrixAndNormalize(
-          new UI.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]), matrix);
-    }
-    // Calculating quad plane normal
-    const normal = UI.Geometry.crossProduct(
-        UI.Geometry.subtract(points[1], points[0]), UI.Geometry.subtract(points[2], points[1]));
-    // General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
-    const A = normal.x;
-    const B = normal.y;
-    const C = normal.z;
-    const D = -(A * points[0].x + B * points[0].y + C * points[0].z);
-    // Finding t from the equation
-    const t = -(D + A * x0 + B * y0) / C;
-    // Point of the intersection
-    const pt = new UI.Geometry.Vector(x0, y0, t);
-    // Vectors from the intersection point to vertices of the quad
-    const tVects = points.map(UI.Geometry.subtract.bind(null, pt));
-    // Intersection point lies inside of the polygon if scalar products of normal of the plane and
-    // cross products of successive tVects are all nonstrictly above or all nonstrictly below zero
-    for (i = 0; i < tVects.length; ++i) {
-      const product =
-          UI.Geometry.scalarProduct(normal, UI.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
-      if (product < 0)
-        return undefined;
-    }
-    return t;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-LayerViewer.LayerTextureManager.Tile = class {
-  /**
-   * @param {!SDK.SnapshotWithRect} snapshotWithRect
-   */
-  constructor(snapshotWithRect) {
-    this.snapshot = snapshotWithRect.snapshot;
-    this.rect = snapshotWithRect.rect;
-    this.scale = 0;
-    /** @type {?WebGLTexture} */
-    this.texture = null;
-  }
-
-  dispose() {
-    this.snapshot.release();
-    if (this.texture) {
-      this._gl.deleteTexture(this.texture);
-      this.texture = null;
-    }
-  }
-
-  /**
-   * @param {!WebGLRenderingContext} glContext
-   * @param {number} scale
-   * @return {?Promise}
-   */
-  updateScale(glContext, scale) {
-    if (this.texture && this.scale >= scale)
-      return null;
-    return this.update(glContext, scale);
-  }
-
-  /**
-   * @param {!WebGLRenderingContext} glContext
-   * @param {number} scale
-   * @return {!Promise}
-   */
-  async update(glContext, scale) {
-    this._gl = glContext;
-    this.scale = scale;
-    const imageURL = await this.snapshot.replay(scale);
-    const image = imageURL && await UI.loadImage(imageURL);
-    this.texture = image && LayerViewer.LayerTextureManager._createTextureForImage(glContext, image);
-  }
-};
diff --git a/front_end/layer_viewer/PaintProfilerView.js b/front_end/layer_viewer/PaintProfilerView.js
deleted file mode 100644
index c5d88b9..0000000
--- a/front_end/layer_viewer/PaintProfilerView.js
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-LayerViewer.PaintProfilerView = class extends UI.HBox {
-  /**
-   * @param {function(string=)} showImageCallback
-   */
-  constructor(showImageCallback) {
-    super(true);
-    this.registerRequiredCSS('layer_viewer/paintProfiler.css');
-    this.contentElement.classList.add('paint-profiler-overview');
-    this._canvasContainer = this.contentElement.createChild('div', 'paint-profiler-canvas-container');
-    this._progressBanner = this.contentElement.createChild('div', 'full-widget-dimmed-banner hidden');
-    this._progressBanner.textContent = Common.UIString('Profiling\u2026');
-    this._pieChart = new PerfUI.PieChart(55, this._formatPieChartTime.bind(this), true);
-    this._pieChart.element.classList.add('paint-profiler-pie-chart');
-    this.contentElement.appendChild(this._pieChart.element);
-
-    this._showImageCallback = showImageCallback;
-
-    this._canvas = this._canvasContainer.createChild('canvas', 'fill');
-    this._context = this._canvas.getContext('2d');
-    this._selectionWindow = new PerfUI.OverviewGrid.Window(this._canvasContainer);
-    this._selectionWindow.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-
-    this._innerBarWidth = 4 * window.devicePixelRatio;
-    this._minBarHeight = window.devicePixelRatio;
-    this._barPaddingWidth = 2 * window.devicePixelRatio;
-    this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth;
-    this._pendingScale = 1;
-    this._scale = this._pendingScale;
-
-    this._reset();
-  }
-
-  /**
-   * @return {!Object.<string, !LayerViewer.PaintProfilerCategory>}
-   */
-  static categories() {
-    if (LayerViewer.PaintProfilerView._categories)
-      return LayerViewer.PaintProfilerView._categories;
-    LayerViewer.PaintProfilerView._categories = {
-      shapes: new LayerViewer.PaintProfilerCategory('shapes', Common.UIString('Shapes'), 'rgb(255, 161, 129)'),
-      bitmap: new LayerViewer.PaintProfilerCategory('bitmap', Common.UIString('Bitmap'), 'rgb(136, 196, 255)'),
-      text: new LayerViewer.PaintProfilerCategory('text', Common.UIString('Text'), 'rgb(180, 255, 137)'),
-      misc: new LayerViewer.PaintProfilerCategory('misc', Common.UIString('Misc'), 'rgb(206, 160, 255)')
-    };
-    return LayerViewer.PaintProfilerView._categories;
-  }
-
-  /**
-   * @return {!Object.<string, !LayerViewer.PaintProfilerCategory>}
-   */
-  static _initLogItemCategories() {
-    if (LayerViewer.PaintProfilerView._logItemCategoriesMap)
-      return LayerViewer.PaintProfilerView._logItemCategoriesMap;
-
-    const categories = LayerViewer.PaintProfilerView.categories();
-
-    const logItemCategories = {};
-    logItemCategories['Clear'] = categories['misc'];
-    logItemCategories['DrawPaint'] = categories['misc'];
-    logItemCategories['DrawData'] = categories['misc'];
-    logItemCategories['SetMatrix'] = categories['misc'];
-    logItemCategories['PushCull'] = categories['misc'];
-    logItemCategories['PopCull'] = categories['misc'];
-    logItemCategories['Translate'] = categories['misc'];
-    logItemCategories['Scale'] = categories['misc'];
-    logItemCategories['Concat'] = categories['misc'];
-    logItemCategories['Restore'] = categories['misc'];
-    logItemCategories['SaveLayer'] = categories['misc'];
-    logItemCategories['Save'] = categories['misc'];
-    logItemCategories['BeginCommentGroup'] = categories['misc'];
-    logItemCategories['AddComment'] = categories['misc'];
-    logItemCategories['EndCommentGroup'] = categories['misc'];
-    logItemCategories['ClipRect'] = categories['misc'];
-    logItemCategories['ClipRRect'] = categories['misc'];
-    logItemCategories['ClipPath'] = categories['misc'];
-    logItemCategories['ClipRegion'] = categories['misc'];
-    logItemCategories['DrawPoints'] = categories['shapes'];
-    logItemCategories['DrawRect'] = categories['shapes'];
-    logItemCategories['DrawOval'] = categories['shapes'];
-    logItemCategories['DrawRRect'] = categories['shapes'];
-    logItemCategories['DrawPath'] = categories['shapes'];
-    logItemCategories['DrawVertices'] = categories['shapes'];
-    logItemCategories['DrawDRRect'] = categories['shapes'];
-    logItemCategories['DrawBitmap'] = categories['bitmap'];
-    logItemCategories['DrawBitmapRectToRect'] = categories['bitmap'];
-    logItemCategories['DrawBitmapMatrix'] = categories['bitmap'];
-    logItemCategories['DrawBitmapNine'] = categories['bitmap'];
-    logItemCategories['DrawSprite'] = categories['bitmap'];
-    logItemCategories['DrawPicture'] = categories['bitmap'];
-    logItemCategories['DrawText'] = categories['text'];
-    logItemCategories['DrawPosText'] = categories['text'];
-    logItemCategories['DrawPosTextH'] = categories['text'];
-    logItemCategories['DrawTextOnPath'] = categories['text'];
-
-    LayerViewer.PaintProfilerView._logItemCategoriesMap = logItemCategories;
-    return logItemCategories;
-  }
-
-  /**
-   * @param {!Object} logItem
-   * @return {!LayerViewer.PaintProfilerCategory}
-   */
-  static _categoryForLogItem(logItem) {
-    const method = logItem.method.toTitleCase();
-
-    const logItemCategories = LayerViewer.PaintProfilerView._initLogItemCategories();
-    let result = logItemCategories[method];
-    if (!result) {
-      result = LayerViewer.PaintProfilerView.categories()['misc'];
-      logItemCategories[method] = result;
-    }
-    return result;
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._update();
-  }
-
-  /**
-   * @param {?SDK.PaintProfilerSnapshot} snapshot
-   * @param {!Array.<!SDK.PaintProfilerLogItem>} log
-   * @param {?Protocol.DOM.Rect} clipRect
-   */
-  async setSnapshotAndLog(snapshot, log, clipRect) {
-    this._reset();
-    this._snapshot = snapshot;
-    if (this._snapshot)
-      this._snapshot.addReference();
-    this._log = log;
-    this._logCategories = this._log.map(LayerViewer.PaintProfilerView._categoryForLogItem);
-
-    if (!this._snapshot) {
-      this._update();
-      this._pieChart.setTotal(0);
-      this._selectionWindow.setEnabled(false);
-      return;
-    }
-    this._selectionWindow.setEnabled(true);
-    this._progressBanner.classList.remove('hidden');
-    this._updateImage();
-
-    const profiles = await snapshot.profile(clipRect);
-
-    this._progressBanner.classList.add('hidden');
-    this._profiles = profiles;
-    this._update();
-    this._updatePieChart();
-  }
-
-  /**
-   * @param {number} scale
-   */
-  setScale(scale) {
-    const needsUpdate = scale > this._scale;
-    const predictiveGrowthFactor = 2;
-    this._pendingScale = Math.min(1, scale * predictiveGrowthFactor);
-    if (needsUpdate && this._snapshot)
-      this._updateImage();
-  }
-
-  _update() {
-    this._canvas.width = this._canvasContainer.clientWidth * window.devicePixelRatio;
-    this._canvas.height = this._canvasContainer.clientHeight * window.devicePixelRatio;
-    this._samplesPerBar = 0;
-    if (!this._profiles || !this._profiles.length)
-      return;
-
-    const maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth) / this._outerBarWidth);
-    const sampleCount = this._log.length;
-    this._samplesPerBar = Math.ceil(sampleCount / maxBars);
-
-    let maxBarTime = 0;
-    const barTimes = [];
-    const barHeightByCategory = [];
-    let heightByCategory = {};
-    for (let i = 0, lastBarIndex = 0, lastBarTime = 0; i < sampleCount;) {
-      let categoryName = (this._logCategories[i] && this._logCategories[i].name) || 'misc';
-      const sampleIndex = this._log[i].commandIndex;
-      for (let row = 0; row < this._profiles.length; row++) {
-        const sample = this._profiles[row][sampleIndex];
-        lastBarTime += sample;
-        heightByCategory[categoryName] = (heightByCategory[categoryName] || 0) + sample;
-      }
-      ++i;
-      if (i - lastBarIndex === this._samplesPerBar || i === sampleCount) {
-        // Normalize by total number of samples accumulated.
-        const factor = this._profiles.length * (i - lastBarIndex);
-        lastBarTime /= factor;
-        for (categoryName in heightByCategory)
-          heightByCategory[categoryName] /= factor;
-
-        barTimes.push(lastBarTime);
-        barHeightByCategory.push(heightByCategory);
-
-        if (lastBarTime > maxBarTime)
-          maxBarTime = lastBarTime;
-        lastBarTime = 0;
-        heightByCategory = {};
-        lastBarIndex = i;
-      }
-    }
-
-    const paddingHeight = 4 * window.devicePixelRatio;
-    const scale = (this._canvas.height - paddingHeight - this._minBarHeight) / maxBarTime;
-    for (let i = 0; i < barTimes.length; ++i) {
-      for (const categoryName in barHeightByCategory[i])
-        barHeightByCategory[i][categoryName] *= (barTimes[i] * scale + this._minBarHeight) / barTimes[i];
-      this._renderBar(i, barHeightByCategory[i]);
-    }
-  }
-
-  /**
-   * @param {number} index
-   * @param {!Object.<string, number>} heightByCategory
-   */
-  _renderBar(index, heightByCategory) {
-    const categories = LayerViewer.PaintProfilerView.categories();
-    let currentHeight = 0;
-    const x = this._barPaddingWidth + index * this._outerBarWidth;
-    for (const categoryName in categories) {
-      if (!heightByCategory[categoryName])
-        continue;
-      currentHeight += heightByCategory[categoryName];
-      const y = this._canvas.height - currentHeight;
-      this._context.fillStyle = categories[categoryName].color;
-      this._context.fillRect(x, y, this._innerBarWidth, heightByCategory[categoryName]);
-    }
-  }
-
-  _onWindowChanged() {
-    this.dispatchEventToListeners(LayerViewer.PaintProfilerView.Events.WindowChanged);
-    this._updatePieChart();
-    if (this._updateImageTimer)
-      return;
-    this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100);
-  }
-
-  _updatePieChart() {
-    const window = this.selectionWindow();
-    if (!this._profiles || !this._profiles.length || !window)
-      return;
-    let totalTime = 0;
-    const timeByCategory = {};
-    for (let i = window.left; i < window.right; ++i) {
-      const logEntry = this._log[i];
-      const category = LayerViewer.PaintProfilerView._categoryForLogItem(logEntry);
-      timeByCategory[category.color] = timeByCategory[category.color] || 0;
-      for (let j = 0; j < this._profiles.length; ++j) {
-        const time = this._profiles[j][logEntry.commandIndex];
-        totalTime += time;
-        timeByCategory[category.color] += time;
-      }
-    }
-    this._pieChart.setTotal(totalTime / this._profiles.length);
-    for (const color in timeByCategory)
-      this._pieChart.addSlice(timeByCategory[color] / this._profiles.length, color);
-  }
-
-  /**
-   * @param {number} value
-   * @return {string}
-   */
-  _formatPieChartTime(value) {
-    return Number.millisToString(value * 1000, true);
-  }
-
-  /**
-   * @return {?{left: number, right: number}}
-   */
-  selectionWindow() {
-    if (!this._log)
-      return null;
-
-    const screenLeft = this._selectionWindow.windowLeft * this._canvas.width;
-    const screenRight = this._selectionWindow.windowRight * this._canvas.width;
-    const barLeft = Math.floor(screenLeft / this._outerBarWidth);
-    const barRight = Math.floor((screenRight + this._innerBarWidth - this._barPaddingWidth / 2) / this._outerBarWidth);
-    const stepLeft = Number.constrain(barLeft * this._samplesPerBar, 0, this._log.length - 1);
-    const stepRight = Number.constrain(barRight * this._samplesPerBar, 0, this._log.length);
-
-    return {left: stepLeft, right: stepRight};
-  }
-
-  _updateImage() {
-    delete this._updateImageTimer;
-    let left;
-    let right;
-    const window = this.selectionWindow();
-    if (this._profiles && this._profiles.length && window) {
-      left = this._log[window.left].commandIndex;
-      right = this._log[window.right - 1].commandIndex;
-    }
-    const scale = this._pendingScale;
-    this._snapshot.replay(scale, left, right).then(image => {
-      if (!image)
-        return;
-      this._scale = scale;
-      this._showImageCallback(image);
-    });
-  }
-
-  _reset() {
-    if (this._snapshot)
-      this._snapshot.release();
-    this._snapshot = null;
-    this._profiles = null;
-    this._selectionWindow.reset();
-    this._selectionWindow.setEnabled(false);
-  }
-};
-
-/** @enum {symbol} */
-LayerViewer.PaintProfilerView.Events = {
-  WindowChanged: Symbol('WindowChanged')
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.PaintProfilerCommandLogView = class extends UI.ThrottledWidget {
-  constructor() {
-    super();
-    this.setMinimumSize(100, 25);
-    this.element.classList.add('overflow-auto');
-
-    this._treeOutline = new UI.TreeOutlineInShadow();
-    this.element.appendChild(this._treeOutline.element);
-
-    this._log = [];
-  }
-
-  /**
-   * @param {!Array.<!SDK.PaintProfilerLogItem>} log
-   */
-  setCommandLog(log) {
-    this._log = log;
-    /** @type {!Map<!SDK.PaintProfilerLogItem>} */
-    this._treeItemCache = new Map();
-    this.updateWindow({left: 0, right: this._log.length});
-  }
-
-  /**
-   * @param {!SDK.PaintProfilerLogItem} logItem
-   */
-  _appendLogItem(logItem) {
-    let treeElement = this._treeItemCache.get(logItem);
-    if (!treeElement) {
-      treeElement = new LayerViewer.LogTreeElement(this, logItem);
-      this._treeItemCache.set(logItem, treeElement);
-    } else if (treeElement.parent) {
-      return;
-    }
-    this._treeOutline.appendChild(treeElement);
-  }
-
-  /**
-   * @param {?{left: number, right: number}} selectionWindow
-   */
-  updateWindow(selectionWindow) {
-    this._selectionWindow = selectionWindow;
-    this.update();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<*>}
-   */
-  doUpdate() {
-    if (!this._selectionWindow || !this._log.length) {
-      this._treeOutline.removeChildren();
-      return Promise.resolve();
-    }
-    const root = this._treeOutline.rootElement();
-    for (;;) {
-      const child = root.firstChild();
-      if (!child || child._logItem.commandIndex >= this._selectionWindow.left)
-        break;
-      root.removeChildAtIndex(0);
-    }
-    for (;;) {
-      const child = root.lastChild();
-      if (!child || child._logItem.commandIndex < this._selectionWindow.right)
-        break;
-      root.removeChildAtIndex(root.children().length - 1);
-    }
-    for (let i = this._selectionWindow.left, right = this._selectionWindow.right; i < right; ++i)
-      this._appendLogItem(this._log[i]);
-    return Promise.resolve();
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LogTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!LayerViewer.PaintProfilerCommandLogView} ownerView
-   * @param {!SDK.PaintProfilerLogItem} logItem
-   */
-  constructor(ownerView, logItem) {
-    super('', !!logItem.params);
-    this._logItem = logItem;
-    this._ownerView = ownerView;
-    this._filled = false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this._update();
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    for (const param in this._logItem.params)
-      LayerViewer.LogPropertyTreeElement._appendLogPropertyItem(this, param, this._logItem.params[param]);
-  }
-
-  /**
-   * @param {*} param
-   * @param {string} name
-   * @return {string}
-   */
-  _paramToString(param, name) {
-    if (typeof param !== 'object')
-      return typeof param === 'string' && param.length > 100 ? name : JSON.stringify(param);
-    let str = '';
-    let keyCount = 0;
-    for (const key in param) {
-      if (++keyCount > 4 || typeof param[key] === 'object' ||
-          (typeof param[key] === 'string' && param[key].length > 100))
-        return name;
-      if (str)
-        str += ', ';
-      str += param[key];
-    }
-    return str;
-  }
-
-  /**
-   * @param {?Object<string, *>} params
-   * @return {string}
-   */
-  _paramsToString(params) {
-    let str = '';
-    for (const key in params) {
-      if (str)
-        str += ', ';
-      str += this._paramToString(params[key], key);
-    }
-    return str;
-  }
-
-  _update() {
-    const title = createDocumentFragment();
-    title.createTextChild(this._logItem.method + '(' + this._paramsToString(this._logItem.params) + ')');
-    this.title = title;
-  }
-};
-
-/**
- * @unrestricted
- */
-LayerViewer.LogPropertyTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!{name: string, value}} property
-   */
-  constructor(property) {
-    super();
-    this._property = property;
-  }
-
-  /**
-   * @param {!UI.TreeElement} element
-   * @param {string} name
-   * @param {*} value
-   */
-  static _appendLogPropertyItem(element, name, value) {
-    const treeElement = new LayerViewer.LogPropertyTreeElement({name: name, value: value});
-    element.appendChild(treeElement);
-    if (value && typeof value === 'object') {
-      for (const property in value)
-        LayerViewer.LogPropertyTreeElement._appendLogPropertyItem(treeElement, property, value[property]);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    const title = createDocumentFragment();
-    const nameElement = title.createChild('span', 'name');
-    nameElement.textContent = this._property.name;
-    const separatorElement = title.createChild('span', 'separator');
-    separatorElement.textContent = ': ';
-    if (this._property.value === null || typeof this._property.value !== 'object') {
-      const valueElement = title.createChild('span', 'value');
-      valueElement.textContent = JSON.stringify(this._property.value);
-      valueElement.classList.add('cm-js-' + (this._property.value === null ? 'null' : typeof this._property.value));
-    }
-    this.title = title;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-LayerViewer.PaintProfilerCategory = class {
-  /**
-   * @param {string} name
-   * @param {string} title
-   * @param {string} color
-   */
-  constructor(name, title, color) {
-    this.name = name;
-    this.title = title;
-    this.color = color;
-  }
-};
diff --git a/front_end/layer_viewer/TransformController.js b/front_end/layer_viewer/TransformController.js
deleted file mode 100644
index a63494b..0000000
--- a/front_end/layer_viewer/TransformController.js
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * @unrestricted
- */
-LayerViewer.TransformController = class extends Common.Object {
-  /**
-   * @param {!Element} element
-   * @param {boolean=} disableRotate
-   */
-  constructor(element, disableRotate) {
-    super();
-    this._shortcuts = {};
-    this.element = element;
-    if (this.element.tabIndex < 0)
-      this.element.tabIndex = 0;
-    this._registerShortcuts();
-    UI.installDragHandle(
-        element, this._onDragStart.bind(this), this._onDrag.bind(this), this._onDragEnd.bind(this), 'move', null);
-    element.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    element.addEventListener('keyup', this._onKeyUp.bind(this), false);
-    element.addEventListener('mousewheel', this._onMouseWheel.bind(this), false);
-    this._minScale = 0;
-    this._maxScale = Infinity;
-
-    this._controlPanelToolbar = new UI.Toolbar('transform-control-panel');
-
-    /** @type {!Object<string, !UI.ToolbarToggle>} */
-    this._modeButtons = {};
-    if (!disableRotate) {
-      const panModeButton = new UI.ToolbarToggle(Common.UIString('Pan mode (X)'), 'largeicon-pan');
-      panModeButton.addEventListener(
-          UI.ToolbarButton.Events.Click, this._setMode.bind(this, LayerViewer.TransformController.Modes.Pan));
-      this._modeButtons[LayerViewer.TransformController.Modes.Pan] = panModeButton;
-      this._controlPanelToolbar.appendToolbarItem(panModeButton);
-      const rotateModeButton = new UI.ToolbarToggle(Common.UIString('Rotate mode (V)'), 'largeicon-rotate');
-      rotateModeButton.addEventListener(
-          UI.ToolbarButton.Events.Click, this._setMode.bind(this, LayerViewer.TransformController.Modes.Rotate));
-      this._modeButtons[LayerViewer.TransformController.Modes.Rotate] = rotateModeButton;
-      this._controlPanelToolbar.appendToolbarItem(rotateModeButton);
-    }
-    this._setMode(LayerViewer.TransformController.Modes.Pan);
-
-    const resetButton = new UI.ToolbarButton(Common.UIString('Reset transform (0)'), 'largeicon-center');
-    resetButton.addEventListener(UI.ToolbarButton.Events.Click, this.resetAndNotify.bind(this, undefined));
-    this._controlPanelToolbar.appendToolbarItem(resetButton);
-
-    this._reset();
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  toolbar() {
-    return this._controlPanelToolbar;
-  }
-
-  _onKeyDown(event) {
-    if (event.keyCode === UI.KeyboardShortcut.Keys.Shift.code) {
-      this._toggleMode();
-      return;
-    }
-
-    const shortcutKey = UI.KeyboardShortcut.makeKeyFromEventIgnoringModifiers(event);
-    const handler = this._shortcuts[shortcutKey];
-    if (handler && handler(event))
-      event.consume();
-  }
-
-  _onKeyUp(event) {
-    if (event.keyCode === UI.KeyboardShortcut.Keys.Shift.code)
-      this._toggleMode();
-  }
-
-  _addShortcuts(keys, handler) {
-    for (let i = 0; i < keys.length; ++i)
-      this._shortcuts[keys[i].key] = handler;
-  }
-
-  _registerShortcuts() {
-    this._addShortcuts(UI.ShortcutsScreen.LayersPanelShortcuts.ResetView, this.resetAndNotify.bind(this));
-    this._addShortcuts(
-        UI.ShortcutsScreen.LayersPanelShortcuts.PanMode,
-        this._setMode.bind(this, LayerViewer.TransformController.Modes.Pan));
-    this._addShortcuts(
-        UI.ShortcutsScreen.LayersPanelShortcuts.RotateMode,
-        this._setMode.bind(this, LayerViewer.TransformController.Modes.Rotate));
-    const zoomFactor = 1.1;
-    this._addShortcuts(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, this._onKeyboardZoom.bind(this, zoomFactor));
-    this._addShortcuts(
-        UI.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, this._onKeyboardZoom.bind(this, 1 / zoomFactor));
-    this._addShortcuts(UI.ShortcutsScreen.LayersPanelShortcuts.Up, this._onKeyboardPanOrRotate.bind(this, 0, -1));
-    this._addShortcuts(UI.ShortcutsScreen.LayersPanelShortcuts.Down, this._onKeyboardPanOrRotate.bind(this, 0, 1));
-    this._addShortcuts(UI.ShortcutsScreen.LayersPanelShortcuts.Left, this._onKeyboardPanOrRotate.bind(this, -1, 0));
-    this._addShortcuts(UI.ShortcutsScreen.LayersPanelShortcuts.Right, this._onKeyboardPanOrRotate.bind(this, 1, 0));
-  }
-
-  _postChangeEvent() {
-    this.dispatchEventToListeners(LayerViewer.TransformController.Events.TransformChanged);
-  }
-
-  _reset() {
-    this._scale = 1;
-    this._offsetX = 0;
-    this._offsetY = 0;
-    this._rotateX = 0;
-    this._rotateY = 0;
-  }
-
-  _toggleMode() {
-    this._setMode(
-        this._mode === LayerViewer.TransformController.Modes.Pan ? LayerViewer.TransformController.Modes.Rotate :
-                                                                   LayerViewer.TransformController.Modes.Pan);
-  }
-
-  /**
-   * @param {!LayerViewer.TransformController.Modes} mode
-   */
-  _setMode(mode) {
-    if (this._mode === mode)
-      return;
-    this._mode = mode;
-    this._updateModeButtons();
-    this.element.focus();
-  }
-
-  _updateModeButtons() {
-    for (const mode in this._modeButtons)
-      this._modeButtons[mode].setToggled(mode === this._mode);
-  }
-
-  /**
-   * @param {!Event=} event
-   */
-  resetAndNotify(event) {
-    this._reset();
-    this._postChangeEvent();
-    if (event)
-      event.preventDefault();
-    this.element.focus();
-  }
-
-  /**
-   * @param {number} minScale
-   * @param {number} maxScale
-   */
-  setScaleConstraints(minScale, maxScale) {
-    this._minScale = minScale;
-    this._maxScale = maxScale;
-    this._scale = Number.constrain(this._scale, minScale, maxScale);
-  }
-
-  /**
-   * @param {number} minX
-   * @param {number} maxX
-   * @param {number} minY
-   * @param {number} maxY
-   */
-  clampOffsets(minX, maxX, minY, maxY) {
-    this._offsetX = Number.constrain(this._offsetX, minX, maxX);
-    this._offsetY = Number.constrain(this._offsetY, minY, maxY);
-  }
-
-  /**
-   * @return {number}
-   */
-  scale() {
-    return this._scale;
-  }
-
-  /**
-   * @return {number}
-   */
-  offsetX() {
-    return this._offsetX;
-  }
-
-  /**
-   * @return {number}
-   */
-  offsetY() {
-    return this._offsetY;
-  }
-
-  /**
-   * @return {number}
-   */
-  rotateX() {
-    return this._rotateX;
-  }
-
-  /**
-   * @return {number}
-   */
-  rotateY() {
-    return this._rotateY;
-  }
-
-  /**
-   * @param {number} scaleFactor
-   * @param {number} x
-   * @param {number} y
-   */
-  _onScale(scaleFactor, x, y) {
-    scaleFactor = Number.constrain(this._scale * scaleFactor, this._minScale, this._maxScale) / this._scale;
-    this._scale *= scaleFactor;
-    this._offsetX -= (x - this._offsetX) * (scaleFactor - 1);
-    this._offsetY -= (y - this._offsetY) * (scaleFactor - 1);
-    this._postChangeEvent();
-  }
-
-  /**
-   * @param {number} offsetX
-   * @param {number} offsetY
-   */
-  _onPan(offsetX, offsetY) {
-    this._offsetX += offsetX;
-    this._offsetY += offsetY;
-    this._postChangeEvent();
-  }
-
-  /**
-   * @param {number} rotateX
-   * @param {number} rotateY
-   */
-  _onRotate(rotateX, rotateY) {
-    this._rotateX = rotateX;
-    this._rotateY = rotateY;
-    this._postChangeEvent();
-  }
-
-  /**
-   * @param {number} zoomFactor
-   */
-  _onKeyboardZoom(zoomFactor) {
-    this._onScale(zoomFactor, this.element.clientWidth / 2, this.element.clientHeight / 2);
-  }
-
-  /**
-   * @param {number} xMultiplier
-   * @param {number} yMultiplier
-   */
-  _onKeyboardPanOrRotate(xMultiplier, yMultiplier) {
-    const panStepInPixels = 6;
-    const rotateStepInDegrees = 5;
-
-    if (this._mode === LayerViewer.TransformController.Modes.Rotate) {
-      // Sic! _onRotate treats X and Y as "rotate around X" and "rotate around Y", so swap X/Y multiplers.
-      this._onRotate(
-          this._rotateX + yMultiplier * rotateStepInDegrees, this._rotateY + xMultiplier * rotateStepInDegrees);
-    } else {
-      this._onPan(xMultiplier * panStepInPixels, yMultiplier * panStepInPixels);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseWheel(event) {
-    /** @const */
-    const zoomFactor = 1.1;
-    /** @const */
-    const mouseWheelZoomSpeed = 1 / 120;
-    const scaleFactor = Math.pow(zoomFactor, event.wheelDeltaY * mouseWheelZoomSpeed);
-    this._onScale(
-        scaleFactor, event.clientX - this.element.totalOffsetLeft(), event.clientY - this.element.totalOffsetTop());
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDrag(event) {
-    if (this._mode === LayerViewer.TransformController.Modes.Rotate) {
-      this._onRotate(
-          this._oldRotateX + (this._originY - event.clientY) / this.element.clientHeight * 180,
-          this._oldRotateY - (this._originX - event.clientX) / this.element.clientWidth * 180);
-    } else {
-      this._onPan(event.clientX - this._originX, event.clientY - this._originY);
-      this._originX = event.clientX;
-      this._originY = event.clientY;
-    }
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _onDragStart(event) {
-    this.element.focus();
-    this._originX = event.clientX;
-    this._originY = event.clientY;
-    this._oldRotateX = this._rotateX;
-    this._oldRotateY = this._rotateY;
-    return true;
-  }
-
-  _onDragEnd() {
-    delete this._originX;
-    delete this._originY;
-    delete this._oldRotateX;
-    delete this._oldRotateY;
-  }
-};
-
-/** @enum {symbol} */
-LayerViewer.TransformController.Events = {
-  TransformChanged: Symbol('TransformChanged')
-};
-
-/**
- * @enum {string}
- */
-LayerViewer.TransformController.Modes = {
-  Pan: 'Pan',
-  Rotate: 'Rotate',
-};
diff --git a/front_end/layer_viewer/layerDetailsView.css b/front_end/layer_viewer/layerDetailsView.css
deleted file mode 100644
index a36c0e4..0000000
--- a/front_end/layer_viewer/layerDetailsView.css
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-table td {
-    padding-left: 8px;
-}
-
-table td:first-child {
-    font-weight: bold;
-}
-
-.scroll-rect.active {
-    background-color: rgba(100, 100, 100, 0.2);
-}
-
-ul {
-    list-style: none;
-    -webkit-padding-start: 0;
-    -webkit-margin-before: 0;
-    -webkit-margin-after: 0;
-}
-
-a {
-    padding: 8px;
-    display: block;
-}
diff --git a/front_end/layer_viewer/layers3DView.css b/front_end/layer_viewer/layers3DView.css
deleted file mode 100644
index a2f93df..0000000
--- a/front_end/layer_viewer/layers3DView.css
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.layers-3d-view {
-    overflow: hidden;
-    -webkit-user-select: none;
-}
-
-.toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-canvas {
-    flex: 1 1;
-}
diff --git a/front_end/layer_viewer/module.json b/front_end/layer_viewer/module.json
deleted file mode 100644
index 0943277..0000000
--- a/front_end/layer_viewer/module.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "dependencies": [
-        "components",
-        "sdk",
-        "timeline_model",
-        "ui",
-        "perf_ui"
-    ],
-    "scripts": [
-        "LayerDetailsView.js",
-        "LayerTreeOutline.js",
-        "LayerViewHost.js",
-        "Layers3DView.js",
-        "PaintProfilerView.js",
-        "TransformController.js"
-    ],
-    "resources": [
-        "layers3DView.css",
-        "paintProfiler.css",
-        "layerDetailsView.css"
-    ]
-}
diff --git a/front_end/layer_viewer/paintProfiler.css b/front_end/layer_viewer/paintProfiler.css
deleted file mode 100644
index 48a06b3..0000000
--- a/front_end/layer_viewer/paintProfiler.css
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.paint-profiler-overview {
-    background-color: #eee;
-}
-
-.paint-profiler-canvas-container {
-    flex: auto;
-    position: relative;
-}
-
-.paint-profiler-pie-chart {
-    width: 60px !important;
-    height: 60px !important;
-    padding: 2px;
-    overflow: hidden;
-    font-size: 10px;
-}
-
-.paint-profiler-canvas-container canvas {
-    z-index: 200;
-    background-color: white;
-    opacity: 0.95;
-    height: 100%;
-    width: 100%;
-}
-
-.paint-profiler-canvas-container .overview-grid-dividers-background,
-.paint-profiler-canvas-container .overview-grid-window {
-    bottom: 0;
-    height: auto;
-}
-
-.paint-profiler-canvas-container .overview-grid-window-resizer {
-    z-index: 2000;
-}
diff --git a/front_end/layers/LayerPaintProfilerView.js b/front_end/layers/LayerPaintProfilerView.js
deleted file mode 100644
index 629ff48..0000000
--- a/front_end/layers/LayerPaintProfilerView.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Layers.LayerPaintProfilerView = class extends UI.SplitWidget {
-  /**
-   * @param {function(string=)} showImageCallback
-   */
-  constructor(showImageCallback) {
-    super(true, false);
-
-    this._logTreeView = new LayerViewer.PaintProfilerCommandLogView();
-    this.setSidebarWidget(this._logTreeView);
-    this._paintProfilerView = new LayerViewer.PaintProfilerView(showImageCallback);
-    this.setMainWidget(this._paintProfilerView);
-
-    this._paintProfilerView.addEventListener(
-        LayerViewer.PaintProfilerView.Events.WindowChanged, this._onWindowChanged, this);
-  }
-
-  reset() {
-    this._paintProfilerView.setSnapshotAndLog(null, [], null);
-  }
-
-  /**
-   * @param {!SDK.PaintProfilerSnapshot} snapshot
-   */
-  profile(snapshot) {
-    snapshot.commandLog().then(log => setSnapshotAndLog.call(this, snapshot, log));
-
-    /**
-     * @param {?SDK.PaintProfilerSnapshot} snapshot
-     * @param {?Array<!SDK.PaintProfilerLogItem>} log
-     * @this {Layers.LayerPaintProfilerView}
-     */
-    function setSnapshotAndLog(snapshot, log) {
-      this._logTreeView.setCommandLog(log || []);
-      this._paintProfilerView.setSnapshotAndLog(snapshot, log || [], null);
-      if (snapshot)
-        snapshot.release();
-    }
-  }
-
-  /**
-   * @param {number} scale
-   */
-  setScale(scale) {
-    this._paintProfilerView.setScale(scale);
-  }
-
-  _onWindowChanged() {
-    this._logTreeView.updateWindow(this._paintProfilerView.selectionWindow());
-  }
-};
diff --git a/front_end/layers/LayerTreeModel.js b/front_end/layers/LayerTreeModel.js
deleted file mode 100644
index db9d6e1..0000000
--- a/front_end/layers/LayerTreeModel.js
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Layers.LayerTreeModel = class extends SDK.SDKModel {
-  constructor(target) {
-    super(target);
-    this._layerTreeAgent = target.layerTreeAgent();
-    target.registerLayerTreeDispatcher(new Layers.LayerTreeDispatcher(this));
-    this._paintProfilerModel = /** @type {!SDK.PaintProfilerModel} */ (target.model(SDK.PaintProfilerModel));
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (resourceTreeModel) {
-      resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
-    }
-    /** @type {?SDK.LayerTreeBase} */
-    this._layerTree = null;
-    this._throttler = new Common.Throttler(20);
-  }
-
-  disable() {
-    if (!this._enabled)
-      return;
-    this._enabled = false;
-    this._layerTreeAgent.disable();
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-    this._enabled = true;
-    this._forceEnable();
-  }
-
-  _forceEnable() {
-    this._lastPaintRectByLayerId = {};
-    if (!this._layerTree)
-      this._layerTree = new Layers.AgentLayerTree(this);
-    this._layerTreeAgent.enable();
-  }
-
-  /**
-   * @return {?SDK.LayerTreeBase}
-   */
-  layerTree() {
-    return this._layerTree;
-  }
-
-  /**
-   * @param {?Array.<!Protocol.LayerTree.Layer>} layers
-   */
-  async _layerTreeChanged(layers) {
-    if (!this._enabled)
-      return;
-    this._throttler.schedule(this._innerSetLayers.bind(this, layers));
-  }
-
-  /**
-   * @param {?Array.<!Protocol.LayerTree.Layer>} layers
-   */
-  async _innerSetLayers(layers) {
-    const layerTree = /** @type {!Layers.AgentLayerTree} */ (this._layerTree);
-
-    await layerTree.setLayers(layers);
-
-    for (const layerId in this._lastPaintRectByLayerId) {
-      const lastPaintRect = this._lastPaintRectByLayerId[layerId];
-      const layer = layerTree.layerById(layerId);
-      if (layer)
-        layer._lastPaintRect = lastPaintRect;
-    }
-    this._lastPaintRectByLayerId = {};
-
-    this.dispatchEventToListeners(Layers.LayerTreeModel.Events.LayerTreeChanged);
-  }
-
-  /**
-   * @param {!Protocol.LayerTree.LayerId} layerId
-   * @param {!Protocol.DOM.Rect} clipRect
-   */
-  _layerPainted(layerId, clipRect) {
-    if (!this._enabled)
-      return;
-    const layerTree = /** @type {!Layers.AgentLayerTree} */ (this._layerTree);
-    const layer = layerTree.layerById(layerId);
-    if (!layer) {
-      this._lastPaintRectByLayerId[layerId] = clipRect;
-      return;
-    }
-    layer._didPaint(clipRect);
-    this.dispatchEventToListeners(Layers.LayerTreeModel.Events.LayerPainted, layer);
-  }
-
-  _onMainFrameNavigated() {
-    this._layerTree = null;
-    if (this._enabled)
-      this._forceEnable();
-  }
-};
-
-SDK.SDKModel.register(Layers.LayerTreeModel, SDK.Target.Capability.DOM, false);
-
-/** @enum {symbol} */
-Layers.LayerTreeModel.Events = {
-  LayerTreeChanged: Symbol('LayerTreeChanged'),
-  LayerPainted: Symbol('LayerPainted'),
-};
-
-/**
- * @unrestricted
- */
-Layers.AgentLayerTree = class extends SDK.LayerTreeBase {
-  /**
-   * @param {!Layers.LayerTreeModel} layerTreeModel
-   */
-  constructor(layerTreeModel) {
-    super(layerTreeModel.target());
-    this._layerTreeModel = layerTreeModel;
-  }
-
-  /**
-   * @param {?Array<!Protocol.LayerTree.Layer>} payload
-   * @return {!Promise}
-   */
-  async setLayers(payload) {
-    if (!payload) {
-      this._innerSetLayers(payload);
-      return;
-    }
-    const idsToResolve = new Set();
-    for (let i = 0; i < payload.length; ++i) {
-      const backendNodeId = payload[i].backendNodeId;
-      if (!backendNodeId || this.backendNodeIdToNode().has(backendNodeId))
-        continue;
-      idsToResolve.add(backendNodeId);
-    }
-    await this.resolveBackendNodeIds(idsToResolve);
-    this._innerSetLayers(payload);
-  }
-
-  /**
-   * @param {?Array.<!Protocol.LayerTree.Layer>} layers
-   */
-  _innerSetLayers(layers) {
-    this.setRoot(null);
-    this.setContentRoot(null);
-    // Payload will be null when not in the composited mode.
-    if (!layers)
-      return;
-    let root;
-    const oldLayersById = this._layersById;
-    this._layersById = {};
-    for (let i = 0; i < layers.length; ++i) {
-      const layerId = layers[i].layerId;
-      let layer = oldLayersById[layerId];
-      if (layer)
-        layer._reset(layers[i]);
-      else
-        layer = new Layers.AgentLayer(this._layerTreeModel, layers[i]);
-      this._layersById[layerId] = layer;
-      const backendNodeId = layers[i].backendNodeId;
-      if (backendNodeId)
-        layer._setNode(this.backendNodeIdToNode().get(backendNodeId));
-      if (!this.contentRoot() && layer.drawsContent())
-        this.setContentRoot(layer);
-      const parentId = layer.parentId();
-      if (parentId) {
-        const parent = this._layersById[parentId];
-        if (!parent)
-          console.assert(parent, 'missing parent ' + parentId + ' for layer ' + layerId);
-        parent.addChild(layer);
-      } else {
-        if (root)
-          console.assert(false, 'Multiple root layers');
-        root = layer;
-      }
-    }
-    if (root) {
-      this.setRoot(root);
-      root._calculateQuad(new WebKitCSSMatrix());
-    }
-  }
-};
-
-/**
- * @implements {SDK.Layer}
- * @unrestricted
- */
-Layers.AgentLayer = class {
-  /**
-   * @param {!Layers.LayerTreeModel} layerTreeModel
-   * @param {!Protocol.LayerTree.Layer} layerPayload
-   */
-  constructor(layerTreeModel, layerPayload) {
-    this._layerTreeModel = layerTreeModel;
-    this._reset(layerPayload);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  id() {
-    return this._layerPayload.layerId;
-  }
-
-  /**
-   * @override
-   * @return {?string}
-   */
-  parentId() {
-    return this._layerPayload.parentLayerId;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.Layer}
-   */
-  parent() {
-    return this._parent;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isRoot() {
-    return !this.parentId();
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!SDK.Layer>}
-   */
-  children() {
-    return this._children;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Layer} child
-   */
-  addChild(child) {
-    if (child._parent)
-      console.assert(false, 'Child already has a parent');
-    this._children.push(child);
-    child._parent = this;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  _setNode(node) {
-    this._node = node;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.DOMNode}
-   */
-  nodeForSelfOrAncestor() {
-    for (let layer = this; layer; layer = layer._parent) {
-      if (layer._node)
-        return layer._node;
-    }
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  offsetX() {
-    return this._layerPayload.offsetX;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  offsetY() {
-    return this._layerPayload.offsetY;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  width() {
-    return this._layerPayload.width;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  height() {
-    return this._layerPayload.height;
-  }
-
-  /**
-   * @override
-   * @return {?Array.<number>}
-   */
-  transform() {
-    return this._layerPayload.transform;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<number>}
-   */
-  quad() {
-    return this._quad;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<number>}
-   */
-  anchorPoint() {
-    return [
-      this._layerPayload.anchorX || 0,
-      this._layerPayload.anchorY || 0,
-      this._layerPayload.anchorZ || 0,
-    ];
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  invisible() {
-    return this._layerPayload.invisible;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  paintCount() {
-    return this._paintCount || this._layerPayload.paintCount;
-  }
-
-  /**
-   * @override
-   * @return {?Protocol.DOM.Rect}
-   */
-  lastPaintRect() {
-    return this._lastPaintRect;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Protocol.LayerTree.ScrollRect>}
-   */
-  scrollRects() {
-    return this._scrollRects;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.Layer.StickyPositionConstraint}
-   */
-  stickyPositionConstraint() {
-    return this._stickyPositionConstraint;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<!Array<string>>}
-   */
-  async requestCompositingReasons() {
-    const reasons = await this._layerTreeModel._layerTreeAgent.compositingReasons(this.id());
-    return reasons || [];
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  drawsContent() {
-    return this._layerPayload.drawsContent;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  gpuMemoryUsage() {
-    /**
-     * @const
-     */
-    const bytesPerPixel = 4;
-    return this.drawsContent() ? this.width() * this.height() * bytesPerPixel : 0;
-  }
-
-  /**
-   * @override
-   * @return {!Array<!Promise<?SDK.SnapshotWithRect>>}
-   */
-  snapshots() {
-    const promise = this._layerTreeModel._paintProfilerModel.makeSnapshot(this.id()).then(snapshot => {
-      if (!snapshot)
-        return null;
-      return {rect: {x: 0, y: 0, width: this.width(), height: this.height()}, snapshot: snapshot};
-    });
-    return [promise];
-  }
-
-  /**
-   * @param {!Protocol.DOM.Rect} rect
-   */
-  _didPaint(rect) {
-    this._lastPaintRect = rect;
-    this._paintCount = this.paintCount() + 1;
-    this._image = null;
-  }
-
-  /**
-   * @param {!Protocol.LayerTree.Layer} layerPayload
-   */
-  _reset(layerPayload) {
-    /** @type {?SDK.DOMNode} */
-    this._node = null;
-    this._children = [];
-    this._parent = null;
-    this._paintCount = 0;
-    this._layerPayload = layerPayload;
-    this._image = null;
-    this._scrollRects = this._layerPayload.scrollRects || [];
-    this._stickyPositionConstraint = this._layerPayload.stickyPositionConstraint ?
-        new SDK.Layer.StickyPositionConstraint(
-            this._layerTreeModel.layerTree(), this._layerPayload.stickyPositionConstraint) :
-        null;
-  }
-
-  /**
-   * @param {!Array.<number>} a
-   * @return {!CSSMatrix}
-   */
-  _matrixFromArray(a) {
-    function toFixed9(x) {
-      return x.toFixed(9);
-    }
-    return new WebKitCSSMatrix('matrix3d(' + a.map(toFixed9).join(',') + ')');
-  }
-
-  /**
-   * @param {!CSSMatrix} parentTransform
-   * @return {!CSSMatrix}
-   */
-  _calculateTransformToViewport(parentTransform) {
-    const offsetMatrix = new WebKitCSSMatrix().translate(this._layerPayload.offsetX, this._layerPayload.offsetY);
-    let matrix = offsetMatrix;
-
-    if (this._layerPayload.transform) {
-      const transformMatrix = this._matrixFromArray(this._layerPayload.transform);
-      const anchorVector = new UI.Geometry.Vector(
-          this._layerPayload.width * this.anchorPoint()[0], this._layerPayload.height * this.anchorPoint()[1],
-          this.anchorPoint()[2]);
-      const anchorPoint = UI.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector, matrix);
-      const anchorMatrix = new WebKitCSSMatrix().translate(-anchorPoint.x, -anchorPoint.y, -anchorPoint.z);
-      matrix = anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));
-    }
-
-    matrix = parentTransform.multiply(matrix);
-    return matrix;
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   * @return {!Array.<number>}
-   */
-  _createVertexArrayForRect(width, height) {
-    return [0, 0, 0, width, 0, 0, width, height, 0, 0, height, 0];
-  }
-
-  /**
-   * @param {!CSSMatrix} parentTransform
-   */
-  _calculateQuad(parentTransform) {
-    const matrix = this._calculateTransformToViewport(parentTransform);
-    this._quad = [];
-    const vertices = this._createVertexArrayForRect(this._layerPayload.width, this._layerPayload.height);
-    for (let i = 0; i < 4; ++i) {
-      const point = UI.Geometry.multiplyVectorByMatrixAndNormalize(
-          new UI.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
-      this._quad.push(point.x, point.y);
-    }
-
-    function calculateQuadForLayer(layer) {
-      layer._calculateQuad(matrix);
-    }
-
-    this._children.forEach(calculateQuadForLayer);
-  }
-};
-
-/**
- * @implements {Protocol.LayerTreeDispatcher}
- * @unrestricted
- */
-Layers.LayerTreeDispatcher = class {
-  /**
-   * @param {!Layers.LayerTreeModel} layerTreeModel
-   */
-  constructor(layerTreeModel) {
-    this._layerTreeModel = layerTreeModel;
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!Protocol.LayerTree.Layer>=} layers
-   */
-  layerTreeDidChange(layers) {
-    this._layerTreeModel._layerTreeChanged(layers || null);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.LayerTree.LayerId} layerId
-   * @param {!Protocol.DOM.Rect} clipRect
-   */
-  layerPainted(layerId, clipRect) {
-    this._layerTreeModel._layerPainted(layerId, clipRect);
-  }
-};
diff --git a/front_end/layers/LayersPanel.js b/front_end/layers/LayersPanel.js
deleted file mode 100644
index 413c0e0..0000000
--- a/front_end/layers/LayersPanel.js
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-Layers.LayersPanel = class extends UI.PanelWithSidebar {
-  constructor() {
-    super('layers', 225);
-
-    /** @type {?Layers.LayerTreeModel} */
-    this._model = null;
-
-    SDK.targetManager.observeTargets(this);
-    this._layerViewHost = new LayerViewer.LayerViewHost();
-    this._layerTreeOutline = new LayerViewer.LayerTreeOutline(this._layerViewHost);
-    this.panelSidebarElement().appendChild(this._layerTreeOutline.element);
-    this.setDefaultFocusedElement(this._layerTreeOutline.element);
-
-    this._rightSplitWidget = new UI.SplitWidget(false, true, 'layerDetailsSplitViewState');
-    this.splitWidget().setMainWidget(this._rightSplitWidget);
-
-    this._layers3DView = new LayerViewer.Layers3DView(this._layerViewHost);
-    this._rightSplitWidget.setMainWidget(this._layers3DView);
-    this._layers3DView.addEventListener(
-        LayerViewer.Layers3DView.Events.PaintProfilerRequested, this._onPaintProfileRequested, this);
-    this._layers3DView.addEventListener(LayerViewer.Layers3DView.Events.ScaleChanged, this._onScaleChanged, this);
-
-    this._tabbedPane = new UI.TabbedPane();
-    this._rightSplitWidget.setSidebarWidget(this._tabbedPane);
-
-    this._layerDetailsView = new LayerViewer.LayerDetailsView(this._layerViewHost);
-    this._layerDetailsView.addEventListener(
-        LayerViewer.LayerDetailsView.Events.PaintProfilerRequested, this._onPaintProfileRequested, this);
-    this._tabbedPane.appendTab(
-        Layers.LayersPanel.DetailsViewTabs.Details, Common.UIString('Details'), this._layerDetailsView);
-
-    this._paintProfilerView = new Layers.LayerPaintProfilerView(this._showImage.bind(this));
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabClosed, this._onTabClosed, this);
-    this._updateThrottler = new Common.Throttler(100);
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._layerTreeOutline.focus();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    if (this._model)
-      this._model.enable();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    if (this._model)
-      this._model.disable();
-    super.willHide();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    if (this._model)
-      return;
-    this._model = target.model(Layers.LayerTreeModel);
-    if (!this._model)
-      return;
-    this._model.addEventListener(Layers.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
-    this._model.addEventListener(Layers.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
-    if (this.isShowing())
-      this._model.enable();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    if (!this._model || this._model.target() !== target)
-      return;
-    this._model.removeEventListener(Layers.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
-    this._model.removeEventListener(Layers.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
-    this._model.disable();
-    this._model = null;
-  }
-
-  _onLayerTreeUpdated() {
-    this._updateThrottler.schedule(this._update.bind(this));
-  }
-
-  /**
-   * @return {!Promise<*>}
-   */
-  _update() {
-    if (this._model)
-      this._layerViewHost.setLayerTree(this._model.layerTree());
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onLayerPainted(event) {
-    if (!this._model)
-      return;
-    const layer = /** @type {!SDK.Layer} */ (event.data);
-    if (this._layerViewHost.selection() && this._layerViewHost.selection().layer() === layer)
-      this._layerDetailsView.update();
-    this._layers3DView.updateLayerSnapshot(layer);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onPaintProfileRequested(event) {
-    const selection = /** @type {!LayerViewer.LayerView.Selection} */ (event.data);
-    this._layers3DView.snapshotForSelection(selection).then(snapshotWithRect => {
-      if (!snapshotWithRect)
-        return;
-      this._layerBeingProfiled = selection.layer();
-      if (!this._tabbedPane.hasTab(Layers.LayersPanel.DetailsViewTabs.Profiler)) {
-        this._tabbedPane.appendTab(
-            Layers.LayersPanel.DetailsViewTabs.Profiler, Common.UIString('Profiler'), this._paintProfilerView,
-            undefined, true, true);
-      }
-      this._tabbedPane.selectTab(Layers.LayersPanel.DetailsViewTabs.Profiler);
-      this._paintProfilerView.profile(snapshotWithRect.snapshot);
-    });
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onTabClosed(event) {
-    if (event.data.tabId !== Layers.LayersPanel.DetailsViewTabs.Profiler || !this._layerBeingProfiled)
-      return;
-    this._paintProfilerView.reset();
-    this._layers3DView.showImageForLayer(this._layerBeingProfiled, undefined);
-    this._layerBeingProfiled = null;
-  }
-
-  /**
-   * @param {string=} imageURL
-   */
-  _showImage(imageURL) {
-    this._layers3DView.showImageForLayer(this._layerBeingProfiled, imageURL);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onScaleChanged(event) {
-    this._paintProfilerView.setScale(/** @type {number} */ (event.data));
-  }
-};
-
-Layers.LayersPanel.DetailsViewTabs = {
-  Details: 'details',
-  Profiler: 'profiler'
-};
diff --git a/front_end/layers/module.json b/front_end/layers/module.json
deleted file mode 100644
index 1778f3b..0000000
--- a/front_end/layers/module.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "layers",
-            "title": "Layers",
-            "order": 100,
-            "persistence": "closeable",
-            "className": "Layers.LayersPanel"
-        }
-    ],
-    "dependencies": ["layer_viewer"],
-    "scripts": [
-        "LayerPaintProfilerView.js",
-        "LayerTreeModel.js",
-        "LayersPanel.js"
-    ]
-}
diff --git a/front_end/layers_test_runner/LayersTestRunner.js b/front_end/layers_test_runner/LayersTestRunner.js
deleted file mode 100644
index d5c69d7..0000000
--- a/front_end/layers_test_runner/LayersTestRunner.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-LayersTestRunner.layerTreeModel = function() {
-  if (!LayersTestRunner._layerTreeModel)
-    LayersTestRunner._layerTreeModel = TestRunner.mainTarget.model(Layers.LayerTreeModel);
-
-  return LayersTestRunner._layerTreeModel;
-};
-
-LayersTestRunner.labelForLayer = function(layer) {
-  const node = layer.nodeForSelfOrAncestor();
-  let label = (node ? Elements.DOMPath.fullQualifiedSelector(node, false) : '<invalid node id>');
-  const height = layer.height();
-  const width = layer.width();
-
-  if (height <= 200 && width <= 200)
-    label += ' ' + height + 'x' + width;
-
-  if (typeof layer.__extraData !== 'undefined')
-    label += ' (' + layer.__extraData + ')';
-
-  return label;
-};
-
-LayersTestRunner.dumpLayerTree = function(prefix, root) {
-  if (!prefix)
-    prefix = '';
-
-  if (!root) {
-    root = LayersTestRunner.layerTreeModel().layerTree().contentRoot();
-
-    if (!root) {
-      TestRunner.addResult('No layer root, perhaps not in the composited mode! ');
-      TestRunner.completeTest();
-      return;
-    }
-  }
-
-  TestRunner.addResult(prefix + LayersTestRunner.labelForLayer(root));
-  root.children().forEach(LayersTestRunner.dumpLayerTree.bind(LayersTestRunner, prefix + '    '));
-};
-
-LayersTestRunner.dumpLayers3DView = function(prefix, root) {
-  if (!prefix)
-    prefix = '';
-
-  if (!root)
-    root = UI.panels.layers._layers3DView._rotatingContainerElement;
-
-  if (root.__layer)
-    TestRunner.addResult(prefix + LayersTestRunner.labelForLayer(root.__layer));
-
-  for (let element = root.firstElementChild; element; element = element.nextSibling)
-    LayersTestRunner.dumpLayers3DView(prefix + '    ', element);
-};
-
-LayersTestRunner.evaluateAndWaitForTreeChange = async function(expression) {
-  await TestRunner.evaluateInPageAnonymously(expression);
-  return LayersTestRunner.layerTreeModel().once(Layers.LayerTreeModel.Events.LayerTreeChanged);
-};
-
-LayersTestRunner.findLayerByNodeIdAttribute = function(nodeIdAttribute) {
-  let result;
-
-  function testLayer(layer) {
-    const node = layer.node();
-
-    if (!node)
-      return false;
-
-    if (!node || node.getAttribute('id') !== nodeIdAttribute)
-      return false;
-
-    result = layer;
-    return true;
-  }
-
-  LayersTestRunner.layerTreeModel().layerTree().forEachLayer(testLayer);
-
-  if (!result)
-    TestRunner.addResult('ERROR: No layer for ' + nodeIdAttribute);
-
-  return result;
-};
-
-LayersTestRunner.requestLayers = function() {
-  LayersTestRunner.layerTreeModel().enable();
-  return LayersTestRunner.layerTreeModel().once(Layers.LayerTreeModel.Events.LayerTreeChanged);
-};
-
-LayersTestRunner.dispatchMouseEvent = function(eventType, button, element, offsetX, offsetY) {
-  const totalOffset = element.totalOffset();
-
-  const eventArguments = {
-    bubbles: true,
-    cancelable: true,
-    view: window,
-    screenX: totalOffset.left - element.scrollLeft + offsetX,
-    screenY: totalOffset.top - element.scrollTop + offsetY,
-    clientX: totalOffset.left + offsetX,
-    clientY: totalOffset.top + offsetY,
-    button: button
-  };
-
-  if (eventType === 'mouseout') {
-    eventArguments.screenX = 0;
-    eventArguments.screenY = 0;
-    eventArguments.clientX = 0;
-    eventArguments.clientY = 0;
-  }
-
-  element.dispatchEvent(new MouseEvent(eventType, eventArguments));
-};
-
-LayersTestRunner.findLayerTreeElement = function(layer) {
-  const element = layer[LayerViewer.LayerTreeElement._symbol];
-  element.reveal();
-  return element.listItemElement;
-};
-
-LayersTestRunner.dispatchMouseEventToLayerTree = function(eventType, button, layer) {
-  const element = LayersTestRunner.findLayerTreeElement(layer);
-  TestRunner.assertTrue(!!element);
-  LayersTestRunner.dispatchMouseEvent(eventType, button, element, element.clientWidth >> 1, element.clientHeight >> 1);
-};
-
-LayersTestRunner.dumpSelectedStyles = function(message, element) {
-  const classes = [];
-  if (element.classList.contains('selected'))
-    classes.push('selected');
-  if (element.classList.contains('hovered'))
-    classes.push('hovered');
-
-  TestRunner.addResult(message + ': ' + classes.join(', '));
-};
diff --git a/front_end/layers_test_runner/module.json b/front_end/layers_test_runner/module.json
deleted file mode 100644
index 5cb7257..0000000
--- a/front_end/layers_test_runner/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "layers",
-    "elements",
-    "components"
-  ],
-  "scripts": [
-    "LayersTestRunner.js"
-  ],
-  "skip_compilation": [
-    "LayersTestRunner.js"
-  ]
-}
diff --git a/front_end/main/ExecutionContextSelector.js b/front_end/main/ExecutionContextSelector.js
deleted file mode 100644
index 52740f0..0000000
--- a/front_end/main/ExecutionContextSelector.js
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-Main.ExecutionContextSelector = class {
-  /**
-   * @param {!SDK.TargetManager} targetManager
-   * @param {!UI.Context} context
-   */
-  constructor(targetManager, context) {
-    targetManager.observeTargets(this, SDK.Target.Capability.JS);
-    context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this);
-    context.addFlavorChangeListener(SDK.Target, this._targetChanged, this);
-
-    targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
-    targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
-    targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextOrderChanged, this._onExecutionContextOrderChanged,
-        this);
-    this._targetManager = targetManager;
-    this._context = context;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    // Defer selecting default target since we need all clients to get their
-    // targetAdded notifications first.
-    setImmediate(deferred.bind(this));
-
-    /**
-     * @this {Main.ExecutionContextSelector}
-     */
-    function deferred() {
-      // We always want the second context for the service worker targets.
-      if (!this._context.flavor(SDK.Target))
-        this._context.setFlavor(SDK.Target, target);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    const currentExecutionContext = this._context.flavor(SDK.ExecutionContext);
-    if (currentExecutionContext && currentExecutionContext.target() === target)
-      this._currentExecutionContextGone();
-
-    const targets = this._targetManager.targets(SDK.Target.Capability.JS);
-    if (this._context.flavor(SDK.Target) === target && targets.length)
-      this._context.setFlavor(SDK.Target, targets[0]);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _executionContextChanged(event) {
-    const newContext = /** @type {?SDK.ExecutionContext} */ (event.data);
-    if (newContext) {
-      this._context.setFlavor(SDK.Target, newContext.target());
-      if (!this._ignoreContextChanged)
-        this._lastSelectedContextId = this._contextPersistentId(newContext);
-    }
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {string}
-   */
-  _contextPersistentId(executionContext) {
-    return executionContext.isDefault ? executionContext.target().name() + ':' + executionContext.frameId : '';
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _targetChanged(event) {
-    const newTarget = /** @type {?SDK.Target} */ (event.data);
-    const currentContext = this._context.flavor(SDK.ExecutionContext);
-
-    if (!newTarget || (currentContext && currentContext.target() === newTarget))
-      return;
-
-    const runtimeModel = newTarget.model(SDK.RuntimeModel);
-    const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
-    if (!executionContexts.length)
-      return;
-
-    let newContext = null;
-    for (let i = 0; i < executionContexts.length && !newContext; ++i) {
-      if (this._shouldSwitchToContext(executionContexts[i]))
-        newContext = executionContexts[i];
-    }
-    for (let i = 0; i < executionContexts.length && !newContext; ++i) {
-      if (this._isDefaultContext(executionContexts[i]))
-        newContext = executionContexts[i];
-    }
-    this._ignoreContextChanged = true;
-    this._context.setFlavor(SDK.ExecutionContext, newContext || executionContexts[0]);
-    this._ignoreContextChanged = false;
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {boolean}
-   */
-  _shouldSwitchToContext(executionContext) {
-    if (this._lastSelectedContextId && this._lastSelectedContextId === this._contextPersistentId(executionContext))
-      return true;
-    if (!this._lastSelectedContextId && this._isDefaultContext(executionContext))
-      return true;
-    return false;
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {boolean}
-   */
-  _isDefaultContext(executionContext) {
-    if (!executionContext.isDefault || !executionContext.frameId)
-      return false;
-    if (executionContext.target().parentTarget())
-      return false;
-    const resourceTreeModel = executionContext.target().model(SDK.ResourceTreeModel);
-    const frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId);
-    if (frame && frame.isTopFrame())
-      return true;
-    return false;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onExecutionContextCreated(event) {
-    this._switchContextIfNecessary(/** @type {!SDK.ExecutionContext} */ (event.data));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onExecutionContextDestroyed(event) {
-    const executionContext = /** @type {!SDK.ExecutionContext}*/ (event.data);
-    if (this._context.flavor(SDK.ExecutionContext) === executionContext)
-      this._currentExecutionContextGone();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onExecutionContextOrderChanged(event) {
-    const runtimeModel = /** @type {!SDK.RuntimeModel} */ (event.data);
-    const executionContexts = runtimeModel.executionContexts();
-    for (let i = 0; i < executionContexts.length; i++) {
-      if (this._switchContextIfNecessary(executionContexts[i]))
-        break;
-    }
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {boolean}
-   */
-  _switchContextIfNecessary(executionContext) {
-    if (!this._context.flavor(SDK.ExecutionContext) || this._shouldSwitchToContext(executionContext)) {
-      this._ignoreContextChanged = true;
-      this._context.setFlavor(SDK.ExecutionContext, executionContext);
-      this._ignoreContextChanged = false;
-      return true;
-    }
-    return false;
-  }
-
-  _currentExecutionContextGone() {
-    const runtimeModels = this._targetManager.models(SDK.RuntimeModel);
-    let newContext = null;
-    for (let i = 0; i < runtimeModels.length && !newContext; ++i) {
-      const executionContexts = runtimeModels[i].executionContexts();
-      for (const executionContext of executionContexts) {
-        if (this._isDefaultContext(executionContext)) {
-          newContext = executionContext;
-          break;
-        }
-      }
-    }
-    if (!newContext) {
-      for (let i = 0; i < runtimeModels.length && !newContext; ++i) {
-        const executionContexts = runtimeModels[i].executionContexts();
-        if (executionContexts.length) {
-          newContext = executionContexts[0];
-          break;
-        }
-      }
-    }
-    this._ignoreContextChanged = true;
-    this._context.setFlavor(SDK.ExecutionContext, newContext);
-    this._ignoreContextChanged = false;
-  }
-};
diff --git a/front_end/main/Main.js b/front_end/main/Main.js
deleted file mode 100644
index c6b19c0..0000000
--- a/front_end/main/Main.js
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Main.Main = class {
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  constructor() {
-    Main.Main._instanceForTest = this;
-    runOnWindowLoad(this._loaded.bind(this));
-  }
-
-  /**
-   * @param {string} label
-   */
-  static time(label) {
-    if (Host.isUnderTest())
-      return;
-    console.time(label);
-  }
-
-  /**
-   * @param {string} label
-   */
-  static timeEnd(label) {
-    if (Host.isUnderTest())
-      return;
-    console.timeEnd(label);
-  }
-
-  async _loaded() {
-    console.timeStamp('Main._loaded');
-    await Runtime.runtimeReady();
-    Runtime.setPlatform(Host.platform());
-    InspectorFrontendHost.getPreferences(this._gotPreferences.bind(this));
-  }
-
-  /**
-   * @param {!Object<string, string>} prefs
-   */
-  _gotPreferences(prefs) {
-    console.timeStamp('Main._gotPreferences');
-    if (Host.isUnderTest(prefs))
-      self.runtime.useTestBase();
-    this._createSettings(prefs);
-    this._createAppUI();
-  }
-
-  /**
-   * @param {!Object<string, string>} prefs
-   * Note: this function is called from testSettings in Tests.js.
-   */
-  _createSettings(prefs) {
-    this._initializeExperiments();
-    let storagePrefix = '';
-    if (Host.isCustomDevtoolsFrontend())
-      storagePrefix = '__custom__';
-    else if (!Runtime.queryParam('can_dock') && !!Runtime.queryParam('debugFrontend') && !Host.isUnderTest())
-      storagePrefix = '__bundled__';
-
-    let localStorage;
-    if (!Host.isUnderTest() && window.localStorage) {
-      localStorage = new Common.SettingsStorage(
-          window.localStorage, undefined, undefined, () => window.localStorage.clear(), storagePrefix);
-    } else {
-      localStorage = new Common.SettingsStorage({}, undefined, undefined, undefined, storagePrefix);
-    }
-    const globalStorage = new Common.SettingsStorage(
-        prefs, InspectorFrontendHost.setPreference, InspectorFrontendHost.removePreference,
-        InspectorFrontendHost.clearPreferences, storagePrefix);
-    Common.settings = new Common.Settings(globalStorage, localStorage);
-    if (!Host.isUnderTest())
-      new Common.VersionController().updateVersion();
-  }
-
-  _initializeExperiments() {
-    // Keep this sorted alphabetically: both keys and values.
-    Runtime.experiments.register('applyCustomStylesheet', 'Allow custom UI themes');
-    Runtime.experiments.register('blackboxJSFramesOnTimeline', 'Blackbox JavaScript frames on Timeline', true);
-    Runtime.experiments.register('colorContrastRatio', 'Color contrast ratio line in color picker', true);
-    Runtime.experiments.register('emptySourceMapAutoStepping', 'Empty sourcemap auto-stepping');
-    Runtime.experiments.register('inputEventsOnTimelineOverview', 'Input events on Timeline overview', true);
-    Runtime.experiments.register('nativeHeapProfiler', 'Native memory sampling heap profiler', true);
-    Runtime.experiments.register('networkSearch', 'Network search');
-    Runtime.experiments.register('oopifInlineDOM', 'OOPIF: inline DOM ', true);
-    Runtime.experiments.register('protocolMonitor', 'Protocol Monitor');
-    Runtime.experiments.register('sourceDiff', 'Source diff');
-    Runtime.experiments.register(
-        'stepIntoAsync', 'Introduce separate step action, stepInto becomes powerful enough to go inside async call');
-    Runtime.experiments.register('terminalInDrawer', 'Terminal in drawer', true);
-
-    // Timeline
-    Runtime.experiments.register('timelineEventInitiators', 'Timeline: event initiators');
-    Runtime.experiments.register('timelineFlowEvents', 'Timeline: flow events', true);
-    Runtime.experiments.register('timelineInvalidationTracking', 'Timeline: invalidation tracking', true);
-    Runtime.experiments.register('timelinePaintTimingMarkers', 'Timeline: paint timing markers', true);
-    Runtime.experiments.register('timelineShowAllEvents', 'Timeline: show all events', true);
-    Runtime.experiments.register('timelineShowAllProcesses', 'Timeline: show all processes', true);
-    Runtime.experiments.register('timelineTracingJSProfile', 'Timeline: tracing based JS profiler', true);
-    Runtime.experiments.register('timelineV8RuntimeCallStats', 'Timeline: V8 Runtime Call Stats on Timeline', true);
-
-    Runtime.experiments.cleanUpStaleExperiments();
-
-    if (Host.isUnderTest()) {
-      const testPath = Runtime.queryParam('test');
-      // Enable experiments for testing.
-      if (testPath.indexOf('oopif/') !== -1)
-        Runtime.experiments.enableForTest('oopifInlineDOM');
-      if (testPath.indexOf('network/') !== -1)
-        Runtime.experiments.enableForTest('networkSearch');
-    }
-
-    Runtime.experiments.setDefaultExperiments(['colorContrastRatio', 'stepIntoAsync', 'oopifInlineDOM']);
-  }
-
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  async _createAppUI() {
-    Main.Main.time('Main._createAppUI');
-
-    UI.viewManager = new UI.ViewManager();
-
-    // Request filesystems early, we won't create connections until callback is fired. Things will happen in parallel.
-    Persistence.isolatedFileSystemManager = new Persistence.IsolatedFileSystemManager();
-
-    const themeSetting = Common.settings.createSetting('uiTheme', 'default');
-    UI.initializeUIUtils(document, themeSetting);
-    themeSetting.addChangeListener(Components.reload.bind(Components));
-
-    UI.installComponentRootStyles(/** @type {!Element} */ (document.body));
-
-    this._addMainEventListeners(document);
-
-    const canDock = !!Runtime.queryParam('can_dock');
-    UI.zoomManager = new UI.ZoomManager(window, InspectorFrontendHost);
-    UI.inspectorView = UI.InspectorView.instance();
-    UI.ContextMenu.initialize();
-    UI.ContextMenu.installHandler(document);
-    UI.Tooltip.installHandler(document);
-    Components.dockController = new Components.DockController(canDock);
-    SDK.consoleModel = new SDK.ConsoleModel();
-    SDK.multitargetNetworkManager = new SDK.MultitargetNetworkManager();
-    SDK.domDebuggerManager = new SDK.DOMDebuggerManager();
-    SDK.targetManager.addEventListener(
-        SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged.bind(this));
-
-    UI.shortcutsScreen = new UI.ShortcutsScreen();
-    // set order of some sections explicitly
-    UI.shortcutsScreen.section(Common.UIString('Elements Panel'));
-    UI.shortcutsScreen.section(Common.UIString('Styles Pane'));
-    UI.shortcutsScreen.section(Common.UIString('Debugger'));
-    UI.shortcutsScreen.section(Common.UIString('Console'));
-
-    Workspace.fileManager = new Workspace.FileManager();
-    Workspace.workspace = new Workspace.Workspace();
-
-    Bindings.networkProjectManager = new Bindings.NetworkProjectManager();
-    Bindings.resourceMapping = new Bindings.ResourceMapping(SDK.targetManager, Workspace.workspace);
-    new Bindings.PresentationConsoleMessageManager();
-    Bindings.cssWorkspaceBinding = new Bindings.CSSWorkspaceBinding(SDK.targetManager, Workspace.workspace);
-    Bindings.debuggerWorkspaceBinding = new Bindings.DebuggerWorkspaceBinding(SDK.targetManager, Workspace.workspace);
-    Bindings.breakpointManager =
-        new Bindings.BreakpointManager(Workspace.workspace, SDK.targetManager, Bindings.debuggerWorkspaceBinding);
-    Extensions.extensionServer = new Extensions.ExtensionServer();
-
-    new Persistence.FileSystemWorkspaceBinding(Persistence.isolatedFileSystemManager, Workspace.workspace);
-    Persistence.persistence = new Persistence.Persistence(Workspace.workspace, Bindings.breakpointManager);
-    Persistence.networkPersistenceManager = new Persistence.NetworkPersistenceManager(Workspace.workspace);
-
-    new Main.ExecutionContextSelector(SDK.targetManager, UI.context);
-    Bindings.blackboxManager = new Bindings.BlackboxManager(Bindings.debuggerWorkspaceBinding);
-
-    new Main.Main.PauseListener();
-
-    UI.actionRegistry = new UI.ActionRegistry();
-    UI.shortcutRegistry = new UI.ShortcutRegistry(UI.actionRegistry, document);
-    UI.ShortcutsScreen.registerShortcuts();
-    this._registerForwardedShortcuts();
-    this._registerMessageSinkListener();
-
-    Main.Main.timeEnd('Main._createAppUI');
-    this._showAppUI(await self.runtime.extension(Common.AppProvider).instance());
-  }
-
-  /**
-   * @param {!Object} appProvider
-   * @suppressGlobalPropertiesCheck
-   */
-  _showAppUI(appProvider) {
-    Main.Main.time('Main._showAppUI');
-    const app = /** @type {!Common.AppProvider} */ (appProvider).createApp();
-    // It is important to kick controller lifetime after apps are instantiated.
-    Components.dockController.initialize();
-    app.presentUI(document);
-
-    const toggleSearchNodeAction = UI.actionRegistry.action('elements.toggle-element-search');
-    // TODO: we should not access actions from other modules.
-    if (toggleSearchNodeAction) {
-      InspectorFrontendHost.events.addEventListener(
-          InspectorFrontendHostAPI.Events.EnterInspectElementMode,
-          toggleSearchNodeAction.execute.bind(toggleSearchNodeAction), this);
-    }
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.RevealSourceLine, this._revealSourceLine, this);
-
-    UI.inspectorView.createToolbars();
-    InspectorFrontendHost.loadCompleted();
-
-    const extensions = self.runtime.extensions(Common.QueryParamHandler);
-    for (const extension of extensions) {
-      const value = Runtime.queryParam(extension.descriptor()['name']);
-      if (value !== null)
-        extension.instance().then(handleQueryParam.bind(null, value));
-    }
-
-    /**
-     * @param {string} value
-     * @param {!Common.QueryParamHandler} handler
-     */
-    function handleQueryParam(value, handler) {
-      handler.handleQueryParam(value);
-    }
-
-    // Allow UI cycles to repaint prior to creating connection.
-    setTimeout(this._initializeTarget.bind(this), 0);
-    Main.Main.timeEnd('Main._showAppUI');
-  }
-
-  async _initializeTarget() {
-    Main.Main.time('Main._initializeTarget');
-    const instances =
-        await Promise.all(self.runtime.extensions('early-initialization').map(extension => extension.instance()));
-    for (const instance of instances)
-      /** @type {!Common.Runnable} */ (instance).run();
-    // Used for browser tests.
-    InspectorFrontendHost.readyForTest();
-    // Asynchronously run the extensions.
-    setTimeout(this._lateInitialization.bind(this), 100);
-    Main.Main.timeEnd('Main._initializeTarget');
-  }
-
-  _lateInitialization() {
-    Main.Main.time('Main._lateInitialization');
-    this._registerShortcuts();
-    Extensions.extensionServer.initializeExtensions();
-    if (!Host.isUnderTest()) {
-      for (const extension of self.runtime.extensions('late-initialization'))
-        extension.instance().then(instance => (/** @type {!Common.Runnable} */ (instance)).run());
-    }
-    Main.Main.timeEnd('Main._lateInitialization');
-  }
-
-  _registerForwardedShortcuts() {
-    /** @const */ const forwardedActions = [
-      'main.toggle-dock', 'debugger.toggle-breakpoints-active', 'debugger.toggle-pause', 'commandMenu.show',
-      'console.show'
-    ];
-    const actionKeys =
-        UI.shortcutRegistry.keysForActions(forwardedActions).map(UI.KeyboardShortcut.keyCodeAndModifiersFromKey);
-    InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
-  }
-
-  _registerMessageSinkListener() {
-    Common.console.addEventListener(Common.Console.Events.MessageAdded, messageAdded);
-
-    /**
-     * @param {!Common.Event} event
-     */
-    function messageAdded(event) {
-      const message = /** @type {!Common.Console.Message} */ (event.data);
-      if (message.show)
-        Common.console.show();
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _revealSourceLine(event) {
-    const url = /** @type {string} */ (event.data['url']);
-    const lineNumber = /** @type {number} */ (event.data['lineNumber']);
-    const columnNumber = /** @type {number} */ (event.data['columnNumber']);
-
-    const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
-    if (uiSourceCode) {
-      Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
-      return;
-    }
-
-    /**
-     * @param {!Common.Event} event
-     */
-    function listener(event) {
-      const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-      if (uiSourceCode.url() === url) {
-        Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
-        Workspace.workspace.removeEventListener(Workspace.Workspace.Events.UISourceCodeAdded, listener);
-      }
-    }
-
-    Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, listener);
-  }
-
-  _registerShortcuts() {
-    const shortcut = UI.KeyboardShortcut;
-    const section = UI.shortcutsScreen.section(Common.UIString('All Panels'));
-    let keys = [
-      shortcut.makeDescriptor('[', shortcut.Modifiers.CtrlOrMeta),
-      shortcut.makeDescriptor(']', shortcut.Modifiers.CtrlOrMeta)
-    ];
-    section.addRelatedKeys(keys, Common.UIString('Go to the panel to the left/right'));
-
-    const toggleConsoleLabel = Common.UIString('Show console');
-    section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
-    section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), Common.UIString('Toggle drawer'));
-    if (Components.dockController.canDock()) {
-      section.addKey(
-          shortcut.makeDescriptor('M', shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift),
-          Common.UIString('Toggle device mode'));
-      section.addKey(
-          shortcut.makeDescriptor('D', shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Shift),
-          Common.UIString('Toggle dock side'));
-    }
-    section.addKey(shortcut.makeDescriptor('f', shortcut.Modifiers.CtrlOrMeta), Common.UIString('Search'));
-
-    const advancedSearchShortcutModifier = Host.isMac() ?
-        UI.KeyboardShortcut.Modifiers.Meta | UI.KeyboardShortcut.Modifiers.Alt :
-        UI.KeyboardShortcut.Modifiers.Ctrl | UI.KeyboardShortcut.Modifiers.Shift;
-    const advancedSearchShortcut = shortcut.makeDescriptor('f', advancedSearchShortcutModifier);
-    section.addKey(advancedSearchShortcut, Common.UIString('Search across all sources'));
-
-    const inspectElementModeShortcuts =
-        UI.shortcutRegistry.shortcutDescriptorsForAction('elements.toggle-element-search');
-    if (inspectElementModeShortcuts.length)
-      section.addKey(inspectElementModeShortcuts[0], Common.UIString('Select node to inspect'));
-
-    const openResourceShortcut = UI.KeyboardShortcut.makeDescriptor('p', UI.KeyboardShortcut.Modifiers.CtrlOrMeta);
-    section.addKey(openResourceShortcut, Common.UIString('Go to source'));
-
-    if (Host.isMac()) {
-      keys = [
-        shortcut.makeDescriptor('g', shortcut.Modifiers.Meta),
-        shortcut.makeDescriptor('g', shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
-      ];
-      section.addRelatedKeys(keys, Common.UIString('Find next/previous'));
-    }
-  }
-
-  _postDocumentKeyDown(event) {
-    if (event.handled)
-      return;
-
-    if (!UI.Dialog.hasInstance() && UI.inspectorView.currentPanelDeprecated()) {
-      UI.inspectorView.currentPanelDeprecated().handleShortcut(event);
-      if (event.handled) {
-        event.consume(true);
-        return;
-      }
-    }
-
-    UI.shortcutRegistry.handleShortcut(event);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _redispatchClipboardEvent(event) {
-    const eventCopy = new CustomEvent('clipboard-' + event.type, {bubbles: true});
-    eventCopy['original'] = event;
-    const document = event.target && event.target.ownerDocument;
-    const target = document ? document.deepActiveElement() : null;
-    if (target)
-      target.dispatchEvent(eventCopy);
-    if (eventCopy.handled)
-      event.preventDefault();
-  }
-
-  _contextMenuEventFired(event) {
-    if (event.handled || event.target.classList.contains('popup-glasspane'))
-      event.preventDefault();
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  _addMainEventListeners(document) {
-    document.addEventListener('keydown', this._postDocumentKeyDown.bind(this), false);
-    document.addEventListener('beforecopy', this._redispatchClipboardEvent.bind(this), true);
-    document.addEventListener('copy', this._redispatchClipboardEvent.bind(this), false);
-    document.addEventListener('cut', this._redispatchClipboardEvent.bind(this), false);
-    document.addEventListener('paste', this._redispatchClipboardEvent.bind(this), false);
-    document.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), true);
-  }
-
-  _onSuspendStateChanged() {
-    const suspended = SDK.targetManager.allTargetsSuspended();
-    UI.inspectorView.onSuspendStateChanged(suspended);
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Main.Main.ZoomActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    if (InspectorFrontendHost.isHostedMode())
-      return false;
-
-    switch (actionId) {
-      case 'main.zoom-in':
-        InspectorFrontendHost.zoomIn();
-        return true;
-      case 'main.zoom-out':
-        InspectorFrontendHost.zoomOut();
-        return true;
-      case 'main.zoom-reset':
-        InspectorFrontendHost.resetZoom();
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Main.Main.SearchActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   * @suppressGlobalPropertiesCheck
-   */
-  handleAction(context, actionId) {
-    const searchableView = UI.SearchableView.fromElement(document.deepActiveElement()) ||
-        UI.inspectorView.currentPanelDeprecated().searchableView();
-    if (!searchableView)
-      return false;
-    switch (actionId) {
-      case 'main.search-in-panel.find':
-        return searchableView.handleFindShortcut();
-      case 'main.search-in-panel.cancel':
-        return searchableView.handleCancelSearchShortcut();
-      case 'main.search-in-panel.find-next':
-        return searchableView.handleFindNextShortcut();
-      case 'main.search-in-panel.find-previous':
-        return searchableView.handleFindPreviousShortcut();
-    }
-    return false;
-  }
-};
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- */
-Main.Main.MainMenuItem = class {
-  constructor() {
-    this._item = new UI.ToolbarMenuButton(this._handleContextMenu.bind(this), true);
-    this._item.setTitle(Common.UIString('Customize and control DevTools'));
-  }
-
-  /**
-   * @override
-   * @return {?UI.ToolbarItem}
-   */
-  item() {
-    return this._item;
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _handleContextMenu(contextMenu) {
-    if (Components.dockController.canDock()) {
-      const dockItemElement = createElementWithClass('div', 'flex-centered flex-auto');
-      const titleElement = dockItemElement.createChild('span', 'flex-auto');
-      titleElement.textContent = Common.UIString('Dock side');
-      const toggleDockSideShorcuts = UI.shortcutRegistry.shortcutDescriptorsForAction('main.toggle-dock');
-      titleElement.title = Common.UIString(
-          'Placement of DevTools relative to the page. (%s to restore last position)', toggleDockSideShorcuts[0].name);
-      dockItemElement.appendChild(titleElement);
-      const dockItemToolbar = new UI.Toolbar('', dockItemElement);
-      dockItemToolbar.makeBlueOnHover();
-      const undock = new UI.ToolbarToggle(Common.UIString('Undock into separate window'), 'largeicon-undock');
-      const bottom = new UI.ToolbarToggle(Common.UIString('Dock to bottom'), 'largeicon-dock-to-bottom');
-      const right = new UI.ToolbarToggle(Common.UIString('Dock to right'), 'largeicon-dock-to-right');
-      const left = new UI.ToolbarToggle(Common.UIString('Dock to left'), 'largeicon-dock-to-left');
-      undock.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
-      bottom.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
-      right.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
-      left.addEventListener(UI.ToolbarButton.Events.MouseDown, event => event.data.consume());
-      undock.addEventListener(
-          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.Undocked));
-      bottom.addEventListener(
-          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.DockedToBottom));
-      right.addEventListener(
-          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.DockedToRight));
-      left.addEventListener(
-          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.DockedToLeft));
-      undock.setToggled(Components.dockController.dockSide() === Components.DockController.State.Undocked);
-      bottom.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToBottom);
-      right.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToRight);
-      left.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToLeft);
-      dockItemToolbar.appendToolbarItem(undock);
-      dockItemToolbar.appendToolbarItem(left);
-      dockItemToolbar.appendToolbarItem(bottom);
-      dockItemToolbar.appendToolbarItem(right);
-      contextMenu.headerSection().appendCustomItem(dockItemElement);
-    }
-
-    /**
-     * @param {string} side
-     */
-    function setDockSide(side) {
-      Components.dockController.setDockSide(side);
-      contextMenu.discard();
-    }
-
-    if (Components.dockController.dockSide() === Components.DockController.State.Undocked &&
-        SDK.targetManager.mainTarget() && SDK.targetManager.mainTarget().hasBrowserCapability())
-      contextMenu.defaultSection().appendAction('inspector_main.focus-debuggee', Common.UIString('Focus debuggee'));
-
-    contextMenu.defaultSection().appendAction(
-        'main.toggle-drawer',
-        UI.inspectorView.drawerVisible() ? Common.UIString('Hide console drawer') :
-                                           Common.UIString('Show console drawer'));
-    contextMenu.appendItemsAtLocation('mainMenu');
-    const moreTools = contextMenu.defaultSection().appendSubMenuItem(Common.UIString('More tools'));
-    const extensions = self.runtime.extensions('view', undefined, true);
-    for (const extension of extensions) {
-      const descriptor = extension.descriptor();
-      if (descriptor['persistence'] !== 'closeable')
-        continue;
-      if (descriptor['location'] !== 'drawer-view' && descriptor['location'] !== 'panel')
-        continue;
-      moreTools.defaultSection().appendItem(
-          extension.title(), UI.viewManager.showView.bind(UI.viewManager, descriptor['id']));
-    }
-
-    const helpSubMenu = contextMenu.footerSection().appendSubMenuItem(Common.UIString('Help'));
-    helpSubMenu.appendItemsAtLocation('mainMenuHelp');
-  }
-};
-
-/**
- * @unrestricted
- */
-Main.Main.PauseListener = class {
-  constructor() {
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _debuggerPaused(event) {
-    SDK.targetManager.removeModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    const debuggerPausedDetails = debuggerModel.debuggerPausedDetails();
-    UI.context.setFlavor(SDK.Target, debuggerModel.target());
-    Common.Revealer.reveal(debuggerPausedDetails);
-  }
-};
-
-/**
- * @param {string} method
- * @param {?Object} params
- * @return {!Promise}
- */
-Main.sendOverProtocol = function(method, params) {
-  return new Promise((resolve, reject) => {
-    Protocol.InspectorBackend.sendRawMessageForTesting(method, params, (err, ...results) => {
-      if (err)
-        return reject(err);
-      return resolve(results);
-    });
-  });
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Main.ReloadActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    switch (actionId) {
-      case 'main.debug-reload':
-        Components.reload();
-        return true;
-    }
-    return false;
-  }
-};
-
-new Main.Main();
diff --git a/front_end/main/SimpleApp.js b/front_end/main/SimpleApp.js
deleted file mode 100644
index d257d23..0000000
--- a/front_end/main/SimpleApp.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Common.App}
- * @unrestricted
- */
-Main.SimpleApp = class {
-  /**
-   * @override
-   * @param {!Document} document
-   */
-  presentUI(document) {
-    const rootView = new UI.RootView();
-    UI.inspectorView.show(rootView.element);
-    rootView.attachToDocument(document);
-    rootView.focus();
-  }
-};
-
-/**
- * @implements {Common.AppProvider}
- * @unrestricted
- */
-Main.SimpleAppProvider = class {
-  /**
-   * @override
-   * @return {!Common.App}
-   */
-  createApp() {
-    return new Main.SimpleApp();
-  }
-};
diff --git a/front_end/main/module.json b/front_end/main/module.json
deleted file mode 100644
index c51f586..0000000
--- a/front_end/main/module.json
+++ /dev/null
@@ -1,310 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@Common.AppProvider",
-            "className": "Main.SimpleAppProvider",
-            "order": 10
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "Workspace.UISourceCode",
-                "SDK.Resource",
-                "SDK.NetworkRequest"
-            ],
-            "className": "Components.Linkifier.ContentProviderContextMenuProvider"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "Node"
-            ],
-            "className": "UI.XLink.ContextMenuProvider"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "Node"
-            ],
-            "className": "Components.Linkifier.LinkContextMenuProvider"
-        },
-        {
-            "type": "action",
-            "category": "Drawer",
-            "actionId": "inspector_main.focus-debuggee",
-            "className": "InspectorMain.FocusDebuggeeActionDelegate",
-            "order": 100,
-            "title": "Focus debuggee",
-            "bindings": [
-                {
-                    "shortcut": "F12"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Drawer",
-            "actionId": "main.toggle-drawer",
-            "className": "UI.InspectorView.DrawerToggleActionDelegate",
-            "order": 101,
-            "title": "Toggle drawer",
-            "bindings": [
-                {
-                    "shortcut": "Esc"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.debug-reload",
-            "className": "Main.ReloadActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "Alt+R"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "DevTools",
-            "title": "Restore last dock position",
-            "actionId": "main.toggle-dock",
-            "className": "Components.DockController.ToggleDockActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Shift+D"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Shift+D"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.zoom-in",
-            "className": "Main.Main.ZoomActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Plus Ctrl+Shift+Plus Ctrl+NumpadPlus Ctrl+Shift+NumpadPlus"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Plus Meta+Shift+Plus Meta+NumpadPlus Meta+Shift+NumpadPlus"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.zoom-out",
-            "className": "Main.Main.ZoomActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Minus Ctrl+Shift+Minus Ctrl+NumpadMinus Ctrl+Shift+NumpadMinus"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Minus Meta+Shift+Minus Meta+NumpadMinus Meta+Shift+NumpadMinus"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.zoom-reset",
-            "className": "Main.Main.ZoomActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+0 Ctrl+Numpad0"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+0 Meta+Numpad0"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.search-in-panel.find",
-            "className": "Main.Main.SearchActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+F"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+F F3"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.search-in-panel.cancel",
-            "className": "Main.Main.SearchActionDelegate",
-            "order": 10,
-            "bindings": [
-                {
-                    "shortcut": "Esc"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.search-in-panel.find-next",
-            "className": "Main.Main.SearchActionDelegate",
-            "bindings": [
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+G"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "main.search-in-panel.find-previous",
-            "className": "Main.Main.SearchActionDelegate",
-            "bindings": [
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Shift+G"
-                }
-            ]
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "separator": true,
-            "location": "main-toolbar-left",
-            "order": 100
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "separator": true,
-            "order": 98,
-            "location": "main-toolbar-right"
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "Main.Main.MainMenuItem",
-            "order": 99,
-            "location": "main-toolbar-right"
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "Components.DockController.CloseButtonProvider",
-            "order": 100,
-            "location": "main-toolbar-right"
-        },
-        {
-            "type": "setting",
-            "category": "Appearance",
-            "title": "Theme:",
-            "settingName": "uiTheme",
-            "settingType": "enum",
-            "defaultValue": "default",
-            "options": [
-                {
-                    "title": "Switch to light theme",
-                    "text": "Light",
-                    "value": "default"
-                },
-                {
-                    "title": "Switch to dark theme",
-                    "text": "Dark",
-                    "value": "dark"
-                }
-            ],
-            "tags": "dark, light"
-        },
-        {
-            "type": "setting",
-            "category": "Appearance",
-            "title": "Panel layout:",
-            "settingName": "sidebarPosition",
-            "settingType": "enum",
-            "defaultValue": "auto",
-            "options": [
-                {
-                    "title": "Use horizontal panel layout",
-                    "text": "horizontal",
-                    "value": "bottom"
-                },
-                {
-                    "title": "Use vertical panel layout",
-                    "text": "vertical",
-                    "value": "right"
-                },
-                {
-                    "title": "Use automatic panel layout",
-                    "text": "auto",
-                    "value": "auto"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Appearance",
-            "title": "Enable Ctrl + 1-9 shortcut to switch panels",
-            "title-mac": "Enable \u2318 + 1-9 shortcut to switch panels",
-            "settingName": "shortcutPanelSwitch",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "@UI.SettingUI",
-            "category": "Extensions",
-            "className": "Components.Linkifier.LinkHandlerSettingUI"
-        },
-        {
-            "type": "setting",
-            "category": "DevTools",
-            "settingName": "currentDockState",
-            "settingType": "enum",
-            "defaultValue": "right",
-            "options": [
-                {
-                    "value": "right",
-                    "text": "Right",
-                    "title": "Dock to right"
-                },
-                {
-                    "value": "bottom",
-                    "text": "Bottom",
-                    "title": "Dock to bottom"
-                },
-                {
-                    "value": "undocked",
-                    "text": "Undocked",
-                    "title": "Undock into separate window"
-                }
-            ]
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "drawer-view",
-            "category": "Drawer",
-            "className": "UI.InspectorView"
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "panel",
-            "category": "Panel",
-            "className": "UI.InspectorView"
-        }
-    ],
-    "dependencies": [
-        "extensions",
-        "host",
-        "platform",
-        "sdk",
-        "persistence"
-    ],
-    "scripts": [
-        "SimpleApp.js",
-        "ExecutionContextSelector.js",
-        "Main.js"
-    ]
-}
diff --git a/front_end/mobile_throttling/MobileThrottlingSelector.js b/front_end/mobile_throttling/MobileThrottlingSelector.js
deleted file mode 100644
index b7c246f..0000000
--- a/front_end/mobile_throttling/MobileThrottlingSelector.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-MobileThrottling.MobileThrottlingSelector = class {
-  /**
-   * @param {function(!Array<!MobileThrottling.MobileThrottlingConditionsGroup>):!MobileThrottling.ConditionsList} populateCallback
-   * @param {function(number)} selectCallback
-   */
-  constructor(populateCallback, selectCallback) {
-    this._populateCallback = populateCallback;
-    this._selectCallback = selectCallback;
-    MobileThrottling.throttlingManager().addEventListener(
-        MobileThrottling.ThrottlingManager.Events.RateChanged, this._conditionsChanged, this);
-    SDK.multitargetNetworkManager.addEventListener(
-        SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._conditionsChanged, this);
-    /** @type {!MobileThrottling.ConditionsList} */
-    this._options = this._populateOptions();
-    this._conditionsChanged();
-  }
-
-  /**
-   * @param {!MobileThrottling.Conditions} conditions
-   */
-  optionSelected(conditions) {
-    SDK.multitargetNetworkManager.setNetworkConditions(conditions.network);
-    MobileThrottling.throttlingManager().setCPUThrottlingRate(conditions.cpuThrottlingRate);
-  }
-
-  /**
-   * @return {!MobileThrottling.ConditionsList}
-   */
-  _populateOptions() {
-    const disabledGroup = {title: Common.UIString('Disabled'), items: [MobileThrottling.NoThrottlingConditions]};
-    const presetsGroup = {title: Common.UIString('Presets'), items: MobileThrottling.mobilePresets};
-    const advancedGroup = {title: Common.UIString('Advanced'), items: MobileThrottling.advancedMobilePresets};
-    return this._populateCallback([disabledGroup, presetsGroup, advancedGroup]);
-  }
-
-  _conditionsChanged() {
-    const networkConditions = SDK.multitargetNetworkManager.networkConditions();
-    const cpuThrottlingRate = MobileThrottling.throttlingManager().cpuThrottlingRate();
-    for (let index = 0; index < this._options.length; ++index) {
-      const option = this._options[index];
-      if (option && option.network === networkConditions && option.cpuThrottlingRate === cpuThrottlingRate) {
-        this._selectCallback(index);
-        return;
-      }
-    }
-    this._selectCallback(this._options.indexOf(MobileThrottling.CustomConditions));
-  }
-};
diff --git a/front_end/mobile_throttling/NetworkPanelIndicator.js b/front_end/mobile_throttling/NetworkPanelIndicator.js
deleted file mode 100644
index a3de20b..0000000
--- a/front_end/mobile_throttling/NetworkPanelIndicator.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-MobileThrottling.NetworkPanelIndicator = class {
-  constructor() {
-    // TODO: we should not access network from other modules.
-    if (!UI.inspectorView.hasPanel('network'))
-      return;
-    const manager = SDK.multitargetNetworkManager;
-    manager.addEventListener(SDK.MultitargetNetworkManager.Events.ConditionsChanged, updateVisibility);
-    manager.addEventListener(SDK.MultitargetNetworkManager.Events.BlockedPatternsChanged, updateVisibility);
-    manager.addEventListener(SDK.MultitargetNetworkManager.Events.InterceptorsChanged, updateVisibility);
-    updateVisibility();
-
-    function updateVisibility() {
-      let icon = null;
-      if (manager.isThrottling()) {
-        icon = UI.Icon.create('smallicon-warning');
-        icon.title = Common.UIString('Network throttling is enabled');
-      } else if (SDK.multitargetNetworkManager.isIntercepting()) {
-        icon = UI.Icon.create('smallicon-warning');
-        icon.title = Common.UIString('Requests may be rewritten');
-      } else if (manager.isBlocking()) {
-        icon = UI.Icon.create('smallicon-warning');
-        icon.title = Common.UIString('Requests may be blocked');
-      }
-      UI.inspectorView.setPanelIcon('network', icon);
-    }
-  }
-};
diff --git a/front_end/mobile_throttling/NetworkThrottlingSelector.js b/front_end/mobile_throttling/NetworkThrottlingSelector.js
deleted file mode 100644
index cb1290f..0000000
--- a/front_end/mobile_throttling/NetworkThrottlingSelector.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-MobileThrottling.NetworkThrottlingSelector = class {
-  /**
-   * @param {function(!Array<!MobileThrottling.NetworkThrottlingConditionsGroup>):!Array<?SDK.NetworkManager.Conditions>} populateCallback
-   * @param {function(number)} selectCallback
-   * @param {!Common.Setting<!Array<!SDK.NetworkManager.Conditions>>} customNetworkConditionsSetting
-   */
-  constructor(populateCallback, selectCallback, customNetworkConditionsSetting) {
-    this._populateCallback = populateCallback;
-    this._selectCallback = selectCallback;
-    this._customNetworkConditionsSetting = customNetworkConditionsSetting;
-    this._customNetworkConditionsSetting.addChangeListener(this._populateOptions, this);
-    SDK.multitargetNetworkManager.addEventListener(
-        SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._networkConditionsChanged, this);
-    /** @type {!Array<?SDK.NetworkManager.Conditions>} */
-    this._options;
-    this._populateOptions();
-  }
-
-  revealAndUpdate() {
-    Common.Revealer.reveal(this._customNetworkConditionsSetting);
-    this._networkConditionsChanged();
-  }
-
-  /**
-   * @param {!SDK.NetworkManager.Conditions} conditions
-   */
-  optionSelected(conditions) {
-    SDK.multitargetNetworkManager.setNetworkConditions(conditions);
-  }
-
-  _populateOptions() {
-    const disabledGroup = {title: Common.UIString('Disabled'), items: [SDK.NetworkManager.NoThrottlingConditions]};
-    const presetsGroup = {title: Common.UIString('Presets'), items: MobileThrottling.networkPresets};
-    const customGroup = {title: Common.UIString('Custom'), items: this._customNetworkConditionsSetting.get()};
-    this._options = this._populateCallback([disabledGroup, presetsGroup, customGroup]);
-    if (!this._networkConditionsChanged()) {
-      for (let i = this._options.length - 1; i >= 0; i--) {
-        if (this._options[i]) {
-          this.optionSelected(/** @type {!SDK.NetworkManager.Conditions} */ (this._options[i]));
-          break;
-        }
-      }
-    }
-  }
-
-  /**
-   * @return {boolean} returns false if selected condition no longer exists
-   */
-  _networkConditionsChanged() {
-    const value = SDK.multitargetNetworkManager.networkConditions();
-    for (let index = 0; index < this._options.length; ++index) {
-      const option = this._options[index];
-      if (option && option.download === value.download && option.upload === value.upload &&
-          option.latency === value.latency && option.title === value.title) {
-        this._selectCallback(index);
-        return true;
-      }
-    }
-    return false;
-  }
-};
diff --git a/front_end/mobile_throttling/ThrottlingManager.js b/front_end/mobile_throttling/ThrottlingManager.js
deleted file mode 100644
index ab8834b..0000000
--- a/front_end/mobile_throttling/ThrottlingManager.js
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.EmulationModel>}
- */
-MobileThrottling.ThrottlingManager = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!MobileThrottling.CPUThrottlingRates} */
-    this._cpuThrottlingRate = MobileThrottling.CPUThrottlingRates.NoThrottling;
-    /** @type {!Set<!UI.ToolbarComboBox>} */
-    this._cpuThrottlingControls = new Set();
-    this._cpuThrottlingRates = MobileThrottling.cpuThrottlingPresets;
-    /** @type {!Common.Setting<!Array<!SDK.NetworkManager.Conditions>>} */
-    this._customNetworkConditionsSetting = Common.moduleSetting('customNetworkConditions');
-    /** @type {!SDK.NetworkManager.Conditions} */
-    this._currentNetworkThrottlingConditions = SDK.NetworkManager.NoThrottlingConditions;
-    /** @type {!SDK.NetworkManager.Conditions} */
-    this._lastNetworkThrottlingConditions;
-
-    SDK.multitargetNetworkManager.addEventListener(SDK.MultitargetNetworkManager.Events.ConditionsChanged, () => {
-      this._lastNetworkThrottlingConditions = this._currentNetworkThrottlingConditions;
-      this._currentNetworkThrottlingConditions = SDK.multitargetNetworkManager.networkConditions();
-    });
-
-    SDK.targetManager.observeModels(SDK.EmulationModel, this);
-  }
-
-
-  /**
-   * @param {!HTMLSelectElement} selectElement
-   * @return {!MobileThrottling.NetworkThrottlingSelector}
-   */
-  decorateSelectWithNetworkThrottling(selectElement) {
-    let options = [];
-    const selector =
-        new MobileThrottling.NetworkThrottlingSelector(populate, select, this._customNetworkConditionsSetting);
-    selectElement.addEventListener('change', optionSelected, false);
-    return selector;
-
-    /**
-     * @param {!Array.<!MobileThrottling.NetworkThrottlingConditionsGroup>} groups
-     * @return {!Array<?SDK.NetworkManager.Conditions>}
-     */
-    function populate(groups) {
-      selectElement.removeChildren();
-      options = [];
-      for (let i = 0; i < groups.length; ++i) {
-        const group = groups[i];
-        const groupElement = selectElement.createChild('optgroup');
-        groupElement.label = group.title;
-        for (const conditions of group.items) {
-          const title = conditions.title;
-          const option = new Option(title, title);
-          groupElement.appendChild(option);
-          options.push(conditions);
-        }
-        if (i === groups.length - 1) {
-          groupElement.appendChild(new Option(Common.UIString('Add\u2026'), Common.UIString('Add\u2026')));
-          options.push(null);
-        }
-      }
-      return options;
-    }
-
-    function optionSelected() {
-      if (selectElement.selectedIndex === selectElement.options.length - 1)
-        selector.revealAndUpdate();
-      else
-        selector.optionSelected(options[selectElement.selectedIndex]);
-    }
-
-    /**
-     * @param {number} index
-     */
-    function select(index) {
-      if (selectElement.selectedIndex !== index)
-        selectElement.selectedIndex = index;
-    }
-  }
-
-  /**
-   * @return {!UI.ToolbarCheckbox}
-   */
-  createOfflineToolbarCheckbox() {
-    const checkbox = new UI.ToolbarCheckbox(
-        Common.UIString('Offline'), Common.UIString('Force disconnected from network'), forceOffline.bind(this));
-    SDK.multitargetNetworkManager.addEventListener(
-        SDK.MultitargetNetworkManager.Events.ConditionsChanged, networkConditionsChanged);
-    checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() === SDK.NetworkManager.OfflineConditions);
-
-    /**
-     * @this {!MobileThrottling.ThrottlingManager}
-     */
-    function forceOffline() {
-      if (checkbox.checked())
-        SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.OfflineConditions);
-      else
-        SDK.multitargetNetworkManager.setNetworkConditions(this._lastNetworkThrottlingConditions);
-    }
-
-    function networkConditionsChanged() {
-      checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() === SDK.NetworkManager.OfflineConditions);
-    }
-
-    return checkbox;
-  }
-
-
-  /**
-   * @return {!UI.ToolbarMenuButton}
-   */
-  createMobileThrottlingButton() {
-    const button = new UI.ToolbarMenuButton(appendItems);
-    button.setTitle(Common.UIString('Throttling'));
-    button.setGlyph('');
-    button.turnIntoSelect();
-    button.setDarkText();
-
-    /** @type {!MobileThrottling.ConditionsList} */
-    let options = [];
-    let selectedIndex = -1;
-    const selector = new MobileThrottling.MobileThrottlingSelector(populate, select);
-    return button;
-
-    /**
-     * @param {!UI.ContextMenu} contextMenu
-     */
-    function appendItems(contextMenu) {
-      for (let index = 0; index < options.length; ++index) {
-        const conditions = options[index];
-        if (!conditions)
-          continue;
-        if (conditions.title === MobileThrottling.CustomConditions.title &&
-            conditions.description === MobileThrottling.CustomConditions.description)
-          continue;
-        contextMenu.defaultSection().appendCheckboxItem(
-            Common.UIString(conditions.title),
-            selector.optionSelected.bind(selector, /** @type {!MobileThrottling.Conditions} */ (conditions)),
-            selectedIndex === index);
-      }
-    }
-
-    /**
-     * @param {!Array.<!MobileThrottling.MobileThrottlingConditionsGroup>} groups
-     * @return {!MobileThrottling.ConditionsList}
-     */
-    function populate(groups) {
-      options = [];
-      for (const group of groups) {
-        for (const conditions of group.items)
-          options.push(conditions);
-        options.push(null);
-      }
-      return options;
-    }
-
-    /**
-     * @param {number} index
-     */
-    function select(index) {
-      selectedIndex = index;
-      button.setText(options[index].title);
-      button.setTitle(options[index].description);
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  cpuThrottlingRate() {
-    return this._cpuThrottlingRate;
-  }
-
-  /**
-   * @param {!MobileThrottling.CPUThrottlingRates} rate
-   */
-  setCPUThrottlingRate(rate) {
-    this._cpuThrottlingRate = rate;
-    for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-      emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate);
-    let icon = null;
-    if (this._cpuThrottlingRate !== MobileThrottling.CPUThrottlingRates.NoThrottling) {
-      Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuThrottlingEnabled);
-      icon = UI.Icon.create('smallicon-warning');
-      icon.title = Common.UIString('CPU throttling is enabled');
-    }
-    const index = this._cpuThrottlingRates.indexOf(this._cpuThrottlingRate);
-    for (const control of this._cpuThrottlingControls)
-      control.setSelectedIndex(index);
-    UI.inspectorView.setPanelIcon('timeline', icon);
-    this.dispatchEventToListeners(MobileThrottling.ThrottlingManager.Events.RateChanged, this._cpuThrottlingRate);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.EmulationModel} emulationModel
-   */
-  modelAdded(emulationModel) {
-    if (this._cpuThrottlingRate !== MobileThrottling.CPUThrottlingRates.NoThrottling)
-      emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.EmulationModel} emulationModel
-   */
-  modelRemoved(emulationModel) {
-  }
-
-  /**
-   * @return {!UI.ToolbarComboBox}
-   */
-  createCPUThrottlingSelector() {
-    const control = new UI.ToolbarComboBox(
-        event => this.setCPUThrottlingRate(this._cpuThrottlingRates[event.target.selectedIndex]));
-    this._cpuThrottlingControls.add(control);
-    const currentRate = this._cpuThrottlingRate;
-
-    for (let i = 0; i < this._cpuThrottlingRates.length; ++i) {
-      const rate = this._cpuThrottlingRates[i];
-      const title = rate === 1 ? Common.UIString('No throttling') : Common.UIString('%d\xD7 slowdown', rate);
-      const option = control.createOption(title);
-      control.addOption(option);
-      if (currentRate === rate)
-        control.setSelectedIndex(i);
-    }
-    return control;
-  }
-};
-
-/** @enum {symbol} */
-MobileThrottling.ThrottlingManager.Events = {
-  RateChanged: Symbol('RateChanged')
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-MobileThrottling.ThrottlingManager.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    if (actionId === 'network-conditions.network-online') {
-      SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.NoThrottlingConditions);
-      return true;
-    }
-    if (actionId === 'network-conditions.network-offline') {
-      SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.OfflineConditions);
-      return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @return {!MobileThrottling.ThrottlingManager}
- */
-MobileThrottling.throttlingManager = function() {
-  return self.singleton(MobileThrottling.ThrottlingManager);
-};
diff --git a/front_end/mobile_throttling/ThrottlingPresets.js b/front_end/mobile_throttling/ThrottlingPresets.js
deleted file mode 100644
index 463ddb0..0000000
--- a/front_end/mobile_throttling/ThrottlingPresets.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/** @enum {number} */
-MobileThrottling.CPUThrottlingRates = {
-  NoThrottling: 1,
-  MidTierMobile: 4,
-  LowEndMobile: 6,
-};
-
-/**
- * @typedef {{
- *   title: string,
- *   description: string,
- *   network: !SDK.NetworkManager.Conditions,
- *   cpuThrottlingRate: !MobileThrottling.CPUThrottlingRates
- * }}
- **/
-MobileThrottling.Conditions;
-
-/** @type {!MobileThrottling.Conditions} */
-MobileThrottling.NoThrottlingConditions = {
-  title: SDK.NetworkManager.NoThrottlingConditions.title,
-  description: Common.UIString('No throttling'),
-  network: SDK.NetworkManager.NoThrottlingConditions,
-  cpuThrottlingRate: MobileThrottling.CPUThrottlingRates.NoThrottling,
-};
-
-/** @type {!MobileThrottling.Conditions} */
-MobileThrottling.OfflineConditions = {
-  title: SDK.NetworkManager.OfflineConditions.title,
-  description: Common.UIString('No internet connectivity'),
-  network: SDK.NetworkManager.OfflineConditions,
-  cpuThrottlingRate: MobileThrottling.CPUThrottlingRates.NoThrottling,
-};
-
-/** @type {!MobileThrottling.Conditions} */
-MobileThrottling.LowEndMobileConditions = {
-  title: Common.UIString('Low-end mobile'),
-  description: Common.UIString('Slow 3G & 6x CPU slowdown'),
-  network: SDK.NetworkManager.Slow3GConditions,
-  cpuThrottlingRate: MobileThrottling.CPUThrottlingRates.LowEndMobile,
-};
-
-/** @type {!MobileThrottling.Conditions} */
-MobileThrottling.MidTierMobileConditions = {
-  title: Common.UIString('Mid-tier mobile'),
-  description: Common.UIString('Fast 3G & 4x CPU slowdown'),
-  network: SDK.NetworkManager.Fast3GConditions,
-  cpuThrottlingRate: MobileThrottling.CPUThrottlingRates.MidTierMobile,
-};
-
-/**
- * @typedef {{
- *   title: string,
- *   description: string
- * }}
- **/
-MobileThrottling.PlaceholderConditions;
-
-/** @type {!MobileThrottling.PlaceholderConditions} */
-MobileThrottling.CustomConditions = {
-  title: Common.UIString('Custom'),
-  description: Common.UIString('Check Network and Performance panels'),
-};
-
-/** @typedef {!{title: string, items: !Array<!SDK.NetworkManager.Conditions>}} */
-MobileThrottling.NetworkThrottlingConditionsGroup;
-
-/** @typedef {!{title: string, items: !Array<!MobileThrottling.Conditions|!MobileThrottling.PlaceholderConditions>}} */
-MobileThrottling.MobileThrottlingConditionsGroup;
-
-/** @typedef {!Array<?MobileThrottling.Conditions|!MobileThrottling.PlaceholderConditions>} */
-MobileThrottling.ConditionsList;
-
-/** @type {!Array.<!MobileThrottling.Conditions>} */
-MobileThrottling.mobilePresets = [
-  MobileThrottling.MidTierMobileConditions, MobileThrottling.LowEndMobileConditions, MobileThrottling.CustomConditions
-];
-
-/** @type {!Array.<!MobileThrottling.Conditions>} */
-MobileThrottling.advancedMobilePresets = [
-  MobileThrottling.OfflineConditions,
-];
-
-/** @type {!Array<!SDK.NetworkManager.Conditions>} */
-MobileThrottling.networkPresets = [
-  SDK.NetworkManager.Fast3GConditions,
-  SDK.NetworkManager.Slow3GConditions,
-  SDK.NetworkManager.OfflineConditions,
-];
-
-/** @type {!Array<!MobileThrottling.CPUThrottlingRates>} */
-MobileThrottling.cpuThrottlingPresets = [
-  MobileThrottling.CPUThrottlingRates.NoThrottling,
-  MobileThrottling.CPUThrottlingRates.MidTierMobile,
-  MobileThrottling.CPUThrottlingRates.LowEndMobile,
-];
diff --git a/front_end/mobile_throttling/ThrottlingSettingsTab.js b/front_end/mobile_throttling/ThrottlingSettingsTab.js
deleted file mode 100644
index e303163..0000000
--- a/front_end/mobile_throttling/ThrottlingSettingsTab.js
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {UI.ListWidget.Delegate}
- * @unrestricted
- */
-MobileThrottling.ThrottlingSettingsTab = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('mobile_throttling/throttlingSettingsTab.css');
-
-    this.contentElement.createChild('div', 'header').textContent = Common.UIString('Network Throttling Profiles');
-
-    const addButton = UI.createTextButton(
-        Common.UIString('Add custom profile...'), this._addButtonClicked.bind(this), 'add-conditions-button');
-    this.contentElement.appendChild(addButton);
-
-    this._list = new UI.ListWidget(this);
-    this._list.element.classList.add('conditions-list');
-    this._list.registerRequiredCSS('mobile_throttling/throttlingSettingsTab.css');
-    this._list.show(this.contentElement);
-
-    this._customSetting = Common.moduleSetting('customNetworkConditions');
-    this._customSetting.addChangeListener(this._conditionsUpdated, this);
-
-    this.setDefaultFocusedElement(addButton);
-    this.contentElement.tabIndex = 0;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._conditionsUpdated();
-  }
-
-  _conditionsUpdated() {
-    this._list.clear();
-
-    const conditions = this._customSetting.get();
-    for (let i = 0; i < conditions.length; ++i)
-      this._list.appendItem(conditions[i], true);
-
-    this._list.appendSeparator();
-  }
-
-  _addButtonClicked() {
-    this._list.addNewItem(this._customSetting.get().length, {title: '', download: -1, upload: -1, latency: 0});
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(item, editable) {
-    const conditions = /** @type {!SDK.NetworkManager.Conditions} */ (item);
-    const element = createElementWithClass('div', 'conditions-list-item');
-    const title = element.createChild('div', 'conditions-list-text conditions-list-title');
-    const titleText = title.createChild('div', 'conditions-list-title-text');
-    titleText.textContent = conditions.title;
-    titleText.title = conditions.title;
-    element.createChild('div', 'conditions-list-separator');
-    element.createChild('div', 'conditions-list-text').textContent =
-        MobileThrottling.throughputText(conditions.download);
-    element.createChild('div', 'conditions-list-separator');
-    element.createChild('div', 'conditions-list-text').textContent = MobileThrottling.throughputText(conditions.upload);
-    element.createChild('div', 'conditions-list-separator');
-    element.createChild('div', 'conditions-list-text').textContent = Common.UIString('%dms', conditions.latency);
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {number} index
-   */
-  removeItemRequested(item, index) {
-    const list = this._customSetting.get();
-    list.splice(index, 1);
-    this._customSetting.set(list);
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {
-    const conditions = /** @type {?SDK.NetworkManager.Conditions} */ (item);
-    conditions.title = editor.control('title').value.trim();
-    const download = editor.control('download').value.trim();
-    conditions.download = download ? parseInt(download, 10) * (1024 / 8) : -1;
-    const upload = editor.control('upload').value.trim();
-    conditions.upload = upload ? parseInt(upload, 10) * (1024 / 8) : -1;
-    const latency = editor.control('latency').value.trim();
-    conditions.latency = latency ? parseInt(latency, 10) : 0;
-
-    const list = this._customSetting.get();
-    if (isNew)
-      list.push(conditions);
-    this._customSetting.set(list);
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(item) {
-    const conditions = /** @type {?SDK.NetworkManager.Conditions} */ (item);
-    const editor = this._createEditor();
-    editor.control('title').value = conditions.title;
-    editor.control('download').value = conditions.download <= 0 ? '' : String(conditions.download / (1024 / 8));
-    editor.control('upload').value = conditions.upload <= 0 ? '' : String(conditions.upload / (1024 / 8));
-    editor.control('latency').value = conditions.latency ? String(conditions.latency) : '';
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._editor = editor;
-    const content = editor.contentElement();
-
-    const titles = content.createChild('div', 'conditions-edit-row');
-    titles.createChild('div', 'conditions-list-text conditions-list-title').textContent =
-        Common.UIString('Profile Name');
-    titles.createChild('div', 'conditions-list-separator conditions-list-separator-invisible');
-    titles.createChild('div', 'conditions-list-text').textContent = Common.UIString('Download');
-    titles.createChild('div', 'conditions-list-separator conditions-list-separator-invisible');
-    titles.createChild('div', 'conditions-list-text').textContent = Common.UIString('Upload');
-    titles.createChild('div', 'conditions-list-separator conditions-list-separator-invisible');
-    titles.createChild('div', 'conditions-list-text').textContent = Common.UIString('Latency');
-
-    const fields = content.createChild('div', 'conditions-edit-row');
-    fields.createChild('div', 'conditions-list-text conditions-list-title')
-        .appendChild(editor.createInput('title', 'text', '', titleValidator));
-    fields.createChild('div', 'conditions-list-separator conditions-list-separator-invisible');
-
-    let cell = fields.createChild('div', 'conditions-list-text');
-    cell.appendChild(editor.createInput('download', 'text', Common.UIString('kb/s'), throughputValidator));
-    cell.createChild('div', 'conditions-edit-optional').textContent = Common.UIString('optional');
-    fields.createChild('div', 'conditions-list-separator conditions-list-separator-invisible');
-
-    cell = fields.createChild('div', 'conditions-list-text');
-    cell.appendChild(editor.createInput('upload', 'text', Common.UIString('kb/s'), throughputValidator));
-    cell.createChild('div', 'conditions-edit-optional').textContent = Common.UIString('optional');
-    fields.createChild('div', 'conditions-list-separator conditions-list-separator-invisible');
-
-    cell = fields.createChild('div', 'conditions-list-text');
-    cell.appendChild(editor.createInput('latency', 'text', Common.UIString('ms'), latencyValidator));
-    cell.createChild('div', 'conditions-edit-optional').textContent = Common.UIString('optional');
-
-    return editor;
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function titleValidator(item, index, input) {
-      const value = input.value.trim();
-      return value.length > 0 && value.length < 50;
-    }
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function throughputValidator(item, index, input) {
-      const value = input.value.trim();
-      return !value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10000000);
-    }
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function latencyValidator(item, index, input) {
-      const value = input.value.trim();
-      return !value || (/^[\d]+$/.test(value) && value >= 0 && value <= 1000000);
-    }
-  }
-};
-
-/**
- * @param {number} throughput
- * @param {boolean=} plainText
- * @return {string}
- */
-MobileThrottling.throughputText = function(throughput, plainText) {
-  if (throughput < 0)
-    return '';
-  const throughputInKbps = throughput / (1024 / 8);
-  const delimiter = plainText ? '' : ' ';
-  if (throughputInKbps < 1024)
-    return Common.UIString('%d%skb/s', throughputInKbps, delimiter);
-  if (throughputInKbps < 1024 * 10)
-    return Common.UIString('%.1f%sMb/s', throughputInKbps / 1024, delimiter);
-  return Common.UIString('%d%sMb/s', (throughputInKbps / 1024) | 0, delimiter);
-};
diff --git a/front_end/mobile_throttling/module.json b/front_end/mobile_throttling/module.json
deleted file mode 100644
index 217bc85..0000000
--- a/front_end/mobile_throttling/module.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "setting",
-            "settingName": "customNetworkConditions",
-            "settingType": "array",
-            "defaultValue": []
-        },
-        {
-            "type": "action",
-            "actionId": "network-conditions.network-offline",
-            "category": "Network",
-            "title": "Go offline",
-            "className": "MobileThrottling.ThrottlingManager.ActionDelegate",
-            "tags": "device"
-        },
-        {
-            "type": "action",
-            "actionId": "network-conditions.network-online",
-            "category": "Network",
-            "title": "Go online",
-            "className": "MobileThrottling.ThrottlingManager.ActionDelegate",
-            "tags": "device"
-        },
-        {
-            "type": "view",
-            "location": "settings-view",
-            "id": "throttling-conditions",
-            "title": "Throttling",
-            "order": 35,
-            "className": "MobileThrottling.ThrottlingSettingsTab",
-            "settings": [
-                "customNetworkConditions"
-            ]
-        }
-    ],
-    "dependencies": [
-        "common",
-        "sdk",
-        "ui",
-        "protocol"
-    ],
-    "scripts": [
-        "ThrottlingPresets.js",
-        "MobileThrottlingSelector.js",
-        "NetworkPanelIndicator.js",
-        "NetworkThrottlingSelector.js",
-        "ThrottlingSettingsTab.js",
-        "ThrottlingManager.js"
-    ],
-    "resources": [
-        "throttlingSettingsTab.css"
-    ]
-}
diff --git a/front_end/mobile_throttling/throttlingSettingsTab.css b/front_end/mobile_throttling/throttlingSettingsTab.css
deleted file mode 100644
index d85c7bd..0000000
--- a/front_end/mobile_throttling/throttlingSettingsTab.css
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    overflow:hidden;
-}
-
-.header {
-    padding: 0 0 6px;
-    border-bottom: 1px solid #EEEEEE;
-    font-size: 18px;
-    font-weight: normal;
-    flex: none;
-}
-
-.add-conditions-button {
-    flex: none;
-    margin: 10px 2px;
-    min-width: 140px;
-    align-self: flex-start;
-}
-
-.conditions-list {
-    max-width: 500px;
-    min-width: 340px;
-    flex: auto;
-}
-
-.conditions-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    position: relative;
-    flex: auto 1 1;
-}
-
-.conditions-list-text {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    flex: 0 0 70px;
-    -webkit-user-select: none;
-    color: #222;
-    text-align: end;
-    position: relative;
-}
-
-.conditions-list-title {
-    text-align: start;
-    flex: auto;
-    display: flex;
-    align-items: flex-start;
-}
-
-.conditions-list-title-text {
-    overflow: hidden;
-    flex: auto;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-
-.conditions-list-separator {
-    flex: 0 0 1px;
-    background-color: rgb(231, 231, 231);
-    height: 30px;
-    margin: 0 4px;
-}
-
-.conditions-list-separator-invisible {
-    visibility: hidden;
-    height: 100% !important;
-}
-
-.conditions-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 6px 5px;
-}
-
-.conditions-edit-row input {
-    width: 100%;
-    text-align: inherit;
-}
-
-.conditions-edit-optional {
-    position: absolute;
-    bottom: -20px;
-    right: 0;
-    color: rgb(128, 128, 128);
-}
diff --git a/front_end/ndb_app.html b/front_end/ndb_app.html
deleted file mode 100644
index 13977f7..0000000
--- a/front_end/ndb_app.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <meta name="referrer" content="no-referrer">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="ndb_app.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/ndb_app.js b/front_end/ndb_app.js
deleted file mode 100644
index c3eb0e5..0000000
--- a/front_end/ndb_app.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Runtime.startApplication('ndb_app');
diff --git a/front_end/ndb_app.json b/front_end/ndb_app.json
deleted file mode 100644
index b591b4f..0000000
--- a/front_end/ndb_app.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "modules" : [
-  ],
-  "extends": "shell",
-  "has_html": true
-}
diff --git a/front_end/network/BlockedURLsPane.js b/front_end/network/BlockedURLsPane.js
deleted file mode 100644
index 21e81fb..0000000
--- a/front_end/network/BlockedURLsPane.js
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.ListWidget.Delegate<SDK.NetworkManager.BlockedPattern>}
- */
-Network.BlockedURLsPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('network/blockedURLsPane.css');
-
-    Network.BlockedURLsPane._instance = this;
-    this._manager = SDK.multitargetNetworkManager;
-    this._manager.addEventListener(SDK.MultitargetNetworkManager.Events.BlockedPatternsChanged, this._update, this);
-
-    this._toolbar = new UI.Toolbar('', this.contentElement);
-    this._enabledCheckbox =
-        new UI.ToolbarCheckbox(Common.UIString('Enable request blocking'), undefined, this._toggleEnabled.bind(this));
-    this._toolbar.appendToolbarItem(this._enabledCheckbox);
-    this._toolbar.appendSeparator();
-    const addButton = new UI.ToolbarButton(Common.UIString('Add pattern'), 'largeicon-add');
-    addButton.addEventListener(UI.ToolbarButton.Events.Click, this._addButtonClicked, this);
-    this._toolbar.appendToolbarItem(addButton);
-    const clearButton = new UI.ToolbarButton(Common.UIString('Remove all patterns'), 'largeicon-clear');
-    clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._removeAll, this);
-    this._toolbar.appendToolbarItem(clearButton);
-
-    /** @type {!UI.ListWidget<!SDK.NetworkManager.BlockedPattern>} */
-    this._list = new UI.ListWidget(this);
-    this._list.element.classList.add('blocked-urls');
-    this._list.registerRequiredCSS('network/blockedURLsPane.css');
-    this._list.setEmptyPlaceholder(this._createEmptyPlaceholder());
-    this._list.show(this.contentElement);
-
-    /** @type {?UI.ListWidget.Editor<!SDK.NetworkManager.BlockedPattern>} */
-    this._editor = null;
-
-    /** @type {!Map<string, number>} */
-    this._blockedCountForUrl = new Map();
-    SDK.targetManager.addModelListener(
-        SDK.NetworkManager, SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this);
-
-    this._updateThrottler = new Common.Throttler(200);
-
-    this._update();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _createEmptyPlaceholder() {
-    const element = this.contentElement.createChild('div', 'no-blocked-urls');
-    element.createChild('span').textContent = Common.UIString('Requests are not blocked. ');
-    const addLink = element.createChild('span', 'link');
-    addLink.textContent = Common.UIString('Add pattern.');
-    addLink.href = '';
-    addLink.addEventListener('click', this._addButtonClicked.bind(this), false);
-    return element;
-  }
-
-  static reset() {
-    if (Network.BlockedURLsPane._instance)
-      Network.BlockedURLsPane._instance.reset();
-  }
-
-  _addButtonClicked() {
-    this._manager.setBlockingEnabled(true);
-    this._list.addNewItem(0, {url: '', enabled: true});
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager.BlockedPattern} pattern
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(pattern, editable) {
-    const count = this._blockedRequestsCount(pattern.url);
-    const element = createElementWithClass('div', 'blocked-url');
-    const checkbox = element.createChild('input', 'blocked-url-checkbox');
-    checkbox.type = 'checkbox';
-    checkbox.checked = pattern.enabled;
-    checkbox.disabled = !this._manager.blockingEnabled();
-    element.createChild('div', 'blocked-url-label').textContent = pattern.url;
-    element.createChild('div', 'blocked-url-count').textContent = Common.UIString('%d blocked', count);
-    element.addEventListener('click', event => this._togglePattern(pattern, event), false);
-    checkbox.addEventListener('click', event => this._togglePattern(pattern, event), false);
-    return element;
-  }
-
-  /**
-   * @param {!SDK.NetworkManager.BlockedPattern} pattern
-   * @param {!Event} event
-   */
-  _togglePattern(pattern, event) {
-    event.consume(true);
-    const patterns = this._manager.blockedPatterns();
-    patterns.splice(patterns.indexOf(pattern), 1, {enabled: !pattern.enabled, url: pattern.url});
-    this._manager.setBlockedPatterns(patterns);
-  }
-
-  _toggleEnabled() {
-    this._manager.setBlockingEnabled(!this._manager.blockingEnabled());
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager.BlockedPattern} pattern
-   * @param {number} index
-   */
-  removeItemRequested(pattern, index) {
-    const patterns = this._manager.blockedPatterns();
-    patterns.splice(index, 1);
-    this._manager.setBlockedPatterns(patterns);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager.BlockedPattern} pattern
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(pattern) {
-    this._editor = this._createEditor();
-    this._editor.control('url').value = pattern.url;
-    return this._editor;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager.BlockedPattern} item
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {
-    const url = editor.control('url').value;
-    const patterns = this._manager.blockedPatterns();
-    if (isNew)
-      patterns.push({enabled: true, url: url});
-    else
-      patterns.splice(patterns.indexOf(item), 1, {enabled: true, url: url});
-
-    this._manager.setBlockedPatterns(patterns);
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor<!SDK.NetworkManager.BlockedPattern>}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    const content = editor.contentElement();
-    const titles = content.createChild('div', 'blocked-url-edit-row');
-    titles.createChild('div').textContent =
-        Common.UIString('Text pattern to block matching requests; use * for wildcard');
-    const fields = content.createChild('div', 'blocked-url-edit-row');
-    const urlInput = editor.createInput(
-        'url', 'text', '',
-        (item, index, input) =>
-            !!input.value && !this._manager.blockedPatterns().find(pattern => pattern.url === input.value));
-    fields.createChild('div', 'blocked-url-edit-value').appendChild(urlInput);
-    return editor;
-  }
-
-  _removeAll() {
-    this._manager.setBlockedPatterns([]);
-  }
-
-  /**
-   * @return {!Promise<?>}
-   */
-  _update() {
-    const enabled = this._manager.blockingEnabled();
-    this._list.element.classList.toggle('blocking-disabled', !enabled && !!this._manager.blockedPatterns().length);
-    this._enabledCheckbox.setChecked(enabled);
-    this._list.clear();
-    for (const pattern of this._manager.blockedPatterns())
-      this._list.appendItem(pattern, true);
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {string} url
-   * @return {number}
-   */
-  _blockedRequestsCount(url) {
-    if (!url)
-      return 0;
-
-    let result = 0;
-    for (const blockedUrl of this._blockedCountForUrl.keys()) {
-      if (this._matches(url, blockedUrl))
-        result += this._blockedCountForUrl.get(blockedUrl);
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} pattern
-   * @param {string} url
-   * @return {boolean}
-   */
-  _matches(pattern, url) {
-    let pos = 0;
-    const parts = pattern.split('*');
-    for (let index = 0; index < parts.length; index++) {
-      const part = parts[index];
-      if (!part.length)
-        continue;
-      pos = url.indexOf(part, pos);
-      if (pos === -1)
-        return false;
-      pos += part.length;
-    }
-    return true;
-  }
-
-  reset() {
-    this._blockedCountForUrl.clear();
-    this._updateThrottler.schedule(this._update.bind(this));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestFinished(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    if (request.wasBlocked()) {
-      const count = this._blockedCountForUrl.get(request.url()) || 0;
-      this._blockedCountForUrl.set(request.url(), count + 1);
-      this._updateThrottler.schedule(this._update.bind(this));
-    }
-  }
-};
-
-/** @type {?Network.BlockedURLsPane} */
-Network.BlockedURLsPane._instance = null;
diff --git a/front_end/network/EventSourceMessagesView.js b/front_end/network/EventSourceMessagesView.js
deleted file mode 100644
index 626519b..0000000
--- a/front_end/network/EventSourceMessagesView.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Network.EventSourceMessagesView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super();
-    this.registerRequiredCSS('network/eventSourceMessagesView.css');
-    this.element.classList.add('event-source-messages-view');
-    this._request = request;
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'id', title: Common.UIString('Id'), sortable: true, weight: 8},
-      {id: 'type', title: Common.UIString('Type'), sortable: true, weight: 8},
-      {id: 'data', title: Common.UIString('Data'), sortable: false, weight: 88},
-      {id: 'time', title: Common.UIString('Time'), sortable: true, weight: 8}
-    ]);
-
-    this._dataGrid = new DataGrid.SortableDataGrid(columns);
-    this._dataGrid.setStriped(true);
-    this._dataGrid.setStickToBottom(true);
-    this._dataGrid.markColumnAsSortedBy('time', DataGrid.DataGrid.Order.Ascending);
-    this._sortItems();
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortItems, this);
-
-    this._dataGrid.setName('EventSourceMessagesView');
-    this._dataGrid.asWidget().show(this.element);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._dataGrid.rootNode().removeChildren();
-    const messages = this._request.eventSourceMessages();
-    for (let i = 0; i < messages.length; ++i)
-      this._dataGrid.insertChild(new Network.EventSourceMessageNode(messages[i]));
-
-    this._request.addEventListener(SDK.NetworkRequest.Events.EventSourceMessageAdded, this._messageAdded, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._request.removeEventListener(SDK.NetworkRequest.Events.EventSourceMessageAdded, this._messageAdded, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _messageAdded(event) {
-    const message = /** @type {!SDK.NetworkRequest.EventSourceMessage} */ (event.data);
-    this._dataGrid.insertChild(new Network.EventSourceMessageNode(message));
-  }
-
-  _sortItems() {
-    const sortColumnId = this._dataGrid.sortColumnId();
-    if (!sortColumnId)
-      return;
-    const comparator = Network.EventSourceMessageNode.Comparators[sortColumnId];
-    if (!comparator)
-      return;
-    this._dataGrid.sortNodes(comparator, !this._dataGrid.isSortOrderAscending());
-  }
-};
-
-/**
- * @unrestricted
- */
-Network.EventSourceMessageNode = class extends DataGrid.SortableDataGridNode {
-  /**
-   * @param {!SDK.NetworkRequest.EventSourceMessage} message
-   */
-  constructor(message) {
-    const time = new Date(message.time * 1000);
-    const timeText = ('0' + time.getHours()).substr(-2) + ':' + ('0' + time.getMinutes()).substr(-2) + ':' +
-        ('0' + time.getSeconds()).substr(-2) + '.' + ('00' + time.getMilliseconds()).substr(-3);
-    const timeNode = createElement('div');
-    timeNode.createTextChild(timeText);
-    timeNode.title = time.toLocaleString();
-    super({id: message.eventId, type: message.eventName, data: message.data, time: timeNode});
-    this._message = message;
-  }
-};
-
-/**
- * @param {string} field
- * @param {!Network.EventSourceMessageNode} a
- * @param {!Network.EventSourceMessageNode} b
- * @return {number}
- */
-Network.EventSourceMessageNodeComparator = function(field, a, b) {
-  const aValue = a._message[field];
-  const bValue = b._message[field];
-  return aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
-};
-
-/** @type {!Object.<string, function(!Network.EventSourceMessageNode, !Network.EventSourceMessageNode):number>} */
-Network.EventSourceMessageNode.Comparators = {
-  'id': Network.EventSourceMessageNodeComparator.bind(null, 'eventId'),
-  'type': Network.EventSourceMessageNodeComparator.bind(null, 'eventName'),
-  'time': Network.EventSourceMessageNodeComparator.bind(null, 'time')
-};
diff --git a/front_end/network/HARWriter.js b/front_end/network/HARWriter.js
deleted file mode 100644
index 46476dc..0000000
--- a/front_end/network/HARWriter.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Network.HARWriter = class {
-  /**
-   * @param {!Common.OutputStream} stream
-   * @param {!Array.<!SDK.NetworkRequest>} requests
-   * @param {!Common.Progress} progress
-   * @return {!Promise}
-   */
-  static async write(stream, requests, progress) {
-    const compositeProgress = new Common.CompositeProgress(progress);
-
-    const content = await Network.HARWriter._harStringForRequests(requests, compositeProgress);
-    if (progress.isCanceled())
-      return Promise.resolve();
-    return Network.HARWriter._writeToStream(stream, compositeProgress, content);
-  }
-
-  /**
-   * @param {!Array<!SDK.NetworkRequest>} requests
-   * @param {!Common.CompositeProgress} compositeProgress
-   * @return {!Promise<string>}
-   */
-  static async _harStringForRequests(requests, compositeProgress) {
-    const progress = compositeProgress.createSubProgress();
-    progress.setTitle(Common.UIString('Collecting content\u2026'));
-    progress.setTotalWork(requests.length);
-
-    const harLog = await BrowserSDK.HARLog.build(requests);
-    const promises = [];
-    for (let i = 0; i < requests.length; i++) {
-      const promise = requests[i].contentData();
-      promises.push(promise.then(contentLoaded.bind(null, harLog.entries[i])));
-    }
-
-    await Promise.all(promises);
-    progress.done();
-
-    if (progress.isCanceled())
-      return '';
-    return JSON.stringify({log: harLog}, null, Network.HARWriter._jsonIndent);
-
-    /**
-     * @param {!Object} entry
-     * @param {!SDK.NetworkRequest.ContentData} contentData
-     */
-    function contentLoaded(entry, contentData) {
-      progress.worked();
-      if (contentData.content !== null)
-        entry.response.content.text = contentData.content;
-      if (contentData.encoded)
-        entry.response.content.encoding = 'base64';
-    }
-  }
-
-  /**
-   * @param {!Common.OutputStream} stream
-   * @param {!Common.CompositeProgress} compositeProgress
-   * @param {string} fileContent
-   * @return {!Promise}
-   */
-  static async _writeToStream(stream, compositeProgress, fileContent) {
-    const progress = compositeProgress.createSubProgress();
-    progress.setTitle(Common.UIString('Writing file\u2026'));
-    progress.setTotalWork(fileContent.length);
-    for (let i = 0; i < fileContent.length && !progress.isCanceled(); i += Network.HARWriter._chunkSize) {
-      const chunk = fileContent.substr(i, Network.HARWriter._chunkSize);
-      await stream.write(chunk);
-      progress.worked(chunk.length);
-    }
-    progress.done();
-  }
-};
-
-/** @const */
-Network.HARWriter._jsonIndent = 2;
-
-/** @const */
-Network.HARWriter._chunkSize = 100000;
diff --git a/front_end/network/NetworkConfigView.js b/front_end/network/NetworkConfigView.js
deleted file mode 100644
index 1a29522..0000000
--- a/front_end/network/NetworkConfigView.js
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Network.NetworkConfigView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('network/networkConfigView.css');
-    this.contentElement.classList.add('network-config');
-
-    this._createCacheSection();
-    this.contentElement.createChild('div').classList.add('panel-section-separator');
-    this._createNetworkThrottlingSection();
-    this.contentElement.createChild('div').classList.add('panel-section-separator');
-    this._createUserAgentSection();
-  }
-
-  /**
-   * @return {{select: !Element, input: !Element}}
-   */
-  static createUserAgentSelectAndInput() {
-    const userAgentSetting = Common.settings.createSetting('customUserAgent', '');
-    const userAgentSelectElement = createElement('select');
-
-    const customOverride = {title: Common.UIString('Custom...'), value: 'custom'};
-    userAgentSelectElement.appendChild(new Option(customOverride.title, customOverride.value));
-
-    const groups = Network.NetworkConfigView._userAgentGroups;
-    for (const userAgentDescriptor of groups) {
-      const groupElement = userAgentSelectElement.createChild('optgroup');
-      groupElement.label = userAgentDescriptor.title;
-      for (const userAgentVersion of userAgentDescriptor.values) {
-        const userAgentValue = SDK.MultitargetNetworkManager.patchUserAgentWithChromeVersion(userAgentVersion.value);
-        groupElement.appendChild(new Option(userAgentVersion.title, userAgentValue));
-      }
-    }
-
-    userAgentSelectElement.selectedIndex = 0;
-
-    const otherUserAgentElement = UI.createInput('', 'text');
-    otherUserAgentElement.value = userAgentSetting.get();
-    otherUserAgentElement.title = userAgentSetting.get();
-    otherUserAgentElement.placeholder = Common.UIString('Enter a custom user agent');
-    otherUserAgentElement.required = true;
-
-    settingChanged();
-    userAgentSelectElement.addEventListener('change', userAgentSelected, false);
-    otherUserAgentElement.addEventListener('input', applyOtherUserAgent, false);
-
-    function userAgentSelected() {
-      const value = userAgentSelectElement.options[userAgentSelectElement.selectedIndex].value;
-      if (value !== customOverride.value) {
-        userAgentSetting.set(value);
-        otherUserAgentElement.value = value;
-        otherUserAgentElement.title = value;
-      } else {
-        otherUserAgentElement.select();
-      }
-    }
-
-    function settingChanged() {
-      const value = userAgentSetting.get();
-      const options = userAgentSelectElement.options;
-      let selectionRestored = false;
-      for (let i = 0; i < options.length; ++i) {
-        if (options[i].value === value) {
-          userAgentSelectElement.selectedIndex = i;
-          selectionRestored = true;
-          break;
-        }
-      }
-
-      if (!selectionRestored)
-        userAgentSelectElement.selectedIndex = 0;
-    }
-
-    function applyOtherUserAgent() {
-      if (userAgentSetting.get() !== otherUserAgentElement.value) {
-        userAgentSetting.set(otherUserAgentElement.value);
-        otherUserAgentElement.title = otherUserAgentElement.value;
-        settingChanged();
-      }
-    }
-
-    return {select: userAgentSelectElement, input: otherUserAgentElement};
-  }
-
-  /**
-   * @param {string} title
-   * @param {string=} className
-   * @return {!Element}
-   */
-  _createSection(title, className) {
-    const section = this.contentElement.createChild('section', 'network-config-group');
-    if (className)
-      section.classList.add(className);
-    section.createChild('div', 'network-config-title').textContent = title;
-    return section.createChild('div', 'network-config-fields');
-  }
-
-  _createCacheSection() {
-    const section = this._createSection(Common.UIString('Caching'), 'network-config-disable-cache');
-    section.appendChild(UI.SettingsUI.createSettingCheckbox(
-        Common.UIString('Disable cache'), Common.moduleSetting('cacheDisabled'), true));
-  }
-
-  _createNetworkThrottlingSection() {
-    const section = this._createSection(Common.UIString('Network throttling'), 'network-config-throttling');
-    const networkThrottlingSelect =
-        /** @type {!HTMLSelectElement} */ (section.createChild('select', 'chrome-select'));
-    MobileThrottling.throttlingManager().decorateSelectWithNetworkThrottling(networkThrottlingSelect);
-  }
-
-  _createUserAgentSection() {
-    const section = this._createSection(Common.UIString('User agent'), 'network-config-ua');
-    const checkboxLabel = UI.CheckboxLabel.create(Common.UIString('Select automatically'), true);
-    section.appendChild(checkboxLabel);
-    const autoCheckbox = checkboxLabel.checkboxElement;
-
-    const customUserAgentSetting = Common.settings.createSetting('customUserAgent', '');
-    customUserAgentSetting.addChangeListener(() => {
-      if (autoCheckbox.checked)
-        return;
-      SDK.multitargetNetworkManager.setCustomUserAgentOverride(customUserAgentSetting.get());
-    });
-    const customUserAgentSelectBox = section.createChild('div', 'network-config-ua-custom');
-    autoCheckbox.addEventListener('change', userAgentSelectBoxChanged);
-    const customSelectAndInput = Network.NetworkConfigView.createUserAgentSelectAndInput();
-    customSelectAndInput.select.classList.add('chrome-select');
-    customUserAgentSelectBox.appendChild(customSelectAndInput.select);
-    customUserAgentSelectBox.appendChild(customSelectAndInput.input);
-    userAgentSelectBoxChanged();
-
-    function userAgentSelectBoxChanged() {
-      const useCustomUA = !autoCheckbox.checked;
-      customUserAgentSelectBox.classList.toggle('checked', useCustomUA);
-      customSelectAndInput.select.disabled = !useCustomUA;
-      customSelectAndInput.input.disabled = !useCustomUA;
-      const customUA = useCustomUA ? customUserAgentSetting.get() : '';
-      SDK.multitargetNetworkManager.setCustomUserAgentOverride(customUA);
-    }
-  }
-};
-
-/** @type {!Array.<{title: string, values: !Array.<{title: string, value: string}>}>} */
-Network.NetworkConfigView._userAgentGroups = [
-  {
-    title: 'Android',
-    values: [
-      {
-        title: 'Android (4.0.2) Browser \u2014 Galaxy Nexus',
-        value:
-            'Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
-      },
-      {
-        title: 'Android (2.3) Browser \u2014 Nexus S',
-        value:
-            'Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
-      }
-    ]
-  },
-  {
-    title: 'BlackBerry',
-    values: [
-      {
-        title: 'BlackBerry \u2014 BB10',
-        value:
-            'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+'
-      },
-      {
-        title: 'BlackBerry \u2014 PlayBook 2.1',
-        value:
-            'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+'
-      },
-      {
-        title: 'BlackBerry \u2014 9900',
-        value:
-            'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+'
-      }
-    ]
-  },
-  {
-    title: 'Chrome',
-    values: [
-      {
-        title: 'Chrome \u2014 Android Mobile',
-        value:
-            'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36'
-      },
-      {
-        title: 'Chrome \u2014 Android Tablet',
-        value:
-            'Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36'
-      },
-      {
-        title: 'Chrome \u2014 iPhone',
-        value:
-            'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/%s Mobile/13B143 Safari/601.1.46'
-      },
-      {
-        title: 'Chrome \u2014 iPad',
-        value:
-            'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/%s Mobile/13B143 Safari/601.1.46'
-      },
-      {
-        title: 'Chrome \u2014 Chrome OS',
-        value: 'Mozilla/5.0 (X11; CrOS x86_64 10066.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36'
-      },
-      {
-        title: 'Chrome \u2014 Mac',
-        value:
-            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36'
-      },
-      {
-        title: 'Chrome \u2014 Windows',
-        value: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36'
-      }
-    ]
-  },
-  {
-    title: 'Edge',
-    values: [
-      {
-        title: 'Edge \u2014 Windows',
-        value:
-            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240'
-      },
-      {
-        title: 'Edge \u2014 Mobile',
-        value:
-            'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 640 XL LTE) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Edge/12.10166'
-      },
-      {
-        title: 'Edge \u2014 XBox',
-        value:
-            'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586'
-      }
-    ]
-  },
-  {
-    title: 'Firefox',
-    values: [
-      {
-        title: 'Firefox \u2014 Android Mobile',
-        value: 'Mozilla/5.0 (Android 4.4; Mobile; rv:46.0) Gecko/46.0 Firefox/46.0'
-      },
-      {
-        title: 'Firefox \u2014 Android Tablet',
-        value: 'Mozilla/5.0 (Android 4.4; Tablet; rv:46.0) Gecko/46.0 Firefox/46.0'
-      },
-      {
-        title: 'Firefox \u2014 iPhone',
-        value:
-            'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4'
-      },
-      {
-        title: 'Firefox \u2014 iPad',
-        value:
-            'Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4'
-      },
-      {
-        title: 'Firefox \u2014 Mac',
-        value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0'
-      },
-      {
-        title: 'Firefox \u2014 Windows',
-        value: 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0'
-      }
-    ]
-  },
-  {
-    title: 'Googlebot',
-    values: [
-      {title: 'Googlebot', value: 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'}, {
-        title: 'Googlebot Smartphone',
-        value:
-            'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
-      }
-    ]
-  },
-  {
-    title: 'Internet Explorer',
-    values: [
-      {title: 'Internet Explorer 11', value: 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'},
-      {title: 'Internet Explorer 10', value: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)'},
-      {title: 'Internet Explorer 9', value: 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'},
-      {title: 'Internet Explorer 8', value: 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'},
-      {title: 'Internet Explorer 7', value: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)'}
-    ]
-  },
-  {
-    title: 'Opera',
-    values: [
-      {
-        title: 'Opera \u2014 Mac',
-        value:
-            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.31'
-      },
-      {
-        title: 'Opera \u2014 Windows',
-        value:
-            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.31'
-      },
-      {
-        title: 'Opera (Presto) \u2014 Mac',
-        value: 'Opera/9.80 (Macintosh; Intel Mac OS X 10.9.1) Presto/2.12.388 Version/12.16'
-      },
-      {title: 'Opera (Presto) \u2014 Windows', value: 'Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16'}, {
-        title: 'Opera Mobile \u2014 Android Mobile',
-        value: 'Opera/12.02 (Android 4.1; Linux; Opera Mobi/ADR-1111101157; U; en-US) Presto/2.9.201 Version/12.02'
-      },
-      {
-        title: 'Opera Mini \u2014 iOS',
-        value: 'Opera/9.80 (iPhone; Opera Mini/8.0.0/34.2336; U; en) Presto/2.8.119 Version/11.10'
-      }
-    ]
-  },
-  {
-    title: 'Safari',
-    values: [
-      {
-        title: 'Safari \u2014 iPad iOS 9',
-        value:
-            'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1'
-      },
-      {
-        title: 'Safari \u2014 iPhone iOS 9',
-        value:
-            'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1'
-      },
-      {
-        title: 'Safari \u2014 Mac',
-        value:
-            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A'
-      }
-    ]
-  },
-  {
-    title: 'UC Browser',
-    values: [
-      {
-        title: 'UC Browser \u2014 Android Mobile',
-        value:
-            'Mozilla/5.0 (Linux; U; Android 4.4.4; en-US; XT1022 Build/KXC21.5-40) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/10.7.0.636 U3/0.8.0 Mobile Safari/534.30'
-      },
-      {
-        title: 'UC Browser \u2014 iOS',
-        value: 'UCWEB/2.0 (iPad; U; CPU OS 7_1 like Mac OS X; en; iPad3,6) U2/1.0.0 UCBrowser/9.3.1.344'
-      },
-      {
-        title: 'UC Browser \u2014 Windows Phone',
-        value:
-            'NokiaX2-02/2.0 (11.79) Profile/MIDP-2.1 Configuration/CLDC-1.1 Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2;.NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2) UCBrowser8.4.0.159/70/352'
-      }
-    ]
-  }
-];
diff --git a/front_end/network/NetworkDataGridNode.js b/front_end/network/NetworkDataGridNode.js
deleted file mode 100644
index a2819ff..0000000
--- a/front_end/network/NetworkDataGridNode.js
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Network.NetworkNode = class extends DataGrid.SortableDataGridNode {
-  /**
-   * @param {!Network.NetworkLogView} parentView
-   */
-  constructor(parentView) {
-    super({});
-    this._parentView = parentView;
-    this._isHovered = false;
-    this._isProduct = false;
-    this._showingInitiatorChain = false;
-    /** @type {?SDK.NetworkRequest} */
-    this._requestOrFirstKnownChildRequest = null;
-  }
-
-  /**
-   * @return {!Network.NetworkNode._SupportedBackgroundColors}
-   */
-  static _themedBackgroundColors() {
-    if (Network.NetworkNode._themedBackgroundColorsCache)
-      return Network.NetworkNode._themedBackgroundColorsCache;
-    const themedColors = {};
-    for (const name in Network.NetworkNode._backgroundColors) {
-      const color = Common.Color.fromRGBA(Network.NetworkNode._backgroundColors[name]);
-      themedColors[name] = UI.themeSupport.patchColor(color, UI.ThemeSupport.ColorUsage.Background);
-    }
-    Network.NetworkNode._themedBackgroundColorsCache =
-        /** @type {!Network.NetworkNode._SupportedBackgroundColors} */ (themedColors);
-    return Network.NetworkNode._themedBackgroundColorsCache;
-  }
-
-  /**
-   * @return {string}
-   */
-  displayName() {
-    return '';
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = this.createTD(columnId);
-    this.renderCell(cell, columnId);
-    return cell;
-  }
-
-  /**
-   * @protected
-   * @param {!Element} cell
-   * @param {string} columnId
-   */
-  renderCell(cell, columnId) {
-  }
-
-  /**
-   * @return {string}
-   */
-  backgroundColor() {
-    const bgColors = Network.NetworkNode._themedBackgroundColors();
-    if (this.selected)
-      return /** @type {string} */ (bgColors.Selected.asString(Common.Color.Format.HEX));
-    let color = this.isStriped() ? bgColors.Stripe : bgColors.Default;
-    if (this.isNavigationRequest())
-      color = color.blendWith(bgColors.Navigation);
-    if (this.hovered())
-      color = color.blendWith(bgColors.Hovered);
-    if (this.isOnInitiatorPath())
-      color = color.blendWith(bgColors.InitiatorPath);
-    if (this.isOnInitiatedPath())
-      color = color.blendWith(bgColors.InitiatedPath);
-
-    return /** @type {string} */ (color.asString(Common.Color.Format.HEX));
-  }
-
-  _updateBackgroundColor() {
-    const element = this.existingElement();
-    if (!element)
-      return;
-    element.style.backgroundColor = this.backgroundColor();
-    this._parentView.stylesChanged();
-  }
-
-  /**
-   * @override
-   * @param {boolean} isStriped
-   */
-  setStriped(isStriped) {
-    super.setStriped(isStriped);
-    this._updateBackgroundColor();
-  }
-
-  /**
-   * @return {!Network.NetworkLogView}
-   */
-  parentView() {
-    return this._parentView;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hovered() {
-    return this._isHovered;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  showingInitiatorChain() {
-    return this._showingInitiatorChain;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  nodeSelfHeight() {
-    return this._parentView.rowHeight();
-  }
-
-  /**
-   * @param {boolean} hovered
-   * @param {boolean} showInitiatorChain
-   */
-  setHovered(hovered, showInitiatorChain) {
-    if (this._isHovered === hovered && this._showingInitiatorChain === showInitiatorChain)
-      return;
-    if (this._isHovered !== hovered) {
-      this._isHovered = hovered;
-      if (this.attached())
-        this.element().classList.toggle('hover', hovered);
-    }
-    if (this._showingInitiatorChain !== showInitiatorChain) {
-      this._showingInitiatorChain = showInitiatorChain;
-      this.showingInitiatorChainChanged();
-    }
-    this._parentView.stylesChanged();
-    this._updateBackgroundColor();
-  }
-
-  /**
-   * @protected
-   */
-  showingInitiatorChainChanged() {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isOnInitiatorPath() {
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isOnInitiatedPath() {
-    return false;
-  }
-
-  /**
-   * @return {?SDK.NetworkRequest}
-   */
-  request() {
-    return null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isNavigationRequest() {
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  clearFlatNodes() {
-    super.clearFlatNodes();
-    this._requestOrFirstKnownChildRequest = null;
-  }
-
-  /**
-   * @protected
-   * @return {?SDK.NetworkRequest}
-   */
-  requestOrFirstKnownChildRequest() {
-    if (this._requestOrFirstKnownChildRequest)
-      return this._requestOrFirstKnownChildRequest;
-    let request = this.request();
-    if (request || !this.hasChildren()) {
-      this._requestOrFirstKnownChildRequest = request;
-      return this._requestOrFirstKnownChildRequest;
-    }
-
-    let firstChildRequest = null;
-    const flatChildren = this.flatChildren();
-    for (let i = 0; i < flatChildren.length; i++) {
-      request = flatChildren[i].request();
-      if (!firstChildRequest || (request && request.issueTime() < firstChildRequest.issueTime()))
-        firstChildRequest = request;
-    }
-    this._requestOrFirstKnownChildRequest = firstChildRequest;
-    return this._requestOrFirstKnownChildRequest;
-  }
-};
-
-/** @type {!Object<string, !Array<number>>} */
-Network.NetworkNode._backgroundColors = {
-  Default: [255, 255, 255, 1.0],
-  Stripe: [245, 245, 245, 1.0],
-  Navigation: [221, 238, 255, 1.0],
-  Hovered: [235, 242, 252, 0.7],
-  InitiatorPath: [58, 217, 58, 0.4],
-  InitiatedPath: [217, 58, 58, 0.4],
-  Selected: [63, 81, 181, .6],
-  FromFrame: [224, 247, 250, .4],
-  IsProduct: [255, 252, 225, .6],
-};
-
-/** @typedef {!{
-  Default: !Common.Color,
-  Stripe: !Common.Color,
-  Navigation: !Common.Color,
-  Hovered: !Common.Color,
-  InitiatorPath: !Common.Color,
-  InitiatedPath: !Common.Color,
-  Selected: !Common.Color,
-  FromFrame: !Common.Color,
-  IsProduct: !Common.Color
-}} */
-Network.NetworkNode._SupportedBackgroundColors;
-
-/** @type {!Network.NetworkNode._SupportedBackgroundColors} */
-Network.NetworkNode._themedBackgroundColorsCache;
-
-/** @typedef {!{entry: !ProductRegistry.Registry.ProductEntry, matchedURL: !Common.ParsedURL}} */
-Network.NetworkNode._ProductEntryInfo;
-
-/**
- * @unrestricted
- */
-Network.NetworkRequestNode = class extends Network.NetworkNode {
-  /**
-   * @param {!Network.NetworkLogView} parentView
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(parentView, request) {
-    super(parentView);
-    /** @type {?Element} */
-    this._nameCell = null;
-    /** @type {?Element} */
-    this._nameBadgeElement = null;
-    /** @type {?Element} */
-    this._initiatorCell = null;
-    this._request = request;
-    this._isNavigationRequest = false;
-    this.selectable = true;
-    this._isOnInitiatorPath = false;
-    this._isOnInitiatedPath = false;
-  }
-
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static NameComparator(a, b) {
-    const aName = a.displayName().toLowerCase();
-    const bName = b.displayName().toLowerCase();
-    if (aName === bName) {
-      const aRequest = a.requestOrFirstKnownChildRequest();
-      const bRequest = b.requestOrFirstKnownChildRequest();
-      if (aRequest && bRequest)
-        return aRequest.indentityCompare(bRequest);
-      return aRequest ? -1 : 1;
-    }
-    return aName < bName ? -1 : 1;
-  }
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static RemoteAddressComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aRemoteAddress = aRequest.remoteAddress();
-    const bRemoteAddress = bRequest.remoteAddress();
-    if (aRemoteAddress > bRemoteAddress)
-      return 1;
-    if (bRemoteAddress > aRemoteAddress)
-      return -1;
-    return aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {!ProductRegistry.Registry} productRegistry
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static ProductComparator(productRegistry, a, b) {
-    const aRequest = a.request();
-    const bRequest = b.request();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aName = productRegistry.nameForUrl(aRequest.parsedURL) || '';
-    const bName = productRegistry.nameForUrl(bRequest.parsedURL) || '';
-    return aName.localeCompare(bName) || aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static SizeComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    if (bRequest.cached() && !aRequest.cached())
-      return 1;
-    if (aRequest.cached() && !bRequest.cached())
-      return -1;
-    return (aRequest.transferSize - bRequest.transferSize) || aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static TypeComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aSimpleType = a.displayType();
-    const bSimpleType = b.displayType();
-
-    if (aSimpleType > bSimpleType)
-      return 1;
-    if (bSimpleType > aSimpleType)
-      return -1;
-    return aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static InitiatorComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    if (!a._initiatorCell || !b._initiatorCell)
-      return !a._initiatorCell ? -1 : 1;
-    const aText = a._linkifiedInitiatorAnchor ? a._linkifiedInitiatorAnchor.textContent : a._initiatorCell.title;
-    const bText = b._linkifiedInitiatorAnchor ? b._linkifiedInitiatorAnchor.textContent : b._initiatorCell.title;
-    return aText.localeCompare(bText);
-  }
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static RequestCookiesCountComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aScore = aRequest.requestCookies ? aRequest.requestCookies.length : 0;
-    const bScore = bRequest.requestCookies ? bRequest.requestCookies.length : 0;
-    return (aScore - bScore) || aRequest.indentityCompare(bRequest);
-  }
-
-  // TODO(allada) This function deserves to be in a network-common of some sort.
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static ResponseCookiesCountComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aScore = aRequest.responseCookies ? aRequest.responseCookies.length : 0;
-    const bScore = bRequest.responseCookies ? bRequest.responseCookies.length : 0;
-    return (aScore - bScore) || aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static PriorityComparator(a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aPriority = aRequest.priority();
-    let aScore = aPriority ? PerfUI.networkPriorityWeight(aPriority) : 0;
-    aScore = aScore || 0;
-    const bPriority = bRequest.priority();
-    let bScore = bPriority ? PerfUI.networkPriorityWeight(bPriority) : 0;
-    bScore = bScore || 0;
-
-    return aScore - bScore || aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static RequestPropertyComparator(propertyName, a, b) {
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aValue = aRequest[propertyName];
-    const bValue = bRequest[propertyName];
-    if (aValue === bValue)
-      return aRequest.indentityCompare(bRequest);
-    return aValue > bValue ? 1 : -1;
-  }
-
-  /**
-   * @param {string} propertyName
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static ResponseHeaderStringComparator(propertyName, a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aValue = String(aRequest.responseHeaderValue(propertyName) || '');
-    const bValue = String(bRequest.responseHeaderValue(propertyName) || '');
-    return aValue.localeCompare(bValue) || aRequest.indentityCompare(bRequest);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static ResponseHeaderNumberComparator(propertyName, a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aValue = (aRequest.responseHeaderValue(propertyName) !== undefined) ?
-        parseFloat(aRequest.responseHeaderValue(propertyName)) :
-        -Infinity;
-    const bValue = (bRequest.responseHeaderValue(propertyName) !== undefined) ?
-        parseFloat(bRequest.responseHeaderValue(propertyName)) :
-        -Infinity;
-    if (aValue === bValue)
-      return aRequest.indentityCompare(bRequest);
-    return aValue > bValue ? 1 : -1;
-  }
-
-  /**
-   * @param {string} propertyName
-   * @param {!Network.NetworkNode} a
-   * @param {!Network.NetworkNode} b
-   * @return {number}
-   */
-  static ResponseHeaderDateComparator(propertyName, a, b) {
-    // TODO(allada) Handle this properly for group nodes.
-    const aRequest = a.requestOrFirstKnownChildRequest();
-    const bRequest = b.requestOrFirstKnownChildRequest();
-    if (!aRequest || !bRequest)
-      return !aRequest ? -1 : 1;
-    const aHeader = aRequest.responseHeaderValue(propertyName);
-    const bHeader = bRequest.responseHeaderValue(propertyName);
-    const aValue = aHeader ? new Date(aHeader).getTime() : -Infinity;
-    const bValue = bHeader ? new Date(bHeader).getTime() : -Infinity;
-    if (aValue === bValue)
-      return aRequest.indentityCompare(bRequest);
-    return aValue > bValue ? 1 : -1;
-  }
-
-  /**
-   * @override
-   */
-  showingInitiatorChainChanged() {
-    const showInitiatorChain = this.showingInitiatorChain();
-
-    const initiatorGraph = BrowserSDK.networkLog.initiatorGraphForRequest(this._request);
-    for (const request of initiatorGraph.initiators) {
-      if (request === this._request)
-        continue;
-      const node = this.parentView().nodeForRequest(request);
-      if (!node)
-        continue;
-      node._setIsOnInitiatorPath(showInitiatorChain);
-    }
-    for (const request of initiatorGraph.initiated) {
-      if (request === this._request)
-        continue;
-      const node = this.parentView().nodeForRequest(request);
-      if (!node)
-        continue;
-      node._setIsOnInitiatedPath(showInitiatorChain);
-    }
-  }
-
-  /**
-   * @param {boolean} isOnInitiatorPath
-   */
-  _setIsOnInitiatorPath(isOnInitiatorPath) {
-    if (this._isOnInitiatorPath === isOnInitiatorPath || !this.attached())
-      return;
-    this._isOnInitiatorPath = isOnInitiatorPath;
-    this._updateBackgroundColor();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isOnInitiatorPath() {
-    return this._isOnInitiatorPath;
-  }
-
-  /**
-   * @param {boolean} isOnInitiatedPath
-   */
-  _setIsOnInitiatedPath(isOnInitiatedPath) {
-    if (this._isOnInitiatedPath === isOnInitiatedPath || !this.attached())
-      return;
-    this._isOnInitiatedPath = isOnInitiatedPath;
-    this._updateBackgroundColor();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isOnInitiatedPath() {
-    return this._isOnInitiatedPath;
-  }
-
-  /**
-   * @return {string}
-   */
-  displayType() {
-    const mimeType = this._request.mimeType || this._request.requestContentType() || '';
-    const resourceType = this._request.resourceType();
-    let simpleType = resourceType.name();
-
-    if (resourceType === Common.resourceTypes.Other || resourceType === Common.resourceTypes.Image)
-      simpleType = mimeType.replace(/^(application|image)\//, '');
-
-    return simpleType;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  displayName() {
-    return this._request.name();
-  }
-
-  /**
-   * @override
-   * @return {!SDK.NetworkRequest}
-   */
-  request() {
-    return this._request;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isNavigationRequest() {
-    const pageLoad = BrowserSDK.PageLoad.forRequest(this._request);
-    return pageLoad ? pageLoad.mainRequest === this._request : false;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  nodeSelfHeight() {
-    return this.parentView().rowHeight();
-  }
-
-  /**
-   * @override
-   * @param {!Element} element
-   */
-  createCells(element) {
-    this._nameCell = null;
-    this._initiatorCell = null;
-
-    element.classList.toggle('network-error-row', this._isFailed());
-    element.classList.toggle('network-navigation-row', this._isNavigationRequest);
-    super.createCells(element);
-    this._updateBackgroundColor();
-    ProductRegistry.instance().then(productRegistry => {
-      if (productRegistry.entryForUrl(this._request.parsedURL)) {
-        this._isProduct = true;
-        this._updateBackgroundColor();
-      }
-    });
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} text
-   */
-  _setTextAndTitle(element, text) {
-    element.createTextChild(text);
-    element.title = text;
-  }
-
-  /**
-   * @override
-   * @param {!Element} cell
-   * @param {string} columnId
-   */
-  renderCell(cell, columnId) {
-    switch (columnId) {
-      case 'name':
-        this._renderNameCell(cell);
-        break;
-      case 'method':
-        this._setTextAndTitle(cell, this._request.requestMethod);
-        break;
-      case 'status':
-        this._renderStatusCell(cell);
-        break;
-      case 'protocol':
-        this._setTextAndTitle(cell, this._request.protocol);
-        break;
-      case 'scheme':
-        this._setTextAndTitle(cell, this._request.scheme);
-        break;
-      case 'domain':
-        this._setTextAndTitle(cell, this._request.domain);
-        break;
-      case 'remoteaddress':
-        this._setTextAndTitle(cell, this._request.remoteAddress());
-        break;
-      case 'cookies':
-        this._setTextAndTitle(cell, this._arrayLength(this._request.requestCookies));
-        break;
-      case 'setcookies':
-        this._setTextAndTitle(cell, this._arrayLength(this._request.responseCookies));
-        break;
-      case 'priority':
-        const priority = this._request.priority();
-        this._setTextAndTitle(cell, priority ? PerfUI.uiLabelForNetworkPriority(priority) : '');
-        break;
-      case 'connectionid':
-        this._setTextAndTitle(cell, this._request.connectionId);
-        break;
-      case 'type':
-        this._setTextAndTitle(cell, this.displayType());
-        break;
-      case 'initiator':
-        this._renderInitiatorCell(cell);
-        break;
-      case 'size':
-        this._renderSizeCell(cell);
-        break;
-      case 'time':
-        this._renderTimeCell(cell);
-        break;
-      case 'timeline':
-        this._setTextAndTitle(cell, '');
-        break;
-      default:
-        this._setTextAndTitle(cell, this._request.responseHeaderValue(columnId) || '');
-        break;
-    }
-  }
-
-  /**
-   * @param {?Array} array
-   * @return {string}
-   */
-  _arrayLength(array) {
-    return array ? '' + array.length : '';
-  }
-
-  /**
-   * @override
-   * @param {boolean=} supressSelectedEvent
-   */
-  select(supressSelectedEvent) {
-    super.select(supressSelectedEvent);
-    this.parentView().dispatchEventToListeners(Network.NetworkLogView.Events.RequestSelected, this._request);
-  }
-
-  /**
-   * @param {?RegExp} regexp
-   * @return {!Array.<!Object>}
-   */
-  highlightMatchedSubstring(regexp) {
-    if (!regexp)
-      return [];
-    // Ensure element is created.
-    this.element();
-    const domChanges = [];
-    const matchInfo = this._nameCell.textContent.match(regexp);
-    if (matchInfo)
-      UI.highlightSearchResult(this._nameCell, matchInfo.index, matchInfo[0].length, domChanges);
-    return domChanges;
-  }
-
-  _openInNewTab() {
-    InspectorFrontendHost.openInNewTab(this._request.url());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isFailed() {
-    return (this._request.failed && !this._request.statusCode) || (this._request.statusCode >= 400);
-  }
-
-  /**
-   * @param {!Element} cell
-   */
-  _renderNameCell(cell) {
-    const leftPadding = this.leftPadding ? this.leftPadding + 'px' : '';
-    cell.style.setProperty('padding-left', leftPadding);
-    this._nameCell = cell;
-    cell.addEventListener('dblclick', this._openInNewTab.bind(this), false);
-    let iconElement;
-    if (this._request.resourceType() === Common.resourceTypes.Image) {
-      const previewImage = createElementWithClass('img', 'image-network-icon-preview');
-      this._request.populateImageSource(previewImage);
-
-      iconElement = createElementWithClass('div', 'icon');
-      iconElement.appendChild(previewImage);
-    } else {
-      iconElement = createElementWithClass('img', 'icon');
-    }
-    iconElement.classList.add(this._request.resourceType().name());
-
-    cell.appendChild(iconElement);
-    if (!this._nameBadgeElement) {
-      this._nameBadgeElement = this.parentView().badgePool.badgeForURL(this._request.parsedURL);
-      this._nameBadgeElement.classList.add('network-badge');
-    }
-    cell.appendChild(this._nameBadgeElement);
-    const name = this._request.name().trimMiddle(100);
-    const networkManager = SDK.NetworkManager.forRequest(this._request);
-    cell.createTextChild(networkManager ? networkManager.target().decorateLabel(name) : name);
-    this._appendSubtitle(cell, this._request.path());
-    cell.title = this._request.url();
-  }
-
-  /**
-   * @param {!Element} cell
-   */
-  _renderStatusCell(cell) {
-    cell.classList.toggle(
-        'network-dim-cell', !this._isFailed() && (this._request.cached() || !this._request.statusCode));
-
-    if (this._request.failed && !this._request.canceled && !this._request.wasBlocked()) {
-      const failText = Common.UIString('(failed)');
-      if (this._request.localizedFailDescription) {
-        cell.createTextChild(failText);
-        this._appendSubtitle(cell, this._request.localizedFailDescription);
-        cell.title = failText + ' ' + this._request.localizedFailDescription;
-      } else {
-        this._setTextAndTitle(cell, failText);
-      }
-    } else if (this._request.statusCode) {
-      cell.createTextChild('' + this._request.statusCode);
-      this._appendSubtitle(cell, this._request.statusText);
-      cell.title = this._request.statusCode + ' ' + this._request.statusText;
-    } else if (this._request.parsedURL.isDataURL()) {
-      this._setTextAndTitle(cell, Common.UIString('(data)'));
-    } else if (this._request.canceled) {
-      this._setTextAndTitle(cell, Common.UIString('(canceled)'));
-    } else if (this._request.wasBlocked()) {
-      let reason = Common.UIString('other');
-      switch (this._request.blockedReason()) {
-        case Protocol.Network.BlockedReason.Csp:
-          reason = Common.UIString('csp');
-          break;
-        case Protocol.Network.BlockedReason.MixedContent:
-          reason = Common.UIString('mixed-content');
-          break;
-        case Protocol.Network.BlockedReason.Origin:
-          reason = Common.UIString('origin');
-          break;
-        case Protocol.Network.BlockedReason.Inspector:
-          reason = Common.UIString('devtools');
-          break;
-        case Protocol.Network.BlockedReason.Other:
-          reason = Common.UIString('other');
-          break;
-      }
-      this._setTextAndTitle(cell, Common.UIString('(blocked:%s)', reason));
-    } else if (this._request.finished) {
-      this._setTextAndTitle(cell, Common.UIString('Finished'));
-    } else {
-      this._setTextAndTitle(cell, Common.UIString('(pending)'));
-    }
-  }
-
-  /**
-   * @param {!Element} cell
-   */
-  _renderInitiatorCell(cell) {
-    this._initiatorCell = cell;
-    const request = this._request;
-    const initiator = BrowserSDK.networkLog.initiatorInfoForRequest(request);
-
-    const timing = request.timing;
-    if (timing && timing.pushStart)
-      cell.appendChild(createTextNode(Common.UIString('Push / ')));
-    switch (initiator.type) {
-      case SDK.NetworkRequest.InitiatorType.Parser:
-        cell.title = initiator.url + ':' + (initiator.lineNumber + 1);
-        const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(initiator.url);
-        cell.appendChild(Components.Linkifier.linkifyURL(initiator.url, {
-          text: uiSourceCode ? uiSourceCode.displayName() : undefined,
-          lineNumber: initiator.lineNumber,
-          columnNumber: initiator.columnNumber
-        }));
-        this._appendSubtitle(cell, Common.UIString('Parser'));
-        break;
-
-      case SDK.NetworkRequest.InitiatorType.Redirect:
-        cell.title = initiator.url;
-        const redirectSource = /** @type {!SDK.NetworkRequest} */ (request.redirectSource());
-        console.assert(redirectSource);
-        if (this.parentView().nodeForRequest(redirectSource)) {
-          cell.appendChild(
-              Components.Linkifier.linkifyRevealable(redirectSource, Bindings.displayNameForURL(redirectSource.url())));
-        } else {
-          cell.appendChild(Components.Linkifier.linkifyURL(redirectSource.url()));
-        }
-        this._appendSubtitle(cell, Common.UIString('Redirect'));
-        break;
-
-      case SDK.NetworkRequest.InitiatorType.Script:
-        const networkManager = SDK.NetworkManager.forRequest(request);
-        if (initiator.stack) {
-          this._linkifiedInitiatorAnchor = this.parentView().linkifier.linkifyStackTraceTopFrame(
-              networkManager ? networkManager.target() : null, initiator.stack);
-        } else {
-          this._linkifiedInitiatorAnchor = this.parentView().linkifier.linkifyScriptLocation(
-              networkManager ? networkManager.target() : null, initiator.scriptId, initiator.url, initiator.lineNumber,
-              initiator.columnNumber);
-        }
-        this._linkifiedInitiatorAnchor.title = '';
-        cell.appendChild(this._linkifiedInitiatorAnchor);
-        this._appendSubtitle(cell, Common.UIString('Script'));
-        cell.classList.add('network-script-initiated');
-        cell.request = request;
-        break;
-
-      case SDK.NetworkRequest.InitiatorType.Preload:
-        cell.title = Common.UIString('Preload');
-        cell.classList.add('network-dim-cell');
-        cell.appendChild(createTextNode(Common.UIString('Preload')));
-        break;
-
-      default:
-        cell.title = Common.UIString('Other');
-        cell.classList.add('network-dim-cell');
-        cell.appendChild(createTextNode(Common.UIString('Other')));
-    }
-  }
-
-  /**
-   * @param {!Element} cell
-   */
-  _renderSizeCell(cell) {
-    if (this._request.fetchedViaServiceWorker) {
-      this._setTextAndTitle(cell, Common.UIString('(from ServiceWorker)'));
-      cell.classList.add('network-dim-cell');
-    } else if (this._request.cached()) {
-      if (this._request.cachedInMemory())
-        this._setTextAndTitle(cell, Common.UIString('(from memory cache)'));
-      else
-        this._setTextAndTitle(cell, Common.UIString('(from disk cache)'));
-      cell.classList.add('network-dim-cell');
-    } else {
-      const resourceSize = Number.bytesToString(this._request.resourceSize);
-      const transferSize = Number.bytesToString(this._request.transferSize);
-      this._setTextAndTitle(cell, transferSize);
-      this._appendSubtitle(cell, resourceSize);
-    }
-  }
-
-  /**
-   * @param {!Element} cell
-   */
-  _renderTimeCell(cell) {
-    if (this._request.duration > 0) {
-      this._setTextAndTitle(cell, Number.secondsToString(this._request.duration));
-      this._appendSubtitle(cell, Number.secondsToString(this._request.latency));
-    } else {
-      cell.classList.add('network-dim-cell');
-      this._setTextAndTitle(cell, Common.UIString('Pending'));
-    }
-  }
-
-  /**
-   * @param {!Element} cellElement
-   * @param {string} subtitleText
-   */
-  _appendSubtitle(cellElement, subtitleText) {
-    const subtitleElement = createElement('div');
-    subtitleElement.className = 'network-cell-subtitle';
-    subtitleElement.textContent = subtitleText;
-    cellElement.appendChild(subtitleElement);
-  }
-};
-
-Network.NetworkGroupNode = class extends Network.NetworkNode {
-  /**
-   * @override
-   * @param {!Element} cell
-   * @param {string} columnId
-   */
-  renderCell(cell, columnId) {
-    if (columnId === 'name') {
-      const leftPadding = this.leftPadding ? this.leftPadding + 'px' : '';
-      cell.style.setProperty('padding-left', leftPadding);
-      cell.classList.add('disclosure');
-    }
-  }
-
-  /**
-   * @override
-   * @param {boolean=} supressSelectedEvent
-   */
-  select(supressSelectedEvent) {
-    if (this.expanded) {
-      this.collapse();
-      return;
-    }
-    this.expand();
-  }
-};
diff --git a/front_end/network/NetworkFrameGrouper.js b/front_end/network/NetworkFrameGrouper.js
deleted file mode 100644
index 0e39df6..0000000
--- a/front_end/network/NetworkFrameGrouper.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Network.GroupLookupInterface}
- */
-Network.NetworkFrameGrouper = class {
-  /**
-   * @param {!Network.NetworkLogView} parentView
-   */
-  constructor(parentView) {
-    this._parentView = parentView;
-    /** @type {!Map<!SDK.ResourceTreeFrame, !Network.FrameGroupNode>} */
-    this._activeGroups = new Map();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkRequest} request
-   * @return {?Network.NetworkGroupNode}
-   */
-  groupNodeForRequest(request) {
-    const frame = SDK.ResourceTreeModel.frameForRequest(request);
-    if (!frame || frame.isTopFrame())
-      return null;
-    let groupNode = this._activeGroups.get(frame);
-    if (groupNode)
-      return groupNode;
-    groupNode = new Network.FrameGroupNode(this._parentView, frame);
-    this._activeGroups.set(frame, groupNode);
-    return groupNode;
-  }
-
-  /**
-   * @override
-   */
-  reset() {
-    this._activeGroups.clear();
-  }
-};
-
-Network.FrameGroupNode = class extends Network.NetworkGroupNode {
-  /**
-   * @param {!Network.NetworkLogView} parentView
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  constructor(parentView, frame) {
-    super(parentView);
-    this._frame = frame;
-    /** @type {?Element} */
-    this._productBadge = null;
-  }
-
-  /**
-   * @override
-   */
-  displayName() {
-    return new Common.ParsedURL(this._frame.url).domain() || this._frame.name || '<iframe>';
-  }
-
-  /**
-   * @override
-   * @param {!Element} cell
-   * @param {string} columnId
-   */
-  renderCell(cell, columnId) {
-    super.renderCell(cell, columnId);
-    if (columnId === 'name') {
-      const name = this.displayName();
-      if (!this._productBadge) {
-        this._productBadge = this.parentView().badgePool.badgeForFrame(this._frame);
-        this._productBadge.classList.add('network-frame-group-badge');
-      }
-      cell.appendChild(UI.Icon.create('largeicon-navigator-frame', 'network-frame-group-icon'));
-      cell.appendChild(this._productBadge);
-      cell.createTextChild(name);
-      cell.title = name;
-    }
-  }
-};
diff --git a/front_end/network/NetworkItemView.js b/front_end/network/NetworkItemView.js
deleted file mode 100644
index 6954773..0000000
--- a/front_end/network/NetworkItemView.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Network.NetworkItemView = class extends UI.TabbedPane {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {!Network.NetworkTimeCalculator} calculator
-   */
-  constructor(request, calculator) {
-    super();
-    this.element.classList.add('network-item-view');
-
-    this._resourceViewTabSetting = Common.settings.createSetting('resourceViewTab', 'preview');
-
-    this._headersView = new Network.RequestHeadersView(request);
-    this.appendTab(Network.NetworkItemView.Tabs.Headers, Common.UIString('Headers'), this._headersView);
-
-    this.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-
-    if (request.resourceType() === Common.resourceTypes.WebSocket) {
-      const frameView = new Network.ResourceWebSocketFrameView(request);
-      this.appendTab(Network.NetworkItemView.Tabs.WsFrames, Common.UIString('Frames'), frameView);
-    } else if (request.mimeType === 'text/event-stream') {
-      this.appendTab(
-          Network.NetworkItemView.Tabs.EventSource, Common.UIString('EventStream'),
-          new Network.EventSourceMessagesView(request));
-    } else {
-      this._responseView = new Network.RequestResponseView(request);
-      const previewView = new Network.RequestPreviewView(request);
-      this.appendTab(Network.NetworkItemView.Tabs.Preview, Common.UIString('Preview'), previewView);
-      this.appendTab(Network.NetworkItemView.Tabs.Response, Common.UIString('Response'), this._responseView);
-    }
-
-    if (request.requestCookies || request.responseCookies) {
-      this._cookiesView = new Network.RequestCookiesView(request);
-      this.appendTab(Network.NetworkItemView.Tabs.Cookies, Common.UIString('Cookies'), this._cookiesView);
-    }
-
-    this.appendTab(
-        Network.NetworkItemView.Tabs.Timing, Common.UIString('Timing'),
-        new Network.RequestTimingView(request, calculator));
-
-    this._request = request;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._selectTab();
-  }
-
-  /**
-   * @param {string=} tabId
-   */
-  _selectTab(tabId) {
-    if (!tabId)
-      tabId = this._resourceViewTabSetting.get();
-
-    if (!this.selectTab(tabId))
-      this.selectTab('headers');
-  }
-
-  _tabSelected(event) {
-    if (!event.data.isUserGesture)
-      return;
-    this._resourceViewTabSetting.set(event.data.tabId);
-  }
-
-  /**
-   * @return {!SDK.NetworkRequest}
-   */
-  request() {
-    return this._request;
-  }
-
-  /**
-   * @param {number=} line
-   * @return {!Promise}
-   */
-  async revealResponseBody(line) {
-    this._selectTab(Network.NetworkItemView.Tabs.Response);
-    if (this._responseView && typeof line === 'number')
-      await this._responseView.revealLine(/** @type {number} */ (line));
-  }
-
-  /**
-   * @param {string} header
-   */
-  revealRequestHeader(header) {
-    this._selectTab(Network.NetworkItemView.Tabs.Headers);
-    this._headersView.revealRequestHeader(header);
-  }
-
-  /**
-   * @param {string} header
-   */
-  revealResponseHeader(header) {
-    this._selectTab(Network.NetworkItemView.Tabs.Headers);
-    this._headersView.revealResponseHeader(header);
-  }
-};
-
-/**
- * @enum {string}
- */
-Network.NetworkItemView.Tabs = {
-  Cookies: 'cookies',
-  EventSource: 'eventSource',
-  Headers: 'headers',
-  Preview: 'preview',
-  Response: 'response',
-  Timing: 'timing',
-  WsFrames: 'webSocketFrames'
-};
diff --git a/front_end/network/NetworkLogView.js b/front_end/network/NetworkLogView.js
deleted file mode 100644
index 57d4010..0000000
--- a/front_end/network/NetworkLogView.js
+++ /dev/null
@@ -1,1860 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.NetworkManager>}
- */
-Network.NetworkLogView = class extends UI.VBox {
-  /**
-   * @param {!UI.FilterBar} filterBar
-   * @param {!Element} progressBarContainer
-   * @param {!Common.Setting} networkLogLargeRowsSetting
-   */
-  constructor(filterBar, progressBarContainer, networkLogLargeRowsSetting) {
-    super();
-    this.setMinimumSize(50, 64);
-    this.registerRequiredCSS('network/networkLogView.css');
-
-    this.element.id = 'network-container';
-
-    this._networkHideDataURLSetting = Common.settings.createSetting('networkHideDataURL', false);
-    this._networkResourceTypeFiltersSetting = Common.settings.createSetting('networkResourceTypeFilters', {});
-
-    this._rawRowHeight = 0;
-    this._progressBarContainer = progressBarContainer;
-    this._networkLogLargeRowsSetting = networkLogLargeRowsSetting;
-    this._networkLogLargeRowsSetting.addChangeListener(updateRowHeight.bind(this), this);
-
-    /**
-     * @this {Network.NetworkLogView}
-     */
-    function updateRowHeight() {
-      this._rawRowHeight = !!this._networkLogLargeRowsSetting.get() ? 41 : 21;
-      this._rowHeight = this._computeRowHeight();
-    }
-    this._rawRowHeight = 0;
-    this._rowHeight = 0;
-    updateRowHeight.call(this);
-
-    /** @type {!Network.NetworkTransferTimeCalculator} */
-    this._timeCalculator = new Network.NetworkTransferTimeCalculator();
-    /** @type {!Network.NetworkTransferDurationCalculator} */
-    this._durationCalculator = new Network.NetworkTransferDurationCalculator();
-    this._calculator = this._timeCalculator;
-
-    this._columns = new Network.NetworkLogViewColumns(
-        this, this._timeCalculator, this._durationCalculator, networkLogLargeRowsSetting);
-    this._columns.show(this.element);
-
-    /** @type {!Set<!SDK.NetworkRequest>} */
-    this._staleRequests = new Set();
-    /** @type {number} */
-    this._mainRequestLoadTime = -1;
-    /** @type {number} */
-    this._mainRequestDOMContentLoadedTime = -1;
-    this._highlightedSubstringChanges = [];
-
-    /** @type {!Array.<!Network.NetworkLogView.Filter>} */
-    this._filters = [];
-    /** @type {?Network.NetworkLogView.Filter} */
-    this._timeFilter = null;
-    /** @type {?Network.NetworkNode} */
-    this._hoveredNode = null;
-    /** @type {?Element} */
-    this._recordingHint = null;
-    /** @type {?number} */
-    this._refreshRequestId = null;
-    /** @type {?Network.NetworkRequestNode} */
-    this._highlightedNode = null;
-
-    this.linkifier = new Components.Linkifier();
-    this.badgePool = new ProductRegistry.BadgePool();
-
-    this._recording = false;
-    this._needsRefresh = false;
-
-    this._headerHeight = 0;
-
-    /** @type {!Map<string, !Network.GroupLookupInterface>} */
-    this._groupLookups = new Map();
-    this._groupLookups.set('Frame', new Network.NetworkFrameGrouper(this));
-
-    /** @type {?Network.GroupLookupInterface} */
-    this._activeGroupLookup = null;
-
-    this._textFilterUI = new UI.TextFilterUI();
-    this._textFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged, this);
-    filterBar.addFilter(this._textFilterUI);
-
-    this._dataURLFilterUI = new UI.CheckboxFilterUI(
-        'hide-data-url', Common.UIString('Hide data URLs'), true, this._networkHideDataURLSetting);
-    this._dataURLFilterUI.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
-    filterBar.addFilter(this._dataURLFilterUI);
-
-    const filterItems =
-        Object.values(Common.resourceCategories)
-            .map(category => ({name: category.title, label: category.shortTitle, title: category.title}));
-    this._resourceCategoryFilterUI = new UI.NamedBitSetFilterUI(filterItems, this._networkResourceTypeFiltersSetting);
-    this._resourceCategoryFilterUI.addEventListener(
-        UI.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
-    filterBar.addFilter(this._resourceCategoryFilterUI);
-
-    this._filterParser = new TextUtils.FilterParser(Network.NetworkLogView._searchKeys);
-    this._suggestionBuilder =
-        new UI.FilterSuggestionBuilder(Network.NetworkLogView._searchKeys, Network.NetworkLogView._sortSearchValues);
-    this._resetSuggestionBuilder();
-
-    this._dataGrid = this._columns.dataGrid();
-    this._setupDataGrid();
-    this._columns.sortByCurrentColumn();
-
-    this._summaryBarElement = this.element.createChild('div', 'network-summary-bar');
-
-    new UI.DropTarget(
-        this.element, [UI.DropTarget.Type.File], Common.UIString('Drop HAR files here'), this._handleDrop.bind(this));
-
-    Common.moduleSetting('networkColorCodeResourceTypes')
-        .addChangeListener(this._invalidateAllItems.bind(this, false), this);
-
-    SDK.targetManager.observeModels(SDK.NetworkManager, this);
-    BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this);
-    BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this);
-    BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._reset, this);
-
-    this._updateGroupByFrame();
-    Common.moduleSetting('network.group-by-frame').addChangeListener(() => this._updateGroupByFrame());
-
-    this._filterBar = filterBar;
-    this._searchHint = new UI.HBox();
-    this._searchHint.element.classList.add('open-search-view');
-    this._filterStringSearchReminder = this._createSearchPrompt();
-    this._updateSearchPrompt();
-  }
-
-  _createSearchPrompt() {
-    const text = this._searchHint.contentElement.createChild('div', 'search-button');
-    text.createChild('span').textContent = ls`Search headers and response bodies for `;
-    const filterString = text.createChild('strong');
-    const button = UI.createTextButton('Find All', () => this._openSearchView());
-    this._searchHint.contentElement.appendChild(button);
-    this._filterBar.element.addEventListener('keydown', event => {
-      if (event.key === 'ArrowDown')
-        button.focus();
-    });
-    return filterString;
-  }
-
-
-  _updateGroupByFrame() {
-    const value = Common.moduleSetting('network.group-by-frame').get();
-    this._setGrouping(value ? 'Frame' : null);
-  }
-
-  /**
-   * @param {string} key
-   * @param {!Array<string>} values
-   */
-  static _sortSearchValues(key, values) {
-    if (key === Network.NetworkLogView.FilterType.Priority) {
-      values.sort((a, b) => {
-        const aPriority = /** @type {!Protocol.Network.ResourcePriority} */ (PerfUI.uiLabelToNetworkPriority(a));
-        const bPriority = /** @type {!Protocol.Network.ResourcePriority} */ (PerfUI.uiLabelToNetworkPriority(b));
-        return PerfUI.networkPriorityWeight(aPriority) - PerfUI.networkPriorityWeight(bPriority);
-      });
-    } else {
-      values.sort();
-    }
-  }
-
-  /**
-   * @param {!Network.NetworkLogView.Filter} filter
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _negativeFilter(filter, request) {
-    return !filter(request);
-  }
-
-  /**
-   * @param {?RegExp} regex
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestPathFilter(regex, request) {
-    if (!regex)
-      return false;
-
-    return regex.test(request.path() + '/' + request.name());
-  }
-
-  /**
-   * @param {string} domain
-   * @return {!Array.<string>}
-   */
-  static _subdomains(domain) {
-    const result = [domain];
-    let indexOfPeriod = domain.indexOf('.');
-    while (indexOfPeriod !== -1) {
-      result.push('*' + domain.substring(indexOfPeriod));
-      indexOfPeriod = domain.indexOf('.', indexOfPeriod + 1);
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} value
-   * @return {!Network.NetworkLogView.Filter}
-   */
-  static _createRequestDomainFilter(value) {
-    /**
-     * @param {string} string
-     * @return {string}
-     */
-    function escapeForRegExp(string) {
-      return string.escapeForRegExp();
-    }
-    const escapedPattern = value.split('*').map(escapeForRegExp).join('.*');
-    return Network.NetworkLogView._requestDomainFilter.bind(null, new RegExp('^' + escapedPattern + '$', 'i'));
-  }
-
-  /**
-   * @param {!RegExp} regex
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestDomainFilter(regex, request) {
-    return regex.test(request.domain);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _runningRequestFilter(request) {
-    return !request.finished;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _fromCacheRequestFilter(request) {
-    return request.cached();
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestResponseHeaderFilter(value, request) {
-    return request.responseHeaderValue(value) !== undefined;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestMethodFilter(value, request) {
-    return request.requestMethod === value;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestPriorityFilter(value, request) {
-    return request.priority() === value;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestMimeTypeFilter(value, request) {
-    return request.mimeType === value;
-  }
-
-  /**
-   * @param {!Network.NetworkLogView.MixedContentFilterValues} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestMixedContentFilter(value, request) {
-    if (value === Network.NetworkLogView.MixedContentFilterValues.Displayed)
-      return request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable;
-    else if (value === Network.NetworkLogView.MixedContentFilterValues.Blocked)
-      return request.mixedContentType === Protocol.Security.MixedContentType.Blockable && request.wasBlocked();
-    else if (value === Network.NetworkLogView.MixedContentFilterValues.BlockOverridden)
-      return request.mixedContentType === Protocol.Security.MixedContentType.Blockable && !request.wasBlocked();
-    else if (value === Network.NetworkLogView.MixedContentFilterValues.All)
-      return request.mixedContentType !== Protocol.Security.MixedContentType.None;
-
-    return false;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestSchemeFilter(value, request) {
-    return request.scheme === value;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestSetCookieDomainFilter(value, request) {
-    const cookies = request.responseCookies;
-    for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
-      if (cookies[i].domain() === value)
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestSetCookieNameFilter(value, request) {
-    const cookies = request.responseCookies;
-    for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
-      if (cookies[i].name() === value)
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestSetCookieValueFilter(value, request) {
-    const cookies = request.responseCookies;
-    for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
-      if (cookies[i].value() === value)
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {number} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestSizeLargerThanFilter(value, request) {
-    return request.transferSize >= value;
-  }
-
-  /**
-   * @param {string} value
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _statusCodeFilter(value, request) {
-    return ('' + request.statusCode) === value;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static HTTPRequestsFilter(request) {
-    return request.parsedURL.isValid && (request.scheme in Network.NetworkLogView.HTTPSchemas);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static FinishedRequestsFilter(request) {
-    return request.finished;
-  }
-
-  /**
-   * @param {number} windowStart
-   * @param {number} windowEnd
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static _requestTimeFilter(windowStart, windowEnd, request) {
-    if (request.issueTime() > windowEnd)
-      return false;
-    if (request.endTime !== -1 && request.endTime < windowStart)
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  static _copyRequestHeaders(request) {
-    InspectorFrontendHost.copyText(request.requestHeadersText());
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  static _copyResponseHeaders(request) {
-    InspectorFrontendHost.copyText(request.responseHeadersText);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  static async _copyResponse(request) {
-    const contentData = await request.contentData();
-    let content = contentData.content;
-    if (contentData.encoded) {
-      content = Common.ContentProvider.contentAsDataURL(
-          contentData.content, request.mimeType, contentData.encoded, contentData.encoded ? 'utf-8' : null);
-    }
-    InspectorFrontendHost.copyText(content || '');
-  }
-
-  /**
-   * @param {!DataTransfer} dataTransfer
-   */
-  _handleDrop(dataTransfer) {
-    const items = dataTransfer.items;
-    if (!items.length)
-      return;
-    const entry = items[0].webkitGetAsEntry();
-    if (entry.isDirectory)
-      return;
-
-    entry.file(this._onLoadFromFile.bind(this));
-  }
-
-  /**
-   * @param {!File} file
-   */
-  async _onLoadFromFile(file) {
-    const outputStream = new Common.StringOutputStream();
-    const reader = new Bindings.ChunkedFileReader(file, /* chunkSize */ 10000000);
-    const success = await reader.read(outputStream);
-    if (!success) {
-      this._harLoadFailed(reader.error().message);
-      return;
-    }
-    let harRoot;
-    try {
-      // HARRoot and JSON.parse might throw.
-      harRoot = new HARImporter.HARRoot(JSON.parse(outputStream.data()));
-    } catch (e) {
-      this._harLoadFailed(e);
-      return;
-    }
-    BrowserSDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log));
-  }
-
-  /**
-   * @param {string} message
-   */
-  _harLoadFailed(message) {
-    Common.console.error('Failed to load HAR file with following error: ' + message);
-  }
-
-  /**
-   * @param {?string} groupKey
-   */
-  _setGrouping(groupKey) {
-    if (this._activeGroupLookup)
-      this._activeGroupLookup.reset();
-    const groupLookup = groupKey ? this._groupLookups.get(groupKey) || null : null;
-    this._activeGroupLookup = groupLookup;
-    this._invalidateAllItems();
-  }
-
-  /**
-   * @return {number}
-   */
-  _computeRowHeight() {
-    return Math.round(this._rawRowHeight * window.devicePixelRatio) / window.devicePixelRatio;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?Network.NetworkRequestNode}
-   */
-  nodeForRequest(request) {
-    return request[Network.NetworkLogView._networkNodeSymbol] || null;
-  }
-
-  /**
-   * @return {number}
-   */
-  headerHeight() {
-    return this._headerHeight;
-  }
-
-  /**
-   * @param {boolean} recording
-   */
-  setRecording(recording) {
-    this._recording = recording;
-    this._updateSummaryBar();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager} networkManager
-   */
-  modelAdded(networkManager) {
-    // TODO(allada) Remove dependency on networkManager and instead use NetworkLog and PageLoad for needed data.
-    if (networkManager.target().parentTarget())
-      return;
-    const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
-    if (resourceTreeModel) {
-      resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
-      resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkManager} networkManager
-   */
-  modelRemoved(networkManager) {
-    if (!networkManager.target().parentTarget()) {
-      const resourceTreeModel = networkManager.target().model(SDK.ResourceTreeModel);
-      if (resourceTreeModel) {
-        resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
-        resourceTreeModel.removeEventListener(
-            SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
-      }
-    }
-  }
-
-  /**
-   * @param {number} start
-   * @param {number} end
-   */
-  setWindow(start, end) {
-    if (!start && !end) {
-      this._timeFilter = null;
-      this._timeCalculator.setWindow(null);
-    } else {
-      this._timeFilter = Network.NetworkLogView._requestTimeFilter.bind(null, start, end);
-      this._timeCalculator.setWindow(new Network.NetworkTimeBoundary(start, end));
-    }
-    this._filterRequests();
-  }
-
-  clearSelection() {
-    if (this._dataGrid.selectedNode)
-      this._dataGrid.selectedNode.deselect();
-  }
-
-  _resetSuggestionBuilder() {
-    this._suggestionBuilder.clear();
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Is, Network.NetworkLogView.IsFilterType.Running);
-    this._suggestionBuilder.addItem(
-        Network.NetworkLogView.FilterType.Is, Network.NetworkLogView.IsFilterType.FromCache);
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.LargerThan, '100');
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.LargerThan, '10k');
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.LargerThan, '1M');
-    this._textFilterUI.setSuggestionProvider(this._suggestionBuilder.completions.bind(this._suggestionBuilder));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _filterChanged(event) {
-    this.removeAllNodeHighlights();
-    this._parseFilterQuery(this._textFilterUI.value());
-    this._filterRequests();
-    this._updateSearchPrompt();
-  }
-
-  _showRecordingHint() {
-    this._hideRecordingHint();
-    this._recordingHint = this.element.createChild('div', 'network-status-pane fill');
-    const hintText = this._recordingHint.createChild('div', 'recording-hint');
-    const reloadShortcutNode = this._recordingHint.createChild('b');
-    reloadShortcutNode.textContent = UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0].name;
-
-    if (this._recording) {
-      const recordingText = hintText.createChild('span');
-      recordingText.textContent = Common.UIString('Recording network activity\u2026');
-      hintText.createChild('br');
-      hintText.appendChild(
-          UI.formatLocalized('Perform a request or hit %s to record the reload.', [reloadShortcutNode]));
-    } else {
-      const recordNode = hintText.createChild('b');
-      recordNode.textContent = UI.shortcutRegistry.shortcutTitleForAction('network.toggle-recording');
-      hintText.appendChild(UI.formatLocalized(
-          'Record (%s) or reload (%s) to display network activity.', [recordNode, reloadShortcutNode]));
-    }
-  }
-
-  _hideRecordingHint() {
-    if (this._recordingHint)
-      this._recordingHint.remove();
-    this._recordingHint = null;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    if (!this._dataGrid)  // Not initialized yet.
-      return [];
-    return [this._dataGrid.scrollContainer];
-  }
-
-  columnExtensionResolved() {
-    this._invalidateAllItems(true);
-  }
-
-  _setupDataGrid() {
-    this._dataGrid.setRowContextMenuCallback((contextMenu, node) => {
-      const request = node.request();
-      if (request)
-        this.handleContextMenuForRequest(contextMenu, request);
-    });
-    this._dataGrid.setStickToBottom(true);
-    this._dataGrid.setName('networkLog');
-    this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
-    this._dataGrid.element.classList.add('network-log-grid');
-    this._dataGrid.element.addEventListener('mousedown', this._dataGridMouseDown.bind(this), true);
-    this._dataGrid.element.addEventListener('mousemove', this._dataGridMouseMove.bind(this), true);
-    this._dataGrid.element.addEventListener('mouseleave', () => this._setHoveredNode(null), true);
-    return this._dataGrid;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _dataGridMouseMove(event) {
-    const node = (this._dataGrid.dataGridNodeFromNode(/** @type {!Node} */ (event.target)));
-    const highlightInitiatorChain = event.shiftKey;
-    this._setHoveredNode(node, highlightInitiatorChain);
-  }
-
-  /**
-   * @return {?Network.NetworkNode}
-   */
-  hoveredNode() {
-    return this._hoveredNode;
-  }
-
-  /**
-   * @param {?Network.NetworkNode} node
-   * @param {boolean=} highlightInitiatorChain
-   */
-  _setHoveredNode(node, highlightInitiatorChain) {
-    if (this._hoveredNode)
-      this._hoveredNode.setHovered(false, false);
-    this._hoveredNode = node;
-    if (this._hoveredNode)
-      this._hoveredNode.setHovered(true, !!highlightInitiatorChain);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _dataGridMouseDown(event) {
-    if (!this._dataGrid.selectedNode && event.button)
-      event.consume();
-  }
-
-  _updateSummaryBar() {
-    this._hideRecordingHint();
-
-    let transferSize = 0;
-    let selectedNodeNumber = 0;
-    let selectedTransferSize = 0;
-    let baseTime = -1;
-    let maxTime = -1;
-
-    let nodeCount = 0;
-    for (const request of BrowserSDK.networkLog.requests()) {
-      const node = request[Network.NetworkLogView._networkNodeSymbol];
-      if (!node)
-        continue;
-      nodeCount++;
-      const requestTransferSize = request.transferSize;
-      transferSize += requestTransferSize;
-      if (!node[Network.NetworkLogView._isFilteredOutSymbol]) {
-        selectedNodeNumber++;
-        selectedTransferSize += requestTransferSize;
-      }
-      const networkManager = SDK.NetworkManager.forRequest(request);
-      // TODO(allada) inspectedURL should be stored in PageLoad used instead of target so HAR requests can have an
-      // inspected url.
-      if (networkManager && request.url() === networkManager.target().inspectedURL() &&
-          request.resourceType() === Common.resourceTypes.Document && !networkManager.target().parentTarget())
-        baseTime = request.startTime;
-      if (request.endTime > maxTime)
-        maxTime = request.endTime;
-    }
-
-    if (!nodeCount) {
-      this._showRecordingHint();
-      return;
-    }
-
-    const summaryBar = this._summaryBarElement;
-    summaryBar.removeChildren();
-    const separator = '\u2002\u2758\u2002';
-    let text = '';
-    /**
-     * @param {string} chunk
-     * @return {!Element}
-     */
-    function appendChunk(chunk) {
-      const span = summaryBar.createChild('span');
-      span.textContent = chunk;
-      text += chunk;
-      return span;
-    }
-
-    if (selectedNodeNumber !== nodeCount) {
-      appendChunk(Common.UIString('%d / %d requests', selectedNodeNumber, nodeCount));
-      appendChunk(separator);
-      appendChunk(Common.UIString(
-          '%s / %s transferred', Number.bytesToString(selectedTransferSize), Number.bytesToString(transferSize)));
-    } else {
-      appendChunk(Common.UIString('%d requests', nodeCount));
-      appendChunk(separator);
-      appendChunk(Common.UIString('%s transferred', Number.bytesToString(transferSize)));
-    }
-    if (baseTime !== -1 && maxTime !== -1) {
-      appendChunk(separator);
-      appendChunk(Common.UIString('Finish: %s', Number.secondsToString(maxTime - baseTime)));
-      if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) {
-        appendChunk(separator);
-        const domContentLoadedText = Common.UIString(
-            'DOMContentLoaded: %s', Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime));
-        appendChunk(domContentLoadedText).classList.add('summary-blue');
-      }
-      if (this._mainRequestLoadTime !== -1) {
-        appendChunk(separator);
-        const loadText = Common.UIString('Load: %s', Number.secondsToString(this._mainRequestLoadTime - baseTime));
-        appendChunk(loadText).classList.add('summary-red');
-      }
-    }
-    summaryBar.title = text;
-  }
-
-  scheduleRefresh() {
-    if (this._needsRefresh)
-      return;
-
-    this._needsRefresh = true;
-
-    if (this.isShowing() && !this._refreshRequestId)
-      this._refreshRequestId = this.element.window().requestAnimationFrame(this._refresh.bind(this));
-  }
-
-  /**
-   * @param {!Array<number>} times
-   */
-  addFilmStripFrames(times) {
-    this._columns.addEventDividers(times, 'network-frame-divider');
-  }
-
-  /**
-   * @param {number} time
-   */
-  selectFilmStripFrame(time) {
-    this._columns.selectFilmStripFrame(time);
-  }
-
-  clearFilmStripFrame() {
-    this._columns.clearFilmStripFrame();
-  }
-
-  _refreshIfNeeded() {
-    if (this._needsRefresh)
-      this._refresh();
-  }
-
-  /**
-   * @param {boolean=} deferUpdate
-   */
-  _invalidateAllItems(deferUpdate) {
-    this._staleRequests = new Set(BrowserSDK.networkLog.requests());
-    if (deferUpdate)
-      this.scheduleRefresh();
-    else
-      this._refresh();
-  }
-
-  /**
-   * @return {!Network.NetworkTimeCalculator}
-   */
-  timeCalculator() {
-    return this._timeCalculator;
-  }
-
-  /**
-   * @return {!Network.NetworkTimeCalculator}
-   */
-  calculator() {
-    return this._calculator;
-  }
-
-  /**
-   * @param {!Network.NetworkTimeCalculator} x
-   */
-  setCalculator(x) {
-    if (!x || this._calculator === x)
-      return;
-
-    if (this._calculator !== x) {
-      this._calculator = x;
-      this._columns.setCalculator(this._calculator);
-    }
-    this._calculator.reset();
-
-    if (this._calculator.startAtZero)
-      this._columns.hideEventDividers();
-    else
-      this._columns.showEventDividers();
-
-    this._invalidateAllItems();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _loadEventFired(event) {
-    if (!this._recording)
-      return;
-
-    const time = /** @type {number} */ (event.data.loadTime);
-    if (time) {
-      this._mainRequestLoadTime = time;
-      this._columns.addEventDividers([time], 'network-red-divider');
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domContentLoadedEventFired(event) {
-    if (!this._recording)
-      return;
-    const data = /** @type {number} */ (event.data);
-    if (data) {
-      this._mainRequestDOMContentLoadedTime = data;
-      this._columns.addEventDividers([data], 'network-blue-divider');
-    }
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._refreshIfNeeded();
-    this._columns.wasShown();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._columns.willHide();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._rowHeight = this._computeRowHeight();
-  }
-
-  /**
-   * @return {!Array<!Network.NetworkNode>}
-   */
-  flatNodesList() {
-    return this._dataGrid.rootNode().flatChildren();
-  }
-
-  stylesChanged() {
-    this._columns.scheduleRefresh();
-  }
-
-  _refresh() {
-    this._needsRefresh = false;
-
-    if (this._refreshRequestId) {
-      this.element.window().cancelAnimationFrame(this._refreshRequestId);
-      this._refreshRequestId = null;
-    }
-
-    this.removeAllNodeHighlights();
-
-    this._timeCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
-    this._durationCalculator.updateBoundariesForEventTime(this._mainRequestLoadTime);
-    this._timeCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
-    this._durationCalculator.updateBoundariesForEventTime(this._mainRequestDOMContentLoadedTime);
-
-    /** @type {!Map<!Network.NetworkNode, !Network.NetworkNode>} */
-    const nodesToInsert = new Map();
-    /** @type {!Array<!Network.NetworkNode>} */
-    const nodesToRefresh = [];
-
-    /** @type {!Set<!Network.NetworkRequestNode>} */
-    const staleNodes = new Set();
-
-    // While creating nodes it may add more entries into _staleRequests because redirect request nodes update the parent
-    // node so we loop until we have no more stale requests.
-    while (this._staleRequests.size) {
-      const request = this._staleRequests.firstValue();
-      this._staleRequests.delete(request);
-      let node = request[Network.NetworkLogView._networkNodeSymbol];
-      if (!node)
-        node = this._createNodeForRequest(request);
-      staleNodes.add(node);
-    }
-
-    for (const node of staleNodes) {
-      const isFilteredOut = !this._applyFilter(node);
-      if (isFilteredOut && node === this._hoveredNode)
-        this._setHoveredNode(null);
-
-      if (!isFilteredOut)
-        nodesToRefresh.push(node);
-      const request = node.request();
-      this._timeCalculator.updateBoundaries(request);
-      this._durationCalculator.updateBoundaries(request);
-      const newParent = this._parentNodeForInsert(node);
-      if (node[Network.NetworkLogView._isFilteredOutSymbol] === isFilteredOut && node.parent === newParent)
-        continue;
-      node[Network.NetworkLogView._isFilteredOutSymbol] = isFilteredOut;
-      const removeFromParent = node.parent && (isFilteredOut || node.parent !== newParent);
-      if (removeFromParent) {
-        let parent = node.parent;
-        parent.removeChild(node);
-        while (parent && !parent.hasChildren() && parent.dataGrid && parent.dataGrid.rootNode() !== parent) {
-          const grandparent = parent.parent;
-          grandparent.removeChild(parent);
-          parent = grandparent;
-        }
-      }
-
-      if (!newParent || isFilteredOut)
-        continue;
-
-      if (!newParent.dataGrid && !nodesToInsert.has(newParent)) {
-        nodesToInsert.set(newParent, this._dataGrid.rootNode());
-        nodesToRefresh.push(newParent);
-      }
-      nodesToInsert.set(node, newParent);
-    }
-
-    for (const node of nodesToInsert.keys())
-      nodesToInsert.get(node).appendChild(node);
-
-    for (const node of nodesToRefresh)
-      node.refresh();
-
-    this._updateSummaryBar();
-
-    if (nodesToInsert.size)
-      this._columns.sortByCurrentColumn();
-
-    this._dataGrid.updateInstantly();
-    this._didRefreshForTest();
-  }
-
-  _didRefreshForTest() {
-  }
-
-  /**
-   * @param {!Network.NetworkRequestNode} node
-   * @return {?Network.NetworkNode}
-   */
-  _parentNodeForInsert(node) {
-    if (!this._activeGroupLookup)
-      return this._dataGrid.rootNode();
-
-    const groupNode = this._activeGroupLookup.groupNodeForRequest(node.request());
-    if (!groupNode)
-      return this._dataGrid.rootNode();
-    return groupNode;
-  }
-
-  _reset() {
-    this.dispatchEventToListeners(Network.NetworkLogView.Events.RequestSelected, null);
-
-    this._setHoveredNode(null);
-    this._columns.reset();
-
-    this._timeFilter = null;
-    this._calculator.reset();
-
-    this._timeCalculator.setWindow(null);
-    this.linkifier.reset();
-    this.badgePool.reset();
-
-    if (this._activeGroupLookup)
-      this._activeGroupLookup.reset();
-    this._staleRequests.clear();
-    this._resetSuggestionBuilder();
-
-    this._mainRequestLoadTime = -1;
-    this._mainRequestDOMContentLoadedTime = -1;
-
-    this._dataGrid.rootNode().removeChildren();
-    this._updateSummaryBar();
-    this._dataGrid.setStickToBottom(true);
-    this.scheduleRefresh();
-  }
-
-  /**
-   * @param {string} filterString
-   */
-  setTextFilterValue(filterString) {
-    this._textFilterUI.setValue(filterString);
-    this._dataURLFilterUI.setChecked(false);
-    this._resourceCategoryFilterUI.reset();
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  _createNodeForRequest(request) {
-    const node = new Network.NetworkRequestNode(this, request);
-    request[Network.NetworkLogView._networkNodeSymbol] = node;
-    node[Network.NetworkLogView._isFilteredOutSymbol] = true;
-
-    for (let redirect = request.redirectSource(); redirect; redirect = redirect.redirectSource())
-      this._refreshRequest(redirect);
-    return node;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestUpdated(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    this._refreshRequest(request);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  _refreshRequest(request) {
-    Network.NetworkLogView._subdomains(request.domain)
-        .forEach(
-            this._suggestionBuilder.addItem.bind(this._suggestionBuilder, Network.NetworkLogView.FilterType.Domain));
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Method, request.requestMethod);
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.MimeType, request.mimeType);
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.Scheme, '' + request.scheme);
-    this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.StatusCode, '' + request.statusCode);
-
-    const priority = request.priority();
-    if (priority) {
-      this._suggestionBuilder.addItem(
-          Network.NetworkLogView.FilterType.Priority, PerfUI.uiLabelForNetworkPriority(priority));
-    }
-
-    if (request.mixedContentType !== Protocol.Security.MixedContentType.None) {
-      this._suggestionBuilder.addItem(
-          Network.NetworkLogView.FilterType.MixedContent, Network.NetworkLogView.MixedContentFilterValues.All);
-    }
-
-    if (request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable) {
-      this._suggestionBuilder.addItem(
-          Network.NetworkLogView.FilterType.MixedContent, Network.NetworkLogView.MixedContentFilterValues.Displayed);
-    }
-
-    if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable) {
-      const suggestion = request.wasBlocked() ? Network.NetworkLogView.MixedContentFilterValues.Blocked :
-                                                Network.NetworkLogView.MixedContentFilterValues.BlockOverridden;
-      this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.MixedContent, suggestion);
-    }
-
-    const responseHeaders = request.responseHeaders;
-    for (let i = 0, l = responseHeaders.length; i < l; ++i)
-      this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.HasResponseHeader, responseHeaders[i].name);
-    const cookies = request.responseCookies;
-    for (let i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
-      const cookie = cookies[i];
-      this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieDomain, cookie.domain());
-      this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieName, cookie.name());
-      this._suggestionBuilder.addItem(Network.NetworkLogView.FilterType.SetCookieValue, cookie.value());
-    }
-
-    this._staleRequests.add(request);
-    this.scheduleRefresh();
-  }
-
-  /**
-   * @return {number}
-   */
-  rowHeight() {
-    return this._rowHeight;
-  }
-
-  /**
-   * @param {boolean} gridMode
-   */
-  switchViewMode(gridMode) {
-    this._columns.switchViewMode(gridMode);
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!SDK.NetworkRequest} request
-   */
-  handleContextMenuForRequest(contextMenu, request) {
-    contextMenu.appendApplicableItems(request);
-    let copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
-    const footerSection = copyMenu.footerSection();
-    if (request) {
-      copyMenu.defaultSection().appendItem(
-          UI.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, request.contentURL()));
-      if (request.requestHeadersText()) {
-        copyMenu.defaultSection().appendItem(
-            Common.UIString('Copy request headers'), Network.NetworkLogView._copyRequestHeaders.bind(null, request));
-      }
-
-      if (request.responseHeadersText) {
-        copyMenu.defaultSection().appendItem(
-            Common.UIString('Copy response headers'), Network.NetworkLogView._copyResponseHeaders.bind(null, request));
-      }
-
-      if (request.finished) {
-        copyMenu.defaultSection().appendItem(
-            Common.UIString('Copy response'), Network.NetworkLogView._copyResponse.bind(null, request));
-      }
-
-      if (Host.isWin()) {
-        footerSection.appendItem(
-            Common.UIString('Copy as PowerShell'), this._copyPowerShellCommand.bind(this, request));
-        footerSection.appendItem(Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request));
-        footerSection.appendItem(
-            Common.UIString('Copy as cURL (cmd)'), this._copyCurlCommand.bind(this, request, 'win'));
-        footerSection.appendItem(
-            Common.UIString('Copy as cURL (bash)'), this._copyCurlCommand.bind(this, request, 'unix'));
-        footerSection.appendItem(Common.UIString('Copy all as PowerShell'), this._copyAllPowerShellCommand.bind(this));
-        footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this));
-        footerSection.appendItem(Common.UIString('Copy all as cURL (cmd)'), this._copyAllCurlCommand.bind(this, 'win'));
-        footerSection.appendItem(
-            Common.UIString('Copy all as cURL (bash)'), this._copyAllCurlCommand.bind(this, 'unix'));
-      } else {
-        footerSection.appendItem(Common.UIString('Copy as fetch'), this._copyFetchCall.bind(this, request));
-        footerSection.appendItem(Common.UIString('Copy as cURL'), this._copyCurlCommand.bind(this, request, 'unix'));
-        footerSection.appendItem(Common.UIString('Copy all as fetch'), this._copyAllFetchCall.bind(this));
-        footerSection.appendItem(Common.UIString('Copy all as cURL'), this._copyAllCurlCommand.bind(this, 'unix'));
-      }
-    } else {
-      copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy'));
-    }
-    footerSection.appendItem(Common.UIString('Copy all as HAR'), this._copyAll.bind(this));
-
-    contextMenu.saveSection().appendItem(Common.UIString('Save as HAR with content'), this._exportAll.bind(this));
-
-    contextMenu.editSection().appendItem(Common.UIString('Clear browser cache'), this._clearBrowserCache.bind(this));
-    contextMenu.editSection().appendItem(
-        Common.UIString('Clear browser cookies'), this._clearBrowserCookies.bind(this));
-
-    if (request) {
-      const maxBlockedURLLength = 20;
-      const manager = SDK.multitargetNetworkManager;
-      let patterns = manager.blockedPatterns();
-
-      const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
-      if (urlWithoutScheme && !patterns.find(pattern => pattern.url === urlWithoutScheme)) {
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Block request URL'), addBlockedURL.bind(null, urlWithoutScheme));
-      } else if (urlWithoutScheme) {
-        const croppedURL = urlWithoutScheme.trimMiddle(maxBlockedURLLength);
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Unblock %s', croppedURL), removeBlockedURL.bind(null, urlWithoutScheme));
-      }
-
-      const domain = request.parsedURL.domain();
-      if (domain && !patterns.find(pattern => pattern.url === domain)) {
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Block request domain'), addBlockedURL.bind(null, domain));
-      } else if (domain) {
-        const croppedDomain = domain.trimMiddle(maxBlockedURLLength);
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Unblock %s', croppedDomain), removeBlockedURL.bind(null, domain));
-      }
-
-      if (SDK.NetworkManager.canReplayRequest(request)) {
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request));
-      }
-
-      /**
-       * @param {string} url
-       */
-      function addBlockedURL(url) {
-        patterns.push({enabled: true, url: url});
-        manager.setBlockedPatterns(patterns);
-        manager.setBlockingEnabled(true);
-        UI.viewManager.showView('network.blocked-urls');
-      }
-
-      /**
-       * @param {string} url
-       */
-      function removeBlockedURL(url) {
-        patterns = patterns.filter(pattern => pattern.url !== url);
-        manager.setBlockedPatterns(patterns);
-        UI.viewManager.showView('network.blocked-urls');
-      }
-    }
-  }
-
-  _harRequests() {
-    const httpRequests = BrowserSDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter);
-    return httpRequests.filter(Network.NetworkLogView.FinishedRequestsFilter);
-  }
-
-  async _copyAll() {
-    const harArchive = {log: await BrowserSDK.HARLog.build(this._harRequests())};
-    InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {string} platform
-   */
-  async _copyCurlCommand(request, platform) {
-    const command = await this._generateCurlCommand(request, platform);
-    InspectorFrontendHost.copyText(command);
-  }
-
-  /**
-   * @param {string} platform
-   */
-  async _copyAllCurlCommand(platform) {
-    const requests = BrowserSDK.networkLog.requests();
-    const commands = await Promise.all(requests.map(request => this._generateCurlCommand(request, platform)));
-    if (platform === 'win')
-      InspectorFrontendHost.copyText(commands.join(' &\r\n'));
-    else
-      InspectorFrontendHost.copyText(commands.join(' ;\n'));
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {string} platform
-   */
-  async _copyFetchCall(request, platform) {
-    const command = await this._generateFetchCall(request);
-    InspectorFrontendHost.copyText(command);
-  }
-
-  async _copyAllFetchCall() {
-    const requests = BrowserSDK.networkLog.requests();
-    const commands = await Promise.all(requests.map(request => this._generateFetchCall(request)));
-    InspectorFrontendHost.copyText(commands.join(' ;\n'));
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  async _copyPowerShellCommand(request) {
-    const command = await this._generatePowerShellCommand(request);
-    InspectorFrontendHost.copyText(command);
-  }
-
-  async _copyAllPowerShellCommand() {
-    const requests = BrowserSDK.networkLog.requests();
-    const commands = await Promise.all(requests.map(request => this._generatePowerShellCommand(request)));
-    InspectorFrontendHost.copyText(commands.join(';\r\n'));
-  }
-
-  async _exportAll() {
-    const url = SDK.targetManager.mainTarget().inspectedURL();
-    const parsedURL = url.asParsedURL();
-    const filename = parsedURL ? parsedURL.host : 'network-log';
-    const stream = new Bindings.FileOutputStream();
-
-    if (!await stream.open(filename + '.har'))
-      return;
-
-    const progressIndicator = new UI.ProgressIndicator();
-    this._progressBarContainer.appendChild(progressIndicator.element);
-    await Network.HARWriter.write(stream, this._harRequests(), progressIndicator);
-    progressIndicator.done();
-    stream.close();
-  }
-
-  _clearBrowserCache() {
-    if (confirm(Common.UIString('Are you sure you want to clear browser cache?')))
-      SDK.multitargetNetworkManager.clearBrowserCache();
-  }
-
-  _clearBrowserCookies() {
-    if (confirm(Common.UIString('Are you sure you want to clear browser cookies?')))
-      SDK.multitargetNetworkManager.clearBrowserCookies();
-  }
-
-  _removeAllHighlights() {
-    this.removeAllNodeHighlights();
-    for (let i = 0; i < this._highlightedSubstringChanges.length; ++i)
-      UI.revertDomChanges(this._highlightedSubstringChanges[i]);
-    this._highlightedSubstringChanges = [];
-  }
-
-  /**
-   * @param {!Network.NetworkRequestNode} node
-   * @return {boolean}
-   */
-  _applyFilter(node) {
-    const request = node.request();
-    if (this._timeFilter && !this._timeFilter(request))
-      return false;
-    const categoryName = request.resourceType().category().title;
-    if (!this._resourceCategoryFilterUI.accept(categoryName))
-      return false;
-    if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
-      return false;
-    if (request.statusText === 'Service Worker Fallback Required')
-      return false;
-    for (let i = 0; i < this._filters.length; ++i) {
-      if (!this._filters[i](request))
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @param {string} query
-   */
-  _parseFilterQuery(query) {
-    const descriptors = this._filterParser.parse(query);
-    this._filters = descriptors.map(descriptor => {
-      const key = descriptor.key;
-      const text = descriptor.text || '';
-      const regex = descriptor.regex;
-      let filter;
-      if (key) {
-        const defaultText = (key + ':' + text).escapeForRegExp();
-        filter = this._createSpecialFilter(/** @type {!Network.NetworkLogView.FilterType} */ (key), text) ||
-            Network.NetworkLogView._requestPathFilter.bind(null, new RegExp(defaultText, 'i'));
-      } else if (descriptor.regex) {
-        filter = Network.NetworkLogView._requestPathFilter.bind(null, /** @type {!RegExp} */ (regex));
-      } else {
-        filter = Network.NetworkLogView._requestPathFilter.bind(null, new RegExp(text.escapeForRegExp(), 'i'));
-      }
-      return descriptor.negative ? Network.NetworkLogView._negativeFilter.bind(null, filter) : filter;
-    });
-  }
-
-  /**
-   * @param {!Network.NetworkLogView.FilterType} type
-   * @param {string} value
-   * @return {?Network.NetworkLogView.Filter}
-   */
-  _createSpecialFilter(type, value) {
-    switch (type) {
-      case Network.NetworkLogView.FilterType.Domain:
-        return Network.NetworkLogView._createRequestDomainFilter(value);
-
-      case Network.NetworkLogView.FilterType.HasResponseHeader:
-        return Network.NetworkLogView._requestResponseHeaderFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.Is:
-        if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.Running)
-          return Network.NetworkLogView._runningRequestFilter;
-        if (value.toLowerCase() === Network.NetworkLogView.IsFilterType.FromCache)
-          return Network.NetworkLogView._fromCacheRequestFilter;
-        break;
-
-      case Network.NetworkLogView.FilterType.LargerThan:
-        return this._createSizeFilter(value.toLowerCase());
-
-      case Network.NetworkLogView.FilterType.Method:
-        return Network.NetworkLogView._requestMethodFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.MimeType:
-        return Network.NetworkLogView._requestMimeTypeFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.MixedContent:
-        return Network.NetworkLogView._requestMixedContentFilter.bind(
-            null, /** @type {!Network.NetworkLogView.MixedContentFilterValues} */ (value));
-
-      case Network.NetworkLogView.FilterType.Scheme:
-        return Network.NetworkLogView._requestSchemeFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.SetCookieDomain:
-        return Network.NetworkLogView._requestSetCookieDomainFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.SetCookieName:
-        return Network.NetworkLogView._requestSetCookieNameFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.SetCookieValue:
-        return Network.NetworkLogView._requestSetCookieValueFilter.bind(null, value);
-
-      case Network.NetworkLogView.FilterType.Priority:
-        return Network.NetworkLogView._requestPriorityFilter.bind(null, PerfUI.uiLabelToNetworkPriority(value));
-
-      case Network.NetworkLogView.FilterType.StatusCode:
-        return Network.NetworkLogView._statusCodeFilter.bind(null, value);
-    }
-    return null;
-  }
-
-  /**
-   * @param {string} value
-   * @return {?Network.NetworkLogView.Filter}
-   */
-  _createSizeFilter(value) {
-    let multiplier = 1;
-    if (value.endsWith('k')) {
-      multiplier = 1024;
-      value = value.substring(0, value.length - 1);
-    } else if (value.endsWith('m')) {
-      multiplier = 1024 * 1024;
-      value = value.substring(0, value.length - 1);
-    }
-    const quantity = Number(value);
-    if (isNaN(quantity))
-      return null;
-    return Network.NetworkLogView._requestSizeLargerThanFilter.bind(null, quantity * multiplier);
-  }
-
-  _filterRequests() {
-    this._removeAllHighlights();
-    this._invalidateAllItems();
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?Network.NetworkRequestNode}
-   */
-  _reveal(request) {
-    this.removeAllNodeHighlights();
-    const node = request[Network.NetworkLogView._networkNodeSymbol];
-    if (!node || !node.dataGrid)
-      return null;
-    node.reveal();
-    return node;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  revealAndHighlightRequest(request) {
-    const node = this._reveal(request);
-    if (node)
-      this._highlightNode(node);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  selectRequest(request) {
-    const node = this._reveal(request);
-    if (node)
-      node.select();
-  }
-
-  removeAllNodeHighlights() {
-    if (this._highlightedNode) {
-      this._highlightedNode.element().classList.remove('highlighted-row');
-      this._highlightedNode = null;
-    }
-  }
-
-  /**
-   * @param {!Network.NetworkRequestNode} node
-   */
-  _highlightNode(node) {
-    UI.runCSSAnimationOnce(node.element(), 'highlighted-row');
-    this._highlightedNode = node;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<string>}
-   */
-  async _generateFetchCall(request) {
-    const ignoredHeaders = {
-      // Internal headers
-      'method': 1,
-      'path': 1,
-      'scheme': 1,
-      'version': 1,
-
-      // Unsafe headers
-      // Keep this list synchronized with src/net/http/http_util.cc
-      'accept-charset': 1,
-      'accept-encoding': 1,
-      'access-control-request-headers': 1,
-      'access-control-request-method': 1,
-      'connection': 1,
-      'content-length': 1,
-      'cookie': 1,
-      'cookie2': 1,
-      'date': 1,
-      'dnt': 1,
-      'expect': 1,
-      'host': 1,
-      'keep-alive': 1,
-      'origin': 1,
-      'referer': 1,
-      'te': 1,
-      'trailer': 1,
-      'transfer-encoding': 1,
-      'upgrade': 1,
-      'via': 1,
-      // TODO(phistuck) - remove this once crbug.com/571722 is fixed.
-      'user-agent': 1
-    };
-
-    const credentialHeaders = {'cookie': 1, 'authorization': 1};
-
-    const url = JSON.stringify(request.url());
-
-    const requestHeaders = request.requestHeaders();
-    const headerData = requestHeaders.reduce((result, header) => {
-      const name = header.name;
-
-      if (!ignoredHeaders[name.toLowerCase()] && !name.includes(':'))
-        result.append(name, header.value);
-
-      return result;
-    }, new Headers());
-
-    const headers = {};
-    for (const headerArray of headerData)
-      headers[headerArray[0]] = headers[headerArray[1]];
-
-
-    const credentials =
-        request.requestCookies || requestHeaders.some(({name}) => credentialHeaders[name.toLowerCase()]) ? 'include' :
-                                                                                                           'omit';
-
-    const referrerHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'referer');
-
-    const referrer = referrerHeader ? referrerHeader.value : void 0;
-
-    const referrerPolicy = request.referrerPolicy() || void 0;
-
-    const requestBody = await request.requestFormData();
-
-    const fetchOptions = {
-      credentials,
-      headers,
-      referrer,
-      referrerPolicy,
-      body: requestBody,
-      method: request.requestMethod,
-      mode: 'cors'
-    };
-
-    const options = JSON.stringify(fetchOptions);
-    return `fetch(${url}, ${options});`;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {string} platform
-   * @return {!Promise<string>}
-   */
-  async _generateCurlCommand(request, platform) {
-    let command = ['curl'];
-    // These headers are derived from URL (except "version") and would be added by cURL anyway.
-    const ignoredHeaders = {'host': 1, 'method': 1, 'path': 1, 'scheme': 1, 'version': 1};
-
-    function escapeStringWin(str) {
-      /* If there are no new line characters do not escape the " characters
-               since it only uglifies the command.
-
-               Because cmd.exe parser and MS Crt arguments parsers use some of the
-               same escape characters, they can interact with each other in
-               horrible ways, the order of operations is critical.
-
-               Replace \ with \\ first because it is an escape character for certain
-               conditions in both parsers.
-
-               Replace all " with \" to ensure the first parser does not remove it.
-
-               Then escape all characters we are not sure about with ^ to ensure it
-               gets to MS Crt parser safely.
-
-               The % character is special because MS Crt parser will try and look for
-               ENV variables and fill them in it's place. We cannot escape them with %
-               and cannot escape them with ^ (because it's cmd.exe's escape not MS Crt
-               parser); So we can get cmd.exe parser to escape the character after it,
-               if it is followed by a valid beginning character of an ENV variable.
-               This ensures we do not try and double escape another ^ if it was placed
-               by the previous replace.
-
-               Lastly we replace new lines with ^ and TWO new lines because the first
-               new line is there to enact the escape command the second is the character
-               to escape (in this case new line).
-            */
-      const encapsChars = /[\r\n]/.test(str) ? '^"' : '"';
-      return encapsChars +
-          str.replace(/\\/g, '\\\\')
-              .replace(/"/g, '\\"')
-              .replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g, '^$&')
-              .replace(/%(?=[a-zA-Z0-9_])/g, '%^')
-              .replace(/\r\n|[\n\r]/g, '^\n\n') +
-          encapsChars;
-    }
-
-    /**
-     * @param {string} str
-     * @return {string}
-     */
-    function escapeStringPosix(str) {
-      /**
-       * @param {string} x
-       * @return {string}
-       */
-      function escapeCharacter(x) {
-        let code = x.charCodeAt(0);
-        if (code < 256) {
-          // Add leading zero when needed to not care about the next character.
-          return code < 16 ? '\\x0' + code.toString(16) : '\\x' + code.toString(16);
-        }
-        code = code.toString(16);
-        return '\\u' + ('0000' + code).substr(code.length, 4);
-      }
-
-      if (/[^\x20-\x7E]|\'/.test(str)) {
-        // Use ANSI-C quoting syntax.
-        return '$\'' +
-            str.replace(/\\/g, '\\\\')
-                .replace(/\'/g, '\\\'')
-                .replace(/\n/g, '\\n')
-                .replace(/\r/g, '\\r')
-                .replace(/[^\x20-\x7E]/g, escapeCharacter) +
-            '\'';
-      } else {
-        // Use single quote syntax.
-        return '\'' + str + '\'';
-      }
-    }
-
-    // cURL command expected to run on the same platform that DevTools run
-    // (it may be different from the inspected page platform).
-    const escapeString = platform === 'win' ? escapeStringWin : escapeStringPosix;
-
-    command.push(escapeString(request.url()).replace(/[[{}\]]/g, '\\$&'));
-
-    let inferredMethod = 'GET';
-    const data = [];
-    const requestContentType = request.requestContentType();
-    const formData = await request.requestFormData();
-    if (requestContentType && requestContentType.startsWith('application/x-www-form-urlencoded') && formData) {
-      data.push('--data');
-      data.push(escapeString(formData));
-      ignoredHeaders['content-length'] = true;
-      inferredMethod = 'POST';
-    } else if (formData) {
-      data.push('--data-binary');
-      data.push(escapeString(formData));
-      ignoredHeaders['content-length'] = true;
-      inferredMethod = 'POST';
-    }
-
-    if (request.requestMethod !== inferredMethod) {
-      command.push('-X');
-      command.push(request.requestMethod);
-    }
-
-    const requestHeaders = request.requestHeaders();
-    for (let i = 0; i < requestHeaders.length; i++) {
-      const header = requestHeaders[i];
-      const name = header.name.replace(/^:/, '');  // Translate SPDY v3 headers to HTTP headers.
-      if (name.toLowerCase() in ignoredHeaders)
-        continue;
-      command.push('-H');
-      command.push(escapeString(name + ': ' + header.value));
-    }
-    command = command.concat(data);
-    command.push('--compressed');
-
-    if (request.securityState() === Protocol.Security.SecurityState.Insecure)
-      command.push('--insecure');
-    return command.join(' ');
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<string>}
-   */
-  async _generatePowerShellCommand(request) {
-    const command = ['Invoke-WebRequest'];
-    const ignoredHeaders =
-        new Set(['host', 'connection', 'proxy-connection', 'content-length', 'expect', 'range', 'content-type']);
-
-    /**
-     * @param {string} str
-     * @return {string}
-     */
-    function escapeString(str) {
-      return '"' +
-          str.replace(/[`\$"]/g, '`$&').replace(/[^\x20-\x7E]/g, char => '$([char]' + char.charCodeAt(0) + ')') + '"';
-    }
-
-    command.push('-Uri');
-    command.push(escapeString(request.url()));
-
-    if (request.requestMethod !== 'GET') {
-      command.push('-Method');
-      command.push(escapeString(request.requestMethod));
-    }
-
-    const requestHeaders = request.requestHeaders();
-    const headerNameValuePairs = [];
-    for (const header of requestHeaders) {
-      const name = header.name.replace(/^:/, '');  // Translate h2 headers to HTTP headers.
-      if (ignoredHeaders.has(name.toLowerCase()))
-        continue;
-      headerNameValuePairs.push(escapeString(name) + '=' + escapeString(header.value));
-    }
-    if (headerNameValuePairs.length) {
-      command.push('-Headers');
-      command.push('@{' + headerNameValuePairs.join('; ') + '}');
-    }
-
-    const contentTypeHeader = requestHeaders.find(({name}) => name.toLowerCase() === 'content-type');
-    if (contentTypeHeader) {
-      command.push('-ContentType');
-      command.push(escapeString(contentTypeHeader.value));
-    }
-
-    const formData = await request.requestFormData();
-    if (formData) {
-      command.push('-Body');
-      const body = escapeString(formData);
-      if (/[^\x20-\x7E]/.test(formData))
-        command.push('([System.Text.Encoding]::UTF8.GetBytes(' + body + '))');
-      else
-        command.push(body);
-    }
-
-    return command.join(' ');
-  }
-
-  _updateSearchPrompt() {
-    const filterString = this._filterBar.visible() ? this._textFilterUI.value() : '';
-    if (filterString.length) {
-      const filterBarElement = this._filterBar.element;
-      this._searchHint.show(/** @type {!Element} */ (filterBarElement.parentElement), filterBarElement.nextSibling);
-      this._filterStringSearchReminder.textContent = filterString;
-    } else {
-      this._searchHint.hideWidget();
-    }
-  }
-
-  _openSearchView() {
-    const filterString = this._textFilterUI.value();
-    this._textFilterUI.setValue('');
-    Network.SearchNetworkView.openSearch(filterString, true);
-  }
-};
-
-Network.NetworkLogView._isFilteredOutSymbol = Symbol('isFilteredOut');
-Network.NetworkLogView._networkNodeSymbol = Symbol('NetworkNode');
-
-Network.NetworkLogView.HTTPSchemas = {
-  'http': true,
-  'https': true,
-  'ws': true,
-  'wss': true
-};
-
-/** @enum {symbol} */
-Network.NetworkLogView.Events = {
-  RequestSelected: Symbol('RequestSelected')
-};
-
-/** @enum {string} */
-Network.NetworkLogView.FilterType = {
-  Domain: 'domain',
-  HasResponseHeader: 'has-response-header',
-  Is: 'is',
-  LargerThan: 'larger-than',
-  Method: 'method',
-  MimeType: 'mime-type',
-  MixedContent: 'mixed-content',
-  Priority: 'priority',
-  Scheme: 'scheme',
-  SetCookieDomain: 'set-cookie-domain',
-  SetCookieName: 'set-cookie-name',
-  SetCookieValue: 'set-cookie-value',
-  StatusCode: 'status-code'
-};
-
-/** @enum {string} */
-Network.NetworkLogView.MixedContentFilterValues = {
-  All: 'all',
-  Displayed: 'displayed',
-  Blocked: 'blocked',
-  BlockOverridden: 'block-overridden'
-};
-
-/** @enum {string} */
-Network.NetworkLogView.IsFilterType = {
-  Running: 'running',
-  FromCache: 'from-cache'
-};
-
-/** @type {!Array<string>} */
-Network.NetworkLogView._searchKeys =
-    Object.keys(Network.NetworkLogView.FilterType).map(key => Network.NetworkLogView.FilterType[key]);
-
-/** @typedef {function(!SDK.NetworkRequest): boolean} */
-Network.NetworkLogView.Filter;
-
-/**
- * @interface
- */
-Network.GroupLookupInterface = function() {};
-
-Network.GroupLookupInterface.prototype = {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?Network.NetworkGroupNode}
-   */
-  groupNodeForRequest: function(request) {},
-
-  reset: function() {}
-};
diff --git a/front_end/network/NetworkLogViewColumns.js b/front_end/network/NetworkLogViewColumns.js
deleted file mode 100644
index c00716e..0000000
--- a/front_end/network/NetworkLogViewColumns.js
+++ /dev/null
@@ -1,809 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Network.NetworkLogViewColumns = class {
-  /**
-   * @param {!Network.NetworkLogView} networkLogView
-   * @param {!Network.NetworkTransferTimeCalculator} timeCalculator
-   * @param {!Network.NetworkTransferDurationCalculator} durationCalculator
-   * @param {!Common.Setting} networkLogLargeRowsSetting
-   */
-  constructor(networkLogView, timeCalculator, durationCalculator, networkLogLargeRowsSetting) {
-    this._networkLogView = networkLogView;
-
-    /** @type {!Common.Setting} */
-    this._persistantSettings = Common.settings.createSetting('networkLogColumns', {});
-
-    this._networkLogLargeRowsSetting = networkLogLargeRowsSetting;
-    this._networkLogLargeRowsSetting.addChangeListener(this._updateRowsSize, this);
-
-    /** @type {!Map<string, !Array<number>>} */
-    this._eventDividers = new Map();
-    this._eventDividersShown = false;
-
-    this._gridMode = true;
-
-    /** @type {!Array.<!Network.NetworkLogViewColumns.Descriptor>} */
-    this._columns = [];
-
-    this._waterfallRequestsAreStale = false;
-    this._waterfallScrollerWidthIsStale = true;
-
-    /** @type {!Components.Linkifier} */
-    this._popupLinkifier = new Components.Linkifier();
-
-    /** @type {!Map<string, !Network.NetworkTimeCalculator>} */
-    this._calculatorsMap = new Map();
-    this._calculatorsMap.set(Network.NetworkLogViewColumns._calculatorTypes.Time, timeCalculator);
-    this._calculatorsMap.set(Network.NetworkLogViewColumns._calculatorTypes.Duration, durationCalculator);
-
-    this._setupDataGrid();
-    this._setupWaterfall();
-  }
-
-  /**
-   * @param {!Network.NetworkLogViewColumns.Descriptor} columnConfig
-   * @return {!DataGrid.DataGrid.ColumnDescriptor}
-   */
-  static _convertToDataGridDescriptor(columnConfig) {
-    return /** @type {!DataGrid.DataGrid.ColumnDescriptor} */ ({
-      id: columnConfig.id,
-      title: columnConfig.title,
-      sortable: columnConfig.sortable,
-      align: columnConfig.align,
-      nonSelectable: columnConfig.nonSelectable,
-      weight: columnConfig.weight
-    });
-  }
-
-  wasShown() {
-    this._updateRowsSize();
-  }
-
-  willHide() {
-    this._popoverHelper.hidePopover();
-  }
-
-  reset() {
-    if (this._popoverHelper)
-      this._popoverHelper.hidePopover();
-    this._eventDividers.clear();
-  }
-
-  _setupDataGrid() {
-    const defaultColumns = Network.NetworkLogViewColumns._defaultColumns;
-
-    const defaultColumnConfig = Network.NetworkLogViewColumns._defaultColumnConfig;
-
-    this._columns = /** @type {!Array<!Network.NetworkLogViewColumns.Descriptor>} */ ([]);
-    for (const currentConfigColumn of defaultColumns) {
-      const columnConfig = /** @type {!Network.NetworkLogViewColumns.Descriptor} */ (
-          Object.assign({}, defaultColumnConfig, currentConfigColumn));
-      columnConfig.id = columnConfig.id;
-      if (columnConfig.subtitle)
-        columnConfig.titleDOMFragment = this._makeHeaderFragment(columnConfig.title, columnConfig.subtitle);
-      this._columns.push(columnConfig);
-    }
-    this._loadCustomColumnsAndSettings();
-
-    this._popoverHelper = new UI.PopoverHelper(this._networkLogView.element, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setHasPadding(true);
-    this._popoverHelper.setTimeout(300, 300);
-
-    /** @type {!DataGrid.SortableDataGrid<!Network.NetworkNode>} */
-    this._dataGrid =
-        new DataGrid.SortableDataGrid(this._columns.map(Network.NetworkLogViewColumns._convertToDataGridDescriptor));
-    this._dataGrid.element.addEventListener('mousedown', event => {
-      if (!this._dataGrid.selectedNode && event.button)
-        event.consume();
-    }, true);
-
-    this._dataGridScroller = this._dataGrid.scrollContainer;
-
-    this._updateColumns();
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortHandler, this);
-    this._dataGrid.setHeaderContextMenuCallback(this._innerHeaderContextMenu.bind(this));
-
-    this._activeWaterfallSortId = Network.NetworkLogViewColumns.WaterfallSortIds.StartTime;
-    this._dataGrid.markColumnAsSortedBy(
-        Network.NetworkLogViewColumns._initialSortColumn, DataGrid.DataGrid.Order.Ascending);
-
-    this._splitWidget = new UI.SplitWidget(true, true, 'networkPanelSplitViewWaterfall', 200);
-    const widget = this._dataGrid.asWidget();
-    widget.setMinimumSize(150, 0);
-    this._splitWidget.setMainWidget(widget);
-  }
-
-  _setupWaterfall() {
-    this._waterfallColumn = new Network.NetworkWaterfallColumn(this._networkLogView.calculator());
-
-    this._waterfallColumn.element.addEventListener('contextmenu', handleContextMenu.bind(this));
-    this._waterfallColumn.element.addEventListener('mousewheel', this._onMouseWheel.bind(this, false), {passive: true});
-    this._dataGridScroller.addEventListener('mousewheel', this._onMouseWheel.bind(this, true), true);
-
-    this._waterfallScroller = this._waterfallColumn.contentElement.createChild('div', 'network-waterfall-v-scroll');
-    this._waterfallScrollerContent = this._waterfallScroller.createChild('div', 'network-waterfall-v-scroll-content');
-
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.PaddingChanged, () => {
-      this._waterfallScrollerWidthIsStale = true;
-      this._syncScrollers();
-    });
-    this._dataGrid.addEventListener(
-        DataGrid.ViewportDataGrid.Events.ViewportCalculated, this._redrawWaterfallColumn.bind(this));
-
-    this._createWaterfallHeader();
-    this._waterfallColumn.contentElement.classList.add('network-waterfall-view');
-
-    this._waterfallColumn.setMinimumSize(100, 0);
-    this._splitWidget.setSidebarWidget(this._waterfallColumn);
-
-    this.switchViewMode(false);
-
-    /**
-     * @param {!Event} event
-     * @this {Network.NetworkLogViewColumns}
-     */
-    function handleContextMenu(event) {
-      const node = this._waterfallColumn.getNodeFromPoint(event.offsetX, event.offsetY);
-      if (!node)
-        return;
-      const request = node.request();
-      if (!request)
-        return;
-      const contextMenu = new UI.ContextMenu(event);
-      this._networkLogView.handleContextMenuForRequest(contextMenu, request);
-      contextMenu.show();
-    }
-  }
-
-  /**
-   * @param {boolean} shouldConsume
-   * @param {!Event} event
-   */
-  _onMouseWheel(shouldConsume, event) {
-    if (shouldConsume)
-      event.consume(true);
-    this._activeScroller.scrollTop -= event.wheelDeltaY;
-    this._syncScrollers();
-  }
-
-  _syncScrollers() {
-    if (!this._waterfallColumn.isShowing())
-      return;
-    this._waterfallScrollerContent.style.height = this._dataGridScroller.scrollHeight + 'px';
-    this._updateScrollerWidthIfNeeded();
-    this._dataGridScroller.scrollTop = this._waterfallScroller.scrollTop;
-  }
-
-  _updateScrollerWidthIfNeeded() {
-    if (this._waterfallScrollerWidthIsStale) {
-      this._waterfallScrollerWidthIsStale = false;
-      this._waterfallColumn.setRightPadding(
-          this._waterfallScroller.offsetWidth - this._waterfallScrollerContent.offsetWidth);
-    }
-  }
-
-  _redrawWaterfallColumn() {
-    if (!this._waterfallRequestsAreStale) {
-      this._updateScrollerWidthIfNeeded();
-      this._waterfallColumn.update(
-          this._activeScroller.scrollTop, this._eventDividersShown ? this._eventDividers : undefined);
-      return;
-    }
-    this._syncScrollers();
-    const nodes = this._networkLogView.flatNodesList();
-    this._waterfallColumn.update(this._activeScroller.scrollTop, this._eventDividers, nodes);
-  }
-
-  _createWaterfallHeader() {
-    this._waterfallHeaderElement = this._waterfallColumn.contentElement.createChild('div', 'network-waterfall-header');
-    this._waterfallHeaderElement.addEventListener('click', waterfallHeaderClicked.bind(this));
-    this._waterfallHeaderElement.addEventListener(
-        'contextmenu', event => this._innerHeaderContextMenu(new UI.ContextMenu(event)));
-    const innerElement = this._waterfallHeaderElement.createChild('div');
-    innerElement.textContent = Common.UIString('Waterfall');
-    this._waterfallColumnSortIcon = UI.Icon.create('', 'sort-order-icon');
-    this._waterfallHeaderElement.createChild('div', 'sort-order-icon-container')
-        .appendChild(this._waterfallColumnSortIcon);
-
-    /**
-     * @this {Network.NetworkLogViewColumns}
-     */
-    function waterfallHeaderClicked() {
-      const sortOrders = DataGrid.DataGrid.Order;
-      const sortOrder =
-          this._dataGrid.sortOrder() === sortOrders.Ascending ? sortOrders.Descending : sortOrders.Ascending;
-      this._dataGrid.markColumnAsSortedBy('waterfall', sortOrder);
-      this._sortHandler();
-    }
-  }
-
-  /**
-   * @param {!Network.NetworkTimeCalculator} x
-   */
-  setCalculator(x) {
-    this._waterfallColumn.setCalculator(x);
-  }
-
-  scheduleRefresh() {
-    this._waterfallColumn.scheduleDraw();
-  }
-
-  _updateRowsSize() {
-    const largeRows = !!this._networkLogLargeRowsSetting.get();
-
-    this._dataGrid.element.classList.toggle('small', !largeRows);
-    this._dataGrid.scheduleUpdate();
-
-    this._waterfallScrollerWidthIsStale = true;
-    this._waterfallColumn.setRowHeight(largeRows ? 41 : 21);
-    this._waterfallScroller.classList.toggle('small', !largeRows);
-    this._waterfallHeaderElement.classList.toggle('small', !largeRows);
-    this._waterfallColumn.setHeaderHeight(this._waterfallScroller.offsetTop);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  show(element) {
-    this._splitWidget.show(element);
-  }
-
-  /**
-   * @return {!DataGrid.SortableDataGrid<!Network.NetworkNode>} dataGrid
-   */
-  dataGrid() {
-    return this._dataGrid;
-  }
-
-  sortByCurrentColumn() {
-    this._sortHandler();
-  }
-
-  _sortHandler() {
-    const columnId = this._dataGrid.sortColumnId();
-    this._networkLogView.removeAllNodeHighlights();
-    this._waterfallRequestsAreStale = true;
-    if (columnId === 'waterfall') {
-      if (this._dataGrid.sortOrder() === DataGrid.DataGrid.Order.Ascending)
-        this._waterfallColumnSortIcon.setIconType('smallicon-triangle-up');
-      else
-        this._waterfallColumnSortIcon.setIconType('smallicon-triangle-down');
-
-      const sortFunction = Network.NetworkRequestNode.RequestPropertyComparator.bind(null, this._activeWaterfallSortId);
-      this._dataGrid.sortNodes(sortFunction, !this._dataGrid.isSortOrderAscending());
-      this._dataGridSortedForTest();
-      return;
-    }
-    this._waterfallColumnSortIcon.setIconType('');
-
-    const columnConfig = this._columns.find(columnConfig => columnConfig.id === columnId);
-    if (!columnConfig || !columnConfig.sortingFunction)
-      return;
-
-    this._dataGrid.sortNodes(columnConfig.sortingFunction, !this._dataGrid.isSortOrderAscending());
-    this._dataGridSortedForTest();
-  }
-
-  _dataGridSortedForTest() {
-  }
-
-  _updateColumns() {
-    if (!this._dataGrid)
-      return;
-    const visibleColumns = /** @type {!Object.<string, boolean>} */ ({});
-    if (this._gridMode) {
-      for (const columnConfig of this._columns)
-        visibleColumns[columnConfig.id] = columnConfig.visible;
-    } else {
-      visibleColumns.name = true;
-    }
-    this._dataGrid.setColumnsVisiblity(visibleColumns);
-  }
-
-  /**
-   * @param {boolean} gridMode
-   */
-  switchViewMode(gridMode) {
-    if (this._gridMode === gridMode)
-      return;
-    this._gridMode = gridMode;
-
-    if (gridMode) {
-      if (this._dataGrid.selectedNode)
-        this._dataGrid.selectedNode.selected = false;
-      this._splitWidget.showBoth();
-      this._activeScroller = this._waterfallScroller;
-      this._waterfallScroller.scrollTop = this._dataGridScroller.scrollTop;
-      this._dataGrid.setScrollContainer(this._waterfallScroller);
-    } else {
-      this._networkLogView.removeAllNodeHighlights();
-      this._splitWidget.hideSidebar();
-      this._activeScroller = this._dataGridScroller;
-      this._dataGrid.setScrollContainer(this._dataGridScroller);
-    }
-    this._networkLogView.element.classList.toggle('brief-mode', !gridMode);
-    this._updateColumns();
-    this._updateRowsSize();
-  }
-
-  /**
-   * @param {!Network.NetworkLogViewColumns.Descriptor} columnConfig
-   */
-  _toggleColumnVisibility(columnConfig) {
-    this._loadCustomColumnsAndSettings();
-    columnConfig.visible = !columnConfig.visible;
-    this._saveColumnsSettings();
-    this._updateColumns();
-  }
-
-  _saveColumnsSettings() {
-    const saveableSettings = {};
-    for (const columnConfig of this._columns)
-      saveableSettings[columnConfig.id] = {visible: columnConfig.visible, title: columnConfig.title};
-
-    this._persistantSettings.set(saveableSettings);
-  }
-
-  _loadCustomColumnsAndSettings() {
-    const savedSettings = this._persistantSettings.get();
-    const columnIds = Object.keys(savedSettings);
-    for (const columnId of columnIds) {
-      const setting = savedSettings[columnId];
-      let columnConfig = this._columns.find(columnConfig => columnConfig.id === columnId);
-      if (!columnConfig)
-        columnConfig = this._addCustomHeader(setting.title, columnId);
-      if (columnConfig.hideable && typeof setting.visible === 'boolean')
-        columnConfig.visible = !!setting.visible;
-      if (typeof setting.title === 'string')
-        columnConfig.title = setting.title;
-    }
-  }
-
-  /**
-   * @param {string} title
-   * @param {string} subtitle
-   * @return {!DocumentFragment}
-   */
-  _makeHeaderFragment(title, subtitle) {
-    const fragment = createDocumentFragment();
-    fragment.createTextChild(title);
-    const subtitleDiv = fragment.createChild('div', 'network-header-subtitle');
-    subtitleDiv.createTextChild(subtitle);
-    return fragment;
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _innerHeaderContextMenu(contextMenu) {
-    const columnConfigs = this._columns.filter(columnConfig => columnConfig.hideable);
-    const nonResponseHeaders = columnConfigs.filter(columnConfig => !columnConfig.isResponseHeader);
-    for (const columnConfig of nonResponseHeaders) {
-      contextMenu.headerSection().appendCheckboxItem(
-          columnConfig.title, this._toggleColumnVisibility.bind(this, columnConfig), columnConfig.visible);
-    }
-
-    const responseSubMenu = contextMenu.footerSection().appendSubMenuItem(Common.UIString('Response Headers'));
-    const responseHeaders = columnConfigs.filter(columnConfig => columnConfig.isResponseHeader);
-    for (const columnConfig of responseHeaders) {
-      responseSubMenu.defaultSection().appendCheckboxItem(
-          columnConfig.title, this._toggleColumnVisibility.bind(this, columnConfig), columnConfig.visible);
-    }
-
-    responseSubMenu.footerSection().appendItem(
-        Common.UIString('Manage Header Columns\u2026'), this._manageCustomHeaderDialog.bind(this));
-
-    const waterfallSortIds = Network.NetworkLogViewColumns.WaterfallSortIds;
-    const waterfallSubMenu = contextMenu.footerSection().appendSubMenuItem(Common.UIString('Waterfall'));
-    waterfallSubMenu.defaultSection().appendCheckboxItem(
-        Common.UIString('Start Time'), setWaterfallMode.bind(this, waterfallSortIds.StartTime),
-        this._activeWaterfallSortId === waterfallSortIds.StartTime);
-    waterfallSubMenu.defaultSection().appendCheckboxItem(
-        Common.UIString('Response Time'), setWaterfallMode.bind(this, waterfallSortIds.ResponseTime),
-        this._activeWaterfallSortId === waterfallSortIds.ResponseTime);
-    waterfallSubMenu.defaultSection().appendCheckboxItem(
-        Common.UIString('End Time'), setWaterfallMode.bind(this, waterfallSortIds.EndTime),
-        this._activeWaterfallSortId === waterfallSortIds.EndTime);
-    waterfallSubMenu.defaultSection().appendCheckboxItem(
-        Common.UIString('Total Duration'), setWaterfallMode.bind(this, waterfallSortIds.Duration),
-        this._activeWaterfallSortId === waterfallSortIds.Duration);
-    waterfallSubMenu.defaultSection().appendCheckboxItem(
-        Common.UIString('Latency'), setWaterfallMode.bind(this, waterfallSortIds.Latency),
-        this._activeWaterfallSortId === waterfallSortIds.Latency);
-
-    contextMenu.show();
-
-    /**
-     * @param {!Network.NetworkLogViewColumns.WaterfallSortIds} sortId
-     * @this {Network.NetworkLogViewColumns}
-     */
-    function setWaterfallMode(sortId) {
-      let calculator = this._calculatorsMap.get(Network.NetworkLogViewColumns._calculatorTypes.Time);
-      const waterfallSortIds = Network.NetworkLogViewColumns.WaterfallSortIds;
-      if (sortId === waterfallSortIds.Duration || sortId === waterfallSortIds.Latency)
-        calculator = this._calculatorsMap.get(Network.NetworkLogViewColumns._calculatorTypes.Duration);
-      this._networkLogView.setCalculator(calculator);
-
-      this._activeWaterfallSortId = sortId;
-      this._dataGrid.markColumnAsSortedBy('waterfall', DataGrid.DataGrid.Order.Ascending);
-      this._sortHandler();
-    }
-  }
-
-  _manageCustomHeaderDialog() {
-    const customHeaders = [];
-    for (const columnConfig of this._columns) {
-      if (columnConfig.isResponseHeader)
-        customHeaders.push({title: columnConfig.title, editable: columnConfig.isCustomHeader});
-    }
-    const manageCustomHeaders = new Network.NetworkManageCustomHeadersView(
-        customHeaders, headerTitle => !!this._addCustomHeader(headerTitle), this._changeCustomHeader.bind(this),
-        this._removeCustomHeader.bind(this));
-    const dialog = new UI.Dialog();
-    manageCustomHeaders.show(dialog.contentElement);
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.show(this._networkLogView.element);
-  }
-
-  /**
-   * @param {string} headerId
-   * @return {boolean}
-   */
-  _removeCustomHeader(headerId) {
-    headerId = headerId.toLowerCase();
-    const index = this._columns.findIndex(columnConfig => columnConfig.id === headerId);
-    if (index === -1)
-      return false;
-    this._columns.splice(index, 1);
-    this._dataGrid.removeColumn(headerId);
-    this._saveColumnsSettings();
-    this._updateColumns();
-    return true;
-  }
-
-  /**
-   * @param {string} headerTitle
-   * @param {string=} headerId
-   * @param {number=} index
-   * @return {?Network.NetworkLogViewColumns.Descriptor}
-   */
-  _addCustomHeader(headerTitle, headerId, index) {
-    if (!headerId)
-      headerId = headerTitle.toLowerCase();
-    if (index === undefined)
-      index = this._columns.length - 1;
-
-    const currentColumnConfig = this._columns.find(columnConfig => columnConfig.id === headerId);
-    if (currentColumnConfig)
-      return null;
-
-    const columnConfig = /** @type {!Network.NetworkLogViewColumns.Descriptor} */ (
-        Object.assign({}, Network.NetworkLogViewColumns._defaultColumnConfig, {
-          id: headerId,
-          title: headerTitle,
-          isResponseHeader: true,
-          isCustomHeader: true,
-          visible: true,
-          sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, headerId)
-        }));
-    this._columns.splice(index, 0, columnConfig);
-    if (this._dataGrid)
-      this._dataGrid.addColumn(Network.NetworkLogViewColumns._convertToDataGridDescriptor(columnConfig), index);
-    this._saveColumnsSettings();
-    this._updateColumns();
-    return columnConfig;
-  }
-
-  /**
-   * @param {string} oldHeaderId
-   * @param {string} newHeaderTitle
-   * @param {string=} newHeaderId
-   * @return {boolean}
-   */
-  _changeCustomHeader(oldHeaderId, newHeaderTitle, newHeaderId) {
-    if (!newHeaderId)
-      newHeaderId = newHeaderTitle.toLowerCase();
-    oldHeaderId = oldHeaderId.toLowerCase();
-
-    const oldIndex = this._columns.findIndex(columnConfig => columnConfig.id === oldHeaderId);
-    const oldColumnConfig = this._columns[oldIndex];
-    const currentColumnConfig = this._columns.find(columnConfig => columnConfig.id === newHeaderId);
-    if (!oldColumnConfig || (currentColumnConfig && oldHeaderId !== newHeaderId))
-      return false;
-
-    this._removeCustomHeader(oldHeaderId);
-    this._addCustomHeader(newHeaderTitle, newHeaderId, oldIndex);
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    if (!this._gridMode)
-      return null;
-    const hoveredNode = this._networkLogView.hoveredNode();
-    if (!hoveredNode)
-      return null;
-
-    const anchor = event.target.enclosingNodeOrSelfWithClass('network-script-initiated');
-    if (!anchor)
-      return null;
-    const request = hoveredNode.request();
-    const initiator = request ? request.initiator() : null;
-    if (!initiator || !initiator.stack)
-      return null;
-    return {
-      box: anchor.boxInWindow(),
-      show: popover => {
-        const manager = anchor.request ? SDK.NetworkManager.forRequest(anchor.request) : null;
-        const content = Components.JSPresentationUtils.buildStackTracePreviewContents(
-            manager ? manager.target() : null, this._popupLinkifier, initiator.stack,
-            () => popover.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent));
-        popover.contentElement.appendChild(content);
-        return Promise.resolve(true);
-      },
-      hide: this._popupLinkifier.reset.bind(this._popupLinkifier)
-    };
-  }
-
-  /**
-   * @param {!Array<number>} times
-   * @param {string} className
-   */
-  addEventDividers(times, className) {
-    // TODO(allada) Remove this and pass in the color.
-    let color = 'transparent';
-    switch (className) {
-      case 'network-blue-divider':
-        color = 'hsla(240, 100%, 80%, 0.7)';
-        break;
-      case 'network-red-divider':
-        color = 'rgba(255, 0, 0, 0.5)';
-        break;
-      default:
-        return;
-    }
-    const currentTimes = this._eventDividers.get(color) || [];
-    this._eventDividers.set(color, currentTimes.concat(times));
-    this._networkLogView.scheduleRefresh();
-  }
-
-  hideEventDividers() {
-    this._eventDividersShown = true;
-    this._redrawWaterfallColumn();
-  }
-
-  showEventDividers() {
-    this._eventDividersShown = false;
-    this._redrawWaterfallColumn();
-  }
-
-  /**
-   * @param {number} time
-   */
-  selectFilmStripFrame(time) {
-    this._eventDividers.set(Network.NetworkLogViewColumns._filmStripDividerColor, [time]);
-    this._redrawWaterfallColumn();
-  }
-
-  clearFilmStripFrame() {
-    this._eventDividers.delete(Network.NetworkLogViewColumns._filmStripDividerColor);
-    this._redrawWaterfallColumn();
-  }
-};
-
-Network.NetworkLogViewColumns._initialSortColumn = 'waterfall';
-
-/**
- * @typedef {{
- *     id: string,
- *     title: string,
- *     titleDOMFragment: (!DocumentFragment|undefined),
- *     subtitle: (string|null),
- *     visible: boolean,
- *     weight: number,
- *     hideable: boolean,
- *     nonSelectable: boolean,
- *     sortable: boolean,
- *     align: (?DataGrid.DataGrid.Align|undefined),
- *     isResponseHeader: boolean,
- *     sortingFunction: (!function(!Network.NetworkNode, !Network.NetworkNode):number|undefined),
- *     isCustomHeader: boolean
- * }}
- */
-Network.NetworkLogViewColumns.Descriptor;
-
-/** @enum {string} */
-Network.NetworkLogViewColumns._calculatorTypes = {
-  Duration: 'Duration',
-  Time: 'Time'
-};
-
-/**
- * @type {!Object} column
- */
-Network.NetworkLogViewColumns._defaultColumnConfig = {
-  subtitle: null,
-  visible: false,
-  weight: 6,
-  sortable: true,
-  hideable: true,
-  nonSelectable: true,
-  isResponseHeader: false,
-  alwaysVisible: false,
-  isCustomHeader: false
-};
-
-/**
- * @type {!Array.<!Network.NetworkLogViewColumns.Descriptor>} column
- */
-Network.NetworkLogViewColumns._defaultColumns = [
-  {
-    id: 'name',
-    title: Common.UIString('Name'),
-    subtitle: Common.UIString('Path'),
-    visible: true,
-    weight: 20,
-    hideable: false,
-    nonSelectable: false,
-    alwaysVisible: true,
-    sortingFunction: Network.NetworkRequestNode.NameComparator
-  },
-  {
-    id: 'method',
-    title: Common.UIString('Method'),
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'requestMethod')
-  },
-  {
-    id: 'status',
-    title: Common.UIString('Status'),
-    visible: true,
-    subtitle: Common.UIString('Text'),
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'statusCode')
-  },
-  {
-    id: 'protocol',
-    title: Common.UIString('Protocol'),
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'protocol')
-  },
-  {
-    id: 'scheme',
-    title: Common.UIString('Scheme'),
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'scheme')
-  },
-  {
-    id: 'domain',
-    title: Common.UIString('Domain'),
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'domain')
-  },
-  {
-    id: 'remoteaddress',
-    title: Common.UIString('Remote Address'),
-    weight: 10,
-    align: DataGrid.DataGrid.Align.Right,
-    sortingFunction: Network.NetworkRequestNode.RemoteAddressComparator
-  },
-  {
-    id: 'type',
-    title: Common.UIString('Type'),
-    visible: true,
-    sortingFunction: Network.NetworkRequestNode.TypeComparator
-  },
-  {
-    id: 'initiator',
-    title: Common.UIString('Initiator'),
-    visible: true,
-    weight: 10,
-    sortingFunction: Network.NetworkRequestNode.InitiatorComparator
-  },
-  {
-    id: 'cookies',
-    title: Common.UIString('Cookies'),
-    align: DataGrid.DataGrid.Align.Right,
-    sortingFunction: Network.NetworkRequestNode.RequestCookiesCountComparator
-  },
-  {
-    id: 'setcookies',
-    title: Common.UIString('Set Cookies'),
-    align: DataGrid.DataGrid.Align.Right,
-    sortingFunction: Network.NetworkRequestNode.ResponseCookiesCountComparator
-  },
-  {
-    id: 'size',
-    title: Common.UIString('Size'),
-    visible: true,
-    subtitle: Common.UIString('Content'),
-    align: DataGrid.DataGrid.Align.Right,
-    sortingFunction: Network.NetworkRequestNode.SizeComparator
-  },
-  {
-    id: 'time',
-    title: Common.UIString('Time'),
-    visible: true,
-    subtitle: Common.UIString('Latency'),
-    align: DataGrid.DataGrid.Align.Right,
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'duration')
-  },
-  {id: 'priority', title: Common.UIString('Priority'), sortingFunction: Network.NetworkRequestNode.PriorityComparator},
-  {
-    id: 'connectionid',
-    title: Common.UIString('Connection ID'),
-    sortingFunction: Network.NetworkRequestNode.RequestPropertyComparator.bind(null, 'connectionId')
-  },
-  {
-    id: 'cache-control',
-    isResponseHeader: true,
-    title: Common.UIString('Cache-Control'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'cache-control')
-  },
-  {
-    id: 'connection',
-    isResponseHeader: true,
-    title: Common.UIString('Connection'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'connection')
-  },
-  {
-    id: 'content-encoding',
-    isResponseHeader: true,
-    title: Common.UIString('Content-Encoding'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'content-encoding')
-  },
-  {
-    id: 'content-length',
-    isResponseHeader: true,
-    title: Common.UIString('Content-Length'),
-    align: DataGrid.DataGrid.Align.Right,
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderNumberComparator.bind(null, 'content-length')
-  },
-  {
-    id: 'etag',
-    isResponseHeader: true,
-    title: Common.UIString('ETag'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'etag')
-  },
-  {
-    id: 'keep-alive',
-    isResponseHeader: true,
-    title: Common.UIString('Keep-Alive'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'keep-alive')
-  },
-  {
-    id: 'last-modified',
-    isResponseHeader: true,
-    title: Common.UIString('Last-Modified'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderDateComparator.bind(null, 'last-modified')
-  },
-  {
-    id: 'server',
-    isResponseHeader: true,
-    title: Common.UIString('Server'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'server')
-  },
-  {
-    id: 'vary',
-    isResponseHeader: true,
-    title: Common.UIString('Vary'),
-    sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'vary')
-  },
-  // This header is a placeholder to let datagrid know that it can be sorted by this column, but never shown.
-  {id: 'waterfall', title: '', visible: false, hideable: false}
-];
-
-Network.NetworkLogViewColumns._filmStripDividerColor = '#fccc49';
-
-/**
- * @enum {string}
- */
-Network.NetworkLogViewColumns.WaterfallSortIds = {
-  StartTime: 'startTime',
-  ResponseTime: 'responseReceivedTime',
-  EndTime: 'endTime',
-  Duration: 'duration',
-  Latency: 'latency'
-};
diff --git a/front_end/network/NetworkManageCustomHeadersView.js b/front_end/network/NetworkManageCustomHeadersView.js
deleted file mode 100644
index 4136dd9..0000000
--- a/front_end/network/NetworkManageCustomHeadersView.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-/**
- * @implements {UI.ListWidget.Delegate}
- * @unrestricted
- */
-Network.NetworkManageCustomHeadersView = class extends UI.VBox {
-  /**
-   * @param {!Array.<!{title: string, editable: boolean}>} columnData
-   * @param {function(string) : boolean} addHeaderColumnCallback
-   * @param {function(string, string) : boolean} changeHeaderColumnCallback
-   * @param {function(string) : boolean} removeHeaderColumnCallback
-   */
-  constructor(columnData, addHeaderColumnCallback, changeHeaderColumnCallback, removeHeaderColumnCallback) {
-    super(true);
-    this.registerRequiredCSS('network/networkManageCustomHeadersView.css');
-
-    this.contentElement.classList.add('custom-headers-wrapper');
-    this.contentElement.createChild('div', 'header').textContent = Common.UIString('Manage Header Columns');
-
-    this._list = new UI.ListWidget(this);
-    this._list.element.classList.add('custom-headers-list');
-    this._list.registerRequiredCSS('network/networkManageCustomHeadersView.css');
-
-    const placeholder = createElementWithClass('div', 'custom-headers-list-list-empty');
-    placeholder.textContent = Common.UIString('No custom headers');
-    this._list.setEmptyPlaceholder(placeholder);
-    this._list.show(this.contentElement);
-    this.contentElement.appendChild(UI.createTextButton(
-        Common.UIString('Add custom header\u2026'), this._addButtonClicked.bind(this), 'add-button'));
-
-    /** @type {!Map.<string, !{title: string, editable: boolean}>} */
-    this._columnConfigs = new Map();
-    columnData.forEach(columnData => this._columnConfigs.set(columnData.title.toLowerCase(), columnData));
-
-    this._addHeaderColumnCallback = addHeaderColumnCallback;
-    this._changeHeaderColumnCallback = changeHeaderColumnCallback;
-    this._removeHeaderColumnCallback = removeHeaderColumnCallback;
-
-    this.contentElement.tabIndex = 0;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._headersUpdated();
-  }
-
-  _headersUpdated() {
-    this._list.clear();
-    this._columnConfigs.forEach(headerData => this._list.appendItem({header: headerData.title}, headerData.editable));
-  }
-
-  _addButtonClicked() {
-    this._list.addNewItem(this._columnConfigs.size, {header: ''});
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(item, editable) {
-    const element = createElementWithClass('div', 'custom-headers-list-item');
-    const header = element.createChild('div', 'custom-header-name');
-    header.textContent = item.header;
-    header.title = item.header;
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {number} index
-   */
-  removeItemRequested(item, index) {
-    this._removeHeaderColumnCallback(item.header);
-    this._columnConfigs.delete(item.header.toLowerCase());
-    this._headersUpdated();
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {
-    const headerId = editor.control('header').value.trim();
-    let success;
-    if (isNew)
-      success = this._addHeaderColumnCallback(headerId);
-    else
-      success = this._changeHeaderColumnCallback(item.header, headerId);
-
-    if (success && !isNew)
-      this._columnConfigs.delete(item.header.toLowerCase());
-    if (success)
-      this._columnConfigs.set(headerId.toLowerCase(), {title: headerId, editable: true});
-
-    this._headersUpdated();
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(item) {
-    const editor = this._createEditor();
-    editor.control('header').value = item.header;
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._editor = editor;
-    const content = editor.contentElement();
-
-    const titles = content.createChild('div', 'custom-headers-edit-row');
-    titles.createChild('div', 'custom-headers-header').textContent = Common.UIString('Header Name');
-
-    const fields = content.createChild('div', 'custom-headers-edit-row');
-    fields.createChild('div', 'custom-headers-header')
-        .appendChild(editor.createInput('header', 'text', 'x-custom-header', validateHeader.bind(this)));
-
-    return editor;
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @this {Network.NetworkManageCustomHeadersView}
-     * @return {boolean}
-     */
-    function validateHeader(item, index, input) {
-      const headerId = editor.control('header').value.trim().toLowerCase();
-      if (this._columnConfigs.has(headerId) && item.header !== headerId)
-        return false;
-      return true;
-    }
-  }
-};
diff --git a/front_end/network/NetworkOverview.js b/front_end/network/NetworkOverview.js
deleted file mode 100644
index 0c9f5ca..0000000
--- a/front_end/network/NetworkOverview.js
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Network.NetworkOverview = class extends PerfUI.TimelineOverviewBase {
-  constructor() {
-    super();
-    this._selectedFilmStripTime = -1;
-    this.element.classList.add('network-overview');
-
-    /** @type {number} */
-    this._numBands = 1;
-    /** @type {boolean} */
-    this._updateScheduled = false;
-
-    SDK.targetManager.addModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
-    SDK.targetManager.addModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEventFired, this);
-
-    this.reset();
-  }
-
-  /**
-   * @param {?SDK.FilmStripModel} filmStripModel
-   */
-  setFilmStripModel(filmStripModel) {
-    this._filmStripModel = filmStripModel;
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {number} time
-   */
-  selectFilmStripFrame(time) {
-    this._selectedFilmStripTime = time;
-    this.scheduleUpdate();
-  }
-
-  clearFilmStripFrame() {
-    this._selectedFilmStripTime = -1;
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _loadEventFired(event) {
-    const time = /** @type {number} */ (event.data.loadTime);
-    if (time)
-      this._loadEvents.push(time * 1000);
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domContentLoadedEventFired(event) {
-    const data = /** @type {number} */ (event.data);
-    if (data)
-      this._domContentLoadedEvents.push(data * 1000);
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {string} connectionId
-   * @return {number}
-   */
-  _bandId(connectionId) {
-    if (!connectionId || connectionId === '0')
-      return -1;
-    if (this._bandMap.has(connectionId))
-      return /** @type {number} */ (this._bandMap.get(connectionId));
-    const result = this._nextBand++;
-    this._bandMap.set(connectionId, result);
-    return result;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  updateRequest(request) {
-    if (!this._requestsSet.has(request)) {
-      this._requestsSet.add(request);
-      this._requestsList.push(request);
-    }
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.onResize();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    const width = this.element.offsetWidth;
-    const height = this.element.offsetHeight;
-    this.calculator().setDisplayWidth(width);
-    this.resetCanvas();
-    const numBands = (((height - 1) / Network.NetworkOverview._bandHeight) - 1) | 0;
-    this._numBands = (numBands > 0) ? numBands : 1;
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @override
-   */
-  reset() {
-    /** @type {?SDK.FilmStripModel} */
-    this._filmStripModel = null;
-
-    /** @type {number} */
-    this._span = 1;
-    /** @type {?Network.NetworkTimeBoundary} */
-    this._lastBoundary = null;
-    /** @type {number} */
-    this._nextBand = 0;
-    /** @type {!Map.<string, number>} */
-    this._bandMap = new Map();
-    /** @type {!Array.<!SDK.NetworkRequest>} */
-    this._requestsList = [];
-    /** @type {!Set.<!SDK.NetworkRequest>} */
-    this._requestsSet = new Set();
-    /** @type {!Array.<number>} */
-    this._loadEvents = [];
-    /** @type {!Array.<number>} */
-    this._domContentLoadedEvents = [];
-
-    // Clear screen.
-    this.resetCanvas();
-  }
-
-  /**
-   * @protected
-   */
-  scheduleUpdate() {
-    if (this._updateScheduled || !this.isShowing())
-      return;
-    this._updateScheduled = true;
-    this.element.window().requestAnimationFrame(this.update.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    this._updateScheduled = false;
-
-    const calculator = this.calculator();
-
-    const newBoundary = new Network.NetworkTimeBoundary(calculator.minimumBoundary(), calculator.maximumBoundary());
-    if (!this._lastBoundary || !newBoundary.equals(this._lastBoundary)) {
-      const span = calculator.boundarySpan();
-      while (this._span < span)
-        this._span *= 1.25;
-
-      calculator.setBounds(calculator.minimumBoundary(), calculator.minimumBoundary() + this._span);
-      this._lastBoundary = new Network.NetworkTimeBoundary(calculator.minimumBoundary(), calculator.maximumBoundary());
-    }
-
-    const context = this.context();
-    const linesByType = {};
-    const paddingTop = 2;
-
-    /**
-     * @param {string} type
-     * @param {string} strokeStyle
-     */
-    function drawLines(type, strokeStyle) {
-      const lines = linesByType[type];
-      if (!lines)
-        return;
-      const n = lines.length;
-      context.beginPath();
-      context.strokeStyle = strokeStyle;
-      for (let i = 0; i < n;) {
-        const y = lines[i++] * Network.NetworkOverview._bandHeight + paddingTop;
-        const startTime = lines[i++];
-        let endTime = lines[i++];
-        if (endTime === Number.MAX_VALUE)
-          endTime = calculator.maximumBoundary();
-        context.moveTo(calculator.computePosition(startTime), y);
-        context.lineTo(calculator.computePosition(endTime) + 1, y);
-      }
-      context.stroke();
-    }
-
-    /**
-     * @param {string} type
-     * @param {number} y
-     * @param {number} start
-     * @param {number} end
-     */
-    function addLine(type, y, start, end) {
-      let lines = linesByType[type];
-      if (!lines) {
-        lines = [];
-        linesByType[type] = lines;
-      }
-      lines.push(y, start, end);
-    }
-
-    const requests = this._requestsList;
-    const n = requests.length;
-    for (let i = 0; i < n; ++i) {
-      const request = requests[i];
-      const band = this._bandId(request.connectionId);
-      const y = (band === -1) ? 0 : (band % this._numBands + 1);
-      const timeRanges =
-          Network.RequestTimingView.calculateRequestTimeRanges(request, this.calculator().minimumBoundary());
-      for (let j = 0; j < timeRanges.length; ++j) {
-        const type = timeRanges[j].name;
-        if (band !== -1 || type === Network.RequestTimeRangeNames.Total)
-          addLine(type, y, timeRanges[j].start * 1000, timeRanges[j].end * 1000);
-      }
-    }
-
-    context.clearRect(0, 0, this.width(), this.height());
-    context.save();
-    context.scale(window.devicePixelRatio, window.devicePixelRatio);
-    context.lineWidth = 2;
-    drawLines(Network.RequestTimeRangeNames.Total, '#CCCCCC');
-    drawLines(Network.RequestTimeRangeNames.Blocking, '#AAAAAA');
-    drawLines(Network.RequestTimeRangeNames.Connecting, '#FF9800');
-    drawLines(Network.RequestTimeRangeNames.ServiceWorker, '#FF9800');
-    drawLines(Network.RequestTimeRangeNames.ServiceWorkerPreparation, '#FF9800');
-    drawLines(Network.RequestTimeRangeNames.Push, '#8CDBff');
-    drawLines(Network.RequestTimeRangeNames.Proxy, '#A1887F');
-    drawLines(Network.RequestTimeRangeNames.DNS, '#009688');
-    drawLines(Network.RequestTimeRangeNames.SSL, '#9C27B0');
-    drawLines(Network.RequestTimeRangeNames.Sending, '#B0BEC5');
-    drawLines(Network.RequestTimeRangeNames.Waiting, '#00C853');
-    drawLines(Network.RequestTimeRangeNames.Receiving, '#03A9F4');
-
-    const height = this.element.offsetHeight;
-    context.lineWidth = 1;
-    context.beginPath();
-    context.strokeStyle = '#8080FF';  // Keep in sync with .network-blue-divider CSS rule.
-    for (let i = this._domContentLoadedEvents.length - 1; i >= 0; --i) {
-      const x = Math.round(calculator.computePosition(this._domContentLoadedEvents[i])) + 0.5;
-      context.moveTo(x, 0);
-      context.lineTo(x, height);
-    }
-    context.stroke();
-
-    context.beginPath();
-    context.strokeStyle = '#FF8080';  // Keep in sync with .network-red-divider CSS rule.
-    for (let i = this._loadEvents.length - 1; i >= 0; --i) {
-      const x = Math.round(calculator.computePosition(this._loadEvents[i])) + 0.5;
-      context.moveTo(x, 0);
-      context.lineTo(x, height);
-    }
-    context.stroke();
-
-    if (this._selectedFilmStripTime !== -1) {
-      context.lineWidth = 2;
-      context.beginPath();
-      context.strokeStyle = '#FCCC49';  // Keep in sync with .network-frame-divider CSS rule.
-      const x = Math.round(calculator.computePosition(this._selectedFilmStripTime));
-      context.moveTo(x, 0);
-      context.lineTo(x, height);
-      context.stroke();
-    }
-    context.restore();
-  }
-};
-
-/** @type {number} */
-Network.NetworkOverview._bandHeight = 3;
-
-/** @typedef {{start: number, end: number}} */
-Network.NetworkOverview.Window;
diff --git a/front_end/network/NetworkPanel.js b/front_end/network/NetworkPanel.js
deleted file mode 100644
index 4164102..0000000
--- a/front_end/network/NetworkPanel.js
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ContextMenu.Provider}
- * @implements {UI.ViewLocationResolver}
- */
-Network.NetworkPanel = class extends UI.Panel {
-  constructor() {
-    super('network');
-    this.registerRequiredCSS('network/networkPanel.css');
-
-    this._networkLogShowOverviewSetting = Common.settings.createSetting('networkLogShowOverview', true);
-    this._networkLogLargeRowsSetting = Common.settings.createSetting('networkLogLargeRows', false);
-    this._networkRecordFilmStripSetting = Common.settings.createSetting('networkRecordFilmStripSetting', false);
-    this._toggleRecordAction = /** @type {!UI.Action }*/ (UI.actionRegistry.action('network.toggle-recording'));
-
-    /** @type {number|undefined} */
-    this._pendingStopTimer;
-    /** @type {?Network.NetworkItemView} */
-    this._networkItemView = null;
-    /** @type {?PerfUI.FilmStripView} */
-    this._filmStripView = null;
-    /** @type {?Network.NetworkPanel.FilmStripRecorder} */
-    this._filmStripRecorder = null;
-
-    const panel = new UI.VBox();
-
-    this._panelToolbar = new UI.Toolbar('', panel.contentElement);
-    this._filterBar = new UI.FilterBar('networkPanel', true);
-    this._filterBar.show(panel.contentElement);
-
-    this._filmStripPlaceholderElement = panel.contentElement.createChild('div', 'network-film-strip-placeholder');
-
-    // Create top overview component.
-    this._overviewPane = new PerfUI.TimelineOverviewPane('network');
-    this._overviewPane.addEventListener(
-        PerfUI.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
-    this._overviewPane.element.id = 'network-overview-panel';
-    this._networkOverview = new Network.NetworkOverview();
-    this._overviewPane.setOverviewControls([this._networkOverview]);
-    this._overviewPlaceholderElement = panel.contentElement.createChild('div');
-
-    this._calculator = new Network.NetworkTransferTimeCalculator();
-
-    this._splitWidget = new UI.SplitWidget(true, false, 'networkPanelSplitViewState');
-    this._splitWidget.hideMain();
-    this._splitWidget.show(panel.contentElement);
-
-    panel.setDefaultFocusedChild(this._filterBar);
-
-    const initialSidebarWidth = 225;
-    const splitWidget = new UI.SplitWidget(true, false, 'networkPanelSidebarState', initialSidebarWidth);
-    splitWidget.hideSidebar();
-    splitWidget.enableShowModeSaving();
-    splitWidget.element.tabIndex = 0;
-    splitWidget.show(this.element);
-    this._sidebarLocation = UI.viewManager.createTabbedLocation(async () => {
-      UI.viewManager.showView('network');
-      splitWidget.showBoth();
-    }, 'network-sidebar', true);
-    const tabbedPane = this._sidebarLocation.tabbedPane();
-    tabbedPane.setMinimumSize(100, 25);
-    tabbedPane.element.classList.add('network-tabbed-pane');
-    tabbedPane.element.addEventListener('keydown', event => {
-      if (event.key !== 'Escape')
-        return;
-      splitWidget.hideSidebar();
-      event.consume();
-    });
-    const closeSidebar = new UI.ToolbarButton(Common.UIString('Close'), 'largeicon-delete');
-    closeSidebar.addEventListener(UI.ToolbarButton.Events.Click, () => splitWidget.hideSidebar());
-    tabbedPane.rightToolbar().appendToolbarItem(closeSidebar);
-    splitWidget.setSidebarWidget(tabbedPane);
-    splitWidget.setMainWidget(panel);
-    splitWidget.setDefaultFocusedChild(panel);
-    this.setDefaultFocusedChild(splitWidget);
-
-    this._progressBarContainer = createElement('div');
-
-    /** @type {!Network.NetworkLogView} */
-    this._networkLogView =
-        new Network.NetworkLogView(this._filterBar, this._progressBarContainer, this._networkLogLargeRowsSetting);
-    this._splitWidget.setSidebarWidget(this._networkLogView);
-
-    this._detailsWidget = new UI.VBox();
-    this._detailsWidget.element.classList.add('network-details-view');
-    this._splitWidget.setMainWidget(this._detailsWidget);
-
-    this._closeButtonElement = createElement('div', 'dt-close-button');
-    this._closeButtonElement.addEventListener('click', this._showRequest.bind(this, null), false);
-    this._closeButtonElement.style.margin = '0 5px';
-
-    this._networkLogShowOverviewSetting.addChangeListener(this._toggleShowOverview, this);
-    this._networkLogLargeRowsSetting.addChangeListener(this._toggleLargerRequests, this);
-    this._networkRecordFilmStripSetting.addChangeListener(this._toggleRecordFilmStrip, this);
-
-    this._preserveLogSetting = Common.moduleSetting('network_log.preserve-log');
-
-    this._offlineCheckbox = MobileThrottling.throttlingManager().createOfflineToolbarCheckbox();
-    this._throttlingSelect = this._createThrottlingConditionsSelect();
-    this._setupToolbarButtons(splitWidget);
-
-    this._toggleRecord(true);
-    this._toggleShowOverview();
-    this._toggleLargerRequests();
-    this._toggleRecordFilmStrip();
-    this._updateUI();
-
-    SDK.targetManager.addModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.WillReloadPage, this._willReloadPage, this);
-    SDK.targetManager.addModelListener(SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._load, this);
-    this._networkLogView.addEventListener(Network.NetworkLogView.Events.RequestSelected, this._onRequestSelected, this);
-    BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this);
-    BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this);
-    BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._onNetworkLogReset, this);
-  }
-
-  /**
-   * @param {!Array<{filterType: !Network.NetworkLogView.FilterType, filterValue: string}>} filters
-   */
-  static revealAndFilter(filters) {
-    const panel = Network.NetworkPanel._instance();
-    let filterString = '';
-    for (const filter of filters)
-      filterString += `${filter.filterType}:${filter.filterValue} `;
-    panel._networkLogView.setTextFilterValue(filterString);
-    UI.viewManager.showView('network');
-  }
-
-  /**
-   * @return {!Network.NetworkPanel}
-   */
-  static _instance() {
-    return /** @type {!Network.NetworkPanel} */ (self.runtime.sharedInstance(Network.NetworkPanel));
-  }
-
-  /**
-   * @return {!UI.ToolbarCheckbox}
-   */
-  offlineCheckboxForTest() {
-    return this._offlineCheckbox;
-  }
-
-  /**
-   * @return {!UI.ToolbarComboBox}
-   */
-  throttlingSelectForTest() {
-    return this._throttlingSelect;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWindowChanged(event) {
-    const startTime = Math.max(this._calculator.minimumBoundary(), event.data.startTime / 1000);
-    const endTime = Math.min(this._calculator.maximumBoundary(), event.data.endTime / 1000);
-    this._networkLogView.setWindow(startTime, endTime);
-  }
-
-  _setupToolbarButtons(splitWidget) {
-    const searchToggle = new UI.ToolbarToggle('Search', 'largeicon-search');
-    function updateSidebarToggle() {
-      searchToggle.setToggled(splitWidget.showMode() !== UI.SplitWidget.ShowMode.OnlyMain);
-    }
-    this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
-    const clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
-    clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => BrowserSDK.networkLog.reset(), this);
-    this._panelToolbar.appendToolbarItem(clearButton);
-    this._panelToolbar.appendSeparator();
-    const recordFilmStripButton = new UI.ToolbarSettingToggle(
-        this._networkRecordFilmStripSetting, 'largeicon-camera', Common.UIString('Capture screenshots'));
-    this._panelToolbar.appendToolbarItem(recordFilmStripButton);
-
-    this._panelToolbar.appendToolbarItem(this._filterBar.filterButton());
-    updateSidebarToggle();
-    splitWidget.addEventListener(UI.SplitWidget.Events.ShowModeChanged, updateSidebarToggle);
-    searchToggle.addEventListener(UI.ToolbarButton.Events.Click, () => {
-      if (splitWidget.showMode() === UI.SplitWidget.ShowMode.OnlyMain)
-        splitWidget.showBoth();
-      else
-        splitWidget.hideSidebar();
-    });
-    this._panelToolbar.appendToolbarItem(searchToggle);
-    this._panelToolbar.appendSeparator();
-
-    this._panelToolbar.appendText(Common.UIString('View:'));
-
-    const largerRequestsButton = new UI.ToolbarSettingToggle(
-        this._networkLogLargeRowsSetting, 'largeicon-large-list', Common.UIString('Use large request rows'),
-        Common.UIString('Use small request rows'));
-    this._panelToolbar.appendToolbarItem(largerRequestsButton);
-
-    const showOverviewButton = new UI.ToolbarSettingToggle(
-        this._networkLogShowOverviewSetting, 'largeicon-waterfall', Common.UIString('Show overview'),
-        Common.UIString('Hide overview'));
-    this._panelToolbar.appendToolbarItem(showOverviewButton);
-
-    this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
-        Common.moduleSetting('network.group-by-frame'), '', Common.UIString('Group by frame')));
-
-    this._panelToolbar.appendSeparator();
-    this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
-        this._preserveLogSetting, Common.UIString('Do not clear log on page reload / navigation'),
-        Common.UIString('Preserve log')));
-
-    const disableCacheCheckbox = new UI.ToolbarSettingCheckbox(
-        Common.moduleSetting('cacheDisabled'), Common.UIString('Disable cache (while DevTools is open)'),
-        Common.UIString('Disable cache'));
-    this._panelToolbar.appendToolbarItem(disableCacheCheckbox);
-
-    this._panelToolbar.appendSeparator();
-    this._panelToolbar.appendToolbarItem(this._offlineCheckbox);
-    this._panelToolbar.appendToolbarItem(this._throttlingSelect);
-
-    this._panelToolbar.appendToolbarItem(new UI.ToolbarItem(this._progressBarContainer));
-  }
-
-  /**
-   * @return {!UI.ToolbarComboBox}
-   */
-  _createThrottlingConditionsSelect() {
-    const toolbarItem = new UI.ToolbarComboBox(null);
-    toolbarItem.setMaxWidth(160);
-    MobileThrottling.throttlingManager().decorateSelectWithNetworkThrottling(toolbarItem.selectElement());
-    return toolbarItem;
-  }
-
-  _toggleRecording() {
-    if (!this._preserveLogSetting.get() && !this._toggleRecordAction.toggled())
-      BrowserSDK.networkLog.reset();
-    this._toggleRecord(!this._toggleRecordAction.toggled());
-  }
-
-  /**
-   * @param {boolean} toggled
-   */
-  _toggleRecord(toggled) {
-    this._toggleRecordAction.setToggled(toggled);
-    this._networkLogView.setRecording(toggled);
-    if (!toggled && this._filmStripRecorder)
-      this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));
-    // TODO(einbinder) This should be moved to a setting/action that NetworkLog owns but NetworkPanel controls, but
-    // always be present in the command menu.
-    BrowserSDK.networkLog.setIsRecording(toggled);
-  }
-
-  /**
-   * @param {?SDK.FilmStripModel} filmStripModel
-   */
-  _filmStripAvailable(filmStripModel) {
-    if (!filmStripModel)
-      return;
-    const calculator = this._networkLogView.timeCalculator();
-    this._filmStripView.setModel(filmStripModel, calculator.minimumBoundary() * 1000, calculator.boundarySpan() * 1000);
-    this._networkOverview.setFilmStripModel(filmStripModel);
-    const timestamps = filmStripModel.frames().map(mapTimestamp);
-
-    /**
-     * @param {!SDK.FilmStripModel.Frame} frame
-     * @return {number}
-     */
-    function mapTimestamp(frame) {
-      return frame.timestamp / 1000;
-    }
-
-    this._networkLogView.addFilmStripFrames(timestamps);
-  }
-
-  _onNetworkLogReset() {
-    Network.BlockedURLsPane.reset();
-    if (!this._preserveLogSetting.get()) {
-      this._calculator.reset();
-      this._overviewPane.reset();
-    }
-    if (this._filmStripView)
-      this._resetFilmStripView();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _willReloadPage(event) {
-    this._toggleRecord(true);
-    if (this._pendingStopTimer) {
-      clearTimeout(this._pendingStopTimer);
-      delete this._pendingStopTimer;
-    }
-    if (this.isShowing() && this._filmStripRecorder)
-      this._filmStripRecorder.startRecording();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _load(event) {
-    if (this._filmStripRecorder && this._filmStripRecorder.isRecording()) {
-      this._pendingStopTimer =
-          setTimeout(this._stopFilmStripRecording.bind(this), Network.NetworkPanel.displayScreenshotDelay);
-    }
-  }
-
-  _stopFilmStripRecording() {
-    this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));
-    delete this._pendingStopTimer;
-  }
-
-  _toggleLargerRequests() {
-    this._updateUI();
-  }
-
-  _toggleShowOverview() {
-    const toggled = this._networkLogShowOverviewSetting.get();
-    if (toggled)
-      this._overviewPane.show(this._overviewPlaceholderElement);
-    else
-      this._overviewPane.detach();
-    this.doResize();
-  }
-
-  _toggleRecordFilmStrip() {
-    const toggled = this._networkRecordFilmStripSetting.get();
-    if (toggled && !this._filmStripRecorder) {
-      this._filmStripView = new PerfUI.FilmStripView();
-      this._filmStripView.setMode(PerfUI.FilmStripView.Modes.FrameBased);
-      this._filmStripView.element.classList.add('network-film-strip');
-      this._filmStripRecorder =
-          new Network.NetworkPanel.FilmStripRecorder(this._networkLogView.timeCalculator(), this._filmStripView);
-      this._filmStripView.show(this._filmStripPlaceholderElement);
-      this._filmStripView.addEventListener(PerfUI.FilmStripView.Events.FrameSelected, this._onFilmFrameSelected, this);
-      this._filmStripView.addEventListener(PerfUI.FilmStripView.Events.FrameEnter, this._onFilmFrameEnter, this);
-      this._filmStripView.addEventListener(PerfUI.FilmStripView.Events.FrameExit, this._onFilmFrameExit, this);
-      this._resetFilmStripView();
-    }
-
-    if (!toggled && this._filmStripRecorder) {
-      this._filmStripView.detach();
-      this._filmStripView = null;
-      this._filmStripRecorder = null;
-    }
-  }
-
-  _resetFilmStripView() {
-    this._filmStripView.reset();
-    this._filmStripView.setStatusText(Common.UIString(
-        'Hit %s to reload and capture filmstrip.',
-        UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0].name));
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return this._networkLogView.elementsToRestoreScrollPositionsFor();
-  }
-
-  /**
-   * @override
-   * @param {!KeyboardEvent} event
-   */
-  handleShortcut(event) {
-    if (this._networkItemView && event.keyCode === UI.KeyboardShortcut.Keys.Esc.code) {
-      this._showRequest(null);
-      event.handled = true;
-      return;
-    }
-
-    super.handleShortcut(event);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Network.NetworkPanel, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.context.setFlavor(Network.NetworkPanel, null);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  revealAndHighlightRequest(request) {
-    this._showRequest(null);
-    if (request)
-      this._networkLogView.revealAndHighlightRequest(request);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<?Network.NetworkItemView>}
-   */
-  async selectRequest(request) {
-    await UI.viewManager.showView('network');
-    this._networkLogView.selectRequest(request);
-    return this._networkItemView;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRowSizeChanged(event) {
-    this._updateUI();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestSelected(event) {
-    const request = /** @type {?SDK.NetworkRequest} */ (event.data);
-    this._showRequest(request);
-  }
-
-  /**
-   * @param {?SDK.NetworkRequest} request
-   */
-  _showRequest(request) {
-    if (this._networkItemView) {
-      this._networkItemView.detach();
-      this._networkItemView = null;
-    }
-
-    if (request) {
-      this._networkItemView = new Network.NetworkItemView(request, this._networkLogView.timeCalculator());
-      this._networkItemView.leftToolbar().appendToolbarItem(new UI.ToolbarItem(this._closeButtonElement));
-      this._networkItemView.show(this._detailsWidget.element);
-      this._splitWidget.showBoth();
-    } else {
-      this._splitWidget.hideMain();
-      this._networkLogView.clearSelection();
-    }
-    this._updateUI();
-  }
-
-  _updateUI() {
-    this._detailsWidget.element.classList.toggle(
-        'network-details-view-tall-header', this._networkLogLargeRowsSetting.get());
-    this._networkLogView.switchViewMode(!this._splitWidget.isResizable());
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   * @this {Network.NetworkPanel}
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    /**
-     * @this {Network.NetworkPanel}
-     */
-    function reveal(request) {
-      UI.viewManager.showView('network').then(this.revealAndHighlightRequest.bind(this, request));
-    }
-
-    /**
-     * @this {Network.NetworkPanel}
-     */
-    function appendRevealItem(request) {
-      contextMenu.revealSection().appendItem(Common.UIString('Reveal in Network panel'), reveal.bind(this, request));
-    }
-
-    if (event.target.isSelfOrDescendant(this.element))
-      return;
-
-    if (target instanceof SDK.Resource) {
-      const resource = /** @type {!SDK.Resource} */ (target);
-      if (resource.request)
-        appendRevealItem.call(this, resource.request);
-      return;
-    }
-    if (target instanceof Workspace.UISourceCode) {
-      const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (target);
-      const resource = Bindings.resourceForURL(uiSourceCode.url());
-      if (resource && resource.request)
-        appendRevealItem.call(this, resource.request);
-      return;
-    }
-
-    if (!(target instanceof SDK.NetworkRequest))
-      return;
-    const request = /** @type {!SDK.NetworkRequest} */ (target);
-    if (this._networkItemView && this._networkItemView.isShowing() && this._networkItemView.request() === request)
-      return;
-
-    appendRevealItem.call(this, request);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFilmFrameSelected(event) {
-    const timestamp = /** @type {number} */ (event.data);
-    this._overviewPane.requestWindowTimes(0, timestamp);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFilmFrameEnter(event) {
-    const timestamp = /** @type {number} */ (event.data);
-    this._networkOverview.selectFilmStripFrame(timestamp);
-    this._networkLogView.selectFilmStripFrame(timestamp / 1000);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFilmFrameExit(event) {
-    this._networkOverview.clearFilmStripFrame();
-    this._networkLogView.clearFilmStripFrame();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onUpdateRequest(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    this._calculator.updateBoundaries(request);
-    // FIXME: Unify all time units across the frontend!
-    this._overviewPane.setBounds(this._calculator.minimumBoundary() * 1000, this._calculator.maximumBoundary() * 1000);
-    this._networkOverview.updateRequest(request);
-    this._overviewPane.scheduleUpdate();
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   * @return {?UI.ViewLocation}
-   */
-  resolveLocation(locationName) {
-    if (locationName === 'network-sidebar')
-      return this._sidebarLocation;
-    return null;
-  }
-};
-
-Network.NetworkPanel.displayScreenshotDelay = 1000;
-
-/**
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Network.NetworkPanel.ContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    Network.NetworkPanel._instance().appendApplicableItems(event, contextMenu, target);
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Network.NetworkPanel.RequestRevealer = class {
-  /**
-   * @override
-   * @param {!Object} request
-   * @return {!Promise}
-   */
-  reveal(request) {
-    if (!(request instanceof SDK.NetworkRequest))
-      return Promise.reject(new Error('Internal error: not a network request'));
-    const panel = Network.NetworkPanel._instance();
-    return UI.viewManager.showView('network').then(panel.revealAndHighlightRequest.bind(panel, request));
-  }
-};
-
-
-/**
- * @implements {SDK.TracingManagerClient}
- */
-Network.NetworkPanel.FilmStripRecorder = class {
-  /**
-   * @param {!Network.NetworkTimeCalculator} timeCalculator
-   * @param {!PerfUI.FilmStripView} filmStripView
-   */
-  constructor(timeCalculator, filmStripView) {
-    /** @type {?SDK.TracingManager} */
-    this._tracingManager = null;
-    /** @type {?SDK.ResourceTreeModel} */
-    this._resourceTreeModel = null;
-    this._timeCalculator = timeCalculator;
-    this._filmStripView = filmStripView;
-    /** @type {?SDK.TracingModel} */
-    this._tracingModel = null;
-    /** @type {?function(?SDK.FilmStripModel)} */
-    this._callback = null;
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   */
-  traceEventsCollected(events) {
-    if (this._tracingModel)
-      this._tracingModel.addEvents(events);
-  }
-
-  /**
-   * @override
-   */
-  tracingComplete() {
-    if (!this._tracingModel || !this._tracingManager)
-      return;
-    this._tracingModel.tracingComplete();
-    this._tracingManager = null;
-    this._callback(new SDK.FilmStripModel(this._tracingModel, this._timeCalculator.minimumBoundary() * 1000));
-    this._callback = null;
-    if (this._resourceTreeModel)
-      this._resourceTreeModel.resumeReload();
-    this._resourceTreeModel = null;
-  }
-
-  /**
-   * @override
-   */
-  tracingBufferUsage() {
-  }
-
-  /**
-   * @override
-   * @param {number} progress
-   */
-  eventsRetrievalProgress(progress) {
-  }
-
-  startRecording() {
-    this._filmStripView.reset();
-    this._filmStripView.setStatusText(Common.UIString('Recording frames...'));
-    const tracingManagers = SDK.targetManager.models(SDK.TracingManager);
-    if (this._tracingManager || !tracingManagers.length)
-      return;
-
-    this._tracingManager = tracingManagers[0];
-    this._resourceTreeModel = this._tracingManager.target().model(SDK.ResourceTreeModel);
-    if (this._tracingModel)
-      this._tracingModel.dispose();
-    this._tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage());
-    this._tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', '');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRecording() {
-    return !!this._tracingManager;
-  }
-
-  /**
-   * @param {function(?SDK.FilmStripModel)} callback
-   */
-  stopRecording(callback) {
-    if (!this._tracingManager)
-      return;
-
-    this._tracingManager.stop();
-    if (this._resourceTreeModel)
-      this._resourceTreeModel.suspendReload();
-    this._callback = callback;
-    this._filmStripView.setStatusText(Common.UIString('Fetching frames...'));
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Network.NetworkPanel.RecordActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const panel = UI.context.flavor(Network.NetworkPanel);
-    console.assert(panel && panel instanceof Network.NetworkPanel);
-    panel._toggleRecording();
-    return true;
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- */
-Network.NetworkPanel.RequestLocationRevealer = class {
-  /**
-   * @override
-   * @param {!Object} match
-   * @return {!Promise}
-   */
-  async reveal(match) {
-    const location = /** @type {!Network.UIRequestLocation} */ (match);
-    const view = await Network.NetworkPanel._instance().selectRequest(location.request);
-    if (!view)
-      return;
-    if (location.searchMatch)
-      await view.revealResponseBody(location.searchMatch.lineNumber);
-    if (location.requestHeader)
-      view.revealRequestHeader(location.requestHeader.name);
-    if (location.responseHeader)
-      view.revealResponseHeader(location.responseHeader.name);
-  }
-};
-
-Network.SearchNetworkView = class extends Search.SearchView {
-  constructor() {
-    super('network');
-  }
-
-  /**
-   * @param {string} query
-   * @param {boolean=} searchImmediately
-   * @return {!Promise<!Search.SearchView>}
-   */
-  static async openSearch(query, searchImmediately) {
-    await UI.viewManager.showView('network.search-network-tab');
-    const searchView =
-        /** @type {!Network.SearchNetworkView} */ (self.runtime.sharedInstance(Network.SearchNetworkView));
-    searchView.toggle(query, !!searchImmediately);
-    return searchView;
-  }
-
-  /**
-   * @override
-   * @return {!Search.SearchScope}
-   */
-  createScope() {
-    return new Network.NetworkSearchScope();
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Network.NetworkPanel.SearchActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    this._showSearch();
-    return true;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _showSearch() {
-    const selection = UI.inspectorView.element.window().getSelection();
-    let queryCandidate = '';
-    if (selection.rangeCount)
-      queryCandidate = selection.toString().replace(/\r?\n.*/, '');
-    return Network.SearchNetworkView.openSearch(queryCandidate);
-  }
-};
diff --git a/front_end/network/NetworkSearchScope.js b/front_end/network/NetworkSearchScope.js
deleted file mode 100644
index de93182..0000000
--- a/front_end/network/NetworkSearchScope.js
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Search.SearchScope}
- */
-Network.NetworkSearchScope = class {
-  /**
-   * @override
-   * @param {!Common.Progress} progress
-   */
-  performIndexing(progress) {
-    setImmediate(progress.done.bind(progress));
-  }
-
-  /**
-   * @override
-   * @param {!Search.SearchConfig} searchConfig
-   * @param {!Common.Progress} progress
-   * @param {function(!Search.SearchResult)} searchResultCallback
-   * @param {function(boolean)} searchFinishedCallback
-   * @return {?}
-   */
-  async performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) {
-    const promises = [];
-    const requests =
-        BrowserSDK.networkLog.requests().filter(request => searchConfig.filePathMatchesFileQuery(request.url()));
-    progress.setTotalWork(requests.length);
-    for (const request of requests) {
-      const promise = this._searchRequest(searchConfig, request, progress);
-      promises.push(promise);
-    }
-    const results = await Promise.all(promises);
-    if (progress.isCanceled()) {
-      searchFinishedCallback(false);
-      return;
-    }
-    for (const result of results.sort((r1, r2) => r1.label().localeCompare(r2.label()))) {
-      if (result.matchesCount() > 0)
-        searchResultCallback(result);
-    }
-    progress.done();
-    searchFinishedCallback(true);
-  }
-
-  /**
-   * @param {!Search.SearchConfig} searchConfig
-   * @param {!SDK.NetworkRequest} request
-   * @param {!Common.Progress} progress
-   * @return {!Promise<?Network.NetworkSearchResult>}
-   */
-  async _searchRequest(searchConfig, request, progress) {
-    let bodyMatches = [];
-    if (request.contentType().isTextType()) {
-      bodyMatches =
-          await request.searchInContent(searchConfig.query(), !searchConfig.ignoreCase(), searchConfig.isRegex());
-    }
-    if (progress.isCanceled())
-      return null;
-    const locations = [];
-    for (const header of request.requestHeaders()) {
-      if (headerMatchesQuery(header))
-        locations.push(new Network.UIRequestLocation(request, header, null, null));
-    }
-    for (const header of request.responseHeaders) {
-      if (headerMatchesQuery(header))
-        locations.push(new Network.UIRequestLocation(request, null, header, null));
-    }
-    for (const match of bodyMatches)
-      locations.push(new Network.UIRequestLocation(request, null, null, match));
-    progress.worked();
-    return new Network.NetworkSearchResult(request, locations);
-
-    /**
-     * @param {!SDK.NetworkRequest.NameValue} header
-     * @return {boolean}
-     */
-    function headerMatchesQuery(header) {
-      const string = `${header.name}: ${header.value}`;
-      const flags = searchConfig.ignoreCase() ? 'i' : '';
-      const regExps = searchConfig.queries().map(query => new RegExp(query, flags));
-      let pos = 0;
-      for (const regExp of regExps) {
-        const match = string.substr(pos).match(regExp);
-        if (!match)
-          return false;
-        pos += match.index + match[0].length;
-      }
-      return true;
-    }
-  }
-
-  /**
-   * @override
-   */
-  stopSearch() {
-  }
-};
-
-Network.UIRequestLocation = class {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {?SDK.NetworkRequest.NameValue} requestHeader
-   * @param {?SDK.NetworkRequest.NameValue} responseHeader
-   * @param {?Common.ContentProvider.SearchMatch} searchMatch
-   */
-  constructor(request, requestHeader, responseHeader, searchMatch) {
-    this.request = request;
-    this.requestHeader = requestHeader;
-    this.responseHeader = responseHeader;
-    this.searchMatch = searchMatch;
-  }
-};
-
-/**
- * @implements Search.SearchResult
- */
-Network.NetworkSearchResult = class {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {!Array<!Network.UIRequestLocation>} locations
-   */
-  constructor(request, locations) {
-    this._request = request;
-    this._locations = locations;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  matchesCount() {
-    return this._locations.length;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  label() {
-    return this._request.displayName;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  description() {
-    const parsedUrl = this._request.parsedURL;
-    if (!parsedUrl)
-      return this._request.url();
-    return parsedUrl.urlWithoutScheme();
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {string}
-   */
-  matchLineContent(index) {
-    const location = this._locations[index];
-    const header = location.requestHeader || location.responseHeader;
-    if (header)
-      return header.value;
-    return location.searchMatch.lineContent;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {!Object}
-   */
-  matchRevealable(index) {
-    return this._locations[index];
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?}
-   */
-  matchLabel(index) {
-    const location = this._locations[index];
-    const header = location.requestHeader || location.responseHeader;
-    if (header)
-      return `${header.name}:`;
-    return location.searchMatch.lineNumber + 1;
-  }
-};
diff --git a/front_end/network/NetworkTimeCalculator.js b/front_end/network/NetworkTimeCalculator.js
deleted file mode 100644
index d1b2898..0000000
--- a/front_end/network/NetworkTimeCalculator.js
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Network.NetworkTimeBoundary = class {
-  /**
-   * @param {number} minimum
-   * @param {number} maximum
-   */
-  constructor(minimum, maximum) {
-    this.minimum = minimum;
-    this.maximum = maximum;
-  }
-
-  /**
-   * @param {!Network.NetworkTimeBoundary} other
-   * @return {boolean}
-   */
-  equals(other) {
-    return (this.minimum === other.minimum) && (this.maximum === other.maximum);
-  }
-};
-
-/**
- * @implements {PerfUI.TimelineGrid.Calculator}
- * @unrestricted
- */
-Network.NetworkTimeCalculator = class extends Common.Object {
-  constructor(startAtZero) {
-    super();
-    this.startAtZero = startAtZero;
-    this._minimumBoundary = -1;
-    this._maximumBoundary = -1;
-    this._boundryChangedEventThrottler = new Common.Throttler(0);
-    /** @type {?Network.NetworkTimeBoundary} */
-    this._window = null;
-  }
-
-  /**
-   * @param {?Network.NetworkTimeBoundary} window
-   */
-  setWindow(window) {
-    this._window = window;
-    this._boundaryChanged();
-  }
-
-  setInitialUserFriendlyBoundaries() {
-    this._minimumBoundary = 0;
-    this._maximumBoundary = 1;
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {
-    return (time - this.minimumBoundary()) / this.boundarySpan() * this._workingArea;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.secondsToString(value, !!precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._window ? this._window.minimum : this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zeroTime() {
-    return this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maximumBoundary() {
-    return this._window ? this._window.maximum : this._maximumBoundary;
-  }
-
-  /**
-   * @return {!Network.NetworkTimeBoundary}
-   */
-  boundary() {
-    return new Network.NetworkTimeBoundary(this.minimumBoundary(), this.maximumBoundary());
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  boundarySpan() {
-    return this.maximumBoundary() - this.minimumBoundary();
-  }
-
-  reset() {
-    this._minimumBoundary = -1;
-    this._maximumBoundary = -1;
-    this._boundaryChanged();
-  }
-
-  /**
-   * @return {number}
-   */
-  _value(item) {
-    return 0;
-  }
-
-  /**
-   * @param {number} clientWidth
-   */
-  setDisplayWidth(clientWidth) {
-    this._workingArea = clientWidth;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!{start: number, middle: number, end: number}}
-   */
-  computeBarGraphPercentages(request) {
-    let start;
-    let middle;
-    let end;
-    if (request.startTime !== -1)
-      start = ((request.startTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
-    else
-      start = 0;
-
-    if (request.responseReceivedTime !== -1)
-      middle = ((request.responseReceivedTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
-    else
-      middle = (this.startAtZero ? start : 100);
-
-    if (request.endTime !== -1)
-      end = ((request.endTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
-    else
-      end = (this.startAtZero ? middle : 100);
-
-    if (this.startAtZero) {
-      end -= start;
-      middle -= start;
-      start = 0;
-    }
-
-    return {start: start, middle: middle, end: end};
-  }
-
-  /**
-   * @param {number} eventTime
-   * @return {number}
-   */
-  computePercentageFromEventTime(eventTime) {
-    // This function computes a percentage in terms of the total loading time
-    // of a specific event. If startAtZero is set, then this is useless, and we
-    // want to return 0.
-    if (eventTime !== -1 && !this.startAtZero)
-      return ((eventTime - this.minimumBoundary()) / this.boundarySpan()) * 100;
-
-    return 0;
-  }
-
-  /**
-   * @param {number} percentage
-   * @return {number}
-   */
-  percentageToTime(percentage) {
-    return percentage * this.boundarySpan() / 100 + this.minimumBoundary();
-  }
-
-  _boundaryChanged() {
-    this._boundryChangedEventThrottler.schedule(dispatchEvent.bind(this));
-
-    /**
-     * @return {!Promise.<undefined>}
-     * @this {Network.NetworkTimeCalculator}
-     */
-    function dispatchEvent() {
-      this.dispatchEventToListeners(Network.NetworkTimeCalculator.Events.BoundariesChanged);
-      return Promise.resolve();
-    }
-  }
-
-  /**
-   * @param {number} eventTime
-   */
-  updateBoundariesForEventTime(eventTime) {
-    if (eventTime === -1 || this.startAtZero)
-      return;
-
-    if (this._maximumBoundary === undefined || eventTime > this._maximumBoundary) {
-      this._maximumBoundary = eventTime;
-      this._boundaryChanged();
-    }
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!{left: string, right: string, tooltip: (string|undefined)}}
-   */
-  computeBarGraphLabels(request) {
-    let rightLabel = '';
-    if (request.responseReceivedTime !== -1 && request.endTime !== -1)
-      rightLabel = Number.secondsToString(request.endTime - request.responseReceivedTime);
-
-    const hasLatency = request.latency > 0;
-    const leftLabel = hasLatency ? Number.secondsToString(request.latency) : rightLabel;
-
-    if (request.timing)
-      return {left: leftLabel, right: rightLabel};
-
-    let tooltip;
-    if (hasLatency && rightLabel) {
-      const total = Number.secondsToString(request.duration);
-      tooltip = Network.NetworkTimeCalculator._latencyDownloadTotalFormat.format(leftLabel, rightLabel, total);
-    } else if (hasLatency) {
-      tooltip = Network.NetworkTimeCalculator._latencyFormat.format(leftLabel);
-    } else if (rightLabel) {
-      tooltip = Network.NetworkTimeCalculator._downloadFormat.format(rightLabel);
-    }
-
-    if (request.fetchedViaServiceWorker)
-      tooltip = Network.NetworkTimeCalculator._fromServiceWorkerFormat.format(tooltip);
-    else if (request.cached())
-      tooltip = Network.NetworkTimeCalculator._fromCacheFormat.format(tooltip);
-    return {left: leftLabel, right: rightLabel, tooltip: tooltip};
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  updateBoundaries(request) {
-    const lowerBound = this._lowerBound(request);
-    const upperBound = this._upperBound(request);
-    let changed = false;
-    if (lowerBound !== -1 || this.startAtZero)
-      changed = this._extendBoundariesToIncludeTimestamp(this.startAtZero ? 0 : lowerBound);
-    if (upperBound !== -1)
-      changed = this._extendBoundariesToIncludeTimestamp(upperBound) || changed;
-    if (changed)
-      this._boundaryChanged();
-  }
-
-  /**
-   * @param {number} timestamp
-   * @return {boolean}
-   */
-  _extendBoundariesToIncludeTimestamp(timestamp) {
-    const previousMinimumBoundary = this._minimumBoundary;
-    const previousMaximumBoundary = this._maximumBoundary;
-    const minOffset = Network.NetworkTimeCalculator._minimumSpread;
-    if (this._minimumBoundary === -1 || this._maximumBoundary === -1) {
-      this._minimumBoundary = timestamp;
-      this._maximumBoundary = timestamp + minOffset;
-    } else {
-      this._minimumBoundary = Math.min(timestamp, this._minimumBoundary);
-      this._maximumBoundary = Math.max(timestamp, this._minimumBoundary + minOffset, this._maximumBoundary);
-    }
-    return previousMinimumBoundary !== this._minimumBoundary || previousMaximumBoundary !== this._maximumBoundary;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {number}
-   */
-  _lowerBound(request) {
-    return 0;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {number}
-   */
-  _upperBound(request) {
-    return 0;
-  }
-};
-
-Network.NetworkTimeCalculator._minimumSpread = 0.1;
-
-/** @enum {symbol} */
-Network.NetworkTimeCalculator.Events = {
-  BoundariesChanged: Symbol('BoundariesChanged')
-};
-
-/** @type {!Common.UIStringFormat} */
-Network.NetworkTimeCalculator._latencyDownloadTotalFormat =
-    new Common.UIStringFormat('%s latency, %s download (%s total)');
-
-/** @type {!Common.UIStringFormat} */
-Network.NetworkTimeCalculator._latencyFormat = new Common.UIStringFormat('%s latency');
-
-/** @type {!Common.UIStringFormat} */
-Network.NetworkTimeCalculator._downloadFormat = new Common.UIStringFormat('%s download');
-
-/** @type {!Common.UIStringFormat} */
-Network.NetworkTimeCalculator._fromServiceWorkerFormat = new Common.UIStringFormat('%s (from ServiceWorker)');
-
-/** @type {!Common.UIStringFormat} */
-Network.NetworkTimeCalculator._fromCacheFormat = new Common.UIStringFormat('%s (from cache)');
-
-/**
- * @unrestricted
- */
-Network.NetworkTransferTimeCalculator = class extends Network.NetworkTimeCalculator {
-  constructor() {
-    super(false);
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.secondsToString(value - this.zeroTime(), !!precision);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkRequest} request
-   * @return {number}
-   */
-  _lowerBound(request) {
-    return request.issueTime();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkRequest} request
-   * @return {number}
-   */
-  _upperBound(request) {
-    return request.endTime;
-  }
-};
-
-/**
- * @unrestricted
- */
-Network.NetworkTransferDurationCalculator = class extends Network.NetworkTimeCalculator {
-  constructor() {
-    super(true);
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.secondsToString(value, !!precision);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.NetworkRequest} request
-   * @return {number}
-   */
-  _upperBound(request) {
-    return request.duration;
-  }
-};
diff --git a/front_end/network/NetworkWaterfallColumn.js b/front_end/network/NetworkWaterfallColumn.js
deleted file mode 100644
index d904b26..0000000
--- a/front_end/network/NetworkWaterfallColumn.js
+++ /dev/null
@@ -1,620 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Network.NetworkWaterfallColumn = class extends UI.VBox {
-  /**
-   * @param {!Network.NetworkTimeCalculator} calculator
-   */
-  constructor(calculator) {
-    // TODO(allada) Make this a shadowDOM when the NetworkWaterfallColumn gets moved into NetworkLogViewColumns.
-    super(false);
-    this.registerRequiredCSS('network/networkWaterfallColumn.css');
-
-    this._canvas = this.contentElement.createChild('canvas');
-    this._canvas.tabIndex = 1;
-    this.setDefaultFocusedElement(this._canvas);
-    this._canvasPosition = this._canvas.getBoundingClientRect();
-
-    /** @const */
-    this._leftPadding = 5;
-    /** @const */
-    this._fontSize = 10;
-
-    this._rightPadding = 0;
-    this._scrollTop = 0;
-
-    this._headerHeight = 0;
-    this._calculator = calculator;
-
-    // this._rawRowHeight captures model height (41 or 21px),
-    // this._rowHeight is computed height of the row in CSS pixels, can be 20.8 for zoomed-in content.
-    this._rawRowHeight = 0;
-    this._rowHeight = 0;
-
-    this._offsetWidth = 0;
-    this._offsetHeight = 0;
-    this._startTime = this._calculator.minimumBoundary();
-    this._endTime = this._calculator.maximumBoundary();
-
-    this._popoverHelper = new UI.PopoverHelper(this.element, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setHasPadding(true);
-    this._popoverHelper.setTimeout(300, 300);
-
-    /** @type {!Array<!Network.NetworkNode>} */
-    this._nodes = [];
-
-    /** @type {?Network.NetworkNode} */
-    this._hoveredNode = null;
-
-    /** @type {!Map<string, !Array<number>>} */
-    this._eventDividers = new Map();
-
-    /** @type {(number|undefined)} */
-    this._updateRequestID;
-
-    this.element.addEventListener('mousemove', this._onMouseMove.bind(this), true);
-    this.element.addEventListener('mouseleave', event => this._setHoveredNode(null, false), true);
-
-    this._styleForTimeRangeName = Network.NetworkWaterfallColumn._buildRequestTimeRangeStyle();
-
-    const resourceStyleTuple = Network.NetworkWaterfallColumn._buildResourceTypeStyle();
-    /** @type {!Map<!Common.ResourceType, !Network.NetworkWaterfallColumn._LayerStyle>} */
-    this._styleForWaitingResourceType = resourceStyleTuple[0];
-    /** @type {!Map<!Common.ResourceType, !Network.NetworkWaterfallColumn._LayerStyle>} */
-    this._styleForDownloadingResourceType = resourceStyleTuple[1];
-
-    const baseLineColor = UI.themeSupport.patchColorText('#a5a5a5', UI.ThemeSupport.ColorUsage.Foreground);
-    /** @type {!Network.NetworkWaterfallColumn._LayerStyle} */
-    this._wiskerStyle = {borderColor: baseLineColor, lineWidth: 1};
-    /** @type {!Network.NetworkWaterfallColumn._LayerStyle} */
-    this._hoverDetailsStyle = {fillStyle: baseLineColor, lineWidth: 1, borderColor: baseLineColor};
-
-    /** @type {!Map<!Network.NetworkWaterfallColumn._LayerStyle, !Path2D>} */
-    this._pathForStyle = new Map();
-    /** @type {!Array<!Network.NetworkWaterfallColumn._TextLayer>} */
-    this._textLayers = [];
-  }
-
-  /**
-   * @return {!Map<!Network.RequestTimeRangeNames, !Network.NetworkWaterfallColumn._LayerStyle>}
-   */
-  static _buildRequestTimeRangeStyle() {
-    const types = Network.RequestTimeRangeNames;
-    const styleMap = new Map();
-    styleMap.set(types.Connecting, {fillStyle: '#FF9800'});
-    styleMap.set(types.SSL, {fillStyle: '#9C27B0'});
-    styleMap.set(types.DNS, {fillStyle: '#009688'});
-    styleMap.set(types.Proxy, {fillStyle: '#A1887F'});
-    styleMap.set(types.Blocking, {fillStyle: '#AAAAAA'});
-    styleMap.set(types.Push, {fillStyle: '#8CDBff'});
-    styleMap.set(types.Queueing, {fillStyle: 'white', lineWidth: 2, borderColor: 'lightgrey'});
-    // This ensures we always show at least 2 px for a request.
-    styleMap.set(types.Receiving, {fillStyle: '#03A9F4', lineWidth: 2, borderColor: '#03A9F4'});
-    styleMap.set(types.Waiting, {fillStyle: '#00C853'});
-    styleMap.set(types.ReceivingPush, {fillStyle: '#03A9F4'});
-    styleMap.set(types.ServiceWorker, {fillStyle: 'orange'});
-    styleMap.set(types.ServiceWorkerPreparation, {fillStyle: 'orange'});
-    return styleMap;
-  }
-
-  /**
-   * @return {!Array<!Map<!Common.ResourceType, !Network.NetworkWaterfallColumn._LayerStyle>>}
-   */
-  static _buildResourceTypeStyle() {
-    const baseResourceTypeColors = new Map([
-      ['document', 'hsl(215, 100%, 80%)'],
-      ['font', 'hsl(8, 100%, 80%)'],
-      ['media', 'hsl(90, 50%, 80%)'],
-      ['image', 'hsl(90, 50%, 80%)'],
-      ['script', 'hsl(31, 100%, 80%)'],
-      ['stylesheet', 'hsl(272, 64%, 80%)'],
-      ['texttrack', 'hsl(8, 100%, 80%)'],
-      ['websocket', 'hsl(0, 0%, 95%)'],
-      ['xhr', 'hsl(53, 100%, 80%)'],
-      ['fetch', 'hsl(53, 100%, 80%)'],
-      ['other', 'hsl(0, 0%, 95%)'],
-    ]);
-    const waitingStyleMap = new Map();
-    const downloadingStyleMap = new Map();
-
-    for (const resourceType of Object.values(Common.resourceTypes)) {
-      let color = baseResourceTypeColors.get(resourceType.name());
-      if (!color)
-        color = baseResourceTypeColors.get('other');
-      const borderColor = toBorderColor(color);
-
-      waitingStyleMap.set(resourceType, {fillStyle: toWaitingColor(color), lineWidth: 1, borderColor: borderColor});
-      downloadingStyleMap.set(resourceType, {fillStyle: color, lineWidth: 1, borderColor: borderColor});
-    }
-    return [waitingStyleMap, downloadingStyleMap];
-
-    /**
-     * @param {string} color
-     */
-    function toBorderColor(color) {
-      const parsedColor = Common.Color.parse(color);
-      const hsla = parsedColor.hsla();
-      hsla[1] /= 2;
-      hsla[2] -= Math.min(hsla[2], 0.2);
-      return parsedColor.asString(null);
-    }
-
-    /**
-     * @param {string} color
-     */
-    function toWaitingColor(color) {
-      const parsedColor = Common.Color.parse(color);
-      const hsla = parsedColor.hsla();
-      hsla[2] *= 1.1;
-      return parsedColor.asString(null);
-    }
-  }
-
-  _resetPaths() {
-    this._pathForStyle.clear();
-    this._pathForStyle.set(this._wiskerStyle, new Path2D());
-    this._styleForTimeRangeName.forEach(style => this._pathForStyle.set(style, new Path2D()));
-    this._styleForWaitingResourceType.forEach(style => this._pathForStyle.set(style, new Path2D()));
-    this._styleForDownloadingResourceType.forEach(style => this._pathForStyle.set(style, new Path2D()));
-    this._pathForStyle.set(this._hoverDetailsStyle, new Path2D());
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._popoverHelper.hidePopover();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.update();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    this._setHoveredNode(this.getNodeFromPoint(event.offsetX, event.offsetY), event.shiftKey);
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    if (!this._hoveredNode)
-      return null;
-    const request = this._hoveredNode.request();
-    if (!request)
-      return null;
-    const useTimingBars = !Common.moduleSetting('networkColorCodeResourceTypes').get() && !this._calculator.startAtZero;
-    let range;
-    let start;
-    let end;
-    if (useTimingBars) {
-      range = Network.RequestTimingView.calculateRequestTimeRanges(request, 0)
-                  .find(data => data.name === Network.RequestTimeRangeNames.Total);
-      start = this._timeToPosition(range.start);
-      end = this._timeToPosition(range.end);
-    } else {
-      range = this._getSimplifiedBarRange(request, 0);
-      start = range.start;
-      end = range.end;
-    }
-
-    if (end - start < 50) {
-      const halfWidth = (end - start) / 2;
-      start = start + halfWidth - 25;
-      end = end - halfWidth + 25;
-    }
-
-    if (event.clientX < this._canvasPosition.left + start || event.clientX > this._canvasPosition.left + end)
-      return null;
-
-    const rowIndex = this._nodes.findIndex(node => node.hovered());
-    const barHeight = this._getBarHeight(range.name);
-    const y = this._headerHeight + (this._rowHeight * rowIndex - this._scrollTop) + ((this._rowHeight - barHeight) / 2);
-
-    if (event.clientY < this._canvasPosition.top + y || event.clientY > this._canvasPosition.top + y + barHeight)
-      return null;
-
-    const anchorBox = this.element.boxInWindow();
-    anchorBox.x += start;
-    anchorBox.y += y;
-    anchorBox.width = end - start;
-    anchorBox.height = barHeight;
-
-    return {
-      box: anchorBox,
-      show: popover => {
-        const content =
-            Network.RequestTimingView.createTimingTable(/** @type {!SDK.NetworkRequest} */ (request), this._calculator);
-        popover.contentElement.appendChild(content);
-        return Promise.resolve(true);
-      }
-    };
-  }
-
-  /**
-   * @param {?Network.NetworkNode} node
-   * @param {boolean} highlightInitiatorChain
-   */
-  _setHoveredNode(node, highlightInitiatorChain) {
-    if (this._hoveredNode)
-      this._hoveredNode.setHovered(false, false);
-    this._hoveredNode = node;
-    if (this._hoveredNode)
-      this._hoveredNode.setHovered(true, highlightInitiatorChain);
-  }
-
-  /**
-   * @param {number} height
-   */
-  setRowHeight(height) {
-    this._rawRowHeight = height;
-    this._updateRowHeight();
-  }
-
-  _updateRowHeight() {
-    this._rowHeight = Math.round(this._rawRowHeight * window.devicePixelRatio) / window.devicePixelRatio;
-  }
-
-  /**
-   * @param {number} height
-   */
-  setHeaderHeight(height) {
-    this._headerHeight = height;
-  }
-
-  /**
-   * @param {number} padding
-   */
-  setRightPadding(padding) {
-    this._rightPadding = padding;
-    this._calculateCanvasSize();
-  }
-
-  /**
-   * @param {!Network.NetworkTimeCalculator} calculator
-   */
-  setCalculator(calculator) {
-    this._calculator = calculator;
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @return {?Network.NetworkNode}
-   */
-  getNodeFromPoint(x, y) {
-    if (y <= this._headerHeight)
-      return null;
-    return this._nodes[Math.floor((this._scrollTop + y - this._headerHeight) / this._rowHeight)];
-  }
-
-  scheduleDraw() {
-    if (this._updateRequestID)
-      return;
-    this._updateRequestID = this.element.window().requestAnimationFrame(() => this.update());
-  }
-
-  /**
-   * @param {number=} scrollTop
-   * @param {!Map<string, !Array<number>>=} eventDividers
-   * @param {!Array<!Network.NetworkNode>=} nodes
-   */
-  update(scrollTop, eventDividers, nodes) {
-    if (scrollTop !== undefined && this._scrollTop !== scrollTop) {
-      this._popoverHelper.hidePopover();
-      this._scrollTop = scrollTop;
-    }
-    if (nodes) {
-      this._nodes = nodes;
-      this._calculateCanvasSize();
-    }
-    if (eventDividers !== undefined)
-      this._eventDividers = eventDividers;
-    if (this._updateRequestID) {
-      this.element.window().cancelAnimationFrame(this._updateRequestID);
-      delete this._updateRequestID;
-    }
-
-    this._startTime = this._calculator.minimumBoundary();
-    this._endTime = this._calculator.maximumBoundary();
-    this._resetCanvas();
-    this._resetPaths();
-    this._textLayers = [];
-    this._draw();
-  }
-
-  _resetCanvas() {
-    const ratio = window.devicePixelRatio;
-    this._canvas.width = this._offsetWidth * ratio;
-    this._canvas.height = this._offsetHeight * ratio;
-    this._canvas.style.width = this._offsetWidth + 'px';
-    this._canvas.style.height = this._offsetHeight + 'px';
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    super.onResize();
-    this._updateRowHeight();
-    this._calculateCanvasSize();
-    this.scheduleDraw();
-  }
-
-  _calculateCanvasSize() {
-    this._offsetWidth = this.contentElement.offsetWidth - this._rightPadding;
-    this._offsetHeight = this.contentElement.offsetHeight;
-    this._calculator.setDisplayWidth(this._offsetWidth);
-    this._canvasPosition = this._canvas.getBoundingClientRect();
-  }
-
-  /**
-   * @param {number} time
-   * @return {number}
-   */
-  _timeToPosition(time) {
-    const availableWidth = this._offsetWidth - this._leftPadding;
-    const timeToPixel = availableWidth / (this._endTime - this._startTime);
-    return Math.floor(this._leftPadding + (time - this._startTime) * timeToPixel);
-  }
-
-  _didDrawForTest() {
-  }
-
-  _draw() {
-    const useTimingBars = !Common.moduleSetting('networkColorCodeResourceTypes').get() && !this._calculator.startAtZero;
-    const nodes = this._nodes;
-    const context = this._canvas.getContext('2d');
-    context.save();
-    context.scale(window.devicePixelRatio, window.devicePixelRatio);
-    context.translate(0, this._headerHeight);
-    context.rect(0, 0, this._offsetWidth, this._offsetHeight);
-    context.clip();
-    const firstRequestIndex = Math.floor(this._scrollTop / this._rowHeight);
-    const lastRequestIndex =
-        Math.min(nodes.length, firstRequestIndex + Math.ceil(this._offsetHeight / this._rowHeight));
-    for (let i = firstRequestIndex; i < lastRequestIndex; i++) {
-      const rowOffset = this._rowHeight * i;
-      const node = nodes[i];
-      this._decorateRow(context, node, rowOffset - this._scrollTop);
-      let drawNodes = [];
-      if (node.hasChildren() && !node.expanded)
-        drawNodes = /** @type {!Array<!Network.NetworkNode>} */ (node.flatChildren());
-      drawNodes.push(node);
-      for (const drawNode of drawNodes) {
-        if (useTimingBars)
-          this._buildTimingBarLayers(drawNode, rowOffset - this._scrollTop);
-        else
-          this._buildSimplifiedBarLayers(context, drawNode, rowOffset - this._scrollTop);
-      }
-    }
-    this._drawLayers(context);
-
-    context.save();
-    context.fillStyle = UI.themeSupport.patchColorText('#888', UI.ThemeSupport.ColorUsage.Foreground);
-    for (const textData of this._textLayers)
-      context.fillText(textData.text, textData.x, textData.y);
-    context.restore();
-
-    this._drawEventDividers(context);
-    context.restore();
-
-    const freeZoneAtLeft = 75;
-    const freeZoneAtRight = 18;
-    const dividersData = PerfUI.TimelineGrid.calculateGridOffsets(this._calculator);
-    PerfUI.TimelineGrid.drawCanvasGrid(context, dividersData);
-    PerfUI.TimelineGrid.drawCanvasHeaders(
-        context, dividersData, time => this._calculator.formatValue(time, dividersData.precision), this._fontSize,
-        this._headerHeight, freeZoneAtLeft);
-    context.clearRect(this._offsetWidth - freeZoneAtRight, 0, freeZoneAtRight, this._headerHeight);
-    this._didDrawForTest();
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   */
-  _drawLayers(context) {
-    for (const entry of this._pathForStyle) {
-      const style = /** @type {!Network.NetworkWaterfallColumn._LayerStyle} */ (entry[0]);
-      const path = /** @type {!Path2D} */ (entry[1]);
-      context.save();
-      context.beginPath();
-      if (style.lineWidth) {
-        context.lineWidth = style.lineWidth;
-        context.strokeStyle = style.borderColor;
-        context.stroke(path);
-      }
-      if (style.fillStyle) {
-        context.fillStyle = style.fillStyle;
-        context.fill(path);
-      }
-      context.restore();
-    }
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   */
-  _drawEventDividers(context) {
-    context.save();
-    context.lineWidth = 1;
-    for (const color of this._eventDividers.keys()) {
-      context.strokeStyle = color;
-      for (const time of this._eventDividers.get(color)) {
-        context.beginPath();
-        const x = this._timeToPosition(time);
-        context.moveTo(x, 0);
-        context.lineTo(x, this._offsetHeight);
-      }
-      context.stroke();
-    }
-    context.restore();
-  }
-
-  /**
-   * @param {!Network.RequestTimeRangeNames=} type
-   * @return {number}
-   */
-  _getBarHeight(type) {
-    const types = Network.RequestTimeRangeNames;
-    switch (type) {
-      case types.Connecting:
-      case types.SSL:
-      case types.DNS:
-      case types.Proxy:
-      case types.Blocking:
-      case types.Push:
-      case types.Queueing:
-        return 7;
-      default:
-        return 13;
-    }
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {number} borderOffset
-   * @return {!{start: number, mid: number, end: number}}
-   */
-  _getSimplifiedBarRange(request, borderOffset) {
-    const drawWidth = this._offsetWidth - this._leftPadding;
-    const percentages = this._calculator.computeBarGraphPercentages(request);
-    return {
-      start: this._leftPadding + Math.floor((percentages.start / 100) * drawWidth) + borderOffset,
-      mid: this._leftPadding + Math.floor((percentages.middle / 100) * drawWidth) + borderOffset,
-      end: this._leftPadding + Math.floor((percentages.end / 100) * drawWidth) + borderOffset
-    };
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {!Network.NetworkNode} node
-   * @param {number} y
-   */
-  _buildSimplifiedBarLayers(context, node, y) {
-    const request = node.request();
-    if (!request)
-      return;
-    const borderWidth = 1;
-    const borderOffset = borderWidth % 2 === 0 ? 0 : 0.5;
-
-    const ranges = this._getSimplifiedBarRange(request, borderOffset);
-    const height = this._getBarHeight();
-    y += Math.floor(this._rowHeight / 2 - height / 2 + borderWidth) - borderWidth / 2;
-
-    const waitingStyle = this._styleForWaitingResourceType.get(request.resourceType());
-    const waitingPath = this._pathForStyle.get(waitingStyle);
-    waitingPath.rect(ranges.start, y, ranges.mid - ranges.start, height - borderWidth);
-
-    const barWidth = Math.max(2, ranges.end - ranges.mid);
-    const downloadingStyle = this._styleForDownloadingResourceType.get(request.resourceType());
-    const downloadingPath = this._pathForStyle.get(downloadingStyle);
-    downloadingPath.rect(ranges.mid, y, barWidth, height - borderWidth);
-
-    /** @type {?{left: string, right: string, tooltip: (string|undefined)}} */
-    let labels = null;
-    if (node.hovered()) {
-      labels = this._calculator.computeBarGraphLabels(request);
-      const barDotLineLength = 10;
-      const leftLabelWidth = context.measureText(labels.left).width;
-      const rightLabelWidth = context.measureText(labels.right).width;
-      const hoverLinePath = this._pathForStyle.get(this._hoverDetailsStyle);
-
-      if (leftLabelWidth < ranges.mid - ranges.start) {
-        const midBarX = ranges.start + (ranges.mid - ranges.start - leftLabelWidth) / 2;
-        this._textLayers.push({text: labels.left, x: midBarX, y: y + this._fontSize});
-      } else if (barDotLineLength + leftLabelWidth + this._leftPadding < ranges.start) {
-        this._textLayers.push(
-            {text: labels.left, x: ranges.start - leftLabelWidth - barDotLineLength - 1, y: y + this._fontSize});
-        hoverLinePath.moveTo(ranges.start - barDotLineLength, y + Math.floor(height / 2));
-        hoverLinePath.arc(ranges.start, y + Math.floor(height / 2), 2, 0, 2 * Math.PI);
-        hoverLinePath.moveTo(ranges.start - barDotLineLength, y + Math.floor(height / 2));
-        hoverLinePath.lineTo(ranges.start, y + Math.floor(height / 2));
-      }
-
-      const endX = ranges.mid + barWidth + borderOffset;
-      if (rightLabelWidth < endX - ranges.mid) {
-        const midBarX = ranges.mid + (endX - ranges.mid - rightLabelWidth) / 2;
-        this._textLayers.push({text: labels.right, x: midBarX, y: y + this._fontSize});
-      } else if (endX + barDotLineLength + rightLabelWidth < this._offsetWidth - this._leftPadding) {
-        this._textLayers.push({text: labels.right, x: endX + barDotLineLength + 1, y: y + this._fontSize});
-        hoverLinePath.moveTo(endX, y + Math.floor(height / 2));
-        hoverLinePath.arc(endX, y + Math.floor(height / 2), 2, 0, 2 * Math.PI);
-        hoverLinePath.moveTo(endX, y + Math.floor(height / 2));
-        hoverLinePath.lineTo(endX + barDotLineLength, y + Math.floor(height / 2));
-      }
-    }
-
-    if (!this._calculator.startAtZero) {
-      const queueingRange = Network.RequestTimingView.calculateRequestTimeRanges(request, 0)
-                                .find(data => data.name === Network.RequestTimeRangeNames.Total);
-      const leftLabelWidth = labels ? context.measureText(labels.left).width : 0;
-      const leftTextPlacedInBar = leftLabelWidth < ranges.mid - ranges.start;
-      const wiskerTextPadding = 13;
-      const textOffset = (labels && !leftTextPlacedInBar) ? leftLabelWidth + wiskerTextPadding : 0;
-      const queueingStart = this._timeToPosition(queueingRange.start);
-      if (ranges.start - textOffset > queueingStart) {
-        const wiskerPath = this._pathForStyle.get(this._wiskerStyle);
-        wiskerPath.moveTo(queueingStart, y + Math.floor(height / 2));
-        wiskerPath.lineTo(ranges.start - textOffset, y + Math.floor(height / 2));
-
-        // TODO(allada) This needs to be floored.
-        const wiskerHeight = height / 2;
-        wiskerPath.moveTo(queueingStart + borderOffset, y + wiskerHeight / 2);
-        wiskerPath.lineTo(queueingStart + borderOffset, y + height - wiskerHeight / 2 - 1);
-      }
-    }
-  }
-
-  /**
-   * @param {!Network.NetworkNode} node
-   * @param {number} y
-   */
-  _buildTimingBarLayers(node, y) {
-    const request = node.request();
-    if (!request)
-      return;
-    const ranges = Network.RequestTimingView.calculateRequestTimeRanges(request, 0);
-    for (const range of ranges) {
-      if (range.name === Network.RequestTimeRangeNames.Total || range.name === Network.RequestTimeRangeNames.Sending ||
-          range.end - range.start === 0)
-        continue;
-
-      const style = this._styleForTimeRangeName.get(range.name);
-      const path = this._pathForStyle.get(style);
-      const lineWidth = style.lineWidth || 0;
-      const height = this._getBarHeight(range.name);
-      const middleBarY = y + Math.floor(this._rowHeight / 2 - height / 2) + lineWidth / 2;
-      const start = this._timeToPosition(range.start);
-      const end = this._timeToPosition(range.end);
-      path.rect(start, middleBarY, end - start, height - lineWidth);
-    }
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {!Network.NetworkNode} node
-   * @param {number} y
-   */
-  _decorateRow(context, node, y) {
-    context.save();
-    context.beginPath();
-    context.fillStyle = node.backgroundColor();
-    context.rect(0, y, this._offsetWidth, this._rowHeight);
-    context.fill();
-    context.restore();
-  }
-};
-
-/** @typedef {!{fillStyle: (string|undefined), lineWidth: (number|undefined), borderColor: (string|undefined)}} */
-Network.NetworkWaterfallColumn._LayerStyle;
-
-/** @typedef {!{x: number, y: number, text: string}} */
-Network.NetworkWaterfallColumn._TextLayer;
diff --git a/front_end/network/RequestCookiesView.js b/front_end/network/RequestCookiesView.js
deleted file mode 100644
index fee8596..0000000
--- a/front_end/network/RequestCookiesView.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Network.RequestCookiesView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super();
-    this.registerRequiredCSS('network/requestCookiesView.css');
-    this.element.classList.add('request-cookies-view');
-
-    this._request = request;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshCookies, this);
-    this._request.addEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshCookies, this);
-
-    if (!this._gotCookies) {
-      if (!this._emptyWidget) {
-        this._emptyWidget = new UI.EmptyWidget(Common.UIString('This request has no cookies.'));
-        this._emptyWidget.show(this.element);
-      }
-      return;
-    }
-
-    if (!this._cookiesTable)
-      this._buildCookiesTable();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._request.removeEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshCookies, this);
-    this._request.removeEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshCookies, this);
-  }
-
-  get _gotCookies() {
-    return (this._request.requestCookies && this._request.requestCookies.length) ||
-        (this._request.responseCookies && this._request.responseCookies.length);
-  }
-
-  _buildCookiesTable() {
-    this.detachChildWidgets();
-
-    this._cookiesTable = new CookieTable.CookiesTable();
-    this._cookiesTable.setCookieFolders([
-      {folderName: Common.UIString('Request Cookies'), cookies: this._request.requestCookies},
-      {folderName: Common.UIString('Response Cookies'), cookies: this._request.responseCookies}
-    ]);
-    this._cookiesTable.show(this.element);
-  }
-
-  _refreshCookies() {
-    delete this._cookiesTable;
-    if (!this._gotCookies || !this.isShowing())
-      return;
-    this._buildCookiesTable();
-  }
-};
diff --git a/front_end/network/RequestHTMLView.js b/front_end/network/RequestHTMLView.js
deleted file mode 100644
index 866c93e..0000000
--- a/front_end/network/RequestHTMLView.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Network.RequestHTMLView = class extends UI.VBox {
-  /**
-   * @param {string} dataURL
-   */
-  constructor(dataURL) {
-    super(true);
-    this.registerRequiredCSS('network/requestHTMLView.css');
-    this._dataURL = dataURL;
-    this.contentElement.classList.add('html', 'request-view');
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._createIFrame();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this.contentElement.removeChildren();
-  }
-
-  _createIFrame() {
-    // We need to create iframe again each time because contentDocument
-    // is deleted when iframe is removed from its parent.
-    this.contentElement.removeChildren();
-    const iframe = createElement('iframe');
-    iframe.className = 'html-preview-frame';
-    iframe.setAttribute('sandbox', '');  // Forbid to run JavaScript and set unique origin.
-    iframe.setAttribute('src', this._dataURL);
-    this.contentElement.appendChild(iframe);
-  }
-};
diff --git a/front_end/network/RequestHeadersView.js b/front_end/network/RequestHeadersView.js
deleted file mode 100644
index 6d4ad1a..0000000
--- a/front_end/network/RequestHeadersView.js
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) IBM Corp. 2009  All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Network.RequestHeadersView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super();
-    this.registerRequiredCSS('network/requestHeadersView.css');
-    this.element.classList.add('request-headers-view');
-
-    this._request = request;
-    this._decodeRequestParameters = true;
-    this._showRequestHeadersText = false;
-    this._showResponseHeadersText = false;
-
-    /** @type {?UI.TreeElement} */
-    this._highlightedElement = null;
-
-    const root = new UI.TreeOutlineInShadow();
-    root.registerRequiredCSS('network/requestHeadersTree.css');
-    root.element.classList.add('request-headers-tree');
-    root.setFocusable(false);
-    root.makeDense();
-    root.expandTreeElementsWhenArrowing = true;
-    this.element.appendChild(root.element);
-
-    const generalCategory = new Network.RequestHeadersView.Category(root, 'general', Common.UIString('General'));
-    generalCategory.hidden = false;
-    this._urlItem = generalCategory.createLeaf();
-    this._requestMethodItem = generalCategory.createLeaf();
-    this._statusCodeItem = generalCategory.createLeaf();
-    this._remoteAddressItem = generalCategory.createLeaf();
-    this._remoteAddressItem.hidden = true;
-    this._referrerPolicyItem = generalCategory.createLeaf();
-    this._referrerPolicyItem.hidden = true;
-
-    this._responseHeadersCategory = new Network.RequestHeadersView.Category(root, 'responseHeaders', '');
-    this._requestHeadersCategory = new Network.RequestHeadersView.Category(root, 'requestHeaders', '');
-    this._queryStringCategory = new Network.RequestHeadersView.Category(root, 'queryString', '');
-    this._formDataCategory = new Network.RequestHeadersView.Category(root, 'formData', '');
-    this._requestPayloadCategory =
-        new Network.RequestHeadersView.Category(root, 'requestPayload', Common.UIString('Request Payload'));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._clearHighlight();
-    this._request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
-    this._request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
-    this._request.addEventListener(
-        SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
-    this._request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
-
-    this._refreshURL();
-    this._refreshQueryString();
-    this._refreshRequestHeaders();
-    this._refreshResponseHeaders();
-    this._refreshHTTPInformation();
-    this._refreshRemoteAddress();
-    this._refreshReferrerPolicy();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
-    this._request.removeEventListener(
-        SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
-    this._request.removeEventListener(
-        SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
-    this._request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   * @return {!DocumentFragment}
-   */
-  _formatHeader(name, value) {
-    const fragment = createDocumentFragment();
-    fragment.createChild('div', 'header-name').textContent = name + ': ';
-    fragment.createChild('span', 'header-separator');
-    fragment.createChild('div', 'header-value source-code').textContent = value;
-
-    return fragment;
-  }
-
-  /**
-   * @param {string} value
-   * @param {string} className
-   * @param {boolean} decodeParameters
-   * @return {!Element}
-   */
-  _formatParameter(value, className, decodeParameters) {
-    let errorDecoding = false;
-
-    if (decodeParameters) {
-      value = value.replace(/\+/g, ' ');
-      if (value.indexOf('%') >= 0) {
-        try {
-          value = decodeURIComponent(value);
-        } catch (e) {
-          errorDecoding = true;
-        }
-      }
-    }
-    const div = createElementWithClass('div', className);
-    if (value === '')
-      div.classList.add('empty-value');
-    if (errorDecoding)
-      div.createChild('span', 'header-decode-error').textContent = Common.UIString('(unable to decode value)');
-    else
-      div.textContent = value;
-    return div;
-  }
-
-  _refreshURL() {
-    this._urlItem.title = this._formatHeader(Common.UIString('Request URL'), this._request.url());
-  }
-
-  _refreshQueryString() {
-    const queryString = this._request.queryString();
-    const queryParameters = this._request.queryParameters;
-    this._queryStringCategory.hidden = !queryParameters;
-    if (queryParameters) {
-      this._refreshParams(
-          Common.UIString('Query String Parameters'), queryParameters, queryString, this._queryStringCategory);
-    }
-  }
-
-  async _refreshFormData() {
-    this._formDataCategory.hidden = true;
-    this._requestPayloadCategory.hidden = true;
-
-    const formData = await this._request.requestFormData();
-    if (!formData)
-      return;
-
-    const formParameters = await this._request.formParameters();
-    if (formParameters) {
-      this._formDataCategory.hidden = false;
-      this._refreshParams(Common.UIString('Form Data'), formParameters, formData, this._formDataCategory);
-    } else {
-      this._requestPayloadCategory.hidden = false;
-      try {
-        const json = JSON.parse(formData);
-        this._refreshRequestJSONPayload(json, formData);
-      } catch (e) {
-        this._populateTreeElementWithSourceText(this._requestPayloadCategory, formData);
-      }
-    }
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeElement
-   * @param {?string} sourceText
-   */
-  _populateTreeElementWithSourceText(treeElement, sourceText) {
-    const max_len = 3000;
-    const text = (sourceText || '').trim();
-    const trim = text.length > max_len;
-
-    const sourceTextElement = createElementWithClass('span', 'header-value source-code');
-    sourceTextElement.textContent = trim ? text.substr(0, max_len) : text;
-
-    const sourceTreeElement = new UI.TreeElement(sourceTextElement);
-    sourceTreeElement.selectable = false;
-    treeElement.removeChildren();
-    treeElement.appendChild(sourceTreeElement);
-    if (!trim)
-      return;
-
-    const showMoreButton = createElementWithClass('button', 'request-headers-show-more-button');
-    showMoreButton.textContent = Common.UIString('Show more');
-    showMoreButton.addEventListener('click', () => {
-      showMoreButton.remove();
-      sourceTextElement.textContent = text;
-    });
-    sourceTextElement.appendChild(showMoreButton);
-  }
-
-  /**
-   * @param {string} title
-   * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
-   * @param {?string} sourceText
-   * @param {!UI.TreeElement} paramsTreeElement
-   */
-  _refreshParams(title, params, sourceText, paramsTreeElement) {
-    paramsTreeElement.removeChildren();
-
-    paramsTreeElement.listItemElement.removeChildren();
-    paramsTreeElement.listItemElement.createTextChild(title);
-
-    const headerCount = createElementWithClass('span', 'header-count');
-    headerCount.textContent = Common.UIString('\u00A0(%d)', params.length);
-    paramsTreeElement.listItemElement.appendChild(headerCount);
-
-    /**
-     * @param {!Event} event
-     * @this {Network.RequestHeadersView}
-     */
-    function toggleViewSource(event) {
-      paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol] =
-          !paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol];
-      this._refreshParams(title, params, sourceText, paramsTreeElement);
-      event.consume();
-    }
-
-    paramsTreeElement.listItemElement.appendChild(this._createViewSourceToggle(
-        paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol], toggleViewSource.bind(this)));
-
-    if (paramsTreeElement[Network.RequestHeadersView._viewSourceSymbol]) {
-      this._populateTreeElementWithSourceText(paramsTreeElement, sourceText);
-      return;
-    }
-
-    const toggleTitle =
-        this._decodeRequestParameters ? Common.UIString('view URL encoded') : Common.UIString('view decoded');
-    const toggleButton = this._createToggleButton(toggleTitle);
-    toggleButton.addEventListener('click', this._toggleURLDecoding.bind(this), false);
-    paramsTreeElement.listItemElement.appendChild(toggleButton);
-
-    for (let i = 0; i < params.length; ++i) {
-      const paramNameValue = createDocumentFragment();
-      if (params[i].name !== '') {
-        const name = this._formatParameter(params[i].name + ': ', 'header-name', this._decodeRequestParameters);
-        const value = this._formatParameter(params[i].value, 'header-value source-code', this._decodeRequestParameters);
-        paramNameValue.appendChild(name);
-        paramNameValue.createChild('span', 'header-separator');
-        paramNameValue.appendChild(value);
-      } else {
-        paramNameValue.appendChild(
-            this._formatParameter(Common.UIString('(empty)'), 'empty-request-header', this._decodeRequestParameters));
-      }
-
-      const paramTreeElement = new UI.TreeElement(paramNameValue);
-      paramTreeElement.selectable = false;
-      paramsTreeElement.appendChild(paramTreeElement);
-    }
-  }
-
-  /**
-   * @param {*} parsedObject
-   * @param {string} sourceText
-   */
-  _refreshRequestJSONPayload(parsedObject, sourceText) {
-    const treeElement = this._requestPayloadCategory;
-    treeElement.removeChildren();
-
-    const listItem = this._requestPayloadCategory.listItemElement;
-    listItem.removeChildren();
-    listItem.createTextChild(this._requestPayloadCategory.title);
-
-    /**
-     * @param {!Event} event
-     * @this {Network.RequestHeadersView}
-     */
-    function toggleViewSource(event) {
-      treeElement[Network.RequestHeadersView._viewSourceSymbol] =
-          !treeElement[Network.RequestHeadersView._viewSourceSymbol];
-      this._refreshRequestJSONPayload(parsedObject, sourceText);
-      event.consume();
-    }
-
-    listItem.appendChild(this._createViewSourceToggle(
-        treeElement[Network.RequestHeadersView._viewSourceSymbol], toggleViewSource.bind(this)));
-    if (treeElement[Network.RequestHeadersView._viewSourceSymbol]) {
-      this._populateTreeElementWithSourceText(this._requestPayloadCategory, sourceText);
-    } else {
-      const object = SDK.RemoteObject.fromLocalObject(parsedObject);
-      const section = new ObjectUI.ObjectPropertiesSection(object, object.description);
-      section.expand();
-      section.editable = false;
-      treeElement.appendChild(new UI.TreeElement(section.element));
-    }
-  }
-
-  /**
-   * @param {boolean} viewSource
-   * @param {function(!Event)} handler
-   * @return {!Element}
-   */
-  _createViewSourceToggle(viewSource, handler) {
-    const viewSourceToggleTitle = viewSource ? Common.UIString('view parsed') : Common.UIString('view source');
-    const viewSourceToggleButton = this._createToggleButton(viewSourceToggleTitle);
-    viewSourceToggleButton.addEventListener('click', handler, false);
-    return viewSourceToggleButton;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _toggleURLDecoding(event) {
-    this._decodeRequestParameters = !this._decodeRequestParameters;
-    this._refreshQueryString();
-    this._refreshFormData();
-    event.consume();
-  }
-
-  _refreshRequestHeaders() {
-    const treeElement = this._requestHeadersCategory;
-    const headers = this._request.requestHeaders().slice();
-    headers.sort(function(a, b) {
-      return a.name.toLowerCase().compareTo(b.name.toLowerCase());
-    });
-    const headersText = this._request.requestHeadersText();
-
-    if (this._showRequestHeadersText && headersText)
-      this._refreshHeadersText(Common.UIString('Request Headers'), headers.length, headersText, treeElement);
-    else
-      this._refreshHeaders(Common.UIString('Request Headers'), headers, treeElement, headersText === undefined);
-
-    if (headersText) {
-      const toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
-      toggleButton.addEventListener('click', this._toggleRequestHeadersText.bind(this), false);
-      treeElement.listItemElement.appendChild(toggleButton);
-    }
-
-    this._refreshFormData();
-  }
-
-  _refreshResponseHeaders() {
-    const treeElement = this._responseHeadersCategory;
-    const headers = this._request.sortedResponseHeaders.slice();
-    const headersText = this._request.responseHeadersText;
-
-    if (this._showResponseHeadersText)
-      this._refreshHeadersText(Common.UIString('Response Headers'), headers.length, headersText, treeElement);
-    else
-      this._refreshHeaders(Common.UIString('Response Headers'), headers, treeElement);
-
-    if (headersText) {
-      const toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
-      toggleButton.addEventListener('click', this._toggleResponseHeadersText.bind(this), false);
-      treeElement.listItemElement.appendChild(toggleButton);
-    }
-  }
-
-  _refreshHTTPInformation() {
-    const requestMethodElement = this._requestMethodItem;
-    requestMethodElement.hidden = !this._request.statusCode;
-    const statusCodeElement = this._statusCodeItem;
-    statusCodeElement.hidden = !this._request.statusCode;
-
-    if (this._request.statusCode) {
-      const statusCodeFragment = createDocumentFragment();
-      statusCodeFragment.createChild('div', 'header-name').textContent = Common.UIString('Status Code') + ': ';
-      statusCodeFragment.createChild('span', 'header-separator');
-
-      const statusCodeImage = statusCodeFragment.createChild('label', 'resource-status-image', 'dt-icon-label');
-      statusCodeImage.title = this._request.statusCode + ' ' + this._request.statusText;
-
-      if (this._request.statusCode < 300 || this._request.statusCode === 304)
-        statusCodeImage.type = 'smallicon-green-ball';
-      else if (this._request.statusCode < 400)
-        statusCodeImage.type = 'smallicon-orange-ball';
-      else
-        statusCodeImage.type = 'smallicon-red-ball';
-
-      requestMethodElement.title = this._formatHeader(Common.UIString('Request Method'), this._request.requestMethod);
-
-      const statusTextElement = statusCodeFragment.createChild('div', 'header-value source-code');
-      let statusText = this._request.statusCode + ' ' + this._request.statusText;
-      if (this._request.fetchedViaServiceWorker) {
-        statusText += ' ' + Common.UIString('(from ServiceWorker)');
-        statusTextElement.classList.add('status-from-cache');
-      } else if (this._request.cached()) {
-        if (this._request.cachedInMemory())
-          statusText += ' ' + Common.UIString('(from memory cache)');
-        else
-          statusText += ' ' + Common.UIString('(from disk cache)');
-        statusTextElement.classList.add('status-from-cache');
-      }
-      statusTextElement.textContent = statusText;
-
-      statusCodeElement.title = statusCodeFragment;
-    }
-  }
-
-  /**
-   * @param {string} title
-   * @param {!UI.TreeElement} headersTreeElement
-   * @param {number} headersLength
-   */
-  _refreshHeadersTitle(title, headersTreeElement, headersLength) {
-    headersTreeElement.listItemElement.removeChildren();
-    headersTreeElement.listItemElement.createTextChild(title);
-
-    const headerCount = Common.UIString('\u00A0(%d)', headersLength);
-    headersTreeElement.listItemElement.createChild('span', 'header-count').textContent = headerCount;
-  }
-
-  /**
-   * @param {string} title
-   * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
-   * @param {!UI.TreeElement} headersTreeElement
-   * @param {boolean=} provisionalHeaders
-   */
-  _refreshHeaders(title, headers, headersTreeElement, provisionalHeaders) {
-    headersTreeElement.removeChildren();
-
-    const length = headers.length;
-    this._refreshHeadersTitle(title, headersTreeElement, length);
-
-    if (provisionalHeaders) {
-      const cautionText = Common.UIString('Provisional headers are shown');
-      const cautionFragment = createDocumentFragment();
-      cautionFragment.createChild('label', '', 'dt-icon-label').type = 'smallicon-warning';
-      cautionFragment.createChild('div', 'caution').textContent = cautionText;
-      const cautionTreeElement = new UI.TreeElement(cautionFragment);
-      cautionTreeElement.selectable = false;
-      headersTreeElement.appendChild(cautionTreeElement);
-    }
-
-    headersTreeElement.hidden = !length && !provisionalHeaders;
-    for (let i = 0; i < length; ++i) {
-      const headerTreeElement = new UI.TreeElement(this._formatHeader(headers[i].name, headers[i].value));
-      headerTreeElement.selectable = false;
-      headersTreeElement.appendChild(headerTreeElement);
-      headerTreeElement[Network.RequestHeadersView._headerNameSymbol] = headers[i].name;
-    }
-  }
-
-  /**
-   * @param {string} title
-   * @param {number} count
-   * @param {string} headersText
-   * @param {!UI.TreeElement} headersTreeElement
-   */
-  _refreshHeadersText(title, count, headersText, headersTreeElement) {
-    this._populateTreeElementWithSourceText(headersTreeElement, headersText);
-    this._refreshHeadersTitle(title, headersTreeElement, count);
-  }
-
-  _refreshRemoteAddress() {
-    const remoteAddress = this._request.remoteAddress();
-    const treeElement = this._remoteAddressItem;
-    treeElement.hidden = !remoteAddress;
-    if (remoteAddress)
-      treeElement.title = this._formatHeader(Common.UIString('Remote Address'), remoteAddress);
-  }
-
-  _refreshReferrerPolicy() {
-    const referrerPolicy = this._request.referrerPolicy();
-    const treeElement = this._referrerPolicyItem;
-    treeElement.hidden = !referrerPolicy;
-    if (referrerPolicy)
-      treeElement.title = this._formatHeader(Common.UIString('Referrer Policy'), referrerPolicy);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _toggleRequestHeadersText(event) {
-    this._showRequestHeadersText = !this._showRequestHeadersText;
-    this._refreshRequestHeaders();
-    event.consume();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _toggleResponseHeadersText(event) {
-    this._showResponseHeadersText = !this._showResponseHeadersText;
-    this._refreshResponseHeaders();
-    event.consume();
-  }
-
-  /**
-   * @param {string} title
-   * @return {!Element}
-   */
-  _createToggleButton(title) {
-    const button = createElementWithClass('span', 'header-toggle');
-    button.textContent = title;
-    return button;
-  }
-
-  /**
-   * @param {boolean} isHeadersTextShown
-   * @return {!Element}
-   */
-  _createHeadersToggleButton(isHeadersTextShown) {
-    const toggleTitle = isHeadersTextShown ? Common.UIString('view parsed') : Common.UIString('view source');
-    return this._createToggleButton(toggleTitle);
-  }
-
-  _clearHighlight() {
-    if (this._highlightedElement)
-      this._highlightedElement.listItemElement.classList.remove('header-highlight');
-    this._highlightedElement = null;
-  }
-
-
-  /**
-   * @param {?UI.TreeElement} category
-   * @param {string} name
-   */
-  _revealAndHighlight(category, name) {
-    this._clearHighlight();
-    for (const element of category.children()) {
-      if (element[Network.RequestHeadersView._headerNameSymbol] !== name)
-        continue;
-      this._highlightedElement = element;
-      element.reveal();
-      element.listItemElement.classList.add('header-highlight');
-      return;
-    }
-  }
-
-  /**
-   * @param {string} header
-   */
-  revealRequestHeader(header) {
-    this._revealAndHighlight(this._requestHeadersCategory, header);
-  }
-
-  /**
-   * @param {string} header
-   */
-  revealResponseHeader(header) {
-    this._revealAndHighlight(this._responseHeadersCategory, header);
-  }
-};
-
-Network.RequestHeadersView._headerNameSymbol = Symbol('HeaderName');
-Network.RequestHeadersView._viewSourceSymbol = Symbol('ViewSource');
-
-/**
- * @unrestricted
- */
-Network.RequestHeadersView.Category = class extends UI.TreeElement {
-  /**
-   * @param {!UI.TreeOutline} root
-   * @param {string} name
-   * @param {string=} title
-   */
-  constructor(root, name, title) {
-    super(title || '', true);
-    this.selectable = false;
-    this.toggleOnClick = true;
-    this.hidden = true;
-    this._expandedSetting = Common.settings.createSetting('request-info-' + name + '-category-expanded', true);
-    this.expanded = this._expandedSetting.get();
-    root.appendChild(this);
-  }
-
-  /**
-   * @return {!UI.TreeElement}
-   */
-  createLeaf() {
-    const leaf = new UI.TreeElement();
-    leaf.selectable = false;
-    this.appendChild(leaf);
-    return leaf;
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    this._expandedSetting.set(true);
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    this._expandedSetting.set(false);
-  }
-};
diff --git a/front_end/network/RequestPreviewView.js b/front_end/network/RequestPreviewView.js
deleted file mode 100644
index d75b1e9..0000000
--- a/front_end/network/RequestPreviewView.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Network.RequestPreviewView = class extends Network.RequestResponseView {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super(request);
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise<!UI.Widget>}
-   */
-  async showPreview() {
-    const view = await super.showPreview();
-    if (!(view instanceof UI.SimpleView))
-      return view;
-    const toolbar = new UI.Toolbar('network-item-preview-toolbar', this.element);
-    for (const item of view.syncToolbarItems())
-      toolbar.appendToolbarItem(item);
-    return view;
-  }
-
-  /**
-   * @return {!Promise<?UI.Widget>}
-   */
-  async _htmlPreview() {
-    const contentData = await this.request.contentData();
-    if (contentData.error)
-      return new UI.EmptyWidget(Common.UIString('Failed to load response data'));
-
-    const whitelist = new Set(['text/html', 'text/plain', 'application/xhtml+xml']);
-    if (!whitelist.has(this.request.mimeType))
-      return null;
-
-    // http://crbug.com/767393 - DevTools should recognize JSON regardless of the content type
-    const jsonView = await SourceFrame.JSONView.createView(contentData.content);
-    if (jsonView)
-      return jsonView;
-
-    const dataURL = Common.ContentProvider.contentAsDataURL(
-        contentData.content, this.request.mimeType, contentData.encoded, contentData.encoded ? 'utf-8' : null);
-    return dataURL ? new Network.RequestHTMLView(dataURL) : null;
-  }
-
-  /**
-   * @override
-   * @protected
-   * @return {!Promise<!UI.Widget>}
-   */
-  async createPreview() {
-    const htmlErrorPreview = await this._htmlPreview();
-    if (htmlErrorPreview)
-      return htmlErrorPreview;
-
-    // Try provider before the source view - so JSON and XML are not shown in generic editor
-    const provided = await SourceFrame.PreviewFactory.createPreview(this.request, this.request.mimeType);
-    if (provided)
-      return provided;
-
-    const sourceView = await Network.RequestResponseView.sourceViewForRequest(this.request);
-    if (sourceView)
-      return sourceView;
-    return new UI.EmptyWidget(Common.UIString('Preview not available'));
-  }
-};
diff --git a/front_end/network/RequestResponseView.js b/front_end/network/RequestResponseView.js
deleted file mode 100644
index ff36c80..0000000
--- a/front_end/network/RequestResponseView.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Network.RequestResponseView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super();
-    this.element.classList.add('request-view');
-    /** @protected */
-    this.request = request;
-    /** @type {?Promise<!UI.Widget>} */
-    this._contentViewPromise = null;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {!SDK.NetworkRequest.ContentData} contentData
-   * @return {boolean}
-   */
-  static _hasTextContent(request, contentData) {
-    const mimeType = request.mimeType;
-    let resourceType = Common.ResourceType.fromMimeType(mimeType);
-    if (resourceType === Common.resourceTypes.Other)
-      resourceType = request.contentType();
-    if (resourceType === Common.resourceTypes.Image)
-      return mimeType.startsWith('image/svg');
-    if (resourceType.isTextType())
-      return true;
-    if (contentData.error)
-      return false;
-    if (resourceType === Common.resourceTypes.Other)
-      return !!contentData.content && !contentData.encoded;
-    return false;
-  }
-
-  /**
-   * @protected
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<?UI.SearchableView>}
-   */
-  static async sourceViewForRequest(request) {
-    let sourceView = request[Network.RequestResponseView._sourceViewSymbol];
-    if (sourceView !== undefined)
-      return sourceView;
-
-    const contentData = await request.contentData();
-    if (!Network.RequestResponseView._hasTextContent(request, contentData)) {
-      request[Network.RequestResponseView._sourceViewSymbol] = null;
-      return null;
-    }
-
-    const contentProvider = new Network.DecodingContentProvider(request);
-    const highlighterType = request.resourceType().canonicalMimeType() || request.mimeType;
-    sourceView = SourceFrame.ResourceSourceFrame.createSearchableView(contentProvider, highlighterType);
-    request[Network.RequestResponseView._sourceViewSymbol] = sourceView;
-    return sourceView;
-  }
-
-  /**
-   * @override
-   * @final
-   */
-  wasShown() {
-    this._doShowPreview();
-  }
-
-  /**
-   * @return {!Promise<!UI.Widget>}
-   */
-  _doShowPreview() {
-    if (!this._contentViewPromise)
-      this._contentViewPromise = this.showPreview();
-    return this._contentViewPromise;
-  }
-
-  /**
-   * @protected
-   * @return {!Promise<!UI.Widget>}
-   */
-  async showPreview() {
-    const responseView = await this.createPreview();
-    responseView.show(this.element);
-    return responseView;
-  }
-
-  /**
-   * @protected
-   * @return {!Promise<!UI.Widget>}
-   */
-  async createPreview() {
-    const contentData = await this.request.contentData();
-    const sourceView = await Network.RequestResponseView.sourceViewForRequest(this.request);
-    if ((!contentData.content || !sourceView) && !contentData.error)
-      return new UI.EmptyWidget(Common.UIString('This request has no response data available.'));
-    if (contentData.content && sourceView)
-      return sourceView;
-    return new UI.EmptyWidget(Common.UIString('Failed to load response data'));
-  }
-
-  /**
-   * @param {number} line
-   */
-  async revealLine(line) {
-    const view = await this._doShowPreview();
-    if (view instanceof SourceFrame.ResourceSourceFrame.SearchableContainer)
-      view.revealPosition(line);
-  }
-};
-
-Network.RequestResponseView._sourceViewSymbol = Symbol('RequestResponseSourceView');
-
-/**
- * @implements {Common.ContentProvider}
- */
-Network.DecodingContentProvider = class {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    this._request = request;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._request.contentURL();
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._request.resourceType();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  async requestContent() {
-    const contentData = await this._request.contentData();
-    return contentData.encoded ? window.atob(contentData.content || '') : contentData.content;
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInContent(query, caseSensitive, isRegex) {
-    return this._request.searchInContent(query, caseSensitive, isRegex);
-  }
-};
diff --git a/front_end/network/RequestTimingView.js b/front_end/network/RequestTimingView.js
deleted file mode 100644
index 9bec34b..0000000
--- a/front_end/network/RequestTimingView.js
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Network.RequestTimingView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {!Network.NetworkTimeCalculator} calculator
-   */
-  constructor(request, calculator) {
-    super();
-    this.element.classList.add('resource-timing-view');
-
-    this._request = request;
-    this._calculator = calculator;
-  }
-
-  /**
-   * @param {!Network.RequestTimeRangeNames} name
-   * @return {string}
-   */
-  static _timeRangeTitle(name) {
-    switch (name) {
-      case Network.RequestTimeRangeNames.Push:
-        return Common.UIString('Receiving Push');
-      case Network.RequestTimeRangeNames.Queueing:
-        return Common.UIString('Queueing');
-      case Network.RequestTimeRangeNames.Blocking:
-        return Common.UIString('Stalled');
-      case Network.RequestTimeRangeNames.Connecting:
-        return Common.UIString('Initial connection');
-      case Network.RequestTimeRangeNames.DNS:
-        return Common.UIString('DNS Lookup');
-      case Network.RequestTimeRangeNames.Proxy:
-        return Common.UIString('Proxy negotiation');
-      case Network.RequestTimeRangeNames.ReceivingPush:
-        return Common.UIString('Reading Push');
-      case Network.RequestTimeRangeNames.Receiving:
-        return Common.UIString('Content Download');
-      case Network.RequestTimeRangeNames.Sending:
-        return Common.UIString('Request sent');
-      case Network.RequestTimeRangeNames.ServiceWorker:
-        return Common.UIString('Request to ServiceWorker');
-      case Network.RequestTimeRangeNames.ServiceWorkerPreparation:
-        return Common.UIString('ServiceWorker Preparation');
-      case Network.RequestTimeRangeNames.SSL:
-        return Common.UIString('SSL');
-      case Network.RequestTimeRangeNames.Total:
-        return Common.UIString('Total');
-      case Network.RequestTimeRangeNames.Waiting:
-        return Common.UIString('Waiting (TTFB)');
-      default:
-        return Common.UIString(name);
-    }
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {number} navigationStart
-   * @return {!Array.<!Network.RequestTimeRange>}
-   */
-  static calculateRequestTimeRanges(request, navigationStart) {
-    const result = [];
-    /**
-     * @param {!Network.RequestTimeRangeNames} name
-     * @param {number} start
-     * @param {number} end
-     */
-    function addRange(name, start, end) {
-      if (start < Number.MAX_VALUE && start <= end)
-        result.push({name: name, start: start, end: end});
-    }
-
-    /**
-     * @param {!Array.<number>} numbers
-     * @return {number|undefined}
-     */
-    function firstPositive(numbers) {
-      for (let i = 0; i < numbers.length; ++i) {
-        if (numbers[i] > 0)
-          return numbers[i];
-      }
-      return undefined;
-    }
-
-    /**
-     * @param {!Network.RequestTimeRangeNames} name
-     * @param {number} start
-     * @param {number} end
-     */
-    function addOffsetRange(name, start, end) {
-      if (start >= 0 && end >= 0)
-        addRange(name, startTime + (start / 1000), startTime + (end / 1000));
-    }
-
-    const timing = request.timing;
-    if (!timing) {
-      const start = request.issueTime() !== -1 ? request.issueTime() : request.startTime !== -1 ? request.startTime : 0;
-      const middle = (request.responseReceivedTime === -1) ? Number.MAX_VALUE : request.responseReceivedTime;
-      const end = (request.endTime === -1) ? Number.MAX_VALUE : request.endTime;
-      addRange(Network.RequestTimeRangeNames.Total, start, end);
-      addRange(Network.RequestTimeRangeNames.Blocking, start, middle);
-      addRange(Network.RequestTimeRangeNames.Receiving, middle, end);
-      return result;
-    }
-
-    const issueTime = request.issueTime();
-    const startTime = timing.requestTime;
-    const endTime = firstPositive([request.endTime, request.responseReceivedTime]) || startTime;
-
-    addRange(Network.RequestTimeRangeNames.Total, issueTime < startTime ? issueTime : startTime, endTime);
-    if (timing.pushStart) {
-      const pushEnd = timing.pushEnd || endTime;
-      // Only show the part of push that happened after the navigation/reload.
-      // Pushes that happened on the same connection before we started main request will not be shown.
-      if (pushEnd > navigationStart)
-        addRange(Network.RequestTimeRangeNames.Push, Math.max(timing.pushStart, navigationStart), pushEnd);
-    }
-    if (issueTime < startTime)
-      addRange(Network.RequestTimeRangeNames.Queueing, issueTime, startTime);
-
-    const responseReceived = (request.responseReceivedTime - startTime) * 1000;
-    if (request.fetchedViaServiceWorker) {
-      addOffsetRange(Network.RequestTimeRangeNames.Blocking, 0, timing.workerStart);
-      addOffsetRange(Network.RequestTimeRangeNames.ServiceWorkerPreparation, timing.workerStart, timing.workerReady);
-      addOffsetRange(Network.RequestTimeRangeNames.ServiceWorker, timing.workerReady, timing.sendEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.Waiting, timing.sendEnd, responseReceived);
-    } else if (!timing.pushStart) {
-      const blockingEnd =
-          firstPositive([timing.dnsStart, timing.connectStart, timing.sendStart, responseReceived]) || 0;
-      addOffsetRange(Network.RequestTimeRangeNames.Blocking, 0, blockingEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.Proxy, timing.proxyStart, timing.proxyEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.DNS, timing.dnsStart, timing.dnsEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.Connecting, timing.connectStart, timing.connectEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.SSL, timing.sslStart, timing.sslEnd);
-      addOffsetRange(Network.RequestTimeRangeNames.Sending, timing.sendStart, timing.sendEnd);
-      addOffsetRange(
-          Network.RequestTimeRangeNames.Waiting,
-          Math.max(timing.sendEnd, timing.connectEnd, timing.dnsEnd, timing.proxyEnd, blockingEnd), responseReceived);
-    }
-
-    if (request.endTime !== -1) {
-      addRange(
-          timing.pushStart ? Network.RequestTimeRangeNames.ReceivingPush : Network.RequestTimeRangeNames.Receiving,
-          request.responseReceivedTime, endTime);
-    }
-
-    return result;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {!Network.NetworkTimeCalculator} calculator
-   * @return {!Element}
-   */
-  static createTimingTable(request, calculator) {
-    const tableElement = createElementWithClass('table', 'network-timing-table');
-    UI.appendStyle(tableElement, 'network/networkTimingTable.css');
-    const colgroup = tableElement.createChild('colgroup');
-    colgroup.createChild('col', 'labels');
-    colgroup.createChild('col', 'bars');
-    colgroup.createChild('col', 'duration');
-
-    const timeRanges = Network.RequestTimingView.calculateRequestTimeRanges(request, calculator.minimumBoundary());
-    const startTime = timeRanges.map(r => r.start).reduce((a, b) => Math.min(a, b));
-    const endTime = timeRanges.map(r => r.end).reduce((a, b) => Math.max(a, b));
-    const scale = 100 / (endTime - startTime);
-
-    let connectionHeader;
-    let dataHeader;
-    let queueingHeader;
-    let totalDuration = 0;
-
-    const startTimeHeader = tableElement.createChild('thead', 'network-timing-start');
-    const queuedCell = startTimeHeader.createChild('tr').createChild('td');
-    const startedCell = startTimeHeader.createChild('tr').createChild('td');
-    queuedCell.colSpan = startedCell.colSpan = 2;
-    queuedCell.createTextChild(Common.UIString('Queued at %s', calculator.formatValue(request.issueTime(), 2)));
-    startedCell.createTextChild(Common.UIString('Started at %s', calculator.formatValue(request.startTime, 2)));
-
-    let right;
-    for (let i = 0; i < timeRanges.length; ++i) {
-      const range = timeRanges[i];
-      const rangeName = range.name;
-      if (rangeName === Network.RequestTimeRangeNames.Total) {
-        totalDuration = range.end - range.start;
-        continue;
-      }
-      if (rangeName === Network.RequestTimeRangeNames.Push) {
-        createHeader(Common.UIString('Server Push'));
-      } else if (rangeName === Network.RequestTimeRangeNames.Queueing) {
-        queueingHeader = tableElement.createChild('tr', 'network-timing-table-header');
-        queueingHeader.createChild('td').createTextChild(Common.UIString('Resource Scheduling'));
-        queueingHeader.createChild('td').createTextChild('');
-        queueingHeader.createChild('td').createTextChild(Common.UIString('TIME'));
-      } else if (Network.RequestTimingView.ConnectionSetupRangeNames.has(rangeName)) {
-        if (!connectionHeader)
-          connectionHeader = createHeader(Common.UIString('Connection Start'));
-      } else {
-        if (!dataHeader)
-          dataHeader = createHeader(Common.UIString('Request/Response'));
-      }
-
-      const left = (scale * (range.start - startTime));
-      right = (scale * (endTime - range.end));
-      const duration = range.end - range.start;
-
-      const tr = tableElement.createChild('tr');
-      tr.createChild('td').createTextChild(Network.RequestTimingView._timeRangeTitle(rangeName));
-
-      const row = tr.createChild('td').createChild('div', 'network-timing-row');
-      const bar = row.createChild('span', 'network-timing-bar ' + rangeName);
-      bar.style.left = left + '%';
-      bar.style.right = right + '%';
-      bar.textContent = '\u200B';  // Important for 0-time items to have 0 width.
-      const label = tr.createChild('td').createChild('div', 'network-timing-bar-title');
-      label.textContent = Number.secondsToString(duration, true);
-    }
-
-    if (!request.finished) {
-      const cell = tableElement.createChild('tr').createChild('td', 'caution');
-      cell.colSpan = 3;
-      cell.createTextChild(Common.UIString('CAUTION: request is not finished yet!'));
-    }
-
-    const footer = tableElement.createChild('tr', 'network-timing-footer');
-    const note = footer.createChild('td');
-    note.colSpan = 1;
-    note.appendChild(
-        UI.createDocumentationLink('network-performance/reference#timing-explanation', Common.UIString('Explanation')));
-    footer.createChild('td');
-    footer.createChild('td').createTextChild(Number.secondsToString(totalDuration, true));
-
-    const serverTimings = request.serverTimings;
-    if (!serverTimings)
-      return tableElement;
-
-    const lastTimingRightEdge = right === undefined ? 100 : right;
-
-    const breakElement = tableElement.createChild('tr', 'network-timing-table-header').createChild('td');
-    breakElement.colSpan = 3;
-    breakElement.createChild('hr', 'break');
-
-    const serverHeader = tableElement.createChild('tr', 'network-timing-table-header');
-    serverHeader.createChild('td').createTextChild(Common.UIString('Server Timing'));
-    serverHeader.createChild('td');
-    serverHeader.createChild('td').createTextChild(Common.UIString('TIME'));
-
-    serverTimings.filter(item => item.metric.toLowerCase() !== 'total')
-        .forEach(item => addTiming(item, lastTimingRightEdge));
-    serverTimings.filter(item => item.metric.toLowerCase() === 'total')
-        .forEach(item => addTiming(item, lastTimingRightEdge));
-
-    return tableElement;
-
-    /**
-     * @param {!SDK.ServerTiming} serverTiming
-     * @param {number} right
-     */
-    function addTiming(serverTiming, right) {
-      const colorGenerator = new Common.Color.Generator({min: 0, max: 360, count: 36}, {min: 50, max: 80}, 80);
-      const isTotal = serverTiming.metric.toLowerCase() === 'total';
-      const tr = tableElement.createChild('tr', isTotal ? 'network-timing-footer' : '');
-      const metric = tr.createChild('td', 'network-timing-metric');
-      metric.createTextChild(serverTiming.description || serverTiming.metric);
-      const row = tr.createChild('td').createChild('div', 'network-timing-row');
-
-      if (serverTiming.value === null)
-        return;
-      const left = scale * (endTime - startTime - (serverTiming.value / 1000));
-      if (left >= 0) {  // don't chart values too big or too small
-        const bar = row.createChild('span', 'network-timing-bar server-timing');
-        bar.style.left = left + '%';
-        bar.style.right = right + '%';
-        bar.textContent = '\u200B';  // Important for 0-time items to have 0 width.
-        if (!isTotal)
-          bar.style.backgroundColor = colorGenerator.colorForID(serverTiming.metric);
-      }
-      const label = tr.createChild('td').createChild('div', 'network-timing-bar-title');
-      label.textContent = Number.millisToString(serverTiming.value, true);
-    }
-
-    /**
-     * @param {string} title
-     * @return {!Element}
-     */
-    function createHeader(title) {
-      const dataHeader = tableElement.createChild('tr', 'network-timing-table-header');
-      dataHeader.createChild('td').createTextChild(title);
-      dataHeader.createChild('td').createTextChild('');
-      dataHeader.createChild('td').createTextChild(Common.UIString('TIME'));
-      return dataHeader;
-    }
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._request.addEventListener(SDK.NetworkRequest.Events.TimingChanged, this._refresh, this);
-    this._request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refresh, this);
-    this._calculator.addEventListener(Network.NetworkTimeCalculator.Events.BoundariesChanged, this._refresh, this);
-    this._refresh();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._request.removeEventListener(SDK.NetworkRequest.Events.TimingChanged, this._refresh, this);
-    this._request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refresh, this);
-    this._calculator.removeEventListener(Network.NetworkTimeCalculator.Events.BoundariesChanged, this._refresh, this);
-  }
-
-  _refresh() {
-    if (this._tableElement)
-      this._tableElement.remove();
-
-    this._tableElement = Network.RequestTimingView.createTimingTable(this._request, this._calculator);
-    this._tableElement.classList.add('resource-timing-table');
-    this.element.appendChild(this._tableElement);
-  }
-};
-
-/** @enum {string} */
-Network.RequestTimeRangeNames = {
-  Push: 'push',
-  Queueing: 'queueing',
-  Blocking: 'blocking',
-  Connecting: 'connecting',
-  DNS: 'dns',
-  Proxy: 'proxy',
-  Receiving: 'receiving',
-  ReceivingPush: 'receiving-push',
-  Sending: 'sending',
-  ServiceWorker: 'serviceworker',
-  ServiceWorkerPreparation: 'serviceworker-preparation',
-  SSL: 'ssl',
-  Total: 'total',
-  Waiting: 'waiting'
-};
-
-Network.RequestTimingView.ConnectionSetupRangeNames = new Set([
-  Network.RequestTimeRangeNames.Queueing, Network.RequestTimeRangeNames.Blocking,
-  Network.RequestTimeRangeNames.Connecting, Network.RequestTimeRangeNames.DNS, Network.RequestTimeRangeNames.Proxy,
-  Network.RequestTimeRangeNames.SSL
-]);
-
-/** @typedef {{name: !Network.RequestTimeRangeNames, start: number, end: number}} */
-Network.RequestTimeRange;
diff --git a/front_end/network/ResourceWebSocketFrameView.js b/front_end/network/ResourceWebSocketFrameView.js
deleted file mode 100644
index cee68f4..0000000
--- a/front_end/network/ResourceWebSocketFrameView.js
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-/**
- * @unrestricted
- */
-Network.ResourceWebSocketFrameView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super();
-    this.registerRequiredCSS('network/webSocketFrameView.css');
-    this.element.classList.add('websocket-frame-view');
-    this._request = request;
-
-    this._splitWidget = new UI.SplitWidget(false, true, 'resourceWebSocketFrameSplitViewState');
-    this._splitWidget.show(this.element);
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'data', title: Common.UIString('Data'), sortable: false, weight: 88}, {
-        id: 'length',
-        title: Common.UIString('Length'),
-        sortable: false,
-        align: DataGrid.DataGrid.Align.Right,
-        weight: 5
-      },
-      {id: 'time', title: Common.UIString('Time'), sortable: true, weight: 7}
-    ]);
-
-    this._dataGrid = new DataGrid.SortableDataGrid(columns);
-    this._dataGrid.setRowContextMenuCallback(onRowContextMenu.bind(this));
-    this._dataGrid.setStickToBottom(true);
-    this._dataGrid.setCellClass('websocket-frame-view-td');
-    this._timeComparator =
-        /** @type {function(!Network.ResourceWebSocketFrameNode, !Network.ResourceWebSocketFrameNode):number} */ (
-            Network.ResourceWebSocketFrameNodeTimeComparator);
-    this._dataGrid.sortNodes(this._timeComparator, false);
-    this._dataGrid.markColumnAsSortedBy('time', DataGrid.DataGrid.Order.Ascending);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortItems, this);
-
-    this._dataGrid.setName('ResourceWebSocketFrameView');
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._onFrameSelected, this);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, this._onFrameDeselected, this);
-
-    this._mainToolbar = new UI.Toolbar('');
-
-    this._clearAllButton = new UI.ToolbarButton(Common.UIString('Clear All'), 'largeicon-clear');
-    this._clearAllButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearFrames, this);
-    this._mainToolbar.appendToolbarItem(this._clearAllButton);
-
-    this._filterTypeCombobox = new UI.ToolbarComboBox(this._updateFilterSetting.bind(this));
-    for (const filterItem of Network.ResourceWebSocketFrameView._filterTypes) {
-      const option = this._filterTypeCombobox.createOption(filterItem.label, filterItem.label, filterItem.name);
-      this._filterTypeCombobox.addOption(option);
-    }
-    this._mainToolbar.appendToolbarItem(this._filterTypeCombobox);
-    this._filterType = null;
-
-    const placeholder = 'Enter regex, for example: (web)?socket';
-    this._filterTextInput = new UI.ToolbarInput(Common.UIString(placeholder), 0.4);
-    this._filterTextInput.addEventListener(UI.ToolbarInput.Event.TextChanged, this._updateFilterSetting, this);
-    this._mainToolbar.appendToolbarItem(this._filterTextInput);
-    this._filterRegex = null;
-
-    const mainContainer = new UI.VBox();
-    mainContainer.element.appendChild(this._mainToolbar.element);
-    this._dataGrid.asWidget().show(mainContainer.element);
-    this._splitWidget.setMainWidget(mainContainer);
-
-    this._frameEmptyWidget = new UI.EmptyWidget(Common.UIString('Select frame to browse its content.'));
-    this._splitWidget.setSidebarWidget(this._frameEmptyWidget);
-
-    /** @type {?Network.ResourceWebSocketFrameNode} */
-    this._selectedNode = null;
-
-    /**
-     * @param {!UI.ContextMenu} contextMenu
-     * @param {!DataGrid.DataGridNode} node
-     * @this {Network.ResourceWebSocketFrameView}
-     */
-    function onRowContextMenu(contextMenu, node) {
-      contextMenu.clipboardSection().appendItem(
-          Common.UIString('Copy message'), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, node.data.data));
-      contextMenu.footerSection().appendItem(Common.UIString('Clear all'), this._clearFrames.bind(this));
-    }
-  }
-
-  /**
-   * @param {number} opCode
-   * @param {boolean} mask
-   * @return {string}
-   */
-  static opCodeDescription(opCode, mask) {
-    const rawDescription = Network.ResourceWebSocketFrameView.opCodeDescriptions[opCode] || '';
-    const localizedDescription = Common.UIString(rawDescription);
-    return Common.UIString('%s (Opcode %d%s)', localizedDescription, opCode, (mask ? ', mask' : ''));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.refresh();
-    this._request.addEventListener(SDK.NetworkRequest.Events.WebsocketFrameAdded, this._frameAdded, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._request.removeEventListener(SDK.NetworkRequest.Events.WebsocketFrameAdded, this._frameAdded, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameAdded(event) {
-    const frame = /** @type {!SDK.NetworkRequest.WebSocketFrame} */ (event.data);
-    if (!this._frameFilter(frame))
-      return;
-    this._dataGrid.insertChild(new Network.ResourceWebSocketFrameNode(this._request.url(), frame));
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest.WebSocketFrame} frame
-   * @return {boolean}
-   */
-  _frameFilter(frame) {
-    if (this._filterType && frame.type !== this._filterType)
-      return false;
-    return !this._filterRegex || this._filterRegex.test(frame.text);
-  }
-
-  _clearFrames() {
-    // TODO(allada): actially remove frames from request.
-    this._request[Network.ResourceWebSocketFrameView._clearFrameOffsetSymbol] = this._request.frames().length;
-    this.refresh();
-  }
-
-  _updateFilterSetting() {
-    const text = this._filterTextInput.value();
-    const type = this._filterTypeCombobox.selectedOption().value;
-    this._filterRegex = text ? new RegExp(text, 'i') : null;
-    this._filterType = type === 'all' ? null : type;
-    this.refresh();
-  }
-
-  /**
-  * @param {!Common.Event} event
-   */
-  async _onFrameSelected(event) {
-    const selectedNode = /** @type {!Network.ResourceWebSocketFrameNode} */ (event.data);
-    this._currentSelectedNode = selectedNode;
-    const contentProvider = selectedNode.contentProvider();
-    const content = await contentProvider.requestContent();
-    const jsonView = await SourceFrame.JSONView.createView(content);
-    if (this._currentSelectedNode !== selectedNode)
-      return;
-    if (jsonView)
-      this._splitWidget.setSidebarWidget(jsonView);
-    else
-      this._splitWidget.setSidebarWidget(new SourceFrame.ResourceSourceFrame(contentProvider));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFrameDeselected(event) {
-    this._currentSelectedNode = null;
-    this._splitWidget.setSidebarWidget(this._frameEmptyWidget);
-  }
-
-  refresh() {
-    this._dataGrid.rootNode().removeChildren();
-
-    const url = this._request.url();
-    let frames = this._request.frames();
-    const offset = this._request[Network.ResourceWebSocketFrameView._clearFrameOffsetSymbol] || 0;
-    frames = frames.slice(offset);
-    frames = frames.filter(this._frameFilter.bind(this));
-    frames.forEach(frame => this._dataGrid.insertChild(new Network.ResourceWebSocketFrameNode(url, frame)));
-  }
-
-  _sortItems() {
-    this._dataGrid.sortNodes(this._timeComparator, !this._dataGrid.isSortOrderAscending());
-  }
-};
-
-/** @enum {number} */
-Network.ResourceWebSocketFrameView.OpCodes = {
-  ContinuationFrame: 0,
-  TextFrame: 1,
-  BinaryFrame: 2,
-  ConnectionCloseFrame: 8,
-  PingFrame: 9,
-  PongFrame: 10
-};
-
-/** @type {!Array.<string> } */
-Network.ResourceWebSocketFrameView.opCodeDescriptions = (function() {
-  const opCodes = Network.ResourceWebSocketFrameView.OpCodes;
-  const map = [];
-  map[opCodes.ContinuationFrame] = 'Continuation Frame';
-  map[opCodes.TextFrame] = 'Text Frame';
-  map[opCodes.BinaryFrame] = 'Binary Frame';
-  map[opCodes.ContinuationFrame] = 'Connection Close Frame';
-  map[opCodes.PingFrame] = 'Ping Frame';
-  map[opCodes.PongFrame] = 'Pong Frame';
-  return map;
-})();
-
-/** @type {!Array<!UI.NamedBitSetFilterUI.Item>} */
-Network.ResourceWebSocketFrameView._filterTypes = [
-  {name: 'all', label: Common.UIString('All')},
-  {name: 'send', label: Common.UIString('Send')},
-  {name: 'receive', label: Common.UIString('Receive')},
-];
-
-/**
- * @unrestricted
- */
-Network.ResourceWebSocketFrameNode = class extends DataGrid.SortableDataGridNode {
-  /**
-   * @param {string} url
-   * @param {!SDK.NetworkRequest.WebSocketFrame} frame
-   */
-  constructor(url, frame) {
-    let dataText = frame.text;
-    const length = frame.text.length;
-    const time = new Date(frame.time * 1000);
-    const timeText = ('0' + time.getHours()).substr(-2) + ':' + ('0' + time.getMinutes()).substr(-2) + ':' +
-        ('0' + time.getSeconds()).substr(-2) + '.' + ('00' + time.getMilliseconds()).substr(-3);
-    const timeNode = createElement('div');
-    timeNode.createTextChild(timeText);
-    timeNode.title = time.toLocaleString();
-
-    const isTextFrame = frame.opCode === Network.ResourceWebSocketFrameView.OpCodes.TextFrame;
-    if (!isTextFrame)
-      dataText = Network.ResourceWebSocketFrameView.opCodeDescription(frame.opCode, frame.mask);
-
-    super({data: dataText, length: length, time: timeNode});
-
-    this._url = url;
-    this._frame = frame;
-    this._isTextFrame = isTextFrame;
-    this._dataText = dataText;
-  }
-
-  /**
-   * @override
-   * @param {!Element} element
-   */
-  createCells(element) {
-    element.classList.toggle(
-        'websocket-frame-view-row-error', this._frame.type === SDK.NetworkRequest.WebSocketFrameType.Error);
-    element.classList.toggle(
-        'websocket-frame-view-row-send', this._frame.type === SDK.NetworkRequest.WebSocketFrameType.Send);
-    element.classList.toggle(
-        'websocket-frame-view-row-receive', this._frame.type === SDK.NetworkRequest.WebSocketFrameType.Receive);
-    element.classList.toggle('websocket-frame-view-row-opcode', !this._isTextFrame);
-    super.createCells(element);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  nodeSelfHeight() {
-    return 21;
-  }
-
-  /**
-   * @return {!Common.ContentProvider}
-   */
-  contentProvider() {
-    return Common.StaticContentProvider.fromString(this._url, Common.resourceTypes.WebSocket, this._dataText);
-  }
-};
-
-/**
- * @param {!Network.ResourceWebSocketFrameNode} a
- * @param {!Network.ResourceWebSocketFrameNode} b
- * @return {number}
- */
-Network.ResourceWebSocketFrameNodeTimeComparator = function(a, b) {
-  return a._frame.time - b._frame.time;
-};
-
-Network.ResourceWebSocketFrameView._clearFrameOffsetSymbol = Symbol('ClearFrameOffset');
diff --git a/front_end/network/blockedURLsPane.css b/front_end/network/blockedURLsPane.css
deleted file mode 100644
index dcadf7e..0000000
--- a/front_end/network/blockedURLsPane.css
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.list {
-    border: none !important;
-    border-top: var(--divider-border) !important;
-}
-
-.blocking-disabled {
-    pointer-events: none;
-    opacity: 0.8;
-}
-
-.editor-container {
-    padding: 0 4px;
-}
-
-.no-blocked-urls, .blocked-urls {
-    overflow-x: hidden;
-    overflow-y: auto;
-}
-
-.no-blocked-urls {
-    display: flex;
-    justify-content: center;
-    padding: 10px;
-}
-
-.no-blocked-urls > span {
-    white-space: pre;
-}
-
-.blocked-url {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    flex: auto;
-}
-
-.blocked-url-count {
-    flex: none;
-    padding-right: 9px;
-}
-
-.blocked-url-checkbox {
-    margin-left: 8px;
-    flex: none;
-}
-
-.blocked-url-label {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    flex: auto;
-    padding: 0 3px;
-}
-
-.blocked-url-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 7px 5px 0 5px;
-    align-items: center;
-}
-
-.blocked-url-edit-value {
-    -webkit-user-select: none;
-    flex: 1 1 0px;
-}
-
-.blocked-url-edit-row input {
-    width: 100%;
-    text-align: inherit;
-    height: 22px;
-}
diff --git a/front_end/network/eventSourceMessagesView.css b/front_end/network/eventSourceMessagesView.css
deleted file mode 100644
index 60174c5..0000000
--- a/front_end/network/eventSourceMessagesView.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.event-source-messages-view .data-grid {
-    flex: auto;
-    border: none;
-}
diff --git a/front_end/network/module.json b/front_end/network/module.json
deleted file mode 100644
index 50c1890..0000000
--- a/front_end/network/module.json
+++ /dev/null
@@ -1,210 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "network",
-            "title": "Network",
-            "order": 40,
-            "className": "Network.NetworkPanel"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "SDK.NetworkRequest",
-                "SDK.Resource",
-                "Workspace.UISourceCode"
-            ],
-            "className": "Network.NetworkPanel.ContextMenuProvider"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "SDK.NetworkRequest"
-            ],
-            "destination": "Network panel",
-            "className": "Network.NetworkPanel.RequestRevealer"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "Network.UIRequestLocation"
-            ],
-            "className": "Network.NetworkPanel.RequestLocationRevealer"
-        },
-        {
-            "type": "setting",
-            "category": "Network",
-            "title": "Color-code resource types",
-            "settingName": "networkColorCodeResourceTypes",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "tags": "color code, resource type",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Color code by resource type"
-                },
-                {
-                    "value": false,
-                    "title": "Use default colors"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Network",
-            "title": "Group network log by frame",
-            "settingName": "network.group-by-frame",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "tags": "network, frame, group",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Group network log items by frame"
-                },
-                {
-                    "value": false,
-                    "title": "Don't group network log items by frame"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "network.toggle-recording",
-            "iconClass": "largeicon-start-recording",
-            "toggledIconClass": "largeicon-stop-recording",
-            "toggleWithRedColor": true,
-            "contextTypes": [
-                "Network.NetworkPanel"
-            ],
-            "className": "Network.NetworkPanel.RecordActionDelegate",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Record network log"
-                },
-                {
-                    "value": false,
-                    "title": "Stop recording network log"
-                }
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+E"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+E"
-                }
-            ]
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "network.blocked-urls",
-            "title": "Request blocking",
-            "persistence": "closeable",
-            "order": 60,
-            "className": "Network.BlockedURLsPane"
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "network.config",
-            "title": "Network conditions",
-            "persistence": "closeable",
-            "order": 40,
-            "className": "Network.NetworkConfigView",
-            "tags": "disk cache, network throttling, useragent, user agent"
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "network-sidebar",
-            "category": "Network",
-            "className": "Network.NetworkPanel"
-        },
-        {
-            "type": "view",
-            "location": "network-sidebar",
-            "id": "network.search-network-tab",
-            "title": "Search",
-            "persistence": "permanent",
-            "className": "Network.SearchNetworkView"
-        },
-        {
-            "type": "action",
-            "actionId": "network.search",
-            "title": "Search",
-            "className": "Network.NetworkPanel.SearchActionDelegate",
-            "contextTypes": [
-                "Network.NetworkPanel"
-            ],
-            "category": "DevTools",
-            "bindings": [
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+F"
-                },
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+F"
-                }
-            ]
-        }
-    ],
-    "dependencies": [
-        "search",
-        "source_frame",
-        "components",
-        "perf_ui",
-        "cookie_table",
-        "data_grid",
-        "browser_sdk",
-        "product_registry",
-        "mobile_throttling",
-        "har_importer",
-        "persistence"
-    ],
-    "scripts": [
-        "BlockedURLsPane.js",
-        "EventSourceMessagesView.js",
-        "HARWriter.js",
-        "NetworkConfigView.js",
-        "NetworkDataGridNode.js",
-        "NetworkItemView.js",
-        "NetworkTimeCalculator.js",
-        "NetworkLogView.js",
-        "NetworkLogViewColumns.js",
-        "NetworkFrameGrouper.js",
-        "NetworkManageCustomHeadersView.js",
-        "NetworkOverview.js",
-        "NetworkSearchScope.js",
-        "NetworkWaterfallColumn.js",
-        "RequestCookiesView.js",
-        "RequestHeadersView.js",
-        "RequestHTMLView.js",
-        "RequestResponseView.js",
-        "RequestPreviewView.js",
-        "RequestTimingView.js",
-        "ResourceWebSocketFrameView.js",
-        "NetworkPanel.js"
-    ],
-    "resources": [
-        "blockedURLsPane.css",
-        "eventSourceMessagesView.css",
-        "networkConfigView.css",
-        "networkLogView.css",
-        "networkManageCustomHeadersView.css",
-        "networkPanel.css",
-        "networkTimingTable.css",
-        "networkWaterfallColumn.css",
-        "requestCookiesView.css",
-        "requestHeadersTree.css",
-        "requestHeadersView.css",
-        "requestHTMLView.css",
-        "webSocketFrameView.css"
-    ]
-}
diff --git a/front_end/network/networkConfigView.css b/front_end/network/networkConfigView.css
deleted file mode 100644
index 5c9f81f..0000000
--- a/front_end/network/networkConfigView.css
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.network-config {
-    padding: 12px;
-    display: block;
-}
-
-.network-config-group {
-    display: flex;
-    margin-bottom: 10px;
-    flex-wrap: wrap;
-    flex: 0 0 auto;
-    min-height: 30px;
-}
-
-.network-config-title {
-    margin-right: 16px;
-    width: 130px;
-}
-
-.network-config-fields {
-    flex: 2 0 200px;
-}
-
-.panel-section-separator {
-    height: 1px;
-    margin-bottom: 10px;
-    background: #f0f0f0;
-}
-
-/* Disable cache */
-
-.network-config-disable-cache {
-    line-height: 28px;
-    border-top: none;
-    padding-top: 0;
-}
-
-/* Network throttling */
-
-.network-config-throttling .chrome-select {
-    width: 100%;
-    max-width: 250px;
-}
-
-.network-config-throttling > .network-config-title {
-    line-height: 24px;
-}
-
-/* User agent */
-
-.network-config-ua > .network-config-title {
-    line-height: 20px;
-}
-
-.network-config-ua label[is="dt-radio"].checked > * {
-    display: none
-}
-
-.network-config-ua input:not(.dt-radio-button) {
-    display: block;
-    width: calc(100% - 20px);
-    max-width: 250px;
-}
-
-.network-config-ua input[readonly] {
-    background-color: rgb(235, 235, 228);
-}
-
-.network-config-ua input[type=text], .network-config-ua .chrome-select {
-    margin-top: 8px;
-}
-
-.network-config-ua .chrome-select {
-    width: calc(100% - 20px);
-    max-width: 250px;
-}
-
-.network-config-ua label[is="dt-radio"] {
-    display: block;
-}
-
-.network-config-ua-auto, .network-config-ua-custom {
-    opacity: 0.5;
-}
-
-.network-config-ua-auto.checked, .network-config-ua-custom.checked {
-    opacity: 1;
-}
diff --git a/front_end/network/networkLogView.css b/front_end/network/networkLogView.css
deleted file mode 100644
index b7240de..0000000
--- a/front_end/network/networkLogView.css
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.network-log-grid.data-grid {
-    border: none;
-    flex: auto;
-}
-
-.network-summary-bar {
-    flex: 0 0 27px;
-    line-height: 27px;
-    padding-left: 5px;
-    background-color: #eee;
-    border-top: 1px solid #ccc;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.network-summary-bar label[is=dt-icon-label] {
-    margin-right: 6px;
-}
-
-.network-summary-bar > * {
-    flex: none;
-}
-
-.network-log-grid.data-grid table.data {
-    background: transparent;
-}
-
-.network-log-grid.data-grid td {
-    height: 41px;
-    border-left: 1px solid #e1e1e1;
-    vertical-align: middle;
-}
-
-.network-log-grid.data-grid .corner {
-    display: none;
-}
-
-.network-log-grid.data-grid.small td {
-    height: 21px;
-}
-
-.network-waterfall-header, .network-log-grid.data-grid th {
-    border-bottom: 1px solid rgb(205, 205, 205);
-    border-left: 1px solid rgb(205, 205, 205);
-}
-
-.network-waterfall-header, .network-log-grid.data-grid .header-container {
-    height: 31px;
-    background-color: var(--toolbar-bg-color);
-}
-
-.network-log-grid.data-grid .data-container {
-    top: 31px;
-}
-
-.network-waterfall-header.small, .network-log-grid.data-grid.small .header-container {
-    height: 27px;
-}
-
-.network-log-grid.data-grid.small .data-container {
-    top: 27px;
-}
-
-.network-log-grid.data-grid select {
-    -webkit-appearance: none;
-    border: none;
-    width: 100%;
-    color: inherit;
-}
-
-.network-log-grid.data-grid .name-column {
-    cursor: pointer;
-}
-
-.network-log-grid.data-grid .waterfall-column {
-    padding: 1px 0;
-}
-
-.network-log-grid.data-grid .waterfall-column .sort-order-icon-container {
-    right: 15px;
-    pointer-events: none;
-}
-
-.network-log-grid.data-grid th.sortable:active {
-    background-image: none !important;
-}
-
-.network-cell-subtitle {
-    font-weight: normal;
-    color: gray;
-}
-
-.network-badge {
-    margin-right: 4px;
-}
-
-.network-error-row,
-.network-error-row .network-cell-subtitle {
-    color: rgb(230, 0, 0);
-}
-
-.initiator-column .devtools-link {
-    color: inherit;
-}
-
-.network-log-grid.data-grid tr.selected,
-.network-log-grid.data-grid tr.selected .network-cell-subtitle,
-.network-log-grid.data-grid tr.selected .network-dim-cell {
-    color: inherit !important;
-}
-
-.network-log-grid.data-grid:focus tr.selected,
-.network-log-grid.data-grid:focus tr.selected .network-cell-subtitle,
-.network-log-grid.data-grid:focus tr.selected .network-dim-cell {
-    color: var(--selection-fg-color) !important;
-}
-
-.network-log-grid tr.highlighted-row {
-    -webkit-animation: network-row-highlight-fadeout 2s 0s;
-}
-
-@-webkit-keyframes network-row-highlight-fadeout {
-    from {background-color: rgba(255, 255, 120, 1); }
-    to { background-color: rgba(255, 255, 120, 0); }
-}
-
-.network-header-subtitle {
-    color: gray;
-}
-
-.network-log-grid.data-grid.small .network-cell-subtitle,
-.network-log-grid.data-grid.small .network-header-subtitle {
-    display: none;
-}
-
-/* Resource preview icons */
-
-.network-log-grid.data-grid .icon {
-    content: url(Images/resourcePlainIcon.png);
-}
-
-.network-log-grid.data-grid.small .icon {
-    content: url(Images/resourcePlainIconSmall.png);
-}
-
-.network-log-grid.data-grid .icon.script {
-    content: url(Images/resourceJSIcon.png);
-}
-
-.network-log-grid.data-grid.small .icon.script {
-    content: url(Images/resourceDocumentIconSmall.png);
-}
-
-.network-log-grid.data-grid .icon.document {
-    content: url(Images/resourceDocumentIcon.png);
-}
-
-.network-log-grid.data-grid.small .icon.document {
-    content: url(Images/resourceDocumentIconSmall.png);
-}
-
-.network-log-grid.data-grid .icon.stylesheet {
-    content: url(Images/resourceCSSIcon.png);
-}
-
-.network-log-grid.data-grid.small .icon.stylesheet {
-    content: url(Images/resourceDocumentIconSmall.png);
-}
-
-.network-log-grid.data-grid .icon.media {
-    content: url(Images/resourcePlainIcon.png); /* FIXME: media icon */
-}
-
-.network-log-grid.data-grid.small .icon.media {
-    content: url(Images/resourcePlainIconSmall.png); /* FIXME: media icon */
-}
-.network-log-grid.data-grid .icon.texttrack {
-    content: url(Images/resourcePlainIcon.png); /* FIXME: vtt icon */
-}
-
-.network-log-grid.data-grid.small .icon.texttrack {
-    content: url(Images/resourcePlainIconSmall.png); /* FIXME: vtt icon */
-}
-
-.network-log-grid.data-grid .icon.image {
-    position: relative;
-    background-image: url(Images/resourcePlainIcon.png);
-    background-repeat: no-repeat;
-    content: "";
-}
-
-.network-log-grid.data-grid.small .icon.image {
-    background-image: url(Images/resourcePlainIconSmall.png);
-    content: "";
-}
-
-.network-log-grid.data-grid .icon {
-    float: left;
-    width: 32px;
-    height: 32px;
-    margin-top: 1px;
-    margin-right: 3px;
-}
-
-.network-log-grid.data-grid.small .icon {
-    width: 16px;
-    height: 16px;
-}
-
-.network-log-grid.data-grid .image-network-icon-preview {
-    position: absolute;
-    margin: auto;
-    top: 3px;
-    bottom: 4px;
-    left: 5px;
-    right: 5px;
-    max-width: 18px;
-    max-height: 21px;
-    min-width: 1px;
-    min-height: 1px;
-}
-
-.network-log-grid.data-grid.small .image-network-icon-preview {
-    top: 2px;
-    bottom: 1px;
-    left: 3px;
-    right: 3px;
-    max-width: 8px;
-    max-height: 11px;
-}
-
-.network-dim-cell {
-    color: grey;
-}
-
-.network-summary-bar .summary-red {
-    color: red;
-}
-
-.network-frame-divider {
-    width: 2px;
-    background-color: #FCCC49;
-    z-index: 10;
-    visibility: hidden;
-}
-
-#network-container:not(.brief-mode) .data-container {
-    overflow: hidden;
-}
-
-.network-summary-bar .summary-blue {
-    color: blue;
-}
-
-.-theme-with-dark-background .network-summary-bar .summary-blue {
-    color: #03A9F4;
-}
-
-.network-log-grid.data-grid .resources-dividers {
-    z-index: 0;
-}
-
-.network-log-grid.data-grid .resources-dividers-label-bar {
-    background-color: transparent;
-    border: none;
-    height: 30px;
-    pointer-events: none;
-}
-
-#network-container {
-    overflow: hidden;
-}
-
-.network-status-pane {
-    color: #777;
-    background-color: white;
-    z-index: 500;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    text-align: center;
-    padding: 0 20px;
-    overflow: auto;
-}
-
-.network-status-pane > .recording-hint {
-    font-size: 14px;
-    text-align: center;
-    line-height: 28px;
-}
-
-.network-waterfall-header {
-    position: absolute;
-    border-left: 0px;
-    width: 100%;
-    display: table;
-    z-index: 200;
-}
-
-.network-waterfall-header:hover {
-    background-color: hsla(0, 0%, 10%, 0.1);
-}
-
-.network-waterfall-header div {
-    display: table-cell;
-    line-height: 14px;
-    margin: auto 0px;
-    vertical-align: middle;
-    text-align: left;
-    font-weight: normal;
-    padding: 0px 4px;
-}
-
-.network-waterfall-header .sort-order-icon-container {
-    position: absolute;
-    top: 1px;
-    right: 0;
-    bottom: 1px;
-    display: flex;
-    align-items: center;
-}
-
-.network-waterfall-header .sort-order-icon {
-    align-items: center;
-    margin-right: 4px;
-    margin-bottom: -2px;
-}
-
-.network-frame-group-icon {
-    display: inline-block;
-    margin: -8px -2px;
-}
-
-.network-frame-group-badge {
-    margin-right: 4px;
-}
diff --git a/front_end/network/networkManageCustomHeadersView.css b/front_end/network/networkManageCustomHeadersView.css
deleted file mode 100644
index 26eccb5..0000000
--- a/front_end/network/networkManageCustomHeadersView.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-.custom-headers-list {
-    height: 272px;
-    width: 250px;
-}
-
-.custom-headers-wrapper{
-    margin: 10px;
-}
-
-.header {
-    padding: 0 0 6px;
-    font-size: 18px;
-    font-weight: normal;
-    flex: none;
-}
-
-.custom-headers-header {
-    padding:2px;
-}
-
-.custom-headers-list-item {
-    padding-left: 5px;
-}
-
-.editor-container {
-    padding: 5px 0px 0px 5px;
-}
-
-.add-button {
-    width: 150px;
-    margin: auto;
-    margin-top: 5px;
-}
diff --git a/front_end/network/networkPanel.css b/front_end/network/networkPanel.css
deleted file mode 100644
index ba6505e..0000000
--- a/front_end/network/networkPanel.css
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.panel.network .toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.network-details-view {
-    background: rgb(203, 203, 203);
-}
-
-.network-details-view-tall-header {
-    margin-top: 4px;
-}
-
-.network-item-view {
-    display: flex;
-    background: white;
-}
-
-.network-item-preview-toolbar {
-    border-top: 1px solid #ccc;
-    background-color: #eee;
-}
-
-.resource-timing-view {
-    display: block;
-    margin: 6px;
-    color: rgb(30%, 30%, 30%);
-}
-
-.resource-timing-table {
-    width: 100% !important;
-}
-
-#network-overview-panel {
-    flex: none;
-    position: relative;
-}
-
-#network-overview-container {
-    overflow: hidden;
-    flex: auto;
-    display: flex;
-    flex-direction: column;
-    position: relative;
-    border-bottom: 1px solid #CDCDCD;
-}
-
-#network-overview-container canvas {
-    width: 100%;
-    height: 100%;
-}
-
-#network-overview-grid .resources-dividers-label-bar {
-    pointer-events: auto;
-}
-
-.network .network-overview {
-    flex: 0 0 60px;
-}
-
-.network-overview .overview-grid-window,
-.network-overview .overview-grid-dividers-background {
-    height: 100%;
-}
-
-.network-overview .resources-dividers-label-bar {
-    background-color: rgba(255, 255, 255, 0.95);
-}
-
-.network-overview .resources-dividers-label-bar .resources-divider {
-    background-color: transparent;
-}
-
-.network-overview .resources-dividers {
-    z-index: 250;
-}
-
-.request-view.html iframe {
-    width: 100%;
-    height: 100%;
-    position: absolute;
-}
-
-.network-film-strip {
-    border-bottom: solid 1px #cdcdcd;
-    flex: none !important;
-}
-
-.network-film-strip-placeholder {
-    flex-shrink: 0;
-}
-
-.network-blocked-urls {
-    border-top: var(--divider-border);
-    flex: 104px 0 0;
-}
-
-.open-search-view {
-    align-items: center;
-    background-color: hsl(50, 100%, 88%);
-    border-bottom: var(--divider-border);
-    cursor: pointer;
-    flex-grow: 0;
-    padding: 4px;
-}
-
-.open-search-view > * {
-    margin: 0 4px;
-}
-
-.network-tabbed-pane {
-    background-color: var(--toolbar-bg-color);
-}
diff --git a/front_end/network/networkTimingTable.css b/front_end/network/networkTimingTable.css
deleted file mode 100644
index 6b1f3d0..0000000
--- a/front_end/network/networkTimingTable.css
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.network-timing-table {
-    width: 380px;
-    border-spacing: 0;
-    padding-left: 10px;
-    padding-right: 10px;
-    line-height: initial;
-}
-
-.network-timing-start {
-    border-top: 5px solid transparent;
-}
-.network-timing-table-header td, .network-timing-footer td {
-    border-top: 10px solid transparent;
-}
-
-.network-timing-table-header td {
-    color: #bbb;
-}
-
-.network-timing-table-header td:last-child {
-    text-align: right;
-}
-
-.network-timing-table col.labels {
-    width: 156px;
-}
-
-.network-timing-table col.duration {
-    width: 80px;
-}
-
-.network-timing-table td {
-    padding: 4px 0;
-}
-
-.network-timing-table td.caution {
-    font-weight: bold;
-    color: rgb(255, 128, 0);
-    padding: 2px 0;
-}
-
-.network-timing-table hr.break {
-    border: 0;
-    height: 1px;
-    background-image: linear-gradient(to right, #eee, #bbb, #eee);
-}
-
-.network-timing-footer td:last-child {
-    font-weight: bold;
-    text-align: right;
-}
-
-.network-timing-row {
-    position: relative;
-    height: 15px;
-}
-
-.network-timing-bar {
-    position: absolute;
-    min-width: 1px;
-    top: 0;
-    bottom: 0;
-}
-
-.network-timing-bar-title {
-    color: #222;
-    white-space: nowrap;
-    text-align: right;
-}
-
-.network-timing-bar.queueing,
-.network-timing-bar.total {
-    border: 1px solid rgba(0, 0, 0, 0.1);
-}
-
-.network-timing-bar.blocking, -theme-preserve {
-    background-color: #AAAAAA;
-}
-
-.network-timing-bar.proxy, -theme-preserve {
-    background-color: #A1887F;
-}
-
-.network-timing-bar.dns, -theme-preserve {
-    background-color: #009688;
-}
-
-.network-timing-bar.connecting,
-.network-timing-bar.serviceworker,
-.network-timing-bar.serviceworker-preparation, -theme-preserve {
-    background-color: #FF9800;
-}
-
-.network-timing-bar.ssl, -theme-preserve {
-    background-color: #9C27B0;
-}
-
-.network-timing-bar.sending, -theme-preserve {
-    background-color: #B0BEC5;
-}
-
-.network-timing-bar.waiting, -theme-preserve {
-    background-color: #00C853;
-}
-
-.network-timing-bar.receiving, -theme-preserve,
-.network-timing-bar.receiving-push, -theme-preserve {
-    background-color: #03A9F4;
-}
-
-.network-timing-bar.push, -theme-preserve {
-    background-color: #8CDBff;
-}
-
-.network-timing-bar.server-timing, -theme-preserve {
-    background-color: #ddd;
-}
-
-.network-timing-table td.network-timing-metric {
-    white-space: nowrap;
-    max-width: 150px;
-    overflow-x: hidden;
-    text-overflow: ellipsis;
-}
-
-.network-timing-bar.proxy,
-.network-timing-bar.dns,
-.network-timing-bar.ssl,
-.network-timing-bar.connecting,
-.network-timing-bar.blocking {
-    height: 10px;
-    margin: auto;
-}
diff --git a/front_end/network/networkWaterfallColumn.css b/front_end/network/networkWaterfallColumn.css
deleted file mode 100644
index dfa47d8..0000000
--- a/front_end/network/networkWaterfallColumn.css
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-.network-waterfall-v-scroll {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    overflow-x: hidden;
-    margin-top: 31px;
-    z-index: 200;
-}
-
-.network-waterfall-v-scroll.small {
-    margin-top: 27px;
-}
-
-.network-waterfall-v-scroll-content {
-    width: 15px;
-    pointer-events: none;
-}
diff --git a/front_end/network/requestCookiesView.css b/front_end/network/requestCookiesView.css
deleted file mode 100644
index d771b1a..0000000
--- a/front_end/network/requestCookiesView.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.request-cookies-view {
-    display: flex;
-    overflow: auto;
-    margin: 12px;
-    height: 100%;
-}
-
-.request-cookies-view .data-grid {
-    flex: auto;
-    height: 100%;
-}
-
-.request-cookies-view .data-grid .row-group {
-    font-weight: bold;
-}
diff --git a/front_end/network/requestHTMLView.css b/front_end/network/requestHTMLView.css
deleted file mode 100644
index dac6625..0000000
--- a/front_end/network/requestHTMLView.css
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-.html-preview-frame {
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
-  flex-grow: 1;
-  margin: 20px;
-  pointer-events: none;
-}
diff --git a/front_end/network/requestHeadersTree.css b/front_end/network/requestHeadersTree.css
deleted file mode 100644
index aed4901..0000000
--- a/front_end/network/requestHeadersTree.css
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tree-outline {
-    padding-left: 0;
-}
-
-.tree-outline > ol {
-    padding-bottom: 5px;
-    border-bottom: solid 1px #e0e0e0;
-}
-
-.tree-outline > .parent {
-    -webkit-user-select: none;
-    font-weight: bold;
-    color: #616161;
-    margin-top: -1px;
-    height: 20px;
-    display: flex;
-    align-items: center;
-    height: 26px;
-}
-
-.tree-outline li {
-    display: block;
-    padding-left: 5px;
-    line-height: 20px;
-}
-
-.tree-outline li:not(.parent) {
-    margin-left: 10px;
-}
-
-.tree-outline li:not(.parent)::before {
-    display: none;
-}
-
-.tree-outline .caution {
-    margin-left: 4px;
-    display: inline-block;
-    font-weight: bold;
-}
-
-.tree-outline li.expanded .header-count {
-    display: none;
-}
-
-.tree-outline li .header-toggle {
-    display: none;
-}
-
-.tree-outline li .status-from-cache {
-    color: gray;
-}
-
-.tree-outline li.expanded .header-toggle {
-    display: inline;
-    margin-left: 30px;
-    font-weight: normal;
-    color: rgb(45%, 45%, 45%);
-}
-
-.tree-outline li .header-toggle:hover {
-    color: rgb(20%, 20%, 45%);
-    cursor: pointer;
-}
-
-.tree-outline .header-name {
-    color: rgb(33%, 33%, 33%);
-    display: inline-block;
-    margin-right: 0.25em;
-    font-weight: bold;
-    vertical-align: top;
-    white-space: pre-wrap;
-}
-
-.tree-outline .header-separator {
-    user-select: none;
-}
-
-.tree-outline .header-value {
-    display: inline;
-    margin-right: 1em;
-    white-space: pre-wrap;
-    word-break: break-all;
-    margin-top: 1px;
-}
-
-.tree-outline .empty-request-header {
-    color: rgba(33%, 33%, 33%, 0.5);
-}
-
-.request-headers-show-more-button {
-    border: none;
-    border-radius: 3px;
-    display: inline-block;
-    font-size: 12px;
-    font-family: sans-serif;
-    cursor: pointer;
-    margin: 0 4px;
-    padding: 2px 4px;
-}
-
-.header-highlight {
-    background-color: #FFFF78
-}
diff --git a/front_end/network/requestHeadersView.css b/front_end/network/requestHeadersView.css
deleted file mode 100644
index f864987..0000000
--- a/front_end/network/requestHeadersView.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.request-headers-view {
-    -webkit-user-select: text;
-    overflow: auto;
-}
-
-.resource-status-image {
-    margin-top: -2px;
-    margin-right: 3px;
-}
-
-.request-headers-view .filter-input {
-    outline: none !important;
-    border: none;
-    border-bottom: solid 1px #ccc;
-    flex: 0 0 19px;
-    padding: 0 4px;
-}
-
-.request-headers-tree {
-    flex-grow: 1;
-    overflow-y: auto;
-    margin: 0;
-}
-
-.header-decode-error {
-    color: red;
-}
-
-.-theme-with-dark-background .header-decode-error {
-    color: hsl(0, 100%, 65%);
-}
diff --git a/front_end/network/webSocketFrameView.css b/front_end/network/webSocketFrameView.css
deleted file mode 100644
index 9e95e84..0000000
--- a/front_end/network/webSocketFrameView.css
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.websocket-frame-view {
-    -webkit-user-select: text;
-}
-
-.websocket-frame-view .data-grid {
-    flex: auto;
-    border: none;
-}
-
-.websocket-frame-view .data-grid .data {
-    background-image: none;
-}
-
-.websocket-frame-view-td {
-    border-bottom: 1px solid #ccc;
-}
-
-.websocket-frame-view .data-grid tr.selected {
-    background-color: #def;
-}
-
-.websocket-frame-view .data-grid td,
-.websocket-frame-view .data-grid th {
-    border-left-color: #ccc;
-}
-
-.websocket-frame-view-row-send td:first-child::before {
-    content: "\2B06 ";
-    color: #080;
-}
-
-.websocket-frame-view-row-receive td:first-child::before {
-    content: "\2B07 ";
-    color: #E65100;
-}
-
-.data-grid:focus .websocket-frame-view-row-send.selected td:first-child::before,
-.data-grid:focus .websocket-frame-view-row-receive.selected td:first-child::before {
-    color: white;
-}
-
-.websocket-frame-view-row-send {
-    background-color: rgb(226, 247, 218);
-}
-
-.websocket-frame-view-row-opcode {
-    background-color: rgb(255, 255, 232);
-    color: rgb(170, 111, 71);
-}
-
-.websocket-frame-view-row-error {
-    background-color: rgb(255, 237, 237);
-    color: rgb(182, 0, 0);
-}
-
-.websocket-frame-view .toolbar {
-    border-bottom: var(--divider-border);
-}
diff --git a/front_end/network_test_runner/NetworkTestRunner.js b/front_end/network_test_runner/NetworkTestRunner.js
deleted file mode 100644
index be0d83c..0000000
--- a/front_end/network_test_runner/NetworkTestRunner.js
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-NetworkTestRunner.waitForRequestResponse = function(request) {
-  if (request.responseReceivedTime !== -1)
-    return Promise.resolve(request);
-
-  return TestRunner.waitForEvent(
-      SDK.NetworkManager.Events.RequestUpdated, TestRunner.networkManager,
-      updateRequest => updateRequest === request && request.responseReceivedTime !== -1);
-};
-
-NetworkTestRunner.waitForNetworkLogViewNodeForRequest = function(request) {
-  const networkLogView = UI.panels.network._networkLogView;
-  const node = networkLogView.nodeForRequest(request);
-
-  if (node)
-    return Promise.resolve(node);
-
-  console.assert(networkLogView._staleRequests.has(request));
-
-  return TestRunner.addSnifferPromise(networkLogView, '_didRefreshForTest').then(() => {
-    const node = networkLogView.nodeForRequest(request);
-    console.assert(node);
-    return node;
-  });
-};
-
-NetworkTestRunner.waitForWebsocketFrameReceived = function(wsRequest, message) {
-  for (const frame of wsRequest.frames()) {
-    if (checkFrame(frame))
-      return Promise.resolve(frame);
-  }
-
-  return TestRunner.waitForEvent(SDK.NetworkRequest.Events.WebsocketFrameAdded, wsRequest, checkFrame);
-
-  function checkFrame(frame) {
-    return frame.type === SDK.NetworkRequest.WebSocketFrameType.Receive && frame.text === message;
-  }
-};
-
-NetworkTestRunner.recordNetwork = function() {
-  UI.panels.network._networkLogView.setRecording(true);
-};
-
-NetworkTestRunner.networkWaterfallColumn = function() {
-  return UI.panels.network._networkLogView._columns._waterfallColumn;
-};
-
-NetworkTestRunner.networkRequests = function() {
-  return Array.from(BrowserSDK.networkLog.requests());
-};
-
-NetworkTestRunner.dumpNetworkRequests = function() {
-  const requests = NetworkTestRunner.networkRequests();
-
-  requests.sort(function(a, b) {
-    return a.url().localeCompare(b.url());
-  });
-
-  TestRunner.addResult('resources count = ' + requests.length);
-
-  for (i = 0; i < requests.length; i++)
-    TestRunner.addResult(requests[i].url());
-};
-
-NetworkTestRunner.findRequestsByURLPattern = function(urlPattern) {
-  return NetworkTestRunner.networkRequests().filter(function(value) {
-    return urlPattern.test(value.url());
-  });
-};
-
-NetworkTestRunner.makeSimpleXHR = function(method, url, async, callback) {
-  NetworkTestRunner.makeXHR(method, url, async, undefined, undefined, [], false, undefined, undefined, callback);
-};
-
-NetworkTestRunner.makeSimpleXHRWithPayload = function(method, url, async, payload, callback) {
-  NetworkTestRunner.makeXHR(method, url, async, undefined, undefined, [], false, payload, undefined, callback);
-};
-
-NetworkTestRunner.makeXHR = function(
-    method, url, async, user, password, headers, withCredentials, payload, type, callback) {
-  const args = {};
-  args.method = method;
-  args.url = TestRunner.url(url);
-  args.async = async;
-  args.user = user;
-  args.password = password;
-  args.headers = headers;
-  args.withCredentials = withCredentials;
-  args.payload = payload;
-  args.type = type;
-  const jsonArgs = JSON.stringify(args).replace(/\"/g, '\\"');
-
-  function innerCallback(msg) {
-    if (msg.messageText.indexOf('XHR loaded') !== -1) {
-      if (callback)
-        callback();
-    } else {
-      ConsoleTestRunner.addConsoleSniffer(innerCallback);
-    }
-  }
-
-  ConsoleTestRunner.addConsoleSniffer(innerCallback);
-  TestRunner.evaluateInPageAnonymously('makeXHRForJSONArguments("' + jsonArgs + '")');
-};
-
-NetworkTestRunner.makeFetch = function(url, requestInitializer, callback) {
-  TestRunner.callFunctionInPageAsync('makeFetch', [url, requestInitializer]).then(callback);
-};
-
-NetworkTestRunner.makeFetchInWorker = function(url, requestInitializer, callback) {
-  TestRunner.callFunctionInPageAsync('makeFetchInWorker', [url, requestInitializer]).then(callback);
-};
-
-NetworkTestRunner.clearNetworkCache = function() {
-  // This turns cache off and then on, effectively clearning the memory cache.
-  return Promise.all([
-    TestRunner.NetworkAgent.clearBrowserCache(),
-    TestRunner.NetworkAgent.setCacheDisabled(true).then(() => TestRunner.NetworkAgent.setCacheDisabled(false))
-  ]);
-};
-
-NetworkTestRunner.HARPropertyFormatters = {
-  bodySize: 'formatAsTypeName',
-  compression: 'formatAsTypeName',
-  connection: 'formatAsTypeName',
-  headers: 'formatAsTypeName',
-  headersSize: 'formatAsTypeName',
-  id: 'formatAsTypeName',
-  onContentLoad: 'formatAsTypeName',
-  onLoad: 'formatAsTypeName',
-  receive: 'formatAsTypeName',
-  startedDateTime: 'formatAsRecentTime',
-  time: 'formatAsTypeName',
-  timings: 'formatAsTypeName',
-  version: 'formatAsTypeName',
-  wait: 'formatAsTypeName',
-  _transferSize: 'formatAsTypeName',
-  _error: 'skip'
-};
-
-NetworkTestRunner.HARPropertyFormattersWithSize = JSON.parse(JSON.stringify(NetworkTestRunner.HARPropertyFormatters));
-NetworkTestRunner.HARPropertyFormattersWithSize.size = 'formatAsTypeName';
-
-TestRunner.deprecatedInitAsync(`
-  let lastXHRIndex = 0;
-
-  function xhrLoadedCallback() {
-    console.log('XHR loaded: ' + ++lastXHRIndex);
-  }
-
-  function makeSimpleXHR(method, url, async, callback) {
-    makeSimpleXHRWithPayload(method, url, async, null, callback);
-  }
-
-  function makeSimpleXHRWithPayload(method, url, async, payload, callback) {
-    makeXHR(method, url, async, undefined, undefined, [], false, payload, undefined, callback);
-  }
-
-  function makeXHR(method, url, async, user, password, headers, withCredentials, payload, type, callback) {
-    let xhr = new XMLHttpRequest();
-
-    if (type == undefined)
-      xhr.responseType = '';
-    else
-      xhr.responseType = type;
-
-    xhr.onreadystatechange = function() {
-      if (xhr.readyState === XMLHttpRequest.DONE) {
-        if (typeof callback === 'function')
-          callback();
-      }
-    };
-
-    xhr.open(method, url, async, user, password);
-    xhr.withCredentials = withCredentials;
-
-    for (let i = 0; i < headers.length; ++i)
-      xhr.setRequestHeader(headers[i][0], headers[i][1]);
-
-    try { xhr.send(payload); } catch (e) {}
-  }
-
-  function makeXHRForJSONArguments(jsonArgs) {
-    let args = JSON.parse(jsonArgs);
-
-    makeXHR(
-      args.method,
-      args.url,
-      args.async,
-      args.user,
-      args.password,
-      args.headers || [],
-      args.withCredentials,
-      args.payload,
-      args.type,
-      xhrLoadedCallback
-    );
-  }
-
-  function makeFetch(url, requestInitializer) {
-    return fetch(url, requestInitializer).then(res => {
-      res.text();
-      return res;
-    }).catch(e => e);
-  }
-
-  function makeFetchInWorker(url, requestInitializer) {
-    return new Promise(resolve => {
-      let worker = new Worker('/devtools/network/resources/fetch-worker.js');
-
-      worker.onmessage = event => {
-        resolve(event.data);
-      };
-
-      worker.postMessage({
-        url: url,
-        init: requestInitializer
-      });
-    });
-  }
-`);
diff --git a/front_end/network_test_runner/ProductRegistryTestRunner.js b/front_end/network_test_runner/ProductRegistryTestRunner.js
deleted file mode 100644
index 0fb85dd..0000000
--- a/front_end/network_test_runner/ProductRegistryTestRunner.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-NetworkTestRunner.resetProductRegistry = function() {
-  TestRunner.addResult('Cleared ProductRegistryImpl');
-  ProductRegistryImpl._productsByDomainHash.clear();
-};
-
-NetworkTestRunner.addProductRegistryEntry = function(domainPattern, productName, type) {
-  TestRunner.addResult('Adding entry: ' + domainPattern);
-  const wildCardPosition = domainPattern.indexOf('*');
-  let prefix = '';
-
-  if (wildCardPosition === -1) {
-  } else if (wildCardPosition === 0) {
-    prefix = '*';
-    console.assert(domainPattern.substr(1, 1) === '.', 'Domain pattern wildcard must be followed by \'.\'');
-    domainPattern = domainPattern.substr(2);
-  } else {
-    prefix = domainPattern.substr(0, wildCardPosition);
-    console.assert(
-        domainPattern.substr(wildCardPosition + 1, 1) === '.', 'Domain pattern wildcard must be followed by \'.\'');
-    domainPattern = domainPattern.substr(wildCardPosition + 2);
-  }
-
-  console.assert(domainPattern.indexOf('*') === -1, 'Domain pattern may only have 1 wildcard.');
-  const prefixes = {};
-
-  prefixes[prefix] = {product: 0, type: type};
-
-  ProductRegistryImpl.register(
-      [productName], [{hash: ProductRegistryImpl._hashForDomain(domainPattern), prefixes: prefixes}]);
-};
diff --git a/front_end/network_test_runner/module.json b/front_end/network_test_runner/module.json
deleted file mode 100644
index 0bdf090..0000000
--- a/front_end/network_test_runner/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "product_registry_impl",
-    "console_test_runner"
-  ],
-  "scripts": [
-    "NetworkTestRunner.js",
-    "ProductRegistryTestRunner.js"
-  ],
-  "skip_compilation": [
-    "NetworkTestRunner.js",
-    "ProductRegistryTestRunner.js"
-  ]
-}
diff --git a/front_end/node_app.html b/front_end/node_app.html
deleted file mode 100644
index 6b9ddcd..0000000
--- a/front_end/node_app.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <meta name="referrer" content="no-referrer">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="node_app.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/node_app.js b/front_end/node_app.js
deleted file mode 100644
index 6517c7d..0000000
--- a/front_end/node_app.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Runtime.startApplication('node_app');
diff --git a/front_end/node_app.json b/front_end/node_app.json
deleted file mode 100644
index 35f77b3..0000000
--- a/front_end/node_app.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "modules" : [
-    { "name": "node_main", "type": "autostart" },
-    { "name": "node_debugger" },
-    { "name": "js_profiler" }
-  ],
-  "extends": "shell",
-  "has_html": true
-}
diff --git a/front_end/node_debugger/module.json b/front_end/node_debugger/module.json
deleted file mode 100644
index b375368..0000000
--- a/front_end/node_debugger/module.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "navigator-view",
-            "id": "navigator-network",
-            "title": "Node",
-            "order": 2,
-            "persistence": "permanent",
-            "className": "Sources.NetworkNavigatorView"
-        }
-    ],
-    "dependencies": [
-        "sources"
-    ]
-}
diff --git a/front_end/node_main/NodeConnectionsPanel.js b/front_end/node_main/NodeConnectionsPanel.js
deleted file mode 100644
index ddc77d1..0000000
--- a/front_end/node_main/NodeConnectionsPanel.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-NodeMain.NodeConnectionsPanel = class extends UI.Panel {
-  constructor() {
-    super('node-connection');
-    this.registerRequiredCSS('node_main/nodeConnectionsPanel.css');
-    this.contentElement.classList.add('node-panel');
-
-    const container = this.contentElement.createChild('div', 'node-panel-center');
-
-    const image = container.createChild('img', 'node-panel-logo');
-    image.src = 'https://nodejs.org/static/images/logos/nodejs-new-pantone-black.png';
-
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this);
-
-    /** @type {!Adb.Config} */
-    this._config;
-
-    this.contentElement.tabIndex = 0;
-    this.setDefaultFocusedElement(this.contentElement);
-
-    // Trigger notification once.
-    InspectorFrontendHost.setDevicesUpdatesEnabled(false);
-    InspectorFrontendHost.setDevicesUpdatesEnabled(true);
-
-    this._networkDiscoveryView = new NodeMain.NodeConnectionsView(config => {
-      this._config.networkDiscoveryConfig = config;
-      InspectorFrontendHost.setDevicesDiscoveryConfig(this._config);
-    });
-    this._networkDiscoveryView.show(container);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _devicesDiscoveryConfigChanged(event) {
-    this._config = /** @type {!Adb.Config} */ (event.data);
-    this._networkDiscoveryView.discoveryConfigChanged(this._config.networkDiscoveryConfig);
-  }
-};
-
-/**
- * @implements {UI.ListWidget.Delegate<Adb.PortForwardingRule>}
- */
-NodeMain.NodeConnectionsView = class extends UI.VBox {
-  /**
-   * @param {function(!Adb.NetworkDiscoveryConfig)} callback
-   */
-  constructor(callback) {
-    super();
-    this._callback = callback;
-    this.element.classList.add('network-discovery-view');
-
-    const networkDiscoveryFooter = this.element.createChild('div', 'network-discovery-footer');
-    networkDiscoveryFooter.createChild('span').textContent =
-        Common.UIString('Specify network endpoint and DevTools will connect to it automatically. ');
-    const link = networkDiscoveryFooter.createChild('span', 'link');
-    link.textContent = Common.UIString('Learn more');
-    link.addEventListener('click', () => InspectorFrontendHost.openInNewTab('https://nodejs.org/en/docs/inspector/'));
-
-    /** @type {!UI.ListWidget<!Adb.PortForwardingRule>} */
-    this._list = new UI.ListWidget(this);
-    this._list.registerRequiredCSS('node_main/nodeConnectionsPanel.css');
-    this._list.element.classList.add('network-discovery-list');
-    const placeholder = createElementWithClass('div', 'network-discovery-list-empty');
-    placeholder.textContent = Common.UIString('No connections specified');
-    this._list.setEmptyPlaceholder(placeholder);
-    this._list.show(this.element);
-    /** @type {?UI.ListWidget.Editor<!Adb.PortForwardingRule>} */
-    this._editor = null;
-
-    const addButton = UI.createTextButton(
-        Common.UIString('Add connection'), this._addNetworkTargetButtonClicked.bind(this), 'add-network-target-button',
-        true /* primary */);
-    this.element.appendChild(addButton);
-
-    /** @type {!Array<{address: string}>} */
-    this._networkDiscoveryConfig = [];
-
-    this.element.classList.add('node-frontend');
-  }
-
-  _update() {
-    const config = this._networkDiscoveryConfig.map(item => item.address);
-    this._callback.call(null, config);
-  }
-
-  _addNetworkTargetButtonClicked() {
-    this._list.addNewItem(this._networkDiscoveryConfig.length, {address: '', port: ''});
-  }
-
-  /**
-   * @param {!Adb.NetworkDiscoveryConfig} networkDiscoveryConfig
-   */
-  discoveryConfigChanged(networkDiscoveryConfig) {
-    this._networkDiscoveryConfig = [];
-    this._list.clear();
-    for (const address of networkDiscoveryConfig) {
-      const item = {address: address, port: ''};
-      this._networkDiscoveryConfig.push(item);
-      this._list.appendItem(item, true);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(rule, editable) {
-    const element = createElementWithClass('div', 'network-discovery-list-item');
-    element.createChild('div', 'network-discovery-value network-discovery-address').textContent = rule.address;
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @param {number} index
-   */
-  removeItemRequested(rule, index) {
-    this._networkDiscoveryConfig.splice(index, 1);
-    this._list.removeItem(index);
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(rule, editor, isNew) {
-    rule.address = editor.control('address').value.trim();
-    if (isNew)
-      this._networkDiscoveryConfig.push(rule);
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {!Adb.PortForwardingRule} rule
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(rule) {
-    const editor = this._createEditor();
-    editor.control('address').value = rule.address;
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor<!Adb.PortForwardingRule>}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._editor = editor;
-    const content = editor.contentElement();
-    const fields = content.createChild('div', 'network-discovery-edit-row');
-    const input = editor.createInput('address', 'text', 'Network address (e.g. localhost:9229)', addressValidator);
-    fields.createChild('div', 'network-discovery-value network-discovery-address').appendChild(input);
-    return editor;
-
-    /**
-     * @param {!Adb.PortForwardingRule} rule
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function addressValidator(rule, index, input) {
-      const match = input.value.trim().match(/^([a-zA-Z0-9\.\-_]+):(\d+)$/);
-      if (!match)
-        return false;
-      const port = parseInt(match[2], 10);
-      return port <= 65535;
-    }
-  }
-};
diff --git a/front_end/node_main/NodeMain.js b/front_end/node_main/NodeMain.js
deleted file mode 100644
index 28dc0b4..0000000
--- a/front_end/node_main/NodeMain.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.Runnable}
- */
-NodeMain.NodeMain = class extends Common.Object {
-  /**
-   * @override
-   */
-  run() {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConnectToNodeJSFromFrontend);
-    const target = SDK.targetManager.createTarget(
-        'main', Common.UIString('Main'), SDK.Target.Capability.Target, params => new SDK.MainConnection(params), null);
-    target.setInspectedURL('Node.js');
-    InspectorFrontendHost.connectionReady();
-  }
-};
-
-/**
- * @implements {Protocol.TargetDispatcher}
- */
-NodeMain.NodeChildTargetManager = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} parentTarget
-   */
-  constructor(parentTarget) {
-    super(parentTarget);
-    this._targetManager = parentTarget.targetManager();
-    this._parentTarget = parentTarget;
-    this._targetAgent = parentTarget.targetAgent();
-    /** @type {!Map<string, !SDK.ChildConnection>} */
-    this._childConnections = new Map();
-
-    parentTarget.registerTargetDispatcher(this);
-    this._targetAgent.setDiscoverTargets(true);
-
-    InspectorFrontendHost.setDevicesUpdatesEnabled(true);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _devicesDiscoveryConfigChanged(event) {
-    const config = /** @type {!Adb.Config} */ (event.data);
-    const locations = [];
-    for (const address of config.networkDiscoveryConfig) {
-      const parts = address.split(':');
-      const port = parseInt(parts[1], 10);
-      if (parts[0] && port)
-        locations.push({host: parts[0], port: port});
-    }
-    this._targetAgent.setRemoteLocations(locations);
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    InspectorFrontendHost.events.removeEventListener(
-        InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this);
-
-    for (const sessionId of this._childConnections.keys())
-      this.detachedFromTarget(sessionId, undefined);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   */
-  targetCreated(targetInfo) {
-    if (targetInfo.type === 'node' && !targetInfo.attached)
-      this._targetAgent.attachToTarget(targetInfo.targetId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   */
-  targetInfoChanged(targetInfo) {
-  }
-
-  /**
-   * @override
-   * @param {string} targetId
-   */
-  targetDestroyed(targetId) {
-  }
-
-  /**
-   * @override
-   * @param {string} sessionId
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   * @param {boolean} waitingForDebugger
-   */
-  attachedToTarget(sessionId, targetInfo, waitingForDebugger) {
-    const target = this._targetManager.createTarget(
-        targetInfo.targetId, Common.UIString('Node.js: %s', targetInfo.url), SDK.Target.Capability.JS,
-        this._createChildConnection.bind(this, this._targetAgent, sessionId), this._parentTarget);
-    target.runtimeAgent().runIfWaitingForDebugger();
-  }
-
-  /**
-   * @override
-   * @param {string} sessionId
-   * @param {string=} childTargetId
-   */
-  detachedFromTarget(sessionId, childTargetId) {
-    this._childConnections.get(sessionId).onDisconnect.call(null, 'target terminated');
-    this._childConnections.delete(sessionId);
-  }
-
-  /**
-   * @override
-   * @param {string} sessionId
-   * @param {string} message
-   * @param {string=} childTargetId
-   */
-  receivedMessageFromTarget(sessionId, message, childTargetId) {
-    const connection = this._childConnections.get(sessionId);
-    if (connection)
-      connection.onMessage.call(null, message);
-  }
-
-  /**
-   * @param {!Protocol.TargetAgent} agent
-   * @param {string} sessionId
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   * @return {!Protocol.InspectorBackend.Connection}
-   */
-  _createChildConnection(agent, sessionId, params) {
-    const connection = new SDK.ChildConnection(agent, sessionId, params);
-    this._childConnections.set(sessionId, connection);
-    return connection;
-  }
-};
-
-SDK.SDKModel.register(NodeMain.NodeChildTargetManager, SDK.Target.Capability.Target, true);
diff --git a/front_end/node_main/module.json b/front_end/node_main/module.json
deleted file mode 100644
index 2a1b133..0000000
--- a/front_end/node_main/module.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "early-initialization",
-            "className": "NodeMain.NodeMain"
-        },
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "node-connection",
-            "title": "Connection",
-            "order": 0,
-            "className": "NodeMain.NodeConnectionsPanel",
-            "tags": "node"
-        }
-    ],
-    "dependencies": ["platform", "ui", "host", "components"],
-    "scripts": [
-        "NodeConnectionsPanel.js",
-        "NodeMain.js"
-    ],
-    "resources": [
-        "nodeConnectionsPanel.css"
-    ]
-}
diff --git a/front_end/node_main/nodeConnectionsPanel.css b/front_end/node_main/nodeConnectionsPanel.css
deleted file mode 100644
index 5f4e875..0000000
--- a/front_end/node_main/nodeConnectionsPanel.css
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.network-discovery-header {
-    display: flex;
-    align-items: center;
-    flex-direction: row;
-    margin-top: 5px;
-}
-
-.add-network-target-button {
-    margin: 10px 25px;
-    align-self: flex-start;
-}
-
-.network-discovery-list {
-    margin: 10px 0 0 25px;
-    max-width: 500px;
-    flex: none;
-}
-
-.network-discovery-list-empty {
-    flex: auto;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.network-discovery-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    position: relative;
-    flex: auto 1 1;
-}
-
-.list-item .network-discovery-value {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -webkit-user-select: none;
-    color: #222;
-    overflow: hidden;
-}
-
-.network-discovery-value {
-    flex: 3 1 0;
-}
-
-.network-discovery-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 6px 5px;
-    align-items: center;
-}
-
-.network-discovery-edit-row input {
-    width: 100%;
-    text-align: inherit;
-}
-
-.network-discovery-footer {
-    overflow: hidden;
-    margin: 15px 0 0 25px;
-    max-width: 500px;
-}
-
-.network-discovery-footer > * {
-    white-space: pre-wrap;
-}
-
-.network-discovery-header {
-    display: none;
-}
-
-.node-panel {
-    align-items: center;
-    justify-content: flex-start;
-}
-
-.network-discovery-view {
-    min-width: 400px;
-    flex: auto;
-}
-
-.add-network-target-button {
-    align-self: center;
-}
-
-:host-context(.node-frontend) .network-discovery-list-empty {
-    height: 40px;
-}
-
-:host-context(.node-frontend) .network-discovery-list-item {
-    padding: 3px 15px;
-    height: 40px;
-}
-
-.network-discovery-list {
-    margin: 20px 0 5px 0;
-    max-width: 600px;
-    max-height: 202px;
-}
-
-.network-discovery-footer {
-    margin: 0;
-}
-
-.node-panel-center {
-    display: flex;
-    align-items: stretch;
-    justify-content: center;
-    max-width: 600px;
-    flex-direction: column;
-    padding-top: 50px;
-}
-
-.node-panel-logo {
-    align-self: center;
-    width: 400px;
-    margin-bottom: 50px;
-    flex: none;
-}
-
-:host-context(.node-frontend) .network-discovery-edit-row input {
-    height: 30px;
-    padding-left: 5px;
-}
-
-:host-context(.node-frontend) .network-discovery-edit-row {
-    margin: 6px 9px;
-}
diff --git a/front_end/object_ui/CustomPreviewComponent.js b/front_end/object_ui/CustomPreviewComponent.js
deleted file mode 100644
index b3094cf..0000000
--- a/front_end/object_ui/CustomPreviewComponent.js
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-ObjectUI.CustomPreviewSection = class {
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  constructor(object) {
-    this._sectionElement = createElementWithClass('span', 'custom-expandable-section');
-    this._object = object;
-    this._expanded = false;
-    this._cachedContent = null;
-    const customPreview = object.customPreview();
-
-    let headerJSON;
-    try {
-      headerJSON = JSON.parse(customPreview.header);
-    } catch (e) {
-      Common.console.error('Broken formatter: header is invalid json ' + e);
-      return;
-    }
-    this._header = this._renderJSONMLTag(headerJSON);
-    if (this._header.nodeType === Node.TEXT_NODE) {
-      Common.console.error('Broken formatter: header should be an element node.');
-      return;
-    }
-
-    if (customPreview.hasBody) {
-      this._header.classList.add('custom-expandable-section-header');
-      this._header.addEventListener('click', this._onClick.bind(this), false);
-      this._expandIcon = UI.Icon.create('smallicon-triangle-right', 'custom-expand-icon');
-      this._header.insertBefore(this._expandIcon, this._header.firstChild);
-    }
-
-    this._sectionElement.appendChild(this._header);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._sectionElement;
-  }
-
-  /**
-   * @param {*} jsonML
-   * @return {!Node}
-   */
-  _renderJSONMLTag(jsonML) {
-    if (!Array.isArray(jsonML))
-      return createTextNode(jsonML + '');
-
-    const array = /** @type {!Array.<*>} */ (jsonML);
-    return array[0] === 'object' ? this._layoutObjectTag(array) : this._renderElement(array);
-  }
-
-  /**
-   *
-   * @param {!Array.<*>} object
-   * @return {!Node}
-   */
-  _renderElement(object) {
-    const tagName = object.shift();
-    if (!ObjectUI.CustomPreviewSection._tagsWhiteList.has(tagName)) {
-      Common.console.error('Broken formatter: element ' + tagName + ' is not allowed!');
-      return createElement('span');
-    }
-    const element = createElement(/** @type {string} */ (tagName));
-    if ((typeof object[0] === 'object') && !Array.isArray(object[0])) {
-      const attributes = object.shift();
-      for (const key in attributes) {
-        const value = attributes[key];
-        if ((key !== 'style') || (typeof value !== 'string'))
-          continue;
-
-        element.setAttribute(key, value);
-      }
-    }
-
-    this._appendJsonMLTags(element, object);
-    return element;
-  }
-
-  /**
-   * @param {!Array.<*>} objectTag
-   * @return {!Node}
-   */
-  _layoutObjectTag(objectTag) {
-    objectTag.shift();
-    const attributes = objectTag.shift();
-    const remoteObject = this._object.runtimeModel().createRemoteObject(
-        /** @type {!Protocol.Runtime.RemoteObject} */ (attributes));
-    if (remoteObject.customPreview())
-      return (new ObjectUI.CustomPreviewSection(remoteObject)).element();
-
-    const sectionElement = ObjectUI.ObjectPropertiesSection.defaultObjectPresentation(remoteObject);
-    sectionElement.classList.toggle('custom-expandable-section-standard-section', remoteObject.hasChildren);
-    return sectionElement;
-  }
-
-  /**
-   * @param {!Node} parentElement
-   * @param {!Array.<*>} jsonMLTags
-   */
-  _appendJsonMLTags(parentElement, jsonMLTags) {
-    for (let i = 0; i < jsonMLTags.length; ++i)
-      parentElement.appendChild(this._renderJSONMLTag(jsonMLTags[i]));
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    event.consume(true);
-    if (this._cachedContent)
-      this._toggleExpand();
-    else
-      this._loadBody();
-  }
-
-  _toggleExpand() {
-    this._expanded = !this._expanded;
-    this._header.classList.toggle('expanded', this._expanded);
-    this._cachedContent.classList.toggle('hidden', !this._expanded);
-    if (this._expanded)
-      this._expandIcon.setIconType('smallicon-triangle-down');
-    else
-      this._expandIcon.setIconType('smallicon-triangle-right');
-  }
-
-  _loadBody() {
-    /**
-     * @suppressReceiverCheck
-     * @suppressGlobalPropertiesCheck
-     * @suppress {undefinedVars}
-     * @this {Object}
-     * @param {function(!Object, *):*} bindRemoteObject
-     * @param {*=} formatter
-     * @param {*=} config
-     */
-    function load(bindRemoteObject, formatter, config) {
-      /**
-       * @param {*} jsonMLObject
-       * @throws {string} error message
-       */
-      function substituteObjectTagsInCustomPreview(jsonMLObject) {
-        if (!jsonMLObject || (typeof jsonMLObject !== 'object') || (typeof jsonMLObject.splice !== 'function'))
-          return;
-
-        const obj = jsonMLObject.length;
-        if (!(typeof obj === 'number' && obj >>> 0 === obj && (obj > 0 || 1 / obj > 0)))
-          return;
-
-        let startIndex = 1;
-        if (jsonMLObject[0] === 'object') {
-          const attributes = jsonMLObject[1];
-          const originObject = attributes['object'];
-          const config = attributes['config'];
-          if (typeof originObject === 'undefined')
-            throw 'Illegal format: obligatory attribute "object" isn\'t specified';
-
-          jsonMLObject[1] = bindRemoteObject(originObject, config);
-          startIndex = 2;
-        }
-        for (let i = startIndex; i < jsonMLObject.length; ++i)
-          substituteObjectTagsInCustomPreview(jsonMLObject[i]);
-      }
-
-      try {
-        const body = formatter.body(this, config);
-        substituteObjectTagsInCustomPreview(body);
-        return body;
-      } catch (e) {
-        console.error('Custom Formatter Failed: ' + e);
-        return null;
-      }
-    }
-
-    const customPreview = this._object.customPreview();
-    const args = [{objectId: customPreview.bindRemoteObjectFunctionId}, {objectId: customPreview.formatterObjectId}];
-    if (customPreview.configObjectId)
-      args.push({objectId: customPreview.configObjectId});
-    this._object.callFunctionJSON(load, args, onBodyLoaded.bind(this));
-
-    /**
-     * @param {*} bodyJsonML
-     * @this {ObjectUI.CustomPreviewSection}
-     */
-    function onBodyLoaded(bodyJsonML) {
-      if (!bodyJsonML)
-        return;
-
-      this._cachedContent = this._renderJSONMLTag(bodyJsonML);
-      this._sectionElement.appendChild(this._cachedContent);
-      this._toggleExpand();
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-ObjectUI.CustomPreviewComponent = class {
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  constructor(object) {
-    this._object = object;
-    this._customPreviewSection = new ObjectUI.CustomPreviewSection(object);
-    this.element = createElementWithClass('span', 'source-code');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'object_ui/customPreviewComponent.css');
-    this.element.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), false);
-    shadowRoot.appendChild(this._customPreviewSection.element());
-  }
-
-  expandIfPossible() {
-    if (this._object.customPreview().hasBody && this._customPreviewSection)
-      this._customPreviewSection._loadBody();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _contextMenuEventFired(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    if (this._customPreviewSection) {
-      contextMenu.revealSection().appendItem(
-          Common.UIString('Show as JavaScript object'), this._disassemble.bind(this));
-    }
-    contextMenu.appendApplicableItems(this._object);
-    contextMenu.show();
-  }
-
-  _disassemble() {
-    this.element.shadowRoot.textContent = '';
-    this._customPreviewSection = null;
-    this.element.shadowRoot.appendChild(ObjectUI.ObjectPropertiesSection.defaultObjectPresentation(this._object));
-  }
-};
-
-ObjectUI.CustomPreviewSection._tagsWhiteList = new Set(['span', 'div', 'ol', 'li', 'table', 'tr', 'td']);
diff --git a/front_end/object_ui/JavaScriptAutocomplete.js b/front_end/object_ui/JavaScriptAutocomplete.js
deleted file mode 100644
index 4a2850d..0000000
--- a/front_end/object_ui/JavaScriptAutocomplete.js
+++ /dev/null
@@ -1,478 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-ObjectUI.JavaScriptAutocomplete = class {
-  constructor() {
-    /** @type {!Map<string, {date: number, value: !Promise<?Object>}>} */
-    this._expressionCache = new Map();
-    SDK.consoleModel.addEventListener(SDK.ConsoleModel.Events.CommandEvaluated, this._clearCache, this);
-    SDK.targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextChanged, this._clearCache, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._clearCache, this);
-  }
-
-  _clearCache() {
-    this._expressionCache.clear();
-  }
-
-  /**
-   * @param {string} text
-   * @param {string} query
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  completionsForTextInCurrentContext(text, query, force) {
-    const clippedExpression = this._clipExpression(text, true);
-    const mapCompletionsPromise = this._mapCompletions(text, query);
-    return this._completionsForExpression(clippedExpression, query, force)
-        .then(completions => mapCompletionsPromise.then(mapCompletions => mapCompletions.concat(completions)));
-  }
-
-  /**
-   * @param {string} text
-   * @param {boolean=} allowEndingBracket
-   * @return {string}
-   */
-  _clipExpression(text, allowEndingBracket) {
-    let index;
-    const stopChars = new Set('=:({;,!+-*/&|^<>`'.split(''));
-    const whiteSpaceChars = new Set(' \r\n\t'.split(''));
-    const continueChars = new Set('[. \r\n\t'.split(''));
-
-    for (index = text.length - 1; index >= 0; index--) {
-      if (stopChars.has(text.charAt(index)))
-        break;
-      if (whiteSpaceChars.has(text.charAt(index)) && !continueChars.has(text.charAt(index - 1)))
-        break;
-    }
-    const clippedExpression = text.substring(index + 1).trim();
-    let bracketCount = 0;
-
-    index = clippedExpression.length - 1;
-    while (index >= 0) {
-      const character = clippedExpression.charAt(index);
-      if (character === ']')
-        bracketCount++;
-      // Allow an open bracket at the end for property completion.
-      if (character === '[' && (index < clippedExpression.length - 1 || !allowEndingBracket)) {
-        bracketCount--;
-        if (bracketCount < 0)
-          break;
-      }
-      index--;
-    }
-    return clippedExpression.substring(index + 1).trim();
-  }
-
-  /**
-   * @param {string} text
-   * @param {string} query
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  async _mapCompletions(text, query) {
-    const mapMatch = text.match(/\.\s*(get|set|delete)\s*\(\s*$/);
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext || !mapMatch)
-      return [];
-
-    const clippedExpression = this._clipExpression(text.substring(0, mapMatch.index));
-    const result = await executionContext.evaluate(
-        {
-          expression: clippedExpression,
-          objectGroup: 'completion',
-          includeCommandLineAPI: true,
-          silent: true,
-          returnByValue: false,
-          generatePreview: false
-        },
-        /* userGesture */ false, /* awaitPromise */ false);
-    if (result.error || !!result.exceptionDetails || result.object.subtype !== 'map')
-      return [];
-    const properties = await result.object.getOwnPropertiesPromise(false);
-    const internalProperties = properties.internalProperties || [];
-    const entriesProperty = internalProperties.find(property => property.name === '[[Entries]]');
-    if (!entriesProperty)
-      return [];
-    const keysObj = await entriesProperty.value.callFunctionJSONPromise(getEntries);
-    return gotKeys(Object.keys(keysObj));
-
-    /**
-     * @suppressReceiverCheck
-     * @this {!Array<{key:?, value:?}>}
-     * @return {!Object}
-     */
-    function getEntries() {
-      const result = {__proto__: null};
-      for (let i = 0; i < this.length; i++) {
-        if (typeof this[i].key === 'string')
-          result[this[i].key] = true;
-      }
-      return result;
-    }
-
-    /**
-     * @param {!Array<string>} rawKeys
-     * @return {!UI.SuggestBox.Suggestions}
-     */
-    function gotKeys(rawKeys) {
-      const caseSensitivePrefix = [];
-      const caseInsensitivePrefix = [];
-      const caseSensitiveAnywhere = [];
-      const caseInsensitiveAnywhere = [];
-      let quoteChar = '"';
-      if (query.startsWith('\''))
-        quoteChar = '\'';
-      let endChar = ')';
-      if (mapMatch[0].indexOf('set') !== -1)
-        endChar = ', ';
-
-      const sorter = rawKeys.length < 1000 ? String.naturalOrderComparator : undefined;
-      const keys = rawKeys.sort(sorter).map(key => quoteChar + key + quoteChar);
-
-      for (const key of keys) {
-        if (key.length < query.length)
-          continue;
-        if (query.length && key.toLowerCase().indexOf(query.toLowerCase()) === -1)
-          continue;
-        // Substitute actual newlines with newline characters. @see crbug.com/498421
-        const title = key.split('\n').join('\\n');
-        const text = title + endChar;
-
-        if (key.startsWith(query))
-          caseSensitivePrefix.push({text: text, title: title, priority: 4});
-        else if (key.toLowerCase().startsWith(query.toLowerCase()))
-          caseInsensitivePrefix.push({text: text, title: title, priority: 3});
-        else if (key.indexOf(query) !== -1)
-          caseSensitiveAnywhere.push({text: text, title: title, priority: 2});
-        else
-          caseInsensitiveAnywhere.push({text: text, title: title, priority: 1});
-      }
-      const suggestions =
-          caseSensitivePrefix.concat(caseInsensitivePrefix, caseSensitiveAnywhere, caseInsensitiveAnywhere);
-      if (suggestions.length)
-        suggestions[0].subtitle = Common.UIString('Keys');
-      return suggestions;
-    }
-  }
-
-  /**
-   * @param {string} expressionString
-   * @param {string} query
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  async _completionsForExpression(expressionString, query, force) {
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext)
-      return [];
-
-    const lastIndex = expressionString.length - 1;
-
-    const dotNotation = (expressionString[lastIndex] === '.');
-    const bracketNotation = (expressionString.length > 1 && expressionString[lastIndex] === '[');
-
-    if (dotNotation || bracketNotation)
-      expressionString = expressionString.substr(0, lastIndex);
-    else
-      expressionString = '';
-
-    // User is entering float value, do not suggest anything.
-    if ((expressionString && !isNaN(expressionString)) || (!expressionString && query && !isNaN(query)))
-      return [];
-
-
-    if (!query && !expressionString && !force)
-      return [];
-    const selectedFrame = executionContext.debuggerModel.selectedCallFrame();
-    let completionGroups;
-    const TEN_SECONDS = 10000;
-    let cache = this._expressionCache.get(expressionString);
-    if (cache && cache.date + TEN_SECONDS > Date.now()) {
-      completionGroups = await cache.value;
-    } else if (!expressionString && selectedFrame) {
-      cache = {date: Date.now(), value: completionsOnPause(selectedFrame)};
-      this._expressionCache.set(expressionString, cache);
-      completionGroups = await cache.value;
-    } else {
-      const resultPromise = executionContext.evaluate(
-          {
-            expression: expressionString,
-            objectGroup: 'completion',
-            includeCommandLineAPI: true,
-            silent: true,
-            returnByValue: false,
-            generatePreview: false
-          },
-          /* userGesture */ false, /* awaitPromise */ false);
-      cache = {date: Date.now(), value: resultPromise.then(result => completionsOnGlobal.call(this, result))};
-      this._expressionCache.set(expressionString, cache);
-      completionGroups = await cache.value;
-    }
-    return this._receivedPropertyNames(
-        completionGroups.slice(0), dotNotation, bracketNotation, expressionString, query);
-
-    /**
-     * @this {ObjectUI.JavaScriptAutocomplete}
-     * @param {!SDK.RuntimeModel.EvaluationResult} result
-     * @return {!Promise<!Array<!ObjectUI.JavaScriptAutocomplete.CompletionGroup>>}
-     */
-    async function completionsOnGlobal(result) {
-      if (result.error || !!result.exceptionDetails || !result.object)
-        return [];
-
-      let object = result.object;
-      while (object && object.type === 'object' && object.subtype === 'proxy') {
-        const properties = await object.getOwnPropertiesPromise(false /* generatePreview */);
-        const internalProperties = properties.internalProperties || [];
-        const target = internalProperties.find(property => property.name === '[[Target]]');
-        object = target ? target.value : null;
-      }
-      if (!object)
-        return [];
-      let completions = [];
-      if (object.type === 'object' || object.type === 'function') {
-        completions =
-            await object.callFunctionJSONPromise(getCompletions, [SDK.RemoteObject.toCallArgument(object.subtype)]) ||
-            [];
-      } else if (
-          object.type === 'string' || object.type === 'number' || object.type === 'boolean' ||
-          object.type === 'bigint') {
-        const evaluateResult = await executionContext.evaluate(
-            {
-              expression: '(' + getCompletions + ')("' + object.type + '")',
-              objectGroup: 'completion',
-              includeCommandLineAPI: false,
-              silent: true,
-              returnByValue: true,
-              generatePreview: false
-            },
-            /* userGesture */ false,
-            /* awaitPromise */ false);
-        if (evaluateResult.object && !evaluateResult.exceptionDetails)
-          completions = evaluateResult.object.value || [];
-      }
-      executionContext.runtimeModel.releaseObjectGroup('completion');
-
-      if (!expressionString) {
-        const globalNames = await executionContext.globalLexicalScopeNames();
-        // Merge lexical scope names with first completion group on global object: let a and let b should be in the same group.
-        if (completions.length)
-          completions[0].items = completions[0].items.concat(globalNames);
-        else
-          completions.push({items: globalNames.sort(), title: Common.UIString('Lexical scope variables')});
-      }
-
-      for (const group of completions) {
-        for (let i = 0; i < group.items.length; i++)
-          group.items[i] = group.items[i].replace(/\n/g, '\\n');
-
-        group.items.sort(group.items.length < 1000 ? this._itemComparator : undefined);
-      }
-
-      return completions;
-
-      /**
-       * @param {string=} type
-       * @return {!Object}
-       * @suppressReceiverCheck
-       * @this {Object}
-       */
-      function getCompletions(type) {
-        let object;
-        if (type === 'string')
-          object = new String('');
-        else if (type === 'number')
-          object = new Number(0);
-        // Object-wrapped BigInts cannot be constructed via `new BigInt`.
-        else if (type === 'bigint')
-          object = Object(BigInt(0));
-        else if (type === 'boolean')
-          object = new Boolean(false);
-        else
-          object = this;
-
-        const result = [];
-        try {
-          for (let o = object; o; o = Object.getPrototypeOf(o)) {
-            if ((type === 'array' || type === 'typedarray') && o === object && o.length > 9999)
-              continue;
-
-            const group = {items: [], __proto__: null};
-            try {
-              if (typeof o === 'object' && o.constructor && o.constructor.name)
-                group.title = o.constructor.name;
-            } catch (ee) {
-              // we could break upon cross origin check.
-            }
-            result[result.length] = group;
-            const names = Object.getOwnPropertyNames(o);
-            const isArray = Array.isArray(o);
-            for (let i = 0; i < names.length && group.items.length < 10000; ++i) {
-              // Skip array elements indexes.
-              if (isArray && /^[0-9]/.test(names[i]))
-                continue;
-              group.items[group.items.length] = names[i];
-            }
-          }
-        } catch (e) {
-        }
-        return result;
-      }
-    }
-
-    /**
-     * @param {!SDK.DebuggerModel.CallFrame} callFrame
-     * @return {!Promise<?Object>}
-     */
-    async function completionsOnPause(callFrame) {
-      const result = [{items: ['this']}];
-      const scopeChain = callFrame.scopeChain();
-      const groupPromises = [];
-      for (const scope of scopeChain) {
-        groupPromises.push(scope.object()
-                               .getAllPropertiesPromise(false /* accessorPropertiesOnly */, false /* generatePreview */)
-                               .then(result => ({properties: result.properties, name: scope.name()})));
-      }
-      const fullScopes = await Promise.all(groupPromises);
-      executionContext.runtimeModel.releaseObjectGroup('completion');
-      for (const scope of fullScopes)
-        result.push({title: scope.name, items: scope.properties.map(property => property.name).sort()});
-      return result;
-    }
-  }
-
-  /**
-   * @param {?Array<!ObjectUI.JavaScriptAutocomplete.CompletionGroup>} propertyGroups
-   * @param {boolean} dotNotation
-   * @param {boolean} bracketNotation
-   * @param {string} expressionString
-   * @param {string} query
-   * @return {!UI.SuggestBox.Suggestions}
-   */
-  _receivedPropertyNames(propertyGroups, dotNotation, bracketNotation, expressionString, query) {
-    if (!propertyGroups)
-      return [];
-    const includeCommandLineAPI = (!dotNotation && !bracketNotation);
-    if (includeCommandLineAPI) {
-      const commandLineAPI = [
-        'dir',
-        'dirxml',
-        'keys',
-        'values',
-        'profile',
-        'profileEnd',
-        'monitorEvents',
-        'unmonitorEvents',
-        'inspect',
-        'copy',
-        'clear',
-        'getEventListeners',
-        'debug',
-        'undebug',
-        'monitor',
-        'unmonitor',
-        'table',
-        'queryObjects',
-        '$',
-        '$$',
-        '$x'
-      ];
-      propertyGroups.push({items: commandLineAPI});
-    }
-    return this._completionsForQuery(dotNotation, bracketNotation, expressionString, query, propertyGroups);
-  }
-
-  /**
-     * @param {boolean} dotNotation
-     * @param {boolean} bracketNotation
-     * @param {string} expressionString
-     * @param {string} query
-     * @param {!Array<!ObjectUI.JavaScriptAutocomplete.CompletionGroup>} propertyGroups
-     * @return {!UI.SuggestBox.Suggestions}
-     */
-  _completionsForQuery(dotNotation, bracketNotation, expressionString, query, propertyGroups) {
-    const quoteUsed = (bracketNotation && query.startsWith('\'')) ? '\'' : '"';
-
-    if (!expressionString) {
-      const keywords = [
-        'break', 'case',     'catch',  'continue', 'default',    'delete', 'do',     'else',   'finally',
-        'for',   'function', 'if',     'in',       'instanceof', 'new',    'return', 'switch', 'this',
-        'throw', 'try',      'typeof', 'var',      'void',       'while',  'with'
-      ];
-      propertyGroups.push({title: Common.UIString('keywords'), items: keywords});
-    }
-
-    let result = [];
-    let lastGroupTitle;
-    const regex = /^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFFFF]*$/;
-    const lowerCaseQuery = query.toLowerCase();
-    for (const group of propertyGroups) {
-      const caseSensitivePrefix = [];
-      const caseInsensitivePrefix = [];
-      const caseSensitiveAnywhere = [];
-      const caseInsensitiveAnywhere = [];
-
-      for (let i = 0; i < group.items.length; i++) {
-        let property = group.items[i];
-        // Assume that all non-ASCII characters are letters and thus can be used as part of identifier.
-        if (!bracketNotation && !regex.test(property))
-          continue;
-
-        if (bracketNotation) {
-          if (!/^[0-9]+$/.test(property))
-            property = quoteUsed + property.escapeCharacters(quoteUsed + '\\') + quoteUsed;
-          property += ']';
-        }
-
-        if (property.length < query.length)
-          continue;
-        const lowerCaseProperty = property.toLowerCase();
-        if (query.length && lowerCaseProperty.indexOf(lowerCaseQuery) === -1)
-          continue;
-
-        if (property.startsWith(query))
-          caseSensitivePrefix.push({text: property, priority: 4});
-        else if (lowerCaseProperty.startsWith(lowerCaseQuery))
-          caseInsensitivePrefix.push({text: property, priority: 3});
-        else if (property.indexOf(query) !== -1)
-          caseSensitiveAnywhere.push({text: property, priority: 2});
-        else
-          caseInsensitiveAnywhere.push({text: property, priority: 1});
-      }
-      const structuredGroup =
-          caseSensitivePrefix.concat(caseInsensitivePrefix, caseSensitiveAnywhere, caseInsensitiveAnywhere);
-      if (structuredGroup.length && group.title !== lastGroupTitle) {
-        structuredGroup[0].subtitle = group.title;
-        lastGroupTitle = group.title;
-      }
-      result = result.concat(structuredGroup);
-      result.forEach(item => {
-        if (item.text.endsWith(']'))
-          item.title = item.text.substring(0, item.text.length - 1);
-      });
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} a
-   * @param {string} b
-   * @return {number}
-   */
-  _itemComparator(a, b) {
-    const aStartsWithUnderscore = a.startsWith('_');
-    const bStartsWithUnderscore = b.startsWith('_');
-    if (aStartsWithUnderscore && !bStartsWithUnderscore)
-      return 1;
-    if (bStartsWithUnderscore && !aStartsWithUnderscore)
-      return -1;
-    return String.naturalOrderComparator(a, b);
-  }
-};
-
-/** @typedef {{title:(string|undefined), items:Array<string>}} */
-ObjectUI.JavaScriptAutocomplete.CompletionGroup;
-
-ObjectUI.javaScriptAutocomplete = new ObjectUI.JavaScriptAutocomplete();
\ No newline at end of file
diff --git a/front_end/object_ui/ObjectPopoverHelper.js b/front_end/object_ui/ObjectPopoverHelper.js
deleted file mode 100644
index a649f89..0000000
--- a/front_end/object_ui/ObjectPopoverHelper.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-ObjectUI.ObjectPopoverHelper = class {
-  /**
-   * @param {?Components.Linkifier} linkifier
-   * @param {boolean} resultHighlightedAsDOM
-   */
-  constructor(linkifier, resultHighlightedAsDOM) {
-    this._linkifier = linkifier;
-    this._resultHighlightedAsDOM = resultHighlightedAsDOM;
-  }
-
-  dispose() {
-    if (this._resultHighlightedAsDOM)
-      SDK.OverlayModel.hideDOMNodeHighlight();
-    if (this._linkifier)
-      this._linkifier.dispose();
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} result
-   * @param {!UI.GlassPane} popover
-   * @return {!Promise<?ObjectUI.ObjectPopoverHelper>}
-   */
-  static buildObjectPopover(result, popover) {
-    let fulfill;
-    const promise = new Promise(x => fulfill = x);
-
-    /**
-     * @param {!SDK.RemoteObject} funcObject
-     * @param {!Element} popoverContentElement
-     * @param {!Element} popoverValueElement
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     */
-    function didGetFunctionProperties(
-        funcObject, popoverContentElement, popoverValueElement, properties, internalProperties) {
-      if (internalProperties) {
-        for (let i = 0; i < internalProperties.length; i++) {
-          if (internalProperties[i].name === '[[TargetFunction]]') {
-            funcObject = internalProperties[i].value;
-            break;
-          }
-        }
-      }
-      ObjectUI.ObjectPropertiesSection.formatObjectAsFunction(funcObject, popoverValueElement, true);
-      funcObject.debuggerModel()
-          .functionDetailsPromise(funcObject)
-          .then(didGetFunctionDetails.bind(null, popoverContentElement));
-    }
-
-    /**
-     * @param {!Element} popoverContentElement
-     * @param {?SDK.DebuggerModel.FunctionDetails} response
-     */
-    function didGetFunctionDetails(popoverContentElement, response) {
-      if (!response) {
-        fulfill(null);
-        return;
-      }
-
-      const container = createElementWithClass('div', 'object-popover-container');
-      const title = container.createChild('div', 'function-popover-title source-code');
-      const functionName = title.createChild('span', 'function-name');
-      functionName.textContent = UI.beautifyFunctionName(response.functionName);
-
-      const rawLocation = response.location;
-      const linkContainer = title.createChild('div', 'function-title-link-container');
-      const sourceURL = rawLocation && rawLocation.script() ? rawLocation.script().sourceURL : null;
-      let linkifier = null;
-      if (rawLocation && sourceURL) {
-        linkifier = new Components.Linkifier();
-        linkContainer.appendChild(linkifier.linkifyRawLocation(rawLocation, sourceURL));
-      }
-      container.appendChild(popoverContentElement);
-      popover.contentElement.appendChild(container);
-      fulfill(new ObjectUI.ObjectPopoverHelper(linkifier, false));
-    }
-
-    const description = result.description.trimEnd(ObjectUI.ObjectPopoverHelper.MaxPopoverTextLength);
-    let popoverContentElement = null;
-    if (result.type !== 'object') {
-      popoverContentElement = createElement('span');
-      UI.appendStyle(popoverContentElement, 'object_ui/objectValue.css');
-      UI.appendStyle(popoverContentElement, 'object_ui/objectPopover.css');
-      const valueElement = popoverContentElement.createChild('span', 'monospace object-value-' + result.type);
-      valueElement.style.whiteSpace = 'pre';
-
-      if (result.type === 'string')
-        valueElement.createTextChildren('"', description, '"');
-      else if (result.type !== 'function')
-        valueElement.textContent = description;
-
-      if (result.type === 'function') {
-        result.getOwnProperties(
-            false /* generatePreview */,
-            didGetFunctionProperties.bind(null, result, popoverContentElement, valueElement));
-        return promise;
-      }
-      popover.contentElement.appendChild(popoverContentElement);
-      fulfill(new ObjectUI.ObjectPopoverHelper(null, false));
-    } else {
-      let linkifier = null;
-      let resultHighlightedAsDOM = false;
-      if (result.subtype === 'node') {
-        SDK.OverlayModel.highlightObjectAsDOMNode(result);
-        resultHighlightedAsDOM = true;
-      }
-
-      if (result.customPreview()) {
-        const customPreviewComponent = new ObjectUI.CustomPreviewComponent(result);
-        customPreviewComponent.expandIfPossible();
-        popoverContentElement = customPreviewComponent.element;
-      } else {
-        popoverContentElement = createElementWithClass('div', 'object-popover-content');
-        UI.appendStyle(popoverContentElement, 'object_ui/objectPopover.css');
-        const titleElement = popoverContentElement.createChild('div', 'monospace object-popover-title');
-        titleElement.createChild('span').textContent = description;
-        linkifier = new Components.Linkifier();
-        const section = new ObjectUI.ObjectPropertiesSection(result, '', linkifier);
-        section.element.classList.add('object-popover-tree');
-        section.titleLessMode();
-        popoverContentElement.appendChild(section.element);
-      }
-      popover.setMaxContentSize(new UI.Size(300, 250));
-      popover.setSizeBehavior(UI.GlassPane.SizeBehavior.SetExactSize);
-      popover.contentElement.appendChild(popoverContentElement);
-      fulfill(new ObjectUI.ObjectPopoverHelper(linkifier, resultHighlightedAsDOM));
-    }
-    return promise;
-  }
-};
-
-ObjectUI.ObjectPopoverHelper.MaxPopoverTextLength = 10000;
diff --git a/front_end/object_ui/ObjectPropertiesSection.js b/front_end/object_ui/ObjectPropertiesSection.js
deleted file mode 100644
index ca4d3be..0000000
--- a/front_end/object_ui/ObjectPropertiesSection.js
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-ObjectUI.ObjectPropertiesSection = class extends UI.TreeOutlineInShadow {
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {?string|!Element=} title
-   * @param {!Components.Linkifier=} linkifier
-   * @param {?string=} emptyPlaceholder
-   * @param {boolean=} ignoreHasOwnProperty
-   * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties
-   */
-  constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) {
-    super();
-    this._object = object;
-    this._editable = true;
-    this.hideOverflow();
-    this.setFocusable(false);
-    this._objectTreeElement = new ObjectUI.ObjectPropertiesSection.RootElement(
-        object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties);
-    this.appendChild(this._objectTreeElement);
-    if (typeof title === 'string' || !title) {
-      this.titleElement = this.element.createChild('span');
-      this.titleElement.textContent = title || '';
-    } else {
-      this.titleElement = title;
-      this.element.appendChild(title);
-    }
-
-    this.element._section = this;
-    this.registerRequiredCSS('object_ui/objectValue.css');
-    this.registerRequiredCSS('object_ui/objectPropertiesSection.css');
-    this.rootElement().childrenListElement.classList.add('source-code', 'object-properties-section');
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {!Components.Linkifier=} linkifier
-   * @param {boolean=} skipProto
-   * @return {!Element}
-   */
-  static defaultObjectPresentation(object, linkifier, skipProto) {
-    const componentRoot = createElementWithClass('span', 'source-code');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(componentRoot, 'object_ui/objectValue.css');
-    shadowRoot.appendChild(
-        ObjectUI.ObjectPropertiesSection.createValueElement(object, false /* wasThrown */, true /* showPreview */));
-    if (!object.hasChildren)
-      return componentRoot;
-
-    const objectPropertiesSection = new ObjectUI.ObjectPropertiesSection(object, componentRoot, linkifier);
-    objectPropertiesSection.editable = false;
-    if (skipProto)
-      objectPropertiesSection.skipProto();
-
-    return objectPropertiesSection.element;
-  }
-
-  /**
-   * @param {!SDK.RemoteObjectProperty} propertyA
-   * @param {!SDK.RemoteObjectProperty} propertyB
-   * @return {number}
-   */
-  static CompareProperties(propertyA, propertyB) {
-    const a = propertyA.name;
-    const b = propertyB.name;
-    if (a === '__proto__')
-      return 1;
-    if (b === '__proto__')
-      return -1;
-    if (!propertyA.enumerable && propertyB.enumerable)
-      return 1;
-    if (!propertyB.enumerable && propertyA.enumerable)
-      return -1;
-    if (a.startsWith('_') && !b.startsWith('_'))
-      return 1;
-    if (b.startsWith('_') && !a.startsWith('_'))
-      return -1;
-    if (propertyA.symbol && !propertyB.symbol)
-      return 1;
-    if (propertyB.symbol && !propertyA.symbol)
-      return -1;
-    return String.naturalOrderComparator(a, b);
-  }
-
-  /**
-   * @param {?string} name
-   * @return {!Element}
-   */
-  static createNameElement(name) {
-    const nameElement = createElementWithClass('span', 'name');
-    if (/^\s|\s$|^$|\n/.test(name))
-      nameElement.createTextChildren('"', name.replace(/\n/g, '\u21B5'), '"');
-    else
-      nameElement.textContent = name;
-    return nameElement;
-  }
-
-  /**
-   * @param {?string=} description
-   * @param {boolean=} includePreview
-   * @param {string=} defaultName
-   * @return {!Element} valueElement
-   */
-  static valueElementForFunctionDescription(description, includePreview, defaultName) {
-    const valueElement = createElementWithClass('span', 'object-value-function');
-    let text = '';
-    if (description) {
-      text = description.replace(/^function [gs]et /, 'function ')
-                 .replace(/^function [gs]et\(/, 'function\(')
-                 .replace(/^[gs]et /, '');
-    }
-    defaultName = defaultName || '';
-
-    // This set of best-effort regular expressions captures common function descriptions.
-    // Ideally, some parser would provide prefix, arguments, function body text separately.
-    const asyncMatch = text.match(/^(async\s+function)/);
-    const isGenerator = text.startsWith('function*');
-    const isGeneratorShorthand = text.startsWith('*');
-    const isBasic = !isGenerator && text.startsWith('function');
-    const isClass = text.startsWith('class ') || text.startsWith('class{');
-    const firstArrowIndex = text.indexOf('=>');
-    const isArrow = !asyncMatch && !isGenerator && !isBasic && !isClass && firstArrowIndex > 0;
-
-    let textAfterPrefix;
-    if (isClass) {
-      textAfterPrefix = text.substring('class'.length);
-      const classNameMatch = /^[^{\s]+/.exec(textAfterPrefix.trim());
-      let className = defaultName;
-      if (classNameMatch)
-        className = classNameMatch[0].trim() || defaultName;
-      addElements('class', textAfterPrefix, className);
-    } else if (asyncMatch) {
-      textAfterPrefix = text.substring(asyncMatch[1].length);
-      addElements('async \u0192', textAfterPrefix, nameAndArguments(textAfterPrefix));
-    } else if (isGenerator) {
-      textAfterPrefix = text.substring('function*'.length);
-      addElements('\u0192*', textAfterPrefix, nameAndArguments(textAfterPrefix));
-    } else if (isGeneratorShorthand) {
-      textAfterPrefix = text.substring('*'.length);
-      addElements('\u0192*', textAfterPrefix, nameAndArguments(textAfterPrefix));
-    } else if (isBasic) {
-      textAfterPrefix = text.substring('function'.length);
-      addElements('\u0192', textAfterPrefix, nameAndArguments(textAfterPrefix));
-    } else if (isArrow) {
-      const maxArrowFunctionCharacterLength = 60;
-      let abbreviation = text;
-      if (defaultName)
-        abbreviation = defaultName + '()';
-      else if (text.length > maxArrowFunctionCharacterLength)
-        abbreviation = text.substring(0, firstArrowIndex + 2) + ' {\u2026}';
-      addElements('', text, abbreviation);
-    } else {
-      addElements('\u0192', text, nameAndArguments(text));
-    }
-    valueElement.title = description || '';
-    return valueElement;
-
-    /**
-     * @param {string} contents
-     * @return {string}
-     */
-    function nameAndArguments(contents) {
-      const startOfArgumentsIndex = contents.indexOf('(');
-      const endOfArgumentsMatch = contents.match(/\)\s*{/);
-      if (startOfArgumentsIndex !== -1 && endOfArgumentsMatch && endOfArgumentsMatch.index > startOfArgumentsIndex) {
-        const name = contents.substring(0, startOfArgumentsIndex).trim() || defaultName;
-        const args = contents.substring(startOfArgumentsIndex, endOfArgumentsMatch.index + 1);
-        return name + args;
-      }
-      return defaultName + '()';
-    }
-
-    /**
-     * @param {string} prefix
-     * @param {string} body
-     * @param {string} abbreviation
-     */
-    function addElements(prefix, body, abbreviation) {
-      const maxFunctionBodyLength = 200;
-      if (prefix.length)
-        valueElement.createChild('span', 'object-value-function-prefix').textContent = prefix + ' ';
-      if (includePreview)
-        valueElement.createTextChild(body.trim().trimEnd(maxFunctionBodyLength));
-      else
-        valueElement.createTextChild(abbreviation.replace(/\n/g, ' '));
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} value
-   * @param {boolean} wasThrown
-   * @param {boolean} showPreview
-   * @param {!Element=} parentElement
-   * @param {!Components.Linkifier=} linkifier
-   * @return {!Element}
-   */
-  static createValueElementWithCustomSupport(value, wasThrown, showPreview, parentElement, linkifier) {
-    if (value.customPreview()) {
-      const result = (new ObjectUI.CustomPreviewComponent(value)).element;
-      result.classList.add('object-properties-section-custom-section');
-      return result;
-    }
-    return ObjectUI.ObjectPropertiesSection.createValueElement(value, wasThrown, showPreview, parentElement, linkifier);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} value
-   * @param {boolean} wasThrown
-   * @param {boolean} showPreview
-   * @param {!Element=} parentElement
-   * @param {!Components.Linkifier=} linkifier
-   * @return {!Element}
-   */
-  static createValueElement(value, wasThrown, showPreview, parentElement, linkifier) {
-    let valueElement;
-    const type = value.type;
-    const subtype = value.subtype;
-    const description = value.description;
-    if (type === 'object' && subtype === 'internal#location') {
-      const rawLocation = value.debuggerModel().createRawLocationByScriptId(
-          value.value.scriptId, value.value.lineNumber, value.value.columnNumber);
-      if (rawLocation && linkifier)
-        return linkifier.linkifyRawLocation(rawLocation, '');
-      valueElement = createUnknownInternalLocationElement();
-    } else if (type === 'string' && typeof description === 'string') {
-      valueElement = createStringElement();
-    } else if (type === 'function') {
-      valueElement = ObjectUI.ObjectPropertiesSection.valueElementForFunctionDescription(description);
-    } else if (type === 'object' && subtype === 'node' && description) {
-      valueElement = createNodeElement();
-    } else if (type === 'number' && description && description.indexOf('e') !== -1) {
-      valueElement = createNumberWithExponentElement();
-      if (parentElement)  // FIXME: do it in the caller.
-        parentElement.classList.add('hbox');
-    } else {
-      valueElement = createElementWithClass('span', 'object-value-' + (subtype || type));
-      valueElement.title = description || '';
-      if (value.preview && showPreview) {
-        const previewFormatter = new ObjectUI.RemoteObjectPreviewFormatter();
-        previewFormatter.appendObjectPreview(valueElement, value.preview, false /* isEntry */);
-      } else {
-        valueElement.setTextContentTruncatedIfNeeded(description);
-      }
-    }
-
-    if (wasThrown) {
-      const wrapperElement = createElementWithClass('span', 'error value');
-      wrapperElement.createTextChild('[' + Common.UIString('Exception') + ': ');
-      wrapperElement.appendChild(valueElement);
-      wrapperElement.createTextChild(']');
-      return wrapperElement;
-    }
-    valueElement.classList.add('value');
-    return valueElement;
-
-    /**
-     * @return {!Element}
-     */
-    function createUnknownInternalLocationElement() {
-      const valueElement = createElementWithClass('span');
-      valueElement.textContent = '<' + Common.UIString('unknown') + '>';
-      valueElement.title = description || '';
-      return valueElement;
-    }
-
-    /**
-     * @return {!Element}
-     */
-    function createStringElement() {
-      const valueElement = createElementWithClass('span', 'object-value-string');
-      valueElement.createChild('span', 'object-value-string-quote').textContent = '"';
-      valueElement.createTextChild('').setTextContentTruncatedIfNeeded(description.replace(/\n/g, '\u21B5'));
-      valueElement.createChild('span', 'object-value-string-quote').textContent = '"';
-      valueElement.title = description || '';
-      return valueElement;
-    }
-
-    /**
-     * @return {!Element}
-     */
-    function createNodeElement() {
-      const valueElement = createElementWithClass('span', 'object-value-node');
-      ObjectUI.RemoteObjectPreviewFormatter.createSpansForNodeTitle(valueElement, /** @type {string} */ (description));
-      valueElement.addEventListener('click', event => {
-        Common.Revealer.reveal(value);
-        event.consume(true);
-      }, false);
-      valueElement.addEventListener('mousemove', () => SDK.OverlayModel.highlightObjectAsDOMNode(value), false);
-      valueElement.addEventListener('mouseleave', () => SDK.OverlayModel.hideDOMNodeHighlight(), false);
-      return valueElement;
-    }
-
-    /**
-     * @return {!Element}
-     */
-    function createNumberWithExponentElement() {
-      const valueElement = createElementWithClass('span', 'object-value-number');
-      const numberParts = description.split('e');
-      valueElement.createChild('span', 'object-value-scientific-notation-mantissa').textContent = numberParts[0];
-      valueElement.createChild('span', 'object-value-scientific-notation-exponent').textContent = 'e' + numberParts[1];
-      valueElement.classList.add('object-value-scientific-notation-number');
-      valueElement.title = description || '';
-      return valueElement;
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} func
-   * @param {!Element} element
-   * @param {boolean} linkify
-   * @param {boolean=} includePreview
-   */
-  static formatObjectAsFunction(func, element, linkify, includePreview) {
-    func.debuggerModel().functionDetailsPromise(func).then(didGetDetails);
-
-    /**
-     * @param {?SDK.DebuggerModel.FunctionDetails} response
-     */
-    function didGetDetails(response) {
-      if (linkify && response && response.location) {
-        element.classList.add('linkified');
-        element.addEventListener('click', () => Common.Revealer.reveal(response.location) && false);
-      }
-
-      // The includePreview flag is false for formats such as console.dir().
-      let defaultName = includePreview ? '' : 'anonymous';
-      if (response && response.functionName)
-        defaultName = response.functionName;
-      const valueElement = ObjectUI.ObjectPropertiesSection.valueElementForFunctionDescription(
-          func.description, includePreview, defaultName);
-      element.appendChild(valueElement);
-    }
-  }
-
-  skipProto() {
-    this._skipProto = true;
-  }
-
-  expand() {
-    this._objectTreeElement.expand();
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setEditable(value) {
-    this._editable = value;
-  }
-
-  /**
-   * @return {!UI.TreeElement}
-   */
-  objectTreeElement() {
-    return this._objectTreeElement;
-  }
-
-  enableContextMenu() {
-    this.element.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), false);
-  }
-
-  _contextMenuEventFired(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.appendApplicableItems(this._object);
-    if (this._object instanceof SDK.LocalJSONObject) {
-      contextMenu.viewSection().appendItem(
-          ls`Expand recursively`,
-          this._objectTreeElement.expandRecursively.bind(this._objectTreeElement, Number.MAX_VALUE));
-      contextMenu.viewSection().appendItem(
-          ls`Collapse children`, this._objectTreeElement.collapseChildren.bind(this._objectTreeElement));
-    }
-    contextMenu.show();
-  }
-
-  titleLessMode() {
-    this._objectTreeElement.listItemElement.classList.add('hidden');
-    this._objectTreeElement.childrenListElement.classList.add('title-less-mode');
-    this._objectTreeElement.expand();
-  }
-};
-
-/** @const */
-ObjectUI.ObjectPropertiesSection._arrayLoadThreshold = 100;
-
-
-/**
- * @unrestricted
- */
-ObjectUI.ObjectPropertiesSection.RootElement = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {!Components.Linkifier=} linkifier
-   * @param {?string=} emptyPlaceholder
-   * @param {boolean=} ignoreHasOwnProperty
-   * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties
-   */
-  constructor(object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) {
-    const contentElement = createElement('content');
-    super(contentElement);
-
-    this._object = object;
-    this._extraProperties = extraProperties || [];
-    this._ignoreHasOwnProperty = !!ignoreHasOwnProperty;
-    this._emptyPlaceholder = emptyPlaceholder;
-
-    this.setExpandable(true);
-    this.selectable = false;
-    this.toggleOnClick = true;
-    this.listItemElement.classList.add('object-properties-section-root-element');
-    this._linkifier = linkifier;
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    if (this.treeOutline)
-      this.treeOutline.element.classList.add('expanded');
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    if (this.treeOutline)
-      this.treeOutline.element.classList.remove('expanded');
-  }
-
-  /**
-   * @override
-   * @param {!Event} e
-   * @return {boolean}
-   */
-  ondblclick(e) {
-    return true;
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    ObjectUI.ObjectPropertyTreeElement._populate(
-        this, this._object, !!this.treeOutline._skipProto, this._linkifier, this._emptyPlaceholder,
-        this._ignoreHasOwnProperty, this._extraProperties);
-  }
-};
-
-/**
- * @unrestricted
- */
-ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.RemoteObjectProperty} property
-   * @param {!Components.Linkifier=} linkifier
-   */
-  constructor(property, linkifier) {
-    // Pass an empty title, the title gets made later in onattach.
-    super();
-
-    this.property = property;
-    this.toggleOnClick = true;
-    this.selectable = false;
-    /** @type {!Array.<!Object>} */
-    this._highlightChanges = [];
-    this._linkifier = linkifier;
-    this.listItemElement.addEventListener('contextmenu', this._contextMenuFired.bind(this), false);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeElement
-   * @param {!SDK.RemoteObject} value
-   * @param {boolean} skipProto
-   * @param {!Components.Linkifier=} linkifier
-   * @param {?string=} emptyPlaceholder
-   * @param {boolean=} flattenProtoChain
-   * @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties
-   * @param {!SDK.RemoteObject=} targetValue
-   */
-  static _populate(
-      treeElement,
-      value,
-      skipProto,
-      linkifier,
-      emptyPlaceholder,
-      flattenProtoChain,
-      extraProperties,
-      targetValue) {
-    if (value.arrayLength() > ObjectUI.ObjectPropertiesSection._arrayLoadThreshold) {
-      treeElement.removeChildren();
-      ObjectUI.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1, linkifier);
-      return;
-    }
-
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     */
-    function callback(properties, internalProperties) {
-      treeElement.removeChildren();
-      if (!properties)
-        return;
-
-      extraProperties = extraProperties || [];
-      for (let i = 0; i < extraProperties.length; ++i)
-        properties.push(extraProperties[i]);
-
-      ObjectUI.ObjectPropertyTreeElement.populateWithProperties(
-          treeElement, properties, internalProperties, skipProto, targetValue || value, linkifier, emptyPlaceholder);
-    }
-
-    if (flattenProtoChain)
-      value.getAllProperties(false /* accessorPropertiesOnly */, true /* generatePreview */, callback);
-    else
-      SDK.RemoteObject.loadFromObjectPerProto(value, true /* generatePreview */, callback);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeNode
-   * @param {!Array.<!SDK.RemoteObjectProperty>} properties
-   * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-   * @param {boolean} skipProto
-   * @param {?SDK.RemoteObject} value
-   * @param {!Components.Linkifier=} linkifier
-   * @param {?string=} emptyPlaceholder
-   */
-  static populateWithProperties(
-      treeNode,
-      properties,
-      internalProperties,
-      skipProto,
-      value,
-      linkifier,
-      emptyPlaceholder) {
-    properties.sort(ObjectUI.ObjectPropertiesSection.CompareProperties);
-
-    const tailProperties = [];
-    let protoProperty = null;
-    for (let i = 0; i < properties.length; ++i) {
-      const property = properties[i];
-      property.parentObject = value;
-      if (property.name === '__proto__' && !property.isAccessorProperty()) {
-        protoProperty = property;
-        continue;
-      }
-
-      if (property.isOwn && property.getter) {
-        const getterProperty = new SDK.RemoteObjectProperty('get ' + property.name, property.getter, false);
-        getterProperty.parentObject = value;
-        tailProperties.push(getterProperty);
-      }
-      if (property.isOwn && property.setter) {
-        const setterProperty = new SDK.RemoteObjectProperty('set ' + property.name, property.setter, false);
-        setterProperty.parentObject = value;
-        tailProperties.push(setterProperty);
-      }
-      const canShowProperty = property.getter || !property.isAccessorProperty();
-      if (canShowProperty && property.name !== '__proto__')
-        treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(property, linkifier));
-    }
-    for (let i = 0; i < tailProperties.length; ++i)
-      treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(tailProperties[i], linkifier));
-    if (!skipProto && protoProperty)
-      treeNode.appendChild(new ObjectUI.ObjectPropertyTreeElement(protoProperty, linkifier));
-
-    if (internalProperties) {
-      for (let i = 0; i < internalProperties.length; i++) {
-        internalProperties[i].parentObject = value;
-        const treeElement = new ObjectUI.ObjectPropertyTreeElement(internalProperties[i], linkifier);
-        if (internalProperties[i].name === '[[Entries]]') {
-          treeElement.setExpandable(true);
-          treeElement.expand();
-        }
-        treeNode.appendChild(treeElement);
-      }
-    }
-
-    ObjectUI.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(treeNode, emptyPlaceholder);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeNode
-   * @param {?string=} emptyPlaceholder
-   */
-  static _appendEmptyPlaceholderIfNeeded(treeNode, emptyPlaceholder) {
-    if (treeNode.childCount())
-      return;
-    const title = createElementWithClass('div', 'gray-info-message');
-    title.textContent = emptyPlaceholder || Common.UIString('No properties');
-    const infoElement = new UI.TreeElement(title);
-    treeNode.appendChild(infoElement);
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} object
-   * @param {!Array.<string>} propertyPath
-   * @param {function(?SDK.RemoteObject, boolean=)} callback
-   * @return {!Element}
-   */
-  static createRemoteObjectAccessorPropertySpan(object, propertyPath, callback) {
-    const rootElement = createElement('span');
-    const element = rootElement.createChild('span');
-    element.textContent = Common.UIString('(...)');
-    if (!object)
-      return rootElement;
-    element.classList.add('object-value-calculate-value-button');
-    element.title = Common.UIString('Invoke property getter');
-    element.addEventListener('click', onInvokeGetterClick, false);
-
-    function onInvokeGetterClick(event) {
-      event.consume();
-      object.getProperty(propertyPath, callback);
-    }
-
-    return rootElement;
-  }
-
-  /**
-   * @param {!RegExp} regex
-   * @param {string=} additionalCssClassName
-   * @return {boolean}
-   */
-  setSearchRegex(regex, additionalCssClassName) {
-    let cssClasses = UI.highlightedSearchResultClassName;
-    if (additionalCssClassName)
-      cssClasses += ' ' + additionalCssClassName;
-    this.revertHighlightChanges();
-
-    this._applySearch(regex, this.nameElement, cssClasses);
-    const valueType = this.property.value.type;
-    if (valueType !== 'object')
-      this._applySearch(regex, this.valueElement, cssClasses);
-
-    return !!this._highlightChanges.length;
-  }
-
-  /**
-   * @param {!RegExp} regex
-   * @param {!Element} element
-   * @param {string} cssClassName
-   */
-  _applySearch(regex, element, cssClassName) {
-    const ranges = [];
-    const content = element.textContent;
-    regex.lastIndex = 0;
-    let match = regex.exec(content);
-    while (match) {
-      ranges.push(new TextUtils.SourceRange(match.index, match[0].length));
-      match = regex.exec(content);
-    }
-    if (ranges.length)
-      UI.highlightRangesWithStyleClass(element, ranges, cssClassName, this._highlightChanges);
-  }
-
-  revertHighlightChanges() {
-    UI.revertDomChanges(this._highlightChanges);
-    this._highlightChanges = [];
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    const propertyValue = /** @type {!SDK.RemoteObject} */ (this.property.value);
-    console.assert(propertyValue);
-    const skipProto = this.treeOutline ? this.treeOutline._skipProto : true;
-    const targetValue = this.property.name !== '__proto__' ? propertyValue : this.property.parentObject;
-    ObjectUI.ObjectPropertyTreeElement._populate(
-        this, propertyValue, skipProto, this._linkifier, undefined, undefined, undefined, targetValue);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondblclick(event) {
-    const inEditableElement = event.target.isSelfOrDescendant(this.valueElement) ||
-        (this.expandedValueElement && event.target.isSelfOrDescendant(this.expandedValueElement));
-    if (!this.property.value.customPreview() && inEditableElement && (this.property.writable || this.property.setter))
-      this._startEditing();
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.update();
-    this._updateExpandable();
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    this._showExpandedValueElement(true);
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    this._showExpandedValueElement(false);
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  _showExpandedValueElement(value) {
-    if (!this.expandedValueElement)
-      return;
-    if (value)
-      this.listItemElement.replaceChild(this.expandedValueElement, this.valueElement);
-    else
-      this.listItemElement.replaceChild(this.valueElement, this.expandedValueElement);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} value
-   * @return {?Element}
-   */
-  _createExpandedValueElement(value) {
-    const needsAlternateValue = value.hasChildren && !value.customPreview() && value.subtype !== 'node' &&
-        value.type !== 'function' && (value.type !== 'object' || value.preview);
-    if (!needsAlternateValue)
-      return null;
-
-    const valueElement = createElementWithClass('span', 'value');
-    if (value.description === 'Object')
-      valueElement.textContent = '';
-    else
-      valueElement.setTextContentTruncatedIfNeeded(value.description || '');
-    valueElement.classList.add('object-value-' + (value.subtype || value.type));
-    valueElement.title = value.description || '';
-    return valueElement;
-  }
-
-  update() {
-    this.nameElement = ObjectUI.ObjectPropertiesSection.createNameElement(this.property.name);
-    if (!this.property.enumerable)
-      this.nameElement.classList.add('object-properties-section-dimmed');
-    if (this.property.synthetic)
-      this.nameElement.classList.add('synthetic-property');
-
-    this._updatePropertyPath();
-
-    const separatorElement = createElementWithClass('span', 'object-properties-section-separator');
-    separatorElement.textContent = ': ';
-
-    if (this.property.value) {
-      const showPreview = this.property.name !== '__proto__';
-      this.valueElement = ObjectUI.ObjectPropertiesSection.createValueElementWithCustomSupport(
-          this.property.value, this.property.wasThrown, showPreview, this.listItemElement, this._linkifier);
-    } else if (this.property.getter) {
-      this.valueElement = ObjectUI.ObjectPropertyTreeElement.createRemoteObjectAccessorPropertySpan(
-          this.property.parentObject, [this.property.name], this._onInvokeGetterClick.bind(this));
-    } else {
-      this.valueElement = createElementWithClass('span', 'object-value-undefined');
-      this.valueElement.textContent = Common.UIString('<unreadable>');
-      this.valueElement.title = Common.UIString('No property getter');
-    }
-
-    const valueText = this.valueElement.textContent;
-    if (this.property.value && valueText && !this.property.wasThrown)
-      this.expandedValueElement = this._createExpandedValueElement(this.property.value);
-
-    this.listItemElement.removeChildren();
-    this.listItemElement.appendChildren(this.nameElement, separatorElement, this.valueElement);
-  }
-
-  _updatePropertyPath() {
-    if (this.nameElement.title)
-      return;
-
-    const useDotNotation = /^(_|\$|[A-Z])(_|\$|[A-Z]|\d)*$/i;
-    const isInteger = /^[1-9]\d*$/;
-    const name = this.property.name;
-    const parentPath = this.parent.nameElement ? this.parent.nameElement.title : '';
-    if (useDotNotation.test(name))
-      this.nameElement.title = parentPath + '.' + name;
-    else if (isInteger.test(name))
-      this.nameElement.title = parentPath + '[' + name + ']';
-    else
-      this.nameElement.title = parentPath + '["' + name + '"]';
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _contextMenuFired(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    if (this.property.symbol)
-      contextMenu.appendApplicableItems(this.property.symbol);
-    if (this.property.value)
-      contextMenu.appendApplicableItems(this.property.value);
-    if (this.nameElement && this.nameElement.title) {
-      const copyPathHandler = InspectorFrontendHost.copyText.bind(InspectorFrontendHost, this.nameElement.title);
-      contextMenu.clipboardSection().appendItem(ls`Copy property path`, copyPathHandler);
-    }
-    if (this.property.parentObject instanceof SDK.LocalJSONObject) {
-      contextMenu.viewSection().appendItem(ls`Expand recursively`, this.expandRecursively.bind(this, Number.MAX_VALUE));
-      contextMenu.viewSection().appendItem(ls`Collapse children`, this.collapseChildren.bind(this));
-    }
-    contextMenu.show();
-  }
-
-  _startEditing() {
-    if (this._prompt || !this.treeOutline._editable || this._readOnly)
-      return;
-
-    this._editableDiv = this.listItemElement.createChild('span', 'editable-div');
-
-    let text = this.property.value.description;
-    if (this.property.value.type === 'string' && typeof text === 'string')
-      text = '"' + text + '"';
-
-    this._editableDiv.setTextContentTruncatedIfNeeded(text, Common.UIString('<string is too large to edit>'));
-    const originalContent = this._editableDiv.textContent;
-
-    // Lie about our children to prevent expanding on double click and to collapse subproperties.
-    this.setExpandable(false);
-    this.listItemElement.classList.add('editing-sub-part');
-    this.valueElement.classList.add('hidden');
-
-    this._prompt = new ObjectUI.ObjectPropertyPrompt();
-
-    const proxyElement =
-        this._prompt.attachAndStartEditing(this._editableDiv, this._editingCommitted.bind(this, originalContent));
-    this.listItemElement.getComponentSelection().selectAllChildren(this._editableDiv);
-    proxyElement.addEventListener('keydown', this._promptKeyDown.bind(this, originalContent), false);
-  }
-
-  _editingEnded() {
-    this._prompt.detach();
-    delete this._prompt;
-    this._editableDiv.remove();
-    this._updateExpandable();
-    this.listItemElement.scrollLeft = 0;
-    this.listItemElement.classList.remove('editing-sub-part');
-  }
-
-  _editingCancelled() {
-    this.valueElement.classList.remove('hidden');
-    this._editingEnded();
-  }
-
-  /**
-   * @param {string} originalContent
-   */
-  _editingCommitted(originalContent) {
-    const userInput = this._prompt.text();
-    if (userInput === originalContent) {
-      this._editingCancelled();  // nothing changed, so cancel
-      return;
-    }
-
-    this._editingEnded();
-    this._applyExpression(userInput);
-  }
-
-  /**
-   * @param {string} originalContent
-   * @param {!Event} event
-   */
-  _promptKeyDown(originalContent, event) {
-    if (isEnterKey(event)) {
-      event.consume();
-      this._editingCommitted(originalContent);
-      return;
-    }
-    if (event.key === 'Escape') {
-      event.consume();
-      this._editingCancelled();
-      return;
-    }
-  }
-
-  /**
-   * @param {string} expression
-   */
-  async _applyExpression(expression) {
-    const property = SDK.RemoteObject.toCallArgument(this.property.symbol || this.property.name);
-    expression = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(expression.trim());
-
-    if (this.property.synthetic) {
-      let invalidate = false;
-      if (expression)
-        invalidate = await this.property.setSyntheticValue(expression);
-      if (invalidate) {
-        const parent = this.parent;
-        parent.invalidateChildren();
-        parent.onpopulate();
-      } else {
-        this.update();
-      }
-      return;
-    }
-
-    const errorPromise = expression ? this.property.parentObject.setPropertyValue(property, expression) :
-                                      this.property.parentObject.deleteProperty(property);
-    const error = await errorPromise;
-    if (error) {
-      this.update();
-      return;
-    }
-
-    if (!expression) {
-      // The property was deleted, so remove this tree element.
-      this.parent.removeChild(this);
-    } else {
-      // Call updateSiblings since their value might be based on the value that just changed.
-      const parent = this.parent;
-      parent.invalidateChildren();
-      parent.onpopulate();
-    }
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} result
-   * @param {boolean=} wasThrown
-   */
-  _onInvokeGetterClick(result, wasThrown) {
-    if (!result)
-      return;
-    this.property.value = result;
-    this.property.wasThrown = wasThrown;
-
-    this.update();
-    this.invalidateChildren();
-    this._updateExpandable();
-  }
-
-  _updateExpandable() {
-    if (this.property.value) {
-      this.setExpandable(
-          !this.property.value.customPreview() && this.property.value.hasChildren && !this.property.wasThrown);
-    } else {
-      this.setExpandable(false);
-    }
-  }
-};
-
-
-/**
- * @unrestricted
- */
-ObjectUI.ArrayGroupingTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {number} fromIndex
-   * @param {number} toIndex
-   * @param {number} propertyCount
-   * @param {!Components.Linkifier=} linkifier
-   */
-  constructor(object, fromIndex, toIndex, propertyCount, linkifier) {
-    super(String.sprintf('[%d \u2026 %d]', fromIndex, toIndex), true);
-    this.toggleOnClick = true;
-    this.selectable = false;
-    this._fromIndex = fromIndex;
-    this._toIndex = toIndex;
-    this._object = object;
-    this._readOnly = true;
-    this._propertyCount = propertyCount;
-    this._linkifier = linkifier;
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeNode
-   * @param {!SDK.RemoteObject} object
-   * @param {number} fromIndex
-   * @param {number} toIndex
-   * @param {!Components.Linkifier=} linkifier
-   */
-  static _populateArray(treeNode, object, fromIndex, toIndex, linkifier) {
-    ObjectUI.ArrayGroupingTreeElement._populateRanges(treeNode, object, fromIndex, toIndex, true, linkifier);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeNode
-   * @param {!SDK.RemoteObject} object
-   * @param {number} fromIndex
-   * @param {number} toIndex
-   * @param {boolean} topLevel
-   * @param {!Components.Linkifier=} linkifier
-   * @this {ObjectUI.ArrayGroupingTreeElement}
-   */
-  static _populateRanges(treeNode, object, fromIndex, toIndex, topLevel, linkifier) {
-    object.callFunctionJSON(
-        packRanges,
-        [
-          {value: fromIndex}, {value: toIndex}, {value: ObjectUI.ArrayGroupingTreeElement._bucketThreshold},
-          {value: ObjectUI.ArrayGroupingTreeElement._sparseIterationThreshold},
-          {value: ObjectUI.ArrayGroupingTreeElement._getOwnPropertyNamesThreshold}
-        ],
-        callback);
-
-    /**
-     * Note: must declare params as optional.
-     * @param {number=} fromIndex
-     * @param {number=} toIndex
-     * @param {number=} bucketThreshold
-     * @param {number=} sparseIterationThreshold
-     * @param {number=} getOwnPropertyNamesThreshold
-     * @suppressReceiverCheck
-     * @this {Object}
-     */
-    function packRanges(fromIndex, toIndex, bucketThreshold, sparseIterationThreshold, getOwnPropertyNamesThreshold) {
-      let ownPropertyNames = null;
-      const consecutiveRange = (toIndex - fromIndex >= sparseIterationThreshold) && ArrayBuffer.isView(this);
-      const skipGetOwnPropertyNames = consecutiveRange && (toIndex - fromIndex >= getOwnPropertyNamesThreshold);
-
-      function* arrayIndexes(object) {
-        if (toIndex - fromIndex < sparseIterationThreshold) {
-          for (let i = fromIndex; i <= toIndex; ++i) {
-            if (i in object)
-              yield i;
-          }
-        } else {
-          ownPropertyNames = ownPropertyNames || Object.getOwnPropertyNames(object);
-          for (let i = 0; i < ownPropertyNames.length; ++i) {
-            const name = ownPropertyNames[i];
-            const index = name >>> 0;
-            if (('' + index) === name && fromIndex <= index && index <= toIndex)
-              yield index;
-          }
-        }
-      }
-
-      let count = 0;
-      if (consecutiveRange) {
-        count = toIndex - fromIndex + 1;
-      } else {
-        for (const i of arrayIndexes(this))  // eslint-disable-line
-          ++count;
-      }
-
-      let bucketSize = count;
-      if (count <= bucketThreshold)
-        bucketSize = count;
-      else
-        bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1);
-
-      const ranges = [];
-      if (consecutiveRange) {
-        for (let i = fromIndex; i <= toIndex; i += bucketSize) {
-          const groupStart = i;
-          let groupEnd = groupStart + bucketSize - 1;
-          if (groupEnd > toIndex)
-            groupEnd = toIndex;
-          ranges.push([groupStart, groupEnd, groupEnd - groupStart + 1]);
-        }
-      } else {
-        count = 0;
-        let groupStart = -1;
-        let groupEnd = 0;
-        for (const i of arrayIndexes(this)) {
-          if (groupStart === -1)
-            groupStart = i;
-          groupEnd = i;
-          if (++count === bucketSize) {
-            ranges.push([groupStart, groupEnd, count]);
-            count = 0;
-            groupStart = -1;
-          }
-        }
-        if (count > 0)
-          ranges.push([groupStart, groupEnd, count]);
-      }
-
-      return {ranges: ranges, skipGetOwnPropertyNames: skipGetOwnPropertyNames};
-    }
-
-    function callback(result) {
-      if (!result)
-        return;
-      const ranges = /** @type {!Array.<!Array.<number>>} */ (result.ranges);
-      if (ranges.length === 1) {
-        ObjectUI.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, ranges[0][0], ranges[0][1], linkifier);
-      } else {
-        for (let i = 0; i < ranges.length; ++i) {
-          const fromIndex = ranges[i][0];
-          const toIndex = ranges[i][1];
-          const count = ranges[i][2];
-          if (fromIndex === toIndex)
-            ObjectUI.ArrayGroupingTreeElement._populateAsFragment(treeNode, object, fromIndex, toIndex, linkifier);
-          else
-            treeNode.appendChild(new ObjectUI.ArrayGroupingTreeElement(object, fromIndex, toIndex, count, linkifier));
-        }
-      }
-      if (topLevel) {
-        ObjectUI.ArrayGroupingTreeElement._populateNonIndexProperties(
-            treeNode, object, result.skipGetOwnPropertyNames, linkifier);
-      }
-    }
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeNode
-   * @param {!SDK.RemoteObject} object
-   * @param {number} fromIndex
-   * @param {number} toIndex
-   * @param {!Components.Linkifier=} linkifier
-   * @this {ObjectUI.ArrayGroupingTreeElement}
-   */
-  static _populateAsFragment(treeNode, object, fromIndex, toIndex, linkifier) {
-    object.callFunction(
-        buildArrayFragment,
-        [{value: fromIndex}, {value: toIndex}, {value: ObjectUI.ArrayGroupingTreeElement._sparseIterationThreshold}],
-        processArrayFragment.bind(this));
-
-    /**
-     * @suppressReceiverCheck
-     * @this {Object}
-     * @param {number=} fromIndex // must declare optional
-     * @param {number=} toIndex // must declare optional
-     * @param {number=} sparseIterationThreshold // must declare optional
-     */
-    function buildArrayFragment(fromIndex, toIndex, sparseIterationThreshold) {
-      const result = Object.create(null);
-      if (toIndex - fromIndex < sparseIterationThreshold) {
-        for (let i = fromIndex; i <= toIndex; ++i) {
-          if (i in this)
-            result[i] = this[i];
-        }
-      } else {
-        const ownPropertyNames = Object.getOwnPropertyNames(this);
-        for (let i = 0; i < ownPropertyNames.length; ++i) {
-          const name = ownPropertyNames[i];
-          const index = name >>> 0;
-          if (String(index) === name && fromIndex <= index && index <= toIndex)
-            result[index] = this[index];
-        }
-      }
-      return result;
-    }
-
-    /**
-     * @param {?SDK.RemoteObject} arrayFragment
-     * @param {boolean=} wasThrown
-     * @this {ObjectUI.ArrayGroupingTreeElement}
-     */
-    function processArrayFragment(arrayFragment, wasThrown) {
-      if (!arrayFragment || wasThrown)
-        return;
-      arrayFragment.getAllProperties(
-          false /* accessorPropertiesOnly */, true /* generatePreview */, processProperties.bind(this));
-    }
-
-    /** @this {ObjectUI.ArrayGroupingTreeElement} */
-    function processProperties(properties, internalProperties) {
-      if (!properties)
-        return;
-
-      properties.sort(ObjectUI.ObjectPropertiesSection.CompareProperties);
-      for (let i = 0; i < properties.length; ++i) {
-        properties[i].parentObject = this._object;
-        const childTreeElement = new ObjectUI.ObjectPropertyTreeElement(properties[i], linkifier);
-        childTreeElement._readOnly = true;
-        treeNode.appendChild(childTreeElement);
-      }
-    }
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeNode
-   * @param {!SDK.RemoteObject} object
-   * @param {boolean} skipGetOwnPropertyNames
-   * @param {!Components.Linkifier=} linkifier
-   * @this {ObjectUI.ArrayGroupingTreeElement}
-   */
-  static _populateNonIndexProperties(treeNode, object, skipGetOwnPropertyNames, linkifier) {
-    object.callFunction(buildObjectFragment, [{value: skipGetOwnPropertyNames}], processObjectFragment.bind(this));
-
-    /**
-     * @param {boolean=} skipGetOwnPropertyNames
-     * @suppressReceiverCheck
-     * @this {Object}
-     */
-    function buildObjectFragment(skipGetOwnPropertyNames) {
-      const result = {__proto__: this.__proto__};
-      if (skipGetOwnPropertyNames)
-        return result;
-      const names = Object.getOwnPropertyNames(this);
-      for (let i = 0; i < names.length; ++i) {
-        const name = names[i];
-        // Array index check according to the ES5-15.4.
-        if (String(name >>> 0) === name && name >>> 0 !== 0xffffffff)
-          continue;
-        const descriptor = Object.getOwnPropertyDescriptor(this, name);
-        if (descriptor)
-          Object.defineProperty(result, name, descriptor);
-      }
-      return result;
-    }
-
-    /**
-     * @param {?SDK.RemoteObject} arrayFragment
-     * @param {boolean=} wasThrown
-     * @this {ObjectUI.ArrayGroupingTreeElement}
-     */
-    function processObjectFragment(arrayFragment, wasThrown) {
-      if (!arrayFragment || wasThrown)
-        return;
-      arrayFragment.getOwnProperties(true /* generatePreview */, processProperties.bind(this));
-    }
-
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>=} internalProperties
-     * @this {ObjectUI.ArrayGroupingTreeElement}
-     */
-    function processProperties(properties, internalProperties) {
-      if (!properties)
-        return;
-      properties.sort(ObjectUI.ObjectPropertiesSection.CompareProperties);
-      for (let i = 0; i < properties.length; ++i) {
-        properties[i].parentObject = this._object;
-        const childTreeElement = new ObjectUI.ObjectPropertyTreeElement(properties[i], linkifier);
-        childTreeElement._readOnly = true;
-        treeNode.appendChild(childTreeElement);
-      }
-    }
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    if (this._propertyCount >= ObjectUI.ArrayGroupingTreeElement._bucketThreshold) {
-      ObjectUI.ArrayGroupingTreeElement._populateRanges(
-          this, this._object, this._fromIndex, this._toIndex, false, this._linkifier);
-      return;
-    }
-    ObjectUI.ArrayGroupingTreeElement._populateAsFragment(
-        this, this._object, this._fromIndex, this._toIndex, this._linkifier);
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.classList.add('object-properties-section-name');
-  }
-};
-
-ObjectUI.ArrayGroupingTreeElement._bucketThreshold = 100;
-ObjectUI.ArrayGroupingTreeElement._sparseIterationThreshold = 250000;
-ObjectUI.ArrayGroupingTreeElement._getOwnPropertyNamesThreshold = 500000;
-
-
-/**
- * @unrestricted
- */
-ObjectUI.ObjectPropertyPrompt = class extends UI.TextPrompt {
-  constructor() {
-    super();
-    this.initialize(
-        ObjectUI.javaScriptAutocomplete.completionsForTextInCurrentContext.bind(ObjectUI.javaScriptAutocomplete));
-  }
-};
-
-/**
- * @unrestricted
- */
-ObjectUI.ObjectPropertiesSectionExpandController = class {
-  constructor() {
-    /** @type {!Set.<string>} */
-    this._expandedProperties = new Set();
-  }
-
-  /**
-   * @param {string} id
-   * @param {!ObjectUI.ObjectPropertiesSection} section
-   */
-  watchSection(id, section) {
-    section.addEventListener(UI.TreeOutline.Events.ElementAttached, this._elementAttached, this);
-    section.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._elementExpanded, this);
-    section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._elementCollapsed, this);
-    section[ObjectUI.ObjectPropertiesSectionExpandController._treeOutlineId] = id;
-
-    if (this._expandedProperties.has(id))
-      section.expand();
-  }
-
-  /**
-   * @param {string} id
-   */
-  stopWatchSectionsWithId(id) {
-    for (const property of this._expandedProperties) {
-      if (property.startsWith(id + ':'))
-        this._expandedProperties.delete(property);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _elementAttached(event) {
-    const element = /** @type {!UI.TreeElement} */ (event.data);
-    if (element.isExpandable() && this._expandedProperties.has(this._propertyPath(element)))
-      element.expand();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _elementExpanded(event) {
-    const element = /** @type {!UI.TreeElement} */ (event.data);
-    this._expandedProperties.add(this._propertyPath(element));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _elementCollapsed(event) {
-    const element = /** @type {!UI.TreeElement} */ (event.data);
-    this._expandedProperties.delete(this._propertyPath(element));
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeElement
-   * @return {string}
-   */
-  _propertyPath(treeElement) {
-    const cachedPropertyPath = treeElement[ObjectUI.ObjectPropertiesSectionExpandController._cachedPathSymbol];
-    if (cachedPropertyPath)
-      return cachedPropertyPath;
-
-    let current = treeElement;
-    const rootElement = treeElement.treeOutline.objectTreeElement();
-
-    let result;
-
-    while (current !== rootElement) {
-      let currentName = '';
-      if (current.property)
-        currentName = current.property.name;
-      else
-        currentName = typeof current.title === 'string' ? current.title : current.title.textContent;
-
-      result = currentName + (result ? '.' + result : '');
-      current = current.parent;
-    }
-    const treeOutlineId = treeElement.treeOutline[ObjectUI.ObjectPropertiesSectionExpandController._treeOutlineId];
-    result = treeOutlineId + (result ? ':' + result : '');
-    treeElement[ObjectUI.ObjectPropertiesSectionExpandController._cachedPathSymbol] = result;
-    return result;
-  }
-};
-
-ObjectUI.ObjectPropertiesSectionExpandController._cachedPathSymbol = Symbol('cachedPath');
-ObjectUI.ObjectPropertiesSectionExpandController._treeOutlineId = Symbol('treeOutlineId');
-
-/**
- * @implements {Common.Renderer}
- */
-ObjectUI.ObjectPropertiesSection.Renderer = class {
-  /**
-   * @override
-   * @param {!Object} object
-   * @param {!Common.Renderer.Options=} options
-   * @return {!Promise<?Node>}
-   */
-  render(object, options) {
-    if (!(object instanceof SDK.RemoteObject))
-      return Promise.reject(new Error('Can\'t render ' + object));
-    options = options || {};
-    const title = options.title;
-    const section = new ObjectUI.ObjectPropertiesSection(object, title);
-    if (!title)
-      section.titleLessMode();
-    if (options.expanded)
-      section.expand();
-    section.editable = !!options.editable;
-    return Promise.resolve(section.element);
-  }
-};
\ No newline at end of file
diff --git a/front_end/object_ui/RemoteObjectPreviewFormatter.js b/front_end/object_ui/RemoteObjectPreviewFormatter.js
deleted file mode 100644
index 3a67026..0000000
--- a/front_end/object_ui/RemoteObjectPreviewFormatter.js
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-ObjectUI.RemoteObjectPreviewFormatter = class {
-  /**
-   * @param {!Protocol.Runtime.PropertyPreview} a
-   * @param {!Protocol.Runtime.PropertyPreview} b
-   * @return {number}
-   */
-  static _objectPropertyComparator(a, b) {
-    return sortValue(a) - sortValue(b);
-
-    /**
-     * @param {!Protocol.Runtime.PropertyPreview} property
-     * @return {number}
-     */
-    function sortValue(property) {
-      const internalName = ObjectUI.RemoteObjectPreviewFormatter._internalName;
-      if (property.name === internalName.PromiseStatus)
-        return 1;
-      else if (property.name === internalName.PromiseValue)
-        return 2;
-      else if (property.name === internalName.GeneratorStatus || internalName.PrimitiveValue)
-        return 3;
-      else if (property.type !== 'function')
-        return 4;
-      return 5;
-    }
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Protocol.Runtime.ObjectPreview} preview
-   * @param {boolean} isEntry
-   */
-  appendObjectPreview(parentElement, preview, isEntry) {
-    const description = preview.description;
-    const subTypesWithoutValuePreview = new Set(['null', 'regexp', 'error', 'internal#entry']);
-    if (preview.type !== 'object' || subTypesWithoutValuePreview.has(preview.subtype) || isEntry) {
-      parentElement.appendChild(this.renderPropertyPreview(preview.type, preview.subtype, description));
-      return;
-    }
-    const isArrayOrTypedArray = preview.subtype === 'array' || preview.subtype === 'typedarray';
-    if (description) {
-      let text;
-      if (isArrayOrTypedArray) {
-        const arrayLength = SDK.RemoteObject.arrayLength(preview);
-        const arrayLengthText = arrayLength > 1 ? ('(' + arrayLength + ')') : '';
-        const arrayName = SDK.RemoteObject.arrayNameFromDescription(description);
-        text = arrayName === 'Array' ? arrayLengthText : (arrayName + arrayLengthText);
-      } else {
-        const hideDescription = description === 'Object';
-        text = hideDescription ? '' : description;
-      }
-      if (text.length > 0)
-        parentElement.createChild('span', 'object-description').textContent = text + '\u00a0';
-    }
-
-    const propertiesElement = parentElement.createChild('span', 'object-properties-preview');
-    propertiesElement.createTextChild(isArrayOrTypedArray ? '[' : '{');
-    if (preview.entries)
-      this._appendEntriesPreview(propertiesElement, preview);
-    else if (isArrayOrTypedArray)
-      this._appendArrayPropertiesPreview(propertiesElement, preview);
-    else
-      this._appendObjectPropertiesPreview(propertiesElement, preview);
-    if (preview.overflow) {
-      const ellipsisText = propertiesElement.textContent.length > 1 ? ',\u00a0\u2026' : '\u2026';
-      propertiesElement.createChild('span').textContent = ellipsisText;
-    }
-    propertiesElement.createTextChild(isArrayOrTypedArray ? ']' : '}');
-  }
-
-  /**
-   * @param {string} description
-   * @return {string}
-   */
-  _abbreviateFullQualifiedClassName(description) {
-    const abbreviatedDescription = description.split('.');
-    for (let i = 0; i < abbreviatedDescription.length - 1; ++i)
-      abbreviatedDescription[i] = abbreviatedDescription[i].trimMiddle(3);
-    return abbreviatedDescription.join('.');
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Protocol.Runtime.ObjectPreview} preview
-   */
-  _appendObjectPropertiesPreview(parentElement, preview) {
-    const internalName = ObjectUI.RemoteObjectPreviewFormatter._internalName;
-    const properties = preview.properties.filter(p => p.type !== 'accessor')
-                           .stableSort(ObjectUI.RemoteObjectPreviewFormatter._objectPropertyComparator);
-    for (let i = 0; i < properties.length; ++i) {
-      if (i > 0)
-        parentElement.createTextChild(', ');
-
-      const property = properties[i];
-      const name = property.name;
-      // Internal properties are given special formatting, e.g. Promises `<rejected>: 123`.
-      if (preview.subtype === 'promise' && name === internalName.PromiseStatus) {
-        parentElement.appendChild(this._renderDisplayName('<' + property.value + '>'));
-        const nextProperty = i + 1 < properties.length ? properties[i + 1] : null;
-        if (nextProperty && nextProperty.name === internalName.PromiseValue) {
-          if (property.value !== 'pending') {
-            parentElement.createTextChild(': ');
-            parentElement.appendChild(this._renderPropertyPreviewOrAccessor([nextProperty]));
-          }
-          i++;
-        }
-      } else if (preview.subtype === 'generator' && name === internalName.GeneratorStatus) {
-        parentElement.appendChild(this._renderDisplayName('<' + property.value + '>'));
-      } else if (name === internalName.PrimitiveValue) {
-        parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
-      } else {
-        parentElement.appendChild(this._renderDisplayName(name));
-        parentElement.createTextChild(': ');
-        parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
-      }
-    }
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Protocol.Runtime.ObjectPreview} preview
-   */
-  _appendArrayPropertiesPreview(parentElement, preview) {
-    const arrayLength = SDK.RemoteObject.arrayLength(preview);
-    const indexProperties =
-        preview.properties.filter(p => toArrayIndex(p.name) !== -1).stableSort(arrayEntryComparator);
-    const otherProperties = preview.properties.filter(p => toArrayIndex(p.name) === -1)
-                                .stableSort(ObjectUI.RemoteObjectPreviewFormatter._objectPropertyComparator);
-
-    /**
-     * @param {!Protocol.Runtime.PropertyPreview} a
-     * @param {!Protocol.Runtime.PropertyPreview} b
-     * @return {number}
-     */
-    function arrayEntryComparator(a, b) {
-      return toArrayIndex(a.name) - toArrayIndex(b.name);
-    }
-
-    /**
-     * @param {string} name
-     * @return {number}
-     */
-    function toArrayIndex(name) {
-      const index = name >>> 0;
-      if (String(index) === name && index < arrayLength)
-        return index;
-      return -1;
-    }
-
-    // Gaps can be shown when all properties are guaranteed to be in the preview.
-    const canShowGaps = !preview.overflow;
-    let lastNonEmptyArrayIndex = -1;
-    let elementsAdded = false;
-    for (let i = 0; i < indexProperties.length; ++i) {
-      if (elementsAdded)
-        parentElement.createTextChild(', ');
-
-      const property = indexProperties[i];
-      const index = toArrayIndex(property.name);
-      if (canShowGaps && index - lastNonEmptyArrayIndex > 1) {
-        appendUndefined(index);
-        parentElement.createTextChild(', ');
-      }
-      if (!canShowGaps && i !== index) {
-        parentElement.appendChild(this._renderDisplayName(property.name));
-        parentElement.createTextChild(': ');
-      }
-      parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
-      lastNonEmptyArrayIndex = index;
-      elementsAdded = true;
-    }
-
-    if (canShowGaps && arrayLength - lastNonEmptyArrayIndex > 1) {
-      if (elementsAdded)
-        parentElement.createTextChild(', ');
-      appendUndefined(arrayLength);
-    }
-
-    for (let i = 0; i < otherProperties.length; ++i) {
-      if (elementsAdded)
-        parentElement.createTextChild(', ');
-
-      const property = otherProperties[i];
-      parentElement.appendChild(this._renderDisplayName(property.name));
-      parentElement.createTextChild(': ');
-      parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
-      elementsAdded = true;
-    }
-
-    /**
-     * @param {number} index
-     */
-    function appendUndefined(index) {
-      const span = parentElement.createChild('span', 'object-value-undefined');
-      const count = index - lastNonEmptyArrayIndex - 1;
-      span.textContent = count !== 1 ? Common.UIString('empty × %d', count) : Common.UIString('empty');
-      elementsAdded = true;
-    }
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Protocol.Runtime.ObjectPreview} preview
-   */
-  _appendEntriesPreview(parentElement, preview) {
-    for (let i = 0; i < preview.entries.length; ++i) {
-      if (i > 0)
-        parentElement.createTextChild(', ');
-
-      const entry = preview.entries[i];
-      if (entry.key) {
-        this.appendObjectPreview(parentElement, entry.key, true /* isEntry */);
-        parentElement.createTextChild(' => ');
-      }
-      this.appendObjectPreview(parentElement, entry.value, true /* isEntry */);
-    }
-  }
-
-  /**
-   * @param {string} name
-   * @return {!Element}
-   */
-  _renderDisplayName(name) {
-    const result = createElementWithClass('span', 'name');
-    const needsQuotes = /^\s|\s$|^$|\n/.test(name);
-    result.textContent = needsQuotes ? '"' + name.replace(/\n/g, '\u21B5') + '"' : name;
-    return result;
-  }
-
-  /**
-   * @param {!Array.<!Protocol.Runtime.PropertyPreview>} propertyPath
-   * @return {!Element}
-   */
-  _renderPropertyPreviewOrAccessor(propertyPath) {
-    const property = propertyPath.peekLast();
-    return this.renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value);
-  }
-
-  /**
-   * @param {string} type
-   * @param {string=} subtype
-   * @param {string=} description
-   * @return {!Element}
-   */
-  renderPropertyPreview(type, subtype, description) {
-    const span = createElementWithClass('span', 'object-value-' + (subtype || type));
-    description = description || '';
-
-    if (type === 'accessor') {
-      span.textContent = '(...)';
-      span.title = Common.UIString('The property is computed with a getter');
-      return span;
-    }
-
-    if (type === 'function') {
-      span.textContent = '\u0192';
-      return span;
-    }
-
-    if (type === 'object' && subtype === 'node' && description) {
-      ObjectUI.RemoteObjectPreviewFormatter.createSpansForNodeTitle(span, description);
-      return span;
-    }
-
-    if (type === 'string') {
-      span.createTextChildren('"', description.replace(/\n/g, '\u21B5'), '"');
-      return span;
-    }
-
-    if (type === 'object' && !subtype) {
-      let preview = this._abbreviateFullQualifiedClassName(description);
-      if (preview === 'Object')
-        preview = '{\u2026}';
-      span.textContent = preview;
-      span.title = description;
-      return span;
-    }
-
-    span.textContent = description;
-    return span;
-  }
-};
-
-/** @enum {string} */
-ObjectUI.RemoteObjectPreviewFormatter._internalName = {
-  GeneratorStatus: '[[GeneratorStatus]]',
-  PrimitiveValue: '[[PrimitiveValue]]',
-  PromiseStatus: '[[PromiseStatus]]',
-  PromiseValue: '[[PromiseValue]]'
-};
-
-/**
- * @param {!Element} container
- * @param {string} nodeTitle
- */
-ObjectUI.RemoteObjectPreviewFormatter.createSpansForNodeTitle = function(container, nodeTitle) {
-  const match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
-  container.createChild('span', 'webkit-html-tag-name').textContent = match[1];
-  if (match[2])
-    container.createChild('span', 'webkit-html-attribute-value').textContent = match[2];
-  if (match[3])
-    container.createChild('span', 'webkit-html-attribute-name').textContent = match[3];
-};
diff --git a/front_end/object_ui/customPreviewComponent.css b/front_end/object_ui/customPreviewComponent.css
deleted file mode 100644
index 1123521..0000000
--- a/front_end/object_ui/customPreviewComponent.css
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.custom-expandable-section {
-    display: inline-flex;
-    flex-direction: column;
-}
-
-.custom-expand-icon {
-    -webkit-user-select: none;
-    opacity: 0.5;
-    margin-right: 4px;
-    margin-bottom: -2px;
-    background: black;
-}
-
-.custom-expandable-section-standard-section {
-    display: inline-flex;
-}
\ No newline at end of file
diff --git a/front_end/object_ui/module.json b/front_end/object_ui/module.json
deleted file mode 100644
index 216588d..0000000
--- a/front_end/object_ui/module.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@Common.Renderer",
-            "contextTypes": [
-                "SDK.RemoteObject"
-            ],
-            "className": "ObjectUI.ObjectPropertiesSection.Renderer"
-        }
-    ],
-    "dependencies": [
-        "ui",
-        "sdk",
-        "components"
-    ],
-    "scripts": [
-        "CustomPreviewComponent.js",
-        "ObjectPopoverHelper.js",
-        "ObjectPropertiesSection.js",
-        "JavaScriptAutocomplete.js",
-        "RemoteObjectPreviewFormatter.js"
-    ],
-    "resources": [
-        "customPreviewComponent.css",
-        "objectPopover.css",
-        "objectPropertiesSection.css",
-        "objectValue.css"
-    ]
-}
diff --git a/front_end/object_ui/objectPopover.css b/front_end/object_ui/objectPopover.css
deleted file mode 100644
index c04f202..0000000
--- a/front_end/object_ui/objectPopover.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.object-popover-content {
-    display: block;
-    position: relative;
-    overflow: hidden;
-    flex: 1 1 auto;
-}
-
-.object-popover-title {
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-    font-weight: bold;
-    padding-left: 18px;
-    padding-bottom: 2px;
-}
-
-.object-popover-tree {
-    border-top: 1px solid rgb(184, 184, 184);
-    overflow: auto;
-    width: 100%;
-    height: calc(100% - 13px);
-}
-
-.object-popover-container {
-    display: inline-block;
-}
-
-.function-popover-title {
-    border-bottom: 1px solid #AAA;
-    margin-bottom: 3px;
-    padding-bottom: 2px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-}
-
-.function-popover-title .function-name {
-    font-weight: bold;
-}
-
-.function-title-link-container {
-    display: flex;
-    align-items: center;
-    position: relative;
-    margin-left: 10px;
-}
-
-.function-title-link-container .devtools-link {
-    white-space: nowrap;
-    overflow: hidden;
-}
-
-.function-location-step-into {
-    position: relative;
-    height: 14px;
-    transform: rotate(-90deg);
-}
diff --git a/front_end/object_ui/objectPropertiesSection.css b/front_end/object_ui/objectPropertiesSection.css
deleted file mode 100644
index 73c0ee3..0000000
--- a/front_end/object_ui/objectPropertiesSection.css
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.object-properties-section-separator {
-    flex-shrink: 0;
-    padding-right: 5px;
-}
-
-.object-properties-section-dimmed {
-    opacity: 0.6;
-}
-
-.object-properties-section {
-    padding: 0 0 0px 0px;
-    color: rgb(33,33,33) !important;
-    display: flex;
-    flex-direction: column;
-}
-
-.object-properties-section li {
-    -webkit-user-select: text;
-}
-
-.object-properties-section li::before {
-    top: -1px;
-}
-
-.object-properties-section li.editing-sub-part {
-    padding: 3px 12px 8px 6px;
-    margin: -1px -6px -8px -6px;
-    text-overflow: clip;
-}
-
-.object-properties-section li.editing {
-    margin-left: 10px;
-    text-overflow: clip;
-}
-
-.tree-outline ol.title-less-mode {
-    padding-left: 0px;
-}
-
-.object-properties-section .synthetic-property {
-    font-style: italic;
-}
-
-.object-properties-section-root-element {
-    display: flex;
-    flex-direction: row;
-}
-
-.object-properties-section .editable-div {
-    overflow: hidden;
-}
diff --git a/front_end/object_ui/objectValue.css b/front_end/object_ui/objectValue.css
deleted file mode 100644
index 6d75996..0000000
--- a/front_end/object_ui/objectValue.css
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.object-value-scientific-notation-exponent {
-    flex-shrink: 0;
-}
-
-.object-value-scientific-notation-mantissa {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    flex-shrink: 1;
-    min-width: 1ex;
-}
-
-.object-value-scientific-notation-number {
-    display: flex !important;
-}
-
-.value.object-value-node:hover {
-    background-color: rgba(56, 121, 217, 0.1);
-}
-
-.object-value-function-prefix,
-.object-value-boolean {
-    color: rgb(13, 34, 170);
-}
-
-.object-value-function {
-    font-style: italic;
-}
-
-.object-value-function.linkified:hover {
-    background-color: rgba(0, 0, 0, 0.1);
-    cursor: pointer;
-}
-
-.object-value-number {
-    color: rgb(28, 0, 207);
-}
-
-.object-value-bigint {
-    color: rgb(0, 93, 0);
-}
-
-.object-value-string,
-.object-value-regexp,
-.object-value-symbol {
-    white-space: pre;
-    unicode-bidi: -webkit-isolate;
-    color: rgb(196, 26, 22);
-}
-
-.object-value-string-quote {
-    color: #222;
-}
-
-.object-value-node {
-    position: relative;
-    vertical-align: baseline;
-    color: rgb(48, 57, 66);
-    display: inline-block;
-}
-
-.object-value-null,
-.object-value-undefined {
-    color: rgb(128, 128, 128);
-}
-
-.object-value {
-    text-overflow: ellipsis;
-    overflow: hidden;
-    -webkit-user-select: text;
-}
-
-.object-value-calculate-value-button:hover {
-    text-decoration: underline;
-}
-
-.object-properties-section-custom-section {
-    display: inline-flex;
-    flex-direction: column;
-}
-
-.-theme-with-dark-background .object-value-number,
-:host-context(.-theme-with-dark-background) .object-value-number,
-.-theme-with-dark-background .object-value-boolean,
-:host-context(.-theme-with-dark-background) .object-value-boolean {
-    color: hsl(252, 100%, 75%);
-}
-
-.object-properties-section .object-description {
-    color: gray;
-}
-
-.value .object-properties-preview {
-    white-space: nowrap;
-}
-
-.name {
-    color: rgb(136, 19, 145);
-    flex-shrink: 0;
-}
-
-.object-properties-preview .name {
-    color: #565656;
-}
diff --git a/front_end/perf_ui/ChartViewport.js b/front_end/perf_ui/ChartViewport.js
deleted file mode 100644
index 67fddcc..0000000
--- a/front_end/perf_ui/ChartViewport.js
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @interface
- */
-PerfUI.ChartViewportDelegate = function() {};
-
-PerfUI.ChartViewportDelegate.prototype = {
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {boolean} animate
-   */
-  requestWindowTimes(startTime, endTime, animate) {},
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  updateRangeSelection(startTime, endTime) {},
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  setSize(width, height) {},
-
-  update() {}
-};
-
-/**
- * @unrestricted
- */
-PerfUI.ChartViewport = class extends UI.VBox {
-  /**
-   * @param {!PerfUI.ChartViewportDelegate} delegate
-   */
-  constructor(delegate) {
-    super();
-    this.registerRequiredCSS('perf_ui/chartViewport.css');
-
-    this._delegate = delegate;
-
-    this.viewportElement = this.contentElement.createChild('div', 'fill');
-    this.viewportElement.addEventListener('mousemove', this._updateCursorPosition.bind(this), false);
-    this.viewportElement.addEventListener('mouseout', this._onMouseOut.bind(this), false);
-    this.viewportElement.addEventListener('mousewheel', this._onMouseWheel.bind(this), false);
-    this.viewportElement.addEventListener('keydown', this._onChartKeyDown.bind(this), false);
-    this.viewportElement.addEventListener('keyup', this._onChartKeyUp.bind(this), false);
-
-    UI.installDragHandle(
-        this.viewportElement, this._startDragging.bind(this), this._dragging.bind(this), this._endDragging.bind(this),
-        '-webkit-grabbing', null);
-    UI.installDragHandle(
-        this.viewportElement, this._startRangeSelection.bind(this), this._rangeSelectionDragging.bind(this),
-        this._endRangeSelection.bind(this), 'text', null);
-
-    this._alwaysShowVerticalScroll = false;
-    this._rangeSelectionEnabled = true;
-    this._vScrollElement = this.contentElement.createChild('div', 'chart-viewport-v-scroll');
-    this._vScrollContent = this._vScrollElement.createChild('div');
-    this._vScrollElement.addEventListener('scroll', this._onScroll.bind(this), false);
-
-    this._selectionOverlay = this.contentElement.createChild('div', 'chart-viewport-selection-overlay hidden');
-    this._selectedTimeSpanLabel = this._selectionOverlay.createChild('div', 'time-span');
-
-    this._cursorElement = this.contentElement.createChild('div', 'chart-cursor-element hidden');
-
-    this.reset();
-  }
-
-  alwaysShowVerticalScroll() {
-    this._alwaysShowVerticalScroll = true;
-    this._vScrollElement.classList.add('always-show-scrollbar');
-  }
-
-  disableRangeSelection() {
-    this._rangeSelectionEnabled = false;
-    this._rangeSelectionStart = null;
-    this._rangeSelectionEnd = null;
-    this._updateRangeSelectionOverlay();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDragging() {
-    return this._isDragging;
-  }
-
-  /**
-   * @override
-   * @return {!Array<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [this._vScrollElement];
-  }
-
-  _updateScrollBar() {
-    const showScroll = this._alwaysShowVerticalScroll || this._totalHeight > this._offsetHeight;
-    if (this._vScrollElement.classList.contains('hidden') !== showScroll)
-      return;
-    this._vScrollElement.classList.toggle('hidden', !showScroll);
-    this._updateContentElementSize();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._updateScrollBar();
-    this._updateContentElementSize();
-    this.scheduleUpdate();
-  }
-
-  reset() {
-    this._vScrollElement.scrollTop = 0;
-    this._scrollTop = 0;
-    this._rangeSelectionStart = null;
-    this._rangeSelectionEnd = null;
-    this._isDragging = false;
-    this._dragStartPointX = 0;
-    this._dragStartPointY = 0;
-    this._dragStartScrollTop = 0;
-    this._visibleLeftTime = 0;
-    this._visibleRightTime = 0;
-    this._offsetWidth = 0;
-    this._offsetHeight = 0;
-    this._totalHeight = 0;
-    this._targetLeftTime = 0;
-    this._targetRightTime = 0;
-    this._updateContentElementSize();
-  }
-
-  _updateContentElementSize() {
-    let offsetWidth = this._vScrollElement.offsetLeft;
-    if (!offsetWidth)
-      offsetWidth = this.contentElement.offsetWidth;
-    this._offsetWidth = offsetWidth;
-    this._offsetHeight = this.contentElement.offsetHeight;
-    this._delegate.setSize(this._offsetWidth, this._offsetHeight);
-  }
-
-  /**
-   * @param {number} totalHeight
-   */
-  setContentHeight(totalHeight) {
-    this._totalHeight = totalHeight;
-    this._vScrollContent.style.height = totalHeight + 'px';
-    this._updateScrollBar();
-    if (this._scrollTop + this._offsetHeight <= totalHeight)
-      return;
-    this._scrollTop = Math.max(0, totalHeight - this._offsetHeight);
-    this._vScrollElement.scrollTop = this._scrollTop;
-  }
-
-  /**
-   * @param {number} offset
-   * @param {number=} height
-   */
-  setScrollOffset(offset, height) {
-    height = height || 0;
-    if (this._vScrollElement.scrollTop > offset)
-      this._vScrollElement.scrollTop = offset;
-    else if (this._vScrollElement.scrollTop < offset - this._offsetHeight + height)
-      this._vScrollElement.scrollTop = offset - this._offsetHeight + height;
-  }
-
-  /**
-   * @return {number}
-   */
-  scrollOffset() {
-    return this._vScrollElement.scrollTop;
-  }
-
-  /**
-   * @param {number} zeroTime
-   * @param {number} totalTime
-   */
-  setBoundaries(zeroTime, totalTime) {
-    this._minimumBoundary = zeroTime;
-    this._totalTime = totalTime;
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _onMouseWheel(e) {
-    const doZoomInstead = e.shiftKey ^ (Common.moduleSetting('flamechartMouseWheelAction').get() === 'zoom');
-    const panVertically = !doZoomInstead && (e.wheelDeltaY || Math.abs(e.wheelDeltaX) === 120);
-    const panHorizontally = doZoomInstead && Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY);
-    if (panVertically) {
-      this._vScrollElement.scrollTop -= (e.wheelDeltaY || e.wheelDeltaX) / 120 * this._offsetHeight / 8;
-    } else if (panHorizontally) {
-      this._handlePanGesture(-e.wheelDeltaX, /* animate */ true);
-    } else {  // Zoom.
-      const mouseWheelZoomSpeed = 1 / 120;
-      this._handleZoomGesture(Math.pow(1.2, -(e.wheelDeltaY || e.wheelDeltaX) * mouseWheelZoomSpeed) - 1);
-    }
-
-    // Block swipe gesture.
-    e.consume(true);
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _startDragging(event) {
-    if (event.shiftKey)
-      return false;
-    this._isDragging = true;
-    this._dragStartPointX = event.pageX;
-    this._dragStartPointY = event.pageY;
-    this._dragStartScrollTop = this._vScrollElement.scrollTop;
-    this.viewportElement.style.cursor = '';
-    return true;
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _dragging(event) {
-    const pixelShift = this._dragStartPointX - event.pageX;
-    this._dragStartPointX = event.pageX;
-    this._handlePanGesture(pixelShift);
-    const pixelScroll = this._dragStartPointY - event.pageY;
-    this._vScrollElement.scrollTop = this._dragStartScrollTop + pixelScroll;
-  }
-
-  _endDragging() {
-    this._isDragging = false;
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _startRangeSelection(event) {
-    if (!event.shiftKey || !this._rangeSelectionEnabled)
-      return false;
-    this._isDragging = true;
-    this._selectionOffsetShiftX = event.offsetX - event.pageX;
-    this._selectionOffsetShiftY = event.offsetY - event.pageY;
-    this._selectionStartX = event.offsetX;
-    const style = this._selectionOverlay.style;
-    style.left = this._selectionStartX + 'px';
-    style.width = '1px';
-    this._selectedTimeSpanLabel.textContent = '';
-    this._selectionOverlay.classList.remove('hidden');
-    return true;
-  }
-
-  _endRangeSelection() {
-    this._isDragging = false;
-    this._selectionStartX = null;
-  }
-
-  hideRangeSelection() {
-    this._selectionOverlay.classList.add('hidden');
-    this._rangeSelectionStart = null;
-    this._rangeSelectionEnd = null;
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  setRangeSelection(startTime, endTime) {
-    if (!this._rangeSelectionEnabled)
-      return;
-    this._rangeSelectionStart = Math.min(startTime, endTime);
-    this._rangeSelectionEnd = Math.max(startTime, endTime);
-    this._updateRangeSelectionOverlay();
-    this._delegate.updateRangeSelection(this._rangeSelectionStart, this._rangeSelectionEnd);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  onClick(event) {
-    const time = this.pixelToTime(event.offsetX);
-    if (this._rangeSelectionStart !== null && time >= this._rangeSelectionStart && time <= this._rangeSelectionEnd)
-      return;
-    this.hideRangeSelection();
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _rangeSelectionDragging(event) {
-    const x = Number.constrain(event.pageX + this._selectionOffsetShiftX, 0, this._offsetWidth);
-    const start = this.pixelToTime(this._selectionStartX);
-    const end = this.pixelToTime(x);
-    this.setRangeSelection(start, end);
-  }
-
-  _updateRangeSelectionOverlay() {
-    const /** @const */ margin = 100;
-    const left = Number.constrain(this.timeToPosition(this._rangeSelectionStart), -margin, this._offsetWidth + margin);
-    const right = Number.constrain(this.timeToPosition(this._rangeSelectionEnd), -margin, this._offsetWidth + margin);
-    const style = this._selectionOverlay.style;
-    style.left = left + 'px';
-    style.width = (right - left) + 'px';
-    const timeSpan = this._rangeSelectionEnd - this._rangeSelectionStart;
-    this._selectedTimeSpanLabel.textContent = Number.preciseMillisToString(timeSpan, 2);
-  }
-
-  _onScroll() {
-    this._scrollTop = this._vScrollElement.scrollTop;
-    this.scheduleUpdate();
-  }
-
-  _onMouseOut() {
-    this._lastMouseOffsetX = -1;
-    this._showCursor(false);
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _updateCursorPosition(e) {
-    this._showCursor(e.shiftKey);
-    this._cursorElement.style.left = e.offsetX + 'px';
-    this._lastMouseOffsetX = e.offsetX;
-  }
-
-  /**
-   * @param {number} x
-   * @return {number}
-   */
-  pixelToTime(x) {
-    return this.pixelToTimeOffset(x) + this._visibleLeftTime;
-  }
-
-  /**
-   * @param {number} x
-   * @return {number}
-   */
-  pixelToTimeOffset(x) {
-    return x * (this._visibleRightTime - this._visibleLeftTime) / this._offsetWidth;
-  }
-
-  /**
-   * @param {number} time
-   * @return {number}
-   */
-  timeToPosition(time) {
-    return Math.floor(
-        (time - this._visibleLeftTime) / (this._visibleRightTime - this._visibleLeftTime) * this._offsetWidth);
-  }
-
-  /**
-   * @return {number}
-   */
-  timeToPixel() {
-    return this._offsetWidth / (this._visibleRightTime - this._visibleLeftTime);
-  }
-
-  /**
-   * @param {boolean} visible
-   */
-  _showCursor(visible) {
-    this._cursorElement.classList.toggle('hidden', !visible || this._isDragging);
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _onChartKeyDown(e) {
-    this._showCursor(e.shiftKey);
-    this._handleZoomPanKeys(e);
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _onChartKeyUp(e) {
-    this._showCursor(e.shiftKey);
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _handleZoomPanKeys(e) {
-    if (!UI.KeyboardShortcut.hasNoModifiers(e))
-      return;
-    const zoomFactor = e.shiftKey ? 0.8 : 0.3;
-    const panOffset = e.shiftKey ? 320 : 160;
-    switch (e.code) {
-      case 'KeyA':
-        this._handlePanGesture(-panOffset, /* animate */ true);
-        break;
-      case 'KeyD':
-        this._handlePanGesture(panOffset, /* animate */ true);
-        break;
-      case 'KeyW':
-        this._handleZoomGesture(-zoomFactor);
-        break;
-      case 'KeyS':
-        this._handleZoomGesture(zoomFactor);
-        break;
-      default:
-        return;
-    }
-    e.consume(true);
-  }
-
-  /**
-   * @param {number} zoom
-   */
-  _handleZoomGesture(zoom) {
-    const bounds = {left: this._targetLeftTime, right: this._targetRightTime};
-    const cursorTime = this.pixelToTime(this._lastMouseOffsetX);
-    bounds.left += (bounds.left - cursorTime) * zoom;
-    bounds.right += (bounds.right - cursorTime) * zoom;
-    this._requestWindowTimes(bounds, /* animate */ true);
-  }
-
-  /**
-   * @param {number} offset
-   * @param {boolean=} animate
-   */
-  _handlePanGesture(offset, animate) {
-    const bounds = {left: this._targetLeftTime, right: this._targetRightTime};
-    const timeOffset = Number.constrain(
-        this.pixelToTimeOffset(offset), this._minimumBoundary - bounds.left,
-        this._totalTime + this._minimumBoundary - bounds.right);
-    bounds.left += timeOffset;
-    bounds.right += timeOffset;
-    this._requestWindowTimes(bounds, !!animate);
-  }
-
-  /**
-   * @param {!{left: number, right: number}} bounds
-   * @param {boolean} animate
-   */
-  _requestWindowTimes(bounds, animate) {
-    const maxBound = this._minimumBoundary + this._totalTime;
-    if (bounds.left < this._minimumBoundary) {
-      bounds.right = Math.min(bounds.right + this._minimumBoundary - bounds.left, maxBound);
-      bounds.left = this._minimumBoundary;
-    } else if (bounds.right > maxBound) {
-      bounds.left = Math.max(bounds.left - bounds.right + maxBound, this._minimumBoundary);
-      bounds.right = maxBound;
-    }
-    if (bounds.right - bounds.left < PerfUI.FlameChart.MinimalTimeWindowMs)
-      return;
-    this._delegate.requestWindowTimes(bounds.left, bounds.right, animate);
-  }
-
-  scheduleUpdate() {
-    if (this._updateTimerId || this._cancelWindowTimesAnimation)
-      return;
-    this._updateTimerId = this.element.window().requestAnimationFrame(() => {
-      this._updateTimerId = 0;
-      this._update();
-    });
-  }
-
-  _update() {
-    this._updateRangeSelectionOverlay();
-    this._delegate.update();
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {boolean=} animate
-   */
-  setWindowTimes(startTime, endTime, animate) {
-    if (startTime === this._targetLeftTime && endTime === this._targetRightTime)
-      return;
-    if (!animate || this._visibleLeftTime === 0 || this._visibleRightTime === Infinity ||
-        (startTime === 0 && endTime === Infinity) || (startTime === Infinity && endTime === Infinity)) {
-      // Skip animation, move instantly.
-      this._targetLeftTime = startTime;
-      this._targetRightTime = endTime;
-      this._visibleLeftTime = startTime;
-      this._visibleRightTime = endTime;
-      this.scheduleUpdate();
-      return;
-    }
-    if (this._cancelWindowTimesAnimation) {
-      this._cancelWindowTimesAnimation();
-      this._visibleLeftTime = this._targetLeftTime;
-      this._visibleRightTime = this._targetRightTime;
-    }
-    this._targetLeftTime = startTime;
-    this._targetRightTime = endTime;
-    this._cancelWindowTimesAnimation = UI.animateFunction(
-        this.element.window(), animateWindowTimes.bind(this),
-        [{from: this._visibleLeftTime, to: startTime}, {from: this._visibleRightTime, to: endTime}], 100,
-        () => this._cancelWindowTimesAnimation = null);
-
-    /**
-     * @param {number} startTime
-     * @param {number} endTime
-     * @this {PerfUI.ChartViewport}
-     */
-    function animateWindowTimes(startTime, endTime) {
-      this._visibleLeftTime = startTime;
-      this._visibleRightTime = endTime;
-      this._update();
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  windowLeftTime() {
-    return this._visibleLeftTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  windowRightTime() {
-    return this._visibleRightTime;
-  }
-};
diff --git a/front_end/perf_ui/FilmStripView.js b/front_end/perf_ui/FilmStripView.js
deleted file mode 100644
index 3b120e7..0000000
--- a/front_end/perf_ui/FilmStripView.js
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-PerfUI.FilmStripView = class extends UI.HBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('perf_ui/filmStripView.css');
-    this.contentElement.classList.add('film-strip-view');
-    this._statusLabel = this.contentElement.createChild('div', 'label');
-    this.reset();
-    this.setMode(PerfUI.FilmStripView.Modes.TimeBased);
-  }
-
-  /**
-   * @param {!Element} imageElement
-   * @param {?string} data
-   */
-  static _setImageData(imageElement, data) {
-    if (data)
-      imageElement.src = 'data:image/jpg;base64,' + data;
-  }
-
-  /**
-   * @param {string} mode
-   */
-  setMode(mode) {
-    this._mode = mode;
-    this.contentElement.classList.toggle('time-based', mode === PerfUI.FilmStripView.Modes.TimeBased);
-    this.update();
-  }
-
-  /**
-   * @param {!SDK.FilmStripModel} filmStripModel
-   * @param {number} zeroTime
-   * @param {number} spanTime
-   */
-  setModel(filmStripModel, zeroTime, spanTime) {
-    this._model = filmStripModel;
-    this._zeroTime = zeroTime;
-    this._spanTime = spanTime;
-    const frames = filmStripModel.frames();
-    if (!frames.length) {
-      this.reset();
-      return;
-    }
-    this.update();
-  }
-
-  /**
-   * @param {!SDK.FilmStripModel.Frame} frame
-   * @return {!Promise<!Element>}
-   */
-  createFrameElement(frame) {
-    const time = frame.timestamp;
-    const element = createElementWithClass('div', 'frame');
-    element.title = Common.UIString('Doubleclick to zoom image. Click to view preceding requests.');
-    element.createChild('div', 'time').textContent = Number.millisToString(time - this._zeroTime);
-    const imageElement = element.createChild('div', 'thumbnail').createChild('img');
-    element.addEventListener(
-        'mousedown', this._onMouseEvent.bind(this, PerfUI.FilmStripView.Events.FrameSelected, time), false);
-    element.addEventListener(
-        'mouseenter', this._onMouseEvent.bind(this, PerfUI.FilmStripView.Events.FrameEnter, time), false);
-    element.addEventListener(
-        'mouseout', this._onMouseEvent.bind(this, PerfUI.FilmStripView.Events.FrameExit, time), false);
-    element.addEventListener('dblclick', this._onDoubleClick.bind(this, frame), false);
-
-    return frame.imageDataPromise()
-        .then(PerfUI.FilmStripView._setImageData.bind(null, imageElement))
-        .then(returnElement);
-    /**
-     * @return {!Element}
-     */
-    function returnElement() {
-      return element;
-    }
-  }
-
-  /**
-   * @param {number} time
-   * @return {!SDK.FilmStripModel.Frame}
-   */
-  frameByTime(time) {
-    /**
-     * @param {number} time
-     * @param {!SDK.FilmStripModel.Frame} frame
-     * @return {number}
-     */
-    function comparator(time, frame) {
-      return time - frame.timestamp;
-    }
-    // Using the first frame to fill the interval between recording start
-    // and a moment the frame is taken.
-    const frames = this._model.frames();
-    const index = Math.max(frames.upperBound(time, comparator) - 1, 0);
-    return frames[index];
-  }
-
-  update() {
-    if (!this._model)
-      return;
-    const frames = this._model.frames();
-    if (!frames.length)
-      return;
-
-    if (this._mode === PerfUI.FilmStripView.Modes.FrameBased) {
-      Promise.all(frames.map(this.createFrameElement.bind(this))).then(appendElements.bind(this));
-      return;
-    }
-
-    const width = this.contentElement.clientWidth;
-    const scale = this._spanTime / width;
-    this.createFrameElement(frames[0]).then(
-        continueWhenFrameImageLoaded.bind(this));  // Calculate frame width basing on the first frame.
-
-    /**
-     * @this {PerfUI.FilmStripView}
-     * @param {!Element} element0
-     */
-    function continueWhenFrameImageLoaded(element0) {
-      const frameWidth = Math.ceil(UI.measurePreferredSize(element0, this.contentElement).width);
-      if (!frameWidth)
-        return;
-
-      const promises = [];
-      for (let pos = frameWidth; pos < width; pos += frameWidth) {
-        const time = pos * scale + this._zeroTime;
-        promises.push(this.createFrameElement(this.frameByTime(time)).then(fixWidth));
-      }
-      Promise.all(promises).then(appendElements.bind(this));
-      /**
-       * @param {!Element} element
-       * @return {!Element}
-       */
-      function fixWidth(element) {
-        element.style.width = frameWidth + 'px';
-        return element;
-      }
-    }
-
-    /**
-     * @param {!Array.<!Element>} elements
-     * @this {PerfUI.FilmStripView}
-     */
-    function appendElements(elements) {
-      this.contentElement.removeChildren();
-      for (let i = 0; i < elements.length; ++i)
-        this.contentElement.appendChild(elements[i]);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._mode === PerfUI.FilmStripView.Modes.FrameBased)
-      return;
-    this.update();
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {number} timestamp
-   */
-  _onMouseEvent(eventName, timestamp) {
-    this.dispatchEventToListeners(eventName, timestamp);
-  }
-
-  /**
-   * @param {!SDK.FilmStripModel.Frame} filmStripFrame
-   */
-  _onDoubleClick(filmStripFrame) {
-    new PerfUI.FilmStripView.Dialog(filmStripFrame, this._zeroTime);
-  }
-
-  reset() {
-    this._zeroTime = 0;
-    this.contentElement.removeChildren();
-    this.contentElement.appendChild(this._statusLabel);
-  }
-
-  /**
-   * @param {string} text
-   */
-  setStatusText(text) {
-    this._statusLabel.textContent = text;
-  }
-};
-
-/** @enum {symbol} */
-PerfUI.FilmStripView.Events = {
-  FrameSelected: Symbol('FrameSelected'),
-  FrameEnter: Symbol('FrameEnter'),
-  FrameExit: Symbol('FrameExit'),
-};
-
-PerfUI.FilmStripView.Modes = {
-  TimeBased: 'TimeBased',
-  FrameBased: 'FrameBased'
-};
-
-PerfUI.FilmStripView.Dialog = class {
-  /**
-   * @param {!SDK.FilmStripModel.Frame} filmStripFrame
-   * @param {number=} zeroTime
-   */
-  constructor(filmStripFrame, zeroTime) {
-    const prevButton = UI.createTextButton('\u25C0', this._onPrevFrame.bind(this));
-    prevButton.title = Common.UIString('Previous frame');
-    const nextButton = UI.createTextButton('\u25B6', this._onNextFrame.bind(this));
-    nextButton.title = Common.UIString('Next frame');
-
-    this._fragment = UI.Fragment.build`
-      <x-widget flex=none margin=12px>
-        <x-hbox overflow=auto border='1px solid #ddd' max-height=80vh max-width=80vw>
-          <img $=image></img>
-        </x-hbox>
-        <x-hbox x-center justify-content=center margin-top=10px>
-          ${prevButton}
-          <x-hbox $=time margin=8px></x-hbox>
-          ${nextButton}
-        </x-hbox>
-      </x-widget>
-    `;
-
-    this._widget = /** @type {!UI.XWidget} */ (this._fragment.element());
-    this._widget.tabIndex = 0;
-    this._widget.addEventListener('keydown', this._keyDown.bind(this), false);
-
-    this._frames = filmStripFrame.model().frames();
-    this._index = filmStripFrame.index;
-    this._zeroTime = zeroTime || filmStripFrame.model().zeroTime();
-    /** @type {?UI.Dialog} */
-    this._dialog = null;
-    this._render();
-  }
-
-  _resize() {
-    if (!this._dialog) {
-      this._dialog = new UI.Dialog();
-      this._dialog.contentElement.appendChild(this._widget);
-      this._dialog.setDefaultFocusedElement(this._widget);
-      this._dialog.show();
-    }
-    this._dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _keyDown(event) {
-    switch (event.key) {
-      case 'ArrowLeft':
-        if (Host.isMac() && event.metaKey)
-          this._onFirstFrame();
-        else
-          this._onPrevFrame();
-        break;
-
-      case 'ArrowRight':
-        if (Host.isMac() && event.metaKey)
-          this._onLastFrame();
-        else
-          this._onNextFrame();
-        break;
-
-      case 'Home':
-        this._onFirstFrame();
-        break;
-
-      case 'End':
-        this._onLastFrame();
-        break;
-    }
-  }
-
-  _onPrevFrame() {
-    if (this._index > 0)
-      --this._index;
-    this._render();
-  }
-
-  _onNextFrame() {
-    if (this._index < this._frames.length - 1)
-      ++this._index;
-    this._render();
-  }
-
-  _onFirstFrame() {
-    this._index = 0;
-    this._render();
-  }
-
-  _onLastFrame() {
-    this._index = this._frames.length - 1;
-    this._render();
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  _render() {
-    const frame = this._frames[this._index];
-    this._fragment.$('time').textContent = Number.millisToString(frame.timestamp - this._zeroTime);
-    return frame.imageDataPromise()
-        .then(PerfUI.FilmStripView._setImageData.bind(null, this._fragment.$('image')))
-        .then(this._resize.bind(this));
-  }
-};
diff --git a/front_end/perf_ui/FlameChart.js b/front_end/perf_ui/FlameChart.js
deleted file mode 100644
index de2f855..0000000
--- a/front_end/perf_ui/FlameChart.js
+++ /dev/null
@@ -1,1675 +0,0 @@
-/**
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @interface
- */
-PerfUI.FlameChartDelegate = function() {};
-
-PerfUI.FlameChartDelegate.prototype = {
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {boolean} animate
-   */
-  requestWindowTimes(startTime, endTime, animate) {},
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  updateRangeSelection(startTime, endTime) {},
-
-  /**
-   * @param {!PerfUI.FlameChart} flameChart
-   * @param {?PerfUI.FlameChart.Group} group
-   */
-  updateSelectedGroup(flameChart, group) {},
-};
-
-/**
- * @unrestricted
- * @implements {PerfUI.TimelineGrid.Calculator}
- * @implements {PerfUI.ChartViewportDelegate}
- */
-PerfUI.FlameChart = class extends UI.VBox {
-  /**
-   * @param {!PerfUI.FlameChartDataProvider} dataProvider
-   * @param {!PerfUI.FlameChartDelegate} flameChartDelegate
-   * @param {!Common.Setting=} groupExpansionSetting
-   */
-  constructor(dataProvider, flameChartDelegate, groupExpansionSetting) {
-    super(true);
-    this.registerRequiredCSS('perf_ui/flameChart.css');
-    this.contentElement.classList.add('flame-chart-main-pane');
-    this._groupExpansionSetting = groupExpansionSetting;
-    this._groupExpansionState = groupExpansionSetting && groupExpansionSetting.get() || {};
-    this._flameChartDelegate = flameChartDelegate;
-
-    this._chartViewport = new PerfUI.ChartViewport(this);
-    this._chartViewport.show(this.contentElement);
-
-    this._dataProvider = dataProvider;
-
-    this._viewportElement = this._chartViewport.viewportElement;
-    this._canvas = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas'));
-
-    this._canvas.tabIndex = 1;
-    this.setDefaultFocusedElement(this._canvas);
-    this._canvas.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    this._canvas.addEventListener('mouseout', this._onMouseOut.bind(this), false);
-    this._canvas.addEventListener('click', this._onClick.bind(this), false);
-    this._canvas.addEventListener('keydown', this._onKeyDown.bind(this), false);
-
-    this._entryInfo = this._viewportElement.createChild('div', 'flame-chart-entry-info');
-    this._markerHighlighElement = this._viewportElement.createChild('div', 'flame-chart-marker-highlight-element');
-    this._highlightElement = this._viewportElement.createChild('div', 'flame-chart-highlight-element');
-    this._selectedElement = this._viewportElement.createChild('div', 'flame-chart-selected-element');
-
-    UI.installDragHandle(
-        this._viewportElement, this._startDragging.bind(this), this._dragging.bind(this), this._endDragging.bind(this),
-        null);
-
-    this._rulerEnabled = true;
-    this._rangeSelectionStart = 0;
-    this._rangeSelectionEnd = 0;
-    this._barHeight = 17;
-    this._textBaseline = 5;
-    this._textPadding = 5;
-    this._markerRadius = 6;
-    this._chartViewport.setWindowTimes(
-        dataProvider.minimumBoundary(), dataProvider.minimumBoundary() + dataProvider.totalTime());
-
-    /** @const */
-    this._headerLeftPadding = 6;
-    /** @const */
-    this._arrowSide = 8;
-    /** @const */
-    this._expansionArrowIndent = this._headerLeftPadding + this._arrowSide / 2;
-    /** @const */
-    this._headerLabelXPadding = 3;
-    /** @const */
-    this._headerLabelYPadding = 2;
-
-    this._highlightedMarkerIndex = -1;
-    this._highlightedEntryIndex = -1;
-    this._selectedEntryIndex = -1;
-    this._rawTimelineDataLength = 0;
-    /** @type {!Map<string,!Map<string,number>>} */
-    this._textWidth = new Map();
-
-    this._lastMouseOffsetX = 0;
-    this._selectedGroup = -1;
-    this._selectedGroupBackroundColor = UI.themeSupport.patchColorText(
-        PerfUI.FlameChart.Colors.SelectedGroupBackground, UI.ThemeSupport.ColorUsage.Background);
-    this._selectedGroupBorderColor = UI.themeSupport.patchColorText(
-        PerfUI.FlameChart.Colors.SelectedGroupBorder, UI.ThemeSupport.ColorUsage.Background);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this.hideHighlight();
-  }
-
-  /**
-   * @param {number} value
-   */
-  setBarHeight(value) {
-    this._barHeight = value;
-  }
-
-  /**
-   * @param {number} value
-   */
-  setTextBaseline(value) {
-    this._textBaseline = value;
-  }
-
-  /**
-   * @param {number} value
-   */
-  setTextPadding(value) {
-    this._textPadding = value;
-  }
-
-  /**
-   * @param {boolean} enable
-   */
-  enableRuler(enable) {
-    this._rulerEnabled = enable;
-  }
-
-  alwaysShowVerticalScroll() {
-    this._chartViewport.alwaysShowVerticalScroll();
-  }
-
-  disableRangeSelection() {
-    this._chartViewport.disableRangeSelection();
-  }
-
-  /**
-   * @param {number} entryIndex
-   */
-  highlightEntry(entryIndex) {
-    if (this._highlightedEntryIndex === entryIndex)
-      return;
-    if (!this._dataProvider.entryColor(entryIndex))
-      return;
-    this._highlightedEntryIndex = entryIndex;
-    this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
-    this.dispatchEventToListeners(PerfUI.FlameChart.Events.EntryHighlighted, entryIndex);
-  }
-
-  hideHighlight() {
-    this._entryInfo.removeChildren();
-    this._highlightedEntryIndex = -1;
-    this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
-    this.dispatchEventToListeners(PerfUI.FlameChart.Events.EntryHighlighted, -1);
-  }
-
-  _resetCanvas() {
-    const ratio = window.devicePixelRatio;
-    const width = Math.round(this._offsetWidth * ratio);
-    const height = Math.round(this._offsetHeight * ratio);
-    this._canvas.width = width;
-    this._canvas.height = height;
-    this._canvas.style.width = `${width / ratio}px`;
-    this._canvas.style.height = `${height / ratio}px`;
-  }
-
-  /**
-   * @override
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {boolean} animate
-   */
-  requestWindowTimes(startTime, endTime, animate) {
-    this._flameChartDelegate.requestWindowTimes(startTime, endTime, animate);
-  }
-
-  /**
-   * @override
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  updateRangeSelection(startTime, endTime) {
-    this._flameChartDelegate.updateRangeSelection(startTime, endTime);
-  }
-
-  /**
-   * @override
-   * @param {number} width
-   * @param {number} height
-   */
-  setSize(width, height) {
-    this._offsetWidth = width;
-    this._offsetHeight = height;
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _startDragging(event) {
-    this.hideHighlight();
-    this._maxDragOffset = 0;
-    this._dragStartX = event.pageX;
-    this._dragStartY = event.pageY;
-    return true;
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _dragging(event) {
-    const dx = event.pageX - this._dragStartX;
-    const dy = event.pageY - this._dragStartY;
-    this._maxDragOffset = Math.max(this._maxDragOffset, Math.sqrt(dx * dx + dy * dy));
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _endDragging(event) {
-    this._updateHighlight();
-  }
-
-  /**
-   * @return {?PerfUI.FlameChart.TimelineData}
-   */
-  _timelineData() {
-    if (!this._dataProvider)
-      return null;
-    const timelineData = this._dataProvider.timelineData();
-    if (timelineData !== this._rawTimelineData || timelineData.entryStartTimes.length !== this._rawTimelineDataLength)
-      this._processTimelineData(timelineData);
-    return this._rawTimelineData;
-  }
-
-  /**
-   * @param {number} entryIndex
-   */
-  _revealEntry(entryIndex) {
-    const timelineData = this._timelineData();
-    if (!timelineData)
-      return;
-    const timeLeft = this._chartViewport.windowLeftTime();
-    const timeRight = this._chartViewport.windowRightTime();
-    const entryStartTime = timelineData.entryStartTimes[entryIndex];
-    const entryTotalTime = timelineData.entryTotalTimes[entryIndex];
-    const entryEndTime = entryStartTime + entryTotalTime;
-    let minEntryTimeWindow = Math.min(entryTotalTime, timeRight - timeLeft);
-
-    const level = timelineData.entryLevels[entryIndex];
-    this._chartViewport.setScrollOffset(this._levelToOffset(level), this._levelHeight(level));
-
-    const minVisibleWidthPx = 30;
-    const futurePixelToTime = (timeRight - timeLeft) / this._offsetWidth;
-    minEntryTimeWindow = Math.max(minEntryTimeWindow, futurePixelToTime * minVisibleWidthPx);
-    if (timeLeft > entryEndTime) {
-      const delta = timeLeft - entryEndTime + minEntryTimeWindow;
-      this.requestWindowTimes(timeLeft - delta, timeRight - delta, /* animate */ true);
-    } else if (timeRight < entryStartTime) {
-      const delta = entryStartTime - timeRight + minEntryTimeWindow;
-      this.requestWindowTimes(timeLeft + delta, timeRight + delta, /* animate */ true);
-    }
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {boolean=} animate
-   */
-  setWindowTimes(startTime, endTime, animate) {
-    this._chartViewport.setWindowTimes(startTime, endTime, animate);
-    this._updateHighlight();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    this._lastMouseOffsetX = event.offsetX;
-    this._lastMouseOffsetY = event.offsetY;
-    if (!this._enabled())
-      return;
-    if (this._chartViewport.isDragging())
-      return;
-    if (this._coordinatesToGroupIndex(event.offsetX, event.offsetY, true /* headerOnly */) >= 0) {
-      this.hideHighlight();
-      this._viewportElement.style.cursor = 'pointer';
-      return;
-    }
-    this._updateHighlight();
-  }
-
-  _updateHighlight() {
-    const inDividersBar = this._lastMouseOffsetY < PerfUI.FlameChart.HeaderHeight;
-    this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPosition(this._lastMouseOffsetX) : -1;
-    this._updateMarkerHighlight();
-
-    const entryIndex = this._highlightedMarkerIndex === -1 ?
-        this._coordinatesToEntryIndex(this._lastMouseOffsetX, this._lastMouseOffsetY) :
-        -1;
-    if (entryIndex === -1) {
-      this.hideHighlight();
-      const group =
-          this._coordinatesToGroupIndex(this._lastMouseOffsetX, this._lastMouseOffsetY, false /* headerOnly */);
-      if (group >= 0 && this._rawTimelineData.groups[group].selectable)
-        this._viewportElement.style.cursor = 'pointer';
-      else
-        this._viewportElement.style.cursor = 'default';
-      return;
-    }
-    if (this._chartViewport.isDragging())
-      return;
-    this._updatePopover(entryIndex);
-    this._viewportElement.style.cursor = this._dataProvider.canJumpToEntry(entryIndex) ? 'pointer' : 'default';
-    this.highlightEntry(entryIndex);
-  }
-
-  _onMouseOut() {
-    this._lastMouseOffsetX = -1;
-    this._lastMouseOffsetY = -1;
-    this.hideHighlight();
-  }
-
-  /**
-   * @param {number} entryIndex
-   */
-  _updatePopover(entryIndex) {
-    if (entryIndex === this._highlightedEntryIndex) {
-      this._updatePopoverOffset();
-      return;
-    }
-    this._entryInfo.removeChildren();
-    const popoverElement = this._dataProvider.prepareHighlightedEntryInfo(entryIndex);
-    if (popoverElement) {
-      this._entryInfo.appendChild(popoverElement);
-      this._updatePopoverOffset();
-    }
-  }
-
-  _updatePopoverOffset() {
-    const mouseX = this._lastMouseOffsetX;
-    const mouseY = this._lastMouseOffsetY;
-    const parentWidth = this._entryInfo.parentElement.clientWidth;
-    const parentHeight = this._entryInfo.parentElement.clientHeight;
-    const infoWidth = this._entryInfo.clientWidth;
-    const infoHeight = this._entryInfo.clientHeight;
-    const /** @const */ offsetX = 10;
-    const /** @const */ offsetY = 6;
-    let x;
-    let y;
-    for (let quadrant = 0; quadrant < 4; ++quadrant) {
-      const dx = quadrant & 2 ? -offsetX - infoWidth : offsetX;
-      const dy = quadrant & 1 ? -offsetY - infoHeight : offsetY;
-      x = Number.constrain(mouseX + dx, 0, parentWidth - infoWidth);
-      y = Number.constrain(mouseY + dy, 0, parentHeight - infoHeight);
-      if (x >= mouseX || mouseX >= x + infoWidth || y >= mouseY || mouseY >= y + infoHeight)
-        break;
-    }
-    this._entryInfo.style.left = x + 'px';
-    this._entryInfo.style.top = y + 'px';
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    this.focus();
-    // onClick comes after dragStart and dragEnd events.
-    // So if there was drag (mouse move) in the middle of that events
-    // we skip the click. Otherwise we jump to the sources.
-    const /** @const */ clickThreshold = 5;
-    if (this._maxDragOffset > clickThreshold)
-      return;
-
-    this._selectGroup(this._coordinatesToGroupIndex(event.offsetX, event.offsetY, false /* headerOnly */));
-    this._toggleGroupVisibility(this._coordinatesToGroupIndex(event.offsetX, event.offsetY, true /* headerOnly */));
-    const timelineData = this._timelineData();
-    if (event.shiftKey && this._highlightedEntryIndex !== -1 && timelineData) {
-      const start = timelineData.entryStartTimes[this._highlightedEntryIndex];
-      const end = start + timelineData.entryTotalTimes[this._highlightedEntryIndex];
-      this._chartViewport.setRangeSelection(start, end);
-    } else {
-      this._chartViewport.onClick(event);
-      this.dispatchEventToListeners(PerfUI.FlameChart.Events.EntrySelected, this._highlightedEntryIndex);
-    }
-  }
-
-  /**
-   * @param {number} groupIndex
-   */
-  _selectGroup(groupIndex) {
-    const groups = this._rawTimelineData.groups;
-    if (groupIndex < 0 || !groups[groupIndex].selectable || this._selectedGroup === groupIndex)
-      return;
-
-    this._selectedGroup = groupIndex;
-    this._flameChartDelegate.updateSelectedGroup(this, groups[groupIndex]);
-    this._resetCanvas();
-    this._draw();
-  }
-
-  /**
-   * @param {number} groupIndex
-   */
-  _toggleGroupVisibility(groupIndex) {
-    if (groupIndex < 0 || !this._isGroupCollapsible(groupIndex))
-      return;
-
-    const groups = this._rawTimelineData.groups;
-    const group = groups[groupIndex];
-    group.expanded = !group.expanded;
-    this._groupExpansionState[group.name] = group.expanded;
-    if (this._groupExpansionSetting)
-      this._groupExpansionSetting.set(this._groupExpansionState);
-    this._updateLevelPositions();
-
-    this._updateHighlight();
-    if (!group.expanded) {
-      const timelineData = this._timelineData();
-      const level = timelineData.entryLevels[this._selectedEntryIndex];
-      if (this._selectedEntryIndex >= 0 && level >= group.startLevel &&
-          (groupIndex >= groups.length - 1 || groups[groupIndex + 1].startLevel > level))
-        this._selectedEntryIndex = -1;
-    }
-
-    this._updateHeight();
-    this._resetCanvas();
-    this._draw();
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _onKeyDown(e) {
-    this._handleSelectionNavigation(e);
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _handleSelectionNavigation(e) {
-    if (!UI.KeyboardShortcut.hasNoModifiers(e))
-      return;
-    if (this._selectedEntryIndex === -1)
-      return;
-    const timelineData = this._timelineData();
-    if (!timelineData)
-      return;
-
-    /**
-     * @param {number} time
-     * @param {number} entryIndex
-     * @return {number}
-     */
-    function timeComparator(time, entryIndex) {
-      return time - timelineData.entryStartTimes[entryIndex];
-    }
-
-    /**
-     * @param {number} entry1
-     * @param {number} entry2
-     * @return {boolean}
-     */
-    function entriesIntersect(entry1, entry2) {
-      const start1 = timelineData.entryStartTimes[entry1];
-      const start2 = timelineData.entryStartTimes[entry2];
-      const end1 = start1 + timelineData.entryTotalTimes[entry1];
-      const end2 = start2 + timelineData.entryTotalTimes[entry2];
-      return start1 < end2 && start2 < end1;
-    }
-
-    const keys = UI.KeyboardShortcut.Keys;
-    if (e.keyCode === keys.Left.code || e.keyCode === keys.Right.code) {
-      const level = timelineData.entryLevels[this._selectedEntryIndex];
-      const levelIndexes = this._timelineLevels[level];
-      let indexOnLevel = levelIndexes.lowerBound(this._selectedEntryIndex);
-      indexOnLevel += e.keyCode === keys.Left.code ? -1 : 1;
-      e.consume(true);
-      if (indexOnLevel >= 0 && indexOnLevel < levelIndexes.length)
-        this.dispatchEventToListeners(PerfUI.FlameChart.Events.EntrySelected, levelIndexes[indexOnLevel]);
-      return;
-    }
-    if (e.keyCode === keys.Up.code || e.keyCode === keys.Down.code) {
-      e.consume(true);
-      let level = timelineData.entryLevels[this._selectedEntryIndex];
-      level += e.keyCode === keys.Up.code ? -1 : 1;
-      if (level < 0 || level >= this._timelineLevels.length)
-        return;
-      const entryTime = timelineData.entryStartTimes[this._selectedEntryIndex] +
-          timelineData.entryTotalTimes[this._selectedEntryIndex] / 2;
-      const levelIndexes = this._timelineLevels[level];
-      let indexOnLevel = levelIndexes.upperBound(entryTime, timeComparator) - 1;
-      if (!entriesIntersect(this._selectedEntryIndex, levelIndexes[indexOnLevel])) {
-        ++indexOnLevel;
-        if (indexOnLevel >= levelIndexes.length ||
-            !entriesIntersect(this._selectedEntryIndex, levelIndexes[indexOnLevel]))
-          return;
-      }
-      this.dispatchEventToListeners(PerfUI.FlameChart.Events.EntrySelected, levelIndexes[indexOnLevel]);
-    }
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @return {number}
-   */
-  _coordinatesToEntryIndex(x, y) {
-    if (x < 0 || y < 0)
-      return -1;
-    const timelineData = this._timelineData();
-    if (!timelineData)
-      return -1;
-    y += this._chartViewport.scrollOffset();
-    const cursorLevel = this._visibleLevelOffsets.upperBound(y) - 1;
-    if (cursorLevel < 0 || !this._visibleLevels[cursorLevel])
-      return -1;
-    const offsetFromLevel = y - this._visibleLevelOffsets[cursorLevel];
-    if (offsetFromLevel > this._levelHeight(cursorLevel))
-      return -1;
-    const entryStartTimes = timelineData.entryStartTimes;
-    const entryTotalTimes = timelineData.entryTotalTimes;
-    const entryIndexes = this._timelineLevels[cursorLevel];
-    if (!entryIndexes || !entryIndexes.length)
-      return -1;
-
-    /**
-     * @param {number} time
-     * @param {number} entryIndex
-     * @return {number}
-     */
-    function comparator(time, entryIndex) {
-      return time - entryStartTimes[entryIndex];
-    }
-    const cursorTime = this._chartViewport.pixelToTime(x);
-    const indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparator) - 1, 0);
-
-    /**
-     * @this {PerfUI.FlameChart}
-     * @param {number} entryIndex
-     * @return {boolean}
-     */
-    function checkEntryHit(entryIndex) {
-      if (entryIndex === undefined)
-        return false;
-      const startTime = entryStartTimes[entryIndex];
-      const startX = this._chartViewport.timeToPosition(startTime);
-      const duration = entryTotalTimes[entryIndex];
-      if (isNaN(duration)) {
-        const dx = startX - x;
-        const dy = this._levelHeight(cursorLevel) / 2 - offsetFromLevel;
-        return dx * dx + dy * dy < this._markerRadius * this._markerRadius;
-      }
-      const endX = this._chartViewport.timeToPosition(startTime + duration);
-      const /** @const */ barThresholdPx = 3;
-      return startX - barThresholdPx < x && x < endX + barThresholdPx;
-    }
-
-    let entryIndex = entryIndexes[indexOnLevel];
-    if (checkEntryHit.call(this, entryIndex))
-      return entryIndex;
-    entryIndex = entryIndexes[indexOnLevel + 1];
-    if (checkEntryHit.call(this, entryIndex))
-      return entryIndex;
-    return -1;
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @param {boolean} headerOnly
-   * @return {number}
-   */
-  _coordinatesToGroupIndex(x, y, headerOnly) {
-    if (x < 0 || y < 0)
-      return -1;
-    y += this._chartViewport.scrollOffset();
-    const groups = this._rawTimelineData.groups || [];
-    const group = this._groupOffsets.upperBound(y) - 1;
-    if (group < 0 || group >= groups.length)
-      return -1;
-    const height = headerOnly ? groups[group].style.height : this._groupOffsets[group + 1] - this._groupOffsets[group];
-    if (y - this._groupOffsets[group] >= height)
-      return -1;
-    if (!headerOnly)
-      return group;
-
-    const context = /** @type {!CanvasRenderingContext2D} */ (this._canvas.getContext('2d'));
-    context.save();
-    context.font = groups[group].style.font;
-    const right = this._headerLeftPadding + this._labelWidthForGroup(context, groups[group]);
-    context.restore();
-    if (x > right)
-      return -1;
-
-    return group;
-  }
-
-  /**
-   * @param {number} x
-   * @return {number}
-   */
-  _markerIndexAtPosition(x) {
-    const markers = this._timelineData().markers;
-    if (!markers)
-      return -1;
-    const /** @const */ accurracyOffsetPx = 4;
-    const time = this._chartViewport.pixelToTime(x);
-    const leftTime = this._chartViewport.pixelToTime(x - accurracyOffsetPx);
-    const rightTime = this._chartViewport.pixelToTime(x + accurracyOffsetPx);
-    const left = this._markerIndexBeforeTime(leftTime);
-    let markerIndex = -1;
-    let distance = Infinity;
-    for (let i = left; i < markers.length && markers[i].startTime() < rightTime; i++) {
-      const nextDistance = Math.abs(markers[i].startTime() - time);
-      if (nextDistance < distance) {
-        markerIndex = i;
-        distance = nextDistance;
-      }
-    }
-    return markerIndex;
-  }
-
-  /**
-   * @param {number} time
-   * @return {number}
-   */
-  _markerIndexBeforeTime(time) {
-    return this._timelineData().markers.lowerBound(
-        time, (markerTimestamp, marker) => markerTimestamp - marker.startTime());
-  }
-
-  _draw() {
-    const timelineData = this._timelineData();
-    if (!timelineData)
-      return;
-
-    const width = this._offsetWidth;
-    const height = this._offsetHeight;
-    const context = /** @type {!CanvasRenderingContext2D} */ (this._canvas.getContext('2d'));
-    context.save();
-    const ratio = window.devicePixelRatio;
-    const top = this._chartViewport.scrollOffset();
-    context.scale(ratio, ratio);
-    context.translate(0, -top);
-    const defaultFont = '11px ' + Host.fontFamily();
-    context.font = defaultFont;
-
-    const entryTotalTimes = timelineData.entryTotalTimes;
-    const entryStartTimes = timelineData.entryStartTimes;
-    const entryLevels = timelineData.entryLevels;
-    const timeToPixel = this._chartViewport.timeToPixel();
-
-    const titleIndices = [];
-    const markerIndices = [];
-    const textPadding = this._textPadding;
-    const minTextWidth = 2 * textPadding + UI.measureTextWidth(context, '\u2026');
-    const minVisibleBarLevel = Math.max(this._visibleLevelOffsets.upperBound(top) - 1, 0);
-
-    context.save();
-    this._forEachGroup((offset, index, group, isFirst, groupHeight) => {
-      if (index === this._selectedGroup) {
-        context.fillStyle = this._selectedGroupBackroundColor;
-        context.fillRect(0, offset - 2, width, groupHeight - 1);
-      }
-    });
-    context.restore();
-
-    /** @type {!Map<string, !Array<number>>} */
-    const colorBuckets = new Map();
-    for (let level = minVisibleBarLevel; level < this._dataProvider.maxStackDepth(); ++level) {
-      if (this._levelToOffset(level) > top + height)
-        break;
-      if (!this._visibleLevels[level])
-        continue;
-
-      // Entries are ordered by start time within a level, so find the last visible entry.
-      const levelIndexes = this._timelineLevels[level];
-      const rightIndexOnLevel =
-          levelIndexes.lowerBound(
-              this._chartViewport.windowRightTime(), (time, entryIndex) => time - entryStartTimes[entryIndex]) -
-          1;
-      let lastDrawOffset = Infinity;
-      for (let entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) {
-        const entryIndex = levelIndexes[entryIndexOnLevel];
-        const entryStartTime = entryStartTimes[entryIndex];
-        const entryOffsetRight = entryStartTime + (entryTotalTimes[entryIndex] || 0);
-        if (entryOffsetRight <= this._chartViewport.windowLeftTime())
-          break;
-
-        const barX = this._timeToPositionClipped(entryStartTime);
-        // Check if the entry entirely fits into an already drawn pixel, we can just skip drawing it.
-        if (barX >= lastDrawOffset)
-          continue;
-        lastDrawOffset = barX;
-
-        const color = this._dataProvider.entryColor(entryIndex);
-        let bucket = colorBuckets.get(color);
-        if (!bucket) {
-          bucket = [];
-          colorBuckets.set(color, bucket);
-        }
-        bucket.push(entryIndex);
-      }
-    }
-
-    const colors = colorBuckets.keysArray();
-    // We don't use for-of here because it's slow.
-    for (let c = 0; c < colors.length; ++c) {
-      const color = colors[c];
-      const indexes = colorBuckets.get(color);
-      context.beginPath();
-      for (let i = 0; i < indexes.length; ++i) {
-        const entryIndex = indexes[i];
-        const entryStartTime = entryStartTimes[entryIndex];
-        const barX = this._timeToPositionClipped(entryStartTime);
-        const duration = entryTotalTimes[entryIndex];
-        const barLevel = entryLevels[entryIndex];
-        const barHeight = this._levelHeight(barLevel);
-        const barY = this._levelToOffset(barLevel);
-        if (isNaN(duration)) {
-          context.moveTo(barX + this._markerRadius, barY + barHeight / 2);
-          context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2);
-          markerIndices.push(entryIndex);
-          continue;
-        }
-        const barRight = this._timeToPositionClipped(entryStartTime + duration);
-        const barWidth = Math.max(barRight - barX, 1);
-        if (color)
-          context.rect(barX, barY, barWidth - 0.4, barHeight - 1);
-        if (barWidth > minTextWidth || this._dataProvider.forceDecoration(entryIndex))
-          titleIndices.push(entryIndex);
-      }
-      if (!color)
-        continue;
-      context.fillStyle = color;
-      context.fill();
-    }
-
-    context.beginPath();
-    for (let m = 0; m < markerIndices.length; ++m) {
-      const entryIndex = markerIndices[m];
-      const entryStartTime = entryStartTimes[entryIndex];
-      const barX = this._timeToPositionClipped(entryStartTime);
-      const barLevel = entryLevels[entryIndex];
-      const y = this._levelToOffset(barLevel) + this._levelHeight(barLevel) / 2;
-      context.moveTo(barX + this._markerRadius, y);
-      context.arc(barX, y, this._markerRadius, 0, Math.PI * 2);
-    }
-    context.strokeStyle = 'rgba(0, 0, 0, 0.2)';
-    context.stroke();
-
-    context.textBaseline = 'alphabetic';
-    for (let i = 0; i < titleIndices.length; ++i) {
-      const entryIndex = titleIndices[i];
-      const entryStartTime = entryStartTimes[entryIndex];
-      const barX = this._timeToPositionClipped(entryStartTime);
-      const barRight = Math.min(this._timeToPositionClipped(entryStartTime + entryTotalTimes[entryIndex]), width) + 1;
-      const barWidth = barRight - barX;
-      const barLevel = entryLevels[entryIndex];
-      const barY = this._levelToOffset(barLevel);
-      let text = this._dataProvider.entryTitle(entryIndex);
-      if (text && text.length) {
-        context.font = this._dataProvider.entryFont(entryIndex) || defaultFont;
-        text = UI.trimTextMiddle(context, text, barWidth - 2 * textPadding);
-      }
-      const unclippedBarX = this._chartViewport.timeToPosition(entryStartTime);
-      const barHeight = this._levelHeight(barLevel);
-      if (this._dataProvider.decorateEntry(
-              entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixel))
-        continue;
-      if (!text || !text.length)
-        continue;
-      context.fillStyle = this._dataProvider.textColor(entryIndex);
-      context.fillText(text, barX + textPadding, barY + barHeight - this._textBaseline);
-    }
-
-    context.restore();
-
-    this._drawGroupHeaders(width, height);
-    this._drawFlowEvents(context, width, height);
-    this._drawMarkers();
-    const dividersData = PerfUI.TimelineGrid.calculateGridOffsets(this);
-    PerfUI.TimelineGrid.drawCanvasGrid(context, dividersData);
-    if (this._rulerEnabled) {
-      PerfUI.TimelineGrid.drawCanvasHeaders(
-          context, dividersData, time => this.formatValue(time, dividersData.precision), 3,
-          PerfUI.FlameChart.HeaderHeight);
-    }
-
-    this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
-    this._updateElementPosition(this._selectedElement, this._selectedEntryIndex);
-    this._updateMarkerHighlight();
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  _drawGroupHeaders(width, height) {
-    const context = /** @type {!CanvasRenderingContext2D} */ (this._canvas.getContext('2d'));
-    const top = this._chartViewport.scrollOffset();
-    const ratio = window.devicePixelRatio;
-    const groups = this._rawTimelineData.groups || [];
-    if (!groups.length)
-      return;
-
-    const groupOffsets = this._groupOffsets;
-    const lastGroupOffset = Array.prototype.peekLast.call(groupOffsets);
-    const colorUsage = UI.ThemeSupport.ColorUsage;
-
-    context.save();
-    context.scale(ratio, ratio);
-    context.translate(0, -top);
-    const defaultFont = '11px ' + Host.fontFamily();
-    context.font = defaultFont;
-
-    context.fillStyle = UI.themeSupport.patchColorText('#fff', colorUsage.Background);
-    this._forEachGroup((offset, index, group) => {
-      const paddingHeight = group.style.padding;
-      if (paddingHeight < 5)
-        return;
-      context.fillRect(0, offset - paddingHeight + 2, width, paddingHeight - 4);
-    });
-    if (groups.length && lastGroupOffset < top + height)
-      context.fillRect(0, lastGroupOffset + 2, width, top + height - lastGroupOffset);
-
-    context.strokeStyle = UI.themeSupport.patchColorText('#eee', colorUsage.Background);
-    context.beginPath();
-    this._forEachGroup((offset, index, group, isFirst) => {
-      if (isFirst || group.style.padding < 4)
-        return;
-      hLine(offset - 2.5);
-    });
-    hLine(lastGroupOffset + 1.5);
-    context.stroke();
-
-    this._forEachGroup((offset, index, group) => {
-      if (group.style.useFirstLineForOverview)
-        return;
-      if (!this._isGroupCollapsible(index) || group.expanded) {
-        if (!group.style.shareHeaderLine && index !== this._selectedGroup) {
-          context.fillStyle = group.style.backgroundColor;
-          context.fillRect(0, offset, width, group.style.height);
-        }
-        return;
-      }
-      let nextGroup = index + 1;
-      while (nextGroup < groups.length && groups[nextGroup].style.nestingLevel > group.style.nestingLevel)
-        nextGroup++;
-      const endLevel = nextGroup < groups.length ? groups[nextGroup].startLevel : this._dataProvider.maxStackDepth();
-      this._drawCollapsedOverviewForGroup(group, offset + 1, endLevel);
-    });
-
-    context.save();
-    this._forEachGroup((offset, index, group) => {
-      context.font = group.style.font;
-      if (this._isGroupCollapsible(index) && !group.expanded || group.style.shareHeaderLine) {
-        const width = this._labelWidthForGroup(context, group) + 2;
-        if (index === this._selectedGroup)
-          context.fillStyle = this._selectedGroupBackroundColor;
-        else
-          context.fillStyle = Common.Color.parse(group.style.backgroundColor).setAlpha(0.8).asString(null);
-
-        context.fillRect(
-            this._headerLeftPadding - this._headerLabelXPadding, offset + this._headerLabelYPadding, width,
-            group.style.height - 2 * this._headerLabelYPadding);
-      }
-      context.fillStyle = group.style.color;
-      context.fillText(
-          group.name, Math.floor(this._expansionArrowIndent * (group.style.nestingLevel + 1) + this._arrowSide),
-          offset + group.style.height - this._textBaseline);
-    });
-    context.restore();
-
-    context.fillStyle = UI.themeSupport.patchColorText('#6e6e6e', colorUsage.Foreground);
-    context.beginPath();
-    this._forEachGroup((offset, index, group) => {
-      if (this._isGroupCollapsible(index)) {
-        drawExpansionArrow.call(
-            this, this._expansionArrowIndent * (group.style.nestingLevel + 1),
-            offset + group.style.height - this._textBaseline - this._arrowSide / 2, !!group.expanded);
-      }
-    });
-    context.fill();
-
-    context.strokeStyle = UI.themeSupport.patchColorText('#ddd', colorUsage.Background);
-    context.beginPath();
-    context.stroke();
-
-    this._forEachGroup((offset, index, group, isFirst, groupHeight) => {
-      if (index === this._selectedGroup) {
-        context.fillStyle = this._selectedGroupBorderColor;
-        context.fillRect(0, offset - 2, 2, groupHeight - 1);
-        context.fillRect(0, offset - 2, 10, 2);
-        context.fillRect(0, offset + groupHeight - 5, 10, 2);
-      }
-    });
-
-    context.restore();
-
-    /**
-     * @param {number} y
-     */
-    function hLine(y) {
-      context.moveTo(0, y);
-      context.lineTo(width, y);
-    }
-
-    /**
-     * @param {number} x
-     * @param {number} y
-     * @param {boolean} expanded
-     * @this {PerfUI.FlameChart}
-     */
-    function drawExpansionArrow(x, y, expanded) {
-      const arrowHeight = this._arrowSide * Math.sqrt(3) / 2;
-      const arrowCenterOffset = Math.round(arrowHeight / 2);
-      context.save();
-      context.translate(x, y);
-      context.rotate(expanded ? Math.PI / 2 : 0);
-      context.moveTo(-arrowCenterOffset, -this._arrowSide / 2);
-      context.lineTo(-arrowCenterOffset, this._arrowSide / 2);
-      context.lineTo(arrowHeight - arrowCenterOffset, 0);
-      context.restore();
-    }
-  }
-
-  /**
-   * @param {function(number, number, !PerfUI.FlameChart.Group, boolean, number)} callback
-   */
-  _forEachGroup(callback) {
-    const top = this._chartViewport.scrollOffset();
-    const groups = this._rawTimelineData.groups || [];
-    if (!groups.length)
-      return;
-    const groupOffsets = this._groupOffsets;
-    /** @type !Array<{nestingLevel: number, visible: boolean}> */
-    const groupStack = [{nestingLevel: -1, visible: true}];
-    for (let i = 0; i < groups.length; ++i) {
-      const groupTop = groupOffsets[i];
-      const group = groups[i];
-      if (groupTop - group.style.padding > top + this._offsetHeight)
-        break;
-      let firstGroup = true;
-      while (groupStack.peekLast().nestingLevel >= group.style.nestingLevel) {
-        groupStack.pop();
-        firstGroup = false;
-      }
-      const parentGroupVisible = groupStack.peekLast().visible;
-      const thisGroupVisible = parentGroupVisible && (!this._isGroupCollapsible(i) || group.expanded);
-      groupStack.push({nestingLevel: group.style.nestingLevel, visible: thisGroupVisible});
-      const nextOffset = i === groups.length - 1 ? groupOffsets[i + 1] + group.style.padding - 2 : groupOffsets[i + 1];
-      if (!parentGroupVisible || nextOffset < top)
-        continue;
-      callback(groupTop, i, group, firstGroup, nextOffset - groupTop);
-    }
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {!PerfUI.FlameChart.Group} group
-   * @return {number}
-   */
-  _labelWidthForGroup(context, group) {
-    return UI.measureTextWidth(context, group.name) + this._expansionArrowIndent * (group.style.nestingLevel + 1) +
-        2 * this._headerLabelXPadding;
-  }
-
-  /**
-   * @param {!PerfUI.FlameChart.Group} group
-   * @param {number} y
-   * @param {number} endLevel
-   */
-  _drawCollapsedOverviewForGroup(group, y, endLevel) {
-    const range = new Common.SegmentedRange(mergeCallback);
-    const timeWindowLeft = this._chartViewport.windowLeftTime();
-    const timeWindowRight = this._chartViewport.windowRightTime();
-    const context = /** @type {!CanvasRenderingContext2D} */ (this._canvas.getContext('2d'));
-    const barHeight = group.style.height;
-    const entryStartTimes = this._rawTimelineData.entryStartTimes;
-    const entryTotalTimes = this._rawTimelineData.entryTotalTimes;
-    const timeToPixel = this._chartViewport.timeToPixel();
-
-    for (let level = group.startLevel; level < endLevel; ++level) {
-      const levelIndexes = this._timelineLevels[level];
-      const rightIndexOnLevel =
-          levelIndexes.lowerBound(timeWindowRight, (time, entryIndex) => time - entryStartTimes[entryIndex]) - 1;
-      let lastDrawOffset = Infinity;
-
-      for (let entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) {
-        const entryIndex = levelIndexes[entryIndexOnLevel];
-        const entryStartTime = entryStartTimes[entryIndex];
-        const barX = this._timeToPositionClipped(entryStartTime);
-        const entryEndTime = entryStartTime + entryTotalTimes[entryIndex];
-        if (isNaN(entryEndTime) || barX >= lastDrawOffset)
-          continue;
-        if (entryEndTime <= timeWindowLeft)
-          break;
-        lastDrawOffset = barX;
-        const color = this._dataProvider.entryColor(entryIndex);
-        const endBarX = this._timeToPositionClipped(entryEndTime);
-        if (group.style.useDecoratorsForOverview && this._dataProvider.forceDecoration(entryIndex)) {
-          const unclippedBarX = this._chartViewport.timeToPosition(entryStartTime);
-          const barWidth = endBarX - barX;
-          context.beginPath();
-          context.fillStyle = color;
-          context.fillRect(barX, y, barWidth, barHeight - 1);
-          this._dataProvider.decorateEntry(
-              entryIndex, context, '', barX, y, barWidth, barHeight, unclippedBarX, timeToPixel);
-          continue;
-        }
-        range.append(new Common.Segment(barX, endBarX, color));
-      }
-    }
-
-    const segments = range.segments().slice().sort((a, b) => a.data.localeCompare(b.data));
-    let lastColor;
-    context.beginPath();
-    for (let i = 0; i < segments.length; ++i) {
-      const segment = segments[i];
-      if (lastColor !== segments[i].data) {
-        context.fill();
-        context.beginPath();
-        lastColor = segments[i].data;
-        context.fillStyle = lastColor;
-      }
-      context.rect(segment.begin, y, segment.end - segment.begin, barHeight - 1);
-    }
-    context.fill();
-
-    /**
-     * @param {!Common.Segment} a
-     * @param {!Common.Segment} b
-     * @return {?Common.Segment}
-     */
-    function mergeCallback(a, b) {
-      return a.data === b.data && a.end + 0.4 > b.end ? a : null;
-    }
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {number} height
-   * @param {number} width
-   */
-  _drawFlowEvents(context, width, height) {
-    context.save();
-    const ratio = window.devicePixelRatio;
-    const top = this._chartViewport.scrollOffset();
-    const arrowWidth = 6;
-    context.scale(ratio, ratio);
-    context.translate(0, -top);
-
-    context.fillStyle = '#7f5050';
-    context.strokeStyle = '#7f5050';
-    const td = this._timelineData();
-    const endIndex = td.flowStartTimes.lowerBound(this._chartViewport.windowRightTime());
-
-    context.lineWidth = 0.5;
-    for (let i = 0; i < endIndex; ++i) {
-      if (!td.flowEndTimes[i] || td.flowEndTimes[i] < this._chartViewport.windowLeftTime())
-        continue;
-      const startX = this._chartViewport.timeToPosition(td.flowStartTimes[i]);
-      const endX = this._chartViewport.timeToPosition(td.flowEndTimes[i]);
-      const startLevel = td.flowStartLevels[i];
-      const endLevel = td.flowEndLevels[i];
-      const startY = this._levelToOffset(startLevel) + this._levelHeight(startLevel) / 2;
-      const endY = this._levelToOffset(endLevel) + this._levelHeight(endLevel) / 2;
-
-
-      const segment = Math.min((endX - startX) / 4, 40);
-      const distanceTime = td.flowEndTimes[i] - td.flowStartTimes[i];
-      const distanceY = (endY - startY) / 10;
-      const spread = 30;
-      const lineY = distanceTime < 1 ? startY : spread + Math.max(0, startY + distanceY * (i % spread));
-
-      const p = [];
-      p.push({x: startX, y: startY});
-      p.push({x: startX + arrowWidth, y: startY});
-      p.push({x: startX + segment + 2 * arrowWidth, y: startY});
-      p.push({x: startX + segment, y: lineY});
-      p.push({x: startX + segment * 2, y: lineY});
-      p.push({x: endX - segment * 2, y: lineY});
-      p.push({x: endX - segment, y: lineY});
-      p.push({x: endX - segment - 2 * arrowWidth, y: endY});
-      p.push({x: endX - arrowWidth, y: endY});
-
-      context.beginPath();
-      context.moveTo(p[0].x, p[0].y);
-      context.lineTo(p[1].x, p[1].y);
-      context.bezierCurveTo(p[2].x, p[2].y, p[3].x, p[3].y, p[4].x, p[4].y);
-      context.lineTo(p[5].x, p[5].y);
-      context.bezierCurveTo(p[6].x, p[6].y, p[7].x, p[7].y, p[8].x, p[8].y);
-      context.stroke();
-
-      context.beginPath();
-      context.arc(startX, startY, 2, -Math.PI / 2, Math.PI / 2, false);
-      context.fill();
-
-      context.beginPath();
-      context.moveTo(endX, endY);
-      context.lineTo(endX - arrowWidth, endY - 3);
-      context.lineTo(endX - arrowWidth, endY + 3);
-      context.fill();
-    }
-    context.restore();
-  }
-
-  _drawMarkers() {
-    const markers = this._timelineData().markers;
-    const left = this._markerIndexBeforeTime(this.minimumBoundary());
-    const rightBoundary = this.maximumBoundary();
-    const timeToPixel = this._chartViewport.timeToPixel();
-
-    const context = /** @type {!CanvasRenderingContext2D} */ (this._canvas.getContext('2d'));
-    context.save();
-    const ratio = window.devicePixelRatio;
-    context.scale(ratio, ratio);
-    context.translate(0, 3);
-    const height = PerfUI.FlameChart.HeaderHeight - 1;
-    for (let i = left; i < markers.length; i++) {
-      const timestamp = markers[i].startTime();
-      if (timestamp > rightBoundary)
-        break;
-      markers[i].draw(context, this._chartViewport.timeToPosition(timestamp), height, timeToPixel);
-    }
-    context.restore();
-  }
-
-  _updateMarkerHighlight() {
-    const element = this._markerHighlighElement;
-    if (element.parentElement)
-      element.remove();
-    const markerIndex = this._highlightedMarkerIndex;
-    if (markerIndex === -1)
-      return;
-    const marker = this._timelineData().markers[markerIndex];
-    const barX = this._timeToPositionClipped(marker.startTime());
-    element.title = marker.title();
-    const style = element.style;
-    style.left = barX + 'px';
-    style.backgroundColor = marker.color();
-    this._viewportElement.appendChild(element);
-  }
-
-  /**
-   * @param {?PerfUI.FlameChart.TimelineData} timelineData
-   */
-  _processTimelineData(timelineData) {
-    if (!timelineData) {
-      this._timelineLevels = null;
-      this._visibleLevelOffsets = null;
-      this._visibleLevels = null;
-      this._groupOffsets = null;
-      this._rawTimelineData = null;
-      this._rawTimelineDataLength = 0;
-      this._selectedGroup = -1;
-      this._flameChartDelegate.updateSelectedGroup(this, null);
-      return;
-    }
-
-    this._rawTimelineData = timelineData;
-    this._rawTimelineDataLength = timelineData.entryStartTimes.length;
-
-    const entryCounters = new Uint32Array(this._dataProvider.maxStackDepth() + 1);
-    for (let i = 0; i < timelineData.entryLevels.length; ++i)
-      ++entryCounters[timelineData.entryLevels[i]];
-    const levelIndexes = new Array(entryCounters.length);
-    for (let i = 0; i < levelIndexes.length; ++i) {
-      levelIndexes[i] = new Uint32Array(entryCounters[i]);
-      entryCounters[i] = 0;
-    }
-    for (let i = 0; i < timelineData.entryLevels.length; ++i) {
-      const level = timelineData.entryLevels[i];
-      levelIndexes[level][entryCounters[level]++] = i;
-    }
-    this._timelineLevels = levelIndexes;
-    const groups = this._rawTimelineData.groups || [];
-    for (let i = 0; i < groups.length; ++i) {
-      const expanded = this._groupExpansionState[groups[i].name];
-      if (expanded !== undefined)
-        groups[i].expanded = expanded;
-    }
-    this._updateLevelPositions();
-    this._updateHeight();
-
-    this._selectedGroup = timelineData.selectedGroup ? groups.indexOf(timelineData.selectedGroup) : -1;
-    this._flameChartDelegate.updateSelectedGroup(this, timelineData.selectedGroup);
-  }
-
-  _updateLevelPositions() {
-    const levelCount = this._dataProvider.maxStackDepth();
-    const groups = this._rawTimelineData.groups || [];
-    this._visibleLevelOffsets = new Uint32Array(levelCount + 1);
-    this._visibleLevelHeights = new Uint32Array(levelCount);
-    this._visibleLevels = new Uint16Array(levelCount);
-    this._groupOffsets = new Uint32Array(groups.length + 1);
-
-    let groupIndex = -1;
-    let currentOffset = this._rulerEnabled ? PerfUI.FlameChart.HeaderHeight : 2;
-    let visible = true;
-    /** @type !Array<{nestingLevel: number, visible: boolean}> */
-    const groupStack = [{nestingLevel: -1, visible: true}];
-    const lastGroupLevel = Math.max(levelCount, groups.length ? groups.peekLast().startLevel + 1 : 0);
-    let level;
-    for (level = 0; level < lastGroupLevel; ++level) {
-      let parentGroupIsVisible = true;
-      let style;
-      while (groupIndex < groups.length - 1 && level === groups[groupIndex + 1].startLevel) {
-        ++groupIndex;
-        style = groups[groupIndex].style;
-        let nextLevel = true;
-        while (groupStack.peekLast().nestingLevel >= style.nestingLevel) {
-          groupStack.pop();
-          nextLevel = false;
-        }
-        const thisGroupIsVisible =
-            groupIndex >= 0 && this._isGroupCollapsible(groupIndex) ? groups[groupIndex].expanded : true;
-        parentGroupIsVisible = groupStack.peekLast().visible;
-        visible = thisGroupIsVisible && parentGroupIsVisible;
-        groupStack.push({nestingLevel: style.nestingLevel, visible: visible});
-        if (parentGroupIsVisible)
-          currentOffset += nextLevel ? 0 : style.padding;
-        this._groupOffsets[groupIndex] = currentOffset;
-        if (parentGroupIsVisible && !style.shareHeaderLine)
-          currentOffset += style.height;
-      }
-      const isFirstOnLevel = groupIndex >= 0 && level === groups[groupIndex].startLevel;
-      const thisLevelIsVisible =
-          parentGroupIsVisible && (visible || isFirstOnLevel && groups[groupIndex].style.useFirstLineForOverview);
-      if (level < levelCount) {
-        let height;
-        if (groupIndex >= 0) {
-          const group = groups[groupIndex];
-          const styleB = group.style;
-          height = isFirstOnLevel && !styleB.shareHeaderLine || (styleB.collapsible && !group.expanded) ?
-              styleB.height :
-              (styleB.itemsHeight || this._barHeight);
-        } else {
-          height = this._barHeight;
-        }
-        this._visibleLevels[level] = thisLevelIsVisible;
-        this._visibleLevelOffsets[level] = currentOffset;
-        this._visibleLevelHeights[level] = height;
-      }
-      if (thisLevelIsVisible || (parentGroupIsVisible && style && style.shareHeaderLine && isFirstOnLevel))
-        currentOffset += this._visibleLevelHeights[level];
-    }
-    if (groupIndex >= 0)
-      this._groupOffsets[groupIndex + 1] = currentOffset;
-    this._visibleLevelOffsets[level] = currentOffset;
-  }
-
-  /**
-   * @param {number} index
-   */
-  _isGroupCollapsible(index) {
-    const groups = this._rawTimelineData.groups || [];
-    const style = groups[index].style;
-    if (!style.shareHeaderLine || !style.collapsible)
-      return !!style.collapsible;
-    const isLastGroup = index + 1 >= groups.length;
-    if (!isLastGroup && groups[index + 1].style.nestingLevel > style.nestingLevel)
-      return true;
-    const nextGroupLevel = isLastGroup ? this._dataProvider.maxStackDepth() : groups[index + 1].startLevel;
-    if (nextGroupLevel !== groups[index].startLevel + 1)
-      return true;
-    // For groups that only have one line and share header line, pretend these are not collapsible
-    // unless the itemsHeight does not match the headerHeight
-    return style.height !== style.itemsHeight;
-  }
-
-  /**
-   * @param {number} entryIndex
-   */
-  setSelectedEntry(entryIndex) {
-    if (this._selectedEntryIndex === entryIndex)
-      return;
-    if (entryIndex !== -1)
-      this._chartViewport.hideRangeSelection();
-    this._selectedEntryIndex = entryIndex;
-    this._revealEntry(entryIndex);
-    this._updateElementPosition(this._selectedElement, this._selectedEntryIndex);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {number} entryIndex
-   */
-  _updateElementPosition(element, entryIndex) {
-    const /** @const */ elementMinWidthPx = 2;
-    if (element.parentElement)
-      element.remove();
-    if (entryIndex === -1)
-      return;
-    const timelineData = this._timelineData();
-    const startTime = timelineData.entryStartTimes[entryIndex];
-    const endTime = startTime + (timelineData.entryTotalTimes[entryIndex] || 0);
-    let barX = this._timeToPositionClipped(startTime);
-    const barRight = this._timeToPositionClipped(endTime);
-    if (barRight === 0 || barX === this._offsetWidth)
-      return;
-    let barWidth = barRight - barX;
-    const barCenter = barX + barWidth / 2;
-    barWidth = Math.max(barWidth, elementMinWidthPx);
-    barX = barCenter - barWidth / 2;
-    const entryLevel = timelineData.entryLevels[entryIndex];
-    const barY = this._levelToOffset(entryLevel) - this._chartViewport.scrollOffset();
-    const barHeight = this._levelHeight(entryLevel);
-    const style = element.style;
-    style.left = barX + 'px';
-    style.top = barY + 'px';
-    style.width = barWidth + 'px';
-    style.height = barHeight - 1 + 'px';
-    this._viewportElement.appendChild(element);
-  }
-
-  /**
-   * @param {number} time
-   * @return {number}
-   */
-  _timeToPositionClipped(time) {
-    return Number.constrain(this._chartViewport.timeToPosition(time), 0, this._offsetWidth);
-  }
-
-  /**
-   * @param {number} level
-   * @return {number}
-   */
-  _levelToOffset(level) {
-    return this._visibleLevelOffsets[level];
-  }
-
-  /**
-   * @param {number} level
-   * @return {number}
-   */
-  _levelHeight(level) {
-    return this._visibleLevelHeights[level];
-  }
-
-  _updateBoundaries() {
-    this._totalTime = this._dataProvider.totalTime();
-    this._minimumBoundary = this._dataProvider.minimumBoundary();
-    this._chartViewport.setBoundaries(this._minimumBoundary, this._totalTime);
-  }
-
-  _updateHeight() {
-    const height = this._levelToOffset(this._dataProvider.maxStackDepth());
-    this._chartViewport.setContentHeight(height);
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    if (!this._timelineData())
-      return;
-    this._resetCanvas();
-    this._updateHeight();
-    this._updateBoundaries();
-    this._draw();
-    if (!this._chartViewport.isDragging())
-      this._updateHighlight();
-  }
-
-  reset() {
-    this._chartViewport.reset();
-    this._rawTimelineData = null;
-    this._rawTimelineDataLength = 0;
-    this._highlightedMarkerIndex = -1;
-    this._highlightedEntryIndex = -1;
-    this._selectedEntryIndex = -1;
-    /** @type {!Map<string,!Map<string,number>>} */
-    this._textWidth = new Map();
-    this._chartViewport.scheduleUpdate();
-  }
-
-  scheduleUpdate() {
-    this._chartViewport.scheduleUpdate();
-  }
-
-  _enabled() {
-    return this._rawTimelineDataLength !== 0;
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {
-    return this._chartViewport.timeToPosition(time);
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return this._dataProvider.formatValue(value - this.zeroTime(), precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maximumBoundary() {
-    return this._chartViewport.windowRightTime();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._chartViewport.windowLeftTime();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zeroTime() {
-    return this._dataProvider.minimumBoundary();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  boundarySpan() {
-    return this._dataProvider.totalTime();
-  }
-};
-
-PerfUI.FlameChart.HeaderHeight = 15;
-
-PerfUI.FlameChart.MinimalTimeWindowMs = 0.5;
-
-/**
- * @interface
- */
-PerfUI.FlameChartDataProvider = function() {};
-
-/**
- * @typedef {!{
- *     name: string,
- *     startLevel: number,
- *     expanded: (boolean|undefined),
- *     selectable: (boolean|undefined),
- *     style: !PerfUI.FlameChart.GroupStyle
- * }}
- */
-PerfUI.FlameChart.Group;
-
-/**
- * @typedef {!{
- *     height: number,
- *     padding: number,
- *     collapsible: boolean,
- *     font: string,
- *     color: string,
- *     backgroundColor: string,
- *     nestingLevel: number,
- *     itemsHeight: (number|undefined),
- *     shareHeaderLine: (boolean|undefined),
- *     useFirstLineForOverview: (boolean|undefined),
- *     useDecoratorsForOverview: (boolean|undefined)
- * }}
- */
-PerfUI.FlameChart.GroupStyle;
-
-/**
- * @unrestricted
- */
-PerfUI.FlameChart.TimelineData = class {
-  /**
-   * @param {!Array<number>|!Uint16Array} entryLevels
-   * @param {!Array<number>|!Float32Array} entryTotalTimes
-   * @param {!Array<number>|!Float64Array} entryStartTimes
-   * @param {?Array<!PerfUI.FlameChart.Group>} groups
-   */
-  constructor(entryLevels, entryTotalTimes, entryStartTimes, groups) {
-    this.entryLevels = entryLevels;
-    this.entryTotalTimes = entryTotalTimes;
-    this.entryStartTimes = entryStartTimes;
-    this.groups = groups;
-    /** @type {!Array.<!PerfUI.FlameChartMarker>} */
-    this.markers = [];
-    this.flowStartTimes = [];
-    this.flowStartLevels = [];
-    this.flowEndTimes = [];
-    this.flowEndLevels = [];
-    /** @type {?PerfUI.FlameChart.Group} */
-    this.selectedGroup = null;
-  }
-};
-
-PerfUI.FlameChartDataProvider.prototype = {
-  /**
-   * @return {number}
-   */
-  minimumBoundary() {},
-
-  /**
-   * @return {number}
-   */
-  totalTime() {},
-
-  /**
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {},
-
-  /**
-   * @return {number}
-   */
-  maxStackDepth() {},
-
-  /**
-   * @return {?PerfUI.FlameChart.TimelineData}
-   */
-  timelineData() {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {?Element}
-   */
-  prepareHighlightedEntryInfo(entryIndex) {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  canJumpToEntry(entryIndex) {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {?string}
-   */
-  entryTitle(entryIndex) {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {?string}
-   */
-  entryFont(entryIndex) {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {string}
-   */
-  entryColor(entryIndex) {},
-
-  /**
-   * @param {number} entryIndex
-   * @param {!CanvasRenderingContext2D} context
-   * @param {?string} text
-   * @param {number} barX
-   * @param {number} barY
-   * @param {number} barWidth
-   * @param {number} barHeight
-   * @param {number} unclippedBarX
-   * @param {number} timeToPixelRatio
-   * @return {boolean}
-   */
-  decorateEntry(entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixelRatio) {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  forceDecoration(entryIndex) {},
-
-  /**
-   * @param {number} entryIndex
-   * @return {string}
-   */
-  textColor(entryIndex) {},
-};
-
-/**
- * @interface
- */
-PerfUI.FlameChartMarker = function() {};
-
-PerfUI.FlameChartMarker.prototype = {
-  /**
-   * @return {number}
-   */
-  startTime() {},
-
-  /**
-   * @return {string}
-   */
-  color() {},
-
-  /**
-   * @return {string}
-   */
-  title() {},
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {number} x
-   * @param {number} height
-   * @param {number} pixelsPerMillisecond
-   */
-  draw(context, x, height, pixelsPerMillisecond) {},
-};
-
-/** @enum {symbol} */
-PerfUI.FlameChart.Events = {
-  EntrySelected: Symbol('EntrySelected'),
-  EntryHighlighted: Symbol('EntryHighlighted')
-};
-
-PerfUI.FlameChart.Colors = {
-  SelectedGroupBackground: 'hsl(215, 85%, 98%)',
-  SelectedGroupBorder: 'hsl(216, 68%, 54%)',
-};
diff --git a/front_end/perf_ui/GCActionDelegate.js b/front_end/perf_ui/GCActionDelegate.js
deleted file mode 100644
index a443d0c..0000000
--- a/front_end/perf_ui/GCActionDelegate.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {UI.ActionDelegate}
- */
-PerfUI.GCActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    for (const heapProfilerModel of SDK.targetManager.models(SDK.HeapProfilerModel))
-      heapProfilerModel.collectGarbage();
-    return true;
-  }
-};
diff --git a/front_end/perf_ui/LineLevelProfile.js b/front_end/perf_ui/LineLevelProfile.js
deleted file mode 100644
index fa4d83c..0000000
--- a/front_end/perf_ui/LineLevelProfile.js
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-PerfUI.LineLevelProfile = class {
-  constructor() {
-    this._locationPool = new Bindings.LiveLocationPool();
-    this.reset();
-  }
-
-  /**
-   * @return {!PerfUI.LineLevelProfile}
-   */
-  static instance() {
-    if (!PerfUI.LineLevelProfile._instance)
-      PerfUI.LineLevelProfile._instance = new PerfUI.LineLevelProfile();
-    return PerfUI.LineLevelProfile._instance;
-  }
-
-  /**
-   * @param {!SDK.CPUProfileDataModel} profile
-   */
-  appendCPUProfile(profile) {
-    const nodesToGo = [profile.profileHead];
-    const sampleDuration = (profile.profileEndTime - profile.profileStartTime) / profile.totalHitCount;
-    while (nodesToGo.length) {
-      const nodes = nodesToGo.pop().children;
-      for (let i = 0; i < nodes.length; ++i) {
-        const node = nodes[i];
-        nodesToGo.push(node);
-        if (!node.url || !node.positionTicks)
-          continue;
-        let fileInfo = this._files.get(node.url);
-        if (!fileInfo) {
-          fileInfo = new Map();
-          this._files.set(node.url, fileInfo);
-        }
-        for (let j = 0; j < node.positionTicks.length; ++j) {
-          const lineInfo = node.positionTicks[j];
-          const line = lineInfo.line;
-          const time = lineInfo.ticks * sampleDuration;
-          fileInfo.set(line, (fileInfo.get(line) || 0) + time);
-        }
-      }
-    }
-    this._scheduleUpdate();
-  }
-
-  reset() {
-    /** @type {!Map<string, !Map<number, number>>} */
-    this._files = new Map();
-    this._scheduleUpdate();
-  }
-
-  _scheduleUpdate() {
-    if (this._updateTimer)
-      return;
-    this._updateTimer = setTimeout(() => {
-      this._updateTimer = null;
-      this._doUpdate();
-    }, 0);
-  }
-
-  _doUpdate() {
-    // TODO(alph): use scriptId instead of urls for the target.
-    this._locationPool.disposeAll();
-    Workspace.workspace.uiSourceCodes().forEach(
-        uiSourceCode => uiSourceCode.removeDecorationsForType(PerfUI.LineLevelProfile.LineDecorator.type));
-    for (const fileInfo of this._files) {
-      const url = /** @type {string} */ (fileInfo[0]);
-      const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
-      if (!uiSourceCode)
-        continue;
-      const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode) || SDK.targetManager.mainTarget();
-      const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
-      if (!debuggerModel)
-        continue;
-      for (const lineInfo of fileInfo[1]) {
-        const line = lineInfo[0] - 1;
-        const time = lineInfo[1];
-        const rawLocation = debuggerModel.createRawLocationByURL(url, line, 0);
-        if (rawLocation)
-          new PerfUI.LineLevelProfile.Presentation(rawLocation, time, this._locationPool);
-        else if (uiSourceCode)
-          uiSourceCode.addLineDecoration(line, PerfUI.LineLevelProfile.LineDecorator.type, time);
-      }
-    }
-  }
-};
-
-
-/**
- * @unrestricted
- */
-PerfUI.LineLevelProfile.Presentation = class {
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @param {number} time
-   * @param {!Bindings.LiveLocationPool} locationPool
-   */
-  constructor(rawLocation, time, locationPool) {
-    this._time = time;
-    Bindings.debuggerWorkspaceBinding.createLiveLocation(rawLocation, this.updateLocation.bind(this), locationPool);
-  }
-
-  /**
-   * @param {!Bindings.LiveLocation} liveLocation
-   */
-  updateLocation(liveLocation) {
-    if (this._uiLocation)
-      this._uiLocation.uiSourceCode.removeDecorationsForType(PerfUI.LineLevelProfile.LineDecorator.type);
-    this._uiLocation = liveLocation.uiLocation();
-    if (this._uiLocation) {
-      this._uiLocation.uiSourceCode.addLineDecoration(
-          this._uiLocation.lineNumber, PerfUI.LineLevelProfile.LineDecorator.type, this._time);
-    }
-  }
-};
-
-/**
- * @implements {SourceFrame.LineDecorator}
- * @unrestricted
- */
-PerfUI.LineLevelProfile.LineDecorator = class {
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   */
-  decorate(uiSourceCode, textEditor) {
-    const gutterType = 'CodeMirror-gutter-performance';
-    const decorations = uiSourceCode.decorationsForType(PerfUI.LineLevelProfile.LineDecorator.type);
-    textEditor.uninstallGutter(gutterType);
-    if (!decorations || !decorations.size)
-      return;
-    textEditor.installGutter(gutterType, false);
-    for (const decoration of decorations) {
-      const time = /** @type {number} */ (decoration.data());
-      const text = Common.UIString('%.1f\xa0ms', time);
-      const intensity = Number.constrain(Math.log10(1 + 2 * time) / 5, 0.02, 1);
-      const element = createElementWithClass('div', 'text-editor-line-marker-performance');
-      element.textContent = text;
-      element.style.backgroundColor = `hsla(44, 100%, 50%, ${intensity.toFixed(3)})`;
-      textEditor.setGutterDecoration(decoration.range().startLine, gutterType, element);
-    }
-  }
-};
-
-PerfUI.LineLevelProfile.LineDecorator.type = 'performance';
diff --git a/front_end/perf_ui/NetworkPriorities.js b/front_end/perf_ui/NetworkPriorities.js
deleted file mode 100644
index 16b3862..0000000
--- a/front_end/perf_ui/NetworkPriorities.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @param {!Protocol.Network.ResourcePriority} priority
- * @return {string}
- */
-PerfUI.uiLabelForNetworkPriority = function(priority) {
-  return PerfUI._priorityUILabelMap().get(priority) || '';
-};
-
-/**
- * @param {string} priorityLabel
- * @return {string}
- */
-PerfUI.uiLabelToNetworkPriority = function(priorityLabel) {
-  if (!PerfUI._uiLabelToPriorityMapInstance) {
-    /** @type {!Map<string, !Protocol.Network.ResourcePriority>} */
-    PerfUI._uiLabelToPriorityMapInstance = new Map();
-    PerfUI._priorityUILabelMap().forEach((value, key) => PerfUI._uiLabelToPriorityMapInstance.set(value, key));
-  }
-  return PerfUI._uiLabelToPriorityMapInstance.get(priorityLabel) || '';
-};
-
-/**
- * @return {!Map<!Protocol.Network.ResourcePriority, string>}
- */
-PerfUI._priorityUILabelMap = function() {
-  if (PerfUI._priorityUILabelMapInstance)
-    return PerfUI._priorityUILabelMapInstance;
-
-  /** @type {!Map<!Protocol.Network.ResourcePriority, string>} */
-  const map = new Map();
-  map.set(Protocol.Network.ResourcePriority.VeryLow, Common.UIString('Lowest'));
-  map.set(Protocol.Network.ResourcePriority.Low, Common.UIString('Low'));
-  map.set(Protocol.Network.ResourcePriority.Medium, Common.UIString('Medium'));
-  map.set(Protocol.Network.ResourcePriority.High, Common.UIString('High'));
-  map.set(Protocol.Network.ResourcePriority.VeryHigh, Common.UIString('Highest'));
-  PerfUI._priorityUILabelMapInstance = map;
-  return map;
-};
-
-/**
- * @param {!Protocol.Network.ResourcePriority} priority
- * @return {number}
- */
-PerfUI.networkPriorityWeight = function(priority) {
-  if (!PerfUI._networkPriorityWeights) {
-    /** @type {!Map<!Protocol.Network.ResourcePriority, number>} */
-    const priorityMap = new Map();
-    priorityMap.set(Protocol.Network.ResourcePriority.VeryLow, 1);
-    priorityMap.set(Protocol.Network.ResourcePriority.Low, 2);
-    priorityMap.set(Protocol.Network.ResourcePriority.Medium, 3);
-    priorityMap.set(Protocol.Network.ResourcePriority.High, 4);
-    priorityMap.set(Protocol.Network.ResourcePriority.VeryHigh, 5);
-    PerfUI._networkPriorityWeights = priorityMap;
-  }
-  return PerfUI._networkPriorityWeights.get(priority) || 0;
-};
diff --git a/front_end/perf_ui/OverviewGrid.js b/front_end/perf_ui/OverviewGrid.js
deleted file mode 100644
index ca98103..0000000
--- a/front_end/perf_ui/OverviewGrid.js
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-PerfUI.OverviewGrid = class {
-  /**
-   * @param {string} prefix
-   */
-  constructor(prefix) {
-    this.element = createElement('div');
-    this.element.id = prefix + '-overview-container';
-
-    this._grid = new PerfUI.TimelineGrid();
-    this._grid.element.id = prefix + '-overview-grid';
-    this._grid.setScrollTop(0);
-
-    this.element.appendChild(this._grid.element);
-
-    this._window = new PerfUI.OverviewGrid.Window(this.element, this._grid.dividersLabelBarElement);
-  }
-
-  /**
-   * @return {number}
-   */
-  clientWidth() {
-    return this.element.clientWidth;
-  }
-
-  /**
-   * @param {!PerfUI.TimelineGrid.Calculator} calculator
-   */
-  updateDividers(calculator) {
-    this._grid.updateDividers(calculator);
-  }
-
-  /**
-   * @param {!Array.<!Element>} dividers
-   */
-  addEventDividers(dividers) {
-    this._grid.addEventDividers(dividers);
-  }
-
-  removeEventDividers() {
-    this._grid.removeEventDividers();
-  }
-
-  reset() {
-    this._window.reset();
-  }
-
-  /**
-   * @return {number}
-   */
-  windowLeft() {
-    return this._window.windowLeft;
-  }
-
-  /**
-   * @return {number}
-   */
-  windowRight() {
-    return this._window.windowRight;
-  }
-
-  /**
-   * @param {number} left
-   * @param {number} right
-   */
-  setWindow(left, right) {
-    this._window._setWindow(left, right);
-  }
-
-  /**
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   * @return {!Common.EventTarget.EventDescriptor}
-   */
-  addEventListener(eventType, listener, thisObject) {
-    return this._window.addEventListener(eventType, listener, thisObject);
-  }
-
-  /**
-   * @param {?function(!Event):boolean} clickHandler
-   */
-  setClickHandler(clickHandler) {
-    this._window.setClickHandler(clickHandler);
-  }
-
-  /**
-   * @param {number} zoomFactor
-   * @param {number} referencePoint
-   */
-  zoom(zoomFactor, referencePoint) {
-    this._window._zoom(zoomFactor, referencePoint);
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setResizeEnabled(enabled) {
-    this._window.setEnabled(enabled);
-  }
-};
-
-PerfUI.OverviewGrid.MinSelectableSize = 14;
-
-PerfUI.OverviewGrid.WindowScrollSpeedFactor = .3;
-
-PerfUI.OverviewGrid.ResizerOffset = 3.5;  // half pixel because offset values are not rounded but ceiled
-
-/**
- * @unrestricted
- */
-PerfUI.OverviewGrid.Window = class extends Common.Object {
-  /**
-   * @param {!Element} parentElement
-   * @param {!Element=} dividersLabelBarElement
-   */
-  constructor(parentElement, dividersLabelBarElement) {
-    super();
-    this._parentElement = parentElement;
-
-    UI.installDragHandle(
-        this._parentElement, this._startWindowSelectorDragging.bind(this), this._windowSelectorDragging.bind(this),
-        this._endWindowSelectorDragging.bind(this), 'text', null);
-    if (dividersLabelBarElement) {
-      UI.installDragHandle(
-          dividersLabelBarElement, this._startWindowDragging.bind(this), this._windowDragging.bind(this), null,
-          '-webkit-grabbing', '-webkit-grab');
-    }
-
-    this._parentElement.addEventListener('mousewheel', this._onMouseWheel.bind(this), true);
-    this._parentElement.addEventListener('dblclick', this._resizeWindowMaximum.bind(this), true);
-    UI.appendStyle(this._parentElement, 'perf_ui/overviewGrid.css');
-
-    this._leftResizeElement = parentElement.createChild('div', 'overview-grid-window-resizer');
-    UI.installDragHandle(
-        this._leftResizeElement, this._resizerElementStartDragging.bind(this),
-        this._leftResizeElementDragging.bind(this), null, 'ew-resize');
-    this._rightResizeElement = parentElement.createChild('div', 'overview-grid-window-resizer');
-    UI.installDragHandle(
-        this._rightResizeElement, this._resizerElementStartDragging.bind(this),
-        this._rightResizeElementDragging.bind(this), null, 'ew-resize');
-
-    this._leftCurtainElement = parentElement.createChild('div', 'window-curtain-left');
-    this._rightCurtainElement = parentElement.createChild('div', 'window-curtain-right');
-    this.reset();
-  }
-
-  reset() {
-    this.windowLeft = 0.0;
-    this.windowRight = 1.0;
-    this.setEnabled(true);
-    this._updateCurtains();
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._enabled = enabled;
-  }
-
-  /**
-   * @param {?function(!Event):boolean} clickHandler
-   */
-  setClickHandler(clickHandler) {
-    this._clickHandler = clickHandler;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _resizerElementStartDragging(event) {
-    if (!this._enabled)
-      return false;
-    this._resizerParentOffsetLeft = event.pageX - event.offsetX - event.target.offsetLeft;
-    event.stopPropagation();
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _leftResizeElementDragging(event) {
-    this._resizeWindowLeft(event.pageX - this._resizerParentOffsetLeft);
-    event.preventDefault();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _rightResizeElementDragging(event) {
-    this._resizeWindowRight(event.pageX - this._resizerParentOffsetLeft);
-    event.preventDefault();
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _startWindowSelectorDragging(event) {
-    if (!this._enabled)
-      return false;
-    this._offsetLeft = this._parentElement.totalOffsetLeft();
-    const position = event.x - this._offsetLeft;
-    this._overviewWindowSelector = new PerfUI.OverviewGrid.WindowSelector(this._parentElement, position);
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _windowSelectorDragging(event) {
-    this._overviewWindowSelector._updatePosition(event.x - this._offsetLeft);
-    event.preventDefault();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _endWindowSelectorDragging(event) {
-    const window = this._overviewWindowSelector._close(event.x - this._offsetLeft);
-    delete this._overviewWindowSelector;
-    const clickThreshold = 3;
-    if (window.end - window.start < clickThreshold) {
-      if (this._clickHandler && this._clickHandler.call(null, event))
-        return;
-      const middle = window.end;
-      window.start = Math.max(0, middle - PerfUI.OverviewGrid.MinSelectableSize / 2);
-      window.end = Math.min(this._parentElement.clientWidth, middle + PerfUI.OverviewGrid.MinSelectableSize / 2);
-    } else if (window.end - window.start < PerfUI.OverviewGrid.MinSelectableSize) {
-      if (this._parentElement.clientWidth - window.end > PerfUI.OverviewGrid.MinSelectableSize)
-        window.end = window.start + PerfUI.OverviewGrid.MinSelectableSize;
-      else
-        window.start = window.end - PerfUI.OverviewGrid.MinSelectableSize;
-    }
-    this._setWindowPosition(window.start, window.end);
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _startWindowDragging(event) {
-    this._dragStartPoint = event.pageX;
-    this._dragStartLeft = this.windowLeft;
-    this._dragStartRight = this.windowRight;
-    event.stopPropagation();
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _windowDragging(event) {
-    event.preventDefault();
-    let delta = (event.pageX - this._dragStartPoint) / this._parentElement.clientWidth;
-    if (this._dragStartLeft + delta < 0)
-      delta = -this._dragStartLeft;
-
-    if (this._dragStartRight + delta > 1)
-      delta = 1 - this._dragStartRight;
-
-    this._setWindow(this._dragStartLeft + delta, this._dragStartRight + delta);
-  }
-
-  /**
-   * @param {number} start
-   */
-  _resizeWindowLeft(start) {
-    // Glue to edge.
-    if (start < 10)
-      start = 0;
-    else if (start > this._rightResizeElement.offsetLeft - 4)
-      start = this._rightResizeElement.offsetLeft - 4;
-    this._setWindowPosition(start, null);
-  }
-
-  /**
-   * @param {number} end
-   */
-  _resizeWindowRight(end) {
-    // Glue to edge.
-    if (end > this._parentElement.clientWidth - 10)
-      end = this._parentElement.clientWidth;
-    else if (end < this._leftResizeElement.offsetLeft + PerfUI.OverviewGrid.MinSelectableSize)
-      end = this._leftResizeElement.offsetLeft + PerfUI.OverviewGrid.MinSelectableSize;
-    this._setWindowPosition(null, end);
-  }
-
-  _resizeWindowMaximum() {
-    this._setWindowPosition(0, this._parentElement.clientWidth);
-  }
-
-  /**
-   * @param {number} windowLeft
-   * @param {number} windowRight
-   */
-  _setWindow(windowLeft, windowRight) {
-    this.windowLeft = windowLeft;
-    this.windowRight = windowRight;
-    this._updateCurtains();
-    this.dispatchEventToListeners(PerfUI.OverviewGrid.Events.WindowChanged);
-  }
-
-  _updateCurtains() {
-    let left = this.windowLeft;
-    let right = this.windowRight;
-    const width = right - left;
-
-    // We allow actual time window to be arbitrarily small but don't want the UI window to be too small.
-    const widthInPixels = width * this._parentElement.clientWidth;
-    const minWidthInPixels = PerfUI.OverviewGrid.MinSelectableSize / 2;
-    if (widthInPixels < minWidthInPixels) {
-      const factor = minWidthInPixels / widthInPixels;
-      left = ((this.windowRight + this.windowLeft) - width * factor) / 2;
-      right = ((this.windowRight + this.windowLeft) + width * factor) / 2;
-    }
-    this._leftResizeElement.style.left = (100 * left).toFixed(2) + '%';
-    this._rightResizeElement.style.left = (100 * right).toFixed(2) + '%';
-
-    this._leftCurtainElement.style.width = (100 * left).toFixed(2) + '%';
-    this._rightCurtainElement.style.width = (100 * (1 - right)).toFixed(2) + '%';
-  }
-
-  /**
-   * @param {?number} start
-   * @param {?number} end
-   */
-  _setWindowPosition(start, end) {
-    const clientWidth = this._parentElement.clientWidth;
-    const windowLeft = typeof start === 'number' ? start / clientWidth : this.windowLeft;
-    const windowRight = typeof end === 'number' ? end / clientWidth : this.windowRight;
-    this._setWindow(windowLeft, windowRight);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseWheel(event) {
-    if (!this._enabled)
-      return;
-    if (typeof event.wheelDeltaY === 'number' && event.wheelDeltaY) {
-      const zoomFactor = 1.1;
-      const mouseWheelZoomSpeed = 1 / 120;
-
-      const reference = event.offsetX / event.target.clientWidth;
-      this._zoom(Math.pow(zoomFactor, -event.wheelDeltaY * mouseWheelZoomSpeed), reference);
-    }
-    if (typeof event.wheelDeltaX === 'number' && event.wheelDeltaX) {
-      let offset = Math.round(event.wheelDeltaX * PerfUI.OverviewGrid.WindowScrollSpeedFactor);
-      const windowLeft = this._leftResizeElement.offsetLeft + PerfUI.OverviewGrid.ResizerOffset;
-      const windowRight = this._rightResizeElement.offsetLeft + PerfUI.OverviewGrid.ResizerOffset;
-
-      if (windowLeft - offset < 0)
-        offset = windowLeft;
-
-      if (windowRight - offset > this._parentElement.clientWidth)
-        offset = windowRight - this._parentElement.clientWidth;
-
-      this._setWindowPosition(windowLeft - offset, windowRight - offset);
-
-      event.preventDefault();
-    }
-  }
-
-  /**
-   * @param {number} factor
-   * @param {number} reference
-   */
-  _zoom(factor, reference) {
-    let left = this.windowLeft;
-    let right = this.windowRight;
-    const windowSize = right - left;
-    let newWindowSize = factor * windowSize;
-    if (newWindowSize > 1) {
-      newWindowSize = 1;
-      factor = newWindowSize / windowSize;
-    }
-    left = reference + (left - reference) * factor;
-    left = Number.constrain(left, 0, 1 - newWindowSize);
-
-    right = reference + (right - reference) * factor;
-    right = Number.constrain(right, newWindowSize, 1);
-    this._setWindow(left, right);
-  }
-};
-
-/** @enum {symbol} */
-PerfUI.OverviewGrid.Events = {
-  WindowChanged: Symbol('WindowChanged')
-};
-
-/**
- * @unrestricted
- */
-PerfUI.OverviewGrid.WindowSelector = class {
-  constructor(parent, position) {
-    this._startPosition = position;
-    this._width = parent.offsetWidth;
-    this._windowSelector = createElement('div');
-    this._windowSelector.className = 'overview-grid-window-selector';
-    this._windowSelector.style.left = this._startPosition + 'px';
-    this._windowSelector.style.right = this._width - this._startPosition + 'px';
-    parent.appendChild(this._windowSelector);
-  }
-
-  _close(position) {
-    position = Math.max(0, Math.min(position, this._width));
-    this._windowSelector.remove();
-    return this._startPosition < position ? {start: this._startPosition, end: position} :
-                                            {start: position, end: this._startPosition};
-  }
-
-  _updatePosition(position) {
-    position = Math.max(0, Math.min(position, this._width));
-    if (position < this._startPosition) {
-      this._windowSelector.style.left = position + 'px';
-      this._windowSelector.style.right = this._width - this._startPosition + 'px';
-    } else {
-      this._windowSelector.style.left = this._startPosition + 'px';
-      this._windowSelector.style.right = this._width - position + 'px';
-    }
-  }
-};
diff --git a/front_end/perf_ui/PieChart.js b/front_end/perf_ui/PieChart.js
deleted file mode 100644
index 773c9ed..0000000
--- a/front_end/perf_ui/PieChart.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-PerfUI.PieChart = class {
-  /**
-   * @param {number} size
-   * @param {function(number):string=} formatter
-   * @param {boolean=} showTotal
-   */
-  constructor(size, formatter, showTotal) {
-    this.element = createElement('div');
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'perf_ui/pieChart.css');
-    const root = this._shadowRoot.createChild('div', 'root');
-    const svg = this._createSVGChild(root, 'svg');
-    this._group = this._createSVGChild(svg, 'g');
-    this._innerR = 0.618;
-    const strokeWidth = 1 / size;
-    let circle = this._createSVGChild(this._group, 'circle');
-    circle.setAttribute('r', 1);
-    circle.setAttribute('stroke', 'hsl(0, 0%, 80%)');
-    circle.setAttribute('fill', 'transparent');
-    circle.setAttribute('stroke-width', strokeWidth);
-    circle = this._createSVGChild(this._group, 'circle');
-    circle.setAttribute('r', this._innerR);
-    circle.setAttribute('stroke', 'hsl(0, 0%, 80%)');
-    circle.setAttribute('fill', 'transparent');
-    circle.setAttribute('stroke-width', strokeWidth);
-    this._foregroundElement = root.createChild('div', 'pie-chart-foreground');
-    if (showTotal)
-      this._totalElement = this._foregroundElement.createChild('div', 'pie-chart-total');
-    this._formatter = formatter;
-    this._slices = [];
-    this._lastAngle = -Math.PI / 2;
-    this._setSize(size);
-  }
-
-  /**
-   * @param {number} totalValue
-   */
-  setTotal(totalValue) {
-    for (let i = 0; i < this._slices.length; ++i)
-      this._slices[i].remove();
-    this._slices = [];
-    this._totalValue = totalValue;
-    this._lastAngle = -Math.PI / 2;
-    let totalString;
-    if (totalValue)
-      totalString = this._formatter ? this._formatter(totalValue) : totalValue;
-    else
-      totalString = '';
-    if (this._totalElement)
-      this._totalElement.textContent = totalString;
-  }
-
-  /**
-   * @param {number} value
-   */
-  _setSize(value) {
-    this._group.setAttribute('transform', 'scale(' + (value / 2) + ') translate(1, 1) scale(0.99, 0.99)');
-    const size = value + 'px';
-    this.element.style.width = size;
-    this.element.style.height = size;
-  }
-
-  /**
-   * @param {number} value
-   * @param {string} color
-   */
-  addSlice(value, color) {
-    let sliceAngle = value / this._totalValue * 2 * Math.PI;
-    if (!isFinite(sliceAngle))
-      return;
-    sliceAngle = Math.min(sliceAngle, 2 * Math.PI * 0.9999);
-    const path = this._createSVGChild(this._group, 'path');
-    const x1 = Math.cos(this._lastAngle);
-    const y1 = Math.sin(this._lastAngle);
-    this._lastAngle += sliceAngle;
-    const x2 = Math.cos(this._lastAngle);
-    const y2 = Math.sin(this._lastAngle);
-    const r2 = this._innerR;
-    const x3 = x2 * r2;
-    const y3 = y2 * r2;
-    const x4 = x1 * r2;
-    const y4 = y1 * r2;
-    const largeArc = sliceAngle > Math.PI ? 1 : 0;
-    path.setAttribute('d',
-        `M${x1},${y1} A1,1,0,${largeArc},1,${x2},${y2} L${x3},${y3} A${r2},${r2},0,${largeArc},0,${x4},${y4} Z`);
-    path.setAttribute('fill', color);
-    this._slices.push(path);
-  }
-
-  /**
-   * @param {!Element} parent
-   * @param {string} childType
-   * @return {!Element}
-   */
-  _createSVGChild(parent, childType) {
-    const child = parent.ownerDocument.createElementNS('http://www.w3.org/2000/svg', childType);
-    parent.appendChild(child);
-    return child;
-  }
-};
diff --git a/front_end/perf_ui/TimelineGrid.js b/front_end/perf_ui/TimelineGrid.js
deleted file mode 100644
index af644ce..0000000
--- a/front_end/perf_ui/TimelineGrid.js
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-PerfUI.TimelineGrid = class {
-  constructor() {
-    this.element = createElement('div');
-    UI.appendStyle(this.element, 'perf_ui/timelineGrid.css');
-
-    this._dividersElement = this.element.createChild('div', 'resources-dividers');
-
-    this._gridHeaderElement = createElement('div');
-    this._gridHeaderElement.classList.add('timeline-grid-header');
-    this._eventDividersElement = this._gridHeaderElement.createChild('div', 'resources-event-dividers');
-    this._dividersLabelBarElement = this._gridHeaderElement.createChild('div', 'resources-dividers-label-bar');
-    this.element.appendChild(this._gridHeaderElement);
-  }
-
-  /**
-   * @param {!PerfUI.TimelineGrid.Calculator} calculator
-   * @param {number=} freeZoneAtLeft
-   * @return {!PerfUI.TimelineGrid.DividersData}
-   */
-  static calculateGridOffsets(calculator, freeZoneAtLeft) {
-    /** @const */ const minGridSlicePx = 64;  // minimal distance between grid lines.
-
-    const clientWidth = calculator.computePosition(calculator.maximumBoundary());
-    let dividersCount = clientWidth / minGridSlicePx;
-    let gridSliceTime = calculator.boundarySpan() / dividersCount;
-    const pixelsPerTime = clientWidth / calculator.boundarySpan();
-
-    // Align gridSliceTime to a nearest round value.
-    // We allow spans that fit into the formula: span = (1|2|5)x10^n,
-    // e.g.: ...  .1  .2  .5  1  2  5  10  20  50  ...
-    // After a span has been chosen make grid lines at multiples of the span.
-
-    const logGridSliceTime = Math.ceil(Math.log(gridSliceTime) / Math.LN10);
-    gridSliceTime = Math.pow(10, logGridSliceTime);
-    if (gridSliceTime * pixelsPerTime >= 5 * minGridSlicePx)
-      gridSliceTime = gridSliceTime / 5;
-    if (gridSliceTime * pixelsPerTime >= 2 * minGridSlicePx)
-      gridSliceTime = gridSliceTime / 2;
-
-    const firstDividerTime =
-        Math.ceil((calculator.minimumBoundary() - calculator.zeroTime()) / gridSliceTime) * gridSliceTime +
-        calculator.zeroTime();
-    let lastDividerTime = calculator.maximumBoundary();
-    // Add some extra space past the right boundary as the rightmost divider label text
-    // may be partially shown rather than just pop up when a new rightmost divider gets into the view.
-    lastDividerTime += minGridSlicePx / pixelsPerTime;
-    dividersCount = Math.ceil((lastDividerTime - firstDividerTime) / gridSliceTime);
-
-    if (!gridSliceTime)
-      dividersCount = 0;
-
-    const offsets = [];
-    for (let i = 0; i < dividersCount; ++i) {
-      const time = firstDividerTime + gridSliceTime * i;
-      if (calculator.computePosition(time) < freeZoneAtLeft)
-        continue;
-      offsets.push({position: Math.floor(calculator.computePosition(time)), time: time});
-    }
-
-    return {offsets: offsets, precision: Math.max(0, -Math.floor(Math.log(gridSliceTime * 1.01) / Math.LN10))};
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {!PerfUI.TimelineGrid.DividersData} dividersData
-   */
-  static drawCanvasGrid(context, dividersData) {
-    context.save();
-    context.scale(window.devicePixelRatio, window.devicePixelRatio);
-    const height = Math.floor(context.canvas.height / window.devicePixelRatio);
-    context.strokeStyle = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.1)', UI.ThemeSupport.ColorUsage.Foreground);
-    context.lineWidth = 1;
-
-    context.translate(0.5, 0.5);
-    context.beginPath();
-    for (const offsetInfo of dividersData.offsets) {
-      context.moveTo(offsetInfo.position, 0);
-      context.lineTo(offsetInfo.position, height);
-    }
-    context.stroke();
-    context.restore();
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {!PerfUI.TimelineGrid.DividersData} dividersData
-   * @param {function(number):string} formatTimeFunction
-   * @param {number} paddingTop
-   * @param {number} headerHeight
-   * @param {number=} freeZoneAtLeft
-   */
-  static drawCanvasHeaders(context, dividersData, formatTimeFunction, paddingTop, headerHeight, freeZoneAtLeft) {
-    context.save();
-    context.scale(window.devicePixelRatio, window.devicePixelRatio);
-    const width = Math.ceil(context.canvas.width / window.devicePixelRatio);
-
-    context.beginPath();
-    context.fillStyle =
-        UI.themeSupport.patchColorText('rgba(255, 255, 255, 0.5)', UI.ThemeSupport.ColorUsage.Background);
-    context.fillRect(0, 0, width, headerHeight);
-
-    context.fillStyle = UI.themeSupport.patchColorText('#333', UI.ThemeSupport.ColorUsage.Foreground);
-    context.textBaseline = 'hanging';
-    context.font = '11px ' + Host.fontFamily();
-
-    const paddingRight = 4;
-    for (const offsetInfo of dividersData.offsets) {
-      const text = formatTimeFunction(offsetInfo.time);
-      const textWidth = context.measureText(text).width;
-      const textPosition = offsetInfo.position - textWidth - paddingRight;
-      if (!freeZoneAtLeft || freeZoneAtLeft < textPosition)
-        context.fillText(text, textPosition, paddingTop);
-    }
-    context.restore();
-  }
-
-  get dividersElement() {
-    return this._dividersElement;
-  }
-
-  get dividersLabelBarElement() {
-    return this._dividersLabelBarElement;
-  }
-
-  removeDividers() {
-    this._dividersElement.removeChildren();
-    this._dividersLabelBarElement.removeChildren();
-  }
-
-  /**
-   * @param {!PerfUI.TimelineGrid.Calculator} calculator
-   * @param {number=} freeZoneAtLeft
-   * @return {boolean}
-   */
-  updateDividers(calculator, freeZoneAtLeft) {
-    const dividersData = PerfUI.TimelineGrid.calculateGridOffsets(calculator, freeZoneAtLeft);
-    const dividerOffsets = dividersData.offsets;
-    const precision = dividersData.precision;
-
-    const dividersElementClientWidth = this._dividersElement.clientWidth;
-
-    // Reuse divider elements and labels.
-    let divider = /** @type {?Element} */ (this._dividersElement.firstChild);
-    let dividerLabelBar = /** @type {?Element} */ (this._dividersLabelBarElement.firstChild);
-
-    for (let i = 0; i < dividerOffsets.length; ++i) {
-      if (!divider) {
-        divider = createElement('div');
-        divider.className = 'resources-divider';
-        this._dividersElement.appendChild(divider);
-
-        dividerLabelBar = createElement('div');
-        dividerLabelBar.className = 'resources-divider';
-        const label = createElement('div');
-        label.className = 'resources-divider-label';
-        dividerLabelBar._labelElement = label;
-        dividerLabelBar.appendChild(label);
-        this._dividersLabelBarElement.appendChild(dividerLabelBar);
-      }
-
-      const time = dividerOffsets[i].time;
-      const position = dividerOffsets[i].position;
-      dividerLabelBar._labelElement.textContent = calculator.formatValue(time, precision);
-
-      const percentLeft = 100 * position / dividersElementClientWidth;
-      divider.style.left = percentLeft + '%';
-      dividerLabelBar.style.left = percentLeft + '%';
-
-      divider = /** @type {?Element} */ (divider.nextSibling);
-      dividerLabelBar = /** @type {?Element} */ (dividerLabelBar.nextSibling);
-    }
-
-    // Remove extras.
-    while (divider) {
-      const nextDivider = divider.nextSibling;
-      this._dividersElement.removeChild(divider);
-      divider = nextDivider;
-    }
-    while (dividerLabelBar) {
-      const nextDivider = dividerLabelBar.nextSibling;
-      this._dividersLabelBarElement.removeChild(dividerLabelBar);
-      dividerLabelBar = nextDivider;
-    }
-    return true;
-  }
-
-  /**
-   * @param {!Element} divider
-   */
-  addEventDivider(divider) {
-    this._eventDividersElement.appendChild(divider);
-  }
-
-  /**
-   * @param {!Array.<!Element>} dividers
-   */
-  addEventDividers(dividers) {
-    this._gridHeaderElement.removeChild(this._eventDividersElement);
-    for (const divider of dividers)
-      this._eventDividersElement.appendChild(divider);
-    this._gridHeaderElement.appendChild(this._eventDividersElement);
-  }
-
-  removeEventDividers() {
-    this._eventDividersElement.removeChildren();
-  }
-
-  hideEventDividers() {
-    this._eventDividersElement.classList.add('hidden');
-  }
-
-  showEventDividers() {
-    this._eventDividersElement.classList.remove('hidden');
-  }
-
-  hideDividers() {
-    this._dividersElement.classList.add('hidden');
-  }
-
-  showDividers() {
-    this._dividersElement.classList.remove('hidden');
-  }
-
-  /**
-   * @param {number} scrollTop
-   */
-  setScrollTop(scrollTop) {
-    this._dividersLabelBarElement.style.top = scrollTop + 'px';
-    this._eventDividersElement.style.top = scrollTop + 'px';
-  }
-};
-
-/** @typedef {!{offsets: !Array<!{position: number, time: number}>, precision: number}} */
-PerfUI.TimelineGrid.DividersData;
-
-/**
- * @interface
- */
-PerfUI.TimelineGrid.Calculator = function() {};
-
-PerfUI.TimelineGrid.Calculator.prototype = {
-  /**
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {},
-
-  /**
-   * @param {number} time
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(time, precision) {},
-
-  /** @return {number} */
-  minimumBoundary() {},
-
-  /** @return {number} */
-  zeroTime() {},
-
-  /** @return {number} */
-  maximumBoundary() {},
-
-  /** @return {number} */
-  boundarySpan() {}
-};
diff --git a/front_end/perf_ui/TimelineOverviewPane.js b/front_end/perf_ui/TimelineOverviewPane.js
deleted file mode 100644
index 98be922..0000000
--- a/front_end/perf_ui/TimelineOverviewPane.js
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-PerfUI.TimelineOverviewPane = class extends UI.VBox {
-  /**
-   * @param {string} prefix
-   */
-  constructor(prefix) {
-    super();
-    this.element.id = prefix + '-overview-pane';
-
-    this._overviewCalculator = new PerfUI.TimelineOverviewCalculator();
-    this._overviewGrid = new PerfUI.OverviewGrid(prefix);
-    this.element.appendChild(this._overviewGrid.element);
-    this._cursorArea = this._overviewGrid.element.createChild('div', 'overview-grid-cursor-area');
-    this._cursorElement = this._overviewGrid.element.createChild('div', 'overview-grid-cursor-position');
-    this._cursorArea.addEventListener('mousemove', this._onMouseMove.bind(this), true);
-    this._cursorArea.addEventListener('mouseleave', this._hideCursor.bind(this), true);
-
-    this._overviewGrid.setResizeEnabled(false);
-    this._overviewGrid.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-    this._overviewGrid.setClickHandler(this._onClick.bind(this));
-    this._overviewControls = [];
-    this._markers = new Map();
-
-    this._overviewInfo = new PerfUI.TimelineOverviewPane.OverviewInfo(this._cursorElement);
-    this._updateThrottler = new Common.Throttler(100);
-
-    this._cursorEnabled = false;
-    this._cursorPosition = 0;
-    this._lastWidth = 0;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    if (!this._cursorEnabled)
-      return;
-    this._cursorPosition = event.offsetX + event.target.offsetLeft;
-    this._cursorElement.style.left = this._cursorPosition + 'px';
-    this._cursorElement.style.visibility = 'visible';
-    this._overviewInfo.setContent(this._buildOverviewInfo());
-  }
-
-  /**
-   * @return {!Promise<!DocumentFragment>}
-   */
-  async _buildOverviewInfo() {
-    const document = this.element.ownerDocument;
-    const x = this._cursorPosition;
-    const elements = await Promise.all(this._overviewControls.map(control => control.overviewInfoPromise(x)));
-    const fragment = document.createDocumentFragment();
-    elements.remove(null);
-    fragment.appendChildren.apply(fragment, elements);
-    return fragment;
-  }
-
-  _hideCursor() {
-    this._cursorElement.style.visibility = 'hidden';
-    this._overviewInfo.hide();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._update();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._overviewInfo.hide();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    const width = this.element.offsetWidth;
-    if (width === this._lastWidth)
-      return;
-    this._lastWidth = width;
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {!Array.<!PerfUI.TimelineOverview>} overviewControls
-   */
-  setOverviewControls(overviewControls) {
-    for (let i = 0; i < this._overviewControls.length; ++i)
-      this._overviewControls[i].dispose();
-
-    for (let i = 0; i < overviewControls.length; ++i) {
-      overviewControls[i].setCalculator(this._overviewCalculator);
-      overviewControls[i].show(this._overviewGrid.element);
-    }
-    this._overviewControls = overviewControls;
-    this._update();
-  }
-
-  /**
-   * @param {number} minimumBoundary
-   * @param {number} maximumBoundary
-   */
-  setBounds(minimumBoundary, maximumBoundary) {
-    this._overviewCalculator.setBounds(minimumBoundary, maximumBoundary);
-    this._overviewGrid.setResizeEnabled(true);
-    this._cursorEnabled = true;
-  }
-
-  scheduleUpdate() {
-    this._updateThrottler.schedule(process.bind(this));
-    /**
-     * @this {PerfUI.TimelineOverviewPane}
-     * @return {!Promise.<undefined>}
-     */
-    function process() {
-      this._update();
-      return Promise.resolve();
-    }
-  }
-
-  _update() {
-    if (!this.isShowing())
-      return;
-    this._overviewCalculator.setDisplayWidth(this._overviewGrid.clientWidth());
-    for (let i = 0; i < this._overviewControls.length; ++i)
-      this._overviewControls[i].update();
-    this._overviewGrid.updateDividers(this._overviewCalculator);
-    this._updateMarkers();
-    this._updateWindow();
-  }
-
-  /**
-   * @param {!Map<number, !Element>} markers
-   */
-  setMarkers(markers) {
-    this._markers = markers;
-  }
-
-  _updateMarkers() {
-    const filteredMarkers = new Map();
-    for (const time of this._markers.keys()) {
-      const marker = this._markers.get(time);
-      const position = Math.round(this._overviewCalculator.computePosition(time));
-      // Limit the number of markers to one per pixel.
-      if (filteredMarkers.has(position))
-        continue;
-      filteredMarkers.set(position, marker);
-      marker.style.left = position + 'px';
-    }
-    this._overviewGrid.removeEventDividers();
-    this._overviewGrid.addEventDividers(filteredMarkers.valuesArray());
-  }
-
-  reset() {
-    this._windowStartTime = 0;
-    this._windowEndTime = Infinity;
-    this._overviewCalculator.reset();
-    this._overviewGrid.reset();
-    this._overviewGrid.setResizeEnabled(false);
-    this._cursorEnabled = false;
-    this._hideCursor();
-    this._markers = new Map();
-    for (const control of this._overviewControls)
-      control.reset();
-    this._overviewInfo.hide();
-    this.scheduleUpdate();
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _onClick(event) {
-    return this._overviewControls.some(control => control.onClick(event));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWindowChanged(event) {
-    if (this._muteOnWindowChanged)
-      return;
-    // Always use first control as a time converter.
-    if (!this._overviewControls.length)
-      return;
-
-    const absoluteMin = this._overviewCalculator.minimumBoundary();
-    const timeSpan = this._overviewCalculator.maximumBoundary() - absoluteMin;
-    const windowTimes = {
-      startTime: absoluteMin + timeSpan * this._overviewGrid.windowLeft(),
-      endTime: absoluteMin + timeSpan * this._overviewGrid.windowRight()
-    };
-    this._windowStartTime = windowTimes.startTime;
-    this._windowEndTime = windowTimes.endTime;
-    this.dispatchEventToListeners(PerfUI.TimelineOverviewPane.Events.WindowChanged, windowTimes);
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  requestWindowTimes(startTime, endTime) {
-    if (startTime === this._windowStartTime && endTime === this._windowEndTime)
-      return;
-    this._windowStartTime = startTime;
-    this._windowEndTime = endTime;
-    this._updateWindow();
-    this.dispatchEventToListeners(
-        PerfUI.TimelineOverviewPane.Events.WindowChanged, {startTime: startTime, endTime: endTime});
-  }
-
-  _updateWindow() {
-    if (!this._overviewControls.length)
-      return;
-    const absoluteMin = this._overviewCalculator.minimumBoundary();
-    const timeSpan = this._overviewCalculator.maximumBoundary() - absoluteMin;
-    const haveRecords = absoluteMin > 0;
-    const left =
-        haveRecords && this._windowStartTime ? Math.min((this._windowStartTime - absoluteMin) / timeSpan, 1) : 0;
-    const right = haveRecords && this._windowEndTime < Infinity ? (this._windowEndTime - absoluteMin) / timeSpan : 1;
-    this._muteOnWindowChanged = true;
-    this._overviewGrid.setWindow(left, right);
-    this._muteOnWindowChanged = false;
-  }
-};
-
-/** @enum {symbol} */
-PerfUI.TimelineOverviewPane.Events = {
-  WindowChanged: Symbol('WindowChanged')
-};
-
-/**
- * @implements {PerfUI.TimelineGrid.Calculator}
- * @unrestricted
- */
-PerfUI.TimelineOverviewCalculator = class {
-  constructor() {
-    this.reset();
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {
-    return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea;
-  }
-
-  /**
-   * @param {number} position
-   * @return {number}
-   */
-  positionToTime(position) {
-    return position / this._workingArea * this.boundarySpan() + this._minimumBoundary;
-  }
-
-  /**
-   * @param {number} minimumBoundary
-   * @param {number} maximumBoundary
-   */
-  setBounds(minimumBoundary, maximumBoundary) {
-    this._minimumBoundary = minimumBoundary;
-    this._maximumBoundary = maximumBoundary;
-  }
-
-  /**
-   * @param {number} clientWidth
-   */
-  setDisplayWidth(clientWidth) {
-    this._workingArea = clientWidth;
-  }
-
-  reset() {
-    this.setBounds(0, 100);
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.preciseMillisToString(value - this.zeroTime(), precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maximumBoundary() {
-    return this._maximumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zeroTime() {
-    return this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  boundarySpan() {
-    return this._maximumBoundary - this._minimumBoundary;
-  }
-};
-
-/**
- * @interface
- */
-PerfUI.TimelineOverview = function() {};
-
-PerfUI.TimelineOverview.prototype = {
-  /**
-   * @param {!Element} parentElement
-   * @param {?Element=} insertBefore
-   */
-  show(parentElement, insertBefore) {},
-
-  update() {},
-
-  dispose() {},
-
-  reset() {},
-
-  /**
-   * @param {number} x
-   * @return {!Promise<?Element>}
-   */
-  overviewInfoPromise(x) {},
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  onClick(event) {},
-};
-
-/**
- * @implements {PerfUI.TimelineOverview}
- * @unrestricted
- */
-PerfUI.TimelineOverviewBase = class extends UI.VBox {
-  constructor() {
-    super();
-    /** @type {?PerfUI.TimelineOverviewCalculator} */
-    this._calculator = null;
-    this._canvas = this.element.createChild('canvas', 'fill');
-    this._context = this._canvas.getContext('2d');
-  }
-
-  /** @return {number} */
-  width() {
-    return this._canvas.width;
-  }
-
-  /** @return {number} */
-  height() {
-    return this._canvas.height;
-  }
-
-  /** @return {!CanvasRenderingContext2D} */
-  context() {
-    return this._context;
-  }
-
-  /**
-   * @protected
-   * @return {?PerfUI.TimelineOverviewCalculator}
-   */
-  calculator() {
-    return this._calculator;
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    this.resetCanvas();
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this.detach();
-  }
-
-  /**
-   * @override
-   */
-  reset() {
-  }
-
-  /**
-   * @override
-   * @param {number} x
-   * @return {!Promise<?Element>}
-   */
-  overviewInfoPromise(x) {
-    return Promise.resolve(/** @type {?Element} */ (null));
-  }
-
-  /**
-   * @param {!PerfUI.TimelineOverviewCalculator} calculator
-   */
-  setCalculator(calculator) {
-    this._calculator = calculator;
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  onClick(event) {
-    return false;
-  }
-
-  resetCanvas() {
-    if (this.element.clientWidth)
-      this.setCanvasSize(this.element.clientWidth, this.element.clientHeight);
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  setCanvasSize(width, height) {
-    this._canvas.width = width * window.devicePixelRatio;
-    this._canvas.height = height * window.devicePixelRatio;
-  }
-};
-
-PerfUI.TimelineOverviewPane.OverviewInfo = class {
-  /**
-   * @param {!Element} anchor
-   */
-  constructor(anchor) {
-    this._anchorElement = anchor;
-    this._glassPane = new UI.GlassPane();
-    this._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.PierceContents);
-    this._glassPane.setMarginBehavior(UI.GlassPane.MarginBehavior.Arrow);
-    this._glassPane.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    this._visible = false;
-    this._element =
-        UI.createShadowRootWithCoreStyles(this._glassPane.contentElement, 'perf_ui/timelineOverviewInfo.css')
-            .createChild('div', 'overview-info');
-  }
-
-  /**
-   * @param {!Promise<!DocumentFragment>} contentPromise
-   */
-  async setContent(contentPromise) {
-    this._visible = true;
-    const content = await contentPromise;
-    if (!this._visible)
-      return;
-    this._element.removeChildren();
-    this._element.appendChild(content);
-    this._glassPane.setContentAnchorBox(this._anchorElement.boxInWindow());
-    if (!this._glassPane.isShowing())
-      this._glassPane.show(/** @type {!Document} */ (this._anchorElement.ownerDocument));
-  }
-
-  hide() {
-    this._visible = false;
-    this._glassPane.hide();
-  }
-};
diff --git a/front_end/perf_ui/chartViewport.css b/front_end/perf_ui/chartViewport.css
deleted file mode 100644
index 22e1d6d..0000000
--- a/front_end/perf_ui/chartViewport.css
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.chart-viewport-v-scroll {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    overflow-x: hidden;
-    z-index: 200;
-    padding-left: 1px;
-}
-
-.chart-viewport-v-scroll.always-show-scrollbar {
-    overflow-y: scroll;
-}
-
-/* force non overlay scrollbars for Mac */
-:host-context(.platform-mac) .chart-viewport-v-scroll {
-    right: 2px;
-    top: 3px;
-    bottom: 3px;
-}
-
-:host-context(.platform-mac) ::-webkit-scrollbar {
-    width: 8px;
-}
-
-:host-context(.platform-mac) ::-webkit-scrollbar-thumb {
-    background-color: hsla(0, 0%, 56%, 0.6);
-    border-radius: 50px;
-}
-
-:host-context(.platform-mac) .chart-viewport-v-scroll:hover::-webkit-scrollbar-thumb {
-    background-color: hsla(0, 0%, 25%, 0.6);
-}
-
-/* force non overlay scrollbars for Aura Overlay Scrollbar enabled */
-:host-context(.overlay-scrollbar-enabled) ::-webkit-scrollbar {
-    width: 10px;
-}
-
-:host-context(.overlay-scrollbar-enabled) ::-webkit-scrollbar-thumb {
-    background-color: hsla(0, 0%, 0%, 0.5);
-}
-
-:host-context(.overlay-scrollbar-enabled) .chart-viewport-v-scroll:hover::-webkit-scrollbar-thumb {
-    background-color: hsla(0, 0%, 0%, 0.7);
-}
-
-.chart-viewport-selection-overlay {
-    position: absolute;
-    z-index: 100;
-    background-color: rgba(56, 121, 217, 0.3);
-    border-color: rgb(16, 81, 177);
-    border-width: 0 1px;
-    border-style: solid;
-    pointer-events: none;
-    top: 0;
-    bottom: 0;
-    text-align: center;
-}
-
-.chart-viewport-selection-overlay .time-span {
-    white-space: nowrap;
-    position: absolute;
-    left: 0;
-    right: 0;
-    bottom: 0;
-}
diff --git a/front_end/perf_ui/filmStripView.css b/front_end/perf_ui/filmStripView.css
deleted file mode 100644
index 34143c6..0000000
--- a/front_end/perf_ui/filmStripView.css
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.film-strip-view {
-    overflow-x: auto;
-    overflow-y: hidden;
-    align-content: flex-start;
-    min-height: 81px;
-}
-
-.film-strip-view.time-based .frame .time {
-    display: none;
-}
-
-.film-strip-view .label {
-    margin: auto;
-    font-size: 18px;
-    color: #999;
-}
-
-.film-strip-view .frame {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    padding: 4px;
-    flex: none;
-    cursor: pointer;
-}
-
-.film-strip-view .frame-limit-reached {
-    font-size: 24px;
-    color: #888;
-    justify-content: center;
-    display: inline-flex;
-    flex-direction: column;
-    flex: none;
-}
-
-.film-strip-view .frame .thumbnail {
-    min-width: 24px;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    pointer-events: none;
-    margin: 4px 0 2px;
-    border: 2px solid transparent;
-}
-
-.film-strip-view .frame:hover .thumbnail {
-    border-color: #FBCA46;
-}
-
-.film-strip-view .frame .thumbnail img {
-    height: auto;
-    width: auto;
-    max-width: 80px;
-    max-height: 50px;
-    pointer-events: none;
-    box-shadow: 0 0 3px #bbb;
-    flex: 0 0 auto;
-}
-
-.film-strip-view .frame:hover .thumbnail img {
-    box-shadow: none;
-}
-
-.film-strip-view .frame .time {
-    font-size: 10px;
-    margin-top: 2px;
-}
diff --git a/front_end/perf_ui/flameChart.css b/front_end/perf_ui/flameChart.css
deleted file mode 100644
index 7c085e5..0000000
--- a/front_end/perf_ui/flameChart.css
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.flame-chart-main-pane {
-    overflow: hidden;
-}
-
-.flame-chart-marker-highlight-element {
-    position: absolute;
-    top: 1px;
-    height: 18px;
-    width: 6px;
-    margin: 0 -3px;
-    content: "";
-    display: block;
-}
-
-.flame-chart-highlight-element {
-    position: absolute;
-    pointer-events: none;
-    background-color: rgba(56, 121, 217, 0.1);
-}
-
-.flame-chart-selected-element {
-    position: absolute;
-    pointer-events: none;
-    outline: 2px solid var(--selection-bg-color);
-    background-color: rgba(56, 121, 217, 0.1);
-}
-
-.chart-cursor-element {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    z-index: 100;
-    width: 2px;
-    background-color: var(--selection-bg-color);
-    pointer-events: none;
-}
-
-.flame-chart-entry-info:not(:empty) {
-    z-index: 2000;
-    position: absolute;
-    background-color: white;
-    pointer-events: none;
-    padding: 4px 8px;
-    white-space: nowrap;
-    max-width: 80%;
-    box-shadow: var(--drop-shadow);
-}
-
-.flame-chart-entry-info table tr td:empty {
-    padding: 0;
-}
-
-.flame-chart-entry-info table tr td:not(:empty) {
-    padding: 0 5px;
-    white-space: nowrap;
-}
-
-.flame-chart-entry-info table tr td:first-child {
-    font-weight: bold;
-}
-
-.flame-chart-entry-info table tr td span {
-    margin-right: 5px;
-}
diff --git a/front_end/perf_ui/module.json b/front_end/perf_ui/module.json
deleted file mode 100644
index 49e3abc..0000000
--- a/front_end/perf_ui/module.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@SourceFrame.LineDecorator",
-            "className": "PerfUI.LineLevelProfile.LineDecorator",
-            "decoratorType": "performance"
-        },
-        {
-            "type": "setting",
-            "category": "Performance",
-            "title": "Flamechart mouse wheel action:",
-            "settingName": "flamechartMouseWheelAction",
-            "settingType": "enum",
-            "defaultValue": "zoom",
-            "options": [
-                {
-                    "title": "Scroll",
-                    "text": "Scroll",
-                    "value": "scroll"
-                },
-                {
-                    "title": "Zoom",
-                    "text": "Zoom",
-                    "value": "zoom"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "components.collect-garbage",
-            "title": "Collect garbage",
-            "iconClass": "largeicon-trash-bin",
-            "className": "PerfUI.GCActionDelegate"
-        }
-    ],
-    "dependencies": [
-        "ui",
-        "sdk",
-        "bindings",
-        "source_frame",
-        "text_editor"
-    ],
-    "scripts": [
-        "ChartViewport.js",
-        "FilmStripView.js",
-        "FlameChart.js",
-        "GCActionDelegate.js",
-        "LineLevelProfile.js",
-        "NetworkPriorities.js",
-        "OverviewGrid.js",
-        "PieChart.js",
-        "TimelineGrid.js",
-        "TimelineOverviewPane.js"
-    ],
-    "resources": [
-        "chartViewport.css",
-        "filmStripView.css",
-        "flameChart.css",
-        "overviewGrid.css",
-        "pieChart.css",
-        "timelineGrid.css",
-        "timelineOverviewInfo.css"
-    ]
-}
diff --git a/front_end/perf_ui/overviewGrid.css b/front_end/perf_ui/overviewGrid.css
deleted file mode 100644
index fd09baf..0000000
--- a/front_end/perf_ui/overviewGrid.css
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.overview-grid-window-selector {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    background-color: rgba(125, 173, 217, 0.5);
-    z-index: 250;
-    pointer-events: none;
-}
-
-.overview-grid-window-resizer {
-    position: absolute;
-    top: -1px;
-    height: 20px;
-    width: 6px;
-    margin-left: -3px;
-    background-color: rgb(153, 153, 153);
-    border: 1px solid white;
-    z-index: 500;
-}
-
-.overview-grid-cursor-area {
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 20px;
-    bottom: 0;
-    z-index: 500;
-    cursor: text;
-}
-
-.overview-grid-cursor-position {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    width: 2px;
-    background-color: hsla(220, 95%, 50%, 0.7);
-    z-index: 500;
-    pointer-events: none;
-    visibility: hidden;
-    overflow: hidden;
-}
-
-.window-curtain-left, .window-curtain-right {
-    background-color: hsla(0, 0%, 80%, 0.5);
-    position: absolute;
-    top: 0;
-    height: 100%;
-    z-index: 300;
-    pointer-events: none;
-    border: 1px none hsla(0, 0%, 70%, 0.5);
-}
-
-.window-curtain-left {
-    left: 0;
-    border-right-style: solid;
-}
-
-.window-curtain-right {
-    right: 0;
-    border-left-style: solid;
-}
diff --git a/front_end/perf_ui/pieChart.css b/front_end/perf_ui/pieChart.css
deleted file mode 100644
index bef554f..0000000
--- a/front_end/perf_ui/pieChart.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.root {
-    position: relative;
-    width: 100%;
-    height: 100%;
-}
-
-.pie-chart-foreground {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    z-index: 10;
-    top: 0;
-    display: flex;
-}
-
-.pie-chart-total {
-    margin: auto;
-    padding: 2px 5px;
-    background-color: rgba(255, 255, 255, 0.6);
-}
diff --git a/front_end/perf_ui/timelineGrid.css b/front_end/perf_ui/timelineGrid.css
deleted file mode 100644
index 9e2382e..0000000
--- a/front_end/perf_ui/timelineGrid.css
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.resources-dividers {
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 0;
-    z-index: -100;
-    bottom: 0;
-}
-
-.resources-event-dividers {
-    position: absolute;
-    left: 0;
-    right: 0;
-    height: 100%;
-    top: 0;
-    z-index: 300;
-    pointer-events: none;
-}
-
-.resources-dividers-label-bar {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    background-color: rgba(255, 255, 255, 0.85);
-    background-clip: padding-box;
-    height: 20px;
-    z-index: 200;
-    pointer-events: none;
-    overflow: hidden;
-}
-
-.resources-divider {
-    position: absolute;
-    width: 1px;
-    top: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, 0.1);
-}
-
-.resources-event-divider {
-    position: absolute;
-    width: 1px;
-    top: 0;
-    bottom: 0;
-    z-index: 300;
-}
-
-.resources-divider-label {
-    position: absolute;
-    top: 4px;
-    right: 3px;
-    font-size: 80%;
-    white-space: nowrap;
-    pointer-events: none;
-}
-
-.timeline-grid-header {
-    height: 20px;
-    pointer-events: none;
-}
diff --git a/front_end/perf_ui/timelineOverviewInfo.css b/front_end/perf_ui/timelineOverviewInfo.css
deleted file mode 100644
index c79d7a7..0000000
--- a/front_end/perf_ui/timelineOverviewInfo.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.overview-info:not(:empty) {
-    display: flex;
-    background: white;
-    box-shadow: var(--drop-shadow);
-    padding: 3px;
-}
-
-.overview-info .frame .time {
-    display: none;
-}
-
-.overview-info .frame .thumbnail img {
-    max-width: 50vw;
-    max-height: 50vh;
-}
diff --git a/front_end/performance_monitor/PerformanceMonitor.js b/front_end/performance_monitor/PerformanceMonitor.js
deleted file mode 100644
index cd83433..0000000
--- a/front_end/performance_monitor/PerformanceMonitor.js
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-PerformanceMonitor.PerformanceMonitor = class extends UI.HBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('performance_monitor/performanceMonitor.css');
-    this.contentElement.classList.add('perfmon-pane');
-    this._model = SDK.targetManager.mainTarget().model(SDK.PerformanceMetricsModel);
-    /** @type {!Array<!{timestamp: number, metrics: !Map<string, number>}>} */
-    this._metricsBuffer = [];
-    /** @const */
-    this._pixelsPerMs = 20 / 1000;
-    /** @const */
-    this._pollIntervalMs = 500;
-    /** @const */
-    this._scaleHeight = 16;
-    /** @const */
-    this._graphHeight = 90;
-    this._gridColor = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.08)', UI.ThemeSupport.ColorUsage.Foreground);
-    this._controlPane = new PerformanceMonitor.PerformanceMonitor.ControlPane(this.contentElement);
-    const chartContainer = this.contentElement.createChild('div', 'perfmon-chart-container');
-    this._canvas = /** @type {!HTMLCanvasElement} */ (chartContainer.createChild('canvas'));
-    this.contentElement.createChild('div', 'perfmon-chart-suspend-overlay fill').createChild('div').textContent =
-        Common.UIString('Paused');
-    this._controlPane.addEventListener(
-        PerformanceMonitor.PerformanceMonitor.ControlPane.Events.MetricChanged, this._recalcChartHeight, this);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._suspendStateChanged, this);
-    this._model.enable();
-    this._suspendStateChanged();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    SDK.targetManager.removeEventListener(
-        SDK.TargetManager.Events.SuspendStateChanged, this._suspendStateChanged, this);
-    this._stopPolling();
-    this._model.disable();
-  }
-
-  _suspendStateChanged() {
-    const suspended = SDK.targetManager.allTargetsSuspended();
-    if (suspended)
-      this._stopPolling();
-    else
-      this._startPolling();
-    this.contentElement.classList.toggle('suspended', suspended);
-  }
-
-  _startPolling() {
-    this._startTimestamp = 0;
-    this._pollTimer = setInterval(() => this._poll(), this._pollIntervalMs);
-    this.onResize();
-    animate.call(this);
-
-    /**
-     * @this {PerformanceMonitor.PerformanceMonitor}
-     */
-    function animate() {
-      this._draw();
-      this._animationId = this.contentElement.window().requestAnimationFrame(animate.bind(this));
-    }
-  }
-
-  _stopPolling() {
-    clearInterval(this._pollTimer);
-    this.contentElement.window().cancelAnimationFrame(this._animationId);
-    this._metricsBuffer = [];
-  }
-
-  async _poll() {
-    const data = await this._model.requestMetrics();
-    const timestamp = data.timestamp;
-    const metrics = data.metrics;
-    this._metricsBuffer.push({timestamp, metrics: metrics});
-    const millisPerWidth = this._width / this._pixelsPerMs;
-    // Multiply by 2 as the pollInterval has some jitter and to have some extra samples if window is resized.
-    const maxCount = Math.ceil(millisPerWidth / this._pollIntervalMs * 2);
-    if (this._metricsBuffer.length > maxCount * 2)  // Multiply by 2 to have a hysteresis.
-      this._metricsBuffer.splice(0, this._metricsBuffer.length - maxCount);
-    this._controlPane.updateMetrics(metrics);
-  }
-
-  _draw() {
-    const ctx = /** @type {!CanvasRenderingContext2D} */ (this._canvas.getContext('2d'));
-    ctx.save();
-    ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
-    ctx.clearRect(0, 0, this._width, this._height);
-    ctx.save();
-    ctx.translate(0, this._scaleHeight);  // Reserve space for the scale bar.
-    for (const chartInfo of this._controlPane.charts()) {
-      if (!this._controlPane.isActive(chartInfo.metrics[0].name))
-        continue;
-      this._drawChart(ctx, chartInfo, this._graphHeight);
-      ctx.translate(0, this._graphHeight);
-    }
-    ctx.restore();
-    this._drawHorizontalGrid(ctx);
-    ctx.restore();
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} ctx
-   */
-  _drawHorizontalGrid(ctx) {
-    const lightGray = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.02)', UI.ThemeSupport.ColorUsage.Foreground);
-    ctx.font = '9px ' + Host.fontFamily();
-    ctx.fillStyle = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.3)', UI.ThemeSupport.ColorUsage.Foreground);
-    const currentTime = Date.now() / 1000;
-    for (let sec = Math.ceil(currentTime);; --sec) {
-      const x = this._width - ((currentTime - sec) * 1000 - this._pollIntervalMs) * this._pixelsPerMs;
-      if (x < -50)
-        break;
-      ctx.beginPath();
-      ctx.moveTo(Math.round(x) + 0.5, 0);
-      ctx.lineTo(Math.round(x) + 0.5, this._height);
-      if (sec >= 0 && sec % 5 === 0)
-        ctx.fillText(new Date(sec * 1000).toLocaleTimeString(), Math.round(x) + 4, 12);
-      ctx.strokeStyle = sec % 5 ? lightGray : this._gridColor;
-      ctx.stroke();
-    }
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} ctx
-   * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} chartInfo
-   * @param {number} height
-   */
-  _drawChart(ctx, chartInfo, height) {
-    ctx.save();
-    ctx.rect(0, 0, this._width, height);
-    ctx.clip();
-    const bottomPadding = 8;
-    const extraSpace = 1.05;
-    const max = this._calcMax(chartInfo) * extraSpace;
-    const stackedChartBaseLandscape = chartInfo.stacked ? new Map() : null;
-    const paths = [];
-    for (let i = chartInfo.metrics.length - 1; i >= 0; --i) {
-      const metricInfo = chartInfo.metrics[i];
-      paths.push({
-        path: this._buildMetricPath(
-            chartInfo, metricInfo, height - bottomPadding, max, i ? stackedChartBaseLandscape : null),
-        color: metricInfo.color
-      });
-    }
-    const backgroundColor =
-        Common.Color.parse(UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background));
-    for (const path of paths.reverse()) {
-      const color = path.color;
-      ctx.save();
-      ctx.fillStyle = backgroundColor.blendWith(Common.Color.parse(color).setAlpha(0.2)).asString(null);
-      ctx.fill(path.path);
-      ctx.strokeStyle = color;
-      ctx.lineWidth = 0.5;
-      ctx.stroke(path.path);
-      ctx.restore();
-    }
-    this._drawVerticalGrid(ctx, height - bottomPadding, max, chartInfo);
-    ctx.restore();
-  }
-
-  /**
-   * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} chartInfo
-   * @return {number}
-   */
-  _calcMax(chartInfo) {
-    if (chartInfo.max)
-      return chartInfo.max;
-    const width = this._width;
-    const startTime = performance.now() - this._pollIntervalMs - width / this._pixelsPerMs;
-    let max = -Infinity;
-    for (const metricInfo of chartInfo.metrics) {
-      for (let i = this._metricsBuffer.length - 1; i >= 0; --i) {
-        const metrics = this._metricsBuffer[i];
-        const value = metrics.metrics.get(metricInfo.name);
-        max = Math.max(max, value);
-        if (metrics.timestamp < startTime)
-          break;
-      }
-    }
-    if (!this._metricsBuffer.length)
-      return 10;
-
-    const base10 = Math.pow(10, Math.floor(Math.log10(max)));
-    max = Math.ceil(max / base10 / 2) * base10 * 2;
-
-    const alpha = 0.2;
-    chartInfo.currentMax = max * alpha + (chartInfo.currentMax || max) * (1 - alpha);
-    return chartInfo.currentMax;
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} ctx
-   * @param {number} height
-   * @param {number} max
-   * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} info
-   */
-  _drawVerticalGrid(ctx, height, max, info) {
-    let base = Math.pow(10, Math.floor(Math.log10(max)));
-    const firstDigit = Math.floor(max / base);
-    if (firstDigit !== 1 && firstDigit % 2 === 1)
-      base *= 2;
-    let scaleValue = Math.floor(max / base) * base;
-
-    const span = max;
-    const topPadding = 5;
-    const visibleHeight = height - topPadding;
-    ctx.fillStyle = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.3)', UI.ThemeSupport.ColorUsage.Foreground);
-    ctx.strokeStyle = this._gridColor;
-    ctx.beginPath();
-    for (let i = 0; i < 2; ++i) {
-      const y = calcY(scaleValue);
-      const labelText = PerformanceMonitor.PerformanceMonitor.MetricIndicator._formatNumber(scaleValue, info);
-      ctx.moveTo(0, y);
-      ctx.lineTo(4, y);
-      ctx.moveTo(ctx.measureText(labelText).width + 12, y);
-      ctx.lineTo(this._width, y);
-      ctx.fillText(labelText, 8, calcY(scaleValue) + 3);
-      scaleValue /= 2;
-    }
-    ctx.stroke();
-    ctx.beginPath();
-    ctx.moveTo(0, height + 0.5);
-    ctx.lineTo(this._width, height + 0.5);
-    ctx.strokeStyle = UI.themeSupport.patchColorText('rgba(0, 0, 0, 0.2)', UI.ThemeSupport.ColorUsage.Foreground);
-    ctx.stroke();
-    /**
-     * @param {number} value
-     * @return {number}
-     */
-    function calcY(value) {
-      return Math.round(height - visibleHeight * value / span) + 0.5;
-    }
-  }
-
-  /**
-   * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} chartInfo
-   * @param {!PerformanceMonitor.PerformanceMonitor.MetricInfo} metricInfo
-   * @param {number} height
-   * @param {number} scaleMax
-   * @param {?Map<number, number>} stackedChartBaseLandscape
-   * @return {!Path2D}
-   */
-  _buildMetricPath(chartInfo, metricInfo, height, scaleMax, stackedChartBaseLandscape) {
-    const path = new Path2D();
-    const topPadding = 5;
-    const visibleHeight = height - topPadding;
-    if (visibleHeight < 1)
-      return path;
-    const span = scaleMax;
-    const metricName = metricInfo.name;
-    const pixelsPerMs = this._pixelsPerMs;
-    const startTime = performance.now() - this._pollIntervalMs - this._width / pixelsPerMs;
-    const smooth = chartInfo.smooth;
-
-    let x = 0;
-    let lastY = 0;
-    let lastX = 0;
-    if (this._metricsBuffer.length) {
-      x = (this._metricsBuffer[0].timestamp - startTime) * pixelsPerMs;
-      path.moveTo(x, calcY(0));
-      path.lineTo(this._width + 5, calcY(0));
-      lastY = calcY(this._metricsBuffer.peekLast().metrics.get(metricName));
-      lastX = this._width + 5;
-      path.lineTo(lastX, lastY);
-    }
-    for (let i = this._metricsBuffer.length - 1; i >= 0; --i) {
-      const metrics = this._metricsBuffer[i];
-      const timestamp = metrics.timestamp;
-      let value = metrics.metrics.get(metricName);
-      if (stackedChartBaseLandscape) {
-        value += stackedChartBaseLandscape.get(timestamp) || 0;
-        value = Number.constrain(value, 0, 1);
-        stackedChartBaseLandscape.set(timestamp, value);
-      }
-      const y = calcY(value);
-      x = (timestamp - startTime) * pixelsPerMs;
-      if (smooth) {
-        const midX = (lastX + x) / 2;
-        path.bezierCurveTo(midX, lastY, midX, y, x, y);
-      } else {
-        path.lineTo(x, lastY);
-        path.lineTo(x, y);
-      }
-      lastX = x;
-      lastY = y;
-      if (timestamp < startTime)
-        break;
-    }
-    return path;
-
-    /**
-     * @param {number} value
-     * @return {number}
-     */
-    function calcY(value) {
-      return Math.round(height - visibleHeight * value / span) + 0.5;
-    }
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    super.onResize();
-    this._width = this._canvas.offsetWidth;
-    this._canvas.width = Math.round(this._width * window.devicePixelRatio);
-    this._recalcChartHeight();
-  }
-
-  _recalcChartHeight() {
-    let height = this._scaleHeight;
-    for (const chartInfo of this._controlPane.charts()) {
-      if (this._controlPane.isActive(chartInfo.metrics[0].name))
-        height += this._graphHeight;
-    }
-    this._height = Math.ceil(height * window.devicePixelRatio);
-    this._canvas.height = this._height;
-    this._canvas.style.height = `${this._height / window.devicePixelRatio}px`;
-  }
-};
-
-/** @enum {symbol} */
-PerformanceMonitor.PerformanceMonitor.Format = {
-  Percent: Symbol('Percent'),
-  Bytes: Symbol('Bytes'),
-};
-
-/**
- * @typedef {!{
- *   title: string,
- *   metrics: !Array<!PerformanceMonitor.PerformanceMonitor.MetricInfo>,
- *   max: (number|undefined),
- *   currentMax: (number|undefined),
- *   format: (!PerformanceMonitor.PerformanceMonitor.Format|undefined),
- *   smooth: (boolean|undefined)
- * }}
- */
-PerformanceMonitor.PerformanceMonitor.ChartInfo;
-
-/**
- * @typedef {!{
- *   name: string,
- *   color: string
- * }}
- */
-PerformanceMonitor.PerformanceMonitor.MetricInfo;
-
-PerformanceMonitor.PerformanceMonitor.ControlPane = class extends Common.Object {
-  /**
-   * @param {!Element} parent
-   */
-  constructor(parent) {
-    super();
-    this.element = parent.createChild('div', 'perfmon-control-pane');
-
-    this._enabledChartsSetting =
-        Common.settings.createSetting('perfmonActiveIndicators2', ['TaskDuration', 'JSHeapTotalSize', 'Nodes']);
-    /** @type {!Set<string>} */
-    this._enabledCharts = new Set(this._enabledChartsSetting.get());
-    const format = PerformanceMonitor.PerformanceMonitor.Format;
-
-    /** @type {!Array<!PerformanceMonitor.PerformanceMonitor.ChartInfo>} */
-    this._chartsInfo = [
-      {
-        title: Common.UIString('CPU usage'),
-        metrics: [
-          {name: 'TaskDuration', color: '#999'}, {name: 'ScriptDuration', color: 'orange'},
-          {name: 'LayoutDuration', color: 'blueviolet'}, {name: 'RecalcStyleDuration', color: 'violet'}
-        ],
-        format: format.Percent,
-        smooth: true,
-        stacked: true,
-        color: 'red',
-        max: 1
-      },
-      {
-        title: Common.UIString('JS heap size'),
-        metrics: [{name: 'JSHeapTotalSize', color: '#99f'}, {name: 'JSHeapUsedSize', color: 'blue'}],
-        format: format.Bytes,
-        color: 'blue'
-      },
-      {title: Common.UIString('DOM Nodes'), metrics: [{name: 'Nodes', color: 'green'}]},
-      {title: Common.UIString('JS event listeners'), metrics: [{name: 'JSEventListeners', color: 'yellowgreen'}]},
-      {title: Common.UIString('Documents'), metrics: [{name: 'Documents', color: 'darkblue'}]},
-      {title: Common.UIString('Document Frames'), metrics: [{name: 'Frames', color: 'darkcyan'}]},
-      {title: Common.UIString('Layouts / sec'), metrics: [{name: 'LayoutCount', color: 'hotpink'}]},
-      {title: Common.UIString('Style recalcs / sec'), metrics: [{name: 'RecalcStyleCount', color: 'deeppink'}]}
-    ];
-    for (const info of this._chartsInfo) {
-      for (const metric of info.metrics)
-        metric.color = UI.themeSupport.patchColorText(metric.color, UI.ThemeSupport.ColorUsage.Foreground);
-    }
-
-    /** @type {!Map<string, !PerformanceMonitor.PerformanceMonitor.MetricIndicator>} */
-    this._indicators = new Map();
-    for (const chartInfo of this._chartsInfo) {
-      const chartName = chartInfo.metrics[0].name;
-      const active = this._enabledCharts.has(chartName);
-      const indicator = new PerformanceMonitor.PerformanceMonitor.MetricIndicator(
-          this.element, chartInfo, active, this._onToggle.bind(this, chartName));
-      this._indicators.set(chartName, indicator);
-    }
-  }
-
-  /**
-   * @param {string} chartName
-   * @param {boolean} active
-   */
-  _onToggle(chartName, active) {
-    if (active)
-      this._enabledCharts.add(chartName);
-    else
-      this._enabledCharts.delete(chartName);
-    this._enabledChartsSetting.set(Array.from(this._enabledCharts));
-    this.dispatchEventToListeners(PerformanceMonitor.PerformanceMonitor.ControlPane.Events.MetricChanged);
-  }
-
-  /**
-   * @return {!Array<!PerformanceMonitor.PerformanceMonitor.ChartInfo>}
-   */
-  charts() {
-    return this._chartsInfo;
-  }
-
-  /**
-   * @param {string} metricName
-   * @return {boolean}
-   */
-  isActive(metricName) {
-    return this._enabledCharts.has(metricName);
-  }
-
-  /**
-   * @param {!Map<string, number>} metrics
-   */
-  updateMetrics(metrics) {
-    for (const name of this._indicators.keys()) {
-      if (metrics.has(name))
-        this._indicators.get(name).setValue(metrics.get(name));
-    }
-  }
-};
-
-/** @enum {symbol} */
-PerformanceMonitor.PerformanceMonitor.ControlPane.Events = {
-  MetricChanged: Symbol('MetricChanged')
-};
-
-PerformanceMonitor.PerformanceMonitor.MetricIndicator = class {
-  /**
-   * @param {!Element} parent
-   * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} info
-   * @param {boolean} active
-   * @param {function(boolean)} onToggle
-   */
-  constructor(parent, info, active, onToggle) {
-    const color = info.color || info.metrics[0].color;
-    this._info = info;
-    this._active = active;
-    this._onToggle = onToggle;
-    this.element = parent.createChild('div', 'perfmon-indicator');
-    this._swatchElement = UI.Icon.create('smallicon-checkmark-square', 'perfmon-indicator-swatch');
-    this._swatchElement.style.backgroundColor = color;
-    this.element.appendChild(this._swatchElement);
-    this.element.createChild('div', 'perfmon-indicator-title').textContent = info.title;
-    this._valueElement = this.element.createChild('div', 'perfmon-indicator-value');
-    this._valueElement.style.color = color;
-    this.element.addEventListener('click', () => this._toggleIndicator());
-    this.element.classList.toggle('active', active);
-  }
-
-  /**
-   * @param {number} value
-   * @param {!PerformanceMonitor.PerformanceMonitor.ChartInfo} info
-   * @return {string}
-   */
-  static _formatNumber(value, info) {
-    switch (info.format) {
-      case PerformanceMonitor.PerformanceMonitor.Format.Percent:
-        return value.toLocaleString('en-US', {maximumFractionDigits: 1, style: 'percent'});
-      case PerformanceMonitor.PerformanceMonitor.Format.Bytes:
-        return Number.bytesToString(value);
-      default:
-        return value.toLocaleString('en-US', {maximumFractionDigits: 1});
-    }
-  }
-
-  /**
-   * @param {number} value
-   */
-  setValue(value) {
-    this._valueElement.textContent =
-        PerformanceMonitor.PerformanceMonitor.MetricIndicator._formatNumber(value, this._info);
-  }
-
-  _toggleIndicator() {
-    this._active = !this._active;
-    this.element.classList.toggle('active', this._active);
-    this._onToggle(this._active);
-  }
-};
-
-PerformanceMonitor.PerformanceMonitor.MetricIndicator._format =
-    new Intl.NumberFormat('en-US', {maximumFractionDigits: 1});
diff --git a/front_end/performance_monitor/module.json b/front_end/performance_monitor/module.json
deleted file mode 100644
index e86cc98..0000000
--- a/front_end/performance_monitor/module.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "performance.monitor",
-            "title": "Performance monitor",
-            "persistence": "closeable",
-            "order": 100,
-            "className": "PerformanceMonitor.PerformanceMonitor",
-            "tags": "performance, system monitor, monitor, activity, metrics"
-        }
-    ],
-    "dependencies": [
-        "sdk",
-        "ui"
-    ],
-    "scripts": [
-        "PerformanceMonitor.js"
-    ],
-    "resources": [
-        "performanceMonitor.css"
-    ]
-}
diff --git a/front_end/performance_monitor/performanceMonitor.css b/front_end/performance_monitor/performanceMonitor.css
deleted file mode 100644
index afa5735..0000000
--- a/front_end/performance_monitor/performanceMonitor.css
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.perfmon-pane {
-  overflow: hidden;
-}
-
-.perfmon-pane.suspended {
-  opacity: 0.4;
-  pointer-events: none;
-}
-
-.perfmon-pane .perfmon-chart-suspend-overlay {
-  display: none;
-  font-size: 26px;
-  align-items: center;
-  justify-content: center;
-}
-
-.perfmon-pane.suspended .perfmon-chart-suspend-overlay {
-  display: flex;
-}
-
-.perfmon-control-pane {
-  display: flex;
-  flex-direction: column;
-  padding: 6px 0;
-  overflow-x: hidden;
-  overflow-y: auto;
-}
-
-.perfmon-chart-container {
-  display: flex;
-  flex: 1 1;
-  border-left: 1px solid #ccc;
-  overflow-y: auto;
-}
-
-.perfmon-chart-container canvas {
-  width: 100%;
-}
-
-.perfmon-indicator {
-  padding: 6px 12px;
-  margin: -1px 0;
-  display: flex;
-  flex-shrink: 0;
-  width: 210px;
-}
-
-.perfmon-indicator:hover {
-  background-color: #f8f8f8;
-}
-
-.perfmon-indicator-swatch {
-  margin-right: 6px;
-}
-
-.perfmon-indicator:not(.active) .perfmon-indicator-swatch {
-  background-color: #eee !important;
-}
-
-.perfmon-indicator-title {
-  flex: 0 0 115px;
-}
-
-.perfmon-indicator:not(.active) .perfmon-indicator-title {
-  color: #aaa;
-}
-
-.perfmon-indicator-value {
-  flex: 0 0 55px;
-  text-align: right;
-  overflow: visible;
-}
-
-.perfmon-indicator:not(.active) .perfmon-indicator-value {
-  opacity: 0;
-}
-
-.perfmon-indicator-close {
-  padding-left: 4px;
-}
-
-.perfmon-indicator:not(:hover) .perfmon-indicator-close {
-  opacity: 0;
-}
-
-.perfmon-add-button:not(:hover) {
-  color: #bbb;
-}
diff --git a/front_end/performance_test_runner/TimelineDataTestRunner.js b/front_end/performance_test_runner/TimelineDataTestRunner.js
deleted file mode 100644
index 57eb6ec..0000000
--- a/front_end/performance_test_runner/TimelineDataTestRunner.js
+++ /dev/null
@@ -1,5375 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-PerformanceTestRunner.timelineData = function() {
-  return JSON.stringify([
-    {
-      'args': {'number': 32},
-
-      'cat': '__metadata',
-      'name': 'num_cpus',
-      'ph': 'M',
-      'pid': 3840,
-      'tid': 0,
-      'ts': 0
-    },
-    {
-      'args': {'sort_index': -5},
-
-      'cat': '__metadata',
-      'name': 'process_sort_index',
-      'ph': 'M',
-      'pid': 3840,
-      'tid': 12,
-      'ts': 0
-    },
-    {
-      'args': {'name': 'Renderer'},
-
-      'cat': '__metadata',
-      'name': 'process_name',
-      'ph': 'M',
-      'pid': 3840,
-      'tid': 12,
-      'ts': 0
-    },
-    {
-      'args': {'sort_index': -1},
-
-      'cat': '__metadata',
-      'name': 'thread_sort_index',
-      'ph': 'M',
-      'pid': 3840,
-      'tid': 11,
-      'ts': 0
-    },
-    {
-      'args': {'data': {'sessionId': '9.4', 'frames': [{'frame': 'frame1', 'url': 'frameurl', 'name': 'frame-name'}]}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'TracingStartedInPage',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673092068,
-      'tts': 170409
-    },
-    {
-      'args': {'data': {'layerTreeId': 17, 'frame': 'frame-unknown'}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'SetLayerTreeId',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673092082,
-      'tts': 170421
-    },
-    {
-      'args': {'data': {'layerTreeId': 1, 'frame': 'frame1'}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'SetLayerTreeId',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673092083,
-      'tts': 170421
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673092095,
-      'tts': 170434
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673107791,
-      'tts': 170482
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673107799,
-      'tts': 170490
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 438}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 65,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 64,
-      'tid': 9,
-      'ts': 1122673107821,
-      'tts': 170511
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 27,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 26,
-      'tid': 9,
-      'ts': 1122673107849,
-      'tts': 170539
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 439}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673107869,
-      'tts': 170559
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2688936, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673107883,
-      'tts': 170573
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673107891,
-      'tts': 170581
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673107921,
-      'tts': 170612
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673107934,
-      'tts': 170624
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673107941,
-      'tts': 170631
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673126470,
-      'tts': 170708
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673126480,
-      'tts': 170717
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 439}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 108,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 107,
-      'tid': 9,
-      'ts': 1122673126522,
-      'tts': 170759
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 47,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 46,
-      'tid': 9,
-      'ts': 1122673126569,
-      'tts': 170806
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 440}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673126606,
-      'tts': 170843
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2688952, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673126627,
-      'tts': 170864
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673126637,
-      'tts': 170874
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673126683,
-      'tts': 170920
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673126699,
-      'tts': 170936
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673126708,
-      'tts': 170944
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673141177,
-      'tts': 171002
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673141186,
-      'tts': 171010
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 440}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 110,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 109,
-      'tid': 9,
-      'ts': 1122673141212,
-      'tts': 171036
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 46,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 43,
-      'tid': 9,
-      'ts': 1122673141259,
-      'tts': 171084
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 441}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673141293,
-      'tts': 171117
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2688968, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673141318,
-      'tts': 171142
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673141329,
-      'tts': 171154
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673141379,
-      'tts': 171204
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673141406,
-      'tts': 171231
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673141421,
-      'tts': 171246
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673162929,
-      'tts': 171304
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673162938,
-      'tts': 171313
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 441}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122673162975,
-      'tts': 171350
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 41,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 39,
-      'tid': 9,
-      'ts': 1122673163020,
-      'tts': 171395
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 442}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673163051,
-      'tts': 171426
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2688984, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673163070,
-      'tts': 171445
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673163081,
-      'tts': 171455
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673163119,
-      'tts': 171493
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673163133,
-      'tts': 171508
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673163141,
-      'tts': 171516
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673179592,
-      'tts': 171569
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673179600,
-      'tts': 171576
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 442}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 77,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 76,
-      'tid': 9,
-      'ts': 1122673179625,
-      'tts': 171601
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 31,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 31,
-      'tid': 9,
-      'ts': 1122673179660,
-      'tts': 171635
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 443}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673179683,
-      'tts': 171659
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689000, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673179699,
-      'tts': 171675
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673179707,
-      'tts': 171682
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673179736,
-      'tts': 171711
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673179751,
-      'tts': 171727
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673179759,
-      'tts': 171735
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673196258,
-      'tts': 171788
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673196265,
-      'tts': 171794
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 443}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 73,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 72,
-      'tid': 9,
-      'ts': 1122673196291,
-      'tts': 171820
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 30,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 29,
-      'tid': 9,
-      'ts': 1122673196323,
-      'tts': 171852
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 444}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673196346,
-      'tts': 171875
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689016, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673196361,
-      'tts': 171890
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673196370,
-      'tts': 171899
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673196402,
-      'tts': 171931
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673196417,
-      'tts': 171946
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673196425,
-      'tts': 171954
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673213043,
-      'tts': 172016
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673107747,
-      'tts': 77989
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673107777,
-      'tts': 78018
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673126358,
-      'tts': 78708
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673126413,
-      'tts': 78760
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673141111,
-      'tts': 78880
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673141133,
-      'tts': 78902
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673162867,
-      'tts': 79126
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673162886,
-      'tts': 79145
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673179534,
-      'tts': 79253
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122673179551,
-      'tts': 79269
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673313423,
-      'tts': 174171
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673313452,
-      'tts': 174200
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673313467,
-      'tts': 174215
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673329958,
-      'tts': 174302
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673329971,
-      'tts': 174314
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 451}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122673330000,
-      'tts': 174343
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 41,
-      'tid': 9,
-      'ts': 1122673330035,
-      'tts': 174379
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 452}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673330066,
-      'tts': 174409
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689144, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673330092,
-      'tts': 174435
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673330106,
-      'tts': 174450
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673330151,
-      'tts': 174495
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673330180,
-      'tts': 174523
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673330194,
-      'tts': 174538
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673346680,
-      'tts': 174624
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673346692,
-      'tts': 174635
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 452}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122673346721,
-      'tts': 174664
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 43,
-      'tid': 9,
-      'ts': 1122673346756,
-      'tts': 174699
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 453}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673346787,
-      'tts': 174730
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689160, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673346813,
-      'tts': 174756
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673346827,
-      'tts': 174770
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673346871,
-      'tts': 174814
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673346900,
-      'tts': 174843
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673346914,
-      'tts': 174857
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673363348,
-      'tts': 174943
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673363361,
-      'tts': 174954
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 453}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122673363390,
-      'tts': 174984
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673363425,
-      'tts': 175019
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 454}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673363456,
-      'tts': 175050
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689176, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673363482,
-      'tts': 175075
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673363496,
-      'tts': 175090
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673363540,
-      'tts': 175134
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673363569,
-      'tts': 175163
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673363584,
-      'tts': 175177
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673380043,
-      'tts': 175286
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673380057,
-      'tts': 175299
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 454}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 99,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122673380086,
-      'tts': 175328
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673380122,
-      'tts': 175364
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 455}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673380153,
-      'tts': 175396
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689192, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673380179,
-      'tts': 175421
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673380194,
-      'tts': 175436
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673380238,
-      'tts': 175480
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673380266,
-      'tts': 175508
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673380281,
-      'tts': 175523
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673396686,
-      'tts': 175611
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673396699,
-      'tts': 175622
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 455}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 99,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122673396735,
-      'tts': 175659
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673396771,
-      'tts': 175694
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 456}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673396802,
-      'tts': 175725
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689208, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673396828,
-      'tts': 175751
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673396842,
-      'tts': 175765
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673396886,
-      'tts': 175810
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673396915,
-      'tts': 175838
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673396930,
-      'tts': 175853
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673413345,
-      'tts': 175940
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673413358,
-      'tts': 175952
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674113927,
-      'tts': 89784
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674113950,
-      'tts': 89806
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674130606,
-      'tts': 89979
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674130629,
-      'tts': 90001
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674147273,
-      'tts': 90157
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674147296,
-      'tts': 90179
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674163929,
-      'tts': 90337
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674163951,
-      'tts': 90358
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673747387,
-      'tts': 182445
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 476}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 100,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122673747439,
-      'tts': 182498
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673747475,
-      'tts': 182534
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 477}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673747507,
-      'tts': 182565
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689544, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673747532,
-      'tts': 182591
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673747547,
-      'tts': 182605
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673747592,
-      'tts': 182650
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673747621,
-      'tts': 182680
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673747636,
-      'tts': 182694
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673764047,
-      'tts': 182781
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673764060,
-      'tts': 182792
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 477}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 99,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122673764089,
-      'tts': 182821
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673764125,
-      'tts': 182858
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 478}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673764156,
-      'tts': 182889
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689560, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673764182,
-      'tts': 182914
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673764196,
-      'tts': 182929
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673764241,
-      'tts': 182973
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673764268,
-      'tts': 183001
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673764283,
-      'tts': 183015
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673780702,
-      'tts': 183103
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673780715,
-      'tts': 183114
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 478}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 106,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 104,
-      'tid': 9,
-      'ts': 1122673780744,
-      'tts': 183143
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673780787,
-      'tts': 183186
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 479}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673780818,
-      'tts': 183217
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689576, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673780844,
-      'tts': 183243
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673780858,
-      'tts': 183257
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673780902,
-      'tts': 183302
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673780932,
-      'tts': 183331
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673780946,
-      'tts': 183346
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673797374,
-      'tts': 183434
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673797387,
-      'tts': 183445
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 479}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 106,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 104,
-      'tid': 9,
-      'ts': 1122673797416,
-      'tts': 183475
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673797458,
-      'tts': 183517
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 480}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673797489,
-      'tts': 183548
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689592, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673797516,
-      'tts': 183575
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673797530,
-      'tts': 183589
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673797575,
-      'tts': 183633
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673797604,
-      'tts': 183662
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673797618,
-      'tts': 183677
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673814044,
-      'tts': 183764
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673814056,
-      'tts': 183776
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 480}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122673814086,
-      'tts': 183805
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 43,
-      'tid': 9,
-      'ts': 1122673814121,
-      'tts': 183840
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 481}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673814153,
-      'tts': 183872
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689608, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673814178,
-      'tts': 183897
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673814193,
-      'tts': 183912
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673814237,
-      'tts': 183956
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673814265,
-      'tts': 183985
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673814280,
-      'tts': 183999
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673830696,
-      'tts': 184086
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673830709,
-      'tts': 184097
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 481}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 99,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122673830738,
-      'tts': 184126
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122673830774,
-      'tts': 184163
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 482}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673830806,
-      'tts': 184194
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689624, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673830831,
-      'tts': 184219
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673830846,
-      'tts': 184234
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673830890,
-      'tts': 184278
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673830917,
-      'tts': 184305
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673830932,
-      'tts': 184320
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122673847325,
-      'tts': 184405
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122673847337,
-      'tts': 184417
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674030729,
-      'tts': 188070
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 493}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122674030758,
-      'tts': 188099
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674030794,
-      'tts': 188135
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 494}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674030825,
-      'tts': 188166
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689816, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674030850,
-      'tts': 188191
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674030864,
-      'tts': 188205
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674030908,
-      'tts': 188249
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674030937,
-      'tts': 188278
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674030951,
-      'tts': 188292
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674047345,
-      'tts': 188381
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674047358,
-      'tts': 188393
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 494}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122674047387,
-      'tts': 188422
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 43,
-      'tid': 9,
-      'ts': 1122674047422,
-      'tts': 188457
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 495}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674047453,
-      'tts': 188489
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689832, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674047479,
-      'tts': 188514
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674047493,
-      'tts': 188528
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674047538,
-      'tts': 188573
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674047566,
-      'tts': 188601
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674047580,
-      'tts': 188615
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674064041,
-      'tts': 188723
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674064054,
-      'tts': 188735
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 495}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 114,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 112,
-      'tid': 9,
-      'ts': 1122674064084,
-      'tts': 188765
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 60,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 57,
-      'tid': 9,
-      'ts': 1122674064120,
-      'tts': 188801
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 496}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674064166,
-      'tts': 188847
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689848, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674064192,
-      'tts': 188873
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674064207,
-      'tts': 188888
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674064252,
-      'tts': 188933
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674064279,
-      'tts': 188960
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674064293,
-      'tts': 188974
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674080701,
-      'tts': 189063
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674080714,
-      'tts': 189075
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 496}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 112,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 110,
-      'tid': 9,
-      'ts': 1122674080743,
-      'tts': 189104
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 46,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 44,
-      'tid': 9,
-      'ts': 1122674080791,
-      'tts': 189152
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 497}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674080823,
-      'tts': 189185
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689864, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674080849,
-      'tts': 189210
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674080864,
-      'tts': 189225
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674080908,
-      'tts': 189269
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674080936,
-      'tts': 189297
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674080950,
-      'tts': 189312
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674097365,
-      'tts': 189401
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674097378,
-      'tts': 189412
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 497}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 97,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122674097407,
-      'tts': 189441
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 43,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674097443,
-      'tts': 189477
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 498}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674097473,
-      'tts': 189507
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689880, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674097498,
-      'tts': 189532
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674097513,
-      'tts': 189547
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674097556,
-      'tts': 189591
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674097585,
-      'tts': 189619
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674097599,
-      'tts': 189634
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674114019,
-      'tts': 189724
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674114032,
-      'tts': 189735
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 498}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 97,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122674114061,
-      'tts': 189765
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674114096,
-      'tts': 189800
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 499}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674114127,
-      'tts': 189830
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689896, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674114153,
-      'tts': 189856
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674114167,
-      'tts': 189870
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674114211,
-      'tts': 189914
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674114239,
-      'tts': 189942
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674114253,
-      'tts': 189957
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674130694,
-      'tts': 190042
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674130707,
-      'tts': 190054
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 499}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122674130736,
-      'tts': 190084
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674130772,
-      'tts': 190119
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 500}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674130802,
-      'tts': 190150
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689912, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674130828,
-      'tts': 190175
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674130842,
-      'tts': 190189
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674130887,
-      'tts': 190234
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674130914,
-      'tts': 190262
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674130929,
-      'tts': 190276
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674147364,
-      'tts': 190365
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674147377,
-      'tts': 190376
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 500}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 111,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 109,
-      'tid': 9,
-      'ts': 1122674147406,
-      'tts': 190406
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 47,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 44,
-      'tid': 9,
-      'ts': 1122674147452,
-      'tts': 190453
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 501}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674147486,
-      'tts': 190486
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689928, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674147511,
-      'tts': 190511
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674147526,
-      'tts': 190526
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674147570,
-      'tts': 190570
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674147598,
-      'tts': 190598
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674147613,
-      'tts': 190613
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674164055,
-      'tts': 190720
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674164068,
-      'tts': 190732
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 501}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 113,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 111,
-      'tid': 9,
-      'ts': 1122674164097,
-      'tts': 190761
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 46,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 44,
-      'tid': 9,
-      'ts': 1122674164146,
-      'tts': 190810
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 502}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674164178,
-      'tts': 190842
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689944, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674164204,
-      'tts': 190868
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674164219,
-      'tts': 190883
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674164263,
-      'tts': 190927
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674164312,
-      'tts': 190976
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674164327,
-      'tts': 190991
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674180694,
-      'tts': 191071
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674180707,
-      'tts': 191083
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 502}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 111,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 109,
-      'tid': 9,
-      'ts': 1122674180736,
-      'tts': 191112
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 46,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 43,
-      'tid': 9,
-      'ts': 1122674180783,
-      'tts': 191160
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 503}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674180816,
-      'tts': 191192
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689960, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674180841,
-      'tts': 191217
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674180855,
-      'tts': 191232
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674180899,
-      'tts': 191276
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674180928,
-      'tts': 191305
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674180943,
-      'tts': 191319
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674197354,
-      'tts': 191407
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674197367,
-      'tts': 191418
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 503}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 96,
-      'tid': 9,
-      'ts': 1122674197396,
-      'tts': 191447
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674197431,
-      'tts': 191483
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 504}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674197462,
-      'tts': 191514
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689976, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674197487,
-      'tts': 191539
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674197502,
-      'tts': 191553
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674197546,
-      'tts': 191598
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674197590,
-      'tts': 191642
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674197606,
-      'tts': 191657
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674214025,
-      'tts': 191747
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674214038,
-      'tts': 191759
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 504}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 111,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 110,
-      'tid': 9,
-      'ts': 1122674214067,
-      'tts': 191788
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 43,
-      'tid': 9,
-      'ts': 1122674214115,
-      'tts': 191836
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 505}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674214147,
-      'tts': 191868
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2689992, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674214173,
-      'tts': 191894
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674214187,
-      'tts': 191908
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674214232,
-      'tts': 191953
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674214259,
-      'tts': 191981
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674214274,
-      'tts': 191995
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674230673,
-      'tts': 192083
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674230686,
-      'tts': 192095
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 505}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 125,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 123,
-      'tid': 9,
-      'ts': 1122674230716,
-      'tts': 192124
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 48,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 46,
-      'tid': 9,
-      'ts': 1122674230775,
-      'tts': 192183
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 506}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674230809,
-      'tts': 192217
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2690008, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674230835,
-      'tts': 192243
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674230849,
-      'tts': 192258
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674230894,
-      'tts': 192303
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674230924,
-      'tts': 192332
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674230938,
-      'tts': 192347
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674247362,
-      'tts': 192436
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674247374,
-      'tts': 192447
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 506}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 97,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122674247403,
-      'tts': 192476
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 43,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 41,
-      'tid': 9,
-      'ts': 1122674247439,
-      'tts': 192512
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 507}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674247469,
-      'tts': 192543
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2690024, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674247494,
-      'tts': 192567
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674247509,
-      'tts': 192582
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674247553,
-      'tts': 192626
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674247581,
-      'tts': 192655
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674247596,
-      'tts': 192669
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674264048,
-      'tts': 192774
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674264062,
-      'tts': 192786
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 507}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 99,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122674264091,
-      'tts': 192815
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 45,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674264127,
-      'tts': 192851
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 508}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674264158,
-      'tts': 192883
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2690040, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674264184,
-      'tts': 192908
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674264199,
-      'tts': 192923
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674264243,
-      'tts': 192967
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674264272,
-      'tts': 192996
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674264286,
-      'tts': 193010
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674280687,
-      'tts': 193099
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674180599,
-      'tts': 90536
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674180634,
-      'tts': 90570
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674197265,
-      'tts': 90728
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674197288,
-      'tts': 90750
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674213934,
-      'tts': 90908
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674213956,
-      'tts': 90929
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674230583,
-      'tts': 91100
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674230606,
-      'tts': 91122
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674247271,
-      'tts': 91300
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674247293,
-      'tts': 91321
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674263915,
-      'tts': 91477
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674263938,
-      'tts': 91499
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674280596,
-      'tts': 91655
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674280619,
-      'tts': 91677
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674297261,
-      'tts': 91831
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674297287,
-      'tts': 91856
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674313908,
-      'tts': 92015
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674313930,
-      'tts': 92036
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674330601,
-      'tts': 92208
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674330623,
-      'tts': 92230
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674347259,
-      'tts': 92385
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674347281,
-      'tts': 92407
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674363933,
-      'tts': 92564
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674363956,
-      'tts': 92586
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674380587,
-      'tts': 92742
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674380610,
-      'tts': 92764
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674397245,
-      'tts': 92919
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674397268,
-      'tts': 92940
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674413915,
-      'tts': 93111
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674413938,
-      'tts': 93133
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674430594,
-      'tts': 93290
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674430617,
-      'tts': 93312
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674447250,
-      'tts': 93468
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674447273,
-      'tts': 93490
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674463925,
-      'tts': 93617
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674463948,
-      'tts': 93639
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674480599,
-      'tts': 93799
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674480621,
-      'tts': 93820
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674497252,
-      'tts': 93974
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674497275,
-      'tts': 93996
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674513924,
-      'tts': 94167
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674513946,
-      'tts': 94189
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674530585,
-      'tts': 94357
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674530607,
-      'tts': 94379
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674547254,
-      'tts': 94537
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674547276,
-      'tts': 94558
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'BeginFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674563916,
-      'tts': 94716
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline.frame',
-      'name': 'RequestMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 't',
-      'tid': 17,
-      'ts': 1122674563954,
-      'tts': 94753
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674514204,
-      'tts': 198558
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674514232,
-      'tts': 198586
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674514246,
-      'tts': 198600
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674530672,
-      'tts': 198686
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674530685,
-      'tts': 198697
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 523}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 97,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122674530714,
-      'tts': 198727
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 41,
-      'tid': 9,
-      'ts': 1122674530749,
-      'tts': 198762
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 524}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674530780,
-      'tts': 198792
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2693784, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674530805,
-      'tts': 198817
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674530820,
-      'tts': 198832
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674530864,
-      'tts': 198876
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674530892,
-      'tts': 198905
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674530907,
-      'tts': 198919
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674547345,
-      'tts': 199009
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674547358,
-      'tts': 199020
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 524}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 98,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 95,
-      'tid': 9,
-      'ts': 1122674547387,
-      'tts': 199050
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 41,
-      'tid': 9,
-      'ts': 1122674547423,
-      'tts': 199086
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 525}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674547454,
-      'tts': 199116
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2693800, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674547479,
-      'tts': 199141
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674547493,
-      'tts': 199156
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674547538,
-      'tts': 199200
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674547566,
-      'tts': 199229
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674547581,
-      'tts': 199243
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674564053,
-      'tts': 199343
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'BeginMainThreadFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674564066,
-      'tts': 199355
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 525}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 99,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 97,
-      'tid': 9,
-      'ts': 1122674564096,
-      'tts': 199384
-    },
-    {
-      'args': {
-        'data':
-            {'frame': '0x1100e70a8000', 'scriptId': '29', 'scriptLine': 2, 'scriptName': 'http://localhost/raf.html'}
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 44,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3834,
-      'tdur': 42,
-      'tid': 9,
-      'ts': 1122674564132,
-      'tts': 199420
-    },
-    {
-      'args': {'data': {'frame': '0x1100e70a8000', 'id': 526}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674564162,
-      'tts': 199451
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 0, 'jsHeapSizeUsed': 2693816, 'nodes': 7}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674564188,
-      'tts': 199477
-    },
-    {
-      'args': {'frame': '0x1100e70a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3834,
-      's': 'g',
-      'tid': 9,
-      'ts': 1122674564203,
-      'tts': 199492
-    },
-    {
-      'args': {'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'B',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674564248,
-      'tts': 199536
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'CompositeLayers',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674564276,
-      'tts': 199565
-    },
-    {
-      'args': {},
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Program',
-      'ph': 'E',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 1122674564291,
-      'tts': 199579
-    },
-    {
-      'args': {'number': 32},
-
-      'cat': '__metadata',
-      'name': 'num_cpus',
-      'ph': 'M',
-      'pid': 3834,
-      'tid': 0,
-      'ts': 0
-    },
-    {
-      'args': {'sort_index': -5},
-
-      'cat': '__metadata',
-      'name': 'process_sort_index',
-      'ph': 'M',
-      'pid': 3834,
-      'tid': 10,
-      'ts': 0
-    },
-    {
-      'args': {'name': 'Renderer'},
-
-      'cat': '__metadata',
-      'name': 'process_name',
-      'ph': 'M',
-      'pid': 3834,
-      'tid': 10,
-      'ts': 0
-    },
-    {
-      'args': {'sort_index': -1},
-
-      'cat': '__metadata',
-      'name': 'thread_sort_index',
-      'ph': 'M',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 0
-    },
-    {
-      'args': {'name': 'CrRendererMain'},
-
-      'cat': '__metadata',
-      'name': 'thread_name',
-      'ph': 'M',
-      'pid': 3834,
-      'tid': 9,
-      'ts': 0
-    },
-    {
-      'args': {'name': 'Compositor'},
-
-      'cat': '__metadata',
-      'name': 'thread_name',
-      'ph': 'M',
-      'pid': 3834,
-      'tid': 17,
-      'ts': 0
-    },
-    {
-      'args': {'elementCount': 47},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RecalculateStyles',
-      'ph': 'E',
-      'pid': 3872,
-      'tid': 26,
-      'ts': 1122673092850,
-      'tts': 827512
-    },
-    {
-      'args':
-          {'beginData': {'dirtyObjects': 44, 'frame': '0x176b9c2a8000', 'partialLayout': false, 'totalObjects': 261}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Layout',
-      'ph': 'B',
-      'pid': 3872,
-      'tid': 26,
-      'ts': 1122673092873,
-      'tts': 827535
-    },
-    {
-      'args': {'endData': {'root': [0, 0, 1570, 0, 1570, 1472, 0, 1472], 'rootNode': 2}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'Layout',
-      'ph': 'E',
-      'pid': 3872,
-      'tid': 26,
-      'ts': 1122673093523,
-      'tts': 828186
-    },
-    {
-      'args': {'data': {'frame': '0x176b9c2a8000', 'id': 12}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 1828,
-      'name': 'FireAnimationFrame',
-      'ph': 'X',
-      'pid': 3872,
-      'tdur': 1827,
-      'tid': 26,
-      'ts': 1122673093558,
-      'tts': 828220
-    },
-    {
-      'args': {
-        'data': {
-          'frame': '0x176b9c2a8000',
-          'scriptId': '65',
-          'scriptLine': 939,
-          'scriptName': 'chrome-devtools://devtools/bundled/ui/UIUtils.js'
-        }
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 1770,
-      'name': 'FunctionCall',
-      'ph': 'X',
-      'pid': 3872,
-      'tdur': 1770,
-      'tid': 26,
-      'ts': 1122673093604,
-      'tts': 828265
-    },
-    {
-      'args': {'frame': '0x176b9c2a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'ScheduleStyleRecalculation',
-      'ph': 'I',
-      'pid': 3872,
-      's': 'g',
-      'tid': 26,
-      'ts': 1122673094798,
-      'tts': 829461
-    },
-    {
-      'args': {'frame': '0x176b9c2a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RecalculateStyles',
-      'ph': 'B',
-      'pid': 3872,
-      'tid': 26,
-      'ts': 1122673094958,
-      'tts': 829620
-    },
-    {
-      'args': {'elementCount': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RecalculateStyles',
-      'ph': 'E',
-      'pid': 3872,
-      'tid': 26,
-      'ts': 1122673094989,
-      'tts': 829651
-    },
-    {
-      'args': {'data': {'frame': '0x176b9c2a8000', 'id': 13}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'RequestAnimationFrame',
-      'ph': 'I',
-      'pid': 3872,
-      's': 'g',
-      'tid': 26,
-      'ts': 1122673095367,
-      'tts': 830030
-    },
-    {
-      'args': {'data': {'documents': 1, 'jsEventListeners': 141, 'jsHeapSizeUsed': 15850696, 'nodes': 1705}},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateCounters',
-      'ph': 'I',
-      'pid': 3872,
-      's': 'g',
-      'tid': 26,
-      'ts': 1122673095384,
-      'tts': 830046
-    },
-    {
-      'args': {'frame': '0x176b9c2a8000'},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayerTree',
-      'ph': 'I',
-      'pid': 3872,
-      's': 'g',
-      'tid': 26,
-      'ts': 1122673095390,
-      'tts': 830052
-    },
-    {
-      'args': {'layerId': 11, 'layerTreeId': 1},
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'name': 'UpdateLayer',
-      'ph': 'B',
-      'pid': 3872,
-      'tid': 26,
-      'ts': 1122673095845,
-      'tts': 830507
-    },
-    {
-      'args': {
-        'data': {
-          'clip': [-15, -15, 1585, -15, 1585, 1487, -15, 1487],
-          'frame': '0x176b9c2a8000',
-          'layerId': 11,
-          'nodeId': 2
-        }
-      },
-
-      'cat': 'disabled-by-default-devtools.timeline',
-      'dur': 4637,
-      'name': 'Paint',
-      'ph': 'X',
-      'pid': 3872,
-      'tdur': 4630,
-      'tid': 26,
-      'ts': 1122673095897,
-      'tts': 830559
-    },
-    {
-      'args': {'name': 'Browser'},
-
-      'cat': '__metadata',
-      'name': 'process_name',
-      'ph': 'M',
-      'pid': 3778,
-      'tid': 3801,
-      'ts': 0
-    },
-    {
-      'args': {'name': 'CrBrowserMain'},
-
-      'cat': '__metadata',
-      'name': 'thread_name',
-      'ph': 'M',
-      'pid': 3778,
-      'tid': 3778,
-      'ts': 0
-    }
-  ]);
-};
diff --git a/front_end/performance_test_runner/TimelineTestRunner.js b/front_end/performance_test_runner/TimelineTestRunner.js
deleted file mode 100644
index ee79361..0000000
--- a/front_end/performance_test_runner/TimelineTestRunner.js
+++ /dev/null
@@ -1,406 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-PerformanceTestRunner.timelinePropertyFormatters = {
-  children: 'formatAsTypeName',
-  endTime: 'formatAsTypeName',
-  requestId: 'formatAsTypeName',
-  startTime: 'formatAsTypeName',
-  stackTrace: 'formatAsTypeName',
-  url: 'formatAsURL',
-  fileName: 'formatAsURL',
-  scriptName: 'formatAsTypeName',
-  scriptId: 'formatAsTypeName',
-  usedHeapSizeDelta: 'skip',
-  id: 'formatAsTypeName',
-  timerId: 'formatAsTypeName',
-  layerId: 'formatAsTypeName',
-  frameId: 'formatAsTypeName',
-  frame: 'formatAsTypeName',
-  page: 'formatAsTypeName',
-  encodedDataLength: 'formatAsTypeName',
-  identifier: 'formatAsTypeName',
-  clip: 'formatAsTypeName',
-  root: 'formatAsTypeName',
-  backendNodeId: 'formatAsTypeName',
-  nodeId: 'formatAsTypeName',
-  rootNode: 'formatAsTypeName',
-  finishTime: 'formatAsTypeName',
-  thread: 'formatAsTypeName',
-  allottedMilliseconds: 'formatAsTypeName',
-  timedOut: 'formatAsTypeName',
-  networkTime: 'formatAsTypeName',
-  timing: 'formatAsTypeName',
-  streamed: 'formatAsTypeName',
-  producedCacheSize: 'formatAsTypeName',
-  consumedCacheSize: 'formatAsTypeName'
-};
-
-PerformanceTestRunner.InvalidationFormatters = {
-  _tracingEvent: 'skip',
-  cause: 'formatAsInvalidationCause',
-  frame: 'skip',
-  invalidatedSelectorId: 'skip',
-  invalidationList: 'skip',
-  invalidationSet: 'skip',
-  linkedRecalcStyleEvent: 'skip',
-  linkedLayoutEvent: 'skip',
-  nodeId: 'skip',
-  paintId: 'skip',
-  startTime: 'skip'
-};
-
-TestRunner.formatters.formatAsInvalidationCause = function(cause) {
-  if (!cause)
-    return '<undefined>';
-
-  let stackTrace;
-
-  if (cause.stackTrace && cause.stackTrace.length) {
-    stackTrace =
-        TestRunner.formatters.formatAsURL(cause.stackTrace[0].url) + ':' + (cause.stackTrace[0].lineNumber + 1);
-  }
-
-  return '{reason: ' + cause.reason + ', stackTrace: ' + stackTrace + '}';
-};
-
-PerformanceTestRunner.createTracingModel = function(events) {
-  const model = new SDK.TracingModel(new Bindings.TempFileBackingStorage('tracing'));
-  model.addEvents(events);
-  model.tracingComplete();
-  return model;
-};
-
-PerformanceTestRunner.tracingModel = function() {
-  return UI.panels.timeline._performanceModel.tracingModel();
-};
-
-PerformanceTestRunner.invokeWithTracing = function(functionName, callback, additionalCategories, enableJSSampling) {
-  let categories =
-      '-*,disabled-by-default-devtools.timeline*,devtools.timeline,' + SDK.TracingModel.TopLevelEventCategory;
-
-  if (additionalCategories)
-    categories += ',' + additionalCategories;
-
-  const timelinePanel = UI.panels.timeline;
-  const timelineController = PerformanceTestRunner.createTimelineController();
-  timelinePanel._timelineController = timelineController;
-  timelineController._startRecordingWithCategories(categories, enableJSSampling).then(tracingStarted);
-
-  function tracingStarted() {
-    timelinePanel._recordingStarted();
-    TestRunner.callFunctionInPageAsync(functionName).then(onPageActionsDone);
-  }
-
-  function onPageActionsDone() {
-    PerformanceTestRunner.runWhenTimelineIsReady(callback);
-    timelineController.stopRecording();
-  }
-};
-
-PerformanceTestRunner.performanceModel = function() {
-  return UI.panels.timeline._performanceModel;
-};
-
-PerformanceTestRunner.timelineModel = function() {
-  return PerformanceTestRunner.performanceModel().timelineModel();
-};
-
-PerformanceTestRunner.timelineFrameModel = function() {
-  return PerformanceTestRunner.performanceModel().frameModel();
-};
-
-PerformanceTestRunner.createPerformanceModelWithEvents = function(events) {
-  const tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage('tracing'));
-  tracingModel.addEvents(events);
-  tracingModel.tracingComplete();
-  const performanceModel = new Timeline.PerformanceModel();
-  performanceModel.setTracingModel(tracingModel);
-  UI.panels.timeline._performanceModel = performanceModel;
-  return performanceModel;
-};
-
-PerformanceTestRunner.createTimelineController = function() {
-  const controller = new Timeline.TimelineController(SDK.targetManager.mainTarget(), UI.panels.timeline);
-  controller._tracingManager = TestRunner.tracingManager;
-  return controller;
-};
-
-PerformanceTestRunner.runWhenTimelineIsReady = function(callback) {
-  TestRunner.addSniffer(UI.panels.timeline, 'loadingComplete', () => callback());
-};
-
-PerformanceTestRunner.startTimeline = function() {
-  const panel = UI.panels.timeline;
-  panel._toggleRecording();
-  return TestRunner.addSnifferPromise(panel, '_recordingStarted');
-};
-
-PerformanceTestRunner.stopTimeline = function() {
-  return new Promise(resolve => {
-    PerformanceTestRunner.runWhenTimelineIsReady(resolve);
-    UI.panels.timeline._toggleRecording();
-  });
-};
-
-PerformanceTestRunner.evaluateWithTimeline = async function(actions) {
-  await PerformanceTestRunner.startTimeline();
-  await TestRunner.evaluateInPageAnonymously(actions);
-  await PerformanceTestRunner.stopTimeline();
-};
-
-PerformanceTestRunner.invokeAsyncWithTimeline = async function(functionName) {
-  await PerformanceTestRunner.startTimeline();
-  await TestRunner.callFunctionInPageAsync(functionName);
-  await PerformanceTestRunner.stopTimeline();
-};
-
-PerformanceTestRunner.performActionsAndPrint = async function(actions, typeName, includeTimeStamps) {
-  await PerformanceTestRunner.evaluateWithTimeline(actions);
-  PerformanceTestRunner.printTimelineRecordsWithDetails(typeName);
-  if (includeTimeStamps) {
-    TestRunner.addResult('Timestamp records: ');
-    PerformanceTestRunner.printTimestampRecords(typeName);
-  }
-  TestRunner.completeTest();
-};
-
-PerformanceTestRunner.printTimelineRecords = function(name) {
-  for (const event of PerformanceTestRunner.timelineModel().inspectedTargetEvents()) {
-    if (event.name === name)
-      PerformanceTestRunner.printTraceEventProperties(event);
-  }
-};
-
-PerformanceTestRunner.printTimelineRecordsWithDetails = function(name) {
-  for (const event of PerformanceTestRunner.timelineModel().inspectedTargetEvents()) {
-    if (name === event.name)
-      PerformanceTestRunner.printTraceEventPropertiesWithDetails(event);
-  }
-};
-
-PerformanceTestRunner.walkTimelineEventTree = function(callback) {
-  const view = new Timeline.EventsTimelineTreeView(UI.panels.timeline._filters, null);
-  view.setModel(PerformanceTestRunner.performanceModel(), PerformanceTestRunner.mainTrack());
-  const selection = Timeline.TimelineSelection.fromRange(
-      PerformanceTestRunner.timelineModel().minimumRecordTime(),
-      PerformanceTestRunner.timelineModel().maximumRecordTime());
-  view.updateContents(selection);
-  PerformanceTestRunner.walkTimelineEventTreeUnderNode(callback, view._currentTree, 0);
-};
-
-PerformanceTestRunner.walkTimelineEventTreeUnderNode = function(callback, root, level) {
-  const event = root.event;
-
-  if (event)
-    callback(event, level);
-
-  for (const child of root.children().values())
-    PerformanceTestRunner.walkTimelineEventTreeUnderNode(callback, child, (level || 0) + 1);
-};
-
-PerformanceTestRunner.printTimestampRecords = function(typeName) {
-  const dividers = PerformanceTestRunner.timelineModel().eventDividers();
-
-  for (const event of dividers) {
-    if (event.name === typeName)
-      PerformanceTestRunner.printTraceEventProperties(event);
-  }
-};
-
-PerformanceTestRunner.forAllEvents = function(events, callback) {
-  const eventStack = [];
-
-  for (const event of events) {
-    while (eventStack.length && eventStack.peekLast().endTime <= event.startTime)
-      eventStack.pop();
-
-    callback(event, eventStack);
-
-    if (event.endTime)
-      eventStack.push(event);
-  }
-};
-
-PerformanceTestRunner.printTraceEventProperties = function(traceEvent) {
-  TestRunner.addResult(traceEvent.name + ' Properties:');
-  const data = traceEvent.args['beginData'] || traceEvent.args['data'];
-  const frameId = data && data['frame'];
-
-  const object = {
-    data: traceEvent.args['data'] || traceEvent.args,
-    endTime: traceEvent.endTime || traceEvent.startTime,
-    frameId: frameId,
-    stackTrace: TimelineModel.TimelineData.forEvent(traceEvent).stackTrace,
-    startTime: traceEvent.startTime,
-    type: traceEvent.name
-  };
-
-  for (const field in object) {
-    if (object[field] === null || object[field] === undefined)
-      delete object[field];
-  }
-
-  TestRunner.addObject(object, PerformanceTestRunner.timelinePropertyFormatters);
-};
-
-PerformanceTestRunner.printTraceEventPropertiesWithDetails = function(event) {
-  PerformanceTestRunner.printTraceEventProperties(event);
-  const details = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(
-      event, SDK.targetManager.mainTarget(), new Components.Linkifier());
-  TestRunner.addResult(`Text details for ${event.name}: ${details}`);
-
-  if (TimelineModel.TimelineData.forEvent(event).warning)
-    TestRunner.addResult(`${event.name} has a warning`);
-};
-
-PerformanceTestRunner.mainTrack = function() {
-  let mainTrack;
-  for (const track of PerformanceTestRunner.timelineModel().tracks()) {
-    if (track.type === TimelineModel.TimelineModel.TrackType.MainThread && track.forMainFrame)
-      mainTrack = track;
-  }
-  return mainTrack;
-};
-
-PerformanceTestRunner.mainTrackEvents = function() {
-  return PerformanceTestRunner.mainTrack().events;
-};
-
-PerformanceTestRunner.findTimelineEvent = function(name, index) {
-  return PerformanceTestRunner.mainTrackEvents().filter(e => e.name === name)[index || 0];
-};
-
-PerformanceTestRunner.findChildEvent = function(events, parentIndex, name) {
-  const endTime = events[parentIndex].endTime;
-
-  for (let i = parentIndex + 1; i < events.length && (!events[i].endTime || events[i].endTime <= endTime); ++i) {
-    if (events[i].name === name)
-      return events[i];
-  }
-
-  return null;
-};
-
-PerformanceTestRunner.dumpFrame = function(frame) {
-  const fieldsToDump = [
-    'cpuTime', 'duration', 'startTime', 'endTime', 'id', 'mainThreadFrameId', 'timeByCategory', 'other', 'scripting',
-    'painting', 'rendering', 'committedFrom', 'idle'
-  ];
-
-  function formatFields(object) {
-    const result = {};
-
-    for (const key in object) {
-      if (fieldsToDump.indexOf(key) < 0)
-        continue;
-
-      let value = object[key];
-
-      if (typeof value === 'number')
-        value = Number(value.toFixed(7));
-      else if (typeof value === 'object' && value)
-        value = formatFields(value);
-
-      result[key] = value;
-    }
-
-    return result;
-  }
-
-  TestRunner.addObject(formatFields(frame));
-};
-
-PerformanceTestRunner.dumpInvalidations = function(recordType, index, comment) {
-  const event = PerformanceTestRunner.findTimelineEvent(recordType, index || 0);
-
-  TestRunner.addArray(
-      TimelineModel.InvalidationTracker.invalidationEventsFor(event), PerformanceTestRunner.InvalidationFormatters, '',
-      comment);
-};
-
-PerformanceTestRunner.dumpFlameChartProvider = function(provider, includeGroups) {
-  const includeGroupsSet = includeGroups && new Set(includeGroups);
-  const timelineData = provider.timelineData();
-  const stackDepth = provider.maxStackDepth();
-  const entriesByLevel = new Multimap();
-
-  for (let i = 0; i < timelineData.entryLevels.length; ++i)
-    entriesByLevel.set(timelineData.entryLevels[i], i);
-
-  for (let groupIndex = 0; groupIndex < timelineData.groups.length; ++groupIndex) {
-    const group = timelineData.groups[groupIndex];
-
-    if (includeGroupsSet && !includeGroupsSet.has(group.name))
-      continue;
-
-    const maxLevel =
-        (groupIndex + 1 < timelineData.groups.length ? timelineData.groups[groupIndex + 1].startLevel : stackDepth);
-    TestRunner.addResult(`Group: ${group.name}`);
-
-    for (let level = group.startLevel; level < maxLevel; ++level) {
-      TestRunner.addResult(`Level ${level - group.startLevel}`);
-      const entries = entriesByLevel.get(level);
-
-      for (const index of entries) {
-        const title = provider.entryTitle(index);
-        const color = provider.entryColor(index);
-        TestRunner.addResult(`${title} (${color})`);
-      }
-    }
-  }
-};
-
-PerformanceTestRunner.dumpTimelineFlameChart = function(includeGroups) {
-  const provider = UI.panels.timeline._flameChart._mainDataProvider;
-  TestRunner.addResult('Timeline Flame Chart');
-  PerformanceTestRunner.dumpFlameChartProvider(provider, includeGroups);
-};
-
-PerformanceTestRunner.loadTimeline = function(timelineData) {
-  const promise = new Promise(fulfill => PerformanceTestRunner.runWhenTimelineIsReady(fulfill));
-
-  UI.panels.timeline._loadFromFile(new Blob([timelineData], {type: 'text/plain'}));
-
-  return promise;
-};
-
-TestRunner.deprecatedInitAsync(`
-  function wrapCallFunctionForTimeline(f) {
-    let script = document.createElement('script');
-    script.textContent = '(' + f.toString() + ')()\\n//# sourceURL=wrapCallFunctionForTimeline.js';
-    document.body.appendChild(script);
-  }
-
-  function generateFrames(count) {
-    let promise = Promise.resolve();
-
-    for (let i = count; i > 0; --i)
-      promise = promise.then(changeBackgroundAndWaitForFrame.bind(null, i));
-
-    return promise;
-
-    function changeBackgroundAndWaitForFrame(i) {
-      document.body.style.backgroundColor = (i & 1 ? 'rgb(200, 200, 200)' : 'rgb(240, 240, 240)');
-      return waitForFrame();
-    }
-  }
-
-  function waitForFrame() {
-    let callback;
-    let promise = new Promise(fulfill => callback = fulfill);
-
-    if (window.testRunner)
-      testRunner.capturePixelsAsyncThen(callback);
-    else
-      window.requestAnimationFrame(callback);
-
-    return promise;
-  }
-`);
diff --git a/front_end/performance_test_runner/module.json b/front_end/performance_test_runner/module.json
deleted file mode 100644
index 1dc81fd..0000000
--- a/front_end/performance_test_runner/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "timeline_model",
-    "timeline"
-  ],
-  "scripts": [
-    "TimelineTestRunner.js",
-    "TimelineDataTestRunner.js"
-  ],
-  "skip_compilation": [
-    "TimelineTestRunner.js",
-    "TimelineDataTestRunner.js"
-  ]
-}
diff --git a/front_end/persistence/Automapping.js b/front_end/persistence/Automapping.js
deleted file mode 100644
index ab71f33..0000000
--- a/front_end/persistence/Automapping.js
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Persistence.MappingSystem}
- * @unrestricted
- */
-Persistence.Automapping = class {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {function(!Persistence.AutomappingStatus)} onStatusAdded
-   * @param {function(!Persistence.AutomappingStatus)} onStatusRemoved
-   */
-  constructor(workspace, onStatusAdded, onStatusRemoved) {
-    this._workspace = workspace;
-
-    this._onStatusAdded = onStatusAdded;
-    this._onStatusRemoved = onStatusRemoved;
-    /** @type {!Set<!Persistence.AutomappingStatus>} */
-    this._statuses = new Set();
-
-    /** @type {!Map<string, !Workspace.UISourceCode>} */
-    this._fileSystemUISourceCodes = new Map();
-    this._sweepThrottler = new Common.Throttler(100);
-
-    const pathEncoder = new Persistence.PathEncoder();
-    this._filesIndex = new Persistence.Automapping.FilePathIndex(pathEncoder);
-    this._projectFoldersIndex = new Persistence.Automapping.FolderIndex(pathEncoder);
-    this._activeFoldersIndex = new Persistence.Automapping.FolderIndex(pathEncoder);
-
-    this._eventListeners = [
-      this._workspace.addEventListener(
-          Workspace.Workspace.Events.UISourceCodeAdded,
-          event => this._onUISourceCodeAdded(/** @type {!Workspace.UISourceCode} */ (event.data))),
-      this._workspace.addEventListener(
-          Workspace.Workspace.Events.UISourceCodeRemoved,
-          event => this._onUISourceCodeRemoved(/** @type {!Workspace.UISourceCode} */ (event.data))),
-      this._workspace.addEventListener(
-          Workspace.Workspace.Events.UISourceCodeRenamed, this._onUISourceCodeRenamed, this),
-      this._workspace.addEventListener(
-          Workspace.Workspace.Events.ProjectAdded,
-          event => this._onProjectAdded(/** @type {!Workspace.Project} */ (event.data)), this),
-      this._workspace.addEventListener(
-          Workspace.Workspace.Events.ProjectRemoved,
-          event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data)), this),
-    ];
-
-    for (const fileSystem of workspace.projects())
-      this._onProjectAdded(fileSystem);
-    for (const uiSourceCode of workspace.uiSourceCodes())
-      this._onUISourceCodeAdded(uiSourceCode);
-  }
-
-  _scheduleRemap() {
-    for (const status of this._statuses.valuesArray())
-      this._clearNetworkStatus(status.network);
-    this._scheduleSweep();
-  }
-
-  _scheduleSweep() {
-    this._sweepThrottler.schedule(sweepUnmapped.bind(this));
-
-    /**
-     * @this {Persistence.Automapping}
-     * @return {!Promise}
-     */
-    function sweepUnmapped() {
-      const networkProjects = this._workspace.projectsForType(Workspace.projectTypes.Network);
-      for (const networkProject of networkProjects) {
-        for (const uiSourceCode of networkProject.uiSourceCodes())
-          this._computeNetworkStatus(uiSourceCode);
-      }
-      this._onSweepHappenedForTest();
-      return Promise.resolve();
-    }
-  }
-
-  _onSweepHappenedForTest() {
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _onProjectRemoved(project) {
-    for (const uiSourceCode of project.uiSourceCodes())
-      this._onUISourceCodeRemoved(uiSourceCode);
-    if (project.type() !== Workspace.projectTypes.FileSystem)
-      return;
-    const fileSystem = /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (project);
-    for (const gitFolder of fileSystem.initialGitFolders())
-      this._projectFoldersIndex.removeFolder(gitFolder);
-    this._projectFoldersIndex.removeFolder(fileSystem.fileSystemPath());
-    this._scheduleRemap();
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _onProjectAdded(project) {
-    if (project.type() !== Workspace.projectTypes.FileSystem)
-      return;
-    const fileSystem = /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (project);
-    for (const gitFolder of fileSystem.initialGitFolders())
-      this._projectFoldersIndex.addFolder(gitFolder);
-    this._projectFoldersIndex.addFolder(fileSystem.fileSystemPath());
-    project.uiSourceCodes().forEach(this._onUISourceCodeAdded.bind(this));
-    this._scheduleRemap();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _onUISourceCodeAdded(uiSourceCode) {
-    const project = uiSourceCode.project();
-    if (project.type() === Workspace.projectTypes.FileSystem) {
-      // Never do bindings to filesystems that are typed to another client.
-      if (Persistence.FileSystemWorkspaceBinding.fileSystemType(project))
-        return;
-      this._filesIndex.addPath(uiSourceCode.url());
-      this._fileSystemUISourceCodes.set(uiSourceCode.url(), uiSourceCode);
-      this._scheduleSweep();
-    } else if (project.type() === Workspace.projectTypes.Network) {
-      this._computeNetworkStatus(uiSourceCode);
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _onUISourceCodeRemoved(uiSourceCode) {
-    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem) {
-      this._filesIndex.removePath(uiSourceCode.url());
-      this._fileSystemUISourceCodes.delete(uiSourceCode.url());
-      const status = uiSourceCode[Persistence.Automapping._status];
-      if (status)
-        this._clearNetworkStatus(status.network);
-    } else if (uiSourceCode.project().type() === Workspace.projectTypes.Network) {
-      this._clearNetworkStatus(uiSourceCode);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onUISourceCodeRenamed(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    const oldURL = /** @type {string} */ (event.data.oldURL);
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem)
-      return;
-
-    this._filesIndex.removePath(oldURL);
-    this._fileSystemUISourceCodes.delete(oldURL);
-    const status = uiSourceCode[Persistence.Automapping._status];
-    if (status)
-      this._clearNetworkStatus(status.network);
-
-    this._filesIndex.addPath(uiSourceCode.url());
-    this._fileSystemUISourceCodes.set(uiSourceCode.url(), uiSourceCode);
-    this._scheduleSweep();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} networkSourceCode
-   */
-  _computeNetworkStatus(networkSourceCode) {
-    if (networkSourceCode[Persistence.Automapping._processingPromise] ||
-        networkSourceCode[Persistence.Automapping._status])
-      return;
-    const createBindingPromise =
-        this._createBinding(networkSourceCode).then(validateStatus.bind(this)).then(onStatus.bind(this));
-    networkSourceCode[Persistence.Automapping._processingPromise] = createBindingPromise;
-
-    /**
-     * @param {?Persistence.AutomappingStatus} status
-     * @return {!Promise<?Persistence.AutomappingStatus>}
-     * @this {Persistence.Automapping}
-     */
-    async function validateStatus(status) {
-      if (!status)
-        return null;
-      if (status.network.contentType().isFromSourceMap() || !status.fileSystem.contentType().isTextType())
-        return status;
-
-      // At the time binding comes, there are multiple user scenarios:
-      // 1. Both network and fileSystem files are **not** dirty.
-      //    This is a typical scenario when user hasn't done any edits yet to the
-      //    files in question.
-      // 2. FileSystem file has unsaved changes, network is clear.
-      //    This typically happens with CSS files editing. Consider the following
-      //    scenario:
-      //      - user edits file that has been successfully mapped before
-      //      - user doesn't save the file
-      //      - user hits reload
-      // 3. Network file has either unsaved changes or commits, but fileSystem file is clear.
-      //    This typically happens when we've been editing file and then realized we'd like to drop
-      //    a folder and persist all the changes.
-      // 4. Network file has either unsaved changes or commits, and fileSystem file has unsaved changes.
-      //    We consider this to be un-realistic scenario and in this case just fail gracefully.
-      //
-      // To support usecase (3), we need to validate against original network content.
-      if (status.fileSystem.isDirty() && (status.network.isDirty() || status.network.hasCommits()))
-        return null;
-
-      const contents = await Promise.all([
-        status.fileSystem.requestContent(),
-        new Promise(x => status.network.project().requestFileContent(status.network, x))
-      ]);
-      const fileSystemContent = contents[0];
-      const networkContent = contents[1];
-      if (fileSystemContent === null || networkContent === null)
-        return null;
-
-      if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise)
-        return null;
-
-      const target = Bindings.NetworkProject.targetForUISourceCode(status.network);
-      let isValid = false;
-      if (target && target.isNodeJS()) {
-        const rewrappedNetworkContent =
-            Persistence.Persistence.rewrapNodeJSContent(status.fileSystem, fileSystemContent, networkContent);
-        isValid = fileSystemContent === rewrappedNetworkContent;
-      } else {
-        // Trim trailing whitespaces because V8 adds trailing newline.
-        isValid = fileSystemContent.trimRight() === networkContent.trimRight();
-      }
-      if (!isValid) {
-        this._prevalidationFailedForTest(status);
-        return null;
-      }
-      return status;
-    }
-
-    /**
-     * @param {?Persistence.AutomappingStatus} status
-     * @this {Persistence.Automapping}
-     */
-    function onStatus(status) {
-      if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise)
-        return;
-      networkSourceCode[Persistence.Automapping._processingPromise] = null;
-      if (!status || this._disposed) {
-        this._onBindingFailedForTest();
-        return;
-      }
-      // TODO(lushnikov): remove this check once there's a single uiSourceCode per url. @see crbug.com/670180
-      if (status.network[Persistence.Automapping._status] || status.fileSystem[Persistence.Automapping._status])
-        return;
-
-      this._statuses.add(status);
-      status.network[Persistence.Automapping._status] = status;
-      status.fileSystem[Persistence.Automapping._status] = status;
-      if (status.exactMatch) {
-        const projectFolder = this._projectFoldersIndex.closestParentFolder(status.fileSystem.url());
-        const newFolderAdded = projectFolder ? this._activeFoldersIndex.addFolder(projectFolder) : false;
-        if (newFolderAdded)
-          this._scheduleSweep();
-      }
-      this._onStatusAdded.call(null, status);
-    }
-  }
-
-  /**
-   * @param {!Persistence.AutomappingStatus} binding
-   */
-  _prevalidationFailedForTest(binding) {
-  }
-
-  _onBindingFailedForTest() {
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} networkSourceCode
-   */
-  _clearNetworkStatus(networkSourceCode) {
-    if (networkSourceCode[Persistence.Automapping._processingPromise]) {
-      networkSourceCode[Persistence.Automapping._processingPromise] = null;
-      return;
-    }
-    const status = networkSourceCode[Persistence.Automapping._status];
-    if (!status)
-      return;
-
-    this._statuses.delete(status);
-    status.network[Persistence.Automapping._status] = null;
-    status.fileSystem[Persistence.Automapping._status] = null;
-    if (status.exactMatch) {
-      const projectFolder = this._projectFoldersIndex.closestParentFolder(status.fileSystem.url());
-      if (projectFolder)
-        this._activeFoldersIndex.removeFolder(projectFolder);
-    }
-    this._onStatusRemoved.call(null, status);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} networkSourceCode
-   * @return {!Promise<?Persistence.AutomappingStatus>}
-   */
-  _createBinding(networkSourceCode) {
-    if (networkSourceCode.url().startsWith('file://')) {
-      const fileSourceCode = this._fileSystemUISourceCodes.get(networkSourceCode.url());
-      const status =
-          fileSourceCode ? new Persistence.AutomappingStatus(networkSourceCode, fileSourceCode, false) : null;
-      return Promise.resolve(status);
-    }
-
-    let networkPath = Common.ParsedURL.extractPath(networkSourceCode.url());
-    if (networkPath === null)
-      return Promise.resolve(/** @type {?Persistence.AutomappingStatus} */ (null));
-
-    if (networkPath.endsWith('/'))
-      networkPath += 'index.html';
-    const similarFiles =
-        this._filesIndex.similarFiles(networkPath).map(path => this._fileSystemUISourceCodes.get(path));
-    if (!similarFiles.length)
-      return Promise.resolve(/** @type {?Persistence.AutomappingStatus} */ (null));
-
-    return this._pullMetadatas(similarFiles.concat(networkSourceCode)).then(onMetadatas.bind(this));
-
-    /**
-     * @this {Persistence.Automapping}
-     */
-    function onMetadatas() {
-      const activeFiles = similarFiles.filter(file => !!this._activeFoldersIndex.closestParentFolder(file.url()));
-      const networkMetadata = networkSourceCode[Persistence.Automapping._metadata];
-      if (!networkMetadata || (!networkMetadata.modificationTime && typeof networkMetadata.contentSize !== 'number')) {
-        // If networkSourceCode does not have metadata, try to match against active folders.
-        if (activeFiles.length !== 1)
-          return null;
-        return new Persistence.AutomappingStatus(networkSourceCode, activeFiles[0], false);
-      }
-
-      // Try to find exact matches, prioritizing active folders.
-      let exactMatches = this._filterWithMetadata(activeFiles, networkMetadata);
-      if (!exactMatches.length)
-        exactMatches = this._filterWithMetadata(similarFiles, networkMetadata);
-      if (exactMatches.length !== 1)
-        return null;
-      return new Persistence.AutomappingStatus(networkSourceCode, exactMatches[0], true);
-    }
-  }
-
-  /**
-   * @param {!Array<!Workspace.UISourceCode>} uiSourceCodes
-   * @return {!Promise}
-   */
-  _pullMetadatas(uiSourceCodes) {
-    const promises = uiSourceCodes.map(file => fetchMetadata(file));
-    return Promise.all(promises);
-
-    /**
-     * @param {!Workspace.UISourceCode} file
-     * @return {!Promise}
-     */
-    function fetchMetadata(file) {
-      return file.requestMetadata().then(metadata => file[Persistence.Automapping._metadata] = metadata);
-    }
-  }
-
-  /**
-   * @param {!Array<!Workspace.UISourceCode>} files
-   * @param {!Workspace.UISourceCodeMetadata} networkMetadata
-   * @return {!Array<!Workspace.UISourceCode>}
-   */
-  _filterWithMetadata(files, networkMetadata) {
-    return files.filter(file => {
-      const fileMetadata = file[Persistence.Automapping._metadata];
-      if (!fileMetadata)
-        return false;
-      // Allow a second of difference due to network timestamps lack of precision.
-      const timeMatches = !networkMetadata.modificationTime ||
-          Math.abs(networkMetadata.modificationTime - fileMetadata.modificationTime) < 1000;
-      const contentMatches = !networkMetadata.contentSize || fileMetadata.contentSize === networkMetadata.contentSize;
-      return timeMatches && contentMatches;
-    });
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    if (this._disposed)
-      return;
-    this._disposed = true;
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    for (const status of this._statuses.valuesArray())
-      this._clearNetworkStatus(status.network);
-  }
-};
-
-Persistence.Automapping._status = Symbol('Automapping.Status');
-Persistence.Automapping._processingPromise = Symbol('Automapping.ProcessingPromise');
-Persistence.Automapping._metadata = Symbol('Automapping.Metadata');
-
-/**
- * @unrestricted
- */
-Persistence.Automapping.FilePathIndex = class {
-  /**
-   * @param {!Persistence.PathEncoder} encoder
-   */
-  constructor(encoder) {
-    this._encoder = encoder;
-    this._reversedIndex = new Common.Trie();
-  }
-
-  /**
-   * @param {string} path
-   */
-  addPath(path) {
-    const encodedPath = this._encoder.encode(path);
-    this._reversedIndex.add(encodedPath.reverse());
-  }
-
-  /**
-   * @param {string} path
-   */
-  removePath(path) {
-    const encodedPath = this._encoder.encode(path);
-    this._reversedIndex.remove(encodedPath.reverse());
-  }
-
-  /**
-   * @param {string} networkPath
-   * @return {!Array<string>}
-   */
-  similarFiles(networkPath) {
-    const encodedPath = this._encoder.encode(networkPath);
-    const longestCommonPrefix = this._reversedIndex.longestPrefix(encodedPath.reverse(), false);
-    if (!longestCommonPrefix)
-      return [];
-    return this._reversedIndex.words(longestCommonPrefix)
-        .map(encodedPath => this._encoder.decode(encodedPath.reverse()));
-  }
-};
-
-/**
- * @unrestricted
- */
-Persistence.Automapping.FolderIndex = class {
-  /**
-   * @param {!Persistence.PathEncoder} encoder
-   */
-  constructor(encoder) {
-    this._encoder = encoder;
-    this._index = new Common.Trie();
-    /** @type {!Map<string, number>} */
-    this._folderCount = new Map();
-  }
-
-  /**
-   * @param {string} path
-   * @return {boolean}
-   */
-  addFolder(path) {
-    if (path.endsWith('/'))
-      path = path.substring(0, path.length - 1);
-    const encodedPath = this._encoder.encode(path);
-    this._index.add(encodedPath);
-    const count = this._folderCount.get(encodedPath) || 0;
-    this._folderCount.set(encodedPath, count + 1);
-    return count === 0;
-  }
-
-  /**
-   * @param {string} path
-   * @return {boolean}
-   */
-  removeFolder(path) {
-    if (path.endsWith('/'))
-      path = path.substring(0, path.length - 1);
-    const encodedPath = this._encoder.encode(path);
-    const count = this._folderCount.get(encodedPath) || 0;
-    if (!count)
-      return false;
-    if (count > 1) {
-      this._folderCount.set(encodedPath, count - 1);
-      return false;
-    }
-    this._index.remove(encodedPath);
-    this._folderCount.delete(encodedPath);
-    return true;
-  }
-
-  /**
-   * @param {string} path
-   * @return {string}
-   */
-  closestParentFolder(path) {
-    const encodedPath = this._encoder.encode(path);
-    const commonPrefix = this._index.longestPrefix(encodedPath, true);
-    return this._encoder.decode(commonPrefix);
-  }
-};
-
-/**
- * @unrestricted
- */
-Persistence.AutomappingStatus = class {
-  /**
-   * @param {!Workspace.UISourceCode} network
-   * @param {!Workspace.UISourceCode} fileSystem
-   * @param {boolean} exactMatch
-   */
-  constructor(network, fileSystem, exactMatch) {
-    this.network = network;
-    this.fileSystem = fileSystem;
-    this.exactMatch = exactMatch;
-  }
-};
diff --git a/front_end/persistence/EditFileSystemView.js b/front_end/persistence/EditFileSystemView.js
deleted file mode 100644
index 420468b..0000000
--- a/front_end/persistence/EditFileSystemView.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ListWidget.Delegate}
- * @unrestricted
- */
-Persistence.EditFileSystemView = class extends UI.VBox {
-  /**
-   * @param {string} fileSystemPath
-   */
-  constructor(fileSystemPath) {
-    super(true);
-    this.registerRequiredCSS('persistence/editFileSystemView.css');
-    this._fileSystemPath = fileSystemPath;
-
-    this._eventListeners = [
-      Persistence.isolatedFileSystemManager.addEventListener(
-          Persistence.IsolatedFileSystemManager.Events.ExcludedFolderAdded, this._update, this),
-      Persistence.isolatedFileSystemManager.addEventListener(
-          Persistence.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, this._update, this)
-    ];
-
-    const excludedFoldersHeader = this.contentElement.createChild('div', 'file-system-header');
-    excludedFoldersHeader.createChild('div', 'file-system-header-text').textContent =
-        Common.UIString('Excluded folders');
-    excludedFoldersHeader.appendChild(
-        UI.createTextButton(Common.UIString('Add'), this._addExcludedFolderButtonClicked.bind(this), 'add-button'));
-    this._excludedFoldersList = new UI.ListWidget(this);
-    this._excludedFoldersList.element.classList.add('file-system-list');
-    this._excludedFoldersList.registerRequiredCSS('persistence/editFileSystemView.css');
-    const excludedFoldersPlaceholder = createElementWithClass('div', 'file-system-list-empty');
-    excludedFoldersPlaceholder.textContent = Common.UIString('None');
-    this._excludedFoldersList.setEmptyPlaceholder(excludedFoldersPlaceholder);
-    this._excludedFoldersList.show(this.contentElement);
-
-    this.contentElement.tabIndex = 0;
-    this._update();
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-  }
-
-  _update() {
-    if (this._muteUpdate)
-      return;
-
-    this._excludedFoldersList.clear();
-    this._excludedFolders = [];
-    for (const folder of Persistence.isolatedFileSystemManager.fileSystem(this._fileSystemPath)
-             .excludedFolders()
-             .values()) {
-      this._excludedFolders.push(folder);
-      this._excludedFoldersList.appendItem(folder, true);
-    }
-  }
-
-  _addExcludedFolderButtonClicked() {
-    this._excludedFoldersList.addNewItem(0, '');
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(item, editable) {
-    const element = createElementWithClass('div', 'file-system-list-item');
-    const pathPrefix = /** @type {string} */ (editable ? item : Common.UIString('%s (via .devtools)', item));
-    const pathPrefixElement = element.createChild('div', 'file-system-value');
-    pathPrefixElement.textContent = pathPrefix;
-    pathPrefixElement.title = pathPrefix;
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {number} index
-   */
-  removeItemRequested(item, index) {
-    Persistence.isolatedFileSystemManager.fileSystem(this._fileSystemPath)
-        .removeExcludedFolder(this._excludedFolders[index]);
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {
-    this._muteUpdate = true;
-    if (!isNew) {
-      Persistence.isolatedFileSystemManager.fileSystem(this._fileSystemPath)
-          .removeExcludedFolder(/** @type {string} */ (item));
-    }
-    Persistence.isolatedFileSystemManager.fileSystem(this._fileSystemPath)
-        .addExcludedFolder(this._normalizePrefix(editor.control('pathPrefix').value));
-    this._muteUpdate = false;
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(item) {
-    const editor = this._createExcludedFolderEditor();
-    editor.control('pathPrefix').value = item;
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor}
-   */
-  _createExcludedFolderEditor() {
-    if (this._excludedFolderEditor)
-      return this._excludedFolderEditor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._excludedFolderEditor = editor;
-    const content = editor.contentElement();
-
-    const titles = content.createChild('div', 'file-system-edit-row');
-    titles.createChild('div', 'file-system-value').textContent = Common.UIString('Folder path');
-
-    const fields = content.createChild('div', 'file-system-edit-row');
-    fields.createChild('div', 'file-system-value')
-        .appendChild(editor.createInput('pathPrefix', 'text', '/path/to/folder/', pathPrefixValidator.bind(this)));
-
-    return editor;
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     * @this {Persistence.EditFileSystemView}
-     */
-    function pathPrefixValidator(item, index, input) {
-      const prefix = this._normalizePrefix(input.value);
-      const configurableCount =
-          Persistence.isolatedFileSystemManager.fileSystem(this._fileSystemPath).excludedFolders().size;
-      for (let i = 0; i < configurableCount; ++i) {
-        if (i !== index && this._excludedFolders[i] === prefix)
-          return false;
-      }
-      return !!prefix;
-    }
-  }
-
-  /**
-   * @param {string} prefix
-   * @return {string}
-   */
-  _normalizePrefix(prefix) {
-    if (!prefix)
-      return '';
-    return prefix + (prefix[prefix.length - 1] === '/' ? '' : '/');
-  }
-};
diff --git a/front_end/persistence/FileSystemWorkspaceBinding.js b/front_end/persistence/FileSystemWorkspaceBinding.js
deleted file mode 100644
index a6c66ac..0000000
--- a/front_end/persistence/FileSystemWorkspaceBinding.js
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Persistence.FileSystemWorkspaceBinding = class {
-  /**
-   * @param {!Persistence.IsolatedFileSystemManager} isolatedFileSystemManager
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(isolatedFileSystemManager, workspace) {
-    this._isolatedFileSystemManager = isolatedFileSystemManager;
-    this._workspace = workspace;
-    this._eventListeners = [
-      this._isolatedFileSystemManager.addEventListener(
-          Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, this._onFileSystemAdded, this),
-      this._isolatedFileSystemManager.addEventListener(
-          Persistence.IsolatedFileSystemManager.Events.FileSystemRemoved, this._onFileSystemRemoved, this),
-      this._isolatedFileSystemManager.addEventListener(
-          Persistence.IsolatedFileSystemManager.Events.FileSystemFilesChanged, this._fileSystemFilesChanged, this)
-    ];
-    /** @type {!Map.<string, !Persistence.FileSystemWorkspaceBinding.FileSystem>} */
-    this._boundFileSystems = new Map();
-    this._isolatedFileSystemManager.waitForFileSystems().then(this._onFileSystemsLoaded.bind(this));
-  }
-
-  /**
-   * @param {string} fileSystemPath
-   * @return {string}
-   */
-  static projectId(fileSystemPath) {
-    return fileSystemPath;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array<string>}
-   */
-  static relativePath(uiSourceCode) {
-    const baseURL =
-        /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (uiSourceCode.project())._fileSystemBaseURL;
-    return uiSourceCode.url().substring(baseURL.length).split('/');
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @return {string}
-   */
-  static fileSystemType(project) {
-    const fileSystem =
-        /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (project)._fileSystem;
-    return fileSystem.type();
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {string} relativePath
-   * @return {string}
-   */
-  static completeURL(project, relativePath) {
-    const fsProject = /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (project);
-    return fsProject._fileSystemBaseURL + relativePath;
-  }
-
-  /**
-   * @param {string} extension
-   * @return {!Common.ResourceType}
-   */
-  static _contentTypeForExtension(extension) {
-    if (Persistence.FileSystemWorkspaceBinding._styleSheetExtensions.has(extension))
-      return Common.resourceTypes.Stylesheet;
-    if (Persistence.FileSystemWorkspaceBinding._documentExtensions.has(extension))
-      return Common.resourceTypes.Document;
-    if (Persistence.FileSystemWorkspaceBinding._imageExtensions.has(extension))
-      return Common.resourceTypes.Image;
-    if (Persistence.FileSystemWorkspaceBinding._scriptExtensions.has(extension))
-      return Common.resourceTypes.Script;
-    return Persistence.FileSystemWorkspaceBinding._binaryExtensions.has(extension) ? Common.resourceTypes.Other :
-                                                                                     Common.resourceTypes.Document;
-  }
-
-  /**
-   * @param {string} projectId
-   * @return {string}
-   */
-  static fileSystemPath(projectId) {
-    return projectId;
-  }
-
-  /**
-   * @return {!Persistence.IsolatedFileSystemManager}
-   */
-  fileSystemManager() {
-    return this._isolatedFileSystemManager;
-  }
-
-  /**
-   * @param {!Array<!Persistence.IsolatedFileSystem>} fileSystems
-   */
-  _onFileSystemsLoaded(fileSystems) {
-    for (const fileSystem of fileSystems)
-      this._addFileSystem(fileSystem);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFileSystemAdded(event) {
-    const fileSystem = /** @type {!Persistence.IsolatedFileSystem} */ (event.data);
-    this._addFileSystem(fileSystem);
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   */
-  _addFileSystem(fileSystem) {
-    const boundFileSystem = new Persistence.FileSystemWorkspaceBinding.FileSystem(this, fileSystem, this._workspace);
-    this._boundFileSystems.set(fileSystem.path(), boundFileSystem);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFileSystemRemoved(event) {
-    const fileSystem = /** @type {!Persistence.IsolatedFileSystem} */ (event.data);
-    const boundFileSystem = this._boundFileSystems.get(fileSystem.path());
-    boundFileSystem.dispose();
-    this._boundFileSystems.remove(fileSystem.path());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _fileSystemFilesChanged(event) {
-    const paths = /** @type {!Persistence.IsolatedFileSystemManager.FilesChangedData} */ (event.data);
-    for (const fileSystemPath of paths.changed.keysArray()) {
-      const fileSystem = this._boundFileSystems.get(fileSystemPath);
-      if (!fileSystem)
-        continue;
-      paths.changed.get(fileSystemPath).forEach(path => fileSystem._fileChanged(path));
-    }
-
-    for (const fileSystemPath of paths.added.keysArray()) {
-      const fileSystem = this._boundFileSystems.get(fileSystemPath);
-      if (!fileSystem)
-        continue;
-      paths.added.get(fileSystemPath).forEach(path => fileSystem._fileChanged(path));
-    }
-
-    for (const fileSystemPath of paths.removed.keysArray()) {
-      const fileSystem = this._boundFileSystems.get(fileSystemPath);
-      if (!fileSystem)
-        continue;
-      paths.removed.get(fileSystemPath).forEach(path => fileSystem.removeUISourceCode(path));
-    }
-  }
-
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    for (const fileSystem of this._boundFileSystems.values()) {
-      fileSystem.dispose();
-      this._boundFileSystems.remove(fileSystem._fileSystem.path());
-    }
-  }
-};
-
-Persistence.FileSystemWorkspaceBinding._styleSheetExtensions = new Set(['css', 'scss', 'sass', 'less']);
-Persistence.FileSystemWorkspaceBinding._documentExtensions = new Set(['htm', 'html', 'asp', 'aspx', 'phtml', 'jsp']);
-Persistence.FileSystemWorkspaceBinding._scriptExtensions = new Set([
-  'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js',
-  'jsp', 'jsx',  'h', 'm',  'mjs',  'mm',     'py',  'sh', 'ts',   'tsx',  'ls'
-]);
-
-Persistence.FileSystemWorkspaceBinding._imageExtensions = Persistence.IsolatedFileSystem.ImageExtensions;
-
-Persistence.FileSystemWorkspaceBinding._binaryExtensions = Persistence.IsolatedFileSystem.BinaryExtensions;
-
-/**
- * @implements {Workspace.Project}
- * @unrestricted
- */
-Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.ProjectStore {
-  /**
-   * @param {!Persistence.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
-   * @param {!Persistence.IsolatedFileSystem} isolatedFileSystem
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(fileSystemWorkspaceBinding, isolatedFileSystem, workspace) {
-    const fileSystemPath = isolatedFileSystem.path();
-    const id = Persistence.FileSystemWorkspaceBinding.projectId(fileSystemPath);
-    console.assert(!workspace.project(id));
-    const displayName = fileSystemPath.substr(fileSystemPath.lastIndexOf('/') + 1);
-
-    super(workspace, id, Workspace.projectTypes.FileSystem, displayName);
-
-    this._fileSystem = isolatedFileSystem;
-    this._fileSystemBaseURL = this._fileSystem.path() + '/';
-    this._fileSystemParentURL = this._fileSystemBaseURL.substr(0, fileSystemPath.lastIndexOf('/') + 1);
-    this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding;
-    this._fileSystemPath = fileSystemPath;
-    /** @type {!Set<string>} */
-    this._creatingFilesGuard = new Set();
-
-    workspace.addProject(this);
-    this.populate();
-  }
-
-  /**
-   * @return {string}
-   */
-  fileSystemPath() {
-    return this._fileSystemPath;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  mimeType(uiSourceCode) {
-    return Common.ResourceType.mimeFromURL(uiSourceCode.url()) || 'text/plain';
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  initialGitFolders() {
-    return this._fileSystem.initialGitFolders().map(folder => this._fileSystemPath + '/' + folder);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  _filePathForUISourceCode(uiSourceCode) {
-    return uiSourceCode.url().substring(this._fileSystemPath.length);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isServiceProject() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<?Workspace.UISourceCodeMetadata>}
-   */
-  requestMetadata(uiSourceCode) {
-    if (uiSourceCode[Persistence.FileSystemWorkspaceBinding._metadata])
-      return uiSourceCode[Persistence.FileSystemWorkspaceBinding._metadata];
-    const relativePath = this._filePathForUISourceCode(uiSourceCode);
-    const promise = this._fileSystem.getMetadata(relativePath).then(onMetadata);
-    uiSourceCode[Persistence.FileSystemWorkspaceBinding._metadata] = promise;
-    return promise;
-
-    /**
-     * @param {?{modificationTime: !Date, size: number}} metadata
-     * @return {?Workspace.UISourceCodeMetadata}
-     */
-    function onMetadata(metadata) {
-      if (!metadata)
-        return null;
-      return new Workspace.UISourceCodeMetadata(metadata.modificationTime, metadata.size);
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<?Blob>}
-   */
-  requestFileBlob(uiSourceCode) {
-    return this._fileSystem.requestFileBlob(this._filePathForUISourceCode(uiSourceCode));
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function(?string, boolean)} callback
-   */
-  requestFileContent(uiSourceCode, callback) {
-    const filePath = this._filePathForUISourceCode(uiSourceCode);
-    this._fileSystem.requestFileContent(filePath, callback);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canSetFileContent() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newContent
-   * @param {boolean} isBase64
-   * @param {function(?string)} callback
-   */
-  setFileContent(uiSourceCode, newContent, isBase64, callback) {
-    const filePath = this._filePathForUISourceCode(uiSourceCode);
-    this._fileSystem.setFileContent(filePath, newContent, isBase64, callback.bind(this, ''));
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  fullDisplayName(uiSourceCode) {
-    const baseURL =
-        /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (uiSourceCode.project())._fileSystemParentURL;
-    return uiSourceCode.url().substring(baseURL.length);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canRename() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newName
-   * @param {function(boolean, string=, string=, !Common.ResourceType=)} callback
-   */
-  rename(uiSourceCode, newName, callback) {
-    if (newName === uiSourceCode.name()) {
-      callback(true, uiSourceCode.name(), uiSourceCode.url(), uiSourceCode.contentType());
-      return;
-    }
-
-    let filePath = this._filePathForUISourceCode(uiSourceCode);
-    this._fileSystem.renameFile(filePath, newName, innerCallback.bind(this));
-
-    /**
-     * @param {boolean} success
-     * @param {string=} newName
-     * @this {Persistence.FileSystemWorkspaceBinding.FileSystem}
-     */
-    function innerCallback(success, newName) {
-      if (!success || !newName) {
-        callback(false, newName);
-        return;
-      }
-      console.assert(newName);
-      const slash = filePath.lastIndexOf('/');
-      const parentPath = filePath.substring(0, slash);
-      filePath = parentPath + '/' + newName;
-      filePath = filePath.substr(1);
-      const extension = this._extensionForPath(newName);
-      const newURL = this._fileSystemBaseURL + filePath;
-      const newContentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(extension);
-      this.renameUISourceCode(uiSourceCode, newName);
-      callback(true, newName, newURL, newContentType);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInFileContent(uiSourceCode, query, caseSensitive, isRegex) {
-    return new Promise(resolve => {
-      const filePath = this._filePathForUISourceCode(uiSourceCode);
-      this._fileSystem.requestFileContent(filePath, contentCallback);
-
-      /**
-       * @param {?string} content
-       */
-      function contentCallback(content) {
-        resolve(content ? Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex) : []);
-      }
-    });
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.ProjectSearchConfig} searchConfig
-   * @param {!Array.<string>} filesMathingFileQuery
-   * @param {!Common.Progress} progress
-   * @return {!Promise<!Array<string>>}
-   */
-  async findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, progress) {
-    let result = filesMathingFileQuery;
-    const queriesToRun = searchConfig.queries().slice();
-    if (!queriesToRun.length)
-      queriesToRun.push('');
-    progress.setTotalWork(queriesToRun.length);
-
-    for (const query of queriesToRun) {
-      const files = await this._fileSystem.searchInPath(searchConfig.isRegex() ? '' : query, progress);
-      result = result.intersectOrdered(files.sort(), String.naturalOrderComparator);
-      progress.worked(1);
-    }
-
-    progress.done();
-    return result;
-  }
-
-  /**
-   * @override
-   * @param {!Common.Progress} progress
-   */
-  indexContent(progress) {
-    this._fileSystem.indexContent(progress);
-  }
-
-  /**
-   * @param {string} path
-   * @return {string}
-   */
-  _extensionForPath(path) {
-    return Common.ParsedURL.extractExtension(path);
-  }
-
-  populate() {
-    const chunkSize = 1000;
-    const filePaths = this._fileSystem.initialFilePaths();
-    reportFileChunk.call(this, 0);
-
-    /**
-     * @param {number} from
-     * @this {Persistence.FileSystemWorkspaceBinding.FileSystem}
-     */
-    function reportFileChunk(from) {
-      const to = Math.min(from + chunkSize, filePaths.length);
-      for (let i = from; i < to; ++i)
-        this._addFile(filePaths[i]);
-      if (to < filePaths.length)
-        setTimeout(reportFileChunk.bind(this, to), 100);
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   */
-  excludeFolder(url) {
-    let relativeFolder = url.substring(this._fileSystemBaseURL.length);
-    if (!relativeFolder.startsWith('/'))
-      relativeFolder = '/' + relativeFolder;
-    if (!relativeFolder.endsWith('/'))
-      relativeFolder += '/';
-    this._fileSystem.addExcludedFolder(relativeFolder);
-
-    const uiSourceCodes = this.uiSourceCodes().slice();
-    for (let i = 0; i < uiSourceCodes.length; ++i) {
-      const uiSourceCode = uiSourceCodes[i];
-      if (uiSourceCode.url().startsWith(url))
-        this.removeUISourceCode(uiSourceCode.url());
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} path
-   * @return {boolean}
-   */
-  canExcludeFolder(path) {
-    return !!path && Persistence.FileSystemWorkspaceBinding.fileSystemType(this) !== 'overrides';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canCreateFile() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {string} path
-   * @param {?string} name
-   * @param {string} content
-   * @param {boolean=} isBase64
-   * @return {!Promise<?Workspace.UISourceCode>}
-   */
-  async createFile(path, name, content, isBase64) {
-    const guardFileName = this._fileSystemPath + path + (!path.endsWith('/') ? '/' : '') + name;
-    this._creatingFilesGuard.add(guardFileName);
-    const filePath = await this._fileSystem.createFile(path, name);
-    if (!filePath)
-      return null;
-    if (content)
-      await new Promise(resolve => this._fileSystem.setFileContent(filePath, content, isBase64 || false, resolve));
-    this._creatingFilesGuard.delete(guardFileName);
-    return this._addFile(filePath);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  deleteFile(uiSourceCode) {
-    const relativePath = this._filePathForUISourceCode(uiSourceCode);
-    this._fileSystem.deleteFile(relativePath).then(success => {
-      if (success)
-        this.removeUISourceCode(uiSourceCode.url());
-    });
-  }
-
-  /**
-   * @override
-   */
-  remove() {
-    this._fileSystemWorkspaceBinding._isolatedFileSystemManager.removeFileSystem(this._fileSystem);
-  }
-
-  /**
-   * @param {string} filePath
-   * @return {!Workspace.UISourceCode}
-   */
-  _addFile(filePath) {
-    const extension = this._extensionForPath(filePath);
-    const contentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(extension);
-
-    const uiSourceCode = this.createUISourceCode(this._fileSystemBaseURL + filePath, contentType);
-    this.addUISourceCode(uiSourceCode);
-    return uiSourceCode;
-  }
-
-  /**
-   * @param {string} path
-   */
-  _fileChanged(path) {
-    // Ignore files that are being created but do not have content yet.
-    if (this._creatingFilesGuard.has(path))
-      return;
-    const uiSourceCode = this.uiSourceCodeForURL(path);
-    if (!uiSourceCode) {
-      const contentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(this._extensionForPath(path));
-      this.addUISourceCode(this.createUISourceCode(path, contentType));
-      return;
-    }
-    uiSourceCode[Persistence.FileSystemWorkspaceBinding._metadata] = null;
-    uiSourceCode.checkContentUpdated();
-  }
-
-  dispose() {
-    this.removeProject();
-  }
-};
-
-Persistence.FileSystemWorkspaceBinding._metadata = Symbol('FileSystemWorkspaceBinding.Metadata');
diff --git a/front_end/persistence/IsolatedFileSystem.js b/front_end/persistence/IsolatedFileSystem.js
deleted file mode 100644
index c9f1110..0000000
--- a/front_end/persistence/IsolatedFileSystem.js
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Persistence.IsolatedFileSystem = class {
-  /**
-   * @param {!Persistence.IsolatedFileSystemManager} manager
-   * @param {string} path
-   * @param {string} embedderPath
-   * @param {!DOMFileSystem} domFileSystem
-   * @param {string} type
-   */
-  constructor(manager, path, embedderPath, domFileSystem, type) {
-    this._manager = manager;
-    this._path = path;
-    this._embedderPath = embedderPath;
-    this._domFileSystem = domFileSystem;
-    this._type = type;
-    this._excludedFoldersSetting = Common.settings.createLocalSetting('workspaceExcludedFolders', {});
-    /** @type {!Set<string>} */
-    this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] || []);
-    /** @type {!Array<string>} */
-    this._excludedEmbedderFolders = [];
-
-    /** @type {!Set<string>} */
-    this._initialFilePaths = new Set();
-    /** @type {!Set<string>} */
-    this._initialGitFolders = new Set();
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystemManager} manager
-   * @param {string} path
-   * @param {string} embedderPath
-   * @param {string} type
-   * @param {string} name
-   * @param {string} rootURL
-   * @return {!Promise<?Persistence.IsolatedFileSystem>}
-   */
-  static create(manager, path, embedderPath, type, name, rootURL) {
-    const domFileSystem = InspectorFrontendHost.isolatedFileSystem(name, rootURL);
-    if (!domFileSystem)
-      return Promise.resolve(/** @type {?Persistence.IsolatedFileSystem} */ (null));
-
-    const fileSystem = new Persistence.IsolatedFileSystem(manager, path, embedderPath, domFileSystem, type);
-    return fileSystem._initializeFilePaths()
-        .then(() => fileSystem)
-        .catchException(/** @type {?Persistence.IsolatedFileSystem} */ (null));
-  }
-
-  /**
-   * @param {!DOMError} error
-   * @return {string}
-   */
-  static errorMessage(error) {
-    return Common.UIString('File system error: %s', error.message);
-  }
-
-  /**
-   * @param {string} path
-   * @return {!Promise<?{modificationTime: !Date, size: number}>}
-   */
-  getMetadata(path) {
-    let fulfill;
-    const promise = new Promise(f => fulfill = f);
-    this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded, errorHandler);
-    return promise;
-
-    /**
-     * @param {!FileEntry} entry
-     */
-    function fileEntryLoaded(entry) {
-      entry.getMetadata(fulfill, errorHandler);
-    }
-
-    /**
-     * @param {!FileError} error
-     */
-    function errorHandler(error) {
-      const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-      console.error(errorMessage + ' when getting file metadata \'' + path);
-      fulfill(null);
-    }
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  initialFilePaths() {
-    return this._initialFilePaths.valuesArray();
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  initialGitFolders() {
-    return this._initialGitFolders.valuesArray();
-  }
-
-  /**
-   * @return {string}
-   */
-  path() {
-    return this._path;
-  }
-
-  /**
-   * @return {string}
-   */
-  embedderPath() {
-    return this._embedderPath;
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _initializeFilePaths() {
-    let fulfill;
-    const promise = new Promise(x => fulfill = x);
-    let pendingRequests = 1;
-    const boundInnerCallback = innerCallback.bind(this);
-    this._requestEntries('', boundInnerCallback);
-    return promise;
-
-    /**
-     * @param {!Array.<!FileEntry>} entries
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function innerCallback(entries) {
-      for (let i = 0; i < entries.length; ++i) {
-        const entry = entries[i];
-        if (!entry.isDirectory) {
-          if (this.isFileExcluded(entry.fullPath))
-            continue;
-          this._initialFilePaths.add(entry.fullPath.substr(1));
-        } else {
-          if (entry.fullPath.endsWith('/.git')) {
-            const lastSlash = entry.fullPath.lastIndexOf('/');
-            const parentFolder = entry.fullPath.substring(1, lastSlash);
-            this._initialGitFolders.add(parentFolder);
-          }
-          if (this.isFileExcluded(entry.fullPath + '/')) {
-            this._excludedEmbedderFolders.push(
-                Common.ParsedURL.urlToPlatformPath(this._path + entry.fullPath, Host.isWin()));
-            continue;
-          }
-          ++pendingRequests;
-          this._requestEntries(entry.fullPath, boundInnerCallback);
-        }
-      }
-      if ((--pendingRequests === 0))
-        fulfill();
-    }
-  }
-
-  /**
-   * @param {string} folderPath
-   * @return {!Promise<?DirectoryEntry>}
-   */
-  async _createFoldersIfNotExist(folderPath) {
-    // Fast-path. If parent directory already exists we return it immidiatly.
-    let dirEntry = await new Promise(
-        resolve => this._domFileSystem.root.getDirectory(folderPath, undefined, resolve, () => resolve(null)));
-    if (dirEntry)
-      return dirEntry;
-    const paths = folderPath.split('/');
-    let activePath = '';
-    for (const path of paths) {
-      activePath = activePath + '/' + path;
-      dirEntry = await this._innerCreateFolderIfNeeded(activePath);
-      if (!dirEntry)
-        return null;
-    }
-    return dirEntry;
-  }
-
-  /**
-   * @param {string} path
-   * @return {!Promise<?DirectoryEntry>}
-   */
-  _innerCreateFolderIfNeeded(path) {
-    return new Promise(resolve => {
-      this._domFileSystem.root.getDirectory(path, {create: true}, dirEntry => resolve(dirEntry), error => {
-        const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-        console.error(errorMessage + ' trying to create directory \'' + path + '\'');
-        resolve(null);
-      });
-    });
-  }
-
-  /**
-   * @param {string} path
-   * @param {?string} name
-   * @return {!Promise<?string>}
-   */
-  async createFile(path, name) {
-    const dirEntry = await this._createFoldersIfNotExist(path);
-    if (!dirEntry)
-      return null;
-    const fileEntry = await createFileCandidate.call(this, name || 'NewFile');
-    if (!fileEntry)
-      return null;
-    return fileEntry.fullPath.substr(1);
-
-    /**
-     * @param {string} name
-     * @param {number=} newFileIndex
-     * @return {!Promise<?FileEntry>}
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function createFileCandidate(name, newFileIndex) {
-      return new Promise(resolve => {
-        const nameCandidate = name + (newFileIndex || '');
-        dirEntry.getFile(nameCandidate, {create: true, exclusive: true}, resolve, error => {
-          if (error.name === 'InvalidModificationError') {
-            resolve(createFileCandidate.call(this, name, (newFileIndex ? newFileIndex + 1 : 1)));
-            return;
-          }
-          const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-          console.error(
-              errorMessage + ' when testing if file exists \'' + (this._path + '/' + path + '/' + nameCandidate) +
-              '\'');
-          resolve(null);
-        });
-      });
-    }
-  }
-
-  /**
-   * @param {string} path
-   * @return {!Promise<boolean>}
-   */
-  deleteFile(path) {
-    let resolveCallback;
-    const promise = new Promise(resolve => resolveCallback = resolve);
-    this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
-    return promise;
-
-    /**
-     * @param {!FileEntry} fileEntry
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function fileEntryLoaded(fileEntry) {
-      fileEntry.remove(fileEntryRemoved, errorHandler.bind(this));
-    }
-
-    function fileEntryRemoved() {
-      resolveCallback(true);
-    }
-
-    /**
-     * @param {!FileError} error
-     * @this {Persistence.IsolatedFileSystem}
-     * @suppress {checkTypes}
-     * TODO(jsbell): Update externs replacing FileError with DOMException. https://crbug.com/496901
-     */
-    function errorHandler(error) {
-      const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-      console.error(errorMessage + ' when deleting file \'' + (this._path + '/' + path) + '\'');
-      resolveCallback(false);
-    }
-  }
-
-  /**
-   * @param {string} path
-   * @return {!Promise<?Blob>}
-   */
-  requestFileBlob(path) {
-    return new Promise(resolve => {
-      this._domFileSystem.root.getFile(path, undefined, entry => {
-        entry.file(resolve, errorHandler.bind(this));
-      }, errorHandler.bind(this));
-
-      /**
-       * @this {Persistence.IsolatedFileSystem}
-       */
-      function errorHandler(error) {
-        if (error.name === 'NotFoundError') {
-          resolve(null);
-          return;
-        }
-
-        const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-        console.error(errorMessage + ' when getting content for file \'' + (this._path + '/' + path) + '\'');
-        resolve(null);
-      }
-    });
-  }
-
-  /**
-   * @param {string} path
-   * @param {function(?string,boolean)} callback
-   */
-  async requestFileContent(path, callback) {
-    const blob = await this.requestFileBlob(path);
-    if (!blob)
-      return null;
-
-    const reader = new FileReader();
-    const extension = Common.ParsedURL.extractExtension(path);
-    const encoded = Persistence.IsolatedFileSystem.BinaryExtensions.has(extension);
-    reader.onloadend = content => {
-      if (reader.error) {
-        console.error('Can\'t read file: ' + path + ': ' + reader.error);
-        callback(null, false);
-        return;
-      }
-      let result;
-      try {
-        result = reader.result;
-      } catch (e) {
-        result = null;
-        console.error('Can\'t read file: ' + path + ': ' + e);
-      }
-      if (result === undefined || result === null) {
-        callback(null, false);
-        return;
-      }
-      callback(encoded ? btoa(result) : result, encoded);
-    };
-
-    if (encoded)
-      reader.readAsBinaryString(blob);
-    else
-      reader.readAsText(blob);
-  }
-
-  /**
-   * @param {string} path
-   * @param {string} content
-   * @param {boolean} isBase64
-   * @param {function()} callback
-   */
-  setFileContent(path, content, isBase64, callback) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.FileSavedInWorkspace);
-    this._domFileSystem.root.getFile(path, {create: true}, fileEntryLoaded.bind(this), errorHandler.bind(this));
-
-    /**
-     * @param {!FileEntry} entry
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function fileEntryLoaded(entry) {
-      entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(this));
-    }
-
-    /**
-     * @param {!FileWriter} fileWriter
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    async function fileWriterCreated(fileWriter) {
-      fileWriter.onerror = errorHandler.bind(this);
-      fileWriter.onwriteend = fileWritten;
-      let blob;
-      if (isBase64)
-        blob = await(await fetch(`data:application/octet-stream;base64,${content}`)).blob();
-      else
-        blob = new Blob([content], {type: 'text/plain'});
-      fileWriter.write(blob);
-
-      function fileWritten() {
-        fileWriter.onwriteend = callback;
-        fileWriter.truncate(blob.size);
-      }
-    }
-
-    /**
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function errorHandler(error) {
-      const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-      console.error(errorMessage + ' when setting content for file \'' + (this._path + '/' + path) + '\'');
-      callback();
-    }
-  }
-
-  /**
-   * @param {string} path
-   * @param {string} newName
-   * @param {function(boolean, string=)} callback
-   */
-  renameFile(path, newName, callback) {
-    newName = newName ? newName.trim() : newName;
-    if (!newName || newName.indexOf('/') !== -1) {
-      callback(false);
-      return;
-    }
-    let fileEntry;
-    let dirEntry;
-
-    this._domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
-
-    /**
-     * @param {!FileEntry} entry
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function fileEntryLoaded(entry) {
-      if (entry.name === newName) {
-        callback(false);
-        return;
-      }
-
-      fileEntry = entry;
-      fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(this));
-    }
-
-    /**
-     * @param {!Entry} entry
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function dirEntryLoaded(entry) {
-      dirEntry = entry;
-      dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoadErrorHandler.bind(this));
-    }
-
-    /**
-     * @param {!FileEntry} entry
-     */
-    function newFileEntryLoaded(entry) {
-      callback(false);
-    }
-
-    /**
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function newFileEntryLoadErrorHandler(error) {
-      if (error.name !== 'NotFoundError') {
-        callback(false);
-        return;
-      }
-      fileEntry.moveTo(dirEntry, newName, fileRenamed, errorHandler.bind(this));
-    }
-
-    /**
-     * @param {!FileEntry} entry
-     */
-    function fileRenamed(entry) {
-      callback(true, entry.name);
-    }
-
-    /**
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function errorHandler(error) {
-      const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-      console.error(errorMessage + ' when renaming file \'' + (this._path + '/' + path) + '\' to \'' + newName + '\'');
-      callback(false);
-    }
-  }
-
-  /**
-   * @param {!DirectoryEntry} dirEntry
-   * @param {function(!Array.<!FileEntry>)} callback
-   */
-  _readDirectory(dirEntry, callback) {
-    const dirReader = dirEntry.createReader();
-    let entries = [];
-
-    function innerCallback(results) {
-      if (!results.length) {
-        callback(entries.sort());
-      } else {
-        entries = entries.concat(toArray(results));
-        dirReader.readEntries(innerCallback, errorHandler);
-      }
-    }
-
-    function toArray(list) {
-      return Array.prototype.slice.call(list || [], 0);
-    }
-
-    dirReader.readEntries(innerCallback, errorHandler);
-
-    function errorHandler(error) {
-      const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-      console.error(errorMessage + ' when reading directory \'' + dirEntry.fullPath + '\'');
-      callback([]);
-    }
-  }
-
-  /**
-   * @param {string} path
-   * @param {function(!Array.<!FileEntry>)} callback
-   */
-  _requestEntries(path, callback) {
-    this._domFileSystem.root.getDirectory(path, undefined, innerCallback.bind(this), errorHandler);
-
-    /**
-     * @param {!DirectoryEntry} dirEntry
-     * @this {Persistence.IsolatedFileSystem}
-     */
-    function innerCallback(dirEntry) {
-      this._readDirectory(dirEntry, callback);
-    }
-
-    function errorHandler(error) {
-      const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
-      console.error(errorMessage + ' when requesting entry \'' + path + '\'');
-      callback([]);
-    }
-  }
-
-  _saveExcludedFolders() {
-    const settingValue = this._excludedFoldersSetting.get();
-    settingValue[this._path] = this._excludedFolders.valuesArray();
-    this._excludedFoldersSetting.set(settingValue);
-  }
-
-  /**
-   * @param {string} path
-   */
-  addExcludedFolder(path) {
-    this._excludedFolders.add(path);
-    this._saveExcludedFolders();
-    this._manager.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.ExcludedFolderAdded, path);
-  }
-
-  /**
-   * @param {string} path
-   */
-  removeExcludedFolder(path) {
-    this._excludedFolders.delete(path);
-    this._saveExcludedFolders();
-    this._manager.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, path);
-  }
-
-  fileSystemRemoved() {
-    const settingValue = this._excludedFoldersSetting.get();
-    delete settingValue[this._path];
-    this._excludedFoldersSetting.set(settingValue);
-  }
-
-  /**
-   * @param {string} folderPath
-   * @return {boolean}
-   */
-  isFileExcluded(folderPath) {
-    if (this._excludedFolders.has(folderPath))
-      return true;
-    const regex = this._manager.workspaceFolderExcludePatternSetting().asRegExp();
-    return !!(regex && regex.test(folderPath));
-  }
-
-  /**
-   * @return {!Set<string>}
-   */
-  excludedFolders() {
-    return this._excludedFolders;
-  }
-
-  /**
-   * @param {string} query
-   * @param {!Common.Progress} progress
-   * @return {!Promise<!Array<string>>}
-   */
-  searchInPath(query, progress) {
-    return new Promise(resolve => {
-      const requestId = this._manager.registerCallback(innerCallback);
-      InspectorFrontendHost.searchInPath(requestId, this._embedderPath, query);
-
-      /**
-       * @param {!Array<string>} files
-       */
-      function innerCallback(files) {
-        resolve(files.map(path => Common.ParsedURL.platformPathToURL(path)));
-        progress.worked(1);
-      }
-    });
-  }
-
-  /**
-   * @param {!Common.Progress} progress
-   */
-  indexContent(progress) {
-    progress.setTotalWork(1);
-    const requestId = this._manager.registerProgress(progress);
-    InspectorFrontendHost.indexPath(requestId, this._embedderPath, JSON.stringify(this._excludedEmbedderFolders));
-  }
-};
-
-Persistence.IsolatedFileSystem.ImageExtensions =
-    new Set(['jpeg', 'jpg', 'svg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', 'bmp']);
-
-Persistence.IsolatedFileSystem.BinaryExtensions = new Set([
-  // Executable extensions, roughly taken from https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
-  'cmd', 'com', 'exe',
-  // Archive extensions, roughly taken from https://en.wikipedia.org/wiki/List_of_archive_formats
-  'a', 'ar', 'iso', 'tar', 'bz2', 'gz', 'lz', 'lzma', 'z', '7z', 'apk', 'arc', 'cab', 'dmg', 'jar', 'pak', 'rar', 'zip',
-  // Audio file extensions, roughly taken from https://en.wikipedia.org/wiki/Audio_file_format#List_of_formats
-  '3gp', 'aac', 'aiff', 'flac', 'm4a', 'mmf', 'mp3', 'ogg', 'oga', 'raw', 'sln', 'wav', 'wma', 'webm',
-  // Video file extensions, roughly taken from https://en.wikipedia.org/wiki/Video_file_format
-  'mkv', 'flv', 'vob', 'ogv', 'gifv', 'avi', 'mov', 'qt', 'mp4', 'm4p', 'm4v', 'mpg', 'mpeg',
-  // Image file extensions
-  'jpeg', 'jpg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', 'bmp'
-]);
diff --git a/front_end/persistence/IsolatedFileSystemManager.js b/front_end/persistence/IsolatedFileSystemManager.js
deleted file mode 100644
index 4cc6233..0000000
--- a/front_end/persistence/IsolatedFileSystemManager.js
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Persistence.IsolatedFileSystemManager = class extends Common.Object {
-  constructor() {
-    super();
-
-    /** @type {!Map<string, !Persistence.IsolatedFileSystem>} */
-    this._fileSystems = new Map();
-    /** @type {!Map<number, function(!Array.<string>)>} */
-    this._callbacks = new Map();
-    /** @type {!Map<number, !Common.Progress>} */
-    this._progresses = new Map();
-
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.FileSystemRemoved, this._onFileSystemRemoved, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.FileSystemAdded, this._onFileSystemAdded, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, this._onFileSystemFilesChanged, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, this._onIndexingTotalWorkCalculated, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.IndexingWorked, this._onIndexingWorked, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.IndexingDone, this._onIndexingDone, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.SearchCompleted, this._onSearchCompleted, this);
-
-    this._initExcludePatterSetting();
-
-    /** @type {?function(?Persistence.IsolatedFileSystem)} */
-    this._fileSystemRequestResolve = null;
-    this._fileSystemsLoadedPromise = this._requestFileSystems();
-  }
-
-  /**
-   * @return {!Promise<!Array<!Persistence.IsolatedFileSystem>>}
-   */
-  _requestFileSystems() {
-    let fulfill;
-    const promise = new Promise(f => fulfill = f);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.FileSystemsLoaded, onFileSystemsLoaded, this);
-    InspectorFrontendHost.requestFileSystems();
-    return promise;
-
-    /**
-     * @param {!Common.Event} event
-     * @this {Persistence.IsolatedFileSystemManager}
-     */
-    function onFileSystemsLoaded(event) {
-      const fileSystems = /** @type {!Array.<!Persistence.IsolatedFileSystemManager.FileSystem>} */ (event.data);
-      const promises = [];
-      for (let i = 0; i < fileSystems.length; ++i)
-        promises.push(this._innerAddFileSystem(fileSystems[i], false));
-      Promise.all(promises).then(onFileSystemsAdded);
-    }
-
-    /**
-     * @param {!Array<?Persistence.IsolatedFileSystem>} fileSystems
-     */
-    function onFileSystemsAdded(fileSystems) {
-      fulfill(fileSystems.filter(fs => !!fs));
-    }
-  }
-
-  /**
-   * @param {string=} type
-   * @return {!Promise<?Persistence.IsolatedFileSystem>}
-   */
-  addFileSystem(type) {
-    return new Promise(resolve => {
-      this._fileSystemRequestResolve = resolve;
-      InspectorFrontendHost.addFileSystem(type || '');
-    });
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   */
-  removeFileSystem(fileSystem) {
-    InspectorFrontendHost.removeFileSystem(fileSystem.embedderPath());
-  }
-
-  /**
-   * @return {!Promise<!Array<!Persistence.IsolatedFileSystem>>}
-   */
-  waitForFileSystems() {
-    return this._fileSystemsLoadedPromise;
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystemManager.FileSystem} fileSystem
-   * @param {boolean} dispatchEvent
-   * @return {!Promise<?Persistence.IsolatedFileSystem>}
-   */
-  _innerAddFileSystem(fileSystem, dispatchEvent) {
-    const embedderPath = fileSystem.fileSystemPath;
-    const fileSystemURL = Common.ParsedURL.platformPathToURL(fileSystem.fileSystemPath);
-    const promise = Persistence.IsolatedFileSystem.create(
-        this, fileSystemURL, embedderPath, fileSystem.type, fileSystem.fileSystemName, fileSystem.rootURL);
-    return promise.then(storeFileSystem.bind(this));
-
-    /**
-     * @param {?Persistence.IsolatedFileSystem} fileSystem
-     * @this {Persistence.IsolatedFileSystemManager}
-     */
-    function storeFileSystem(fileSystem) {
-      if (!fileSystem)
-        return null;
-      this._fileSystems.set(fileSystemURL, fileSystem);
-      if (dispatchEvent)
-        this.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, fileSystem);
-      return fileSystem;
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  async _onFileSystemAdded(event) {
-    const errorMessage = /** @type {string} */ (event.data['errorMessage']);
-    let fileSystem = /** @type {?Persistence.IsolatedFileSystemManager.FileSystem} */ (event.data['fileSystem']);
-    if (errorMessage) {
-      Common.console.error(Common.UIString('Unable to add filesystem: %s', errorMessage));
-      if (!this._fileSystemRequestResolve)
-        return;
-      this._fileSystemRequestResolve.call(null, null);
-      this._fileSystemRequestResolve = null;
-    } else if (fileSystem) {
-      fileSystem = await this._innerAddFileSystem(fileSystem, true);
-      if (this._fileSystemRequestResolve) {
-        this._fileSystemRequestResolve.call(null, fileSystem);
-        this._fileSystemRequestResolve = null;
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFileSystemRemoved(event) {
-    const embedderPath = /** @type {string} */ (event.data);
-    const fileSystemPath = Common.ParsedURL.platformPathToURL(embedderPath);
-    const isolatedFileSystem = this._fileSystems.get(fileSystemPath);
-    if (!isolatedFileSystem)
-      return;
-    this._fileSystems.delete(fileSystemPath);
-    isolatedFileSystem.fileSystemRemoved();
-    this.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.FileSystemRemoved, isolatedFileSystem);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onFileSystemFilesChanged(event) {
-    const urlPaths = {
-      changed: groupFilePathsIntoFileSystemPaths.call(this, event.data.changed),
-      added: groupFilePathsIntoFileSystemPaths.call(this, event.data.added),
-      removed: groupFilePathsIntoFileSystemPaths.call(this, event.data.removed)
-    };
-
-    this.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.FileSystemFilesChanged, urlPaths);
-
-    /**
-     * @param {!Array<string>} embedderPaths
-     * @return {!Multimap<string, string>}
-     * @this {Persistence.IsolatedFileSystemManager}
-     */
-    function groupFilePathsIntoFileSystemPaths(embedderPaths) {
-      const paths = new Multimap();
-      for (const embedderPath of embedderPaths) {
-        const filePath = Common.ParsedURL.platformPathToURL(embedderPath);
-        for (const fileSystemPath of this._fileSystems.keys()) {
-          if (this._fileSystems.get(fileSystemPath).isFileExcluded(embedderPath))
-            continue;
-          const pathPrefix = fileSystemPath.endsWith('/') ? fileSystemPath : fileSystemPath + '/';
-          if (!filePath.startsWith(pathPrefix))
-            continue;
-          paths.set(fileSystemPath, filePath);
-        }
-      }
-      return paths;
-    }
-  }
-
-  /**
-   * @return {!Array<!Persistence.IsolatedFileSystem>}
-   */
-  fileSystems() {
-    return this._fileSystems.valuesArray();
-  }
-
-  /**
-   * @param {string} fileSystemPath
-   * @return {?Persistence.IsolatedFileSystem}
-   */
-  fileSystem(fileSystemPath) {
-    return this._fileSystems.get(fileSystemPath) || null;
-  }
-
-  _initExcludePatterSetting() {
-    const defaultCommonExcludedFolders = [
-      '/node_modules/', '/bower_components/', '/\\.devtools', '/\\.git/', '/\\.sass-cache/', '/\\.hg/', '/\\.idea/',
-      '/\\.svn/', '/\\.cache/', '/\\.project/'
-    ];
-    const defaultWinExcludedFolders = ['/Thumbs.db$', '/ehthumbs.db$', '/Desktop.ini$', '/\\$RECYCLE.BIN/'];
-    const defaultMacExcludedFolders = [
-      '/\\.DS_Store$', '/\\.Trashes$', '/\\.Spotlight-V100$', '/\\.AppleDouble$', '/\\.LSOverride$', '/Icon$',
-      '/\\._.*$'
-    ];
-    const defaultLinuxExcludedFolders = ['/.*~$'];
-    let defaultExcludedFolders = defaultCommonExcludedFolders;
-    if (Host.isWin())
-      defaultExcludedFolders = defaultExcludedFolders.concat(defaultWinExcludedFolders);
-    else if (Host.isMac())
-      defaultExcludedFolders = defaultExcludedFolders.concat(defaultMacExcludedFolders);
-    else
-      defaultExcludedFolders = defaultExcludedFolders.concat(defaultLinuxExcludedFolders);
-    const defaultExcludedFoldersPattern = defaultExcludedFolders.join('|');
-    this._workspaceFolderExcludePatternSetting = Common.settings.createRegExpSetting(
-        'workspaceFolderExcludePattern', defaultExcludedFoldersPattern, Host.isWin() ? 'i' : '');
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  workspaceFolderExcludePatternSetting() {
-    return this._workspaceFolderExcludePatternSetting;
-  }
-
-  /**
-   * @param {function(!Array.<string>)} callback
-   * @return {number}
-   */
-  registerCallback(callback) {
-    const requestId = ++Persistence.IsolatedFileSystemManager._lastRequestId;
-    this._callbacks.set(requestId, callback);
-    return requestId;
-  }
-
-  /**
-   * @param {!Common.Progress} progress
-   * @return {number}
-   */
-  registerProgress(progress) {
-    const requestId = ++Persistence.IsolatedFileSystemManager._lastRequestId;
-    this._progresses.set(requestId, progress);
-    return requestId;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onIndexingTotalWorkCalculated(event) {
-    const requestId = /** @type {number} */ (event.data['requestId']);
-    const totalWork = /** @type {number} */ (event.data['totalWork']);
-
-    const progress = this._progresses.get(requestId);
-    if (!progress)
-      return;
-    progress.setTotalWork(totalWork);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onIndexingWorked(event) {
-    const requestId = /** @type {number} */ (event.data['requestId']);
-    const worked = /** @type {number} */ (event.data['worked']);
-
-    const progress = this._progresses.get(requestId);
-    if (!progress)
-      return;
-    progress.worked(worked);
-    if (progress.isCanceled()) {
-      InspectorFrontendHost.stopIndexing(requestId);
-      this._onIndexingDone(event);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onIndexingDone(event) {
-    const requestId = /** @type {number} */ (event.data['requestId']);
-
-    const progress = this._progresses.get(requestId);
-    if (!progress)
-      return;
-    progress.done();
-    this._progresses.delete(requestId);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onSearchCompleted(event) {
-    const requestId = /** @type {number} */ (event.data['requestId']);
-    const files = /** @type {!Array.<string>} */ (event.data['files']);
-
-    const callback = this._callbacks.get(requestId);
-    if (!callback)
-      return;
-    callback.call(null, files);
-    this._callbacks.delete(requestId);
-  }
-};
-
-/** @typedef {!{type: string, fileSystemName: string, rootURL: string, fileSystemPath: string}} */
-Persistence.IsolatedFileSystemManager.FileSystem;
-
-/** @typedef {!{changed:!Multimap<string, string>, added:!Multimap<string, string>, removed:!Multimap<string, string>}} */
-Persistence.IsolatedFileSystemManager.FilesChangedData;
-
-/** @enum {symbol} */
-Persistence.IsolatedFileSystemManager.Events = {
-  FileSystemAdded: Symbol('FileSystemAdded'),
-  FileSystemRemoved: Symbol('FileSystemRemoved'),
-  FileSystemFilesChanged: Symbol('FileSystemFilesChanged'),
-  ExcludedFolderAdded: Symbol('ExcludedFolderAdded'),
-  ExcludedFolderRemoved: Symbol('ExcludedFolderRemoved')
-};
-
-Persistence.IsolatedFileSystemManager._lastRequestId = 0;
-
-/**
- * @type {!Persistence.IsolatedFileSystemManager}
- */
-Persistence.isolatedFileSystemManager;
diff --git a/front_end/persistence/NetworkPersistenceManager.js b/front_end/persistence/NetworkPersistenceManager.js
deleted file mode 100644
index 8c69273..0000000
--- a/front_end/persistence/NetworkPersistenceManager.js
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Persistence.NetworkPersistenceManager = class extends Common.Object {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(workspace) {
-    super();
-    this._bindingSymbol = Symbol('NetworkPersistenceBinding');
-    this._originalResponseContentPromiseSymbol = Symbol('OriginalResponsePromise');
-    this._savingSymbol = Symbol('SavingForOverrides');
-
-    this._enabledSetting = Common.settings.moduleSetting('persistenceNetworkOverridesEnabled');
-    this._enabledSetting.addChangeListener(this._enabledChanged, this);
-
-    this._workspace = workspace;
-
-    /** @type {!Map<string, !Workspace.UISourceCode>} */
-    this._networkUISourceCodeForEncodedPath = new Map();
-    this._interceptionHandlerBound = this._interceptionHandler.bind(this);
-    this._updateInterceptionThrottler = new Common.Throttler(50);
-
-    /** @type {?Workspace.Project} */
-    this._project = null;
-    /** @type {?Workspace.Project} */
-    this._activeProject = null;
-
-    this._active = false;
-    this._enabled = false;
-
-    this._workspace.addEventListener(
-        Workspace.Workspace.Events.ProjectAdded,
-        event => this._onProjectAdded(/** @type {!Workspace.Project} */ (event.data)));
-    this._workspace.addEventListener(
-        Workspace.Workspace.Events.ProjectRemoved,
-        event => this._onProjectRemoved(/** @type {!Workspace.Project} */ (event.data)));
-
-    /** @type {!Array<!Common.EventTarget.EventDescriptor>} */
-    this._eventDescriptors = [];
-    this._enabledChanged();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  active() {
-    return this._active;
-  }
-
-  /**
-   * @return {?Workspace.Project}
-   */
-  project() {
-    return this._project;
-  }
-
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?Promise<?string>}
-   */
-  originalContentForUISourceCode(uiSourceCode) {
-    if (!uiSourceCode[this._bindingSymbol])
-      return null;
-    const fileSystemUISourceCode = uiSourceCode[this._bindingSymbol].fileSystem;
-    return fileSystemUISourceCode[this._originalResponseContentPromiseSymbol] || null;
-  }
-
-  _enabledChanged() {
-    if (this._enabled === this._enabledSetting.get())
-      return;
-    this._enabled = this._enabledSetting.get();
-    if (this._enabled) {
-      this._eventDescriptors = [
-        Workspace.workspace.addEventListener(
-            Workspace.Workspace.Events.UISourceCodeRenamed,
-            event => {
-              const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-              this._onUISourceCodeRemoved(uiSourceCode);
-              this._onUISourceCodeAdded(uiSourceCode);
-            }),
-        Workspace.workspace.addEventListener(
-            Workspace.Workspace.Events.UISourceCodeAdded,
-            event => this._onUISourceCodeAdded(/** @type {!Workspace.UISourceCode} */ (event.data))),
-        Workspace.workspace.addEventListener(
-            Workspace.Workspace.Events.UISourceCodeRemoved,
-            event => this._onUISourceCodeRemoved(/** @type {!Workspace.UISourceCode} */ (event.data))),
-        Workspace.workspace.addEventListener(
-            Workspace.Workspace.Events.WorkingCopyCommitted,
-            event => this._onUISourceCodeWorkingCopyCommitted(
-                /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode)))
-      ];
-      this._updateActiveProject();
-    } else {
-      Common.EventTarget.removeEventListeners(this._eventDescriptors);
-      this._updateActiveProject();
-    }
-  }
-
-  _updateActiveProject() {
-    const wasActive = this._active;
-    this._active = !!(this._enabledSetting.get() && SDK.targetManager.mainTarget() && this._project);
-    if (this._active === wasActive)
-      return;
-
-    if (this._active) {
-      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeAdded.bind(this));
-      const networkProjects = this._workspace.projectsForType(Workspace.projectTypes.Network);
-      for (const networkProject of networkProjects)
-        networkProject.uiSourceCodes().forEach(this._networkUISourceCodeAdded.bind(this));
-    } else if (this._project) {
-      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeRemoved.bind(this));
-      this._networkUISourceCodeForEncodedPath.clear();
-    }
-    Persistence.persistence.setAutomappingEnabled(!this._active);
-  }
-
-  /**
-   * @param {string} url
-   * @return {string}
-   */
-  _encodedPathFromUrl(url) {
-    if (!this._active)
-      return '';
-    let urlPath = Common.ParsedURL.urlWithoutHash(url.replace(/^https?:\/\//, ''));
-    if (urlPath.endsWith('/') && urlPath.indexOf('?') === -1)
-      urlPath = urlPath + 'index.html';
-    let encodedPathParts = encodeUrlPathToLocalPathParts(urlPath);
-    const projectPath = Persistence.FileSystemWorkspaceBinding.fileSystemPath(this._project.id());
-    const encodedPath = encodedPathParts.join('/');
-    if (projectPath.length + encodedPath.length > 200) {
-      const domain = encodedPathParts[0];
-      const encodedFileName = encodedPathParts[encodedPathParts.length - 1];
-      const shortFileName = encodedFileName ? encodedFileName.substr(0, 10) + '-' : '';
-      const extension = Common.ParsedURL.extractExtension(urlPath);
-      const extensionPart = extension ? '.' + extension.substr(0, 10) : '';
-      encodedPathParts =
-          [domain, 'longurls', shortFileName + String.hashCode(encodedPath).toString(16) + extensionPart];
-    }
-    return encodedPathParts.join('/');
-
-    /**
-     * @param {string} urlPath
-     * @return {!Array<string>}
-     */
-    function encodeUrlPathToLocalPathParts(urlPath) {
-      const encodedParts = [];
-      for (const pathPart of fileNamePartsFromUrlPath(urlPath)) {
-        if (!pathPart)
-          continue;
-        // encodeURI() escapes all the unsafe filename characters except /:?*
-        let encodedName = encodeURI(pathPart).replace(/[\/:\?\*]/g, match => '%' + match[0].charCodeAt(0).toString(16));
-        // Windows does not allow a small set of filenames.
-        if (Persistence.NetworkPersistenceManager._reservedFileNames.has(encodedName.toLowerCase()))
-          encodedName = encodedName.split('').map(char => '%' + char.charCodeAt(0).toString(16)).join('');
-        // Windows does not allow the file to end in a space or dot (space should already be encoded).
-        const lastChar = encodedName.charAt(encodedName.length - 1);
-        if (lastChar === '.')
-          encodedName = encodedName.substr(0, encodedName.length - 1) + '%2e';
-        encodedParts.push(encodedName);
-      }
-      return encodedParts;
-    }
-
-    /**
-     * @param {string} urlPath
-     * @return {!Array<string>}
-     */
-    function fileNamePartsFromUrlPath(urlPath) {
-      urlPath = Common.ParsedURL.urlWithoutHash(urlPath);
-      const queryIndex = urlPath.indexOf('?');
-      if (queryIndex === -1)
-        return urlPath.split('/');
-      if (queryIndex === 0)
-        return [urlPath];
-      const endSection = urlPath.substr(queryIndex);
-      const parts = urlPath.substr(0, urlPath.length - endSection.length).split('/');
-      parts[parts.length - 1] += endSection;
-      return parts;
-    }
-  }
-
-  /**
-   * @param {string} path
-   * @return {string}
-   */
-  _decodeLocalPathToUrlPath(path) {
-    try {
-      return unescape(path);
-    } catch (e) {
-      console.error(e);
-    }
-    return path;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _unbind(uiSourceCode) {
-    const binding = uiSourceCode[this._bindingSymbol];
-    if (!binding)
-      return;
-    delete binding.network[this._bindingSymbol];
-    delete binding.fileSystem[this._bindingSymbol];
-    Persistence.persistence.removeBinding(binding);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} networkUISourceCode
-   * @param {!Workspace.UISourceCode} fileSystemUISourceCode
-   */
-  async _bind(networkUISourceCode, fileSystemUISourceCode) {
-    if (networkUISourceCode[this._bindingSymbol])
-      this._unbind(networkUISourceCode);
-    if (fileSystemUISourceCode[this._bindingSymbol])
-      this._unbind(fileSystemUISourceCode);
-    const binding = new Persistence.PersistenceBinding(networkUISourceCode, fileSystemUISourceCode);
-    networkUISourceCode[this._bindingSymbol] = binding;
-    fileSystemUISourceCode[this._bindingSymbol] = binding;
-    Persistence.persistence.addBinding(binding);
-    const uiSourceCodeOfTruth = networkUISourceCode[this._savingSymbol] ? networkUISourceCode : fileSystemUISourceCode;
-    const content = await uiSourceCodeOfTruth.requestContent();
-    Persistence.persistence.syncContent(uiSourceCodeOfTruth, content);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _onUISourceCodeWorkingCopyCommitted(uiSourceCode) {
-    this.saveUISourceCodeForOverrides(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  canSaveUISourceCodeForOverrides(uiSourceCode) {
-    return this._active && uiSourceCode.project().type() === Workspace.projectTypes.Network &&
-        !uiSourceCode[this._bindingSymbol] && !uiSourceCode[this._savingSymbol];
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  async saveUISourceCodeForOverrides(uiSourceCode) {
-    if (!this.canSaveUISourceCodeForOverrides(uiSourceCode))
-      return;
-    uiSourceCode[this._savingSymbol] = true;
-    let encodedPath = this._encodedPathFromUrl(uiSourceCode.url());
-    const content = await uiSourceCode.requestContent();
-    const encoded = await uiSourceCode.contentEncoded();
-    const lastIndexOfSlash = encodedPath.lastIndexOf('/');
-    const encodedFileName = encodedPath.substr(lastIndexOfSlash + 1);
-    encodedPath = encodedPath.substr(0, lastIndexOfSlash);
-    await this._project.createFile(encodedPath, encodedFileName, content, encoded);
-    this._fileCreatedForTest(encodedPath, encodedFileName);
-    uiSourceCode[this._savingSymbol] = false;
-  }
-
-  /**
-   * @param {string} path
-   * @param {string} fileName
-   */
-  _fileCreatedForTest(path, fileName) {
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  _patternForFileSystemUISourceCode(uiSourceCode) {
-    const relativePathParts = Persistence.FileSystemWorkspaceBinding.relativePath(uiSourceCode);
-    if (relativePathParts.length < 2)
-      return '';
-    if (relativePathParts[1] === 'longurls' && relativePathParts.length !== 2)
-      return 'http?://' + relativePathParts[0] + '/*';
-    return 'http?://' + this._decodeLocalPathToUrlPath(relativePathParts.join('/'));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _onUISourceCodeAdded(uiSourceCode) {
-    this._networkUISourceCodeAdded(uiSourceCode);
-    this._filesystemUISourceCodeAdded(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _networkUISourceCodeAdded(uiSourceCode) {
-    if (!this._active || uiSourceCode.project().type() !== Workspace.projectTypes.Network)
-      return;
-    const url = Common.ParsedURL.urlWithoutHash(uiSourceCode.url());
-    this._networkUISourceCodeForEncodedPath.set(this._encodedPathFromUrl(url), uiSourceCode);
-
-    const fileSystemUISourceCode =
-        this._project.uiSourceCodeForURL(this._project.fileSystemPath() + '/' + this._encodedPathFromUrl(url));
-    if (!fileSystemUISourceCode)
-      return;
-    this._bind(uiSourceCode, fileSystemUISourceCode);
-  }
-
-  /**
-    * @param {!Workspace.UISourceCode} uiSourceCode
-    */
-  _filesystemUISourceCodeAdded(uiSourceCode) {
-    if (!this._active || uiSourceCode.project() !== this._project)
-      return;
-    this._updateInterceptionPatterns();
-
-    const relativePath = Persistence.FileSystemWorkspaceBinding.relativePath(uiSourceCode);
-    const networkUISourceCode = this._networkUISourceCodeForEncodedPath.get(relativePath.join('/'));
-    if (networkUISourceCode)
-      this._bind(networkUISourceCode, uiSourceCode);
-  }
-
-  _updateInterceptionPatterns() {
-    this._updateInterceptionThrottler.schedule(innerUpdateInterceptionPatterns.bind(this));
-
-    /**
-     * @this {Persistence.NetworkPersistenceManager}
-     * @return {!Promise}
-     */
-    function innerUpdateInterceptionPatterns() {
-      if (!this._active)
-        return SDK.multitargetNetworkManager.setInterceptionHandlerForPatterns([], this._interceptionHandlerBound);
-      const patterns = new Set();
-      const indexFileName = 'index.html';
-      for (const uiSourceCode of this._project.uiSourceCodes()) {
-        const pattern = this._patternForFileSystemUISourceCode(uiSourceCode);
-        patterns.add(pattern);
-        if (pattern.endsWith('/' + indexFileName))
-          patterns.add(pattern.substr(0, pattern.length - indexFileName.length));
-      }
-
-      return SDK.multitargetNetworkManager.setInterceptionHandlerForPatterns(
-          Array.from(patterns).map(
-              pattern =>
-                  ({urlPattern: pattern, interceptionStage: Protocol.Network.InterceptionStage.HeadersReceived})),
-          this._interceptionHandlerBound);
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _onUISourceCodeRemoved(uiSourceCode) {
-    this._networkUISourceCodeRemoved(uiSourceCode);
-    this._filesystemUISourceCodeRemoved(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _networkUISourceCodeRemoved(uiSourceCode) {
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.Network)
-      return;
-    this._unbind(uiSourceCode);
-    this._networkUISourceCodeForEncodedPath.delete(this._encodedPathFromUrl(uiSourceCode.url()));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _filesystemUISourceCodeRemoved(uiSourceCode) {
-    if (uiSourceCode.project() !== this._project)
-      return;
-    this._updateInterceptionPatterns();
-    delete uiSourceCode[this._originalResponseContentPromiseSymbol];
-    this._unbind(uiSourceCode);
-  }
-
-  _setProject(project) {
-    if (project === this._project)
-      return;
-
-    if (this._project)
-      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeRemoved.bind(this));
-
-    this._project = project;
-
-    if (this._project)
-      this._project.uiSourceCodes().forEach(this._filesystemUISourceCodeAdded.bind(this));
-
-    this._updateActiveProject();
-    this.dispatchEventToListeners(Persistence.NetworkPersistenceManager.Events.ProjectChanged, this._project);
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _onProjectAdded(project) {
-    if (project.type() !== Workspace.projectTypes.FileSystem ||
-        Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides')
-      return;
-    const fileSystemPath = Persistence.FileSystemWorkspaceBinding.fileSystemPath(project.id());
-    if (!fileSystemPath)
-      return;
-    if (this._project)
-      this._project.remove();
-
-    this._setProject(project);
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _onProjectRemoved(project) {
-    if (project !== this._project)
-      return;
-    this._setProject(null);
-  }
-
-  /**
-   * @param {!SDK.MultitargetNetworkManager.InterceptedRequest} interceptedRequest
-   * @return {!Promise}
-   */
-  async _interceptionHandler(interceptedRequest) {
-    const method = interceptedRequest.request.method;
-    if (!this._active || (method !== 'GET' && method !== 'POST'))
-      return;
-    const path = this._project.fileSystemPath() + '/' + this._encodedPathFromUrl(interceptedRequest.request.url);
-    const fileSystemUISourceCode = this._project.uiSourceCodeForURL(path);
-    if (!fileSystemUISourceCode)
-      return;
-
-    let mimeType = '';
-    if (interceptedRequest.responseHeaders) {
-      const responseHeaders = SDK.NetworkManager.lowercaseHeaders(interceptedRequest.responseHeaders);
-      mimeType = responseHeaders['content-type'];
-    }
-
-    if (!mimeType) {
-      const expectedResourceType = Common.resourceTypes[interceptedRequest.resourceType] || Common.resourceTypes.Other;
-      mimeType = fileSystemUISourceCode.mimeType();
-      if (Common.ResourceType.fromMimeType(mimeType) !== expectedResourceType)
-        mimeType = expectedResourceType.canonicalMimeType();
-    }
-    const project =
-        /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (fileSystemUISourceCode.project());
-
-    fileSystemUISourceCode[this._originalResponseContentPromiseSymbol] =
-        interceptedRequest.responseBody().then(response => {
-          if (response.error || response.content === null)
-            return null;
-          return response.encoded ? atob(response.content) : response.content;
-        });
-
-    const blob = await project.requestFileBlob(fileSystemUISourceCode);
-    interceptedRequest.continueRequestWithContent(new Blob([blob], {type: mimeType}));
-  }
-};
-
-Persistence.NetworkPersistenceManager._reservedFileNames = new Set([
-  'con',  'prn',  'aux',  'nul',  'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7',
-  'com8', 'com9', 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9'
-]);
-
-Persistence.NetworkPersistenceManager.Events = {
-  ProjectChanged: Symbol('ProjectChanged')
-};
-
-/** @type {!Persistence.NetworkPersistenceManager} */
-Persistence.networkPersistenceManager;
diff --git a/front_end/persistence/Persistence.js b/front_end/persistence/Persistence.js
deleted file mode 100644
index a216bf4..0000000
--- a/front_end/persistence/Persistence.js
+++ /dev/null
@@ -1,451 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Persistence.Persistence = class extends Common.Object {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {!Bindings.BreakpointManager} breakpointManager
-   */
-  constructor(workspace, breakpointManager) {
-    super();
-    this._workspace = workspace;
-    this._breakpointManager = breakpointManager;
-    /** @type {!Map<string, number>} */
-    this._filePathPrefixesToBindingCount = new Map();
-
-    /** @type {!Multimap<!Workspace.UISourceCode, function()>} */
-    this._subscribedBindingEventListeners = new Multimap();
-
-    const linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this);
-    Components.Linkifier.setLinkDecorator(linkDecorator);
-    this._mapping = null;
-    this.setAutomappingEnabled(true);
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setAutomappingEnabled(enabled) {
-    if (enabled === !!this._mapping)
-      return;
-    if (!enabled) {
-      this._mapping.dispose();
-      this._mapping = null;
-    } else {
-      this._mapping = new Persistence.Automapping(
-          this._workspace, this._onStatusAdded.bind(this), this._onStatusRemoved.bind(this));
-    }
-  }
-
-  /**
-   * @param {!Persistence.PersistenceBinding} binding
-   */
-  addBinding(binding) {
-    this._innerAddBinding(binding);
-  }
-
-  /**
-   * @param {!Persistence.PersistenceBinding} binding
-   */
-  addBindingForTest(binding) {
-    this._innerAddBinding(binding);
-  }
-
-  /**
-   * @param {!Persistence.PersistenceBinding} binding
-   */
-  removeBinding(binding) {
-    this._innerRemoveBinding(binding);
-  }
-
-  /**
-   * @param {!Persistence.PersistenceBinding} binding
-   */
-  removeBindingForTest(binding) {
-    this._innerRemoveBinding(binding);
-  }
-
-  /**
-   * @param {!Persistence.PersistenceBinding} binding
-   */
-  _innerAddBinding(binding) {
-    binding.network[Persistence.Persistence._binding] = binding;
-    binding.fileSystem[Persistence.Persistence._binding] = binding;
-
-    binding.fileSystem.forceLoadOnCheckContent();
-
-    binding.network.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
-    binding.fileSystem.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
-    binding.network.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
-    binding.fileSystem.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
-
-    this._addFilePathBindingPrefixes(binding.fileSystem.url());
-
-    this._moveBreakpoints(binding.fileSystem, binding.network);
-
-    console.assert(!binding.fileSystem.isDirty() || !binding.network.isDirty());
-    if (binding.fileSystem.isDirty()) {
-      this._syncWorkingCopy(binding.fileSystem);
-    } else if (binding.network.isDirty()) {
-      this._syncWorkingCopy(binding.network);
-    } else if (binding.network.hasCommits()) {
-      binding.network.setWorkingCopy(binding.network.content());
-      this._syncWorkingCopy(binding.network);
-    }
-
-    this._notifyBindingEvent(binding.network);
-    this._notifyBindingEvent(binding.fileSystem);
-    this.dispatchEventToListeners(Persistence.Persistence.Events.BindingCreated, binding);
-  }
-
-  /**
-   * @param {!Persistence.PersistenceBinding} binding
-   */
-  _innerRemoveBinding(binding) {
-    if (binding.network[Persistence.Persistence._binding] !== binding)
-      return;
-    console.assert(
-        binding.network[Persistence.Persistence._binding] === binding.fileSystem[Persistence.Persistence._binding],
-        'ERROR: inconsistent binding for networkURL ' + binding.network.url());
-
-    binding.network[Persistence.Persistence._binding] = null;
-    binding.fileSystem[Persistence.Persistence._binding] = null;
-
-    binding.network.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
-    binding.fileSystem.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
-    binding.network.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
-    binding.fileSystem.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
-
-    this._removeFilePathBindingPrefixes(binding.fileSystem.url());
-    this._breakpointManager.copyBreakpoints(binding.network.url(), binding.fileSystem);
-
-    this._notifyBindingEvent(binding.network);
-    this._notifyBindingEvent(binding.fileSystem);
-    this.dispatchEventToListeners(Persistence.Persistence.Events.BindingRemoved, binding);
-  }
-
-  /**
-   * @param {!Persistence.AutomappingStatus} status
-   */
-  _onStatusAdded(status) {
-    const binding = new Persistence.PersistenceBinding(status.network, status.fileSystem);
-    status[Persistence.Persistence._binding] = binding;
-    this._innerAddBinding(binding);
-  }
-
-  /**
-   * @param {!Persistence.AutomappingStatus} status
-   */
-  _onStatusRemoved(status) {
-    const binding = /** @type {!Persistence.PersistenceBinding} */ (status[Persistence.Persistence._binding]);
-    this._innerRemoveBinding(binding);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWorkingCopyChanged(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._syncWorkingCopy(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _syncWorkingCopy(uiSourceCode) {
-    const binding = uiSourceCode[Persistence.Persistence._binding];
-    if (!binding || binding[Persistence.Persistence._muteWorkingCopy])
-      return;
-    const other = binding.network === uiSourceCode ? binding.fileSystem : binding.network;
-    if (!uiSourceCode.isDirty()) {
-      binding[Persistence.Persistence._muteWorkingCopy] = true;
-      other.resetWorkingCopy();
-      binding[Persistence.Persistence._muteWorkingCopy] = false;
-      this._contentSyncedForTest();
-      return;
-    }
-
-    const target = Bindings.NetworkProject.targetForUISourceCode(binding.network);
-    if (target.isNodeJS()) {
-      const newContent = uiSourceCode.workingCopy();
-      other.requestContent().then(() => {
-        const nodeJSContent = Persistence.Persistence.rewrapNodeJSContent(other, other.workingCopy(), newContent);
-        setWorkingCopy.call(this, () => nodeJSContent);
-      });
-      return;
-    }
-
-    setWorkingCopy.call(this, () => uiSourceCode.workingCopy());
-
-    /**
-     * @param {function():string} workingCopyGetter
-     * @this {Persistence.Persistence}
-     */
-    function setWorkingCopy(workingCopyGetter) {
-      binding[Persistence.Persistence._muteWorkingCopy] = true;
-      other.setWorkingCopyGetter(workingCopyGetter);
-      binding[Persistence.Persistence._muteWorkingCopy] = false;
-      this._contentSyncedForTest();
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWorkingCopyCommitted(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    const newContent = /** @type {string} */ (event.data.content);
-    this.syncContent(uiSourceCode, newContent);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newContent
-   */
-  syncContent(uiSourceCode, newContent) {
-    const binding = uiSourceCode[Persistence.Persistence._binding];
-    if (!binding || binding[Persistence.Persistence._muteCommit])
-      return;
-    const other = binding.network === uiSourceCode ? binding.fileSystem : binding.network;
-    const target = Bindings.NetworkProject.targetForUISourceCode(binding.network);
-    if (target.isNodeJS()) {
-      other.requestContent().then(currentContent => {
-        const nodeJSContent = Persistence.Persistence.rewrapNodeJSContent(other, currentContent, newContent);
-        setContent.call(this, nodeJSContent);
-      });
-      return;
-    }
-    setContent.call(this, newContent);
-
-    /**
-     * @param {string} newContent
-     * @this {Persistence.Persistence}
-     */
-    function setContent(newContent) {
-      binding[Persistence.Persistence._muteCommit] = true;
-      other.addRevision(newContent);
-      binding[Persistence.Persistence._muteCommit] = false;
-      this._contentSyncedForTest();
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} currentContent
-   * @param {string} newContent
-   * @return {string}
-   */
-  static rewrapNodeJSContent(uiSourceCode, currentContent, newContent) {
-    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem) {
-      if (newContent.startsWith(Persistence.Persistence._NodePrefix) &&
-          newContent.endsWith(Persistence.Persistence._NodeSuffix)) {
-        newContent = newContent.substring(
-            Persistence.Persistence._NodePrefix.length, newContent.length - Persistence.Persistence._NodeSuffix.length);
-      }
-      if (currentContent.startsWith(Persistence.Persistence._NodeShebang))
-        newContent = Persistence.Persistence._NodeShebang + newContent;
-    } else {
-      if (newContent.startsWith(Persistence.Persistence._NodeShebang))
-        newContent = newContent.substring(Persistence.Persistence._NodeShebang.length);
-      if (currentContent.startsWith(Persistence.Persistence._NodePrefix) &&
-          currentContent.endsWith(Persistence.Persistence._NodeSuffix))
-        newContent = Persistence.Persistence._NodePrefix + newContent + Persistence.Persistence._NodeSuffix;
-    }
-    return newContent;
-  }
-
-  _contentSyncedForTest() {
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} from
-   * @param {!Workspace.UISourceCode} to
-   */
-  _moveBreakpoints(from, to) {
-    const breakpoints = this._breakpointManager.breakpointsForUISourceCode(from);
-    for (const breakpoint of breakpoints) {
-      breakpoint.remove(false /* keepInStorage */);
-      this._breakpointManager.setBreakpoint(
-          to, breakpoint.lineNumber(), breakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled());
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  hasUnsavedCommittedChanges(uiSourceCode) {
-    if (this._workspace.hasResourceContentTrackingExtensions())
-      return false;
-    if (uiSourceCode.project().canSetFileContent())
-      return false;
-    if (uiSourceCode[Persistence.Persistence._binding])
-      return false;
-    return !!uiSourceCode.hasCommits();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?Persistence.PersistenceBinding}
-   */
-  binding(uiSourceCode) {
-    return uiSourceCode[Persistence.Persistence._binding] || null;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function()} listener
-   */
-  subscribeForBindingEvent(uiSourceCode, listener) {
-    this._subscribedBindingEventListeners.set(uiSourceCode, listener);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function()} listener
-   */
-  unsubscribeFromBindingEvent(uiSourceCode, listener) {
-    this._subscribedBindingEventListeners.delete(uiSourceCode, listener);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _notifyBindingEvent(uiSourceCode) {
-    if (!this._subscribedBindingEventListeners.has(uiSourceCode))
-      return;
-    const listeners = Array.from(this._subscribedBindingEventListeners.get(uiSourceCode));
-    for (const listener of listeners)
-      listener.call(null);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?Workspace.UISourceCode}
-   */
-  fileSystem(uiSourceCode) {
-    const binding = this.binding(uiSourceCode);
-    return binding ? binding.fileSystem : null;
-  }
-
-  /**
-   * @param {string} filePath
-   */
-  _addFilePathBindingPrefixes(filePath) {
-    let relative = '';
-    for (const token of filePath.split('/')) {
-      relative += token + '/';
-      const count = this._filePathPrefixesToBindingCount.get(relative) || 0;
-      this._filePathPrefixesToBindingCount.set(relative, count + 1);
-    }
-  }
-
-  /**
-   * @param {string} filePath
-   */
-  _removeFilePathBindingPrefixes(filePath) {
-    let relative = '';
-    for (const token of filePath.split('/')) {
-      relative += token + '/';
-      const count = this._filePathPrefixesToBindingCount.get(relative);
-      if (count === 1)
-        this._filePathPrefixesToBindingCount.delete(relative);
-      else
-        this._filePathPrefixesToBindingCount.set(relative, count - 1);
-    }
-  }
-
-  /**
-   * @param {string} filePath
-   * @return {boolean}
-   */
-  filePathHasBindings(filePath) {
-    if (!filePath.endsWith('/'))
-      filePath += '/';
-    return this._filePathPrefixesToBindingCount.has(filePath);
-  }
-
-  dispose() {
-    if (this._mapping) {
-      this._mapping.dispose();
-      this._mapping = null;
-    }
-  }
-};
-
-Persistence.Persistence._binding = Symbol('Persistence.Binding');
-Persistence.Persistence._muteCommit = Symbol('Persistence.MuteCommit');
-Persistence.Persistence._muteWorkingCopy = Symbol('Persistence.MuteWorkingCopy');
-
-Persistence.Persistence._NodePrefix = '(function (exports, require, module, __filename, __dirname) { ';
-Persistence.Persistence._NodeSuffix = '\n});';
-Persistence.Persistence._NodeShebang = '#!/usr/bin/env node';
-
-Persistence.Persistence.Events = {
-  BindingCreated: Symbol('BindingCreated'),
-  BindingRemoved: Symbol('BindingRemoved')
-};
-
-/**
- * @unrestricted
- */
-Persistence.PathEncoder = class {
-  constructor() {
-    /** @type {!Common.CharacterIdMap<string>} */
-    this._encoder = new Common.CharacterIdMap();
-  }
-
-  /**
-   * @param {string} path
-   * @return {string}
-   */
-  encode(path) {
-    return path.split('/').map(token => this._encoder.toChar(token)).join('');
-  }
-
-  /**
-   * @param {string} path
-   * @return {string}
-   */
-  decode(path) {
-    return path.split('').map(token => this._encoder.fromChar(token)).join('/');
-  }
-};
-
-/**
- * @unrestricted
- */
-Persistence.PersistenceBinding = class {
-  /**
-   * @param {!Workspace.UISourceCode} network
-   * @param {!Workspace.UISourceCode} fileSystem
-   */
-  constructor(network, fileSystem) {
-    this.network = network;
-    this.fileSystem = fileSystem;
-  }
-};
-
-/**
- * @interface
- */
-Persistence.MappingSystem = function() {};
-
-Persistence.MappingSystem.prototype = {
-  dispose: function() {}
-};
-
-/** @type {!Persistence.Persistence} */
-Persistence.persistence;
diff --git a/front_end/persistence/PersistenceActions.js b/front_end/persistence/PersistenceActions.js
deleted file mode 100644
index 8307698..0000000
--- a/front_end/persistence/PersistenceActions.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Persistence.PersistenceActions = {};
-
-/**
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Persistence.PersistenceActions.ContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    const contentProvider = /** @type {!Common.ContentProvider} */ (target);
-    async function saveAs() {
-      if (contentProvider instanceof Workspace.UISourceCode)
-        /** @type {!Workspace.UISourceCode} */ (contentProvider).commitWorkingCopy();
-      const content = await contentProvider.requestContent();
-      const url = contentProvider.contentURL();
-      Workspace.fileManager.save(url, /** @type {string} */ (content), true);
-      Workspace.fileManager.close(url);
-    }
-
-    if (contentProvider.contentType().isDocumentOrScriptOrStyleSheet())
-      contextMenu.saveSection().appendItem(Common.UIString('Save as...'), saveAs);
-
-    // Retrieve uiSourceCode by URL to pick network resources everywhere.
-    const uiSourceCode = Workspace.workspace.uiSourceCodeForURL(contentProvider.contentURL());
-    if (uiSourceCode && Persistence.networkPersistenceManager.canSaveUISourceCodeForOverrides(uiSourceCode)) {
-      contextMenu.saveSection().appendItem(Common.UIString('Save for overrides'), () => {
-        uiSourceCode.commitWorkingCopy();
-        Persistence.networkPersistenceManager.saveUISourceCodeForOverrides(
-            /** @type {!Workspace.UISourceCode} */ (uiSourceCode));
-        Common.Revealer.reveal(uiSourceCode);
-      });
-    }
-
-    const binding = uiSourceCode && Persistence.persistence.binding(uiSourceCode);
-    const fileURL = binding ? binding.fileSystem.contentURL() : contentProvider.contentURL();
-    if (fileURL.startsWith('file://')) {
-      const path = Common.ParsedURL.urlToPlatformPath(fileURL, Host.isWin());
-      contextMenu.revealSection().appendItem(
-          Common.UIString('Open in containing folder'), () => InspectorFrontendHost.showItemInFolder(path));
-    }
-  }
-};
diff --git a/front_end/persistence/PersistenceUtils.js b/front_end/persistence/PersistenceUtils.js
deleted file mode 100644
index 5f50be1..0000000
--- a/front_end/persistence/PersistenceUtils.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Persistence.PersistenceUtils = class {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  static tooltipForUISourceCode(uiSourceCode) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-    if (!binding)
-      return '';
-    if (uiSourceCode === binding.network)
-      return Common.UIString('Persisted to file system: %s', binding.fileSystem.url().trimMiddle(150));
-    if (binding.network.contentType().isFromSourceMap())
-      return Common.UIString('Linked to source map: %s', binding.network.url().trimMiddle(150));
-    return Common.UIString('Linked to %s', binding.network.url().trimMiddle(150));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?UI.Icon}
-   */
-  static iconForUISourceCode(uiSourceCode) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-    if (binding) {
-      const icon = UI.Icon.create('mediumicon-file-sync');
-      icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(binding.fileSystem);
-      // TODO(allada) This will not work properly with dark theme.
-      if (Persistence.networkPersistenceManager.project() === binding.fileSystem.project())
-        icon.style.filter = 'hue-rotate(160deg)';
-      return icon;
-    }
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem)
-      return null;
-    const icon = UI.Icon.create('mediumicon-file');
-    icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(uiSourceCode);
-    return icon;
-  }
-};
-
-/**
- * @extends {Common.Object}
- * @implements {Components.LinkDecorator}
- */
-Persistence.PersistenceUtils.LinkDecorator = class extends Common.Object {
-  /**
-   * @param {!Persistence.Persistence} persistence
-   */
-  constructor(persistence) {
-    super();
-    persistence.addEventListener(Persistence.Persistence.Events.BindingCreated, this._bindingChanged, this);
-    persistence.addEventListener(Persistence.Persistence.Events.BindingRemoved, this._bindingChanged, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _bindingChanged(event) {
-    const binding = /** @type {!Persistence.PersistenceBinding} */ (event.data);
-    this.dispatchEventToListeners(Components.LinkDecorator.Events.LinkIconChanged, binding.network);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {?UI.Icon}
-   */
-  linkIcon(uiSourceCode) {
-    return Persistence.PersistenceUtils.iconForUISourceCode(uiSourceCode);
-  }
-};
\ No newline at end of file
diff --git a/front_end/persistence/WorkspaceSettingsTab.js b/front_end/persistence/WorkspaceSettingsTab.js
deleted file mode 100644
index 7cb2637..0000000
--- a/front_end/persistence/WorkspaceSettingsTab.js
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Persistence.WorkspaceSettingsTab = class extends UI.VBox {
-  constructor() {
-    super();
-    this.registerRequiredCSS('persistence/workspaceSettingsTab.css');
-
-    const header = this.element.createChild('header');
-    header.createChild('h3').createTextChild(Common.UIString('Workspace'));
-
-    this.containerElement = this.element.createChild('div', 'settings-container-wrapper')
-                                .createChild('div', 'settings-tab settings-content settings-container');
-
-    Persistence.isolatedFileSystemManager.addEventListener(
-        Persistence.IsolatedFileSystemManager.Events.FileSystemAdded,
-        event => this._fileSystemAdded(/** @type {!Persistence.IsolatedFileSystem} */ (event.data)), this);
-    Persistence.isolatedFileSystemManager.addEventListener(
-        Persistence.IsolatedFileSystemManager.Events.FileSystemRemoved,
-        event => this._fileSystemRemoved(/** @type {!Persistence.IsolatedFileSystem} */ (event.data)), this);
-
-    const folderExcludePatternInput = this._createFolderExcludePatternInput();
-    folderExcludePatternInput.classList.add('folder-exclude-pattern');
-    this.containerElement.appendChild(folderExcludePatternInput);
-
-    const div = this.containerElement.createChild('div', 'settings-info-message');
-    div.createTextChild(Common.UIString('Mappings are inferred automatically. Please '));
-    div.appendChild(UI.XLink.create(
-        'https://bugs.chromium.org/p/chromium/issues/entry?template=Defect%20report%20from%20user&components=Platform%3EDevTools%3EAuthoring&comment=DevTools%20failed%20to%20link%20network%20resource%20to%20filesystem.%0A%0APlatform%3A%20%3CLinux%2FWin%2FMac%3E%0AChrome%20version%3A%20%3Cyour%20chrome%20version%3E%0A%0AWhat%20are%20the%20details%20of%20your%20project%3F%0A-%20Source%20code%20(if%20any)%3A%20http%3A%2F%2Fgithub.com%2Fexample%2Fexample%0A-%20Build%20System%3A%20gulp%2Fgrunt%2Fwebpack%2Frollup%2F...%0A-%20HTTP%20server%3A%20node%20HTTP%2Fnginx%2Fapache...%0A%0AAssets%20failed%20to%20link%20(or%20incorrectly%20linked)%3A%0A1.%0A2.%0A3.%0A%0AIf%20possible%2C%20please%20attach%20a%20screenshot%20of%20network%20sources%20navigator%20which%20should%0Ashow%20which%20resources%20failed%20to%20map',
-        Common.UIString('report')));
-    div.createTextChild(Common.UIString(' any bugs.'));
-
-    this._fileSystemsListContainer = this.containerElement.createChild('div', '');
-
-    this.containerElement.appendChild(
-        UI.createTextButton(Common.UIString('Add folder\u2026'), this._addFileSystemClicked.bind(this)));
-
-    /** @type {!Map<string, !Element>} */
-    this._elementByPath = new Map();
-
-    /** @type {!Map<string, !Persistence.EditFileSystemView>} */
-    this._mappingViewByPath = new Map();
-
-    const fileSystems = Persistence.isolatedFileSystemManager.fileSystems();
-    for (let i = 0; i < fileSystems.length; ++i)
-      this._addItem(fileSystems[i]);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _createFolderExcludePatternInput() {
-    const p = createElement('p');
-    const labelElement = p.createChild('label');
-    labelElement.textContent = Common.UIString('Folder exclude pattern');
-    const inputElement = UI.createInput('', 'text');
-    p.appendChild(inputElement);
-    inputElement.style.width = '270px';
-    const folderExcludeSetting = Persistence.isolatedFileSystemManager.workspaceFolderExcludePatternSetting();
-    const setValue =
-        UI.bindInput(inputElement, folderExcludeSetting.set.bind(folderExcludeSetting), regexValidator, false);
-    folderExcludeSetting.addChangeListener(() => setValue.call(null, folderExcludeSetting.get()));
-    setValue(folderExcludeSetting.get());
-    return p;
-
-    /**
-     * @param {string} value
-     * @return {boolean}
-     */
-    function regexValidator(value) {
-      let regex;
-      try {
-        regex = new RegExp(value);
-      } catch (e) {
-      }
-      return !!regex;
-    }
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   */
-  _addItem(fileSystem) {
-    const networkPersistenceProject = Persistence.networkPersistenceManager.project();
-    if (networkPersistenceProject &&
-        Persistence.isolatedFileSystemManager.fileSystem(networkPersistenceProject.fileSystemPath()) === fileSystem)
-      return;
-    const element = this._renderFileSystem(fileSystem);
-    this._elementByPath.set(fileSystem.path(), element);
-
-    this._fileSystemsListContainer.appendChild(element);
-
-    const mappingView = new Persistence.EditFileSystemView(fileSystem.path());
-    this._mappingViewByPath.set(fileSystem.path(), mappingView);
-    mappingView.element.classList.add('file-system-mapping-view');
-    mappingView.show(element);
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   * @return {!Element}
-   */
-  _renderFileSystem(fileSystem) {
-    const fileSystemPath = fileSystem.path();
-    const lastIndexOfSlash = fileSystemPath.lastIndexOf(Host.isWin() ? '\\' : '/');
-    const folderName = fileSystemPath.substr(lastIndexOfSlash + 1);
-
-    const element = createElementWithClass('div', 'file-system-container');
-    const header = element.createChild('div', 'file-system-header');
-
-    header.createChild('div', 'file-system-name').textContent = folderName;
-    const path = header.createChild('div', 'file-system-path');
-    path.textContent = fileSystemPath;
-    path.title = fileSystemPath;
-
-    const toolbar = new UI.Toolbar('');
-    const button = new UI.ToolbarButton(Common.UIString('Remove'), 'largeicon-delete');
-    button.addEventListener(UI.ToolbarButton.Events.Click, this._removeFileSystemClicked.bind(this, fileSystem));
-    toolbar.appendToolbarItem(button);
-    header.appendChild(toolbar.element);
-
-    return element;
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   */
-  _removeFileSystemClicked(fileSystem) {
-    Persistence.isolatedFileSystemManager.removeFileSystem(fileSystem);
-  }
-
-  _addFileSystemClicked() {
-    Persistence.isolatedFileSystemManager.addFileSystem();
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   */
-  _fileSystemAdded(fileSystem) {
-    this._addItem(fileSystem);
-  }
-
-  /**
-   * @param {!Persistence.IsolatedFileSystem} fileSystem
-   */
-  _fileSystemRemoved(fileSystem) {
-    const mappingView = this._mappingViewByPath.get(fileSystem.path());
-    if (mappingView) {
-      mappingView.dispose();
-      this._mappingViewByPath.delete(fileSystem.path());
-    }
-
-    const element = this._elementByPath.get(fileSystem.path());
-    if (element) {
-      this._elementByPath.delete(fileSystem.path());
-      element.remove();
-    }
-  }
-};
diff --git a/front_end/persistence/editFileSystemView.css b/front_end/persistence/editFileSystemView.css
deleted file mode 100644
index 022e3cf..0000000
--- a/front_end/persistence/editFileSystemView.css
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.file-system-header {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    flex: auto;
-    margin: 10px 0;
-}
-
-.file-system-header-text {
-    flex: 1 0 auto;
-}
-
-.add-button {
-    margin-left: 10px;
-    align-self: flex-start;
-}
-
-.file-system-list {
-    flex: auto;
-}
-
-.file-system-list-empty {
-    flex: auto;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    text-align: center;
-}
-
-.file-system-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    flex: auto 1 1;
-}
-
-.list-item .file-system-value {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -webkit-user-select: none;
-    overflow: hidden;
-}
-
-.file-system-value {
-    flex: 1 1 0px;
-}
-
-.file-system-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 6px 5px;
-    align-items: center;
-}
-
-.file-system-edit-row input {
-    width: 100%;
-    text-align: inherit;
-}
diff --git a/front_end/persistence/module.json b/front_end/persistence/module.json
deleted file mode 100644
index 254391a..0000000
--- a/front_end/persistence/module.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
-    "dependencies": [
-        "bindings",
-        "workspace",
-        "components",
-        "sdk"
-    ],
-    "extensions": [
-        {
-            "type": "view",
-            "location": "settings-view",
-            "id": "workspace",
-            "title": "Workspace",
-            "order": 1,
-            "className": "Persistence.WorkspaceSettingsTab"
-        },
-        {
-            "type": "setting",
-            "category": "Persistence",
-            "title": "Enable Local Overrides",
-            "settingName": "persistenceNetworkOverridesEnabled",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "tags": "interception, override, network, rewrite, request",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable override network requests"
-                },
-                {
-                    "value": false,
-                    "title": "Disable override network requests"
-                }
-            ]
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "Workspace.UISourceCode",
-                "SDK.Resource",
-                "SDK.NetworkRequest"
-            ],
-            "className": "Persistence.PersistenceActions.ContextMenuProvider"
-        }
-    ],
-    "scripts": [
-        "IsolatedFileSystem.js",
-        "IsolatedFileSystemManager.js",
-        "FileSystemWorkspaceBinding.js",
-        "Automapping.js",
-        "NetworkPersistenceManager.js",
-        "Persistence.js",
-        "PersistenceActions.js",
-        "PersistenceUtils.js",
-        "EditFileSystemView.js",
-        "WorkspaceSettingsTab.js"
-    ],
-    "resources": [
-        "editFileSystemView.css",
-        "workspaceSettingsTab.css"
-    ]
-}
diff --git a/front_end/persistence/workspaceSettingsTab.css b/front_end/persistence/workspaceSettingsTab.css
deleted file mode 100644
index ee24213..0000000
--- a/front_end/persistence/workspaceSettingsTab.css
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-header {
-    padding: 0 0 6px;
-    border-bottom: 1px solid #EEEEEE;
-}
-
-header > h3 {
-    font-size: 18px;
-    font-weight: normal;
-    margin: 0;
-    padding-bottom: 3px;
-}
-
-.settings-content {
-    overflow-y: auto;
-    overflow-x: hidden;
-    margin: 8px 8px 8px 0;
-    padding: 0 4px;
-    flex: auto;
-}
-
-.settings-container {
-    width: 100%;
-    -webkit-column-width: 288px;
-}
-
-
-.settings-tab.settings-container {
-    -webkit-column-width: 308px;
-}
-
-.settings-tab label {
-    padding-right: 4px;
-    display: inline-flex;
-}
-
-.settings-container-wrapper {
-    position: absolute;
-    top: 31px;
-    left: 0px;
-    right: 0;
-    bottom: 0;
-    overflow: auto;
-    padding-top: 9px;
-}
-
-.settings-tab.settings-content {
-    margin: 0;
-    padding: 0;
-}
-
-.settings-tab p {
-    margin: 12px 0;
-}
-
-p.folder-exclude-pattern {
-    display: flex;
-    align-items: center;
-}
-
-p.folder-exclude-pattern > input {
-    flex: auto;
-}
-
-.settings-tab .file-system-container {
-    border-top: 1px solid #aaa;
-    padding: 19px 0 10px;
-    margin: 20px 0;
-}
-
-.settings-tab .file-system-header {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-}
-
-.settings-tab .file-system-name {
-    font-weight: bold;
-    flex: none;
-    margin-right: 10px;
-    font-size: 15px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    max-width: 70%;
-}
-
-.settings-tab .file-system-path {
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    flex: auto;
-}
-
-.settings-info-message {
-    background-color: #eee;
-    padding: 10px;
-    margin: 20px 0;
-}
-
-.settings-tab.settings-content.settings-container {
-    -webkit-column-width: initial;
-    overflow: hidden;
-    padding-right: 10px;
-}
diff --git a/front_end/platform/module.json b/front_end/platform/module.json
deleted file mode 100644
index cbb4b4c..0000000
--- a/front_end/platform/module.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "dependencies": [
-    ],
-    "scripts": [
-        "utilities.js"
-    ]
-}
diff --git a/front_end/platform/utilities.js b/front_end/platform/utilities.js
deleted file mode 100644
index 87ecd30..0000000
--- a/front_end/platform/utilities.js
+++ /dev/null
@@ -1,1433 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @typedef {Array|NodeList|Arguments|{length: number}} */
-let ArrayLike;
-
-/**
- * @param {number} m
- * @param {number} n
- * @return {number}
- */
-function mod(m, n) {
-  return ((m % n) + n) % n;
-}
-
-/**
- * @param {string} string
- * @return {!Array.<number>}
- */
-String.prototype.findAll = function(string) {
-  const matches = [];
-  let i = this.indexOf(string);
-  while (i !== -1) {
-    matches.push(i);
-    i = this.indexOf(string, i + string.length);
-  }
-  return matches;
-};
-
-/**
- * @return {string}
- */
-String.prototype.reverse = function() {
-  return this.split('').reverse().join('');
-};
-
-/**
- * @return {string}
- */
-String.prototype.replaceControlCharacters = function() {
-  // Replace C0 and C1 control character sets with printable character.
-  // Do not replace '\t', \n' and '\r'.
-  return this.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u0080-\u009f]/g, '�');
-};
-
-/**
- * @return {boolean}
- */
-String.prototype.isWhitespace = function() {
-  return /^\s*$/.test(this);
-};
-
-/**
- * @return {!Array.<number>}
- */
-String.prototype.computeLineEndings = function() {
-  const endings = this.findAll('\n');
-  endings.push(this.length);
-  return endings;
-};
-
-/**
- * @param {string} chars
- * @return {string}
- */
-String.prototype.escapeCharacters = function(chars) {
-  let foundChar = false;
-  for (let i = 0; i < chars.length; ++i) {
-    if (this.indexOf(chars.charAt(i)) !== -1) {
-      foundChar = true;
-      break;
-    }
-  }
-
-  if (!foundChar)
-    return String(this);
-
-  let result = '';
-  for (let i = 0; i < this.length; ++i) {
-    if (chars.indexOf(this.charAt(i)) !== -1)
-      result += '\\';
-    result += this.charAt(i);
-  }
-
-  return result;
-};
-
-/**
- * @return {string}
- */
-String.regexSpecialCharacters = function() {
-  return '^[]{}()\\.^$*+?|-,';
-};
-
-/**
- * @return {string}
- */
-String.prototype.escapeForRegExp = function() {
-  return this.escapeCharacters(String.regexSpecialCharacters());
-};
-
-/**
- * @param {string} query
- * @return {!RegExp}
- */
-String.filterRegex = function(query) {
-  const toEscape = String.regexSpecialCharacters();
-  let regexString = '';
-  for (let i = 0; i < query.length; ++i) {
-    let c = query.charAt(i);
-    if (toEscape.indexOf(c) !== -1)
-      c = '\\' + c;
-    if (i)
-      regexString += '[^\\0' + c + ']*';
-    regexString += c;
-  }
-  return new RegExp(regexString, 'i');
-};
-
-/**
- * @return {string}
- */
-String.prototype.escapeHTML = function() {
-  return this.replace(/&/g, '&amp;')
-      .replace(/</g, '&lt;')
-      .replace(/>/g, '&gt;')
-      .replace(/"/g, '&quot;');  // " doublequotes just for editor
-};
-
-/**
- * @return {string}
- */
-String.prototype.unescapeHTML = function() {
-  return this.replace(/&lt;/g, '<')
-      .replace(/&gt;/g, '>')
-      .replace(/&#58;/g, ':')
-      .replace(/&quot;/g, '"')
-      .replace(/&#60;/g, '<')
-      .replace(/&#62;/g, '>')
-      .replace(/&amp;/g, '&');
-};
-
-/**
- * @return {string}
- */
-String.prototype.collapseWhitespace = function() {
-  return this.replace(/[\s\xA0]+/g, ' ');
-};
-
-/**
- * @param {number} maxLength
- * @return {string}
- */
-String.prototype.trimMiddle = function(maxLength) {
-  if (this.length <= maxLength)
-    return String(this);
-  let leftHalf = maxLength >> 1;
-  let rightHalf = maxLength - leftHalf - 1;
-  if (this.codePointAt(this.length - rightHalf - 1) >= 0x10000) {
-    --rightHalf;
-    ++leftHalf;
-  }
-  if (leftHalf > 0 && this.codePointAt(leftHalf - 1) >= 0x10000)
-    --leftHalf;
-  return this.substr(0, leftHalf) + '\u2026' + this.substr(this.length - rightHalf, rightHalf);
-};
-
-/**
- * @param {number} maxLength
- * @return {string}
- */
-String.prototype.trimEnd = function(maxLength) {
-  if (this.length <= maxLength)
-    return String(this);
-  return this.substr(0, maxLength - 1) + '\u2026';
-};
-
-/**
- * @param {?string=} baseURLDomain
- * @return {string}
- */
-String.prototype.trimURL = function(baseURLDomain) {
-  let result = this.replace(/^(https|http|file):\/\//i, '');
-  if (baseURLDomain) {
-    if (result.toLowerCase().startsWith(baseURLDomain.toLowerCase()))
-      result = result.substr(baseURLDomain.length);
-  }
-  return result;
-};
-
-/**
- * @return {string}
- */
-String.prototype.toTitleCase = function() {
-  return this.substring(0, 1).toUpperCase() + this.substring(1);
-};
-
-/**
- * @param {string} other
- * @return {number}
- */
-String.prototype.compareTo = function(other) {
-  if (this > other)
-    return 1;
-  if (this < other)
-    return -1;
-  return 0;
-};
-
-/**
- * @return {string}
- */
-String.prototype.removeURLFragment = function() {
-  let fragmentIndex = this.indexOf('#');
-  if (fragmentIndex === -1)
-    fragmentIndex = this.length;
-  return this.substring(0, fragmentIndex);
-};
-
-/**
- * @param {string|undefined} string
- * @return {number}
- */
-String.hashCode = function(string) {
-  if (!string)
-    return 0;
-  // Hash algorithm for substrings is described in "Über die Komplexität der Multiplikation in
-  // eingeschränkten Branchingprogrammmodellen" by Woelfe.
-  // http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
-  const p = ((1 << 30) * 4 - 5);  // prime: 2^32 - 5
-  const z = 0x5033d967;           // 32 bits from random.org
-  const z2 = 0x59d2f15d;          // random odd 32 bit number
-  let s = 0;
-  let zi = 1;
-  for (let i = 0; i < string.length; i++) {
-    const xi = string.charCodeAt(i) * z2;
-    s = (s + zi * xi) % p;
-    zi = (zi * z) % p;
-  }
-  s = (s + zi * (p - 1)) % p;
-  return Math.abs(s | 0);
-};
-
-/**
- * @param {string} string
- * @param {number} index
- * @return {boolean}
- */
-String.isDigitAt = function(string, index) {
-  const c = string.charCodeAt(index);
-  return (48 <= c && c <= 57);
-};
-
-/**
- * @return {string}
- */
-String.prototype.toBase64 = function() {
-  /**
-   * @param {number} b
-   * @return {number}
-   */
-  function encodeBits(b) {
-    return b < 26 ? b + 65 : b < 52 ? b + 71 : b < 62 ? b - 4 : b === 62 ? 43 : b === 63 ? 47 : 65;
-  }
-  const encoder = new TextEncoder();
-  const data = encoder.encode(this.toString());
-  const n = data.length;
-  let encoded = '';
-  if (n === 0)
-    return encoded;
-  let shift;
-  let v = 0;
-  for (let i = 0; i < n; i++) {
-    shift = i % 3;
-    v |= data[i] << (16 >>> shift & 24);
-    if (shift === 2) {
-      encoded += String.fromCharCode(
-          encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), encodeBits(v >>> 6 & 63), encodeBits(v & 63));
-      v = 0;
-    }
-  }
-  if (shift === 0)
-    encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), 61, 61);
-  else if (shift === 1)
-    encoded += String.fromCharCode(encodeBits(v >>> 18 & 63), encodeBits(v >>> 12 & 63), encodeBits(v >>> 6 & 63), 61);
-  return encoded;
-};
-
-/**
- * @param {string} a
- * @param {string} b
- * @return {number}
- */
-String.naturalOrderComparator = function(a, b) {
-  const chunk = /^\d+|^\D+/;
-  let chunka, chunkb, anum, bnum;
-  while (1) {
-    if (a) {
-      if (!b)
-        return 1;
-    } else {
-      if (b)
-        return -1;
-      else
-        return 0;
-    }
-    chunka = a.match(chunk)[0];
-    chunkb = b.match(chunk)[0];
-    anum = !isNaN(chunka);
-    bnum = !isNaN(chunkb);
-    if (anum && !bnum)
-      return -1;
-    if (bnum && !anum)
-      return 1;
-    if (anum && bnum) {
-      const diff = chunka - chunkb;
-      if (diff)
-        return diff;
-      if (chunka.length !== chunkb.length) {
-        if (! + chunka && ! + chunkb)  // chunks are strings of all 0s (special case)
-          return chunka.length - chunkb.length;
-        else
-          return chunkb.length - chunka.length;
-      }
-    } else if (chunka !== chunkb) {
-      return (chunka < chunkb) ? -1 : 1;
-    }
-    a = a.substring(chunka.length);
-    b = b.substring(chunkb.length);
-  }
-};
-
-/**
- * @param {string} a
- * @param {string} b
- * @return {number}
- */
-String.caseInsensetiveComparator = function(a, b) {
-  a = a.toUpperCase();
-  b = b.toUpperCase();
-  if (a === b)
-    return 0;
-  return a > b ? 1 : -1;
-};
-
-/**
- * @param {number} num
- * @param {number} min
- * @param {number} max
- * @return {number}
- */
-Number.constrain = function(num, min, max) {
-  if (num < min)
-    num = min;
-  else if (num > max)
-    num = max;
-  return num;
-};
-
-/**
- * @param {number} a
- * @param {number} b
- * @return {number}
- */
-Number.gcd = function(a, b) {
-  if (b === 0)
-    return a;
-  else
-    return Number.gcd(b, a % b);
-};
-
-/**
- * @param {string} value
- * @return {string}
- */
-Number.toFixedIfFloating = function(value) {
-  if (!value || isNaN(value))
-    return value;
-  const number = Number(value);
-  return number % 1 ? number.toFixed(3) : String(number);
-};
-
-/**
- * @return {boolean}
- */
-Date.prototype.isValid = function() {
-  return !isNaN(this.getTime());
-};
-
-/**
- * @return {string}
- */
-Date.prototype.toISO8601Compact = function() {
-  /**
-   * @param {number} x
-   * @return {string}
-   */
-  function leadZero(x) {
-    return (x > 9 ? '' : '0') + x;
-  }
-  return this.getFullYear() + leadZero(this.getMonth() + 1) + leadZero(this.getDate()) + 'T' +
-      leadZero(this.getHours()) + leadZero(this.getMinutes()) + leadZero(this.getSeconds());
-};
-
-Object.defineProperty(Array.prototype, 'remove', {
-  /**
-   * @param {!T} value
-   * @param {boolean=} firstOnly
-   * @return {boolean}
-   * @this {Array.<!T>}
-   * @template T
-   */
-  value: function(value, firstOnly) {
-    let index = this.indexOf(value);
-    if (index === -1)
-      return false;
-    if (firstOnly) {
-      this.splice(index, 1);
-      return true;
-    }
-    for (let i = index + 1, n = this.length; i < n; ++i) {
-      if (this[i] !== value)
-        this[index++] = this[i];
-    }
-    this.length = index;
-    return true;
-  }
-});
-
-Object.defineProperty(Array.prototype, 'pushAll', {
-  /**
-   * @param {!Array<!T>} array
-   * @this {Array<!T>}
-   * @template T
-   */
-  value: function(array) {
-    for (let i = 0; i < array.length; ++i)
-      this.push(array[i]);
-  }
-});
-
-Object.defineProperty(Array.prototype, 'rotate', {
-  /**
-   * @param {number} index
-   * @return {!Array.<!T>}
-   * @this {Array.<!T>}
-   * @template T
-   */
-  value: function(index) {
-    const result = [];
-    for (let i = index; i < index + this.length; ++i)
-      result.push(this[i % this.length]);
-    return result;
-  }
-});
-
-Object.defineProperty(Array.prototype, 'sortNumbers', {
-  /**
-   * @this {Array.<number>}
-   */
-  value: function() {
-    /**
-     * @param {number} a
-     * @param {number} b
-     * @return {number}
-     */
-    function numericComparator(a, b) {
-      return a - b;
-    }
-
-    this.sort(numericComparator);
-  }
-});
-
-Object.defineProperty(Uint32Array.prototype, 'sort', {value: Array.prototype.sort});
-
-(function() {
-const partition = {
-  /**
-     * @this {Array.<number>}
-     * @param {function(number, number): number} comparator
-     * @param {number} left
-     * @param {number} right
-     * @param {number} pivotIndex
-     */
-  value: function(comparator, left, right, pivotIndex) {
-    function swap(array, i1, i2) {
-      const temp = array[i1];
-      array[i1] = array[i2];
-      array[i2] = temp;
-    }
-
-    const pivotValue = this[pivotIndex];
-    swap(this, right, pivotIndex);
-    let storeIndex = left;
-    for (let i = left; i < right; ++i) {
-      if (comparator(this[i], pivotValue) < 0) {
-        swap(this, storeIndex, i);
-        ++storeIndex;
-      }
-    }
-    swap(this, right, storeIndex);
-    return storeIndex;
-  }
-};
-Object.defineProperty(Array.prototype, 'partition', partition);
-Object.defineProperty(Uint32Array.prototype, 'partition', partition);
-
-const sortRange = {
-  /**
-     * @param {function(number, number): number} comparator
-     * @param {number} leftBound
-     * @param {number} rightBound
-     * @param {number} sortWindowLeft
-     * @param {number} sortWindowRight
-     * @return {!Array.<number>}
-     * @this {Array.<number>}
-     */
-  value: function(comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight) {
-    function quickSortRange(array, comparator, left, right, sortWindowLeft, sortWindowRight) {
-      if (right <= left)
-        return;
-      const pivotIndex = Math.floor(Math.random() * (right - left)) + left;
-      const pivotNewIndex = array.partition(comparator, left, right, pivotIndex);
-      if (sortWindowLeft < pivotNewIndex)
-        quickSortRange(array, comparator, left, pivotNewIndex - 1, sortWindowLeft, sortWindowRight);
-      if (pivotNewIndex < sortWindowRight)
-        quickSortRange(array, comparator, pivotNewIndex + 1, right, sortWindowLeft, sortWindowRight);
-    }
-    if (leftBound === 0 && rightBound === (this.length - 1) && sortWindowLeft === 0 && sortWindowRight >= rightBound)
-      this.sort(comparator);
-    else
-      quickSortRange(this, comparator, leftBound, rightBound, sortWindowLeft, sortWindowRight);
-    return this;
-  }
-};
-Object.defineProperty(Array.prototype, 'sortRange', sortRange);
-Object.defineProperty(Uint32Array.prototype, 'sortRange', sortRange);
-})();
-
-Object.defineProperty(Array.prototype, 'stableSort', {
-  /**
-   * @param {function(?T, ?T): number=} comparator
-   * @return {!Array.<?T>}
-   * @this {Array.<?T>}
-   * @template T
-   */
-  value: function(comparator) {
-    function defaultComparator(a, b) {
-      return a < b ? -1 : (a > b ? 1 : 0);
-    }
-    comparator = comparator || defaultComparator;
-
-    const indices = new Array(this.length);
-    for (let i = 0; i < this.length; ++i)
-      indices[i] = i;
-    const self = this;
-    /**
-     * @param {number} a
-     * @param {number} b
-     * @return {number}
-     */
-    function indexComparator(a, b) {
-      const result = comparator(self[a], self[b]);
-      return result ? result : a - b;
-    }
-    indices.sort(indexComparator);
-
-    for (let i = 0; i < this.length; ++i) {
-      if (indices[i] < 0 || i === indices[i])
-        continue;
-      let cyclical = i;
-      const saved = this[i];
-      while (true) {
-        const next = indices[cyclical];
-        indices[cyclical] = -1;
-        if (next === i) {
-          this[cyclical] = saved;
-          break;
-        } else {
-          this[cyclical] = this[next];
-          cyclical = next;
-        }
-      }
-    }
-    return this;
-  }
-});
-
-Object.defineProperty(Array.prototype, 'qselect', {
-  /**
-   * @param {number} k
-   * @param {function(number, number): number=} comparator
-   * @return {number|undefined}
-   * @this {Array.<number>}
-   */
-  value: function(k, comparator) {
-    if (k < 0 || k >= this.length)
-      return;
-    if (!comparator) {
-      comparator = function(a, b) {
-        return a - b;
-      };
-    }
-
-    let low = 0;
-    let high = this.length - 1;
-    for (;;) {
-      const pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2));
-      if (pivotPosition === k)
-        return this[k];
-      else if (pivotPosition > k)
-        high = pivotPosition - 1;
-      else
-        low = pivotPosition + 1;
-    }
-  }
-});
-
-Object.defineProperty(Array.prototype, 'lowerBound', {
-  /**
-   * Return index of the leftmost element that is equal or greater
-   * than the specimen object. If there's no such element (i.e. all
-   * elements are smaller than the specimen) returns right bound.
-   * The function works for sorted array.
-   * When specified, |left| (inclusive) and |right| (exclusive) indices
-   * define the search window.
-   *
-   * @param {!T} object
-   * @param {function(!T,!S):number=} comparator
-   * @param {number=} left
-   * @param {number=} right
-   * @return {number}
-   * @this {Array.<!S>}
-   * @template T,S
-   */
-  value: function(object, comparator, left, right) {
-    function defaultComparator(a, b) {
-      return a < b ? -1 : (a > b ? 1 : 0);
-    }
-    comparator = comparator || defaultComparator;
-    let l = left || 0;
-    let r = right !== undefined ? right : this.length;
-    while (l < r) {
-      const m = (l + r) >> 1;
-      if (comparator(object, this[m]) > 0)
-        l = m + 1;
-      else
-        r = m;
-    }
-    return r;
-  }
-});
-
-Object.defineProperty(Array.prototype, 'upperBound', {
-  /**
-   * Return index of the leftmost element that is greater
-   * than the specimen object. If there's no such element (i.e. all
-   * elements are smaller or equal to the specimen) returns right bound.
-   * The function works for sorted array.
-   * When specified, |left| (inclusive) and |right| (exclusive) indices
-   * define the search window.
-   *
-   * @param {!T} object
-   * @param {function(!T,!S):number=} comparator
-   * @param {number=} left
-   * @param {number=} right
-   * @return {number}
-   * @this {Array.<!S>}
-   * @template T,S
-   */
-  value: function(object, comparator, left, right) {
-    function defaultComparator(a, b) {
-      return a < b ? -1 : (a > b ? 1 : 0);
-    }
-    comparator = comparator || defaultComparator;
-    let l = left || 0;
-    let r = right !== undefined ? right : this.length;
-    while (l < r) {
-      const m = (l + r) >> 1;
-      if (comparator(object, this[m]) >= 0)
-        l = m + 1;
-      else
-        r = m;
-    }
-    return r;
-  }
-});
-
-Object.defineProperty(Uint32Array.prototype, 'lowerBound', {value: Array.prototype.lowerBound});
-
-Object.defineProperty(Uint32Array.prototype, 'upperBound', {value: Array.prototype.upperBound});
-
-Object.defineProperty(Int32Array.prototype, 'lowerBound', {value: Array.prototype.lowerBound});
-
-Object.defineProperty(Int32Array.prototype, 'upperBound', {value: Array.prototype.upperBound});
-
-Object.defineProperty(Float64Array.prototype, 'lowerBound', {value: Array.prototype.lowerBound});
-
-Object.defineProperty(Array.prototype, 'binaryIndexOf', {
-  /**
-   * @param {!T} value
-   * @param {function(!T,!S):number} comparator
-   * @return {number}
-   * @this {Array.<!S>}
-   * @template T,S
-   */
-  value: function(value, comparator) {
-    const index = this.lowerBound(value, comparator);
-    return index < this.length && comparator(value, this[index]) === 0 ? index : -1;
-  }
-});
-
-Object.defineProperty(Array.prototype, 'select', {
-  /**
-   * @param {string} field
-   * @return {!Array.<!T>}
-   * @this {Array.<!Object.<string,!T>>}
-   * @template T
-   */
-  value: function(field) {
-    const result = new Array(this.length);
-    for (let i = 0; i < this.length; ++i)
-      result[i] = this[i][field];
-    return result;
-  }
-});
-
-Object.defineProperty(Array.prototype, 'peekLast', {
-  /**
-   * @return {!T|undefined}
-   * @this {Array.<!T>}
-   * @template T
-   */
-  value: function() {
-    return this[this.length - 1];
-  }
-});
-
-(function() {
-  /**
-   * @param {!Array.<T>} array1
-   * @param {!Array.<T>} array2
-   * @param {function(T,T):number} comparator
-   * @param {boolean} mergeNotIntersect
-   * @return {!Array.<T>}
-   * @template T
-   */
-  function mergeOrIntersect(array1, array2, comparator, mergeNotIntersect) {
-    const result = [];
-    let i = 0;
-    let j = 0;
-    while (i < array1.length && j < array2.length) {
-      const compareValue = comparator(array1[i], array2[j]);
-      if (mergeNotIntersect || !compareValue)
-        result.push(compareValue <= 0 ? array1[i] : array2[j]);
-      if (compareValue <= 0)
-        i++;
-      if (compareValue >= 0)
-        j++;
-    }
-    if (mergeNotIntersect) {
-      while (i < array1.length)
-        result.push(array1[i++]);
-      while (j < array2.length)
-        result.push(array2[j++]);
-    }
-    return result;
-  }
-
-  Object.defineProperty(Array.prototype, 'intersectOrdered', {
-    /**
-     * @param {!Array.<T>} array
-     * @param {function(T,T):number} comparator
-     * @return {!Array.<T>}
-     * @this {!Array.<T>}
-     * @template T
-     */
-    value: function(array, comparator) {
-      return mergeOrIntersect(this, array, comparator, false);
-    }
-  });
-
-  Object.defineProperty(Array.prototype, 'mergeOrdered', {
-    /**
-     * @param {!Array.<T>} array
-     * @param {function(T,T):number} comparator
-     * @return {!Array.<T>}
-     * @this {!Array.<T>}
-     * @template T
-     */
-    value: function(array, comparator) {
-      return mergeOrIntersect(this, array, comparator, true);
-    }
-  });
-})();
-
-/**
- * @param {string} format
- * @param {...*} var_arg
- * @return {string}
- */
-String.sprintf = function(format, var_arg) {
-  return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
-};
-
-/**
- * @param {string} format
- * @param {!Object.<string, function(string, ...):*>} formatters
- * @return {!Array.<!Object>}
- */
-String.tokenizeFormatString = function(format, formatters) {
-  const tokens = [];
-  let substitutionIndex = 0;
-
-  function addStringToken(str) {
-    if (tokens.length && tokens[tokens.length - 1].type === 'string')
-      tokens[tokens.length - 1].value += str;
-    else
-      tokens.push({type: 'string', value: str});
-  }
-
-  function addSpecifierToken(specifier, precision, substitutionIndex) {
-    tokens.push({type: 'specifier', specifier: specifier, precision: precision, substitutionIndex: substitutionIndex});
-  }
-
-  let index = 0;
-  for (let precentIndex = format.indexOf('%', index); precentIndex !== -1; precentIndex = format.indexOf('%', index)) {
-    if (format.length === index)  // unescaped % sign at the end of the format string.
-      break;
-    addStringToken(format.substring(index, precentIndex));
-    index = precentIndex + 1;
-
-    if (format[index] === '%') {
-      // %% escape sequence.
-      addStringToken('%');
-      ++index;
-      continue;
-    }
-
-    if (String.isDigitAt(format, index)) {
-      // The first character is a number, it might be a substitution index.
-      const number = parseInt(format.substring(index), 10);
-      while (String.isDigitAt(format, index))
-        ++index;
-
-      // If the number is greater than zero and ends with a "$",
-      // then this is a substitution index.
-      if (number > 0 && format[index] === '$') {
-        substitutionIndex = (number - 1);
-        ++index;
-      }
-    }
-
-    let precision = -1;
-    if (format[index] === '.') {
-      // This is a precision specifier. If no digit follows the ".",
-      // then the precision should be zero.
-      ++index;
-      precision = parseInt(format.substring(index), 10);
-      if (isNaN(precision))
-        precision = 0;
-
-      while (String.isDigitAt(format, index))
-        ++index;
-    }
-
-    if (!(format[index] in formatters)) {
-      addStringToken(format.substring(precentIndex, index + 1));
-      ++index;
-      continue;
-    }
-
-    addSpecifierToken(format[index], precision, substitutionIndex);
-
-    ++substitutionIndex;
-    ++index;
-  }
-
-  addStringToken(format.substring(index));
-
-  return tokens;
-};
-
-String.standardFormatters = {
-  /**
-   * @return {number}
-   */
-  d: function(substitution) {
-    return !isNaN(substitution) ? substitution : 0;
-  },
-
-  /**
-   * @return {number}
-   */
-  f: function(substitution, token) {
-    if (substitution && token.precision > -1)
-      substitution = substitution.toFixed(token.precision);
-    return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
-  },
-
-  /**
-   * @return {string}
-   */
-  s: function(substitution) {
-    return substitution;
-  }
-};
-
-/**
- * @param {string} format
- * @param {!Array.<*>} substitutions
- * @return {string}
- */
-String.vsprintf = function(format, substitutions) {
-  return String
-      .format(
-          format, substitutions, String.standardFormatters, '',
-          function(a, b) {
-            return a + b;
-          })
-      .formattedResult;
-};
-
-/**
- * @param {string} format
- * @param {?ArrayLike} substitutions
- * @param {!Object.<string, function(string, ...):Q>} formatters
- * @param {!T} initialValue
- * @param {function(T, Q): T|undefined} append
- * @param {!Array.<!Object>=} tokenizedFormat
- * @return {!{formattedResult: T, unusedSubstitutions: ?ArrayLike}};
- * @template T, Q
- */
-String.format = function(format, substitutions, formatters, initialValue, append, tokenizedFormat) {
-  if (!format || !substitutions || !substitutions.length)
-    return {formattedResult: append(initialValue, format), unusedSubstitutions: substitutions};
-
-  function prettyFunctionName() {
-    return 'String.format("' + format + '", "' + Array.prototype.join.call(substitutions, '", "') + '")';
-  }
-
-  function warn(msg) {
-    console.warn(prettyFunctionName() + ': ' + msg);
-  }
-
-  function error(msg) {
-    console.error(prettyFunctionName() + ': ' + msg);
-  }
-
-  let result = initialValue;
-  const tokens = tokenizedFormat || String.tokenizeFormatString(format, formatters);
-  const usedSubstitutionIndexes = {};
-
-  for (let i = 0; i < tokens.length; ++i) {
-    const token = tokens[i];
-
-    if (token.type === 'string') {
-      result = append(result, token.value);
-      continue;
-    }
-
-    if (token.type !== 'specifier') {
-      error('Unknown token type "' + token.type + '" found.');
-      continue;
-    }
-
-    if (token.substitutionIndex >= substitutions.length) {
-      // If there are not enough substitutions for the current substitutionIndex
-      // just output the format specifier literally and move on.
-      error(
-          'not enough substitution arguments. Had ' + substitutions.length + ' but needed ' +
-          (token.substitutionIndex + 1) + ', so substitution was skipped.');
-      result = append(result, '%' + (token.precision > -1 ? token.precision : '') + token.specifier);
-      continue;
-    }
-
-    usedSubstitutionIndexes[token.substitutionIndex] = true;
-
-    if (!(token.specifier in formatters)) {
-      // Encountered an unsupported format character, treat as a string.
-      warn('unsupported format character \u201C' + token.specifier + '\u201D. Treating as a string.');
-      result = append(result, substitutions[token.substitutionIndex]);
-      continue;
-    }
-
-    result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
-  }
-
-  const unusedSubstitutions = [];
-  for (let i = 0; i < substitutions.length; ++i) {
-    if (i in usedSubstitutionIndexes)
-      continue;
-    unusedSubstitutions.push(substitutions[i]);
-  }
-
-  return {formattedResult: result, unusedSubstitutions: unusedSubstitutions};
-};
-
-/**
- * @param {string} query
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
- * @return {!RegExp}
- */
-function createSearchRegex(query, caseSensitive, isRegex) {
-  const regexFlags = caseSensitive ? 'g' : 'gi';
-  let regexObject;
-
-  if (isRegex) {
-    try {
-      regexObject = new RegExp(query, regexFlags);
-    } catch (e) {
-      // Silent catch.
-    }
-  }
-
-  if (!regexObject)
-    regexObject = createPlainTextSearchRegex(query, regexFlags);
-
-  return regexObject;
-}
-
-/**
- * @param {string} query
- * @param {string=} flags
- * @return {!RegExp}
- */
-function createPlainTextSearchRegex(query, flags) {
-  // This should be kept the same as the one in StringUtil.cpp.
-  const regexSpecialCharacters = String.regexSpecialCharacters();
-  let regex = '';
-  for (let i = 0; i < query.length; ++i) {
-    const c = query.charAt(i);
-    if (regexSpecialCharacters.indexOf(c) !== -1)
-      regex += '\\';
-    regex += c;
-  }
-  return new RegExp(regex, flags || '');
-}
-
-/**
- * @param {!RegExp} regex
- * @param {string} content
- * @return {number}
- */
-function countRegexMatches(regex, content) {
-  let text = content;
-  let result = 0;
-  let match;
-  while (text && (match = regex.exec(text))) {
-    if (match[0].length > 0)
-      ++result;
-    text = text.substring(match.index + 1);
-  }
-  return result;
-}
-
-/**
- * @param {number} spacesCount
- * @return {string}
- */
-function spacesPadding(spacesCount) {
-  return '\u00a0'.repeat(spacesCount);
-}
-
-/**
- * @param {number} value
- * @param {number} symbolsCount
- * @return {string}
- */
-function numberToStringWithSpacesPadding(value, symbolsCount) {
-  const numberString = value.toString();
-  const paddingLength = Math.max(0, symbolsCount - numberString.length);
-  return spacesPadding(paddingLength) + numberString;
-}
-
-/**
- * @return {!Array.<T>}
- * @template T
- */
-Set.prototype.valuesArray = function() {
-  return Array.from(this.values());
-};
-
-/**
- * @return {?T}
- * @template T
- */
-Set.prototype.firstValue = function() {
-  if (!this.size)
-    return null;
-  return this.values().next().value;
-};
-
-/**
- * @param {!Iterable<T>|!Array<!T>} iterable
- * @template T
- */
-Set.prototype.addAll = function(iterable) {
-  for (const e of iterable)
-    this.add(e);
-};
-
-/**
- * @param {!Iterable<T>|!Array<!T>} iterable
- * @return {boolean}
- * @template T
- */
-Set.prototype.containsAll = function(iterable) {
-  for (const e of iterable) {
-    if (!this.has(e))
-      return false;
-  }
-  return true;
-};
-
-/**
- * @return {T}
- * @template T
- */
-Map.prototype.remove = function(key) {
-  const value = this.get(key);
-  this.delete(key);
-  return value;
-};
-
-/**
- * @return {!Array<!VALUE>}
- */
-Map.prototype.valuesArray = function() {
-  return Array.from(this.values());
-};
-
-/**
- * @return {!Array<!KEY>}
- */
-Map.prototype.keysArray = function() {
-  return Array.from(this.keys());
-};
-
-/**
- * @return {!Multimap<!KEY, !VALUE>}
- */
-Map.prototype.inverse = function() {
-  const result = new Multimap();
-  for (const key of this.keys()) {
-    const value = this.get(key);
-    result.set(value, key);
-  }
-  return result;
-};
-
-/**
- * @constructor
- * @template K, V
- */
-var Multimap = function() {  // eslint-disable-line
-  /** @type {!Map.<K, !Set.<!V>>} */
-  this._map = new Map();
-};
-
-Multimap.prototype = {
-  /**
-   * @param {K} key
-   * @param {V} value
-   */
-  set: function(key, value) {
-    let set = this._map.get(key);
-    if (!set) {
-      set = new Set();
-      this._map.set(key, set);
-    }
-    set.add(value);
-  },
-
-  /**
-   * @param {K} key
-   * @return {!Set.<!V>}
-   */
-  get: function(key) {
-    let result = this._map.get(key);
-    if (!result)
-      result = new Set();
-    return result;
-  },
-
-  /**
-   * @param {K} key
-   * @return {boolean}
-   */
-  has: function(key) {
-    return this._map.has(key);
-  },
-
-  /**
-   * @param {K} key
-   * @param {V} value
-   * @return {boolean}
-   */
-  hasValue: function(key, value) {
-    const set = this._map.get(key);
-    if (!set)
-      return false;
-    return set.has(value);
-  },
-
-  /**
-   * @return {number}
-   */
-  get size() {
-    return this._map.size;
-  },
-
-  /**
-   * @param {K} key
-   * @param {V} value
-   * @return {boolean}
-   */
-  delete: function(key, value) {
-    const values = this.get(key);
-    if (!values)
-      return false;
-    const result = values.delete(value);
-    if (!values.size)
-      this._map.delete(key);
-    return result;
-  },
-
-  /**
-   * @param {K} key
-   */
-  deleteAll: function(key) {
-    this._map.delete(key);
-  },
-
-  /**
-   * @return {!Array.<K>}
-   */
-  keysArray: function() {
-    return this._map.keysArray();
-  },
-
-  /**
-   * @return {!Array.<!V>}
-   */
-  valuesArray: function() {
-    const result = [];
-    const keys = this.keysArray();
-    for (let i = 0; i < keys.length; ++i)
-      result.pushAll(this.get(keys[i]).valuesArray());
-    return result;
-  },
-
-  clear: function() {
-    this._map.clear();
-  }
-};
-
-/**
- * @param {string} url
- * @return {!Promise.<string>}
- */
-function loadXHR(url) {
-  return new Promise(load);
-
-  function load(successCallback, failureCallback) {
-    function onReadyStateChanged() {
-      if (xhr.readyState !== XMLHttpRequest.DONE)
-        return;
-      if (xhr.status !== 200) {
-        xhr.onreadystatechange = null;
-        failureCallback(new Error(xhr.status));
-        return;
-      }
-      xhr.onreadystatechange = null;
-      successCallback(xhr.responseText);
-    }
-
-    const xhr = new XMLHttpRequest();
-    xhr.withCredentials = false;
-    xhr.open('GET', url, true);
-    xhr.onreadystatechange = onReadyStateChanged;
-    xhr.send(null);
-  }
-}
-
-/**
- * @param {*} value
- */
-function suppressUnused(value) {
-}
-
-/**
- * @param {function()} callback
- * @return {number}
- */
-self.setImmediate = function(callback) {
-  const args = [...arguments].slice(1);
-  Promise.resolve().then(() => callback(...args));
-  return 0;
-};
-
-/**
- * @param {function(...?)} callback
- * @return {!Promise.<T>}
- * @template T
- */
-Promise.prototype.spread = function(callback) {
-  return this.then(spreadPromise);
-
-  function spreadPromise(arg) {
-    return callback.apply(null, arg);
-  }
-};
-
-/**
- * @param {T} defaultValue
- * @return {!Promise.<T>}
- * @template T
- */
-Promise.prototype.catchException = function(defaultValue) {
-  return this.catch(function(error) {
-    console.error(error);
-    return defaultValue;
-  });
-};
-
-/**
- * @param {!Map<number, ?>} other
- * @param {function(!VALUE,?):boolean} isEqual
- * @return {!{removed: !Array<!VALUE>, added: !Array<?>, equal: !Array<!VALUE>}}
- * @this {Map<number, VALUE>}
- */
-Map.prototype.diff = function(other, isEqual) {
-  const leftKeys = this.keysArray();
-  const rightKeys = other.keysArray();
-  leftKeys.sort((a, b) => a - b);
-  rightKeys.sort((a, b) => a - b);
-
-  const removed = [];
-  const added = [];
-  const equal = [];
-  let leftIndex = 0;
-  let rightIndex = 0;
-  while (leftIndex < leftKeys.length && rightIndex < rightKeys.length) {
-    const leftKey = leftKeys[leftIndex];
-    const rightKey = rightKeys[rightIndex];
-    if (leftKey === rightKey && isEqual(this.get(leftKey), other.get(rightKey))) {
-      equal.push(this.get(leftKey));
-      ++leftIndex;
-      ++rightIndex;
-      continue;
-    }
-    if (leftKey <= rightKey) {
-      removed.push(this.get(leftKey));
-      ++leftIndex;
-      continue;
-    }
-    added.push(other.get(rightKey));
-    ++rightIndex;
-  }
-  while (leftIndex < leftKeys.length) {
-    const leftKey = leftKeys[leftIndex++];
-    removed.push(this.get(leftKey));
-  }
-  while (rightIndex < rightKeys.length) {
-    const rightKey = rightKeys[rightIndex++];
-    added.push(other.get(rightKey));
-  }
-  return {added: added, removed: removed, equal: equal};
-};
-
-/**
- * TODO: move into its own module
- * @param {function()} callback
- * @suppressGlobalPropertiesCheck
- */
-function runOnWindowLoad(callback) {
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  function windowLoaded() {
-    self.removeEventListener('DOMContentLoaded', windowLoaded, false);
-    callback();
-  }
-
-  if (document.readyState === 'complete' || document.readyState === 'interactive')
-    callback();
-  else
-    self.addEventListener('DOMContentLoaded', windowLoaded, false);
-}
-
-const _singletonSymbol = Symbol('singleton');
-
-/**
- * @template T
- * @param {function(new:T, ...)} constructorFunction
- * @return {!T}
- */
-function singleton(constructorFunction) {
-  if (_singletonSymbol in constructorFunction)
-    return constructorFunction[_singletonSymbol];
-  const instance = new constructorFunction();
-  constructorFunction[_singletonSymbol] = instance;
-  return instance;
-}
diff --git a/front_end/product_registry/BadgePool.js b/front_end/product_registry/BadgePool.js
deleted file mode 100644
index c5c06a9..0000000
--- a/front_end/product_registry/BadgePool.js
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-ProductRegistry.BadgePool = class {
-  /**
-   * @param {boolean=} forceShow
-   */
-  constructor(forceShow) {
-    this._showTitles = false;
-    /** @type {!Map<!Element, function():!Promise<!Common.ParsedURL>>} */
-    this._badgeElements = new Map();
-    if (!forceShow) {
-      this._setting = Common.settings.moduleSetting('product_registry.badges-visible');
-      this._setting.addChangeListener(this._settingUpdated.bind(this));
-      if (this._setting.get())
-        Host.userMetrics.actionTaken(Host.UserMetrics.Action.ShowedThirdPartyBadges);
-    }
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setShowTitles(value) {
-    this._showTitles = value;
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   * @return {!Element}
-   */
-  badgeForFrame(frame) {
-    return this._badgeForFrameOrUrl(this._resolveUrl.bind(this, frame));
-  }
-
-  /**
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {!Element}
-   */
-  badgeForURL(parsedUrl) {
-    return this._badgeForFrameOrUrl(() => Promise.resolve(parsedUrl));
-  }
-
-  reset() {
-    this._badgeElements.clear();
-  }
-
-  /**
-   * @param {function():!Promise<!Common.ParsedURL>} urlResolver
-   * @return {!Element}
-   */
-  _badgeForFrameOrUrl(urlResolver) {
-    const element = createElementWithClass('span', 'hidden');
-    const root = UI.createShadowRootWithCoreStyles(element, 'product_registry/badge.css');
-    const badgeElement = root.createChild('span');
-    badgeElement.classList.toggle('hide-badge-title', !this._showTitles);
-    badgeElement.addEventListener('mousedown', event => event.consume());
-    badgeElement.addEventListener('click', event => {
-      this._showPopup(badgeElement);
-      event.consume();
-    }, false);
-    this._badgeElements.set(badgeElement, urlResolver);
-    this._renderBadge(badgeElement);
-    return element;
-  }
-
-  /**
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @return {!Promise<!Common.ParsedURL>}
-   */
-  async _resolveUrl(frame) {
-    const registry = await ProductRegistry.instance();
-    let parsedUrl = new Common.ParsedURL(frame.url);
-    const entry = registry.entryForUrl(parsedUrl);
-    if (!entry) {
-      frame.findCreationCallFrame(callFrame => {
-        if (!callFrame.url)
-          return false;
-        parsedUrl = new Common.ParsedURL(callFrame.url);
-        return !!registry.entryForUrl(parsedUrl);
-      });
-    }
-    return parsedUrl;
-  }
-
-  /**
-   * @param {!Element} badgeElement
-   */
-  async _renderBadge(badgeElement) {
-    if (badgeElement.children.length || !this._isVisible(badgeElement)) {
-      this._updateBadgeElementVisibility(badgeElement);
-      return;
-    }
-
-    const parsedUrl = await this._badgeElements.get(badgeElement)();
-    const registry = await ProductRegistry.instance();
-    const entryName = parsedUrl && registry.nameForUrl(parsedUrl);
-    if (!entryName)
-      return;
-
-    const tokens = entryName.replace(/[a-z]*/g, '').split(' ');
-    let label;
-    if (tokens.length > 1)
-      label = tokens[0][0] + tokens[1][0];
-    else
-      label = entryName;
-
-    const iconElement = badgeElement.createChild('span', 'product-registry-badge monospace');
-    iconElement.setAttribute('data-initial', label.substring(0, 2).toUpperCase());
-    iconElement.title = entryName;
-    iconElement.style.backgroundColor = ProductRegistry.BadgePool.colorForEntryName(entryName);
-
-    badgeElement.createChild('span', 'product-registry-badge-title').textContent = entryName;
-    this._updateBadgeElementVisibility(badgeElement);
-  }
-
-  _settingUpdated() {
-    for (const badgeElement of this._badgeElements.keys())
-      this._renderBadge(badgeElement);
-  }
-
-  /**
-   * @param {!Element} badgeElement
-   * @return {boolean}
-   */
-  _isVisible(badgeElement) {
-    return !this._setting || this._setting.get();
-  }
-
-  /**
-   * @param {!Element} badgeElement
-   */
-  _updateBadgeElementVisibility(badgeElement) {
-    badgeElement.parentNodeOrShadowHost().parentNodeOrShadowHost().classList.toggle(
-        'hidden', !this._isVisible(badgeElement));
-  }
-
-  /**
-   * @param {!Element} badgeElement
-   */
-  async _showPopup(badgeElement) {
-    if (!this._badgeElements.has(badgeElement))
-      return;
-
-    const registry = await ProductRegistry.instance();
-    const parsedUrl = await this._badgeElements.get(badgeElement)();
-    const entryName = registry.nameForUrl(parsedUrl);
-
-    const element = createElement('div');
-    const root = UI.createShadowRootWithCoreStyles(element, 'product_registry/popup.css');
-    const popupElement = root.createChild('div', 'product-registry-popup');
-    const domainElement = popupElement.createChild('div', 'product-registry-domain');
-    domainElement.textContent = parsedUrl.domain();
-    const entryNameElement = popupElement.createChild('div', 'product-registry-name');
-    entryNameElement.textContent = entryName;
-    const reportLink =
-        'https://docs.google.com/forms/d/e/1FAIpQLSchz2FdcQ-rRllzl8BbhWaTRRY-12BpPjW6Hr9e1-BpCA083w/viewform' +
-        '?entry_1425918171=' + encodeURIComponent((parsedUrl.domain() + parsedUrl.path).substr(0, 100));
-    popupElement.appendChild(UI.XLink.create(reportLink, 'Report mismatch', 'product-registry-link'));
-
-    const dialog = new UI.Dialog();
-    dialog.setContentAnchorBox(badgeElement.boxInWindow());
-    dialog.contentElement.appendChild(element);
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.setAnchorBehavior(UI.GlassPane.AnchorBehavior.PreferTop);
-    dialog.addCloseButton();
-    dialog.show(/** @type {!Document} */ (badgeElement.ownerDocument));
-  }
-
-  /**
-   * @param {string} entryName
-   * @return {string}
-   */
-  static colorForEntryName(entryName) {
-    if (!ProductRegistry.BadgePool._colorGenerator) {
-      ProductRegistry.BadgePool._colorGenerator =
-          new Common.Color.Generator({min: 30, max: 330}, {min: 50, max: 80, count: 3}, 80);
-    }
-    return ProductRegistry.BadgePool._colorGenerator.colorForID(entryName);
-  }
-};
diff --git a/front_end/product_registry/ProductRegistry.js b/front_end/product_registry/ProductRegistry.js
deleted file mode 100644
index 6067da6..0000000
--- a/front_end/product_registry/ProductRegistry.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @return {!Promise<!ProductRegistry.Registry>}
- */
-ProductRegistry.instance = function() {
-  const extension = self.runtime.extension(ProductRegistry.Registry);
-  if (extension)
-    return extension.instance();
-  return Promise.resolve(self.singleton(ProductRegistry.RegistryStub));
-};
-
-/**
- * @interface
- */
-ProductRegistry.Registry = function() {};
-
-ProductRegistry.Registry.prototype = {
-  /**
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?string}
-   */
-  nameForUrl: function(parsedUrl) {},
-
-  /**
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?ProductRegistry.Registry.ProductEntry}
-   */
-  entryForUrl: function(parsedUrl) {},
-
-  /**
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?number}
-   */
-  typeForUrl: function(parsedUrl) {}
-};
-
-/**
- * @implements {ProductRegistry.Registry}
- */
-ProductRegistry.RegistryStub = class {
-  /**
-   * @override
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?string}
-   */
-  nameForUrl(parsedUrl) {
-    return null;
-  }
-
-  /**
-   * @override
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?ProductRegistry.Registry.ProductEntry}
-   */
-  entryForUrl(parsedUrl) {
-    return null;
-  }
-
-  /**
-   * @override
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?number}
-   */
-  typeForUrl(parsedUrl) {
-    return null;
-  }
-};
-
-/** @typedef {!{name: string, type: ?number}} */
-ProductRegistry.Registry.ProductEntry;
diff --git a/front_end/product_registry/badge.css b/front_end/product_registry/badge.css
deleted file mode 100644
index 10c9e53..0000000
--- a/front_end/product_registry/badge.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.product-registry-badge {
-  background-color: rgba(0, 0, 0, 0.2);
-  border-radius: 2px;
-  padding: 1px 2px;
-  white-space: pre;
-  cursor: pointer;
-}
-
-.product-registry-badge::before {
-  content: attr(data-initial);
-  color: #222;
-}
-
-.hide-badge-title .product-registry-badge-title {
-  display: none;
-}
-
-.product-registry-badge-title {
-  padding-left: 4px;
-}
\ No newline at end of file
diff --git a/front_end/product_registry/module.json b/front_end/product_registry/module.json
deleted file mode 100644
index fc6f445..0000000
--- a/front_end/product_registry/module.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "setting",
-            "category": "Appearance",
-            "title": "Show third party URL badges",
-            "settingName": "product_registry.badges-visible",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show third party badges"
-                },
-                {
-                    "value": false,
-                    "title": "Do not show third party badges"
-                }
-            ]
-        }
-    ],
-    "dependencies": [
-        "common",
-        "sdk",
-        "ui"
-    ],
-    "scripts": [
-        "BadgePool.js",
-        "ProductRegistry.js"
-    ],
-    "resources": [
-        "badge.css",
-        "popup.css"
-    ]
-}
diff --git a/front_end/product_registry/popup.css b/front_end/product_registry/popup.css
deleted file mode 100644
index 9929aee..0000000
--- a/front_end/product_registry/popup.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.product-registry-popup {
-    background-color: white;
-    padding: 15px 45px 15px 15px;
-    border-radius: 4px;
-    white-space: nowrap;
-    box-shadow: 0px 1px 2px 0px gray;
-}
-
-.product-registry-domain {
-    font-weight: bold;
-}
-
-.product-registry-name {
-    padding: 10px 0;
-}
-
-.product-registry-link {
-    display: block;
-}
-
-div[is=dt-close-button] {
-  position: absolute;
-  top: 5px;
-  right: 5px;
-}
diff --git a/front_end/product_registry_impl/ProductRegistryData.js b/front_end/product_registry_impl/ProductRegistryData.js
deleted file mode 100644
index b040ac0..0000000
--- a/front_end/product_registry_impl/ProductRegistryData.js
+++ /dev/null
@@ -1,6778 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// clang-format off
-/* eslint-disable */
-ProductRegistryImpl.register([
-  "AppNexus Open AdStream",
-  "Interworks Media, Inc.",
-  "Action Exchange, Inc.",
-  "TripAdvisor LLC",
-  "FSN ASIA PRIVATE LIMITED",
-  "iPromote",
-  "33Across Inc.",
-  "8thBridge",
-  "A9",
-  "AdGenie",
-  "Affilinet GmbH",
-  "Eulerian Technologies SARL",
-  "Conversant Ad Server",
-  "Napster Luxemburg SARL",
-  "Wize Commerce, Inc.",
-  "Research Now Limited",
-  "Spartoo",
-  "eBay",
-  "advanced STORE GmbH",
-  "Madeleine Mode GmbH",
-  "Telefonica UK / O2 UK",
-  "Tamome",
-  "TUI UK Limited",
-  "iJento",
-  "McCann Erikson",
-  "Tribes Research Limited",
-  "On Device Research Ltd.",
-  "SuperVista AG",
-  "National Lottery",
-  "Rakuten Display",
-  "Retailigence",
-  "Logly DSP",
-  "App-CM Inc.",
-  "Yahoo! Japan Corporation",
-  "Oggifinogi",
-  "PaperG",
-  "Public-Idées",
-  "The Trade Desk Inc.",
-  "Amazon",
-  "Airpush, Inc.",
-  "Clinch.co",
-  "F# Inc.",
-  "Transout Inc.",
-  "ADZIP",
-  "Adways SAS",
-  "Opera Mediaworks Inc.",
-  "DistroScale Inc.",
-  "Enzymic Consultancy",
-  "Fluct Inc.",
-  "Acuity Ads",
-  "iLead",
-  "Canned Banners LLC",
-  "AdBroker GmbH",
-  "InMind Opinion Media",
-  "Adcentric",
-  "AdClear GmbH",
-  "DeinDeal AG",
-  "Sixt Leasing SE",
-  "Air Berlin",
-  "Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper",
-  "Adform DSP",
-  "Adconion Media Group",
-  "Adform",
-  "Adition",
-  "Active Agent",
-  "mov.ad GmbH",
-  "AdJug",
-  "AdJuggler",
-  "AdKeeper",
-  "AdKnife",
-  "Adku",
-  "AdLantic Online Advertising",
-  "Adloox",
-  "adMarketplace",
-  "AdMotion",
-  "AdMotion USA Inc.",
-  "Digilant",
-  "Adnologies GmbH",
-  "Adometry by Google",
-  "Adperium BV",
-  "AdPredictive",
-  "Usemax",
-  "Adrime",
-  "AdRiver",
-  "Adroit Interactive",
-  "MediaMath Inc.",
-  "Campaign Monitor",
-  "Integral Ad Science Firewall",
-  "AdShuffle",
-  "ADSOVO",
-  "ADTECH GmbH",
-  "Adtelligence",
-  "Adverline",
-  "AOL Advertising.com",
-  "Adap.tv Inc. (AdX)",
-  "Convertro Inc",
-  "Tacoda",
-  "Digital Control GmbH (Advolution)",
-  "AdXcel",
-  "Alenty S.A.S",
-  "DoubleClick Bid Manager",
-  "BigaBid Media Ltd.",
-  "Cogo Labs, Inc.",
-  "AudienceProject",
-  "Rockabox Media Ltd",
-  "PocketMath",
-  "Kpsule",
-  "Immedium, Inc.",
-  "Fractional Media, LLC",
-  "Bonzai Digital Pvt. Ltd",
-  "Epic Combo Malta Ltd.",
-  "Quixey",
-  "YOOX NET-A-PORTER GROUP SPA",
-  "TapTap Networks S.L.",
-  "ComScore (AdXpose)",
-  "AdYard",
-  "Affectv",
-  "SET.tv",
-  "Adroit Digital Solutions (ADS)",
-  "AppNexus Inc",
-  "Adfusion",
-  "ARC Media Group",
-  "Semasio GmbH",
-  "Mojiva",
-  "Mocean mobile, Inc.",
-  "Phluant",
-  "AdSpirit",
-  "ConvertMedia Ltd.",
-  "ATK Media GmbH",
-  "Atlas",
-  "AudienceScience",
-  "BeWebMedia",
-  "Bidalpha Inc.",
-  "AdGear Technologies Inc.",
-  "BlueKai",
-  "Bluestreak",
-  "blurbIQ",
-  "Brand.net",
-  "Brandscreen Inc.",
-  "BrightRoll Inc.",
-  "Brightroll Inc.",
-  "Vindico",
-  "Spark Flow S.A.",
-  "Aarki, Inc.",
-  "SiteScout AdServer",
-  "Burst Media LLC d/b/a AdConductor",
-  "Advertising.com Dynamic Retargeter",
-  "NetAffiliation",
-  "C3 Metrics Inc.",
-  "CAPITALDATA (SARL)",
-  "e-Planning",
-  "Chango Inc.",
-  "Chango",
-  "Channel Intelligence",
-  "Chartbeat Inc",
-  "Choicestream Inc.",
-  "AddThis, Inc",
-  "Platform 161",
-  "ClickPoint",
-  "Cobalt Group",
-  "Cognitive Match Limited",
-  "Tagtoo Tech Limited",
-  "wayStorm Co., Ltd.",
-  "Collective Media LLC",
-  "ComScore Campaign Essentials (CE)",
-  "ComScore Validated Campaign Essentials (vCE)",
-  "VoiceFive (ComScore)",
-  "Connexity LLC",
-  "Constant Contact",
-  "ContextWeb Inc.",
-  "Conversive BV",
-  "IBM Digital Analytics",
-  "Crimtan",
-  "Criteo",
-  "D.A. Consortium Inc. (EffectiveOne)",
-  "Platform One",
-  "Dapper Inc.",
-  "DataXu Inc.",
-  "Aperture",
-  "Rakuten Attribution",
-  "AdAction",
-  "Demandbase Inc.",
-  "Omniture",
-  "Rovion, Inc.",
-  "AdHui.com LLC",
-  "Bidlab sp. z o.o",
-  "CyberAgent Inc.",
-  "Relay42 Technology B.V.",
-  "Nielsen Digital Ad Ratings (JS)",
-  "Nielsen (Audience Measurement Platform)",
-  "Nielsen OBE (Vizu)",
-  "Nielsen (Sales Effect)",
-  "Ohana Media India Private Limited",
-  "Avail Intelligence",
-  "Adobe Scene 7",
-  "Asda",
-  "Adsfactor Limited",
-  "Trademob GmbH",
-  "Zamplus Technology Co., Ltd.",
-  "Telemetry Limited",
-  "AdPilot",
-  "ebookers",
-  "Mashero GmbH",
-  "4wMarketPlace Srl",
-  "Meetic Partners",
-  "Adara Media",
-  "Adledge",
-  "Adledge: Ad Swapping",
-  "LifeStreet Corportation",
-  "AdCirrus",
-  "Dimestore",
-  "GfK SE",
-  "Conversant CRM",
-  "DoubleVerify Inc.",
-  "DoubleVerify Inc. (BrandShield): Ad Swapping",
-  "Dynamic Video LLC",
-  "Think RealTime, LLC",
-  "Effective Measure",
-  "Adobe Media Optimizer",
-  "Effiliation",
-  "EmediateAd",
-  "engage:BDR Inc.",
-  "Ghostery Enterprise",
-  "Experteer GmbH",
-  "Action Allocator",
-  "AdTraxx",
-  "eyeDemand",
-  "EyeReturn Marketing",
-  "EyeView Inc.",
-  "EyeView, Inc",
-  "Eyewonder Inc.",
-  "MLB Advanced Media, L.P.",
-  "Facilitate For Agencies (FFA)",
-  "Flashtalking",
-  "Hostelworld.com Limited",
-  "Knorex Pte. Ltd.",
-  "Flite Inc.",
-  "Forbes Media LLC",
-  "Scene Stealer Ltd.",
-  "FreakOut Inc.",
-  "FreeWheel",
-  "Fringe81 Inc.",
-  "Fringe81 - IBV",
-  "FuseBox Inc.",
-  "gemiusDirectEffect+",
-  "AdOcean Ltd",
-  "Intomart GfK (GfK Daphne)",
-  "Gigya",
-  "Global Market Insite Inc.",
-  "DoubleClick Campaign Manager",
-  "DoubleClick Bidder Pilot for Networks",
-  "DoubleClick for Publishers Premium",
-  "GroovinAds",
-  "Reddion",
-  "HQ GmbH",
-  "Performance Display Advertising",
-  "Avazu Inc.",
-  "Aerify Media",
-  "IClick Interactive Ltd.",
-  "iCrossing",
-  "Impact Engine Inc.",
-  "Inadco Inc.",
-  "Innity Singapore Pte Ltd.",
-  "Insight Express (Cross Media - Ignite)",
-  "intelliAd Media GmbH",
-  "DePauli AG",
-  "Intelliad",
-  "Genome",
-  "Intergi LLC dba PlaywireMedia",
-  "Intermundo Media LLC",
-  "Interpolls",
-  "Intelligent Reach (Intuitive Search Technologies)",
-  "IPONWEB Limited",
-  "JasperLabs Inc.",
-  "Jivox Corporation",
-  "Joinville AB",
-  "KliKKicom Oy",
-  "Komli Media Inc.",
-  "Koninklijke Luchtvaart Maatschappij N.V.",
-  "J.D. Power O2O",
-  "Kwanzoo Inc.",
-  "Legolas Media Inc.",
-  "Undertone Ad System (UAS)",
-  "LEVEL Studios",
-  "LinkedIn Corporation",
-  "Content Directions, Inc. dba Linkstorm",
-  "Liverail Inc.",
-  "Lotame Solutions Inc.",
-  "LucidMedia Networks Inc.",
-  "Magnetic Media Online Inc.",
-  "Mate1.com",
-  "MaxPoint Interactive Inc.",
-  "Media Armor Inc.",
-  "Xaxis, Inc",
-  "Dstillery",
-  "Rakuten MediaForge",
-  "Sizmek",
-  "MediaMind",
-  "Paypal",
-  "ZEDO Inc.",
-  "Contobox",
-  "Melt Tecnologia e Informatica S.A",
-  "MeMo2 / Hottraffic",
-  "DMA Institute dba Hottraffic",
-  "Mercado Livre.com Atividades de Internet Ltda",
-  "Merchenta Limited",
-  "Metapeople GmbH",
-  "MetrixLab B.V.",
-  "Mixpo Inc.",
-  "Monsoon Ads Pvt. Ltd.",
-  "Monster",
-  "neckermann.de GmbH",
-  "Ad.agio",
-  "Netmining LLC",
-  "AdoTube",
-  "Next Audience GmbH",
-  "Nextperf",
-  "Calibex",
-  "ViziAds for Advertisers",
-  "FinanceGenerator",
-  "Telstra Corporation",
-  "The Online Research Unit",
-  "Webling Pty Ltd",
-  "Lasoo Pty Ltd",
-  "Salefinder Ltd.",
-  "The Monkeys Pty Ltd",
-  "Louder Digital Pty Ltd",
-  "Publisher’s Internationale Pty Ltd",
-  "NowSpots",
-  "Ocapi",
-  "Predicta",
-  "Comune SA",
-  "EuroAds Group A/S",
-  "Hotwords Informação LTDA",
-  "uMotion",
-  "Google Zoo",
-  "Audience Manager",
-  "ONDCP",
-  "OpenX OnRamp",
-  "OpenX Ad Server",
-  "Parship",
-  "pauldirekt GmbH",
-  "Pictela Inc.",
-  "Pilot 1/0 GmbH & Co KG",
-  "Piximedia",
-  "Pointroll",
-  "Beijing PinYou Interactive Information Technology",
-  "YoYi Interactive",
-  "AdMaster",
-  "D.A.Consortium Beijing (Platform One China)",
-  "New Allyes Information Technology (winmax)",
-  "PurposeLab",
-  "Proclivity Systems",
-  "Viewbix",
-  "Quantcast Inc.",
-  "QuinStreet",
-  "Quisma GmbH",
-  "Quismatch / Quisma Tracker",
-  "Qwobl Inc.",
-  "RadiumOne Inc.",
-  "Core Audience, Inc",
-  "The Reach Group",
-  "revenue cloud",
-  "Register.it",
-  "ReleStar",
-  "Research Horizons LLC dba Phoenix Marketing",
-  "Retention Media Inc.",
-  "Suite 66",
-  "Dynamic Logic / Safecount (AdIndex)",
-  "BridgeTrack",
-  "adnanny.com GmbH",
-  "AdRoll",
-  "AdExtent",
-  "ShareThis Inc.",
-  "Shirtinator",
-  "Simplifi Holdings Inc.",
-  "Centro DSP",
-  "Smart Adserver",
-  "smartclip Holding AG",
-  "Snap Technologies Inc.",
-  "So-net Media Networks",
-  "SocialMedia.com",
-  "Content to Emotion (CTE)",
-  "Sociomantic.com",
-  "AdSpeed",
-  "Sophus3",
-  "Specific Media Inc.",
-  "Metrigo GmbH",
-  "SpongeCell",
-  "SpngeCell LLC",
-  "SpotXchange",
-  "Spotxchange",
-  "Encore Attribution Platform",
-  "Steelhouse",
-  "Strike New Media Limited",
-  "Struq Limited",
-  "SundaySky Inc.",
-  "Symphony Advanced Media",
-  "TagMan Ltd.",
-  "Taobao",
-  "Target.com",
-  "Teadma",
-  "BannerConnect BV",
-  "Teracent Corporation",
-  "The Travelers Indemnity Company",
-  "Videology",
-  "TNS Custom Research Inc.",
-  "TrackingSoft LLC",
-  "Tradedoubler",
-  "Epic Marketplace",
-  "Tribal Fusion",
-  "Triggit",
-  "True Ultimate Standards Everywhere Inc.",
-  "CarMax Business Services LLC",
-  "Charter Communications",
-  "General Nutrition Centers Inc.",
-  "Hamilton Beach",
-  "JacquieLawson.com",
-  "TruEffect",
-  "American Greetings",
-  "BlueMountain",
-  "Cardstore",
-  "Chemistry.com",
-  "Donald J Pliner",
-  "Gevalia",
-  "GSI Media",
-  "Match.com",
-  "Optimum Response",
-  "Oreck",
-  "Tassimo",
-  "uSwitch",
-  "TubeMogul Inc.",
-  "Tumri",
-  "iMarker",
-  "Turn Inc.",
-  "Twelvefold Media",
-  "Tynt",
-  "Unica an IBM Company",
-  "Unicast",
-  "UniQlick",
-  "United Virtualities",
-  "VideoHub",
-  "Visible Measures Corp.",
-  "Vizury Interactive Solutions Pvt. Ltd.",
-  "Markit On Demand (Adhesion)",
-  "WebMetro Inc",
-  "Weborama Campaign Manager (former name AdPerf)",
-  "Weborama Campaign Manager",
-  "Shopping Network",
-  "Shanghai WiseMedia Technology Co. Ltd.",
-  "XA.net",
-  "Xaxis LLC",
-  "Net Edge",
-  "Xplusone Solutions Inc.",
-  "Yahoo! Ad Exchange",
-  "Yahoo Ad Manager Plus",
-  "APT from Yahoo!",
-  "Yieldr",
-  "YuMe Inc.",
-  "Ebuzzing",
-  "Ziff Davis",
-  "DataPoint Media Inc.",
-  "Simplytics Limited",
-  "Makazi",
-  "Rich Relevance",
-  "MainADV",
-  "MediaV Advertising",
-  "MicroAd Inc.",
-  "Platform ID Inc.",
-  "Xrost",
-  "Sociocast Networks LLC D/B/A Velos",
-  "Trend Research",
-  "Black Swan Verification",
-  "Momentum K.K",
-  "Betgenius Limited",
-  "AT Internet",
-  "DataLab",
-  "Innovid Inc.",
-  "Adacado",
-  "NetDNA, LLC",
-  "Pipewave Inc.",
-  "US Media Consulting",
-  "SKYTOUCH TECHNOLOGY CO., LIMITED",
-  "Hanesbrands Direct LLC",
-  "A1platform",
-  "Agency.com",
-  "Adap.tv Inc. (AdWords/YouTube)",
-  "Fjord Technologies S.A.S.",
-  "Refined Ads",
-  "nugg.ad AG",
-  "Miaozhen Systems",
-  "Meetrics GmbH",
-  "Meetrics",
-  "Digital Control GmbH & Co. KG",
-  "Dedicated Media",
-  "Accuen",
-  "Pulse 360, Inc.",
-  "ZANOX AG",
-  "Webgains Ltd",
-  "Virgin Media Limited",
-  "MyBuys MyAds",
-  "VCCP Search LTD",
-  "Conversant Media",
-  "Up-Value GmbH & Co. KG",
-  "Unruly Media",
-  "Underdog Media LLC",
-  "SVG Media Pvt. Ltd.",
-  "TRAFFIQ LLC",
-  "TellApart Inc.",
-  "Shopzilla Inc.",
-  "Reactivpub",
-  "Netseer Inc.",
-  "eBay Enterprise",
-  "Goodway Group",
-  "Double Positive Marketing Group Inc.",
-  "Chitika Inc.",
-  "Scigineer Inc.",
-  "Sales Spider Inc.",
-  "Rocket Fuel Inc.",
-  "RTBlab",
-  "abilicom GmbH",
-  "Pulpo Media Inc",
-  "OneSpot",
-  "MyThings UK Ltd",
-  "Exactag",
-  "Kyocera Communication Systems Co. Ltd.",
-  "Beijing LangTaoJin Interactive",
-  "Conversant Mobile Media",
-  "MM1X.nl",
-  "Trivu Media Inc.",
-  "BlueCava Inc.",
-  "Beijing Gridsum Technology Co. Ltd.",
-  "Adsvana DSP",
-  "Target Performance",
-  "Content Spread",
-  "Datamind Effective Media",
-  "ScaleOut Inc.",
-  "Ensighten",
-  "Sony Electronics Inc.",
-  "Gravity Research and Development LTD",
-  "Project SunBlock",
-  "Novem sp. z o.o.",
-  "Econda GmbH",
-  "AdMaxim LLC",
-  "Alliance Health Networks",
-  "Adsame Advertising Co., Ltd",
-  "Guangzhou Shunfei Infomation Technology Corporatio",
-  "PK Online Ventures Limited",
-  "Bigpoint Gmbh",
-  "Mirapodo GmbH",
-  "Digitize New Media Ltd.",
-  "AdSage",
-  "Fingereach",
-  "Calvin Klein",
-  "Medialets Servo",
-  "Webmoblink Inc.",
-  "Moat Inc.",
-  "Bannerflow AB",
-  "Batch Media Gmbh",
-  "Twenga",
-  "TraceAd",
-  "Speed Shift Media",
-  "CCB Paris",
-  "Nielsen Digital Ad Ratings",
-  "OpenDSP",
-  "Beijing NetEase YouDao Computer System Co., Ltd.",
-  "Mediarithmics",
-  "RUN, INC.",
-  "Shanghai Menlo Network Technologies Co.,Ltd",
-  "Beijing Oasis Technology Co. Ltd (Mjoys)",
-  "NET-Metrix-Audit",
-  "New Allyes Information Technology (Quantone)",
-  "Resonate Networks, Inc",
-  "Triple Lift, Inc.",
-  "Indie Ads",
-  "Ocean Park Interactive",
-  "Impulse Media Pvt. Ltd.",
-  "CrowdTwist",
-  "Adzerk Inc.",
-  "Adtarget.me",
-  "Recruit Marketing Partners Co.,Ltd",
-  "Beijing Emar Online Technology Co.,Ltd",
-  "AdMagnet",
-  "Momondo A/S",
-  "DKK Agency",
-  "OneScreen Inc.",
-  "AdElement Media Solutions Pvt Ltd",
-  "Beijing Sheng Jin Lan Advertising Co., Ltd.",
-  "Adsit Media Advertising Ltd. Co., (AdMan)",
-  "AdMan",
-  "MicroAd Inc. (China)",
-  "Adfonic",
-  "OwnerIQ Inc.",
-  "Mobile Space Ltd",
-  "Jaduda GmbH",
-  "Omotenashi Banner",
-  "Infectious Media Ltd.",
-  "One97 Communications Limited (Ad Works)",
-  "Walk Light Media Inc.",
-  "AdBrite Inc.",
-  "Hi-Media",
-  "Adlabs",
-  "Arth Salutions",
-  "Konverta",
-  "Shopall",
-  "targeting360 GmbH",
-  "xplosion interactive GmbH",
-  "Hubrus LLC",
-  "Here Media Inc.",
-  "Silver Egg Technology Co., Ltd.",
-  "QuarticOn.com",
-  "Kavanga LLC",
-  "Vodafone D2 GmbH",
-  "Qubit Digital Ltd",
-  "NEORY GmbH",
-  "Populis Ireland Limited",
-  "LiquidM Technology GmbH",
-  "Celtra Inc.",
-  "Adfox",
-  "Accordant Media LLC",
-  "Fiksu DSP",
-  "MdotM, Inc.",
-  "TNS GALLUP ADFACT, ZAO",
-  "MicroAd Inc. (APAC)",
-  "ECRITEL SARL",
-  "Gloto Corp.",
-  "OOO GPM-Digital",
-  "adverserve digital advertising services",
-  "Abstract",
-  "Adscale GmbH",
-  "Weebly, Inc.",
-  "KPI Solutions Co.,Ltd.",
-  "LuckyBrand.com",
-  "Bedrijvenweb.nl",
-  "EdgeCast Networks Inc.",
-  "AdFrontier",
-  "NFQ",
-  "DataLogix, Inc.",
-  "Brightcove",
-  "Experian",
-  "Disqus",
-  "Namecheap.com",
-  "Polldaddy",
-  "Outbrain Inc.",
-  "Lijit Networks, Inc.",
-  "PubMatic",
-  "Say Media Inc.",
-  "Rubicon Project Turing, Inc. (SSP)",
-  "Rubicon Project Edison, Inc. (DSP)",
-  "Wordpress Stats",
-  "Twitter",
-  "Yandex LLC",
-  "Rutarget / Segmento",
-  "Addoor LatinMarkets, SL",
-  "Kate Spade",
-  "TARGUSinfo",
-  "Adblade",
-  "Adiant",
-  "AddToAny",
-  "Bizo Inc",
-  "Google Analytics",
-  "Gravatar",
-  "MediaGlu",
-  "Tapstream Network Inc.",
-  "HUNT Mobile Ads",
-  "Apsalar, Inc.",
-  "Videology DSP",
-  "Videostrip",
-  "Affinity – Hostway Corporation",
-  "Taptica",
-  "LiveRamp, Inc.",
-  "Plista GmbH",
-  "Netquest Ad Tracking",
-  "Mediasmart Mobile S.L.",
-  "Netshelter Technology Media, Inc.",
-  "Mixmarket Affiliate Network",
-  "Turbobytes",
-  "Voodoo Video AG",
-  "Google CDN",
-  "Full Performance",
-  "eXelate Inc.",
-  "Oreck Canada",
-  "Beijing WuShuang Technology Ltd. (AGrant)",
-  "Matomy Media",
-  "Mail.Ru Group",
-  "LSi - Lionsoft Studios, spol. s r.o.",
-  "Adelphic Inc.",
-  "Lincoln Technical Institute, Inc.",
-  "Smartstream.tv",
-  "Reklamport",
-  "Fattext LLC (DBA Moolah Media)",
-  "MoGo Marketing & Media Inc.",
-  "SA Media, llc",
-  "Barons Media LLC",
-  "apprupt GmbH",
-  "PropellerADs media Ltd",
-  "CJ Affiliate by Conversant",
-  "Millennial Media Inc",
-  "BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd",
-  "Manage.com Group, Inc.",
-  "MASSMOTIONMEDIA SARL",
-  "Brainworks Sp. z.o.o.",
-  "Media Intelligence Platform (Aggregate Knowledge)",
-  "S4M",
-  "Sobmag LTD",
-  "Netbooster",
-  "Musikhaus Thomann e.K.",
-  "Trovit",
-  "O2online",
-  "E-Plus Mobilfunk GmbH & Co. KG",
-  "Meteora",
-  "Madison Logic, Inc.",
-  "万相DSP(IZP Technologies)",
-  "righTarget",
-  "e.QQ.com",
-  "Shen Zhen ShiJi KaiXuan Technology Company Ltd.",
-  "Bannercockpit",
-  "Outrigger Media Inc.",
-  "shopLocal",
-  "Impact Radius",
-  "Unister AdServer",
-  "Unister Media GmbH",
-  "TLV Media Online Ltd",
-  "d3media AG",
-  "Innovative Metrics",
-  "AthenaHealth",
-  "TAPVALUE SAS",
-  "Meteor Worldwide LLC.",
-  "Audience2Media Limited",
-  "HRB Digital LLC.",
-  "!NOOB",
-  "OSV online",
-  "Addroid™",
-  "AdAccess",
-  "Yabuka Media, Inc.",
-  "Bridgewell Incorporated",
-  "Bidtheatre AB",
-  "AdMoment",
-  "UDG München GmbH",
-  "Pixalate, Inc.",
-  "InMobi Inc.",
-  "Crisp Media Inc.",
-  "Choozle, Inc.",
-  "Tapad",
-  "ReachLocal, Inc",
-  "OpenX Ad Exchange",
-  "OpenX",
-  "Placester, Inc.",
-  "Spiceworks, Inc",
-  "WapStart",
-  "Ambercrow (Epayments)",
-  "Audiencevalue Pte Ltd",
-  "UNITED. Inc.",
-  "United Bypass Tech",
-  "SAS Naoplay",
-  "CuriosityStream",
-  "Alliance Internet (ntree)",
-  "Centraltag",
-  "eTargeting",
-  "Walmart Inc",
-  "Walmart.com",
-  "Extreme Reach, Inc.",
-  "Extreme Reach Digital (ER Digital)",
-  "Netflix",
-  "Netflix, Inc.",
-  "Scarab Personalized Ads",
-  "CrowdMob Inc.",
-  "Gruvi Ltd.",
-  "Macromill, Inc.",
-  "Nielsen (Cross Platform Brand Effect [IAG/TVBE])",
-  "GetIntent",
-  "Belboon",
-  "Ozone Media Solutions Pvt Ltd",
-  "Hindustan Times Mobile Solutions Limited",
-  "SoftLayer Technologies, Inc.",
-  "GoldSpot Media",
-  "Zeeto Media",
-  "DYNADMIC SAS",
-  "Yoc Mobile Advertising GmbH",
-  "Velti",
-  "Lockon",
-  "Recruit Co., Ltd. Communications",
-  "RECRUIT Communications",
-  "Hatena Co., Ltd",
-  "Trafmag",
-  "Pagewoo",
-  "Adnet Media",
-  "Ligatus GmbH",
-  "Webtrekk GmbH",
-  "Kantar World Panel",
-  "PubSquared LLC",
-  "Baidu.com Times Technology (Beijing) Co., Ltd",
-  "travel audience GmbH",
-  "Krux Digital, Inc.",
-  "The Weather Channel",
-  "Social Quantum",
-  "AdVentori SAS",
-  "MindTake Research GmbH",
-  "Leger Marketing",
-  "BlisMedia Limited",
-  "Double6",
-  "TRADEADS INTERACTIVE",
-  "Epigrams, Inc.",
-  "Activecore Inc.",
-  "Activecore,Inc.",
-  "ADCASH",
-  "Videoplaza",
-  "Targetix LLC",
-  "Adriver LLC",
-  "Beso",
-  "Voopter.com",
-  "Hostbasket",
-  "Rollad",
-  "hdtMedia",
-  "DXP Media",
-  "ebuilders BV",
-  "COADVERTISE",
-  "Blizzard",
-  "Adgibbon",
-  "Wider Planet, Inc.",
-  "ResponsiveAds, Inc",
-  "Duepuntozero Research SRL",
-  "AdMovate, Inc.",
-  "go.pl",
-  "AppLovin Corporation",
-  "twentysix ltd",
-  "Epsilon International SA",
-  "Zebestof",
-  "SOL UTD Benelux BV",
-  "M,P,NEWMEDIA, GmbH",
-  "MediaCrossing Inc.",
-  "MBR Targeting Gmbh",
-  "VivaKi",
-  "Affiliate Window",
-  "TubeMogul Inc. (AdWords/YouTube)",
-  "Way2traffic Polska S.A.",
-  "TNS Sifo AB",
-  "3xchange/Hunkal",
-  "Emerse Sverige AB",
-  "Sokno Media",
-  "Blackheart, a division of Hot Topic, Inc.",
-  "Torrid",
-  "Hot Topic, Inc.",
-  "WebHue LLC",
-  "Content to Emotion",
-  "Adman Interactive SL",
-  "AudienceFUEL, Inc.",
-  "TapCommerce LLC",
-  "AdTheorent, Inc.",
-  "AdTheorent, Inc",
-  "Barometric",
-  "CrossInstall, Inc",
-  "Theorem Inc.",
-  "KeyVersion",
-  "Ancestry",
-  "Shanghai Lijing Advertising Co., Ltd.",
-  "Shanghai Lijing Advertising Co., Ltd",
-  "KissNoFrog.com",
-  "DigiEQ",
-  "Mobile Professinals BV",
-  "Decisive, Inc.",
-  "Tumi, Inc. US",
-  "Tumi, Inc. UK",
-  "Tumi, Inc. DE",
-  "Nanigans, Inc",
-  "AdSniper LLC",
-  "Fabric Worldwide Inc",
-  "Vorwerk Deutschland Stiftung & Co. KG",
-  "Chico Distribution Services, LLC",
-  "12Mnkys GmbH",
-  "Spacyz, Inc.",
-  "MBuy, Inc.",
-  "FullSpeed Inc.",
-  "Madhouse Co. Limited (OptiMad)",
-  "Nano Interactive / Audiencemanager",
-  "Omnibus co. Ltd",
-  "Omnibus co. Ltd.",
-  "Education Management Corporation",
-  "Screen6 (s6.io)",
-  "LINK Marketing Services AG",
-  "TiqIQ",
-  "Ibibo Group Private Limited",
-  "justAd TV LTD",
-  "Appier Inc.",
-  "Kate Spade Saturday",
-  "Teufel GmbH",
-  "Aitarget LLC",
-  "Engage Lab Ltd.",
-  "Signal Digital, Inc dba Signal",
-  "Motrixi Media Group LLC",
-  "WHITE HOUSE | BLACK MARKET, Chico Brands, Inc.",
-  "Liftoff Mobile, Inc.",
-  "etracker GmbH",
-  "MezzoMedia",
-  "Eyeota Limited",
-  "Beijing PageChoice Network Technology co., Ltd.",
-  "Padopolis, Inc.",
-  "Republic Project, Inc.",
-  "C8 Network",
-  "Data Artist Inc.",
-  "AirFrance",
-  "YDigital Media",
-  "Zentrick",
-  "FreeBit Co. Ltd.",
-  "Dennoo Inc.",
-  "Adbrain",
-  "MSI-ACI Europe BV",
-  "A.Mob",
-  "Toys R Us",
-  "Geniee,Inc",
-  "Adsecure",
-  "Kimia Solutions SL",
-  "Sojern",
-  "Where 2 Get It, Inc.",
-  "Tomoko Cloud",
-  "RevenueMantra",
-  "Automobile Ltd.",
-  "Big Mobile Group Pty Ltd",
-  "ADMIZED AG",
-  "Sparks47 s.r.l.",
-  "Between Digital dba Intency DSP",
-  "eprofessional GmbH",
-  "Channel Factory, LLC",
-  "ConvertStar Incorporated",
-  "VisualDNA (Imagini)",
-  "Avocet",
-  "Auction.com, LLC",
-  "White Ops, Inc.",
-  "Hangzhou Qiguan Network Technology Co., Ltd.",
-  "Admetrics",
-  "Admetrics GmbH",
-  "Amobee Inc. d/b/a Gradient X",
-  "Datalicious Pty Ltd",
-  "Intent Media",
-  "AdNear Pte Ltd.",
-  "Zhejiang MediaAdx Network Technology Co., Ltd",
-  "Harris Interactive",
-  "BuzzCity Pte Ltd",
-  "Sputnyx",
-  "CyberZ, Inc",
-  "Spark Networks USA, LLC",
-  "Ezakus",
-  "V4x SAS",
-  "Tapjoy Inc.",
-  "EXEBID",
-  "Exposebox Ltd",
-  "MotoMiner",
-  "BuySellAds.com Inc.",
-  "Viking River Cruises",
-  "Sittercity Incorporated",
-  "Facetz",
-  "YOOSE Pte. Ltd.",
-  "AdYapper, Inc.",
-  "Clickky LLP DBA Clickky",
-  "eRate Online Measurement Solutions Ltd.",
-  "Baumann Ber Rivnay",
-  "TUI Connect GmbH",
-  "INFOnline GmbH",
-  "Adizio",
-  "Joystick Interactive",
-  "EngageClick Inc",
-  "GeeeN, Inc.",
-  "Arbigo Inc.",
-  "FlxOne BV",
-  "ExtendTV, Inc.",
-  "momentM, Inc",
-  "OnCard Marketing dba RevTrax",
-  "Youtube - API",
-  "Thirdpresence Ltd",
-  "Visual IQ, Inc.",
-  "Appreciate",
-  "CyberAgent d/b/a GameLogic",
-  "Lodeo",
-  "CyberAgent d/b/a Dynalyst",
-  "LTD \"RTB-MEDIA\"",
-  "Maverick., inc.",
-  "FuelX",
-  "Tutor.com",
-  "Rebelmouse",
-  "Adviator DSP",
-  "Acens Technologies, S.L.",
-  "Yashi, Inc",
-  "Flaminem Inc",
-  "Mediahead AG",
-  "Admixer",
-  "Communication Services Tele2 GmbH",
-  "99click",
-  "Ströer Mobile Media GmbH",
-  "LLC \"Life Style\"",
-  "2Y Media SAS (adserverpub)",
-  "Platform IQ",
-  "Silveredge Inc",
-  "SMADEX",
-  "Suzu Muchi",
-  "LOKA Research inc.",
-  "Edgesuite",
-  "PlannTo Technologies Private Limited",
-  "Viator, Inc",
-  "NODDINGTON TECHNOLOGIES LIMITED",
-  "Plan Blue Ltd",
-  "Addictive Mobility",
-  "A6 Corporation",
-  "Mobusi Mobile Advertising",
-  "Wishabi",
-  "onAd GmbH",
-  "Media Decision GmbH",
-  "Unitymedia NRW",
-  "Nowspots INC, dba Perfect Audience",
-  "Avis",
-  "Comcast",
-  "Jack Spade",
-  "Dollar General",
-  "Care.com",
-  "Clickagy, LLC",
-  "GlobalWebIndex",
-  "King.com",
-  "Proquire LLC - Accenture",
-  "Dynamic Yield",
-  "Charter business",
-  "The ADEX",
-  "OneDigitalAd Technologies",
-  "ADJUST",
-  "ADmantX, SPA",
-  "Sogou.com",
-  "xAd, Inc.",
-  "VideoBlocks",
-  "GraphicStocks",
-  "Microsoft Advertising",
-  "Rontar LTD",
-  "Torrential, Inc.",
-  "AMoAd, Inc.",
-  "Tukmob Information Technology(Shanghai)Co. Ltd",
-  "Jampp/Devego S.A.",
-  "Placed",
-  "Digitas Health",
-  "Answer Media, LLC",
-  "1000mercis",
-  "Upstart Network, Inc.",
-  "Forensiq, LLC",
-  "LoopMe Ltd",
-  "Bannerlink (Liquidus)",
-  "Dell Inc.",
-  "My Perfect Resume",
-  "Ajillion Max Ltd",
-  "Swelen France SA.",
-  "Sleeptrain",
-  "Sleepcountry",
-  "Hoover",
-  "Bidtellect",
-  "Mocoplex Inc.",
-  "Brightsparc Technologies Pty Ltd trading as Native",
-  "Verengo Solar",
-  "Mobile Professionals BV",
-  "APNIC Pty Ltd",
-  "Dun and Bradstreet Corporation",
-  "UpToLike",
-  "Mobile360 Sdn Bhd",
-  "Elite Fixtures",
-  "Advanse Ads",
-  "Insurance Step",
-  "Causal Impact",
-  "Pixnet",
-  "Zapp360",
-  "Kijiji",
-  "Spotad LTD.",
-  "Go Daddy",
-  "Bilendi",
-  "Hitokuse",
-  "MGID Inc.",
-  "AreaOne",
-  "DynAd",
-  "Loop Pay",
-  "Remerge GmbH",
-  "Audience Trading Platform LTD",
-  "Whisla",
-  "Bridgevine",
-  "ADgraph DMP",
-  "Gravity4 Inc.",
-  "Hipmunk",
-  "VideoHub DSP",
-  "DuMedia",
-  "F@N Communications, Inc.",
-  "VIVALU GmbH",
-  "Advertising Technologies LTD",
-  "Authenticated Digital Inc",
-  "PaeDae, Inc., DBA The Mobile Majority",
-  "METROPCS",
-  "PapayaMobile Inc.",
-  "Raumfeld",
-  "GREE Ads DSP",
-  "Tender Industries AB",
-  "BySide",
-  "Sentrant Security Inc.",
-  "Locon Solutions Pvt. Ltd.",
-  "Interrogare GmbH",
-  "ChannelAdvisor",
-  "VideoAmp",
-  "The Bridge",
-  "Pharmaca Integrative Pharmacy",
-  "Scrutineer",
-  "TF1 - FR",
-  "Core Digital",
-  "Adventive, Inc.",
-  "Turner Sports Interactive, Inc.",
-  "SnappyTV",
-  "Target Media Partners",
-  "KAIZEN platform Inc.",
-  "Bidstalk Pte Ltd",
-  "ESPN",
-  "Online Media Group",
-  "Luxury Link",
-  "ESKIMI",
-  "AdsYolo Media",
-  "Arrivalist",
-  "MobileWebAdz Ltd",
-  "Demand Side Science, Inc.",
-  "SOCIETE FRANCAISE DU RADIOTELEPHONE",
-  "Mobitrans FZ LLC",
-  "CoCo Reef",
-  "Kumma DP LTD",
-  "Cablato Limited",
-  "EURO DISNEY SCA",
-  "Norstat",
-  "John Varvatos",
-  "Spritz Technology, Inc.",
-  "Wix.com",
-  "TapTap Networks",
-  "Permodo",
-  "Gaiam, Inc.",
-  "Plusing interactive co.,Ltd",
-  "Paypersale",
-  "OCP Collective Corp. (d/b/a AdCade)",
-  "ESV Digital",
-  "RevJet LLC.",
-  "GET IT Mobile, Inc",
-  "IBM",
-  "Lucid Holdings, LLC",
-  "Stratio Big Data Inc.",
-  "Tripping.com",
-  "Vidible",
-  "MiMTiD Corp",
-  "Moloco, Inc.",
-  "MEC SP. Z O.O",
-  "Abudantia LLC",
-  "Realzeit",
-  "Shanghai DigitalMatrix Information Technology Co.",
-  "Alkemics",
-  "Sodel Software Solutions Pvt. Ltd.",
-  "Clearstream.TV, Inc",
-  "KuaiziTech",
-  "Adluxe",
-  "NinthDecimal",
-  "RICH MEDIA STUDIO",
-  "TenMax Co., Ltd.",
-  "twiago GmbH",
-  "Ad Dynamo International (Pty) Ltd",
-  "Swarm Enterprises Inc",
-  "Media Forum",
-  "Beeswax.io",
-  "Varick Media Management",
-  "JD",
-  "Lotlinx Inc.",
-  "Lotlinx Inc",
-  "Ingenio, LLC",
-  "MVMT Watches",
-  "C1X Inc",
-  "Vitro Agency",
-  "Kabbage",
-  "Redbranch, Inc. (dba Fraudlogix)",
-  "AutoWeb, Inc.",
-  "Aimee Soft Ltd.",
-  "SAS Azameo",
-  "Keyade",
-  "Digital To Store (DTS)",
-  "Media iQ Digital",
-  "Ingenious Technologies",
-  "Sonicmoov co.,ltd",
-  "Bonadza LLC",
-  "Axis Shift Limited",
-  "TreSensa, Inc.",
-  "Media Logic Group LLC dba AerisWeather LLC",
-  "Fugumobile",
-  "Localstars Ltd",
-  "Fluidads",
-  "Wayfair LLC",
-  "VCCORP CORPORATION",
-  "IGAWorks",
-  "Cellcom Ltd",
-  "Upsolver",
-  "Phluidmedia, Inc.",
-  "Roy Morgan Research Ltd",
-  "TapSense, Inc.",
-  "Southwest Airlines",
-  "Market Points, Inc.",
-  "UberMedia Inc.",
-  "Kadam SIA",
-  "Alveo Platform (VMM own bidder)",
-  "Adbalancer EDV-DienstleistungsgesellschaftgmbH",
-  "JWPlayer",
-  "Adiquity Technologies Pvt Ltd",
-  "Smart Digital GmbH",
-  "Auditorius LLC",
-  "Treepodia",
-  "Adamatic",
-  "SAS Web2ROI",
-  "Cardlytics",
-  "MyFonts Inc.",
-  "Bluecore, Inc.",
-  "EverQuote, Inc.",
-  "Optimize LCC D.B.A Genius Monkey",
-  "EverString Technology Ltd",
-  "Axonix Limited",
-  "Ubimo Ltd.",
-  "PlaceIQ, Inc.",
-  "DataBerries",
-  "Otto (GmbH & Co KG)",
-  "Beijing ADirects Technology Corporation Limited",
-  "MagicGroup Asia Pte. Ltd.",
-  "Local Content, Inc.",
-  "Flavia",
-  "Webtype",
-  "Aditor",
-  "YCmedia",
-  "Addwish Aps",
-  "AIDO TECHNOLOGY INC.",
-  "Herolens Group LLC",
-  "Fuisz Media, Inc.",
-  "Bucksense, Inc.",
-  "Taylor Nelson Sofres Ukraine LLC",
-  "MotionLead",
-  "CJSC Recomendatsii tovarov i uslug",
-  "Adobe Edge",
-  "Bizible",
-  "Adludio Limited",
-  "Ally Financial",
-  "AIAd Ltd.",
-  "Petplan",
-  "Vidazoo Ltd.",
-  "RTBstar LLC",
-  "Chalk Media Holdings",
-  "Oxford Biochronometrics",
-  "SGN Games, Inc.",
-  "Crutchfield New Media, LLC",
-  "Laserlike Inc",
-  "Adtile Technologies Inc.",
-  "Adgravity",
-  "Protected Media LTD",
-  "Media Detect GmbH",
-  "Centro CDN",
-  "DeltaX",
-  "SoMo Audience Corp.",
-  "Distribute Ltd",
-  "Poppin",
-  "EUROZEST MEDIA LIMITED/Avid Ad Server",
-  "Art of Click Pte. Ltd",
-  "Quantasy LLC",
-  "Wavenet Technology Co., Ltd.",
-  "ENVISIONX LTD",
-  "Adhood",
-  "Telogical Systems, LLC",
-  "twyn group IT solutions & marketing services G",
-  "Marchex Sales, LLC",
-  "SmartyAds LLP",
-  "Reach150 Social, Inc.",
-  "Leadmill ApS",
-  "TapHeaven, Inc.",
-  "spring GmbH & Co. KG",
-  "Roq.ad GmbH",
-  "AdKernel LLC",
-  "Uprise Technologies",
-  "Sled, Inc.",
-  "Pengtai Interactive Advertising Co.Ltd",
-  "Adello Group AG",
-  "BitGravity",
-  "44 Interactive",
-  "Shopalyst Technologies Pvt Ltd",
-  "Total Access Communication Public Company Limited",
-  "TACTIC Real-time marketing AS",
-  "Mobilewalla, Inc",
-  "Nuviad Ltd",
-  "AmberData LLC",
-  "Aedgency",
-  "MobPartner, Inc.",
-  "AdTriba GmbH",
-  "DISH Network L.L.C.",
-  "Monotype Imaging Inc.",
-  "MEDIAN Ltd.",
-  "ClickForce Inc.",
-  "Zemanta Inc.",
-  "jsdelivr.com",
-  "Adssets AB",
-  "Sellpoints Inc.",
-  "HockeyCurve Growth Solutions Pvt Ltd",
-  "HockeyCurve Growth Solutions Pyt Ltd",
-  "Umeng Plus Beijing Technology Limited Company",
-  "Survata, Inc.",
-  "JustWatch GmbH",
-  "Interactive Tracker Next",
-  "Unisport A/S",
-  "OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ",
-  "Softcube Inc.",
-  "YOptima Media Solutions Pvt. Ltd",
-  "ZMAGS INC",
-  "Aniview LTD.",
-  "Realtag",
-  "Bitsngo.net",
-  "AdCanvas",
-  "Happyfication, Inc.",
-  "Cinarra Systems Japan株式会社",
-  "Cinarra Systems Japan",
-  "CUBED Attribution",
-  "StackAdapt Inc.",
-  "Statiq Ltd",
-  "Tagular Analytics, LLC",
-  "ComboTag Technologies Ltd.",
-  "Juice Mobile",
-  "Bebe",
-  "Augur",
-  "Seracast Digital LLC",
-  "AerServ LLC",
-  "PT. Tokopedia",
-  "Terapeak, Inc.",
-  "OpenStreetMap France",
-  "Front Porch, Inc",
-  "Vertamedia",
-  "Codewise (VoluumDSP)",
-  "Virool Inc.",
-  "SpringServe LLC",
-  "Intimate Merger",
-  "Telecoming Connectivity S.A.",
-  "Webssup",
-  "INCUBIQ Solutions Ltd",
-  "ADSpend",
-  "AdTradr Corporation",
-  "Quint Growth Inc.",
-  "ZAPR",
-  "1trn LLC",
-  "Matiro",
-  "Inspired Mobile Ltd.",
-  "Selectmedia International LTD.",
-  "Internet Billboard, a. s",
-  "Volvelle",
-  "StreamRail Ltd.",
-  "E-Contenta",
-  "Bath and Body Works",
-  "WooTag Pte Ltd",
-  "Cint AB",
-  "Stein Mart",
-  "Sift Media, Inc.",
-  "StartApp Inc.",
-  "Pxene - DSP",
-  "Integral Marketing",
-  "Expedia, Inc.",
-  "DeepIntent, Inc",
-  "OmniVirt",
-  "\"Index20\" LLC",
-  "Conversion Logic, Inc.",
-  "Collegehumor",
-  "Silence Media Limited",
-  "Zuuvi Aps",
-  "SoftBank Corp.",
-  "ConnectOM, Inc.",
-  "Skillup Video Technologies Corporation",
-  "Adara Impact Analytics",
-  "TabMo SAS",
-  "Casale Media",
-  "StickyADStv",
-  "Teads Technology SAS",
-  "Anomaly Communications, LLC",
-  "ClickTicker, LTD",
-  "Tremour",
-  "Roket Media LTD",
-  "Video Jam (MauDau LTD)",
-  "MINIMOB (CY) LTD",
-  "Snitcher B.V.",
-  "Analights",
-  "Romir Panel Ltd.",
-  "Dievision",
-  "Ignite Technologies",
-  "Navegg",
-  "Adalyser",
-  "Nordic Factory International Inc.",
-  "Addition Plus Ltd",
-  "Karmatech Mediaworks Pvt Ltd",
-  "Mediatropy Pte Ltd",
-  "Wayve Limited",
-  "Kreditech Holding SSL GmbH",
-  "Yengo",
-  "DANtrack",
-  "Integral Markt- und Meinungsforschungsges.m.b.H.",
-  "Millemedia GmbH",
-  "Hiro-Media",
-  "Simplaex Gmbh",
-  "Telekom Deutschland GmbH",
-  "Infernotions Technologies Limited",
-  "Goldfish Media LLC",
-  "Smartology Limited",
-  "GroupM",
-  "Haystagg Inc.",
-  "Digital Turbine Media, Inc",
-  "MDSP INC",
-  "Quadas (YiDong Data Inc.)",
-  "Recruit Career Co., Ltd.",
-  "R2Net Inc.",
-  "Madberry OY",
-  "QVC",
-  "Micro Cube Digital Limited",
-  "egg.de GmbH",
-  "Headway Mexico",
-  "RTBiQ Inc.",
-  "SCIBIDS TECHNOLOGY S.A.S.",
-  "Kyocera Communication Systems",
-  "Cortex Media Group",
-  "appTV",
-  "ProgSol, Programmatic Solution, s.r.o.",
-  "Rezonence",
-  "LKQD Platform",
-  "target value GmbH",
-  "Firecracker",
-  "MADGIC",
-  "Digiseg",
-  "Bulbit Inc.",
-  "Lost My Name",
-  "People Media",
-  "Platform.io",
-  "Bidspeaker",
-  "YouGov PLC",
-  "SAP SE",
-  "Adchex",
-  "Smart Bid Limited",
-  "UAd Exchange",
-  "UAd Exchange - IBV",
-  "esc mediagroup GmbH",
-  "defacto smart reach GmbH",
-  "Research and Analysis of Media in Sweden AB",
-  "OnAudience.com",
-  "OneTag",
-  "Fiverr International Ltd.",
-  "Adikteev",
-  "CenterPoint Media",
-  "Digital Trace",
-  "Pure Cobalt",
-  "Cedato",
-  "Jonsden Properties Limited",
-  "Realytics",
-  "Twinpine",
-  "Mopedo AB",
-  "Netsales",
-  "ViewersLogic LTD",
-  "ADMAN",
-  "Hyper",
-  "Hurra Communications",
-  "Groundhog TW",
-  "ImediaMax",
-  "Flixbus",
-  "AudienceTV",
-  "b34106183_test",
-  "Netscore",
-  "Chu Technology Limited",
-  "SmartyAds LLC",
-  "dbupdate1",
-  "The Big Willow Inc.",
-  "LiveIntent Inc",
-  "OpenLedger ApS",
-  "Whichit",
-  "ParkDIA",
-  "Atedra Inc.",
-  "Digital Forest OÜ",
-  "Isobar Werbeagentur GmbH",
-  "Valuepotion Pte. Ltd.",
-  "Vuble Inc",
-  "adlocal.net",
-  "Freckle IoT",
-  "Personalization LLC",
-  "ThoughtLeadr Inc.",
-  "Noqoush Mobile Media Group FZ-LLC",
-  "G-Core Labs",
-  "Haensel AMS GmbH",
-  "LemonPI",
-  "4Info, Inc."
-],
-[
-  {"hash":"8fd259996da5f3d8","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"56837fe2597a4f9e","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"fb4ddfafadb387cf","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"07a11d9d007c60f8","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"9f36fc0bb2911046","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"57c7af60819b3f3e","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"c3363b1ccf0e2ab6","prefixes":{"":{"product":1,"type":0}}}, // [Interworks Media, Inc.]
-  {"hash":"9d16bd99e929eccd","prefixes":{"":{"product":1,"type":0}}}, // [Interworks Media, Inc.]
-  {"hash":"211d3b9ea9bf8f2e","prefixes":{"":{"product":2,"type":0}}}, // [Action Exchange, Inc.]
-  {"hash":"414adfe007d3587f","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"4486e584990f9603","prefixes":{"":{"product":4,"type":0}}}, // [FSN ASIA PRIVATE LIMITED]
-  {"hash":"8cfb66b1b7bbe43b","prefixes":{"":{"product":5,"type":0}}}, // [iPromote]
-  {"hash":"fba2a0cd626a5289","prefixes":{"":{"product":5,"type":0}}}, // [iPromote]
-  {"hash":"113620ff3bb3ea60","prefixes":{"":{"product":5,"type":0}}}, // [iPromote]
-  {"hash":"b5f6b4570a07977c","prefixes":{"*":{"product":6,"type":0}}}, // [33Across Inc.]
-  {"hash":"877f3b2ffe34bf4a","prefixes":{"*":{"product":7,"type":0}}}, // [8thBridge]
-  {"hash":"bc5882cc43d24a0b","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"5506a3935677620c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"4a8f0380d8c0ee22","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"54e1d163948509ad","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"534e3733e4e5309d","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"c7db8e0e25c7df2d","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"222afdeb29be30ca","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"a082f434d9ec1f91","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"e00092cf7fb8c74a","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"6b3557e54073f90d","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"b825724682d4bd41","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"62a0c6b3cd3ed567","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"7e5f80275a654f93","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"96d3bf36a066a721","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"14f8bb92c4036403","prefixes":{"*":{"product":8,"type":0}}}, // [A9]
-  {"hash":"8aaada51ee8ebb86","prefixes":{"*":{"product":8,"type":0}}}, // [A9]
-  {"hash":"7e1d4edc3530e448","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"c0bf2b011199054e","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"b4dd68c5d9b68922","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"8d943586f8f86d04","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"f60b51325cdf4f80","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"080dea15fa602a8c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"a01c9f1f745acb3b","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"eae49b84950db230","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"154c00442038842c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"bb5191c2744e5157","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"24f8ee8d41010340","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"dde97a25d741083b","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"c40e51f0d4308aef","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"dafae404fe4bf9e0","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"2965d60c41f24692","prefixes":{"*":{"product":9,"type":0}}}, // [AdGenie]
-  {"hash":"947df9bf1ccc5af0","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"5874ab2040fd92e5","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"12c9a3fc47eec655","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"ff950154b65538b5","prefixes":{"":{"product":12,"type":0}}}, // [Conversant Ad Server]
-  {"hash":"cca88c18c3a955c3","prefixes":{"*":{"product":13,"type":1}}}, // [Napster Luxemburg SARL]
-  {"hash":"cf583a4f1b85a63d","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"b1f24fb9f4e82bc4","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"7ed3ef3bd9b7964c","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"802185637db97f57","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"69ac52e6452dcdcc","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"99d6e276a9f3dce4","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"20cea422f633f132","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"abac0e92b7c09189","prefixes":{"":{"product":19,"type":1}}}, // [Madeleine Mode GmbH]
-  {"hash":"ab6d5bcfcb13c98c","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"17c760570121cb8e","prefixes":{"":{"product":20,"type":1}}}, // [Telefonica UK / O2 UK]
-  {"hash":"cca991b6ab7e6463","prefixes":{"":{"product":21,"type":0}}}, // [Tamome]
-  {"hash":"b24aab8ad8822e3b","prefixes":{"":{"product":21,"type":0}}}, // [Tamome]
-  {"hash":"e068190951dbb5ef","prefixes":{"":{"product":21,"type":0}}}, // [Tamome]
-  {"hash":"c5a5fd495c44b8e2","prefixes":{"":{"product":21,"type":0}}}, // [Tamome]
-  {"hash":"95305154969e81b9","prefixes":{"":{"product":21,"type":0}}}, // [Tamome]
-  {"hash":"f40a7549c998fd96","prefixes":{"":{"product":22,"type":0}}}, // [TUI UK Limited]
-  {"hash":"96eeaa2c9afb8955","prefixes":{"":{"product":22,"type":0}}}, // [TUI UK Limited]
-  {"hash":"bfeca1a08eac1f5e","prefixes":{"*":{"product":23,"type":1}}}, // [iJento]
-  {"hash":"cfbb894fdba5489a","prefixes":{"":{"product":24}}}, // [McCann Erikson]
-  {"hash":"4ce21296b7adb20d","prefixes":{"":{"product":25,"type":1}}}, // [Tribes Research Limited]
-  {"hash":"72b12a834f93bbd1","prefixes":{"":{"product":26,"type":1}}}, // [On Device Research Ltd.]
-  {"hash":"5a885783941e6540","prefixes":{"*":{"product":27,"type":1}}}, // [SuperVista AG]
-  {"hash":"382734d54ddf7100","prefixes":{"":{"product":28}}}, // [National Lottery]
-  {"hash":"dabd2bc95093ab29","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"8912c7bdde481292","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"c735e4adfc754475","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"297bba8cd045b252","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"b4ee04e1cb1b0cb0","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"1f9925b611b3db5e","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"e63f21a01153ba8c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"5df92c4776ddb318","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"995e4fe402d230d4","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"f27bb2795a31311c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"7ef41a846501bb38","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"f69c9d0a6726d8a2","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"fbe82cac507c4685","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"b30108dc4fef7d3d","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"3db91f22497fff29","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"8c93f288d1c9adaa","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"dd3abfa7756f945e","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"562f4260ff4f65a6","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"94d8ddce749b5392","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"031269afdaee38ca","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"0c0ba1aaf374eac4","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"cb1dbab4bb9d139b","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"144dac73c5669441","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"b6b232e5fbf868f0","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"3c15562b6abc1319","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"722c811d70136506","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"78a792effa9e4967","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"a59637a7ca9dc579","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"6b3ce5ea793ecbbf","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"2b5bd0c505a178d0","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"c41cefa39852e538","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"e572b55cf0c6834b","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"80d0b8e46094b1c9","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"343036881041aa23","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"2559ed3163479794","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"95acf3d42f565375","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"a3fe80607786880e","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"b7629e7fab881e7a","prefixes":{"":{"product":30,"type":0}}}, // [Retailigence]
-  {"hash":"03ec1a841574bd4d","prefixes":{"":{"product":31,"type":0}}}, // [Logly DSP]
-  {"hash":"7ff5ce1768464e16","prefixes":{"":{"product":31,"type":0}}}, // [Logly DSP]
-  {"hash":"10fb9dcb49e1abe6","prefixes":{"":{"product":32}}}, // [App-CM Inc.]
-  {"hash":"6d3713ad37a0966c","prefixes":{"":{"product":32}}}, // [App-CM Inc.]
-  {"hash":"41670ff004a04f19","prefixes":{"":{"product":32}}}, // [App-CM Inc.]
-  {"hash":"cd681b4891935464","prefixes":{"":{"product":33,"type":1}}}, // [Yahoo! Japan Corporation]
-  {"hash":"b97383320b594f18","prefixes":{"":{"product":33,"type":1}}}, // [Yahoo! Japan Corporation]
-  {"hash":"e2fff6e598b3035e","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"cb3ceda4f0c38995","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"a218e065250d793c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"deb1ce911dfb392b","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"de5ead15f1d0f171","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"92615d394883ce3c","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"6cd842b12d20b208","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"dc6acfacad6c1026","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"81aa25ff76990996","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"1254067a80cf3d7b","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"31e2549e82b92770","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"be41bb940608434e","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"05a4ab4a11bd1fbf","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"05677aca712e9b65","prefixes":{"":{"product":8,"type":0}}}, // [A9]
-  {"hash":"00620801050945d1","prefixes":{"":{"product":34,"type":0}}}, // [Oggifinogi]
-  {"hash":"c0ceae7cfc4144c6","prefixes":{"":{"product":35,"type":0}}}, // [PaperG]
-  {"hash":"996c3990310cfc19","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"14210f0f0a8d71cb","prefixes":{"":{"product":37,"type":0}}}, // [The Trade Desk Inc.]
-  {"hash":"05b4ef50eb9dedd3","prefixes":{"":{"product":38,"type":2}}}, // [Amazon]
-  {"hash":"6205b589bcd2cd97","prefixes":{"":{"product":38,"type":2}}}, // [Amazon]
-  {"hash":"3401a90f3a35a7e8","prefixes":{"":{"product":38,"type":2}}}, // [Amazon]
-  {"hash":"4ee229bd95f9bb17","prefixes":{"":{"product":38,"type":2}}}, // [Amazon]
-  {"hash":"2a0766a8dd2ce2b0","prefixes":{"":{"product":38,"type":2}}}, // [Amazon]
-  {"hash":"736b87f504b5e113","prefixes":{"":{"product":39,"type":0}}}, // [Airpush, Inc.]
-  {"hash":"0bcef81372eadfe9","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"9ea6769e672968e9","prefixes":{"":{"product":41,"type":0}}}, // [F# Inc.]
-  {"hash":"0fde612c20c42c6f","prefixes":{"":{"product":42,"type":0}}}, // [Transout Inc.]
-  {"hash":"5ed995763ce85029","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"497082972c1c0dfd","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"6d7e4a203b969d9e","prefixes":{"":{"product":45,"type":0}}}, // [Opera Mediaworks Inc.]
-  {"hash":"d3a9057528c14a56","prefixes":{"":{"product":46,"type":0}}}, // [DistroScale Inc.]
-  {"hash":"479d2f8d9b7a2efe","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"6f7f9fb0065f745f","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"893d967f4540bb44","prefixes":{"":{"product":48,"type":0}}}, // [Fluct Inc.]
-  {"hash":"3830f0b6ca460fe9","prefixes":{"*":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"e917237ee7b0ad79","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"e0792ffd5eca94d8","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"29beee316a393584","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"ce9e7bf17bba4aae","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"fcf604f90166bb66","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"f11d9059950b4a07","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"7d142a85f84f3402","prefixes":{"":{"product":49,"type":0}}}, // [Acuity Ads]
-  {"hash":"83c0bb224cb5622f","prefixes":{"*":{"product":50,"type":0}}}, // [iLead]
-  {"hash":"27841e5ac1581a67","prefixes":{"":{"product":51,"type":0}}}, // [Canned Banners LLC]
-  {"hash":"83fbdce4f2519684","prefixes":{"":{"product":51,"type":0}}}, // [Canned Banners LLC]
-  {"hash":"db7bac94f2b2d2b7","prefixes":{"":{"product":52,"type":0}}}, // [AdBroker GmbH]
-  {"hash":"e0de5430253205fc","prefixes":{"":{"product":52,"type":0}}}, // [AdBroker GmbH]
-  {"hash":"bde57b6011499edf","prefixes":{"":{"product":52,"type":0}}}, // [AdBroker GmbH]
-  {"hash":"077ad042e29c79fb","prefixes":{"":{"product":52,"type":0}}}, // [AdBroker GmbH]
-  {"hash":"d3c6fc5ff77f0d5c","prefixes":{"":{"product":52,"type":0}}}, // [AdBroker GmbH]
-  {"hash":"b88fb01ba215894e","prefixes":{"*":{"product":53,"type":1}}}, // [InMind Opinion Media]
-  {"hash":"3d509f557aeca6de","prefixes":{"*":{"product":54,"type":0}}}, // [Adcentric]
-  {"hash":"3a9959c8cadd20af","prefixes":{"*":{"product":55,"type":1}}}, // [AdClear GmbH]
-  {"hash":"e8adb806a39f661d","prefixes":{"":{"product":56,"type":1}}}, // [DeinDeal AG]
-  {"hash":"da7343c16a51f1d4","prefixes":{"":{"product":57,"type":1}}}, // [Sixt Leasing SE]
-  {"hash":"5b4d4595453d5b23","prefixes":{"":{"product":58,"type":1}}}, // [Air Berlin]
-  {"hash":"b5085d3a3ede7503","prefixes":{"":{"product":59,"type":1}}}, // [Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper]
-  {"hash":"076e39b7aa354c83","prefixes":{"":{"product":55,"type":1}}}, // [AdClear GmbH]
-  {"hash":"61c6a6d15b340f45","prefixes":{"":{"product":60,"type":0}}}, // [Adform DSP]
-  {"hash":"36f5cb213a4d1469","prefixes":{"":{"product":60,"type":0}}}, // [Adform DSP]
-  {"hash":"95b61c012402be18","prefixes":{"":{"product":60,"type":0}}}, // [Adform DSP]
-  {"hash":"34e291794974e891","prefixes":{"":{"product":60,"type":0}}}, // [Adform DSP]
-  {"hash":"1d0d393655ae7ce4","prefixes":{"*":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"dbeb328acc5a5a14","prefixes":{"*":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"9e6e5f626bc3d43c","prefixes":{"":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"66659e79ff807f39","prefixes":{"":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"ce965bb06760436e","prefixes":{"":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"ca8e04a5cdd8fd1f","prefixes":{"":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"1084f1e2b04f5f93","prefixes":{"":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"04b3778457a3ba99","prefixes":{"*":{"product":61,"type":0}}}, // [Adconion Media Group]
-  {"hash":"1b843f2f1a39c98b","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"8c7beead1ea37382","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"2b59e3efe59d97d5","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"518308907f5f69a2","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"07d4474fae9c6b06","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"47c590566f0c869a","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"409240a38e5e72b9","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"98421a6d07f5517b","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"4f00fb001635132a","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"c6ba94708f6d7d53","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"caae109e8a3bec4f","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"9137b5cdfcb54ca8","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"ae96d818a0674db2","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"f67fecc339ee273d","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"763cc84e4a6c6fce","prefixes":{"":{"product":62,"type":0}}}, // [Adform]
-  {"hash":"170707627205d14d","prefixes":{"*":{"product":63,"type":0}}}, // [Adition]
-  {"hash":"4b3783127a962269","prefixes":{"":{"product":63,"type":0}}}, // [Adition]
-  {"hash":"457cb5e9c72500bd","prefixes":{"":{"product":63,"type":0}}}, // [Adition]
-  {"hash":"0f529dc32c1b9057","prefixes":{"":{"product":63,"type":0}}}, // [Adition]
-  {"hash":"e63845bad50263e0","prefixes":{"":{"product":64,"type":0}}}, // [Active Agent]
-  {"hash":"08b8d8e397848984","prefixes":{"":{"product":64,"type":0}}}, // [Active Agent]
-  {"hash":"146ac0ff21924e7d","prefixes":{"*":{"product":63,"type":0}}}, // [Adition]
-  {"hash":"a51da6855de3a256","prefixes":{"":{"product":65,"type":0}}}, // [mov.ad GmbH]
-  {"hash":"150498b9d10f053f","prefixes":{"*":{"product":63,"type":0}}}, // [Adition]
-  {"hash":"fa1803e00adafe6b","prefixes":{"":{"product":65,"type":0}}}, // [mov.ad GmbH]
-  {"hash":"ba820e9bd3ccd291","prefixes":{"":{"product":65,"type":0}}}, // [mov.ad GmbH]
-  {"hash":"73f70045beea25cc","prefixes":{"":{"product":65,"type":0}}}, // [mov.ad GmbH]
-  {"hash":"14725cb7b6e3ed94","prefixes":{"":{"product":65,"type":0}}}, // [mov.ad GmbH]
-  {"hash":"fd2740cbee10696e","prefixes":{"":{"product":65,"type":0}}}, // [mov.ad GmbH]
-  {"hash":"e150d6342c6a3952","prefixes":{"*":{"product":66,"type":0}}}, // [AdJug]
-  {"hash":"50b8b93a8b536983","prefixes":{"*":{"product":67,"type":0}}}, // [AdJuggler]
-  {"hash":"85335d83efc9839b","prefixes":{"*":{"product":67,"type":0}}}, // [AdJuggler]
-  {"hash":"08f0bb45326cffe3","prefixes":{"*":{"product":68,"type":0}}}, // [AdKeeper]
-  {"hash":"5e2b2393dad3f5eb","prefixes":{"*":{"product":68,"type":0}}}, // [AdKeeper]
-  {"hash":"da818bcf61df9002","prefixes":{"*":{"product":68,"type":0}}}, // [AdKeeper]
-  {"hash":"846fc96edd68e2f8","prefixes":{"*":{"product":69,"type":0}}}, // [AdKnife]
-  {"hash":"914d48df3d7aeaae","prefixes":{"*":{"product":70,"type":0}}}, // [Adku]
-  {"hash":"8a5b58174cc938bf","prefixes":{"*":{"product":71,"type":0}}}, // [AdLantic Online Advertising]
-  {"hash":"218eb49612488266","prefixes":{"":{"product":72,"type":1}}}, // [Adloox]
-  {"hash":"85c9a55ea5b2a32a","prefixes":{"data":{"product":72,"type":1},"am":{"product":72,"type":1}}}, // [Adloox] [Adloox]
-  {"hash":"9827ba4725b53982","prefixes":{"":{"product":72,"type":1}}}, // [Adloox]
-  {"hash":"bfbbf6b81b109b36","prefixes":{"*":{"product":73,"type":0}}}, // [adMarketplace]
-  {"hash":"006d6718806b7562","prefixes":{"*":{"product":74,"type":0}}}, // [AdMotion]
-  {"hash":"43871f2ce46890ca","prefixes":{"":{"product":75,"type":0}}}, // [AdMotion USA Inc.]
-  {"hash":"2648f20c5fa7ee09","prefixes":{"":{"product":75,"type":0}}}, // [AdMotion USA Inc.]
-  {"hash":"63e0b0f085a8b214","prefixes":{"*":{"product":76,"type":0}}}, // [Digilant]
-  {"hash":"7288a07f340911e5","prefixes":{"":{"product":77,"type":0}}}, // [Adnologies GmbH]
-  {"hash":"a9fe843107d85e5c","prefixes":{"":{"product":77,"type":0}}}, // [Adnologies GmbH]
-  {"hash":"230c59512261d73d","prefixes":{"cdn-":{"product":77,"type":0}}}, // [Adnologies GmbH]
-  {"hash":"8ca4fb13619b77f1","prefixes":{"*":{"product":78,"type":1}}}, // [Adometry by Google]
-  {"hash":"18652cba5445b34f","prefixes":{"":{"product":79,"type":0}}}, // [Adperium BV]
-  {"hash":"6d09f83aefc4501e","prefixes":{"*":{"product":80,"type":0}}}, // [AdPredictive]
-  {"hash":"70732e61af9adb0a","prefixes":{"":{"product":81,"type":0}}}, // [Usemax]
-  {"hash":"b4ede094fe706ace","prefixes":{"*":{"product":82,"type":0}}}, // [Adrime]
-  {"hash":"b19cfc95f67d0fa7","prefixes":{"*":{"product":82,"type":0}}}, // [Adrime]
-  {"hash":"a6e49b6248014fa6","prefixes":{"*":{"product":83,"type":0}}}, // [AdRiver]
-  {"hash":"4a53a59490c4a38e","prefixes":{"*":{"product":84,"type":1}}}, // [Adroit Interactive]
-  {"hash":"683e22cafa5f3bd9","prefixes":{"":{"product":84,"type":1}}}, // [Adroit Interactive]
-  {"hash":"02e8a15ca61fbc33","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"a3c3a62c565da599","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"73e23ad84157f244","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"b8bd71aaaa715a18","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"34049e798c80bbab","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"838eef1c1fe8af0c","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"3a7e3dfea00e8162","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"0173cd7bab46f6fd","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"c14663d78cbafed8","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"308a1884ba632254","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"0e219f63d92e9f36","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"f01c179c5f1e71ec","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"37523eaeb9b1fe5b","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"65eb7e97acb7c098","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"3caa5b10b768447a","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"c8ca517332beacb1","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"8af902c81b793154","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"38ed924c01545a3b","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"5b57e356a62d6828","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"4281a0a413796f1b","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"66e356358c42a9dd","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"ebe26069a0940456","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"9d2283ab81bb7a35","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"d5e05919c2d72fad","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"519afd00add32a74","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"88d48f3ceb8d02bb","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"d93b7d2660301b12","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"6a71009da4358f28","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"71f627786ab80897","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"f1b3147102656b41","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"1a3040f79f3eda5d","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"1c81402568ca4c6f","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"5a0f681f5d3714ed","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"fb3d4d280f621627","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"6811c6e8c717b25b","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"2b559615c990392b","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"d8447dd40d9ce63f","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"98a32e82bd6110c6","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"e3ff44ab0bbc3669","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"d8a244effa85d1e6","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"fa65d62c20cc94bb","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"1d55dfbdf9f318d1","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"e06269227a02ae45","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"2d2bf9a9cb6e9f86","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"0adbf6085946bbf6","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"61d2d4f25972fccd","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"d9506dcf3ab8ec68","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"61448b088aea7146","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"12b1ed92371498e2","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"b8f763d46b3d230a","prefixes":{"":{"product":87,"type":0}}}, // [Integral Ad Science Firewall]
-  {"hash":"d4033ecbe069d318","prefixes":{"":{"product":86,"type":1}}}, // [Campaign Monitor]
-  {"hash":"b45ea1eb9c9290a1","prefixes":{"*":{"product":88,"type":0}}}, // [AdShuffle]
-  {"hash":"333bed71fe872c88","prefixes":{"":{"product":89,"type":0}}}, // [ADSOVO]
-  {"hash":"ad77e48d841a15a8","prefixes":{"":{"product":89,"type":0}}}, // [ADSOVO]
-  {"hash":"f822525b349866b4","prefixes":{"*":{"product":90,"type":0}}}, // [ADTECH GmbH]
-  {"hash":"6cda8dd1b92f6c35","prefixes":{"*":{"product":90,"type":0}}}, // [ADTECH GmbH]
-  {"hash":"4d592efbff40197f","prefixes":{"*":{"product":91,"type":0}}}, // [Adtelligence]
-  {"hash":"0f57dc611a2e469e","prefixes":{"":{"product":92,"type":0}}}, // [Adverline]
-  {"hash":"ef6cb8337223cbd6","prefixes":{"*":{"product":92,"type":0}}}, // [Adverline]
-  {"hash":"1902c407bbf1add8","prefixes":{"*":{"product":93,"type":0}}}, // [AOL Advertising.com]
-  {"hash":"c0956c63084023a8","prefixes":{"":{"product":94,"type":0}}}, // [Adap.tv Inc. (AdX)]
-  {"hash":"f029d231882ed252","prefixes":{"":{"product":94,"type":0}}}, // [Adap.tv Inc. (AdX)]
-  {"hash":"ee175aa478efb9b3","prefixes":{"*":{"product":93,"type":0}}}, // [AOL Advertising.com]
-  {"hash":"c0fff6b8232710c4","prefixes":{"*":{"product":93,"type":0}}}, // [AOL Advertising.com]
-  {"hash":"a846e3340ac27ada","prefixes":{"":{"product":95,"type":1}}}, // [Convertro Inc]
-  {"hash":"548e9e34dbc275b6","prefixes":{"":{"product":96,"type":0}}}, // [Tacoda]
-  {"hash":"e9695f56eaa054e2","prefixes":{"":{"product":93,"type":0}}}, // [AOL Advertising.com]
-  {"hash":"f7f6bc8c4345347a","prefixes":{"*":{"product":97,"type":0}}}, // [Digital Control GmbH (Advolution)]
-  {"hash":"484a656ace404140","prefixes":{"":{"product":97,"type":0}}}, // [Digital Control GmbH (Advolution)]
-  {"hash":"a224f896601ec717","prefixes":{"":{"product":97,"type":0}}}, // [Digital Control GmbH (Advolution)]
-  {"hash":"3a79a6d9af12ef9a","prefixes":{"*":{"product":98,"type":0}}}, // [AdXcel]
-  {"hash":"b3dec77d20a55dcb","prefixes":{"*":{"product":98,"type":0}}}, // [AdXcel]
-  {"hash":"1f25b55eca65221c","prefixes":{"":{"product":98,"type":0}}}, // [AdXcel]
-  {"hash":"f531a655b1982ee7","prefixes":{"":{"product":99,"type":1}}}, // [Alenty S.A.S]
-  {"hash":"b884f71dddd78a28","prefixes":{"":{"product":100,"type":0}}}, // [DoubleClick Bid Manager]
-  {"hash":"839eb75d0e9ef128","prefixes":{"":{"product":101,"type":0}}}, // [BigaBid Media Ltd.]
-  {"hash":"ad920773d5c3e050","prefixes":{"":{"product":102,"type":0}}}, // [Cogo Labs, Inc.]
-  {"hash":"6cbe6bc5d5fed35c","prefixes":{"":{"product":103,"type":1}}}, // [AudienceProject]
-  {"hash":"78cfcb50606e44f8","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"37f3aa55bd48760c","prefixes":{"":{"product":105,"type":0}}}, // [PocketMath]
-  {"hash":"fa92c520ca116999","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"26d760f54a265d93","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"c046bec428f602d5","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"7fbe2c9290629394","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"16d261a6c03c3de9","prefixes":{"":{"product":107,"type":0}}}, // [Immedium, Inc.]
-  {"hash":"1787c49522ce0278","prefixes":{"":{"product":108,"type":0}}}, // [Fractional Media, LLC]
-  {"hash":"45ccf99ac2ed3af1","prefixes":{"":{"product":108,"type":0}}}, // [Fractional Media, LLC]
-  {"hash":"8c431268cc5c116b","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"645dd2a279a77bf5","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"53aaf4b4f2f2cc8b","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"a6175c31fc587fa2","prefixes":{"":{"product":110,"type":0}}}, // [Epic Combo Malta Ltd.]
-  {"hash":"c0e7c2ad3d5d28a0","prefixes":{"":{"product":110,"type":0}}}, // [Epic Combo Malta Ltd.]
-  {"hash":"b6a3ce0dea65f762","prefixes":{"":{"product":111,"type":0}}}, // [Quixey]
-  {"hash":"29e07de898fa18f4","prefixes":{"":{"product":111,"type":0}}}, // [Quixey]
-  {"hash":"1959efaae117c9fa","prefixes":{"":{"product":112,"type":0}}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"0a59c33253f15970","prefixes":{"":{"product":113,"type":0}}}, // [TapTap Networks S.L.]
-  {"hash":"383161133467d12b","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"e2e18e4ba75c8e58","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"1f9da694ae6dd7cf","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"5038b4de783848d4","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"3542b95dcaa08c84","prefixes":{"":{"product":114,"type":1}}}, // [ComScore (AdXpose)]
-  {"hash":"7bbbdfeb3d7b8ad3","prefixes":{"*":{"product":115,"type":0}}}, // [AdYard]
-  {"hash":"2ff57c503c5f110d","prefixes":{"":{"product":116,"type":0}}}, // [Affectv]
-  {"hash":"7558d4293841e1f0","prefixes":{"":{"product":116,"type":0}}}, // [Affectv]
-  {"hash":"a8adad05a6ff5945","prefixes":{"":{"product":116,"type":0}}}, // [Affectv]
-  {"hash":"cd1a91dee22478d6","prefixes":{"":{"product":116,"type":0}}}, // [Affectv]
-  {"hash":"ebca243af085210f","prefixes":{"":{"product":116,"type":0}}}, // [Affectv]
-  {"hash":"bc7fe0dc5bf3e869","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"c894a0e3f6a6b627","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"bfdba513f8cb5b8b","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"1227c609f898a707","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"4f884065e1e88de2","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"93d5950ea0bfe437","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"560c5b8e23e29733","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"28d74bfc94c9635f","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"8f7f83e4f5f9e2c0","prefixes":{"":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"fd2b5d860fd44749","prefixes":{"*":{"product":10,"type":1}}}, // [Affilinet GmbH]
-  {"hash":"1d0953961a14d2fc","prefixes":{"*":{"product":117,"type":0}}}, // [SET.tv]
-  {"hash":"5edf63353d8e0fcd","prefixes":{"":{"product":117,"type":0}}}, // [SET.tv]
-  {"hash":"e4e5eb11299f703e","prefixes":{"*":{"product":118,"type":0}}}, // [Adroit Digital Solutions (ADS)]
-  {"hash":"e5cf3445847fef93","prefixes":{"*":{"product":118,"type":0}}}, // [Adroit Digital Solutions (ADS)]
-  {"hash":"8441a2216167c3d4","prefixes":{"at":{"product":99,"type":1}}}, // [Alenty S.A.S]
-  {"hash":"b9dab57457cf6477","prefixes":{"":{"product":99,"type":1}}}, // [Alenty S.A.S]
-  {"hash":"94b55596aadb2893","prefixes":{"":{"product":99,"type":1}}}, // [Alenty S.A.S]
-  {"hash":"16b31027fd40c9ad","prefixes":{"":{"product":99,"type":1}}}, // [Alenty S.A.S]
-  {"hash":"bb4adabba7b0b6b8","prefixes":{"*":{"product":119,"type":0}}}, // [AppNexus Inc]
-  {"hash":"3b2105469f3563e3","prefixes":{"*":{"product":120,"type":0}}}, // [Adfusion]
-  {"hash":"2f29d38052b5a8a6","prefixes":{"":{"product":121,"type":0}}}, // [ARC Media Group]
-  {"hash":"c133787bd9e605a7","prefixes":{"":{"product":122}}}, // [Semasio GmbH]
-  {"hash":"b9a83d8bd4f31543","prefixes":{"":{"product":123,"type":0}}}, // [Mojiva]
-  {"hash":"2a1b04ad13f24350","prefixes":{"":{"product":123,"type":0}}}, // [Mojiva]
-  {"hash":"a3c6b5ffd4fe1547","prefixes":{"":{"product":124,"type":0}}}, // [Mocean mobile, Inc.]
-  {"hash":"0d52aafa33281228","prefixes":{"":{"product":125,"type":0}}}, // [Phluant]
-  {"hash":"655e31ecb8719994","prefixes":{"":{"product":125,"type":0}}}, // [Phluant]
-  {"hash":"dca17bd2f3edb917","prefixes":{"":{"product":125,"type":0}}}, // [Phluant]
-  {"hash":"53de58004f88a1c2","prefixes":{"*":{"product":126,"type":0}}}, // [AdSpirit]
-  {"hash":"6a1ebf671194b458","prefixes":{"*":{"product":126,"type":0}}}, // [AdSpirit]
-  {"hash":"6ae5a4877aab564f","prefixes":{"":{"product":126,"type":0}}}, // [AdSpirit]
-  {"hash":"9dcf8d17ea42466e","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"32e0acbf3d2ecfcf","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"708d275466f5230b","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"7532d83428e05417","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"3258e49c5f504307","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"2c381faaa3144a37","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"776a64cc3a9c6f81","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"d38247a8e8d14a7c","prefixes":{"*":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"50e5ca70dbb69c03","prefixes":{"":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"c1dfde405c173e3b","prefixes":{"":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"5bce52b0f221aac2","prefixes":{"":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"5a0e5730145156e2","prefixes":{"":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"c081c626ad2c0f1f","prefixes":{"":{"product":127,"type":0}}}, // [ConvertMedia Ltd.]
-  {"hash":"a31f53c0c58e67c0","prefixes":{"":{"product":128,"type":0}}}, // [ATK Media GmbH]
-  {"hash":"514b4f19cbdabb49","prefixes":{"":{"product":128,"type":0}}}, // [ATK Media GmbH]
-  {"hash":"264493bb5046087f","prefixes":{"":{"product":128,"type":0}}}, // [ATK Media GmbH]
-  {"hash":"f4e40d6832493420","prefixes":{"":{"product":128,"type":0}}}, // [ATK Media GmbH]
-  {"hash":"126b6492c0b1b53a","prefixes":{"*":{"product":129,"type":0}}}, // [Atlas]
-  {"hash":"0493e6c92c59fd4d","prefixes":{"":{"product":129,"type":0}}}, // [Atlas]
-  {"hash":"d6d40b4417fefcf6","prefixes":{"":{"product":129,"type":0}}}, // [Atlas]
-  {"hash":"0b16a7cf8dcb70ee","prefixes":{"*":{"product":130,"type":0}}}, // [AudienceScience]
-  {"hash":"edbae80f2449aaee","prefixes":{"":{"product":131,"type":0}}}, // [BeWebMedia]
-  {"hash":"c1196b1418bf9de9","prefixes":{"*":{"product":132,"type":0}}}, // [Bidalpha Inc.]
-  {"hash":"87016c0f34162bc6","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"2db3b8adb9c37590","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"a10756ccfb034a50","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"1ea7188c5cc22ccf","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"c70dfe98c3735972","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"05aa49d024d6d67c","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"27c08401857f47aa","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"9a569266b426d074","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"5a764c1f870e4e38","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"64b993405c35034f","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"afe660eca2d01217","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"cd398b1d3fe6caf4","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"bb2cf5a27552ba10","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"b79ee8778f5b56d6","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"cae97638b357a30e","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"2c552297aa3abdf1","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"75bbf901ed30d891","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"365bc710167be24c","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"49849f3497cc7ff5","prefixes":{"":{"product":133,"type":0}}}, // [AdGear Technologies Inc.]
-  {"hash":"14bb8555907973f5","prefixes":{"":{"product":134,"type":1}}}, // [BlueKai]
-  {"hash":"db6cb381e20a210a","prefixes":{"":{"product":134,"type":1}}}, // [BlueKai]
-  {"hash":"8e4e07437ae4b61c","prefixes":{"*":{"product":135,"type":0}}}, // [Bluestreak]
-  {"hash":"4bb6a17c8b5ec2e7","prefixes":{"":{"product":136,"type":0}}}, // [blurbIQ]
-  {"hash":"4aefb106f857a0de","prefixes":{"":{"product":136,"type":0}}}, // [blurbIQ]
-  {"hash":"a7b4452428f93120","prefixes":{"":{"product":136,"type":0}}}, // [blurbIQ]
-  {"hash":"38f01d050feb50e8","prefixes":{"":{"product":136,"type":0}}}, // [blurbIQ]
-  {"hash":"d4ab70ba7caf1ed7","prefixes":{"":{"product":137,"type":0}}}, // [Brand.net]
-  {"hash":"94655d9cadd8e829","prefixes":{"":{"product":137,"type":0}}}, // [Brand.net]
-  {"hash":"f3347a75843fd9c6","prefixes":{"":{"product":137,"type":0}}}, // [Brand.net]
-  {"hash":"60e2856d32c1da23","prefixes":{"*":{"product":138,"type":0}}}, // [Brandscreen Inc.]
-  {"hash":"16460b1ac6e3b229","prefixes":{"*":{"product":139,"type":0}}}, // [BrightRoll Inc.]
-  {"hash":"814fef93d6498b58","prefixes":{"*":{"product":139,"type":0}}}, // [BrightRoll Inc.]
-  {"hash":"72fc1d7c40b9af03","prefixes":{"":{"product":140,"type":0}}}, // [Brightroll Inc.]
-  {"hash":"80f8944423cc936c","prefixes":{"*":{"product":141,"type":0}}}, // [Vindico]
-  {"hash":"bf2db20b09960c7b","prefixes":{"":{"product":141,"type":0}}}, // [Vindico]
-  {"hash":"1e90c625da6683a5","prefixes":{"":{"product":142,"type":0}}}, // [Spark Flow S.A.]
-  {"hash":"d385e514fe92e6d9","prefixes":{"":{"product":143,"type":0}}}, // [Aarki, Inc.]
-  {"hash":"4646e46d55455ffe","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"a8c5f49831b36ab9","prefixes":{"*":{"product":145,"type":0}}}, // [Burst Media LLC d/b/a AdConductor]
-  {"hash":"f22276edaf005231","prefixes":{"*":{"product":146,"type":0}}}, // [Advertising.com Dynamic Retargeter]
-  {"hash":"220db526eb84992d","prefixes":{"*":{"product":147,"type":0}}}, // [NetAffiliation]
-  {"hash":"cda3d9612026866c","prefixes":{"*":{"product":147,"type":0}}}, // [NetAffiliation]
-  {"hash":"9f8018bcbf15a592","prefixes":{"*":{"product":148,"type":1}}}, // [C3 Metrics Inc.]
-  {"hash":"78ec342986654215","prefixes":{"":{"product":148,"type":1}}}, // [C3 Metrics Inc.]
-  {"hash":"e4ad94837095a9bc","prefixes":{"*":{"product":148,"type":1}}}, // [C3 Metrics Inc.]
-  {"hash":"32401b2118eff57a","prefixes":{"":{"product":149,"type":0}}}, // [CAPITALDATA (SARL)]
-  {"hash":"a5f9db92cb5aeb3e","prefixes":{"":{"product":149,"type":0}}}, // [CAPITALDATA (SARL)]
-  {"hash":"ae12db7e0621ec0b","prefixes":{"*":{"product":149,"type":0}}}, // [CAPITALDATA (SARL)]
-  {"hash":"d7c4970fde31fd62","prefixes":{"*":{"product":150,"type":0}}}, // [e-Planning]
-  {"hash":"20cadab7abdae752","prefixes":{"*":{"product":151,"type":0}}}, // [Chango Inc.]
-  {"hash":"38363f7ac872a916","prefixes":{"":{"product":152,"type":0}}}, // [Chango]
-  {"hash":"114215c6a5b66e37","prefixes":{"":{"product":152,"type":0}}}, // [Chango]
-  {"hash":"1ab7b29d135c11fc","prefixes":{"":{"product":153,"type":1}}}, // [Channel Intelligence]
-  {"hash":"6e8e21cf50387d5b","prefixes":{"":{"product":153,"type":1}}}, // [Channel Intelligence]
-  {"hash":"cbd8c46855691ac9","prefixes":{"*":{"product":153,"type":1}}}, // [Channel Intelligence]
-  {"hash":"8bde0d3ba731b24b","prefixes":{"":{"product":153,"type":1}}}, // [Channel Intelligence]
-  {"hash":"d415664f4794184e","prefixes":{"":{"product":153,"type":1}}}, // [Channel Intelligence]
-  {"hash":"bc8edad5208e36aa","prefixes":{"*":{"product":153,"type":1}}}, // [Channel Intelligence]
-  {"hash":"00900e4af3795b7d","prefixes":{"":{"product":154,"type":1}}}, // [Chartbeat Inc]
-  {"hash":"dddd416675de98d6","prefixes":{"":{"product":154,"type":1}}}, // [Chartbeat Inc]
-  {"hash":"085835cbbea3af5b","prefixes":{"":{"product":154,"type":1}}}, // [Chartbeat Inc]
-  {"hash":"0a5fd555ed989cf1","prefixes":{"":{"product":154,"type":1}}}, // [Chartbeat Inc]
-  {"hash":"38e6dfa04599d610","prefixes":{"":{"product":154,"type":1}}}, // [Chartbeat Inc]
-  {"hash":"282ab213b57d8196","prefixes":{"":{"product":154,"type":1}}}, // [Chartbeat Inc]
-  {"hash":"465922959fd197de","prefixes":{"*":{"product":155,"type":0}}}, // [Choicestream Inc.]
-  {"hash":"07b64c6d94aaeede","prefixes":{"*":{"product":156,"type":0}}}, // [AddThis, Inc]
-  {"hash":"8285ed75ebbab1bf","prefixes":{"*":{"product":156,"type":0}}}, // [AddThis, Inc]
-  {"hash":"397da235f9c6c4dc","prefixes":{"*":{"product":157,"type":0}}}, // [Platform 161]
-  {"hash":"3e4380669a97a9da","prefixes":{"":{"product":157,"type":0}}}, // [Platform 161]
-  {"hash":"0cf7c3db283e4fde","prefixes":{"":{"product":158,"type":0}}}, // [ClickPoint]
-  {"hash":"e3f610966ee4998e","prefixes":{"":{"product":159,"type":0}}}, // [Cobalt Group]
-  {"hash":"5458332ef0eff5a0","prefixes":{"":{"product":159,"type":0}}}, // [Cobalt Group]
-  {"hash":"755391831ca3c171","prefixes":{"*":{"product":159,"type":0}}}, // [Cobalt Group]
-  {"hash":"82d7785d13750576","prefixes":{"*":{"product":159,"type":0}}}, // [Cobalt Group]
-  {"hash":"f1b10b28e8a1e8a9","prefixes":{"*":{"product":159,"type":0}}}, // [Cobalt Group]
-  {"hash":"ca9dc80141cf19b5","prefixes":{"*":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"d02173b857f779a2","prefixes":{"*":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"987bec8a1c07a02f","prefixes":{"*":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"da18ae94f7dd99ab","prefixes":{"":{"product":161,"type":0}}}, // [Tagtoo Tech Limited]
-  {"hash":"5e1256c5e919daf9","prefixes":{"":{"product":162,"type":0}}}, // [wayStorm Co., Ltd.]
-  {"hash":"9e92efa06a26b83d","prefixes":{"*":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"cf3c8c24a0eb24a6","prefixes":{"*":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"eac24a30a92872f1","prefixes":{"":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"a508105d922876fe","prefixes":{"":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"b7f1551e6c1615df","prefixes":{"":{"product":160,"type":0}}}, // [Cognitive Match Limited]
-  {"hash":"e56a388aae6f063e","prefixes":{"*":{"product":163,"type":0}}}, // [Collective Media LLC]
-  {"hash":"adc75d0087df3e89","prefixes":{"":{"product":164,"type":1}}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"6f0ca09cdc147fb0","prefixes":{"":{"product":164,"type":1}}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"11f6ca20d229d8ad","prefixes":{"":{"product":164,"type":1}}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"e4d55634b8d3126d","prefixes":{"":{"product":164,"type":1}}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"6100cc0a622faa8e","prefixes":{"":{"product":165,"type":1}}}, // [ComScore Validated Campaign Essentials (vCE)]
-  {"hash":"a30e99f000f781c7","prefixes":{"":{"product":165,"type":1}}}, // [ComScore Validated Campaign Essentials (vCE)]
-  {"hash":"1ee7cb55ae2cb071","prefixes":{"":{"product":164,"type":1}}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"7dfd981d4c018953","prefixes":{"":{"product":165,"type":1}}}, // [ComScore Validated Campaign Essentials (vCE)]
-  {"hash":"5011cb94579baba5","prefixes":{"*":{"product":166,"type":1}}}, // [VoiceFive (ComScore)]
-  {"hash":"a0cff89b286fc309","prefixes":{"":{"product":166,"type":1}}}, // [VoiceFive (ComScore)]
-  {"hash":"4782e75d195d3144","prefixes":{"":{"product":166,"type":1}}}, // [VoiceFive (ComScore)]
-  {"hash":"e63472329b04aab9","prefixes":{"":{"product":166,"type":1}}}, // [VoiceFive (ComScore)]
-  {"hash":"5814e7da11d65131","prefixes":{"":{"product":166,"type":1}}}, // [VoiceFive (ComScore)]
-  {"hash":"26c9b653ef6bfb53","prefixes":{"*":{"product":167,"type":0}}}, // [Connexity LLC]
-  {"hash":"eb38b3659a232a56","prefixes":{"":{"product":167,"type":0}}}, // [Connexity LLC]
-  {"hash":"08abcdb9184877f9","prefixes":{"":{"product":167,"type":0}}}, // [Connexity LLC]
-  {"hash":"65a439ff09c9f7dc","prefixes":{"":{"product":167,"type":0}}}, // [Connexity LLC]
-  {"hash":"b3afc505f1f5487b","prefixes":{"":{"product":167,"type":0}}}, // [Connexity LLC]
-  {"hash":"b35a41328f2a6830","prefixes":{"*":{"product":168,"type":1}}}, // [Constant Contact]
-  {"hash":"e7a596af94ad559e","prefixes":{"":{"product":169,"type":0}}}, // [ContextWeb Inc.]
-  {"hash":"25ccc25c112607e9","prefixes":{"":{"product":169,"type":0}}}, // [ContextWeb Inc.]
-  {"hash":"44e652990824ddee","prefixes":{"":{"product":169,"type":0}}}, // [ContextWeb Inc.]
-  {"hash":"8eac48fda4ccaec8","prefixes":{"":{"product":169,"type":0}}}, // [ContextWeb Inc.]
-  {"hash":"0b4eee92ed72b991","prefixes":{"ant-":{"product":170,"type":0}}}, // [Conversive BV]
-  {"hash":"dae78afe5d5cc699","prefixes":{"":{"product":170,"type":0}}}, // [Conversive BV]
-  {"hash":"7729d423a7fc3adf","prefixes":{"*":{"product":95,"type":1}}}, // [Convertro Inc]
-  {"hash":"cdff1e442509fafe","prefixes":{"":{"product":171,"type":1}}}, // [IBM Digital Analytics]
-  {"hash":"a07829ef9a9d6762","prefixes":{"*":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"43c19f0523939982","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"2c4f3b76ebfafe80","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"078603692b0949b1","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"aa8844a1d3e7c3aa","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"15ef2aafaa03e60b","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"5f1ef71046a359f7","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"2fb5d0d81abd43be","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"75ce1d1edaf8f426","prefixes":{"":{"product":172,"type":0}}}, // [Crimtan]
-  {"hash":"a7b80b09927034f7","prefixes":{"*":{"product":173,"type":0}}}, // [Criteo]
-  {"hash":"3a96f385ff402ab6","prefixes":{"*":{"product":173,"type":0}}}, // [Criteo]
-  {"hash":"189c3bab631d09cf","prefixes":{"":{"product":174,"type":0}}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"3d9109a2e81eee2d","prefixes":{"":{"product":174,"type":0}}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"e7170acff5d6fda1","prefixes":{"":{"product":174,"type":0}}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"e0496c88da22371f","prefixes":{"":{"product":174,"type":0}}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"59ab4e7744543242","prefixes":{"":{"product":175,"type":0}}}, // [Platform One]
-  {"hash":"f6b2b21a0a0417b3","prefixes":{"":{"product":175,"type":0}}}, // [Platform One]
-  {"hash":"4384a84e6276861a","prefixes":{"*":{"product":176,"type":0}}}, // [Dapper Inc.]
-  {"hash":"1ccbc5b91f4c5fc9","prefixes":{"*":{"product":177,"type":0}}}, // [DataXu Inc.]
-  {"hash":"4840192a8cb4b1ca","prefixes":{"*":{"product":177,"type":0}}}, // [DataXu Inc.]
-  {"hash":"b50faf8c7e5fc38c","prefixes":{"":{"product":178,"type":1}}}, // [Aperture]
-  {"hash":"bdcf8ed53f1b3802","prefixes":{"*":{"product":179,"type":1}}}, // [Rakuten Attribution]
-  {"hash":"d31e7c4efd1a5191","prefixes":{"*":{"product":179,"type":1}}}, // [Rakuten Attribution]
-  {"hash":"68318c6d8f72133b","prefixes":{"*":{"product":179,"type":1}}}, // [Rakuten Attribution]
-  {"hash":"c0c4eb0ce58ef4b1","prefixes":{"*":{"product":179,"type":1}}}, // [Rakuten Attribution]
-  {"hash":"ae713ee10231204e","prefixes":{"*":{"product":180,"type":0}}}, // [AdAction]
-  {"hash":"e4282cef85ee5728","prefixes":{"":{"product":181,"type":0}}}, // [Demandbase Inc.]
-  {"hash":"79f6c3d16c278e94","prefixes":{"":{"product":181,"type":0}}}, // [Demandbase Inc.]
-  {"hash":"13e7a7b6c40ef05b","prefixes":{"":{"product":181,"type":0}}}, // [Demandbase Inc.]
-  {"hash":"57e736fc045f8fbd","prefixes":{"":{"product":181,"type":0}}}, // [Demandbase Inc.]
-  {"hash":"82137a4a2aa17f33","prefixes":{"*":{"product":182,"type":0}}}, // [Omniture]
-  {"hash":"ddc305710749f5b7","prefixes":{"*":{"product":182,"type":0}}}, // [Omniture]
-  {"hash":"3cd74441fc237226","prefixes":{"*":{"product":182,"type":0}}}, // [Omniture]
-  {"hash":"5b40000c858b730d","prefixes":{"":{"product":183,"type":0}}}, // [Rovion, Inc.]
-  {"hash":"47d66d29363322cd","prefixes":{"":{"product":184,"type":0}}}, // [AdHui.com LLC]
-  {"hash":"10a0efb999eedf90","prefixes":{"":{"product":184,"type":0}}}, // [AdHui.com LLC]
-  {"hash":"b1bf29ae383ea0cd","prefixes":{"":{"product":185,"type":0}}}, // [Bidlab sp. z o.o]
-  {"hash":"baa26df04dbce196","prefixes":{"":{"product":185,"type":0}}}, // [Bidlab sp. z o.o]
-  {"hash":"c3f807fb12d64ef3","prefixes":{"":{"product":186,"type":0}}}, // [CyberAgent Inc.]
-  {"hash":"8caed248711d066a","prefixes":{"":{"product":186,"type":0}}}, // [CyberAgent Inc.]
-  {"hash":"03524472b71baf6f","prefixes":{"":{"product":187,"type":0}}}, // [Relay42 Technology B.V.]
-  {"hash":"c26a754afcf8496d","prefixes":{"":{"product":187,"type":0}}}, // [Relay42 Technology B.V.]
-  {"hash":"fa7ea4c2400b9304","prefixes":{"":{"product":187,"type":0}}}, // [Relay42 Technology B.V.]
-  {"hash":"f91d12ea09409395","prefixes":{"":{"product":187,"type":0}}}, // [Relay42 Technology B.V.]
-  {"hash":"a3404139a451726c","prefixes":{"":{"product":188,"type":1}}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"072f7bf8cea1803c","prefixes":{"":{"product":188,"type":1}}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"8a6e324bbf4e02dc","prefixes":{"":{"product":188,"type":1}}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"e59faa8d364c3ad2","prefixes":{"":{"product":188,"type":1}}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"fe39de2cc1550ee8","prefixes":{"":{"product":188,"type":1}}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"41808f1a9bcd4cdf","prefixes":{"":{"product":188,"type":1}}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"1774fa7feee9a3ba","prefixes":{"":{"product":189,"type":1}}}, // [Nielsen (Audience Measurement Platform)]
-  {"hash":"8bcfafa30bb9a496","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"04a15100eebd5238","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"37669b02a11574d6","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"b0e609cae76778ef","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"8602961190244c78","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"cf6160cc55083e3f","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"d8e0147c7067e033","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"fa4e638adbad854a","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"bfc104d8ae540578","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"a77b609ecb948524","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"5b2d6c6512b90826","prefixes":{"":{"product":191,"type":1}}}, // [Nielsen (Sales Effect)]
-  {"hash":"3f0eefad5865a4ed","prefixes":{"":{"product":192,"type":0}}}, // [Ohana Media India Private Limited]
-  {"hash":"ba149fc47bfe9e3c","prefixes":{"":{"product":192,"type":0}}}, // [Ohana Media India Private Limited]
-  {"hash":"3f8d8705aeaf2a69","prefixes":{"":{"product":193,"type":0}}}, // [Avail Intelligence]
-  {"hash":"3aa373d150e55bb8","prefixes":{"":{"product":193,"type":0}}}, // [Avail Intelligence]
-  {"hash":"01168e37c54407ec","prefixes":{"":{"product":193,"type":0}}}, // [Avail Intelligence]
-  {"hash":"9d0088e875d03291","prefixes":{"":{"product":194,"type":2}}}, // [Adobe Scene 7]
-  {"hash":"7892719f65634daf","prefixes":{"":{"product":195,"type":0}}}, // [Asda]
-  {"hash":"76913c314e7299f2","prefixes":{"":{"product":196,"type":0}}}, // [Adsfactor Limited]
-  {"hash":"ec3d301a1049a29c","prefixes":{"":{"product":197,"type":0}}}, // [Trademob GmbH]
-  {"hash":"0407237113d1e01a","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"3c2b08727db96f57","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"28d8cdf30ea5e75d","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"4ba6006c59a0afb3","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"34b0d82da56a6e14","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"c9293b8324f3a30f","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"78ad5395bf22ddd5","prefixes":{"":{"product":198,"type":0}}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"b0a5ecf647236d2a","prefixes":{"*":{"product":199,"type":0}}}, // [Telemetry Limited]
-  {"hash":"7d7cd86e56968411","prefixes":{"*":{"product":199,"type":0}}}, // [Telemetry Limited]
-  {"hash":"ccaf0946d1809711","prefixes":{"*":{"product":199,"type":0}}}, // [Telemetry Limited]
-  {"hash":"c1ee73ca85937956","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"b3ee9fcc7f773476","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"0dededd99d2513e4","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"efd59a0198028c96","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"b43b6c20f3008842","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"5d96f09a039b26e6","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"039408a17f3d50d7","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"16d696fe52cae068","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"ebb9da6e533fc7e4","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"c8afb150eb1b6ac1","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"1e21c92ae4d08330","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"07ef420d707be72c","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"3d9fb95e3108b648","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"938e971e186be4f8","prefixes":{"":{"product":200,"type":0}}}, // [AdPilot]
-  {"hash":"94682de65e11f128","prefixes":{"":{"product":201,"type":0}}}, // [ebookers]
-  {"hash":"32548cc45dcf9e95","prefixes":{"":{"product":201,"type":0}}}, // [ebookers]
-  {"hash":"baa9bf6209e38821","prefixes":{"":{"product":201,"type":0}}}, // [ebookers]
-  {"hash":"25a263451425f7e3","prefixes":{"*":{"product":202,"type":0}}}, // [Mashero GmbH]
-  {"hash":"4871ba81fe73b693","prefixes":{"":{"product":203,"type":0}}}, // [4wMarketPlace Srl]
-  {"hash":"f95f038fea1148ab","prefixes":{"*":{"product":204,"type":0}}}, // [Meetic Partners]
-  {"hash":"8c555d8aa0a96ecc","prefixes":{"*":{"product":205,"type":0}}}, // [Adara Media]
-  {"hash":"a31f9bce31634750","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"bb0d6b4eac177896","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"02712dc83414bc52","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"03cfa92cdadd6c20","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"4d8640e955380082","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"42ab78ba8d28d0d9","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"113f35a595990303","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"9566d797c39bca8e","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"caab6878aaf1b900","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"13581af42d29c3fd","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"8ad4e9b59b6cfebf","prefixes":{"":{"product":206,"type":1}}}, // [Adledge]
-  {"hash":"025223bda779fb50","prefixes":{"":{"product":207,"type":0}}}, // [Adledge: Ad Swapping]
-  {"hash":"6c7970d8fe11d946","prefixes":{"":{"product":208,"type":0}}}, // [LifeStreet Corportation]
-  {"hash":"226c377d19c24dca","prefixes":{"":{"product":208,"type":0}}}, // [LifeStreet Corportation]
-  {"hash":"bc64475cc35aba69","prefixes":{"":{"product":208,"type":0}}}, // [LifeStreet Corportation]
-  {"hash":"8a184297457cd4e1","prefixes":{"":{"product":208,"type":0}}}, // [LifeStreet Corportation]
-  {"hash":"900f97a5320abcc7","prefixes":{"":{"product":209,"type":0}}}, // [AdCirrus]
-  {"hash":"39b102bb2f01d1b4","prefixes":{"":{"product":210,"type":1}}}, // [Dimestore]
-  {"hash":"a144c6442bbc8a0a","prefixes":{"":{"product":210,"type":1}}}, // [Dimestore]
-  {"hash":"8020cac4e8fee023","prefixes":{"":{"product":210,"type":1}}}, // [Dimestore]
-  {"hash":"2dcefe5fe106e478","prefixes":{"*":{"product":211,"type":1}}}, // [GfK SE]
-  {"hash":"d8f9a95c0ea00853","prefixes":{"*":{"product":210,"type":1}}}, // [Dimestore]
-  {"hash":"829fbeefc45bca87","prefixes":{"*":{"product":212,"type":0}}}, // [Conversant CRM]
-  {"hash":"357a04f93d25ae56","prefixes":{"cdn":{"product":213},"log":{"product":213},"tps":{"product":213},"rtb":{"product":214,"type":0}}}, // [DoubleVerify Inc.] [DoubleVerify Inc.] [DoubleVerify Inc.] [DoubleVerify Inc. (BrandShield): Ad Swapping]
-  {"hash":"e88f040d82035294","prefixes":{"":{"product":213,"type":1}}}, // [DoubleVerify Inc.]
-  {"hash":"a378f9f7b3d5241c","prefixes":{"*":{"product":215,"type":0}}}, // [Dynamic Video LLC]
-  {"hash":"665ab90fa95fb304","prefixes":{"":{"product":215,"type":0}}}, // [Dynamic Video LLC]
-  {"hash":"1358623e271c4d67","prefixes":{"":{"product":215,"type":0}}}, // [Dynamic Video LLC]
-  {"hash":"a11e7a579fa98970","prefixes":{"*":{"product":216,"type":0}}}, // [Think RealTime, LLC]
-  {"hash":"9225aaedf058b2a2","prefixes":{"":{"product":217,"type":1}}}, // [Effective Measure]
-  {"hash":"36703887ac49b84b","prefixes":{"":{"product":217,"type":1}}}, // [Effective Measure]
-  {"hash":"eabfdf13f38b7671","prefixes":{"*":{"product":218,"type":0}}}, // [Adobe Media Optimizer]
-  {"hash":"e6c60b5e8bab7589","prefixes":{"*":{"product":218,"type":0}}}, // [Adobe Media Optimizer]
-  {"hash":"d4ca4e6c8a0bedf0","prefixes":{"*":{"product":218,"type":0}}}, // [Adobe Media Optimizer]
-  {"hash":"2e2899c7688fb6b3","prefixes":{"":{"product":219,"type":0}}}, // [Effiliation]
-  {"hash":"3a8f463e807ab596","prefixes":{"":{"product":219,"type":0}}}, // [Effiliation]
-  {"hash":"4c49524999954857","prefixes":{"":{"product":219,"type":0}}}, // [Effiliation]
-  {"hash":"99a4dc2c14dac648","prefixes":{"*":{"product":220,"type":0}}}, // [EmediateAd]
-  {"hash":"eb4d633002c35102","prefixes":{"*":{"product":220,"type":0}}}, // [EmediateAd]
-  {"hash":"a4155988849d9899","prefixes":{"":{"product":220,"type":0}}}, // [EmediateAd]
-  {"hash":"a29dc15ab67e4109","prefixes":{"*":{"product":220,"type":0}}}, // [EmediateAd]
-  {"hash":"244ed2f383a41c11","prefixes":{"*":{"product":220,"type":0}}}, // [EmediateAd]
-  {"hash":"f1d41523d742a4c4","prefixes":{"*":{"product":221,"type":0}}}, // [engage:BDR Inc.]
-  {"hash":"0c985c5bee46dcca","prefixes":{"":{"product":221,"type":0}}}, // [engage:BDR Inc.]
-  {"hash":"6f92a4165360659f","prefixes":{"":{"product":221,"type":0}}}, // [engage:BDR Inc.]
-  {"hash":"e65b14b1de797d5e","prefixes":{"":{"product":221,"type":0}}}, // [engage:BDR Inc.]
-  {"hash":"8908058eec675b88","prefixes":{"*":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"dae357b5105fb541","prefixes":{"*":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"7e5c5286bc6286af","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"6459463a599e26cf","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"d49c14999963fa7c","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"f7508ecdfd1b76f8","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"747ac3c2114de916","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"5445e9650966f2c9","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"b701368b6964f28f","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"b8d4853208b3d665","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"a3c05ce1535a1bb0","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"4113e02fa7f80330","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"1ec6c8299f47c92d","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"6213db1c94ff78b4","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"afdce1f639f05293","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"c00800107f132ba6","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"f989cf5678a6cd73","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"7248d6bb2e2d2812","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"5decec320495d46c","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"ffffd176ae6095cd","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"a0ead46cc7797fc4","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"d1b36183709cf97c","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"f08e0f4d46762277","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"1082450fce471aec","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"0c44a72359ff962b","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"c6ced7239fa526b8","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"bcd4afcb16a1bf83","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"c4629483e0f61849","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"3a8a51dc5059eb82","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"10d4846e0b0f6213","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"8e03e96054cde307","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"d1c591453eeceb89","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"a9ee5e0b07924cbe","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"4909d0f68d7f7dd5","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"1954dcac7d36e9a9","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"855fab1b44b2cc38","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"9a977de69b69e767","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"32c7999b9a328d48","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"675aab76d51e4be4","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"454f35d478088b2f","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"af6f37ce228476e6","prefixes":{"*":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"dfa2565386557dbb","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"7bdee1b08b69b7fa","prefixes":{"*":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"259e3811976143d2","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"29633cedc9fc7e43","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"758fea4a1e3ad80f","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"cf9bd7435c526efc","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"913928e477b69d4d","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"391c770feaa49fc6","prefixes":{"":{"product":11,"type":0}}}, // [Eulerian Technologies SARL]
-  {"hash":"9aea11673c37df0c","prefixes":{"*":{"product":222}}}, // [Ghostery Enterprise]
-  {"hash":"5efff70d6937c916","prefixes":{"*":{"product":223,"type":0}}}, // [Experteer GmbH]
-  {"hash":"070f9075bd0072ca","prefixes":{"":{"product":224,"type":1}}}, // [Action Allocator]
-  {"hash":"2a8c1779456949e3","prefixes":{"":{"product":225,"type":1}}}, // [AdTraxx]
-  {"hash":"0d3994abeed42b53","prefixes":{"*":{"product":226,"type":0}}}, // [eyeDemand]
-  {"hash":"f804a9a8eb6b2828","prefixes":{"*":{"product":227,"type":0}}}, // [EyeReturn Marketing]
-  {"hash":"e7b16a7fe9d18804","prefixes":{"*":{"product":227,"type":0}}}, // [EyeReturn Marketing]
-  {"hash":"9a826150ea3a7b3d","prefixes":{"*":{"product":228,"type":0}}}, // [EyeView Inc.]
-  {"hash":"00f40aaf7abec691","prefixes":{"":{"product":229,"type":0}}}, // [EyeView, Inc]
-  {"hash":"a47b1640e108c4e8","prefixes":{"":{"product":229,"type":0}}}, // [EyeView, Inc]
-  {"hash":"73c2e89f340530ca","prefixes":{"*":{"product":230,"type":0}}}, // [Eyewonder Inc.]
-  {"hash":"ab1869399e555ac8","prefixes":{"":{"product":231,"type":0}}}, // [MLB Advanced Media, L.P.]
-  {"hash":"6792c3d3132bf7d7","prefixes":{"":{"product":231,"type":0}}}, // [MLB Advanced Media, L.P.]
-  {"hash":"3d02d3a5042f5ad8","prefixes":{"":{"product":231,"type":0}}}, // [MLB Advanced Media, L.P.]
-  {"hash":"c75b8641d2e585d7","prefixes":{"*":{"product":232,"type":0}}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"535ecf05ae26ef66","prefixes":{"*":{"product":232,"type":0}}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"2393220aafcd7f07","prefixes":{"*":{"product":232,"type":0}}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"ead2626488917d96","prefixes":{"*":{"product":232,"type":0}}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"82402af773d46078","prefixes":{"*":{"product":232,"type":0}}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"0afacf5097d4ca72","prefixes":{"*":{"product":233,"type":0}}}, // [Flashtalking]
-  {"hash":"5215ee9300af8125","prefixes":{"":{"product":234,"type":0}}}, // [Hostelworld.com Limited]
-  {"hash":"e8d6e54e3ce31711","prefixes":{"":{"product":235,"type":0}}}, // [Knorex Pte. Ltd.]
-  {"hash":"a8ac5a522ae936d9","prefixes":{"":{"product":235,"type":0}}}, // [Knorex Pte. Ltd.]
-  {"hash":"c88080a9090fa828","prefixes":{"":{"product":235,"type":0}}}, // [Knorex Pte. Ltd.]
-  {"hash":"90727ba23e427206","prefixes":{"":{"product":235,"type":0}}}, // [Knorex Pte. Ltd.]
-  {"hash":"d496e8a41b845c1e","prefixes":{"":{"product":235,"type":0}}}, // [Knorex Pte. Ltd.]
-  {"hash":"e3463a0b0d9d0b84","prefixes":{"*":{"product":236,"type":0}}}, // [Flite Inc.]
-  {"hash":"93eff417d773ad79","prefixes":{"*":{"product":236,"type":0}}}, // [Flite Inc.]
-  {"hash":"48c727cb39130203","prefixes":{"*":{"product":236,"type":0}}}, // [Flite Inc.]
-  {"hash":"1f8b889072fc177c","prefixes":{"*":{"product":237,"type":0}}}, // [Forbes Media LLC]
-  {"hash":"830e0f5dd1181234","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"daf4edc7545d5166","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"f786c1dcc4eb883e","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"82534a9af0bc48e0","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"091c6487b80c3425","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"5250da9f53cd928c","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"9a8514c0fd5d6754","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"ad91bc98d2a8be55","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"91e5780ca48d75cc","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"481acfc271cd8a12","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"ef2a23dc677d8426","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"c6c8ce28b06bbda5","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"2bb2e1ea24146c0b","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"a0f3f5041ae3893c","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"4d6c5ce49301c775","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"747c952599211285","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"59f1e6a6110f9a68","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"f76895f67d1585b2","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"a2e125e235d1ffd4","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"17cbbfe7617725b3","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"1c118cc87c632e94","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"a48217ad66a56eb4","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"949fd73ca6fcc6f5","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"7d647d3164d8e6e2","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"e6d9d61b6785d883","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"aad9a81ea12d3c42","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"f0d9b5588abc50f9","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"dcb3db79fcab6476","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"1985d21c9c0b8366","prefixes":{"":{"product":239,"type":0}}}, // [FreakOut Inc.]
-  {"hash":"a268d22dc85b4108","prefixes":{"*":{"product":240,"type":0}}}, // [FreeWheel]
-  {"hash":"a796f300b3d2c84e","prefixes":{"*":{"product":241,"type":0}}}, // [Fringe81 Inc.]
-  {"hash":"bb563c63d09f3d76","prefixes":{"":{"product":242}}}, // [Fringe81 - IBV]
-  {"hash":"c6ac10cc9ddfb3e7","prefixes":{"":{"product":242}}}, // [Fringe81 - IBV]
-  {"hash":"48983a0d5a27b120","prefixes":{"*":{"product":243,"type":0}}}, // [FuseBox Inc.]
-  {"hash":"6f59caebdaac019e","prefixes":{"":{"product":243,"type":0}}}, // [FuseBox Inc.]
-  {"hash":"8090c608651eca30","prefixes":{"*":{"product":244,"type":1}}}, // [gemiusDirectEffect+]
-  {"hash":"e7b75209bd73a1d9","prefixes":{"*":{"product":245,"type":0}}}, // [AdOcean Ltd]
-  {"hash":"24fb4ed27ae8cf88","prefixes":{"*":{"product":246,"type":1}}}, // [Intomart GfK (GfK Daphne)]
-  {"hash":"91571a34ff0fcf44","prefixes":{"*":{"product":247,"type":0}}}, // [Gigya]
-  {"hash":"bd66201f4f935a9d","prefixes":{"*":{"product":248,"type":1}}}, // [Global Market Insite Inc.]
-  {"hash":"c0854a371610fbf2","prefixes":{"*":{"product":248,"type":1}}}, // [Global Market Insite Inc.]
-  {"hash":"4a32fa997117f00d","prefixes":{"*":{"product":249,"type":0},"":{"product":250,"type":0}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"68d0356c33bd8ec4","prefixes":{"*":{"product":249,"type":0},"":{"product":250,"type":0}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"813ca9ac3483af55","prefixes":{"*":{"product":249,"type":0},"":{"product":250,"type":0}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"ee88383142da014d","prefixes":{"*":{"product":249,"type":0},"":{"product":250,"type":0}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"1332f3da43091ed3","prefixes":{"":{"product":249,"type":0},"*":{"product":251,"type":0}}}, // [DoubleClick Campaign Manager] [DoubleClick for Publishers Premium]
-  {"hash":"f04082d14282d452","prefixes":{"":{"product":249,"type":0}}}, // [DoubleClick Campaign Manager]
-  {"hash":"c6ad6c580aef6ce5","prefixes":{"":{"product":249,"type":0}}}, // [DoubleClick Campaign Manager]
-  {"hash":"642706b0b0335500","prefixes":{"":{"product":249,"type":0}}}, // [DoubleClick Campaign Manager]
-  {"hash":"8e23699963552b18","prefixes":{"*":{"product":249,"type":0}}}, // [DoubleClick Campaign Manager]
-  {"hash":"bafedfe69ed92305","prefixes":{"*":{"product":250,"type":0}}}, // [DoubleClick Bidder Pilot for Networks]
-  {"hash":"f2b999c597cd97af","prefixes":{"*":{"product":250,"type":0}}}, // [DoubleClick Bidder Pilot for Networks]
-  {"hash":"66399889a04f9513","prefixes":{"cdn":{"product":252,"type":0},"ads":{"product":252,"type":0},"db":{"product":252,"type":0},"img":{"product":252,"type":0},"ssl":{"product":252,"type":0}}}, // [GroovinAds] [GroovinAds] [GroovinAds] [GroovinAds] [GroovinAds]
-  {"hash":"ea8510cdf6991d43","prefixes":{"":{"product":252,"type":0}}}, // [GroovinAds]
-  {"hash":"fc2e03aac9426552","prefixes":{"":{"product":253,"type":0}}}, // [Reddion]
-  {"hash":"6db39bcc7e0f7fed","prefixes":{"":{"product":254,"type":0}}}, // [HQ GmbH]
-  {"hash":"4de0590ca954b13b","prefixes":{"*":{"product":255,"type":0}}}, // [Performance Display Advertising]
-  {"hash":"44f4a1b16ff856e5","prefixes":{"":{"product":12,"type":0}}}, // [Conversant Ad Server]
-  {"hash":"127f97cfaedd763a","prefixes":{"":{"product":12,"type":0}}}, // [Conversant Ad Server]
-  {"hash":"508035bfa2d95844","prefixes":{"*":{"product":12,"type":0}}}, // [Conversant Ad Server]
-  {"hash":"6ea225859ddfba18","prefixes":{"*":{"product":12,"type":0}}}, // [Conversant Ad Server]
-  {"hash":"600a5a5f53775d42","prefixes":{"*":{"product":213,"type":1}}}, // [DoubleVerify Inc.]
-  {"hash":"cabba15c5ee8f039","prefixes":{"*":{"product":256,"type":0}}}, // [Avazu Inc.]
-  {"hash":"ec98881ed60ffe62","prefixes":{"":{"product":90,"type":0}}}, // [ADTECH GmbH]
-  {"hash":"b1e5dca23b928251","prefixes":{"":{"product":90,"type":0}}}, // [ADTECH GmbH]
-  {"hash":"87e919d72e293303","prefixes":{"*":{"product":257,"type":0}}}, // [Aerify Media]
-  {"hash":"652d7fe0079512a8","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"8e1afef4fbf079f4","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"3f697fb2c06659ac","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"cb5ae4cc94e8cb57","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"3cd44a0f52d69fed","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"fd87dfe8678e2630","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"274e4476c8fbfe0c","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"e3f56a006c4f8fc8","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"11d582be18893073","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"54768ce9ed6664fc","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"6de580016869f523","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"7fc8a77e5f366b6d","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"06838afa0ce9cde5","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"d788f92161d75b72","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"bd27e9c073c7b133","prefixes":{"":{"product":258,"type":0}}}, // [IClick Interactive Ltd.]
-  {"hash":"71096991891dc36f","prefixes":{"*":{"product":259,"type":0}}}, // [iCrossing]
-  {"hash":"0a48c6448ca1af83","prefixes":{"":{"product":259,"type":0}}}, // [iCrossing]
-  {"hash":"23cce2ff5ce35111","prefixes":{"*":{"product":260,"type":0}}}, // [Impact Engine Inc.]
-  {"hash":"b63329d63303bcac","prefixes":{"*":{"product":261}}}, // [Inadco Inc.]
-  {"hash":"9dab6f7b066953b6","prefixes":{"":{"product":261}}}, // [Inadco Inc.]
-  {"hash":"83efdfb00e5e0bb5","prefixes":{"":{"product":262,"type":0}}}, // [Innity Singapore Pte Ltd.]
-  {"hash":"5cdf5c58d4a95757","prefixes":{"":{"product":262,"type":0}}}, // [Innity Singapore Pte Ltd.]
-  {"hash":"e84e4c75279b444c","prefixes":{"":{"product":262,"type":0}}}, // [Innity Singapore Pte Ltd.]
-  {"hash":"0ad278b0f1bf83c7","prefixes":{"":{"product":263,"type":1}}}, // [Insight Express (Cross Media - Ignite)]
-  {"hash":"75089fef153b99d9","prefixes":{"":{"product":263,"type":1}}}, // [Insight Express (Cross Media - Ignite)]
-  {"hash":"17e48170b29e8c55","prefixes":{"":{"product":264,"type":0}}}, // [intelliAd Media GmbH]
-  {"hash":"8ff3a159f3a3dd37","prefixes":{"":{"product":264,"type":0}}}, // [intelliAd Media GmbH]
-  {"hash":"d5ad6ce37d416c20","prefixes":{"":{"product":264,"type":0}}}, // [intelliAd Media GmbH]
-  {"hash":"829116e73bbd766e","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"58b6a73b811a6744","prefixes":{"":{"product":264,"type":0}}}, // [intelliAd Media GmbH]
-  {"hash":"1b02753d1ebc5935","prefixes":{"":{"product":266,"type":0}}}, // [Intelliad]
-  {"hash":"2d4767b28a0a3dc9","prefixes":{"":{"product":266,"type":0}}}, // [Intelliad]
-  {"hash":"04e4138ad91eba43","prefixes":{"*":{"product":267,"type":0}}}, // [Genome]
-  {"hash":"a80259001a08f5fe","prefixes":{"":{"product":267,"type":0}}}, // [Genome]
-  {"hash":"bccc7d85fcbd6406","prefixes":{"*":{"product":268,"type":0}}}, // [Intergi LLC dba PlaywireMedia]
-  {"hash":"c0e12f3f6483d539","prefixes":{"":{"product":269,"type":0}}}, // [Intermundo Media LLC]
-  {"hash":"aa0d2346396993dc","prefixes":{"*":{"product":270,"type":0}}}, // [Interpolls]
-  {"hash":"391f02c89579c41e","prefixes":{"*":{"product":271,"type":1}}}, // [Intelligent Reach (Intuitive Search Technologies)]
-  {"hash":"dd7ece8c8b4dd4db","prefixes":{"*":{"product":271,"type":1}}}, // [Intelligent Reach (Intuitive Search Technologies)]
-  {"hash":"51beebfd5a677c74","prefixes":{"":{"product":271,"type":1}}}, // [Intelligent Reach (Intuitive Search Technologies)]
-  {"hash":"15a557d1be0b55bc","prefixes":{"*":{"product":272,"type":0}}}, // [IPONWEB Limited]
-  {"hash":"ab800ebb45ab5e96","prefixes":{"":{"product":272,"type":0}}}, // [IPONWEB Limited]
-  {"hash":"cf6003cf8be11c49","prefixes":{"*":{"product":272,"type":0}}}, // [IPONWEB Limited]
-  {"hash":"bd97f2dac673ccef","prefixes":{"*":{"product":273,"type":0}}}, // [JasperLabs Inc.]
-  {"hash":"833a1bb3e47002bf","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"925afb63a81d22ae","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"e3546ee6177ce1af","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"a6e81a993b0dc090","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"57cf72a6bcc6ed09","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"aef508a87f7b9342","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"a1a0984cf6e12596","prefixes":{"":{"product":274,"type":0}}}, // [Jivox Corporation]
-  {"hash":"c1b82a9e7564881f","prefixes":{"*":{"product":275,"type":0}}}, // [Joinville AB]
-  {"hash":"e20dd6e83cbd14d9","prefixes":{"":{"product":276,"type":0}}}, // [KliKKicom Oy]
-  {"hash":"a1f03f455fc97850","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"fb87830648f1fe7c","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"93a6bcd7660ef88b","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"14fba951393c4cc1","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"96bf72901db53556","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"00ceea10fed6f827","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"5deb6288aeb4b20d","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"30a9e5cf761c2db9","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"b49fda322943ed64","prefixes":{"":{"product":277,"type":0}}}, // [Komli Media Inc.]
-  {"hash":"30067241c16c9f88","prefixes":{"*":{"product":278,"type":1}}}, // [Koninklijke Luchtvaart Maatschappij N.V.]
-  {"hash":"06076b672be3af43","prefixes":{"*":{"product":279,"type":1}}}, // [J.D. Power O2O]
-  {"hash":"1e23ff61443f919a","prefixes":{"*":{"product":280,"type":0}}}, // [Kwanzoo Inc.]
-  {"hash":"32327b1f6a21f5e3","prefixes":{"":{"product":281,"type":0}}}, // [Legolas Media Inc.]
-  {"hash":"0a98bd3ecf6d4f39","prefixes":{"":{"product":281,"type":0}}}, // [Legolas Media Inc.]
-  {"hash":"4141a8162aadd52a","prefixes":{"":{"product":281,"type":0}}}, // [Legolas Media Inc.]
-  {"hash":"9562185c6a06e194","prefixes":{"*":{"product":282,"type":0}}}, // [Undertone Ad System (UAS)]
-  {"hash":"d8be1c121ccbdb84","prefixes":{"":{"product":283,"type":0}}}, // [LEVEL Studios]
-  {"hash":"1b274516ac601c1d","prefixes":{"*":{"product":284,"type":0}}}, // [LinkedIn Corporation]
-  {"hash":"a9aceb9b28670518","prefixes":{"*":{"product":284,"type":0}}}, // [LinkedIn Corporation]
-  {"hash":"f202e32e7503e766","prefixes":{"":{"product":284,"type":0}}}, // [LinkedIn Corporation]
-  {"hash":"cf2094771b42b367","prefixes":{"*":{"product":284,"type":0}}}, // [LinkedIn Corporation]
-  {"hash":"ad94f98bfc0092ce","prefixes":{"*":{"product":285,"type":0}}}, // [Content Directions, Inc. dba Linkstorm]
-  {"hash":"2c97a2e1f7f59cde","prefixes":{"*":{"product":286,"type":1}}}, // [Liverail Inc.]
-  {"hash":"562dd0a17776cfc3","prefixes":{"*":{"product":287,"type":1}}}, // [Lotame Solutions Inc.]
-  {"hash":"85c409cdb78a6fec","prefixes":{"*":{"product":288,"type":0}}}, // [LucidMedia Networks Inc.]
-  {"hash":"25cdc372f14aa636","prefixes":{"":{"product":289,"type":0}}}, // [Magnetic Media Online Inc.]
-  {"hash":"490a692feb4f5f83","prefixes":{"":{"product":289,"type":0}}}, // [Magnetic Media Online Inc.]
-  {"hash":"8cd182ca413a6770","prefixes":{"":{"product":289,"type":0}}}, // [Magnetic Media Online Inc.]
-  {"hash":"891ff79862603ca1","prefixes":{"*":{"product":290,"type":1}}}, // [Mate1.com]
-  {"hash":"ae4598324ee10cb2","prefixes":{"":{"product":291,"type":0}}}, // [MaxPoint Interactive Inc.]
-  {"hash":"66eafecb064a6d3f","prefixes":{"*":{"product":292,"type":0}}}, // [Media Armor Inc.]
-  {"hash":"d9921090d75b28f3","prefixes":{"*":{"product":293,"type":1}}}, // [Xaxis, Inc]
-  {"hash":"4c897372b3205c67","prefixes":{"*":{"product":294,"type":0}}}, // [Dstillery]
-  {"hash":"78172051b147ff71","prefixes":{"*":{"product":294,"type":0}}}, // [Dstillery]
-  {"hash":"3e32e501635bb994","prefixes":{"*":{"product":295,"type":0}}}, // [Rakuten MediaForge]
-  {"hash":"ab3637f7ff19f3be","prefixes":{"*":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"eacb348c2bfde7c6","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"6ec884dc33afd8e3","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"6a0b44c268e0ea34","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"5ec2ba6f16455240","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"f6a166105958340d","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"1bafa194e1b43948","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"c4c10492cf3f1e5c","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"fb29996f4dbe86a3","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"33cba419c0d99c36","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"1471e355753e333a","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"8445471e74aaf1ad","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"fe448fc8fa6792c7","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"7142d0f7c95e6c11","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"f71e7939a3a06b85","prefixes":{"":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"25c9493f4ceef0b3","prefixes":{"*":{"product":296,"type":0}}}, // [Sizmek]
-  {"hash":"1c0486f5c9ddccc1","prefixes":{"":{"product":297,"type":0}}}, // [MediaMind]
-  {"hash":"511f53552d7c07f9","prefixes":{"*":{"product":298,"type":0}}}, // [Paypal]
-  {"hash":"c23b8169e8d6f935","prefixes":{"*":{"product":298,"type":0}}}, // [Paypal]
-  {"hash":"4cb72fa17c1e6b21","prefixes":{"*":{"product":299,"type":0}}}, // [ZEDO Inc.]
-  {"hash":"1f5866beb3a2da29","prefixes":{"":{"product":300,"type":0}}}, // [Contobox]
-  {"hash":"ab4011df7412e85a","prefixes":{"":{"product":300,"type":0}}}, // [Contobox]
-  {"hash":"4c55c99f7e731e4a","prefixes":{"":{"product":300,"type":0}}}, // [Contobox]
-  {"hash":"b32dad95de4864bb","prefixes":{"":{"product":300,"type":0}}}, // [Contobox]
-  {"hash":"e0636cdabf7592eb","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"9e011383339e65c3","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"c7f6b97c8a7defa6","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"ba29743e534631a5","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"df986bbd43ef130c","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"32e39349c0434e31","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"4b920fabf61fd6f3","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"068f3a0cd7e03112","prefixes":{"":{"product":301,"type":0}}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"95cce4f80c49239f","prefixes":{"*":{"product":302,"type":1}}}, // [MeMo2 / Hottraffic]
-  {"hash":"7672c0e258e0a20b","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"065ac7f58737b759","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"f0c15855e3418345","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"45068fe6a5fe83c0","prefixes":{"*":{"product":304,"type":0}}}, // [Mercado Livre.com Atividades de Internet Ltda]
-  {"hash":"a3fbfa83663a40a6","prefixes":{"*":{"product":304,"type":0}}}, // [Mercado Livre.com Atividades de Internet Ltda]
-  {"hash":"5241d2ae86ff307f","prefixes":{"":{"product":305,"type":0}}}, // [Merchenta Limited]
-  {"hash":"7b92690c1232eb23","prefixes":{"":{"product":305,"type":0}}}, // [Merchenta Limited]
-  {"hash":"e5b1a15c3a7a1ee6","prefixes":{"":{"product":305,"type":0}}}, // [Merchenta Limited]
-  {"hash":"f0b40488d9ecd9a2","prefixes":{"":{"product":305,"type":0}}}, // [Merchenta Limited]
-  {"hash":"63600c9242f10b0d","prefixes":{"":{"product":305,"type":0}}}, // [Merchenta Limited]
-  {"hash":"e89e81c1ed314cc1","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"297f0571158ef576","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"2228e5ce36c007c1","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"798bcbf9415873df","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"ab03f3b496037843","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"eca01f0508fbf30b","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"0d839898fade319a","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"4fc010b1e52ce252","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"31e7fb81bf0ec52f","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"a6edfa074ceff9c5","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"289dc75a912dcc97","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"5a8de8926c410758","prefixes":{"":{"product":306,"type":0}}}, // [Metapeople GmbH]
-  {"hash":"79c798a9d8e32afc","prefixes":{"":{"product":307,"type":1}}}, // [MetrixLab B.V.]
-  {"hash":"61617058e6206283","prefixes":{"":{"product":307,"type":1}}}, // [MetrixLab B.V.]
-  {"hash":"cf945767a2fa79f3","prefixes":{"*":{"product":308,"type":0}}}, // [Mixpo Inc.]
-  {"hash":"541f85cbc710f2b3","prefixes":{"":{"product":309,"type":1}}}, // [Monsoon Ads Pvt. Ltd.]
-  {"hash":"c800e798e160fe89","prefixes":{"*":{"product":310,"type":0}}}, // [Monster]
-  {"hash":"775035c4c49057eb","prefixes":{"":{"product":310,"type":0}}}, // [Monster]
-  {"hash":"2a26221290e24a08","prefixes":{"":{"product":310,"type":0}}}, // [Monster]
-  {"hash":"fda966b5c6ec2b2f","prefixes":{"":{"product":310,"type":0}}}, // [Monster]
-  {"hash":"887d148a8ae98b2e","prefixes":{"*":{"product":311,"type":1}}}, // [neckermann.de GmbH]
-  {"hash":"35c76c9165e3349f","prefixes":{"*":{"product":312,"type":1}}}, // [Ad.agio]
-  {"hash":"d5c7d1240bf8989e","prefixes":{"":{"product":312,"type":1}}}, // [Ad.agio]
-  {"hash":"1e5ea56690a0716d","prefixes":{"*":{"product":312,"type":0}}}, // [Ad.agio]
-  {"hash":"a54661777ef51189","prefixes":{"*":{"product":313,"type":0}}}, // [Netmining LLC]
-  {"hash":"cc673c90c8abe830","prefixes":{"*":{"product":314,"type":0}}}, // [AdoTube]
-  {"hash":"5f4b0cbb95552b3f","prefixes":{"*":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"a78e1096b3c03fbc","prefixes":{"":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"582d973b69391ebe","prefixes":{"":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"18585076a5b0c6dd","prefixes":{"":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"1df4ee86fc680406","prefixes":{"":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"ecd80a6a46f6a1ce","prefixes":{"":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"8ee876aaaaf537e0","prefixes":{"":{"product":315,"type":0}}}, // [Next Audience GmbH]
-  {"hash":"92bc4f011133f05a","prefixes":{"*":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"b10d35d6cde76082","prefixes":{"*":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"8e6e5d6dc4720f98","prefixes":{"":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"edc7f4e87a8ea4a3","prefixes":{"":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"f0c76e07985c56c5","prefixes":{"":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"cff1b3137482e5e3","prefixes":{"":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"33f28c5ebbd4525e","prefixes":{"":{"product":316,"type":0}}}, // [Nextperf]
-  {"hash":"849c8324d4c32ea5","prefixes":{"*":{"product":317,"type":0}}}, // [Calibex]
-  {"hash":"0bbcc61ed60a63c7","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"7da7b69cf130f867","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"524bf7ee34882325","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"0fc0858e8d42a096","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"94d1d06666f458b2","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"9515f9226eae0ee6","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"c610850a50287c6c","prefixes":{"":{"product":318,"type":1}}}, // [ViziAds for Advertisers]
-  {"hash":"1324d12fd047205a","prefixes":{"":{"product":318,"type":1}}}, // [ViziAds for Advertisers]
-  {"hash":"922df75b11e4bdb8","prefixes":{"":{"product":318,"type":1}}}, // [ViziAds for Advertisers]
-  {"hash":"94be9a0ad636acc1","prefixes":{"":{"product":318,"type":1}}}, // [ViziAds for Advertisers]
-  {"hash":"921f858655989bdb","prefixes":{"":{"product":318,"type":1}}}, // [ViziAds for Advertisers]
-  {"hash":"0f44f6f2024007e3","prefixes":{"":{"product":319,"type":0}}}, // [FinanceGenerator]
-  {"hash":"c5d545736ea3f40c","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"c5190fb3c11efd5c","prefixes":{"":{"product":320,"type":1}}}, // [Telstra Corporation]
-  {"hash":"f8e19bba6ecb9d4d","prefixes":{"":{"product":320,"type":1}}}, // [Telstra Corporation]
-  {"hash":"78cb9e34e18a70c6","prefixes":{"":{"product":320,"type":1}}}, // [Telstra Corporation]
-  {"hash":"555b77a6dbc1077b","prefixes":{"":{"product":320,"type":1}}}, // [Telstra Corporation]
-  {"hash":"04cd318d8c9e0aa1","prefixes":{"":{"product":321,"type":1}}}, // [The Online Research Unit]
-  {"hash":"44b28a9d35489468","prefixes":{"":{"product":322,"type":0}}}, // [Webling Pty Ltd]
-  {"hash":"ce2a97a2bc3975b0","prefixes":{"*":{"product":323,"type":0}}}, // [Lasoo Pty Ltd]
-  {"hash":"70c03e717046730c","prefixes":{"":{"product":323,"type":0}}}, // [Lasoo Pty Ltd]
-  {"hash":"a1956c55f379362a","prefixes":{"":{"product":323,"type":0}}}, // [Lasoo Pty Ltd]
-  {"hash":"78761e0920b86d00","prefixes":{"":{"product":323,"type":0}}}, // [Lasoo Pty Ltd]
-  {"hash":"fb49a17ebf575b4b","prefixes":{"":{"product":323,"type":0}}}, // [Lasoo Pty Ltd]
-  {"hash":"3ba767e322876167","prefixes":{"":{"product":323,"type":0}}}, // [Lasoo Pty Ltd]
-  {"hash":"db60b4edeb07e6e0","prefixes":{"*":{"product":324,"type":0}}}, // [Salefinder Ltd.]
-  {"hash":"1a2b2619e15f81ed","prefixes":{"":{"product":325,"type":1}}}, // [The Monkeys Pty Ltd]
-  {"hash":"d33c5423234580d2","prefixes":{"":{"product":326}}}, // [Louder Digital Pty Ltd]
-  {"hash":"35c305dfff8e956a","prefixes":{"":{"product":327,"type":0}}}, // [Publisher’s Internationale Pty Ltd]
-  {"hash":"ab95fd39f34e1919","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"e394eac0c09e952a","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"d754759cedf098a4","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"469abb509832dcba","prefixes":{"":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"089ade7154cdafd2","prefixes":{"":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"7c4e77c7146bc27c","prefixes":{"":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"27943a61af56578c","prefixes":{"":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"5b9d47d01e06e207","prefixes":{"":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"efae037999b8354a","prefixes":{"":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"64b1c22f19588e65","prefixes":{"*":{"product":14,"type":0}}}, // [Wize Commerce, Inc.]
-  {"hash":"1b500703c376dccf","prefixes":{"":{"product":328,"type":0}}}, // [NowSpots]
-  {"hash":"0b8a5111da2a18e6","prefixes":{"":{"product":328,"type":0}}}, // [NowSpots]
-  {"hash":"6cbd63b4b5a258e2","prefixes":{"":{"product":329,"type":0}}}, // [Ocapi]
-  {"hash":"2ecb3e4de562d83f","prefixes":{"*":{"product":330,"type":0}}}, // [Predicta]
-  {"hash":"b0032d1f28de6b8e","prefixes":{"*":{"product":330,"type":0}}}, // [Predicta]
-  {"hash":"495b10f97369710c","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"07b876ce04abdfc9","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"bd1d888d58054387","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"deb9a6a0e78770f8","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"3d9897472cebdff7","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"a036e7b2680b1720","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"ae8e27c2a1195c9d","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"685a4ece024544f3","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"d705e49e2ecfc500","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"4fd0a4a032a34191","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"2640f60d445d4d0d","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"0067af133fbf162f","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"62e23e8e0a53b097","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"57643f79e10fdc91","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"fe70aef371b87e0d","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"c80b88907c4da662","prefixes":{"":{"product":331,"type":0}}}, // [Comune SA]
-  {"hash":"3c027bef12167411","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"9e7ef06636d0b122","prefixes":{"":{"product":333,"type":0}}}, // [Hotwords Informação LTDA]
-  {"hash":"ac577d2ba001c2f9","prefixes":{"":{"product":333,"type":0}}}, // [Hotwords Informação LTDA]
-  {"hash":"8baa23f77cec98d3","prefixes":{"":{"product":333,"type":0}}}, // [Hotwords Informação LTDA]
-  {"hash":"86e7352358e7a0a1","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"461a9aacd5db8b62","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"4523c8dd39cb10d8","prefixes":{"":{"product":334,"type":0}}}, // [uMotion]
-  {"hash":"a7eaf4ae4152200d","prefixes":{"":{"product":334,"type":0}}}, // [uMotion]
-  {"hash":"1874ed5aa610db51","prefixes":{"*":{"product":335,"type":1}}}, // [Google Zoo]
-  {"hash":"0dc9eb6c8b1c77fa","prefixes":{"*":{"product":34,"type":0}}}, // [Oggifinogi]
-  {"hash":"60d67cd6819e7de4","prefixes":{"*":{"product":336,"type":1}}}, // [Audience Manager]
-  {"hash":"2ae524eac16b06f8","prefixes":{"":{"product":337,"type":0}}}, // [ONDCP]
-  {"hash":"c7e974006ec125b7","prefixes":{"*":{"product":338,"type":0}}}, // [OpenX OnRamp]
-  {"hash":"a985fc121086ead8","prefixes":{"*":{"product":339,"type":0}}}, // [OpenX Ad Server]
-  {"hash":"402ca9fbb308a1c5","prefixes":{"*":{"product":35,"type":0}}}, // [PaperG]
-  {"hash":"53f1cd9b06aea643","prefixes":{"*":{"product":35,"type":0}}}, // [PaperG]
-  {"hash":"36b3ccfb92c2fb71","prefixes":{"*":{"product":340,"type":0}}}, // [Parship]
-  {"hash":"28832d626c0b0925","prefixes":{"*":{"product":341,"type":1}}}, // [pauldirekt GmbH]
-  {"hash":"1d474301c170499d","prefixes":{"*":{"product":342,"type":0}}}, // [Pictela Inc.]
-  {"hash":"fd1aa96507b2bf44","prefixes":{"":{"product":342,"type":0}}}, // [Pictela Inc.]
-  {"hash":"7f890c0fd0c6a4d9","prefixes":{"":{"product":343,"type":0}}}, // [Pilot 1/0 GmbH & Co KG]
-  {"hash":"549e294957d756d8","prefixes":{"":{"product":343,"type":0}}}, // [Pilot 1/0 GmbH & Co KG]
-  {"hash":"5dc046f77f32adf1","prefixes":{"*":{"product":344,"type":0}}}, // [Piximedia]
-  {"hash":"637b449ba51266a3","prefixes":{"*":{"product":344,"type":0}}}, // [Piximedia]
-  {"hash":"013ba3dd6b18ee4a","prefixes":{"*":{"product":345,"type":0}}}, // [Pointroll]
-  {"hash":"d96024cf9bafa9d0","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"4f0c9093d18b4ecd","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"d63f961e0c8cc056","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"1bcfb023adee2b08","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"6ed6fb838bd994d7","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"9fd07c030d45578d","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"5370f7b026779f44","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"c367910d58376fa0","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"670926f337b85492","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"77d7124c8aa87819","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"3726ef9236aeff59","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"84078980dc7d0310","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"496666ed92d32be6","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"3e8a19db4e7dd91a","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"33cfdc955bd4ab90","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"543046798ae8e38d","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"54537a7d4ce6fc35","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"242ab5d44fae500c","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"e81d4aa82d04d068","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"7c7f55d8a75cb9bc","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"e4a82caa59141478","prefixes":{"":{"product":346,"type":0}}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"caf06dc269e4cbd7","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"70584cd7bcb88744","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"c9cabfef49bb4ec1","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"993089a2d306632e","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"cf04aaaa5ae5f383","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"a1cd6a668ae89bc8","prefixes":{"*":{"product":348,"type":1}}}, // [AdMaster]
-  {"hash":"f72dd5293eba3ca3","prefixes":{"":{"product":348,"type":1}}}, // [AdMaster]
-  {"hash":"e946e6b718e0e81a","prefixes":{"":{"product":348,"type":1}}}, // [AdMaster]
-  {"hash":"01b5e469f3b6d1d9","prefixes":{"":{"product":349,"type":0}}}, // [D.A.Consortium Beijing (Platform One China)]
-  {"hash":"f091b3175305cced","prefixes":{"":{"product":349,"type":0}}}, // [D.A.Consortium Beijing (Platform One China)]
-  {"hash":"1a095d1901f0940b","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"f66f99ee20105c2c","prefixes":{"*":{"product":351,"type":0}}}, // [PurposeLab]
-  {"hash":"86c250cf0da31481","prefixes":{"":{"product":351,"type":0}}}, // [PurposeLab]
-  {"hash":"8f204c79d6b23736","prefixes":{"*":{"product":330,"type":0}}}, // [Predicta]
-  {"hash":"43d06db6d6527876","prefixes":{"":{"product":352,"type":0}}}, // [Proclivity Systems]
-  {"hash":"5f76990173953807","prefixes":{"":{"product":352,"type":0}}}, // [Proclivity Systems]
-  {"hash":"7d3947ee9533bf30","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"fb241396adc3ebde","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"b8c5f46fb8945332","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"ade9cbc2becb390f","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"874cfa4e9fe27233","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"2cd6bee614e910f1","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"854f37cd1f444e62","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"19a83c7a2b673a6d","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"ca312e078723d178","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"4aa2d41fa2878d8f","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"8931cc3c2d6bbbff","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"e67e88dcc0afe050","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"3f6c08baf48fa0ae","prefixes":{"":{"product":36,"type":0}}}, // [Public-Idées]
-  {"hash":"6303a58061eaabd1","prefixes":{"*":{"product":353,"type":0}}}, // [Viewbix]
-  {"hash":"4fdc8f2ff122ce2e","prefixes":{"":{"product":353,"type":0}}}, // [Viewbix]
-  {"hash":"ba78a984ad7a8c06","prefixes":{"":{"product":353,"type":0}}}, // [Viewbix]
-  {"hash":"00885ce869b93eab","prefixes":{"":{"product":353,"type":0}}}, // [Viewbix]
-  {"hash":"eb59f3a64b415670","prefixes":{"":{"product":354,"type":1}}}, // [Quantcast Inc.]
-  {"hash":"243c70f61da9731c","prefixes":{"":{"product":354,"type":1}}}, // [Quantcast Inc.]
-  {"hash":"ed6b204d6b8f351e","prefixes":{"":{"product":354,"type":1}}}, // [Quantcast Inc.]
-  {"hash":"e6888b5be4ecca23","prefixes":{"":{"product":354,"type":0}}}, // [Quantcast Inc.]
-  {"hash":"8034327c12c77172","prefixes":{"":{"product":354,"type":0}}}, // [Quantcast Inc.]
-  {"hash":"d48f950e0036e4ee","prefixes":{"*":{"product":355,"type":0}}}, // [QuinStreet]
-  {"hash":"6118e4e0e4001349","prefixes":{"*":{"product":356,"type":0}}}, // [Quisma GmbH]
-  {"hash":"1b2f3dadf0889c1c","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"491acc9692437dcc","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"95be38e789f1c074","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"7d13c9a93867cfd5","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"aee8b719a85b0392","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"03c0d3572439e910","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"42c10737e9d2eb44","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"1ece70926dbb1e9c","prefixes":{"*":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"15b1b56db686d6b8","prefixes":{"":{"product":357,"type":0}}}, // [Quismatch / Quisma Tracker]
-  {"hash":"6f2fb017c596785a","prefixes":{"*":{"product":358,"type":0}}}, // [Qwobl Inc.]
-  {"hash":"45bd1c4bac827eb4","prefixes":{"*":{"product":359,"type":0}}}, // [RadiumOne Inc.]
-  {"hash":"a4cc28a873663be4","prefixes":{"*":{"product":360,"type":0}}}, // [Core Audience, Inc]
-  {"hash":"b1b347108c9875ae","prefixes":{"*":{"product":361,"type":0}}}, // [The Reach Group]
-  {"hash":"9680c32132a31294","prefixes":{"":{"product":362,"type":0}}}, // [revenue cloud]
-  {"hash":"4654f1b3d29f0a2a","prefixes":{"":{"product":362,"type":0}}}, // [revenue cloud]
-  {"hash":"c8daf5a2befc762c","prefixes":{"":{"product":362,"type":0}}}, // [revenue cloud]
-  {"hash":"cd7c04dcaab54cf3","prefixes":{"":{"product":361,"type":0}}}, // [The Reach Group]
-  {"hash":"6a7ac3b20a8267da","prefixes":{"*":{"product":363,"type":0}}}, // [Register.it]
-  {"hash":"24064a7ef37c0464","prefixes":{"":{"product":364,"type":0}}}, // [ReleStar]
-  {"hash":"28a4e40561f9acae","prefixes":{"":{"product":364,"type":0}}}, // [ReleStar]
-  {"hash":"3de1987cea55e4a5","prefixes":{"":{"product":364,"type":0}}}, // [ReleStar]
-  {"hash":"827fd98c61df481c","prefixes":{"":{"product":364,"type":0}}}, // [ReleStar]
-  {"hash":"eec1a8a2a7fb129b","prefixes":{"":{"product":364,"type":0}}}, // [ReleStar]
-  {"hash":"6c1b7209cced7033","prefixes":{"*":{"product":365,"type":1}}}, // [Research Horizons LLC dba Phoenix Marketing]
-  {"hash":"c946c0fe5eecd55f","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"2feb43f5f97da585","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"4847977384b78f1d","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"308241d0fe4d6897","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"2cb30990aa0823eb","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"2c25ebde178886b1","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"d4eeb4a4736e8358","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"12498108d00bd104","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"c7437019688a5c87","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"ebc599442a1e60e0","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"ab9c2a8a5ed26375","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"c9473e1a1e9213bc","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"a15bca05fb29201f","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"8c2336c1a87e9c7e","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"67f7079b53ce160f","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"a07c7ea743bca71c","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"ce0849726cb792fb","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"6d2feeb6316bf983","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"056132328ebc8a3b","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"c0dd251eb151bbdd","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"02e6b230a73d95aa","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"62cef89124c9831e","prefixes":{"*":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"1bb2fad94e9dfd9e","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"0bca341ab2881187","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"fb725c5783121bc4","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"6d442fcb13dbd9da","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"6020c585ae546ba6","prefixes":{"":{"product":15,"type":1}}}, // [Research Now Limited]
-  {"hash":"bf994d767fc23e27","prefixes":{"":{"product":366,"type":0}}}, // [Retention Media Inc.]
-  {"hash":"5c801bba74bf0884","prefixes":{"":{"product":367,"type":0}}}, // [Suite 66]
-  {"hash":"f727f4c8af36c75c","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"d0ffa461035bdf6a","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"f1381513cbb99bf4","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"2b675a4d048f6d58","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"ff9153951d29d7eb","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"9a2d88a64367054f","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"22fc5e00cc71b2ca","prefixes":{"":{"product":368,"type":1}}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"d680287680a3b47b","prefixes":{"*":{"product":369,"type":0}}}, // [BridgeTrack]
-  {"hash":"6659ffe0ec0db1a1","prefixes":{"*":{"product":370,"type":0}}}, // [adnanny.com GmbH]
-  {"hash":"cdef303f827a483a","prefixes":{"":{"product":370,"type":0}}}, // [adnanny.com GmbH]
-  {"hash":"d37d706078f5ef0e","prefixes":{"":{"product":370,"type":0}}}, // [adnanny.com GmbH]
-  {"hash":"cefa23f603f78274","prefixes":{"":{"product":370,"type":0}}}, // [adnanny.com GmbH]
-  {"hash":"9beed54a2448f091","prefixes":{"*":{"product":371,"type":0}}}, // [AdRoll]
-  {"hash":"131ff02cd8b2b585","prefixes":{"*":{"product":372,"type":0}}}, // [AdExtent]
-  {"hash":"7b03a999ce62649a","prefixes":{"*":{"product":372,"type":0}}}, // [AdExtent]
-  {"hash":"d888444955526bb9","prefixes":{"*":{"product":373,"type":0}}}, // [ShareThis Inc.]
-  {"hash":"24bedaecde8de52e","prefixes":{"*":{"product":374,"type":1}}}, // [Shirtinator]
-  {"hash":"b2227832d5aab97c","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"29d1a1af90fe4764","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"55d58888ac21e28e","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"15a0a565c098bb6c","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"c740f7042a936f94","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"83b6131729d98b9a","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"df61075a3761234c","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"31d664b6a0c86fc5","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"b3f1fda5ca08f66c","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"a505bd8c5fdbe348","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"ff4b6ade85c0fa47","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"55fbb05b573abfc0","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"7509d096b740a94e","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"3e05ad70e7b857f6","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"f3122b05b916b4d8","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"7df77439ca0af167","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"7b6f3b92d848f180","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"c50b3a11c75c1de2","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"42bd2bd016c36072","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"d964e110e03add5e","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"b2f31dc5aea81475","prefixes":{"":{"product":375,"type":0}}}, // [Simplifi Holdings Inc.]
-  {"hash":"fd3e5505c689b1bc","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"e21937d0011ae5da","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"0f5e4a0353dbf996","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"0ece74eb8682685e","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"3d8ea3f0d5d389d5","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"b5602307e99e9538","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"c13decc96884eb9a","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"b815964fd4b63ffe","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"a49f2db509757639","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"a3ff80b45a2b0087","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"b1b2c1399cbf19be","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"ba44917903f4a6c0","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"ad5130e5aa2d0bcd","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"ceb371583c3948ee","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"5d5d4fe496a7b543","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"30e80084c1e7285e","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"d1d0fc6a034973b5","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"e2814abcd5399a68","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"9d4acd34336a73d4","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"dcbf7d7841f88317","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"c19fe37a92d8a1f4","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"dd502cbc700beb03","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"a76947b64ea18232","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"75875c5fcc471f0e","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"5323dbf9f56befc9","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"fd3df839224700c5","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"dc544506e0acf31c","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"fbadeeb25ac766a9","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"f344fa72c3acea98","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"e0d1929f5490ba3c","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"150d5c444034d16f","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"63c9992c37df81e6","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"9a2f65999a2602e7","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"b13d21bc9d60e3cf","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"36778688c2c8550d","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"7764641665318d7a","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"137839bac6b52f11","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"75b17e7427d84ec0","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"f576b8f6b5698927","prefixes":{"":{"product":376,"type":0}}}, // [Centro DSP]
-  {"hash":"a0bef488713fd8ba","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"c4f4b5d7a3bc8772","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"652de2e0257cc6f9","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"e1eb84d2322dd53f","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"0759e6e60e23806b","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"b97f9d3a0092f5df","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"6f7d322aac5f6093","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"d6d2092af97f6672","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"700b4497422246d3","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"24758e00974c4842","prefixes":{"*":{"product":377,"type":0}}}, // [Smart Adserver]
-  {"hash":"229fb1e217ec3254","prefixes":{"*":{"product":377,"type":0}}}, // [Smart Adserver]
-  {"hash":"24f84ec66db45f3d","prefixes":{"":{"product":378,"type":0}}}, // [smartclip Holding AG]
-  {"hash":"7bce0d8d711753ea","prefixes":{"":{"product":378,"type":0}}}, // [smartclip Holding AG]
-  {"hash":"f748f5ce8e9c4b7d","prefixes":{"*":{"product":379,"type":0}}}, // [Snap Technologies Inc.]
-  {"hash":"c17d7dedc318749c","prefixes":{"":{"product":380,"type":0}}}, // [So-net Media Networks]
-  {"hash":"d3a65eea99debc9b","prefixes":{"":{"product":380,"type":0}}}, // [So-net Media Networks]
-  {"hash":"f28c7fc4a06bcfa7","prefixes":{"*":{"product":381,"type":0}}}, // [SocialMedia.com]
-  {"hash":"17591c31cbbe7cf8","prefixes":{"":{"product":382,"type":0}}}, // [Content to Emotion (CTE)]
-  {"hash":"7c350f8bcf5a54b9","prefixes":{"":{"product":382,"type":0}}}, // [Content to Emotion (CTE)]
-  {"hash":"e003938122f9ac4f","prefixes":{"":{"product":382,"type":0}}}, // [Content to Emotion (CTE)]
-  {"hash":"6deac101ca463319","prefixes":{"static":{"product":382,"type":0}}}, // [Content to Emotion (CTE)]
-  {"hash":"304e631663a87e67","prefixes":{"*":{"product":383,"type":0}}}, // [Sociomantic.com]
-  {"hash":"e86474f9c6ad794d","prefixes":{"":{"product":384,"type":0}}}, // [AdSpeed]
-  {"hash":"de0816aa39c8b153","prefixes":{"*":{"product":385,"type":1}}}, // [Sophus3]
-  {"hash":"df8355613a445a85","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"a72f2b989760c8dc","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"fbdc1704c28873c8","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"d4674ccaf8fb7e31","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"f184677fb7e2abca","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"e7d695bf507e45d5","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"ea3f746342f05dbf","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"96ce83a8f0d84d99","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"62c6410f3e4000d8","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"b5172a6eee01acbe","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"36f9ba3a735ea443","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"f4d96ab5c7d0f720","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"7c8204a143e83abb","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"cb5b72c4fdc90b38","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"01c1382916f7a580","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"49505fd99e787062","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"a931030a5dbd7346","prefixes":{"":{"product":16,"type":0}}}, // [Spartoo]
-  {"hash":"3a09b22266ba0b12","prefixes":{"*":{"product":386,"type":0}}}, // [Specific Media Inc.]
-  {"hash":"2136a3b6f6600ad0","prefixes":{"*":{"product":386,"type":0}}}, // [Specific Media Inc.]
-  {"hash":"600e429523014251","prefixes":{"*":{"product":386,"type":0}}}, // [Specific Media Inc.]
-  {"hash":"e8b1c9274a662ad3","prefixes":{"":{"product":387,"type":0}}}, // [Metrigo GmbH]
-  {"hash":"d0ffd80eda189780","prefixes":{"":{"product":387,"type":0}}}, // [Metrigo GmbH]
-  {"hash":"e4ab3c31faef2b98","prefixes":{"":{"product":387,"type":0}}}, // [Metrigo GmbH]
-  {"hash":"97db8dd1bcbc33b8","prefixes":{"*":{"product":388,"type":0}}}, // [SpongeCell]
-  {"hash":"363a0f26e680d077","prefixes":{"":{"product":389,"type":0}}}, // [SpngeCell LLC]
-  {"hash":"fbef9c1b28b0cb05","prefixes":{"*":{"product":388,"type":0}}}, // [SpongeCell]
-  {"hash":"2218b5ce1e656e21","prefixes":{"":{"product":390,"type":0}}}, // [SpotXchange]
-  {"hash":"a520f16cf6177ebd","prefixes":{"":{"product":390,"type":0}}}, // [SpotXchange]
-  {"hash":"cda310d3654d07a5","prefixes":{"":{"product":390,"type":0}}}, // [SpotXchange]
-  {"hash":"2fc5567578510af6","prefixes":{"":{"product":391,"type":0}}}, // [Spotxchange]
-  {"hash":"abab2d20e98c266d","prefixes":{"":{"product":390,"type":0}}}, // [SpotXchange]
-  {"hash":"0d78cf3b068120c3","prefixes":{"":{"product":390,"type":0}}}, // [SpotXchange]
-  {"hash":"6da7c1b25ca845b3","prefixes":{"":{"product":390,"type":0}}}, // [SpotXchange]
-  {"hash":"c824df0fb0fdf482","prefixes":{"":{"product":392,"type":0}}}, // [Encore Attribution Platform]
-  {"hash":"9796e014709ccbec","prefixes":{"":{"product":392,"type":1}}}, // [Encore Attribution Platform]
-  {"hash":"fced1a8e32fb989c","prefixes":{"*":{"product":393,"type":0}}}, // [Steelhouse]
-  {"hash":"314523d1c217734f","prefixes":{"*":{"product":394,"type":0}}}, // [Strike New Media Limited]
-  {"hash":"276a5e6003750c07","prefixes":{"*":{"product":395,"type":0}}}, // [Struq Limited]
-  {"hash":"e5652beb11c7fceb","prefixes":{"*":{"product":396,"type":0}}}, // [SundaySky Inc.]
-  {"hash":"173a426f6562928a","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"81a2745fc67a8ecf","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"0aea8cde58b4f14e","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"b73e77077b022d36","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"fcf0d2e1f5fa003b","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"361c645b41a96807","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"81df9375fed9172e","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"c1493a0cd3b358a5","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"bdedb9447527960a","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"1cb83aa94e1a92ed","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"2172731c879fab72","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"7dd683bf50ce5c95","prefixes":{"":{"product":397,"type":1}}}, // [Symphony Advanced Media]
-  {"hash":"aa47b70219d2ee5e","prefixes":{"*":{"product":398,"type":1}}}, // [TagMan Ltd.]
-  {"hash":"097edb88beda9a20","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"bc65fc5f46cd88c9","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"a4d1bf696dde4d0b","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"c94f9318ace953f1","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"9e2b38828859944c","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"02319fc6286418de","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"dacc570e07ffd91a","prefixes":{"img":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"e8ccbc8f652e85a2","prefixes":{"*":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"da1ba7cc516336c0","prefixes":{"":{"product":399,"type":0}}}, // [Taobao]
-  {"hash":"41035e7733acf867","prefixes":{"":{"product":400,"type":1}}}, // [Target.com]
-  {"hash":"0509bdf297db5010","prefixes":{"*":{"product":401,"type":0}}}, // [Teadma]
-  {"hash":"69925c7888575612","prefixes":{"":{"product":402,"type":0}}}, // [BannerConnect BV]
-  {"hash":"4d44c3cec23aea09","prefixes":{"":{"product":402,"type":0}}}, // [BannerConnect BV]
-  {"hash":"447ea46d0797b32f","prefixes":{"*":{"product":403,"type":0}}}, // [Teracent Corporation]
-  {"hash":"26ca7e33d194e46e","prefixes":{"":{"product":403,"type":0}}}, // [Teracent Corporation]
-  {"hash":"b49b79e2e870c3e9","prefixes":{"":{"product":403,"type":0}}}, // [Teracent Corporation]
-  {"hash":"3a555db76a46f881","prefixes":{"*":{"product":37,"type":0}}}, // [The Trade Desk Inc.]
-  {"hash":"c4684dd3ef28687a","prefixes":{"*":{"product":404,"type":1}}}, // [The Travelers Indemnity Company]
-  {"hash":"1c38e7ac2dcf5d58","prefixes":{"":{"product":405,"type":0}}}, // [Videology]
-  {"hash":"4872cdec0944a698","prefixes":{"":{"product":405,"type":0}}}, // [Videology]
-  {"hash":"d4e30248b2920988","prefixes":{"*":{"product":406,"type":1}}}, // [TNS Custom Research Inc.]
-  {"hash":"48a3c2e049507f03","prefixes":{"*":{"product":407,"type":0}}}, // [TrackingSoft LLC]
-  {"hash":"4c5b26902a10b85b","prefixes":{"*":{"product":407,"type":0}}}, // [TrackingSoft LLC]
-  {"hash":"51a48ea23568f817","prefixes":{"*":{"product":408,"type":0}}}, // [Tradedoubler]
-  {"hash":"14251708a577d8c0","prefixes":{"*":{"product":409,"type":0}}}, // [Epic Marketplace]
-  {"hash":"20f50db7213cc9ee","prefixes":{"*":{"product":410,"type":0}}}, // [Tribal Fusion]
-  {"hash":"37b92f46ce8d0fa5","prefixes":{"":{"product":410,"type":0}}}, // [Tribal Fusion]
-  {"hash":"218cac8e116dcf7a","prefixes":{"":{"product":411,"type":0}}}, // [Triggit]
-  {"hash":"135ee5dfe108d144","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"f6afa26369731900","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"600a58efa4b0a4fa","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"c274f6336d4a40c8","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"0476503f0fc5138a","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"f6364185e21bdfb4","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"3b746cbe2984928e","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"2966c06482ab340c","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"1320f91c88734ed7","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"49e73f2dfe503088","prefixes":{"":{"product":412}}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"345de3574a5cef61","prefixes":{"":{"product":413,"type":0}}}, // [CarMax Business Services LLC]
-  {"hash":"8aba77355315b602","prefixes":{"":{"product":414,"type":0}}}, // [Charter Communications]
-  {"hash":"f7e3882cd37d1a5b","prefixes":{"":{"product":414,"type":0}}}, // [Charter Communications]
-  {"hash":"a62179d5dc8551f8","prefixes":{"":{"product":414,"type":0}}}, // [Charter Communications]
-  {"hash":"ac3760dc99259bf9","prefixes":{"":{"product":415,"type":0}}}, // [General Nutrition Centers Inc.]
-  {"hash":"e1c51fbf9b39950a","prefixes":{"":{"product":416,"type":0}}}, // [Hamilton Beach]
-  {"hash":"68a80c829eb9c95e","prefixes":{"":{"product":417,"type":0}}}, // [JacquieLawson.com]
-  {"hash":"a02b27c9af68c051","prefixes":{"":{"product":418,"type":0}}}, // [TruEffect]
-  {"hash":"76b54dcac102ae32","prefixes":{"":{"product":418,"type":0}}}, // [TruEffect]
-  {"hash":"f36743b8c729a3e5","prefixes":{"":{"product":419,"type":0}}}, // [American Greetings]
-  {"hash":"0d479c4b1d2026b9","prefixes":{"":{"product":420,"type":0}}}, // [BlueMountain]
-  {"hash":"c442eae221355ece","prefixes":{"":{"product":421,"type":0}}}, // [Cardstore]
-  {"hash":"1277d75c5bace94e","prefixes":{"":{"product":422,"type":0}}}, // [Chemistry.com]
-  {"hash":"2534adb635b0540f","prefixes":{"":{"product":423,"type":0}}}, // [Donald J Pliner]
-  {"hash":"6e81f110e25ceba1","prefixes":{"*":{"product":424,"type":0}}}, // [Gevalia]
-  {"hash":"58cb024039904795","prefixes":{"":{"product":425,"type":0}}}, // [GSI Media]
-  {"hash":"36b7a450ddb92a81","prefixes":{"":{"product":426,"type":0}}}, // [Match.com]
-  {"hash":"7f6a517c8eef7bf6","prefixes":{"":{"product":426,"type":0}}}, // [Match.com]
-  {"hash":"b5aa9057f4ab3a79","prefixes":{"":{"product":426,"type":0}}}, // [Match.com]
-  {"hash":"177eb410b9eee3c2","prefixes":{"":{"product":426,"type":0}}}, // [Match.com]
-  {"hash":"5a75e9cff48a157c","prefixes":{"":{"product":426,"type":0}}}, // [Match.com]
-  {"hash":"e561536f4b9b0f5e","prefixes":{"*":{"product":427,"type":0}}}, // [Optimum Response]
-  {"hash":"3aaed06dec8e119b","prefixes":{"":{"product":428,"type":0}}}, // [Oreck]
-  {"hash":"e7b19cb5471c10b3","prefixes":{"":{"product":429,"type":0}}}, // [Tassimo]
-  {"hash":"5eca8c8aa7c01b0e","prefixes":{"*":{"product":430,"type":0}}}, // [uSwitch]
-  {"hash":"974734b3e01eab8f","prefixes":{"*":{"product":431,"type":0}}}, // [TubeMogul Inc.]
-  {"hash":"9f562a308fffc5c4","prefixes":{"*":{"product":432,"type":0}}}, // [Tumri]
-  {"hash":"09845e50cbc70b8a","prefixes":{"*":{"product":180,"type":0}}}, // [AdAction]
-  {"hash":"82ae5c9a96804ec8","prefixes":{"":{"product":101,"type":0}}}, // [BigaBid Media Ltd.]
-  {"hash":"b91b0c7d1d3bb786","prefixes":{"":{"product":101,"type":0}}}, // [BigaBid Media Ltd.]
-  {"hash":"2804070c2606fca7","prefixes":{"":{"product":101,"type":0}}}, // [BigaBid Media Ltd.]
-  {"hash":"d601d362a989dcf9","prefixes":{"":{"product":433,"type":0}}}, // [iMarker]
-  {"hash":"0a0084b896887917","prefixes":{"":{"product":433,"type":0}}}, // [iMarker]
-  {"hash":"64596506e8398578","prefixes":{"":{"product":433,"type":0}}}, // [iMarker]
-  {"hash":"4af3f67573bdbad8","prefixes":{"":{"product":433,"type":0}}}, // [iMarker]
-  {"hash":"1348f7d07273dfcf","prefixes":{"":{"product":433,"type":0}}}, // [iMarker]
-  {"hash":"4329a4ad527e4779","prefixes":{"":{"product":433,"type":0}}}, // [iMarker]
-  {"hash":"5eca470b27725f28","prefixes":{"*":{"product":434,"type":0}}}, // [Turn Inc.]
-  {"hash":"83807aae08d0747f","prefixes":{"*":{"product":434,"type":0}}}, // [Turn Inc.]
-  {"hash":"a0542aaf969b6041","prefixes":{"*":{"product":435,"type":0}}}, // [Twelvefold Media]
-  {"hash":"7837c4e8623f0409","prefixes":{"":{"product":435,"type":0}}}, // [Twelvefold Media]
-  {"hash":"13c46ea92caeecf8","prefixes":{"":{"product":436,"type":0}}}, // [Tynt]
-  {"hash":"5f7c83b68361da73","prefixes":{"*":{"product":437,"type":1}}}, // [Unica an IBM Company]
-  {"hash":"bd242bcdc493f1d5","prefixes":{"*":{"product":438,"type":0}}}, // [Unicast]
-  {"hash":"58ad481190b46e2e","prefixes":{"":{"product":439,"type":0}}}, // [UniQlick]
-  {"hash":"7f5d2102ab11e53c","prefixes":{"":{"product":439,"type":0}}}, // [UniQlick]
-  {"hash":"c9dd94a27435350b","prefixes":{"":{"product":439,"type":0}}}, // [UniQlick]
-  {"hash":"4ba8d85cfc1bf5de","prefixes":{"*":{"product":440,"type":0}}}, // [United Virtualities]
-  {"hash":"0e4c474511c6dfff","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"875bbc4dbaee8734","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"58b08ddd9e3cccf9","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"356603d457828911","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"77c85cb3240da7c5","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"010912cf400592bc","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"28e6d587198883be","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"e64d00be64f97a79","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"fa0271d4d3cf41f2","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"a227d04cd3bf04f7","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"b69205c5372d2357","prefixes":{"":{"product":441,"type":1}}}, // [VideoHub]
-  {"hash":"da30259edef87286","prefixes":{"*":{"product":442,"type":1}}}, // [Visible Measures Corp.]
-  {"hash":"46ff1406588e7ceb","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"32ca2bff73328a83","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"3fc1dc351d4952c8","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"80d2379485452f29","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"35183abb3e2c864c","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"3b235045cc005d15","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"34e6561d9300f451","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"08980f63c2ca7971","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"327755ab5ee91d4e","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"c3d3383046b5690f","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"d196d3b7e439011e","prefixes":{"":{"product":190,"type":1}}}, // [Nielsen OBE (Vizu)]
-  {"hash":"09582bb8c4f0bdcd","prefixes":{"*":{"product":443,"type":0}}}, // [Vizury Interactive Solutions Pvt. Ltd.]
-  {"hash":"ccbe4ed34be8ea01","prefixes":{"":{"product":444,"type":0}}}, // [Markit On Demand (Adhesion)]
-  {"hash":"5c0c23d6d5b2aa7d","prefixes":{"":{"product":444,"type":0}}}, // [Markit On Demand (Adhesion)]
-  {"hash":"6fe5393d68aec474","prefixes":{"":{"product":444,"type":0}}}, // [Markit On Demand (Adhesion)]
-  {"hash":"24de99047e3e2592","prefixes":{"":{"product":444,"type":0}}}, // [Markit On Demand (Adhesion)]
-  {"hash":"a1d810c22ef4c8c1","prefixes":{"":{"product":444,"type":0}}}, // [Markit On Demand (Adhesion)]
-  {"hash":"a961c235191ccc5c","prefixes":{"":{"product":444,"type":0}}}, // [Markit On Demand (Adhesion)]
-  {"hash":"30327e228a69909d","prefixes":{"":{"product":445,"type":1}}}, // [WebMetro Inc]
-  {"hash":"1440114026d0b8a7","prefixes":{"*":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"178b8b7280deb93c","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"8398687ebe990cf1","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"5cad65c27ef8d2b4","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"f28574a110053221","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"64eae6bdfc8cc1be","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"36b0c30f5f967ffd","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"10c282544a39807b","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"ce2ed22191804ffa","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"bd56114f26a64020","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"54e283b8884709c3","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"313822ab7be9585a","prefixes":{"":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"d54943c8060334b5","prefixes":{"":{"product":447,"type":0}}}, // [Weborama Campaign Manager]
-  {"hash":"7928274bf854b28b","prefixes":{"*":{"product":446,"type":0}}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"80415fbb74db7704","prefixes":{"":{"product":448,"type":0}}}, // [Shopping Network]
-  {"hash":"0840f634995e25fb","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"5fd40859cc837b00","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"c58731043a973263","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"ee286fbf0440d595","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"660d555331a8be68","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"c412040c18d978ce","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"667b34ab71cb2381","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"b888d9e69003de82","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"38dafaa727179ef7","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"78da2db9d3a51f98","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"94a731a76dd26bfc","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"c4ca9b6aebf488dc","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"0a42e116235fec6e","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"ac4d0bcf3017cc3d","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"6653125411676c31","prefixes":{"":{"product":449,"type":0}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"062b10abe02277c1","prefixes":{"":{"product":450,"type":0}}}, // [XA.net]
-  {"hash":"b0e3a57e8f415aec","prefixes":{"":{"product":450,"type":0}}}, // [XA.net]
-  {"hash":"6e1bb44d175a20af","prefixes":{"":{"product":450,"type":0}}}, // [XA.net]
-  {"hash":"34984bab025a1372","prefixes":{"":{"product":450,"type":0}}}, // [XA.net]
-  {"hash":"d9eb2f654e80ebc6","prefixes":{"*":{"product":451,"type":0}}}, // [Xaxis LLC]
-  {"hash":"b86d63843110e02a","prefixes":{"*":{"product":452,"type":0}}}, // [Net Edge]
-  {"hash":"8b526a29c7f2b3dc","prefixes":{"*":{"product":453,"type":0}}}, // [Xplusone Solutions Inc.]
-  {"hash":"fe0ea2a1c212cfde","prefixes":{"":{"product":454,"type":0}}}, // [Yahoo! Ad Exchange]
-  {"hash":"dc06a1403eb499df","prefixes":{"":{"product":454,"type":0}}}, // [Yahoo! Ad Exchange]
-  {"hash":"5a36dbbd382aa12c","prefixes":{"":{"product":454,"type":0}}}, // [Yahoo! Ad Exchange]
-  {"hash":"c8fd15f0a5fc19aa","prefixes":{"":{"product":454,"type":0}}}, // [Yahoo! Ad Exchange]
-  {"hash":"ce63a8ab511ec5bb","prefixes":{"":{"product":454,"type":0}}}, // [Yahoo! Ad Exchange]
-  {"hash":"a6d2abe55f73bc22","prefixes":{"":{"product":455,"type":0}}}, // [Yahoo Ad Manager Plus]
-  {"hash":"707a11e6dcfa57db","prefixes":{"":{"product":455,"type":0}}}, // [Yahoo Ad Manager Plus]
-  {"hash":"f75439bd7693fa84","prefixes":{"":{"product":455,"type":0}}}, // [Yahoo Ad Manager Plus]
-  {"hash":"2f7feb27a1b93524","prefixes":{"":{"product":455,"type":0}}}, // [Yahoo Ad Manager Plus]
-  {"hash":"f801c9750710d30a","prefixes":{"":{"product":455,"type":0}}}, // [Yahoo Ad Manager Plus]
-  {"hash":"9b96f7700d727da9","prefixes":{"":{"product":456,"type":0}}}, // [APT from Yahoo!]
-  {"hash":"e4de2f3b2c06e193","prefixes":{"":{"product":456,"type":0}}}, // [APT from Yahoo!]
-  {"hash":"21aa62a45ef75fb2","prefixes":{"*":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"85bf1ed3ee6ee615","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"2cf45ce27d0b73c2","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"e8595ade1fd26e2f","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"5660279fe13cfe3b","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"ad26a995ee586915","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"23412da5a5a538cc","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"6b333dd78d119434","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"f3621ca5777d61d5","prefixes":{"":{"product":457,"type":0}}}, // [Yieldr]
-  {"hash":"cafa71178e1de4db","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"2ca490afaa90c2b3","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"8f0dd7539cf77aa5","prefixes":{"":{"product":347,"type":0}}}, // [YoYi Interactive]
-  {"hash":"005700973b435023","prefixes":{"":{"product":458,"type":0}}}, // [YuMe Inc.]
-  {"hash":"bd83427751c351a9","prefixes":{"":{"product":458,"type":0}}}, // [YuMe Inc.]
-  {"hash":"e504ebfcb6b2722e","prefixes":{"":{"product":458,"type":0}}}, // [YuMe Inc.]
-  {"hash":"8080438b5792b260","prefixes":{"":{"product":459,"type":0}}}, // [Ebuzzing]
-  {"hash":"274889e98fbfc776","prefixes":{"":{"product":459,"type":0}}}, // [Ebuzzing]
-  {"hash":"b62ee5e77fde7ec7","prefixes":{"":{"product":459,"type":0}}}, // [Ebuzzing]
-  {"hash":"cc6a7a565374c257","prefixes":{"":{"product":459,"type":0}}}, // [Ebuzzing]
-  {"hash":"e02936a6a6a2cb94","prefixes":{"":{"product":460,"type":0}}}, // [Ziff Davis]
-  {"hash":"223b94a95f6849cf","prefixes":{"":{"product":460,"type":0}}}, // [Ziff Davis]
-  {"hash":"a8742ddae80b031b","prefixes":{"":{"product":461,"type":0}}}, // [DataPoint Media Inc.]
-  {"hash":"fd4a16bf59718107","prefixes":{"":{"product":462,"type":0}}}, // [Simplytics Limited]
-  {"hash":"a3d523521bc4ba12","prefixes":{"":{"product":462,"type":0}}}, // [Simplytics Limited]
-  {"hash":"9da8a1153308d7f2","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"d9cc216c8d482336","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"166c65d7776be9f8","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"55f15e5b7746999f","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"213194bd445e551d","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"31406bff4dc35eea","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"ea9607b28f4238c2","prefixes":{"":{"product":463,"type":0}}}, // [Makazi]
-  {"hash":"707d5310f27d0dd2","prefixes":{"":{"product":464,"type":0}}}, // [Rich Relevance]
-  {"hash":"59fa19b8a48477fe","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"efb9b464f6ebaa1d","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"8848350bd85fffe4","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"519275c83a5a1c92","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"fc92bec8fbcb03ef","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"91fa39bc27e156b4","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"408d55e8995335ad","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"d0efa7323c77b1a5","prefixes":{"":{"product":465,"type":0}}}, // [MainADV]
-  {"hash":"baa5cf88a0176bc6","prefixes":{"":{"product":466,"type":0}}}, // [MediaV Advertising]
-  {"hash":"3ea0854e74c32c87","prefixes":{"":{"product":466,"type":0}}}, // [MediaV Advertising]
-  {"hash":"88a70c2ebfe38ffe","prefixes":{"":{"product":466,"type":0}}}, // [MediaV Advertising]
-  {"hash":"dc0b1dfe6de6a967","prefixes":{"":{"product":466,"type":0}}}, // [MediaV Advertising]
-  {"hash":"cb234228af27fa32","prefixes":{"":{"product":466,"type":0}}}, // [MediaV Advertising]
-  {"hash":"c7abee58863b27a4","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"7e34b0d37ded49ed","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"d7255d3135b0294d","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"e21264db24be060c","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"466676eb4c2066ac","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"2505a55ead3f2266","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"e97b9e2d31ac962d","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"906215055f6880fa","prefixes":{"":{"product":467,"type":0}}}, // [MicroAd Inc.]
-  {"hash":"df04046f11aea628","prefixes":{"*":{"product":468,"type":0}}}, // [Platform ID Inc.]
-  {"hash":"9fe8e93d55562003","prefixes":{"":{"product":469,"type":0}}}, // [Xrost]
-  {"hash":"6b29d401833f79d8","prefixes":{"":{"product":468,"type":0}}}, // [Platform ID Inc.]
-  {"hash":"00928c6f847a4785","prefixes":{"":{"product":470,"type":1}}}, // [Sociocast Networks LLC D/B/A Velos]
-  {"hash":"c3964f299adbe862","prefixes":{"":{"product":471,"type":1}}}, // [Trend Research]
-  {"hash":"76b5ddb10f769c6b","prefixes":{"*":{"product":245,"type":0}}}, // [AdOcean Ltd]
-  {"hash":"f52edd3926705507","prefixes":{"":{"product":472,"type":0}}}, // [Black Swan Verification]
-  {"hash":"d63e38f4eba51f77","prefixes":{"":{"product":473,"type":0}}}, // [Momentum K.K]
-  {"hash":"6c0f8db03b28099b","prefixes":{"":{"product":472,"type":0}}}, // [Black Swan Verification]
-  {"hash":"248772911542d550","prefixes":{"*":{"product":474,"type":0}}}, // [Betgenius Limited]
-  {"hash":"38a72a4924027d8f","prefixes":{"*":{"product":475,"type":1}}}, // [AT Internet]
-  {"hash":"255b63d169bd9d10","prefixes":{"*":{"product":475,"type":1}}}, // [AT Internet]
-  {"hash":"3a7fbbad166769ad","prefixes":{"":{"product":476,"type":1}}}, // [DataLab]
-  {"hash":"fe64230a84967d3c","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"a91296d609efe0b4","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"947fa5564eccc0b2","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"89a64fe46687237f","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"ce1cd4220063df2d","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"1c489f83a79301c6","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"9dc25ef9b3ed3e5d","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"9898ab0c57d683ae","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"0229fe19979f88b0","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"6dedd3fca4d243ac","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"cbc23a15e9f02987","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"95119cbc05f9e42a","prefixes":{"":{"product":477,"type":1}}}, // [Innovid Inc.]
-  {"hash":"784647d3eb0236dc","prefixes":{"*":{"product":478,"type":0}}}, // [Adacado]
-  {"hash":"4be5d3939998bc39","prefixes":{"":{"product":478,"type":0}}}, // [Adacado]
-  {"hash":"cec4d2059bbb1365","prefixes":{"*":{"product":479,"type":0}}}, // [NetDNA, LLC]
-  {"hash":"87a9bf2f660b2673","prefixes":{"":{"product":473,"type":0}}}, // [Momentum K.K]
-  {"hash":"33f6a4c9eb1313f6","prefixes":{"":{"product":473,"type":0}}}, // [Momentum K.K]
-  {"hash":"38afcf5464d4a46e","prefixes":{"":{"product":473,"type":0}}}, // [Momentum K.K]
-  {"hash":"4a13b10532de4033","prefixes":{"*":{"product":480,"type":0}}}, // [Pipewave Inc.]
-  {"hash":"a703750c918980b9","prefixes":{"":{"product":481,"type":0}}}, // [US Media Consulting]
-  {"hash":"77b351109047edb2","prefixes":{"":{"product":482,"type":0}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"f9f554c96902397e","prefixes":{"":{"product":482,"type":0}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"e8f2c7f5eb75983e","prefixes":{"":{"product":482,"type":0}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"f8680fe819857e65","prefixes":{"image":{"product":482,"type":0}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"fe12b35f78c433a6","prefixes":{"":{"product":482,"type":0}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"531f5c369a189473","prefixes":{"":{"product":483,"type":0}}}, // [Hanesbrands Direct LLC]
-  {"hash":"4bfbc25da5ec8116","prefixes":{"":{"product":484,"type":0}}}, // [A1platform]
-  {"hash":"56cea5c2b408989a","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"2c24b521f38d28dd","prefixes":{"":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"d6449351ee8e33eb","prefixes":{"*":{"product":485,"type":0}}}, // [Agency.com]
-  {"hash":"5e040f7b958d9ee5","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"379ed8ab1690a74c","prefixes":{"":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"6ed4dac9c333ef4b","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"b4a9e54654a6de08","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"687aa30619ec8e7f","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"5ac823af612c4492","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"ce4e70466c43ade3","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"c865cf822ab64a71","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"083c339aac7e418c","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"8d689bf60029c98f","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"19d0e1eba389dfe1","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"b789395149868329","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"25e9f5191f3d2397","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"82a743999425aaad","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"97a729e5b41fd4ed","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"0db7dee9d3c756cc","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"10981271cb66af25","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"8c86bc9ba67482c6","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"d36efad270e3e7c6","prefixes":{"*":{"product":17,"type":0}}}, // [eBay]
-  {"hash":"b709ca3f38e77645","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"3cba207e4aa9d6c6","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"fd8da92d6de2518b","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"d9e4d4444ebd418f","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"4c1c4999d1501943","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"a635762b8125bba5","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"99818fe6fd4c4a9c","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"cae59de4e054a5a8","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"d1ec771fe9489a9f","prefixes":{"":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"d9effad74da2b097","prefixes":{"*":{"product":486,"type":0}}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"46b1fc5fe9da3681","prefixes":{"*":{"product":487,"type":1}}}, // [Fjord Technologies S.A.S.]
-  {"hash":"e0b6d05a8e75e14a","prefixes":{"*":{"product":487,"type":1}}}, // [Fjord Technologies S.A.S.]
-  {"hash":"11a89bdf6bc5cf28","prefixes":{"":{"product":488,"type":1}}}, // [Refined Ads]
-  {"hash":"8e6414939f586d4c","prefixes":{"":{"product":488,"type":1}}}, // [Refined Ads]
-  {"hash":"6462a1b97a382278","prefixes":{"":{"product":488,"type":1}}}, // [Refined Ads]
-  {"hash":"9f99479854cea2e7","prefixes":{"":{"product":488,"type":1}}}, // [Refined Ads]
-  {"hash":"72b40aacd2b4e226","prefixes":{"":{"product":488,"type":1}}}, // [Refined Ads]
-  {"hash":"67401ef133d2ed76","prefixes":{"":{"product":489}}}, // [nugg.ad AG]
-  {"hash":"696757eb9e07845f","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"c84660fcf8a4c99c","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"df10c5e0e18fda2b","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"c71dfe726124b24c","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"f603a3b56996fe4c","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"149593d24f74e3e1","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"a1b9a8ff7b829f8f","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"37cb27fb57319c52","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"16e50e7e7b499ab7","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"c10f5df1adb6160f","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"df3ea734f608dc0d","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"3014b8652e4fd340","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"68034e41a59505be","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"4ff550d2f5a384d7","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"266c6cb54cc8f810","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"c174c4c7c469cbb9","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"19b8f26cb5987d86","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"0301de7ebef3ded7","prefixes":{"":{"product":490,"type":1}}}, // [Miaozhen Systems]
-  {"hash":"5f6ccacecc90b6ab","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"cee43a3e7001e664","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"27d64efa61e9fb8c","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"05eae7c7a976d6b2","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"da375ad9bc86ad05","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"1a62d22c13d4f003","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"65f8018fc9a58ba7","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"c790c87ca2abbb6c","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"5aefca188560242d","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"eaa7adee1317cb7d","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"db5afb1288bacbff","prefixes":{"*":{"product":491,"type":1}}}, // [Meetrics GmbH]
-  {"hash":"7d618e8de39f548c","prefixes":{"*":{"product":491,"type":1}}}, // [Meetrics GmbH]
-  {"hash":"b5c30978f10b1f56","prefixes":{"s":{"product":491,"type":1},"":{"product":492,"type":0}}}, // [Meetrics GmbH] [Meetrics]
-  {"hash":"5c4a10a5bc0897c7","prefixes":{"":{"product":493,"type":1}}}, // [Digital Control GmbH & Co. KG]
-  {"hash":"38d57267aeada6cc","prefixes":{"":{"product":493,"type":1}}}, // [Digital Control GmbH & Co. KG]
-  {"hash":"7dc82de98d234295","prefixes":{"":{"product":494,"type":1}}}, // [Dedicated Media]
-  {"hash":"98cac3ed2db221c5","prefixes":{"":{"product":494,"type":1}}}, // [Dedicated Media]
-  {"hash":"74da617dd78c4c25","prefixes":{"":{"product":494,"type":1}}}, // [Dedicated Media]
-  {"hash":"ad829d4fccaec076","prefixes":{"":{"product":494,"type":1}}}, // [Dedicated Media]
-  {"hash":"93214296470961ea","prefixes":{"":{"product":495,"type":1}}}, // [Accuen]
-  {"hash":"fb8e16c2a3413e04","prefixes":{"*":{"product":496,"type":0}}}, // [Pulse 360, Inc.]
-  {"hash":"56de3497c2b187f9","prefixes":{"*":{"product":496,"type":0}}}, // [Pulse 360, Inc.]
-  {"hash":"1763cb8cd4ecb455","prefixes":{"*":{"product":497,"type":0}}}, // [ZANOX AG]
-  {"hash":"dd420134fd0b31f7","prefixes":{"*":{"product":497,"type":0}}}, // [ZANOX AG]
-  {"hash":"f942b375b4c9d301","prefixes":{"":{"product":498,"type":0}}}, // [Webgains Ltd]
-  {"hash":"03b41741559a5775","prefixes":{"":{"product":499,"type":0}}}, // [Virgin Media Limited]
-  {"hash":"e01702c3ace07a42","prefixes":{"*":{"product":500,"type":0}}}, // [MyBuys MyAds]
-  {"hash":"a09aa03b7ab4a6a0","prefixes":{"*":{"product":501,"type":0}}}, // [VCCP Search LTD]
-  {"hash":"8ae53030752d70fd","prefixes":{"":{"product":502,"type":0}}}, // [Conversant Media]
-  {"hash":"3f911ef887ffe5a7","prefixes":{"":{"product":502,"type":0}}}, // [Conversant Media]
-  {"hash":"dd0195d7ab665db3","prefixes":{"":{"product":502,"type":0}}}, // [Conversant Media]
-  {"hash":"6ac275e8e99e5fb3","prefixes":{"":{"product":502,"type":0}}}, // [Conversant Media]
-  {"hash":"5960f055d64bd6fb","prefixes":{"":{"product":502,"type":0}}}, // [Conversant Media]
-  {"hash":"d07a0c93a2f5da33","prefixes":{"":{"product":502,"type":0}}}, // [Conversant Media]
-  {"hash":"b7e7f7ab4a600ced","prefixes":{"":{"product":503,"type":0}}}, // [Up-Value GmbH & Co. KG]
-  {"hash":"e92a06c68de2a79d","prefixes":{"":{"product":504,"type":0}}}, // [Unruly Media]
-  {"hash":"789659215cb1620d","prefixes":{"":{"product":504,"type":0}}}, // [Unruly Media]
-  {"hash":"b61a48cd46cb7b06","prefixes":{"*":{"product":505,"type":0}}}, // [Underdog Media LLC]
-  {"hash":"eea5fa46bce35e24","prefixes":{"":{"product":506,"type":0}}}, // [SVG Media Pvt. Ltd.]
-  {"hash":"9b346c0d77f1fcf2","prefixes":{"*":{"product":507,"type":0}}}, // [TRAFFIQ LLC]
-  {"hash":"51324f52aa5eb734","prefixes":{"*":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"26e3ca8cc9a6afd8","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"2e9a57a3dcc61e3e","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"2e6202e113ae62e3","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"9a1d6d8445e2cce9","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"88015c5982735097","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"9cf10e72a2db48a9","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"cf5ba41c477d8aa5","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"fe50c8a7f665cf78","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"5c9fb160269ccb5c","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"366f4f435bfb9255","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"5dde0b5371aae6bb","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"ebd682e181b553a7","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"df61db1cec60b5a1","prefixes":{"":{"product":508,"type":0}}}, // [TellApart Inc.]
-  {"hash":"bdf8043c482f8afd","prefixes":{"*":{"product":509,"type":0}}}, // [Shopzilla Inc.]
-  {"hash":"83ce758172dc68fb","prefixes":{"*":{"product":509,"type":0}}}, // [Shopzilla Inc.]
-  {"hash":"45cc9e8ea0e405cc","prefixes":{"*":{"product":509,"type":0}}}, // [Shopzilla Inc.]
-  {"hash":"bc8d543772676fe4","prefixes":{"*":{"product":509,"type":0}}}, // [Shopzilla Inc.]
-  {"hash":"6a51a8a28265901e","prefixes":{"*":{"product":510,"type":0}}}, // [Reactivpub]
-  {"hash":"b03903f1abac9b82","prefixes":{"*":{"product":510,"type":0}}}, // [Reactivpub]
-  {"hash":"14281bd870fa9e85","prefixes":{"*":{"product":510,"type":0}}}, // [Reactivpub]
-  {"hash":"52c9dfb471edf4de","prefixes":{"*":{"product":510,"type":0}}}, // [Reactivpub]
-  {"hash":"b9cf807aee694b90","prefixes":{"*":{"product":511,"type":0}}}, // [Netseer Inc.]
-  {"hash":"720c7cdaeb3d3edf","prefixes":{"":{"product":511,"type":0}}}, // [Netseer Inc.]
-  {"hash":"a7e82477ddc48f23","prefixes":{"*":{"product":512,"type":0}}}, // [eBay Enterprise]
-  {"hash":"c35bcff10cd62a44","prefixes":{"":{"product":513,"type":0}}}, // [Goodway Group]
-  {"hash":"a45b6c7292b7b560","prefixes":{"":{"product":513,"type":0}}}, // [Goodway Group]
-  {"hash":"d76efc82324fb8d5","prefixes":{"":{"product":513,"type":0}}}, // [Goodway Group]
-  {"hash":"5eb742c77c59dd05","prefixes":{"":{"product":513,"type":0}}}, // [Goodway Group]
-  {"hash":"33f9a4e4a440eeda","prefixes":{"*":{"product":514,"type":0}}}, // [Double Positive Marketing Group Inc.]
-  {"hash":"285da2e20d7ae651","prefixes":{"*":{"product":515,"type":0}}}, // [Chitika Inc.]
-  {"hash":"9ac26bc76037dd72","prefixes":{"*":{"product":516,"type":0}}}, // [Scigineer Inc.]
-  {"hash":"11971f02aee2996f","prefixes":{"*":{"product":517,"type":0}}}, // [Sales Spider Inc.]
-  {"hash":"0dfb620c1f99f67a","prefixes":{"*":{"product":517,"type":0}}}, // [Sales Spider Inc.]
-  {"hash":"dee182aa38b90802","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"ee4bb512aa7bff3f","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"051b6a2f5170871a","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"ef2266eab416e344","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"40701593c87a2a6d","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"4dfd82e7fcbfe056","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"2848c783f1d69118","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"26fd0c0c1bbdf578","prefixes":{"":{"product":518,"type":0}}}, // [Rocket Fuel Inc.]
-  {"hash":"9362d437c6649ac0","prefixes":{"":{"product":519,"type":0}}}, // [RTBlab]
-  {"hash":"83cd554cdc78cc1c","prefixes":{"":{"product":519,"type":0}}}, // [RTBlab]
-  {"hash":"e4e3ec12949d311d","prefixes":{"":{"product":519,"type":0}}}, // [RTBlab]
-  {"hash":"9db675ca1ddbc25e","prefixes":{"":{"product":519,"type":0}}}, // [RTBlab]
-  {"hash":"c407f5eb4837736a","prefixes":{"":{"product":519,"type":0}}}, // [RTBlab]
-  {"hash":"27e52d41a00bf2fd","prefixes":{"":{"product":519,"type":0}}}, // [RTBlab]
-  {"hash":"efa545dd9d577a82","prefixes":{"":{"product":520,"type":0}}}, // [abilicom GmbH]
-  {"hash":"f690d50313c4d883","prefixes":{"":{"product":520,"type":0}}}, // [abilicom GmbH]
-  {"hash":"e59063ed858c1ac6","prefixes":{"":{"product":520,"type":0}}}, // [abilicom GmbH]
-  {"hash":"08ecd0f7d816b029","prefixes":{"":{"product":29,"type":0}}}, // [Rakuten Display]
-  {"hash":"6321d1d2e3ff13cf","prefixes":{"":{"product":521,"type":0}}}, // [Pulpo Media Inc]
-  {"hash":"68778ff49de5f6b7","prefixes":{"":{"product":521,"type":0}}}, // [Pulpo Media Inc]
-  {"hash":"4fe62a295bf7110a","prefixes":{"*":{"product":522,"type":0}}}, // [OneSpot]
-  {"hash":"0a03e9309eac6fef","prefixes":{"*":{"product":523,"type":0}}}, // [MyThings UK Ltd]
-  {"hash":"aefee6cf21fb21d0","prefixes":{"*":{"product":523,"type":0}}}, // [MyThings UK Ltd]
-  {"hash":"013cf49561a61d0a","prefixes":{"":{"product":524,"type":0}}}, // [Exactag]
-  {"hash":"a5db93b0474bf88a","prefixes":{"":{"product":524,"type":0}}}, // [Exactag]
-  {"hash":"8eaf146d58acaea3","prefixes":{"":{"product":348,"type":1}}}, // [AdMaster]
-  {"hash":"62f9a92e2fa55157","prefixes":{"":{"product":348,"type":1}}}, // [AdMaster]
-  {"hash":"2246fe417fb594d4","prefixes":{"":{"product":348,"type":1}}}, // [AdMaster]
-  {"hash":"46be6b3d05c938b5","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"b588a450d30940dc","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"9013d3536e80f01a","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"705829297e5108ae","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"bfd58f70292d02ab","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"ff5875b2546d8499","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"ccc16a9e8656612f","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"a764b52c155c440b","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"a8a184b600fd3af1","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"6c106d279e66ed61","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"7c8663ad744aeec9","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"c3860e5673290a36","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"485e37ef683e6da8","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"03c59eef464ffa9d","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"e8d28d6ae9ed1064","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"1fc896b89972c4a3","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"89d45cf6716d92c4","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"c374b8ef2cc0a6d3","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"e0a60df6ec972762","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"dfd819866072d81c","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"dbaab38c6254fc44","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"25e404b1d7cfa7b3","prefixes":{"":{"product":525,"type":0}}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"f9b4a878a9f66629","prefixes":{"":{"product":526,"type":0}}}, // [Beijing LangTaoJin Interactive]
-  {"hash":"5be19b5ec9da0217","prefixes":{"":{"product":526,"type":0}}}, // [Beijing LangTaoJin Interactive]
-  {"hash":"c3dd7532c047b725","prefixes":{"":{"product":527,"type":0}}}, // [Conversant Mobile Media]
-  {"hash":"fd89a621a7abcb21","prefixes":{"":{"product":527,"type":0}}}, // [Conversant Mobile Media]
-  {"hash":"8b03c1ce3a37af3e","prefixes":{"":{"product":528,"type":0}}}, // [MM1X.nl]
-  {"hash":"51f16f2963b5ab62","prefixes":{"":{"product":528,"type":0}}}, // [MM1X.nl]
-  {"hash":"a34aa5b1e90b35d0","prefixes":{"":{"product":529,"type":0}}}, // [Trivu Media Inc.]
-  {"hash":"f5fe0a711d905029","prefixes":{"":{"product":529,"type":0}}}, // [Trivu Media Inc.]
-  {"hash":"284614e662fae11d","prefixes":{"*":{"product":530,"type":0}}}, // [BlueCava Inc.]
-  {"hash":"cd9e8f6b8e3bb0bb","prefixes":{"":{"product":531,"type":1}}}, // [Beijing Gridsum Technology Co. Ltd.]
-  {"hash":"97de03485c681efe","prefixes":{"":{"product":531,"type":1}}}, // [Beijing Gridsum Technology Co. Ltd.]
-  {"hash":"6c624568b77c2f15","prefixes":{"":{"product":531,"type":1}}}, // [Beijing Gridsum Technology Co. Ltd.]
-  {"hash":"2b74e65baabdf4a8","prefixes":{"":{"product":532,"type":0}}}, // [Adsvana DSP]
-  {"hash":"fcd2a83347336f39","prefixes":{"":{"product":532,"type":0}}}, // [Adsvana DSP]
-  {"hash":"7cadddba30cbf68b","prefixes":{"":{"product":362,"type":0}}}, // [revenue cloud]
-  {"hash":"39fe4b58f8d0c85a","prefixes":{"":{"product":533,"type":0}}}, // [Target Performance]
-  {"hash":"219259d49fac1ccb","prefixes":{"":{"product":534,"type":1}}}, // [Content Spread]
-  {"hash":"ca8d76b63fdfd7e7","prefixes":{"":{"product":362,"type":0}}}, // [revenue cloud]
-  {"hash":"ed86b10928624d27","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"205f80e614b45d0c","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"88c9d142721a0010","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"c918497df4612dee","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"ecc68ce18bc92eac","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"acd6e7d757515791","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"611fb7a1125a9f9d","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"b47f7e78adfcce8c","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"e7d6867de133fef3","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"022353c9ab0821d7","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"2571a0502f188936","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"f1efca13f787818a","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"1c982ec87cdd98c7","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"ffa62eae8604dfb9","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"8c7ba8485b195fda","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"188fb424b02d01b3","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"92807e8eb5ceed53","prefixes":{"":{"product":535,"type":0}}}, // [Datamind Effective Media]
-  {"hash":"b01a0f9c920b194e","prefixes":{"":{"product":536,"type":0}}}, // [ScaleOut Inc.]
-  {"hash":"da51b7d5383143f5","prefixes":{"":{"product":536,"type":0}}}, // [ScaleOut Inc.]
-  {"hash":"acca27df7ac50ef3","prefixes":{"":{"product":536,"type":0}}}, // [ScaleOut Inc.]
-  {"hash":"8a45863cac015863","prefixes":{"":{"product":536,"type":0}}}, // [ScaleOut Inc.]
-  {"hash":"ae50046a864ceafd","prefixes":{"":{"product":536,"type":0}}}, // [ScaleOut Inc.]
-  {"hash":"de57dfdaf9a2c48a","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"b1235d3bdac69ad1","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"b2717d6d54a069e3","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"d7152b8a7fbdcfd9","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"66d946b524ae15cb","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"cb87adb62a805e43","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"64b417a15cd2caba","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"fe5fbbb5f87923ec","prefixes":{"":{"product":537,"type":1}}}, // [Ensighten]
-  {"hash":"7955dee10fac2b43","prefixes":{"":{"product":538,"type":1}}}, // [Sony Electronics Inc.]
-  {"hash":"18b842a485714b88","prefixes":{"":{"product":538,"type":1}}}, // [Sony Electronics Inc.]
-  {"hash":"5e881c11a6141a0e","prefixes":{"*":{"product":539,"type":0}}}, // [Gravity Research and Development LTD]
-  {"hash":"eb0586aa7b44d1a7","prefixes":{"":{"product":540,"type":1}}}, // [Project SunBlock]
-  {"hash":"e49a615e7e072e05","prefixes":{"":{"product":541,"type":0}}}, // [Novem sp. z o.o.]
-  {"hash":"c36795d664275022","prefixes":{"*":{"product":542,"type":1}}}, // [Econda GmbH]
-  {"hash":"1dafa12902626628","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"ddc49ed0d5adc099","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"43e36030afe70656","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"f4acd265af4a8b2c","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"2d00af9d31137b46","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"6330d2d69fac5592","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"07924db4fbf62ed8","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"40fa76b0dfe6cba9","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"cb5e5323270dac31","prefixes":{"":{"product":543,"type":0}}}, // [AdMaxim LLC]
-  {"hash":"644395b50223d6f0","prefixes":{"":{"product":77,"type":0}}}, // [Adnologies GmbH]
-  {"hash":"e816f89057c8ad52","prefixes":{"":{"product":77,"type":0}}}, // [Adnologies GmbH]
-  {"hash":"8d2b1cab5958796f","prefixes":{"":{"product":544,"type":0}}}, // [Alliance Health Networks]
-  {"hash":"3568ed34edbd0a3b","prefixes":{"":{"product":545,"type":0}}}, // [Adsame Advertising Co., Ltd]
-  {"hash":"5fd75bdc8d48469a","prefixes":{"":{"product":545,"type":0}}}, // [Adsame Advertising Co., Ltd]
-  {"hash":"f24f098ee46d7e52","prefixes":{"":{"product":545,"type":0}}}, // [Adsame Advertising Co., Ltd]
-  {"hash":"695c924af8b7be90","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"8c21b1544107f44b","prefixes":{"":{"product":547,"type":0}}}, // [PK Online Ventures Limited]
-  {"hash":"b709e5fa7a0a3284","prefixes":{"":{"product":548,"type":0}}}, // [Bigpoint Gmbh]
-  {"hash":"54393b0479bf4296","prefixes":{"":{"product":548,"type":0}}}, // [Bigpoint Gmbh]
-  {"hash":"0228e75fa4f7ba29","prefixes":{"":{"product":548,"type":0}}}, // [Bigpoint Gmbh]
-  {"hash":"161b02c3430e8493","prefixes":{"":{"product":549,"type":0}}}, // [Mirapodo GmbH]
-  {"hash":"cbfa294f671394f5","prefixes":{"":{"product":550,"type":0}}}, // [Digitize New Media Ltd.]
-  {"hash":"126e76895e35030f","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"d1a3397960a0c962","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"27111f31c7f7870c","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"5066a54cd7ed6242","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"5447e7edfecbefc9","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"763e1c5a534cdce1","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"664f6761d6e1bdc5","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"85dc2dbb9cf8ba01","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"efd9939ccbcea7ca","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"5095b815554d166d","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"bbd5220662a5b37e","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"ad929f7cd3353264","prefixes":{"":{"product":551,"type":0}}}, // [AdSage]
-  {"hash":"aebf7b2a7ee1ff12","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"01ef28aab34283cc","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"c075f26f4aa57d43","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"f651f54211351ca7","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"98e7e8f01b1e7221","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"7f46832cdf7b45db","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"4a37345bf96b65b5","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"ee9f377ce8711040","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"f6f6db9a07009087","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"37414a33ff3de4a0","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"7cc06f83f0710408","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"beb1894d6a5dd8d5","prefixes":{"":{"product":552,"type":0}}}, // [Fingereach]
-  {"hash":"ab305fad96c94e68","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"abb33b12777d693c","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"cf57baa1fe60d65d","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"1e230cd699b878e6","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"0e9f493079696ce3","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"7d3350cd22011e53","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"f50b2ec037f5428b","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"c171c26c4996ef48","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"558975de73dc2727","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"ee6b8472f5558865","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"8183f3c56cedc5d3","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"9e46a78131a70a25","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"9805160753b78db8","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"9665241d465c8ced","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"0886098ece10411f","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"1b9aa72e21da1cf9","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"75eaf92a0259fced","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"6647ef959a9060b1","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"55bbd43420c048ba","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"769a3492166f2234","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"88bf787fe78aa617","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"62db61a5802ee5f9","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"ecc8b48b5b165bff","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"3b713a488717f579","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"7d501d2362243528","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"1e2c100fab457dce","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"7adb32ad76289644","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"3f4747021104b435","prefixes":{"":{"product":303,"type":1}}}, // [DMA Institute dba Hottraffic]
-  {"hash":"55ade41cc24f1b54","prefixes":{"":{"product":553,"type":0}}}, // [Calvin Klein]
-  {"hash":"210f025e6c6b8122","prefixes":{"":{"product":554,"type":0}}}, // [Medialets Servo]
-  {"hash":"233555f3daf9abb0","prefixes":{"":{"product":554,"type":0}}}, // [Medialets Servo]
-  {"hash":"eea93545b322651b","prefixes":{"":{"product":554,"type":0}}}, // [Medialets Servo]
-  {"hash":"d9fe49eeaf35eb01","prefixes":{"":{"product":554,"type":0}}}, // [Medialets Servo]
-  {"hash":"ea41698b95338591","prefixes":{"s-cdn-":{"product":554,"type":0}}}, // [Medialets Servo]
-  {"hash":"5f4e90726b181c95","prefixes":{"":{"product":555,"type":0}}}, // [Webmoblink Inc.]
-  {"hash":"9d51efd26ab44317","prefixes":{"":{"product":30,"type":0}}}, // [Retailigence]
-  {"hash":"32440ed26b61d14a","prefixes":{"":{"product":30,"type":0}}}, // [Retailigence]
-  {"hash":"8234d0306d8984eb","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"e35bf94930bc4d1a","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"aec3f56c7f99151f","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"ef395b96d922c238","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"5a053ab1bcfcfb41","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"2cf811bb8aa279b5","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"cd383e750e6cfcdb","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"c30fc77cd822188e","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"fb9678eef7ea227d","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"102facb286a88bbe","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"aa39a58ff4ed2114","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"e33908ca9604cfa4","prefixes":{"*":{"product":556,"type":1},"":{"product":557,"type":0}}}, // [Moat Inc.] [Bannerflow AB]
-  {"hash":"31902ac0cc3e362b","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"796535f10f1e1ea0","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"681a390e8faf08c1","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"1ef04ebc565a6f48","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"1461b89b1a4a5e39","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"a7c34fe979c7afe2","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"30142bb0f24faa5a","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"dc8fdd8b9daae8d5","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"80a2d23602bd08d7","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"e8713f2da85d0fff","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"08fe20173c2a758a","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"105d629b41621e8f","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"c2c8a87c65874f50","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"ecc3d954923aa593","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"313e3d29b4712d5d","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"bf332f1705b05b91","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"c2fac5215807677b","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"b1db7fe55b719fd0","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"c405962725b0a49f","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"f30974f87632ff65","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"c3a0f51c7a475e24","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"470beffefc05bd89","prefixes":{"":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"44c6bfd7fd3ae379","prefixes":{"*":{"product":556,"type":1}}}, // [Moat Inc.]
-  {"hash":"ed26e1a4862cb993","prefixes":{"":{"product":558,"type":1}}}, // [Batch Media Gmbh]
-  {"hash":"8cc35cd28ab69e7b","prefixes":{"":{"product":558,"type":1}}}, // [Batch Media Gmbh]
-  {"hash":"b480ee3cdb39aba3","prefixes":{"":{"product":558,"type":1}}}, // [Batch Media Gmbh]
-  {"hash":"42b8cf3c1fba5649","prefixes":{"":{"product":558,"type":1}}}, // [Batch Media Gmbh]
-  {"hash":"9c59afa20426083f","prefixes":{"":{"product":559,"type":0}}}, // [Twenga]
-  {"hash":"96fa4f0d4282b74b","prefixes":{"":{"product":559,"type":0}}}, // [Twenga]
-  {"hash":"147ff4cde8f7b63b","prefixes":{"":{"product":559,"type":0}}}, // [Twenga]
-  {"hash":"e6d43f305d0372aa","prefixes":{"":{"product":560,"type":0}}}, // [TraceAd]
-  {"hash":"e2a94bb0b8f09309","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"7b17e990632021fb","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"c82cc94c761aff4f","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"9bb0143d6745a1fc","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"9906e8d23a282ab0","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"c29531bb7c2a5a95","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"53972f8a807a3522","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"d8acabec202014c0","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"4062ceb50584895d","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"776d48fd287f99c8","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"caf4c25a1be2f9cc","prefixes":{"":{"product":561,"type":0}}}, // [Speed Shift Media]
-  {"hash":"ad66fb580dfc0f61","prefixes":{"*":{"product":562,"type":0}}}, // [CCB Paris]
-  {"hash":"2cd1c0997e13f343","prefixes":{"":{"product":563,"type":1}}}, // [Nielsen Digital Ad Ratings]
-  {"hash":"cc67f7e32922d026","prefixes":{"*":{"product":564,"type":0}}}, // [OpenDSP]
-  {"hash":"37ac881f55f6b624","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"6eaeb2fb0379f719","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"0f37e190c3f7659c","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"cd5e1f475a9a9cb9","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"70dae8af3c6cb2af","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"60e90d920044304d","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"9d34d5e680004543","prefixes":{"":{"product":546,"type":0}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"b4b546c24d350673","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"d0b7581f4a3ff9b8","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"0c865d217e1f18f3","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"6333a18d75125edb","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"ed4cdc36d8829848","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"3643c909d7cbe0b8","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"296c21a7001df348","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"97079bad5fb6ead8","prefixes":{"":{"product":565,"type":0}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"7b936711dd1e9a43","prefixes":{"":{"product":566,"type":0}}}, // [Mediarithmics]
-  {"hash":"c1d09d8bf99adaae","prefixes":{"":{"product":567,"type":0}}}, // [RUN, INC.]
-  {"hash":"c1a2559db78be890","prefixes":{"":{"product":567,"type":0}}}, // [RUN, INC.]
-  {"hash":"99a2370c6cb03aad","prefixes":{"":{"product":567,"type":0}}}, // [RUN, INC.]
-  {"hash":"58188c996594e74c","prefixes":{"":{"product":568,"type":0}}}, // [Shanghai Menlo Network Technologies Co.,Ltd]
-  {"hash":"ae01937a71f3c8ec","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"bb20b492d8e895ee","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"a174c7ffc06f1430","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"b04d26682765cf0f","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"3d8976d50a72415a","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"0b937695e283332d","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"5a633d8ed4134176","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"a3d5abb1d31313bb","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"651fcbfafdaa1c3b","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"210045798925d1ec","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"cb9c94ed4430c0d7","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"eb42b6b78e25a31e","prefixes":{"":{"product":569,"type":0}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"e21aeaa35d9e4534","prefixes":{"*":{"product":570,"type":1}}}, // [NET-Metrix-Audit]
-  {"hash":"d563d7cb84148f5b","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"881b6320fa6c5a13","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"648b287843959e5a","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"aa60743a7bfcd1af","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"afa7ee2a02f86074","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"3b21af5a3fa47754","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"e8f690279ec23223","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"8763304c40959465","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"97be7bbbd0aa71f1","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"1610ab8331e9fa67","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"5cf6c3a758fb5a50","prefixes":{"":{"product":571,"type":0}}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"753372717104cecb","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"9868ccc3384ca704","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"834fc9317bd55432","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"77a58434eda65f1d","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"d6c8f549569824c7","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"605f200bf3a42aec","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"24475a888daf195d","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"577626a5c9b3a87c","prefixes":{"":{"product":572,"type":1}}}, // [Resonate Networks, Inc]
-  {"hash":"c258f6da0cd8b8cb","prefixes":{"":{"product":572,"type":1}}}, // [Resonate Networks, Inc]
-  {"hash":"d9483fc3fe68e764","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"7caa53e1a6ec2bae","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"dcd74656fa3b323d","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"10fa95c5f15310d2","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"6f83daf020ab465f","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"d3d1a09a28024ddc","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"9b208cc58454fb78","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"4645c6078dc34d50","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"b238cbc325c6ef22","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"49deee4d32200263","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"773d9411487a25e3","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"0f6cf491f7eb2baa","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"8dfcd3664fa1302b","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"800bb9e7968e58aa","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"b05b363e5a0511e8","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"20c70723848457f0","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"66114e4ff94b609f","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"f2d188b48acaeb7f","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"409d1c85462adead","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"4d380a7d15d0a78a","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"d5449f5767bfafa7","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"bd39dc0af22a3152","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"f86c1368c7c5eb92","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"e8f74e435e9df1dd","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"9b5fa6e2f606ce7d","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"9a9e03501130b17a","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"2a12549f5c240468","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"215711257cc47c2c","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"77f3f7c79d95de48","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"6d31870e0469ddc6","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"d43e8e7f0b7db722","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"cf4d5bbc8b02dc1c","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"fa69e0b93ab494f2","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"5df810b59c15eb88","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"1bad3858e6b1db68","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"1f0663d5a32c3b7d","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"0accadb2b8868065","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"29fa86d0b3c09f26","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"6c3481a4787dc989","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"dd2cdf0ae459961c","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"b7ddbc93720778f5","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"65db5bf588a1552c","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"d63dadf02badb9bc","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"12a0ac899815d56b","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"4e73ffb09594e8a6","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"7bd28c9beb85782f","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"e5a3c52df181ad93","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"5db249180904a1af","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"f33943be4b14e2cc","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"3304828c6a87914b","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"0dee81e461b3c8bb","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"23282a1244ed862f","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"8b1d859efda195f4","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"e22129fd14c58ef7","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"c11b0627d1105ed8","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"fee7a2b84c23b6bb","prefixes":{"":{"product":18,"type":0}}}, // [advanced STORE GmbH]
-  {"hash":"3f3d4a96d97bc12a","prefixes":{"":{"product":573}}}, // [Triple Lift, Inc.]
-  {"hash":"7e4d08be26af0913","prefixes":{"":{"product":573}}}, // [Triple Lift, Inc.]
-  {"hash":"ab1718aa8ada6ceb","prefixes":{"":{"product":573}}}, // [Triple Lift, Inc.]
-  {"hash":"00810432ca3a5adf","prefixes":{"":{"product":573}}}, // [Triple Lift, Inc.]
-  {"hash":"e597ba5088abb36a","prefixes":{"":{"product":573}}}, // [Triple Lift, Inc.]
-  {"hash":"d206640e7ca174cd","prefixes":{"":{"product":574,"type":0}}}, // [Indie Ads]
-  {"hash":"d8ed39f1e603b870","prefixes":{"":{"product":575,"type":0}}}, // [Ocean Park Interactive]
-  {"hash":"a241e76a04cef012","prefixes":{"":{"product":575,"type":0}}}, // [Ocean Park Interactive]
-  {"hash":"dcc0a9d204aaa55d","prefixes":{"":{"product":575,"type":0}}}, // [Ocean Park Interactive]
-  {"hash":"8372761b0392f8a9","prefixes":{"":{"product":575,"type":0}}}, // [Ocean Park Interactive]
-  {"hash":"e7b8261c49b1fbf6","prefixes":{"":{"product":575,"type":0}}}, // [Ocean Park Interactive]
-  {"hash":"d5094d4667f378a7","prefixes":{"":{"product":575,"type":0}}}, // [Ocean Park Interactive]
-  {"hash":"4091c3043c2da68a","prefixes":{"":{"product":576,"type":0}}}, // [Impulse Media Pvt. Ltd.]
-  {"hash":"6eb5dacfebab8b02","prefixes":{"":{"product":577,"type":1}}}, // [CrowdTwist]
-  {"hash":"123db0626c48324c","prefixes":{"":{"product":577,"type":1}}}, // [CrowdTwist]
-  {"hash":"4f356e0d187085b0","prefixes":{"":{"product":578,"type":0}}}, // [Adzerk Inc.]
-  {"hash":"79c1600f16f0c0ad","prefixes":{"":{"product":578,"type":0}}}, // [Adzerk Inc.]
-  {"hash":"170c4bddaa53e87c","prefixes":{"":{"product":579,"type":0}}}, // [Adtarget.me]
-  {"hash":"b514da98fbd70da7","prefixes":{"":{"product":579,"type":0}}}, // [Adtarget.me]
-  {"hash":"e585ef712f906ce4","prefixes":{"":{"product":579,"type":0}}}, // [Adtarget.me]
-  {"hash":"ed5e6e621b9e9e9e","prefixes":{"":{"product":579,"type":0}}}, // [Adtarget.me]
-  {"hash":"904a8c71f0ac4b5c","prefixes":{"":{"product":579,"type":0}}}, // [Adtarget.me]
-  {"hash":"138d782ff8ef8b3d","prefixes":{"":{"product":580,"type":1}}}, // [Recruit Marketing Partners Co.,Ltd]
-  {"hash":"8899c2499d762095","prefixes":{"":{"product":581,"type":0}}}, // [Beijing Emar Online Technology Co.,Ltd]
-  {"hash":"29f87adefe40afd5","prefixes":{"":{"product":581,"type":0}}}, // [Beijing Emar Online Technology Co.,Ltd]
-  {"hash":"1f57d0a967ca4f30","prefixes":{"":{"product":581,"type":0}}}, // [Beijing Emar Online Technology Co.,Ltd]
-  {"hash":"378c4fbbd1d161e2","prefixes":{"":{"product":582,"type":0}}}, // [AdMagnet]
-  {"hash":"bb42bdad4318ee55","prefixes":{"":{"product":582,"type":0}}}, // [AdMagnet]
-  {"hash":"71d1cec71f53e140","prefixes":{"":{"product":582,"type":0}}}, // [AdMagnet]
-  {"hash":"e3bad45f1f3d21a5","prefixes":{"":{"product":582,"type":0}}}, // [AdMagnet]
-  {"hash":"aa63c60aa73e9d29","prefixes":{"":{"product":583,"type":0}}}, // [Momondo A/S]
-  {"hash":"b34444583646725a","prefixes":{"*":{"product":583,"type":0}}}, // [Momondo A/S]
-  {"hash":"cbf8a85fbf4c22e5","prefixes":{"*":{"product":584,"type":0}}}, // [DKK Agency]
-  {"hash":"e775e327a7a42402","prefixes":{"":{"product":585,"type":0}}}, // [OneScreen Inc.]
-  {"hash":"080fcbb984e6ecdd","prefixes":{"":{"product":585,"type":0}}}, // [OneScreen Inc.]
-  {"hash":"8c1ae0a34a3df5d0","prefixes":{"":{"product":585,"type":0}}}, // [OneScreen Inc.]
-  {"hash":"ba491e57276128df","prefixes":{"":{"product":586,"type":0}}}, // [AdElement Media Solutions Pvt Ltd]
-  {"hash":"620a368e66b0d054","prefixes":{"":{"product":586,"type":0}}}, // [AdElement Media Solutions Pvt Ltd]
-  {"hash":"f100a71a63d2ccfa","prefixes":{"":{"product":586,"type":0}}}, // [AdElement Media Solutions Pvt Ltd]
-  {"hash":"636877d8cc1827f4","prefixes":{"":{"product":587,"type":0}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"e066625a70a1d5c0","prefixes":{"":{"product":587,"type":0}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"117aaf00ef5036e3","prefixes":{"":{"product":587,"type":0}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"4f795b8396901621","prefixes":{"":{"product":587,"type":0}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"b8da1e9feb0bc01d","prefixes":{"":{"product":587,"type":0}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"433e8fe3ca1684d7","prefixes":{"":{"product":587,"type":0}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"f2fc51beddbeb4a9","prefixes":{"":{"product":588,"type":0}}}, // [Adsit Media Advertising Ltd. Co., (AdMan)]
-  {"hash":"ba7f680031ef6ba6","prefixes":{"":{"product":589,"type":1}}}, // [AdMan]
-  {"hash":"cba16dd5f4409e30","prefixes":{"":{"product":589,"type":1}}}, // [AdMan]
-  {"hash":"3e32b1ab3e9c66b6","prefixes":{"":{"product":588,"type":0}}}, // [Adsit Media Advertising Ltd. Co., (AdMan)]
-  {"hash":"59225b3e2dce506e","prefixes":{"":{"product":590,"type":0}}}, // [MicroAd Inc. (China)]
-  {"hash":"8a3b315693f80801","prefixes":{"":{"product":590,"type":0}}}, // [MicroAd Inc. (China)]
-  {"hash":"9ecae05881ad91ad","prefixes":{"":{"product":590,"type":0}}}, // [MicroAd Inc. (China)]
-  {"hash":"86a1bc63ec059f25","prefixes":{"":{"product":591,"type":0}}}, // [Adfonic]
-  {"hash":"ea28de00a6512e88","prefixes":{"":{"product":591,"type":0}}}, // [Adfonic]
-  {"hash":"42bb8749687dee83","prefixes":{"":{"product":592,"type":0}}}, // [OwnerIQ Inc.]
-  {"hash":"125539a4b58c9087","prefixes":{"":{"product":592,"type":0}}}, // [OwnerIQ Inc.]
-  {"hash":"895ef87fbdd546df","prefixes":{"":{"product":593,"type":0}}}, // [Mobile Space Ltd]
-  {"hash":"55e398544c3aeb40","prefixes":{"":{"product":593,"type":0}}}, // [Mobile Space Ltd]
-  {"hash":"c5e19d61efa129d7","prefixes":{"ap":{"product":593,"type":0},"e":{"product":593,"type":0},"":{"product":594,"type":0}}}, // [Mobile Space Ltd] [Mobile Space Ltd] [Jaduda GmbH]
-  {"hash":"3668b933b223ee50","prefixes":{"":{"product":595,"type":0}}}, // [Omotenashi Banner]
-  {"hash":"209fb323c4db09ef","prefixes":{"":{"product":595,"type":0}}}, // [Omotenashi Banner]
-  {"hash":"d95ee45ed75216b1","prefixes":{"":{"product":595,"type":0}}}, // [Omotenashi Banner]
-  {"hash":"7fb039cd298570d4","prefixes":{"":{"product":595,"type":0}}}, // [Omotenashi Banner]
-  {"hash":"a7d0a34772320297","prefixes":{"":{"product":595,"type":0}}}, // [Omotenashi Banner]
-  {"hash":"a86ff9f748f6a5ab","prefixes":{"":{"product":595,"type":0}}}, // [Omotenashi Banner]
-  {"hash":"046d69c93f0ab29e","prefixes":{"":{"product":596,"type":0}}}, // [Infectious Media Ltd.]
-  {"hash":"735a86882c4fccc6","prefixes":{"":{"product":597,"type":0}}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"c454c081e737b7e2","prefixes":{"":{"product":597,"type":0}}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"1e8ed560dc22bbb5","prefixes":{"":{"product":597,"type":0}}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"3a57d7982ec36d46","prefixes":{"":{"product":597,"type":0}}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"282d5dfa72aee67e","prefixes":{"":{"product":598,"type":0}}}, // [Walk Light Media Inc.]
-  {"hash":"350189fcd66d737d","prefixes":{"":{"product":599,"type":0}}}, // [AdBrite Inc.]
-  {"hash":"727c2c9dbde23217","prefixes":{"":{"product":599,"type":0}}}, // [AdBrite Inc.]
-  {"hash":"f0011932876966b7","prefixes":{"":{"product":600,"type":0}}}, // [Hi-Media]
-  {"hash":"49a154fb3339d1c9","prefixes":{"":{"product":600,"type":0}}}, // [Hi-Media]
-  {"hash":"bc9403b31553c2c3","prefixes":{"":{"product":600,"type":0}}}, // [Hi-Media]
-  {"hash":"4a763539fb83a309","prefixes":{"":{"product":600,"type":0}}}, // [Hi-Media]
-  {"hash":"ad517dcc393c2311","prefixes":{"":{"product":600,"type":0}}}, // [Hi-Media]
-  {"hash":"ea321c60d183257c","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"44405675d1af2241","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"703f39c13b597e32","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"5bdae611f2bbe659","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"87862d3ee53095a7","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"376d93acf5e8d717","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"3f0e8ced0049c1d6","prefixes":{"":{"product":601,"type":0}}}, // [Adlabs]
-  {"hash":"a04ea3bd56ab64bb","prefixes":{"":{"product":602,"type":0}}}, // [Arth Salutions]
-  {"hash":"b6ce2c8ae8e9a415","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"ebd466a03db9081b","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"2df213fa126d1ca4","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"901ec1b8062c3af6","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"3cdfbabfa37b6bd8","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"4a23a2c45d1e92c3","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"72784278d856920c","prefixes":{"":{"product":603,"type":0}}}, // [Konverta]
-  {"hash":"61aa8fff3eb4e893","prefixes":{"":{"product":102,"type":0}}}, // [Cogo Labs, Inc.]
-  {"hash":"def94469bdc7241e","prefixes":{"":{"product":102,"type":0}}}, // [Cogo Labs, Inc.]
-  {"hash":"f17d17eabacc3756","prefixes":{"":{"product":102,"type":0}}}, // [Cogo Labs, Inc.]
-  {"hash":"8644dbe4c2172593","prefixes":{"":{"product":604,"type":0}}}, // [Shopall]
-  {"hash":"4b55c6a7d9c2a9a2","prefixes":{"":{"product":604,"type":0}}}, // [Shopall]
-  {"hash":"305615cf8dbc9be2","prefixes":{"":{"product":605,"type":0}}}, // [targeting360 GmbH]
-  {"hash":"bed5b722b1bc1ba5","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"1528f8323f342e8b","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"3c0f20ff410483fa","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"929748002c9b8ecf","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"da8d84b561cc6dae","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"4d73c36d7413bcac","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"fa03c22fb3892bf3","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"9671a9ac26a91d0a","prefixes":{"":{"product":606,"type":0}}}, // [xplosion interactive GmbH]
-  {"hash":"ca13edee3fffee4e","prefixes":{"":{"product":607,"type":0}}}, // [Hubrus LLC]
-  {"hash":"e6c8579483f7b40c","prefixes":{"":{"product":607,"type":0}}}, // [Hubrus LLC]
-  {"hash":"5426e12fbea3fce8","prefixes":{"":{"product":607,"type":0}}}, // [Hubrus LLC]
-  {"hash":"e1b8d2118c9dc529","prefixes":{"":{"product":608,"type":0}}}, // [Here Media Inc.]
-  {"hash":"6ab38da002eadbc3","prefixes":{"":{"product":609,"type":0}}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"8ef09da008fcfae7","prefixes":{"":{"product":609,"type":0}}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"f09f918279f1e9ac","prefixes":{"":{"product":609,"type":0}}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"ddfd965ee920e41c","prefixes":{"":{"product":609,"type":0}}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"47758f4c45a57ea4","prefixes":{"":{"product":609,"type":0}}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"9b402085270b3ed3","prefixes":{"":{"product":609,"type":0}}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"5a4e20d5da4d99f0","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"1a32d33420507504","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"c841d6764f10305d","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"c0be785071fbf1f8","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"a48b68d5e7caa5da","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"93764efbaea60a26","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"2d1e1dbc88160b0a","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"49c9a4898d7eda62","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"51f27880010fd487","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"1930e597dd2d66f9","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"9138d5d361766aa2","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"942211eb94fc3c91","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"ac957255586d114c","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"1174020d0986b7c7","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"1386eff7c87966ca","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"d3c3497dc1813ac6","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"ec8bb52d56c92778","prefixes":{"":{"product":610,"type":0}}}, // [QuarticOn.com]
-  {"hash":"b999321725f081a5","prefixes":{"":{"product":611,"type":0}}}, // [Kavanga LLC]
-  {"hash":"43f2f88cac5c1e66","prefixes":{"":{"product":612,"type":1}}}, // [Vodafone D2 GmbH]
-  {"hash":"71f43d2f0436d908","prefixes":{"":{"product":612,"type":1}}}, // [Vodafone D2 GmbH]
-  {"hash":"4b13b8a28b6556d3","prefixes":{"":{"product":612,"type":1}}}, // [Vodafone D2 GmbH]
-  {"hash":"b9c154f4d363eebc","prefixes":{"":{"product":613,"type":1}}}, // [Qubit Digital Ltd]
-  {"hash":"f3c32c6c7e1ac882","prefixes":{"":{"product":533,"type":0},"ad":{"product":614,"type":0},"tm":{"product":614,"type":0}}}, // [Target Performance] [NEORY GmbH] [NEORY GmbH]
-  {"hash":"728524adefe77058","prefixes":{"static-":{"product":615,"type":0}}}, // [Populis Ireland Limited]
-  {"hash":"7f78aff31bba38ad","prefixes":{"":{"product":615,"type":0}}}, // [Populis Ireland Limited]
-  {"hash":"cacb07348e9e3ca3","prefixes":{"":{"product":615,"type":0}}}, // [Populis Ireland Limited]
-  {"hash":"ce069e74d10aa948","prefixes":{"":{"product":616,"type":0}}}, // [LiquidM Technology GmbH]
-  {"hash":"b6284e5bbeacee78","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"f71102b0f2425eb8","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"da76d0a397ab42fc","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"d30b0fd7cd3dc387","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"d3643510dc9a55a3","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"f74f9b96eb974ad7","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"538d09650aaff88b","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"7533124cd83c8651","prefixes":{"":{"product":617,"type":0}}}, // [Celtra Inc.]
-  {"hash":"8413a3afa447ddd6","prefixes":{"":{"product":618,"type":0}}}, // [Adfox]
-  {"hash":"28b1ebc0a8b51b58","prefixes":{"":{"product":618,"type":0}}}, // [Adfox]
-  {"hash":"0c6cea5dd49d0361","prefixes":{"sd":{"product":618,"type":0},"rt":{"product":618,"type":0}}}, // [Adfox] [Adfox]
-  {"hash":"2e3df7d60b00392d","prefixes":{"":{"product":618,"type":0}}}, // [Adfox]
-  {"hash":"4cdee950d7417a19","prefixes":{"":{"product":618,"type":0}}}, // [Adfox]
-  {"hash":"2060d81c3f4dbace","prefixes":{"":{"product":619,"type":0}}}, // [Accordant Media LLC]
-  {"hash":"f2c07b1834365ee5","prefixes":{"":{"product":620,"type":0}}}, // [Fiksu DSP]
-  {"hash":"c61068cc57f0f219","prefixes":{"":{"product":620,"type":0}}}, // [Fiksu DSP]
-  {"hash":"a1f4b4a83add949d","prefixes":{"":{"product":620,"type":0}}}, // [Fiksu DSP]
-  {"hash":"70b9063aeb27d88a","prefixes":{"":{"product":620,"type":0}}}, // [Fiksu DSP]
-  {"hash":"f66693ef14e4cd79","prefixes":{"":{"product":620,"type":0}}}, // [Fiksu DSP]
-  {"hash":"7f9c748aa884dba0","prefixes":{"":{"product":621,"type":0}}}, // [MdotM, Inc.]
-  {"hash":"13c8f5f12f3b9ca6","prefixes":{"":{"product":621,"type":0}}}, // [MdotM, Inc.]
-  {"hash":"c47f6172a03d7b4c","prefixes":{"":{"product":622,"type":1}}}, // [TNS GALLUP ADFACT, ZAO]
-  {"hash":"f9a74c430e157e57","prefixes":{"":{"product":622,"type":1}}}, // [TNS GALLUP ADFACT, ZAO]
-  {"hash":"534ec1b9f199f18a","prefixes":{"":{"product":623,"type":0}}}, // [MicroAd Inc. (APAC)]
-  {"hash":"98bec02f53970649","prefixes":{"":{"product":623,"type":0}}}, // [MicroAd Inc. (APAC)]
-  {"hash":"dab5b2f5150fe52c","prefixes":{"*":{"product":624,"type":2}}}, // [ECRITEL SARL]
-  {"hash":"039caee3c590ef51","prefixes":{"*":{"product":624,"type":2}}}, // [ECRITEL SARL]
-  {"hash":"56d4c8e77cf378ca","prefixes":{"*":{"product":624,"type":2}}}, // [ECRITEL SARL]
-  {"hash":"ea054eef4a7b535d","prefixes":{"*":{"product":624,"type":2}}}, // [ECRITEL SARL]
-  {"hash":"503f3e019cf902f7","prefixes":{"":{"product":103,"type":1}}}, // [AudienceProject]
-  {"hash":"d07ac29d5418a5a2","prefixes":{"":{"product":103,"type":1}}}, // [AudienceProject]
-  {"hash":"252a5f53fef3adef","prefixes":{"":{"product":625}}}, // [Gloto Corp.]
-  {"hash":"c45cf16c98289ef3","prefixes":{"":{"product":625}}}, // [Gloto Corp.]
-  {"hash":"43869a9fbc1e93ac","prefixes":{"":{"product":626,"type":0}}}, // [OOO GPM-Digital]
-  {"hash":"4334255596024dac","prefixes":{"*":{"product":627,"type":2}}}, // [adverserve digital advertising services]
-  {"hash":"c1cbc8c1a131b486","prefixes":{"":{"product":628,"type":0}}}, // [Abstract]
-  {"hash":"f0a24e1beb2ff006","prefixes":{"":{"product":628,"type":0}}}, // [Abstract]
-  {"hash":"5d7848291e6b2aac","prefixes":{"":{"product":628,"type":0}}}, // [Abstract]
-  {"hash":"678875d741d45390","prefixes":{"":{"product":629,"type":0}}}, // [Adscale GmbH]
-  {"hash":"bdf162f8a955792f","prefixes":{"":{"product":629,"type":0}}}, // [Adscale GmbH]
-  {"hash":"e2aa93ef150b6625","prefixes":{"":{"product":629,"type":0}}}, // [Adscale GmbH]
-  {"hash":"fbecc41bd388e9da","prefixes":{"":{"product":629,"type":0}}}, // [Adscale GmbH]
-  {"hash":"33d677c1746e032b","prefixes":{"":{"product":629,"type":0}}}, // [Adscale GmbH]
-  {"hash":"7b632e1d26173d9a","prefixes":{"":{"product":630,"type":0}}}, // [Weebly, Inc.]
-  {"hash":"d60691434c15d686","prefixes":{"":{"product":631,"type":0}}}, // [KPI Solutions Co.,Ltd.]
-  {"hash":"6bcb40c428dea82d","prefixes":{"*":{"product":631,"type":0}}}, // [KPI Solutions Co.,Ltd.]
-  {"hash":"a7261ab41534a5a9","prefixes":{"":{"product":632,"type":0}}}, // [LuckyBrand.com]
-  {"hash":"8ade692ce59ddf24","prefixes":{"":{"product":633,"type":0}}}, // [Bedrijvenweb.nl]
-  {"hash":"d14784769a5e3e32","prefixes":{"*":{"product":634,"type":0}}}, // [EdgeCast Networks Inc.]
-  {"hash":"eeb0b9405b4e70a9","prefixes":{"*":{"product":634,"type":0}}}, // [EdgeCast Networks Inc.]
-  {"hash":"799a922119603cf7","prefixes":{"":{"product":635,"type":0}}}, // [AdFrontier]
-  {"hash":"b99f16bd08f23e1d","prefixes":{"":{"product":636,"type":0}}}, // [NFQ]
-  {"hash":"55b741a8d993b7af","prefixes":{"":{"product":636,"type":0}}}, // [NFQ]
-  {"hash":"7733707370fb05c7","prefixes":{"":{"product":636,"type":0}}}, // [NFQ]
-  {"hash":"9a42cb5421abffa9","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"47ee3c7f6cf3211f","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"5e4b5dd08e9b52fd","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"6bc3a667cd012222","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"18656382f2827e60","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"c73db0ed241d269e","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"bc0f02a06b74b7a3","prefixes":{"":{"product":637}}}, // [DataLogix, Inc.]
-  {"hash":"0405bea2af551e19","prefixes":{"":{"product":637,"type":1}}}, // [DataLogix, Inc.]
-  {"hash":"c35511ecd49cebb7","prefixes":{"":{"product":638,"type":0}}}, // [Brightcove]
-  {"hash":"22bfe38898977ed4","prefixes":{"":{"product":638,"type":0}}}, // [Brightcove]
-  {"hash":"c095755780478f7e","prefixes":{"":{"product":639}}}, // [Experian]
-  {"hash":"18562cb1149fda1e","prefixes":{"*":{"product":640,"type":1}}}, // [Disqus]
-  {"hash":"37b749b8858eb61b","prefixes":{"*":{"product":641,"type":0}}}, // [Namecheap.com]
-  {"hash":"3d59be0f5f7101a0","prefixes":{"":{"product":642,"type":1}}}, // [Polldaddy]
-  {"hash":"510cff549d2cb397","prefixes":{"":{"product":643,"type":1}}}, // [Outbrain Inc.]
-  {"hash":"e23ebc9959ce4873","prefixes":{"":{"product":643,"type":1}}}, // [Outbrain Inc.]
-  {"hash":"623fd0210b11d4fb","prefixes":{"":{"product":644,"type":0}}}, // [Lijit Networks, Inc.]
-  {"hash":"686b7accbfa398fa","prefixes":{"":{"product":644,"type":0}}}, // [Lijit Networks, Inc.]
-  {"hash":"85c44f0602598dd8","prefixes":{"":{"product":644,"type":0}}}, // [Lijit Networks, Inc.]
-  {"hash":"a107b1fdcffae5b9","prefixes":{"*":{"product":479,"type":0}}}, // [NetDNA, LLC]
-  {"hash":"7f37823a3f5c76b3","prefixes":{"*":{"product":645,"type":0}}}, // [PubMatic]
-  {"hash":"6d306315a1fecfda","prefixes":{"":{"product":646,"type":0}}}, // [Say Media Inc.]
-  {"hash":"c2568516b08f0d3d","prefixes":{"":{"product":646,"type":0}}}, // [Say Media Inc.]
-  {"hash":"308d3a8d1ca52ff3","prefixes":{"":{"product":646,"type":0}}}, // [Say Media Inc.]
-  {"hash":"59e488c5f151e7c3","prefixes":{"":{"product":646,"type":0}}}, // [Say Media Inc.]
-  {"hash":"7efe6908db5a1d44","prefixes":{"":{"product":647,"type":0}}}, // [Rubicon Project Turing, Inc. (SSP)]
-  {"hash":"c6ee8faaa7d6734c","prefixes":{"":{"product":648,"type":0}}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"d93c07cc68e53d91","prefixes":{"":{"product":648,"type":0}}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"86ae2b216def9790","prefixes":{"":{"product":648,"type":0}}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"1267f5857549a6ab","prefixes":{"":{"product":648,"type":0}}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"367db80c0776f6d8","prefixes":{"":{"product":648,"type":0}}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"c4c762a7e666da1c","prefixes":{"":{"product":648,"type":0}}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"bb66261f843823d5","prefixes":{"":{"product":649,"type":1}}}, // [Wordpress Stats]
-  {"hash":"a0f3bb8dcd67010e","prefixes":{"":{"product":649,"type":1}}}, // [Wordpress Stats]
-  {"hash":"4a423f1da960eda6","prefixes":{"*":{"product":650,"type":1}}}, // [Twitter]
-  {"hash":"13c55ef8102cbdbb","prefixes":{"":{"product":651,"type":0}}}, // [Yandex LLC]
-  {"hash":"db546baba3acb079","prefixes":{"":{"product":651,"type":0}}}, // [Yandex LLC]
-  {"hash":"3dd0667dbad0af61","prefixes":{"":{"product":651,"type":0}}}, // [Yandex LLC]
-  {"hash":"78e224c91aabe6de","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"75acb8a5a60ef63d","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"6f7720a054c19a2b","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"dbd76c26579bf2b1","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"2cd7f311595e164e","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"b08380cf2fcb4415","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"59ac14277edec497","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"88893eeb26e546a0","prefixes":{"":{"product":652,"type":0}}}, // [Rutarget / Segmento]
-  {"hash":"da151dbe8b815dfb","prefixes":{"":{"product":653,"type":2}}}, // [Addoor LatinMarkets, SL]
-  {"hash":"b2a44f920e268749","prefixes":{"":{"product":654,"type":0}}}, // [Kate Spade]
-  {"hash":"96a8c3ab1740bf2f","prefixes":{"":{"product":96,"type":0}}}, // [Tacoda]
-  {"hash":"95e85e3cbd858779","prefixes":{"":{"product":655}}}, // [TARGUSinfo]
-  {"hash":"dbf2963c9bf26f55","prefixes":{"":{"product":656,"type":0}}}, // [Adblade]
-  {"hash":"8064758f6c80afed","prefixes":{"":{"product":656,"type":0}}}, // [Adblade]
-  {"hash":"b7aaa083e4151ca8","prefixes":{"":{"product":656,"type":0}}}, // [Adblade]
-  {"hash":"f4d5f13eb7d1ba2b","prefixes":{"":{"product":656,"type":0}}}, // [Adblade]
-  {"hash":"eca68f2e6cd8a07e","prefixes":{"":{"product":657,"type":0}}}, // [Adiant]
-  {"hash":"30f4c3f682592add","prefixes":{"":{"product":658,"type":1}}}, // [AddToAny]
-  {"hash":"39b76d24e28075d4","prefixes":{"*":{"product":659}}}, // [Bizo Inc]
-  {"hash":"dabe4d73219c06e0","prefixes":{"":{"product":660,"type":1}}}, // [Google Analytics]
-  {"hash":"f8c6758a214299be","prefixes":{"":{"product":661,"type":1}}}, // [Gravatar]
-  {"hash":"0a130612d187bc06","prefixes":{"":{"product":661,"type":1}}}, // [Gravatar]
-  {"hash":"6802f0145385df51","prefixes":{"":{"product":662,"type":0}}}, // [MediaGlu]
-  {"hash":"ccbeaf028d3c721b","prefixes":{"":{"product":662,"type":0}}}, // [MediaGlu]
-  {"hash":"1d7daeed381c33aa","prefixes":{"":{"product":662,"type":0}}}, // [MediaGlu]
-  {"hash":"038b4d8cab2d2a58","prefixes":{"":{"product":662,"type":0}}}, // [MediaGlu]
-  {"hash":"bd4919274e19987e","prefixes":{"":{"product":662,"type":0}}}, // [MediaGlu]
-  {"hash":"dcdf95e5abf7c100","prefixes":{"":{"product":663,"type":0}}}, // [Tapstream Network Inc.]
-  {"hash":"1f751fd80b11ad3c","prefixes":{"":{"product":664,"type":0}}}, // [HUNT Mobile Ads]
-  {"hash":"de1c8591006ce969","prefixes":{"":{"product":665,"type":0}}}, // [Apsalar, Inc.]
-  {"hash":"9fd29903977b5176","prefixes":{"":{"product":665,"type":0}}}, // [Apsalar, Inc.]
-  {"hash":"c3930fc2f4cd70df","prefixes":{"*":{"product":666,"type":0}}}, // [Videology DSP]
-  {"hash":"8924b56175f6f114","prefixes":{"":{"product":667,"type":0}}}, // [Videostrip]
-  {"hash":"f4b2d76af9987952","prefixes":{"":{"product":668,"type":0}}}, // [Affinity – Hostway Corporation]
-  {"hash":"b11ec5ee5b26491a","prefixes":{"*":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"a0b6774e583d1787","prefixes":{"":{"product":669,"type":0}}}, // [Taptica]
-  {"hash":"e6ad999a7fc77500","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"4056609d04bfec9c","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"d1f59501d08f217a","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"bd467d941e65225d","prefixes":{"":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"0de83b2d387d2a84","prefixes":{"*":{"product":238,"type":0}}}, // [Scene Stealer Ltd.]
-  {"hash":"227a1699196d5009","prefixes":{"":{"product":670,"type":1}}}, // [LiveRamp, Inc.]
-  {"hash":"2077744d64232ddc","prefixes":{"":{"product":670,"type":1}}}, // [LiveRamp, Inc.]
-  {"hash":"5ff42e5327d8c926","prefixes":{"":{"product":671,"type":0}}}, // [Plista GmbH]
-  {"hash":"1d36941de87ee056","prefixes":{"":{"product":671,"type":0}}}, // [Plista GmbH]
-  {"hash":"0534ec41ce34cced","prefixes":{"":{"product":671,"type":0}}}, // [Plista GmbH]
-  {"hash":"c5ca32bf780ff41c","prefixes":{"":{"product":672,"type":1}}}, // [Netquest Ad Tracking]
-  {"hash":"fcb4d508b7c17d00","prefixes":{"":{"product":673,"type":0}}}, // [Mediasmart Mobile S.L.]
-  {"hash":"32de5cdddc7878d9","prefixes":{"":{"product":673,"type":0}}}, // [Mediasmart Mobile S.L.]
-  {"hash":"832d7e03cfa50775","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"5d0747bdde7700a5","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"6cda89e3ca547147","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"6825c9c2052b6d49","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"dac91e433fa392a8","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"5112708cd650c1bf","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"8c56edbaad9d7666","prefixes":{"":{"product":674,"type":0}}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"e3f867313a3a22ff","prefixes":{"*":{"product":675,"type":0}}}, // [Mixmarket Affiliate Network]
-  {"hash":"337d4f2254b699bd","prefixes":{"":{"product":675,"type":0}}}, // [Mixmarket Affiliate Network]
-  {"hash":"7dd6cb3709637812","prefixes":{"*":{"product":676,"type":0}}}, // [Turbobytes]
-  {"hash":"b42ea914a5e25208","prefixes":{"":{"product":677,"type":0}}}, // [Voodoo Video AG]
-  {"hash":"a7ab005368d54a08","prefixes":{"*":{"product":678,"type":2}}}, // [Google CDN]
-  {"hash":"273fe37ef5880422","prefixes":{"lh":{"product":678,"type":2},"geo":{"product":678,"type":2}}}, // [Google CDN] [Google CDN]
-  {"hash":"cf71755ff09e2183","prefixes":{"":{"product":678,"type":2}}}, // [Google CDN]
-  {"hash":"b004042c33f57ce5","prefixes":{"":{"product":678,"type":2}}}, // [Google CDN]
-  {"hash":"3a32bf25eec1a95b","prefixes":{"*":{"product":679,"type":1}}}, // [Full Performance]
-  {"hash":"783c5679a80d5c10","prefixes":{"":{"product":680}}}, // [eXelate Inc.]
-  {"hash":"40f709f76b1af3f1","prefixes":{"":{"product":680}}}, // [eXelate Inc.]
-  {"hash":"a97762efe739bb85","prefixes":{"*":{"product":681,"type":0}}}, // [Oreck Canada]
-  {"hash":"f3460c4c9a5112cc","prefixes":{"":{"product":682,"type":0}}}, // [Beijing WuShuang Technology Ltd. (AGrant)]
-  {"hash":"f132b41fc3fed2c5","prefixes":{"":{"product":683,"type":2}}}, // [Matomy Media]
-  {"hash":"930103c79d1886c9","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"befa931c2b772e6d","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"e1a46a5a294589c8","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"7aaf1724444529c4","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"a8e6cfd540b8a74b","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"4dd30b722c120fe4","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"5785365f3a4da9e4","prefixes":{"":{"product":684,"type":0}}}, // [Mail.Ru Group]
-  {"hash":"b4cbadcc4ab58981","prefixes":{"":{"product":685,"type":0}}}, // [LSi - Lionsoft Studios, spol. s r.o.]
-  {"hash":"a41a0099a363da99","prefixes":{"":{"product":686,"type":0}}}, // [Adelphic Inc.]
-  {"hash":"9a9d3ceef9c489c7","prefixes":{"":{"product":686,"type":0}}}, // [Adelphic Inc.]
-  {"hash":"8c652e1d454ab3a2","prefixes":{"":{"product":686,"type":0}}}, // [Adelphic Inc.]
-  {"hash":"36e0703b50fb3eed","prefixes":{"":{"product":686,"type":0}}}, // [Adelphic Inc.]
-  {"hash":"a437c97b4d64cafd","prefixes":{"":{"product":687,"type":0}}}, // [Lincoln Technical Institute, Inc.]
-  {"hash":"f69a68a2d09d0720","prefixes":{"":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"26dfb2b8bad92f4f","prefixes":{"":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"dc67b62ecf5a9b08","prefixes":{"":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"23b6f2b40a209645","prefixes":{"":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"40536f7cc3f3bcdb","prefixes":{"":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"7eab1c802c1cb708","prefixes":{"*":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"8381e43653c976d7","prefixes":{"":{"product":688,"type":0}}}, // [Smartstream.tv]
-  {"hash":"010611867004fb28","prefixes":{"":{"product":689,"type":0}}}, // [Reklamport]
-  {"hash":"8c138e749437f931","prefixes":{"":{"product":689,"type":0}}}, // [Reklamport]
-  {"hash":"735ef6cfbe0d0549","prefixes":{"":{"product":690,"type":0}}}, // [Fattext LLC (DBA Moolah Media)]
-  {"hash":"7a17aa6bfdfb3de1","prefixes":{"":{"product":690,"type":0}}}, // [Fattext LLC (DBA Moolah Media)]
-  {"hash":"3c593814e40d8a9e","prefixes":{"":{"product":691,"type":0}}}, // [MoGo Marketing & Media Inc.]
-  {"hash":"0f36027c1644631a","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"ec8b441e84a18442","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"b923ca8213dfa24a","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"fe0b93fc6d0ad89a","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"b7164c05e2fb0d2f","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"6e085b0ec37b404f","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"d282ecf2666110dd","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"131054b9a54841da","prefixes":{"":{"product":692,"type":1}}}, // [SA Media, llc]
-  {"hash":"556351c03849a4c1","prefixes":{"":{"product":692,"type":1}}}, // [SA Media, llc]
-  {"hash":"bebf7033727205d4","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"e77b9add119d1d72","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"fbcb122264bcdbda","prefixes":{"":{"product":692,"type":0}}}, // [SA Media, llc]
-  {"hash":"10f64b8265e0b1be","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"cc468e0676f36482","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"a445930c60af8d98","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"63e594feafaae08b","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"045d86072bc5dc10","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"ea9d0ea08d06528d","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"94bc93c21ca5d014","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"bcfa082cf700866c","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"17f352a8e88349c9","prefixes":{"":{"product":693,"type":0}}}, // [Barons Media LLC]
-  {"hash":"8b18a83b14ef8906","prefixes":{"":{"product":694,"type":0}}}, // [apprupt GmbH]
-  {"hash":"46ba596945892a31","prefixes":{"":{"product":694,"type":0}}}, // [apprupt GmbH]
-  {"hash":"b0780943092b032a","prefixes":{"":{"product":694,"type":0}}}, // [apprupt GmbH]
-  {"hash":"7d76822bfe9ffcd9","prefixes":{"":{"product":694,"type":0}}}, // [apprupt GmbH]
-  {"hash":"87582b95561cf002","prefixes":{"":{"product":694,"type":0}}}, // [apprupt GmbH]
-  {"hash":"eb0a0cd03ec7f57b","prefixes":{"":{"product":695,"type":0}}}, // [PropellerADs media Ltd]
-  {"hash":"73009a8d32988e92","prefixes":{"*":{"product":696,"type":0}}}, // [CJ Affiliate by Conversant]
-  {"hash":"698b1ec9df8d6759","prefixes":{"*":{"product":696,"type":0}}}, // [CJ Affiliate by Conversant]
-  {"hash":"00e17f99243707e9","prefixes":{"":{"product":697,"type":0}}}, // [Millennial Media Inc]
-  {"hash":"62ddc5a87d328e5a","prefixes":{"":{"product":697,"type":0}}}, // [Millennial Media Inc]
-  {"hash":"0e02d11afea79a5e","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"56b1e984216b464b","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"815a3c2c1ed6f999","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"28175ac65441fbce","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"fe775b2f045dcced","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"d47b0a700d84bfba","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"1c34827419405aee","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"7e99ada6b2533f54","prefixes":{"":{"product":698,"type":0}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"2c5ac4af628363a6","prefixes":{"*":{"product":699,"type":0}}}, // [Manage.com Group, Inc.]
-  {"hash":"1b728798f387160d","prefixes":{"":{"product":700,"type":0}}}, // [MASSMOTIONMEDIA SARL]
-  {"hash":"fb80c91c77673741","prefixes":{"":{"product":701,"type":0}}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"6ff7dff7c1404e1b","prefixes":{"":{"product":701,"type":0}}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"bd6c259e3bb98101","prefixes":{"":{"product":701,"type":0}}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"0dcb02764319e823","prefixes":{"":{"product":701,"type":0}}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"258ec0f081f1c767","prefixes":{"":{"product":701,"type":0}}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"518594f7ef9754dc","prefixes":{"*":{"product":702,"type":1}}}, // [Media Intelligence Platform (Aggregate Knowledge)]
-  {"hash":"223b1b79a6de9f04","prefixes":{"*":{"product":702,"type":1}}}, // [Media Intelligence Platform (Aggregate Knowledge)]
-  {"hash":"848f45768ee0ad4e","prefixes":{"":{"product":703,"type":0}}}, // [S4M]
-  {"hash":"77b7e5f4ec17a6e5","prefixes":{"":{"product":703,"type":0}}}, // [S4M]
-  {"hash":"f965c1f8d2cce837","prefixes":{"":{"product":703,"type":0}}}, // [S4M]
-  {"hash":"3e327352cea146b3","prefixes":{"":{"product":703,"type":0}}}, // [S4M]
-  {"hash":"0658ca5e4baec224","prefixes":{"":{"product":703,"type":0}}}, // [S4M]
-  {"hash":"f2e7a2604319636b","prefixes":{"":{"product":703,"type":0}}}, // [S4M]
-  {"hash":"c825977950596abc","prefixes":{"":{"product":703}}}, // [S4M]
-  {"hash":"b55fc4c23b864e56","prefixes":{"":{"product":703}}}, // [S4M]
-  {"hash":"3eddbbcdb5a13a1b","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"f133f36dd9e9688d","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"06ead346af8ecc6d","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"16a442ad35246027","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"778068a948335ee6","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"2bb088766e0a77ce","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"f54b41faf3e29ddb","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"3d71c7985374fc62","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"de336679348d46a5","prefixes":{"":{"product":704,"type":0}}}, // [Sobmag LTD]
-  {"hash":"6818fc4cb694f0d4","prefixes":{"*":{"product":705,"type":2}}}, // [Netbooster]
-  {"hash":"5682fbd14ad230ca","prefixes":{"":{"product":706,"type":2}}}, // [Musikhaus Thomann e.K.]
-  {"hash":"abbb14ff2ab0311d","prefixes":{"":{"product":706,"type":2}}}, // [Musikhaus Thomann e.K.]
-  {"hash":"578726cfc508157e","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"a141aaa30beb2f05","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"9161fa28951da89a","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"2e52f74b27e9eb2f","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"0ecdef2f55913790","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"409546c7e7a9ce63","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"3dceafc40a01cd8c","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"e748a008fcd2910c","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"499e3537aead5990","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"aad99655e792b7af","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"df381181135b37f3","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"49fe77e073f907d5","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"fe445db4579e7177","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"f7038d35f22c32db","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"184913b8eec78f63","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"4db6f08af3d6cf66","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"0a71646e475ff9c1","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"7847dd8c5608a507","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"cde33b0511f42c7c","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"6a5ae5d2380647dc","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"0821cc1422e91328","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"0e157baa999502bc","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"cb93fe6df3fe4097","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"657c19e08d899173","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"e411fd988f243d89","prefixes":{"":{"product":707,"type":0}}}, // [Trovit]
-  {"hash":"1ea512003540106b","prefixes":{"":{"product":707,"type":0}}}, // [Trovit]
-  {"hash":"48255f09ec2021d3","prefixes":{"":{"product":707,"type":0}}}, // [Trovit]
-  {"hash":"7b5b7cfa3d62a886","prefixes":{"":{"product":707,"type":0}}}, // [Trovit]
-  {"hash":"1235b8279a106276","prefixes":{"":{"product":708,"type":1}}}, // [O2online]
-  {"hash":"cf76706eea2f0be6","prefixes":{"":{"product":709,"type":0}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"766b747f8dec4417","prefixes":{"":{"product":710,"type":0}}}, // [Meteora]
-  {"hash":"270677f86b7f115b","prefixes":{"":{"product":710,"type":0}}}, // [Meteora]
-  {"hash":"0a500f94a8a562f0","prefixes":{"":{"product":711,"type":0}}}, // [Madison Logic, Inc.]
-  {"hash":"764d3a17a9512438","prefixes":{"":{"product":711,"type":0}}}, // [Madison Logic, Inc.]
-  {"hash":"38c3aac1b79f0478","prefixes":{"":{"product":711,"type":0}}}, // [Madison Logic, Inc.]
-  {"hash":"babcc401d384553f","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"2ddae58a55ab72ef","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"db564708d2871d3a","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"a4199cfcbe70d7f5","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"e6f5851275bc1fb3","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"16e6d7e84ad7fa3a","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"58ae73a3bb4327d7","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"366a0ad35670aef5","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"5b30682b9dfa7060","prefixes":{"":{"product":712,"type":0}}}, // [万相DSP(IZP Technologies)]
-  {"hash":"67128a22cdd1a7cd","prefixes":{"":{"product":0,"type":0}}}, // [AppNexus Open AdStream]
-  {"hash":"db56992e1a1a3f90","prefixes":{"":{"product":713,"type":0}}}, // [righTarget]
-  {"hash":"479ab75d77a40d72","prefixes":{"":{"product":713,"type":0}}}, // [righTarget]
-  {"hash":"17bcd2af46fb1fe6","prefixes":{"":{"product":713,"type":0}}}, // [righTarget]
-  {"hash":"45681f09a76fe33e","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"612f6aab80bc21df","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"ab7e80409519ca9d","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"a3ae7b8a84f28040","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"b25f21b316565014","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"cc9eeba2126e4261","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"9d4819b235a5272b","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"78bb032f283d8f48","prefixes":{"":{"product":715,"type":0}}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
-  {"hash":"de11a5b150526c21","prefixes":{"":{"product":715,"type":0}}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
-  {"hash":"bbd9e4a668c4e348","prefixes":{"":{"product":715,"type":0}}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
-  {"hash":"c38a1d9eab08d787","prefixes":{"*":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"5b2c8d90176bd14e","prefixes":{"":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"62980dc2fa42e1e0","prefixes":{"*":{"product":714,"type":0}}}, // [e.QQ.com]
-  {"hash":"9b37bab01bf28d39","prefixes":{"*":{"product":716,"type":0}}}, // [Bannercockpit]
-  {"hash":"01ec60ee4671b195","prefixes":{"":{"product":717,"type":0}}}, // [Outrigger Media Inc.]
-  {"hash":"4be86c0a73547960","prefixes":{"":{"product":717,"type":0}}}, // [Outrigger Media Inc.]
-  {"hash":"e3ab574adac96838","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"91bb53a0f22994f8","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"fd65eb28a70ed09a","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"9f41f821ddcb5092","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"ee70168f83fb2cce","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"c15fc4a18b25e6d3","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"f5f66dfaf3d2d2a3","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"e6e8716836c8a21d","prefixes":{"":{"product":104,"type":0}}}, // [Rockabox Media Ltd]
-  {"hash":"da37db68457e2782","prefixes":{"*":{"product":718,"type":0}}}, // [shopLocal]
-  {"hash":"ab8c1ee046adfbb1","prefixes":{"*":{"product":719,"type":1}}}, // [Impact Radius]
-  {"hash":"0e8c1ff7462c1084","prefixes":{"*":{"product":719,"type":1}}}, // [Impact Radius]
-  {"hash":"8f228d8317e4718d","prefixes":{"":{"product":719,"type":1}}}, // [Impact Radius]
-  {"hash":"29d7e31af4b1be0b","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"efeab3df1fe3849a","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"8f2fea31a1c79b34","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"9cda8eeaf1e150bf","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"714091c1b8581de0","prefixes":{"":{"product":721,"type":0}}}, // [Unister Media GmbH]
-  {"hash":"c7002b2b9e4b5370","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"1802591342537dae","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"787cbd14bb54b647","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"084ef5666af6a26c","prefixes":{"":{"product":720,"type":0}}}, // [Unister AdServer]
-  {"hash":"df72b5eb4be388d1","prefixes":{"":{"product":722,"type":0}}}, // [TLV Media Online Ltd]
-  {"hash":"64ffcabaf6ec2bcf","prefixes":{"":{"product":723,"type":0}}}, // [d3media AG]
-  {"hash":"a6d58332a182c9f4","prefixes":{"":{"product":723,"type":0}}}, // [d3media AG]
-  {"hash":"0bbd108959983b32","prefixes":{"":{"product":724,"type":0}}}, // [Innovative Metrics]
-  {"hash":"80eab7dfc5e4cc5f","prefixes":{"*":{"product":725,"type":0}}}, // [AthenaHealth]
-  {"hash":"131ce36599fa0d6c","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"9181181a015040bc","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"fca830abc4829657","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"e78333a733c1b05a","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"3f82423bd28a526a","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"f2da501e4086afa3","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"719080d33b283abc","prefixes":{"":{"product":726,"type":0}}}, // [TAPVALUE SAS]
-  {"hash":"3502e0d544b9b739","prefixes":{"":{"product":727}}}, // [Meteor Worldwide LLC.]
-  {"hash":"a6227ad6f805c298","prefixes":{"":{"product":727}}}, // [Meteor Worldwide LLC.]
-  {"hash":"0933cf49bb328213","prefixes":{"*":{"product":187,"type":0}}}, // [Relay42 Technology B.V.]
-  {"hash":"bea1d6b2a32d3927","prefixes":{"*":{"product":187,"type":0}}}, // [Relay42 Technology B.V.]
-  {"hash":"8d1313bfd522fcf6","prefixes":{"":{"product":728,"type":0}}}, // [Audience2Media Limited]
-  {"hash":"ec4f449051680a17","prefixes":{"":{"product":728,"type":0}}}, // [Audience2Media Limited]
-  {"hash":"9badeeb4c9cff3b3","prefixes":{"":{"product":729,"type":0}}}, // [HRB Digital LLC.]
-  {"hash":"e0e362bb66a6c5dd","prefixes":{"*":{"product":730,"type":0}}}, // [!NOOB]
-  {"hash":"e1e1866cde6f23c7","prefixes":{"":{"product":161,"type":0}}}, // [Tagtoo Tech Limited]
-  {"hash":"60a41acd40c494b4","prefixes":{"":{"product":161,"type":0}}}, // [Tagtoo Tech Limited]
-  {"hash":"4dbc45b703241615","prefixes":{"":{"product":161,"type":0}}}, // [Tagtoo Tech Limited]
-  {"hash":"d11722ff46ba063b","prefixes":{"":{"product":161,"type":0}}}, // [Tagtoo Tech Limited]
-  {"hash":"706cd1e56e4ca9f0","prefixes":{"":{"product":161,"type":0}}}, // [Tagtoo Tech Limited]
-  {"hash":"eabe2f56a564ea71","prefixes":{"":{"product":124,"type":0}}}, // [Mocean mobile, Inc.]
-  {"hash":"9ab3f80172f06a67","prefixes":{"":{"product":124,"type":0}}}, // [Mocean mobile, Inc.]
-  {"hash":"19c44c882811c0bd","prefixes":{"":{"product":731,"type":1}}}, // [OSV online]
-  {"hash":"1f888bdc491d19c5","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"3259bacc0853f3ce","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"4a7fe8ed74a69bb1","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"72680bf564258b75","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"d25a0b5dd4617071","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"4e53e370f5c0d9c8","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"2585ec8519ec2a03","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"9ebfdd26621d46c7","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"083fd3b939cbd105","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"3fd28ace41da6736","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"3f5d8ed1881e0849","prefixes":{"":{"product":732,"type":0}}}, // [Addroid™]
-  {"hash":"4f0f13d0fae2b262","prefixes":{"":{"product":733,"type":0}}}, // [AdAccess]
-  {"hash":"5a40dbdf15bc0d0c","prefixes":{"":{"product":733,"type":0}}}, // [AdAccess]
-  {"hash":"0eff5ff163f074f0","prefixes":{"":{"product":733,"type":0}}}, // [AdAccess]
-  {"hash":"f5ce32de4ea8770e","prefixes":{"":{"product":733,"type":0}}}, // [AdAccess]
-  {"hash":"8a367cea803ead3b","prefixes":{"":{"product":733,"type":0}}}, // [AdAccess]
-  {"hash":"960b38f18a31bf7f","prefixes":{"":{"product":733,"type":0}}}, // [AdAccess]
-  {"hash":"45b03c5f8881301a","prefixes":{"":{"product":734,"type":0}}}, // [Yabuka Media, Inc.]
-  {"hash":"c2875e9f5741c896","prefixes":{"":{"product":734,"type":0}}}, // [Yabuka Media, Inc.]
-  {"hash":"46751092d6f82d66","prefixes":{"":{"product":734,"type":0}}}, // [Yabuka Media, Inc.]
-  {"hash":"5033b8e8796bc944","prefixes":{"":{"product":735,"type":0}}}, // [Bridgewell Incorporated]
-  {"hash":"fcbb4f6f5d116bcf","prefixes":{"":{"product":735,"type":0}}}, // [Bridgewell Incorporated]
-  {"hash":"6d68bbc023aff7a8","prefixes":{"":{"product":735,"type":0}}}, // [Bridgewell Incorporated]
-  {"hash":"98a17e63899d6f0f","prefixes":{"":{"product":735,"type":0}}}, // [Bridgewell Incorporated]
-  {"hash":"1cae38f50bbcbe1a","prefixes":{"":{"product":735,"type":0}}}, // [Bridgewell Incorporated]
-  {"hash":"df13ce542b6c0e84","prefixes":{"":{"product":736,"type":0}}}, // [Bidtheatre AB]
-  {"hash":"f9e2fc82f27f7b60","prefixes":{"":{"product":736,"type":0}}}, // [Bidtheatre AB]
-  {"hash":"0d324dc8c79d8b3c","prefixes":{"":{"product":736,"type":0}}}, // [Bidtheatre AB]
-  {"hash":"1d9569d0ee02dcee","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"73bd54b1be5e9df1","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"dae6130e1d796d90","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"53335dc721cbee0b","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"ae279eee4c5b4941","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"684276719f3b5728","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"b7376659acddae09","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"aa7f623da51e1603","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"6785583c4297f7c5","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"20138e51a97d179b","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"cc3a77dca011bc78","prefixes":{"":{"product":737,"type":0}}}, // [AdMoment]
-  {"hash":"6d441f7565cc5de4","prefixes":{"":{"product":738,"type":1}}}, // [UDG München GmbH]
-  {"hash":"f8c1c6199f46e722","prefixes":{"":{"product":738,"type":1}}}, // [UDG München GmbH]
-  {"hash":"151a96d84e31a957","prefixes":{"":{"product":738,"type":1}}}, // [UDG München GmbH]
-  {"hash":"5d34fdb93148d891","prefixes":{"":{"product":739,"type":1}}}, // [Pixalate, Inc.]
-  {"hash":"6855407f17ce6aec","prefixes":{"":{"product":739,"type":1}}}, // [Pixalate, Inc.]
-  {"hash":"b9f9a074ce5d4d07","prefixes":{"":{"product":739,"type":1}}}, // [Pixalate, Inc.]
-  {"hash":"41ddcdd6ba9e42fe","prefixes":{"":{"product":739,"type":1}}}, // [Pixalate, Inc.]
-  {"hash":"c72923bea1fa64ce","prefixes":{"":{"product":740,"type":0}}}, // [InMobi Inc.]
-  {"hash":"9085e035c617887b","prefixes":{"":{"product":740,"type":0}}}, // [InMobi Inc.]
-  {"hash":"0f7037ee4e476493","prefixes":{"":{"product":740,"type":0}}}, // [InMobi Inc.]
-  {"hash":"bdfbe6247c640d80","prefixes":{"":{"product":741,"type":0}}}, // [Crisp Media Inc.]
-  {"hash":"2cb723bdc82533b2","prefixes":{"":{"product":741,"type":0}}}, // [Crisp Media Inc.]
-  {"hash":"be72bf3ef3e3bd14","prefixes":{"":{"product":741,"type":0}}}, // [Crisp Media Inc.]
-  {"hash":"3af5f91fedb0e598","prefixes":{"":{"product":741,"type":0}}}, // [Crisp Media Inc.]
-  {"hash":"9feb6dbe57a5ab9b","prefixes":{"":{"product":741,"type":0}}}, // [Crisp Media Inc.]
-  {"hash":"1953012d699dc24e","prefixes":{"":{"product":742}}}, // [Choozle, Inc.]
-  {"hash":"560479fb0478e76e","prefixes":{"":{"product":742}}}, // [Choozle, Inc.]
-  {"hash":"fb3c191358de9e97","prefixes":{"*":{"product":743,"type":1}}}, // [Tapad]
-  {"hash":"faa63745af097785","prefixes":{"*":{"product":744,"type":1}}}, // [ReachLocal, Inc]
-  {"hash":"c6a0024a8fdbd244","prefixes":{"":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"1b09e9588e619f63","prefixes":{"":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"c923ecff86d0026f","prefixes":{"":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"0b38e9ab66f134b5","prefixes":{"":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"b07b0a6a32b39c67","prefixes":{"rtb-":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"a66019bd1d8d6523","prefixes":{"":{"product":746,"type":0}}}, // [OpenX]
-  {"hash":"3461a8e14dfa7234","prefixes":{"*":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"50f406d696ea09e2","prefixes":{"*":{"product":745,"type":0}}}, // [OpenX Ad Exchange]
-  {"hash":"28f15a404c22c5ae","prefixes":{"":{"product":747,"type":0}}}, // [Placester, Inc.]
-  {"hash":"2eabf2a9cc47f6db","prefixes":{"":{"product":747,"type":0}}}, // [Placester, Inc.]
-  {"hash":"04e56c0e39ffb379","prefixes":{"":{"product":748,"type":0}}}, // [Spiceworks, Inc]
-  {"hash":"a342cde98acae2a3","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"816943ad229d59bd","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"9aeccecf18437372","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"e24006f3d8614cdf","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"2678adb8d16c1bd0","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"690b9d06ee7b618c","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"ba64173aac6883fa","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"3f334c96b9489b6f","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"4acb6ede5efaa0ce","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"f848368a90033112","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"fc58526ac2c34887","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"bcec64a939aa6248","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"2237ba07a36c2440","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"9b1bd3e45cc8d37b","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"f9447e97a352a2e8","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"4aa3c10d0fa51575","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"edb1b5b0a2ecd2b9","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"3eee53fed713d5b2","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"5562c787acd84d8d","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"27d45cd108fe99b4","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"06da026d99fd30c4","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"43e91c0e2d266107","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"2b8ee71c143b611a","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"31773affdbc2f93f","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"24f5edbbeab30fc6","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"b1275f1680c5e050","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"1f0e98fd24844df9","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"207973ef90437496","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"5e573612b3181547","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"5237a5b231dbf245","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"b4872bd493703ef0","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"7268f40680faccfd","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"f18cc00e2cfb170d","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"2be692602def45f7","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"5d15e875488cccd1","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"7da3afc36d1c6b59","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"e0767b1a03a64ce6","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"202d0d2b1168aeb8","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"5e070df0dbe151e6","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"e4337ec6681cbc61","prefixes":{"":{"product":749,"type":0}}}, // [WapStart]
-  {"hash":"944f2609259bac7c","prefixes":{"":{"product":750,"type":0}}}, // [Ambercrow (Epayments)]
-  {"hash":"8bcd6f943c02d066","prefixes":{"":{"product":750,"type":0}}}, // [Ambercrow (Epayments)]
-  {"hash":"f0529ee08a090045","prefixes":{"":{"product":750,"type":0}}}, // [Ambercrow (Epayments)]
-  {"hash":"f44423b0de62f78e","prefixes":{"":{"product":750,"type":0}}}, // [Ambercrow (Epayments)]
-  {"hash":"00fb6871b70e1fd9","prefixes":{"":{"product":750,"type":0}}}, // [Ambercrow (Epayments)]
-  {"hash":"588e459942f9f953","prefixes":{"":{"product":751,"type":0}}}, // [Audiencevalue Pte Ltd]
-  {"hash":"2b94a7bb996b3a9c","prefixes":{"":{"product":751,"type":0}}}, // [Audiencevalue Pte Ltd]
-  {"hash":"5796b5e246266e0c","prefixes":{"":{"product":752,"type":0}}}, // [UNITED. Inc.]
-  {"hash":"aa1ee475645d94b7","prefixes":{"":{"product":752,"type":0}}}, // [UNITED. Inc.]
-  {"hash":"716f227b7327feba","prefixes":{"":{"product":752,"type":0}}}, // [UNITED. Inc.]
-  {"hash":"44c3a88f2dcdee6f","prefixes":{"":{"product":753}}}, // [United Bypass Tech]
-  {"hash":"0f010d866f5763fa","prefixes":{"":{"product":754,"type":0}}}, // [SAS Naoplay]
-  {"hash":"6a978d7b8efc594d","prefixes":{"":{"product":754,"type":0}}}, // [SAS Naoplay]
-  {"hash":"d3e10ee4fc900d26","prefixes":{"":{"product":754,"type":0}}}, // [SAS Naoplay]
-  {"hash":"e83a4038aff02b6e","prefixes":{"":{"product":754,"type":0}}}, // [SAS Naoplay]
-  {"hash":"acce217e5e09149a","prefixes":{"":{"product":754,"type":0}}}, // [SAS Naoplay]
-  {"hash":"3a93fbc111c8603f","prefixes":{"":{"product":755,"type":0}}}, // [CuriosityStream]
-  {"hash":"065426aaa5552ffe","prefixes":{"":{"product":756,"type":0}}}, // [Alliance Internet (ntree)]
-  {"hash":"9a843715746291f3","prefixes":{"":{"product":756,"type":0}}}, // [Alliance Internet (ntree)]
-  {"hash":"2d4ed5b7f85f950a","prefixes":{"n":{"product":756,"type":0}}}, // [Alliance Internet (ntree)]
-  {"hash":"86f628e66b67be4d","prefixes":{"":{"product":757,"type":0}}}, // [Centraltag]
-  {"hash":"419e8a03b3f16a8c","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"b9ee79ef4e8c15f5","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"46e3b67ae4549155","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"3064ccb85e72d2df","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"1b58e47cefd5e220","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"93b3f973b09c5513","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"607d4f0311eec7af","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"311502ef7317df7d","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"cdf3897e12242607","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"a5a0d71d2f6b631c","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"10f5415b8d24f2b0","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"c126382fcba55688","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"a92d9d96a9338816","prefixes":{"":{"product":758,"type":0}}}, // [eTargeting]
-  {"hash":"74549e43319467f8","prefixes":{"":{"product":759,"type":1}}}, // [Walmart Inc]
-  {"hash":"3d8d433ae123d216","prefixes":{"":{"product":759,"type":1}}}, // [Walmart Inc]
-  {"hash":"6baa1cd3500dc43f","prefixes":{"":{"product":760,"type":0}}}, // [Walmart.com]
-  {"hash":"12bc009e74ca3655","prefixes":{"":{"product":759}}}, // [Walmart Inc]
-  {"hash":"abb8ec1b9995e7db","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"a489082dd8c6d1b0","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"b8eaffd4f3298628","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"fa888dd08124e8f6","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"d33163e42a34ac6b","prefixes":{"":{"product":762,"type":1}}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"26271fd98d79e29f","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"f958e80b82fbeb15","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"0efc1cccd29292d2","prefixes":{"*":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"ec1cfeb7c8ad8e74","prefixes":{"*":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"06ea295dea974069","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"166f6d9041d2cffe","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"d209952bca4546fc","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"8977e19e27e82a31","prefixes":{"":{"product":761,"type":0}}}, // [Extreme Reach, Inc.]
-  {"hash":"f276cc84c3030bf7","prefixes":{"":{"product":763,"type":1}}}, // [Netflix]
-  {"hash":"cf97c9d0a75da1fb","prefixes":{"":{"product":763,"type":1}}}, // [Netflix]
-  {"hash":"acf43321c04d641b","prefixes":{"":{"product":763,"type":1}}}, // [Netflix]
-  {"hash":"bb55681ae13b2fa8","prefixes":{"":{"product":763,"type":1}}}, // [Netflix]
-  {"hash":"2d5400efd94a66d0","prefixes":{"":{"product":763,"type":1}}}, // [Netflix]
-  {"hash":"c4a2daa282a0af48","prefixes":{"":{"product":763,"type":1}}}, // [Netflix]
-  {"hash":"670a8e12f579ee63","prefixes":{"":{"product":764,"type":0}}}, // [Netflix, Inc.]
-  {"hash":"15b7e69ddffa3a8c","prefixes":{"":{"product":764,"type":0}}}, // [Netflix, Inc.]
-  {"hash":"7b7add7c969d93fe","prefixes":{"*":{"product":765,"type":0}}}, // [Scarab Personalized Ads]
-  {"hash":"4e1907aa0eb0ff71","prefixes":{"":{"product":765,"type":0}}}, // [Scarab Personalized Ads]
-  {"hash":"a3315978597aa707","prefixes":{"":{"product":766,"type":0}}}, // [CrowdMob Inc.]
-  {"hash":"452715cede41650c","prefixes":{"":{"product":767,"type":0}}}, // [Gruvi Ltd.]
-  {"hash":"36ce2eb140f75f32","prefixes":{"":{"product":766,"type":0}}}, // [CrowdMob Inc.]
-  {"hash":"ae6b13daf4bc714d","prefixes":{"":{"product":105,"type":0}}}, // [PocketMath]
-  {"hash":"13696777dabedeae","prefixes":{"":{"product":768,"type":1}}}, // [Macromill, Inc.]
-  {"hash":"9971928c88e3fa4e","prefixes":{"*":{"product":769,"type":1}}}, // [Nielsen (Cross Platform Brand Effect [IAG/TVBE])]
-  {"hash":"65df6515d4615cea","prefixes":{"f":{"product":770,"type":0},"vast-":{"product":770,"type":0},"ivid-":{"product":770}}}, // [GetIntent] [GetIntent] [GetIntent]
-  {"hash":"b54db54df2c407f8","prefixes":{"":{"product":770,"type":0}}}, // [GetIntent]
-  {"hash":"2258062bb1ab01dd","prefixes":{"":{"product":770,"type":0}}}, // [GetIntent]
-  {"hash":"630338f7109ea305","prefixes":{"*":{"product":770,"type":0}}}, // [GetIntent]
-  {"hash":"b3c93c6142991123","prefixes":{"":{"product":770}}}, // [GetIntent]
-  {"hash":"6ef8d315575de4c7","prefixes":{"":{"product":770}}}, // [GetIntent]
-  {"hash":"b7769b25a2035147","prefixes":{"vid-":{"product":770}}}, // [GetIntent]
-  {"hash":"2e2859be7da1ee82","prefixes":{"":{"product":771,"type":0}}}, // [Belboon]
-  {"hash":"ff591094a6a13480","prefixes":{"*":{"product":772,"type":0}}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"3bd09c8fad6ac0cd","prefixes":{"*":{"product":772,"type":0}}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"41385cd812900dd3","prefixes":{"*":{"product":772,"type":0}}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"78bdf43617c9f3ed","prefixes":{"":{"product":773,"type":0}}}, // [Hindustan Times Mobile Solutions Limited]
-  {"hash":"f669a1035330e753","prefixes":{"*":{"product":772,"type":0}}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"74c5a373ee6172a1","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"3762c6694e48ada4","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"885e91388dd960b6","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"f6a553969be0331b","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"48d6fc29b318593f","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"1e571da94b4242ba","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"e6770fd6222ae990","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"20b17ee9acc1afb9","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"c483854c67d0c950","prefixes":{"":{"product":774,"type":0}}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"5214f14e27a71d7f","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"61c576ffa8275ef3","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"c6af9ddc14757f86","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"86e9128d66cc0207","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"c71d0bd2e6f83f82","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"97be67a3b0baedf9","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"9622fe3e417564fb","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"a63ebe94fca61ed9","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"bbc1dd12d3cdb0b4","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"962da7f5c63ff169","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"94bb51394747c625","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"3ff8867b3d239d21","prefixes":{"":{"product":775,"type":0}}}, // [GoldSpot Media]
-  {"hash":"a970a6e82a98c461","prefixes":{"":{"product":776,"type":0}}}, // [Zeeto Media]
-  {"hash":"4c975affcaea9100","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"dfd86d0838962249","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"91f2b2338b35b7b2","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"3bec5ca280ea1b83","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"3d88758bd6e0003a","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"5c4e7b396a2ff6d6","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"a95488bd107fec32","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"aa8e84bd80448410","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"63a0cca4218135c9","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"91a1733ac5874a1c","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"5c8abc657915fd35","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"917cc91081fe5b07","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"a53545381bdd0cbf","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"4bc186645ccbf442","prefixes":{"":{"product":777,"type":0}}}, // [DYNADMIC SAS]
-  {"hash":"3d6ddf04f9124237","prefixes":{"":{"product":778,"type":0}}}, // [Yoc Mobile Advertising GmbH]
-  {"hash":"ec5fe7560209f819","prefixes":{"":{"product":354,"type":0}}}, // [Quantcast Inc.]
-  {"hash":"5fe3e321ae6e4bf6","prefixes":{"":{"product":354,"type":0}}}, // [Quantcast Inc.]
-  {"hash":"8be056c242dd9d72","prefixes":{"":{"product":354}}}, // [Quantcast Inc.]
-  {"hash":"f8ee5abf7ea1abc7","prefixes":{"":{"product":779,"type":0}}}, // [Velti]
-  {"hash":"59f840ce07769698","prefixes":{"":{"product":779,"type":0}}}, // [Velti]
-  {"hash":"e013843f461a8d4b","prefixes":{"":{"product":779,"type":0}}}, // [Velti]
-  {"hash":"bfe3cf089cc18922","prefixes":{"":{"product":779,"type":0}}}, // [Velti]
-  {"hash":"9bd20c9549f20865","prefixes":{"":{"product":780,"type":0}}}, // [Lockon]
-  {"hash":"f24f331de69a707a","prefixes":{"":{"product":780,"type":0}}}, // [Lockon]
-  {"hash":"566f866251bd714e","prefixes":{"":{"product":780,"type":0}}}, // [Lockon]
-  {"hash":"4baa350d3cc68f76","prefixes":{"":{"product":781,"type":0}}}, // [Recruit Co., Ltd. Communications]
-  {"hash":"9bc564a146df07e7","prefixes":{"":{"product":781,"type":0}}}, // [Recruit Co., Ltd. Communications]
-  {"hash":"35c56cfd7e378fad","prefixes":{"":{"product":782,"type":0}}}, // [RECRUIT Communications]
-  {"hash":"6b9aad5cb94eb206","prefixes":{"":{"product":782,"type":0}}}, // [RECRUIT Communications]
-  {"hash":"671a4bc2e5c9113e","prefixes":{"":{"product":783,"type":1}}}, // [Hatena Co., Ltd]
-  {"hash":"6d3fdce985f31bd4","prefixes":{"":{"product":784,"type":0}}}, // [Trafmag]
-  {"hash":"1a311d346529c16b","prefixes":{"":{"product":784,"type":0}}}, // [Trafmag]
-  {"hash":"cd26b0ae13c2440e","prefixes":{"":{"product":785,"type":0}}}, // [Pagewoo]
-  {"hash":"06e9b4b216458951","prefixes":{"":{"product":786,"type":0}}}, // [Adnet Media]
-  {"hash":"cc0e43344ef5e735","prefixes":{"":{"product":786,"type":0}}}, // [Adnet Media]
-  {"hash":"2bff36578242b6b3","prefixes":{"":{"product":786,"type":0}}}, // [Adnet Media]
-  {"hash":"6bcb758317103435","prefixes":{"":{"product":786,"type":0}}}, // [Adnet Media]
-  {"hash":"5819339a3e48afa9","prefixes":{"":{"product":786,"type":0}}}, // [Adnet Media]
-  {"hash":"4249805768b5eaf7","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"c5d5cf4beb6462cf","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"41b628c1a22b441e","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"88d751d3810273e3","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"41ec9f7d9d627e03","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"02eb3f21dd6df789","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"6b48a245a94ab12a","prefixes":{"":{"product":787,"type":0}}}, // [Ligatus GmbH]
-  {"hash":"41d07cfbdb75024a","prefixes":{"":{"product":788,"type":0}}}, // [Webtrekk GmbH]
-  {"hash":"be359c4fcc3f3a06","prefixes":{"":{"product":788,"type":0}}}, // [Webtrekk GmbH]
-  {"hash":"6f767739019dd808","prefixes":{"":{"product":788,"type":0}}}, // [Webtrekk GmbH]
-  {"hash":"f253ef05e042b018","prefixes":{"":{"product":789,"type":1}}}, // [Kantar World Panel]
-  {"hash":"d01896485cd39018","prefixes":{"":{"product":789,"type":1}}}, // [Kantar World Panel]
-  {"hash":"0e0818ed2e61ee95","prefixes":{"":{"product":790,"type":0}}}, // [PubSquared LLC]
-  {"hash":"b05f21964e55a827","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"d333d9afb4898681","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"1639db8eb5956a46","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"5549a4c097f9b83d","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"1dbbc11fea26048b","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"098ed47c32246e74","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"48556c67606eaf5a","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"e9846bc3bb03a920","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"49353a0b9f2b5bb5","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"96bcc9c54b64eb5b","prefixes":{"":{"product":791,"type":0}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"f6e1c581da74f06c","prefixes":{"":{"product":792,"type":0}}}, // [travel audience GmbH]
-  {"hash":"a00eb1259ded5bb1","prefixes":{"":{"product":792,"type":0}}}, // [travel audience GmbH]
-  {"hash":"8026726dce357c58","prefixes":{"":{"product":793,"type":1}}}, // [Krux Digital, Inc.]
-  {"hash":"95e17daf76b8a492","prefixes":{"":{"product":793,"type":1}}}, // [Krux Digital, Inc.]
-  {"hash":"e2aedb8e35ba9ad0","prefixes":{"":{"product":793,"type":1}}}, // [Krux Digital, Inc.]
-  {"hash":"7e954379b20a3955","prefixes":{"":{"product":793,"type":1}}}, // [Krux Digital, Inc.]
-  {"hash":"bb2cd97362773074","prefixes":{"":{"product":793,"type":1}}}, // [Krux Digital, Inc.]
-  {"hash":"5f545b8ac29b5d2d","prefixes":{"":{"product":794,"type":0}}}, // [The Weather Channel]
-  {"hash":"188340d4038f111f","prefixes":{"":{"product":794,"type":0}}}, // [The Weather Channel]
-  {"hash":"88ce1340354cf56f","prefixes":{"":{"product":794,"type":0}}}, // [The Weather Channel]
-  {"hash":"6aa9e1031d5ce5ea","prefixes":{"":{"product":795,"type":1}}}, // [Social Quantum]
-  {"hash":"924b0bbf98095055","prefixes":{"":{"product":795,"type":1}}}, // [Social Quantum]
-  {"hash":"a8316ec9f577d677","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"4987a53ffae0e799","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"afafb80716e16e29","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"d0487d64f040dbfa","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"2c543734a4cbc5dd","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"067045f689cb5363","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"7ff291f0586a3dca","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"0a19a7d8484e10da","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"4614ce2d8cea29b5","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"c3164e283cfacd29","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"a1df629f546b9e31","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"6cbf35f72f18a347","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"1cb0768d21f55dd6","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"085272e0502f18c3","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"64b888da84877b17","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"c579af2db70b5cc0","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"306de8baaf32da18","prefixes":{"":{"product":796,"type":0}}}, // [AdVentori SAS]
-  {"hash":"1e9f7eb550327800","prefixes":{"":{"product":797,"type":1}}}, // [MindTake Research GmbH]
-  {"hash":"1c922be621564b9b","prefixes":{"":{"product":797,"type":1}}}, // [MindTake Research GmbH]
-  {"hash":"b3f33aa4d02b6fb2","prefixes":{"":{"product":798,"type":1}}}, // [Leger Marketing]
-  {"hash":"eead3245cdc680da","prefixes":{"":{"product":798,"type":1}}}, // [Leger Marketing]
-  {"hash":"1239f4aeb30a0c6e","prefixes":{"":{"product":799,"type":0}}}, // [BlisMedia Limited]
-  {"hash":"544a45aa905f9c6e","prefixes":{"":{"product":799,"type":0}}}, // [BlisMedia Limited]
-  {"hash":"c5e4c8510e3cac80","prefixes":{"":{"product":800,"type":1}}}, // [Double6]
-  {"hash":"d0fa41ada692b1b9","prefixes":{"":{"product":801,"type":0}}}, // [TRADEADS INTERACTIVE]
-  {"hash":"3db0a72bcd75db25","prefixes":{"":{"product":802,"type":0}}}, // [Epigrams, Inc.]
-  {"hash":"f42d4e28510cfcb3","prefixes":{"":{"product":802,"type":0}}}, // [Epigrams, Inc.]
-  {"hash":"22d2d672aad6f400","prefixes":{"":{"product":803,"type":1}}}, // [Activecore Inc.]
-  {"hash":"1ab5c06bec002a04","prefixes":{"":{"product":803,"type":1}}}, // [Activecore Inc.]
-  {"hash":"c34010f1f0a2a2bd","prefixes":{"":{"product":803,"type":1}}}, // [Activecore Inc.]
-  {"hash":"b274e3909d6409ff","prefixes":{"":{"product":804,"type":0}}}, // [Activecore,Inc.]
-  {"hash":"1bdc7aff17b34632","prefixes":{"":{"product":804,"type":0}}}, // [Activecore,Inc.]
-  {"hash":"a5f385ad8794bbf7","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"7fbf5ab845c319c3","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"636714c3598df906","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"9e6785892cd34bdd","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"047573e0075b371a","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"30468687bd7540d7","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"d38c33250529e4cf","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"311b59743017ebda","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"fceae2ba76fa56d8","prefixes":{"":{"product":805,"type":0}}}, // [ADCASH]
-  {"hash":"e3e53a304101f0b8","prefixes":{"*":{"product":806,"type":0}}}, // [Videoplaza]
-  {"hash":"66ae7f0627345a0e","prefixes":{"":{"product":807,"type":0}}}, // [Targetix LLC]
-  {"hash":"f2825950bbc13084","prefixes":{"":{"product":807,"type":0}}}, // [Targetix LLC]
-  {"hash":"5844bebbb6ebc2c8","prefixes":{"":{"product":807,"type":0}}}, // [Targetix LLC]
-  {"hash":"af1d9e1f4d4a29ee","prefixes":{"":{"product":807,"type":0}}}, // [Targetix LLC]
-  {"hash":"eabbec12e479563f","prefixes":{"":{"product":807,"type":0}}}, // [Targetix LLC]
-  {"hash":"063e5c59c898b6b2","prefixes":{"":{"product":807,"type":0}}}, // [Targetix LLC]
-  {"hash":"768e497f05eb9210","prefixes":{"":{"product":808,"type":1}}}, // [Adriver LLC]
-  {"hash":"a3e9e1ffdc9ef6f3","prefixes":{"":{"product":809,"type":0}}}, // [Beso]
-  {"hash":"dc3b4a3bb1a98472","prefixes":{"*":{"product":810,"type":0}}}, // [Voopter.com]
-  {"hash":"608c4fc0e1249087","prefixes":{"":{"product":811,"type":0}}}, // [Hostbasket]
-  {"hash":"ec50bd1f8e55703a","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"75f08f4a618e4c29","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"5e28845a397448ed","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"43baf1a2f5c604eb","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"9113c91f7c97eda8","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"6e46faf33af4223b","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"b8629ee4f4882cf4","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"c580bf68b5705ecc","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"30c1badbfab295cc","prefixes":{"":{"product":812,"type":0}}}, // [Rollad]
-  {"hash":"07206ed226f7d186","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"af031421c35c12bb","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"c1e9215522e84feb","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"f99b1e1004ffe36c","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"cc5aed10326009cd","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"a59bac0d7936d725","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"85c92ca45eb6137a","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"ecfa86f147eea591","prefixes":{"":{"product":813,"type":0}}}, // [hdtMedia]
-  {"hash":"89c418c61cc46dbf","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"36712fa880f9f4fd","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"77af178b53829cee","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"19e3098ce56eae94","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"605d50a0c132e0b5","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"9cb69b24762928be","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"7ad4195e3856bc8b","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"a1f419f69f83a3cb","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"a8184454cf33a5e3","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"8c22c5755c763066","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"862c4454fe07929d","prefixes":{"":{"product":815,"type":2}}}, // [ebuilders BV]
-  {"hash":"ac0afa5e86463dcf","prefixes":{"":{"product":816,"type":0}}}, // [COADVERTISE]
-  {"hash":"049d375ddb03cca6","prefixes":{"":{"product":816,"type":0}}}, // [COADVERTISE]
-  {"hash":"2ce968c3c01dac2b","prefixes":{"":{"product":817,"type":2}}}, // [Blizzard]
-  {"hash":"6e4734c6df5289ef","prefixes":{"":{"product":817,"type":2}}}, // [Blizzard]
-  {"hash":"9fe6f25a55c854ab","prefixes":{"":{"product":818,"type":0}}}, // [Adgibbon]
-  {"hash":"008bfe35bcbd016d","prefixes":{"":{"product":818,"type":0}}}, // [Adgibbon]
-  {"hash":"084705198bf3893b","prefixes":{"":{"product":818,"type":0}}}, // [Adgibbon]
-  {"hash":"a1b65ade9cc861cb","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"42f9c0b081bf4152","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"ea90626af94135dd","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"ae4cfcc8964ff838","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"29ed865d96c2134b","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"f0ad420cd06e916d","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"02fa3036dfdd1f55","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"2e1689e37ca87292","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"e0f93c05dad3c3c6","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"3a2e2804dc9fbb61","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"deed6c9248e53552","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"c4597285474e8048","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"e127ffe380012cba","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"2f548a00d118d32e","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"015756b75eb89403","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"35d2e95d1522b0c5","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"a43e409504b254d3","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"5a4147bb67b5b23c","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"9866a49aaacb720e","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"f101934b33880c8d","prefixes":{"":{"product":819,"type":0}}}, // [Wider Planet, Inc.]
-  {"hash":"5fc0aea809357158","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"ed7b8006e50dc195","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"fe112ea448efa84b","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"807a0ad2ef7d844d","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"24daf2e5c1e30aeb","prefixes":{"":{"product":106,"type":0}}}, // [Kpsule]
-  {"hash":"9091656f8979f5f0","prefixes":{"":{"product":106}}}, // [Kpsule]
-  {"hash":"bb5ef61e19944a06","prefixes":{"":{"product":820,"type":0}}}, // [ResponsiveAds, Inc]
-  {"hash":"ef4fefbe73da4a59","prefixes":{"":{"product":820,"type":0}}}, // [ResponsiveAds, Inc]
-  {"hash":"e78ef2faad563e6b","prefixes":{"":{"product":820,"type":0}}}, // [ResponsiveAds, Inc]
-  {"hash":"20e99abfa9e5de7c","prefixes":{"":{"product":820,"type":0}}}, // [ResponsiveAds, Inc]
-  {"hash":"0dedc650dbf5d391","prefixes":{"":{"product":820,"type":0}}}, // [ResponsiveAds, Inc]
-  {"hash":"5bdaec9fd3ff4dac","prefixes":{"":{"product":821,"type":1}}}, // [Duepuntozero Research SRL]
-  {"hash":"318bfe954294ea40","prefixes":{"":{"product":822,"type":0}}}, // [AdMovate, Inc.]
-  {"hash":"e24259ffed4d244f","prefixes":{"":{"product":822,"type":0}}}, // [AdMovate, Inc.]
-  {"hash":"c39b0621d7a8b616","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"29c359aefdd48c40","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"6ecf3c2aeb5aec2b","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"eea1a3478557a7a6","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"0b0e365de9c89436","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"875d9d8b11a6dff7","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"5edb8f1a6337d5d0","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"435808ca4dd1dce5","prefixes":{"":{"product":823,"type":0}}}, // [go.pl]
-  {"hash":"fd43d007391147de","prefixes":{"":{"product":700,"type":1}}}, // [MASSMOTIONMEDIA SARL]
-  {"hash":"633236a94b694dd7","prefixes":{"":{"product":700,"type":1}}}, // [MASSMOTIONMEDIA SARL]
-  {"hash":"a076e91e809efc28","prefixes":{"*":{"product":824,"type":0}}}, // [AppLovin Corporation]
-  {"hash":"14c26da0caac0796","prefixes":{"":{"product":825,"type":1}}}, // [twentysix ltd]
-  {"hash":"1f8d7bcebd64d2c9","prefixes":{"":{"product":21,"type":0}}}, // [Tamome]
-  {"hash":"41f4c0bf12c8f029","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"e674b14a061bb7d7","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"f485e2bb528d3147","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"82c09e315af7d70c","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"fc2b985669148068","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"cf9a9377bc72c2e4","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"d550149a2d5cfdde","prefixes":{"":{"product":332,"type":0}}}, // [EuroAds Group A/S]
-  {"hash":"d51c2c24cd771a6a","prefixes":{"":{"product":826,"type":0}}}, // [Epsilon International SA]
-  {"hash":"d34cf98578200c93","prefixes":{"":{"product":827,"type":0}}}, // [Zebestof]
-  {"hash":"44c2302577bd8e84","prefixes":{"":{"product":827,"type":0}}}, // [Zebestof]
-  {"hash":"52b835c5657206c1","prefixes":{"":{"product":827,"type":0}}}, // [Zebestof]
-  {"hash":"caa0c94cf57e2295","prefixes":{"":{"product":827,"type":0}}}, // [Zebestof]
-  {"hash":"02e54ec6b0aca548","prefixes":{"":{"product":828,"type":1}}}, // [SOL UTD Benelux BV]
-  {"hash":"1cf1a7f5c323d6e0","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"079a647886a5afa5","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"ec320d28ebdfac8c","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"e59449da7e642b45","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"1d61751db94dfc15","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"43f7746544162324","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"4f80c8700c459a79","prefixes":{"":{"product":829,"type":0}}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"23f62ba113f0fa4f","prefixes":{"":{"product":830,"type":1}}}, // [MediaCrossing Inc.]
-  {"hash":"62fc0fc3102b918b","prefixes":{"":{"product":831,"type":0}}}, // [MBR Targeting Gmbh]
-  {"hash":"0066f0743ade259b","prefixes":{"":{"product":831,"type":0}}}, // [MBR Targeting Gmbh]
-  {"hash":"4288d021c49b7e1b","prefixes":{"":{"product":831,"type":0}}}, // [MBR Targeting Gmbh]
-  {"hash":"6620a58a1f4cd480","prefixes":{"":{"product":832,"type":1}}}, // [VivaKi]
-  {"hash":"47db57aade94670f","prefixes":{"":{"product":832,"type":1}}}, // [VivaKi]
-  {"hash":"2924b77c1d7eab3b","prefixes":{"":{"product":832,"type":1}}}, // [VivaKi]
-  {"hash":"d2143dbf1699f4fa","prefixes":{"":{"product":833,"type":1}}}, // [Affiliate Window]
-  {"hash":"13c2a94c46886705","prefixes":{"":{"product":833,"type":1}}}, // [Affiliate Window]
-  {"hash":"c0d30b023dc9139f","prefixes":{"*":{"product":834,"type":0}}}, // [TubeMogul Inc. (AdWords/YouTube)]
-  {"hash":"108d788939e4b7a4","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"6fdc121917e19eb9","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"5262a88cfa363303","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"b597af924fe5ff97","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"dca60f44a70d5d38","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"c44308d5c2e3bb8a","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"90f5b971c961816f","prefixes":{"":{"product":814,"type":0}}}, // [DXP Media]
-  {"hash":"5d64c1152c075739","prefixes":{"":{"product":835,"type":0}}}, // [Way2traffic Polska S.A.]
-  {"hash":"01b13121d2ce9699","prefixes":{"":{"product":835,"type":0}}}, // [Way2traffic Polska S.A.]
-  {"hash":"f48791a2746e2a93","prefixes":{"":{"product":836,"type":1}}}, // [TNS Sifo AB]
-  {"hash":"935b8079b74f344c","prefixes":{"":{"product":836,"type":1}}}, // [TNS Sifo AB]
-  {"hash":"24e5b8b342d1b1fe","prefixes":{"":{"product":837,"type":1}}}, // [3xchange/Hunkal]
-  {"hash":"ad8c8bc165611bf2","prefixes":{"":{"product":837,"type":1}}}, // [3xchange/Hunkal]
-  {"hash":"b1b5bdd82d143e90","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"aeddaa071ba3b313","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"474802ea42555e39","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"b28e42ea18df1c00","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"826635800b12eb0c","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"22c10728f555913e","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"0b7f364ef0beed45","prefixes":{"":{"product":838,"type":0}}}, // [Emerse Sverige AB]
-  {"hash":"8d31e79105c5380a","prefixes":{"":{"product":839,"type":0}}}, // [Sokno Media]
-  {"hash":"037264ef7d8383f6","prefixes":{"":{"product":839,"type":0}}}, // [Sokno Media]
-  {"hash":"ff6372e6621d88ba","prefixes":{"":{"product":840,"type":0}}}, // [Blackheart, a division of Hot Topic, Inc.]
-  {"hash":"37742852c2a4ccc8","prefixes":{"":{"product":841,"type":0}}}, // [Torrid]
-  {"hash":"a86786ce90b23e3f","prefixes":{"":{"product":842,"type":0}}}, // [Hot Topic, Inc.]
-  {"hash":"93e1c22a4427a32f","prefixes":{"":{"product":843,"type":1}}}, // [WebHue LLC]
-  {"hash":"fca0a42aad108345","prefixes":{"static":{"product":844,"type":0},"img":{"product":844,"type":0},"log":{"product":844,"type":0}}}, // [Content to Emotion] [Content to Emotion] [Content to Emotion]
-  {"hash":"15948cae619c2e58","prefixes":{"":{"product":844,"type":0}}}, // [Content to Emotion]
-  {"hash":"db2a81c15837ddbd","prefixes":{"":{"product":845,"type":0}}}, // [Adman Interactive SL]
-  {"hash":"accf1565984e2899","prefixes":{"":{"product":845,"type":0}}}, // [Adman Interactive SL]
-  {"hash":"45351e5c4862b2dd","prefixes":{"":{"product":845,"type":0}}}, // [Adman Interactive SL]
-  {"hash":"ba3196c50e6c1be4","prefixes":{"":{"product":845,"type":0}}}, // [Adman Interactive SL]
-  {"hash":"eab724fbba4f83d6","prefixes":{"":{"product":845,"type":0}}}, // [Adman Interactive SL]
-  {"hash":"0edc8e7b8a8fe3ee","prefixes":{"":{"product":846,"type":0}}}, // [AudienceFUEL, Inc.]
-  {"hash":"dfa423315ab48813","prefixes":{"":{"product":847,"type":0}}}, // [TapCommerce LLC]
-  {"hash":"777b0f4301aa1643","prefixes":{"":{"product":847,"type":0}}}, // [TapCommerce LLC]
-  {"hash":"294cba0ae232447c","prefixes":{"":{"product":848,"type":0}}}, // [AdTheorent, Inc.]
-  {"hash":"ba7ad5da6db014c7","prefixes":{"":{"product":849,"type":0}}}, // [AdTheorent, Inc]
-  {"hash":"09bfc8a7f1c7896f","prefixes":{"":{"product":848,"type":0}}}, // [AdTheorent, Inc.]
-  {"hash":"362136e847a35f7e","prefixes":{"":{"product":848,"type":0}}}, // [AdTheorent, Inc.]
-  {"hash":"5492d77bb75e6380","prefixes":{"":{"product":850,"type":0}}}, // [Barometric]
-  {"hash":"94bb816c4a375220","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"f10e1a418576d219","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"245fc951b0a9ce59","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"babdceabca3ae2b8","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"c6474114ede3195a","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"26faef64bd072723","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"0a19b1f547a3a935","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"b4ef56642916cc60","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"c1fc9d245fa85b02","prefixes":{"":{"product":851,"type":0}}}, // [CrossInstall, Inc]
-  {"hash":"0e3ddb4868b0e99f","prefixes":{"":{"product":852,"type":0}}}, // [Theorem Inc.]
-  {"hash":"976d4ea6507dfd2e","prefixes":{"":{"product":852,"type":0}}}, // [Theorem Inc.]
-  {"hash":"70a3fe87d3bbbae9","prefixes":{"":{"product":852,"type":0}}}, // [Theorem Inc.]
-  {"hash":"1cf1ec002a07d6a4","prefixes":{"":{"product":853,"type":0}}}, // [KeyVersion]
-  {"hash":"b2c480f3bc7b03b6","prefixes":{"":{"product":853,"type":0}}}, // [KeyVersion]
-  {"hash":"c94dbc0a3ffc6eda","prefixes":{"":{"product":854,"type":0}}}, // [Ancestry]
-  {"hash":"04fb46af993df556","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"b9adf25b55c4d0f3","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"1c1211c84dbee054","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"575fafb094c71d93","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"f2b020b3d3861db2","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"609d13c5cd3771c8","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"aeae313934102cfe","prefixes":{"":{"product":856,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd]
-  {"hash":"f8721bcf4d9f6196","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"09e5f7c9f30f4fd6","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"a1ce57d387427206","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"bb4b6377666172c4","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"d6a6a6cd062bc76e","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"0313ce8a9851d837","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"6862450d2314df40","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"0a34c9f6f0cf9556","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"8e311fce80eccafd","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"296fdad7e8336d5a","prefixes":{"":{"product":855,"type":0}}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"27c0e177312a3c0f","prefixes":{"":{"product":107,"type":0}}}, // [Immedium, Inc.]
-  {"hash":"fc3c7114081863bd","prefixes":{"":{"product":107,"type":0}}}, // [Immedium, Inc.]
-  {"hash":"811582f5df157ff9","prefixes":{"":{"product":857,"type":1}}}, // [KissNoFrog.com]
-  {"hash":"284d8a4f9b174bab","prefixes":{"":{"product":858,"type":1}}}, // [DigiEQ]
-  {"hash":"aa0e7b7a1fe279dc","prefixes":{"":{"product":858,"type":1}}}, // [DigiEQ]
-  {"hash":"1f551f934400f81e","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"1c3b94cabbbc5b8c","prefixes":{"":{"product":85,"type":0}}}, // [MediaMath Inc.]
-  {"hash":"505b194aeebd6baf","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"8f2e12e9677e4d41","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"e2a3fe5e482432e8","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"7d03cd1b92c167a8","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"532402cd3ab13402","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"48e577ba3e61c748","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"1480a6580cb81dde","prefixes":{"":{"product":859,"type":0}}}, // [Mobile Professinals BV]
-  {"hash":"b1ec46dd2c4c824e","prefixes":{"*":{"product":108,"type":0}}}, // [Fractional Media, LLC]
-  {"hash":"6c6240697771befd","prefixes":{"*":{"product":108,"type":0}}}, // [Fractional Media, LLC]
-  {"hash":"f2e16038c0d83b85","prefixes":{"":{"product":860,"type":0}}}, // [Decisive, Inc.]
-  {"hash":"654da4ed85d77fb9","prefixes":{"":{"product":860,"type":0}}}, // [Decisive, Inc.]
-  {"hash":"c9e2ea0486216534","prefixes":{"":{"product":860,"type":0}}}, // [Decisive, Inc.]
-  {"hash":"9e4f5b2f200fbb25","prefixes":{"":{"product":861,"type":0}}}, // [Tumi, Inc. US]
-  {"hash":"4378c60894195c4f","prefixes":{"":{"product":862,"type":0}}}, // [Tumi, Inc. UK]
-  {"hash":"61e82c5e74c5ce7c","prefixes":{"":{"product":863,"type":0}}}, // [Tumi, Inc. DE]
-  {"hash":"712f010eb9792fa4","prefixes":{"":{"product":864,"type":0}}}, // [Nanigans, Inc]
-  {"hash":"589eceaef79619dd","prefixes":{"":{"product":864,"type":0}}}, // [Nanigans, Inc]
-  {"hash":"1d66f17c949dbaee","prefixes":{"":{"product":864,"type":0}}}, // [Nanigans, Inc]
-  {"hash":"6dbd7b9480163af0","prefixes":{"":{"product":864,"type":0}}}, // [Nanigans, Inc]
-  {"hash":"41d56e0870364212","prefixes":{"":{"product":138,"type":0}}}, // [Brandscreen Inc.]
-  {"hash":"2d701495cf72af5b","prefixes":{"*":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"0bd14e8d5a6b2f2d","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"9b504cc586da72e5","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"a89d4cb4490b4286","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"dce925353cbc1dbe","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"ff8d26679ce7dafc","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"11db2fec76a76647","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"00a09e8788ee6f2b","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"709d79bfe214aa48","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"7a37fa5ff1a37799","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"42a24e1ab1c2d947","prefixes":{"":{"product":865,"type":0}}}, // [AdSniper LLC]
-  {"hash":"63f4e4d315bc085b","prefixes":{"":{"product":866,"type":1}}}, // [Fabric Worldwide Inc]
-  {"hash":"b9c11e67d7eb2963","prefixes":{"":{"product":866,"type":1}}}, // [Fabric Worldwide Inc]
-  {"hash":"e3882e6bc0c2e382","prefixes":{"":{"product":867,"type":1}}}, // [Vorwerk Deutschland Stiftung & Co. KG]
-  {"hash":"944d86d40b9ae089","prefixes":{"":{"product":867,"type":1}}}, // [Vorwerk Deutschland Stiftung & Co. KG]
-  {"hash":"ebd456010571b5ae","prefixes":{"":{"product":867,"type":1}}}, // [Vorwerk Deutschland Stiftung & Co. KG]
-  {"hash":"4456fa769be90ba2","prefixes":{"":{"product":64,"type":0}}}, // [Active Agent]
-  {"hash":"84d65f5782dd26d6","prefixes":{"":{"product":868,"type":0}}}, // [Chico Distribution Services, LLC]
-  {"hash":"a6185f46e2849f58","prefixes":{"":{"product":869,"type":0}}}, // [12Mnkys GmbH]
-  {"hash":"bf874935c6972629","prefixes":{"":{"product":869,"type":0}}}, // [12Mnkys GmbH]
-  {"hash":"094b301a712414f2","prefixes":{"":{"product":869,"type":0}}}, // [12Mnkys GmbH]
-  {"hash":"56ee8d67408b2316","prefixes":{"":{"product":869,"type":0}}}, // [12Mnkys GmbH]
-  {"hash":"d62d9c20c47ec863","prefixes":{"":{"product":869,"type":0}}}, // [12Mnkys GmbH]
-  {"hash":"bb716a8269a2e79c","prefixes":{"":{"product":870,"type":0}}}, // [Spacyz, Inc.]
-  {"hash":"5a6ff8a620bb8de1","prefixes":{"":{"product":870,"type":0}}}, // [Spacyz, Inc.]
-  {"hash":"61cf0a8426083e54","prefixes":{"":{"product":870,"type":0}}}, // [Spacyz, Inc.]
-  {"hash":"4cf4aa4b0e37fdfd","prefixes":{"":{"product":709,"type":0}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"745acee8f5973f56","prefixes":{"":{"product":709,"type":0}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"9a834a1cc05cb878","prefixes":{"":{"product":871,"type":1}}}, // [MBuy, Inc.]
-  {"hash":"73cd161c10ebcf69","prefixes":{"":{"product":872,"type":0}}}, // [FullSpeed Inc.]
-  {"hash":"75c72b5cc4c40c16","prefixes":{"":{"product":872,"type":0}}}, // [FullSpeed Inc.]
-  {"hash":"33c5c398130ddfec","prefixes":{"":{"product":872,"type":0}}}, // [FullSpeed Inc.]
-  {"hash":"1c0653651245a014","prefixes":{"":{"product":872,"type":0}}}, // [FullSpeed Inc.]
-  {"hash":"271d057b15f67166","prefixes":{"":{"product":872,"type":0}}}, // [FullSpeed Inc.]
-  {"hash":"e9723a229b8b9eeb","prefixes":{"":{"product":872,"type":0}}}, // [FullSpeed Inc.]
-  {"hash":"8e3c99c5cc10c217","prefixes":{"":{"product":350,"type":0}}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"07141bfb96faa93c","prefixes":{"":{"product":873,"type":0}}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"1d7294abbaa26e26","prefixes":{"":{"product":873,"type":0}}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"6872272e097d2cd9","prefixes":{"":{"product":873,"type":0}}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"66ec8aa560cf2231","prefixes":{"":{"product":873,"type":0}}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"17cd9dcba702b7e6","prefixes":{"":{"product":873,"type":0}}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"2347e9e88f6ead88","prefixes":{"":{"product":874,"type":0}}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"7f19740ff86dc642","prefixes":{"":{"product":874,"type":0}}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"18f553670e23734b","prefixes":{"":{"product":874,"type":0}}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"ca862d199926ad1c","prefixes":{"":{"product":874,"type":0}}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"2238776218564026","prefixes":{"":{"product":874,"type":0}}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"0d60795f6997311e","prefixes":{"":{"product":875,"type":0}}}, // [Omnibus co. Ltd]
-  {"hash":"f32008e13be0f96e","prefixes":{"":{"product":875,"type":0}}}, // [Omnibus co. Ltd]
-  {"hash":"dd5533aa2d49cc10","prefixes":{"":{"product":876,"type":1}}}, // [Omnibus co. Ltd.]
-  {"hash":"3bcd500b684d5142","prefixes":{"":{"product":875,"type":0}}}, // [Omnibus co. Ltd]
-  {"hash":"14eef63a2889c8da","prefixes":{"":{"product":875,"type":0}}}, // [Omnibus co. Ltd]
-  {"hash":"53f31e427551538d","prefixes":{"":{"product":875,"type":0}}}, // [Omnibus co. Ltd]
-  {"hash":"5296819de63f3444","prefixes":{"":{"product":875,"type":0}}}, // [Omnibus co. Ltd]
-  {"hash":"d8389fea989da8d7","prefixes":{"":{"product":39,"type":0}}}, // [Airpush, Inc.]
-  {"hash":"e251b17a002b679b","prefixes":{"":{"product":877,"type":1}}}, // [Education Management Corporation]
-  {"hash":"ec35188a522b7db9","prefixes":{"*":{"product":878,"type":1}}}, // [Screen6 (s6.io)]
-  {"hash":"8ee1cf907bbca914","prefixes":{"":{"product":879,"type":1}}}, // [LINK Marketing Services AG]
-  {"hash":"18a5decf96e8c80d","prefixes":{"":{"product":880,"type":0}}}, // [TiqIQ]
-  {"hash":"8927e5364d1bf1d1","prefixes":{"":{"product":880,"type":0}}}, // [TiqIQ]
-  {"hash":"86292c524ac79685","prefixes":{"":{"product":880,"type":0}}}, // [TiqIQ]
-  {"hash":"52562df3f7208c8f","prefixes":{"":{"product":880,"type":0}}}, // [TiqIQ]
-  {"hash":"a7d6fe32ab078e86","prefixes":{"":{"product":880,"type":0}}}, // [TiqIQ]
-  {"hash":"497857c899894a0f","prefixes":{"":{"product":880,"type":0}}}, // [TiqIQ]
-  {"hash":"0d8c5ad133d4c83e","prefixes":{"":{"product":881,"type":0}}}, // [Ibibo Group Private Limited]
-  {"hash":"a8c10e41d2d4b31a","prefixes":{"":{"product":881,"type":0}}}, // [Ibibo Group Private Limited]
-  {"hash":"9699d29520d1b9b8","prefixes":{"":{"product":881,"type":0}}}, // [Ibibo Group Private Limited]
-  {"hash":"103308c15ca4c459","prefixes":{"":{"product":876,"type":1}}}, // [Omnibus co. Ltd.]
-  {"hash":"d7a1b3fc5e1252ce","prefixes":{"":{"product":876,"type":1}}}, // [Omnibus co. Ltd.]
-  {"hash":"ee40bf7c9bae2361","prefixes":{"":{"product":882,"type":0}}}, // [justAd TV LTD]
-  {"hash":"8755d187f8ffb5e9","prefixes":{"":{"product":882,"type":0}}}, // [justAd TV LTD]
-  {"hash":"1bdf54cf79d18915","prefixes":{"":{"product":882,"type":0}}}, // [justAd TV LTD]
-  {"hash":"ed61950d43d99717","prefixes":{"":{"product":882,"type":0}}}, // [justAd TV LTD]
-  {"hash":"aff928fc58637cb3","prefixes":{"":{"product":883,"type":0}}}, // [Appier Inc.]
-  {"hash":"797f76218537ad5d","prefixes":{"*":{"product":883,"type":0}}}, // [Appier Inc.]
-  {"hash":"6bdcdb03ff6173af","prefixes":{"*":{"product":883,"type":0}}}, // [Appier Inc.]
-  {"hash":"6a3dec8b5a467987","prefixes":{"*":{"product":883,"type":0}}}, // [Appier Inc.]
-  {"hash":"a3d5f58bbde56b12","prefixes":{"":{"product":883,"type":0}}}, // [Appier Inc.]
-  {"hash":"7d0adb9089ff21ca","prefixes":{"":{"product":883,"type":0}}}, // [Appier Inc.]
-  {"hash":"c241f36263ea7c84","prefixes":{"":{"product":884,"type":0}}}, // [Kate Spade Saturday]
-  {"hash":"79dd595e79611766","prefixes":{"":{"product":885,"type":0}}}, // [Teufel GmbH]
-  {"hash":"df829b8e840c11e1","prefixes":{"":{"product":885,"type":0}}}, // [Teufel GmbH]
-  {"hash":"c3004b48539587e5","prefixes":{"":{"product":885,"type":0}}}, // [Teufel GmbH]
-  {"hash":"08eb365a3723ee17","prefixes":{"":{"product":885,"type":0}}}, // [Teufel GmbH]
-  {"hash":"71bc88c0bd0dc170","prefixes":{"":{"product":885,"type":0}}}, // [Teufel GmbH]
-  {"hash":"fb208e41a565430a","prefixes":{"":{"product":886,"type":0}}}, // [Aitarget LLC]
-  {"hash":"6121d39232612f56","prefixes":{"":{"product":886,"type":0}}}, // [Aitarget LLC]
-  {"hash":"532febae5cf9194f","prefixes":{"":{"product":887,"type":0}}}, // [Engage Lab Ltd.]
-  {"hash":"fbfff8f12503c208","prefixes":{"":{"product":888,"type":1}}}, // [Signal Digital, Inc dba Signal]
-  {"hash":"14afd1fc2da14d71","prefixes":{"":{"product":889,"type":0}}}, // [Motrixi Media Group LLC]
-  {"hash":"aa674bd59dee4716","prefixes":{"":{"product":889,"type":0}}}, // [Motrixi Media Group LLC]
-  {"hash":"7fd4fa8a06589cab","prefixes":{"":{"product":889,"type":0}}}, // [Motrixi Media Group LLC]
-  {"hash":"56f94b2620357eb5","prefixes":{"":{"product":889,"type":0}}}, // [Motrixi Media Group LLC]
-  {"hash":"32ddc8b6874f030b","prefixes":{"":{"product":890,"type":0}}}, // [WHITE HOUSE | BLACK MARKET, Chico Brands, Inc.]
-  {"hash":"fea26de6b70aafb9","prefixes":{"":{"product":891,"type":0}}}, // [Liftoff Mobile, Inc.]
-  {"hash":"4687be4922e9d22e","prefixes":{"":{"product":892,"type":1}}}, // [etracker GmbH]
-  {"hash":"b41f235329fba677","prefixes":{"*":{"product":893,"type":1}}}, // [MezzoMedia]
-  {"hash":"3362cc82ba37c826","prefixes":{"":{"product":893,"type":1}}}, // [MezzoMedia]
-  {"hash":"7c5cbde65c1f0a61","prefixes":{"":{"product":894,"type":1}}}, // [Eyeota Limited]
-  {"hash":"d85ebb0a3c0bdef4","prefixes":{"":{"product":895,"type":0}}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"52d134e034c55e1d","prefixes":{"":{"product":895,"type":0}}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"9d9805e510965156","prefixes":{"":{"product":895,"type":0}}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"5ed6426649a5142e","prefixes":{"":{"product":895,"type":0}}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"e629bb2b2df81562","prefixes":{"":{"product":895,"type":0}}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"37a1384fb3fc6090","prefixes":{"":{"product":266,"type":0}}}, // [Intelliad]
-  {"hash":"9d931008b4067d12","prefixes":{"":{"product":896,"type":0}}}, // [Padopolis, Inc.]
-  {"hash":"2e0eb051f10f4fe7","prefixes":{"":{"product":896,"type":0}}}, // [Padopolis, Inc.]
-  {"hash":"e4e066ee012dd820","prefixes":{"":{"product":897,"type":0}}}, // [Republic Project, Inc.]
-  {"hash":"6bda23da60f6517c","prefixes":{"":{"product":897,"type":0}}}, // [Republic Project, Inc.]
-  {"hash":"8af361ef2f58932e","prefixes":{"":{"product":897,"type":0}}}, // [Republic Project, Inc.]
-  {"hash":"9cf685ac4bd3c1a0","prefixes":{"":{"product":897,"type":0}}}, // [Republic Project, Inc.]
-  {"hash":"ceb2ae18496c4062","prefixes":{"":{"product":897,"type":0}}}, // [Republic Project, Inc.]
-  {"hash":"a1c74be312c1e501","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"e2305a44231103a0","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"e9ea3f2053ff0ac5","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"18f65ffdee8f8402","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"dc902603963cc6c8","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"6addef0844f148c5","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"c2889776656d63b3","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"1a1ac1eeae181fe7","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"fa03396d4a303d45","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"f632f69c34840122","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"082e62ce70aa66fc","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"775c7d89c606cd3c","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"74b282bb3c686219","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"a8e1956c97315aaf","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"26dc9f78ec72cc0c","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"c4ef7b6eeeda12ce","prefixes":{"":{"product":898,"type":0}}}, // [C8 Network]
-  {"hash":"e78c2b0997dfa249","prefixes":{"":{"product":899,"type":0}}}, // [Data Artist Inc.]
-  {"hash":"41045058078214c7","prefixes":{"":{"product":899,"type":0}}}, // [Data Artist Inc.]
-  {"hash":"c3b23588f42fedff","prefixes":{"":{"product":899,"type":0}}}, // [Data Artist Inc.]
-  {"hash":"5e94c742d87aa747","prefixes":{"":{"product":899,"type":0}}}, // [Data Artist Inc.]
-  {"hash":"52632067f5495750","prefixes":{"":{"product":900,"type":0}}}, // [AirFrance]
-  {"hash":"0b27c948dba1fda0","prefixes":{"":{"product":901,"type":1}}}, // [YDigital Media]
-  {"hash":"7e30f931dbb7180a","prefixes":{"":{"product":902,"type":2}}}, // [Zentrick]
-  {"hash":"b3e2285b6fc03e5c","prefixes":{"":{"product":902,"type":2}}}, // [Zentrick]
-  {"hash":"e2f247795ad2ad87","prefixes":{"":{"product":902,"type":2}}}, // [Zentrick]
-  {"hash":"1c9e4d1810e659fa","prefixes":{"":{"product":902,"type":2}}}, // [Zentrick]
-  {"hash":"57511b10e2ed4785","prefixes":{"":{"product":902,"type":2}}}, // [Zentrick]
-  {"hash":"c012faa898c62e0b","prefixes":{"":{"product":903,"type":0}}}, // [FreeBit Co. Ltd.]
-  {"hash":"41b7f33c961162f8","prefixes":{"":{"product":903,"type":0}}}, // [FreeBit Co. Ltd.]
-  {"hash":"ffac4f6c5fa1aa82","prefixes":{"":{"product":903,"type":0}}}, // [FreeBit Co. Ltd.]
-  {"hash":"a23bae62ab25e2c1","prefixes":{"":{"product":903,"type":0}}}, // [FreeBit Co. Ltd.]
-  {"hash":"ae08459757b76c12","prefixes":{"":{"product":903,"type":0}}}, // [FreeBit Co. Ltd.]
-  {"hash":"83efb7fcb7770789","prefixes":{"":{"product":904,"type":0}}}, // [Dennoo Inc.]
-  {"hash":"042456e26a44a268","prefixes":{"":{"product":904,"type":0}}}, // [Dennoo Inc.]
-  {"hash":"cb0b16dd50ba9d7d","prefixes":{"":{"product":904,"type":0}}}, // [Dennoo Inc.]
-  {"hash":"541a895df01d2b2c","prefixes":{"":{"product":904,"type":0}}}, // [Dennoo Inc.]
-  {"hash":"8f01887bb7405ab5","prefixes":{"":{"product":905,"type":0}}}, // [Adbrain]
-  {"hash":"33734a86766d25a9","prefixes":{"*":{"product":906,"type":1}}}, // [MSI-ACI Europe BV]
-  {"hash":"f66543f279b3e1e7","prefixes":{"":{"product":907,"type":0}}}, // [A.Mob]
-  {"hash":"74ee8c0f2fb31813","prefixes":{"":{"product":907,"type":0}}}, // [A.Mob]
-  {"hash":"584db20b69521f40","prefixes":{"":{"product":908,"type":0}}}, // [Toys R Us]
-  {"hash":"6a001e8bc99fede6","prefixes":{"":{"product":909,"type":0}}}, // [Geniee,Inc]
-  {"hash":"b8ff7bd604535ea9","prefixes":{"":{"product":909,"type":0}}}, // [Geniee,Inc]
-  {"hash":"3e005c1dfdc23488","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"ddef7bb2f5930121","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"424399e643b329b8","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"23df92e04ec66406","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"06f0caf4a4fe6ed1","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"9697a0818cbd79bd","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"ec7f61f2511ae20e","prefixes":{"":{"product":910,"type":1}}}, // [Adsecure]
-  {"hash":"fb4e7ecb8304ade4","prefixes":{"":{"product":911,"type":0}}}, // [Kimia Solutions SL]
-  {"hash":"84f5d0f934bd60f1","prefixes":{"":{"product":911,"type":0}}}, // [Kimia Solutions SL]
-  {"hash":"b3fcc22fcd382f3b","prefixes":{"":{"product":911,"type":0}}}, // [Kimia Solutions SL]
-  {"hash":"4eca8c3218b372ae","prefixes":{"":{"product":912,"type":1}}}, // [Sojern]
-  {"hash":"9636bfb4feaef839","prefixes":{"":{"product":912,"type":1}}}, // [Sojern]
-  {"hash":"a525b67906a4cb94","prefixes":{"":{"product":913,"type":0}}}, // [Where 2 Get It, Inc.]
-  {"hash":"6c959985d7181026","prefixes":{"":{"product":913,"type":0}}}, // [Where 2 Get It, Inc.]
-  {"hash":"7843db8d760e28cb","prefixes":{"":{"product":914,"type":0}}}, // [Tomoko Cloud]
-  {"hash":"eb7b756fc1f88aa1","prefixes":{"":{"product":914,"type":0}}}, // [Tomoko Cloud]
-  {"hash":"ed4d672687c27603","prefixes":{"":{"product":914,"type":0}}}, // [Tomoko Cloud]
-  {"hash":"b156b34e4d693e49","prefixes":{"":{"product":914,"type":0}}}, // [Tomoko Cloud]
-  {"hash":"16e146e87e7d0383","prefixes":{"":{"product":915,"type":0}}}, // [RevenueMantra]
-  {"hash":"1457bcbc098b2864","prefixes":{"":{"product":915,"type":0}}}, // [RevenueMantra]
-  {"hash":"450eb4f9273a5014","prefixes":{"":{"product":916,"type":0}}}, // [Automobile Ltd.]
-  {"hash":"436e4eaa95b23fcb","prefixes":{"":{"product":916,"type":0}}}, // [Automobile Ltd.]
-  {"hash":"a47ee9f00ca4f855","prefixes":{"":{"product":916,"type":0}}}, // [Automobile Ltd.]
-  {"hash":"889ab5643c83668a","prefixes":{"":{"product":916,"type":0}}}, // [Automobile Ltd.]
-  {"hash":"4ea96f1e0388da92","prefixes":{"":{"product":917,"type":0}}}, // [Big Mobile Group Pty Ltd]
-  {"hash":"ae895a18cc8c416e","prefixes":{"":{"product":917,"type":0}}}, // [Big Mobile Group Pty Ltd]
-  {"hash":"bbb46a7f5062448e","prefixes":{"":{"product":918,"type":0}}}, // [ADMIZED AG]
-  {"hash":"0b4e26a40cc2e647","prefixes":{"":{"product":919,"type":0}}}, // [Sparks47 s.r.l.]
-  {"hash":"745030cd7ac80402","prefixes":{"":{"product":920,"type":0}}}, // [Between Digital dba Intency DSP]
-  {"hash":"55db959f7c533183","prefixes":{"":{"product":920,"type":0}}}, // [Between Digital dba Intency DSP]
-  {"hash":"15b9a82ccbf2d7ff","prefixes":{"":{"product":920,"type":0}}}, // [Between Digital dba Intency DSP]
-  {"hash":"801d43da2c97866b","prefixes":{"":{"product":920,"type":0}}}, // [Between Digital dba Intency DSP]
-  {"hash":"d9f810d72012d4c4","prefixes":{"":{"product":921,"type":1}}}, // [eprofessional GmbH]
-  {"hash":"23c665bb68cc30cc","prefixes":{"":{"product":921,"type":1}}}, // [eprofessional GmbH]
-  {"hash":"8439b0c8f73daf02","prefixes":{"":{"product":921,"type":1}}}, // [eprofessional GmbH]
-  {"hash":"6a17378968b598f2","prefixes":{"":{"product":921,"type":1}}}, // [eprofessional GmbH]
-  {"hash":"4e157cd578931a97","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"9cdf7d74bee2159f","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"58c684b764b4dcab","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"85218b0017b8f452","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"9f790c0c14fa8f4d","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"e7518acf5c44d0a4","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"ec763282f8f41299","prefixes":{"":{"product":922,"type":0}}}, // [Channel Factory, LLC]
-  {"hash":"41a0870b895e73b4","prefixes":{"":{"product":923,"type":0}}}, // [ConvertStar Incorporated]
-  {"hash":"f0134a17d368f3d8","prefixes":{"":{"product":923,"type":0}}}, // [ConvertStar Incorporated]
-  {"hash":"58f6c00f44fb69a4","prefixes":{"":{"product":923,"type":0}}}, // [ConvertStar Incorporated]
-  {"hash":"ff266e088e3010a8","prefixes":{"":{"product":924}}}, // [VisualDNA (Imagini)]
-  {"hash":"9748c01f8dcd17ee","prefixes":{"":{"product":924}}}, // [VisualDNA (Imagini)]
-  {"hash":"8e588a0818c4fcfe","prefixes":{"":{"product":924}}}, // [VisualDNA (Imagini)]
-  {"hash":"b499a754cc7d2c9b","prefixes":{"":{"product":924}}}, // [VisualDNA (Imagini)]
-  {"hash":"12d363fa8ee6c4d3","prefixes":{"":{"product":925,"type":0}}}, // [Avocet]
-  {"hash":"a8bc7b6f66702489","prefixes":{"":{"product":925,"type":0}}}, // [Avocet]
-  {"hash":"5166d9515e755f19","prefixes":{"":{"product":926,"type":0}}}, // [Auction.com, LLC]
-  {"hash":"3adf8560ada830b8","prefixes":{"":{"product":926,"type":0}}}, // [Auction.com, LLC]
-  {"hash":"f24f87c799e92ae5","prefixes":{"":{"product":926,"type":0}}}, // [Auction.com, LLC]
-  {"hash":"a60dedada0fd44b6","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5d0f226850d2e68c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e4c703070b535b17","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"bc640a9c42502b35","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"defb06aab760992e","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"9bb069524856b34b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ef253518584f013f","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e100ba963ad8ecf2","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"05b625ee62d8685f","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5a88fb5abffcefc9","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a31c0b568cc8ade8","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"3498894fbeac8341","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1b82605c41d8b709","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"8138ad98ed0394e9","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"751c9ebb221bb5f9","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"8e3793804d9cdab5","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a6ecf1a95c24b6a3","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d27fe0e9834e648b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"2a0c1b5a904b36c1","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"f0d6c35febee8008","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"3c01a29e3c9c7264","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"4a74fdfd9b816fe8","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"aac8184f18b04958","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"368da19a90db3ad7","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"116d46403c6e95b7","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"808bb76ca34e4d1b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"b19f61f6e35aaa6a","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"9afc01573e38d021","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"11d7bce194c54912","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a28be439cad08ebb","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"968792ffe85f5d2d","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d3bc9343531e6c0c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a11d6b37b0382222","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"4bf65fa3bba0c55b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"4e1d992a76cf0b41","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"b09978a8e01fdbca","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"7394b2453f854b55","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a76d4645267ff0be","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"7e60860df0c8945b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ed9d4b0db5598264","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"466d1d16f3a935fb","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"21ac8963bf026e1a","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e04f72461a1fdf7d","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"549860a6933e906e","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ddc7313241f77312","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d89759a9687ad368","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"343ad98c7f4d71ed","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"2cb5047919d88ce8","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e9739ef3b0403f17","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"2b8ce30f483d90da","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1d1295f1cdac7503","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"57fd3c09e35ca17e","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"050dd41acc3ac3be","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1b853fb5c08c8727","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1c3db6034ad5c3e7","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"4b87160668f51e71","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d0875bc7510fbaa1","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a46257724ca67bc0","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"c93d397e8d1ed4fe","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"2cc9ae96e6b56fc3","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"051e72fcceee74d6","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"c24b55da2a7095df","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"88981afd076ecf48","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1ac94ef8a4d9ad5b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a57f0b4ed1a21743","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ff1f4076329cb91c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1ea1f1044008a0b2","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5a9b4bfa6d03c94b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"16bcde8365ddf2a8","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"7d3732d8588ffedb","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"fb6a6a06e4463001","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e357e4b19a11617f","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ee8aa73feac66773","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"8aa426bd808ed75a","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e5eed224f946f11b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"3b812696a50c7061","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a04facc89859d775","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"37413c9d9331953b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d5713942d78606a2","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"52e5d6a64f47f9e8","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"bb49554e8d0ea27b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"9943d790e614f45a","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"b318da3bafca323e","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"8a6b3193ebf16daf","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"9a4e890c561b1f49","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"38f8c78460d0c171","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ceb269cfcbfb3737","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"6fc86b42fa2194c7","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"948868ae3f88e79e","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"f78a9daa44503acf","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"f065b37e2901ab44","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"03f33a24e5022801","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"db26cef88e3879aa","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"496f2ff2ad72eb56","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a33121c16f5e4d20","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1b5947476f3297ae","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ebaf8ad16d676e4c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5ec7e2368a41e7d1","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"f69cbc017c2bee73","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e2095571b8a4a9ea","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"8e8d9589ff612ccb","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"4acd7b14907d2eab","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"00b864b32ca6962f","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"0e7fd376997e0ce6","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"8947ab8c7604a712","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"12ae4c62954fb4d7","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5c70a05c3b20c460","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"7920d4521fc31742","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"14d71824a114fae5","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5c58f35ad11ea36d","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"c68ff69ac1086025","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"bfb4d21e0325cd27","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"1c5328ce70a7d781","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"3a27002f3a51c391","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"15c536b247ddda9b","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"b8dfd3383dc85e16","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d834384f74b37311","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"33ad4a447e65fe4c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"5f92334372103621","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"3b36a0673402ddea","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"b8e5c9de8614511a","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d6f7d0951a76b20f","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"dc731362e0a22c79","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"c37ce29a12797b87","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"b7f8903cecd3c417","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"e9aea7737083ea26","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ca849c611df2249c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"eba969c354d1a2b6","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"828d340d34a88e86","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"18a6bfdbc9b1999c","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"ea6de81ee5ad1594","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"46f992eaa836ef3e","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"a6c162781ee3a889","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"926d3b6bfe6e1943","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"7e15147781f2b0b4","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"221d9d61291eac74","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"d1c16d1fc4dc5998","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"25596ab30bae8f45","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"6f03c0e16553edcf","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"af7ab58246b4c2a5","prefixes":{"":{"product":927,"type":1}}}, // [White Ops, Inc.]
-  {"hash":"82a102dc6f580854","prefixes":{"":{"product":762,"type":0}}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"35f665efa0e2a55c","prefixes":{"":{"product":762,"type":0}}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"3a48f18bf340e74a","prefixes":{"":{"product":762,"type":0}}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"ee365433c62a5c89","prefixes":{"":{"product":762,"type":0}}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"abe6370bd088dcf4","prefixes":{"":{"product":928,"type":0}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"92dba1cdcba82d8a","prefixes":{"":{"product":928,"type":0}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"ee0ccb57505565f7","prefixes":{"":{"product":928,"type":0}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"f25f5e4909b9792c","prefixes":{"":{"product":928,"type":0}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"8a9e6f7beeb084c5","prefixes":{"":{"product":928,"type":0}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"94542c85cf399cbd","prefixes":{"":{"product":319,"type":0}}}, // [FinanceGenerator]
-  {"hash":"46ea052a92233562","prefixes":{"":{"product":929,"type":1}}}, // [Admetrics]
-  {"hash":"ea5d2271464ca35f","prefixes":{"":{"product":929,"type":1}}}, // [Admetrics]
-  {"hash":"286ad0ac5bca5d03","prefixes":{"":{"product":930,"type":0}}}, // [Admetrics GmbH]
-  {"hash":"ff1ffc67b7e3f33a","prefixes":{"":{"product":931,"type":0}}}, // [Amobee Inc. d/b/a Gradient X]
-  {"hash":"72cbc5ba1ec93b34","prefixes":{"":{"product":931,"type":0}}}, // [Amobee Inc. d/b/a Gradient X]
-  {"hash":"a6fc31f82c22f31e","prefixes":{"":{"product":2,"type":0}}}, // [Action Exchange, Inc.]
-  {"hash":"1ba64e5bb4889fc8","prefixes":{"":{"product":2,"type":0}}}, // [Action Exchange, Inc.]
-  {"hash":"1d75cb11df01626e","prefixes":{"":{"product":2,"type":0}}}, // [Action Exchange, Inc.]
-  {"hash":"91e1e972e2691a51","prefixes":{"":{"product":2,"type":0}}}, // [Action Exchange, Inc.]
-  {"hash":"23c68afb7d193b79","prefixes":{"":{"product":2,"type":0}}}, // [Action Exchange, Inc.]
-  {"hash":"63d64a70ef1c102e","prefixes":{"":{"product":781,"type":0}}}, // [Recruit Co., Ltd. Communications]
-  {"hash":"5e5fd982d3646780","prefixes":{"":{"product":782,"type":0}}}, // [RECRUIT Communications]
-  {"hash":"405787e06ebc6f4c","prefixes":{"dc":{"product":932,"type":1}}}, // [Datalicious Pty Ltd]
-  {"hash":"cddbf4fe7458433c","prefixes":{"":{"product":932,"type":1}}}, // [Datalicious Pty Ltd]
-  {"hash":"1c6b7ff16564ebc9","prefixes":{"":{"product":932,"type":1}}}, // [Datalicious Pty Ltd]
-  {"hash":"8b00b076af37f543","prefixes":{"":{"product":932,"type":1}}}, // [Datalicious Pty Ltd]
-  {"hash":"688a0b3764e1741b","prefixes":{"":{"product":933,"type":1}}}, // [Intent Media]
-  {"hash":"04bba28fa6468b07","prefixes":{"":{"product":934,"type":0}}}, // [AdNear Pte Ltd.]
-  {"hash":"c10761fe93bddd5e","prefixes":{"":{"product":935,"type":1}}}, // [Zhejiang MediaAdx Network Technology Co., Ltd]
-  {"hash":"3b0fa4efa209ebfa","prefixes":{"":{"product":935,"type":1}}}, // [Zhejiang MediaAdx Network Technology Co., Ltd]
-  {"hash":"e1b43b2549b03858","prefixes":{"":{"product":936,"type":1}}}, // [Harris Interactive]
-  {"hash":"6ade6d73b73295b2","prefixes":{"":{"product":936,"type":1}}}, // [Harris Interactive]
-  {"hash":"63efa9155999d096","prefixes":{"":{"product":937,"type":0}}}, // [BuzzCity Pte Ltd]
-  {"hash":"564ef19eef7254cf","prefixes":{"":{"product":937,"type":0}}}, // [BuzzCity Pte Ltd]
-  {"hash":"6bbdf3ce8eec6f52","prefixes":{"":{"product":937,"type":0}}}, // [BuzzCity Pte Ltd]
-  {"hash":"436cc9ab781b357d","prefixes":{"":{"product":937,"type":0}}}, // [BuzzCity Pte Ltd]
-  {"hash":"e8cc8c7d43c80259","prefixes":{"":{"product":938,"type":0}}}, // [Sputnyx]
-  {"hash":"2150e4c3d0f193b2","prefixes":{"":{"product":938,"type":0}}}, // [Sputnyx]
-  {"hash":"54d8f3466d5879bc","prefixes":{"":{"product":938,"type":0}}}, // [Sputnyx]
-  {"hash":"b930b780e12735dc","prefixes":{"":{"product":938,"type":0}}}, // [Sputnyx]
-  {"hash":"5817597124959a0f","prefixes":{"":{"product":939,"type":0}}}, // [CyberZ, Inc]
-  {"hash":"52a82bf3bc55f753","prefixes":{"":{"product":940,"type":1}}}, // [Spark Networks USA, LLC]
-  {"hash":"de87290af2710dce","prefixes":{"*":{"product":941,"type":1}}}, // [Ezakus]
-  {"hash":"9fa7220a9c513b82","prefixes":{"":{"product":942,"type":0}}}, // [V4x SAS]
-  {"hash":"cdea2314328db64c","prefixes":{"":{"product":942,"type":0}}}, // [V4x SAS]
-  {"hash":"9ab122baee7ffef0","prefixes":{"":{"product":942,"type":0}}}, // [V4x SAS]
-  {"hash":"5b7763887f62f0e2","prefixes":{"":{"product":943,"type":0}}}, // [Tapjoy Inc.]
-  {"hash":"c476f40a640ceb50","prefixes":{"":{"product":19,"type":1}}}, // [Madeleine Mode GmbH]
-  {"hash":"b03d8c48bc51a903","prefixes":{"":{"product":19,"type":1}}}, // [Madeleine Mode GmbH]
-  {"hash":"6ccfc9d681f1cce4","prefixes":{"":{"product":19,"type":1}}}, // [Madeleine Mode GmbH]
-  {"hash":"519e706c784712cd","prefixes":{"":{"product":19,"type":1}}}, // [Madeleine Mode GmbH]
-  {"hash":"4b99f5579a32d2ac","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"7bb686f653faf750","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"59bac04b09eb1850","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"c7c593cac7252275","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"9a2642b29d01ad5a","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"19e7f2b697047d0f","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"9ccde0a8ec3f9703","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"a81ee6b474d31f53","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"3b743b2fda71dd5f","prefixes":{"":{"product":944,"type":0}}}, // [EXEBID]
-  {"hash":"6378b3090ceafcf5","prefixes":{"*":{"product":557,"type":0}}}, // [Bannerflow AB]
-  {"hash":"09de5d9c8a08a419","prefixes":{"":{"product":945,"type":0}}}, // [Exposebox Ltd]
-  {"hash":"d88faf97f4f01be0","prefixes":{"":{"product":945,"type":0}}}, // [Exposebox Ltd]
-  {"hash":"1b7a8075387597c8","prefixes":{"":{"product":945,"type":0}}}, // [Exposebox Ltd]
-  {"hash":"42127ec758c4891f","prefixes":{"":{"product":946,"type":0}}}, // [MotoMiner]
-  {"hash":"f5fe6be8ffc65b45","prefixes":{"":{"product":947,"type":0}}}, // [BuySellAds.com Inc.]
-  {"hash":"4b9190a98d317014","prefixes":{"":{"product":947,"type":0}}}, // [BuySellAds.com Inc.]
-  {"hash":"3b55d9e306cf9e3c","prefixes":{"":{"product":947,"type":0}}}, // [BuySellAds.com Inc.]
-  {"hash":"a9da15f40498a6f3","prefixes":{"":{"product":948,"type":0}}}, // [Viking River Cruises]
-  {"hash":"e2a8d45a4c55dae6","prefixes":{"":{"product":949,"type":0}}}, // [Sittercity Incorporated]
-  {"hash":"5dd667d71a34b766","prefixes":{"":{"product":950,"type":1}}}, // [Facetz]
-  {"hash":"00776ec1c54574db","prefixes":{"":{"product":951,"type":0}}}, // [YOOSE Pte. Ltd.]
-  {"hash":"f8c3b8f01c62da3c","prefixes":{"":{"product":952,"type":1}}}, // [AdYapper, Inc.]
-  {"hash":"6c1804db5b6679a9","prefixes":{"":{"product":952,"type":1}}}, // [AdYapper, Inc.]
-  {"hash":"a361de3d2fcba609","prefixes":{"":{"product":952,"type":1}}}, // [AdYapper, Inc.]
-  {"hash":"1f805f58db63a12d","prefixes":{"":{"product":952,"type":1}}}, // [AdYapper, Inc.]
-  {"hash":"7090e79d9ec26768","prefixes":{"":{"product":952,"type":1}}}, // [AdYapper, Inc.]
-  {"hash":"727b3d1100b7d374","prefixes":{"":{"product":952,"type":1}}}, // [AdYapper, Inc.]
-  {"hash":"17b396141b96c236","prefixes":{"":{"product":788,"type":1}}}, // [Webtrekk GmbH]
-  {"hash":"b0149857f43862d9","prefixes":{"":{"product":142,"type":0}}}, // [Spark Flow S.A.]
-  {"hash":"f9c00c55ede792e2","prefixes":{"":{"product":142,"type":0}}}, // [Spark Flow S.A.]
-  {"hash":"8eb24e3340b4c707","prefixes":{"":{"product":953,"type":0}}}, // [Clickky LLP DBA Clickky]
-  {"hash":"2d27319a70fb6262","prefixes":{"":{"product":953,"type":0}}}, // [Clickky LLP DBA Clickky]
-  {"hash":"b140173de591dc64","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"7e2351ba05fefcce","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"88a66ce20c2df5e5","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"705049ea1378adbd","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"eadabb19d68f0e02","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"684343b8f00b5425","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"fedb0d981d151071","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"eb26cb8958b84143","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"b4f42222ff48d611","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"3ef4c3e15c3889aa","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"346ac90e489a0d27","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"f0685c9d889a4dcb","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"d2ae279176821009","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"98746e3eb9075cc5","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"f4e7d8ca3f73252e","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"145b69a5570cf0e6","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"b96e6d8a02aabe0f","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"5f7def46ec1776af","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"075bdf0eaa8a2d8a","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"374ddadb8b59c656","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"e75f11f13cf01278","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"fa9f043b6f9f0225","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"51046da25aac136a","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"e3d9117eacb00b04","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"2291e11d2ca518c2","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"208af3ccccac3a8a","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"8a7e7a7c9510a539","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"d62dab4e5ba19318","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"9faead99b5b9e15b","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"21ad4e7e6897e7be","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"5f6e332f4f7ad081","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"28c87295fd99d9b2","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"ec4d1f8447f0f153","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"bcdb0c5a6199a121","prefixes":{"":{"product":954,"type":0}}}, // [eRate Online Measurement Solutions Ltd.]
-  {"hash":"dc1424820d5085bc","prefixes":{"":{"product":954,"type":0}}}, // [eRate Online Measurement Solutions Ltd.]
-  {"hash":"d110aae732b1c80d","prefixes":{"":{"product":954,"type":0}}}, // [eRate Online Measurement Solutions Ltd.]
-  {"hash":"d461527c3648da49","prefixes":{"":{"product":955,"type":2}}}, // [Baumann Ber Rivnay]
-  {"hash":"da8fb21c56d3c224","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"abb93e258191198a","prefixes":{"":{"product":3,"type":1}}}, // [TripAdvisor LLC]
-  {"hash":"67ce1b0bfa972cc4","prefixes":{"":{"product":956,"type":0}}}, // [TUI Connect GmbH]
-  {"hash":"63c1158e18a5ea27","prefixes":{"":{"product":957,"type":1}}}, // [INFOnline GmbH]
-  {"hash":"46a40e7a328ffee7","prefixes":{"":{"product":958,"type":0}}}, // [Adizio]
-  {"hash":"c5ca269d09b7c25f","prefixes":{"*":{"product":959,"type":1}}}, // [Joystick Interactive]
-  {"hash":"93d3775dcb79f65b","prefixes":{"":{"product":960,"type":0}}}, // [EngageClick Inc]
-  {"hash":"0af466da8ca75d0b","prefixes":{"":{"product":960,"type":0}}}, // [EngageClick Inc]
-  {"hash":"111ffa6b19238149","prefixes":{"":{"product":961,"type":0}}}, // [GeeeN, Inc.]
-  {"hash":"46313b1a2b164e11","prefixes":{"":{"product":961,"type":0}}}, // [GeeeN, Inc.]
-  {"hash":"edeaec47d1406cde","prefixes":{"":{"product":961,"type":0}}}, // [GeeeN, Inc.]
-  {"hash":"e4fa03e71e81c717","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"b05d395ad43a6851","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"babf6252b4c60056","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"db86fc0d97ddf866","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"ea61f7fa94bc2f36","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"495d58c312a856b7","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"ce854368c8ba8c24","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"7c1ebbe2aa48388d","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"0ac9c5956a237913","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"5e22bf81f1721d99","prefixes":{"":{"product":962,"type":1}}}, // [Arbigo Inc.]
-  {"hash":"ad1ab56f3a151112","prefixes":{"":{"product":963,"type":1}}}, // [FlxOne BV]
-  {"hash":"6c833f73351e1f63","prefixes":{"":{"product":963,"type":1}}}, // [FlxOne BV]
-  {"hash":"82f8d328de710cff","prefixes":{"":{"product":963,"type":1}}}, // [FlxOne BV]
-  {"hash":"95c33537789a441f","prefixes":{"":{"product":963,"type":1}}}, // [FlxOne BV]
-  {"hash":"712c817d06c0d8c6","prefixes":{"":{"product":963,"type":1}}}, // [FlxOne BV]
-  {"hash":"63446ae2652818ab","prefixes":{"":{"product":17}}}, // [eBay]
-  {"hash":"45b598cd3bc42672","prefixes":{"":{"product":964,"type":1}}}, // [ExtendTV, Inc.]
-  {"hash":"372fde25faa1c878","prefixes":{"":{"product":964,"type":1}}}, // [ExtendTV, Inc.]
-  {"hash":"db1da0ef7de3e1e6","prefixes":{"":{"product":965,"type":0}}}, // [momentM, Inc]
-  {"hash":"5710705dc9e3a971","prefixes":{"":{"product":965,"type":0}}}, // [momentM, Inc]
-  {"hash":"4ee3d75e96c8e3aa","prefixes":{"":{"product":965,"type":0}}}, // [momentM, Inc]
-  {"hash":"b329682f26e4fcc6","prefixes":{"":{"product":965,"type":0}}}, // [momentM, Inc]
-  {"hash":"71215c2931d79d35","prefixes":{"":{"product":965,"type":0}}}, // [momentM, Inc]
-  {"hash":"667a4fe4b59238b9","prefixes":{"":{"product":965,"type":0}}}, // [momentM, Inc]
-  {"hash":"a7fbeec4fb43f9d9","prefixes":{"*":{"product":966,"type":1}}}, // [OnCard Marketing dba RevTrax]
-  {"hash":"48a825a8c5ef9edd","prefixes":{"*":{"product":967}}}, // [Youtube - API]
-  {"hash":"19459fb447ce4de4","prefixes":{"*":{"product":968,"type":0}}}, // [Thirdpresence Ltd]
-  {"hash":"f079f0a998c56593","prefixes":{"":{"product":968,"type":0}}}, // [Thirdpresence Ltd]
-  {"hash":"108dd21ceba53008","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"7b0dec2d8c1ec967","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"b5c3f2f3c1c37850","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"ba9b4eca15987843","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"4e521b3e57d76700","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"29ab2715e00761b0","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"688071d177180274","prefixes":{"":{"product":969,"type":1}}}, // [Visual IQ, Inc.]
-  {"hash":"4e682c7f7f2ebda9","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"4b6451297bd74247","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"95d75ced1262ecda","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"ac94d70ffcad5c63","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"578591a9eb9652f2","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"5528666c72c7c71c","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"3deb1cd39233765c","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"4e05303df9f07532","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"99936e7e455c77b7","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"f0e5986dc65416fd","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"5095285a4ab05444","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"670fdb8ea86ee233","prefixes":{"":{"product":970,"type":0}}}, // [Appreciate]
-  {"hash":"ad2de628bc6fd483","prefixes":{"":{"product":971,"type":0},"lodeo-":{"product":972}}}, // [CyberAgent d/b/a GameLogic] [Lodeo]
-  {"hash":"66e26f9703f2dd67","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"80451e302607b653","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"bb7f7e8ab7b99724","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"51dbfc01b5f86601","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"2a8926ec16272a9b","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"4e2334aabf3b7af7","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"1bbabf05900a894f","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"a45a66788779b9bc","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"c4d101005526e2ef","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"7f43400e381d40ff","prefixes":{"":{"product":971,"type":0}}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"e323697c02e1a841","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"11c505e6e21eefdb","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"afc246433e1284d8","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"c7322cd1ad0df953","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"a090f61c3ee5e028","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"846ea0c461560421","prefixes":{"":{"product":972}}}, // [Lodeo]
-  {"hash":"b433db4fe5f6ed8d","prefixes":{"":{"product":974,"type":1}}}, // [LTD "RTB-MEDIA"]
-  {"hash":"e5b814009c134495","prefixes":{"":{"product":974,"type":1}}}, // [LTD "RTB-MEDIA"]
-  {"hash":"ce6b2c64ce23d14b","prefixes":{"":{"product":975,"type":0}}}, // [Maverick., inc.]
-  {"hash":"32ef8d9c49285e19","prefixes":{"":{"product":975,"type":0}}}, // [Maverick., inc.]
-  {"hash":"ac99e3b588f1d521","prefixes":{"":{"product":976,"type":0}}}, // [FuelX]
-  {"hash":"da9e2cf59b85610c","prefixes":{"":{"product":976,"type":0}}}, // [FuelX]
-  {"hash":"d86ff177f1095173","prefixes":{"":{"product":976,"type":0}}}, // [FuelX]
-  {"hash":"7853aedd1a267ffb","prefixes":{"":{"product":976,"type":0}}}, // [FuelX]
-  {"hash":"5f505217689c7174","prefixes":{"":{"product":976,"type":0}}}, // [FuelX]
-  {"hash":"27be294cbea039f9","prefixes":{"":{"product":976,"type":0}}}, // [FuelX]
-  {"hash":"bae6c7f50fff772d","prefixes":{"":{"product":976}}}, // [FuelX]
-  {"hash":"63f51428712678ec","prefixes":{"":{"product":320,"type":1}}}, // [Telstra Corporation]
-  {"hash":"f1d920cc5a16b3a9","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"12a7d7495eb7a91f","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"6ca28320c4765235","prefixes":{"":{"product":973,"type":0}}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"aeb171f5cad96320","prefixes":{"":{"product":977,"type":0}}}, // [Tutor.com]
-  {"hash":"5de1c09366f03919","prefixes":{"":{"product":162,"type":0}}}, // [wayStorm Co., Ltd.]
-  {"hash":"9977349a2c52c1b6","prefixes":{"":{"product":162,"type":0}}}, // [wayStorm Co., Ltd.]
-  {"hash":"3304d732f88c9ebe","prefixes":{"":{"product":162,"type":0}}}, // [wayStorm Co., Ltd.]
-  {"hash":"8b1b0e966a643448","prefixes":{"":{"product":162,"type":0}}}, // [wayStorm Co., Ltd.]
-  {"hash":"852a445ec03b1224","prefixes":{"":{"product":978,"type":0}}}, // [Rebelmouse]
-  {"hash":"ebef84a02e75b037","prefixes":{"*":{"product":978,"type":0}}}, // [Rebelmouse]
-  {"hash":"6ff0ad7b4d4ee2ef","prefixes":{"":{"product":979,"type":0}}}, // [Adviator DSP]
-  {"hash":"c28458e1bac3bb75","prefixes":{"":{"product":979,"type":0}}}, // [Adviator DSP]
-  {"hash":"041403702e0ae9f0","prefixes":{"":{"product":979,"type":0}}}, // [Adviator DSP]
-  {"hash":"31890d74ba2e0eca","prefixes":{"":{"product":520,"type":0}}}, // [abilicom GmbH]
-  {"hash":"16f2a07aea3c767b","prefixes":{"":{"product":980}}}, // [Acens Technologies, S.L.]
-  {"hash":"4d628548402f2933","prefixes":{"":{"product":981,"type":0}}}, // [Yashi, Inc]
-  {"hash":"6f97eb7dc578c1d3","prefixes":{"":{"product":669,"type":0}}}, // [Taptica]
-  {"hash":"843cc26d64f855e3","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"7f81eef44c27fceb","prefixes":{"":{"product":490,"type":0}}}, // [Miaozhen Systems]
-  {"hash":"f36b5e4d896bf9fc","prefixes":{"":{"product":982,"type":0}}}, // [Flaminem Inc]
-  {"hash":"ec10935d7141abb2","prefixes":{"":{"product":983,"type":0}}}, // [Mediahead AG]
-  {"hash":"d074e5017286d25a","prefixes":{"":{"product":983,"type":0}}}, // [Mediahead AG]
-  {"hash":"e7aa39274c05edf9","prefixes":{"":{"product":983,"type":0}}}, // [Mediahead AG]
-  {"hash":"06d3dae2f13a3dcb","prefixes":{"":{"product":983,"type":0}}}, // [Mediahead AG]
-  {"hash":"1cc1098f16d364e0","prefixes":{"":{"product":983,"type":0}}}, // [Mediahead AG]
-  {"hash":"15ee5953d4c74d48","prefixes":{"":{"product":983,"type":0}}}, // [Mediahead AG]
-  {"hash":"b434b094029a84a8","prefixes":{"":{"product":984,"type":0}}}, // [Admixer]
-  {"hash":"766b3c24fb448820","prefixes":{"":{"product":985,"type":1}}}, // [Communication Services Tele2 GmbH]
-  {"hash":"35e369c14d37cb1c","prefixes":{"*":{"product":986,"type":1}}}, // [99click]
-  {"hash":"c5b7e1faef274865","prefixes":{"":{"product":987,"type":0}}}, // [Ströer Mobile Media GmbH]
-  {"hash":"dc01aead4f784e4d","prefixes":{"":{"product":987,"type":0}}}, // [Ströer Mobile Media GmbH]
-  {"hash":"39525c5c19a8a044","prefixes":{"":{"product":987,"type":0}}}, // [Ströer Mobile Media GmbH]
-  {"hash":"397c77c97b7945f8","prefixes":{"":{"product":987,"type":0}}}, // [Ströer Mobile Media GmbH]
-  {"hash":"3097a79ab689b320","prefixes":{"":{"product":987,"type":0}}}, // [Ströer Mobile Media GmbH]
-  {"hash":"c27b66085df0c0da","prefixes":{"":{"product":988,"type":0}}}, // [LLC "Life Style"]
-  {"hash":"3a7913ff0ce0cc21","prefixes":{"":{"product":988,"type":0}}}, // [LLC "Life Style"]
-  {"hash":"9d1661dae6ff9304","prefixes":{"":{"product":988,"type":0}}}, // [LLC "Life Style"]
-  {"hash":"cdd266d878d3e9d5","prefixes":{"":{"product":988,"type":0}}}, // [LLC "Life Style"]
-  {"hash":"d3c08bf02865217e","prefixes":{"":{"product":989,"type":0}}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"bbfe70399cd3fcb3","prefixes":{"":{"product":989,"type":0}}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"a17b33aa94234849","prefixes":{"":{"product":989,"type":0}}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"8e073ea44074ec93","prefixes":{"":{"product":989,"type":0}}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"12afa442e09a07c9","prefixes":{"":{"product":989,"type":0}}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"7fa5ca05a3a0b474","prefixes":{"":{"product":990,"type":0}}}, // [Platform IQ]
-  {"hash":"f6f0f65947909d69","prefixes":{"":{"product":990,"type":0}}}, // [Platform IQ]
-  {"hash":"77b586602e5dec3f","prefixes":{"":{"product":990,"type":0}}}, // [Platform IQ]
-  {"hash":"bba327f348a4693e","prefixes":{"":{"product":990,"type":0}}}, // [Platform IQ]
-  {"hash":"a544a3b25c4d5113","prefixes":{"":{"product":991,"type":0}}}, // [Silveredge Inc]
-  {"hash":"037cb4c9598870ee","prefixes":{"":{"product":991,"type":0}}}, // [Silveredge Inc]
-  {"hash":"2a6ed7c1b6a78509","prefixes":{"":{"product":991,"type":0}}}, // [Silveredge Inc]
-  {"hash":"06d23751a7963710","prefixes":{"":{"product":992,"type":0}}}, // [SMADEX]
-  {"hash":"0a84ed2865a74b8a","prefixes":{"":{"product":992,"type":0}}}, // [SMADEX]
-  {"hash":"e97a828dc740d645","prefixes":{"":{"product":992,"type":0}}}, // [SMADEX]
-  {"hash":"aa964a10a9ccda5b","prefixes":{"":{"product":992,"type":0}}}, // [SMADEX]
-  {"hash":"d7675b344c153db3","prefixes":{"":{"product":992,"type":0}}}, // [SMADEX]
-  {"hash":"76eaf06fcd95e8e8","prefixes":{"":{"product":993,"type":0}}}, // [Suzu Muchi]
-  {"hash":"fcf26d7eec95d72d","prefixes":{"":{"product":994,"type":0}}}, // [LOKA Research inc.]
-  {"hash":"3b238a232cbc26bd","prefixes":{"":{"product":994,"type":0}}}, // [LOKA Research inc.]
-  {"hash":"a544c76e7ec01862","prefixes":{"":{"product":994,"type":0}}}, // [LOKA Research inc.]
-  {"hash":"7922cb2f11972c85","prefixes":{"":{"product":994,"type":0}}}, // [LOKA Research inc.]
-  {"hash":"060ee4c312a8e977","prefixes":{"":{"product":994,"type":0}}}, // [LOKA Research inc.]
-  {"hash":"d4a0ad756fe236b8","prefixes":{"":{"product":995}}}, // [Edgesuite]
-  {"hash":"613551ec99bec944","prefixes":{"":{"product":996,"type":0}}}, // [PlannTo Technologies Private Limited]
-  {"hash":"bb07eb5de3d95038","prefixes":{"":{"product":996,"type":0}}}, // [PlannTo Technologies Private Limited]
-  {"hash":"729165b2ebbc6996","prefixes":{"":{"product":996,"type":0}}}, // [PlannTo Technologies Private Limited]
-  {"hash":"187629571e0338cf","prefixes":{"":{"product":996,"type":0}}}, // [PlannTo Technologies Private Limited]
-  {"hash":"bdd2e20221d7e507","prefixes":{"":{"product":997,"type":1}}}, // [Viator, Inc]
-  {"hash":"1caf0cb7a05c5941","prefixes":{"":{"product":469,"type":0}}}, // [Xrost]
-  {"hash":"4c6513300966da08","prefixes":{"":{"product":998,"type":1}}}, // [NODDINGTON TECHNOLOGIES LIMITED]
-  {"hash":"2c1d6a203788af2b","prefixes":{"":{"product":999,"type":0}}}, // [Plan Blue Ltd]
-  {"hash":"3c0da2d4356e18a5","prefixes":{"":{"product":999,"type":0}}}, // [Plan Blue Ltd]
-  {"hash":"2568d0917d238964","prefixes":{"":{"product":1000,"type":0}}}, // [Addictive Mobility]
-  {"hash":"f79c822ab2cca8ee","prefixes":{"":{"product":1000,"type":0}}}, // [Addictive Mobility]
-  {"hash":"c610b5ae3df923cd","prefixes":{"":{"product":1000,"type":0}}}, // [Addictive Mobility]
-  {"hash":"a614ab43bf2d906b","prefixes":{"":{"product":1000,"type":0}}}, // [Addictive Mobility]
-  {"hash":"747eeca86822f19c","prefixes":{"":{"product":1001,"type":1}}}, // [A6 Corporation]
-  {"hash":"cbdfdaeff8b7d933","prefixes":{"":{"product":1002,"type":0}}}, // [Mobusi Mobile Advertising]
-  {"hash":"5b2d082c7811bead","prefixes":{"":{"product":1003,"type":0}}}, // [Wishabi]
-  {"hash":"c811726b56670631","prefixes":{"":{"product":1003,"type":0}}}, // [Wishabi]
-  {"hash":"09d3b27d380d43a0","prefixes":{"":{"product":1003,"type":0}}}, // [Wishabi]
-  {"hash":"eecab68f555d1f9f","prefixes":{"":{"product":1004,"type":0}}}, // [onAd GmbH]
-  {"hash":"d05b20f38e3bb984","prefixes":{"":{"product":1005,"type":0}}}, // [Media Decision GmbH]
-  {"hash":"4a9b8dddd4c7567c","prefixes":{"":{"product":1005,"type":0}}}, // [Media Decision GmbH]
-  {"hash":"5121142c1b8676fd","prefixes":{"":{"product":1005,"type":0}}}, // [Media Decision GmbH]
-  {"hash":"e083b93d5a87c743","prefixes":{"":{"product":1006,"type":1}}}, // [Unitymedia NRW]
-  {"hash":"c665046a783daa9d","prefixes":{"":{"product":1007,"type":0}}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"663d5fdbc3a52729","prefixes":{"":{"product":1007,"type":0}}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"991e96310871571b","prefixes":{"":{"product":1007,"type":0}}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"0503d775704af4a2","prefixes":{"":{"product":1007,"type":0}}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"2c55a4ef41531200","prefixes":{"":{"product":1008,"type":0}}}, // [Avis]
-  {"hash":"62817a7d196cbdcf","prefixes":{"":{"product":1009,"type":0}}}, // [Comcast]
-  {"hash":"2e4bb1f4d07f3180","prefixes":{"":{"product":1010,"type":0}}}, // [Jack Spade]
-  {"hash":"e7d369c24971784a","prefixes":{"":{"product":1011,"type":0}}}, // [Dollar General]
-  {"hash":"a8c9b93aae571ed5","prefixes":{"":{"product":1012,"type":0}}}, // [Care.com]
-  {"hash":"713775b7bc737116","prefixes":{"":{"product":1013,"type":0}}}, // [Clickagy, LLC]
-  {"hash":"8b6b45c1c86cd84b","prefixes":{"":{"product":1013,"type":0}}}, // [Clickagy, LLC]
-  {"hash":"34376185507c9ae0","prefixes":{"":{"product":1014,"type":1}}}, // [GlobalWebIndex]
-  {"hash":"8b17254892b590e3","prefixes":{"":{"product":1015,"type":0}}}, // [King.com]
-  {"hash":"8516f044f19bb3ae","prefixes":{"":{"product":1015,"type":0}}}, // [King.com]
-  {"hash":"d811179454fad251","prefixes":{"":{"product":1015,"type":0}}}, // [King.com]
-  {"hash":"946611fa2f4b067a","prefixes":{"":{"product":1016,"type":1}}}, // [Proquire LLC - Accenture]
-  {"hash":"cfa0e9025fcd5712","prefixes":{"":{"product":1017,"type":0}}}, // [Dynamic Yield]
-  {"hash":"b01c0239af74e72e","prefixes":{"":{"product":1017,"type":0}}}, // [Dynamic Yield]
-  {"hash":"e480d03a980d3bfc","prefixes":{"":{"product":1017,"type":0}}}, // [Dynamic Yield]
-  {"hash":"f22fe7e17c58b562","prefixes":{"":{"product":1017,"type":0}}}, // [Dynamic Yield]
-  {"hash":"f8da77c2fdcad106","prefixes":{"":{"product":1017,"type":0}}}, // [Dynamic Yield]
-  {"hash":"cea3bf4afe576984","prefixes":{"":{"product":1018,"type":0}}}, // [Charter business]
-  {"hash":"f8029c009186163f","prefixes":{"":{"product":1019,"type":1}}}, // [The ADEX]
-  {"hash":"61b09f5d40722e69","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"aa63151485efa109","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"ed37e98f45f10404","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"f9fda879239cf155","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"2dfe9124b3439d80","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"93a9e29ac238b380","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"5e080b13877f5de7","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"eb22d59d4594e6d3","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"a28e072f804db6a0","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"945f948eacea62c9","prefixes":{"":{"product":1020,"type":0}}}, // [OneDigitalAd Technologies]
-  {"hash":"b85074a47da33b83","prefixes":{"":{"product":1021,"type":0}}}, // [ADJUST]
-  {"hash":"9f369deb4f045364","prefixes":{"":{"product":1021,"type":0}}}, // [ADJUST]
-  {"hash":"2d6ceeb3eef38c27","prefixes":{"":{"product":1021,"type":0}}}, // [ADJUST]
-  {"hash":"65240dfe37410021","prefixes":{"":{"product":1021,"type":0}}}, // [ADJUST]
-  {"hash":"8d3dfcbf705f1191","prefixes":{"":{"product":1021,"type":0}}}, // [ADJUST]
-  {"hash":"a2d35afc9c960448","prefixes":{"":{"product":1022,"type":1}}}, // [ADmantX, SPA]
-  {"hash":"3d3bc7f00b0ef8d3","prefixes":{"":{"product":1023,"type":0}}}, // [Sogou.com]
-  {"hash":"9eb0737a130a6f08","prefixes":{"":{"product":1024,"type":0}}}, // [xAd, Inc.]
-  {"hash":"a9ff22250a3c29a1","prefixes":{"":{"product":1025,"type":0}}}, // [VideoBlocks]
-  {"hash":"61f27a00f3821730","prefixes":{"":{"product":1026,"type":0}}}, // [GraphicStocks]
-  {"hash":"f0792974945e7184","prefixes":{"":{"product":1027,"type":1}}}, // [Microsoft Advertising]
-  {"hash":"81f27cb33d47894b","prefixes":{"":{"product":1028,"type":0}}}, // [Rontar LTD]
-  {"hash":"e8ae13fee2796336","prefixes":{"":{"product":1028,"type":0}}}, // [Rontar LTD]
-  {"hash":"d979ed3048a9dc3d","prefixes":{"":{"product":1028,"type":0}}}, // [Rontar LTD]
-  {"hash":"187c7e948b323b3a","prefixes":{"dsp":{"product":1028,"type":0}}}, // [Rontar LTD]
-  {"hash":"1a5cfb3f08b31682","prefixes":{"":{"product":1029,"type":0}}}, // [Torrential, Inc.]
-  {"hash":"99bb29582234b47b","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"14a0b2d821feb403","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"4bfb576f457b3ad4","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"d2e32e6a4c73344a","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"3c8aa320c0f5fb9d","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"8c3cae9472fcd43a","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"18d673cc147eaba5","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"fb4f3dd591cba22f","prefixes":{"bid":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"49aef0b488ab5024","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"2b7a17458f44228d","prefixes":{"":{"product":1030,"type":0}}}, // [AMoAd, Inc.]
-  {"hash":"7458cceedc9f812a","prefixes":{"":{"product":1031,"type":0}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"dd47f178c7a055b8","prefixes":{"":{"product":1031,"type":0}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"db975b73da86c8ce","prefixes":{"":{"product":1031,"type":0}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"6216946891299e23","prefixes":{"":{"product":1031,"type":0}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"52ee7c22862a74b6","prefixes":{"":{"product":1031,"type":0}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"3cc39e801c92ea89","prefixes":{"":{"product":1032,"type":0}}}, // [Jampp/Devego S.A.]
-  {"hash":"31fb8bdf6d2b85d2","prefixes":{"":{"product":1033,"type":1}}}, // [Placed]
-  {"hash":"a6ff57032773fe41","prefixes":{"*":{"product":1034,"type":1}}}, // [Digitas Health]
-  {"hash":"caeb7a071a866e17","prefixes":{"*":{"product":1034,"type":1}}}, // [Digitas Health]
-  {"hash":"6e946f5fac72b0b4","prefixes":{"":{"product":1035,"type":0}}}, // [Answer Media, LLC]
-  {"hash":"31c3d7ef1499fd26","prefixes":{"":{"product":1035,"type":0}}}, // [Answer Media, LLC]
-  {"hash":"d681f06391c7f861","prefixes":{"":{"product":1036,"type":1}}}, // [1000mercis]
-  {"hash":"1549387212aaa6a3","prefixes":{"":{"product":1037,"type":0}}}, // [Upstart Network, Inc.]
-  {"hash":"e48f63d27d0c24c7","prefixes":{"":{"product":1038,"type":1}}}, // [Forensiq, LLC]
-  {"hash":"7579b1341b228f93","prefixes":{"":{"product":1038,"type":1}}}, // [Forensiq, LLC]
-  {"hash":"f2e570ecd2540399","prefixes":{"":{"product":1039,"type":0}}}, // [LoopMe Ltd]
-  {"hash":"7d4e3b90001a044e","prefixes":{"":{"product":1039,"type":0}}}, // [LoopMe Ltd]
-  {"hash":"528167a286d8ccf8","prefixes":{"":{"product":1040,"type":0}}}, // [Bannerlink (Liquidus)]
-  {"hash":"0b2d528c0dce5bba","prefixes":{"":{"product":1040,"type":0}}}, // [Bannerlink (Liquidus)]
-  {"hash":"758cc459053712cf","prefixes":{"":{"product":1040,"type":0}}}, // [Bannerlink (Liquidus)]
-  {"hash":"57951d4b34add1a9","prefixes":{"":{"product":1040,"type":0}}}, // [Bannerlink (Liquidus)]
-  {"hash":"3d93ddd2b1dc8083","prefixes":{"":{"product":1040,"type":0}}}, // [Bannerlink (Liquidus)]
-  {"hash":"88f0b992c4b99c65","prefixes":{"":{"product":1041,"type":1}}}, // [Dell Inc.]
-  {"hash":"f8820430b42f89f8","prefixes":{"":{"product":1042,"type":0}}}, // [My Perfect Resume]
-  {"hash":"6f018db6d7a12f5e","prefixes":{"":{"product":1043,"type":0}}}, // [Ajillion Max Ltd]
-  {"hash":"b591ab0baccecd52","prefixes":{"":{"product":1043,"type":0}}}, // [Ajillion Max Ltd]
-  {"hash":"35d86d0121dbd41a","prefixes":{"":{"product":1044,"type":0}}}, // [Swelen France SA.]
-  {"hash":"25b09dd0e8d2977a","prefixes":{"":{"product":1044,"type":0}}}, // [Swelen France SA.]
-  {"hash":"f5cb853eba61193a","prefixes":{"":{"product":1045,"type":0}}}, // [Sleeptrain]
-  {"hash":"c620109c65610aeb","prefixes":{"":{"product":1046,"type":0}}}, // [Sleepcountry]
-  {"hash":"9c6554ebebdbfa08","prefixes":{"":{"product":1047,"type":0}}}, // [Hoover]
-  {"hash":"f34ddb2b65330794","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"5d9eb2a8dc1a1687","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"e2207dc37f1b89e8","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"682ec1b47db930b9","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"638a2c2dc53d2ab7","prefixes":{"":{"product":1049,"type":0}}}, // [Mocoplex Inc.]
-  {"hash":"ee330ed89897a55c","prefixes":{"":{"product":1049,"type":0}}}, // [Mocoplex Inc.]
-  {"hash":"60ab035f28a35e30","prefixes":{"":{"product":1049,"type":0}}}, // [Mocoplex Inc.]
-  {"hash":"5929f2c289d9e073","prefixes":{"":{"product":767,"type":0}}}, // [Gruvi Ltd.]
-  {"hash":"c16c02248018a374","prefixes":{"":{"product":767,"type":0}}}, // [Gruvi Ltd.]
-  {"hash":"e6eb2d1c03d2be83","prefixes":{"":{"product":767,"type":0}}}, // [Gruvi Ltd.]
-  {"hash":"95fa4396cadc336e","prefixes":{"":{"product":767,"type":0}}}, // [Gruvi Ltd.]
-  {"hash":"2604a7d96f168c84","prefixes":{"":{"product":1050,"type":0}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"294fdebfd41771a8","prefixes":{"":{"product":1050,"type":0}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"c6beb451fe4c58c2","prefixes":{"":{"product":1050,"type":0}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"b0f5f51210e6f2af","prefixes":{"":{"product":1050,"type":0}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"ab3da2eb1a35cba6","prefixes":{"":{"product":1051,"type":0}}}, // [Verengo Solar]
-  {"hash":"c3bf5a10743772ec","prefixes":{"*":{"product":1052,"type":0}}}, // [Mobile Professionals BV]
-  {"hash":"d22325b6d6b04918","prefixes":{"*":{"product":1053,"type":1}}}, // [APNIC Pty Ltd]
-  {"hash":"27966131215e508a","prefixes":{"*":{"product":1053,"type":1}}}, // [APNIC Pty Ltd]
-  {"hash":"80022b9d8ddaffde","prefixes":{"*":{"product":1053,"type":1}}}, // [APNIC Pty Ltd]
-  {"hash":"9352d77ba286c03d","prefixes":{"":{"product":1054,"type":0}}}, // [Dun and Bradstreet Corporation]
-  {"hash":"74b7ef01f42d93ee","prefixes":{"":{"product":1055,"type":0}}}, // [UpToLike]
-  {"hash":"f2a78bb802dc4abd","prefixes":{"":{"product":1055,"type":0}}}, // [UpToLike]
-  {"hash":"f885798eaaace647","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"3bc813f113908f06","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"e1a6852c86da418c","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"0343b65d010db4b2","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"a9b74e1bcb339dd0","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"e8d325d7be0f046b","prefixes":{"*":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"f7ccb1753b9ae2ed","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"4a96db729cb9dd47","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"afde8c2ebcc380c8","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"05840eb3ff4432a8","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"3e5f0f83b0e34391","prefixes":{"":{"product":1056,"type":0}}}, // [Mobile360 Sdn Bhd]
-  {"hash":"f79fe1474c475ade","prefixes":{"":{"product":1057,"type":0}}}, // [Elite Fixtures]
-  {"hash":"b8b63e29130d798a","prefixes":{"":{"product":1058,"type":0}}}, // [Advanse Ads]
-  {"hash":"662442a875d5ae62","prefixes":{"":{"product":1058,"type":0}}}, // [Advanse Ads]
-  {"hash":"d8487e4c88a21c7f","prefixes":{"":{"product":1058,"type":0}}}, // [Advanse Ads]
-  {"hash":"37694729baf29aa5","prefixes":{"":{"product":1059,"type":0}}}, // [Insurance Step]
-  {"hash":"0153c16587a0c97c","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"c7bcca7e8dc820fe","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"2176b8c755bbab42","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"1979b33f68eb0ded","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"32a9ea6936225587","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"16fec67040bf3ff7","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"ed89b325a7c3ac6d","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"ae3bc4690ef89e8d","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"ed9a2a4f49ad4647","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"398d36669a77aca6","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"5bf9c0f450f9eb14","prefixes":{"":{"product":1060,"type":1}}}, // [Causal Impact]
-  {"hash":"30e7de1e277c7698","prefixes":{"":{"product":143,"type":0}}}, // [Aarki, Inc.]
-  {"hash":"888d9446d621d82f","prefixes":{"":{"product":143,"type":0}}}, // [Aarki, Inc.]
-  {"hash":"3061a4cd653ea2dc","prefixes":{"*":{"product":1061,"type":0}}}, // [Pixnet]
-  {"hash":"06daa5b82ebfa413","prefixes":{"":{"product":1062,"type":0}}}, // [Zapp360]
-  {"hash":"6f0f9a90c798715d","prefixes":{"":{"product":1063,"type":0}}}, // [Kijiji]
-  {"hash":"0259cba89f8f9676","prefixes":{"":{"product":1064,"type":0}}}, // [Spotad LTD.]
-  {"hash":"0ca2babbaeeca3bf","prefixes":{"":{"product":1064,"type":0}}}, // [Spotad LTD.]
-  {"hash":"e9a9d4fd1b468042","prefixes":{"":{"product":1064,"type":0}}}, // [Spotad LTD.]
-  {"hash":"6a79ac93cddc0cc5","prefixes":{"":{"product":1064,"type":0}}}, // [Spotad LTD.]
-  {"hash":"685b17838f2d9b82","prefixes":{"":{"product":1065,"type":0}}}, // [Go Daddy]
-  {"hash":"aa66f01be33256d0","prefixes":{"":{"product":1066,"type":1}}}, // [Bilendi]
-  {"hash":"3b8dfd79ab921d9b","prefixes":{"":{"product":1067,"type":0}}}, // [Hitokuse]
-  {"hash":"1992e397e0dff18d","prefixes":{"":{"product":1067,"type":0}}}, // [Hitokuse]
-  {"hash":"03eb230cd9f67c73","prefixes":{"":{"product":1067,"type":0}}}, // [Hitokuse]
-  {"hash":"0a75c26f5c580b3a","prefixes":{"*":{"product":1068,"type":0}}}, // [MGID Inc.]
-  {"hash":"4466d73d5d5dce19","prefixes":{"*":{"product":1068,"type":0}}}, // [MGID Inc.]
-  {"hash":"10bfb2327400e2ea","prefixes":{"":{"product":1068,"type":0}}}, // [MGID Inc.]
-  {"hash":"121b77f4b4412c85","prefixes":{"":{"product":1068,"type":0}}}, // [MGID Inc.]
-  {"hash":"e46ec8aa62f3f432","prefixes":{"":{"product":1069,"type":0}}}, // [AreaOne]
-  {"hash":"9849db4d4a694f16","prefixes":{"t":{"product":1070,"type":0},"s":{"product":1070,"type":0},"sna":{"product":1070,"type":0}}}, // [DynAd] [DynAd] [DynAd]
-  {"hash":"5fc0aef37d5fffca","prefixes":{"":{"product":1071,"type":0}}}, // [Loop Pay]
-  {"hash":"4cc75be32553222a","prefixes":{"":{"product":1072,"type":0}}}, // [Remerge GmbH]
-  {"hash":"b1a90d2aaa32932c","prefixes":{"":{"product":1072,"type":0}}}, // [Remerge GmbH]
-  {"hash":"3bea81bc90640751","prefixes":{"":{"product":1073,"type":1}}}, // [Audience Trading Platform LTD]
-  {"hash":"d193540bb7540e5c","prefixes":{"":{"product":1074,"type":0}}}, // [Whisla]
-  {"hash":"abd1c2a37733128b","prefixes":{"":{"product":1074,"type":0}}}, // [Whisla]
-  {"hash":"9546fe15199cbce1","prefixes":{"":{"product":1074,"type":0}}}, // [Whisla]
-  {"hash":"f43c40d1949f2c52","prefixes":{"":{"product":1075,"type":0}}}, // [Bridgevine]
-  {"hash":"28577f7c17c55b0f","prefixes":{"":{"product":1076,"type":1}}}, // [ADgraph DMP]
-  {"hash":"fa0c51dc55faddc6","prefixes":{"":{"product":1077,"type":0}}}, // [Gravity4 Inc.]
-  {"hash":"6dea119c4c95aaa8","prefixes":{"":{"product":1077,"type":0}}}, // [Gravity4 Inc.]
-  {"hash":"79b4752426dedd83","prefixes":{"":{"product":1078,"type":0}}}, // [Hipmunk]
-  {"hash":"ccba9f3966eabe6b","prefixes":{"*":{"product":1079,"type":0}}}, // [VideoHub DSP]
-  {"hash":"a6baef75f126450e","prefixes":{"":{"product":1080,"type":1}}}, // [DuMedia]
-  {"hash":"cf45efd3feda1ba3","prefixes":{"":{"product":1080,"type":1}}}, // [DuMedia]
-  {"hash":"efebf8c1ea6bab87","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"a866ff2bfe3133e7","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"49b89555382dac9e","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"e2d2b1537271ff61","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"5804e7cf2cdbbda0","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"db0ef2b4eff25274","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"d960535fd30704f8","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"258915df4406fd06","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"b34a1e3fd51aadb9","prefixes":{"":{"product":1081,"type":0}}}, // [F@N Communications, Inc.]
-  {"hash":"c0ad7ec6e1d46299","prefixes":{"":{"product":1082,"type":0}}}, // [VIVALU GmbH]
-  {"hash":"65c049a517720b5c","prefixes":{"":{"product":1082,"type":0}}}, // [VIVALU GmbH]
-  {"hash":"b60b2426028baba5","prefixes":{"":{"product":1083,"type":0}}}, // [Advertising Technologies LTD]
-  {"hash":"6d2df95e2bf52046","prefixes":{"":{"product":1083,"type":0}}}, // [Advertising Technologies LTD]
-  {"hash":"b4ad6ea6ca336f55","prefixes":{"":{"product":1083,"type":0}}}, // [Advertising Technologies LTD]
-  {"hash":"b750311cbd5c4013","prefixes":{"":{"product":1084,"type":1}}}, // [Authenticated Digital Inc]
-  {"hash":"aa634a3d8862b3be","prefixes":{"":{"product":1084,"type":1}}}, // [Authenticated Digital Inc]
-  {"hash":"361eefdfa29ada10","prefixes":{"":{"product":1085,"type":0}}}, // [PaeDae, Inc., DBA The Mobile Majority]
-  {"hash":"8a5c2c8d21fc6dd4","prefixes":{"":{"product":1085,"type":0}}}, // [PaeDae, Inc., DBA The Mobile Majority]
-  {"hash":"13b3d2e0ed78e518","prefixes":{"":{"product":1086,"type":0}}}, // [METROPCS]
-  {"hash":"c9b29fe277a47b8d","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"60f32eaa9335e4b9","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"c8f49035cb273e42","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"92d9e360f16ecdc9","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"2d3b5566afb5350b","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"0ca3b2088de2514c","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"67da96d5ae99faa0","prefixes":{"":{"product":1087,"type":0}}}, // [PapayaMobile Inc.]
-  {"hash":"347e898491d027ee","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"ae3f27ad4a4f2f7d","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"cd0c8a5dd793ee52","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"451f4083f03028e0","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"e1b048e4fa37eef2","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"837ae92d9cf6b933","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"6ae82aac87db94d3","prefixes":{"":{"product":1088,"type":0}}}, // [Raumfeld]
-  {"hash":"84ddfa5a2e93cb69","prefixes":{"":{"product":1089,"type":0}}}, // [GREE Ads DSP]
-  {"hash":"a7201f5a80824242","prefixes":{"":{"product":1089,"type":0}}}, // [GREE Ads DSP]
-  {"hash":"2ec22ca05310362a","prefixes":{"":{"product":1090,"type":0}}}, // [Tender Industries AB]
-  {"hash":"d159abbaeda22e7c","prefixes":{"":{"product":1091,"type":1}}}, // [BySide]
-  {"hash":"426783d6fe8d039e","prefixes":{"":{"product":1092,"type":1}}}, // [Sentrant Security Inc.]
-  {"hash":"d270ad50bb53fb01","prefixes":{"":{"product":1092,"type":1}}}, // [Sentrant Security Inc.]
-  {"hash":"49c693058534be83","prefixes":{"":{"product":1093,"type":0}}}, // [Locon Solutions Pvt. Ltd.]
-  {"hash":"a2b9f627da8737de","prefixes":{"":{"product":1094,"type":1}}}, // [Interrogare GmbH]
-  {"hash":"13b73169540642e5","prefixes":{"":{"product":1094,"type":1}}}, // [Interrogare GmbH]
-  {"hash":"afaa106d11846fa4","prefixes":{"*":{"product":1095,"type":1}}}, // [ChannelAdvisor]
-  {"hash":"b8b4eadeb5d3a123","prefixes":{"":{"product":1096,"type":0}}}, // [VideoAmp]
-  {"hash":"43546e9f6ff5bf2a","prefixes":{"":{"product":1096,"type":0}}}, // [VideoAmp]
-  {"hash":"61a9edb9af3769cf","prefixes":{"":{"product":1096,"type":0}}}, // [VideoAmp]
-  {"hash":"f76b3fe7048e93e2","prefixes":{"":{"product":1096,"type":0}}}, // [VideoAmp]
-  {"hash":"57263424c0e88a92","prefixes":{"track":{"product":1097,"type":0}}}, // [The Bridge]
-  {"hash":"516e9fc5ede4af0d","prefixes":{"":{"product":1097,"type":0}}}, // [The Bridge]
-  {"hash":"6bc0303a4262cb67","prefixes":{"":{"product":1097,"type":0}}}, // [The Bridge]
-  {"hash":"30a32fe2a89dccd8","prefixes":{"":{"product":1098,"type":0}}}, // [Pharmaca Integrative Pharmacy]
-  {"hash":"7881da604383a640","prefixes":{"":{"product":666,"type":0}}}, // [Videology DSP]
-  {"hash":"dec02c663bb06094","prefixes":{"":{"product":1099,"type":0}}}, // [Scrutineer]
-  {"hash":"6e2098af577c671d","prefixes":{"":{"product":1100,"type":1}}}, // [TF1 - FR]
-  {"hash":"60774075776e2612","prefixes":{"":{"product":1101,"type":0}}}, // [Core Digital]
-  {"hash":"79a775eea6a902e6","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"c0576db5cf4ba20b","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"d90fda985e3fb6bf","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"ee49dcf9326e853f","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"5b3c6abcd44de720","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"f97a320480541a27","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"57fc36302e0bde3c","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"736a8a8a0cef7bdf","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"36263b4a0d607a71","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"226480bf58f4fd1c","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"58379bd623597d70","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"f68e3a544a7397be","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"0f2880d71794e516","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"4ef52741fc1ade73","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"97d6a93635d72af0","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"ab75a46dc8bf2c1e","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"efeb8f966db03b87","prefixes":{"":{"product":109,"type":0}}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"2a4d804c0fb397c1","prefixes":{"":{"product":1102,"type":0}}}, // [Adventive, Inc.]
-  {"hash":"29d370caa59b4ecc","prefixes":{"":{"product":1102,"type":0}}}, // [Adventive, Inc.]
-  {"hash":"a06632ec1be82319","prefixes":{"":{"product":1103}}}, // [Turner Sports Interactive, Inc.]
-  {"hash":"bf10e40bae047225","prefixes":{"":{"product":1103}}}, // [Turner Sports Interactive, Inc.]
-  {"hash":"67dbd4ebfca8ed7c","prefixes":{"":{"product":1103}}}, // [Turner Sports Interactive, Inc.]
-  {"hash":"3ccffb010a6151f8","prefixes":{"":{"product":1104}}}, // [SnappyTV]
-  {"hash":"7d838005a39552d8","prefixes":{"":{"product":1105,"type":0}}}, // [Target Media Partners]
-  {"hash":"003b7537bd9a7cfe","prefixes":{"":{"product":1105,"type":0}}}, // [Target Media Partners]
-  {"hash":"26b33a79482ab7ab","prefixes":{"":{"product":1106,"type":0}}}, // [KAIZEN platform Inc.]
-  {"hash":"15cdc1963890a6a2","prefixes":{"":{"product":1106,"type":0}}}, // [KAIZEN platform Inc.]
-  {"hash":"1f36b920b7ac4ebb","prefixes":{"":{"product":1107,"type":0}}}, // [Bidstalk Pte Ltd]
-  {"hash":"a59afaa1821362bd","prefixes":{"":{"product":1108,"type":0}}}, // [ESPN]
-  {"hash":"e0edcd5fafde3e7a","prefixes":{"":{"product":1108,"type":0}}}, // [ESPN]
-  {"hash":"7bd48d6255130db4","prefixes":{"":{"product":1109,"type":0}}}, // [Online Media Group]
-  {"hash":"88c41fbe0db9a483","prefixes":{"":{"product":1109,"type":0}}}, // [Online Media Group]
-  {"hash":"fc1080dbf4fae3f9","prefixes":{"":{"product":1109,"type":0}}}, // [Online Media Group]
-  {"hash":"37fc205007f7a040","prefixes":{"":{"product":1109,"type":0}}}, // [Online Media Group]
-  {"hash":"60c02a2ea01a737e","prefixes":{"":{"product":1110,"type":0}}}, // [Luxury Link]
-  {"hash":"24108d30b52b9587","prefixes":{"":{"product":1111,"type":0}}}, // [ESKIMI]
-  {"hash":"9de510a2d7f81a6e","prefixes":{"":{"product":1111}}}, // [ESKIMI]
-  {"hash":"d0e18c7e72b51bf3","prefixes":{"":{"product":1111,"type":0}}}, // [ESKIMI]
-  {"hash":"6dbe16f5894e20af","prefixes":{"":{"product":1112,"type":0}}}, // [AdsYolo Media]
-  {"hash":"5292ef4ba83623a8","prefixes":{"":{"product":1113,"type":0}}}, // [Arrivalist]
-  {"hash":"b94285ae50bcb48e","prefixes":{"":{"product":1113,"type":0}}}, // [Arrivalist]
-  {"hash":"cd7b432729ab016a","prefixes":{"":{"product":1113,"type":0}}}, // [Arrivalist]
-  {"hash":"ae0442a300ebce47","prefixes":{"":{"product":1113,"type":0}}}, // [Arrivalist]
-  {"hash":"3c8cc56d5b514ec5","prefixes":{"":{"product":1113,"type":0}}}, // [Arrivalist]
-  {"hash":"794b2a51546b4f7f","prefixes":{"":{"product":1114,"type":0}}}, // [MobileWebAdz Ltd]
-  {"hash":"223eacf97254c888","prefixes":{"":{"product":1114,"type":0}}}, // [MobileWebAdz Ltd]
-  {"hash":"a3c5eeef285517f3","prefixes":{"":{"product":1114,"type":0}}}, // [MobileWebAdz Ltd]
-  {"hash":"b222f9498fcdb24c","prefixes":{"":{"product":1115,"type":0}}}, // [Demand Side Science, Inc.]
-  {"hash":"87af9974b30c5872","prefixes":{"":{"product":1115,"type":0}}}, // [Demand Side Science, Inc.]
-  {"hash":"db4cd3e487418898","prefixes":{"":{"product":1115,"type":0}}}, // [Demand Side Science, Inc.]
-  {"hash":"3fca6191597f44f2","prefixes":{"":{"product":1116,"type":1}}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
-  {"hash":"6873487b11c1952e","prefixes":{"":{"product":1116,"type":1}}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
-  {"hash":"d4b4ed3e1d07b00e","prefixes":{"":{"product":1116,"type":1}}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
-  {"hash":"e647f502df0429f5","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"34f8fc43e14bad03","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"5f43507f5a877784","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"1466e6f77352194a","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"e097497d606d17ed","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"05c9b2eb92c8b5ba","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"ce3bfbe09ddeb858","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"3aa96b751d2c0d1c","prefixes":{"":{"product":1117,"type":0}}}, // [Mobitrans FZ LLC]
-  {"hash":"289e565c9c686515","prefixes":{"":{"product":1118,"type":0}}}, // [CoCo Reef]
-  {"hash":"0b6740b395a65857","prefixes":{"":{"product":1119}}}, // [Kumma DP LTD]
-  {"hash":"c00365ed4d1c464c","prefixes":{"":{"product":1120,"type":0}}}, // [Cablato Limited]
-  {"hash":"9ee2a07ebdef206f","prefixes":{"":{"product":1120,"type":0}}}, // [Cablato Limited]
-  {"hash":"e270375f27c5f31c","prefixes":{"":{"product":1120,"type":0}}}, // [Cablato Limited]
-  {"hash":"0ebf573ebb6b30e1","prefixes":{"":{"product":1120,"type":0}}}, // [Cablato Limited]
-  {"hash":"e28b4c253b1f854f","prefixes":{"":{"product":1121,"type":1}}}, // [EURO DISNEY SCA]
-  {"hash":"3c8900c851ba9b28","prefixes":{"":{"product":1122,"type":1}}}, // [Norstat]
-  {"hash":"39518e51adbe0cd7","prefixes":{"":{"product":1122,"type":1}}}, // [Norstat]
-  {"hash":"2c5efd1ea532f0eb","prefixes":{"":{"product":1123,"type":0}}}, // [John Varvatos]
-  {"hash":"5679368e6b2bb34c","prefixes":{"":{"product":1124,"type":0}}}, // [Spritz Technology, Inc.]
-  {"hash":"60be7d8a6a76b62f","prefixes":{"":{"product":1124,"type":0}}}, // [Spritz Technology, Inc.]
-  {"hash":"cefbe9240a377d95","prefixes":{"":{"product":1125,"type":1}}}, // [Wix.com]
-  {"hash":"a56824227bb496f7","prefixes":{"*":{"product":1126,"type":0}}}, // [TapTap Networks]
-  {"hash":"41f2ae7d2d6939ae","prefixes":{"":{"product":1126,"type":0}}}, // [TapTap Networks]
-  {"hash":"51fd8b1d5b983b31","prefixes":{"":{"product":1127,"type":0}}}, // [Permodo]
-  {"hash":"12c3d246c6d4e6b1","prefixes":{"":{"product":1127,"type":0}}}, // [Permodo]
-  {"hash":"69da2bfa4e414e2c","prefixes":{"":{"product":1127,"type":0}}}, // [Permodo]
-  {"hash":"67bb1e3460d8e2eb","prefixes":{"":{"product":1127,"type":0}}}, // [Permodo]
-  {"hash":"38912558a11ff73e","prefixes":{"":{"product":1127,"type":0}}}, // [Permodo]
-  {"hash":"eb4d36cf5e4909c1","prefixes":{"":{"product":1128,"type":0}}}, // [Gaiam, Inc.]
-  {"hash":"16578371f24a5e90","prefixes":{"":{"product":1129,"type":0}}}, // [Plusing interactive co.,Ltd]
-  {"hash":"ecdb68bd2622aa9e","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"8adccb3847cc8b0f","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"2b5433780334b542","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"c853c92986d0cc90","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"388da33e7f0adca1","prefixes":{"":{"product":40,"type":0}}}, // [Clinch.co]
-  {"hash":"03d7a65aa1bc87bc","prefixes":{"":{"product":1130,"type":0}}}, // [Paypersale]
-  {"hash":"176eb71c0938f4a5","prefixes":{"":{"product":110,"type":0}}}, // [Epic Combo Malta Ltd.]
-  {"hash":"4366ec3ae9f41f7c","prefixes":{"":{"product":110,"type":0}}}, // [Epic Combo Malta Ltd.]
-  {"hash":"2e9617ef727ff0b5","prefixes":{"":{"product":1131,"type":0}}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"11d6d13e3eb48a86","prefixes":{"":{"product":1131,"type":0}}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"20e14ef573248fec","prefixes":{"":{"product":1131,"type":0}}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"234345fe3c0da842","prefixes":{"":{"product":1131,"type":0}}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"30fb60c9c450221d","prefixes":{"":{"product":1131,"type":0}}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"69ddc7852224e18f","prefixes":{"":{"product":1132,"type":1}}}, // [ESV Digital]
-  {"hash":"240174bad001108d","prefixes":{"":{"product":1133,"type":0}}}, // [RevJet LLC.]
-  {"hash":"5250a7a3f2e4f73a","prefixes":{"":{"product":1133,"type":0}}}, // [RevJet LLC.]
-  {"hash":"590feb6b793ba20a","prefixes":{"":{"product":1133,"type":0}}}, // [RevJet LLC.]
-  {"hash":"23db13cb66f769e3","prefixes":{"":{"product":1134,"type":0}}}, // [GET IT Mobile, Inc]
-  {"hash":"cd7cd6c16f714024","prefixes":{"":{"product":1134,"type":0}}}, // [GET IT Mobile, Inc]
-  {"hash":"00ea35d76275dbeb","prefixes":{"":{"product":1134,"type":0}}}, // [GET IT Mobile, Inc]
-  {"hash":"5239cdae00ff02ea","prefixes":{"":{"product":1135,"type":0}}}, // [IBM]
-  {"hash":"e2c539bef8d2970c","prefixes":{"":{"product":1136,"type":1}}}, // [Lucid Holdings, LLC]
-  {"hash":"7078be8707b5ec93","prefixes":{"":{"product":1136,"type":1}}}, // [Lucid Holdings, LLC]
-  {"hash":"d65fe9ed9f23afbd","prefixes":{"":{"product":1137,"type":1}}}, // [Stratio Big Data Inc.]
-  {"hash":"9ccfc7f2ecfbaeec","prefixes":{"":{"product":1137,"type":1}}}, // [Stratio Big Data Inc.]
-  {"hash":"54e80254bbf4e20b","prefixes":{"":{"product":1138,"type":0}}}, // [Tripping.com]
-  {"hash":"4aaf263b4bae6cd1","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"b782d6c10170e732","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"ceef29c52329c405","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"f14df6ca2e300bb9","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"514c355026c95637","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"b2529b7ebc0cbb27","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"14ebf9b0cbed945c","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"048147eea378ee03","prefixes":{"":{"product":1139}}}, // [Vidible]
-  {"hash":"7b61440491bd2a65","prefixes":{"":{"product":1140,"type":0}}}, // [MiMTiD Corp]
-  {"hash":"036455e7801e853e","prefixes":{"":{"product":1140,"type":0}}}, // [MiMTiD Corp]
-  {"hash":"e631f0342d59176b","prefixes":{"":{"product":1141,"type":0}}}, // [Moloco, Inc.]
-  {"hash":"87938522c669c682","prefixes":{"":{"product":1141,"type":0}}}, // [Moloco, Inc.]
-  {"hash":"a102c87f9921beb6","prefixes":{"":{"product":1142,"type":1}}}, // [MEC SP. Z O.O]
-  {"hash":"f9133e4a069a0f4f","prefixes":{"":{"product":1142,"type":1}}}, // [MEC SP. Z O.O]
-  {"hash":"6c7737c0ecbf0d91","prefixes":{"":{"product":1142,"type":1}}}, // [MEC SP. Z O.O]
-  {"hash":"a82a0c18f6dfb959","prefixes":{"":{"product":1142,"type":1}}}, // [MEC SP. Z O.O]
-  {"hash":"e1bea08ea38dc600","prefixes":{"":{"product":1143,"type":0}}}, // [Abudantia LLC]
-  {"hash":"d60e1ada8dfa48fa","prefixes":{"":{"product":1143,"type":0}}}, // [Abudantia LLC]
-  {"hash":"b57f7b99f9deda72","prefixes":{"":{"product":1143,"type":0}}}, // [Abudantia LLC]
-  {"hash":"63f93976910e4aff","prefixes":{"":{"product":1143,"type":0}}}, // [Abudantia LLC]
-  {"hash":"93a75f3f5174e472","prefixes":{"":{"product":1143,"type":0}}}, // [Abudantia LLC]
-  {"hash":"ba1500537064494c","prefixes":{"":{"product":1144,"type":0}}}, // [Realzeit]
-  {"hash":"ce1c3e183853dec6","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"697384881bfb9a85","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"3b5e1e5d71bb095f","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"a55289ec43a1fd1c","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"0ea122741b5a296d","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"139c147db4a66d45","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"91a98ad80489e2aa","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"276f5a9d0ed20d4a","prefixes":{"":{"product":1145,"type":0}}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"8408cf6c93d2f24f","prefixes":{"":{"product":1146,"type":1}}}, // [Alkemics]
-  {"hash":"658222dab2aa692d","prefixes":{"":{"product":1146,"type":1}}}, // [Alkemics]
-  {"hash":"8835156415ef5c70","prefixes":{"":{"product":1146,"type":1}}}, // [Alkemics]
-  {"hash":"3ba6cc7216a7d5ae","prefixes":{"":{"product":144,"type":0}}}, // [SiteScout AdServer]
-  {"hash":"7d76d0b7c2c49e1c","prefixes":{"":{"product":1147,"type":0}}}, // [Sodel Software Solutions Pvt. Ltd.]
-  {"hash":"26b315a19bf762cb","prefixes":{"":{"product":1148,"type":0}}}, // [Clearstream.TV, Inc]
-  {"hash":"80ce05889af3bb0e","prefixes":{"":{"product":1148,"type":0}}}, // [Clearstream.TV, Inc]
-  {"hash":"2d9798f06f3cd0f8","prefixes":{"":{"product":1148,"type":0}}}, // [Clearstream.TV, Inc]
-  {"hash":"4724e51f601e7bfa","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"e0f93294ef7c3cb7","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"ed1e0f5237be934f","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"4a0011b21f8d95f9","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"1af9efa73c3b3b29","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"49eea06f0c13da7f","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"584459c8cfe5595f","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"3b72d8e306588e71","prefixes":{"":{"product":1149,"type":0}}}, // [KuaiziTech]
-  {"hash":"f8d6e6d127d9c894","prefixes":{"":{"product":1150,"type":0}}}, // [Adluxe]
-  {"hash":"93d864f5e43a3230","prefixes":{"":{"product":1150,"type":0}}}, // [Adluxe]
-  {"hash":"793d5c9c5c35b0d9","prefixes":{"":{"product":1150,"type":0}}}, // [Adluxe]
-  {"hash":"7b9c5864364d5f5e","prefixes":{"*":{"product":1151,"type":1}}}, // [NinthDecimal]
-  {"hash":"7c86152a561c4b4b","prefixes":{"*":{"product":1151,"type":1}}}, // [NinthDecimal]
-  {"hash":"ec998efdf99b0c51","prefixes":{"*":{"product":1152,"type":0}}}, // [RICH MEDIA STUDIO]
-  {"hash":"e83c01ec741a261e","prefixes":{"":{"product":1153,"type":0}}}, // [TenMax Co., Ltd.]
-  {"hash":"e333d70ac6d1acda","prefixes":{"":{"product":1154,"type":0}}}, // [twiago GmbH]
-  {"hash":"bb81d5fd8a052b7f","prefixes":{"":{"product":1155,"type":0}}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"55b2516509252adb","prefixes":{"":{"product":1155,"type":0}}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"59e4e15b4fe6dccd","prefixes":{"":{"product":1155,"type":0}}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"f5005d7a14ac0a47","prefixes":{"":{"product":1155,"type":0}}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"ecf3dd9926cbe25e","prefixes":{"":{"product":1155,"type":0}}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"2ccdffccbbf20e3f","prefixes":{"":{"product":1156,"type":1}}}, // [Swarm Enterprises Inc]
-  {"hash":"bf0dd6fdbc53dfee","prefixes":{"":{"product":111,"type":0}}}, // [Quixey]
-  {"hash":"ac6a75f10f9f0391","prefixes":{"":{"product":1157,"type":0}}}, // [Media Forum]
-  {"hash":"2b5f5e731d08116b","prefixes":{"":{"product":1157,"type":0}}}, // [Media Forum]
-  {"hash":"8bf2fe7f00b3c760","prefixes":{"":{"product":1158,"type":0}}}, // [Beeswax.io]
-  {"hash":"480bd3bc762861ae","prefixes":{"":{"product":1159,"type":0}}}, // [Varick Media Management]
-  {"hash":"d9faa36410c39273","prefixes":{"":{"product":1159,"type":0}}}, // [Varick Media Management]
-  {"hash":"6114cbf7f45fd639","prefixes":{"":{"product":1160,"type":0}}}, // [JD]
-  {"hash":"739568f083f383e2","prefixes":{"":{"product":1160,"type":0}}}, // [JD]
-  {"hash":"1fc63d36c1d330fa","prefixes":{"":{"product":1160,"type":0}}}, // [JD]
-  {"hash":"bdb07c050de0bbd2","prefixes":{"":{"product":1160,"type":0}}}, // [JD]
-  {"hash":"6b6a891a61b05435","prefixes":{"":{"product":1161,"type":0}}}, // [Lotlinx Inc.]
-  {"hash":"b7831e02a1168f7b","prefixes":{"":{"product":1161,"type":0}}}, // [Lotlinx Inc.]
-  {"hash":"78f18ca9103e6031","prefixes":{"":{"product":1162}}}, // [Lotlinx Inc]
-  {"hash":"9a1f751c74a01145","prefixes":{"":{"product":41,"type":0}}}, // [F# Inc.]
-  {"hash":"09ddf4e3268e6597","prefixes":{"":{"product":1163,"type":1}}}, // [Ingenio, LLC]
-  {"hash":"c5dd0849ac2febc6","prefixes":{"":{"product":1164,"type":0}}}, // [MVMT Watches]
-  {"hash":"3b471f8f08410883","prefixes":{"":{"product":1165,"type":0}}}, // [C1X Inc]
-  {"hash":"1bb74ab211a41c9c","prefixes":{"":{"product":1166,"type":0}}}, // [Vitro Agency]
-  {"hash":"96c0acfcd81b2dd4","prefixes":{"":{"product":1167,"type":0}}}, // [Kabbage]
-  {"hash":"0e5b93a6bd6f704b","prefixes":{"":{"product":1168,"type":1}}}, // [Redbranch, Inc. (dba Fraudlogix)]
-  {"hash":"a810be7236bf948f","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"ffe13e4342fd9a35","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"91d97869f45df6e0","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"c9f1716ec9d29c4b","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"4a9148e717cb46a9","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"9b57b296c2edd01c","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"1db72ea880eb28dc","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"61889d0078dd40a7","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"fd8f5971bf862430","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"d0da5b57fc3b9611","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"00449172b70d520c","prefixes":{"":{"product":1169,"type":0}}}, // [AutoWeb, Inc.]
-  {"hash":"7b3027f5a6cb4f20","prefixes":{"":{"product":1170,"type":0}}}, // [Aimee Soft Ltd.]
-  {"hash":"c29f58ba8b9fccc8","prefixes":{"":{"product":1170,"type":0}}}, // [Aimee Soft Ltd.]
-  {"hash":"e8cb0d7824f08de4","prefixes":{"":{"product":1170,"type":0}}}, // [Aimee Soft Ltd.]
-  {"hash":"97efe77626897346","prefixes":{"":{"product":1170,"type":0}}}, // [Aimee Soft Ltd.]
-  {"hash":"78afe44858076c81","prefixes":{"":{"product":1170,"type":0}}}, // [Aimee Soft Ltd.]
-  {"hash":"f5162869e573dcd7","prefixes":{"":{"product":1171,"type":1}}}, // [SAS Azameo]
-  {"hash":"3d35f5eb2971f5fe","prefixes":{"":{"product":23,"type":1}}}, // [iJento]
-  {"hash":"b98ddad6854c87b1","prefixes":{"":{"product":1172,"type":1}}}, // [Keyade]
-  {"hash":"65aab53cd46ccc7f","prefixes":{"":{"product":1173,"type":0}}}, // [Digital To Store (DTS)]
-  {"hash":"e1e5e1a4c7857257","prefixes":{"":{"product":1173,"type":0}}}, // [Digital To Store (DTS)]
-  {"hash":"c9f6517091430433","prefixes":{"":{"product":1173,"type":0}}}, // [Digital To Store (DTS)]
-  {"hash":"76d9ee307388af98","prefixes":{"":{"product":1173,"type":0}}}, // [Digital To Store (DTS)]
-  {"hash":"8fdb48d3b5466119","prefixes":{"":{"product":1173,"type":0}}}, // [Digital To Store (DTS)]
-  {"hash":"bd53e2fe0c663545","prefixes":{"":{"product":1174,"type":0}}}, // [Media iQ Digital]
-  {"hash":"58b54a485703f6ba","prefixes":{"":{"product":1174,"type":0}}}, // [Media iQ Digital]
-  {"hash":"35616fb4ea0feb94","prefixes":{"":{"product":1174,"type":0}}}, // [Media iQ Digital]
-  {"hash":"0a1563142096ed40","prefixes":{"":{"product":1175,"type":1}}}, // [Ingenious Technologies]
-  {"hash":"427d170b486c74e6","prefixes":{"":{"product":1175,"type":1}}}, // [Ingenious Technologies]
-  {"hash":"79480a2b5de32430","prefixes":{"":{"product":1175,"type":1}}}, // [Ingenious Technologies]
-  {"hash":"aaf44b046fb5c10d","prefixes":{"":{"product":1176,"type":0}}}, // [Sonicmoov co.,ltd]
-  {"hash":"e5d30ca87b591280","prefixes":{"":{"product":1176,"type":0}}}, // [Sonicmoov co.,ltd]
-  {"hash":"9ec9f8d7f0fc8c4a","prefixes":{"":{"product":1176,"type":0}}}, // [Sonicmoov co.,ltd]
-  {"hash":"dd0bf16db1e39f59","prefixes":{"":{"product":1176,"type":0}}}, // [Sonicmoov co.,ltd]
-  {"hash":"b32a4da2bc7363a0","prefixes":{"":{"product":1177,"type":0}}}, // [Bonadza LLC]
-  {"hash":"66a81343ae0223df","prefixes":{"":{"product":1177,"type":0}}}, // [Bonadza LLC]
-  {"hash":"ae76287d25b463d2","prefixes":{"":{"product":1177,"type":0}}}, // [Bonadza LLC]
-  {"hash":"7429b926177d09a6","prefixes":{"":{"product":1177,"type":0}}}, // [Bonadza LLC]
-  {"hash":"170cc20a9af99287","prefixes":{"":{"product":1178,"type":0}}}, // [Axis Shift Limited]
-  {"hash":"6e94333e674450ec","prefixes":{"":{"product":1179,"type":0}}}, // [TreSensa, Inc.]
-  {"hash":"8fac335d75d968fd","prefixes":{"":{"product":1179,"type":0}}}, // [TreSensa, Inc.]
-  {"hash":"eec936c95af6b31f","prefixes":{"":{"product":1179,"type":0}}}, // [TreSensa, Inc.]
-  {"hash":"3c744b206f15c46d","prefixes":{"":{"product":1179,"type":0}}}, // [TreSensa, Inc.]
-  {"hash":"049a71c722403987","prefixes":{"":{"product":1180,"type":1}}}, // [Media Logic Group LLC dba AerisWeather LLC]
-  {"hash":"efa6686cf4b6b73c","prefixes":{"":{"product":56,"type":1}}}, // [DeinDeal AG]
-  {"hash":"847219545b169784","prefixes":{"":{"product":1181,"type":0}}}, // [Fugumobile]
-  {"hash":"790ab0ec39724b71","prefixes":{"":{"product":1182,"type":0}}}, // [Localstars Ltd]
-  {"hash":"0133a556a80fd808","prefixes":{"":{"product":1183,"type":0}}}, // [Fluidads]
-  {"hash":"fc8901303bada188","prefixes":{"":{"product":1183,"type":0}}}, // [Fluidads]
-  {"hash":"ba549c39b1f43523","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"5d0b84261f7b6d5c","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"d48dde21b5917906","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"337dabe98702ae52","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"efad84d0a4dd4e46","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"019c3ee24427b355","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"ec79c848ccf2d648","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"ccf7fd5647b92698","prefixes":{"*":{"product":1184,"type":0}}}, // [Wayfair LLC]
-  {"hash":"3b03a24eea2a6345","prefixes":{"":{"product":1185,"type":0}}}, // [VCCORP CORPORATION]
-  {"hash":"f7f53c88139460cf","prefixes":{"":{"product":1186,"type":0}}}, // [IGAWorks]
-  {"hash":"93b9518285f54887","prefixes":{"":{"product":1187,"type":0}}}, // [Cellcom Ltd]
-  {"hash":"f59e6427783c3da0","prefixes":{"*":{"product":1188,"type":0}}}, // [Upsolver]
-  {"hash":"adb55d98bb4aef6e","prefixes":{"":{"product":1188,"type":0}}}, // [Upsolver]
-  {"hash":"7efba976eeea2d41","prefixes":{"":{"product":1188,"type":0}}}, // [Upsolver]
-  {"hash":"cdde375c1240991d","prefixes":{"":{"product":922,"type":1}}}, // [Channel Factory, LLC]
-  {"hash":"79c4dc57905857aa","prefixes":{"":{"product":1189,"type":0}}}, // [Phluidmedia, Inc.]
-  {"hash":"4948ea141d1a72e1","prefixes":{"":{"product":1189,"type":0}}}, // [Phluidmedia, Inc.]
-  {"hash":"e4aed5bf5c295c3a","prefixes":{"":{"product":1190,"type":1}}}, // [Roy Morgan Research Ltd]
-  {"hash":"547734f17effda77","prefixes":{"":{"product":1191,"type":0}}}, // [TapSense, Inc.]
-  {"hash":"96289aeef06d0a9f","prefixes":{"":{"product":1192,"type":0}}}, // [Southwest Airlines]
-  {"hash":"de497c6fbed4588d","prefixes":{"":{"product":783,"type":1}}}, // [Hatena Co., Ltd]
-  {"hash":"91412d534d321cb4","prefixes":{"":{"product":1193,"type":1}}}, // [Market Points, Inc.]
-  {"hash":"97aab20dd873dd2c","prefixes":{"":{"product":1194,"type":0}}}, // [UberMedia Inc.]
-  {"hash":"73cadeea8e1bd9e8","prefixes":{"":{"product":1194,"type":0}}}, // [UberMedia Inc.]
-  {"hash":"0e1bd2938a06a2e6","prefixes":{"":{"product":1195,"type":0}}}, // [Kadam SIA]
-  {"hash":"aa9658253aa81e62","prefixes":{"":{"product":1195,"type":0}}}, // [Kadam SIA]
-  {"hash":"75f1eab33abfa4f9","prefixes":{"":{"product":1195,"type":0}}}, // [Kadam SIA]
-  {"hash":"59f64b09b8e430ae","prefixes":{"":{"product":1195,"type":0}}}, // [Kadam SIA]
-  {"hash":"61947a042af2e3e8","prefixes":{"":{"product":1196,"type":0}}}, // [Alveo Platform (VMM own bidder)]
-  {"hash":"62c095e8dfbb0458","prefixes":{"":{"product":1197,"type":0}}}, // [Adbalancer EDV-DienstleistungsgesellschaftgmbH]
-  {"hash":"5cc57103c26df76f","prefixes":{"":{"product":1197,"type":0}}}, // [Adbalancer EDV-DienstleistungsgesellschaftgmbH]
-  {"hash":"53685a43fc711ea4","prefixes":{"":{"product":1198,"type":0}}}, // [JWPlayer]
-  {"hash":"53bdf03af7a44e2c","prefixes":{"":{"product":1198,"type":0}}}, // [JWPlayer]
-  {"hash":"eaff21a1a9591dab","prefixes":{"":{"product":1198,"type":0}}}, // [JWPlayer]
-  {"hash":"1d5626ba7394e6a1","prefixes":{"":{"product":1198,"type":0}}}, // [JWPlayer]
-  {"hash":"2e106bd1d1d064c6","prefixes":{"":{"product":1198,"type":0}}}, // [JWPlayer]
-  {"hash":"9f7691306b0805ea","prefixes":{"":{"product":1198,"type":0}}}, // [JWPlayer]
-  {"hash":"909df8f91bd33085","prefixes":{"*":{"product":1199,"type":0}}}, // [Adiquity Technologies Pvt Ltd]
-  {"hash":"d1eca614d3cc8883","prefixes":{"":{"product":1200,"type":1}}}, // [Smart Digital GmbH]
-  {"hash":"53d8de6b018c1793","prefixes":{"":{"product":1201,"type":0}}}, // [Auditorius LLC]
-  {"hash":"fd9a420ade305e17","prefixes":{"":{"product":1202,"type":0}}}, // [Treepodia]
-  {"hash":"c9fd06f055d4af40","prefixes":{"":{"product":1202,"type":0}}}, // [Treepodia]
-  {"hash":"6eb24d470a6f1018","prefixes":{"":{"product":1202,"type":0}}}, // [Treepodia]
-  {"hash":"e35bb07367786d4c","prefixes":{"":{"product":1203,"type":0}}}, // [Adamatic]
-  {"hash":"3943df18ad20915d","prefixes":{"":{"product":1203,"type":0}}}, // [Adamatic]
-  {"hash":"341d248dc25e4ea7","prefixes":{"":{"product":1203,"type":0}}}, // [Adamatic]
-  {"hash":"ad1f1681bab5cc6b","prefixes":{"":{"product":1204,"type":1}}}, // [SAS Web2ROI]
-  {"hash":"532b5bfa711f405e","prefixes":{"":{"product":1205,"type":1}}}, // [Cardlytics]
-  {"hash":"799c283a6f1c8ece","prefixes":{"":{"product":1206}}}, // [MyFonts Inc.]
-  {"hash":"4448bee927dde7e6","prefixes":{"*":{"product":1207,"type":0}}}, // [Bluecore, Inc.]
-  {"hash":"a0bd7b7a099833b6","prefixes":{"":{"product":1207,"type":0}}}, // [Bluecore, Inc.]
-  {"hash":"fa3e77058c021551","prefixes":{"*":{"product":1207,"type":0}}}, // [Bluecore, Inc.]
-  {"hash":"4761d233715098ce","prefixes":{"":{"product":1208,"type":0}}}, // [EverQuote, Inc.]
-  {"hash":"35694b7df8059b22","prefixes":{"":{"product":1208,"type":0}}}, // [EverQuote, Inc.]
-  {"hash":"0740880077130a2d","prefixes":{"":{"product":1209,"type":1}}}, // [Optimize LCC D.B.A Genius Monkey]
-  {"hash":"bfe2c1b41278b804","prefixes":{"":{"product":1209,"type":1}}}, // [Optimize LCC D.B.A Genius Monkey]
-  {"hash":"6dd3f6dcd500314e","prefixes":{"":{"product":1209,"type":1}}}, // [Optimize LCC D.B.A Genius Monkey]
-  {"hash":"2f3f7cacd3fe0763","prefixes":{"*":{"product":1210,"type":0}}}, // [EverString Technology Ltd]
-  {"hash":"bca80e9becb74dcb","prefixes":{"*":{"product":1210,"type":0}}}, // [EverString Technology Ltd]
-  {"hash":"46edf29e9ba4ff96","prefixes":{"":{"product":1211,"type":0}}}, // [Axonix Limited]
-  {"hash":"98961093c86583f5","prefixes":{"":{"product":1212,"type":0}}}, // [Ubimo Ltd.]
-  {"hash":"e36b044e9f38bad6","prefixes":{"":{"product":1213,"type":0}}}, // [PlaceIQ, Inc.]
-  {"hash":"fe5b89fe7dbbd534","prefixes":{"":{"product":1214,"type":0}}}, // [DataBerries]
-  {"hash":"ddf083a57d484592","prefixes":{"":{"product":1215,"type":1}}}, // [Otto (GmbH & Co KG)]
-  {"hash":"7975f7864f4fa759","prefixes":{"":{"product":1216,"type":0}}}, // [Beijing ADirects Technology Corporation Limited]
-  {"hash":"657d40c4d7322985","prefixes":{"":{"product":1217,"type":0}}}, // [MagicGroup Asia Pte. Ltd.]
-  {"hash":"f5559eee02dd33ad","prefixes":{"":{"product":1217,"type":0}}}, // [MagicGroup Asia Pte. Ltd.]
-  {"hash":"e81aa2815c378230","prefixes":{"":{"product":1217,"type":0}}}, // [MagicGroup Asia Pte. Ltd.]
-  {"hash":"49269f9273c66c00","prefixes":{"":{"product":1218,"type":0}}}, // [Local Content, Inc.]
-  {"hash":"210fa7d8376be47a","prefixes":{"":{"product":1218,"type":0}}}, // [Local Content, Inc.]
-  {"hash":"e4ba8ed4e3abc143","prefixes":{"":{"product":1219,"type":0}}}, // [Flavia]
-  {"hash":"269e0d49e8a941b8","prefixes":{"":{"product":42,"type":0}}}, // [Transout Inc.]
-  {"hash":"b9cd0135bbe2cf40","prefixes":{"":{"product":42,"type":0}}}, // [Transout Inc.]
-  {"hash":"e4b01f2271c4171a","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"e5b4daaa6c4ae231","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"cfb3a28bf24f27aa","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"db9ed30c0cbece36","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"dd0d7f22eaea16dd","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"4f3fc6e6fa75b1e8","prefixes":{"":{"product":43,"type":0}}}, // [ADZIP]
-  {"hash":"17a3e1cbc6818d71","prefixes":{"*":{"product":1220}}}, // [Webtype]
-  {"hash":"39697008117e49f0","prefixes":{"":{"product":1221,"type":0}}}, // [Aditor]
-  {"hash":"50bd67909486f9f5","prefixes":{"":{"product":1221,"type":0}}}, // [Aditor]
-  {"hash":"d58ef2e47a1b5b3b","prefixes":{"":{"product":1222,"type":0}}}, // [YCmedia]
-  {"hash":"fc8e2c447edda6c9","prefixes":{"":{"product":1223,"type":0}}}, // [Addwish Aps]
-  {"hash":"d5ac956c9f185ddc","prefixes":{"":{"product":1224,"type":0}}}, // [AIDO TECHNOLOGY INC.]
-  {"hash":"24015d44b9900d67","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"460c0600751cbd60","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"77050f5bbccffdb1","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"cdf17fb674f06ff0","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"8fb430c8ece16b19","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"c9d79e6f1f2694cd","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"80c75e37374a2ef0","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"5f9ca3a706ea1a32","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"2839cda166e75a72","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"762d13ee90c23c96","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"c0ea3a6ac5a15ff4","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"70c0b65944772c14","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"06d5db93059745e1","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"ea0e52e08087883d","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"dd48f2110336efda","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"bac37ceef6479f6b","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"a16d986f3ad09790","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"44addae7b850b89f","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"ef08ba4268518e6e","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"1f2560020ac4a5dd","prefixes":{"":{"product":1225,"type":0}}}, // [Herolens Group LLC]
-  {"hash":"67339d8f9c205d19","prefixes":{"":{"product":1226,"type":0}}}, // [Fuisz Media, Inc.]
-  {"hash":"b3ebdb16675afb79","prefixes":{"":{"product":1226,"type":0}}}, // [Fuisz Media, Inc.]
-  {"hash":"33e8b1a10d6cf9bb","prefixes":{"":{"product":1226,"type":0}}}, // [Fuisz Media, Inc.]
-  {"hash":"33c97b2942fbfb43","prefixes":{"":{"product":1227,"type":0}}}, // [Bucksense, Inc.]
-  {"hash":"f7be89ec6f521ed4","prefixes":{"":{"product":657,"type":0}}}, // [Adiant]
-  {"hash":"8ad32c44e7f009d9","prefixes":{"":{"product":1228,"type":1}}}, // [Taylor Nelson Sofres Ukraine LLC]
-  {"hash":"9913ba5c46add495","prefixes":{"*":{"product":1229}}}, // [MotionLead]
-  {"hash":"ed341f6ed9722885","prefixes":{"":{"product":1230,"type":0}}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"b84298a2bc76c877","prefixes":{"":{"product":1230,"type":0}}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"d7bd450b5571f32e","prefixes":{"":{"product":1230,"type":0}}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"788739abab822f20","prefixes":{"":{"product":1230,"type":0}}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"5119113b90253a71","prefixes":{"":{"product":1230,"type":0}}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"8391f54ef2dd8235","prefixes":{"":{"product":1231}}}, // [Adobe Edge]
-  {"hash":"ecbec0da60be727e","prefixes":{"":{"product":1231}}}, // [Adobe Edge]
-  {"hash":"45df05b3b1fd2039","prefixes":{"":{"product":1231}}}, // [Adobe Edge]
-  {"hash":"7f8b63980ada138f","prefixes":{"":{"product":1232,"type":1}}}, // [Bizible]
-  {"hash":"fcff0eb6c45bdf72","prefixes":{"":{"product":1233,"type":0}}}, // [Adludio Limited]
-  {"hash":"58ae271664061630","prefixes":{"":{"product":1233,"type":0}}}, // [Adludio Limited]
-  {"hash":"19795a3ce2a7e620","prefixes":{"":{"product":1233,"type":0}}}, // [Adludio Limited]
-  {"hash":"aa3822d449c78db7","prefixes":{"":{"product":1233,"type":0}}}, // [Adludio Limited]
-  {"hash":"b1269cde121b05a1","prefixes":{"":{"product":1233,"type":0}}}, // [Adludio Limited]
-  {"hash":"1581c4afe0d48fa2","prefixes":{"":{"product":1234,"type":0}}}, // [Ally Financial]
-  {"hash":"2e171be7640cf4cd","prefixes":{"":{"product":1235,"type":0}}}, // [AIAd Ltd.]
-  {"hash":"ae7e973c225c0a01","prefixes":{"":{"product":1236,"type":0}}}, // [Petplan]
-  {"hash":"78db497564cd4bf9","prefixes":{"bis":{"product":1237,"type":0},"":{"product":1237,"type":0},"openrtb":{"product":1237,"type":0}}}, // [Vidazoo Ltd.] [Vidazoo Ltd.] [Vidazoo Ltd.]
-  {"hash":"c0fe1ea55404bcbb","prefixes":{"bis":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"f7fbe362db50024a","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"55abab5eb4ff10bd","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"e542a9dea283be31","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"a49f5bf572a22bae","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"7e02810393b6fe89","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"89c0cbd03222de92","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"31a98e1d5bba9ae8","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"15010236a7d3b5a4","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"9f927848d0417d12","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"7a2f5d3665e9a31a","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"02fb27611632d82c","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"0b95d00c8ef095ae","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"2d42c2d0a5ab84ae","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"5e405c19a402590e","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"d037ae4b54d7e7ec","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"fa3f8d822f471c8e","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"1fd9bf19c5906c01","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"f989a4e87da3e6d9","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"26937f461d535e88","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"755c357326a37b3f","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"aac0686686b2d53c","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"3ce944fa0cf0291a","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"7302f12cc4ace16b","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"52816f3d4542b887","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"59bf7df499fa52b5","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"ebabd6c7d62c634c","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"53ac53e2f538f2e2","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"3ed73abadb9c898a","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"9574295460ce8d22","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"d591fdb6045eb90f","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"8b39993907ef0e90","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"fff9c91a1d02e69d","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"d086a625516bdfc4","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"dedb3c41790f0b92","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"d9d28815b7351be9","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"0eceb2a8a6aa5014","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"c3cd28d4911901ef","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"906300510974cf1a","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"6bbcc411e84396ce","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"18f5beb4c7518ce0","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"445bbe1950cddd7b","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"2b7cc0f2bdc9e984","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"2e1ee42fbe53923e","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"0d75de8359eb1e90","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"5439763db9182a6c","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"924a269d7fa953ef","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"56592bc98da7add7","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"e350307b97e81944","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"62d2d232adb7f5ce","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"9dbd1f71df681f87","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"60aa872cca3ea408","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"574290c159276582","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"520b03b31ba99ffe","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"8927dc4db3ffd9a0","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"cea75e5e1bcb3e75","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"00fc1e5ba5cf11e1","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"241443df62a11bdb","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"958852e67d999446","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"d7dde4fdd1b42ac2","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"b9a6386a13d1f59c","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"1b00c21eb7dca0ba","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"3b5a0569a91c1f27","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"07b3c413dcf0891e","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"4b15aef39cd29476","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"25743e7a87ec9352","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"2fe16a518eee6e23","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"a154647a02beff09","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"73a06806ded66bc0","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"a82c6297f56276f8","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"514b9e5dcf88791d","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"80e10fe664c9676b","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"788de2248f446546","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"e1e58f0b49a0e5c7","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"c56afa9dadaace8c","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"4084c6a05941d212","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"fafe943a3ce4b828","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"00cfc10d1f469dfc","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"cdb86fef4fddecdd","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"97b3473c7082a4c8","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"99973a84d3bda612","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"ba67aff057d8dc5d","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"a3c0da72dbefc878","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"5925a6291dd2ab40","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"34129d9457495ffd","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"e2505c6002184e33","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"9bcac0e9fd77ddc6","prefixes":{"":{"product":1237,"type":0}}}, // [Vidazoo Ltd.]
-  {"hash":"737c1868e55d5b37","prefixes":{"":{"product":1238,"type":0}}}, // [RTBstar LLC]
-  {"hash":"302ec6d6755746d6","prefixes":{"*":{"product":1239,"type":0}}}, // [Chalk Media Holdings]
-  {"hash":"202f611d1eab4195","prefixes":{"*":{"product":1239,"type":0}}}, // [Chalk Media Holdings]
-  {"hash":"a6ab491761f03a1c","prefixes":{"":{"product":1240,"type":1}}}, // [Oxford Biochronometrics]
-  {"hash":"3f8968d2bc62134f","prefixes":{"":{"product":1240,"type":1}}}, // [Oxford Biochronometrics]
-  {"hash":"fbe6ab3bc9d21558","prefixes":{"":{"product":1240,"type":1}}}, // [Oxford Biochronometrics]
-  {"hash":"769529a9ad14a9b6","prefixes":{"":{"product":1241,"type":0}}}, // [SGN Games, Inc.]
-  {"hash":"f1a29a10c1ad80be","prefixes":{"*":{"product":1242,"type":1}}}, // [Crutchfield New Media, LLC]
-  {"hash":"930e98a126b97c02","prefixes":{"":{"product":112,"type":0}}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"915e8620d61e782c","prefixes":{"":{"product":112,"type":0}}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"0492037eab3835e9","prefixes":{"":{"product":112,"type":0}}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"5eee79daa9337871","prefixes":{"":{"product":1243,"type":0}}}, // [Laserlike Inc]
-  {"hash":"3262121ae456ec62","prefixes":{"":{"product":1244}}}, // [Adtile Technologies Inc.]
-  {"hash":"eefeb24c8c0df59f","prefixes":{"":{"product":1244}}}, // [Adtile Technologies Inc.]
-  {"hash":"2f77e3292a158b3c","prefixes":{"":{"product":1244}}}, // [Adtile Technologies Inc.]
-  {"hash":"ed04984091cd6edc","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"63c7ce8ea1112262","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"842d35d55c520fe2","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"3fb91c004caeeba4","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"4673bf1b8fb41012","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"60c5047efc444089","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"9daf201eb861bd5a","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"8fb045042ba8dab7","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"b5c5f11aa533f8f8","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"e69760fd18a7e847","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"afdb50efeb58adb3","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"54ade0c2fc33d554","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"980a9356a0a0604b","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"0d064f41dd06b071","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"4e9cc6d069d0700f","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"abc81c5ff7313f61","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"4d8e54db683834b5","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"958c891ea7a22760","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"02b0aa7dbed4dc70","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"cd655ca6f3e7c5b4","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"117f6d5c385c0fbf","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"974b3e895eb889a1","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"2315e038cabe7cf3","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"256e6db135713c95","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"44b4921e1dd83428","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"2ececb465fbab022","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"b3a40f1c056c981d","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"c4f8f640f24e3592","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"0a6e85210f1d99c3","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"d12573269a748046","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"deabc924d996a1ca","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"cfae73045c7b29a6","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"c97db9d5ee0b71c7","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"ca6bb3442fa58646","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"f38fbdc9759c0ef4","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"6db47cd08bed3122","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"86c0634020121d1e","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"98c1045cd61f979d","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"7bdc1a49cf0ccc1d","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"cdceb4fead43eafb","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"b8a7ac4ace0ce6e9","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"081ccef35be56b36","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"e29de726004b6e06","prefixes":{"":{"product":1245,"type":1}}}, // [Adgravity]
-  {"hash":"3044eb15f0757788","prefixes":{"":{"product":1246,"type":1}}}, // [Protected Media LTD]
-  {"hash":"675f561d3f31df38","prefixes":{"":{"product":1246,"type":1}}}, // [Protected Media LTD]
-  {"hash":"506fa56f8b748a67","prefixes":{"":{"product":1247,"type":1}}}, // [Media Detect GmbH]
-  {"hash":"d8795d8df3c0b355","prefixes":{"":{"product":1248,"type":0}}}, // [Centro CDN]
-  {"hash":"92690e6cf2068609","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"bcb296520399e855","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"eeba4d486f2a193f","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"36ba79aa125ace1d","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"755e0fb3a6d853e7","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"926c7d8c47cdc6a4","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"112f8b5a749d05e9","prefixes":{"":{"product":1249,"type":0}}}, // [DeltaX]
-  {"hash":"7ed84366898b6e95","prefixes":{"":{"product":1250,"type":0}}}, // [SoMo Audience Corp.]
-  {"hash":"7b7b8f4fea812106","prefixes":{"":{"product":1250,"type":0}}}, // [SoMo Audience Corp.]
-  {"hash":"cd27a627925b605e","prefixes":{"":{"product":1250,"type":0}}}, // [SoMo Audience Corp.]
-  {"hash":"8de4d0c2e5a785d3","prefixes":{"":{"product":1250,"type":0}}}, // [SoMo Audience Corp.]
-  {"hash":"dd090795aa41d39d","prefixes":{"":{"product":1250,"type":0}}}, // [SoMo Audience Corp.]
-  {"hash":"a792d2d9ef8b7d44","prefixes":{"":{"product":1251,"type":0}}}, // [Distribute Ltd]
-  {"hash":"a41d8bffbb4dde29","prefixes":{"c":{"product":1251,"type":0}}}, // [Distribute Ltd]
-  {"hash":"cb03110aa3eafbc3","prefixes":{"":{"product":1251,"type":0}}}, // [Distribute Ltd]
-  {"hash":"f8d5c1c3c0137b95","prefixes":{"":{"product":1251,"type":0}}}, // [Distribute Ltd]
-  {"hash":"fdbd7675a0a4e4d2","prefixes":{"":{"product":1251,"type":0}}}, // [Distribute Ltd]
-  {"hash":"c152daf3639bfd61","prefixes":{"":{"product":1252,"type":0}}}, // [Poppin]
-  {"hash":"77afc197a9ed3c55","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"f000d51ba83c9b81","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"e6b0bd562a8a6c44","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"b67bb576e01ff3b8","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"b74cae0d407627c6","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"d02ca334243aeff6","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"27c4aebe8feb1d61","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"cffac58b1fe6a120","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"060b85b3672a94b9","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"993dbbd9a4428116","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"5d08c05fd8f3e6b6","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"733a8e48aa3496c3","prefixes":{"":{"product":1253,"type":0}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"6dfff15240319d9a","prefixes":{"":{"product":1254,"type":0}}}, // [Art of Click Pte. Ltd]
-  {"hash":"3771e4f81d75a524","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"b2d089ed26249e9c","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"6cb0920968e42462","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"779587babf9a845a","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"21fd838e467abf9e","prefixes":{"":{"product":44,"type":0}}}, // [Adways SAS]
-  {"hash":"f35db5d8e41be046","prefixes":{"":{"product":1255,"type":0}}}, // [Quantasy LLC]
-  {"hash":"fb881e61783803db","prefixes":{"":{"product":1256,"type":0}}}, // [Wavenet Technology Co., Ltd.]
-  {"hash":"4a5a7154d849b6df","prefixes":{"":{"product":1257,"type":0}}}, // [ENVISIONX LTD]
-  {"hash":"4c0fc55e8fe8be51","prefixes":{"":{"product":1258,"type":0}}}, // [Adhood]
-  {"hash":"62b3383734c496fb","prefixes":{"":{"product":1258,"type":0}}}, // [Adhood]
-  {"hash":"27e40c1642b59b0e","prefixes":{"":{"product":1258,"type":0}}}, // [Adhood]
-  {"hash":"b7bcec8f502b24cf","prefixes":{"":{"product":1258,"type":0}}}, // [Adhood]
-  {"hash":"b8885905bf9e213f","prefixes":{"":{"product":1258,"type":0}}}, // [Adhood]
-  {"hash":"8238d8729bb3748c","prefixes":{"":{"product":1259,"type":0}}}, // [Telogical Systems, LLC]
-  {"hash":"92dbc0e618f7816a","prefixes":{"":{"product":1259,"type":0}}}, // [Telogical Systems, LLC]
-  {"hash":"d3be8ee2ff24c8dd","prefixes":{"":{"product":1259,"type":0}}}, // [Telogical Systems, LLC]
-  {"hash":"0767b016186f9908","prefixes":{"":{"product":1260,"type":0}}}, // [twyn group IT solutions & marketing services G]
-  {"hash":"1bf7b44093f4c0b5","prefixes":{"":{"product":1261,"type":1}}}, // [Marchex Sales, LLC]
-  {"hash":"b60099c5a3ff5579","prefixes":{"":{"product":1262,"type":0}}}, // [SmartyAds LLP]
-  {"hash":"e1e5cbc69ff27126","prefixes":{"":{"product":1262,"type":0}}}, // [SmartyAds LLP]
-  {"hash":"01e34dcf6356f25b","prefixes":{"":{"product":1262,"type":0}}}, // [SmartyAds LLP]
-  {"hash":"0587980840cbad28","prefixes":{"":{"product":1262,"type":0}}}, // [SmartyAds LLP]
-  {"hash":"c13574923293d7c7","prefixes":{"":{"product":1263,"type":0}}}, // [Reach150 Social, Inc.]
-  {"hash":"e87358da2b6ad070","prefixes":{"":{"product":1264,"type":1}}}, // [Leadmill ApS]
-  {"hash":"2a24bd7dfe371075","prefixes":{"":{"product":1264,"type":1}}}, // [Leadmill ApS]
-  {"hash":"3f6b6ba536add909","prefixes":{"":{"product":1265,"type":0}}}, // [TapHeaven, Inc.]
-  {"hash":"050f2328d34461a7","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"a66968f05d34f468","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"2c309ae9bbbe9384","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"fec9fa0c1f3ffe6e","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"49989970caa95c3d","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"32eb6e39519c6d65","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"5ecf91c30b7a0a6a","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"6394e1f93c660614","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"3c6f41d29f5df8e7","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"cda46d94d7efda5c","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"164782d64f732408","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"af8c779439f17da0","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"0394176d4d575a93","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"c9a808631e01ad1a","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"1478be442db9d539","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"171f00354c5c6b43","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"521c6ad185dff69d","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"a7c6cb92086909f4","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"efb2ad70cb64944c","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"35e50ce841196503","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"683154a56472f3e2","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"6664d0e4be1a2011","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"efefa03759c8eb89","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"20477544dc10c916","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"922d2397edef5dbd","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"a9591e706ed0da18","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"c073c895bf061908","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"8a7804498832f633","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"45c2a9f766453c46","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"2a167f8c5d41c9de","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"0992810376313bba","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"e4588caa0c232726","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"73fbee089a438309","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"48743ee797fa8c98","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"22561af78d8aeebe","prefixes":{"":{"product":1266,"type":1}}}, // [spring GmbH & Co. KG]
-  {"hash":"ee6f381082694c53","prefixes":{"":{"product":1267,"type":0}}}, // [Roq.ad GmbH]
-  {"hash":"606e92e46118e68c","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"5dd554237e590e7a","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"47c55cdc2352963b","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"698477bb42f577d9","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"4d35613bf3c5608c","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"8bbcbb68e24aba75","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"b5d289baee77f3bb","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"1eab99893ccb6812","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"2d38a36747a2e4c8","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"2aaee44de4212440","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"720594080864ccd0","prefixes":{"":{"product":1268,"type":0}}}, // [AdKernel LLC]
-  {"hash":"8cf8db96c95ad703","prefixes":{"":{"product":1269,"type":0}}}, // [Uprise Technologies]
-  {"hash":"bdc43b963f1225e2","prefixes":{"":{"product":1270,"type":0}}}, // [Sled, Inc.]
-  {"hash":"bd39b2a3b45ba87e","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"987e96fd53ac3377","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"ae49bd17dd4ead54","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"8d132f34a86f51b3","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"4210564496763546","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"c395c961fb4a60ae","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"2f37a86d54dbe4f9","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"04730e3fb984e716","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"8e040ece0573e008","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"a2aafd8d622f674d","prefixes":{"":{"product":1271,"type":1}}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"4da566f98e41e44f","prefixes":{"":{"product":1272,"type":0}}}, // [Adello Group AG]
-  {"hash":"469779ba0b2d7340","prefixes":{"":{"product":1273,"type":2}}}, // [BitGravity]
-  {"hash":"bfa6d675fa0c17c3","prefixes":{"":{"product":1274,"type":1}}}, // [44 Interactive]
-  {"hash":"d36cc93ea8fd1701","prefixes":{"":{"product":1275,"type":0}}}, // [Shopalyst Technologies Pvt Ltd]
-  {"hash":"95ad856091f4bc84","prefixes":{"":{"product":1275,"type":0}}}, // [Shopalyst Technologies Pvt Ltd]
-  {"hash":"848239e92ef8cdab","prefixes":{"":{"product":1276,"type":0}}}, // [Total Access Communication Public Company Limited]
-  {"hash":"0607ff309fec62de","prefixes":{"":{"product":1277,"type":0}}}, // [TACTIC Real-time marketing AS]
-  {"hash":"abcc33d7fb9de6d9","prefixes":{"":{"product":1278,"type":0}}}, // [Mobilewalla, Inc]
-  {"hash":"c7bbc2be78119074","prefixes":{"":{"product":1279,"type":0}}}, // [Nuviad Ltd]
-  {"hash":"63da29d5b072ec2a","prefixes":{"*":{"product":1280}}}, // [AmberData LLC]
-  {"hash":"6c2f34d23d272f4b","prefixes":{"":{"product":1281,"type":0}}}, // [Aedgency]
-  {"hash":"2da837b490e2d01c","prefixes":{"":{"product":1282,"type":0}}}, // [MobPartner, Inc.]
-  {"hash":"900c7f6444e6ccdd","prefixes":{"":{"product":1283,"type":1}}}, // [AdTriba GmbH]
-  {"hash":"9110b2853fbfc1f4","prefixes":{"":{"product":1283,"type":1}}}, // [AdTriba GmbH]
-  {"hash":"0a9e29016a6f697e","prefixes":{"":{"product":1284,"type":1}}}, // [DISH Network L.L.C.]
-  {"hash":"8c7746484c824908","prefixes":{"":{"product":1285}}}, // [Monotype Imaging Inc.]
-  {"hash":"11826b3490b70597","prefixes":{"":{"product":1285}}}, // [Monotype Imaging Inc.]
-  {"hash":"55b9261efb54de8c","prefixes":{"":{"product":1285}}}, // [Monotype Imaging Inc.]
-  {"hash":"57f3bae0dc69937f","prefixes":{"":{"product":1285}}}, // [Monotype Imaging Inc.]
-  {"hash":"b5158a795c80a5a2","prefixes":{"":{"product":1286,"type":1}}}, // [MEDIAN Ltd.]
-  {"hash":"e79098d30fde1a28","prefixes":{"":{"product":1287,"type":0}}}, // [ClickForce Inc.]
-  {"hash":"36739070f3c0ff16","prefixes":{"":{"product":1287,"type":0}}}, // [ClickForce Inc.]
-  {"hash":"40febfb412ba6ddb","prefixes":{"":{"product":1288,"type":0}}}, // [Zemanta Inc.]
-  {"hash":"80e8d865a27bacac","prefixes":{"":{"product":234,"type":0}}}, // [Hostelworld.com Limited]
-  {"hash":"2a3acfae7d4bdd9b","prefixes":{"":{"product":850,"type":0}}}, // [Barometric]
-  {"hash":"a48dde8fab3a9ca1","prefixes":{"*":{"product":1289,"type":0}}}, // [jsdelivr.com]
-  {"hash":"82b544dbc2fdd536","prefixes":{"*":{"product":1290,"type":0}}}, // [Adssets AB]
-  {"hash":"46106972e3ebaddb","prefixes":{"":{"product":1291,"type":1}}}, // [Sellpoints Inc.]
-  {"hash":"bbc8c43681364c14","prefixes":{"":{"product":45,"type":0}}}, // [Opera Mediaworks Inc.]
-  {"hash":"a3ff6df6612f21df","prefixes":{"":{"product":45,"type":0}}}, // [Opera Mediaworks Inc.]
-  {"hash":"759162b5823db802","prefixes":{"":{"product":1292,"type":0}}}, // [HockeyCurve Growth Solutions Pvt Ltd]
-  {"hash":"b3f9f03fb2c77a95","prefixes":{"":{"product":1293,"type":1}}}, // [HockeyCurve Growth Solutions Pyt Ltd]
-  {"hash":"0dcbeed5fe35278e","prefixes":{"":{"product":1293,"type":1}}}, // [HockeyCurve Growth Solutions Pyt Ltd]
-  {"hash":"e6898006d78eca08","prefixes":{"":{"product":1294,"type":1}}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"c2ecb9f34950ae64","prefixes":{"":{"product":1294,"type":1}}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"e530de1f6ff8ed8c","prefixes":{"":{"product":1294,"type":1}}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"ef9efb2dfd9b223f","prefixes":{"":{"product":1294,"type":1}}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"8dad79c9e968f7ca","prefixes":{"":{"product":1295,"type":1}}}, // [Survata, Inc.]
-  {"hash":"7a5110db80c0493f","prefixes":{"":{"product":1295,"type":1}}}, // [Survata, Inc.]
-  {"hash":"e8cb0ee7c430e881","prefixes":{"":{"product":1296,"type":1}}}, // [JustWatch GmbH]
-  {"hash":"c85404f2f558dbd2","prefixes":{"":{"product":1296,"type":1}}}, // [JustWatch GmbH]
-  {"hash":"b44b63d6e81094e4","prefixes":{"":{"product":1296,"type":1}}}, // [JustWatch GmbH]
-  {"hash":"e1614140e3cef4fd","prefixes":{"":{"product":1296,"type":1}}}, // [JustWatch GmbH]
-  {"hash":"2cfd0204e2673c60","prefixes":{"":{"product":1297,"type":1}}}, // [Interactive Tracker Next]
-  {"hash":"1c5f8f88ce98b360","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"fbac71ab5dbe5025","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"4e08c60f61b1ac87","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"3f4bfa67b5290ada","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"a9b4af4145bf90b2","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"d0d20b9b53b41e58","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"ff37598c00132a2a","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"daae3b285b4abeee","prefixes":{"":{"product":1298}}}, // [Unisport A/S]
-  {"hash":"20cdb1f9a8066fe2","prefixes":{"":{"product":1299,"type":0}}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
-  {"hash":"a53281df69681314","prefixes":{"":{"product":1299,"type":0}}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
-  {"hash":"f25344f6f85b0f61","prefixes":{"":{"product":1299,"type":0}}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
-  {"hash":"b544d72a6726ee1d","prefixes":{"":{"product":1300,"type":0}}}, // [Softcube Inc.]
-  {"hash":"d924c399f5813397","prefixes":{"":{"product":1301,"type":0}}}, // [YOptima Media Solutions Pvt. Ltd]
-  {"hash":"3405e57b3b784a16","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"8a5251fd38cf1d3b","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"039987610c50338a","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"0f7d3c301f70dfd0","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"77f81cf76bb9bd07","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"ec6a93785f45f030","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"3fcf5b9a36bb776b","prefixes":{"":{"product":1302}}}, // [ZMAGS INC]
-  {"hash":"b81945950b163ad1","prefixes":{"":{"product":1293,"type":1}}}, // [HockeyCurve Growth Solutions Pyt Ltd]
-  {"hash":"36c7ea48fdc42362","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"a3bfc331d20ba3e8","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"64a6cb69505f47a8","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"e7d85f73b7514aa9","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"0263af098607c6d6","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"5c911e8fdb9b3507","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"665d12aaa10c1858","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"206d02e9bc6dc66f","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"681210fb48272cc7","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"f42b80ceeefbc2e4","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"9b951656519bc7f0","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"f615949643fdcebb","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"814934c13235b868","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"d451d289ed990ba0","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"b2de6bb8607f747e","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"fa9dba37389c8a9e","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"fe776ee0016175b8","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"1a561a0db871620b","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"84440122e5725865","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"f98baedc7354d85b","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"cedef135a07c2d1b","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"b7196f696d55352b","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"90c8f9118f9c2653","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"227010fe11d13050","prefixes":{"":{"product":1303,"type":0}}}, // [Aniview LTD.]
-  {"hash":"5460e19d75ae0d01","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"7ec460729f94a446","prefixes":{"":{"product":1304,"type":1}}}, // [Realtag]
-  {"hash":"c84baed94e3d3a6c","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"88c72a0edf15af94","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"8ffa9e7ae82fdaf3","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"b2b5e138d12de438","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"1249b88e4ce20439","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"9555623f08217ce6","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"0358d164ffcdc51b","prefixes":{"":{"product":1305}}}, // [Bitsngo.net]
-  {"hash":"d27b1458c8f91a54","prefixes":{"":{"product":1306,"type":0}}}, // [AdCanvas]
-  {"hash":"5fd4bc3f3699146f","prefixes":{"":{"product":1306,"type":0}}}, // [AdCanvas]
-  {"hash":"62f35089b9876ae5","prefixes":{"":{"product":1306,"type":0}}}, // [AdCanvas]
-  {"hash":"92d701b4810ee717","prefixes":{"":{"product":1306,"type":0}}}, // [AdCanvas]
-  {"hash":"3f927191adac8a66","prefixes":{"":{"product":1306,"type":0}}}, // [AdCanvas]
-  {"hash":"051c9e70f0515e04","prefixes":{"":{"product":1307,"type":0}}}, // [Happyfication, Inc.]
-  {"hash":"13580fc82945639c","prefixes":{"":{"product":1307,"type":0}}}, // [Happyfication, Inc.]
-  {"hash":"914acd1211445b65","prefixes":{"":{"product":1307,"type":0}}}, // [Happyfication, Inc.]
-  {"hash":"046e11a0cbc2124d","prefixes":{"":{"product":1307,"type":0}}}, // [Happyfication, Inc.]
-  {"hash":"df5483bdd241c0b5","prefixes":{"":{"product":254}}}, // [HQ GmbH]
-  {"hash":"8ee2f36b1789e47d","prefixes":{"":{"product":1308,"type":0},"*":{"product":1309,"type":0}}}, // [Cinarra Systems Japan株式会社] [Cinarra Systems Japan]
-  {"hash":"92d76828c2bc5e86","prefixes":{"":{"product":946,"type":0}}}, // [MotoMiner]
-  {"hash":"014c99288a655e93","prefixes":{"":{"product":1310,"type":1}}}, // [CUBED Attribution]
-  {"hash":"34d44a28a42c30fc","prefixes":{"":{"product":1310,"type":1}}}, // [CUBED Attribution]
-  {"hash":"6525e4a55892b035","prefixes":{"":{"product":1311,"type":0}}}, // [StackAdapt Inc.]
-  {"hash":"9108433b6be75366","prefixes":{"":{"product":1311,"type":0}}}, // [StackAdapt Inc.]
-  {"hash":"ca5914cdc3f95c5a","prefixes":{"":{"product":1311,"type":0}}}, // [StackAdapt Inc.]
-  {"hash":"e25d7e6b7298b655","prefixes":{"":{"product":1312,"type":1}}}, // [Statiq Ltd]
-  {"hash":"63a988f83e509eca","prefixes":{"":{"product":46,"type":0}}}, // [DistroScale Inc.]
-  {"hash":"e6c8188134efb49f","prefixes":{"":{"product":46,"type":0}}}, // [DistroScale Inc.]
-  {"hash":"eab29bab9fd4b969","prefixes":{"":{"product":46,"type":0}}}, // [DistroScale Inc.]
-  {"hash":"c24f6dcb16cfd4e4","prefixes":{"":{"product":46,"type":0}}}, // [DistroScale Inc.]
-  {"hash":"e6a95c6bb8d6efd4","prefixes":{"":{"product":1313,"type":1}}}, // [Tagular Analytics, LLC]
-  {"hash":"9c2dcc6473dee219","prefixes":{"":{"product":1313,"type":1}}}, // [Tagular Analytics, LLC]
-  {"hash":"986af10dd127ff07","prefixes":{"":{"product":1313,"type":1}}}, // [Tagular Analytics, LLC]
-  {"hash":"f74107ff21d433e9","prefixes":{"":{"product":1313,"type":1}}}, // [Tagular Analytics, LLC]
-  {"hash":"ce5c1378f1f941f6","prefixes":{"":{"product":1314,"type":0}}}, // [ComboTag Technologies Ltd.]
-  {"hash":"879f914a15df34e0","prefixes":{"":{"product":1315,"type":0}}}, // [Juice Mobile]
-  {"hash":"17e1300dbcc39afb","prefixes":{"":{"product":1315,"type":0}}}, // [Juice Mobile]
-  {"hash":"d22e60c27d37cebc","prefixes":{"":{"product":1315,"type":0}}}, // [Juice Mobile]
-  {"hash":"80d91748976f3124","prefixes":{"":{"product":1315,"type":0}}}, // [Juice Mobile]
-  {"hash":"74478806654499c0","prefixes":{"":{"product":1315,"type":0}}}, // [Juice Mobile]
-  {"hash":"1b02f5c5bfc0039d","prefixes":{"":{"product":1315,"type":0}}}, // [Juice Mobile]
-  {"hash":"ee644eb69f62cdec","prefixes":{"":{"product":1316,"type":0}}}, // [Bebe]
-  {"hash":"8fb13ead8b0754fb","prefixes":{"":{"product":1317,"type":1}}}, // [Augur]
-  {"hash":"cfbc4ef83efc3949","prefixes":{"*":{"product":1318,"type":0}}}, // [Seracast Digital LLC]
-  {"hash":"a8285782e9e5e7e8","prefixes":{"*":{"product":1318}}}, // [Seracast Digital LLC]
-  {"hash":"3a9b5e5bcd74ba27","prefixes":{"":{"product":1319,"type":0}}}, // [AerServ LLC]
-  {"hash":"dd4e82ee18499196","prefixes":{"":{"product":1319}}}, // [AerServ LLC]
-  {"hash":"2163ccdaf0c7ac04","prefixes":{"*":{"product":1308,"type":0}}}, // [Cinarra Systems Japan株式会社]
-  {"hash":"e16e6171a3e50ef3","prefixes":{"":{"product":1320,"type":0}}}, // [PT. Tokopedia]
-  {"hash":"74b1225f4470815b","prefixes":{"":{"product":1321,"type":0}}}, // [Terapeak, Inc.]
-  {"hash":"7eb7af632c622616","prefixes":{"*":{"product":1322}}}, // [OpenStreetMap France]
-  {"hash":"63c3a3e6536f0b7f","prefixes":{"*":{"product":1323,"type":0}}}, // [Front Porch, Inc]
-  {"hash":"2c6aaec84cacd716","prefixes":{"*":{"product":1323,"type":0}}}, // [Front Porch, Inc]
-  {"hash":"6f469a516e0ea586","prefixes":{"":{"product":1324,"type":0}}}, // [Vertamedia]
-  {"hash":"d06485ea48298b7e","prefixes":{"":{"product":1325,"type":0}}}, // [Codewise (VoluumDSP)]
-  {"hash":"7a43b35e42bcef39","prefixes":{"":{"product":1326,"type":0}}}, // [Virool Inc.]
-  {"hash":"4ff7c90f1d23d419","prefixes":{"":{"product":1327,"type":0}}}, // [SpringServe LLC]
-  {"hash":"7f06352affc07566","prefixes":{"":{"product":1327,"type":0}}}, // [SpringServe LLC]
-  {"hash":"96ea998589a3f7ab","prefixes":{"":{"product":1327,"type":0}}}, // [SpringServe LLC]
-  {"hash":"32ec7c3af8d6ee95","prefixes":{"":{"product":1327,"type":0}}}, // [SpringServe LLC]
-  {"hash":"294e9804817557ed","prefixes":{"":{"product":1327,"type":0}}}, // [SpringServe LLC]
-  {"hash":"e9c681d4af45ad2c","prefixes":{"":{"product":1328,"type":1}}}, // [Intimate Merger]
-  {"hash":"68cc07724e870731","prefixes":{"":{"product":1328,"type":1}}}, // [Intimate Merger]
-  {"hash":"60f3c72e07bc4431","prefixes":{"":{"product":1329,"type":0}}}, // [Telecoming Connectivity S.A.]
-  {"hash":"22081b94e890803c","prefixes":{"":{"product":1330,"type":0}}}, // [Webssup]
-  {"hash":"00e22da76abf1e12","prefixes":{"":{"product":1330,"type":0}}}, // [Webssup]
-  {"hash":"498495a391901f22","prefixes":{"":{"product":1331,"type":1}}}, // [INCUBIQ Solutions Ltd]
-  {"hash":"606c712ed1507693","prefixes":{"":{"product":1331,"type":1}}}, // [INCUBIQ Solutions Ltd]
-  {"hash":"a9af6bbd9a022211","prefixes":{"*":{"product":1323}}}, // [Front Porch, Inc]
-  {"hash":"5ad9370da8c17992","prefixes":{"":{"product":1332,"type":0}}}, // [ADSpend]
-  {"hash":"fdd6cbfd0c4ad857","prefixes":{"":{"product":1333}}}, // [AdTradr Corporation]
-  {"hash":"81b9923f85553957","prefixes":{"":{"product":1333}}}, // [AdTradr Corporation]
-  {"hash":"a145ad19f618929c","prefixes":{"":{"product":1333}}}, // [AdTradr Corporation]
-  {"hash":"b1930e60745f4b68","prefixes":{"":{"product":1333}}}, // [AdTradr Corporation]
-  {"hash":"57f97d99aaf44ad1","prefixes":{"":{"product":1333}}}, // [AdTradr Corporation]
-  {"hash":"99143cae9fe8dcb7","prefixes":{"":{"product":1334,"type":0}}}, // [Quint Growth Inc.]
-  {"hash":"eb5cead7881dc3da","prefixes":{"":{"product":1335,"type":0}}}, // [ZAPR]
-  {"hash":"2fe0bb9349d1959b","prefixes":{"":{"product":1335}}}, // [ZAPR]
-  {"hash":"b959bccbc132d322","prefixes":{"":{"product":26,"type":1}}}, // [On Device Research Ltd.]
-  {"hash":"8a8c554522b206ad","prefixes":{"":{"product":1336}}}, // [1trn LLC]
-  {"hash":"45dfdbe509539a3b","prefixes":{"":{"product":1336,"type":0}}}, // [1trn LLC]
-  {"hash":"6265ceee0906cac8","prefixes":{"":{"product":1337,"type":0}}}, // [Matiro]
-  {"hash":"279177f20ce276af","prefixes":{"":{"product":1337,"type":0}}}, // [Matiro]
-  {"hash":"b90e8e5f5f114049","prefixes":{"":{"product":1337,"type":0}}}, // [Matiro]
-  {"hash":"68519953a094dc0c","prefixes":{"":{"product":1337,"type":0}}}, // [Matiro]
-  {"hash":"2c9356fdc6a3d512","prefixes":{"":{"product":1337,"type":0}}}, // [Matiro]
-  {"hash":"486312e316f3d301","prefixes":{"":{"product":1337,"type":0}}}, // [Matiro]
-  {"hash":"0dea0840245a2dd2","prefixes":{"*":{"product":1338,"type":0}}}, // [Inspired Mobile Ltd.]
-  {"hash":"e1e444909b156b50","prefixes":{"*":{"product":1338,"type":0}}}, // [Inspired Mobile Ltd.]
-  {"hash":"ba50b6623ecf06b7","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"bb2433b4d9ceaf93","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"752e7bd32ca03e2b","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"fecd6600c1d54571","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"e2f5a8707a39a63f","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"6e7cd3eb7639d09a","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"e0afc2f779238a59","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"51c4028642a5ca4c","prefixes":{"":{"product":1339,"type":0}}}, // [Selectmedia International LTD.]
-  {"hash":"1640e1eeb06df964","prefixes":{"":{"product":1339}}}, // [Selectmedia International LTD.]
-  {"hash":"6c8c2f363cf647b5","prefixes":{"":{"product":1339}}}, // [Selectmedia International LTD.]
-  {"hash":"d9f31e1a90e8fb75","prefixes":{"":{"product":1339}}}, // [Selectmedia International LTD.]
-  {"hash":"845fb9c6387bef97","prefixes":{"":{"product":1339}}}, // [Selectmedia International LTD.]
-  {"hash":"0459341df70cc072","prefixes":{"":{"product":1339}}}, // [Selectmedia International LTD.]
-  {"hash":"be68419b316ae4c5","prefixes":{"":{"product":1340,"type":0}}}, // [Internet Billboard, a. s]
-  {"hash":"ba9be76fe6cba556","prefixes":{"":{"product":1340,"type":0}}}, // [Internet Billboard, a. s]
-  {"hash":"ec3aa5f11c754de6","prefixes":{"":{"product":1340,"type":0}}}, // [Internet Billboard, a. s]
-  {"hash":"5023d333c14740b4","prefixes":{"":{"product":1340,"type":0}}}, // [Internet Billboard, a. s]
-  {"hash":"eab4b496bc09743b","prefixes":{"":{"product":1341,"type":0}}}, // [Volvelle]
-  {"hash":"2afdaf8d1bad3cb9","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"c2367faa0f667908","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"ed58e98b46833296","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"e0249363e0c7a5fa","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"3f6dfa5fad816543","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"0daca079a0ddd2c5","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"eb2192ea666d6dfe","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"6a1269cf9dab66ee","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"39079f1183b1a260","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"9455a8e3fa7e9a01","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"bebc1faa9d73b7b0","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"c5069619b84c740e","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"8effee3cd53dcfe8","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"8251bfe6accaab04","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"f1019f4619cbfe25","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"825efa7e6eea91b6","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"cdeee95936c4dbc6","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"812ac20217e10e22","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"a20318efcc942b0c","prefixes":{"":{"product":1342}}}, // [StreamRail Ltd.]
-  {"hash":"7ba3379a648cbc77","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"faca10de01f9747f","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"c4bada2290c2b41f","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"7e8290508a81ecfd","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"415fbdfa7cf95914","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"97322010e9179343","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"07549a667fcd0003","prefixes":{"":{"product":1343,"type":0}}}, // [E-Contenta]
-  {"hash":"f5359f09115e5a08","prefixes":{"":{"product":1344,"type":0}}}, // [Bath and Body Works]
-  {"hash":"93931937deeacde2","prefixes":{"":{"product":1149}}}, // [KuaiziTech]
-  {"hash":"885efbcb155efd68","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"8515f5e803de693b","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"7990fea9b4cdbdf9","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"a6632e804a3dc853","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"ae4745b0fd104fbb","prefixes":{"":{"product":1303}}}, // [Aniview LTD.]
-  {"hash":"956dc47eeadd36f7","prefixes":{"":{"product":1345,"type":0}}}, // [WooTag Pte Ltd]
-  {"hash":"091b478316a2c133","prefixes":{"":{"product":1345,"type":0}}}, // [WooTag Pte Ltd]
-  {"hash":"dc8fa04b592b8307","prefixes":{"":{"product":1345,"type":0}}}, // [WooTag Pte Ltd]
-  {"hash":"fe0e326ac7dc8d7c","prefixes":{"":{"product":1345}}}, // [WooTag Pte Ltd]
-  {"hash":"410a107d660ab1cd","prefixes":{"":{"product":1346,"type":1}}}, // [Cint AB]
-  {"hash":"b294fa0e55fcd2f4","prefixes":{"":{"product":1346,"type":1}}}, // [Cint AB]
-  {"hash":"5519fa5da5e57ad1","prefixes":{"":{"product":1347,"type":0}}}, // [Stein Mart]
-  {"hash":"7277d1fc5bc3c416","prefixes":{"":{"product":1348,"type":0}}}, // [Sift Media, Inc.]
-  {"hash":"4b89510469e15939","prefixes":{"":{"product":1349,"type":0}}}, // [StartApp Inc.]
-  {"hash":"d3b5600174198250","prefixes":{"":{"product":1349,"type":0}}}, // [StartApp Inc.]
-  {"hash":"5597070a34018ed8","prefixes":{"":{"product":1349,"type":0}}}, // [StartApp Inc.]
-  {"hash":"17f290970639d124","prefixes":{"":{"product":1350,"type":0}}}, // [Pxene - DSP]
-  {"hash":"263ee2028bc08b39","prefixes":{"":{"product":1350,"type":0}}}, // [Pxene - DSP]
-  {"hash":"da0f3a897355dd67","prefixes":{"":{"product":1350,"type":0}}}, // [Pxene - DSP]
-  {"hash":"9ca84ba93389421b","prefixes":{"":{"product":1350,"type":0}}}, // [Pxene - DSP]
-  {"hash":"4d5f045a10baa819","prefixes":{"":{"product":1351,"type":0}}}, // [Integral Marketing]
-  {"hash":"50bc395b6101613b","prefixes":{"":{"product":1351}}}, // [Integral Marketing]
-  {"hash":"3affd533937e3000","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"971d313a32301476","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"c5351f32e51be2fe","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"4d91e6834270bed5","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"5d662bce285c4f62","prefixes":{"":{"product":47,"type":0}}}, // [Enzymic Consultancy]
-  {"hash":"acf96648fc83494b","prefixes":{"":{"product":47}}}, // [Enzymic Consultancy]
-  {"hash":"ea62a03194f9fd95","prefixes":{"":{"product":1352}}}, // [Expedia, Inc.]
-  {"hash":"d3ff1633dded1329","prefixes":{"":{"product":1353,"type":0}}}, // [DeepIntent, Inc]
-  {"hash":"2b5d6ad4574423ab","prefixes":{"":{"product":1353,"type":0}}}, // [DeepIntent, Inc]
-  {"hash":"dd8c5b641bb2871c","prefixes":{"":{"product":1353,"type":0}}}, // [DeepIntent, Inc]
-  {"hash":"4ba3d981f5073f12","prefixes":{"":{"product":1353,"type":0}}}, // [DeepIntent, Inc]
-  {"hash":"92f845f3cbfc83ca","prefixes":{"":{"product":179,"type":1}}}, // [Rakuten Attribution]
-  {"hash":"ff93f30e29dd79ce","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"1219256c57d362c2","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"588a30ada75d3716","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"f99b3a1ad217ec24","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"cffe29c52b1b73c5","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"f03d942c23c65a90","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"272d4c035a088de6","prefixes":{"":{"product":1354,"type":0}}}, // [OmniVirt]
-  {"hash":"724568d0c3fc08a4","prefixes":{"":{"product":1355,"type":0}}}, // ["Index20" LLC]
-  {"hash":"be108323d132726d","prefixes":{"":{"product":1356,"type":1}}}, // [Conversion Logic, Inc.]
-  {"hash":"9fc3b91614502933","prefixes":{"":{"product":1357}}}, // [Collegehumor]
-  {"hash":"bb96895ad0b3fb46","prefixes":{"":{"product":1357}}}, // [Collegehumor]
-  {"hash":"830074aed1a53d22","prefixes":{"":{"product":1357}}}, // [Collegehumor]
-  {"hash":"db32b2c0136553c9","prefixes":{"":{"product":764,"type":0}}}, // [Netflix, Inc.]
-  {"hash":"47df197461b802d5","prefixes":{"":{"product":764,"type":0}}}, // [Netflix, Inc.]
-  {"hash":"acbf0ad8badc6915","prefixes":{"":{"product":764,"type":0}}}, // [Netflix, Inc.]
-  {"hash":"c0b6c8d5b1736dc3","prefixes":{"":{"product":764,"type":0}}}, // [Netflix, Inc.]
-  {"hash":"05dd2a6c687d34c0","prefixes":{"":{"product":1358,"type":0}}}, // [Silence Media Limited]
-  {"hash":"cea7d6ed17648fbf","prefixes":{"":{"product":1358,"type":0}}}, // [Silence Media Limited]
-  {"hash":"ad7149f316532231","prefixes":{"":{"product":1359,"type":0}}}, // [Zuuvi Aps]
-  {"hash":"693751faddbb5801","prefixes":{"":{"product":1359,"type":0}}}, // [Zuuvi Aps]
-  {"hash":"8da87b729d579d09","prefixes":{"":{"product":1359,"type":0}}}, // [Zuuvi Aps]
-  {"hash":"ab5cc3951d346c77","prefixes":{"":{"product":1359,"type":0}}}, // [Zuuvi Aps]
-  {"hash":"f41a4b1ac6a3bfb2","prefixes":{"":{"product":1360,"type":1}}}, // [SoftBank Corp.]
-  {"hash":"1d0977195dc18825","prefixes":{"":{"product":1361,"type":0}}}, // [ConnectOM, Inc.]
-  {"hash":"912365bfc81f780a","prefixes":{"":{"product":1361,"type":0}}}, // [ConnectOM, Inc.]
-  {"hash":"7434a888611cfaf2","prefixes":{"":{"product":1361,"type":0}}}, // [ConnectOM, Inc.]
-  {"hash":"1d73404a4d6b3cda","prefixes":{"":{"product":48,"type":0}}}, // [Fluct Inc.]
-  {"hash":"938fa93131d63045","prefixes":{"":{"product":48,"type":0}}}, // [Fluct Inc.]
-  {"hash":"67f35499d1bf5216","prefixes":{"":{"product":1362,"type":0}}}, // [Skillup Video Technologies Corporation]
-  {"hash":"c8e2c0c42c388ceb","prefixes":{"":{"product":1362,"type":0}}}, // [Skillup Video Technologies Corporation]
-  {"hash":"0800074e9a8aa9e0","prefixes":{"":{"product":1362}}}, // [Skillup Video Technologies Corporation]
-  {"hash":"f6853fba1d5c8366","prefixes":{"":{"product":1363,"type":1}}}, // [Adara Impact Analytics]
-  {"hash":"7d5aa0875b5b03ee","prefixes":{"":{"product":1363,"type":1}}}, // [Adara Impact Analytics]
-  {"hash":"e1a55205d635d049","prefixes":{"":{"product":1363,"type":1}}}, // [Adara Impact Analytics]
-  {"hash":"b5ea51bb0aec174c","prefixes":{"":{"product":1363,"type":1}}}, // [Adara Impact Analytics]
-  {"hash":"e4140b78afda4fb4","prefixes":{"":{"product":1363,"type":1}}}, // [Adara Impact Analytics]
-  {"hash":"a4c74032025e0589","prefixes":{"":{"product":1364,"type":0}}}, // [TabMo SAS]
-  {"hash":"d9638d78485cff41","prefixes":{"":{"product":1364,"type":0}}}, // [TabMo SAS]
-  {"hash":"6ea3e003ed64d138","prefixes":{"":{"product":57,"type":1}}}, // [Sixt Leasing SE]
-  {"hash":"22ae0beb131c4b8c","prefixes":{"":{"product":1365,"type":0}}}, // [Casale Media]
-  {"hash":"29d1aaca6b9e6edd","prefixes":{"":{"product":1365,"type":0}}}, // [Casale Media]
-  {"hash":"7d1380d196e0f347","prefixes":{"":{"product":1366,"type":0}}}, // [StickyADStv]
-  {"hash":"147ac7b767355a32","prefixes":{"":{"product":1367,"type":0}}}, // [Teads Technology SAS]
-  {"hash":"4b60266ba860a4c5","prefixes":{"":{"product":1368,"type":1}}}, // [Anomaly Communications, LLC]
-  {"hash":"296893a9570ca935","prefixes":{"*":{"product":1369,"type":0}}}, // [ClickTicker, LTD]
-  {"hash":"094df71f27ebd6f1","prefixes":{"":{"product":1370,"type":0}}}, // [Tremour]
-  {"hash":"a1119d262b86de34","prefixes":{"":{"product":1371}}}, // [Roket Media LTD]
-  {"hash":"b1ed20b79d8a43cb","prefixes":{"":{"product":150}}}, // [e-Planning]
-  {"hash":"5bd05c801bb32096","prefixes":{"":{"product":1372,"type":0}}}, // [Video Jam (MauDau LTD)]
-  {"hash":"dacf613410c17f5e","prefixes":{"":{"product":1372,"type":0}}}, // [Video Jam (MauDau LTD)]
-  {"hash":"561f104ba38d6e64","prefixes":{"":{"product":1372}}}, // [Video Jam (MauDau LTD)]
-  {"hash":"a43509d6a08d1777","prefixes":{"":{"product":1373,"type":0}}}, // [MINIMOB (CY) LTD]
-  {"hash":"b66514ac6530a3fd","prefixes":{"":{"product":1374,"type":0}}}, // [Snitcher B.V.]
-  {"hash":"79b3660bde132ba1","prefixes":{"":{"product":1374,"type":0}}}, // [Snitcher B.V.]
-  {"hash":"aaf7781b800509ba","prefixes":{"":{"product":1374,"type":0}}}, // [Snitcher B.V.]
-  {"hash":"8fec6c672f5b204a","prefixes":{"":{"product":1374,"type":0}}}, // [Snitcher B.V.]
-  {"hash":"825e7df4dfb9bae0","prefixes":{"":{"product":1374,"type":0}}}, // [Snitcher B.V.]
-  {"hash":"379899626d07c3b5","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"664ce6265f73ec6a","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"ab33f6650feb44c2","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"557404c787c545cb","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"0c881f692e8ec0de","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"36c7264c1d06cc29","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"2f7b75786675821b","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"714fd218f12fce7a","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"d140a5f747a666f1","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"cbcfd9d592f2d19d","prefixes":{"":{"product":1375,"type":1}}}, // [Analights]
-  {"hash":"a214f6ac537cafa2","prefixes":{"":{"product":1376,"type":1}}}, // [Romir Panel Ltd.]
-  {"hash":"84fe21a8c3ba3818","prefixes":{"":{"product":1377,"type":0}}}, // [Dievision]
-  {"hash":"c709bff0d2284ecc","prefixes":{"":{"product":1378,"type":1}}}, // [Ignite Technologies]
-  {"hash":"3510f10ff5914868","prefixes":{"*":{"product":1379,"type":1}}}, // [Navegg]
-  {"hash":"ea594377060cafc6","prefixes":{"":{"product":1380,"type":1}}}, // [Adalyser]
-  {"hash":"631a68a191554bae","prefixes":{"":{"product":1380,"type":1}}}, // [Adalyser]
-  {"hash":"8d9638d9355607ba","prefixes":{"":{"product":1380,"type":1}}}, // [Adalyser]
-  {"hash":"d6e288fc5cf14c83","prefixes":{"":{"product":1380,"type":1}}}, // [Adalyser]
-  {"hash":"90ec5cb29381e1ca","prefixes":{"":{"product":1380,"type":1}}}, // [Adalyser]
-  {"hash":"3debdfa22ee00230","prefixes":{"":{"product":1380,"type":1}}}, // [Adalyser]
-  {"hash":"45852dff86c0a7e0","prefixes":{"":{"product":1381,"type":0}}}, // [Nordic Factory International Inc.]
-  {"hash":"063e04585364c0e5","prefixes":{"":{"product":709,"type":0}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"aa4bfba1bb15cb76","prefixes":{"":{"product":709,"type":0}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"3f43b05864c28c77","prefixes":{"":{"product":1382,"type":1}}}, // [Addition Plus Ltd]
-  {"hash":"9e1057ca77b6610c","prefixes":{"":{"product":1382,"type":1}}}, // [Addition Plus Ltd]
-  {"hash":"a6278ebdf3ca7bce","prefixes":{"":{"product":1383,"type":0}}}, // [Karmatech Mediaworks Pvt Ltd]
-  {"hash":"954044969f047c6c","prefixes":{"":{"product":1383,"type":0}}}, // [Karmatech Mediaworks Pvt Ltd]
-  {"hash":"ca32fcf3a3101ca0","prefixes":{"":{"product":1384,"type":0}}}, // [Mediatropy Pte Ltd]
-  {"hash":"54a24d41044c0730","prefixes":{"":{"product":4,"type":0}}}, // [FSN ASIA PRIVATE LIMITED]
-  {"hash":"b3302c4e4fc23cb8","prefixes":{"":{"product":845}}}, // [Adman Interactive SL]
-  {"hash":"328eed54ff330e78","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"98ed7d7c1ae050b7","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"226e8c98a3e2e091","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"9e777471181caa70","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"9df613858a859407","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"37af06459214925d","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"0fdc04aa3cd4e402","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"f33f14a479b17a13","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"535ad6947981986b","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"0db16a6e891b1ff5","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"11b3c502d4eb1fa3","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"001bd6970eef2bbe","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"93505db1f9bf4a47","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"a1c9ac37054fc828","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"f4f375e269f34a60","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"e61b3b137beecfbc","prefixes":{"":{"product":1385,"type":0}}}, // [Wayve Limited]
-  {"hash":"07bf22fe56be8d20","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"619e27568b55894c","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"374b60567f3c7f8b","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"af11cb377f269b3b","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"6bd694da478fa87b","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"75c4aedcbc945c91","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"71e8a51762fe81b6","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"5412f8017660207b","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"ba29363e3e139066","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"05de1e7e9f3271c3","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"5d73b4b9b8705846","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"711d9c4ce084aa7d","prefixes":{"*":{"product":1386,"type":1}}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"1ed6fde4c65ef6f7","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"4a6b1490dc059d0b","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"cab81dbe20c0957f","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"af1f3ce39e3b4862","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"19e97b139ae15342","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"fb46fee1ceef4719","prefixes":{"*":{"product":265,"type":1}}}, // [DePauli AG]
-  {"hash":"798bda76da15abeb","prefixes":{"*":{"product":27,"type":1}}}, // [SuperVista AG]
-  {"hash":"38bf7a598ad0c498","prefixes":{"*":{"product":27,"type":1}}}, // [SuperVista AG]
-  {"hash":"48651b09d312b814","prefixes":{"*":{"product":27,"type":1}}}, // [SuperVista AG]
-  {"hash":"bb2482d6022a94ba","prefixes":{"*":{"product":27,"type":1}}}, // [SuperVista AG]
-  {"hash":"d58f8af9ff4e691e","prefixes":{"":{"product":1387,"type":0}}}, // [Yengo]
-  {"hash":"8e9bee1bb54d54ee","prefixes":{"":{"product":1387}}}, // [Yengo]
-  {"hash":"06689ed650e2b8c3","prefixes":{"":{"product":1388,"type":1}}}, // [DANtrack]
-  {"hash":"96c97b30a03579ac","prefixes":{"":{"product":1388,"type":1}}}, // [DANtrack]
-  {"hash":"407face2b2c27397","prefixes":{"":{"product":1389,"type":1}}}, // [Integral Markt- und Meinungsforschungsges.m.b.H.]
-  {"hash":"184f80ef53a0f178","prefixes":{"":{"product":1389,"type":1}}}, // [Integral Markt- und Meinungsforschungsges.m.b.H.]
-  {"hash":"076a460590b496bf","prefixes":{"":{"product":1390,"type":0}}}, // [Millemedia GmbH]
-  {"hash":"9febeed138f5f2ce","prefixes":{"":{"product":1391,"type":0}}}, // [Hiro-Media]
-  {"hash":"dd35fc0a5f5fa07b","prefixes":{"":{"product":1391,"type":0}}}, // [Hiro-Media]
-  {"hash":"b22687a0d4bd341f","prefixes":{"":{"product":1391,"type":0}}}, // [Hiro-Media]
-  {"hash":"1625640192348305","prefixes":{"*":{"product":1392,"type":0}}}, // [Simplaex Gmbh]
-  {"hash":"444356542461e7d2","prefixes":{"":{"product":1392,"type":0}}}, // [Simplaex Gmbh]
-  {"hash":"b9edac442e488ddf","prefixes":{"":{"product":1392,"type":0}}}, // [Simplaex Gmbh]
-  {"hash":"afed9502218fc1cd","prefixes":{"":{"product":1393,"type":0}}}, // [Telekom Deutschland GmbH]
-  {"hash":"286d994374ce8a57","prefixes":{"":{"product":1394,"type":1}}}, // [Infernotions Technologies Limited]
-  {"hash":"385225c96e123b3f","prefixes":{"":{"product":1395,"type":0}}}, // [Goldfish Media LLC]
-  {"hash":"19c11b9ad47802f9","prefixes":{"":{"product":1352,"type":1}}}, // [Expedia, Inc.]
-  {"hash":"d710ea66b904cd82","prefixes":{"":{"product":1396,"type":0}}}, // [Smartology Limited]
-  {"hash":"24bbec831a84a114","prefixes":{"":{"product":1396,"type":0}}}, // [Smartology Limited]
-  {"hash":"9c3279986e25304c","prefixes":{"":{"product":1396,"type":0}}}, // [Smartology Limited]
-  {"hash":"8ce94299572dc9b8","prefixes":{"":{"product":1396,"type":0}}}, // [Smartology Limited]
-  {"hash":"e51f784e66ceb1cb","prefixes":{"":{"product":1397,"type":0}}}, // [GroupM]
-  {"hash":"72bd4ec98dea633b","prefixes":{"":{"product":1397,"type":0}}}, // [GroupM]
-  {"hash":"0836c753510a4fd6","prefixes":{"*":{"product":1398,"type":0}}}, // [Haystagg Inc.]
-  {"hash":"4a13b1d65c372006","prefixes":{"*":{"product":1398,"type":0}}}, // [Haystagg Inc.]
-  {"hash":"14ec018232a87385","prefixes":{"":{"product":1399,"type":0}}}, // [Digital Turbine Media, Inc]
-  {"hash":"fdabfb7535e313a7","prefixes":{"":{"product":1399,"type":0}}}, // [Digital Turbine Media, Inc]
-  {"hash":"cddef42a99b1f0e2","prefixes":{"":{"product":1400,"type":0}}}, // [MDSP INC]
-  {"hash":"1bcc84762c0f2df8","prefixes":{"":{"product":1401,"type":0}}}, // [Quadas (YiDong Data Inc.)]
-  {"hash":"6c46a69428837566","prefixes":{"":{"product":1402,"type":1}}}, // [Recruit Career Co., Ltd.]
-  {"hash":"17319e35b3b89b68","prefixes":{"":{"product":1403,"type":1}}}, // [R2Net Inc.]
-  {"hash":"0825a9da5dd17373","prefixes":{"":{"product":1403,"type":1}}}, // [R2Net Inc.]
-  {"hash":"aaa00ce722ea0d35","prefixes":{"":{"product":1403,"type":1}}}, // [R2Net Inc.]
-  {"hash":"40b683cc8c061f6f","prefixes":{"":{"product":1404,"type":0}}}, // [Madberry OY]
-  {"hash":"ea76804ad8af9b5c","prefixes":{"":{"product":1404,"type":0}}}, // [Madberry OY]
-  {"hash":"985cce26aeab90d8","prefixes":{"":{"product":1404,"type":0}}}, // [Madberry OY]
-  {"hash":"d67d98cbb9553a81","prefixes":{"":{"product":1404,"type":0}}}, // [Madberry OY]
-  {"hash":"ee1c2ae2ffdaa754","prefixes":{"":{"product":1404,"type":0}}}, // [Madberry OY]
-  {"hash":"8c162379b63896e6","prefixes":{"":{"product":1405,"type":0}}}, // [QVC]
-  {"hash":"4c23d567b98e413f","prefixes":{"*":{"product":1406,"type":0}}}, // [Micro Cube Digital Limited]
-  {"hash":"9e74e9e50b7e6116","prefixes":{"":{"product":1407}}}, // [egg.de GmbH]
-  {"hash":"8242efdacea6ca14","prefixes":{"":{"product":1408,"type":0}}}, // [Headway Mexico]
-  {"hash":"82b90117a5beb869","prefixes":{"":{"product":1409,"type":0}}}, // [RTBiQ Inc.]
-  {"hash":"7d4bc30e9d495d00","prefixes":{"":{"product":1183,"type":0}}}, // [Fluidads]
-  {"hash":"44305a81af328854","prefixes":{"":{"product":1183,"type":0}}}, // [Fluidads]
-  {"hash":"f5d44df23b5b7f0a","prefixes":{"":{"product":1410,"type":1}}}, // [SCIBIDS TECHNOLOGY S.A.S.]
-  {"hash":"e86f56889ef213b9","prefixes":{"*":{"product":1411,"type":0}}}, // [Kyocera Communication Systems]
-  {"hash":"e4f3abfdd94fbb95","prefixes":{"":{"product":1412,"type":0}}}, // [Cortex Media Group]
-  {"hash":"7525243b1d665de2","prefixes":{"":{"product":1413,"type":0}}}, // [appTV]
-  {"hash":"f27453a19aa2370e","prefixes":{"":{"product":1413,"type":0}}}, // [appTV]
-  {"hash":"8156979d25af9817","prefixes":{"":{"product":1414,"type":0}}}, // [ProgSol, Programmatic Solution, s.r.o.]
-  {"hash":"888e465d14dbfeb5","prefixes":{"":{"product":1414,"type":0}}}, // [ProgSol, Programmatic Solution, s.r.o.]
-  {"hash":"6bcdb8e4cf28b730","prefixes":{"":{"product":1414,"type":0}}}, // [ProgSol, Programmatic Solution, s.r.o.]
-  {"hash":"cc229228113699d8","prefixes":{"":{"product":1415}}}, // [Rezonence]
-  {"hash":"fd7695df1dfe9f20","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"fbee76565472bc95","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"e53efe28417732fd","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"4f76dc8807a1b25a","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"b7cd9e7666d175e1","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"ba124e354a70dcb2","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"8c9e63d24d4fbe6b","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"ea6157fcb7c5c718","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"6063abef39fb89be","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"8a3b3647f6fae243","prefixes":{"":{"product":1416}}}, // [LKQD Platform]
-  {"hash":"25b652ead7abb3b0","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"ff03eb40846eaa12","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"649ada5375fff936","prefixes":{"":{"product":1048,"type":0}}}, // [Bidtellect]
-  {"hash":"79b86a55d8f149ef","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"a6e4ebed7d417fec","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"e7a27d73288188b6","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"24028ce468194c75","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"d7f89ed8a6431a69","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"079f75aa60b736a9","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"55ab38530ebcb2e7","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"244a99d8deb4343c","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"02afdba2d61c6d76","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"50fcadafe2e2734b","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"0a5d998860b7968b","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"ff1ef9a23c2bdf51","prefixes":{"":{"product":1417,"type":0}}}, // [target value GmbH]
-  {"hash":"b7be02479c9268a9","prefixes":{"":{"product":1418,"type":0}}}, // [Firecracker]
-  {"hash":"2841b43a0e0ddb37","prefixes":{"":{"product":1418,"type":0}}}, // [Firecracker]
-  {"hash":"ea77ccf69493306c","prefixes":{"":{"product":1418,"type":0}}}, // [Firecracker]
-  {"hash":"786060a6ba793b32","prefixes":{"":{"product":1418,"type":0}}}, // [Firecracker]
-  {"hash":"af58243a5817c930","prefixes":{"":{"product":1418,"type":0}}}, // [Firecracker]
-  {"hash":"b90ffee242259e26","prefixes":{"":{"product":1419,"type":0}}}, // [MADGIC]
-  {"hash":"037e84a783130203","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"724c85c96cc72a57","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"df235ed188c82f5b","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"df21bf354a2570e1","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"52a9b224dd3e1b02","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"ef749fa483d558a9","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"a6b20df6c2ce3063","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"7e7e73dfe402883c","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"1cafe416eb8d746c","prefixes":{"":{"product":1420,"type":1}}}, // [Digiseg]
-  {"hash":"45c0ef64ecfb6525","prefixes":{"":{"product":1421,"type":0}}}, // [Bulbit Inc.]
-  {"hash":"d3710c2900e90f84","prefixes":{"":{"product":1421}}}, // [Bulbit Inc.]
-  {"hash":"fed8a97b9e855887","prefixes":{"":{"product":1422,"type":1}}}, // [Lost My Name]
-  {"hash":"5c18434d5d721456","prefixes":{"":{"product":1423,"type":0}}}, // [People Media]
-  {"hash":"fd4a671d34b4c76c","prefixes":{"":{"product":1423,"type":0}}}, // [People Media]
-  {"hash":"181b385a8ea5a687","prefixes":{"":{"product":1424,"type":0}}}, // [Platform.io]
-  {"hash":"00393673ca5c1d8a","prefixes":{"":{"product":1424}}}, // [Platform.io]
-  {"hash":"6479d1c5a241da2f","prefixes":{"":{"product":1425,"type":0}}}, // [Bidspeaker]
-  {"hash":"f30e44d5503f39c4","prefixes":{"":{"product":1426,"type":1}}}, // [YouGov PLC]
-  {"hash":"4f07a6c89151a2eb","prefixes":{"":{"product":1427,"type":0}}}, // [SAP SE]
-  {"hash":"519e46f12c141c48","prefixes":{"":{"product":1427,"type":0}}}, // [SAP SE]
-  {"hash":"413cdfaa8215b8f5","prefixes":{"":{"product":1427,"type":0}}}, // [SAP SE]
-  {"hash":"dd8e150b503eb12f","prefixes":{"":{"product":1428,"type":1}}}, // [Adchex]
-  {"hash":"58e19248782ce688","prefixes":{"":{"product":1429,"type":0}}}, // [Smart Bid Limited]
-  {"hash":"8ccc1dd45e305817","prefixes":{"":{"product":1430,"type":0}}}, // [UAd Exchange]
-  {"hash":"9543cb4330fa1d6e","prefixes":{"":{"product":1431}}}, // [UAd Exchange - IBV]
-  {"hash":"fc1a7604d6ced7c3","prefixes":{"":{"product":1432,"type":0}}}, // [esc mediagroup GmbH]
-  {"hash":"90c354743de0b811","prefixes":{"":{"product":1433,"type":0}}}, // [defacto smart reach GmbH]
-  {"hash":"0d8f41278d702251","prefixes":{"":{"product":1434,"type":1}}}, // [Research and Analysis of Media in Sweden AB]
-  {"hash":"607c4919b3c8d5cd","prefixes":{"":{"product":1434,"type":1}}}, // [Research and Analysis of Media in Sweden AB]
-  {"hash":"d0d7647dc2ea9dd9","prefixes":{"":{"product":1435,"type":1}}}, // [OnAudience.com]
-  {"hash":"3c0c99d90a16804f","prefixes":{"":{"product":1436,"type":0}}}, // [OneTag]
-  {"hash":"a50e8a4129f160c8","prefixes":{"":{"product":1436,"type":0}}}, // [OneTag]
-  {"hash":"62105b8204658950","prefixes":{"":{"product":1436}}}, // [OneTag]
-  {"hash":"8069afc9a94b92b9","prefixes":{"*":{"product":1336,"type":0}}}, // [1trn LLC]
-  {"hash":"c9cc947471099a0e","prefixes":{"":{"product":58,"type":1}}}, // [Air Berlin]
-  {"hash":"516352d734faa684","prefixes":{"":{"product":1437,"type":1}}}, // [Fiverr International Ltd.]
-  {"hash":"562a3da1a81ae4ec","prefixes":{"":{"product":1437,"type":1}}}, // [Fiverr International Ltd.]
-  {"hash":"1ba262fef7c9b94b","prefixes":{"":{"product":1438,"type":0}}}, // [Adikteev]
-  {"hash":"cd63e73725fa2b8d","prefixes":{"":{"product":1438,"type":0}}}, // [Adikteev]
-  {"hash":"f24819f2edd93c69","prefixes":{"":{"product":1438,"type":0}}}, // [Adikteev]
-  {"hash":"e3b1538bced5ec72","prefixes":{"":{"product":1438,"type":0}}}, // [Adikteev]
-  {"hash":"341df4e708fbbc07","prefixes":{"":{"product":1439,"type":0}}}, // [CenterPoint Media]
-  {"hash":"1f984187723f0399","prefixes":{"":{"product":1439,"type":0}}}, // [CenterPoint Media]
-  {"hash":"6ed35b33de5147be","prefixes":{"":{"product":1439,"type":0}}}, // [CenterPoint Media]
-  {"hash":"d3f04891cabd56f8","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"8429b5e7c7905de9","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"eadb7778a29b9617","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"15595532c38662ea","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"ce365566d66a72ee","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"60ef24e820a6a881","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"176be2434ca2f68b","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"3f72f2b4ec7f816e","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"bcc519027914bd79","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"86628b5f01332c66","prefixes":{"":{"product":1440,"type":0}}}, // [Digital Trace]
-  {"hash":"1c34c62a587e6c1e","prefixes":{"":{"product":1441,"type":0}}}, // [Pure Cobalt]
-  {"hash":"a30f9c646772cf0f","prefixes":{"":{"product":59,"type":1}}}, // [Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper]
-  {"hash":"b23d960b2ea25b51","prefixes":{"":{"product":1442}}}, // [Cedato]
-  {"hash":"030115e352ac8e99","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"77da2d98a4da970f","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"aa0555e19cf5d6cc","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"badc121e99935aa5","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"115df78aa77ac9c4","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"04713a193ed96cc0","prefixes":{"s":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"fd6fd1f29de71285","prefixes":{"":{"product":1442}}}, // [Cedato]
-  {"hash":"c5de6239a6efe818","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"4c0be33a1c14428d","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"09eaafed5beae0e1","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"ff987bad618809e7","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"2b50033d06870385","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"8b399204d27d07c0","prefixes":{"s":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"5f78d380fa9514b1","prefixes":{"":{"product":1442}}}, // [Cedato]
-  {"hash":"c4912c3d8f04b948","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"361fa6df6bb3216e","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"b18ab9dfb513f02b","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"de511a44653105ea","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"f990d873e1622766","prefixes":{"":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"f53618fe52956dbf","prefixes":{"s":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"96ed69252978cab9","prefixes":{"cdn":{"product":1442,"type":0}}}, // [Cedato]
-  {"hash":"f38b31b7e204355c","prefixes":{"":{"product":930,"type":0}}}, // [Admetrics GmbH]
-  {"hash":"895a9c8a3b52c95f","prefixes":{"":{"product":930,"type":0}}}, // [Admetrics GmbH]
-  {"hash":"62ba002fe91498c3","prefixes":{"":{"product":930,"type":0}}}, // [Admetrics GmbH]
-  {"hash":"30fe524e700bd89f","prefixes":{"":{"product":930,"type":0}}}, // [Admetrics GmbH]
-  {"hash":"6ce86e7a47d6dfbc","prefixes":{"":{"product":1443,"type":0}}}, // [Jonsden Properties Limited]
-  {"hash":"8bed3db3f252b657","prefixes":{"":{"product":1444,"type":1}}}, // [Realytics]
-  {"hash":"c2dcbb4796436e89","prefixes":{"":{"product":1445}}}, // [Twinpine]
-  {"hash":"97a8b5033c272f3c","prefixes":{"":{"product":1445}}}, // [Twinpine]
-  {"hash":"3d39eae9e2370c3e","prefixes":{"":{"product":1446,"type":0}}}, // [Mopedo AB]
-  {"hash":"38a9bfae76c9b2f1","prefixes":{"*":{"product":1447,"type":1}}}, // [Netsales]
-  {"hash":"9b1148932500d0b5","prefixes":{"":{"product":1448,"type":1}}}, // [ViewersLogic LTD]
-  {"hash":"901b2f7c0272451b","prefixes":{"":{"product":1448,"type":1}}}, // [ViewersLogic LTD]
-  {"hash":"7d45cf386f5c3f27","prefixes":{"":{"product":1449,"type":0}}}, // [ADMAN]
-  {"hash":"e68e2f7630af032b","prefixes":{"":{"product":1449,"type":0}}}, // [ADMAN]
-  {"hash":"79dc640f62208944","prefixes":{"":{"product":1449,"type":0}}}, // [ADMAN]
-  {"hash":"4d6e312d6aba1117","prefixes":{"":{"product":1449,"type":0}}}, // [ADMAN]
-  {"hash":"29e85c5af35e3751","prefixes":{"":{"product":1449}}}, // [ADMAN]
-  {"hash":"e5f2b6b92cc6daa3","prefixes":{"":{"product":1450,"type":0}}}, // [Hyper]
-  {"hash":"f867e04c6dde165d","prefixes":{"":{"product":1451,"type":1}}}, // [Hurra Communications]
-  {"hash":"8353a34ee35ff30c","prefixes":{"":{"product":1451,"type":1}}}, // [Hurra Communications]
-  {"hash":"cc7f69fa55a7518f","prefixes":{"":{"product":1452,"type":0}}}, // [Groundhog TW]
-  {"hash":"95ba2d10b1b0675c","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"e8f62a52edbdf4bd","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"321a7e08d4b4fd55","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"c6f272ed0a206999","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"bd34d2733467c1af","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"1b49f6113458dc63","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"58b83e3b3a97943e","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"814bcd9589533387","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"9465fc7c156593f4","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"7c1c219e78b2f270","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"9d376bb5982319b0","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"12ec9a0b2888a4a9","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"f3d7dfcb60972b0c","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"460cac48ec149c6d","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"2614d3ffa05e19a5","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"1f9b770c08378ced","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"054864ff1578657a","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"a5505306000e20f2","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"12cae8bbd22d8673","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"d7724f8a49b96fa6","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"3013078a26f31e2f","prefixes":{"":{"product":1453,"type":0}}}, // [ImediaMax]
-  {"hash":"80193dea6eb67372","prefixes":{"":{"product":1454,"type":1}}}, // [Flixbus]
-  {"hash":"02c439b9cc7e33b5","prefixes":{"":{"product":1455}}}, // [AudienceTV]
-  {"hash":"fcb4adbb2bc559e7","prefixes":{"":{"product":1456,"type":0}}}, // [b34106183_test]
-  {"hash":"b08446a676a287b4","prefixes":{"":{"product":1456,"type":0}}}, // [b34106183_test]
-  {"hash":"12105a6cc17c32e7","prefixes":{"":{"product":1457,"type":1}}}, // [Netscore]
-  {"hash":"036d15c3ad4a0735","prefixes":{"":{"product":1457,"type":1}}}, // [Netscore]
-  {"hash":"c0c40e6f63813be1","prefixes":{"":{"product":1458,"type":0}}}, // [Chu Technology Limited]
-  {"hash":"4c434a52325c0b6e","prefixes":{"":{"product":1459,"type":1}}}, // [SmartyAds LLC]
-  {"hash":"825a99c46b61053a","prefixes":{"":{"product":1460,"type":0}}}, // [dbupdate1]
-  {"hash":"31ab5366866e8622","prefixes":{"":{"product":1460,"type":0}}}, // [dbupdate1]
-  {"hash":"32a21f3a47cb8ddc","prefixes":{"":{"product":127}}}, // [ConvertMedia Ltd.]
-  {"hash":"44a7af6d373bd713","prefixes":{"":{"product":972,"type":0}}}, // [Lodeo]
-  {"hash":"36d8680483227de8","prefixes":{"":{"product":972}}}, // [Lodeo]
-  {"hash":"9709c6b69d2e3e90","prefixes":{"":{"product":972}}}, // [Lodeo]
-  {"hash":"5efefb78ec9b146f","prefixes":{"":{"product":1461,"type":0}}}, // [The Big Willow Inc.]
-  {"hash":"3e5b3c0010f7172f","prefixes":{"":{"product":1462,"type":0}}}, // [LiveIntent Inc]
-  {"hash":"07bf09263d039040","prefixes":{"":{"product":1463}}}, // [OpenLedger ApS]
-  {"hash":"db879c71876741d0","prefixes":{"":{"product":1464,"type":0}}}, // [Whichit]
-  {"hash":"4a6caded0a4565d9","prefixes":{"":{"product":1464,"type":0}}}, // [Whichit]
-  {"hash":"05e0b02a9af28e89","prefixes":{"":{"product":1464,"type":0}}}, // [Whichit]
-  {"hash":"3aca7ac4649f240c","prefixes":{"":{"product":1464,"type":0}}}, // [Whichit]
-  {"hash":"81abe9587250fab1","prefixes":{"":{"product":1464,"type":0}}}, // [Whichit]
-  {"hash":"a3b6bac891e57819","prefixes":{"":{"product":1465,"type":0}}}, // [ParkDIA]
-  {"hash":"ddc3507bc6f79de4","prefixes":{"":{"product":1466,"type":0}}}, // [Atedra Inc.]
-  {"hash":"881c2002027de2ec","prefixes":{"":{"product":1466,"type":0}}}, // [Atedra Inc.]
-  {"hash":"28084881f4e51f6c","prefixes":{"":{"product":1467,"type":0}}}, // [Digital Forest OÜ]
-  {"hash":"d563745e0fed92f4","prefixes":{"":{"product":1468,"type":2}}}, // [Isobar Werbeagentur GmbH]
-  {"hash":"d6d13ce525771ba4","prefixes":{"":{"product":1469,"type":0}}}, // [Valuepotion Pte. Ltd.]
-  {"hash":"446766a73edf76a2","prefixes":{"":{"product":1470,"type":0}}}, // [Vuble Inc]
-  {"hash":"0753aa310a2a75aa","prefixes":{"":{"product":1471,"type":0}}}, // [adlocal.net]
-  {"hash":"772284fa4bfb8e5a","prefixes":{"":{"product":1471,"type":0}}}, // [adlocal.net]
-  {"hash":"0dd444b76d1727ab","prefixes":{"":{"product":1471,"type":0}}}, // [adlocal.net]
-  {"hash":"1db1fc299e2dc73a","prefixes":{"":{"product":1471,"type":0}}}, // [adlocal.net]
-  {"hash":"169447ab5f0b2b32","prefixes":{"":{"product":1472,"type":1}}}, // [Freckle IoT]
-  {"hash":"143b45f2e52d871c","prefixes":{"":{"product":1473,"type":0}}}, // [Personalization LLC]
-  {"hash":"bdc55693a2c62858","prefixes":{"":{"product":1474,"type":0}}}, // [ThoughtLeadr Inc.]
-  {"hash":"e69058fe073a8d07","prefixes":{"":{"product":1474,"type":0}}}, // [ThoughtLeadr Inc.]
-  {"hash":"ded94145085d34ed","prefixes":{"":{"product":1474,"type":0}}}, // [ThoughtLeadr Inc.]
-  {"hash":"ef66f2e1bb6a3605","prefixes":{"":{"product":1474,"type":0}}}, // [ThoughtLeadr Inc.]
-  {"hash":"5f62ecd0eec6b82a","prefixes":{"":{"product":1474,"type":0}}}, // [ThoughtLeadr Inc.]
-  {"hash":"45281cea83398309","prefixes":{"":{"product":1475,"type":0},"web":{"product":1475,"type":0},"app":{"product":1475,"type":0},"cdn":{"product":1475,"type":0},"api":{"product":1475,"type":0},"p":{"product":1475,"type":0},"mobpages":{"product":1475,"type":0}}}, // [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC]
-  {"hash":"7ea0c7c8484fb7b4","prefixes":{"cdn":{"product":1475,"type":0}}}, // [Noqoush Mobile Media Group FZ-LLC]
-  {"hash":"6839ebcbc8dce175","prefixes":{"":{"product":1475,"type":0},"p":{"product":1475,"type":0}}}, // [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC]
-  {"hash":"c338016e1aa2a5f7","prefixes":{"":{"product":1476,"type":2}}}, // [G-Core Labs]
-  {"hash":"3bb879b5ab17cbeb","prefixes":{"":{"product":1477,"type":1}}}, // [Haensel AMS GmbH]
-  {"hash":"26627407df51f73d","prefixes":{"t":{"product":1477,"type":1},"d":{"product":1477,"type":1},"s":{"product":1477,"type":1}}}, // [Haensel AMS GmbH] [Haensel AMS GmbH] [Haensel AMS GmbH]
-  {"hash":"44e07e9341e20fd0","prefixes":{"":{"product":1478,"type":2}}}, // [LemonPI]
-  {"hash":"71d7abda3a6093b3","prefixes":{"":{"product":1478,"type":2}}}, // [LemonPI]
-  {"hash":"f57717e6df039cd1","prefixes":{"":{"product":1478,"type":2}}}, // [LemonPI]
-  {"hash":"0ae0087cfa7b79c3","prefixes":{"":{"product":1478,"type":2}}}, // [LemonPI]
-  {"hash":"59afc0d091a22f58","prefixes":{"":{"product":1479,"type":0}}}, // [4Info, Inc.]
-  {"hash":"fd299e0138ad90c1","prefixes":{"":{"product":1479,"type":0}}}, // [4Info, Inc.]
-  {"hash":"1e408d2e9033a6e2","prefixes":{"":{"product":1479,"type":0}}} // [4Info, Inc.]
-]);
diff --git a/front_end/product_registry_impl/ProductRegistryImpl.js b/front_end/product_registry_impl/ProductRegistryImpl.js
deleted file mode 100644
index fb3f493..0000000
--- a/front_end/product_registry_impl/ProductRegistryImpl.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {ProductRegistry.Registry}
- */
-ProductRegistryImpl.Registry = class {
-  constructor() {
-  }
-
-  /**
-   * @override
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?string}
-   */
-  nameForUrl(parsedUrl) {
-    const entry = this.entryForUrl(parsedUrl);
-    if (entry)
-      return entry.name;
-    return null;
-  }
-
-  /**
-   * @override
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?ProductRegistry.Registry.ProductEntry}
-   */
-  entryForUrl(parsedUrl) {
-    if (parsedUrl.isDataURL() || !parsedUrl.isValid)
-      return null;
-    // TODO(allada) This should be expanded to allow paths as as well as domain to find a product.
-    const productsByDomainHash = ProductRegistryImpl._productsByDomainHash;
-    // Remove leading www. if it is the only subdomain.
-    const domain = parsedUrl.domain().replace(/^www\.(?=[^.]+\.[^.]+$)/, '');
-
-    let previousIndex = -1;
-    let index = -1;
-    // Ensure we loop with full domain first, but do not loop over last part (ie: ".com").
-    for (let nextIndex = domain.indexOf('.'); nextIndex !== -1; nextIndex = domain.indexOf('.', nextIndex + 1)) {
-      const previousSubdomain = domain.substring(previousIndex + 1, index);
-      const subDomain = domain.substring(index + 1);
-      const prefixes = productsByDomainHash.get(ProductRegistryImpl._hashForDomain(subDomain));
-      previousIndex = index;
-      index = nextIndex;
-      if (!prefixes)
-        continue;
-      // Exact match domains are always highest priority.
-      if ('' in prefixes && domain === subDomain)
-        return prefixes[''];
-      if (previousSubdomain) {
-        for (const prefix in prefixes) {
-          const domainPrefix = previousSubdomain.substr(0, prefix.length);
-          if (domainPrefix === prefix && prefix !== '')
-            return prefixes[prefix];
-        }
-      }
-      // Process wildcard subdomain if no better match found.
-      if (prefixes && '*' in prefixes)
-        return prefixes['*'];
-    }
-    return null;
-  }
-
-  /**
-   * @override
-   * @param {!Common.ParsedURL} parsedUrl
-   * @return {?number}
-   */
-  typeForUrl(parsedUrl) {
-    const entry = this.entryForUrl(parsedUrl);
-    if (entry)
-      return entry.type;
-    return null;
-  }
-};
-
-/**
- * @param {string} domain
- * @return {string}
- */
-ProductRegistryImpl._hashForDomain = function(domain) {
-  return ProductRegistryImpl.sha1(domain).substr(0, 16);
-};
-
-/**
- * @param {!Array<string>} productNames
- * @param {!Array<!{hash: string, prefixes: !Object<string, !{product: number, type: (number|undefined)}>}>} data
- */
-ProductRegistryImpl.register = function(productNames, data) {
-  for (let i = 0; i < data.length; i++) {
-    const entry = data[i];
-    const prefixes = {};
-    for (const prefix in entry.prefixes) {
-      const prefixEntry = entry.prefixes[prefix];
-      const type = prefixEntry.type !== undefined ? prefixEntry.type : null;
-      prefixes[prefix] = {name: productNames[prefixEntry.product], type: type};
-    }
-    ProductRegistryImpl._productsByDomainHash.set(entry.hash, prefixes);
-  }
-};
-
-/** @type {!Map<string, !Object<string, !ProductRegistry.Registry.ProductEntry>>}} */
-ProductRegistryImpl._productsByDomainHash = new Map();
diff --git a/front_end/product_registry_impl/module.json b/front_end/product_registry_impl/module.json
deleted file mode 100644
index 726d199..0000000
--- a/front_end/product_registry_impl/module.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "extensions": [
-        {
-          "type": "@ProductRegistry.Registry",
-          "className": "ProductRegistryImpl.Registry"
-        }
-    ],
-    "dependencies": [
-        "common",
-        "product_registry"
-    ],
-    "scripts": [
-        "ProductRegistryImpl.js",
-        "ProductRegistryData.js",
-        "sha1/sha1.js"
-    ]
-}
diff --git a/front_end/product_registry_impl/sha1/README.chromium b/front_end/product_registry_impl/sha1/README.chromium
deleted file mode 100644
index e8b6bf0..0000000
--- a/front_end/product_registry_impl/sha1/README.chromium
+++ /dev/null
@@ -1,9 +0,0 @@
-Name: A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1.
-Short Name: sha1.js
-URL: http://pajhome.org.uk/crypt/md5/
-License: BSD
-Security Critical: no
-
-This directory contains Chromium's version of sha1.js which is for hashing strings in javascript synchronously. Added
-jsdoc types to functions, wrapped functions in an outer function and removed portions of code that are not needed by
-Chromium.
\ No newline at end of file
diff --git a/front_end/product_registry_impl/sha1/sha1.js b/front_end/product_registry_impl/sha1/sha1.js
deleted file mode 100644
index b4581a1..0000000
--- a/front_end/product_registry_impl/sha1/sha1.js
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS 180-1
- * Version 2.2 Copyright Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-// clang-format off
-/* eslint-disable */
-/**
- * @param {string} str
- * @return {string}
- */
-ProductRegistryImpl.sha1 = function(str) {
-  return rstr2hex(rstr_sha1(str2rstr_utf8(str)));
-
-  /**
-   * Calculate the SHA1 of a raw string
-   * @param {string} s
-   * @return {string}
-   */
-  function rstr_sha1(s)
-  {
-    return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
-  }
-
-  /**
-   * Convert a raw string to a hex string
-   * @param {string} input
-   * @return {string}
-   */
-  function rstr2hex(input)
-  {
-    let hex_tab = "0123456789abcdef";
-    let output = "";
-    let x;
-    for(let i = 0; i < input.length; i++)
-    {
-      x = input.charCodeAt(i);
-      output += hex_tab.charAt((x >>> 4) & 0x0F)
-             +  hex_tab.charAt( x        & 0x0F);
-    }
-    return output;
-  }
-
-  /**
-   * Encode a string as utf-8.
-   * For efficiency, this assumes the input is valid utf-16.
-   * @param {string} input
-   * @return {string}
-   */
-  function str2rstr_utf8(input)
-  {
-    let output = "";
-    let i = -1;
-    let x, y;
-
-    while(++i < input.length)
-    {
-      /* Decode utf-16 surrogate pairs */
-      x = input.charCodeAt(i);
-      y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-      if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-      {
-        x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-        i++;
-      }
-
-      /* Encode output as utf-8 */
-      if(x <= 0x7F)
-        output += String.fromCharCode(x);
-      else if(x <= 0x7FF)
-        output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                      0x80 | ( x         & 0x3F));
-      else if(x <= 0xFFFF)
-        output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                      0x80 | ((x >>> 6 ) & 0x3F),
-                                      0x80 | ( x         & 0x3F));
-      else if(x <= 0x1FFFFF)
-        output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                      0x80 | ((x >>> 12) & 0x3F),
-                                      0x80 | ((x >>> 6 ) & 0x3F),
-                                      0x80 | ( x         & 0x3F));
-    }
-    return output;
-  }
-
-  /**
-   * Convert a raw string to an array of big-endian words
-   * Characters >255 have their high-byte silently ignored.
-   * @param {string} input
-   * @return {!Array<number>}
-   */
-  function rstr2binb(input)
-  {
-    let output = Array(input.length >> 2);
-    for(let i = 0; i < output.length; i++)
-      output[i] = 0;
-    for(let i = 0; i < input.length * 8; i += 8)
-      output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
-    return output;
-  }
-
-  /**
-   * Convert an array of big-endian words to a string
-   * @param {!Array<number>} input
-   * @return {string}
-   */
-  function binb2rstr(input)
-  {
-    let output = "";
-    for(let i = 0; i < input.length * 32; i += 8)
-      output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-    return output;
-  }
-
-  /**
-   * Calculate the SHA-1 of an array of big-endian words, and a bit length
-   * @param {!Array<number>} x
-   * @param {number} len
-   * @return {!Array<number>}
-   */
-  function binb_sha1(x, len)
-  {
-    /* append padding */
-    x[len >> 5] |= 0x80 << (24 - len % 32);
-    x[((len + 64 >> 9) << 4) + 15] = len;
-
-    let w = Array(80);
-    let a =  1732584193;
-    let b = -271733879;
-    let c = -1732584194;
-    let d =  271733878;
-    let e = -1009589776;
-
-    for(let i = 0; i < x.length; i += 16)
-    {
-      let olda = a;
-      let oldb = b;
-      let oldc = c;
-      let oldd = d;
-      let olde = e;
-
-      for(let j = 0; j < 80; j++)
-      {
-        if(j < 16) w[j] = x[i + j];
-        else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
-        let t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
-                         safe_add(safe_add(e, w[j]), sha1_kt(j)));
-        e = d;
-        d = c;
-        c = bit_rol(b, 30);
-        b = a;
-        a = t;
-      }
-
-      a = safe_add(a, olda);
-      b = safe_add(b, oldb);
-      c = safe_add(c, oldc);
-      d = safe_add(d, oldd);
-      e = safe_add(e, olde);
-    }
-    return Array(a, b, c, d, e);
-
-  }
-
-  /**
-   * Perform the appropriate triplet combination function for the current
-   * iteration
-   * @param {number} t
-   * @param {number} b
-   * @param {number} c
-   * @param {number} d
-   * @return {number}
-   */
-  function sha1_ft(t, b, c, d)
-  {
-    if(t < 20) return (b & c) | ((~b) & d);
-    if(t < 40) return b ^ c ^ d;
-    if(t < 60) return (b & c) | (b & d) | (c & d);
-    return b ^ c ^ d;
-  }
-
-  /**
-   * Determine the appropriate additive constant for the current iteration
-   * @param {number} t
-   * @return {number}
-   */
-  function sha1_kt(t)
-  {
-    return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
-           (t < 60) ? -1894007588 : -899497514;
-  }
-
-  /**
-   * Add integers, wrapping at 2^32. This uses 16-bit operations internally
-   * to work around bugs in some JS interpreters.
-   * @param {number} x
-   * @param {number} y
-   * @return {number}
-   */
-  function safe_add(x, y)
-  {
-    let lsw = (x & 0xFFFF) + (y & 0xFFFF);
-    let msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-    return (msw << 16) | (lsw & 0xFFFF);
-  }
-
-  /**
-   * Bitwise rotate a 32-bit number to the left.
-   * @param {number} num
-   * @param {number} cnt
-   * @return {number}
-   */
-  function bit_rol(num, cnt)
-  {
-    return (num << cnt) | (num >>> (32 - cnt));
-  }
-};
diff --git a/front_end/profiler/BottomUpProfileDataGrid.js b/front_end/profiler/BottomUpProfileDataGrid.js
deleted file mode 100644
index 66e697c..0000000
--- a/front_end/profiler/BottomUpProfileDataGrid.js
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2009 280 North Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// Bottom Up Profiling shows the entire callstack backwards:
-// The root node is a representation of each individual function called, and each child of that node represents
-// a reverse-callstack showing how many of those calls came from it. So, unlike top-down, the statistics in
-// each child still represent the root node. We have to be particularly careful of recursion with this mode
-// because a root node can represent itself AND an ancestor.
-
-/**
- * @unrestricted
- */
-Profiler.BottomUpProfileDataGridNode = class extends Profiler.ProfileDataGridNode {
-  /**
-   * @param {!SDK.ProfileNode} profileNode
-   * @param {!Profiler.TopDownProfileDataGridTree} owningTree
-   */
-  constructor(profileNode, owningTree) {
-    super(profileNode, owningTree, !!profileNode.parent && !!profileNode.parent.parent);
-    this._remainingNodeInfos = [];
-  }
-
-  /**
-   * @param {!Profiler.BottomUpProfileDataGridNode|!Profiler.BottomUpProfileDataGridTree} container
-   */
-  static _sharedPopulate(container) {
-    const remainingNodeInfos = container._remainingNodeInfos;
-    const count = remainingNodeInfos.length;
-
-    for (let index = 0; index < count; ++index) {
-      const nodeInfo = remainingNodeInfos[index];
-      const ancestor = nodeInfo.ancestor;
-      const focusNode = nodeInfo.focusNode;
-      let child = container.findChild(ancestor);
-
-      // If we already have this child, then merge the data together.
-      if (child) {
-        const totalAccountedFor = nodeInfo.totalAccountedFor;
-
-        child.self += focusNode.self;
-
-        if (!totalAccountedFor)
-          child.total += focusNode.total;
-      } else {
-        // If not, add it as a true ancestor.
-        // In heavy mode, we take our visual identity from ancestor node...
-        child = new Profiler.BottomUpProfileDataGridNode(
-            ancestor, /** @type {!Profiler.TopDownProfileDataGridTree} */ (container.tree));
-
-        if (ancestor !== focusNode) {
-          // But the actual statistics from the "root" node (bottom of the callstack).
-          child.self = focusNode.self;
-          child.total = focusNode.total;
-        }
-
-        container.appendChild(child);
-      }
-
-      const parent = ancestor.parent;
-      if (parent && parent.parent) {
-        nodeInfo.ancestor = parent;
-        child._remainingNodeInfos.push(nodeInfo);
-      }
-    }
-
-    delete container._remainingNodeInfos;
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
-   */
-  _takePropertiesFromProfileDataGridNode(profileDataGridNode) {
-    this.save();
-    this.self = profileDataGridNode.self;
-    this.total = profileDataGridNode.total;
-  }
-
-  /**
-   * When focusing, we keep just the members of the callstack.
-   * @param {!Profiler.ProfileDataGridNode} child
-   */
-  _keepOnlyChild(child) {
-    this.save();
-
-    this.removeChildren();
-    this.appendChild(child);
-  }
-
-  /**
-   * @param {string} aCallUID
-   */
-  _exclude(aCallUID) {
-    if (this._remainingNodeInfos)
-      this.populate();
-
-    this.save();
-
-    const children = this.children;
-    let index = this.children.length;
-
-    while (index--)
-      children[index]._exclude(aCallUID);
-
-    const child = this.childrenByCallUID.get(aCallUID);
-
-    if (child)
-      this.merge(child, true);
-  }
-
-  /**
-   * @override
-   */
-  restore() {
-    super.restore();
-
-    if (!this.children.length)
-      this.setHasChildren(this._willHaveChildren(this.profileNode));
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.ProfileDataGridNode} child
-   * @param {boolean} shouldAbsorb
-   */
-  merge(child, shouldAbsorb) {
-    this.self -= child.self;
-    super.merge(child, shouldAbsorb);
-  }
-
-  /**
-   * @override
-   */
-  populateChildren() {
-    Profiler.BottomUpProfileDataGridNode._sharedPopulate(this);
-  }
-
-  _willHaveChildren(profileNode) {
-    // In bottom up mode, our parents are our children since we display an inverted tree.
-    // However, we don't want to show the very top parent since it is redundant.
-    return !!(profileNode.parent && profileNode.parent.parent);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Profiler.BottomUpProfileDataGridTree = class extends Profiler.ProfileDataGridTree {
-  /**
-   * @param {!Profiler.ProfileDataGridNode.Formatter} formatter
-   * @param {!UI.SearchableView} searchableView
-   * @param {!SDK.ProfileNode} rootProfileNode
-   * @param {number} total
-   */
-  constructor(formatter, searchableView, rootProfileNode, total) {
-    super(formatter, searchableView, total);
-    this.deepSearch = false;
-
-    // Iterate each node in pre-order.
-    let profileNodeUIDs = 0;
-    const profileNodeGroups = [[], [rootProfileNode]];
-    /** @type {!Map<string, !Set<number>>} */
-    const visitedProfileNodesForCallUID = new Map();
-
-    this._remainingNodeInfos = [];
-
-    for (let profileNodeGroupIndex = 0; profileNodeGroupIndex < profileNodeGroups.length; ++profileNodeGroupIndex) {
-      const parentProfileNodes = profileNodeGroups[profileNodeGroupIndex];
-      const profileNodes = profileNodeGroups[++profileNodeGroupIndex];
-      const count = profileNodes.length;
-
-      for (let index = 0; index < count; ++index) {
-        const profileNode = profileNodes[index];
-
-        if (!profileNode.UID)
-          profileNode.UID = ++profileNodeUIDs;
-
-        if (profileNode.parent) {
-          // The total time of this ancestor is accounted for if we're in any form of recursive cycle.
-          let visitedNodes = visitedProfileNodesForCallUID.get(profileNode.callUID);
-          let totalAccountedFor = false;
-
-          if (!visitedNodes) {
-            visitedNodes = new Set();
-            visitedProfileNodesForCallUID.set(profileNode.callUID, visitedNodes);
-          } else {
-            // The total time for this node has already been accounted for iff one of it's parents has already been visited.
-            // We can do this check in this style because we are traversing the tree in pre-order.
-            const parentCount = parentProfileNodes.length;
-            for (let parentIndex = 0; parentIndex < parentCount; ++parentIndex) {
-              if (visitedNodes.has(parentProfileNodes[parentIndex].UID)) {
-                totalAccountedFor = true;
-                break;
-              }
-            }
-          }
-
-          visitedNodes.add(profileNode.UID);
-
-          this._remainingNodeInfos.push(
-              {ancestor: profileNode, focusNode: profileNode, totalAccountedFor: totalAccountedFor});
-        }
-
-        const children = profileNode.children;
-        if (children.length) {
-          profileNodeGroups.push(parentProfileNodes.concat([profileNode]));
-          profileNodeGroups.push(children);
-        }
-      }
-    }
-
-    // Populate the top level nodes.
-    Profiler.ProfileDataGridNode.populate(this);
-
-    return this;
-  }
-
-  /**
-   * When focusing, we keep the entire callstack up to this ancestor.
-   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
-   */
-  focus(profileDataGridNode) {
-    if (!profileDataGridNode)
-      return;
-
-    this.save();
-
-    let currentNode = profileDataGridNode;
-    let focusNode = profileDataGridNode;
-
-    while (currentNode.parent && (currentNode instanceof Profiler.ProfileDataGridNode)) {
-      currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode);
-
-      focusNode = currentNode;
-      currentNode = currentNode.parent;
-
-      if (currentNode instanceof Profiler.ProfileDataGridNode)
-        currentNode._keepOnlyChild(focusNode);
-    }
-
-    this.children = [focusNode];
-    this.total = profileDataGridNode.total;
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
-   */
-  exclude(profileDataGridNode) {
-    if (!profileDataGridNode)
-      return;
-
-    this.save();
-
-    const excludedCallUID = profileDataGridNode.callUID;
-    const excludedTopLevelChild = this.childrenByCallUID.get(excludedCallUID);
-
-    // If we have a top level node that is excluded, get rid of it completely (not keeping children),
-    // since bottom up data relies entirely on the root node.
-    if (excludedTopLevelChild)
-      this.children.remove(excludedTopLevelChild);
-
-    const children = this.children;
-    const count = children.length;
-
-    for (let index = 0; index < count; ++index)
-      children[index]._exclude(excludedCallUID);
-
-    if (this.lastComparator)
-      this.sort(this.lastComparator, true);
-  }
-
-  /**
-   * @override
-   */
-  populateChildren() {
-    Profiler.BottomUpProfileDataGridNode._sharedPopulate(this);
-  }
-};
diff --git a/front_end/profiler/CPUProfileFlameChart.js b/front_end/profiler/CPUProfileFlameChart.js
deleted file mode 100644
index 2d858bb..0000000
--- a/front_end/profiler/CPUProfileFlameChart.js
+++ /dev/null
@@ -1,568 +0,0 @@
-/**
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {PerfUI.FlameChartDataProvider}
- * @unrestricted
- */
-Profiler.ProfileFlameChartDataProvider = class {
-  constructor() {
-    PerfUI.FlameChartDataProvider.call(this);
-    this._colorGenerator = Profiler.ProfileFlameChartDataProvider.colorGenerator();
-  }
-
-  /**
-   * @return {!Common.Color.Generator}
-   */
-  static colorGenerator() {
-    if (!Profiler.ProfileFlameChartDataProvider._colorGenerator) {
-      const colorGenerator =
-          new Common.Color.Generator({min: 30, max: 330}, {min: 50, max: 80, count: 5}, {min: 80, max: 90, count: 3});
-
-      colorGenerator.setColorForID('(idle)', 'hsl(0, 0%, 94%)');
-      colorGenerator.setColorForID('(program)', 'hsl(0, 0%, 80%)');
-      colorGenerator.setColorForID('(garbage collector)', 'hsl(0, 0%, 80%)');
-      Profiler.ProfileFlameChartDataProvider._colorGenerator = colorGenerator;
-    }
-    return Profiler.ProfileFlameChartDataProvider._colorGenerator;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._cpuProfile.profileStartTime;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  totalTime() {
-    return this._cpuProfile.profileHead.total;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.preciseMillisToString(value, precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maxStackDepth() {
-    return this._maxStackDepth;
-  }
-
-  /**
-   * @override
-   * @return {?PerfUI.FlameChart.TimelineData}
-   */
-  timelineData() {
-    return this._timelineData || this._calculateTimelineData();
-  }
-
-  /**
-   * @return {!PerfUI.FlameChart.TimelineData}
-   */
-  _calculateTimelineData() {
-    throw 'Not implemented.';
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {?Element}
-   */
-  prepareHighlightedEntryInfo(entryIndex) {
-    throw 'Not implemented.';
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  canJumpToEntry(entryIndex) {
-    return this._entryNodes[entryIndex].scriptId !== '0';
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {string}
-   */
-  entryTitle(entryIndex) {
-    const node = this._entryNodes[entryIndex];
-    return UI.beautifyFunctionName(node.functionName);
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {?string}
-   */
-  entryFont(entryIndex) {
-    if (!this._font) {
-      this._font = '11px ' + Host.fontFamily();
-      this._boldFont = 'bold ' + this._font;
-    }
-    const node = this._entryNodes[entryIndex];
-    return node.deoptReason ? this._boldFont : this._font;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {string}
-   */
-  entryColor(entryIndex) {
-    const node = this._entryNodes[entryIndex];
-    // For idle and program, we want different 'shades of gray', so we fallback to functionName as scriptId = 0
-    // For rest of nodes e.g eval scripts, if url is empty then scriptId will be guaranteed to be non-zero
-    return this._colorGenerator.colorForID(node.url || (node.scriptId !== '0' ? node.scriptId : node.functionName));
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @param {!CanvasRenderingContext2D} context
-   * @param {?string} text
-   * @param {number} barX
-   * @param {number} barY
-   * @param {number} barWidth
-   * @param {number} barHeight
-   * @return {boolean}
-   */
-  decorateEntry(entryIndex, context, text, barX, barY, barWidth, barHeight) {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  forceDecoration(entryIndex) {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {string}
-   */
-  textColor(entryIndex) {
-    return '#333';
-  }
-};
-
-
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Profiler.CPUProfileFlameChart = class extends UI.VBox {
-  /**
-   * @param {!UI.SearchableView} searchableView
-   * @param {!PerfUI.FlameChartDataProvider} dataProvider
-   */
-  constructor(searchableView, dataProvider) {
-    super();
-    this.element.id = 'cpu-flame-chart';
-
-    this._searchableView = searchableView;
-    this._overviewPane = new Profiler.CPUProfileFlameChart.OverviewPane(dataProvider);
-    this._overviewPane.show(this.element);
-
-    this._mainPane = new PerfUI.FlameChart(dataProvider, this._overviewPane);
-    this._mainPane.setBarHeight(15);
-    this._mainPane.setTextBaseline(4);
-    this._mainPane.setTextPadding(2);
-    this._mainPane.show(this.element);
-    this._mainPane.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
-    this._overviewPane.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-    this._dataProvider = dataProvider;
-    this._searchResults = [];
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._mainPane.focus();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWindowChanged(event) {
-    const windowLeft = event.data.windowTimeLeft;
-    const windowRight = event.data.windowTimeRight;
-    this._mainPane.setWindowTimes(windowLeft, windowRight, /* animate */ true);
-  }
-
-  /**
-   * @param {number} timeLeft
-   * @param {number} timeRight
-   */
-  selectRange(timeLeft, timeRight) {
-    this._overviewPane._selectRange(timeLeft, timeRight);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onEntrySelected(event) {
-    this.dispatchEventToListeners(PerfUI.FlameChart.Events.EntrySelected, event.data);
-  }
-
-  update() {
-    this._overviewPane.update();
-    this._mainPane.update();
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    const matcher = createPlainTextSearchRegex(searchConfig.query, searchConfig.caseSensitive ? '' : 'i');
-
-    const selectedEntryIndex = this._searchResultIndex !== -1 ? this._searchResults[this._searchResultIndex] : -1;
-    this._searchResults = [];
-    const entriesCount = this._dataProvider._entryNodes.length;
-    for (let index = 0; index < entriesCount; ++index) {
-      if (this._dataProvider.entryTitle(index).match(matcher))
-        this._searchResults.push(index);
-    }
-
-    if (this._searchResults.length) {
-      this._searchResultIndex = this._searchResults.indexOf(selectedEntryIndex);
-      if (this._searchResultIndex === -1)
-        this._searchResultIndex = jumpBackwards ? this._searchResults.length - 1 : 0;
-      this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);
-    } else {
-      this.searchCanceled();
-    }
-    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-    this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._mainPane.setSelectedEntry(-1);
-    this._searchResults = [];
-    this._searchResultIndex = -1;
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    this._searchResultIndex = (this._searchResultIndex + 1) % this._searchResults.length;
-    this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);
-    this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    this._searchResultIndex = (this._searchResultIndex - 1 + this._searchResults.length) % this._searchResults.length;
-    this._mainPane.setSelectedEntry(this._searchResults[this._searchResultIndex]);
-    this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return false;
-  }
-};
-
-/**
- * @implements {PerfUI.TimelineGrid.Calculator}
- * @unrestricted
- */
-Profiler.CPUProfileFlameChart.OverviewCalculator = class {
-  constructor(dataProvider) {
-    this._dataProvider = dataProvider;
-  }
-
-  /**
-   * @param {!Profiler.CPUProfileFlameChart.OverviewPane} overviewPane
-   */
-  _updateBoundaries(overviewPane) {
-    this._minimumBoundaries = overviewPane._dataProvider.minimumBoundary();
-    const totalTime = overviewPane._dataProvider.totalTime();
-    this._maximumBoundaries = this._minimumBoundaries + totalTime;
-    this._xScaleFactor = overviewPane._overviewContainer.clientWidth / totalTime;
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {
-    return (time - this._minimumBoundaries) * this._xScaleFactor;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return this._dataProvider.formatValue(value - this._minimumBoundaries, precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maximumBoundary() {
-    return this._maximumBoundaries;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._minimumBoundaries;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zeroTime() {
-    return this._minimumBoundaries;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  boundarySpan() {
-    return this._maximumBoundaries - this._minimumBoundaries;
-  }
-};
-
-/**
- * @implements {PerfUI.FlameChartDelegate}
- * @unrestricted
- */
-Profiler.CPUProfileFlameChart.OverviewPane = class extends UI.VBox {
-  /**
-   * @param {!PerfUI.FlameChartDataProvider} dataProvider
-   */
-  constructor(dataProvider) {
-    super();
-    this.element.classList.add('cpu-profile-flame-chart-overview-pane');
-    this._overviewContainer = this.element.createChild('div', 'cpu-profile-flame-chart-overview-container');
-    this._overviewGrid = new PerfUI.OverviewGrid('cpu-profile-flame-chart');
-    this._overviewGrid.element.classList.add('fill');
-    this._overviewCanvas = this._overviewContainer.createChild('canvas', 'cpu-profile-flame-chart-overview-canvas');
-    this._overviewContainer.appendChild(this._overviewGrid.element);
-    this._overviewCalculator = new Profiler.CPUProfileFlameChart.OverviewCalculator(dataProvider);
-    this._dataProvider = dataProvider;
-    this._overviewGrid.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-  }
-
-  /**
-   * @override
-   * @param {number} windowStartTime
-   * @param {number} windowEndTime
-   */
-  requestWindowTimes(windowStartTime, windowEndTime) {
-    this._selectRange(windowStartTime, windowEndTime);
-  }
-
-  /**
-   * @override
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  updateRangeSelection(startTime, endTime) {
-  }
-
-  /**
-   * @override
-   * @param {!PerfUI.FlameChart} flameChart
-   * @param {?PerfUI.FlameChart.Group} group
-   */
-  updateSelectedGroup(flameChart, group) {
-  }
-
-  /**
-   * @param {number} timeLeft
-   * @param {number} timeRight
-   */
-  _selectRange(timeLeft, timeRight) {
-    const startTime = this._dataProvider.minimumBoundary();
-    const totalTime = this._dataProvider.totalTime();
-    this._overviewGrid.setWindow((timeLeft - startTime) / totalTime, (timeRight - startTime) / totalTime);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWindowChanged(event) {
-    const startTime = this._dataProvider.minimumBoundary();
-    const totalTime = this._dataProvider.totalTime();
-    const data = {
-      windowTimeLeft: startTime + this._overviewGrid.windowLeft() * totalTime,
-      windowTimeRight: startTime + this._overviewGrid.windowRight() * totalTime
-    };
-    this.dispatchEventToListeners(PerfUI.OverviewGrid.Events.WindowChanged, data);
-  }
-
-  /**
-   * @return {?PerfUI.FlameChart.TimelineData}
-   */
-  _timelineData() {
-    return this._dataProvider.timelineData();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._scheduleUpdate();
-  }
-
-  _scheduleUpdate() {
-    if (this._updateTimerId)
-      return;
-    this._updateTimerId = this.element.window().requestAnimationFrame(this.update.bind(this));
-  }
-
-  update() {
-    this._updateTimerId = 0;
-    const timelineData = this._timelineData();
-    if (!timelineData)
-      return;
-    this._resetCanvas(
-        this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - PerfUI.FlameChart.HeaderHeight);
-    this._overviewCalculator._updateBoundaries(this);
-    this._overviewGrid.updateDividers(this._overviewCalculator);
-    this._drawOverviewCanvas();
-  }
-
-  _drawOverviewCanvas() {
-    const canvasWidth = this._overviewCanvas.width;
-    const canvasHeight = this._overviewCanvas.height;
-    const drawData = this._calculateDrawData(canvasWidth);
-    const context = this._overviewCanvas.getContext('2d');
-    const ratio = window.devicePixelRatio;
-    const offsetFromBottom = ratio;
-    const lineWidth = 1;
-    const yScaleFactor = canvasHeight / (this._dataProvider.maxStackDepth() * 1.1);
-    context.lineWidth = lineWidth;
-    context.translate(0.5, 0.5);
-    context.strokeStyle = 'rgba(20,0,0,0.4)';
-    context.fillStyle = 'rgba(214,225,254,0.8)';
-    context.moveTo(-lineWidth, canvasHeight + lineWidth);
-    context.lineTo(-lineWidth, Math.round(canvasHeight - drawData[0] * yScaleFactor - offsetFromBottom));
-    let value;
-    for (let x = 0; x < canvasWidth; ++x) {
-      value = Math.round(canvasHeight - drawData[x] * yScaleFactor - offsetFromBottom);
-      context.lineTo(x, value);
-    }
-    context.lineTo(canvasWidth + lineWidth, value);
-    context.lineTo(canvasWidth + lineWidth, canvasHeight + lineWidth);
-    context.fill();
-    context.stroke();
-    context.closePath();
-  }
-
-  /**
-   * @param {number} width
-   * @return {!Uint8Array}
-   */
-  _calculateDrawData(width) {
-    const dataProvider = this._dataProvider;
-    const timelineData = this._timelineData();
-    const entryStartTimes = timelineData.entryStartTimes;
-    const entryTotalTimes = timelineData.entryTotalTimes;
-    const entryLevels = timelineData.entryLevels;
-    const length = entryStartTimes.length;
-    const minimumBoundary = this._dataProvider.minimumBoundary();
-
-    const drawData = new Uint8Array(width);
-    const scaleFactor = width / dataProvider.totalTime();
-
-    for (let entryIndex = 0; entryIndex < length; ++entryIndex) {
-      const start = Math.floor((entryStartTimes[entryIndex] - minimumBoundary) * scaleFactor);
-      const finish =
-          Math.floor((entryStartTimes[entryIndex] - minimumBoundary + entryTotalTimes[entryIndex]) * scaleFactor);
-      for (let x = start; x <= finish; ++x)
-        drawData[x] = Math.max(drawData[x], entryLevels[entryIndex] + 1);
-    }
-    return drawData;
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  _resetCanvas(width, height) {
-    const ratio = window.devicePixelRatio;
-    this._overviewCanvas.width = width * ratio;
-    this._overviewCanvas.height = height * ratio;
-    this._overviewCanvas.style.width = width + 'px';
-    this._overviewCanvas.style.height = height + 'px';
-  }
-};
diff --git a/front_end/profiler/CPUProfileView.js b/front_end/profiler/CPUProfileView.js
deleted file mode 100644
index 5b9025d..0000000
--- a/front_end/profiler/CPUProfileView.js
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Profiler.CPUProfileView = class extends Profiler.ProfileView {
-  /**
-   * @param {!Profiler.CPUProfileHeader} profileHeader
-   */
-  constructor(profileHeader) {
-    super();
-    this._profileHeader = profileHeader;
-    this.profile = profileHeader.profileModel();
-    this.adjustedTotal = this.profile.profileHead.total;
-    this.adjustedTotal -= this.profile.idleNode ? this.profile.idleNode.total : 0;
-    this.initialize(new Profiler.CPUProfileView.NodeFormatter(this));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    const lineLevelProfile = PerfUI.LineLevelProfile.instance();
-    lineLevelProfile.reset();
-    lineLevelProfile.appendCPUProfile(this.profile);
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {string}
-   */
-  columnHeader(columnId) {
-    switch (columnId) {
-      case 'self':
-        return Common.UIString('Self Time');
-      case 'total':
-        return Common.UIString('Total Time');
-    }
-    return '';
-  }
-
-  /**
-   * @override
-   * @return {!PerfUI.FlameChartDataProvider}
-   */
-  createFlameChartDataProvider() {
-    return new Profiler.CPUFlameChartDataProvider(this.profile, this._profileHeader._cpuProfilerModel);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.CPUProfileType = class extends Profiler.ProfileType {
-  constructor() {
-    super(Profiler.CPUProfileType.TypeId, Common.UIString('Record JavaScript CPU Profile'));
-    this._recording = false;
-
-    Profiler.CPUProfileType.instance = this;
-    SDK.targetManager.addModelListener(
-        SDK.CPUProfilerModel, SDK.CPUProfilerModel.Events.ConsoleProfileFinished, this._consoleProfileFinished, this);
-  }
-
-  /**
-   * @override
-   * @return {?Profiler.CPUProfileHeader}
-   */
-  profileBeingRecorded() {
-    return /** @type {?Profiler.CPUProfileHeader} */ (super.profileBeingRecorded());
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  typeName() {
-    return 'CPU';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  fileExtension() {
-    return '.cpuprofile';
-  }
-
-  get buttonTooltip() {
-    return this._recording ? Common.UIString('Stop CPU profiling') : Common.UIString('Start CPU profiling');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  buttonClicked() {
-    if (this._recording) {
-      this.stopRecordingProfile();
-      return false;
-    } else {
-      this.startRecordingProfile();
-      return true;
-    }
-  }
-
-  get treeItemTitle() {
-    return Common.UIString('CPU PROFILES');
-  }
-
-  get description() {
-    return Common.UIString('CPU profiles show where the execution time is spent in your page\'s JavaScript functions.');
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _consoleProfileFinished(event) {
-    const data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
-    const cpuProfile = /** @type {!Protocol.Profiler.Profile} */ (data.cpuProfile);
-    const profile = new Profiler.CPUProfileHeader(data.cpuProfilerModel, this, data.title);
-    profile.setProtocolProfile(cpuProfile);
-    this.addProfile(profile);
-  }
-
-  startRecordingProfile() {
-    const cpuProfilerModel = UI.context.flavor(SDK.CPUProfilerModel);
-    if (this.profileBeingRecorded() || !cpuProfilerModel)
-      return;
-    const profile = new Profiler.CPUProfileHeader(cpuProfilerModel, this);
-    this.setProfileBeingRecorded(profile);
-    SDK.targetManager.suspendAllTargets();
-    this.addProfile(profile);
-    profile.updateStatus(Common.UIString('Recording\u2026'));
-    this._recording = true;
-    cpuProfilerModel.startRecording();
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ProfilesCPUProfileTaken);
-  }
-
-  async stopRecordingProfile() {
-    this._recording = false;
-    if (!this.profileBeingRecorded() || !this.profileBeingRecorded()._cpuProfilerModel)
-      return;
-
-    const profile = await this.profileBeingRecorded()._cpuProfilerModel.stopRecording();
-    const recordedProfile = this.profileBeingRecorded();
-    if (recordedProfile) {
-      console.assert(profile);
-      recordedProfile.setProtocolProfile(profile);
-      recordedProfile.updateStatus('');
-      this.setProfileBeingRecorded(null);
-    }
-
-    await SDK.targetManager.resumeAllTargets();
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, recordedProfile);
-  }
-
-  /**
-   * @override
-   * @param {string} title
-   * @return {!Profiler.ProfileHeader}
-   */
-  createProfileLoadedFromFile(title) {
-    return new Profiler.CPUProfileHeader(null, this, title);
-  }
-
-  /**
-   * @override
-   */
-  profileBeingRecordedRemoved() {
-    this.stopRecordingProfile();
-  }
-};
-
-Profiler.CPUProfileType.TypeId = 'CPU';
-
-/**
- * @unrestricted
- */
-Profiler.CPUProfileHeader = class extends Profiler.WritableProfileHeader {
-  /**
-   * @param {?SDK.CPUProfilerModel} cpuProfilerModel
-   * @param {!Profiler.CPUProfileType} type
-   * @param {string=} title
-   */
-  constructor(cpuProfilerModel, type, title) {
-    super(cpuProfilerModel && cpuProfilerModel.debuggerModel(), type, title);
-    this._cpuProfilerModel = cpuProfilerModel;
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.ProfileView}
-   */
-  createView() {
-    return new Profiler.CPUProfileView(this);
-  }
-
-  /**
-   * @return {!Protocol.Profiler.Profile}
-   */
-  protocolProfile() {
-    return this._protocolProfile;
-  }
-
-  /**
-   * @return {!SDK.CPUProfileDataModel}
-   */
-  profileModel() {
-    return this._profileModel;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Profiler.Profile} profile
-   */
-  setProfile(profile) {
-    this._profileModel = new SDK.CPUProfileDataModel(profile);
-  }
-};
-
-/**
- * @implements {Profiler.ProfileDataGridNode.Formatter}
- * @unrestricted
- */
-Profiler.CPUProfileView.NodeFormatter = class {
-  /**
-   * @param {!Profiler.CPUProfileView} profileView
-   */
-  constructor(profileView) {
-    this._profileView = profileView;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @return {string}
-   */
-  formatValue(value) {
-    return Common.UIString('%.1f\xa0ms', value);
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {!Profiler.ProfileDataGridNode} node
-   * @return {string}
-   */
-  formatPercent(value, node) {
-    return node.profileNode === this._profileView.profile.idleNode ? '' : Common.UIString('%.2f\xa0%%', value);
-  }
-
-  /**
-   * @override
-   * @param  {!Profiler.ProfileDataGridNode} node
-   * @return {?Element}
-   */
-  linkifyNode(node) {
-    const cpuProfilerModel = this._profileView._profileHeader._cpuProfilerModel;
-    return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(
-        cpuProfilerModel ? cpuProfilerModel.target() : null, node.profileNode.callFrame, 'profile-node-file');
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.CPUFlameChartDataProvider = class extends Profiler.ProfileFlameChartDataProvider {
-  /**
-   * @param {!SDK.CPUProfileDataModel} cpuProfile
-   * @param {?SDK.CPUProfilerModel} cpuProfilerModel
-   */
-  constructor(cpuProfile, cpuProfilerModel) {
-    super();
-    this._cpuProfile = cpuProfile;
-    this._cpuProfilerModel = cpuProfilerModel;
-  }
-
-  /**
-   * @override
-   * @return {!PerfUI.FlameChart.TimelineData}
-   */
-  _calculateTimelineData() {
-    /** @type {!Array.<?Profiler.CPUFlameChartDataProvider.ChartEntry>} */
-    const entries = [];
-    /** @type {!Array.<number>} */
-    const stack = [];
-    let maxDepth = 5;
-
-    function onOpenFrame() {
-      stack.push(entries.length);
-      // Reserve space for the entry, as they have to be ordered by startTime.
-      // The entry itself will be put there in onCloseFrame.
-      entries.push(null);
-    }
-    /**
-     * @param {number} depth
-     * @param {!SDK.CPUProfileNode} node
-     * @param {number} startTime
-     * @param {number} totalTime
-     * @param {number} selfTime
-     */
-    function onCloseFrame(depth, node, startTime, totalTime, selfTime) {
-      const index = stack.pop();
-      entries[index] = new Profiler.CPUFlameChartDataProvider.ChartEntry(depth, totalTime, startTime, selfTime, node);
-      maxDepth = Math.max(maxDepth, depth);
-    }
-    this._cpuProfile.forEachFrame(onOpenFrame, onCloseFrame);
-
-    /** @type {!Array<!SDK.CPUProfileNode>} */
-    const entryNodes = new Array(entries.length);
-    const entryLevels = new Uint16Array(entries.length);
-    const entryTotalTimes = new Float32Array(entries.length);
-    const entrySelfTimes = new Float32Array(entries.length);
-    const entryStartTimes = new Float64Array(entries.length);
-
-    for (let i = 0; i < entries.length; ++i) {
-      const entry = entries[i];
-      entryNodes[i] = entry.node;
-      entryLevels[i] = entry.depth;
-      entryTotalTimes[i] = entry.duration;
-      entryStartTimes[i] = entry.startTime;
-      entrySelfTimes[i] = entry.selfTime;
-    }
-
-    this._maxStackDepth = maxDepth + 1;
-
-    this._timelineData = new PerfUI.FlameChart.TimelineData(entryLevels, entryTotalTimes, entryStartTimes, null);
-
-    /** @type {!Array<!SDK.CPUProfileNode>} */
-    this._entryNodes = entryNodes;
-    this._entrySelfTimes = entrySelfTimes;
-
-    return this._timelineData;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {?Element}
-   */
-  prepareHighlightedEntryInfo(entryIndex) {
-    const timelineData = this._timelineData;
-    const node = this._entryNodes[entryIndex];
-    if (!node)
-      return null;
-
-    const entryInfo = [];
-    /**
-     * @param {string} title
-     * @param {string} value
-     */
-    function pushEntryInfoRow(title, value) {
-      entryInfo.push({title: title, value: value});
-    }
-    /**
-     * @param {number} ms
-     * @return {string}
-     */
-    function millisecondsToString(ms) {
-      if (ms === 0)
-        return '0';
-      if (ms < 1000)
-        return Common.UIString('%.1f\xa0ms', ms);
-      return Number.secondsToString(ms / 1000, true);
-    }
-    const name = UI.beautifyFunctionName(node.functionName);
-    pushEntryInfoRow(Common.UIString('Name'), name);
-    const selfTime = millisecondsToString(this._entrySelfTimes[entryIndex]);
-    const totalTime = millisecondsToString(timelineData.entryTotalTimes[entryIndex]);
-    pushEntryInfoRow(Common.UIString('Self time'), selfTime);
-    pushEntryInfoRow(Common.UIString('Total time'), totalTime);
-    const linkifier = new Components.Linkifier();
-    const link = linkifier.maybeLinkifyConsoleCallFrame(
-        this._cpuProfilerModel && this._cpuProfilerModel.target(), node.callFrame);
-    if (link)
-      pushEntryInfoRow(Common.UIString('URL'), link.textContent);
-    linkifier.dispose();
-    pushEntryInfoRow(Common.UIString('Aggregated self time'), Number.secondsToString(node.self / 1000, true));
-    pushEntryInfoRow(Common.UIString('Aggregated total time'), Number.secondsToString(node.total / 1000, true));
-    if (node.deoptReason)
-      pushEntryInfoRow(Common.UIString('Not optimized'), node.deoptReason);
-
-    return Profiler.ProfileView.buildPopoverTable(entryInfo);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.CPUFlameChartDataProvider.ChartEntry = class {
-  /**
-   * @param {number} depth
-   * @param {number} duration
-   * @param {number} startTime
-   * @param {number} selfTime
-   * @param {!SDK.CPUProfileNode} node
-   */
-  constructor(depth, duration, startTime, selfTime, node) {
-    this.depth = depth;
-    this.duration = duration;
-    this.startTime = startTime;
-    this.selfTime = selfTime;
-    this.node = node;
-  }
-};
diff --git a/front_end/profiler/HeapProfileView.js b/front_end/profiler/HeapProfileView.js
deleted file mode 100644
index 0d5d641..0000000
--- a/front_end/profiler/HeapProfileView.js
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Profiler.HeapProfileView = class extends Profiler.ProfileView {
-  /**
-   * @param {!Profiler.SamplingHeapProfileHeader} profileHeader
-   */
-  constructor(profileHeader) {
-    super();
-    this._profileHeader = profileHeader;
-    this.profile = new Profiler.SamplingHeapProfileModel(profileHeader._profile || profileHeader.protocolProfile());
-    this.adjustedTotal = this.profile.total;
-    const views = [
-      Profiler.ProfileView.ViewTypes.Flame, Profiler.ProfileView.ViewTypes.Heavy, Profiler.ProfileView.ViewTypes.Tree
-    ];
-    this.initialize(new Profiler.HeapProfileView.NodeFormatter(this), views);
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {string}
-   */
-  columnHeader(columnId) {
-    switch (columnId) {
-      case 'self':
-        return Common.UIString('Self Size (bytes)');
-      case 'total':
-        return Common.UIString('Total Size (bytes)');
-    }
-    return '';
-  }
-
-  /**
-   * @override
-   * @return {!PerfUI.FlameChartDataProvider}
-   */
-  createFlameChartDataProvider() {
-    return new Profiler.HeapFlameChartDataProvider(this.profile, this._profileHeader._heapProfilerModel);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.SamplingHeapProfileTypeBase = class extends Profiler.ProfileType {
-  constructor(typeId, description) {
-    super(typeId, description);
-    this._recording = false;
-  }
-
-  /**
-   * @override
-   * @return {?Profiler.SamplingHeapProfileHeader}
-   */
-  profileBeingRecorded() {
-    return /** @type {?Profiler.SamplingHeapProfileHeader} */ (super.profileBeingRecorded());
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  typeName() {
-    return 'Heap';
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  fileExtension() {
-    return '.heapprofile';
-  }
-
-  get buttonTooltip() {
-    return this._recording ? Common.UIString('Stop heap profiling') : Common.UIString('Start heap profiling');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  buttonClicked() {
-    const wasRecording = this._recording;
-    if (wasRecording)
-      this.stopRecordingProfile();
-    else
-      this.startRecordingProfile();
-    return !wasRecording;
-  }
-
-  startRecordingProfile() {
-    const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
-    if (this.profileBeingRecorded() || !heapProfilerModel)
-      return;
-    const profile = new Profiler.SamplingHeapProfileHeader(heapProfilerModel, this);
-    this.setProfileBeingRecorded(profile);
-    SDK.targetManager.suspendAllTargets();
-    this.addProfile(profile);
-    profile.updateStatus(Common.UIString('Recording\u2026'));
-    this._recording = true;
-    this._startSampling();
-  }
-
-  async stopRecordingProfile() {
-    this._recording = false;
-    if (!this.profileBeingRecorded() || !this.profileBeingRecorded()._heapProfilerModel)
-      return;
-
-    this.profileBeingRecorded().updateStatus(Common.UIString('Stopping\u2026'));
-    const profile = await this._stopSampling();
-    const recordedProfile = this.profileBeingRecorded();
-    if (recordedProfile) {
-      console.assert(profile);
-      recordedProfile.setProtocolProfile(profile);
-      recordedProfile.updateStatus('');
-      this.setProfileBeingRecorded(null);
-    }
-
-    await SDK.targetManager.resumeAllTargets();
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, recordedProfile);
-  }
-
-  /**
-   * @override
-   * @param {string} title
-   * @return {!Profiler.ProfileHeader}
-   */
-  createProfileLoadedFromFile(title) {
-    return new Profiler.SamplingHeapProfileHeader(null, this, title);
-  }
-
-  /**
-   * @override
-   */
-  profileBeingRecordedRemoved() {
-    this.stopRecordingProfile();
-  }
-
-  _startSampling() {
-    throw 'Not implemented';
-  }
-
-  /**
-   * return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
-   */
-  _stopSampling() {
-    throw 'Not implemented';
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Profiler.SamplingHeapProfileType = class extends Profiler.SamplingHeapProfileTypeBase {
-  constructor() {
-    super(Profiler.SamplingHeapProfileType.TypeId, ls`Allocation sampling`);
-    Profiler.SamplingHeapProfileType.instance = this;
-  }
-
-  get treeItemTitle() {
-    return ls`SAMPLING PROFILES`;
-  }
-
-  get description() {
-    return ls`Record memory allocations using sampling method.
-              This profile type has minimal performance overhead and can be used for long running operations.
-              It provides good approximation of allocations broken down by JavaScript execution stack.`;
-  }
-
-  /**
-   * @override
-   */
-  _startSampling() {
-    this.profileBeingRecorded()._heapProfilerModel.startSampling();
-  }
-
-  /**
-   * @override
-   * return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
-   */
-  _stopSampling() {
-    return this.profileBeingRecorded()._heapProfilerModel.stopSampling();
-  }
-};
-
-Profiler.SamplingHeapProfileType.TypeId = 'SamplingHeap';
-
-/**
- * @unrestricted
- */
-Profiler.SamplingNativeHeapProfileType = class extends Profiler.SamplingHeapProfileTypeBase {
-  constructor() {
-    super(Profiler.SamplingNativeHeapProfileType.TypeId, ls`Native memory allocation sampling`);
-    Profiler.SamplingNativeHeapProfileType.instance = this;
-  }
-
-  get treeItemTitle() {
-    return ls`NATIVE SAMPLING PROFILES`;
-  }
-
-  get description() {
-    return ls`Allocation profiles show sampled native memory allocations from the renderer process.`;
-  }
-
-  /**
-   * @override
-   */
-  _startSampling() {
-    this.profileBeingRecorded()._heapProfilerModel.startNativeSampling();
-  }
-
-  /**
-   * @override
-   * return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
-   */
-  _stopSampling() {
-    return this.profileBeingRecorded()._heapProfilerModel.stopNativeSampling();
-  }
-};
-
-Profiler.SamplingNativeHeapProfileType.TypeId = 'SamplingNativeHeapRecording';
-
-/**
- * @unrestricted
- */
-Profiler.SamplingNativeHeapSnapshotType = class extends Profiler.SamplingHeapProfileTypeBase {
-  constructor() {
-    super(Profiler.SamplingNativeHeapSnapshotType.TypeId, ls`Native memory allocation snapshot`);
-    Profiler.SamplingNativeHeapSnapshotType.instance = this;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isInstantProfile() {
-    return true;
-  }
-
-  get treeItemTitle() {
-    return ls`NATIVE SNAPSHOTS`;
-  }
-
-  get description() {
-    return ls`Native memory snapshots show sampled native allocations in the renderer process since start up.
-              Chrome has to be started with --sampling-heap-profiler flag.
-              Check flags at chrome://flags`;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  buttonClicked() {
-    this._takeSnapshot();
-    return false;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async _takeSnapshot() {
-    if (this.profileBeingRecorded())
-      return;
-    const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
-    if (!heapProfilerModel)
-      return;
-
-    const profile = new Profiler.SamplingHeapProfileHeader(
-        heapProfilerModel, this, Common.UIString('Snapshot %d', this.nextProfileUid()));
-    this.setProfileBeingRecorded(profile);
-    this.addProfile(profile);
-    profile.updateStatus(Common.UIString('Snapshotting\u2026'));
-
-    const protocolProfile = await heapProfilerModel.takeNativeSnapshot();
-    const recordedProfile = this.profileBeingRecorded();
-    if (recordedProfile) {
-      console.assert(protocolProfile);
-      recordedProfile.setProtocolProfile(protocolProfile);
-      recordedProfile.updateStatus('');
-      this.setProfileBeingRecorded(null);
-    }
-
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, recordedProfile);
-  }
-};
-
-Profiler.SamplingNativeHeapSnapshotType.TypeId = 'SamplingNativeHeapSnapshot';
-
-/**
- * @unrestricted
- */
-Profiler.SamplingHeapProfileHeader = class extends Profiler.WritableProfileHeader {
-  /**
-   * @param {?SDK.HeapProfilerModel} heapProfilerModel
-   * @param {!Profiler.SamplingHeapProfileTypeBase} type
-   * @param {string=} title
-   */
-  constructor(heapProfilerModel, type, title) {
-    super(
-        heapProfilerModel && heapProfilerModel.debuggerModel(), type,
-        title || Common.UIString('Profile %d', type.nextProfileUid()));
-    this._heapProfilerModel = heapProfilerModel;
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.ProfileView}
-   */
-  createView() {
-    return new Profiler.HeapProfileView(this);
-  }
-
-  /**
-   * @return {!Protocol.HeapProfiler.SamplingHeapProfile}
-   */
-  protocolProfile() {
-    return this._protocolProfile;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.SamplingHeapProfileNode = class extends SDK.ProfileNode {
-  /**
-   * @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} node
-   */
-  constructor(node) {
-    const callFrame = node.callFrame || /** @type {!Protocol.Runtime.CallFrame} */ ({
-                        // Backward compatibility for old CpuProfileNode format.
-                        functionName: node['functionName'],
-                        scriptId: node['scriptId'],
-                        url: node['url'],
-                        lineNumber: node['lineNumber'] - 1,
-                        columnNumber: node['columnNumber'] - 1
-                      });
-    super(callFrame);
-    this.self = node.selfSize;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.SamplingHeapProfileModel = class extends SDK.ProfileTreeModel {
-  /**
-   * @param {!Protocol.HeapProfiler.SamplingHeapProfile} profile
-   */
-  constructor(profile) {
-    super();
-    this.initialize(translateProfileTree(profile.head));
-
-    /**
-     * @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} root
-     * @return {!Profiler.SamplingHeapProfileNode}
-     */
-    function translateProfileTree(root) {
-      const resultRoot = new Profiler.SamplingHeapProfileNode(root);
-      const targetNodeStack = [resultRoot];
-      const sourceNodeStack = [root];
-      while (sourceNodeStack.length) {
-        const sourceNode = sourceNodeStack.pop();
-        const parentNode = targetNodeStack.pop();
-        parentNode.children = sourceNode.children.map(child => new Profiler.SamplingHeapProfileNode(child));
-        sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children);
-        targetNodeStack.push.apply(targetNodeStack, parentNode.children);
-      }
-      return resultRoot;
-    }
-  }
-};
-
-/**
- * @implements {Profiler.ProfileDataGridNode.Formatter}
- * @unrestricted
- */
-Profiler.HeapProfileView.NodeFormatter = class {
-  /**
-   * @param {!Profiler.HeapProfileView} profileView
-   */
-  constructor(profileView) {
-    this._profileView = profileView;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @return {string}
-   */
-  formatValue(value) {
-    return Number.withThousandsSeparator(value);
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {!Profiler.ProfileDataGridNode} node
-   * @return {string}
-   */
-  formatPercent(value, node) {
-    return Common.UIString('%.2f\xa0%%', value);
-  }
-
-  /**
-   * @override
-   * @param  {!Profiler.ProfileDataGridNode} node
-   * @return {?Element}
-   */
-  linkifyNode(node) {
-    const heapProfilerModel = this._profileView._profileHeader._heapProfilerModel;
-    return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(
-        heapProfilerModel ? heapProfilerModel.target() : null, node.profileNode.callFrame, 'profile-node-file');
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapFlameChartDataProvider = class extends Profiler.ProfileFlameChartDataProvider {
-  /**
-   * @param {!SDK.ProfileTreeModel} profile
-   * @param {?SDK.HeapProfilerModel} heapProfilerModel
-   */
-  constructor(profile, heapProfilerModel) {
-    super();
-    this._profile = profile;
-    this._heapProfilerModel = heapProfilerModel;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return 0;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  totalTime() {
-    return this._profile.root.total;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Common.UIString('%s\xa0KB', Number.withThousandsSeparator(value / 1e3));
-  }
-
-  /**
-   * @override
-   * @return {!PerfUI.FlameChart.TimelineData}
-   */
-  _calculateTimelineData() {
-    /**
-     * @param  {!SDK.ProfileNode} node
-     * @return {number}
-     */
-    function nodesCount(node) {
-      return node.children.reduce((count, node) => count + nodesCount(node), 1);
-    }
-    const count = nodesCount(this._profile.root);
-    /** @type {!Array<!SDK.ProfileNode>} */
-    const entryNodes = new Array(count);
-    const entryLevels = new Uint16Array(count);
-    const entryTotalTimes = new Float32Array(count);
-    const entryStartTimes = new Float64Array(count);
-    let depth = 0;
-    let maxDepth = 0;
-    let position = 0;
-    let index = 0;
-
-    /**
-     * @param {!SDK.ProfileNode} node
-     */
-    function addNode(node) {
-      const start = position;
-      entryNodes[index] = node;
-      entryLevels[index] = depth;
-      entryTotalTimes[index] = node.total;
-      entryStartTimes[index] = position;
-      ++index;
-      ++depth;
-      node.children.forEach(addNode);
-      --depth;
-      maxDepth = Math.max(maxDepth, depth);
-      position = start + node.total;
-    }
-    addNode(this._profile.root);
-
-    this._maxStackDepth = maxDepth + 1;
-    this._entryNodes = entryNodes;
-    this._timelineData = new PerfUI.FlameChart.TimelineData(entryLevels, entryTotalTimes, entryStartTimes, null);
-
-    return this._timelineData;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {?Element}
-   */
-  prepareHighlightedEntryInfo(entryIndex) {
-    const node = this._entryNodes[entryIndex];
-    if (!node)
-      return null;
-    const entryInfo = [];
-    /**
-     * @param {string} title
-     * @param {string} value
-     */
-    function pushEntryInfoRow(title, value) {
-      entryInfo.push({title: title, value: value});
-    }
-    pushEntryInfoRow(Common.UIString('Name'), UI.beautifyFunctionName(node.functionName));
-    pushEntryInfoRow(Common.UIString('Self size'), Number.bytesToString(node.self));
-    pushEntryInfoRow(Common.UIString('Total size'), Number.bytesToString(node.total));
-    const linkifier = new Components.Linkifier();
-    const link = linkifier.maybeLinkifyConsoleCallFrame(
-        this._heapProfilerModel ? this._heapProfilerModel.target() : null, node.callFrame);
-    if (link)
-      pushEntryInfoRow(Common.UIString('URL'), link.textContent);
-    linkifier.dispose();
-    return Profiler.ProfileView.buildPopoverTable(entryInfo);
-  }
-};
diff --git a/front_end/profiler/HeapProfilerPanel.js b/front_end/profiler/HeapProfilerPanel.js
deleted file mode 100644
index c3ae83d..0000000
--- a/front_end/profiler/HeapProfilerPanel.js
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {UI.ContextMenu.Provider}
- * @implements {UI.ActionDelegate}
- */
-Profiler.HeapProfilerPanel = class extends Profiler.ProfilesPanel {
-  constructor() {
-    const registry = Profiler.ProfileTypeRegistry.instance;
-    const profileTypes =
-        [registry.heapSnapshotProfileType, registry.trackingHeapSnapshotProfileType, registry.samplingHeapProfileType];
-    if (Runtime.experiments.isEnabled('nativeHeapProfiler'))
-      profileTypes.push(registry.samplingNativeHeapProfileType, registry.samplingNativeHeapSnapshotType);
-    super('heap_profiler', profileTypes, 'profiler.heap-toggle-recording');
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    if (!(target instanceof SDK.RemoteObject))
-      return;
-
-    if (!this.isShowing())
-      return;
-
-    const object = /** @type {!SDK.RemoteObject} */ (target);
-    if (!object.objectId)
-      return;
-    const objectId = /** @type {string} */ (object.objectId);
-
-    const heapProfiles = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
-    if (!heapProfiles.length)
-      return;
-
-    const heapProfilerModel = object.runtimeModel().heapProfilerModel();
-    if (!heapProfilerModel)
-      return;
-
-    /**
-     * @param {string} viewName
-     * @this {Profiler.ProfilesPanel}
-     */
-    function revealInView(viewName) {
-      heapProfilerModel.snapshotObjectIdForObjectId(objectId).then(result => {
-        if (this.isShowing() && result)
-          this.showObject(result, viewName);
-      });
-    }
-
-    contextMenu.revealSection().appendItem(
-        Common.UIString('Reveal in Summary view'), revealInView.bind(this, 'Summary'));
-  }
-
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const panel = UI.context.flavor(Profiler.HeapProfilerPanel);
-    console.assert(panel && panel instanceof Profiler.HeapProfilerPanel);
-    panel.toggleRecord();
-    return true;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Profiler.HeapProfilerPanel, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.context.setFlavor(Profiler.HeapProfilerPanel, null);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
-   * @param {string} perspectiveName
-   */
-  showObject(snapshotObjectId, perspectiveName) {
-    const registry = Profiler.ProfileTypeRegistry.instance;
-    const heapProfiles = registry.heapSnapshotProfileType.getProfiles();
-    for (let i = 0; i < heapProfiles.length; i++) {
-      const profile = heapProfiles[i];
-      // FIXME: allow to choose snapshot if there are several options.
-      if (profile.maxJSObjectId >= snapshotObjectId) {
-        this.showProfile(profile);
-        const view = this.viewForProfile(profile);
-        view.selectLiveObject(perspectiveName, snapshotObjectId);
-        break;
-      }
-    }
-  }
-};
diff --git a/front_end/profiler/HeapSnapshotDataGrids.js b/front_end/profiler/HeapSnapshotDataGrids.js
deleted file mode 100644
index f87c6fe..0000000
--- a/front_end/profiler/HeapSnapshotDataGrids.js
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotSortableDataGrid = class extends DataGrid.DataGrid {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {!Array.<!DataGrid.DataGrid.ColumnDescriptor>} columns
-   */
-  constructor(dataDisplayDelegate, columns) {
-    // TODO(allada) This entire class needs to be converted to use the templates in DataGridNode.
-    super(columns);
-    this._dataDisplayDelegate = dataDisplayDelegate;
-
-    /**
-     * @type {number}
-     */
-    this._recursiveSortingDepth = 0;
-    /**
-     * @type {?Profiler.HeapSnapshotGridNode}
-     */
-    this._highlightedNode = null;
-    /**
-     * @type {boolean}
-     */
-    this._populatedAndSorted = false;
-    /**
-     * @type {?UI.ToolbarInput}
-     */
-    this._nameFilter = null;
-    this._nodeFilter = new HeapSnapshotModel.NodeFilter();
-    this.addEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, this._sortingComplete, this);
-    this.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this.sortingChanged, this);
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.NodeFilter}
-   */
-  nodeFilter() {
-    return this._nodeFilter;
-  }
-
-  /**
-   * @param {!UI.ToolbarInput} nameFilter
-   */
-  setNameFilter(nameFilter) {
-    this._nameFilter = nameFilter;
-  }
-
-  /**
-   * @return {number}
-   */
-  defaultPopulateCount() {
-    return 100;
-  }
-
-  _disposeAllNodes() {
-    const children = this.topLevelNodes();
-    for (let i = 0, l = children.length; i < l; ++i)
-      children[i].dispose();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._nameFilter) {
-      this._nameFilter.addEventListener(UI.ToolbarInput.Event.TextChanged, this._onNameFilterChanged, this);
-      this.updateVisibleNodes(true);
-    }
-    if (this._populatedAndSorted)
-      this.dispatchEventToListeners(Profiler.HeapSnapshotSortableDataGrid.Events.ContentShown, this);
-  }
-
-  _sortingComplete() {
-    this.removeEventListener(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete, this._sortingComplete, this);
-    this._populatedAndSorted = true;
-    this.dispatchEventToListeners(Profiler.HeapSnapshotSortableDataGrid.Events.ContentShown, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    if (this._nameFilter)
-      this._nameFilter.removeEventListener(UI.ToolbarInput.Event.TextChanged, this._onNameFilterChanged, this);
-    this._clearCurrentHighlight();
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Event} event
-   */
-  populateContextMenu(contextMenu, event) {
-    const td = event.target.enclosingNodeOrSelfWithNodeName('td');
-    if (!td)
-      return;
-    const node = td.heapSnapshotNode;
-    contextMenu.revealSection().appendItem(ls`Reveal in Summary view`, () => {
-      this._dataDisplayDelegate.showObject(node.snapshotNodeId, ls`Summary`);
-    });
-  }
-
-  resetSortingCache() {
-    delete this._lastSortColumnId;
-    delete this._lastSortAscending;
-  }
-
-  /**
-   * @return {!Array.<!Profiler.HeapSnapshotGridNode>}
-   */
-  topLevelNodes() {
-    return this.rootNode().children;
-  }
-
-  /**
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} heapSnapshotObjectId
-   * @return {!Promise<?Profiler.HeapSnapshotGridNode>}
-   */
-  revealObjectByHeapSnapshotId(heapSnapshotObjectId) {
-    return Promise.resolve(/** @type {?Profiler.HeapSnapshotGridNode} */ (null));
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotGridNode} node
-   */
-  highlightNode(node) {
-    this._clearCurrentHighlight();
-    this._highlightedNode = node;
-    UI.runCSSAnimationOnce(this._highlightedNode.element(), 'highlighted-row');
-  }
-
-  _clearCurrentHighlight() {
-    if (!this._highlightedNode)
-      return;
-    this._highlightedNode.element().classList.remove('highlighted-row');
-    this._highlightedNode = null;
-  }
-
-  resetNameFilter() {
-    this._nameFilter.setValue('');
-  }
-
-  _onNameFilterChanged() {
-    this.updateVisibleNodes(true);
-  }
-
-  sortingChanged() {
-    const sortAscending = this.isSortOrderAscending();
-    const sortColumnId = this.sortColumnId();
-    if (this._lastSortColumnId === sortColumnId && this._lastSortAscending === sortAscending)
-      return;
-    this._lastSortColumnId = sortColumnId;
-    this._lastSortAscending = sortAscending;
-    const sortFields = this._sortFields(sortColumnId, sortAscending);
-
-    function SortByTwoFields(nodeA, nodeB) {
-      let field1 = nodeA[sortFields[0]];
-      let field2 = nodeB[sortFields[0]];
-      let result = field1 < field2 ? -1 : (field1 > field2 ? 1 : 0);
-      if (!sortFields[1])
-        result = -result;
-      if (result !== 0)
-        return result;
-      field1 = nodeA[sortFields[2]];
-      field2 = nodeB[sortFields[2]];
-      result = field1 < field2 ? -1 : (field1 > field2 ? 1 : 0);
-      if (!sortFields[3])
-        result = -result;
-      return result;
-    }
-    this._performSorting(SortByTwoFields);
-  }
-
-  _performSorting(sortFunction) {
-    this.recursiveSortingEnter();
-    const children = this.allChildren(this.rootNode());
-    this.rootNode().removeChildren();
-    children.sort(sortFunction);
-    for (let i = 0, l = children.length; i < l; ++i) {
-      const child = children[i];
-      this.appendChildAfterSorting(child);
-      if (child.expanded)
-        child.sort();
-    }
-    this.recursiveSortingLeave();
-  }
-
-  appendChildAfterSorting(child) {
-    const revealed = child.revealed;
-    this.rootNode().appendChild(child);
-    child.revealed = revealed;
-  }
-
-  recursiveSortingEnter() {
-    ++this._recursiveSortingDepth;
-  }
-
-  recursiveSortingLeave() {
-    if (!this._recursiveSortingDepth)
-      return;
-    if (--this._recursiveSortingDepth)
-      return;
-    this.updateVisibleNodes(true);
-    this.dispatchEventToListeners(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete);
-  }
-
-  /**
-   * @param {boolean} force
-   */
-  updateVisibleNodes(force) {
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} parent
-   * @return {!Array.<!Profiler.HeapSnapshotGridNode>}
-   */
-  allChildren(parent) {
-    return parent.children;
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} parent
-   * @param {!DataGrid.DataGridNode} node
-   * @param {number} index
-   */
-  insertChild(parent, node, index) {
-    parent.insertChild(node, index);
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotGridNode} parent
-   * @param {number} index
-   */
-  removeChildByIndex(parent, index) {
-    parent.removeChild(parent.children[index]);
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotGridNode} parent
-   */
-  removeAllChildren(parent) {
-    parent.removeChildren();
-  }
-};
-
-/** @enum {symbol} */
-Profiler.HeapSnapshotSortableDataGrid.Events = {
-  ContentShown: Symbol('ContentShown'),
-  SortingComplete: Symbol('SortingComplete')
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotViewportDataGrid = class extends Profiler.HeapSnapshotSortableDataGrid {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {!Array.<!DataGrid.DataGrid.ColumnDescriptor>} columns
-   */
-  constructor(dataDisplayDelegate, columns) {
-    super(dataDisplayDelegate, columns);
-    this.scrollContainer.addEventListener('scroll', this._onScroll.bind(this), true);
-    this._topPaddingHeight = 0;
-    this._bottomPaddingHeight = 0;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Profiler.HeapSnapshotGridNode>}
-   */
-  topLevelNodes() {
-    return this.allChildren(this.rootNode());
-  }
-
-  /**
-   * @override
-   */
-  appendChildAfterSorting(child) {
-    // Do nothing here, it will be added in updateVisibleNodes.
-  }
-
-  /**
-   * @override
-   * @param {boolean} force
-   */
-  updateVisibleNodes(force) {
-    // Guard zone is used to ensure there are always some extra items
-    // above and below the viewport to support keyboard navigation.
-    const guardZoneHeight = 40;
-    const scrollHeight = this.scrollContainer.scrollHeight;
-    let scrollTop = this.scrollContainer.scrollTop;
-    let scrollBottom = scrollHeight - scrollTop - this.scrollContainer.offsetHeight;
-    scrollTop = Math.max(0, scrollTop - guardZoneHeight);
-    scrollBottom = Math.max(0, scrollBottom - guardZoneHeight);
-    let viewPortHeight = scrollHeight - scrollTop - scrollBottom;
-    // Do nothing if populated nodes still fit the viewport.
-    if (!force && scrollTop >= this._topPaddingHeight && scrollBottom >= this._bottomPaddingHeight)
-      return;
-    const hysteresisHeight = 500;
-    scrollTop -= hysteresisHeight;
-    viewPortHeight += 2 * hysteresisHeight;
-    const selectedNode = this.selectedNode;
-    this.rootNode().removeChildren();
-
-    this._topPaddingHeight = 0;
-    this._bottomPaddingHeight = 0;
-
-    this._addVisibleNodes(this.rootNode(), scrollTop, scrollTop + viewPortHeight);
-
-    this.setVerticalPadding(this._topPaddingHeight, this._bottomPaddingHeight);
-
-    if (selectedNode) {
-      // Keep selection even if the node is not in the current viewport.
-      if (selectedNode.parent)
-        selectedNode.select(true);
-      else
-        this.selectedNode = selectedNode;
-    }
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} parentNode
-   * @param {number} topBound
-   * @param {number} bottomBound
-   * @return {number}
-   */
-  _addVisibleNodes(parentNode, topBound, bottomBound) {
-    if (!parentNode.expanded)
-      return 0;
-
-    const children = this.allChildren(parentNode);
-    let topPadding = 0;
-    const nameFilterValue = this._nameFilter ? this._nameFilter.value().toLowerCase() : '';
-    // Iterate over invisible nodes beyond the upper bound of viewport.
-    // Do not insert them into the grid, but count their total height.
-    let i = 0;
-    for (; i < children.length; ++i) {
-      const child = children[i];
-      if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
-        continue;
-      const newTop = topPadding + this._nodeHeight(child);
-      if (newTop > topBound)
-        break;
-      topPadding = newTop;
-    }
-
-    // Put visible nodes into the data grid.
-    let position = topPadding;
-    for (; i < children.length && position < bottomBound; ++i) {
-      const child = children[i];
-      if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
-        continue;
-      const hasChildren = child.hasChildren();
-      child.removeChildren();
-      child.setHasChildren(hasChildren);
-      parentNode.appendChild(child);
-      position += child.nodeSelfHeight();
-      position += this._addVisibleNodes(child, topBound - position, bottomBound - position);
-    }
-
-    // Count the invisible nodes beyond the bottom bound of the viewport.
-    let bottomPadding = 0;
-    for (; i < children.length; ++i) {
-      const child = children[i];
-      if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
-        continue;
-      bottomPadding += this._nodeHeight(child);
-    }
-
-    this._topPaddingHeight += topPadding;
-    this._bottomPaddingHeight += bottomPadding;
-    return position + bottomPadding;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotGridNode} node
-   * @return {number}
-   */
-  _nodeHeight(node) {
-    let result = node.nodeSelfHeight();
-    if (!node.expanded)
-      return result;
-    const children = this.allChildren(node);
-    for (let i = 0; i < children.length; i++)
-      result += this._nodeHeight(children[i]);
-    return result;
-  }
-
-  /**
-   * @param {!Array<!Profiler.HeapSnapshotGridNode>} pathToReveal
-   * @return {!Promise<!Profiler.HeapSnapshotGridNode>}
-   */
-  revealTreeNode(pathToReveal) {
-    const height = this._calculateOffset(pathToReveal);
-    const node = /** @type {!Profiler.HeapSnapshotGridNode} */ (pathToReveal.peekLast());
-    const scrollTop = this.scrollContainer.scrollTop;
-    const scrollBottom = scrollTop + this.scrollContainer.offsetHeight;
-    if (height >= scrollTop && height < scrollBottom)
-      return Promise.resolve(node);
-
-    const scrollGap = 40;
-    this.scrollContainer.scrollTop = Math.max(0, height - scrollGap);
-    return new Promise(resolve => {
-      console.assert(!this._scrollToResolveCallback);
-      this._scrollToResolveCallback = resolve.bind(null, node);
-      // Still resolve the promise if it does not scroll for some reason.
-      this.scrollContainer.window().requestAnimationFrame(() => {
-        if (!this._scrollToResolveCallback)
-          return;
-        this._scrollToResolveCallback();
-        this._scrollToResolveCallback = null;
-      });
-    });
-  }
-
-  /**
-   * @param {!Array.<!Profiler.HeapSnapshotGridNode>} pathToReveal
-   * @return {number}
-   */
-  _calculateOffset(pathToReveal) {
-    let parentNode = this.rootNode();
-    let height = 0;
-    for (let i = 0; i < pathToReveal.length; ++i) {
-      const node = pathToReveal[i];
-      const children = this.allChildren(parentNode);
-      for (let j = 0; j < children.length; ++j) {
-        const child = children[j];
-        if (node === child) {
-          height += node.nodeSelfHeight();
-          break;
-        }
-        height += this._nodeHeight(child);
-      }
-      parentNode = node;
-    }
-    return height - pathToReveal.peekLast().nodeSelfHeight();
-  }
-
-  /**
-   * @override
-   * @param {!DataGrid.DataGridNode} parent
-   * @return {!Array.<!Profiler.HeapSnapshotGridNode>}
-   */
-  allChildren(parent) {
-    return parent._allChildren || (parent._allChildren = []);
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} parent
-   * @param {!Profiler.HeapSnapshotGridNode} node
-   */
-  appendNode(parent, node) {
-    this.allChildren(parent).push(node);
-  }
-
-  /**
-   * @override
-   * @param {!DataGrid.DataGridNode} parent
-   * @param {!DataGrid.DataGridNode} node
-   * @param {number} index
-   */
-  insertChild(parent, node, index) {
-    this.allChildren(parent).splice(index, 0, /** @type {!Profiler.HeapSnapshotGridNode} */ (node));
-  }
-
-  /**
-   * @override
-   */
-  removeChildByIndex(parent, index) {
-    this.allChildren(parent).splice(index, 1);
-  }
-
-  /**
-   * @override
-   */
-  removeAllChildren(parent) {
-    parent._allChildren = [];
-  }
-
-  removeTopLevelNodes() {
-    this._disposeAllNodes();
-    this.rootNode().removeChildren();
-    this.rootNode()._allChildren = [];
-  }
-
-  /**
-   * @param {!Element} element
-   * @return {boolean}
-   */
-  _isScrolledIntoView(element) {
-    const viewportTop = this.scrollContainer.scrollTop;
-    const viewportBottom = viewportTop + this.scrollContainer.clientHeight;
-    const elemTop = element.offsetTop;
-    const elemBottom = elemTop + element.offsetHeight;
-    return elemBottom <= viewportBottom && elemTop >= viewportTop;
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    super.onResize();
-    this.updateVisibleNodes(false);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onScroll(event) {
-    this.updateVisibleNodes(false);
-
-    if (this._scrollToResolveCallback) {
-      this._scrollToResolveCallback();
-      this._scrollToResolveCallback = null;
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotContainmentDataGrid = class extends Profiler.HeapSnapshotSortableDataGrid {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {!Array.<!DataGrid.DataGrid.ColumnDescriptor>=} columns
-   */
-  constructor(dataDisplayDelegate, columns) {
-    columns =
-        columns || (/** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-          {id: 'object', title: Common.UIString('Object'), disclosure: true, sortable: true},
-          {id: 'distance', title: Common.UIString('Distance'), width: '70px', sortable: true, fixedWidth: true},
-          {id: 'shallowSize', title: Common.UIString('Shallow Size'), width: '110px', sortable: true, fixedWidth: true},
-          {
-            id: 'retainedSize',
-            title: Common.UIString('Retained Size'),
-            width: '110px',
-            sortable: true,
-            fixedWidth: true,
-            sort: DataGrid.DataGrid.Order.Descending
-          }
-        ]));
-    super(dataDisplayDelegate, columns);
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   * @param {number} nodeIndex
-   */
-  setDataSource(snapshot, nodeIndex) {
-    this.snapshot = snapshot;
-    const node = {nodeIndex: nodeIndex || snapshot.rootNodeIndex};
-    const fakeEdge = {node: node};
-    this.setRootNode(this._createRootNode(snapshot, fakeEdge));
-    this.rootNode().sort();
-  }
-
-  _createRootNode(snapshot, fakeEdge) {
-    return new Profiler.HeapSnapshotObjectNode(this, snapshot, fakeEdge, null);
-  }
-
-  /**
-   * @override
-   */
-  sortingChanged() {
-    const rootNode = this.rootNode();
-    if (rootNode.hasChildren())
-      rootNode.sort();
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotRetainmentDataGrid = class extends Profiler.HeapSnapshotContainmentDataGrid {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   */
-  constructor(dataDisplayDelegate) {
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'object', title: Common.UIString('Object'), disclosure: true, sortable: true}, {
-        id: 'distance',
-        title: Common.UIString('Distance'),
-        width: '70px',
-        sortable: true,
-        fixedWidth: true,
-        sort: DataGrid.DataGrid.Order.Ascending
-      },
-      {id: 'shallowSize', title: Common.UIString('Shallow Size'), width: '110px', sortable: true, fixedWidth: true},
-      {id: 'retainedSize', title: Common.UIString('Retained Size'), width: '110px', sortable: true, fixedWidth: true}
-    ]);
-    super(dataDisplayDelegate, columns);
-  }
-
-  /**
-   * @override
-   */
-  _createRootNode(snapshot, fakeEdge) {
-    return new Profiler.HeapSnapshotRetainingObjectNode(this, snapshot, fakeEdge, null);
-  }
-
-  _sortFields(sortColumn, sortAscending) {
-    return {
-      object: ['_name', sortAscending, '_count', false],
-      count: ['_count', sortAscending, '_name', true],
-      shallowSize: ['_shallowSize', sortAscending, '_name', true],
-      retainedSize: ['_retainedSize', sortAscending, '_name', true],
-      distance: ['_distance', sortAscending, '_name', true]
-    }[sortColumn];
-  }
-
-  reset() {
-    this.rootNode().removeChildren();
-    this.resetSortingCache();
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   * @param {number} nodeIndex
-   */
-  setDataSource(snapshot, nodeIndex) {
-    super.setDataSource(snapshot, nodeIndex);
-    this.rootNode().expand();
-  }
-};
-
-/** @enum {symbol} */
-Profiler.HeapSnapshotRetainmentDataGrid.Events = {
-  ExpandRetainersComplete: Symbol('ExpandRetainersComplete')
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotConstructorsDataGrid = class extends Profiler.HeapSnapshotViewportDataGrid {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   */
-  constructor(dataDisplayDelegate) {
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'object', title: Common.UIString('Constructor'), disclosure: true, sortable: true},
-      {id: 'distance', title: Common.UIString('Distance'), width: '70px', sortable: true, fixedWidth: true},
-      {id: 'count', title: Common.UIString('Objects Count'), width: '100px', sortable: true, fixedWidth: true},
-      {id: 'shallowSize', title: Common.UIString('Shallow Size'), width: '110px', sortable: true, fixedWidth: true}, {
-        id: 'retainedSize',
-        title: Common.UIString('Retained Size'),
-        width: '110px',
-        sort: DataGrid.DataGrid.Order.Descending,
-        sortable: true,
-        fixedWidth: true
-      }
-    ]);
-    super(dataDisplayDelegate, columns);
-    this._profileIndex = -1;
-
-    this._objectIdToSelect = null;
-  }
-
-  _sortFields(sortColumn, sortAscending) {
-    return {
-      object: ['_name', sortAscending, '_count', false],
-      distance: ['_distance', sortAscending, '_retainedSize', true],
-      count: ['_count', sortAscending, '_name', true],
-      shallowSize: ['_shallowSize', sortAscending, '_name', true],
-      retainedSize: ['_retainedSize', sortAscending, '_name', true]
-    }[sortColumn];
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} id
-   * @return {!Promise<?Profiler.HeapSnapshotGridNode>}
-   */
-  async revealObjectByHeapSnapshotId(id) {
-    if (!this.snapshot) {
-      this._objectIdToSelect = id;
-      return null;
-    }
-
-    const className = await this.snapshot.nodeClassName(parseInt(id, 10));
-    if (!className)
-      return null;
-
-    const parent = this.topLevelNodes().find(classNode => classNode._name === className);
-    if (!parent)
-      return null;
-
-    const nodes = await parent.populateNodeBySnapshotObjectId(parseInt(id, 10));
-    return nodes.length ? this.revealTreeNode(nodes) : null;
-  }
-
-  clear() {
-    this._nextRequestedFilter = null;
-    this._lastFilter = null;
-    this.removeTopLevelNodes();
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   */
-  setDataSource(snapshot) {
-    this.snapshot = snapshot;
-    if (this._profileIndex === -1)
-      this._populateChildren();
-
-    if (this._objectIdToSelect) {
-      this.revealObjectByHeapSnapshotId(this._objectIdToSelect);
-      this._objectIdToSelect = null;
-    }
-  }
-
-  /**
-   * @param {number} minNodeId
-   * @param {number} maxNodeId
-   */
-  setSelectionRange(minNodeId, maxNodeId) {
-    this._nodeFilter = new HeapSnapshotModel.NodeFilter(minNodeId, maxNodeId);
-    this._populateChildren(this._nodeFilter);
-  }
-
-  /**
-   * @param {number} allocationNodeId
-   */
-  setAllocationNodeId(allocationNodeId) {
-    this._nodeFilter = new HeapSnapshotModel.NodeFilter();
-    this._nodeFilter.allocationNodeId = allocationNodeId;
-    this._populateChildren(this._nodeFilter);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   * @param {!Object<string, !HeapSnapshotModel.Aggregate>} aggregates
-   */
-  _aggregatesReceived(nodeFilter, aggregates) {
-    this._filterInProgress = null;
-    if (this._nextRequestedFilter) {
-      this.snapshot.aggregatesWithFilter(this._nextRequestedFilter)
-          .then(this._aggregatesReceived.bind(this, this._nextRequestedFilter));
-      this._filterInProgress = this._nextRequestedFilter;
-      this._nextRequestedFilter = null;
-    }
-    this.removeTopLevelNodes();
-    this.resetSortingCache();
-    for (const constructor in aggregates) {
-      this.appendNode(
-          this.rootNode(),
-          new Profiler.HeapSnapshotConstructorNode(this, constructor, aggregates[constructor], nodeFilter));
-    }
-    this.sortingChanged();
-    this._lastFilter = nodeFilter;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.NodeFilter=} maybeNodeFilter
-   */
-  async _populateChildren(maybeNodeFilter) {
-    const nodeFilter = maybeNodeFilter || new HeapSnapshotModel.NodeFilter();
-
-    if (this._filterInProgress) {
-      this._nextRequestedFilter = this._filterInProgress.equals(nodeFilter) ? null : nodeFilter;
-      return;
-    }
-    if (this._lastFilter && this._lastFilter.equals(nodeFilter))
-      return;
-    this._filterInProgress = nodeFilter;
-
-    const aggregates = await this.snapshot.aggregatesWithFilter(nodeFilter);
-
-    this._aggregatesReceived(nodeFilter, aggregates);
-  }
-
-  filterSelectIndexChanged(profiles, profileIndex) {
-    this._profileIndex = profileIndex;
-    this._nodeFilter = undefined;
-    if (profileIndex !== -1) {
-      const minNodeId = profileIndex > 0 ? profiles[profileIndex - 1].maxJSObjectId : 0;
-      const maxNodeId = profiles[profileIndex].maxJSObjectId;
-      this._nodeFilter = new HeapSnapshotModel.NodeFilter(minNodeId, maxNodeId);
-    }
-
-    this._populateChildren(this._nodeFilter);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotDiffDataGrid = class extends Profiler.HeapSnapshotViewportDataGrid {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   */
-  constructor(dataDisplayDelegate) {
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'object', title: Common.UIString('Constructor'), disclosure: true, sortable: true},
-      {id: 'addedCount', title: Common.UIString('# New'), width: '75px', sortable: true, fixedWidth: true},
-      {id: 'removedCount', title: Common.UIString('# Deleted'), width: '75px', sortable: true, fixedWidth: true},
-      {id: 'countDelta', title: Common.UIString('# Delta'), width: '65px', sortable: true, fixedWidth: true}, {
-        id: 'addedSize',
-        title: Common.UIString('Alloc. Size'),
-        width: '75px',
-        sortable: true,
-        fixedWidth: true,
-        sort: DataGrid.DataGrid.Order.Descending
-      },
-      {id: 'removedSize', title: Common.UIString('Freed Size'), width: '75px', sortable: true, fixedWidth: true},
-      {id: 'sizeDelta', title: Common.UIString('Size Delta'), width: '75px', sortable: true, fixedWidth: true}
-    ]);
-    super(dataDisplayDelegate, columns);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  defaultPopulateCount() {
-    return 50;
-  }
-
-  _sortFields(sortColumn, sortAscending) {
-    return {
-      object: ['_name', sortAscending, '_count', false],
-      addedCount: ['_addedCount', sortAscending, '_name', true],
-      removedCount: ['_removedCount', sortAscending, '_name', true],
-      countDelta: ['_countDelta', sortAscending, '_name', true],
-      addedSize: ['_addedSize', sortAscending, '_name', true],
-      removedSize: ['_removedSize', sortAscending, '_name', true],
-      sizeDelta: ['_sizeDelta', sortAscending, '_name', true]
-    }[sortColumn];
-  }
-
-  setDataSource(snapshot) {
-    this.snapshot = snapshot;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotProxy} baseSnapshot
-   */
-  setBaseDataSource(baseSnapshot) {
-    this.baseSnapshot = baseSnapshot;
-    this.removeTopLevelNodes();
-    this.resetSortingCache();
-    if (this.baseSnapshot === this.snapshot) {
-      this.dispatchEventToListeners(Profiler.HeapSnapshotSortableDataGrid.Events.SortingComplete);
-      return;
-    }
-    this._populateChildren();
-  }
-
-  async _populateChildren() {
-    // Two snapshots live in different workers isolated from each other. That is why
-    // we first need to collect information about the nodes in the first snapshot and
-    // then pass it to the second snapshot to calclulate the diff.
-    const aggregatesForDiff = await this.baseSnapshot.aggregatesForDiff();
-    const diffByClassName = await this.snapshot.calculateSnapshotDiff(this.baseSnapshot.uid, aggregatesForDiff);
-
-    for (const className in diffByClassName) {
-      const diff = diffByClassName[className];
-      this.appendNode(this.rootNode(), new Profiler.HeapSnapshotDiffNode(this, className, diff));
-    }
-    this.sortingChanged();
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.AllocationDataGrid = class extends Profiler.HeapSnapshotViewportDataGrid {
-  /**
-   * @param {?SDK.HeapProfilerModel} heapProfilerModel
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   */
-  constructor(heapProfilerModel, dataDisplayDelegate) {
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'liveCount', title: Common.UIString('Live Count'), width: '75px', sortable: true, fixedWidth: true},
-      {id: 'count', title: Common.UIString('Count'), width: '65px', sortable: true, fixedWidth: true},
-      {id: 'liveSize', title: Common.UIString('Live Size'), width: '75px', sortable: true, fixedWidth: true},
-      {
-        id: 'size',
-        title: Common.UIString('Size'),
-        width: '75px',
-        sortable: true,
-        fixedWidth: true,
-        sort: DataGrid.DataGrid.Order.Descending
-      },
-      {id: 'name', title: Common.UIString('Function'), disclosure: true, sortable: true},
-    ]);
-    super(dataDisplayDelegate, columns);
-    this._heapProfilerModel = heapProfilerModel;
-    this._linkifier = new Components.Linkifier();
-  }
-
-  /**
-   * @return {?SDK.HeapProfilerModel}
-   */
-  heapProfilerModel() {
-    return this._heapProfilerModel;
-  }
-
-  dispose() {
-    this._linkifier.reset();
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   */
-  async setDataSource(snapshot) {
-    this.snapshot = snapshot;
-    this._topNodes = await this.snapshot.allocationTracesTops();
-    this._populateChildren();
-  }
-
-  _populateChildren() {
-    this.removeTopLevelNodes();
-    const root = this.rootNode();
-    const tops = this._topNodes;
-    for (const top of tops)
-      this.appendNode(root, new Profiler.AllocationGridNode(this, top));
-    this.updateVisibleNodes(true);
-  }
-
-  /**
-   * @override
-   */
-  sortingChanged() {
-    this._topNodes.sort(this._createComparator());
-    this.rootNode().removeChildren();
-    this._populateChildren();
-  }
-
-  /**
-   * @return {function(!Object, !Object):number}
-   */
-  _createComparator() {
-    const fieldName = this.sortColumnId();
-    const compareResult = (this.sortOrder() === DataGrid.DataGrid.Order.Ascending) ? +1 : -1;
-    /**
-     * @param {!Object} a
-     * @param {!Object} b
-     * @return {number}
-     */
-    function compare(a, b) {
-      if (a[fieldName] > b[fieldName])
-        return compareResult;
-      if (a[fieldName] < b[fieldName])
-        return -compareResult;
-      return 0;
-    }
-    return compare;
-  }
-};
diff --git a/front_end/profiler/HeapSnapshotGridNodes.js b/front_end/profiler/HeapSnapshotGridNodes.js
deleted file mode 100644
index 6e454a5..0000000
--- a/front_end/profiler/HeapSnapshotGridNodes.js
+++ /dev/null
@@ -1,1368 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotGridNode = class extends DataGrid.DataGridNode {
-  /**
-   * @param {!Profiler.HeapSnapshotSortableDataGrid} tree
-   * @param {boolean} hasChildren
-   */
-  constructor(tree, hasChildren) {
-    super(null, hasChildren);
-    this._dataGrid = tree;
-    this._instanceCount = 0;
-
-    this._savedChildren = null;
-    /**
-     * List of position ranges for all visible nodes: [startPos1, endPos1),...,[startPosN, endPosN)
-     * Position is an item position in the provider.
-     */
-    this._retrievedChildrenRanges = [];
-
-    /**
-     * @type {?Profiler.HeapSnapshotGridNode.ChildrenProvider}
-     */
-    this._providerObject = null;
-    this._reachableFromWindow = false;
-  }
-
-  /**
-   * @param {!Array.<string>} fieldNames
-   * @return {!HeapSnapshotModel.ComparatorConfig}
-   */
-  static createComparator(fieldNames) {
-    return /** @type {!HeapSnapshotModel.ComparatorConfig} */ (
-        {fieldName1: fieldNames[0], ascending1: fieldNames[1], fieldName2: fieldNames[2], ascending2: fieldNames[3]});
-  }
-
-  /**
-   * @return {!Profiler.HeapSnapshotSortableDataGrid}
-   */
-  heapSnapshotDataGrid() {
-    return this._dataGrid;
-  }
-
-  /**
-   * @return {!Profiler.HeapSnapshotGridNode.ChildrenProvider}
-   */
-  createProvider() {
-    throw new Error('Not implemented.');
-  }
-
-  /**
-   * @return {?{snapshot:!Profiler.HeapSnapshotProxy, snapshotNodeIndex:number}}
-   */
-  retainersDataSource() {
-    return null;
-  }
-
-  /**
-   * @return {!Profiler.HeapSnapshotGridNode.ChildrenProvider}
-   */
-  _provider() {
-    if (!this._providerObject)
-      this._providerObject = this.createProvider();
-    return this._providerObject;
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = super.createCell(columnId);
-    if (this._searchMatched)
-      cell.classList.add('highlight');
-    return cell;
-  }
-
-  /**
-   * @override
-   */
-  collapse() {
-    super.collapse();
-    this._dataGrid.updateVisibleNodes(true);
-  }
-
-  /**
-   * @override
-   */
-  expand() {
-    super.expand();
-    this._dataGrid.updateVisibleNodes(true);
-  }
-
-  dispose() {
-    if (this._providerObject)
-      this._providerObject.dispose();
-    for (let node = this.children[0]; node; node = node.traverseNextNode(true, this, true)) {
-      if (node.dispose)
-        node.dispose();
-    }
-  }
-
-  /**
-   * @param {!SDK.HeapProfilerModel} heapProfilerModel
-   * @param {string} objectGroupName
-   * @return {!Promise<!SDK.RemoteObject>}
-   */
-  queryObjectContent(heapProfilerModel, objectGroupName) {
-  }
-
-  /**
-   * @param {number} num
-   * @return {string}
-   */
-  _toPercentString(num) {
-    return num.toFixed(0) + '\xa0%';  // \xa0 is a non-breaking space.
-  }
-
-  /**
-   * @param {number} distance
-   * @return {string}
-   */
-  _toUIDistance(distance) {
-    const baseSystemDistance = HeapSnapshotModel.baseSystemDistance;
-    return distance >= 0 && distance < baseSystemDistance ? Common.UIString('%d', distance) : Common.UIString('\u2212');
-  }
-
-  /**
-   * @return {!Array.<!DataGrid.DataGridNode>}
-   */
-  allChildren() {
-    return this._dataGrid.allChildren(this);
-  }
-
-  /**
-   * @param {number} index
-   */
-  removeChildByIndex(index) {
-    this._dataGrid.removeChildByIndex(this, index);
-  }
-
-  /**
-   * @param {number} nodePosition
-   * @return {?DataGrid.DataGridNode}
-   */
-  childForPosition(nodePosition) {
-    let indexOfFirstChildInRange = 0;
-    for (let i = 0; i < this._retrievedChildrenRanges.length; i++) {
-      const range = this._retrievedChildrenRanges[i];
-      if (range.from <= nodePosition && nodePosition < range.to) {
-        const childIndex = indexOfFirstChildInRange + nodePosition - range.from;
-        return this.allChildren()[childIndex];
-      }
-      indexOfFirstChildInRange += range.to - range.from + 1;
-    }
-    return null;
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  _createValueCell(columnId) {
-    const cell = createElement('td');
-    cell.className = 'numeric-column';
-    if (this.dataGrid.snapshot.totalSize !== 0) {
-      const div = createElement('div');
-      const valueSpan = createElement('span');
-      valueSpan.textContent = this.data[columnId];
-      div.appendChild(valueSpan);
-      const percentColumn = columnId + '-percent';
-      if (percentColumn in this.data) {
-        const percentSpan = createElement('span');
-        percentSpan.className = 'percent-column';
-        percentSpan.textContent = this.data[percentColumn];
-        div.appendChild(percentSpan);
-        div.classList.add('profile-multiple-values');
-      }
-      cell.appendChild(div);
-    }
-    return cell;
-  }
-
-  /**
-   * @override
-   */
-  populate() {
-    if (this._populated)
-      return;
-    this._populated = true;
-    this._provider().sortAndRewind(this.comparator()).then(() => this._populateChildren());
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  expandWithoutPopulate() {
-    // Make sure default populate won't take action.
-    this._populated = true;
-    this.expand();
-    return this._provider().sortAndRewind(this.comparator());
-  }
-
-  /**
-   * @param {?number=} fromPosition
-   * @param {?number=} toPosition
-   * @return {!Promise}
-   */
-  _populateChildren(fromPosition, toPosition) {
-    let afterPopulate;
-    const promise = new Promise(resolve => afterPopulate = resolve);
-    fromPosition = fromPosition || 0;
-    toPosition = toPosition || fromPosition + this._dataGrid.defaultPopulateCount();
-    let firstNotSerializedPosition = fromPosition;
-    serializeNextChunk.call(this);
-    return promise;
-
-    /**
-     * @this {Profiler.HeapSnapshotGridNode}
-     */
-    function serializeNextChunk() {
-      if (firstNotSerializedPosition >= toPosition)
-        return;
-      const end = Math.min(firstNotSerializedPosition + this._dataGrid.defaultPopulateCount(), toPosition);
-      this._provider().serializeItemsRange(firstNotSerializedPosition, end).then(childrenRetrieved.bind(this));
-      firstNotSerializedPosition = end;
-    }
-
-    /**
-     * @this {Profiler.HeapSnapshotGridNode}
-     */
-    function insertRetrievedChild(item, insertionIndex) {
-      if (this._savedChildren) {
-        const hash = this._childHashForEntity(item);
-        if (hash in this._savedChildren) {
-          this._dataGrid.insertChild(this, this._savedChildren[hash], insertionIndex);
-          return;
-        }
-      }
-      this._dataGrid.insertChild(this, this._createChildNode(item), insertionIndex);
-    }
-
-    /**
-     * @this {Profiler.HeapSnapshotGridNode}
-     */
-    function insertShowMoreButton(from, to, insertionIndex) {
-      const button = new DataGrid.ShowMoreDataGridNode(
-          this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount());
-      this._dataGrid.insertChild(this, button, insertionIndex);
-    }
-
-    /**
-     * @param {!HeapSnapshotModel.ItemsRange} itemsRange
-     * @this {Profiler.HeapSnapshotGridNode}
-     */
-    function childrenRetrieved(itemsRange) {
-      let itemIndex = 0;
-      let itemPosition = itemsRange.startPosition;
-      const items = itemsRange.items;
-      let insertionIndex = 0;
-
-      if (!this._retrievedChildrenRanges.length) {
-        if (itemsRange.startPosition > 0) {
-          this._retrievedChildrenRanges.push({from: 0, to: 0});
-          insertShowMoreButton.call(this, 0, itemsRange.startPosition, insertionIndex++);
-        }
-        this._retrievedChildrenRanges.push({from: itemsRange.startPosition, to: itemsRange.endPosition});
-        for (let i = 0, l = items.length; i < l; ++i)
-          insertRetrievedChild.call(this, items[i], insertionIndex++);
-        if (itemsRange.endPosition < itemsRange.totalLength)
-          insertShowMoreButton.call(this, itemsRange.endPosition, itemsRange.totalLength, insertionIndex++);
-      } else {
-        let rangeIndex = 0;
-        let found = false;
-        let range;
-        while (rangeIndex < this._retrievedChildrenRanges.length) {
-          range = this._retrievedChildrenRanges[rangeIndex];
-          if (range.to >= itemPosition) {
-            found = true;
-            break;
-          }
-          insertionIndex += range.to - range.from;
-          // Skip the button if there is one.
-          if (range.to < itemsRange.totalLength)
-            insertionIndex += 1;
-          ++rangeIndex;
-        }
-
-        if (!found || itemsRange.startPosition < range.from) {
-          // Update previous button.
-          this.allChildren()[insertionIndex - 1].setEndPosition(itemsRange.startPosition);
-          insertShowMoreButton.call(
-              this, itemsRange.startPosition, found ? range.from : itemsRange.totalLength, insertionIndex);
-          range = {from: itemsRange.startPosition, to: itemsRange.startPosition};
-          if (!found)
-            rangeIndex = this._retrievedChildrenRanges.length;
-          this._retrievedChildrenRanges.splice(rangeIndex, 0, range);
-        } else {
-          insertionIndex += itemPosition - range.from;
-        }
-        // At this point insertionIndex is always an index before button or between nodes.
-        // Also it is always true here that range.from <= itemPosition <= range.to
-
-        // Stretch the range right bound to include all new items.
-        while (range.to < itemsRange.endPosition) {
-          // Skip already added nodes.
-          const skipCount = range.to - itemPosition;
-          insertionIndex += skipCount;
-          itemIndex += skipCount;
-          itemPosition = range.to;
-
-          // We're at the position before button: ...<?node>x<button>
-          const nextRange = this._retrievedChildrenRanges[rangeIndex + 1];
-          let newEndOfRange = nextRange ? nextRange.from : itemsRange.totalLength;
-          if (newEndOfRange > itemsRange.endPosition)
-            newEndOfRange = itemsRange.endPosition;
-          while (itemPosition < newEndOfRange) {
-            insertRetrievedChild.call(this, items[itemIndex++], insertionIndex++);
-            ++itemPosition;
-          }
-
-          // Merge with the next range.
-          if (nextRange && newEndOfRange === nextRange.from) {
-            range.to = nextRange.to;
-            // Remove "show next" button if there is one.
-            this.removeChildByIndex(insertionIndex);
-            this._retrievedChildrenRanges.splice(rangeIndex + 1, 1);
-          } else {
-            range.to = newEndOfRange;
-            // Remove or update next button.
-            if (newEndOfRange === itemsRange.totalLength)
-              this.removeChildByIndex(insertionIndex);
-            else
-              this.allChildren()[insertionIndex].setStartPosition(itemsRange.endPosition);
-          }
-        }
-      }
-
-      // TODO: fix this.
-      this._instanceCount += items.length;
-      if (firstNotSerializedPosition < toPosition) {
-        serializeNextChunk.call(this);
-        return;
-      }
-
-      if (this.expanded)
-        this._dataGrid.updateVisibleNodes(true);
-      afterPopulate();
-      this.dispatchEventToListeners(Profiler.HeapSnapshotGridNode.Events.PopulateComplete);
-    }
-  }
-
-  _saveChildren() {
-    this._savedChildren = null;
-    const children = this.allChildren();
-    for (let i = 0, l = children.length; i < l; ++i) {
-      const child = children[i];
-      if (!child.expanded)
-        continue;
-      if (!this._savedChildren)
-        this._savedChildren = {};
-      this._savedChildren[this._childHashForNode(child)] = child;
-    }
-  }
-
-  async sort() {
-    this._dataGrid.recursiveSortingEnter();
-
-    await this._provider().sortAndRewind(this.comparator());
-
-    this._saveChildren();
-    this._dataGrid.removeAllChildren(this);
-    this._retrievedChildrenRanges = [];
-    const instanceCount = this._instanceCount;
-    this._instanceCount = 0;
-
-    await this._populateChildren(0, instanceCount);
-
-    for (const child of this.allChildren()) {
-      if (child.expanded)
-        child.sort();
-    }
-    this._dataGrid.recursiveSortingLeave();
-  }
-};
-
-/** @enum {symbol} */
-Profiler.HeapSnapshotGridNode.Events = {
-  PopulateComplete: Symbol('PopulateComplete')
-};
-
-/**
- * @interface
- */
-Profiler.HeapSnapshotGridNode.ChildrenProvider = function() {};
-
-Profiler.HeapSnapshotGridNode.ChildrenProvider.prototype = {
-  dispose() {},
-
-  /**
-   * @param {number} snapshotObjectId
-   * @return {!Promise<number>}
-   */
-  nodePosition(snapshotObjectId) {},
-
-  /**
-   * @return {!Promise<boolean>}
-   */
-  isEmpty() {},
-
-  /**
-   * @param {number} startPosition
-   * @param {number} endPosition
-   * @return {!Promise<!HeapSnapshotModel.ItemsRange>}
-   */
-  serializeItemsRange(startPosition, endPosition) {},
-
-  /**
-   * @param {!HeapSnapshotModel.ComparatorConfig} comparator
-   * @return {!Promise<?>}
-   */
-  sortAndRewind(comparator) {}
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotGenericObjectNode = class extends Profiler.HeapSnapshotGridNode {
-  /**
-   * @param {!Profiler.HeapSnapshotSortableDataGrid} dataGrid
-   * @param {!HeapSnapshotModel.Node} node
-   */
-  constructor(dataGrid, node) {
-    super(dataGrid, false);
-    // node is null for DataGrid root nodes.
-    if (!node)
-      return;
-    this._name = node.name;
-    this._type = node.type;
-    this._distance = node.distance;
-    this._shallowSize = node.selfSize;
-    this._retainedSize = node.retainedSize;
-    this.snapshotNodeId = node.id;
-    this.snapshotNodeIndex = node.nodeIndex;
-    if (this._type === 'string') {
-      this._reachableFromWindow = true;
-    } else if (this._type === 'object' && this._name.startsWith('Window')) {
-      this._name = this.shortenWindowURL(this._name, false);
-      this._reachableFromWindow = true;
-    } else if (node.canBeQueried) {
-      this._reachableFromWindow = true;
-    }
-    if (node.detachedDOMTreeNode)
-      this.detachedDOMTreeNode = true;
-
-    const snapshot = dataGrid.snapshot;
-    const shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
-    const retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
-    this.data = {
-      'distance': this._toUIDistance(this._distance),
-      'shallowSize': Number.withThousandsSeparator(this._shallowSize),
-      'retainedSize': Number.withThousandsSeparator(this._retainedSize),
-      'shallowSize-percent': this._toPercentString(shallowSizePercent),
-      'retainedSize-percent': this._toPercentString(retainedSizePercent)
-    };
-  }
-
-  /**
-   * @override
-   * @return {?{snapshot:!Profiler.HeapSnapshotProxy, snapshotNodeIndex:number}}
-   */
-  retainersDataSource() {
-    return {snapshot: this._dataGrid.snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = columnId !== 'object' ? this._createValueCell(columnId) : this._createObjectCell();
-    if (this._searchMatched)
-      cell.classList.add('highlight');
-    return cell;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _createObjectCell() {
-    let value = this._name;
-    let valueStyle = 'object';
-    switch (this._type) {
-      case 'concatenated string':
-      case 'string':
-        value = '"' + value + '"';
-        valueStyle = 'string';
-        break;
-      case 'regexp':
-        value = '/' + value + '/';
-        valueStyle = 'string';
-        break;
-      case 'closure':
-        value = value + '()';
-        valueStyle = 'function';
-        break;
-      case 'bigint':
-        valueStyle = 'bigint';
-        break;
-      case 'number':
-        valueStyle = 'number';
-        break;
-      case 'hidden':
-        valueStyle = 'null';
-        break;
-      case 'array':
-        value = (value || '') + '[]';
-        break;
-    }
-    if (this._reachableFromWindow && !this.detachedDOMTreeNode)
-      valueStyle += ' highlight';
-    if (value === 'Object')
-      value = '';
-    if (this.detachedDOMTreeNode)
-      valueStyle += ' detached-dom-tree-node';
-    return this._createObjectCellWithValue(valueStyle, value);
-  }
-
-  _createObjectCellWithValue(valueStyle, value) {
-    const cell = createElement('td');
-    cell.className = 'object-column';
-    const div = createElement('div');
-    div.className = 'source-code event-properties';
-    div.style.overflow = 'visible';
-
-    this._prefixObjectCell(div);
-
-    const valueSpan = createElement('span');
-    valueSpan.className = 'value object-value-' + valueStyle;
-    valueSpan.textContent = value;
-    div.appendChild(valueSpan);
-
-    const idSpan = createElement('span');
-    idSpan.className = 'object-value-id';
-    idSpan.textContent = ' @' + this.snapshotNodeId;
-    div.appendChild(idSpan);
-
-    cell.appendChild(div);
-    cell.classList.add('disclosure');
-    if (this.depth)
-      cell.style.setProperty('padding-left', (this.depth * this.dataGrid.indentWidth) + 'px');
-    cell.heapSnapshotNode = this;
-    return cell;
-  }
-
-  _prefixObjectCell(div) {
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} heapProfilerModel
-   * @param {string} objectGroupName
-   * @return {!Promise<!SDK.RemoteObject>}
-   */
-  queryObjectContent(heapProfilerModel, objectGroupName) {
-    let fulfill;
-    const promise = new Promise(x => fulfill = x);
-
-    /**
-     * @param {?SDK.RemoteObject} object
-     */
-    function onResult(object) {
-      fulfill(object || runtimeModel.createRemoteObjectFromPrimitiveValue(Common.UIString('Preview is not available')));
-    }
-
-    const runtimeModel = heapProfilerModel.runtimeModel();
-    if (this._type === 'string')
-      onResult(runtimeModel.createRemoteObjectFromPrimitiveValue(this._name));
-    else if (!heapProfilerModel || !runtimeModel)
-      onResult(null);
-    else
-      heapProfilerModel.objectForSnapshotObjectId(String(this.snapshotNodeId), objectGroupName).then(onResult);
-    return promise;
-  }
-
-  async updateHasChildren() {
-    const isEmpty = await this._provider().isEmpty();
-    this.setHasChildren(!isEmpty);
-  }
-
-  /**
-   * @param {string} fullName
-   * @param {boolean} hasObjectId
-   * @return {string}
-   */
-  shortenWindowURL(fullName, hasObjectId) {
-    const startPos = fullName.indexOf('/');
-    const endPos = hasObjectId ? fullName.indexOf('@') : fullName.length;
-    if (startPos === -1 || endPos === -1)
-      return fullName;
-    const fullURL = fullName.substring(startPos + 1, endPos).trimLeft();
-    let url = fullURL.trimURL();
-    if (url.length > 40)
-      url = url.trimMiddle(40);
-    return fullName.substr(0, startPos + 2) + url + fullName.substr(endPos);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotObjectNode = class extends Profiler.HeapSnapshotGenericObjectNode {
-  /**
-   * @param {!Profiler.HeapSnapshotSortableDataGrid} dataGrid
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   * @param {!HeapSnapshotModel.Edge} edge
-   * @param {?Profiler.HeapSnapshotObjectNode} parentObjectNode
-   */
-  constructor(dataGrid, snapshot, edge, parentObjectNode) {
-    super(dataGrid, edge.node);
-    this._referenceName = edge.name;
-    this._referenceType = edge.type;
-    this._edgeIndex = edge.edgeIndex;
-    this._snapshot = snapshot;
-
-    this._parentObjectNode = parentObjectNode;
-    this._cycledWithAncestorGridNode = this._findAncestorWithSameSnapshotNodeId();
-    if (!this._cycledWithAncestorGridNode)
-      this.updateHasChildren();
-
-    const data = this.data;
-    data['count'] = '';
-    data['addedCount'] = '';
-    data['removedCount'] = '';
-    data['countDelta'] = '';
-    data['addedSize'] = '';
-    data['removedSize'] = '';
-    data['sizeDelta'] = '';
-  }
-
-  /**
-   * @override
-   * @return {?{snapshot:!Profiler.HeapSnapshotProxy, snapshotNodeIndex:number}}
-   */
-  retainersDataSource() {
-    return {snapshot: this._snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.HeapSnapshotProviderProxy}
-   */
-  createProvider() {
-    return this._snapshot.createEdgesProvider(this.snapshotNodeIndex);
-  }
-
-  _findAncestorWithSameSnapshotNodeId() {
-    let ancestor = this._parentObjectNode;
-    while (ancestor) {
-      if (ancestor.snapshotNodeId === this.snapshotNodeId)
-        return ancestor;
-      ancestor = ancestor._parentObjectNode;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Edge} item
-   * @return {!Profiler.HeapSnapshotObjectNode}
-   */
-  _createChildNode(item) {
-    return new Profiler.HeapSnapshotObjectNode(this._dataGrid, this._snapshot, item, this);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Edge} edge
-   * @return {number}
-   */
-  _childHashForEntity(edge) {
-    return edge.edgeIndex;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotObjectNode} childNode
-   * @return {number}
-   */
-  _childHashForNode(childNode) {
-    return childNode._edgeIndex;
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.ComparatorConfig}
-   */
-  comparator() {
-    const sortAscending = this._dataGrid.isSortOrderAscending();
-    const sortColumnId = this._dataGrid.sortColumnId();
-    const sortFields = {
-      object: ['!edgeName', sortAscending, 'retainedSize', false],
-      count: ['!edgeName', true, 'retainedSize', false],
-      shallowSize: ['selfSize', sortAscending, '!edgeName', true],
-      retainedSize: ['retainedSize', sortAscending, '!edgeName', true],
-      distance: ['distance', sortAscending, '_name', true]
-    }[sortColumnId] ||
-        ['!edgeName', true, 'retainedSize', false];
-    return Profiler.HeapSnapshotGridNode.createComparator(sortFields);
-  }
-
-  /**
-   * @override
-   */
-  _prefixObjectCell(div) {
-    let name = this._referenceName || '(empty)';
-    let nameClass = 'name';
-    switch (this._referenceType) {
-      case 'context':
-        nameClass = 'object-value-number';
-        break;
-      case 'internal':
-      case 'hidden':
-      case 'weak':
-        nameClass = 'object-value-null';
-        break;
-      case 'element':
-        name = '[' + name + ']';
-        break;
-    }
-
-    if (this._cycledWithAncestorGridNode)
-      div.className += ' cycled-ancessor-node';
-
-    const nameSpan = createElement('span');
-    nameSpan.className = nameClass;
-    nameSpan.textContent = name;
-    div.appendChild(nameSpan);
-
-    const separatorSpan = createElement('span');
-    separatorSpan.className = 'grayed';
-    separatorSpan.textContent = this._edgeNodeSeparator();
-    div.appendChild(separatorSpan);
-  }
-
-  /**
-   * @return {string}
-   */
-  _edgeNodeSeparator() {
-    return ' :: ';
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotRetainingObjectNode = class extends Profiler.HeapSnapshotObjectNode {
-  /**
-   * @param {!Profiler.HeapSnapshotSortableDataGrid} dataGrid
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   * @param {!HeapSnapshotModel.Edge} edge
-   * @param {?Profiler.HeapSnapshotRetainingObjectNode} parentRetainingObjectNode
-   */
-  constructor(dataGrid, snapshot, edge, parentRetainingObjectNode) {
-    super(dataGrid, snapshot, edge, parentRetainingObjectNode);
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.HeapSnapshotProviderProxy}
-   */
-  createProvider() {
-    return this._snapshot.createRetainingEdgesProvider(this.snapshotNodeIndex);
-  }
-
-  /**
-   * @override
-   * @param {!HeapSnapshotModel.Edge} item
-   * @return {!Profiler.HeapSnapshotRetainingObjectNode}
-   */
-  _createChildNode(item) {
-    return new Profiler.HeapSnapshotRetainingObjectNode(this._dataGrid, this._snapshot, item, this);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  _edgeNodeSeparator() {
-    return ' in ';
-  }
-
-  /**
-   * @override
-   */
-  expand() {
-    this._expandRetainersChain(20);
-  }
-
-  /**
-   * @param {number} maxExpandLevels
-   */
-  _expandRetainersChain(maxExpandLevels) {
-    if (!this._populated) {
-      this.once(Profiler.HeapSnapshotGridNode.Events.PopulateComplete)
-          .then(() => this._expandRetainersChain(maxExpandLevels));
-      this.populate();
-      return;
-    }
-    super.expand();
-    if (--maxExpandLevels > 0 && this.children.length > 0) {
-      const retainer = this.children[0];
-      if (retainer._distance > 1) {
-        retainer._expandRetainersChain(maxExpandLevels);
-        return;
-      }
-    }
-    this._dataGrid.dispatchEventToListeners(Profiler.HeapSnapshotRetainmentDataGrid.Events.ExpandRetainersComplete);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotInstanceNode = class extends Profiler.HeapSnapshotGenericObjectNode {
-  /**
-   * @param {!Profiler.HeapSnapshotSortableDataGrid} dataGrid
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   * @param {!HeapSnapshotModel.Node} node
-   * @param {boolean} isDeletedNode
-   */
-  constructor(dataGrid, snapshot, node, isDeletedNode) {
-    super(dataGrid, node);
-    this._baseSnapshotOrSnapshot = snapshot;
-    this._isDeletedNode = isDeletedNode;
-    this.updateHasChildren();
-
-    const data = this.data;
-    data['count'] = '';
-    data['countDelta'] = '';
-    data['sizeDelta'] = '';
-    if (this._isDeletedNode) {
-      data['addedCount'] = '';
-      data['addedSize'] = '';
-      data['removedCount'] = '\u2022';
-      data['removedSize'] = Number.withThousandsSeparator(this._shallowSize);
-    } else {
-      data['addedCount'] = '\u2022';
-      data['addedSize'] = Number.withThousandsSeparator(this._shallowSize);
-      data['removedCount'] = '';
-      data['removedSize'] = '';
-    }
-  }
-
-  /**
-   * @override
-   * @return {?{snapshot:!Profiler.HeapSnapshotProxy, snapshotNodeIndex:number}}
-   */
-  retainersDataSource() {
-    return {snapshot: this._baseSnapshotOrSnapshot, snapshotNodeIndex: this.snapshotNodeIndex};
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.HeapSnapshotProviderProxy}
-   */
-  createProvider() {
-    return this._baseSnapshotOrSnapshot.createEdgesProvider(this.snapshotNodeIndex);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Edge} item
-   * @return {!Profiler.HeapSnapshotObjectNode}
-   */
-  _createChildNode(item) {
-    return new Profiler.HeapSnapshotObjectNode(this._dataGrid, this._baseSnapshotOrSnapshot, item, null);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Edge} edge
-   * @return {number}
-   */
-  _childHashForEntity(edge) {
-    return edge.edgeIndex;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotObjectNode} childNode
-   * @return {number}
-   */
-  _childHashForNode(childNode) {
-    return childNode._edgeIndex;
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.ComparatorConfig}
-   */
-  comparator() {
-    const sortAscending = this._dataGrid.isSortOrderAscending();
-    const sortColumnId = this._dataGrid.sortColumnId();
-    const sortFields = {
-      object: ['!edgeName', sortAscending, 'retainedSize', false],
-      distance: ['distance', sortAscending, 'retainedSize', false],
-      count: ['!edgeName', true, 'retainedSize', false],
-      addedSize: ['selfSize', sortAscending, '!edgeName', true],
-      removedSize: ['selfSize', sortAscending, '!edgeName', true],
-      shallowSize: ['selfSize', sortAscending, '!edgeName', true],
-      retainedSize: ['retainedSize', sortAscending, '!edgeName', true]
-    }[sortColumnId] ||
-        ['!edgeName', true, 'retainedSize', false];
-    return Profiler.HeapSnapshotGridNode.createComparator(sortFields);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotConstructorNode = class extends Profiler.HeapSnapshotGridNode {
-  /**
-   * @param {!Profiler.HeapSnapshotConstructorsDataGrid} dataGrid
-   * @param {string} className
-   * @param {!HeapSnapshotModel.Aggregate} aggregate
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   */
-  constructor(dataGrid, className, aggregate, nodeFilter) {
-    super(dataGrid, aggregate.count > 0);
-    this._name = className;
-    this._nodeFilter = nodeFilter;
-    this._distance = aggregate.distance;
-    this._count = aggregate.count;
-    this._shallowSize = aggregate.self;
-    this._retainedSize = aggregate.maxRet;
-
-    const snapshot = dataGrid.snapshot;
-    const countPercent = this._count / snapshot.nodeCount * 100.0;
-    const retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
-    const shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
-
-    this.data = {
-      'object': className,
-      'count': Number.withThousandsSeparator(this._count),
-      'distance': this._toUIDistance(this._distance),
-      'shallowSize': Number.withThousandsSeparator(this._shallowSize),
-      'retainedSize': Number.withThousandsSeparator(this._retainedSize),
-      'count-percent': this._toPercentString(countPercent),
-      'shallowSize-percent': this._toPercentString(shallowSizePercent),
-      'retainedSize-percent': this._toPercentString(retainedSizePercent)
-    };
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.HeapSnapshotProviderProxy}
-   */
-  createProvider() {
-    return this._dataGrid.snapshot.createNodesProviderForClass(this._name, this._nodeFilter);
-  }
-
-  /**
-   * @param {number} snapshotObjectId
-   * @return {!Promise<!Array<!Profiler.HeapSnapshotGridNode>>}
-   */
-  async populateNodeBySnapshotObjectId(snapshotObjectId) {
-    this._dataGrid.resetNameFilter();
-    await this.expandWithoutPopulate();
-
-    const nodePosition = await this._provider().nodePosition(snapshotObjectId);
-    if (nodePosition === -1) {
-      this.collapse();
-      return [];
-    }
-
-    await this._populateChildren(nodePosition, null);
-
-    const node = /** @type {?Profiler.HeapSnapshotGridNode} */ (this.childForPosition(nodePosition));
-    return node ? [this, node] : [];
-  }
-
-  /**
-   * @param {string} filterValue
-   * @return {boolean}
-   */
-  filteredOut(filterValue) {
-    return this._name.toLowerCase().indexOf(filterValue) === -1;
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = columnId !== 'object' ? this._createValueCell(columnId) : super.createCell(columnId);
-    if (this._searchMatched)
-      cell.classList.add('highlight');
-    return cell;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Node} item
-   * @return {!Profiler.HeapSnapshotInstanceNode}
-   */
-  _createChildNode(item) {
-    return new Profiler.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.ComparatorConfig}
-   */
-  comparator() {
-    const sortAscending = this._dataGrid.isSortOrderAscending();
-    const sortColumnId = this._dataGrid.sortColumnId();
-    const sortFields = {
-      object: ['name', sortAscending, 'id', true],
-      distance: ['distance', sortAscending, 'retainedSize', false],
-      count: ['name', true, 'id', true],
-      shallowSize: ['selfSize', sortAscending, 'id', true],
-      retainedSize: ['retainedSize', sortAscending, 'id', true]
-    }[sortColumnId];
-    return Profiler.HeapSnapshotGridNode.createComparator(sortFields);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Node} node
-   * @return {number}
-   */
-  _childHashForEntity(node) {
-    return node.id;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotInstanceNode} childNode
-   * @return {number}
-   */
-  _childHashForNode(childNode) {
-    return childNode.snapshotNodeId;
-  }
-};
-
-/**
- * @implements {Profiler.HeapSnapshotGridNode.ChildrenProvider}
- * @unrestricted
- */
-Profiler.HeapSnapshotDiffNodesProvider = class {
-  /**
-   * @param {!Profiler.HeapSnapshotProviderProxy} addedNodesProvider
-   * @param {!Profiler.HeapSnapshotProviderProxy} deletedNodesProvider
-   * @param {number} addedCount
-   * @param {number} removedCount
-   */
-  constructor(addedNodesProvider, deletedNodesProvider, addedCount, removedCount) {
-    this._addedNodesProvider = addedNodesProvider;
-    this._deletedNodesProvider = deletedNodesProvider;
-    this._addedCount = addedCount;
-    this._removedCount = removedCount;
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this._addedNodesProvider.dispose();
-    this._deletedNodesProvider.dispose();
-  }
-
-  /**
-   * @override
-   * @param {number} snapshotObjectId
-   * @return {!Promise<number>}
-   */
-  nodePosition(snapshotObjectId) {
-    throw new Error('Unreachable');
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  isEmpty() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @param {number} beginPosition
-   * @param {number} endPosition
-   * @return {!Promise<!HeapSnapshotModel.ItemsRange>}
-   */
-  async serializeItemsRange(beginPosition, endPosition) {
-    let itemsRange;
-    let addedItems;
-    if (beginPosition < this._addedCount) {
-      itemsRange = await this._addedNodesProvider.serializeItemsRange(beginPosition, endPosition);
-
-      for (const item of itemsRange.items)
-        item.isAddedNotRemoved = true;
-
-      if (itemsRange.endPosition >= endPosition) {
-        itemsRange.totalLength = this._addedCount + this._removedCount;
-        return itemsRange;
-      }
-
-      addedItems = itemsRange;
-      itemsRange = await this._deletedNodesProvider.serializeItemsRange(0, endPosition - itemsRange.endPosition);
-    } else {
-      addedItems = new HeapSnapshotModel.ItemsRange(0, 0, 0, []);
-      itemsRange = await this._deletedNodesProvider.serializeItemsRange(
-          beginPosition - this._addedCount, endPosition - this._addedCount);
-    }
-
-    if (!addedItems.items.length)
-      addedItems.startPosition = this._addedCount + itemsRange.startPosition;
-    for (const item of itemsRange.items)
-      item.isAddedNotRemoved = false;
-    addedItems.items.pushAll(itemsRange.items);
-    addedItems.endPosition = this._addedCount + itemsRange.endPosition;
-    addedItems.totalLength = this._addedCount + this._removedCount;
-    return addedItems;
-  }
-
-  /**
-   * @override
-   * @param {!HeapSnapshotModel.ComparatorConfig} comparator
-   * @return {!Promise}
-   */
-  async sortAndRewind(comparator) {
-    await this._addedNodesProvider.sortAndRewind(comparator);
-    await this._deletedNodesProvider.sortAndRewind(comparator);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotDiffNode = class extends Profiler.HeapSnapshotGridNode {
-  /**
-   * @param {!Profiler.HeapSnapshotDiffDataGrid} dataGrid
-   * @param {string} className
-   * @param {!HeapSnapshotModel.DiffForClass} diffForClass
-   */
-  constructor(dataGrid, className, diffForClass) {
-    super(dataGrid, true);
-    this._name = className;
-    this._addedCount = diffForClass.addedCount;
-    this._removedCount = diffForClass.removedCount;
-    this._countDelta = diffForClass.countDelta;
-    this._addedSize = diffForClass.addedSize;
-    this._removedSize = diffForClass.removedSize;
-    this._sizeDelta = diffForClass.sizeDelta;
-    this._deletedIndexes = diffForClass.deletedIndexes;
-    this.data = {
-      'object': className,
-      'addedCount': Number.withThousandsSeparator(this._addedCount),
-      'removedCount': Number.withThousandsSeparator(this._removedCount),
-      'countDelta': this._signForDelta(this._countDelta) + Number.withThousandsSeparator(Math.abs(this._countDelta)),
-      'addedSize': Number.withThousandsSeparator(this._addedSize),
-      'removedSize': Number.withThousandsSeparator(this._removedSize),
-      'sizeDelta': this._signForDelta(this._sizeDelta) + Number.withThousandsSeparator(Math.abs(this._sizeDelta))
-    };
-  }
-
-  /**
-   * @override
-   * @return {!Profiler.HeapSnapshotDiffNodesProvider}
-   */
-  createProvider() {
-    const tree = this._dataGrid;
-    return new Profiler.HeapSnapshotDiffNodesProvider(
-        tree.snapshot.createAddedNodesProvider(tree.baseSnapshot.uid, this._name),
-        tree.baseSnapshot.createDeletedNodesProvider(this._deletedIndexes), this._addedCount, this._removedCount);
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = super.createCell(columnId);
-    if (columnId !== 'object')
-      cell.classList.add('numeric-column');
-    return cell;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Node} item
-   * @return {!Profiler.HeapSnapshotInstanceNode}
-   */
-  _createChildNode(item) {
-    if (item.isAddedNotRemoved)
-      return new Profiler.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
-    else
-      return new Profiler.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.baseSnapshot, item, true);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.Node} node
-   * @return {number}
-   */
-  _childHashForEntity(node) {
-    return node.id;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotInstanceNode} childNode
-   * @return {number}
-   */
-  _childHashForNode(childNode) {
-    return childNode.snapshotNodeId;
-  }
-
-  /**
-   * @return {!HeapSnapshotModel.ComparatorConfig}
-   */
-  comparator() {
-    const sortAscending = this._dataGrid.isSortOrderAscending();
-    const sortColumnId = this._dataGrid.sortColumnId();
-    const sortFields = {
-      object: ['name', sortAscending, 'id', true],
-      addedCount: ['name', true, 'id', true],
-      removedCount: ['name', true, 'id', true],
-      countDelta: ['name', true, 'id', true],
-      addedSize: ['selfSize', sortAscending, 'id', true],
-      removedSize: ['selfSize', sortAscending, 'id', true],
-      sizeDelta: ['selfSize', sortAscending, 'id', true]
-    }[sortColumnId];
-    return Profiler.HeapSnapshotGridNode.createComparator(sortFields);
-  }
-
-  /**
-   * @param {string} filterValue
-   * @return {boolean}
-   */
-  filteredOut(filterValue) {
-    return this._name.toLowerCase().indexOf(filterValue) === -1;
-  }
-
-  _signForDelta(delta) {
-    if (delta === 0)
-      return '';
-    if (delta > 0)
-      return '+';
-    else
-      return '\u2212';  // Math minus sign, same width as plus.
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.AllocationGridNode = class extends Profiler.HeapSnapshotGridNode {
-  /**
-   * @param {!Profiler.AllocationDataGrid} dataGrid
-   * @param {!HeapSnapshotModel.SerializedAllocationNode} data
-   */
-  constructor(dataGrid, data) {
-    super(dataGrid, data.hasChildren);
-    this._populated = false;
-    this._allocationNode = data;
-    this.data = {
-      'liveCount': Number.withThousandsSeparator(data.liveCount),
-      'count': Number.withThousandsSeparator(data.count),
-      'liveSize': Number.withThousandsSeparator(data.liveSize),
-      'size': Number.withThousandsSeparator(data.size),
-      'name': data.name
-    };
-  }
-
-  /**
-   * @override
-   */
-  populate() {
-    if (this._populated)
-      return;
-    this._doPopulate();
-  }
-
-  async _doPopulate() {
-    this._populated = true;
-
-    const callers = await this._dataGrid.snapshot.allocationNodeCallers(this._allocationNode.id);
-
-    const callersChain = callers.nodesWithSingleCaller;
-    let parentNode = this;
-    const dataGrid = /** @type {!Profiler.AllocationDataGrid} */ (this._dataGrid);
-    for (const caller of callersChain) {
-      const child = new Profiler.AllocationGridNode(dataGrid, caller);
-      dataGrid.appendNode(parentNode, child);
-      parentNode = child;
-      parentNode._populated = true;
-      if (this.expanded)
-        parentNode.expand();
-    }
-
-    const callersBranch = callers.branchingCallers;
-    callersBranch.sort(this._dataGrid._createComparator());
-    for (const caller of callersBranch)
-      dataGrid.appendNode(parentNode, new Profiler.AllocationGridNode(dataGrid, caller));
-    dataGrid.updateVisibleNodes(true);
-  }
-
-  /**
-   * @override
-   */
-  expand() {
-    super.expand();
-    if (this.children.length === 1)
-      this.children[0].expand();
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    if (columnId !== 'name')
-      return this._createValueCell(columnId);
-
-    const cell = super.createCell(columnId);
-    const allocationNode = this._allocationNode;
-    const heapProfilerModel = this._dataGrid.heapProfilerModel();
-    if (allocationNode.scriptId) {
-      const linkifier = this._dataGrid._linkifier;
-      const urlElement = linkifier.linkifyScriptLocation(
-          heapProfilerModel ? heapProfilerModel.target() : null, String(allocationNode.scriptId),
-          allocationNode.scriptName, allocationNode.line - 1, allocationNode.column - 1, 'profile-node-file');
-      urlElement.style.maxWidth = '75%';
-      cell.insertBefore(urlElement, cell.firstChild);
-    }
-    return cell;
-  }
-
-  /**
-   * @return {number}
-   */
-  allocationNodeId() {
-    return this._allocationNode.id;
-  }
-};
diff --git a/front_end/profiler/HeapSnapshotProxy.js b/front_end/profiler/HeapSnapshotProxy.js
deleted file mode 100644
index 98c2f67..0000000
--- a/front_end/profiler/HeapSnapshotProxy.js
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyrightdd
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotWorkerProxy = class extends Common.Object {
-  /**
-   * @param {function(string, *)} eventHandler
-   */
-  constructor(eventHandler) {
-    super();
-    this._eventHandler = eventHandler;
-    this._nextObjectId = 1;
-    this._nextCallId = 1;
-    /** @type {!Map<number, function(*)>} */
-    this._callbacks = new Map();
-    /** @type {!Set<number>} */
-    this._previousCallbacks = new Set();
-    this._worker = new Common.Worker('heap_snapshot_worker');
-    this._worker.onmessage = this._messageReceived.bind(this);
-  }
-
-  /**
-   * @param {number} profileUid
-   * @param {function(!Profiler.HeapSnapshotProxy)} snapshotReceivedCallback
-   * @return {!Profiler.HeapSnapshotLoaderProxy}
-   */
-  createLoader(profileUid, snapshotReceivedCallback) {
-    const objectId = this._nextObjectId++;
-    const proxy = new Profiler.HeapSnapshotLoaderProxy(this, objectId, profileUid, snapshotReceivedCallback);
-    this._postMessage({
-      callId: this._nextCallId++,
-      disposition: 'create',
-      objectId: objectId,
-      methodName: 'HeapSnapshotWorker.HeapSnapshotLoader'
-    });
-    return proxy;
-  }
-
-  dispose() {
-    this._worker.terminate();
-    if (this._interval)
-      clearInterval(this._interval);
-  }
-
-  disposeObject(objectId) {
-    this._postMessage({callId: this._nextCallId++, disposition: 'dispose', objectId: objectId});
-  }
-
-  evaluateForTest(script, callback) {
-    const callId = this._nextCallId++;
-    this._callbacks.set(callId, callback);
-    this._postMessage({callId: callId, disposition: 'evaluateForTest', source: script});
-  }
-
-  /**
-   * @param {?function(...?)} callback
-   * @param {string} objectId
-   * @param {string} methodName
-   * @param {function(new:T, ...?)} proxyConstructor
-   * @return {?Object}
-   * @template T
-   */
-  callFactoryMethod(callback, objectId, methodName, proxyConstructor) {
-    const callId = this._nextCallId++;
-    const methodArguments = Array.prototype.slice.call(arguments, 4);
-    const newObjectId = this._nextObjectId++;
-
-    /**
-     * @this {Profiler.HeapSnapshotWorkerProxy}
-     */
-    function wrapCallback(remoteResult) {
-      callback(remoteResult ? new proxyConstructor(this, newObjectId) : null);
-    }
-
-    if (callback) {
-      this._callbacks.set(callId, wrapCallback.bind(this));
-      this._postMessage({
-        callId: callId,
-        disposition: 'factory',
-        objectId: objectId,
-        methodName: methodName,
-        methodArguments: methodArguments,
-        newObjectId: newObjectId
-      });
-      return null;
-    } else {
-      this._postMessage({
-        callId: callId,
-        disposition: 'factory',
-        objectId: objectId,
-        methodName: methodName,
-        methodArguments: methodArguments,
-        newObjectId: newObjectId
-      });
-      return new proxyConstructor(this, newObjectId);
-    }
-  }
-
-  /**
-   * @param {function(*)} callback
-   * @param {string} objectId
-   * @param {string} methodName
-   */
-  callMethod(callback, objectId, methodName) {
-    const callId = this._nextCallId++;
-    const methodArguments = Array.prototype.slice.call(arguments, 3);
-    if (callback)
-      this._callbacks.set(callId, callback);
-    this._postMessage({
-      callId: callId,
-      disposition: 'method',
-      objectId: objectId,
-      methodName: methodName,
-      methodArguments: methodArguments
-    });
-  }
-
-  startCheckingForLongRunningCalls() {
-    if (this._interval)
-      return;
-    this._checkLongRunningCalls();
-    this._interval = setInterval(this._checkLongRunningCalls.bind(this), 300);
-  }
-
-  _checkLongRunningCalls() {
-    for (const callId of this._previousCallbacks) {
-      if (!this._callbacks.has(callId))
-        this._previousCallbacks.delete(callId);
-    }
-    const hasLongRunningCalls = !!this._previousCallbacks.size;
-    this.dispatchEventToListeners(Profiler.HeapSnapshotWorkerProxy.Events.Wait, hasLongRunningCalls);
-    for (const callId of this._callbacks.keysArray())
-      this._previousCallbacks.add(callId);
-  }
-
-  /**
-   * @param {!MessageEvent} event
-   */
-  _messageReceived(event) {
-    const data = event.data;
-    if (data.eventName) {
-      if (this._eventHandler)
-        this._eventHandler(data.eventName, data.data);
-      return;
-    }
-    if (data.error) {
-      if (data.errorMethodName) {
-        Common.console.error(
-            Common.UIString('An error occurred when a call to method \'%s\' was requested', data.errorMethodName));
-      }
-      Common.console.error(data['errorCallStack']);
-      this._callbacks.delete(data.callId);
-      return;
-    }
-    if (!this._callbacks.has(data.callId))
-      return;
-    const callback = this._callbacks.get(data.callId);
-    this._callbacks.delete(data.callId);
-    callback(data.result);
-  }
-
-  _postMessage(message) {
-    this._worker.postMessage(message);
-  }
-};
-
-Profiler.HeapSnapshotWorkerProxy.Events = {
-  Wait: Symbol('Wait')
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotProxyObject = class {
-  /**
-   * @param {!Profiler.HeapSnapshotWorkerProxy} worker
-   * @param {number} objectId
-   */
-  constructor(worker, objectId) {
-    this._worker = worker;
-    this._objectId = objectId;
-  }
-
-  /**
-   * @param {string} workerMethodName
-   * @param {!Array.<*>} args
-   */
-  _callWorker(workerMethodName, args) {
-    args.splice(1, 0, this._objectId);
-    return this._worker[workerMethodName].apply(this._worker, args);
-  }
-
-  dispose() {
-    this._worker.disposeObject(this._objectId);
-  }
-
-  disposeWorker() {
-    this._worker.dispose();
-  }
-
-  /**
-   * @param {?function(...?)} callback
-   * @param {string} methodName
-   * @param {function (new:T, ...?)} proxyConstructor
-   * @param {...*} var_args
-   * @return {!T}
-   * @template T
-   */
-  callFactoryMethod(callback, methodName, proxyConstructor, var_args) {
-    return this._callWorker('callFactoryMethod', Array.prototype.slice.call(arguments, 0));
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {...*} var_args
-   * @return {!Promise.<?T>}
-   * @template T
-   */
-  _callMethodPromise(methodName, var_args) {
-    const args = Array.prototype.slice.call(arguments);
-    return new Promise(resolve => this._callWorker('callMethod', [resolve, ...args]));
-  }
-};
-
-/**
- * @implements {Common.OutputStream}
- * @unrestricted
- */
-Profiler.HeapSnapshotLoaderProxy = class extends Profiler.HeapSnapshotProxyObject {
-  /**
-   * @param {!Profiler.HeapSnapshotWorkerProxy} worker
-   * @param {number} objectId
-   * @param {number} profileUid
-   * @param {function(!Profiler.HeapSnapshotProxy)} snapshotReceivedCallback
-   */
-  constructor(worker, objectId, profileUid, snapshotReceivedCallback) {
-    super(worker, objectId);
-    this._profileUid = profileUid;
-    this._snapshotReceivedCallback = snapshotReceivedCallback;
-  }
-
-  /**
-   * @override
-   * @param {string} chunk
-   * @return {!Promise}
-   */
-  write(chunk) {
-    return this._callMethodPromise('write', chunk);
-  }
-
-  /**
-   * @override
-   */
-  async close() {
-    await this._callMethodPromise('close');
-    const snapshotProxy =
-        await new Promise(resolve => this.callFactoryMethod(resolve, 'buildSnapshot', Profiler.HeapSnapshotProxy));
-    this.dispose();
-    snapshotProxy.setProfileUid(this._profileUid);
-    await snapshotProxy.updateStaticData();
-    this._snapshotReceivedCallback(snapshotProxy);
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotProxy = class extends Profiler.HeapSnapshotProxyObject {
-  /**
-   * @param {!Profiler.HeapSnapshotWorkerProxy} worker
-   * @param {number} objectId
-   */
-  constructor(worker, objectId) {
-    super(worker, objectId);
-    /** @type {?HeapSnapshotModel.StaticData} */
-    this._staticData = null;
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.SearchConfig} searchConfig
-   * @param {!HeapSnapshotModel.NodeFilter} filter
-   * @return {!Promise<!Array<number>>}
-   */
-  search(searchConfig, filter) {
-    return this._callMethodPromise('search', searchConfig, filter);
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.NodeFilter} filter
-   * @return {!Promise<!Object<string, !HeapSnapshotModel.Aggregate>>}
-   */
-  aggregatesWithFilter(filter) {
-    return this._callMethodPromise('aggregatesWithFilter', filter);
-  }
-
-  /**
-   * @return {!Promise<!Object.<string, !HeapSnapshotModel.AggregateForDiff>>}
-   */
-  aggregatesForDiff() {
-    return this._callMethodPromise('aggregatesForDiff');
-  }
-
-  /**
-   * @param {string} baseSnapshotId
-   * @param {!Object<string, !HeapSnapshotModel.AggregateForDiff>} baseSnapshotAggregates
-   * @return {!Promise<!Object<string, !HeapSnapshotModel.Diff>>}
-   */
-  calculateSnapshotDiff(baseSnapshotId, baseSnapshotAggregates) {
-    return this._callMethodPromise('calculateSnapshotDiff', baseSnapshotId, baseSnapshotAggregates);
-  }
-
-  /**
-   * @param {number} snapshotObjectId
-   * @return {!Promise<?string>}
-   */
-  nodeClassName(snapshotObjectId) {
-    return this._callMethodPromise('nodeClassName', snapshotObjectId);
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {!Profiler.HeapSnapshotProviderProxy}
-   */
-  createEdgesProvider(nodeIndex) {
-    return this.callFactoryMethod(null, 'createEdgesProvider', Profiler.HeapSnapshotProviderProxy, nodeIndex);
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {!Profiler.HeapSnapshotProviderProxy}
-   */
-  createRetainingEdgesProvider(nodeIndex) {
-    return this.callFactoryMethod(null, 'createRetainingEdgesProvider', Profiler.HeapSnapshotProviderProxy, nodeIndex);
-  }
-
-  /**
-   * @param {string} baseSnapshotId
-   * @param {string} className
-   * @return {?Profiler.HeapSnapshotProviderProxy}
-   */
-  createAddedNodesProvider(baseSnapshotId, className) {
-    return this.callFactoryMethod(
-        null, 'createAddedNodesProvider', Profiler.HeapSnapshotProviderProxy, baseSnapshotId, className);
-  }
-
-  /**
-   * @param {!Array.<number>} nodeIndexes
-   * @return {?Profiler.HeapSnapshotProviderProxy}
-   */
-  createDeletedNodesProvider(nodeIndexes) {
-    return this.callFactoryMethod(null, 'createDeletedNodesProvider', Profiler.HeapSnapshotProviderProxy, nodeIndexes);
-  }
-
-  /**
-   * @param {function(*):boolean} filter
-   * @return {?Profiler.HeapSnapshotProviderProxy}
-   */
-  createNodesProvider(filter) {
-    return this.callFactoryMethod(null, 'createNodesProvider', Profiler.HeapSnapshotProviderProxy, filter);
-  }
-
-  /**
-   * @param {string} className
-   * @param {!HeapSnapshotModel.NodeFilter} nodeFilter
-   * @return {?Profiler.HeapSnapshotProviderProxy}
-   */
-  createNodesProviderForClass(className, nodeFilter) {
-    return this.callFactoryMethod(
-        null, 'createNodesProviderForClass', Profiler.HeapSnapshotProviderProxy, className, nodeFilter);
-  }
-
-  /**
-   * @return {!Promise<!Array<!HeapSnapshotModel.SerializedAllocationNode>>}
-   */
-  allocationTracesTops() {
-    return this._callMethodPromise('allocationTracesTops');
-  }
-
-  /**
-   * @param {number} nodeId
-   * @return {!Promise<!HeapSnapshotModel.AllocationNodeCallers>}
-   */
-  allocationNodeCallers(nodeId) {
-    return this._callMethodPromise('allocationNodeCallers', nodeId);
-  }
-
-  /**
-   * @param {number} nodeIndex
-   * @return {!Promise<?Array<!HeapSnapshotModel.AllocationStackFrame>>}
-   */
-  allocationStack(nodeIndex) {
-    return this._callMethodPromise('allocationStack', nodeIndex);
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    throw new Error('Should never be called');
-  }
-
-  get nodeCount() {
-    return this._staticData.nodeCount;
-  }
-
-  get rootNodeIndex() {
-    return this._staticData.rootNodeIndex;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async updateStaticData() {
-    this._staticData = await this._callMethodPromise('updateStaticData');
-  }
-
-  /**
-   * @return {!Promise<!HeapSnapshotModel.Statistics>}
-   */
-  getStatistics() {
-    return this._callMethodPromise('getStatistics');
-  }
-
-  /**
-   * @return {!Promise.<?HeapSnapshotModel.Samples>}
-   */
-  getSamples() {
-    return this._callMethodPromise('getSamples');
-  }
-
-  get totalSize() {
-    return this._staticData.totalSize;
-  }
-
-  get uid() {
-    return this._profileUid;
-  }
-
-  setProfileUid(profileUid) {
-    this._profileUid = profileUid;
-  }
-
-  /**
-   * @return {number}
-   */
-  maxJSObjectId() {
-    return this._staticData.maxJSObjectId;
-  }
-};
-
-/**
- * @implements {Profiler.HeapSnapshotGridNode.ChildrenProvider}
- * @unrestricted
- */
-Profiler.HeapSnapshotProviderProxy = class extends Profiler.HeapSnapshotProxyObject {
-  /**
-   * @param {!Profiler.HeapSnapshotWorkerProxy} worker
-   * @param {number} objectId
-   */
-  constructor(worker, objectId) {
-    super(worker, objectId);
-  }
-
-  /**
-   * @override
-   * @param {number} snapshotObjectId
-   * @return {!Promise<number>}
-   */
-  nodePosition(snapshotObjectId) {
-    return this._callMethodPromise('nodePosition', snapshotObjectId);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  isEmpty() {
-    return this._callMethodPromise('isEmpty');
-  }
-
-  /**
-   * @override
-   * @param {number} startPosition
-   * @param {number} endPosition
-   * @return {!Promise<!HeapSnapshotModel.ItemsRange>}
-   */
-  serializeItemsRange(startPosition, endPosition) {
-    return this._callMethodPromise('serializeItemsRange', startPosition, endPosition);
-  }
-
-  /**
-   * @override
-   * @param {!HeapSnapshotModel.ComparatorConfig} comparator
-   * @return {!Promise}
-   */
-  sortAndRewind(comparator) {
-    return this._callMethodPromise('sortAndRewind', comparator);
-  }
-};
diff --git a/front_end/profiler/HeapSnapshotView.js b/front_end/profiler/HeapSnapshotView.js
deleted file mode 100644
index 1f4d6b8..0000000
--- a/front_end/profiler/HeapSnapshotView.js
+++ /dev/null
@@ -1,2007 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Profiler.ProfileType.DataDisplayDelegate}
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Profiler.HeapSnapshotView = class extends UI.SimpleView {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {!Profiler.HeapProfileHeader} profile
-   */
-  constructor(dataDisplayDelegate, profile) {
-    super(Common.UIString('Heap Snapshot'));
-
-    this.element.classList.add('heap-snapshot-view');
-    this._profile = profile;
-
-    profile.profileType().addEventListener(
-        Profiler.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
-    profile.profileType().addEventListener(
-        Profiler.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
-
-    const isHeapTimeline = profile.profileType().id === Profiler.TrackingHeapSnapshotProfileType.TypeId;
-    if (isHeapTimeline) {
-      this._trackingOverviewGrid = new Profiler.HeapTrackingOverviewGrid(profile);
-      this._trackingOverviewGrid.addEventListener(
-          Profiler.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
-    }
-
-    this._parentDataDisplayDelegate = dataDisplayDelegate;
-
-    this._searchableView = new UI.SearchableView(this);
-    this._searchableView.show(this.element);
-
-    this._splitWidget = new UI.SplitWidget(false, true, 'heapSnapshotSplitViewState', 200, 200);
-    this._splitWidget.show(this._searchableView.element);
-
-    this._containmentDataGrid = new Profiler.HeapSnapshotContainmentDataGrid(this);
-    this._containmentDataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-    this._containmentWidget = this._containmentDataGrid.asWidget();
-    this._containmentWidget.setMinimumSize(50, 25);
-
-    this._statisticsView = new Profiler.HeapSnapshotStatisticsView();
-
-    this._constructorsDataGrid = new Profiler.HeapSnapshotConstructorsDataGrid(this);
-    this._constructorsDataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-    this._constructorsWidget = this._constructorsDataGrid.asWidget();
-    this._constructorsWidget.setMinimumSize(50, 25);
-
-    this._diffDataGrid = new Profiler.HeapSnapshotDiffDataGrid(this);
-    this._diffDataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-    this._diffWidget = this._diffDataGrid.asWidget();
-    this._diffWidget.setMinimumSize(50, 25);
-
-    if (isHeapTimeline) {
-      this._allocationDataGrid = new Profiler.AllocationDataGrid(profile._heapProfilerModel, this);
-      this._allocationDataGrid.addEventListener(
-          DataGrid.DataGrid.Events.SelectedNode, this._onSelectAllocationNode, this);
-      this._allocationWidget = this._allocationDataGrid.asWidget();
-      this._allocationWidget.setMinimumSize(50, 25);
-
-      this._allocationStackView = new Profiler.HeapAllocationStackView(profile._heapProfilerModel);
-      this._allocationStackView.setMinimumSize(50, 25);
-
-      this._tabbedPane = new UI.TabbedPane();
-    }
-
-    this._retainmentDataGrid = new Profiler.HeapSnapshotRetainmentDataGrid(this);
-    this._retainmentWidget = this._retainmentDataGrid.asWidget();
-    this._retainmentWidget.setMinimumSize(50, 21);
-    this._retainmentWidget.element.classList.add('retaining-paths-view');
-
-    let splitWidgetResizer;
-    if (this._allocationStackView) {
-      this._tabbedPane = new UI.TabbedPane();
-
-      this._tabbedPane.appendTab('retainers', Common.UIString('Retainers'), this._retainmentWidget);
-      this._tabbedPane.appendTab('allocation-stack', Common.UIString('Allocation stack'), this._allocationStackView);
-
-      splitWidgetResizer = this._tabbedPane.headerElement();
-      this._objectDetailsView = this._tabbedPane;
-    } else {
-      const retainmentViewHeader = createElementWithClass('div', 'heap-snapshot-view-resizer');
-      const retainingPathsTitleDiv = retainmentViewHeader.createChild('div', 'title');
-      const retainingPathsTitle = retainingPathsTitleDiv.createChild('span');
-      retainingPathsTitle.textContent = Common.UIString('Retainers');
-
-      splitWidgetResizer = retainmentViewHeader;
-      this._objectDetailsView = new UI.VBox();
-      this._objectDetailsView.element.appendChild(retainmentViewHeader);
-      this._retainmentWidget.show(this._objectDetailsView.element);
-    }
-    this._splitWidget.hideDefaultResizer();
-    this._splitWidget.installResizer(splitWidgetResizer);
-
-    this._retainmentDataGrid.addEventListener(
-        DataGrid.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this);
-    this._retainmentDataGrid.reset();
-
-    this._perspectives = [];
-    this._comparisonPerspective = new Profiler.HeapSnapshotView.ComparisonPerspective();
-    this._perspectives.push(new Profiler.HeapSnapshotView.SummaryPerspective());
-    if (profile.profileType() !== Profiler.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
-      this._perspectives.push(this._comparisonPerspective);
-    this._perspectives.push(new Profiler.HeapSnapshotView.ContainmentPerspective());
-    if (this._allocationWidget)
-      this._perspectives.push(new Profiler.HeapSnapshotView.AllocationPerspective());
-    this._perspectives.push(new Profiler.HeapSnapshotView.StatisticsPerspective());
-
-    this._perspectiveSelect = new UI.ToolbarComboBox(this._onSelectedPerspectiveChanged.bind(this));
-    this._updatePerspectiveOptions();
-
-    this._baseSelect = new UI.ToolbarComboBox(this._changeBase.bind(this));
-    this._baseSelect.setVisible(false);
-    this._updateBaseOptions();
-
-    this._filterSelect = new UI.ToolbarComboBox(this._changeFilter.bind(this));
-    this._filterSelect.setVisible(false);
-    this._updateFilterOptions();
-
-    this._classNameFilter = new UI.ToolbarInput('Class filter');
-    this._classNameFilter.setVisible(false);
-    this._constructorsDataGrid.setNameFilter(this._classNameFilter);
-    this._diffDataGrid.setNameFilter(this._classNameFilter);
-
-    this._selectedSizeText = new UI.ToolbarText();
-
-    this._popoverHelper = new UI.PopoverHelper(this.element, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setDisableOnClick(true);
-    this._popoverHelper.setHasPadding(true);
-    this.element.addEventListener('scroll', this._popoverHelper.hidePopover.bind(this._popoverHelper), true);
-
-    this._currentPerspectiveIndex = 0;
-    this._currentPerspective = this._perspectives[0];
-    this._currentPerspective.activate(this);
-    this._dataGrid = this._currentPerspective.masterGrid(this);
-
-    this._populate();
-    this._searchThrottler = new Common.Throttler(0);
-
-    this.element.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-
-    for (const existingProfile of this._profiles())
-      existingProfile.addEventListener(Profiler.ProfileHeader.Events.ProfileTitleChanged, this._updateControls, this);
-  }
-
-  /**
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  /**
-   * @override
-   * @param {?Profiler.ProfileHeader} profile
-   * @return {?UI.Widget}
-   */
-  showProfile(profile) {
-    return this._parentDataDisplayDelegate.showProfile(profile);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
-   * @param {string} perspectiveName
-   */
-  showObject(snapshotObjectId, perspectiveName) {
-    if (snapshotObjectId <= this._profile.maxJSObjectId)
-      this.selectLiveObject(perspectiveName, snapshotObjectId);
-    else
-      this._parentDataDisplayDelegate.showObject(snapshotObjectId, perspectiveName);
-  }
-
-  async _populate() {
-    const heapSnapshotProxy = await this._profile._loadPromise;
-
-    this._retrieveStatistics(heapSnapshotProxy);
-    this._dataGrid.setDataSource(heapSnapshotProxy);
-
-    if (this._profile.profileType().id === Profiler.TrackingHeapSnapshotProfileType.TypeId &&
-        this._profile.fromFile()) {
-      const samples = await heapSnapshotProxy.getSamples();
-      this._trackingOverviewGrid._setSamples(samples);
-    }
-
-    const list = this._profiles();
-    const profileIndex = list.indexOf(this._profile);
-    this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1));
-    if (this._trackingOverviewGrid)
-      this._trackingOverviewGrid._updateGrid();
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotProxy} heapSnapshotProxy
-   * @return {!Promise<!HeapSnapshotModel.Statistics>}
-   */
-  async _retrieveStatistics(heapSnapshotProxy) {
-    const statistics = await heapSnapshotProxy.getStatistics();
-    this._statisticsView.setTotal(statistics.total);
-    this._statisticsView.addRecord(statistics.code, Common.UIString('Code'), '#f77');
-    this._statisticsView.addRecord(statistics.strings, Common.UIString('Strings'), '#5e5');
-    this._statisticsView.addRecord(statistics.jsArrays, Common.UIString('JS Arrays'), '#7af');
-    this._statisticsView.addRecord(statistics.native, Common.UIString('Typed Arrays'), '#fc5');
-    this._statisticsView.addRecord(statistics.system, Common.UIString('System Objects'), '#98f');
-    this._statisticsView.addRecord(statistics.total, Common.UIString('Total'));
-    return statistics;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onIdsRangeChanged(event) {
-    const minId = event.data.minId;
-    const maxId = event.data.maxId;
-    this._selectedSizeText.setText(Common.UIString('Selected size: %s', Number.bytesToString(event.data.size)));
-    if (this._constructorsDataGrid.snapshot)
-      this._constructorsDataGrid.setSelectionRange(minId, maxId);
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    const result = [this._perspectiveSelect, this._classNameFilter];
-    if (this._profile.profileType() !== Profiler.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
-      result.push(this._baseSelect, this._filterSelect);
-    result.push(this._selectedSizeText);
-    return result;
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._currentSearchResultIndex = -1;
-    this._popoverHelper.hidePopover();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._currentSearchResultIndex = -1;
-    this._searchResults = [];
-  }
-
-  /**
-   * @param {?Profiler.HeapSnapshotGridNode} node
-   */
-  _selectRevealedNode(node) {
-    if (node)
-      node.select();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    if (this._dataGrid)
-      this._dataGrid.populateContextMenu(contextMenu, event);
-    contextMenu.show();
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    const nextQuery = new HeapSnapshotModel.SearchConfig(
-        searchConfig.query.trim(), searchConfig.caseSensitive, searchConfig.isRegex, shouldJump,
-        jumpBackwards || false);
-
-    this._searchThrottler.schedule(this._performSearch.bind(this, nextQuery));
-  }
-
-  /**
-   * @param {!HeapSnapshotModel.SearchConfig} nextQuery
-   * @return {!Promise}
-   */
-  async _performSearch(nextQuery) {
-    // Call searchCanceled since it will reset everything we need before doing a new search.
-    this.searchCanceled();
-
-    if (!this._currentPerspective.supportsSearch())
-      return;
-
-    this.currentQuery = nextQuery;
-    const query = nextQuery.query.trim();
-
-    if (!query)
-      return;
-
-    if (query.charAt(0) === '@') {
-      const snapshotNodeId = parseInt(query.substring(1), 10);
-      if (isNaN(snapshotNodeId))
-        return;
-      const node = await this._dataGrid.revealObjectByHeapSnapshotId(String(snapshotNodeId));
-      this._selectRevealedNode(node);
-      return;
-    }
-
-    this._searchResults = await this._profile._snapshotProxy.search(this.currentQuery, this._dataGrid.nodeFilter());
-
-    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-    if (this._searchResults.length)
-      this._currentSearchResultIndex = nextQuery.jumpBackwards ? this._searchResults.length - 1 : 0;
-    await this._jumpToSearchResult(this._currentSearchResultIndex);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._searchResults.length)
-      return;
-    this._currentSearchResultIndex = (this._currentSearchResultIndex + 1) % this._searchResults.length;
-    this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex));
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._searchResults.length)
-      return;
-    this._currentSearchResultIndex =
-        (this._currentSearchResultIndex + this._searchResults.length - 1) % this._searchResults.length;
-    this._searchThrottler.schedule(this._jumpToSearchResult.bind(this, this._currentSearchResultIndex));
-  }
-
-  /**
-   * @param {number} searchResultIndex
-   * @return {!Promise}
-   */
-  async _jumpToSearchResult(searchResultIndex) {
-    this._searchableView.updateCurrentMatchIndex(searchResultIndex);
-    if (searchResultIndex === -1)
-      return;
-    const node = await this._dataGrid.revealObjectByHeapSnapshotId(String(this._searchResults[searchResultIndex]));
-    this._selectRevealedNode(node);
-  }
-
-  refreshVisibleData() {
-    if (!this._dataGrid)
-      return;
-    let child = this._dataGrid.rootNode().children[0];
-    while (child) {
-      child.refresh();
-      child = child.traverseNextNode(false, null, true);
-    }
-  }
-
-  _changeBase() {
-    if (this._baseProfile === this._profiles()[this._baseSelect.selectedIndex()])
-      return;
-
-    this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
-    const dataGrid = /** @type {!Profiler.HeapSnapshotDiffDataGrid} */ (this._dataGrid);
-    // Change set base data source only if main data source is already set.
-    if (dataGrid.snapshot)
-      this._baseProfile._loadPromise.then(dataGrid.setBaseDataSource.bind(dataGrid));
-
-    if (!this.currentQuery || !this._searchResults)
-      return;
-
-    // The current search needs to be performed again. First negate out previous match
-    // count by calling the search finished callback with a negative number of matches.
-    // Then perform the search again with the same query and callback.
-    this.performSearch(this.currentQuery, false);
-  }
-
-  _changeFilter() {
-    const profileIndex = this._filterSelect.selectedIndex() - 1;
-    this._dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex);
-
-    if (!this.currentQuery || !this._searchResults)
-      return;
-
-    // The current search needs to be performed again. First negate out previous match
-    // count by calling the search finished callback with a negative number of matches.
-    // Then perform the search again with the same query and callback.
-    this.performSearch(this.currentQuery, false);
-  }
-
-  /**
-   * @return {!Array.<!Profiler.ProfileHeader>}
-   */
-  _profiles() {
-    return this._profile.profileType().getProfiles();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _selectionChanged(event) {
-    const selectedNode = /** @type {!Profiler.HeapSnapshotGridNode} */ (event.data);
-    this._setSelectedNodeForDetailsView(selectedNode);
-    this._inspectedObjectChanged(event);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onSelectAllocationNode(event) {
-    const selectedNode = /** @type {!DataGrid.DataGridNode} */ (event.data);
-    this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
-    this._setSelectedNodeForDetailsView(null);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _inspectedObjectChanged(event) {
-    const selectedNode = /** @type {!DataGrid.DataGridNode} */ (event.data);
-    if (this._profile._heapProfilerModel && selectedNode instanceof Profiler.HeapSnapshotGenericObjectNode)
-      this._profile._heapProfilerModel.addInspectedHeapObject(String(selectedNode.snapshotNodeId));
-  }
-
-  /**
-   * @param {?Profiler.HeapSnapshotGridNode} nodeItem
-   */
-  _setSelectedNodeForDetailsView(nodeItem) {
-    const dataSource = nodeItem && nodeItem.retainersDataSource();
-    if (dataSource) {
-      this._retainmentDataGrid.setDataSource(dataSource.snapshot, dataSource.snapshotNodeIndex);
-      if (this._allocationStackView)
-        this._allocationStackView.setAllocatedObject(dataSource.snapshot, dataSource.snapshotNodeIndex);
-    } else {
-      if (this._allocationStackView)
-        this._allocationStackView.clear();
-      this._retainmentDataGrid.reset();
-    }
-  }
-
-  /**
-   * @param {string} perspectiveTitle
-   * @return {!Promise}
-   */
-  _changePerspectiveAndWait(perspectiveTitle) {
-    const perspectiveIndex = this._perspectives.findIndex(perspective => perspective.title() === perspectiveTitle);
-    if (perspectiveIndex === -1 || this._currentPerspectiveIndex === perspectiveIndex)
-      return Promise.resolve();
-
-    const promise = this._perspectives[perspectiveIndex].masterGrid(this).once(
-        Profiler.HeapSnapshotSortableDataGrid.Events.ContentShown);
-
-    const option = this._perspectiveSelect.options().find(option => option.value === perspectiveIndex);
-    this._perspectiveSelect.select(/** @type {!Element} */ (option));
-    this._changePerspective(perspectiveIndex);
-    return promise;
-  }
-
-  async _updateDataSourceAndView() {
-    const dataGrid = this._dataGrid;
-    if (!dataGrid || dataGrid.snapshot)
-      return;
-
-    const snapshotProxy = await this._profile._loadPromise;
-
-    if (this._dataGrid !== dataGrid)
-      return;
-    if (dataGrid.snapshot !== snapshotProxy)
-      dataGrid.setDataSource(snapshotProxy);
-    if (dataGrid !== this._diffDataGrid)
-      return;
-    if (!this._baseProfile)
-      this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
-
-    const baseSnapshotProxy = await this._baseProfile._loadPromise;
-
-    if (this._diffDataGrid.baseSnapshot !== baseSnapshotProxy)
-      this._diffDataGrid.setBaseDataSource(baseSnapshotProxy);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onSelectedPerspectiveChanged(event) {
-    this._changePerspective(event.target.selectedOptions[0].value);
-  }
-
-  /**
-   * @param {number} selectedIndex
-   */
-  _changePerspective(selectedIndex) {
-    if (selectedIndex === this._currentPerspectiveIndex)
-      return;
-
-    this._currentPerspectiveIndex = selectedIndex;
-
-    this._currentPerspective.deactivate(this);
-    const perspective = this._perspectives[selectedIndex];
-    this._currentPerspective = perspective;
-    this._dataGrid = perspective.masterGrid(this);
-    perspective.activate(this);
-
-    this.refreshVisibleData();
-    if (this._dataGrid)
-      this._dataGrid.updateWidths();
-
-    this._updateDataSourceAndView();
-
-    if (!this.currentQuery || !this._searchResults)
-      return;
-
-    // The current search needs to be performed again. First negate out previous match
-    // count by calling the search finished callback with a negative number of matches.
-    // Then perform the search again the with same query and callback.
-    this.performSearch(this.currentQuery, false);
-  }
-
-  /**
-   * @param {string} perspectiveName
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
-   */
-  async selectLiveObject(perspectiveName, snapshotObjectId) {
-    await this._changePerspectiveAndWait(perspectiveName);
-    const node = await this._dataGrid.revealObjectByHeapSnapshotId(snapshotObjectId);
-    if (node)
-      node.select();
-    else
-      Common.console.error('Cannot find corresponding heap snapshot node');
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    const span = event.target.enclosingNodeOrSelfWithNodeName('span');
-    const row = event.target.enclosingNodeOrSelfWithNodeName('tr');
-    const heapProfilerModel = this._profile._heapProfilerModel;
-    if (!row || !span || !heapProfilerModel)
-      return null;
-    const node = row._dataGridNode;
-    let objectPopoverHelper;
-    return {
-      box: span.boxInWindow(),
-      show: async popover => {
-        const remoteObject = await node.queryObjectContent(heapProfilerModel, 'popover');
-        if (!remoteObject)
-          return false;
-        objectPopoverHelper = await ObjectUI.ObjectPopoverHelper.buildObjectPopover(remoteObject, popover);
-        if (!objectPopoverHelper) {
-          heapProfilerModel.runtimeModel().releaseObjectGroup('popover');
-          return false;
-        }
-        return true;
-      },
-      hide: () => {
-        heapProfilerModel.runtimeModel().releaseObjectGroup('popover');
-        objectPopoverHelper.dispose();
-      }
-    };
-  }
-
-  _updatePerspectiveOptions() {
-    const multipleSnapshots = this._profiles().length > 1;
-    this._perspectiveSelect.removeOptions();
-    this._perspectives.forEach((perspective, index) => {
-      if (multipleSnapshots || perspective !== this._comparisonPerspective)
-        this._perspectiveSelect.createOption(perspective.title(), '', String(index));
-    });
-  }
-
-  _updateBaseOptions() {
-    const list = this._profiles();
-    const selectedIndex = this._baseSelect.selectedIndex();
-
-    this._baseSelect.removeOptions();
-    for (const item of list)
-      this._baseSelect.createOption(item.title);
-
-    if (selectedIndex > -1)
-      this._baseSelect.setSelectedIndex(selectedIndex);
-  }
-
-  _updateFilterOptions() {
-    const list = this._profiles();
-    const selectedIndex = this._filterSelect.selectedIndex();
-
-    this._filterSelect.removeOptions();
-    this._filterSelect.createOption(Common.UIString('All objects'));
-    for (let i = 0; i < list.length; ++i) {
-      let title;
-      if (!i)
-        title = Common.UIString('Objects allocated before %s', list[i].title);
-      else
-        title = Common.UIString('Objects allocated between %s and %s', list[i - 1].title, list[i].title);
-      this._filterSelect.createOption(title);
-    }
-
-    if (selectedIndex > -1)
-      this._filterSelect.setSelectedIndex(selectedIndex);
-  }
-
-  _updateControls() {
-    this._updatePerspectiveOptions();
-    this._updateBaseOptions();
-    this._updateFilterOptions();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onReceiveSnapshot(event) {
-    this._updateControls();
-    const profile = event.data;
-    profile.addEventListener(Profiler.ProfileHeader.Events.ProfileTitleChanged, this._updateControls, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onProfileHeaderRemoved(event) {
-    const profile = event.data;
-    profile.removeEventListener(Profiler.ProfileHeader.Events.ProfileTitleChanged, this._updateControls, this);
-
-    if (this._profile === profile) {
-      this.detach();
-      this._profile.profileType().removeEventListener(
-          Profiler.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
-      this._profile.profileType().removeEventListener(
-          Profiler.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
-      this.dispose();
-    } else {
-      this._updateControls();
-    }
-  }
-
-  dispose() {
-    this._popoverHelper.dispose();
-    if (this._allocationStackView) {
-      this._allocationStackView.clear();
-      this._allocationDataGrid.dispose();
-    }
-    if (this._trackingOverviewGrid)
-      this._trackingOverviewGrid.dispose();
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotView.Perspective = class {
-  /**
-   * @param {string} title
-   */
-  constructor(title) {
-    this._title = title;
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  activate(heapSnapshotView) {
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  deactivate(heapSnapshotView) {
-    heapSnapshotView._baseSelect.setVisible(false);
-    heapSnapshotView._filterSelect.setVisible(false);
-    heapSnapshotView._classNameFilter.setVisible(false);
-    if (heapSnapshotView._trackingOverviewGrid)
-      heapSnapshotView._trackingOverviewGrid.detach();
-    if (heapSnapshotView._allocationWidget)
-      heapSnapshotView._allocationWidget.detach();
-    if (heapSnapshotView._statisticsView)
-      heapSnapshotView._statisticsView.detach();
-
-    heapSnapshotView._splitWidget.detach();
-    heapSnapshotView._splitWidget.detachChildWidgets();
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   * @return {?DataGrid.DataGrid}
-   */
-  masterGrid(heapSnapshotView) {
-    return null;
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  supportsSearch() {
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotView.SummaryPerspective = class extends Profiler.HeapSnapshotView.Perspective {
-  constructor() {
-    super(Common.UIString('Summary'));
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  activate(heapSnapshotView) {
-    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);
-    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
-    heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
-    heapSnapshotView._filterSelect.setVisible(true);
-    heapSnapshotView._classNameFilter.setVisible(true);
-    if (!heapSnapshotView._trackingOverviewGrid)
-      return;
-    heapSnapshotView._trackingOverviewGrid.show(
-        heapSnapshotView._searchableView.element, heapSnapshotView._splitWidget.element);
-    heapSnapshotView._trackingOverviewGrid.update();
-    heapSnapshotView._trackingOverviewGrid._updateGrid();
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   * @return {?DataGrid.DataGrid}
-   */
-  masterGrid(heapSnapshotView) {
-    return heapSnapshotView._constructorsDataGrid;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsSearch() {
-    return true;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotView.ComparisonPerspective = class extends Profiler.HeapSnapshotView.Perspective {
-  constructor() {
-    super(Common.UIString('Comparison'));
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  activate(heapSnapshotView) {
-    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._diffWidget);
-    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
-    heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
-    heapSnapshotView._baseSelect.setVisible(true);
-    heapSnapshotView._classNameFilter.setVisible(true);
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   * @return {?DataGrid.DataGrid}
-   */
-  masterGrid(heapSnapshotView) {
-    return heapSnapshotView._diffDataGrid;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsSearch() {
-    return true;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotView.ContainmentPerspective = class extends Profiler.HeapSnapshotView.Perspective {
-  constructor() {
-    super(Common.UIString('Containment'));
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  activate(heapSnapshotView) {
-    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._containmentWidget);
-    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
-    heapSnapshotView._splitWidget.show(heapSnapshotView._searchableView.element);
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   * @return {?DataGrid.DataGrid}
-   */
-  masterGrid(heapSnapshotView) {
-    return heapSnapshotView._containmentDataGrid;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotView.AllocationPerspective = class extends Profiler.HeapSnapshotView.Perspective {
-  constructor() {
-    super(Common.UIString('Allocation'));
-    this._allocationSplitWidget = new UI.SplitWidget(false, true, 'heapSnapshotAllocationSplitViewState', 200, 200);
-    this._allocationSplitWidget.setSidebarWidget(new UI.VBox());
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  activate(heapSnapshotView) {
-    this._allocationSplitWidget.setMainWidget(heapSnapshotView._allocationWidget);
-    heapSnapshotView._splitWidget.setMainWidget(heapSnapshotView._constructorsWidget);
-    heapSnapshotView._splitWidget.setSidebarWidget(heapSnapshotView._objectDetailsView);
-
-    const allocatedObjectsView = new UI.VBox();
-    const resizer = createElementWithClass('div', 'heap-snapshot-view-resizer');
-    const title = resizer.createChild('div', 'title').createChild('span');
-    title.textContent = Common.UIString('Live objects');
-    this._allocationSplitWidget.hideDefaultResizer();
-    this._allocationSplitWidget.installResizer(resizer);
-    allocatedObjectsView.element.appendChild(resizer);
-    heapSnapshotView._splitWidget.show(allocatedObjectsView.element);
-    this._allocationSplitWidget.setSidebarWidget(allocatedObjectsView);
-
-    this._allocationSplitWidget.show(heapSnapshotView._searchableView.element);
-
-    heapSnapshotView._constructorsDataGrid.clear();
-    const selectedNode = heapSnapshotView._allocationDataGrid.selectedNode;
-    if (selectedNode)
-      heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  deactivate(heapSnapshotView) {
-    this._allocationSplitWidget.detach();
-    super.deactivate(heapSnapshotView);
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   * @return {?DataGrid.DataGrid}
-   */
-  masterGrid(heapSnapshotView) {
-    return heapSnapshotView._allocationDataGrid;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotView.StatisticsPerspective = class extends Profiler.HeapSnapshotView.Perspective {
-  constructor() {
-    super(Common.UIString('Statistics'));
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   */
-  activate(heapSnapshotView) {
-    heapSnapshotView._statisticsView.show(heapSnapshotView._searchableView.element);
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.HeapSnapshotView} heapSnapshotView
-   * @return {?DataGrid.DataGrid}
-   */
-  masterGrid(heapSnapshotView) {
-    return null;
-  }
-};
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.HeapProfilerModel>}
- * @unrestricted
- */
-Profiler.HeapSnapshotProfileType = class extends Profiler.ProfileType {
-  /**
-   * @param {string=} id
-   * @param {string=} title
-   */
-  constructor(id, title) {
-    super(id || Profiler.HeapSnapshotProfileType.TypeId, title || ls`Heap snapshot`);
-    SDK.targetManager.observeModels(SDK.HeapProfilerModel, this);
-    SDK.targetManager.addModelListener(
-        SDK.HeapProfilerModel, SDK.HeapProfilerModel.Events.ResetProfiles, this._resetProfiles, this);
-    SDK.targetManager.addModelListener(
-        SDK.HeapProfilerModel, SDK.HeapProfilerModel.Events.AddHeapSnapshotChunk, this._addHeapSnapshotChunk, this);
-    SDK.targetManager.addModelListener(
-        SDK.HeapProfilerModel, SDK.HeapProfilerModel.Events.ReportHeapSnapshotProgress,
-        this._reportHeapSnapshotProgress, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} heapProfilerModel
-   */
-  modelAdded(heapProfilerModel) {
-    heapProfilerModel.enable();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} heapProfilerModel
-   */
-  modelRemoved(heapProfilerModel) {
-  }
-
-  /**
-   * @override
-   * @return {!Array<!Profiler.HeapProfileHeader>}
-   */
-  getProfiles() {
-    return /** @type {!Array<!Profiler.HeapProfileHeader>} */ (super.getProfiles());
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  fileExtension() {
-    return '.heapsnapshot';
-  }
-
-  get buttonTooltip() {
-    return Common.UIString('Take heap snapshot');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isInstantProfile() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  buttonClicked() {
-    this._takeHeapSnapshot();
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ProfilesHeapProfileTaken);
-    return false;
-  }
-
-  get treeItemTitle() {
-    return Common.UIString('HEAP SNAPSHOTS');
-  }
-
-  get description() {
-    return Common.UIString(
-        'Heap snapshot profiles show memory distribution among your page\'s JavaScript objects and related DOM nodes.');
-  }
-
-  /**
-   * @override
-   * @param {string} title
-   * @return {!Profiler.ProfileHeader}
-   */
-  createProfileLoadedFromFile(title) {
-    return new Profiler.HeapProfileHeader(null, this, title);
-  }
-
-  async _takeHeapSnapshot() {
-    if (this.profileBeingRecorded())
-      return;
-    const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
-    if (!heapProfilerModel)
-      return;
-
-    let profile = new Profiler.HeapProfileHeader(heapProfilerModel, this);
-    this.setProfileBeingRecorded(profile);
-    this.addProfile(profile);
-    profile.updateStatus(Common.UIString('Snapshotting\u2026'));
-
-    await heapProfilerModel.takeHeapSnapshot(true);
-    // ------------ ASYNC ------------
-    profile = this.profileBeingRecorded();
-    profile.title = Common.UIString('Snapshot %d', profile.uid);
-    profile._finishLoad();
-    this.setProfileBeingRecorded(null);
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, profile);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _addHeapSnapshotChunk(event) {
-    if (!this.profileBeingRecorded())
-      return;
-    const chunk = /** @type {string} */ (event.data);
-    this.profileBeingRecorded().transferChunk(chunk);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _reportHeapSnapshotProgress(event) {
-    const profile = this.profileBeingRecorded();
-    if (!profile)
-      return;
-    const data = /** @type {{done: number, total: number, finished: boolean}} */ (event.data);
-    profile.updateStatus(Common.UIString('%.0f%%', (data.done / data.total) * 100), true);
-    if (data.finished)
-      profile._prepareToLoad();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _resetProfiles(event) {
-    const heapProfilerModel = /** @type {!SDK.HeapProfilerModel} */ (event.data);
-    for (const profile of this.getProfiles()) {
-      if (profile._heapProfilerModel === heapProfilerModel)
-        this.removeProfile(profile);
-    }
-  }
-
-  _snapshotReceived(profile) {
-    if (this.profileBeingRecorded() === profile)
-      this.setProfileBeingRecorded(null);
-    this.dispatchEventToListeners(Profiler.HeapSnapshotProfileType.SnapshotReceived, profile);
-  }
-};
-
-Profiler.HeapSnapshotProfileType.TypeId = 'HEAP';
-Profiler.HeapSnapshotProfileType.SnapshotReceived = 'SnapshotReceived';
-
-/**
- * @unrestricted
- */
-Profiler.TrackingHeapSnapshotProfileType = class extends Profiler.HeapSnapshotProfileType {
-  constructor() {
-    super(Profiler.TrackingHeapSnapshotProfileType.TypeId, ls`Allocation instrumentation on timeline`);
-    this._recordAllocationStacksSetting = Common.settings.createSetting('recordAllocationStacks', false);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} heapProfilerModel
-   */
-  modelAdded(heapProfilerModel) {
-    super.modelAdded(heapProfilerModel);
-    heapProfilerModel.addEventListener(SDK.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this);
-    heapProfilerModel.addEventListener(SDK.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} heapProfilerModel
-   */
-  modelRemoved(heapProfilerModel) {
-    super.modelRemoved(heapProfilerModel);
-    heapProfilerModel.removeEventListener(SDK.HeapProfilerModel.Events.HeapStatsUpdate, this._heapStatsUpdate, this);
-    heapProfilerModel.removeEventListener(SDK.HeapProfilerModel.Events.LastSeenObjectId, this._lastSeenObjectId, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _heapStatsUpdate(event) {
-    if (!this._profileSamples)
-      return;
-    const samples = /** @type {!Array.<number>} */ (event.data);
-    let index;
-    for (let i = 0; i < samples.length; i += 3) {
-      index = samples[i];
-      const size = samples[i + 2];
-      this._profileSamples.sizes[index] = size;
-      if (!this._profileSamples.max[index])
-        this._profileSamples.max[index] = size;
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _lastSeenObjectId(event) {
-    const profileSamples = this._profileSamples;
-    if (!profileSamples)
-      return;
-    const data = /** @type {{lastSeenObjectId: number, timestamp: number}} */ (event.data);
-    const currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1);
-    profileSamples.ids[currentIndex] = data.lastSeenObjectId;
-    if (!profileSamples.max[currentIndex]) {
-      profileSamples.max[currentIndex] = 0;
-      profileSamples.sizes[currentIndex] = 0;
-    }
-    profileSamples.timestamps[currentIndex] = data.timestamp;
-    if (profileSamples.totalTime < data.timestamp - profileSamples.timestamps[0])
-      profileSamples.totalTime *= 2;
-    this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
-    this.profileBeingRecorded().updateStatus(null, true);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasTemporaryView() {
-    return true;
-  }
-
-  get buttonTooltip() {
-    return this._recording ? ls`Stop recording heap profile` : ls`Start recording heap profile`;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isInstantProfile() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  buttonClicked() {
-    return this._toggleRecording();
-  }
-
-  _startRecordingProfile() {
-    if (this.profileBeingRecorded())
-      return;
-    const heapProfilerModel = this._addNewProfile();
-    if (!heapProfilerModel)
-      return;
-    heapProfilerModel.startTrackingHeapObjects(this._recordAllocationStacksSetting.get());
-  }
-
-  /**
-   * @override
-   * @return {?Element}
-   */
-  customContent() {
-    return UI.SettingsUI.createSettingCheckbox(
-        ls`Record allocation stacks (extra performance overhead)`, this._recordAllocationStacksSetting, true);
-  }
-
-  /**
-   * @return {?SDK.HeapProfilerModel}
-   */
-  _addNewProfile() {
-    const heapProfilerModel = UI.context.flavor(SDK.HeapProfilerModel);
-    if (!heapProfilerModel)
-      return null;
-    this.setProfileBeingRecorded(new Profiler.HeapProfileHeader(heapProfilerModel, this, undefined));
-    this._profileSamples = new Profiler.TrackingHeapSnapshotProfileType.Samples();
-    this.profileBeingRecorded()._profileSamples = this._profileSamples;
-    this._recording = true;
-    this.addProfile(/** @type {!Profiler.ProfileHeader} */ (this.profileBeingRecorded()));
-    this.profileBeingRecorded().updateStatus(Common.UIString('Recording\u2026'));
-    this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.TrackingStarted);
-    return heapProfilerModel;
-  }
-
-  async _stopRecordingProfile() {
-    this.profileBeingRecorded().updateStatus(Common.UIString('Snapshotting\u2026'));
-    const stopPromise = this.profileBeingRecorded()._heapProfilerModel.stopTrackingHeapObjects(true);
-    this._recording = false;
-    this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.TrackingStopped);
-    await stopPromise;
-    // ------------ ASYNC ------------
-    const profile = this.profileBeingRecorded();
-    if (!profile)
-      return;
-    profile._finishLoad();
-    this._profileSamples = null;
-    this.setProfileBeingRecorded(null);
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, profile);
-  }
-
-  _toggleRecording() {
-    if (this._recording)
-      this._stopRecordingProfile();
-    else
-      this._startRecordingProfile();
-    return this._recording;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  fileExtension() {
-    return '.heaptimeline';
-  }
-
-  get treeItemTitle() {
-    return ls`ALLOCATION TIMELINES`;
-  }
-
-  get description() {
-    return ls`
-        Allocation timelines show instrumented JavaScript memory allocations over time.
-        Once profile is recorded you can select a time interval to see objects that
-        were allocated within it and still alive by the end of recording.
-        Use this profile type to isolate memory leaks.`;
-  }
-
-  /**
-   * @override
-   * @param {!Common.Event} event
-   */
-  _resetProfiles(event) {
-    const wasRecording = this._recording;
-    // Clear current profile to avoid stopping backend.
-    this.setProfileBeingRecorded(null);
-    super._resetProfiles(event);
-    this._profileSamples = null;
-    if (wasRecording)
-      this._addNewProfile();
-  }
-
-  /**
-   * @override
-   */
-  profileBeingRecordedRemoved() {
-    this._stopRecordingProfile();
-    this._profileSamples = null;
-  }
-};
-
-Profiler.TrackingHeapSnapshotProfileType.TypeId = 'HEAP-RECORD';
-
-Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate = 'HeapStatsUpdate';
-Profiler.TrackingHeapSnapshotProfileType.TrackingStarted = 'TrackingStarted';
-Profiler.TrackingHeapSnapshotProfileType.TrackingStopped = 'TrackingStopped';
-
-/**
- * @unrestricted
- */
-Profiler.TrackingHeapSnapshotProfileType.Samples = class {
-  constructor() {
-    /** @type {!Array.<number>} */
-    this.sizes = [];
-    /** @type {!Array.<number>} */
-    this.ids = [];
-    /** @type {!Array.<number>} */
-    this.timestamps = [];
-    /** @type {!Array.<number>} */
-    this.max = [];
-    /** @type {number} */
-    this.totalTime = 30000;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapProfileHeader = class extends Profiler.ProfileHeader {
-  /**
-   * @param {?SDK.HeapProfilerModel} heapProfilerModel
-   * @param {!Profiler.HeapSnapshotProfileType} type
-   * @param {string=} title
-   */
-  constructor(heapProfilerModel, type, title) {
-    super(type, title || Common.UIString('Snapshot %d', type.nextProfileUid()));
-    this._heapProfilerModel = heapProfilerModel;
-    this.maxJSObjectId = -1;
-    /** @type {?Profiler.HeapSnapshotWorkerProxy} */
-    this._workerProxy = null;
-    /** @type {?Common.OutputStream} */
-    this._receiver = null;
-    /** @type {?Profiler.HeapSnapshotProxy} */
-    this._snapshotProxy = null;
-    /** @type {!Promise<!Profiler.HeapSnapshotProxy>} */
-    this._loadPromise = new Promise(resolve => this._fulfillLoad = resolve);
-    this._totalNumberOfChunks = 0;
-    this._bufferedWriter = null;
-    /** @type {?Bindings.TempFile} */
-    this._tempFile = null;
-  }
-
-  /**
-   * @return {?SDK.HeapProfilerModel}
-   */
-  heapProfilerModel() {
-    return this._heapProfilerModel;
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @return {!Profiler.ProfileSidebarTreeElement}
-   */
-  createSidebarTreeElement(dataDisplayDelegate) {
-    return new Profiler.ProfileSidebarTreeElement(dataDisplayDelegate, this, 'heap-snapshot-sidebar-tree-item');
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @return {!Profiler.HeapSnapshotView}
-   */
-  createView(dataDisplayDelegate) {
-    return new Profiler.HeapSnapshotView(dataDisplayDelegate, this);
-  }
-
-  _prepareToLoad() {
-    console.assert(!this._receiver, 'Already loading');
-    this._setupWorker();
-    this.updateStatus(Common.UIString('Loading\u2026'), true);
-  }
-
-  _finishLoad() {
-    if (!this._wasDisposed)
-      this._receiver.close();
-    if (!this._bufferedWriter)
-      return;
-    this._didWriteToTempFile(this._bufferedWriter);
-  }
-
-  /**
-   * @param {!Bindings.TempFile} tempFile
-   */
-  _didWriteToTempFile(tempFile) {
-    if (this._wasDisposed) {
-      if (tempFile)
-        tempFile.remove();
-      return;
-    }
-    this._tempFile = tempFile;
-    if (!tempFile)
-      this._failedToCreateTempFile = true;
-    if (this._onTempFileReady) {
-      this._onTempFileReady();
-      this._onTempFileReady = null;
-    }
-  }
-
-  _setupWorker() {
-    /**
-     * @this {Profiler.HeapProfileHeader}
-     */
-    function setProfileWait(event) {
-      this.updateStatus(null, event.data);
-    }
-    console.assert(!this._workerProxy, 'HeapSnapshotWorkerProxy already exists');
-    this._workerProxy = new Profiler.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
-    this._workerProxy.addEventListener(Profiler.HeapSnapshotWorkerProxy.Events.Wait, setProfileWait, this);
-    this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this));
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {*} data
-   */
-  _handleWorkerEvent(eventName, data) {
-    if (HeapSnapshotModel.HeapSnapshotProgressEvent.BrokenSnapshot === eventName) {
-      const error = /** @type {string} */ (data);
-      Common.console.error(error);
-      return;
-    }
-
-    if (HeapSnapshotModel.HeapSnapshotProgressEvent.Update !== eventName)
-      return;
-    const subtitle = /** @type {string} */ (data);
-    this.updateStatus(subtitle);
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    if (this._workerProxy)
-      this._workerProxy.dispose();
-    this.removeTempFile();
-    this._wasDisposed = true;
-  }
-
-  _didCompleteSnapshotTransfer() {
-    if (!this._snapshotProxy)
-      return;
-    this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false);
-  }
-
-  /**
-   * @param {string} chunk
-   */
-  transferChunk(chunk) {
-    if (!this._bufferedWriter)
-      this._bufferedWriter = new Bindings.TempFile();
-    this._bufferedWriter.write([chunk]);
-
-    ++this._totalNumberOfChunks;
-    this._receiver.write(chunk);
-  }
-
-  _snapshotReceived(snapshotProxy) {
-    if (this._wasDisposed)
-      return;
-    this._receiver = null;
-    this._snapshotProxy = snapshotProxy;
-    this.maxJSObjectId = snapshotProxy.maxJSObjectId();
-    this._didCompleteSnapshotTransfer();
-    this._workerProxy.startCheckingForLongRunningCalls();
-    this.notifySnapshotReceived();
-  }
-
-  notifySnapshotReceived() {
-    this._fulfillLoad(this._snapshotProxy);
-    this.profileType()._snapshotReceived(this);
-    if (this.canSaveToFile())
-      this.dispatchEventToListeners(Profiler.ProfileHeader.Events.ProfileReceived);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canSaveToFile() {
-    return !this.fromFile() && !!this._snapshotProxy;
-  }
-
-  /**
-   * @override
-   */
-  saveToFile() {
-    const fileOutputStream = new Bindings.FileOutputStream();
-    this._fileName = this._fileName || 'Heap-' + new Date().toISO8601Compact() + this.profileType().fileExtension();
-    fileOutputStream.open(this._fileName).then(onOpen.bind(this));
-
-    /**
-     * @param {boolean} accepted
-     * @this {Profiler.HeapProfileHeader}
-     */
-    async function onOpen(accepted) {
-      if (!accepted)
-        return;
-      if (this._failedToCreateTempFile) {
-        Common.console.error('Failed to open temp file with heap snapshot');
-        fileOutputStream.close();
-        return;
-      }
-      if (this._tempFile) {
-        const error = await this._tempFile.copyToOutputStream(fileOutputStream, this._onChunkTransferred.bind(this));
-        if (error)
-          Common.console.error('Failed to read heap snapshot from temp file: ' + error.message);
-        this._didCompleteSnapshotTransfer();
-        return;
-      }
-      this._onTempFileReady = onOpen.bind(this, accepted);
-      this._updateSaveProgress(0, 1);
-    }
-  }
-
-  /**
-   * @param {!Bindings.ChunkedReader} reader
-   */
-  _onChunkTransferred(reader) {
-    this._updateSaveProgress(reader.loadedSize(), reader.fileSize());
-  }
-
-  /**
-   * @param {number} value
-   * @param {number} total
-   */
-  _updateSaveProgress(value, total) {
-    const percentValue = ((total && value / total) * 100).toFixed(0);
-    this.updateStatus(Common.UIString('Saving\u2026 %d%%', percentValue));
-  }
-
-  /**
-   * @override
-   * @param {!File} file
-   * @return {!Promise<?Error>}
-   */
-  async loadFromFile(file) {
-    this.updateStatus(Common.UIString('Loading\u2026'), true);
-    this._setupWorker();
-    const reader = new Bindings.ChunkedFileReader(file, 10000000);
-    const success = await reader.read(/** @type {!Common.OutputStream} */ (this._receiver));
-    if (!success)
-      this.updateStatus(reader.error().message);
-    return success ? null : reader.error();
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapTrackingOverviewGrid = class extends UI.VBox {
-  /**
-   * @param {!Profiler.HeapProfileHeader} heapProfileHeader
-   */
-  constructor(heapProfileHeader) {
-    super();
-    this.element.id = 'heap-recording-view';
-    this.element.classList.add('heap-tracking-overview');
-
-    this._overviewContainer = this.element.createChild('div', 'heap-overview-container');
-    this._overviewGrid = new PerfUI.OverviewGrid('heap-recording');
-    this._overviewGrid.element.classList.add('fill');
-
-    this._overviewCanvas = this._overviewContainer.createChild('canvas', 'heap-recording-overview-canvas');
-    this._overviewContainer.appendChild(this._overviewGrid.element);
-    this._overviewCalculator = new Profiler.HeapTrackingOverviewGrid.OverviewCalculator();
-    this._overviewGrid.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-
-    this._profileSamples = heapProfileHeader.fromFile() ? new Profiler.TrackingHeapSnapshotProfileType.Samples() :
-                                                          heapProfileHeader._profileSamples;
-    this._profileType = heapProfileHeader.profileType();
-    if (!heapProfileHeader.fromFile() && heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) {
-      this._profileType.addEventListener(
-          Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
-      this._profileType.addEventListener(
-          Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
-    }
-    this._windowLeft = 0.0;
-    this._windowRight = 1.0;
-    this._overviewGrid.setWindow(this._windowLeft, this._windowRight);
-    this._yScale = new Profiler.HeapTrackingOverviewGrid.SmoothScale();
-    this._xScale = new Profiler.HeapTrackingOverviewGrid.SmoothScale();
-  }
-
-  dispose() {
-    this._onStopTracking();
-  }
-
-  _onStopTracking() {
-    this._profileType.removeEventListener(
-        Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
-    this._profileType.removeEventListener(
-        Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onHeapStatsUpdate(event) {
-    this._profileSamples = event.data;
-    this._scheduleUpdate();
-  }
-
-  /**
-   * @param {?HeapSnapshotModel.Samples} samples
-   */
-  _setSamples(samples) {
-    if (!samples)
-      return;
-    console.assert(!this._profileSamples.timestamps.length, 'Should only call this method when loading from file.');
-    console.assert(samples.timestamps.length);
-    this._profileSamples = new Profiler.TrackingHeapSnapshotProfileType.Samples();
-    this._profileSamples.sizes = samples.sizes;
-    this._profileSamples.ids = samples.lastAssignedIds;
-    this._profileSamples.timestamps = samples.timestamps;
-    this._profileSamples.max = samples.sizes;
-    this._profileSamples.totalTime = /** @type{number} */ (samples.timestamps.peekLast());
-    this.update();
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  _drawOverviewCanvas(width, height) {
-    if (!this._profileSamples)
-      return;
-    const profileSamples = this._profileSamples;
-    const sizes = profileSamples.sizes;
-    const topSizes = profileSamples.max;
-    const timestamps = profileSamples.timestamps;
-    const startTime = timestamps[0];
-    const endTime = timestamps[timestamps.length - 1];
-
-    const scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime);
-    let maxSize = 0;
-    /**
-     * @param {!Array.<number>} sizes
-     * @param {function(number, number):void} callback
-     */
-    function aggregateAndCall(sizes, callback) {
-      let size = 0;
-      let currentX = 0;
-      for (let i = 1; i < timestamps.length; ++i) {
-        const x = Math.floor((timestamps[i] - startTime) * scaleFactor);
-        if (x !== currentX) {
-          if (size)
-            callback(currentX, size);
-          size = 0;
-          currentX = x;
-        }
-        size += sizes[i];
-      }
-      callback(currentX, size);
-    }
-
-    /**
-     * @param {number} x
-     * @param {number} size
-     */
-    function maxSizeCallback(x, size) {
-      maxSize = Math.max(maxSize, size);
-    }
-
-    aggregateAndCall(sizes, maxSizeCallback);
-
-    const yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0);
-
-    this._overviewCanvas.width = width * window.devicePixelRatio;
-    this._overviewCanvas.height = height * window.devicePixelRatio;
-    this._overviewCanvas.style.width = width + 'px';
-    this._overviewCanvas.style.height = height + 'px';
-
-    const context = this._overviewCanvas.getContext('2d');
-    context.scale(window.devicePixelRatio, window.devicePixelRatio);
-
-    context.beginPath();
-    context.lineWidth = 2;
-    context.strokeStyle = 'rgba(192, 192, 192, 0.6)';
-    const currentX = (endTime - startTime) * scaleFactor;
-    context.moveTo(currentX, height - 1);
-    context.lineTo(currentX, 0);
-    context.stroke();
-    context.closePath();
-
-    let gridY;
-    let gridValue;
-    const gridLabelHeight = 14;
-    if (yScaleFactor) {
-      const maxGridValue = (height - gridLabelHeight) / yScaleFactor;
-      // The round value calculation is a bit tricky, because
-      // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer,
-      // e.g. a round value 10KB is 10240 bytes.
-      gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024)));
-      gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10));
-      if (gridValue * 5 <= maxGridValue)
-        gridValue *= 5;
-      gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5;
-      context.beginPath();
-      context.lineWidth = 1;
-      context.strokeStyle = 'rgba(0, 0, 0, 0.2)';
-      context.moveTo(0, gridY);
-      context.lineTo(width, gridY);
-      context.stroke();
-      context.closePath();
-    }
-
-    /**
-     * @param {number} x
-     * @param {number} size
-     */
-    function drawBarCallback(x, size) {
-      context.moveTo(x, height - 1);
-      context.lineTo(x, Math.round(height - size * yScaleFactor - 1));
-    }
-
-    context.beginPath();
-    context.lineWidth = 2;
-    context.strokeStyle = 'rgba(192, 192, 192, 0.6)';
-    aggregateAndCall(topSizes, drawBarCallback);
-    context.stroke();
-    context.closePath();
-
-    context.beginPath();
-    context.lineWidth = 2;
-    context.strokeStyle = 'rgba(0, 0, 192, 0.8)';
-    aggregateAndCall(sizes, drawBarCallback);
-    context.stroke();
-    context.closePath();
-
-    if (gridValue) {
-      const label = Number.bytesToString(gridValue);
-      const labelPadding = 4;
-      const labelX = 0;
-      const labelY = gridY - 0.5;
-      const labelWidth = 2 * labelPadding + context.measureText(label).width;
-      context.beginPath();
-      context.textBaseline = 'bottom';
-      context.font = '10px ' + window.getComputedStyle(this.element, null).getPropertyValue('font-family');
-      context.fillStyle = 'rgba(255, 255, 255, 0.75)';
-      context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight);
-      context.fillStyle = 'rgb(64, 64, 64)';
-      context.fillText(label, labelX + labelPadding, labelY);
-      context.fill();
-      context.closePath();
-    }
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._updateOverviewCanvas = true;
-    this._scheduleUpdate();
-  }
-
-  _onWindowChanged() {
-    if (!this._updateGridTimerId)
-      this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10);
-  }
-
-  _scheduleUpdate() {
-    if (this._updateTimerId)
-      return;
-    this._updateTimerId = setTimeout(this.update.bind(this), 10);
-  }
-
-  _updateBoundaries() {
-    this._windowLeft = this._overviewGrid.windowLeft();
-    this._windowRight = this._overviewGrid.windowRight();
-    this._windowWidth = this._windowRight - this._windowLeft;
-  }
-
-  update() {
-    this._updateTimerId = null;
-    if (!this.isShowing())
-      return;
-    this._updateBoundaries();
-    this._overviewCalculator._updateBoundaries(this);
-    this._overviewGrid.updateDividers(this._overviewCalculator);
-    this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
-  }
-
-  _updateGrid() {
-    this._updateGridTimerId = 0;
-    this._updateBoundaries();
-    const ids = this._profileSamples.ids;
-    const timestamps = this._profileSamples.timestamps;
-    const sizes = this._profileSamples.sizes;
-    const startTime = timestamps[0];
-    const totalTime = this._profileSamples.totalTime;
-    const timeLeft = startTime + totalTime * this._windowLeft;
-    const timeRight = startTime + totalTime * this._windowRight;
-    let minId = 0;
-    let maxId = ids[ids.length - 1] + 1;
-    let size = 0;
-    for (let i = 0; i < timestamps.length; ++i) {
-      if (!timestamps[i])
-        continue;
-      if (timestamps[i] > timeRight)
-        break;
-      maxId = ids[i];
-      if (timestamps[i] < timeLeft) {
-        minId = ids[i];
-        continue;
-      }
-      size += sizes[i];
-    }
-
-    this.dispatchEventToListeners(
-        Profiler.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size});
-  }
-};
-
-Profiler.HeapTrackingOverviewGrid.IdsRangeChanged = Symbol('IdsRangeChanged');
-
-Profiler.HeapTrackingOverviewGrid.SmoothScale = class {
-  constructor() {
-    this._lastUpdate = 0;
-    this._currentScale = 0.0;
-  }
-
-  /**
-   * @param {number} target
-   * @return {number}
-   */
-  nextScale(target) {
-    target = target || this._currentScale;
-    if (this._currentScale) {
-      const now = Date.now();
-      const timeDeltaMs = now - this._lastUpdate;
-      this._lastUpdate = now;
-      const maxChangePerSec = 20;
-      const maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000);
-      const scaleChange = target / this._currentScale;
-      this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta);
-    } else {
-      this._currentScale = target;
-    }
-    return this._currentScale;
-  }
-};
-
-/**
- * @implements {PerfUI.TimelineGrid.Calculator}
- * @unrestricted
- */
-Profiler.HeapTrackingOverviewGrid.OverviewCalculator = class {
-  /**
-   * @param {!Profiler.HeapTrackingOverviewGrid} chart
-   */
-  _updateBoundaries(chart) {
-    this._minimumBoundaries = 0;
-    this._maximumBoundaries = chart._profileSamples.totalTime;
-    this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries;
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {
-    return (time - this._minimumBoundaries) * this._xScaleFactor;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.secondsToString(value / 1000, !!precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maximumBoundary() {
-    return this._maximumBoundaries;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._minimumBoundaries;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zeroTime() {
-    return this._minimumBoundaries;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  boundarySpan() {
-    return this._maximumBoundaries - this._minimumBoundaries;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.HeapSnapshotStatisticsView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.element.classList.add('heap-snapshot-statistics-view');
-    this._pieChart = new PerfUI.PieChart(150, Profiler.HeapSnapshotStatisticsView._valueFormatter, true);
-    this._pieChart.element.classList.add('heap-snapshot-stats-pie-chart');
-    this.element.appendChild(this._pieChart.element);
-    this._labels = this.element.createChild('div', 'heap-snapshot-stats-legend');
-  }
-
-  /**
-   * @param {number} value
-   * @return {string}
-   */
-  static _valueFormatter(value) {
-    return Common.UIString('%s KB', Number.withThousandsSeparator(Math.round(value / 1024)));
-  }
-
-  /**
-   * @param {number} value
-   */
-  setTotal(value) {
-    this._pieChart.setTotal(value);
-  }
-
-  /**
-   * @param {number} value
-   * @param {string} name
-   * @param {string=} color
-   */
-  addRecord(value, name, color) {
-    if (color)
-      this._pieChart.addSlice(value, color);
-
-    const node = this._labels.createChild('div');
-    const swatchDiv = node.createChild('div', 'heap-snapshot-stats-swatch');
-    const nameDiv = node.createChild('div', 'heap-snapshot-stats-name');
-    const sizeDiv = node.createChild('div', 'heap-snapshot-stats-size');
-    if (color)
-      swatchDiv.style.backgroundColor = color;
-    else
-      swatchDiv.classList.add('heap-snapshot-stats-empty-swatch');
-    nameDiv.textContent = name;
-    sizeDiv.textContent = Profiler.HeapSnapshotStatisticsView._valueFormatter(value);
-  }
-};
-
-Profiler.HeapAllocationStackView = class extends UI.Widget {
-  /**
-   * @param {?SDK.HeapProfilerModel} heapProfilerModel
-   */
-  constructor(heapProfilerModel) {
-    super();
-    this._heapProfilerModel = heapProfilerModel;
-    this._linkifier = new Components.Linkifier();
-  }
-
-  /**
-   * @param {!Profiler.HeapSnapshotProxy} snapshot
-   * @param {number} snapshotNodeIndex
-   */
-  async setAllocatedObject(snapshot, snapshotNodeIndex) {
-    this.clear();
-    const frames = await snapshot.allocationStack(snapshotNodeIndex);
-
-    if (!frames) {
-      const stackDiv = this.element.createChild('div', 'no-heap-allocation-stack');
-      stackDiv.createTextChild(Common.UIString(
-          'Stack was not recorded for this object because it had been allocated before this profile recording started.'));
-      return;
-    }
-
-    const stackDiv = this.element.createChild('div', 'heap-allocation-stack');
-    for (const frame of frames) {
-      const frameDiv = stackDiv.createChild('div', 'stack-frame');
-      const name = frameDiv.createChild('div');
-      name.textContent = UI.beautifyFunctionName(frame.functionName);
-      if (!frame.scriptId)
-        continue;
-      const urlElement = this._linkifier.linkifyScriptLocation(
-          this._heapProfilerModel ? this._heapProfilerModel.target() : null, String(frame.scriptId), frame.scriptName,
-          frame.line - 1, frame.column - 1);
-      frameDiv.appendChild(urlElement);
-    }
-  }
-
-  clear() {
-    this.element.removeChildren();
-    this._linkifier.reset();
-  }
-};
diff --git a/front_end/profiler/IsolateSelector.js b/front_end/profiler/IsolateSelector.js
deleted file mode 100644
index cf3460c..0000000
--- a/front_end/profiler/IsolateSelector.js
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.RuntimeModel>}
- * @implements {UI.ListDelegate<!Profiler.IsolateSelector.ListItem>}
- */
-Profiler.IsolateSelector = class extends UI.VBox {
-  constructor() {
-    super(true);
-
-    /** @type {!UI.ListModel<!Profiler.IsolateSelector.ListItem>} */
-    this._items = new UI.ListModel();
-    /** @type {!UI.ListControl<!Profiler.IsolateSelector.ListItem>} */
-    this._list = new UI.ListControl(this._items, this, UI.ListMode.NonViewport);
-    this.contentElement.appendChild(this._list.element);
-
-    this.registerRequiredCSS('profiler/profileLauncherView.css');
-    /** @type {!Map<!SDK.RuntimeModel, !Promise<string>>} */
-    this._isolateByModel = new Map();
-    /** @type {!Map<string, !Profiler.IsolateSelector.ListItem>} */
-    this._itemByIsolate = new Map();
-
-    SDK.targetManager.observeModels(SDK.RuntimeModel, this);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.NameChanged, this._targetChanged, this);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._targetChanged, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.RuntimeModel} model
-   */
-  modelAdded(model) {
-    this._modelAdded(model);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} model
-   */
-  async _modelAdded(model) {
-    const isolatePromise = model.isolateId();
-    this._isolateByModel.set(model, isolatePromise);
-    const isolate = await isolatePromise;
-    let item = this._itemByIsolate.get(isolate);
-    if (!item) {
-      item = new Profiler.IsolateSelector.ListItem(model);
-      const index = model.target() === SDK.targetManager.mainTarget() ? 0 : this._items.length;
-      this._items.insert(index, item);
-      this._itemByIsolate.set(isolate, item);
-      if (this._items.length === 1)
-        this._list.selectItem(item);
-    } else {
-      item.addModel(model);
-    }
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.RuntimeModel} model
-   */
-  modelRemoved(model) {
-    this._modelRemoved(model);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} model
-   */
-  async _modelRemoved(model) {
-    const isolate = await this._isolateByModel.get(model);
-    this._isolateByModel.delete(model);
-    const item = this._itemByIsolate.get(isolate);
-    item.removeModel(model);
-    if (!item.models().length) {
-      this._items.remove(this._items.indexOf(item));
-      this._itemByIsolate.delete(isolate);
-    }
-    this._update();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  async _targetChanged(event) {
-    const target = /** @type {!SDK.Target} */ (event.data);
-    const model = target.model(SDK.RuntimeModel);
-    const isolate = model && await this._isolateByModel.get(model);
-    const item = isolate && this._itemByIsolate.get(isolate);
-    if (item)
-      item.updateTitle();
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.IsolateSelector.ListItem} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    return item.element;
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.IsolateSelector.ListItem} item
-   * @return {number}
-   */
-  heightForItem(item) {
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.IsolateSelector.ListItem} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?Profiler.IsolateSelector.ListItem} from
-   * @param {?Profiler.IsolateSelector.ListItem} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('selected');
-    if (toElement)
-      toElement.classList.add('selected');
-    const model = to && to.models()[0];
-    UI.context.setFlavor(SDK.HeapProfilerModel, model && model.heapProfilerModel());
-    UI.context.setFlavor(SDK.CPUProfilerModel, model && model.target().model(SDK.CPUProfilerModel));
-  }
-
-  _update() {
-    this._list.invalidateRange(0, this._items.length);
-  }
-};
-
-Profiler.IsolateSelector.ListItem = class {
-  /**
-   * @param {!SDK.RuntimeModel} model
-   */
-  constructor(model) {
-    /** @type {!Set<!SDK.RuntimeModel>} */
-    this._models = new Set([model]);
-    this.element = createElementWithClass('div', 'profile-isolate-item hbox');
-    this._heapDiv = this.element.createChild('div', 'profile-isolate-item-heap');
-    this._nameDiv = this.element.createChild('div', 'profile-isolate-item-name');
-    this._updateTimer = null;
-    this.updateTitle();
-    this._updateStats();
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} model
-   */
-  addModel(model) {
-    this._models.add(model);
-    this.updateTitle();
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} model
-   */
-  removeModel(model) {
-    this._models.delete(model);
-    this.updateTitle();
-    if (this._models.size)
-      return;
-    clearTimeout(this._updateTimer);
-  }
-
-  /**
-   * @return {!Array<!SDK.RuntimeModel>}
-   */
-  models() {
-    return Array.from(this._models);
-  }
-
-  async _updateStats() {
-    const heapStats = await this._models.values().next().value.heapUsage();
-    if (!heapStats)
-      return;
-    this._heapDiv.textContent =
-        `${Number.bytesToString(heapStats.usedSize)} / ${Number.bytesToString(heapStats.totalSize)}`;
-    const heapStatsUpdateIntervalMs = 2000;
-    this._updateTimer = setTimeout(() => this._updateStats(), heapStatsUpdateIntervalMs);
-  }
-
-  updateTitle() {
-    /** @type {!Map<string, number>} */
-    const modelCountByName = new Map();
-    for (const model of this._models.values()) {
-      const target = model.target();
-      const name = SDK.targetManager.mainTarget() !== target ? target.name() : '';
-      const parsedURL = new Common.ParsedURL(target.inspectedURL());
-      const domain = parsedURL.isValid ? parsedURL.domain() : '';
-      const title = target.decorateLabel(domain && name ? `${domain}: ${name}` : name || domain || ls`(empty)`);
-      modelCountByName.set(title, (modelCountByName.get(title) || 0) + 1);
-    }
-    this._nameDiv.removeChildren();
-    for (const [name, count] of modelCountByName) {
-      const lineDiv = this._nameDiv.createChild('div');
-      const title = count > 1 ? `${name} (${count})` : name;
-      lineDiv.textContent = title;
-      lineDiv.setAttribute('title', title);
-    }
-  }
-};
diff --git a/front_end/profiler/ProfileDataGrid.js b/front_end/profiler/ProfileDataGrid.js
deleted file mode 100644
index 8ac82b6..0000000
--- a/front_end/profiler/ProfileDataGrid.js
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright (C) 2009 280 North Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Profiler.ProfileDataGridNode = class extends DataGrid.DataGridNode {
-  /**
-   * @param {!SDK.ProfileNode} profileNode
-   * @param {!Profiler.ProfileDataGridTree} owningTree
-   * @param {boolean} hasChildren
-   */
-  constructor(profileNode, owningTree, hasChildren) {
-    super(null, hasChildren);
-
-    this.profileNode = profileNode;
-    this.tree = owningTree;
-    /** @type {!Map<string, !Profiler.ProfileDataGridNode>} */
-    this.childrenByCallUID = new Map();
-    this.lastComparator = null;
-
-    this.callUID = profileNode.callUID;
-    this.self = profileNode.self;
-    this.total = profileNode.total;
-    this.functionName = UI.beautifyFunctionName(profileNode.functionName);
-    this._deoptReason = profileNode.deoptReason || '';
-    this.url = profileNode.url;
-  }
-
-  /**
-   * @param {!Array<!Array<!Profiler.ProfileDataGridNode>>} gridNodeGroups
-   * @param {function(!T, !T)} comparator
-   * @param {boolean} force
-   * @template T
-   */
-  static sort(gridNodeGroups, comparator, force) {
-    for (let gridNodeGroupIndex = 0; gridNodeGroupIndex < gridNodeGroups.length; ++gridNodeGroupIndex) {
-      const gridNodes = gridNodeGroups[gridNodeGroupIndex];
-      const count = gridNodes.length;
-
-      for (let index = 0; index < count; ++index) {
-        const gridNode = gridNodes[index];
-
-        // If the grid node is collapsed, then don't sort children (save operation for later).
-        // If the grid node has the same sorting as previously, then there is no point in sorting it again.
-        if (!force && (!gridNode.expanded || gridNode.lastComparator === comparator)) {
-          if (gridNode.children.length)
-            gridNode.shouldRefreshChildren = true;
-          continue;
-        }
-
-        gridNode.lastComparator = comparator;
-
-        const children = gridNode.children;
-        const childCount = children.length;
-
-        if (childCount) {
-          children.sort(comparator);
-
-          for (let childIndex = 0; childIndex < childCount; ++childIndex)
-            children[childIndex].recalculateSiblings(childIndex);
-
-          gridNodeGroups.push(children);
-        }
-      }
-    }
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode|!Profiler.ProfileDataGridTree} container
-   * @param {!Profiler.ProfileDataGridNode} child
-   * @param {boolean} shouldAbsorb
-   */
-  static merge(container, child, shouldAbsorb) {
-    container.self += child.self;
-
-    if (!shouldAbsorb)
-      container.total += child.total;
-
-    let children = container.children.slice();
-
-    container.removeChildren();
-
-    let count = children.length;
-
-    for (let index = 0; index < count; ++index) {
-      if (!shouldAbsorb || children[index] !== child)
-        container.appendChild(children[index]);
-    }
-
-    children = child.children.slice();
-    count = children.length;
-
-    for (let index = 0; index < count; ++index) {
-      const orphanedChild = children[index];
-      const existingChild = container.childrenByCallUID.get(orphanedChild.callUID);
-
-      if (existingChild)
-        existingChild.merge(/** @type{!Profiler.ProfileDataGridNode} */ (orphanedChild), false);
-      else
-        container.appendChild(orphanedChild);
-    }
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode|!Profiler.ProfileDataGridTree} container
-   */
-  static populate(container) {
-    if (container._populated)
-      return;
-    container._populated = true;
-
-    container.populateChildren();
-
-    const currentComparator = container.tree.lastComparator;
-
-    if (currentComparator)
-      container.sort(currentComparator, true);
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    let cell;
-    switch (columnId) {
-      case 'self':
-        cell = this._createValueCell(this.self, this.selfPercent);
-        cell.classList.toggle('highlight', this._searchMatchedSelfColumn);
-        break;
-
-      case 'total':
-        cell = this._createValueCell(this.total, this.totalPercent);
-        cell.classList.toggle('highlight', this._searchMatchedTotalColumn);
-        break;
-
-      case 'function':
-        cell = this.createTD(columnId);
-        cell.classList.toggle('highlight', this._searchMatchedFunctionColumn);
-        if (this._deoptReason) {
-          cell.classList.add('not-optimized');
-          const warningIcon = UI.Icon.create('smallicon-warning', 'profile-warn-marker');
-          warningIcon.title = Common.UIString('Not optimized: %s', this._deoptReason);
-          cell.appendChild(warningIcon);
-        }
-        cell.createTextChild(this.functionName);
-        if (this.profileNode.scriptId === '0')
-          break;
-        const urlElement = this.tree._formatter.linkifyNode(this);
-        if (!urlElement)
-          break;
-        urlElement.style.maxWidth = '75%';
-        cell.appendChild(urlElement);
-        break;
-
-      default:
-        cell = super.createCell(columnId);
-        break;
-    }
-    return cell;
-  }
-
-  /**
-   * @param {number} value
-   * @param {number} percent
-   * @return {!Element}
-   */
-  _createValueCell(value, percent) {
-    const cell = createElementWithClass('td', 'numeric-column');
-    const div = cell.createChild('div', 'profile-multiple-values');
-    div.createChild('span').textContent = this.tree._formatter.formatValue(value, this);
-    div.createChild('span', 'percent-column').textContent = this.tree._formatter.formatPercent(percent, this);
-    return cell;
-  }
-
-  /**
-   * @param {function(!T, !T)} comparator
-   * @param {boolean} force
-   * @template T
-   */
-  sort(comparator, force) {
-    return Profiler.ProfileDataGridNode.sort([[this]], comparator, force);
-  }
-
-  /**
-   * @override
-   * @param {!DataGrid.DataGridNode} profileDataGridNode
-   * @param {number} index
-   */
-  insertChild(profileDataGridNode, index) {
-    super.insertChild(profileDataGridNode, index);
-
-    this.childrenByCallUID.set(
-        profileDataGridNode.callUID, /** @type {!Profiler.ProfileDataGridNode} */ (profileDataGridNode));
-  }
-
-  /**
-   * @override
-   * @param {!DataGrid.DataGridNode} profileDataGridNode
-   */
-  removeChild(profileDataGridNode) {
-    super.removeChild(profileDataGridNode);
-
-    this.childrenByCallUID.delete((/** @type {!Profiler.ProfileDataGridNode} */ (profileDataGridNode)).callUID);
-  }
-
-  /**
-   * @override
-   */
-  removeChildren() {
-    super.removeChildren();
-
-    this.childrenByCallUID.clear();
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} node
-   * @return {?Profiler.ProfileDataGridNode}
-   */
-  findChild(node) {
-    if (!node)
-      return null;
-    return this.childrenByCallUID.get(node.callUID);
-  }
-
-  get selfPercent() {
-    return this.self / this.tree.total * 100.0;
-  }
-
-  get totalPercent() {
-    return this.total / this.tree.total * 100.0;
-  }
-
-  /**
-   * @override
-   */
-  populate() {
-    Profiler.ProfileDataGridNode.populate(this);
-  }
-
-  /**
-   * @protected
-   */
-  populateChildren() {
-  }
-
-  // When focusing and collapsing we modify lots of nodes in the tree.
-  // This allows us to restore them all to their original state when we revert.
-
-  save() {
-    if (this._savedChildren)
-      return;
-
-    this._savedSelf = this.self;
-    this._savedTotal = this.total;
-
-    this._savedChildren = this.children.slice();
-  }
-
-  /**
-   * When focusing and collapsing we modify lots of nodes in the tree.
-   * This allows us to restore them all to their original state when we revert.
-   * @protected
-   */
-  restore() {
-    if (!this._savedChildren)
-      return;
-
-    this.self = this._savedSelf;
-    this.total = this._savedTotal;
-
-    this.removeChildren();
-
-    const children = this._savedChildren;
-    const count = children.length;
-
-    for (let index = 0; index < count; ++index) {
-      children[index].restore();
-      this.appendChild(children[index]);
-    }
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} child
-   * @param {boolean} shouldAbsorb
-   */
-  merge(child, shouldAbsorb) {
-    Profiler.ProfileDataGridNode.merge(this, child, shouldAbsorb);
-  }
-};
-
-
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Profiler.ProfileDataGridTree = class {
-  /**
-   * @param {!Profiler.ProfileDataGridNode.Formatter} formatter
-   * @param {!UI.SearchableView} searchableView
-   * @param {number} total
-   */
-  constructor(formatter, searchableView, total) {
-    this.tree = this;
-    this.children = [];
-    this._formatter = formatter;
-    this._searchableView = searchableView;
-    this.total = total;
-    this.lastComparator = null;
-    this.childrenByCallUID = new Map();
-    this.deepSearch = true;
-  }
-
-  /**
-   * @param {string} property
-   * @param {boolean} isAscending
-   * @return {function(!Object.<string, *>, !Object.<string, *>)}
-   */
-  static propertyComparator(property, isAscending) {
-    let comparator = Profiler.ProfileDataGridTree.propertyComparators[(isAscending ? 1 : 0)][property];
-
-    if (!comparator) {
-      if (isAscending) {
-        comparator = function(lhs, rhs) {
-          if (lhs[property] < rhs[property])
-            return -1;
-
-          if (lhs[property] > rhs[property])
-            return 1;
-
-          return 0;
-        };
-      } else {
-        comparator = function(lhs, rhs) {
-          if (lhs[property] > rhs[property])
-            return -1;
-
-          if (lhs[property] < rhs[property])
-            return 1;
-
-          return 0;
-        };
-      }
-
-      Profiler.ProfileDataGridTree.propertyComparators[(isAscending ? 1 : 0)][property] = comparator;
-    }
-
-    return comparator;
-  }
-
-  get expanded() {
-    return true;
-  }
-
-  appendChild(child) {
-    this.insertChild(child, this.children.length);
-  }
-
-  insertChild(child, index) {
-    this.children.splice(index, 0, child);
-    this.childrenByCallUID.set(child.callUID, child);
-  }
-
-  removeChildren() {
-    this.children = [];
-    this.childrenByCallUID.clear();
-  }
-
-  populateChildren() {
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} node
-   * @return {?Profiler.ProfileDataGridNode}
-   */
-  findChild(node) {
-    if (!node)
-      return null;
-    return this.childrenByCallUID.get(node.callUID);
-  }
-
-  /**
-   * @param {function(!T, !T)} comparator
-   * @param {boolean} force
-   * @template T
-   */
-  sort(comparator, force) {
-    return Profiler.ProfileDataGridNode.sort([[this]], comparator, force);
-  }
-
-  /**
-   * @protected
-   */
-  save() {
-    if (this._savedChildren)
-      return;
-
-    this._savedTotal = this.total;
-    this._savedChildren = this.children.slice();
-  }
-
-  restore() {
-    if (!this._savedChildren)
-      return;
-
-    this.children = this._savedChildren;
-    this.total = this._savedTotal;
-
-    const children = this.children;
-    const count = children.length;
-
-    for (let index = 0; index < count; ++index)
-      children[index].restore();
-
-    this._savedChildren = null;
-  }
-
-  /**
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @return {?function(!Profiler.ProfileDataGridNode):boolean}
-   */
-  _matchFunction(searchConfig) {
-    const query = searchConfig.query.trim();
-    if (!query.length)
-      return null;
-
-    const greaterThan = (query.startsWith('>'));
-    const lessThan = (query.startsWith('<'));
-    let equalTo = (query.startsWith('=') || ((greaterThan || lessThan) && query.indexOf('=') === 1));
-    const percentUnits = (query.endsWith('%'));
-    const millisecondsUnits = (query.length > 2 && query.endsWith('ms'));
-    const secondsUnits = (!millisecondsUnits && query.endsWith('s'));
-
-    let queryNumber = parseFloat(query);
-    if (greaterThan || lessThan || equalTo) {
-      if (equalTo && (greaterThan || lessThan))
-        queryNumber = parseFloat(query.substring(2));
-      else
-        queryNumber = parseFloat(query.substring(1));
-    }
-
-    const queryNumberMilliseconds = (secondsUnits ? (queryNumber * 1000) : queryNumber);
-
-    // Make equalTo implicitly true if it wasn't specified there is no other operator.
-    if (!isNaN(queryNumber) && !(greaterThan || lessThan))
-      equalTo = true;
-
-    const matcher = createPlainTextSearchRegex(query, 'i');
-
-    /**
-     * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
-     * @return {boolean}
-     */
-    function matchesQuery(profileDataGridNode) {
-      delete profileDataGridNode._searchMatchedSelfColumn;
-      delete profileDataGridNode._searchMatchedTotalColumn;
-      delete profileDataGridNode._searchMatchedFunctionColumn;
-
-      if (percentUnits) {
-        if (lessThan) {
-          if (profileDataGridNode.selfPercent < queryNumber)
-            profileDataGridNode._searchMatchedSelfColumn = true;
-          if (profileDataGridNode.totalPercent < queryNumber)
-            profileDataGridNode._searchMatchedTotalColumn = true;
-        } else if (greaterThan) {
-          if (profileDataGridNode.selfPercent > queryNumber)
-            profileDataGridNode._searchMatchedSelfColumn = true;
-          if (profileDataGridNode.totalPercent > queryNumber)
-            profileDataGridNode._searchMatchedTotalColumn = true;
-        }
-
-        if (equalTo) {
-          if (profileDataGridNode.selfPercent === queryNumber)
-            profileDataGridNode._searchMatchedSelfColumn = true;
-          if (profileDataGridNode.totalPercent === queryNumber)
-            profileDataGridNode._searchMatchedTotalColumn = true;
-        }
-      } else if (millisecondsUnits || secondsUnits) {
-        if (lessThan) {
-          if (profileDataGridNode.self < queryNumberMilliseconds)
-            profileDataGridNode._searchMatchedSelfColumn = true;
-          if (profileDataGridNode.total < queryNumberMilliseconds)
-            profileDataGridNode._searchMatchedTotalColumn = true;
-        } else if (greaterThan) {
-          if (profileDataGridNode.self > queryNumberMilliseconds)
-            profileDataGridNode._searchMatchedSelfColumn = true;
-          if (profileDataGridNode.total > queryNumberMilliseconds)
-            profileDataGridNode._searchMatchedTotalColumn = true;
-        }
-
-        if (equalTo) {
-          if (profileDataGridNode.self === queryNumberMilliseconds)
-            profileDataGridNode._searchMatchedSelfColumn = true;
-          if (profileDataGridNode.total === queryNumberMilliseconds)
-            profileDataGridNode._searchMatchedTotalColumn = true;
-        }
-      }
-
-      if (profileDataGridNode.functionName.match(matcher) ||
-          (profileDataGridNode.url && profileDataGridNode.url.match(matcher)))
-        profileDataGridNode._searchMatchedFunctionColumn = true;
-
-      if (profileDataGridNode._searchMatchedSelfColumn || profileDataGridNode._searchMatchedTotalColumn ||
-          profileDataGridNode._searchMatchedFunctionColumn) {
-        profileDataGridNode.refresh();
-        return true;
-      }
-
-      return false;
-    }
-    return matchesQuery;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this.searchCanceled();
-    const matchesQuery = this._matchFunction(searchConfig);
-    if (!matchesQuery)
-      return;
-
-    this._searchResults = [];
-    const deepSearch = this.deepSearch;
-    for (let current = this.children[0]; current; current = current.traverseNextNode(!deepSearch, null, !deepSearch)) {
-      if (matchesQuery(current))
-        this._searchResults.push({profileNode: current});
-    }
-    this._searchResultIndex = jumpBackwards ? 0 : this._searchResults.length - 1;
-    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-    this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    if (this._searchResults) {
-      for (let i = 0; i < this._searchResults.length; ++i) {
-        const profileNode = this._searchResults[i].profileNode;
-        delete profileNode._searchMatchedSelfColumn;
-        delete profileNode._searchMatchedTotalColumn;
-        delete profileNode._searchMatchedFunctionColumn;
-        profileNode.refresh();
-      }
-    }
-
-    this._searchResults = [];
-    this._searchResultIndex = -1;
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._searchResults || !this._searchResults.length)
-      return;
-    this._searchResultIndex = (this._searchResultIndex + 1) % this._searchResults.length;
-    this._jumpToSearchResult(this._searchResultIndex);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._searchResults || !this._searchResults.length)
-      return;
-    this._searchResultIndex = (this._searchResultIndex - 1 + this._searchResults.length) % this._searchResults.length;
-    this._jumpToSearchResult(this._searchResultIndex);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return false;
-  }
-
-  /**
-   * @param {number} index
-   */
-  _jumpToSearchResult(index) {
-    const searchResult = this._searchResults[index];
-    if (!searchResult)
-      return;
-    const profileNode = searchResult.profileNode;
-    profileNode.revealAndSelect();
-    this._searchableView.updateCurrentMatchIndex(index);
-  }
-};
-
-Profiler.ProfileDataGridTree.propertyComparators = [{}, {}];
-
-
-/**
- * @interface
- */
-Profiler.ProfileDataGridNode.Formatter = function() {};
-
-Profiler.ProfileDataGridNode.Formatter.prototype = {
-  /**
-   * @param {number} value
-   * @param {!Profiler.ProfileDataGridNode} node
-   * @return {string}
-   */
-  formatValue(value, node) {},
-
-  /**
-   * @param {number} value
-   * @param {!Profiler.ProfileDataGridNode} node
-   * @return {string}
-   */
-  formatPercent(value, node) {},
-
-  /**
-   * @param  {!Profiler.ProfileDataGridNode} node
-   * @return {?Element}
-   */
-  linkifyNode(node) {}
-};
diff --git a/front_end/profiler/ProfileHeader.js b/front_end/profiler/ProfileHeader.js
deleted file mode 100644
index 8498fbe..0000000
--- a/front_end/profiler/ProfileHeader.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Profiler.ProfileHeader = class extends Common.Object {
-  /**
-   * @param {!Profiler.ProfileType} profileType
-   * @param {string} title
-   */
-  constructor(profileType, title) {
-    super();
-    this._profileType = profileType;
-    this.title = title;
-    this.uid = profileType.incrementProfileUid();
-    this._fromFile = false;
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    this.title = title;
-    this.dispatchEventToListeners(Profiler.ProfileHeader.Events.ProfileTitleChanged, this);
-  }
-
-  /**
-   * @return {!Profiler.ProfileType}
-   */
-  profileType() {
-    return this._profileType;
-  }
-
-  /**
-   * @param {?string} subtitle
-   * @param {boolean=} wait
-   */
-  updateStatus(subtitle, wait) {
-    this.dispatchEventToListeners(
-        Profiler.ProfileHeader.Events.UpdateStatus, new Profiler.ProfileHeader.StatusUpdate(subtitle, wait));
-  }
-
-  /**
-   * Must be implemented by subclasses.
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @return {!Profiler.ProfileSidebarTreeElement}
-   */
-  createSidebarTreeElement(dataDisplayDelegate) {
-    throw new Error('Not implemented.');
-  }
-
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @return {!UI.Widget}
-   */
-  createView(dataDisplayDelegate) {
-    throw new Error('Not implemented.');
-  }
-
-  removeTempFile() {
-    if (this._tempFile)
-      this._tempFile.remove();
-  }
-
-  dispose() {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canSaveToFile() {
-    return false;
-  }
-
-  saveToFile() {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @param {!File} file
-   * @return {!Promise<?Error>}
-   */
-  loadFromFile(file) {
-    throw new Error('Not implemented');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  fromFile() {
-    return this._fromFile;
-  }
-
-  setFromFile() {
-    this._fromFile = true;
-  }
-
-  /**
-   * @param {!Protocol.Profiler.Profile} profile
-   */
-  setProfile(profile) {
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileHeader.StatusUpdate = class {
-  /**
-   * @param {?string} subtitle
-   * @param {boolean|undefined} wait
-   */
-  constructor(subtitle, wait) {
-    /** @type {?string} */
-    this.subtitle = subtitle;
-    /** @type {boolean|undefined} */
-    this.wait = wait;
-  }
-};
-
-/** @enum {symbol} */
-Profiler.ProfileHeader.Events = {
-  UpdateStatus: Symbol('UpdateStatus'),
-  ProfileReceived: Symbol('ProfileReceived'),
-  ProfileTitleChanged: Symbol('ProfileTitleChanged')
-};
diff --git a/front_end/profiler/ProfileLauncherView.js b/front_end/profiler/ProfileLauncherView.js
deleted file mode 100644
index dae7142..0000000
--- a/front_end/profiler/ProfileLauncherView.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Profiler.ProfileLauncherView = class extends UI.VBox {
-  /**
-   * @param {!Profiler.ProfilesPanel} profilesPanel
-   */
-  constructor(profilesPanel) {
-    super();
-    this._panel = profilesPanel;
-    this.element.classList.add('profile-launcher-view');
-
-    this._contentElement = this.element.createChild('div', 'profile-launcher-view-content');
-    this._innerContentElement = this._contentElement.createChild('div');
-    const controlDiv = this._contentElement.createChild('div', 'hbox profile-launcher-control');
-    controlDiv.createChild('h1').textContent = ls`Select JavaScript VM instance`;
-    const targetDiv = controlDiv.createChild('div', 'hbox profile-launcher-target-list');
-    new Profiler.IsolateSelector().show(targetDiv);
-    this._controlButton =
-        UI.createTextButton('', this._controlButtonClicked.bind(this), 'profile-launcher-button', true /* primary */);
-    this._contentElement.appendChild(this._controlButton);
-    this._recordButtonEnabled = true;
-    this._loadButton =
-        UI.createTextButton(Common.UIString('Load'), this._loadButtonClicked.bind(this), 'profile-launcher-button');
-    this._contentElement.appendChild(this._loadButton);
-
-    this._selectedProfileTypeSetting = Common.settings.createSetting('selectedProfileType', 'CPU');
-    this._header = this._innerContentElement.createChild('h1');
-    this._profileTypeSelectorForm = this._innerContentElement.createChild('form');
-    this._innerContentElement.createChild('div', 'flexible-space');
-    /** @type {!Map<string, !HTMLOptionElement>} */
-    this._typeIdToOptionElement = new Map();
-  }
-
-  _loadButtonClicked() {
-    this._panel.showLoadFromFileDialog();
-  }
-
-  _updateControls() {
-    if (this._isEnabled && this._recordButtonEnabled)
-      this._controlButton.removeAttribute('disabled');
-    else
-      this._controlButton.setAttribute('disabled', '');
-    this._controlButton.title = this._recordButtonEnabled ? '' : UI.anotherProfilerActiveLabel();
-    if (this._isInstantProfile) {
-      this._controlButton.classList.remove('running');
-      this._controlButton.classList.add('primary-button');
-      this._controlButton.textContent = Common.UIString('Take snapshot');
-    } else if (this._isProfiling) {
-      this._controlButton.classList.add('running');
-      this._controlButton.classList.remove('primary-button');
-      this._controlButton.textContent = Common.UIString('Stop');
-    } else {
-      this._controlButton.classList.remove('running');
-      this._controlButton.classList.add('primary-button');
-      this._controlButton.textContent = Common.UIString('Start');
-    }
-    for (const item of this._typeIdToOptionElement.values())
-      item.disabled = !!this._isProfiling;
-  }
-
-  profileStarted() {
-    this._isProfiling = true;
-    this._updateControls();
-  }
-
-  profileFinished() {
-    this._isProfiling = false;
-    this._updateControls();
-  }
-
-  /**
-   * @param {!Profiler.ProfileType} profileType
-   * @param {boolean} recordButtonEnabled
-   */
-  updateProfileType(profileType, recordButtonEnabled) {
-    this._isInstantProfile = profileType.isInstantProfile();
-    this._recordButtonEnabled = recordButtonEnabled;
-    this._isEnabled = profileType.isEnabled();
-    this._updateControls();
-  }
-
-  /**
-   * @param {!Profiler.ProfileType} profileType
-   */
-  addProfileType(profileType) {
-    const labelElement = UI.createRadioLabel('profile-type', profileType.name);
-    this._profileTypeSelectorForm.appendChild(labelElement);
-    const optionElement = labelElement.radioElement;
-    this._typeIdToOptionElement.set(profileType.id, optionElement);
-    optionElement._profileType = profileType;
-    optionElement.style.hidden = true;
-    optionElement.addEventListener('change', this._profileTypeChanged.bind(this, profileType), false);
-    const descriptionElement = this._profileTypeSelectorForm.createChild('p');
-    descriptionElement.textContent = profileType.description;
-    const customContent = profileType.customContent();
-    if (customContent)
-      this._profileTypeSelectorForm.createChild('p').appendChild(customContent);
-    if (this._typeIdToOptionElement.size > 1)
-      this._header.textContent = ls`Select profiling type`;
-    else
-      this._header.textContent = profileType.name;
-  }
-
-  restoreSelectedProfileType() {
-    let typeId = this._selectedProfileTypeSetting.get();
-    if (!this._typeIdToOptionElement.has(typeId))
-      typeId = this._typeIdToOptionElement.keys().next().value;
-    this._typeIdToOptionElement.get(typeId).checked = true;
-    const type = this._typeIdToOptionElement.get(typeId)._profileType;
-    this.dispatchEventToListeners(Profiler.ProfileLauncherView.Events.ProfileTypeSelected, type);
-  }
-
-  _controlButtonClicked() {
-    this._panel.toggleRecord();
-  }
-
-  /**
-   * @param {!Profiler.ProfileType} profileType
-   */
-  _profileTypeChanged(profileType) {
-    this.dispatchEventToListeners(Profiler.ProfileLauncherView.Events.ProfileTypeSelected, profileType);
-    this._isInstantProfile = profileType.isInstantProfile();
-    this._isEnabled = profileType.isEnabled();
-    this._updateControls();
-    this._selectedProfileTypeSetting.set(profileType.id);
-  }
-};
-
-/** @enum {symbol} */
-Profiler.ProfileLauncherView.Events = {
-  ProfileTypeSelected: Symbol('ProfileTypeSelected')
-};
diff --git a/front_end/profiler/ProfileType.js b/front_end/profiler/ProfileType.js
deleted file mode 100644
index a8be4a1..0000000
--- a/front_end/profiler/ProfileType.js
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Profiler.ProfileType = class extends Common.Object {
-  /**
-   * @param {string} id
-   * @param {string} name
-   * @suppressGlobalPropertiesCheck
-   */
-  constructor(id, name) {
-    super();
-    this._id = id;
-    this._name = name;
-    /** @type {!Array.<!Profiler.ProfileHeader>} */
-    this._profiles = [];
-    /** @type {?Profiler.ProfileHeader} */
-    this._profileBeingRecorded = null;
-    this._nextProfileUid = 1;
-
-    if (!window.opener)
-      window.addEventListener('unload', this._clearTempStorage.bind(this), false);
-  }
-
-  /**
-   * @return {string}
-   */
-  typeName() {
-    return '';
-  }
-
-  /**
-   * @return {number}
-   */
-  nextProfileUid() {
-    return this._nextProfileUid;
-  }
-
-  /**
-   * @return {number}
-   */
-  incrementProfileUid() {
-    return this._nextProfileUid++;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasTemporaryView() {
-    return false;
-  }
-
-  /**
-   * @return {?string}
-   */
-  fileExtension() {
-    return null;
-  }
-
-  get buttonTooltip() {
-    return '';
-  }
-
-  get id() {
-    return this._id;
-  }
-
-  get treeItemTitle() {
-    return this._name;
-  }
-
-  get name() {
-    return this._name;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  buttonClicked() {
-    return false;
-  }
-
-  get description() {
-    return '';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInstantProfile() {
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEnabled() {
-    return true;
-  }
-
-  /**
-   * @return {!Array.<!Profiler.ProfileHeader>}
-   */
-  getProfiles() {
-    /**
-     * @param {!Profiler.ProfileHeader} profile
-     * @return {boolean}
-     * @this {Profiler.ProfileType}
-     */
-    function isFinished(profile) {
-      return this._profileBeingRecorded !== profile;
-    }
-    return this._profiles.filter(isFinished.bind(this));
-  }
-
-  /**
-   * @return {?Element}
-   */
-  customContent() {
-    return null;
-  }
-
-  /**
-   * @param {number} uid
-   * @return {?Profiler.ProfileHeader}
-   */
-  getProfile(uid) {
-    for (let i = 0; i < this._profiles.length; ++i) {
-      if (this._profiles[i].uid === uid)
-        return this._profiles[i];
-    }
-    return null;
-  }
-
-  /**
-   * @param {!File} file
-   * @return {!Promise<?Error>}
-   */
-  loadFromFile(file) {
-    let name = file.name;
-    const fileExtension = this.fileExtension();
-    if (fileExtension && name.endsWith(fileExtension))
-      name = name.substr(0, name.length - fileExtension.length);
-    const profile = this.createProfileLoadedFromFile(name);
-    profile.setFromFile();
-    this.setProfileBeingRecorded(profile);
-    this.addProfile(profile);
-    return profile.loadFromFile(file);
-  }
-
-  /**
-   * @param {string} title
-   * @return {!Profiler.ProfileHeader}
-   */
-  createProfileLoadedFromFile(title) {
-    throw new Error('Needs implemented.');
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  addProfile(profile) {
-    this._profiles.push(profile);
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.AddProfileHeader, profile);
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  removeProfile(profile) {
-    const index = this._profiles.indexOf(profile);
-    if (index === -1)
-      return;
-    this._profiles.splice(index, 1);
-    this._disposeProfile(profile);
-  }
-
-  _clearTempStorage() {
-    for (let i = 0; i < this._profiles.length; ++i)
-      this._profiles[i].removeTempFile();
-  }
-
-  /**
-   * @return {?Profiler.ProfileHeader}
-   */
-  profileBeingRecorded() {
-    return this._profileBeingRecorded;
-  }
-
-  /**
-   * @param {?Profiler.ProfileHeader} profile
-   */
-  setProfileBeingRecorded(profile) {
-    this._profileBeingRecorded = profile;
-  }
-
-  profileBeingRecordedRemoved() {
-  }
-
-  reset() {
-    for (const profile of this._profiles.slice())
-      this._disposeProfile(profile);
-    this._profiles = [];
-    this._nextProfileUid = 1;
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  _disposeProfile(profile) {
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.RemoveProfileHeader, profile);
-    profile.dispose();
-    if (this._profileBeingRecorded === profile) {
-      this.profileBeingRecordedRemoved();
-      this.setProfileBeingRecorded(null);
-    }
-  }
-};
-
-/** @enum {symbol} */
-Profiler.ProfileType.Events = {
-  AddProfileHeader: Symbol('add-profile-header'),
-  ProfileComplete: Symbol('profile-complete'),
-  RemoveProfileHeader: Symbol('remove-profile-header'),
-  ViewUpdated: Symbol('view-updated')
-};
-
-/**
- * @interface
- */
-Profiler.ProfileType.DataDisplayDelegate = function() {};
-
-Profiler.ProfileType.DataDisplayDelegate.prototype = {
-  /**
-   * @param {?Profiler.ProfileHeader} profile
-   * @return {?UI.Widget}
-   */
-  showProfile(profile) {},
-
-  /**
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
-   * @param {string} perspectiveName
-   */
-  showObject(snapshotObjectId, perspectiveName) {}
-};
diff --git a/front_end/profiler/ProfileTypeRegistry.js b/front_end/profiler/ProfileTypeRegistry.js
deleted file mode 100644
index 658d327..0000000
--- a/front_end/profiler/ProfileTypeRegistry.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Profiler.ProfileTypeRegistry = class {
-  constructor() {
-    this.cpuProfileType = new Profiler.CPUProfileType();
-    this.heapSnapshotProfileType = new Profiler.HeapSnapshotProfileType();
-    this.samplingHeapProfileType = new Profiler.SamplingHeapProfileType();
-    this.samplingNativeHeapProfileType = new Profiler.SamplingNativeHeapProfileType();
-    this.samplingNativeHeapSnapshotType = new Profiler.SamplingNativeHeapSnapshotType();
-    this.trackingHeapSnapshotProfileType = new Profiler.TrackingHeapSnapshotProfileType();
-  }
-};
-
-Profiler.ProfileTypeRegistry.instance = new Profiler.ProfileTypeRegistry();
diff --git a/front_end/profiler/ProfileView.js b/front_end/profiler/ProfileView.js
deleted file mode 100644
index 11c33fc..0000000
--- a/front_end/profiler/ProfileView.js
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Profiler.ProfileView = class extends UI.SimpleView {
-  constructor() {
-    super(Common.UIString('Profile'));
-
-    this._searchableView = new UI.SearchableView(this);
-    this._searchableView.setPlaceholder(Common.UIString('Find by cost (>50ms), name or file'));
-    this._searchableView.show(this.element);
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([]);
-    columns.push({
-      id: 'self',
-      title: this.columnHeader('self'),
-      width: '120px',
-      fixedWidth: true,
-      sortable: true,
-      sort: DataGrid.DataGrid.Order.Descending
-    });
-    columns.push({id: 'total', title: this.columnHeader('total'), width: '120px', fixedWidth: true, sortable: true});
-    columns.push({id: 'function', title: Common.UIString('Function'), disclosure: true, sortable: true});
-
-    this.dataGrid = new DataGrid.DataGrid(columns);
-    this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortProfile, this);
-    this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._nodeSelected.bind(this, true));
-    this.dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, this._nodeSelected.bind(this, false));
-
-    this.viewSelectComboBox = new UI.ToolbarComboBox(this._changeView.bind(this));
-
-    this.focusButton = new UI.ToolbarButton(Common.UIString('Focus selected function'), 'largeicon-visibility');
-    this.focusButton.setEnabled(false);
-    this.focusButton.addEventListener(UI.ToolbarButton.Events.Click, this._focusClicked, this);
-
-    this.excludeButton = new UI.ToolbarButton(Common.UIString('Exclude selected function'), 'largeicon-delete');
-    this.excludeButton.setEnabled(false);
-    this.excludeButton.addEventListener(UI.ToolbarButton.Events.Click, this._excludeClicked, this);
-
-    this.resetButton = new UI.ToolbarButton(Common.UIString('Restore all functions'), 'largeicon-refresh');
-    this.resetButton.setEnabled(false);
-    this.resetButton.addEventListener(UI.ToolbarButton.Events.Click, this._resetClicked, this);
-
-    this._linkifier = new Components.Linkifier(Profiler.ProfileView._maxLinkLength);
-  }
-
-  /**
-   * @param {!Array<!{title: string, value: string}>} entryInfo
-   * @return {!Element}
-   */
-  static buildPopoverTable(entryInfo) {
-    const table = createElement('table');
-    for (const entry of entryInfo) {
-      const row = table.createChild('tr');
-      row.createChild('td').textContent = entry.title;
-      row.createChild('td').textContent = entry.value;
-    }
-    return table;
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode.Formatter} nodeFormatter
-   * @param {!Array<string>=} viewTypes
-   * @protected
-   */
-  initialize(nodeFormatter, viewTypes) {
-    this._nodeFormatter = nodeFormatter;
-
-    this._viewType = Common.settings.createSetting('profileView', Profiler.ProfileView.ViewTypes.Heavy);
-    viewTypes = viewTypes || [
-      Profiler.ProfileView.ViewTypes.Flame, Profiler.ProfileView.ViewTypes.Heavy, Profiler.ProfileView.ViewTypes.Tree
-    ];
-
-    const optionNames = new Map([
-      [Profiler.ProfileView.ViewTypes.Flame, Common.UIString('Chart')],
-      [Profiler.ProfileView.ViewTypes.Heavy, Common.UIString('Heavy (Bottom Up)')],
-      [Profiler.ProfileView.ViewTypes.Tree, Common.UIString('Tree (Top Down)')],
-    ]);
-
-    const options =
-        new Map(viewTypes.map(type => [type, this.viewSelectComboBox.createOption(optionNames.get(type), '', type)]));
-    const optionName = this._viewType.get() || viewTypes[0];
-    const option = options.get(optionName) || options.get(viewTypes[0]);
-    this.viewSelectComboBox.select(option);
-
-    this._changeView();
-    if (this._flameChart)
-      this._flameChart.update();
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (this._flameChart)
-      this._flameChart.focus();
-    else
-      super.focus();
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {string}
-   */
-  columnHeader(columnId) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {number} timeLeft
-   * @param {number} timeRight
-   */
-  selectRange(timeLeft, timeRight) {
-    if (!this._flameChart)
-      return;
-    this._flameChart.selectRange(timeLeft, timeRight);
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return [this.viewSelectComboBox, this.focusButton, this.excludeButton, this.resetButton];
-  }
-
-  /**
-   * @return {!Profiler.ProfileDataGridTree}
-   */
-  _getBottomUpProfileDataGridTree() {
-    if (!this._bottomUpProfileDataGridTree) {
-      this._bottomUpProfileDataGridTree = new Profiler.BottomUpProfileDataGridTree(
-          this._nodeFormatter, this._searchableView, this.profile.root, this.adjustedTotal);
-    }
-    return this._bottomUpProfileDataGridTree;
-  }
-
-  /**
-   * @return {!Profiler.ProfileDataGridTree}
-   */
-  _getTopDownProfileDataGridTree() {
-    if (!this._topDownProfileDataGridTree) {
-      this._topDownProfileDataGridTree = new Profiler.TopDownProfileDataGridTree(
-          this._nodeFormatter, this._searchableView, this.profile.root, this.adjustedTotal);
-    }
-    return this._topDownProfileDataGridTree;
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._currentSearchResultIndex = -1;
-  }
-
-  refresh() {
-    const selectedProfileNode = this.dataGrid.selectedNode ? this.dataGrid.selectedNode.profileNode : null;
-
-    this.dataGrid.rootNode().removeChildren();
-
-    const children = this.profileDataGridTree.children;
-    const count = children.length;
-
-    for (let index = 0; index < count; ++index)
-      this.dataGrid.rootNode().appendChild(children[index]);
-
-    if (selectedProfileNode)
-      selectedProfileNode.selected = true;
-  }
-
-  refreshVisibleData() {
-    let child = this.dataGrid.rootNode().children[0];
-    while (child) {
-      child.refresh();
-      child = child.traverseNextNode(false, null, true);
-    }
-  }
-
-  /**
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._searchableElement.searchCanceled();
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this._searchableElement.performSearch(searchConfig, shouldJump, jumpBackwards);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    this._searchableElement.jumpToNextSearchResult();
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    this._searchableElement.jumpToPreviousSearchResult();
-  }
-
-  /**
-   * @return {!Components.Linkifier}
-   */
-  linkifier() {
-    return this._linkifier;
-  }
-
-  /**
-   * @return {!PerfUI.FlameChartDataProvider}
-   */
-  createFlameChartDataProvider() {
-    throw 'Not implemented';
-  }
-
-  _ensureFlameChartCreated() {
-    if (this._flameChart)
-      return;
-    this._dataProvider = this.createFlameChartDataProvider();
-    this._flameChart = new Profiler.CPUProfileFlameChart(this._searchableView, this._dataProvider);
-    this._flameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onEntrySelected.bind(this));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onEntrySelected(event) {
-    const entryIndex = event.data;
-    const node = this._dataProvider._entryNodes[entryIndex];
-    const debuggerModel = this._profileHeader._debuggerModel;
-    if (!node || !node.scriptId || !debuggerModel)
-      return;
-    const script = debuggerModel.scriptForId(node.scriptId);
-    if (!script)
-      return;
-    const location = /** @type {!SDK.DebuggerModel.Location} */ (
-        debuggerModel.createRawLocation(script, node.lineNumber, node.columnNumber));
-    Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location));
-  }
-
-  _changeView() {
-    if (!this.profile)
-      return;
-
-    this._searchableView.closeSearch();
-
-    if (this._visibleView)
-      this._visibleView.detach();
-
-    this._viewType.set(this.viewSelectComboBox.selectedOption().value);
-    switch (this._viewType.get()) {
-      case Profiler.ProfileView.ViewTypes.Flame:
-        this._ensureFlameChartCreated();
-        this._visibleView = this._flameChart;
-        this._searchableElement = this._flameChart;
-        break;
-      case Profiler.ProfileView.ViewTypes.Tree:
-        this.profileDataGridTree = this._getTopDownProfileDataGridTree();
-        this._sortProfile();
-        this._visibleView = this.dataGrid.asWidget();
-        this._searchableElement = this.profileDataGridTree;
-        break;
-      case Profiler.ProfileView.ViewTypes.Heavy:
-        this.profileDataGridTree = this._getBottomUpProfileDataGridTree();
-        this._sortProfile();
-        this._visibleView = this.dataGrid.asWidget();
-        this._searchableElement = this.profileDataGridTree;
-        break;
-    }
-
-    const isFlame = this._viewType.get() === Profiler.ProfileView.ViewTypes.Flame;
-    this.focusButton.setVisible(!isFlame);
-    this.excludeButton.setVisible(!isFlame);
-    this.resetButton.setVisible(!isFlame);
-
-    this._visibleView.show(this._searchableView.element);
-  }
-
-  /**
-   * @param {boolean} selected
-   */
-  _nodeSelected(selected) {
-    this.focusButton.setEnabled(selected);
-    this.excludeButton.setEnabled(selected);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _focusClicked(event) {
-    if (!this.dataGrid.selectedNode)
-      return;
-
-    this.resetButton.setEnabled(true);
-    this.profileDataGridTree.focus(this.dataGrid.selectedNode);
-    this.refresh();
-    this.refreshVisibleData();
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuProfileNodeFocused);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _excludeClicked(event) {
-    const selectedNode = this.dataGrid.selectedNode;
-
-    if (!selectedNode)
-      return;
-
-    selectedNode.deselect();
-
-    this.resetButton.setEnabled(true);
-    this.profileDataGridTree.exclude(selectedNode);
-    this.refresh();
-    this.refreshVisibleData();
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuProfileNodeExcluded);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _resetClicked(event) {
-    this.resetButton.setEnabled(false);
-    this.profileDataGridTree.restore();
-    this._linkifier.reset();
-    this.refresh();
-    this.refreshVisibleData();
-  }
-
-  _sortProfile() {
-    const sortAscending = this.dataGrid.isSortOrderAscending();
-    const sortColumnId = this.dataGrid.sortColumnId();
-    const sortProperty = sortColumnId === 'function' ? 'functionName' : sortColumnId || '';
-    this.profileDataGridTree.sort(Profiler.ProfileDataGridTree.propertyComparator(sortProperty, sortAscending));
-
-    this.refresh();
-  }
-};
-
-Profiler.ProfileView._maxLinkLength = 30;
-
-/** @enum {string} */
-Profiler.ProfileView.ViewTypes = {
-  Flame: 'Flame',
-  Tree: 'Tree',
-  Heavy: 'Heavy'
-};
-
-
-/**
- * @implements {Common.OutputStream}
- * @unrestricted
- */
-Profiler.WritableProfileHeader = class extends Profiler.ProfileHeader {
-  /**
-   * @param {?SDK.DebuggerModel} debuggerModel
-   * @param {!Profiler.ProfileType} type
-   * @param {string=} title
-   */
-  constructor(debuggerModel, type, title) {
-    super(type, title || Common.UIString('Profile %d', type.nextProfileUid()));
-    this._debuggerModel = debuggerModel;
-    this._tempFile = null;
-  }
-
-  /**
-   * @param {!Bindings.ChunkedReader} reader
-   */
-  _onChunkTransferred(reader) {
-    this.updateStatus(Common.UIString('Loading\u2026 %d%%', Number.bytesToString(this._jsonifiedProfile.length)));
-  }
-
-  /**
-   * @param {!Bindings.ChunkedReader} reader
-   */
-  _onError(reader) {
-    this.updateStatus(Common.UIString(`File '%s' read error: %s`, reader.fileName(), reader.error().message));
-  }
-
-  /**
-   * @override
-   * @param {string} text
-   * @return {!Promise}
-   */
-  async write(text) {
-    this._jsonifiedProfile += text;
-  }
-
-  /**
-   * @override
-   */
-  close() {
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this.removeTempFile();
-  }
-
-  /**
-   * @override
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} panel
-   * @return {!Profiler.ProfileSidebarTreeElement}
-   */
-  createSidebarTreeElement(panel) {
-    return new Profiler.ProfileSidebarTreeElement(panel, this, 'profile-sidebar-tree-item');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canSaveToFile() {
-    return !this.fromFile() && this._protocolProfile;
-  }
-
-  /**
-   * @override
-   */
-  async saveToFile() {
-    const fileOutputStream = new Bindings.FileOutputStream();
-    this._fileName = this._fileName ||
-        `${this.profileType().typeName()}-${new Date().toISO8601Compact()}${this.profileType().fileExtension()}`;
-    const accepted = await fileOutputStream.open(this._fileName);
-    if (!accepted || !this._tempFile)
-      return;
-    const data = await this._tempFile.read();
-    if (data)
-      await fileOutputStream.write(data);
-    fileOutputStream.close();
-  }
-
-  /**
-   * @override
-   * @param {!File} file
-   * @return {!Promise<?Error>}
-   */
-  async loadFromFile(file) {
-    this.updateStatus(Common.UIString('Loading\u2026'), true);
-    const fileReader = new Bindings.ChunkedFileReader(file, 10000000, this._onChunkTransferred.bind(this));
-    this._jsonifiedProfile = '';
-
-    const success = await fileReader.read(this);
-    if (!success) {
-      this._onError(fileReader);
-      return new Error(Common.UIString('Failed to read file'));
-    }
-
-    this.updateStatus(Common.UIString('Parsing\u2026'), true);
-    let error = null;
-    try {
-      this._profile = /** @type {!Protocol.Profiler.Profile} */ (JSON.parse(this._jsonifiedProfile));
-      this.setProfile(this._profile);
-      this.updateStatus(Common.UIString('Loaded'), false);
-    } catch (e) {
-      error = e;
-      this.profileType().removeProfile(this);
-    }
-    this._jsonifiedProfile = null;
-
-    if (this.profileType().profileBeingRecorded() === this)
-      this.profileType().setProfileBeingRecorded(null);
-    return error;
-  }
-
-  /**
-   * @param {!Protocol.Profiler.Profile} profile
-   */
-  setProtocolProfile(profile) {
-    this.setProfile(profile);
-    this._protocolProfile = profile;
-    this._tempFile = new Bindings.TempFile();
-    this._tempFile.write([JSON.stringify(profile)]);
-    if (this.canSaveToFile())
-      this.dispatchEventToListeners(Profiler.ProfileHeader.Events.ProfileReceived);
-  }
-};
diff --git a/front_end/profiler/ProfilesPanel.js b/front_end/profiler/ProfilesPanel.js
deleted file mode 100644
index 2647061..0000000
--- a/front_end/profiler/ProfilesPanel.js
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Profiler.ProfileType.DataDisplayDelegate}
- * @unrestricted
- */
-Profiler.ProfilesPanel = class extends UI.PanelWithSidebar {
-  /**
-   * @param {string} name
-   * @param {!Array.<!Profiler.ProfileType>} profileTypes
-   * @param {string} recordingActionId
-   */
-  constructor(name, profileTypes, recordingActionId) {
-    super(name);
-    this._profileTypes = profileTypes;
-    this.registerRequiredCSS('profiler/heapProfiler.css');
-    this.registerRequiredCSS('profiler/profilesPanel.css');
-    this.registerRequiredCSS('object_ui/objectValue.css');
-
-    const mainContainer = new UI.VBox();
-    this.splitWidget().setMainWidget(mainContainer);
-
-    this.profilesItemTreeElement = new Profiler.ProfilesSidebarTreeElement(this);
-
-    this._sidebarTree = new UI.TreeOutlineInShadow();
-    this._sidebarTree.registerRequiredCSS('profiler/profilesSidebarTree.css');
-    this._sidebarTree.element.classList.add('profiles-sidebar-tree-box');
-    this.panelSidebarElement().appendChild(this._sidebarTree.element);
-
-    this._sidebarTree.appendChild(this.profilesItemTreeElement);
-
-    this.profileViews = createElement('div');
-    this.profileViews.id = 'profile-views';
-    this.profileViews.classList.add('vbox');
-    mainContainer.element.appendChild(this.profileViews);
-
-    this._toolbarElement = createElementWithClass('div', 'profiles-toolbar');
-    mainContainer.element.insertBefore(this._toolbarElement, mainContainer.element.firstChild);
-
-    this.panelSidebarElement().classList.add('profiles-tree-sidebar');
-    const toolbarContainerLeft = createElementWithClass('div', 'profiles-toolbar');
-    this.panelSidebarElement().insertBefore(toolbarContainerLeft, this.panelSidebarElement().firstChild);
-    const toolbar = new UI.Toolbar('', toolbarContainerLeft);
-
-    this._toggleRecordAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action(recordingActionId));
-    this._toggleRecordButton = UI.Toolbar.createActionButton(this._toggleRecordAction);
-    toolbar.appendToolbarItem(this._toggleRecordButton);
-
-    this.clearResultsButton = new UI.ToolbarButton(Common.UIString('Clear all profiles'), 'largeicon-clear');
-    this.clearResultsButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset, this);
-    toolbar.appendToolbarItem(this.clearResultsButton);
-    toolbar.appendSeparator();
-    toolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));
-
-    this._profileViewToolbar = new UI.Toolbar('', this._toolbarElement);
-
-    this._profileGroups = {};
-    this._launcherView = new Profiler.ProfileLauncherView(this);
-    this._launcherView.addEventListener(
-        Profiler.ProfileLauncherView.Events.ProfileTypeSelected, this._onProfileTypeSelected, this);
-
-    this._profileToView = [];
-    this._typeIdToSidebarSection = {};
-    const types = this._profileTypes;
-    for (let i = 0; i < types.length; i++)
-      this._registerProfileType(types[i]);
-    this._launcherView.restoreSelectedProfileType();
-    this.profilesItemTreeElement.select();
-    this._showLauncherView();
-
-    this._createFileSelectorElement();
-    this.element.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
-
-    this.contentElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
-
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    let handled = false;
-    if (event.key === 'ArrowDown' && !event.altKey)
-      handled = this._sidebarTree.selectNext();
-    else if (event.key === 'ArrowUp' && !event.altKey)
-      handled = this._sidebarTree.selectPrevious();
-    if (handled)
-      event.consume(true);
-  }
-
-  /**
-   * @override
-   * @return {?UI.SearchableView}
-   */
-  searchableView() {
-    return this.visibleView && this.visibleView.searchableView ? this.visibleView.searchableView() : null;
-  }
-
-  _createFileSelectorElement() {
-    if (this._fileSelectorElement)
-      this.element.removeChild(this._fileSelectorElement);
-    this._fileSelectorElement = UI.createFileSelectorElement(this._loadFromFile.bind(this));
-    Profiler.ProfilesPanel._fileSelectorElement = this._fileSelectorElement;
-    this.element.appendChild(this._fileSelectorElement);
-  }
-
-  /**
-   * @param {string} fileName
-   * @return {?Profiler.ProfileType}
-   */
-  _findProfileTypeByExtension(fileName) {
-    return this._profileTypes.find(type => !!type.fileExtension() && fileName.endsWith(type.fileExtension() || '')) ||
-        null;
-  }
-
-  /**
-   * @param {!File} file
-   */
-  async _loadFromFile(file) {
-    this._createFileSelectorElement();
-
-    const profileType = this._findProfileTypeByExtension(file.name);
-    if (!profileType) {
-      const extensions = new Set(this._profileTypes.map(type => type.fileExtension()).filter(ext => ext));
-      Common.console.error(
-          Common.UIString(`Can't load file. Supported file extensions: '%s'.`, Array.from(extensions).join(`', '`)));
-      return;
-    }
-
-    if (!!profileType.profileBeingRecorded()) {
-      Common.console.error(Common.UIString(`Can't load profile while another profile is being recorded.`));
-      return;
-    }
-
-    const error = await profileType.loadFromFile(file);
-    if (error)
-      UI.MessageDialog.show(Common.UIString('Profile loading failed: %s.', error.message));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  toggleRecord() {
-    if (!this._toggleRecordAction.enabled())
-      return true;
-    const type = this._selectedProfileType;
-    const isProfiling = type.buttonClicked();
-    this._updateToggleRecordAction(isProfiling);
-    if (isProfiling) {
-      this._launcherView.profileStarted();
-      if (type.hasTemporaryView())
-        this.showProfile(type.profileBeingRecorded());
-    } else {
-      this._launcherView.profileFinished();
-    }
-    return true;
-  }
-
-  _onSuspendStateChanged() {
-    this._updateToggleRecordAction(this._toggleRecordAction.toggled());
-  }
-
-  /**
-   * @param {boolean} toggled
-   */
-  _updateToggleRecordAction(toggled) {
-    const enable = toggled || !SDK.targetManager.allTargetsSuspended();
-    this._toggleRecordAction.setEnabled(enable);
-    this._toggleRecordAction.setToggled(toggled);
-    if (enable)
-      this._toggleRecordButton.setTitle(this._selectedProfileType ? this._selectedProfileType.buttonTooltip : '');
-    else
-      this._toggleRecordButton.setTitle(UI.anotherProfilerActiveLabel());
-    if (this._selectedProfileType)
-      this._launcherView.updateProfileType(this._selectedProfileType, enable);
-  }
-
-  _profileBeingRecordedRemoved() {
-    this._updateToggleRecordAction(false);
-    this._launcherView.profileFinished();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onProfileTypeSelected(event) {
-    this._selectedProfileType = /** @type {!Profiler.ProfileType} */ (event.data);
-    this._updateProfileTypeSpecificUI();
-  }
-
-  _updateProfileTypeSpecificUI() {
-    this._updateToggleRecordAction(this._toggleRecordAction.toggled());
-  }
-
-  _reset() {
-    this._profileTypes.forEach(type => type.reset());
-
-    delete this.visibleView;
-
-    this._profileGroups = {};
-    this._updateToggleRecordAction(false);
-    this._launcherView.profileFinished();
-
-    this._sidebarTree.element.classList.remove('some-expandable');
-
-    this._launcherView.detach();
-    this.profileViews.removeChildren();
-    this._profileViewToolbar.removeToolbarItems();
-
-    this.clearResultsButton.element.classList.remove('hidden');
-    this.profilesItemTreeElement.select();
-    this._showLauncherView();
-  }
-
-  _showLauncherView() {
-    this.closeVisibleView();
-    this._profileViewToolbar.removeToolbarItems();
-    this._launcherView.show(this.profileViews);
-    this.visibleView = this._launcherView;
-    this._toolbarElement.classList.add('hidden');
-  }
-
-  /**
-   * @param {!Profiler.ProfileType} profileType
-   */
-  _registerProfileType(profileType) {
-    this._launcherView.addProfileType(profileType);
-    const profileTypeSection = new Profiler.ProfileTypeSidebarSection(this, profileType);
-    this._typeIdToSidebarSection[profileType.id] = profileTypeSection;
-    this._sidebarTree.appendChild(profileTypeSection);
-    profileTypeSection.childrenListElement.addEventListener(
-        'contextmenu', this._handleContextMenuEvent.bind(this), false);
-
-    /**
-     * @param {!Common.Event} event
-     * @this {Profiler.ProfilesPanel}
-     */
-    function onAddProfileHeader(event) {
-      this._addProfileHeader(/** @type {!Profiler.ProfileHeader} */ (event.data));
-    }
-
-    /**
-     * @param {!Common.Event} event
-     * @this {Profiler.ProfilesPanel}
-     */
-    function onRemoveProfileHeader(event) {
-      this._removeProfileHeader(/** @type {!Profiler.ProfileHeader} */ (event.data));
-    }
-
-    /**
-     * @param {!Common.Event} event
-     * @this {Profiler.ProfilesPanel}
-     */
-    function profileComplete(event) {
-      this.showProfile(/** @type {!Profiler.ProfileHeader} */ (event.data));
-    }
-
-    profileType.addEventListener(Profiler.ProfileType.Events.ViewUpdated, this._updateProfileTypeSpecificUI, this);
-    profileType.addEventListener(Profiler.ProfileType.Events.AddProfileHeader, onAddProfileHeader, this);
-    profileType.addEventListener(Profiler.ProfileType.Events.RemoveProfileHeader, onRemoveProfileHeader, this);
-    profileType.addEventListener(Profiler.ProfileType.Events.ProfileComplete, profileComplete, this);
-
-    const profiles = profileType.getProfiles();
-    for (let i = 0; i < profiles.length; i++)
-      this._addProfileHeader(profiles[i]);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    if (this.panelSidebarElement().isSelfOrAncestor(event.srcElement)) {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString('Load\u2026'), this._fileSelectorElement.click.bind(this._fileSelectorElement));
-    }
-    contextMenu.show();
-  }
-
-  showLoadFromFileDialog() {
-    this._fileSelectorElement.click();
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  _addProfileHeader(profile) {
-    const profileType = profile.profileType();
-    const typeId = profileType.id;
-    this._typeIdToSidebarSection[typeId].addProfileHeader(profile);
-    if (!this.visibleView || this.visibleView === this._launcherView)
-      this.showProfile(profile);
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  _removeProfileHeader(profile) {
-    if (profile.profileType().profileBeingRecorded() === profile)
-      this._profileBeingRecordedRemoved();
-
-    const i = this._indexOfViewForProfile(profile);
-    if (i !== -1)
-      this._profileToView.splice(i, 1);
-
-    const profileType = profile.profileType();
-    const typeId = profileType.id;
-    const sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileHeader(profile);
-
-    // No other item will be selected if there aren't any other profiles, so
-    // make sure that view gets cleared when the last profile is removed.
-    if (sectionIsEmpty) {
-      this.profilesItemTreeElement.select();
-      this._showLauncherView();
-    }
-  }
-
-  /**
-   * @override
-   * @param {?Profiler.ProfileHeader} profile
-   * @return {?UI.Widget}
-   */
-  showProfile(profile) {
-    if (!profile ||
-        (profile.profileType().profileBeingRecorded() === profile) && !profile.profileType().hasTemporaryView())
-      return null;
-
-    const view = this.viewForProfile(profile);
-    if (view === this.visibleView)
-      return view;
-
-    this.closeVisibleView();
-
-    view.show(this.profileViews);
-    view.focus();
-    this._toolbarElement.classList.remove('hidden');
-    this.visibleView = view;
-
-    const profileTypeSection = this._typeIdToSidebarSection[profile.profileType().id];
-    const sidebarElement = profileTypeSection.sidebarElementForProfile(profile);
-    sidebarElement.revealAndSelect();
-
-    this._profileViewToolbar.removeToolbarItems();
-
-    const toolbarItems = view.syncToolbarItems();
-    for (let i = 0; i < toolbarItems.length; ++i)
-      this._profileViewToolbar.appendToolbarItem(toolbarItems[i]);
-
-    return view;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
-   * @param {string} perspectiveName
-   */
-  showObject(snapshotObjectId, perspectiveName) {
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   * @return {!UI.Widget}
-   */
-  viewForProfile(profile) {
-    const index = this._indexOfViewForProfile(profile);
-    if (index !== -1)
-      return this._profileToView[index].view;
-    const view = profile.createView(this);
-    view.element.classList.add('profile-view');
-    this._profileToView.push({profile: profile, view: view});
-    return view;
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   * @return {number}
-   */
-  _indexOfViewForProfile(profile) {
-    for (let i = 0; i < this._profileToView.length; i++) {
-      if (this._profileToView[i].profile === profile)
-        return i;
-    }
-    return -1;
-  }
-
-  closeVisibleView() {
-    if (this.visibleView)
-      this.visibleView.detach();
-    delete this.visibleView;
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._sidebarTree.focus();
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileTypeSidebarSection = class extends UI.TreeElement {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {!Profiler.ProfileType} profileType
-   */
-  constructor(dataDisplayDelegate, profileType) {
-    super(profileType.treeItemTitle.escapeHTML(), true);
-    this.selectable = false;
-    this._dataDisplayDelegate = dataDisplayDelegate;
-    /** @type {!Array<!Profiler.ProfileSidebarTreeElement>} */
-    this._profileTreeElements = [];
-    /** @type {!Object<string, !Profiler.ProfileTypeSidebarSection.ProfileGroup>} */
-    this._profileGroups = {};
-    this.expand();
-    this.hidden = true;
-    this.setCollapsible(false);
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  addProfileHeader(profile) {
-    this.hidden = false;
-    const profileType = profile.profileType();
-    let sidebarParent = this;
-    const profileTreeElement = profile.createSidebarTreeElement(this._dataDisplayDelegate);
-    this._profileTreeElements.push(profileTreeElement);
-
-    if (!profile.fromFile() && profileType.profileBeingRecorded() !== profile) {
-      const profileTitle = profile.title;
-      let group = this._profileGroups[profileTitle];
-      if (!group) {
-        group = new Profiler.ProfileTypeSidebarSection.ProfileGroup();
-        this._profileGroups[profileTitle] = group;
-      }
-      group.profileSidebarTreeElements.push(profileTreeElement);
-
-      const groupSize = group.profileSidebarTreeElements.length;
-      if (groupSize === 2) {
-        // Make a group UI.TreeElement now that there are 2 profiles.
-        group.sidebarTreeElement =
-            new Profiler.ProfileGroupSidebarTreeElement(this._dataDisplayDelegate, profile.title);
-
-        const firstProfileTreeElement = group.profileSidebarTreeElements[0];
-        // Insert at the same index for the first profile of the group.
-        const index = this.children().indexOf(firstProfileTreeElement);
-        this.insertChild(group.sidebarTreeElement, index);
-
-        // Move the first profile to the group.
-        const selected = firstProfileTreeElement.selected;
-        this.removeChild(firstProfileTreeElement);
-        group.sidebarTreeElement.appendChild(firstProfileTreeElement);
-        if (selected)
-          firstProfileTreeElement.revealAndSelect();
-
-        firstProfileTreeElement.setSmall(true);
-        firstProfileTreeElement.setMainTitle(Common.UIString('Run %d', 1));
-
-        this.treeOutline.element.classList.add('some-expandable');
-      }
-
-      if (groupSize >= 2) {
-        sidebarParent = group.sidebarTreeElement;
-        profileTreeElement.setSmall(true);
-        profileTreeElement.setMainTitle(Common.UIString('Run %d', groupSize));
-      }
-    }
-
-    sidebarParent.appendChild(profileTreeElement);
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   * @return {boolean}
-   */
-  removeProfileHeader(profile) {
-    const index = this._sidebarElementIndex(profile);
-    if (index === -1)
-      return false;
-    const profileTreeElement = this._profileTreeElements[index];
-    this._profileTreeElements.splice(index, 1);
-
-    let sidebarParent = this;
-    const group = this._profileGroups[profile.title];
-    if (group) {
-      const groupElements = group.profileSidebarTreeElements;
-      groupElements.splice(groupElements.indexOf(profileTreeElement), 1);
-      if (groupElements.length === 1) {
-        // Move the last profile out of its group and remove the group.
-        const pos = sidebarParent.children().indexOf(
-            /** @type {!Profiler.ProfileGroupSidebarTreeElement} */ (group.sidebarTreeElement));
-        group.sidebarTreeElement.removeChild(groupElements[0]);
-        this.insertChild(groupElements[0], pos);
-        groupElements[0].setSmall(false);
-        groupElements[0].setMainTitle(profile.title);
-        this.removeChild(group.sidebarTreeElement);
-      }
-      if (groupElements.length !== 0)
-        sidebarParent = group.sidebarTreeElement;
-    }
-    sidebarParent.removeChild(profileTreeElement);
-    profileTreeElement.dispose();
-
-    if (this.childCount())
-      return false;
-    this.hidden = true;
-    return true;
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   * @return {?Profiler.ProfileSidebarTreeElement}
-   */
-  sidebarElementForProfile(profile) {
-    const index = this._sidebarElementIndex(profile);
-    return index === -1 ? null : this._profileTreeElements[index];
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   * @return {number}
-   */
-  _sidebarElementIndex(profile) {
-    const elements = this._profileTreeElements;
-    for (let i = 0; i < elements.length; i++) {
-      if (elements[i].profile === profile)
-        return i;
-    }
-    return -1;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.classList.add('profiles-tree-section');
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileTypeSidebarSection.ProfileGroup = class {
-  constructor() {
-    /** @type {!Array<!Profiler.ProfileSidebarTreeElement>} */
-    this.profileSidebarTreeElements = [];
-    /** @type {?Profiler.ProfileGroupSidebarTreeElement} */
-    this.sidebarTreeElement = null;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileSidebarTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {!Profiler.ProfileHeader} profile
-   * @param {string} className
-   */
-  constructor(dataDisplayDelegate, profile, className) {
-    super('', false);
-    this._iconElement = createElementWithClass('div', 'icon');
-    this._titlesElement = createElementWithClass('div', 'titles no-subtitle');
-    this._titleContainer = this._titlesElement.createChild('span', 'title-container');
-    this._titleElement = this._titleContainer.createChild('span', 'title');
-    this._subtitleElement = this._titlesElement.createChild('span', 'subtitle');
-
-    this._titleElement.textContent = profile.title;
-    this._className = className;
-    this._small = false;
-    this._dataDisplayDelegate = dataDisplayDelegate;
-    this.profile = profile;
-    profile.addEventListener(Profiler.ProfileHeader.Events.UpdateStatus, this._updateStatus, this);
-    if (profile.canSaveToFile())
-      this._createSaveLink();
-    else
-      profile.addEventListener(Profiler.ProfileHeader.Events.ProfileReceived, this._onProfileReceived, this);
-  }
-
-  _createSaveLink() {
-    this._saveLinkElement = this._titleContainer.createChild('span', 'save-link');
-    this._saveLinkElement.textContent = Common.UIString('Save');
-    this._saveLinkElement.addEventListener('click', this._saveProfile.bind(this), false);
-  }
-
-  _onProfileReceived(event) {
-    this._createSaveLink();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _updateStatus(event) {
-    const statusUpdate = event.data;
-    if (statusUpdate.subtitle !== null) {
-      this._subtitleElement.textContent = statusUpdate.subtitle || '';
-      this._titlesElement.classList.toggle('no-subtitle', !statusUpdate.subtitle);
-    }
-    if (typeof statusUpdate.wait === 'boolean' && this.listItemElement)
-      this.listItemElement.classList.toggle('wait', statusUpdate.wait);
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  ondblclick(event) {
-    if (!this._editing)
-      this._startEditing(/** @type {!Element} */ (event.target));
-    return false;
-  }
-
-  /**
-   * @param {!Element} eventTarget
-   */
-  _startEditing(eventTarget) {
-    const container = eventTarget.enclosingNodeOrSelfWithClass('title');
-    if (!container)
-      return;
-    const config = new UI.InplaceEditor.Config(this._editingCommitted.bind(this), this._editingCancelled.bind(this));
-    this._editing = UI.InplaceEditor.startEditing(container, config);
-  }
-
-  /**
-   * @param {!Element} container
-   * @param {string} newTitle
-   */
-  _editingCommitted(container, newTitle) {
-    delete this._editing;
-    this.profile.setTitle(newTitle);
-  }
-
-  _editingCancelled() {
-    delete this._editing;
-  }
-
-  dispose() {
-    this.profile.removeEventListener(Profiler.ProfileHeader.Events.UpdateStatus, this._updateStatus, this);
-    this.profile.removeEventListener(Profiler.ProfileHeader.Events.ProfileReceived, this._onProfileReceived, this);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect() {
-    this._dataDisplayDelegate.showProfile(this.profile);
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondelete() {
-    this.profile.profileType().removeProfile(this.profile);
-    return true;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    if (this._className)
-      this.listItemElement.classList.add(this._className);
-    if (this._small)
-      this.listItemElement.classList.add('small');
-    this.listItemElement.appendChildren(this._iconElement, this._titlesElement);
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    const profile = this.profile;
-    const contextMenu = new UI.ContextMenu(event);
-    // FIXME: use context menu provider
-    contextMenu.headerSection().appendItem(
-        Common.UIString('Load\u2026'),
-        Profiler.ProfilesPanel._fileSelectorElement.click.bind(Profiler.ProfilesPanel._fileSelectorElement));
-    if (profile.canSaveToFile())
-      contextMenu.saveSection().appendItem(Common.UIString('Save\u2026'), profile.saveToFile.bind(profile));
-    contextMenu.footerSection().appendItem(Common.UIString('Delete'), this.ondelete.bind(this));
-    contextMenu.show();
-  }
-
-  _saveProfile(event) {
-    this.profile.saveToFile();
-  }
-
-  /**
-   * @param {boolean} small
-   */
-  setSmall(small) {
-    this._small = small;
-    if (this.listItemElement)
-      this.listItemElement.classList.toggle('small', this._small);
-  }
-
-  /**
-   * @param {string} title
-   */
-  setMainTitle(title) {
-    this._titleElement.textContent = title;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileGroupSidebarTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @param {string} title
-   */
-  constructor(dataDisplayDelegate, title) {
-    super('', true);
-    this.selectable = false;
-    this._dataDisplayDelegate = dataDisplayDelegate;
-    this._title = title;
-    this.expand();
-    this.toggleOnClick = true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect() {
-    const hasChildren = this.childCount() > 0;
-    if (hasChildren)
-      this._dataDisplayDelegate.showProfile(this.lastChild().profile);
-    return hasChildren;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.classList.add('profile-group-sidebar-tree-item');
-    this.listItemElement.createChild('div', 'icon');
-    this.listItemElement.createChild('div', 'titles no-subtitle')
-        .createChild('span', 'title-container')
-        .createChild('span', 'title')
-        .textContent = this._title;
-  }
-};
-
-Profiler.ProfilesSidebarTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Profiler.ProfilesPanel} panel
-   */
-  constructor(panel) {
-    super('', false);
-    this.selectable = true;
-    this._panel = panel;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect() {
-    this._panel._showLauncherView();
-    return true;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.classList.add('profile-launcher-view-tree-item');
-    this.listItemElement.createChild('div', 'icon');
-    this.listItemElement.createChild('div', 'titles no-subtitle')
-        .createChild('span', 'title-container')
-        .createChild('span', 'title')
-        .textContent = Common.UIString('Profiles');
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Profiler.JSProfilerPanel = class extends Profiler.ProfilesPanel {
-  constructor() {
-    const registry = Profiler.ProfileTypeRegistry.instance;
-    super('js_profiler', [registry.cpuProfileType], 'profiler.js-toggle-recording');
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Profiler.JSProfilerPanel, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.context.setFlavor(Profiler.JSProfilerPanel, null);
-  }
-
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const panel = UI.context.flavor(Profiler.JSProfilerPanel);
-    console.assert(panel && panel instanceof Profiler.JSProfilerPanel);
-    panel.toggleRecord();
-    return true;
-  }
-};
diff --git a/front_end/profiler/TopDownProfileDataGrid.js b/front_end/profiler/TopDownProfileDataGrid.js
deleted file mode 100644
index b073b7e..0000000
--- a/front_end/profiler/TopDownProfileDataGrid.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2009 280 North Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Profiler.TopDownProfileDataGridNode = class extends Profiler.ProfileDataGridNode {
-  /**
-   * @param {!SDK.ProfileNode} profileNode
-   * @param {!Profiler.TopDownProfileDataGridTree} owningTree
-   */
-  constructor(profileNode, owningTree) {
-    const hasChildren = !!(profileNode.children && profileNode.children.length);
-
-    super(profileNode, owningTree, hasChildren);
-
-    this._remainingChildren = profileNode.children;
-  }
-
-  /**
-   * @param {!Profiler.TopDownProfileDataGridNode|!Profiler.TopDownProfileDataGridTree} container
-   */
-  static _sharedPopulate(container) {
-    const children = container._remainingChildren;
-    const childrenLength = children.length;
-
-    for (let i = 0; i < childrenLength; ++i) {
-      container.appendChild(new Profiler.TopDownProfileDataGridNode(
-          children[i], /** @type {!Profiler.TopDownProfileDataGridTree} */ (container.tree)));
-    }
-
-    container._remainingChildren = null;
-  }
-
-  /**
-   * @param {!Profiler.TopDownProfileDataGridNode|!Profiler.TopDownProfileDataGridTree} container
-   * @param {string} aCallUID
-   */
-  static _excludeRecursively(container, aCallUID) {
-    if (container._remainingChildren)
-      container.populate();
-
-    container.save();
-
-    const children = container.children;
-    let index = container.children.length;
-
-    while (index--)
-      Profiler.TopDownProfileDataGridNode._excludeRecursively(children[index], aCallUID);
-
-    const child = container.childrenByCallUID.get(aCallUID);
-
-    if (child)
-      Profiler.ProfileDataGridNode.merge(container, child, true);
-  }
-
-  /**
-   * @override
-   */
-  populateChildren() {
-    Profiler.TopDownProfileDataGridNode._sharedPopulate(this);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Profiler.TopDownProfileDataGridTree = class extends Profiler.ProfileDataGridTree {
-  /**
-   * @param {!Profiler.ProfileDataGridNode.Formatter} formatter
-   * @param {!UI.SearchableView} searchableView
-   * @param {!SDK.ProfileNode} rootProfileNode
-   * @param {number} total
-   */
-  constructor(formatter, searchableView, rootProfileNode, total) {
-    super(formatter, searchableView, total);
-    this._remainingChildren = rootProfileNode.children;
-    Profiler.ProfileDataGridNode.populate(this);
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
-   */
-  focus(profileDataGridNode) {
-    if (!profileDataGridNode)
-      return;
-
-    this.save();
-    profileDataGridNode.savePosition();
-
-    this.children = [profileDataGridNode];
-    this.total = profileDataGridNode.total;
-  }
-
-  /**
-   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
-   */
-  exclude(profileDataGridNode) {
-    if (!profileDataGridNode)
-      return;
-
-    this.save();
-
-    Profiler.TopDownProfileDataGridNode._excludeRecursively(this, profileDataGridNode.callUID);
-
-    if (this.lastComparator)
-      this.sort(this.lastComparator, true);
-  }
-
-  /**
-   * @override
-   */
-  restore() {
-    if (!this._savedChildren)
-      return;
-
-    this.children[0].restorePosition();
-
-    super.restore();
-  }
-
-  /**
-   * @override
-   */
-  populateChildren() {
-    Profiler.TopDownProfileDataGridNode._sharedPopulate(this);
-  }
-};
diff --git a/front_end/profiler/heapProfiler.css b/front_end/profiler/heapProfiler.css
deleted file mode 100644
index b60620d..0000000
--- a/front_end/profiler/heapProfiler.css
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.heap-snapshot-view {
-    overflow: hidden;
-}
-
-.heap-snapshot-view .data-grid {
-    border: none;
-}
-
-.heap-snapshot-view .data-grid tr:empty {
-    height: 16px;
-    visibility: hidden;
-}
-
-.heap-snapshot-view .data-grid span.percent-column {
-    width: 35px !important;
-}
-
-.heap-snapshot-view .object-value-object,
-.object-value-node {
-    display: inline;
-    position: static;
-}
-
-.detached-dom-tree-node {
-    background-color: #FF9999;
-}
-
-.heap-snapshot-view .object-value-string {
-    white-space: nowrap;
-}
-
-.heap-snapshot-view tr:not(.selected) .object-value-id {
-    color: grey;
-}
-
-.heap-snapshot-view .data-grid {
-    flex: auto;
-}
-
-.heap-snapshot-view .heap-tracking-overview {
-    flex: 0 0 80px;
-    height: 80px;
-}
-
-.heap-snapshot-view .retaining-paths-view {
-    overflow: hidden;
-}
-
-.heap-snapshot-view .heap-snapshot-view-resizer {
-    background-image: url(Images/toolbarResizerVertical.png);
-    background-color: #eee;
-    border-bottom: 1px solid rgb(179, 179, 179);
-    background-repeat: no-repeat;
-    background-position: right center, center;
-    flex: 0 0 21px;
-}
-
-.heap-snapshot-view .heap-snapshot-view-resizer .title > span {
-    display: inline-block;
-    padding-top: 3px;
-    vertical-align: middle;
-    margin-left: 4px;
-    margin-right: 8px;
-}
-
-.heap-snapshot-view .heap-snapshot-view-resizer * {
-    pointer-events: none;
-}
-
-.heap-snapshot-view tr:not(.selected) td.object-column span.highlight {
-    background-color: rgb(255, 255, 200);
-}
-
-.heap-snapshot-view td.object-column span.grayed {
-    color: gray;
-}
-
-.cycled-ancessor-node {
-    opacity: 0.6;
-}
-
-#heap-recording-view .heap-snapshot-view {
-    top: 80px;
-}
-
-.heap-overview-container {
-    overflow: hidden;
-    position: absolute;
-    top: 0;
-    width: 100%;
-    height: 80px;
-}
-
-#heap-recording-overview-grid .resources-dividers-label-bar {
-    pointer-events: auto;
-}
-
-#heap-recording-overview-container {
-    border-bottom: 1px solid rgba(0, 0, 0, 0.3);
-}
-
-.heap-recording-overview-canvas {
-    position: absolute;
-    top: 20px;
-    left: 0;
-    right: 0;
-    bottom: 0;
-}
-
-.heap-snapshot-statistics-view {
-    overflow: auto;
-}
-
-.heap-snapshot-stats-pie-chart {
-    margin: 12px 30px;
-    flex-shrink: 0;
-}
-
-.heap-snapshot-stats-legend {
-    margin-left: 24px;
-    flex-shrink: 0;
-}
-
-.heap-snapshot-stats-legend > div {
-    margin-top: 1px;
-    width: 170px;
-}
-
-.heap-snapshot-stats-swatch {
-    display: inline-block;
-    width: 10px;
-    height: 10px;
-    border: 1px solid rgba(100, 100, 100, 0.3);
-}
-
-.heap-snapshot-stats-swatch.heap-snapshot-stats-empty-swatch {
-    border: none;
-}
-
-.heap-snapshot-stats-name,
-.heap-snapshot-stats-size {
-    display: inline-block;
-    margin-left: 6px;
-}
-
-.heap-snapshot-stats-size {
-    float: right;
-    text-align: right;
-}
-
-.heap-allocation-stack .stack-frame {
-    display: flex;
-    justify-content: space-between;
-    border-bottom: 1px solid rgb(240, 240, 240);
-    padding: 2px;
-}
-
-.heap-allocation-stack .stack-frame .devtools-link {
-    color: rgb(33%, 33%, 33%);
-}
-
-.no-heap-allocation-stack {
-    padding: 5px;
-}
diff --git a/front_end/profiler/module.json b/front_end/profiler/module.json
deleted file mode 100644
index aa037d8..0000000
--- a/front_end/profiler/module.json
+++ /dev/null
@@ -1,110 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "heap_profiler",
-            "title": "Memory",
-            "order": 60,
-            "className": "Profiler.HeapProfilerPanel"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "SDK.RemoteObject"
-            ],
-            "className": "Profiler.HeapProfilerPanel"
-        },
-        {
-            "type": "setting",
-            "category": "Performance",
-            "title": "High resolution CPU profiling",
-            "settingName": "highResolutionCpuProfiling",
-            "settingType": "boolean",
-            "defaultValue": true
-        },
-        {
-            "type": "setting",
-            "category": "Performance",
-            "title": "Show native functions in JS Profile",
-            "settingName": "showNativeFunctionsInJSProfile",
-            "settingType": "boolean",
-            "defaultValue": true
-        },
-        {
-            "type": "action",
-            "actionId": "profiler.heap-toggle-recording",
-            "iconClass": "largeicon-start-recording",
-            "toggledIconClass": "largeicon-stop-recording",
-            "toggleWithRedColor": true,
-            "contextTypes": [
-                "Profiler.HeapProfilerPanel"
-            ],
-            "className": "Profiler.HeapProfilerPanel",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+E"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+E"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "profiler.js-toggle-recording",
-            "iconClass": "largeicon-start-recording",
-            "toggledIconClass": "largeicon-stop-recording",
-            "toggleWithRedColor": true,
-            "contextTypes": [
-                "Profiler.JSProfilerPanel"
-            ],
-            "className": "Profiler.JSProfilerPanel",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+E"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+E"
-                }
-            ]
-        }
-    ],
-    "dependencies": [
-        "components",
-        "perf_ui",
-        "data_grid",
-        "heap_snapshot_model",
-        "object_ui"
-    ],
-    "scripts": [
-        "ProfileType.js",
-        "ProfileHeader.js",
-        "ProfilesPanel.js",
-        "ProfileView.js",
-        "ProfileDataGrid.js",
-        "BottomUpProfileDataGrid.js",
-        "TopDownProfileDataGrid.js",
-        "CPUProfileFlameChart.js",
-        "CPUProfileView.js",
-        "HeapProfileView.js",
-        "HeapSnapshotProxy.js",
-        "HeapSnapshotDataGrids.js",
-        "HeapSnapshotGridNodes.js",
-        "HeapSnapshotView.js",
-        "HeapProfilerPanel.js",
-        "IsolateSelector.js",
-        "ProfileLauncherView.js",
-        "ProfileTypeRegistry.js"
-    ],
-    "resources": [
-        "heapProfiler.css",
-        "profileLauncherView.css",
-        "profilesPanel.css",
-        "profilesSidebarTree.css"
-    ]
-}
diff --git a/front_end/profiler/profileLauncherView.css b/front_end/profiler/profileLauncherView.css
deleted file mode 100644
index 207dee2..0000000
--- a/front_end/profiler/profileLauncherView.css
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.profile-isolate-item {
-    padding: 4px;
-    line-height: 16px;
-    border-left: 2px solid transparent;
-    overflow-x: hidden;
-}
-
-.profile-isolate-item:hover {
-    background-color: hsla(0, 0%, 0%, 0.05);
-}
-
-.profile-isolate-item.selected {
-    border-color: #4285f4;
-    background-color: #4285f420;
-}
-
-.profile-isolate-item > div {
-    flex-shrink: 0;
-    margin-left: 9px;
-}
-
-.profile-isolate-item-heap {
-    width: 120px;
-}
diff --git a/front_end/profiler/profilesPanel.css b/front_end/profiler/profilesPanel.css
deleted file mode 100644
index de3964e..0000000
--- a/front_end/profiler/profilesPanel.css
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Profiler Style */
-
-#profile-views {
-    flex: auto;
-    position: relative;
-}
-
-.profile-view .data-grid table.data {
-    background: white;
-}
-
-.profile-view .data-grid tr:not(.selected) .highlight {
-    background-color: rgb(255, 230, 179);
-}
-
-.profile-view .data-grid tr:hover td:not(.bottom-filler-td) {
-    background-color: rgba(0, 0, 0, 0.1);
-}
-
-.profile-view .data-grid td.numeric-column {
-    text-align: right;
-}
-
-.profile-view .data-grid div.profile-multiple-values {
-    float: right;
-}
-
-.profile-view .data-grid span.percent-column {
-    color: #999;
-    width: 50px;
-    display: inline-block;
-}
-
-.profile-view .data-grid tr.selected span {
-    color: inherit;
-}
-
-.profiles-toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: 1px solid #ccc;
-    flex-shrink: 0;
-}
-
-.profiles-tree-sidebar {
-    flex: auto;
-    overflow: hidden;
-}
-
-.profiles-sidebar-tree-box {
-    overflow-y: auto;
-}
-
-.profile-view {
-    display: flex;
-    overflow: hidden;
-}
-
-.profile-view .data-grid {
-    border: none;
-    flex: auto;
-}
-
-.profile-view .data-grid th.self-column,
-.profile-view .data-grid th.total-column {
-    text-align: center;
-}
-
-.profile-node-file {
-    float: right;
-    color: gray;
-}
-
-.profile-warn-marker {
-    vertical-align: -1px;
-    margin-right: 2px;
-}
-
-.data-grid tr.selected .profile-node-file {
-    color: rgb(33%, 33%, 33%);
-}
-
-.data-grid:focus tr.selected .profile-node-file {
-    color: white;
-}
-
-.profile-launcher-view-content {
-    padding: 10px 16px;
-    overflow: auto;
-}
-
-.profile-launcher-view-content h1 {
-    font-size: 15px;
-    font-weight: normal;
-    padding: 6px 0;
-    margin: 0 0 5px 0;
-}
-
-.profile-launcher-view-content label {
-    font-size: 13px;
-}
-
-.profile-launcher-control {
-    align-items: center;
-    flex-wrap: wrap;
-}
-
-.profile-launcher-control {
-    margin-top: 10px;
-    margin-right: 6px;
-}
-
-.profile-launcher-control button {
-    min-width: 110px;
-}
-
-.profile-launcher-target-list {
-    width: 100%;
-    height: 150px;
-    margin-bottom: 10px;
-    border: 1px solid #ddd;
-}
-
-.profile-launcher-target {
-    align-items: baseline;
-}
-
-.profile-launcher-target > * {
-    flex: 0 0 auto;
-    margin-right: 8px;
-}
-
-.profile-launcher-view-content p {
-    color: grey;
-    margin-top: 1px;
-    margin-left: 22px;
-}
-
-.profile-launcher-view-content p label {
-    display: flex;
-}
-
-.profile-launcher-view-content button.running {
-    color: hsl(0, 100%, 58%);
-}
-
-.profile-launcher-view-content button.running:hover {
-    color: hsl(0, 100%, 42%);
-}
-
-body.inactive .profile-launcher-view-content button.running:not(.toolbar-item) {
-    color: rgb(220, 130, 130);
-}
-
-.highlighted-row {
-    -webkit-animation: row_highlight 2s 0s;
-}
-
-@-webkit-keyframes row_highlight {
-    from {background-color: rgba(255, 255, 120, 1); }
-    to { background-color: rgba(255, 255, 120, 0); }
-}
-
-.profile-canvas-decoration label[is=dt-icon-label] {
-    margin-right: 4px;
-}
-
-.profile-canvas-decoration {
-    color: red;
-    margin: -14px 0 13px 22px;
-    padding-left: 14px;
-}
-
-.profile-canvas-decoration button {
-    margin: 0 0 0 10px !important;
-}
-
-.profile-launcher-button {
-    min-width: 120px;
-    height: 28px;
-    margin: 8px 16px 8px 0;
-}
-
-.cpu-profile-flame-chart-overview-container {
-    overflow: hidden;
-    position: absolute;
-    top: 0;
-    width: 100%;
-    height: 80px;
-}
-
-#cpu-profile-flame-chart-overview-container {
-    border-bottom: 1px solid rgba(0, 0, 0, 0.3);
-}
-
-.cpu-profile-flame-chart-overview-canvas {
-    position: absolute;
-    top: 20px;
-    left: 0;
-    right: 0;
-    bottom: 0;
-}
-
-#cpu-profile-flame-chart-overview-grid .resources-dividers-label-bar {
-    pointer-events: auto;
-}
-
-.cpu-profile-flame-chart-overview-pane {
-    flex: 0 0 80px !important;
-}
diff --git a/front_end/profiler/profilesSidebarTree.css b/front_end/profiler/profilesSidebarTree.css
deleted file mode 100644
index ff2eb84..0000000
--- a/front_end/profiler/profilesSidebarTree.css
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Tree outline overrides */
-
-:host {
-    padding: 0;
-}
-
-ol.tree-outline {
-    overflow: auto;
-    flex: auto;
-    padding: 0;
-    margin: 0;
-}
-
-.tree-outline li {
-    height: 36px;
-    padding-right: 5px;
-    margin-top: 1px;
-    line-height: 34px;
-    border-top: 1px solid transparent;
-}
-
-.tree-outline li:not(.parent)::before {
-    display: none;
-}
-
-:host-context(.some-expandable) .tree-outline li:not(.parent) {
-    margin-left: 10px;
-}
-
-.tree-outline li.profiles-tree-section {
-    height: 18px;
-    padding: 0 10px;
-    white-space: nowrap;
-    margin-top: 1px;
-    color: rgb(92, 110, 129);
-    text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
-    line-height: 18px;
-}
-
-.tree-outline li.profiles-tree-section::before {
-    display: none;
-}
-
-.tree-outline ol {
-    overflow: hidden;
-}
-
-/* Generic items styling */
-
-.title-container > .save-link {
-    text-decoration: underline;
-    margin-left: auto;
-    display: none;
-}
-
-li.selected .title-container > .save-link {
-    display: block;
-    cursor: pointer;
-}
-
-.tree-outline > .icon {
-    margin-left: 16px;
-}
-
-li .icon {
-    width: 32px;
-    height: 32px;
-    margin-top: 1px;
-    margin-right: 3px;
-    flex: none;
-}
-
-li.wait .icon {
-    content: none;
-}
-
-li.wait .icon::before {
-    display: block;
-    width: 24px;
-    height: 24px;
-    margin: 4px;
-    border: 3px solid grey;
-    border-radius: 12px;
-    clip: rect(0, 15px, 15px, 0);
-    content: "";
-    position: absolute;
-    -webkit-animation: spinner-animation 1s linear infinite;
-    box-sizing: border-box;
-}
-
-li.wait.small .icon::before {
-    width: 14px;
-    height: 14px;
-    margin: 1px;
-    clip: rect(0, 9px, 9px, 0);
-    border-width: 2px;
-}
-
-li.wait.selected .icon::before {
-    border-color: white;
-}
-
-@-webkit-keyframes spinner-animation {
-    from { transform: rotate(0); }
-    to { transform: rotate(360deg); }
-}
-
-li.small {
-    height: 20px;
-}
-
-li.small .icon {
-    width: 16px;
-    height: 16px;
-}
-
-li .titles {
-    display: flex;
-    flex-direction: column;
-    top: 5px;
-    line-height: 12px;
-    padding-bottom: 1px;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-    flex: auto;
-}
-
-li .titles > .title-container {
-    display: flex;
-}
-
-li.small .titles {
-    top: 2px;
-    line-height: normal;
-}
-
-li:not(.small) .title::after {
-    content: "\A";
-    white-space: pre;
-}
-
-li .subtitle {
-    font-size: 80%;
-}
-
-li.small .subtitle {
-    display: none;
-}
-
-/* Heap profiles */
-
-.heap-snapshot-sidebar-tree-item .icon {
-    content: url(Images/profileIcon.png);
-}
-
-.heap-snapshot-sidebar-tree-item.small .icon {
-    content: url(Images/profileSmallIcon.png);
-}
-
-/* Launcher */
-
-.profile-launcher-view-tree-item {
-    margin-left: 0 !important;
-}
-
-.profile-launcher-view-tree-item > .icon {
-    width: 8px !important;
-    visibility: hidden;
-}
-
-/* CPU profiles */
-
-.profile-sidebar-tree-item .icon {
-    content: url(Images/profileIcon.png);
-}
-
-.profile-sidebar-tree-item.small .icon {
-    content: url(Images/profileSmallIcon.png);
-}
-
-.profile-group-sidebar-tree-item .icon {
-    content: url(Images/profileGroupIcon.png);
-}
diff --git a/front_end/protocol/InspectorBackend.js b/front_end/protocol/InspectorBackend.js
deleted file mode 100644
index b73d299..0000000
--- a/front_end/protocol/InspectorBackend.js
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @typedef {string} */
-Protocol.Error = Symbol('Protocol.Error');
-
-/**
- * @unrestricted
- */
-Protocol.InspectorBackend = class {
-  constructor() {
-    this._agentPrototypes = {};
-    this._dispatcherPrototypes = {};
-    this._initialized = false;
-  }
-
-  /**
-   * @param {string} error
-   * @param {!Object} messageObject
-   */
-  static reportProtocolError(error, messageObject) {
-    console.error(error + ': ' + JSON.stringify(messageObject));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInitialized() {
-    return this._initialized;
-  }
-
-  /**
-   * @param {string} domain
-   */
-  _addAgentGetterMethodToProtocolTargetPrototype(domain) {
-    let upperCaseLength = 0;
-    while (upperCaseLength < domain.length && domain[upperCaseLength].toLowerCase() !== domain[upperCaseLength])
-      ++upperCaseLength;
-
-    const methodName = domain.substr(0, upperCaseLength).toLowerCase() + domain.slice(upperCaseLength) + 'Agent';
-
-    /**
-     * @this {Protocol.TargetBase}
-     */
-    function agentGetter() {
-      return this._agents[domain];
-    }
-
-    Protocol.TargetBase.prototype[methodName] = agentGetter;
-
-    /**
-     * @this {Protocol.TargetBase}
-     */
-    function registerDispatcher(dispatcher) {
-      this.registerDispatcher(domain, dispatcher);
-    }
-
-    Protocol.TargetBase.prototype['register' + domain + 'Dispatcher'] = registerDispatcher;
-  }
-
-  /**
-   * @param {string} domain
-   * @return {!Protocol.InspectorBackend._AgentPrototype}
-   */
-  _agentPrototype(domain) {
-    if (!this._agentPrototypes[domain]) {
-      this._agentPrototypes[domain] = new Protocol.InspectorBackend._AgentPrototype(domain);
-      this._addAgentGetterMethodToProtocolTargetPrototype(domain);
-    }
-
-    return this._agentPrototypes[domain];
-  }
-
-  /**
-   * @param {string} domain
-   * @return {!Protocol.InspectorBackend._DispatcherPrototype}
-   */
-  _dispatcherPrototype(domain) {
-    if (!this._dispatcherPrototypes[domain])
-      this._dispatcherPrototypes[domain] = new Protocol.InspectorBackend._DispatcherPrototype();
-    return this._dispatcherPrototypes[domain];
-  }
-
-  /**
-   * @param {string} method
-   * @param {!Array.<!Object>} signature
-   * @param {!Array.<string>} replyArgs
-   * @param {boolean} hasErrorData
-   */
-  registerCommand(method, signature, replyArgs, hasErrorData) {
-    const domainAndMethod = method.split('.');
-    this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod[1], signature, replyArgs, hasErrorData);
-    this._initialized = true;
-  }
-
-  /**
-   * @param {string} type
-   * @param {!Object} values
-   */
-  registerEnum(type, values) {
-    const domainAndName = type.split('.');
-    const domain = domainAndName[0];
-    if (!Protocol[domain])
-      Protocol[domain] = {};
-
-    Protocol[domain][domainAndName[1]] = values;
-    this._initialized = true;
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {!Object} params
-   */
-  registerEvent(eventName, params) {
-    const domain = eventName.split('.')[0];
-    this._dispatcherPrototype(domain).registerEvent(eventName, params);
-    this._initialized = true;
-  }
-
-  /**
-   * @param {function(T)} clientCallback
-   * @param {string} errorPrefix
-   * @param {function(new:T,S)=} constructor
-   * @param {T=} defaultValue
-   * @return {function(?string, S)}
-   * @template T,S
-   */
-  wrapClientCallback(clientCallback, errorPrefix, constructor, defaultValue) {
-    /**
-     * @param {?string} error
-     * @param {S} value
-     * @template S
-     */
-    function callbackWrapper(error, value) {
-      if (error) {
-        console.error(errorPrefix + error);
-        clientCallback(defaultValue);
-        return;
-      }
-      if (constructor)
-        clientCallback(new constructor(value));
-      else
-        clientCallback(value);
-    }
-    return callbackWrapper;
-  }
-};
-
-Protocol.InspectorBackend._ConnectionClosedErrorCode = -32000;
-Protocol.InspectorBackend.DevToolsStubErrorCode = -32015;
-
-
-Protocol.inspectorBackend = new Protocol.InspectorBackend();
-
-/**
- * @interface
- */
-Protocol.InspectorBackend.Connection = function() {};
-
-Protocol.InspectorBackend.Connection.prototype = {
-  /**
-   * @param {string} message
-   */
-  sendMessage(message) {},
-
-  /**
-   * @return {!Promise}
-   */
-  disconnect() {},
-};
-
-/**
- * @typedef {!{
- *   onMessage: function((!Object|string)),
- *   onDisconnect: function(string)
- * }}
- */
-Protocol.InspectorBackend.Connection.Params;
-
-/**
- * @typedef {function(!Protocol.InspectorBackend.Connection.Params):!Protocol.InspectorBackend.Connection}
- */
-Protocol.InspectorBackend.Connection.Factory;
-
-/**
- * @unrestricted
- */
-Protocol.TargetBase = class extends Common.Object {
-  /**
-   *  @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory
-   */
-  constructor(connectionFactory) {
-    super();
-    this._connection =
-        connectionFactory({onMessage: this._onMessage.bind(this), onDisconnect: this._onDisconnect.bind(this)});
-    this._lastMessageId = 1;
-    this._pendingResponsesCount = 0;
-    this._agents = {};
-    this._dispatchers = {};
-    this._callbacks = {};
-    this._initialize(Protocol.inspectorBackend._agentPrototypes, Protocol.inspectorBackend._dispatcherPrototypes);
-    this._domainToLogger = new Map();
-    if (!Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches) {
-      Protocol.InspectorBackend.deprecatedRunAfterPendingDispatches =
-          this._deprecatedRunAfterPendingDispatches.bind(this);
-    }
-    if (!Protocol.InspectorBackend.sendRawMessageForTesting)
-      Protocol.InspectorBackend.sendRawMessageForTesting = this._sendRawMessageForTesting.bind(this);
-  }
-
-  /**
-   * @param {!Object.<string, !Protocol.InspectorBackend._AgentPrototype>} agentPrototypes
-   * @param {!Object.<string, !Protocol.InspectorBackend._DispatcherPrototype>} dispatcherPrototypes
-   */
-  _initialize(agentPrototypes, dispatcherPrototypes) {
-    for (const domain in agentPrototypes) {
-      this._agents[domain] = Object.create(agentPrototypes[domain]);
-      this._agents[domain].setTarget(this);
-    }
-
-    for (const domain in dispatcherPrototypes) {
-      this._dispatchers[domain] = Object.create(dispatcherPrototypes[domain]);
-      this._dispatchers[domain].initialize();
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  _nextMessageId() {
-    return this._lastMessageId++;
-  }
-
-  /**
-   * @param {string} domain
-   * @return {!Protocol.InspectorBackend._AgentPrototype}
-   */
-  _agent(domain) {
-    return this._agents[domain];
-  }
-
-  /**
-   * @param {string} domain
-   * @param {string} method
-   * @param {?Object} params
-   * @param {?function(*)} callback
-   */
-  _wrapCallbackAndSendMessageObject(domain, method, params, callback) {
-    if (!this._connection) {
-      if (callback)
-        this._dispatchConnectionErrorResponse(domain, method, callback);
-      return;
-    }
-
-    const messageObject = {};
-    const messageId = this._nextMessageId();
-    messageObject.id = messageId;
-    messageObject.method = method;
-    if (params)
-      messageObject.params = params;
-
-    const wrappedCallback = this._wrap(callback, domain, method);
-    const message = JSON.stringify(messageObject);
-
-    if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages)
-      this._dumpProtocolMessage('frontend: ' + message, '[FE] ' + domain);
-    if (this.hasEventListeners(Protocol.TargetBase.Events.MessageSent)) {
-      this.dispatchEventToListeners(
-          Protocol.TargetBase.Events.MessageSent,
-          {domain, method, params: JSON.parse(JSON.stringify(params)), id: messageId});
-    }
-
-    this._connection.sendMessage(message);
-    ++this._pendingResponsesCount;
-    this._callbacks[messageId] = wrappedCallback;
-  }
-
-  /**
-   * @param {?function(*)} callback
-   * @param {string} method
-   * @param {string} domain
-   * @return {function(*)}
-   */
-  _wrap(callback, domain, method) {
-    if (!callback)
-      callback = function() {};
-
-    callback.methodName = method;
-    callback.domain = domain;
-    if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
-      callback.sendRequestTime = Date.now();
-
-    return callback;
-  }
-
-  /**
-   * @param {string} method
-   * @param {?Object} params
-   * @param {?function(...*)} callback
-   */
-  _sendRawMessageForTesting(method, params, callback) {
-    const domain = method.split('.')[0];
-    this._wrapCallbackAndSendMessageObject(domain, method, params, callback);
-  }
-
-  /**
-   * @param {!Object|string} message
-   */
-  _onMessage(message) {
-    if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages) {
-      this._dumpProtocolMessage(
-          'backend: ' + ((typeof message === 'string') ? message : JSON.stringify(message)), 'Backend');
-    }
-    if (this.hasEventListeners(Protocol.TargetBase.Events.MessageReceived)) {
-      this.dispatchEventToListeners(Protocol.TargetBase.Events.MessageReceived, {
-        message: JSON.parse((typeof message === 'string') ? message : JSON.stringify(message)),
-      });
-    }
-
-
-    const messageObject = /** @type {!Object} */ ((typeof message === 'string') ? JSON.parse(message) : message);
-
-    if ('id' in messageObject) {  // just a response for some request
-      const callback = this._callbacks[messageObject.id];
-      if (!callback) {
-        Protocol.InspectorBackend.reportProtocolError('Protocol Error: the message with wrong id', messageObject);
-        return;
-      }
-
-      const timingLabel = 'time-stats: ' + callback.methodName;
-      if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
-        Protocol.InspectorBackend._timeLogger.time(timingLabel);
-
-      this._agent(callback.domain).dispatchResponse(messageObject, callback.methodName, callback);
-      --this._pendingResponsesCount;
-      delete this._callbacks[messageObject.id];
-
-      if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
-        Protocol.InspectorBackend._timeLogger.timeEnd(timingLabel);
-
-      if (this._scripts && !this._pendingResponsesCount)
-        this._deprecatedRunAfterPendingDispatches();
-    } else {
-      if (!('method' in messageObject)) {
-        Protocol.InspectorBackend.reportProtocolError('Protocol Error: the message without method', messageObject);
-        return;
-      }
-
-      const method = messageObject.method.split('.');
-      const domainName = method[0];
-      if (!(domainName in this._dispatchers)) {
-        Protocol.InspectorBackend.reportProtocolError(
-            `Protocol Error: the message ${messageObject.method} is for non-existing domain '${domainName}'`,
-            messageObject);
-        return;
-      }
-
-      this._dispatchers[domainName].dispatch(method[1], messageObject);
-    }
-  }
-
-  /**
-   * @param {string} domain
-   * @param {!Object} dispatcher
-   */
-  registerDispatcher(domain, dispatcher) {
-    if (!this._dispatchers[domain])
-      return;
-
-    this._dispatchers[domain].addDomainDispatcher(dispatcher);
-  }
-
-  /**
-   * @param {function()=} script
-   */
-  _deprecatedRunAfterPendingDispatches(script) {
-    if (!this._scripts)
-      this._scripts = [];
-
-    if (script)
-      this._scripts.push(script);
-
-    // Execute all promises.
-    setTimeout(function() {
-      if (!this._pendingResponsesCount)
-        this._executeAfterPendingDispatches();
-      else
-        this._deprecatedRunAfterPendingDispatches();
-    }.bind(this), 0);
-  }
-
-  _executeAfterPendingDispatches() {
-    if (!this._pendingResponsesCount) {
-      const scripts = this._scripts;
-      this._scripts = [];
-      for (let id = 0; id < scripts.length; ++id)
-        scripts[id].call(this);
-    }
-  }
-
-  /**
-   * @param {string} message
-   * @param {string} context
-   */
-  _dumpProtocolMessage(message, context) {
-    if (!this._domainToLogger.get(context))
-      this._domainToLogger.set(context, console.context ? console.context(context) : console);
-    const logger = this._domainToLogger.get(context);
-    logger.log(message);
-  }
-
-  /**
-   * @param {string} reason
-   */
-  _onDisconnect(reason) {
-    this._connection = null;
-    this._runPendingCallbacks();
-    this.dispose();
-  }
-
-  /**
-   * @protected
-   */
-  dispose() {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDisposed() {
-    return !this._connection;
-  }
-
-  _runPendingCallbacks() {
-    const keys = Object.keys(this._callbacks).map(function(num) {
-      return parseInt(num, 10);
-    });
-    for (let i = 0; i < keys.length; ++i) {
-      const callback = this._callbacks[keys[i]];
-      this._dispatchConnectionErrorResponse(callback.domain, callback.methodName, callback);
-    }
-    this._callbacks = {};
-  }
-
-  /**
-   * @param {string} domain
-   * @param {string} methodName
-   * @param {function(*)} callback
-   */
-  _dispatchConnectionErrorResponse(domain, methodName, callback) {
-    const error = {
-      message: 'Connection is closed, can\'t dispatch pending ' + methodName,
-      code: Protocol.InspectorBackend._ConnectionClosedErrorCode,
-      data: null
-    };
-    const messageObject = {error: error};
-    setTimeout(
-        Protocol.InspectorBackend._AgentPrototype.prototype.dispatchResponse.bind(
-            this._agent(domain), messageObject, methodName, callback),
-        0);
-  }
-};
-
-Protocol.TargetBase.Events = {
-  MessageSent: Symbol('MessageSent'),
-  MessageReceived: Symbol('MessageReceived')
-};
-
-/**
- * @unrestricted
- */
-Protocol.InspectorBackend._AgentPrototype = class {
-  /**
-   * @param {string} domain
-   */
-  constructor(domain) {
-    this._replyArgs = {};
-    this._hasErrorData = {};
-    this._domain = domain;
-  }
-
-  /**
-   * @param {!Protocol.TargetBase} target
-   */
-  setTarget(target) {
-    this._target = target;
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {!Array.<!Object>} signature
-   * @param {!Array.<string>} replyArgs
-   * @param {boolean} hasErrorData
-   */
-  registerCommand(methodName, signature, replyArgs, hasErrorData) {
-    const domainAndMethod = this._domain + '.' + methodName;
-
-    /**
-     * @param {...*} vararg
-     * @this {Protocol.InspectorBackend._AgentPrototype}
-     * @return {!Promise.<*>}
-     */
-    function sendMessagePromise(vararg) {
-      const params = Array.prototype.slice.call(arguments);
-      return Protocol.InspectorBackend._AgentPrototype.prototype._sendMessageToBackendPromise.call(
-          this, domainAndMethod, signature, params);
-    }
-
-    this[methodName] = sendMessagePromise;
-
-    /**
-     * @param {!Object} request
-     * @return {!Promise}
-     * @this {Protocol.InspectorBackend._AgentPrototype}
-     */
-    function invoke(request) {
-      return this._invoke(domainAndMethod, request);
-    }
-
-    this['invoke_' + methodName] = invoke;
-
-    this._replyArgs[domainAndMethod] = replyArgs;
-    if (hasErrorData)
-      this._hasErrorData[domainAndMethod] = true;
-  }
-
-  /**
-   * @param {string} method
-   * @param {!Array.<!Object>} signature
-   * @param {!Array.<*>} args
-   * @param {function(string)} errorCallback
-   * @return {?Object}
-   */
-  _prepareParameters(method, signature, args, errorCallback) {
-    const params = {};
-    let hasParams = false;
-
-    for (const param of signature) {
-      const paramName = param['name'];
-      const typeName = param['type'];
-      const optionalFlag = param['optional'];
-
-      if (!args.length && !optionalFlag) {
-        errorCallback(
-            `Protocol Error: Invalid number of arguments for method '${method}' call. ` +
-            `It must have the following arguments ${JSON.stringify(signature)}'.`);
-        return null;
-      }
-
-      const value = args.shift();
-      if (optionalFlag && typeof value === 'undefined')
-        continue;
-
-      if (typeof value !== typeName) {
-        errorCallback(
-            `Protocol Error: Invalid type of argument '${paramName}' for method '${method}' call. ` +
-            `It must be '${typeName}' but it is '${typeof value}'.`);
-        return null;
-      }
-
-      params[paramName] = value;
-      hasParams = true;
-    }
-
-    if (args.length) {
-      errorCallback(`Protocol Error: Extra ${args.length} arguments in a call to method '${method}'.`);
-      return null;
-    }
-
-    return hasParams ? params : null;
-  }
-
-  /**
-   * @param {string} method
-   * @param {!Array<!Object>} signature
-   * @param {!Array<*>} args
-   * @return {!Promise<?>}
-   */
-  _sendMessageToBackendPromise(method, signature, args) {
-    let errorMessage;
-    /**
-     * @param {string} message
-     */
-    function onError(message) {
-      console.error(message);
-      errorMessage = message;
-    }
-    const params = this._prepareParameters(method, signature, args, onError);
-    if (errorMessage)
-      return Promise.resolve(null);
-
-    return new Promise(resolve => {
-      this._target._wrapCallbackAndSendMessageObject(this._domain, method, params, (error, result) => {
-        if (error) {
-          resolve(null);
-          return;
-        }
-        const args = this._replyArgs[method];
-        resolve(result && args.length ? result[args[0]] : undefined);
-      });
-    });
-  }
-
-  /**
-   * @param {string} method
-   * @param {?Object} request
-   * @return {!Promise<!Object>}
-   */
-  _invoke(method, request) {
-    return new Promise(fulfill => {
-      this._target._wrapCallbackAndSendMessageObject(this._domain, method, request, (error, result) => {
-        if (!result)
-          result = {};
-        if (error)
-          result[Protocol.Error] = error.message;
-        fulfill(result);
-      });
-    });
-  }
-
-  /**
-   * @param {!Object} messageObject
-   * @param {string} methodName
-   * @param {function(?Protocol.Error, ?Object)} callback
-   */
-  dispatchResponse(messageObject, methodName, callback) {
-    if (messageObject.error && messageObject.error.code !== Protocol.InspectorBackend._ConnectionClosedErrorCode &&
-        messageObject.error.code !== Protocol.InspectorBackend.DevToolsStubErrorCode &&
-        !Protocol.InspectorBackend.Options.suppressRequestErrors) {
-      const id =
-          Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages ? ' with id = ' + messageObject.id : '';
-      console.error('Request ' + methodName + id + ' failed. ' + JSON.stringify(messageObject.error));
-    }
-    callback(messageObject.error, messageObject.result);
-  }
-};
-
-/**
- * @unrestricted
- */
-Protocol.InspectorBackend._DispatcherPrototype = class {
-  constructor() {
-    this._eventArgs = {};
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {!Object} params
-   */
-  registerEvent(eventName, params) {
-    this._eventArgs[eventName] = params;
-  }
-
-  initialize() {
-    this._dispatchers = [];
-  }
-
-  /**
-   * @param {!Object} dispatcher
-   */
-  addDomainDispatcher(dispatcher) {
-    this._dispatchers.push(dispatcher);
-  }
-
-  /**
-   * @param {string} functionName
-   * @param {!Object} messageObject
-   */
-  dispatch(functionName, messageObject) {
-    if (!this._dispatchers.length)
-      return;
-
-    if (!this._eventArgs[messageObject.method]) {
-      Protocol.InspectorBackend.reportProtocolError(
-          `Protocol Error: Attempted to dispatch an unspecified method '${messageObject.method}'`, messageObject);
-      return;
-    }
-
-    const params = [];
-    if (messageObject.params) {
-      const paramNames = this._eventArgs[messageObject.method];
-      for (let i = 0; i < paramNames.length; ++i)
-        params.push(messageObject.params[paramNames[i]]);
-    }
-
-    const timingLabel = 'time-stats: ' + messageObject.method;
-    if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
-      Protocol.InspectorBackend._timeLogger.time(timingLabel);
-
-    for (let index = 0; index < this._dispatchers.length; ++index) {
-      const dispatcher = this._dispatchers[index];
-      if (functionName in dispatcher)
-        dispatcher[functionName].apply(dispatcher, params);
-    }
-
-    if (Protocol.InspectorBackend.Options.dumpInspectorTimeStats)
-      Protocol.InspectorBackend._timeLogger.timeEnd(timingLabel);
-  }
-};
-
-Protocol.InspectorBackend.Options = {
-  dumpInspectorTimeStats: false,
-  dumpInspectorProtocolMessages: false,
-  suppressRequestErrors: false
-};
-
-Protocol.InspectorBackend._timeLogger = console.context ? console.context('Protocol timing') : console;
diff --git a/front_end/protocol/module.json b/front_end/protocol/module.json
deleted file mode 100644
index c69e67a..0000000
--- a/front_end/protocol/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "dependencies": [
-    "common"
-  ],
-  "scripts": [
-    "InspectorBackend.js",
-    "../InspectorBackendCommands.js"
-  ],
-  "skip_compilation": [
-    "../InspectorBackendCommands.js"
-  ]
-}
diff --git a/front_end/protocol_monitor/ProtocolMonitor.js b/front_end/protocol_monitor/ProtocolMonitor.js
deleted file mode 100644
index 540000c..0000000
--- a/front_end/protocol_monitor/ProtocolMonitor.js
+++ /dev/null
@@ -1,285 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-ProtocolMonitor.ProtocolMonitor = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this._nodes = [];
-    this._recordingListeners = null;
-    this._started = false;
-    this._startTime = 0;
-    this._nodeForId = {};
-    this._filter = node => true;
-    this._columns = [
-      {id: 'method', title: ls`Method`, visible: true, sortable: true, weight: 60},
-      {id: 'direction', title: ls`Direction`, visible: false, sortable: true, hideable: true, weight: 30},
-      {id: 'request', title: ls`Request`, visible: true, hideable: true, weight: 60},
-      {id: 'response', title: ls`Response`, visible: true, hideable: true, weight: 60},
-      {id: 'timestamp', title: ls`Timestamp`, visible: false, sortable: true, hideable: true, weight: 30}
-    ];
-
-    this.registerRequiredCSS('protocol_monitor/protocolMonitor.css');
-    const topToolbar = new UI.Toolbar('protocol-monitor-toolbar', this.contentElement);
-    const recordButton = new UI.ToolbarToggle(ls`Record`, 'largeicon-start-recording', 'largeicon-stop-recording');
-    recordButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
-      recordButton.setToggled(!recordButton.toggled());
-      this._setRecording(recordButton.toggled());
-    });
-    recordButton.setToggleWithRedColor(true);
-    topToolbar.appendToolbarItem(recordButton);
-    recordButton.setToggled(true);
-
-    const clearButton = new UI.ToolbarButton(ls`Clear all`, 'largeicon-clear');
-    clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
-      this._dataGrid.rootNode().removeChildren();
-      this._nodes = [];
-      this._nodeForId = {};
-    });
-    topToolbar.appendToolbarItem(clearButton);
-
-    const split = new UI.SplitWidget(true, true, 'protocol-monitor-panel-split', 250);
-    split.show(this.contentElement);
-    this._dataGrid = new DataGrid.SortableDataGrid(this._columns);
-    this._dataGrid.element.style.flex = '1';
-    this._infoWidget = new ProtocolMonitor.ProtocolMonitor.InfoWidget();
-    split.setMainWidget(this._dataGrid.asWidget());
-    split.setSidebarWidget(this._infoWidget);
-    this._dataGrid.addEventListener(
-        DataGrid.DataGrid.Events.SelectedNode, event => this._infoWidget.render(event.data.data));
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, event => this._infoWidget.render(null));
-    this._dataGrid.setHeaderContextMenuCallback(this._innerHeaderContextMenu.bind(this));
-
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortDataGrid.bind(this));
-    this._dataGrid.setStickToBottom(true);
-    this._dataGrid.sortNodes(DataGrid.SortableDataGrid.NumericComparator.bind(null, 'timestamp'), false);
-    this._updateColumnVisibility();
-
-    const keys = ['method', 'request', 'response', 'direction'];
-    this._filterParser = new TextUtils.FilterParser(keys);
-    this._suggestionBuilder = new UI.FilterSuggestionBuilder(keys);
-
-    this._textFilterUI =
-        new UI.ToolbarInput(ls`Filter`, 1, .2, '', this._suggestionBuilder.completions.bind(this._suggestionBuilder));
-    this._textFilterUI.addEventListener(UI.ToolbarInput.Event.TextChanged, event => {
-      const query = /** @type {string} */ (event.data);
-      const filters = this._filterParser.parse(query);
-      this._filter = node => {
-        for (const {key, text, negative} of filters) {
-          if (!(key in node.data) || !text)
-            continue;
-          const found = JSON.stringify(node.data[key]).indexOf(text) !== -1;
-          if (found === negative)
-            return false;
-        }
-        return true;
-      };
-      this._filterNodes();
-    });
-    topToolbar.appendToolbarItem(this._textFilterUI);
-  }
-
-  _filterNodes() {
-    for (const node of this._nodes) {
-      if (this._filter(node)) {
-        if (!node.parent)
-          this._dataGrid.insertChild(node);
-      } else {
-        node.remove();
-      }
-    }
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _innerHeaderContextMenu(contextMenu) {
-    const columnConfigs = this._columns.filter(columnConfig => columnConfig.hideable);
-    for (const columnConfig of columnConfigs) {
-      contextMenu.headerSection().appendCheckboxItem(
-          columnConfig.title, this._toggleColumnVisibility.bind(this, columnConfig), columnConfig.visible);
-    }
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Object} columnConfig
-   */
-  _toggleColumnVisibility(columnConfig) {
-    columnConfig.visible = !columnConfig.visible;
-    this._updateColumnVisibility();
-  }
-
-  _updateColumnVisibility() {
-    const visibleColumns = /** @type {!Object.<string, boolean>} */ ({});
-    for (const columnConfig of this._columns)
-      visibleColumns[columnConfig.id] = columnConfig.visible;
-    this._dataGrid.setColumnsVisiblity(visibleColumns);
-  }
-
-  _sortDataGrid() {
-    const sortColumnId = this._dataGrid.sortColumnId();
-    if (!sortColumnId)
-      return;
-
-    let columnIsNumeric = true;
-    switch (sortColumnId) {
-      case 'method':
-      case 'direction':
-        columnIsNumeric = false;
-        break;
-    }
-
-
-    const comparator =
-        columnIsNumeric ? DataGrid.SortableDataGrid.NumericComparator : DataGrid.SortableDataGrid.StringComparator;
-    this._dataGrid.sortNodes(comparator.bind(null, sortColumnId), !this._dataGrid.isSortOrderAscending());
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._started)
-      return;
-    this._started = true;
-    this._startTime = Date.now();
-    this._setRecording(true);
-  }
-
-  /**
-   * @param {boolean} recording
-   */
-  _setRecording(recording) {
-    if (this._recordingListeners) {
-      Common.EventTarget.removeEventListeners(this._recordingListeners);
-      this._recordingListeners = null;
-    }
-
-    if (recording) {
-      this._recordingListeners = [
-        SDK.targetManager.mainTarget().addEventListener(
-            Protocol.TargetBase.Events.MessageReceived, this._messageRecieved, this),
-        SDK.targetManager.mainTarget().addEventListener(Protocol.TargetBase.Events.MessageSent, this._messageSent, this)
-      ];
-    }
-  }
-
-  _messageRecieved(event) {
-    const message = event.data.message;
-    if ('id' in message) {
-      const node = this._nodeForId[message.id];
-      if (!node)
-        return;
-      node.data.response = message.result;
-      node.refresh();
-      if (this._dataGrid.selectedNode === node)
-        this._infoWidget.render(node.data);
-      return;
-    }
-    const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({
-      method: message.method,
-      direction: 'recieved',
-      response: message.params,
-      timestamp: Date.now() - this._startTime,
-      request: ''
-    });
-    this._nodes.push(node);
-    if (this._filter(node))
-      this._dataGrid.insertChild(node);
-  }
-
-  _messageSent(event) {
-    const message = event.data;
-    const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({
-      method: message.method,
-      direction: 'sent',
-      request: message.params,
-      timestamp: Date.now() - this._startTime,
-      response: '(pending)',
-      id: message.id
-    });
-    this._nodeForId[message.id] = node;
-    this._nodes.push(node);
-    if (this._filter(node))
-      this._dataGrid.insertChild(node);
-  }
-};
-
-ProtocolMonitor.ProtocolMonitor.ProtocolNode = class extends DataGrid.SortableDataGridNode {
-  constructor(data) {
-    super(data);
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    switch (columnId) {
-      case 'response':
-        if (!this.data[columnId] && this.data.direction === 'send') {
-          const cell = this.createTD(columnId);
-          cell.textContent = '(pending)';
-          return cell;
-        }
-      // fall through
-      case 'request': {
-        const cell = this.createTD(columnId);
-        const obj = SDK.RemoteObject.fromLocalObject(this.data[columnId]);
-        cell.textContent = obj.description.trimEnd(50);
-        cell.classList.add('source-code');
-        return cell;
-      }
-
-      case 'timestamp': {
-        const cell = this.createTD(columnId);
-        cell.textContent = ls`${this.data[columnId]} ms`;
-        return cell;
-      }
-    }
-    return super.createCell(columnId);
-  }
-
-  /**
-   * @override
-   */
-  element() {
-    const element = super.element();
-    element.classList.toggle('protocol-message-sent', this.data.direction === 'sent');
-    element.classList.toggle('protocol-message-recieved', this.data.direction !== 'sent');
-    return element;
-  }
-};
-
-
-ProtocolMonitor.ProtocolMonitor.InfoWidget = class extends UI.VBox {
-  constructor() {
-    super();
-    this._tabbedPane = new UI.TabbedPane();
-    this._tabbedPane.appendTab('request', 'Request', new UI.Widget());
-    this._tabbedPane.appendTab('response', 'Response', new UI.Widget());
-    this._tabbedPane.show(this.contentElement);
-    this._tabbedPane.selectTab('response');
-    this.render(null);
-  }
-
-  /**
-   * @param {?{method: string, direction: string, request: ?Object, response: ?Object, timestamp: number}} data
-   */
-  render(data) {
-    const requestEnabled = data && data.direction === 'sent';
-    this._tabbedPane.setTabEnabled('request', !!requestEnabled);
-    if (!data) {
-      this._tabbedPane.changeTabView('request', new UI.EmptyWidget(ls`No message selected`));
-      this._tabbedPane.changeTabView('response', new UI.EmptyWidget(ls`No message selected`));
-      return;
-    }
-    if (!requestEnabled)
-      this._tabbedPane.selectTab('response');
-
-    this._tabbedPane.changeTabView('request', SourceFrame.JSONView.createViewSync(data.request));
-    this._tabbedPane.changeTabView('response', SourceFrame.JSONView.createViewSync(data.response));
-  }
-};
diff --git a/front_end/protocol_monitor/module.json b/front_end/protocol_monitor/module.json
deleted file mode 100644
index 57f04f9..0000000
--- a/front_end/protocol_monitor/module.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "extensions": [
-    {
-        "type": "view",
-        "location": "drawer-view",
-        "id": "protocol-monitor",
-        "title": "Protocol monitor",
-        "order": 100,
-        "persistence": "closeable",
-        "className": "ProtocolMonitor.ProtocolMonitor",
-        "experiment": "protocolMonitor"
-    }
-  ],
-  "dependencies": ["platform", "ui", "host", "components", "data_grid", "source_frame"],
-  "scripts": [
-    "ProtocolMonitor.js"
-  ],
-  "resources": [
-    "protocolMonitor.css"
-  ]
-}
\ No newline at end of file
diff --git a/front_end/protocol_monitor/protocolMonitor.css b/front_end/protocol_monitor/protocolMonitor.css
deleted file mode 100644
index 5787a07..0000000
--- a/front_end/protocol_monitor/protocolMonitor.css
+++ /dev/null
@@ -1,32 +0,0 @@
-.data-grid {
-    border: none;
-}
-.data-grid {
-    flex: auto;
-    border: none;
-}
-
-.data-grid .data {
-    background-image: none;
-}
-
-.data-grid td {
-    /* border-bottom: 1px solid #ccc; */
-    border-left-color: #ccc;
-}
-
-.data-grid tr.selected {
-    background-color: #def;
-}
-
-.data-grid th {
-    border-left-color: #ccc;
-}
-
-.protocol-message-sent {
-    background-color: hsl(281, 64%, 95%);
-}
-
-.protocol-monitor-toolbar {
-    border-bottom:var(--divider-border);
-}
diff --git a/front_end/quick_open/CommandMenu.js b/front_end/quick_open/CommandMenu.js
deleted file mode 100644
index 488750d..0000000
--- a/front_end/quick_open/CommandMenu.js
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-QuickOpen.CommandMenu = class {
-  constructor() {
-    this._commands = [];
-    this._loadCommands();
-  }
-
-  /**
-   * @param {string} category
-   * @param {string} keys
-   * @param {string} title
-   * @param {string} shortcut
-   * @param {function()} executeHandler
-   * @param {function()=} availableHandler
-   * @return {!QuickOpen.CommandMenu.Command}
-   */
-  static createCommand(category, keys, title, shortcut, executeHandler, availableHandler) {
-    // Separate keys by null character, to prevent fuzzy matching from matching across them.
-    const key = keys.replace(/,/g, '\0');
-    return new QuickOpen.CommandMenu.Command(category, title, key, shortcut, executeHandler, availableHandler);
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @param {string} title
-   * @param {V} value
-   * @return {!QuickOpen.CommandMenu.Command}
-   * @template V
-   */
-  static createSettingCommand(extension, title, value) {
-    const category = extension.descriptor()['category'] || '';
-    const tags = extension.descriptor()['tags'] || '';
-    const setting = Common.settings.moduleSetting(extension.descriptor()['settingName']);
-    return QuickOpen.CommandMenu.createCommand(
-        category, tags, title, '', setting.set.bind(setting, value), availableHandler);
-
-    /**
-     * @return {boolean}
-     */
-    function availableHandler() {
-      return setting.get() !== value;
-    }
-  }
-
-  /**
-   * @param {!UI.Action} action
-   * @return {!QuickOpen.CommandMenu.Command}
-   */
-  static createActionCommand(action) {
-    const shortcut = UI.shortcutRegistry.shortcutTitleForAction(action.id()) || '';
-    return QuickOpen.CommandMenu.createCommand(
-        action.category(), action.tags(), action.title(), shortcut, action.execute.bind(action));
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @param {string} category
-   * @return {!QuickOpen.CommandMenu.Command}
-   */
-  static createRevealViewCommand(extension, category) {
-    const viewId = extension.descriptor()['id'];
-    const executeHandler = UI.viewManager.showView.bind(UI.viewManager, viewId);
-    const tags = extension.descriptor()['tags'] || '';
-    return QuickOpen.CommandMenu.createCommand(
-        category, tags, Common.UIString('Show %s', extension.title()), '', executeHandler);
-  }
-
-  _loadCommands() {
-    const locations = new Map();
-    self.runtime.extensions(UI.ViewLocationResolver).forEach(extension => {
-      const category = extension.descriptor()['category'];
-      const name = extension.descriptor()['name'];
-      if (category && name)
-        locations.set(name, category);
-    });
-    const viewExtensions = self.runtime.extensions('view');
-    for (const extension of viewExtensions) {
-      const category = locations.get(extension.descriptor()['location']);
-      if (category)
-        this._commands.push(QuickOpen.CommandMenu.createRevealViewCommand(extension, category));
-    }
-
-    // Populate whitelisted settings.
-    const settingExtensions = self.runtime.extensions('setting');
-    for (const extension of settingExtensions) {
-      const options = extension.descriptor()['options'];
-      if (!options || !extension.descriptor()['category'])
-        continue;
-      for (const pair of options)
-        this._commands.push(QuickOpen.CommandMenu.createSettingCommand(extension, pair['title'], pair['value']));
-    }
-  }
-
-  /**
-   * @return {!Array.<!QuickOpen.CommandMenu.Command>}
-   */
-  commands() {
-    return this._commands;
-  }
-};
-
-QuickOpen.CommandMenuProvider = class extends QuickOpen.FilteredListWidget.Provider {
-  constructor() {
-    super();
-    this._commands = [];
-  }
-
-  /**
-   * @override
-   */
-  attach() {
-    const allCommands = QuickOpen.commandMenu.commands();
-
-    // Populate whitelisted actions.
-    const actions = UI.actionRegistry.availableActions();
-    for (const action of actions) {
-      if (action.category())
-        this._commands.push(QuickOpen.CommandMenu.createActionCommand(action));
-    }
-
-    for (const command of allCommands) {
-      if (command.available())
-        this._commands.push(command);
-    }
-
-    this._commands = this._commands.sort(commandComparator);
-
-    /**
-     * @param {!QuickOpen.CommandMenu.Command} left
-     * @param {!QuickOpen.CommandMenu.Command} right
-     * @return {number}
-     */
-    function commandComparator(left, right) {
-      const cats = left.category().compareTo(right.category());
-      return cats ? cats : left.title().compareTo(right.title());
-    }
-  }
-
-  /**
-   * @override
-   */
-  detach() {
-    this._commands = [];
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemCount() {
-    return this._commands.length;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @return {string}
-   */
-  itemKeyAt(itemIndex) {
-    return this._commands[itemIndex].key();
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @return {number}
-   */
-  itemScoreAt(itemIndex, query) {
-    const command = this._commands[itemIndex];
-    const opcodes = Diff.Diff.charDiff(query.toLowerCase(), command.title().toLowerCase());
-    let score = 0;
-    // Score longer sequences higher.
-    for (let i = 0; i < opcodes.length; ++i) {
-      if (opcodes[i][0] === Diff.Diff.Operation.Equal)
-        score += opcodes[i][1].length * opcodes[i][1].length;
-    }
-
-    // Score panel/drawer reveals above regular actions.
-    if (command.category().startsWith('Panel'))
-      score += 2;
-    else if (command.category().startsWith('Drawer'))
-      score += 1;
-
-    return score;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @param {!Element} titleElement
-   * @param {!Element} subtitleElement
-   */
-  renderItem(itemIndex, query, titleElement, subtitleElement) {
-    const command = this._commands[itemIndex];
-    titleElement.removeChildren();
-    const tagElement = titleElement.createChild('span', 'tag');
-    const index = String.hashCode(command.category()) % QuickOpen.CommandMenuProvider.MaterialPaletteColors.length;
-    tagElement.style.backgroundColor = QuickOpen.CommandMenuProvider.MaterialPaletteColors[index];
-    tagElement.textContent = command.category();
-    titleElement.createTextChild(command.title());
-    QuickOpen.FilteredListWidget.highlightRanges(titleElement, query, true);
-    subtitleElement.textContent = command.shortcut();
-  }
-
-  /**
-   * @override
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-    if (itemIndex === null)
-      return;
-    this._commands[itemIndex].execute();
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.SelectCommandFromCommandMenu);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  notFoundText() {
-    return Common.UIString('No commands found');
-  }
-};
-
-QuickOpen.CommandMenuProvider.MaterialPaletteColors = [
-  '#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#03A9F4', '#00BCD4', '#009688', '#4CAF50', '#8BC34A',
-  '#CDDC39', '#FFC107', '#FF9800', '#FF5722', '#795548', '#9E9E9E', '#607D8B'
-];
-
-/**
- * @unrestricted
- */
-QuickOpen.CommandMenu.Command = class {
-  /**
-   * @param {string} category
-   * @param {string} title
-   * @param {string} key
-   * @param {string} shortcut
-   * @param {function()} executeHandler
-   * @param {function()=} availableHandler
-   */
-  constructor(category, title, key, shortcut, executeHandler, availableHandler) {
-    this._category = category;
-    this._title = title;
-    this._key = category + '\0' + title + '\0' + key;
-    this._shortcut = shortcut;
-    this._executeHandler = executeHandler;
-    this._availableHandler = availableHandler;
-  }
-
-  /**
-   * @return {string}
-   */
-  category() {
-    return this._category;
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-
-  /**
-   * @return {string}
-   */
-  key() {
-    return this._key;
-  }
-
-  /**
-   * @return {string}
-   */
-  shortcut() {
-    return this._shortcut;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  available() {
-    return this._availableHandler ? this._availableHandler() : true;
-  }
-
-  execute() {
-    this._executeHandler();
-  }
-};
-
-
-/** @type {!QuickOpen.CommandMenu} */
-QuickOpen.commandMenu = new QuickOpen.CommandMenu();
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-QuickOpen.CommandMenu.ShowActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    InspectorFrontendHost.bringToFront();
-    QuickOpen.QuickOpen.show('>');
-    return true;
-  }
-};
diff --git a/front_end/quick_open/FilteredListWidget.js b/front_end/quick_open/FilteredListWidget.js
deleted file mode 100644
index c146b19..0000000
--- a/front_end/quick_open/FilteredListWidget.js
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-/**
- * @unrestricted
- * @implements {UI.ListDelegate}
- */
-QuickOpen.FilteredListWidget = class extends UI.VBox {
-  /**
-   * @param {?QuickOpen.FilteredListWidget.Provider} provider
-   * @param {!Array<string>=} promptHistory
-   * @param {function(string)=} queryChangedCallback
-   */
-  constructor(provider, promptHistory, queryChangedCallback) {
-    super(true);
-    this._promptHistory = promptHistory || [];
-
-    this.contentElement.classList.add('filtered-list-widget');
-    this.contentElement.addEventListener('keydown', this._onKeyDown.bind(this), true);
-    this.registerRequiredCSS('quick_open/filteredListWidget.css');
-
-    this._promptElement = this.contentElement.createChild('div', 'filtered-list-widget-input');
-    this._promptElement.setAttribute('spellcheck', 'false');
-    this._promptElement.setAttribute('contenteditable', 'plaintext-only');
-    this._prompt = new UI.TextPrompt();
-    this._prompt.initialize(() => Promise.resolve([]));
-    const promptProxy = this._prompt.attach(this._promptElement);
-    promptProxy.addEventListener('input', this._onInput.bind(this), false);
-    promptProxy.classList.add('filtered-list-widget-prompt-element');
-
-    this._bottomElementsContainer = this.contentElement.createChild('div', 'vbox');
-    this._progressElement = this._bottomElementsContainer.createChild('div', 'filtered-list-widget-progress');
-    this._progressBarElement = this._progressElement.createChild('div', 'filtered-list-widget-progress-bar');
-
-    /** @type {!UI.ListModel<number>} */
-    this._items = new UI.ListModel();
-    /** @type {!UI.ListControl<number>} */
-    this._list = new UI.ListControl(this._items, this, UI.ListMode.EqualHeightItems);
-    this._itemElementsContainer = this._list.element;
-    this._itemElementsContainer.classList.add('container');
-    this._bottomElementsContainer.appendChild(this._itemElementsContainer);
-    this._itemElementsContainer.addEventListener('click', this._onClick.bind(this), false);
-
-    this._notFoundElement = this._bottomElementsContainer.createChild('div', 'not-found-text');
-    this._notFoundElement.classList.add('hidden');
-
-    this.setDefaultFocusedElement(this._promptElement);
-
-    this._prefix = '';
-    this._provider = provider;
-    this._queryChangedCallback = queryChangedCallback;
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} query
-   * @param {boolean=} caseInsensitive
-   * @return {boolean}
-   */
-  static highlightRanges(element, query, caseInsensitive) {
-    if (!query)
-      return false;
-
-    /**
-     * @param {string} text
-     * @param {string} query
-     * @return {?Array.<!TextUtils.SourceRange>}
-     */
-    function rangesForMatch(text, query) {
-      const opcodes = Diff.Diff.charDiff(query, text);
-      let offset = 0;
-      const ranges = [];
-      for (let i = 0; i < opcodes.length; ++i) {
-        const opcode = opcodes[i];
-        if (opcode[0] === Diff.Diff.Operation.Equal)
-          ranges.push(new TextUtils.SourceRange(offset, opcode[1].length));
-        else if (opcode[0] !== Diff.Diff.Operation.Insert)
-          return null;
-        offset += opcode[1].length;
-      }
-      return ranges;
-    }
-
-    const text = element.textContent;
-    let ranges = rangesForMatch(text, query);
-    if (!ranges || caseInsensitive)
-      ranges = rangesForMatch(text.toUpperCase(), query.toUpperCase());
-    if (ranges) {
-      UI.highlightRangesWithStyleClass(element, ranges, 'highlight');
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {string} placeholder
-   */
-  setPlaceholder(placeholder) {
-    this._prompt.setPlaceholder(placeholder);
-  }
-
-  showAsDialog() {
-    this._dialog = new UI.Dialog();
-    this._dialog.setMaxContentSize(new UI.Size(504, 340));
-    this._dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.SetExactWidthMaxHeight);
-    this._dialog.setContentPosition(null, 22);
-    this.show(this._dialog.contentElement);
-    this._dialog.show();
-  }
-
-  /**
-   * @param {string} prefix
-   */
-  setPrefix(prefix) {
-    this._prefix = prefix;
-  }
-
-  /**
-   * @param {?QuickOpen.FilteredListWidget.Provider} provider
-   */
-  setProvider(provider) {
-    if (provider === this._provider)
-      return;
-
-    if (this._provider)
-      this._provider.detach();
-    this._clearTimers();
-
-    this._provider = provider;
-    if (this.isShowing())
-      this._attachProvider();
-  }
-
-  _attachProvider() {
-    this._items.replaceAll([]);
-    this._list.invalidateItemHeight();
-    if (this._provider) {
-      this._provider.setRefreshCallback(this._itemsLoaded.bind(this, this._provider));
-      this._provider.attach();
-    }
-    this._itemsLoaded(this._provider);
-  }
-
-  /**
-   * @return {string}
-   */
-  _value() {
-    return this._prompt.text().trim();
-  }
-
-  _cleanValue() {
-    return this._value().substring(this._prefix.length);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._attachProvider();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    if (this._provider)
-      this._provider.detach();
-    this._clearTimers();
-  }
-
-  _clearTimers() {
-    clearTimeout(this._filterTimer);
-    clearTimeout(this._scoringTimer);
-    clearTimeout(this._loadTimeout);
-    delete this._filterTimer;
-    delete this._scoringTimer;
-    delete this._loadTimeout;
-    delete this._refreshListWithCurrentResult;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onEnter(event) {
-    if (!this._provider)
-      return;
-    const selectedIndexInProvider = this._provider.itemCount() ? this._list.selectedItem() : null;
-
-    this._selectItem(selectedIndexInProvider);
-    if (this._dialog)
-      this._dialog.hide();
-  }
-
-  /**
-   * @param {?QuickOpen.FilteredListWidget.Provider} provider
-   */
-  _itemsLoaded(provider) {
-    if (this._loadTimeout || provider !== this._provider)
-      return;
-    this._loadTimeout = setTimeout(this._updateAfterItemsLoaded.bind(this), 0);
-  }
-
-  _updateAfterItemsLoaded() {
-    delete this._loadTimeout;
-    this._filterItems();
-  }
-
-  /**
-   * @override
-   * @param {number} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    const itemElement = createElement('div');
-    itemElement.className = 'filtered-list-widget-item ' + (this._provider.renderAsTwoRows() ? 'two-rows' : 'one-row');
-    const titleElement = itemElement.createChild('div', 'filtered-list-widget-title');
-    const subtitleElement = itemElement.createChild('div', 'filtered-list-widget-subtitle');
-    subtitleElement.textContent = '\u200B';
-    this._provider.renderItem(item, this._cleanValue(), titleElement, subtitleElement);
-    return itemElement;
-  }
-
-  /**
-   * @override
-   * @param {number} item
-   * @return {number}
-   */
-  heightForItem(item) {
-    // Let the list measure items for us.
-    return 0;
-  }
-
-  /**
-   * @override
-   * @param {number} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?number} from
-   * @param {?number} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('selected');
-    if (toElement) {
-      toElement.classList.add('selected');
-      UI.ARIAUtils.alert(toElement.textContent, toElement);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    const item = this._list.itemForNode(/** @type {?Node} */ (event.target));
-    if (item === null)
-      return;
-
-    event.consume(true);
-    this._selectItem(item);
-    if (this._dialog)
-      this._dialog.hide();
-  }
-
-  /**
-   * @param {string} query
-   */
-  setQuery(query) {
-    this._prompt.focus();
-    this._prompt.setText(query);
-    this._queryChanged();
-    this._prompt.autoCompleteSoon(true);
-    this._scheduleFilter();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _tabKeyPressed() {
-    const userEnteredText = this._prompt.text();
-    let completion;
-    for (let i = this._promptHistory.length - 1; i >= 0; i--) {
-      if (this._promptHistory[i] !== userEnteredText && this._promptHistory[i].startsWith(userEnteredText)) {
-        completion = this._promptHistory[i];
-        break;
-      }
-    }
-    if (!completion)
-      return false;
-    this._prompt.focus();
-    this._prompt.setText(completion);
-    this._prompt.setDOMSelection(userEnteredText.length, completion.length);
-    this._scheduleFilter();
-    return true;
-  }
-
-  _itemsFilteredForTest() {
-    // Sniffed in tests.
-  }
-
-  _filterItems() {
-    delete this._filterTimer;
-    if (this._scoringTimer) {
-      clearTimeout(this._scoringTimer);
-      delete this._scoringTimer;
-
-      if (this._refreshListWithCurrentResult)
-        this._refreshListWithCurrentResult();
-    }
-
-    if (!this._provider) {
-      this._bottomElementsContainer.classList.toggle('hidden', true);
-      this._itemsFilteredForTest();
-      return;
-    }
-
-    this._bottomElementsContainer.classList.toggle('hidden', false);
-
-    this._progressBarElement.style.transform = 'scaleX(0)';
-    this._progressBarElement.classList.remove('filtered-widget-progress-fade');
-    this._progressBarElement.classList.remove('hidden');
-
-    const query = this._provider.rewriteQuery(this._cleanValue());
-    this._query = query;
-
-    const filterRegex = query ? String.filterRegex(query) : null;
-
-    const filteredItems = [];
-
-    const bestScores = [];
-    const bestItems = [];
-    const bestItemsToCollect = 100;
-    let minBestScore = 0;
-    const overflowItems = [];
-    const scoreStartTime = window.performance.now();
-
-    const maxWorkItems = Number.constrain(10, 500, (this._provider.itemCount() / 10) | 0);
-
-    scoreItems.call(this, 0);
-
-    /**
-     * @param {number} a
-     * @param {number} b
-     * @return {number}
-     */
-    function compareIntegers(a, b) {
-      return b - a;
-    }
-
-    /**
-     * @param {number} fromIndex
-     * @this {QuickOpen.FilteredListWidget}
-     */
-    function scoreItems(fromIndex) {
-      delete this._scoringTimer;
-      let workDone = 0;
-      let i;
-
-      for (i = fromIndex; i < this._provider.itemCount() && workDone < maxWorkItems; ++i) {
-        // Filter out non-matching items quickly.
-        if (filterRegex && !filterRegex.test(this._provider.itemKeyAt(i)))
-          continue;
-
-        // Score item.
-        const score = this._provider.itemScoreAt(i, query);
-        if (query)
-          workDone++;
-
-        // Find its index in the scores array (earlier elements have bigger scores).
-        if (score > minBestScore || bestScores.length < bestItemsToCollect) {
-          const index = bestScores.upperBound(score, compareIntegers);
-          bestScores.splice(index, 0, score);
-          bestItems.splice(index, 0, i);
-          if (bestScores.length > bestItemsToCollect) {
-            // Best list is too large -> drop last elements.
-            overflowItems.push(bestItems.peekLast());
-            bestScores.length = bestItemsToCollect;
-            bestItems.length = bestItemsToCollect;
-          }
-          minBestScore = bestScores.peekLast();
-        } else {
-          filteredItems.push(i);
-        }
-      }
-
-      this._refreshListWithCurrentResult = this._refreshList.bind(this, bestItems, overflowItems, filteredItems);
-
-      // Process everything in chunks.
-      if (i < this._provider.itemCount()) {
-        this._scoringTimer = setTimeout(scoreItems.bind(this, i), 0);
-        if (window.performance.now() - scoreStartTime > 50)
-          this._progressBarElement.style.transform = 'scaleX(' + i / this._provider.itemCount() + ')';
-        return;
-      }
-      if (window.performance.now() - scoreStartTime > 100) {
-        this._progressBarElement.style.transform = 'scaleX(1)';
-        this._progressBarElement.classList.add('filtered-widget-progress-fade');
-      } else {
-        this._progressBarElement.classList.add('hidden');
-      }
-      this._refreshListWithCurrentResult();
-    }
-  }
-
-  /**
-   * @param {!Array<number>} bestItems
-   * @param {!Array<number>} overflowItems
-   * @param {!Array<number>} filteredItems
-   */
-  _refreshList(bestItems, overflowItems, filteredItems) {
-    delete this._refreshListWithCurrentResult;
-    filteredItems = [].concat(bestItems, overflowItems, filteredItems);
-    this._updateNotFoundMessage(!!filteredItems.length);
-    const oldHeight = this._list.element.offsetHeight;
-    this._items.replaceAll(filteredItems);
-    if (filteredItems.length)
-      this._list.selectItem(filteredItems[0]);
-    if (this._list.element.offsetHeight !== oldHeight)
-      this._list.viewportResized();
-    this._itemsFilteredForTest();
-  }
-
-  /**
-   * @param {boolean} hasItems
-   */
-  _updateNotFoundMessage(hasItems) {
-    this._list.element.classList.toggle('hidden', !hasItems);
-    this._notFoundElement.classList.toggle('hidden', hasItems);
-    if (!hasItems)
-      this._notFoundElement.textContent = this._provider.notFoundText(this._cleanValue());
-  }
-
-  _onInput() {
-    this._queryChanged();
-    this._scheduleFilter();
-  }
-
-  _queryChanged() {
-    if (this._queryChangedCallback)
-      this._queryChangedCallback(this._value());
-    if (this._provider)
-      this._provider.queryChanged(this._cleanValue());
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    let handled = false;
-    switch (event.key) {
-      case 'Enter':
-        this._onEnter(event);
-        return;
-      case 'Tab':
-        handled = this._tabKeyPressed();
-        break;
-      case 'ArrowUp':
-        handled = this._list.selectPreviousItem(true, false);
-        break;
-      case 'ArrowDown':
-        handled = this._list.selectNextItem(true, false);
-        break;
-      case 'PageUp':
-        handled = this._list.selectItemPreviousPage(false);
-        break;
-      case 'PageDown':
-        handled = this._list.selectItemNextPage(false);
-        break;
-    }
-    if (handled)
-      event.consume(true);
-  }
-
-  _scheduleFilter() {
-    if (this._filterTimer)
-      return;
-    this._filterTimer = setTimeout(this._filterItems.bind(this), 0);
-  }
-
-  /**
-   * @param {?number} itemIndex
-   */
-  _selectItem(itemIndex) {
-    this._promptHistory.push(this._value());
-    if (this._promptHistory.length > 100)
-      this._promptHistory.shift();
-    this._provider.selectItem(itemIndex, this._cleanValue());
-  }
-};
-
-
-/**
- * @unrestricted
- */
-QuickOpen.FilteredListWidget.Provider = class {
-  /**
-   * @param {function():void} refreshCallback
-   */
-  setRefreshCallback(refreshCallback) {
-    this._refreshCallback = refreshCallback;
-  }
-
-  attach() {
-  }
-
-  /**
-   * @return {number}
-   */
-  itemCount() {
-    return 0;
-  }
-
-  /**
-   * @param {number} itemIndex
-   * @return {string}
-   */
-  itemKeyAt(itemIndex) {
-    return '';
-  }
-
-  /**
-   * @param {number} itemIndex
-   * @param {string} query
-   * @return {number}
-   */
-  itemScoreAt(itemIndex, query) {
-    return 1;
-  }
-
-  /**
-   * @param {number} itemIndex
-   * @param {string} query
-   * @param {!Element} titleElement
-   * @param {!Element} subtitleElement
-   */
-  renderItem(itemIndex, query, titleElement, subtitleElement) {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  renderAsTwoRows() {
-    return false;
-  }
-
-  /**
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-  }
-
-  refresh() {
-    this._refreshCallback();
-  }
-
-  /**
-   * @param {string} query
-   * @return {string}
-   */
-  rewriteQuery(query) {
-    return query;
-  }
-
-  /**
-   * @param {string} query
-   */
-  queryChanged(query) {
-  }
-
-  /**
-   * @param {string} query
-   * @return {string}
-   */
-  notFoundText(query) {
-    return Common.UIString('No results found');
-  }
-
-  detach() {
-  }
-};
diff --git a/front_end/quick_open/HelpQuickOpen.js b/front_end/quick_open/HelpQuickOpen.js
deleted file mode 100644
index 4399d74..0000000
--- a/front_end/quick_open/HelpQuickOpen.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-QuickOpen.HelpQuickOpen = class extends QuickOpen.FilteredListWidget.Provider {
-  constructor() {
-    super();
-    /** @type {!Array<{prefix: string, title: string}>} */
-    this._providers = [];
-    self.runtime.extensions(QuickOpen.FilteredListWidget.Provider).forEach(this._addProvider.bind(this));
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  _addProvider(extension) {
-    if (extension.descriptor()['title'])
-      this._providers.push({prefix: extension.descriptor()['prefix'], title: extension.descriptor()['title']});
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemCount() {
-    return this._providers.length;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @return {string}
-   */
-  itemKeyAt(itemIndex) {
-    return this._providers[itemIndex].prefix;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @return {number}
-   */
-  itemScoreAt(itemIndex, query) {
-    return -this._providers[itemIndex].prefix.length;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @param {!Element} titleElement
-   * @param {!Element} subtitleElement
-   */
-  renderItem(itemIndex, query, titleElement, subtitleElement) {
-    const provider = this._providers[itemIndex];
-    const prefixElement = titleElement.createChild('span', 'monospace');
-    prefixElement.textContent = (provider.prefix || '\u2026') + ' ';
-    titleElement.createTextChild(provider.title);
-  }
-
-  /**
-   * @override
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-    if (itemIndex !== null)
-      QuickOpen.QuickOpen.show(this._providers[itemIndex].prefix);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  renderAsTwoRows() {
-    return false;
-  }
-};
diff --git a/front_end/quick_open/QuickOpen.js b/front_end/quick_open/QuickOpen.js
deleted file mode 100644
index 9f1160d..0000000
--- a/front_end/quick_open/QuickOpen.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-QuickOpen.QuickOpen = class {
-  constructor() {
-    this._prefix = null;
-    this._query = '';
-    /** @type {!Map<string, function():!Promise<!QuickOpen.FilteredListWidget.Provider>>} */
-    this._providers = new Map();
-    /** @type {!Array<string>} */
-    this._prefixes = [];
-    this._filteredListWidget = null;
-    self.runtime.extensions(QuickOpen.FilteredListWidget.Provider).forEach(this._addProvider.bind(this));
-    this._prefixes.sort((a, b) => b.length - a.length);
-  }
-
-  /**
-   * @param {string} query
-   */
-  static show(query) {
-    const quickOpen = new this();
-    const filteredListWidget =
-        new QuickOpen.FilteredListWidget(null, this._history, quickOpen._queryChanged.bind(quickOpen));
-    quickOpen._filteredListWidget = filteredListWidget;
-    filteredListWidget.setPlaceholder(Common.UIString('Type \'?\' to see available commands'));
-    filteredListWidget.showAsDialog();
-    filteredListWidget.setQuery(query);
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  _addProvider(extension) {
-    const prefix = extension.descriptor()['prefix'];
-    this._prefixes.push(prefix);
-    this._providers.set(
-        prefix, /** @type {function():!Promise<!QuickOpen.FilteredListWidget.Provider>} */
-        (extension.instance.bind(extension)));
-  }
-
-  /**
-   * @param {string} query
-   */
-  _queryChanged(query) {
-    const prefix = this._prefixes.find(prefix => query.startsWith(prefix));
-    if (typeof prefix !== 'string' || this._prefix === prefix)
-      return;
-
-    this._prefix = prefix;
-    this._filteredListWidget.setPrefix(prefix);
-    this._filteredListWidget.setProvider(null);
-    this._providers.get(prefix)().then(provider => {
-      if (this._prefix !== prefix)
-        return;
-      this._filteredListWidget.setProvider(provider);
-      this._providerLoadedForTest(provider);
-    });
-  }
-
-  /**
-   * @param {!QuickOpen.FilteredListWidget.Provider} provider
-   */
-  _providerLoadedForTest(provider) {
-  }
-};
-
-QuickOpen.QuickOpen._history = [];
-
-/**
- * @implements {UI.ActionDelegate}
- */
-QuickOpen.QuickOpen.ShowActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    switch (actionId) {
-      case 'quickOpen.show':
-        QuickOpen.QuickOpen.show('');
-        return true;
-    }
-    return false;
-  }
-};
diff --git a/front_end/quick_open/filteredListWidget.css b/front_end/quick_open/filteredListWidget.css
deleted file mode 100644
index 9e83438..0000000
--- a/front_end/quick_open/filteredListWidget.css
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.filtered-list-widget {
-    display: flex;
-    flex-direction: column;
-    flex: auto;
-}
-
-.filtered-list-widget-prompt-element {
-    flex: 0 0 34px;
-    border: 0;
-    margin: 0;
-    padding: 0 6px;
-    z-index: 1;
-    font-size: inherit;
-}
-
-.filtered-list-widget-input {
-    white-space: pre;
-    height: 18px;
-    margin-top: 12px;
-    overflow: hidden;
-    flex: auto;
-}
-
-.filtered-list-widget-progress {
-    flex: none;
-    background: rgba(0, 0, 0, 0.2);
-    height: 2px;
-}
-
-.filtered-list-widget-progress-bar {
-    background-color: #2196F3;
-    height: 2px;
-    width: 100%;
-    transform: scaleX(0);
-    transform-origin: top left;
-    opacity: 1;
-    transition: none;
-}
-
-.filtered-widget-progress-fade {
-    opacity: 0;
-    transition: opacity 500ms;
-}
-
-.filtered-list-widget > div.container {
-    flex: auto;
-    overflow-y: auto;
-    background: #fbfbfb;
-}
-
-.filtered-list-widget-item {
-    padding: 4px 6px;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    color: rgb(95, 95, 95);
-}
-
-.filtered-list-widget-item.selected {
-    background-color: #f0f0f0;
-}
-
-:host-context(.-theme-with-dark-background) .filtered-list-widget-item.selected {
-    background-color: #333333;
-}
-
-.filtered-list-widget-item span.highlight {
-    color: #222;
-    font-weight: bold;
-}
-
-.filtered-list-widget-item .filtered-list-widget-title {
-    flex: auto;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.filtered-list-widget-item .filtered-list-widget-subtitle {
-    flex: none;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    color: rgb(155, 155, 155);
-    display: flex;
-}
-
-.filtered-list-widget-item .filtered-list-widget-subtitle .first-part {
-    flex-shrink: 1000;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.filtered-list-widget-item.one-row {
-    display: flex;
-}
-
-.filtered-list-widget-item.two-rows {
-    border-bottom: 1px solid rgb(235, 235, 235);
-}
-
-.tag {
-    color: white;
-    padding: 1px 3px;
-    margin-right: 5px;
-    border-radius: 2px;
-    line-height: 18px;
-}
-
-.filtered-list-widget-item .tag .highlight {
-    color: white;
-}
-
-.not-found-text {
-    height: 34px;
-    line-height: 34px;
-    padding-left: 4px;
-    font-style: italic;
-    color: #888;
-    background: #fbfbfb;
-}
diff --git a/front_end/quick_open/module.json b/front_end/quick_open/module.json
deleted file mode 100644
index 7fa6171..0000000
--- a/front_end/quick_open/module.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@QuickOpen.FilteredListWidget.Provider",
-            "title": "Run command",
-            "prefix": ">",
-            "className": "QuickOpen.CommandMenuProvider"
-        },
-        {
-            "type": "@QuickOpen.FilteredListWidget.Provider",
-            "prefix": "?",
-            "className": "QuickOpen.HelpQuickOpen"
-        },
-        {
-            "type": "action",
-            "actionId": "commandMenu.show",
-            "className": "QuickOpen.CommandMenu.ShowActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Shift+P"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Shift+P"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "quickOpen.show",
-            "title": "Open file",
-            "className": "QuickOpen.QuickOpen.ShowActionDelegate",
-            "order": 100,
-            "bindings": [
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+P Meta+O"
-                },
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+P Ctrl+O"
-                }
-            ]
-        },
-        {
-            "type": "context-menu-item",
-            "location": "mainMenu/default",
-            "actionId": "quickOpen.show"
-        }
-    ],
-    "dependencies": [
-        "ui",
-        "diff"
-    ],
-    "scripts": [
-        "FilteredListWidget.js",
-        "QuickOpen.js",
-        "CommandMenu.js",
-        "HelpQuickOpen.js"
-    ],
-    "resources": [
-        "filteredListWidget.css"
-    ]
-}
diff --git a/front_end/resources/AppManifestView.js b/front_end/resources/AppManifestView.js
deleted file mode 100644
index 6057f58..0000000
--- a/front_end/resources/AppManifestView.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!SDK.ResourceTreeModel>}
- * @unrestricted
- */
-Resources.AppManifestView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('resources/appManifestView.css');
-
-    this._emptyView = new UI.EmptyWidget(Common.UIString('No manifest detected'));
-    const p = this._emptyView.appendParagraph();
-    const linkElement = UI.XLink.create(
-        'https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/?utm_source=devtools',
-        Common.UIString('Read more about the web manifest'));
-    p.appendChild(UI.formatLocalized('A web manifest allows you to control how your app behaves when launched and displayed to the user. %s', [linkElement]));
-
-    this._emptyView.show(this.contentElement);
-    this._emptyView.hideWidget();
-
-    this._reportView = new UI.ReportView(Common.UIString('App Manifest'));
-    this._reportView.show(this.contentElement);
-    this._reportView.hideWidget();
-
-    this._errorsSection = this._reportView.appendSection(Common.UIString('Errors and warnings'));
-    this._identitySection = this._reportView.appendSection(Common.UIString('Identity'));
-    const toolbar = this._identitySection.createToolbar();
-    toolbar.renderAsLinks();
-    const addToHomeScreen =
-        new UI.ToolbarButton(Common.UIString('Add to homescreen'), undefined, Common.UIString('Add to homescreen'));
-    addToHomeScreen.addEventListener(UI.ToolbarButton.Events.Click, this._addToHomescreen, this);
-    toolbar.appendToolbarItem(addToHomeScreen);
-
-    this._presentationSection = this._reportView.appendSection(Common.UIString('Presentation'));
-    this._iconsSection = this._reportView.appendSection(Common.UIString('Icons'));
-
-    this._nameField = this._identitySection.appendField(Common.UIString('Name'));
-    this._shortNameField = this._identitySection.appendField(Common.UIString('Short name'));
-
-    this._startURLField = this._presentationSection.appendField(Common.UIString('Start URL'));
-
-    const themeColorField = this._presentationSection.appendField(Common.UIString('Theme color'));
-    this._themeColorSwatch = InlineEditor.ColorSwatch.create();
-    themeColorField.appendChild(this._themeColorSwatch);
-
-    const backgroundColorField = this._presentationSection.appendField(Common.UIString('Background color'));
-    this._backgroundColorSwatch = InlineEditor.ColorSwatch.create();
-    backgroundColorField.appendChild(this._backgroundColorSwatch);
-
-    this._orientationField = this._presentationSection.appendField(Common.UIString('Orientation'));
-    this._displayField = this._presentationSection.appendField(Common.UIString('Display'));
-
-    SDK.targetManager.observeModels(SDK.ResourceTreeModel, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  modelAdded(resourceTreeModel) {
-    if (this._resourceTreeModel)
-      return;
-    this._resourceTreeModel = resourceTreeModel;
-    this._updateManifest();
-    resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated, this._updateManifest, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  modelRemoved(resourceTreeModel) {
-    if (!this._resourceTreeModel || this._resourceTreeModel !== resourceTreeModel)
-      return;
-    resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated, this._updateManifest, this);
-    delete this._resourceTreeModel;
-  }
-
-  _updateManifest() {
-    this._resourceTreeModel.fetchAppManifest(this._renderManifest.bind(this));
-  }
-
-  /**
-   * @param {string} url
-   * @param {?string} data
-   * @param {!Array<!Protocol.Page.AppManifestError>} errors
-   */
-  _renderManifest(url, data, errors) {
-    if (!data && !errors.length) {
-      this._emptyView.showWidget();
-      this._reportView.hideWidget();
-      return;
-    }
-    this._emptyView.hideWidget();
-    this._reportView.showWidget();
-
-    this._reportView.setURL(Components.Linkifier.linkifyURL(url));
-    this._errorsSection.clearContent();
-    this._errorsSection.element.classList.toggle('hidden', !errors.length);
-    for (const error of errors) {
-      this._errorsSection.appendRow().appendChild(
-          UI.createLabel(error.message, error.critical ? 'smallicon-error' : 'smallicon-warning'));
-    }
-
-    if (!data)
-      return;
-
-    if (data.charCodeAt(0) === 0xFEFF)
-      data = data.slice(1);  // Trim the BOM as per https://tools.ietf.org/html/rfc7159#section-8.1.
-
-    const parsedManifest = JSON.parse(data);
-    this._nameField.textContent = stringProperty('name');
-    this._shortNameField.textContent = stringProperty('short_name');
-    this._startURLField.removeChildren();
-    const startURL = stringProperty('start_url');
-    if (startURL) {
-      const completeURL = /** @type {string} */ (Common.ParsedURL.completeURL(url, startURL));
-      this._startURLField.appendChild(Components.Linkifier.linkifyURL(completeURL, {text: startURL}));
-    }
-
-    this._themeColorSwatch.classList.toggle('hidden', !stringProperty('theme_color'));
-    const themeColor = Common.Color.parse(stringProperty('theme_color') || 'white') || Common.Color.parse('white');
-    this._themeColorSwatch.setColor(/** @type {!Common.Color} */ (themeColor));
-    this._backgroundColorSwatch.classList.toggle('hidden', !stringProperty('background_color'));
-    const backgroundColor =
-        Common.Color.parse(stringProperty('background_color') || 'white') || Common.Color.parse('white');
-    this._backgroundColorSwatch.setColor(/** @type {!Common.Color} */ (backgroundColor));
-
-    this._orientationField.textContent = stringProperty('orientation');
-    this._displayField.textContent = stringProperty('display');
-
-    const icons = parsedManifest['icons'] || [];
-    this._iconsSection.clearContent();
-    for (const icon of icons) {
-      const title = (icon['sizes'] || '') + '\n' + (icon['type'] || '');
-      const field = this._iconsSection.appendField(title);
-      const imageElement = field.createChild('img');
-      imageElement.style.maxWidth = '200px';
-      imageElement.style.maxHeight = '200px';
-      imageElement.src = Common.ParsedURL.completeURL(url, icon['src']);
-    }
-
-    /**
-     * @param {string} name
-     * @return {string}
-     */
-    function stringProperty(name) {
-      const value = parsedManifest[name];
-      if (typeof value !== 'string')
-        return '';
-      return value;
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _addToHomescreen(event) {
-    const target = SDK.targetManager.mainTarget();
-    if (target && target.hasBrowserCapability()) {
-      target.pageAgent().requestAppBanner();
-      Common.console.show();
-    }
-  }
-};
diff --git a/front_end/resources/ApplicationCacheItemsView.js b/front_end/resources/ApplicationCacheItemsView.js
deleted file mode 100644
index 6c2373b..0000000
--- a/front_end/resources/ApplicationCacheItemsView.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.ApplicationCacheItemsView = class extends UI.SimpleView {
-  constructor(model, frameId) {
-    super(Common.UIString('AppCache'));
-
-    this._model = model;
-
-    this.element.classList.add('storage-view', 'table');
-
-    this._deleteButton = new UI.ToolbarButton(Common.UIString('Delete'), 'largeicon-delete');
-    this._deleteButton.setVisible(false);
-    this._deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._deleteButtonClicked, this);
-
-    this._connectivityIcon = createElement('label', 'dt-icon-label');
-    this._connectivityIcon.style.margin = '0 2px 0 5px';
-    this._statusIcon = createElement('label', 'dt-icon-label');
-    this._statusIcon.style.margin = '0 2px 0 5px';
-
-    this._frameId = frameId;
-
-    this._emptyWidget = new UI.EmptyWidget(Common.UIString('No Application Cache information available.'));
-    this._emptyWidget.show(this.element);
-
-    this._markDirty();
-
-    const status = this._model.frameManifestStatus(frameId);
-    this.updateStatus(status);
-    this.updateNetworkState(this._model.onLine);
-
-    // FIXME: Status bar items don't work well enough yet, so they are being hidden.
-    // http://webkit.org/b/41637 Web Inspector: Give Semantics to "Refresh" and "Delete" Buttons in ApplicationCache DataGrid
-    this._deleteButton.element.style.display = 'none';
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return [
-      this._deleteButton, new UI.ToolbarItem(this._connectivityIcon), new UI.ToolbarSeparator(),
-      new UI.ToolbarItem(this._statusIcon)
-    ];
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._maybeUpdate();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._deleteButton.setVisible(false);
-  }
-
-  _maybeUpdate() {
-    if (!this.isShowing() || !this._viewDirty)
-      return;
-
-    this._update();
-    this._viewDirty = false;
-  }
-
-  _markDirty() {
-    this._viewDirty = true;
-  }
-
-  /**
-   * @param {number} status
-   */
-  updateStatus(status) {
-    const oldStatus = this._status;
-    this._status = status;
-
-    const statusInformation = {};
-    // We should never have UNCACHED status, since we remove frames with UNCACHED application cache status from the tree.
-    statusInformation[applicationCache.UNCACHED] = {type: 'smallicon-red-ball', text: 'UNCACHED'};
-    statusInformation[applicationCache.IDLE] = {type: 'smallicon-green-ball', text: 'IDLE'};
-    statusInformation[applicationCache.CHECKING] = {type: 'smallicon-orange-ball', text: 'CHECKING'};
-    statusInformation[applicationCache.DOWNLOADING] = {type: 'smallicon-orange-ball', text: 'DOWNLOADING'};
-    statusInformation[applicationCache.UPDATEREADY] = {type: 'smallicon-green-ball', text: 'UPDATEREADY'};
-    statusInformation[applicationCache.OBSOLETE] = {type: 'smallicon-red-ball', text: 'OBSOLETE'};
-
-    const info = statusInformation[status] || statusInformation[applicationCache.UNCACHED];
-
-    this._statusIcon.type = info.type;
-    this._statusIcon.textContent = info.text;
-
-    if (this.isShowing() && this._status === applicationCache.IDLE &&
-        (oldStatus === applicationCache.UPDATEREADY || !this._resources))
-      this._markDirty();
-    this._maybeUpdate();
-  }
-
-  /**
-   * @param {boolean} isNowOnline
-   */
-  updateNetworkState(isNowOnline) {
-    if (isNowOnline) {
-      this._connectivityIcon.type = 'smallicon-green-ball';
-      this._connectivityIcon.textContent = Common.UIString('Online');
-    } else {
-      this._connectivityIcon.type = 'smallicon-red-ball';
-      this._connectivityIcon.textContent = Common.UIString('Offline');
-    }
-  }
-
-  async _update() {
-    const applicationCache = await this._model.requestApplicationCache(this._frameId);
-
-    if (!applicationCache || !applicationCache.manifestURL) {
-      delete this._manifest;
-      delete this._creationTime;
-      delete this._updateTime;
-      delete this._size;
-      delete this._resources;
-
-      this._emptyWidget.show(this.element);
-      this._deleteButton.setVisible(false);
-      if (this._dataGrid)
-        this._dataGrid.element.classList.add('hidden');
-      return;
-    }
-    // FIXME: are these variables needed anywhere else?
-    this._manifest = applicationCache.manifestURL;
-    this._creationTime = applicationCache.creationTime;
-    this._updateTime = applicationCache.updateTime;
-    this._size = applicationCache.size;
-    this._resources = applicationCache.resources;
-
-    if (!this._dataGrid)
-      this._createDataGrid();
-
-    this._populateDataGrid();
-    this._dataGrid.autoSizeColumns(20, 80);
-    this._dataGrid.element.classList.remove('hidden');
-    this._emptyWidget.detach();
-    this._deleteButton.setVisible(true);
-
-    // FIXME: For Chrome, put creationTime and updateTime somewhere.
-    // NOTE: localizedString has not yet been added.
-    // Common.UIString("(%s) Created: %s Updated: %s", this._size, this._creationTime, this._updateTime);
-  }
-
-  _createDataGrid() {
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'resource', title: Common.UIString('Resource'), sort: DataGrid.DataGrid.Order.Ascending, sortable: true},
-      {id: 'type', title: Common.UIString('Type'), sortable: true},
-      {id: 'size', title: Common.UIString('Size'), align: DataGrid.DataGrid.Align.Right, sortable: true}
-    ]);
-    this._dataGrid = new DataGrid.DataGrid(columns);
-    this._dataGrid.setStriped(true);
-    this._dataGrid.asWidget().show(this.element);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._populateDataGrid, this);
-  }
-
-  _populateDataGrid() {
-    const selectedResource = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.resource : null;
-    const sortDirection = this._dataGrid.isSortOrderAscending() ? 1 : -1;
-
-    function numberCompare(field, resource1, resource2) {
-      return sortDirection * (resource1[field] - resource2[field]);
-    }
-    function localeCompare(field, resource1, resource2) {
-      return sortDirection * (resource1[field] + '').localeCompare(resource2[field] + '');
-    }
-
-    let comparator;
-    switch (this._dataGrid.sortColumnId()) {
-      case 'resource':
-        comparator = localeCompare.bind(null, 'url');
-        break;
-      case 'type':
-        comparator = localeCompare.bind(null, 'type');
-        break;
-      case 'size':
-        comparator = numberCompare.bind(null, 'size');
-        break;
-      default:
-        localeCompare.bind(null, 'resource');  // FIXME: comparator = ?
-    }
-
-    this._resources.sort(comparator);
-    this._dataGrid.rootNode().removeChildren();
-
-    let nodeToSelect;
-    for (let i = 0; i < this._resources.length; ++i) {
-      const data = {};
-      const resource = this._resources[i];
-      data.resource = resource.url;
-      data.type = resource.type;
-      data.size = Number.bytesToString(resource.size);
-      const node = new DataGrid.DataGridNode(data);
-      node.resource = resource;
-      node.selectable = true;
-      this._dataGrid.rootNode().appendChild(node);
-      if (resource === selectedResource) {
-        nodeToSelect = node;
-        nodeToSelect.selected = true;
-      }
-    }
-
-    if (!nodeToSelect && this._dataGrid.rootNode().children.length)
-      this._dataGrid.rootNode().children[0].selected = true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _deleteButtonClicked(event) {
-    if (!this._dataGrid || !this._dataGrid.selectedNode)
-      return;
-
-    // FIXME: Delete Button semantics are not yet defined. (Delete a single, or all?)
-    this._deleteCallback(this._dataGrid.selectedNode);
-  }
-
-  _deleteCallback(node) {
-    // FIXME: Should we delete a single (selected) resource or all resources?
-    // Protocol.inspectorBackend.deleteCachedResource(...)
-    // this._update();
-  }
-};
diff --git a/front_end/resources/ApplicationCacheModel.js b/front_end/resources/ApplicationCacheModel.js
deleted file mode 100644
index ffed9b6..0000000
--- a/front_end/resources/ApplicationCacheModel.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.ApplicationCacheModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    target.registerApplicationCacheDispatcher(new Resources.ApplicationCacheDispatcher(this));
-    this._agent = target.applicationCacheAgent();
-    this._agent.enable();
-
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this);
-    resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameDetached, this._frameDetached, this);
-
-    this._statuses = {};
-    this._manifestURLsByFrame = {};
-
-    this._mainFrameNavigated();
-    this._onLine = true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  async _frameNavigated(event) {
-    const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    if (frame.isMainFrame()) {
-      this._mainFrameNavigated();
-      return;
-    }
-
-    const frameId = frame.id;
-    const manifestURL = await this._agent.getManifestForFrame(frameId);
-    if (manifestURL !== null && !manifestURL)
-      this._frameManifestRemoved(frameId);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameDetached(event) {
-    const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
-    this._frameManifestRemoved(frame.id);
-  }
-
-  reset() {
-    this._statuses = {};
-    this._manifestURLsByFrame = {};
-    this.dispatchEventToListeners(Resources.ApplicationCacheModel.Events.FrameManifestsReset);
-  }
-
-  async _mainFrameNavigated() {
-    const framesWithManifests = await this._agent.getFramesWithManifests();
-    for (const frame of framesWithManifests || [])
-      this._frameManifestUpdated(frame.frameId, frame.manifestURL, frame.status);
-  }
-
-  /**
-   * @param {string} frameId
-   * @param {string} manifestURL
-   * @param {number} status
-   */
-  _frameManifestUpdated(frameId, manifestURL, status) {
-    if (status === applicationCache.UNCACHED) {
-      this._frameManifestRemoved(frameId);
-      return;
-    }
-
-    if (!manifestURL)
-      return;
-
-    if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
-      this._frameManifestRemoved(frameId);
-
-    const statusChanged = this._statuses[frameId] !== status;
-    this._statuses[frameId] = status;
-
-    if (!this._manifestURLsByFrame[frameId]) {
-      this._manifestURLsByFrame[frameId] = manifestURL;
-      this.dispatchEventToListeners(Resources.ApplicationCacheModel.Events.FrameManifestAdded, frameId);
-    }
-
-    if (statusChanged)
-      this.dispatchEventToListeners(Resources.ApplicationCacheModel.Events.FrameManifestStatusUpdated, frameId);
-  }
-
-  /**
-   * @param {string} frameId
-   */
-  _frameManifestRemoved(frameId) {
-    if (!this._manifestURLsByFrame[frameId])
-      return;
-
-    delete this._manifestURLsByFrame[frameId];
-    delete this._statuses[frameId];
-
-    this.dispatchEventToListeners(Resources.ApplicationCacheModel.Events.FrameManifestRemoved, frameId);
-  }
-
-  /**
-   * @param {string} frameId
-   * @return {string}
-   */
-  frameManifestURL(frameId) {
-    return this._manifestURLsByFrame[frameId] || '';
-  }
-
-  /**
-   * @param {string} frameId
-   * @return {number}
-   */
-  frameManifestStatus(frameId) {
-    return this._statuses[frameId] || applicationCache.UNCACHED;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get onLine() {
-    return this._onLine;
-  }
-
-  /**
-   * @param {string} frameId
-   * @param {string} manifestURL
-   * @param {number} status
-   */
-  _statusUpdated(frameId, manifestURL, status) {
-    this._frameManifestUpdated(frameId, manifestURL, status);
-  }
-
-  /**
-   * @param {string} frameId
-   * @return {!Promise<?Protocol.ApplicationCache.ApplicationCache>}
-   */
-  requestApplicationCache(frameId) {
-    return this._agent.getApplicationCacheForFrame(frameId);
-  }
-
-  /**
-   * @param {boolean} isNowOnline
-   */
-  _networkStateUpdated(isNowOnline) {
-    this._onLine = isNowOnline;
-    this.dispatchEventToListeners(Resources.ApplicationCacheModel.Events.NetworkStateChanged, isNowOnline);
-  }
-};
-
-SDK.SDKModel.register(Resources.ApplicationCacheModel, SDK.Target.Capability.DOM, false);
-
-/** @enum {symbol} */
-Resources.ApplicationCacheModel.Events = {
-  FrameManifestStatusUpdated: Symbol('FrameManifestStatusUpdated'),
-  FrameManifestAdded: Symbol('FrameManifestAdded'),
-  FrameManifestRemoved: Symbol('FrameManifestRemoved'),
-  FrameManifestsReset: Symbol('FrameManifestsReset'),
-  NetworkStateChanged: Symbol('NetworkStateChanged')
-};
-
-/**
- * @implements {Protocol.ApplicationCacheDispatcher}
- * @unrestricted
- */
-Resources.ApplicationCacheDispatcher = class {
-  constructor(applicationCacheModel) {
-    this._applicationCacheModel = applicationCacheModel;
-  }
-
-  /**
-   * @override
-   * @param {string} frameId
-   * @param {string} manifestURL
-   * @param {number} status
-   */
-  applicationCacheStatusUpdated(frameId, manifestURL, status) {
-    this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
-  }
-
-  /**
-   * @override
-   * @param {boolean} isNowOnline
-   */
-  networkStateUpdated(isNowOnline) {
-    this._applicationCacheModel._networkStateUpdated(isNowOnline);
-  }
-};
diff --git a/front_end/resources/ApplicationPanelSidebar.js b/front_end/resources/ApplicationPanelSidebar.js
deleted file mode 100644
index ae46e2c..0000000
--- a/front_end/resources/ApplicationPanelSidebar.js
+++ /dev/null
@@ -1,1674 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2010 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-Resources.ApplicationPanelSidebar = class extends UI.VBox {
-  /**
-   * @param {!Resources.ResourcesPanel} panel
-   */
-  constructor(panel) {
-    super();
-
-    this._panel = panel;
-
-    this._sidebarTree = new UI.TreeOutlineInShadow();
-    this._sidebarTree.element.classList.add('resources-sidebar');
-    this._sidebarTree.registerRequiredCSS('resources/resourcesSidebar.css');
-    this._sidebarTree.element.classList.add('filter-all');
-    // Listener needs to have been set up before the elements are added
-    this._sidebarTree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._treeElementAdded, this);
-
-    this.contentElement.appendChild(this._sidebarTree.element);
-    this._applicationTreeElement = this._addSidebarSection(Common.UIString('Application'));
-    const manifestTreeElement = new Resources.AppManifestTreeElement(panel);
-    this._applicationTreeElement.appendChild(manifestTreeElement);
-    this.serviceWorkersTreeElement = new Resources.ServiceWorkersTreeElement(panel);
-    this._applicationTreeElement.appendChild(this.serviceWorkersTreeElement);
-    const clearStorageTreeElement = new Resources.ClearStorageTreeElement(panel);
-    this._applicationTreeElement.appendChild(clearStorageTreeElement);
-
-    const storageTreeElement = this._addSidebarSection(Common.UIString('Storage'));
-    this.localStorageListTreeElement =
-        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Local Storage'), 'LocalStorage');
-    const localStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.localStorageListTreeElement.setLeadingIcons([localStorageIcon]);
-
-    storageTreeElement.appendChild(this.localStorageListTreeElement);
-    this.sessionStorageListTreeElement =
-        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Session Storage'), 'SessionStorage');
-    const sessionStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.sessionStorageListTreeElement.setLeadingIcons([sessionStorageIcon]);
-
-    storageTreeElement.appendChild(this.sessionStorageListTreeElement);
-    this.indexedDBListTreeElement = new Resources.IndexedDBTreeElement(panel);
-    storageTreeElement.appendChild(this.indexedDBListTreeElement);
-    this.databasesListTreeElement =
-        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Web SQL'), 'Databases');
-    const databaseIcon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
-    this.databasesListTreeElement.setLeadingIcons([databaseIcon]);
-
-    storageTreeElement.appendChild(this.databasesListTreeElement);
-    this.cookieListTreeElement = new Resources.StorageCategoryTreeElement(panel, Common.UIString('Cookies'), 'Cookies');
-    const cookieIcon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item');
-    this.cookieListTreeElement.setLeadingIcons([cookieIcon]);
-    storageTreeElement.appendChild(this.cookieListTreeElement);
-
-    const cacheTreeElement = this._addSidebarSection(Common.UIString('Cache'));
-    this.cacheStorageListTreeElement = new Resources.ServiceWorkerCacheTreeElement(panel);
-    cacheTreeElement.appendChild(this.cacheStorageListTreeElement);
-    this.applicationCacheListTreeElement =
-        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Application Cache'), 'ApplicationCache');
-    const applicationCacheIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.applicationCacheListTreeElement.setLeadingIcons([applicationCacheIcon]);
-
-    cacheTreeElement.appendChild(this.applicationCacheListTreeElement);
-
-    this._resourcesSection = new Resources.ResourcesSection(panel, this._addSidebarSection(Common.UIString('Frames')));
-
-    /** @type {!Map.<!Resources.Database, !Object.<string, !Resources.DatabaseTableView>>} */
-    this._databaseTableViews = new Map();
-    /** @type {!Map.<!Resources.Database, !Resources.DatabaseQueryView>} */
-    this._databaseQueryViews = new Map();
-    /** @type {!Map.<!Resources.Database, !Resources.DatabaseTreeElement>} */
-    this._databaseTreeElements = new Map();
-    /** @type {!Map.<!Resources.DOMStorage, !Resources.DOMStorageTreeElement>} */
-    this._domStorageTreeElements = new Map();
-    /** @type {!Object.<string, boolean>} */
-    this._domains = {};
-
-    this._sidebarTree.contentElement.addEventListener('mousemove', this._onmousemove.bind(this), false);
-    this._sidebarTree.contentElement.addEventListener('mouseleave', this._onmouseleave.bind(this), false);
-
-    SDK.targetManager.observeTargets(this);
-    SDK.targetManager.addModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this);
-
-    const selection = this._panel.lastSelectedItemPath();
-    if (!selection.length)
-      manifestTreeElement.select();
-  }
-
-  /**
-   * @param {string} title
-   * @return {!UI.TreeElement}
-   */
-  _addSidebarSection(title) {
-    const treeElement = new UI.TreeElement(title, true);
-    treeElement.listItemElement.classList.add('storage-group-list-item');
-    treeElement.setCollapsible(false);
-    treeElement.selectable = false;
-    this._sidebarTree.appendChild(treeElement);
-    return treeElement;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    if (this._target)
-      return;
-    this._target = target;
-    this._databaseModel = target.model(Resources.DatabaseModel);
-    this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
-    this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this);
-
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (!resourceTreeModel)
-      return;
-
-    if (resourceTreeModel.cachedResourcesLoaded())
-      this._initialize();
-
-    resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this);
-    resourceTreeModel.addEventListener(
-        SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    if (target !== this._target)
-      return;
-    delete this._target;
-
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (resourceTreeModel) {
-      resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this);
-      resourceTreeModel.removeEventListener(
-          SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this);
-    }
-    this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
-    this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this);
-
-    this._resetWithFrames();
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._sidebarTree.focus();
-  }
-
-  _initialize() {
-    for (const frame of SDK.ResourceTreeModel.frames())
-      this._addCookieDocument(frame);
-    this._databaseModel.enable();
-
-    const indexedDBModel = this._target.model(Resources.IndexedDBModel);
-    if (indexedDBModel)
-      indexedDBModel.enable();
-
-    const cacheStorageModel = this._target.model(SDK.ServiceWorkerCacheModel);
-    if (cacheStorageModel)
-      cacheStorageModel.enable();
-    const resourceTreeModel = this._target.model(SDK.ResourceTreeModel);
-    if (resourceTreeModel)
-      this._populateApplicationCacheTree(resourceTreeModel);
-    const domStorageModel = this._target.model(Resources.DOMStorageModel);
-    if (domStorageModel)
-      this._populateDOMStorageTree(domStorageModel);
-    this.indexedDBListTreeElement._initialize();
-    const serviceWorkerCacheModel = this._target.model(SDK.ServiceWorkerCacheModel);
-    this.cacheStorageListTreeElement._initialize(serviceWorkerCacheModel);
-  }
-
-  _resetWithFrames() {
-    this._resourcesSection.reset();
-    this._reset();
-  }
-
-  _resetWebSQL() {
-    const queryViews = this._databaseQueryViews.valuesArray();
-    for (let i = 0; i < queryViews.length; ++i) {
-      queryViews[i].removeEventListener(
-          Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
-    }
-    this._databaseTableViews.clear();
-    this._databaseQueryViews.clear();
-    this._databaseTreeElements.clear();
-    this.databasesListTreeElement.removeChildren();
-    this.databasesListTreeElement.setExpandable(false);
-  }
-
-  _resetAppCache() {
-    for (const frameId of Object.keys(this._applicationCacheFrameElements))
-      this._applicationCacheFrameManifestRemoved({data: frameId});
-    this.applicationCacheListTreeElement.setExpandable(false);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _treeElementAdded(event) {
-    const selection = this._panel.lastSelectedItemPath();
-    if (!selection.length)
-      return;
-    const element = event.data;
-    const index = selection.indexOf(element.itemURL);
-    if (index < 0)
-      return;
-    for (let parent = element.parent; parent; parent = parent.parent)
-      parent.expand();
-    if (index > 0)
-      element.expand();
-    element.select();
-  }
-
-  _reset() {
-    this._domains = {};
-    this._resetWebSQL();
-    this.cookieListTreeElement.removeChildren();
-  }
-
-  _frameNavigated(event) {
-    const frame = event.data;
-
-    if (frame.isTopFrame())
-      this._reset();
-
-    const applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frame.id];
-    if (applicationCacheFrameTreeElement)
-      applicationCacheFrameTreeElement.frameNavigated(frame);
-    this._addCookieDocument(frame);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _databaseAdded(event) {
-    const database = /** @type {!Resources.Database} */ (event.data);
-    const databaseTreeElement = new Resources.DatabaseTreeElement(this, database);
-    this._databaseTreeElements.set(database, databaseTreeElement);
-    this.databasesListTreeElement.appendChild(databaseTreeElement);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _addCookieDocument(frame) {
-    const parsedURL = frame.url.asParsedURL();
-    if (!parsedURL || (parsedURL.scheme !== 'http' && parsedURL.scheme !== 'https' && parsedURL.scheme !== 'file'))
-      return;
-
-    const domain = parsedURL.securityOrigin();
-    if (!this._domains[domain]) {
-      this._domains[domain] = true;
-      const cookieDomainTreeElement = new Resources.CookieTreeElement(this._panel, frame, domain);
-      this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domStorageAdded(event) {
-    const domStorage = /** @type {!Resources.DOMStorage} */ (event.data);
-    this._addDOMStorage(domStorage);
-  }
-
-  /**
-   * @param {!Resources.DOMStorage} domStorage
-   */
-  _addDOMStorage(domStorage) {
-    console.assert(!this._domStorageTreeElements.get(domStorage));
-
-    const domStorageTreeElement = new Resources.DOMStorageTreeElement(this._panel, domStorage);
-    this._domStorageTreeElements.set(domStorage, domStorageTreeElement);
-    if (domStorage.isLocalStorage)
-      this.localStorageListTreeElement.appendChild(domStorageTreeElement);
-    else
-      this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domStorageRemoved(event) {
-    const domStorage = /** @type {!Resources.DOMStorage} */ (event.data);
-    this._removeDOMStorage(domStorage);
-  }
-
-  /**
-   * @param {!Resources.DOMStorage} domStorage
-   */
-  _removeDOMStorage(domStorage) {
-    const treeElement = this._domStorageTreeElements.get(domStorage);
-    if (!treeElement)
-      return;
-    const wasSelected = treeElement.selected;
-    const parentListTreeElement = treeElement.parent;
-    parentListTreeElement.removeChild(treeElement);
-    if (wasSelected)
-      parentListTreeElement.select();
-    this._domStorageTreeElements.remove(domStorage);
-  }
-
-  /**
-   * @param {!Resources.Database} database
-   */
-  selectDatabase(database) {
-    if (database) {
-      this._showDatabase(database);
-      this._databaseTreeElements.get(database).select();
-    }
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   * @param {number=} line
-   * @param {number=} column
-   * @return {!Promise}
-   */
-  async showResource(resource, line, column) {
-    await this._resourcesSection.revealResource(resource, line, column);
-  }
-
-  /**
-   * @param {!Resources.Database} database
-   * @param {string=} tableName
-   */
-  _showDatabase(database, tableName) {
-    if (!database)
-      return;
-
-    let view;
-    if (tableName) {
-      let tableViews = this._databaseTableViews.get(database);
-      if (!tableViews) {
-        tableViews = /** @type {!Object.<string, !Resources.DatabaseTableView>} */ ({});
-        this._databaseTableViews.set(database, tableViews);
-      }
-      view = tableViews[tableName];
-      if (!view) {
-        view = new Resources.DatabaseTableView(database, tableName);
-        tableViews[tableName] = view;
-      }
-    } else {
-      view = this._databaseQueryViews.get(database);
-      if (!view) {
-        view = new Resources.DatabaseQueryView(database);
-        this._databaseQueryViews.set(database, view);
-        view.addEventListener(Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
-      }
-    }
-
-    this._innerShowView(view);
-  }
-
-  _showApplicationCache(frameId) {
-    if (!this._applicationCacheViews[frameId]) {
-      this._applicationCacheViews[frameId] =
-          new Resources.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
-    }
-
-    this._innerShowView(this._applicationCacheViews[frameId]);
-  }
-
-  /**
-   *  @param {!UI.Widget} view
-   */
-  showFileSystem(view) {
-    this._innerShowView(view);
-  }
-
-  _innerShowView(view) {
-    this._panel.showView(view);
-  }
-
-  _updateDatabaseTables(event) {
-    const database = event.data;
-
-    if (!database)
-      return;
-
-    const databasesTreeElement = this._databaseTreeElements.get(database);
-    if (!databasesTreeElement)
-      return;
-
-    databasesTreeElement.invalidateChildren();
-    const tableViews = this._databaseTableViews.get(database);
-
-    if (!tableViews)
-      return;
-
-    const tableNamesHash = {};
-    const panel = this._panel;
-    function tableNamesCallback(tableNames) {
-      const tableNamesLength = tableNames.length;
-      for (let i = 0; i < tableNamesLength; ++i)
-        tableNamesHash[tableNames[i]] = true;
-
-      for (const tableName in tableViews) {
-        if (!(tableName in tableNamesHash)) {
-          if (panel.visibleView === tableViews[tableName])
-            panel.showView(null);
-          delete tableViews[tableName];
-        }
-      }
-    }
-    database.getTableNames(tableNamesCallback);
-  }
-
-  /**
-   * @param {!Resources.DOMStorageModel} domStorageModel
-   */
-  _populateDOMStorageTree(domStorageModel) {
-    domStorageModel.enable();
-    domStorageModel.storages().forEach(this._addDOMStorage.bind(this));
-    domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
-    domStorageModel.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  _populateApplicationCacheTree(resourceTreeModel) {
-    this._applicationCacheModel = this._target.model(Resources.ApplicationCacheModel);
-
-    this._applicationCacheViews = {};
-    this._applicationCacheFrameElements = {};
-    this._applicationCacheManifestElements = {};
-
-    this._applicationCacheModel.addEventListener(
-        Resources.ApplicationCacheModel.Events.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
-    this._applicationCacheModel.addEventListener(
-        Resources.ApplicationCacheModel.Events.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
-    this._applicationCacheModel.addEventListener(
-        Resources.ApplicationCacheModel.Events.FrameManifestsReset, this._resetAppCache, this);
-
-    this._applicationCacheModel.addEventListener(
-        Resources.ApplicationCacheModel.Events.FrameManifestStatusUpdated,
-        this._applicationCacheFrameManifestStatusChanged, this);
-    this._applicationCacheModel.addEventListener(
-        Resources.ApplicationCacheModel.Events.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
-  }
-
-  _applicationCacheFrameManifestAdded(event) {
-    const frameId = event.data;
-    const manifestURL = this._applicationCacheModel.frameManifestURL(frameId);
-
-    let manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
-    if (!manifestTreeElement) {
-      manifestTreeElement = new Resources.ApplicationCacheManifestTreeElement(this._panel, manifestURL);
-      this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
-      this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
-    }
-
-    const model = this._target.model(SDK.ResourceTreeModel);
-    const frameTreeElement =
-        new Resources.ApplicationCacheFrameTreeElement(this, model.frameForId(frameId), manifestURL);
-    manifestTreeElement.appendChild(frameTreeElement);
-    manifestTreeElement.expand();
-    this._applicationCacheFrameElements[frameId] = frameTreeElement;
-  }
-
-  _applicationCacheFrameManifestRemoved(event) {
-    const frameId = event.data;
-    const frameTreeElement = this._applicationCacheFrameElements[frameId];
-    if (!frameTreeElement)
-      return;
-
-    const manifestURL = frameTreeElement.manifestURL;
-    delete this._applicationCacheFrameElements[frameId];
-    delete this._applicationCacheViews[frameId];
-    frameTreeElement.parent.removeChild(frameTreeElement);
-
-    const manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
-    if (manifestTreeElement.childCount())
-      return;
-
-    delete this._applicationCacheManifestElements[manifestURL];
-    manifestTreeElement.parent.removeChild(manifestTreeElement);
-  }
-
-  _applicationCacheFrameManifestStatusChanged(event) {
-    const frameId = event.data;
-    const status = this._applicationCacheModel.frameManifestStatus(frameId);
-
-    if (this._applicationCacheViews[frameId])
-      this._applicationCacheViews[frameId].updateStatus(status);
-  }
-
-  _applicationCacheNetworkStateChanged(event) {
-    const isNowOnline = event.data;
-
-    for (const manifestURL in this._applicationCacheViews)
-      this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
-  }
-
-  showView(view) {
-    if (view)
-      this.showResource(view.resource);
-  }
-
-  _onmousemove(event) {
-    const nodeUnderMouse = event.target;
-    if (!nodeUnderMouse)
-      return;
-
-    const listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName('li');
-    if (!listNode)
-      return;
-
-    const element = listNode.treeElement;
-    if (this._previousHoveredElement === element)
-      return;
-
-    if (this._previousHoveredElement) {
-      this._previousHoveredElement.hovered = false;
-      delete this._previousHoveredElement;
-    }
-
-    if (element instanceof Resources.FrameTreeElement) {
-      this._previousHoveredElement = element;
-      element.hovered = true;
-    }
-  }
-
-  _onmouseleave(event) {
-    if (this._previousHoveredElement) {
-      this._previousHoveredElement.hovered = false;
-      delete this._previousHoveredElement;
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.BaseStorageTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {string} title
-   * @param {boolean} expandable
-   */
-  constructor(storagePanel, title, expandable) {
-    super(title, expandable);
-    this._storagePanel = storagePanel;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    if (!selectedByUser)
-      return false;
-
-    const path = [];
-    for (let el = this; el; el = el.parent) {
-      const url = el.itemURL;
-      if (!url)
-        break;
-      path.push(url);
-    }
-    this._storagePanel.setLastSelectedItemPath(path);
-
-    return false;
-  }
-
-  /**
-   * @protected
-   * @param {?UI.Widget} view
-   */
-  showView(view) {
-    this._storagePanel.showView(view);
-  }
-};
-
-Resources.StorageCategoryTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {string} categoryName
-   * @param {string} settingsKey
-   */
-  constructor(storagePanel, categoryName, settingsKey) {
-    super(storagePanel, categoryName, false);
-    this._expandedSetting =
-        Common.settings.createSetting('resources' + settingsKey + 'Expanded', settingsKey === 'Frames');
-    this._categoryName = categoryName;
-  }
-
-
-  get itemURL() {
-    return 'category://' + this._categoryName;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._storagePanel.showCategoryView(this._categoryName);
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    if (this._expandedSetting.get())
-      this.expand();
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    this._expandedSetting.set(true);
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    this._expandedSetting.set(false);
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.DatabaseTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ApplicationPanelSidebar} sidebar
-   * @param {!Resources.Database} database
-   */
-  constructor(sidebar, database) {
-    super(sidebar._panel, database.name, true);
-    this._sidebar = sidebar;
-    this._database = database;
-
-    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    return 'database://' + encodeURI(this._database.name);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._sidebar._showDatabase(this._database);
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    this._updateChildren();
-  }
-
-  async _updateChildren() {
-    const tableNames = await this._database.tableNames();
-    for (const tableName of tableNames)
-      this.appendChild(new Resources.DatabaseTableTreeElement(this._sidebar, this._database, tableName));
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.DatabaseTableTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ApplicationPanelSidebar} sidebar
-   * @param {!Resources.Database} database
-   * @param {string} tableName
-   */
-  constructor(sidebar, database, tableName) {
-    super(sidebar._panel, tableName, false);
-    this._sidebar = sidebar;
-    this._database = database;
-    this._tableName = tableName;
-    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    return 'database://' + encodeURI(this._database.name) + '/' + encodeURI(this._tableName);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._sidebar._showDatabase(this._database, this._tableName);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.ServiceWorkerCacheTreeElement = class extends Resources.StorageCategoryTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   */
-  constructor(storagePanel) {
-    super(storagePanel, Common.UIString('Cache Storage'), 'CacheStorage');
-    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-    /** @type {?SDK.ServiceWorkerCacheModel} */
-    this._swCacheModel = null;
-  }
-
-  /**
-   * @param {?SDK.ServiceWorkerCacheModel} model
-   */
-  _initialize(model) {
-    /** @type {!Array.<!Resources.SWCacheTreeElement>} */
-    this._swCacheTreeElements = [];
-    this._swCacheModel = model;
-    if (model) {
-      for (const cache of model.caches())
-        this._addCache(model, cache);
-    }
-    SDK.targetManager.addModelListener(
-        SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheAdded, this._cacheAdded, this);
-    SDK.targetManager.addModelListener(
-        SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheRemoved, this._cacheRemoved, this);
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Refresh Caches'), this._refreshCaches.bind(this));
-    contextMenu.show();
-  }
-
-  _refreshCaches() {
-    if (this._swCacheModel)
-      this._swCacheModel.refreshCacheNames();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _cacheAdded(event) {
-    const cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache);
-    const model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model);
-    this._addCache(model, cache);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel} model
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  _addCache(model, cache) {
-    const swCacheTreeElement = new Resources.SWCacheTreeElement(this._storagePanel, model, cache);
-    this._swCacheTreeElements.push(swCacheTreeElement);
-    this.appendChild(swCacheTreeElement);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _cacheRemoved(event) {
-    const cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache);
-    const model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model);
-
-    const swCacheTreeElement = this._cacheTreeElement(model, cache);
-    if (!swCacheTreeElement)
-      return;
-
-    this.removeChild(swCacheTreeElement);
-    this._swCacheTreeElements.remove(swCacheTreeElement);
-    this.setExpandable(this.childCount() > 0);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel} model
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   * @return {?Resources.SWCacheTreeElement}
-   */
-  _cacheTreeElement(model, cache) {
-    let index = -1;
-    let i;
-    for (i = 0; i < this._swCacheTreeElements.length; ++i) {
-      if (this._swCacheTreeElements[i]._cache.equals(cache) && this._swCacheTreeElements[i]._model === model) {
-        index = i;
-        break;
-      }
-    }
-    if (index !== -1)
-      return this._swCacheTreeElements[i];
-    return null;
-  }
-};
-
-Resources.SWCacheTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!SDK.ServiceWorkerCacheModel} model
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  constructor(storagePanel, model, cache) {
-    super(storagePanel, cache.cacheName + ' - ' + cache.securityOrigin, false);
-    this._model = model;
-    this._cache = cache;
-    /** @type {?Resources.ServiceWorkerCacheView} */
-    this._view = null;
-    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    // I don't think this will work at all.
-    return 'cache://' + this._cache.cacheId;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Delete'), this._clearCache.bind(this));
-    contextMenu.show();
-  }
-
-  _clearCache() {
-    this._model.deleteCache(this._cache);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  update(cache) {
-    this._cache = cache;
-    if (this._view)
-      this._view.update(cache);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.ServiceWorkerCacheView(this._model, this._cache);
-
-    this.showView(this._view);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.ServiceWorkersTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   */
-  constructor(storagePanel) {
-    super(storagePanel, Common.UIString('Service Workers'), false);
-    const icon = UI.Icon.create('mediumicon-service-worker', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  /**
-   * @return {string}
-   */
-  get itemURL() {
-    return 'service-workers://';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.ServiceWorkersView();
-    this.showView(this._view);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.AppManifestTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   */
-  constructor(storagePanel) {
-    super(storagePanel, Common.UIString('Manifest'), false);
-    const icon = UI.Icon.create('mediumicon-manifest', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  /**
-   * @return {string}
-   */
-  get itemURL() {
-    return 'manifest://';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.AppManifestView();
-    this.showView(this._view);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.ClearStorageTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   */
-  constructor(storagePanel) {
-    super(storagePanel, Common.UIString('Clear storage'), false);
-    const icon = UI.Icon.create('mediumicon-clear-storage', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  /**
-   * @return {string}
-   */
-  get itemURL() {
-    return 'clear-storage://';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.ClearStorageView();
-    this.showView(this._view);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   */
-  constructor(storagePanel) {
-    super(storagePanel, Common.UIString('IndexedDB'), 'IndexedDB');
-    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  _initialize() {
-    SDK.targetManager.addModelListener(
-        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseAdded, this._indexedDBAdded, this);
-    SDK.targetManager.addModelListener(
-        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseRemoved, this._indexedDBRemoved, this);
-    SDK.targetManager.addModelListener(
-        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseLoaded, this._indexedDBLoaded, this);
-    SDK.targetManager.addModelListener(
-        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.IndexedDBContentUpdated,
-        this._indexedDBContentUpdated, this);
-    /** @type {!Array.<!Resources.IDBDatabaseTreeElement>} */
-    this._idbDatabaseTreeElements = [];
-
-    for (const indexedDBModel of SDK.targetManager.models(Resources.IndexedDBModel)) {
-      const databases = indexedDBModel.databases();
-      for (let j = 0; j < databases.length; ++j)
-        this._addIndexedDB(indexedDBModel, databases[j]);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Refresh IndexedDB'), this.refreshIndexedDB.bind(this));
-    contextMenu.show();
-  }
-
-  refreshIndexedDB() {
-    for (const indexedDBModel of SDK.targetManager.models(Resources.IndexedDBModel))
-      indexedDBModel.refreshDatabaseNames();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _indexedDBAdded(event) {
-    const databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
-    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
-    this._addIndexedDB(model, databaseId);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel} model
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   */
-  _addIndexedDB(model, databaseId) {
-    const idbDatabaseTreeElement = new Resources.IDBDatabaseTreeElement(this._storagePanel, model, databaseId);
-    this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
-    this.appendChild(idbDatabaseTreeElement);
-    model.refreshDatabase(databaseId);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _indexedDBRemoved(event) {
-    const databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
-    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
-
-    const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId);
-    if (!idbDatabaseTreeElement)
-      return;
-
-    idbDatabaseTreeElement.clear();
-    this.removeChild(idbDatabaseTreeElement);
-    this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
-    this.setExpandable(this.childCount() > 0);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _indexedDBLoaded(event) {
-    const database = /** @type {!Resources.IndexedDBModel.Database} */ (event.data.database);
-    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
-    const entriesUpdated = /** @type {boolean} */ (event.data.entriesUpdated);
-
-    const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId);
-    if (!idbDatabaseTreeElement)
-      return;
-    idbDatabaseTreeElement.update(database, entriesUpdated);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _indexedDBContentUpdated(event) {
-    const databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
-    const objectStoreName = /** @type {string} */ (event.data.objectStoreName);
-    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
-
-    const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId);
-    if (!idbDatabaseTreeElement)
-      return;
-    idbDatabaseTreeElement.indexedDBContentUpdated(objectStoreName);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {!Resources.IndexedDBModel} model
-   * @return {?Resources.IDBDatabaseTreeElement}
-   */
-  _idbDatabaseTreeElement(model, databaseId) {
-    let index = -1;
-    let i;
-    for (i = 0; i < this._idbDatabaseTreeElements.length; ++i) {
-      if (this._idbDatabaseTreeElements[i]._databaseId.equals(databaseId) &&
-          this._idbDatabaseTreeElements[i]._model === model) {
-        index = i;
-        break;
-      }
-    }
-    if (index !== -1)
-      return this._idbDatabaseTreeElements[i];
-    return null;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IDBDatabaseTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!Resources.IndexedDBModel} model
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   */
-  constructor(storagePanel, model, databaseId) {
-    super(storagePanel, databaseId.name + ' - ' + databaseId.securityOrigin, false);
-    this._model = model;
-    this._databaseId = databaseId;
-    this._idbObjectStoreTreeElements = {};
-    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-    this._model.addEventListener(Resources.IndexedDBModel.Events.DatabaseNamesRefreshed, this._refreshIndexedDB, this);
-  }
-
-  get itemURL() {
-    return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Refresh IndexedDB'), this._refreshIndexedDB.bind(this));
-    contextMenu.show();
-  }
-
-  _refreshIndexedDB() {
-    this._model.refreshDatabase(this._databaseId);
-  }
-
-  /**
-   * @param {string} objectStoreName
-   */
-  indexedDBContentUpdated(objectStoreName) {
-    if (this._idbObjectStoreTreeElements[objectStoreName])
-      this._idbObjectStoreTreeElements[objectStoreName].markNeedsRefresh();
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.Database} database
-   * @param {boolean} entriesUpdated
-   */
-  update(database, entriesUpdated) {
-    this._database = database;
-    const objectStoreNames = {};
-    for (const objectStoreName in this._database.objectStores) {
-      const objectStore = this._database.objectStores[objectStoreName];
-      objectStoreNames[objectStore.name] = true;
-      if (!this._idbObjectStoreTreeElements[objectStore.name]) {
-        const idbObjectStoreTreeElement =
-            new Resources.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
-        this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
-        this.appendChild(idbObjectStoreTreeElement);
-      }
-      this._idbObjectStoreTreeElements[objectStore.name].update(objectStore, entriesUpdated);
-    }
-    for (const objectStoreName in this._idbObjectStoreTreeElements) {
-      if (!objectStoreNames[objectStoreName])
-        this._objectStoreRemoved(objectStoreName);
-    }
-
-    if (this._view)
-      this._view.update(database);
-
-    this._updateTooltip();
-  }
-
-  _updateTooltip() {
-    this.tooltip = Common.UIString('Version') + ': ' + this._database.version;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view)
-      this._view = new Resources.IDBDatabaseView(this._model, this._database);
-
-    this.showView(this._view);
-    return false;
-  }
-
-  /**
-   * @param {string} objectStoreName
-   */
-  _objectStoreRemoved(objectStoreName) {
-    const objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
-    objectStoreTreeElement.clear();
-    this.removeChild(objectStoreTreeElement);
-    delete this._idbObjectStoreTreeElements[objectStoreName];
-  }
-
-  clear() {
-    for (const objectStoreName in this._idbObjectStoreTreeElements)
-      this._objectStoreRemoved(objectStoreName);
-  }
-};
-
-Resources.IDBObjectStoreTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!Resources.IndexedDBModel} model
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
-   */
-  constructor(storagePanel, model, databaseId, objectStore) {
-    super(storagePanel, objectStore.name, false);
-    this._model = model;
-    this._databaseId = databaseId;
-    this._idbIndexTreeElements = {};
-    this._objectStore = objectStore;
-    /** @type {?Resources.IDBDataView} */
-    this._view = null;
-    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' +
-        this._objectStore.name;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  markNeedsRefresh() {
-    if (this._view)
-      this._view.markNeedsRefresh();
-    for (const indexName in this._idbIndexTreeElements)
-      this._idbIndexTreeElements[indexName].markNeedsRefresh();
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Clear'), this._clearObjectStore.bind(this));
-    contextMenu.show();
-  }
-
-  _refreshObjectStore() {
-    if (this._view)
-      this._view.refreshData();
-    for (const indexName in this._idbIndexTreeElements)
-      this._idbIndexTreeElements[indexName].refreshIndex();
-  }
-
-  async _clearObjectStore() {
-    await this._model.clearObjectStore(this._databaseId, this._objectStore.name);
-    this.update(this._objectStore, true);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
-   * @param {boolean} entriesUpdated
-   */
-  update(objectStore, entriesUpdated) {
-    this._objectStore = objectStore;
-
-    const indexNames = {};
-    for (const indexName in this._objectStore.indexes) {
-      const index = this._objectStore.indexes[indexName];
-      indexNames[index.name] = true;
-      if (!this._idbIndexTreeElements[index.name]) {
-        const idbIndexTreeElement = new Resources.IDBIndexTreeElement(
-            this._storagePanel, this._model, this._databaseId, this._objectStore, index,
-            this._refreshObjectStore.bind(this));
-        this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
-        this.appendChild(idbIndexTreeElement);
-      }
-      this._idbIndexTreeElements[index.name].update(this._objectStore, index, entriesUpdated);
-    }
-    for (const indexName in this._idbIndexTreeElements) {
-      if (!indexNames[indexName])
-        this._indexRemoved(indexName);
-    }
-    for (const indexName in this._idbIndexTreeElements) {
-      if (!indexNames[indexName]) {
-        this.removeChild(this._idbIndexTreeElements[indexName]);
-        delete this._idbIndexTreeElements[indexName];
-      }
-    }
-
-    if (this.childCount())
-      this.expand();
-
-    if (this._view && entriesUpdated)
-      this._view.update(this._objectStore, null);
-
-    this._updateTooltip();
-  }
-
-  _updateTooltip() {
-    const keyPathString = this._objectStore.keyPathString;
-    let tooltipString = keyPathString !== null ? (Common.UIString('Key path: ') + keyPathString) : '';
-    if (this._objectStore.autoIncrement)
-      tooltipString += '\n' + Common.UIString('autoIncrement');
-    this.tooltip = tooltipString;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view) {
-      this._view = new Resources.IDBDataView(
-          this._model, this._databaseId, this._objectStore, null, this._refreshObjectStore.bind(this));
-    }
-
-    this.showView(this._view);
-    return false;
-  }
-
-  /**
-   * @param {string} indexName
-   */
-  _indexRemoved(indexName) {
-    const indexTreeElement = this._idbIndexTreeElements[indexName];
-    indexTreeElement.clear();
-    this.removeChild(indexTreeElement);
-    delete this._idbIndexTreeElements[indexName];
-  }
-
-  clear() {
-    for (const indexName in this._idbIndexTreeElements)
-      this._indexRemoved(indexName);
-    if (this._view)
-      this._view.clear();
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IDBIndexTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!Resources.IndexedDBModel} model
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
-   * @param {!Resources.IndexedDBModel.Index} index
-   * @param {function()} refreshObjectStore
-   */
-  constructor(storagePanel, model, databaseId, objectStore, index, refreshObjectStore) {
-    super(storagePanel, index.name, false);
-    this._model = model;
-    this._databaseId = databaseId;
-    this._objectStore = objectStore;
-    this._index = index;
-    this._refreshObjectStore = refreshObjectStore;
-  }
-
-  get itemURL() {
-    return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' +
-        this._objectStore.name + '/' + this._index.name;
-  }
-
-  markNeedsRefresh() {
-    if (this._view)
-      this._view.markNeedsRefresh();
-  }
-
-  refreshIndex() {
-    if (this._view)
-      this._view.refreshData();
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
-   * @param {!Resources.IndexedDBModel.Index} index
-   * @param {boolean} entriesUpdated
-   */
-  update(objectStore, index, entriesUpdated) {
-    this._objectStore = objectStore;
-    this._index = index;
-
-    if (this._view && entriesUpdated)
-      this._view.update(this._objectStore, this._index);
-
-    this._updateTooltip();
-  }
-
-  _updateTooltip() {
-    const tooltipLines = [];
-    const keyPathString = this._index.keyPathString;
-    tooltipLines.push(Common.UIString('Key path: ') + keyPathString);
-    if (this._index.unique)
-      tooltipLines.push(Common.UIString('unique'));
-    if (this._index.multiEntry)
-      tooltipLines.push(Common.UIString('multiEntry'));
-    this.tooltip = tooltipLines.join('\n');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    if (!this._view) {
-      this._view = new Resources.IDBDataView(
-          this._model, this._databaseId, this._objectStore, this._index, this._refreshObjectStore);
-    }
-
-    this.showView(this._view);
-    return false;
-  }
-
-  clear() {
-    if (this._view)
-      this._view.clear();
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.DOMStorageTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!Resources.DOMStorage} domStorage
-   */
-  constructor(storagePanel, domStorage) {
-    super(storagePanel, domStorage.securityOrigin ? domStorage.securityOrigin : Common.UIString('Local Files'), false);
-    this._domStorage = domStorage;
-    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    return 'storage://' + this._domStorage.securityOrigin + '/' +
-        (this._domStorage.isLocalStorage ? 'local' : 'session');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._storagePanel.showDOMStorage(this._domStorage);
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Clear'), () => this._domStorage.clear());
-    contextMenu.show();
-  }
-};
-
-Resources.CookieTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!SDK.ResourceTreeFrame} frame
-   * @param {string} cookieDomain
-   */
-  constructor(storagePanel, frame, cookieDomain) {
-    super(storagePanel, cookieDomain ? cookieDomain : Common.UIString('Local Files'), false);
-    this._target = frame.resourceTreeModel().target();
-    this._cookieDomain = cookieDomain;
-    const icon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    return 'cookies://' + this._cookieDomain;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(
-        Common.UIString('Clear'), () => this._storagePanel.clearCookies(this._target, this._cookieDomain));
-    contextMenu.show();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._storagePanel.showCookies(this._target, this._cookieDomain);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.ApplicationCacheManifestTreeElement = class extends Resources.BaseStorageTreeElement {
-  constructor(storagePanel, manifestURL) {
-    const title = new Common.ParsedURL(manifestURL).displayName;
-    super(storagePanel, title, false);
-    this.tooltip = manifestURL;
-    this._manifestURL = manifestURL;
-  }
-
-  get itemURL() {
-    return 'appcache://' + this._manifestURL;
-  }
-
-  get manifestURL() {
-    return this._manifestURL;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._storagePanel.showCategoryView(this._manifestURL);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.ApplicationCacheFrameTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ApplicationPanelSidebar} sidebar
-   * @param {!SDK.ResourceTreeFrame} frame
-   * @param {string} manifestURL
-   */
-  constructor(sidebar, frame, manifestURL) {
-    super(sidebar._panel, '', false);
-    this._sidebar = sidebar;
-    this._frameId = frame.id;
-    this._manifestURL = manifestURL;
-    this._refreshTitles(frame);
-
-    const icon = UI.Icon.create('largeicon-navigator-folder', 'navigator-tree-item');
-    icon.classList.add('navigator-folder-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  get itemURL() {
-    return 'appcache://' + this._manifestURL + '/' + encodeURI(this.titleAsText());
-  }
-
-  get frameId() {
-    return this._frameId;
-  }
-
-  get manifestURL() {
-    return this._manifestURL;
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _refreshTitles(frame) {
-    this.title = frame.displayName();
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  frameNavigated(frame) {
-    this._refreshTitles(frame);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._sidebar._showApplicationCache(this._frameId);
-    return false;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.StorageCategoryView = class extends UI.VBox {
-  constructor() {
-    super();
-
-    this.element.classList.add('storage-view');
-    this._emptyWidget = new UI.EmptyWidget('');
-    this._emptyWidget.show(this.element);
-  }
-
-  setText(text) {
-    this._emptyWidget.text = text;
-  }
-};
diff --git a/front_end/resources/ClearStorageView.js b/front_end/resources/ClearStorageView.js
deleted file mode 100644
index 0872cfa..0000000
--- a/front_end/resources/ClearStorageView.js
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.TargetManager.Observer}
- */
-Resources.ClearStorageView = class extends UI.ThrottledWidget {
-  constructor() {
-    super(true, 1000);
-    const types = Protocol.Storage.StorageType;
-    this._pieColors = new Map([
-      [types.Appcache, 'rgb(110, 161, 226)'],        // blue
-      [types.Cache_storage, 'rgb(229, 113, 113)'],   // red
-      [types.Cookies, 'rgb(239, 196, 87)'],          // yellow
-      [types.Indexeddb, 'rgb(155, 127, 230)'],       // purple
-      [types.Local_storage, 'rgb(116, 178, 102)'],   // green
-      [types.Service_workers, 'rgb(255, 167, 36)'],  // orange
-      [types.Websql, 'rgb(203, 220, 56)'],           // lime
-    ]);
-
-    this._reportView = new UI.ReportView(Common.UIString('Clear storage'));
-    this._reportView.registerRequiredCSS('resources/clearStorageView.css');
-    this._reportView.element.classList.add('clear-storage-header');
-    this._reportView.show(this.contentElement);
-    /** @type {?SDK.Target} */
-    this._target = null;
-    /** @type {?string} */
-    this._securityOrigin = null;
-
-    this._settings = new Map();
-    for (const type of
-             [types.Appcache, types.Cache_storage, types.Cookies, types.Indexeddb, types.Local_storage,
-              types.Service_workers, types.Websql])
-      this._settings.set(type, Common.settings.createSetting('clear-storage-' + type, true));
-
-    const quota = this._reportView.appendSection(Common.UIString('Usage'));
-    this._quotaRow = quota.appendRow();
-    this._quotaUsage = null;
-    this._pieChart = new PerfUI.PieChart(110, Number.bytesToString, true);
-    this._pieChartLegend = createElement('div');
-    const usageBreakdownRow = quota.appendRow();
-    usageBreakdownRow.classList.add('usage-breakdown-row');
-    usageBreakdownRow.appendChild(this._pieChart.element);
-    usageBreakdownRow.appendChild(this._pieChartLegend);
-
-    const application = this._reportView.appendSection(Common.UIString('Application'));
-    this._appendItem(application, Common.UIString('Unregister service workers'), 'service_workers');
-
-    const storage = this._reportView.appendSection(Common.UIString('Storage'));
-    this._appendItem(storage, Common.UIString('Local and session storage'), 'local_storage');
-    this._appendItem(storage, Common.UIString('IndexedDB'), 'indexeddb');
-    this._appendItem(storage, Common.UIString('Web SQL'), 'websql');
-    this._appendItem(storage, Common.UIString('Cookies'), 'cookies');
-
-    const caches = this._reportView.appendSection(Common.UIString('Cache'));
-    this._appendItem(caches, Common.UIString('Cache storage'), 'cache_storage');
-    this._appendItem(caches, Common.UIString('Application cache'), 'appcache');
-
-    SDK.targetManager.observeTargets(this, SDK.Target.Capability.Browser);
-    const footer = this._reportView.appendSection('', 'clear-storage-button').appendRow();
-    this._clearButton = UI.createTextButton(
-        Common.UIString('Clear site data'), this._clear.bind(this), Common.UIString('Clear site data'));
-    footer.appendChild(this._clearButton);
-  }
-
-  /**
-   * @param {!UI.ReportView.Section} section
-   * @param {string} title
-   * @param {string} settingName
-   */
-  _appendItem(section, title, settingName) {
-    const row = section.appendRow();
-    row.appendChild(UI.SettingsUI.createSettingCheckbox(title, this._settings.get(settingName), true));
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    if (this._target)
-      return;
-    this._target = target;
-    const securityOriginManager = target.model(SDK.SecurityOriginManager);
-    this._updateOrigin(securityOriginManager.mainSecurityOrigin());
-    securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, this._originChanged, this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    if (this._target !== target)
-      return;
-    const securityOriginManager = target.model(SDK.SecurityOriginManager);
-    securityOriginManager.removeEventListener(
-        SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, this._originChanged, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _originChanged(event) {
-    const origin = /** *@type {string} */ (event.data);
-    this._updateOrigin(origin);
-  }
-
-  /**
-   * @param {string} url
-   */
-  _updateOrigin(url) {
-    this._securityOrigin = new Common.ParsedURL(url).securityOrigin();
-    this._reportView.setSubtitle(this._securityOrigin);
-    this.doUpdate();
-  }
-
-  _clear() {
-    if (!this._securityOrigin)
-      return;
-    const storageTypes = [];
-    for (const type of this._settings.keys()) {
-      if (this._settings.get(type).get())
-        storageTypes.push(type);
-    }
-
-    this._target.storageAgent().clearDataForOrigin(this._securityOrigin, storageTypes.join(','));
-
-    const set = new Set(storageTypes);
-    const hasAll = set.has(Protocol.Storage.StorageType.All);
-    if (set.has(Protocol.Storage.StorageType.Cookies) || hasAll) {
-      const cookieModel = this._target.model(SDK.CookieModel);
-      if (cookieModel)
-        cookieModel.clear();
-    }
-
-    if (set.has(Protocol.Storage.StorageType.Indexeddb) || hasAll) {
-      for (const target of SDK.targetManager.targets()) {
-        const indexedDBModel = target.model(Resources.IndexedDBModel);
-        if (indexedDBModel)
-          indexedDBModel.clearForOrigin(this._securityOrigin);
-      }
-    }
-
-    if (set.has(Protocol.Storage.StorageType.Local_storage) || hasAll) {
-      const storageModel = this._target.model(Resources.DOMStorageModel);
-      if (storageModel)
-        storageModel.clearForOrigin(this._securityOrigin);
-    }
-
-    if (set.has(Protocol.Storage.StorageType.Websql) || hasAll) {
-      const databaseModel = this._target.model(Resources.DatabaseModel);
-      if (databaseModel) {
-        databaseModel.disable();
-        databaseModel.enable();
-      }
-    }
-
-    if (set.has(Protocol.Storage.StorageType.Cache_storage) || hasAll) {
-      const target = SDK.targetManager.mainTarget();
-      const model = target && target.model(SDK.ServiceWorkerCacheModel);
-      if (model)
-        model.clearForOrigin(this._securityOrigin);
-    }
-
-    if (set.has(Protocol.Storage.StorageType.Appcache) || hasAll) {
-      const appcacheModel = this._target.model(Resources.ApplicationCacheModel);
-      if (appcacheModel)
-        appcacheModel.reset();
-    }
-
-    this._clearButton.disabled = true;
-    const label = this._clearButton.textContent;
-    this._clearButton.textContent = Common.UIString('Clearing...');
-    setTimeout(() => {
-      this._clearButton.disabled = false;
-      this._clearButton.textContent = label;
-    }, 500);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?>}
-   */
-  async doUpdate() {
-    if (!this._securityOrigin)
-      return;
-
-    const securityOrigin = /** @type {string} */ (this._securityOrigin);
-    const response = await this._target.storageAgent().invoke_getUsageAndQuota({origin: securityOrigin});
-    if (response[Protocol.Error]) {
-      this._quotaRow.textContent = '';
-      this._resetPieChart(0);
-      return;
-    }
-    this._quotaRow.textContent = Common.UIString(
-        '%s used out of %s storage quota', Number.bytesToString(response.usage), Number.bytesToString(response.quota));
-
-    if (!this._quotaUsage || this._quotaUsage !== response.usage) {
-      this._quotaUsage = response.usage;
-      this._resetPieChart(response.usage);
-      for (const usageForType of response.usageBreakdown.sort((a, b) => b.usage - a.usage)) {
-        const value = usageForType.usage;
-        if (!value)
-          continue;
-        const title = this._getStorageTypeName(usageForType.storageType);
-        const color = this._pieColors.get(usageForType.storageType) || '#ccc';
-        this._pieChart.addSlice(value, color);
-        const rowElement = this._pieChartLegend.createChild('div', 'usage-breakdown-legend-row');
-        rowElement.createChild('span', 'usage-breakdown-legend-value').textContent = Number.bytesToString(value);
-        rowElement.createChild('span', 'usage-breakdown-legend-swatch').style.backgroundColor = color;
-        rowElement.createChild('span', 'usage-breakdown-legend-title').textContent = title;
-      }
-    }
-
-    this._usageUpdatedForTest(response.usage, response.quota, response.usageBreakdown);
-    this.update();
-  }
-
-  /**
-   * @param {number} total
-   */
-  _resetPieChart(total) {
-    this._pieChart.setTotal(total);
-    this._pieChartLegend.removeChildren();
-  }
-
-  /**
-   * @param {string} type
-   * @return {string}
-   */
-  _getStorageTypeName(type) {
-    switch (type) {
-      case Protocol.Storage.StorageType.File_systems:
-        return Common.UIString('File System');
-      case Protocol.Storage.StorageType.Websql:
-        return Common.UIString('Web SQL');
-      case Protocol.Storage.StorageType.Appcache:
-        return Common.UIString('Application Cache');
-      case Protocol.Storage.StorageType.Indexeddb:
-        return Common.UIString('IndexedDB');
-      case Protocol.Storage.StorageType.Cache_storage:
-        return Common.UIString('Cache Storage');
-      case Protocol.Storage.StorageType.Service_workers:
-        return Common.UIString('Service Workers');
-      default:
-        return Common.UIString('Other');
-    }
-  }
-
-  /**
-   * @param {number} usage
-   * @param {number} quota
-   * @param {!Array<!Protocol.Storage.UsageForType>} usageBreakdown
-   */
-  _usageUpdatedForTest(usage, quota, usageBreakdown) {
-  }
-};
diff --git a/front_end/resources/CookieItemsView.js b/front_end/resources/CookieItemsView.js
deleted file mode 100644
index fcb7abe..0000000
--- a/front_end/resources/CookieItemsView.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Resources.CookieItemsView = class extends Resources.StorageItemsView {
-  /**
-   * @param {!SDK.CookieModel} model
-   * @param {string} cookieDomain
-   */
-  constructor(model, cookieDomain) {
-    super(Common.UIString('Cookies'), 'cookiesPanel');
-
-    this.element.classList.add('storage-view');
-
-    this._model = model;
-    this._cookieDomain = cookieDomain;
-
-    this._totalSize = 0;
-    /** @type {?CookieTable.CookiesTable} */
-    this._cookiesTable = null;
-    this._refreshThrottler = new Common.Throttler(300);
-    /** @type {!Array<!Common.EventTarget.EventDescriptor>} */
-    this._eventDescriptors = [];
-    this.setCookiesDomain(model, cookieDomain);
-  }
-
-  /**
-   * @param {!SDK.CookieModel} model
-   * @param {string} domain
-   */
-  setCookiesDomain(model, domain) {
-    this._model = model;
-    this._cookieDomain = domain;
-    this.refreshItems();
-    Common.EventTarget.removeEventListeners(this._eventDescriptors);
-    const networkManager = model.target().model(SDK.NetworkManager);
-    this._eventDescriptors =
-        [networkManager.addEventListener(SDK.NetworkManager.Events.ResponseReceived, this._onResponseReceived, this)];
-  }
-
-  /**
-   * @param {!SDK.Cookie} newCookie
-   * @param {?SDK.Cookie} oldCookie
-   * @return {!Promise<boolean>}
-   */
-  _saveCookie(newCookie, oldCookie) {
-    if (!this._model)
-      return Promise.resolve(false);
-    if (oldCookie && (newCookie.name() !== oldCookie.name() || newCookie.url() !== oldCookie.url()))
-      this._model.deleteCookie(oldCookie);
-    return this._model.saveCookie(newCookie);
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookie
-   * @param {function()} callback
-   */
-  _deleteCookie(cookie, callback) {
-    this._model.deleteCookie(cookie, callback);
-  }
-
-  /**
-   * @param {!Array<!SDK.Cookie>} allCookies
-   */
-  _updateWithCookies(allCookies) {
-    this._totalSize = allCookies.reduce((size, cookie) => size + cookie.size(), 0);
-
-    if (!this._cookiesTable) {
-      this._cookiesTable = new CookieTable.CookiesTable(
-          this._saveCookie.bind(this),
-          this.refreshItems.bind(this),
-          () => this.setCanDeleteSelected(!!this._cookiesTable.selectedCookie()),
-          this._deleteCookie.bind(this));
-    }
-
-    const parsedURL = this._cookieDomain.asParsedURL();
-    const host = parsedURL ? parsedURL.host : '';
-    this._cookiesTable.setCookieDomain(host);
-
-    const shownCookies = this.filter(allCookies, cookie => `${cookie.name()} ${cookie.value()} ${cookie.domain()}`);
-    this._cookiesTable.setCookies(shownCookies);
-    this._cookiesTable.show(this.element);
-    this.setCanFilter(true);
-    this.setCanDeleteAll(true);
-    this.setCanDeleteSelected(!!this._cookiesTable.selectedCookie());
-  }
-
-  /**
-   * @override
-   */
-  deleteAllItems() {
-    this._model.clear(this._cookieDomain, () => this.refreshItems());
-  }
-
-  /**
-   * @override
-   */
-  deleteSelectedItem() {
-    const selectedCookie = this._cookiesTable.selectedCookie();
-    if (selectedCookie)
-      this._model.deleteCookie(selectedCookie, () => this.refreshItems());
-  }
-
-  /**
-   * @override
-   */
-  refreshItems() {
-    this._model.getCookiesForDomain(this._cookieDomain).then(this._updateWithCookies.bind(this));
-  }
-
-  _onResponseReceived() {
-    this._refreshThrottler.schedule(() => Promise.resolve(this.refreshItems()));
-  }
-};
diff --git a/front_end/resources/DOMStorageItemsView.js b/front_end/resources/DOMStorageItemsView.js
deleted file mode 100644
index 004e709..0000000
--- a/front_end/resources/DOMStorageItemsView.js
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Inc.  All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-Resources.DOMStorageItemsView = class extends Resources.StorageItemsView {
-  /**
-   * @param {!Resources.DOMStorage} domStorage
-   */
-  constructor(domStorage) {
-    super(Common.UIString('DOM Storage'), 'domStoragePanel');
-
-    this._domStorage = domStorage;
-
-    this.element.classList.add('storage-view', 'table');
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'key', title: Common.UIString('Key'), sortable: false, editable: true, longText: true, weight: 50},
-      {id: 'value', title: Common.UIString('Value'), sortable: false, editable: true, longText: true, weight: 50}
-    ]);
-    this._dataGrid = new DataGrid.DataGrid(columns, this._editingCallback.bind(this), this._deleteCallback.bind(this));
-    this._dataGrid.addEventListener(
-        DataGrid.DataGrid.Events.SelectedNode,
-        event => this._previewEntry(/** @type {!DataGrid.DataGridNode} */ (event.data)));
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, event => this._previewEntry(null));
-    this._dataGrid.setStriped(true);
-    this._dataGrid.setName('DOMStorageItemsView');
-
-    this._splitWidget = new UI.SplitWidget(false, false);
-    this._splitWidget.show(this.element);
-    this._splitWidget.setSecondIsSidebar(true);
-
-    this._previewPanel = new UI.VBox();
-    const resizer = this._previewPanel.element.createChild('div', 'preview-panel-resizer');
-    this._splitWidget.setMainWidget(this._dataGrid.asWidget());
-    this._splitWidget.setSidebarWidget(this._previewPanel);
-    this._splitWidget.installResizer(resizer);
-
-    /** @type {?UI.Widget} */
-    this._preview = null;
-    /** @type {?string} */
-    this._previewValue = null;
-
-    this._showPreview(null, null);
-
-    this._eventListeners = [];
-    this.setStorage(domStorage);
-  }
-
-  /**
-   * @param {!Resources.DOMStorage} domStorage
-   */
-  setStorage(domStorage) {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._domStorage = domStorage;
-    this._eventListeners = [
-      this._domStorage.addEventListener(
-          Resources.DOMStorage.Events.DOMStorageItemsCleared, this._domStorageItemsCleared, this),
-      this._domStorage.addEventListener(
-          Resources.DOMStorage.Events.DOMStorageItemRemoved, this._domStorageItemRemoved, this),
-      this._domStorage.addEventListener(
-          Resources.DOMStorage.Events.DOMStorageItemAdded, this._domStorageItemAdded, this),
-      this._domStorage.addEventListener(
-          Resources.DOMStorage.Events.DOMStorageItemUpdated, this._domStorageItemUpdated, this),
-    ];
-    this.refreshItems();
-  }
-
-  _domStorageItemsCleared() {
-    if (!this.isShowing() || !this._dataGrid)
-      return;
-
-    this._dataGrid.rootNode().removeChildren();
-    this._dataGrid.addCreationNode(false);
-    this.setCanDeleteSelected(false);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domStorageItemRemoved(event) {
-    if (!this.isShowing() || !this._dataGrid)
-      return;
-
-    const storageData = event.data;
-    const rootNode = this._dataGrid.rootNode();
-    const children = rootNode.children;
-
-    for (let i = 0; i < children.length; ++i) {
-      const childNode = children[i];
-      if (childNode.data.key === storageData.key) {
-        rootNode.removeChild(childNode);
-        this.setCanDeleteSelected(children.length > 1);
-        return;
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domStorageItemAdded(event) {
-    if (!this.isShowing() || !this._dataGrid)
-      return;
-
-    const storageData = event.data;
-    const rootNode = this._dataGrid.rootNode();
-    const children = rootNode.children;
-
-    for (let i = 0; i < children.length; ++i) {
-      if (children[i].data.key === storageData.key)
-        return;
-    }
-
-    const childNode = new DataGrid.DataGridNode({key: storageData.key, value: storageData.value}, false);
-    rootNode.insertChild(childNode, children.length - 1);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _domStorageItemUpdated(event) {
-    if (!this.isShowing() || !this._dataGrid)
-      return;
-
-    const storageData = event.data;
-    const childNode = this._dataGrid.rootNode().children.find(child => child.data.key === storageData.key);
-    if (!childNode || childNode.data.value === storageData.value)
-      return;
-
-    childNode.data.value = storageData.value;
-    childNode.refresh();
-    if (!childNode.selected)
-      return;
-    this._previewEntry(childNode);
-    this.setCanDeleteSelected(true);
-  }
-
-  /**
-   * @param {!Array<!Array<string>>} items
-   */
-  _showDOMStorageItems(items) {
-    const rootNode = this._dataGrid.rootNode();
-    let selectedKey = null;
-    for (const node of rootNode.children) {
-      if (!node.selected)
-        continue;
-      selectedKey = node.data.key;
-      break;
-    }
-    rootNode.removeChildren();
-    let selectedNode = null;
-    const filteredItems = item => `${item[0]} ${item[1]}`;
-    for (const item of this.filter(items, filteredItems)) {
-      const key = item[0];
-      const value = item[1];
-      const node = new DataGrid.DataGridNode({key: key, value: value}, false);
-      node.selectable = true;
-      rootNode.appendChild(node);
-      if (!selectedNode || key === selectedKey)
-        selectedNode = node;
-    }
-    if (selectedNode)
-      selectedNode.selected = true;
-    this._dataGrid.addCreationNode(false);
-    this.setCanDeleteSelected(!!selectedNode);
-  }
-
-  /**
-   * @override
-   */
-  deleteSelectedItem() {
-    if (!this._dataGrid || !this._dataGrid.selectedNode)
-      return;
-
-    this._deleteCallback(this._dataGrid.selectedNode);
-  }
-
-  /**
-   * @override
-   */
-  refreshItems() {
-    this._domStorage.getItems().then(items => items && this._showDOMStorageItems(items));
-  }
-
-  /**
-   * @override
-   */
-  deleteAllItems() {
-    this._domStorage.clear();
-    // explicitly clear the view because the event won't be fired when it has no items
-    this._domStorageItemsCleared();
-  }
-
-  _editingCallback(editingNode, columnIdentifier, oldText, newText) {
-    const domStorage = this._domStorage;
-    if (columnIdentifier === 'key') {
-      if (typeof oldText === 'string')
-        domStorage.removeItem(oldText);
-      domStorage.setItem(newText, editingNode.data.value || '');
-      this._removeDupes(editingNode);
-    } else {
-      domStorage.setItem(editingNode.data.key || '', newText);
-    }
-  }
-
-  /**
-   * @param {!DataGrid.DataGridNode} masterNode
-   */
-  _removeDupes(masterNode) {
-    const rootNode = this._dataGrid.rootNode();
-    const children = rootNode.children;
-    for (let i = children.length - 1; i >= 0; --i) {
-      const childNode = children[i];
-      if ((childNode.data.key === masterNode.data.key) && (masterNode !== childNode))
-        rootNode.removeChild(childNode);
-    }
-  }
-
-  _deleteCallback(node) {
-    if (!node || node.isCreationNode)
-      return;
-
-    if (this._domStorage)
-      this._domStorage.removeItem(node.data.key);
-  }
-
-  /**
-   * @param {?UI.Widget} preview
-   * @param {?string} value
-   */
-  _showPreview(preview, value) {
-    if (this._preview && this._previewValue === value)
-      return;
-    if (this._preview)
-      this._preview.detach();
-    if (!preview)
-      preview = new UI.EmptyWidget(Common.UIString('Select a value to preview'));
-    this._previewValue = value;
-    this._preview = preview;
-    preview.show(this._previewPanel.contentElement);
-  }
-
-  /**
-   * @param {?DataGrid.DataGridNode} entry
-   */
-  async _previewEntry(entry) {
-    const value = entry && entry.data && entry.data.value;
-    if (!value) {
-      this._showPreview(null, value);
-      return;
-    }
-    const protocol = this._domStorage.isLocalStorage ? 'localstorage' : 'sessionstorage';
-    const url = `${protocol}://${entry.key}`;
-    const provider =
-        Common.StaticContentProvider.fromString(url, Common.resourceTypes.XHR, /** @type {string} */ (value));
-    const preview = await SourceFrame.PreviewFactory.createPreview(provider, 'text/plain');
-    // Selection could've changed while the preview was loaded
-    if (!entry.selected)
-      return;
-    this._showPreview(preview, value);
-  }
-};
diff --git a/front_end/resources/DOMStorageModel.js b/front_end/resources/DOMStorageModel.js
deleted file mode 100644
index e01000d..0000000
--- a/front_end/resources/DOMStorageModel.js
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2008 Nokia Inc.  All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.DOMStorage = class extends Common.Object {
-  /**
-   * @param {!Resources.DOMStorageModel} model
-   * @param {string} securityOrigin
-   * @param {boolean} isLocalStorage
-   */
-  constructor(model, securityOrigin, isLocalStorage) {
-    super();
-    this._model = model;
-    this._securityOrigin = securityOrigin;
-    this._isLocalStorage = isLocalStorage;
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {boolean} isLocalStorage
-   * @return {!Protocol.DOMStorage.StorageId}
-   */
-  static storageId(securityOrigin, isLocalStorage) {
-    return {securityOrigin: securityOrigin, isLocalStorage: isLocalStorage};
-  }
-
-  /** @return {!Protocol.DOMStorage.StorageId} */
-  get id() {
-    return Resources.DOMStorage.storageId(this._securityOrigin, this._isLocalStorage);
-  }
-
-  /** @return {string} */
-  get securityOrigin() {
-    return this._securityOrigin;
-  }
-
-  /** @return {boolean} */
-  get isLocalStorage() {
-    return this._isLocalStorage;
-  }
-
-  /**
-   * @return {!Promise<?Array<!Protocol.DOMStorage.Item>>}
-   */
-  getItems() {
-    return this._model._agent.getDOMStorageItems(this.id);
-  }
-
-  /**
-   * @param {string} key
-   * @param {string} value
-   */
-  setItem(key, value) {
-    this._model._agent.setDOMStorageItem(this.id, key, value);
-  }
-
-  /**
-   * @param {string} key
-   */
-  removeItem(key) {
-    this._model._agent.removeDOMStorageItem(this.id, key);
-  }
-
-  clear() {
-    this._model._agent.clear(this.id);
-  }
-};
-
-
-/** @enum {symbol} */
-Resources.DOMStorage.Events = {
-  DOMStorageItemsCleared: Symbol('DOMStorageItemsCleared'),
-  DOMStorageItemRemoved: Symbol('DOMStorageItemRemoved'),
-  DOMStorageItemAdded: Symbol('DOMStorageItemAdded'),
-  DOMStorageItemUpdated: Symbol('DOMStorageItemUpdated')
-};
-
-/**
- * @unrestricted
- */
-Resources.DOMStorageModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    this._securityOriginManager = target.model(SDK.SecurityOriginManager);
-    /** @type {!Object.<string, !Resources.DOMStorage>} */
-    this._storages = {};
-    this._agent = target.domstorageAgent();
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-
-    this.target().registerDOMStorageDispatcher(new Resources.DOMStorageDispatcher(this));
-    this._securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._securityOriginAdded, this);
-    this._securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this);
-
-    for (const securityOrigin of this._securityOriginManager.securityOrigins())
-      this._addOrigin(securityOrigin);
-    this._agent.enable();
-
-    this._enabled = true;
-  }
-
-  /**
-   * @param {string} origin
-   */
-  clearForOrigin(origin) {
-    if (!this._enabled)
-      return;
-    for (const isLocal of [true, false]) {
-      const key = this._storageKey(origin, isLocal);
-      const storage = this._storages[key];
-      storage.clear();
-    }
-    this._removeOrigin(origin);
-    this._addOrigin(origin);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _securityOriginAdded(event) {
-    this._addOrigin(/** @type {string} */ (event.data));
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  _addOrigin(securityOrigin) {
-    for (const isLocal of [true, false]) {
-      const key = this._storageKey(securityOrigin, isLocal);
-      console.assert(!this._storages[key]);
-      const storage = new Resources.DOMStorage(this, securityOrigin, isLocal);
-      this._storages[key] = storage;
-      this.dispatchEventToListeners(Resources.DOMStorageModel.Events.DOMStorageAdded, storage);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _securityOriginRemoved(event) {
-    this._removeOrigin(/** @type {string} */ (event.data));
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  _removeOrigin(securityOrigin) {
-    for (const isLocal of [true, false]) {
-      const key = this._storageKey(securityOrigin, isLocal);
-      const storage = this._storages[key];
-      console.assert(storage);
-      delete this._storages[key];
-      this.dispatchEventToListeners(Resources.DOMStorageModel.Events.DOMStorageRemoved, storage);
-    }
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {boolean} isLocalStorage
-   * @return {string}
-   */
-  _storageKey(securityOrigin, isLocalStorage) {
-    return JSON.stringify(Resources.DOMStorage.storageId(securityOrigin, isLocalStorage));
-  }
-
-  /**
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   */
-  _domStorageItemsCleared(storageId) {
-    const domStorage = this.storageForId(storageId);
-    if (!domStorage)
-      return;
-
-    const eventData = {};
-    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemsCleared, eventData);
-  }
-
-  /**
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @param {string} key
-   */
-  _domStorageItemRemoved(storageId, key) {
-    const domStorage = this.storageForId(storageId);
-    if (!domStorage)
-      return;
-
-    const eventData = {key: key};
-    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemRemoved, eventData);
-  }
-
-  /**
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @param {string} key
-   * @param {string} value
-   */
-  _domStorageItemAdded(storageId, key, value) {
-    const domStorage = this.storageForId(storageId);
-    if (!domStorage)
-      return;
-
-    const eventData = {key: key, value: value};
-    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemAdded, eventData);
-  }
-
-  /**
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @param {string} key
-   * @param {string} oldValue
-   * @param {string} value
-   */
-  _domStorageItemUpdated(storageId, key, oldValue, value) {
-    const domStorage = this.storageForId(storageId);
-    if (!domStorage)
-      return;
-
-    const eventData = {key: key, oldValue: oldValue, value: value};
-    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemUpdated, eventData);
-  }
-
-  /**
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @return {!Resources.DOMStorage}
-   */
-  storageForId(storageId) {
-    return this._storages[JSON.stringify(storageId)];
-  }
-
-  /**
-   * @return {!Array.<!Resources.DOMStorage>}
-   */
-  storages() {
-    const result = [];
-    for (const id in this._storages)
-      result.push(this._storages[id]);
-    return result;
-  }
-};
-
-SDK.SDKModel.register(Resources.DOMStorageModel, SDK.Target.Capability.None, false);
-
-/** @enum {symbol} */
-Resources.DOMStorageModel.Events = {
-  DOMStorageAdded: Symbol('DOMStorageAdded'),
-  DOMStorageRemoved: Symbol('DOMStorageRemoved')
-};
-
-/**
- * @implements {Protocol.DOMStorageDispatcher}
- * @unrestricted
- */
-Resources.DOMStorageDispatcher = class {
-  /**
-   * @param {!Resources.DOMStorageModel} model
-   */
-  constructor(model) {
-    this._model = model;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   */
-  domStorageItemsCleared(storageId) {
-    this._model._domStorageItemsCleared(storageId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @param {string} key
-   */
-  domStorageItemRemoved(storageId, key) {
-    this._model._domStorageItemRemoved(storageId, key);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @param {string} key
-   * @param {string} value
-   */
-  domStorageItemAdded(storageId, key, value) {
-    this._model._domStorageItemAdded(storageId, key, value);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOMStorage.StorageId} storageId
-   * @param {string} key
-   * @param {string} oldValue
-   * @param {string} value
-   */
-  domStorageItemUpdated(storageId, key, oldValue, value) {
-    this._model._domStorageItemUpdated(storageId, key, oldValue, value);
-  }
-};
-
-Resources.DOMStorageModel._symbol = Symbol('DomStorage');
diff --git a/front_end/resources/DatabaseModel.js b/front_end/resources/DatabaseModel.js
deleted file mode 100644
index 08572a6..0000000
--- a/front_end/resources/DatabaseModel.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.Database = class {
-  /**
-   * @param {!Resources.DatabaseModel} model
-   * @param {string} id
-   * @param {string} domain
-   * @param {string} name
-   * @param {string} version
-   */
-  constructor(model, id, domain, name, version) {
-    this._model = model;
-    this._id = id;
-    this._domain = domain;
-    this._name = name;
-    this._version = version;
-  }
-
-  /** @return {string} */
-  get id() {
-    return this._id;
-  }
-
-  /** @return {string} */
-  get name() {
-    return this._name;
-  }
-
-  /** @param {string} x */
-  set name(x) {
-    this._name = x;
-  }
-
-  /** @return {string} */
-  get version() {
-    return this._version;
-  }
-
-  /** @param {string} x */
-  set version(x) {
-    this._version = x;
-  }
-
-  /** @return {string} */
-  get domain() {
-    return this._domain;
-  }
-
-  /** @param {string} x */
-  set domain(x) {
-    this._domain = x;
-  }
-
-  /**
-   * @return {!Promise<!Array<string>>}
-   */
-  async tableNames() {
-    const names = await this._model._agent.getDatabaseTableNames(this._id) || [];
-    return names.sort();
-  }
-
-  /**
-   * @param {string} query
-   * @param {function(!Array.<string>=, !Array.<*>=)} onSuccess
-   * @param {function(string)} onError
-   */
-  async executeSql(query, onSuccess, onError) {
-    const response = await this._model._agent.invoke_executeSQL({'databaseId': this._id, 'query': query});
-    const error = response[Protocol.Error];
-    if (error) {
-      onError(error);
-      return;
-    }
-    const sqlError = response.sqlError;
-    if (!sqlError) {
-      onSuccess(response.columnNames, response.values);
-      return;
-    }
-    let message;
-    if (sqlError.message)
-      message = sqlError.message;
-    else if (sqlError.code === 2)
-      message = Common.UIString('Database no longer has expected version.');
-    else
-      message = Common.UIString('An unexpected error %s occurred.', sqlError.code);
-    onError(message);
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.DatabaseModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    this._databases = [];
-    this._agent = target.databaseAgent();
-    this.target().registerDatabaseDispatcher(new Resources.DatabaseDispatcher(this));
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-    this._agent.enable();
-    this._enabled = true;
-  }
-
-  disable() {
-    if (!this._enabled)
-      return;
-    this._enabled = false;
-    this._databases = [];
-    this._agent.disable();
-    this.dispatchEventToListeners(Resources.DatabaseModel.Events.DatabasesRemoved);
-  }
-
-  /**
-   * @return {!Array.<!Resources.Database>}
-   */
-  databases() {
-    const result = [];
-    for (const database of this._databases)
-      result.push(database);
-    return result;
-  }
-
-  /**
-   * @param {!Resources.Database} database
-   */
-  _addDatabase(database) {
-    this._databases.push(database);
-    this.dispatchEventToListeners(Resources.DatabaseModel.Events.DatabaseAdded, database);
-  }
-};
-
-SDK.SDKModel.register(Resources.DatabaseModel, SDK.Target.Capability.None, false);
-
-/** @enum {symbol} */
-Resources.DatabaseModel.Events = {
-  DatabaseAdded: Symbol('DatabaseAdded'),
-  DatabasesRemoved: Symbol('DatabasesRemoved'),
-};
-
-/**
- * @implements {Protocol.DatabaseDispatcher}
- * @unrestricted
- */
-Resources.DatabaseDispatcher = class {
-  /**
-   * @param {!Resources.DatabaseModel} model
-   */
-  constructor(model) {
-    this._model = model;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Database.Database} payload
-   */
-  addDatabase(payload) {
-    this._model._addDatabase(
-        new Resources.Database(this._model, payload.id, payload.domain, payload.name, payload.version));
-  }
-};
-
-Resources.DatabaseModel._symbol = Symbol('DatabaseModel');
diff --git a/front_end/resources/DatabaseQueryView.js b/front_end/resources/DatabaseQueryView.js
deleted file mode 100644
index bb499e1..0000000
--- a/front_end/resources/DatabaseQueryView.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.DatabaseQueryView = class extends UI.VBox {
-  constructor(database) {
-    super();
-
-    this.database = database;
-
-    this.element.classList.add('storage-view', 'query', 'monospace');
-    this.element.addEventListener('selectstart', this._selectStart.bind(this), false);
-
-    this._promptContainer = this.element.createChild('div', 'database-query-prompt-container');
-    this._promptContainer.appendChild(UI.Icon.create('smallicon-text-prompt', 'prompt-icon'));
-    this._promptElement = this._promptContainer.createChild('div');
-    this._promptElement.className = 'database-query-prompt';
-    this._promptElement.addEventListener('keydown', this._promptKeyDown.bind(this), true);
-
-    this._prompt = new UI.TextPrompt();
-    this._prompt.initialize(this.completions.bind(this), ' ');
-    this._proxyElement = this._prompt.attach(this._promptElement);
-
-    this.element.addEventListener('click', this._messagesClicked.bind(this), true);
-  }
-
-  _messagesClicked() {
-    if (!this._prompt.isCaretInsidePrompt() && !this.element.hasSelection())
-      this._prompt.moveCaretToEndOfPrompt();
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} prefix
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  async completions(expression, prefix, force) {
-    if (!prefix)
-      return [];
-
-    prefix = prefix.toLowerCase();
-    const tableNames = await this.database.tableNames();
-    return tableNames.map(name => name + ' ')
-        .concat(Resources.DatabaseQueryView._SQL_BUILT_INS)
-        .filter(proposal => proposal.toLowerCase().startsWith(prefix))
-        .map(completion => ({text: completion}));
-  }
-
-  _selectStart(event) {
-    if (this._selectionTimeout)
-      clearTimeout(this._selectionTimeout);
-
-    this._prompt.clearAutocomplete();
-
-    /**
-     * @this {Resources.DatabaseQueryView}
-     */
-    function moveBackIfOutside() {
-      delete this._selectionTimeout;
-      if (!this._prompt.isCaretInsidePrompt() && !this.element.hasSelection())
-        this._prompt.moveCaretToEndOfPrompt();
-      this._prompt.autoCompleteSoon();
-    }
-
-    this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
-  }
-
-  _promptKeyDown(event) {
-    if (isEnterKey(event)) {
-      this._enterKeyPressed(event);
-      return;
-    }
-  }
-
-  _enterKeyPressed(event) {
-    event.consume();
-
-    this._prompt.clearAutocomplete();
-
-    const query = this._prompt.text();
-    if (!query.length)
-      return;
-
-    this._prompt.setText('');
-
-    this.database.executeSql(query, this._queryFinished.bind(this, query), this._queryError.bind(this, query));
-  }
-
-  _queryFinished(query, columnNames, values) {
-    const dataGrid = DataGrid.SortableDataGrid.create(columnNames, values);
-    const trimmedQuery = query.trim();
-
-    if (dataGrid) {
-      dataGrid.setStriped(true);
-      dataGrid.renderInline();
-      this._appendViewQueryResult(trimmedQuery, dataGrid.asWidget());
-      dataGrid.autoSizeColumns(5);
-    }
-
-    if (trimmedQuery.match(/^create /i) || trimmedQuery.match(/^drop table /i))
-      this.dispatchEventToListeners(Resources.DatabaseQueryView.Events.SchemaUpdated, this.database);
-  }
-
-  _queryError(query, errorMessage) {
-    this._appendErrorQueryResult(query, errorMessage);
-  }
-
-  /**
-   * @param {string} query
-   * @param {!UI.Widget} view
-   */
-  _appendViewQueryResult(query, view) {
-    const resultElement = this._appendQueryResult(query);
-    view.show(resultElement);
-    this._promptElement.scrollIntoView(false);
-  }
-
-  /**
-   * @param {string} query
-   * @param {string} errorText
-   */
-  _appendErrorQueryResult(query, errorText) {
-    const resultElement = this._appendQueryResult(query);
-    resultElement.classList.add('error');
-    resultElement.appendChild(UI.Icon.create('smallicon-error', 'prompt-icon'));
-    resultElement.createTextChild(errorText);
-
-    this._promptElement.scrollIntoView(false);
-  }
-
-  /**
-   * @param {string} query
-   */
-  _appendQueryResult(query) {
-    const element = createElement('div');
-    element.className = 'database-user-query';
-    element.appendChild(UI.Icon.create('smallicon-user-command', 'prompt-icon'));
-    this.element.insertBefore(element, this._promptContainer);
-
-    const commandTextElement = createElement('span');
-    commandTextElement.className = 'database-query-text';
-    commandTextElement.textContent = query;
-    element.appendChild(commandTextElement);
-
-    const resultElement = createElement('div');
-    resultElement.className = 'database-query-result';
-    element.appendChild(resultElement);
-    return resultElement;
-  }
-};
-
-/** @enum {symbol} */
-Resources.DatabaseQueryView.Events = {
-  SchemaUpdated: Symbol('SchemaUpdated')
-};
-
-Resources.DatabaseQueryView._SQL_BUILT_INS = [
-  'SELECT ', 'FROM ', 'WHERE ', 'LIMIT ', 'DELETE FROM ', 'CREATE ', 'DROP ', 'TABLE ', 'INDEX ', 'UPDATE ',
-  'INSERT INTO ', 'VALUES ('
-];
diff --git a/front_end/resources/DatabaseTableView.js b/front_end/resources/DatabaseTableView.js
deleted file mode 100644
index 72b05b9..0000000
--- a/front_end/resources/DatabaseTableView.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.DatabaseTableView = class extends UI.SimpleView {
-  constructor(database, tableName) {
-    super(Common.UIString('Database'));
-
-    this.database = database;
-    this.tableName = tableName;
-
-    this.element.classList.add('storage-view', 'table');
-
-    this._visibleColumnsSetting = Common.settings.createSetting('databaseTableViewVisibleColumns', {});
-
-    this.refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this.refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
-    this._visibleColumnsInput = new UI.ToolbarInput(Common.UIString('Visible columns'), 1);
-    this._visibleColumnsInput.addEventListener(UI.ToolbarInput.Event.TextChanged, this._onVisibleColumnsChanged, this);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.update();
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return [this.refreshButton, this._visibleColumnsInput];
-  }
-
-  /**
-   * @param {string} tableName
-   * @return {string}
-   */
-  _escapeTableName(tableName) {
-    return tableName.replace(/\"/g, '""');
-  }
-
-  update() {
-    this.database.executeSql(
-        'SELECT rowid, * FROM "' + this._escapeTableName(this.tableName) + '"', this._queryFinished.bind(this),
-        this._queryError.bind(this));
-  }
-
-  _queryFinished(columnNames, values) {
-    this.detachChildWidgets();
-    this.element.removeChildren();
-
-    this._dataGrid = DataGrid.SortableDataGrid.create(columnNames, values);
-    this._visibleColumnsInput.setVisible(!!this._dataGrid);
-    if (!this._dataGrid) {
-      this._emptyWidget = new UI.EmptyWidget(Common.UIString('The “%s”\ntable is empty.', this.tableName));
-      this._emptyWidget.show(this.element);
-      return;
-    }
-    this._dataGrid.setStriped(true);
-    this._dataGrid.asWidget().show(this.element);
-    this._dataGrid.autoSizeColumns(5);
-
-    this._columnsMap = new Map();
-    for (let i = 1; i < columnNames.length; ++i)
-      this._columnsMap.set(columnNames[i], String(i));
-    this._lastVisibleColumns = '';
-    const visibleColumnsText = this._visibleColumnsSetting.get()[this.tableName] || '';
-    this._visibleColumnsInput.setValue(visibleColumnsText);
-    this._onVisibleColumnsChanged();
-  }
-
-  _onVisibleColumnsChanged() {
-    if (!this._dataGrid)
-      return;
-    const text = this._visibleColumnsInput.value();
-    const parts = text.split(/[\s,]+/);
-    const matches = new Set();
-    const columnsVisibility = {};
-    columnsVisibility['0'] = true;
-    for (let i = 0; i < parts.length; ++i) {
-      const part = parts[i];
-      if (this._columnsMap.has(part)) {
-        matches.add(part);
-        columnsVisibility[this._columnsMap.get(part)] = true;
-      }
-    }
-    const newVisibleColumns = matches.valuesArray().sort().join(', ');
-    if (newVisibleColumns.length === 0) {
-      for (const v of this._columnsMap.values())
-        columnsVisibility[v] = true;
-    }
-    if (newVisibleColumns === this._lastVisibleColumns)
-      return;
-    const visibleColumnsRegistry = this._visibleColumnsSetting.get();
-    visibleColumnsRegistry[this.tableName] = text;
-    this._visibleColumnsSetting.set(visibleColumnsRegistry);
-    this._dataGrid.setColumnsVisiblity(columnsVisibility);
-    this._lastVisibleColumns = newVisibleColumns;
-  }
-
-  _queryError(error) {
-    this.detachChildWidgets();
-    this.element.removeChildren();
-
-    const errorMsgElement = createElement('div');
-    errorMsgElement.className = 'storage-table-error';
-    errorMsgElement.textContent = Common.UIString('An error occurred trying to\nread the “%s” table.', this.tableName);
-    this.element.appendChild(errorMsgElement);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _refreshButtonClicked(event) {
-    this.update();
-  }
-};
diff --git a/front_end/resources/IndexedDBModel.js b/front_end/resources/IndexedDBModel.js
deleted file mode 100644
index 534c56d..0000000
--- a/front_end/resources/IndexedDBModel.js
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Protocol.StorageDispatcher}
- * @unrestricted
- */
-Resources.IndexedDBModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    target.registerStorageDispatcher(this);
-    this._securityOriginManager = target.model(SDK.SecurityOriginManager);
-    this._indexedDBAgent = target.indexedDBAgent();
-    this._storageAgent = target.storageAgent();
-
-    /** @type {!Map.<!Resources.IndexedDBModel.DatabaseId, !Resources.IndexedDBModel.Database>} */
-    this._databases = new Map();
-    /** @type {!Object.<string, !Array.<string>>} */
-    this._databaseNamesBySecurityOrigin = {};
-
-    this._originsUpdated = new Set();
-    this._throttler = new Common.Throttler(1000);
-  }
-
-  /**
-   * @param {*} idbKey
-   * @return {({
-   *   array: (!Array<?>|undefined),
-   *   date: (number|undefined),
-   *   number: (number|undefined),
-   *   string: (string|undefined),
-   *   type: !Protocol.IndexedDB.KeyType<string>
-   * }|undefined)}
-   */
-  static keyFromIDBKey(idbKey) {
-    if (typeof(idbKey) === 'undefined' || idbKey === null)
-      return undefined;
-
-    let type;
-    const key = {};
-    switch (typeof(idbKey)) {
-      case 'number':
-        key.number = idbKey;
-        type = Resources.IndexedDBModel.KeyTypes.NumberType;
-        break;
-      case 'string':
-        key.string = idbKey;
-        type = Resources.IndexedDBModel.KeyTypes.StringType;
-        break;
-      case 'object':
-        if (idbKey instanceof Date) {
-          key.date = idbKey.getTime();
-          type = Resources.IndexedDBModel.KeyTypes.DateType;
-        } else if (Array.isArray(idbKey)) {
-          key.array = [];
-          for (let i = 0; i < idbKey.length; ++i)
-            key.array.push(Resources.IndexedDBModel.keyFromIDBKey(idbKey[i]));
-          type = Resources.IndexedDBModel.KeyTypes.ArrayType;
-        }
-        break;
-      default:
-        return undefined;
-    }
-    key.type = /** @type {!Protocol.IndexedDB.KeyType<string>} */ (type);
-    return key;
-  }
-
-  /**
-   * @param {!IDBKeyRange} idbKeyRange
-   * @return {!Protocol.IndexedDB.KeyRange}
-   */
-  static _keyRangeFromIDBKeyRange(idbKeyRange) {
-    const keyRange = {};
-    keyRange.lower = Resources.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
-    keyRange.upper = Resources.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
-    keyRange.lowerOpen = !!idbKeyRange.lowerOpen;
-    keyRange.upperOpen = !!idbKeyRange.upperOpen;
-    return keyRange;
-  }
-
-  /**
-   * @param {!Protocol.IndexedDB.KeyPath} keyPath
-   * @return {?string|!Array.<string>|undefined}
-   */
-  static idbKeyPathFromKeyPath(keyPath) {
-    let idbKeyPath;
-    switch (keyPath.type) {
-      case Resources.IndexedDBModel.KeyPathTypes.NullType:
-        idbKeyPath = null;
-        break;
-      case Resources.IndexedDBModel.KeyPathTypes.StringType:
-        idbKeyPath = keyPath.string;
-        break;
-      case Resources.IndexedDBModel.KeyPathTypes.ArrayType:
-        idbKeyPath = keyPath.array;
-        break;
-    }
-    return idbKeyPath;
-  }
-
-  /**
-   * @param {?string|!Array.<string>|undefined} idbKeyPath
-   * @return {?string}
-   */
-  static keyPathStringFromIDBKeyPath(idbKeyPath) {
-    if (typeof idbKeyPath === 'string')
-      return '"' + idbKeyPath + '"';
-    if (idbKeyPath instanceof Array)
-      return '["' + idbKeyPath.join('", "') + '"]';
-    return null;
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-
-    this._indexedDBAgent.enable();
-    this._securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._securityOriginAdded, this);
-    this._securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this);
-
-    for (const securityOrigin of this._securityOriginManager.securityOrigins())
-      this._addOrigin(securityOrigin);
-
-    this._enabled = true;
-  }
-
-  /**
-   * @param {string} origin
-   */
-  clearForOrigin(origin) {
-    if (!this._enabled)
-      return;
-
-    this._removeOrigin(origin);
-    this._addOrigin(origin);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   */
-  async deleteDatabase(databaseId) {
-    if (!this._enabled)
-      return;
-    await this._indexedDBAgent.deleteDatabase(databaseId.securityOrigin, databaseId.name);
-    this._loadDatabaseNames(databaseId.securityOrigin);
-  }
-
-  async refreshDatabaseNames() {
-    for (const securityOrigin in this._databaseNamesBySecurityOrigin)
-      await this._loadDatabaseNames(securityOrigin);
-    this.dispatchEventToListeners(Resources.IndexedDBModel.Events.DatabaseNamesRefreshed);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   */
-  refreshDatabase(databaseId) {
-    this._loadDatabase(databaseId, true);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {string} objectStoreName
-   * @return {!Promise}
-   */
-  clearObjectStore(databaseId, objectStoreName) {
-    return this._indexedDBAgent.clearObjectStore(databaseId.securityOrigin, databaseId.name, objectStoreName);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {string} objectStoreName
-   * @param {!IDBKeyRange} idbKeyRange
-   * @return {!Promise}
-   */
-  deleteEntries(databaseId, objectStoreName, idbKeyRange) {
-    const keyRange = Resources.IndexedDBModel._keyRangeFromIDBKeyRange(idbKeyRange);
-    return this._indexedDBAgent.deleteObjectStoreEntries(
-        databaseId.securityOrigin, databaseId.name, objectStoreName, keyRange);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _securityOriginAdded(event) {
-    const securityOrigin = /** @type {string} */ (event.data);
-    this._addOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _securityOriginRemoved(event) {
-    const securityOrigin = /** @type {string} */ (event.data);
-    this._removeOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  _addOrigin(securityOrigin) {
-    console.assert(!this._databaseNamesBySecurityOrigin[securityOrigin]);
-    this._databaseNamesBySecurityOrigin[securityOrigin] = [];
-    this._loadDatabaseNames(securityOrigin);
-    if (this._isValidSecurityOrigin(securityOrigin))
-      this._storageAgent.trackIndexedDBForOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  _removeOrigin(securityOrigin) {
-    console.assert(this._databaseNamesBySecurityOrigin[securityOrigin]);
-    for (let i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
-      this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
-    delete this._databaseNamesBySecurityOrigin[securityOrigin];
-    if (this._isValidSecurityOrigin(securityOrigin))
-      this._storageAgent.untrackIndexedDBForOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @return {boolean}
-   */
-  _isValidSecurityOrigin(securityOrigin) {
-    const parsedURL = securityOrigin.asParsedURL();
-    return !!parsedURL && parsedURL.scheme.startsWith('http');
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {!Array.<string>} databaseNames
-   */
-  _updateOriginDatabaseNames(securityOrigin, databaseNames) {
-    const newDatabaseNames = new Set(databaseNames);
-    const oldDatabaseNames = new Set(this._databaseNamesBySecurityOrigin[securityOrigin]);
-
-    this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;
-
-    for (const databaseName of oldDatabaseNames) {
-      if (!newDatabaseNames.has(databaseName))
-        this._databaseRemoved(securityOrigin, databaseName);
-    }
-    for (const databaseName of newDatabaseNames) {
-      if (!oldDatabaseNames.has(databaseName))
-        this._databaseAdded(securityOrigin, databaseName);
-    }
-  }
-
-  /**
-   * @return {!Array.<!Resources.IndexedDBModel.DatabaseId>}
-   */
-  databases() {
-    const result = [];
-    for (const securityOrigin in this._databaseNamesBySecurityOrigin) {
-      const databaseNames = this._databaseNamesBySecurityOrigin[securityOrigin];
-      for (let i = 0; i < databaseNames.length; ++i)
-        result.push(new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseNames[i]));
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {string} databaseName
-   */
-  _databaseAdded(securityOrigin, databaseName) {
-    const databaseId = new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
-    this.dispatchEventToListeners(Resources.IndexedDBModel.Events.DatabaseAdded, {model: this, databaseId: databaseId});
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {string} databaseName
-   */
-  _databaseRemoved(securityOrigin, databaseName) {
-    const databaseId = new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
-    this.dispatchEventToListeners(
-        Resources.IndexedDBModel.Events.DatabaseRemoved, {model: this, databaseId: databaseId});
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @return {!Promise<!Array.<string>>} databaseNames
-   */
-  async _loadDatabaseNames(securityOrigin) {
-    const databaseNames = await this._indexedDBAgent.requestDatabaseNames(securityOrigin);
-    if (!databaseNames)
-      return [];
-    if (!this._databaseNamesBySecurityOrigin[securityOrigin])
-      return [];
-    this._updateOriginDatabaseNames(securityOrigin, databaseNames);
-    return databaseNames;
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {boolean} entriesUpdated
-   */
-  async _loadDatabase(databaseId, entriesUpdated) {
-    const databaseWithObjectStores =
-        await this._indexedDBAgent.requestDatabase(databaseId.securityOrigin, databaseId.name);
-
-    if (!databaseWithObjectStores)
-      return;
-    if (!this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
-      return;
-
-    const databaseModel = new Resources.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version);
-    this._databases.set(databaseId, databaseModel);
-    for (const objectStore of databaseWithObjectStores.objectStores) {
-      const objectStoreIDBKeyPath = Resources.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
-      const objectStoreModel =
-          new Resources.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
-      for (let j = 0; j < objectStore.indexes.length; ++j) {
-        const index = objectStore.indexes[j];
-        const indexIDBKeyPath = Resources.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
-        const indexModel =
-            new Resources.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
-        objectStoreModel.indexes[indexModel.name] = indexModel;
-      }
-      databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
-    }
-
-    this.dispatchEventToListeners(
-        Resources.IndexedDBModel.Events.DatabaseLoaded,
-        {model: this, database: databaseModel, entriesUpdated: entriesUpdated});
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {string} objectStoreName
-   * @param {?IDBKeyRange} idbKeyRange
-   * @param {number} skipCount
-   * @param {number} pageSize
-   * @param {function(!Array.<!Resources.IndexedDBModel.Entry>, boolean)} callback
-   */
-  loadObjectStoreData(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback) {
-    this._requestData(databaseId, databaseId.name, objectStoreName, '', idbKeyRange, skipCount, pageSize, callback);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {string} objectStoreName
-   * @param {string} indexName
-   * @param {?IDBKeyRange} idbKeyRange
-   * @param {number} skipCount
-   * @param {number} pageSize
-   * @param {function(!Array.<!Resources.IndexedDBModel.Entry>, boolean)} callback
-   */
-  loadIndexData(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback) {
-    this._requestData(
-        databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {string} databaseName
-   * @param {string} objectStoreName
-   * @param {string} indexName
-   * @param {?IDBKeyRange} idbKeyRange
-   * @param {number} skipCount
-   * @param {number} pageSize
-   * @param {function(!Array.<!Resources.IndexedDBModel.Entry>, boolean)} callback
-   */
-  async _requestData(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback) {
-    const keyRange = idbKeyRange ? Resources.IndexedDBModel._keyRangeFromIDBKeyRange(idbKeyRange) : undefined;
-
-    const response = await this._indexedDBAgent.invoke_requestData({
-      securityOrigin: databaseId.securityOrigin,
-      databaseName,
-      objectStoreName,
-      indexName,
-      skipCount,
-      pageSize,
-      keyRange
-    });
-
-    if (response[Protocol.Error]) {
-      console.error('IndexedDBAgent error: ' + response[Protocol.Error]);
-      return;
-    }
-
-    const runtimeModel = this.target().model(SDK.RuntimeModel);
-    if (!runtimeModel || !this._databaseNamesBySecurityOrigin[databaseId.securityOrigin])
-      return;
-    const dataEntries = response.objectStoreDataEntries;
-    const entries = [];
-    for (const dataEntry of dataEntries) {
-      const key = runtimeModel.createRemoteObject(dataEntry.key);
-      const primaryKey = runtimeModel.createRemoteObject(dataEntry.primaryKey);
-      const value = runtimeModel.createRemoteObject(dataEntry.value);
-      entries.push(new Resources.IndexedDBModel.Entry(key, primaryKey, value));
-    }
-    callback(entries, response.hasMore);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  async _refreshDatabaseList(securityOrigin) {
-    const databaseNames = await this._loadDatabaseNames(securityOrigin);
-    for (const databaseName of databaseNames)
-      this._loadDatabase(new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName), false);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @override
-   */
-  indexedDBListUpdated(securityOrigin) {
-    this._originsUpdated.add(securityOrigin);
-
-    this._throttler.schedule(() => {
-      const promises = Array.from(this._originsUpdated, securityOrigin => {
-        this._refreshDatabaseList(securityOrigin);
-      });
-      this._originsUpdated.clear();
-      return Promise.all(promises);
-    });
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {string} databaseName
-   * @param {string} objectStoreName
-   * @override
-   */
-  indexedDBContentUpdated(securityOrigin, databaseName, objectStoreName) {
-    const databaseId = new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
-    this.dispatchEventToListeners(
-        Resources.IndexedDBModel.Events.IndexedDBContentUpdated,
-        {databaseId: databaseId, objectStoreName: objectStoreName, model: this});
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @override
-   */
-  cacheStorageListUpdated(securityOrigin) {
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @override
-   */
-  cacheStorageContentUpdated(securityOrigin) {
-  }
-};
-
-SDK.SDKModel.register(Resources.IndexedDBModel, SDK.Target.Capability.None, false);
-
-Resources.IndexedDBModel.KeyTypes = {
-  NumberType: 'number',
-  StringType: 'string',
-  DateType: 'date',
-  ArrayType: 'array'
-};
-
-Resources.IndexedDBModel.KeyPathTypes = {
-  NullType: 'null',
-  StringType: 'string',
-  ArrayType: 'array'
-};
-
-/** @enum {symbol} */
-Resources.IndexedDBModel.Events = {
-  DatabaseAdded: Symbol('DatabaseAdded'),
-  DatabaseRemoved: Symbol('DatabaseRemoved'),
-  DatabaseLoaded: Symbol('DatabaseLoaded'),
-  DatabaseNamesRefreshed: Symbol('DatabaseNamesRefreshed'),
-  IndexedDBContentUpdated: Symbol('IndexedDBContentUpdated')
-};
-
-/**
- * @unrestricted
- */
-Resources.IndexedDBModel.Entry = class {
-  /**
-   * @param {!SDK.RemoteObject} key
-   * @param {!SDK.RemoteObject} primaryKey
-   * @param {!SDK.RemoteObject} value
-   */
-  constructor(key, primaryKey, value) {
-    this.key = key;
-    this.primaryKey = primaryKey;
-    this.value = value;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IndexedDBModel.DatabaseId = class {
-  /**
-   * @param {string} securityOrigin
-   * @param {string} name
-   */
-  constructor(securityOrigin, name) {
-    this.securityOrigin = securityOrigin;
-    this.name = name;
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @return {boolean}
-   */
-  equals(databaseId) {
-    return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IndexedDBModel.Database = class {
-  /**
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {number} version
-   */
-  constructor(databaseId, version) {
-    this.databaseId = databaseId;
-    this.version = version;
-    this.objectStores = {};
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IndexedDBModel.ObjectStore = class {
-  /**
-   * @param {string} name
-   * @param {*} keyPath
-   * @param {boolean} autoIncrement
-   */
-  constructor(name, keyPath, autoIncrement) {
-    this.name = name;
-    this.keyPath = keyPath;
-    this.autoIncrement = autoIncrement;
-    this.indexes = {};
-  }
-
-  /**
-   * @return {string}
-   */
-  get keyPathString() {
-    return /** @type {string}*/ (
-        Resources.IndexedDBModel.keyPathStringFromIDBKeyPath(/** @type {string}*/ (this.keyPath)));
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IndexedDBModel.Index = class {
-  /**
-   * @param {string} name
-   * @param {*} keyPath
-   * @param {boolean} unique
-   * @param {boolean} multiEntry
-   */
-  constructor(name, keyPath, unique, multiEntry) {
-    this.name = name;
-    this.keyPath = keyPath;
-    this.unique = unique;
-    this.multiEntry = multiEntry;
-  }
-
-  /**
-   * @return {string}
-   */
-  get keyPathString() {
-    return /** @type {string}*/ (
-        Resources.IndexedDBModel.keyPathStringFromIDBKeyPath(/** @type {string}*/ (this.keyPath)));
-  }
-};
diff --git a/front_end/resources/IndexedDBViews.js b/front_end/resources/IndexedDBViews.js
deleted file mode 100644
index 65ec8ed..0000000
--- a/front_end/resources/IndexedDBViews.js
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Resources.IDBDatabaseView = class extends UI.VBox {
-  /**
-   * @param {!Resources.IndexedDBModel} model
-   * @param {?Resources.IndexedDBModel.Database} database
-   */
-  constructor(model, database) {
-    super();
-
-    this._model = model;
-    const databaseName = database ? database.databaseId.name : Common.UIString('Loading\u2026');
-
-    this._reportView = new UI.ReportView(databaseName);
-    this._reportView.show(this.contentElement);
-
-    const bodySection = this._reportView.appendSection('');
-    this._securityOriginElement = bodySection.appendField(Common.UIString('Security origin'));
-    this._versionElement = bodySection.appendField(Common.UIString('Version'));
-
-    const footer = this._reportView.appendSection('').appendRow();
-    this._clearButton = UI.createTextButton(
-        Common.UIString('Delete database'), () => this._deleteDatabase(), Common.UIString('Delete database'));
-    footer.appendChild(this._clearButton);
-
-    this._refreshButton = UI.createTextButton(
-        Common.UIString('Refresh database'), () => this._refreshDatabaseButtonClicked(),
-        Common.UIString('Refresh database'));
-    footer.appendChild(this._refreshButton);
-
-    if (database)
-      this.update(database);
-  }
-
-  _refreshDatabase() {
-    this._securityOriginElement.textContent = this._database.databaseId.securityOrigin;
-    this._versionElement.textContent = this._database.version;
-  }
-
-  _refreshDatabaseButtonClicked() {
-    this._model.refreshDatabase(this._database.databaseId);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.Database} database
-   */
-  update(database) {
-    this._database = database;
-    this._reportView.setTitle(this._database.databaseId.name);
-    this._refreshDatabase();
-    this._updatedForTests();
-  }
-
-  _updatedForTests() {
-    // Sniffed in tests.
-  }
-
-  async _deleteDatabase() {
-    const ok = await UI.ConfirmDialog.show(
-        Common.UIString('Please confirm delete of "%s" database.', this._database.databaseId.name), this.element);
-    if (ok)
-      this._model.deleteDatabase(this._database.databaseId);
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IDBDataView = class extends UI.SimpleView {
-  /**
-   * @param {!Resources.IndexedDBModel} model
-   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
-   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
-   * @param {?Resources.IndexedDBModel.Index} index
-   * @param {function()} refreshObjectStoreCallback
-   */
-  constructor(model, databaseId, objectStore, index, refreshObjectStoreCallback) {
-    super(Common.UIString('IDB'));
-    this.registerRequiredCSS('resources/indexedDBViews.css');
-
-    this._model = model;
-    this._databaseId = databaseId;
-    this._isIndex = !!index;
-    this._refreshObjectStoreCallback = refreshObjectStoreCallback;
-
-    this.element.classList.add('indexed-db-data-view', 'storage-view');
-
-    this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
-
-    this._deleteSelectedButton = new UI.ToolbarButton(Common.UIString('Delete selected'), 'largeicon-delete');
-    this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._deleteButtonClicked(null));
-
-    this._clearButton = new UI.ToolbarButton(Common.UIString('Clear object store'), 'largeicon-clear');
-    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearButtonClicked, this);
-
-    this._needsRefresh = new UI.ToolbarItem(UI.createLabel(Common.UIString('Data may be stale'), 'smallicon-warning'));
-    this._needsRefresh.setVisible(false);
-    this._needsRefresh.setTitle(Common.UIString('Some entries may have been modified'));
-
-    this._createEditorToolbar();
-
-    this._pageSize = 50;
-    this._skipCount = 0;
-
-    this.update(objectStore, index);
-    this._entries = [];
-  }
-
-  /**
-   * @return {!DataGrid.DataGrid}
-   */
-  _createDataGrid() {
-    const keyPath = this._isIndex ? this._index.keyPath : this._objectStore.keyPath;
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([]);
-    columns.push({id: 'number', title: Common.UIString('#'), sortable: false, width: '50px'});
-    columns.push(
-        {id: 'key', titleDOMFragment: this._keyColumnHeaderFragment(Common.UIString('Key'), keyPath), sortable: false});
-    if (this._isIndex) {
-      columns.push({
-        id: 'primaryKey',
-        titleDOMFragment: this._keyColumnHeaderFragment(Common.UIString('Primary key'), this._objectStore.keyPath),
-        sortable: false
-      });
-    }
-    columns.push({id: 'value', title: Common.UIString('Value'), sortable: false});
-
-    const dataGrid = new DataGrid.DataGrid(
-        columns, undefined, this._deleteButtonClicked.bind(this), this._updateData.bind(this, true));
-    dataGrid.setStriped(true);
-    dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, event => this._updateToolbarEnablement(), this);
-    return dataGrid;
-  }
-
-  /**
-   * @param {string} prefix
-   * @param {*} keyPath
-   * @return {!DocumentFragment}
-   */
-  _keyColumnHeaderFragment(prefix, keyPath) {
-    const keyColumnHeaderFragment = createDocumentFragment();
-    keyColumnHeaderFragment.createTextChild(prefix);
-    if (keyPath === null)
-      return keyColumnHeaderFragment;
-
-    keyColumnHeaderFragment.createTextChild(' (' + Common.UIString('Key path: '));
-    if (Array.isArray(keyPath)) {
-      keyColumnHeaderFragment.createTextChild('[');
-      for (let i = 0; i < keyPath.length; ++i) {
-        if (i !== 0)
-          keyColumnHeaderFragment.createTextChild(', ');
-        keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPath[i]));
-      }
-      keyColumnHeaderFragment.createTextChild(']');
-    } else {
-      const keyPathString = /** @type {string} */ (keyPath);
-      keyColumnHeaderFragment.appendChild(this._keyPathStringFragment(keyPathString));
-    }
-    keyColumnHeaderFragment.createTextChild(')');
-    return keyColumnHeaderFragment;
-  }
-
-  /**
-   * @param {string} keyPathString
-   * @return {!DocumentFragment}
-   */
-  _keyPathStringFragment(keyPathString) {
-    const keyPathStringFragment = createDocumentFragment();
-    keyPathStringFragment.createTextChild('"');
-    const keyPathSpan = keyPathStringFragment.createChild('span', 'source-code indexed-db-key-path');
-    keyPathSpan.textContent = keyPathString;
-    keyPathStringFragment.createTextChild('"');
-    return keyPathStringFragment;
-  }
-
-  _createEditorToolbar() {
-    const editorToolbar = new UI.Toolbar('data-view-toolbar', this.element);
-
-    editorToolbar.appendToolbarItem(this._refreshButton);
-    editorToolbar.appendToolbarItem(this._clearButton);
-    editorToolbar.appendToolbarItem(this._deleteSelectedButton);
-
-    editorToolbar.appendToolbarItem(new UI.ToolbarSeparator());
-
-    this._pageBackButton = new UI.ToolbarButton(Common.UIString('Show previous page'), 'largeicon-play-back');
-    this._pageBackButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageBackButtonClicked, this);
-    editorToolbar.appendToolbarItem(this._pageBackButton);
-
-    this._pageForwardButton = new UI.ToolbarButton(Common.UIString('Show next page'), 'largeicon-play');
-    this._pageForwardButton.setEnabled(false);
-    this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageForwardButtonClicked, this);
-    editorToolbar.appendToolbarItem(this._pageForwardButton);
-
-    this._keyInputElement = UI.createInput('toolbar-input');
-    editorToolbar.appendToolbarItem(new UI.ToolbarItem(this._keyInputElement));
-    this._keyInputElement.placeholder = Common.UIString('Start from key');
-    this._keyInputElement.addEventListener('paste', this._keyInputChanged.bind(this), false);
-    this._keyInputElement.addEventListener('cut', this._keyInputChanged.bind(this), false);
-    this._keyInputElement.addEventListener('keypress', this._keyInputChanged.bind(this), false);
-    this._keyInputElement.addEventListener('keydown', this._keyInputChanged.bind(this), false);
-
-    editorToolbar.appendToolbarItem(this._needsRefresh);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _pageBackButtonClicked(event) {
-    this._skipCount = Math.max(0, this._skipCount - this._pageSize);
-    this._updateData(false);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _pageForwardButtonClicked(event) {
-    this._skipCount = this._skipCount + this._pageSize;
-    this._updateData(false);
-  }
-
-  _keyInputChanged() {
-    window.setTimeout(this._updateData.bind(this, false), 0);
-  }
-
-  refreshData() {
-    this._updateData(true);
-  }
-
-  /**
-   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
-   * @param {?Resources.IndexedDBModel.Index} index
-   */
-  update(objectStore, index) {
-    this._objectStore = objectStore;
-    this._index = index;
-
-    if (this._dataGrid)
-      this._dataGrid.asWidget().detach();
-    this._dataGrid = this._createDataGrid();
-    this._dataGrid.asWidget().show(this.element);
-
-    this._skipCount = 0;
-    this._updateData(true);
-  }
-
-  /**
-   * @param {string} keyString
-   */
-  _parseKey(keyString) {
-    let result;
-    try {
-      result = JSON.parse(keyString);
-    } catch (e) {
-      result = keyString;
-    }
-    return result;
-  }
-
-  /**
-   * @param {boolean} force
-   */
-  _updateData(force) {
-    const key = this._parseKey(this._keyInputElement.value);
-    const pageSize = this._pageSize;
-    let skipCount = this._skipCount;
-    let selected = this._dataGrid.selectedNode ? this._dataGrid.selectedNode.data['number'] : 0;
-    selected = Math.max(selected, this._skipCount);  // Page forward should select top entry
-    this._refreshButton.setEnabled(false);
-    this._clearButton.setEnabled(!this._isIndex);
-
-    if (!force && this._lastKey === key && this._lastPageSize === pageSize && this._lastSkipCount === skipCount)
-      return;
-
-    if (this._lastKey !== key || this._lastPageSize !== pageSize) {
-      skipCount = 0;
-      this._skipCount = 0;
-    }
-    this._lastKey = key;
-    this._lastPageSize = pageSize;
-    this._lastSkipCount = skipCount;
-
-    /**
-     * @param {!Array.<!Resources.IndexedDBModel.Entry>} entries
-     * @param {boolean} hasMore
-     * @this {Resources.IDBDataView}
-     */
-    function callback(entries, hasMore) {
-      this._refreshButton.setEnabled(true);
-      this.clear();
-      this._entries = entries;
-      let selectedNode = null;
-      for (let i = 0; i < entries.length; ++i) {
-        const data = {};
-        data['number'] = i + skipCount;
-        data['key'] = entries[i].key;
-        data['primaryKey'] = entries[i].primaryKey;
-        data['value'] = entries[i].value;
-
-        const node = new Resources.IDBDataGridNode(data);
-        this._dataGrid.rootNode().appendChild(node);
-        if (data['number'] <= selected)
-          selectedNode = node;
-      }
-
-      if (selectedNode)
-        selectedNode.select();
-      this._pageBackButton.setEnabled(!!skipCount);
-      this._pageForwardButton.setEnabled(hasMore);
-      this._needsRefresh.setVisible(false);
-      this._updateToolbarEnablement();
-      this._updatedDataForTests();
-    }
-
-    const idbKeyRange = key ? window.IDBKeyRange.lowerBound(key) : null;
-    if (this._isIndex) {
-      this._model.loadIndexData(
-          this._databaseId, this._objectStore.name, this._index.name, idbKeyRange, skipCount, pageSize,
-          callback.bind(this));
-    } else {
-      this._model.loadObjectStoreData(
-          this._databaseId, this._objectStore.name, idbKeyRange, skipCount, pageSize, callback.bind(this));
-    }
-  }
-
-  _updatedDataForTests() {
-    // Sniffed in tests.
-  }
-
-  /**
-   * @param {?Common.Event} event
-   */
-  _refreshButtonClicked(event) {
-    this._updateData(true);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  async _clearButtonClicked(event) {
-    this._clearButton.setEnabled(false);
-    await this._model.clearObjectStore(this._databaseId, this._objectStore.name);
-    this._clearButton.setEnabled(true);
-    this._updateData(true);
-  }
-
-  markNeedsRefresh() {
-    this._needsRefresh.setVisible(true);
-  }
-
-  /**
-   * @param {?DataGrid.DataGridNode} node
-   */
-  async _deleteButtonClicked(node) {
-    if (!node) {
-      node = this._dataGrid.selectedNode;
-      if (!node)
-        return;
-    }
-    const key = /** @type {!SDK.RemoteObject} */ (this._isIndex ? node.data.primaryKey : node.data.key);
-    const keyValue = /** @type {!Array<?>|!Date|number|string} */ (key.value);
-    await this._model.deleteEntries(this._databaseId, this._objectStore.name, window.IDBKeyRange.only(keyValue));
-    this._refreshObjectStoreCallback();
-  }
-
-  clear() {
-    this._dataGrid.rootNode().removeChildren();
-    this._entries = [];
-  }
-
-  _updateToolbarEnablement() {
-    const empty = !this._dataGrid || this._dataGrid.rootNode().children.length === 0;
-    this._clearButton.setEnabled(!empty);
-    this._deleteSelectedButton.setEnabled(!empty && this._dataGrid.selectedNode !== null);
-  }
-};
-
-/**
- * @unrestricted
- */
-Resources.IDBDataGridNode = class extends DataGrid.DataGridNode {
-  /**
-   * @param {!Object.<string, *>} data
-   */
-  constructor(data) {
-    super(data, false);
-    this.selectable = true;
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  createCell(columnIdentifier) {
-    const cell = super.createCell(columnIdentifier);
-    const value = /** @type {!SDK.RemoteObject} */ (this.data[columnIdentifier]);
-
-    switch (columnIdentifier) {
-      case 'value':
-      case 'key':
-      case 'primaryKey':
-        cell.removeChildren();
-        const objectElement = ObjectUI.ObjectPropertiesSection.defaultObjectPresentation(value, undefined, true);
-        cell.appendChild(objectElement);
-        break;
-      default:
-    }
-
-    return cell;
-  }
-};
diff --git a/front_end/resources/ResourcesPanel.js b/front_end/resources/ResourcesPanel.js
deleted file mode 100644
index 96c091e..0000000
--- a/front_end/resources/ResourcesPanel.js
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Resources.ResourcesPanel = class extends UI.PanelWithSidebar {
-  constructor() {
-    super('resources');
-    this.registerRequiredCSS('resources/resourcesPanel.css');
-
-    this._resourcesLastSelectedItemSetting = Common.settings.createSetting('resourcesLastSelectedElementPath', []);
-
-    /** @type {?UI.Widget} */
-    this.visibleView = null;
-
-    /** @type {?Promise<!UI.Widget>} */
-    this._pendingViewPromise = null;
-
-    /** @type {?Resources.StorageCategoryView} */
-    this._categoryView = null;
-
-    const mainContainer = new UI.VBox();
-    this.storageViews = mainContainer.element.createChild('div', 'vbox flex-auto');
-    this._storageViewToolbar = new UI.Toolbar('resources-toolbar', mainContainer.element);
-    this.splitWidget().setMainWidget(mainContainer);
-
-    /** @type {?Resources.DOMStorageItemsView} */
-    this._domStorageView = null;
-
-    /** @type {?Resources.CookieItemsView} */
-    this._cookieView = null;
-
-    /** @type {?UI.EmptyWidget} */
-    this._emptyWidget = null;
-
-    this._sidebar = new Resources.ApplicationPanelSidebar(this);
-    this._sidebar.show(this.panelSidebarElement());
-  }
-
-  /**
-   * @return {!Resources.ResourcesPanel}
-   */
-  static _instance() {
-    return /** @type {!Resources.ResourcesPanel} */ (self.runtime.sharedInstance(Resources.ResourcesPanel));
-  }
-
-  /**
-   * @param {!UI.Widget} view
-   * @return {boolean}
-   */
-  static _shouldCloseOnReset(view) {
-    const viewClassesToClose = [
-      SourceFrame.ResourceSourceFrame, SourceFrame.ImageView, SourceFrame.FontView, Resources.StorageItemsView,
-      Resources.DatabaseQueryView, Resources.DatabaseTableView
-    ];
-    return viewClassesToClose.some(type => view instanceof type);
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._sidebar.focus();
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  lastSelectedItemPath() {
-    return this._resourcesLastSelectedItemSetting.get();
-  }
-
-  /**
-   * @param {!Array<string>} path
-   */
-  setLastSelectedItemPath(path) {
-    this._resourcesLastSelectedItemSetting.set(path);
-  }
-
-  resetView() {
-    if (this.visibleView && Resources.ResourcesPanel._shouldCloseOnReset(this.visibleView))
-      this.showView(null);
-  }
-
-  /**
-   * @param {?UI.Widget} view
-   */
-  showView(view) {
-    this._pendingViewPromise = null;
-    if (this.visibleView === view)
-      return;
-
-    if (this.visibleView)
-      this.visibleView.detach();
-
-    if (view)
-      view.show(this.storageViews);
-    this.visibleView = view;
-
-    this._storageViewToolbar.removeToolbarItems();
-    const toolbarItems = (view instanceof UI.SimpleView && view.syncToolbarItems()) || [];
-    for (let i = 0; i < toolbarItems.length; ++i)
-      this._storageViewToolbar.appendToolbarItem(toolbarItems[i]);
-    this._storageViewToolbar.element.classList.toggle('hidden', !toolbarItems.length);
-  }
-
-  /**
-   * @param {!Promise<!UI.Widget>} viewPromise
-   * @return {!Promise<?UI.Widget>}
-   */
-  async scheduleShowView(viewPromise) {
-    this._pendingViewPromise = viewPromise;
-    const view = await viewPromise;
-    if (this._pendingViewPromise !== viewPromise)
-      return null;
-    this.showView(view);
-    return view;
-  }
-
-  /**
-   * @param {string} categoryName
-   */
-  showCategoryView(categoryName) {
-    if (!this._categoryView)
-      this._categoryView = new Resources.StorageCategoryView();
-    this._categoryView.setText(categoryName);
-    this.showView(this._categoryView);
-  }
-
-  /**
-   * @param {!Resources.DOMStorage} domStorage
-   */
-  showDOMStorage(domStorage) {
-    if (!domStorage)
-      return;
-
-    if (!this._domStorageView)
-      this._domStorageView = new Resources.DOMStorageItemsView(domStorage);
-    else
-      this._domStorageView.setStorage(domStorage);
-    this.showView(this._domStorageView);
-  }
-
-  /**
-   * @param {!SDK.Target} cookieFrameTarget
-   * @param {string} cookieDomain
-   */
-  showCookies(cookieFrameTarget, cookieDomain) {
-    const model = cookieFrameTarget.model(SDK.CookieModel);
-    if (!model)
-      return;
-    if (!this._cookieView)
-      this._cookieView = new Resources.CookieItemsView(model, cookieDomain);
-    else
-      this._cookieView.setCookiesDomain(model, cookieDomain);
-    this.showView(this._cookieView);
-  }
-
-  /**
-   * @param {string} text
-   */
-  showEmptyWidget(text) {
-    if (!this._emptyWidget)
-      this._emptyWidget = new UI.EmptyWidget(text);
-    else
-      this._emptyWidget.text = text;
-    this.showView(this._emptyWidget);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @param {string} cookieDomain
-   */
-  clearCookies(target, cookieDomain) {
-    const model = target.model(SDK.CookieModel);
-    if (!model)
-      return;
-    model.clear(cookieDomain, () => {
-      if (this._cookieView)
-        this._cookieView.refreshItems();
-    });
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- */
-Resources.ResourcesPanel.ResourceRevealer = class {
-  /**
-   * @override
-   * @param {!Object} resource
-   * @return {!Promise}
-   */
-  async reveal(resource) {
-    if (!(resource instanceof SDK.Resource))
-      return Promise.reject(new Error('Internal error: not a resource'));
-    const sidebar = Resources.ResourcesPanel._instance()._sidebar;
-    await UI.viewManager.showView('resources');
-    await sidebar.showResource(resource);
-  }
-};
diff --git a/front_end/resources/ResourcesSection.js b/front_end/resources/ResourcesSection.js
deleted file mode 100644
index 3187665..0000000
--- a/front_end/resources/ResourcesSection.js
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Resources.ResourcesSection = class {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!UI.TreeElement} treeElement
-   */
-  constructor(storagePanel, treeElement) {
-    this._panel = storagePanel;
-    this._treeElement = treeElement;
-    /** @type {!Map<string, !Resources.FrameTreeElement>} */
-    this._treeElementForFrameId = new Map();
-
-    function addListener(eventType, handler, target) {
-      SDK.targetManager.addModelListener(SDK.ResourceTreeModel, eventType, event => handler.call(target, event.data));
-    }
-    addListener(SDK.ResourceTreeModel.Events.FrameAdded, this._frameAdded, this);
-    addListener(SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this);
-    addListener(SDK.ResourceTreeModel.Events.FrameDetached, this._frameDetached, this);
-    addListener(SDK.ResourceTreeModel.Events.ResourceAdded, this._resourceAdded, this);
-
-    const mainTarget = SDK.targetManager.mainTarget();
-    const resourceTreeModel = mainTarget && mainTarget.model(SDK.ResourceTreeModel);
-    const mainFrame = resourceTreeModel && resourceTreeModel.mainFrame;
-    if (mainFrame)
-      this._frameAdded(mainFrame);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   * @returns {?SDK.ResourceTreeFrame}
-   */
-  static _getParentFrame(frame) {
-    const parentFrame = frame.parentFrame;
-    if (parentFrame)
-      return parentFrame;
-    const parentTarget = frame.resourceTreeModel().target().parentTarget();
-    if (!parentTarget)
-      return null;
-    return parentTarget.model(SDK.ResourceTreeModel).mainFrame;
-  }
-
-  /**
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @return {boolean}
-   */
-  _expandFrame(frame) {
-    if (!frame)
-      return false;
-    let treeElement = this._treeElementForFrameId.get(frame.id);
-    if (!treeElement && !this._expandFrame(Resources.ResourcesSection._getParentFrame(frame)))
-      return false;
-    treeElement = this._treeElementForFrameId.get(frame.id);
-    if (!treeElement)
-      return false;
-    treeElement.expand();
-    return true;
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   * @param {number=} line
-   * @param {number=} column
-   * @return {!Promise}
-   */
-  async revealResource(resource, line, column) {
-    if (!this._expandFrame(resource.frame()))
-      return;
-    const resourceTreeElement = Resources.FrameResourceTreeElement.forResource(resource);
-    if (resourceTreeElement)
-      await resourceTreeElement.revealResource(line, column);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _frameAdded(frame) {
-    const parentFrame = Resources.ResourcesSection._getParentFrame(frame);
-    const parentTreeElement = parentFrame ? this._treeElementForFrameId.get(parentFrame.id) : this._treeElement;
-    if (!parentTreeElement)
-      return;
-    const frameTreeElement = new Resources.FrameTreeElement(this, frame);
-    this._treeElementForFrameId.set(frame.id, frameTreeElement);
-    parentTreeElement.appendChild(frameTreeElement);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _frameDetached(frame) {
-    const frameTreeElement = this._treeElementForFrameId.get(frame.id);
-    if (!frameTreeElement)
-      return;
-
-    this._treeElementForFrameId.remove(frame.id);
-    if (frameTreeElement.parent)
-      frameTreeElement.parent.removeChild(frameTreeElement);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _frameNavigated(frame) {
-    const frameTreeElement = this._treeElementForFrameId.get(frame.id);
-    if (frameTreeElement)
-      frameTreeElement.frameNavigated(frame);
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  _resourceAdded(resource) {
-    const frameTreeElement = this._treeElementForFrameId.get(resource.frameId);
-    if (!frameTreeElement) {
-      // This is a frame's main resource, it will be retained
-      // and re-added by the resource manager;
-      return;
-    }
-    frameTreeElement.appendResource(resource);
-  }
-
-  reset() {
-    this._treeElement.removeChildren();
-    this._treeElementForFrameId.clear();
-  }
-};
-
-Resources.FrameTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesSection} section
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  constructor(section, frame) {
-    super(section._panel, '', false);
-    this._populated = false;
-    this._section = section;
-    this._frame = frame;
-    this._frameId = frame.id;
-    this._categoryElements = {};
-    this._treeElementForResource = {};
-    this.setExpandable(true);
-    this.frameNavigated(frame);
-
-    const icon = UI.Icon.create('largeicon-navigator-frame', 'navigator-tree-item');
-    icon.classList.add('navigator-frame-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  frameNavigated(frame) {
-    this.invalidateChildren();
-    this._frameId = frame.id;
-    this.title = frame.displayName();
-    this._categoryElements = {};
-    this._treeElementForResource = {};
-  }
-
-  get itemURL() {
-    return 'frame://' + encodeURI(this.titleAsText());
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._section._panel.showCategoryView(this.titleAsText());
-
-    this.listItemElement.classList.remove('hovered');
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    return false;
-  }
-
-  set hovered(hovered) {
-    if (hovered) {
-      this.listItemElement.classList.add('hovered');
-      this._frame.resourceTreeModel().domModel().overlayModel().highlightFrame(this._frameId);
-    } else {
-      this.listItemElement.classList.remove('hovered');
-      SDK.OverlayModel.hideDOMNodeHighlight();
-    }
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  appendResource(resource) {
-    if (!this._populated)
-      return;
-    const statusCode = resource['statusCode'];
-    if (statusCode >= 301 && statusCode <= 303)
-      return;
-
-    const resourceType = resource.resourceType();
-    const categoryName = resourceType.name();
-    let categoryElement = resourceType === Common.resourceTypes.Document ? this : this._categoryElements[categoryName];
-    if (!categoryElement) {
-      categoryElement = new Resources.StorageCategoryTreeElement(
-          this._section._panel, resource.resourceType().category().title, categoryName);
-      this._categoryElements[resourceType.name()] = categoryElement;
-      this._insertInPresentationOrder(this, categoryElement);
-    }
-    const resourceTreeElement = new Resources.FrameResourceTreeElement(this._section._panel, resource);
-    this._insertInPresentationOrder(categoryElement, resourceTreeElement);
-    this._treeElementForResource[resource.url] = resourceTreeElement;
-  }
-
-  /**
-   * @param {string} url
-   * @return {?SDK.Resource}
-   */
-  resourceByURL(url) {
-    const treeElement = this._treeElementForResource[url];
-    return treeElement ? treeElement._resource : null;
-  }
-
-  /**
-   * @override
-   * @param {!UI.TreeElement} treeElement
-   */
-  appendChild(treeElement) {
-    if (!this._populated)
-      return;
-    this._insertInPresentationOrder(this, treeElement);
-  }
-
-  _insertInPresentationOrder(parentTreeElement, childTreeElement) {
-    // Insert in the alphabetical order, first frames, then resources. Document resource goes last.
-    function typeWeight(treeElement) {
-      if (treeElement instanceof Resources.StorageCategoryTreeElement)
-        return 2;
-      if (treeElement instanceof Resources.FrameTreeElement)
-        return 1;
-      return 3;
-    }
-
-    function compare(treeElement1, treeElement2) {
-      const typeWeight1 = typeWeight(treeElement1);
-      const typeWeight2 = typeWeight(treeElement2);
-
-      let result;
-      if (typeWeight1 > typeWeight2)
-        result = 1;
-      else if (typeWeight1 < typeWeight2)
-        result = -1;
-      else
-        result = treeElement1.titleAsText().localeCompare(treeElement2.titleAsText());
-      return result;
-    }
-
-    const childCount = parentTreeElement.childCount();
-    let i;
-    for (i = 0; i < childCount; ++i) {
-      if (compare(childTreeElement, parentTreeElement.childAt(i)) < 0)
-        break;
-    }
-    parentTreeElement.insertChild(childTreeElement, i);
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    this._populated = true;
-    for (const child of this._frame.childFrames)
-      this._section._frameAdded(child);
-    for (const resource of this._frame.resources())
-      this.appendResource(resource);
-  }
-};
-
-Resources.FrameResourceTreeElement = class extends Resources.BaseStorageTreeElement {
-  /**
-   * @param {!Resources.ResourcesPanel} storagePanel
-   * @param {!SDK.Resource} resource
-   */
-  constructor(storagePanel, resource) {
-    super(storagePanel, resource.displayName, false);
-    this._panel = storagePanel;
-    /** @type {!SDK.Resource} */
-    this._resource = resource;
-    /** @type {?Promise<!UI.Widget>} */
-    this._previewPromise = null;
-    this.tooltip = resource.url;
-    this._resource[Resources.FrameResourceTreeElement._symbol] = this;
-
-    const icon = UI.Icon.create('largeicon-navigator-file', 'navigator-tree-item');
-    icon.classList.add('navigator-file-tree-item');
-    icon.classList.add('navigator-' + resource.resourceType().name() + '-tree-item');
-    this.setLeadingIcons([icon]);
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  static forResource(resource) {
-    return resource[Resources.FrameResourceTreeElement._symbol];
-  }
-
-  get itemURL() {
-    return this._resource.url;
-  }
-
-  /**
-   * @return {!Promise<!UI.Widget>}
-   */
-  _preparePreview() {
-    if (this._previewPromise)
-      return this._previewPromise;
-    const viewPromise = SourceFrame.PreviewFactory.createPreview(this._resource, this._resource.mimeType);
-    this._previewPromise = viewPromise.then(view => {
-      if (view)
-        return view;
-      return new UI.EmptyWidget(this._resource.url);
-    });
-    return this._previewPromise;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    super.onselect(selectedByUser);
-    this._panel.scheduleShowView(this._preparePreview());
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondblclick(event) {
-    InspectorFrontendHost.openInNewTab(this._resource.url);
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    super.onattach();
-    this.listItemElement.draggable = true;
-    this.listItemElement.addEventListener('dragstart', this._ondragstart.bind(this), false);
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _ondragstart(event) {
-    event.dataTransfer.setData('text/plain', this._resource.content || '');
-    event.dataTransfer.effectAllowed = 'copy';
-    return true;
-  }
-
-  _handleContextMenuEvent(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.appendApplicableItems(this._resource);
-    contextMenu.show();
-  }
-
-  /**
-   * @param {number=} line
-   * @param {number=} column
-   */
-  async revealResource(line, column) {
-    this.revealAndSelect(true);
-    const view = await this._panel.scheduleShowView(this._preparePreview());
-    if (!(view instanceof SourceFrame.ResourceSourceFrame) || typeof line !== 'number')
-      return;
-    view.revealPosition(line, column, true);
-  }
-};
-
-Resources.FrameResourceTreeElement._symbol = Symbol('treeElement');
diff --git a/front_end/resources/ServiceWorkerCacheViews.js b/front_end/resources/ServiceWorkerCacheViews.js
deleted file mode 100644
index 15f5494..0000000
--- a/front_end/resources/ServiceWorkerCacheViews.js
+++ /dev/null
@@ -1,409 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Resources.ServiceWorkerCacheView = class extends UI.SimpleView {
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel} model
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  constructor(model, cache) {
-    super(Common.UIString('Cache'));
-    this.registerRequiredCSS('resources/serviceWorkerCacheViews.css');
-
-    this._model = model;
-    this._entriesForTest = null;
-
-    this.element.classList.add('service-worker-cache-data-view');
-    this.element.classList.add('storage-view');
-
-    const editorToolbar = new UI.Toolbar('data-view-toolbar', this.element);
-    this._splitWidget = new UI.SplitWidget(false, false);
-    this._splitWidget.show(this.element);
-
-    this._previewPanel = new UI.VBox();
-    const resizer = this._previewPanel.element.createChild('div', 'cache-preview-panel-resizer');
-    this._splitWidget.setMainWidget(this._previewPanel);
-    this._splitWidget.installResizer(resizer);
-
-    /** @type {?UI.Widget} */
-    this._preview = null;
-
-    this._cache = cache;
-    /** @type {?DataGrid.DataGrid} */
-    this._dataGrid = null;
-    /** @type {?number} */
-    this._lastPageSize = null;
-    /** @type {?number} */
-    this._lastSkipCount = null;
-    this._refreshThrottler = new Common.Throttler(300);
-
-    this._pageBackButton = new UI.ToolbarButton(Common.UIString('Show previous page'), 'largeicon-play-back');
-    this._pageBackButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageBackButtonClicked, this);
-    editorToolbar.appendToolbarItem(this._pageBackButton);
-
-    this._pageForwardButton = new UI.ToolbarButton(Common.UIString('Show next page'), 'largeicon-play');
-    this._pageForwardButton.setEnabled(false);
-    this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageForwardButtonClicked, this);
-    editorToolbar.appendToolbarItem(this._pageForwardButton);
-
-    this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
-    editorToolbar.appendToolbarItem(this._refreshButton);
-
-    this._deleteSelectedButton = new UI.ToolbarButton(Common.UIString('Delete Selected'), 'largeicon-delete');
-    this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._deleteButtonClicked(null));
-    editorToolbar.appendToolbarItem(this._deleteSelectedButton);
-
-    this._pageSize = 50;
-    this._skipCount = 0;
-
-    this.update(cache);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._model.addEventListener(
-        SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated, this._cacheContentUpdated, this);
-    this._updateData(true);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._model.removeEventListener(
-        SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated, this._cacheContentUpdated, this);
-  }
-
-  /**
-   * @param {?UI.Widget} preview
-   */
-  _showPreview(preview) {
-    if (this._preview === preview)
-      return;
-    if (this._preview)
-      this._preview.detach();
-    if (!preview)
-      preview = new UI.EmptyWidget(Common.UIString('Select a cache entry above to preview'));
-    this._preview = preview;
-    this._preview.show(this._previewPanel.element);
-  }
-
-  /**
-   * @return {!DataGrid.DataGrid}
-   */
-  _createDataGrid() {
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'path', title: Common.UIString('Path'), weight: 4, sortable: true},
-      {id: 'contentType', title: Common.UIString('Content-Type'), weight: 1, sortable: true}, {
-        id: 'contentLength',
-        title: Common.UIString('Content-Length'),
-        weight: 1,
-        align: DataGrid.DataGrid.Align.Right,
-        sortable: true
-      },
-      {
-        id: 'responseTime',
-        title: Common.UIString('Time Cached'),
-        width: '12em',
-        weight: 1,
-        align: DataGrid.DataGrid.Align.Right,
-        sortable: true
-      }
-    ]);
-    const dataGrid = new DataGrid.DataGrid(
-        columns, undefined, this._deleteButtonClicked.bind(this), this._updateData.bind(this, true));
-
-    dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortingChanged, this);
-
-    dataGrid.addEventListener(
-        DataGrid.DataGrid.Events.SelectedNode, event => this._previewCachedResponse(event.data.data), this);
-    dataGrid.setStriped(true);
-    return dataGrid;
-  }
-
-  _sortingChanged() {
-    if (!this._dataGrid)
-      return;
-
-    const accending = this._dataGrid.isSortOrderAscending();
-    const columnId = this._dataGrid.sortColumnId();
-    let comparator;
-    if (columnId === 'path')
-      comparator = (a, b) => a._path.localeCompare(b._path);
-    else if (columnId === 'contentType')
-      comparator = (a, b) => a.data.mimeType.localeCompare(b.data.mimeType);
-    else if (columnId === 'contentLength')
-      comparator = (a, b) => a.data.resourceSize - b.data.resourceSize;
-    else if (columnId === 'responseTime')
-      comparator = (a, b) => a.data.endTime - b.data.endTime;
-
-    const children = this._dataGrid.rootNode().children.slice();
-    this._dataGrid.rootNode().removeChildren();
-    children.sort((a, b) => {
-      const result = comparator(a, b);
-      return accending ? result : -result;
-    });
-    children.forEach(child => this._dataGrid.rootNode().appendChild(child));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _pageBackButtonClicked(event) {
-    this._skipCount = Math.max(0, this._skipCount - this._pageSize);
-    this._updateData(false);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _pageForwardButtonClicked(event) {
-    this._skipCount = this._skipCount + this._pageSize;
-    this._updateData(false);
-  }
-
-  /**
-   * @param {?DataGrid.DataGridNode} node
-   */
-  async _deleteButtonClicked(node) {
-    if (!node) {
-      node = this._dataGrid && this._dataGrid.selectedNode;
-      if (!node)
-        return;
-    }
-    await this._model.deleteCacheEntry(this._cache, /** @type {string} */ (node.data.url()));
-    node.remove();
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  update(cache) {
-    this._cache = cache;
-
-    if (this._dataGrid)
-      this._dataGrid.asWidget().detach();
-    this._dataGrid = this._createDataGrid();
-    this._splitWidget.setSidebarWidget(this._dataGrid.asWidget());
-    this._skipCount = 0;
-    this._updateData(true);
-  }
-
-  /**
-   * @param {number} skipCount
-   * @param {!Array<!Protocol.CacheStorage.DataEntry>} entries
-   * @param {boolean} hasMore
-   * @this {Resources.ServiceWorkerCacheView}
-   */
-  _updateDataCallback(skipCount, entries, hasMore) {
-    const selected = this._dataGrid.selectedNode && this._dataGrid.selectedNode.data.url();
-    this._refreshButton.setEnabled(true);
-    this._entriesForTest = entries;
-
-    /** @type {!Map<string, !DataGrid.DataGridNode>} */
-    const oldEntries = new Map();
-    const rootNode = this._dataGrid.rootNode();
-    for (const node of rootNode.children)
-      oldEntries.set(node.data.url, node);
-    rootNode.removeChildren();
-    let selectedNode = null;
-    for (const entry of entries) {
-      let node = oldEntries.get(entry.requestURL);
-      if (!node || node.data.responseTime !== entry.responseTime) {
-        node = new Resources.ServiceWorkerCacheView.DataGridNode(this._createRequest(entry));
-        node.selectable = true;
-      }
-      rootNode.appendChild(node);
-      if (entry.requestURL === selected)
-        selectedNode = node;
-    }
-    this._pageBackButton.setEnabled(!!skipCount);
-    this._pageForwardButton.setEnabled(hasMore);
-    if (!selectedNode)
-      this._showPreview(null);
-    else
-      selectedNode.revealAndSelect();
-    this._updatedForTest();
-  }
-
-  /**
-   * @param {boolean} force
-   */
-  _updateData(force) {
-    const pageSize = this._pageSize;
-    let skipCount = this._skipCount;
-
-    if (!force && this._lastPageSize === pageSize && this._lastSkipCount === skipCount)
-      return;
-    this._refreshButton.setEnabled(false);
-    if (this._lastPageSize !== pageSize) {
-      skipCount = 0;
-      this._skipCount = 0;
-    }
-    this._lastPageSize = pageSize;
-    this._lastSkipCount = skipCount;
-    this._model.loadCacheData(this._cache, skipCount, pageSize, this._updateDataCallback.bind(this, skipCount));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _refreshButtonClicked(event) {
-    this._updateData(true);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _cacheContentUpdated(event) {
-    const nameAndOrigin = event.data;
-    if (this._cache.securityOrigin !== nameAndOrigin.origin || this._cache.cacheName !== nameAndOrigin.cacheName)
-      return;
-    this._refreshThrottler.schedule(() => Promise.resolve(this._updateData(true)), true);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  async _previewCachedResponse(request) {
-    let preview = request[Resources.ServiceWorkerCacheView._previewSymbol];
-    if (!preview) {
-      preview = new Resources.ServiceWorkerCacheView.RequestView(request);
-      request[Resources.ServiceWorkerCacheView._previewSymbol] = preview;
-    }
-
-    // It is possible that table selection changes before the preview opens.
-    if (request === this._dataGrid.selectedNode.data)
-      this._showPreview(preview);
-  }
-
-  /**
-   * @param {!Protocol.CacheStorage.DataEntry} entry
-   * @return {!SDK.NetworkRequest}
-   */
-  _createRequest(entry) {
-    const request = new SDK.NetworkRequest('cache-storage-' + entry.requestURL, entry.requestURL, '', '', '', null);
-    request.requestMethod = entry.requestMethod;
-    request.setRequestHeaders(entry.requestHeaders);
-    request.statusCode = entry.responseStatus;
-    request.statusText = entry.responseStatusText;
-    request.protocol = new Common.ParsedURL(entry.requestURL).scheme;
-    request.responseHeaders = entry.responseHeaders;
-    request.setRequestHeadersText('');
-    request.endTime = entry.responseTime;
-
-    let header = entry.responseHeaders.find(header => header.name.toLowerCase() === 'content-type');
-    const contentType = header ? header.value : 'text/plain';
-    request.mimeType = contentType;
-
-    header = entry.responseHeaders.find(header => header.name.toLowerCase() === 'content-length');
-    request.resourceSize = (header && header.value) | 0;
-
-    let resourceType = Common.ResourceType.fromMimeType(contentType);
-    if (!resourceType)
-      resourceType = Common.ResourceType.fromURL(entry.requestURL) || Common.resourceTypes.Other;
-    request.setResourceType(resourceType);
-    request.setContentDataProvider(this._requestContent.bind(this, request));
-    return request;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<!SDK.NetworkRequest.ContentData>}
-   */
-  async _requestContent(request) {
-    const isText = request.resourceType().isTextType();
-    const contentData = {error: null, content: null, encoded: !isText};
-    const response = await this._cache.requestCachedResponse(request.url());
-    if (response)
-      contentData.content = isText ? window.atob(response.body) : response.body;
-    return contentData;
-  }
-
-  _updatedForTest() {
-  }
-};
-
-Resources.ServiceWorkerCacheView._previewSymbol = Symbol('preview');
-
-Resources.ServiceWorkerCacheView._RESPONSE_CACHE_SIZE = 10;
-
-Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridNode {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super(request);
-    this._path = Common.ParsedURL.extractPath(request.url());
-    if (!this._path)
-      this._path = request.url();
-    if (this._path.length > 1 && this._path.startsWith('/'))
-      this._path = this._path.substring(1);
-    this._request = request;
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    const cell = this.createTD(columnId);
-    let value;
-    if (columnId === 'path')
-      value = this._path;
-    else if (columnId === 'contentType')
-      value = this._request.mimeType;
-    else if (columnId === 'contentLength')
-      value = (this._request.resourceSize | 0).toLocaleString('en-US');
-    else if (columnId === 'responseTime')
-      value = new Date(this._request.endTime * 1000).toLocaleString();
-    DataGrid.DataGrid.setElementText(cell, value || '', true);
-    return cell;
-  }
-};
-
-Resources.ServiceWorkerCacheView.RequestView = class extends UI.VBox {
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  constructor(request) {
-    super();
-
-    this._tabbedPane = new UI.TabbedPane();
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-    this._resourceViewTabSetting = Common.settings.createSetting('cacheStorageViewTab', 'preview');
-
-    this._tabbedPane.appendTab('headers', Common.UIString('Headers'), new Network.RequestHeadersView(request));
-    this._tabbedPane.appendTab('preview', Common.UIString('Preview'), new Network.RequestPreviewView(request));
-    this._tabbedPane.show(this.element);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._selectTab();
-  }
-
-  /**
-   * @param {string=} tabId
-   */
-  _selectTab(tabId) {
-    if (!tabId)
-      tabId = this._resourceViewTabSetting.get();
-    if (!this._tabbedPane.selectTab(tabId))
-      this._tabbedPane.selectTab('headers');
-  }
-
-  _tabSelected(event) {
-    if (!event.data.isUserGesture)
-      return;
-    this._resourceViewTabSetting.set(event.data.tabId);
-  }
-};
diff --git a/front_end/resources/ServiceWorkersView.js b/front_end/resources/ServiceWorkersView.js
deleted file mode 100644
index a8f3da1..0000000
--- a/front_end/resources/ServiceWorkersView.js
+++ /dev/null
@@ -1,587 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!SDK.ServiceWorkerManager>}
- */
-Resources.ServiceWorkersView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('resources/serviceWorkersView.css');
-
-    this._currentWorkersView = new UI.ReportView(Common.UIString('Service Workers'));
-    this._currentWorkersView.setBodyScrollable(false);
-    this.contentElement.classList.add('service-worker-list');
-    this._currentWorkersView.show(this.contentElement);
-    this._currentWorkersView.element.classList.add('service-workers-this-origin');
-
-    this._toolbar = this._currentWorkersView.createToolbar();
-    this._toolbar.makeWrappable(false, true);
-
-    /** @type {!Map<!SDK.ServiceWorkerRegistration, !Resources.ServiceWorkersView.Section>} */
-    this._sections = new Map();
-
-    /** @type {?SDK.ServiceWorkerManager} */
-    this._manager = null;
-    /** @type {?SDK.SecurityOriginManager} */
-    this._securityOriginManager = null;
-
-    this._filterThrottler = new Common.Throttler(300);
-
-    this._otherWorkers = this.contentElement.createChild('div', 'service-workers-other-origin');
-    this._otherSWFilter = this._otherWorkers.createChild('div', 'service-worker-filter');
-    this._otherSWFilter.setAttribute('tabindex', 0);
-    this._otherSWFilter.setAttribute('role', 'switch');
-    this._otherSWFilter.setAttribute('aria-checked', false);
-    this._otherSWFilter.addEventListener('keydown', event => {
-      if (isEnterKey(event) || event.keyCode === UI.KeyboardShortcut.Keys.Space.code)
-        this._toggleFilter();
-    });
-    const filterLabel = this._otherSWFilter.createChild('label', 'service-worker-filter-label');
-    filterLabel.textContent = Common.UIString('Service workers from other domains');
-    filterLabel.setAttribute('for', 'expand-all');
-    filterLabel.addEventListener('click', () => this._toggleFilter());
-
-    const toolbar = new UI.Toolbar('service-worker-filter-toolbar', this._otherSWFilter);
-    this._filter = new UI.ToolbarInput('Filter', 1);
-    this._filter.addEventListener(UI.ToolbarInput.Event.TextChanged, () => this._filterChanged());
-    toolbar.appendToolbarItem(this._filter);
-
-    this._otherWorkersView = new UI.ReportView();
-    this._otherWorkersView.setBodyScrollable(false);
-    this._otherWorkersView.show(this._otherWorkers);
-    this._otherWorkersView.element.classList.add('service-workers-for-other-origins');
-
-    this._updateCollapsedStyle();
-
-    this._toolbar.appendToolbarItem(MobileThrottling.throttlingManager().createOfflineToolbarCheckbox());
-    const updateOnReloadSetting = Common.settings.createSetting('serviceWorkerUpdateOnReload', false);
-    updateOnReloadSetting.setTitle(Common.UIString('Update on reload'));
-    const forceUpdate = new UI.ToolbarSettingCheckbox(
-        updateOnReloadSetting, Common.UIString('Force update Service Worker on page reload'));
-    this._toolbar.appendToolbarItem(forceUpdate);
-    const bypassServiceWorkerSetting = Common.settings.createSetting('bypassServiceWorker', false);
-    bypassServiceWorkerSetting.setTitle(Common.UIString('Bypass for network'));
-    const fallbackToNetwork = new UI.ToolbarSettingCheckbox(
-        bypassServiceWorkerSetting, Common.UIString('Bypass Service Worker and load resources from the network'));
-    this._toolbar.appendToolbarItem(fallbackToNetwork);
-
-    /** @type {!Map<!SDK.ServiceWorkerManager, !Array<!Common.EventTarget.EventDescriptor>>}*/
-    this._eventListeners = new Map();
-    SDK.targetManager.observeModels(SDK.ServiceWorkerManager, this);
-    this._updateListVisibility();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ServiceWorkerManager} serviceWorkerManager
-   */
-  modelAdded(serviceWorkerManager) {
-    if (this._manager)
-      return;
-    this._manager = serviceWorkerManager;
-    this._securityOriginManager = serviceWorkerManager.target().model(SDK.SecurityOriginManager);
-
-    for (const registration of this._manager.registrations().values())
-      this._updateRegistration(registration);
-
-    this._eventListeners.set(serviceWorkerManager, [
-      this._manager.addEventListener(
-          SDK.ServiceWorkerManager.Events.RegistrationUpdated, this._registrationUpdated, this),
-      this._manager.addEventListener(
-          SDK.ServiceWorkerManager.Events.RegistrationDeleted, this._registrationDeleted, this),
-      this._securityOriginManager.addEventListener(
-          SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._updateSectionVisibility, this),
-      this._securityOriginManager.addEventListener(
-          SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._updateSectionVisibility, this),
-    ]);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ServiceWorkerManager} serviceWorkerManager
-   */
-  modelRemoved(serviceWorkerManager) {
-    if (!this._manager || this._manager !== serviceWorkerManager)
-      return;
-
-    Common.EventTarget.removeEventListeners(this._eventListeners.get(serviceWorkerManager));
-    this._eventListeners.delete(serviceWorkerManager);
-    this._manager = null;
-    this._securityOriginManager = null;
-  }
-
-  _updateSectionVisibility() {
-    let hasOthers = false;
-    let hasThis = false;
-    const movedSections = [];
-    for (const section of this._sections.values()) {
-      const expectedView = this._getReportViewForOrigin(section._registration.securityOrigin);
-      hasOthers |= expectedView === this._otherWorkersView;
-      hasThis |= expectedView === this._currentWorkersView;
-      if (section._section.parentWidget() !== expectedView)
-        movedSections.push(section);
-    }
-
-    for (const section of movedSections) {
-      const registration = section._registration;
-      this._removeRegistrationFromList(registration);
-      this._updateRegistration(registration, true);
-    }
-
-    const scorer = new Sources.FilePathScoreFunction(this._filter.value());
-    this._otherWorkersView.sortSections((a, b) => {
-      const cmp = scorer.score(b.title(), null) - scorer.score(a.title(), null);
-      return cmp === 0 ? a.title().localeCompare(b.title()) : cmp;
-    });
-    for (const section of this._sections.values()) {
-      if (section._section.parentWidget() === this._currentWorkersView ||
-          this._isRegistrationVisible(section._registration))
-        section._section.showWidget();
-      else
-        section._section.hideWidget();
-    }
-    this.contentElement.classList.toggle('service-worker-has-current', hasThis);
-    this._otherWorkers.classList.toggle('hidden', !hasOthers);
-    this._updateListVisibility();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _registrationUpdated(event) {
-    const registration = /** @type {!SDK.ServiceWorkerRegistration} */ (event.data);
-    this._updateRegistration(registration);
-    this._gcRegistrations();
-  }
-
-  _gcRegistrations() {
-    let hasNonDeletedRegistrations = false;
-    const securityOrigins = new Set(this._securityOriginManager.securityOrigins());
-    for (const registration of this._manager.registrations().values()) {
-      if (!securityOrigins.has(registration.securityOrigin) && !this._isRegistrationVisible(registration))
-        continue;
-      if (!registration.canBeRemoved()) {
-        hasNonDeletedRegistrations = true;
-        break;
-      }
-    }
-
-    if (!hasNonDeletedRegistrations)
-      return;
-
-    for (const registration of this._manager.registrations().values()) {
-      const visible = securityOrigins.has(registration.securityOrigin) || this._isRegistrationVisible(registration);
-      if (!visible && registration.canBeRemoved())
-        this._removeRegistrationFromList(registration);
-    }
-  }
-
-  /**
-   * @param {string} origin
-   * @return {!UI.ReportView}
-   */
-  _getReportViewForOrigin(origin) {
-    if (this._securityOriginManager.securityOrigins().includes(origin))
-      return this._currentWorkersView;
-    else
-      return this._otherWorkersView;
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerRegistration} registration
-   * @param {boolean=} skipUpdate
-   */
-  _updateRegistration(registration, skipUpdate) {
-    let section = this._sections.get(registration);
-    if (!section) {
-      const title = Resources.ServiceWorkersView._displayScopeURL(registration.scopeURL);
-      section = new Resources.ServiceWorkersView.Section(
-          /** @type {!SDK.ServiceWorkerManager} */ (this._manager),
-          this._getReportViewForOrigin(registration.securityOrigin).appendSection(title), registration);
-      this._sections.set(registration, section);
-    }
-    if (skipUpdate)
-      return;
-    this._updateSectionVisibility();
-    section._scheduleUpdate();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _registrationDeleted(event) {
-    const registration = /** @type {!SDK.ServiceWorkerRegistration} */ (event.data);
-    this._removeRegistrationFromList(registration);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerRegistration} registration
-   */
-  _removeRegistrationFromList(registration) {
-    const section = this._sections.get(registration);
-    if (section)
-      section._section.detach();
-    this._sections.delete(registration);
-    this._updateSectionVisibility();
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerRegistration} registration
-   * @return {boolean}
-   */
-  _isRegistrationVisible(registration) {
-    const filterString = this._filter.value();
-    if (!filterString || !registration.scopeURL)
-      return true;
-
-    const regex = String.filterRegex(filterString);
-    return registration.scopeURL.match(regex);
-  }
-
-  _filterChanged() {
-    this._updateCollapsedStyle();
-    this._filterThrottler.schedule(() => Promise.resolve(this._updateSectionVisibility()));
-  }
-
-  _updateCollapsedStyle() {
-    const expanded = this._otherSWFilter.getAttribute('aria-checked') === 'true';
-    this._otherWorkers.classList.toggle('service-worker-filter-collapsed', !expanded);
-    if (expanded)
-      this._otherWorkersView.showWidget();
-    else
-      this._otherWorkersView.hideWidget();
-    this._otherWorkersView.setHeaderVisible(false);
-  }
-
-  /**
-   * @param {string} scopeURL
-   * @return {string}
-   */
-  static _displayScopeURL(scopeURL) {
-    const parsedURL = scopeURL.asParsedURL();
-    let path = parsedURL.path;
-    if (path.endsWith('/'))
-      path = path.substring(0, path.length - 1);
-    return parsedURL.host + path;
-  }
-
-  _updateListVisibility() {
-    this.contentElement.classList.toggle('service-worker-list-empty', this._sections.size === 0);
-  }
-
-  _toggleFilter() {
-    const expanded = this._otherSWFilter.getAttribute('aria-checked') === 'true';
-    this._otherSWFilter.setAttribute('aria-checked', !expanded);
-    this._filterChanged();
-  }
-};
-
-Resources.ServiceWorkersView.Section = class {
-  /**
-   * @param {!SDK.ServiceWorkerManager} manager
-   * @param {!UI.ReportView.Section} section
-   * @param {!SDK.ServiceWorkerRegistration} registration
-   */
-  constructor(manager, section, registration) {
-    this._manager = manager;
-    this._section = section;
-    this._registration = registration;
-    /** @type {?symbol} */
-    this._fingerprint = null;
-    this._pushNotificationDataSetting =
-        Common.settings.createLocalSetting('pushData', Common.UIString('Test push message from DevTools.'));
-    this._syncTagNameSetting = Common.settings.createLocalSetting('syncTagName', 'test-tag-from-devtools');
-
-    this._toolbar = section.createToolbar();
-    this._toolbar.renderAsLinks();
-    this._updateButton = new UI.ToolbarButton(Common.UIString('Update'), undefined, Common.UIString('Update'));
-    this._updateButton.addEventListener(UI.ToolbarButton.Events.Click, this._updateButtonClicked, this);
-    this._toolbar.appendToolbarItem(this._updateButton);
-    this._deleteButton =
-        new UI.ToolbarButton(Common.UIString('Unregister service worker'), undefined, Common.UIString('Unregister'));
-    this._deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._unregisterButtonClicked, this);
-    this._toolbar.appendToolbarItem(this._deleteButton);
-
-    // Preserve the order.
-    this._sourceField = this._wrapWidget(this._section.appendField(Common.UIString('Source')));
-    this._statusField = this._wrapWidget(this._section.appendField(Common.UIString('Status')));
-    this._clientsField = this._wrapWidget(this._section.appendField(Common.UIString('Clients')));
-    this._createSyncNotificationField(
-        Common.UIString('Push'), this._pushNotificationDataSetting.get(), Common.UIString('Push data'),
-        this._push.bind(this));
-    this._createSyncNotificationField(
-        Common.UIString('Sync'), this._syncTagNameSetting.get(), Common.UIString('Sync tag'), this._sync.bind(this));
-
-    this._linkifier = new Components.Linkifier();
-    /** @type {!Map<string, !Protocol.Target.TargetInfo>} */
-    this._clientInfoCache = new Map();
-    this._throttler = new Common.Throttler(500);
-  }
-
-  /**
-   * @param {string} label
-   * @param {string} initialValue
-   * @param {string} placeholder
-   * @param {function(string)} callback
-   */
-  _createSyncNotificationField(label, initialValue, placeholder, callback) {
-    const form =
-        this._wrapWidget(this._section.appendField(label)).createChild('form', 'service-worker-editor-with-button');
-    const editor = form.createChild('input', 'source-code service-worker-notification-editor');
-    const button = UI.createTextButton(label);
-    button.type = 'submit';
-    form.appendChild(button);
-
-    editor.value = initialValue;
-    editor.placeholder = placeholder;
-
-    form.addEventListener('submit', e => {
-      callback(editor.value || '');
-      e.consume(true);
-    });
-  }
-
-  _scheduleUpdate() {
-    if (Resources.ServiceWorkersView._noThrottle) {
-      this._update();
-      return;
-    }
-    this._throttler.schedule(this._update.bind(this));
-  }
-
-  /**
-   * @param {string} versionId
-   * @return {?SDK.Target}
-   */
-  _targetForVersionId(versionId) {
-    const version = this._manager.findVersion(versionId);
-    if (!version || !version.targetId)
-      return null;
-    return SDK.targetManager.targetById(version.targetId);
-  }
-
-  /**
-   * @param {!Element} versionsStack
-   * @param {string} icon
-   * @param {string} label
-   * @return {!Element}
-   */
-  _addVersion(versionsStack, icon, label) {
-    const installingEntry = versionsStack.createChild('div', 'service-worker-version');
-    installingEntry.createChild('div', icon);
-    installingEntry.createChild('span').textContent = label;
-    return installingEntry;
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerVersion} version
-   */
-  _updateClientsField(version) {
-    this._clientsField.removeChildren();
-    this._section.setFieldVisible(Common.UIString('Clients'), version.controlledClients.length);
-    for (const client of version.controlledClients) {
-      const clientLabelText = this._clientsField.createChild('div', 'service-worker-client');
-      if (this._clientInfoCache.has(client)) {
-        this._updateClientInfo(
-            clientLabelText, /** @type {!Protocol.Target.TargetInfo} */ (this._clientInfoCache.get(client)));
-      }
-      this._manager.target().targetAgent().getTargetInfo(client).then(this._onClientInfo.bind(this, clientLabelText));
-    }
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerVersion} version
-   */
-  _updateSourceField(version) {
-    this._sourceField.removeChildren();
-    const fileName = Common.ParsedURL.extractName(version.scriptURL);
-    const name = this._sourceField.createChild('div', 'report-field-value-filename');
-    name.appendChild(Components.Linkifier.linkifyURL(version.scriptURL, {text: fileName}));
-    if (this._registration.errors.length) {
-      const errorsLabel = UI.createLabel(String(this._registration.errors.length), 'smallicon-error');
-      errorsLabel.classList.add('link');
-      errorsLabel.addEventListener('click', () => Common.console.show());
-      name.appendChild(errorsLabel);
-    }
-    this._sourceField.createChild('div', 'report-field-value-subtitle').textContent =
-        Common.UIString('Received %s', new Date(version.scriptResponseTime * 1000).toLocaleString());
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _update() {
-    const fingerprint = this._registration.fingerprint();
-    if (fingerprint === this._fingerprint)
-      return Promise.resolve();
-    this._fingerprint = fingerprint;
-
-    this._toolbar.setEnabled(!this._registration.isDeleted);
-
-    const versions = this._registration.versionsByMode();
-    const scopeURL = Resources.ServiceWorkersView._displayScopeURL(this._registration.scopeURL);
-    const title = this._registration.isDeleted ? Common.UIString('%s - deleted', scopeURL) : scopeURL;
-    this._section.setTitle(title);
-
-    const active = versions.get(SDK.ServiceWorkerVersion.Modes.Active);
-    const waiting = versions.get(SDK.ServiceWorkerVersion.Modes.Waiting);
-    const installing = versions.get(SDK.ServiceWorkerVersion.Modes.Installing);
-    const redundant = versions.get(SDK.ServiceWorkerVersion.Modes.Redundant);
-
-    this._statusField.removeChildren();
-    const versionsStack = this._statusField.createChild('div', 'service-worker-version-stack');
-    versionsStack.createChild('div', 'service-worker-version-stack-bar');
-
-    if (active) {
-      this._updateSourceField(active);
-      const activeEntry = this._addVersion(
-          versionsStack, 'service-worker-active-circle',
-          Common.UIString('#%s activated and is %s', active.id, active.runningStatus));
-
-      if (active.isRunning() || active.isStarting()) {
-        createLink(activeEntry, Common.UIString('stop'), this._stopButtonClicked.bind(this, active.id));
-        if (!this._targetForVersionId(active.id))
-          createLink(activeEntry, Common.UIString('inspect'), this._inspectButtonClicked.bind(this, active.id));
-      } else if (active.isStartable()) {
-        createLink(activeEntry, Common.UIString('start'), this._startButtonClicked.bind(this));
-      }
-      this._updateClientsField(active);
-    } else if (redundant) {
-      this._updateSourceField(redundant);
-      this._addVersion(
-          versionsStack, 'service-worker-redundant-circle', Common.UIString('#%s is redundant', redundant.id));
-      this._updateClientsField(redundant);
-    }
-
-    if (waiting) {
-      const waitingEntry = this._addVersion(
-          versionsStack, 'service-worker-waiting-circle', Common.UIString('#%s waiting to activate', waiting.id));
-      createLink(waitingEntry, Common.UIString('skipWaiting'), this._skipButtonClicked.bind(this));
-      waitingEntry.createChild('div', 'service-worker-subtitle').textContent =
-          Common.UIString('Received %s', new Date(waiting.scriptResponseTime * 1000).toLocaleString());
-      if (!this._targetForVersionId(waiting.id) && (waiting.isRunning() || waiting.isStarting()))
-        createLink(waitingEntry, Common.UIString('inspect'), this._inspectButtonClicked.bind(this, waiting.id));
-    }
-    if (installing) {
-      const installingEntry = this._addVersion(
-          versionsStack, 'service-worker-installing-circle', Common.UIString('#%s installing', installing.id));
-      installingEntry.createChild('div', 'service-worker-subtitle').textContent =
-          Common.UIString('Received %s', new Date(installing.scriptResponseTime * 1000).toLocaleString());
-      if (!this._targetForVersionId(installing.id) && (installing.isRunning() || installing.isStarting()))
-        createLink(installingEntry, Common.UIString('inspect'), this._inspectButtonClicked.bind(this, installing.id));
-    }
-
-    /**
-     * @param {!Element} parent
-     * @param {string} title
-     * @param {function()} listener
-     * @return {!Element}
-     */
-    function createLink(parent, title, listener) {
-      const span = parent.createChild('span', 'link');
-      span.textContent = title;
-      span.addEventListener('click', listener, false);
-      return span;
-    }
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _unregisterButtonClicked(event) {
-    this._manager.deleteRegistration(this._registration.id);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _updateButtonClicked(event) {
-    this._manager.updateRegistration(this._registration.id);
-  }
-
-  /**
-   * @param {string} data
-   */
-  _push(data) {
-    this._pushNotificationDataSetting.set(data);
-    this._manager.deliverPushMessage(this._registration.id, data);
-  }
-
-  /**
-   * @param {string} tag
-   */
-  _sync(tag) {
-    this._syncTagNameSetting.set(tag);
-    this._manager.dispatchSyncEvent(this._registration.id, tag, true);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {?Protocol.Target.TargetInfo} targetInfo
-   */
-  _onClientInfo(element, targetInfo) {
-    if (!targetInfo)
-      return;
-    this._clientInfoCache.set(targetInfo.targetId, targetInfo);
-    this._updateClientInfo(element, targetInfo);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   */
-  _updateClientInfo(element, targetInfo) {
-    if (targetInfo.type !== 'page' && targetInfo.type === 'iframe') {
-      element.createTextChild(Common.UIString('Worker: %s', targetInfo.url));
-      return;
-    }
-    element.removeChildren();
-    element.createTextChild(targetInfo.url);
-    const focusLabel = element.createChild('label', 'link');
-    focusLabel.createTextChild('focus');
-    focusLabel.addEventListener('click', this._activateTarget.bind(this, targetInfo.targetId), true);
-  }
-
-  /**
-   * @param {string} targetId
-   */
-  _activateTarget(targetId) {
-    this._manager.target().targetAgent().activateTarget(targetId);
-  }
-
-  _startButtonClicked() {
-    this._manager.startWorker(this._registration.scopeURL);
-  }
-
-  _skipButtonClicked() {
-    this._manager.skipWaiting(this._registration.scopeURL);
-  }
-
-  /**
-   * @param {string} versionId
-   */
-  _stopButtonClicked(versionId) {
-    this._manager.stopWorker(versionId);
-  }
-
-  /**
-   * @param {string} versionId
-   */
-  _inspectButtonClicked(versionId) {
-    this._manager.inspectWorker(versionId);
-  }
-
-  /**
-   * @param {!Element} container
-   * @return {!Element}
-   */
-  _wrapWidget(container) {
-    const shadowRoot = UI.createShadowRootWithCoreStyles(container);
-    UI.appendStyle(shadowRoot, 'resources/serviceWorkersView.css');
-    const contentElement = createElement('div');
-    shadowRoot.appendChild(contentElement);
-    return contentElement;
-  }
-};
diff --git a/front_end/resources/StorageItemsView.js b/front_end/resources/StorageItemsView.js
deleted file mode 100644
index eae6414..0000000
--- a/front_end/resources/StorageItemsView.js
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Resources.StorageItemsView = class extends UI.VBox {
-  /**
-   * @param {string} title
-   * @param {string} filterName
-   */
-  constructor(title, filterName) {
-    super(false);
-    /** @type {?RegExp} */
-    this._filterRegex = null;
-
-    this._deleteAllButton = this._addButton(Common.UIString('Clear All'), 'largeicon-clear', this.deleteAllItems);
-    this._deleteSelectedButton =
-        this._addButton(Common.UIString('Delete Selected'), 'largeicon-delete', this.deleteSelectedItem);
-    this._refreshButton = this._addButton(Common.UIString('Refresh'), 'largeicon-refresh', this.refreshItems);
-
-    this._mainToolbar = new UI.Toolbar('top-resources-toolbar', this.element);
-
-    this._filterItem = new UI.ToolbarInput(Common.UIString('Filter'), 0.4);
-    this._filterItem.addEventListener(UI.ToolbarInput.Event.TextChanged, this._filterChanged, this);
-
-    const toolbarItems = [this._refreshButton, this._deleteAllButton, this._deleteSelectedButton, this._filterItem];
-    for (const item of toolbarItems)
-      this._mainToolbar.appendToolbarItem(item);
-
-    this.element.addEventListener('contextmenu', this._showContextMenu.bind(this), true);
-  }
-
-  /**
-   * @param {string} label
-   * @param {string} glyph
-   * @param {!Function} callback
-   * @return {!UI.ToolbarButton}
-   */
-  _addButton(label, glyph, callback) {
-    const button = new UI.ToolbarButton(label, glyph);
-    button.addEventListener(UI.ToolbarButton.Events.Click, callback, this);
-    return button;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _showContextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.defaultSection().appendItem(Common.UIString('Refresh'), this.refreshItems.bind(this));
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _filterChanged(event) {
-    const text = /** @type {?string} */ (event.data);
-    this._filterRegex = text ? new RegExp(text.escapeForRegExp(), 'i') : null;
-    this.refreshItems();
-  }
-
-  /**
-   * @param {!Array<?Object>} items
-   * @param {function(?Object): string} keyFunction
-   * @return {!Array<?Object>}
-   * @protected
-   */
-  filter(items, keyFunction) {
-    if (!this._filterRegex)
-      return items;
-    return items.filter(item => this._filterRegex.test(keyFunction(item)));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.refreshItems();
-  }
-
-  /**
-   * @param {boolean} enabled
-   * @protected
-   */
-  setCanDeleteAll(enabled) {
-    this._deleteAllButton.setEnabled(enabled);
-  }
-
-  /**
-   * @param {boolean} enabled
-   * @protected
-   */
-  setCanDeleteSelected(enabled) {
-    this._deleteSelectedButton.setEnabled(enabled);
-  }
-
-  /**
-   * @param {boolean} enabled
-   * @protected
-   */
-  setCanRefresh(enabled) {
-    this._refreshButton.setEnabled(enabled);
-  }
-
-  /**
-   * @param {boolean} enabled
-   * @protected
-   */
-  setCanFilter(enabled) {
-    this._filterItem.setEnabled(enabled);
-  }
-
-  deleteAllItems() {
-  }
-
-  deleteSelectedItem() {
-  }
-
-  refreshItems() {
-  }
-};
diff --git a/front_end/resources/appManifestView.css b/front_end/resources/appManifestView.css
deleted file mode 100644
index d9dcd73..0000000
--- a/front_end/resources/appManifestView.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
diff --git a/front_end/resources/clearStorageView.css b/front_end/resources/clearStorageView.css
deleted file mode 100644
index abbed68..0000000
--- a/front_end/resources/clearStorageView.css
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.report-row {
-    display: flex;
-    align-items: center;
-}
-
-.clear-storage-button .report-row {
-    margin: 0 0 0 20px;
-    display: flex;
-}
-
-.link {
-    margin-left: 10px;
-    display: none;
-}
-
-.report-row:hover .link {
-    display: inline;
-}
-
-.usage-breakdown-row {
-    min-width: fit-content;
-}
-
-.usage-breakdown-legend-row {
-    margin: 5px auto;
-}
-
-.usage-breakdown-legend-title {
-    display: inline-block;
-}
-
-.usage-breakdown-legend-value {
-    display: inline-block;
-    width: 70px;
-    text-align: right;
-}
-
-.usage-breakdown-legend-swatch {
-    display: inline-block;
-    width: 11px;
-    height: 11px;
-    margin: 0 6px;
-    position: relative;
-    top: 1px;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-}
diff --git a/front_end/resources/indexedDBViews.css b/front_end/resources/indexedDBViews.css
deleted file mode 100644
index 58de433..0000000
--- a/front_end/resources/indexedDBViews.css
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.indexed-db-database-view {
-    -webkit-user-select: text;
-    margin-top: 5px;
-}
-
-.indexed-db-data-view .data-view-toolbar {
-    position: relative;
-    background-color: #eee;
-    border-bottom: 1px solid #ccc;
-}
-
-.indexed-db-data-view .data-grid {
-    flex: auto;
-}
-
-.indexed-db-data-view .data-grid .data-container tr:nth-last-child(1) {
-    background-color: white;
-}
-
-.indexed-db-data-view .data-grid .data-container tr:nth-last-child(1) td {
-    border: 0;
-}
-
-.indexed-db-data-view .data-grid .data-container tr:nth-last-child(2) td {
-    border-bottom: 1px solid #aaa;
-}
-
-.indexed-db-data-view .data-grid:focus .data-container tr.selected {
-    background-color: #cdddf5;
-    color: inherit;
-}
-
-.indexed-db-data-view .section,
-.indexed-db-data-view .section > .header,
-.indexed-db-data-view .section > .header .title {
-    margin: 0;
-    min-height: inherit;
-    line-height: inherit;
-}
-
-.indexed-db-data-view .primitive-value {
-    padding-top: 1px;
-}
-
-.indexed-db-data-view .data-grid .data-container td .section .header .title {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.indexed-db-key-path {
-    color: rgb(196, 26, 22);
-    white-space: pre-wrap;
-    unicode-bidi: -webkit-isolate;
-}
-
-.source-code.indexed-db-key-path {
-    font-size: unset !important;
-}
-
-.resources-toolbar {
-    padding-right: 10px;
-}
diff --git a/front_end/resources/module.json b/front_end/resources/module.json
deleted file mode 100644
index a703461..0000000
--- a/front_end/resources/module.json
+++ /dev/null
@@ -1,61 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "resources",
-            "title": "Application",
-            "order": 70,
-            "className": "Resources.ResourcesPanel"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "SDK.Resource"
-            ],
-            "destination": "Application panel",
-            "className": "Resources.ResourcesPanel.ResourceRevealer"
-        }
-    ],
-    "dependencies": [
-        "source_frame",
-        "cookie_table",
-        "inline_editor",
-        "data_grid",
-        "components",
-        "object_ui",
-        "perf_ui",
-        "mobile_throttling",
-        "network",
-        "sources"
-    ],
-    "scripts": [
-        "ApplicationCacheModel.js",
-        "AppManifestView.js",
-        "ApplicationCacheItemsView.js",
-        "ClearStorageView.js",
-        "StorageItemsView.js",
-        "CookieItemsView.js",
-        "DatabaseModel.js",
-        "DOMStorageModel.js",
-        "DOMStorageItemsView.js",
-        "DatabaseQueryView.js",
-        "DatabaseTableView.js",
-        "IndexedDBModel.js",
-        "IndexedDBViews.js",
-        "ResourcesPanel.js",
-        "ApplicationPanelSidebar.js",
-        "ResourcesSection.js",
-        "ServiceWorkerCacheViews.js",
-        "ServiceWorkersView.js"
-    ],
-    "resources": [
-        "appManifestView.css",
-        "clearStorageView.css",
-        "indexedDBViews.css",
-        "resourcesPanel.css",
-        "resourcesSidebar.css",
-        "serviceWorkerCacheViews.css",
-        "serviceWorkersView.css"
-    ]
-}
diff --git a/front_end/resources/resourcesPanel.css b/front_end/resources/resourcesPanel.css
deleted file mode 100644
index 6349e00..0000000
--- a/front_end/resources/resourcesPanel.css
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.resources-toolbar {
-    border-top: 1px solid #ccc;
-    background-color: var(--toolbar-bg-color);
-}
-
-.top-resources-toolbar {
-    border-bottom: 1px solid #ccc;
-    background-color: var(--toolbar-bg-color);
-}
-
-li.selected .base-storage-tree-element-subtitle {
-    color: white;
-}
-
-.base-storage-tree-element-subtitle {
-    padding-left: 2px;
-    color: rgb(80, 80, 80);
-    text-shadow: none;
-}
-
-.resources.panel .status {
-    float: right;
-    height: 16px;
-    margin-top: 1px;
-    margin-left: 4px;
-    line-height: 1em;
-}
-
-.storage-view {
-    display: flex;
-    overflow: hidden;
-}
-
-.storage-view {
-    overflow: hidden;
-}
-
-.storage-view .data-grid:not(.inline) {
-    border: none;
-    flex: auto;
-}
-
-.storage-view .storage-table-error {
-    color: rgb(66%, 33%, 33%);
-    font-size: 24px;
-    font-weight: bold;
-    padding: 10px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.storage-view.query {
-    padding: 2px 0;
-    overflow-y: overlay;
-    overflow-x: hidden;
-}
-
-.storage-view .filter-bar {
-    border-top: none;
-    border-bottom: var(--divider-border);
-}
-
-.database-query-prompt-container {
-    position: relative;
-    padding: 1px 22px 1px 24px;
-}
-
-.database-query-prompt {
-    min-height: 16px;
-    white-space: pre-wrap;
-}
-
-.prompt-icon {
-    position: absolute;
-    display: block;
-    left: 7px;
-    top: 9px;
-    margin-top: -7px;
-    -webkit-user-select: none;
-}
-
-.database-query-prompt-container .prompt-icon {
-    top: 10px;
-}
-
-.database-user-query {
-    position: relative;
-    border-bottom: 1px solid rgb(245, 245, 245);
-    padding: 1px 22px 1px 24px;
-    min-height: 16px;
-    flex-shrink: 0;
-}
-
-.database-query-text {
-    color: rgb(0, 128, 255);
-    -webkit-user-select: text;
-}
-
-.database-query-result {
-    position: relative;
-    padding: 1px 22px 1px 24px;
-    min-height: 16px;
-    margin-left: -24px;
-    padding-right: 0;
-}
-
-.database-query-result.error {
-    color: red;
-    -webkit-user-select: text;
-}
-
-.resource-sidebar-tree-item .icon {
-    content: url(Images/resourcePlainIconSmall.png);
-}
-
-.resource-sidebar-tree-item.resources-type-image .icon {
-    position: relative;
-    background-image: url(Images/resourcePlainIcon.png);
-    background-repeat: no-repeat;
-    content: "";
-}
-
-.resources-type-image .image-resource-icon-preview {
-    position: absolute;
-    margin: auto;
-    min-width: 1px;
-    min-height: 1px;
-    top: 2px;
-    bottom: 1px;
-    left: 3px;
-    right: 3px;
-    max-width: 8px;
-    max-height: 11px;
-    overflow: hidden;
-}
-
-.resources-sidebar {
-    padding: 0;
-}
diff --git a/front_end/resources/resourcesSidebar.css b/front_end/resources/resourcesSidebar.css
deleted file mode 100644
index d1d413a..0000000
--- a/front_end/resources/resourcesSidebar.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tree-outline {
-    padding-left: 0;
-    color: rgb(90, 90, 90);
-}
-
-.tree-outline > ol {
-    padding-bottom: 10px;
-}
-
-.tree-outline li {
-    min-height: 20px;
-}
-
-li.storage-group-list-item {
-    padding: 10px 8px 6px 8px;
-}
-
-li.storage-group-list-item:not(:first-child) {
-    border-top: 1px solid rgb(230, 230, 230);
-}
-
-li.storage-group-list-item::before {
-    display: none;
-}
-
-.navigator-tree-item {
-    margin: -3px -7px -3px -7px;
-}
-
-.navigator-file-tree-item {
-    background: linear-gradient(45deg, hsl(0, 0%, 50%), hsl(0, 0%, 70%));
-}
-
-.navigator-folder-tree-item {
-    background: linear-gradient(45deg, hsl(210, 82%, 65%), hsl(210, 82%, 80%));
-}
-
-.navigator-frame-tree-item {
-    background-color: #5a5a5a;
-}
-
-.navigator-script-tree-item {
-    background: linear-gradient(45deg, hsl(48, 70%, 50%), hsl(48, 70%, 70%));
-}
-
-.navigator-stylesheet-tree-item {
-    background: linear-gradient(45deg, hsl(256, 50%, 50%), hsl(256, 50%, 70%));
-}
-
-.navigator-image-tree-item,
-.navigator-font-tree-item {
-    background: linear-gradient(45deg, hsl(109, 33%, 50%), hsl(109, 33%, 70%));
-}
-
-.resource-tree-item {
-    background: rgba(90, 90, 90, .7);
-}
diff --git a/front_end/resources/serviceWorkerCacheViews.css b/front_end/resources/serviceWorkerCacheViews.css
deleted file mode 100644
index 6f4eeda..0000000
--- a/front_end/resources/serviceWorkerCacheViews.css
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.service-worker-cache-data-view .data-view-toolbar {
-    position: relative;
-    background-color: #eee;
-    border-bottom: 1px solid #ccc;
-    padding-right: 10px;
-}
-
-.service-worker-cache-data-view .data-view-toolbar .key-input {
-    margin: auto 0;
-    width: 200px;
-}
-
-.service-worker-cache-data-view .data-grid {
-    flex: auto;
-}
-
-.service-worker-cache-data-view .data-grid .data-container tr:nth-last-child(1) td {
-    border: 0;
-}
-
-.service-worker-cache-data-view .data-grid .data-container tr:nth-last-child(2) td {
-    border-bottom: 1px solid #aaa;
-}
-
-.service-worker-cache-data-view .data-grid .data-container tr.selected {
-    background-color: rgb(212, 212, 212);
-    color: inherit;
-}
-
-.service-worker-cache-data-view .data-grid:focus .data-container tr.selected {
-    background-color: var(--selection-bg-color);
-    color: white;
-}
-
-.service-worker-cache-data-view .section,
-.service-worker-cache-data-view .section > .header,
-.service-worker-cache-data-view .section > .header .title {
-    margin: 0;
-    min-height: inherit;
-    line-height: inherit;
-}
-
-.service-worker-cache-data-view .primitive-value {
-    padding-top: 1px;
-}
-
-.service-worker-cache-data-view .data-grid .data-container td .section .header .title {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.cache-preview-panel-resizer {
-    background-color: #eee;
-    height: 4px;
-    border-bottom: 1px solid rgb(64%, 64%, 64%);
-}
diff --git a/front_end/resources/serviceWorkersView.css b/front_end/resources/serviceWorkersView.css
deleted file mode 100644
index b18d04c..0000000
--- a/front_end/resources/serviceWorkersView.css
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.service-worker-error-stack {
-    max-height: 200px;
-    overflow: auto;
-    display: flex;
-    flex-direction: column;
-    border: 1px solid #ccc;
-    background-color: #fff0f0;
-    color: red;
-    line-height: 18px;
-    margin: 10px 2px 0 -14px;
-    white-space: initial;
-}
-
-.service-worker-error-stack > div {
-    flex: none;
-    padding: 3px 4px;
-}
-
-.service-worker-error-stack > div:not(:last-child) {
-    border-bottom: 1px solid #ffd7d7;
-}
-
-.service-worker-error-stack label {
-    flex: auto;
-}
-
-.service-worker-error-stack .devtools-link {
-    float: right;
-    color: rgb(33%, 33%, 33%);
-    cursor: pointer;
-}
-
-.service-worker-version-stack {
-    position: relative;
-}
-
-.service-worker-version-stack-bar {
-    position: absolute;
-    top: 10px;
-    bottom: 20px;
-    left: 4px;
-    content: "";
-    border-left: 1px solid #888;
-    z-index: 0;
-}
-
-.service-worker-version:not(:last-child) {
-    margin-bottom: 7px;
-}
-
-.service-worker-active-circle,
-.service-worker-redundant-circle,
-.service-worker-waiting-circle,
-.service-worker-installing-circle {
-    position: relative;
-    display: inline-block;
-    width: 10px;
-    height: 10px;
-    z-index: 10;
-    margin-right: 5px;
-    border-radius: 50%;
-    border: 1px solid #555;
-}
-
-.service-worker-active-circle {
-    background-color: #50B04F;
-}
-.service-worker-waiting-circle {
-    background-color: #F38E24;
-
-}
-.service-worker-installing-circle {
-    background-color: white;
-}
-
-.service-worker-redundant-circle {
-    background-color: gray;
-}
-
-.service-worker-subtitle {
-    padding-left: 14px;
-    line-height: 14px;
-    color: #888;
-}
-
-.link {
-    margin-left: 10px;
-}
-
-.service-worker-editor-with-button {
-    align-items: baseline;
-    display: flex;
-}
-
-.service-worker-notification-editor {
-    border: solid 1px #d8d8d8;
-    display: flex;
-    flex: auto;
-    margin-right: 4px;
-    max-width: 400px;
-    min-width: 80px;
-}
-
-.service-worker-notification-editor.source-code {
-    /** Simulate CodeMirror that is shown above */
-    padding: 4px;
-}
-
-.service-worker-list {
-    background-color: #f9f9f9;
-    overflow: auto;
-}
-
-.service-workers-this-origin {
-    flex-shrink: 0;
-    flex-grow: 0;
-}
-
-.service-worker-has-current .service-workers-other-origin {
-    margin-top: 16px;
-    border-top: 1px solid rgb(230, 230, 230)
-}
-
-.service-worker-list-empty .service-workers-other-origin {
-    display: none;
-}
-
-.service-workers-this-origin,
-.service-worker-filter,
-.service-workers-other-origin {
-    min-width: 400px;
-}
-
-.service-worker-filter {
-    padding: 16px 20px 12px 12px;
-    flex-grow: 0;
-    flex-shrink: 0;
-    background-color: white;
-    border-bottom: solid 1px rgb(230, 230, 230);
-}
-
-.service-worker-filter-label {
-    cursor: pointer;
-    margin-left: 4px;
-}
-
-.service-worker-filter-label::before {
-    -webkit-user-select: none;
-    -webkit-mask-image: url(Images/treeoutlineTriangles.png);
-    -webkit-mask-size: 32px 24px;
-    content: "aa";
-    color: transparent;
-    background-color: rgb(110, 110, 110);
-    text-shadow: none;
-    height: 12px;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-.service-worker-filter-label::before {
-    -webkit-mask-image: url(Images/treeoutlineTriangles_2x.png);
-}
-} /* media */
-
-.service-worker-filter[aria-checked="true"] .service-worker-filter-label::before {
-    -webkit-mask-position: -16px 0;
-}
-
-.service-worker-filter-toolbar {
-    margin: 8px 10px 0 12px;
-    max-width: 530px;
-}
-
-.service-worker-filter-collapsed .service-worker-filter-toolbar {
-    display: none;
-}
diff --git a/front_end/screencast/InputModel.js b/front_end/screencast/InputModel.js
deleted file mode 100644
index 3006f39..0000000
--- a/front_end/screencast/InputModel.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Screencast.InputModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._inputAgent = target.inputAgent();
-    /** @type {?number} */
-    this._activeTouchOffsetTop = null;
-    this._activeTouchParams = null;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  emitKeyEvent(event) {
-    let type;
-    switch (event.type) {
-      case 'keydown':
-        type = 'keyDown';
-        break;
-      case 'keyup':
-        type = 'keyUp';
-        break;
-      case 'keypress':
-        type = 'char';
-        break;
-      default:
-        return;
-    }
-
-    const text = event.type === 'keypress' ? String.fromCharCode(event.charCode) : undefined;
-    this._inputAgent.invoke_dispatchKeyEvent({
-      type: type,
-      modifiers: this._modifiersForEvent(event),
-      text: text,
-      unmodifiedText: text ? text.toLowerCase() : undefined,
-      keyIdentifier: event.keyIdentifier,
-      code: event.code,
-      key: event.key,
-      windowsVirtualKeyCode: event.keyCode,
-      nativeVirtualKeyCode: event.keyCode,
-      autoRepeat: false,
-      isKeypad: false,
-      isSystemKey: false
-    });
-  }
-
-  /**
-   * @param {!Event} event
-   * @param {number} offsetTop
-   * @param {number} zoom
-   */
-  emitTouchFromMouseEvent(event, offsetTop, zoom) {
-    const buttons = {0: 'none', 1: 'left', 2: 'middle', 3: 'right'};
-    const types = {
-      'mousedown': 'mousePressed',
-      'mouseup': 'mouseReleased',
-      'mousemove': 'mouseMoved',
-      'mousewheel': 'mouseWheel'
-    };
-    if (!(event.type in types) || !(event.which in buttons))
-      return;
-    if (event.type !== 'mousewheel' && buttons[event.which] === 'none')
-      return;
-
-    if (event.type === 'mousedown' || this._activeTouchOffsetTop === null)
-      this._activeTouchOffsetTop = offsetTop;
-
-    const x = Math.round(event.offsetX / zoom);
-    let y = Math.round(event.offsetY / zoom);
-    y = Math.round(y - this._activeTouchOffsetTop);
-    const params = {
-      type: types[event.type],
-      x: x,
-      y: y,
-      modifiers: this._modifiersForEvent(event),
-      button: buttons[event.which],
-      clickCount: 0
-    };
-    if (event.type === 'mousewheel') {
-      params.deltaX = event.wheelDeltaX / zoom;
-      params.deltaY = event.wheelDeltaY / zoom;
-    } else {
-      this._activeTouchParams = params;
-    }
-    if (event.type === 'mouseup')
-      this._activeTouchOffsetTop = null;
-    this._inputAgent.invoke_emulateTouchFromMouseEvent(params);
-  }
-
-  cancelTouch() {
-    if (this._activeTouchOffsetTop !== null) {
-      const params = this._activeTouchParams;
-      this._activeTouchParams = null;
-      params.type = 'mouseReleased';
-      this._inputAgent.invoke_emulateTouchFromMouseEvent(params);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {number}
-   */
-  _modifiersForEvent(event) {
-    return (event.altKey ? 1 : 0) | (event.ctrlKey ? 2 : 0) | (event.metaKey ? 4 : 0) | (event.shiftKey ? 8 : 0);
-  }
-};
-
-SDK.SDKModel.register(Screencast.InputModel, SDK.Target.Capability.Input, false);
diff --git a/front_end/screencast/ScreencastApp.js b/front_end/screencast/ScreencastApp.js
deleted file mode 100644
index c65f7fe..0000000
--- a/front_end/screencast/ScreencastApp.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Common.App}
- * @implements {SDK.SDKModelObserver<!SDK.ScreenCaptureModel>}
- * @unrestricted
- */
-Screencast.ScreencastApp = class {
-  constructor() {
-    this._enabledSetting = Common.settings.createSetting('screencastEnabled', true);
-    this._toggleButton = new UI.ToolbarToggle(Common.UIString('Toggle screencast'), 'largeicon-phone');
-    this._toggleButton.setToggled(this._enabledSetting.get());
-    this._toggleButton.setEnabled(false);
-    this._toggleButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleButtonClicked, this);
-    SDK.targetManager.observeModels(SDK.ScreenCaptureModel, this);
-  }
-
-  /**
-   * @return {!Screencast.ScreencastApp}
-   */
-  static _instance() {
-    if (!Screencast.ScreencastApp._appInstance)
-      Screencast.ScreencastApp._appInstance = new Screencast.ScreencastApp();
-    return Screencast.ScreencastApp._appInstance;
-  }
-
-  /**
-   * @override
-   * @param {!Document} document
-   */
-  presentUI(document) {
-    const rootView = new UI.RootView();
-
-    this._rootSplitWidget = new UI.SplitWidget(false, true, 'InspectorView.screencastSplitViewState', 300, 300);
-    this._rootSplitWidget.setVertical(true);
-    this._rootSplitWidget.setSecondIsSidebar(true);
-    this._rootSplitWidget.show(rootView.element);
-    this._rootSplitWidget.hideMain();
-
-    this._rootSplitWidget.setSidebarWidget(UI.inspectorView);
-    rootView.attachToDocument(document);
-    rootView.focus();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ScreenCaptureModel} screenCaptureModel
-   */
-  modelAdded(screenCaptureModel) {
-    if (this._screenCaptureModel)
-      return;
-    this._screenCaptureModel = screenCaptureModel;
-    this._toggleButton.setEnabled(true);
-    this._screencastView = new Screencast.ScreencastView(screenCaptureModel);
-    this._rootSplitWidget.setMainWidget(this._screencastView);
-    this._screencastView.initialize();
-    this._onScreencastEnabledChanged();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.ScreenCaptureModel} screenCaptureModel
-   */
-  modelRemoved(screenCaptureModel) {
-    if (this._screenCaptureModel !== screenCaptureModel)
-      return;
-    delete this._screenCaptureModel;
-    this._toggleButton.setEnabled(false);
-    this._screencastView.detach();
-    delete this._screencastView;
-    this._onScreencastEnabledChanged();
-  }
-
-  _toggleButtonClicked() {
-    const enabled = !this._toggleButton.toggled();
-    this._enabledSetting.set(enabled);
-    this._onScreencastEnabledChanged();
-  }
-
-  _onScreencastEnabledChanged() {
-    if (!this._rootSplitWidget)
-      return;
-    const enabled = this._enabledSetting.get() && this._screencastView;
-    this._toggleButton.setToggled(enabled);
-    if (enabled)
-      this._rootSplitWidget.showBoth();
-    else
-      this._rootSplitWidget.hideMain();
-  }
-};
-
-/** @type {!Screencast.ScreencastApp} */
-Screencast.ScreencastApp._appInstance;
-
-
-/**
- * @implements {UI.ToolbarItem.Provider}
- * @unrestricted
- */
-Screencast.ScreencastApp.ToolbarButtonProvider = class {
-  /**
-   * @override
-   * @return {?UI.ToolbarItem}
-   */
-  item() {
-    return Screencast.ScreencastApp._instance()._toggleButton;
-  }
-};
-
-/**
- * @implements {Common.AppProvider}
- * @unrestricted
- */
-Screencast.ScreencastAppProvider = class {
-  /**
-   * @override
-   * @return {!Common.App}
-   */
-  createApp() {
-    return Screencast.ScreencastApp._instance();
-  }
-};
diff --git a/front_end/screencast/ScreencastView.js b/front_end/screencast/ScreencastView.js
deleted file mode 100644
index 28ae541..0000000
--- a/front_end/screencast/ScreencastView.js
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {SDK.OverlayModel.Highlighter}
- * @unrestricted
- */
-Screencast.ScreencastView = class extends UI.VBox {
-  /**
-   * @param {!SDK.ScreenCaptureModel} screenCaptureModel
-   */
-  constructor(screenCaptureModel) {
-    super();
-    this._screenCaptureModel = screenCaptureModel;
-    this._domModel = screenCaptureModel.target().model(SDK.DOMModel);
-    this._overlayModel = screenCaptureModel.target().model(SDK.OverlayModel);
-    this._resourceTreeModel = screenCaptureModel.target().model(SDK.ResourceTreeModel);
-    this._networkManager = screenCaptureModel.target().model(SDK.NetworkManager);
-    this._inputModel = screenCaptureModel.target().model(Screencast.InputModel);
-
-    this.setMinimumSize(150, 150);
-    this.registerRequiredCSS('screencast/screencastView.css');
-  }
-
-  initialize() {
-    this.element.classList.add('screencast');
-
-    this._createNavigationBar();
-
-    this._viewportElement = this.element.createChild('div', 'screencast-viewport hidden');
-    this._canvasContainerElement = this._viewportElement.createChild('div', 'screencast-canvas-container');
-    this._glassPaneElement = this._canvasContainerElement.createChild('div', 'screencast-glasspane fill hidden');
-
-    this._canvasElement = this._canvasContainerElement.createChild('canvas');
-    this._canvasElement.tabIndex = 1;
-    this._canvasElement.addEventListener('mousedown', this._handleMouseEvent.bind(this), false);
-    this._canvasElement.addEventListener('mouseup', this._handleMouseEvent.bind(this), false);
-    this._canvasElement.addEventListener('mousemove', this._handleMouseEvent.bind(this), false);
-    this._canvasElement.addEventListener('mousewheel', this._handleMouseEvent.bind(this), false);
-    this._canvasElement.addEventListener('click', this._handleMouseEvent.bind(this), false);
-    this._canvasElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
-    this._canvasElement.addEventListener('keydown', this._handleKeyEvent.bind(this), false);
-    this._canvasElement.addEventListener('keyup', this._handleKeyEvent.bind(this), false);
-    this._canvasElement.addEventListener('keypress', this._handleKeyEvent.bind(this), false);
-    this._canvasElement.addEventListener('blur', this._handleBlurEvent.bind(this), false);
-
-    this._titleElement = this._canvasContainerElement.createChild('div', 'screencast-element-title monospace hidden');
-    this._tagNameElement = this._titleElement.createChild('span', 'screencast-tag-name');
-    this._nodeIdElement = this._titleElement.createChild('span', 'screencast-node-id');
-    this._classNameElement = this._titleElement.createChild('span', 'screencast-class-name');
-    this._titleElement.createTextChild(' ');
-    this._nodeWidthElement = this._titleElement.createChild('span');
-    this._titleElement.createChild('span', 'screencast-px').textContent = 'px';
-    this._titleElement.createTextChild(' \u00D7 ');
-    this._nodeHeightElement = this._titleElement.createChild('span');
-    this._titleElement.createChild('span', 'screencast-px').textContent = 'px';
-    this._titleElement.style.top = '0';
-    this._titleElement.style.left = '0';
-
-    this._imageElement = new Image();
-    this._isCasting = false;
-    this._context = this._canvasElement.getContext('2d');
-    this._checkerboardPattern = this._createCheckerboardPattern(this._context);
-
-    this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
-    this._shortcuts[UI.KeyboardShortcut.makeKey('l', UI.KeyboardShortcut.Modifiers.Ctrl)] =
-        this._focusNavigationBar.bind(this);
-
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChange, this);
-    this._updateGlasspane();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._startCasting();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._stopCasting();
-  }
-
-  _startCasting() {
-    if (SDK.targetManager.allTargetsSuspended())
-      return;
-    if (this._isCasting)
-      return;
-    this._isCasting = true;
-
-    const maxImageDimension = 2048;
-    const dimensions = this._viewportDimensions();
-    if (dimensions.width < 0 || dimensions.height < 0) {
-      this._isCasting = false;
-      return;
-    }
-    dimensions.width *= window.devicePixelRatio;
-    dimensions.height *= window.devicePixelRatio;
-    // Note: startScreencast width and height are expected to be integers so must be floored.
-    this._screenCaptureModel.startScreencast(
-        'jpeg', 80, Math.floor(Math.min(maxImageDimension, dimensions.width)),
-        Math.floor(Math.min(maxImageDimension, dimensions.height)), undefined, this._screencastFrame.bind(this),
-        this._screencastVisibilityChanged.bind(this));
-    for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-      emulationModel.overrideEmulateTouch(true);
-    if (this._overlayModel)
-      this._overlayModel.setHighlighter(this);
-  }
-
-  _stopCasting() {
-    if (!this._isCasting)
-      return;
-    this._isCasting = false;
-    this._screenCaptureModel.stopScreencast();
-    for (const emulationModel of SDK.targetManager.models(SDK.EmulationModel))
-      emulationModel.overrideEmulateTouch(false);
-    if (this._overlayModel)
-      this._overlayModel.setHighlighter(null);
-  }
-
-  /**
-   * @param {string} base64Data
-   * @param {!Protocol.Page.ScreencastFrameMetadata} metadata
-   */
-  _screencastFrame(base64Data, metadata) {
-    this._imageElement.onload = () => {
-      this._pageScaleFactor = metadata.pageScaleFactor;
-      this._screenOffsetTop = metadata.offsetTop;
-      this._scrollOffsetX = metadata.scrollOffsetX;
-      this._scrollOffsetY = metadata.scrollOffsetY;
-
-      const deviceSizeRatio = metadata.deviceHeight / metadata.deviceWidth;
-      const dimensionsCSS = this._viewportDimensions();
-
-      this._imageZoom = Math.min(
-          dimensionsCSS.width / this._imageElement.naturalWidth,
-          dimensionsCSS.height / (this._imageElement.naturalWidth * deviceSizeRatio));
-      this._viewportElement.classList.remove('hidden');
-      const bordersSize = Screencast.ScreencastView._bordersSize;
-      if (this._imageZoom < 1.01 / window.devicePixelRatio)
-        this._imageZoom = 1 / window.devicePixelRatio;
-      this._screenZoom = this._imageElement.naturalWidth * this._imageZoom / metadata.deviceWidth;
-      this._viewportElement.style.width = metadata.deviceWidth * this._screenZoom + bordersSize + 'px';
-      this._viewportElement.style.height = metadata.deviceHeight * this._screenZoom + bordersSize + 'px';
-
-      this.highlightDOMNode(this._highlightNode, this._highlightConfig);
-    };
-    this._imageElement.src = 'data:image/jpg;base64,' + base64Data;
-  }
-
-  _isGlassPaneActive() {
-    return !this._glassPaneElement.classList.contains('hidden');
-  }
-
-  /**
-   * @param {boolean} visible
-   */
-  _screencastVisibilityChanged(visible) {
-    this._targetInactive = !visible;
-    this._updateGlasspane();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onSuspendStateChange(event) {
-    if (SDK.targetManager.allTargetsSuspended())
-      this._stopCasting();
-    else
-      this._startCasting();
-    this._updateGlasspane();
-  }
-
-  _updateGlasspane() {
-    if (this._targetInactive) {
-      this._glassPaneElement.textContent = Common.UIString('The tab is inactive');
-      this._glassPaneElement.classList.remove('hidden');
-    } else if (SDK.targetManager.allTargetsSuspended()) {
-      this._glassPaneElement.textContent = Common.UIString('Profiling in progress');
-      this._glassPaneElement.classList.remove('hidden');
-    } else {
-      this._glassPaneElement.classList.add('hidden');
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  async _handleMouseEvent(event) {
-    if (this._isGlassPaneActive()) {
-      event.consume();
-      return;
-    }
-
-    if (!this._pageScaleFactor || !this._domModel)
-      return;
-
-    if (!this._inspectModeConfig || event.type === 'mousewheel') {
-      if (this._inputModel)
-        this._inputModel.emitTouchFromMouseEvent(event, this._screenOffsetTop, this._screenZoom);
-      event.preventDefault();
-      if (event.type === 'mousedown')
-        this._canvasElement.focus();
-      return;
-    }
-
-    const position = this._convertIntoScreenSpace(event);
-
-    const node = await this._domModel.nodeForLocation(
-        Math.floor(position.x / this._pageScaleFactor + this._scrollOffsetX),
-        Math.floor(position.y / this._pageScaleFactor + this._scrollOffsetY),
-        Common.moduleSetting('showUAShadowDOM').get());
-
-    if (!node)
-      return;
-    if (event.type === 'mousemove') {
-      this.highlightDOMNode(node, this._inspectModeConfig);
-      this._domModel.overlayModel().nodeHighlightRequested(node.id);
-    } else if (event.type === 'click') {
-      Common.Revealer.reveal(node);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleKeyEvent(event) {
-    if (this._isGlassPaneActive()) {
-      event.consume();
-      return;
-    }
-
-    const shortcutKey = UI.KeyboardShortcut.makeKeyFromEvent(/** @type {!KeyboardEvent} */ (event));
-    const handler = this._shortcuts[shortcutKey];
-    if (handler && handler(event)) {
-      event.consume();
-      return;
-    }
-
-    if (this._inputModel)
-      this._inputModel.emitKeyEvent(event);
-    event.consume();
-    this._canvasElement.focus();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    event.consume(true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleBlurEvent(event) {
-    if (this._inputModel)
-      this._inputModel.cancelTouch();
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {!{x: number, y: number}}
-   */
-  _convertIntoScreenSpace(event) {
-    const position = {};
-    position.x = Math.round(event.offsetX / this._screenZoom);
-    position.y = Math.round(event.offsetY / this._screenZoom - this._screenOffsetTop);
-    return position;
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._deferredCasting) {
-      clearTimeout(this._deferredCasting);
-      delete this._deferredCasting;
-    }
-
-    this._stopCasting();
-    this._deferredCasting = setTimeout(this._startCasting.bind(this), 100);
-  }
-
-  /**
-   * @override
-   * @param {?SDK.DOMNode} node
-   * @param {?Protocol.Overlay.HighlightConfig} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(node, config, backendNodeId, objectId) {
-    this._highlightNode = node;
-    this._highlightConfig = config;
-    if (!node) {
-      this._model = null;
-      this._config = null;
-      this._node = null;
-      this._titleElement.classList.add('hidden');
-      this._repaint();
-      return;
-    }
-
-    this._node = node;
-    node.boxModel().then(model => {
-      if (!model || !this._pageScaleFactor) {
-        this._repaint();
-        return;
-      }
-      this._model = this._scaleModel(model);
-      this._config = config;
-      this._repaint();
-    });
-  }
-
-  /**
-   * @param {!Protocol.DOM.BoxModel} model
-   * @return {!Protocol.DOM.BoxModel}
-   */
-  _scaleModel(model) {
-    /**
-     * @param {!Protocol.DOM.Quad} quad
-     * @this {Screencast.ScreencastView}
-     */
-    function scaleQuad(quad) {
-      for (let i = 0; i < quad.length; i += 2) {
-        quad[i] = quad[i] * this._pageScaleFactor * this._screenZoom;
-        quad[i + 1] = (quad[i + 1] * this._pageScaleFactor + this._screenOffsetTop) * this._screenZoom;
-      }
-    }
-
-    scaleQuad.call(this, model.content);
-    scaleQuad.call(this, model.padding);
-    scaleQuad.call(this, model.border);
-    scaleQuad.call(this, model.margin);
-    return model;
-  }
-
-  _repaint() {
-    const model = this._model;
-    const config = this._config;
-
-    const canvasWidth = this._canvasElement.getBoundingClientRect().width;
-    const canvasHeight = this._canvasElement.getBoundingClientRect().height;
-    this._canvasElement.width = window.devicePixelRatio * canvasWidth;
-    this._canvasElement.height = window.devicePixelRatio * canvasHeight;
-
-    this._context.save();
-    this._context.scale(window.devicePixelRatio, window.devicePixelRatio);
-
-    // Paint top and bottom gutter.
-    this._context.save();
-    this._context.fillStyle = this._checkerboardPattern;
-    this._context.fillRect(0, 0, canvasWidth, this._screenOffsetTop * this._screenZoom);
-    this._context.fillRect(
-        0, this._screenOffsetTop * this._screenZoom + this._imageElement.naturalHeight * this._imageZoom, canvasWidth,
-        canvasHeight);
-    this._context.restore();
-
-    if (model && config) {
-      this._context.save();
-      const transparentColor = 'rgba(0, 0, 0, 0)';
-      const quads = [];
-      if (model.content && config.contentColor !== transparentColor)
-        quads.push({quad: model.content, color: config.contentColor});
-      if (model.padding && config.paddingColor !== transparentColor)
-        quads.push({quad: model.padding, color: config.paddingColor});
-      if (model.border && config.borderColor !== transparentColor)
-        quads.push({quad: model.border, color: config.borderColor});
-      if (model.margin && config.marginColor !== transparentColor)
-        quads.push({quad: model.margin, color: config.marginColor});
-
-      for (let i = quads.length - 1; i > 0; --i)
-        this._drawOutlinedQuadWithClip(quads[i].quad, quads[i - 1].quad, quads[i].color);
-      if (quads.length > 0)
-        this._drawOutlinedQuad(quads[0].quad, quads[0].color);
-      this._context.restore();
-
-      this._drawElementTitle();
-
-      this._context.globalCompositeOperation = 'destination-over';
-    }
-
-    this._context.drawImage(
-        this._imageElement, 0, this._screenOffsetTop * this._screenZoom,
-        this._imageElement.naturalWidth * this._imageZoom, this._imageElement.naturalHeight * this._imageZoom);
-    this._context.restore();
-  }
-
-  /**
-   * @param {!Protocol.DOM.RGBA} color
-   * @return {string}
-   */
-  _cssColor(color) {
-    if (!color)
-      return 'transparent';
-    return Common.Color.fromRGBA([color.r, color.g, color.b, color.a]).asString(Common.Color.Format.RGBA) || '';
-  }
-
-  /**
-   * @param {!Protocol.DOM.Quad} quad
-   * @return {!CanvasRenderingContext2D}
-   */
-  _quadToPath(quad) {
-    this._context.beginPath();
-    this._context.moveTo(quad[0], quad[1]);
-    this._context.lineTo(quad[2], quad[3]);
-    this._context.lineTo(quad[4], quad[5]);
-    this._context.lineTo(quad[6], quad[7]);
-    this._context.closePath();
-    return this._context;
-  }
-
-  /**
-   * @param {!Protocol.DOM.Quad} quad
-   * @param {!Protocol.DOM.RGBA} fillColor
-   */
-  _drawOutlinedQuad(quad, fillColor) {
-    this._context.save();
-    this._context.lineWidth = 2;
-    this._quadToPath(quad).clip();
-    this._context.fillStyle = this._cssColor(fillColor);
-    this._context.fill();
-    this._context.restore();
-  }
-
-  /**
-   * @param {!Protocol.DOM.Quad} quad
-   * @param {!Protocol.DOM.Quad} clipQuad
-   * @param {!Protocol.DOM.RGBA} fillColor
-   */
-  _drawOutlinedQuadWithClip(quad, clipQuad, fillColor) {
-    this._context.fillStyle = this._cssColor(fillColor);
-    this._context.save();
-    this._context.lineWidth = 0;
-    this._quadToPath(quad).fill();
-    this._context.globalCompositeOperation = 'destination-out';
-    this._context.fillStyle = 'red';
-    this._quadToPath(clipQuad).fill();
-    this._context.restore();
-  }
-
-  _drawElementTitle() {
-    if (!this._node)
-      return;
-
-    const canvasWidth = this._canvasElement.getBoundingClientRect().width;
-    const canvasHeight = this._canvasElement.getBoundingClientRect().height;
-
-    const lowerCaseName = this._node.localName() || this._node.nodeName().toLowerCase();
-    this._tagNameElement.textContent = lowerCaseName;
-    this._nodeIdElement.textContent = this._node.getAttribute('id') ? '#' + this._node.getAttribute('id') : '';
-    this._nodeIdElement.textContent = this._node.getAttribute('id') ? '#' + this._node.getAttribute('id') : '';
-    let className = this._node.getAttribute('class');
-    if (className && className.length > 50)
-      className = className.substring(0, 50) + '\u2026';
-    this._classNameElement.textContent = className || '';
-    this._nodeWidthElement.textContent = this._model.width;
-    this._nodeHeightElement.textContent = this._model.height;
-
-    this._titleElement.classList.remove('hidden');
-    const titleWidth = this._titleElement.offsetWidth + 6;
-    const titleHeight = this._titleElement.offsetHeight + 4;
-
-    const anchorTop = this._model.margin[1];
-    const anchorBottom = this._model.margin[7];
-
-    const arrowHeight = 7;
-    let renderArrowUp = false;
-    let renderArrowDown = false;
-
-    let boxX = Math.max(2, this._model.margin[0]);
-    if (boxX + titleWidth > canvasWidth)
-      boxX = canvasWidth - titleWidth - 2;
-
-    let boxY;
-    if (anchorTop > canvasHeight) {
-      boxY = canvasHeight - titleHeight - arrowHeight;
-      renderArrowDown = true;
-    } else if (anchorBottom < 0) {
-      boxY = arrowHeight;
-      renderArrowUp = true;
-    } else if (anchorBottom + titleHeight + arrowHeight < canvasHeight) {
-      boxY = anchorBottom + arrowHeight - 4;
-      renderArrowUp = true;
-    } else if (anchorTop - titleHeight - arrowHeight > 0) {
-      boxY = anchorTop - titleHeight - arrowHeight + 3;
-      renderArrowDown = true;
-    } else {
-      boxY = arrowHeight;
-    }
-
-    this._context.save();
-    this._context.translate(0.5, 0.5);
-    this._context.beginPath();
-    this._context.moveTo(boxX, boxY);
-    if (renderArrowUp) {
-      this._context.lineTo(boxX + 2 * arrowHeight, boxY);
-      this._context.lineTo(boxX + 3 * arrowHeight, boxY - arrowHeight);
-      this._context.lineTo(boxX + 4 * arrowHeight, boxY);
-    }
-    this._context.lineTo(boxX + titleWidth, boxY);
-    this._context.lineTo(boxX + titleWidth, boxY + titleHeight);
-    if (renderArrowDown) {
-      this._context.lineTo(boxX + 4 * arrowHeight, boxY + titleHeight);
-      this._context.lineTo(boxX + 3 * arrowHeight, boxY + titleHeight + arrowHeight);
-      this._context.lineTo(boxX + 2 * arrowHeight, boxY + titleHeight);
-    }
-    this._context.lineTo(boxX, boxY + titleHeight);
-    this._context.closePath();
-    this._context.fillStyle = 'rgb(255, 255, 194)';
-    this._context.fill();
-    this._context.strokeStyle = 'rgb(128, 128, 128)';
-    this._context.stroke();
-
-    this._context.restore();
-
-    this._titleElement.style.top = (boxY + 3) + 'px';
-    this._titleElement.style.left = (boxX + 3) + 'px';
-  }
-
-  /**
-   * @return {!{width: number, height: number}}
-   */
-  _viewportDimensions() {
-    const gutterSize = 30;
-    const bordersSize = Screencast.ScreencastView._bordersSize;
-    const width = this.element.offsetWidth - bordersSize - gutterSize;
-    const height = this.element.offsetHeight - bordersSize - gutterSize - Screencast.ScreencastView._navBarHeight;
-    return {width: width, height: height};
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Overlay.InspectMode} mode
-   * @param {!Protocol.Overlay.HighlightConfig} config
-   * @return {!Promise}
-   */
-  setInspectMode(mode, config) {
-    this._inspectModeConfig = mode !== Protocol.Overlay.InspectMode.None ? config : null;
-    return Promise.resolve();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   */
-  _createCheckerboardPattern(context) {
-    const pattern = /** @type {!HTMLCanvasElement} */ (createElement('canvas'));
-    const size = 32;
-    pattern.width = size * 2;
-    pattern.height = size * 2;
-    const pctx = pattern.getContext('2d');
-
-    pctx.fillStyle = 'rgb(195, 195, 195)';
-    pctx.fillRect(0, 0, size * 2, size * 2);
-
-    pctx.fillStyle = 'rgb(225, 225, 225)';
-    pctx.fillRect(0, 0, size, size);
-    pctx.fillRect(size, size, size, size);
-    return context.createPattern(pattern, 'repeat');
-  }
-
-  _createNavigationBar() {
-    this._navigationBar = this.element.createChild('div', 'screencast-navigation');
-    this._navigationBack = this._navigationBar.createChild('button', 'back');
-    this._navigationBack.disabled = true;
-    this._navigationForward = this._navigationBar.createChild('button', 'forward');
-    this._navigationForward.disabled = true;
-    this._navigationReload = this._navigationBar.createChild('button', 'reload');
-    this._navigationUrl = UI.createInput();
-    this._navigationBar.appendChild(this._navigationUrl);
-    this._navigationUrl.type = 'text';
-    this._navigationProgressBar = new Screencast.ScreencastView.ProgressTracker(
-        this._resourceTreeModel, this._networkManager, this._navigationBar.createChild('div', 'progress'));
-
-    if (this._resourceTreeModel) {
-      this._navigationBack.addEventListener('click', this._navigateToHistoryEntry.bind(this, -1), false);
-      this._navigationForward.addEventListener('click', this._navigateToHistoryEntry.bind(this, 1), false);
-      this._navigationReload.addEventListener('click', this._navigateReload.bind(this), false);
-      this._navigationUrl.addEventListener('keyup', this._navigationUrlKeyUp.bind(this), true);
-      this._requestNavigationHistory();
-      this._resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._requestNavigationHistory, this);
-      this._resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._requestNavigationHistory, this);
-    }
-  }
-
-  /**
-   * @param {number} offset
-   */
-  _navigateToHistoryEntry(offset) {
-    const newIndex = this._historyIndex + offset;
-    if (newIndex < 0 || newIndex >= this._historyEntries.length)
-      return;
-    this._resourceTreeModel.navigateToHistoryEntry(this._historyEntries[newIndex]);
-    this._requestNavigationHistory();
-  }
-
-  _navigateReload() {
-    this._resourceTreeModel.reloadPage();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _navigationUrlKeyUp(event) {
-    if (event.key !== 'Enter')
-      return;
-    let url = this._navigationUrl.value;
-    if (!url)
-      return;
-    if (!url.match(Screencast.ScreencastView._SchemeRegex))
-      url = 'http://' + url;
-    this._resourceTreeModel.navigate(url);
-    this._canvasElement.focus();
-  }
-
-  async _requestNavigationHistory() {
-    const history = await this._resourceTreeModel.navigationHistory();
-    if (!history)
-      return;
-
-    this._historyIndex = history.currentIndex;
-    this._historyEntries = history.entries;
-
-    this._navigationBack.disabled = this._historyIndex === 0;
-    this._navigationForward.disabled = this._historyIndex === (this._historyEntries.length - 1);
-
-    let url = this._historyEntries[this._historyIndex].url;
-    const match = url.match(Screencast.ScreencastView._HttpRegex);
-    if (match)
-      url = match[1];
-    InspectorFrontendHost.inspectedURLChanged(url);
-    this._navigationUrl.value = url;
-  }
-
-  _focusNavigationBar() {
-    this._navigationUrl.focus();
-    this._navigationUrl.select();
-    return true;
-  }
-};
-
-Screencast.ScreencastView._bordersSize = 44;
-
-Screencast.ScreencastView._navBarHeight = 29;
-
-Screencast.ScreencastView._HttpRegex = /^http:\/\/(.+)/;
-
-Screencast.ScreencastView._SchemeRegex = /^(https?|about|chrome):/;
-
-/**
- * @unrestricted
- */
-Screencast.ScreencastView.ProgressTracker = class {
-  /**
-   * @param {?SDK.ResourceTreeModel} resourceTreeModel
-   * @param {?SDK.NetworkManager} networkManager
-   * @param {!Element} element
-   */
-  constructor(resourceTreeModel, networkManager, element) {
-    this._element = element;
-    if (resourceTreeModel) {
-      resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this);
-      resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, this._onLoad, this);
-    }
-    if (networkManager) {
-      networkManager.addEventListener(SDK.NetworkManager.Events.RequestStarted, this._onRequestStarted, this);
-      networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this);
-    }
-  }
-
-  _onMainFrameNavigated() {
-    this._requestIds = {};
-    this._startedRequests = 0;
-    this._finishedRequests = 0;
-    this._maxDisplayedProgress = 0;
-    this._updateProgress(0.1);  // Display first 10% on navigation start.
-  }
-
-  _onLoad() {
-    delete this._requestIds;
-    this._updateProgress(1);  // Display 100% progress on load, hide it in 0.5s.
-    setTimeout(function() {
-      if (!this._navigationProgressVisible())
-        this._displayProgress(0);
-    }.bind(this), 500);
-  }
-
-  _navigationProgressVisible() {
-    return !!this._requestIds;
-  }
-
-  _onRequestStarted(event) {
-    if (!this._navigationProgressVisible())
-      return;
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
-    if (request.type === Common.resourceTypes.WebSocket)
-      return;
-    this._requestIds[request.requestId()] = request;
-    ++this._startedRequests;
-  }
-
-  _onRequestFinished(event) {
-    if (!this._navigationProgressVisible())
-      return;
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    if (!(request.requestId() in this._requestIds))
-      return;
-    ++this._finishedRequests;
-    setTimeout(function() {
-      this._updateProgress(
-          this._finishedRequests / this._startedRequests * 0.9);  // Finished requests drive the progress up to 90%.
-    }.bind(this), 500);  // Delay to give the new requests time to start. This makes the progress smoother.
-  }
-
-  _updateProgress(progress) {
-    if (!this._navigationProgressVisible())
-      return;
-    if (this._maxDisplayedProgress >= progress)
-      return;
-    this._maxDisplayedProgress = progress;
-    this._displayProgress(progress);
-  }
-
-  _displayProgress(progress) {
-    this._element.style.width = (100 * progress) + '%';
-  }
-};
diff --git a/front_end/screencast/module.json b/front_end/screencast/module.json
deleted file mode 100644
index 9dbb35d..0000000
--- a/front_end/screencast/module.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@Common.AppProvider",
-            "className": "Screencast.ScreencastAppProvider",
-            "order": 1
-        },
-        {
-            "type": "@UI.ToolbarItem.Provider",
-            "className": "Screencast.ScreencastApp.ToolbarButtonProvider",
-            "order": 1,
-            "location": "main-toolbar-left"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "mainMenu",
-            "order": 10,
-            "actionId": "components.request-app-banner"
-        }
-    ],
-    "dependencies": [
-        "components",
-        "emulation"
-    ],
-    "scripts": [
-        "InputModel.js",
-        "ScreencastApp.js",
-        "ScreencastView.js"
-    ],
-    "resources": [
-        "screencastView.css"
-    ]
-}
diff --git a/front_end/screencast/screencastView.css b/front_end/screencast/screencastView.css
deleted file mode 100644
index e07bac1..0000000
--- a/front_end/screencast/screencastView.css
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.screencast {
-    overflow: hidden;
-}
-
-.screencast-navigation {
-    flex-direction: row;
-    display: flex;
-    flex: 24px 0 0;
-    position: relative;
-    padding-left: 1px;
-    border-bottom: 1px solid rgb(64%, 64%, 64%);
-    background-origin: padding-box;
-    background-clip: padding-box;
-}
-
-.screencast-navigation button {
-    border-radius: 2px;
-    background-color: transparent;
-    background-image: -webkit-image-set(
-        url(Images/navigationControls.png) 1x,
-        url(Images/navigationControls_2x.png) 2x);
-    background-clip: content-box;
-    background-origin: content-box;
-    background-repeat: no-repeat;
-    border: 1px solid transparent;
-    height: 23px;
-    padding: 2px;
-    width: 23px;
-}
-
-.screencast-navigation button:hover {
-    border-color: #ccc;
-}
-
-.screencast-navigation button:active {
-    border-color: #aaa;
-}
-
-.screencast-navigation button[disabled] {
-    opacity: 0.5;
-}
-
-.screencast-navigation button.back {
-    background-position-x: -1px;
-}
-
-.screencast-navigation button.forward {
-    background-position-x: -18px;
-}
-
-.screencast-navigation button.reload {
-    background-position-x: -37px;
-}
-
-.screencast-navigation input {
-    -webkit-flex: 1;
-    margin: 2px;
-    max-height: 19px;
-}
-
-.screencast-navigation .progress {
-    background-color: rgb(66, 129, 235);
-    height: 3px;
-    left: 0;
-    position: absolute;
-    top: 100%;  /* Align with the bottom edge of the parent. */
-    width: 0;
-    z-index: 2;  /* Above .screencast-glasspane. */
-}
-
-.screencast-viewport {
-    display: flex;
-    border: 1px solid #999;
-    border-radius: 20px;
-    flex: none;
-    padding: 20px;
-    margin: 10px;
-    background-color: #eee;
-}
-
-.screencast-canvas-container {
-    flex: auto;
-    display: flex;
-    border: 1px solid #999;
-    position: relative;
-    cursor: -webkit-image-set(url(Images/touchCursor.png) 1x, url(Images/touchCursor_2x.png) 2x), default;
-}
-
-.screencast canvas {
-    flex: auto;
-    position: relative;
-}
-
-.screencast-px {
-    color: rgb(128, 128, 128);
-}
-
-.screencast-element-title {
-    position: absolute;
-    z-index: 10;
-}
-
-.screencast-tag-name {
-    /* Keep this in sync with view-source.css (.webkit-html-tag) */
-    color: rgb(136, 18, 128);
-}
-
-.screencast-node-id {
-    /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */
-    color: rgb(26, 26, 166);
-}
-
-.screencast-class-name {
-    /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */
-    color: rgb(153, 69, 0);
-}
-
-.screencast-glasspane {
-    background-color: rgba(255, 255, 255, 0.8);
-    font-size: 30px;
-    z-index: 100;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-}
diff --git a/front_end/sdk/CPUProfileDataModel.js b/front_end/sdk/CPUProfileDataModel.js
deleted file mode 100644
index 95f87ae..0000000
--- a/front_end/sdk/CPUProfileDataModel.js
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.CPUProfileNode = class extends SDK.ProfileNode {
-  /**
-   * @param {!Protocol.Profiler.ProfileNode} node
-   * @param {number} sampleTime
-   */
-  constructor(node, sampleTime) {
-    const callFrame = node.callFrame || /** @type {!Protocol.Runtime.CallFrame} */ ({
-                        // Backward compatibility for old SamplingHeapProfileNode format.
-                        functionName: node['functionName'],
-                        scriptId: node['scriptId'],
-                        url: node['url'],
-                        lineNumber: node['lineNumber'] - 1,
-                        columnNumber: node['columnNumber'] - 1
-                      });
-    super(callFrame);
-    this.id = node.id;
-    this.self = node.hitCount * sampleTime;
-    this.positionTicks = node.positionTicks;
-    // Compatibility: legacy backends could provide "no reason" for optimized functions.
-    this.deoptReason = node.deoptReason && node.deoptReason !== 'no reason' ? node.deoptReason : null;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CPUProfileDataModel = class extends SDK.ProfileTreeModel {
-  /**
-   * @param {!Protocol.Profiler.Profile} profile
-   */
-  constructor(profile) {
-    super();
-    const isLegacyFormat = !!profile['head'];
-    if (isLegacyFormat) {
-      // Legacy format contains raw timestamps and start/stop times are in seconds.
-      this.profileStartTime = profile.startTime * 1000;
-      this.profileEndTime = profile.endTime * 1000;
-      this.timestamps = profile.timestamps;
-      this._compatibilityConversionHeadToNodes(profile);
-    } else {
-      // Current format encodes timestamps as deltas. Start/stop times are in microseconds.
-      this.profileStartTime = profile.startTime / 1000;
-      this.profileEndTime = profile.endTime / 1000;
-      this.timestamps = this._convertTimeDeltas(profile);
-    }
-    this.samples = profile.samples;
-    this.totalHitCount = 0;
-    this.profileHead = this._translateProfileTree(profile.nodes);
-    this.initialize(this.profileHead);
-    this._extractMetaNodes();
-    if (this.samples) {
-      this._buildIdToNodeMap();
-      this._sortSamples();
-      this._normalizeTimestamps();
-      this._fixMissingSamples();
-    }
-  }
-
-  /**
-   * @param {!Protocol.Profiler.Profile} profile
-   */
-  _compatibilityConversionHeadToNodes(profile) {
-    if (!profile.head || profile.nodes)
-      return;
-    /** @type {!Array<!Protocol.Profiler.ProfileNode>} */
-    const nodes = [];
-    convertNodesTree(profile.head);
-    profile.nodes = nodes;
-    delete profile.head;
-    /**
-     * @param {!Protocol.Profiler.ProfileNode} node
-     * @return {number}
-     */
-    function convertNodesTree(node) {
-      nodes.push(node);
-      node.children = (/** @type {!Array<!Protocol.Profiler.ProfileNode>} */ (node.children)).map(convertNodesTree);
-      return node.id;
-    }
-  }
-
-  /**
-   * @param {!Protocol.Profiler.Profile} profile
-   * @return {?Array<number>}
-   */
-  _convertTimeDeltas(profile) {
-    if (!profile.timeDeltas)
-      return null;
-    let lastTimeUsec = profile.startTime;
-    const timestamps = new Array(profile.timeDeltas.length + 1);
-    for (let i = 0; i < profile.timeDeltas.length; ++i) {
-      timestamps[i] = lastTimeUsec;
-      lastTimeUsec += profile.timeDeltas[i];
-    }
-    timestamps[profile.timeDeltas.length] = lastTimeUsec;
-    return timestamps;
-  }
-
-  /**
-   * @param {!Array<!Protocol.Profiler.ProfileNode>} nodes
-   * @return {!SDK.CPUProfileNode}
-   */
-  _translateProfileTree(nodes) {
-    /**
-     * @param {!Protocol.Profiler.ProfileNode} node
-     * @return {boolean}
-     */
-    function isNativeNode(node) {
-      if (node.callFrame)
-        return !!node.callFrame.url && node.callFrame.url.startsWith('native ');
-      return !!node['url'] && node['url'].startsWith('native ');
-    }
-    /**
-     * @param {!Array<!Protocol.Profiler.ProfileNode>} nodes
-     */
-    function buildChildrenFromParents(nodes) {
-      if (nodes[0].children)
-        return;
-      nodes[0].children = [];
-      for (let i = 1; i < nodes.length; ++i) {
-        const node = nodes[i];
-        const parentNode = nodeByIdMap.get(node.parent);
-        if (parentNode.children)
-          parentNode.children.push(node.id);
-        else
-          parentNode.children = [node.id];
-      }
-    }
-    /** @type {!Map<number, !Protocol.Profiler.ProfileNode>} */
-    const nodeByIdMap = new Map();
-    for (let i = 0; i < nodes.length; ++i) {
-      const node = nodes[i];
-      nodeByIdMap.set(node.id, node);
-    }
-    buildChildrenFromParents(nodes);
-    this.totalHitCount = nodes.reduce((acc, node) => acc + node.hitCount, 0);
-    const sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount;
-    const keepNatives = !!Common.moduleSetting('showNativeFunctionsInJSProfile').get();
-    const root = nodes[0];
-    /** @type {!Map<number, number>} */
-    const idMap = new Map([[root.id, root.id]]);
-    const resultRoot = new SDK.CPUProfileNode(root, sampleTime);
-    const parentNodeStack = root.children.map(() => resultRoot);
-    const sourceNodeStack = root.children.map(id => nodeByIdMap.get(id));
-    while (sourceNodeStack.length) {
-      let parentNode = parentNodeStack.pop();
-      const sourceNode = sourceNodeStack.pop();
-      if (!sourceNode.children)
-        sourceNode.children = [];
-      const targetNode = new SDK.CPUProfileNode(sourceNode, sampleTime);
-      if (keepNatives || !isNativeNode(sourceNode)) {
-        parentNode.children.push(targetNode);
-        parentNode = targetNode;
-      } else {
-        parentNode.self += targetNode.self;
-      }
-      idMap.set(sourceNode.id, parentNode.id);
-      parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode));
-      sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(id => nodeByIdMap.get(id)));
-    }
-    if (this.samples)
-      this.samples = this.samples.map(id => idMap.get(id));
-    return resultRoot;
-  }
-
-  _sortSamples() {
-    const timestamps = this.timestamps;
-    if (!timestamps)
-      return;
-    const samples = this.samples;
-    const indices = timestamps.map((x, index) => index);
-    indices.sort((a, b) => timestamps[a] - timestamps[b]);
-    for (let i = 0; i < timestamps.length; ++i) {
-      let index = indices[i];
-      if (index === i)
-        continue;
-      // Move items in a cycle.
-      const savedTimestamp = timestamps[i];
-      const savedSample = samples[i];
-      let currentIndex = i;
-      while (index !== i) {
-        samples[currentIndex] = samples[index];
-        timestamps[currentIndex] = timestamps[index];
-        currentIndex = index;
-        index = indices[index];
-        indices[currentIndex] = currentIndex;
-      }
-      samples[currentIndex] = savedSample;
-      timestamps[currentIndex] = savedTimestamp;
-    }
-  }
-
-  _normalizeTimestamps() {
-    let timestamps = this.timestamps;
-    if (!timestamps) {
-      // Support loading old CPU profiles that are missing timestamps.
-      // Derive timestamps from profile start and stop times.
-      const profileStartTime = this.profileStartTime;
-      const interval = (this.profileEndTime - profileStartTime) / this.samples.length;
-      timestamps = new Float64Array(this.samples.length + 1);
-      for (let i = 0; i < timestamps.length; ++i)
-        timestamps[i] = profileStartTime + i * interval;
-      this.timestamps = timestamps;
-      return;
-    }
-
-    // Convert samples from usec to msec
-    for (let i = 0; i < timestamps.length; ++i)
-      timestamps[i] /= 1000;
-    if (this.samples.length === timestamps.length) {
-      // Support for a legacy format where were no timeDeltas.
-      // Add an extra timestamp used to calculate the last sample duration.
-      const averageSample = (timestamps.peekLast() - timestamps[0]) / (timestamps.length - 1);
-      this.timestamps.push(timestamps.peekLast() + averageSample);
-    }
-    this.profileStartTime = timestamps[0];
-    this.profileEndTime = timestamps.peekLast();
-  }
-
-  _buildIdToNodeMap() {
-    /** @type {!Map<number, !SDK.CPUProfileNode>} */
-    this._idToNode = new Map();
-    const idToNode = this._idToNode;
-    const stack = [this.profileHead];
-    while (stack.length) {
-      const node = stack.pop();
-      idToNode.set(node.id, node);
-      stack.push.apply(stack, node.children);
-    }
-  }
-
-  _extractMetaNodes() {
-    const topLevelNodes = this.profileHead.children;
-    for (let i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) {
-      const node = topLevelNodes[i];
-      if (node.functionName === '(garbage collector)')
-        this.gcNode = node;
-      else if (node.functionName === '(program)')
-        this.programNode = node;
-      else if (node.functionName === '(idle)')
-        this.idleNode = node;
-    }
-  }
-
-  _fixMissingSamples() {
-    // Sometimes sampler is not able to parse the JS stack and returns
-    // a (program) sample instead. The issue leads to call frames belong
-    // to the same function invocation being split apart.
-    // Here's a workaround for that. When there's a single (program) sample
-    // between two call stacks sharing the same bottom node, it is replaced
-    // with the preceeding sample.
-    const samples = this.samples;
-    const samplesCount = samples.length;
-    if (!this.programNode || samplesCount < 3)
-      return;
-    const idToNode = this._idToNode;
-    const programNodeId = this.programNode.id;
-    const gcNodeId = this.gcNode ? this.gcNode.id : -1;
-    const idleNodeId = this.idleNode ? this.idleNode.id : -1;
-    let prevNodeId = samples[0];
-    let nodeId = samples[1];
-    let count = 0;
-    for (let sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) {
-      const nextNodeId = samples[sampleIndex + 1];
-      if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId) &&
-          bottomNode(idToNode.get(prevNodeId)) === bottomNode(idToNode.get(nextNodeId))) {
-        ++count;
-        samples[sampleIndex] = prevNodeId;
-      }
-      prevNodeId = nodeId;
-      nodeId = nextNodeId;
-    }
-    Common.console.warn(ls`DevTools: CPU profile parser is fixing ${count} missing samples.`);
-    /**
-     * @param {!SDK.ProfileNode} node
-     * @return {!SDK.ProfileNode}
-     */
-    function bottomNode(node) {
-      while (node.parent && node.parent.parent)
-        node = node.parent;
-      return node;
-    }
-    /**
-     * @param {number} nodeId
-     * @return {boolean}
-     */
-    function isSystemNode(nodeId) {
-      return nodeId === programNodeId || nodeId === gcNodeId || nodeId === idleNodeId;
-    }
-  }
-
-  /**
-   * @param {function(number, !SDK.CPUProfileNode, number)} openFrameCallback
-   * @param {function(number, !SDK.CPUProfileNode, number, number, number)} closeFrameCallback
-   * @param {number=} startTime
-   * @param {number=} stopTime
-   */
-  forEachFrame(openFrameCallback, closeFrameCallback, startTime, stopTime) {
-    if (!this.profileHead || !this.samples)
-      return;
-
-    startTime = startTime || 0;
-    stopTime = stopTime || Infinity;
-    const samples = this.samples;
-    const timestamps = this.timestamps;
-    const idToNode = this._idToNode;
-    const gcNode = this.gcNode;
-    const samplesCount = samples.length;
-    const startIndex = timestamps.lowerBound(startTime);
-    let stackTop = 0;
-    const stackNodes = [];
-    let prevId = this.profileHead.id;
-    let sampleTime;
-    let gcParentNode = null;
-
-    // Extra slots for gc being put on top,
-    // and one at the bottom to allow safe stackTop-1 access.
-    const stackDepth = this.maxDepth + 3;
-    if (!this._stackStartTimes)
-      this._stackStartTimes = new Float64Array(stackDepth);
-    const stackStartTimes = this._stackStartTimes;
-    if (!this._stackChildrenDuration)
-      this._stackChildrenDuration = new Float64Array(stackDepth);
-    const stackChildrenDuration = this._stackChildrenDuration;
-
-    let node;
-    let sampleIndex;
-    for (sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) {
-      sampleTime = timestamps[sampleIndex];
-      if (sampleTime >= stopTime)
-        break;
-      const id = samples[sampleIndex];
-      if (id === prevId)
-        continue;
-      node = idToNode.get(id);
-      let prevNode = idToNode.get(prevId);
-
-      if (node === gcNode) {
-        // GC samples have no stack, so we just put GC node on top of the last recorded sample.
-        gcParentNode = prevNode;
-        openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime);
-        stackStartTimes[++stackTop] = sampleTime;
-        stackChildrenDuration[stackTop] = 0;
-        prevId = id;
-        continue;
-      }
-      if (prevNode === gcNode) {
-        // end of GC frame
-        const start = stackStartTimes[stackTop];
-        const duration = sampleTime - start;
-        stackChildrenDuration[stackTop - 1] += duration;
-        closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]);
-        --stackTop;
-        prevNode = gcParentNode;
-        prevId = prevNode.id;
-        gcParentNode = null;
-      }
-
-      while (node.depth > prevNode.depth) {
-        stackNodes.push(node);
-        node = node.parent;
-      }
-
-      // Go down to the LCA and close current intervals.
-      while (prevNode !== node) {
-        const start = stackStartTimes[stackTop];
-        const duration = sampleTime - start;
-        stackChildrenDuration[stackTop - 1] += duration;
-        closeFrameCallback(
-            prevNode.depth, /** @type {!SDK.CPUProfileNode} */ (prevNode), start, duration,
-            duration - stackChildrenDuration[stackTop]);
-        --stackTop;
-        if (node.depth === prevNode.depth) {
-          stackNodes.push(node);
-          node = node.parent;
-        }
-        prevNode = prevNode.parent;
-      }
-
-      // Go up the nodes stack and open new intervals.
-      while (stackNodes.length) {
-        node = stackNodes.pop();
-        openFrameCallback(node.depth, node, sampleTime);
-        stackStartTimes[++stackTop] = sampleTime;
-        stackChildrenDuration[stackTop] = 0;
-      }
-
-      prevId = id;
-    }
-
-    sampleTime = timestamps[sampleIndex] || this.profileEndTime;
-    if (idToNode.get(prevId) === gcNode) {
-      const start = stackStartTimes[stackTop];
-      const duration = sampleTime - start;
-      stackChildrenDuration[stackTop - 1] += duration;
-      closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]);
-      --stackTop;
-      prevId = gcParentNode.id;
-    }
-
-    for (let node = idToNode.get(prevId); node.parent; node = node.parent) {
-      const start = stackStartTimes[stackTop];
-      const duration = sampleTime - start;
-      stackChildrenDuration[stackTop - 1] += duration;
-      closeFrameCallback(
-          node.depth, /** @type {!SDK.CPUProfileNode} */ (node), start, duration,
-          duration - stackChildrenDuration[stackTop]);
-      --stackTop;
-    }
-  }
-
-  /**
-   * @param {number} index
-   * @return {?SDK.CPUProfileNode}
-   */
-  nodeByIndex(index) {
-    return this._idToNode.get(this.samples[index]) || null;
-  }
-};
diff --git a/front_end/sdk/CPUProfilerModel.js b/front_end/sdk/CPUProfilerModel.js
deleted file mode 100644
index 5377bbb..0000000
--- a/front_end/sdk/CPUProfilerModel.js
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Protocol.ProfilerDispatcher}
- */
-SDK.CPUProfilerModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._isRecording = false;
-    this._nextAnonymousConsoleProfileNumber = 1;
-    this._anonymousConsoleProfileIdToTitle = new Map();
-    this._profilerAgent = target.profilerAgent();
-    target.registerProfilerDispatcher(this);
-    this._profilerAgent.enable();
-    this._debuggerModel = /** @type {!SDK.DebuggerModel} */ (target.model(SDK.DebuggerModel));
-  }
-
-  /**
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._debuggerModel.runtimeModel();
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel}
-   */
-  debuggerModel() {
-    return this._debuggerModel;
-  }
-
-  /**
-   * @override
-   * @param {string} id
-   * @param {!Protocol.Debugger.Location} scriptLocation
-   * @param {string=} title
-   */
-  consoleProfileStarted(id, scriptLocation, title) {
-    if (!title) {
-      title = Common.UIString('Profile %d', this._nextAnonymousConsoleProfileNumber++);
-      this._anonymousConsoleProfileIdToTitle.set(id, title);
-    }
-    this._dispatchProfileEvent(SDK.CPUProfilerModel.Events.ConsoleProfileStarted, id, scriptLocation, title);
-  }
-
-  /**
-   * @override
-   * @param {string} id
-   * @param {!Protocol.Debugger.Location} scriptLocation
-   * @param {!Protocol.Profiler.Profile} cpuProfile
-   * @param {string=} title
-   */
-  consoleProfileFinished(id, scriptLocation, cpuProfile, title) {
-    if (!title) {
-      title = this._anonymousConsoleProfileIdToTitle.get(id);
-      this._anonymousConsoleProfileIdToTitle.delete(id);
-    }
-    // Make sure ProfilesPanel is initialized and CPUProfileType is created.
-    self.runtime.loadModulePromise('profiler').then(() => {
-      this._dispatchProfileEvent(
-          SDK.CPUProfilerModel.Events.ConsoleProfileFinished, id, scriptLocation, title, cpuProfile);
-    });
-  }
-
-  /**
-   * @param {symbol} eventName
-   * @param {string} id
-   * @param {!Protocol.Debugger.Location} scriptLocation
-   * @param {string=} title
-   * @param {!Protocol.Profiler.Profile=} cpuProfile
-   */
-  _dispatchProfileEvent(eventName, id, scriptLocation, title, cpuProfile) {
-    const debuggerLocation = SDK.DebuggerModel.Location.fromPayload(this._debuggerModel, scriptLocation);
-    const globalId = this.target().id() + '.' + id;
-    const data = /** @type {!SDK.CPUProfilerModel.EventData} */ (
-        {id: globalId, scriptLocation: debuggerLocation, cpuProfile: cpuProfile, title: title, cpuProfilerModel: this});
-    this.dispatchEventToListeners(eventName, data);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRecordingProfile() {
-    return this._isRecording;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  startRecording() {
-    this._isRecording = true;
-    const intervalUs = Common.moduleSetting('highResolutionCpuProfiling').get() ? 100 : 1000;
-    this._profilerAgent.setSamplingInterval(intervalUs);
-    return this._profilerAgent.start();
-  }
-
-  /**
-   * @return {!Promise<?Protocol.Profiler.Profile>}
-   */
-  stopRecording() {
-    this._isRecording = false;
-    return this._profilerAgent.stop();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  startPreciseCoverage() {
-    const callCount = false;
-    const detailed = true;
-    return this._profilerAgent.startPreciseCoverage(callCount, detailed);
-  }
-
-  /**
-   * @return {!Promise<!Array<!Protocol.Profiler.ScriptCoverage>>}
-   */
-  takePreciseCoverage() {
-    return this._profilerAgent.takePreciseCoverage().then(result => result || []);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  stopPreciseCoverage() {
-    return this._profilerAgent.stopPreciseCoverage();
-  }
-
-  /**
-   * @return {!Promise<!Array<!Protocol.Profiler.ScriptCoverage>>}
-   */
-  bestEffortCoverage() {
-    return this._profilerAgent.getBestEffortCoverage().then(result => result || []);
-  }
-};
-
-SDK.SDKModel.register(SDK.CPUProfilerModel, SDK.Target.Capability.JS, true);
-
-/** @enum {symbol} */
-SDK.CPUProfilerModel.Events = {
-  ConsoleProfileStarted: Symbol('ConsoleProfileStarted'),
-  ConsoleProfileFinished: Symbol('ConsoleProfileFinished')
-};
-
-/** @typedef {!{id: string, scriptLocation: !SDK.DebuggerModel.Location, title: string, cpuProfile: (!Protocol.Profiler.Profile|undefined), cpuProfilerModel: !SDK.CPUProfilerModel}} */
-SDK.CPUProfilerModel.EventData;
diff --git a/front_end/sdk/CSSMatchedStyles.js b/front_end/sdk/CSSMatchedStyles.js
deleted file mode 100644
index 9000e9b..0000000
--- a/front_end/sdk/CSSMatchedStyles.js
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.CSSMatchedStyles = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!SDK.DOMNode} node
-   * @param {?Protocol.CSS.CSSStyle} inlinePayload
-   * @param {?Protocol.CSS.CSSStyle} attributesPayload
-   * @param {!Array.<!Protocol.CSS.RuleMatch>} matchedPayload
-   * @param {!Array.<!Protocol.CSS.PseudoElementMatches>} pseudoPayload
-   * @param {!Array.<!Protocol.CSS.InheritedStyleEntry>} inheritedPayload
-   * @param {!Array.<!Protocol.CSS.CSSKeyframesRule>} animationsPayload
-   */
-  constructor(
-      cssModel,
-      node,
-      inlinePayload,
-      attributesPayload,
-      matchedPayload,
-      pseudoPayload,
-      inheritedPayload,
-      animationsPayload) {
-    this._cssModel = cssModel;
-    this._node = node;
-    /** @type {!Map<!SDK.CSSStyleDeclaration, !SDK.DOMNode>} */
-    this._addedStyles = new Map();
-    /** @type {!Map<!Protocol.DOM.NodeId, !Map<string, boolean>>} */
-    this._matchingSelectors = new Map();
-    this._keyframes = [];
-    if (animationsPayload)
-      this._keyframes = animationsPayload.map(rule => new SDK.CSSKeyframesRule(cssModel, rule));
-
-    /** @type {!Map<!SDK.CSSStyleDeclaration, ?SDK.DOMNode>} */
-    this._nodeForStyle = new Map();
-    /** @type {!Set<!SDK.CSSStyleDeclaration>} */
-    this._inheritedStyles = new Set();
-    this._mainDOMCascade = this._buildMainCascade(inlinePayload, attributesPayload, matchedPayload, inheritedPayload);
-    this._pseudoDOMCascades = this._buildPseudoCascades(pseudoPayload);
-
-    /** @type {!Map<!SDK.CSSStyleDeclaration, !SDK.CSSMatchedStyles.DOMInheritanceCascade>} */
-    this._styleToDOMCascade = new Map();
-    for (const domCascade of Array.from(this._pseudoDOMCascades.values()).concat(this._mainDOMCascade)) {
-      for (const style of domCascade.styles())
-        this._styleToDOMCascade.set(style, domCascade);
-    }
-  }
-
-  /**
-   * @param {?Protocol.CSS.CSSStyle} inlinePayload
-   * @param {?Protocol.CSS.CSSStyle} attributesPayload
-   * @param {!Array.<!Protocol.CSS.RuleMatch>} matchedPayload
-   * @param {!Array.<!Protocol.CSS.InheritedStyleEntry>} inheritedPayload
-   * @return {!SDK.CSSMatchedStyles.DOMInheritanceCascade}
-   */
-  _buildMainCascade(inlinePayload, attributesPayload, matchedPayload, inheritedPayload) {
-    /** @type {!Array<!SDK.CSSMatchedStyles.NodeCascade>} */
-    const nodeCascades = [];
-
-    /** @type {!Array<!SDK.CSSStyleDeclaration>} */
-    const nodeStyles = [];
-
-    /**
-     * @this {SDK.CSSMatchedStyles}
-     */
-    function addAttributesStyle() {
-      if (!attributesPayload)
-        return;
-      const style =
-          new SDK.CSSStyleDeclaration(this._cssModel, null, attributesPayload, SDK.CSSStyleDeclaration.Type.Attributes);
-      this._nodeForStyle.set(style, this._node);
-      nodeStyles.push(style);
-    }
-
-    // Inline style has the greatest specificity.
-    if (inlinePayload && this._node.nodeType() === Node.ELEMENT_NODE) {
-      const style =
-          new SDK.CSSStyleDeclaration(this._cssModel, null, inlinePayload, SDK.CSSStyleDeclaration.Type.Inline);
-      this._nodeForStyle.set(style, this._node);
-      nodeStyles.push(style);
-    }
-
-    // Add rules in reverse order to match the cascade order.
-    let addedAttributesStyle;
-    for (let i = matchedPayload.length - 1; i >= 0; --i) {
-      const rule = new SDK.CSSStyleRule(this._cssModel, matchedPayload[i].rule);
-      if ((rule.isInjected() || rule.isUserAgent()) && !addedAttributesStyle) {
-        // Show element's Style Attributes after all author rules.
-        addedAttributesStyle = true;
-        addAttributesStyle.call(this);
-      }
-      this._nodeForStyle.set(rule.style, this._node);
-      nodeStyles.push(rule.style);
-      this._addMatchingSelectors(this._node, rule, matchedPayload[i].matchingSelectors);
-    }
-
-    if (!addedAttributesStyle)
-      addAttributesStyle.call(this);
-    nodeCascades.push(new SDK.CSSMatchedStyles.NodeCascade(this, nodeStyles, false /* isInherited */));
-
-    // Walk the node structure and identify styles with inherited properties.
-    let parentNode = this._node.parentNode;
-    for (let i = 0; parentNode && inheritedPayload && i < inheritedPayload.length; ++i) {
-      const inheritedStyles = [];
-      const entryPayload = inheritedPayload[i];
-      const inheritedInlineStyle = entryPayload.inlineStyle ?
-          new SDK.CSSStyleDeclaration(
-              this._cssModel, null, entryPayload.inlineStyle, SDK.CSSStyleDeclaration.Type.Inline) :
-          null;
-      if (inheritedInlineStyle && this._containsInherited(inheritedInlineStyle)) {
-        this._nodeForStyle.set(inheritedInlineStyle, parentNode);
-        inheritedStyles.push(inheritedInlineStyle);
-        this._inheritedStyles.add(inheritedInlineStyle);
-      }
-
-      const inheritedMatchedCSSRules = entryPayload.matchedCSSRules || [];
-      for (let j = inheritedMatchedCSSRules.length - 1; j >= 0; --j) {
-        const inheritedRule = new SDK.CSSStyleRule(this._cssModel, inheritedMatchedCSSRules[j].rule);
-        this._addMatchingSelectors(parentNode, inheritedRule, inheritedMatchedCSSRules[j].matchingSelectors);
-        if (!this._containsInherited(inheritedRule.style))
-          continue;
-        this._nodeForStyle.set(inheritedRule.style, parentNode);
-        inheritedStyles.push(inheritedRule.style);
-        this._inheritedStyles.add(inheritedRule.style);
-      }
-      parentNode = parentNode.parentNode;
-      nodeCascades.push(new SDK.CSSMatchedStyles.NodeCascade(this, inheritedStyles, true /* isInherited */));
-    }
-
-    return new SDK.CSSMatchedStyles.DOMInheritanceCascade(nodeCascades);
-  }
-
-  /**
-   * @param {!Array.<!Protocol.CSS.PseudoElementMatches>} pseudoPayload
-   * @return {!Map<!Protocol.DOM.PseudoType, !SDK.CSSMatchedStyles.DOMInheritanceCascade>}
-   */
-  _buildPseudoCascades(pseudoPayload) {
-    /** @type {!Map<!Protocol.DOM.PseudoType, !SDK.CSSMatchedStyles.DOMInheritanceCascade>} */
-    const pseudoCascades = new Map();
-    if (!pseudoPayload)
-      return pseudoCascades;
-    for (let i = 0; i < pseudoPayload.length; ++i) {
-      const entryPayload = pseudoPayload[i];
-      // PseudoElement nodes are not created unless "content" css property is set.
-      const pseudoElement = this._node.pseudoElements().get(entryPayload.pseudoType) || null;
-      const pseudoStyles = [];
-      const rules = entryPayload.matches || [];
-      for (let j = rules.length - 1; j >= 0; --j) {
-        const pseudoRule = new SDK.CSSStyleRule(this._cssModel, rules[j].rule);
-        pseudoStyles.push(pseudoRule.style);
-        this._nodeForStyle.set(pseudoRule.style, pseudoElement);
-        if (pseudoElement)
-          this._addMatchingSelectors(pseudoElement, pseudoRule, rules[j].matchingSelectors);
-      }
-      const nodeCascade = new SDK.CSSMatchedStyles.NodeCascade(this, pseudoStyles, false /* isInherited */);
-      pseudoCascades.set(entryPayload.pseudoType, new SDK.CSSMatchedStyles.DOMInheritanceCascade([nodeCascade]));
-    }
-    return pseudoCascades;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {!SDK.CSSStyleRule} rule
-   * @param {!Array<number>} matchingSelectorIndices
-   * @this {SDK.CSSMatchedStyles}
-   */
-  _addMatchingSelectors(node, rule, matchingSelectorIndices) {
-    for (const matchingSelectorIndex of matchingSelectorIndices) {
-      const selector = rule.selectors[matchingSelectorIndex];
-      this._setSelectorMatches(node, selector.text, true);
-    }
-  }
-
-  /**
-   * @return {!SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @return {!SDK.CSSModel}
-   */
-  cssModel() {
-    return this._cssModel;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleRule} rule
-   * @return {boolean}
-   */
-  hasMatchingSelectors(rule) {
-    const matchingSelectors = this.matchingSelectors(rule);
-    return matchingSelectors.length > 0 && this.mediaMatches(rule.style);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleRule} rule
-   * @return {!Array<number>}
-   */
-  matchingSelectors(rule) {
-    const node = this.nodeForStyle(rule.style);
-    if (!node)
-      return [];
-    const map = this._matchingSelectors.get(node.id);
-    if (!map)
-      return [];
-    const result = [];
-    for (let i = 0; i < rule.selectors.length; ++i) {
-      if (map.get(rule.selectors[i].text))
-        result.push(i);
-    }
-    return result;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleRule} rule
-   * @return {!Promise}
-   */
-  recomputeMatchingSelectors(rule) {
-    const node = this.nodeForStyle(rule.style);
-    if (!node)
-      return Promise.resolve();
-    const promises = [];
-    for (const selector of rule.selectors)
-      promises.push(querySelector.call(this, node, selector.text));
-    return Promise.all(promises);
-
-    /**
-     * @param {!SDK.DOMNode} node
-     * @param {string} selectorText
-     * @this {SDK.CSSMatchedStyles}
-     */
-    async function querySelector(node, selectorText) {
-      const ownerDocument = node.ownerDocument || null;
-      // We assume that "matching" property does not ever change during the
-      // MatchedStyleResult's lifetime.
-      const map = this._matchingSelectors.get(node.id);
-      if ((map && map.has(selectorText)) || !ownerDocument)
-        return;
-
-      const matchingNodeIds = await this._node.domModel().querySelectorAll(ownerDocument.id, selectorText);
-
-      if (matchingNodeIds)
-        this._setSelectorMatches(node, selectorText, matchingNodeIds.indexOf(node.id) !== -1);
-    }
-  }
-
-  /**
-   * @param {!SDK.CSSStyleRule} rule
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise}
-   */
-  addNewRule(rule, node) {
-    this._addedStyles.set(rule.style, node);
-    return this.recomputeMatchingSelectors(rule);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {string} selectorText
-   * @param {boolean} value
-   */
-  _setSelectorMatches(node, selectorText, value) {
-    let map = this._matchingSelectors.get(node.id);
-    if (!map) {
-      map = new Map();
-      this._matchingSelectors.set(node.id, map);
-    }
-    map.set(selectorText, value);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @return {boolean}
-   */
-  mediaMatches(style) {
-    const media = style.parentRule ? style.parentRule.media : [];
-    for (let i = 0; media && i < media.length; ++i) {
-      if (!media[i].active())
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @return {!Array<!SDK.CSSStyleDeclaration>}
-   */
-  nodeStyles() {
-    return this._mainDOMCascade.styles();
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSKeyframesRule>}
-   */
-  keyframes() {
-    return this._keyframes;
-  }
-
-  /**
-   * @param {!Protocol.DOM.PseudoType} pseudoType
-   * @return {!Array<!SDK.CSSStyleDeclaration>}
-   */
-  pseudoStyles(pseudoType) {
-    const domCascade = this._pseudoDOMCascades.get(pseudoType);
-    return domCascade ? domCascade.styles() : [];
-  }
-
-  /**
-   * @return {!Set<!Protocol.DOM.PseudoType>}
-   */
-  pseudoTypes() {
-    return new Set(this._pseudoDOMCascades.keys());
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @return {boolean}
-   */
-  _containsInherited(style) {
-    const properties = style.allProperties();
-    for (let i = 0; i < properties.length; ++i) {
-      const property = properties[i];
-      // Does this style contain non-overridden inherited property?
-      if (property.activeInStyle() && SDK.cssMetadata().isPropertyInherited(property.name))
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @return {?SDK.DOMNode}
-   */
-  nodeForStyle(style) {
-    return this._addedStyles.get(style) || this._nodeForStyle.get(style) || null;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @return {!Array<string>}
-   */
-  availableCSSVariables(style) {
-    const domCascade = this._styleToDOMCascade.get(style) || null;
-    return domCascade ? domCascade.availableCSSVariables(style) : [];
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @param {string} variableName
-   * @return {?string}
-   */
-  computeCSSVariable(style, variableName) {
-    const domCascade = this._styleToDOMCascade.get(style) || null;
-    return domCascade ? domCascade.computeCSSVariable(style, variableName) : null;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @param {string} value
-   * @return {?string}
-   */
-  computeValue(style, value) {
-    const domCascade = this._styleToDOMCascade.get(style) || null;
-    return domCascade ? domCascade.computeValue(style, value) : null;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @return {boolean}
-   */
-  isInherited(style) {
-    return this._inheritedStyles.has(style);
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} property
-   * @return {?SDK.CSSMatchedStyles.PropertyState}
-   */
-  propertyState(property) {
-    const domCascade = this._styleToDOMCascade.get(property.ownerStyle);
-    return domCascade ? domCascade.propertyState(property) : null;
-  }
-
-  resetActiveProperties() {
-    this._mainDOMCascade.reset();
-    for (const domCascade of this._pseudoDOMCascades.values())
-      domCascade.reset();
-  }
-};
-
-SDK.CSSMatchedStyles.NodeCascade = class {
-  /**
-   * @param {!SDK.CSSMatchedStyles} matchedStyles
-   * @param {!Array<!SDK.CSSStyleDeclaration>} styles
-   * @param {boolean} isInherited
-   */
-  constructor(matchedStyles, styles, isInherited) {
-    this._matchedStyles = matchedStyles;
-    this._styles = styles;
-    this._isInherited = isInherited;
-    /** @type {!Map<!SDK.CSSProperty, !SDK.CSSMatchedStyles.PropertyState>} */
-    this._propertiesState = new Map();
-    /** @type {!Map.<string, !SDK.CSSProperty>} */
-    this._activeProperties = new Map();
-  }
-
-  _computeActiveProperties() {
-    this._propertiesState.clear();
-    this._activeProperties.clear();
-
-    for (const style of this._styles) {
-      const rule = style.parentRule;
-      // Compute cascade for CSSStyleRules only.
-      if (rule && !(rule instanceof SDK.CSSStyleRule))
-        continue;
-      if (rule && !this._matchedStyles.hasMatchingSelectors(rule))
-        continue;
-
-      for (const property of style.allProperties()) {
-        // Do not pick non-inherited properties from inherited styles.
-        if (this._isInherited && !SDK.cssMetadata().isPropertyInherited(property.name))
-          continue;
-
-        if (!property.activeInStyle()) {
-          this._propertiesState.set(property, SDK.CSSMatchedStyles.PropertyState.Overloaded);
-          continue;
-        }
-
-        const canonicalName = SDK.cssMetadata().canonicalPropertyName(property.name);
-        const activeProperty = this._activeProperties.get(canonicalName);
-        if (activeProperty && (activeProperty.important || !property.important)) {
-          this._propertiesState.set(property, SDK.CSSMatchedStyles.PropertyState.Overloaded);
-          continue;
-        }
-
-        if (activeProperty)
-          this._propertiesState.set(activeProperty, SDK.CSSMatchedStyles.PropertyState.Overloaded);
-        this._propertiesState.set(property, SDK.CSSMatchedStyles.PropertyState.Active);
-        this._activeProperties.set(canonicalName, property);
-      }
-    }
-  }
-};
-
-SDK.CSSMatchedStyles.DOMInheritanceCascade = class {
-  /**
-   * @param {!Array<!SDK.CSSMatchedStyles.NodeCascade>} nodeCascades
-   */
-  constructor(nodeCascades) {
-    this._nodeCascades = nodeCascades;
-    /** @type {!Map<!SDK.CSSProperty, !SDK.CSSMatchedStyles.PropertyState>} */
-    this._propertiesState = new Map();
-    /** @type {!Map<!SDK.CSSMatchedStyles.NodeCascade, !Map<string, string>>} */
-    this._availableCSSVariables = new Map();
-    /** @type {!Map<!SDK.CSSMatchedStyles.NodeCascade, !Map<string, ?string>>} */
-    this._computedCSSVariables = new Map();
-    this._initialized = false;
-
-    /** @type {!Map<!SDK.CSSStyleDeclaration, !SDK.CSSMatchedStyles.NodeCascade>} */
-    this._styleToNodeCascade = new Map();
-    for (const nodeCascade of nodeCascades) {
-      for (const style of nodeCascade._styles)
-        this._styleToNodeCascade.set(style, nodeCascade);
-    }
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @return {!Array<string>}
-   */
-  availableCSSVariables(style) {
-    const nodeCascade = this._styleToNodeCascade.get(style);
-    if (!nodeCascade)
-      return [];
-    this._ensureInitialized();
-    return Array.from(this._availableCSSVariables.get(nodeCascade).keys());
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @param {string} variableName
-   * @return {?string}
-   */
-  computeCSSVariable(style, variableName) {
-    const nodeCascade = this._styleToNodeCascade.get(style);
-    if (!nodeCascade)
-      return null;
-    this._ensureInitialized();
-    const availableCSSVariables = this._availableCSSVariables.get(nodeCascade);
-    const computedCSSVariables = this._computedCSSVariables.get(nodeCascade);
-    return this._innerComputeCSSVariable(availableCSSVariables, computedCSSVariables, variableName);
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} style
-   * @param {string} value
-   * @return {?string}
-   */
-  computeValue(style, value) {
-    const nodeCascade = this._styleToNodeCascade.get(style);
-    if (!nodeCascade)
-      return null;
-    this._ensureInitialized();
-    const availableCSSVariables = this._availableCSSVariables.get(nodeCascade);
-    const computedCSSVariables = this._computedCSSVariables.get(nodeCascade);
-    return this._innerComputeValue(availableCSSVariables, computedCSSVariables, value);
-  }
-
-  /**
-   * @param {!Map<string, string>} availableCSSVariables
-   * @param {!Map<string, ?string>} computedCSSVariables
-   * @param {string} variableName
-   * @return {?string}
-   */
-  _innerComputeCSSVariable(availableCSSVariables, computedCSSVariables, variableName) {
-    if (!availableCSSVariables.has(variableName))
-      return null;
-    if (computedCSSVariables.has(variableName))
-      return computedCSSVariables.get(variableName);
-    // Set dummy value to avoid infinite recursion.
-    computedCSSVariables.set(variableName, null);
-    const definedValue = availableCSSVariables.get(variableName);
-    const computedValue = this._innerComputeValue(availableCSSVariables, computedCSSVariables, definedValue);
-    computedCSSVariables.set(variableName, computedValue);
-    return computedValue;
-  }
-
-  /**
-   * @param {!Map<string, string>} availableCSSVariables
-   * @param {!Map<string, ?string>} computedCSSVariables
-   * @param {string} value
-   * @return {?string}
-   */
-  _innerComputeValue(availableCSSVariables, computedCSSVariables, value) {
-    const results = TextUtils.TextUtils.splitStringByRegexes(value, [SDK.CSSMetadata.VariableRegex]);
-    const tokens = [];
-    for (const result of results) {
-      if (result.regexIndex === -1) {
-        tokens.push(result.value);
-        continue;
-      }
-      // process var() function
-      const regexMatch = result.value.match(/^var\((--[a-zA-Z0-9-_]+)[,]?\s*(.*)\)$/);
-      if (!regexMatch)
-        return null;
-      const cssVariable = regexMatch[1];
-      const computedValue = this._innerComputeCSSVariable(availableCSSVariables, computedCSSVariables, cssVariable);
-      if (computedValue === null && !regexMatch[2])
-        return null;
-      if (computedValue === null)
-        tokens.push(regexMatch[2]);
-      else
-        tokens.push(computedValue);
-    }
-    return tokens.map(token => token.trim()).join(' ');
-  }
-
-  /**
-   * @return {!Array<!SDK.CSSStyleDeclaration>}
-   */
-  styles() {
-    return Array.from(this._styleToNodeCascade.keys());
-  }
-
-  /**
-   * @param {!SDK.CSSProperty} property
-   * @return {?SDK.CSSMatchedStyles.PropertyState}
-   */
-  propertyState(property) {
-    this._ensureInitialized();
-    return this._propertiesState.get(property) || null;
-  }
-
-  reset() {
-    this._initialized = false;
-    this._propertiesState.clear();
-    this._availableCSSVariables.clear();
-    this._computedCSSVariables.clear();
-  }
-
-  _ensureInitialized() {
-    if (this._initialized)
-      return;
-    this._initialized = true;
-
-    const activeProperties = new Map();
-    for (const nodeCascade of this._nodeCascades) {
-      nodeCascade._computeActiveProperties();
-      for (const entry of nodeCascade._propertiesState.entries()) {
-        const property = /** @type {!SDK.CSSProperty} */ (entry[0]);
-        const state = /** @type {!SDK.CSSMatchedStyles.PropertyState} */ (entry[1]);
-        if (state === SDK.CSSMatchedStyles.PropertyState.Overloaded) {
-          this._propertiesState.set(property, SDK.CSSMatchedStyles.PropertyState.Overloaded);
-          continue;
-        }
-        const canonicalName = SDK.cssMetadata().canonicalPropertyName(property.name);
-        if (activeProperties.has(canonicalName)) {
-          this._propertiesState.set(property, SDK.CSSMatchedStyles.PropertyState.Overloaded);
-          continue;
-        }
-        activeProperties.set(canonicalName, property);
-        this._propertiesState.set(property, SDK.CSSMatchedStyles.PropertyState.Active);
-      }
-    }
-    // If every longhand of the shorthand is not active, then the shorthand is not active too.
-    for (const entry of activeProperties.entries()) {
-      const canonicalName = /** @type {string} */ (entry[0]);
-      const shorthandProperty = /** @type {!SDK.CSSProperty} */ (entry[1]);
-      const shorthandStyle = shorthandProperty.ownerStyle;
-      const longhands = shorthandStyle.longhandProperties(shorthandProperty.name);
-      if (!longhands.length)
-        continue;
-      let hasActiveLonghands = false;
-      for (const longhand of longhands) {
-        const longhandCanonicalName = SDK.cssMetadata().canonicalPropertyName(longhand.name);
-        const longhandActiveProperty = activeProperties.get(longhandCanonicalName);
-        if (!longhandActiveProperty)
-          continue;
-        if (longhandActiveProperty.ownerStyle === shorthandStyle) {
-          hasActiveLonghands = true;
-          break;
-        }
-      }
-      if (hasActiveLonghands)
-        continue;
-      activeProperties.delete(canonicalName);
-      this._propertiesState.set(shorthandProperty, SDK.CSSMatchedStyles.PropertyState.Overloaded);
-    }
-
-    // Work inheritance chain backwards to compute visible CSS Variables.
-    const accumulatedCSSVariables = new Map();
-    for (let i = this._nodeCascades.length - 1; i >= 0; --i) {
-      const nodeCascade = this._nodeCascades[i];
-      for (const entry of nodeCascade._activeProperties.entries()) {
-        const propertyName = /** @type {string} */ (entry[0]);
-        const property = /** @type {!SDK.CSSProperty} */ (entry[1]);
-        if (propertyName.startsWith('--'))
-          accumulatedCSSVariables.set(propertyName, property.value);
-      }
-      this._availableCSSVariables.set(nodeCascade, new Map(accumulatedCSSVariables));
-      this._computedCSSVariables.set(nodeCascade, new Map());
-    }
-  }
-};
-
-/** @enum {string} */
-SDK.CSSMatchedStyles.PropertyState = {
-  Active: 'Active',
-  Overloaded: 'Overloaded'
-};
diff --git a/front_end/sdk/CSSMedia.js b/front_end/sdk/CSSMedia.js
deleted file mode 100644
index c6f7118..0000000
--- a/front_end/sdk/CSSMedia.js
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.CSSMediaQuery = class {
-  /**
-   * @param {!Protocol.CSS.MediaQuery} payload
-   */
-  constructor(payload) {
-    this._active = payload.active;
-    this._expressions = [];
-    for (let j = 0; j < payload.expressions.length; ++j)
-      this._expressions.push(SDK.CSSMediaQueryExpression.parsePayload(payload.expressions[j]));
-  }
-
-  /**
-   * @param {!Protocol.CSS.MediaQuery} payload
-   * @return {!SDK.CSSMediaQuery}
-   */
-  static parsePayload(payload) {
-    return new SDK.CSSMediaQuery(payload);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  active() {
-    return this._active;
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSMediaQueryExpression>}
-   */
-  expressions() {
-    return this._expressions;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SDK.CSSMediaQueryExpression = class {
-  /**
-   * @param {!Protocol.CSS.MediaQueryExpression} payload
-   */
-  constructor(payload) {
-    this._value = payload.value;
-    this._unit = payload.unit;
-    this._feature = payload.feature;
-    this._valueRange = payload.valueRange ? TextUtils.TextRange.fromObject(payload.valueRange) : null;
-    this._computedLength = payload.computedLength || null;
-  }
-
-  /**
-   * @param {!Protocol.CSS.MediaQueryExpression} payload
-   * @return {!SDK.CSSMediaQueryExpression}
-   */
-  static parsePayload(payload) {
-    return new SDK.CSSMediaQueryExpression(payload);
-  }
-
-  /**
-   * @return {number}
-   */
-  value() {
-    return this._value;
-  }
-
-  /**
-   * @return {string}
-   */
-  unit() {
-    return this._unit;
-  }
-
-  /**
-   * @return {string}
-   */
-  feature() {
-    return this._feature;
-  }
-
-  /**
-   * @return {?TextUtils.TextRange}
-   */
-  valueRange() {
-    return this._valueRange;
-  }
-
-  /**
-   * @return {?number}
-   */
-  computedLength() {
-    return this._computedLength;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SDK.CSSMedia = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Protocol.CSS.CSSMedia} payload
-   */
-  constructor(cssModel, payload) {
-    this._cssModel = cssModel;
-    this._reinitialize(payload);
-  }
-
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Protocol.CSS.CSSMedia} payload
-   * @return {!SDK.CSSMedia}
-   */
-  static parsePayload(cssModel, payload) {
-    return new SDK.CSSMedia(cssModel, payload);
-  }
-
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Array.<!Protocol.CSS.CSSMedia>} payload
-   * @return {!Array.<!SDK.CSSMedia>}
-   */
-  static parseMediaArrayPayload(cssModel, payload) {
-    const result = [];
-    for (let i = 0; i < payload.length; ++i)
-      result.push(SDK.CSSMedia.parsePayload(cssModel, payload[i]));
-    return result;
-  }
-
-  /**
-   * @param {!Protocol.CSS.CSSMedia} payload
-   */
-  _reinitialize(payload) {
-    this.text = payload.text;
-    this.source = payload.source;
-    this.sourceURL = payload.sourceURL || '';
-    this.range = payload.range ? TextUtils.TextRange.fromObject(payload.range) : null;
-    this.styleSheetId = payload.styleSheetId;
-    this.mediaList = null;
-    if (payload.mediaList) {
-      this.mediaList = [];
-      for (let i = 0; i < payload.mediaList.length; ++i)
-        this.mediaList.push(SDK.CSSMediaQuery.parsePayload(payload.mediaList[i]));
-    }
-  }
-
-  /**
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (this.styleSheetId !== edit.styleSheetId || !this.range)
-      return;
-    if (edit.oldRange.equal(this.range))
-      this._reinitialize(/** @type {!Protocol.CSS.CSSMedia} */ (edit.payload));
-    else
-      this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
-  }
-
-  /**
-   * @param {!SDK.CSSMedia} other
-   * @return {boolean}
-   */
-  equal(other) {
-    if (!this.styleSheetId || !this.range || !other.range)
-      return false;
-    return this.styleSheetId === other.styleSheetId && this.range.equal(other.range);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  active() {
-    if (!this.mediaList)
-      return true;
-    for (let i = 0; i < this.mediaList.length; ++i) {
-      if (this.mediaList[i].active())
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @return {number|undefined}
-   */
-  lineNumberInSource() {
-    if (!this.range)
-      return undefined;
-    const header = this.header();
-    if (!header)
-      return undefined;
-    return header.lineNumberInSource(this.range.startLine);
-  }
-
-  /**
-   * @return {number|undefined}
-   */
-  columnNumberInSource() {
-    if (!this.range)
-      return undefined;
-    const header = this.header();
-    if (!header)
-      return undefined;
-    return header.columnNumberInSource(this.range.startLine, this.range.startColumn);
-  }
-
-  /**
-   * @return {?SDK.CSSStyleSheetHeader}
-   */
-  header() {
-    return this.styleSheetId ? this._cssModel.styleSheetHeaderForId(this.styleSheetId) : null;
-  }
-
-  /**
-   * @return {?SDK.CSSLocation}
-   */
-  rawLocation() {
-    const header = this.header();
-    if (!header || this.lineNumberInSource() === undefined)
-      return null;
-    const lineNumber = Number(this.lineNumberInSource());
-    return new SDK.CSSLocation(header, lineNumber, this.columnNumberInSource());
-  }
-};
-
-SDK.CSSMedia.Source = {
-  LINKED_SHEET: 'linkedSheet',
-  INLINE_SHEET: 'inlineSheet',
-  MEDIA_RULE: 'mediaRule',
-  IMPORT_RULE: 'importRule'
-};
diff --git a/front_end/sdk/CSSMetadata.js b/front_end/sdk/CSSMetadata.js
deleted file mode 100644
index 70eae3c..0000000
--- a/front_end/sdk/CSSMetadata.js
+++ /dev/null
@@ -1,1409 +0,0 @@
-/*
- * Copyright (C) 2010 Nikita Vasilyev. All rights reserved.
- * Copyright (C) 2010 Joseph Pecoraro. All rights reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.CSSMetadata = class {
-  /**
-   * @param {!Array.<!{name: string, longhands: !Array.<string>, inherited: boolean, svg: boolean}>} properties
-   */
-  constructor(properties) {
-    this._values = /** !Array.<string> */ ([]);
-    /** @type {!Map<string, !Array<string>>} */
-    this._longhands = new Map();
-    /** @type {!Map<string, !Array<string>>} */
-    this._shorthands = new Map();
-    /** @type {!Set<string>} */
-    this._inherited = new Set();
-    /** @type {!Set<string>} */
-    this._svgProperties = new Set();
-    for (let i = 0; i < properties.length; ++i) {
-      const property = properties[i];
-      const propertyName = property.name;
-      if (!CSS.supports(propertyName, 'initial'))
-        continue;
-      this._values.push(propertyName);
-
-      if (property.inherited)
-        this._inherited.add(propertyName);
-      if (property.svg)
-        this._svgProperties.add(propertyName);
-
-      const longhands = properties[i].longhands;
-      if (longhands) {
-        this._longhands.set(propertyName, longhands);
-        for (let j = 0; j < longhands.length; ++j) {
-          const longhandName = longhands[j];
-          let shorthands = this._shorthands.get(longhandName);
-          if (!shorthands) {
-            shorthands = [];
-            this._shorthands.set(longhandName, shorthands);
-          }
-          shorthands.push(propertyName);
-        }
-      }
-    }
-    this._values.sort();
-    this._valuesSet = new Set(this._values);
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  allProperties() {
-    return this._values;
-  }
-
-  /**
-   * @param {string} name
-   * @return {boolean}
-   */
-  isSVGProperty(name) {
-    name = name.toLowerCase();
-    return this._svgProperties.has(name);
-  }
-
-  /**
-   * @param {string} shorthand
-   * @return {?Array.<string>}
-   */
-  longhands(shorthand) {
-    return this._longhands.get(shorthand) || null;
-  }
-
-  /**
-   * @param {string} longhand
-   * @return {?Array.<string>}
-   */
-  shorthands(longhand) {
-    return this._shorthands.get(longhand) || null;
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isColorAwareProperty(propertyName) {
-    return !!SDK.CSSMetadata._colorAwareProperties.has(propertyName.toLowerCase()) ||
-        this.isCustomProperty(propertyName.toLowerCase());
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isLengthProperty(propertyName) {
-    propertyName = propertyName.toLowerCase();
-    if (propertyName === 'line-height')
-      return false;
-    return SDK.CSSMetadata._distanceProperties.has(propertyName) || propertyName.startsWith('margin') ||
-        propertyName.startsWith('padding') || propertyName.indexOf('width') !== -1 ||
-        propertyName.indexOf('height') !== -1;
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isBezierAwareProperty(propertyName) {
-    propertyName = propertyName.toLowerCase();
-    return !!SDK.CSSMetadata._bezierAwareProperties.has(propertyName) || this.isCustomProperty(propertyName);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isCustomProperty(propertyName) {
-    return propertyName.startsWith('--');
-  }
-
-  /**
-   * @param {string} name
-   * @return {string}
-   */
-  canonicalPropertyName(name) {
-    name = name.toLowerCase();
-    if (!name || name.length < 9 || name.charAt(0) !== '-')
-      return name;
-    const match = name.match(/(?:-webkit-)(.+)/);
-    if (!match || !this._valuesSet.has(match[1]))
-      return name;
-    return match[1];
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isCSSPropertyName(propertyName) {
-    propertyName = propertyName.toLowerCase();
-    if (propertyName.startsWith('-moz-') || propertyName.startsWith('-o-') || propertyName.startsWith('-webkit-') ||
-        propertyName.startsWith('-ms-'))
-      return true;
-    return this._valuesSet.has(propertyName);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {boolean}
-   */
-  isPropertyInherited(propertyName) {
-    propertyName = propertyName.toLowerCase();
-    return propertyName.startsWith('--') || this._inherited.has(this.canonicalPropertyName(propertyName)) ||
-        this._inherited.has(propertyName);
-  }
-
-  /**
-   * @param {string} propertyName
-   * @return {!Array<string>}
-   */
-  propertyValues(propertyName) {
-    const acceptedKeywords = ['inherit', 'initial', 'unset'];
-    propertyName = propertyName.toLowerCase();
-    const unprefixedName = propertyName.replace(/^-webkit-/, '');
-    const entry = SDK.CSSMetadata._propertyDataMap[propertyName] || SDK.CSSMetadata._propertyDataMap[unprefixedName];
-    if (entry && entry.values)
-      acceptedKeywords.pushAll(entry.values);
-    if (this.isColorAwareProperty(propertyName)) {
-      acceptedKeywords.push('currentColor');
-      for (const color in Common.Color.Nicknames)
-        acceptedKeywords.push(color);
-    }
-    return acceptedKeywords.sort();
-  }
-
-  /**
-   * @param {string} property
-   * @return {number}
-   */
-  propertyUsageWeight(property) {
-    return SDK.CSSMetadata.Weight[property] || SDK.CSSMetadata.Weight[this.canonicalPropertyName(property)] || 0;
-  }
-};
-
-SDK.CSSMetadata.VariableRegex = /(var\(--.*?\))/g;
-SDK.CSSMetadata.URLRegex = /url\(\s*('.+?'|".+?"|[^)]+)\s*\)/g;
-
-/**
- * @return {!SDK.CSSMetadata}
- */
-SDK.cssMetadata = function() {
-  if (!SDK.CSSMetadata._instance)
-    SDK.CSSMetadata._instance = new SDK.CSSMetadata(SDK.CSSMetadata._generatedProperties || []);
-  return SDK.CSSMetadata._instance;
-};
-
-SDK.CSSMetadata._distanceProperties = new Set([
-  'background-position', 'border-spacing', 'bottom', 'font-size', 'height', 'left', 'letter-spacing', 'max-height',
-  'max-width', 'min-height', 'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing', 'grid-row-gap',
-  'grid-column-gap'
-]);
-
-SDK.CSSMetadata._bezierAwareProperties = new Set([
-  'animation', 'animation-timing-function', 'transition', 'transition-timing-function', '-webkit-animation',
-  '-webkit-animation-timing-function', '-webkit-transition', '-webkit-transition-timing-function'
-]);
-
-SDK.CSSMetadata._colorAwareProperties = new Set([
-  'backdrop-filter',
-  'background',
-  'background-color',
-  'background-image',
-  'border',
-  'border-color',
-  'border-image',
-  'border-image-source',
-  'border-bottom',
-  'border-bottom-color',
-  'border-left',
-  'border-left-color',
-  'border-right',
-  'border-right-color',
-  'border-top',
-  'border-top-color',
-  'box-shadow',
-  'caret-color',
-  'color',
-  'column-rule',
-  'column-rule-color',
-  'fill',
-  'list-style',
-  'list-style-image',
-  'outline',
-  'outline-color',
-  'stroke',
-  'text-decoration-color',
-  'text-shadow',
-  '-webkit-border-after',
-  '-webkit-border-after-color',
-  '-webkit-border-before',
-  '-webkit-border-before-color',
-  '-webkit-border-end',
-  '-webkit-border-end-color',
-  '-webkit-border-start',
-  '-webkit-border-start-color',
-  '-webkit-box-reflect',
-  '-webkit-box-shadow',
-  '-webkit-column-rule-color',
-  '-webkit-filter',
-  '-webkit-mask',
-  '-webkit-mask-box-image',
-  '-webkit-mask-box-image-source',
-  '-webkit-mask-image',
-  '-webkit-tap-highlight-color',
-  '-webkit-text-decoration-color',
-  '-webkit-text-emphasis',
-  '-webkit-text-emphasis-color',
-  '-webkit-text-fill-color',
-  '-webkit-text-stroke',
-  '-webkit-text-stroke-color'
-]);
-
-SDK.CSSMetadata._propertyDataMap = {
-  'table-layout': {values: ['auto', 'fixed']},
-  'visibility': {values: ['hidden', 'visible', 'collapse']},
-  'background-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']},
-  'content': {values: ['none', 'normal', 'close-quote', 'no-close-quote', 'no-open-quote', 'open-quote']},
-  'list-style-image': {values: ['none']},
-  'clear': {values: ['none', 'left', 'right', 'both']},
-  'overflow-x': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll']},
-  'stroke-linejoin': {values: ['round', 'miter', 'bevel']},
-  'baseline-shift': {values: ['baseline', 'sub', 'super']},
-  'border-bottom-width': {values: ['medium', 'thick', 'thin']},
-  'margin-top-collapse': {values: ['collapse', 'separate', 'discard']},
-  'max-height': {values: ['none', 'min-content', 'max-content', '-webkit-fill-available', 'fit-content']},
-  'box-orient': {
-    values: ['horizontal', 'vertical', 'inline-axis', 'block-axis'],
-  },
-  'font-stretch': {
-    values: [
-      'normal', 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'semi-expanded', 'expanded',
-      'extra-expanded', 'ultra-expanded'
-    ]
-  },
-  'border-left-width': {values: ['medium', 'thick', 'thin']},
-  'box-shadow': {values: ['inset', 'none']},
-  '-webkit-writing-mode': {values: ['horizontal-tb', 'vertical-rl', 'vertical-lr']},
-  'writing-mode':
-      {values: ['lr', 'rl', 'tb', 'lr-tb', 'rl-tb', 'tb-rl', 'horizontal-tb', 'vertical-rl', 'vertical-lr']},
-  'border-collapse': {values: ['collapse', 'separate']},
-  'page-break-inside': {values: ['auto', 'avoid']},
-  'border-top-width': {values: ['medium', 'thick', 'thin']},
-  'outline-style':
-      {values: ['auto', 'none', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
-  'cursor': {
-    values: [
-      'none',
-      'copy',
-      'auto',
-      'crosshair',
-      'default',
-      'pointer',
-      'move',
-      'vertical-text',
-      'cell',
-      'context-menu',
-      'alias',
-      'progress',
-      'no-drop',
-      'not-allowed',
-      '-webkit-zoom-in',
-      '-webkit-zoom-out',
-      'e-resize',
-      'ne-resize',
-      'nw-resize',
-      'n-resize',
-      'se-resize',
-      'sw-resize',
-      's-resize',
-      'w-resize',
-      'ew-resize',
-      'ns-resize',
-      'nesw-resize',
-      'nwse-resize',
-      'col-resize',
-      'row-resize',
-      'text',
-      'wait',
-      'help',
-      'all-scroll',
-      'zoom-in',
-      'zoom-out',
-      '-webkit-grab',
-      '-webkit-grabbing'
-    ]
-  },
-  'border-width': {values: ['medium', 'thick', 'thin']},
-  'border-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
-  'size': {values: ['auto', 'a3', 'a4', 'a5', 'b4', 'b5', 'landscape', 'ledger', 'legal', 'letter', 'portrait']},
-  'background-size': {values: ['auto', 'contain', 'cover']},
-  'direction': {values: ['ltr', 'rtl']},
-  'enable-background': {values: ['accumulate', 'new']},
-  'float': {values: ['none', 'left', 'right']},
-  'overflow-y': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
-  'margin-bottom-collapse': {values: ['collapse', 'separate', 'discard']},
-  'box-reflect': {values: ['left', 'right', 'above', 'below']},
-  'overflow': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
-  'contain': {values: ['none', 'strict', 'content', 'size', 'layout', 'style', 'paint']},
-  'text-rendering': {values: ['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision']},
-  'text-align': {
-    values: [
-      '-webkit-auto', 'start', 'end', 'left', 'right', 'center', 'justify', '-webkit-left', '-webkit-right',
-      '-webkit-center', '-webkit-match-parent'
-    ]
-  },
-  'list-style-position': {values: ['outside', 'inside']},
-  'margin-bottom': {values: ['auto']},
-  'color-interpolation': {values: ['auto', 'sRGB', 'linearRGB']},
-  'background-origin': {values: ['border-box', 'content-box', 'padding-box']},
-  'word-wrap': {values: ['normal', 'break-word']},
-  'font-weight':
-      {values: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900']},
-  'margin-before-collapse': {values: ['collapse', 'separate', 'discard']},
-  'text-transform': {values: ['none', 'capitalize', 'uppercase', 'lowercase']},
-  'border-right-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
-  'border-left-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
-  '-webkit-text-emphasis': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame', 'none']},
-  'font-style': {values: ['italic', 'oblique', 'normal']},
-  'speak': {values: ['none', 'normal', 'spell-out', 'digits', 'literal-punctuation', 'no-punctuation']},
-  'color-rendering': {values: ['auto', 'optimizeSpeed', 'optimizeQuality']},
-  'list-style-type': {
-    values: [
-      'none',
-      'disc',
-      'circle',
-      'square',
-      'decimal',
-      'decimal-leading-zero',
-      'arabic-indic',
-      'bengali',
-      'cambodian',
-      'khmer',
-      'devanagari',
-      'gujarati',
-      'gurmukhi',
-      'kannada',
-      'lao',
-      'malayalam',
-      'mongolian',
-      'myanmar',
-      'oriya',
-      'persian',
-      'urdu',
-      'telugu',
-      'tibetan',
-      'thai',
-      'lower-roman',
-      'upper-roman',
-      'lower-greek',
-      'lower-alpha',
-      'lower-latin',
-      'upper-alpha',
-      'upper-latin',
-      'ethiopic-halehame',
-      'ethiopic-halehame-am',
-      'ethiopic-halehame-ti-er',
-      'ethiopic-halehame-ti-et',
-      'cjk-earthly-branch',
-      'cjk-heavenly-stem',
-      'hangul-consonant',
-      'hangul',
-      'korean-hangul-formal',
-      'korean-hanja-formal',
-      'korean-hanja-informal',
-      'simp-chinese-formal',
-      'simp-chinese-informal',
-      'trad-chinese-formal',
-      'trad-chinese-informal',
-      'hebrew',
-      'armenian',
-      'lower-armenian',
-      'upper-armenian',
-      'georgian',
-      'cjk-ideographic',
-      'hiragana',
-      'katakana',
-      'hiragana-iroha',
-      'katakana-iroha'
-    ]
-  },
-  'text-combine-upright': {values: ['none', 'all']},
-  '-webkit-text-combine': {values: ['none', 'horizontal']},
-  'text-orientation': {values: ['mixed', 'upright', 'sideways', 'sideways-right']},
-  'outline': {
-    values: [
-      'none', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'auto', 'thick',
-      'thin'
-    ]
-  },
-  'font': {
-    values: [
-      'caption',
-      'icon',
-      'menu',
-      'message-box',
-      'small-caption',
-      '-webkit-mini-control',
-      '-webkit-small-control',
-      '-webkit-control',
-      'status-bar',
-      'italic',
-      'oblique',
-      'small-caps',
-      'normal',
-      'bold',
-      'bolder',
-      'lighter',
-      '100',
-      '200',
-      '300',
-      '400',
-      '500',
-      '600',
-      '700',
-      '800',
-      '900',
-      'xx-small',
-      'x-small',
-      'small',
-      'medium',
-      'large',
-      'x-large',
-      'xx-large',
-      '-webkit-xxx-large',
-      'smaller',
-      'larger',
-      'serif',
-      'sans-serif',
-      'cursive',
-      'fantasy',
-      'monospace',
-      '-webkit-body',
-      '-webkit-pictograph'
-    ]
-  },
-  'dominant-baseline': {
-    values: [
-      'middle', 'auto', 'central', 'text-before-edge', 'text-after-edge', 'ideographic', 'alphabetic', 'hanging',
-      'mathematical', 'use-script', 'no-change', 'reset-size'
-    ]
-  },
-  'display': {
-    values: [
-      'none',
-      'inline',
-      'block',
-      'flow-root',
-      'list-item',
-      'inline-block',
-      'table',
-      'inline-table',
-      'table-row-group',
-      'table-header-group',
-      'table-footer-group',
-      'table-row',
-      'table-column-group',
-      'table-column',
-      'table-cell',
-      'table-caption',
-      '-webkit-box',
-      '-webkit-inline-box',
-      'flex',
-      'inline-flex',
-      'grid',
-      'inline-grid',
-      'contents'
-    ]
-  },
-  '-webkit-text-emphasis-position': {values: ['over', 'under']},
-  'image-rendering': {values: ['auto', 'pixelated', '-webkit-optimize-contrast']},
-  'alignment-baseline': {
-    values: [
-      'baseline', 'middle', 'auto', 'before-edge', 'after-edge', 'central', 'text-before-edge', 'text-after-edge',
-      'ideographic', 'alphabetic', 'hanging', 'mathematical'
-    ]
-  },
-  'outline-width': {values: ['medium', 'thick', 'thin']},
-  'box-align': {values: ['baseline', 'center', 'stretch', 'start', 'end']},
-  'border-right-width': {values: ['medium', 'thick', 'thin']},
-  'border-top-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
-  'line-height': {values: ['normal']},
-  'text-overflow': {values: ['clip', 'ellipsis']},
-  'overflow-wrap': {values: ['normal', 'break-word']},
-  'box-direction': {values: ['normal', 'reverse']},
-  'margin-after-collapse': {values: ['collapse', 'separate', 'discard']},
-  'page-break-before': {values: ['left', 'right', 'auto', 'always', 'avoid']},
-  'border-image': {values: ['repeat', 'stretch', 'none', 'space', 'round']},
-  'text-decoration': {
-    values: ['none', 'blink', 'line-through', 'overline', 'underline', 'wavy', 'double', 'solid', 'dashed', 'dotted']
-  },
-  'position': {values: ['absolute', 'fixed', 'relative', 'static', 'sticky']},
-  'font-family':
-      {values: ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace', '-webkit-body', '-webkit-pictograph']},
-  'text-overflow-mode': {values: ['clip', 'ellipsis']},
-  'border-bottom-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
-  'unicode-bidi': {values: ['normal', 'bidi-override', 'embed', 'isolate', 'isolate-override', 'plaintext']},
-  'clip-rule': {values: ['nonzero', 'evenodd']},
-  'margin-left': {values: ['auto']},
-  'margin-top': {values: ['auto']},
-  'zoom': {values: ['normal']},
-  'max-width': {values: ['none', 'min-content', 'max-content', '-webkit-fill-available', 'fit-content']},
-  'caption-side': {values: ['top', 'bottom']},
-  'empty-cells': {values: ['hide', 'show']},
-  'pointer-events': {
-    values: [
-      'none', 'all', 'auto', 'visible', 'visiblepainted', 'visiblefill', 'visiblestroke', 'painted', 'fill', 'stroke',
-      'bounding-box'
-    ]
-  },
-  'letter-spacing': {values: ['normal']},
-  'background-clip': {values: ['border-box', 'content-box', 'padding-box']},
-  '-webkit-font-smoothing': {values: ['none', 'auto', 'antialiased', 'subpixel-antialiased']},
-  'border': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  'font-size': {
-    values: [
-      'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large', 'smaller', 'larger'
-    ]
-  },
-  'font-variant': {
-    values: [
-      'small-caps',
-      'normal',
-      'none',
-      'common-ligatures',
-      'no-common-ligatures',
-      'discretionary-ligatures',
-      'no-discretionary-ligatures',
-      'historical-ligatures',
-      'no-historical-ligatures',
-      'contextual',
-      'no-contextual',
-      'all-small-caps',
-      'petite-caps',
-      'all-petite-caps',
-      'unicase',
-      'titling-caps',
-      'lining-nums',
-      'oldstyle-nums',
-      'proportional-nums',
-      'tabular-nums',
-      'diagonal-fractions',
-      'stacked-fractions',
-      'ordinal',
-      'slashed-zero',
-      'jis78',
-      'jis83',
-      'jis90',
-      'jis04',
-      'simplified',
-      'traditional',
-      'full-width',
-      'proportional-width',
-      'ruby'
-    ]
-  },
-  'vertical-align': {
-    values:
-        ['baseline', 'middle', 'sub', 'super', 'text-top', 'text-bottom', 'top', 'bottom', '-webkit-baseline-middle']
-  },
-  'white-space': {values: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap']},
-  'page-break-after': {values: ['left', 'right', 'auto', 'always', 'avoid']},
-  'clip-path': {values: ['none']},
-  'margin': {values: ['auto']},
-  'margin-right': {values: ['auto']},
-  'word-break': {values: ['normal', 'break-all', 'break-word', 'keep-all']},
-  'word-spacing': {values: ['normal']},
-  '-webkit-text-emphasis-style':
-      {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame', 'none']},
-  'transform': {
-    values: [
-      'scale',      'scaleX',     'scaleY',      'scale3d', 'rotate',   'rotateX',     'rotateY',
-      'rotateZ',    'rotate3d',   'skew',        'skewX',   'skewY',    'translate',   'translateX',
-      'translateY', 'translateZ', 'translate3d', 'matrix',  'matrix3d', 'perspective', 'none'
-    ]
-  },
-  'image-resolution': {values: ['from-image', 'snap']},
-  'box-sizing': {values: ['content-box', 'border-box']},
-  'clip': {values: ['auto']},
-  'resize': {values: ['none', 'both', 'horizontal', 'vertical', 'auto']},
-  'align-content': {
-    values: [
-      'normal', 'baseline', 'space-between', 'space-around', 'space-evenly', 'stretch', 'unsafe', 'safe', 'center',
-      'start', 'end', 'flex-start', 'flex-end', 'left', 'right'
-    ]
-  },
-  'justify-content': {
-    values: [
-      'normal', 'space-between', 'space-around', 'space-evenly', 'stretch', 'unsafe', 'safe', 'center', 'start', 'end',
-      'flex-start', 'flex-end', 'left', 'right', 'baseline'
-    ]
-  },
-  'place-content': {
-    values: [
-      'normal', 'space-between', 'space-around', 'space-evenly', 'stretch', 'unsafe', 'safe', 'center', 'start', 'end',
-      'flex-start', 'flex-end', 'left', 'right', 'baseline'
-    ]
-  },
-  'align-items': {
-    values: [
-      'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
-      'flex-start', 'flex-end', 'left', 'right'
-    ]
-  },
-  'justify-items': {
-    values: [
-      'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
-      'flex-start', 'flex-end', 'left', 'right', 'legacy', 'auto'
-    ]
-  },
-  'place-items': {
-    values: [
-      'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
-      'flex-start', 'flex-end', 'left', 'right'
-    ]
-  },
-  'align-self': {
-    values: [
-      'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
-      'flex-start', 'flex-end', 'left', 'right'
-    ]
-  },
-  'justify-self': {
-    values: [
-      'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
-      'flex-start', 'flex-end', 'left', 'right'
-    ]
-  },
-  'place-self': {
-    values: [
-      'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
-      'flex-start', 'flex-end', 'left', 'right'
-    ]
-  },
-  'flex-direction': {values: ['row', 'row-reverse', 'column', 'column-reverse']},
-  'flex-wrap': {values: ['nowrap', 'wrap', 'wrap-reverse']},
-  'perspective': {values: ['none']},
-  'perspective-origin': {values: ['left', 'center', 'right', 'top', 'bottom']},
-  'transform-origin': {values: ['left', 'center', 'right', 'top', 'bottom']},
-  'transform-style': {values: ['flat', 'preserve-3d']},
-  'transition-timing-function': {
-    values: [
-      'ease', 'linear', 'ease-in', 'ease-out', 'ease-in-out', 'step-start', 'step-end', 'steps', 'frames',
-      'cubic-bezier', 'step-middle'
-    ]
-  },
-  'animation-timing-function': {
-    values: [
-      'ease', 'linear', 'ease-in', 'ease-out', 'ease-in-out', 'step-start', 'step-end', 'steps', 'frames',
-      'cubic-bezier', 'step-middle'
-    ]
-  },
-  'animation-direction': {values: ['normal', 'reverse', 'alternate', 'alternate-reverse']},
-  'animation-play-state': {values: ['running', 'paused']},
-  'animation-fill-mode': {values: ['none', 'forwards', 'backwards', 'both']},
-  '-webkit-backface-visibility': {values: ['visible', 'hidden']},
-  '-webkit-box-decoration-break': {values: ['slice', 'clone']},
-  '-webkit-column-break-after':
-      {values: ['auto', 'always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']},
-  '-webkit-column-break-before':
-      {values: ['auto', 'always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']},
-  '-webkit-column-break-inside': {values: ['auto', 'avoid', 'avoid-page', 'avoid-column']},
-  '-webkit-column-span': {values: ['none', 'all']},
-  '-webkit-column-count': {values: ['auto']},
-  '-webkit-column-gap': {values: ['normal']},
-  'filter': {
-    values: [
-      'url', 'blur', 'brightness', 'contrast', 'drop-shadow', 'grayscale', 'hue-rotate', 'invert', 'opacity',
-      'saturate', 'sepia', 'none'
-    ]
-  },
-  'line-break': {values: ['auto', 'loose', 'normal', 'strict', 'after-white-space']},
-  'user-select': {values: ['none', 'text', 'all', 'auto']},
-  '-webkit-user-modify': {values: ['read-only', 'read-write', 'read-write-plaintext-only']},
-  'text-align-last': {values: ['auto', 'start', 'end', 'left', 'right', 'center', 'justify']},
-  '-webkit-text-decoration-line': {values: ['none', 'underline', 'overline', 'line-through', 'blink']},
-  '-webkit-text-decoration-style': {values: ['solid', 'double', 'dotted', 'dashed', 'wavy']},
-  '-webkit-text-decoration-skip': {values: ['none', 'objects', 'spaces', 'ink', 'edges', 'box-decoration']},
-  'mix-blend-mode': {
-    values: [
-      'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light',
-      'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'unset'
-    ]
-  },
-  'background-blend-mode': {
-    values: [
-      'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light',
-      'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'unset'
-    ]
-  },
-  'caret-color': {values: ['auto']},
-  'grid-template-columns': {values: ['none', 'auto', 'min-content', 'max-content']},
-  'grid-template-rows': {values: ['none', 'auto', 'min-content', 'max-content']},
-  'grid-template-areas': {values: ['none']},
-  'grid-template': {values: ['none']},
-  'grid-auto-columns': {values: ['auto', 'min-content', 'max-content']},
-  'grid-auto-rows': {values: ['auto', 'min-content', 'max-content']},
-  'grid-auto-flow': {values: ['row', 'column', 'dense']},
-  'grid': {values: ['none']},
-  'grid-row-start': {values: ['auto']},
-  'grid-column-start': {values: ['auto']},
-  'grid-row-end': {values: ['auto']},
-  'grid-column-end': {values: ['auto']},
-  'grid-row': {values: ['auto']},
-  'grid-column': {values: ['auto']},
-  'grid-area': {values: ['auto']},
-  'animation-iteration-count': {values: ['infinite']},
-  'font-feature-settings': {values: ['normal']},
-  'font-kerning': {values: ['none', 'normal', 'auto']},
-  'font-size-adjust': {values: ['none']},
-  'font-variant-caps':
-      {values: ['small-caps', 'all-small-caps', 'petite-caps', 'all-petite-caps', 'unicase', 'titling-caps', 'normal']},
-  'font-variant-east-asian': {
-    values:
-        ['jis78', 'jis83', 'jis90', 'jis04', 'simplified', 'traditional', 'full-width', 'proportional-width', 'ruby']
-  },
-  'font-variant-ligatures': {
-    values: [
-      'none', 'common-ligatures', 'no-common-ligatures', 'discretionary-ligatures', 'no-discretionary-ligatures',
-      'historical-ligatures', 'no-historical-ligatures', 'contextual', 'no-contextual', 'normal'
-    ]
-  },
-  'font-variant-numeric': {
-    values: [
-      'lining-nums', 'oldstyle-nums', 'proportional-nums', 'tabular-nums', 'diagonal-fractions', 'stacked-fractions',
-      'ordinal', 'slashed-zero', 'normal'
-    ]
-  },
-  'font-variation-settings': {values: ['normal']},
-  '-webkit-locale': {values: ['auto']},
-  'backdrop-filter': {values: ['none']},
-  'backface-visibility': {values: ['hidden', 'visible']},
-  'background': {
-    values: [
-      'none', 'repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'top', 'bottom', 'left', 'right', 'center', 'fixed',
-      'local', 'scroll', 'space', 'round', 'border-box', 'content-box', 'padding-box'
-    ]
-  },
-  'background-attachment': {values: ['fixed', 'local', 'scroll']},
-  'background-image': {values: ['none']},
-  'background-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
-  'background-position-x': {values: ['left', 'right', 'center']},
-  'background-position-y': {values: ['top', 'bottom', 'center']},
-  'background-repeat-x': {values: ['repeat', 'no-repeat']},
-  'background-repeat-y': {values: ['repeat', 'no-repeat']},
-  'border-bottom': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  'border-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']},
-  'border-image-source': {values: ['none']},
-  'border-image-width': {values: ['auto']},
-  'border-left': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  'border-right': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  'border-top': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  'bottom': {values: ['auto']},
-  'break-after':
-      {values: ['left', 'right', 'auto', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']},
-  'break-before':
-      {values: ['left', 'right', 'auto', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']},
-  'break-inside': {values: ['auto', 'avoid', 'avoid-page', 'avoid-column']},
-  'buffered-rendering': {values: ['auto', 'static', 'dynamic']},
-  'color-interpolation-filters': {values: ['auto', 'srgb', 'linearrgb']},
-  'column-count': {values: ['auto']},
-  'column-fill': {values: ['auto', 'balance']},
-  'column-gap': {values: ['normal']},
-  'column-rule': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  'column-rule-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
-  'column-rule-width': {values: ['medium', 'thick', 'thin']},
-  'column-span': {values: ['none', 'all']},
-  'column-width': {values: ['auto']},
-  'columns': {values: ['auto']},
-  'd': {values: ['none']},
-  'fill': {values: ['none']},
-  'fill-rule': {values: ['nonzero', 'evenodd']},
-  'flex': {values: ['none', 'auto']},
-  'flex-basis': {values: ['auto']},
-  'flex-flow': {values: ['nowrap', 'row', 'row-reverse', 'column', 'column-reverse', 'wrap', 'wrap-reverse']},
-  'height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'hyphens': {values: ['none', 'manual']},
-  'inline-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'isolation': {values: ['auto', 'isolate']},
-  'left': {values: ['auto']},
-  'list-style': {
-    values: [
-      'none',
-      'outside',
-      'inside',
-      'disc',
-      'circle',
-      'square',
-      'decimal',
-      'decimal-leading-zero',
-      'arabic-indic',
-      'bengali',
-      'cambodian',
-      'khmer',
-      'devanagari',
-      'gujarati',
-      'gurmukhi',
-      'kannada',
-      'lao',
-      'malayalam',
-      'mongolian',
-      'myanmar',
-      'oriya',
-      'persian',
-      'urdu',
-      'telugu',
-      'tibetan',
-      'thai',
-      'lower-roman',
-      'upper-roman',
-      'lower-greek',
-      'lower-alpha',
-      'lower-latin',
-      'upper-alpha',
-      'upper-latin',
-      'cjk-earthly-branch',
-      'cjk-heavenly-stem',
-      'ethiopic-halehame',
-      'ethiopic-halehame-am',
-      'ethiopic-halehame-ti-er',
-      'ethiopic-halehame-ti-et',
-      'hangul',
-      'hangul-consonant',
-      'korean-hangul-formal',
-      'korean-hanja-formal',
-      'korean-hanja-informal',
-      'hebrew',
-      'armenian',
-      'lower-armenian',
-      'upper-armenian',
-      'georgian',
-      'cjk-ideographic',
-      'simp-chinese-formal',
-      'simp-chinese-informal',
-      'trad-chinese-formal',
-      'trad-chinese-informal',
-      'hiragana',
-      'katakana',
-      'hiragana-iroha',
-      'katakana-iroha'
-    ]
-  },
-  'marker': {values: ['none']},
-  'marker-end': {values: ['none']},
-  'marker-mid': {values: ['none']},
-  'marker-start': {values: ['none']},
-  'mask': {values: ['none']},
-  'mask-source-type': {values: ['auto', 'alpha', 'luminance']},
-  'mask-type': {values: ['alpha', 'luminance']},
-  'max-block-size': {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'max-inline-size': {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'min-block-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'min-height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'min-inline-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'min-width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'object-fit': {values: ['none', 'contain', 'cover', 'fill', 'scale-down']},
-  'object-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
-  'offset-anchor': {values: ['top', 'bottom', 'left', 'right', 'center', 'auto']},
-  'offset-path': {values: ['none']},
-  'offset-position': {values: ['top', 'bottom', 'left', 'right', 'center', 'auto']},
-  'offset-rotate': {values: ['auto', 'reverse']},
-  'overflow-anchor': {values: ['none', 'auto', 'visible']},
-  'paint-order': {values: ['normal', 'fill', 'stroke', 'markers']},
-  'quotes': {values: ['none']},
-  'right': {values: ['auto']},
-  'rotate': {values: ['none']},
-  'rx': {values: ['auto']},
-  'ry': {values: ['auto']},
-  'scale': {values: ['none']},
-  'scroll-behavior': {values: ['auto', 'smooth']},
-  'scroll-customization': {
-    values: [
-      'none',
-      'auto',
-      'pan-x',
-      'pan-y',
-      'pan-left',
-      'pan-right',
-      'pan-up',
-      'pan-down',
-    ]
-  },
-  'shape-outside': {values: ['none', 'border-box', 'content-box', 'padding-box', 'margin-box']},
-  'shape-rendering': {values: ['auto', 'optimizespeed', 'geometricprecision', 'crispedges']},
-  'stroke': {values: ['none']},
-  'stroke-dasharray': {values: ['none']},
-  'stroke-linecap': {values: ['square', 'round', 'butt']},
-  'text-anchor': {values: ['middle', 'start', 'end']},
-  'text-decoration-line': {values: ['none', 'blink', 'line-through', 'overline', 'underline']},
-  'text-decoration-skip': {values: ['objects', 'ink']},
-  'text-decoration-style': {values: ['dotted', 'dashed', 'solid', 'double', 'wavy']},
-  'text-justify': {values: ['none', 'inter-word', 'distribute', 'auto']},
-  'text-shadow': {values: ['none']},
-  'text-size-adjust': {values: ['none', 'auto']},
-  'text-underline-position': {values: ['auto', 'under']},
-  'top': {values: ['auto']},
-  'touch-action': {
-    values: [
-      'none', 'auto', 'pan-x', 'pan-y', 'pan-left', 'pan-right', 'pan-up', 'pan-down', 'manipulation', 'pinch-zoom'
-    ]
-  },
-  'transform-box': {values: ['border-box', 'fill-box', 'view-box']},
-  'translate': {values: ['none']},
-  'vector-effect': {values: ['none', 'non-scaling-stroke']},
-  '-webkit-app-region': {values: ['drag', 'no-drag']},
-  '-webkit-appearance': {
-    values: [
-      'none',
-      'checkbox',
-      'radio',
-      'push-button',
-      'square-button',
-      'button',
-      'button-bevel',
-      'inner-spin-button',
-      'listbox',
-      'listitem',
-      'media-enter-fullscreen-button',
-      'media-exit-fullscreen-button',
-      'media-mute-button',
-      'media-play-button',
-      'media-overlay-play-button',
-      'media-toggle-closed-captions-button',
-      'media-slider',
-      'media-sliderthumb',
-      'media-volume-slider-container',
-      'media-volume-slider',
-      'media-volume-sliderthumb',
-      'media-controls-background',
-      'media-controls-fullscreen-background',
-      'media-current-time-display',
-      'media-time-remaining-display',
-      'menulist',
-      'menulist-button',
-      'menulist-text',
-      'menulist-textfield',
-      'meter',
-      'progress-bar',
-      'progress-bar-value',
-      'slider-horizontal',
-      'slider-vertical',
-      'sliderthumb-horizontal',
-      'sliderthumb-vertical',
-      'caret',
-      'searchfield',
-      'searchfield-cancel-button',
-      'textfield',
-      'textarea'
-    ]
-  },
-  '-webkit-border-after': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  '-webkit-border-after-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
-  '-webkit-border-after-width': {values: ['medium', 'thick', 'thin']},
-  '-webkit-border-before': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  '-webkit-border-before-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
-  '-webkit-border-before-width': {values: ['medium', 'thick', 'thin']},
-  '-webkit-border-end': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  '-webkit-border-end-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
-  '-webkit-border-end-width': {values: ['medium', 'thick', 'thin']},
-  '-webkit-border-start': {
-    values: [
-      'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
-      'thin'
-    ]
-  },
-  '-webkit-border-start-style':
-      {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
-  '-webkit-border-start-width': {values: ['medium', 'thick', 'thin']},
-  '-webkit-box-pack': {values: ['center', 'justify', 'start', 'end']},
-  '-webkit-highlight': {values: ['none']},
-  '-webkit-hyphenate-character': {values: ['auto']},
-  '-webkit-logical-height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  '-webkit-logical-width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  '-webkit-margin-after': {values: ['auto']},
-  '-webkit-margin-before': {values: ['auto']},
-  '-webkit-margin-collapse': {values: ['collapse', 'separate', 'discard']},
-  '-webkit-margin-end': {values: ['auto']},
-  '-webkit-margin-start': {values: ['auto']},
-  '-webkit-mask-box-image': {values: ['none', 'repeat', 'stretch', 'space', 'round']},
-  '-webkit-mask-box-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']},
-  '-webkit-mask-box-image-source': {values: ['none']},
-  '-webkit-mask-box-image-width': {values: ['auto']},
-  '-webkit-mask-clip': {values: ['text', 'border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']},
-  '-webkit-mask-composite': {
-    values: [
-      'clear', 'copy', 'source-over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in',
-      'destination-out', 'destination-atop', 'xor', 'plus-lighter'
-    ]
-  },
-  '-webkit-mask-image': {values: ['none']},
-  '-webkit-mask-origin': {values: ['border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']},
-  '-webkit-mask-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
-  '-webkit-mask-position-x': {values: ['left', 'right', 'center']},
-  '-webkit-mask-position-y': {values: ['top', 'bottom', 'center']},
-  '-webkit-mask-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']},
-  '-webkit-mask-size': {values: ['auto', 'contain', 'cover']},
-  '-webkit-max-logical-height':
-      {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  '-webkit-max-logical-width':
-      {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  '-webkit-min-logical-height':
-      {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  '-webkit-min-logical-width':
-      {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  '-webkit-perspective-origin-x': {values: ['left', 'right', 'center']},
-  '-webkit-perspective-origin-y': {values: ['top', 'bottom', 'center']},
-  '-webkit-print-color-adjust': {values: ['economy', 'exact']},
-  '-webkit-rtl-ordering': {values: ['logical', 'visual']},
-  '-webkit-ruby-position': {values: ['after', 'before']},
-  '-webkit-text-decorations-in-effect': {values: ['none', 'blink', 'line-through', 'overline', 'underline']},
-  '-webkit-text-security': {values: ['none', 'disc', 'circle', 'square']},
-  '-webkit-text-stroke': {values: ['medium', 'thick', 'thin']},
-  '-webkit-text-stroke-width': {values: ['medium', 'thick', 'thin']},
-  '-webkit-transform-origin-x': {values: ['left', 'right', 'center']},
-  '-webkit-transform-origin-y': {values: ['top', 'bottom', 'center']},
-  '-webkit-user-drag': {values: ['none', 'auto', 'element']},
-  'width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
-  'z-index': {values: ['auto']}
-};
-
-// Weight of CSS properties based on their usage from https://www.chromestatus.com/metrics/css/popularity
-SDK.CSSMetadata.Weight = {
-  'align-content': 57,
-  'align-items': 129,
-  'align-self': 55,
-  'animation': 175,
-  'animation-delay': 114,
-  'animation-direction': 113,
-  'animation-duration': 137,
-  'animation-fill-mode': 132,
-  'animation-iteration-count': 124,
-  'animation-name': 139,
-  'animation-play-state': 104,
-  'animation-timing-function': 141,
-  'backface-visibility': 123,
-  'background': 260,
-  'background-attachment': 119,
-  'background-clip': 165,
-  'background-color': 259,
-  'background-image': 246,
-  'background-origin': 107,
-  'background-position': 237,
-  'background-position-x': 108,
-  'background-position-y': 93,
-  'background-repeat': 234,
-  'background-size': 203,
-  'border': 263,
-  'border-bottom': 233,
-  'border-bottom-color': 190,
-  'border-bottom-left-radius': 186,
-  'border-bottom-right-radius': 185,
-  'border-bottom-style': 150,
-  'border-bottom-width': 179,
-  'border-collapse': 209,
-  'border-color': 226,
-  'border-image': 89,
-  'border-image-outset': 50,
-  'border-image-repeat': 49,
-  'border-image-slice': 58,
-  'border-image-source': 32,
-  'border-image-width': 52,
-  'border-left': 221,
-  'border-left-color': 174,
-  'border-left-style': 142,
-  'border-left-width': 172,
-  'border-radius': 224,
-  'border-right': 223,
-  'border-right-color': 182,
-  'border-right-style': 130,
-  'border-right-width': 178,
-  'border-spacing': 198,
-  'border-style': 206,
-  'border-top': 231,
-  'border-top-color': 192,
-  'border-top-left-radius': 187,
-  'border-top-right-radius': 189,
-  'border-top-style': 152,
-  'border-top-width': 180,
-  'border-width': 214,
-  'bottom': 227,
-  'box-shadow': 213,
-  'box-sizing': 216,
-  'caption-side': 96,
-  'clear': 229,
-  'clip': 173,
-  'clip-rule': 5,
-  'color': 256,
-  'content': 219,
-  'counter-increment': 111,
-  'counter-reset': 110,
-  'cursor': 250,
-  'direction': 176,
-  'display': 262,
-  'empty-cells': 99,
-  'fill': 140,
-  'fill-opacity': 82,
-  'fill-rule': 22,
-  'filter': 160,
-  'flex': 133,
-  'flex-basis': 66,
-  'flex-direction': 85,
-  'flex-flow': 94,
-  'flex-grow': 112,
-  'flex-shrink': 61,
-  'flex-wrap': 68,
-  'float': 252,
-  'font': 211,
-  'font-family': 254,
-  'font-kerning': 18,
-  'font-size': 264,
-  'font-stretch': 77,
-  'font-style': 220,
-  'font-variant': 161,
-  'font-weight': 257,
-  'height': 266,
-  'image-rendering': 90,
-  'justify-content': 127,
-  'left': 248,
-  'letter-spacing': 188,
-  'line-height': 244,
-  'list-style': 215,
-  'list-style-image': 145,
-  'list-style-position': 149,
-  'list-style-type': 199,
-  'margin': 267,
-  'margin-bottom': 241,
-  'margin-left': 243,
-  'margin-right': 238,
-  'margin-top': 253,
-  'mask': 20,
-  'max-height': 205,
-  'max-width': 225,
-  'min-height': 217,
-  'min-width': 218,
-  'object-fit': 33,
-  'opacity': 251,
-  'order': 117,
-  'orphans': 146,
-  'outline': 222,
-  'outline-color': 153,
-  'outline-offset': 147,
-  'outline-style': 151,
-  'outline-width': 148,
-  'overflow': 255,
-  'overflow-wrap': 105,
-  'overflow-x': 184,
-  'overflow-y': 196,
-  'padding': 265,
-  'padding-bottom': 230,
-  'padding-left': 235,
-  'padding-right': 232,
-  'padding-top': 240,
-  'page': 8,
-  'page-break-after': 120,
-  'page-break-before': 69,
-  'page-break-inside': 121,
-  'perspective': 92,
-  'perspective-origin': 103,
-  'pointer-events': 183,
-  'position': 261,
-  'quotes': 158,
-  'resize': 168,
-  'right': 245,
-  'shape-rendering': 38,
-  'size': 64,
-  'speak': 118,
-  'src': 170,
-  'stop-color': 42,
-  'stop-opacity': 31,
-  'stroke': 98,
-  'stroke-dasharray': 36,
-  'stroke-dashoffset': 3,
-  'stroke-linecap': 30,
-  'stroke-linejoin': 21,
-  'stroke-miterlimit': 12,
-  'stroke-opacity': 34,
-  'stroke-width': 87,
-  'table-layout': 171,
-  'tab-size': 46,
-  'text-align': 260,
-  'text-anchor': 35,
-  'text-decoration': 247,
-  'text-indent': 207,
-  'text-overflow': 204,
-  'text-rendering': 155,
-  'text-shadow': 208,
-  'text-transform': 202,
-  'top': 258,
-  'touch-action': 80,
-  'transform': 181,
-  'transform-origin': 162,
-  'transform-style': 86,
-  'transition': 193,
-  'transition-delay': 134,
-  'transition-duration': 135,
-  'transition-property': 131,
-  'transition-timing-function': 122,
-  'unicode-bidi': 156,
-  'unicode-range': 136,
-  'vertical-align': 236,
-  'visibility': 242,
-  '-webkit-appearance': 191,
-  '-webkit-backface-visibility': 154,
-  '-webkit-background-clip': 164,
-  '-webkit-background-origin': 40,
-  '-webkit-background-size': 163,
-  '-webkit-border-end': 9,
-  '-webkit-border-horizontal-spacing': 81,
-  '-webkit-border-image': 75,
-  '-webkit-border-radius': 212,
-  '-webkit-border-start': 10,
-  '-webkit-border-start-color': 16,
-  '-webkit-border-start-width': 13,
-  '-webkit-border-vertical-spacing': 43,
-  '-webkit-box-align': 101,
-  '-webkit-box-direction': 51,
-  '-webkit-box-flex': 128,
-  '-webkit-box-ordinal-group': 91,
-  '-webkit-box-orient': 144,
-  '-webkit-box-pack': 106,
-  '-webkit-box-reflect': 39,
-  '-webkit-box-shadow': 210,
-  '-webkit-column-break-inside': 60,
-  '-webkit-column-count': 84,
-  '-webkit-column-gap': 76,
-  '-webkit-column-rule': 25,
-  '-webkit-column-rule-color': 23,
-  '-webkit-columns': 44,
-  '-webkit-column-span': 29,
-  '-webkit-column-width': 47,
-  '-webkit-filter': 159,
-  '-webkit-font-feature-settings': 59,
-  '-webkit-font-smoothing': 177,
-  '-webkit-highlight': 1,
-  '-webkit-line-break': 45,
-  '-webkit-line-clamp': 126,
-  '-webkit-margin-after': 67,
-  '-webkit-margin-before': 70,
-  '-webkit-margin-collapse': 14,
-  '-webkit-margin-end': 65,
-  '-webkit-margin-start': 100,
-  '-webkit-margin-top-collapse': 78,
-  '-webkit-mask': 19,
-  '-webkit-mask-box-image': 72,
-  '-webkit-mask-image': 88,
-  '-webkit-mask-position': 54,
-  '-webkit-mask-repeat': 63,
-  '-webkit-mask-size': 79,
-  '-webkit-padding-after': 15,
-  '-webkit-padding-before': 28,
-  '-webkit-padding-end': 48,
-  '-webkit-padding-start': 73,
-  '-webkit-print-color-adjust': 83,
-  '-webkit-rtl-ordering': 7,
-  '-webkit-tap-highlight-color': 169,
-  '-webkit-text-emphasis-color': 11,
-  '-webkit-text-fill-color': 71,
-  '-webkit-text-security': 17,
-  '-webkit-text-stroke': 56,
-  '-webkit-text-stroke-color': 37,
-  '-webkit-text-stroke-width': 53,
-  '-webkit-user-drag': 95,
-  '-webkit-user-modify': 62,
-  '-webkit-user-select': 194,
-  '-webkit-writing-mode': 4,
-  'white-space': 228,
-  'widows': 115,
-  'width': 268,
-  'will-change': 74,
-  'word-break': 166,
-  'word-spacing': 157,
-  'word-wrap': 197,
-  'writing-mode': 41,
-  'z-index': 239,
-  'zoom': 200
-};
diff --git a/front_end/sdk/CSSModel.js b/front_end/sdk/CSSModel.js
deleted file mode 100644
index d8d152c..0000000
--- a/front_end/sdk/CSSModel.js
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.CSSModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
-    /** @type {!SDK.SourceMapManager<!SDK.CSSStyleSheetHeader>} */
-    this._sourceMapManager = new SDK.SourceMapManager(target);
-    this._agent = target.cssAgent();
-    this._styleLoader = new SDK.CSSModel.ComputedStyleLoader(this);
-    this._resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (this._resourceTreeModel) {
-      this._resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._resetStyleSheets, this);
-    }
-    target.registerCSSDispatcher(new SDK.CSSDispatcher(this));
-    if (!target.suspended())
-      this._enable();
-    /** @type {!Map.<string, !SDK.CSSStyleSheetHeader>} */
-    this._styleSheetIdToHeader = new Map();
-    /** @type {!Map.<string, !Object.<!Protocol.Page.FrameId, !Array.<!Protocol.CSS.StyleSheetId>>>} */
-    this._styleSheetIdsForURL = new Map();
-
-    /** @type {!Map.<!SDK.CSSStyleSheetHeader, !Promise<?string>>} */
-    this._originalStyleSheetText = new Map();
-
-    this._sourceMapManager.setEnabled(Common.moduleSetting('cssSourceMapsEnabled').get());
-    Common.moduleSetting('cssSourceMapsEnabled')
-        .addChangeListener(event => this._sourceMapManager.setEnabled(/** @type {boolean} */ (event.data)));
-  }
-
-  /**
-   * @return {!SDK.SourceMapManager<!SDK.CSSStyleSheetHeader>}
-   */
-  sourceMapManager() {
-    return this._sourceMapManager;
-  }
-
-  /**
-   * @param {string} text
-   * @return {string}
-   */
-  static trimSourceURL(text) {
-    let sourceURLIndex = text.lastIndexOf('/*# sourceURL=');
-    if (sourceURLIndex === -1) {
-      sourceURLIndex = text.lastIndexOf('/*@ sourceURL=');
-      if (sourceURLIndex === -1)
-        return text;
-    }
-    const sourceURLLineIndex = text.lastIndexOf('\n', sourceURLIndex);
-    if (sourceURLLineIndex === -1)
-      return text;
-    const sourceURLLine = text.substr(sourceURLLineIndex + 1).split('\n', 1)[0];
-    const sourceURLRegex = /[\040\t]*\/\*[#@] sourceURL=[\040\t]*([^\s]*)[\040\t]*\*\/[\040\t]*$/;
-    if (sourceURLLine.search(sourceURLRegex) === -1)
-      return text;
-    return text.substr(0, sourceURLLineIndex) + text.substr(sourceURLLineIndex + sourceURLLine.length + 1);
-  }
-
-  /**
-   * @return {!SDK.DOMModel}
-   */
-  domModel() {
-    return this._domModel;
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {!TextUtils.TextRange} range
-   * @param {string} text
-   * @param {boolean} majorChange
-   * @return {!Promise<boolean>}
-   */
-  setStyleText(styleSheetId, range, text, majorChange) {
-    const original = this._innerSetStyleTexts.bind(this, [styleSheetId], [range], [text], majorChange);
-    const header = this.styleSheetHeaderForId(styleSheetId);
-    if (!header)
-      return original();
-
-    const sourceMap = this._sourceMapManager.sourceMapForClient(header);
-    if (!sourceMap)
-      return original();
-
-    const originalAndDetach = originalAndDetachIfSuccess.bind(this, header);
-
-    if (!sourceMap.editable())
-      return original();
-
-    return /** @type {!Promise<boolean>} */ (
-        sourceMap.editCompiled([range], [text]).then(onEditingDone.bind(this)).catch(onError.bind(this, header)));
-
-    /**
-     * @param {?SDK.SourceMap.EditResult} editResult
-     * @return {!Promise<boolean>}
-     * @this {SDK.CSSModel}
-     */
-    function onEditingDone(editResult) {
-      if (!editResult)
-        return Promise.resolve(false);
-
-      let edits = editResult.compiledEdits;
-      if (!edits.length)
-        return onCSSPatched.call(this, editResult, true);
-
-      edits.sort(TextUtils.SourceEdit.comparator);
-      edits = edits.reverse();
-
-      const styleSheetIds = [];
-      const ranges = [];
-      const texts = [];
-      for (const edit of edits) {
-        styleSheetIds.push(header.id);
-        ranges.push(edit.oldRange);
-        texts.push(edit.newText);
-      }
-      return this._innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange)
-          .then(onCSSPatched.bind(this, editResult));
-    }
-
-    /**
-     * @param {!SDK.SourceMap.EditResult} editResult
-     * @param {boolean} success
-     * @return {!Promise<boolean>}
-     * @this {SDK.CSSModel}
-     */
-    function onCSSPatched(editResult, success) {
-      if (!success)
-        return originalAndDetach();
-
-      this._sourceMapManager.applySourceMapEdit(editResult);
-      return Promise.resolve(true);
-    }
-
-    /**
-     * @param {!SDK.CSSStyleSheetHeader} header
-     * @param {*} error
-     * @return {!Promise<boolean>}
-     * @this {SDK.CSSModel}
-     */
-    function onError(header, error) {
-      Common.console.error(Common.UIString('LiveSASS failed: %s', sourceMap.compiledURL()));
-      console.error(error);
-      this._sourceMapManager.detachSourceMap(header);
-      return original();
-    }
-
-    /**
-     * @param {!SDK.CSSStyleSheetHeader} header
-     * @return {!Promise<boolean>}
-     * @this {SDK.CSSModel}
-     */
-    function originalAndDetachIfSuccess(header) {
-      return this._innerSetStyleTexts([styleSheetId], [range], [text], majorChange).then(detachIfSuccess.bind(this));
-
-      /**
-       * @param {boolean} success
-       * @return {boolean}
-       * @this {SDK.CSSModel}
-       */
-      function detachIfSuccess(success) {
-        if (success)
-          this._sourceMapManager.detachSourceMap(header);
-        return success;
-      }
-    }
-  }
-
-  /**
-   * @param {!Array<!Protocol.CSS.StyleSheetId>} styleSheetIds
-   * @param {!Array<!TextUtils.TextRange>} ranges
-   * @param {!Array<string>} texts
-   * @param {boolean} majorChange
-   * @return {!Promise<boolean>}
-   */
-  async _innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange) {
-    console.assert(
-        styleSheetIds.length === ranges.length && ranges.length === texts.length, 'Array lengths must be equal');
-    const edits = [];
-    const ensureContentPromises = [];
-    for (let i = 0; i < styleSheetIds.length; ++i) {
-      edits.push({styleSheetId: styleSheetIds[i], range: ranges[i].serializeToObject(), text: texts[i]});
-      ensureContentPromises.push(this._ensureOriginalStyleSheetText(styleSheetIds[i]));
-    }
-
-    try {
-      await Promise.all(ensureContentPromises);
-      const stylePayloads = await this._agent.setStyleTexts(edits);
-
-      if (!stylePayloads || stylePayloads.length !== ranges.length)
-        return false;
-
-      this._domModel.markUndoableState(!majorChange);
-      for (let i = 0; i < ranges.length; ++i) {
-        const edit = new SDK.CSSModel.Edit(styleSheetIds[i], ranges[i], texts[i], stylePayloads[i]);
-        this._fireStyleSheetChanged(styleSheetIds[i], edit);
-      }
-      return true;
-    } catch (e) {
-      return false;
-    }
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {!TextUtils.TextRange} range
-   * @param {string} text
-   * @return {!Promise<boolean>}
-   */
-  async setSelectorText(styleSheetId, range, text) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
-
-    try {
-      await this._ensureOriginalStyleSheetText(styleSheetId);
-      const selectorPayload = await this._agent.setRuleSelector(styleSheetId, range, text);
-
-      if (!selectorPayload)
-        return false;
-      this._domModel.markUndoableState();
-      const edit = new SDK.CSSModel.Edit(styleSheetId, range, text, selectorPayload);
-      this._fireStyleSheetChanged(styleSheetId, edit);
-      return true;
-    } catch (e) {
-      return false;
-    }
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {!TextUtils.TextRange} range
-   * @param {string} text
-   * @return {!Promise<boolean>}
-   */
-  async setKeyframeKey(styleSheetId, range, text) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
-
-    try {
-      await this._ensureOriginalStyleSheetText(styleSheetId);
-      const payload = await this._agent.setKeyframeKey(styleSheetId, range, text);
-
-      if (!payload)
-        return false;
-      this._domModel.markUndoableState();
-      const edit = new SDK.CSSModel.Edit(styleSheetId, range, text, payload);
-      this._fireStyleSheetChanged(styleSheetId, edit);
-      return true;
-    } catch (e) {
-      return false;
-    }
-  }
-
-  startCoverage() {
-    this._agent.startRuleUsageTracking();
-  }
-
-  /**
-   * @return {!Promise<!Array<!Protocol.CSS.RuleUsage>>}
-   */
-  takeCoverageDelta() {
-    return this._agent.takeCoverageDelta().then(ruleUsage => ruleUsage || []);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  stopCoverage() {
-    return this._agent.stopRuleUsageTracking();
-  }
-
-  /**
-   * @return {!Promise<!Array<!SDK.CSSMedia>>}
-   */
-  async mediaQueriesPromise() {
-    const payload = await this._agent.getMediaQueries();
-    return payload ? SDK.CSSMedia.parseMediaArrayPayload(this, payload) : [];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEnabled() {
-    return this._isEnabled;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async _enable() {
-    await this._agent.enable();
-    this._isEnabled = true;
-    this.dispatchEventToListeners(SDK.CSSModel.Events.ModelWasEnabled);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @return {!Promise<?SDK.CSSMatchedStyles>}
-   */
-  async matchedStylesPromise(nodeId) {
-    const response = await this._agent.invoke_getMatchedStylesForNode({nodeId});
-
-    if (response[Protocol.Error])
-      return null;
-
-    const node = this._domModel.nodeForId(nodeId);
-    if (!node)
-      return null;
-
-    return new SDK.CSSMatchedStyles(
-        this, /** @type {!SDK.DOMNode} */ (node), response.inlineStyle || null, response.attributesStyle || null,
-        response.matchedCSSRules || [], response.pseudoElements || [], response.inherited || [],
-        response.cssKeyframesRules || []);
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @return {!Promise<!Array<string>>}
-   */
-  classNamesPromise(styleSheetId) {
-    return this._agent.collectClassNames(styleSheetId).then(classNames => classNames || []);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @return {!Promise<?Map<string, string>>}
-   */
-  computedStylePromise(nodeId) {
-    return this._styleLoader.computedStylePromise(nodeId);
-  }
-
-  /**
-   * @param {number} nodeId
-   * @return {!Promise<?SDK.CSSModel.ContrastInfo>}
-   */
-  async backgroundColorsPromise(nodeId) {
-    const response = this._agent.invoke_getBackgroundColors({nodeId});
-    if (response[Protocol.Error])
-      return null;
-
-    return response;
-  }
-
-  /**
-   * @param {number} nodeId
-   * @return {!Promise<?Array<!Protocol.CSS.PlatformFontUsage>>}
-   */
-  platformFontsPromise(nodeId) {
-    return this._agent.getPlatformFontsForNode(nodeId);
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSStyleSheetHeader>}
-   */
-  allStyleSheets() {
-    const values = this._styleSheetIdToHeader.valuesArray();
-    /**
-     * @param {!SDK.CSSStyleSheetHeader} a
-     * @param {!SDK.CSSStyleSheetHeader} b
-     * @return {number}
-     */
-    function styleSheetComparator(a, b) {
-      if (a.sourceURL < b.sourceURL)
-        return -1;
-      else if (a.sourceURL > b.sourceURL)
-        return 1;
-      return a.startLine - b.startLine || a.startColumn - b.startColumn;
-    }
-    values.sort(styleSheetComparator);
-
-    return values;
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @return {!Promise<?SDK.CSSModel.InlineStyleResult>}
-   */
-  async inlineStylesPromise(nodeId) {
-    const response = await this._agent.invoke_getInlineStylesForNode({nodeId});
-
-    if (response[Protocol.Error] || !response.inlineStyle)
-      return null;
-    const inlineStyle =
-        new SDK.CSSStyleDeclaration(this, null, response.inlineStyle, SDK.CSSStyleDeclaration.Type.Inline);
-    const attributesStyle = response.attributesStyle ?
-        new SDK.CSSStyleDeclaration(this, null, response.attributesStyle, SDK.CSSStyleDeclaration.Type.Attributes) :
-        null;
-    return new SDK.CSSModel.InlineStyleResult(inlineStyle, attributesStyle);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {string} pseudoClass
-   * @param {boolean} enable
-   * @return {boolean}
-   */
-  forcePseudoState(node, pseudoClass, enable) {
-    const pseudoClasses = node.marker(SDK.CSSModel.PseudoStateMarker) || [];
-    if (enable) {
-      if (pseudoClasses.indexOf(pseudoClass) >= 0)
-        return false;
-      pseudoClasses.push(pseudoClass);
-      node.setMarker(SDK.CSSModel.PseudoStateMarker, pseudoClasses);
-    } else {
-      if (pseudoClasses.indexOf(pseudoClass) < 0)
-        return false;
-      pseudoClasses.remove(pseudoClass);
-      if (pseudoClasses.length)
-        node.setMarker(SDK.CSSModel.PseudoStateMarker, pseudoClasses);
-      else
-        node.setMarker(SDK.CSSModel.PseudoStateMarker, null);
-    }
-
-    this._agent.forcePseudoState(node.id, pseudoClasses);
-    this.dispatchEventToListeners(
-        SDK.CSSModel.Events.PseudoStateForced, {node: node, pseudoClass: pseudoClass, enable: enable});
-    return true;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {?Array<string>} state
-   */
-  pseudoState(node) {
-    return node.marker(SDK.CSSModel.PseudoStateMarker) || [];
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {!TextUtils.TextRange} range
-   * @param {string} newMediaText
-   * @return {!Promise<boolean>}
-   */
-  async setMediaText(styleSheetId, range, newMediaText) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
-
-    try {
-      await this._ensureOriginalStyleSheetText(styleSheetId);
-      const mediaPayload = await this._agent.setMediaText(styleSheetId, range, newMediaText);
-
-      if (!mediaPayload)
-        return false;
-      this._domModel.markUndoableState();
-      const edit = new SDK.CSSModel.Edit(styleSheetId, range, newMediaText, mediaPayload);
-      this._fireStyleSheetChanged(styleSheetId, edit);
-      return true;
-    } catch (e) {
-      return false;
-    }
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {string} ruleText
-   * @param {!TextUtils.TextRange} ruleLocation
-   * @return {!Promise<?SDK.CSSStyleRule>}
-   */
-  async addRule(styleSheetId, ruleText, ruleLocation) {
-    try {
-      await this._ensureOriginalStyleSheetText(styleSheetId);
-      const rulePayload = await this._agent.addRule(styleSheetId, ruleText, ruleLocation);
-
-      if (!rulePayload)
-        return null;
-      this._domModel.markUndoableState();
-      const edit = new SDK.CSSModel.Edit(styleSheetId, ruleLocation, ruleText, rulePayload);
-      this._fireStyleSheetChanged(styleSheetId, edit);
-      return new SDK.CSSStyleRule(this, rulePayload);
-    } catch (e) {
-      return null;
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise<?SDK.CSSStyleSheetHeader>}
-   */
-  async requestViaInspectorStylesheet(node) {
-    const frameId = node.frameId() || (this._resourceTreeModel ? this._resourceTreeModel.mainFrame.id : '');
-    const headers = this._styleSheetIdToHeader.valuesArray();
-    const styleSheetHeader = headers.find(header => header.frameId === frameId && header.isViaInspector());
-    if (styleSheetHeader)
-      return styleSheetHeader;
-
-    try {
-      const styleSheetId = await this._agent.createStyleSheet(frameId);
-      return styleSheetId && this._styleSheetIdToHeader.get(styleSheetId) || null;
-    } catch (e) {
-      return null;
-    }
-  }
-
-  mediaQueryResultChanged() {
-    this.dispatchEventToListeners(SDK.CSSModel.Events.MediaQueryResultChanged);
-  }
-
-  fontsUpdated() {
-    this.dispatchEventToListeners(SDK.CSSModel.Events.FontsUpdated);
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} id
-   * @return {?SDK.CSSStyleSheetHeader}
-   */
-  styleSheetHeaderForId(id) {
-    return this._styleSheetIdToHeader.get(id) || null;
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSStyleSheetHeader>}
-   */
-  styleSheetHeaders() {
-    return this._styleSheetIdToHeader.valuesArray();
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {!SDK.CSSModel.Edit=} edit
-   */
-  _fireStyleSheetChanged(styleSheetId, edit) {
-    this.dispatchEventToListeners(SDK.CSSModel.Events.StyleSheetChanged, {styleSheetId: styleSheetId, edit: edit});
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @return {!Promise<?string>}
-   */
-  _ensureOriginalStyleSheetText(styleSheetId) {
-    const header = this.styleSheetHeaderForId(styleSheetId);
-    if (!header)
-      return Promise.resolve(/** @type {?string} */ (null));
-    let promise = this._originalStyleSheetText.get(header);
-    if (!promise) {
-      promise = this.getStyleSheetText(header.id);
-      this._originalStyleSheetText.set(header, promise);
-      this._originalContentRequestedForTest(header);
-    }
-    return promise;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   */
-  _originalContentRequestedForTest(header) {
-  }
-
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   * @return {!Promise<?string>}
-   */
-  originalStyleSheetText(header) {
-    return this._ensureOriginalStyleSheetText(header.id);
-  }
-
-  /**
-   * @param {!Protocol.CSS.CSSStyleSheetHeader} header
-   */
-  _styleSheetAdded(header) {
-    console.assert(!this._styleSheetIdToHeader.get(header.styleSheetId));
-    const styleSheetHeader = new SDK.CSSStyleSheetHeader(this, header);
-    this._styleSheetIdToHeader.set(header.styleSheetId, styleSheetHeader);
-    const url = styleSheetHeader.resourceURL();
-    if (!this._styleSheetIdsForURL.get(url))
-      this._styleSheetIdsForURL.set(url, {});
-    const frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
-    let styleSheetIds = frameIdToStyleSheetIds[styleSheetHeader.frameId];
-    if (!styleSheetIds) {
-      styleSheetIds = [];
-      frameIdToStyleSheetIds[styleSheetHeader.frameId] = styleSheetIds;
-    }
-    styleSheetIds.push(styleSheetHeader.id);
-    this._sourceMapManager.attachSourceMap(styleSheetHeader, styleSheetHeader.sourceURL, styleSheetHeader.sourceMapURL);
-    this.dispatchEventToListeners(SDK.CSSModel.Events.StyleSheetAdded, styleSheetHeader);
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} id
-   */
-  _styleSheetRemoved(id) {
-    const header = this._styleSheetIdToHeader.get(id);
-    console.assert(header);
-    if (!header)
-      return;
-    this._styleSheetIdToHeader.remove(id);
-    const url = header.resourceURL();
-    const frameIdToStyleSheetIds =
-        /** @type {!Object.<!Protocol.Page.FrameId, !Array.<!Protocol.CSS.StyleSheetId>>} */ (
-            this._styleSheetIdsForURL.get(url));
-    console.assert(frameIdToStyleSheetIds, 'No frameId to styleSheetId map is available for given style sheet URL.');
-    frameIdToStyleSheetIds[header.frameId].remove(id);
-    if (!frameIdToStyleSheetIds[header.frameId].length) {
-      delete frameIdToStyleSheetIds[header.frameId];
-      if (!Object.keys(frameIdToStyleSheetIds).length)
-        this._styleSheetIdsForURL.remove(url);
-    }
-    this._originalStyleSheetText.remove(header);
-    this._sourceMapManager.detachSourceMap(header);
-    this.dispatchEventToListeners(SDK.CSSModel.Events.StyleSheetRemoved, header);
-  }
-
-  /**
-   * @param {string} url
-   * @return {!Array.<!Protocol.CSS.StyleSheetId>}
-   */
-  styleSheetIdsForURL(url) {
-    const frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
-    if (!frameIdToStyleSheetIds)
-      return [];
-
-    let result = [];
-    for (const frameId in frameIdToStyleSheetIds)
-      result = result.concat(frameIdToStyleSheetIds[frameId]);
-    return result;
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {string} newText
-   * @param {boolean} majorChange
-   * @return {!Promise<?string>}
-   */
-  async setStyleSheetText(styleSheetId, newText, majorChange) {
-    const header = /** @type {!SDK.CSSStyleSheetHeader} */ (this._styleSheetIdToHeader.get(styleSheetId));
-    console.assert(header);
-    newText = SDK.CSSModel.trimSourceURL(newText);
-    if (header.hasSourceURL)
-      newText += '\n/*# sourceURL=' + header.sourceURL + ' */';
-
-    await this._ensureOriginalStyleSheetText(styleSheetId);
-    const response = await this._agent.invoke_setStyleSheetText({styleSheetId: header.id, text: newText});
-    const sourceMapURL = response.sourceMapURL;
-
-    this._sourceMapManager.detachSourceMap(header);
-    header.setSourceMapURL(sourceMapURL);
-    this._sourceMapManager.attachSourceMap(header, header.sourceURL, header.sourceMapURL);
-    if (sourceMapURL === null)
-      return 'Error in CSS.setStyleSheetText';
-    this._domModel.markUndoableState(!majorChange);
-    this._fireStyleSheetChanged(styleSheetId);
-    return null;
-  }
-
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @return {!Promise<?string>}
-   */
-  async getStyleSheetText(styleSheetId) {
-    try {
-      const text = await this._agent.getStyleSheetText(styleSheetId);
-      return text && SDK.CSSModel.trimSourceURL(text);
-    } catch (e) {
-      return null;
-    }
-  }
-
-  _resetStyleSheets() {
-    const headers = this._styleSheetIdToHeader.valuesArray();
-    this._styleSheetIdsForURL.clear();
-    this._styleSheetIdToHeader.clear();
-    for (let i = 0; i < headers.length; ++i) {
-      this._sourceMapManager.detachSourceMap(headers[i]);
-      this.dispatchEventToListeners(SDK.CSSModel.Events.StyleSheetRemoved, headers[i]);
-    }
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  suspendModel() {
-    this._isEnabled = false;
-    return this._agent.disable().then(this._resetStyleSheets.bind(this));
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  async resumeModel() {
-    return this._enable();
-  }
-
-  /**
-   * @param {number} nodeId
-   * @param {string} name
-   * @param {string} value
-   */
-  setEffectivePropertyValueForNode(nodeId, name, value) {
-    this._agent.setEffectivePropertyValueForNode(nodeId, name, value);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {!Promise.<?SDK.CSSMatchedStyles>}
-   */
-  cachedMatchedCascadeForNode(node) {
-    if (this._cachedMatchedCascadeNode !== node)
-      this.discardCachedMatchedCascade();
-    this._cachedMatchedCascadeNode = node;
-    if (!this._cachedMatchedCascadePromise)
-      this._cachedMatchedCascadePromise = this.matchedStylesPromise(node.id);
-    return this._cachedMatchedCascadePromise;
-  }
-
-  discardCachedMatchedCascade() {
-    delete this._cachedMatchedCascadeNode;
-    delete this._cachedMatchedCascadePromise;
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    super.dispose();
-    this._sourceMapManager.dispose();
-  }
-};
-
-SDK.SDKModel.register(SDK.CSSModel, SDK.Target.Capability.DOM, true);
-
-/** @typedef {!{range: !Protocol.CSS.SourceRange, styleSheetId: !Protocol.CSS.StyleSheetId, wasUsed: boolean}} */
-SDK.CSSModel.RuleUsage;
-
-/** @typedef {{backgroundColors: ?Array<string>, computedFontSize: string, computedFontWeights: string, computedBodyFontSize: string}} */
-SDK.CSSModel.ContrastInfo;
-
-/** @enum {symbol} */
-SDK.CSSModel.Events = {
-  FontsUpdated: Symbol('FontsUpdated'),
-  MediaQueryResultChanged: Symbol('MediaQueryResultChanged'),
-  ModelWasEnabled: Symbol('ModelWasEnabled'),
-  PseudoStateForced: Symbol('PseudoStateForced'),
-  StyleSheetAdded: Symbol('StyleSheetAdded'),
-  StyleSheetChanged: Symbol('StyleSheetChanged'),
-  StyleSheetRemoved: Symbol('StyleSheetRemoved')
-};
-
-SDK.CSSModel.MediaTypes =
-    ['all', 'braille', 'embossed', 'handheld', 'print', 'projection', 'screen', 'speech', 'tty', 'tv'];
-
-SDK.CSSModel.PseudoStateMarker = 'pseudo-state-marker';
-
-/**
- * @unrestricted
- */
-SDK.CSSModel.Edit = class {
-  /**
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   * @param {!TextUtils.TextRange} oldRange
-   * @param {string} newText
-   * @param {?Object} payload
-   */
-  constructor(styleSheetId, oldRange, newText, payload) {
-    this.styleSheetId = styleSheetId;
-    this.oldRange = oldRange;
-    this.newRange = TextUtils.TextRange.fromEdit(oldRange, newText);
-    this.newText = newText;
-    this.payload = payload;
-  }
-};
-
-SDK.CSSLocation = class {
-  /**
-   * @param {!SDK.CSSStyleSheetHeader} header
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   */
-  constructor(header, lineNumber, columnNumber) {
-    this._cssModel = header.cssModel();
-    this.styleSheetId = header.id;
-    this.url = header.resourceURL();
-    this.lineNumber = lineNumber;
-    this.columnNumber = columnNumber || 0;
-  }
-
-  /**
-   * @return {!SDK.CSSModel}
-   */
-  cssModel() {
-    return this._cssModel;
-  }
-
-  /**
-   * @return {?SDK.CSSStyleSheetHeader}
-   */
-  header() {
-    return this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-  }
-};
-
-/**
- * @implements {Protocol.CSSDispatcher}
- * @unrestricted
- */
-SDK.CSSDispatcher = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   */
-  constructor(cssModel) {
-    this._cssModel = cssModel;
-  }
-
-  /**
-   * @override
-   */
-  mediaQueryResultChanged() {
-    this._cssModel.mediaQueryResultChanged();
-  }
-
-  /**
-   * @override
-   */
-  fontsUpdated() {
-    this._cssModel.fontsUpdated();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.CSS.StyleSheetId} styleSheetId
-   */
-  styleSheetChanged(styleSheetId) {
-    this._cssModel._fireStyleSheetChanged(styleSheetId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.CSS.CSSStyleSheetHeader} header
-   */
-  styleSheetAdded(header) {
-    this._cssModel._styleSheetAdded(header);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.CSS.StyleSheetId} id
-   */
-  styleSheetRemoved(id) {
-    this._cssModel._styleSheetRemoved(id);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CSSModel.ComputedStyleLoader = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   */
-  constructor(cssModel) {
-    this._cssModel = cssModel;
-    /** @type {!Map<!Protocol.DOM.NodeId, !Promise<?Map<string, string>>>} */
-    this._nodeIdToPromise = new Map();
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @return {!Promise<?Map<string, string>>}
-   */
-  computedStylePromise(nodeId) {
-    let promise = this._nodeIdToPromise.get(nodeId);
-    if (promise)
-      return promise;
-    promise = this._cssModel._agent.getComputedStyleForNode(nodeId).then(parsePayload.bind(this));
-    this._nodeIdToPromise.set(nodeId, promise);
-    return promise;
-
-    /**
-     * @param {?Array<!Protocol.CSS.CSSComputedStyleProperty>} computedPayload
-     * @return {?Map<string, string>}
-     * @this {SDK.CSSModel.ComputedStyleLoader}
-     */
-    function parsePayload(computedPayload) {
-      this._nodeIdToPromise.delete(nodeId);
-      if (!computedPayload || !computedPayload.length)
-        return null;
-      const result = new Map();
-      for (const property of computedPayload)
-        result.set(property.name, property.value);
-      return result;
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CSSModel.InlineStyleResult = class {
-  /**
-   * @param {?SDK.CSSStyleDeclaration} inlineStyle
-   * @param {?SDK.CSSStyleDeclaration} attributesStyle
-   */
-  constructor(inlineStyle, attributesStyle) {
-    this.inlineStyle = inlineStyle;
-    this.attributesStyle = attributesStyle;
-  }
-};
diff --git a/front_end/sdk/CSSProperty.js b/front_end/sdk/CSSProperty.js
deleted file mode 100644
index 552d531..0000000
--- a/front_end/sdk/CSSProperty.js
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.CSSProperty = class {
-  /**
-   * @param {!SDK.CSSStyleDeclaration} ownerStyle
-   * @param {number} index
-   * @param {string} name
-   * @param {string} value
-   * @param {boolean} important
-   * @param {boolean} disabled
-   * @param {boolean} parsedOk
-   * @param {boolean} implicit
-   * @param {?string=} text
-   * @param {!Protocol.CSS.SourceRange=} range
-   */
-  constructor(ownerStyle, index, name, value, important, disabled, parsedOk, implicit, text, range) {
-    this.ownerStyle = ownerStyle;
-    this.index = index;
-    this.name = name;
-    this.value = value;
-    this.important = important;
-    this.disabled = disabled;
-    this.parsedOk = parsedOk;
-    this.implicit = implicit;  // A longhand, implicitly set by missing values of shorthand.
-    this.text = text;
-    this.range = range ? TextUtils.TextRange.fromObject(range) : null;
-    this._active = true;
-    this._nameRange = null;
-    this._valueRange = null;
-  }
-
-  /**
-   * @param {!SDK.CSSStyleDeclaration} ownerStyle
-   * @param {number} index
-   * @param {!Protocol.CSS.CSSProperty} payload
-   * @return {!SDK.CSSProperty}
-   */
-  static parsePayload(ownerStyle, index, payload) {
-    // The following default field values are used in the payload:
-    // important: false
-    // parsedOk: true
-    // implicit: false
-    // disabled: false
-    const result = new SDK.CSSProperty(
-        ownerStyle, index, payload.name, payload.value, payload.important || false, payload.disabled || false,
-        ('parsedOk' in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text, payload.range);
-    return result;
-  }
-
-  _ensureRanges() {
-    if (this._nameRange && this._valueRange)
-      return;
-    const range = this.range;
-    const text = this.text ? new TextUtils.Text(this.text) : null;
-    if (!range || !text)
-      return;
-
-    const nameIndex = text.value().indexOf(this.name);
-    const valueIndex = text.value().lastIndexOf(this.value);
-    if (nameIndex === -1 || valueIndex === -1 || nameIndex > valueIndex)
-      return;
-
-    const nameSourceRange = new TextUtils.SourceRange(nameIndex, this.name.length);
-    const valueSourceRange = new TextUtils.SourceRange(valueIndex, this.value.length);
-
-    this._nameRange = rebase(text.toTextRange(nameSourceRange), range.startLine, range.startColumn);
-    this._valueRange = rebase(text.toTextRange(valueSourceRange), range.startLine, range.startColumn);
-
-    /**
-     * @param {!TextUtils.TextRange} oneLineRange
-     * @param {number} lineOffset
-     * @param {number} columnOffset
-     * @return {!TextUtils.TextRange}
-     */
-    function rebase(oneLineRange, lineOffset, columnOffset) {
-      if (oneLineRange.startLine === 0) {
-        oneLineRange.startColumn += columnOffset;
-        oneLineRange.endColumn += columnOffset;
-      }
-      oneLineRange.startLine += lineOffset;
-      oneLineRange.endLine += lineOffset;
-      return oneLineRange;
-    }
-  }
-
-  /**
-   * @return {?TextUtils.TextRange}
-   */
-  nameRange() {
-    this._ensureRanges();
-    return this._nameRange;
-  }
-
-  /**
-   * @return {?TextUtils.TextRange}
-   */
-  valueRange() {
-    this._ensureRanges();
-    return this._valueRange;
-  }
-
-  /**
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (this.ownerStyle.styleSheetId !== edit.styleSheetId)
-      return;
-    if (this.range)
-      this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
-  }
-
-  /**
-   * @param {boolean} active
-   */
-  setActive(active) {
-    this._active = active;
-  }
-
-  get propertyText() {
-    if (this.text !== undefined)
-      return this.text;
-
-    if (this.name === '')
-      return '';
-    return this.name + ': ' + this.value + (this.important ? ' !important' : '') + ';';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  activeInStyle() {
-    return this._active;
-  }
-
-  /**
-   * @param {string} propertyText
-   * @param {boolean} majorChange
-   * @param {boolean=} overwrite
-   * @return {!Promise.<boolean>}
-   */
-  setText(propertyText, majorChange, overwrite) {
-    if (!this.ownerStyle)
-      return Promise.reject(new Error('No ownerStyle for property'));
-
-    if (!this.ownerStyle.styleSheetId)
-      return Promise.reject(new Error('No owner style id'));
-
-    if (!this.range || !this.ownerStyle.range)
-      return Promise.reject(new Error('Style not editable'));
-
-    if (majorChange)
-      Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
-
-    if (overwrite && propertyText === this.propertyText) {
-      this.ownerStyle.cssModel().domModel().markUndoableState(!majorChange);
-      return Promise.resolve(true);
-    }
-
-    const range = this.range.relativeTo(this.ownerStyle.range.startLine, this.ownerStyle.range.startColumn);
-    const indentation = this.ownerStyle.cssText ? this._detectIndentation(this.ownerStyle.cssText) :
-                                                  Common.moduleSetting('textEditorIndent').get();
-    const endIndentation = this.ownerStyle.cssText ? indentation.substring(0, this.ownerStyle.range.endColumn) : '';
-    const text = new TextUtils.Text(this.ownerStyle.cssText || '');
-    const newStyleText = text.replaceRange(range, String.sprintf(';%s;', propertyText));
-
-    return self.runtime.extension(TextUtils.TokenizerFactory)
-        .instance()
-        .then(this._formatStyle.bind(this, newStyleText, indentation, endIndentation))
-        .then(setStyleText.bind(this));
-
-    /**
-     * @param {string} styleText
-     * @this {SDK.CSSProperty}
-     * @return {!Promise.<boolean>}
-     */
-    function setStyleText(styleText) {
-      return this.ownerStyle.setText(styleText, majorChange);
-    }
-  }
-
-  /**
-   * @param {string} styleText
-   * @param {string} indentation
-   * @param {string} endIndentation
-   * @param {!TextUtils.TokenizerFactory} tokenizerFactory
-   * @return {string}
-   */
-  _formatStyle(styleText, indentation, endIndentation, tokenizerFactory) {
-    if (indentation)
-      indentation = '\n' + indentation;
-    let result = '';
-    let propertyText;
-    let insideProperty = false;
-    const tokenize = tokenizerFactory.createTokenizer('text/css');
-
-    tokenize('*{' + styleText + '}', processToken);
-    if (insideProperty)
-      result += propertyText;
-    result = result.substring(2, result.length - 1).trimRight();
-    return result + (indentation ? '\n' + endIndentation : '');
-
-    /**
-     * @param {string} token
-     * @param {?string} tokenType
-     * @param {number} column
-     * @param {number} newColumn
-     */
-    function processToken(token, tokenType, column, newColumn) {
-      if (!insideProperty) {
-        const disabledProperty = tokenType && tokenType.includes('css-comment') && isDisabledProperty(token);
-        const isPropertyStart = tokenType &&
-            (tokenType.includes('css-string') || tokenType.includes('css-meta') || tokenType.includes('css-property') ||
-             tokenType.includes('css-variable-2'));
-        if (disabledProperty) {
-          result = result.trimRight() + indentation + token;
-        } else if (isPropertyStart) {
-          insideProperty = true;
-          propertyText = token;
-        } else if (token !== ';') {
-          result += token;
-        }
-        return;
-      }
-
-      if (token === '}' || token === ';') {
-        result = result.trimRight() + indentation + propertyText.trim() + ';';
-        insideProperty = false;
-        if (token === '}')
-          result += '}';
-      } else {
-        propertyText += token;
-      }
-    }
-
-    /**
-     * @param {string} text
-     * @return {boolean}
-     */
-    function isDisabledProperty(text) {
-      const colon = text.indexOf(':');
-      if (colon === -1)
-        return false;
-      const propertyName = text.substring(2, colon).trim();
-      return SDK.cssMetadata().isCSSPropertyName(propertyName);
-    }
-  }
-
-  /**
-   * @param {string} text
-   * @return {string}
-   */
-  _detectIndentation(text) {
-    const lines = text.split('\n');
-    if (lines.length < 2)
-      return '';
-    return TextUtils.TextUtils.lineIndent(lines[1]);
-  }
-
-  /**
-   * @param {string} newValue
-   * @param {boolean} majorChange
-   * @param {boolean} overwrite
-   * @param {function(boolean)=} userCallback
-   */
-  setValue(newValue, majorChange, overwrite, userCallback) {
-    const text = this.name + ': ' + newValue + (this.important ? ' !important' : '') + ';';
-    this.setText(text, majorChange, overwrite).then(userCallback);
-  }
-
-  /**
-   * @param {boolean} disabled
-   * @return {!Promise.<boolean>}
-   */
-  setDisabled(disabled) {
-    if (!this.ownerStyle)
-      return Promise.resolve(false);
-    if (disabled === this.disabled)
-      return Promise.resolve(true);
-    const propertyText = this.text.trim();
-    const text = disabled ? '/* ' + propertyText + ' */' : this.text.substring(2, propertyText.length - 2).trim();
-    return this.setText(text, true, true);
-  }
-};
diff --git a/front_end/sdk/CSSRule.js b/front_end/sdk/CSSRule.js
deleted file mode 100644
index bb866f9..0000000
--- a/front_end/sdk/CSSRule.js
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.CSSValue = class {
-  /**
-   * @param {!Protocol.CSS.Value} payload
-   */
-  constructor(payload) {
-    this.text = payload.text;
-    if (payload.range)
-      this.range = TextUtils.TextRange.fromObject(payload.range);
-  }
-
-  /**
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (!this.range)
-      return;
-    this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CSSRule = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {{style: !Protocol.CSS.CSSStyle, styleSheetId: (string|undefined), origin: !Protocol.CSS.StyleSheetOrigin}} payload
-   */
-  constructor(cssModel, payload) {
-    this._cssModel = cssModel;
-    this.styleSheetId = payload.styleSheetId;
-
-    if (this.styleSheetId) {
-      const styleSheetHeader = cssModel.styleSheetHeaderForId(this.styleSheetId);
-      this.sourceURL = styleSheetHeader.sourceURL;
-    }
-    this.origin = payload.origin;
-    this.style = new SDK.CSSStyleDeclaration(this._cssModel, this, payload.style, SDK.CSSStyleDeclaration.Type.Regular);
-  }
-
-  /**
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (this.styleSheetId !== edit.styleSheetId)
-      return;
-    this.style.rebase(edit);
-  }
-
-  /**
-   * @return {string}
-   */
-  resourceURL() {
-    if (!this.styleSheetId)
-      return '';
-    const styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-    return styleSheetHeader.resourceURL();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isUserAgent() {
-    return this.origin === Protocol.CSS.StyleSheetOrigin.UserAgent;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInjected() {
-    return this.origin === Protocol.CSS.StyleSheetOrigin.Injected;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isViaInspector() {
-    return this.origin === Protocol.CSS.StyleSheetOrigin.Inspector;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRegular() {
-    return this.origin === Protocol.CSS.StyleSheetOrigin.Regular;
-  }
-
-  /**
-   * @return {!SDK.CSSModel}
-   */
-  cssModel() {
-    return this._cssModel;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CSSStyleRule = class extends SDK.CSSRule {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Protocol.CSS.CSSRule} payload
-   * @param {boolean=} wasUsed
-   */
-  constructor(cssModel, payload, wasUsed) {
-    super(cssModel, payload);
-
-    this._reinitializeSelectors(payload.selectorList);
-    this.media = payload.media ? SDK.CSSMedia.parseMediaArrayPayload(cssModel, payload.media) : [];
-    this.wasUsed = wasUsed || false;
-  }
-
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {string} selectorText
-   * @return {!SDK.CSSStyleRule}
-   */
-  static createDummyRule(cssModel, selectorText) {
-    const dummyPayload = {
-      selectorList: {
-        selectors: [{text: selectorText}],
-      },
-      style: {styleSheetId: '0', range: new TextUtils.TextRange(0, 0, 0, 0), shorthandEntries: [], cssProperties: []}
-    };
-    return new SDK.CSSStyleRule(cssModel, /** @type {!Protocol.CSS.CSSRule} */ (dummyPayload));
-  }
-
-  /**
-   * @param {!Protocol.CSS.SelectorList} selectorList
-   */
-  _reinitializeSelectors(selectorList) {
-    /** @type {!Array.<!SDK.CSSValue>} */
-    this.selectors = [];
-    for (let i = 0; i < selectorList.selectors.length; ++i)
-      this.selectors.push(new SDK.CSSValue(selectorList.selectors[i]));
-  }
-
-  /**
-   * @param {string} newSelector
-   * @return {!Promise.<boolean>}
-   */
-  setSelectorText(newSelector) {
-    const styleSheetId = this.styleSheetId;
-    if (!styleSheetId)
-      throw 'No rule stylesheet id';
-    const range = this.selectorRange();
-    if (!range)
-      throw 'Rule selector is not editable';
-    return this._cssModel.setSelectorText(styleSheetId, range, newSelector);
-  }
-
-  /**
-   * @return {string}
-   */
-  selectorText() {
-    return this.selectors.select('text').join(', ');
-  }
-
-  /**
-   * @return {?TextUtils.TextRange}
-   */
-  selectorRange() {
-    const firstRange = this.selectors[0].range;
-    if (!firstRange)
-      return null;
-    const lastRange = this.selectors.peekLast().range;
-    return new TextUtils.TextRange(
-        firstRange.startLine, firstRange.startColumn, lastRange.endLine, lastRange.endColumn);
-  }
-
-  /**
-   * @param {number} selectorIndex
-   * @return {number}
-   */
-  lineNumberInSource(selectorIndex) {
-    const selector = this.selectors[selectorIndex];
-    if (!selector || !selector.range || !this.styleSheetId)
-      return 0;
-    const styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-    return styleSheetHeader.lineNumberInSource(selector.range.startLine);
-  }
-
-  /**
-   * @param {number} selectorIndex
-   * @return {number|undefined}
-   */
-  columnNumberInSource(selectorIndex) {
-    const selector = this.selectors[selectorIndex];
-    if (!selector || !selector.range || !this.styleSheetId)
-      return undefined;
-    const styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
-    console.assert(styleSheetHeader);
-    return styleSheetHeader.columnNumberInSource(selector.range.startLine, selector.range.startColumn);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (this.styleSheetId !== edit.styleSheetId)
-      return;
-    if (this.selectorRange().equal(edit.oldRange)) {
-      this._reinitializeSelectors(/** @type {!Protocol.CSS.SelectorList} */ (edit.payload));
-    } else {
-      for (let i = 0; i < this.selectors.length; ++i)
-        this.selectors[i].rebase(edit);
-    }
-    for (const media of this.media)
-      media.rebase(edit);
-
-    super.rebase(edit);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SDK.CSSKeyframesRule = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Protocol.CSS.CSSKeyframesRule} payload
-   */
-  constructor(cssModel, payload) {
-    this._cssModel = cssModel;
-    this._animationName = new SDK.CSSValue(payload.animationName);
-    this._keyframes = payload.keyframes.map(keyframeRule => new SDK.CSSKeyframeRule(cssModel, keyframeRule));
-  }
-
-  /**
-   * @return {!SDK.CSSValue}
-   */
-  name() {
-    return this._animationName;
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSKeyframeRule>}
-   */
-  keyframes() {
-    return this._keyframes;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CSSKeyframeRule = class extends SDK.CSSRule {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Protocol.CSS.CSSKeyframeRule} payload
-   */
-  constructor(cssModel, payload) {
-    super(cssModel, payload);
-    this._reinitializeKey(payload.keyText);
-  }
-
-  /**
-   * @return {!SDK.CSSValue}
-   */
-  key() {
-    return this._keyText;
-  }
-
-  /**
-   * @param {!Protocol.CSS.Value} payload
-   */
-  _reinitializeKey(payload) {
-    this._keyText = new SDK.CSSValue(payload);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (this.styleSheetId !== edit.styleSheetId || !this._keyText.range)
-      return;
-    if (edit.oldRange.equal(this._keyText.range))
-      this._reinitializeKey(/** @type {!Protocol.CSS.Value} */ (edit.payload));
-    else
-      this._keyText.rebase(edit);
-
-    super.rebase(edit);
-  }
-
-  /**
-   * @param {string} newKeyText
-   * @return {!Promise.<boolean>}
-   */
-  setKeyText(newKeyText) {
-    const styleSheetId = this.styleSheetId;
-    if (!styleSheetId)
-      throw 'No rule stylesheet id';
-    const range = this._keyText.range;
-    if (!range)
-      throw 'Keyframe key is not editable';
-    return this._cssModel.setKeyframeKey(styleSheetId, range, newKeyText);
-  }
-};
diff --git a/front_end/sdk/CSSStyleDeclaration.js b/front_end/sdk/CSSStyleDeclaration.js
deleted file mode 100644
index 2692bdf..0000000
--- a/front_end/sdk/CSSStyleDeclaration.js
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-SDK.CSSStyleDeclaration = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {?SDK.CSSRule} parentRule
-   * @param {!Protocol.CSS.CSSStyle} payload
-   * @param {!SDK.CSSStyleDeclaration.Type} type
-   */
-  constructor(cssModel, parentRule, payload, type) {
-    this._cssModel = cssModel;
-    this.parentRule = parentRule;
-    /** @type {!Array<!SDK.CSSProperty>} */
-    this._allProperties;
-    /** @type {string|undefined} */
-    this.styleSheetId;
-    /** @type {?TextUtils.TextRange} */
-    this.range;
-    /** @type {string|undefined} */
-    this.cssText;
-    /** @type {!Map<string, string>} */
-    this._shorthandValues;
-    /** @type {!Set<string>} */
-    this._shorthandIsImportant;
-    /** @type {!Map<string, !SDK.CSSProperty>} */
-    this._activePropertyMap;
-    /** @type {?Array<!SDK.CSSProperty>} */
-    this._leadingProperties;
-    this._reinitialize(payload);
-    this.type = type;
-  }
-
-  /**
-   * @param {!SDK.CSSModel.Edit} edit
-   */
-  rebase(edit) {
-    if (this.styleSheetId !== edit.styleSheetId || !this.range)
-      return;
-    if (edit.oldRange.equal(this.range)) {
-      this._reinitialize(/** @type {!Protocol.CSS.CSSStyle} */ (edit.payload));
-    } else {
-      this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange);
-      for (let i = 0; i < this._allProperties.length; ++i)
-        this._allProperties[i].rebase(edit);
-    }
-  }
-
-  /**
-   * @param {!Protocol.CSS.CSSStyle} payload
-   */
-  _reinitialize(payload) {
-    this.styleSheetId = payload.styleSheetId;
-    this.range = payload.range ? TextUtils.TextRange.fromObject(payload.range) : null;
-
-    const shorthandEntries = payload.shorthandEntries;
-    this._shorthandValues = new Map();
-    this._shorthandIsImportant = new Set();
-    for (let i = 0; i < shorthandEntries.length; ++i) {
-      this._shorthandValues.set(shorthandEntries[i].name, shorthandEntries[i].value);
-      if (shorthandEntries[i].important)
-        this._shorthandIsImportant.add(shorthandEntries[i].name);
-    }
-
-    this._allProperties = [];
-    for (let i = 0; i < payload.cssProperties.length; ++i) {
-      const property = SDK.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
-      this._allProperties.push(property);
-    }
-
-    this._generateSyntheticPropertiesIfNeeded();
-    this._computeInactiveProperties();
-
-    this._activePropertyMap = new Map();
-    for (const property of this._allProperties) {
-      if (!property.activeInStyle())
-        continue;
-      this._activePropertyMap.set(property.name, property);
-    }
-
-    this.cssText = payload.cssText;
-    this._leadingProperties = null;
-  }
-
-  _generateSyntheticPropertiesIfNeeded() {
-    if (this.range)
-      return;
-
-    if (!this._shorthandValues.size)
-      return;
-
-    const propertiesSet = new Set();
-    for (const property of this._allProperties)
-      propertiesSet.add(property.name);
-
-    const generatedProperties = [];
-    // For style-based properties, generate shorthands with values when possible.
-    for (const property of this._allProperties) {
-      // For style-based properties, try generating shorthands.
-      const shorthands = SDK.cssMetadata().shorthands(property.name) || [];
-      for (const shorthand of shorthands) {
-        if (propertiesSet.has(shorthand))
-          continue;  // There already is a shorthand this longhands falls under.
-        const shorthandValue = this._shorthandValues.get(shorthand);
-        if (!shorthandValue)
-          continue;  // Never generate synthetic shorthands when no value is available.
-
-        // Generate synthetic shorthand we have a value for.
-        const shorthandImportance = !!this._shorthandIsImportant.has(shorthand);
-        const shorthandProperty = new SDK.CSSProperty(
-            this, this.allProperties().length, shorthand, shorthandValue, shorthandImportance, false, true, false);
-        generatedProperties.push(shorthandProperty);
-        propertiesSet.add(shorthand);
-      }
-    }
-    this._allProperties = this._allProperties.concat(generatedProperties);
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSProperty>}
-   */
-  _computeLeadingProperties() {
-    /**
-     * @param {!SDK.CSSProperty} property
-     * @return {boolean}
-     */
-    function propertyHasRange(property) {
-      return !!property.range;
-    }
-
-    if (this.range)
-      return this._allProperties.filter(propertyHasRange);
-
-    const leadingProperties = [];
-    for (const property of this._allProperties) {
-      const shorthands = SDK.cssMetadata().shorthands(property.name) || [];
-      let belongToAnyShorthand = false;
-      for (const shorthand of shorthands) {
-        if (this._shorthandValues.get(shorthand)) {
-          belongToAnyShorthand = true;
-          break;
-        }
-      }
-      if (!belongToAnyShorthand)
-        leadingProperties.push(property);
-    }
-
-    return leadingProperties;
-  }
-
-  /**
-   * @return {!Array.<!SDK.CSSProperty>}
-   */
-  leadingProperties() {
-    if (!this._leadingProperties)
-      this._leadingProperties = this._computeLeadingProperties();
-    return this._leadingProperties;
-  }
-
-  /**
-   * @return {!SDK.Target}
-   */
-  target() {
-    return this._cssModel.target();
-  }
-
-  /**
-   * @return {!SDK.CSSModel}
-   */
-  cssModel() {
-    return this._cssModel;
-  }
-
-  _computeInactiveProperties() {
-    const activeProperties = {};
-    for (let i = 0; i < this._allProperties.length; ++i) {
-      const property = this._allProperties[i];
-      if (property.disabled || !property.parsedOk) {
-        property.setActive(false);
-        continue;
-      }
-      const canonicalName = SDK.cssMetadata().canonicalPropertyName(property.name);
-      const activeProperty = activeProperties[canonicalName];
-      if (!activeProperty) {
-        activeProperties[canonicalName] = property;
-      } else if (!activeProperty.important || property.important) {
-        activeProperty.setActive(false);
-        activeProperties[canonicalName] = property;
-      } else {
-        property.setActive(false);
-      }
-    }
-  }
-
-  /**
-   * @return {!Array<!SDK.CSSProperty>}
-   */
-  allProperties() {
-    return this._allProperties;
-  }
-
-  /**
-   * @param {string} name
-   * @return {string}
-   */
-  getPropertyValue(name) {
-    const property = this._activePropertyMap.get(name);
-    return property ? property.value : '';
-  }
-
-  /**
-   * @param {string} name
-   * @return {boolean}
-   */
-  isPropertyImplicit(name) {
-    const property = this._activePropertyMap.get(name);
-    return property ? property.implicit : false;
-  }
-
-  /**
-   * @param {string} name
-   * @return {!Array.<!SDK.CSSProperty>}
-   */
-  longhandProperties(name) {
-    const longhands = SDK.cssMetadata().longhands(name);
-    const result = [];
-    for (let i = 0; longhands && i < longhands.length; ++i) {
-      const property = this._activePropertyMap.get(longhands[i]);
-      if (property)
-        result.push(property);
-    }
-    return result;
-  }
-
-  /**
-   * @param {number} index
-   * @return {?SDK.CSSProperty}
-   */
-  propertyAt(index) {
-    return (index < this.allProperties().length) ? this.allProperties()[index] : null;
-  }
-
-  /**
-   * @return {number}
-   */
-  pastLastSourcePropertyIndex() {
-    for (let i = this.allProperties().length - 1; i >= 0; --i) {
-      if (this.allProperties()[i].range)
-        return i + 1;
-    }
-    return 0;
-  }
-
-  /**
-   * @param {number} index
-   * @return {!TextUtils.TextRange}
-   */
-  _insertionRange(index) {
-    const property = this.propertyAt(index);
-    return property && property.range ? property.range.collapseToStart() : this.range.collapseToEnd();
-  }
-
-  /**
-   * @param {number=} index
-   * @return {!SDK.CSSProperty}
-   */
-  newBlankProperty(index) {
-    index = (typeof index === 'undefined') ? this.pastLastSourcePropertyIndex() : index;
-    const property =
-        new SDK.CSSProperty(this, index, '', '', false, false, true, false, '', this._insertionRange(index));
-    return property;
-  }
-
-  /**
-   * @param {string} text
-   * @param {boolean} majorChange
-   * @return {!Promise.<boolean>}
-   */
-  setText(text, majorChange) {
-    if (!this.range || !this.styleSheetId)
-      return Promise.resolve(false);
-    return this._cssModel.setStyleText(this.styleSheetId, this.range, text, majorChange);
-  }
-
-  /**
-   * @param {number} index
-   * @param {string} name
-   * @param {string} value
-   * @param {function(boolean)=} userCallback
-   */
-  insertPropertyAt(index, name, value, userCallback) {
-    this.newBlankProperty(index).setText(name + ': ' + value + ';', false, true).then(userCallback);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   * @param {function(boolean)=} userCallback
-   */
-  appendProperty(name, value, userCallback) {
-    this.insertPropertyAt(this.allProperties().length, name, value, userCallback);
-  }
-};
-
-/** @enum {string} */
-SDK.CSSStyleDeclaration.Type = {
-  Regular: 'Regular',
-  Inline: 'Inline',
-  Attributes: 'Attributes'
-};
diff --git a/front_end/sdk/CSSStyleSheetHeader.js b/front_end/sdk/CSSStyleSheetHeader.js
deleted file mode 100644
index 7219fc6..0000000
--- a/front_end/sdk/CSSStyleSheetHeader.js
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-SDK.CSSStyleSheetHeader = class {
-  /**
-   * @param {!SDK.CSSModel} cssModel
-   * @param {!Protocol.CSS.CSSStyleSheetHeader} payload
-   */
-  constructor(cssModel, payload) {
-    this._cssModel = cssModel;
-    this.id = payload.styleSheetId;
-    this.frameId = payload.frameId;
-    this.sourceURL = payload.sourceURL;
-    this.hasSourceURL = !!payload.hasSourceURL;
-    this.origin = payload.origin;
-    this.title = payload.title;
-    this.disabled = payload.disabled;
-    this.isInline = payload.isInline;
-    this.startLine = payload.startLine;
-    this.startColumn = payload.startColumn;
-    this.contentLength = payload.length;
-    if (payload.ownerNode)
-      this.ownerNode = new SDK.DeferredDOMNode(cssModel.target(), payload.ownerNode);
-    this.setSourceMapURL(payload.sourceMapURL);
-  }
-
-  /**
-   * @return {!Common.ContentProvider}
-   */
-  originalContentProvider() {
-    if (!this._originalContentProvider) {
-      const lazyContent = this._cssModel.originalStyleSheetText.bind(this._cssModel, this);
-      this._originalContentProvider = new Common.StaticContentProvider(
-          this.contentURL(), this.contentType(), /** @type {function():!Promise<?string>} */ (lazyContent));
-    }
-    return this._originalContentProvider;
-  }
-
-  /**
-   * @param {string=} sourceMapURL
-   */
-  setSourceMapURL(sourceMapURL) {
-    this.sourceMapURL = sourceMapURL;
-  }
-
-  /**
-   * @return {!SDK.CSSModel}
-   */
-  cssModel() {
-    return this._cssModel;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isAnonymousInlineStyleSheet() {
-    return !this.resourceURL() && !this._cssModel.sourceMapManager().sourceMapForClient(this);
-  }
-
-  /**
-   * @return {string}
-   */
-  resourceURL() {
-    return this.isViaInspector() ? this._viaInspectorResourceURL() : this.sourceURL;
-  }
-
-  /**
-   * @return {string}
-   */
-  _viaInspectorResourceURL() {
-    const frame = this._cssModel.target().model(SDK.ResourceTreeModel).frameForId(this.frameId);
-    console.assert(frame);
-    const parsedURL = new Common.ParsedURL(frame.url);
-    let fakeURL = 'inspector://' + parsedURL.host + parsedURL.folderPathComponents;
-    if (!fakeURL.endsWith('/'))
-      fakeURL += '/';
-    fakeURL += 'inspector-stylesheet';
-    return fakeURL;
-  }
-
-  /**
-   * @param {number} lineNumberInStyleSheet
-   * @return {number}
-   */
-  lineNumberInSource(lineNumberInStyleSheet) {
-    return this.startLine + lineNumberInStyleSheet;
-  }
-
-  /**
-   * @param {number} lineNumberInStyleSheet
-   * @param {number} columnNumberInStyleSheet
-   * @return {number|undefined}
-   */
-  columnNumberInSource(lineNumberInStyleSheet, columnNumberInStyleSheet) {
-    return (lineNumberInStyleSheet ? 0 : this.startColumn) + columnNumberInStyleSheet;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this.resourceURL();
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return Common.resourceTypes.Stylesheet;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    return this._cssModel.getStyleSheetText(this.id);
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  async searchInContent(query, caseSensitive, isRegex) {
-    const content = await this.requestContent();
-    return Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isViaInspector() {
-    return this.origin === 'inspector';
-  }
-};
diff --git a/front_end/sdk/ChildTargetManager.js b/front_end/sdk/ChildTargetManager.js
deleted file mode 100644
index c0d11fc..0000000
--- a/front_end/sdk/ChildTargetManager.js
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Protocol.TargetDispatcher}
- */
-SDK.ChildTargetManager = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} parentTarget
-   */
-  constructor(parentTarget) {
-    super(parentTarget);
-    this._targetManager = parentTarget.targetManager();
-    this._parentTarget = parentTarget;
-    this._targetAgent = parentTarget.targetAgent();
-    /** @type {!Map<string, !Protocol.Target.TargetInfo>} */
-    this._targetInfos = new Map();
-
-    /** @type {!Map<string, !SDK.ChildConnection>} */
-    this._childConnections = new Map();
-
-    parentTarget.registerTargetDispatcher(this);
-    this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
-
-    if (!parentTarget.parentTarget()) {
-      this._targetAgent.setDiscoverTargets(true);
-      this._targetAgent.setRemoteLocations([{host: 'localhost', port: 9229}]);
-    }
-  }
-
-  /**
-   * @param {function({target: !SDK.Target, waitingForDebugger: boolean})=} attachCallback
-   */
-  static install(attachCallback) {
-    SDK.ChildTargetManager._attachCallback = attachCallback;
-    SDK.SDKModel.register(SDK.ChildTargetManager, SDK.Target.Capability.Target, true);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  suspendModel() {
-    return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false});
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  resumeModel() {
-    return this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    for (const sessionId of this._childConnections.keys())
-      this.detachedFromTarget(sessionId, undefined);
-  }
-
-  /**
-   * @param {string} type
-   * @return {number}
-   */
-  _capabilitiesForType(type) {
-    if (type === 'worker')
-      return SDK.Target.Capability.JS | SDK.Target.Capability.Log | SDK.Target.Capability.Network;
-    if (type === 'service_worker')
-      return SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target;
-    if (type === 'iframe') {
-      return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS |
-          SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target |
-          SDK.Target.Capability.Tracing | SDK.Target.Capability.Emulation | SDK.Target.Capability.Input;
-    }
-    return 0;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   */
-  targetCreated(targetInfo) {
-    this._targetInfos.set(targetInfo.targetId, targetInfo);
-    this._fireAvailableTargetsChanged();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   */
-  targetInfoChanged(targetInfo) {
-    this._targetInfos.set(targetInfo.targetId, targetInfo);
-    this._fireAvailableTargetsChanged();
-  }
-
-  /**
-   * @override
-   * @param {string} targetId
-   */
-  targetDestroyed(targetId) {
-    this._targetInfos.delete(targetId);
-    this._fireAvailableTargetsChanged();
-  }
-
-  _fireAvailableTargetsChanged() {
-    SDK.targetManager.dispatchEventToListeners(
-        SDK.TargetManager.Events.AvailableTargetsChanged, this._targetInfos.valuesArray());
-  }
-
-  /**
-   * @override
-   * @param {string} sessionId
-   * @param {!Protocol.Target.TargetInfo} targetInfo
-   * @param {boolean} waitingForDebugger
-   */
-  attachedToTarget(sessionId, targetInfo, waitingForDebugger) {
-    let targetName = '';
-    if (targetInfo.type !== 'iframe') {
-      const parsedURL = targetInfo.url.asParsedURL();
-      targetName = parsedURL ? parsedURL.lastPathComponentWithFragment() :
-                               '#' + (++SDK.ChildTargetManager._lastAnonymousTargetId);
-    }
-    const target = this._targetManager.createTarget(
-        targetInfo.targetId, targetName, this._capabilitiesForType(targetInfo.type),
-        this._createChildConnection.bind(this, this._targetAgent, sessionId), this._parentTarget);
-
-    if (SDK.ChildTargetManager._attachCallback)
-      SDK.ChildTargetManager._attachCallback({target, waitingForDebugger});
-    target.runtimeAgent().runIfWaitingForDebugger();
-  }
-
-  /**
-   * @override
-   * @param {string} sessionId
-   * @param {string=} childTargetId
-   */
-  detachedFromTarget(sessionId, childTargetId) {
-    this._childConnections.get(sessionId).onDisconnect.call(null, 'target terminated');
-    this._childConnections.delete(sessionId);
-  }
-
-  /**
-   * @override
-   * @param {string} sessionId
-   * @param {string} message
-   * @param {string=} childTargetId
-   */
-  receivedMessageFromTarget(sessionId, message, childTargetId) {
-    const connection = this._childConnections.get(sessionId);
-    if (connection)
-      connection.onMessage.call(null, message);
-  }
-
-  /**
-   * @param {!Protocol.TargetAgent} agent
-   * @param {string} sessionId
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   * @return {!Protocol.InspectorBackend.Connection}
-   */
-  _createChildConnection(agent, sessionId, params) {
-    const connection = new SDK.ChildConnection(agent, sessionId, params);
-    this._childConnections.set(sessionId, connection);
-    return connection;
-  }
-};
-
-SDK.ChildTargetManager._lastAnonymousTargetId = 0;
-
-/** @type {function({target: !SDK.Target, waitingForDebugger: boolean})|undefined} */
-SDK.ChildTargetManager._attachCallback;
diff --git a/front_end/sdk/Connections.js b/front_end/sdk/Connections.js
deleted file mode 100644
index 01811b8..0000000
--- a/front_end/sdk/Connections.js
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Protocol.InspectorBackend.Connection}
- * @unrestricted
- */
-SDK.MainConnection = class {
-  /**
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   */
-  constructor(params) {
-    this._onMessage = params.onMessage;
-    this._onDisconnect = params.onDisconnect;
-    this._disconnected = false;
-    this._eventListeners = [
-      InspectorFrontendHost.events.addEventListener(
-          InspectorFrontendHostAPI.Events.DispatchMessage, this._dispatchMessage, this),
-      InspectorFrontendHost.events.addEventListener(
-          InspectorFrontendHostAPI.Events.DispatchMessageChunk, this._dispatchMessageChunk, this),
-    ];
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   */
-  sendMessage(message) {
-    if (!this._disconnected)
-      InspectorFrontendHost.sendMessageToBackend(message);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _dispatchMessage(event) {
-    this._onMessage.call(null, /** @type {string} */ (event.data));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _dispatchMessageChunk(event) {
-    const messageChunk = /** @type {string} */ (event.data['messageChunk']);
-    const messageSize = /** @type {number} */ (event.data['messageSize']);
-    if (messageSize) {
-      this._messageBuffer = '';
-      this._messageSize = messageSize;
-    }
-    this._messageBuffer += messageChunk;
-    if (this._messageBuffer.length === this._messageSize) {
-      this._onMessage.call(null, this._messageBuffer);
-      this._messageBuffer = '';
-      this._messageSize = 0;
-    }
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  disconnect() {
-    const onDisconnect = this._onDisconnect;
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-    this._onDisconnect = null;
-    this._onMessage = null;
-    this._disconnected = true;
-
-    let fulfill;
-    const promise = new Promise(f => fulfill = f);
-    InspectorFrontendHost.reattach(() => {
-      onDisconnect.call(null, 'force disconnect');
-      fulfill();
-    });
-    return promise;
-  }
-};
-
-/**
- * @implements {Protocol.InspectorBackend.Connection}
- * @unrestricted
- */
-SDK.WebSocketConnection = class {
-  /**
-   * @param {string} url
-   * @param {function()} onWebSocketDisconnect
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   */
-  constructor(url, onWebSocketDisconnect, params) {
-    this._socket = new WebSocket(url);
-    this._socket.onerror = this._onError.bind(this);
-    this._socket.onopen = this._onOpen.bind(this);
-    this._socket.onmessage = messageEvent => params.onMessage.call(null, /** @type {string} */ (messageEvent.data));
-    this._socket.onclose = this._onClose.bind(this);
-
-    this._onDisconnect = params.onDisconnect;
-    this._onWebSocketDisconnect = onWebSocketDisconnect;
-    this._connected = false;
-    this._messages = [];
-  }
-
-  _onError() {
-    this._onWebSocketDisconnect.call(null);
-    // This is called if error occurred while connecting.
-    this._onDisconnect.call(null, 'connection failed');
-    this._close();
-  }
-
-  _onOpen() {
-    this._socket.onerror = console.error;
-    this._connected = true;
-    for (const message of this._messages)
-      this._socket.send(message);
-    this._messages = [];
-  }
-
-  _onClose() {
-    this._onWebSocketDisconnect.call(null);
-    this._onDisconnect.call(null, 'websocket closed');
-    this._close();
-  }
-
-  /**
-   * @param {function()=} callback
-   */
-  _close(callback) {
-    this._socket.onerror = null;
-    this._socket.onopen = null;
-    this._socket.onclose = callback || null;
-    this._socket.onmessage = null;
-    this._socket.close();
-    this._socket = null;
-    this._onWebSocketDisconnect = null;
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   */
-  sendMessage(message) {
-    if (this._connected)
-      this._socket.send(message);
-    else
-      this._messages.push(message);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  disconnect() {
-    let fulfill;
-    const promise = new Promise(f => fulfill = f);
-    this._close(() => {
-      this._onDisconnect.call(null, 'force disconnect');
-      fulfill();
-    });
-    return promise;
-  }
-};
-
-/**
- * @implements {Protocol.InspectorBackend.Connection}
- * @unrestricted
- */
-SDK.StubConnection = class {
-  /**
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   */
-  constructor(params) {
-    this._onMessage = params.onMessage;
-    this._onDisconnect = params.onDisconnect;
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   */
-  sendMessage(message) {
-    setTimeout(this._respondWithError.bind(this, message), 0);
-  }
-
-  /**
-   * @param {string} message
-   */
-  _respondWithError(message) {
-    const messageObject = JSON.parse(message);
-    const error = {
-      message: 'This is a stub connection, can\'t dispatch message.',
-      code: Protocol.InspectorBackend.DevToolsStubErrorCode,
-      data: messageObject
-    };
-    this._onMessage.call(null, {id: messageObject.id, error: error});
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  disconnect() {
-    this._onDisconnect.call(null, 'force disconnect');
-    this._onDisconnect = null;
-    this._onMessage = null;
-    return Promise.resolve();
-  }
-};
-
-/**
- * @implements {Protocol.InspectorBackend.Connection}
- */
-SDK.ChildConnection = class {
-  /**
-   * @param {!Protocol.TargetAgent} agent
-   * @param {string} sessionId
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   */
-  constructor(agent, sessionId, params) {
-    this._agent = agent;
-    this._sessionId = sessionId;
-    this.onMessage = params.onMessage;
-    this.onDisconnect = params.onDisconnect;
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   */
-  sendMessage(message) {
-    this._agent.sendMessageToTarget(message, this._sessionId);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  disconnect() {
-    throw 'Not implemented';
-  }
-};
-
-/**
- * @param {!Protocol.InspectorBackend.Connection.Params} params
- * @param {function()} connectionLostCallback
- * @return {!Protocol.InspectorBackend.Connection}
- */
-SDK.createMainConnection = function(params, connectionLostCallback) {
-  const wsParam = Runtime.queryParam('ws');
-  const wssParam = Runtime.queryParam('wss');
-
-  if (wsParam || wssParam) {
-    const ws = wsParam ? `ws://${wsParam}` : `wss://${wssParam}`;
-    return new SDK.WebSocketConnection(ws, connectionLostCallback, params);
-  }
-
-  if (InspectorFrontendHost.isHostedMode())
-    return new SDK.StubConnection(params);
-  return new SDK.MainConnection(params);
-};
diff --git a/front_end/sdk/ConsoleModel.js b/front_end/sdk/ConsoleModel.js
deleted file mode 100644
index 0edbf43..0000000
--- a/front_end/sdk/ConsoleModel.js
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {SDK.TargetManager.Observer}
- */
-SDK.ConsoleModel = class extends Common.Object {
-  constructor() {
-    super();
-
-    /** @type {!Array.<!SDK.ConsoleMessage>} */
-    this._messages = [];
-    /** @type {!Map<!SDK.RuntimeModel, !Map<number, !SDK.ConsoleMessage>>} */
-    this._messageByExceptionId = new Map();
-    this._warnings = 0;
-    this._errors = 0;
-    this._pageLoadSequenceNumber = 0;
-
-    SDK.targetManager.observeTargets(this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (!resourceTreeModel || resourceTreeModel.cachedResourcesLoaded()) {
-      this._initTarget(target);
-      return;
-    }
-
-    const eventListener = resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, () => {
-      Common.EventTarget.removeEventListeners([eventListener]);
-      this._initTarget(target);
-    });
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  _initTarget(target) {
-    const eventListeners = [];
-
-    const cpuProfilerModel = target.model(SDK.CPUProfilerModel);
-    if (cpuProfilerModel) {
-      eventListeners.push(cpuProfilerModel.addEventListener(
-          SDK.CPUProfilerModel.Events.ConsoleProfileStarted, this._consoleProfileStarted.bind(this, cpuProfilerModel)));
-      eventListeners.push(cpuProfilerModel.addEventListener(
-          SDK.CPUProfilerModel.Events.ConsoleProfileFinished,
-          this._consoleProfileFinished.bind(this, cpuProfilerModel)));
-    }
-
-    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
-    if (resourceTreeModel && !target.parentTarget()) {
-      eventListeners.push(resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._mainFrameNavigated, this));
-    }
-
-    const runtimeModel = target.model(SDK.RuntimeModel);
-    if (runtimeModel) {
-      eventListeners.push(runtimeModel.addEventListener(
-          SDK.RuntimeModel.Events.ExceptionThrown, this._exceptionThrown.bind(this, runtimeModel)));
-      eventListeners.push(runtimeModel.addEventListener(
-          SDK.RuntimeModel.Events.ExceptionRevoked, this._exceptionRevoked.bind(this, runtimeModel)));
-      eventListeners.push(runtimeModel.addEventListener(
-          SDK.RuntimeModel.Events.ConsoleAPICalled, this._consoleAPICalled.bind(this, runtimeModel)));
-      if (!target.parentTarget()) {
-        eventListeners.push(runtimeModel.debuggerModel().addEventListener(
-            SDK.DebuggerModel.Events.GlobalObjectCleared, this._clearIfNecessary, this));
-      }
-      eventListeners.push(runtimeModel.addEventListener(
-          SDK.RuntimeModel.Events.QueryObjectRequested, this._queryObjectRequested.bind(this, runtimeModel)));
-    }
-
-    target[SDK.ConsoleModel._events] = eventListeners;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    const runtimeModel = target.model(SDK.RuntimeModel);
-    if (runtimeModel)
-      this._messageByExceptionId.delete(runtimeModel);
-    Common.EventTarget.removeEventListeners(target[SDK.ConsoleModel._events] || []);
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @param {!SDK.ConsoleMessage} originatingMessage
-   * @param {string} expression
-   * @param {boolean} useCommandLineAPI
-   * @param {boolean} awaitPromise
-   */
-  async evaluateCommandInConsole(executionContext, originatingMessage, expression, useCommandLineAPI, awaitPromise) {
-    const result = await executionContext.evaluate(
-        {
-          expression: expression,
-          objectGroup: 'console',
-          includeCommandLineAPI: useCommandLineAPI,
-          silent: false,
-          returnByValue: false,
-          generatePreview: true
-        },
-        /* userGesture */ true, awaitPromise);
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ConsoleEvaluated);
-    if (result.error)
-      return;
-    await Common.console.showPromise();
-    this.dispatchEventToListeners(
-        SDK.ConsoleModel.Events.CommandEvaluated,
-        {result: result.object, commandMessage: originatingMessage, exceptionDetails: result.exceptionDetails});
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @param {string} text
-   * @return {!SDK.ConsoleMessage}
-   */
-  addCommandMessage(executionContext, text) {
-    const commandMessage = new SDK.ConsoleMessage(
-        executionContext.runtimeModel, SDK.ConsoleMessage.MessageSource.JS, null, text,
-        SDK.ConsoleMessage.MessageType.Command);
-    commandMessage.setExecutionContextId(executionContext.id);
-    this.addMessage(commandMessage);
-    return commandMessage;
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} msg
-   */
-  addMessage(msg) {
-    if (msg.source === SDK.ConsoleMessage.MessageSource.Worker && SDK.targetManager.targetById(msg.workerId))
-      return;
-
-    msg._pageLoadSequenceNumber = this._pageLoadSequenceNumber;
-    if (msg.source === SDK.ConsoleMessage.MessageSource.ConsoleAPI && msg.type === SDK.ConsoleMessage.MessageType.Clear)
-      this._clearIfNecessary();
-
-    this._messages.push(msg);
-    const runtimeModel = msg.runtimeModel();
-    if (msg._exceptionId && runtimeModel) {
-      let modelMap = this._messageByExceptionId.get(runtimeModel);
-      if (!modelMap) {
-        modelMap = new Map();
-        this._messageByExceptionId.set(runtimeModel, modelMap);
-      }
-      modelMap.set(msg._exceptionId, msg);
-    }
-    this._incrementErrorWarningCount(msg);
-    this.dispatchEventToListeners(SDK.ConsoleModel.Events.MessageAdded, msg);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {!Common.Event} event
-   */
-  _exceptionThrown(runtimeModel, event) {
-    const exceptionWithTimestamp = /** @type {!SDK.RuntimeModel.ExceptionWithTimestamp} */ (event.data);
-    const consoleMessage = SDK.ConsoleMessage.fromException(
-        runtimeModel, exceptionWithTimestamp.details, undefined, exceptionWithTimestamp.timestamp, undefined);
-    consoleMessage.setExceptionId(exceptionWithTimestamp.details.exceptionId);
-    this.addMessage(consoleMessage);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {!Common.Event} event
-   */
-  _exceptionRevoked(runtimeModel, event) {
-    const exceptionId = /** @type {number} */ (event.data);
-    const modelMap = this._messageByExceptionId.get(runtimeModel);
-    const exceptionMessage = modelMap ? modelMap.get(exceptionId) : null;
-    if (!exceptionMessage)
-      return;
-    this._errors--;
-    exceptionMessage.level = SDK.ConsoleMessage.MessageLevel.Info;
-    this.dispatchEventToListeners(SDK.ConsoleModel.Events.MessageUpdated, exceptionMessage);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {!Common.Event} event
-   */
-  _consoleAPICalled(runtimeModel, event) {
-    const call = /** @type {!SDK.RuntimeModel.ConsoleAPICall} */ (event.data);
-    let level = SDK.ConsoleMessage.MessageLevel.Info;
-    if (call.type === SDK.ConsoleMessage.MessageType.Debug)
-      level = SDK.ConsoleMessage.MessageLevel.Verbose;
-    else if (call.type === SDK.ConsoleMessage.MessageType.Error || call.type === SDK.ConsoleMessage.MessageType.Assert)
-      level = SDK.ConsoleMessage.MessageLevel.Error;
-    else if (call.type === SDK.ConsoleMessage.MessageType.Warning)
-      level = SDK.ConsoleMessage.MessageLevel.Warning;
-    else if (call.type === SDK.ConsoleMessage.MessageType.Info || call.type === SDK.ConsoleMessage.MessageType.Log)
-      level = SDK.ConsoleMessage.MessageLevel.Info;
-    let message = '';
-    if (call.args.length && call.args[0].unserializableValue)
-      message = call.args[0].unserializableValue;
-    else if (call.args.length && (typeof call.args[0].value !== 'object' || call.args[0].value === null))
-      message = call.args[0].value + '';
-    else if (call.args.length && call.args[0].description)
-      message = call.args[0].description;
-    const callFrame = call.stackTrace && call.stackTrace.callFrames.length ? call.stackTrace.callFrames[0] : null;
-    const consoleMessage = new SDK.ConsoleMessage(
-        runtimeModel, SDK.ConsoleMessage.MessageSource.ConsoleAPI, level,
-        /** @type {string} */ (message), call.type, callFrame ? callFrame.url : undefined,
-        callFrame ? callFrame.lineNumber : undefined, callFrame ? callFrame.columnNumber : undefined, call.args,
-        call.stackTrace, call.timestamp, call.executionContextId, undefined, undefined, call.context);
-    this.addMessage(consoleMessage);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {!Common.Event} event
-   */
-  _queryObjectRequested(runtimeModel, event) {
-    const consoleMessage = new SDK.ConsoleMessage(
-        runtimeModel, SDK.ConsoleMessage.MessageSource.ConsoleAPI, SDK.ConsoleMessage.MessageLevel.Info, '',
-        SDK.ConsoleMessage.MessageType.QueryObjectResult, undefined, undefined, undefined, [event.data.objects]);
-    this.addMessage(consoleMessage);
-  }
-
-  _clearIfNecessary() {
-    if (!Common.moduleSetting('preserveConsoleLog').get())
-      this._clear();
-    ++this._pageLoadSequenceNumber;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _mainFrameNavigated(event) {
-    if (Common.moduleSetting('preserveConsoleLog').get())
-      Common.console.log(Common.UIString('Navigated to %s', event.data.url));
-  }
-
-  /**
-   * @param {!SDK.CPUProfilerModel} cpuProfilerModel
-   * @param {!Common.Event} event
-   */
-  _consoleProfileStarted(cpuProfilerModel, event) {
-    const data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
-    this._addConsoleProfileMessage(
-        cpuProfilerModel, SDK.ConsoleMessage.MessageType.Profile, data.scriptLocation,
-        Common.UIString('Profile \'%s\' started.', data.title));
-  }
-
-  /**
-   * @param {!SDK.CPUProfilerModel} cpuProfilerModel
-   * @param {!Common.Event} event
-   */
-  _consoleProfileFinished(cpuProfilerModel, event) {
-    const data = /** @type {!SDK.CPUProfilerModel.EventData} */ (event.data);
-    this._addConsoleProfileMessage(
-        cpuProfilerModel, SDK.ConsoleMessage.MessageType.ProfileEnd, data.scriptLocation,
-        Common.UIString('Profile \'%s\' finished.', data.title));
-  }
-
-  /**
-   * @param {!SDK.CPUProfilerModel} cpuProfilerModel
-   * @param {string} type
-   * @param {!SDK.DebuggerModel.Location} scriptLocation
-   * @param {string} messageText
-   */
-  _addConsoleProfileMessage(cpuProfilerModel, type, scriptLocation, messageText) {
-    const stackTrace = [{
-      functionName: '',
-      scriptId: scriptLocation.scriptId,
-      url: scriptLocation.script() ? scriptLocation.script().contentURL() : '',
-      lineNumber: scriptLocation.lineNumber,
-      columnNumber: scriptLocation.columnNumber || 0
-    }];
-    this.addMessage(new SDK.ConsoleMessage(
-        cpuProfilerModel.runtimeModel(), SDK.ConsoleMessage.MessageSource.ConsoleAPI,
-        SDK.ConsoleMessage.MessageLevel.Info, messageText, type, undefined, undefined, undefined, stackTrace));
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} msg
-   */
-  _incrementErrorWarningCount(msg) {
-    if (msg.source === SDK.ConsoleMessage.MessageSource.Violation)
-      return;
-    switch (msg.level) {
-      case SDK.ConsoleMessage.MessageLevel.Warning:
-        this._warnings++;
-        break;
-      case SDK.ConsoleMessage.MessageLevel.Error:
-        this._errors++;
-        break;
-    }
-  }
-
-  /**
-   * @return {!Array.<!SDK.ConsoleMessage>}
-   */
-  messages() {
-    return this._messages;
-  }
-
-  requestClearMessages() {
-    for (const logModel of SDK.targetManager.models(SDK.LogModel))
-      logModel.requestClear();
-    for (const runtimeModel of SDK.targetManager.models(SDK.RuntimeModel))
-      runtimeModel.discardConsoleEntries();
-    this._clear();
-  }
-
-  _clear() {
-    this._messages = [];
-    this._messageByExceptionId.clear();
-    this._errors = 0;
-    this._warnings = 0;
-    this.dispatchEventToListeners(SDK.ConsoleModel.Events.ConsoleCleared);
-  }
-
-  /**
-   * @return {number}
-   */
-  errors() {
-    return this._errors;
-  }
-
-  /**
-   * @return {number}
-   */
-  warnings() {
-    return this._warnings;
-  }
-};
-
-/** @enum {symbol} */
-SDK.ConsoleModel.Events = {
-  ConsoleCleared: Symbol('ConsoleCleared'),
-  MessageAdded: Symbol('MessageAdded'),
-  MessageUpdated: Symbol('MessageUpdated'),
-  CommandEvaluated: Symbol('CommandEvaluated')
-};
-
-
-/**
- * @unrestricted
- */
-SDK.ConsoleMessage = class {
-  /**
-   * @param {?SDK.RuntimeModel} runtimeModel
-   * @param {string} source
-   * @param {?string} level
-   * @param {string} messageText
-   * @param {string=} type
-   * @param {?string=} url
-   * @param {number=} line
-   * @param {number=} column
-   * @param {!Array.<!Protocol.Runtime.RemoteObject>=} parameters
-   * @param {!Protocol.Runtime.StackTrace=} stackTrace
-   * @param {number=} timestamp
-   * @param {!Protocol.Runtime.ExecutionContextId=} executionContextId
-   * @param {?string=} scriptId
-   * @param {?string=} workerId
-   * @param {string=} context
-   */
-  constructor(
-      runtimeModel, source, level, messageText, type, url, line, column, parameters, stackTrace, timestamp,
-      executionContextId, scriptId, workerId, context) {
-    this._runtimeModel = runtimeModel;
-    this.source = source;
-    this.level = /** @type {?SDK.ConsoleMessage.MessageLevel} */ (level);
-    this.messageText = messageText;
-    this.type = type || SDK.ConsoleMessage.MessageType.Log;
-    /** @type {string|undefined} */
-    this.url = url || undefined;
-    /** @type {number} */
-    this.line = line || 0;
-    /** @type {number} */
-    this.column = column || 0;
-    this.parameters = parameters;
-    /** @type {!Protocol.Runtime.StackTrace|undefined} */
-    this.stackTrace = stackTrace;
-    this.timestamp = timestamp || Date.now();
-    this.executionContextId = executionContextId || 0;
-    this.scriptId = scriptId || null;
-    this.workerId = workerId || null;
-
-    if (!this.executionContextId && this._runtimeModel) {
-      if (this.scriptId)
-        this.executionContextId = this._runtimeModel.executionContextIdForScriptId(this.scriptId);
-      else if (this.stackTrace)
-        this.executionContextId = this._runtimeModel.executionContextForStackTrace(this.stackTrace);
-    }
-
-    if (context)
-      this.context = context.match(/[^#]*/)[0];
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
-   * @param {string=} messageType
-   * @param {number=} timestamp
-   * @param {string=} forceUrl
-   * @return {!SDK.ConsoleMessage}
-   */
-  static fromException(runtimeModel, exceptionDetails, messageType, timestamp, forceUrl) {
-    return new SDK.ConsoleMessage(
-        runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Error,
-        SDK.RuntimeModel.simpleTextFromException(exceptionDetails), messageType, forceUrl || exceptionDetails.url,
-        exceptionDetails.lineNumber, exceptionDetails.columnNumber,
-        exceptionDetails.exception ?
-            [SDK.RemoteObject.fromLocalObject(exceptionDetails.text), exceptionDetails.exception] :
-            undefined,
-        exceptionDetails.stackTrace, timestamp, exceptionDetails.executionContextId, exceptionDetails.scriptId);
-  }
-
-  /**
-   * @return {?SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._runtimeModel;
-  }
-
-  /**
-   * @return {?SDK.Target}
-   */
-  target() {
-    return this._runtimeModel ? this._runtimeModel.target() : null;
-  }
-
-  /**
-   * @param {!SDK.ConsoleMessage} originatingMessage
-   */
-  setOriginatingMessage(originatingMessage) {
-    this._originatingConsoleMessage = originatingMessage;
-    this.executionContextId = originatingMessage.executionContextId;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ExecutionContextId} executionContextId
-   */
-  setExecutionContextId(executionContextId) {
-    this.executionContextId = executionContextId;
-  }
-
-  /**
-   * @param {number} exceptionId
-   */
-  setExceptionId(exceptionId) {
-    this._exceptionId = exceptionId;
-  }
-
-  /**
-   * @return {?SDK.ConsoleMessage}
-   */
-  originatingMessage() {
-    return this._originatingConsoleMessage;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isGroupMessage() {
-    return this.type === SDK.ConsoleMessage.MessageType.StartGroup ||
-        this.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed ||
-        this.type === SDK.ConsoleMessage.MessageType.EndGroup;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isGroupStartMessage() {
-    return this.type === SDK.ConsoleMessage.MessageType.StartGroup ||
-        this.type === SDK.ConsoleMessage.MessageType.StartGroupCollapsed;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isErrorOrWarning() {
-    return (
-        this.level === SDK.ConsoleMessage.MessageLevel.Warning || this.level === SDK.ConsoleMessage.MessageLevel.Error);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isGroupable() {
-    const isUngroupableError = this.level === SDK.ConsoleMessage.MessageLevel.Error &&
-        (this.source === SDK.ConsoleMessage.MessageSource.JS ||
-         this.source === SDK.ConsoleMessage.MessageSource.Network);
-    return (
-        this.source !== SDK.ConsoleMessage.MessageSource.ConsoleAPI &&
-        this.type !== SDK.ConsoleMessage.MessageType.Command && this.type !== SDK.ConsoleMessage.MessageType.Result &&
-        this.type !== SDK.ConsoleMessage.MessageType.System && !isUngroupableError);
-  }
-
-  /**
-   * @return {string}
-   */
-  groupCategoryKey() {
-    return [this.source, this.level, this.type, this._pageLoadSequenceNumber].join(':');
-  }
-
-  /**
-   * @param {?SDK.ConsoleMessage} msg
-   * @return {boolean}
-   */
-  isEqual(msg) {
-    if (!msg)
-      return false;
-
-    if (!this._isEqualStackTraces(this.stackTrace, msg.stackTrace))
-      return false;
-
-    if (this.parameters) {
-      if (!msg.parameters || this.parameters.length !== msg.parameters.length)
-        return false;
-
-      for (let i = 0; i < msg.parameters.length; ++i) {
-        // Never treat objects as equal - their properties might change over time. Errors can be treated as equal
-        // since they are always formatted as strings.
-        if (msg.parameters[i].type === 'object' && msg.parameters[i].subtype !== 'error')
-          return false;
-        if (this.parameters[i].type !== msg.parameters[i].type ||
-            this.parameters[i].value !== msg.parameters[i].value ||
-            this.parameters[i].description !== msg.parameters[i].description)
-          return false;
-      }
-    }
-
-    return (this.runtimeModel() === msg.runtimeModel()) && (this.source === msg.source) && (this.type === msg.type) &&
-        (this.level === msg.level) && (this.line === msg.line) && (this.url === msg.url) &&
-        (this.messageText === msg.messageText) && (this.request === msg.request) &&
-        (this.executionContextId === msg.executionContextId);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTrace|undefined} stackTrace1
-   * @param {!Protocol.Runtime.StackTrace|undefined} stackTrace2
-   * @return {boolean}
-   */
-  _isEqualStackTraces(stackTrace1, stackTrace2) {
-    if (!stackTrace1 !== !stackTrace2)
-      return false;
-    if (!stackTrace1)
-      return true;
-    const callFrames1 = stackTrace1.callFrames;
-    const callFrames2 = stackTrace2.callFrames;
-    if (callFrames1.length !== callFrames2.length)
-      return false;
-    for (let i = 0, n = callFrames1.length; i < n; ++i) {
-      if (callFrames1[i].url !== callFrames2[i].url || callFrames1[i].functionName !== callFrames2[i].functionName ||
-          callFrames1[i].lineNumber !== callFrames2[i].lineNumber ||
-          callFrames1[i].columnNumber !== callFrames2[i].columnNumber)
-        return false;
-    }
-    return this._isEqualStackTraces(stackTrace1.parent, stackTrace2.parent);
-  }
-};
-
-// Note: Keep these constants in sync with the ones in ConsoleTypes.h
-/**
- * @enum {string}
- */
-SDK.ConsoleMessage.MessageSource = {
-  XML: 'xml',
-  JS: 'javascript',
-  Network: 'network',
-  ConsoleAPI: 'console-api',
-  Storage: 'storage',
-  AppCache: 'appcache',
-  Rendering: 'rendering',
-  CSS: 'css',
-  Security: 'security',
-  Deprecation: 'deprecation',
-  Worker: 'worker',
-  Violation: 'violation',
-  Intervention: 'intervention',
-  Recommendation: 'recommendation',
-  Other: 'other'
-};
-
-/**
- * @enum {string}
- */
-SDK.ConsoleMessage.MessageType = {
-  Log: 'log',
-  Debug: 'debug',
-  Info: 'info',
-  Error: 'error',
-  Warning: 'warning',
-  Dir: 'dir',
-  DirXML: 'dirxml',
-  Table: 'table',
-  Trace: 'trace',
-  Clear: 'clear',
-  StartGroup: 'startGroup',
-  StartGroupCollapsed: 'startGroupCollapsed',
-  EndGroup: 'endGroup',
-  Assert: 'assert',
-  Result: 'result',
-  Profile: 'profile',
-  ProfileEnd: 'profileEnd',
-  Command: 'command',
-  System: 'system',
-  QueryObjectResult: 'queryObjectResult'
-};
-
-/**
- * @enum {string}
- */
-SDK.ConsoleMessage.MessageLevel = {
-  Verbose: 'verbose',
-  Info: 'info',
-  Warning: 'warning',
-  Error: 'error'
-};
-
-/** @type {!Map<!SDK.ConsoleMessage.MessageSource, string>} */
-SDK.ConsoleMessage.MessageSourceDisplayName = new Map([
-  [SDK.ConsoleMessage.MessageSource.XML, 'xml'], [SDK.ConsoleMessage.MessageSource.JS, 'javascript'],
-  [SDK.ConsoleMessage.MessageSource.Network, 'network'], [SDK.ConsoleMessage.MessageSource.ConsoleAPI, 'console-api'],
-  [SDK.ConsoleMessage.MessageSource.Storage, 'storage'], [SDK.ConsoleMessage.MessageSource.AppCache, 'appcache'],
-  [SDK.ConsoleMessage.MessageSource.Rendering, 'rendering'], [SDK.ConsoleMessage.MessageSource.CSS, 'css'],
-  [SDK.ConsoleMessage.MessageSource.Security, 'security'],
-  [SDK.ConsoleMessage.MessageSource.Deprecation, 'deprecation'], [SDK.ConsoleMessage.MessageSource.Worker, 'worker'],
-  [SDK.ConsoleMessage.MessageSource.Violation, 'violation'],
-  [SDK.ConsoleMessage.MessageSource.Intervention, 'intervention'],
-  [SDK.ConsoleMessage.MessageSource.Recommendation, 'recommendation'],
-  [SDK.ConsoleMessage.MessageSource.Other, 'other']
-]);
-
-SDK.ConsoleModel._events = Symbol('SDK.ConsoleModel.events');
-
-/**
- * @type {!SDK.ConsoleModel}
- */
-SDK.consoleModel;
diff --git a/front_end/sdk/ContentProviders.js b/front_end/sdk/ContentProviders.js
deleted file mode 100644
index 5cd03c9..0000000
--- a/front_end/sdk/ContentProviders.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-SDK.CompilerSourceMappingContentProvider = class {
-  /**
-   * @param {string} sourceURL
-   * @param {!Common.ResourceType} contentType
-   */
-  constructor(sourceURL, contentType) {
-    this._sourceURL = sourceURL;
-    this._contentType = contentType;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._sourceURL;
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._contentType;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    let callback;
-    const promise = new Promise(fulfill => callback = fulfill);
-    SDK.multitargetNetworkManager.loadResource(this._sourceURL, contentLoaded.bind(this));
-    return promise;
-
-    /**
-     * @param {number} statusCode
-     * @param {!Object.<string, string>} headers
-     * @param {string} content
-     * @this {SDK.CompilerSourceMappingContentProvider}
-     */
-    function contentLoaded(statusCode, headers, content) {
-      if (statusCode >= 400) {
-        console.error(
-            'Could not load content for ' + this._sourceURL + ' : ' +
-            'HTTP status code: ' + statusCode);
-        callback(null);
-        return;
-      }
-
-      callback(content);
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  async searchInContent(query, caseSensitive, isRegex) {
-    const content = await this.requestContent();
-    if (typeof content !== 'string')
-      return [];
-    return Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
-  }
-};
diff --git a/front_end/sdk/CookieModel.js b/front_end/sdk/CookieModel.js
deleted file mode 100644
index cf3ab19..0000000
--- a/front_end/sdk/CookieModel.js
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-SDK.CookieModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-  }
-
-  /**
-   * @param {!Protocol.Network.Cookie} protocolCookie
-   * @return {!SDK.Cookie}
-   */
-  static _parseProtocolCookie(protocolCookie) {
-    const cookie = new SDK.Cookie(protocolCookie.name, protocolCookie.value, null);
-    cookie.addAttribute('domain', protocolCookie['domain']);
-    cookie.addAttribute('path', protocolCookie['path']);
-    cookie.addAttribute('port', protocolCookie['port']);
-    if (protocolCookie['expires'])
-      cookie.addAttribute('expires', protocolCookie['expires'] * 1000);
-    if (protocolCookie['httpOnly'])
-      cookie.addAttribute('httpOnly');
-    if (protocolCookie['secure'])
-      cookie.addAttribute('secure');
-    if (protocolCookie['sameSite'])
-      cookie.addAttribute('sameSite', protocolCookie['sameSite']);
-    cookie.setSize(protocolCookie['size']);
-    return cookie;
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookie
-   * @param {string} resourceURL
-   * @return {boolean}
-   */
-  static cookieMatchesResourceURL(cookie, resourceURL) {
-    const url = resourceURL.asParsedURL();
-    if (!url || !SDK.CookieModel.cookieDomainMatchesResourceDomain(cookie.domain(), url.host))
-      return false;
-    return (
-        url.path.startsWith(cookie.path()) && (!cookie.port() || url.port === cookie.port()) &&
-        (!cookie.secure() || url.scheme === 'https'));
-  }
-
-  /**
-   * @param {string} cookieDomain
-   * @param {string} resourceDomain
-   * @return {boolean}
-   */
-  static cookieDomainMatchesResourceDomain(cookieDomain, resourceDomain) {
-    if (cookieDomain.charAt(0) !== '.')
-      return resourceDomain === cookieDomain;
-    return !!resourceDomain.match(
-        new RegExp('^([^\\.]+\\.)*' + cookieDomain.substring(1).escapeForRegExp() + '$', 'i'));
-  }
-
-  /**
-   * @param {!Array<string>} urls
-   * @return {!Promise<!Array<!SDK.Cookie>>}
-   */
-  getCookies(urls) {
-    return this.target().networkAgent().getCookies(urls).then(
-        cookies => (cookies || []).map(cookie => SDK.CookieModel._parseProtocolCookie(cookie)));
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookie
-   * @param {function()=} callback
-   */
-  deleteCookie(cookie, callback) {
-    this._deleteAll([cookie], callback);
-  }
-
-  /**
-   * @param {string=} domain
-   * @param {function()=} callback
-   */
-  clear(domain, callback) {
-    this.getCookiesForDomain(domain || null).then(cookies => this._deleteAll(cookies, callback));
-  }
-
-  /**
-   * @param {!SDK.Cookie} cookie
-   * @return {!Promise<boolean>}
-   */
-  saveCookie(cookie) {
-    let domain = cookie.domain();
-    if (!domain.startsWith('.'))
-      domain = '';
-    let expires = undefined;
-    if (cookie.expires())
-      expires = Math.floor(Date.parse(cookie.expires()) / 1000);
-    return this.target()
-        .networkAgent()
-        .setCookie(
-            cookie.name(), cookie.value(), cookie.url(), domain, cookie.path(), cookie.secure(), cookie.httpOnly(),
-            cookie.sameSite(), expires)
-        .then(success => !!success);
-  }
-
-  /**
-   * @param {?string} domain
-   * @return {!Promise<!Array<!SDK.Cookie>>}
-   */
-  getCookiesForDomain(domain) {
-    const resourceURLs = [];
-    /**
-     * @param {!SDK.Resource} resource
-     */
-    function populateResourceURLs(resource) {
-      const url = resource.documentURL.asParsedURL();
-      if (url && (!domain || url.securityOrigin() === domain))
-        resourceURLs.push(resource.url);
-    }
-    const resourceTreeModel = this.target().model(SDK.ResourceTreeModel);
-    if (resourceTreeModel)
-      resourceTreeModel.forAllResources(populateResourceURLs);
-    return this.getCookies(resourceURLs);
-  }
-
-  /**
-   * @param {!Array<!SDK.Cookie>} cookies
-   * @param {function()=} callback
-   */
-  _deleteAll(cookies, callback) {
-    const networkAgent = this.target().networkAgent();
-    Promise
-        .all(
-            cookies.map(cookie => networkAgent.deleteCookies(cookie.name(), undefined, cookie.domain(), cookie.path())))
-        .then(callback || function() {});
-  }
-};
-
-SDK.SDKModel.register(SDK.CookieModel, SDK.Target.Capability.Network, false);
diff --git a/front_end/sdk/CookieParser.js b/front_end/sdk/CookieParser.js
deleted file mode 100644
index f5f0d76..0000000
--- a/front_end/sdk/CookieParser.js
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// Ideally, we would rely on platform support for parsing a cookie, since
-// this would save us from any potential inconsistency. However, exposing
-// platform cookie parsing logic would require quite a bit of additional
-// plumbing, and at least some platforms lack support for parsing Cookie,
-// which is in a format slightly different from Set-Cookie and is normally
-// only required on the server side.
-
-/**
- * @unrestricted
- */
-SDK.CookieParser = class {
-  constructor() {
-  }
-
-  /**
-   * @param {string|undefined} header
-   * @return {?Array<!SDK.Cookie>}
-   */
-  static parseCookie(header) {
-    return (new SDK.CookieParser()).parseCookie(header);
-  }
-
-  /**
-   * @param {string|undefined} header
-   * @return {?Array<!SDK.Cookie>}
-   */
-  static parseSetCookie(header) {
-    return (new SDK.CookieParser()).parseSetCookie(header);
-  }
-
-  /**
-   * @return {!Array<!SDK.Cookie>}
-   */
-  cookies() {
-    return this._cookies;
-  }
-
-  /**
-   * @param {string|undefined} cookieHeader
-   * @return {?Array<!SDK.Cookie>}
-   */
-  parseCookie(cookieHeader) {
-    if (!this._initialize(cookieHeader))
-      return null;
-
-    for (let kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
-      if (kv.key.charAt(0) === '$' && this._lastCookie)
-        this._lastCookie.addAttribute(kv.key.slice(1), kv.value);
-      else if (kv.key.toLowerCase() !== '$version' && typeof kv.value === 'string')
-        this._addCookie(kv, SDK.Cookie.Type.Request);
-      this._advanceAndCheckCookieDelimiter();
-    }
-    this._flushCookie();
-    return this._cookies;
-  }
-
-  /**
-   * @param {string|undefined} setCookieHeader
-   * @return {?Array<!SDK.Cookie>}
-   */
-  parseSetCookie(setCookieHeader) {
-    if (!this._initialize(setCookieHeader))
-      return null;
-    for (let kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
-      if (this._lastCookie)
-        this._lastCookie.addAttribute(kv.key, kv.value);
-      else
-        this._addCookie(kv, SDK.Cookie.Type.Response);
-      if (this._advanceAndCheckCookieDelimiter())
-        this._flushCookie();
-    }
-    this._flushCookie();
-    return this._cookies;
-  }
-
-  /**
-   * @param {string|undefined} headerValue
-   * @return {boolean}
-   */
-  _initialize(headerValue) {
-    this._input = headerValue;
-    if (typeof headerValue !== 'string')
-      return false;
-    this._cookies = [];
-    this._lastCookie = null;
-    this._originalInputLength = this._input.length;
-    return true;
-  }
-
-  _flushCookie() {
-    if (this._lastCookie)
-      this._lastCookie.setSize(this._originalInputLength - this._input.length - this._lastCookiePosition);
-    this._lastCookie = null;
-  }
-
-  /**
-   * @return {?SDK.CookieParser.KeyValue}
-   */
-  _extractKeyValue() {
-    if (!this._input || !this._input.length)
-      return null;
-    // Note: RFCs offer an option for quoted values that may contain commas and semicolons.
-    // Many browsers/platforms do not support this, however (see http://webkit.org/b/16699
-    // and http://crbug.com/12361). The logic below matches latest versions of IE, Firefox,
-    // Chrome and Safari on some old platforms. The latest version of Safari supports quoted
-    // cookie values, though.
-    const keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this._input);
-    if (!keyValueMatch) {
-      console.error('Failed parsing cookie header before: ' + this._input);
-      return null;
-    }
-
-    const result = new SDK.CookieParser.KeyValue(
-        keyValueMatch[1], keyValueMatch[2] && keyValueMatch[2].trim(), this._originalInputLength - this._input.length);
-    this._input = this._input.slice(keyValueMatch[0].length);
-    return result;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _advanceAndCheckCookieDelimiter() {
-    const match = /^\s*[\n;]\s*/.exec(this._input);
-    if (!match)
-      return false;
-    this._input = this._input.slice(match[0].length);
-    return match[0].match('\n') !== null;
-  }
-
-  /**
-   * @param {!SDK.CookieParser.KeyValue} keyValue
-   * @param {!SDK.Cookie.Type} type
-   */
-  _addCookie(keyValue, type) {
-    if (this._lastCookie)
-      this._lastCookie.setSize(keyValue.position - this._lastCookiePosition);
-
-    // Mozilla bug 169091: Mozilla, IE and Chrome treat single token (w/o "=") as
-    // specifying a value for a cookie with empty name.
-    this._lastCookie = typeof keyValue.value === 'string' ? new SDK.Cookie(keyValue.key, keyValue.value, type) :
-                                                            new SDK.Cookie('', keyValue.key, type);
-    this._lastCookiePosition = keyValue.position;
-    this._cookies.push(this._lastCookie);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.CookieParser.KeyValue = class {
-  /**
-   * @param {string} key
-   * @param {string|undefined} value
-   * @param {number} position
-   */
-  constructor(key, value, position) {
-    this.key = key;
-    this.value = value;
-    this.position = position;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SDK.Cookie = class {
-  /**
-   * @param {string} name
-   * @param {string} value
-   * @param {?SDK.Cookie.Type} type
-   */
-  constructor(name, value, type) {
-    this._name = name;
-    this._value = value;
-    this._type = type;
-    this._attributes = {};
-    this._size = 0;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._name;
-  }
-
-  /**
-   * @return {string}
-   */
-  value() {
-    return this._value;
-  }
-
-  /**
-   * @return {?SDK.Cookie.Type}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  httpOnly() {
-    return 'httponly' in this._attributes;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  secure() {
-    return 'secure' in this._attributes;
-  }
-
-  /**
-   * @return {!Protocol.Network.CookieSameSite}
-   */
-  sameSite() {
-    // TODO(allada) This should not rely on _attributes and instead store them individually.
-    return /** @type {!Protocol.Network.CookieSameSite} */ (this._attributes['samesite']);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  session() {
-    // RFC 2965 suggests using Discard attribute to mark session cookies, but this does not seem to be widely used.
-    // Check for absence of explicitly max-age or expiry date instead.
-    return !('expires' in this._attributes || 'max-age' in this._attributes);
-  }
-
-  /**
-   * @return {string}
-   */
-  path() {
-    return this._attributes['path'];
-  }
-
-  /**
-   * @return {string}
-   */
-  port() {
-    return this._attributes['port'];
-  }
-
-  /**
-   * @return {string}
-   */
-  domain() {
-    return this._attributes['domain'];
-  }
-
-  /**
-   * @return {number}
-   */
-  expires() {
-    return this._attributes['expires'];
-  }
-
-  /**
-   * @return {string}
-   */
-  maxAge() {
-    return this._attributes['max-age'];
-  }
-
-  /**
-   * @return {number}
-   */
-  size() {
-    return this._size;
-  }
-
-  /**
-   * @return {string}
-   */
-  url() {
-    return (this.secure() ? 'https://' : 'http://') + this.domain() + this.path();
-  }
-
-  /**
-   * @param {number} size
-   */
-  setSize(size) {
-    this._size = size;
-  }
-
-  /**
-   * @return {?Date}
-   */
-  expiresDate(requestDate) {
-    // RFC 6265 indicates that the max-age attribute takes precedence over the expires attribute
-    if (this.maxAge()) {
-      const targetDate = requestDate === null ? new Date() : requestDate;
-      return new Date(targetDate.getTime() + 1000 * this.maxAge());
-    }
-
-    if (this.expires())
-      return new Date(this.expires());
-
-    return null;
-  }
-
-  /**
-   * @return {!Object}
-   */
-  attributes() {
-    return this._attributes;
-  }
-
-  /**
-   * @param {string} key
-   * @param {string|number=} value
-   */
-  addAttribute(key, value) {
-    this._attributes[key.toLowerCase()] = value;
-  }
-};
-
-/**
- * @enum {number}
- */
-SDK.Cookie.Type = {
-  Request: 0,
-  Response: 1
-};
diff --git a/front_end/sdk/DOMDebuggerModel.js b/front_end/sdk/DOMDebuggerModel.js
deleted file mode 100644
index af0c41a..0000000
--- a/front_end/sdk/DOMDebuggerModel.js
+++ /dev/null
@@ -1,847 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-SDK.DOMDebuggerModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._agent = target.domdebuggerAgent();
-    this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
-    this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
-    this._domModel.addEventListener(SDK.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
-    this._domModel.addEventListener(SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
-
-    /** @type {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} */
-    this._domBreakpoints = [];
-    this._domBreakpointsSetting = Common.settings.createLocalSetting('domBreakpoints', []);
-    if (this._domModel.existingDocument())
-      this._documentUpdated();
-  }
-
-  /**
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._runtimeModel;
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} remoteObject
-   * @return {!Promise<!Array<!SDK.EventListener>>}
-   */
-  async eventListeners(remoteObject) {
-    console.assert(remoteObject.runtimeModel() === this._runtimeModel);
-    if (!remoteObject.objectId)
-      return [];
-
-    const payloads = await this._agent.getEventListeners(/** @type {string} */ (remoteObject.objectId));
-    const eventListeners = [];
-    for (const payload of payloads || []) {
-      const location = this._runtimeModel.debuggerModel().createRawLocationByScriptId(
-          payload.scriptId, payload.lineNumber, payload.columnNumber);
-      if (!location)
-        continue;
-      eventListeners.push(new SDK.EventListener(
-          this, remoteObject, payload.type, payload.useCapture, payload.passive, payload.once,
-          payload.handler ? this._runtimeModel.createRemoteObject(payload.handler) : null,
-          payload.originalHandler ? this._runtimeModel.createRemoteObject(payload.originalHandler) : null, location,
-          null));
-    }
-    return eventListeners;
-  }
-
-  retrieveDOMBreakpoints() {
-    this._domModel.requestDocument();
-  }
-
-  /**
-   * @return {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>}
-   */
-  domBreakpoints() {
-    return this._domBreakpoints.slice();
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
-   * @return {boolean}
-   */
-  hasDOMBreakpoint(node, type) {
-    return this._domBreakpoints.some(breakpoint => (breakpoint.node === node && breakpoint.type === type));
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
-   * @return {!SDK.DOMDebuggerModel.DOMBreakpoint}
-   */
-  setDOMBreakpoint(node, type) {
-    for (const breakpoint of this._domBreakpoints) {
-      if (breakpoint.node === node && breakpoint.type === type) {
-        this.toggleDOMBreakpoint(breakpoint, true);
-        return breakpoint;
-      }
-    }
-    const breakpoint = new SDK.DOMDebuggerModel.DOMBreakpoint(this, node, type, true);
-    this._domBreakpoints.push(breakpoint);
-    this._saveDOMBreakpoints();
-    this._enableDOMBreakpoint(breakpoint);
-    this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, breakpoint);
-    return breakpoint;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
-   */
-  removeDOMBreakpoint(node, type) {
-    this._removeDOMBreakpoints(breakpoint => breakpoint.node === node && breakpoint.type === type);
-  }
-
-  removeAllDOMBreakpoints() {
-    this._removeDOMBreakpoints(breakpoint => true);
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint
-   * @param {boolean} enabled
-   */
-  toggleDOMBreakpoint(breakpoint, enabled) {
-    if (enabled === breakpoint.enabled)
-      return;
-    breakpoint.enabled = enabled;
-    if (enabled)
-      this._enableDOMBreakpoint(breakpoint);
-    else
-      this._disableDOMBreakpoint(breakpoint);
-    this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointToggled, breakpoint);
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint
-   */
-  _enableDOMBreakpoint(breakpoint) {
-    this._agent.setDOMBreakpoint(breakpoint.node.id, breakpoint.type);
-    breakpoint.node.setMarker(SDK.DOMDebuggerModel.DOMBreakpoint.Marker, true);
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint
-   */
-  _disableDOMBreakpoint(breakpoint) {
-    this._agent.removeDOMBreakpoint(breakpoint.node.id, breakpoint.type);
-    breakpoint.node.setMarker(
-        SDK.DOMDebuggerModel.DOMBreakpoint.Marker, this._nodeHasBreakpoints(breakpoint.node) ? true : null);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {boolean}
-   */
-  _nodeHasBreakpoints(node) {
-    for (const breakpoint of this._domBreakpoints) {
-      if (breakpoint.node === node && breakpoint.enabled)
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!Object} auxData
-   * @return {?{type: !SDK.DOMDebuggerModel.DOMBreakpoint.Type, node: !SDK.DOMNode, targetNode: ?SDK.DOMNode, insertion: boolean}}
-   */
-  resolveDOMBreakpointData(auxData) {
-    const type = auxData['type'];
-    const node = this._domModel.nodeForId(auxData['nodeId']);
-    if (!type || !node)
-      return null;
-    let targetNode = null;
-    let insertion = false;
-    if (type === SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified) {
-      insertion = auxData['insertion'] || false;
-      targetNode = this._domModel.nodeForId(auxData['targetNodeId']);
-    }
-    return {type: type, node: node, targetNode: targetNode, insertion: insertion};
-  }
-
-  /**
-   * @return {string}
-   */
-  _currentURL() {
-    const domDocument = this._domModel.existingDocument();
-    return domDocument ? domDocument.documentURL : '';
-  }
-
-  _documentUpdated() {
-    const removed = this._domBreakpoints;
-    this._domBreakpoints = [];
-    this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved, removed);
-
-    const currentURL = this._currentURL();
-    for (const breakpoint of this._domBreakpointsSetting.get()) {
-      if (breakpoint.url === currentURL)
-        this._domModel.pushNodeByPathToFrontend(breakpoint.path).then(appendBreakpoint.bind(this, breakpoint));
-    }
-
-    /**
-     * @param {!{type: !SDK.DOMDebuggerModel.DOMBreakpoint.Type, enabled: boolean}} breakpoint
-     * @param {?number} nodeId
-     * @this {SDK.DOMDebuggerModel}
-     */
-    function appendBreakpoint(breakpoint, nodeId) {
-      const node = nodeId ? this._domModel.nodeForId(nodeId) : null;
-      if (!node)
-        return;
-      const domBreakpoint = new SDK.DOMDebuggerModel.DOMBreakpoint(this, node, breakpoint.type, breakpoint.enabled);
-      this._domBreakpoints.push(domBreakpoint);
-      if (breakpoint.enabled)
-        this._enableDOMBreakpoint(domBreakpoint);
-      this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, domBreakpoint);
-    }
-  }
-
-  /**
-   * @param {function(!SDK.DOMDebuggerModel.DOMBreakpoint):boolean} filter
-   */
-  _removeDOMBreakpoints(filter) {
-    const removed = [];
-    const left = [];
-    for (const breakpoint of this._domBreakpoints) {
-      if (filter(breakpoint)) {
-        removed.push(breakpoint);
-        if (breakpoint.enabled) {
-          breakpoint.enabled = false;
-          this._disableDOMBreakpoint(breakpoint);
-        }
-      } else {
-        left.push(breakpoint);
-      }
-    }
-
-    if (!removed.length)
-      return;
-    this._domBreakpoints = left;
-    this._saveDOMBreakpoints();
-    this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved, removed);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _nodeRemoved(event) {
-    const node = /** @type {!SDK.DOMNode} */ (event.data.node);
-    const children = node.children() || [];
-    this._removeDOMBreakpoints(breakpoint => breakpoint.node === node || children.indexOf(breakpoint.node) !== -1);
-  }
-
-  _saveDOMBreakpoints() {
-    const currentURL = this._currentURL();
-    const breakpoints = this._domBreakpointsSetting.get().filter(breakpoint => breakpoint.url !== currentURL);
-    for (const breakpoint of this._domBreakpoints) {
-      breakpoints.push(
-          {url: currentURL, path: breakpoint.node.path(), type: breakpoint.type, enabled: breakpoint.enabled});
-    }
-    this._domBreakpointsSetting.set(breakpoints);
-  }
-};
-
-SDK.SDKModel.register(SDK.DOMDebuggerModel, SDK.Target.Capability.DOM, false);
-
-/** @enum {symbol} */
-SDK.DOMDebuggerModel.Events = {
-  DOMBreakpointAdded: Symbol('DOMBreakpointAdded'),
-  DOMBreakpointToggled: Symbol('DOMBreakpointToggled'),
-  DOMBreakpointsRemoved: Symbol('DOMBreakpointsRemoved'),
-};
-
-SDK.DOMDebuggerModel.DOMBreakpoint = class {
-  /**
-   * @param {!SDK.DOMDebuggerModel} domDebuggerModel
-   * @param {!SDK.DOMNode} node
-   * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type
-   * @param {boolean} enabled
-   */
-  constructor(domDebuggerModel, node, type, enabled) {
-    this.domDebuggerModel = domDebuggerModel;
-    this.node = node;
-    this.type = type;
-    this.enabled = enabled;
-  }
-};
-
-/** @typedef {Protocol.DOMDebugger.DOMBreakpointType} */
-SDK.DOMDebuggerModel.DOMBreakpoint.Type = Protocol.DOMDebugger.DOMBreakpointType;
-
-SDK.DOMDebuggerModel.DOMBreakpoint.Marker = 'breakpoint-marker';
-
-SDK.EventListener = class {
-  /**
-   * @param {!SDK.DOMDebuggerModel} domDebuggerModel
-   * @param {!SDK.RemoteObject} eventTarget
-   * @param {string} type
-   * @param {boolean} useCapture
-   * @param {boolean} passive
-   * @param {boolean} once
-   * @param {?SDK.RemoteObject} handler
-   * @param {?SDK.RemoteObject} originalHandler
-   * @param {!SDK.DebuggerModel.Location} location
-   * @param {?SDK.RemoteObject} customRemoveFunction
-   * @param {!SDK.EventListener.Origin=} origin
-   */
-  constructor(
-      domDebuggerModel, eventTarget, type, useCapture, passive, once, handler, originalHandler, location,
-      customRemoveFunction, origin) {
-    this._domDebuggerModel = domDebuggerModel;
-    this._eventTarget = eventTarget;
-    this._type = type;
-    this._useCapture = useCapture;
-    this._passive = passive;
-    this._once = once;
-    this._handler = handler;
-    this._originalHandler = originalHandler || handler;
-    this._location = location;
-    const script = location.script();
-    this._sourceURL = script ? script.contentURL() : '';
-    this._customRemoveFunction = customRemoveFunction;
-    this._origin = origin || SDK.EventListener.Origin.Raw;
-  }
-
-  /**
-   * @return {!SDK.DOMDebuggerModel}
-   */
-  domDebuggerModel() {
-    return this._domDebuggerModel;
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  useCapture() {
-    return this._useCapture;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  passive() {
-    return this._passive;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  once() {
-    return this._once;
-  }
-
-  /**
-   * @return {?SDK.RemoteObject}
-   */
-  handler() {
-    return this._handler;
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel.Location}
-   */
-  location() {
-    return this._location;
-  }
-
-  /**
-   * @return {string}
-   */
-  sourceURL() {
-    return this._sourceURL;
-  }
-
-  /**
-   * @return {?SDK.RemoteObject}
-   */
-  originalHandler() {
-    return this._originalHandler;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canRemove() {
-    return !!this._customRemoveFunction || this._origin !== SDK.EventListener.Origin.FrameworkUser;
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  remove() {
-    if (!this.canRemove())
-      return Promise.resolve();
-
-    if (this._origin !== SDK.EventListener.Origin.FrameworkUser) {
-      /**
-       * @param {string} type
-       * @param {function()} listener
-       * @param {boolean} useCapture
-       * @this {Object}
-       * @suppressReceiverCheck
-       */
-      function removeListener(type, listener, useCapture) {
-        this.removeEventListener(type, listener, useCapture);
-        if (this['on' + type])
-          this['on' + type] = undefined;
-      }
-
-      return /** @type {!Promise<undefined>} */ (this._eventTarget.callFunctionPromise(removeListener, [
-        SDK.RemoteObject.toCallArgument(this._type), SDK.RemoteObject.toCallArgument(this._originalHandler),
-        SDK.RemoteObject.toCallArgument(this._useCapture)
-      ]));
-    }
-
-    return this._customRemoveFunction
-        .callFunctionPromise(
-            callCustomRemove,
-            [
-              SDK.RemoteObject.toCallArgument(this._type),
-              SDK.RemoteObject.toCallArgument(this._originalHandler),
-              SDK.RemoteObject.toCallArgument(this._useCapture),
-              SDK.RemoteObject.toCallArgument(this._passive),
-            ])
-        .then(() => undefined);
-
-    /**
-     * @param {string} type
-     * @param {function()} listener
-     * @param {boolean} useCapture
-     * @param {boolean} passive
-     * @this {Function}
-     * @suppressReceiverCheck
-     */
-    function callCustomRemove(type, listener, useCapture, passive) {
-      this.call(null, type, listener, useCapture, passive);
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canTogglePassive() {
-    return this._origin !== SDK.EventListener.Origin.FrameworkUser;
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  togglePassive() {
-    return /** @type {!Promise<undefined>} */ (this._eventTarget.callFunctionPromise(callTogglePassive, [
-      SDK.RemoteObject.toCallArgument(this._type),
-      SDK.RemoteObject.toCallArgument(this._originalHandler),
-      SDK.RemoteObject.toCallArgument(this._useCapture),
-      SDK.RemoteObject.toCallArgument(this._passive),
-    ]));
-
-    /**
-     * @param {string} type
-     * @param {function()} listener
-     * @param {boolean} useCapture
-     * @param {boolean} passive
-     * @this {Object}
-     * @suppressReceiverCheck
-     */
-    function callTogglePassive(type, listener, useCapture, passive) {
-      this.removeEventListener(type, listener, {capture: useCapture});
-      this.addEventListener(type, listener, {capture: useCapture, passive: !passive});
-    }
-  }
-
-  /**
-   * @return {!SDK.EventListener.Origin}
-   */
-  origin() {
-    return this._origin;
-  }
-
-  markAsFramework() {
-    this._origin = SDK.EventListener.Origin.Framework;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isScrollBlockingType() {
-    return this._type === 'touchstart' || this._type === 'touchmove' || this._type === 'mousewheel' ||
-        this._type === 'wheel';
-  }
-};
-
-/** @enum {string} */
-SDK.EventListener.Origin = {
-  Raw: 'Raw',
-  Framework: 'Framework',
-  FrameworkUser: 'FrameworkUser'
-};
-
-SDK.DOMDebuggerModel.EventListenerBreakpoint = class {
-  /**
-   * @param {string} instrumentationName
-   * @param {string} eventName
-   * @param {!Array<string>} eventTargetNames
-   * @param {string} category
-   * @param {string} title
-   */
-  constructor(instrumentationName, eventName, eventTargetNames, category, title) {
-    this._instrumentationName = instrumentationName;
-    this._eventName = eventName;
-    this._eventTargetNames = eventTargetNames;
-    this._category = category;
-    this._title = title;
-    this._enabled = false;
-  }
-
-  /**
-   * @return {string}
-   */
-  category() {
-    return this._category;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  enabled() {
-    return this._enabled;
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    if (this._enabled === enabled)
-      return;
-    this._enabled = enabled;
-    for (const model of SDK.targetManager.models(SDK.DOMDebuggerModel))
-      this._updateOnModel(model);
-  }
-
-  /**
-   * @param {!SDK.DOMDebuggerModel} model
-   */
-  _updateOnModel(model) {
-    if (this._instrumentationName) {
-      if (this._enabled)
-        model._agent.setInstrumentationBreakpoint(this._instrumentationName);
-      else
-        model._agent.removeInstrumentationBreakpoint(this._instrumentationName);
-    } else {
-      for (const eventTargetName of this._eventTargetNames) {
-        if (this._enabled)
-          model._agent.setEventListenerBreakpoint(this._eventName, eventTargetName);
-        else
-          model._agent.removeEventListenerBreakpoint(this._eventName, eventTargetName);
-      }
-    }
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-};
-
-SDK.DOMDebuggerModel.EventListenerBreakpoint._listener = 'listener:';
-SDK.DOMDebuggerModel.EventListenerBreakpoint._instrumentation = 'instrumentation:';
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.DOMDebuggerModel>}
- */
-SDK.DOMDebuggerManager = class {
-  constructor() {
-    this._xhrBreakpointsSetting = Common.settings.createLocalSetting('xhrBreakpoints', []);
-    /** @type {!Map<string, boolean>} */
-    this._xhrBreakpoints = new Map();
-    for (const breakpoint of this._xhrBreakpointsSetting.get())
-      this._xhrBreakpoints.set(breakpoint.url, breakpoint.enabled);
-
-    /** @type {!Array<!SDK.DOMDebuggerModel.EventListenerBreakpoint>} */
-    this._eventListenerBreakpoints = [];
-    this._createInstrumentationBreakpoints(
-        Common.UIString('Animation'),
-        ['requestAnimationFrame', 'cancelAnimationFrame', 'requestAnimationFrame.callback']);
-    this._createInstrumentationBreakpoints(
-        Common.UIString('Canvas'), ['canvasContextCreated', 'webglErrorFired', 'webglWarningFired']);
-    this._createInstrumentationBreakpoints(
-        Common.UIString('Geolocation'), ['Geolocation.getCurrentPosition', 'Geolocation.watchPosition']);
-    this._createInstrumentationBreakpoints(Common.UIString('Notification'), ['Notification.requestPermission']);
-    this._createInstrumentationBreakpoints(Common.UIString('Parse'), ['Element.setInnerHTML', 'Document.write']);
-    this._createInstrumentationBreakpoints(Common.UIString('Script'), ['scriptFirstStatement', 'scriptBlockedByCSP']);
-    this._createInstrumentationBreakpoints(
-        Common.UIString('Timer'),
-        ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'setTimeout.callback', 'setInterval.callback']);
-    this._createInstrumentationBreakpoints(Common.UIString('Window'), ['DOMWindow.close']);
-
-    this._createEventListenerBreakpoints(
-        Common.UIString('Media'),
-        [
-          'play',      'pause',          'playing',    'canplay',    'canplaythrough', 'seeking',
-          'seeked',    'timeupdate',     'ended',      'ratechange', 'durationchange', 'volumechange',
-          'loadstart', 'progress',       'suspend',    'abort',      'error',          'emptied',
-          'stalled',   'loadedmetadata', 'loadeddata', 'waiting'
-        ],
-        ['audio', 'video']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Clipboard'), ['copy', 'cut', 'paste', 'beforecopy', 'beforecut', 'beforepaste'], ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Control'),
-        ['resize', 'scroll', 'zoom', 'focus', 'blur', 'select', 'change', 'submit', 'reset'], ['*']);
-    this._createEventListenerBreakpoints(Common.UIString('Device'), ['deviceorientation', 'devicemotion'], ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('DOM Mutation'),
-        [
-          'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMNodeInserted',
-          'DOMNodeInsertedIntoDocument', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMSubtreeModified',
-          'DOMContentLoaded'
-        ],
-        ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Drag / drop'), ['drag', 'dragstart', 'dragend', 'dragenter', 'dragover', 'dragleave', 'drop'],
-        ['*']);
-
-    this._createEventListenerBreakpoints(Common.UIString('Keyboard'), ['keydown', 'keyup', 'keypress', 'input'], ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Load'), ['load', 'beforeunload', 'unload', 'abort', 'error', 'hashchange', 'popstate'], ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Mouse'),
-        [
-          'auxclick', 'click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout', 'mouseenter',
-          'mouseleave', 'mousewheel', 'wheel', 'contextmenu'
-        ],
-        ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Pointer'),
-        [
-          'pointerover', 'pointerout', 'pointerenter', 'pointerleave', 'pointerdown', 'pointerup', 'pointermove',
-          'pointercancel', 'gotpointercapture', 'lostpointercapture'
-        ],
-        ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('Touch'), ['touchstart', 'touchmove', 'touchend', 'touchcancel'], ['*']);
-    this._createEventListenerBreakpoints(Common.UIString('Worker'), ['message', 'messageerror'], ['*']);
-    this._createEventListenerBreakpoints(
-        Common.UIString('XHR'),
-        ['readystatechange', 'load', 'loadstart', 'loadend', 'abort', 'error', 'progress', 'timeout'],
-        ['xmlhttprequest', 'xmlhttprequestupload']);
-
-    this._resolveEventListenerBreakpoint('instrumentation:setTimeout.callback')._title =
-        Common.UIString('setTimeout fired');
-    this._resolveEventListenerBreakpoint('instrumentation:setInterval.callback')._title =
-        Common.UIString('setInterval fired');
-    this._resolveEventListenerBreakpoint('instrumentation:scriptFirstStatement')._title =
-        Common.UIString('Script First Statement');
-    this._resolveEventListenerBreakpoint('instrumentation:scriptBlockedByCSP')._title =
-        Common.UIString('Script Blocked by Content Security Policy');
-    this._resolveEventListenerBreakpoint('instrumentation:requestAnimationFrame')._title =
-        Common.UIString('Request Animation Frame');
-    this._resolveEventListenerBreakpoint('instrumentation:cancelAnimationFrame')._title =
-        Common.UIString('Cancel Animation Frame');
-    this._resolveEventListenerBreakpoint('instrumentation:requestAnimationFrame.callback')._title =
-        Common.UIString('Animation Frame Fired');
-    this._resolveEventListenerBreakpoint('instrumentation:webglErrorFired')._title =
-        Common.UIString('WebGL Error Fired');
-    this._resolveEventListenerBreakpoint('instrumentation:webglWarningFired')._title =
-        Common.UIString('WebGL Warning Fired');
-    this._resolveEventListenerBreakpoint('instrumentation:Element.setInnerHTML')._title =
-        Common.UIString('Set innerHTML');
-    this._resolveEventListenerBreakpoint('instrumentation:canvasContextCreated')._title =
-        Common.UIString('Create canvas context');
-    this._resolveEventListenerBreakpoint('instrumentation:Geolocation.getCurrentPosition')._title =
-        'getCurrentPosition';
-    this._resolveEventListenerBreakpoint('instrumentation:Geolocation.watchPosition')._title = 'watchPosition';
-    this._resolveEventListenerBreakpoint('instrumentation:Notification.requestPermission')._title = 'requestPermission';
-    this._resolveEventListenerBreakpoint('instrumentation:DOMWindow.close')._title = 'window.close';
-    this._resolveEventListenerBreakpoint('instrumentation:Document.write')._title = 'document.write';
-
-    SDK.targetManager.observeModels(SDK.DOMDebuggerModel, this);
-  }
-
-  /**
-   * @param {string} category
-   * @param {!Array<string>} instrumentationNames
-   */
-  _createInstrumentationBreakpoints(category, instrumentationNames) {
-    for (const instrumentationName of instrumentationNames) {
-      this._eventListenerBreakpoints.push(
-          new SDK.DOMDebuggerModel.EventListenerBreakpoint(instrumentationName, '', [], category, instrumentationName));
-    }
-  }
-
-  /**
-   * @param {string} category
-   * @param {!Array<string>} eventNames
-   * @param {!Array<string>} eventTargetNames
-   */
-  _createEventListenerBreakpoints(category, eventNames, eventTargetNames) {
-    for (const eventName of eventNames) {
-      this._eventListenerBreakpoints.push(
-          new SDK.DOMDebuggerModel.EventListenerBreakpoint('', eventName, eventTargetNames, category, eventName));
-    }
-  }
-
-  /**
-   * @param {string} eventName
-   * @param {string=} eventTargetName
-   * @return {?SDK.DOMDebuggerModel.EventListenerBreakpoint}
-   */
-  _resolveEventListenerBreakpoint(eventName, eventTargetName) {
-    const instrumentationPrefix = 'instrumentation:';
-    const listenerPrefix = 'listener:';
-    let instrumentationName = '';
-    if (eventName.startsWith(instrumentationPrefix)) {
-      instrumentationName = eventName.substring(instrumentationPrefix.length);
-      eventName = '';
-    } else if (eventName.startsWith(listenerPrefix)) {
-      eventName = eventName.substring(listenerPrefix.length);
-    } else {
-      return null;
-    }
-    eventTargetName = (eventTargetName || '*').toLowerCase();
-    let result = null;
-    for (const breakpoint of this._eventListenerBreakpoints) {
-      if (instrumentationName && breakpoint._instrumentationName === instrumentationName)
-        result = breakpoint;
-      if (eventName && breakpoint._eventName === eventName &&
-          breakpoint._eventTargetNames.indexOf(eventTargetName) !== -1)
-        result = breakpoint;
-      if (!result && eventName && breakpoint._eventName === eventName &&
-          breakpoint._eventTargetNames.indexOf('*') !== -1)
-        result = breakpoint;
-    }
-    return result;
-  }
-
-  /**
-   * @return {!Array<!SDK.DOMDebuggerModel.EventListenerBreakpoint>}
-   */
-  eventListenerBreakpoints() {
-    return this._eventListenerBreakpoints.slice();
-  }
-
-  /**
-   * @param {!Object} auxData
-   * @return {string}
-   */
-  resolveEventListenerBreakpointTitle(auxData) {
-    const id = auxData['eventName'];
-    if (id === 'instrumentation:webglErrorFired' && auxData['webglErrorName']) {
-      let errorName = auxData['webglErrorName'];
-      // If there is a hex code of the error, display only this.
-      errorName = errorName.replace(/^.*(0x[0-9a-f]+).*$/i, '$1');
-      return Common.UIString('WebGL Error Fired (%s)', errorName);
-    }
-    if (id === 'instrumentation:scriptBlockedByCSP' && auxData['directiveText'])
-      return Common.UIString('Script blocked due to Content Security Policy directive: %s', auxData['directiveText']);
-    const breakpoint = this._resolveEventListenerBreakpoint(id, auxData['targetName']);
-    if (!breakpoint)
-      return '';
-    if (auxData['targetName'])
-      return auxData['targetName'] + '.' + breakpoint._title;
-    return breakpoint._title;
-  }
-
-  /**
-   * @param {!Object} auxData
-   * @return {?SDK.DOMDebuggerModel.EventListenerBreakpoint}
-   */
-  resolveEventListenerBreakpoint(auxData) {
-    return this._resolveEventListenerBreakpoint(auxData['eventName'], auxData['targetName']);
-  }
-
-  /**
-   * @return {!Map<string, boolean>}
-   */
-  xhrBreakpoints() {
-    return this._xhrBreakpoints;
-  }
-
-  _saveXHRBreakpoints() {
-    const breakpoints = [];
-    for (const url of this._xhrBreakpoints.keys())
-      breakpoints.push({url: url, enabled: this._xhrBreakpoints.get(url)});
-    this._xhrBreakpointsSetting.set(breakpoints);
-  }
-
-  /**
-   * @param {string} url
-   * @param {boolean} enabled
-   */
-  addXHRBreakpoint(url, enabled) {
-    this._xhrBreakpoints.set(url, enabled);
-    if (enabled) {
-      for (const model of SDK.targetManager.models(SDK.DOMDebuggerModel))
-        model._agent.setXHRBreakpoint(url);
-    }
-    this._saveXHRBreakpoints();
-  }
-
-  /**
-   * @param {string} url
-   */
-  removeXHRBreakpoint(url) {
-    const enabled = this._xhrBreakpoints.get(url);
-    this._xhrBreakpoints.delete(url);
-    if (enabled) {
-      for (const model of SDK.targetManager.models(SDK.DOMDebuggerModel))
-        model._agent.removeXHRBreakpoint(url);
-    }
-    this._saveXHRBreakpoints();
-  }
-
-  /**
-   * @param {string} url
-   * @param {boolean} enabled
-   */
-  toggleXHRBreakpoint(url, enabled) {
-    this._xhrBreakpoints.set(url, enabled);
-    for (const model of SDK.targetManager.models(SDK.DOMDebuggerModel)) {
-      if (enabled)
-        model._agent.setXHRBreakpoint(url);
-      else
-        model._agent.removeXHRBreakpoint(url);
-    }
-    this._saveXHRBreakpoints();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DOMDebuggerModel} domDebuggerModel
-   */
-  modelAdded(domDebuggerModel) {
-    for (const url of this._xhrBreakpoints.keys()) {
-      if (this._xhrBreakpoints.get(url))
-        domDebuggerModel._agent.setXHRBreakpoint(url);
-    }
-    for (const breakpoint of this._eventListenerBreakpoints) {
-      if (breakpoint._enabled)
-        breakpoint._updateOnModel(domDebuggerModel);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DOMDebuggerModel} domDebuggerModel
-   */
-  modelRemoved(domDebuggerModel) {
-  }
-};
-
-/** @type {!SDK.DOMDebuggerManager} */
-SDK.domDebuggerManager;
diff --git a/front_end/sdk/DOMModel.js b/front_end/sdk/DOMModel.js
deleted file mode 100644
index 6dd3a94..0000000
--- a/front_end/sdk/DOMModel.js
+++ /dev/null
@@ -1,1876 +0,0 @@
-/*
- * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.DOMNode = class {
-  /**
-   * @param {!SDK.DOMModel} domModel
-   */
-  constructor(domModel) {
-    this._domModel = domModel;
-  }
-
-  /**
-   * @param {!SDK.DOMModel} domModel
-   * @param {?SDK.DOMDocument} doc
-   * @param {boolean} isInShadowTree
-   * @param {!Protocol.DOM.Node} payload
-   * @return {!SDK.DOMNode}
-   */
-  static create(domModel, doc, isInShadowTree, payload) {
-    const node = new SDK.DOMNode(domModel);
-    node._init(doc, isInShadowTree, payload);
-    return node;
-  }
-
-  /**
-   * @param {?SDK.DOMDocument} doc
-   * @param {boolean} isInShadowTree
-   * @param {!Protocol.DOM.Node} payload
-   */
-  _init(doc, isInShadowTree, payload) {
-    this._agent = this._domModel._agent;
-    this.ownerDocument = doc;
-    this._isInShadowTree = isInShadowTree;
-
-    this.id = payload.nodeId;
-    this._backendNodeId = payload.backendNodeId;
-    this._domModel._idToDOMNode[this.id] = this;
-    this._nodeType = payload.nodeType;
-    this._nodeName = payload.nodeName;
-    this._localName = payload.localName;
-    this._nodeValue = payload.nodeValue;
-    this._pseudoType = payload.pseudoType;
-    this._shadowRootType = payload.shadowRootType;
-    this._frameOwnerFrameId = payload.frameId || null;
-    this._xmlVersion = payload.xmlVersion;
-    this._isSVGNode = !!payload.isSVG;
-
-    this._shadowRoots = [];
-
-    this._attributes = [];
-    this._attributesMap = {};
-    if (payload.attributes)
-      this._setAttributesPayload(payload.attributes);
-
-    /** @type {!Map<string, ?>} */
-    this._markers = new Map();
-    this._subtreeMarkerCount = 0;
-
-    this._childNodeCount = payload.childNodeCount || 0;
-    this._children = null;
-
-    this.nextSibling = null;
-    this.previousSibling = null;
-    this.firstChild = null;
-    this.lastChild = null;
-    this.parentNode = null;
-
-    if (payload.shadowRoots) {
-      for (let i = 0; i < payload.shadowRoots.length; ++i) {
-        const root = payload.shadowRoots[i];
-        const node = SDK.DOMNode.create(this._domModel, this.ownerDocument, true, root);
-        this._shadowRoots.push(node);
-        node.parentNode = this;
-      }
-    }
-
-    if (payload.templateContent) {
-      this._templateContent = SDK.DOMNode.create(this._domModel, this.ownerDocument, true, payload.templateContent);
-      this._templateContent.parentNode = this;
-      this._children = [];
-    }
-
-    if (payload.contentDocument) {
-      this._contentDocument = SDK.DOMNode.create(this._domModel, this.ownerDocument, true, payload.contentDocument);
-      this._contentDocument.parentNode = this;
-      this._children = [];
-    } else if (payload.nodeName === 'IFRAME' && payload.frameId && Runtime.experiments.isEnabled('oopifInlineDOM')) {
-      const childTarget = SDK.targetManager.targetById(payload.frameId);
-      const childModel = childTarget ? childTarget.model(SDK.DOMModel) : null;
-      if (childModel)
-        this._childDocumentPromiseForTesting = childModel.requestDocument();
-      this._children = [];
-    }
-
-    if (payload.importedDocument) {
-      this._importedDocument = SDK.DOMNode.create(this._domModel, this.ownerDocument, true, payload.importedDocument);
-      this._importedDocument.parentNode = this;
-      this._children = [];
-    }
-
-    if (payload.distributedNodes)
-      this._setDistributedNodePayloads(payload.distributedNodes);
-
-    if (payload.children)
-      this._setChildrenPayload(payload.children);
-
-    this._setPseudoElements(payload.pseudoElements);
-
-    if (this._nodeType === Node.ELEMENT_NODE) {
-      // HTML and BODY from internal iframes should not overwrite top-level ones.
-      if (this.ownerDocument && !this.ownerDocument.documentElement && this._nodeName === 'HTML')
-        this.ownerDocument.documentElement = this;
-      if (this.ownerDocument && !this.ownerDocument.body && this._nodeName === 'BODY')
-        this.ownerDocument.body = this;
-    } else if (this._nodeType === Node.DOCUMENT_TYPE_NODE) {
-      this.publicId = payload.publicId;
-      this.systemId = payload.systemId;
-      this.internalSubset = payload.internalSubset;
-    } else if (this._nodeType === Node.ATTRIBUTE_NODE) {
-      this.name = payload.name;
-      this.value = payload.value;
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isSVGNode() {
-    return this._isSVGNode;
-  }
-
-  /**
-   * @return {!SDK.DOMModel}
-   */
-  domModel() {
-    return this._domModel;
-  }
-
-  /**
-   * @return {number}
-   */
-  backendNodeId() {
-    return this._backendNodeId;
-  }
-
-  /**
-   * @return {?Array.<!SDK.DOMNode>}
-   */
-  children() {
-    return this._children ? this._children.slice() : null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasAttributes() {
-    return this._attributes.length > 0;
-  }
-
-  /**
-   * @return {number}
-   */
-  childNodeCount() {
-    return this._childNodeCount;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasShadowRoots() {
-    return !!this._shadowRoots.length;
-  }
-
-  /**
-   * @return {!Array.<!SDK.DOMNode>}
-   */
-  shadowRoots() {
-    return this._shadowRoots.slice();
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  templateContent() {
-    return this._templateContent || null;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  contentDocument() {
-    return this._contentDocument || null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isIframe() {
-    return this._nodeName === 'IFRAME';
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  importedDocument() {
-    return this._importedDocument || null;
-  }
-
-  /**
-   * @return {number}
-   */
-  nodeType() {
-    return this._nodeType;
-  }
-
-  /**
-   * @return {string}
-   */
-  nodeName() {
-    return this._nodeName;
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  pseudoType() {
-    return this._pseudoType;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasPseudoElements() {
-    return this._pseudoElements.size > 0;
-  }
-
-  /**
-   * @return {!Map<string, !SDK.DOMNode>}
-   */
-  pseudoElements() {
-    return this._pseudoElements;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  beforePseudoElement() {
-    if (!this._pseudoElements)
-      return null;
-    return this._pseudoElements.get(SDK.DOMNode.PseudoElementNames.Before);
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  afterPseudoElement() {
-    if (!this._pseudoElements)
-      return null;
-    return this._pseudoElements.get(SDK.DOMNode.PseudoElementNames.After);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInsertionPoint() {
-    return !this.isXMLNode() &&
-        (this._nodeName === 'SHADOW' || this._nodeName === 'CONTENT' || this._nodeName === 'SLOT');
-  }
-
-  /**
-   * @return {!Array.<!SDK.DOMNodeShortcut>}
-   */
-  distributedNodes() {
-    return this._distributedNodes || [];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInShadowTree() {
-    return this._isInShadowTree;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  ancestorShadowHost() {
-    const ancestorShadowRoot = this.ancestorShadowRoot();
-    return ancestorShadowRoot ? ancestorShadowRoot.parentNode : null;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  ancestorShadowRoot() {
-    if (!this._isInShadowTree)
-      return null;
-
-    let current = this;
-    while (current && !current.isShadowRoot())
-      current = current.parentNode;
-    return current;
-  }
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  ancestorUserAgentShadowRoot() {
-    const ancestorShadowRoot = this.ancestorShadowRoot();
-    if (!ancestorShadowRoot)
-      return null;
-    return ancestorShadowRoot.shadowRootType() === SDK.DOMNode.ShadowRootTypes.UserAgent ? ancestorShadowRoot : null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShadowRoot() {
-    return !!this._shadowRootType;
-  }
-
-  /**
-   * @return {?string}
-   */
-  shadowRootType() {
-    return this._shadowRootType || null;
-  }
-
-  /**
-   * @return {string}
-   */
-  nodeNameInCorrectCase() {
-    const shadowRootType = this.shadowRootType();
-    if (shadowRootType)
-      return '#shadow-root (' + shadowRootType + ')';
-
-    // If there is no local name, it's case sensitive
-    if (!this.localName())
-      return this.nodeName();
-
-    // If the names are different lengths, there is a prefix and it's case sensitive
-    if (this.localName().length !== this.nodeName().length)
-      return this.nodeName();
-
-    // Return the localname, which will be case insensitive if its an html node
-    return this.localName();
-  }
-
-  /**
-   * @param {string} name
-   * @param {function(?Protocol.Error, ?SDK.DOMNode)=} callback
-   */
-  setNodeName(name, callback) {
-    this._agent.invoke_setNodeName({nodeId: this.id, name}).then(response => {
-      if (!response[Protocol.Error])
-        this._domModel.markUndoableState();
-      if (callback)
-        callback(response[Protocol.Error] || null, this._domModel.nodeForId(response.nodeId));
-    });
-  }
-
-  /**
-   * @return {string}
-   */
-  localName() {
-    return this._localName;
-  }
-
-  /**
-   * @return {string}
-   */
-  nodeValue() {
-    return this._nodeValue;
-  }
-
-  /**
-   * @param {string} value
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setNodeValue(value, callback) {
-    this._agent.invoke_setNodeValue({nodeId: this.id, value}).then(response => {
-      if (!response[Protocol.Error])
-        this._domModel.markUndoableState();
-      if (callback)
-        callback(response[Protocol.Error] || null);
-    });
-  }
-
-  /**
-   * @param {string} name
-   * @return {string}
-   */
-  getAttribute(name) {
-    const attr = this._attributesMap[name];
-    return attr ? attr.value : undefined;
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} text
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setAttribute(name, text, callback) {
-    this._agent.invoke_setAttributesAsText({nodeId: this.id, text, name}).then(response => {
-      if (!response[Protocol.Error])
-        this._domModel.markUndoableState();
-      if (callback)
-        callback(response[Protocol.Error] || null);
-    });
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setAttributeValue(name, value, callback) {
-    this._agent.invoke_setAttributeValue({nodeId: this.id, name, value}).then(response => {
-      if (!response[Protocol.Error])
-        this._domModel.markUndoableState();
-      if (callback)
-        callback(response[Protocol.Error] || null);
-    });
-  }
-
-  /**
-  * @param {string} name
-  * @param {string} value
-  * @return {!Promise<?Protocol.Error>}
-  */
-  setAttributeValuePromise(name, value) {
-    return new Promise(fulfill => this.setAttributeValue(name, value, fulfill));
-  }
-
-  /**
-   * @return {!Array<!SDK.DOMNode.Attribute>}
-   */
-  attributes() {
-    return this._attributes;
-  }
-
-  /**
-   * @param {string} name
-   * @return {!Promise}
-   */
-  async removeAttribute(name) {
-    const response = await this._agent.invoke_removeAttribute({nodeId: this.id, name});
-    if (response[Protocol.Error])
-      return;
-    delete this._attributesMap[name];
-    const index = this._attributes.findIndex(attr => attr.name === name);
-    if (index !== -1)
-      this._attributes.splice(index, 1);
-    this._domModel.markUndoableState();
-  }
-
-  /**
-   * @param {function(?Array<!SDK.DOMNode>)} callback
-   */
-  getChildNodes(callback) {
-    if (this._children) {
-      callback(this.children());
-      return;
-    }
-    this._agent.invoke_requestChildNodes({nodeId: this.id}).then(response => {
-      callback(response[Protocol.Error] ? null : this.children());
-    });
-  }
-
-  /**
-   * @param {number} depth
-   * @param {boolean} pierce
-   * @return {!Promise<?Array<!SDK.DOMNode>>}
-   */
-  async getSubtree(depth, pierce) {
-    const response = await this._agent.invoke_requestChildNodes({nodeId: this.id, depth: depth, pierce: pierce});
-    return response[Protocol.Error] ? null : this._children;
-  }
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  getOuterHTML() {
-    return this._agent.getOuterHTML(this.id);
-  }
-
-  /**
-   * @param {string} html
-   * @param {function(?Protocol.Error)=} callback
-   */
-  setOuterHTML(html, callback) {
-    this._agent.invoke_setOuterHTML({nodeId: this.id, outerHTML: html}).then(response => {
-      if (!response[Protocol.Error])
-        this._domModel.markUndoableState();
-      if (callback)
-        callback(response[Protocol.Error] || null);
-    });
-  }
-
-  /**
-   * @param {function(?Protocol.Error, !Protocol.DOM.NodeId=)=} callback
-   */
-  removeNode(callback) {
-    this._agent.invoke_removeNode({nodeId: this.id}).then(response => {
-      if (!response[Protocol.Error])
-        this._domModel.markUndoableState();
-      if (callback)
-        callback(response[Protocol.Error] || null);
-    });
-  }
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  async copyNode() {
-    const text = await this._agent.getOuterHTML(this.id);
-    if (text !== null)
-      InspectorFrontendHost.copyText(text);
-    return text;
-  }
-
-  /**
-   * @return {string}
-   */
-  path() {
-    /**
-     * @param {?SDK.DOMNode} node
-     */
-    function canPush(node) {
-      return node && ('index' in node || (node.isShadowRoot() && node.parentNode)) && node._nodeName.length;
-    }
-
-    const path = [];
-    let node = this;
-    while (canPush(node)) {
-      const index = typeof node.index === 'number' ?
-          node.index :
-          (node.shadowRootType() === SDK.DOMNode.ShadowRootTypes.UserAgent ? 'u' : 'a');
-      path.push([index, node._nodeName]);
-      node = node.parentNode;
-    }
-    path.reverse();
-    return path.join(',');
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   * @return {boolean}
-   */
-  isAncestor(node) {
-    if (!node)
-      return false;
-
-    let currentNode = node.parentNode;
-    while (currentNode) {
-      if (this === currentNode)
-        return true;
-      currentNode = currentNode.parentNode;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} descendant
-   * @return {boolean}
-   */
-  isDescendant(descendant) {
-    return descendant !== null && descendant.isAncestor(this);
-  }
-
-  /**
-   * @return {?Protocol.Page.FrameId}
-   */
-  frameId() {
-    let node = this.parentNode || this;
-    while (!node._frameOwnerFrameId && node.parentNode)
-      node = node.parentNode;
-    return node._frameOwnerFrameId;
-  }
-
-  /**
-   * @param {!Array.<string>} attrs
-   * @return {boolean}
-   */
-  _setAttributesPayload(attrs) {
-    let attributesChanged = !this._attributes || attrs.length !== this._attributes.length * 2;
-    const oldAttributesMap = this._attributesMap || {};
-
-    this._attributes = [];
-    this._attributesMap = {};
-
-    for (let i = 0; i < attrs.length; i += 2) {
-      const name = attrs[i];
-      const value = attrs[i + 1];
-      this._addAttribute(name, value);
-
-      if (attributesChanged)
-        continue;
-
-      if (!oldAttributesMap[name] || oldAttributesMap[name].value !== value)
-        attributesChanged = true;
-    }
-    return attributesChanged;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} prev
-   * @param {!Protocol.DOM.Node} payload
-   * @return {!SDK.DOMNode}
-   */
-  _insertChild(prev, payload) {
-    const node = SDK.DOMNode.create(this._domModel, this.ownerDocument, this._isInShadowTree, payload);
-    this._children.splice(this._children.indexOf(prev) + 1, 0, node);
-    this._renumber();
-    return node;
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   */
-  _removeChild(node) {
-    if (node.pseudoType()) {
-      this._pseudoElements.delete(node.pseudoType());
-    } else {
-      const shadowRootIndex = this._shadowRoots.indexOf(node);
-      if (shadowRootIndex !== -1) {
-        this._shadowRoots.splice(shadowRootIndex, 1);
-      } else {
-        console.assert(this._children.indexOf(node) !== -1);
-        this._children.splice(this._children.indexOf(node), 1);
-      }
-    }
-    node.parentNode = null;
-    this._subtreeMarkerCount -= node._subtreeMarkerCount;
-    if (node._subtreeMarkerCount)
-      this._domModel.dispatchEventToListeners(SDK.DOMModel.Events.MarkersChanged, this);
-    this._renumber();
-  }
-
-  /**
-   * @param {!Array.<!Protocol.DOM.Node>} payloads
-   */
-  _setChildrenPayload(payloads) {
-    this._children = [];
-    for (let i = 0; i < payloads.length; ++i) {
-      const payload = payloads[i];
-      const node = SDK.DOMNode.create(this._domModel, this.ownerDocument, this._isInShadowTree, payload);
-      this._children.push(node);
-    }
-    this._renumber();
-  }
-
-  /**
-   * @param {!Array.<!Protocol.DOM.Node>|undefined} payloads
-   */
-  _setPseudoElements(payloads) {
-    this._pseudoElements = new Map();
-    if (!payloads)
-      return;
-
-    for (let i = 0; i < payloads.length; ++i) {
-      const node = SDK.DOMNode.create(this._domModel, this.ownerDocument, this._isInShadowTree, payloads[i]);
-      node.parentNode = this;
-      this._pseudoElements.set(node.pseudoType(), node);
-    }
-  }
-
-  /**
-   * @param {!Array.<!Protocol.DOM.BackendNode>} payloads
-   */
-  _setDistributedNodePayloads(payloads) {
-    this._distributedNodes = [];
-    for (const payload of payloads) {
-      this._distributedNodes.push(
-          new SDK.DOMNodeShortcut(this._domModel.target(), payload.backendNodeId, payload.nodeType, payload.nodeName));
-    }
-  }
-
-  _renumber() {
-    this._childNodeCount = this._children.length;
-    if (this._childNodeCount === 0) {
-      this.firstChild = null;
-      this.lastChild = null;
-      return;
-    }
-    this.firstChild = this._children[0];
-    this.lastChild = this._children[this._childNodeCount - 1];
-    for (let i = 0; i < this._childNodeCount; ++i) {
-      const child = this._children[i];
-      child.index = i;
-      child.nextSibling = i + 1 < this._childNodeCount ? this._children[i + 1] : null;
-      child.previousSibling = i - 1 >= 0 ? this._children[i - 1] : null;
-      child.parentNode = this;
-    }
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   */
-  _addAttribute(name, value) {
-    const attr = {name: name, value: value, _node: this};
-    this._attributesMap[name] = attr;
-    this._attributes.push(attr);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} value
-   */
-  _setAttribute(name, value) {
-    const attr = this._attributesMap[name];
-    if (attr)
-      attr.value = value;
-    else
-      this._addAttribute(name, value);
-  }
-
-  /**
-   * @param {string} name
-   */
-  _removeAttribute(name) {
-    const attr = this._attributesMap[name];
-    if (attr) {
-      this._attributes.remove(attr);
-      delete this._attributesMap[name];
-    }
-  }
-
-  /**
-   * @param {!SDK.DOMNode} targetNode
-   * @param {?SDK.DOMNode} anchorNode
-   * @param {function(?Protocol.Error, !Protocol.DOM.NodeId=)=} callback
-   */
-  copyTo(targetNode, anchorNode, callback) {
-    this._agent
-        .invoke_copyTo(
-            {nodeId: this.id, targetNodeId: targetNode.id, insertBeforeNodeId: anchorNode ? anchorNode.id : undefined})
-        .then(response => {
-          if (!response[Protocol.Error])
-            this._domModel.markUndoableState();
-          if (callback)
-            callback(response[Protocol.Error] || null, response.nodeId);
-        });
-  }
-
-  /**
-   * @param {!SDK.DOMNode} targetNode
-   * @param {?SDK.DOMNode} anchorNode
-   * @param {function(?Protocol.Error, ?SDK.DOMNode)=} callback
-   */
-  moveTo(targetNode, anchorNode, callback) {
-    this._agent
-        .invoke_moveTo(
-            {nodeId: this.id, targetNodeId: targetNode.id, insertBeforeNodeId: anchorNode ? anchorNode.id : undefined})
-        .then(response => {
-          if (!response[Protocol.Error])
-            this._domModel.markUndoableState();
-          if (callback)
-            callback(response[Protocol.Error] || null, this._domModel.nodeForId(response.nodeId));
-        });
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isXMLNode() {
-    return !!this._xmlVersion;
-  }
-
-  /**
-   * @param {string} name
-   * @param {?*} value
-   */
-  setMarker(name, value) {
-    if (value === null) {
-      if (!this._markers.has(name))
-        return;
-
-      this._markers.delete(name);
-      for (let node = this; node; node = node.parentNode)
-        --node._subtreeMarkerCount;
-      for (let node = this; node; node = node.parentNode)
-        this._domModel.dispatchEventToListeners(SDK.DOMModel.Events.MarkersChanged, node);
-      return;
-    }
-
-    if (this.parentNode && !this._markers.has(name)) {
-      for (let node = this; node; node = node.parentNode)
-        ++node._subtreeMarkerCount;
-    }
-    this._markers.set(name, value);
-    for (let node = this; node; node = node.parentNode)
-      this._domModel.dispatchEventToListeners(SDK.DOMModel.Events.MarkersChanged, node);
-  }
-
-  /**
-   * @param {string} name
-   * @return {?T}
-   * @template T
-   */
-  marker(name) {
-    return this._markers.get(name) || null;
-  }
-
-  /**
-   * @param {function(!SDK.DOMNode, string)} visitor
-   */
-  traverseMarkers(visitor) {
-    /**
-     * @param {!SDK.DOMNode} node
-     */
-    function traverse(node) {
-      if (!node._subtreeMarkerCount)
-        return;
-      for (const marker of node._markers.keys())
-        visitor(node, marker);
-      if (!node._children)
-        return;
-      for (const child of node._children)
-        traverse(child);
-    }
-    traverse(this);
-  }
-
-  /**
-   * @param {string} url
-   * @return {?string}
-   */
-  resolveURL(url) {
-    if (!url)
-      return url;
-    for (let frameOwnerCandidate = this; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
-      if (frameOwnerCandidate.baseURL)
-        return Common.ParsedURL.completeURL(frameOwnerCandidate.baseURL, url);
-    }
-    return null;
-  }
-
-  /**
-   * @param {string=} mode
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlight(mode, objectId) {
-    this._domModel.overlayModel().highlightDOMNode(this.id, mode, undefined, objectId);
-  }
-
-  highlightForTwoSeconds() {
-    this._domModel.overlayModel().highlightDOMNodeForTwoSeconds(this.id);
-  }
-
-  /**
-   * @param {string=} objectGroup
-   * @return {!Promise<?SDK.RemoteObject>}
-   */
-  async resolveToObject(objectGroup) {
-    const object = await this._agent.resolveNode(this.id, undefined, objectGroup);
-    return object && this._domModel._runtimeModel.createRemoteObject(object);
-  }
-
-  /**
-   * @return {!Promise<?Protocol.DOM.BoxModel>}
-   */
-  boxModel() {
-    return this._agent.getBoxModel(this.id);
-  }
-
-  setAsInspectedNode() {
-    let node = this;
-    while (true) {
-      let ancestor = node.ancestorUserAgentShadowRoot();
-      if (!ancestor)
-        break;
-      ancestor = node.ancestorShadowHost();
-      if (!ancestor)
-        break;
-      // User agent shadow root, keep climbing up.
-      node = ancestor;
-    }
-    this._agent.setInspectedNode(node.id);
-  }
-
-  /**
-   *  @return {?SDK.DOMNode}
-   */
-  enclosingElementOrSelf() {
-    let node = this;
-    if (node && node.nodeType() === Node.TEXT_NODE && node.parentNode)
-      node = node.parentNode;
-
-    if (node && node.nodeType() !== Node.ELEMENT_NODE)
-      node = null;
-    return node;
-  }
-
-  async scrollIntoView() {
-    const node = this.enclosingElementOrSelf();
-    const object = await node.resolveToObject();
-    if (!object)
-      return;
-    object.callFunction(scrollIntoView);
-    object.release();
-    node.highlightForTwoSeconds();
-
-    /**
-     * @suppressReceiverCheck
-     * @this {!Element}
-     */
-    function scrollIntoView() {
-      this.scrollIntoViewIfNeeded(true);
-    }
-  }
-
-  async focus() {
-    const node = this.enclosingElementOrSelf();
-    const object = await node.resolveToObject();
-    if (!object)
-      return;
-    await object.callFunctionPromise(focusInPage);
-    object.release();
-    node.highlightForTwoSeconds();
-    this._domModel.target().pageAgent().bringToFront();
-
-    /**
-     * @suppressReceiverCheck
-     * @this {!Element}
-     */
-    function focusInPage() {
-      this.focus();
-    }
-  }
-
-  /**
-   * @return {string}
-   */
-  simpleSelector() {
-    const lowerCaseName = this.localName() || this.nodeName().toLowerCase();
-    if (this.nodeType() !== Node.ELEMENT_NODE)
-      return lowerCaseName;
-    if (lowerCaseName === 'input' && this.getAttribute('type') && !this.getAttribute('id') &&
-        !this.getAttribute('class'))
-      return lowerCaseName + '[type="' + this.getAttribute('type') + '"]';
-    if (this.getAttribute('id'))
-      return lowerCaseName + '#' + this.getAttribute('id');
-    if (this.getAttribute('class')) {
-      return (lowerCaseName === 'div' ? '' : lowerCaseName) + '.' +
-          this.getAttribute('class').trim().replace(/\s+/g, '.');
-    }
-    return lowerCaseName;
-  }
-};
-
-/**
- * @enum {string}
- */
-SDK.DOMNode.PseudoElementNames = {
-  Before: 'before',
-  After: 'after'
-};
-
-/**
- * @enum {string}
- */
-SDK.DOMNode.ShadowRootTypes = {
-  UserAgent: 'user-agent',
-  Open: 'open',
-  Closed: 'closed'
-};
-
-/** @typedef {{name: string, value: string, _node: SDK.DOMNode}} */
-SDK.DOMNode.Attribute;
-
-/**
- * @unrestricted
- */
-SDK.DeferredDOMNode = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {number} backendNodeId
-   */
-  constructor(target, backendNodeId) {
-    this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
-    this._backendNodeId = backendNodeId;
-  }
-
-  /**
-   * @param {function(?SDK.DOMNode)} callback
-   */
-  resolve(callback) {
-    this.resolvePromise().then(callback);
-  }
-
-  /**
-   * @return {!Promise<?SDK.DOMNode>}
-   */
-  async resolvePromise() {
-    const nodeIds = await this._domModel.pushNodesByBackendIdsToFrontend(new Set([this._backendNodeId]));
-    return nodeIds && nodeIds.get(this._backendNodeId) || null;
-  }
-
-  /**
-   * @return {number}
-   */
-  backendNodeId() {
-    return this._backendNodeId;
-  }
-
-  /**
-   * @return {!SDK.DOMModel}
-   */
-  domModel() {
-    return this._domModel;
-  }
-
-  highlight() {
-    this._domModel.overlayModel().highlightDOMNode(undefined, undefined, this._backendNodeId);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DOMNodeShortcut = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {number} backendNodeId
-   * @param {number} nodeType
-   * @param {string} nodeName
-   */
-  constructor(target, backendNodeId, nodeType, nodeName) {
-    this.nodeType = nodeType;
-    this.nodeName = nodeName;
-    this.deferredNode = new SDK.DeferredDOMNode(target, backendNodeId);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DOMDocument = class extends SDK.DOMNode {
-  /**
-   * @param {!SDK.DOMModel} domModel
-   * @param {!Protocol.DOM.Node} payload
-   */
-  constructor(domModel, payload) {
-    super(domModel);
-    this._init(this, false, payload);
-    this.documentURL = payload.documentURL || '';
-    this.baseURL = payload.baseURL || '';
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DOMModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    this._agent = target.domAgent();
-
-    /** @type {!Object.<number, !SDK.DOMNode>} */
-    this._idToDOMNode = {};
-    /** @type {?SDK.DOMDocument} */
-    this._document = null;
-    /** @type {!Set<number>} */
-    this._attributeLoadNodeIds = new Set();
-    target.registerDOMDispatcher(new SDK.DOMDispatcher(this));
-
-    this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
-
-    if (!target.suspended())
-      this._agent.enable();
-  }
-
-  /**
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._runtimeModel;
-  }
-
-  /**
-   * @return {!SDK.CSSModel}
-   */
-  cssModel() {
-    return /** @type {!SDK.CSSModel} */ (this.target().model(SDK.CSSModel));
-  }
-
-  /**
-   * @return {!SDK.OverlayModel}
-   */
-  overlayModel() {
-    return /** @type {!SDK.OverlayModel} */ (this.target().model(SDK.OverlayModel));
-  }
-
-  static cancelSearch() {
-    for (const domModel of SDK.targetManager.models(SDK.DOMModel))
-      domModel._cancelSearch();
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   */
-  _scheduleMutationEvent(node) {
-    if (!this.hasEventListeners(SDK.DOMModel.Events.DOMMutated))
-      return;
-
-    this._lastMutationId = (this._lastMutationId || 0) + 1;
-    Promise.resolve().then(callObserve.bind(this, node, this._lastMutationId));
-
-    /**
-     * @this {SDK.DOMModel}
-     * @param {!SDK.DOMNode} node
-     * @param {number} mutationId
-     */
-    function callObserve(node, mutationId) {
-      if (!this.hasEventListeners(SDK.DOMModel.Events.DOMMutated) || this._lastMutationId !== mutationId)
-        return;
-
-      this.dispatchEventToListeners(SDK.DOMModel.Events.DOMMutated, node);
-    }
-  }
-
-  /**
-   * @return {!Promise<!SDK.DOMDocument>}
-   */
-  requestDocument() {
-    if (this._document)
-      return Promise.resolve(this._document);
-    if (!this._pendingDocumentRequestPromise)
-      this._pendingDocumentRequestPromise = this._requestDocument();
-    return this._pendingDocumentRequestPromise;
-  }
-
-  /**
-   * @return {!Promise<!SDK.DOMDocument>}
-   */
-  async _requestDocument() {
-    const documentPayload = await this._agent.getDocument();
-    delete this._pendingDocumentRequestPromise;
-
-    if (documentPayload)
-      this._setDocument(documentPayload);
-    if (!this._document) {
-      console.error('No document');
-      return null;
-    }
-
-    const parentModel = this.parentModel();
-    if (parentModel && !this._frameOwnerNode) {
-      await parentModel.requestDocument();
-      const response = await parentModel._agent.invoke_getFrameOwner({frameId: this.target().id()});
-      if (!response[Protocol.Error])
-        this._frameOwnerNode = parentModel.nodeForId(response.nodeId);
-    }
-
-    // Document could have been cleared by now.
-    if (this._frameOwnerNode) {
-      const oldDocument = this._frameOwnerNode._contentDocument;
-      this._frameOwnerNode._contentDocument = this._document;
-      this._frameOwnerNode._children = [];
-      if (this._document) {
-        this._document.parentNode = this._frameOwnerNode;
-        this.dispatchEventToListeners(SDK.DOMModel.Events.NodeInserted, this._document);
-      } else if (oldDocument) {
-        this.dispatchEventToListeners(
-            SDK.DOMModel.Events.NodeRemoved, {node: oldDocument, parent: this._frameOwnerNode});
-      }
-    }
-    return this._document;
-  }
-
-  /**
-   * @return {?SDK.DOMDocument}
-   */
-  existingDocument() {
-    return this._document;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.RemoteObjectId} objectId
-   * @return {!Promise<?SDK.DOMNode>}
-   */
-  async pushNodeToFrontend(objectId) {
-    await this.requestDocument();
-    const nodeId = await this._agent.requestNode(objectId);
-    return nodeId ? this.nodeForId(nodeId) : null;
-  }
-
-  /**
-   * @param {string} path
-   * @return {!Promise<?Protocol.DOM.NodeId>}
-   */
-  pushNodeByPathToFrontend(path) {
-    return this.requestDocument().then(() => this._agent.pushNodeByPathToFrontend(path));
-  }
-
-  /**
-   * @param {!Set<number>} backendNodeIds
-   * @return {!Promise<?Map<number, ?SDK.DOMNode>>}
-   */
-  async pushNodesByBackendIdsToFrontend(backendNodeIds) {
-    await this.requestDocument();
-    const backendNodeIdsArray = backendNodeIds.valuesArray();
-    const nodeIds = await this._agent.pushNodesByBackendIdsToFrontend(backendNodeIdsArray);
-    if (!nodeIds)
-      return null;
-    /** @type {!Map<number, ?SDK.DOMNode>} */
-    const map = new Map();
-    for (let i = 0; i < nodeIds.length; ++i) {
-      if (nodeIds[i])
-        map.set(backendNodeIdsArray[i], this.nodeForId(nodeIds[i]));
-    }
-    return map;
-  }
-
-  /**
-   * @param {function(?T)} callback
-   * @return {function(?Protocol.Error, !T=)}
-   * @template T
-   */
-  _wrapClientCallback(callback) {
-    /**
-     * @param {?Protocol.Error} error
-     * @param {!T=} result
-     * @template T
-     */
-    function wrapper(error, result) {
-      // Caller is responsible for handling the actual error.
-      callback(error ? null : result || null);
-    }
-    return wrapper;
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} name
-   * @param {string} value
-   */
-  _attributeModified(nodeId, name, value) {
-    const node = this._idToDOMNode[nodeId];
-    if (!node)
-      return;
-
-    node._setAttribute(name, value);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.AttrModified, {node: node, name: name});
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} name
-   */
-  _attributeRemoved(nodeId, name) {
-    const node = this._idToDOMNode[nodeId];
-    if (!node)
-      return;
-    node._removeAttribute(name);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.AttrRemoved, {node: node, name: name});
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Array<!Protocol.DOM.NodeId>} nodeIds
-   */
-  _inlineStyleInvalidated(nodeIds) {
-    this._attributeLoadNodeIds.addAll(nodeIds);
-    if (!this._loadNodeAttributesTimeout)
-      this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bind(this), 20);
-  }
-
-  _loadNodeAttributes() {
-    delete this._loadNodeAttributesTimeout;
-    for (const nodeId of this._attributeLoadNodeIds) {
-      this._agent.getAttributes(nodeId).then(attributes => {
-        if (!attributes) {
-          // We are calling _loadNodeAttributes asynchronously, it is ok if node is not found.
-          return;
-        }
-        const node = this._idToDOMNode[nodeId];
-        if (!node)
-          return;
-        if (node._setAttributesPayload(attributes)) {
-          this.dispatchEventToListeners(SDK.DOMModel.Events.AttrModified, {node: node, name: 'style'});
-          this._scheduleMutationEvent(node);
-        }
-      });
-    }
-    this._attributeLoadNodeIds.clear();
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} newValue
-   */
-  _characterDataModified(nodeId, newValue) {
-    const node = this._idToDOMNode[nodeId];
-    node._nodeValue = newValue;
-    this.dispatchEventToListeners(SDK.DOMModel.Events.CharacterDataModified, node);
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @return {?SDK.DOMNode}
-   */
-  nodeForId(nodeId) {
-    return this._idToDOMNode[nodeId] || null;
-  }
-
-  _documentUpdated() {
-    // If we have this._pendingDocumentRequestPromise in flight,
-    // if it hits backend post document update, it will contain most recent result.
-    const documentWasRequested = this._document || this._pendingDocumentRequestPromise;
-    this._setDocument(null);
-    if (this.parentModel() && documentWasRequested)
-      this.requestDocument();
-  }
-
-  /**
-   * @param {?Protocol.DOM.Node} payload
-   */
-  _setDocument(payload) {
-    this._idToDOMNode = {};
-    if (payload && 'nodeId' in payload)
-      this._document = new SDK.DOMDocument(this, payload);
-    else
-      this._document = null;
-    SDK.domModelUndoStack._dispose(this);
-
-    if (!this.parentModel())
-      this.dispatchEventToListeners(SDK.DOMModel.Events.DocumentUpdated, this);
-  }
-
-  /**
-   * @param {!Protocol.DOM.Node} payload
-   */
-  _setDetachedRoot(payload) {
-    if (payload.nodeName === '#document')
-      new SDK.DOMDocument(this, payload);
-    else
-      SDK.DOMNode.create(this, null, false, payload);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Array.<!Protocol.DOM.Node>} payloads
-   */
-  _setChildNodes(parentId, payloads) {
-    if (!parentId && payloads.length) {
-      this._setDetachedRoot(payloads[0]);
-      return;
-    }
-
-    const parent = this._idToDOMNode[parentId];
-    parent._setChildrenPayload(payloads);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {number} newValue
-   */
-  _childNodeCountUpdated(nodeId, newValue) {
-    const node = this._idToDOMNode[nodeId];
-    node._childNodeCount = newValue;
-    this.dispatchEventToListeners(SDK.DOMModel.Events.ChildNodeCountUpdated, node);
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Protocol.DOM.NodeId} prevId
-   * @param {!Protocol.DOM.Node} payload
-   */
-  _childNodeInserted(parentId, prevId, payload) {
-    const parent = this._idToDOMNode[parentId];
-    const prev = this._idToDOMNode[prevId];
-    const node = parent._insertChild(prev, payload);
-    this._idToDOMNode[node.id] = node;
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeInserted, node);
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  _childNodeRemoved(parentId, nodeId) {
-    const parent = this._idToDOMNode[parentId];
-    const node = this._idToDOMNode[nodeId];
-    parent._removeChild(node);
-    this._unbind(node);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeRemoved, {node: node, parent: parent});
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} hostId
-   * @param {!Protocol.DOM.Node} root
-   */
-  _shadowRootPushed(hostId, root) {
-    const host = this._idToDOMNode[hostId];
-    if (!host)
-      return;
-    const node = SDK.DOMNode.create(this, host.ownerDocument, true, root);
-    node.parentNode = host;
-    this._idToDOMNode[node.id] = node;
-    host._shadowRoots.unshift(node);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeInserted, node);
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} hostId
-   * @param {!Protocol.DOM.NodeId} rootId
-   */
-  _shadowRootPopped(hostId, rootId) {
-    const host = this._idToDOMNode[hostId];
-    if (!host)
-      return;
-    const root = this._idToDOMNode[rootId];
-    if (!root)
-      return;
-    host._removeChild(root);
-    this._unbind(root);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeRemoved, {node: root, parent: host});
-    this._scheduleMutationEvent(root);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Protocol.DOM.Node} pseudoElement
-   */
-  _pseudoElementAdded(parentId, pseudoElement) {
-    const parent = this._idToDOMNode[parentId];
-    if (!parent)
-      return;
-    const node = SDK.DOMNode.create(this, parent.ownerDocument, false, pseudoElement);
-    node.parentNode = parent;
-    this._idToDOMNode[node.id] = node;
-    console.assert(!parent._pseudoElements.get(node.pseudoType()));
-    parent._pseudoElements.set(node.pseudoType(), node);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeInserted, node);
-    this._scheduleMutationEvent(node);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Protocol.DOM.NodeId} pseudoElementId
-   */
-  _pseudoElementRemoved(parentId, pseudoElementId) {
-    const parent = this._idToDOMNode[parentId];
-    if (!parent)
-      return;
-    const pseudoElement = this._idToDOMNode[pseudoElementId];
-    if (!pseudoElement)
-      return;
-    parent._removeChild(pseudoElement);
-    this._unbind(pseudoElement);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.NodeRemoved, {node: pseudoElement, parent: parent});
-    this._scheduleMutationEvent(pseudoElement);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} insertionPointId
-   * @param {!Array.<!Protocol.DOM.BackendNode>} distributedNodes
-   */
-  _distributedNodesUpdated(insertionPointId, distributedNodes) {
-    const insertionPoint = this._idToDOMNode[insertionPointId];
-    if (!insertionPoint)
-      return;
-    insertionPoint._setDistributedNodePayloads(distributedNodes);
-    this.dispatchEventToListeners(SDK.DOMModel.Events.DistributedNodesChanged, insertionPoint);
-    this._scheduleMutationEvent(insertionPoint);
-  }
-
-  /**
-   * @param {!SDK.DOMNode} node
-   */
-  _unbind(node) {
-    delete this._idToDOMNode[node.id];
-    for (let i = 0; node._children && i < node._children.length; ++i)
-      this._unbind(node._children[i]);
-    for (let i = 0; i < node._shadowRoots.length; ++i)
-      this._unbind(node._shadowRoots[i]);
-    const pseudoElements = node.pseudoElements();
-    for (const value of pseudoElements.values())
-      this._unbind(value);
-    if (node._templateContent)
-      this._unbind(node._templateContent);
-  }
-
-  /**
-   * @param {string} query
-   * @param {boolean} includeUserAgentShadowDOM
-   * @return {!Promise<number>}
-   */
-  async performSearch(query, includeUserAgentShadowDOM) {
-    const response = await this._agent.invoke_performSearch({query, includeUserAgentShadowDOM});
-    if (!response[Protocol.Error])
-      this._searchId = response.searchId;
-    return response[Protocol.Error] ? 0 : response.resultCount;
-  }
-
-  /**
-   * @param {number} index
-   * @return {!Promise<?SDK.DOMNode>}
-   */
-  async searchResult(index) {
-    if (!this._searchId)
-      return null;
-    const nodeIds = await this._agent.getSearchResults(this._searchId, index, index + 1);
-    return nodeIds && nodeIds.length === 1 ? this.nodeForId(nodeIds[0]) : null;
-  }
-
-  _cancelSearch() {
-    if (!this._searchId)
-      return;
-    this._agent.discardSearchResults(this._searchId);
-    delete this._searchId;
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @return {!Promise<!Array<string>>}
-   */
-  classNamesPromise(nodeId) {
-    return this._agent.collectClassNamesFromSubtree(nodeId).then(classNames => classNames || []);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} selectors
-   * @return {!Promise<?Protocol.DOM.NodeId>}
-   */
-  querySelector(nodeId, selectors) {
-    return this._agent.querySelector(nodeId, selectors);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} selectors
-   * @return {!Promise<?Array<!Protocol.DOM.NodeId>>}
-   */
-  querySelectorAll(nodeId, selectors) {
-    return this._agent.querySelectorAll(nodeId, selectors);
-  }
-
-  /**
-   * @param {boolean=} minorChange
-   */
-  markUndoableState(minorChange) {
-    SDK.domModelUndoStack._markUndoableState(this, minorChange || false);
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @param {boolean} includeUserAgentShadowDOM
-   * @return {!Promise<?SDK.DOMNode>}
-   */
-  nodeForLocation(x, y, includeUserAgentShadowDOM) {
-    return this._agent.getNodeForLocation(x, y, includeUserAgentShadowDOM)
-        .then(nodeId => nodeId ? this.nodeForId(nodeId) : null);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @return {!Promise<?SDK.DOMNode>}
-   */
-  pushObjectAsNodeToFrontend(object) {
-    return object.isNode() ? this.pushNodeToFrontend(/** @type {string} */ (object.objectId)) : Promise.resolve(null);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  suspendModel() {
-    return this._agent.disable().then(() => this._setDocument(null));
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  resumeModel() {
-    return this._agent.enable();
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    SDK.domModelUndoStack._dispose(this);
-  }
-
-  /**
-   * @return {?SDK.DOMModel}
-   */
-  parentModel() {
-    if (!Runtime.experiments.isEnabled('oopifInlineDOM'))
-      return null;
-    const parentTarget = this.target().parentTarget();
-    return parentTarget ? parentTarget.model(SDK.DOMModel) : null;
-  }
-};
-
-SDK.SDKModel.register(SDK.DOMModel, SDK.Target.Capability.DOM, true);
-
-/** @enum {symbol} */
-SDK.DOMModel.Events = {
-  AttrModified: Symbol('AttrModified'),
-  AttrRemoved: Symbol('AttrRemoved'),
-  CharacterDataModified: Symbol('CharacterDataModified'),
-  DOMMutated: Symbol('DOMMutated'),
-  NodeInserted: Symbol('NodeInserted'),
-  NodeRemoved: Symbol('NodeRemoved'),
-  DocumentUpdated: Symbol('DocumentUpdated'),
-  ChildNodeCountUpdated: Symbol('ChildNodeCountUpdated'),
-  DistributedNodesChanged: Symbol('DistributedNodesChanged'),
-  MarkersChanged: Symbol('MarkersChanged')
-};
-
-
-/**
- * @implements {Protocol.DOMDispatcher}
- * @unrestricted
- */
-SDK.DOMDispatcher = class {
-  /**
-   * @param {!SDK.DOMModel} domModel
-   */
-  constructor(domModel) {
-    this._domModel = domModel;
-  }
-
-  /**
-   * @override
-   */
-  documentUpdated() {
-    this._domModel._documentUpdated();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} name
-   * @param {string} value
-   */
-  attributeModified(nodeId, name, value) {
-    this._domModel._attributeModified(nodeId, name, value);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} name
-   */
-  attributeRemoved(nodeId, name) {
-    this._domModel._attributeRemoved(nodeId, name);
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!Protocol.DOM.NodeId>} nodeIds
-   */
-  inlineStyleInvalidated(nodeIds) {
-    this._domModel._inlineStyleInvalidated(nodeIds);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {string} characterData
-   */
-  characterDataModified(nodeId, characterData) {
-    this._domModel._characterDataModified(nodeId, characterData);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Array.<!Protocol.DOM.Node>} payloads
-   */
-  setChildNodes(parentId, payloads) {
-    this._domModel._setChildNodes(parentId, payloads);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
-   * @param {number} childNodeCount
-   */
-  childNodeCountUpdated(nodeId, childNodeCount) {
-    this._domModel._childNodeCountUpdated(nodeId, childNodeCount);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} parentNodeId
-   * @param {!Protocol.DOM.NodeId} previousNodeId
-   * @param {!Protocol.DOM.Node} payload
-   */
-  childNodeInserted(parentNodeId, previousNodeId, payload) {
-    this._domModel._childNodeInserted(parentNodeId, previousNodeId, payload);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} parentNodeId
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  childNodeRemoved(parentNodeId, nodeId) {
-    this._domModel._childNodeRemoved(parentNodeId, nodeId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} hostId
-   * @param {!Protocol.DOM.Node} root
-   */
-  shadowRootPushed(hostId, root) {
-    this._domModel._shadowRootPushed(hostId, root);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} hostId
-   * @param {!Protocol.DOM.NodeId} rootId
-   */
-  shadowRootPopped(hostId, rootId) {
-    this._domModel._shadowRootPopped(hostId, rootId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Protocol.DOM.Node} pseudoElement
-   */
-  pseudoElementAdded(parentId, pseudoElement) {
-    this._domModel._pseudoElementAdded(parentId, pseudoElement);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} parentId
-   * @param {!Protocol.DOM.NodeId} pseudoElementId
-   */
-  pseudoElementRemoved(parentId, pseudoElementId) {
-    this._domModel._pseudoElementRemoved(parentId, pseudoElementId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} insertionPointId
-   * @param {!Array.<!Protocol.DOM.BackendNode>} distributedNodes
-   */
-  distributedNodesUpdated(insertionPointId, distributedNodes) {
-    this._domModel._distributedNodesUpdated(insertionPointId, distributedNodes);
-  }
-};
-
-SDK.DOMModelUndoStack = class {
-  constructor() {
-    /** @type {!Array<!SDK.DOMModel>} */
-    this._stack = [];
-    this._index = 0;
-    /** @type {?SDK.DOMModel} */
-    this._lastModelWithMinorChange = null;
-  }
-
-  /**
-   * @param {!SDK.DOMModel} model
-   * @param {boolean} minorChange
-   */
-  _markUndoableState(model, minorChange) {
-    // Both minor and major changes get into the stack, but minor updates are coalesced.
-    // Commit major undoable state in the old model upon model switch.
-    if (this._lastModelWithMinorChange && model !== this._lastModelWithMinorChange) {
-      this._lastModelWithMinorChange.markUndoableState();
-      this._lastModelWithMinorChange = null;
-    }
-
-    // Previous minor change is already in the stack.
-    if (minorChange && this._lastModelWithMinorChange === model)
-      return;
-
-    this._stack = this._stack.slice(0, this._index);
-    this._stack.push(model);
-    this._index = this._stack.length;
-
-    // Delay marking as major undoable states in case of minor operations until the
-    // major or model switch.
-    if (minorChange) {
-      this._lastModelWithMinorChange = model;
-    } else {
-      model._agent.markUndoableState();
-      this._lastModelWithMinorChange = null;
-    }
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  undo() {
-    if (this._index === 0)
-      return Promise.resolve();
-    --this._index;
-    this._lastModelWithMinorChange = null;
-    return this._stack[this._index]._agent.undo();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  redo() {
-    if (this._index >= this._stack.length)
-      return Promise.resolve();
-    ++this._index;
-    this._lastModelWithMinorChange = null;
-    return this._stack[this._index - 1]._agent.redo();
-  }
-
-  /**
-   * @param {!SDK.DOMModel} model
-   */
-  _dispose(model) {
-    let shift = 0;
-    for (let i = 0; i < this._index; ++i) {
-      if (this._stack[i] === model)
-        ++shift;
-    }
-    this._stack.remove(model);
-    this._index -= shift;
-    if (this._lastModelWithMinorChange === model)
-      this._lastModelWithMinorChange = null;
-  }
-};
-
-SDK.domModelUndoStack = new SDK.DOMModelUndoStack();
diff --git a/front_end/sdk/DebuggerModel.js b/front_end/sdk/DebuggerModel.js
deleted file mode 100644
index c71ecb3..0000000
--- a/front_end/sdk/DebuggerModel.js
+++ /dev/null
@@ -1,1493 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.DebuggerModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    target.registerDebuggerDispatcher(new SDK.DebuggerDispatcher(this));
-    this._agent = target.debuggerAgent();
-    this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
-
-    /** @type {!SDK.SourceMapManager<!SDK.Script>} */
-    this._sourceMapManager = new SDK.SourceMapManager(target);
-    /** @type {!Map<string, !SDK.Script>} */
-    this._sourceMapIdToScript = new Map();
-
-    /** @type {?SDK.DebuggerPausedDetails} */
-    this._debuggerPausedDetails = null;
-    /** @type {!Map<string, !SDK.Script>} */
-    this._scripts = new Map();
-    /** @type {!Map.<string, !Array.<!SDK.Script>>} */
-    this._scriptsBySourceURL = new Map();
-    /** @type {!Array.<!SDK.Script>} */
-    this._discardableScripts = [];
-
-    /** @type {!Common.Object} */
-    this._breakpointResolvedEventTarget = new Common.Object();
-
-    this._isPausing = false;
-    Common.moduleSetting('pauseOnExceptionEnabled').addChangeListener(this._pauseOnExceptionStateChanged, this);
-    Common.moduleSetting('pauseOnCaughtException').addChangeListener(this._pauseOnExceptionStateChanged, this);
-    Common.moduleSetting('disableAsyncStackTraces').addChangeListener(this._asyncStackTracesStateChanged, this);
-    Common.moduleSetting('breakpointsActive').addChangeListener(this._breakpointsActiveChanged, this);
-
-    if (!target.suspended())
-      this._enableDebugger();
-
-    /** @type {!Map<string, string>} */
-    this._stringMap = new Map();
-    this._sourceMapManager.setEnabled(Common.moduleSetting('jsSourceMapsEnabled').get());
-    Common.moduleSetting('jsSourceMapsEnabled')
-        .addChangeListener(event => this._sourceMapManager.setEnabled(/** @type {boolean} */ (event.data)));
-  }
-
-  /**
-   * @param {string} executionContextId
-   * @param {string} sourceURL
-   * @param {?string} sourceMapURL
-   * @return {?string}
-   */
-  static _sourceMapId(executionContextId, sourceURL, sourceMapURL) {
-    if (!sourceMapURL)
-      return null;
-    return executionContextId + ':' + sourceURL + ':' + sourceMapURL;
-  }
-
-  /**
-   * @return {!SDK.SourceMapManager<!SDK.Script>}
-   */
-  sourceMapManager() {
-    return this._sourceMapManager;
-  }
-
-  /**
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._runtimeModel;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  debuggerEnabled() {
-    return !!this._debuggerEnabled;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _enableDebugger() {
-    if (this._debuggerEnabled)
-      return Promise.resolve();
-    this._debuggerEnabled = true;
-
-    const enablePromise = this._agent.enable();
-    enablePromise.then(this._registerDebugger.bind(this));
-    this._pauseOnExceptionStateChanged();
-    this._asyncStackTracesStateChanged();
-    if (!Common.moduleSetting('breakpointsActive').get())
-      this._breakpointsActiveChanged();
-    if (SDK.DebuggerModel._scheduledPauseOnAsyncCall)
-      this._pauseOnAsyncCall(SDK.DebuggerModel._scheduledPauseOnAsyncCall);
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerWasEnabled, this);
-    return enablePromise;
-  }
-
-  /**
-   * @param {string|null} debuggerId
-   */
-  _registerDebugger(debuggerId) {
-    if (!debuggerId)
-      return;
-    SDK.DebuggerModel._debuggerIdToModel.set(debuggerId, this);
-    this._debuggerId = debuggerId;
-  }
-
-  /**
-   * @param {string} debuggerId
-   * @return {?SDK.DebuggerModel}
-   */
-  static modelForDebuggerId(debuggerId) {
-    return SDK.DebuggerModel._debuggerIdToModel.get(debuggerId) || null;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _disableDebugger() {
-    if (!this._debuggerEnabled)
-      return Promise.resolve();
-    this._debuggerEnabled = false;
-
-    const disablePromise = this._agent.disable();
-    this._isPausing = false;
-    this._asyncStackTracesStateChanged();
-    this.globalObjectCleared();
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerWasDisabled);
-    SDK.DebuggerModel._debuggerIdToModel.delete(this._debuggerId);
-    return disablePromise;
-  }
-
-  /**
-   * @param {boolean} skip
-   */
-  _skipAllPauses(skip) {
-    if (this._skipAllPausesTimeout) {
-      clearTimeout(this._skipAllPausesTimeout);
-      delete this._skipAllPausesTimeout;
-    }
-    this._agent.setSkipAllPauses(skip);
-  }
-
-  /**
-   * @param {number} timeout
-   */
-  skipAllPausesUntilReloadOrTimeout(timeout) {
-    if (this._skipAllPausesTimeout)
-      clearTimeout(this._skipAllPausesTimeout);
-    this._agent.setSkipAllPauses(true);
-    // If reload happens before the timeout, the flag will be already unset and the timeout callback won't change anything.
-    this._skipAllPausesTimeout = setTimeout(this._skipAllPauses.bind(this, false), timeout);
-  }
-
-  _pauseOnExceptionStateChanged() {
-    let state;
-    if (!Common.moduleSetting('pauseOnExceptionEnabled').get())
-      state = SDK.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions;
-    else if (Common.moduleSetting('pauseOnCaughtException').get())
-      state = SDK.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions;
-    else
-      state = SDK.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions;
-
-    this._agent.setPauseOnExceptions(state);
-  }
-
-  _asyncStackTracesStateChanged() {
-    const maxAsyncStackChainDepth = 32;
-    const enabled = !Common.moduleSetting('disableAsyncStackTraces').get() && this._debuggerEnabled;
-    this._agent.setAsyncCallStackDepth(enabled ? maxAsyncStackChainDepth : 0);
-  }
-
-  _breakpointsActiveChanged() {
-    this._agent.setBreakpointsActive(Common.moduleSetting('breakpointsActive').get());
-  }
-
-  stepInto() {
-    this._agent.stepInto();
-  }
-
-  stepOver() {
-    this._agent.stepOver();
-  }
-
-  stepOut() {
-    this._agent.stepOut();
-  }
-
-  scheduleStepIntoAsync() {
-    this._agent.invoke_stepInto({breakOnAsyncCall: true});
-  }
-
-  resume() {
-    this._agent.resume();
-    this._isPausing = false;
-  }
-
-  pause() {
-    this._isPausing = true;
-    this._skipAllPauses(false);
-    this._agent.pause();
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTraceId} parentStackTraceId
-   * @return {!Promise}
-   */
-  _pauseOnAsyncCall(parentStackTraceId) {
-    return this._agent.invoke_pauseOnAsyncCall({parentStackTraceId: parentStackTraceId});
-  }
-
-  /**
-   * @param {string} url
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @param {string=} condition
-   * @return {!Promise<!SDK.DebuggerModel.SetBreakpointResult>}
-   */
-  async setBreakpointByURL(url, lineNumber, columnNumber, condition) {
-    // Convert file url to node-js path.
-    if (this.target().isNodeJS())
-      url = Common.ParsedURL.urlToPlatformPath(url, Host.isWin());
-    // Adjust column if needed.
-    let minColumnNumber = 0;
-    const scripts = this._scriptsBySourceURL.get(url) || [];
-    for (let i = 0, l = scripts.length; i < l; ++i) {
-      const script = scripts[i];
-      if (lineNumber === script.lineOffset)
-        minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, script.columnOffset) : script.columnOffset;
-    }
-    columnNumber = Math.max(columnNumber, minColumnNumber);
-    const response = await this._agent.invoke_setBreakpointByUrl(
-        {lineNumber: lineNumber, url: url, columnNumber: columnNumber, condition: condition});
-    if (response[Protocol.Error])
-      return {locations: [], breakpointId: null};
-    let locations;
-    if (response.locations)
-      locations = response.locations.map(payload => SDK.DebuggerModel.Location.fromPayload(this, payload));
-    return {locations: locations, breakpointId: response.breakpointId};
-  }
-
-  /**
-   * @param {string} scriptId
-   * @param {string} scriptHash
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @param {string=} condition
-   * @return {!Promise<!SDK.DebuggerModel.SetBreakpointResult>}
-   */
-  async setBreakpointInAnonymousScript(scriptId, scriptHash, lineNumber, columnNumber, condition) {
-    const response = await this._agent.invoke_setBreakpointByUrl(
-        {lineNumber: lineNumber, scriptHash: scriptHash, columnNumber: columnNumber, condition: condition});
-    const error = response[Protocol.Error];
-    if (error) {
-      // Old V8 backend doesn't support scriptHash argument.
-      if (error !== 'Either url or urlRegex must be specified.')
-        return {locations: [], breakpointId: null};
-      return this._setBreakpointBySourceId(scriptId, lineNumber, columnNumber, condition);
-    }
-    let locations;
-    if (response.locations)
-      locations = response.locations.map(payload => SDK.DebuggerModel.Location.fromPayload(this, payload));
-    return {locations: locations, breakpointId: response.breakpointId};
-  }
-
-  /**
-   * @param {string} scriptId
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @param {string=} condition
-   * @return {!Promise<!SDK.DebuggerModel.SetBreakpointResult>}
-   */
-  async _setBreakpointBySourceId(scriptId, lineNumber, columnNumber, condition) {
-    // This method is required for backward compatibility with V8 before 6.3.275.
-    const response = await this._agent.invoke_setBreakpoint(
-        {location: {scriptId: scriptId, lineNumber: lineNumber, columnNumber: columnNumber}, condition: condition});
-    if (response[Protocol.Error])
-      return {breakpointId: null, locations: []};
-    let actualLocation = [];
-    if (response.actualLocation)
-      actualLocation = [SDK.DebuggerModel.Location.fromPayload(this, response.actualLocation)];
-    return {locations: actualLocation, breakpointId: response.breakpointId};
-  }
-
-  /**
-   * @param {!Protocol.Debugger.BreakpointId} breakpointId
-   * @return {!Promise}
-   */
-  async removeBreakpoint(breakpointId) {
-    const response = await this._agent.invoke_removeBreakpoint({breakpointId});
-    if (response[Protocol.Error])
-      console.error('Failed to remove breakpoint: ' + response[Protocol.Error]);
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} startLocation
-   * @param {?SDK.DebuggerModel.Location} endLocation
-   * @param {boolean} restrictToFunction
-   * @return {!Promise<!Array<!SDK.DebuggerModel.BreakLocation>>}
-   */
-  async getPossibleBreakpoints(startLocation, endLocation, restrictToFunction) {
-    const response = await this._agent.invoke_getPossibleBreakpoints({
-      start: startLocation.payload(),
-      end: endLocation ? endLocation.payload() : undefined,
-      restrictToFunction: restrictToFunction
-    });
-    if (response[Protocol.Error] || !response.locations)
-      return [];
-    return response.locations.map(location => SDK.DebuggerModel.BreakLocation.fromPayload(this, location));
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTraceId} stackId
-   * @return {!Promise<?Protocol.Runtime.StackTrace>}
-   */
-  async fetchAsyncStackTrace(stackId) {
-    const response = await this._agent.invoke_getStackTrace({stackTraceId: stackId});
-    return response[Protocol.Error] ? null : response.stackTrace;
-  }
-
-  /**
-   * @param {!Protocol.Debugger.BreakpointId} breakpointId
-   * @param {!Protocol.Debugger.Location} location
-   */
-  _breakpointResolved(breakpointId, location) {
-    this._breakpointResolvedEventTarget.dispatchEventToListeners(
-        breakpointId, SDK.DebuggerModel.Location.fromPayload(this, location));
-  }
-
-  globalObjectCleared() {
-    this._setDebuggerPausedDetails(null);
-    this._reset();
-    // TODO(dgozman): move clients to ExecutionContextDestroyed/ScriptCollected events.
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.GlobalObjectCleared, this);
-  }
-
-  _reset() {
-    for (const scriptWithSourceMap of this._sourceMapIdToScript.values())
-      this._sourceMapManager.detachSourceMap(scriptWithSourceMap);
-    this._sourceMapIdToScript.clear();
-
-    this._scripts.clear();
-    this._scriptsBySourceURL.clear();
-    this._stringMap.clear();
-    this._discardableScripts = [];
-  }
-
-  /**
-   * @return {!Array<!SDK.Script>}
-   */
-  scripts() {
-    return Array.from(this._scripts.values());
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @return {?SDK.Script}
-   */
-  scriptForId(scriptId) {
-    return this._scripts.get(scriptId) || null;
-  }
-
-  /**
-   * @return {!Array.<!SDK.Script>}
-   */
-  scriptsForSourceURL(sourceURL) {
-    if (!sourceURL)
-      return [];
-    return this._scriptsBySourceURL.get(sourceURL) || [];
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @return {!Array<!SDK.Script>}
-   */
-  scriptsForExecutionContext(executionContext) {
-    const result = [];
-    for (const script of this._scripts.values()) {
-      if (script.executionContextId === executionContext.id)
-        result.push(script);
-    }
-    return result;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {string} newSource
-   * @param {function(?Protocol.Error, !Protocol.Runtime.ExceptionDetails=)} callback
-   */
-  setScriptSource(scriptId, newSource, callback) {
-    this._scripts.get(scriptId).editSource(
-        newSource, this._didEditScriptSource.bind(this, scriptId, newSource, callback));
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {string} newSource
-   * @param {function(?Protocol.Error, !Protocol.Runtime.ExceptionDetails=)} callback
-   * @param {?Protocol.Error} error
-   * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
-   * @param {!Array.<!Protocol.Debugger.CallFrame>=} callFrames
-   * @param {!Protocol.Runtime.StackTrace=} asyncStackTrace
-   * @param {!Protocol.Runtime.StackTraceId=} asyncStackTraceId
-   * @param {boolean=} needsStepIn
-   */
-  _didEditScriptSource(
-      scriptId, newSource, callback, error, exceptionDetails, callFrames, asyncStackTrace, asyncStackTraceId,
-      needsStepIn) {
-    callback(error, exceptionDetails);
-    if (needsStepIn) {
-      this.stepInto();
-      return;
-    }
-
-    if (!error && callFrames && callFrames.length) {
-      this._pausedScript(
-          callFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData,
-          this._debuggerPausedDetails.breakpointIds, asyncStackTrace, asyncStackTraceId);
-    }
-  }
-
-  /**
-   * @return {?Array.<!SDK.DebuggerModel.CallFrame>}
-   */
-  get callFrames() {
-    return this._debuggerPausedDetails ? this._debuggerPausedDetails.callFrames : null;
-  }
-
-  /**
-   * @return {?SDK.DebuggerPausedDetails}
-   */
-  debuggerPausedDetails() {
-    return this._debuggerPausedDetails;
-  }
-
-  /**
-   * @param {?SDK.DebuggerPausedDetails} debuggerPausedDetails
-   * @return {boolean}
-   */
-  _setDebuggerPausedDetails(debuggerPausedDetails) {
-    this._isPausing = false;
-    this._debuggerPausedDetails = debuggerPausedDetails;
-    if (this._debuggerPausedDetails) {
-      if (Runtime.experiments.isEnabled('emptySourceMapAutoStepping') && this._beforePausedCallback) {
-        if (!this._beforePausedCallback.call(null, this._debuggerPausedDetails))
-          return false;
-      }
-      this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerPaused, this);
-    }
-    if (debuggerPausedDetails)
-      this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
-    else
-      this.setSelectedCallFrame(null);
-    return true;
-  }
-
-  /**
-   * @param {?function(!SDK.DebuggerPausedDetails):boolean} callback
-   */
-  setBeforePausedCallback(callback) {
-    this._beforePausedCallback = callback;
-  }
-
-  /**
-   * @param {!Array.<!Protocol.Debugger.CallFrame>} callFrames
-   * @param {string} reason
-   * @param {!Object|undefined} auxData
-   * @param {!Array.<string>} breakpointIds
-   * @param {!Protocol.Runtime.StackTrace=} asyncStackTrace
-   * @param {!Protocol.Runtime.StackTraceId=} asyncStackTraceId
-   * @param {!Protocol.Runtime.StackTraceId=} asyncCallStackTraceId
-   */
-  async _pausedScript(
-      callFrames, reason, auxData, breakpointIds, asyncStackTrace, asyncStackTraceId, asyncCallStackTraceId) {
-    if (asyncCallStackTraceId) {
-      SDK.DebuggerModel._scheduledPauseOnAsyncCall = asyncCallStackTraceId;
-      const promises = [];
-      for (const model of SDK.DebuggerModel._debuggerIdToModel.values())
-        promises.push(model._pauseOnAsyncCall(asyncCallStackTraceId));
-      await Promise.all(promises);
-      this.resume();
-      return;
-    }
-
-    const pausedDetails = new SDK.DebuggerPausedDetails(
-        this, callFrames, reason, auxData, breakpointIds, asyncStackTrace, asyncStackTraceId);
-
-    if (pausedDetails && this._continueToLocationCallback) {
-      const callback = this._continueToLocationCallback;
-      delete this._continueToLocationCallback;
-      if (callback(pausedDetails))
-        return;
-    }
-
-    if (!this._setDebuggerPausedDetails(pausedDetails))
-      this._agent.stepInto();
-
-    SDK.DebuggerModel._scheduledPauseOnAsyncCall = null;
-  }
-
-  _resumedScript() {
-    this._setDebuggerPausedDetails(null);
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerResumed, this);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {string} sourceURL
-   * @param {number} startLine
-   * @param {number} startColumn
-   * @param {number} endLine
-   * @param {number} endColumn
-   * @param {!Protocol.Runtime.ExecutionContextId} executionContextId
-   * @param {string} hash
-   * @param {*|undefined} executionContextAuxData
-   * @param {boolean} isLiveEdit
-   * @param {string|undefined} sourceMapURL
-   * @param {boolean} hasSourceURLComment
-   * @param {boolean} hasSyntaxError
-   * @param {number} length
-   * @return {!SDK.Script}
-   */
-  _parsedScriptSource(
-      scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
-      executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURLComment, hasSyntaxError, length) {
-    let isContentScript = false;
-    if (executionContextAuxData && ('isDefault' in executionContextAuxData))
-      isContentScript = !executionContextAuxData['isDefault'];
-    // Support file URL for node.js.
-    if (this.target().isNodeJS() && sourceURL && !hasSourceURLComment) {
-      const nodeJSPath = sourceURL;
-      sourceURL = Common.ParsedURL.platformPathToURL(nodeJSPath);
-      sourceURL = this._internString(sourceURL);
-    } else {
-      sourceURL = this._internString(sourceURL);
-    }
-    const script = new SDK.Script(
-        this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId,
-        this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURLComment, length);
-    this._registerScript(script);
-    if (!hasSyntaxError)
-      this.dispatchEventToListeners(SDK.DebuggerModel.Events.ParsedScriptSource, script);
-    else
-      this.dispatchEventToListeners(SDK.DebuggerModel.Events.FailedToParseScriptSource, script);
-
-    const sourceMapId =
-        SDK.DebuggerModel._sourceMapId(script.executionContextId, script.sourceURL, script.sourceMapURL);
-    if (sourceMapId && !hasSyntaxError) {
-      // Consecutive script evaluations in the same execution context with the same sourceURL
-      // and sourceMappingURL should result in source map reloading.
-      const previousScript = this._sourceMapIdToScript.get(sourceMapId);
-      if (previousScript)
-        this._sourceMapManager.detachSourceMap(previousScript);
-      this._sourceMapIdToScript.set(sourceMapId, script);
-      this._sourceMapManager.attachSourceMap(script, script.sourceURL, script.sourceMapURL);
-    }
-
-    const isDiscardable = hasSyntaxError && script.isAnonymousScript();
-    if (isDiscardable) {
-      this._discardableScripts.push(script);
-      this._collectDiscardedScripts();
-    }
-    return script;
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {string} newSourceMapURL
-   */
-  setSourceMapURL(script, newSourceMapURL) {
-    let sourceMapId = SDK.DebuggerModel._sourceMapId(script.executionContextId, script.sourceURL, script.sourceMapURL);
-    if (sourceMapId && this._sourceMapIdToScript.get(sourceMapId) === script)
-      this._sourceMapIdToScript.delete(sourceMapId);
-    this._sourceMapManager.detachSourceMap(script);
-
-    script.sourceMapURL = newSourceMapURL;
-    sourceMapId = SDK.DebuggerModel._sourceMapId(script.executionContextId, script.sourceURL, script.sourceMapURL);
-    if (!sourceMapId)
-      return;
-    this._sourceMapIdToScript.set(sourceMapId, script);
-    this._sourceMapManager.attachSourceMap(script, script.sourceURL, script.sourceMapURL);
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   */
-  executionContextDestroyed(executionContext) {
-    const sourceMapIds = Array.from(this._sourceMapIdToScript.keys());
-    for (const sourceMapId of sourceMapIds) {
-      const script = this._sourceMapIdToScript.get(sourceMapId);
-      if (script.executionContextId === executionContext.id) {
-        this._sourceMapIdToScript.delete(sourceMapId);
-        this._sourceMapManager.detachSourceMap(script);
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  _registerScript(script) {
-    this._scripts.set(script.scriptId, script);
-    if (script.isAnonymousScript())
-      return;
-
-    let scripts = this._scriptsBySourceURL.get(script.sourceURL);
-    if (!scripts) {
-      scripts = [];
-      this._scriptsBySourceURL.set(script.sourceURL, scripts);
-    }
-    scripts.push(script);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   */
-  _unregisterScript(script) {
-    console.assert(script.isAnonymousScript());
-    this._scripts.delete(script.scriptId);
-  }
-
-  _collectDiscardedScripts() {
-    if (this._discardableScripts.length < 1000)
-      return;
-    const scriptsToDiscard = this._discardableScripts.splice(0, 100);
-    for (const script of scriptsToDiscard) {
-      this._unregisterScript(script);
-      this.dispatchEventToListeners(SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, script);
-    }
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  createRawLocation(script, lineNumber, columnNumber) {
-    return new SDK.DebuggerModel.Location(this, script.scriptId, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {string} sourceURL
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  createRawLocationByURL(sourceURL, lineNumber, columnNumber) {
-    let closestScript = null;
-    const scripts = this._scriptsBySourceURL.get(sourceURL) || [];
-    for (let i = 0, l = scripts.length; i < l; ++i) {
-      const script = scripts[i];
-      if (!closestScript)
-        closestScript = script;
-      if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
-        continue;
-      if (script.endLine < lineNumber || (script.endLine === lineNumber && script.endColumn <= columnNumber))
-        continue;
-      closestScript = script;
-      break;
-    }
-    return closestScript ? new SDK.DebuggerModel.Location(this, closestScript.scriptId, lineNumber, columnNumber) :
-                           null;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  createRawLocationByScriptId(scriptId, lineNumber, columnNumber) {
-    const script = this.scriptForId(scriptId);
-    return script ? this.createRawLocation(script, lineNumber, columnNumber) : null;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   * @return {!Array<!SDK.DebuggerModel.Location>}
-   */
-  createRawLocationsByStackTrace(stackTrace) {
-    const frames = [];
-    while (stackTrace) {
-      for (const frame of stackTrace.callFrames)
-        frames.push(frame);
-      stackTrace = stackTrace.parent;
-    }
-
-    const rawLocations = [];
-    for (const frame of frames) {
-      const rawLocation = this.createRawLocationByScriptId(frame.scriptId, frame.lineNumber, frame.columnNumber);
-      if (rawLocation)
-        rawLocations.push(rawLocation);
-    }
-    return rawLocations;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isPaused() {
-    return !!this.debuggerPausedDetails();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isPausing() {
-    return this._isPausing;
-  }
-
-  /**
-   * @param {?SDK.DebuggerModel.CallFrame} callFrame
-   */
-  setSelectedCallFrame(callFrame) {
-    if (this._selectedCallFrame === callFrame)
-      return;
-    this._selectedCallFrame = callFrame;
-    this.dispatchEventToListeners(SDK.DebuggerModel.Events.CallFrameSelected, this);
-  }
-
-  /**
-   * @return {?SDK.DebuggerModel.CallFrame}
-   */
-  selectedCallFrame() {
-    return this._selectedCallFrame;
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel.EvaluationOptions} options
-   * @return {!Promise<!SDK.RuntimeModel.EvaluationResult>}
-   */
-  evaluateOnSelectedCallFrame(options) {
-    return this.selectedCallFrame().evaluate(options);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} remoteObject
-   * @return {!Promise<?SDK.DebuggerModel.FunctionDetails>}
-   */
-  functionDetailsPromise(remoteObject) {
-    return remoteObject.getAllPropertiesPromise(false /* accessorPropertiesOnly */, false /* generatePreview */)
-        .then(buildDetails.bind(this));
-
-    /**
-     * @param {!{properties: ?Array.<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>}} response
-     * @return {?SDK.DebuggerModel.FunctionDetails}
-     * @this {!SDK.DebuggerModel}
-     */
-    function buildDetails(response) {
-      if (!response)
-        return null;
-      let location = null;
-      if (response.internalProperties) {
-        for (const prop of response.internalProperties) {
-          if (prop.name === '[[FunctionLocation]]')
-            location = prop.value;
-        }
-      }
-      let functionName = null;
-      if (response.properties) {
-        for (const prop of response.properties) {
-          if (prop.name === 'name' && prop.value && prop.value.type === 'string')
-            functionName = prop.value;
-          if (prop.name === 'displayName' && prop.value && prop.value.type === 'string') {
-            functionName = prop.value;
-            break;
-          }
-        }
-      }
-      let debuggerLocation = null;
-      if (location) {
-        debuggerLocation = this.createRawLocationByScriptId(
-            location.value.scriptId, location.value.lineNumber, location.value.columnNumber);
-      }
-      return {location: debuggerLocation, functionName: functionName ? functionName.value : ''};
-    }
-  }
-
-  /**
-   * @param {number} scopeNumber
-   * @param {string} variableName
-   * @param {!Protocol.Runtime.CallArgument} newValue
-   * @param {string} callFrameId
-   * @return {!Promise<string|undefined>}
-   */
-  async setVariableValue(scopeNumber, variableName, newValue, callFrameId) {
-    const response = await this._agent.invoke_setVariableValue({scopeNumber, variableName, newValue, callFrameId});
-    const error = response[Protocol.Error];
-    if (error)
-      console.error(error);
-    return error;
-  }
-
-  /**
-   * @param {!Protocol.Debugger.BreakpointId} breakpointId
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  addBreakpointListener(breakpointId, listener, thisObject) {
-    this._breakpointResolvedEventTarget.addEventListener(breakpointId, listener, thisObject);
-  }
-
-  /**
-   * @param {!Protocol.Debugger.BreakpointId} breakpointId
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  removeBreakpointListener(breakpointId, listener, thisObject) {
-    this._breakpointResolvedEventTarget.removeEventListener(breakpointId, listener, thisObject);
-  }
-
-  /**
-   * @param {!Array<string>} patterns
-   * @return {!Promise<boolean>}
-   */
-  async setBlackboxPatterns(patterns) {
-    const response = await this._agent.invoke_setBlackboxPatterns({patterns});
-    const error = response[Protocol.Error];
-    if (error)
-      console.error(error);
-    return !error;
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this._sourceMapManager.dispose();
-    SDK.DebuggerModel._debuggerIdToModel.delete(this._debuggerId);
-    Common.moduleSetting('pauseOnExceptionEnabled').removeChangeListener(this._pauseOnExceptionStateChanged, this);
-    Common.moduleSetting('pauseOnCaughtException').removeChangeListener(this._pauseOnExceptionStateChanged, this);
-    Common.moduleSetting('disableAsyncStackTraces').removeChangeListener(this._asyncStackTracesStateChanged, this);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  async suspendModel() {
-    await this._disableDebugger();
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  async resumeModel() {
-    await this._enableDebugger();
-  }
-
-  /**
-   * @param {string} string
-   * @return {string} string
-   */
-  _internString(string) {
-    if (!this._stringMap.has(string))
-      this._stringMap.set(string, string);
-    return this._stringMap.get(string);
-  }
-};
-
-/** @type {!Map<string, !SDK.DebuggerModel>} */
-SDK.DebuggerModel._debuggerIdToModel = new Map();
-
-/** @type {?Protocol.Runtime.StackTraceId} */
-SDK.DebuggerModel._scheduledPauseOnAsyncCall = null;
-
-SDK.SDKModel.register(SDK.DebuggerModel, SDK.Target.Capability.JS, true);
-
-/** @typedef {{location: ?SDK.DebuggerModel.Location, functionName: string}} */
-SDK.DebuggerModel.FunctionDetails;
-
-/**
- * Keep these in sync with WebCore::V8Debugger
- *
- * @enum {string}
- */
-SDK.DebuggerModel.PauseOnExceptionsState = {
-  DontPauseOnExceptions: 'none',
-  PauseOnAllExceptions: 'all',
-  PauseOnUncaughtExceptions: 'uncaught'
-};
-
-/** @enum {symbol} */
-SDK.DebuggerModel.Events = {
-  DebuggerWasEnabled: Symbol('DebuggerWasEnabled'),
-  DebuggerWasDisabled: Symbol('DebuggerWasDisabled'),
-  DebuggerPaused: Symbol('DebuggerPaused'),
-  DebuggerResumed: Symbol('DebuggerResumed'),
-  ParsedScriptSource: Symbol('ParsedScriptSource'),
-  FailedToParseScriptSource: Symbol('FailedToParseScriptSource'),
-  DiscardedAnonymousScriptSource: Symbol('DiscardedAnonymousScriptSource'),
-  GlobalObjectCleared: Symbol('GlobalObjectCleared'),
-  CallFrameSelected: Symbol('CallFrameSelected'),
-  ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInSelectedCallFrame')
-};
-
-/** @enum {string} */
-SDK.DebuggerModel.BreakReason = {
-  DOM: 'DOM',
-  EventListener: 'EventListener',
-  XHR: 'XHR',
-  Exception: 'exception',
-  PromiseRejection: 'promiseRejection',
-  Assert: 'assert',
-  DebugCommand: 'debugCommand',
-  OOM: 'OOM',
-  Other: 'other'
-};
-
-/** @enum {string} */
-SDK.DebuggerModel.BreakLocationType = {
-  Return: 'return',
-  Call: 'call',
-  DebuggerStatement: 'debuggerStatement'
-};
-
-SDK.DebuggerEventTypes = {
-  JavaScriptPause: 0,
-  JavaScriptBreakpoint: 1,
-  NativeBreakpoint: 2
-};
-
-SDK.DebuggerModel.ContinueToLocationTargetCallFrames = {
-  Any: 'any',
-  Current: 'current'
-};
-
-/** @typedef {{
- *    breakpointId: ?Protocol.Debugger.BreakpointId,
- *    locations: !Array<!SDK.DebuggerModel.Location>
- *  }}
- */
-SDK.DebuggerModel.SetBreakpointResult;
-
-/**
- * @implements {Protocol.DebuggerDispatcher}
- * @unrestricted
- */
-SDK.DebuggerDispatcher = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  constructor(debuggerModel) {
-    this._debuggerModel = debuggerModel;
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!Protocol.Debugger.CallFrame>} callFrames
-   * @param {string} reason
-   * @param {!Object=} auxData
-   * @param {!Array.<string>=} breakpointIds
-   * @param {!Protocol.Runtime.StackTrace=} asyncStackTrace
-   * @param {!Protocol.Runtime.StackTraceId=} asyncStackTraceId
-   * @param {!Protocol.Runtime.StackTraceId=} asyncCallStackTraceId
-   */
-  paused(callFrames, reason, auxData, breakpointIds, asyncStackTrace, asyncStackTraceId, asyncCallStackTraceId) {
-    this._debuggerModel._pausedScript(
-        callFrames, reason, auxData, breakpointIds || [], asyncStackTrace, asyncStackTraceId, asyncCallStackTraceId);
-  }
-
-  /**
-   * @override
-   */
-  resumed() {
-    this._debuggerModel._resumedScript();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {string} sourceURL
-   * @param {number} startLine
-   * @param {number} startColumn
-   * @param {number} endLine
-   * @param {number} endColumn
-   * @param {!Protocol.Runtime.ExecutionContextId} executionContextId
-   * @param {string} hash
-   * @param {*=} executionContextAuxData
-   * @param {boolean=} isLiveEdit
-   * @param {string=} sourceMapURL
-   * @param {boolean=} hasSourceURL
-   * @param {boolean=} isModule
-   * @param {number=} length
-   */
-  scriptParsed(
-      scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
-      executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL, isModule, length) {
-    this._debuggerModel._parsedScriptSource(
-        scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
-        executionContextAuxData, !!isLiveEdit, sourceMapURL, !!hasSourceURL, false, length || 0);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {string} sourceURL
-   * @param {number} startLine
-   * @param {number} startColumn
-   * @param {number} endLine
-   * @param {number} endColumn
-   * @param {!Protocol.Runtime.ExecutionContextId} executionContextId
-   * @param {string} hash
-   * @param {*=} executionContextAuxData
-   * @param {string=} sourceMapURL
-   * @param {boolean=} hasSourceURL
-   * @param {boolean=} isModule
-   * @param {number=} length
-   */
-  scriptFailedToParse(
-      scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
-      executionContextAuxData, sourceMapURL, hasSourceURL, isModule, length) {
-    this._debuggerModel._parsedScriptSource(
-        scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
-        executionContextAuxData, false, sourceMapURL, !!hasSourceURL, true, length || 0);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Debugger.BreakpointId} breakpointId
-   * @param {!Protocol.Debugger.Location} location
-   */
-  breakpointResolved(breakpointId, location) {
-    this._debuggerModel._breakpointResolved(breakpointId, location);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DebuggerModel.Location = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {string} scriptId
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   */
-  constructor(debuggerModel, scriptId, lineNumber, columnNumber) {
-    this.debuggerModel = debuggerModel;
-    this.scriptId = scriptId;
-    this.lineNumber = lineNumber;
-    this.columnNumber = columnNumber || 0;
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Protocol.Debugger.Location} payload
-   * @return {!SDK.DebuggerModel.Location}
-   */
-  static fromPayload(debuggerModel, payload) {
-    return new SDK.DebuggerModel.Location(debuggerModel, payload.scriptId, payload.lineNumber, payload.columnNumber);
-  }
-
-  /**
-   * @return {!Protocol.Debugger.Location}
-   */
-  payload() {
-    return {scriptId: this.scriptId, lineNumber: this.lineNumber, columnNumber: this.columnNumber};
-  }
-
-  /**
-   * @return {?SDK.Script}
-   */
-  script() {
-    return this.debuggerModel.scriptForId(this.scriptId);
-  }
-
-  /**
-   * @param {function()=} pausedCallback
-   */
-  continueToLocation(pausedCallback) {
-    if (pausedCallback)
-      this.debuggerModel._continueToLocationCallback = this._paused.bind(this, pausedCallback);
-    this.debuggerModel._agent.continueToLocation(
-        this.payload(), SDK.DebuggerModel.ContinueToLocationTargetCallFrames.Current);
-  }
-
-  /**
-   * @param {function()|undefined} pausedCallback
-   * @param {!SDK.DebuggerPausedDetails} debuggerPausedDetails
-   * @return {boolean}
-   */
-  _paused(pausedCallback, debuggerPausedDetails) {
-    const location = debuggerPausedDetails.callFrames[0].location();
-    if (location.scriptId === this.scriptId && location.lineNumber === this.lineNumber &&
-        location.columnNumber === this.columnNumber) {
-      pausedCallback();
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this.debuggerModel.target().id() + ':' + this.scriptId + ':' + this.lineNumber + ':' + this.columnNumber;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DebuggerModel.BreakLocation = class extends SDK.DebuggerModel.Location {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {string} scriptId
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @param {!Protocol.Debugger.BreakLocationType=} type
-   */
-  constructor(debuggerModel, scriptId, lineNumber, columnNumber, type) {
-    super(debuggerModel, scriptId, lineNumber, columnNumber);
-    if (type)
-      this.type = type;
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Protocol.Debugger.BreakLocation} payload
-   * @return {!SDK.DebuggerModel.BreakLocation}
-   */
-  static fromPayload(debuggerModel, payload) {
-    return new SDK.DebuggerModel.BreakLocation(
-        debuggerModel, payload.scriptId, payload.lineNumber, payload.columnNumber, payload.type);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DebuggerModel.CallFrame = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!SDK.Script} script
-   * @param {!Protocol.Debugger.CallFrame} payload
-   */
-  constructor(debuggerModel, script, payload) {
-    this.debuggerModel = debuggerModel;
-    this._script = script;
-    this._payload = payload;
-    this._location = SDK.DebuggerModel.Location.fromPayload(debuggerModel, payload.location);
-    this._scopeChain = [];
-    this._localScope = null;
-    for (let i = 0; i < payload.scopeChain.length; ++i) {
-      const scope = new SDK.DebuggerModel.Scope(this, i);
-      this._scopeChain.push(scope);
-      if (scope.type() === Protocol.Debugger.ScopeType.Local)
-        this._localScope = scope;
-    }
-    if (payload.functionLocation)
-      this._functionLocation = SDK.DebuggerModel.Location.fromPayload(debuggerModel, payload.functionLocation);
-    this._returnValue =
-        payload.returnValue ? this.debuggerModel._runtimeModel.createRemoteObject(payload.returnValue) : null;
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Array.<!Protocol.Debugger.CallFrame>} callFrames
-   * @return {!Array.<!SDK.DebuggerModel.CallFrame>}
-   */
-  static fromPayloadArray(debuggerModel, callFrames) {
-    const result = [];
-    for (let i = 0; i < callFrames.length; ++i) {
-      const callFrame = callFrames[i];
-      const script = debuggerModel.scriptForId(callFrame.location.scriptId);
-      if (script)
-        result.push(new SDK.DebuggerModel.CallFrame(debuggerModel, script, callFrame));
-    }
-    return result;
-  }
-
-  /**
-   * @return {!SDK.Script}
-   */
-  get script() {
-    return this._script;
-  }
-
-  /**
-   * @return {string}
-   */
-  get id() {
-    return this._payload.callFrameId;
-  }
-
-  /**
-   * @return {!Array.<!SDK.DebuggerModel.Scope>}
-   */
-  scopeChain() {
-    return this._scopeChain;
-  }
-
-  /**
-   * @return {?SDK.DebuggerModel.Scope}
-   */
-  localScope() {
-    return this._localScope;
-  }
-
-  /**
-   * @return {?SDK.RemoteObject}
-   */
-  thisObject() {
-    return this._payload.this ? this.debuggerModel._runtimeModel.createRemoteObject(this._payload.this) : null;
-  }
-
-  /**
-   * @return {?SDK.RemoteObject}
-   */
-  returnValue() {
-    return this._returnValue;
-  }
-
-  /**
-   * @param {string} expression
-   * @return {!Promise<?SDK.RemoteObject>}
-   */
-  async setReturnValue(expression) {
-    if (!this._returnValue)
-      return null;
-
-    const evaluateResponse = await this.debuggerModel._agent.invoke_evaluateOnCallFrame(
-        {callFrameId: this.id, expression: expression, silent: true, objectGroup: 'backtrace'});
-    if (evaluateResponse[Protocol.Error] || evaluateResponse.exceptionDetails)
-      return null;
-    const response = await this.debuggerModel._agent.invoke_setReturnValue({newValue: evaluateResponse.result});
-    if (response[Protocol.Error])
-      return null;
-    this._returnValue = this.debuggerModel._runtimeModel.createRemoteObject(evaluateResponse.result);
-    return this._returnValue;
-  }
-
-  /**
-   * @return {string}
-   */
-  get functionName() {
-    return this._payload.functionName;
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel.Location}
-   */
-  location() {
-    return this._location;
-  }
-
-  /**
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  functionLocation() {
-    return this._functionLocation || null;
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel.EvaluationOptions} options
-   * @return {!Promise<!SDK.RuntimeModel.EvaluationResult>}
-   */
-  async evaluate(options) {
-    const runtimeModel = this.debuggerModel.runtimeModel();
-    if (options.throwOnSideEffect &&
-        (runtimeModel.hasSideEffectSupport() === false ||
-         (runtimeModel.hasSideEffectSupport() === null && !await runtimeModel.checkSideEffectSupport())))
-      return {error: 'Side-effect checks not supported by backend.'};
-
-    const response = await this.debuggerModel._agent.invoke_evaluateOnCallFrame({
-      callFrameId: this.id,
-      expression: options.expression,
-      objectGroup: options.objectGroup,
-      includeCommandLineAPI: options.includeCommandLineAPI,
-      silent: options.silent,
-      returnByValue: options.returnByValue,
-      generatePreview: options.generatePreview,
-      throwOnSideEffect: options.throwOnSideEffect
-    });
-    const error = response[Protocol.Error];
-    if (error) {
-      console.error(error);
-      return {error: error};
-    }
-    return {object: runtimeModel.createRemoteObject(response.result), exceptionDetails: response.exceptionDetails};
-  }
-
-  async restart() {
-    const response = await this.debuggerModel._agent.invoke_restartFrame({callFrameId: this._payload.callFrameId});
-    if (!response[Protocol.Error])
-      this.debuggerModel.stepInto();
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SDK.DebuggerModel.Scope = class {
-  /**
-   * @param {!SDK.DebuggerModel.CallFrame} callFrame
-   * @param {number} ordinal
-   */
-  constructor(callFrame, ordinal) {
-    this._callFrame = callFrame;
-    this._payload = callFrame._payload.scopeChain[ordinal];
-    this._type = this._payload.type;
-    this._name = this._payload.name;
-    this._ordinal = ordinal;
-    this._startLocation = this._payload.startLocation ?
-        SDK.DebuggerModel.Location.fromPayload(callFrame.debuggerModel, this._payload.startLocation) :
-        null;
-    this._endLocation = this._payload.endLocation ?
-        SDK.DebuggerModel.Location.fromPayload(callFrame.debuggerModel, this._payload.endLocation) :
-        null;
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel.CallFrame}
-   */
-  callFrame() {
-    return this._callFrame;
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {string}
-   */
-  typeName() {
-    switch (this._type) {
-      case Protocol.Debugger.ScopeType.Local:
-        return Common.UIString('Local');
-      case Protocol.Debugger.ScopeType.Closure:
-        return Common.UIString('Closure');
-      case Protocol.Debugger.ScopeType.Catch:
-        return Common.UIString('Catch');
-      case Protocol.Debugger.ScopeType.Block:
-        return Common.UIString('Block');
-      case Protocol.Debugger.ScopeType.Script:
-        return Common.UIString('Script');
-      case Protocol.Debugger.ScopeType.With:
-        return Common.UIString('With Block');
-      case Protocol.Debugger.ScopeType.Global:
-        return Common.UIString('Global');
-      case Protocol.Debugger.ScopeType.Module:
-        return Common.UIString('Module');
-    }
-    return '';
-  }
-
-
-  /**
-   * @return {string|undefined}
-   */
-  name() {
-    return this._name;
-  }
-
-  /**
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  startLocation() {
-    return this._startLocation;
-  }
-
-  /**
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  endLocation() {
-    return this._endLocation;
-  }
-
-  /**
-   * @return {!SDK.RemoteObject}
-   */
-  object() {
-    if (this._object)
-      return this._object;
-    const runtimeModel = this._callFrame.debuggerModel._runtimeModel;
-
-    const declarativeScope =
-        this._type !== Protocol.Debugger.ScopeType.With && this._type !== Protocol.Debugger.ScopeType.Global;
-    if (declarativeScope) {
-      this._object = runtimeModel.createScopeRemoteObject(
-          this._payload.object, new SDK.ScopeRef(this._ordinal, this._callFrame.id));
-    } else {
-      this._object = runtimeModel.createRemoteObject(this._payload.object);
-    }
-
-    return this._object;
-  }
-
-  /**
-   * @return {string}
-   */
-  description() {
-    const declarativeScope =
-        this._type !== Protocol.Debugger.ScopeType.With && this._type !== Protocol.Debugger.ScopeType.Global;
-    return declarativeScope ? '' : (this._payload.object.description || '');
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.DebuggerPausedDetails = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Array.<!Protocol.Debugger.CallFrame>} callFrames
-   * @param {string} reason
-   * @param {!Object|undefined} auxData
-   * @param {!Array.<string>} breakpointIds
-   * @param {!Protocol.Runtime.StackTrace=} asyncStackTrace
-   * @param {!Protocol.Runtime.StackTraceId=} asyncStackTraceId
-   */
-  constructor(debuggerModel, callFrames, reason, auxData, breakpointIds, asyncStackTrace, asyncStackTraceId) {
-    this.debuggerModel = debuggerModel;
-    this.callFrames = SDK.DebuggerModel.CallFrame.fromPayloadArray(debuggerModel, callFrames);
-    this.reason = reason;
-    this.auxData = auxData;
-    this.breakpointIds = breakpointIds;
-    if (asyncStackTrace)
-      this.asyncStackTrace = this._cleanRedundantFrames(asyncStackTrace);
-    this.asyncStackTraceId = asyncStackTraceId;
-  }
-
-  /**
-   * @return {?SDK.RemoteObject}
-   */
-  exception() {
-    if (this.reason !== SDK.DebuggerModel.BreakReason.Exception &&
-        this.reason !== SDK.DebuggerModel.BreakReason.PromiseRejection)
-      return null;
-    return this.debuggerModel._runtimeModel.createRemoteObject(
-        /** @type {!Protocol.Runtime.RemoteObject} */ (this.auxData));
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTrace} asyncStackTrace
-   * @return {!Protocol.Runtime.StackTrace}
-   */
-  _cleanRedundantFrames(asyncStackTrace) {
-    let stack = asyncStackTrace;
-    let previous = null;
-    while (stack) {
-      if (stack.description === 'async function' && stack.callFrames.length)
-        stack.callFrames.shift();
-      if (previous && !stack.callFrames.length)
-        previous.parent = stack.parent;
-      else
-        previous = stack;
-      stack = stack.parent;
-    }
-    return asyncStackTrace;
-  }
-};
diff --git a/front_end/sdk/EmulationModel.js b/front_end/sdk/EmulationModel.js
deleted file mode 100644
index 6e6fcc2..0000000
--- a/front_end/sdk/EmulationModel.js
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-SDK.EmulationModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._emulationAgent = target.emulationAgent();
-    this._pageAgent = target.pageAgent();
-    this._deviceOrientationAgent = target.deviceOrientationAgent();
-    this._cssModel = target.model(SDK.CSSModel);
-    this._overlayModel = target.model(SDK.OverlayModel);
-    if (this._overlayModel)
-      this._overlayModel.addEventListener(SDK.OverlayModel.Events.InspectModeWillBeToggled, this._updateTouch, this);
-
-    const disableJavascriptSetting = Common.settings.moduleSetting('javaScriptDisabled');
-    disableJavascriptSetting.addChangeListener(
-        () => this._emulationAgent.setScriptExecutionDisabled(disableJavascriptSetting.get()));
-    if (disableJavascriptSetting.get())
-      this._emulationAgent.setScriptExecutionDisabled(true);
-
-    const mediaSetting = Common.moduleSetting('emulatedCSSMedia');
-    mediaSetting.addChangeListener(() => this._emulateCSSMedia(mediaSetting.get()));
-    if (mediaSetting.get())
-      this._emulateCSSMedia(mediaSetting.get());
-
-    this._touchEnabled = false;
-    this._touchMobile = false;
-    this._customTouchEnabled = false;
-    this._touchConfiguration = {enabled: false, configuration: 'mobile', scriptId: ''};
-  }
-
-  /**
-   * @return {boolean}
-   */
-  supportsDeviceEmulation() {
-    return this.target().hasAllCapabilities(SDK.Target.Capability.DeviceEmulation);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  resetPageScaleFactor() {
-    return this._emulationAgent.resetPageScaleFactor();
-  }
-
-  /**
-   * @param {?Protocol.PageAgent.SetDeviceMetricsOverrideRequest} metrics
-   * @return {!Promise}
-   */
-  emulateDevice(metrics) {
-    if (metrics)
-      return this._emulationAgent.invoke_setDeviceMetricsOverride(metrics);
-    else
-      return this._emulationAgent.clearDeviceMetricsOverride();
-  }
-
-  /**
-   * @return {?SDK.OverlayModel}
-   */
-  overlayModel() {
-    return this._overlayModel;
-  }
-
-  /**
-   * @param {?SDK.EmulationModel.Geolocation} geolocation
-   */
-  emulateGeolocation(geolocation) {
-    if (!geolocation) {
-      this._emulationAgent.clearGeolocationOverride();
-      return;
-    }
-
-    if (geolocation.error) {
-      this._emulationAgent.setGeolocationOverride();
-    } else {
-      this._emulationAgent.setGeolocationOverride(
-          geolocation.latitude, geolocation.longitude, SDK.EmulationModel.Geolocation.DefaultMockAccuracy);
-    }
-  }
-
-  /**
-   * @param {?SDK.EmulationModel.DeviceOrientation} deviceOrientation
-   */
-  emulateDeviceOrientation(deviceOrientation) {
-    if (deviceOrientation) {
-      this._deviceOrientationAgent.setDeviceOrientationOverride(
-          deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
-    } else {
-      this._deviceOrientationAgent.clearDeviceOrientationOverride();
-    }
-  }
-
-  /**
-   * @param {string} media
-   */
-  _emulateCSSMedia(media) {
-    this._emulationAgent.setEmulatedMedia(media);
-    if (this._cssModel)
-      this._cssModel.mediaQueryResultChanged();
-  }
-
-  /**
-   * @param {number} rate
-   */
-  setCPUThrottlingRate(rate) {
-    this._emulationAgent.setCPUThrottlingRate(rate);
-  }
-
-  /**
-   * @param {boolean} enabled
-   * @param {boolean} mobile
-   */
-  emulateTouch(enabled, mobile) {
-    this._touchEnabled = enabled;
-    this._touchMobile = mobile;
-    this._updateTouch();
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  overrideEmulateTouch(enabled) {
-    this._customTouchEnabled = enabled;
-    this._updateTouch();
-  }
-
-  _updateTouch() {
-    let configuration = {
-      enabled: this._touchEnabled,
-      configuration: this._touchMobile ? 'mobile' : 'desktop',
-    };
-    if (this._customTouchEnabled)
-      configuration = {enabled: true, configuration: 'mobile'};
-
-    if (this._overlayModel && this._overlayModel.inspectModeEnabled())
-      configuration = {enabled: false, configuration: 'mobile'};
-
-    if (!this._touchConfiguration.enabled && !configuration.enabled)
-      return;
-    if (this._touchConfiguration.enabled && configuration.enabled &&
-        this._touchConfiguration.configuration === configuration.configuration)
-      return;
-
-    this._touchConfiguration = configuration;
-    this._emulationAgent.setTouchEmulationEnabled(configuration.enabled, 1);
-    this._emulationAgent.setEmitTouchEventsForMouse(configuration.enabled, configuration.configuration);
-  }
-};
-
-SDK.SDKModel.register(SDK.EmulationModel, SDK.Target.Capability.Emulation, true);
-
-SDK.EmulationModel.Geolocation = class {
-  /**
-   * @param {number} latitude
-   * @param {number} longitude
-   * @param {boolean} error
-   */
-  constructor(latitude, longitude, error) {
-    this.latitude = latitude;
-    this.longitude = longitude;
-    this.error = error;
-  }
-
-  /**
-   * @return {!SDK.EmulationModel.Geolocation}
-   */
-  static parseSetting(value) {
-    if (value) {
-      const splitError = value.split(':');
-      if (splitError.length === 2) {
-        const splitPosition = splitError[0].split('@');
-        if (splitPosition.length === 2) {
-          return new SDK.EmulationModel.Geolocation(
-              parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), !!splitError[1]);
-        }
-      }
-    }
-    return new SDK.EmulationModel.Geolocation(0, 0, false);
-  }
-
-  /**
-   * @param {string} latitudeString
-   * @param {string} longitudeString
-   * @param {string} errorStatus
-   * @return {?SDK.EmulationModel.Geolocation}
-   */
-  static parseUserInput(latitudeString, longitudeString, errorStatus) {
-    if (!latitudeString && !longitudeString)
-      return null;
-
-    const isLatitudeValid = SDK.EmulationModel.Geolocation.latitudeValidator(latitudeString);
-    const isLongitudeValid = SDK.EmulationModel.Geolocation.longitudeValidator(longitudeString);
-
-    if (!isLatitudeValid && !isLongitudeValid)
-      return null;
-
-    const latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
-    const longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
-    return new SDK.EmulationModel.Geolocation(latitude, longitude, !!errorStatus);
-  }
-
-  /**
-   * @param {string} value
-   * @return {boolean}
-   */
-  static latitudeValidator(value) {
-    const numValue = parseFloat(value);
-    return /^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value) && numValue >= -90 && numValue <= 90;
-  }
-
-  /**
-   * @param {string} value
-   * @return {boolean}
-   */
-  static longitudeValidator(value) {
-    const numValue = parseFloat(value);
-    return /^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value) && numValue >= -180 && numValue <= 180;
-  }
-
-  /**
-   * @return {string}
-   */
-  toSetting() {
-    return this.latitude + '@' + this.longitude + ':' + (this.error || '');
-  }
-};
-
-SDK.EmulationModel.Geolocation.DefaultMockAccuracy = 150;
-
-SDK.EmulationModel.DeviceOrientation = class {
-  /**
-   * @param {number} alpha
-   * @param {number} beta
-   * @param {number} gamma
-   */
-  constructor(alpha, beta, gamma) {
-    this.alpha = alpha;
-    this.beta = beta;
-    this.gamma = gamma;
-  }
-
-  /**
-   * @return {!SDK.EmulationModel.DeviceOrientation}
-   */
-  static parseSetting(value) {
-    if (value) {
-      const jsonObject = JSON.parse(value);
-      return new SDK.EmulationModel.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
-    }
-    return new SDK.EmulationModel.DeviceOrientation(0, 0, 0);
-  }
-
-  /**
-   * @return {?SDK.EmulationModel.DeviceOrientation}
-   */
-  static parseUserInput(alphaString, betaString, gammaString) {
-    if (!alphaString && !betaString && !gammaString)
-      return null;
-
-    const isAlphaValid = SDK.EmulationModel.DeviceOrientation.validator(alphaString);
-    const isBetaValid = SDK.EmulationModel.DeviceOrientation.validator(betaString);
-    const isGammaValid = SDK.EmulationModel.DeviceOrientation.validator(gammaString);
-
-    if (!isAlphaValid && !isBetaValid && !isGammaValid)
-      return null;
-
-    const alpha = isAlphaValid ? parseFloat(alphaString) : -1;
-    const beta = isBetaValid ? parseFloat(betaString) : -1;
-    const gamma = isGammaValid ? parseFloat(gammaString) : -1;
-
-    return new SDK.EmulationModel.DeviceOrientation(alpha, beta, gamma);
-  }
-
-  /**
-   * @param {string} value
-   * @return {boolean}
-   */
-  static validator(value) {
-    return /^([+-]?[\d]+(\.\d+)?|[+-]?\.\d+)$/.test(value);
-  }
-
-  /**
-   * @return {string}
-   */
-  toSetting() {
-    return JSON.stringify(this);
-  }
-};
diff --git a/front_end/sdk/FilmStripModel.js b/front_end/sdk/FilmStripModel.js
deleted file mode 100644
index 71c7237..0000000
--- a/front_end/sdk/FilmStripModel.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * @unrestricted
- */
-SDK.FilmStripModel = class {
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {number=} zeroTime
-   */
-  constructor(tracingModel, zeroTime) {
-    this.reset(tracingModel, zeroTime);
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {number=} zeroTime
-   */
-  reset(tracingModel, zeroTime) {
-    this._zeroTime = zeroTime || tracingModel.minimumRecordTime();
-    this._spanTime = tracingModel.maximumRecordTime() - this._zeroTime;
-
-    /** @type {!Array<!SDK.FilmStripModel.Frame>} */
-    this._frames = [];
-    const browserMain = SDK.TracingModel.browserMainThread(tracingModel);
-    if (!browserMain)
-      return;
-
-    const events = browserMain.events();
-    for (let i = 0; i < events.length; ++i) {
-      const event = events[i];
-      if (event.startTime < this._zeroTime)
-        continue;
-      if (!event.hasCategory(SDK.FilmStripModel._category))
-        continue;
-      if (event.name === SDK.FilmStripModel.TraceEvents.CaptureFrame) {
-        const data = event.args['data'];
-        if (data)
-          this._frames.push(SDK.FilmStripModel.Frame._fromEvent(this, event, this._frames.length));
-      } else if (event.name === SDK.FilmStripModel.TraceEvents.Screenshot) {
-        this._frames.push(SDK.FilmStripModel.Frame._fromSnapshot(
-            this, /** @type {!SDK.TracingModel.ObjectSnapshot} */ (event), this._frames.length));
-      }
-    }
-  }
-
-  /**
-   * @return {!Array<!SDK.FilmStripModel.Frame>}
-   */
-  frames() {
-    return this._frames;
-  }
-
-  /**
-   * @return {number}
-   */
-  zeroTime() {
-    return this._zeroTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  spanTime() {
-    return this._spanTime;
-  }
-
-  /**
-   * @param {number} timestamp
-   * @return {?SDK.FilmStripModel.Frame}
-   */
-  frameByTimestamp(timestamp) {
-    const index = this._frames.upperBound(timestamp, (timestamp, frame) => timestamp - frame.timestamp) - 1;
-    return index >= 0 ? this._frames[index] : null;
-  }
-};
-
-SDK.FilmStripModel._category = 'disabled-by-default-devtools.screenshot';
-
-SDK.FilmStripModel.TraceEvents = {
-  CaptureFrame: 'CaptureFrame',
-  Screenshot: 'Screenshot'
-};
-
-/**
- * @unrestricted
- */
-SDK.FilmStripModel.Frame = class {
-  /**
-   * @param {!SDK.FilmStripModel} model
-   * @param {number} timestamp
-   * @param {number} index
-   */
-  constructor(model, timestamp, index) {
-    this._model = model;
-    this.timestamp = timestamp;
-    this.index = index;
-    /** @type {?string} */
-    this._imageData = null;
-    /** @type {?SDK.TracingModel.ObjectSnapshot} */
-    this._snapshot = null;
-  }
-
-  /**
-   * @param {!SDK.FilmStripModel} model
-   * @param {!SDK.TracingModel.Event} event
-   * @param {number} index
-   * @return {!SDK.FilmStripModel.Frame}
-   */
-  static _fromEvent(model, event, index) {
-    const frame = new SDK.FilmStripModel.Frame(model, event.startTime, index);
-    frame._imageData = event.args['data'];
-    return frame;
-  }
-
-  /**
-   * @param {!SDK.FilmStripModel} model
-   * @param {!SDK.TracingModel.ObjectSnapshot} snapshot
-   * @param {number} index
-   * @return {!SDK.FilmStripModel.Frame}
-   */
-  static _fromSnapshot(model, snapshot, index) {
-    const frame = new SDK.FilmStripModel.Frame(model, snapshot.startTime, index);
-    frame._snapshot = snapshot;
-    return frame;
-  }
-
-  /**
-   * @return {!SDK.FilmStripModel}
-   */
-  model() {
-    return this._model;
-  }
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  imageDataPromise() {
-    if (this._imageData || !this._snapshot)
-      return Promise.resolve(this._imageData);
-
-    return /** @type {!Promise<?string>} */ (this._snapshot.objectPromise());
-  }
-};
diff --git a/front_end/sdk/HeapProfilerModel.js b/front_end/sdk/HeapProfilerModel.js
deleted file mode 100644
index 6f28d61..0000000
--- a/front_end/sdk/HeapProfilerModel.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- * @unrestricted
- */
-SDK.HeapProfilerModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    target.registerHeapProfilerDispatcher(new SDK.HeapProfilerDispatcher(this));
-    this._enabled = false;
-    this._heapProfilerAgent = target.heapProfilerAgent();
-    this._memoryAgent = target.memoryAgent();
-    this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel));
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel}
-   */
-  debuggerModel() {
-    return this._runtimeModel.debuggerModel();
-  }
-
-  /**
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._runtimeModel;
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-
-    this._enabled = true;
-    this._heapProfilerAgent.enable();
-  }
-
-  startSampling() {
-    const defaultSamplingIntervalInBytes = 16384;
-    this._heapProfilerAgent.startSampling(defaultSamplingIntervalInBytes);
-  }
-
-  /**
-   * @return {!Promise<?Protocol.HeapProfiler.SamplingHeapProfile>}
-   */
-  stopSampling() {
-    this._isRecording = false;
-    return this._heapProfilerAgent.stopSampling();
-  }
-
-  startNativeSampling() {
-    const defaultSamplingIntervalInBytes = 65536;
-    this._memoryAgent.startSampling(defaultSamplingIntervalInBytes);
-  }
-
-  /**
-   * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
-   */
-  async stopNativeSampling() {
-    const rawProfile = await this._memoryAgent.getSamplingProfile();
-    this._memoryAgent.stopSampling();
-    return this._convertNativeProfile(rawProfile);
-  }
-
-  /**
-   * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
-   */
-  async takeNativeSnapshot() {
-    const rawProfile = await this._memoryAgent.getAllTimeSamplingProfile();
-    return this._convertNativeProfile(rawProfile);
-  }
-
-  /**
-   * @param {!Protocol.Memory.SamplingProfile} rawProfile
-   * @return {!Protocol.HeapProfiler.SamplingHeapProfile}
-   */
-  _convertNativeProfile(rawProfile) {
-    const head = {children: new Map(), selfSize: 0, callFrame: {functionName: '(root)', url: ''}};
-    for (const sample of rawProfile.samples) {
-      const node = sample.stack.reverse().reduce((node, name) => {
-        let child = node.children.get(name);
-        if (child)
-          return child;
-        const namespace = /^([^:]*)::/.exec(name);
-        child = {
-          children: new Map(),
-          callFrame: {functionName: name, url: namespace && namespace[1] || ''},
-          selfSize: 0
-        };
-        node.children.set(name, child);
-        return child;
-      }, head);
-      node.selfSize += sample.total;
-    }
-
-    function convertChildren(node) {
-      node.children = Array.from(node.children.values());
-      node.children.forEach(convertChildren);
-    }
-    convertChildren(head);
-
-    return /** @type {!Protocol.HeapProfiler.SamplingHeapProfile} */ ({head});
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  collectGarbage() {
-    return this._heapProfilerAgent.collectGarbage();
-  }
-
-  /**
-   * @param {string} objectId
-   * @return {!Promise<?string>}
-   */
-  snapshotObjectIdForObjectId(objectId) {
-    return this._heapProfilerAgent.getHeapObjectId(objectId);
-  }
-
-  /**
-   * @param {string} snapshotObjectId
-   * @param {string} objectGroupName
-   * @return {!Promise<?SDK.RemoteObject>}
-   */
-  objectForSnapshotObjectId(snapshotObjectId, objectGroupName) {
-    return this._heapProfilerAgent.getObjectByHeapObjectId(snapshotObjectId, objectGroupName)
-        .then(result => result && result.type ? this._runtimeModel.createRemoteObject(result) : null);
-  }
-
-  /**
-   * @param {string} snapshotObjectId
-   * @return {!Promise}
-   */
-  addInspectedHeapObject(snapshotObjectId) {
-    return this._heapProfilerAgent.addInspectedHeapObject(snapshotObjectId);
-  }
-
-  /**
-   * @param {boolean} reportProgress
-   * @return {!Promise}
-   */
-  takeHeapSnapshot(reportProgress) {
-    return this._heapProfilerAgent.takeHeapSnapshot(reportProgress);
-  }
-
-  /**
-   * @param {boolean} recordAllocationStacks
-   * @return {!Promise}
-   */
-  startTrackingHeapObjects(recordAllocationStacks) {
-    return this._heapProfilerAgent.startTrackingHeapObjects(recordAllocationStacks);
-  }
-
-  /**
-   * @param {boolean} reportProgress
-   * @return {!Promise}
-   */
-  stopTrackingHeapObjects(reportProgress) {
-    return this._heapProfilerAgent.stopTrackingHeapObjects(reportProgress);
-  }
-
-  /**
-   * @param {!Array<number>} samples
-   */
-  heapStatsUpdate(samples) {
-    this.dispatchEventToListeners(SDK.HeapProfilerModel.Events.HeapStatsUpdate, samples);
-  }
-
-  /**
-   * @param {number} lastSeenObjectId
-   * @param {number} timestamp
-   */
-  lastSeenObjectId(lastSeenObjectId, timestamp) {
-    this.dispatchEventToListeners(
-        SDK.HeapProfilerModel.Events.LastSeenObjectId, {lastSeenObjectId: lastSeenObjectId, timestamp: timestamp});
-  }
-
-  /**
-   * @param {string} chunk
-   */
-  addHeapSnapshotChunk(chunk) {
-    this.dispatchEventToListeners(SDK.HeapProfilerModel.Events.AddHeapSnapshotChunk, chunk);
-  }
-
-  /**
-   * @param {number} done
-   * @param {number} total
-   * @param {boolean=} finished
-   */
-  reportHeapSnapshotProgress(done, total, finished) {
-    this.dispatchEventToListeners(
-        SDK.HeapProfilerModel.Events.ReportHeapSnapshotProgress, {done: done, total: total, finished: finished});
-  }
-
-  resetProfiles() {
-    this.dispatchEventToListeners(SDK.HeapProfilerModel.Events.ResetProfiles, this);
-  }
-};
-
-SDK.SDKModel.register(SDK.HeapProfilerModel, SDK.Target.Capability.JS, false);
-
-/** @enum {symbol} */
-SDK.HeapProfilerModel.Events = {
-  HeapStatsUpdate: Symbol('HeapStatsUpdate'),
-  LastSeenObjectId: Symbol('LastSeenObjectId'),
-  AddHeapSnapshotChunk: Symbol('AddHeapSnapshotChunk'),
-  ReportHeapSnapshotProgress: Symbol('ReportHeapSnapshotProgress'),
-  ResetProfiles: Symbol('ResetProfiles')
-};
-
-/**
- * @implements {Protocol.HeapProfilerDispatcher}
- * @unrestricted
- */
-SDK.HeapProfilerDispatcher = class {
-  constructor(model) {
-    this._heapProfilerModel = model;
-  }
-
-  /**
-   * @override
-   * @param {!Array.<number>} samples
-   */
-  heapStatsUpdate(samples) {
-    this._heapProfilerModel.heapStatsUpdate(samples);
-  }
-
-  /**
-   * @override
-   * @param {number} lastSeenObjectId
-   * @param {number} timestamp
-   */
-  lastSeenObjectId(lastSeenObjectId, timestamp) {
-    this._heapProfilerModel.lastSeenObjectId(lastSeenObjectId, timestamp);
-  }
-
-  /**
-   * @override
-   * @param {string} chunk
-   */
-  addHeapSnapshotChunk(chunk) {
-    this._heapProfilerModel.addHeapSnapshotChunk(chunk);
-  }
-
-  /**
-   * @override
-   * @param {number} done
-   * @param {number} total
-   * @param {boolean=} finished
-   */
-  reportHeapSnapshotProgress(done, total, finished) {
-    this._heapProfilerModel.reportHeapSnapshotProgress(done, total, finished);
-  }
-
-  /**
-   * @override
-   */
-  resetProfiles() {
-    this._heapProfilerModel.resetProfiles();
-  }
-};
diff --git a/front_end/sdk/LayerTreeBase.js b/front_end/sdk/LayerTreeBase.js
deleted file mode 100644
index d8d45f5..0000000
--- a/front_end/sdk/LayerTreeBase.js
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/** @typedef {!{
-        rect: !Protocol.DOM.Rect,
-        snapshot: !SDK.PaintProfilerSnapshot
-    }}
-*/
-SDK.SnapshotWithRect;
-
-/**
- * @interface
- */
-SDK.Layer = function() {};
-
-SDK.Layer.prototype = {
-  /**
-   * @return {string}
-   */
-  id() {},
-
-  /**
-   * @return {?string}
-   */
-  parentId() {},
-
-  /**
-   * @return {?SDK.Layer}
-   */
-  parent() {},
-
-  /**
-   * @return {boolean}
-   */
-  isRoot() {},
-
-  /**
-   * @return {!Array.<!SDK.Layer>}
-   */
-  children() {},
-
-  /**
-   * @param {!SDK.Layer} child
-   */
-  addChild(child) {},
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  node() {},
-
-  /**
-   * @return {?SDK.DOMNode}
-   */
-  nodeForSelfOrAncestor() {},
-
-  /**
-   * @return {number}
-   */
-  offsetX() {},
-
-  /**
-   * @return {number}
-   */
-  offsetY() {},
-
-  /**
-   * @return {number}
-   */
-  width() {},
-
-  /**
-   * @return {number}
-   */
-  height() {},
-
-  /**
-   * @return {?Array.<number>}
-   */
-  transform() {},
-
-  /**
-   * @return {!Array.<number>}
-   */
-  quad() {},
-
-  /**
-   * @return {!Array.<number>}
-   */
-  anchorPoint() {},
-
-  /**
-   * @return {boolean}
-   */
-  invisible() {},
-
-  /**
-   * @return {number}
-   */
-  paintCount() {},
-
-  /**
-   * @return {?Protocol.DOM.Rect}
-   */
-  lastPaintRect() {},
-
-  /**
-   * @return {!Array.<!Protocol.LayerTree.ScrollRect>}
-   */
-  scrollRects() {},
-
-  /**
-   * @return {?SDK.Layer.StickyPositionConstraint}
-   */
-  stickyPositionConstraint() {},
-
-  /**
-   * @return {number}
-   */
-  gpuMemoryUsage() {},
-
-  /**
-   * @return {!Promise<!Array<string>>}
-   */
-  requestCompositingReasons() {},
-
-  /**
-   * @return {boolean}
-   */
-  drawsContent() {},
-
-  /**
-   * @return {!Array<!Promise<?SDK.SnapshotWithRect>>}
-   */
-  snapshots() {}
-};
-
-SDK.Layer.ScrollRectType = {
-  NonFastScrollable: 'NonFastScrollable',
-  TouchEventHandler: 'TouchEventHandler',
-  WheelEventHandler: 'WheelEventHandler',
-  RepaintsOnScroll: 'RepaintsOnScroll'
-};
-
-SDK.Layer.StickyPositionConstraint = class {
-  /**
-   * @param {?SDK.LayerTreeBase} layerTree
-   * @param {!Protocol.LayerTree.StickyPositionConstraint} constraint
-   * @struct
-   */
-  constructor(layerTree, constraint) {
-    /** @type {!Protocol.DOM.Rect} */
-    this._stickyBoxRect = constraint.stickyBoxRect;
-    /** @type {!Protocol.DOM.Rect} */
-    this._containingBlockRect = constraint.containingBlockRect;
-    /** @type {?SDK.Layer} */
-    this._nearestLayerShiftingStickyBox = null;
-    if (layerTree && constraint.nearestLayerShiftingStickyBox)
-      this._nearestLayerShiftingStickyBox = layerTree.layerById(constraint.nearestLayerShiftingStickyBox);
-
-    /** @type {?SDK.Layer} */
-    this._nearestLayerShiftingContainingBlock = null;
-    if (layerTree && constraint.nearestLayerShiftingContainingBlock)
-      this._nearestLayerShiftingContainingBlock = layerTree.layerById(constraint.nearestLayerShiftingContainingBlock);
-  }
-
-  /**
-   * @return {!Protocol.DOM.Rect}
-   */
-  stickyBoxRect() {
-    return this._stickyBoxRect;
-  }
-
-  /**
-   * @return {!Protocol.DOM.Rect}
-   */
-  containingBlockRect() {
-    return this._containingBlockRect;
-  }
-
-  /**
-   * @return {?SDK.Layer}
-   */
-  nearestLayerShiftingStickyBox() {
-    return this._nearestLayerShiftingStickyBox;
-  }
-
-  /**
-   * @return {?SDK.Layer}
-   */
-  nearestLayerShiftingContainingBlock() {
-    return this._nearestLayerShiftingContainingBlock;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.LayerTreeBase = class {
-  /**
-   * @param {?SDK.Target} target
-   */
-  constructor(target) {
-    this._target = target;
-    this._domModel = target ? target.model(SDK.DOMModel) : null;
-    this._layersById = {};
-    this._root = null;
-    this._contentRoot = null;
-    /** @type {!Map<number, ?SDK.DOMNode>} */
-    this._backendNodeIdToNode = new Map();
-  }
-
-  /**
-   * @return {?SDK.Target}
-   */
-  target() {
-    return this._target;
-  }
-
-  /**
-   * @return {?SDK.Layer}
-   */
-  root() {
-    return this._root;
-  }
-
-  /**
-   * @param {?SDK.Layer} root
-   * @protected
-   */
-  setRoot(root) {
-    this._root = root;
-  }
-
-  /**
-   * @return {?SDK.Layer}
-   */
-  contentRoot() {
-    return this._contentRoot;
-  }
-
-  /**
-   * @param {?SDK.Layer} contentRoot
-   * @protected
-   */
-  setContentRoot(contentRoot) {
-    this._contentRoot = contentRoot;
-  }
-
-  /**
-   * @param {function(!SDK.Layer)} callback
-   * @param {?SDK.Layer=} root
-   * @return {boolean}
-   */
-  forEachLayer(callback, root) {
-    if (!root) {
-      root = this.root();
-      if (!root)
-        return false;
-    }
-    return callback(root) || root.children().some(this.forEachLayer.bind(this, callback));
-  }
-
-  /**
-   * @param {string} id
-   * @return {?SDK.Layer}
-   */
-  layerById(id) {
-    return this._layersById[id] || null;
-  }
-
-  /**
-   * @param {!Set<number>} requestedNodeIds
-   * @return {!Promise}
-   */
-  async resolveBackendNodeIds(requestedNodeIds) {
-    if (!requestedNodeIds.size || !this._domModel)
-      return;
-
-    const nodesMap = await this._domModel.pushNodesByBackendIdsToFrontend(requestedNodeIds);
-
-    if (!nodesMap)
-      return;
-    for (const nodeId of nodesMap.keysArray())
-      this._backendNodeIdToNode.set(nodeId, nodesMap.get(nodeId) || null);
-  }
-
-  /**
-   * @return {!Map<number, ?SDK.DOMNode>}
-   */
-  backendNodeIdToNode() {
-    return this._backendNodeIdToNode;
-  }
-
-  /**
-   * @param {!{width: number, height: number}} viewportSize
-   */
-  setViewportSize(viewportSize) {
-    this._viewportSize = viewportSize;
-  }
-
-  /**
-   * @return {!{width: number, height: number}|undefined}
-   */
-  viewportSize() {
-    return this._viewportSize;
-  }
-
-  /**
-   * @param {number} id
-   * @return {?SDK.DOMNode}
-   */
-  _nodeForId(id) {
-    return this._domModel ? this._domModel.nodeForId(id) : null;
-  }
-};
diff --git a/front_end/sdk/LogModel.js b/front_end/sdk/LogModel.js
deleted file mode 100644
index dd9ec8c..0000000
--- a/front_end/sdk/LogModel.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Protocol.LogDispatcher}
- */
-SDK.LogModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    target.registerLogDispatcher(this);
-    this._logAgent = target.logAgent();
-    this._logAgent.enable();
-    if (!Host.isUnderTest()) {
-      this._logAgent.startViolationsReport([
-        {name: 'longTask', threshold: 200}, {name: 'longLayout', threshold: 30}, {name: 'blockedEvent', threshold: 100},
-        {name: 'blockedParser', threshold: -1}, {name: 'handler', threshold: 150},
-        {name: 'recurringHandler', threshold: 50}, {name: 'discouragedAPIUse', threshold: -1}
-      ]);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Log.LogEntry} payload
-   */
-  entryAdded(payload) {
-    this.dispatchEventToListeners(SDK.LogModel.Events.EntryAdded, {logModel: this, entry: payload});
-  }
-
-  requestClear() {
-    this._logAgent.clear();
-  }
-};
-
-SDK.SDKModel.register(SDK.LogModel, SDK.Target.Capability.Log, true);
-
-/** @enum {symbol} */
-SDK.LogModel.Events = {
-  EntryAdded: Symbol('EntryAdded')
-};
diff --git a/front_end/sdk/NetworkManager.js b/front_end/sdk/NetworkManager.js
deleted file mode 100644
index a47d9db..0000000
--- a/front_end/sdk/NetworkManager.js
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.NetworkManager = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._dispatcher = new SDK.NetworkDispatcher(this);
-    this._networkAgent = target.networkAgent();
-    target.registerNetworkDispatcher(this._dispatcher);
-    if (Common.moduleSetting('cacheDisabled').get())
-      this._networkAgent.setCacheDisabled(true);
-
-    this._networkAgent.enable(undefined, undefined, SDK.NetworkManager.MAX_EAGER_POST_REQUEST_BODY_LENGTH);
-
-    this._bypassServiceWorkerSetting = Common.settings.createSetting('bypassServiceWorker', false);
-    if (this._bypassServiceWorkerSetting.get())
-      this._bypassServiceWorkerChanged();
-    this._bypassServiceWorkerSetting.addChangeListener(this._bypassServiceWorkerChanged, this);
-
-    Common.moduleSetting('cacheDisabled').addChangeListener(this._cacheDisabledSettingChanged, this);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?SDK.NetworkManager}
-   */
-  static forRequest(request) {
-    return request[SDK.NetworkManager._networkManagerForRequestSymbol];
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {boolean}
-   */
-  static canReplayRequest(request) {
-    return !!request[SDK.NetworkManager._networkManagerForRequestSymbol] &&
-        request.resourceType() === Common.resourceTypes.XHR;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  static replayRequest(request) {
-    const manager = request[SDK.NetworkManager._networkManagerForRequestSymbol];
-    if (!manager)
-      return;
-    manager._networkAgent.replayXHR(request.requestId());
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  static async searchInRequest(request, query, caseSensitive, isRegex) {
-    const manager = SDK.NetworkManager.forRequest(request);
-    if (!manager)
-      return [];
-    const response = await manager._networkAgent.invoke_searchInResponseBody(
-        {requestId: request.requestId(), query: query, caseSensitive: caseSensitive, isRegex: isRegex});
-    return response.result || [];
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<!SDK.NetworkRequest.ContentData>}
-   */
-  static async requestContentData(request) {
-    if (request.resourceType() === Common.resourceTypes.WebSocket)
-      return {error: 'Content for WebSockets is currently not supported', content: null, encoded: false};
-    if (!request.finished)
-      await request.once(SDK.NetworkRequest.Events.FinishedLoading);
-    const manager = SDK.NetworkManager.forRequest(request);
-    if (!manager)
-      return {error: 'No network manager for request', content: null, encoded: false};
-    const response = await manager._networkAgent.invoke_getResponseBody({requestId: request.requestId()});
-    const error = response[Protocol.Error] || null;
-    return {error: error, content: error ? null : response.body, encoded: response.base64Encoded};
-  }
-
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {!Promise<?string>}
-   */
-  static requestPostData(request) {
-    const manager = SDK.NetworkManager.forRequest(request);
-    if (manager)
-      return manager._networkAgent.getRequestPostData(request.backendRequestId());
-    console.error('No network manager for request');
-    return /** @type {!Promise<?string>} */ (Promise.resolve(null));
-  }
-
-  /**
-   * @param {!SDK.NetworkManager.Conditions} conditions
-   * @return {!Protocol.Network.ConnectionType}
-   * TODO(allada): this belongs to NetworkConditionsSelector, which should hardcode/guess it.
-   */
-  static _connectionType(conditions) {
-    if (!conditions.download && !conditions.upload)
-      return Protocol.Network.ConnectionType.None;
-    let types = SDK.NetworkManager._connectionTypes;
-    if (!types) {
-      SDK.NetworkManager._connectionTypes = [];
-      types = SDK.NetworkManager._connectionTypes;
-      types.push(['2g', Protocol.Network.ConnectionType.Cellular2g]);
-      types.push(['3g', Protocol.Network.ConnectionType.Cellular3g]);
-      types.push(['4g', Protocol.Network.ConnectionType.Cellular4g]);
-      types.push(['bluetooth', Protocol.Network.ConnectionType.Bluetooth]);
-      types.push(['wifi', Protocol.Network.ConnectionType.Wifi]);
-      types.push(['wimax', Protocol.Network.ConnectionType.Wimax]);
-    }
-    for (const type of types) {
-      if (conditions.title.toLowerCase().indexOf(type[0]) !== -1)
-        return type[1];
-    }
-    return Protocol.Network.ConnectionType.Other;
-  }
-
-  /**
-   * @param {!Object} headers
-   * @return {!Object<string, string>}
-   */
-  static lowercaseHeaders(headers) {
-    const newHeaders = {};
-    for (const headerName in headers)
-      newHeaders[headerName.toLowerCase()] = headers[headerName];
-    return newHeaders;
-  }
-
-  /**
-   * @param {string} url
-   * @return {!SDK.NetworkRequest}
-   */
-  inflightRequestForURL(url) {
-    return this._dispatcher._inflightRequestsByURL[url];
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _cacheDisabledSettingChanged(event) {
-    const enabled = /** @type {boolean} */ (event.data);
-    this._networkAgent.setCacheDisabled(enabled);
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    Common.moduleSetting('cacheDisabled').removeChangeListener(this._cacheDisabledSettingChanged, this);
-  }
-
-  _bypassServiceWorkerChanged() {
-    this._networkAgent.setBypassServiceWorker(this._bypassServiceWorkerSetting.get());
-  }
-};
-
-SDK.SDKModel.register(SDK.NetworkManager, SDK.Target.Capability.Network, true);
-
-/** @enum {symbol} */
-SDK.NetworkManager.Events = {
-  RequestStarted: Symbol('RequestStarted'),
-  RequestUpdated: Symbol('RequestUpdated'),
-  RequestFinished: Symbol('RequestFinished'),
-  RequestUpdateDropped: Symbol('RequestUpdateDropped'),
-  ResponseReceived: Symbol('ResponseReceived'),
-  MessageGenerated: Symbol('MessageGenerated'),
-  RequestRedirected: Symbol('RequestRedirected'),
-};
-
-/** @typedef {{message: string, requestId: string, warning: boolean}} */
-SDK.NetworkManager.Message;
-
-SDK.NetworkManager._MIMETypes = {
-  'text/html': {'document': true},
-  'text/xml': {'document': true},
-  'text/plain': {'document': true},
-  'application/xhtml+xml': {'document': true},
-  'image/svg+xml': {'document': true},
-  'text/css': {'stylesheet': true},
-  'text/xsl': {'stylesheet': true},
-  'text/vtt': {'texttrack': true},
-};
-
-/**
- * @typedef {{
- *   download: number,
- *   upload: number,
- *   latency: number,
- *   title: string,
- * }}
- **/
-SDK.NetworkManager.Conditions;
-
-/** @type {!SDK.NetworkManager.Conditions} */
-SDK.NetworkManager.NoThrottlingConditions = {
-  title: Common.UIString('Online'),
-  download: -1,
-  upload: -1,
-  latency: 0
-};
-
-/** @type {!SDK.NetworkManager.Conditions} */
-SDK.NetworkManager.OfflineConditions = {
-  title: Common.UIString('Offline'),
-  download: 0,
-  upload: 0,
-  latency: 0,
-};
-
-/** @type {!SDK.NetworkManager.Conditions} */
-SDK.NetworkManager.Slow3GConditions = {
-  title: Common.UIString('Slow 3G'),
-  download: 500 * 1024 / 8 * .8,
-  upload: 500 * 1024 / 8 * .8,
-  latency: 400 * 5,
-};
-
-/** @type {!SDK.NetworkManager.Conditions} */
-SDK.NetworkManager.Fast3GConditions = {
-  title: Common.UIString('Fast 3G'),
-  download: 1.6 * 1024 * 1024 / 8 * .9,
-  upload: 750 * 1024 / 8 * .9,
-  latency: 150 * 3.75,
-};
-
-/** @typedef {{url: string, enabled: boolean}} */
-SDK.NetworkManager.BlockedPattern;
-
-SDK.NetworkManager._networkManagerForRequestSymbol = Symbol('NetworkManager');
-
-SDK.NetworkManager.MAX_EAGER_POST_REQUEST_BODY_LENGTH = 64 * 1024;  // bytes
-
-/**
- * @implements {Protocol.NetworkDispatcher}
- * @unrestricted
- */
-SDK.NetworkDispatcher = class {
-  /**
-   * @param {!SDK.NetworkManager} manager
-   */
-  constructor(manager) {
-    this._manager = manager;
-    /** @type {!Object<!Protocol.Network.RequestId, !SDK.NetworkRequest>} */
-    this._inflightRequestsById = {};
-    /** @type {!Object<string, !SDK.NetworkRequest>} */
-    this._inflightRequestsByURL = {};
-  }
-
-  /**
-   * @param {!Protocol.Network.Headers} headersMap
-   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
-   */
-  _headersMapToHeadersArray(headersMap) {
-    const result = [];
-    for (const name in headersMap) {
-      const values = headersMap[name].split('\n');
-      for (let i = 0; i < values.length; ++i)
-        result.push({name: name, value: values[i]});
-    }
-    return result;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} networkRequest
-   * @param {!Protocol.Network.Request} request
-   */
-  _updateNetworkRequestWithRequest(networkRequest, request) {
-    networkRequest.requestMethod = request.method;
-    networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));
-    networkRequest.setRequestFormData(!!request.hasPostData, request.postData || null);
-    networkRequest.setInitialPriority(request.initialPriority);
-    networkRequest.mixedContentType = request.mixedContentType || Protocol.Security.MixedContentType.None;
-    networkRequest.setReferrerPolicy(request.referrerPolicy);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} networkRequest
-   * @param {!Protocol.Network.Response=} response
-   */
-  _updateNetworkRequestWithResponse(networkRequest, response) {
-    if (response.url && networkRequest.url() !== response.url)
-      networkRequest.setUrl(response.url);
-    networkRequest.mimeType = response.mimeType;
-    networkRequest.statusCode = response.status;
-    networkRequest.statusText = response.statusText;
-    networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
-    if (response.encodedDataLength >= 0)
-      networkRequest.setTransferSize(response.encodedDataLength);
-    if (response.headersText)
-      networkRequest.responseHeadersText = response.headersText;
-    if (response.requestHeaders) {
-      networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
-      networkRequest.setRequestHeadersText(response.requestHeadersText || '');
-    }
-
-    networkRequest.connectionReused = response.connectionReused;
-    networkRequest.connectionId = String(response.connectionId);
-    if (response.remoteIPAddress)
-      networkRequest.setRemoteAddress(response.remoteIPAddress, response.remotePort || -1);
-
-    if (response.fromServiceWorker)
-      networkRequest.fetchedViaServiceWorker = true;
-
-    if (response.fromDiskCache)
-      networkRequest.setFromDiskCache();
-    networkRequest.timing = response.timing;
-
-    networkRequest.protocol = response.protocol;
-
-    networkRequest.setSecurityState(response.securityState);
-
-    if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
-      const message = Common.UIString(
-          'Resource interpreted as %s but transferred with MIME type %s: "%s".', networkRequest.resourceType().title(),
-          networkRequest.mimeType, networkRequest.url());
-      this._manager.dispatchEventToListeners(
-          SDK.NetworkManager.Events.MessageGenerated,
-          {message: message, requestId: networkRequest.requestId(), warning: true});
-    }
-
-    if (response.securityDetails)
-      networkRequest.setSecurityDetails(response.securityDetails);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} networkRequest
-   * @return {boolean}
-   */
-  _mimeTypeIsConsistentWithType(networkRequest) {
-    // If status is an error, content is likely to be of an inconsistent type,
-    // as it's going to be an error message. We do not want to emit a warning
-    // for this, though, as this will already be reported as resource loading failure.
-    // Also, if a URL like http://localhost/wiki/load.php?debug=true&lang=en produces text/css and gets reloaded,
-    // it is 304 Not Modified and its guessed mime-type is text/php, which is wrong.
-    // Don't check for mime-types in 304-resources.
-    if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
-      return true;
-
-    const resourceType = networkRequest.resourceType();
-    if (resourceType !== Common.resourceTypes.Stylesheet && resourceType !== Common.resourceTypes.Document &&
-        resourceType !== Common.resourceTypes.TextTrack)
-      return true;
-
-
-    if (!networkRequest.mimeType)
-      return true;  // Might be not known for cached resources with null responses.
-
-    if (networkRequest.mimeType in SDK.NetworkManager._MIMETypes)
-      return resourceType.name() in SDK.NetworkManager._MIMETypes[networkRequest.mimeType];
-
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.ResourcePriority} newPriority
-   * @param {!Protocol.Network.MonotonicTime} timestamp
-   */
-  resourceChangedPriority(requestId, newPriority, timestamp) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (networkRequest)
-      networkRequest.setPriority(newPriority);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {string} documentURL
-   * @param {!Protocol.Network.Request} request
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Network.TimeSinceEpoch} wallTime
-   * @param {!Protocol.Network.Initiator} initiator
-   * @param {!Protocol.Network.Response=} redirectResponse
-   * @param {!Protocol.Page.ResourceType=} resourceType
-   * @param {!Protocol.Page.FrameId=} frameId
-   */
-  requestWillBeSent(
-      requestId, loaderId, documentURL, request, time, wallTime, initiator, redirectResponse, resourceType, frameId) {
-    let networkRequest = this._inflightRequestsById[requestId];
-    if (networkRequest) {
-      // FIXME: move this check to the backend.
-      if (!redirectResponse)
-        return;
-      this.responseReceived(requestId, loaderId, time, Protocol.Page.ResourceType.Other, redirectResponse, frameId);
-      networkRequest = this._appendRedirect(requestId, time, request.url);
-      this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestRedirected, networkRequest);
-    } else {
-      networkRequest =
-          this._createNetworkRequest(requestId, frameId || '', loaderId, request.url, documentURL, initiator);
-    }
-    networkRequest.hasNetworkData = true;
-    this._updateNetworkRequestWithRequest(networkRequest, request);
-    networkRequest.setIssueTime(time, wallTime);
-    networkRequest.setResourceType(
-        resourceType ? Common.resourceTypes[resourceType] : Protocol.Page.ResourceType.Other);
-
-    this._startNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   */
-  requestServedFromCache(requestId) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.setFromMemoryCache();
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Page.ResourceType} resourceType
-   * @param {!Protocol.Network.Response} response
-   * @param {!Protocol.Page.FrameId=} frameId
-   */
-  responseReceived(requestId, loaderId, time, resourceType, response, frameId) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    const lowercaseHeaders = SDK.NetworkManager.lowercaseHeaders(response.headers);
-    if (!networkRequest) {
-      // We missed the requestWillBeSent.
-      const eventData = {};
-      eventData.url = response.url;
-      eventData.frameId = frameId || '';
-      eventData.loaderId = loaderId;
-      eventData.resourceType = resourceType;
-      eventData.mimeType = response.mimeType;
-      const lastModifiedHeader = lowercaseHeaders['last-modified'];
-      eventData.lastModified = lastModifiedHeader ? new Date(lastModifiedHeader) : null;
-      this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestUpdateDropped, eventData);
-      return;
-    }
-
-    networkRequest.responseReceivedTime = time;
-    networkRequest.setResourceType(Common.resourceTypes[resourceType]);
-
-    // net::ParsedCookie::kMaxCookieSize = 4096 (net/cookies/parsed_cookie.h)
-    if ('set-cookie' in lowercaseHeaders && lowercaseHeaders['set-cookie'].length > 4096) {
-      const message = Common.UIString(
-          'Set-Cookie header is ignored in response from url: %s. Cookie length should be less than or equal to 4096 characters.',
-          response.url);
-      this._manager.dispatchEventToListeners(
-          SDK.NetworkManager.Events.MessageGenerated, {message: message, requestId: requestId, warning: true});
-    }
-
-    this._updateNetworkRequestWithResponse(networkRequest, response);
-
-    this._updateNetworkRequest(networkRequest);
-    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.ResponseReceived, networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {number} dataLength
-   * @param {number} encodedDataLength
-   */
-  dataReceived(requestId, time, dataLength, encodedDataLength) {
-    let networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      networkRequest = this._maybeAdoptMainResourceRequest(requestId);
-    if (!networkRequest)
-      return;
-
-    networkRequest.resourceSize += dataLength;
-    if (encodedDataLength !== -1)
-      networkRequest.increaseTransferSize(encodedDataLength);
-    networkRequest.endTime = time;
-
-    this._updateNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} finishTime
-   * @param {number} encodedDataLength
-   * @param {boolean=} blockedCrossSiteDocument
-   */
-  loadingFinished(requestId, finishTime, encodedDataLength, blockedCrossSiteDocument) {
-    let networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      networkRequest = this._maybeAdoptMainResourceRequest(requestId);
-    if (!networkRequest)
-      return;
-    this._finishNetworkRequest(networkRequest, finishTime, encodedDataLength, blockedCrossSiteDocument);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Page.ResourceType} resourceType
-   * @param {string} localizedDescription
-   * @param {boolean=} canceled
-   * @param {!Protocol.Network.BlockedReason=} blockedReason
-   */
-  loadingFailed(requestId, time, resourceType, localizedDescription, canceled, blockedReason) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.failed = true;
-    networkRequest.setResourceType(Common.resourceTypes[resourceType]);
-    networkRequest.canceled = !!canceled;
-    if (blockedReason) {
-      networkRequest.setBlockedReason(blockedReason);
-      if (blockedReason === Protocol.Network.BlockedReason.Inspector) {
-        const message = Common.UIString('Request was blocked by DevTools: "%s".', networkRequest.url());
-        this._manager.dispatchEventToListeners(
-            SDK.NetworkManager.Events.MessageGenerated, {message: message, requestId: requestId, warning: true});
-      }
-    }
-    networkRequest.localizedFailDescription = localizedDescription;
-    this._finishNetworkRequest(networkRequest, time, -1);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {string} requestURL
-   * @param {!Protocol.Network.Initiator=} initiator
-   */
-  webSocketCreated(requestId, requestURL, initiator) {
-    const networkRequest = new SDK.NetworkRequest(requestId, requestURL, '', '', '', initiator || null);
-    networkRequest[SDK.NetworkManager._networkManagerForRequestSymbol] = this._manager;
-    networkRequest.setResourceType(Common.resourceTypes.WebSocket);
-    this._startNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Network.TimeSinceEpoch} wallTime
-   * @param {!Protocol.Network.WebSocketRequest} request
-   */
-  webSocketWillSendHandshakeRequest(requestId, time, wallTime, request) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.requestMethod = 'GET';
-    networkRequest.setRequestHeaders(this._headersMapToHeadersArray(request.headers));
-    networkRequest.setIssueTime(time, wallTime);
-
-    this._updateNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Network.WebSocketResponse} response
-   */
-  webSocketHandshakeResponseReceived(requestId, time, response) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.statusCode = response.status;
-    networkRequest.statusText = response.statusText;
-    networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
-    networkRequest.responseHeadersText = response.headersText || '';
-    if (response.requestHeaders)
-      networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
-    if (response.requestHeadersText)
-      networkRequest.setRequestHeadersText(response.requestHeadersText);
-    networkRequest.responseReceivedTime = time;
-    networkRequest.protocol = 'websocket';
-
-    this._updateNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Network.WebSocketFrame} response
-   */
-  webSocketFrameReceived(requestId, time, response) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.addFrame(response, time, false);
-    networkRequest.responseReceivedTime = time;
-
-    this._updateNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {!Protocol.Network.WebSocketFrame} response
-   */
-  webSocketFrameSent(requestId, time, response) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.addFrame(response, time, true);
-    networkRequest.responseReceivedTime = time;
-
-    this._updateNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {string} errorMessage
-   */
-  webSocketFrameError(requestId, time, errorMessage) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-
-    networkRequest.addFrameError(errorMessage, time);
-    networkRequest.responseReceivedTime = time;
-
-    this._updateNetworkRequest(networkRequest);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   */
-  webSocketClosed(requestId, time) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-    this._finishNetworkRequest(networkRequest, time, -1);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {string} eventName
-   * @param {string} eventId
-   * @param {string} data
-   */
-  eventSourceMessageReceived(requestId, time, eventName, eventId, data) {
-    const networkRequest = this._inflightRequestsById[requestId];
-    if (!networkRequest)
-      return;
-    networkRequest.addEventSourceMessage(time, eventName, eventId, data);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Network.InterceptionId} interceptionId
-   * @param {!Protocol.Network.Request} request
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Page.ResourceType} resourceType
-   * @param {boolean} isNavigationRequest
-   * @param {string=} redirectUrl
-   * @param {!Protocol.Network.AuthChallenge=} authChallenge
-   * @param {!Protocol.Network.ErrorReason=} responseErrorReason
-   * @param {number=} responseStatusCode
-   * @param {!Protocol.Network.Headers=} responseHeaders
-   */
-  requestIntercepted(
-      interceptionId, request, frameId, resourceType, isNavigationRequest, redirectUrl, authChallenge,
-      responseErrorReason, responseStatusCode, responseHeaders) {
-    SDK.multitargetNetworkManager._requestIntercepted(new SDK.MultitargetNetworkManager.InterceptedRequest(
-        this._manager.target().networkAgent(), interceptionId, request, frameId, resourceType, isNavigationRequest,
-        redirectUrl, authChallenge, responseErrorReason, responseStatusCode, responseHeaders));
-  }
-
-  /**
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {!Protocol.Network.MonotonicTime} time
-   * @param {string} redirectURL
-   * @return {!SDK.NetworkRequest}
-   */
-  _appendRedirect(requestId, time, redirectURL) {
-    const originalNetworkRequest = this._inflightRequestsById[requestId];
-    let redirectCount = 0;
-    for (let redirect = originalNetworkRequest.redirectSource(); redirect; redirect = redirect.redirectSource())
-      redirectCount++;
-
-    originalNetworkRequest.markAsRedirect(redirectCount);
-    this._finishNetworkRequest(originalNetworkRequest, time, -1);
-    const newNetworkRequest = this._createNetworkRequest(
-        requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId, redirectURL,
-        originalNetworkRequest.documentURL, originalNetworkRequest.initiator());
-    newNetworkRequest.setRedirectSource(originalNetworkRequest);
-    return newNetworkRequest;
-  }
-
-  /**
-   * @param {string} requestId
-   * @return {?SDK.NetworkRequest}
-   */
-  _maybeAdoptMainResourceRequest(requestId) {
-    const request = SDK.multitargetNetworkManager._inflightMainResourceRequests.get(requestId);
-    if (!request)
-      return null;
-    const oldDispatcher = SDK.NetworkManager.forRequest(request)._dispatcher;
-    delete oldDispatcher._inflightRequestsById[requestId];
-    delete oldDispatcher._inflightRequestsByURL[request.url()];
-    this._inflightRequestsById[requestId] = request;
-    this._inflightRequestsByURL[request.url()] = request;
-    request[SDK.NetworkManager._networkManagerForRequestSymbol] = this._manager;
-    return request;
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} networkRequest
-   */
-  _startNetworkRequest(networkRequest) {
-    this._inflightRequestsById[networkRequest.requestId()] = networkRequest;
-    this._inflightRequestsByURL[networkRequest.url()] = networkRequest;
-    // The following relies on the fact that loaderIds and requestIds are
-    // globally unique and that the main request has them equal.
-    if (networkRequest.loaderId === networkRequest.requestId())
-      SDK.multitargetNetworkManager._inflightMainResourceRequests.set(networkRequest.requestId(), networkRequest);
-
-    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestStarted, networkRequest);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} networkRequest
-   */
-  _updateNetworkRequest(networkRequest) {
-    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestUpdated, networkRequest);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} networkRequest
-   * @param {!Protocol.Network.MonotonicTime} finishTime
-   * @param {number} encodedDataLength
-   * @param {boolean=} blockedCrossSiteDocument
-   */
-  _finishNetworkRequest(networkRequest, finishTime, encodedDataLength, blockedCrossSiteDocument) {
-    networkRequest.endTime = finishTime;
-    networkRequest.finished = true;
-    if (encodedDataLength >= 0)
-      networkRequest.setTransferSize(encodedDataLength);
-    this._manager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestFinished, networkRequest);
-    delete this._inflightRequestsById[networkRequest.requestId()];
-    delete this._inflightRequestsByURL[networkRequest.url()];
-    SDK.multitargetNetworkManager._inflightMainResourceRequests.delete(networkRequest.requestId());
-
-    if (blockedCrossSiteDocument) {
-      const message = Common.UIString(
-          `Blocked current origin from receiving cross-site document at %s with MIME type %s.`, networkRequest.url(),
-          networkRequest.mimeType);
-      this._manager.dispatchEventToListeners(
-          SDK.NetworkManager.Events.MessageGenerated,
-          {message: message, requestId: networkRequest.requestId(), warning: true});
-    }
-
-    if (Common.moduleSetting('monitoringXHREnabled').get() &&
-        networkRequest.resourceType().category() === Common.resourceCategories.XHR) {
-      const message = Common.UIString(
-          (networkRequest.failed || networkRequest.hasErrorStatusCode()) ? '%s failed loading: %s "%s".' :
-                                                                           '%s finished loading: %s "%s".',
-          networkRequest.resourceType().title(), networkRequest.requestMethod, networkRequest.url());
-      this._manager.dispatchEventToListeners(
-          SDK.NetworkManager.Events.MessageGenerated,
-          {message: message, requestId: networkRequest.requestId(), warning: false});
-    }
-  }
-
-  /**
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {string} frameId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {string} url
-   * @param {string} documentURL
-   * @param {?Protocol.Network.Initiator} initiator
-   */
-  _createNetworkRequest(requestId, frameId, loaderId, url, documentURL, initiator) {
-    const request = new SDK.NetworkRequest(requestId, url, documentURL, frameId, loaderId, initiator);
-    request[SDK.NetworkManager._networkManagerForRequestSymbol] = this._manager;
-    return request;
-  }
-};
-
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-SDK.MultitargetNetworkManager = class extends Common.Object {
-  constructor() {
-    super();
-    this._userAgentOverride = '';
-    /** @type {!Set<!Protocol.NetworkAgent>} */
-    this._agents = new Set();
-    /** @type {!Map<string, !SDK.NetworkRequest>} */
-    this._inflightMainResourceRequests = new Map();
-    /** @type {!SDK.NetworkManager.Conditions} */
-    this._networkConditions = SDK.NetworkManager.NoThrottlingConditions;
-    /** @type {?Promise} */
-    this._updatingInterceptionPatternsPromise = null;
-
-    // TODO(allada) Remove these and merge it with request interception.
-    this._blockingEnabledSetting = Common.moduleSetting('requestBlockingEnabled');
-    this._blockedPatternsSetting = Common.settings.createSetting('networkBlockedPatterns', []);
-    this._effectiveBlockedURLs = [];
-    this._updateBlockedPatterns();
-
-    /** @type {!Multimap<!SDK.MultitargetNetworkManager.RequestInterceptor, !SDK.MultitargetNetworkManager.InterceptionPattern>} */
-    this._urlsForRequestInterceptor = new Multimap();
-
-    SDK.targetManager.observeTargets(this, SDK.Target.Capability.Network);
-  }
-
-  /**
-   * @param {string} uaString
-   * @return {string}
-   */
-  static patchUserAgentWithChromeVersion(uaString) {
-    // Patches Chrome/CriOS version from user agent ("1.2.3.4" when user agent is: "Chrome/1.2.3.4").
-    const chromeRegex = new RegExp('(?:^|\\W)Chrome/(\\S+)');
-    const chromeMatch = navigator.userAgent.match(chromeRegex);
-    if (chromeMatch && chromeMatch.length > 1)
-      return String.sprintf(uaString, chromeMatch[1]);
-    return uaString;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    const networkAgent = target.networkAgent();
-    if (this._extraHeaders)
-      networkAgent.setExtraHTTPHeaders(this._extraHeaders);
-    if (this._currentUserAgent())
-      networkAgent.setUserAgentOverride(this._currentUserAgent());
-    if (this._effectiveBlockedURLs.length)
-      networkAgent.setBlockedURLs(this._effectiveBlockedURLs);
-    if (this.isIntercepting())
-      networkAgent.setRequestInterception(this._urlsForRequestInterceptor.valuesArray());
-    this._agents.add(networkAgent);
-    if (this.isThrottling())
-      this._updateNetworkConditions(networkAgent);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    for (const entry of this._inflightMainResourceRequests) {
-      const manager = SDK.NetworkManager.forRequest(/** @type {!SDK.NetworkRequest} */ (entry[1]));
-      if (manager.target() !== target)
-        continue;
-      this._inflightMainResourceRequests.delete(/** @type {string} */ (entry[0]));
-    }
-    this._agents.delete(target.networkAgent());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isThrottling() {
-    return this._networkConditions.download >= 0 || this._networkConditions.upload >= 0 ||
-        this._networkConditions.latency > 0;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isOffline() {
-    return !this._networkConditions.download && !this._networkConditions.upload;
-  }
-
-  /**
-   * @param {!SDK.NetworkManager.Conditions} conditions
-   */
-  setNetworkConditions(conditions) {
-    this._networkConditions = conditions;
-    for (const agent of this._agents)
-      this._updateNetworkConditions(agent);
-    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.ConditionsChanged);
-  }
-
-  /**
-   * @return {!SDK.NetworkManager.Conditions}
-   */
-  networkConditions() {
-    return this._networkConditions;
-  }
-
-  /**
-   * @param {!Protocol.NetworkAgent} networkAgent
-   */
-  _updateNetworkConditions(networkAgent) {
-    const conditions = this._networkConditions;
-    if (!this.isThrottling()) {
-      networkAgent.emulateNetworkConditions(false, 0, 0, 0);
-    } else {
-      networkAgent.emulateNetworkConditions(
-          this.isOffline(), conditions.latency, conditions.download < 0 ? 0 : conditions.download,
-          conditions.upload < 0 ? 0 : conditions.upload, SDK.NetworkManager._connectionType(conditions));
-    }
-  }
-
-  /**
-   * @param {!Protocol.Network.Headers} headers
-   */
-  setExtraHTTPHeaders(headers) {
-    this._extraHeaders = headers;
-    for (const agent of this._agents)
-      agent.setExtraHTTPHeaders(this._extraHeaders);
-  }
-
-  /**
-   * @return {string}
-   */
-  _currentUserAgent() {
-    return this._customUserAgent ? this._customUserAgent : this._userAgentOverride;
-  }
-
-  _updateUserAgentOverride() {
-    const userAgent = this._currentUserAgent();
-    for (const agent of this._agents)
-      agent.setUserAgentOverride(userAgent);
-  }
-
-  /**
-   * @param {string} userAgent
-   */
-  setUserAgentOverride(userAgent) {
-    if (this._userAgentOverride === userAgent)
-      return;
-    this._userAgentOverride = userAgent;
-    if (!this._customUserAgent)
-      this._updateUserAgentOverride();
-    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.UserAgentChanged);
-  }
-
-  /**
-   * @return {string}
-   */
-  userAgentOverride() {
-    return this._userAgentOverride;
-  }
-
-  /**
-   * @param {string} userAgent
-   */
-  setCustomUserAgentOverride(userAgent) {
-    this._customUserAgent = userAgent;
-    this._updateUserAgentOverride();
-  }
-
-  // TODO(allada) Move all request blocking into interception and let view manage blocking.
-  /**
-   * @return {!Array<!SDK.NetworkManager.BlockedPattern>}
-   */
-  blockedPatterns() {
-    return this._blockedPatternsSetting.get().slice();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  blockingEnabled() {
-    return this._blockingEnabledSetting.get();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isBlocking() {
-    return !!this._effectiveBlockedURLs.length;
-  }
-
-  /**
-   * @param {!Array<!SDK.NetworkManager.BlockedPattern>} patterns
-   */
-  setBlockedPatterns(patterns) {
-    this._blockedPatternsSetting.set(patterns);
-    this._updateBlockedPatterns();
-    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.BlockedPatternsChanged);
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setBlockingEnabled(enabled) {
-    if (this._blockingEnabledSetting.get() === enabled)
-      return;
-    this._blockingEnabledSetting.set(enabled);
-    this._updateBlockedPatterns();
-    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.BlockedPatternsChanged);
-  }
-
-  _updateBlockedPatterns() {
-    const urls = [];
-    if (this._blockingEnabledSetting.get()) {
-      for (const pattern of this._blockedPatternsSetting.get()) {
-        if (pattern.enabled)
-          urls.push(pattern.url);
-      }
-    }
-
-    if (!urls.length && !this._effectiveBlockedURLs.length)
-      return;
-    this._effectiveBlockedURLs = urls;
-    for (const agent of this._agents)
-      agent.setBlockedURLs(this._effectiveBlockedURLs);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isIntercepting() {
-    return !!this._urlsForRequestInterceptor.size;
-  }
-
-  /**
-   * @param {!Array<!SDK.MultitargetNetworkManager.InterceptionPattern>} patterns
-   * @param {!SDK.MultitargetNetworkManager.RequestInterceptor} requestInterceptor
-   * @return {!Promise}
-   */
-  setInterceptionHandlerForPatterns(patterns, requestInterceptor) {
-    // Note: requestInterceptors may recieve interception requests for patterns they did not subscribe to.
-    this._urlsForRequestInterceptor.deleteAll(requestInterceptor);
-    for (const newPattern of patterns)
-      this._urlsForRequestInterceptor.set(requestInterceptor, newPattern);
-    return this._updateInterceptionPatternsOnNextTick();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _updateInterceptionPatternsOnNextTick() {
-    // This is used so we can register and unregister patterns in loops without sending lots of protocol messages.
-    if (!this._updatingInterceptionPatternsPromise)
-      this._updatingInterceptionPatternsPromise = Promise.resolve().then(this._updateInterceptionPatterns.bind(this));
-    return this._updatingInterceptionPatternsPromise;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _updateInterceptionPatterns() {
-    if (!Common.moduleSetting('cacheDisabled').get())
-      Common.moduleSetting('cacheDisabled').set(true);
-    this._updatingInterceptionPatternsPromise = null;
-    const promises = /** @type {!Array<!Promise>} */ ([]);
-    for (const agent of this._agents)
-      promises.push(agent.setRequestInterception(this._urlsForRequestInterceptor.valuesArray()));
-    this.dispatchEventToListeners(SDK.MultitargetNetworkManager.Events.InterceptorsChanged);
-    return Promise.all(promises);
-  }
-
-  /**
-   * @param {!SDK.MultitargetNetworkManager.InterceptedRequest} interceptedRequest
-   */
-  async _requestIntercepted(interceptedRequest) {
-    for (const requestInterceptor of this._urlsForRequestInterceptor.keysArray()) {
-      await requestInterceptor(interceptedRequest);
-      if (interceptedRequest.hasResponded())
-        return;
-    }
-    if (!interceptedRequest.hasResponded())
-      interceptedRequest.continueRequestWithoutChange();
-  }
-
-  clearBrowserCache() {
-    for (const agent of this._agents)
-      agent.clearBrowserCache();
-  }
-
-  clearBrowserCookies() {
-    for (const agent of this._agents)
-      agent.clearBrowserCookies();
-  }
-
-  /**
-   * @param {string} origin
-   * @return {!Promise<!Array<string>>}
-   */
-  getCertificate(origin) {
-    const target = SDK.targetManager.mainTarget();
-    return target.networkAgent().getCertificate(origin).then(certificate => certificate || []);
-  }
-
-  /**
-   * @param {string} url
-   * @param {function(number, !Object.<string, string>, string)} callback
-   */
-  loadResource(url, callback) {
-    const headers = {};
-
-    const currentUserAgent = this._currentUserAgent();
-    if (currentUserAgent)
-      headers['User-Agent'] = currentUserAgent;
-
-    if (Common.moduleSetting('cacheDisabled').get())
-      headers['Cache-Control'] = 'no-cache';
-
-    Host.ResourceLoader.load(url, headers, callback);
-  }
-};
-
-/** @enum {symbol} */
-SDK.MultitargetNetworkManager.Events = {
-  BlockedPatternsChanged: Symbol('BlockedPatternsChanged'),
-  ConditionsChanged: Symbol('ConditionsChanged'),
-  UserAgentChanged: Symbol('UserAgentChanged'),
-  InterceptorsChanged: Symbol('InterceptorsChanged')
-};
-
-SDK.MultitargetNetworkManager.InterceptedRequest = class {
-  /**
-   * @param {!Protocol.NetworkAgent} networkAgent
-   * @param {!Protocol.Network.InterceptionId} interceptionId
-   * @param {!Protocol.Network.Request} request
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Page.ResourceType} resourceType
-   * @param {boolean} isNavigationRequest
-   * @param {string=} redirectUrl
-   * @param {!Protocol.Network.AuthChallenge=} authChallenge
-   * @param {!Protocol.Network.ErrorReason=} responseErrorReason
-   * @param {number=} responseStatusCode
-   * @param {!Protocol.Network.Headers=} responseHeaders
-   */
-  constructor(
-      networkAgent, interceptionId, request, frameId, resourceType, isNavigationRequest, redirectUrl, authChallenge,
-      responseErrorReason, responseStatusCode, responseHeaders) {
-    this._networkAgent = networkAgent;
-    this._interceptionId = interceptionId;
-    this._hasResponded = false;
-    this.request = request;
-    this.frameId = frameId;
-    this.resourceType = resourceType;
-    this.isNavigationRequest = isNavigationRequest;
-    this.redirectUrl = redirectUrl;
-    this.authChallenge = authChallenge;
-    this.responseErrorReason = responseErrorReason;
-    this.responseStatusCode = responseStatusCode;
-    this.responseHeaders = responseHeaders;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasResponded() {
-    return this._hasResponded;
-  }
-
-  /**
-   * @param {!Blob} contentBlob
-   */
-  async continueRequestWithContent(contentBlob) {
-    this._hasResponded = true;
-    const headers = [
-      'HTTP/1.1 200 OK',
-      'Date: ' + (new Date()).toUTCString(),
-      'Server: Chrome Devtools Request Interceptor',
-      'Connection: closed',
-      'Content-Length: ' + contentBlob.size,
-      'Content-Type: ' + contentBlob.type || 'text/x-unknown',
-    ];
-    const encodedResponse = await blobToBase64(new Blob([headers.join('\r\n'), '\r\n\r\n', contentBlob]));
-    this._networkAgent.continueInterceptedRequest(this._interceptionId, undefined, encodedResponse);
-
-    /**
-     * @param {!Blob} blob
-     * @return {!Promise<string>}
-     */
-    async function blobToBase64(blob) {
-      const reader = new FileReader();
-      const fileContentsLoadedPromise = new Promise(resolve => reader.onloadend = resolve);
-      reader.readAsDataURL(blob);
-      await fileContentsLoadedPromise;
-      if (reader.error) {
-        console.error('Could not convert blob to base64.', reader.error);
-        return '';
-      }
-      const result = reader.result;
-      if (result === undefined) {
-        console.error('Could not convert blob to base64.');
-        return '';
-      }
-      return result.substring(result.indexOf(',') + 1);
-    }
-  }
-
-  continueRequestWithoutChange() {
-    console.assert(!this._hasResponded);
-    this._hasResponded = true;
-    this._networkAgent.continueInterceptedRequest(this._interceptionId);
-  }
-
-  /**
-   * @param {!Protocol.Network.ErrorReason} errorReason
-   */
-  continueRequestWithError(errorReason) {
-    console.assert(!this._hasResponded);
-    this._hasResponded = true;
-    this._networkAgent.continueInterceptedRequest(this._interceptionId, errorReason);
-  }
-
-  /**
-   * @return {!Promise<!SDK.NetworkRequest.ContentData>}
-   */
-  async responseBody() {
-    const response =
-        await this._networkAgent.invoke_getResponseBodyForInterception({interceptionId: this._interceptionId});
-    const error = response[Protocol.Error] || null;
-    return {error: error, content: error ? null : response.body, encoded: response.base64Encoded};
-  }
-};
-
-/** @typedef {!{urlPattern: string, interceptionStage: !Protocol.Network.InterceptionStage}} */
-SDK.MultitargetNetworkManager.InterceptionPattern;
-
-/** @typedef {!function(!SDK.MultitargetNetworkManager.InterceptedRequest):!Promise} */
-SDK.MultitargetNetworkManager.RequestInterceptor;
-
-/**
- * @type {!SDK.MultitargetNetworkManager}
- */
-SDK.multitargetNetworkManager;
diff --git a/front_end/sdk/NetworkRequest.js b/front_end/sdk/NetworkRequest.js
deleted file mode 100644
index 0e07b1e..0000000
--- a/front_end/sdk/NetworkRequest.js
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-SDK.NetworkRequest = class extends Common.Object {
-  /**
-   * @param {!Protocol.Network.RequestId} requestId
-   * @param {string} url
-   * @param {string} documentURL
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {?Protocol.Network.Initiator} initiator
-   */
-  constructor(requestId, url, documentURL, frameId, loaderId, initiator) {
-    super();
-
-    this._requestId = requestId;
-    this._backendRequestId = requestId;
-    this.setUrl(url);
-    this._documentURL = documentURL;
-    this._frameId = frameId;
-    this._loaderId = loaderId;
-    /** @type {?Protocol.Network.Initiator} */
-    this._initiator = initiator;
-    /** @type {?SDK.NetworkRequest} */
-    this._redirectSource = null;
-    this._issueTime = -1;
-    this._startTime = -1;
-    this._endTime = -1;
-    /** @type {!Protocol.Network.BlockedReason|undefined} */
-    this._blockedReason = undefined;
-
-    this.statusCode = 0;
-    this.statusText = '';
-    this.requestMethod = '';
-    this.requestTime = 0;
-    this.protocol = '';
-    /** @type {!Protocol.Security.MixedContentType} */
-    this.mixedContentType = Protocol.Security.MixedContentType.None;
-
-    /** @type {?Protocol.Network.ResourcePriority} */
-    this._initialPriority = null;
-    /** @type {?Protocol.Network.ResourcePriority} */
-    this._currentPriority = null;
-
-    /** @type {!Common.ResourceType} */
-    this._resourceType = Common.resourceTypes.Other;
-    /** @type {?Promise<!SDK.NetworkRequest.ContentData>} */
-    this._contentData = null;
-    /** @type {!Array.<!SDK.NetworkRequest.WebSocketFrame>} */
-    this._frames = [];
-    /** @type {!Array.<!SDK.NetworkRequest.EventSourceMessage>} */
-    this._eventSourceMessages = [];
-
-    /** @type {!Object<string, (string|undefined)>} */
-    this._responseHeaderValues = {};
-    this._responseHeadersText = '';
-
-    /** @type {!Array<!SDK.NetworkRequest.NameValue>} */
-    this._requestHeaders = [];
-    /** @type {!Object<string, (string|undefined)>} */
-    this._requestHeaderValues = {};
-
-    this._remoteAddress = '';
-
-    /** @type {?Protocol.Network.RequestReferrerPolicy} */
-    this._referrerPolicy = null;
-
-    /** @type {!Protocol.Security.SecurityState} */
-    this._securityState = Protocol.Security.SecurityState.Unknown;
-    /** @type {?Protocol.Network.SecurityDetails} */
-    this._securityDetails = null;
-
-    /** @type {string} */
-    this.connectionId = '0';
-    /** @type {?Promise<?Array.<!SDK.NetworkRequest.NameValue>>} */
-    this._formParametersPromise = null;
-    // Assume no body initially
-    /** @type {?Promise<?string>} */
-    this._requestFormDataPromise = /** @type {?Promise<?string>} */ (Promise.resolve(null));
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} other
-   * @return {number}
-   */
-  indentityCompare(other) {
-    const thisId = this.requestId();
-    const thatId = other.requestId();
-    if (thisId > thatId)
-      return 1;
-    if (thisId < thatId)
-      return -1;
-    return 0;
-  }
-
-  /**
-   * @return {!Protocol.Network.RequestId}
-   */
-  requestId() {
-    return this._requestId;
-  }
-
-  /**
-   * @return {!Protocol.Network.RequestId}
-   */
-  backendRequestId() {
-    return this._backendRequestId;
-  }
-
-  /**
-   * @return {string}
-   */
-  url() {
-    return this._url;
-  }
-
-  /**
-   * @param {string} x
-   */
-  setUrl(x) {
-    if (this._url === x)
-      return;
-
-    this._url = x;
-    this._parsedURL = new Common.ParsedURL(x);
-    delete this._queryString;
-    delete this._parsedQueryParameters;
-    delete this._name;
-    delete this._path;
-  }
-
-  /**
-   * @return {string}
-   */
-  get documentURL() {
-    return this._documentURL;
-  }
-
-  get parsedURL() {
-    return this._parsedURL;
-  }
-
-  /**
-   * @return {!Protocol.Page.FrameId}
-   */
-  get frameId() {
-    return this._frameId;
-  }
-
-  /**
-   * @return {!Protocol.Network.LoaderId}
-   */
-  get loaderId() {
-    return this._loaderId;
-  }
-
-  /**
-   * @param {string} ip
-   * @param {number} port
-   */
-  setRemoteAddress(ip, port) {
-    this._remoteAddress = ip + ':' + port;
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.RemoteAddressChanged, this);
-  }
-
-  /**
-   * @return {string}
-   */
-  remoteAddress() {
-    return this._remoteAddress;
-  }
-
-  /**
-   * @param {!Protocol.Network.RequestReferrerPolicy} referrerPolicy
-   */
-  setReferrerPolicy(referrerPolicy) {
-    this._referrerPolicy = referrerPolicy;
-  }
-
-  /**
-   * @return {?Protocol.Network.RequestReferrerPolicy}
-   */
-  referrerPolicy() {
-    return this._referrerPolicy;
-  }
-
-  /**
-   * @return {!Protocol.Security.SecurityState}
-   */
-  securityState() {
-    return this._securityState;
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} securityState
-   */
-  setSecurityState(securityState) {
-    this._securityState = securityState;
-  }
-
-  /**
-   * @return {?Protocol.Network.SecurityDetails}
-   */
-  securityDetails() {
-    return this._securityDetails;
-  }
-
-  /**
-   * @param {!Protocol.Network.SecurityDetails} securityDetails
-   */
-  setSecurityDetails(securityDetails) {
-    this._securityDetails = securityDetails;
-  }
-
-  /**
-   * @return {number}
-   */
-  get startTime() {
-    return this._startTime || -1;
-  }
-
-  /**
-   * @param {number} monotonicTime
-   * @param {number} wallTime
-   */
-  setIssueTime(monotonicTime, wallTime) {
-    this._issueTime = monotonicTime;
-    this._wallIssueTime = wallTime;
-    this._startTime = monotonicTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  issueTime() {
-    return this._issueTime;
-  }
-
-  /**
-   * @param {number} monotonicTime
-   * @return {number}
-   */
-  pseudoWallTime(monotonicTime) {
-    return this._wallIssueTime ? this._wallIssueTime - this._issueTime + monotonicTime : monotonicTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  get responseReceivedTime() {
-    return this._responseReceivedTime || -1;
-  }
-
-  /**
-   * @param {number} x
-   */
-  set responseReceivedTime(x) {
-    this._responseReceivedTime = x;
-  }
-
-  /**
-   * @return {number}
-   */
-  get endTime() {
-    return this._endTime || -1;
-  }
-
-  /**
-   * @param {number} x
-   */
-  set endTime(x) {
-    if (this.timing && this.timing.requestTime) {
-      // Check against accurate responseReceivedTime.
-      this._endTime = Math.max(x, this.responseReceivedTime);
-    } else {
-      // Prefer endTime since it might be from the network stack.
-      this._endTime = x;
-      if (this._responseReceivedTime > x)
-        this._responseReceivedTime = x;
-    }
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.TimingChanged, this);
-  }
-
-  /**
-   * @return {number}
-   */
-  get duration() {
-    if (this._endTime === -1 || this._startTime === -1)
-      return -1;
-    return this._endTime - this._startTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  get latency() {
-    if (this._responseReceivedTime === -1 || this._startTime === -1)
-      return -1;
-    return this._responseReceivedTime - this._startTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  get resourceSize() {
-    return this._resourceSize || 0;
-  }
-
-  /**
-   * @param {number} x
-   */
-  set resourceSize(x) {
-    this._resourceSize = x;
-  }
-
-  /**
-   * @return {number}
-   */
-  get transferSize() {
-    return this._transferSize || 0;
-  }
-
-  /**
-   * @param {number} x
-   */
-  increaseTransferSize(x) {
-    this._transferSize = (this._transferSize || 0) + x;
-  }
-
-  /**
-   * @param {number} x
-   */
-  setTransferSize(x) {
-    this._transferSize = x;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get finished() {
-    return this._finished;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set finished(x) {
-    if (this._finished === x)
-      return;
-
-    this._finished = x;
-
-    if (x)
-      this.dispatchEventToListeners(SDK.NetworkRequest.Events.FinishedLoading, this);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get failed() {
-    return this._failed;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set failed(x) {
-    this._failed = x;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get canceled() {
-    return this._canceled;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set canceled(x) {
-    this._canceled = x;
-  }
-
-  /**
-   * @return {!Protocol.Network.BlockedReason|undefined}
-   */
-  blockedReason() {
-    return this._blockedReason;
-  }
-
-  /**
-   * @param {!Protocol.Network.BlockedReason} reason
-   */
-  setBlockedReason(reason) {
-    this._blockedReason = reason;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  wasBlocked() {
-    return !!this._blockedReason;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  cached() {
-    return (!!this._fromMemoryCache || !!this._fromDiskCache) && !this._transferSize;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  cachedInMemory() {
-    return !!this._fromMemoryCache && !this._transferSize;
-  }
-
-  setFromMemoryCache() {
-    this._fromMemoryCache = true;
-    delete this._timing;
-  }
-
-  setFromDiskCache() {
-    this._fromDiskCache = true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get fetchedViaServiceWorker() {
-    return this._fetchedViaServiceWorker;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  set fetchedViaServiceWorker(x) {
-    this._fetchedViaServiceWorker = x;
-  }
-
-  /**
-   * @return {!Protocol.Network.ResourceTiming|undefined}
-   */
-  get timing() {
-    return this._timing;
-  }
-
-  /**
-   * @param {!Protocol.Network.ResourceTiming|undefined} timingInfo
-   */
-  set timing(timingInfo) {
-    if (!timingInfo || this._fromMemoryCache)
-      return;
-    // Take startTime and responseReceivedTime from timing data for better accuracy.
-    // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
-    this._startTime = timingInfo.requestTime;
-    const headersReceivedTime = timingInfo.requestTime + timingInfo.receiveHeadersEnd / 1000.0;
-    if ((this._responseReceivedTime || -1) < 0 || this._responseReceivedTime > headersReceivedTime)
-      this._responseReceivedTime = headersReceivedTime;
-    if (this._startTime > this._responseReceivedTime)
-      this._responseReceivedTime = this._startTime;
-
-    this._timing = timingInfo;
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.TimingChanged, this);
-  }
-
-  /**
-   * @return {string}
-   */
-  get mimeType() {
-    return this._mimeType;
-  }
-
-  /**
-   * @param {string} x
-   */
-  set mimeType(x) {
-    this._mimeType = x;
-  }
-
-  /**
-   * @return {string}
-   */
-  get displayName() {
-    return this._parsedURL.displayName;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    if (this._name)
-      return this._name;
-    this._parseNameAndPathFromURL();
-    return this._name;
-  }
-
-  /**
-   * @return {string}
-   */
-  path() {
-    if (this._path)
-      return this._path;
-    this._parseNameAndPathFromURL();
-    return this._path;
-  }
-
-  _parseNameAndPathFromURL() {
-    if (this._parsedURL.isDataURL()) {
-      this._name = this._parsedURL.dataURLDisplayName();
-      this._path = '';
-    } else if (this._parsedURL.isAboutBlank()) {
-      this._name = this._parsedURL.url;
-      this._path = '';
-    } else {
-      this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;
-
-      const networkManager = SDK.NetworkManager.forRequest(this);
-      const inspectedURL = networkManager ? networkManager.target().inspectedURL().asParsedURL() : null;
-      this._path = this._path.trimURL(inspectedURL ? inspectedURL.host : '');
-      if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams) {
-        this._name =
-            this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? '?' + this._parsedURL.queryParams : '');
-      } else if (this._parsedURL.folderPathComponents) {
-        this._name =
-            this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf('/') + 1) +
-            '/';
-        this._path = this._path.substring(0, this._path.lastIndexOf('/'));
-      } else {
-        this._name = this._parsedURL.host;
-        this._path = '';
-      }
-    }
-  }
-
-  /**
-   * @return {string}
-   */
-  get folder() {
-    let path = this._parsedURL.path;
-    const indexOfQuery = path.indexOf('?');
-    if (indexOfQuery !== -1)
-      path = path.substring(0, indexOfQuery);
-    const lastSlashIndex = path.lastIndexOf('/');
-    return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : '';
-  }
-
-  /**
-   * @return {!Common.ResourceType}
-   */
-  resourceType() {
-    return this._resourceType;
-  }
-
-  /**
-   * @param {!Common.ResourceType} resourceType
-   */
-  setResourceType(resourceType) {
-    this._resourceType = resourceType;
-  }
-
-  /**
-   * @return {string}
-   */
-  get domain() {
-    return this._parsedURL.host;
-  }
-
-  /**
-   * @return {string}
-   */
-  get scheme() {
-    return this._parsedURL.scheme;
-  }
-
-  /**
-   * @return {?SDK.NetworkRequest}
-   */
-  redirectSource() {
-    return this._redirectSource;
-  }
-
-  /**
-   * @param {?SDK.NetworkRequest} originatingRequest
-   */
-  setRedirectSource(originatingRequest) {
-    this._redirectSource = originatingRequest;
-  }
-
-  /**
-   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
-   */
-  requestHeaders() {
-    return this._requestHeaders;
-  }
-
-  /**
-   * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
-   */
-  setRequestHeaders(headers) {
-    this._requestHeaders = headers;
-    delete this._requestCookies;
-
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.RequestHeadersChanged);
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  requestHeadersText() {
-    return this._requestHeadersText;
-  }
-
-  /**
-   * @param {string} text
-   */
-  setRequestHeadersText(text) {
-    this._requestHeadersText = text;
-
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.RequestHeadersChanged);
-  }
-
-  /**
-   * @param {string} headerName
-   * @return {string|undefined}
-   */
-  requestHeaderValue(headerName) {
-    if (headerName in this._requestHeaderValues)
-      return this._requestHeaderValues[headerName];
-    this._requestHeaderValues[headerName] = this._computeHeaderValue(this.requestHeaders(), headerName);
-    return this._requestHeaderValues[headerName];
-  }
-
-  /**
-   * @return {!Array.<!SDK.Cookie>}
-   */
-  get requestCookies() {
-    if (!this._requestCookies)
-      this._requestCookies = SDK.CookieParser.parseCookie(this.requestHeaderValue('Cookie'));
-    return this._requestCookies;
-  }
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  requestFormData() {
-    if (!this._requestFormDataPromise)
-      this._requestFormDataPromise = SDK.NetworkManager.requestPostData(this);
-    return this._requestFormDataPromise;
-  }
-
-  /**
-   * @param {boolean} hasData
-   * @param {?string} data
-   */
-  setRequestFormData(hasData, data) {
-    this._requestFormDataPromise = (hasData && data === null) ? null : Promise.resolve(data);
-    this._formParametersPromise = null;
-  }
-
-  /**
-   * @return {string}
-   */
-  _filteredProtocolName() {
-    const protocol = this.protocol.toLowerCase();
-    if (protocol === 'h2')
-      return 'http/2.0';
-    return protocol.replace(/^http\/2(\.0)?\+/, 'http/2.0+');
-  }
-
-  /**
-   * @return {string}
-   */
-  requestHttpVersion() {
-    const headersText = this.requestHeadersText();
-    if (!headersText) {
-      const version = this.requestHeaderValue('version') || this.requestHeaderValue(':version');
-      if (version)
-        return version;
-      return this._filteredProtocolName();
-    }
-    const firstLine = headersText.split(/\r\n/)[0];
-    const match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
-    return match ? match[1] : 'HTTP/0.9';
-  }
-
-  /**
-   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
-   */
-  get responseHeaders() {
-    return this._responseHeaders || [];
-  }
-
-  /**
-   * @param {!Array.<!SDK.NetworkRequest.NameValue>} x
-   */
-  set responseHeaders(x) {
-    this._responseHeaders = x;
-    delete this._sortedResponseHeaders;
-    delete this._serverTimings;
-    delete this._responseCookies;
-    this._responseHeaderValues = {};
-
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.ResponseHeadersChanged);
-  }
-
-  /**
-   * @return {string}
-   */
-  get responseHeadersText() {
-    return this._responseHeadersText;
-  }
-
-  /**
-   * @param {string} x
-   */
-  set responseHeadersText(x) {
-    this._responseHeadersText = x;
-
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.ResponseHeadersChanged);
-  }
-
-  /**
-   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
-   */
-  get sortedResponseHeaders() {
-    if (this._sortedResponseHeaders !== undefined)
-      return this._sortedResponseHeaders;
-
-    this._sortedResponseHeaders = this.responseHeaders.slice();
-    this._sortedResponseHeaders.sort(function(a, b) {
-      return a.name.toLowerCase().compareTo(b.name.toLowerCase());
-    });
-    return this._sortedResponseHeaders;
-  }
-
-  /**
-   * @param {string} headerName
-   * @return {string|undefined}
-   */
-  responseHeaderValue(headerName) {
-    if (headerName in this._responseHeaderValues)
-      return this._responseHeaderValues[headerName];
-    this._responseHeaderValues[headerName] = this._computeHeaderValue(this.responseHeaders, headerName);
-    return this._responseHeaderValues[headerName];
-  }
-
-  /**
-   * @return {!Array.<!SDK.Cookie>}
-   */
-  get responseCookies() {
-    if (!this._responseCookies)
-      this._responseCookies = SDK.CookieParser.parseSetCookie(this.responseHeaderValue('Set-Cookie'));
-    return this._responseCookies;
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  responseLastModified() {
-    return this.responseHeaderValue('last-modified');
-  }
-
-  /**
-   * @return {?Array.<!SDK.ServerTiming>}
-   */
-  get serverTimings() {
-    if (typeof this._serverTimings === 'undefined')
-      this._serverTimings = SDK.ServerTiming.parseHeaders(this.responseHeaders);
-    return this._serverTimings;
-  }
-
-  /**
-   * @return {?string}
-   */
-  queryString() {
-    if (this._queryString !== undefined)
-      return this._queryString;
-
-    let queryString = null;
-    const url = this.url();
-    const questionMarkPosition = url.indexOf('?');
-    if (questionMarkPosition !== -1) {
-      queryString = url.substring(questionMarkPosition + 1);
-      const hashSignPosition = queryString.indexOf('#');
-      if (hashSignPosition !== -1)
-        queryString = queryString.substring(0, hashSignPosition);
-    }
-    this._queryString = queryString;
-    return this._queryString;
-  }
-
-  /**
-   * @return {?Array.<!SDK.NetworkRequest.NameValue>}
-   */
-  get queryParameters() {
-    if (this._parsedQueryParameters)
-      return this._parsedQueryParameters;
-    const queryString = this.queryString();
-    if (!queryString)
-      return null;
-    this._parsedQueryParameters = this._parseParameters(queryString);
-    return this._parsedQueryParameters;
-  }
-
-  /**
-   * @return {!Promise<?Array<!SDK.NetworkRequest.NameValue>>}
-   */
-  async _parseFormParameters() {
-    const requestContentType = this.requestContentType();
-    if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
-      return null;
-    const formData = await this.requestFormData();
-    if (formData)
-      return this._parseParameters(formData);
-    return null;
-  }
-
-  /**
-   * @return {!Promise<?Array<!SDK.NetworkRequest.NameValue>>}
-   */
-  formParameters() {
-    if (!this._formParametersPromise)
-      this._formParametersPromise = this._parseFormParameters();
-    return this._formParametersPromise;
-  }
-
-  /**
-   * @return {string}
-   */
-  responseHttpVersion() {
-    const headersText = this._responseHeadersText;
-    if (!headersText) {
-      const version = this.responseHeaderValue('version') || this.responseHeaderValue(':version');
-      if (version)
-        return version;
-      return this._filteredProtocolName();
-    }
-    const firstLine = headersText.split(/\r\n/)[0];
-    const match = firstLine.match(/^(HTTP\/\d+\.\d+)/);
-    return match ? match[1] : 'HTTP/0.9';
-  }
-
-  /**
-   * @param {string} queryString
-   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
-   */
-  _parseParameters(queryString) {
-    function parseNameValue(pair) {
-      const position = pair.indexOf('=');
-      if (position === -1)
-        return {name: pair, value: ''};
-      else
-        return {name: pair.substring(0, position), value: pair.substring(position + 1)};
-    }
-    return queryString.split('&').map(parseNameValue);
-  }
-
-  /**
-   * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
-   * @param {string} headerName
-   * @return {string|undefined}
-   */
-  _computeHeaderValue(headers, headerName) {
-    headerName = headerName.toLowerCase();
-
-    const values = [];
-    for (let i = 0; i < headers.length; ++i) {
-      if (headers[i].name.toLowerCase() === headerName)
-        values.push(headers[i].value);
-    }
-    if (!values.length)
-      return undefined;
-    // Set-Cookie values should be separated by '\n', not comma, otherwise cookies could not be parsed.
-    if (headerName === 'set-cookie')
-      return values.join('\n');
-    return values.join(', ');
-  }
-
-  /**
-   * @return {!Promise<!SDK.NetworkRequest.ContentData>}
-   */
-  contentData() {
-    if (this._contentData)
-      return this._contentData;
-    if (this._contentDataProvider)
-      this._contentData = this._contentDataProvider();
-    else
-      this._contentData = SDK.NetworkManager.requestContentData(this);
-    return this._contentData;
-  }
-
-  /**
-   * @param {function():!Promise<!SDK.NetworkRequest.ContentData>} dataProvider
-   */
-  setContentDataProvider(dataProvider) {
-    console.assert(!this._contentData, 'contentData can only be set once.');
-    this._contentDataProvider = dataProvider;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._url;
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._resourceType;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  async contentEncoded() {
-    return (await this.contentData()).encoded;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  async requestContent() {
-    return (await this.contentData()).content;
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInContent(query, caseSensitive, isRegex) {
-    return SDK.NetworkManager.searchInRequest(this, query, caseSensitive, isRegex);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isHttpFamily() {
-    return !!this.url().match(/^https?:/i);
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  requestContentType() {
-    return this.requestHeaderValue('Content-Type');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasErrorStatusCode() {
-    return this.statusCode >= 400;
-  }
-
-  /**
-   * @param {!Protocol.Network.ResourcePriority} priority
-   */
-  setInitialPriority(priority) {
-    this._initialPriority = priority;
-  }
-
-  /**
-   * @return {?Protocol.Network.ResourcePriority}
-   */
-  initialPriority() {
-    return this._initialPriority;
-  }
-
-  /**
-   * @param {!Protocol.Network.ResourcePriority} priority
-   */
-  setPriority(priority) {
-    this._currentPriority = priority;
-  }
-
-  /**
-   * @return {?Protocol.Network.ResourcePriority}
-   */
-  priority() {
-    return this._currentPriority || this._initialPriority || null;
-  }
-
-  /**
-   * @param {!Element} image
-   */
-  populateImageSource(image) {
-    /**
-     * @param {?string} content
-     * @this {SDK.NetworkRequest}
-     */
-    function onResourceContent(content) {
-      let imageSrc = Common.ContentProvider.contentAsDataURL(content, this._mimeType, true);
-      const cacheControl = this.responseHeaderValue('cache-control');
-      if (imageSrc === null && (!cacheControl || !cacheControl.includes('no-cache')))
-        imageSrc = this._url;
-      image.src = imageSrc;
-    }
-    this.requestContent().then(onResourceContent.bind(this));
-  }
-
-  /**
-   * @return {?Protocol.Network.Initiator}
-   */
-  initiator() {
-    return this._initiator;
-  }
-
-  /**
-   * @return {!Array.<!SDK.NetworkRequest.WebSocketFrame>}
-   */
-  frames() {
-    return this._frames;
-  }
-
-  /**
-   * @param {string} errorMessage
-   * @param {number} time
-   */
-  addFrameError(errorMessage, time) {
-    this._addFrame({
-      type: SDK.NetworkRequest.WebSocketFrameType.Error,
-      text: errorMessage,
-      time: this.pseudoWallTime(time),
-      opCode: -1,
-      mask: false
-    });
-  }
-
-  /**
-   * @param {!Protocol.Network.WebSocketFrame} response
-   * @param {number} time
-   * @param {boolean} sent
-   */
-  addFrame(response, time, sent) {
-    const type = sent ? SDK.NetworkRequest.WebSocketFrameType.Send : SDK.NetworkRequest.WebSocketFrameType.Receive;
-    this._addFrame({
-      type: type,
-      text: response.payloadData,
-      time: this.pseudoWallTime(time),
-      opCode: response.opcode,
-      mask: response.mask
-    });
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest.WebSocketFrame} frame
-   */
-  _addFrame(frame) {
-    this._frames.push(frame);
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.WebsocketFrameAdded, frame);
-  }
-
-  /**
-   * @return {!Array.<!SDK.NetworkRequest.EventSourceMessage>}
-   */
-  eventSourceMessages() {
-    return this._eventSourceMessages;
-  }
-
-  /**
-   * @param {number} time
-   * @param {string} eventName
-   * @param {string} eventId
-   * @param {string} data
-   */
-  addEventSourceMessage(time, eventName, eventId, data) {
-    const message = {time: this.pseudoWallTime(time), eventName: eventName, eventId: eventId, data: data};
-    this._eventSourceMessages.push(message);
-    this.dispatchEventToListeners(SDK.NetworkRequest.Events.EventSourceMessageAdded, message);
-  }
-
-  /**
-   * @param {number} redirectCount
-   */
-  markAsRedirect(redirectCount) {
-    this._requestId = `${this._backendRequestId}:redirected.${redirectCount}`;
-  }
-
-  /**
-   * @param {string} requestId
-   */
-  setRequestIdForTest(requestId) {
-    this._backendRequestId = requestId;
-    this._requestId = requestId;
-  }
-};
-
-/** @enum {symbol} */
-SDK.NetworkRequest.Events = {
-  FinishedLoading: Symbol('FinishedLoading'),
-  TimingChanged: Symbol('TimingChanged'),
-  RemoteAddressChanged: Symbol('RemoteAddressChanged'),
-  RequestHeadersChanged: Symbol('RequestHeadersChanged'),
-  ResponseHeadersChanged: Symbol('ResponseHeadersChanged'),
-  WebsocketFrameAdded: Symbol('WebsocketFrameAdded'),
-  EventSourceMessageAdded: Symbol('EventSourceMessageAdded')
-};
-
-/** @enum {string} */
-SDK.NetworkRequest.InitiatorType = {
-  Other: 'other',
-  Parser: 'parser',
-  Redirect: 'redirect',
-  Script: 'script',
-  Preload: 'preload'
-};
-
-/** @typedef {!{name: string, value: string}} */
-SDK.NetworkRequest.NameValue;
-
-/** @enum {string} */
-SDK.NetworkRequest.WebSocketFrameType = {
-  Send: 'send',
-  Receive: 'receive',
-  Error: 'error'
-};
-
-/** @typedef {!{type: SDK.NetworkRequest.WebSocketFrameType, time: number, text: string, opCode: number, mask: boolean}} */
-SDK.NetworkRequest.WebSocketFrame;
-
-/** @typedef {!{time: number, eventName: string, eventId: string, data: string}} */
-SDK.NetworkRequest.EventSourceMessage;
-
-/** @typedef {!{error: ?string, content: ?string, encoded: boolean}} */
-SDK.NetworkRequest.ContentData;
diff --git a/front_end/sdk/OverlayModel.js b/front_end/sdk/OverlayModel.js
deleted file mode 100644
index e2ca71a..0000000
--- a/front_end/sdk/OverlayModel.js
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Protocol.OverlayDispatcher}
- */
-SDK.OverlayModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
-
-    target.registerOverlayDispatcher(this);
-    this._overlayAgent = target.overlayAgent();
-    this._overlayAgent.enable();
-    this._overlayAgent.setShowViewportSizeOnResize(true);
-
-    this._debuggerModel = target.model(SDK.DebuggerModel);
-    if (this._debuggerModel) {
-      Common.moduleSetting('disablePausedStateOverlay').addChangeListener(this._updatePausedInDebuggerMessage, this);
-      this._debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.DebuggerPaused, this._updatePausedInDebuggerMessage, this);
-      this._debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.DebuggerResumed, this._updatePausedInDebuggerMessage, this);
-      // TODO(dgozman): we should get DebuggerResumed on navigations instead of listening to GlobalObjectCleared.
-      this._debuggerModel.addEventListener(
-          SDK.DebuggerModel.Events.GlobalObjectCleared, this._updatePausedInDebuggerMessage, this);
-    }
-
-    this._inspectModeEnabled = false;
-    this._hideHighlightTimeout = null;
-    this._defaultHighlighter = new SDK.OverlayModel.DefaultHighlighter(this);
-    this._highlighter = this._defaultHighlighter;
-
-    this._showPaintRectsSetting = Common.moduleSetting('showPaintRects');
-    this._showPaintRectsSetting.addChangeListener(
-        () => this._overlayAgent.setShowPaintRects(this._showPaintRectsSetting.get()));
-    if (this._showPaintRectsSetting.get())
-      this._overlayAgent.setShowPaintRects(true);
-
-    this._showDebugBordersSetting = Common.moduleSetting('showDebugBorders');
-    this._showDebugBordersSetting.addChangeListener(
-        () => this._overlayAgent.setShowDebugBorders(this._showDebugBordersSetting.get()));
-    if (this._showDebugBordersSetting.get())
-      this._overlayAgent.setShowDebugBorders(true);
-
-    this._showFPSCounterSetting = Common.moduleSetting('showFPSCounter');
-    this._showFPSCounterSetting.addChangeListener(
-        () => this._overlayAgent.setShowFPSCounter(this._showFPSCounterSetting.get()));
-    if (this._showFPSCounterSetting.get())
-      this._overlayAgent.setShowFPSCounter(true);
-
-    this._showScrollBottleneckRectsSetting = Common.moduleSetting('showScrollBottleneckRects');
-    this._showScrollBottleneckRectsSetting.addChangeListener(
-        () => this._overlayAgent.setShowScrollBottleneckRects(this._showScrollBottleneckRectsSetting.get()));
-    if (this._showScrollBottleneckRectsSetting.get())
-      this._overlayAgent.setShowScrollBottleneckRects(true);
-    if (target.suspended())
-      this._overlayAgent.setSuspended(true);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  static highlightObjectAsDOMNode(object) {
-    const domModel = object.runtimeModel().target().model(SDK.DOMModel);
-    if (domModel)
-      domModel.overlayModel().highlightDOMNode(undefined, undefined, undefined, object.objectId);
-  }
-
-  static hideDOMNodeHighlight() {
-    for (const overlayModel of SDK.targetManager.models(SDK.OverlayModel))
-      overlayModel.highlightDOMNode(0);
-  }
-
-  static muteHighlight() {
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    SDK.OverlayModel._highlightDisabled = true;
-  }
-
-  static unmuteHighlight() {
-    SDK.OverlayModel._highlightDisabled = false;
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  suspendModel() {
-    return this._overlayAgent.setSuspended(true);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  resumeModel() {
-    return this._overlayAgent.setSuspended(false);
-  }
-
-  setShowViewportSizeOnResize(show) {
-    this._overlayAgent.setShowViewportSizeOnResize(show);
-  }
-
-  _updatePausedInDebuggerMessage() {
-    const message = this._debuggerModel.isPaused() && !Common.moduleSetting('disablePausedStateOverlay').get() ?
-        Common.UIString('Paused in debugger') :
-        undefined;
-    this._overlayAgent.setPausedInDebuggerMessage(message);
-  }
-
-  /**
-   * @param {?SDK.OverlayModel.Highlighter} highlighter
-   */
-  setHighlighter(highlighter) {
-    this._highlighter = highlighter || this._defaultHighlighter;
-  }
-
-  /**
-   * @param {!Protocol.Overlay.InspectMode} mode
-   * @return {!Promise}
-   */
-  async setInspectMode(mode) {
-    await this._domModel.requestDocument();
-    this._inspectModeEnabled = mode !== Protocol.Overlay.InspectMode.None;
-    this.dispatchEventToListeners(SDK.OverlayModel.Events.InspectModeWillBeToggled, this);
-    this._highlighter.setInspectMode(mode, this._buildHighlightConfig());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  inspectModeEnabled() {
-    return this._inspectModeEnabled;
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId=} nodeId
-   * @param {string=} mode
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(nodeId, mode, backendNodeId, objectId) {
-    this.highlightDOMNodeWithConfig(nodeId, {mode: mode}, backendNodeId, objectId);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId=} nodeId
-   * @param {!{mode: (string|undefined), showInfo: (boolean|undefined), selectors: (string|undefined)}=} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNodeWithConfig(nodeId, config, backendNodeId, objectId) {
-    if (SDK.OverlayModel._highlightDisabled)
-      return;
-    config = config || {mode: 'all', showInfo: undefined, selectors: undefined};
-    if (this._hideHighlightTimeout) {
-      clearTimeout(this._hideHighlightTimeout);
-      this._hideHighlightTimeout = null;
-    }
-    const highlightConfig = this._buildHighlightConfig(config.mode);
-    if (typeof config.showInfo !== 'undefined')
-      highlightConfig.showInfo = config.showInfo;
-    if (typeof config.selectors !== 'undefined')
-      highlightConfig.selectorList = config.selectors;
-    this._highlighter.highlightDOMNode(this._domModel.nodeForId(nodeId || 0), highlightConfig, backendNodeId, objectId);
-  }
-
-  /**
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  highlightDOMNodeForTwoSeconds(nodeId) {
-    this.highlightDOMNode(nodeId);
-    this._hideHighlightTimeout = setTimeout(() => this.highlightDOMNode(0), 2000);
-  }
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {
-    if (SDK.OverlayModel._highlightDisabled)
-      return;
-    this._highlighter.highlightFrame(frameId);
-  }
-
-  /**
-   * @param {string=} mode
-   * @return {!Protocol.Overlay.HighlightConfig}
-   */
-  _buildHighlightConfig(mode) {
-    mode = mode || 'all';
-    const showRulers = Common.moduleSetting('showMetricsRulers').get();
-    const highlightConfig = {showInfo: mode === 'all', showRulers: showRulers, showExtensionLines: showRulers};
-    if (mode === 'all' || mode === 'content')
-      highlightConfig.contentColor = Common.Color.PageHighlight.Content.toProtocolRGBA();
-
-    if (mode === 'all' || mode === 'padding')
-      highlightConfig.paddingColor = Common.Color.PageHighlight.Padding.toProtocolRGBA();
-
-    if (mode === 'all' || mode === 'border')
-      highlightConfig.borderColor = Common.Color.PageHighlight.Border.toProtocolRGBA();
-
-    if (mode === 'all' || mode === 'margin')
-      highlightConfig.marginColor = Common.Color.PageHighlight.Margin.toProtocolRGBA();
-
-    if (mode === 'all') {
-      highlightConfig.eventTargetColor = Common.Color.PageHighlight.EventTarget.toProtocolRGBA();
-      highlightConfig.shapeColor = Common.Color.PageHighlight.Shape.toProtocolRGBA();
-      highlightConfig.shapeMarginColor = Common.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
-      highlightConfig.displayAsMaterial = true;
-    }
-
-    if (mode === 'all')
-      highlightConfig.cssGridColor = Common.Color.PageHighlight.CssGrid.toProtocolRGBA();
-
-    return highlightConfig;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.NodeId} nodeId
-   */
-  nodeHighlightRequested(nodeId) {
-    const node = this._domModel.nodeForId(nodeId);
-    if (node)
-      this.dispatchEventToListeners(SDK.OverlayModel.Events.HighlightNodeRequested, node);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.DOM.BackendNodeId} backendNodeId
-   */
-  inspectNodeRequested(backendNodeId) {
-    const deferredNode = new SDK.DeferredDOMNode(this.target(), backendNodeId);
-    this.dispatchEventToListeners(SDK.OverlayModel.Events.InspectNodeRequested, deferredNode);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.Viewport} viewport
-   */
-  screenshotRequested(viewport) {
-    this.dispatchEventToListeners(SDK.OverlayModel.Events.ScreenshotRequested, viewport);
-  }
-};
-
-SDK.SDKModel.register(SDK.OverlayModel, SDK.Target.Capability.DOM, true);
-
-/** @enum {symbol} */
-SDK.OverlayModel.Events = {
-  InspectModeWillBeToggled: Symbol('InspectModeWillBeToggled'),
-  HighlightNodeRequested: Symbol('HighlightNodeRequested'),
-  InspectNodeRequested: Symbol('InspectNodeRequested'),
-  ScreenshotRequested: Symbol('ScreenshotRequested'),
-};
-
-/**
- * @interface
- */
-SDK.OverlayModel.Highlighter = function() {};
-
-SDK.OverlayModel.Highlighter.prototype = {
-  /**
-   * @param {?SDK.DOMNode} node
-   * @param {!Protocol.Overlay.HighlightConfig} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(node, config, backendNodeId, objectId) {},
-
-  /**
-   * @param {!Protocol.Overlay.InspectMode} mode
-   * @param {!Protocol.Overlay.HighlightConfig} config
-   * @return {!Promise}
-   */
-  setInspectMode(mode, config) {},
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {}
-};
-
-/**
- * @implements {SDK.OverlayModel.Highlighter}
- */
-SDK.OverlayModel.DefaultHighlighter = class {
-  /**
-   * @param {!SDK.OverlayModel} model
-   */
-  constructor(model) {
-    this._model = model;
-  }
-
-  /**
-   * @override
-   * @param {?SDK.DOMNode} node
-   * @param {!Protocol.Overlay.HighlightConfig} config
-   * @param {!Protocol.DOM.BackendNodeId=} backendNodeId
-   * @param {!Protocol.Runtime.RemoteObjectId=} objectId
-   */
-  highlightDOMNode(node, config, backendNodeId, objectId) {
-    if (objectId || node || backendNodeId) {
-      this._model._overlayAgent.highlightNode(
-          config, (objectId || backendNodeId) ? undefined : node.id, backendNodeId, objectId);
-    } else {
-      this._model._overlayAgent.hideHighlight();
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Overlay.InspectMode} mode
-   * @param {!Protocol.Overlay.HighlightConfig} config
-   * @return {!Promise}
-   */
-  setInspectMode(mode, config) {
-    return this._model._overlayAgent.setInspectMode(mode, config);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  highlightFrame(frameId) {
-    this._model._overlayAgent.highlightFrame(
-        frameId, Common.Color.PageHighlight.Content.toProtocolRGBA(),
-        Common.Color.PageHighlight.ContentOutline.toProtocolRGBA());
-  }
-};
diff --git a/front_end/sdk/PaintProfiler.js b/front_end/sdk/PaintProfiler.js
deleted file mode 100644
index c4371d5..0000000
--- a/front_end/sdk/PaintProfiler.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-SDK.PaintProfilerModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._layerTreeAgent = target.layerTreeAgent();
-  }
-
-  /**
-   * @param {!Array.<!SDK.PictureFragment>} fragments
-   * @return {!Promise<?SDK.PaintProfilerSnapshot>}
-   */
-  async loadSnapshotFromFragments(fragments) {
-    const snapshotId = await this._layerTreeAgent.loadSnapshot(fragments);
-    return snapshotId && new SDK.PaintProfilerSnapshot(this, snapshotId);
-  }
-
-  /**
-   * @param {string} encodedPicture
-   * @return {!Promise<?SDK.PaintProfilerSnapshot>}
-   */
-  loadSnapshot(encodedPicture) {
-    const fragment = {x: 0, y: 0, picture: encodedPicture};
-    return this.loadSnapshotFromFragments([fragment]);
-  }
-
-  /**
-   * @param {string} layerId
-   * @return {!Promise<?SDK.PaintProfilerSnapshot>}
-   */
-  async makeSnapshot(layerId) {
-    const snapshotId = await this._layerTreeAgent.makeSnapshot(layerId);
-    return snapshotId && new SDK.PaintProfilerSnapshot(this, snapshotId);
-  }
-};
-
-SDK.SDKModel.register(SDK.PaintProfilerModel, SDK.Target.Capability.DOM, false);
-
-/**
- * @typedef {!{x: number, y: number, picture: string}}
- */
-SDK.PictureFragment;
-
-SDK.PaintProfilerSnapshot = class {
-  /**
-   * @param {!SDK.PaintProfilerModel} paintProfilerModel
-   * @param {string} snapshotId
-   */
-  constructor(paintProfilerModel, snapshotId) {
-    this._paintProfilerModel = paintProfilerModel;
-    this._id = snapshotId;
-    this._refCount = 1;
-  }
-
-  release() {
-    console.assert(this._refCount > 0, 'release is already called on the object');
-    if (!--this._refCount)
-      this._paintProfilerModel._layerTreeAgent.releaseSnapshot(this._id);
-  }
-
-  addReference() {
-    ++this._refCount;
-    console.assert(this._refCount > 0, 'Referencing a dead object');
-  }
-
-  /**
-   * @param {number=} scale
-   * @param {number=} firstStep
-   * @param {number=} lastStep
-   * @return {!Promise<?string>}
-   */
-  replay(scale, firstStep, lastStep) {
-    return this._paintProfilerModel._layerTreeAgent.replaySnapshot(this._id, firstStep, lastStep, scale || 1.0);
-  }
-
-  /**
-   * @param {?Protocol.DOM.Rect} clipRect
-   * @return {!Promise<?Array<!Protocol.LayerTree.PaintProfile>>}
-   */
-  profile(clipRect) {
-    return this._paintProfilerModel._layerTreeAgent.profileSnapshot(this._id, 5, 1, clipRect || undefined);
-  }
-
-  /**
-   * @return {!Promise<?Array<!SDK.PaintProfilerLogItem>>}
-   */
-  async commandLog() {
-    const log = await this._paintProfilerModel._layerTreeAgent.snapshotCommandLog(this._id);
-    return log && log.map((entry, index) => new SDK.PaintProfilerLogItem(entry, index));
-  }
-};
-
-/**
- * @typedef {!{method: string, params: ?Object<string, *>}}
- */
-SDK.RawPaintProfilerLogItem;
-
-/**
- * @unrestricted
- */
-SDK.PaintProfilerLogItem = class {
-  /**
-   * @param {!SDK.RawPaintProfilerLogItem} rawEntry
-   * @param {number} commandIndex
-   */
-  constructor(rawEntry, commandIndex) {
-    this.method = rawEntry.method;
-    this.params = rawEntry.params;
-    this.commandIndex = commandIndex;
-  }
-};
diff --git a/front_end/sdk/PerformanceMetricsModel.js b/front_end/sdk/PerformanceMetricsModel.js
deleted file mode 100644
index ea744f8..0000000
--- a/front_end/sdk/PerformanceMetricsModel.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-SDK.PerformanceMetricsModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._agent = target.performanceAgent();
-
-    const mode = SDK.PerformanceMetricsModel.MetricMode;
-    /** @type {!Map<string, !SDK.PerformanceMetricsModel.MetricMode>} */
-    this._metricModes = new Map([
-      ['TaskDuration', mode.CumulativeTime], ['ScriptDuration', mode.CumulativeTime],
-      ['LayoutDuration', mode.CumulativeTime], ['RecalcStyleDuration', mode.CumulativeTime],
-      ['LayoutCount', mode.CumulativeCount], ['RecalcStyleCount', mode.CumulativeCount]
-    ]);
-
-    /** @type {!Map<string, !{lastValue: (number|undefined), lastTimestamp: (number|undefined)}>} */
-    this._metricData = new Map();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  enable() {
-    return this._agent.enable();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  disable() {
-    return this._agent.disable();
-  }
-
-  /**
-   * @return {!Promise<!{metrics: !Map<string, number>, timestamp: number}>}
-   */
-  async requestMetrics() {
-    const rawMetrics = await this._agent.getMetrics() || [];
-    const metrics = new Map();
-    const timestamp = performance.now();
-    for (const metric of rawMetrics) {
-      let data = this._metricData.get(metric.name);
-      if (!data) {
-        data = {};
-        this._metricData.set(metric.name, data);
-      }
-      let value;
-      switch (this._metricModes.get(metric.name)) {
-        case SDK.PerformanceMetricsModel.MetricMode.CumulativeTime:
-          value = data.lastTimestamp ?
-              Number.constrain((metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp), 0, 1) :
-              0;
-          data.lastValue = metric.value;
-          data.lastTimestamp = timestamp;
-          break;
-        case SDK.PerformanceMetricsModel.MetricMode.CumulativeCount:
-          value = data.lastTimestamp ?
-              Math.max(0, (metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp)) :
-              0;
-          data.lastValue = metric.value;
-          data.lastTimestamp = timestamp;
-          break;
-        default:
-          value = metric.value;
-          break;
-      }
-      metrics.set(metric.name, value);
-    }
-    const totalMemoryUsage = await this._requestTotalMemory();
-    metrics.set('JSHeapUsedSize', totalMemoryUsage.usedSize);
-    metrics.set('JSHeapTotalSize', totalMemoryUsage.totalSize);
-    return {metrics: metrics, timestamp: timestamp};
-  }
-
-  /**
-   * @return {!Promise<!{usedSize: number, totalSize: number}>}
-   */
-  async _requestTotalMemory() {
-    const models = SDK.targetManager.models(SDK.RuntimeModel);
-    const isolates = await Promise.all(models.map(model => model.isolateId()));
-    /** @type {!Map<string, !SDK.RuntimeModel>} */
-    const modelsByIsolate = new Map();
-    for (let i = 0; i < isolates.length; ++i)
-      modelsByIsolate.set(isolates[i], models[i]);
-    const usages = await Promise.all(modelsByIsolate.valuesArray().map(model => model.heapUsage()));
-    let totalSize = 0;
-    let usedSize = 0;
-    for (const usage of usages) {
-      totalSize += usage ? usage.totalSize : 0;
-      usedSize += usage ? usage.usedSize : 0;
-    }
-    return {totalSize, usedSize};
-  }
-};
-
-/** @enum {symbol} */
-SDK.PerformanceMetricsModel.MetricMode = {
-  CumulativeTime: Symbol('CumulativeTime'),
-  CumulativeCount: Symbol('CumulativeCount'),
-};
-
-SDK.SDKModel.register(SDK.PerformanceMetricsModel, SDK.Target.Capability.Browser, false);
diff --git a/front_end/sdk/ProfileTreeModel.js b/front_end/sdk/ProfileTreeModel.js
deleted file mode 100644
index 7f7c72d..0000000
--- a/front_end/sdk/ProfileTreeModel.js
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.ProfileNode = class {
-  /**
-   * @param {!Protocol.Runtime.CallFrame} callFrame
-   */
-  constructor(callFrame) {
-    /** @type {!Protocol.Runtime.CallFrame} */
-    this.callFrame = callFrame;
-    /** @type {string} */
-    this.callUID = `${this.callFrame.functionName}@${this.callFrame.scriptId}:${this.callFrame.lineNumber}`;
-    /** @type {number} */
-    this.self = 0;
-    /** @type {number} */
-    this.total = 0;
-    /** @type {number} */
-    this.id = 0;
-    /** @type {?SDK.ProfileNode} */
-    this.parent = null;
-    /** @type {!Array<!SDK.ProfileNode>} */
-    this.children = [];
-  }
-
-  /**
-   * @return {string}
-   */
-  get functionName() {
-    return this.callFrame.functionName;
-  }
-
-  /**
-   * @return {string}
-   */
-  get scriptId() {
-    return this.callFrame.scriptId;
-  }
-
-  /**
-   * @return {string}
-   */
-  get url() {
-    return this.callFrame.url;
-  }
-
-  /**
-   * @return {number}
-   */
-  get lineNumber() {
-    return this.callFrame.lineNumber;
-  }
-
-  /**
-   * @return {number}
-   */
-  get columnNumber() {
-    return this.callFrame.columnNumber;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.ProfileTreeModel = class {
-  /**
-   * @param {!SDK.ProfileNode} root
-   * @protected
-   */
-  initialize(root) {
-    this.root = root;
-    this._assignDepthsAndParents();
-    this.total = this._calculateTotals(this.root);
-  }
-
-  _assignDepthsAndParents() {
-    const root = this.root;
-    root.depth = -1;
-    root.parent = null;
-    this.maxDepth = 0;
-    const nodesToTraverse = [root];
-    while (nodesToTraverse.length) {
-      const parent = nodesToTraverse.pop();
-      const depth = parent.depth + 1;
-      if (depth > this.maxDepth)
-        this.maxDepth = depth;
-      const children = parent.children;
-      const length = children.length;
-      for (let i = 0; i < length; ++i) {
-        const child = children[i];
-        child.depth = depth;
-        child.parent = parent;
-        if (child.children.length)
-          nodesToTraverse.push(child);
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.ProfileNode} root
-   * @return {number}
-   */
-  _calculateTotals(root) {
-    const nodesToTraverse = [root];
-    const dfsList = [];
-    while (nodesToTraverse.length) {
-      const node = nodesToTraverse.pop();
-      node.total = node.self;
-      dfsList.push(node);
-      nodesToTraverse.push(...node.children);
-    }
-    while (dfsList.length > 1) {
-      const node = dfsList.pop();
-      node.parent.total += node.total;
-    }
-    return root.total;
-  }
-};
diff --git a/front_end/sdk/RemoteObject.js b/front_end/sdk/RemoteObject.js
deleted file mode 100644
index 8ab3a32..0000000
--- a/front_end/sdk/RemoteObject.js
+++ /dev/null
@@ -1,1420 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @typedef {{object: ?SDK.RemoteObject, wasThrown: (boolean|undefined)}}
- */
-SDK.CallFunctionResult;
-
-SDK.RemoteObject = class {
-  /**
-   * This may not be an interface due to "instanceof SDK.RemoteObject" checks in the code.
-   */
-
-  /**
-   * @param {*} value
-   * @return {!SDK.RemoteObject}
-   */
-  static fromLocalObject(value) {
-    return new SDK.LocalJSONObject(value);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} remoteObject
-   * @return {string}
-   */
-  static type(remoteObject) {
-    if (remoteObject === null)
-      return 'null';
-
-    const type = typeof remoteObject;
-    if (type !== 'object' && type !== 'function')
-      return type;
-
-    return remoteObject.type;
-  }
-
-  /**
-   * @param {string} description
-   * @return {string}
-   */
-  static arrayNameFromDescription(description) {
-    return description.replace(SDK.RemoteObject._descriptionLengthParenRegex, '')
-        .replace(SDK.RemoteObject._descriptionLengthSquareRegex, '');
-  }
-
-  /**
-   * @param {!SDK.RemoteObject|!Protocol.Runtime.RemoteObject|!Protocol.Runtime.ObjectPreview} object
-   * @return {number}
-   */
-  static arrayLength(object) {
-    if (object.subtype !== 'array' && object.subtype !== 'typedarray')
-      return 0;
-    // Array lengths in V8-generated descriptions switched from square brackets to parentheses.
-    // Both formats are checked in case the front end is dealing with an old version of V8.
-    const parenMatches = object.description.match(SDK.RemoteObject._descriptionLengthParenRegex);
-    const squareMatches = object.description.match(SDK.RemoteObject._descriptionLengthSquareRegex);
-    return parenMatches ? parseInt(parenMatches[1], 10) : (squareMatches ? parseInt(squareMatches[1], 10) : 0);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.RemoteObject|!SDK.RemoteObject|number|string|boolean|undefined|null|bigint} object
-   * @return {!Protocol.Runtime.CallArgument}
-   */
-  static toCallArgument(object) {
-    const type = typeof object;
-    if (type === 'undefined')
-      return {};
-    if (type === 'number') {
-      const description = String(object);
-      if (object === 0 && 1 / object < 0)
-        return {unserializableValue: SDK.RemoteObject.UnserializableNumber.Negative0};
-      if (description === SDK.RemoteObject.UnserializableNumber.NaN ||
-          description === SDK.RemoteObject.UnserializableNumber.Infinity ||
-          description === SDK.RemoteObject.UnserializableNumber.NegativeInfinity)
-        return {unserializableValue: description};
-      return {value: object};
-    }
-    if (type === 'bigint') {
-      const value = String(object) + 'n';
-      return {unserializableValue: /** @type {!Protocol.Runtime.UnserializableValue} */ (value)};
-    }
-    if (type === 'string' || type === 'boolean')
-      return {value: object};
-
-    if (!object)
-      return {value: null};
-
-    const isSDKRemoteObject = object instanceof SDK.RemoteObjectImpl;
-    if (!isSDKRemoteObject && typeof object.unserializableValue !== 'undefined')
-      return {unserializableValue: object.unserializableValue};
-    if (isSDKRemoteObject && typeof object._unserializableValue !== 'undefined')
-      return {unserializableValue: object._unserializableValue};
-
-    if (typeof object.objectId !== 'undefined')
-      return {objectId: object.objectId};
-
-    return {value: object.value};
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  static loadFromObjectPerProto(object, generatePreview, callback) {
-    // Combines 2 asynch calls. Doesn't rely on call-back orders (some calls may be loop-back).
-    let savedOwnProperties;
-    let savedAccessorProperties;
-    let savedInternalProperties;
-    let resultCounter = 2;
-
-    function processCallback() {
-      if (--resultCounter)
-        return;
-      if (savedOwnProperties && savedAccessorProperties) {
-        const propertiesMap = new Map();
-        const propertySymbols = [];
-        for (let i = 0; i < savedAccessorProperties.length; i++) {
-          const property = savedAccessorProperties[i];
-          if (property.symbol)
-            propertySymbols.push(property);
-          else
-            propertiesMap.set(property.name, property);
-        }
-        for (let i = 0; i < savedOwnProperties.length; i++) {
-          const property = savedOwnProperties[i];
-          if (property.isAccessorProperty())
-            continue;
-          if (property.symbol)
-            propertySymbols.push(property);
-          else
-            propertiesMap.set(property.name, property);
-        }
-        return callback(
-            propertiesMap.valuesArray().concat(propertySymbols),
-            savedInternalProperties ? savedInternalProperties : null);
-      } else {
-        callback(null, null);
-      }
-    }
-
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     */
-    function allAccessorPropertiesCallback(properties, internalProperties) {
-      savedAccessorProperties = properties;
-      processCallback();
-    }
-
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     */
-    function ownPropertiesCallback(properties, internalProperties) {
-      savedOwnProperties = properties;
-      savedInternalProperties = internalProperties;
-      processCallback();
-    }
-
-    object.getAllProperties(true /* accessorPropertiesOnly */, generatePreview, allAccessorPropertiesCallback);
-    object.getOwnProperties(generatePreview, ownPropertiesCallback);
-  }
-
-  /**
-   * @return {?Protocol.Runtime.CustomPreview}
-   */
-  customPreview() {
-    return null;
-  }
-
-  /** @return {!Protocol.Runtime.RemoteObjectId|undefined} */
-  get objectId() {
-    return 'Not implemented';
-  }
-
-  /** @return {string} */
-  get type() {
-    throw 'Not implemented';
-  }
-
-  /** @return {string|undefined} */
-  get subtype() {
-    throw 'Not implemented';
-  }
-
-  /** @return {*} */
-  get value() {
-    throw 'Not implemented';
-  }
-
-  /** @return {string|undefined} */
-  unserializableValue() {
-    throw 'Not implemented';
-  }
-
-  /** @return {string|undefined} */
-  get description() {
-    throw 'Not implemented';
-  }
-
-  /** @return {boolean} */
-  get hasChildren() {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @return {!Protocol.Runtime.ObjectPreview|undefined}
-   */
-  get preview() {
-    return undefined;
-  }
-
-  /**
-   * @return {number}
-   */
-  arrayLength() {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  getOwnProperties(generatePreview, callback) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {boolean} generatePreview
-   * @return {!Promise<!{properties: ?Array.<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>}>}
-   */
-  getOwnPropertiesPromise(generatePreview) {
-    return new Promise(promiseConstructor.bind(this));
-
-    /**
-     * @param {function(!{properties: ?Array.<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>})} success
-     * @this {SDK.RemoteObject}
-     */
-    function promiseConstructor(success) {
-      this.getOwnProperties(!!generatePreview, getOwnPropertiesCallback.bind(null, success));
-    }
-
-    /**
-     * @param {function(!{properties: ?Array.<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>})} callback
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     */
-    function getOwnPropertiesCallback(callback, properties, internalProperties) {
-      callback({properties: properties, internalProperties: internalProperties});
-    }
-  }
-
-  /**
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @param {function(?Array<!SDK.RemoteObjectProperty>, ?Array<!SDK.RemoteObjectProperty>)} callback
-   */
-  getAllProperties(accessorPropertiesOnly, generatePreview, callback) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @return {!Promise<!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array<!SDK.RemoteObjectProperty>}>}
-   */
-  getAllPropertiesPromise(accessorPropertiesOnly, generatePreview) {
-    return new Promise(promiseConstructor.bind(this));
-
-    /**
-     * @param {function(!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array.<!SDK.RemoteObjectProperty>})} success
-     * @this {SDK.RemoteObject}
-     */
-    function promiseConstructor(success) {
-      this.getAllProperties(accessorPropertiesOnly, generatePreview, getAllPropertiesCallback.bind(null, success));
-    }
-
-    /**
-     * @param {function(!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array<!SDK.RemoteObjectProperty>})} callback
-     * @param {?Array<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array<!SDK.RemoteObjectProperty>} internalProperties
-     */
-    function getAllPropertiesCallback(callback, properties, internalProperties) {
-      callback({properties: properties, internalProperties: internalProperties});
-    }
-  }
-
-  /**
-   * @param {!Array.<string>} propertyPath
-   * @param {function(?SDK.RemoteObject, boolean=)} callback
-   */
-  getProperty(propertyPath, callback) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {!Protocol.Runtime.CallArgument} name
-   * @return {!Promise<string|undefined>}
-   */
-  async deleteProperty(name) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {string|!Protocol.Runtime.CallArgument} name
-   * @param {string} value
-   * @return {!Promise<string|undefined>}
-   */
-  async setPropertyValue(name, value) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {function(this:Object, ...)} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>=} args
-   * @param {function(?SDK.RemoteObject, boolean=)=} callback
-   */
-  callFunction(functionDeclaration, args, callback) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {function(this:Object, ...)} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>=} args
-   * @return {!Promise<!SDK.CallFunctionResult>}
-   */
-  callFunctionPromise(functionDeclaration, args) {
-    return new Promise(promiseConstructor.bind(this));
-
-    /**
-     * @param {function(!SDK.CallFunctionResult)} success
-     * @this {SDK.RemoteObject}
-     */
-    function promiseConstructor(success) {
-      this.callFunction(functionDeclaration, args, callFunctionCallback.bind(null, success));
-    }
-
-    /**
-     * @param {function(!SDK.CallFunctionResult)} callback
-     * @param {?SDK.RemoteObject} object
-     * @param {boolean=} wasThrown
-     */
-    function callFunctionCallback(callback, object, wasThrown) {
-      callback({object: object, wasThrown: wasThrown});
-    }
-  }
-
-  /**
-   * @template T
-   * @param {function(this:Object, ...):T} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>|undefined} args
-   * @param {function(T)} callback
-   */
-  callFunctionJSON(functionDeclaration, args, callback) {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {function(this:Object, ...):T} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>|undefined} args
-   * @return {!Promise<T>}
-   * @template T
-   */
-  callFunctionJSONPromise(functionDeclaration, args) {
-    return new Promise(success => this.callFunctionJSON(functionDeclaration, args, success));
-  }
-
-  release() {
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel}
-   */
-  debuggerModel() {
-    throw new Error('DebuggerModel-less object');
-  }
-
-  /**
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    throw new Error('RuntimeModel-less object');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isNode() {
-    return false;
-  }
-};
-
-
-SDK.RemoteObjectImpl = class extends SDK.RemoteObject {
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {string|undefined} objectId
-   * @param {string} type
-   * @param {string|undefined} subtype
-   * @param {*} value
-   * @param {!Protocol.Runtime.UnserializableValue=} unserializableValue
-   * @param {string=} description
-   * @param {!Protocol.Runtime.ObjectPreview=} preview
-   * @param {!Protocol.Runtime.CustomPreview=} customPreview
-   */
-  constructor(runtimeModel, objectId, type, subtype, value, unserializableValue, description, preview, customPreview) {
-    super();
-
-    this._runtimeModel = runtimeModel;
-    this._runtimeAgent = runtimeModel.target().runtimeAgent();
-
-    this._type = type;
-    this._subtype = subtype;
-    if (objectId) {
-      // handle
-      this._objectId = objectId;
-      this._description = description;
-      this._hasChildren = (type !== 'symbol');
-      this._preview = preview;
-    } else {
-      this._description = description;
-      if (!this.description && unserializableValue)
-        this._description = unserializableValue;
-      if (!this._description && (typeof value !== 'object' || value === null))
-        this._description = value + '';
-      this._hasChildren = false;
-      if (typeof unserializableValue === 'string') {
-        this._unserializableValue = unserializableValue;
-        if (unserializableValue === SDK.RemoteObject.UnserializableNumber.Infinity ||
-            unserializableValue === SDK.RemoteObject.UnserializableNumber.NegativeInfinity ||
-            unserializableValue === SDK.RemoteObject.UnserializableNumber.Negative0 ||
-            unserializableValue === SDK.RemoteObject.UnserializableNumber.NaN)
-          this._value = Number(unserializableValue);
-        else if (type === 'bigint' && unserializableValue.endsWith('n'))
-          this._value = BigInt(unserializableValue.substring(0, unserializableValue.length - 1));
-        else
-          this._value = unserializableValue;
-
-      } else {
-        this._value = value;
-      }
-    }
-    this._customPreview = customPreview || null;
-  }
-
-  /**
-   * @override
-   * @return {?Protocol.Runtime.CustomPreview}
-   */
-  customPreview() {
-    return this._customPreview;
-  }
-
-  /**
-   * @override
-   * @return {!Protocol.Runtime.RemoteObjectId|undefined}
-   */
-  get objectId() {
-    return this._objectId;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  get type() {
-    return this._type;
-  }
-
-  /**
-   * @override
-   * @return {string|undefined}
-   */
-  get subtype() {
-    return this._subtype;
-  }
-
-  /**
-   * @override
-   * @return {*}
-   */
-  get value() {
-    return this._value;
-  }
-
-  /**
-   * @override
-   * @return {string|undefined}
-   */
-  unserializableValue() {
-    return this._unserializableValue;
-  }
-
-  /**
-   * @override
-   * @return {string|undefined}
-   */
-  get description() {
-    return this._description;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  get hasChildren() {
-    return this._hasChildren;
-  }
-
-  /**
-   * @override
-   * @return {!Protocol.Runtime.ObjectPreview|undefined}
-   */
-  get preview() {
-    return this._preview;
-  }
-
-  /**
-   * @override
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  getOwnProperties(generatePreview, callback) {
-    this.doGetProperties(true, false, generatePreview, callback);
-  }
-
-  /**
-   * @override
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  getAllProperties(accessorPropertiesOnly, generatePreview, callback) {
-    this.doGetProperties(false, accessorPropertiesOnly, generatePreview, callback);
-  }
-
-  /**
-   * @override
-   * @param {!Array.<string>} propertyPath
-   * @param {function(?SDK.RemoteObject, boolean=)} callback
-   */
-  getProperty(propertyPath, callback) {
-    /**
-     * @param {string} arrayStr
-     * @suppressReceiverCheck
-     * @this {Object}
-     */
-    function remoteFunction(arrayStr) {
-      let result = this;
-      const properties = JSON.parse(arrayStr);
-      for (let i = 0, n = properties.length; i < n; ++i)
-        result = result[properties[i]];
-      return result;
-    }
-
-    const args = [{value: JSON.stringify(propertyPath)}];
-    this.callFunction(remoteFunction, args, callback);
-  }
-
-  /**
-   * @param {boolean} ownProperties
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @param {function(?Array<!SDK.RemoteObjectProperty>, ?Array<!SDK.RemoteObjectProperty>)} callback
-   */
-  doGetProperties(ownProperties, accessorPropertiesOnly, generatePreview, callback) {
-    if (!this._objectId) {
-      callback(null, null);
-      return;
-    }
-
-    this._runtimeAgent
-        .invoke_getProperties({objectId: this._objectId, ownProperties, accessorPropertiesOnly, generatePreview})
-        .then(remoteObjectBinder.bind(this));
-
-    /**
-     * @param {!Protocol.RuntimeAgent.GetPropertiesResponse} response
-     * @this {SDK.RemoteObjectImpl}
-     */
-    function remoteObjectBinder(response) {
-      if (response[Protocol.Error]) {
-        callback(null, null);
-        return;
-      }
-      if (response.exceptionDetails) {
-        this._runtimeModel.exceptionThrown(Date.now(), response.exceptionDetails);
-        callback(null, null);
-        return;
-      }
-      const properties = response.result;
-      const internalProperties = response.internalProperties;
-      const result = [];
-      for (let i = 0; properties && i < properties.length; ++i) {
-        const property = properties[i];
-        const propertyValue = property.value ? this._runtimeModel.createRemoteObject(property.value) : null;
-        const propertySymbol = property.symbol ? this._runtimeModel.createRemoteObject(property.symbol) : null;
-        const remoteProperty = new SDK.RemoteObjectProperty(
-            property.name, propertyValue, !!property.enumerable, !!property.writable, !!property.isOwn,
-            !!property.wasThrown, propertySymbol);
-
-        if (typeof property.value === 'undefined') {
-          if (property.get && property.get.type !== 'undefined')
-            remoteProperty.getter = this._runtimeModel.createRemoteObject(property.get);
-          if (property.set && property.set.type !== 'undefined')
-            remoteProperty.setter = this._runtimeModel.createRemoteObject(property.set);
-        }
-
-        result.push(remoteProperty);
-      }
-      let internalPropertiesResult = null;
-      if (internalProperties) {
-        internalPropertiesResult = [];
-        for (let i = 0; i < internalProperties.length; i++) {
-          const property = internalProperties[i];
-          if (!property.value)
-            continue;
-          const propertyValue = this._runtimeModel.createRemoteObject(property.value);
-          internalPropertiesResult.push(new SDK.RemoteObjectProperty(property.name, propertyValue, true, false));
-        }
-      }
-      callback(result, internalPropertiesResult);
-    }
-  }
-
-  /**
-   * @override
-   * @param {string|!Protocol.Runtime.CallArgument} name
-   * @param {string} value
-   * @return {!Promise<string|undefined>}
-   */
-  async setPropertyValue(name, value) {
-    if (!this._objectId)
-      return `Can't set a property of non-object.`;
-
-    const response = await this._runtimeAgent.invoke_evaluate({expression: value, silent: true});
-    if (response[Protocol.Error] || response.exceptionDetails) {
-      return response[Protocol.Error] ||
-          (response.result.type !== 'string' ? response.result.description :
-                                               /** @type {string} */ (response.result.value));
-    }
-
-    if (typeof name === 'string')
-      name = SDK.RemoteObject.toCallArgument(name);
-
-    const resultPromise = this.doSetObjectPropertyValue(response.result, name);
-
-    if (response.result.objectId)
-      this._runtimeAgent.releaseObject(response.result.objectId);
-
-    return resultPromise;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.RemoteObject} result
-   * @param {!Protocol.Runtime.CallArgument} name
-   * @return {!Promise<string|undefined>}
-   */
-  async doSetObjectPropertyValue(result, name) {
-    // This assignment may be for a regular (data) property, and for an accessor property (with getter/setter).
-    // Note the sensitive matter about accessor property: the property may be physically defined in some proto object,
-    // but logically it is bound to the object in question. JavaScript passes this object to getters/setters, not the object
-    // where property was defined; so do we.
-    const setPropertyValueFunction = 'function(a, b) { this[a] = b; }';
-
-    const argv = [name, SDK.RemoteObject.toCallArgument(result)];
-    const response = await this._runtimeAgent.invoke_callFunctionOn(
-        {objectId: this._objectId, functionDeclaration: setPropertyValueFunction, arguments: argv, silent: true});
-    const error = response[Protocol.Error];
-    return error || response.exceptionDetails ? error || response.result.description : undefined;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.CallArgument} name
-   * @return {!Promise<string|undefined>}
-   */
-  async deleteProperty(name) {
-    if (!this._objectId)
-      return `Can't delete a property of non-object.`;
-
-    const deletePropertyFunction = 'function(a) { delete this[a]; return !(a in this); }';
-    const response = await this._runtimeAgent.invoke_callFunctionOn(
-        {objectId: this._objectId, functionDeclaration: deletePropertyFunction, arguments: [name], silent: true});
-
-    if (response[Protocol.Error] || response.exceptionDetails)
-      return response[Protocol.Error] || response.result.description;
-
-    if (!response.result.value)
-      return 'Failed to delete property.';
-  }
-
-  /**
-   * @override
-   * @param {function(this:Object, ...)} functionDeclaration
-   * @param {!Array.<!Protocol.Runtime.CallArgument>=} args
-   * @param {function(?SDK.RemoteObject, boolean=)=} callback
-   */
-  callFunction(functionDeclaration, args, callback) {
-    this._runtimeAgent
-        .invoke_callFunctionOn({
-          objectId: this._objectId,
-          functionDeclaration: functionDeclaration.toString(),
-          arguments: args,
-          silent: true
-        })
-        .then(response => {
-          if (!callback)
-            return;
-          if (response[Protocol.Error])
-            callback(null, false);
-          else
-            callback(this._runtimeModel.createRemoteObject(response.result), !!response.exceptionDetails);
-        });
-  }
-
-  /**
-   * @override
-   * @param {function(this:Object)} functionDeclaration
-   * @param {!Array.<!Protocol.Runtime.CallArgument>|undefined} args
-   * @param {function(*)} callback
-   */
-  callFunctionJSON(functionDeclaration, args, callback) {
-    this._runtimeAgent
-        .invoke_callFunctionOn({
-          objectId: this._objectId,
-          functionDeclaration: functionDeclaration.toString(),
-          arguments: args,
-          silent: true,
-          returnByValue: true
-        })
-        .then(
-            response => callback(response[Protocol.Error] || response.exceptionDetails ? null : response.result.value));
-  }
-
-  /**
-   * @override
-   */
-  release() {
-    if (!this._objectId)
-      return;
-    this._runtimeAgent.releaseObject(this._objectId);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  arrayLength() {
-    return SDK.RemoteObject.arrayLength(this);
-  }
-
-  /**
-   * @override
-   * @return {!SDK.DebuggerModel}
-   */
-  debuggerModel() {
-    return this._runtimeModel.debuggerModel();
-  }
-
-  /**
-   * @override
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._runtimeModel;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isNode() {
-    return !!this._objectId && this.type === 'object' && this.subtype === 'node';
-  }
-};
-
-
-SDK.ScopeRemoteObject = class extends SDK.RemoteObjectImpl {
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {string|undefined} objectId
-   * @param {!SDK.ScopeRef} scopeRef
-   * @param {string} type
-   * @param {string|undefined} subtype
-   * @param {*} value
-   * @param {!Protocol.Runtime.UnserializableValue=} unserializableValue
-   * @param {string=} description
-   * @param {!Protocol.Runtime.ObjectPreview=} preview
-   */
-  constructor(runtimeModel, objectId, scopeRef, type, subtype, value, unserializableValue, description, preview) {
-    super(runtimeModel, objectId, type, subtype, value, unserializableValue, description, preview);
-    this._scopeRef = scopeRef;
-    this._savedScopeProperties = undefined;
-  }
-
-  /**
-   * @override
-   * @param {boolean} ownProperties
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  doGetProperties(ownProperties, accessorPropertiesOnly, generatePreview, callback) {
-    if (accessorPropertiesOnly) {
-      callback([], []);
-      return;
-    }
-
-    if (this._savedScopeProperties) {
-      // No need to reload scope variables, as the remote object never
-      // changes its properties. If variable is updated, the properties
-      // array is patched locally.
-      callback(this._savedScopeProperties.slice(), []);
-      return;
-    }
-
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     * @this {SDK.ScopeRemoteObject}
-     */
-    function wrappedCallback(properties, internalProperties) {
-      if (this._scopeRef && Array.isArray(properties)) {
-        this._savedScopeProperties = properties.slice();
-        if (!this._scopeRef.callFrameId) {
-          for (const property of this._savedScopeProperties)
-            property.writable = false;
-        }
-      }
-      callback(properties, internalProperties);
-    }
-
-    // Scope objects always fetch preview.
-    generatePreview = true;
-
-    super.doGetProperties(ownProperties, accessorPropertiesOnly, generatePreview, wrappedCallback.bind(this));
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.RemoteObject} result
-   * @param {!Protocol.Runtime.CallArgument} argumentName
-   * @return {!Promise<string|undefined>}
-   */
-  async doSetObjectPropertyValue(result, argumentName) {
-    const name = /** @type {string} */ (argumentName.value);
-    const error = await this.debuggerModel().setVariableValue(
-        this._scopeRef.number, name, SDK.RemoteObject.toCallArgument(result), this._scopeRef.callFrameId);
-    if (error)
-      return error;
-    if (this._savedScopeProperties) {
-      for (const property of this._savedScopeProperties) {
-        if (property.name === name)
-          property.value = this._runtimeModel.createRemoteObject(result);
-      }
-    }
-  }
-};
-
-SDK.ScopeRef = class {
-  /**
-   * @param {number} number
-   * @param {string=} callFrameId
-   */
-  constructor(number, callFrameId) {
-    this.number = number;
-    this.callFrameId = callFrameId;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.RemoteObjectProperty = class {
-  /**
-   * @param {string} name
-   * @param {?SDK.RemoteObject} value
-   * @param {boolean=} enumerable
-   * @param {boolean=} writable
-   * @param {boolean=} isOwn
-   * @param {boolean=} wasThrown
-   * @param {?SDK.RemoteObject=} symbol
-   * @param {boolean=} synthetic
-   * @param {function(string):!Promise<?SDK.RemoteObject>=} syntheticSetter
-   */
-  constructor(name, value, enumerable, writable, isOwn, wasThrown, symbol, synthetic, syntheticSetter) {
-    this.name = name;
-    if (value !== null)
-      this.value = value;
-    this.enumerable = typeof enumerable !== 'undefined' ? enumerable : true;
-    const isNonSyntheticOrSyntheticWritable = !synthetic || !!syntheticSetter;
-    this.writable = typeof writable !== 'undefined' ? writable : isNonSyntheticOrSyntheticWritable;
-    this.isOwn = !!isOwn;
-    this.wasThrown = !!wasThrown;
-    if (symbol)
-      this.symbol = symbol;
-    this.synthetic = !!synthetic;
-    if (syntheticSetter)
-      this.syntheticSetter = syntheticSetter;
-  }
-
-  /**
-   * @param {string} expression
-   * @return {!Promise<boolean>}
-   */
-  async setSyntheticValue(expression) {
-    if (!this.syntheticSetter)
-      return false;
-    const result = await this.syntheticSetter(expression);
-    if (result)
-      this.value = result;
-    return !!result;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isAccessorProperty() {
-    return !!(this.getter || this.setter);
-  }
-};
-
-// Below is a wrapper around a local object that implements the RemoteObject interface,
-// which can be used by the UI code (primarily ObjectPropertiesSection).
-// Note that only JSON-compliant objects are currently supported, as there's no provision
-// for traversing prototypes, extracting class names via constructor, handling properties
-// or functions.
-
-SDK.LocalJSONObject = class extends SDK.RemoteObject {
-  /**
-   * @param {*} value
-   */
-  constructor(value) {
-    super();
-    this._value = value;
-    /** @type {string} */
-    this._cachedDescription;
-    /** @type {!Array<!SDK.RemoteObjectProperty>} */
-    this._cachedChildren;
-  }
-
-  /**
-   * @override
-   * @return {!Protocol.Runtime.RemoteObjectId|undefined}
-   * */
-  get objectId() {
-    return undefined;
-  }
-
-  /**
-   * @override
-   * @return {*}
-   */
-  get value() {
-    return this._value;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  get description() {
-    if (this._cachedDescription)
-      return this._cachedDescription;
-
-    /**
-     * @param {!SDK.RemoteObjectProperty} property
-     * @return {string}
-     * @this {SDK.LocalJSONObject}
-     */
-    function formatArrayItem(property) {
-      return this._formatValue(property.value);
-    }
-
-    /**
-     * @param {!SDK.RemoteObjectProperty} property
-     * @return {string}
-     * @this {SDK.LocalJSONObject}
-     */
-    function formatObjectItem(property) {
-      let name = property.name;
-      if (/^\s|\s$|^$|\n/.test(name))
-        name = '"' + name.replace(/\n/g, '\u21B5') + '"';
-      return name + ': ' + this._formatValue(property.value);
-    }
-
-    if (this.type === 'object') {
-      switch (this.subtype) {
-        case 'array':
-          this._cachedDescription = this._concatenate('[', ']', formatArrayItem.bind(this));
-          break;
-        case 'date':
-          this._cachedDescription = '' + this._value;
-          break;
-        case 'null':
-          this._cachedDescription = 'null';
-          break;
-        default:
-          this._cachedDescription = this._concatenate('{', '}', formatObjectItem.bind(this));
-      }
-    } else {
-      this._cachedDescription = String(this._value);
-    }
-
-    return this._cachedDescription;
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} value
-   * @return {string}
-   */
-  _formatValue(value) {
-    if (!value)
-      return 'undefined';
-    const description = value.description || '';
-    if (value.type === 'string')
-      return '"' + description.replace(/\n/g, '\u21B5') + '"';
-    return description;
-  }
-
-  /**
-   * @param {string} prefix
-   * @param {string} suffix
-   * @param {function(!SDK.RemoteObjectProperty)} formatProperty
-   * @return {string}
-   */
-  _concatenate(prefix, suffix, formatProperty) {
-    const previewChars = 100;
-
-    let buffer = prefix;
-    const children = this._children();
-    for (let i = 0; i < children.length; ++i) {
-      const itemDescription = formatProperty(children[i]);
-      if (buffer.length + itemDescription.length > previewChars) {
-        buffer += ',\u2026';
-        break;
-      }
-      if (i)
-        buffer += ', ';
-      buffer += itemDescription;
-    }
-    buffer += suffix;
-    return buffer;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  get type() {
-    return typeof this._value;
-  }
-
-  /**
-   * @override
-   * @return {string|undefined}
-   */
-  get subtype() {
-    if (this._value === null)
-      return 'null';
-
-    if (Array.isArray(this._value))
-      return 'array';
-
-    if (this._value instanceof Date)
-      return 'date';
-
-    return undefined;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  get hasChildren() {
-    if ((typeof this._value !== 'object') || (this._value === null))
-      return false;
-    return !!Object.keys(/** @type {!Object} */ (this._value)).length;
-  }
-
-  /**
-   * @override
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  getOwnProperties(generatePreview, callback) {
-    callback(this._children(), null);
-  }
-
-  /**
-   * @override
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  getAllProperties(accessorPropertiesOnly, generatePreview, callback) {
-    if (accessorPropertiesOnly)
-      callback([], null);
-    else
-      callback(this._children(), null);
-  }
-
-  /**
-   * @return {!Array.<!SDK.RemoteObjectProperty>}
-   */
-  _children() {
-    if (!this.hasChildren)
-      return [];
-    const value = /** @type {!Object} */ (this._value);
-
-    /**
-     * @param {string} propName
-     * @return {!SDK.RemoteObjectProperty}
-     */
-    function buildProperty(propName) {
-      let propValue = value[propName];
-      if (!(propValue instanceof SDK.RemoteObject))
-        propValue = SDK.RemoteObject.fromLocalObject(propValue);
-      return new SDK.RemoteObjectProperty(propName, propValue);
-    }
-    if (!this._cachedChildren)
-      this._cachedChildren = Object.keys(value).map(buildProperty);
-    return this._cachedChildren;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isError() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  arrayLength() {
-    return Array.isArray(this._value) ? this._value.length : 0;
-  }
-
-  /**
-   * @override
-   * @param {function(this:Object, ...)} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>=} args
-   * @param {function(?SDK.RemoteObject, boolean=)=} callback
-   */
-  callFunction(functionDeclaration, args, callback) {
-    const target = /** @type {?Object} */ (this._value);
-    const rawArgs = args ? args.map(arg => arg.value) : [];
-
-    let result;
-    let wasThrown = false;
-    try {
-      result = functionDeclaration.apply(target, rawArgs);
-    } catch (e) {
-      wasThrown = true;
-    }
-
-    if (!callback)
-      return;
-    callback(SDK.RemoteObject.fromLocalObject(result), wasThrown);
-  }
-
-  /**
-   * @override
-   * @param {function(this:Object)} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>|undefined} args
-   * @param {function(*)} callback
-   */
-  callFunctionJSON(functionDeclaration, args, callback) {
-    const target = /** @type {?Object} */ (this._value);
-    const rawArgs = args ? args.map(arg => arg.value) : [];
-
-    let result;
-    try {
-      result = functionDeclaration.apply(target, rawArgs);
-    } catch (e) {
-      result = null;
-    }
-
-    callback(result);
-  }
-};
-
-SDK.RemoteArray = class {
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  constructor(object) {
-    this._object = object;
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} object
-   * @return {!SDK.RemoteArray}
-   */
-  static objectAsArray(object) {
-    if (!object || object.type !== 'object' || (object.subtype !== 'array' && object.subtype !== 'typedarray'))
-      throw new Error('Object is empty or not an array');
-    return new SDK.RemoteArray(object);
-  }
-
-  /**
-   * @param {!Array<!SDK.RemoteObject>} objects
-   * @return {!Promise<!SDK.RemoteArray>}
-   */
-  static createFromRemoteObjects(objects) {
-    if (!objects.length)
-      throw new Error('Input array is empty');
-    const objectArguments = [];
-    for (let i = 0; i < objects.length; ++i)
-      objectArguments.push(SDK.RemoteObject.toCallArgument(objects[i]));
-    return objects[0].callFunctionPromise(createArray, objectArguments).then(returnRemoteArray);
-
-    /**
-     * @return {!Array<*>}
-     */
-    function createArray() {
-      if (arguments.length > 1)
-        return new Array(arguments);
-      return [arguments[0]];
-    }
-
-    /**
-     * @param {!SDK.CallFunctionResult} result
-     * @return {!SDK.RemoteArray}
-     */
-    function returnRemoteArray(result) {
-      if (result.wasThrown || !result.object)
-        throw new Error('Call function throws exceptions or returns empty value');
-      return SDK.RemoteArray.objectAsArray(result.object);
-    }
-  }
-
-  /**
-   * @param {number} index
-   * @return {!Promise<!SDK.RemoteObject>}
-   */
-  at(index) {
-    if (index < 0 || index > this._object.arrayLength())
-      throw new Error('Out of range');
-    return this._object.callFunctionPromise(at, [SDK.RemoteObject.toCallArgument(index)])
-        .then(assertCallFunctionResult);
-
-    /**
-     * @suppressReceiverCheck
-     * @param {number} index
-     * @return {*}
-     * @this {!Object}
-     */
-    function at(index) {
-      return this[index];
-    }
-
-    /**
-     * @param {!SDK.CallFunctionResult} result
-     * @return {!SDK.RemoteObject}
-     */
-    function assertCallFunctionResult(result) {
-      if (result.wasThrown || !result.object)
-        throw new Error('Exception in callFunction or result value is empty');
-      return result.object;
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  length() {
-    return this._object.arrayLength();
-  }
-
-  /**
-   * @param {function(!SDK.RemoteObject):!Promise<T>} func
-   * @return {!Promise<!Array<T>>}
-   * @template T
-   */
-  map(func) {
-    const promises = [];
-    for (let i = 0; i < this.length(); ++i)
-      promises.push(this.at(i).then(func));
-    return Promise.all(promises);
-  }
-
-  /**
-   * @return {!SDK.RemoteObject}
-   */
-  object() {
-    return this._object;
-  }
-};
-
-
-SDK.RemoteFunction = class {
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  constructor(object) {
-    this._object = object;
-  }
-
-  /**
-   * @param {?SDK.RemoteObject} object
-   * @return {!SDK.RemoteFunction}
-   */
-  static objectAsFunction(object) {
-    if (!object || object.type !== 'function')
-      throw new Error('Object is empty or not a function');
-    return new SDK.RemoteFunction(object);
-  }
-
-  /**
-   * @return {!Promise<!SDK.RemoteObject>}
-   */
-  targetFunction() {
-    return this._object.getOwnPropertiesPromise(false /* generatePreview */).then(targetFunction.bind(this));
-
-    /**
-     * @param {!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array<!SDK.RemoteObjectProperty>}} ownProperties
-     * @return {!SDK.RemoteObject}
-     * @this {SDK.RemoteFunction}
-     */
-    function targetFunction(ownProperties) {
-      if (!ownProperties.internalProperties)
-        return this._object;
-      const internalProperties = ownProperties.internalProperties;
-      for (const property of internalProperties) {
-        if (property.name === '[[TargetFunction]]')
-          return property.value;
-      }
-      return this._object;
-    }
-  }
-
-  /**
-   * @return {!Promise<?SDK.DebuggerModel.FunctionDetails>}
-   */
-  targetFunctionDetails() {
-    return this.targetFunction().then(functionDetails.bind(this));
-
-    /**
-     * @param {!SDK.RemoteObject} targetFunction
-     * @return {!Promise<?SDK.DebuggerModel.FunctionDetails>}
-     * @this {SDK.RemoteFunction}
-     */
-    function functionDetails(targetFunction) {
-      const boundReleaseFunctionDetails =
-          releaseTargetFunction.bind(null, this._object !== targetFunction ? targetFunction : null);
-      return targetFunction.debuggerModel().functionDetailsPromise(targetFunction).then(boundReleaseFunctionDetails);
-    }
-
-    /**
-     * @param {?SDK.RemoteObject} targetFunction
-     * @param {?SDK.DebuggerModel.FunctionDetails} functionDetails
-     * @return {?SDK.DebuggerModel.FunctionDetails}
-     */
-    function releaseTargetFunction(targetFunction, functionDetails) {
-      if (targetFunction)
-        targetFunction.release();
-      return functionDetails;
-    }
-  }
-
-  /**
-   * @return {!SDK.RemoteObject}
-   */
-  object() {
-    return this._object;
-  }
-};
-
-/**
- * @const
- * @type {!RegExp}
- */
-SDK.RemoteObject._descriptionLengthParenRegex = /\(([0-9]+)\)/;
-
-/**
- * @const
- * @type {!RegExp}
- */
-SDK.RemoteObject._descriptionLengthSquareRegex = /\[([0-9]+)\]/;
-
-/**
- * @const
- * @enum {!Protocol.Runtime.UnserializableValue}
- */
-SDK.RemoteObject.UnserializableNumber = {
-  Negative0: /** @type {!Protocol.Runtime.UnserializableValue} */ ('-0'),
-  NaN: /** @type {!Protocol.Runtime.UnserializableValue} */ ('NaN'),
-  Infinity: /** @type {!Protocol.Runtime.UnserializableValue} */ ('Infinity'),
-  NegativeInfinity: /** @type {!Protocol.Runtime.UnserializableValue} */ ('-Infinity')
-};
diff --git a/front_end/sdk/Resource.js b/front_end/sdk/Resource.js
deleted file mode 100644
index 8f0c412..0000000
--- a/front_end/sdk/Resource.js
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-SDK.Resource = class {
-  /**
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   * @param {?SDK.NetworkRequest} request
-   * @param {string} url
-   * @param {string} documentURL
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {!Common.ResourceType} type
-   * @param {string} mimeType
-   * @param {?Date} lastModified
-   * @param {?number} contentSize
-   */
-  constructor(
-      resourceTreeModel, request, url, documentURL, frameId, loaderId, type, mimeType, lastModified, contentSize) {
-    this._resourceTreeModel = resourceTreeModel;
-    this._request = request;
-    this.url = url;
-    this._documentURL = documentURL;
-    this._frameId = frameId;
-    this._loaderId = loaderId;
-    this._type = type || Common.resourceTypes.Other;
-    this._mimeType = mimeType;
-
-    this._lastModified = lastModified && lastModified.isValid() ? lastModified : null;
-    this._contentSize = contentSize;
-
-    /** @type {?string} */ this._content;
-    /** @type {boolean} */ this._contentEncoded;
-    this._pendingContentCallbacks = [];
-    if (this._request && !this._request.finished)
-      this._request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
-  }
-
-  /**
-   * @return {?Date}
-   */
-  lastModified() {
-    if (this._lastModified || !this._request)
-      return this._lastModified;
-    const lastModifiedHeader = this._request.responseLastModified();
-    const date = lastModifiedHeader ? new Date(lastModifiedHeader) : null;
-    this._lastModified = date && date.isValid() ? date : null;
-    return this._lastModified;
-  }
-
-  /**
-   * @return {?number}
-   */
-  contentSize() {
-    if (typeof this._contentSize === 'number' || !this._request)
-      return this._contentSize;
-    return this._request.resourceSize;
-  }
-
-  /**
-   * @return {?SDK.NetworkRequest}
-   */
-  get request() {
-    return this._request;
-  }
-
-  /**
-   * @return {string}
-   */
-  get url() {
-    return this._url;
-  }
-
-  /**
-   * @param {string} x
-   */
-  set url(x) {
-    this._url = x;
-    this._parsedURL = new Common.ParsedURL(x);
-  }
-
-  get parsedURL() {
-    return this._parsedURL;
-  }
-
-  /**
-   * @return {string}
-   */
-  get documentURL() {
-    return this._documentURL;
-  }
-
-  /**
-   * @return {!Protocol.Page.FrameId}
-   */
-  get frameId() {
-    return this._frameId;
-  }
-
-  /**
-   * @return {!Protocol.Network.LoaderId}
-   */
-  get loaderId() {
-    return this._loaderId;
-  }
-
-  /**
-   * @return {string}
-   */
-  get displayName() {
-    return this._parsedURL.displayName;
-  }
-
-  /**
-   * @return {!Common.ResourceType}
-   */
-  resourceType() {
-    return this._request ? this._request.resourceType() : this._type;
-  }
-
-  /**
-   * @return {string}
-   */
-  get mimeType() {
-    return this._request ? this._request.mimeType : this._mimeType;
-  }
-
-  /**
-   * @return {?string}
-   */
-  get content() {
-    return this._content;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this._url;
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    if (this.resourceType() === Common.resourceTypes.Document && this.mimeType.indexOf('javascript') !== -1)
-      return Common.resourceTypes.Script;
-    return this.resourceType();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  async contentEncoded() {
-    await this.requestContent();
-    return this._contentEncoded;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    if (typeof this._content !== 'undefined')
-      return Promise.resolve(this._content);
-
-    let callback;
-    const promise = new Promise(fulfill => callback = fulfill);
-    this._pendingContentCallbacks.push(callback);
-    if (!this._request || this._request.finished)
-      this._innerRequestContent();
-    return promise;
-  }
-
-  /**
-   * @return {string}
-   */
-  canonicalMimeType() {
-    return this.contentType().canonicalMimeType() || this.mimeType;
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  async searchInContent(query, caseSensitive, isRegex) {
-    if (!this.frameId)
-      return [];
-    if (this.request)
-      return this.request.searchInContent(query, caseSensitive, isRegex);
-    const result = await this._resourceTreeModel.target().pageAgent().searchInResource(
-        this.frameId, this.url, query, caseSensitive, isRegex);
-    return result || [];
-  }
-
-  /**
-   * @param {!Element} image
-   */
-  populateImageSource(image) {
-    /**
-     * @param {?string} content
-     * @this {SDK.Resource}
-     */
-    function onResourceContent(content) {
-      let imageSrc = Common.ContentProvider.contentAsDataURL(content, this._mimeType, true);
-      if (imageSrc === null)
-        imageSrc = this._url;
-      image.src = imageSrc;
-    }
-
-    this.requestContent().then(onResourceContent.bind(this));
-  }
-
-  _requestFinished() {
-    this._request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
-    if (this._pendingContentCallbacks.length)
-      this._innerRequestContent();
-  }
-
-  async _innerRequestContent() {
-    if (this._contentRequested)
-      return;
-    this._contentRequested = true;
-
-    if (this.request) {
-      const contentData = await this.request.contentData();
-      this._content = contentData.content;
-      this._contentEncoded = contentData.encoded;
-    } else {
-      const response = await this._resourceTreeModel.target().pageAgent().invoke_getResourceContent(
-          {frameId: this.frameId, url: this.url});
-      this._content = response[Protocol.Error] ? null : response.content;
-      this._contentEncoded = response.base64Encoded;
-    }
-
-    if (this._content === null)
-      this._contentEncoded = false;
-
-    for (const callback of this._pendingContentCallbacks.splice(0))
-      callback(this._content);
-    delete this._contentRequested;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasTextContent() {
-    if (this._type.isTextType())
-      return true;
-    if (this._type === Common.resourceTypes.Other)
-      return !!this._content && !this._contentEncoded;
-    return false;
-  }
-
-  /**
-   * @return {!SDK.ResourceTreeFrame}
-   */
-  frame() {
-    return this._resourceTreeModel.frameForId(this._frameId);
-  }
-};
diff --git a/front_end/sdk/ResourceTreeModel.js b/front_end/sdk/ResourceTreeModel.js
deleted file mode 100644
index 55dd099..0000000
--- a/front_end/sdk/ResourceTreeModel.js
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-SDK.ResourceTreeModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    const networkManager = target.model(SDK.NetworkManager);
-    if (networkManager) {
-      networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this);
-      networkManager.addEventListener(
-          SDK.NetworkManager.Events.RequestUpdateDropped, this._onRequestUpdateDropped, this);
-    }
-    this._agent = target.pageAgent();
-    this._agent.enable();
-    this._securityOriginManager = target.model(SDK.SecurityOriginManager);
-
-    target.registerPageDispatcher(new SDK.PageDispatcher(this));
-
-    /** @type {!Map<string, !SDK.ResourceTreeFrame>} */
-    this._frames = new Map();
-    this._cachedResourcesProcessed = false;
-    this._pendingReloadOptions = null;
-    this._reloadSuspensionCount = 0;
-    this._isInterstitialShowing = false;
-    /** @type {?SDK.ResourceTreeFrame} */
-    this.mainFrame = null;
-
-    this._agent.getResourceTree().then(this._processCachedResources.bind(this));
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   * @return {?SDK.ResourceTreeFrame}
-   */
-  static frameForRequest(request) {
-    const networkManager = SDK.NetworkManager.forRequest(request);
-    const resourceTreeModel = networkManager ? networkManager.target().model(SDK.ResourceTreeModel) : null;
-    if (!resourceTreeModel)
-      return null;
-    return resourceTreeModel.frameForId(request.frameId);
-  }
-
-  /**
-   * @return {!Array.<!SDK.ResourceTreeFrame>}
-   */
-  static frames() {
-    let result = [];
-    for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel))
-      result = result.concat(resourceTreeModel._frames.valuesArray());
-    return result;
-  }
-
-  /**
-   * @param {string} url
-   * @return {?SDK.Resource}
-   */
-  static resourceForURL(url) {
-    for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel)) {
-      const mainFrame = resourceTreeModel.mainFrame;
-      const result = mainFrame ? mainFrame.resourceForURL(url) : null;
-      if (result)
-        return result;
-    }
-    return null;
-  }
-
-  /**
-   * @param {boolean=} bypassCache
-   * @param {string=} scriptToEvaluateOnLoad
-   */
-  static reloadAllPages(bypassCache, scriptToEvaluateOnLoad) {
-    for (const resourceTreeModel of SDK.targetManager.models(SDK.ResourceTreeModel)) {
-      if (!resourceTreeModel.target().parentTarget())
-        resourceTreeModel.reloadPage(bypassCache, scriptToEvaluateOnLoad);
-    }
-  }
-
-  /**
-   * @return {!SDK.DOMModel}
-   */
-  domModel() {
-    return /** @type {!SDK.DOMModel} */ (this.target().model(SDK.DOMModel));
-  }
-
-  /**
-   * @param {?Protocol.Page.FrameResourceTree} mainFramePayload
-   */
-  _processCachedResources(mainFramePayload) {
-    if (mainFramePayload) {
-      this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.WillLoadCachedResources);
-      this._addFramesRecursively(null, mainFramePayload);
-      this.target().setInspectedURL(mainFramePayload.frame.url);
-    }
-    this._cachedResourcesProcessed = true;
-    const runtimeModel = this.target().model(SDK.RuntimeModel);
-    if (runtimeModel) {
-      runtimeModel.setExecutionContextComparator(this._executionContextComparator.bind(this));
-      runtimeModel.fireExecutionContextOrderChanged();
-    }
-    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  cachedResourcesLoaded() {
-    return this._cachedResourcesProcessed;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInterstitialShowing() {
-    return this._isInterstitialShowing;
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   * @param {boolean=} aboutToNavigate
-   */
-  _addFrame(frame, aboutToNavigate) {
-    this._frames.set(frame.id, frame);
-    if (frame.isMainFrame())
-      this.mainFrame = frame;
-    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameAdded, frame);
-    this._updateSecurityOrigins();
-  }
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {?Protocol.Page.FrameId} parentFrameId
-   * @param {!Protocol.Runtime.StackTrace=} stackTrace
-   * @return {?SDK.ResourceTreeFrame}
-   */
-  _frameAttached(frameId, parentFrameId, stackTrace) {
-    const parentFrame = parentFrameId ? (this._frames.get(parentFrameId) || null) : null;
-    // Do nothing unless cached resource tree is processed - it will overwrite everything.
-    if (!this._cachedResourcesProcessed && parentFrame)
-      return null;
-    if (this._frames.has(frameId))
-      return null;
-
-    const frame = new SDK.ResourceTreeFrame(this, parentFrame, frameId, null, stackTrace || null);
-    if (parentFrameId && !parentFrame)
-      frame._crossTargetParentFrameId = parentFrameId;
-    if (frame.isMainFrame() && this.mainFrame) {
-      // Navigation to the new backend process.
-      this._frameDetached(this.mainFrame.id);
-    }
-    this._addFrame(frame, true);
-    return frame;
-  }
-
-  /**
-   * @param {!Protocol.Page.Frame} framePayload
-   */
-  _frameNavigated(framePayload) {
-    const parentFrame = framePayload.parentId ? (this._frames.get(framePayload.parentId) || null) : null;
-    // Do nothing unless cached resource tree is processed - it will overwrite everything.
-    if (!this._cachedResourcesProcessed && parentFrame)
-      return;
-    let frame = this._frames.get(framePayload.id);
-    if (!frame) {
-      // Simulate missed "frameAttached" for a main frame navigation to the new backend process.
-      frame = this._frameAttached(framePayload.id, framePayload.parentId || '');
-      console.assert(frame);
-    }
-
-    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameWillNavigate, frame);
-    frame._navigate(framePayload);
-    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameNavigated, frame);
-
-    if (frame.isMainFrame())
-      this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.MainFrameNavigated, frame);
-
-    // Fill frame with retained resources (the ones loaded using new loader).
-    const resources = frame.resources();
-    for (let i = 0; i < resources.length; ++i)
-      this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ResourceAdded, resources[i]);
-
-    if (frame.isMainFrame())
-      this.target().setInspectedURL(frame.url);
-    this._updateSecurityOrigins();
-  }
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  _frameDetached(frameId) {
-    // Do nothing unless cached resource tree is processed - it will overwrite everything.
-    if (!this._cachedResourcesProcessed)
-      return;
-
-    const frame = this._frames.get(frameId);
-    if (!frame)
-      return;
-
-    if (frame.parentFrame)
-      frame.parentFrame._removeChildFrame(frame);
-    else
-      frame._remove();
-    this._updateSecurityOrigins();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestFinished(event) {
-    if (!this._cachedResourcesProcessed)
-      return;
-
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    if (request.failed || request.resourceType() === Common.resourceTypes.XHR)
-      return;
-
-    const frame = this._frames.get(request.frameId);
-    if (frame)
-      frame._addRequest(request);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestUpdateDropped(event) {
-    if (!this._cachedResourcesProcessed)
-      return;
-
-    const frameId = event.data.frameId;
-    const frame = this._frames.get(frameId);
-    if (!frame)
-      return;
-
-    const url = event.data.url;
-    if (frame._resourcesMap[url])
-      return;
-
-    const resource = new SDK.Resource(
-        this, null, url, frame.url, frameId, event.data.loaderId, Common.resourceTypes[event.data.resourceType],
-        event.data.mimeType, event.data.lastModified, null);
-    frame.addResource(resource);
-  }
-
-  /**
-   * @param {!Protocol.Page.FrameId} frameId
-   * @return {!SDK.ResourceTreeFrame}
-   */
-  frameForId(frameId) {
-    return this._frames.get(frameId);
-  }
-
-  /**
-   * @param {function(!SDK.Resource)} callback
-   * @return {boolean}
-   */
-  forAllResources(callback) {
-    if (this.mainFrame)
-      return this.mainFrame._callForFrameResources(callback);
-    return false;
-  }
-
-  /**
-   * @return {!Array<!SDK.ResourceTreeFrame>}
-   */
-  frames() {
-    return this._frames.valuesArray();
-  }
-
-  /**
-   * @param {string} url
-   * @return {?SDK.Resource}
-   */
-  resourceForURL(url) {
-    // Workers call into this with no frames available.
-    return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
-  }
-
-  /**
-   * @param {?SDK.ResourceTreeFrame} parentFrame
-   * @param {!Protocol.Page.FrameResourceTree} frameTreePayload
-   */
-  _addFramesRecursively(parentFrame, frameTreePayload) {
-    const framePayload = frameTreePayload.frame;
-    const frame = new SDK.ResourceTreeFrame(this, parentFrame, framePayload.id, framePayload, null);
-    if (!parentFrame && framePayload.parentId)
-      frame._crossTargetParentFrameId = framePayload.parentId;
-    this._addFrame(frame);
-
-    for (let i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
-      this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
-
-    for (let i = 0; i < frameTreePayload.resources.length; ++i) {
-      const subresource = frameTreePayload.resources[i];
-      const resource = this._createResourceFromFramePayload(
-          framePayload, subresource.url, Common.resourceTypes[subresource.type], subresource.mimeType,
-          subresource.lastModified || null, subresource.contentSize || null);
-      frame.addResource(resource);
-    }
-
-    if (!frame._resourcesMap[framePayload.url]) {
-      const frameResource = this._createResourceFromFramePayload(
-          framePayload, framePayload.url, Common.resourceTypes.Document, framePayload.mimeType, null, null);
-      frame.addResource(frameResource);
-    }
-  }
-
-  /**
-   * @param {!Protocol.Page.Frame} frame
-   * @param {string} url
-   * @param {!Common.ResourceType} type
-   * @param {string} mimeType
-   * @param {?number} lastModifiedTime
-   * @param {?number} contentSize
-   * @return {!SDK.Resource}
-   */
-  _createResourceFromFramePayload(frame, url, type, mimeType, lastModifiedTime, contentSize) {
-    const lastModified = typeof lastModifiedTime === 'number' ? new Date(lastModifiedTime * 1000) : null;
-    return new SDK.Resource(
-        this, null, url, frame.url, frame.id, frame.loaderId, type, mimeType, lastModified, contentSize);
-  }
-
-  suspendReload() {
-    this._reloadSuspensionCount++;
-  }
-
-  resumeReload() {
-    this._reloadSuspensionCount--;
-    console.assert(this._reloadSuspensionCount >= 0, 'Unbalanced call to ResourceTreeModel.resumeReload()');
-    if (!this._reloadSuspensionCount && this._pendingReloadOptions)
-      this.reloadPage.apply(this, this._pendingReloadOptions);
-  }
-
-  /**
-   * @param {boolean=} bypassCache
-   * @param {string=} scriptToEvaluateOnLoad
-   */
-  reloadPage(bypassCache, scriptToEvaluateOnLoad) {
-    // Only dispatch PageReloadRequested upon first reload request to simplify client logic.
-    if (!this._pendingReloadOptions)
-      this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.PageReloadRequested, this);
-    if (this._reloadSuspensionCount) {
-      this._pendingReloadOptions = [bypassCache, scriptToEvaluateOnLoad];
-      return;
-    }
-    this._pendingReloadOptions = null;
-    this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.WillReloadPage);
-    this._agent.reload(bypassCache, scriptToEvaluateOnLoad);
-  }
-
-  /**
-   * @param {string} url
-   * @return {!Promise}
-   */
-  navigate(url) {
-    return this._agent.navigate(url);
-  }
-
-  /**
-   * @return {!Promise<?{currentIndex: number, entries: !Protocol.Page.NavigationEntry}>}
-   */
-  async navigationHistory() {
-    const response = await this._agent.invoke_getNavigationHistory({});
-    if (response[Protocol.Error])
-      return null;
-    return {currentIndex: response.currentIndex, entries: response.entries};
-  }
-
-  /**
-   * @param {!Protocol.Page.NavigationEntry} entry
-   */
-  navigateToHistoryEntry(entry) {
-    this._agent.navigateToHistoryEntry(entry.id);
-  }
-
-  /**
-   * @param {function(string, ?string, !Array<!Protocol.Page.AppManifestError>)} callback
-   */
-  async fetchAppManifest(callback) {
-    const response = await this._agent.invoke_getAppManifest({});
-    if (response[Protocol.Error])
-      callback(response.url, null, []);
-    else
-      callback(response.url, response.data || null, response.errors);
-  }
-  /**
-   * @param {!SDK.ExecutionContext} a
-   * @param {!SDK.ExecutionContext} b
-   * @return {number}
-   */
-  _executionContextComparator(a, b) {
-    /**
-     * @param {!SDK.ResourceTreeFrame} frame
-     */
-    function framePath(frame) {
-      let currentFrame = frame;
-      const parents = [];
-      while (currentFrame) {
-        parents.push(currentFrame);
-        currentFrame = currentFrame.parentFrame;
-      }
-      return parents.reverse();
-    }
-
-    if (a.target() !== b.target())
-      return SDK.ExecutionContext.comparator(a, b);
-
-    const framesA = a.frameId ? framePath(this.frameForId(a.frameId)) : [];
-    const framesB = b.frameId ? framePath(this.frameForId(b.frameId)) : [];
-    let frameA;
-    let frameB;
-    for (let i = 0;; i++) {
-      if (!framesA[i] || !framesB[i] || (framesA[i] !== framesB[i])) {
-        frameA = framesA[i];
-        frameB = framesB[i];
-        break;
-      }
-    }
-    if (!frameA && frameB)
-      return -1;
-
-    if (!frameB && frameA)
-      return 1;
-
-    if (frameA && frameB)
-      return frameA.id.localeCompare(frameB.id);
-
-    return SDK.ExecutionContext.comparator(a, b);
-  }
-
-  _updateSecurityOrigins() {
-    const securityOrigins = new Set();
-    let mainSecurityOrigin = null;
-    for (const frame of this._frames.values()) {
-      const origin = frame.securityOrigin;
-      if (!origin)
-        continue;
-      securityOrigins.add(origin);
-      if (frame.isMainFrame())
-        mainSecurityOrigin = origin;
-    }
-    this._securityOriginManager.updateSecurityOrigins(securityOrigins);
-    this._securityOriginManager.setMainSecurityOrigin(mainSecurityOrigin || '');
-  }
-};
-
-SDK.SDKModel.register(SDK.ResourceTreeModel, SDK.Target.Capability.DOM, true);
-
-/** @enum {symbol} */
-SDK.ResourceTreeModel.Events = {
-  FrameAdded: Symbol('FrameAdded'),
-  FrameNavigated: Symbol('FrameNavigated'),
-  FrameDetached: Symbol('FrameDetached'),
-  FrameResized: Symbol('FrameResized'),
-  FrameWillNavigate: Symbol('FrameWillNavigate'),
-  MainFrameNavigated: Symbol('MainFrameNavigated'),
-  ResourceAdded: Symbol('ResourceAdded'),
-  WillLoadCachedResources: Symbol('WillLoadCachedResources'),
-  CachedResourcesLoaded: Symbol('CachedResourcesLoaded'),
-  DOMContentLoaded: Symbol('DOMContentLoaded'),
-  LifecycleEvent: Symbol('LifecycleEvent'),
-  Load: Symbol('Load'),
-  PageReloadRequested: Symbol('PageReloadRequested'),
-  WillReloadPage: Symbol('WillReloadPage'),
-  InterstitialShown: Symbol('InterstitialShown'),
-  InterstitialHidden: Symbol('InterstitialHidden')
-};
-
-
-/**
- * @unrestricted
- */
-SDK.ResourceTreeFrame = class {
-  /**
-   * @param {!SDK.ResourceTreeModel} model
-   * @param {?SDK.ResourceTreeFrame} parentFrame
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {?Protocol.Page.Frame} payload
-   * @param {?Protocol.Runtime.StackTrace} creationStackTrace
-   */
-  constructor(model, parentFrame, frameId, payload, creationStackTrace) {
-    this._model = model;
-    this._parentFrame = parentFrame;
-    this._id = frameId;
-    this._url = '';
-    this._crossTargetParentFrameId = null;
-
-    if (payload) {
-      this._loaderId = payload.loaderId;
-      this._name = payload.name;
-      this._url = payload.url;
-      this._securityOrigin = payload.securityOrigin;
-      this._mimeType = payload.mimeType;
-    }
-
-    this._creationStackTrace = creationStackTrace;
-
-    /**
-     * @type {!Array.<!SDK.ResourceTreeFrame>}
-     */
-    this._childFrames = [];
-
-    /**
-     * @type {!Object.<string, !SDK.Resource>}
-     */
-    this._resourcesMap = {};
-
-    if (this._parentFrame)
-      this._parentFrame._childFrames.push(this);
-  }
-
-  /**
-   * @return {!SDK.ResourceTreeModel}
-   */
-  resourceTreeModel() {
-    return this._model;
-  }
-
-  /**
-   * @return {string}
-   */
-  get id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  get name() {
-    return this._name || '';
-  }
-
-  /**
-   * @return {string}
-   */
-  get url() {
-    return this._url;
-  }
-
-  /**
-   * @return {string}
-   */
-  get securityOrigin() {
-    return this._securityOrigin;
-  }
-
-  /**
-   * @return {string}
-   */
-  get loaderId() {
-    return this._loaderId;
-  }
-
-  /**
-   * @return {?SDK.ResourceTreeFrame}
-   */
-  get parentFrame() {
-    return this._parentFrame;
-  }
-
-  /**
-   * @return {!Array.<!SDK.ResourceTreeFrame>}
-   */
-  get childFrames() {
-    return this._childFrames;
-  }
-
-  /**
-   * @return {?SDK.ResourceTreeFrame}
-   */
-  crossTargetParentFrame() {
-    if (!this._crossTargetParentFrameId)
-      return null;
-    if (!this._model.target().parentTarget())
-      return null;
-    const parentModel = this._model.target().parentTarget().model(SDK.ResourceTreeModel);
-    if (!parentModel)
-      return null;
-    // Note that parent model has already processed cached resources:
-    // - when parent target was created, we issued getResourceTree call;
-    // - strictly after we issued setAutoAttach call;
-    // - both of them were handled in renderer in the same order;
-    // - cached resource tree got processed on parent model;
-    // - child target was created as a result of setAutoAttach call.
-    return parentModel._frames.get(this._crossTargetParentFrameId) || null;
-  }
-
-  /**
-   * @param {function(!Protocol.Runtime.CallFrame):boolean} searchFn
-   * @return {?Protocol.Runtime.CallFrame}
-   */
-  findCreationCallFrame(searchFn) {
-    let stackTrace = this._creationStackTrace;
-    while (stackTrace) {
-      const foundEntry = stackTrace.callFrames.find(searchFn);
-      if (foundEntry)
-        return foundEntry;
-      stackTrace = this.parent;
-    }
-    return null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isMainFrame() {
-    return !this._parentFrame;
-  }
-
-  isTopFrame() {
-    return !this._parentFrame && !this._crossTargetParentFrameId;
-  }
-
-  /**
-   * @param {!Protocol.Page.Frame} framePayload
-   */
-  _navigate(framePayload) {
-    this._loaderId = framePayload.loaderId;
-    this._name = framePayload.name;
-    this._url = framePayload.url;
-    this._securityOrigin = framePayload.securityOrigin;
-    this._mimeType = framePayload.mimeType;
-
-    const mainResource = this._resourcesMap[this._url];
-    this._resourcesMap = {};
-    this._removeChildFrames();
-    if (mainResource && mainResource.loaderId === this._loaderId)
-      this.addResource(mainResource);
-  }
-
-  /**
-   * @return {!SDK.Resource}
-   */
-  get mainResource() {
-    return this._resourcesMap[this._url];
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _removeChildFrame(frame) {
-    this._childFrames.remove(frame);
-    frame._remove();
-  }
-
-  _removeChildFrames() {
-    const frames = this._childFrames;
-    this._childFrames = [];
-    for (let i = 0; i < frames.length; ++i)
-      frames[i]._remove();
-  }
-
-  _remove() {
-    this._removeChildFrames();
-    this._model._frames.delete(this.id);
-    this._model.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameDetached, this);
-  }
-
-  /**
-   * @param {!SDK.Resource} resource
-   */
-  addResource(resource) {
-    if (this._resourcesMap[resource.url] === resource) {
-      // Already in the tree, we just got an extra update.
-      return;
-    }
-    this._resourcesMap[resource.url] = resource;
-    this._model.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ResourceAdded, resource);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  _addRequest(request) {
-    let resource = this._resourcesMap[request.url()];
-    if (resource && resource.request === request) {
-      // Already in the tree, we just got an extra update.
-      return;
-    }
-    resource = new SDK.Resource(
-        this._model, request, request.url(), request.documentURL, request.frameId, request.loaderId,
-        request.resourceType(), request.mimeType, null, null);
-    this._resourcesMap[resource.url] = resource;
-    this._model.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ResourceAdded, resource);
-  }
-
-  /**
-   * @return {!Array.<!SDK.Resource>}
-   */
-  resources() {
-    const result = [];
-    for (const url in this._resourcesMap)
-      result.push(this._resourcesMap[url]);
-    return result;
-  }
-
-  /**
-   * @param {string} url
-   * @return {?SDK.Resource}
-   */
-  resourceForURL(url) {
-    let resource = this._resourcesMap[url] || null;
-    if (resource)
-      return resource;
-    for (let i = 0; !resource && i < this._childFrames.length; ++i)
-      resource = this._childFrames[i].resourceForURL(url);
-    return resource;
-  }
-
-  /**
-   * @param {function(!SDK.Resource)} callback
-   * @return {boolean}
-   */
-  _callForFrameResources(callback) {
-    for (const url in this._resourcesMap) {
-      if (callback(this._resourcesMap[url]))
-        return true;
-    }
-
-    for (let i = 0; i < this._childFrames.length; ++i) {
-      if (this._childFrames[i]._callForFrameResources(callback))
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @return {string}
-   */
-  displayName() {
-    if (this.isTopFrame())
-      return Common.UIString('top');
-    const subtitle = new Common.ParsedURL(this._url).displayName;
-    if (subtitle) {
-      if (!this._name)
-        return subtitle;
-      return this._name + ' (' + subtitle + ')';
-    }
-    return Common.UIString('<iframe>');
-  }
-};
-
-
-/**
- * @implements {Protocol.PageDispatcher}
- * @unrestricted
- */
-SDK.PageDispatcher = class {
-  /**
-   * @param {!SDK.ResourceTreeModel} resourceTreeModel
-   */
-  constructor(resourceTreeModel) {
-    this._resourceTreeModel = resourceTreeModel;
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   */
-  domContentEventFired(time) {
-    this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.DOMContentLoaded, time);
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   */
-  loadEventFired(time) {
-    this._resourceTreeModel.dispatchEventToListeners(
-        SDK.ResourceTreeModel.Events.Load, {resourceTreeModel: this._resourceTreeModel, loadTime: time});
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {string} name
-   * @param {number} time
-   */
-  lifecycleEvent(frameId, loaderId, name, time) {
-    this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.LifecycleEvent, {frameId, name});
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Page.FrameId} parentFrameId
-   * @param {!Protocol.Runtime.StackTrace=} stackTrace
-   */
-  frameAttached(frameId, parentFrameId, stackTrace) {
-    this._resourceTreeModel._frameAttached(frameId, parentFrameId, stackTrace);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.Frame} frame
-   */
-  frameNavigated(frame) {
-    this._resourceTreeModel._frameNavigated(frame);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameDetached(frameId) {
-    this._resourceTreeModel._frameDetached(frameId);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameStartedLoading(frameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameStoppedLoading(frameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {number} delay
-   */
-  frameScheduledNavigation(frameId, delay) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameClearedScheduledNavigation(frameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {string} url
-   */
-  navigatedWithinDocument(frameId, url) {
-  }
-
-  /**
-   * @override
-   */
-  frameResized() {
-    this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameResized, null);
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} message
-   * @param {string} dialogType
-   * @param {boolean} hasBrowserHandler
-   * @param {string=} prompt
-   */
-  javascriptDialogOpening(url, message, dialogType, hasBrowserHandler, prompt) {
-    if (!hasBrowserHandler)
-      this._resourceTreeModel._agent.handleJavaScriptDialog(false);
-  }
-
-  /**
-   * @override
-   * @param {boolean} result
-   * @param {string} userInput
-   */
-  javascriptDialogClosed(result, userInput) {
-  }
-
-  /**
-   * @override
-   * @param {string} data
-   * @param {!Protocol.Page.ScreencastFrameMetadata} metadata
-   * @param {number} sessionId
-   */
-  screencastFrame(data, metadata, sessionId) {
-  }
-
-  /**
-   * @override
-   * @param {boolean} visible
-   */
-  screencastVisibilityChanged(visible) {
-  }
-
-  /**
-   * @override
-   */
-  interstitialShown() {
-    this._resourceTreeModel._isInterstitialShowing = true;
-    this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.InterstitialShown);
-  }
-
-  /**
-   * @override
-   */
-  interstitialHidden() {
-    this._resourceTreeModel._isInterstitialShowing = false;
-    this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.InterstitialHidden);
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} windowName
-   * @param {!Array<string>} windowFeatures
-   * @param {boolean} userGesture
-   */
-  windowOpen(url, windowName, windowFeatures, userGesture) {
-  }
-};
diff --git a/front_end/sdk/RuntimeModel.js b/front_end/sdk/RuntimeModel.js
deleted file mode 100644
index 4d454d7..0000000
--- a/front_end/sdk/RuntimeModel.js
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.RuntimeModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    this._agent = target.runtimeAgent();
-    this.target().registerRuntimeDispatcher(new SDK.RuntimeDispatcher(this));
-    this._agent.enable();
-    /** @type {!Map<number, !SDK.ExecutionContext>} */
-    this._executionContextById = new Map();
-    this._executionContextComparator = SDK.ExecutionContext.comparator;
-    /** @type {?boolean} */
-    this._hasSideEffectSupport = null;
-
-    if (Common.moduleSetting('customFormatters').get())
-      this._agent.setCustomObjectFormatterEnabled(true);
-
-    Common.moduleSetting('customFormatters').addChangeListener(this._customFormattersStateChanged.bind(this));
-  }
-
-  /**
-   * @param {string} code
-   * @return {string}
-   */
-  static wrapObjectLiteralExpressionIfNeeded(code) {
-    // Only parenthesize what appears to be an object literal.
-    if (!(/^\s*\{/.test(code) && /\}\s*$/.test(code)))
-      return code;
-
-    const parse = (async () => 0).constructor;
-    try {
-      // Check if the code can be interpreted as an expression.
-      parse('return ' + code + ';');
-
-      // No syntax error! Does it work parenthesized?
-      const wrappedCode = '(' + code + ')';
-      parse(wrappedCode);
-
-      return wrappedCode;
-    } catch (e) {
-      return code;
-    }
-  }
-
-  /**
-   * @return {!SDK.DebuggerModel}
-   */
-  debuggerModel() {
-    return /** @type {!SDK.DebuggerModel} */ (this.target().model(SDK.DebuggerModel));
-  }
-
-  /**
-   * @return {!SDK.HeapProfilerModel}
-   */
-  heapProfilerModel() {
-    return /** @type {!SDK.HeapProfilerModel} */ (this.target().model(SDK.HeapProfilerModel));
-  }
-
-  /**
-   * @return {!Array.<!SDK.ExecutionContext>}
-   */
-  executionContexts() {
-    return this._executionContextById.valuesArray().sort(this.executionContextComparator());
-  }
-
-  /**
-   * @param {function(!SDK.ExecutionContext,!SDK.ExecutionContext)} comparator
-   */
-  setExecutionContextComparator(comparator) {
-    this._executionContextComparator = comparator;
-  }
-
-  /**
-   * @return {function(!SDK.ExecutionContext,!SDK.ExecutionContext)} comparator
-   */
-  executionContextComparator() {
-    return this._executionContextComparator;
-  }
-
-  /**
-   * @return {?SDK.ExecutionContext}
-   */
-  defaultExecutionContext() {
-    for (const context of this.executionContexts()) {
-      if (context.isDefault)
-        return context;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ExecutionContextId} id
-   * @return {?SDK.ExecutionContext}
-   */
-  executionContext(id) {
-    return this._executionContextById.get(id) || null;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ExecutionContextDescription} context
-   */
-  _executionContextCreated(context) {
-    const data = context.auxData || {isDefault: true};
-    const executionContext =
-        new SDK.ExecutionContext(this, context.id, context.name, context.origin, data['isDefault'], data['frameId']);
-    this._executionContextById.set(executionContext.id, executionContext);
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.ExecutionContextCreated, executionContext);
-  }
-
-  /**
-   * @param {number} executionContextId
-   */
-  _executionContextDestroyed(executionContextId) {
-    const executionContext = this._executionContextById.get(executionContextId);
-    if (!executionContext)
-      return;
-    this.debuggerModel().executionContextDestroyed(executionContext);
-    this._executionContextById.delete(executionContextId);
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.ExecutionContextDestroyed, executionContext);
-  }
-
-  fireExecutionContextOrderChanged() {
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.ExecutionContextOrderChanged, this);
-  }
-
-  _executionContextsCleared() {
-    this.debuggerModel().globalObjectCleared();
-    const contexts = this.executionContexts();
-    this._executionContextById.clear();
-    for (let i = 0; i < contexts.length; ++i)
-      this.dispatchEventToListeners(SDK.RuntimeModel.Events.ExecutionContextDestroyed, contexts[i]);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.RemoteObject} payload
-   * @return {!SDK.RemoteObject}
-   */
-  createRemoteObject(payload) {
-    console.assert(typeof payload === 'object', 'Remote object payload should only be an object');
-    return new SDK.RemoteObjectImpl(
-        this, payload.objectId, payload.type, payload.subtype, payload.value, payload.unserializableValue,
-        payload.description, payload.preview, payload.customPreview);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.RemoteObject} payload
-   * @param {!SDK.ScopeRef} scopeRef
-   * @return {!SDK.RemoteObject}
-   */
-  createScopeRemoteObject(payload, scopeRef) {
-    return new SDK.ScopeRemoteObject(
-        this, payload.objectId, scopeRef, payload.type, payload.subtype, payload.value, payload.unserializableValue,
-        payload.description, payload.preview);
-  }
-
-  /**
-   * @param {number|string|boolean|undefined|bigint} value
-   * @return {!SDK.RemoteObject}
-   */
-  createRemoteObjectFromPrimitiveValue(value) {
-    const type = typeof value;
-    let unserializableValue = undefined;
-    if (type === 'number') {
-      const description = String(value);
-      if (value === 0 && 1 / value < 0)
-        unserializableValue = SDK.RemoteObject.UnserializableNumber.Negative0;
-      else if (
-          description === SDK.RemoteObject.UnserializableNumber.NaN ||
-          description === SDK.RemoteObject.UnserializableNumber.Infinity ||
-          description === SDK.RemoteObject.UnserializableNumber.NegativeInfinity)
-        unserializableValue = description;
-    }
-    if (type === 'bigint')
-      unserializableValue = /** @type {!Protocol.Runtime.UnserializableValue} */ (String(value) + 'n');
-    if (typeof unserializableValue !== 'undefined')
-      value = undefined;
-    return new SDK.RemoteObjectImpl(this, undefined, type, undefined, value, unserializableValue);
-  }
-
-  /**
-   * @param {string} name
-   * @param {number|string|boolean} value
-   * @return {!SDK.RemoteObjectProperty}
-   */
-  createRemotePropertyFromPrimitiveValue(name, value) {
-    return new SDK.RemoteObjectProperty(name, this.createRemoteObjectFromPrimitiveValue(value));
-  }
-
-  discardConsoleEntries() {
-    this._agent.discardConsoleEntries();
-  }
-
-  /**
-   * @param {string} objectGroupName
-   */
-  releaseObjectGroup(objectGroupName) {
-    this._agent.releaseObjectGroup(objectGroupName);
-  }
-
-  runIfWaitingForDebugger() {
-    this._agent.runIfWaitingForDebugger();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _customFormattersStateChanged(event) {
-    const enabled = /** @type {boolean} */ (event.data);
-    this._agent.setCustomObjectFormatterEnabled(enabled);
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} sourceURL
-   * @param {boolean} persistScript
-   * @param {number} executionContextId
-   * @return {?Promise<!SDK.RuntimeModel.CompileScriptResult>}
-   */
-  async compileScript(expression, sourceURL, persistScript, executionContextId) {
-    const response = await this._agent.invoke_compileScript({
-      expression: expression,
-      sourceURL: sourceURL,
-      persistScript: persistScript,
-      executionContextId: executionContextId
-    });
-
-    if (response[Protocol.Error]) {
-      console.error(response[Protocol.Error]);
-      return null;
-    }
-    return {scriptId: response.scriptId, exceptionDetails: response.exceptionDetails};
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {number} executionContextId
-   * @param {string=} objectGroup
-   * @param {boolean=} silent
-   * @param {boolean=} includeCommandLineAPI
-   * @param {boolean=} returnByValue
-   * @param {boolean=} generatePreview
-   * @param {boolean=} awaitPromise
-   * @return {!Promise<!SDK.RuntimeModel.EvaluationResult>}
-   */
-  async runScript(
-      scriptId, executionContextId, objectGroup, silent, includeCommandLineAPI, returnByValue, generatePreview,
-      awaitPromise) {
-    const response = await this._agent.invoke_runScript({
-      scriptId,
-      executionContextId,
-      objectGroup,
-      silent,
-      includeCommandLineAPI,
-      returnByValue,
-      generatePreview,
-      awaitPromise
-    });
-
-    const error = response[Protocol.Error];
-    if (error) {
-      console.error(error);
-      return {error: error};
-    }
-    return {object: this.createRemoteObject(response.result), exceptionDetails: response.exceptionDetails};
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} prototype
-   * @return {!Promise<!SDK.RuntimeModel.QueryObjectResult>}
-   */
-  async queryObjects(prototype) {
-    if (!prototype.objectId)
-      return {error: 'Prototype should be an Object.'};
-    const response = await this._agent.invoke_queryObjects(
-        {prototypeObjectId: /** @type {string} */ (prototype.objectId), objectGroup: 'console'});
-    const error = response[Protocol.Error];
-    if (error) {
-      console.error(error);
-      return {error: error};
-    }
-    return {objects: this.createRemoteObject(response.objects)};
-  }
-
-  /**
-   * @return {!Promise<string>}
-   */
-  async isolateId() {
-    return (await this._agent.getIsolateId()) || this.target().id();
-  }
-
-  /**
-   * @return {!Promise<?{usedSize: number, totalSize: number}>}
-   */
-  async heapUsage() {
-    const result = await this._agent.invoke_getHeapUsage({});
-    return result[Protocol.Error] ? null : result;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.RemoteObject} payload
-   * @param {!Object=} hints
-   */
-  _inspectRequested(payload, hints) {
-    const object = this.createRemoteObject(payload);
-
-    if (hints.copyToClipboard) {
-      this._copyRequested(object);
-      return;
-    }
-
-    if (hints.queryObjects) {
-      this._queryObjectsRequested(object);
-      return;
-    }
-
-    if (object.isNode()) {
-      Common.Revealer.reveal(object).then(object.release.bind(object));
-      return;
-    }
-
-    if (object.type === 'function') {
-      SDK.RemoteFunction.objectAsFunction(object).targetFunctionDetails().then(didGetDetails);
-      return;
-    }
-
-    /**
-     * @param {?SDK.DebuggerModel.FunctionDetails} response
-     */
-    function didGetDetails(response) {
-      object.release();
-      if (!response || !response.location)
-        return;
-      Common.Revealer.reveal(response.location);
-    }
-    object.release();
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  _copyRequested(object) {
-    if (!object.objectId) {
-      InspectorFrontendHost.copyText(object.unserializableValue() || object.value);
-      return;
-    }
-    object.callFunctionJSON(
-        toStringForClipboard, [{value: object.subtype}], InspectorFrontendHost.copyText.bind(InspectorFrontendHost));
-
-    /**
-     * @param {string} subtype
-     * @this {Object}
-     * @suppressReceiverCheck
-     */
-    function toStringForClipboard(subtype) {
-      if (subtype === 'node')
-        return this.outerHTML;
-      if (subtype && typeof this === 'undefined')
-        return subtype + '';
-      try {
-        return JSON.stringify(this, null, '  ');
-      } catch (e) {
-        return '' + this;
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} object
-   */
-  async _queryObjectsRequested(object) {
-    const result = await this.queryObjects(object);
-    object.release();
-    if (result.error) {
-      Common.console.error(result.error);
-      return;
-    }
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.QueryObjectRequested, {objects: result.objects});
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
-   * @return {string}
-   */
-  static simpleTextFromException(exceptionDetails) {
-    let text = exceptionDetails.text;
-    if (exceptionDetails.exception && exceptionDetails.exception.description) {
-      let description = exceptionDetails.exception.description;
-      if (description.indexOf('\n') !== -1)
-        description = description.substring(0, description.indexOf('\n'));
-      text += ' ' + description;
-    }
-    return text;
-  }
-
-  /**
-   * @param {number} timestamp
-   * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
-   */
-  exceptionThrown(timestamp, exceptionDetails) {
-    const exceptionWithTimestamp = {timestamp: timestamp, details: exceptionDetails};
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.ExceptionThrown, exceptionWithTimestamp);
-  }
-
-  /**
-   * @param {number} exceptionId
-   */
-  _exceptionRevoked(exceptionId) {
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.ExceptionRevoked, exceptionId);
-  }
-
-  /**
-   * @param {string} type
-   * @param {!Array.<!Protocol.Runtime.RemoteObject>} args
-   * @param {number} executionContextId
-   * @param {number} timestamp
-   * @param {!Protocol.Runtime.StackTrace=} stackTrace
-   * @param {string=} context
-   */
-  _consoleAPICalled(type, args, executionContextId, timestamp, stackTrace, context) {
-    const consoleAPICall = {
-      type: type,
-      args: args,
-      executionContextId: executionContextId,
-      timestamp: timestamp,
-      stackTrace: stackTrace,
-      context: context
-    };
-    this.dispatchEventToListeners(SDK.RuntimeModel.Events.ConsoleAPICalled, consoleAPICall);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @return {number}
-   */
-  executionContextIdForScriptId(scriptId) {
-    const script = this.debuggerModel().scriptForId(scriptId);
-    return script ? script.executionContextId : 0;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   * @return {number}
-   */
-  executionContextForStackTrace(stackTrace) {
-    while (stackTrace && !stackTrace.callFrames.length)
-      stackTrace = stackTrace.parent;
-    if (!stackTrace || !stackTrace.callFrames.length)
-      return 0;
-    return this.executionContextIdForScriptId(stackTrace.callFrames[0].scriptId);
-  }
-
-  /**
-   * @return {?boolean}
-   */
-  hasSideEffectSupport() {
-    return this._hasSideEffectSupport;
-  }
-
-  /**
-   * @return {!Promise<boolean>}
-   */
-  async checkSideEffectSupport() {
-    const testContext = this.executionContexts().peekLast();
-    if (!testContext)
-      return false;
-    // Check for a positive throwOnSideEffect response without triggering side effects.
-    const response = await this._agent.invoke_evaluate(
-        {expression: SDK.RuntimeModel._sideEffectTestExpression, contextId: testContext.id, throwOnSideEffect: true});
-
-    const exceptionDetails = !response[Protocol.Error] && response.exceptionDetails;
-    const supports =
-        !!(exceptionDetails && exceptionDetails.exception &&
-           exceptionDetails.exception.description.startsWith('EvalError: Possible side-effect in debug-evaluate'));
-    this._hasSideEffectSupport = supports;
-    return supports;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  terminateExecution() {
-    return this._agent.invoke_terminateExecution({});
-  }
-};
-
-SDK.SDKModel.register(SDK.RuntimeModel, SDK.Target.Capability.JS, true);
-
-/**
- * This expression:
- * - IMPORTANT: must not actually cause user-visible or JS-visible side-effects.
- * - Must throw when evaluated with `throwOnSideEffect: true`.
- * - Must be valid when run from any ExecutionContext that supports `throwOnSideEffect`.
- * @const
- * @type {string}
- */
-SDK.RuntimeModel._sideEffectTestExpression = '(async function(){ await 1; })()';
-
-/** @enum {symbol} */
-SDK.RuntimeModel.Events = {
-  ExecutionContextCreated: Symbol('ExecutionContextCreated'),
-  ExecutionContextDestroyed: Symbol('ExecutionContextDestroyed'),
-  ExecutionContextChanged: Symbol('ExecutionContextChanged'),
-  ExecutionContextOrderChanged: Symbol('ExecutionContextOrderChanged'),
-  ExceptionThrown: Symbol('ExceptionThrown'),
-  ExceptionRevoked: Symbol('ExceptionRevoked'),
-  ConsoleAPICalled: Symbol('ConsoleAPICalled'),
-  QueryObjectRequested: Symbol('QueryObjectRequested'),
-};
-
-/** @typedef {{timestamp: number, details: !Protocol.Runtime.ExceptionDetails}} */
-SDK.RuntimeModel.ExceptionWithTimestamp;
-
-/** @typedef {{
- *    scriptId: (Protocol.Runtime.ScriptId|undefined),
- *    exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined)
- *  }}
- */
-SDK.RuntimeModel.CompileScriptResult;
-
-/** @typedef {{
- *    expression: string,
- *    objectGroup: (string|undefined),
- *    includeCommandLineAPI: (boolean|undefined),
- *    silent: (boolean|undefined),
- *    returnByValue: (boolean|undefined),
- *    generatePreview: (boolean|undefined),
- *    throwOnSideEffect: (boolean|undefined)
- *  }}
- */
-SDK.RuntimeModel.EvaluationOptions;
-
-/** @typedef {{
- *    object: (!SDK.RemoteObject|undefined),
- *    exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined),
- *    error: (!Protocol.Error|undefined)}
- *  }}
- */
-SDK.RuntimeModel.EvaluationResult;
-
-/** @typedef {{
- *    objects: (!SDK.RemoteObject|undefined),
- *    error: (!Protocol.Error|undefined)}
- *  }}
- */
-SDK.RuntimeModel.QueryObjectResult;
-
-/**
- * @typedef {{
- *    type: string,
- *    args: !Array<!Protocol.Runtime.RemoteObject>,
- *    executionContextId: number,
- *    timestamp: number,
- *    stackTrace: (!Protocol.Runtime.StackTrace|undefined)
- * }}
- */
-SDK.RuntimeModel.ConsoleAPICall;
-
-/**
- * @implements {Protocol.RuntimeDispatcher}
- * @unrestricted
- */
-SDK.RuntimeDispatcher = class {
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   */
-  constructor(runtimeModel) {
-    this._runtimeModel = runtimeModel;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.ExecutionContextDescription} context
-   */
-  executionContextCreated(context) {
-    this._runtimeModel._executionContextCreated(context);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.ExecutionContextId} executionContextId
-   */
-  executionContextDestroyed(executionContextId) {
-    this._runtimeModel._executionContextDestroyed(executionContextId);
-  }
-
-  /**
-   * @override
-   */
-  executionContextsCleared() {
-    this._runtimeModel._executionContextsCleared();
-  }
-
-  /**
-   * @override
-   * @param {number} timestamp
-   * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
-   */
-  exceptionThrown(timestamp, exceptionDetails) {
-    this._runtimeModel.exceptionThrown(timestamp, exceptionDetails);
-  }
-
-  /**
-   * @override
-   * @param {string} reason
-   * @param {number} exceptionId
-   */
-  exceptionRevoked(reason, exceptionId) {
-    this._runtimeModel._exceptionRevoked(exceptionId);
-  }
-
-  /**
-   * @override
-   * @param {string} type
-   * @param {!Array.<!Protocol.Runtime.RemoteObject>} args
-   * @param {number} executionContextId
-   * @param {number} timestamp
-   * @param {!Protocol.Runtime.StackTrace=} stackTrace
-   * @param {string=} context
-   */
-  consoleAPICalled(type, args, executionContextId, timestamp, stackTrace, context) {
-    this._runtimeModel._consoleAPICalled(type, args, executionContextId, timestamp, stackTrace, context);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.RemoteObject} payload
-   * @param {!Object=} hints
-   */
-  inspectRequested(payload, hints) {
-    this._runtimeModel._inspectRequested(payload, hints);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.ExecutionContext = class {
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {number} id
-   * @param {string} name
-   * @param {string} origin
-   * @param {boolean} isDefault
-   * @param {string=} frameId
-   */
-  constructor(runtimeModel, id, name, origin, isDefault, frameId) {
-    this.id = id;
-    this.name = name;
-    this.origin = origin;
-    this.isDefault = isDefault;
-    this.runtimeModel = runtimeModel;
-    this.debuggerModel = runtimeModel.debuggerModel();
-    this.frameId = frameId;
-    this._setLabel('');
-  }
-
-  /**
-   * @return {!SDK.Target}
-   */
-  target() {
-    return this.runtimeModel.target();
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} a
-   * @param {!SDK.ExecutionContext} b
-   * @return {number}
-   */
-  static comparator(a, b) {
-    /**
-     * @param {!SDK.Target} target
-     * @return {number}
-     */
-    function targetWeight(target) {
-      if (!target.parentTarget())
-        return 4;
-      if (target.hasBrowserCapability())
-        return 3;
-      if (target.hasJSCapability())
-        return 2;
-      return 1;
-    }
-
-    const weightDiff = targetWeight(a.target()) - targetWeight(b.target());
-    if (weightDiff)
-      return -weightDiff;
-
-    // Main world context should always go first.
-    if (a.isDefault)
-      return -1;
-    if (b.isDefault)
-      return +1;
-    return a.name.localeCompare(b.name);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel.EvaluationOptions} options
-   * @param {boolean} userGesture
-   * @param {boolean} awaitPromise
-   * @return {!Promise<!SDK.RuntimeModel.EvaluationResult>}
-   */
-  evaluate(options, userGesture, awaitPromise) {
-    // FIXME: It will be moved to separate ExecutionContext.
-    if (this.debuggerModel.selectedCallFrame())
-      return this.debuggerModel.evaluateOnSelectedCallFrame(options);
-    if (!options.throwOnSideEffect || this.runtimeModel.hasSideEffectSupport())
-      return this._evaluateGlobal(options, userGesture, awaitPromise);
-
-    /** @type {!SDK.RuntimeModel.EvaluationResult} */
-    const unsupportedError = {error: 'Side-effect checks not supported by backend.'};
-    if (this.runtimeModel.hasSideEffectSupport() === false)
-      return Promise.resolve(unsupportedError);
-
-    return this.runtimeModel.checkSideEffectSupport().then(() => {
-      if (this.runtimeModel.hasSideEffectSupport())
-        return this._evaluateGlobal(options, userGesture, awaitPromise);
-      return Promise.resolve(unsupportedError);
-    });
-  }
-
-  /**
-   * @param {string} objectGroup
-   * @param {boolean} generatePreview
-   * @return {!Promise<!SDK.RuntimeModel.EvaluationResult>}
-   */
-  globalObject(objectGroup, generatePreview) {
-    return this._evaluateGlobal(
-        {
-          expression: 'this',
-          objectGroup: objectGroup,
-          includeCommandLineAPI: false,
-          silent: true,
-          returnByValue: false,
-          generatePreview: generatePreview
-        },
-        /* userGesture */ false, /* awaitPromise */ false);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel.EvaluationOptions} options
-   * @param {boolean} userGesture
-   * @param {boolean} awaitPromise
-   * @return {!Promise<!SDK.RuntimeModel.EvaluationResult>}
-   */
-  async _evaluateGlobal(options, userGesture, awaitPromise) {
-    if (!options.expression) {
-      // There is no expression, so the completion should happen against global properties.
-      options.expression = 'this';
-    }
-
-    const response = await this.runtimeModel._agent.invoke_evaluate({
-      expression: options.expression,
-      objectGroup: options.objectGroup,
-      includeCommandLineAPI: options.includeCommandLineAPI,
-      silent: options.silent,
-      contextId: this.id,
-      returnByValue: options.returnByValue,
-      generatePreview: options.generatePreview,
-      userGesture: userGesture,
-      awaitPromise: awaitPromise,
-      throwOnSideEffect: options.throwOnSideEffect
-    });
-
-    const error = response[Protocol.Error];
-    if (error) {
-      console.error(error);
-      return {error: error};
-    }
-    return {object: this.runtimeModel.createRemoteObject(response.result), exceptionDetails: response.exceptionDetails};
-  }
-
-  /**
-   * @return {!Promise<?Array<string>>}
-   */
-  async globalLexicalScopeNames() {
-    const response = await this.runtimeModel._agent.invoke_globalLexicalScopeNames({executionContextId: this.id});
-    return response[Protocol.Error] ? [] : response.names;
-  }
-
-  /**
-   * @return {string}
-   */
-  label() {
-    return this._label;
-  }
-
-  /**
-   * @param {string} label
-   */
-  setLabel(label) {
-    this._setLabel(label);
-    this.runtimeModel.dispatchEventToListeners(SDK.RuntimeModel.Events.ExecutionContextChanged, this);
-  }
-
-  /**
-   * @param {string} label
-   */
-  _setLabel(label) {
-    if (label) {
-      this._label = label;
-      return;
-    }
-    if (this.name) {
-      this._label = this.name;
-      return;
-    }
-    const parsedUrl = this.origin.asParsedURL();
-    this._label = parsedUrl ? parsedUrl.lastPathComponentWithFragment() : '';
-  }
-};
diff --git a/front_end/sdk/ScreenCaptureModel.js b/front_end/sdk/ScreenCaptureModel.js
deleted file mode 100644
index be05514..0000000
--- a/front_end/sdk/ScreenCaptureModel.js
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Protocol.PageDispatcher}
- */
-SDK.ScreenCaptureModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._agent = target.pageAgent();
-    /** @type {?function(string, !Protocol.Page.ScreencastFrameMetadata)} */
-    this._onScreencastFrame = null;
-    /** @type {?function(boolean)} */
-    this._onScreencastVisibilityChanged = null;
-    target.registerPageDispatcher(this);
-  }
-
-  /**
-   * @param {string} format
-   * @param {number} quality
-   * @param {number|undefined} width
-   * @param {number|undefined} height
-   * @param {number|undefined} everyNthFrame
-   * @param {function(string, !Protocol.Page.ScreencastFrameMetadata)} onFrame
-   * @param {function(boolean)} onVisibilityChanged
-   */
-  startScreencast(format, quality, width, height, everyNthFrame, onFrame, onVisibilityChanged) {
-    this._onScreencastFrame = onFrame;
-    this._onScreencastVisibilityChanged = onVisibilityChanged;
-    this._agent.startScreencast(format, quality, width, height, everyNthFrame);
-  }
-
-  stopScreencast() {
-    this._onScreencastFrame = null;
-    this._onScreencastVisibilityChanged = null;
-    this._agent.stopScreencast();
-  }
-
-  /**
-   * @param {string} format
-   * @param {number} quality
-   * @param {!Protocol.Page.Viewport=} clip
-   * @return {!Promise<?string>}
-   */
-  captureScreenshot(format, quality, clip) {
-    return this._agent.captureScreenshot(format, quality, clip, true);
-  }
-
-  /**
-   * @return {!Promise<?{viewportX: number, viewportY: number, viewportScale: number, contentWidth: number, contentHeight: number}>}
-   */
-  async fetchLayoutMetrics() {
-    const response = await this._agent.invoke_getLayoutMetrics({});
-    if (response[Protocol.Error])
-      return null;
-    return {
-      viewportX: response.visualViewport.pageX,
-      viewportY: response.visualViewport.pageY,
-      viewportScale: response.visualViewport.scale,
-      contentWidth: response.contentSize.width,
-      contentHeight: response.contentSize.height
-    };
-  }
-
-  /**
-   * @override
-   * @param {string} data
-   * @param {!Protocol.Page.ScreencastFrameMetadata} metadata
-   * @param {number} sessionId
-   */
-  screencastFrame(data, metadata, sessionId) {
-    this._agent.screencastFrameAck(sessionId);
-    if (this._onScreencastFrame)
-      this._onScreencastFrame.call(null, data, metadata);
-  }
-
-  /**
-   * @override
-   * @param {boolean} visible
-   */
-  screencastVisibilityChanged(visible) {
-    if (this._onScreencastVisibilityChanged)
-      this._onScreencastVisibilityChanged.call(null, visible);
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   */
-  domContentEventFired(time) {
-  }
-
-  /**
-   * @override
-   * @param {number} time
-   */
-  loadEventFired(time) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Network.LoaderId} loaderId
-   * @param {string} name
-   * @param {number} time
-   */
-  lifecycleEvent(frameId, loaderId, name, time) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {string} url
-   */
-  navigatedWithinDocument(frameId, url) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {!Protocol.Page.FrameId} parentFrameId
-   */
-  frameAttached(frameId, parentFrameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.Frame} frame
-   */
-  frameNavigated(frame) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameDetached(frameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameStartedLoading(frameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameStoppedLoading(frameId) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   * @param {number} delay
-   */
-  frameScheduledNavigation(frameId, delay) {
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Page.FrameId} frameId
-   */
-  frameClearedScheduledNavigation(frameId) {
-  }
-
-  /**
-   * @override
-   */
-  frameResized() {
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} message
-   * @param {string} dialogType
-   * @param {boolean} hasBrowserHandler
-   * @param {string=} prompt
-   */
-  javascriptDialogOpening(url, message, dialogType, hasBrowserHandler, prompt) {
-  }
-
-  /**
-   * @override
-   * @param {boolean} result
-   * @param {string} userInput
-   */
-  javascriptDialogClosed(result, userInput) {
-  }
-
-  /**
-   * @override
-   */
-  interstitialShown() {
-  }
-
-  /**
-   * @override
-   */
-  interstitialHidden() {
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} windowName
-   * @param {!Array<string>} windowFeatures
-   * @param {boolean} userGesture
-   */
-  windowOpen(url, windowName, windowFeatures, userGesture) {
-  }
-};
-
-SDK.SDKModel.register(SDK.ScreenCaptureModel, SDK.Target.Capability.ScreenCapture, false);
diff --git a/front_end/sdk/Script.js b/front_end/sdk/Script.js
deleted file mode 100644
index 7a2a822..0000000
--- a/front_end/sdk/Script.js
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-SDK.Script = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {string} scriptId
-   * @param {string} sourceURL
-   * @param {number} startLine
-   * @param {number} startColumn
-   * @param {number} endLine
-   * @param {number} endColumn
-   * @param {!Protocol.Runtime.ExecutionContextId} executionContextId
-   * @param {string} hash
-   * @param {boolean} isContentScript
-   * @param {boolean} isLiveEdit
-   * @param {string|undefined} sourceMapURL
-   * @param {boolean} hasSourceURL
-   * @param {number} length
-   */
-  constructor(
-      debuggerModel, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
-      isContentScript, isLiveEdit, sourceMapURL, hasSourceURL, length) {
-    this.debuggerModel = debuggerModel;
-    this.scriptId = scriptId;
-    this.sourceURL = sourceURL;
-    this.lineOffset = startLine;
-    this.columnOffset = startColumn;
-    this.endLine = endLine;
-    this.endColumn = endColumn;
-
-    this.executionContextId = executionContextId;
-    this.hash = hash;
-    this._isContentScript = isContentScript;
-    this._isLiveEdit = isLiveEdit;
-    this.sourceMapURL = sourceMapURL;
-    this.hasSourceURL = hasSourceURL;
-    this.contentLength = length;
-    this._originalContentProvider = null;
-    this._originalSource = null;
-  }
-
-  /**
-   * @param {string} source
-   * @return {string}
-   */
-  static _trimSourceURLComment(source) {
-    let sourceURLIndex = source.lastIndexOf('//# sourceURL=');
-    if (sourceURLIndex === -1) {
-      sourceURLIndex = source.lastIndexOf('//@ sourceURL=');
-      if (sourceURLIndex === -1)
-        return source;
-    }
-    const sourceURLLineIndex = source.lastIndexOf('\n', sourceURLIndex);
-    if (sourceURLLineIndex === -1)
-      return source;
-    const sourceURLLine = source.substr(sourceURLLineIndex + 1).split('\n', 1)[0];
-    if (sourceURLLine.search(SDK.Script.sourceURLRegex) === -1)
-      return source;
-    return source.substr(0, sourceURLLineIndex) + source.substr(sourceURLLineIndex + sourceURLLine.length + 1);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isContentScript() {
-    return this._isContentScript;
-  }
-
-  /**
-   * @return {?SDK.ExecutionContext}
-   */
-  executionContext() {
-    return this.debuggerModel.runtimeModel().executionContext(this.executionContextId);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isLiveEdit() {
-    return this._isLiveEdit;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this.sourceURL;
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return Common.resourceTypes.Script;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  async requestContent() {
-    if (this._source)
-      return this._source;
-    if (!this.scriptId)
-      return '';
-    const source = await this.debuggerModel.target().debuggerAgent().getScriptSource(this.scriptId);
-    this._source = source ? SDK.Script._trimSourceURLComment(source) : '';
-    if (this._originalSource === null)
-      this._originalSource = this._source;
-    return this._source;
-  }
-
-  /**
-   * @return {!Common.ContentProvider}
-   */
-  originalContentProvider() {
-    if (!this._originalContentProvider) {
-      const lazyContent = () => this.requestContent().then(() => this._originalSource);
-      this._originalContentProvider =
-          new Common.StaticContentProvider(this.contentURL(), this.contentType(), lazyContent);
-    }
-    return this._originalContentProvider;
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  async searchInContent(query, caseSensitive, isRegex) {
-    if (!this.scriptId)
-      return [];
-
-    const matches =
-        await this.debuggerModel.target().debuggerAgent().searchInContent(this.scriptId, query, caseSensitive, isRegex);
-    return (matches || []).map(match => new Common.ContentProvider.SearchMatch(match.lineNumber, match.lineContent));
-  }
-
-  /**
-   * @param {string} source
-   * @return {string}
-   */
-  _appendSourceURLCommentIfNeeded(source) {
-    if (!this.hasSourceURL)
-      return source;
-    return source + '\n //# sourceURL=' + this.sourceURL;
-  }
-
-  /**
-   * @param {string} newSource
-   * @param {function(?Protocol.Error, !Protocol.Runtime.ExceptionDetails=, !Array.<!Protocol.Debugger.CallFrame>=, !Protocol.Runtime.StackTrace=, !Protocol.Runtime.StackTraceId=, boolean=)} callback
-   */
-  async editSource(newSource, callback) {
-    newSource = SDK.Script._trimSourceURLComment(newSource);
-    // We append correct sourceURL to script for consistency only. It's not actually needed for things to work correctly.
-    newSource = this._appendSourceURLCommentIfNeeded(newSource);
-
-    if (!this.scriptId) {
-      callback('Script failed to parse');
-      return;
-    }
-
-    await this.requestContent();
-    if (this._source === newSource) {
-      callback(null);
-      return;
-    }
-    const response = await this.debuggerModel.target().debuggerAgent().invoke_setScriptSource(
-        {scriptId: this.scriptId, scriptSource: newSource});
-
-    if (!response[Protocol.Error] && !response.exceptionDetails)
-      this._source = newSource;
-
-    const needsStepIn = !!response.stackChanged;
-    callback(
-        response[Protocol.Error], response.exceptionDetails, response.callFrames, response.asyncStackTrace,
-        response.asyncStackTraceId, needsStepIn);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!SDK.DebuggerModel.Location}
-   */
-  rawLocation(lineNumber, columnNumber) {
-    return new SDK.DebuggerModel.Location(this.debuggerModel, this.scriptId, lineNumber, columnNumber || 0);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInlineScript() {
-    const startsAtZero = !this.lineOffset && !this.columnOffset;
-    return !!this.sourceURL && !startsAtZero;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isAnonymousScript() {
-    return !this.sourceURL;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInlineScriptWithSourceURL() {
-    return !!this.hasSourceURL && this.isInlineScript();
-  }
-
-  /**
-   * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions
-   * @return {!Promise<boolean>}
-   */
-  async setBlackboxedRanges(positions) {
-    const response = await this.debuggerModel.target().debuggerAgent().invoke_setBlackboxedRanges(
-        {scriptId: this.scriptId, positions});
-    const error = response[Protocol.Error];
-    if (error)
-      console.error(error);
-    return !error;
-  }
-};
-
-SDK.Script.sourceURLRegex = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
diff --git a/front_end/sdk/SecurityOriginManager.js b/front_end/sdk/SecurityOriginManager.js
deleted file mode 100644
index 5efa347..0000000
--- a/front_end/sdk/SecurityOriginManager.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.SecurityOriginManager = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-
-    /** @type {!Set<string>} */
-    this._securityOrigins = new Set();
-    this._mainSecurityOrigin = '';
-  }
-
-  /**
-   * @param {!Set<string>} securityOrigins
-   */
-  updateSecurityOrigins(securityOrigins) {
-    const oldOrigins = this._securityOrigins;
-    this._securityOrigins = securityOrigins;
-
-    for (const origin of oldOrigins) {
-      if (!this._securityOrigins.has(origin))
-        this.dispatchEventToListeners(SDK.SecurityOriginManager.Events.SecurityOriginRemoved, origin);
-    }
-
-    for (const origin of this._securityOrigins) {
-      if (!oldOrigins.has(origin))
-        this.dispatchEventToListeners(SDK.SecurityOriginManager.Events.SecurityOriginAdded, origin);
-    }
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  securityOrigins() {
-    return this._securityOrigins.valuesArray();
-  }
-
-  /**
-   * @return {string}
-   */
-  mainSecurityOrigin() {
-    return this._mainSecurityOrigin;
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  setMainSecurityOrigin(securityOrigin) {
-    this._mainSecurityOrigin = securityOrigin;
-    this.dispatchEventToListeners(SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, securityOrigin);
-  }
-};
-
-SDK.SDKModel.register(SDK.SecurityOriginManager, SDK.Target.Capability.None, false);
-
-/** @enum {symbol} */
-SDK.SecurityOriginManager.Events = {
-  SecurityOriginAdded: Symbol('SecurityOriginAdded'),
-  SecurityOriginRemoved: Symbol('SecurityOriginRemoved'),
-  MainSecurityOriginChanged: Symbol('MainSecurityOriginChanged')
-};
diff --git a/front_end/sdk/ServerTiming.js b/front_end/sdk/ServerTiming.js
deleted file mode 100644
index 8a8a12f..0000000
--- a/front_end/sdk/ServerTiming.js
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SDK.ServerTiming = class {
-  /**
-   * @param {string} metric
-   * @param {?number} value
-   * @param {?string} description
-   */
-  constructor(metric, value, description) {
-    this.metric = metric;
-    this.value = value;
-    this.description = description;
-  }
-
-  /**
-   * @param {!Array<!SDK.NetworkRequest.NameValue>} headers
-   * @return {?Array<!SDK.ServerTiming>}
-   */
-  static parseHeaders(headers) {
-    const rawServerTimingHeaders = headers.filter(item => item.name.toLowerCase() === 'server-timing');
-    if (!rawServerTimingHeaders.length)
-      return null;
-
-    const serverTimings = rawServerTimingHeaders.reduce((memo, header) => {
-      const timing = this.createFromHeaderValue(header.value);
-      memo.pushAll(timing.map(function(entry) {
-        return new SDK.ServerTiming(
-            entry.name, entry.hasOwnProperty('dur') ? entry.dur : null, entry.hasOwnProperty('desc') ? entry.desc : '');
-      }));
-      return memo;
-    }, []);
-    serverTimings.sort((a, b) => a.metric.toLowerCase().compareTo(b.metric.toLowerCase()));
-    return serverTimings;
-  }
-
-  /**
-   * @param {string} valueString
-   * @return {?Array<!Object>}
-   */
-  static createFromHeaderValue(valueString) {
-    function trimLeadingWhiteSpace() {
-      valueString = valueString.replace(/^\s*/, '');
-    }
-    function consumeDelimiter(char) {
-      console.assert(char.length === 1);
-      trimLeadingWhiteSpace();
-      if (valueString.charAt(0) !== char)
-        return false;
-
-      valueString = valueString.substring(1);
-      return true;
-    }
-    function consumeToken() {
-      // https://tools.ietf.org/html/rfc7230#appendix-B
-      const result = /^(?:\s*)([\w!#$%&'*+\-.^`|~]+)(?:\s*)(.*)/.exec(valueString);
-      if (!result)
-        return null;
-
-      valueString = result[2];
-      return result[1];
-    }
-    function consumeTokenOrQuotedString() {
-      trimLeadingWhiteSpace();
-      if (valueString.charAt(0) === '"')
-        return consumeQuotedString();
-
-      return consumeToken();
-    }
-    function consumeQuotedString() {
-      console.assert(valueString.charAt(0) === '"');
-      valueString = valueString.substring(1);  // remove leading DQUOTE
-
-      let value = '';
-      while (valueString.length) {
-        // split into two parts:
-        //  -everything before the first " or \
-        //  -everything else
-        const result = /^([^"\\]*)(.*)/.exec(valueString);
-        value += result[1];
-        if (result[2].charAt(0) === '"') {
-          // we have found our closing "
-          valueString = result[2].substring(1);  // strip off everything after the closing "
-          return value;                          // we are done here
-        }
-
-        console.assert(result[2].charAt(0) === '\\');
-        // special rules for \ found in quoted-string (https://tools.ietf.org/html/rfc7230#section-3.2.6)
-        value += result[2].charAt(1);          // grab the character AFTER the \ (if there was one)
-        valueString = result[2].substring(2);  // strip off \ and next character
-      }
-
-      return null;  // not a valid quoted-string
-    }
-    function consumeExtraneous() {
-      const result = /([,;].*)/.exec(valueString);
-      if (result)
-        valueString = result[1];
-    }
-
-    const result = [];
-    let name;
-    while ((name = consumeToken()) !== null) {
-      const entry = {name};
-
-      if (valueString.charAt(0) === '=')
-        this.showWarning(ls`Deprecated syntax found. Please use: <name>;dur=<duration>;desc=<description>`);
-
-      while (consumeDelimiter(';')) {
-        let paramName;
-        if ((paramName = consumeToken()) === null)
-          continue;
-
-        paramName = paramName.toLowerCase();
-        const parseParameter = this.getParserForParameter(paramName);
-        let paramValue = null;
-        if (consumeDelimiter('=')) {
-          // always parse the value, even if we don't recognize the parameter name
-          paramValue = consumeTokenOrQuotedString();
-          consumeExtraneous();
-        }
-
-        if (parseParameter) {
-          // paramName is valid
-          if (entry.hasOwnProperty(paramName)) {
-            this.showWarning(ls`Duplicate parameter \"${paramName}\" ignored.`);
-            continue;
-          }
-
-          if (paramValue === null)
-            this.showWarning(ls`No value found for parameter \"${paramName}\".`);
-
-          parseParameter.call(this, entry, paramValue);
-        } else {
-          // paramName is not valid
-          this.showWarning(ls`Unrecognized parameter \"${paramName}\".`);
-        }
-      }
-
-      result.push(entry);
-      if (!consumeDelimiter(','))
-        break;
-    }
-
-    if (valueString.length)
-      this.showWarning(ls`Extraneous trailing characters.`);
-    return result;
-  }
-
-  /**
-   * @param {string} paramName
-   * @return {?function(!Object, string)}
-   */
-  static getParserForParameter(paramName) {
-    switch (paramName) {
-      case 'dur':
-        return function(entry, paramValue) {
-          entry.dur = 0;
-          if (paramValue !== null) {
-            const duration = parseFloat(paramValue);
-            if (isNaN(duration)) {
-              this.showWarning(ls`Unable to parse \"${paramName}\" value \"${paramValue}\".`);
-              return;
-            }
-            entry.dur = duration;
-          }
-        };
-
-      case 'desc':
-        return function(entry, paramValue) {
-          entry.desc = paramValue || '';
-        };
-
-      default:
-        return null;
-    }
-  }
-
-  /**
-   * @param {string} msg
-   */
-  static showWarning(msg) {
-    Common.console.warn(Common.UIString(`ServerTiming: ${msg}`));
-  }
-};
diff --git a/front_end/sdk/ServiceWorkerCacheModel.js b/front_end/sdk/ServiceWorkerCacheModel.js
deleted file mode 100644
index 2c502a2..0000000
--- a/front_end/sdk/ServiceWorkerCacheModel.js
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Protocol.StorageDispatcher}
- * @unrestricted
- */
-SDK.ServiceWorkerCacheModel = class extends SDK.SDKModel {
-  /**
-   * Invariant: This model can only be constructed on a ServiceWorker target.
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    target.registerStorageDispatcher(this);
-
-    /** @type {!Map<string, !SDK.ServiceWorkerCacheModel.Cache>} */
-    this._caches = new Map();
-
-    this._cacheAgent = target.cacheStorageAgent();
-    this._storageAgent = target.storageAgent();
-
-    this._securityOriginManager = target.model(SDK.SecurityOriginManager);
-
-    this._originsUpdated = new Set();
-    this._throttler = new Common.Throttler(2000);
-
-    /** @type {boolean} */
-    this._enabled = false;
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-
-    this._securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._securityOriginAdded, this);
-    this._securityOriginManager.addEventListener(
-        SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this);
-
-    for (const securityOrigin of this._securityOriginManager.securityOrigins())
-      this._addOrigin(securityOrigin);
-    this._enabled = true;
-  }
-
-  /**
-   * @param {string} origin
-   */
-  clearForOrigin(origin) {
-    this._removeOrigin(origin);
-    this._addOrigin(origin);
-  }
-
-  refreshCacheNames() {
-    for (const cache of this._caches.values())
-      this._cacheRemoved(cache);
-    this._caches.clear();
-    const securityOrigins = this._securityOriginManager.securityOrigins();
-    for (const securityOrigin of securityOrigins)
-      this._loadCacheNames(securityOrigin);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  async deleteCache(cache) {
-    const response = await this._cacheAgent.invoke_deleteCache({cacheId: cache.cacheId});
-    if (response[Protocol.Error]) {
-      console.error(`ServiceWorkerCacheAgent error deleting cache ${cache.toString()}: ${response[Protocol.Error]}`);
-      return;
-    }
-    this._caches.delete(cache.cacheId);
-    this._cacheRemoved(cache);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   * @param {string} request
-   * @return {!Promise}
-   */
-  async deleteCacheEntry(cache, request) {
-    const response = await this._cacheAgent.invoke_deleteEntry({cacheId: cache.cacheId, request});
-    if (!response[Protocol.Error])
-      return;
-    Common.console.error(Common.UIString(
-        'ServiceWorkerCacheAgent error deleting cache entry %s in cache: %s', cache.toString(),
-        response[Protocol.Error]));
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   * @param {number} skipCount
-   * @param {number} pageSize
-   * @param {function(!Array.<!Protocol.CacheStorage.DataEntry>, boolean)} callback
-   */
-  loadCacheData(cache, skipCount, pageSize, callback) {
-    this._requestEntries(cache, skipCount, pageSize, callback);
-  }
-
-  /**
-   * @return {!Array.<!SDK.ServiceWorkerCacheModel.Cache>}
-   */
-  caches() {
-    const caches = new Array();
-    for (const cache of this._caches.values())
-      caches.push(cache);
-    return caches;
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    for (const cache of this._caches.values())
-      this._cacheRemoved(cache);
-    this._caches.clear();
-    if (this._enabled) {
-      this._securityOriginManager.removeEventListener(
-          SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._securityOriginAdded, this);
-      this._securityOriginManager.removeEventListener(
-          SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this);
-    }
-  }
-
-  _addOrigin(securityOrigin) {
-    this._loadCacheNames(securityOrigin);
-    if (this._isValidSecurityOrigin(securityOrigin))
-      this._storageAgent.trackCacheStorageForOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  _removeOrigin(securityOrigin) {
-    for (const opaqueId of this._caches.keys()) {
-      const cache = this._caches.get(opaqueId);
-      if (cache.securityOrigin === securityOrigin) {
-        this._caches.delete(opaqueId);
-        this._cacheRemoved(cache);
-      }
-    }
-    if (this._isValidSecurityOrigin(securityOrigin))
-      this._storageAgent.untrackCacheStorageForOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @return {boolean}
-   */
-  _isValidSecurityOrigin(securityOrigin) {
-    const parsedURL = securityOrigin.asParsedURL();
-    return !!parsedURL && parsedURL.scheme.startsWith('http');
-  }
-
-  /**
-   * @param {string} securityOrigin
-   */
-  async _loadCacheNames(securityOrigin) {
-    const caches = await this._cacheAgent.requestCacheNames(securityOrigin);
-    if (!caches)
-      return;
-    this._updateCacheNames(securityOrigin, caches);
-  }
-
-  /**
-   * @param {string} securityOrigin
-   * @param {!Array} cachesJson
-   */
-  _updateCacheNames(securityOrigin, cachesJson) {
-    /**
-     * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-     * @this {SDK.ServiceWorkerCacheModel}
-     */
-    function deleteAndSaveOldCaches(cache) {
-      if (cache.securityOrigin === securityOrigin && !updatingCachesIds.has(cache.cacheId)) {
-        oldCaches.set(cache.cacheId, cache);
-        this._caches.delete(cache.cacheId);
-      }
-    }
-
-    /** @type {!Set<string>} */
-    const updatingCachesIds = new Set();
-    /** @type {!Map<string, !SDK.ServiceWorkerCacheModel.Cache>} */
-    const newCaches = new Map();
-    /** @type {!Map<string, !SDK.ServiceWorkerCacheModel.Cache>} */
-    const oldCaches = new Map();
-
-    for (const cacheJson of cachesJson) {
-      const cache =
-          new SDK.ServiceWorkerCacheModel.Cache(this, cacheJson.securityOrigin, cacheJson.cacheName, cacheJson.cacheId);
-      updatingCachesIds.add(cache.cacheId);
-      if (this._caches.has(cache.cacheId))
-        continue;
-      newCaches.set(cache.cacheId, cache);
-      this._caches.set(cache.cacheId, cache);
-    }
-    this._caches.forEach(deleteAndSaveOldCaches, this);
-    newCaches.forEach(this._cacheAdded, this);
-    oldCaches.forEach(this._cacheRemoved, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _securityOriginAdded(event) {
-    const securityOrigin = /** @type {string} */ (event.data);
-    this._addOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _securityOriginRemoved(event) {
-    const securityOrigin = /** @type {string} */ (event.data);
-    this._removeOrigin(securityOrigin);
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  _cacheAdded(cache) {
-    this.dispatchEventToListeners(SDK.ServiceWorkerCacheModel.Events.CacheAdded, {model: this, cache: cache});
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   */
-  _cacheRemoved(cache) {
-    this.dispatchEventToListeners(SDK.ServiceWorkerCacheModel.Events.CacheRemoved, {model: this, cache: cache});
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   * @param {number} skipCount
-   * @param {number} pageSize
-   * @param {function(!Array<!Protocol.CacheStorage.DataEntry>, boolean)} callback
-   */
-  async _requestEntries(cache, skipCount, pageSize, callback) {
-    const response = await this._cacheAgent.invoke_requestEntries({cacheId: cache.cacheId, skipCount, pageSize});
-    if (response[Protocol.Error]) {
-      console.error('ServiceWorkerCacheAgent error while requesting entries: ', response[Protocol.Error]);
-      return;
-    }
-    callback(response.cacheDataEntries, response.hasMore);
-  }
-
-  /**
-   * @param {string} origin
-   * @override
-   */
-  cacheStorageListUpdated(origin) {
-    this._originsUpdated.add(origin);
-
-    this._throttler.schedule(() => {
-      const promises = Array.from(this._originsUpdated, origin => this._loadCacheNames(origin));
-      this._originsUpdated.clear();
-      return Promise.all(promises);
-    });
-  }
-
-  /**
-   * @param {string} origin
-   * @param {string} cacheName
-   * @override
-   */
-  cacheStorageContentUpdated(origin, cacheName) {
-    this.dispatchEventToListeners(
-        SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated, {origin: origin, cacheName: cacheName});
-  }
-
-  /**
-   * @param {string} origin
-   * @override
-   */
-  indexedDBListUpdated(origin) {
-  }
-
-  /**
-   * @param {string} origin
-   * @param {string} databaseName
-   * @param {string} objectStoreName
-   * @override
-   */
-  indexedDBContentUpdated(origin, databaseName, objectStoreName) {
-  }
-};
-
-SDK.SDKModel.register(SDK.ServiceWorkerCacheModel, SDK.Target.Capability.Browser, false);
-
-/** @enum {symbol} */
-SDK.ServiceWorkerCacheModel.Events = {
-  CacheAdded: Symbol('CacheAdded'),
-  CacheRemoved: Symbol('CacheRemoved'),
-  CacheStorageContentUpdated: Symbol('CacheStorageContentUpdated')
-};
-
-/**
- * @unrestricted
- */
-SDK.ServiceWorkerCacheModel.Cache = class {
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel} model
-   * @param {string} securityOrigin
-   * @param {string} cacheName
-   * @param {string} cacheId
-   */
-  constructor(model, securityOrigin, cacheName, cacheId) {
-    this._model = model;
-    this.securityOrigin = securityOrigin;
-    this.cacheName = cacheName;
-    this.cacheId = cacheId;
-  }
-
-  /**
-   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
-   * @return {boolean}
-   */
-  equals(cache) {
-    return this.cacheId === cache.cacheId;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return this.securityOrigin + this.cacheName;
-  }
-
-  /**
-   * @param {string} url
-   * @return {!Promise<?Protocol.CacheStorage.CachedResponse>}
-   */
-  requestCachedResponse(url) {
-    return this._model._cacheAgent.requestCachedResponse(this.cacheId, url);
-  }
-};
diff --git a/front_end/sdk/ServiceWorkerManager.js b/front_end/sdk/ServiceWorkerManager.js
deleted file mode 100644
index bbe4f76..0000000
--- a/front_end/sdk/ServiceWorkerManager.js
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.ServiceWorkerManager = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    target.registerServiceWorkerDispatcher(new SDK.ServiceWorkerDispatcher(this));
-    this._lastAnonymousTargetId = 0;
-    this._agent = target.serviceWorkerAgent();
-    /** @type {!Map.<string, !SDK.ServiceWorkerRegistration>} */
-    this._registrations = new Map();
-    this.enable();
-    this._forceUpdateSetting = Common.settings.createSetting('serviceWorkerUpdateOnReload', false);
-    if (this._forceUpdateSetting.get())
-      this._forceUpdateSettingChanged();
-    this._forceUpdateSetting.addChangeListener(this._forceUpdateSettingChanged, this);
-    new SDK.ServiceWorkerContextNamer(target, this);
-  }
-
-  enable() {
-    if (this._enabled)
-      return;
-    this._enabled = true;
-    this._agent.enable();
-  }
-
-  disable() {
-    if (!this._enabled)
-      return;
-    this._enabled = false;
-    this._registrations.clear();
-    this._agent.disable();
-  }
-
-  /**
-   * @return {!Map.<string, !SDK.ServiceWorkerRegistration>}
-   */
-  registrations() {
-    return this._registrations;
-  }
-
-  /**
-   * @param {string} versionId
-   * @return {?SDK.ServiceWorkerVersion}
-   */
-  findVersion(versionId) {
-    for (const registration of this.registrations().values()) {
-      const version = registration.versions.get(versionId);
-      if (version)
-        return version;
-    }
-    return null;
-  }
-
-  /**
-   * @param {string} registrationId
-   */
-  deleteRegistration(registrationId) {
-    const registration = this._registrations.get(registrationId);
-    if (!registration)
-      return;
-    if (registration._isRedundant()) {
-      this._registrations.delete(registrationId);
-      this.dispatchEventToListeners(SDK.ServiceWorkerManager.Events.RegistrationDeleted, registration);
-      return;
-    }
-    registration._deleting = true;
-    for (const version of registration.versions.values())
-      this.stopWorker(version.id);
-    this._unregister(registration.scopeURL);
-  }
-
-  /**
-   * @param {string} registrationId
-   */
-  updateRegistration(registrationId) {
-    const registration = this._registrations.get(registrationId);
-    if (!registration)
-      return;
-    this._agent.updateRegistration(registration.scopeURL);
-  }
-
-  /**
-   * @param {string} registrationId
-   * @param {string} data
-   */
-  deliverPushMessage(registrationId, data) {
-    const registration = this._registrations.get(registrationId);
-    if (!registration)
-      return;
-    const origin = Common.ParsedURL.extractOrigin(registration.scopeURL);
-    this._agent.deliverPushMessage(origin, registrationId, data);
-  }
-
-  /**
-   * @param {string} registrationId
-   * @param {string} tag
-   * @param {boolean} lastChance
-   */
-  dispatchSyncEvent(registrationId, tag, lastChance) {
-    const registration = this._registrations.get(registrationId);
-    if (!registration)
-      return;
-    const origin = Common.ParsedURL.extractOrigin(registration.scopeURL);
-    this._agent.dispatchSyncEvent(origin, registrationId, tag, lastChance);
-  }
-
-  /**
-   * @param {string} scope
-   */
-  _unregister(scope) {
-    this._agent.unregister(scope);
-  }
-
-  /**
-   * @param {string} scope
-   */
-  startWorker(scope) {
-    this._agent.startWorker(scope);
-  }
-
-  /**
-   * @param {string} scope
-   */
-  skipWaiting(scope) {
-    this._agent.skipWaiting(scope);
-  }
-
-  /**
-   * @param {string} versionId
-   */
-  stopWorker(versionId) {
-    this._agent.stopWorker(versionId);
-  }
-
-  /**
-   * @param {string} versionId
-   */
-  inspectWorker(versionId) {
-    this._agent.inspectWorker(versionId);
-  }
-
-  /**
-   * @param {!Array.<!Protocol.ServiceWorker.ServiceWorkerRegistration>} registrations
-   */
-  _workerRegistrationUpdated(registrations) {
-    for (const payload of registrations) {
-      let registration = this._registrations.get(payload.registrationId);
-      if (!registration) {
-        registration = new SDK.ServiceWorkerRegistration(payload);
-        this._registrations.set(payload.registrationId, registration);
-        this.dispatchEventToListeners(SDK.ServiceWorkerManager.Events.RegistrationUpdated, registration);
-        continue;
-      }
-      registration._update(payload);
-
-      if (registration._shouldBeRemoved()) {
-        this._registrations.delete(registration.id);
-        this.dispatchEventToListeners(SDK.ServiceWorkerManager.Events.RegistrationDeleted, registration);
-      } else {
-        this.dispatchEventToListeners(SDK.ServiceWorkerManager.Events.RegistrationUpdated, registration);
-      }
-    }
-  }
-
-  /**
-   * @param {!Array.<!Protocol.ServiceWorker.ServiceWorkerVersion>} versions
-   */
-  _workerVersionUpdated(versions) {
-    /** @type {!Set.<!SDK.ServiceWorkerRegistration>} */
-    const registrations = new Set();
-    for (const payload of versions) {
-      const registration = this._registrations.get(payload.registrationId);
-      if (!registration)
-        continue;
-      registration._updateVersion(payload);
-      registrations.add(registration);
-    }
-    for (const registration of registrations) {
-      if (registration._shouldBeRemoved()) {
-        this._registrations.delete(registration.id);
-        this.dispatchEventToListeners(SDK.ServiceWorkerManager.Events.RegistrationDeleted, registration);
-      } else {
-        this.dispatchEventToListeners(SDK.ServiceWorkerManager.Events.RegistrationUpdated, registration);
-      }
-    }
-  }
-
-  /**
-   * @param {!Protocol.ServiceWorker.ServiceWorkerErrorMessage} payload
-   */
-  _workerErrorReported(payload) {
-    const registration = this._registrations.get(payload.registrationId);
-    if (!registration)
-      return;
-    registration.errors.push(payload);
-    this.dispatchEventToListeners(
-        SDK.ServiceWorkerManager.Events.RegistrationErrorAdded, {registration: registration, error: payload});
-  }
-
-  /**
-   * @return {!Common.Setting}
-   */
-  forceUpdateOnReloadSetting() {
-    return this._forceUpdateSetting;
-  }
-
-  _forceUpdateSettingChanged() {
-    this._agent.setForceUpdateOnPageLoad(this._forceUpdateSetting.get());
-  }
-};
-
-SDK.SDKModel.register(SDK.ServiceWorkerManager, SDK.Target.Capability.Target | SDK.Target.Capability.Browser, true);
-
-/** @enum {symbol} */
-SDK.ServiceWorkerManager.Events = {
-  RegistrationUpdated: Symbol('RegistrationUpdated'),
-  RegistrationErrorAdded: Symbol('RegistrationErrorAdded'),
-  RegistrationDeleted: Symbol('RegistrationDeleted')
-};
-
-/**
- * @implements {Protocol.ServiceWorkerDispatcher}
- * @unrestricted
- */
-SDK.ServiceWorkerDispatcher = class {
-  /**
-   * @param {!SDK.ServiceWorkerManager} manager
-   */
-  constructor(manager) {
-    this._manager = manager;
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!Protocol.ServiceWorker.ServiceWorkerRegistration>} registrations
-   */
-  workerRegistrationUpdated(registrations) {
-    this._manager._workerRegistrationUpdated(registrations);
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!Protocol.ServiceWorker.ServiceWorkerVersion>} versions
-   */
-  workerVersionUpdated(versions) {
-    this._manager._workerVersionUpdated(versions);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.ServiceWorker.ServiceWorkerErrorMessage} errorMessage
-   */
-  workerErrorReported(errorMessage) {
-    this._manager._workerErrorReported(errorMessage);
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.ServiceWorkerVersion = class {
-  /**
-   * @param {!SDK.ServiceWorkerRegistration} registration
-   * @param {!Protocol.ServiceWorker.ServiceWorkerVersion} payload
-   */
-  constructor(registration, payload) {
-    this.registration = registration;
-    this._update(payload);
-  }
-
-  /**
-   * @param {!Protocol.ServiceWorker.ServiceWorkerVersion} payload
-   */
-  _update(payload) {
-    this.id = payload.versionId;
-    this.scriptURL = payload.scriptURL;
-    const parsedURL = new Common.ParsedURL(payload.scriptURL);
-    this.securityOrigin = parsedURL.securityOrigin();
-    this.runningStatus = payload.runningStatus;
-    this.status = payload.status;
-    this.scriptLastModified = payload.scriptLastModified;
-    this.scriptResponseTime = payload.scriptResponseTime;
-    this.controlledClients = [];
-    for (let i = 0; i < payload.controlledClients.length; ++i)
-      this.controlledClients.push(payload.controlledClients[i]);
-    this.targetId = payload.targetId || null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStartable() {
-    return !this.registration.isDeleted && this.isActivated() && this.isStopped();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStoppedAndRedundant() {
-    return this.runningStatus === Protocol.ServiceWorker.ServiceWorkerVersionRunningStatus.Stopped &&
-        this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.Redundant;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStopped() {
-    return this.runningStatus === Protocol.ServiceWorker.ServiceWorkerVersionRunningStatus.Stopped;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStarting() {
-    return this.runningStatus === Protocol.ServiceWorker.ServiceWorkerVersionRunningStatus.Starting;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRunning() {
-    return this.runningStatus === Protocol.ServiceWorker.ServiceWorkerVersionRunningStatus.Running;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isStopping() {
-    return this.runningStatus === Protocol.ServiceWorker.ServiceWorkerVersionRunningStatus.Stopping;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isNew() {
-    return this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.New;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInstalling() {
-    return this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.Installing;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInstalled() {
-    return this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.Installed;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isActivating() {
-    return this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.Activating;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isActivated() {
-    return this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.Activated;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRedundant() {
-    return this.status === Protocol.ServiceWorker.ServiceWorkerVersionStatus.Redundant;
-  }
-
-  /**
-   * @return {string}
-   */
-  mode() {
-    if (this.isNew() || this.isInstalling())
-      return SDK.ServiceWorkerVersion.Modes.Installing;
-    else if (this.isInstalled())
-      return SDK.ServiceWorkerVersion.Modes.Waiting;
-    else if (this.isActivating() || this.isActivated())
-      return SDK.ServiceWorkerVersion.Modes.Active;
-    return SDK.ServiceWorkerVersion.Modes.Redundant;
-  }
-};
-
-/**
- * @enum {string}
- */
-SDK.ServiceWorkerVersion.Modes = {
-  Installing: 'installing',
-  Waiting: 'waiting',
-  Active: 'active',
-  Redundant: 'redundant'
-};
-
-/**
- * @unrestricted
- */
-SDK.ServiceWorkerRegistration = class {
-  /**
-   * @param {!Protocol.ServiceWorker.ServiceWorkerRegistration} payload
-   */
-  constructor(payload) {
-    this._update(payload);
-    /** @type {!Map.<string, !SDK.ServiceWorkerVersion>} */
-    this.versions = new Map();
-    this._deleting = false;
-    /** @type {!Array<!Protocol.ServiceWorker.ServiceWorkerErrorMessage>} */
-    this.errors = [];
-  }
-
-  /**
-   * @param {!Protocol.ServiceWorker.ServiceWorkerRegistration} payload
-   */
-  _update(payload) {
-    this._fingerprint = Symbol('fingerprint');
-    this.id = payload.registrationId;
-    this.scopeURL = payload.scopeURL;
-    const parsedURL = new Common.ParsedURL(payload.scopeURL);
-    this.securityOrigin = parsedURL.securityOrigin();
-    this.isDeleted = payload.isDeleted;
-    this.forceUpdateOnPageLoad = payload.forceUpdateOnPageLoad;
-  }
-
-  /**
-   * @return {symbol}
-   */
-  fingerprint() {
-    return this._fingerprint;
-  }
-
-  /**
-   * @return {!Map<string, !SDK.ServiceWorkerVersion>}
-   */
-  versionsByMode() {
-    /** @type {!Map<string, !SDK.ServiceWorkerVersion>} */
-    const result = new Map();
-    for (const version of this.versions.values())
-      result.set(version.mode(), version);
-    return result;
-  }
-
-  /**
-   * @param {!Protocol.ServiceWorker.ServiceWorkerVersion} payload
-   * @return {!SDK.ServiceWorkerVersion}
-   */
-  _updateVersion(payload) {
-    this._fingerprint = Symbol('fingerprint');
-    let version = this.versions.get(payload.versionId);
-    if (!version) {
-      version = new SDK.ServiceWorkerVersion(this, payload);
-      this.versions.set(payload.versionId, version);
-      return version;
-    }
-    version._update(payload);
-    return version;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isRedundant() {
-    for (const version of this.versions.values()) {
-      if (!version.isStoppedAndRedundant())
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _shouldBeRemoved() {
-    return this._isRedundant() && (!this.errors.length || this._deleting);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canBeRemoved() {
-    return this.isDeleted || this._deleting;
-  }
-
-
-  clearErrors() {
-    this._fingerprint = Symbol('fingerprint');
-    this.errors = [];
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.ServiceWorkerContextNamer = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {!SDK.ServiceWorkerManager} serviceWorkerManager
-   */
-  constructor(target, serviceWorkerManager) {
-    this._target = target;
-    this._serviceWorkerManager = serviceWorkerManager;
-    /** @type {!Map<string, !SDK.ServiceWorkerVersion>} */
-    this._versionByTargetId = new Map();
-    serviceWorkerManager.addEventListener(
-        SDK.ServiceWorkerManager.Events.RegistrationUpdated, this._registrationsUpdated, this);
-    serviceWorkerManager.addEventListener(
-        SDK.ServiceWorkerManager.Events.RegistrationDeleted, this._registrationsUpdated, this);
-    SDK.targetManager.addModelListener(
-        SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this._executionContextCreated, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _registrationsUpdated(event) {
-    this._versionByTargetId.clear();
-    const registrations = this._serviceWorkerManager.registrations().valuesArray();
-    for (const registration of registrations) {
-      const versions = registration.versions.valuesArray();
-      for (const version of versions) {
-        if (version.targetId)
-          this._versionByTargetId.set(version.targetId, version);
-      }
-    }
-    this._updateAllContextLabels();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _executionContextCreated(event) {
-    const executionContext = /** @type {!SDK.ExecutionContext} */ (event.data);
-    const serviceWorkerTargetId = this._serviceWorkerTargetIdForWorker(executionContext.target());
-    if (!serviceWorkerTargetId)
-      return;
-    this._updateContextLabel(executionContext, this._versionByTargetId.get(serviceWorkerTargetId) || null);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @return {?string}
-   */
-  _serviceWorkerTargetIdForWorker(target) {
-    const parent = target.parentTarget();
-    if (!parent || parent.parentTarget() !== this._target)
-      return null;
-    return parent.id();
-  }
-
-  _updateAllContextLabels() {
-    for (const target of SDK.targetManager.targets()) {
-      const serviceWorkerTargetId = this._serviceWorkerTargetIdForWorker(target);
-      if (!serviceWorkerTargetId)
-        continue;
-      const version = this._versionByTargetId.get(serviceWorkerTargetId) || null;
-      const runtimeModel = target.model(SDK.RuntimeModel);
-      const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
-      for (const context of executionContexts)
-        this._updateContextLabel(context, version);
-    }
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} context
-   * @param {?SDK.ServiceWorkerVersion} version
-   */
-  _updateContextLabel(context, version) {
-    if (!version) {
-      context.setLabel('');
-      return;
-    }
-    const parsedUrl = context.origin.asParsedURL();
-    const label = parsedUrl ? parsedUrl.lastPathComponentWithFragment() : context.name;
-    context.setLabel(label + ' #' + version.id + ' (' + version.status + ')');
-  }
-};
diff --git a/front_end/sdk/SourceMap.js b/front_end/sdk/SourceMap.js
deleted file mode 100644
index 0cb8c58..0000000
--- a/front_end/sdk/SourceMap.js
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SDK.SourceMapV3 = class {
-  constructor() {
-    /** @type {number} */ this.version;
-    /** @type {string|undefined} */ this.file;
-    /** @type {!Array.<string>} */ this.sources;
-    /** @type {!Array.<!SDK.SourceMapV3.Section>|undefined} */ this.sections;
-    /** @type {string} */ this.mappings;
-    /** @type {string|undefined} */ this.sourceRoot;
-    /** @type {!Array.<string>|undefined} */ this.names;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.SourceMapV3.Section = class {
-  constructor() {
-    /** @type {!SDK.SourceMapV3} */ this.map;
-    /** @type {!SDK.SourceMapV3.Offset} */ this.offset;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.SourceMapV3.Offset = class {
-  constructor() {
-    /** @type {number} */ this.line;
-    /** @type {number} */ this.column;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.SourceMapEntry = class {
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string=} sourceURL
-   * @param {number=} sourceLineNumber
-   * @param {number=} sourceColumnNumber
-   * @param {string=} name
-   */
-  constructor(lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber, name) {
-    this.lineNumber = lineNumber;
-    this.columnNumber = columnNumber;
-    this.sourceURL = sourceURL;
-    this.sourceLineNumber = sourceLineNumber;
-    this.sourceColumnNumber = sourceColumnNumber;
-    this.name = name;
-  }
-
-  /**
-   * @param {!SDK.SourceMapEntry} entry1
-   * @param {!SDK.SourceMapEntry} entry2
-   * @return {number}
-   */
-  static compare(entry1, entry2) {
-    if (entry1.lineNumber !== entry2.lineNumber)
-      return entry1.lineNumber - entry2.lineNumber;
-    return entry1.columnNumber - entry2.columnNumber;
-  }
-};
-
-/**
- * @interface
- */
-SDK.SourceMap = function() {};
-
-SDK.SourceMap.prototype = {
-  /**
-   * @return {string}
-   */
-  compiledURL() {},
-
-  /**
-   * @return {string}
-   */
-  url() {},
-
-  /**
-   * @return {!Array<string>}
-   */
-  sourceURLs() {},
-
-  /**
-   * @param {string} sourceURL
-   * @param {!Common.ResourceType} contentType
-   * @return {!Common.ContentProvider}
-   */
-  sourceContentProvider(sourceURL, contentType) {},
-
-  /**
-   * @param {string} sourceURL
-   * @return {?string}
-   */
-  embeddedContentByURL(sourceURL) {},
-
-  /**
-   * @param {number} lineNumber in compiled resource
-   * @param {number} columnNumber in compiled resource
-   * @return {?SDK.SourceMapEntry}
-   */
-  findEntry(lineNumber, columnNumber) {},
-
-  /**
-   * @return {boolean}
-   */
-  editable() {},
-
-  /**
-   * @param {!Array<!TextUtils.TextRange>} ranges
-   * @param {!Array<string>} texts
-   * @return {!Promise<?SDK.SourceMap.EditResult>}
-   */
-  editCompiled(ranges, texts) {},
-};
-
-/**
- * @unrestricted
- */
-SDK.SourceMap.EditResult = class {
-  /**
-   * @param {!SDK.SourceMap} map
-   * @param {!Array<!TextUtils.SourceEdit>} compiledEdits
-   * @param {!Map<string, string>} newSources
-   */
-  constructor(map, compiledEdits, newSources) {
-    this.map = map;
-    this.compiledEdits = compiledEdits;
-    this.newSources = newSources;
-  }
-};
-
-/**
- * @interface
- */
-SDK.SourceMapFactory = function() {};
-
-SDK.SourceMapFactory.prototype = {
-  /**
-   * @param {!SDK.Target} target
-   * @param {!SDK.SourceMap} sourceMap
-   * @return {!Promise<?SDK.SourceMap>}
-   */
-  editableSourceMap(target, sourceMap) {},
-};
-
-/**
- * @implements {SDK.SourceMap}
- * @unrestricted
- */
-SDK.TextSourceMap = class {
-  /**
-   * Implements Source Map V3 model. See https://github.com/google/closure-compiler/wiki/Source-Maps
-   * for format description.
-   * @param {string} compiledURL
-   * @param {string} sourceMappingURL
-   * @param {!SDK.SourceMapV3} payload
-   */
-  constructor(compiledURL, sourceMappingURL, payload) {
-    if (!SDK.TextSourceMap._base64Map) {
-      const base64Digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-      SDK.TextSourceMap._base64Map = {};
-      for (let i = 0; i < base64Digits.length; ++i)
-        SDK.TextSourceMap._base64Map[base64Digits.charAt(i)] = i;
-    }
-
-    this._json = payload;
-    this._compiledURL = compiledURL;
-    this._sourceMappingURL = sourceMappingURL;
-    this._baseURL = sourceMappingURL.startsWith('data:') ? compiledURL : sourceMappingURL;
-
-    /** @type {?Array<!SDK.SourceMapEntry>} */
-    this._mappings = null;
-    /** @type {!Map<string, !SDK.TextSourceMap.SourceInfo>} */
-    this._sourceInfos = new Map();
-    this._eachSection(this._parseSources.bind(this));
-  }
-
-  /**
-   * @param {string} sourceMapURL
-   * @param {string} compiledURL
-   * @return {!Promise<?SDK.TextSourceMap>}
-   * @this {SDK.TextSourceMap}
-   */
-  static load(sourceMapURL, compiledURL) {
-    let callback;
-    const promise = new Promise(fulfill => callback = fulfill);
-    SDK.multitargetNetworkManager.loadResource(sourceMapURL, contentLoaded);
-    return promise;
-
-    /**
-     * @param {number} statusCode
-     * @param {!Object.<string, string>} headers
-     * @param {string} content
-     */
-    function contentLoaded(statusCode, headers, content) {
-      if (!content || statusCode >= 400) {
-        callback(null);
-        return;
-      }
-
-      if (content.slice(0, 3) === ')]}')
-        content = content.substring(content.indexOf('\n'));
-      try {
-        const payload = /** @type {!SDK.SourceMapV3} */ (JSON.parse(content));
-        callback(new SDK.TextSourceMap(compiledURL, sourceMapURL, payload));
-      } catch (e) {
-        console.error(e);
-        Common.console.warn('DevTools failed to parse SourceMap: ' + sourceMapURL);
-        callback(null);
-      }
-    }
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  compiledURL() {
-    return this._compiledURL;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  url() {
-    return this._sourceMappingURL;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<string>}
-   */
-  sourceURLs() {
-    return this._sourceInfos.keysArray();
-  }
-
-  /**
-   * @override
-   * @param {string} sourceURL
-   * @param {!Common.ResourceType} contentType
-   * @return {!Common.ContentProvider}
-   */
-  sourceContentProvider(sourceURL, contentType) {
-    const info = this._sourceInfos.get(sourceURL);
-    if (info.content)
-      return Common.StaticContentProvider.fromString(sourceURL, contentType, info.content);
-    return new SDK.CompilerSourceMappingContentProvider(sourceURL, contentType);
-  }
-
-  /**
-   * @override
-   * @param {string} sourceURL
-   * @return {?string}
-   */
-  embeddedContentByURL(sourceURL) {
-    if (!this._sourceInfos.has(sourceURL))
-      return null;
-    return this._sourceInfos.get(sourceURL).content;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  editable() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {!Array<!TextUtils.TextRange>} ranges
-   * @param {!Array<string>} texts
-   * @return {!Promise<?SDK.SourceMap.EditResult>}
-   */
-  editCompiled(ranges, texts) {
-    return Promise.resolve(/** @type {?SDK.SourceMap.EditResult} */ (null));
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber in compiled resource
-   * @param {number} columnNumber in compiled resource
-   * @return {?SDK.SourceMapEntry}
-   */
-  findEntry(lineNumber, columnNumber) {
-    const mappings = this.mappings();
-    const index = mappings.upperBound(
-        undefined, (unused, entry) => lineNumber - entry.lineNumber || columnNumber - entry.columnNumber);
-    return index ? mappings[index - 1] : null;
-  }
-
-  /**
-   * @param {string} sourceURL
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.SourceMapEntry}
-   */
-  sourceLineMapping(sourceURL, lineNumber, columnNumber) {
-    const mappings = this._reversedMappings(sourceURL);
-    const first = mappings.lowerBound(lineNumber, lineComparator);
-    const last = mappings.upperBound(lineNumber, lineComparator);
-    if (first >= mappings.length || mappings[first].sourceLineNumber !== lineNumber)
-      return null;
-    const columnMappings = mappings.slice(first, last);
-    const index =
-        columnMappings.lowerBound(columnNumber, (columnNumber, mapping) => columnNumber - mapping.sourceColumnNumber);
-    if (index >= columnMappings.length)
-      return null;
-    return columnMappings[index];
-
-    /**
-     * @param {number} lineNumber
-     * @param {!SDK.SourceMapEntry} mapping
-     * @return {number}
-     */
-    function lineComparator(lineNumber, mapping) {
-      return lineNumber - mapping.sourceLineNumber;
-    }
-  }
-
-  /**
-   * @param {string} sourceURL
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {!Array<!SDK.SourceMapEntry>}
-   */
-  findReverseEntries(sourceURL, lineNumber, columnNumber) {
-    const mappings = this._reversedMappings(sourceURL);
-    const endIndex = mappings.upperBound(
-        undefined, (unused, entry) => lineNumber - entry.sourceLineNumber || columnNumber - entry.sourceColumnNumber);
-    let startIndex = endIndex;
-    while (startIndex > 0 && mappings[startIndex - 1].sourceLineNumber === mappings[endIndex - 1].sourceLineNumber &&
-           mappings[startIndex - 1].sourceColumnNumber === mappings[endIndex - 1].sourceColumnNumber)
-      --startIndex;
-
-    return mappings.slice(startIndex, endIndex);
-  }
-
-  /**
-   * @return {!Array<!SDK.SourceMapEntry>}
-   */
-  mappings() {
-    if (this._mappings === null) {
-      this._mappings = [];
-      this._eachSection(this._parseMap.bind(this));
-      this._json = null;
-    }
-    return /** @type {!Array<!SDK.SourceMapEntry>} */ (this._mappings);
-  }
-
-  /**
-   * @param {string} sourceURL
-   * @return {!Array.<!SDK.SourceMapEntry>}
-   */
-  _reversedMappings(sourceURL) {
-    if (!this._sourceInfos.has(sourceURL))
-      return [];
-    const mappings = this.mappings();
-    const info = this._sourceInfos.get(sourceURL);
-    if (info.reverseMappings === null)
-      info.reverseMappings = mappings.filter(mapping => mapping.sourceURL === sourceURL).sort(sourceMappingComparator);
-
-    return info.reverseMappings;
-
-    /**
-     * @param {!SDK.SourceMapEntry} a
-     * @param {!SDK.SourceMapEntry} b
-     * @return {number}
-     */
-    function sourceMappingComparator(a, b) {
-      if (a.sourceLineNumber !== b.sourceLineNumber)
-        return a.sourceLineNumber - b.sourceLineNumber;
-      if (a.sourceColumnNumber !== b.sourceColumnNumber)
-        return a.sourceColumnNumber - b.sourceColumnNumber;
-
-      if (a.lineNumber !== b.lineNumber)
-        return a.lineNumber - b.lineNumber;
-
-      return a.columnNumber - b.columnNumber;
-    }
-  }
-
-  /**
-   * @param {function(!SDK.SourceMapV3, number, number)} callback
-   */
-  _eachSection(callback) {
-    if (!this._json.sections) {
-      callback(this._json, 0, 0);
-      return;
-    }
-    for (const section of this._json.sections)
-      callback(section.map, section.offset.line, section.offset.column);
-  }
-
-  /**
-   * @param {!SDK.SourceMapV3} sourceMap
-   */
-  _parseSources(sourceMap) {
-    const sourcesList = [];
-    let sourceRoot = sourceMap.sourceRoot || '';
-    if (sourceRoot && !sourceRoot.endsWith('/'))
-      sourceRoot += '/';
-    for (let i = 0; i < sourceMap.sources.length; ++i) {
-      const href = sourceRoot + sourceMap.sources[i];
-      let url = Common.ParsedURL.completeURL(this._baseURL, href) || href;
-      const source = sourceMap.sourcesContent && sourceMap.sourcesContent[i];
-      if (url === this._compiledURL && source)
-        url += Common.UIString('? [sm]');
-      this._sourceInfos.set(url, new SDK.TextSourceMap.SourceInfo(source, null));
-      sourcesList.push(url);
-    }
-    sourceMap[SDK.TextSourceMap._sourcesListSymbol] = sourcesList;
-  }
-
-  /**
-   * @param {!SDK.SourceMapV3} map
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   */
-  _parseMap(map, lineNumber, columnNumber) {
-    let sourceIndex = 0;
-    let sourceLineNumber = 0;
-    let sourceColumnNumber = 0;
-    let nameIndex = 0;
-    const sources = map[SDK.TextSourceMap._sourcesListSymbol];
-    const names = map.names || [];
-    const stringCharIterator = new SDK.TextSourceMap.StringCharIterator(map.mappings);
-    let sourceURL = sources[sourceIndex];
-
-    while (true) {
-      if (stringCharIterator.peek() === ',') {
-        stringCharIterator.next();
-      } else {
-        while (stringCharIterator.peek() === ';') {
-          lineNumber += 1;
-          columnNumber = 0;
-          stringCharIterator.next();
-        }
-        if (!stringCharIterator.hasNext())
-          break;
-      }
-
-      columnNumber += this._decodeVLQ(stringCharIterator);
-      if (!stringCharIterator.hasNext() || this._isSeparator(stringCharIterator.peek())) {
-        this._mappings.push(new SDK.SourceMapEntry(lineNumber, columnNumber));
-        continue;
-      }
-
-      const sourceIndexDelta = this._decodeVLQ(stringCharIterator);
-      if (sourceIndexDelta) {
-        sourceIndex += sourceIndexDelta;
-        sourceURL = sources[sourceIndex];
-      }
-      sourceLineNumber += this._decodeVLQ(stringCharIterator);
-      sourceColumnNumber += this._decodeVLQ(stringCharIterator);
-
-      if (!stringCharIterator.hasNext() || this._isSeparator(stringCharIterator.peek())) {
-        this._mappings.push(
-            new SDK.SourceMapEntry(lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber));
-        continue;
-      }
-
-      nameIndex += this._decodeVLQ(stringCharIterator);
-      this._mappings.push(new SDK.SourceMapEntry(
-          lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber, names[nameIndex]));
-    }
-
-    // As per spec, mappings are not necessarily sorted.
-    this._mappings.stableSort(SDK.SourceMapEntry.compare);
-  }
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  _isSeparator(char) {
-    return char === ',' || char === ';';
-  }
-
-  /**
-   * @param {!SDK.TextSourceMap.StringCharIterator} stringCharIterator
-   * @return {number}
-   */
-  _decodeVLQ(stringCharIterator) {
-    // Read unsigned value.
-    let result = 0;
-    let shift = 0;
-    let digit;
-    do {
-      digit = SDK.TextSourceMap._base64Map[stringCharIterator.next()];
-      result += (digit & SDK.TextSourceMap._VLQ_BASE_MASK) << shift;
-      shift += SDK.TextSourceMap._VLQ_BASE_SHIFT;
-    } while (digit & SDK.TextSourceMap._VLQ_CONTINUATION_MASK);
-
-    // Fix the sign.
-    const negative = result & 1;
-    result >>= 1;
-    return negative ? -result : result;
-  }
-
-  /**
-   * @param {string} url
-   * @param {!TextUtils.TextRange} textRange
-   * @return {!TextUtils.TextRange}
-   */
-  reverseMapTextRange(url, textRange) {
-    /**
-     * @param {!{lineNumber: number, columnNumber: number}} position
-     * @param {!SDK.SourceMapEntry} mapping
-     * @return {number}
-     */
-    function comparator(position, mapping) {
-      if (position.lineNumber !== mapping.sourceLineNumber)
-        return position.lineNumber - mapping.sourceLineNumber;
-
-      return position.columnNumber - mapping.sourceColumnNumber;
-    }
-
-    const mappings = this._reversedMappings(url);
-    const startIndex =
-        mappings.lowerBound({lineNumber: textRange.startLine, columnNumber: textRange.startColumn}, comparator);
-    const endIndex =
-        mappings.upperBound({lineNumber: textRange.endLine, columnNumber: textRange.endColumn}, comparator);
-
-    const startMapping = mappings[startIndex];
-    const endMapping = mappings[endIndex];
-    return new TextUtils.TextRange(
-        startMapping.lineNumber, startMapping.columnNumber, endMapping.lineNumber, endMapping.columnNumber);
-  }
-};
-
-SDK.TextSourceMap._VLQ_BASE_SHIFT = 5;
-SDK.TextSourceMap._VLQ_BASE_MASK = (1 << 5) - 1;
-SDK.TextSourceMap._VLQ_CONTINUATION_MASK = 1 << 5;
-
-
-/**
- * @unrestricted
- */
-SDK.TextSourceMap.StringCharIterator = class {
-  /**
-   * @param {string} string
-   */
-  constructor(string) {
-    this._string = string;
-    this._position = 0;
-  }
-
-  /**
-   * @return {string}
-   */
-  next() {
-    return this._string.charAt(this._position++);
-  }
-
-  /**
-   * @return {string}
-   */
-  peek() {
-    return this._string.charAt(this._position);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasNext() {
-    return this._position < this._string.length;
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.TextSourceMap.SourceInfo = class {
-  /**
-   * @param {?string} content
-   * @param {?Array<!SDK.SourceMapEntry>} reverseMappings
-   */
-  constructor(content, reverseMappings) {
-    this.content = content;
-    this.reverseMappings = reverseMappings;
-  }
-};
-
-SDK.TextSourceMap._sourcesListSymbol = Symbol('sourcesList');
diff --git a/front_end/sdk/SourceMapManager.js b/front_end/sdk/SourceMapManager.js
deleted file mode 100644
index 0298991..0000000
--- a/front_end/sdk/SourceMapManager.js
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @template T
- */
-SDK.SourceMapManager = class extends Common.Object {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super();
-
-    this._target = target;
-    this._isEnabled = true;
-
-    /** @type {!Map<!T, string>} */
-    this._relativeSourceURL = new Map();
-    /** @type {!Map<!T, string>} */
-    this._relativeSourceMapURL = new Map();
-    /** @type {!Map<!T, string>} */
-    this._resolvedSourceMapURL = new Map();
-
-    /** @type {!Map<string, !SDK.SourceMap>} */
-    this._sourceMapByURL = new Map();
-    /** @type {!Multimap<string, !T>} */
-    this._sourceMapURLToLoadingClients = new Multimap();
-    /** @type {!Multimap<string, !T>} */
-    this._sourceMapURLToClients = new Multimap();
-
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
-  }
-
-  /**
-   * @param {boolean} isEnabled
-   */
-  setEnabled(isEnabled) {
-    if (isEnabled === this._isEnabled)
-      return;
-    this._isEnabled = isEnabled;
-    const clients = Array.from(this._resolvedSourceMapURL.keys());
-    for (const client of clients) {
-      const relativeSourceURL = this._relativeSourceURL.get(client);
-      const relativeSourceMapURL = this._relativeSourceMapURL.get(client);
-      this.detachSourceMap(client);
-      this.attachSourceMap(client, relativeSourceURL, relativeSourceMapURL);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _inspectedURLChanged(event) {
-    if (event.data !== this._target)
-      return;
-
-    const clients = Array.from(this._resolvedSourceMapURL.keys());
-    for (const client of clients) {
-      const relativeSourceURL = this._relativeSourceURL.get(client);
-      const relativeSourceMapURL = this._relativeSourceMapURL.get(client);
-      const resolvedSourceMapURL = this._resolvedSourceMapURL.get(client);
-      const sourceMapURL = this._resolveRelativeURLs(relativeSourceURL, relativeSourceMapURL).sourceMapURL;
-      if (sourceMapURL !== resolvedSourceMapURL) {
-        this.detachSourceMap(client);
-        this.attachSourceMap(client, relativeSourceURL, relativeSourceMapURL);
-      }
-    }
-  }
-
-  /**
-   * @param {!T} client
-   * @return {?SDK.SourceMap}
-   */
-  sourceMapForClient(client) {
-    const sourceMapURL = this._resolvedSourceMapURL.get(client);
-    return sourceMapURL ? this._sourceMapByURL.get(sourceMapURL) || null : null;
-  }
-
-  /**
-   * @param {!SDK.SourceMap} sourceMap
-   * @return {!Array<!T>}
-   */
-  clientsForSourceMap(sourceMap) {
-    if (this._sourceMapURLToClients.has(sourceMap.url()))
-      return this._sourceMapURLToClients.get(sourceMap.url()).valuesArray();
-    return this._sourceMapURLToLoadingClients.get(sourceMap.url()).valuesArray();
-  }
-
-  /**
-   * @param {!SDK.SourceMap.EditResult} editResult
-   */
-  applySourceMapEdit(editResult) {
-    console.assert(
-        this._sourceMapByURL.has(editResult.map.url()), 'Cannot apply edit result for non-existing source map');
-    this._sourceMapByURL.set(editResult.map.url(), editResult.map);
-    this.dispatchEventToListeners(
-        SDK.SourceMapManager.Events.SourceMapChanged, {sourceMap: editResult.map, newSources: editResult.newSources});
-  }
-
-  /**
-   * @param {string} sourceURL
-   * @param {string} sourceMapURL
-   * @return {!{sourceURL: ?string, sourceMapURL: ?string}}
-   */
-  _resolveRelativeURLs(sourceURL, sourceMapURL) {
-    // |sourceURL| can be a random string, but is generally an absolute path.
-    // Complete it to inspected page url for relative links.
-    const resolvedSourceURL = Common.ParsedURL.completeURL(this._target.inspectedURL(), sourceURL);
-    const resolvedSourceMapURL =
-        resolvedSourceURL ? Common.ParsedURL.completeURL(resolvedSourceURL, sourceMapURL) : null;
-    return {sourceURL: resolvedSourceURL, sourceMapURL: resolvedSourceMapURL};
-  }
-
-  /**
-   * @param {!T} client
-   * @param {string} sourceURL
-   * @param {?string} sourceMapURL
-   */
-  attachSourceMap(client, sourceURL, sourceMapURL) {
-    if (!sourceMapURL)
-      return;
-    console.assert(!this._resolvedSourceMapURL.has(client), 'SourceMap is already attached to client');
-    const resolvedURLs = this._resolveRelativeURLs(sourceURL, sourceMapURL);
-    if (!resolvedURLs.sourceURL || !resolvedURLs.sourceMapURL)
-      return;
-    this._relativeSourceURL.set(client, sourceURL);
-    this._relativeSourceMapURL.set(client, sourceMapURL);
-    this._resolvedSourceMapURL.set(client, resolvedURLs.sourceMapURL);
-
-    sourceURL = resolvedURLs.sourceURL;
-    sourceMapURL = resolvedURLs.sourceMapURL;
-    if (!this._isEnabled)
-      return;
-
-    this.dispatchEventToListeners(SDK.SourceMapManager.Events.SourceMapWillAttach, client);
-
-    if (this._sourceMapByURL.has(sourceMapURL)) {
-      attach.call(this, sourceMapURL, client);
-      return;
-    }
-    if (!this._sourceMapURLToLoadingClients.has(sourceMapURL)) {
-      SDK.TextSourceMap.load(sourceMapURL, sourceURL)
-          .then(onTextSourceMapLoaded.bind(this, sourceMapURL))
-          .then(onSourceMap.bind(this, sourceMapURL));
-    }
-    this._sourceMapURLToLoadingClients.set(sourceMapURL, client);
-
-    /**
-     * @param {string} sourceMapURL
-     * @param {?SDK.TextSourceMap} sourceMap
-     * @return {!Promise<?SDK.SourceMap>}
-     * @this {SDK.SourceMapManager}
-     */
-    function onTextSourceMapLoaded(sourceMapURL, sourceMap) {
-      if (!sourceMap)
-        return Promise.resolve(/** @type {?SDK.SourceMap} */ (null));
-      const factoryExtension = this._factoryForSourceMap(sourceMap);
-      if (!factoryExtension)
-        return Promise.resolve(/** @type {?SDK.SourceMap} */ (sourceMap));
-      return factoryExtension.instance()
-          .then(factory => factory.editableSourceMap(this._target, sourceMap))
-          .then(map => map || sourceMap)
-          .catchException(/** @type {?SDK.SourceMap} */ (null));
-    }
-
-    /**
-     * @param {string} sourceMapURL
-     * @param {?SDK.SourceMap} sourceMap
-     * @this {SDK.SourceMapManager}
-     */
-    function onSourceMap(sourceMapURL, sourceMap) {
-      this._sourceMapLoadedForTest();
-      const clients = this._sourceMapURLToLoadingClients.get(sourceMapURL);
-      this._sourceMapURLToLoadingClients.deleteAll(sourceMapURL);
-      if (!clients.size)
-        return;
-      if (!sourceMap) {
-        for (const client of clients)
-          this.dispatchEventToListeners(SDK.SourceMapManager.Events.SourceMapFailedToAttach, client);
-        return;
-      }
-      this._sourceMapByURL.set(sourceMapURL, sourceMap);
-      for (const client of clients)
-        attach.call(this, sourceMapURL, client);
-    }
-
-    /**
-     * @param {string} sourceMapURL
-     * @param {!T} client
-     * @this {SDK.SourceMapManager}
-     */
-    function attach(sourceMapURL, client) {
-      this._sourceMapURLToClients.set(sourceMapURL, client);
-      const sourceMap = this._sourceMapByURL.get(sourceMapURL);
-      this.dispatchEventToListeners(
-          SDK.SourceMapManager.Events.SourceMapAttached, {client: client, sourceMap: sourceMap});
-    }
-  }
-
-  /**
-   * @param {!SDK.SourceMap} sourceMap
-   * @return {?Runtime.Extension}
-   */
-  _factoryForSourceMap(sourceMap) {
-    const sourceExtensions = new Set();
-    for (const url of sourceMap.sourceURLs())
-      sourceExtensions.add(Common.ParsedURL.extractExtension(url));
-    for (const runtimeExtension of self.runtime.extensions(SDK.SourceMapFactory)) {
-      const supportedExtensions = new Set(runtimeExtension.descriptor()['extensions']);
-      if (supportedExtensions.containsAll(sourceExtensions))
-        return runtimeExtension;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!T} client
-   */
-  detachSourceMap(client) {
-    const sourceMapURL = this._resolvedSourceMapURL.get(client);
-    this._relativeSourceURL.delete(client);
-    this._relativeSourceMapURL.delete(client);
-    this._resolvedSourceMapURL.delete(client);
-
-    if (!sourceMapURL)
-      return;
-    if (!this._sourceMapURLToClients.hasValue(sourceMapURL, client)) {
-      if (this._sourceMapURLToLoadingClients.delete(sourceMapURL, client))
-        this.dispatchEventToListeners(SDK.SourceMapManager.Events.SourceMapFailedToAttach, client);
-      return;
-    }
-    this._sourceMapURLToClients.delete(sourceMapURL, client);
-    const sourceMap = this._sourceMapByURL.get(sourceMapURL);
-    if (!this._sourceMapURLToClients.has(sourceMapURL))
-      this._sourceMapByURL.delete(sourceMapURL);
-    this.dispatchEventToListeners(
-        SDK.SourceMapManager.Events.SourceMapDetached, {client: client, sourceMap: sourceMap});
-  }
-
-  _sourceMapLoadedForTest() {
-  }
-
-  dispose() {
-    SDK.targetManager.removeEventListener(
-        SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
-  }
-};
-
-SDK.SourceMapManager.Events = {
-  SourceMapWillAttach: Symbol('SourceMapWillAttach'),
-  SourceMapFailedToAttach: Symbol('SourceMapFailedToAttach'),
-  SourceMapAttached: Symbol('SourceMapAttached'),
-  SourceMapDetached: Symbol('SourceMapDetached'),
-  SourceMapChanged: Symbol('SourceMapChanged')
-};
diff --git a/front_end/sdk/Target.js b/front_end/sdk/Target.js
deleted file mode 100644
index 87cc1c6..0000000
--- a/front_end/sdk/Target.js
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * @unrestricted
- */
-SDK.Target = class extends Protocol.TargetBase {
-  /**
-   * @param {!SDK.TargetManager} targetManager
-   * @param {string} id
-   * @param {string} name
-   * @param {number} capabilitiesMask
-   * @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory
-   * @param {?SDK.Target} parentTarget
-   * @param {boolean} suspended
-   */
-  constructor(targetManager, id, name, capabilitiesMask, connectionFactory, parentTarget, suspended) {
-    super(connectionFactory);
-    this._targetManager = targetManager;
-    this._name = name;
-    this._inspectedURL = '';
-    this._capabilitiesMask = capabilitiesMask;
-    this._parentTarget = parentTarget;
-    this._id = id;
-    this._modelByConstructor = new Map();
-    this._isSuspended = suspended;
-  }
-
-  createModels(required) {
-    this._creatingModels = true;
-    // TODO(dgozman): fix this in bindings layer.
-    this.model(SDK.ResourceTreeModel);
-    const registered = Array.from(SDK.SDKModel._registeredModels.keys());
-    for (const modelClass of registered) {
-      const info = SDK.SDKModel._registeredModels.get(modelClass);
-      if (info.autostart || required.has(modelClass))
-        this.model(modelClass);
-    }
-    this._creatingModels = false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isNodeJS() {
-    // TODO(lushnikov): this is an unreliable way to detect Node.js targets.
-    return this._capabilitiesMask === SDK.Target.Capability.JS || this._isNodeJSForTest;
-  }
-
-  setIsNodeJSForTest() {
-    this._isNodeJSForTest = true;
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._name || this._inspectedURLName;
-  }
-
-  /**
-   * @return {!SDK.TargetManager}
-   */
-  targetManager() {
-    return this._targetManager;
-  }
-
-  /**
-   * @param {number} capabilitiesMask
-   * @return {boolean}
-   */
-  hasAllCapabilities(capabilitiesMask) {
-    return (this._capabilitiesMask & capabilitiesMask) === capabilitiesMask;
-  }
-
-  /**
-   * @param {string} label
-   * @return {string}
-   */
-  decorateLabel(label) {
-    return !this.hasBrowserCapability() ? '\u2699 ' + label : label;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasBrowserCapability() {
-    return this.hasAllCapabilities(SDK.Target.Capability.Browser);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasJSCapability() {
-    return this.hasAllCapabilities(SDK.Target.Capability.JS);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasLogCapability() {
-    return this.hasAllCapabilities(SDK.Target.Capability.Log);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasNetworkCapability() {
-    return this.hasAllCapabilities(SDK.Target.Capability.Network);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasTargetCapability() {
-    return this.hasAllCapabilities(SDK.Target.Capability.Target);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasDOMCapability() {
-    return this.hasAllCapabilities(SDK.Target.Capability.DOM);
-  }
-
-  /**
-   * @return {?SDK.Target}
-   */
-  parentTarget() {
-    return this._parentTarget;
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this._targetManager.removeTarget(this);
-    for (const model of this._modelByConstructor.valuesArray())
-      model.dispose();
-  }
-
-  /**
-   * @param {function(new:T, !SDK.Target)} modelClass
-   * @return {?T}
-   * @template T
-   */
-  model(modelClass) {
-    if (!this._modelByConstructor.get(modelClass)) {
-      const info = SDK.SDKModel._registeredModels.get(modelClass);
-      if (info === undefined)
-        throw 'Model class is not registered @' + new Error().stack;
-      if ((this._capabilitiesMask & info.capabilities) === info.capabilities) {
-        const model = new modelClass(this);
-        this._modelByConstructor.set(modelClass, model);
-        if (!this._creatingModels)
-          this._targetManager.modelAdded(this, modelClass, model);
-      }
-    }
-    return this._modelByConstructor.get(modelClass) || null;
-  }
-
-  /**
-   * @return {!Map<function(new:SDK.SDKModel, !SDK.Target), !SDK.SDKModel>}
-   */
-  models() {
-    return this._modelByConstructor;
-  }
-
-  /**
-   * @return {string}
-   */
-  inspectedURL() {
-    return this._inspectedURL;
-  }
-
-  /**
-   * @param {string} inspectedURL
-   */
-  setInspectedURL(inspectedURL) {
-    this._inspectedURL = inspectedURL;
-    const parsedURL = inspectedURL.asParsedURL();
-    this._inspectedURLName = parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + this._id;
-    if (!this.parentTarget())
-      InspectorFrontendHost.inspectedURLChanged(inspectedURL || '');
-    this._targetManager.dispatchEventToListeners(SDK.TargetManager.Events.InspectedURLChanged, this);
-    if (!this._name)
-      this._targetManager.dispatchEventToListeners(SDK.TargetManager.Events.NameChanged, this);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  suspend() {
-    if (this._isSuspended)
-      return Promise.resolve();
-    this._isSuspended = true;
-
-    const promises = [];
-    for (const model of this.models().values())
-      promises.push(model.suspendModel());
-    return Promise.all(promises);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  resume() {
-    if (!this._isSuspended)
-      return Promise.resolve();
-    this._isSuspended = false;
-
-    const promises = [];
-    for (const model of this.models().values())
-      promises.push(model.resumeModel());
-    return Promise.all(promises);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  suspended() {
-    return this._isSuspended;
-  }
-};
-
-/**
- * @enum {number}
- */
-SDK.Target.Capability = {
-  Browser: 1 << 0,
-  DOM: 1 << 1,
-  JS: 1 << 2,
-  Log: 1 << 3,
-  Network: 1 << 4,
-  Target: 1 << 5,
-  ScreenCapture: 1 << 6,
-  Tracing: 1 << 7,
-  Emulation: 1 << 8,
-  Security: 1 << 9,
-  Input: 1 << 10,
-  Inspector: 1 << 11,
-  DeviceEmulation: 1 << 12,
-
-  None: 0,
-
-  AllForTests: (1 << 13) - 1
-};
-
-/**
- * @unrestricted
- */
-SDK.SDKModel = class extends Common.Object {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super();
-    this._target = target;
-  }
-
-  /**
-   * @return {!SDK.Target}
-   */
-  target() {
-    return this._target;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  suspendModel() {
-    return Promise.resolve();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  resumeModel() {
-    return Promise.resolve();
-  }
-
-  dispose() {
-  }
-};
-
-
-/**
- * @param {function(new:SDK.SDKModel, !SDK.Target)} modelClass
- * @param {number} capabilities
- * @param {boolean} autostart
- */
-SDK.SDKModel.register = function(modelClass, capabilities, autostart) {
-  if (!SDK.SDKModel._registeredModels)
-    SDK.SDKModel._registeredModels = new Map();
-  SDK.SDKModel._registeredModels.set(modelClass, {capabilities: capabilities, autostart: autostart});
-};
-
-/** @type {!Map<function(new:SDK.SDKModel, !SDK.Target), !{capabilities: number, autostart: boolean}>} */
-SDK.SDKModel._registeredModels;
diff --git a/front_end/sdk/TargetManager.js b/front_end/sdk/TargetManager.js
deleted file mode 100644
index 4b13baa..0000000
--- a/front_end/sdk/TargetManager.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-SDK.TargetManager = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!Array.<!SDK.Target>} */
-    this._targets = [];
-    /** @type {!Array.<!SDK.TargetManager.Observer>} */
-    this._observers = [];
-    this._observerCapabiliesMaskSymbol = Symbol('observerCapabilitiesMask');
-    /** @type {!Map<symbol, !Array<{modelClass: !Function, thisObject: (!Object|undefined), listener: function(!Common.Event)}>>} */
-    this._modelListeners = new Map();
-    /** @type {!Map<function(new:SDK.SDKModel, !SDK.Target), !Array<!SDK.SDKModelObserver>>} */
-    this._modelObservers = new Map();
-    this._isSuspended = false;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  suspendAllTargets() {
-    if (this._isSuspended)
-      return Promise.resolve();
-    this._isSuspended = true;
-    this.dispatchEventToListeners(SDK.TargetManager.Events.SuspendStateChanged);
-    return Promise.all(this._targets.map(target => target.suspend()));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  resumeAllTargets() {
-    if (!this._isSuspended)
-      return Promise.resolve();
-    this._isSuspended = false;
-    this.dispatchEventToListeners(SDK.TargetManager.Events.SuspendStateChanged);
-    return Promise.all(this._targets.map(target => target.resume()));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  allTargetsSuspended() {
-    return this._isSuspended;
-  }
-
-  /**
-   * @param {function(new:T,!SDK.Target)} modelClass
-   * @return {!Array<!T>}
-   * @template T
-   */
-  models(modelClass) {
-    const result = [];
-    for (let i = 0; i < this._targets.length; ++i) {
-      const model = this._targets[i].model(modelClass);
-      if (model)
-        result.push(model);
-    }
-    return result;
-  }
-
-  /**
-   * @return {string}
-   */
-  inspectedURL() {
-    return this._targets[0] ? this._targets[0].inspectedURL() : '';
-  }
-
-  /**
-   * @param {function(new:T,!SDK.Target)} modelClass
-   * @param {!SDK.SDKModelObserver<T>} observer
-   * @template T
-   */
-  observeModels(modelClass, observer) {
-    if (!this._modelObservers.has(modelClass))
-      this._modelObservers.set(modelClass, []);
-    this._modelObservers.get(modelClass).push(observer);
-    for (const model of this.models(modelClass))
-      observer.modelAdded(model);
-  }
-
-  /**
-   * @param {function(new:T,!SDK.Target)} modelClass
-   * @param {!SDK.SDKModelObserver<T>} observer
-   * @template T
-   */
-  unobserveModels(modelClass, observer) {
-    if (!this._modelObservers.has(modelClass))
-      return;
-    const observers = this._modelObservers.get(modelClass);
-    observers.remove(observer);
-    if (!observers.length)
-      this._modelObservers.delete(modelClass);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @param {function(new:SDK.SDKModel,!SDK.Target)} modelClass
-   * @param {!SDK.SDKModel} model
-   */
-  modelAdded(target, modelClass, model) {
-    if (!this._modelObservers.has(modelClass))
-      return;
-    for (const observer of this._modelObservers.get(modelClass).slice())
-      observer.modelAdded(model);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @param {function(new:SDK.SDKModel,!SDK.Target)} modelClass
-   * @param {!SDK.SDKModel} model
-   */
-  _modelRemoved(target, modelClass, model) {
-    if (!this._modelObservers.has(modelClass))
-      return;
-    for (const observer of this._modelObservers.get(modelClass).slice())
-      observer.modelRemoved(model);
-  }
-
-  /**
-   * @param {!Function} modelClass
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  addModelListener(modelClass, eventType, listener, thisObject) {
-    for (let i = 0; i < this._targets.length; ++i) {
-      const model = this._targets[i].model(modelClass);
-      if (model)
-        model.addEventListener(eventType, listener, thisObject);
-    }
-    if (!this._modelListeners.has(eventType))
-      this._modelListeners.set(eventType, []);
-    this._modelListeners.get(eventType).push({modelClass: modelClass, thisObject: thisObject, listener: listener});
-  }
-
-  /**
-   * @param {!Function} modelClass
-   * @param {symbol} eventType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  removeModelListener(modelClass, eventType, listener, thisObject) {
-    if (!this._modelListeners.has(eventType))
-      return;
-
-    for (let i = 0; i < this._targets.length; ++i) {
-      const model = this._targets[i].model(modelClass);
-      if (model)
-        model.removeEventListener(eventType, listener, thisObject);
-    }
-
-    const listeners = this._modelListeners.get(eventType);
-    for (let i = 0; i < listeners.length; ++i) {
-      if (listeners[i].modelClass === modelClass && listeners[i].listener === listener &&
-          listeners[i].thisObject === thisObject)
-        listeners.splice(i--, 1);
-    }
-    if (!listeners.length)
-      this._modelListeners.delete(eventType);
-  }
-
-  /**
-   * @param {!SDK.TargetManager.Observer} targetObserver
-   * @param {number=} capabilitiesMask
-   */
-  observeTargets(targetObserver, capabilitiesMask) {
-    if (this._observerCapabiliesMaskSymbol in targetObserver)
-      throw new Error('Observer can only be registered once');
-    targetObserver[this._observerCapabiliesMaskSymbol] = capabilitiesMask || 0;
-    this.targets(capabilitiesMask).forEach(targetObserver.targetAdded.bind(targetObserver));
-    this._observers.push(targetObserver);
-  }
-
-  /**
-   * @param {!SDK.TargetManager.Observer} targetObserver
-   */
-  unobserveTargets(targetObserver) {
-    delete targetObserver[this._observerCapabiliesMaskSymbol];
-    this._observers.remove(targetObserver);
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} name
-   * @param {number} capabilitiesMask
-   * @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory
-   * @param {?SDK.Target} parentTarget
-   * @return {!SDK.Target}
-   */
-  createTarget(id, name, capabilitiesMask, connectionFactory, parentTarget) {
-    const target = new SDK.Target(this, id, name, capabilitiesMask, connectionFactory, parentTarget, this._isSuspended);
-    target.createModels(new Set(this._modelObservers.keys()));
-    this._targets.push(target);
-
-    const copy = this._observersForTarget(target);
-    for (let i = 0; i < copy.length; ++i)
-      copy[i].targetAdded(target);
-
-    for (const modelClass of target.models().keys())
-      this.modelAdded(target, modelClass, target.models().get(modelClass));
-
-    for (const pair of this._modelListeners) {
-      const listeners = pair[1];
-      for (let i = 0; i < listeners.length; ++i) {
-        const model = target.model(listeners[i].modelClass);
-        if (model)
-          model.addEventListener(/** @type {symbol} */ (pair[0]), listeners[i].listener, listeners[i].thisObject);
-      }
-    }
-
-    return target;
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @return {!Array<!SDK.TargetManager.Observer>}
-   */
-  _observersForTarget(target) {
-    return this._observers.filter(
-        observer => target.hasAllCapabilities(observer[this._observerCapabiliesMaskSymbol] || 0));
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  removeTarget(target) {
-    if (!this._targets.includes(target))
-      return;
-
-    this._targets.remove(target);
-    for (const modelClass of target.models().keys())
-      this._modelRemoved(target, modelClass, target.models().get(modelClass));
-
-    const copy = this._observersForTarget(target);
-    for (let i = 0; i < copy.length; ++i)
-      copy[i].targetRemoved(target);
-
-    for (const pair of this._modelListeners) {
-      const listeners = pair[1];
-      for (let i = 0; i < listeners.length; ++i) {
-        const model = target.model(listeners[i].modelClass);
-        if (model)
-          model.removeEventListener(/** @type {symbol} */ (pair[0]), listeners[i].listener, listeners[i].thisObject);
-      }
-    }
-  }
-
-  /**
-   * @param {number=} capabilitiesMask
-   * @return {!Array.<!SDK.Target>}
-   */
-  targets(capabilitiesMask) {
-    if (!capabilitiesMask)
-      return this._targets.slice();
-    else
-      return this._targets.filter(target => target.hasAllCapabilities(capabilitiesMask || 0));
-  }
-
-  /**
-   *
-   * @param {string} id
-   * @return {?SDK.Target}
-   */
-  targetById(id) {
-    // TODO(dgozman): add a map id -> target.
-    for (let i = 0; i < this._targets.length; ++i) {
-      if (this._targets[i].id() === id)
-        return this._targets[i];
-    }
-    return null;
-  }
-
-  /**
-   * @return {?SDK.Target}
-   */
-  mainTarget() {
-    return this._targets[0] || null;
-  }
-};
-
-/** @enum {symbol} */
-SDK.TargetManager.Events = {
-  AvailableTargetsChanged: Symbol('AvailableTargetsChanged'),
-  InspectedURLChanged: Symbol('InspectedURLChanged'),
-  NameChanged: Symbol('NameChanged'),
-  SuspendStateChanged: Symbol('SuspendStateChanged')
-};
-
-/**
- * @interface
- */
-SDK.TargetManager.Observer = function() {};
-
-SDK.TargetManager.Observer.prototype = {
-  /**
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {},
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {},
-};
-
-/**
- * @interface
- * @template T
- */
-SDK.SDKModelObserver = function() {};
-
-SDK.SDKModelObserver.prototype = {
-  /**
-   * @param {!T} model
-   */
-  modelAdded(model) {},
-
-  /**
-   * @param {!T} model
-   */
-  modelRemoved(model) {},
-};
-
-/**
- * @type {!SDK.TargetManager}
- */
-SDK.targetManager = new SDK.TargetManager();
diff --git a/front_end/sdk/TracingManager.js b/front_end/sdk/TracingManager.js
deleted file mode 100644
index bdf2f93..0000000
--- a/front_end/sdk/TracingManager.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-/**
- * @interface
- */
-SDK.TracingManagerClient = function() {};
-
-SDK.TracingManagerClient.prototype = {
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   */
-  traceEventsCollected(events) {},
-  tracingComplete() {},
-  /**
-   * @param {number} usage
-   */
-  tracingBufferUsage(usage) {},
-  /**
-   * @param {number} progress
-   */
-  eventsRetrievalProgress(progress) {}
-};
-
-/**
- * @unrestricted
- */
-SDK.TracingManager = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._tracingAgent = target.tracingAgent();
-    target.registerTracingDispatcher(new SDK.TracingDispatcher(this));
-
-    /** @type {?SDK.TracingManagerClient} */
-    this._activeClient = null;
-    this._eventBufferSize = 0;
-    this._eventsRetrieved = 0;
-  }
-
-  /**
-   * @param {number=} usage
-   * @param {number=} eventCount
-   * @param {number=} percentFull
-   */
-  _bufferUsage(usage, eventCount, percentFull) {
-    this._eventBufferSize = eventCount;
-    this._activeClient.tracingBufferUsage(usage || percentFull || 0);
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   */
-  _eventsCollected(events) {
-    this._activeClient.traceEventsCollected(events);
-    this._eventsRetrieved += events.length;
-    if (!this._eventBufferSize)
-      return;
-    if (this._eventsRetrieved > this._eventBufferSize)
-      this._eventsRetrieved = this._eventBufferSize;
-    this._activeClient.eventsRetrievalProgress(this._eventsRetrieved / this._eventBufferSize);
-  }
-
-  _tracingComplete() {
-    this._eventBufferSize = 0;
-    this._eventsRetrieved = 0;
-    this._activeClient.tracingComplete();
-    this._activeClient = null;
-    this._finishing = false;
-  }
-
-  /**
-   * @param {!SDK.TracingManagerClient} client
-   * @param {string} categoryFilter
-   * @param {string} options
-   * @return {!Promise}
-   */
-  start(client, categoryFilter, options) {
-    if (this._activeClient)
-      throw new Error('Tracing is already started');
-    const bufferUsageReportingIntervalMs = 500;
-    this._activeClient = client;
-    return this._tracingAgent.start(
-        categoryFilter, options, bufferUsageReportingIntervalMs, SDK.TracingManager.TransferMode.ReportEvents);
-  }
-
-  stop() {
-    if (!this._activeClient)
-      throw new Error('Tracing is not started');
-    if (this._finishing)
-      throw new Error('Tracing is already being stopped');
-    this._finishing = true;
-    this._tracingAgent.end();
-  }
-};
-
-SDK.SDKModel.register(SDK.TracingManager, SDK.Target.Capability.Tracing, false);
-
-/** @typedef {!{
-        cat: string,
-        pid: number,
-        tid: number,
-        ts: number,
-        ph: string,
-        name: string,
-        args: !Object,
-        dur: number,
-        id: string,
-        id2: (!{global: (string|undefined), local: (string|undefined)}|undefined),
-        scope: string,
-        bind_id: string,
-        s: string
-    }}
- */
-SDK.TracingManager.EventPayload;
-
-SDK.TracingManager.TransferMode = {
-  ReportEvents: 'ReportEvents',
-  ReturnAsStream: 'ReturnAsStream'
-};
-
-/**
- * @implements {Protocol.TracingDispatcher}
- * @unrestricted
- */
-SDK.TracingDispatcher = class {
-  /**
-   * @param {!SDK.TracingManager} tracingManager
-   */
-  constructor(tracingManager) {
-    this._tracingManager = tracingManager;
-  }
-
-  /**
-   * @override
-   * @param {number=} usage
-   * @param {number=} eventCount
-   * @param {number=} percentFull
-   */
-  bufferUsage(usage, eventCount, percentFull) {
-    this._tracingManager._bufferUsage(usage, eventCount, percentFull);
-  }
-
-  /**
-   * @override
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} data
-   */
-  dataCollected(data) {
-    this._tracingManager._eventsCollected(data);
-  }
-
-  /**
-   * @override
-   */
-  tracingComplete() {
-    this._tracingManager._tracingComplete();
-  }
-};
diff --git a/front_end/sdk/TracingModel.js b/front_end/sdk/TracingModel.js
deleted file mode 100644
index 0158fd7..0000000
--- a/front_end/sdk/TracingModel.js
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-SDK.TracingModel = class {
-  /**
-   * @param {!SDK.BackingStorage} backingStorage
-   */
-  constructor(backingStorage) {
-    this._backingStorage = backingStorage;
-    // Avoid extra reset of the storage as it's expensive.
-    this._firstWritePending = true;
-    /** @type {!Map<(number|string), !SDK.TracingModel.Process>} */
-    this._processById = new Map();
-    this._processByName = new Map();
-    this._minimumRecordTime = 0;
-    this._maximumRecordTime = 0;
-    this._devToolsMetadataEvents = [];
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this._asyncEvents = [];
-    /** @type {!Map<string, !SDK.TracingModel.AsyncEvent>} */
-    this._openAsyncEvents = new Map();
-    /** @type {!Map<string, !Array<!SDK.TracingModel.AsyncEvent>>} */
-    this._openNestableAsyncEvents = new Map();
-    /** @type {!Map<string, !SDK.TracingModel.ProfileEventsGroup>} */
-    this._profileGroups = new Map();
-    /** @type {!Map<string, !Set<string>>} */
-    this._parsedCategories = new Map();
-  }
-
-  /**
-   * @param {string} phase
-   * @return {boolean}
-   */
-  static isNestableAsyncPhase(phase) {
-    return phase === 'b' || phase === 'e' || phase === 'n';
-  }
-
-  /**
-   * @param {string} phase
-   * @return {boolean}
-   */
-  static isAsyncBeginPhase(phase) {
-    return phase === 'S' || phase === 'b';
-  }
-
-  /**
-   * @param {string} phase
-   * @return {boolean}
-   */
-  static isAsyncPhase(phase) {
-    return SDK.TracingModel.isNestableAsyncPhase(phase) || phase === 'S' || phase === 'T' || phase === 'F' ||
-        phase === 'p';
-  }
-
-  /**
-   * @param {string} phase
-   * @return {boolean}
-   */
-  static isFlowPhase(phase) {
-    return phase === 's' || phase === 't' || phase === 'f';
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  static isTopLevelEvent(event) {
-    return event.hasCategory(SDK.TracingModel.TopLevelEventCategory) ||
-        event.hasCategory(SDK.TracingModel.DevToolsMetadataEventCategory) &&
-        event.name === 'Program';  // Older timelines may have this instead of toplevel.
-  }
-
-  /**
-   * @param {!SDK.TracingManager.EventPayload} payload
-   * @return {string|undefined}
-   */
-  static _extractId(payload) {
-    const scope = payload.scope || '';
-    if (typeof payload.id2 === 'undefined')
-      return scope && payload.id ? `${scope}@${payload.id}` : payload.id;
-    const id2 = payload.id2;
-    if (typeof id2 === 'object' && ('global' in id2) !== ('local' in id2)) {
-      return typeof id2['global'] !== 'undefined' ? `:${scope}:${id2['global']}` :
-                                                    `:${scope}:${payload.pid}:${id2['local']}`;
-    }
-    console.error(
-        `Unexpected id2 field at ${payload.ts / 1000}, one and only one of 'local' and 'global' should be present.`);
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @return {?SDK.TracingModel.Thread}
-   *
-   * TODO: Move this to a better place. This is here just for convenience o
-   * re-use between modules. This really belongs to a higher level, since it
-   * is specific to chrome's usage of tracing.
-   */
-  static browserMainThread(tracingModel) {
-    const processes = tracingModel.sortedProcesses();
-    // Avoid warning for an empty model.
-    if (!processes.length)
-      return null;
-    const browserProcesses = [];
-    const crRendererMainThreads = [];
-    for (const process of processes) {
-      if (process.name().toLowerCase().endsWith('browser'))
-        browserProcesses.push(process);
-      crRendererMainThreads.push(...process.sortedThreads().filter(t => t.name() === 'CrBrowserMain'));
-    }
-    if (crRendererMainThreads.length === 1)
-      return crRendererMainThreads[0];
-    if (browserProcesses.length === 1)
-      return browserProcesses[0].threadByName('CrBrowserMain');
-    const tracingStartedInBrowser =
-        tracingModel.devToolsMetadataEvents().filter(e => e.name === 'TracingStartedInBrowser');
-    if (tracingStartedInBrowser.length === 1)
-      return tracingStartedInBrowser[0].thread;
-    Common.console.error('Failed to find browser main thread in trace, some timeline features may be unavailable');
-    return null;
-  }
-
-  /**
-   * @return {!Array.<!SDK.TracingModel.Event>}
-   */
-  devToolsMetadataEvents() {
-    return this._devToolsMetadataEvents;
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   */
-  addEvents(events) {
-    for (let i = 0; i < events.length; ++i)
-      this._addEvent(events[i]);
-  }
-
-  tracingComplete() {
-    this._processPendingAsyncEvents();
-    this._backingStorage.appendString(this._firstWritePending ? '[]' : ']');
-    this._backingStorage.finishWriting();
-    this._firstWritePending = false;
-    for (const process of this._processById.values()) {
-      for (const thread of process._threads.values())
-        thread.tracingComplete();
-    }
-  }
-
-  dispose() {
-    if (!this._firstWritePending)
-      this._backingStorage.reset();
-  }
-
-  /**
-   * @param {number} offset
-   */
-  adjustTime(offset) {
-    this._minimumRecordTime += offset;
-    this._maximumRecordTime += offset;
-    for (const process of this._processById.values()) {
-      for (const thread of process._threads.values()) {
-        for (const event of thread.events()) {
-          event.startTime += offset;
-          if (typeof event.endTime === 'number')
-            event.endTime += offset;
-        }
-        for (const event of thread.asyncEvents()) {
-          event.startTime += offset;
-          if (typeof event.endTime === 'number')
-            event.endTime += offset;
-        }
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingManager.EventPayload} payload
-   */
-  _addEvent(payload) {
-    let process = this._processById.get(payload.pid);
-    if (!process) {
-      process = new SDK.TracingModel.Process(this, payload.pid);
-      this._processById.set(payload.pid, process);
-    }
-
-    const phase = SDK.TracingModel.Phase;
-    const eventsDelimiter = ',\n';
-    this._backingStorage.appendString(this._firstWritePending ? '[' : eventsDelimiter);
-    this._firstWritePending = false;
-    const stringPayload = JSON.stringify(payload);
-    const isAccessible = payload.ph === phase.SnapshotObject;
-    let backingStorage = null;
-    const keepStringsLessThan = 10000;
-    if (isAccessible && stringPayload.length > keepStringsLessThan)
-      backingStorage = this._backingStorage.appendAccessibleString(stringPayload);
-    else
-      this._backingStorage.appendString(stringPayload);
-
-    const timestamp = payload.ts / 1000;
-    // We do allow records for unrelated threads to arrive out-of-order,
-    // so there's a chance we're getting records from the past.
-    if (timestamp && (!this._minimumRecordTime || timestamp < this._minimumRecordTime) &&
-        (payload.ph === phase.Begin || payload.ph === phase.Complete || payload.ph === phase.Instant))
-      this._minimumRecordTime = timestamp;
-    const endTimeStamp = (payload.ts + (payload.dur || 0)) / 1000;
-    this._maximumRecordTime = Math.max(this._maximumRecordTime, endTimeStamp);
-    const event = process._addEvent(payload);
-    if (!event)
-      return;
-    if (payload.ph === phase.Sample) {
-      this._addSampleEvent(event);
-      return;
-    }
-    // Build async event when we've got events from all threads & processes, so we can sort them and process in the
-    // chronological order. However, also add individual async events to the thread flow (above), so we can easily
-    // display them on the same chart as other events, should we choose so.
-    if (SDK.TracingModel.isAsyncPhase(payload.ph))
-      this._asyncEvents.push(event);
-    event._setBackingStorage(backingStorage);
-    if (event.hasCategory(SDK.TracingModel.DevToolsMetadataEventCategory))
-      this._devToolsMetadataEvents.push(event);
-
-    if (payload.ph !== phase.Metadata)
-      return;
-
-    switch (payload.name) {
-      case SDK.TracingModel.MetadataEvent.ProcessSortIndex:
-        process._setSortIndex(payload.args['sort_index']);
-        break;
-      case SDK.TracingModel.MetadataEvent.ProcessName:
-        const processName = payload.args['name'];
-        process._setName(processName);
-        this._processByName.set(processName, process);
-        break;
-      case SDK.TracingModel.MetadataEvent.ThreadSortIndex:
-        process.threadById(payload.tid)._setSortIndex(payload.args['sort_index']);
-        break;
-      case SDK.TracingModel.MetadataEvent.ThreadName:
-        process.threadById(payload.tid)._setName(payload.args['name']);
-        break;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addSampleEvent(event) {
-    const group = this._profileGroups.get(event.id);
-    if (group)
-      group._addChild(event);
-    else
-      this._profileGroups.set(event.id, new SDK.TracingModel.ProfileEventsGroup(event));
-  }
-
-  /**
-   * @param {string} id
-   * @return {?SDK.TracingModel.ProfileEventsGroup}
-   */
-  profileGroup(id) {
-    return this._profileGroups.get(id) || null;
-  }
-
-  /**
-   * @return {number}
-   */
-  minimumRecordTime() {
-    return this._minimumRecordTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  maximumRecordTime() {
-    return this._maximumRecordTime;
-  }
-
-  /**
-   * @return {!Array.<!SDK.TracingModel.Process>}
-   */
-  sortedProcesses() {
-    return SDK.TracingModel.NamedObject._sort(this._processById.valuesArray());
-  }
-
-  /**
-   * @param {string} name
-   * @return {?SDK.TracingModel.Process}
-   */
-  processByName(name) {
-    return this._processByName.get(name);
-  }
-
-  /**
-   * @param {string} processName
-   * @param {string} threadName
-   * @return {?SDK.TracingModel.Thread}
-   */
-  threadByName(processName, threadName) {
-    const process = this.processByName(processName);
-    return process && process.threadByName(threadName);
-  }
-
-  _processPendingAsyncEvents() {
-    this._asyncEvents.stableSort(SDK.TracingModel.Event.compareStartTime);
-    for (let i = 0; i < this._asyncEvents.length; ++i) {
-      const event = this._asyncEvents[i];
-      if (SDK.TracingModel.isNestableAsyncPhase(event.phase))
-        this._addNestableAsyncEvent(event);
-      else
-        this._addAsyncEvent(event);
-    }
-    this._asyncEvents = [];
-    this._closeOpenAsyncEvents();
-  }
-
-  _closeOpenAsyncEvents() {
-    for (const event of this._openAsyncEvents.values()) {
-      event.setEndTime(this._maximumRecordTime);
-      // FIXME: remove this once we figure a better way to convert async console
-      // events to sync [waterfall] timeline records.
-      event.steps[0].setEndTime(this._maximumRecordTime);
-    }
-    this._openAsyncEvents.clear();
-
-    for (const eventStack of this._openNestableAsyncEvents.values()) {
-      while (eventStack.length)
-        eventStack.pop().setEndTime(this._maximumRecordTime);
-    }
-    this._openNestableAsyncEvents.clear();
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addNestableAsyncEvent(event) {
-    const phase = SDK.TracingModel.Phase;
-    const key = event.categoriesString + '.' + event.id;
-    let openEventsStack = this._openNestableAsyncEvents.get(key);
-
-    switch (event.phase) {
-      case phase.NestableAsyncBegin:
-        if (!openEventsStack) {
-          openEventsStack = [];
-          this._openNestableAsyncEvents.set(key, openEventsStack);
-        }
-        const asyncEvent = new SDK.TracingModel.AsyncEvent(event);
-        openEventsStack.push(asyncEvent);
-        event.thread._addAsyncEvent(asyncEvent);
-        break;
-
-      case phase.NestableAsyncInstant:
-        if (openEventsStack && openEventsStack.length)
-          openEventsStack.peekLast()._addStep(event);
-        break;
-
-      case phase.NestableAsyncEnd:
-        if (!openEventsStack || !openEventsStack.length)
-          break;
-        const top = openEventsStack.pop();
-        if (top.name !== event.name) {
-          console.error(
-              `Begin/end event mismatch for nestable async event, ${top.name} vs. ${event.name}, key: ${key}`);
-          break;
-        }
-        top._addStep(event);
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addAsyncEvent(event) {
-    const phase = SDK.TracingModel.Phase;
-    const key = event.categoriesString + '.' + event.name + '.' + event.id;
-    let asyncEvent = this._openAsyncEvents.get(key);
-
-    if (event.phase === phase.AsyncBegin) {
-      if (asyncEvent) {
-        console.error(`Event ${event.name} has already been started`);
-        return;
-      }
-      asyncEvent = new SDK.TracingModel.AsyncEvent(event);
-      this._openAsyncEvents.set(key, asyncEvent);
-      event.thread._addAsyncEvent(asyncEvent);
-      return;
-    }
-    if (!asyncEvent) {
-      // Quietly ignore stray async events, we're probably too late for the start.
-      return;
-    }
-    if (event.phase === phase.AsyncEnd) {
-      asyncEvent._addStep(event);
-      this._openAsyncEvents.delete(key);
-      return;
-    }
-    if (event.phase === phase.AsyncStepInto || event.phase === phase.AsyncStepPast) {
-      const lastStep = asyncEvent.steps.peekLast();
-      if (lastStep.phase !== phase.AsyncBegin && lastStep.phase !== event.phase) {
-        console.assert(
-            false, 'Async event step phase mismatch: ' + lastStep.phase + ' at ' + lastStep.startTime + ' vs. ' +
-                event.phase + ' at ' + event.startTime);
-        return;
-      }
-      asyncEvent._addStep(event);
-      return;
-    }
-    console.assert(false, 'Invalid async event phase');
-  }
-
-  /**
-   * @return {!SDK.BackingStorage}
-   */
-  backingStorage() {
-    return this._backingStorage;
-  }
-
-  /**
-   * @param {string} str
-   * @return {!Set<string>}
-   */
-  _parsedCategoriesForString(str) {
-    let parsedCategories = this._parsedCategories.get(str);
-    if (!parsedCategories) {
-      parsedCategories = new Set(str.split(','));
-      this._parsedCategories.set(str, parsedCategories);
-    }
-    return parsedCategories;
-  }
-};
-
-/**
- * @enum {string}
- */
-SDK.TracingModel.Phase = {
-  Begin: 'B',
-  End: 'E',
-  Complete: 'X',
-  Instant: 'I',
-  AsyncBegin: 'S',
-  AsyncStepInto: 'T',
-  AsyncStepPast: 'p',
-  AsyncEnd: 'F',
-  NestableAsyncBegin: 'b',
-  NestableAsyncEnd: 'e',
-  NestableAsyncInstant: 'n',
-  FlowBegin: 's',
-  FlowStep: 't',
-  FlowEnd: 'f',
-  Metadata: 'M',
-  Counter: 'C',
-  Sample: 'P',
-  CreateObject: 'N',
-  SnapshotObject: 'O',
-  DeleteObject: 'D'
-};
-
-SDK.TracingModel.MetadataEvent = {
-  ProcessSortIndex: 'process_sort_index',
-  ProcessName: 'process_name',
-  ThreadSortIndex: 'thread_sort_index',
-  ThreadName: 'thread_name'
-};
-
-SDK.TracingModel.TopLevelEventCategory = 'toplevel';
-SDK.TracingModel.DevToolsMetadataEventCategory = 'disabled-by-default-devtools.timeline';
-SDK.TracingModel.DevToolsTimelineEventCategory = 'disabled-by-default-devtools.timeline';
-
-SDK.TracingModel.FrameLifecycleEventCategory = 'cc,devtools';
-
-
-/**
- * @interface
- */
-SDK.BackingStorage = function() {};
-
-SDK.BackingStorage.prototype = {
-  /**
-   * @param {string} string
-   */
-  appendString(string) {},
-
-  /**
-   * @param {string} string
-   * @return {function():!Promise.<?string>}
-   */
-  appendAccessibleString(string) {},
-
-  finishWriting() {},
-
-  reset() {}
-};
-
-/**
- * @unrestricted
- */
-SDK.TracingModel.Event = class {
-  /**
-   * @param {string} categories
-   * @param {string} name
-   * @param {!SDK.TracingModel.Phase} phase
-   * @param {number} startTime
-   * @param {!SDK.TracingModel.Thread} thread
-   */
-  constructor(categories, name, phase, startTime, thread) {
-    /** @type {string} */
-    this.categoriesString = categories;
-    /** @type {!Set<string>} */
-    this._parsedCategories = thread._model._parsedCategoriesForString(categories);
-    /** @type {string} */
-    this.name = name;
-    /** @type {!SDK.TracingModel.Phase} */
-    this.phase = phase;
-    /** @type {number} */
-    this.startTime = startTime;
-    /** @type {!SDK.TracingModel.Thread} */
-    this.thread = thread;
-    /** @type {!Object} */
-    this.args = {};
-
-    /** @type {number} */
-    this.selfTime = 0;
-  }
-
-  /**
-   * @param {!SDK.TracingManager.EventPayload} payload
-   * @param {!SDK.TracingModel.Thread} thread
-   * @return {!SDK.TracingModel.Event}
-   */
-  static fromPayload(payload, thread) {
-    const event = new SDK.TracingModel.Event(
-        payload.cat, payload.name, /** @type {!SDK.TracingModel.Phase} */ (payload.ph), payload.ts / 1000, thread);
-    if (payload.args)
-      event.addArgs(payload.args);
-    else
-      console.error('Missing mandatory event argument \'args\' at ' + payload.ts / 1000);
-    if (typeof payload.dur === 'number')
-      event.setEndTime((payload.ts + payload.dur) / 1000);
-    const id = SDK.TracingModel._extractId(payload);
-    if (typeof id !== 'undefined')
-      event.id = id;
-    if (payload.bind_id)
-      event.bind_id = payload.bind_id;
-
-    return event;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} a
-   * @param {!SDK.TracingModel.Event} b
-   * @return {number}
-   */
-  static compareStartTime(a, b) {
-    return a.startTime - b.startTime;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} a
-   * @param {!SDK.TracingModel.Event} b
-   * @return {number}
-   */
-  static compareStartAndEndTime(a, b) {
-    return a.startTime - b.startTime || (b.endTime !== undefined && a.endTime !== undefined && b.endTime - a.endTime) ||
-        0;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} a
-   * @param {!SDK.TracingModel.Event} b
-   * @return {number}
-   */
-  static orderedCompareStartTime(a, b) {
-    // Array.mergeOrdered coalesces objects if comparator returns 0.
-    // To change this behavior this comparator return -1 in the case events
-    // startTime's are equal, so both events got placed into the result array.
-    return a.startTime - b.startTime || a.ordinal - b.ordinal || -1;
-  }
-
-  /**
-   * @param {string} categoryName
-   * @return {boolean}
-   */
-  hasCategory(categoryName) {
-    return this._parsedCategories.has(categoryName);
-  }
-
-  /**
-   * @param {number} endTime
-   */
-  setEndTime(endTime) {
-    if (endTime < this.startTime) {
-      console.assert(false, 'Event out of order: ' + this.name);
-      return;
-    }
-    this.endTime = endTime;
-    this.duration = endTime - this.startTime;
-  }
-
-  /**
-   * @param {!Object} args
-   */
-  addArgs(args) {
-    // Shallow copy args to avoid modifying original payload which may be saved to file.
-    for (const name in args) {
-      if (name in this.args)
-        console.error('Same argument name (' + name + ') is used for begin and end phases of ' + this.name);
-      this.args[name] = args[name];
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} endEvent
-   */
-  _complete(endEvent) {
-    if (endEvent.args)
-      this.addArgs(endEvent.args);
-    else
-      console.error('Missing mandatory event argument \'args\' at ' + endEvent.startTime);
-    this.setEndTime(endEvent.startTime);
-  }
-
-  /**
-   * @param {?function():!Promise.<?string>} backingStorage
-   */
-  _setBackingStorage(backingStorage) {
-  }
-};
-
-SDK.TracingModel.ObjectSnapshot = class extends SDK.TracingModel.Event {
-  /**
-   * @param {string} category
-   * @param {string} name
-   * @param {number} startTime
-   * @param {!SDK.TracingModel.Thread} thread
-   */
-  constructor(category, name, startTime, thread) {
-    super(category, name, SDK.TracingModel.Phase.SnapshotObject, startTime, thread);
-    /** @type {?function():!Promise<?string>} */
-    this._backingStorage = null;
-    /** @type {string} */
-    this.id;
-    /** @type {?Promise<?>} */
-    this._objectPromise = null;
-  }
-
-  /**
-   * @param {!SDK.TracingManager.EventPayload} payload
-   * @param {!SDK.TracingModel.Thread} thread
-   * @return {!SDK.TracingModel.ObjectSnapshot}
-   */
-  static fromPayload(payload, thread) {
-    const snapshot = new SDK.TracingModel.ObjectSnapshot(payload.cat, payload.name, payload.ts / 1000, thread);
-    const id = SDK.TracingModel._extractId(payload);
-    if (typeof id !== 'undefined')
-      snapshot.id = id;
-    if (!payload.args || !payload.args['snapshot']) {
-      console.error('Missing mandatory \'snapshot\' argument at ' + payload.ts / 1000);
-      return snapshot;
-    }
-    if (payload.args)
-      snapshot.addArgs(payload.args);
-    return snapshot;
-  }
-
-  /**
-   * @param {function(?)} callback
-   */
-  requestObject(callback) {
-    const snapshot = this.args['snapshot'];
-    if (snapshot) {
-      callback(snapshot);
-      return;
-    }
-    this._backingStorage().then(onRead, callback.bind(null, null));
-    /**
-     * @param {?string} result
-     */
-    function onRead(result) {
-      if (!result) {
-        callback(null);
-        return;
-      }
-      try {
-        const payload = JSON.parse(result);
-        callback(payload['args']['snapshot']);
-      } catch (e) {
-        Common.console.error('Malformed event data in backing storage');
-        callback(null);
-      }
-    }
-  }
-
-  /**
-   * @return {!Promise<?>}
-   */
-  objectPromise() {
-    if (!this._objectPromise)
-      this._objectPromise = new Promise(this.requestObject.bind(this));
-    return this._objectPromise;
-  }
-
-  /**
-   * @override
-   * @param {?function():!Promise.<?>} backingStorage
-   */
-  _setBackingStorage(backingStorage) {
-    if (!backingStorage)
-      return;
-    this._backingStorage = backingStorage;
-    this.args = {};
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SDK.TracingModel.AsyncEvent = class extends SDK.TracingModel.Event {
-  /**
-   * @param {!SDK.TracingModel.Event} startEvent
-   */
-  constructor(startEvent) {
-    super(startEvent.categoriesString, startEvent.name, startEvent.phase, startEvent.startTime, startEvent.thread);
-    this.addArgs(startEvent.args);
-    this.steps = [startEvent];
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addStep(event) {
-    this.steps.push(event);
-    if (event.phase === SDK.TracingModel.Phase.AsyncEnd || event.phase === SDK.TracingModel.Phase.NestableAsyncEnd) {
-      this.setEndTime(event.startTime);
-      // FIXME: ideally, we shouldn't do this, but this makes the logic of converting
-      // async console events to sync ones much simpler.
-      this.steps[0].setEndTime(event.startTime);
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-SDK.TracingModel.ProfileEventsGroup = class {
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  constructor(event) {
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this.children = [event];
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addChild(event) {
-    this.children.push(event);
-  }
-};
-
-SDK.TracingModel.NamedObject = class {
-  /**
-   * @param {!SDK.TracingModel} model
-   * @param {number} id
-   */
-  constructor(model, id) {
-    this._model = model;
-    this._id = id;
-    this._name = '';
-    this._sortIndex = 0;
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingModel.NamedObject>} array
-   */
-  static _sort(array) {
-    /**
-     * @param {!SDK.TracingModel.NamedObject} a
-     * @param {!SDK.TracingModel.NamedObject} b
-     */
-    function comparator(a, b) {
-      return a._sortIndex !== b._sortIndex ? a._sortIndex - b._sortIndex : a.name().localeCompare(b.name());
-    }
-    return array.sort(comparator);
-  }
-
-  /**
-   * @param {string} name
-   */
-  _setName(name) {
-    this._name = name;
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._name;
-  }
-
-  /**
-   * @param {number} sortIndex
-   */
-  _setSortIndex(sortIndex) {
-    this._sortIndex = sortIndex;
-  }
-};
-
-SDK.TracingModel.Process = class extends SDK.TracingModel.NamedObject {
-  /**
-   * @param {!SDK.TracingModel} model
-   * @param {number} id
-   */
-  constructor(model, id) {
-    super(model, id);
-    /** @type {!Map<number, !SDK.TracingModel.Thread>} */
-    this._threads = new Map();
-    this._threadByName = new Map();
-  }
-
-  /**
-   * @return {number}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @param {number} id
-   * @return {!SDK.TracingModel.Thread}
-   */
-  threadById(id) {
-    let thread = this._threads.get(id);
-    if (!thread) {
-      thread = new SDK.TracingModel.Thread(this, id);
-      this._threads.set(id, thread);
-    }
-    return thread;
-  }
-
-  /**
-   * @param {string} name
-   * @return {?SDK.TracingModel.Thread}
-   */
-  threadByName(name) {
-    return this._threadByName.get(name) || null;
-  }
-
-  /**
-   * @param {string} name
-   * @param {!SDK.TracingModel.Thread} thread
-   */
-  _setThreadByName(name, thread) {
-    this._threadByName.set(name, thread);
-  }
-
-  /**
-   * @param {!SDK.TracingManager.EventPayload} payload
-   * @return {?SDK.TracingModel.Event} event
-   */
-  _addEvent(payload) {
-    return this.threadById(payload.tid)._addEvent(payload);
-  }
-
-  /**
-   * @return {!Array.<!SDK.TracingModel.Thread>}
-   */
-  sortedThreads() {
-    return SDK.TracingModel.NamedObject._sort(this._threads.valuesArray());
-  }
-};
-
-SDK.TracingModel.Thread = class extends SDK.TracingModel.NamedObject {
-  /**
-   * @param {!SDK.TracingModel.Process} process
-   * @param {number} id
-   */
-  constructor(process, id) {
-    super(process._model, id);
-    this._process = process;
-    this._events = [];
-    this._asyncEvents = [];
-    this._lastTopLevelEvent = null;
-  }
-
-  tracingComplete() {
-    this._asyncEvents.stableSort(SDK.TracingModel.Event.compareStartAndEndTime);
-    this._events.stableSort(SDK.TracingModel.Event.compareStartTime);
-    const phases = SDK.TracingModel.Phase;
-    const stack = [];
-    for (let i = 0; i < this._events.length; ++i) {
-      const e = this._events[i];
-      e.ordinal = i;
-      switch (e.phase) {
-        case phases.End:
-          this._events[i] = null;  // Mark for removal.
-          // Quietly ignore unbalanced close events, they're legit (we could have missed start one).
-          if (!stack.length)
-            continue;
-          const top = stack.pop();
-          if (top.name !== e.name || top.categoriesString !== e.categoriesString) {
-            console.error(
-                'B/E events mismatch at ' + top.startTime + ' (' + top.name + ') vs. ' + e.startTime + ' (' + e.name +
-                ')');
-          } else {
-            top._complete(e);
-          }
-          break;
-        case phases.Begin:
-          stack.push(e);
-          break;
-      }
-    }
-    while (stack.length)
-      stack.pop().setEndTime(this._model.maximumRecordTime());
-    this._events.remove(null, false);
-  }
-
-  /**
-   * @param {!SDK.TracingManager.EventPayload} payload
-   * @return {?SDK.TracingModel.Event} event
-   */
-  _addEvent(payload) {
-    const event = payload.ph === SDK.TracingModel.Phase.SnapshotObject ?
-        SDK.TracingModel.ObjectSnapshot.fromPayload(payload, this) :
-        SDK.TracingModel.Event.fromPayload(payload, this);
-    if (SDK.TracingModel.isTopLevelEvent(event)) {
-      // Discard nested "top-level" events.
-      if (this._lastTopLevelEvent && this._lastTopLevelEvent.endTime > event.startTime)
-        return null;
-      this._lastTopLevelEvent = event;
-    }
-    this._events.push(event);
-    return event;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.AsyncEvent} asyncEvent
-   */
-  _addAsyncEvent(asyncEvent) {
-    this._asyncEvents.push(asyncEvent);
-  }
-
-  /**
-   * @override
-   * @param {string} name
-   */
-  _setName(name) {
-    super._setName(name);
-    this._process._setThreadByName(name, this);
-  }
-
-  /**
-   * @return {number}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @return {!SDK.TracingModel.Process}
-   */
-  process() {
-    return this._process;
-  }
-
-  /**
-   * @return {!Array.<!SDK.TracingModel.Event>}
-   */
-  events() {
-    return this._events;
-  }
-
-  /**
-   * @return {!Array.<!SDK.TracingModel.AsyncEvent>}
-   */
-  asyncEvents() {
-    return this._asyncEvents;
-  }
-};
diff --git a/front_end/sdk/module.json b/front_end/sdk/module.json
deleted file mode 100644
index 7edcfed..0000000
--- a/front_end/sdk/module.json
+++ /dev/null
@@ -1,315 +0,0 @@
-{
-    "dependencies": [
-        "common",
-        "host",
-        "platform",
-        "protocol"
-    ],
-    "extensions": [
-        {
-            "type": "setting",
-            "settingName": "skipStackFramesPattern",
-            "settingType": "regex",
-            "defaultValue": ""
-        },
-        {
-            "type": "setting",
-            "settingName": "skipContentScripts",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Preserve log upon navigation",
-            "settingName": "preserveConsoleLog",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Preserve log upon navigation"
-                },
-                {
-                    "value": false,
-                    "title": "Do not preserve log upon navigation"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Debugger",
-            "settingName": "pauseOnExceptionEnabled",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Pause on exceptions"
-                },
-                {
-                    "value": false,
-                    "title": "Do not pause on exceptions"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "settingName": "pauseOnCaughtException",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Debugger",
-            "title": "Disable JavaScript",
-            "settingName": "javaScriptDisabled",
-            "settingType": "boolean",
-            "storageType": "session",
-            "order": 1,
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Disable JavaScript"
-                },
-                {
-                    "value": false,
-                    "title": "Enable JavaScript"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Debugger",
-            "title": "Disable async stack traces",
-            "settingName": "disableAsyncStackTraces",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "order": 2,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Do not capture async stack traces"
-                },
-                {
-                    "value": false,
-                    "title": "Capture async stack traces"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Debugger",
-            "settingName": "breakpointsActive",
-            "settingType": "boolean",
-            "storageType": "session",
-            "defaultValue": true
-        },
-        {
-            "type": "setting",
-            "category": "Elements",
-            "title": "Show rulers",
-            "settingName": "showMetricsRulers",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Rendering",
-            "settingName": "showPaintRects",
-            "settingType": "boolean",
-            "storageType": "session",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show paint flashing rectangles"
-                },
-                {
-                    "value": false,
-                    "title": "Hide paint flashing rectangles"
-                }
-            ],
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Rendering",
-            "settingName": "showDebugBorders",
-            "settingType": "boolean",
-            "storageType": "session",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show layer borders"
-                },
-                {
-                    "value": false,
-                    "title": "Hide layer borders"
-                }
-            ],
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Rendering",
-            "settingName": "showFPSCounter",
-            "settingType": "boolean",
-            "storageType": "session",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show frames per second (FPS) meter"
-                },
-                {
-                    "value": false,
-                    "title": "Hide frames per second (FPS) meter"
-                }
-            ],
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Rendering",
-            "settingName": "showScrollBottleneckRects",
-            "settingType": "boolean",
-            "storageType": "session",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Show scroll performance bottlenecks"
-                },
-                {
-                    "value": false,
-                    "title": "Hide scroll performance bottlenecks"
-                }
-            ],
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Rendering",
-            "settingName": "emulatedCSSMedia",
-            "settingType": "enum",
-            "storageType": "session",
-            "defaultValue": "",
-            "options": [
-                {
-                    "title": "Do not emulate CSS media type",
-                    "text": "No emulation",
-                    "value": ""
-                },
-                {
-                    "title": "Emulate CSS print media type",
-                    "text": "print",
-                    "value": "print"
-                },
-                {
-                    "title": "Emulate CSS screen media type",
-                    "text": "screen",
-                    "value": "screen"
-                }
-            ],
-            "tags": "query"
-        },
-        {
-            "type": "setting",
-            "category": "Console",
-            "title": "Enable custom formatters",
-            "settingName": "customFormatters",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "setting",
-            "category": "Network",
-            "title": "Enable request blocking",
-            "settingName": "requestBlockingEnabled",
-            "settingType": "boolean",
-            "storageType": "session",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable request blocking"
-                },
-                {
-                    "value": false,
-                    "title": "Disable request blocking"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Network",
-            "title": "Disable cache (while DevTools is open)",
-            "settingName": "cacheDisabled",
-            "settingType": "boolean",
-            "order": 0,
-            "defaultValue": false,
-            "userActionCondition": "hasOtherClients",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Disable cache (while DevTools is open)"
-                },
-                {
-                    "value": false,
-                    "title": "Enable cache"
-                }
-            ]
-        }
-    ],
-    "scripts": [
-        "Target.js",
-        "TargetManager.js",
-        "Connections.js",
-        "ContentProviders.js",
-        "CookieModel.js",
-        "CookieParser.js",
-        "ProfileTreeModel.js",
-        "ServerTiming.js",
-        "CPUProfileDataModel.js",
-        "CPUProfilerModel.js",
-        "CSSMatchedStyles.js",
-        "CSSMedia.js",
-        "CSSMetadata.js",
-        "CSSModel.js",
-        "CSSProperty.js",
-        "CSSRule.js",
-        "CSSStyleDeclaration.js",
-        "CSSStyleSheetHeader.js",
-        "ChildTargetManager.js",
-        "DOMDebuggerModel.js",
-        "DOMModel.js",
-        "DebuggerModel.js",
-        "EmulationModel.js",
-        "LayerTreeBase.js",
-        "LogModel.js",
-        "ServiceWorkerManager.js",
-        "TracingManager.js",
-        "TracingModel.js",
-        "OverlayModel.js",
-        "RuntimeModel.js",
-        "ScreenCaptureModel.js",
-        "Script.js",
-        "ServiceWorkerCacheModel.js",
-        "RemoteObject.js",
-        "Resource.js",
-        "ResourceTreeModel.js",
-        "SecurityOriginManager.js",
-        "SourceMap.js",
-        "SourceMapManager.js",
-        "NetworkManager.js",
-        "NetworkRequest.js",
-        "PaintProfiler.js",
-        "HeapProfilerModel.js",
-        "PerformanceMetricsModel.js",
-        "../SupportedCSSProperties.js",
-        "FilmStripModel.js",
-        "ConsoleModel.js"
-    ],
-    "skip_compilation": [
-        "../SupportedCSSProperties.js"
-    ]
-}
diff --git a/front_end/sdk_test_runner/PageMockTestRunner.js b/front_end/sdk_test_runner/PageMockTestRunner.js
deleted file mode 100644
index a6bf418..0000000
--- a/front_end/sdk_test_runner/PageMockTestRunner.js
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-let id = 0;
-
-function nextId(prefix) {
-  return (prefix || '') + ++id;
-}
-
-SDKTestRunner.connectToPage = function(targetName, pageMock, makeMainTarget) {
-  const mockTarget = SDK.targetManager.createTarget(
-      nextId('mock-target-'), targetName, pageMock.capabilities(), params => pageMock.createConnection(params));
-
-  if (makeMainTarget) {
-    SDK.targetManager._targets = SDK.targetManager._targets.filter(target => target !== mockTarget);
-    SDK.targetManager._targets.unshift(mockTarget);
-  }
-
-  return mockTarget;
-};
-
-SDKTestRunner.PageMock = class {
-  constructor(url) {
-    this._url = url;
-    this._capabilities = SDK.Target.Capability.DOM | SDK.Target.Capability.JS | SDK.Target.Capability.Browser;
-    this._enabledDomains = new Set();
-
-    this._mainFrame =
-        {id: nextId(), loaderId: nextId(), mimeType: 'text/html', securityOrigin: this._url, url: this._url};
-
-    this._executionContexts = [];
-    this._executionContexts.push(this._createExecutionContext(this._mainFrame, false));
-    this._scripts = [];
-    this._scriptContents = new Map();
-
-    this._dispatchMap = {
-      'Debugger.enable': this._debuggerEnable,
-      'Debugger.getScriptSource': this._debuggerGetScriptSource,
-      'Debugger.setBlackboxPatterns': (id, params) => this._sendResponse(id, {}),
-      'Runtime.enable': this._runtimeEnable,
-      'Page.enable': this._pageEnable,
-      'Page.getResourceTree': this._pageGetResourceTree
-    };
-  }
-
-  capabilities() {
-    return this._capabilities;
-  }
-
-  disableDOMCapability() {
-    this._capabilities = this._capabilities & ~SDK.Target.Capability.DOM;
-  }
-
-  createConnection(params) {
-    this._enabledDomains.clear();
-    this._connection = new MockPageConnection(this, params);
-    return this._connection;
-  }
-
-  evalScript(url, content, isContentScript) {
-    const id = nextId();
-    content += '\n//# sourceURL=' + url;
-    this._scriptContents.set(id, content);
-    let context = this._executionContexts.find(context => context.auxData.isDefault !== isContentScript);
-
-    if (!context) {
-      context = this._createExecutionContext(this._mainFrame, isContentScript);
-
-      this._fireEvent('Runtime.executionContextCreated', {context: context});
-    }
-
-    const text = new TextUtils.Text(content);
-
-    const script = {
-      scriptId: id,
-      url: url,
-      startLine: 0,
-      startColumn: 0,
-      endLine: text.lineCount(),
-      endColumn: text.lineAt(text.lineCount()).length - 1,
-      executionContextId: context.id,
-      hash: String.hashCode(content),
-      executionContextAuxData: context.auxData,
-      sourceMapURL: '',
-      hasSourceURL: true,
-      isLiveEdit: false,
-      isModule: false,
-      length: content.length
-    };
-
-    this._scripts.push(script);
-    this._fireEvent('Debugger.scriptParsed', script);
-  }
-
-  reload() {
-    this._fireEvent('Page.frameStartedLoading', {frameId: this._mainFrame.id});
-
-    for (const context of this._executionContexts)
-      this._fireEvent('Runtime.executionContextDestroyed', {executionContextId: context.id});
-
-
-    this._scripts = [];
-    this._scriptContents.clear();
-    this._executionContexts = [];
-    this._fireEvent('Runtime.executionContextsCleared', {});
-    this._executionContexts.push(this._createExecutionContext(this._mainFrame, false));
-
-    for (const context of this._executionContexts)
-      this._fireEvent('Runtime.executionContextCreated', {context: context});
-
-
-    this._fireEvent('Page.frameNavigated', {frame: this._mainFrame});
-
-    this._fireEvent('Page.loadEventFired', {timestamp: Date.now() / 1000});
-
-    this._fireEvent('Page.frameStoppedLoading', {frameId: this._mainFrame.id});
-
-    this._fireEvent('Page.domContentEventFired', {timestamp: Date.now() / 1000});
-  }
-
-  close() {
-    if (this._connection) {
-      this._connection.disconnect();
-      this._connection = null;
-    }
-  }
-
-  _createExecutionContext(frame, isContentScript) {
-    return {
-      id: nextId(),
-
-      auxData: {isDefault: !isContentScript, frameId: frame.id},
-
-      origin: frame.securityOrigin,
-      name: ''
-    };
-  }
-
-  _debuggerEnable(id, params) {
-    this._enabledDomains.add('Debugger');
-    this._sendResponse(id, {});
-
-    for (const script of this._scripts)
-      this._fireEvent('Debugger.scriptParsed', script);
-  }
-
-  _debuggerGetScriptSource(id, params) {
-    if (!this._scriptContents.has(params.scriptId)) {
-      this._sendResponse(id, undefined, {message: 'Can\'t get script content for id ' + params.scriptId, code: 1});
-
-      return;
-    }
-
-    const result = {scriptSource: this._scriptContents.get(params.scriptId)};
-
-    this._sendResponse(id, result);
-  }
-
-  _runtimeEnable(id, params) {
-    this._enabledDomains.add('Runtime');
-    this._sendResponse(id, {});
-
-    for (const context of this._executionContexts)
-      this._fireEvent('Runtime.executionContextCreated', {context: context});
-  }
-
-  _pageEnable(id, params) {
-    this._enabledDomains.add('Page');
-    this._sendResponse(id, {});
-  }
-
-  _pageGetResourceTree(id, params) {
-    const result = {frameTree: {frame: this._mainFrame, resources: []}};
-
-    this._sendResponse(id, result);
-  }
-
-  _isSupportedDomain(methodName) {
-    const domain = methodName.split('.')[0];
-
-    if (domain === 'Page')
-      return !!(this._capabilities & SDK.Target.Capability.DOM);
-
-    return true;
-  }
-
-  _dispatch(id, methodName, params, message) {
-    const handler = (this._isSupportedDomain(methodName) ? this._dispatchMap[methodName] : null);
-
-    if (handler)
-      return handler.call(this, id, params);
-
-    this._sendResponse(
-        id, undefined,
-        {message: 'Can\'t handle command ' + methodName, code: Protocol.InspectorBackend.DevToolsStubErrorCode});
-  }
-
-  _sendResponse(id, result, error) {
-    const message = {id: id, result: result, error: error};
-
-    this._connection.sendMessageToDevTools(message);
-  }
-
-  _fireEvent(methodName, params) {
-    const domain = methodName.split('.')[0];
-
-    if (!this._enabledDomains.has(domain))
-      return;
-
-    const message = {method: methodName, params: params};
-
-    this._connection.sendMessageToDevTools(message);
-  }
-};
-
-MockPageConnection = class {
-  constructor(page, params) {
-    this._page = page;
-    this._onMessage = params.onMessage;
-    this._onDisconnect = params.onDisconnect;
-  }
-
-  sendMessageToDevTools(message) {
-    setTimeout(() => this._onMessage.call(null, JSON.stringify(message)), 0);
-  }
-
-  sendMessage(message) {
-    const json = JSON.parse(message);
-    this._page._dispatch(json.id, json.method, json.params, message);
-  }
-
-  disconnect() {
-    this._onDisconnect.call(null, 'force disconnect');
-    this._onDisconnect = null;
-    this._onMessage = null;
-    return Promise.resolve();
-  }
-};
diff --git a/front_end/sdk_test_runner/module.json b/front_end/sdk_test_runner/module.json
deleted file mode 100644
index fcb1faa..0000000
--- a/front_end/sdk_test_runner/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": [
-        "sdk",
-        "test_runner"
-    ],
-    "scripts": [
-        "PageMockTestRunner.js"
-    ],
-    "skip_compilation": [
-        "PageMockTestRunner.js"
-    ]
-}
diff --git a/front_end/search/SearchConfig.js b/front_end/search/SearchConfig.js
deleted file mode 100644
index 0ba3f5c..0000000
--- a/front_end/search/SearchConfig.js
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Workspace.ProjectSearchConfig}
- */
-Search.SearchConfig = class {
-  /**
-   * @param {string} query
-   * @param {boolean} ignoreCase
-   * @param {boolean} isRegex
-   */
-  constructor(query, ignoreCase, isRegex) {
-    this._query = query;
-    this._ignoreCase = ignoreCase;
-    this._isRegex = isRegex;
-    this._parse();
-  }
-
-  /**
-   * @param {{query: string, ignoreCase: boolean, isRegex: boolean}} object
-   * @return {!Search.SearchConfig}
-   */
-  static fromPlainObject(object) {
-    return new Search.SearchConfig(object.query, object.ignoreCase, object.isRegex);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  query() {
-    return this._query;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ignoreCase() {
-    return this._ignoreCase;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isRegex() {
-    return this._isRegex;
-  }
-
-  /**
-   * @return {{query: string, ignoreCase: boolean, isRegex: boolean}}
-   */
-  toPlainObject() {
-    return {query: this.query(), ignoreCase: this.ignoreCase(), isRegex: this.isRegex()};
-  }
-
-  _parse() {
-    // Inside double quotes: any symbol except double quote and backslash or any symbol escaped with a backslash.
-    const quotedPattern = /"([^\\"]|\\.)+"/;
-    // A word is a sequence of any symbols except space and backslash or any symbols escaped with a backslash, that does not start with file:.
-    const unquotedWordPattern = /(\s*(?!-?f(ile)?:)[^\\ ]|\\.)+/;
-    const unquotedPattern = unquotedWordPattern.source + '(\\s+' + unquotedWordPattern.source + ')*';
-
-
-    const pattern = [
-      '(\\s*' + Search.SearchConfig.FilePatternRegex.source + '\\s*)',
-      '(' + quotedPattern.source + ')',
-      '(' + unquotedPattern + ')',
-    ].join('|');
-    const regexp = new RegExp(pattern, 'g');
-    const queryParts = this._query.match(regexp) || [];
-    /**
-     * @type {!Array.<!Search.SearchConfig.QueryTerm>}
-     */
-    this._fileQueries = [];
-
-    /**
-     * @type {!Array.<string>}
-     */
-    this._queries = [];
-
-    for (let i = 0; i < queryParts.length; ++i) {
-      const queryPart = queryParts[i];
-      if (!queryPart)
-        continue;
-      const fileQuery = this._parseFileQuery(queryPart);
-      if (fileQuery) {
-        this._fileQueries.push(fileQuery);
-        /** @type {!Array.<!Search.SearchConfig.RegexQuery>} */
-        this._fileRegexQueries = this._fileRegexQueries || [];
-        this._fileRegexQueries.push(
-            {regex: new RegExp(fileQuery.text, this.ignoreCase ? 'i' : ''), isNegative: fileQuery.isNegative});
-        continue;
-      }
-      if (this._isRegex) {
-        this._queries.push(queryPart);
-        continue;
-      }
-      if (queryPart.startsWith('"')) {
-        if (!queryPart.endsWith('"'))
-          continue;
-        this._queries.push(this._parseQuotedQuery(queryPart));
-        continue;
-      }
-      this._queries.push(this._parseUnquotedQuery(queryPart));
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} filePath
-   * @return {boolean}
-   */
-  filePathMatchesFileQuery(filePath) {
-    if (!this._fileRegexQueries)
-      return true;
-    for (let i = 0; i < this._fileRegexQueries.length; ++i) {
-      if (!!filePath.match(this._fileRegexQueries[i].regex) === this._fileRegexQueries[i].isNegative)
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<string>}
-   */
-  queries() {
-    return this._queries;
-  }
-
-  _parseUnquotedQuery(query) {
-    return query.replace(/\\(.)/g, '$1');
-  }
-
-  _parseQuotedQuery(query) {
-    return query.substring(1, query.length - 1).replace(/\\(.)/g, '$1');
-  }
-
-  /**
-   * @param {string} query
-   * @return {?Search.SearchConfig.QueryTerm}
-   */
-  _parseFileQuery(query) {
-    const match = query.match(Search.SearchConfig.FilePatternRegex);
-    if (!match)
-      return null;
-    const isNegative = !!match[1];
-    query = match[3];
-    let result = '';
-    for (let i = 0; i < query.length; ++i) {
-      const char = query[i];
-      if (char === '*') {
-        result += '.*';
-      } else if (char === '\\') {
-        ++i;
-        const nextChar = query[i];
-        if (nextChar === ' ')
-          result += ' ';
-      } else {
-        if (String.regexSpecialCharacters().indexOf(query.charAt(i)) !== -1)
-          result += '\\';
-        result += query.charAt(i);
-      }
-    }
-    return new Search.SearchConfig.QueryTerm(result, isNegative);
-  }
-};
-
-// After file: prefix: any symbol except space and backslash or any symbol escaped with a backslash.
-Search.SearchConfig.FilePatternRegex = /(-)?f(ile)?:((?:[^\\ ]|\\.)+)/;
-
-/** @typedef {!{regex: !RegExp, isNegative: boolean}} */
-Search.SearchConfig.RegexQuery;
-
-Search.SearchConfig.QueryTerm = class {
-  /**
-   * @param {string} text
-   * @param {boolean} isNegative
-   */
-  constructor(text, isNegative) {
-    this.text = text;
-    this.isNegative = isNegative;
-  }
-};
-
-/**
- * @interface
- */
-Search.SearchResult = function() {};
-
-Search.SearchResult.prototype = {
-  /**
-   * @return {string}
-   */
-  label() {},
-
-  /**
-   * @return {string}
-   */
-  description() {},
-
-  /**
-   * @return {number}
-   */
-  matchesCount() {},
-
-  /**
-   * @param {number} index
-   * @return {string}
-   */
-  matchLabel(index) {},
-
-  /**
-   * @param {number} index
-   * @return {string}
-   */
-  matchLineContent(index) {},
-
-  /**
-   * @param {number} index
-   * @return {!Object}
-   */
-  matchRevealable(index) {}
-};
-
-/**
- * @interface
- */
-Search.SearchScope = function() {};
-
-Search.SearchScope.prototype = {
-  /**
-   * @param {!Search.SearchConfig} searchConfig
-   * @param {!Common.Progress} progress
-   * @param {function(!Search.SearchResult)} searchResultCallback
-   * @param {function(boolean)} searchFinishedCallback
-   */
-  performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) {},
-
-  /**
-   * @param {!Common.Progress} progress
-   */
-  performIndexing(progress) {},
-
-  stopSearch() {}
-};
diff --git a/front_end/search/SearchResultsPane.js b/front_end/search/SearchResultsPane.js
deleted file mode 100644
index 47030ca..0000000
--- a/front_end/search/SearchResultsPane.js
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Search.SearchResultsPane = class extends UI.VBox {
-  /**
-   * @param {!Search.SearchConfig} searchConfig
-   */
-  constructor(searchConfig) {
-    super(true);
-    this._searchConfig = searchConfig;
-
-    /** @type {!Array<!Search.SearchResult>} */
-    this._searchResults = [];
-    this._treeOutline = new UI.TreeOutlineInShadow();
-    this._treeOutline.hideOverflow();
-    this._treeOutline.registerRequiredCSS('search/searchResultsPane.css');
-    this.contentElement.appendChild(this._treeOutline.element);
-
-    this._matchesExpandedCount = 0;
-  }
-
-  /**
-   * @param {!Search.SearchResult} searchResult
-   */
-  addSearchResult(searchResult) {
-    this._searchResults.push(searchResult);
-    this._addTreeElement(searchResult);
-  }
-
-  /**
-   * @param {!Search.SearchResult} searchResult
-   */
-  _addTreeElement(searchResult) {
-    const treeElement = new Search.SearchResultsPane.SearchResultsTreeElement(this._searchConfig, searchResult);
-    this._treeOutline.appendChild(treeElement);
-    // Expand until at least a certain number of matches is expanded.
-    if (this._matchesExpandedCount < Search.SearchResultsPane._matchesExpandedByDefault)
-      treeElement.expand();
-    this._matchesExpandedCount += searchResult.matchesCount();
-  }
-};
-
-Search.SearchResultsPane._matchesExpandedByDefault = 20;
-Search.SearchResultsPane._matchesShownAtOnce = 20;
-
-Search.SearchResultsPane.SearchResultsTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Search.SearchConfig} searchConfig
-   * @param {!Search.SearchResult} searchResult
-   */
-  constructor(searchConfig, searchResult) {
-    super('', true);
-    this._searchConfig = searchConfig;
-    this._searchResult = searchResult;
-    this._initialized = false;
-
-    this.toggleOnClick = true;
-    this.selectable = false;
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    if (this._initialized)
-      return;
-
-    this._updateMatchesUI();
-    this._initialized = true;
-  }
-
-  _updateMatchesUI() {
-    this.removeChildren();
-    const toIndex = Math.min(this._searchResult.matchesCount(), Search.SearchResultsPane._matchesShownAtOnce);
-    if (toIndex < this._searchResult.matchesCount()) {
-      this._appendSearchMatches(0, toIndex - 1);
-      this._appendShowMoreMatchesElement(toIndex - 1);
-    } else {
-      this._appendSearchMatches(0, toIndex);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this._updateSearchMatches();
-  }
-
-  _updateSearchMatches() {
-    this.listItemElement.classList.add('search-result');
-
-    const fileNameSpan = span(this._searchResult.label(), 'search-result-file-name');
-    fileNameSpan.appendChild(span('\u2014', 'search-result-dash'));
-    fileNameSpan.appendChild(span(this._searchResult.description(), 'search-result-qualifier'));
-
-    this.tooltip = this._searchResult.description();
-    this.listItemElement.appendChild(fileNameSpan);
-    const matchesCountSpan = createElement('span');
-    matchesCountSpan.className = 'search-result-matches-count';
-
-    matchesCountSpan.textContent = `${this._searchResult.matchesCount()}`;
-
-    this.listItemElement.appendChild(matchesCountSpan);
-    if (this.expanded)
-      this._updateMatchesUI();
-
-    /**
-     * @param {string} text
-     * @param {string} className
-     * @return {!Element}
-     */
-    function span(text, className) {
-      const span = createElement('span');
-      span.className = className;
-      span.textContent = text;
-      return span;
-    }
-  }
-
-  /**
-   * @param {number} fromIndex
-   * @param {number} toIndex
-   */
-  _appendSearchMatches(fromIndex, toIndex) {
-    const searchResult = this._searchResult;
-
-    const queries = this._searchConfig.queries();
-    const regexes = [];
-    for (let i = 0; i < queries.length; ++i)
-      regexes.push(createSearchRegex(queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex()));
-
-    for (let i = fromIndex; i < toIndex; ++i) {
-      const lineContent = searchResult.matchLineContent(i).trim();
-      let matchRanges = [];
-      for (let j = 0; j < regexes.length; ++j)
-        matchRanges = matchRanges.concat(this._regexMatchRanges(lineContent, regexes[j]));
-
-      const anchor = Components.Linkifier.linkifyRevealable(searchResult.matchRevealable(i), '');
-      anchor.classList.add('search-match-link');
-      const lineNumberSpan = createElement('span');
-      lineNumberSpan.classList.add('search-match-line-number');
-      lineNumberSpan.textContent = searchResult.matchLabel(i);
-      anchor.appendChild(lineNumberSpan);
-
-      const contentSpan = this._createContentSpan(lineContent, matchRanges);
-      anchor.appendChild(contentSpan);
-
-      const searchMatchElement = new UI.TreeElement();
-      searchMatchElement.selectable = false;
-      this.appendChild(searchMatchElement);
-      searchMatchElement.listItemElement.className = 'search-match';
-      searchMatchElement.listItemElement.appendChild(anchor);
-      searchMatchElement.tooltip = lineContent;
-    }
-  }
-
-  /**
-   * @param {number} startMatchIndex
-   */
-  _appendShowMoreMatchesElement(startMatchIndex) {
-    const matchesLeftCount = this._searchResult.matchesCount() - startMatchIndex;
-    const showMoreMatchesText = Common.UIString('Show %d more', matchesLeftCount);
-    const showMoreMatchesTreeElement = new UI.TreeElement(showMoreMatchesText);
-    this.appendChild(showMoreMatchesTreeElement);
-    showMoreMatchesTreeElement.listItemElement.classList.add('show-more-matches');
-    showMoreMatchesTreeElement.onselect =
-        this._showMoreMatchesElementSelected.bind(this, showMoreMatchesTreeElement, startMatchIndex);
-  }
-
-  /**
-   * @param {string} lineContent
-   * @param {!Array.<!TextUtils.SourceRange>} matchRanges
-   * @return {!Element}
-   */
-  _createContentSpan(lineContent, matchRanges) {
-    let trimBy = 0;
-    if (matchRanges.length > 0 && matchRanges[0].offset > 20)
-      trimBy = 15;
-    lineContent = lineContent.substring(trimBy, 1000 + trimBy);
-    if (trimBy) {
-      matchRanges = matchRanges.map(range => new TextUtils.SourceRange(range.offset - trimBy + 1, range.length));
-      lineContent = '\u2026' + lineContent;
-    }
-    const contentSpan = createElement('span');
-    contentSpan.className = 'search-match-content';
-    contentSpan.textContent = lineContent;
-    UI.highlightRangesWithStyleClass(contentSpan, matchRanges, 'highlighted-match');
-    return contentSpan;
-  }
-
-  /**
-   * @param {string} lineContent
-   * @param {!RegExp} regex
-   * @return {!Array.<!TextUtils.SourceRange>}
-   */
-  _regexMatchRanges(lineContent, regex) {
-    regex.lastIndex = 0;
-    let match;
-    const matchRanges = [];
-    while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
-      matchRanges.push(new TextUtils.SourceRange(match.index, match[0].length));
-
-    return matchRanges;
-  }
-
-  /**
-   * @param {!UI.TreeElement} showMoreMatchesTreeElement
-   * @param {number} startMatchIndex
-   * @return {boolean}
-   */
-  _showMoreMatchesElementSelected(showMoreMatchesTreeElement, startMatchIndex) {
-    this.removeChild(showMoreMatchesTreeElement);
-    this._appendSearchMatches(startMatchIndex, this._searchResult.matchesCount());
-    return false;
-  }
-};
diff --git a/front_end/search/SearchView.js b/front_end/search/SearchView.js
deleted file mode 100644
index 4e8c5dd..0000000
--- a/front_end/search/SearchView.js
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Search.SearchView = class extends UI.VBox {
-  /**
-   * @param {string} settingKey
-   */
-  constructor(settingKey) {
-    super(true);
-    this.setMinimumSize(0, 40);
-    this.registerRequiredCSS('search/searchView.css');
-
-    this._focusOnShow = false;
-    this._isIndexing = false;
-    this._searchId = 1;
-    this._searchMatchesCount = 0;
-    this._searchResultsCount = 0;
-    this._nonEmptySearchResultsCount = 0;
-    /** @type {?UI.Widget} */
-    this._searchingView = null;
-    /** @type {?UI.Widget} */
-    this._notFoundView = null;
-    /** @type {?Search.SearchConfig} */
-    this._searchConfig = null;
-    /** @type {?Search.SearchConfig} */
-    this._pendingSearchConfig = null;
-    /** @type {?Search.SearchResultsPane} */
-    this._searchResultsPane = null;
-    /** @type {?UI.ProgressIndicator} */
-    this._progressIndicator = null;
-    /** @type {?UI.Widget} */
-    this._visiblePane = null;
-
-    this.contentElement.classList.add('search-view');
-
-    this._searchPanelElement = this.contentElement.createChild('div', 'search-drawer-header');
-    this._searchPanelElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
-
-    this._searchResultsElement = this.contentElement.createChild('div');
-    this._searchResultsElement.className = 'search-results';
-
-    const searchContainer = createElement('div');
-    searchContainer.style.flex = 'auto';
-    searchContainer.style.justifyContent = 'start';
-    searchContainer.style.maxWidth = '300px';
-    this._search = UI.HistoryInput.create();
-    searchContainer.appendChild(this._search);
-    this._search.placeholder = Common.UIString('Search');
-    this._search.setAttribute('type', 'text');
-    this._search.setAttribute('results', '0');
-    this._search.setAttribute('size', 42);
-    const searchItem = new UI.ToolbarItem(searchContainer);
-
-    const toolbar = new UI.Toolbar('search-toolbar', this._searchPanelElement);
-    this._matchCaseButton = Search.SearchView._appendToolbarToggle(toolbar, 'Aa', Common.UIString('Match Case'));
-    this._regexButton =
-        Search.SearchView._appendToolbarToggle(toolbar, '.*', Common.UIString('Use Regular Expression'));
-    toolbar.appendToolbarItem(searchItem);
-    const refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    const clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
-    toolbar.appendToolbarItem(refreshButton);
-    toolbar.appendToolbarItem(clearButton);
-    refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._onAction.bind(this));
-    clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
-      this._resetSearch();
-      this._onSearchInputClear();
-    });
-
-    const searchStatusBarElement = this.contentElement.createChild('div', 'search-toolbar-summary');
-    this._searchMessageElement = searchStatusBarElement.createChild('div', 'search-message');
-    this._searchProgressPlaceholderElement = searchStatusBarElement.createChild('div', 'flex-centered');
-    this._searchResultsMessageElement = searchStatusBarElement.createChild('div', 'search-message');
-
-    this._advancedSearchConfig = Common.settings.createLocalSetting(
-        settingKey + 'SearchConfig', new Search.SearchConfig('', true, false).toPlainObject());
-
-    this._load();
-    /** @type {?Search.SearchScope} */
-    this._searchScope = null;
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   * @param {string} text
-   * @param {string} tooltip
-   * @return {!UI.ToolbarToggle}
-   */
-  static _appendToolbarToggle(toolbar, text, tooltip) {
-    const toggle = new UI.ToolbarToggle(tooltip);
-    toggle.setText(text);
-    toggle.addEventListener(UI.ToolbarButton.Events.Click, () => toggle.setToggled(!toggle.toggled()));
-    toolbar.appendToolbarItem(toggle);
-    return toggle;
-  }
-
-  /**
-   * @return {!Search.SearchConfig}
-   */
-  _buildSearchConfig() {
-    return new Search.SearchConfig(this._search.value, !this._matchCaseButton.toggled(), this._regexButton.toggled());
-  }
-
-  /**
-   * @protected
-   * @param {string} queryCandidate
-   * @param {boolean=} searchImmediately
-   */
-  async toggle(queryCandidate, searchImmediately) {
-    if (queryCandidate)
-      this._search.value = queryCandidate;
-    if (this.isShowing())
-      this.focus();
-    else
-      this._focusOnShow = true;
-
-    this._initScope();
-    if (searchImmediately)
-      this._onAction();
-    else
-      this._startIndexing();
-  }
-
-  /**
-   * @protected
-   * @return {!Search.SearchScope}
-   */
-  createScope() {
-    throw new Error('Not implemented');
-  }
-
-  _initScope() {
-    this._searchScope = this.createScope();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._focusOnShow) {
-      this.focus();
-      this._focusOnShow = false;
-    }
-  }
-
-  _onIndexingFinished() {
-    const finished = !this._progressIndicator.isCanceled();
-    this._progressIndicator.done();
-    this._progressIndicator = null;
-    this._isIndexing = false;
-    this._indexingFinished(finished);
-    if (!finished)
-      this._pendingSearchConfig = null;
-    if (!this._pendingSearchConfig)
-      return;
-    const searchConfig = this._pendingSearchConfig;
-    this._pendingSearchConfig = null;
-    this._innerStartSearch(searchConfig);
-  }
-
-  _startIndexing() {
-    this._isIndexing = true;
-    if (this._progressIndicator)
-      this._progressIndicator.done();
-    this._progressIndicator = new UI.ProgressIndicator();
-    this._searchMessageElement.textContent = Common.UIString('Indexing\u2026');
-    this._progressIndicator.show(this._searchProgressPlaceholderElement);
-    this._searchScope.performIndexing(
-        new Common.ProgressProxy(this._progressIndicator, this._onIndexingFinished.bind(this)));
-  }
-
-  _onSearchInputClear() {
-    this._search.value = '';
-    this.focus();
-  }
-
-  /**
-   * @param {number} searchId
-   * @param {!Search.SearchResult} searchResult
-   */
-  _onSearchResult(searchId, searchResult) {
-    if (searchId !== this._searchId || !this._progressIndicator)
-      return;
-    if (this._progressIndicator && this._progressIndicator.isCanceled()) {
-      this._onIndexingFinished();
-      return;
-    }
-    this._addSearchResult(searchResult);
-    if (!searchResult.matchesCount())
-      return;
-    if (!this._searchResultsPane) {
-      this._searchResultsPane = new Search.SearchResultsPane(/** @type {!Search.SearchConfig} */ (this._searchConfig));
-      this._showPane(this._searchResultsPane);
-    }
-    this._searchResultsPane.addSearchResult(searchResult);
-  }
-
-  /**
-   * @param {number} searchId
-   * @param {boolean} finished
-   */
-  _onSearchFinished(searchId, finished) {
-    if (searchId !== this._searchId || !this._progressIndicator)
-      return;
-    if (!this._searchResultsPane)
-      this._nothingFound();
-    this._searchFinished(finished);
-    this._searchConfig = null;
-  }
-
-  /**
-   * @param {!Search.SearchConfig} searchConfig
-   */
-  async _startSearch(searchConfig) {
-    this._resetSearch();
-    ++this._searchId;
-    this._initScope();
-    if (!this._isIndexing)
-      this._startIndexing();
-    this._pendingSearchConfig = searchConfig;
-  }
-
-  _innerStartSearch(searchConfig) {
-    this._searchConfig = searchConfig;
-    if (this._progressIndicator)
-      this._progressIndicator.done();
-    this._progressIndicator = new UI.ProgressIndicator();
-    this._searchStarted(this._progressIndicator);
-    this._searchScope.performSearch(
-        searchConfig, this._progressIndicator, this._onSearchResult.bind(this, this._searchId),
-        this._onSearchFinished.bind(this, this._searchId));
-  }
-
-  _resetSearch() {
-    this._stopSearch();
-    this._showPane(null);
-    this._searchResultsPane = null;
-  }
-
-  _stopSearch() {
-    if (this._progressIndicator && !this._isIndexing)
-      this._progressIndicator.cancel();
-    if (this._searchScope)
-      this._searchScope.stopSearch();
-    this._searchConfig = null;
-  }
-
-  /**
-   * @param {!UI.ProgressIndicator} progressIndicator
-   */
-  _searchStarted(progressIndicator) {
-    this._resetCounters();
-    if (!this._searchingView)
-      this._searchingView = new UI.EmptyWidget(Common.UIString('Searching\u2026'));
-    this._showPane(this._searchingView);
-    this._searchMessageElement.textContent = Common.UIString('Searching\u2026');
-    progressIndicator.show(this._searchProgressPlaceholderElement);
-    this._updateSearchResultsMessage();
-  }
-
-  /**
-   * @param {boolean} finished
-   */
-  _indexingFinished(finished) {
-    this._searchMessageElement.textContent = finished ? '' : Common.UIString('Indexing interrupted.');
-  }
-
-  _updateSearchResultsMessage() {
-    if (this._searchMatchesCount && this._searchResultsCount) {
-      if (this._searchMatchesCount === 1 && this._nonEmptySearchResultsCount === 1) {
-        this._searchResultsMessageElement.textContent = Common.UIString('Found 1 matching line in 1 file.');
-      } else if (this._searchMatchesCount > 1 && this._nonEmptySearchResultsCount === 1) {
-        this._searchResultsMessageElement.textContent =
-            Common.UIString('Found %d matching lines in 1 file.', this._searchMatchesCount);
-      } else {
-        this._searchResultsMessageElement.textContent = Common.UIString(
-            'Found %d matching lines in %d files.', this._searchMatchesCount, this._nonEmptySearchResultsCount);
-      }
-    } else {
-      this._searchResultsMessageElement.textContent = '';
-    }
-  }
-
-  /**
-   * @param {?UI.Widget} panel
-   */
-  _showPane(panel) {
-    if (this._visiblePane)
-      this._visiblePane.detach();
-    if (panel)
-      panel.show(this._searchResultsElement);
-    this._visiblePane = panel;
-  }
-
-  _resetCounters() {
-    this._searchMatchesCount = 0;
-    this._searchResultsCount = 0;
-    this._nonEmptySearchResultsCount = 0;
-  }
-
-  _nothingFound() {
-    if (!this._notFoundView)
-      this._notFoundView = new UI.EmptyWidget(Common.UIString('No matches found.'));
-    this._showPane(this._notFoundView);
-    this._searchResultsMessageElement.textContent = Common.UIString('No matches found.');
-  }
-
-  /**
-   * @param {!Search.SearchResult} searchResult
-   */
-  _addSearchResult(searchResult) {
-    const matchesCount = searchResult.matchesCount();
-    this._searchMatchesCount += matchesCount;
-    this._searchResultsCount++;
-    if (matchesCount)
-      this._nonEmptySearchResultsCount++;
-    this._updateSearchResultsMessage();
-  }
-
-  /**
-   * @param {boolean} finished
-   */
-  _searchFinished(finished) {
-    this._searchMessageElement.textContent =
-        finished ? Common.UIString('Search finished.') : Common.UIString('Search interrupted.');
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._search.focus();
-    this._search.select();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._stopSearch();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    switch (event.keyCode) {
-      case UI.KeyboardShortcut.Keys.Enter.code:
-        this._onAction();
-        break;
-    }
-  }
-
-  _save() {
-    this._advancedSearchConfig.set(this._buildSearchConfig().toPlainObject());
-  }
-
-  _load() {
-    const searchConfig = Search.SearchConfig.fromPlainObject(this._advancedSearchConfig.get());
-    this._search.value = searchConfig.query();
-    this._matchCaseButton.setToggled(!searchConfig.ignoreCase());
-    this._regexButton.setToggled(searchConfig.isRegex());
-  }
-
-  _onAction() {
-    const searchConfig = this._buildSearchConfig();
-    if (!searchConfig.query() || !searchConfig.query().length)
-      return;
-    this._save();
-    this._startSearch(searchConfig);
-  }
-};
diff --git a/front_end/search/module.json b/front_end/search/module.json
deleted file mode 100644
index b9db50d..0000000
--- a/front_end/search/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "dependencies": [
-        "components"
-    ],
-    "scripts": [
-        "SearchView.js",
-        "SearchConfig.js",
-        "SearchResultsPane.js"
-    ],
-    "resources": [
-        "searchResultsPane.css",
-        "searchView.css"
-    ]
-}
diff --git a/front_end/search/searchResultsPane.css b/front_end/search/searchResultsPane.css
deleted file mode 100644
index 5e2a662..0000000
--- a/front_end/search/searchResultsPane.css
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    padding: 0;
-    margin: 0;
-    overflow-y: auto;
-}
-
-.tree-outline {
-    padding: 0;
-}
-
-.tree-outline ol {
-    padding: 0;
-}
-
-.tree-outline li {
-    height: 16px;
-}
-
-li.search-result {
-    cursor: pointer;
-    font-size: 12px;
-    margin-top: 8px;
-    padding: 2px 0 2px 4px;
-    word-wrap: normal;
-    white-space: pre;
-}
-
-li.search-result:hover {
-    background-color: rgba(121, 121, 121, 0.1);
-}
-
-li.search-result .search-result-file-name {
-    color: #222;
-    flex: 1 1;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-}
-
-li.search-result .search-result-matches-count {
-    color: #888;
-    margin: 0 8px;
-}
-
-li.search-result.expanded .search-result-matches-count {
-    display: none;
-}
-
-li.show-more-matches {
-    color: #222;
-    cursor: pointer;
-    margin: 8px 0 0 -4px;
-}
-
-li.show-more-matches:hover {
-    text-decoration: underline;
-}
-
-li.search-match {
-    margin: 2px 0;
-    word-wrap: normal;
-    white-space: pre;
-}
-
-li.search-match::before {
-    display: none;
-}
-
-li.search-match .search-match-line-number {
-    color: rgb(128, 128, 128);
-    text-align: right;
-    vertical-align: top;
-    word-break: normal;
-    padding: 2px 4px 2px 6px;
-    margin-right: 5px;
-}
-
-li.search-match:hover {
-    background-color: rgba(56, 121, 217, 0.1);
-}
-
-li.search-match .highlighted-match {
-    background-color: #F1EA00;
-}
-
-:host-context(.-theme-with-dark-background) li.search-match .highlighted-match {
-    background-color: hsl(133, 100%, 30%) !important;
-}
-
-.tree-outline .devtools-link {
-    text-decoration: none;
-    display: block;
-    flex: auto;
-}
-
-li.search-match .search-match-content {
-    color: #000;
-}
-
-ol.children.expanded {
-    padding-bottom: 4px;
-}
-
-.search-match-link {
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.search-result-qualifier {
-    color: #AAA;
-}
-
-.search-result-dash {
-    color: #AAA;
-    margin: 0 4px;
-}
diff --git a/front_end/search/searchView.css b/front_end/search/searchView.css
deleted file mode 100644
index b428e81..0000000
--- a/front_end/search/searchView.css
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.search-drawer-header {
-    align-items: center;
-    flex-shrink: 0;
-    overflow: hidden;
-}
-
-.search-toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.search-toolbar-summary {
-    background-color: #eee;
-    border-top: 1px solid #ccc;
-    padding-left: 5px;
-    flex: 0 0 19px;
-    display: flex;
-    padding-right: 5px;
-}
-
-.search-toolbar-summary .search-message {
-    padding-top: 2px;
-    padding-left: 1ex;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    overflow: hidden;
-}
-
-.search-view .search-results {
-    overflow-y: auto;
-    display: flex;
-    flex: auto;
-}
-
-.search-view .search-results > div {
-    flex: auto;
-}
diff --git a/front_end/security/SecurityModel.js b/front_end/security/SecurityModel.js
deleted file mode 100644
index 1d1648b..0000000
--- a/front_end/security/SecurityModel.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Security.SecurityModel = class extends SDK.SDKModel {
-  /**
-   * @param {!SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    this._dispatcher = new Security.SecurityDispatcher(this);
-    this._securityAgent = target.securityAgent();
-    target.registerSecurityDispatcher(this._dispatcher);
-    this._securityAgent.enable();
-  }
-
-  /**
-   * @return {!SDK.ResourceTreeModel}
-   */
-  resourceTreeModel() {
-    return /** @type {!SDK.ResourceTreeModel} */ (this.target().model(SDK.ResourceTreeModel));
-  }
-
-  /**
-   * @return {!SDK.NetworkManager}
-   */
-  networkManager() {
-    return /** @type {!SDK.NetworkManager} */ (this.target().model(SDK.NetworkManager));
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} a
-   * @param {!Protocol.Security.SecurityState} b
-   * @return {number}
-   */
-  static SecurityStateComparator(a, b) {
-    let securityStateMap;
-    if (Security.SecurityModel._symbolicToNumericSecurityState) {
-      securityStateMap = Security.SecurityModel._symbolicToNumericSecurityState;
-    } else {
-      securityStateMap = new Map();
-      const ordering = [
-        Protocol.Security.SecurityState.Info, Protocol.Security.SecurityState.Insecure,
-        Protocol.Security.SecurityState.Neutral, Protocol.Security.SecurityState.Secure,
-        // Unknown is max so that failed/cancelled requests don't overwrite the origin security state for successful requests,
-        // and so that failed/cancelled requests appear at the bottom of the origins list.
-        Protocol.Security.SecurityState.Unknown
-      ];
-      for (let i = 0; i < ordering.length; i++)
-        securityStateMap.set(ordering[i], i + 1);
-      Security.SecurityModel._symbolicToNumericSecurityState = securityStateMap;
-    }
-    const aScore = securityStateMap.get(a) || 0;
-    const bScore = securityStateMap.get(b) || 0;
-
-    return aScore - bScore;
-  }
-};
-
-SDK.SDKModel.register(Security.SecurityModel, SDK.Target.Capability.Security, false);
-
-/** @enum {symbol} */
-Security.SecurityModel.Events = {
-  SecurityStateChanged: Symbol('SecurityStateChanged')
-};
-
-
-/**
- * @unrestricted
- */
-Security.PageSecurityState = class {
-  /**
-   * @param {!Protocol.Security.SecurityState} securityState
-   * @param {boolean} schemeIsCryptographic
-   * @param {!Array<!Protocol.Security.SecurityStateExplanation>} explanations
-   * @param {?Protocol.Security.InsecureContentStatus} insecureContentStatus
-   * @param {?string} summary
-   */
-  constructor(securityState, schemeIsCryptographic, explanations, insecureContentStatus, summary) {
-    this.securityState = securityState;
-    this.schemeIsCryptographic = schemeIsCryptographic;
-    this.explanations = explanations;
-    this.insecureContentStatus = insecureContentStatus;
-    this.summary = summary;
-  }
-};
-
-/**
- * @implements {Protocol.SecurityDispatcher}
- * @unrestricted
- */
-Security.SecurityDispatcher = class {
-  constructor(model) {
-    this._model = model;
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Security.SecurityState} securityState
-   * @param {boolean} schemeIsCryptographic
-   * @param {!Array<!Protocol.Security.SecurityStateExplanation>} explanations
-   * @param {!Protocol.Security.InsecureContentStatus} insecureContentStatus
-   * @param {?string=} summary
-   */
-  securityStateChanged(securityState, schemeIsCryptographic, explanations, insecureContentStatus, summary) {
-    const pageSecurityState = new Security.PageSecurityState(
-        securityState, schemeIsCryptographic, explanations, insecureContentStatus, summary || null);
-    this._model.dispatchEventToListeners(Security.SecurityModel.Events.SecurityStateChanged, pageSecurityState);
-  }
-
-
-  /**
-   * @override
-   * @param {number} eventId
-   * @param {string} errorType
-   * @param {string} requestURL
-   */
-  certificateError(eventId, errorType, requestURL) {
-  }
-};
diff --git a/front_end/security/SecurityPanel.js b/front_end/security/SecurityPanel.js
deleted file mode 100644
index 44f890f..0000000
--- a/front_end/security/SecurityPanel.js
+++ /dev/null
@@ -1,1013 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!Security.SecurityModel>}
- * @unrestricted
- */
-Security.SecurityPanel = class extends UI.PanelWithSidebar {
-  constructor() {
-    super('security');
-
-    this._mainView = new Security.SecurityMainView(this);
-
-    const title = createElementWithClass('span', 'title');
-    title.textContent = Common.UIString('Overview');
-    this._sidebarMainViewElement = new Security.SecurityPanelSidebarTreeElement(
-        title, this._setVisibleView.bind(this, this._mainView), 'security-main-view-sidebar-tree-item', 'lock-icon');
-    this._sidebarTree = new Security.SecurityPanelSidebarTree(this._sidebarMainViewElement, this.showOrigin.bind(this));
-    this.panelSidebarElement().appendChild(this._sidebarTree.element);
-
-    /** @type {!Map<!Protocol.Network.LoaderId, !SDK.NetworkRequest>} */
-    this._lastResponseReceivedForLoaderId = new Map();
-
-    /** @type {!Map<!Security.SecurityPanel.Origin, !Security.SecurityPanel.OriginState>} */
-    this._origins = new Map();
-
-    /** @type {!Map<!Network.NetworkLogView.MixedContentFilterValues, number>} */
-    this._filterRequestCounts = new Map();
-
-    SDK.targetManager.observeModels(Security.SecurityModel, this);
-  }
-
-  /**
-   * @return {!Security.SecurityPanel}
-   */
-  static _instance() {
-    return /** @type {!Security.SecurityPanel} */ (self.runtime.sharedInstance(Security.SecurityPanel));
-  }
-
-  /**
-   * @param {string} text
-   * @param {string} origin
-   * @return {!Element}
-   */
-  static createCertificateViewerButtonForOrigin(text, origin) {
-    return UI.createTextButton(text, async e => {
-      e.consume();
-      const names = await SDK.multitargetNetworkManager.getCertificate(origin);
-      InspectorFrontendHost.showCertificateViewer(names);
-    }, 'origin-button');
-  }
-
-  /**
-   * @param {string} text
-   * @param {!Array<string>} names
-   * @return {!Element}
-   */
-  static createCertificateViewerButtonForCert(text, names) {
-    return UI.createTextButton(text, e => {
-      e.consume();
-      InspectorFrontendHost.showCertificateViewer(names);
-    }, 'security-certificate-button');
-  }
-
-  /**
-   * @param {string} url
-   * @param {string} securityState
-   * @return {!Element}
-   */
-  static createHighlightedUrl(url, securityState) {
-    const schemeSeparator = '://';
-    const index = url.indexOf(schemeSeparator);
-
-    // If the separator is not found, just display the text without highlighting.
-    if (index === -1) {
-      const text = createElement('span', '');
-      text.textContent = url;
-      return text;
-    }
-
-    const highlightedUrl = createElement('span', 'url-text');
-
-    const scheme = url.substr(0, index);
-    const content = url.substr(index + schemeSeparator.length);
-    highlightedUrl.createChild('span', 'url-scheme-' + securityState).textContent = scheme;
-    highlightedUrl.createChild('span', 'url-scheme-separator').textContent = schemeSeparator;
-    highlightedUrl.createChild('span').textContent = content;
-
-    return highlightedUrl;
-  }
-
-
-  /**
-   * @param {!Protocol.Security.SecurityState} securityState
-   */
-  setRanInsecureContentStyle(securityState) {
-    this._ranInsecureContentStyle = securityState;
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} securityState
-   */
-  setDisplayedInsecureContentStyle(securityState) {
-    this._displayedInsecureContentStyle = securityState;
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} newSecurityState
-   * @param {boolean} schemeIsCryptographic
-   * @param {!Array<!Protocol.Security.SecurityStateExplanation>} explanations
-   * @param {?Protocol.Security.InsecureContentStatus} insecureContentStatus
-   * @param {?string} summary
-   */
-  _updateSecurityState(newSecurityState, schemeIsCryptographic, explanations, insecureContentStatus, summary) {
-    this._sidebarMainViewElement.setSecurityState(newSecurityState);
-    this._mainView.updateSecurityState(
-        newSecurityState, schemeIsCryptographic, explanations, insecureContentStatus, summary);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onSecurityStateChanged(event) {
-    const data = /** @type {!Security.PageSecurityState} */ (event.data);
-    const securityState = /** @type {!Protocol.Security.SecurityState} */ (data.securityState);
-    const schemeIsCryptographic = /** @type {boolean} */ (data.schemeIsCryptographic);
-    const explanations = /** @type {!Array<!Protocol.Security.SecurityStateExplanation>} */ (data.explanations);
-    const insecureContentStatus = /** @type {?Protocol.Security.InsecureContentStatus} */ (data.insecureContentStatus);
-    const summary = /** @type {?string} */ (data.summary);
-    this._updateSecurityState(securityState, schemeIsCryptographic, explanations, insecureContentStatus, summary);
-  }
-
-  selectAndSwitchToMainView() {
-    // The sidebar element will trigger displaying the main view. Rather than making a redundant call to display the main view, we rely on this.
-    this._sidebarMainViewElement.select(true);
-  }
-  /**
-   * @param {!Security.SecurityPanel.Origin} origin
-   */
-  showOrigin(origin) {
-    const originState = this._origins.get(origin);
-    if (!originState.originView)
-      originState.originView = new Security.SecurityOriginView(this, origin, originState);
-
-    this._setVisibleView(originState.originView);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    if (!this._visibleView)
-      this.selectAndSwitchToMainView();
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._sidebarTree.focus();
-  }
-
-  /**
-   * @param {!UI.VBox} view
-   */
-  _setVisibleView(view) {
-    if (this._visibleView === view)
-      return;
-
-    if (this._visibleView)
-      this._visibleView.detach();
-
-    this._visibleView = view;
-
-    if (view)
-      this.splitWidget().setMainWidget(view);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onResponseReceived(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    if (request.resourceType() === Common.resourceTypes.Document)
-      this._lastResponseReceivedForLoaderId.set(request.loaderId, request);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  _processRequest(request) {
-    const origin = Common.ParsedURL.extractOrigin(request.url());
-
-    if (!origin) {
-      // We don't handle resources like data: URIs. Most of them don't affect the lock icon.
-      return;
-    }
-
-    let securityState = /** @type {!Protocol.Security.SecurityState} */ (request.securityState());
-
-    if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable && this._ranInsecureContentStyle)
-      securityState = this._ranInsecureContentStyle;
-    else if (
-        request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable &&
-        this._displayedInsecureContentStyle)
-      securityState = this._displayedInsecureContentStyle;
-
-    if (this._origins.has(origin)) {
-      const originState = this._origins.get(origin);
-      const oldSecurityState = originState.securityState;
-      originState.securityState = this._securityStateMin(oldSecurityState, securityState);
-      if (oldSecurityState !== originState.securityState) {
-        const securityDetails = /** @type {?Protocol.Network.SecurityDetails} */ (request.securityDetails());
-        if (securityDetails)
-          originState.securityDetails = securityDetails;
-        this._sidebarTree.updateOrigin(origin, securityState);
-        if (originState.originView)
-          originState.originView.setSecurityState(securityState);
-      }
-    } else {
-      // This stores the first security details we see for an origin, but we should
-      // eventually store a (deduplicated) list of all the different security
-      // details we have seen. https://crbug.com/503170
-      const originState = {};
-      originState.securityState = securityState;
-
-      const securityDetails = request.securityDetails();
-      if (securityDetails)
-        originState.securityDetails = securityDetails;
-
-      originState.loadedFromCache = request.cached();
-
-      this._origins.set(origin, originState);
-
-      this._sidebarTree.addOrigin(origin, securityState);
-
-      // Don't construct the origin view yet (let it happen lazily).
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onRequestFinished(event) {
-    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
-    this._updateFilterRequestCounts(request);
-    this._processRequest(request);
-  }
-
-  /**
-   * @param {!SDK.NetworkRequest} request
-   */
-  _updateFilterRequestCounts(request) {
-    if (request.mixedContentType === Protocol.Security.MixedContentType.None)
-      return;
-
-    /** @type {!Network.NetworkLogView.MixedContentFilterValues} */
-    let filterKey = Network.NetworkLogView.MixedContentFilterValues.All;
-    if (request.wasBlocked())
-      filterKey = Network.NetworkLogView.MixedContentFilterValues.Blocked;
-    else if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable)
-      filterKey = Network.NetworkLogView.MixedContentFilterValues.BlockOverridden;
-    else if (request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable)
-      filterKey = Network.NetworkLogView.MixedContentFilterValues.Displayed;
-
-    if (!this._filterRequestCounts.has(filterKey))
-      this._filterRequestCounts.set(filterKey, 1);
-    else
-      this._filterRequestCounts.set(filterKey, this._filterRequestCounts.get(filterKey) + 1);
-
-    this._mainView.refreshExplanations();
-  }
-
-  /**
-   * @param {!Network.NetworkLogView.MixedContentFilterValues} filterKey
-   * @return {number}
-   */
-  filterRequestCount(filterKey) {
-    return this._filterRequestCounts.get(filterKey) || 0;
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} stateA
-   * @param {!Protocol.Security.SecurityState} stateB
-   * @return {!Protocol.Security.SecurityState}
-   */
-  _securityStateMin(stateA, stateB) {
-    return Security.SecurityModel.SecurityStateComparator(stateA, stateB) < 0 ? stateA : stateB;
-  }
-
-  /**
-   * @override
-   * @param {!Security.SecurityModel} securityModel
-   */
-  modelAdded(securityModel) {
-    if (this._securityModel)
-      return;
-
-    this._securityModel = securityModel;
-    const resourceTreeModel = securityModel.resourceTreeModel();
-    const networkManager = securityModel.networkManager();
-    this._eventListeners = [
-      securityModel.addEventListener(
-          Security.SecurityModel.Events.SecurityStateChanged, this._onSecurityStateChanged, this),
-      resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this),
-      resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.InterstitialShown, this._onInterstitialShown, this),
-      resourceTreeModel.addEventListener(
-          SDK.ResourceTreeModel.Events.InterstitialHidden, this._onInterstitialHidden, this),
-      networkManager.addEventListener(SDK.NetworkManager.Events.ResponseReceived, this._onResponseReceived, this),
-      networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this),
-    ];
-
-    if (resourceTreeModel.isInterstitialShowing())
-      this._onInterstitialShown();
-  }
-
-  /**
-   * @override
-   * @param {!Security.SecurityModel} securityModel
-   */
-  modelRemoved(securityModel) {
-    if (this._securityModel !== securityModel)
-      return;
-
-    delete this._securityModel;
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onMainFrameNavigated(event) {
-    const frame = /** type {!Protocol.Page.Frame}*/ (event.data);
-    const request = this._lastResponseReceivedForLoaderId.get(frame.loaderId);
-
-    this.selectAndSwitchToMainView();
-    this._sidebarTree.clearOrigins();
-    this._origins.clear();
-    this._lastResponseReceivedForLoaderId.clear();
-    this._filterRequestCounts.clear();
-    // After clearing the filtered request counts, refresh the
-    // explanations to reflect the new counts.
-    this._mainView.refreshExplanations();
-
-    // If we could not find a matching request (as in the case of clicking
-    // through an interstitial, see https://crbug.com/669309), set the origin
-    // based upon the url data from the MainFrameNavigated event itself.
-    const origin = Common.ParsedURL.extractOrigin(request ? request.url() : frame.url);
-    this._sidebarTree.setMainOrigin(origin);
-
-    if (request)
-      this._processRequest(request);
-  }
-
-  _onInterstitialShown() {
-    // The panel might have been displaying the origin view on the
-    // previously loaded page. When showing an interstitial, switch
-    // back to the Overview view.
-    this.selectAndSwitchToMainView();
-    this._sidebarTree.toggleOriginsList(true /* hidden */);
-  }
-
-  _onInterstitialHidden() {
-    this._sidebarTree.toggleOriginsList(false /* hidden */);
-  }
-};
-
-/** @typedef {string} */
-Security.SecurityPanel.Origin;
-
-/**
- * @typedef {Object}
- * @property {!Protocol.Security.SecurityState} securityState
- * @property {?Protocol.Network.SecurityDetails} securityDetails
- * @property {?Promise<>} certificateDetailsPromise
- * @property {?bool} loadedFromCache
- * @property {?Security.SecurityOriginView} originView
- */
-Security.SecurityPanel.OriginState;
-
-
-/**
- * @unrestricted
- */
-Security.SecurityPanelSidebarTree = class extends UI.TreeOutlineInShadow {
-  /**
-   * @param {!Security.SecurityPanelSidebarTreeElement} mainViewElement
-   * @param {function(!Security.SecurityPanel.Origin)} showOriginInPanel
-   */
-  constructor(mainViewElement, showOriginInPanel) {
-    super();
-    this.registerRequiredCSS('security/sidebar.css');
-    this.registerRequiredCSS('security/lockIcon.css');
-    this.appendChild(mainViewElement);
-
-    this._showOriginInPanel = showOriginInPanel;
-    this._mainOrigin = null;
-
-    /** @type {!Map<!Security.SecurityPanelSidebarTree.OriginGroupName, !UI.TreeElement>} */
-    this._originGroups = new Map();
-
-    for (const key in Security.SecurityPanelSidebarTree.OriginGroupName) {
-      const originGroupName = Security.SecurityPanelSidebarTree.OriginGroupName[key];
-      const originGroup = new UI.TreeElement(originGroupName, true);
-      originGroup.selectable = false;
-      originGroup.setCollapsible(false);
-      originGroup.expand();
-      originGroup.listItemElement.classList.add('security-sidebar-origins');
-      this._originGroups.set(originGroupName, originGroup);
-      this.appendChild(originGroup);
-    }
-    this._clearOriginGroups();
-
-    // This message will be removed by clearOrigins() during the first new page load after the panel was opened.
-    const mainViewReloadMessage = new UI.TreeElement(Common.UIString('Reload to view details'));
-    mainViewReloadMessage.selectable = false;
-    mainViewReloadMessage.listItemElement.classList.add('security-main-view-reload-message');
-    this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroupName.MainOrigin)
-        .appendChild(mainViewReloadMessage);
-
-    /** @type {!Map<!Security.SecurityPanel.Origin, !Security.SecurityPanelSidebarTreeElement>} */
-    this._elementsByOrigin = new Map();
-  }
-
-  /**
-   * @param {boolean} hidden
-   */
-  toggleOriginsList(hidden) {
-    for (const key in Security.SecurityPanelSidebarTree.OriginGroupName) {
-      const originGroupName = Security.SecurityPanelSidebarTree.OriginGroupName[key];
-      const group = this._originGroups.get(originGroupName);
-      if (group)
-        group.hidden = hidden;
-    }
-  }
-
-  /**
-   * @param {!Security.SecurityPanel.Origin} origin
-   * @param {!Protocol.Security.SecurityState} securityState
-   */
-  addOrigin(origin, securityState) {
-    const originElement = new Security.SecurityPanelSidebarTreeElement(
-        Security.SecurityPanel.createHighlightedUrl(origin, securityState), this._showOriginInPanel.bind(this, origin),
-        'security-sidebar-tree-item', 'security-property');
-    this._elementsByOrigin.set(origin, originElement);
-    this.updateOrigin(origin, securityState);
-  }
-
-  /**
-   * @param {!Security.SecurityPanel.Origin} origin
-   */
-  setMainOrigin(origin) {
-    this._mainOrigin = origin;
-  }
-
-  /**
-   * @param {!Security.SecurityPanel.Origin} origin
-   * @param {!Protocol.Security.SecurityState} securityState
-   */
-  updateOrigin(origin, securityState) {
-    const originElement =
-        /** @type {!Security.SecurityPanelSidebarTreeElement} */ (this._elementsByOrigin.get(origin));
-    originElement.setSecurityState(securityState);
-
-    let newParent;
-    if (origin === this._mainOrigin) {
-      newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroupName.MainOrigin);
-    } else {
-      switch (securityState) {
-        case Protocol.Security.SecurityState.Secure:
-          newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroupName.Secure);
-          break;
-        case Protocol.Security.SecurityState.Unknown:
-          newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroupName.Unknown);
-          break;
-        default:
-          newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroupName.NonSecure);
-          break;
-      }
-    }
-
-    const oldParent = originElement.parent;
-    if (oldParent !== newParent) {
-      if (oldParent) {
-        oldParent.removeChild(originElement);
-        if (oldParent.childCount() === 0)
-          oldParent.hidden = true;
-      }
-      newParent.appendChild(originElement);
-      newParent.hidden = false;
-    }
-  }
-
-  _clearOriginGroups() {
-    for (const originGroup of this._originGroups.values()) {
-      originGroup.removeChildren();
-      originGroup.hidden = true;
-    }
-    this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroupName.MainOrigin).hidden = false;
-  }
-
-  clearOrigins() {
-    this._clearOriginGroups();
-    this._elementsByOrigin.clear();
-  }
-};
-
-/**
- * A mapping from Javascript key IDs to names (sidebar section titles).
- * Note: The names are used as keys into a map, so they must be distinct from each other.
- * @enum {string}
- */
-Security.SecurityPanelSidebarTree.OriginGroupName = {
-  MainOrigin: Common.UIString('Main origin'),
-  NonSecure: Common.UIString('Non-secure origins'),
-  Secure: Common.UIString('Secure origins'),
-  Unknown: Common.UIString('Unknown / canceled')
-};
-
-/**
- * @unrestricted
- */
-Security.SecurityPanelSidebarTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Element} textElement
-   * @param {function()} selectCallback
-   * @param {string} className
-   * @param {string} cssPrefix
-   */
-  constructor(textElement, selectCallback, className, cssPrefix) {
-    super('', false);
-    this._selectCallback = selectCallback;
-    this._cssPrefix = cssPrefix;
-    this.listItemElement.classList.add(className);
-    this._iconElement = this.listItemElement.createChild('div', 'icon');
-    this._iconElement.classList.add(this._cssPrefix);
-    this.listItemElement.appendChild(textElement);
-    this.setSecurityState(Protocol.Security.SecurityState.Unknown);
-  }
-
-  /**
-   * @param {!Security.SecurityPanelSidebarTreeElement} a
-   * @param {!Security.SecurityPanelSidebarTreeElement} b
-   * @return {number}
-   */
-  static SecurityStateComparator(a, b) {
-    return Security.SecurityModel.SecurityStateComparator(a.securityState(), b.securityState());
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} newSecurityState
-   */
-  setSecurityState(newSecurityState) {
-    if (this._securityState)
-      this._iconElement.classList.remove(this._cssPrefix + '-' + this._securityState);
-
-    this._securityState = newSecurityState;
-    this._iconElement.classList.add(this._cssPrefix + '-' + newSecurityState);
-  }
-
-  /**
-   * @return {!Protocol.Security.SecurityState}
-   */
-  securityState() {
-    return this._securityState;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onselect() {
-    this._selectCallback();
-    return true;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Security.SecurityMainView = class extends UI.VBox {
-  /**
-   * @param {!Security.SecurityPanel} panel
-   */
-  constructor(panel) {
-    super(true);
-    this.registerRequiredCSS('security/mainView.css');
-    this.registerRequiredCSS('security/lockIcon.css');
-    this.setMinimumSize(200, 100);
-
-    this.contentElement.classList.add('security-main-view');
-
-    this._panel = panel;
-
-    this._summarySection = this.contentElement.createChild('div', 'security-summary');
-
-    // Info explanations should appear after all others.
-    this._securityExplanationsMain =
-        this.contentElement.createChild('div', 'security-explanation-list security-explanations-main');
-    this._securityExplanationsExtra =
-        this.contentElement.createChild('div', 'security-explanation-list security-explanations-extra');
-
-    // Fill the security summary section.
-    this._summarySection.createChild('div', 'security-summary-section-title').textContent =
-        Common.UIString('Security overview');
-
-    const lockSpectrum = this._summarySection.createChild('div', 'lock-spectrum');
-    lockSpectrum.createChild('div', 'lock-icon lock-icon-secure').title = Common.UIString('Secure');
-    lockSpectrum.createChild('div', 'lock-icon lock-icon-neutral').title = Common.UIString('Not secure');
-    lockSpectrum.createChild('div', 'lock-icon lock-icon-insecure').title = Common.UIString('Not secure (broken)');
-
-    this._summarySection.createChild('div', 'triangle-pointer-container')
-        .createChild('div', 'triangle-pointer-wrapper')
-        .createChild('div', 'triangle-pointer');
-
-    this._summaryText = this._summarySection.createChild('div', 'security-summary-text');
-  }
-
-  /**
-   * @param {!Element} parent
-   * @param {!Protocol.Security.SecurityStateExplanation} explanation
-   * @return {!Element}
-   */
-  _addExplanation(parent, explanation) {
-    const explanationSection = parent.createChild('div', 'security-explanation');
-    explanationSection.classList.add('security-explanation-' + explanation.securityState);
-
-    explanationSection.createChild('div', 'security-property')
-        .classList.add('security-property-' + explanation.securityState);
-    const text = explanationSection.createChild('div', 'security-explanation-text');
-
-    const explanationHeader = text.createChild('div', 'security-explanation-title');
-
-    if (explanation.title) {
-      explanationHeader.createChild('span').textContent = explanation.title + ' - ';
-      explanationHeader.createChild('span', 'security-explanation-title-' + explanation.securityState).textContent =
-          explanation.summary;
-    } else {
-      explanationHeader.textContent = explanation.summary;
-    }
-
-    text.createChild('div').textContent = explanation.description;
-
-    if (explanation.certificate.length) {
-      text.appendChild(Security.SecurityPanel.createCertificateViewerButtonForCert(
-          Common.UIString('View certificate'), explanation.certificate));
-    }
-    return text;
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} newSecurityState
-   * @param {boolean} schemeIsCryptographic
-   * @param {!Array<!Protocol.Security.SecurityStateExplanation>} explanations
-   * @param {?Protocol.Security.InsecureContentStatus} insecureContentStatus
-   * @param {?string} summary
-   */
-  updateSecurityState(newSecurityState, schemeIsCryptographic, explanations, insecureContentStatus, summary) {
-    // Remove old state.
-    // It's safe to call this even when this._securityState is undefined.
-    this._summarySection.classList.remove('security-summary-' + this._securityState);
-
-    // Add new state.
-    this._securityState = newSecurityState;
-    this._summarySection.classList.add('security-summary-' + this._securityState);
-    const summaryExplanationStrings = {
-      'unknown': Common.UIString('The security of this page is unknown.'),
-      'insecure': Common.UIString('This page is not secure (broken HTTPS).'),
-      'neutral': Common.UIString('This page is not secure.'),
-      'secure': Common.UIString('This page is secure (valid HTTPS).')
-    };
-
-    // Use override summary if present, otherwise use base explanation
-    this._summaryText.textContent = summary || summaryExplanationStrings[this._securityState];
-
-    this._explanations = explanations, this._insecureContentStatus = insecureContentStatus;
-    this._schemeIsCryptographic = schemeIsCryptographic;
-
-    this._panel.setRanInsecureContentStyle(insecureContentStatus.ranInsecureContentStyle);
-    this._panel.setDisplayedInsecureContentStyle(insecureContentStatus.displayedInsecureContentStyle);
-
-    this.refreshExplanations();
-  }
-
-  refreshExplanations() {
-    this._securityExplanationsMain.removeChildren();
-    this._securityExplanationsExtra.removeChildren();
-    for (const explanation of this._explanations) {
-      if (explanation.securityState === Protocol.Security.SecurityState.Info) {
-        this._addExplanation(this._securityExplanationsExtra, explanation);
-      } else {
-        switch (explanation.mixedContentType) {
-          case Protocol.Security.MixedContentType.Blockable:
-            this._addMixedContentExplanation(
-                this._securityExplanationsMain, explanation,
-                Network.NetworkLogView.MixedContentFilterValues.BlockOverridden);
-            break;
-          case Protocol.Security.MixedContentType.OptionallyBlockable:
-            this._addMixedContentExplanation(
-                this._securityExplanationsMain, explanation, Network.NetworkLogView.MixedContentFilterValues.Displayed);
-            break;
-          default:
-            this._addExplanation(this._securityExplanationsMain, explanation);
-            break;
-        }
-      }
-    }
-
-    if (this._panel.filterRequestCount(Network.NetworkLogView.MixedContentFilterValues.Blocked) > 0) {
-      const explanation = /** @type {!Protocol.Security.SecurityStateExplanation} */ ({
-        securityState: Protocol.Security.SecurityState.Info,
-        summary: Common.UIString('Blocked mixed content'),
-        description: Common.UIString('Your page requested non-secure resources that were blocked.'),
-        mixedContentType: Protocol.Security.MixedContentType.Blockable,
-        certificate: []
-      });
-      this._addMixedContentExplanation(
-          this._securityExplanationsMain, explanation, Network.NetworkLogView.MixedContentFilterValues.Blocked);
-    }
-  }
-
-  /**
-   * @param {!Element} parent
-   * @param {!Protocol.Security.SecurityStateExplanation} explanation
-   * @param {!Network.NetworkLogView.MixedContentFilterValues} filterKey
-   */
-  _addMixedContentExplanation(parent, explanation, filterKey) {
-    const element = this._addExplanation(parent, explanation);
-
-    const filterRequestCount = this._panel.filterRequestCount(filterKey);
-    if (!filterRequestCount) {
-      // Network instrumentation might not have been enabled for the page
-      // load, so the security panel does not necessarily know a count of
-      // individual mixed requests at this point. Prompt them to refresh
-      // instead of pointing them to the Network panel to get prompted
-      // to refresh.
-      const refreshPrompt = element.createChild('div', 'security-mixed-content');
-      refreshPrompt.textContent = Common.UIString('Reload the page to record requests for HTTP resources.');
-      return;
-    }
-
-    const requestsAnchor = element.createChild('div', 'security-mixed-content link');
-    if (filterRequestCount === 1)
-      requestsAnchor.textContent = Common.UIString('View %d request in Network Panel', filterRequestCount);
-    else
-      requestsAnchor.textContent = Common.UIString('View %d requests in Network Panel', filterRequestCount);
-
-    requestsAnchor.href = '';
-    requestsAnchor.addEventListener('click', this.showNetworkFilter.bind(this, filterKey));
-  }
-
-  /**
-   * @param {!Network.NetworkLogView.MixedContentFilterValues} filterKey
-   * @param {!Event} e
-   */
-  showNetworkFilter(filterKey, e) {
-    e.consume();
-    Network.NetworkPanel.revealAndFilter(
-        [{filterType: Network.NetworkLogView.FilterType.MixedContent, filterValue: filterKey}]);
-  }
-};
-
-/**
- * @unrestricted
- */
-Security.SecurityOriginView = class extends UI.VBox {
-  /**
-   * @param {!Security.SecurityPanel} panel
-   * @param {!Security.SecurityPanel.Origin} origin
-   * @param {!Security.SecurityPanel.OriginState} originState
-   */
-  constructor(panel, origin, originState) {
-    super();
-    this._panel = panel;
-    this.setMinimumSize(200, 100);
-
-    this.element.classList.add('security-origin-view');
-    this.registerRequiredCSS('security/originView.css');
-    this.registerRequiredCSS('security/lockIcon.css');
-
-    const titleSection = this.element.createChild('div', 'title-section');
-    titleSection.createChild('div', 'title-section-header').textContent = ls`Origin`;
-
-    const originDisplay = titleSection.createChild('div', 'origin-display');
-    this._originLockIcon = originDisplay.createChild('span', 'security-property');
-    this._originLockIcon.classList.add('security-property-' + originState.securityState);
-
-    originDisplay.appendChild(Security.SecurityPanel.createHighlightedUrl(origin, originState.securityState));
-
-    const originNetworkButton = titleSection.createChild('div', 'view-network-button');
-    originNetworkButton.appendChild(UI.createTextButton('View requests in Network Panel', e => {
-      e.consume();
-      const parsedURL = new Common.ParsedURL(origin);
-      Network.NetworkPanel.revealAndFilter([
-        {filterType: Network.NetworkLogView.FilterType.Domain, filterValue: parsedURL.host},
-        {filterType: Network.NetworkLogView.FilterType.Scheme, filterValue: parsedURL.scheme}
-      ]);
-    }, 'origin-button'));
-
-    if (originState.securityDetails) {
-      const connectionSection = this.element.createChild('div', 'origin-view-section');
-      connectionSection.createChild('div', 'origin-view-section-title').textContent = Common.UIString('Connection');
-
-      let table = new Security.SecurityDetailsTable();
-      connectionSection.appendChild(table.element());
-      table.addRow(Common.UIString('Protocol'), originState.securityDetails.protocol);
-      if (originState.securityDetails.keyExchange)
-        table.addRow(Common.UIString('Key exchange'), originState.securityDetails.keyExchange);
-      if (originState.securityDetails.keyExchangeGroup)
-        table.addRow(Common.UIString('Key exchange group'), originState.securityDetails.keyExchangeGroup);
-      table.addRow(
-          Common.UIString('Cipher'),
-          originState.securityDetails.cipher +
-              (originState.securityDetails.mac ? ' with ' + originState.securityDetails.mac : ''));
-
-      // Create the certificate section outside the callback, so that it appears in the right place.
-      const certificateSection = this.element.createChild('div', 'origin-view-section');
-      certificateSection.createChild('div', 'origin-view-section-title').textContent = Common.UIString('Certificate');
-
-      const sctListLength = originState.securityDetails.signedCertificateTimestampList.length;
-      const ctCompliance = originState.securityDetails.certificateTransparencyCompliance;
-      let sctSection;
-      if (sctListLength || ctCompliance !== Protocol.Network.CertificateTransparencyCompliance.Unknown) {
-        // Create the Certificate Transparency section outside the callback, so that it appears in the right place.
-        sctSection = this.element.createChild('div', 'origin-view-section');
-        sctSection.createChild('div', 'origin-view-section-title').textContent =
-            Common.UIString('Certificate Transparency');
-      }
-
-      const sanDiv = this._createSanDiv(originState.securityDetails.sanList);
-      const validFromString = new Date(1000 * originState.securityDetails.validFrom).toUTCString();
-      const validUntilString = new Date(1000 * originState.securityDetails.validTo).toUTCString();
-
-      table = new Security.SecurityDetailsTable();
-      certificateSection.appendChild(table.element());
-      table.addRow(Common.UIString('Subject'), originState.securityDetails.subjectName);
-      table.addRow(Common.UIString('SAN'), sanDiv);
-      table.addRow(Common.UIString('Valid from'), validFromString);
-      table.addRow(Common.UIString('Valid until'), validUntilString);
-      table.addRow(Common.UIString('Issuer'), originState.securityDetails.issuer);
-
-      table.addRow(
-          '',
-          Security.SecurityPanel.createCertificateViewerButtonForOrigin(
-              Common.UIString('Open full certificate details'), origin));
-
-      if (!sctSection)
-        return;
-
-      // Show summary of SCT(s) of Certificate Transparency.
-      const sctSummaryTable = new Security.SecurityDetailsTable();
-      sctSummaryTable.element().classList.add('sct-summary');
-      sctSection.appendChild(sctSummaryTable.element());
-      for (let i = 0; i < sctListLength; i++) {
-        const sct = originState.securityDetails.signedCertificateTimestampList[i];
-        sctSummaryTable.addRow(
-            Common.UIString('SCT'), sct.logDescription + ' (' + sct.origin + ', ' + sct.status + ')');
-      }
-
-      // Show detailed SCT(s) of Certificate Transparency.
-      const sctTableWrapper = sctSection.createChild('div', 'sct-details');
-      sctTableWrapper.classList.add('hidden');
-      for (let i = 0; i < sctListLength; i++) {
-        const sctTable = new Security.SecurityDetailsTable();
-        sctTableWrapper.appendChild(sctTable.element());
-        const sct = originState.securityDetails.signedCertificateTimestampList[i];
-        sctTable.addRow(Common.UIString('Log name'), sct.logDescription);
-        sctTable.addRow(Common.UIString('Log ID'), sct.logId.replace(/(.{2})/g, '$1 '));
-        sctTable.addRow(Common.UIString('Validation status'), sct.status);
-        sctTable.addRow(Common.UIString('Source'), sct.origin);
-        sctTable.addRow(Common.UIString('Issued at'), new Date(sct.timestamp).toUTCString());
-        sctTable.addRow(Common.UIString('Hash algorithm'), sct.hashAlgorithm);
-        sctTable.addRow(Common.UIString('Signature algorithm'), sct.signatureAlgorithm);
-        sctTable.addRow(Common.UIString('Signature data'), sct.signatureData.replace(/(.{2})/g, '$1 '));
-      }
-
-      // Add link to toggle between displaying of the summary of the SCT(s) and the detailed SCT(s).
-      if (sctListLength) {
-        const toggleSctsDetailsLink = sctSection.createChild('div', 'link');
-        toggleSctsDetailsLink.classList.add('sct-toggle');
-        toggleSctsDetailsLink.textContent = Common.UIString('Show full details');
-        function toggleSctDetailsDisplay() {
-          const isDetailsShown = !sctTableWrapper.classList.contains('hidden');
-          if (isDetailsShown)
-            toggleSctsDetailsLink.textContent = Common.UIString('Show full details');
-          else
-            toggleSctsDetailsLink.textContent = Common.UIString('Hide full details');
-          sctSummaryTable.element().classList.toggle('hidden');
-          sctTableWrapper.classList.toggle('hidden');
-        }
-        toggleSctsDetailsLink.addEventListener('click', toggleSctDetailsDisplay, false);
-      }
-
-      switch (ctCompliance) {
-        case Protocol.Network.CertificateTransparencyCompliance.Compliant:
-          sctSection.createChild('div', 'origin-view-section-notes').textContent =
-              Common.UIString('This request complies with Chrome\'s Certificate Transparency policy.');
-          break;
-        case Protocol.Network.CertificateTransparencyCompliance.NotCompliant:
-          sctSection.createChild('div', 'origin-view-section-notes').textContent =
-              Common.UIString('This request does not comply with Chrome\'s Certificate Transparency policy.');
-          break;
-        case Protocol.Network.CertificateTransparencyCompliance.Unknown:
-          break;
-      }
-
-      const noteSection = this.element.createChild('div', 'origin-view-section origin-view-notes');
-      if (originState.loadedFromCache) {
-        noteSection.createChild('div').textContent =
-            Common.UIString('This response was loaded from cache. Some security details might be missing.');
-      }
-      noteSection.createChild('div').textContent =
-          Common.UIString('The security details above are from the first inspected response.');
-    } else if (originState.securityState !== Protocol.Security.SecurityState.Unknown) {
-      const notSecureSection = this.element.createChild('div', 'origin-view-section');
-      notSecureSection.createChild('div', 'origin-view-section-title').textContent = Common.UIString('Not secure');
-      notSecureSection.createChild('div').textContent =
-          Common.UIString('Your connection to this origin is not secure.');
-    } else {
-      const noInfoSection = this.element.createChild('div', 'origin-view-section');
-      noInfoSection.createChild('div', 'origin-view-section-title').textContent =
-          Common.UIString('No security information');
-      noInfoSection.createChild('div').textContent =
-          Common.UIString('No security details are available for this origin.');
-    }
-  }
-
-  /**
-   * @param {!Array<string>} sanList
-   * *return {!Element}
-   */
-  _createSanDiv(sanList) {
-    const sanDiv = createElement('div');
-    if (sanList.length === 0) {
-      sanDiv.textContent = Common.UIString('(n/a)');
-      sanDiv.classList.add('empty-san');
-    } else {
-      const truncatedNumToShow = 2;
-      const listIsTruncated = sanList.length > truncatedNumToShow + 1;
-      for (let i = 0; i < sanList.length; i++) {
-        const span = sanDiv.createChild('span', 'san-entry');
-        span.textContent = sanList[i];
-        if (listIsTruncated && i >= truncatedNumToShow)
-          span.classList.add('truncated-entry');
-      }
-      if (listIsTruncated) {
-        const truncatedSANToggle = sanDiv.createChild('div', 'link');
-        truncatedSANToggle.href = '';
-
-        function toggleSANTruncation() {
-          if (sanDiv.classList.contains('truncated-san')) {
-            sanDiv.classList.remove('truncated-san');
-            truncatedSANToggle.textContent = Common.UIString('Show less');
-          } else {
-            sanDiv.classList.add('truncated-san');
-            truncatedSANToggle.textContent = Common.UIString('Show more (%d total)', sanList.length);
-          }
-        }
-        truncatedSANToggle.addEventListener('click', toggleSANTruncation, false);
-        toggleSANTruncation();
-      }
-    }
-    return sanDiv;
-  }
-
-  /**
-   * @param {!Protocol.Security.SecurityState} newSecurityState
-   */
-  setSecurityState(newSecurityState) {
-    for (const className of Array.prototype.slice.call(this._originLockIcon.classList)) {
-      if (className.startsWith('security-property-'))
-        this._originLockIcon.classList.remove(className);
-    }
-
-    this._originLockIcon.classList.add('security-property-' + newSecurityState);
-  }
-};
-
-/**
- * @unrestricted
- */
-Security.SecurityDetailsTable = class {
-  constructor() {
-    this._element = createElement('table');
-    this._element.classList.add('details-table');
-  }
-
-  /**
-   * @return: {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  /**
-   * @param {string} key
-   * @param {string|!Node} value
-   */
-  addRow(key, value) {
-    const row = this._element.createChild('div', 'details-table-row');
-    row.createChild('div').textContent = key;
-
-    const valueDiv = row.createChild('div');
-    if (typeof value === 'string')
-      valueDiv.textContent = value;
-    else
-      valueDiv.appendChild(value);
-  }
-};
diff --git a/front_end/security/lockIcon.css b/front_end/security/lockIcon.css
deleted file mode 100644
index d58538c..0000000
--- a/front_end/security/lockIcon.css
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.lock-icon,
-.security-property {
-    height: 16px;
-    width: 16px;
-
-    -webkit-mask-image: url(Images/securityIcons.png);
-    -webkit-mask-size: 80px 32px;
-
-    background-color: #888;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-    .lock-icon,
-    .security-property {
-        -webkit-mask-image: url(Images/securityIcons_2x.png);
-    }
-}
-
-.lock-icon-secure {
-    -webkit-mask-position: 0px 0px;
-    background-color: #0B8043;
-}
-
-.lock-icon-unknown,
-.lock-icon-neutral {
-    -webkit-mask-position: -16px 0px;
-    background-color: #000000; /* Black for clarity on lower DPI screens */
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-    .lock-icon-unknown,
-    .lock-icon-neutral {
-        background-color: #5A5A5A; /* Gray for hiDPI screens */
-    }
-}
-
-.lock-icon-insecure {
-    -webkit-mask-position: -32px 0px;
-    background-color: #C63626;
-}
-
-.security-property-secure {
-    -webkit-mask-position: 0px -16px;
-    background-color: #0B8043;
-}
-
-.security-property-neutral {
-    -webkit-mask-position: -16px -16px;
-    background-color: #C63626;
-}
-
-.security-property-insecure {
-    -webkit-mask-position: -32px -16px;
-    background-color: #C63626;
-}
-
-.security-property-info {
-    -webkit-mask-position: -48px -16px;
-    background-color: rgba(0, 0, 0, 0.5);
-}
-
-.security-property-unknown {
-    -webkit-mask-position: -64px -16px;
-    background-color: rgba(0, 0, 0, 0.5);
-}
-
-.url-scheme-secure {
-    color: #0b8043;
-}
-
-.url-scheme-neutral,
-.url-scheme-insecure {
-    color: #cb3626;
-}
-
-.url-scheme-separator {
-    color: #8a8a8a;
-}
diff --git a/front_end/security/mainView.css b/front_end/security/mainView.css
deleted file mode 100644
index 03a8f32..0000000
--- a/front_end/security/mainView.css
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.security-main-view {
-    -webkit-user-select: text;
-    overflow-x: hidden;
-    overflow-y: auto;
-    background-color: var(--toolbar-bg-color);
-}
-
-.security-main-view > div {
-    flex-shrink: 0;
-}
-
-.security-summary-section-title {
-    font-size: 15px;
-    margin: 12px 16px;
-}
-
-.lock-spectrum {
-    margin: 8px 16px;
-    display: flex;
-    align-items: flex-start;
-}
-
-.security-summary .lock-icon {
-    flex: none;
-    width: 16px;
-    height: 16px;
-    margin: 0 0;
-}
-
-/* Separate the middle icon from the other two. */
-.security-summary .lock-icon-neutral {
-    margin: 0 16px;
-}
-
-.security-summary:not(.security-summary-secure) .lock-icon-secure,
-.security-summary:not(.security-summary-neutral) .lock-icon-neutral,
-.security-summary:not(.security-summary-insecure) .lock-icon-insecure {
-    background-color: rgba(90, 90, 90, 0.25);
-}
-
-.triangle-pointer-container {
-    margin: 8px 24px 0;
-    padding: 0 0;
-}
-
-.triangle-pointer-wrapper {
-    /* Defaults for dynamic properties. */
-    transform: translateX(0);
-    transition: transform 0.3s;
-}
-
-.triangle-pointer {
-    width: 12px;
-    height: 12px;
-    margin-bottom: -6px;
-    margin-left: -6px;
-    transform: rotate(-45deg);
-    border-style: solid;
-    border-width: 1px 1px 0 0;
-
-    background: #fff;
-    border-color: rgb(217, 217, 217);
-}
-
-.security-summary-secure .triangle-pointer-wrapper {
-    transform: translateX(0px);
-}
-
-.security-summary-neutral .triangle-pointer-wrapper {
-    transform: translateX(32px);
-}
-
-.security-summary-insecure .triangle-pointer-wrapper {
-    transform: translateX(64px);
-}
-
-.security-summary-text {
-    padding: 16px 24px;
-    border-style: solid;
-    border-width: 1px 0;
-    font-size: 15px;
-
-    background: #fff;
-    border-color: rgb(217, 217, 217);
-    color: rgba(0, 0, 0, 36);
-}
-
-.security-summary-secure .triangle-pointer,
-.security-summary-secure .security-summary-text,
-.security-explanation-title-secure {
-    color: #0b8043;
-}
-
-.security-summary-neutral .triangle-pointer,
-.security-summary-neutral .security-summary-text {
-    color: rgb(253, 177, 48);
-}
-
-.security-summary-insecure .triangle-pointer,
-.security-summary-insecure .security-summary-text,
-.security-explanation-title-neutral,
-.security-explanation-title-insecure {
-    color: #cb3626;
-}
-
-.security-explanation-list {
-    padding-bottom: 16px;
-}
-
-.security-explanation-list:empty {
-    border-bottom: none;
-    padding: 0px;
-}
-
-.security-explanations-main {
-    margin-top: -5px;
-    background-color: #fff;
-    border-bottom: 1px solid rgb(230, 230, 230);
-}
-
-.security-explanations-extra {
-    background-color: transparent;
-}
-
-.security-explanation {
-    padding: 11px;
-    display: flex;
-    white-space: nowrap;
-    border: none;
-    color: #8c8c8c;
-}
-
-.security-explanation-text {
-    flex: auto;
-    white-space: normal;
-    max-width: 400px;
-}
-
-.security-certificate-button {
-    margin-top: 8px;
-}
-
-.security-explanation .security-property {
-    flex: none;
-    width: 16px;
-    height: 16px;
-    margin-right: 16px;
-}
-
-.security-explanation-title {
-    color: rgb(90, 90, 90);
-    margin-top: 1px;
-    margin-bottom: 8px;
-}
-
-.security-explanation-neutral .security-section-title,
-.security-explanation-warning .security-section-title
-{
-    color: #cb3626;
-    font-weight: bold;
-}
-.security-explanation-insecure .security-section-title
-{
-    color: rgb(216, 71, 60);
-    font-weight: bold;
-}
-
-.security-mixed-content {
-    margin-top: 8px;
-}
diff --git a/front_end/security/module.json b/front_end/security/module.json
deleted file mode 100644
index 48aecf7..0000000
--- a/front_end/security/module.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "security",
-            "title": "Security",
-            "order": 80,
-            "className": "Security.SecurityPanel"
-        }
-    ],
-    "dependencies": ["network", "platform", "ui", "sdk"],
-    "scripts": [
-        "SecurityModel.js",
-        "SecurityPanel.js"
-    ],
-    "resources": [
-        "lockIcon.css",
-        "mainView.css",
-        "originView.css",
-        "sidebar.css"
-    ]
-}
diff --git a/front_end/security/originView.css b/front_end/security/originView.css
deleted file mode 100644
index 299e100..0000000
--- a/front_end/security/originView.css
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.title-section {
-    padding: 16px 0 24px 0;
-    border-bottom: 1px solid rgb(230, 230, 230);
-}
-
-.title-section-header {
-    padding-left: 16px;
-    padding-bottom: 10px;
-    font-size: 14px;
-}
-
-.security-origin-view {
-    overflow-x: hidden;
-    overflow-y: scroll;
-    display: block;
-    -webkit-user-select: text;
-}
-
-.security-origin-view .origin-view-section {
-    border-bottom: 1px solid rgb(230, 230, 230);
-    padding: 12px 6px 12px  24px;
-    font-size:12px;
-}
-
-.origin-view-notes {
-    margin-top: 2px;
-    color: #8c8c8c;
-}
-
-.origin-view-section-notes {
-    margin-top: 6px;
-    color: #8c8c8c;
-}
-
-.security-origin-view .origin-display {
-    font-size: 12px;
-    padding-left: 38px;
-    display: flex;
-    align-items: center;
-}
-
-.title-section > .view-network-button {
-    padding: 6px 0 0 16px
-}
-
-.security-origin-view .origin-display .security-property {
-    display: inline-block;
-    vertical-align: middle;
-    position: absolute;
-    left: 16px;
-}
-
-.security-origin-view .origin-view-section-title {
-    margin-top: 4px;
-    margin-bottom: 4px;
-    font-weight: bold;
-}
-
-.security-origin-view .details-table-row {
-    display: flex;
-    white-space: nowrap;
-    overflow: hidden;
-    line-height: 22px;
-}
-
-.security-origin-view .details-table-row > div {
-    align-items: flex-start;
-}
-
-.security-origin-view .details-table-row > div:first-child {
-    color: rgb(140, 140, 140);
-    width: 110px;
-    margin-right: 1em;
-    flex: none;
-    display: flex;
-    justify-content: flex-end;
-}
-.security-origin-view .details-table-row > div:nth-child(2) {
-    flex: auto;
-    white-space: normal;
-}
-
-.security-origin-view .sct-details .details-table .details-table-row:last-child div:last-child {
-    border-bottom: 1px solid rgb(230, 230, 230);
-    padding-bottom: 10px;
-}
-
-.security-origin-view .sct-details .details-table:last-child .details-table-row:last-child div:last-child {
-    border-bottom: none;
-    padding-bottom: 0;
-}
-
-.security-origin-view .sct-toggle {
-    padding-left: 143px;
-    padding-top: 5px;
-}
-
-.security-origin-view .details-table .empty-san {
-    color: rgb(140, 140, 140);
-}
-
-.security-origin-view .details-table .san-entry {
-    display: block;
-}
-
-.security-origin-view .truncated-san .truncated-entry {
-    display: none;
-}
-
-.origin-button {
-    margin-top: 4px;
-}
-
-.origin-view-section:last-child  {
-    border-bottom:none;
-}
diff --git a/front_end/security/sidebar.css b/front_end/security/sidebar.css
deleted file mode 100644
index 0722eb0..0000000
--- a/front_end/security/sidebar.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tree-outline {
-    padding: 0;
-}
-
-.tree-outline li {
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    padding: 2px 5px;
-    overflow: hidden;
-    margin: 2px 0;
-    border-top: 1px solid transparent;
-    white-space: nowrap;
-}
-
-.tree-outline li.selected:focus .lock-icon,
-.tree-outline .security-sidebar-tree-item.selected:focus .icon
-{
-    background-color: var(--selection-fg-color);
-}
-
-.tree-outline .security-main-view-sidebar-tree-item {
-    border-bottom: 1px solid rgb(230, 230, 230);
-    padding: 16px 0;
-}
-
-.tree-outline li.security-sidebar-origins {
-    padding: 1px 8px 1px 13px;
-    margin-top: 1em;
-    margin-bottom: 0.5em;
-    color: rgb(90, 90, 90);
-    border-top: none;
-    line-height: 16px;
-    text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
-}
-
-.tree-outline ol {
-    padding-left: 0;
-}
-
-.tree-outline li::before {
-    content: none;
-}
-
-.tree-outline .security-main-view-sidebar-tree-item,
-.tree-outline .security-sidebar-origins,
-.tree-outline li.security-sidebar-origins + .children > li {
-    padding-left: 16px;
-}
-
-.tree-outline .lock-icon,
-.tree-outline .security-property {
-    margin-right: 4px;
-    flex: none;
-}
-
-.security-sidebar-tree-item {
-    padding: 2px 0;
-}
-
-.security-sidebar-tree-item .title {
-    overflow: hidden;
-    margin-right: 5px;
-}
-
-.security-main-view-reload-message .tree-element-title {
-    color: rgba(0, 0, 0, 0.5);
-    padding-left: 8px;
-}
diff --git a/front_end/security_test_runner/SecurityTestRunner.js b/front_end/security_test_runner/SecurityTestRunner.js
deleted file mode 100644
index 96ac4a9..0000000
--- a/front_end/security_test_runner/SecurityTestRunner.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-SecurityTestRunner.dumpSecurityPanelSidebarOrigins = function() {
-  for (const key in Security.SecurityPanelSidebarTree.OriginGroupName) {
-    const originGroupName = Security.SecurityPanelSidebarTree.OriginGroupName[key];
-    const originGroup = Security.SecurityPanel._instance()._sidebarTree._originGroups.get(originGroupName);
-
-    if (originGroup.hidden)
-      continue;
-
-    TestRunner.addResult('Group: ' + originGroupName);
-    const originTitles = originGroup.childrenListElement.getElementsByTagName('span');
-
-    for (const originTitle of originTitles) {
-      if (originTitle.className !== 'tree-element-title')
-        TestRunner.dumpDeepInnerHTML(originTitle);
-    }
-  }
-};
-
-SecurityTestRunner.dispatchRequestFinished = function(request) {
-  TestRunner.networkManager.dispatchEventToListeners(SDK.NetworkManager.Events.RequestFinished, request);
-};
diff --git a/front_end/security_test_runner/module.json b/front_end/security_test_runner/module.json
deleted file mode 100644
index 58246b6..0000000
--- a/front_end/security_test_runner/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "security"
-  ],
-  "scripts": [
-    "SecurityTestRunner.js"
-  ],
-  "skip_compilation": [
-    "SecurityTestRunner.js"
-  ]
-}
diff --git a/front_end/services/ServiceManager.js b/front_end/services/ServiceManager.js
deleted file mode 100644
index b142533..0000000
--- a/front_end/services/ServiceManager.js
+++ /dev/null
@@ -1,394 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Services.ServiceManager = class {
-  /**
-   * @param {string} serviceName
-   * @return {!Promise<?Services.ServiceManager.Service>}
-   */
-  createRemoteService(serviceName) {
-    if (!this._remoteConnection) {
-      const url = Runtime.queryParam('service-backend');
-      if (!url) {
-        console.error('No endpoint address specified');
-        return /** @type {!Promise<?Services.ServiceManager.Service>} */ (Promise.resolve(null));
-      }
-      this._remoteConnection =
-          new Services.ServiceManager.Connection(new Services.ServiceManager.RemoteServicePort(url));
-    }
-    return this._remoteConnection._createService(serviceName);
-  }
-
-  /**
-   * @param {string} appName
-   * @param {string} serviceName
-   * @return {!Promise<?Services.ServiceManager.Service>}
-   */
-  createAppService(appName, serviceName) {
-    let url = appName + '.js';
-    const remoteBase = Runtime.queryParam('remoteBase');
-    const debugFrontend = Runtime.queryParam('debugFrontend');
-    const isUnderTest = Host.isUnderTest();
-
-    const queryParams = [];
-    if (remoteBase)
-      queryParams.push('remoteBase=' + remoteBase);
-    if (debugFrontend)
-      queryParams.push('debugFrontend=' + debugFrontend);
-    if (isUnderTest)
-      queryParams.push('isUnderTest=true');
-
-    if (queryParams.length)
-      url += `?${queryParams.join('&')}`;
-
-    const worker = new Worker(url);
-    const connection = new Services.ServiceManager.Connection(new Services.ServiceManager.WorkerServicePort(worker));
-    return connection._createService(serviceName);
-  }
-};
-
-/**
- * @unrestricted
- */
-Services.ServiceManager.Connection = class {
-  /**
-   * @param {!ServicePort} port
-   */
-  constructor(port) {
-    this._port = port;
-    this._port.setHandlers(this._onMessage.bind(this), this._connectionClosed.bind(this));
-
-    this._lastId = 1;
-    /** @type {!Map<number, function(?Object)>}*/
-    this._callbacks = new Map();
-    /** @type {!Map<string, !Services.ServiceManager.Service>}*/
-    this._services = new Map();
-  }
-
-  /**
-   * @param {string} serviceName
-   * @return {!Promise<?Services.ServiceManager.Service>}
-   */
-  _createService(serviceName) {
-    return this._sendCommand(serviceName + '.create').then(result => {
-      if (!result) {
-        console.error('Could not initialize service: ' + serviceName);
-        return null;
-      }
-      const service = new Services.ServiceManager.Service(this, serviceName, result.id);
-      this._services.set(serviceName + ':' + result.id, service);
-      return service;
-    });
-  }
-
-  /**
-   * @param {!Services.ServiceManager.Service} service
-   */
-  _serviceDisposed(service) {
-    this._services.delete(service._serviceName + ':' + service._objectId);
-    if (!this._services.size) {
-      // Terminate the connection since it is no longer used.
-      this._port.close();
-    }
-  }
-
-  /**
-   * @param {string} method
-   * @param {!Object=} params
-   * @return {!Promise<?Object>}
-   */
-  _sendCommand(method, params) {
-    const id = this._lastId++;
-    const message = JSON.stringify({id: id, method: method, params: params || {}});
-    return this._port.send(message).then(success => {
-      if (!success)
-        return Promise.resolve(null);
-      return new Promise(fulfill => this._callbacks.set(id, fulfill));
-    });
-  }
-
-  /**
-   * @param {string} data
-   */
-  _onMessage(data) {
-    let object;
-    try {
-      object = JSON.parse(data);
-    } catch (e) {
-      console.error(e);
-      return;
-    }
-    if (object.id) {
-      if (object.error)
-        console.error('Service error: ' + object.error);
-      this._callbacks.get(object.id)(object.error ? null : object.result);
-      this._callbacks.delete(object.id);
-      return;
-    }
-
-    const tokens = object.method.split('.');
-    const serviceName = tokens[0];
-    const methodName = tokens[1];
-    const service = this._services.get(serviceName + ':' + object.params.id);
-    if (!service) {
-      console.error('Unable to lookup stub for ' + serviceName + ':' + object.params.id);
-      return;
-    }
-    service._dispatchNotification(methodName, object.params);
-  }
-
-  _connectionClosed() {
-    for (const callback of this._callbacks.values())
-      callback(null);
-    this._callbacks.clear();
-    for (const service of this._services.values())
-      service._dispatchNotification('disposed');
-    this._services.clear();
-  }
-};
-
-/**
- * @unrestricted
- */
-Services.ServiceManager.Service = class {
-  /**
-   * @param {!Services.ServiceManager.Connection} connection
-   * @param {string} serviceName
-   * @param {string} objectId
-   */
-  constructor(connection, serviceName, objectId) {
-    this._connection = connection;
-    this._serviceName = serviceName;
-    this._objectId = objectId;
-    /** @type {!Map<string, function(!Object=)>}*/
-    this._notificationHandlers = new Map();
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  dispose() {
-    const params = {id: this._objectId};
-    return this._connection._sendCommand(this._serviceName + '.dispose', params).then(() => {
-      this._connection._serviceDisposed(this);
-    });
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {function(!Object=)} handler
-   */
-  on(methodName, handler) {
-    this._notificationHandlers.set(methodName, handler);
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {!Object=} params
-   * @return {!Promise}
-   */
-  send(methodName, params) {
-    params = params || {};
-    params.id = this._objectId;
-    return this._connection._sendCommand(this._serviceName + '.' + methodName, params);
-  }
-
-  /**
-   * @param {string} methodName
-   * @param {!Object=} params
-   */
-  _dispatchNotification(methodName, params) {
-    const handler = this._notificationHandlers.get(methodName);
-    if (!handler) {
-      console.error('Could not report notification \'' + methodName + '\' on \'' + this._objectId + '\'');
-      return;
-    }
-    handler(params);
-  }
-};
-
-/**
- * @implements {ServicePort}
- * @unrestricted
- */
-Services.ServiceManager.RemoteServicePort = class {
-  /**
-   * @param {string} url
-   */
-  constructor(url) {
-    this._url = url;
-  }
-
-  /**
-   * @override
-   * @param {function(string)} messageHandler
-   * @param {function(string)} closeHandler
-   */
-  setHandlers(messageHandler, closeHandler) {
-    this._messageHandler = messageHandler;
-    this._closeHandler = closeHandler;
-  }
-
-  /**
-   * @return {!Promise<boolean>}
-   */
-  _open() {
-    if (!this._connectionPromise)
-      this._connectionPromise = new Promise(promiseBody.bind(this));
-    return this._connectionPromise;
-
-    /**
-     * @param {function(boolean)} fulfill
-     * @this {Services.ServiceManager.RemoteServicePort}
-     */
-    function promiseBody(fulfill) {
-      let socket;
-      try {
-        socket = new WebSocket(/** @type {string} */ (this._url));
-        socket.onmessage = onMessage.bind(this);
-        socket.onclose = onClose.bind(this);
-        socket.onopen = onConnect.bind(this);
-      } catch (e) {
-        fulfill(false);
-      }
-
-      /**
-       * @this {Services.ServiceManager.RemoteServicePort}
-       */
-      function onConnect() {
-        this._socket = socket;
-        fulfill(true);
-      }
-
-      /**
-       * @param {!Event} event
-       * @this {Services.ServiceManager.RemoteServicePort}
-       */
-      function onMessage(event) {
-        this._messageHandler(event.data);
-      }
-
-      /**
-       * @this {Services.ServiceManager.RemoteServicePort}
-       */
-      function onClose() {
-        if (!this._socket)
-          fulfill(false);
-        this._socketClosed(!!this._socket);
-      }
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   * @return {!Promise<boolean>}
-   */
-  send(message) {
-    return this._open().then(() => {
-      if (this._socket) {
-        this._socket.send(message);
-        return true;
-      }
-      return false;
-    });
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  close() {
-    return this._open().then(() => {
-      if (this._socket) {
-        this._socket.close();
-        this._socketClosed(true);
-      }
-      return true;
-    });
-  }
-
-  /**
-   * @param {boolean=} notifyClient
-   */
-  _socketClosed(notifyClient) {
-    this._socket = null;
-    delete this._connectionPromise;
-    if (notifyClient)
-      this._closeHandler();
-  }
-};
-
-/**
- * @implements {ServicePort}
- * @unrestricted
- */
-Services.ServiceManager.WorkerServicePort = class {
-  /**
-   * @param {!Worker} worker
-   */
-  constructor(worker) {
-    this._worker = worker;
-
-    let fulfill;
-    this._workerPromise = new Promise(resolve => fulfill = resolve);
-
-    this._worker.onmessage = onMessage.bind(this);
-    this._worker.onclose = this._closeHandler;
-
-    /**
-     * @param {!Event} event
-     * @this {Services.ServiceManager.WorkerServicePort}
-     */
-    function onMessage(event) {
-      if (event.data === 'workerReady') {
-        fulfill(true);
-        return;
-      }
-      this._messageHandler(event.data);
-    }
-  }
-
-  /**
-   * @override
-   * @param {function(string)} messageHandler
-   * @param {function(string)} closeHandler
-   */
-  setHandlers(messageHandler, closeHandler) {
-    this._messageHandler = messageHandler;
-    this._closeHandler = closeHandler;
-  }
-
-  /**
-   * @override
-   * @param {string} message
-   * @return {!Promise<boolean>}
-   */
-  send(message) {
-    return this._workerPromise.then(() => {
-      try {
-        this._worker.postMessage(message);
-        return true;
-      } catch (e) {
-        return false;
-      }
-    });
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  close() {
-    return this._workerPromise.then(() => {
-      if (this._worker)
-        this._worker.terminate();
-      return false;
-    });
-  }
-};
-
-Services.serviceManager = new Services.ServiceManager();
diff --git a/front_end/services/module.json b/front_end/services/module.json
deleted file mode 100644
index 633b254..0000000
--- a/front_end/services/module.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "dependencies": [
-        "common",
-        "host"
-    ],
-    "scripts": [
-        "ServiceManager.js"
-    ]
-}
diff --git a/front_end/settings/FrameworkBlackboxSettingsTab.js b/front_end/settings/FrameworkBlackboxSettingsTab.js
deleted file mode 100644
index 262d25b..0000000
--- a/front_end/settings/FrameworkBlackboxSettingsTab.js
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-/**
- * @implements {UI.ListWidget.Delegate}
- * @unrestricted
- */
-Settings.FrameworkBlackboxSettingsTab = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('settings/frameworkBlackboxSettingsTab.css');
-
-    this.contentElement.createChild('div', 'header').textContent = Common.UIString('Framework Blackbox Patterns');
-    this.contentElement.createChild('div', 'blackbox-content-scripts')
-        .appendChild(UI.SettingsUI.createSettingCheckbox(
-            Common.UIString('Blackbox content scripts'), Common.moduleSetting('skipContentScripts'), true));
-
-    this._blackboxLabel = Common.UIString('Blackbox');
-    this._disabledLabel = Common.UIString('Disabled');
-
-    this._list = new UI.ListWidget(this);
-    this._list.element.classList.add('blackbox-list');
-    this._list.registerRequiredCSS('settings/frameworkBlackboxSettingsTab.css');
-
-    const placeholder = createElementWithClass('div', 'blackbox-list-empty');
-    placeholder.textContent = Common.UIString('No blackboxed patterns');
-    this._list.setEmptyPlaceholder(placeholder);
-    this._list.show(this.contentElement);
-    const addPatternButton =
-        UI.createTextButton(Common.UIString('Add pattern...'), this._addButtonClicked.bind(this), 'add-button');
-    this.contentElement.appendChild(addPatternButton);
-
-    this._setting = Common.moduleSetting('skipStackFramesPattern');
-    this._setting.addChangeListener(this._settingUpdated, this);
-
-    this.setDefaultFocusedElement(addPatternButton);
-    this.contentElement.tabIndex = 0;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._settingUpdated();
-  }
-
-  _settingUpdated() {
-    this._list.clear();
-    const patterns = this._setting.getAsArray();
-    for (let i = 0; i < patterns.length; ++i)
-      this._list.appendItem(patterns[i], true);
-  }
-
-  _addButtonClicked() {
-    this._list.addNewItem(this._setting.getAsArray().length, {pattern: '', disabled: false});
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(item, editable) {
-    const element = createElementWithClass('div', 'blackbox-list-item');
-    const pattern = element.createChild('div', 'blackbox-pattern');
-    pattern.textContent = item.pattern;
-    pattern.title = item.pattern;
-    element.createChild('div', 'blackbox-separator');
-    element.createChild('div', 'blackbox-behavior').textContent =
-        item.disabled ? this._disabledLabel : this._blackboxLabel;
-    if (item.disabled)
-      element.classList.add('blackbox-disabled');
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {number} index
-   */
-  removeItemRequested(item, index) {
-    const patterns = this._setting.getAsArray();
-    patterns.splice(index, 1);
-    this._setting.setAsArray(patterns);
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @param {!UI.ListWidget.Editor} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {
-    item.pattern = editor.control('pattern').value.trim();
-    item.disabled = editor.control('behavior').value === this._disabledLabel;
-
-    const list = this._setting.getAsArray();
-    if (isNew)
-      list.push(item);
-    this._setting.setAsArray(list);
-  }
-
-  /**
-   * @override
-   * @param {*} item
-   * @return {!UI.ListWidget.Editor}
-   */
-  beginEdit(item) {
-    const editor = this._createEditor();
-    editor.control('pattern').value = item.pattern;
-    editor.control('behavior').value = item.disabled ? this._disabledLabel : this._blackboxLabel;
-    return editor;
-  }
-
-  /**
-   * @return {!UI.ListWidget.Editor}
-   */
-  _createEditor() {
-    if (this._editor)
-      return this._editor;
-
-    const editor = new UI.ListWidget.Editor();
-    this._editor = editor;
-    const content = editor.contentElement();
-
-    const titles = content.createChild('div', 'blackbox-edit-row');
-    titles.createChild('div', 'blackbox-pattern').textContent = Common.UIString('Pattern');
-    titles.createChild('div', 'blackbox-separator blackbox-separator-invisible');
-    titles.createChild('div', 'blackbox-behavior').textContent = Common.UIString('Behavior');
-
-    const fields = content.createChild('div', 'blackbox-edit-row');
-    fields.createChild('div', 'blackbox-pattern')
-        .appendChild(editor.createInput('pattern', 'text', '/framework\\.js$', patternValidator.bind(this)));
-    fields.createChild('div', 'blackbox-separator blackbox-separator-invisible');
-    fields.createChild('div', 'blackbox-behavior')
-        .appendChild(editor.createSelect('behavior', [this._blackboxLabel, this._disabledLabel], behaviorValidator));
-
-    return editor;
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @this {Settings.FrameworkBlackboxSettingsTab}
-     * @return {boolean}
-     */
-    function patternValidator(item, index, input) {
-      const pattern = input.value.trim();
-      const patterns = this._setting.getAsArray();
-      for (let i = 0; i < patterns.length; ++i) {
-        if (i !== index && patterns[i].pattern === pattern)
-          return false;
-      }
-
-      let regex;
-      try {
-        regex = new RegExp(pattern);
-      } catch (e) {
-      }
-      return !!(pattern && regex);
-    }
-
-    /**
-     * @param {*} item
-     * @param {number} index
-     * @param {!HTMLInputElement|!HTMLSelectElement} input
-     * @return {boolean}
-     */
-    function behaviorValidator(item, index, input) {
-      return true;
-    }
-  }
-};
diff --git a/front_end/settings/SettingsScreen.js b/front_end/settings/SettingsScreen.js
deleted file mode 100644
index 2f8d2c9..0000000
--- a/front_end/settings/SettingsScreen.js
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ViewLocationResolver}
- * @unrestricted
- */
-Settings.SettingsScreen = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('settings/settingsScreen.css');
-
-    this.contentElement.tabIndex = 0;
-    this.contentElement.classList.add('settings-window-main');
-    this.contentElement.classList.add('vbox');
-
-    const settingsLabelElement = createElement('div');
-    UI.createShadowRootWithCoreStyles(settingsLabelElement, 'settings/settingsScreen.css')
-        .createChild('div', 'settings-window-title')
-        .textContent = Common.UIString('Settings');
-
-    this._tabbedLocation =
-        UI.viewManager.createTabbedLocation(() => Settings.SettingsScreen._showSettingsScreen(), 'settings-view');
-    const tabbedPane = this._tabbedLocation.tabbedPane();
-    tabbedPane.leftToolbar().appendToolbarItem(new UI.ToolbarItem(settingsLabelElement));
-    tabbedPane.setShrinkableTabs(false);
-    tabbedPane.makeVerticalTabLayout();
-    const shortcutsView = new UI.SimpleView(Common.UIString('Shortcuts'));
-    UI.shortcutsScreen.createShortcutsTabView().show(shortcutsView.element);
-    this._tabbedLocation.appendView(shortcutsView);
-    tabbedPane.show(this.contentElement);
-
-    this.element.addEventListener('keydown', this._keyDown.bind(this), false);
-    this._developerModeCounter = 0;
-    this.setDefaultFocusedElement(this.contentElement);
-  }
-
-  /**
-   * @param {string=} name
-   */
-  static _showSettingsScreen(name) {
-    const settingsScreen =
-        /** @type {!Settings.SettingsScreen} */ (self.runtime.sharedInstance(Settings.SettingsScreen));
-    if (settingsScreen.isShowing())
-      return;
-    const dialog = new UI.Dialog();
-    dialog.addCloseButton();
-    settingsScreen.show(dialog.contentElement);
-    dialog.show();
-    settingsScreen._selectTab(name || 'preferences');
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   * @return {?UI.ViewLocation}
-   */
-  resolveLocation(locationName) {
-    return this._tabbedLocation;
-  }
-
-  /**
-   * @param {string} name
-   */
-  _selectTab(name) {
-    UI.viewManager.showView(name);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _keyDown(event) {
-    const shiftKeyCode = 16;
-    if (event.keyCode === shiftKeyCode && ++this._developerModeCounter > 5)
-      this.contentElement.classList.add('settings-developer-mode');
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Settings.SettingsTab = class extends UI.VBox {
-  /**
-   * @param {string} name
-   * @param {string=} id
-   */
-  constructor(name, id) {
-    super();
-    this.element.classList.add('settings-tab-container');
-    if (id)
-      this.element.id = id;
-    const header = this.element.createChild('header');
-    header.createChild('h3').createTextChild(name);
-    this.containerElement = this.element.createChild('div', 'settings-container-wrapper')
-                                .createChild('div', 'settings-tab settings-content settings-container');
-  }
-
-  /**
-   *  @param {string=} name
-   *  @return {!Element}
-   */
-  _appendSection(name) {
-    const block = this.containerElement.createChild('div', 'settings-block');
-    if (name)
-      block.createChild('div', 'settings-section-title').textContent = name;
-    return block;
-  }
-};
-
-/**
- * @unrestricted
- */
-Settings.GenericSettingsTab = class extends Settings.SettingsTab {
-  constructor() {
-    super(Common.UIString('Preferences'), 'preferences-tab-content');
-
-    /** @const */
-    const explicitSectionOrder =
-        ['', 'Appearance', 'Sources', 'Elements', 'Network', 'Performance', 'Console', 'Extensions'];
-    /** @type {!Map<string, !Element>} */
-    this._nameToSection = new Map();
-    for (const sectionName of explicitSectionOrder)
-      this._sectionElement(sectionName);
-    self.runtime.extensions('setting').forEach(this._addSetting.bind(this));
-    self.runtime.extensions(UI.SettingUI).forEach(this._addSettingUI.bind(this));
-
-    this._appendSection().appendChild(
-        UI.createTextButton(Common.UIString('Restore defaults and reload'), restoreAndReload));
-
-    function restoreAndReload() {
-      Common.settings.clearAll();
-      Components.reload();
-    }
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   * @return {boolean}
-   */
-  static isSettingVisible(extension) {
-    const descriptor = extension.descriptor();
-    if (!('title' in descriptor))
-      return false;
-    if (!('category' in descriptor))
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  _addSetting(extension) {
-    if (!Settings.GenericSettingsTab.isSettingVisible(extension))
-      return;
-    const sectionElement = this._sectionElement(extension.descriptor()['category']);
-    const setting = Common.moduleSetting(extension.descriptor()['settingName']);
-    const settingControl = UI.SettingsUI.createControlForSetting(setting);
-    if (settingControl)
-      sectionElement.appendChild(settingControl);
-  }
-
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  _addSettingUI(extension) {
-    const descriptor = extension.descriptor();
-    const sectionName = descriptor['category'] || '';
-    extension.instance().then(appendCustomSetting.bind(this));
-
-    /**
-     * @param {!Object} object
-     * @this {Settings.GenericSettingsTab}
-     */
-    function appendCustomSetting(object) {
-      const settingUI = /** @type {!UI.SettingUI} */ (object);
-      const element = settingUI.settingElement();
-      if (element)
-        this._sectionElement(sectionName).appendChild(element);
-    }
-  }
-
-  /**
-   * @param {string} sectionName
-   * @return {!Element}
-   */
-  _sectionElement(sectionName) {
-    let sectionElement = this._nameToSection.get(sectionName);
-    if (!sectionElement) {
-      const uiSectionName = sectionName && Common.UIString(sectionName);
-      sectionElement = this._appendSection(uiSectionName);
-      this._nameToSection.set(sectionName, sectionElement);
-    }
-    return sectionElement;
-  }
-};
-
-/**
- * @unrestricted
- */
-Settings.ExperimentsSettingsTab = class extends Settings.SettingsTab {
-  constructor() {
-    super(Common.UIString('Experiments'), 'experiments-tab-content');
-
-    const experiments = Runtime.experiments.allConfigurableExperiments();
-    if (experiments.length) {
-      const experimentsSection = this._appendSection();
-      experimentsSection.appendChild(this._createExperimentsWarningSubsection());
-      for (let i = 0; i < experiments.length; ++i)
-        experimentsSection.appendChild(this._createExperimentCheckbox(experiments[i]));
-    }
-  }
-
-  /**
-   * @return {!Element} element
-   */
-  _createExperimentsWarningSubsection() {
-    const subsection = createElement('div');
-    const warning = subsection.createChild('span', 'settings-experiments-warning-subsection-warning');
-    warning.textContent = Common.UIString('WARNING:');
-    subsection.createTextChild(' ');
-    const message = subsection.createChild('span', 'settings-experiments-warning-subsection-message');
-    message.textContent = Common.UIString('These experiments could be dangerous and may require restart.');
-    return subsection;
-  }
-
-  _createExperimentCheckbox(experiment) {
-    const label = UI.CheckboxLabel.create(Common.UIString(experiment.title), experiment.isEnabled());
-    const input = label.checkboxElement;
-    input.name = experiment.name;
-    function listener() {
-      experiment.setEnabled(input.checked);
-    }
-    input.addEventListener('click', listener, false);
-
-    const p = createElement('p');
-    p.className = experiment.hidden && !experiment.isEnabled() ? 'settings-experiment-hidden' : '';
-    p.appendChild(label);
-    return p;
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Settings.SettingsScreen.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    switch (actionId) {
-      case 'settings.show':
-        Settings.SettingsScreen._showSettingsScreen();
-        return true;
-      case 'settings.documentation':
-        InspectorFrontendHost.openInNewTab('https://developers.google.com/web/tools/chrome-devtools/');
-        return true;
-      case 'settings.shortcuts':
-        Settings.SettingsScreen._showSettingsScreen(Common.UIString('Shortcuts'));
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Settings.SettingsScreen.Revealer = class {
-  /**
-   * @override
-   * @param {!Object} object
-   * @return {!Promise}
-   */
-  reveal(object) {
-    console.assert(object instanceof Common.Setting);
-    const setting = /** @type {!Common.Setting} */ (object);
-    let success = false;
-
-    self.runtime.extensions('setting').forEach(revealModuleSetting);
-    self.runtime.extensions(UI.SettingUI).forEach(revealSettingUI);
-    self.runtime.extensions('view').forEach(revealSettingsView);
-
-    return success ? Promise.resolve() : Promise.reject();
-
-    /**
-     * @param {!Runtime.Extension} extension
-     */
-    function revealModuleSetting(extension) {
-      if (!Settings.GenericSettingsTab.isSettingVisible(extension))
-        return;
-      if (extension.descriptor()['settingName'] === setting.name) {
-        InspectorFrontendHost.bringToFront();
-        Settings.SettingsScreen._showSettingsScreen();
-        success = true;
-      }
-    }
-
-    /**
-     * @param {!Runtime.Extension} extension
-     */
-    function revealSettingUI(extension) {
-      const settings = extension.descriptor()['settings'];
-      if (settings && settings.indexOf(setting.name) !== -1) {
-        InspectorFrontendHost.bringToFront();
-        Settings.SettingsScreen._showSettingsScreen();
-        success = true;
-      }
-    }
-
-    /**
-     * @param {!Runtime.Extension} extension
-     */
-    function revealSettingsView(extension) {
-      const location = extension.descriptor()['location'];
-      if (location !== 'settings-view')
-        return;
-      const settings = extension.descriptor()['settings'];
-      if (settings && settings.indexOf(setting.name) !== -1) {
-        InspectorFrontendHost.bringToFront();
-        Settings.SettingsScreen._showSettingsScreen(extension.descriptor()['id']);
-        success = true;
-      }
-    }
-  }
-};
diff --git a/front_end/settings/frameworkBlackboxSettingsTab.css b/front_end/settings/frameworkBlackboxSettingsTab.css
deleted file mode 100644
index cf607ac..0000000
--- a/front_end/settings/frameworkBlackboxSettingsTab.css
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    overflow:hidden;
-}
-
-.header {
-    padding: 0 0 6px;
-    border-bottom: 1px solid #EEEEEE;
-    font-size: 18px;
-    font-weight: normal;
-    flex: none;
-}
-
-.blackbox-content-scripts {
-    margin-top: 10px;
-    flex: none;
-}
-
-.add-button {
-    margin: 10px 2px;
-    align-self: flex-start;
-    flex: none;
-}
-
-.blackbox-list {
-    margin-top: 10px;
-    max-width: 500px;
-    flex: 0 1 auto;
-    min-height: 30px;
-}
-
-.blackbox-list-empty {
-    flex: auto;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.blackbox-list-item {
-    padding: 3px 5px 3px 5px;
-    height: 30px;
-    display: flex;
-    align-items: center;
-    position: relative;
-    flex: auto 1 1;
-}
-
- .blackbox-list-item .blackbox-pattern {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    -webkit-user-select: none;
-    color: #222;
-    overflow: hidden;
-}
-
-.blackbox-pattern {
-    flex: auto;
-    min-width: 100px;
-}
-
-.blackbox-list-item.blackbox-disabled .blackbox-pattern {
-    text-decoration: line-through;
-}
-
-.blackbox-behavior {
-    flex: 0 0 100px;
-    padding-left: 10px;
-}
-
-.blackbox-behavior > select {
-    margin-left: -10px;
-}
-
-.blackbox-separator {
-    flex: 0 0 1px;
-    background-color: rgb(231, 231, 231);
-    height: 30px;
-    margin: 0 4px;
-}
-
-.blackbox-separator-invisible {
-    visibility: hidden;
-    height: 100% !important;
-}
-
-.blackbox-edit-row {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    margin: 6px 5px;
-    align-items: center;
-}
-
-.blackbox-edit-row input,
-.blackbox-edit-row select {
-    width: 100%;
-    text-align: inherit;
-}
diff --git a/front_end/settings/module.json b/front_end/settings/module.json
deleted file mode 100644
index 6c551ce..0000000
--- a/front_end/settings/module.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "action",
-            "category": "Settings",
-            "actionId": "settings.show",
-            "title": "Settings",
-            "className": "Settings.SettingsScreen.ActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "F1 Shift+?"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Settings",
-            "actionId": "settings.documentation",
-            "title": "Documentation",
-            "className": "Settings.SettingsScreen.ActionDelegate"
-        },
-        {
-            "type": "action",
-            "category": "Settings",
-            "actionId": "settings.shortcuts",
-            "title": "Shortcuts",
-            "className": "Settings.SettingsScreen.ActionDelegate"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "Common.Setting"
-            ],
-            "className": "Settings.SettingsScreen.Revealer"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "mainMenu/footer",
-            "actionId": "settings.shortcuts"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "mainMenuHelp/default",
-            "actionId": "settings.documentation"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "mainMenu/footer",
-            "actionId": "settings.show"
-        },
-        {
-            "type": "view",
-            "location": "settings-view",
-            "id": "preferences",
-            "title": "Preferences",
-            "order": 0,
-            "className": "Settings.GenericSettingsTab"
-        },
-        {
-            "type": "view",
-            "location": "settings-view",
-            "id": "experiments",
-            "title": "Experiments",
-            "order": 3,
-            "experiment": "*",
-            "className": "Settings.ExperimentsSettingsTab"
-        },
-        {
-            "type": "view",
-            "location": "settings-view",
-            "id": "blackbox",
-            "title": "Blackboxing",
-            "order": 4,
-            "className": "Settings.FrameworkBlackboxSettingsTab"
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "settings-view",
-            "category": "Settings",
-            "className": "Settings.SettingsScreen"
-        }
-    ],
-    "dependencies": [
-        "components"
-    ],
-    "scripts": [
-        "SettingsScreen.js",
-        "FrameworkBlackboxSettingsTab.js"
-    ],
-    "resources": [
-        "frameworkBlackboxSettingsTab.css",
-        "settingsScreen.css"
-    ]
-}
diff --git a/front_end/settings/settingsScreen.css b/front_end/settings/settingsScreen.css
deleted file mode 100644
index 47c80a7..0000000
--- a/front_end/settings/settingsScreen.css
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.settings-window-main {
-    color: rgb(48, 57, 66);
-    background-color: white;
-    padding: 11px 0 0 0;
-}
-
-.settings-content {
-    overflow-y: auto;
-    overflow-x: hidden;
-    margin: 8px 8px 8px 0;
-    padding: 0 4px;
-    flex: auto;
-}
-
-.settings-footnote {
-    border-top: 1px solid #EEEEEE;
-    margin: 0;
-    padding: 12px;
-}
-
-.settings-container {
-    width: 100%;
-    -webkit-column-width: 288px;
-}
-
-.settings-block {
-    display: block;
-    padding-bottom: 9px;
-    width: 288px;
-    -webkit-column-break-inside: avoid;
-}
-
-.settings-tab.settings-container {
-    -webkit-column-width: 308px;
-}
-
-.settings-tab .settings-block {
-    margin-left: 20px;
-}
-
-.settings-tab .field-error-message {
-    color: DarkRed;
-    height: 0; /* Avoid changing element height when content is set. */
-}
-
-.settings-line {
-    padding-bottom: 5px;
-    margin-bottom: 5px;
-}
-
-.settings-key-cell {
-    display: inline-block;
-    width: 153px;
-    white-space: nowrap;
-    text-align: right;
-    vertical-align: middle;
-    padding-right: 6px;
-}
-
-.settings-cell {
-    display: inline-block;
-    width: 135px;
-    vertical-align: middle;
-}
-
-.settings-section-title {
-    font-size: 120%;
-    text-align: left;
-}
-
-.settings-key {
-    padding: 0.1em 0.6em;
-    border: 1px solid #ccc;
-    font-size: 11px;
-    background-color: #f7f7f7;
-    color: #333;
-    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset;
-    border-radius: 3px;
-    display: inline-block;
-    margin: 0 0.1em;
-    text-shadow: 0 1px 0 #fff;
-    line-height: 1.5;
-    white-space: nowrap;
-}
-
-.settings-combine-keys,
-.settings-key-delimiter {
-    font-size: 9px;
-}
-
-.settings-combine-keys {
-    margin: 0 0.3em;
-}
-
-.settings-key-delimiter {
-    margin: 0 0.5em;
-    display: none;
-}
-
-fieldset {
-    margin: 0;
-    padding: 0;
-    border: none;
-}
-
-.settings-tab label {
-    padding-right: 4px;
-    display: inline-flex;
-    flex-shrink: 0;
-}
-
-#general-tab-content .settings-block fieldset legend {
-    font-size: 14px;
-}
-
-.settings-block p p {
-    padding-left: 30px;
-}
-
-.settings-content p.settings-section {
-    margin: 0 0 15px 0;
-}
-
-.settings-experiments-warning-subsection-warning {
-    color: rgb(200, 0, 0);
-}
-
-.settings-experiments-warning-subsection-message {
-    color: inherit;
-}
-
-.settings-content input[type=checkbox] {
-    margin: 1px 7px 1px 2px;
-}
-
-.settings-window-title {
-    font-size: 18px;
-    color: rgb(48, 57, 66);
-    padding: 0 0 5px 13px;
-}
-
-.settings-container-wrapper {
-    position: absolute;
-    top: 31px;
-    left: 0px;
-    right: 0;
-    bottom: 0;
-    overflow: auto;
-    padding-top: 9px;
-}
-
-.settings-tab.settings-content {
-    margin: 0;
-    padding: 0;
-}
-
-.settings-tab input.numeric {
-    text-align: right;
-}
-
-.settings-tab-container {
-    flex: auto;
-    overflow: hidden;
-}
-
-.settings-tab-container header {
-    padding: 0 0 6px;
-    border-bottom: 1px solid #EEEEEE;
-}
-
-#experiments-tab-content .settings-container {
-    -webkit-column-width: 470px;
-}
-
-#experiments-tab-content .settings-block {
-    width: 470px;
-    margin-left: 0;
-}
-
-.settings-tab-container header > h3 {
-    font-size: 18px;
-    font-weight: normal;
-    margin: 0;
-    padding-bottom: 3px;
-}
-
-.settings-tab .settings-section-title {
-    margin-left: -20px;
-    color: #222;
-}
-
-.settings-tab .settings-block fieldset:disabled label:hover {
-    color: inherit;
-}
-
-.settings-tab .settings-block label:hover {
-    color: #222;
-}
-
-.settings-tab p {
-    margin: 12px 0;
-}
-
-.settings-tab select {
-    margin-left: 10px;
-}
-
-.settings-indent-labels label {
-    padding-left: 10px;
-}
-
-.settings-experiment-hidden {
-    display: none;
-}
-
-.settings-experiment-hidden label {
-    background-color: #ddd;
-}
-
-.settings-developer-mode .settings-experiment-hidden {
-    display: block;
-}
diff --git a/front_end/shell.json b/front_end/shell.json
deleted file mode 100644
index faac3fd..0000000
--- a/front_end/shell.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "modules" : [
-    { "name": "bindings", "type": "autostart" },
-    { "name": "common", "type": "autostart" },
-    { "name": "components", "type": "autostart"},
-    { "name": "console_counters", "type": "autostart" },
-    { "name": "dom_extension", "type": "autostart" },
-    { "name": "extensions", "type": "autostart" },
-    { "name": "host", "type": "autostart" },
-    { "name": "main", "type": "autostart" },
-    { "name": "persistence", "type": "autostart" },
-    { "name": "platform", "type": "autostart" },
-    { "name": "product_registry", "type": "autostart" },
-    { "name": "protocol", "type": "autostart" },
-    { "name": "sdk", "type": "autostart" },
-    { "name": "browser_sdk", "type": "autostart" },
-    { "name": "services", "type": "autostart" },
-    { "name": "text_utils", "type": "autostart" },
-    { "name": "ui", "type": "autostart" },
-    { "name": "workspace", "type": "autostart" },
-
-    { "name": "changes" },
-    { "name": "cm" },
-    { "name": "cm_modes", "type": "remote" },
-    { "name": "color_picker" },
-    { "name": "console" },
-    { "name": "coverage" },
-    { "name": "data_grid" },
-    { "name": "diff" },
-    { "name": "event_listeners" },
-    { "name": "formatter" },
-    { "name": "heap_snapshot_model" },
-    { "name": "inline_editor" },
-    { "name": "object_ui" },
-    { "name": "perf_ui" },
-    { "name": "profiler" },
-    { "name": "quick_open" },
-    { "name": "search" },
-    { "name": "settings" },
-    { "name": "snippets" },
-    { "name": "source_frame" },
-    { "name": "sources" },
-    { "name": "terminal", "type": "remote" },
-    { "name": "text_editor" },
-    { "name": "workspace_diff" },
-    { "name": "protocol_monitor"}
-  ]
-}
diff --git a/front_end/snippets/ScriptSnippetModel.js b/front_end/snippets/ScriptSnippetModel.js
deleted file mode 100644
index 02e6e2a..0000000
--- a/front_end/snippets/ScriptSnippetModel.js
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @unrestricted
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- * @implements {Bindings.DebuggerSourceMapping}
- */
-Snippets.ScriptSnippetModel = class extends Common.Object {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(workspace) {
-    super();
-    this._workspace = workspace;
-    /** @type {!Object.<string, !Workspace.UISourceCode>} */
-    this._uiSourceCodeForSnippetId = {};
-    /** @type {!Map.<!Workspace.UISourceCode, string>} */
-    this._snippetIdForUISourceCode = new Map();
-
-    /** @type {!Map.<!SDK.DebuggerModel, !Snippets.SnippetScriptMapping>} */
-    this._mappingForDebuggerModel = new Map();
-    this._snippetStorage = new Snippets.SnippetStorage('script', 'Script snippet #');
-    this._lastSnippetEvaluationIndexSetting = Common.settings.createSetting('lastSnippetEvaluationIndex', 0);
-    this._project = new Snippets.SnippetsProject(workspace, this);
-    this._loadSnippets();
-    SDK.targetManager.observeModels(SDK.DebuggerModel, this);
-    Bindings.debuggerWorkspaceBinding.addSourceMapping(this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelAdded(debuggerModel) {
-    this._mappingForDebuggerModel.set(debuggerModel, new Snippets.SnippetScriptMapping(debuggerModel, this));
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    this._mappingForDebuggerModel.remove(debuggerModel);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const mapping = this._mappingForDebuggerModel.get(rawLocation.debuggerModel);
-    if (!mapping)
-      return null;
-    return mapping.rawLocationToUILocation(rawLocation);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    for (const mapping of this._mappingForDebuggerModel.values()) {
-      const rawLocation = mapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
-      if (rawLocation)
-        return rawLocation;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @return {!Snippets.SnippetScriptMapping|undefined}
-   */
-  snippetScriptMapping(debuggerModel) {
-    return this._mappingForDebuggerModel.get(debuggerModel);
-  }
-
-  /**
-   * @return {!Workspace.Project}
-   */
-  project() {
-    return this._project;
-  }
-
-  _loadSnippets() {
-    for (const snippet of this._snippetStorage.snippets())
-      this._addScriptSnippet(snippet);
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Workspace.UISourceCode}
-   */
-  createScriptSnippet(content) {
-    const snippet = this._snippetStorage.createSnippet();
-    snippet.content = content;
-    return this._addScriptSnippet(snippet);
-  }
-
-  /**
-   * @param {!Snippets.Snippet} snippet
-   * @return {!Workspace.UISourceCode}
-   */
-  _addScriptSnippet(snippet) {
-    const uiSourceCode = this._project.addSnippet(snippet.name, new Snippets.SnippetContentProvider(snippet));
-    uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
-    this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id);
-    const breakpointLocations = this._removeBreakpoints(uiSourceCode);
-    this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-    this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
-    return uiSourceCode;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyChanged(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._scriptSnippetEdited(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  deleteScriptSnippet(uiSourceCode) {
-    const snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || '';
-    const snippet = this._snippetStorage.snippetForId(snippetId);
-    if (!snippet)
-      return;
-    this._snippetStorage.deleteSnippet(snippet);
-    this._removeBreakpoints(uiSourceCode);
-    this._releaseSnippetScript(uiSourceCode);
-    delete this._uiSourceCodeForSnippetId[snippet.id];
-    this._snippetIdForUISourceCode.remove(uiSourceCode);
-    this._project.removeFile(snippet.name);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} newName
-   * @param {function(boolean, string=)} callback
-   */
-  renameScriptSnippet(name, newName, callback) {
-    newName = newName.trim();
-    if (!newName || newName.indexOf('/') !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) {
-      callback(false);
-      return;
-    }
-    const snippet = this._snippetStorage.snippetForName(name);
-    console.assert(snippet, 'Snippet \'' + name + '\' was not found.');
-    const uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id];
-    console.assert(uiSourceCode, 'No uiSourceCode was found for snippet \'' + name + '\'.');
-
-    const breakpointLocations = this._removeBreakpoints(uiSourceCode);
-    snippet.name = newName;
-    this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-    callback(true, newName);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} newContent
-   */
-  _setScriptSnippetContent(name, newContent) {
-    const snippet = this._snippetStorage.snippetForName(name);
-    snippet.content = newContent;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _scriptSnippetEdited(uiSourceCode) {
-    const breakpointLocations = this._removeBreakpoints(uiSourceCode);
-    this._releaseSnippetScript(uiSourceCode);
-    this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-    this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) {
-      mapping._restoreBreakpoints(uiSourceCode, breakpointLocations);
-    });
-  }
-
-  /**
-   * @return {number}
-   */
-  _nextEvaluationIndex() {
-    const evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
-    this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
-    return evaluationIndex;
-  }
-
-  /**
-   * @param {!SDK.ExecutionContext} executionContext
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<undefined>}
-   */
-  async evaluateScriptSnippet(executionContext, uiSourceCode) {
-    console.assert(uiSourceCode.project().type() === Workspace.projectTypes.Snippets);
-    let breakpointLocations = this._removeBreakpoints(uiSourceCode);
-    this._releaseSnippetScript(uiSourceCode);
-    this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-
-    const runtimeModel = executionContext.runtimeModel;
-    const debuggerModel = executionContext.debuggerModel;
-    const evaluationIndex = this._nextEvaluationIndex();
-    const mapping = this._mappingForDebuggerModel.get(debuggerModel);
-    mapping._setEvaluationIndex(evaluationIndex, uiSourceCode);
-    const evaluationUrl = mapping._evaluationSourceURL(uiSourceCode);
-    await uiSourceCode.requestContent();
-    const expression = uiSourceCode.workingCopy();
-    Common.console.show();
-    const result = await runtimeModel.compileScript(expression, '', true, executionContext.id);
-    if (!result || mapping.evaluationIndex(uiSourceCode) !== evaluationIndex)
-      return;
-    const script = /** @type {!SDK.Script} */ (
-        debuggerModel.scriptForId(/** @type {string} */ (result.scriptId || result.exceptionDetails.scriptId)));
-    mapping._addScript(script, uiSourceCode);
-    if (!result.scriptId) {
-      this._printRunOrCompileScriptResultFailure(
-          runtimeModel, /** @type {!Protocol.Runtime.ExceptionDetails} */ (result.exceptionDetails), evaluationUrl);
-      return;
-    }
-
-    breakpointLocations = this._removeBreakpoints(uiSourceCode);
-    this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-
-    this._runScript(script.scriptId, executionContext, evaluationUrl);
-  }
-
-  /**
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {!SDK.ExecutionContext} executionContext
-   * @param {?string=} sourceURL
-   */
-  async _runScript(scriptId, executionContext, sourceURL) {
-    const runtimeModel = executionContext.runtimeModel;
-    const result = await runtimeModel.runScript(
-        scriptId, executionContext.id, 'console', /* silent */ false, /* includeCommandLineAPI */ true,
-        /* returnByValue */ false, /* generatePreview */ true);
-    if (result.error)
-      return;
-    if (!result.exceptionDetails)
-      this._printRunScriptResult(runtimeModel, result.object || null, scriptId, sourceURL);
-    else
-      this._printRunOrCompileScriptResultFailure(runtimeModel, result.exceptionDetails, sourceURL);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {?SDK.RemoteObject} result
-   * @param {!Protocol.Runtime.ScriptId} scriptId
-   * @param {?string=} sourceURL
-   */
-  _printRunScriptResult(runtimeModel, result, scriptId, sourceURL) {
-    const consoleMessage = new SDK.ConsoleMessage(
-        runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '',
-        SDK.ConsoleMessage.MessageType.Result, sourceURL, undefined, undefined, [result], undefined, undefined,
-        undefined, scriptId);
-    SDK.consoleModel.addMessage(consoleMessage);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel} runtimeModel
-   * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
-   * @param {?string=} sourceURL
-   */
-  _printRunOrCompileScriptResultFailure(runtimeModel, exceptionDetails, sourceURL) {
-    SDK.consoleModel.addMessage(
-        SDK.ConsoleMessage.fromException(runtimeModel, exceptionDetails, undefined, undefined, sourceURL || undefined));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
-   */
-  _removeBreakpoints(uiSourceCode) {
-    const breakpointLocations = Bindings.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
-    for (let i = 0; i < breakpointLocations.length; ++i)
-      breakpointLocations[i].breakpoint.remove(false /* keepInStorage */);
-    return breakpointLocations;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations
-   */
-  _restoreBreakpoints(uiSourceCode, breakpointLocations) {
-    for (let i = 0; i < breakpointLocations.length; ++i) {
-      const uiLocation = breakpointLocations[i].uiLocation;
-      const breakpoint = breakpointLocations[i].breakpoint;
-      Bindings.breakpointManager.setBreakpoint(
-          uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled());
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _releaseSnippetScript(uiSourceCode) {
-    this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) {
-      mapping._releaseSnippetScript(uiSourceCode);
-    });
-  }
-
-  /**
-   * @param {string} sourceURL
-   * @return {?string}
-   */
-  _snippetIdForSourceURL(sourceURL) {
-    const snippetPrefix = Snippets.ScriptSnippetModel.snippetSourceURLPrefix;
-    if (!sourceURL.startsWith(snippetPrefix))
-      return null;
-    const splitURL = sourceURL.substring(snippetPrefix.length).split('_');
-    const snippetId = splitURL[0];
-    return snippetId;
-  }
-};
-
-Snippets.ScriptSnippetModel.snippetSourceURLPrefix = 'snippets:///';
-
-/**
- * @unrestricted
- */
-Snippets.SnippetScriptMapping = class {
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @param {!Snippets.ScriptSnippetModel} scriptSnippetModel
-   */
-  constructor(debuggerModel, scriptSnippetModel) {
-    this._debuggerModel = debuggerModel;
-    this._scriptSnippetModel = scriptSnippetModel;
-    /** @type {!Object.<string, !Workspace.UISourceCode>} */
-    this._uiSourceCodeForScriptId = {};
-    /** @type {!Map.<!Workspace.UISourceCode, !SDK.Script>} */
-    this._scriptForUISourceCode = new Map();
-    /** @type {!Map.<!Workspace.UISourceCode, number>} */
-    this._evaluationIndexForUISourceCode = new Map();
-    debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._reset, this);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _releaseSnippetScript(uiSourceCode) {
-    const script = this._scriptForUISourceCode.get(uiSourceCode);
-    if (!script)
-      return;
-
-    delete this._uiSourceCodeForScriptId[script.scriptId];
-    this._scriptForUISourceCode.remove(uiSourceCode);
-    this._evaluationIndexForUISourceCode.remove(uiSourceCode);
-  }
-
-  /**
-   * @param {number} evaluationIndex
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _setEvaluationIndex(evaluationIndex, uiSourceCode) {
-    this._evaluationIndexForUISourceCode.set(uiSourceCode, evaluationIndex);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {number|undefined}
-   */
-  evaluationIndex(uiSourceCode) {
-    return this._evaluationIndexForUISourceCode.get(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  _evaluationSourceURL(uiSourceCode) {
-    const evaluationSuffix = '_' + this._evaluationIndexForUISourceCode.get(uiSourceCode);
-    const snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);
-    return Snippets.ScriptSnippetModel.snippetSourceURLPrefix + snippetId + evaluationSuffix;
-  }
-
-  _reset() {
-    this._uiSourceCodeForScriptId = {};
-    this._scriptForUISourceCode.clear();
-    this._evaluationIndexForUISourceCode.clear();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const debuggerModelLocation = /** @type {!SDK.DebuggerModel.Location} */ (rawLocation);
-    const uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
-    if (!uiSourceCode)
-      return null;
-
-    return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    const script = this._scriptForUISourceCode.get(uiSourceCode);
-    if (!script)
-      return null;
-
-    return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
-  }
-
-  /**
-   * @param {!SDK.Script} script
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _addScript(script, uiSourceCode) {
-    console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
-    this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
-    this._scriptForUISourceCode.set(uiSourceCode, script);
-    Bindings.debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations
-   */
-  _restoreBreakpoints(uiSourceCode, breakpointLocations) {
-    const script = this._scriptForUISourceCode.get(uiSourceCode);
-    if (!script)
-      return;
-    const rawLocation =
-        /** @type {!SDK.DebuggerModel.Location} */ (this._debuggerModel.createRawLocation(script, 0, 0));
-    const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
-    if (uiLocation)
-      this._scriptSnippetModel._restoreBreakpoints(uiLocation.uiSourceCode, breakpointLocations);
-  }
-};
-
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-Snippets.SnippetContentProvider = class {
-  /**
-   * @param {!Snippets.Snippet} snippet
-   */
-  constructor(snippet) {
-    this._snippet = snippet;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return '';
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return Common.resourceTypes.Snippet;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  contentEncoded() {
-    return Promise.resolve(false);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    return Promise.resolve(/** @type {?string} */ (this._snippet.content));
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  async searchInContent(query, caseSensitive, isRegex) {
-    return Common.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex);
-  }
-};
-
-/**
- * @unrestricted
- */
-Snippets.SnippetsProject = class extends Bindings.ContentProviderBasedProject {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {!Snippets.ScriptSnippetModel} model
-   */
-  constructor(workspace, model) {
-    super(workspace, 'snippets:', Workspace.projectTypes.Snippets, '', false /* isServiceProject */);
-    this._model = model;
-  }
-
-  /**
-   * @param {string} name
-   * @param {!Common.ContentProvider} contentProvider
-   * @return {!Workspace.UISourceCode}
-   */
-  addSnippet(name, contentProvider) {
-    return this.addContentProvider(name, contentProvider, 'text/javascript');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canSetFileContent() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newContent
-   * @param {boolean} isBase64
-   * @param {function(?string)} callback
-   */
-  setFileContent(uiSourceCode, newContent, isBase64, callback) {
-    this._model._setScriptSnippetContent(uiSourceCode.url(), newContent);
-    callback('');
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  canRename() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {string} newName
-   * @param {function(boolean, string=)} callback
-   */
-  performRename(url, newName, callback) {
-    this._model.renameScriptSnippet(url, newName, callback);
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {?string} name
-   * @param {string} content
-   * @param {boolean=} isBase64
-   * @return {!Promise<?Workspace.UISourceCode>}
-   */
-  createFile(url, name, content, isBase64) {
-    return /** @type {!Promise<?Workspace.UISourceCode>} */ (Promise.resolve(this._model.createScriptSnippet(content)));
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  deleteFile(uiSourceCode) {
-    this._model.deleteScriptSnippet(uiSourceCode);
-  }
-};
-
-/**
- * @type {!Snippets.ScriptSnippetModel}
- */
-Snippets.scriptSnippetModel = new Snippets.ScriptSnippetModel(Workspace.workspace);
diff --git a/front_end/snippets/SnippetStorage.js b/front_end/snippets/SnippetStorage.js
deleted file mode 100644
index 3f0bff0..0000000
--- a/front_end/snippets/SnippetStorage.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Snippets.SnippetStorage = class extends Common.Object {
-  constructor(settingPrefix, namePrefix) {
-    super();
-    /** @type {!Map<string,!Snippets.Snippet>} */
-    this._snippets = new Map();
-
-    this._lastSnippetIdentifierSetting = Common.settings.createSetting(settingPrefix + 'Snippets_lastIdentifier', 0);
-    this._snippetsSetting = Common.settings.createSetting(settingPrefix + 'Snippets', []);
-    this._namePrefix = namePrefix;
-
-    this._loadSettings();
-  }
-
-  get namePrefix() {
-    return this._namePrefix;
-  }
-
-  _saveSettings() {
-    const savedSnippets = [];
-    for (const snippet of this._snippets.values())
-      savedSnippets.push(snippet.serializeToObject());
-    this._snippetsSetting.set(savedSnippets);
-  }
-
-  /**
-   * @return {!Array<!Snippets.Snippet>}
-   */
-  snippets() {
-    return this._snippets.valuesArray();
-  }
-
-  /**
-   * @param {string} id
-   * @return {?Snippets.Snippet}
-   */
-  snippetForId(id) {
-    return this._snippets.get(id);
-  }
-
-  /**
-   * @param {string} name
-   * @return {?Snippets.Snippet}
-   */
-  snippetForName(name) {
-    for (const snippet of this._snippets.values()) {
-      if (snippet.name === name)
-        return snippet;
-    }
-    return null;
-  }
-
-  _loadSettings() {
-    const savedSnippets = this._snippetsSetting.get();
-    for (let i = 0; i < savedSnippets.length; ++i)
-      this._snippetAdded(Snippets.Snippet.fromObject(this, savedSnippets[i]));
-  }
-
-  /**
-   * @param {!Snippets.Snippet} snippet
-   */
-  deleteSnippet(snippet) {
-    this._snippets.delete(snippet.id);
-    this._saveSettings();
-  }
-
-  /**
-   * @return {!Snippets.Snippet}
-   */
-  createSnippet() {
-    const nextId = this._lastSnippetIdentifierSetting.get() + 1;
-    const snippetId = String(nextId);
-    this._lastSnippetIdentifierSetting.set(nextId);
-    const snippet = new Snippets.Snippet(this, snippetId);
-    this._snippetAdded(snippet);
-    this._saveSettings();
-    return snippet;
-  }
-
-  /**
-   * @param {!Snippets.Snippet} snippet
-   */
-  _snippetAdded(snippet) {
-    this._snippets.set(snippet.id, snippet);
-  }
-};
-
-/**
- * @unrestricted
- */
-Snippets.Snippet = class extends Common.Object {
-  /**
-   * @param {!Snippets.SnippetStorage} storage
-   * @param {string} id
-   * @param {string=} name
-   * @param {string=} content
-   */
-  constructor(storage, id, name, content) {
-    super();
-    this._storage = storage;
-    this._id = id;
-    this._name = name || storage.namePrefix + id;
-    this._content = content || '';
-  }
-
-  /**
-   * @param {!Snippets.SnippetStorage} storage
-   * @param {!Object} serializedSnippet
-   * @return {!Snippets.Snippet}
-   */
-  static fromObject(storage, serializedSnippet) {
-    return new Snippets.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
-  }
-
-  /**
-   * @return {string}
-   */
-  get id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  get name() {
-    return this._name;
-  }
-
-  /**
-   * @param {string} name
-   */
-  set name(name) {
-    if (this._name === name)
-      return;
-
-    this._name = name;
-    this._storage._saveSettings();
-  }
-
-  /**
-   * @return {string}
-   */
-  get content() {
-    return this._content;
-  }
-
-  /**
-   * @param {string} content
-   */
-  set content(content) {
-    if (this._content === content)
-      return;
-
-    this._content = content;
-    this._storage._saveSettings();
-  }
-
-  /**
-   * @return {!Object}
-   */
-  serializeToObject() {
-    const serializedSnippet = {};
-    serializedSnippet.id = this.id;
-    serializedSnippet.name = this.name;
-    serializedSnippet.content = this.content;
-    return serializedSnippet;
-  }
-};
diff --git a/front_end/snippets/SnippetsQuickOpen.js b/front_end/snippets/SnippetsQuickOpen.js
deleted file mode 100644
index ba86f8d..0000000
--- a/front_end/snippets/SnippetsQuickOpen.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider {
-  constructor() {
-    super();
-    /** @type {!Array<!Workspace.UISourceCode>} */
-    this._snippets = [];
-  }
-  /**
-   * @override
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-    if (itemIndex === null)
-      return;
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (currentExecutionContext)
-      Snippets.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, this._snippets[itemIndex]);
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @return {string}
-   */
-  notFoundText(query) {
-    return Common.UIString('No snippets found.');
-  }
-
-  /**
-   * @override
-   */
-  attach() {
-    this._snippets = Snippets.scriptSnippetModel.project().uiSourceCodes();
-  }
-
-  /**
-   * @override
-   */
-  detach() {
-    this._snippets = [];
-  }
-
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemCount() {
-    return this._snippets.length;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @return {string}
-   */
-  itemKeyAt(itemIndex) {
-    return this._snippets[itemIndex].name();
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @param {!Element} titleElement
-   * @param {!Element} subtitleElement
-   */
-  renderItem(itemIndex, query, titleElement, subtitleElement) {
-    titleElement.textContent = this._snippets[itemIndex].name();
-    titleElement.classList.add('monospace');
-    QuickOpen.FilteredListWidget.highlightRanges(titleElement, query, true);
-  }
-};
diff --git a/front_end/snippets/module.json b/front_end/snippets/module.json
deleted file mode 100644
index 79774a6..0000000
--- a/front_end/snippets/module.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@QuickOpen.FilteredListWidget.Provider",
-            "title": "Run snippet",
-            "prefix": "!",
-            "className": "Snippets.SnippetsQuickOpen"
-        }
-    ],
-    "dependencies": ["bindings", "quick_open"],
-    "scripts": [
-        "SnippetStorage.js",
-        "ScriptSnippetModel.js",
-        "SnippetsQuickOpen.js"
-    ]
-}
diff --git a/front_end/source_frame/FontView.js b/front_end/source_frame/FontView.js
deleted file mode 100644
index d9030c6..0000000
--- a/front_end/source_frame/FontView.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SourceFrame.FontView = class extends UI.SimpleView {
-  /**
-   * @param {string} mimeType
-   * @param {!Common.ContentProvider} contentProvider
-   */
-  constructor(mimeType, contentProvider) {
-    super(Common.UIString('Font'));
-    this.registerRequiredCSS('source_frame/fontView.css');
-    this.element.classList.add('font-view');
-    this._url = contentProvider.contentURL();
-    this._mimeType = mimeType;
-    this._contentProvider = contentProvider;
-    this._mimeTypeLabel = new UI.ToolbarText(mimeType);
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return [this._mimeTypeLabel];
-  }
-
-  /**
-   * @param {string} uniqueFontName
-   * @param {?string} content
-   */
-  _onFontContentLoaded(uniqueFontName, content) {
-    const url = content ? Common.ContentProvider.contentAsDataURL(content, this._mimeType, true) : this._url;
-    this.fontStyleElement.textContent =
-        String.sprintf('@font-face { font-family: "%s"; src: url(%s); }', uniqueFontName, url);
-  }
-
-  _createContentIfNeeded() {
-    if (this.fontPreviewElement)
-      return;
-
-    const uniqueFontName = 'WebInspectorFontPreview' + (++SourceFrame.FontView._fontId);
-
-    this.fontStyleElement = createElement('style');
-    this._contentProvider.requestContent().then(this._onFontContentLoaded.bind(this, uniqueFontName));
-    this.element.appendChild(this.fontStyleElement);
-
-    const fontPreview = createElement('div');
-    for (let i = 0; i < SourceFrame.FontView._fontPreviewLines.length; ++i) {
-      if (i > 0)
-        fontPreview.createChild('br');
-      fontPreview.createTextChild(SourceFrame.FontView._fontPreviewLines[i]);
-    }
-    this.fontPreviewElement = fontPreview.cloneNode(true);
-    this.fontPreviewElement.style.overflow = 'hidden';
-    this.fontPreviewElement.style.setProperty('font-family', uniqueFontName);
-    this.fontPreviewElement.style.setProperty('visibility', 'hidden');
-
-    this._dummyElement = fontPreview;
-    this._dummyElement.style.visibility = 'hidden';
-    this._dummyElement.style.zIndex = '-1';
-    this._dummyElement.style.display = 'inline';
-    this._dummyElement.style.position = 'absolute';
-    this._dummyElement.style.setProperty('font-family', uniqueFontName);
-    this._dummyElement.style.setProperty('font-size', SourceFrame.FontView._measureFontSize + 'px');
-
-    this.element.appendChild(this.fontPreviewElement);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._createContentIfNeeded();
-
-    this.updateFontPreviewSize();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._inResize)
-      return;
-
-    this._inResize = true;
-    try {
-      this.updateFontPreviewSize();
-    } finally {
-      delete this._inResize;
-    }
-  }
-
-  _measureElement() {
-    this.element.appendChild(this._dummyElement);
-    const result = {width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight};
-    this.element.removeChild(this._dummyElement);
-
-    return result;
-  }
-
-  updateFontPreviewSize() {
-    if (!this.fontPreviewElement || !this.isShowing())
-      return;
-
-    this.fontPreviewElement.style.removeProperty('visibility');
-    const dimension = this._measureElement();
-
-    const height = dimension.height;
-    const width = dimension.width;
-
-    // Subtract some padding. This should match the paddings in the CSS plus room for the scrollbar.
-    const containerWidth = this.element.offsetWidth - 50;
-    const containerHeight = this.element.offsetHeight - 30;
-
-    if (!height || !width || !containerWidth || !containerHeight) {
-      this.fontPreviewElement.style.removeProperty('font-size');
-      return;
-    }
-
-    const widthRatio = containerWidth / width;
-    const heightRatio = containerHeight / height;
-    const finalFontSize = Math.floor(SourceFrame.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2;
-
-    this.fontPreviewElement.style.setProperty('font-size', finalFontSize + 'px', null);
-  }
-};
-
-SourceFrame.FontView._fontPreviewLines =
-    ['ABCDEFGHIJKLM', 'NOPQRSTUVWXYZ', 'abcdefghijklm', 'nopqrstuvwxyz', '1234567890'];
-
-SourceFrame.FontView._fontId = 0;
-
-SourceFrame.FontView._measureFontSize = 50;
diff --git a/front_end/source_frame/ImageView.js b/front_end/source_frame/ImageView.js
deleted file mode 100644
index 7dbaa29..0000000
--- a/front_end/source_frame/ImageView.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SourceFrame.ImageView = class extends UI.SimpleView {
-  /**
-   * @param {string} mimeType
-   * @param {!Common.ContentProvider} contentProvider
-   */
-  constructor(mimeType, contentProvider) {
-    super(Common.UIString('Image'));
-    this.registerRequiredCSS('source_frame/imageView.css');
-    this.element.classList.add('image-view');
-    this._url = contentProvider.contentURL();
-    this._parsedURL = new Common.ParsedURL(this._url);
-    this._mimeType = mimeType;
-    this._contentProvider = contentProvider;
-    this._uiSourceCode = contentProvider instanceof Workspace.UISourceCode ?
-        /** @type {!Workspace.UISourceCode} */ (contentProvider) :
-        null;
-    if (this._uiSourceCode) {
-      this._uiSourceCode.addEventListener(
-          Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-      new UI.DropTarget(
-          this.element, [UI.DropTarget.Type.ImageFile, UI.DropTarget.Type.URI], Common.UIString('Drop image file here'),
-          this._handleDrop.bind(this));
-    }
-    this._sizeLabel = new UI.ToolbarText();
-    this._dimensionsLabel = new UI.ToolbarText();
-    this._mimeTypeLabel = new UI.ToolbarText(mimeType);
-    this._container = this.element.createChild('div', 'image');
-    this._imagePreviewElement = this._container.createChild('img', 'resource-image-view');
-    this._imagePreviewElement.addEventListener('contextmenu', this._contextMenu.bind(this), true);
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return [
-      this._sizeLabel, new UI.ToolbarSeparator(), this._dimensionsLabel, new UI.ToolbarSeparator(), this._mimeTypeLabel
-    ];
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._updateContentIfNeeded();
-  }
-
-  /**
-   * @override
-   */
-  disposeView() {
-    if (this._uiSourceCode) {
-      this._uiSourceCode.removeEventListener(
-          Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-    }
-  }
-
-  _workingCopyCommitted() {
-    this._updateContentIfNeeded();
-  }
-
-  async _updateContentIfNeeded() {
-    const content = await this._contentProvider.requestContent();
-    if (this._cachedContent === content)
-      return;
-
-    const contentEncoded = await this._contentProvider.contentEncoded();
-    this._cachedContent = content;
-    let imageSrc = 'data:' + this._mimeType + (contentEncoded ? ';base64,' : ',') + content;
-    if (imageSrc === null)
-      imageSrc = this._url;
-    this._imagePreviewElement.src = imageSrc;
-    this._sizeLabel.setText(Number.bytesToString(this._base64ToSize(content)));
-    this._dimensionsLabel.setText(
-        Common.UIString('%d × %d', this._imagePreviewElement.naturalWidth, this._imagePreviewElement.naturalHeight));
-  }
-
-  /**
-   * @param {?string} content
-   * @return {number}
-   */
-  _base64ToSize(content) {
-    if (!content || !content.length)
-      return 0;
-    let size = (content.length || 0) * 3 / 4;
-    if (content.length > 0 && content[content.length - 1] === '=')
-      size--;
-    if (content.length > 1 && content[content.length - 2] === '=')
-      size--;
-    return size;
-  }
-
-  _contextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    if (!this._parsedURL.isDataURL())
-      contextMenu.clipboardSection().appendItem(Common.UIString('Copy image URL'), this._copyImageURL.bind(this));
-    if (this._imagePreviewElement.src) {
-      contextMenu.clipboardSection().appendItem(
-          Common.UIString('Copy image as data URI'), this._copyImageAsDataURL.bind(this));
-    }
-
-    contextMenu.clipboardSection().appendItem(Common.UIString('Open image in new tab'), this._openInNewTab.bind(this));
-    contextMenu.clipboardSection().appendItem(Common.UIString('Save\u2026'), this._saveImage.bind(this));
-    contextMenu.show();
-  }
-
-  _copyImageAsDataURL() {
-    InspectorFrontendHost.copyText(this._imagePreviewElement.src);
-  }
-
-  _copyImageURL() {
-    InspectorFrontendHost.copyText(this._url);
-  }
-
-  _saveImage() {
-    const link = createElement('a');
-    link.download = this._parsedURL.displayName;
-    link.href = this._url;
-    link.click();
-  }
-
-  _openInNewTab() {
-    InspectorFrontendHost.openInNewTab(this._url);
-  }
-
-  /**
-   * @param {!DataTransfer} dataTransfer
-   */
-  async _handleDrop(dataTransfer) {
-    const items = dataTransfer.items;
-    if (!items.length || items[0].kind !== 'file')
-      return;
-
-    const entry = items[0].webkitGetAsEntry();
-    const encoded = !entry.name.endsWith('.svg');
-    entry.file(file => {
-      const reader = new FileReader();
-      reader.onloadend = () => {
-        let result;
-        try {
-          result = /** @type {?string} */ (reader.result);
-        } catch (e) {
-          result = null;
-          console.error('Can\'t read file: ' + e);
-        }
-        if (typeof result !== 'string')
-          return;
-        this._uiSourceCode.setContent(encoded ? btoa(result) : result, encoded);
-      };
-      if (encoded)
-        reader.readAsBinaryString(file);
-      else
-        reader.readAsText(file);
-    });
-  }
-};
diff --git a/front_end/source_frame/JSONView.js b/front_end/source_frame/JSONView.js
deleted file mode 100644
index e493566..0000000
--- a/front_end/source_frame/JSONView.js
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.Searchable}
- */
-SourceFrame.JSONView = class extends UI.VBox {
-  /**
-   * @param {!SourceFrame.ParsedJSON} parsedJSON
-   */
-  constructor(parsedJSON) {
-    super();
-    this._initialized = false;
-    this.registerRequiredCSS('source_frame/jsonView.css');
-    this._parsedJSON = parsedJSON;
-    this.element.classList.add('json-view');
-
-    /** @type {?UI.SearchableView} */
-    this._searchableView;
-    /** @type {!ObjectUI.ObjectPropertiesSection} */
-    this._treeOutline;
-    /** @type {number} */
-    this._currentSearchFocusIndex = 0;
-    /** @type {!Array.<!UI.TreeElement>} */
-    this._currentSearchTreeElements = [];
-    /** @type {?RegExp} */
-    this._searchRegex = null;
-  }
-
-  /**
-   * @param {string} content
-   * @return {!Promise<?UI.SearchableView>}
-   */
-  static async createView(content) {
-    // We support non-strict JSON parsing by parsing an AST tree which is why we offload it to a worker.
-    const parsedJSON = await SourceFrame.JSONView._parseJSON(content);
-    if (!parsedJSON || typeof parsedJSON.data !== 'object')
-      return null;
-
-    const jsonView = new SourceFrame.JSONView(parsedJSON);
-    const searchableView = new UI.SearchableView(jsonView);
-    searchableView.setPlaceholder(Common.UIString('Find'));
-    jsonView._searchableView = searchableView;
-    jsonView.show(searchableView.element);
-    jsonView.element.setAttribute('tabIndex', 0);
-    return searchableView;
-  }
-
-  /**
-   * @param {?Object} obj
-   * @return {!UI.SearchableView}
-   */
-  static createViewSync(obj) {
-    const jsonView = new SourceFrame.JSONView(new SourceFrame.ParsedJSON(obj, '', ''));
-    const searchableView = new UI.SearchableView(jsonView);
-    searchableView.setPlaceholder(Common.UIString('Find'));
-    jsonView._searchableView = searchableView;
-    jsonView.show(searchableView.element);
-    jsonView.element.setAttribute('tabIndex', 0);
-    return searchableView;
-  }
-
-  /**
-   * @param {?string} text
-   * @return {!Promise<?SourceFrame.ParsedJSON>}
-   */
-  static _parseJSON(text) {
-    let returnObj = null;
-    if (text)
-      returnObj = SourceFrame.JSONView._extractJSON(/** @type {string} */ (text));
-    if (!returnObj)
-      return Promise.resolve(/** @type {?SourceFrame.ParsedJSON} */ (null));
-    return Formatter.formatterWorkerPool().parseJSONRelaxed(returnObj.data).then(handleReturnedJSON);
-
-    /**
-     * @param {*} data
-     * @return {?SourceFrame.ParsedJSON}
-     */
-    function handleReturnedJSON(data) {
-      if (!data)
-        return null;
-      returnObj.data = data;
-      return returnObj;
-    }
-  }
-
-  /**
-   * @param {string} text
-   * @return {?SourceFrame.ParsedJSON}
-   */
-  static _extractJSON(text) {
-    // Do not treat HTML as JSON.
-    if (text.startsWith('<'))
-      return null;
-    let inner = SourceFrame.JSONView._findBrackets(text, '{', '}');
-    const inner2 = SourceFrame.JSONView._findBrackets(text, '[', ']');
-    inner = inner2.length > inner.length ? inner2 : inner;
-
-    // Return on blank payloads or on payloads significantly smaller than original text.
-    if (inner.length === -1 || text.length - inner.length > 80)
-      return null;
-
-    const prefix = text.substring(0, inner.start);
-    const suffix = text.substring(inner.end + 1);
-    text = text.substring(inner.start, inner.end + 1);
-
-    // Only process valid JSONP.
-    if (suffix.trim().length && !(suffix.trim().startsWith(')') && prefix.trim().endsWith('(')))
-      return null;
-
-    return new SourceFrame.ParsedJSON(text, prefix, suffix);
-  }
-
-  /**
-   * @param {string} text
-   * @param {string} open
-   * @param {string} close
-   * @return {{start: number, end: number, length: number}}
-   */
-  static _findBrackets(text, open, close) {
-    const start = text.indexOf(open);
-    const end = text.lastIndexOf(close);
-    let length = end - start - 1;
-    if (start === -1 || end === -1 || end < start)
-      length = -1;
-    return {start: start, end: end, length: length};
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._initialize();
-  }
-
-  _initialize() {
-    if (this._initialized)
-      return;
-    this._initialized = true;
-
-    const obj = SDK.RemoteObject.fromLocalObject(this._parsedJSON.data);
-    const title = this._parsedJSON.prefix + obj.description + this._parsedJSON.suffix;
-    this._treeOutline = new ObjectUI.ObjectPropertiesSection(obj, title);
-    this._treeOutline.enableContextMenu();
-    this._treeOutline.setEditable(false);
-    this._treeOutline.expand();
-    this.element.appendChild(this._treeOutline.element);
-  }
-
-  /**
-   * @param {number} index
-   */
-  _jumpToMatch(index) {
-    if (!this._searchRegex)
-      return;
-    const previousFocusElement = this._currentSearchTreeElements[this._currentSearchFocusIndex];
-    if (previousFocusElement)
-      previousFocusElement.setSearchRegex(this._searchRegex);
-
-    const newFocusElement = this._currentSearchTreeElements[index];
-    if (newFocusElement) {
-      this._updateSearchIndex(index);
-      newFocusElement.setSearchRegex(this._searchRegex, UI.highlightedCurrentSearchResultClassName);
-      newFocusElement.reveal();
-    } else {
-      this._updateSearchIndex(0);
-    }
-  }
-
-  /**
-   * @param {number} count
-   */
-  _updateSearchCount(count) {
-    if (!this._searchableView)
-      return;
-    this._searchableView.updateSearchMatchesCount(count);
-  }
-
-  /**
-   * @param {number} index
-   */
-  _updateSearchIndex(index) {
-    this._currentSearchFocusIndex = index;
-    if (!this._searchableView)
-      return;
-    this._searchableView.updateCurrentMatchIndex(index);
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._searchRegex = null;
-    this._currentSearchTreeElements = [];
-
-    for (let element = this._treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) {
-      if (!(element instanceof ObjectUI.ObjectPropertyTreeElement))
-        continue;
-      element.revertHighlightChanges();
-    }
-    this._updateSearchCount(0);
-    this._updateSearchIndex(0);
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    let newIndex = this._currentSearchFocusIndex;
-    const previousSearchFocusElement = this._currentSearchTreeElements[newIndex];
-    this.searchCanceled();
-    this._searchRegex = searchConfig.toSearchRegex(true);
-
-    for (let element = this._treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) {
-      if (!(element instanceof ObjectUI.ObjectPropertyTreeElement))
-        continue;
-      const hasMatch = element.setSearchRegex(this._searchRegex);
-      if (hasMatch)
-        this._currentSearchTreeElements.push(element);
-      if (previousSearchFocusElement === element) {
-        const currentIndex = this._currentSearchTreeElements.length - 1;
-        if (hasMatch || jumpBackwards)
-          newIndex = currentIndex;
-        else
-          newIndex = currentIndex + 1;
-      }
-    }
-    this._updateSearchCount(this._currentSearchTreeElements.length);
-
-    if (!this._currentSearchTreeElements.length) {
-      this._updateSearchIndex(0);
-      return;
-    }
-    newIndex = mod(newIndex, this._currentSearchTreeElements.length);
-
-    this._jumpToMatch(newIndex);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._currentSearchTreeElements.length)
-      return;
-    const newIndex = mod(this._currentSearchFocusIndex + 1, this._currentSearchTreeElements.length);
-    this._jumpToMatch(newIndex);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._currentSearchTreeElements.length)
-      return;
-    const newIndex = mod(this._currentSearchFocusIndex - 1, this._currentSearchTreeElements.length);
-    this._jumpToMatch(newIndex);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SourceFrame.ParsedJSON = class {
-  /**
-   * @param {*} data
-   * @param {string} prefix
-   * @param {string} suffix
-   */
-  constructor(data, prefix, suffix) {
-    this.data = data;
-    this.prefix = prefix;
-    this.suffix = suffix;
-  }
-};
diff --git a/front_end/source_frame/PreviewFactory.js b/front_end/source_frame/PreviewFactory.js
deleted file mode 100644
index eaa9bd5..0000000
--- a/front_end/source_frame/PreviewFactory.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-SourceFrame.PreviewFactory = class {
-  /**
-   * @param {!Common.ContentProvider} provider
-   * @param {string} mimeType
-   * @returns {!Promise<?UI.Widget>}
-   */
-  static async createPreview(provider, mimeType) {
-    const content = await provider.requestContent();
-    if (!content)
-      return new UI.EmptyWidget(Common.UIString('Nothing to preview'));
-
-    let resourceType = Common.ResourceType.fromMimeType(mimeType);
-    if (resourceType === Common.resourceTypes.Other)
-      resourceType = provider.contentType();
-
-    switch (resourceType) {
-      case Common.resourceTypes.Image:
-        return new SourceFrame.ImageView(mimeType, provider);
-      case Common.resourceTypes.Font:
-        return new SourceFrame.FontView(mimeType, provider);
-    }
-
-    const parsedXML = SourceFrame.XMLView.parseXML(content, mimeType);
-    if (parsedXML)
-      return SourceFrame.XMLView.createSearchableView(parsedXML);
-
-    const jsonView = await SourceFrame.JSONView.createView(content);
-    if (jsonView)
-      return jsonView;
-
-    if (resourceType.isTextType()) {
-      const highlighterType =
-          provider.contentType().canonicalMimeType() || mimeType.replace(/;.*/, '');  // remove charset
-      return SourceFrame.ResourceSourceFrame.createSearchableView(
-          provider, highlighterType, true /* autoPrettyPrint */);
-    }
-
-    return null;
-  }
-};
diff --git a/front_end/source_frame/ResourceSourceFrame.js b/front_end/source_frame/ResourceSourceFrame.js
deleted file mode 100644
index 32af2b9..0000000
--- a/front_end/source_frame/ResourceSourceFrame.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) IBM Corp. 2009  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-SourceFrame.ResourceSourceFrame = class extends SourceFrame.SourceFrame {
-  /**
-   * @param {!Common.ContentProvider} resource
-   * @param {boolean=} autoPrettyPrint
-   */
-  constructor(resource, autoPrettyPrint) {
-    super(resource.requestContent.bind(resource));
-    this._resource = resource;
-    this.setCanPrettyPrint(this._resource.contentType().isDocumentOrScriptOrStyleSheet(), autoPrettyPrint);
-  }
-
-  /**
-   * @param {!Common.ContentProvider} resource
-   * @param {string} highlighterType
-   * @param {boolean=} autoPrettyPrint
-   * @return {!UI.Widget}
-   */
-  static createSearchableView(resource, highlighterType, autoPrettyPrint) {
-    return new SourceFrame.ResourceSourceFrame.SearchableContainer(resource, highlighterType, autoPrettyPrint);
-  }
-
-  get resource() {
-    return this._resource;
-  }
-
-  /**
-   * @override
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {!Promise}
-   */
-  populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {
-    contextMenu.appendApplicableItems(this._resource);
-    return Promise.resolve();
-  }
-};
-
-SourceFrame.ResourceSourceFrame.SearchableContainer = class extends UI.VBox {
-  /**
-   * @param {!Common.ContentProvider} resource
-   * @param {string} highlighterType
-   * @param {boolean=} autoPrettyPrint
-   * @return {!UI.Widget}
-   */
-  constructor(resource, highlighterType, autoPrettyPrint) {
-    super(true);
-    this.registerRequiredCSS('source_frame/resourceSourceFrame.css');
-    const sourceFrame = new SourceFrame.ResourceSourceFrame(resource, autoPrettyPrint);
-    this._sourceFrame = sourceFrame;
-    sourceFrame.setHighlighterType(highlighterType);
-    const searchableView = new UI.SearchableView(sourceFrame);
-    searchableView.element.classList.add('searchable-view');
-    searchableView.setPlaceholder(ls`Find`);
-    sourceFrame.show(searchableView.element);
-    sourceFrame.setSearchableView(searchableView);
-    searchableView.show(this.contentElement);
-
-    const toolbar = new UI.Toolbar('toolbar', this.contentElement);
-    for (const item of sourceFrame.syncToolbarItems())
-      toolbar.appendToolbarItem(item);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   */
-  async revealPosition(lineNumber, columnNumber) {
-    this._sourceFrame.revealPosition(lineNumber, columnNumber, true);
-  }
-};
diff --git a/front_end/source_frame/SourceCodeDiff.js b/front_end/source_frame/SourceCodeDiff.js
deleted file mode 100644
index f9bf097..0000000
--- a/front_end/source_frame/SourceCodeDiff.js
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SourceFrame.SourceCodeDiff = class {
-  /**
-   * @param {!WorkspaceDiff.WorkspaceDiff} workspaceDiff
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   */
-  constructor(workspaceDiff, textEditor) {
-    this._textEditor = textEditor;
-    this._decorations = [];
-    this._textEditor.installGutter(SourceFrame.SourceCodeDiff.DiffGutterType, true);
-    this._uiSourceCode = null;
-    this._workspaceDiff = workspaceDiff;
-    /** @type {!Array<!TextEditor.TextEditorPositionHandle>}*/
-    this._animatedLines = [];
-
-    this._update();
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   */
-  setUISourceCode(uiSourceCode) {
-    if (uiSourceCode === this._uiSourceCode)
-      return;
-    if (this._uiSourceCode)
-      this._workspaceDiff.unsubscribeFromDiffChange(this._uiSourceCode, this._update, this);
-    if (uiSourceCode)
-      this._workspaceDiff.subscribeToDiffChange(uiSourceCode, this._update, this);
-    this._uiSourceCode = uiSourceCode;
-    this._update();
-  }
-
-  /**
-   * @param {?string} oldContent
-   * @param {?string} newContent
-   */
-  highlightModifiedLines(oldContent, newContent) {
-    if (typeof oldContent !== 'string' || typeof newContent !== 'string')
-      return;
-
-    const diff = this._computeDiff(Diff.Diff.lineDiff(oldContent.split('\n'), newContent.split('\n')));
-    const changedLines = [];
-    for (let i = 0; i < diff.length; ++i) {
-      const diffEntry = diff[i];
-      if (diffEntry.type === SourceFrame.SourceCodeDiff.GutterDecorationType.Delete)
-        continue;
-      for (let lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber) {
-        const position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
-        if (position)
-          changedLines.push(position);
-      }
-    }
-    this._updateHighlightedLines(changedLines);
-    this._animationTimeout = setTimeout(
-        this._updateHighlightedLines.bind(this, []), 400);  // // Keep this timeout in sync with sourcesView.css.
-  }
-
-  /**
-   * @param {!Array<!TextEditor.TextEditorPositionHandle>} newLines
-   */
-  _updateHighlightedLines(newLines) {
-    if (this._animationTimeout)
-      clearTimeout(this._animationTimeout);
-    this._animationTimeout = null;
-    this._textEditor.operation(operation.bind(this));
-
-    /**
-     * @this {SourceFrame.SourceCodeDiff}
-     */
-    function operation() {
-      toggleLines.call(this, false);
-      this._animatedLines = newLines;
-      toggleLines.call(this, true);
-    }
-
-    /**
-     * @param {boolean} value
-     * @this {SourceFrame.SourceCodeDiff}
-     */
-    function toggleLines(value) {
-      for (let i = 0; i < this._animatedLines.length; ++i) {
-        const location = this._animatedLines[i].resolve();
-        if (location)
-          this._textEditor.toggleLineClass(location.lineNumber, 'highlight-line-modification', value);
-      }
-    }
-  }
-
-  /**
-   * @param {!Array<!SourceFrame.SourceCodeDiff.GutterDecoration>} removed
-   * @param {!Array<!SourceFrame.SourceCodeDiff.GutterDecoration>} added
-   */
-  _updateDecorations(removed, added) {
-    this._textEditor.operation(operation);
-
-    function operation() {
-      for (const decoration of removed)
-        decoration.remove();
-      for (const decoration of added)
-        decoration.install();
-    }
-  }
-
-  /**
-   * @param {!Diff.Diff.DiffArray} diff
-   * @return {!Array<!{type: !SourceFrame.SourceCodeDiff.GutterDecorationType, from: number, to: number}>}
-   */
-  _computeDiff(diff) {
-    const result = [];
-    let hasAdded = false;
-    let hasRemoved = false;
-    let blockStartLineNumber = 0;
-    let currentLineNumber = 0;
-    let isInsideBlock = false;
-    for (let i = 0; i < diff.length; ++i) {
-      const token = diff[i];
-      if (token[0] === Diff.Diff.Operation.Equal) {
-        if (isInsideBlock)
-          flush();
-        currentLineNumber += token[1].length;
-        continue;
-      }
-
-      if (!isInsideBlock) {
-        isInsideBlock = true;
-        blockStartLineNumber = currentLineNumber;
-      }
-
-      if (token[0] === Diff.Diff.Operation.Delete) {
-        hasRemoved = true;
-      } else {
-        currentLineNumber += token[1].length;
-        hasAdded = true;
-      }
-    }
-    if (isInsideBlock)
-      flush();
-    if (result.length > 1 && result[0].from === 0 && result[1].from === 0) {
-      const merged = {type: SourceFrame.SourceCodeDiff.GutterDecorationType.Modify, from: 0, to: result[1].to};
-      result.splice(0, 2, merged);
-    }
-    return result;
-
-    function flush() {
-      let type = SourceFrame.SourceCodeDiff.GutterDecorationType.Insert;
-      let from = blockStartLineNumber;
-      let to = currentLineNumber;
-      if (hasAdded && hasRemoved) {
-        type = SourceFrame.SourceCodeDiff.GutterDecorationType.Modify;
-      } else if (!hasAdded && hasRemoved && from === 0 && to === 0) {
-        type = SourceFrame.SourceCodeDiff.GutterDecorationType.Modify;
-        to = 1;
-      } else if (!hasAdded && hasRemoved) {
-        type = SourceFrame.SourceCodeDiff.GutterDecorationType.Delete;
-        from -= 1;
-      }
-      result.push({type: type, from: from, to: to});
-      isInsideBlock = false;
-      hasAdded = false;
-      hasRemoved = false;
-    }
-  }
-
-  _update() {
-    if (this._uiSourceCode)
-      this._workspaceDiff.requestDiff(this._uiSourceCode).then(this._innerUpdate.bind(this));
-    else
-      this._innerUpdate(null);
-  }
-
-  /**
-   * @param {?Diff.Diff.DiffArray} lineDiff
-   */
-  _innerUpdate(lineDiff) {
-    if (!lineDiff) {
-      this._updateDecorations(this._decorations, []);
-      this._decorations = [];
-      return;
-    }
-
-    /** @type {!Map<number, !SourceFrame.SourceCodeDiff.GutterDecoration>} */
-    const oldDecorations = new Map();
-    for (let i = 0; i < this._decorations.length; ++i) {
-      const decoration = this._decorations[i];
-      const lineNumber = decoration.lineNumber();
-      if (lineNumber === -1)
-        continue;
-      oldDecorations.set(lineNumber, decoration);
-    }
-
-    const diff = this._computeDiff(lineDiff);
-
-    /** @type {!Map<number, !{lineNumber: number, type: !SourceFrame.SourceCodeDiff.GutterDecorationType}>} */
-    const newDecorations = new Map();
-    for (let i = 0; i < diff.length; ++i) {
-      const diffEntry = diff[i];
-      for (let lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber)
-        newDecorations.set(lineNumber, {lineNumber: lineNumber, type: diffEntry.type});
-    }
-
-    const decorationDiff = oldDecorations.diff(newDecorations, (e1, e2) => e1.type === e2.type);
-    const addedDecorations = decorationDiff.added.map(
-        entry => new SourceFrame.SourceCodeDiff.GutterDecoration(this._textEditor, entry.lineNumber, entry.type));
-
-    this._decorations = decorationDiff.equal.concat(addedDecorations);
-    this._updateDecorations(decorationDiff.removed, addedDecorations);
-    this._decorationsSetForTest(newDecorations);
-  }
-
-  /**
-   * @param {!Map<number, !{lineNumber: number, type: !SourceFrame.SourceCodeDiff.GutterDecorationType}>} decorations
-   */
-  _decorationsSetForTest(decorations) {
-  }
-
-  dispose() {
-    if (this._uiSourceCode)
-      WorkspaceDiff.workspaceDiff().unsubscribeFromDiffChange(this._uiSourceCode, this._update, this);
-  }
-};
-
-/** @type {string} */
-SourceFrame.SourceCodeDiff.DiffGutterType = 'CodeMirror-gutter-diff';
-
-/** @enum {symbol} */
-SourceFrame.SourceCodeDiff.GutterDecorationType = {
-  Insert: Symbol('Insert'),
-  Delete: Symbol('Delete'),
-  Modify: Symbol('Modify'),
-};
-
-/**
- * @unrestricted
- */
-SourceFrame.SourceCodeDiff.GutterDecoration = class {
-  /**
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   * @param {number} lineNumber
-   * @param {!SourceFrame.SourceCodeDiff.GutterDecorationType} type
-   */
-  constructor(textEditor, lineNumber, type) {
-    this._textEditor = textEditor;
-    this._position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
-    this._className = '';
-    if (type === SourceFrame.SourceCodeDiff.GutterDecorationType.Insert)
-      this._className = 'diff-entry-insert';
-    else if (type === SourceFrame.SourceCodeDiff.GutterDecorationType.Delete)
-      this._className = 'diff-entry-delete';
-    else if (type === SourceFrame.SourceCodeDiff.GutterDecorationType.Modify)
-      this._className = 'diff-entry-modify';
-    this.type = type;
-  }
-
-  /**
-   * @return {number}
-   */
-  lineNumber() {
-    const location = this._position.resolve();
-    if (!location)
-      return -1;
-    return location.lineNumber;
-  }
-
-  install() {
-    const location = this._position.resolve();
-    if (!location)
-      return;
-    const element = createElementWithClass('div', 'diff-marker');
-    element.textContent = '\u00A0';
-    this._textEditor.setGutterDecoration(location.lineNumber, SourceFrame.SourceCodeDiff.DiffGutterType, element);
-    this._textEditor.toggleLineClass(location.lineNumber, this._className, true);
-  }
-
-  remove() {
-    const location = this._position.resolve();
-    if (!location)
-      return;
-    this._textEditor.setGutterDecoration(location.lineNumber, SourceFrame.SourceCodeDiff.DiffGutterType, null);
-    this._textEditor.toggleLineClass(location.lineNumber, this._className, false);
-  }
-};
diff --git a/front_end/source_frame/SourceFrame.js b/front_end/source_frame/SourceFrame.js
deleted file mode 100644
index b6ecaed..0000000
--- a/front_end/source_frame/SourceFrame.js
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.Searchable}
- * @implements {UI.Replaceable}
- * @implements {SourceFrame.SourcesTextEditorDelegate}
- * @unrestricted
- */
-SourceFrame.SourceFrame = class extends UI.SimpleView {
-  /**
-   * @param {function(): !Promise<?string>} lazyContent
-   */
-  constructor(lazyContent) {
-    super(Common.UIString('Source'));
-
-    this._lazyContent = lazyContent;
-
-    this._pretty = false;
-    this._rawContent = '';
-    /** @type {?Promise<string>} */
-    this._formattedContentPromise = null;
-    /** @type {?Formatter.FormatterSourceMapping} */
-    this._formattedMap = null;
-    this._prettyToggle = new UI.ToolbarToggle(ls`Pretty print`, 'largeicon-pretty-print');
-    this._prettyToggle.addEventListener(UI.ToolbarButton.Events.Click, () => {
-      this._setPretty(!this._prettyToggle.toggled());
-    });
-    this._shouldAutoPrettyPrint = false;
-    this._prettyToggle.setVisible(false);
-
-    this._textEditor = new SourceFrame.SourcesTextEditor(this);
-    this._textEditor.show(this.element);
-
-    this._searchConfig = null;
-    this._delayedFindSearchMatches = null;
-    this._currentSearchResultIndex = -1;
-    this._searchResults = [];
-    this._searchRegex = null;
-
-    this._textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.EditorFocused, this._resetCurrentSearchResultIndex, this);
-    this._textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.SelectionChanged, this._updateSourcePosition, this);
-    this._textEditor.addEventListener(UI.TextEditor.Events.TextChanged, event => {
-      if (!this._muteChangeEventsForSetContent)
-        this.onTextChanged(event.data.oldRange, event.data.newRange);
-    });
-    /** @type {boolean} */
-    this._muteChangeEventsForSetContent = false;
-
-    this._sourcePosition = new UI.ToolbarText();
-
-    /**
-     * @type {?UI.SearchableView}
-     */
-    this._searchableView = null;
-    this._editable = false;
-    this._textEditor.setReadOnly(true);
-
-    /** @type {?{line: number, column: (number|undefined), shouldHighlight: (boolean|undefined)}} */
-    this._positionToReveal = null;
-    this._lineToScrollTo = null;
-    this._selectionToSet = null;
-    this._loaded = false;
-    this._contentRequested = false;
-    this._highlighterType = '';
-  }
-
-  /**
-   * @param {boolean} canPrettyPrint
-   * @param {boolean=} autoPrettyPrint
-   */
-  setCanPrettyPrint(canPrettyPrint, autoPrettyPrint) {
-    this._shouldAutoPrettyPrint = canPrettyPrint && !!autoPrettyPrint;
-    this._prettyToggle.setVisible(canPrettyPrint);
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  async _setPretty(value) {
-    this._pretty = value;
-    this._prettyToggle.setToggled(value);
-    this._prettyToggle.setEnabled(false);
-
-    const selection = this.selection();
-    if (this._pretty && this._rawContent) {
-      this.setContent(await this._requestFormattedContent());
-      const start = this._rawToPrettyLocation(selection.startLine, selection.startColumn);
-      const end = this._rawToPrettyLocation(selection.endLine, selection.endColumn);
-      this.setSelection(new TextUtils.TextRange(start[0], start[1], end[0], end[1]));
-      this._textEditor.setLineNumberFormatter(lineNumber => {
-        const line = this._prettyToRawLocation(lineNumber - 1, 0)[0] + 1;
-        if (lineNumber === 1)
-          return String(line);
-        if (line !== this._prettyToRawLocation(lineNumber - 2, 0)[0] + 1)
-          return String(line);
-        return '-';
-      });
-    } else {
-      this._textEditor.setLineNumberFormatter(lineNumber => {
-        return String(lineNumber);
-      });
-      this.setContent(this._rawContent);
-      const start = this._prettyToRawLocation(selection.startLine, selection.startColumn);
-      const end = this._prettyToRawLocation(selection.endLine, selection.endColumn);
-      this.setSelection(new TextUtils.TextRange(start[0], start[1], end[0], end[1]));
-    }
-    this._prettyToggle.setEnabled(true);
-  }
-
-  /**
-   * @param {number} line
-   * @param {number} column
-   * @return {!Array<number>}
-   */
-  _prettyToRawLocation(line, column) {
-    if (!this._formattedMap)
-      return [line, column];
-    return this._formattedMap.formattedToOriginal(line, column);
-  }
-
-  /**
-   * @param {number} line
-   * @param {number} column
-   * @return {!Array<number>}
-   */
-  _rawToPrettyLocation(line, column) {
-    if (!this._formattedMap)
-      return [line, column];
-    return this._formattedMap.originalToFormatted(line, column);
-  }
-
-  /**
-   * @param {boolean} editable
-   * @protected
-   */
-  setEditable(editable) {
-    this._editable = editable;
-    if (this._loaded)
-      this._textEditor.setReadOnly(!editable);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._ensureContentLoaded();
-    this._wasShownOrLoaded();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-
-    this._clearPositionToReveal();
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return [this._prettyToggle, this._sourcePosition];
-  }
-
-  get loaded() {
-    return this._loaded;
-  }
-
-  get textEditor() {
-    return this._textEditor;
-  }
-
-  async _ensureContentLoaded() {
-    if (!this._contentRequested) {
-      this._contentRequested = true;
-      const content = await this._lazyContent();
-      this._rawContent = content || '';
-      this._formattedContentPromise = null;
-      this._formattedMap = null;
-      if (this._shouldAutoPrettyPrint && TextUtils.isMinified(this._rawContent))
-        await this._setPretty(true);
-      else
-        this.setContent(this._rawContent);
-    }
-  }
-
-  /**
-   * @return {!Promise<string>}
-   */
-  _requestFormattedContent() {
-    if (this._formattedContentPromise)
-      return this._formattedContentPromise;
-    let fulfill;
-    this._formattedContentPromise = new Promise(x => fulfill = x);
-    new Formatter.ScriptFormatter(this._highlighterType, this._rawContent, (data, map) => {
-      this._formattedMap = map;
-      fulfill(data);
-    });
-    return this._formattedContentPromise;
-  }
-
-  /**
-   * @param {number} line 0-based
-   * @param {number=} column
-   * @param {boolean=} shouldHighlight
-   */
-  revealPosition(line, column, shouldHighlight) {
-    this._lineToScrollTo = null;
-    this._selectionToSet = null;
-    this._positionToReveal = {line: line, column: column, shouldHighlight: shouldHighlight};
-    this._innerRevealPositionIfNeeded();
-  }
-
-  _innerRevealPositionIfNeeded() {
-    if (!this._positionToReveal)
-      return;
-
-    if (!this.loaded || !this.isShowing())
-      return;
-
-    this._textEditor.revealPosition(
-        this._positionToReveal.line, this._positionToReveal.column, this._positionToReveal.shouldHighlight);
-    this._positionToReveal = null;
-  }
-
-  _clearPositionToReveal() {
-    this._textEditor.clearPositionHighlight();
-    this._positionToReveal = null;
-  }
-
-  /**
-   * @param {number} line
-   */
-  scrollToLine(line) {
-    this._clearPositionToReveal();
-    this._lineToScrollTo = line;
-    this._innerScrollToLineIfNeeded();
-  }
-
-  _innerScrollToLineIfNeeded() {
-    if (this._lineToScrollTo !== null) {
-      if (this.loaded && this.isShowing()) {
-        this._textEditor.scrollToLine(this._lineToScrollTo);
-        this._lineToScrollTo = null;
-      }
-    }
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  selection() {
-    return this.textEditor.selection();
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} textRange
-   */
-  setSelection(textRange) {
-    this._selectionToSet = textRange;
-    this._innerSetSelectionIfNeeded();
-  }
-
-  _innerSetSelectionIfNeeded() {
-    if (this._selectionToSet && this.loaded && this.isShowing()) {
-      this._textEditor.setSelection(this._selectionToSet);
-      this._selectionToSet = null;
-    }
-  }
-
-  _wasShownOrLoaded() {
-    this._innerRevealPositionIfNeeded();
-    this._innerSetSelectionIfNeeded();
-    this._innerScrollToLineIfNeeded();
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} oldRange
-   * @param {!TextUtils.TextRange} newRange
-   */
-  onTextChanged(oldRange, newRange) {
-    if (this._searchConfig && this._searchableView)
-      this.performSearch(this._searchConfig, false, false);
-  }
-
-  /**
-   * @param {string} content
-   * @param {string} mimeType
-   * @return {string}
-   */
-  _simplifyMimeType(content, mimeType) {
-    if (!mimeType)
-      return '';
-    if (mimeType.indexOf('javascript') >= 0 || mimeType.indexOf('jscript') >= 0 || mimeType.indexOf('ecmascript') >= 0)
-      return 'text/javascript';
-    // A hack around the fact that files with "php" extension might be either standalone or html embedded php scripts.
-    if (mimeType === 'text/x-php' && content.match(/\<\?.*\?\>/g))
-      return 'application/x-httpd-php';
-    return mimeType;
-  }
-
-  /**
-   * @param {string} highlighterType
-   */
-  setHighlighterType(highlighterType) {
-    this._highlighterType = highlighterType;
-    this._updateHighlighterType('');
-  }
-
-  /**
-   * @param {string} content
-   */
-  _updateHighlighterType(content) {
-    this._textEditor.setMimeType(this._simplifyMimeType(content, this._highlighterType));
-  }
-
-  /**
-   * @param {?string} content
-   */
-  setContent(content) {
-    this._muteChangeEventsForSetContent = true;
-    if (!this._loaded) {
-      this._loaded = true;
-      this._textEditor.setText(content || '');
-      this._textEditor.markClean();
-      this._textEditor.setReadOnly(!this._editable);
-    } else {
-      const scrollTop = this._textEditor.scrollTop();
-      const selection = this._textEditor.selection();
-      this._textEditor.setText(content || '');
-      this._textEditor.setScrollTop(scrollTop);
-      this._textEditor.setSelection(selection);
-    }
-
-    this._updateHighlighterType(content || '');
-    this._wasShownOrLoaded();
-
-    if (this._delayedFindSearchMatches) {
-      this._delayedFindSearchMatches();
-      this._delayedFindSearchMatches = null;
-    }
-    this._muteChangeEventsForSetContent = false;
-    this.onTextEditorContentSet();
-  }
-
-  onTextEditorContentSet() {
-  }
-
-  /**
-   * @param {?UI.SearchableView} view
-   */
-  setSearchableView(view) {
-    this._searchableView = view;
-  }
-
-  /**
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean} jumpBackwards
-   */
-  _doFindSearchMatches(searchConfig, shouldJump, jumpBackwards) {
-    this._currentSearchResultIndex = -1;
-    this._searchResults = [];
-
-    const regex = searchConfig.toSearchRegex();
-    this._searchRegex = regex;
-    this._searchResults = this._collectRegexMatches(regex);
-
-    if (this._searchableView)
-      this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-
-    if (!this._searchResults.length)
-      this._textEditor.cancelSearchResultsHighlight();
-    else if (shouldJump && jumpBackwards)
-      this.jumpToPreviousSearchResult();
-    else if (shouldJump)
-      this.jumpToNextSearchResult();
-    else
-      this._textEditor.highlightSearchResults(regex, null);
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    if (this._searchableView)
-      this._searchableView.updateSearchMatchesCount(0);
-
-    this._resetSearch();
-    this._searchConfig = searchConfig;
-    if (this.loaded)
-      this._doFindSearchMatches(searchConfig, shouldJump, !!jumpBackwards);
-    else
-      this._delayedFindSearchMatches = this._doFindSearchMatches.bind(this, searchConfig, shouldJump, !!jumpBackwards);
-
-    this._ensureContentLoaded();
-  }
-
-  _resetCurrentSearchResultIndex() {
-    if (!this._searchResults.length)
-      return;
-    this._currentSearchResultIndex = -1;
-    if (this._searchableView)
-      this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
-    this._textEditor.highlightSearchResults(/** @type {!RegExp} */ (this._searchRegex), null);
-  }
-
-  _resetSearch() {
-    this._searchConfig = null;
-    this._delayedFindSearchMatches = null;
-    this._currentSearchResultIndex = -1;
-    this._searchResults = [];
-    this._searchRegex = null;
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    const range = this._currentSearchResultIndex !== -1 ? this._searchResults[this._currentSearchResultIndex] : null;
-    this._resetSearch();
-    if (!this.loaded)
-      return;
-    this._textEditor.cancelSearchResultsHighlight();
-    if (range)
-      this.setSelection(range);
-  }
-
-  jumpToLastSearchResult() {
-    this.jumpToSearchResult(this._searchResults.length - 1);
-  }
-
-  /**
-   * @return {number}
-   */
-  _searchResultIndexForCurrentSelection() {
-    return this._searchResults.lowerBound(this._textEditor.selection().collapseToEnd(), TextUtils.TextRange.comparator);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    const currentIndex = this._searchResultIndexForCurrentSelection();
-    const nextIndex = this._currentSearchResultIndex === -1 ? currentIndex : currentIndex + 1;
-    this.jumpToSearchResult(nextIndex);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    const currentIndex = this._searchResultIndexForCurrentSelection();
-    this.jumpToSearchResult(currentIndex - 1);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-
-  get currentSearchResultIndex() {
-    return this._currentSearchResultIndex;
-  }
-
-  jumpToSearchResult(index) {
-    if (!this.loaded || !this._searchResults.length)
-      return;
-    this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
-    if (this._searchableView)
-      this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
-    this._textEditor.highlightSearchResults(
-        /** @type {!RegExp} */ (this._searchRegex), this._searchResults[this._currentSearchResultIndex]);
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {string} replacement
-   */
-  replaceSelectionWith(searchConfig, replacement) {
-    const range = this._searchResults[this._currentSearchResultIndex];
-    if (!range)
-      return;
-    this._textEditor.highlightSearchResults(/** @type {!RegExp} */ (this._searchRegex), null);
-
-    const oldText = this._textEditor.text(range);
-    const regex = searchConfig.toSearchRegex();
-    let text;
-    if (regex.__fromRegExpQuery) {
-      text = oldText.replace(regex, replacement);
-    } else {
-      text = oldText.replace(regex, function() {
-        return replacement;
-      });
-    }
-
-    const newRange = this._textEditor.editRange(range, text);
-    this._textEditor.setSelection(newRange.collapseToEnd());
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {string} replacement
-   */
-  replaceAllWith(searchConfig, replacement) {
-    this._resetCurrentSearchResultIndex();
-
-    let text = this._textEditor.text();
-    const range = this._textEditor.fullRange();
-
-    const regex = searchConfig.toSearchRegex(true);
-    if (regex.__fromRegExpQuery) {
-      text = text.replace(regex, replacement);
-    } else {
-      text = text.replace(regex, function() {
-        return replacement;
-      });
-    }
-
-    const ranges = this._collectRegexMatches(regex);
-    if (!ranges.length)
-      return;
-
-    // Calculate the position of the end of the last range to be edited.
-    const currentRangeIndex = ranges.lowerBound(this._textEditor.selection(), TextUtils.TextRange.comparator);
-    const lastRangeIndex = mod(currentRangeIndex - 1, ranges.length);
-    const lastRange = ranges[lastRangeIndex];
-    const replacementLineEndings = replacement.computeLineEndings();
-    const replacementLineCount = replacementLineEndings.length;
-    const lastLineNumber = lastRange.startLine + replacementLineEndings.length - 1;
-    let lastColumnNumber = lastRange.startColumn;
-    if (replacementLineEndings.length > 1) {
-      lastColumnNumber =
-          replacementLineEndings[replacementLineCount - 1] - replacementLineEndings[replacementLineCount - 2] - 1;
-    }
-
-    this._textEditor.editRange(range, text);
-    this._textEditor.revealPosition(lastLineNumber, lastColumnNumber);
-    this._textEditor.setSelection(TextUtils.TextRange.createFromLocation(lastLineNumber, lastColumnNumber));
-  }
-
-  _collectRegexMatches(regexObject) {
-    const ranges = [];
-    for (let i = 0; i < this._textEditor.linesCount; ++i) {
-      let line = this._textEditor.line(i);
-      let offset = 0;
-      let match;
-      do {
-        match = regexObject.exec(line);
-        if (match) {
-          const matchEndIndex = match.index + Math.max(match[0].length, 1);
-          if (match[0].length)
-            ranges.push(new TextUtils.TextRange(i, offset + match.index, i, offset + matchEndIndex));
-          offset += matchEndIndex;
-          line = line.substring(matchEndIndex);
-        }
-      } while (match && line);
-    }
-    return ranges;
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  populateLineGutterContextMenu(contextMenu, lineNumber) {
-    return Promise.resolve();
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {
-    return Promise.resolve();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canEditSource() {
-    return this._editable;
-  }
-
-  _updateSourcePosition() {
-    const selections = this._textEditor.selections();
-    if (!selections.length)
-      return;
-    if (selections.length > 1) {
-      this._sourcePosition.setText(Common.UIString('%d selection regions', selections.length));
-      return;
-    }
-    let textRange = selections[0];
-    if (textRange.isEmpty()) {
-      const location = this._prettyToRawLocation(textRange.endLine, textRange.endColumn);
-      this._sourcePosition.setText(`Line ${location[0] + 1}, Column ${location[1] + 1}`);
-      return;
-    }
-    textRange = textRange.normalize();
-
-    const selectedText = this._textEditor.text(textRange);
-    if (textRange.startLine === textRange.endLine) {
-      this._sourcePosition.setText(Common.UIString('%d characters selected', selectedText.length));
-    } else {
-      this._sourcePosition.setText(Common.UIString(
-          '%d lines, %d characters selected', textRange.endLine - textRange.startLine + 1, selectedText.length));
-    }
-  }
-};
-
-/**
- * @interface
- */
-SourceFrame.LineDecorator = function() {};
-
-SourceFrame.LineDecorator.prototype = {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   */
-  decorate(uiSourceCode, textEditor) {}
-};
diff --git a/front_end/source_frame/SourcesTextEditor.js b/front_end/source_frame/SourcesTextEditor.js
deleted file mode 100644
index b273ac1..0000000
--- a/front_end/source_frame/SourcesTextEditor.js
+++ /dev/null
@@ -1,893 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-SourceFrame.SourcesTextEditor = class extends TextEditor.CodeMirrorTextEditor {
-  /**
-   * @param {!SourceFrame.SourcesTextEditorDelegate} delegate
-   */
-  constructor(delegate) {
-    super({
-      lineNumbers: true,
-      lineWrapping: false,
-      bracketMatchingSetting: Common.moduleSetting('textEditorBracketMatching'),
-      padBottom: true
-    });
-
-    this.codeMirror().addKeyMap({'Enter': 'smartNewlineAndIndent', 'Esc': 'sourcesDismiss'});
-
-    this._delegate = delegate;
-
-    this.codeMirror().on('cursorActivity', this._cursorActivity.bind(this));
-    this.codeMirror().on('gutterClick', this._gutterClick.bind(this));
-    this.codeMirror().on('scroll', this._scroll.bind(this));
-    this.codeMirror().on('focus', this._focus.bind(this));
-    this.codeMirror().on('blur', this._blur.bind(this));
-    this.codeMirror().on('beforeSelectionChange', this._fireBeforeSelectionChanged.bind(this));
-    this.element.addEventListener('contextmenu', this._contextMenu.bind(this), false);
-
-    this.codeMirror().addKeyMap(SourceFrame.SourcesTextEditor._BlockIndentController);
-    this._tokenHighlighter = new SourceFrame.SourcesTextEditor.TokenHighlighter(this, this.codeMirror());
-
-    /** @type {!Array<string>} */
-    this._gutters = ['CodeMirror-linenumbers'];
-    this.codeMirror().setOption('gutters', this._gutters.slice());
-
-    this.codeMirror().setOption('electricChars', false);
-    this.codeMirror().setOption('smartIndent', false);
-
-    /**
-     * @this {SourceFrame.SourcesTextEditor}
-     */
-    function updateAnticipateJumpFlag(value) {
-      this._isHandlingMouseDownEvent = value;
-    }
-
-    this.element.addEventListener('mousedown', updateAnticipateJumpFlag.bind(this, true), true);
-    this.element.addEventListener('mousedown', updateAnticipateJumpFlag.bind(this, false), false);
-    Common.moduleSetting('textEditorIndent').addChangeListener(this._onUpdateEditorIndentation, this);
-    Common.moduleSetting('textEditorAutoDetectIndent').addChangeListener(this._onUpdateEditorIndentation, this);
-    Common.moduleSetting('showWhitespacesInEditor').addChangeListener(this._updateWhitespace, this);
-
-    /** @type {?UI.AutocompleteConfig} */
-    this._autocompleteConfig = {isWordChar: TextUtils.TextUtils.isWordChar};
-    Common.moduleSetting('textEditorAutocompletion').addChangeListener(this._updateAutocomplete, this);
-    this._updateAutocomplete();
-
-    this._onUpdateEditorIndentation();
-    this._setupWhitespaceHighlight();
-  }
-
-  /**
-   * @param {!Array.<string>} lines
-   * @return {string}
-   */
-  static _guessIndentationLevel(lines) {
-    const tabRegex = /^\t+/;
-    let tabLines = 0;
-    const indents = {};
-    for (let lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
-      const text = lines[lineNumber];
-      if (text.length === 0 || !TextUtils.TextUtils.isSpaceChar(text[0]))
-        continue;
-      if (tabRegex.test(text)) {
-        ++tabLines;
-        continue;
-      }
-      let i = 0;
-      while (i < text.length && TextUtils.TextUtils.isSpaceChar(text[i]))
-        ++i;
-      if (i % 2 !== 0)
-        continue;
-      indents[i] = 1 + (indents[i] || 0);
-    }
-    const linesCountPerIndentThreshold = 3 * lines.length / 100;
-    if (tabLines && tabLines > linesCountPerIndentThreshold)
-      return '\t';
-    let minimumIndent = Infinity;
-    for (const i in indents) {
-      if (indents[i] < linesCountPerIndentThreshold)
-        continue;
-      const indent = parseInt(i, 10);
-      if (minimumIndent > indent)
-        minimumIndent = indent;
-    }
-    if (minimumIndent === Infinity)
-      return Common.moduleSetting('textEditorIndent').get();
-    return ' '.repeat(minimumIndent);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isSearchActive() {
-    return !!this._tokenHighlighter.highlightedRegex();
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   */
-  scrollToLine(lineNumber) {
-    super.scrollToLine(lineNumber);
-    this._scroll();
-  }
-
-  /**
-   * @param {!RegExp} regex
-   * @param {?TextUtils.TextRange} range
-   */
-  highlightSearchResults(regex, range) {
-    /**
-     * @this {TextEditor.CodeMirrorTextEditor}
-     */
-    function innerHighlightRegex() {
-      if (range) {
-        this.scrollLineIntoView(range.startLine);
-        if (range.endColumn > TextEditor.CodeMirrorTextEditor.maxHighlightLength)
-          this.setSelection(range);
-        else
-          this.setSelection(TextUtils.TextRange.createFromLocation(range.startLine, range.startColumn));
-      }
-      this._tokenHighlighter.highlightSearchResults(regex, range);
-    }
-
-    if (!this._selectionBeforeSearch)
-      this._selectionBeforeSearch = this.selection();
-
-    this.codeMirror().operation(innerHighlightRegex.bind(this));
-  }
-
-  cancelSearchResultsHighlight() {
-    this.codeMirror().operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
-
-    if (this._selectionBeforeSearch) {
-      this._reportJump(this._selectionBeforeSearch, this.selection());
-      delete this._selectionBeforeSearch;
-    }
-  }
-
-  /**
-   * @param {!Object} highlightDescriptor
-   */
-  removeHighlight(highlightDescriptor) {
-    highlightDescriptor.clear();
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {string} cssClass
-   * @return {!Object}
-   */
-  highlightRange(range, cssClass) {
-    cssClass = 'CodeMirror-persist-highlight ' + cssClass;
-    const pos = TextEditor.CodeMirrorUtils.toPos(range);
-    ++pos.end.ch;
-    return this.codeMirror().markText(
-        pos.start, pos.end, {className: cssClass, startStyle: cssClass + '-start', endStyle: cssClass + '-end'});
-  }
-
-  /**
-   * @param {string} type
-   * @param {boolean} leftToNumbers
-   */
-  installGutter(type, leftToNumbers) {
-    if (this._gutters.indexOf(type) !== -1)
-      return;
-
-    if (leftToNumbers)
-      this._gutters.unshift(type);
-    else
-      this._gutters.push(type);
-
-    this.codeMirror().setOption('gutters', this._gutters.slice());
-    this.refresh();
-  }
-
-  /**
-   * @param {string} type
-   */
-  uninstallGutter(type) {
-    const index = this._gutters.indexOf(type);
-    if (index === -1)
-      return;
-    this.codeMirror().clearGutter(type);
-    this._gutters.splice(index, 1);
-    this.codeMirror().setOption('gutters', this._gutters.slice());
-    this.refresh();
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {string} type
-   * @param {?Element} element
-   */
-  setGutterDecoration(lineNumber, type, element) {
-    console.assert(this._gutters.indexOf(type) !== -1, 'Cannot decorate unexisting gutter.');
-    this.codeMirror().setGutterMarker(lineNumber, type, element);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   */
-  setExecutionLocation(lineNumber, columnNumber) {
-    this.clearPositionHighlight();
-
-    this._executionLine = this.codeMirror().getLineHandle(lineNumber);
-    if (!this._executionLine)
-      return;
-
-    this.showExecutionLineBackground();
-    this.codeMirror().addLineClass(this._executionLine, 'wrap', 'cm-execution-line-outline');
-    let token = this.tokenAtTextPosition(lineNumber, columnNumber);
-
-    if (token && !token.type && token.startColumn + 1 === token.endColumn) {
-      const tokenContent = this.codeMirror().getLine(lineNumber)[token.startColumn];
-      if (tokenContent === '.' || tokenContent === '(')
-        token = this.tokenAtTextPosition(lineNumber, token.endColumn + 1);
-    }
-
-    let endColumn;
-    if (token && token.type)
-      endColumn = token.endColumn;
-    else
-      endColumn = this.codeMirror().getLine(lineNumber).length;
-
-    this._executionLineTailMarker = this.codeMirror().markText(
-        {line: lineNumber, ch: columnNumber}, {line: lineNumber, ch: endColumn}, {className: 'cm-execution-line-tail'});
-  }
-
-  showExecutionLineBackground() {
-    if (this._executionLine)
-      this.codeMirror().addLineClass(this._executionLine, 'wrap', 'cm-execution-line');
-  }
-
-  hideExecutionLineBackground() {
-    if (this._executionLine)
-      this.codeMirror().removeLineClass(this._executionLine, 'wrap', 'cm-execution-line');
-  }
-
-  clearExecutionLine() {
-    this.clearPositionHighlight();
-
-    if (this._executionLine) {
-      this.hideExecutionLineBackground();
-      this.codeMirror().removeLineClass(this._executionLine, 'wrap', 'cm-execution-line-outline');
-    }
-    delete this._executionLine;
-
-    if (this._executionLineTailMarker)
-      this._executionLineTailMarker.clear();
-    delete this._executionLineTailMarker;
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {string} className
-   * @param {boolean} toggled
-   */
-  toggleLineClass(lineNumber, className, toggled) {
-    if (this.hasLineClass(lineNumber, className) === toggled)
-      return;
-
-    const lineHandle = this.codeMirror().getLineHandle(lineNumber);
-    if (!lineHandle)
-      return;
-
-    if (toggled) {
-      this.codeMirror().addLineClass(lineHandle, 'gutter', className);
-      this.codeMirror().addLineClass(lineHandle, 'wrap', className);
-    } else {
-      this.codeMirror().removeLineClass(lineHandle, 'gutter', className);
-      this.codeMirror().removeLineClass(lineHandle, 'wrap', className);
-    }
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {string} className
-   * @return {boolean}
-   */
-  hasLineClass(lineNumber, className) {
-    const lineInfo = this.codeMirror().lineInfo(lineNumber);
-    const wrapClass = lineInfo.wrapClass || '';
-    const classNames = wrapClass.split(' ');
-    return classNames.indexOf(className) !== -1;
-  }
-
-  _gutterClick(instance, lineNumber, gutter, event) {
-    this.dispatchEventToListeners(
-        SourceFrame.SourcesTextEditor.Events.GutterClick, {lineNumber: lineNumber, event: event});
-  }
-
-  _contextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    event.consume(true);  // Consume event now to prevent document from handling the async menu
-    const wrapper = event.target.enclosingNodeOrSelfWithClass('CodeMirror-gutter-wrapper');
-    const target = wrapper ? wrapper.querySelector('.CodeMirror-linenumber') : null;
-    let promise;
-    if (target) {
-      promise = this._delegate.populateLineGutterContextMenu(contextMenu, parseInt(target.textContent, 10) - 1);
-    } else {
-      const textSelection = this.selection();
-      promise =
-          this._delegate.populateTextAreaContextMenu(contextMenu, textSelection.startLine, textSelection.startColumn);
-    }
-    promise.then(showAsync.bind(this));
-
-    /**
-     * @this {SourceFrame.SourcesTextEditor}
-     */
-    function showAsync() {
-      contextMenu.appendApplicableItems(this);
-      contextMenu.show();
-    }
-  }
-
-  /**
-   * @override
-   * @param {!TextUtils.TextRange} range
-   * @param {string} text
-   * @param {string=} origin
-   * @return {!TextUtils.TextRange}
-   */
-  editRange(range, text, origin) {
-    const newRange = super.editRange(range, text, origin);
-    if (Common.moduleSetting('textEditorAutoDetectIndent').get())
-      this._onUpdateEditorIndentation();
-
-    return newRange;
-  }
-
-  _onUpdateEditorIndentation() {
-    this._setEditorIndentation(TextEditor.CodeMirrorUtils.pullLines(
-        this.codeMirror(), SourceFrame.SourcesTextEditor.LinesToScanForIndentationGuessing));
-  }
-
-  /**
-   * @param {!Array.<string>} lines
-   */
-  _setEditorIndentation(lines) {
-    const extraKeys = {};
-    let indent = Common.moduleSetting('textEditorIndent').get();
-    if (Common.moduleSetting('textEditorAutoDetectIndent').get())
-      indent = SourceFrame.SourcesTextEditor._guessIndentationLevel(lines);
-
-    if (indent === TextUtils.TextUtils.Indent.TabCharacter) {
-      this.codeMirror().setOption('indentWithTabs', true);
-      this.codeMirror().setOption('indentUnit', 4);
-    } else {
-      this.codeMirror().setOption('indentWithTabs', false);
-      this.codeMirror().setOption('indentUnit', indent.length);
-      extraKeys.Tab = function(codeMirror) {
-        if (codeMirror.somethingSelected())
-          return CodeMirror.Pass;
-        const pos = codeMirror.getCursor('head');
-        codeMirror.replaceRange(indent.substring(pos.ch % indent.length), codeMirror.getCursor());
-      };
-    }
-
-    this.codeMirror().setOption('extraKeys', extraKeys);
-    this._indentationLevel = indent;
-  }
-
-  /**
-   * @return {string}
-   */
-  indent() {
-    return this._indentationLevel;
-  }
-
-  _onAutoAppendedSpaces() {
-    this._autoAppendedSpaces = this._autoAppendedSpaces || [];
-
-    for (let i = 0; i < this._autoAppendedSpaces.length; ++i) {
-      const position = this._autoAppendedSpaces[i].resolve();
-      if (!position)
-        continue;
-      const line = this.line(position.lineNumber);
-      if (line.length === position.columnNumber && TextUtils.TextUtils.lineIndent(line).length === line.length) {
-        this.codeMirror().replaceRange(
-            '', new CodeMirror.Pos(position.lineNumber, 0),
-            new CodeMirror.Pos(position.lineNumber, position.columnNumber));
-      }
-    }
-
-    this._autoAppendedSpaces = [];
-    const selections = this.selections();
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      this._autoAppendedSpaces.push(this.textEditorPositionHandle(selection.startLine, selection.startColumn));
-    }
-  }
-
-  _cursorActivity() {
-    if (!this._isSearchActive())
-      this.codeMirror().operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
-
-    const start = this.codeMirror().getCursor('anchor');
-    const end = this.codeMirror().getCursor('head');
-    this.dispatchEventToListeners(
-        SourceFrame.SourcesTextEditor.Events.SelectionChanged, TextEditor.CodeMirrorUtils.toRange(start, end));
-  }
-
-  /**
-   * @param {?TextUtils.TextRange} from
-   * @param {?TextUtils.TextRange} to
-   */
-  _reportJump(from, to) {
-    if (from && to && from.equal(to))
-      return;
-    this.dispatchEventToListeners(SourceFrame.SourcesTextEditor.Events.JumpHappened, {from: from, to: to});
-  }
-
-  _scroll() {
-    const topmostLineNumber = this.codeMirror().lineAtHeight(this.codeMirror().getScrollInfo().top, 'local');
-    this.dispatchEventToListeners(SourceFrame.SourcesTextEditor.Events.ScrollChanged, topmostLineNumber);
-  }
-
-  _focus() {
-    this.dispatchEventToListeners(SourceFrame.SourcesTextEditor.Events.EditorFocused);
-  }
-
-  _blur() {
-    this.dispatchEventToListeners(SourceFrame.SourcesTextEditor.Events.EditorBlurred);
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   * @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>}} selection
-   */
-  _fireBeforeSelectionChanged(codeMirror, selection) {
-    if (!this._isHandlingMouseDownEvent)
-      return;
-    if (!selection.ranges.length)
-      return;
-
-    const primarySelection = selection.ranges[0];
-    this._reportJump(
-        this.selection(), TextEditor.CodeMirrorUtils.toRange(primarySelection.anchor, primarySelection.head));
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    super.dispose();
-    Common.moduleSetting('textEditorIndent').removeChangeListener(this._onUpdateEditorIndentation, this);
-    Common.moduleSetting('textEditorAutoDetectIndent').removeChangeListener(this._onUpdateEditorIndentation, this);
-    Common.moduleSetting('showWhitespacesInEditor').removeChangeListener(this._updateWhitespace, this);
-  }
-
-  /**
-   * @override
-   * @param {string} text
-   */
-  setText(text) {
-    this._setEditorIndentation(
-        text.split('\n').slice(0, SourceFrame.SourcesTextEditor.LinesToScanForIndentationGuessing));
-    super.setText(text);
-  }
-
-  _updateWhitespace() {
-    this.setMimeType(this.mimeType());
-  }
-
-  /**
-   * @override
-   * @param {string} mimeType
-   * @return {string}
-   */
-  rewriteMimeType(mimeType) {
-    this._setupWhitespaceHighlight();
-    const whitespaceMode = Common.moduleSetting('showWhitespacesInEditor').get();
-    this.element.classList.toggle('show-whitespaces', whitespaceMode === 'all');
-
-    if (whitespaceMode === 'all')
-      return this._allWhitespaceOverlayMode(mimeType);
-    else if (whitespaceMode === 'trailing')
-      return this._trailingWhitespaceOverlayMode(mimeType);
-
-    return mimeType;
-  }
-
-  /**
-   * @param {string} mimeType
-   * @return {string}
-   */
-  _allWhitespaceOverlayMode(mimeType) {
-    let modeName = CodeMirror.mimeModes[mimeType] ?
-        (CodeMirror.mimeModes[mimeType].name || CodeMirror.mimeModes[mimeType]) :
-        CodeMirror.mimeModes['text/plain'];
-    modeName += '+all-whitespaces';
-    if (CodeMirror.modes[modeName])
-      return modeName;
-
-    function modeConstructor(config, parserConfig) {
-      function nextToken(stream) {
-        if (stream.peek() === ' ') {
-          let spaces = 0;
-          while (spaces < SourceFrame.SourcesTextEditor.MaximumNumberOfWhitespacesPerSingleSpan &&
-                 stream.peek() === ' ') {
-            ++spaces;
-            stream.next();
-          }
-          return 'whitespace whitespace-' + spaces;
-        }
-        while (!stream.eol() && stream.peek() !== ' ')
-          stream.next();
-        return null;
-      }
-      const whitespaceMode = {token: nextToken};
-      return CodeMirror.overlayMode(CodeMirror.getMode(config, mimeType), whitespaceMode, false);
-    }
-    CodeMirror.defineMode(modeName, modeConstructor);
-    return modeName;
-  }
-
-  /**
-   * @param {string} mimeType
-   * @return {string}
-   */
-  _trailingWhitespaceOverlayMode(mimeType) {
-    let modeName = CodeMirror.mimeModes[mimeType] ?
-        (CodeMirror.mimeModes[mimeType].name || CodeMirror.mimeModes[mimeType]) :
-        CodeMirror.mimeModes['text/plain'];
-    modeName += '+trailing-whitespaces';
-    if (CodeMirror.modes[modeName])
-      return modeName;
-
-    function modeConstructor(config, parserConfig) {
-      function nextToken(stream) {
-        if (stream.match(/^\s+$/, true))
-          return true ? 'trailing-whitespace' : null;
-        do
-          stream.next();
-        while (!stream.eol() && stream.peek() !== ' ');
-        return null;
-      }
-      const whitespaceMode = {token: nextToken};
-      return CodeMirror.overlayMode(CodeMirror.getMode(config, mimeType), whitespaceMode, false);
-    }
-    CodeMirror.defineMode(modeName, modeConstructor);
-    return modeName;
-  }
-
-  _setupWhitespaceHighlight() {
-    const doc = this.element.ownerDocument;
-    if (doc._codeMirrorWhitespaceStyleInjected || !Common.moduleSetting('showWhitespacesInEditor').get())
-      return;
-    doc._codeMirrorWhitespaceStyleInjected = true;
-    const classBase = '.show-whitespaces .CodeMirror .cm-whitespace-';
-    const spaceChar = '·';
-    let spaceChars = '';
-    let rules = '';
-    for (let i = 1; i <= SourceFrame.SourcesTextEditor.MaximumNumberOfWhitespacesPerSingleSpan; ++i) {
-      spaceChars += spaceChar;
-      const rule = classBase + i + '::before { content: \'' + spaceChars + '\';}\n';
-      rules += rule;
-    }
-    const style = doc.createElement('style');
-    style.textContent = rules;
-    doc.head.appendChild(style);
-  }
-
-  /**
-   * @override
-   * @param {?UI.AutocompleteConfig} config
-   */
-  configureAutocomplete(config) {
-    this._autocompleteConfig = config;
-    this._updateAutocomplete();
-  }
-
-  _updateAutocomplete() {
-    super.configureAutocomplete(
-        Common.moduleSetting('textEditorAutocompletion').get() ? this._autocompleteConfig : null);
-  }
-};
-
-/** @typedef {{lineNumber: number, event: !Event}} */
-SourceFrame.SourcesTextEditor.GutterClickEventData;
-
-/** @enum {symbol} */
-SourceFrame.SourcesTextEditor.Events = {
-  GutterClick: Symbol('GutterClick'),
-  SelectionChanged: Symbol('SelectionChanged'),
-  ScrollChanged: Symbol('ScrollChanged'),
-  EditorFocused: Symbol('EditorFocused'),
-  EditorBlurred: Symbol('EditorBlurred'),
-  JumpHappened: Symbol('JumpHappened')
-};
-
-/**
- * @interface
- */
-SourceFrame.SourcesTextEditorDelegate = function() {};
-SourceFrame.SourcesTextEditorDelegate.prototype = {
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {number} lineNumber
-   * @return {!Promise}
-   */
-  populateLineGutterContextMenu(contextMenu, lineNumber) {},
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {!Promise}
-   */
-  populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {},
-};
-
-/**
- * @param {!CodeMirror} codeMirror
- */
-CodeMirror.commands.smartNewlineAndIndent = function(codeMirror) {
-  codeMirror.operation(innerSmartNewlineAndIndent.bind(null, codeMirror));
-  function innerSmartNewlineAndIndent(codeMirror) {
-    const selections = codeMirror.listSelections();
-    const replacements = [];
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const cur = CodeMirror.cmpPos(selection.head, selection.anchor) < 0 ? selection.head : selection.anchor;
-      const line = codeMirror.getLine(cur.line);
-      const indent = TextUtils.TextUtils.lineIndent(line);
-      replacements.push('\n' + indent.substring(0, Math.min(cur.ch, indent.length)));
-    }
-    codeMirror.replaceSelections(replacements);
-    codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();
-  }
-};
-
-/**
- * @return {!Object|undefined}
- */
-CodeMirror.commands.sourcesDismiss = function(codemirror) {
-  if (codemirror.listSelections().length === 1 && codemirror._codeMirrorTextEditor._isSearchActive())
-    return CodeMirror.Pass;
-  return CodeMirror.commands.dismiss(codemirror);
-};
-
-SourceFrame.SourcesTextEditor._BlockIndentController = {
-  name: 'blockIndentKeymap',
-
-  /**
-   * @return {*}
-   */
-  Enter: function(codeMirror) {
-    let selections = codeMirror.listSelections();
-    const replacements = [];
-    let allSelectionsAreCollapsedBlocks = false;
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const start = CodeMirror.cmpPos(selection.head, selection.anchor) < 0 ? selection.head : selection.anchor;
-      const line = codeMirror.getLine(start.line);
-      const indent = TextUtils.TextUtils.lineIndent(line);
-      let indentToInsert = '\n' + indent + codeMirror._codeMirrorTextEditor.indent();
-      let isCollapsedBlock = false;
-      if (selection.head.ch === 0)
-        return CodeMirror.Pass;
-      if (line.substr(selection.head.ch - 1, 2) === '{}') {
-        indentToInsert += '\n' + indent;
-        isCollapsedBlock = true;
-      } else if (line.substr(selection.head.ch - 1, 1) !== '{') {
-        return CodeMirror.Pass;
-      }
-      if (i > 0 && allSelectionsAreCollapsedBlocks !== isCollapsedBlock)
-        return CodeMirror.Pass;
-      replacements.push(indentToInsert);
-      allSelectionsAreCollapsedBlocks = isCollapsedBlock;
-    }
-    codeMirror.replaceSelections(replacements);
-    if (!allSelectionsAreCollapsedBlocks) {
-      codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();
-      return;
-    }
-    selections = codeMirror.listSelections();
-    const updatedSelections = [];
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const line = codeMirror.getLine(selection.head.line - 1);
-      const position = new CodeMirror.Pos(selection.head.line - 1, line.length);
-      updatedSelections.push({head: position, anchor: position});
-    }
-    codeMirror.setSelections(updatedSelections);
-    codeMirror._codeMirrorTextEditor._onAutoAppendedSpaces();
-  },
-
-  /**
-   * @return {*}
-   */
-  '\'}\'': function(codeMirror) {
-    if (codeMirror.somethingSelected())
-      return CodeMirror.Pass;
-    let selections = codeMirror.listSelections();
-    let replacements = [];
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const line = codeMirror.getLine(selection.head.line);
-      if (line !== TextUtils.TextUtils.lineIndent(line))
-        return CodeMirror.Pass;
-      replacements.push('}');
-    }
-    codeMirror.replaceSelections(replacements);
-    selections = codeMirror.listSelections();
-    replacements = [];
-    const updatedSelections = [];
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const matchingBracket = codeMirror.findMatchingBracket(selection.head);
-      if (!matchingBracket || !matchingBracket.match)
-        return;
-      updatedSelections.push({head: selection.head, anchor: new CodeMirror.Pos(selection.head.line, 0)});
-      const line = codeMirror.getLine(matchingBracket.to.line);
-      const indent = TextUtils.TextUtils.lineIndent(line);
-      replacements.push(indent + '}');
-    }
-    codeMirror.setSelections(updatedSelections);
-    codeMirror.replaceSelections(replacements);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SourceFrame.SourcesTextEditor.TokenHighlighter = class {
-  /**
-   * @param {!SourceFrame.SourcesTextEditor} textEditor
-   * @param {!CodeMirror} codeMirror
-   */
-  constructor(textEditor, codeMirror) {
-    this._textEditor = textEditor;
-    this._codeMirror = codeMirror;
-  }
-
-  /**
-   * @param {!RegExp} regex
-   * @param {?TextUtils.TextRange} range
-   */
-  highlightSearchResults(regex, range) {
-    const oldRegex = this._highlightRegex;
-    this._highlightRegex = regex;
-    this._highlightRange = range;
-    if (this._searchResultMarker) {
-      this._searchResultMarker.clear();
-      delete this._searchResultMarker;
-    }
-    if (this._highlightDescriptor && this._highlightDescriptor.selectionStart)
-      this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, 'wrap', 'cm-line-with-selection');
-    const selectionStart = this._highlightRange ?
-        new CodeMirror.Pos(this._highlightRange.startLine, this._highlightRange.startColumn) :
-        null;
-    if (selectionStart)
-      this._codeMirror.addLineClass(selectionStart.line, 'wrap', 'cm-line-with-selection');
-    if (oldRegex && this._highlightRegex.toString() === oldRegex.toString()) {
-      // Do not re-add overlay mode if regex did not change for better performance.
-      if (this._highlightDescriptor)
-        this._highlightDescriptor.selectionStart = selectionStart;
-    } else {
-      this._removeHighlight();
-      this._setHighlighter(this._searchHighlighter.bind(this, this._highlightRegex), selectionStart);
-    }
-    if (this._highlightRange) {
-      const pos = TextEditor.CodeMirrorUtils.toPos(this._highlightRange);
-      this._searchResultMarker = this._codeMirror.markText(pos.start, pos.end, {className: 'cm-column-with-selection'});
-    }
-  }
-
-  /**
-   * @return {!RegExp|undefined}
-   */
-  highlightedRegex() {
-    return this._highlightRegex;
-  }
-
-  highlightSelectedTokens() {
-    delete this._highlightRegex;
-    delete this._highlightRange;
-    if (this._highlightDescriptor && this._highlightDescriptor.selectionStart)
-      this._codeMirror.removeLineClass(this._highlightDescriptor.selectionStart.line, 'wrap', 'cm-line-with-selection');
-    this._removeHighlight();
-    const selectionStart = this._codeMirror.getCursor('start');
-    const selectionEnd = this._codeMirror.getCursor('end');
-    if (selectionStart.line !== selectionEnd.line)
-      return;
-    if (selectionStart.ch === selectionEnd.ch)
-      return;
-    const selections = this._codeMirror.getSelections();
-    if (selections.length > 1)
-      return;
-    const selectedText = selections[0];
-    if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, selectionEnd.ch)) {
-      if (selectionStart)
-        this._codeMirror.addLineClass(selectionStart.line, 'wrap', 'cm-line-with-selection');
-      this._setHighlighter(this._tokenHighlighter.bind(this, selectedText, selectionStart), selectionStart);
-    }
-  }
-
-  /**
-   * @param {string} selectedText
-   * @param {number} lineNumber
-   * @param {number} startColumn
-   * @param {number} endColumn
-   */
-  _isWord(selectedText, lineNumber, startColumn, endColumn) {
-    const line = this._codeMirror.getLine(lineNumber);
-    const leftBound = startColumn === 0 || !TextUtils.TextUtils.isWordChar(line.charAt(startColumn - 1));
-    const rightBound = endColumn === line.length || !TextUtils.TextUtils.isWordChar(line.charAt(endColumn));
-    return leftBound && rightBound && TextUtils.TextUtils.isWord(selectedText);
-  }
-
-  _removeHighlight() {
-    if (this._highlightDescriptor) {
-      this._codeMirror.removeOverlay(this._highlightDescriptor.overlay);
-      delete this._highlightDescriptor;
-    }
-  }
-
-  /**
-   * @param {!RegExp} regex
-   * @param {!CodeMirror.StringStream} stream
-   */
-  _searchHighlighter(regex, stream) {
-    if (stream.column() === 0)
-      delete this._searchMatchLength;
-    if (this._searchMatchLength) {
-      if (this._searchMatchLength > 2) {
-        for (let i = 0; i < this._searchMatchLength - 2; ++i)
-          stream.next();
-        this._searchMatchLength = 1;
-        return 'search-highlight';
-      } else {
-        stream.next();
-        delete this._searchMatchLength;
-        return 'search-highlight search-highlight-end';
-      }
-    }
-    const match = stream.match(regex, false);
-    if (match) {
-      stream.next();
-      const matchLength = match[0].length;
-      if (matchLength === 1)
-        return 'search-highlight search-highlight-full';
-      this._searchMatchLength = matchLength;
-      return 'search-highlight search-highlight-start';
-    }
-    while (!stream.match(regex, false) && stream.next()) {
-    }
-  }
-
-  /**
-   * @param {string} token
-   * @param {!CodeMirror.Pos} selectionStart
-   * @param {!CodeMirror.StringStream} stream
-   */
-  _tokenHighlighter(token, selectionStart, stream) {
-    const tokenFirstChar = token.charAt(0);
-    if (stream.match(token) && (stream.eol() || !TextUtils.TextUtils.isWordChar(stream.peek())))
-      return stream.column() === selectionStart.ch ? 'token-highlight column-with-selection' : 'token-highlight';
-    let eatenChar;
-    do
-      eatenChar = stream.next();
-    while (eatenChar && (TextUtils.TextUtils.isWordChar(eatenChar) || stream.peek() !== tokenFirstChar));
-  }
-
-  /**
-   * @param {function(!CodeMirror.StringStream)} highlighter
-   * @param {?CodeMirror.Pos} selectionStart
-   */
-  _setHighlighter(highlighter, selectionStart) {
-    const overlayMode = {token: highlighter};
-    this._codeMirror.addOverlay(overlayMode);
-    this._highlightDescriptor = {overlay: overlayMode, selectionStart: selectionStart};
-  }
-};
-
-SourceFrame.SourcesTextEditor.LinesToScanForIndentationGuessing = 1000;
-SourceFrame.SourcesTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16;
diff --git a/front_end/source_frame/XMLView.js b/front_end/source_frame/XMLView.js
deleted file mode 100644
index cc0434b..0000000
--- a/front_end/source_frame/XMLView.js
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.Searchable}
- * @unrestricted
- */
-SourceFrame.XMLView = class extends UI.Widget {
-  /**
-   * @param {!Document} parsedXML
-   */
-  constructor(parsedXML) {
-    super(true);
-    this.registerRequiredCSS('source_frame/xmlView.css');
-    this.contentElement.classList.add('shadow-xml-view', 'source-code');
-    this._treeOutline = new UI.TreeOutlineInShadow();
-    this._treeOutline.registerRequiredCSS('source_frame/xmlTree.css');
-    this.contentElement.appendChild(this._treeOutline.element);
-
-    /** @type {?UI.SearchableView} */
-    this._searchableView;
-    /** @type {number} */
-    this._currentSearchFocusIndex = 0;
-    /** @type {!Array.<!UI.TreeElement>} */
-    this._currentSearchTreeElements = [];
-    /** @type {?UI.SearchableView.SearchConfig} */
-    this._searchConfig;
-
-    SourceFrame.XMLView.Node.populate(this._treeOutline, parsedXML, this);
-  }
-
-  /**
-   * @param {!Document} parsedXML
-   * @return {!UI.SearchableView}
-   */
-  static createSearchableView(parsedXML) {
-    const xmlView = new SourceFrame.XMLView(parsedXML);
-    const searchableView = new UI.SearchableView(xmlView);
-    searchableView.setPlaceholder(Common.UIString('Find'));
-    xmlView._searchableView = searchableView;
-    xmlView.show(searchableView.element);
-    xmlView.contentElement.setAttribute('tabIndex', 0);
-    return searchableView;
-  }
-
-  /**
-   * @param {string} text
-   * @param {string} mimeType
-   * @return {?Document}
-   */
-  static parseXML(text, mimeType) {
-    let parsedXML;
-    try {
-      parsedXML = (new DOMParser()).parseFromString(text, mimeType);
-    } catch (e) {
-      return null;
-    }
-    if (parsedXML.body)
-      return null;
-    return parsedXML;
-  }
-
-  /**
-   * @param {number} index
-   * @param {boolean} shouldJump
-   */
-  _jumpToMatch(index, shouldJump) {
-    if (!this._searchConfig)
-      return;
-    const regex = this._searchConfig.toSearchRegex(true);
-    const previousFocusElement = this._currentSearchTreeElements[this._currentSearchFocusIndex];
-    if (previousFocusElement)
-      previousFocusElement.setSearchRegex(regex);
-
-    const newFocusElement = this._currentSearchTreeElements[index];
-    if (newFocusElement) {
-      this._updateSearchIndex(index);
-      if (shouldJump)
-        newFocusElement.reveal(true);
-      newFocusElement.setSearchRegex(regex, UI.highlightedCurrentSearchResultClassName);
-    } else {
-      this._updateSearchIndex(0);
-    }
-  }
-
-  /**
-   * @param {number} count
-   */
-  _updateSearchCount(count) {
-    if (!this._searchableView)
-      return;
-    this._searchableView.updateSearchMatchesCount(count);
-  }
-
-  /**
-   * @param {number} index
-   */
-  _updateSearchIndex(index) {
-    this._currentSearchFocusIndex = index;
-    if (!this._searchableView)
-      return;
-    this._searchableView.updateCurrentMatchIndex(index);
-  }
-
-  /**
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  _innerPerformSearch(shouldJump, jumpBackwards) {
-    if (!this._searchConfig)
-      return;
-    let newIndex = this._currentSearchFocusIndex;
-    const previousSearchFocusElement = this._currentSearchTreeElements[newIndex];
-    this._innerSearchCanceled();
-    this._currentSearchTreeElements = [];
-    const regex = this._searchConfig.toSearchRegex(true);
-
-    for (let element = this._treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) {
-      if (!(element instanceof SourceFrame.XMLView.Node))
-        continue;
-      const hasMatch = element.setSearchRegex(regex);
-      if (hasMatch)
-        this._currentSearchTreeElements.push(element);
-      if (previousSearchFocusElement === element) {
-        const currentIndex = this._currentSearchTreeElements.length - 1;
-        if (hasMatch || jumpBackwards)
-          newIndex = currentIndex;
-        else
-          newIndex = currentIndex + 1;
-      }
-    }
-    this._updateSearchCount(this._currentSearchTreeElements.length);
-
-    if (!this._currentSearchTreeElements.length) {
-      this._updateSearchIndex(0);
-      return;
-    }
-    newIndex = mod(newIndex, this._currentSearchTreeElements.length);
-
-    this._jumpToMatch(newIndex, shouldJump);
-  }
-
-  _innerSearchCanceled() {
-    for (let element = this._treeOutline.rootElement(); element; element = element.traverseNextTreeElement(false)) {
-      if (!(element instanceof SourceFrame.XMLView.Node))
-        continue;
-      element.revertHighlightChanges();
-    }
-    this._updateSearchCount(0);
-    this._updateSearchIndex(0);
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._searchConfig = null;
-    this._currentSearchTreeElements = [];
-    this._innerSearchCanceled();
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this._searchConfig = searchConfig;
-    this._innerPerformSearch(shouldJump, jumpBackwards);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._currentSearchTreeElements.length)
-      return;
-
-    const newIndex = mod(this._currentSearchFocusIndex + 1, this._currentSearchTreeElements.length);
-    this._jumpToMatch(newIndex, true);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._currentSearchTreeElements.length)
-      return;
-
-    const newIndex = mod(this._currentSearchFocusIndex - 1, this._currentSearchTreeElements.length);
-    this._jumpToMatch(newIndex, true);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-SourceFrame.XMLView.Node = class extends UI.TreeElement {
-  /**
-   * @param {!Node} node
-   * @param {boolean} closeTag
-   * @param {!SourceFrame.XMLView} xmlView
-   */
-  constructor(node, closeTag, xmlView) {
-    super('', !closeTag && !!node.childElementCount);
-    this._node = node;
-    this._closeTag = closeTag;
-    this.selectable = false;
-    /** @type {!Array.<!Object>} */
-    this._highlightChanges = [];
-    this._xmlView = xmlView;
-    this._updateTitle();
-  }
-
-  /**
-   * @param {!UI.TreeOutline|!UI.TreeElement} root
-   * @param {!Node} xmlNode
-   * @param {!SourceFrame.XMLView} xmlView
-   */
-  static populate(root, xmlNode, xmlView) {
-    let node = xmlNode.firstChild;
-    while (node) {
-      const currentNode = node;
-      node = node.nextSibling;
-      const nodeType = currentNode.nodeType;
-      // ignore empty TEXT
-      if (nodeType === 3 && currentNode.nodeValue.match(/\s+/))
-        continue;
-      // ignore ATTRIBUTE, ENTITY_REFERENCE, ENTITY, DOCUMENT, DOCUMENT_TYPE, DOCUMENT_FRAGMENT, NOTATION
-      if ((nodeType !== 1) && (nodeType !== 3) && (nodeType !== 4) && (nodeType !== 7) && (nodeType !== 8))
-        continue;
-      root.appendChild(new SourceFrame.XMLView.Node(currentNode, false, xmlView));
-    }
-  }
-
-  /**
-   * @param {?RegExp} regex
-   * @param {string=} additionalCssClassName
-   * @return {boolean}
-   */
-  setSearchRegex(regex, additionalCssClassName) {
-    this.revertHighlightChanges();
-    if (!regex)
-      return false;
-    if (this._closeTag && this.parent && !this.parent.expanded)
-      return false;
-    regex.lastIndex = 0;
-    let cssClasses = UI.highlightedSearchResultClassName;
-    if (additionalCssClassName)
-      cssClasses += ' ' + additionalCssClassName;
-    const content = this.listItemElement.textContent.replace(/\xA0/g, ' ');
-    let match = regex.exec(content);
-    const ranges = [];
-    while (match) {
-      ranges.push(new TextUtils.SourceRange(match.index, match[0].length));
-      match = regex.exec(content);
-    }
-    if (ranges.length)
-      UI.highlightRangesWithStyleClass(this.listItemElement, ranges, cssClasses, this._highlightChanges);
-    return !!this._highlightChanges.length;
-  }
-
-  revertHighlightChanges() {
-    UI.revertDomChanges(this._highlightChanges);
-    this._highlightChanges = [];
-  }
-
-  _updateTitle() {
-    const node = this._node;
-    switch (node.nodeType) {
-      case 1:  // ELEMENT
-        const tag = node.tagName;
-        if (this._closeTag) {
-          this._setTitle(['</' + tag + '>', 'shadow-xml-view-tag']);
-          return;
-        }
-        const titleItems = ['<' + tag, 'shadow-xml-view-tag'];
-        const attributes = node.attributes;
-        for (let i = 0; i < attributes.length; ++i) {
-          const attributeNode = attributes.item(i);
-          titleItems.push(
-              '\u00a0', 'shadow-xml-view-tag', attributeNode.name, 'shadow-xml-view-attribute-name', '="',
-              'shadow-xml-view-tag', attributeNode.value, 'shadow-xml-view-attribute-value', '"',
-              'shadow-xml-view-tag');
-        }
-        if (!this.expanded) {
-          if (node.childElementCount) {
-            titleItems.push(
-                '>', 'shadow-xml-view-tag', '\u2026', 'shadow-xml-view-comment', '</' + tag, 'shadow-xml-view-tag');
-          } else if (this._node.textContent) {
-            titleItems.push(
-                '>', 'shadow-xml-view-tag', node.textContent, 'shadow-xml-view-text', '</' + tag,
-                'shadow-xml-view-tag');
-          } else {
-            titleItems.push(' /', 'shadow-xml-view-tag');
-          }
-        }
-        titleItems.push('>', 'shadow-xml-view-tag');
-        this._setTitle(titleItems);
-        return;
-      case 3:  // TEXT
-        this._setTitle([node.nodeValue, 'shadow-xml-view-text']);
-        return;
-      case 4:  // CDATA
-        this._setTitle([
-          '<![CDATA[', 'shadow-xml-view-cdata', node.nodeValue, 'shadow-xml-view-text', ']]>', 'shadow-xml-view-cdata'
-        ]);
-        return;
-      case 7:  // PROCESSING_INSTRUCTION
-        this._setTitle(['<?' + node.nodeName + ' ' + node.nodeValue + '?>', 'shadow-xml-view-processing-instruction']);
-        return;
-      case 8:  // COMMENT
-        this._setTitle(['<!--' + node.nodeValue + '-->', 'shadow-xml-view-comment']);
-        return;
-    }
-  }
-
-  /**
-   * @param {!Array.<string>} items
-   */
-  _setTitle(items) {
-    const titleFragment = createDocumentFragment();
-    for (let i = 0; i < items.length; i += 2)
-      titleFragment.createChild('span', items[i + 1]).textContent = items[i];
-    this.title = titleFragment;
-    this._xmlView._innerPerformSearch(false, false);
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.classList.toggle('shadow-xml-view-close-tag', this._closeTag);
-  }
-
-  /**
-   * @override
-   */
-  onexpand() {
-    this._updateTitle();
-  }
-
-  /**
-   * @override
-   */
-  oncollapse() {
-    this._updateTitle();
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    SourceFrame.XMLView.Node.populate(this, this._node, this._xmlView);
-    this.appendChild(new SourceFrame.XMLView.Node(this._node, true, this._xmlView));
-  }
-};
diff --git a/front_end/source_frame/fontView.css b/front_end/source_frame/fontView.css
deleted file mode 100644
index 1faad7e..0000000
--- a/front_end/source_frame/fontView.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.font-view {
-    font-size: 60px;
-    white-space: pre-wrap;
-    word-wrap: break-word;
-    text-align: center;
-    padding: 15px;
-}
diff --git a/front_end/source_frame/imageView.css b/front_end/source_frame/imageView.css
deleted file mode 100644
index 4e2e215..0000000
--- a/front_end/source_frame/imageView.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.image-view {
-    overflow: auto;
-}
-
-.image-view > .image {
-    padding: 20px 20px 10px 20px;
-    text-align: center;
-}
-
-.image-view img.resource-image-view {
-    max-width: 100%;
-    max-height: 1000px;
-    background-image: url(Images/checker.png);
-    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5);
-    -webkit-user-select: text;
-    -webkit-user-drag: auto;
-}
diff --git a/front_end/source_frame/jsonView.css b/front_end/source_frame/jsonView.css
deleted file mode 100644
index b78a071..0000000
--- a/front_end/source_frame/jsonView.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.json-view {
-    padding: 2px 6px;
-    overflow: auto;
-}
diff --git a/front_end/source_frame/messagesPopover.css b/front_end/source_frame/messagesPopover.css
deleted file mode 100644
index f083c46..0000000
--- a/front_end/source_frame/messagesPopover.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.text-editor-messages-description-container {
-    display: inline-block;
-}
-
-.text-editor-row-message:first-child {
-    border-top-width: 0;
-}
-
-.text-editor-row-message {
-    line-height: 1.2;
-    white-space: nowrap;
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    margin-top: 2px;
-}
-
-.text-editor-row-message-repeat-count {
-    margin-right: 0.5em;
-}
diff --git a/front_end/source_frame/module.json b/front_end/source_frame/module.json
deleted file mode 100644
index c670fc1..0000000
--- a/front_end/source_frame/module.json
+++ /dev/null
@@ -1,63 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Default indentation:",
-            "settingName": "textEditorIndent",
-            "settingType": "enum",
-            "defaultValue": "    ",
-            "options": [
-                {
-                    "title": "Set indentation to 2 spaces",
-                    "text": "2 spaces",
-                    "value": "  "
-                },
-                {
-                    "title": "Set indentation to 4 spaces",
-                    "text": "4 spaces",
-                    "value": "    "
-                },
-                {
-                    "title": "Set indentation to 8 spaces",
-                    "text": "8 spaces",
-                    "value": "        "
-                },
-                {
-                    "title": "Set indentation to tab character",
-                    "text": "Tab character",
-                    "value": "\t"
-                }
-            ]
-        }
-    ],
-    "dependencies": [
-        "text_editor",
-        "ui",
-        "platform",
-        "persistence",
-        "formatter",
-        "object_ui",
-        "workspace_diff"
-    ],
-    "scripts": [
-        "SourcesTextEditor.js",
-        "FontView.js",
-        "ImageView.js",
-        "SourceFrame.js",
-        "ResourceSourceFrame.js",
-        "JSONView.js",
-        "XMLView.js",
-        "PreviewFactory.js",
-        "SourceCodeDiff.js"
-    ],
-    "resources": [
-        "fontView.css",
-        "imageView.css",
-        "jsonView.css",
-        "messagesPopover.css",
-        "xmlTree.css",
-        "xmlView.css",
-        "resourceSourceFrame.css"
-    ]
-}
diff --git a/front_end/source_frame/resourceSourceFrame.css b/front_end/source_frame/resourceSourceFrame.css
deleted file mode 100644
index b09ae48..0000000
--- a/front_end/source_frame/resourceSourceFrame.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-.searchable-view {
-  flex: 1;
-}
-
-.toolbar {
-  background-color: #eee;
-  border-top: 1px solid #ccc;
-}
diff --git a/front_end/source_frame/xmlTree.css b/front_end/source_frame/xmlTree.css
deleted file mode 100644
index cd810c2..0000000
--- a/front_end/source_frame/xmlTree.css
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tree-outline ol {
-    list-style: none;
-    padding: 0;
-    margin: 0;
-    -webkit-padding-start: 16px;
-}
-
-ol.tree-outline {
-    -webkit-padding-start: 0;
-}
-
-.tree-outline li {
-    min-height: 12px;
-}
-
-.tree-outline li.shadow-xml-view-close-tag {
-    margin-left: -16px;
-}
-
-.shadow-xml-view-tag {
-    color: rgb(136, 18, 128);
-}
-
-.shadow-xml-view-comment {
-    color: rgb(35, 110, 37);
-}
-
-.shadow-xml-view-processing-instruction {
-    color: rgb(35, 110, 37);
-}
-
-.shadow-xml-view-attribute-name {
-    color: rgb(153, 69, 0);
-}
-
-.shadow-xml-view-attribute-value {
-    color: rgb(26, 26, 166);
-}
-
-.shadow-xml-view-text {
-    color: rgb(0, 0, 0);
-    white-space: pre;
-}
-
-.shadow-xml-view-cdata {
-    color: rgb(0, 0, 0);
-}
diff --git a/front_end/source_frame/xmlView.css b/front_end/source_frame/xmlView.css
deleted file mode 100644
index e05d207..0000000
--- a/front_end/source_frame/xmlView.css
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.shadow-xml-view {
-    -webkit-user-select: text;
-    overflow: auto;
-    padding: 2px 4px;
-}
diff --git a/front_end/sources/AddSourceMapURLDialog.js b/front_end/sources/AddSourceMapURLDialog.js
deleted file mode 100644
index 81959ea..0000000
--- a/front_end/sources/AddSourceMapURLDialog.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Sources.AddSourceMapURLDialog = class extends UI.HBox {
-  /**
-   * @param {function(string)} callback
-   */
-  constructor(callback) {
-    super(true);
-    this.registerRequiredCSS('sources/dialog.css');
-    this.contentElement.createChild('label').textContent = Common.UIString('Source map URL: ');
-
-    this._input = UI.createInput();
-    this.contentElement.appendChild(this._input);
-    this._input.setAttribute('type', 'text');
-    this._input.addEventListener('keydown', this._onKeyDown.bind(this), false);
-
-    const addButton = this.contentElement.createChild('button');
-    addButton.textContent = Common.UIString('Add');
-    addButton.addEventListener('click', this._apply.bind(this), false);
-
-    this.setDefaultFocusedElement(this._input);
-    this._callback = callback;
-    this.contentElement.tabIndex = 0;
-  }
-
-  /**
-   * @param {function(string)} callback
-   */
-  static show(callback) {
-    const dialog = new UI.Dialog();
-    const addSourceMapURLDialog = new Sources.AddSourceMapURLDialog(done);
-    addSourceMapURLDialog.show(dialog.contentElement);
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.show();
-
-    /**
-     * @param {string} value
-     */
-    function done(value) {
-      dialog.hide();
-      callback(value);
-    }
-  }
-
-  _apply() {
-    this._callback(this._input.value);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (event.keyCode === UI.KeyboardShortcut.Keys.Enter.code) {
-      event.preventDefault();
-      this._apply();
-    }
-  }
-};
diff --git a/front_end/sources/CSSPlugin.js b/front_end/sources/CSSPlugin.js
deleted file mode 100644
index 59109dd..0000000
--- a/front_end/sources/CSSPlugin.js
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Sources.UISourceCodeFrame.Plugin}
- * @unrestricted
- */
-Sources.CSSPlugin = class {
-  /**
-   * @param {!SourceFrame.SourcesTextEditor} textEditor
-   */
-  constructor(textEditor) {
-    this._textEditor = textEditor;
-    this._swatchPopoverHelper = new InlineEditor.SwatchPopoverHelper();
-    this._muteSwatchProcessing = false;
-    this._textEditor.configureAutocomplete(
-        {suggestionsCallback: this._cssSuggestions.bind(this), isWordChar: this._isWordChar.bind(this)});
-    this._textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.ScrollChanged, this._textEditorScrolled, this);
-    this._textEditor.addEventListener(UI.TextEditor.Events.TextChanged, this._onTextChanged, this);
-    this._updateSwatches(0, this._textEditor.linesCount - 1);
-
-    this._shortcuts = {};
-    this._registerShortcuts();
-    this._boundHandleKeyDown = this._handleKeyDown.bind(this);
-    this._textEditor.element.addEventListener('keydown', this._boundHandleKeyDown, false);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  static accepts(uiSourceCode) {
-    return uiSourceCode.contentType().isStyleSheet();
-  }
-
-  _registerShortcuts() {
-    const shortcutKeys = UI.ShortcutsScreen.SourcesPanelShortcuts;
-    for (const descriptor of shortcutKeys.IncreaseCSSUnitByOne)
-      this._shortcuts[descriptor.key] = this._handleUnitModification.bind(this, 1);
-    for (const descriptor of shortcutKeys.DecreaseCSSUnitByOne)
-      this._shortcuts[descriptor.key] = this._handleUnitModification.bind(this, -1);
-    for (const descriptor of shortcutKeys.IncreaseCSSUnitByTen)
-      this._shortcuts[descriptor.key] = this._handleUnitModification.bind(this, 10);
-    for (const descriptor of shortcutKeys.DecreaseCSSUnitByTen)
-      this._shortcuts[descriptor.key] = this._handleUnitModification.bind(this, -10);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleKeyDown(event) {
-    const shortcutKey = UI.KeyboardShortcut.makeKeyFromEvent(/** @type {!KeyboardEvent} */ (event));
-    const handler = this._shortcuts[shortcutKey];
-    if (handler && handler())
-      event.consume(true);
-  }
-
-  _textEditorScrolled() {
-    if (this._swatchPopoverHelper.isShowing())
-      this._swatchPopoverHelper.hide(true);
-  }
-
-  /**
-   * @param {string} unit
-   * @param {number} change
-   * @return {?string}
-   */
-  _modifyUnit(unit, change) {
-    const unitValue = parseInt(unit, 10);
-    if (isNaN(unitValue))
-      return null;
-    const tail = unit.substring((unitValue).toString().length);
-    return String.sprintf('%d%s', unitValue + change, tail);
-  }
-
-  /**
-   * @param {number} change
-   * @return {boolean}
-   */
-  _handleUnitModification(change) {
-    const selection = this._textEditor.selection().normalize();
-    let token = this._textEditor.tokenAtTextPosition(selection.startLine, selection.startColumn);
-    if (!token) {
-      if (selection.startColumn > 0)
-        token = this._textEditor.tokenAtTextPosition(selection.startLine, selection.startColumn - 1);
-      if (!token)
-        return false;
-    }
-    if (token.type !== 'css-number')
-      return false;
-
-    const cssUnitRange =
-        new TextUtils.TextRange(selection.startLine, token.startColumn, selection.startLine, token.endColumn);
-    const cssUnitText = this._textEditor.text(cssUnitRange);
-    const newUnitText = this._modifyUnit(cssUnitText, change);
-    if (!newUnitText)
-      return false;
-    this._textEditor.editRange(cssUnitRange, newUnitText);
-    selection.startColumn = token.startColumn;
-    selection.endColumn = selection.startColumn + newUnitText.length;
-    this._textEditor.setSelection(selection);
-    return true;
-  }
-
-  /**
-   * @param {number} startLine
-   * @param {number} endLine
-   */
-  _updateSwatches(startLine, endLine) {
-    const swatches = [];
-    const swatchPositions = [];
-
-    const regexes =
-        [SDK.CSSMetadata.VariableRegex, SDK.CSSMetadata.URLRegex, UI.Geometry.CubicBezier.Regex, Common.Color.Regex];
-    const handlers = new Map();
-    handlers.set(Common.Color.Regex, this._createColorSwatch.bind(this));
-    handlers.set(UI.Geometry.CubicBezier.Regex, this._createBezierSwatch.bind(this));
-
-    for (let lineNumber = startLine; lineNumber <= endLine; lineNumber++) {
-      const line = this._textEditor.line(lineNumber).substring(0, Sources.CSSPlugin.maxSwatchProcessingLength);
-      const results = TextUtils.TextUtils.splitStringByRegexes(line, regexes);
-      for (let i = 0; i < results.length; i++) {
-        const result = results[i];
-        if (result.regexIndex === -1 || !handlers.has(regexes[result.regexIndex]))
-          continue;
-        const delimiters = /[\s:;,(){}]/;
-        const positionBefore = result.position - 1;
-        const positionAfter = result.position + result.value.length;
-        if (positionBefore >= 0 && !delimiters.test(line.charAt(positionBefore)) ||
-            positionAfter < line.length && !delimiters.test(line.charAt(positionAfter)))
-          continue;
-        const swatch = handlers.get(regexes[result.regexIndex])(result.value);
-        if (!swatch)
-          continue;
-        swatches.push(swatch);
-        swatchPositions.push(TextUtils.TextRange.createFromLocation(lineNumber, result.position));
-      }
-    }
-    this._textEditor.operation(putSwatchesInline.bind(this));
-
-    /**
-     * @this {Sources.CSSPlugin}
-     */
-    function putSwatchesInline() {
-      const clearRange = new TextUtils.TextRange(startLine, 0, endLine, this._textEditor.line(endLine).length);
-      this._textEditor.bookmarks(clearRange, Sources.CSSPlugin.SwatchBookmark).forEach(marker => marker.clear());
-
-      for (let i = 0; i < swatches.length; i++) {
-        const swatch = swatches[i];
-        const swatchPosition = swatchPositions[i];
-        const bookmark = this._textEditor.addBookmark(
-            swatchPosition.startLine, swatchPosition.startColumn, swatch, Sources.CSSPlugin.SwatchBookmark);
-        swatch[Sources.CSSPlugin.SwatchBookmark] = bookmark;
-      }
-    }
-  }
-
-  /**
-   * @param {string} text
-   * @return {?InlineEditor.ColorSwatch}
-   */
-  _createColorSwatch(text) {
-    const color = Common.Color.parse(text);
-    if (!color)
-      return null;
-    const swatch = InlineEditor.ColorSwatch.create();
-    swatch.setColor(color);
-    swatch.iconElement().title = Common.UIString('Open color picker.');
-    swatch.iconElement().addEventListener('click', this._swatchIconClicked.bind(this, swatch), false);
-    swatch.hideText(true);
-    return swatch;
-  }
-
-  /**
-   * @param {string} text
-   * @return {?InlineEditor.BezierSwatch}
-   */
-  _createBezierSwatch(text) {
-    if (!UI.Geometry.CubicBezier.parse(text))
-      return null;
-    const swatch = InlineEditor.BezierSwatch.create();
-    swatch.setBezierText(text);
-    swatch.iconElement().title = Common.UIString('Open cubic bezier editor.');
-    swatch.iconElement().addEventListener('click', this._swatchIconClicked.bind(this, swatch), false);
-    swatch.hideText(true);
-    return swatch;
-  }
-
-  /**
-   * @param {!Element} swatch
-   * @param {!Event} event
-   */
-  _swatchIconClicked(swatch, event) {
-    event.consume(true);
-    this._hadSwatchChange = false;
-    this._muteSwatchProcessing = true;
-    const swatchPosition = swatch[Sources.CSSPlugin.SwatchBookmark].position();
-    this._textEditor.setSelection(swatchPosition);
-    this._editedSwatchTextRange = swatchPosition.clone();
-    this._editedSwatchTextRange.endColumn += swatch.textContent.length;
-    this._currentSwatch = swatch;
-
-    if (swatch instanceof InlineEditor.ColorSwatch)
-      this._showSpectrum(swatch);
-    else if (swatch instanceof InlineEditor.BezierSwatch)
-      this._showBezierEditor(swatch);
-  }
-
-  /**
-   * @param {!InlineEditor.ColorSwatch} swatch
-   */
-  _showSpectrum(swatch) {
-    if (!this._spectrum) {
-      this._spectrum = new ColorPicker.Spectrum();
-      this._spectrum.addEventListener(ColorPicker.Spectrum.Events.SizeChanged, this._spectrumResized, this);
-      this._spectrum.addEventListener(ColorPicker.Spectrum.Events.ColorChanged, this._spectrumChanged, this);
-    }
-    this._spectrum.setColor(swatch.color(), swatch.format());
-    this._swatchPopoverHelper.show(this._spectrum, swatch.iconElement(), this._swatchPopoverHidden.bind(this));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _spectrumResized(event) {
-    this._swatchPopoverHelper.reposition();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _spectrumChanged(event) {
-    const colorString = /** @type {string} */ (event.data);
-    const color = Common.Color.parse(colorString);
-    if (!color)
-      return;
-    this._currentSwatch.setColor(color);
-    this._changeSwatchText(colorString);
-  }
-
-  /**
-   * @param {!InlineEditor.BezierSwatch} swatch
-   */
-  _showBezierEditor(swatch) {
-    if (!this._bezierEditor) {
-      this._bezierEditor = new InlineEditor.BezierEditor();
-      this._bezierEditor.addEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._bezierChanged, this);
-    }
-    let cubicBezier = UI.Geometry.CubicBezier.parse(swatch.bezierText());
-    if (!cubicBezier) {
-      cubicBezier =
-          /** @type {!UI.Geometry.CubicBezier} */ (UI.Geometry.CubicBezier.parse('linear'));
-    }
-    this._bezierEditor.setBezier(cubicBezier);
-    this._swatchPopoverHelper.show(this._bezierEditor, swatch.iconElement(), this._swatchPopoverHidden.bind(this));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _bezierChanged(event) {
-    const bezierString = /** @type {string} */ (event.data);
-    this._currentSwatch.setBezierText(bezierString);
-    this._changeSwatchText(bezierString);
-  }
-
-  /**
-   * @param {string} text
-   */
-  _changeSwatchText(text) {
-    this._hadSwatchChange = true;
-    this._textEditor.editRange(this._editedSwatchTextRange, text, '*swatch-text-changed');
-    this._editedSwatchTextRange.endColumn = this._editedSwatchTextRange.startColumn + text.length;
-  }
-
-  /**
-   * @param {boolean} commitEdit
-   */
-  _swatchPopoverHidden(commitEdit) {
-    this._muteSwatchProcessing = false;
-    if (!commitEdit && this._hadSwatchChange)
-      this._textEditor.undo();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onTextChanged(event) {
-    if (!this._muteSwatchProcessing)
-      this._updateSwatches(event.data.newRange.startLine, event.data.newRange.endLine);
-  }
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  _isWordChar(char) {
-    return TextUtils.TextUtils.isWordChar(char) || char === '.' || char === '-' || char === '$';
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} prefixRange
-   * @param {!TextUtils.TextRange} substituteRange
-   * @return {?Promise.<!UI.SuggestBox.Suggestions>}
-   */
-  _cssSuggestions(prefixRange, substituteRange) {
-    const prefix = this._textEditor.text(prefixRange);
-    if (prefix.startsWith('$'))
-      return null;
-
-    const propertyToken = this._backtrackPropertyToken(prefixRange.startLine, prefixRange.startColumn - 1);
-    if (!propertyToken)
-      return null;
-
-    const line = this._textEditor.line(prefixRange.startLine);
-    const tokenContent = line.substring(propertyToken.startColumn, propertyToken.endColumn);
-    const propertyValues = SDK.cssMetadata().propertyValues(tokenContent);
-    return Promise.resolve(propertyValues.filter(value => value.startsWith(prefix)).map(value => ({text: value})));
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?{startColumn: number, endColumn: number, type: string}}
-   */
-  _backtrackPropertyToken(lineNumber, columnNumber) {
-    const backtrackDepth = 10;
-    let tokenPosition = columnNumber;
-    const line = this._textEditor.line(lineNumber);
-    let seenColon = false;
-
-    for (let i = 0; i < backtrackDepth && tokenPosition >= 0; ++i) {
-      const token = this._textEditor.tokenAtTextPosition(lineNumber, tokenPosition);
-      if (!token)
-        return null;
-      if (token.type === 'css-property')
-        return seenColon ? token : null;
-      if (token.type && !(token.type.indexOf('whitespace') !== -1 || token.type.startsWith('css-comment')))
-        return null;
-
-      if (!token.type && line.substring(token.startColumn, token.endColumn) === ':') {
-        if (!seenColon)
-          seenColon = true;
-        else
-          return null;
-      }
-      tokenPosition = token.startColumn - 1;
-    }
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  rightToolbarItems() {
-    return [];
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  leftToolbarItems() {
-    return [];
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    if (this._swatchPopoverHelper.isShowing())
-      this._swatchPopoverHelper.hide(true);
-    this._textEditor.removeEventListener(
-        SourceFrame.SourcesTextEditor.Events.ScrollChanged, this._textEditorScrolled, this);
-    this._textEditor.removeEventListener(UI.TextEditor.Events.TextChanged, this._onTextChanged, this);
-    this._textEditor.bookmarks(this._textEditor.fullRange(), Sources.CSSPlugin.SwatchBookmark)
-        .forEach(marker => marker.clear());
-    this._textEditor.element.removeEventListener('keydown', this._boundHandleKeyDown, false);
-  }
-};
-
-/** @type {number} */
-Sources.CSSPlugin.maxSwatchProcessingLength = 300;
-/** @type {symbol} */
-Sources.CSSPlugin.SwatchBookmark = Symbol('swatch');
diff --git a/front_end/sources/CallStackSidebarPane.js b/front_end/sources/CallStackSidebarPane.js
deleted file mode 100644
index 0f4a03f..0000000
--- a/front_end/sources/CallStackSidebarPane.js
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {UI.ContextFlavorListener}
- * @implements {UI.ListDelegate<!Sources.CallStackSidebarPane.Item>}
- * @unrestricted
- */
-Sources.CallStackSidebarPane = class extends UI.SimpleView {
-  constructor() {
-    super(Common.UIString('Call Stack'), true);
-    this.registerRequiredCSS('sources/callStackSidebarPane.css');
-
-    this._blackboxedMessageElement = this._createBlackboxedMessageElement();
-    this.contentElement.appendChild(this._blackboxedMessageElement);
-
-    this._notPausedMessageElement = this.contentElement.createChild('div', 'gray-info-message');
-    this._notPausedMessageElement.textContent = Common.UIString('Not paused');
-
-    /** @type {!UI.ListModel<!Sources.CallStackSidebarPane.Item>} */
-    this._items = new UI.ListModel();
-    /** @type {!UI.ListControl<!Sources.CallStackSidebarPane.Item>} */
-    this._list = new UI.ListControl(this._items, this, UI.ListMode.NonViewport);
-    this.contentElement.appendChild(this._list.element);
-    this._list.element.addEventListener('contextmenu', this._onContextMenu.bind(this), false);
-    this._list.element.addEventListener('click', this._onClick.bind(this), false);
-
-    this._showMoreMessageElement = this._createShowMoreMessageElement();
-    this._showMoreMessageElement.classList.add('hidden');
-    this.contentElement.appendChild(this._showMoreMessageElement);
-
-    this._showBlackboxed = false;
-    Bindings.blackboxManager.addChangeListener(this._update.bind(this));
-    this._locationPool = new Bindings.LiveLocationPool();
-
-    this._updateThrottler = new Common.Throttler(100);
-    this._maxAsyncStackChainDepth = Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth;
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {?Object} object
-   */
-  flavorChanged(object) {
-    this._showBlackboxed = false;
-    this._maxAsyncStackChainDepth = Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth;
-    this._update();
-  }
-
-  _update() {
-    this._updateThrottler.schedule(() => this._doUpdate());
-  }
-
-  /**
-   * @return {!Promise<undefined>}
-   */
-  async _doUpdate() {
-    this._locationPool.disposeAll();
-
-    const details = UI.context.flavor(SDK.DebuggerPausedDetails);
-    if (!details) {
-      this._notPausedMessageElement.classList.remove('hidden');
-      this._blackboxedMessageElement.classList.add('hidden');
-      this._showMoreMessageElement.classList.add('hidden');
-      this._items.replaceAll([]);
-      UI.context.setFlavor(SDK.DebuggerModel.CallFrame, null);
-      return;
-    }
-
-    let debuggerModel = details.debuggerModel;
-    this._notPausedMessageElement.classList.add('hidden');
-
-    const showBlackboxed = this._showBlackboxed ||
-        details.callFrames.every(frame => Bindings.blackboxManager.isBlackboxedRawLocation(frame.location()));
-
-    let hiddenCallFramesCount = 0;
-    let items = details.callFrames.map(frame => ({debuggerCallFrame: frame, debuggerModel: debuggerModel}));
-    if (!showBlackboxed) {
-      items = items.filter(
-          item => !Bindings.blackboxManager.isBlackboxedRawLocation(
-              /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
-      hiddenCallFramesCount += details.callFrames.length - items.length;
-    }
-
-    let asyncStackTrace = details.asyncStackTrace;
-    if (!asyncStackTrace && details.asyncStackTraceId) {
-      if (details.asyncStackTraceId.debuggerId)
-        debuggerModel = SDK.DebuggerModel.modelForDebuggerId(details.asyncStackTraceId.debuggerId);
-      asyncStackTrace = debuggerModel ? await debuggerModel.fetchAsyncStackTrace(details.asyncStackTraceId) : null;
-    }
-    let peviousStackTrace = details.callFrames;
-    let maxAsyncStackChainDepth = this._maxAsyncStackChainDepth;
-    while (asyncStackTrace && maxAsyncStackChainDepth > 0) {
-      let title = '';
-      const isAwait = asyncStackTrace.description === 'async function';
-      if (isAwait && peviousStackTrace.length && asyncStackTrace.callFrames.length) {
-        const lastPreviousFrame = peviousStackTrace[peviousStackTrace.length - 1];
-        const lastPreviousFrameName = UI.beautifyFunctionName(lastPreviousFrame.functionName);
-        title = UI.asyncStackTraceLabel('await in ' + lastPreviousFrameName);
-      } else {
-        title = UI.asyncStackTraceLabel(asyncStackTrace.description);
-      }
-
-      let asyncItems =
-          asyncStackTrace.callFrames.map(frame => ({runtimeCallFrame: frame, debuggerModel: debuggerModel}));
-      if (!showBlackboxed) {
-        asyncItems = asyncItems.filter(
-            item => !Bindings.blackboxManager.isBlackboxedRawLocation(
-                /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
-        hiddenCallFramesCount += asyncStackTrace.callFrames.length - asyncItems.length;
-      }
-
-      if (asyncItems.length) {
-        items.push({asyncStackHeader: title});
-        items = items.concat(asyncItems);
-      }
-
-      --maxAsyncStackChainDepth;
-      peviousStackTrace = asyncStackTrace.callFrames;
-      if (asyncStackTrace.parent) {
-        asyncStackTrace = asyncStackTrace.parent;
-      } else if (asyncStackTrace.parentId) {
-        if (asyncStackTrace.parentId.debuggerId)
-          debuggerModel = SDK.DebuggerModel.modelForDebuggerId(asyncStackTrace.parentId.debuggerId);
-        asyncStackTrace = debuggerModel ? await debuggerModel.fetchAsyncStackTrace(asyncStackTrace.parentId) : null;
-      } else {
-        asyncStackTrace = null;
-      }
-    }
-    if (asyncStackTrace)
-      this._showMoreMessageElement.classList.remove('hidden');
-    else
-      this._showMoreMessageElement.classList.add('hidden');
-
-    if (!hiddenCallFramesCount) {
-      this._blackboxedMessageElement.classList.add('hidden');
-    } else {
-      if (hiddenCallFramesCount === 1) {
-        this._blackboxedMessageElement.firstChild.textContent =
-            Common.UIString('1 stack frame is hidden (blackboxed).');
-      } else {
-        this._blackboxedMessageElement.firstChild.textContent =
-            Common.UIString('%d stack frames are hidden (blackboxed).', hiddenCallFramesCount);
-      }
-      this._blackboxedMessageElement.classList.remove('hidden');
-    }
-
-    this._items.replaceAll(items);
-    if (this._maxAsyncStackChainDepth === Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth)
-      this._list.selectNextItem(true /* canWrap */, false /* center */);
-    this._updatedForTest();
-  }
-
-  _updatedForTest() {
-  }
-
-  /**
-   * @override
-   * @param {!Sources.CallStackSidebarPane.Item} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    const element = createElementWithClass('div', 'call-frame-item');
-    const title = element.createChild('div', 'call-frame-item-title');
-    title.createChild('div', 'call-frame-title-text').textContent = this._itemTitle(item);
-    if (item.asyncStackHeader)
-      element.classList.add('async-header');
-
-    const location = this._itemLocation(item);
-    if (location) {
-      if (Bindings.blackboxManager.isBlackboxedRawLocation(location))
-        element.classList.add('blackboxed-call-frame');
-
-      /**
-       * @param {!Bindings.LiveLocation} liveLocation
-       */
-      function updateLocation(liveLocation) {
-        const uiLocation = liveLocation.uiLocation();
-        if (!uiLocation)
-          return;
-        const text = uiLocation.linkText();
-        linkElement.textContent = text.trimMiddle(30);
-        linkElement.title = text;
-      }
-
-      const linkElement = element.createChild('div', 'call-frame-location');
-      Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, updateLocation, this._locationPool);
-    }
-
-    element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-call-frame-icon'));
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {!Sources.CallStackSidebarPane.Item} item
-   * @return {number}
-   */
-  heightForItem(item) {
-    console.assert(false);  // Should not be called.
-    return 0;
-  }
-
-  /**
-   * @override
-   * @param {!Sources.CallStackSidebarPane.Item} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    return !!item.debuggerCallFrame;
-  }
-
-  /**
-   * @override
-   * @param {?Sources.CallStackSidebarPane.Item} from
-   * @param {?Sources.CallStackSidebarPane.Item} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('selected');
-    if (toElement)
-      toElement.classList.add('selected');
-    if (to)
-      this._activateItem(to);
-  }
-
-  /**
-   * @param {!Sources.CallStackSidebarPane.Item} item
-   * @return {string}
-   */
-  _itemTitle(item) {
-    if (item.debuggerCallFrame)
-      return UI.beautifyFunctionName(item.debuggerCallFrame.functionName);
-    if (item.runtimeCallFrame)
-      return UI.beautifyFunctionName(item.runtimeCallFrame.functionName);
-    return item.asyncStackHeader || '';
-  }
-
-  /**
-   * @param {!Sources.CallStackSidebarPane.Item} item
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  _itemLocation(item) {
-    if (item.debuggerCallFrame)
-      return item.debuggerCallFrame.location();
-    if (!item.debuggerModel)
-      return null;
-    if (item.runtimeCallFrame) {
-      const frame = item.runtimeCallFrame;
-      return new SDK.DebuggerModel.Location(item.debuggerModel, frame.scriptId, frame.lineNumber, frame.columnNumber);
-    }
-    return null;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _createBlackboxedMessageElement() {
-    const element = createElementWithClass('div', 'blackboxed-message');
-    element.createChild('span');
-    const showAllLink = element.createChild('span', 'link');
-    showAllLink.textContent = Common.UIString('Show');
-    showAllLink.addEventListener('click', () => {
-      this._showBlackboxed = true;
-      this._update();
-    }, false);
-    return element;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _createShowMoreMessageElement() {
-    const element = createElementWithClass('div', 'show-more-message');
-    element.createChild('span');
-    const showAllLink = element.createChild('span', 'link');
-    showAllLink.textContent = Common.UIString('Show more');
-    showAllLink.addEventListener('click', () => {
-      this._maxAsyncStackChainDepth += Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth;
-      this._update();
-    }, false);
-    return element;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onContextMenu(event) {
-    const item = this._list.itemForNode(/** @type {?Node} */ (event.target));
-    if (!item)
-      return;
-    const contextMenu = new UI.ContextMenu(event);
-    if (item.debuggerCallFrame)
-      contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => item.debuggerCallFrame.restart());
-    contextMenu.defaultSection().appendItem(Common.UIString('Copy stack trace'), this._copyStackTrace.bind(this));
-    const location = this._itemLocation(item);
-    const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null;
-    if (uiLocation)
-      this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCode);
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    const item = this._list.itemForNode(/** @type {?Node} */ (event.target));
-    if (item)
-      this._activateItem(item);
-  }
-
-  /**
-   * @param {!Sources.CallStackSidebarPane.Item} item
-   */
-  _activateItem(item) {
-    const location = this._itemLocation(item);
-    if (!location)
-      return;
-    if (item.debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== item.debuggerCallFrame) {
-      item.debuggerModel.setSelectedCallFrame(item.debuggerCallFrame);
-      UI.context.setFlavor(SDK.DebuggerModel.CallFrame, item.debuggerCallFrame);
-    } else {
-      Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location));
-    }
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-    if (binding)
-      uiSourceCode = binding.network;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem)
-      return;
-    const canBlackbox = Bindings.blackboxManager.canBlackboxUISourceCode(uiSourceCode);
-    const isBlackboxed = Bindings.blackboxManager.isBlackboxedUISourceCode(uiSourceCode);
-    const isContentScript = uiSourceCode.project().type() === Workspace.projectTypes.ContentScripts;
-
-    const manager = Bindings.blackboxManager;
-    if (canBlackbox) {
-      if (isBlackboxed) {
-        contextMenu.defaultSection().appendItem(
-            Common.UIString('Stop blackboxing'), manager.unblackboxUISourceCode.bind(manager, uiSourceCode));
-      } else {
-        contextMenu.defaultSection().appendItem(
-            Common.UIString('Blackbox script'), manager.blackboxUISourceCode.bind(manager, uiSourceCode));
-      }
-    }
-    if (isContentScript) {
-      if (isBlackboxed) {
-        contextMenu.defaultSection().appendItem(
-            Common.UIString('Stop blackboxing all content scripts'), manager.blackboxContentScripts.bind(manager));
-      } else {
-        contextMenu.defaultSection().appendItem(
-            Common.UIString('Blackbox all content scripts'), manager.unblackboxContentScripts.bind(manager));
-      }
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _selectNextCallFrameOnStack() {
-    return this._list.selectNextItem(false /* canWrap */, false /* center */);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _selectPreviousCallFrameOnStack() {
-    return this._list.selectPreviousItem(false /* canWrap */, false /* center */);
-  }
-
-  _copyStackTrace() {
-    const text = [];
-    for (const item of this._items) {
-      let itemText = this._itemTitle(item);
-      const location = this._itemLocation(item);
-      const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null;
-      if (uiLocation)
-        itemText += ' (' + uiLocation.linkText(true /* skipTrim */) + ')';
-      text.push(itemText);
-    }
-    InspectorFrontendHost.copyText(text.join('\n'));
-  }
-};
-
-Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth = 32;
-
-/**
- * @typedef {{
- *     debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined),
- *     asyncStackHeader: (string|undefined),
- *     runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined),
- *     debuggerModel: (!SDK.DebuggerModel|undefined)
- * }}
- */
-Sources.CallStackSidebarPane.Item;
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Sources.CallStackSidebarPane.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const callStackSidebarPane = self.runtime.sharedInstance(Sources.CallStackSidebarPane);
-    switch (actionId) {
-      case 'debugger.next-call-frame':
-        callStackSidebarPane._selectNextCallFrameOnStack();
-        return true;
-      case 'debugger.previous-call-frame':
-        callStackSidebarPane._selectPreviousCallFrameOnStack();
-        return true;
-    }
-    return false;
-  }
-};
diff --git a/front_end/sources/DebuggerPausedMessage.js b/front_end/sources/DebuggerPausedMessage.js
deleted file mode 100644
index 4ad256d..0000000
--- a/front_end/sources/DebuggerPausedMessage.js
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Sources.DebuggerPausedMessage = class {
-  constructor() {
-    this._element = createElementWithClass('div', 'paused-message flex-none');
-    const root = UI.createShadowRootWithCoreStyles(this._element, 'sources/debuggerPausedMessage.css');
-    this._contentElement = root.createChild('div');
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  /**
-   * @param {string} description
-   */
-  static _descriptionWithoutStack(description) {
-    const firstCallFrame = /^\s+at\s/m.exec(description);
-    return firstCallFrame ? description.substring(0, firstCallFrame.index - 1) :
-                            description.substring(0, description.lastIndexOf('\n'));
-  }
-
-  /**
-   * @param {!SDK.DebuggerPausedDetails} details
-   * @return {!Promise<!Element>}
-   */
-  static async _createDOMBreakpointHitMessage(details) {
-    const messageWrapper = createElement('span');
-    const domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerModel);
-    if (!details.auxData || !domDebuggerModel)
-      return messageWrapper;
-    const data = domDebuggerModel.resolveDOMBreakpointData(/** @type {!Object} */ (details.auxData));
-    if (!data)
-      return messageWrapper;
-
-    const mainElement = messageWrapper.createChild('div', 'status-main');
-    mainElement.appendChild(UI.Icon.create('smallicon-info', 'status-icon'));
-    mainElement.appendChild(createTextNode(
-        String.sprintf('Paused on %s', Sources.DebuggerPausedMessage.BreakpointTypeNouns.get(data.type))));
-
-    const subElement = messageWrapper.createChild('div', 'status-sub monospace');
-    const linkifiedNode = await Common.Linkifier.linkify(data.node);
-    subElement.appendChild(linkifiedNode);
-
-    if (data.targetNode) {
-      const targetNodeLink = await Common.Linkifier.linkify(data.targetNode);
-      let message;
-      if (data.insertion)
-        message = data.targetNode === data.node ? 'Child %s added' : 'Descendant %s added';
-      else
-        message = 'Descendant %s removed';
-      subElement.appendChild(createElement('br'));
-      subElement.appendChild(UI.formatLocalized(message, [targetNodeLink]));
-    }
-    return messageWrapper;
-  }
-
-  /**
-   * @param {?SDK.DebuggerPausedDetails} details
-   * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
-   * @param {!Bindings.BreakpointManager} breakpointManager
-   * @return {!Promise}
-   */
-  async render(details, debuggerWorkspaceBinding, breakpointManager) {
-    this._contentElement.removeChildren();
-    this._contentElement.hidden = !details;
-    if (!details)
-      return;
-
-    const status = this._contentElement.createChild('div', 'paused-status');
-
-    const errorLike = details.reason === SDK.DebuggerModel.BreakReason.Exception ||
-        details.reason === SDK.DebuggerModel.BreakReason.PromiseRejection ||
-        details.reason === SDK.DebuggerModel.BreakReason.Assert || details.reason === SDK.DebuggerModel.BreakReason.OOM;
-    let messageWrapper;
-    if (details.reason === SDK.DebuggerModel.BreakReason.DOM) {
-      messageWrapper = await Sources.DebuggerPausedMessage._createDOMBreakpointHitMessage(details);
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.EventListener) {
-      let eventNameForUI = '';
-      if (details.auxData) {
-        eventNameForUI =
-            SDK.domDebuggerManager.resolveEventListenerBreakpointTitle(/** @type {!Object} */ (details.auxData));
-      }
-      messageWrapper = buildWrapper(Common.UIString('Paused on event listener'), eventNameForUI);
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.XHR) {
-      messageWrapper = buildWrapper(Common.UIString('Paused on XHR or fetch'), details.auxData['url'] || '');
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.Exception) {
-      const description = details.auxData['description'] || details.auxData['value'] || '';
-      const descriptionWithoutStack = Sources.DebuggerPausedMessage._descriptionWithoutStack(description);
-      messageWrapper = buildWrapper(Common.UIString('Paused on exception'), descriptionWithoutStack, description);
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.PromiseRejection) {
-      const description = details.auxData['description'] || details.auxData['value'] || '';
-      const descriptionWithoutStack = Sources.DebuggerPausedMessage._descriptionWithoutStack(description);
-      messageWrapper =
-          buildWrapper(Common.UIString('Paused on promise rejection'), descriptionWithoutStack, description);
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.Assert) {
-      messageWrapper = buildWrapper(Common.UIString('Paused on assertion'));
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.DebugCommand) {
-      messageWrapper = buildWrapper(Common.UIString('Paused on debugged function'));
-    } else if (details.reason === SDK.DebuggerModel.BreakReason.OOM) {
-      messageWrapper = buildWrapper(Common.UIString('Paused before potential out-of-memory crash'));
-    } else if (details.callFrames.length) {
-      const uiLocation = debuggerWorkspaceBinding.rawLocationToUILocation(details.callFrames[0].location());
-      const breakpoint = uiLocation ?
-          breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber) :
-          null;
-      const defaultText = breakpoint ? Common.UIString('Paused on breakpoint') : Common.UIString('Debugger paused');
-      messageWrapper = buildWrapper(defaultText);
-    } else {
-      console.warn(
-          'ScriptsPanel paused, but callFrames.length is zero.');  // TODO remove this once we understand this case better
-    }
-
-    status.classList.toggle('error-reason', errorLike);
-    if (messageWrapper)
-      status.appendChild(messageWrapper);
-
-    /**
-     * @param  {string} mainText
-     * @param  {string=} subText
-     * @param  {string=} title
-     * @return {!Element}
-     */
-    function buildWrapper(mainText, subText, title) {
-      const messageWrapper = createElement('span');
-      const mainElement = messageWrapper.createChild('div', 'status-main');
-      const icon = UI.Icon.create(errorLike ? 'smallicon-error' : 'smallicon-info', 'status-icon');
-      mainElement.appendChild(icon);
-      mainElement.appendChild(createTextNode(mainText));
-      if (subText) {
-        const subElement = messageWrapper.createChild('div', 'status-sub monospace');
-        subElement.textContent = subText;
-        subElement.title = title || subText;
-      }
-      return messageWrapper;
-    }
-  }
-};
-
-Sources.DebuggerPausedMessage.BreakpointTypeNouns = new Map([
-  [SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified, Common.UIString('subtree modifications')],
-  [SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified, Common.UIString('attribute modifications')],
-  [SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved, Common.UIString('node removal')],
-]);
diff --git a/front_end/sources/EditingLocationHistoryManager.js b/front_end/sources/EditingLocationHistoryManager.js
deleted file mode 100644
index 7c282a3..0000000
--- a/front_end/sources/EditingLocationHistoryManager.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Sources.EditingLocationHistoryManager = class {
-  /**
-   * @param {!Sources.SourcesView} sourcesView
-   * @param {function():?Sources.UISourceCodeFrame} currentSourceFrameCallback
-   */
-  constructor(sourcesView, currentSourceFrameCallback) {
-    this._sourcesView = sourcesView;
-    this._historyManager = new Sources.SimpleHistoryManager(Sources.EditingLocationHistoryManager.HistoryDepth);
-    this._currentSourceFrameCallback = currentSourceFrameCallback;
-  }
-
-  /**
-   * @param {!Sources.UISourceCodeFrame} sourceFrame
-   */
-  trackSourceFrameCursorJumps(sourceFrame) {
-    sourceFrame.textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.JumpHappened, this._onJumpHappened.bind(this));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onJumpHappened(event) {
-    if (event.data.from)
-      this._updateActiveState(event.data.from);
-    if (event.data.to)
-      this._pushActiveState(event.data.to);
-  }
-
-  rollback() {
-    this._historyManager.rollback();
-  }
-
-  rollover() {
-    this._historyManager.rollover();
-  }
-
-  updateCurrentState() {
-    const sourceFrame = this._currentSourceFrameCallback();
-    if (!sourceFrame)
-      return;
-    this._updateActiveState(sourceFrame.textEditor.selection());
-  }
-
-  pushNewState() {
-    const sourceFrame = this._currentSourceFrameCallback();
-    if (!sourceFrame)
-      return;
-    this._pushActiveState(sourceFrame.textEditor.selection());
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} selection
-   */
-  _updateActiveState(selection) {
-    const active = this._historyManager.active();
-    if (!active)
-      return;
-    const sourceFrame = this._currentSourceFrameCallback();
-    if (!sourceFrame)
-      return;
-    const entry = new Sources.EditingLocationHistoryEntry(this._sourcesView, this, sourceFrame, selection);
-    active.merge(entry);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} selection
-   */
-  _pushActiveState(selection) {
-    const sourceFrame = this._currentSourceFrameCallback();
-    if (!sourceFrame)
-      return;
-    const entry = new Sources.EditingLocationHistoryEntry(this._sourcesView, this, sourceFrame, selection);
-    this._historyManager.push(entry);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  removeHistoryForSourceCode(uiSourceCode) {
-    function filterOut(entry) {
-      return entry._projectId === uiSourceCode.project().id() && entry._url === uiSourceCode.url();
-    }
-
-    this._historyManager.filterOut(filterOut);
-  }
-};
-
-Sources.EditingLocationHistoryManager.HistoryDepth = 20;
-
-/**
- * @implements {Sources.HistoryEntry}
- * @unrestricted
- */
-Sources.EditingLocationHistoryEntry = class {
-  /**
-   * @param {!Sources.SourcesView} sourcesView
-   * @param {!Sources.EditingLocationHistoryManager} editingLocationManager
-   * @param {!Sources.UISourceCodeFrame} sourceFrame
-   * @param {!TextUtils.TextRange} selection
-   */
-  constructor(sourcesView, editingLocationManager, sourceFrame, selection) {
-    this._sourcesView = sourcesView;
-    this._editingLocationManager = editingLocationManager;
-    const uiSourceCode = sourceFrame.uiSourceCode();
-    this._projectId = uiSourceCode.project().id();
-    this._url = uiSourceCode.url();
-
-    const position = this._positionFromSelection(selection);
-    this._positionHandle = sourceFrame.textEditor.textEditorPositionHandle(position.lineNumber, position.columnNumber);
-  }
-
-  /**
-   * @param {!Sources.HistoryEntry} entry
-   */
-  merge(entry) {
-    if (this._projectId !== entry._projectId || this._url !== entry._url)
-      return;
-    this._positionHandle = entry._positionHandle;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} selection
-   * @return {!{lineNumber: number, columnNumber: number}}
-   */
-  _positionFromSelection(selection) {
-    return {lineNumber: selection.endLine, columnNumber: selection.endColumn};
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  valid() {
-    const position = this._positionHandle.resolve();
-    const uiSourceCode = Workspace.workspace.uiSourceCode(this._projectId, this._url);
-    return !!(position && uiSourceCode);
-  }
-
-  /**
-   * @override
-   */
-  reveal() {
-    const position = this._positionHandle.resolve();
-    const uiSourceCode = Workspace.workspace.uiSourceCode(this._projectId, this._url);
-    if (!position || !uiSourceCode)
-      return;
-
-    this._editingLocationManager.updateCurrentState();
-    this._sourcesView.showSourceLocation(uiSourceCode, position.lineNumber, position.columnNumber);
-  }
-};
diff --git a/front_end/sources/FilePathScoreFunction.js b/front_end/sources/FilePathScoreFunction.js
deleted file mode 100644
index d9c3b8c..0000000
--- a/front_end/sources/FilePathScoreFunction.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Sources.FilePathScoreFunction = class {
-  /**
-   * @param {string} query
-   */
-  constructor(query) {
-    this._query = query;
-    this._queryUpperCase = query.toUpperCase();
-    this._score = new Int32Array(20 * 100);
-    this._sequence = new Int32Array(20 * 100);
-    this._dataUpperCase = '';
-    this._fileNameIndex = 0;
-  }
-
-  /**
-   * @param {string} data
-   * @param {?Array<number>} matchIndexes
-   * @return {number}
-   */
-  score(data, matchIndexes) {
-    if (!data || !this._query)
-      return 0;
-    const n = this._query.length;
-    const m = data.length;
-    if (!this._score || this._score.length < n * m) {
-      this._score = new Int32Array(n * m * 2);
-      this._sequence = new Int32Array(n * m * 2);
-    }
-    const score = this._score;
-    const sequence = /** @type {!Int32Array} */ (this._sequence);
-    this._dataUpperCase = data.toUpperCase();
-    this._fileNameIndex = data.lastIndexOf('/');
-    for (let i = 0; i < n; ++i) {
-      for (let j = 0; j < m; ++j) {
-        const skipCharScore = j === 0 ? 0 : score[i * m + j - 1];
-        const prevCharScore = i === 0 || j === 0 ? 0 : score[(i - 1) * m + j - 1];
-        const consecutiveMatch = i === 0 || j === 0 ? 0 : sequence[(i - 1) * m + j - 1];
-        const pickCharScore = this._match(this._query, data, i, j, consecutiveMatch);
-        if (pickCharScore && prevCharScore + pickCharScore >= skipCharScore) {
-          sequence[i * m + j] = consecutiveMatch + 1;
-          score[i * m + j] = (prevCharScore + pickCharScore);
-        } else {
-          sequence[i * m + j] = 0;
-          score[i * m + j] = skipCharScore;
-        }
-      }
-    }
-    if (matchIndexes)
-      this._restoreMatchIndexes(sequence, n, m, matchIndexes);
-    const maxDataLength = 256;
-    return score[n * m - 1] * maxDataLength + (maxDataLength - data.length);
-  }
-
-  /**
-   * @param {string} data
-   * @param {number} j
-   * @return {boolean}
-   */
-  _testWordStart(data, j) {
-    if (j === 0)
-      return true;
-
-    const prevChar = data.charAt(j - 1);
-    return prevChar === '_' || prevChar === '-' || prevChar === '/' ||
-        (data[j - 1] !== this._dataUpperCase[j - 1] && data[j] === this._dataUpperCase[j]);
-  }
-
-  /**
-   * @param {!Int32Array} sequence
-   * @param {number} n
-   * @param {number} m
-   * @param {!Array<number>} out
-   */
-  _restoreMatchIndexes(sequence, n, m, out) {
-    let i = n - 1, j = m - 1;
-    while (i >= 0 && j >= 0) {
-      switch (sequence[i * m + j]) {
-        case 0:
-          --j;
-          break;
-        default:
-          out.push(j);
-          --i;
-          --j;
-          break;
-      }
-    }
-    out.reverse();
-  }
-
-  /**
-   * @param {string} query
-   * @param {string} data
-   * @param {number} i
-   * @param {number} j
-   * @return {number}
-   */
-  _singleCharScore(query, data, i, j) {
-    const isWordStart = this._testWordStart(data, j);
-    const isFileName = j > this._fileNameIndex;
-    const isPathTokenStart = j === 0 || data[j - 1] === '/';
-    const isCapsMatch = query[i] === data[j] && query[i] === this._queryUpperCase[i];
-    let score = 10;
-    if (isPathTokenStart)
-      score += 4;
-    if (isWordStart)
-      score += 2;
-    if (isCapsMatch)
-      score += 6;
-    if (isFileName)
-      score += 4;
-    // promote the case of making the whole match in the filename
-    if (j === this._fileNameIndex + 1 && i === 0)
-      score += 5;
-    if (isFileName && isWordStart)
-      score += 3;
-    return score;
-  }
-
-  /**
-   * @param {string} query
-   * @param {string} data
-   * @param {number} i
-   * @param {number} j
-   * @param {number} sequenceLength
-   * @return {number}
-   */
-  _sequenceCharScore(query, data, i, j, sequenceLength) {
-    const isFileName = j > this._fileNameIndex;
-    const isPathTokenStart = j === 0 || data[j - 1] === '/';
-    let score = 10;
-    if (isFileName)
-      score += 4;
-    if (isPathTokenStart)
-      score += 5;
-    score += sequenceLength * 4;
-    return score;
-  }
-
-  /**
-   * @param {string} query
-   * @param {string} data
-   * @param {number} i
-   * @param {number} j
-   * @param {number} consecutiveMatch
-   * @return {number}
-   */
-  _match(query, data, i, j, consecutiveMatch) {
-    if (this._queryUpperCase[i] !== this._dataUpperCase[j])
-      return 0;
-
-    if (!consecutiveMatch)
-      return this._singleCharScore(query, data, i, j);
-    else
-      return this._sequenceCharScore(query, data, i, j - consecutiveMatch, consecutiveMatch);
-  }
-};
diff --git a/front_end/sources/FilteredUISourceCodeListProvider.js b/front_end/sources/FilteredUISourceCodeListProvider.js
deleted file mode 100644
index 0dfdcb3..0000000
--- a/front_end/sources/FilteredUISourceCodeListProvider.js
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * @unrestricted
- */
-Sources.FilteredUISourceCodeListProvider = class extends QuickOpen.FilteredListWidget.Provider {
-  constructor() {
-    super();
-
-    this._queryLineNumberAndColumnNumber = '';
-    this._defaultScores = null;
-    this._scorer = new Sources.FilePathScoreFunction('');
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _projectRemoved(event) {
-    const project = /** @type {!Workspace.Project} */ (event.data);
-    this._populate(project);
-    this.refresh();
-  }
-
-  /**
-   * @param {!Workspace.Project=} skipProject
-   */
-  _populate(skipProject) {
-    /** @type {!Array.<!Workspace.UISourceCode>} */
-    this._uiSourceCodes = [];
-    const projects = Workspace.workspace.projects().filter(this.filterProject.bind(this));
-    for (let i = 0; i < projects.length; ++i) {
-      if (skipProject && projects[i] === skipProject)
-        continue;
-      const uiSourceCodes = projects[i].uiSourceCodes().filter(this._filterUISourceCode.bind(this));
-      this._uiSourceCodes = this._uiSourceCodes.concat(uiSourceCodes);
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  _filterUISourceCode(uiSourceCode) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-    return !binding || binding.fileSystem === uiSourceCode;
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   * @param {number=} lineNumber
-   * @param {number=} columnNumber
-   */
-  uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber) {
-    // Overridden by subclasses
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  filterProject(project) {
-    return true;
-    // Overridden by subclasses
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemCount() {
-    return this._uiSourceCodes.length;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @return {string}
-   */
-  itemKeyAt(itemIndex) {
-    return this._uiSourceCodes[itemIndex].url();
-  }
-
-  /**
-   * @protected
-   * @param {?Map.<!Workspace.UISourceCode, number>} defaultScores
-   */
-  setDefaultScores(defaultScores) {
-    this._defaultScores = defaultScores;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @return {number}
-   */
-  itemScoreAt(itemIndex, query) {
-    const uiSourceCode = this._uiSourceCodes[itemIndex];
-    const score = this._defaultScores ? (this._defaultScores.get(uiSourceCode) || 0) : 0;
-    if (!query || query.length < 2)
-      return score;
-
-    if (this._query !== query) {
-      this._query = query;
-      this._scorer = new Sources.FilePathScoreFunction(query);
-    }
-
-    let multiplier = 10;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem &&
-        !Persistence.persistence.binding(uiSourceCode))
-      multiplier = 5;
-
-    const fullDisplayName = uiSourceCode.fullDisplayName();
-    return score + multiplier * this._scorer.score(fullDisplayName, null);
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @param {!Element} titleElement
-   * @param {!Element} subtitleElement
-   */
-  renderItem(itemIndex, query, titleElement, subtitleElement) {
-    query = this.rewriteQuery(query);
-    const uiSourceCode = this._uiSourceCodes[itemIndex];
-    const fullDisplayName = uiSourceCode.fullDisplayName();
-    const indexes = [];
-    new Sources.FilePathScoreFunction(query).score(fullDisplayName, indexes);
-    const fileNameIndex = fullDisplayName.lastIndexOf('/');
-
-    titleElement.classList.add('monospace');
-    subtitleElement.classList.add('monospace');
-    titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumberAndColumnNumber || '');
-    this._renderSubtitleElement(subtitleElement, fullDisplayName);
-    subtitleElement.title = fullDisplayName;
-    const ranges = [];
-    for (let i = 0; i < indexes.length; ++i)
-      ranges.push({offset: indexes[i], length: 1});
-
-    if (indexes[0] > fileNameIndex) {
-      for (let i = 0; i < ranges.length; ++i)
-        ranges[i].offset -= fileNameIndex + 1;
-      UI.highlightRangesWithStyleClass(titleElement, ranges, 'highlight');
-    } else {
-      UI.highlightRangesWithStyleClass(subtitleElement, ranges, 'highlight');
-    }
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} text
-   */
-  _renderSubtitleElement(element, text) {
-    element.removeChildren();
-    let splitPosition = text.lastIndexOf('/');
-    if (text.length > 55)
-      splitPosition = text.length - 55;
-    const first = element.createChild('div', 'first-part');
-    first.textContent = text.substring(0, splitPosition);
-    const second = element.createChild('div', 'second-part');
-    second.textContent = text.substring(splitPosition);
-    element.title = text;
-  }
-
-  /**
-   * @override
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-    const parsedExpression = promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);
-    if (!parsedExpression)
-      return;
-
-    let lineNumber;
-    let columnNumber;
-    if (parsedExpression[2])
-      lineNumber = parseInt(parsedExpression[2].substr(1), 10) - 1;
-    if (parsedExpression[3])
-      columnNumber = parseInt(parsedExpression[3].substr(1), 10) - 1;
-    const uiSourceCode = itemIndex !== null ? this._uiSourceCodes[itemIndex] : null;
-    this.uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber);
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @return {string}
-   */
-  rewriteQuery(query) {
-    query = query ? query.trim() : '';
-    if (!query || query === ':')
-      return '';
-    const lineNumberMatch = query.match(/^([^:]+)((?::[^:]*){0,2})$/);
-    this._queryLineNumberAndColumnNumber = lineNumberMatch ? lineNumberMatch[2] : '';
-    return lineNumberMatch ? lineNumberMatch[1] : query;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    if (!this._filterUISourceCode(uiSourceCode) || !this.filterProject(uiSourceCode.project()))
-      return;
-    this._uiSourceCodes.push(uiSourceCode);
-    this.refresh();
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  notFoundText() {
-    return Common.UIString('No files found');
-  }
-
-  /**
-   * @override
-   */
-  attach() {
-    Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
-    Workspace.workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
-    this._populate();
-  }
-
-  /**
-   * @override
-   */
-  detach() {
-    Workspace.workspace.removeEventListener(
-        Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
-    Workspace.workspace.removeEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
-    this._queryLineNumberAndColumnNumber = '';
-    this._defaultScores = null;
-  }
-};
diff --git a/front_end/sources/GoToLineQuickOpen.js b/front_end/sources/GoToLineQuickOpen.js
deleted file mode 100644
index d5a6986..0000000
--- a/front_end/sources/GoToLineQuickOpen.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Sources.GoToLineQuickOpen = class extends QuickOpen.FilteredListWidget.Provider {
-  /**
-   * @override
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-    const uiSourceCode = this._currentUISourceCode();
-    if (!uiSourceCode)
-      return;
-    const position = this._parsePosition(promptValue);
-    if (!position)
-      return;
-    Common.Revealer.reveal(uiSourceCode.uiLocation(position.line - 1, position.column - 1));
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @return {string}
-   */
-  notFoundText(query) {
-    if (!this._currentUISourceCode())
-      return Common.UIString('No file selected.');
-    const position = this._parsePosition(query);
-    if (!position)
-      return Common.UIString('Type a number to go to that line.');
-    let text = Common.UIString('Go to line ') + position.line;
-    if (position.column && position.column > 1)
-      text += Common.UIString(' and column ') + position.column;
-    text += '.';
-    return text;
-  }
-
-  /**
-   * @param {string} query
-   * @return {?{line: number, column: number}}
-   */
-  _parsePosition(query) {
-    const parts = query.match(/([0-9]+)(\:[0-9]*)?/);
-    if (!parts || !parts[0] || parts[0].length !== query.length)
-      return null;
-    const line = parseInt(parts[1], 10);
-    let column;
-    if (parts[2])
-      column = parseInt(parts[2].substring(1), 10);
-    return {line: Math.max(line | 0, 1), column: Math.max(column | 0, 1)};
-  }
-
-  /**
-   * @return {?Workspace.UISourceCode}
-   */
-  _currentUISourceCode() {
-    const sourcesView = UI.context.flavor(Sources.SourcesView);
-    if (!sourcesView)
-      return null;
-    return sourcesView.currentUISourceCode();
-  }
-};
diff --git a/front_end/sources/InplaceFormatterEditorAction.js b/front_end/sources/InplaceFormatterEditorAction.js
deleted file mode 100644
index aa3578f..0000000
--- a/front_end/sources/InplaceFormatterEditorAction.js
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Sources.SourcesView.EditorAction}
- * @unrestricted
- */
-Sources.InplaceFormatterEditorAction = class {
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorSelected(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._updateButton(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorClosed(event) {
-    const wasSelected = /** @type {boolean} */ (event.data.wasSelected);
-    if (wasSelected)
-      this._updateButton(null);
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   */
-  _updateButton(uiSourceCode) {
-    this._button.element.classList.toggle('hidden', !this._isFormattable(uiSourceCode));
-  }
-
-  /**
-   * @override
-   * @param {!Sources.SourcesView} sourcesView
-   * @return {!UI.ToolbarButton}
-   */
-  button(sourcesView) {
-    if (this._button)
-      return this._button;
-
-    this._sourcesView = sourcesView;
-    this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
-    this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
-
-    this._button = new UI.ToolbarButton(Common.UIString('Format'), 'largeicon-pretty-print');
-    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._formatSourceInPlace, this);
-    this._updateButton(sourcesView.currentUISourceCode());
-
-    return this._button;
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  _isFormattable(uiSourceCode) {
-    if (!uiSourceCode)
-      return false;
-    if (uiSourceCode.project().canSetFileContent())
-      return true;
-    if (Persistence.persistence.binding(uiSourceCode))
-      return true;
-    return uiSourceCode.contentType().isStyleSheet();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _formatSourceInPlace(event) {
-    const uiSourceCode = this._sourcesView.currentUISourceCode();
-    if (!this._isFormattable(uiSourceCode))
-      return;
-
-    if (uiSourceCode.isDirty())
-      contentLoaded.call(this, uiSourceCode.workingCopy());
-    else
-      uiSourceCode.requestContent().then(contentLoaded.bind(this));
-
-    /**
-     * @this {Sources.InplaceFormatterEditorAction}
-     * @param {?string} content
-     */
-    function contentLoaded(content) {
-      const highlighterType = uiSourceCode.mimeType();
-      Formatter.Formatter.format(uiSourceCode.contentType(), highlighterType, content || '', innerCallback.bind(this));
-    }
-
-    /**
-     * @this {Sources.InplaceFormatterEditorAction}
-     * @param {string} formattedContent
-     * @param {!Formatter.FormatterSourceMapping} formatterMapping
-     */
-    function innerCallback(formattedContent, formatterMapping) {
-      if (uiSourceCode.workingCopy() === formattedContent)
-        return;
-      const sourceFrame = this._sourcesView.viewForFile(uiSourceCode);
-      let start = [0, 0];
-      if (sourceFrame) {
-        const selection = sourceFrame.selection();
-        start = formatterMapping.originalToFormatted(selection.startLine, selection.startColumn);
-      }
-      uiSourceCode.setWorkingCopy(formattedContent);
-
-      this._sourcesView.showSourceLocation(uiSourceCode, start[0], start[1]);
-    }
-  }
-};
diff --git a/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/front_end/sources/JavaScriptBreakpointsSidebarPane.js
deleted file mode 100644
index 7d7f1e1..0000000
--- a/front_end/sources/JavaScriptBreakpointsSidebarPane.js
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.ContextFlavorListener}
- * @unrestricted
- */
-Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('sources/javaScriptBreakpointsSidebarPane.css');
-
-    this._breakpointManager = Bindings.breakpointManager;
-    this._breakpointManager.addEventListener(Bindings.BreakpointManager.Events.BreakpointAdded, this.update, this);
-    this._breakpointManager.addEventListener(Bindings.BreakpointManager.Events.BreakpointRemoved, this.update, this);
-    Common.moduleSetting('breakpointsActive').addChangeListener(this.update, this);
-
-    /** @type {?Element} */
-    this._listElement = null;
-    this.update();
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?>}
-   */
-  doUpdate() {
-    const breakpointLocations = this._breakpointManager.allBreakpointLocations();
-    if (!breakpointLocations.length) {
-      this._listElement = null;
-      this.contentElement.removeChildren();
-      const emptyElement = this.contentElement.createChild('div', 'gray-info-message');
-      emptyElement.textContent = Common.UIString('No breakpoints');
-      this.contentElement.appendChild(emptyElement);
-      this._didUpdateForTest();
-      return Promise.resolve();
-    }
-
-    if (!this._listElement) {
-      this.contentElement.removeChildren();
-      this._listElement = this.contentElement.createChild('div');
-      this.contentElement.appendChild(this._listElement);
-    }
-
-    breakpointLocations.sort((item1, item2) => item1.uiLocation.compareTo(item2.uiLocation));
-
-    /** @type {!Multimap<string, !{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} */
-    const locationForEntry = new Multimap();
-    for (const breakpointLocation of breakpointLocations) {
-      const uiLocation = breakpointLocation.uiLocation;
-      const entryDescriptor = uiLocation.uiSourceCode.url() + ':' + uiLocation.lineNumber;
-      locationForEntry.set(entryDescriptor, breakpointLocation);
-    }
-
-    const details = UI.context.flavor(SDK.DebuggerPausedDetails);
-    const selectedUILocation = details && details.callFrames.length ?
-        Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(details.callFrames[0].location()) :
-        null;
-
-    let shouldShowView = false;
-    let entry = this._listElement.firstChild;
-    const promises = [];
-    for (const descriptor of locationForEntry.keysArray()) {
-      if (!entry) {
-        entry = this._listElement.createChild('div', 'breakpoint-entry');
-        entry.addEventListener('contextmenu', this._breakpointContextMenu.bind(this), true);
-        entry.addEventListener('click', this._revealLocation.bind(this), false);
-        const checkboxLabel = UI.CheckboxLabel.create('');
-        checkboxLabel.addEventListener('click', this._breakpointCheckboxClicked.bind(this), false);
-        entry.appendChild(checkboxLabel);
-        entry[Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol] = checkboxLabel;
-        const snippetElement = entry.createChild('div', 'source-text monospace');
-        entry[Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol] = snippetElement;
-      }
-
-      const locations = Array.from(locationForEntry.get(descriptor));
-      const uiLocation = locations[0].uiLocation;
-      const isSelected =
-          !!selectedUILocation && locations.some(location => location.uiLocation.id() === selectedUILocation.id());
-      const hasEnabled = locations.some(location => location.breakpoint.enabled());
-      const hasDisabled = locations.some(location => !location.breakpoint.enabled());
-      promises.push(this._resetEntry(/** @type {!Element}*/ (entry), uiLocation, isSelected, hasEnabled, hasDisabled));
-
-      if (isSelected)
-        shouldShowView = true;
-      entry = entry.nextSibling;
-    }
-    while (entry) {
-      const next = entry.nextSibling;
-      entry.remove();
-      entry = next;
-    }
-    if (shouldShowView)
-      UI.viewManager.showView('sources.jsBreakpoints');
-    this._listElement.classList.toggle(
-        'breakpoints-list-deactivated', !Common.moduleSetting('breakpointsActive').get());
-    Promise.all(promises).then(() => this._didUpdateForTest());
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {!Workspace.UILocation} uiLocation
-   * @param {boolean} isSelected
-   * @param {boolean} hasEnabled
-   * @param {boolean} hasDisabled
-   * @return {!Promise<undefined>}
-   */
-  _resetEntry(element, uiLocation, isSelected, hasEnabled, hasDisabled) {
-    element[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] = uiLocation;
-    element.classList.toggle('breakpoint-hit', isSelected);
-
-    const checkboxLabel = element[Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol];
-    checkboxLabel.textElement.textContent = uiLocation.linkText();
-    checkboxLabel.checkboxElement.checked = hasEnabled;
-    checkboxLabel.checkboxElement.indeterminate = hasEnabled && hasDisabled;
-
-    const snippetElement = element[Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol];
-    return uiLocation.uiSourceCode.requestContent().then(fillSnippetElement.bind(null, snippetElement));
-
-    /**
-     * @param {!Element} snippetElement
-     * @param {?string} content
-     */
-    function fillSnippetElement(snippetElement, content) {
-      const lineNumber = uiLocation.lineNumber;
-      const text = new TextUtils.Text(content || '');
-      if (lineNumber < text.lineCount()) {
-        const lineText = text.lineAt(lineNumber);
-        const maxSnippetLength = 200;
-        snippetElement.textContent = lineText.trimEnd(maxSnippetLength);
-      }
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?Workspace.UILocation}
-   */
-  _uiLocationFromEvent(event) {
-    const node = event.target.enclosingNodeOrSelfWithClass('breakpoint-entry');
-    if (!node)
-      return null;
-    return node[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] || null;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _breakpointCheckboxClicked(event) {
-    const uiLocation = this._uiLocationFromEvent(event);
-    if (!uiLocation)
-      return;
-
-    const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber);
-    const newState = event.target.checkboxElement.checked;
-    for (const breakpoint of breakpoints)
-      breakpoint.setEnabled(newState);
-    event.consume();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _revealLocation(event) {
-    const uiLocation = this._uiLocationFromEvent(event);
-    if (uiLocation)
-      Common.Revealer.reveal(uiLocation);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _breakpointContextMenu(event) {
-    const uiLocation = this._uiLocationFromEvent(event);
-    if (!uiLocation)
-      return;
-
-    const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber);
-
-    const contextMenu = new UI.ContextMenu(event);
-    const removeEntryTitle = breakpoints.length > 1 ? Common.UIString('Remove all breakpoints in line') :
-                                                      Common.UIString('Remove breakpoint');
-    contextMenu.defaultSection().appendItem(
-        removeEntryTitle, () => breakpoints.map(breakpoint => breakpoint.remove(false /* keepInStorage */)));
-
-    const breakpointActive = Common.moduleSetting('breakpointsActive').get();
-    const breakpointActiveTitle =
-        breakpointActive ? Common.UIString('Deactivate breakpoints') : Common.UIString('Activate breakpoints');
-    contextMenu.defaultSection().appendItem(
-        breakpointActiveTitle, () => Common.moduleSetting('breakpointsActive').set(!breakpointActive));
-
-    if (breakpoints.some(breakpoint => !breakpoint.enabled())) {
-      const enableTitle = Common.UIString('Enable all breakpoints');
-      contextMenu.defaultSection().appendItem(
-          enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true));
-    }
-    if (breakpoints.some(breakpoint => breakpoint.enabled())) {
-      const disableTitle = Common.UIString('Disable all breakpoints');
-      contextMenu.defaultSection().appendItem(
-          disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false));
-    }
-    const removeAllTitle = Common.UIString('Remove all breakpoints');
-    contextMenu.defaultSection().appendItem(
-        removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager));
-    const removeOtherTitle = Common.UIString('Remove other breakpoints');
-    contextMenu.defaultSection().appendItem(
-        removeOtherTitle,
-        this._breakpointManager.removeOtherBreakpoints.bind(this._breakpointManager, new Set(breakpoints)));
-    contextMenu.show();
-  }
-
-  /**
-   * @override
-   * @param {?Object} object
-   */
-  flavorChanged(object) {
-    this.update();
-  }
-
-  _didUpdateForTest() {
-  }
-};
-
-Sources.JavaScriptBreakpointsSidebarPane._locationSymbol = Symbol('location');
-Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol = Symbol('checkbox-label');
-Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol = Symbol('snippet-element');
diff --git a/front_end/sources/JavaScriptCompilerPlugin.js b/front_end/sources/JavaScriptCompilerPlugin.js
deleted file mode 100644
index 60c8beb..0000000
--- a/front_end/sources/JavaScriptCompilerPlugin.js
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Sources.UISourceCodeFrame.Plugin}
- */
-Sources.JavaScriptCompilerPlugin = class {
-  /**
-   * @param {!SourceFrame.SourcesTextEditor} textEditor
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  constructor(textEditor, uiSourceCode) {
-    this._textEditor = textEditor;
-    this._uiSourceCode = uiSourceCode;
-    this._compiling = false;
-    this._recompileScheduled = false;
-    /** @type {?number} */
-    this._timeout = null;
-    /** @type {?Workspace.UISourceCode.Message} */
-    this._message = null;
-    this._disposed = false;
-
-    this._textEditor.addEventListener(UI.TextEditor.Events.TextChanged, this._scheduleCompile, this);
-    if (this._uiSourceCode.hasCommits() || this._uiSourceCode.isDirty())
-      this._scheduleCompile();
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  static accepts(uiSourceCode) {
-    if (uiSourceCode.extension() === 'js')
-      return true;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.Snippets)
-      return true;
-    for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) {
-      if (Bindings.debuggerWorkspaceBinding.scriptFile(uiSourceCode, debuggerModel))
-        return true;
-    }
-    return false;
-  }
-
-  _scheduleCompile() {
-    if (this._compiling) {
-      this._recompileScheduled = true;
-      return;
-    }
-    if (this._timeout)
-      clearTimeout(this._timeout);
-    this._timeout = setTimeout(this._compile.bind(this), Sources.JavaScriptCompilerPlugin.CompileDelay);
-  }
-
-  /**
-   * @return {?SDK.RuntimeModel}
-   */
-  _findRuntimeModel() {
-    // TODO(dgozman): grab correct runtime model from JavaScriptSourceFrame instead.
-    const debuggerModels = SDK.targetManager.models(SDK.DebuggerModel);
-    for (let i = 0; i < debuggerModels.length; ++i) {
-      const scriptFile = Bindings.debuggerWorkspaceBinding.scriptFile(this._uiSourceCode, debuggerModels[i]);
-      if (scriptFile)
-        return debuggerModels[i].runtimeModel();
-    }
-    return SDK.targetManager.mainTarget() ? SDK.targetManager.mainTarget().model(SDK.RuntimeModel) : null;
-  }
-
-  async _compile() {
-    const runtimeModel = this._findRuntimeModel();
-    if (!runtimeModel)
-      return;
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!currentExecutionContext)
-      return;
-
-    const code = this._textEditor.text();
-    if (code.length > 1024 * 100)
-      return;
-
-    this._compiling = true;
-    const result = await runtimeModel.compileScript(code, '', false, currentExecutionContext.id);
-
-    this._compiling = false;
-    if (this._recompileScheduled) {
-      this._recompileScheduled = false;
-      this._scheduleCompile();
-      return;
-    }
-    if (this._message)
-      this._uiSourceCode.removeMessage(this._message);
-    if (this._disposed || !result || !result.exceptionDetails)
-      return;
-
-    const exceptionDetails = result.exceptionDetails;
-    const text = SDK.RuntimeModel.simpleTextFromException(exceptionDetails);
-    this._message = this._uiSourceCode.addLineMessage(
-        Workspace.UISourceCode.Message.Level.Error, text, exceptionDetails.lineNumber, exceptionDetails.columnNumber);
-    this._compilationFinishedForTest();
-  }
-
-  _compilationFinishedForTest() {
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  rightToolbarItems() {
-    return [];
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  leftToolbarItems() {
-    return [];
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this._textEditor.removeEventListener(UI.TextEditor.Events.TextChanged, this._scheduleCompile, this);
-    if (this._message)
-      this._uiSourceCode.removeMessage(this._message);
-    this._disposed = true;
-    if (this._timeout)
-      clearTimeout(this._timeout);
-  }
-};
-
-Sources.JavaScriptCompilerPlugin.CompileDelay = 1000;
diff --git a/front_end/sources/JavaScriptSourceFrame.js b/front_end/sources/JavaScriptSourceFrame.js
deleted file mode 100644
index 3da17f0..0000000
--- a/front_end/sources/JavaScriptSourceFrame.js
+++ /dev/null
@@ -1,1664 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Sources.JavaScriptSourceFrame = class extends Sources.UISourceCodeFrame {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  constructor(uiSourceCode) {
-    super(uiSourceCode);
-    this._debuggerSourceCode = uiSourceCode;
-
-    this._scriptsPanel = Sources.SourcesPanel.instance();
-    this._breakpointManager = Bindings.breakpointManager;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.Debugger)
-      this.element.classList.add('source-frame-debugger-script');
-
-    this._popoverHelper = new UI.PopoverHelper(this._scriptsPanel.element, this._getPopoverRequest.bind(this));
-    this._popoverHelper.setDisableOnClick(true);
-    this._popoverHelper.setTimeout(250, 250);
-    this._popoverHelper.setHasPadding(true);
-    this._scriptsPanel.element.addEventListener(
-        'scroll', this._popoverHelper.hidePopover.bind(this._popoverHelper), true);
-
-    this.textEditor.element.addEventListener('keydown', this._onKeyDown.bind(this), true);
-    this.textEditor.element.addEventListener('keyup', this._onKeyUp.bind(this), true);
-    this.textEditor.element.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    this.textEditor.element.addEventListener('mousedown', this._onMouseDown.bind(this), true);
-    this.textEditor.element.addEventListener('focusout', this._onBlur.bind(this), false);
-    this.textEditor.element.addEventListener('wheel', event => {
-      if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event))
-        event.preventDefault();
-    }, true);
-
-    this.textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.GutterClick, this._handleGutterClick.bind(this), this);
-
-    this._breakpointManager.addEventListener(
-        Bindings.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
-    this._breakpointManager.addEventListener(
-        Bindings.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
-
-    this.uiSourceCode().addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
-    this.uiSourceCode().addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-    this.uiSourceCode().addEventListener(
-        Workspace.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfNeeded, this);
-
-    /** @type {!Set<!Sources.JavaScriptSourceFrame.BreakpointDecoration>} */
-    this._breakpointDecorations = new Set();
-    /** @type {!Map<!Bindings.BreakpointManager.Breakpoint, !Sources.JavaScriptSourceFrame.BreakpointDecoration>} */
-    this._decorationByBreakpoint = new Map();
-    /** @type {!Set<number>} */
-    this._possibleBreakpointsRequested = new Set();
-
-    /** @type {!Map.<!SDK.DebuggerModel, !Bindings.ResourceScriptFile>}*/
-    this._scriptFileForDebuggerModel = new Map();
-
-    Common.moduleSetting('skipStackFramesPattern').addChangeListener(this._showBlackboxInfobarIfNeeded, this);
-    Common.moduleSetting('skipContentScripts').addChangeListener(this._showBlackboxInfobarIfNeeded, this);
-
-    /** @type {!Map.<number, !Element>} */
-    this._valueWidgets = new Map();
-    this.onBindingChanged();
-    /** @type {?Map<!Object, !Function>} */
-    this._continueToLocationDecorations = null;
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    const result = super.syncToolbarItems();
-    const originURL = Bindings.CompilerScriptMapping.uiSourceCodeOrigin(this._debuggerSourceCode);
-    if (originURL) {
-      const parsedURL = originURL.asParsedURL();
-      if (parsedURL)
-        result.push(new UI.ToolbarText(Common.UIString('(source mapped from %s)', parsedURL.displayName)));
-    }
-
-    return result;
-  }
-
-  _showBlackboxInfobarIfNeeded() {
-    const uiSourceCode = this._debuggerSourceCode;
-    if (!uiSourceCode.contentType().hasScripts())
-      return;
-    const projectType = uiSourceCode.project().type();
-    if (!Bindings.blackboxManager.isBlackboxedUISourceCode(uiSourceCode)) {
-      this._hideBlackboxInfobar();
-      return;
-    }
-
-    if (this._blackboxInfobar)
-      this._blackboxInfobar.dispose();
-
-    const infobar = new UI.Infobar(UI.Infobar.Type.Warning, Common.UIString('This script is blackboxed in debugger'));
-    this._blackboxInfobar = infobar;
-
-    infobar.createDetailsRowMessage(
-        Common.UIString('Debugger will skip stepping through this script, and will not stop on exceptions'));
-
-    const scriptFile = this._scriptFileForDebuggerModel.size ? this._scriptFileForDebuggerModel.valuesArray()[0] : null;
-    if (scriptFile && scriptFile.hasSourceMapURL())
-      infobar.createDetailsRowMessage(Common.UIString('Source map found, but ignored for blackboxed file.'));
-    infobar.createDetailsRowMessage();
-    infobar.createDetailsRowMessage(Common.UIString('Possible ways to cancel this behavior are:'));
-
-    infobar.createDetailsRowMessage(' - ').createTextChild(
-        Common.UIString('Go to "%s" tab in settings', Common.UIString('Blackboxing')));
-    const unblackboxLink = infobar.createDetailsRowMessage(' - ').createChild('span', 'link');
-    unblackboxLink.textContent = Common.UIString('Unblackbox this script');
-    unblackboxLink.addEventListener('click', unblackbox, false);
-
-    function unblackbox() {
-      Bindings.blackboxManager.unblackboxUISourceCode(uiSourceCode);
-      if (projectType === Workspace.projectTypes.ContentScripts)
-        Bindings.blackboxManager.unblackboxContentScripts();
-    }
-
-    this.attachInfobars([this._blackboxInfobar]);
-  }
-
-  _hideBlackboxInfobar() {
-    if (!this._blackboxInfobar)
-      return;
-    this._blackboxInfobar.dispose();
-    delete this._blackboxInfobar;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    if (this._executionLocation && this.loaded) {
-      // We need SourcesTextEditor to be initialized prior to this call. @see crbug.com/499889
-      setImmediate(() => {
-        this._generateValuesInSource();
-      });
-    }
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-    this._popoverHelper.hidePopover();
-  }
-
-  /**
-   * @override
-   */
-  onTextChanged(oldRange, newRange) {
-    this._scriptsPanel.updateLastModificationTime();
-    super.onTextChanged(oldRange, newRange);
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  populateLineGutterContextMenu(contextMenu, lineNumber) {
-    /**
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function populate(resolve, reject) {
-      const uiLocation = new Workspace.UILocation(this._debuggerSourceCode, lineNumber, 0);
-      this._scriptsPanel.appendUILocationItems(contextMenu, uiLocation);
-      const breakpoints = this._lineBreakpointDecorations(lineNumber)
-                              .map(decoration => decoration.breakpoint)
-                              .filter(breakpoint => !!breakpoint);
-      if (!breakpoints.length) {
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Add breakpoint'), this._createNewBreakpoint.bind(this, lineNumber, '', true));
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Add conditional breakpoint\u2026'),
-            this._editBreakpointCondition.bind(this, lineNumber, null, null));
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Never pause here'), this._createNewBreakpoint.bind(this, lineNumber, 'false', true));
-      } else {
-        const hasOneBreakpoint = breakpoints.length === 1;
-        const removeTitle =
-            hasOneBreakpoint ? Common.UIString('Remove breakpoint') : Common.UIString('Remove all breakpoints in line');
-        contextMenu.debugSection().appendItem(removeTitle, () => breakpoints.map(breakpoint => breakpoint.remove()));
-        if (hasOneBreakpoint) {
-          contextMenu.debugSection().appendItem(
-              Common.UIString('Edit breakpoint\u2026'),
-              this._editBreakpointCondition.bind(this, lineNumber, breakpoints[0], null));
-        }
-        const hasEnabled = breakpoints.some(breakpoint => breakpoint.enabled());
-        if (hasEnabled) {
-          const title = hasOneBreakpoint ? Common.UIString('Disable breakpoint') :
-                                           Common.UIString('Disable all breakpoints in line');
-          contextMenu.debugSection().appendItem(
-              title, () => breakpoints.map(breakpoint => breakpoint.setEnabled(false)));
-        }
-        const hasDisabled = breakpoints.some(breakpoint => !breakpoint.enabled());
-        if (hasDisabled) {
-          const title = hasOneBreakpoint ? Common.UIString('Enable breakpoint') :
-                                           Common.UIString('Enabled all breakpoints in line');
-          contextMenu.debugSection().appendItem(
-              title, () => breakpoints.map(breakpoint => breakpoint.setEnabled(true)));
-        }
-      }
-      resolve();
-    }
-    return new Promise(populate.bind(this));
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {
-    /**
-     * @param {!Bindings.ResourceScriptFile} scriptFile
-     */
-    function addSourceMapURL(scriptFile) {
-      Sources.AddSourceMapURLDialog.show(addSourceMapURLDialogCallback.bind(null, scriptFile));
-    }
-
-    /**
-     * @param {!Bindings.ResourceScriptFile} scriptFile
-     * @param {string} url
-     */
-    function addSourceMapURLDialogCallback(scriptFile, url) {
-      if (!url)
-        return;
-      scriptFile.addSourceMapURL(url);
-    }
-
-    /**
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function populateSourceMapMembers() {
-      if (this._debuggerSourceCode.project().type() === Workspace.projectTypes.Network &&
-          Common.moduleSetting('jsSourceMapsEnabled').get() &&
-          !Bindings.blackboxManager.isBlackboxedUISourceCode(this._debuggerSourceCode)) {
-        if (this._scriptFileForDebuggerModel.size) {
-          const scriptFile = this._scriptFileForDebuggerModel.valuesArray()[0];
-          const addSourceMapURLLabel = Common.UIString('Add source map\u2026');
-          contextMenu.debugSection().appendItem(addSourceMapURLLabel, addSourceMapURL.bind(null, scriptFile));
-        }
-      }
-    }
-
-    return super.populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber)
-        .then(populateSourceMapMembers.bind(this));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyChanged(event) {
-    if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForDebuggerModel.size)
-      return;
-
-    if (this.uiSourceCode().isDirty())
-      this._muteBreakpointsWhileEditing();
-    else
-      this._restoreBreakpointsAfterEditing();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _workingCopyCommitted(event) {
-    this._scriptsPanel.updateLastModificationTime();
-    if (this._supportsEnabledBreakpointsWhileEditing())
-      return;
-
-    if (!this._scriptFileForDebuggerModel.size)
-      this._restoreBreakpointsAfterEditing();
-  }
-
-  _didMergeToVM() {
-    if (this._supportsEnabledBreakpointsWhileEditing())
-      return;
-    this._restoreBreakpointsIfConsistentScripts();
-  }
-
-  _didDivergeFromVM() {
-    if (this._supportsEnabledBreakpointsWhileEditing())
-      return;
-    this._muteBreakpointsWhileEditing();
-  }
-
-  _muteBreakpointsWhileEditing() {
-    if (this._muted)
-      return;
-    for (const decoration of this._breakpointDecorations)
-      this._updateBreakpointDecoration(decoration);
-    this._muted = true;
-  }
-
-  _supportsEnabledBreakpointsWhileEditing() {
-    return this.uiSourceCode().project().type() === Workspace.projectTypes.Snippets;
-  }
-
-  _restoreBreakpointsIfConsistentScripts() {
-    const scriptFiles = this._scriptFileForDebuggerModel.valuesArray();
-    for (let i = 0; i < scriptFiles.length; ++i) {
-      if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM())
-        return;
-    }
-
-    this._restoreBreakpointsAfterEditing();
-  }
-
-  _restoreBreakpointsAfterEditing() {
-    delete this._muted;
-    const decorations = Array.from(this._breakpointDecorations);
-    this._breakpointDecorations.clear();
-    this.textEditor.operation(() => decorations.map(decoration => decoration.hide()));
-    for (const decoration of decorations) {
-      if (!decoration.breakpoint)
-        continue;
-      const enabled = decoration.enabled;
-      decoration.breakpoint.remove();
-      const location = decoration.handle.resolve();
-      if (location)
-        this._setBreakpoint(location.lineNumber, location.columnNumber, decoration.condition, enabled);
-    }
-  }
-
-  /**
-   * @param {string}  tokenType
-   * @return {boolean}
-   */
-  _isIdentifier(tokenType) {
-    return tokenType.startsWith('js-variable') || tokenType.startsWith('js-property') || tokenType === 'js-def';
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getPopoverRequest(event) {
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event))
-      return null;
-    const target = UI.context.flavor(SDK.Target);
-    const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
-    if (!debuggerModel || !debuggerModel.isPaused())
-      return null;
-
-    const textPosition = this.textEditor.coordinatesToCursorPosition(event.x, event.y);
-    if (!textPosition)
-      return null;
-
-    const mouseLine = textPosition.startLine;
-    const mouseColumn = textPosition.startColumn;
-    const textSelection = this.textEditor.selection().normalize();
-    let anchorBox;
-    let lineNumber;
-    let startHighlight;
-    let endHighlight;
-
-    if (textSelection && !textSelection.isEmpty()) {
-      if (textSelection.startLine !== textSelection.endLine || textSelection.startLine !== mouseLine ||
-          mouseColumn < textSelection.startColumn || mouseColumn > textSelection.endColumn)
-        return null;
-
-      const leftCorner =
-          this.textEditor.cursorPositionToCoordinates(textSelection.startLine, textSelection.startColumn);
-      const rightCorner = this.textEditor.cursorPositionToCoordinates(textSelection.endLine, textSelection.endColumn);
-      anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - leftCorner.x, leftCorner.height);
-      lineNumber = textSelection.startLine;
-      startHighlight = textSelection.startColumn;
-      endHighlight = textSelection.endColumn - 1;
-    } else {
-      const token = this.textEditor.tokenAtTextPosition(textPosition.startLine, textPosition.startColumn);
-      if (!token || !token.type)
-        return null;
-      lineNumber = textPosition.startLine;
-      const line = this.textEditor.line(lineNumber);
-      const tokenContent = line.substring(token.startColumn, token.endColumn);
-
-      const isIdentifier = this._isIdentifier(token.type);
-      if (!isIdentifier && (token.type !== 'js-keyword' || tokenContent !== 'this'))
-        return null;
-
-      const leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.startColumn);
-      const rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.endColumn - 1);
-      anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - leftCorner.x, leftCorner.height);
-
-      startHighlight = token.startColumn;
-      endHighlight = token.endColumn - 1;
-      while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.') {
-        const tokenBefore = this.textEditor.tokenAtTextPosition(lineNumber, startHighlight - 2);
-        if (!tokenBefore || !tokenBefore.type)
-          return null;
-        startHighlight = tokenBefore.startColumn;
-      }
-    }
-
-    let objectPopoverHelper;
-    let highlightDescriptor;
-
-    return {
-      box: anchorBox,
-      show: async popover => {
-        const selectedCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-        if (!selectedCallFrame)
-          return false;
-        const evaluationText = this.textEditor.line(lineNumber).substring(startHighlight, endHighlight + 1);
-        const resolvedText = await Sources.SourceMapNamesResolver.resolveExpression(
-            /** @type {!SDK.DebuggerModel.CallFrame} */ (selectedCallFrame), evaluationText, this._debuggerSourceCode,
-            lineNumber, startHighlight, endHighlight);
-        const result = await selectedCallFrame.evaluate({
-          expression: resolvedText || evaluationText,
-          objectGroup: 'popover',
-          includeCommandLineAPI: false,
-          silent: true,
-          returnByValue: false,
-          generatePreview: false
-        });
-        if (!result.object)
-          return false;
-        objectPopoverHelper = await ObjectUI.ObjectPopoverHelper.buildObjectPopover(result.object, popover);
-        const potentiallyUpdatedCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-        if (!objectPopoverHelper || selectedCallFrame !== potentiallyUpdatedCallFrame) {
-          debuggerModel.runtimeModel().releaseObjectGroup('popover');
-          if (objectPopoverHelper)
-            objectPopoverHelper.dispose();
-          return false;
-        }
-        const highlightRange = new TextUtils.TextRange(lineNumber, startHighlight, lineNumber, endHighlight);
-        highlightDescriptor = this.textEditor.highlightRange(highlightRange, 'source-frame-eval-expression');
-        return true;
-      },
-      hide: () => {
-        objectPopoverHelper.dispose();
-        debuggerModel.runtimeModel().releaseObjectGroup('popover');
-        this.textEditor.removeHighlight(highlightDescriptor);
-      }
-    };
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   */
-  _onKeyDown(event) {
-    this._clearControlDown();
-
-    if (event.key === 'Escape') {
-      if (this._popoverHelper.isPopoverVisible()) {
-        this._popoverHelper.hidePopover();
-        event.consume();
-      }
-      return;
-    }
-
-    if (UI.shortcutRegistry.eventMatchesAction(event, 'debugger.toggle-breakpoint')) {
-      const selection = this.textEditor.selection();
-      if (!selection)
-        return;
-      this._toggleBreakpoint(selection.startLine, false);
-      event.consume(true);
-      return;
-    }
-    if (UI.shortcutRegistry.eventMatchesAction(event, 'debugger.toggle-breakpoint-enabled')) {
-      const selection = this.textEditor.selection();
-      if (!selection)
-        return;
-      this._toggleBreakpoint(selection.startLine, true);
-      event.consume(true);
-      return;
-    }
-
-    if (UI.KeyboardShortcut.eventHasCtrlOrMeta(event) && this._executionLocation) {
-      this._controlDown = true;
-      if (event.key === (Host.isMac() ? 'Meta' : 'Control')) {
-        this._controlTimeout = setTimeout(() => {
-          if (this._executionLocation && this._controlDown)
-            this._showContinueToLocations();
-        }, 150);
-      }
-    }
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _onMouseMove(event) {
-    if (this._executionLocation && this._controlDown && UI.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
-      if (!this._continueToLocationDecorations)
-        this._showContinueToLocations();
-    }
-    if (this._continueToLocationDecorations) {
-      const textPosition = this.textEditor.coordinatesToCursorPosition(event.x, event.y);
-      const hovering = !!event.target.enclosingNodeOrSelfWithClass('source-frame-async-step-in');
-      this._setAsyncStepInHoveredLine(textPosition ? textPosition.startLine : null, hovering);
-    }
-  }
-
-  /**
-   * @param {?number} line
-   * @param {boolean} hovered
-   */
-  _setAsyncStepInHoveredLine(line, hovered) {
-    if (this._asyncStepInHoveredLine === line && this._asyncStepInHovered === hovered)
-      return;
-    if (this._asyncStepInHovered && this._asyncStepInHoveredLine)
-      this.textEditor.toggleLineClass(this._asyncStepInHoveredLine, 'source-frame-async-step-in-hovered', false);
-    this._asyncStepInHoveredLine = line;
-    this._asyncStepInHovered = hovered;
-    if (this._asyncStepInHovered && this._asyncStepInHoveredLine)
-      this.textEditor.toggleLineClass(this._asyncStepInHoveredLine, 'source-frame-async-step-in-hovered', true);
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _onMouseDown(event) {
-    if (!this._executionLocation || !UI.KeyboardShortcut.eventHasCtrlOrMeta(event))
-      return;
-    if (!this._continueToLocationDecorations)
-      return;
-    event.consume();
-    const textPosition = this.textEditor.coordinatesToCursorPosition(event.x, event.y);
-    if (!textPosition)
-      return;
-    for (const decoration of this._continueToLocationDecorations.keys()) {
-      const range = decoration.find();
-      if (range.from.line !== textPosition.startLine || range.to.line !== textPosition.startLine)
-        continue;
-      if (range.from.ch <= textPosition.startColumn && textPosition.startColumn <= range.to.ch) {
-        this._continueToLocationDecorations.get(decoration)();
-        break;
-      }
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onBlur(event) {
-    if (this.textEditor.element.isAncestor(event.target))
-      return;
-    this._clearControlDown();
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   */
-  _onKeyUp(event) {
-    this._clearControlDown();
-  }
-
-  _clearControlDown() {
-    this._controlDown = false;
-    this._clearContinueToLocations();
-    clearTimeout(this._controlTimeout);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {?Bindings.BreakpointManager.Breakpoint} breakpoint
-   * @param {?{lineNumber: number, columnNumber: number}} location
-   */
-  _editBreakpointCondition(lineNumber, breakpoint, location) {
-    this._conditionElement = this._createConditionElement(lineNumber);
-    this.textEditor.addDecoration(this._conditionElement, lineNumber);
-
-    /**
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function finishEditing(committed, element, newText) {
-      this.textEditor.removeDecoration(this._conditionElement, lineNumber);
-      delete this._conditionEditorElement;
-      delete this._conditionElement;
-      if (!committed)
-        return;
-
-      if (breakpoint)
-        breakpoint.setCondition(newText);
-      else if (location)
-        this._setBreakpoint(location.lineNumber, location.columnNumber, newText, true);
-      else
-        this._createNewBreakpoint(lineNumber, newText, true);
-    }
-
-    const config = new UI.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
-    UI.InplaceEditor.startEditing(this._conditionEditorElement, config);
-    this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : '';
-    this._conditionEditorElement.select();
-  }
-
-  _createConditionElement(lineNumber) {
-    const conditionElement = createElementWithClass('div', 'source-frame-breakpoint-condition');
-
-    const labelElement = conditionElement.createChild('label', 'source-frame-breakpoint-message');
-    labelElement.htmlFor = 'source-frame-breakpoint-condition';
-    labelElement.createTextChild(
-        Common.UIString('The breakpoint on line %d will stop only if this expression is true:', lineNumber + 1));
-
-    const editorElement = UI.createInput('monospace', 'text');
-    conditionElement.appendChild(editorElement);
-    editorElement.id = 'source-frame-breakpoint-condition';
-    this._conditionEditorElement = editorElement;
-
-    return conditionElement;
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   */
-  setExecutionLocation(uiLocation) {
-    this._executionLocation = uiLocation;
-    if (!this.loaded)
-      return;
-
-    this.textEditor.setExecutionLocation(uiLocation.lineNumber, uiLocation.columnNumber);
-    if (this.isShowing()) {
-      // We need SourcesTextEditor to be initialized prior to this call. @see crbug.com/506566
-      setImmediate(() => {
-        if (this._controlDown)
-          this._showContinueToLocations();
-        else
-          this._generateValuesInSource();
-      });
-    }
-  }
-
-  _generateValuesInSource() {
-    if (!Common.moduleSetting('inlineVariableValues').get())
-      return;
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext)
-      return;
-    const callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-    if (!callFrame)
-      return;
-
-    const localScope = callFrame.localScope();
-    const functionLocation = callFrame.functionLocation();
-    if (localScope && functionLocation) {
-      Sources.SourceMapNamesResolver.resolveScopeInObject(localScope)
-          .getAllProperties(false, false, this._prepareScopeVariables.bind(this, callFrame));
-    }
-
-    if (this._clearValueWidgetsTimer) {
-      clearTimeout(this._clearValueWidgetsTimer);
-      delete this._clearValueWidgetsTimer;
-    }
-  }
-
-  _showContinueToLocations() {
-    this._popoverHelper.hidePopover();
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext)
-      return;
-    const callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-    if (!callFrame)
-      return;
-    const start = callFrame.functionLocation() || callFrame.location();
-    const debuggerModel = callFrame.debuggerModel;
-    debuggerModel.getPossibleBreakpoints(start, null, true)
-        .then(locations => this.textEditor.operation(renderLocations.bind(this, locations)));
-
-    /**
-     * @param {!Array<!SDK.DebuggerModel.BreakLocation>} locations
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function renderLocations(locations) {
-      this._clearContinueToLocationsNoRestore();
-      this.textEditor.hideExecutionLineBackground();
-      this._clearValueWidgets();
-      this._continueToLocationDecorations = new Map();
-      locations = locations.reverse();
-      let previousCallLine = -1;
-      for (const location of locations) {
-        const lineNumber = location.lineNumber;
-        let token = this.textEditor.tokenAtTextPosition(lineNumber, location.columnNumber);
-        if (!token)
-          continue;
-        const line = this.textEditor.line(lineNumber);
-        let tokenContent = line.substring(token.startColumn, token.endColumn);
-        if (!token.type && tokenContent === '.') {
-          token = this.textEditor.tokenAtTextPosition(lineNumber, token.endColumn + 1);
-          tokenContent = line.substring(token.startColumn, token.endColumn);
-        }
-        if (!token.type)
-          continue;
-        const validKeyword = token.type === 'js-keyword' &&
-            (tokenContent === 'this' || tokenContent === 'return' || tokenContent === 'new' ||
-             tokenContent === 'continue' || tokenContent === 'break');
-        if (!validKeyword && !this._isIdentifier(token.type))
-          continue;
-        if (previousCallLine === lineNumber && location.type !== Protocol.Debugger.BreakLocationType.Call)
-          continue;
-
-        let highlightRange = new TextUtils.TextRange(lineNumber, token.startColumn, lineNumber, token.endColumn - 1);
-        let decoration = this.textEditor.highlightRange(highlightRange, 'source-frame-continue-to-location');
-        this._continueToLocationDecorations.set(decoration, location.continueToLocation.bind(location));
-        if (location.type === Protocol.Debugger.BreakLocationType.Call)
-          previousCallLine = lineNumber;
-
-        let isAsyncCall = (line[token.startColumn - 1] === '.' && tokenContent === 'then') ||
-            tokenContent === 'setTimeout' || tokenContent === 'setInterval' || tokenContent === 'postMessage';
-        if (tokenContent === 'new') {
-          token = this.textEditor.tokenAtTextPosition(lineNumber, token.endColumn + 1);
-          tokenContent = line.substring(token.startColumn, token.endColumn);
-          isAsyncCall = tokenContent === 'Worker';
-        }
-        const isCurrentPosition = this._executionLocation && lineNumber === this._executionLocation.lineNumber &&
-            location.columnNumber === this._executionLocation.columnNumber;
-        if (location.type === Protocol.Debugger.BreakLocationType.Call && isAsyncCall) {
-          const asyncStepInRange = this._findAsyncStepInRange(this.textEditor, lineNumber, line, token.endColumn);
-          if (asyncStepInRange) {
-            highlightRange =
-                new TextUtils.TextRange(lineNumber, asyncStepInRange.from, lineNumber, asyncStepInRange.to - 1);
-            decoration = this.textEditor.highlightRange(highlightRange, 'source-frame-async-step-in');
-            this._continueToLocationDecorations.set(
-                decoration, this._asyncStepIn.bind(this, location, isCurrentPosition));
-          }
-        }
-      }
-
-      this._continueToLocationRenderedForTest();
-    }
-  }
-
-  _continueToLocationRenderedForTest() {
-  }
-
-  /**
-   * @param {!SourceFrame.SourcesTextEditor} textEditor
-   * @param {number} lineNumber
-   * @param {string} line
-   * @param {number} column
-   * @return {?{from: number, to: number}}
-   */
-  _findAsyncStepInRange(textEditor, lineNumber, line, column) {
-    let token;
-    let tokenText;
-    let from = column;
-    let to = line.length;
-
-    let position = line.indexOf('(', column);
-    const argumentsStart = position;
-    if (position === -1)
-      return null;
-    position++;
-
-    skipWhitespace();
-    if (position >= line.length)
-      return null;
-
-    nextToken();
-    if (!token)
-      return null;
-    from = token.startColumn;
-
-    if (token.type === 'js-keyword' && tokenText === 'async') {
-      skipWhitespace();
-      if (position >= line.length)
-        return {from: from, to: to};
-      nextToken();
-      if (!token)
-        return {from: from, to: to};
-    }
-
-    if (token.type === 'js-keyword' && tokenText === 'function')
-      return {from: from, to: to};
-
-    if (token.type === 'js-string')
-      return {from: argumentsStart, to: to};
-
-    if (token.type && this._isIdentifier(token.type))
-      return {from: from, to: to};
-
-    if (tokenText !== '(')
-      return null;
-    const closeParen = line.indexOf(')', position);
-    if (closeParen === -1 || line.substring(position, closeParen).indexOf('(') !== -1)
-      return {from: from, to: to};
-    return {from: from, to: closeParen + 1};
-
-    function nextToken() {
-      token = textEditor.tokenAtTextPosition(lineNumber, position);
-      if (token) {
-        position = token.endColumn;
-        to = token.endColumn;
-        tokenText = line.substring(token.startColumn, token.endColumn);
-      }
-    }
-
-    function skipWhitespace() {
-      while (position < line.length) {
-        if (line[position] === ' ') {
-          position++;
-          continue;
-        }
-        const token = textEditor.tokenAtTextPosition(lineNumber, position);
-        if (token.type === 'js-comment') {
-          position = token.endColumn;
-          continue;
-        }
-        break;
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.BreakLocation} location
-   * @param {boolean} isCurrentPosition
-   */
-  _asyncStepIn(location, isCurrentPosition) {
-    if (!isCurrentPosition)
-      location.continueToLocation(asyncStepIn);
-    else
-      asyncStepIn();
-
-    function asyncStepIn() {
-      location.debuggerModel.scheduleStepIntoAsync();
-    }
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel.CallFrame} callFrame
-   * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-   * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-   */
-  _prepareScopeVariables(callFrame, properties, internalProperties) {
-    if (!properties || !properties.length || properties.length > 500 || !this.isShowing()) {
-      this._clearValueWidgets();
-      return;
-    }
-
-    const functionUILocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(
-        /** @type {!SDK.DebuggerModel.Location} */ (callFrame.functionLocation()));
-    const executionUILocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(callFrame.location());
-    if (!functionUILocation || !executionUILocation || functionUILocation.uiSourceCode !== this._debuggerSourceCode ||
-        executionUILocation.uiSourceCode !== this._debuggerSourceCode) {
-      this._clearValueWidgets();
-      return;
-    }
-
-    const fromLine = functionUILocation.lineNumber;
-    const fromColumn = functionUILocation.columnNumber;
-    let toLine = executionUILocation.lineNumber;
-
-    // Make sure we have a chance to update all existing widgets.
-    if (this._valueWidgets) {
-      for (const line of this._valueWidgets.keys())
-        toLine = Math.max(toLine, line + 1);
-    }
-    if (fromLine >= toLine || toLine - fromLine > 500 || fromLine < 0 || toLine >= this.textEditor.linesCount) {
-      this._clearValueWidgets();
-      return;
-    }
-
-    const valuesMap = new Map();
-    for (const property of properties)
-      valuesMap.set(property.name, property.value);
-
-    /** @type {!Map.<number, !Set<string>>} */
-    const namesPerLine = new Map();
-    let skipObjectProperty = false;
-    const tokenizer = new TextEditor.CodeMirrorUtils.TokenizerFactory().createTokenizer('text/javascript');
-    tokenizer(this.textEditor.line(fromLine).substring(fromColumn), processToken.bind(this, fromLine));
-    for (let i = fromLine + 1; i < toLine; ++i)
-      tokenizer(this.textEditor.line(i), processToken.bind(this, i));
-
-    /**
-     * @param {number} lineNumber
-     * @param {string} tokenValue
-     * @param {?string} tokenType
-     * @param {number} column
-     * @param {number} newColumn
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function processToken(lineNumber, tokenValue, tokenType, column, newColumn) {
-      if (!skipObjectProperty && tokenType && this._isIdentifier(tokenType) && valuesMap.get(tokenValue)) {
-        let names = namesPerLine.get(lineNumber);
-        if (!names) {
-          names = new Set();
-          namesPerLine.set(lineNumber, names);
-        }
-        names.add(tokenValue);
-      }
-      skipObjectProperty = tokenValue === '.';
-    }
-    this.textEditor.operation(this._renderDecorations.bind(this, valuesMap, namesPerLine, fromLine, toLine));
-  }
-
-  /**
-   * @param {!Map.<string,!SDK.RemoteObject>} valuesMap
-   * @param {!Map.<number, !Set<string>>} namesPerLine
-   * @param {number} fromLine
-   * @param {number} toLine
-   */
-  _renderDecorations(valuesMap, namesPerLine, fromLine, toLine) {
-    const formatter = new ObjectUI.RemoteObjectPreviewFormatter();
-    for (let i = fromLine; i < toLine; ++i) {
-      const names = namesPerLine.get(i);
-      const oldWidget = this._valueWidgets.get(i);
-      if (!names) {
-        if (oldWidget) {
-          this._valueWidgets.delete(i);
-          this.textEditor.removeDecoration(oldWidget, i);
-        }
-        continue;
-      }
-
-      const widget = createElementWithClass('div', 'text-editor-value-decoration');
-      const base = this.textEditor.cursorPositionToCoordinates(i, 0);
-      const offset = this.textEditor.cursorPositionToCoordinates(i, this.textEditor.line(i).length);
-      const codeMirrorLinesLeftPadding = 4;
-      const left = offset.x - base.x + codeMirrorLinesLeftPadding;
-      widget.style.left = left + 'px';
-      widget.__nameToToken = new Map();
-
-      let renderedNameCount = 0;
-      for (const name of names) {
-        if (renderedNameCount > 10)
-          break;
-        if (namesPerLine.get(i - 1) && namesPerLine.get(i - 1).has(name))
-          continue;  // Only render name once in the given continuous block.
-        if (renderedNameCount)
-          widget.createTextChild(', ');
-        const nameValuePair = widget.createChild('span');
-        widget.__nameToToken.set(name, nameValuePair);
-        nameValuePair.createTextChild(name + ' = ');
-        const value = valuesMap.get(name);
-        const propertyCount = value.preview ? value.preview.properties.length : 0;
-        const entryCount = value.preview && value.preview.entries ? value.preview.entries.length : 0;
-        if (value.preview && propertyCount + entryCount < 10) {
-          formatter.appendObjectPreview(nameValuePair, value.preview, false /* isEntry */);
-        } else {
-          nameValuePair.appendChild(ObjectUI.ObjectPropertiesSection.createValueElement(
-              value, false /* wasThrown */, false /* showPreview */));
-        }
-        ++renderedNameCount;
-      }
-
-      let widgetChanged = true;
-      if (oldWidget) {
-        widgetChanged = false;
-        for (const name of widget.__nameToToken.keys()) {
-          const oldText = oldWidget.__nameToToken.get(name) ? oldWidget.__nameToToken.get(name).textContent : '';
-          const newText = widget.__nameToToken.get(name) ? widget.__nameToToken.get(name).textContent : '';
-          if (newText !== oldText) {
-            widgetChanged = true;
-            // value has changed, update it.
-            UI.runCSSAnimationOnce(
-                /** @type {!Element} */ (widget.__nameToToken.get(name)), 'source-frame-value-update-highlight');
-          }
-        }
-        if (widgetChanged) {
-          this._valueWidgets.delete(i);
-          this.textEditor.removeDecoration(oldWidget, i);
-        }
-      }
-      if (widgetChanged) {
-        this._valueWidgets.set(i, widget);
-        this.textEditor.addDecoration(widget, i);
-      }
-    }
-  }
-
-  clearExecutionLine() {
-    this.textEditor.operation(() => {
-      if (this.loaded && this._executionLocation)
-        this.textEditor.clearExecutionLine();
-      delete this._executionLocation;
-      this._clearValueWidgetsTimer = setTimeout(this._clearValueWidgets.bind(this), 1000);
-      this._clearContinueToLocationsNoRestore();
-    });
-  }
-
-  _clearValueWidgets() {
-    clearTimeout(this._clearValueWidgetsTimer);
-    delete this._clearValueWidgetsTimer;
-    this.textEditor.operation(() => {
-      for (const line of this._valueWidgets.keys())
-        this.textEditor.removeDecoration(this._valueWidgets.get(line), line);
-      this._valueWidgets.clear();
-    });
-  }
-
-  _clearContinueToLocationsNoRestore() {
-    if (!this._continueToLocationDecorations)
-      return;
-    this.textEditor.operation(() => {
-      for (const decoration of this._continueToLocationDecorations.keys())
-        this.textEditor.removeHighlight(decoration);
-      this._continueToLocationDecorations = null;
-      this._setAsyncStepInHoveredLine(null, false);
-    });
-  }
-
-  _clearContinueToLocations() {
-    if (!this._continueToLocationDecorations)
-      return;
-    this.textEditor.operation(() => {
-      this.textEditor.showExecutionLineBackground();
-      this._generateValuesInSource();
-      this._clearContinueToLocationsNoRestore();
-    });
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @return {!Array<!Sources.JavaScriptSourceFrame.BreakpointDecoration>}
-   */
-  _lineBreakpointDecorations(lineNumber) {
-    return Array.from(this._breakpointDecorations)
-        .filter(decoration => (decoration.handle.resolve() || {}).lineNumber === lineNumber);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?Sources.JavaScriptSourceFrame.BreakpointDecoration}
-   */
-  _breakpointDecoration(lineNumber, columnNumber) {
-    for (const decoration of this._breakpointDecorations) {
-      const location = decoration.handle.resolve();
-      if (!location)
-        continue;
-      if (location.lineNumber === lineNumber && location.columnNumber === columnNumber)
-        return decoration;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!Sources.JavaScriptSourceFrame.BreakpointDecoration} decoration
-   */
-  _updateBreakpointDecoration(decoration) {
-    if (!this._scheduledBreakpointDecorationUpdates) {
-      /** @type {!Set<!Sources.JavaScriptSourceFrame.BreakpointDecoration>} */
-      this._scheduledBreakpointDecorationUpdates = new Set();
-      setImmediate(() => this.textEditor.operation(update.bind(this)));
-    }
-    this._scheduledBreakpointDecorationUpdates.add(decoration);
-
-    /**
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function update() {
-      const lineNumbers = new Set();
-      for (const decoration of this._scheduledBreakpointDecorationUpdates) {
-        const location = decoration.handle.resolve();
-        if (!location)
-          continue;
-        lineNumbers.add(location.lineNumber);
-      }
-      delete this._scheduledBreakpointDecorationUpdates;
-      let waitingForInlineDecorations = false;
-      for (const lineNumber of lineNumbers) {
-        const decorations = this._lineBreakpointDecorations(lineNumber);
-        updateGutter.call(this, lineNumber, decorations);
-        if (this._possibleBreakpointsRequested.has(lineNumber)) {
-          waitingForInlineDecorations = true;
-          continue;
-        }
-        updateInlineDecorations.call(this, lineNumber, decorations);
-      }
-      if (!waitingForInlineDecorations)
-        this._breakpointDecorationsUpdatedForTest();
-    }
-
-    /**
-     * @param {number} lineNumber
-     * @param {!Array<!Sources.JavaScriptSourceFrame.BreakpointDecoration>} decorations
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function updateGutter(lineNumber, decorations) {
-      this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', false);
-      this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-disabled', false);
-      this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-conditional', false);
-
-      if (decorations.length) {
-        decorations.sort(Sources.JavaScriptSourceFrame.BreakpointDecoration.mostSpecificFirst);
-        this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint', true);
-        this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-disabled', !decorations[0].enabled || this._muted);
-        this.textEditor.toggleLineClass(lineNumber, 'cm-breakpoint-conditional', !!decorations[0].condition);
-      }
-    }
-
-    /**
-     * @param {number} lineNumber
-     * @param {!Array<!Sources.JavaScriptSourceFrame.BreakpointDecoration>} decorations
-     * @this {Sources.JavaScriptSourceFrame}
-     */
-    function updateInlineDecorations(lineNumber, decorations) {
-      const actualBookmarks =
-          new Set(decorations.map(decoration => decoration.bookmark).filter(bookmark => !!bookmark));
-      const lineEnd = this.textEditor.line(lineNumber).length;
-      const bookmarks = this.textEditor.bookmarks(
-          new TextUtils.TextRange(lineNumber, 0, lineNumber, lineEnd),
-          Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol);
-      for (const bookmark of bookmarks) {
-        if (!actualBookmarks.has(bookmark))
-          bookmark.clear();
-      }
-      if (!decorations.length)
-        return;
-      if (decorations.length > 1) {
-        for (const decoration of decorations) {
-          decoration.update();
-          if (!this._muted)
-            decoration.show();
-          else
-            decoration.hide();
-        }
-      } else {
-        decorations[0].update();
-        decorations[0].hide();
-      }
-    }
-  }
-
-  _breakpointDecorationsUpdatedForTest() {
-  }
-
-  /**
-   * @param {!Sources.JavaScriptSourceFrame.BreakpointDecoration} decoration
-   * @param {!Event} event
-   */
-  _inlineBreakpointClick(decoration, event) {
-    event.consume(true);
-    if (decoration.breakpoint) {
-      if (event.shiftKey)
-        decoration.breakpoint.setEnabled(!decoration.breakpoint.enabled());
-      else
-        decoration.breakpoint.remove();
-    } else {
-      const location = decoration.handle.resolve();
-      if (!location)
-        return;
-      this._setBreakpoint(location.lineNumber, location.columnNumber, decoration.condition, true);
-    }
-  }
-
-  /**
-   * @param {!Sources.JavaScriptSourceFrame.BreakpointDecoration} decoration
-   * @param {!Event} event
-   */
-  _inlineBreakpointContextMenu(decoration, event) {
-    event.consume(true);
-    const location = decoration.handle.resolve();
-    if (!location)
-      return;
-    const contextMenu = new UI.ContextMenu(event);
-    if (decoration.breakpoint) {
-      contextMenu.debugSection().appendItem(
-          Common.UIString('Edit breakpoint\u2026'),
-          this._editBreakpointCondition.bind(this, location.lineNumber, decoration.breakpoint, null));
-    } else {
-      contextMenu.debugSection().appendItem(
-          Common.UIString('Add conditional breakpoint\u2026'),
-          this._editBreakpointCondition.bind(this, location.lineNumber, null, location));
-      contextMenu.debugSection().appendItem(
-          Common.UIString('Never pause here'),
-          this._setBreakpoint.bind(this, location.lineNumber, location.columnNumber, 'false', true));
-    }
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   * @return {boolean}
-   */
-  _shouldIgnoreExternalBreakpointEvents(event) {
-    const uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation);
-    if (uiLocation.uiSourceCode !== this._debuggerSourceCode || !this.loaded)
-      return true;
-    if (this._supportsEnabledBreakpointsWhileEditing())
-      return false;
-    if (this._muted)
-      return true;
-    const scriptFiles = this._scriptFileForDebuggerModel.valuesArray();
-    for (let i = 0; i < scriptFiles.length; ++i) {
-      if (scriptFiles[i].isDivergingFromVM() || scriptFiles[i].isMergingToVM())
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _breakpointAdded(event) {
-    if (this._shouldIgnoreExternalBreakpointEvents(event))
-      return;
-    const uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation);
-    const breakpoint = /** @type {!Bindings.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
-    this._addBreakpoint(uiLocation, breakpoint);
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   * @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
-   */
-  _addBreakpoint(uiLocation, breakpoint) {
-    const lineDecorations = this._lineBreakpointDecorations(uiLocation.lineNumber);
-    let decoration = this._breakpointDecoration(uiLocation.lineNumber, uiLocation.columnNumber);
-    if (decoration) {
-      decoration.breakpoint = breakpoint;
-      decoration.condition = breakpoint.condition();
-      decoration.enabled = breakpoint.enabled();
-    } else {
-      const handle = this.textEditor.textEditorPositionHandle(uiLocation.lineNumber, uiLocation.columnNumber);
-      decoration = new Sources.JavaScriptSourceFrame.BreakpointDecoration(
-          this.textEditor, handle, breakpoint.condition(), breakpoint.enabled(), breakpoint);
-      decoration.element.addEventListener('click', this._inlineBreakpointClick.bind(this, decoration), true);
-      decoration.element.addEventListener(
-          'contextmenu', this._inlineBreakpointContextMenu.bind(this, decoration), true);
-      this._breakpointDecorations.add(decoration);
-    }
-    this._decorationByBreakpoint.set(breakpoint, decoration);
-    this._updateBreakpointDecoration(decoration);
-    if (breakpoint.enabled() && !lineDecorations.length) {
-      this._possibleBreakpointsRequested.add(uiLocation.lineNumber);
-      this._breakpointManager
-          .possibleBreakpoints(
-              this._debuggerSourceCode, new TextUtils.TextRange(uiLocation.lineNumber, 0, uiLocation.lineNumber + 1, 0))
-          .then(addInlineDecorations.bind(this, uiLocation.lineNumber));
-    }
-
-    /**
-     * @this {Sources.JavaScriptSourceFrame}
-     * @param {number} lineNumber
-     * @param {!Array<!Workspace.UILocation>} possibleLocations
-     */
-    function addInlineDecorations(lineNumber, possibleLocations) {
-      this._possibleBreakpointsRequested.delete(lineNumber);
-      const decorations = this._lineBreakpointDecorations(lineNumber);
-      for (const decoration of decorations)
-        this._updateBreakpointDecoration(decoration);
-      if (!decorations.some(decoration => !!decoration.breakpoint))
-        return;
-      /** @type {!Set<number>} */
-      const columns = new Set();
-      for (const decoration of decorations) {
-        const location = decoration.handle.resolve();
-        if (!location)
-          continue;
-        columns.add(location.columnNumber);
-      }
-      for (const location of possibleLocations) {
-        if (columns.has(location.columnNumber))
-          continue;
-        const handle = this.textEditor.textEditorPositionHandle(location.lineNumber, location.columnNumber);
-        const decoration =
-            new Sources.JavaScriptSourceFrame.BreakpointDecoration(this.textEditor, handle, '', false, null);
-        decoration.element.addEventListener('click', this._inlineBreakpointClick.bind(this, decoration), true);
-        decoration.element.addEventListener(
-            'contextmenu', this._inlineBreakpointContextMenu.bind(this, decoration), true);
-        this._breakpointDecorations.add(decoration);
-        this._updateBreakpointDecoration(decoration);
-      }
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _breakpointRemoved(event) {
-    if (this._shouldIgnoreExternalBreakpointEvents(event))
-      return;
-    const uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation);
-    const breakpoint = /** @type {!Bindings.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
-    const decoration = this._decorationByBreakpoint.get(breakpoint);
-    if (!decoration)
-      return;
-    this._decorationByBreakpoint.delete(breakpoint);
-
-    decoration.breakpoint = null;
-    decoration.enabled = false;
-
-    const lineDecorations = this._lineBreakpointDecorations(uiLocation.lineNumber);
-    if (!lineDecorations.some(decoration => !!decoration.breakpoint)) {
-      for (const lineDecoration of lineDecorations) {
-        this._breakpointDecorations.delete(lineDecoration);
-        this._updateBreakpointDecoration(lineDecoration);
-      }
-    } else {
-      this._updateBreakpointDecoration(decoration);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onBindingChanged() {
-    this._updateDebuggerSourceCode();
-    this._updateScriptFiles();
-    this._refreshBreakpoints();
-    this._showBlackboxInfobarIfNeeded();
-    this._updateLinesWithoutMappingHighlight();
-  }
-
-  _refreshBreakpoints() {
-    if (!this.loaded)
-      return;
-    for (const lineDecoration of this._breakpointDecorations.valuesArray()) {
-      this._breakpointDecorations.delete(lineDecoration);
-      this._updateBreakpointDecoration(lineDecoration);
-    }
-    const breakpointLocations = this._breakpointManager.breakpointLocationsForUISourceCode(this._debuggerSourceCode);
-    for (const breakpointLocation of breakpointLocations)
-      this._addBreakpoint(breakpointLocation.uiLocation, breakpointLocation.breakpoint);
-  }
-
-  _updateDebuggerSourceCode() {
-    const binding = Persistence.persistence.binding(this.uiSourceCode());
-    this._debuggerSourceCode = binding ? binding.network : this.uiSourceCode();
-  }
-
-  _updateLinesWithoutMappingHighlight() {
-    const isSourceMapSource = !!Bindings.CompilerScriptMapping.uiSourceCodeOrigin(this._debuggerSourceCode);
-    if (!isSourceMapSource)
-      return;
-    const linesCount = this.textEditor.linesCount;
-    for (let i = 0; i < linesCount; ++i) {
-      const lineHasMapping = Bindings.CompilerScriptMapping.uiLineHasMapping(this._debuggerSourceCode, i);
-      if (!lineHasMapping)
-        this._hasLineWithoutMapping = true;
-      if (this._hasLineWithoutMapping)
-        this.textEditor.toggleLineClass(i, 'cm-line-without-source-mapping', !lineHasMapping);
-    }
-  }
-
-  _updateScriptFiles() {
-    for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) {
-      const scriptFile = Bindings.debuggerWorkspaceBinding.scriptFile(this._debuggerSourceCode, debuggerModel);
-      if (scriptFile)
-        this._updateScriptFile(debuggerModel);
-    }
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _updateScriptFile(debuggerModel) {
-    const oldScriptFile = this._scriptFileForDebuggerModel.get(debuggerModel);
-    const newScriptFile = Bindings.debuggerWorkspaceBinding.scriptFile(this._debuggerSourceCode, debuggerModel);
-    this._scriptFileForDebuggerModel.delete(debuggerModel);
-    if (oldScriptFile) {
-      oldScriptFile.removeEventListener(Bindings.ResourceScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
-      oldScriptFile.removeEventListener(
-          Bindings.ResourceScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
-      if (this._muted && !this.uiSourceCode().isDirty())
-        this._restoreBreakpointsIfConsistentScripts();
-    }
-    if (!newScriptFile)
-      return;
-    this._scriptFileForDebuggerModel.set(debuggerModel, newScriptFile);
-    newScriptFile.addEventListener(Bindings.ResourceScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
-    newScriptFile.addEventListener(Bindings.ResourceScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
-    if (this.loaded)
-      newScriptFile.checkMapping();
-    this._showSourceMapInfobar(newScriptFile.hasSourceMapURL());
-  }
-
-  /**
-   * @param {boolean} show
-   */
-  _showSourceMapInfobar(show) {
-    if (!show) {
-      if (this._sourceMapInfobar) {
-        this._sourceMapInfobar.dispose();
-        delete this._sourceMapInfobar;
-      }
-      return;
-    }
-    if (this._sourceMapInfobar)
-      return;
-    this._sourceMapInfobar = UI.Infobar.create(
-        UI.Infobar.Type.Info, Common.UIString('Source Map detected.'),
-        Common.settings.createSetting('sourceMapInfobarDisabled', false));
-    if (this._sourceMapInfobar) {
-      this._sourceMapInfobar.createDetailsRowMessage(Common.UIString(
-          'Associated files should be added to the file tree. You can debug these resolved source files as regular JavaScript files.'));
-      this._sourceMapInfobar.createDetailsRowMessage(Common.UIString(
-          'Associated files are available via file tree or %s.',
-          UI.shortcutRegistry.shortcutTitleForAction('quickOpen.show')));
-      this._sourceMapInfobar.setCloseCallback(() => delete this._sourceMapInfobar);
-      this.attachInfobars([this._sourceMapInfobar]);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onTextEditorContentSet() {
-    super.onTextEditorContentSet();
-    if (this._executionLocation)
-      this.setExecutionLocation(this._executionLocation);
-
-    const breakpointLocations = this._breakpointManager.breakpointLocationsForUISourceCode(this._debuggerSourceCode);
-    for (const breakpointLocation of breakpointLocations)
-      this._addBreakpoint(breakpointLocation.uiLocation, breakpointLocation.breakpoint);
-
-    const scriptFiles = this._scriptFileForDebuggerModel.valuesArray();
-    for (let i = 0; i < scriptFiles.length; ++i)
-      scriptFiles[i].checkMapping();
-
-    this._updateLinesWithoutMappingHighlight();
-    this._detectMinified();
-  }
-
-  _detectMinified() {
-    if (this._prettyPrintInfobar)
-      return;
-
-    const content = this.uiSourceCode().content();
-    if (!content || !TextUtils.isMinified(content))
-      return;
-
-    this._prettyPrintInfobar = UI.Infobar.create(
-        UI.Infobar.Type.Info, Common.UIString('Pretty-print this minified file?'),
-        Common.settings.createSetting('prettyPrintInfobarDisabled', false));
-    if (!this._prettyPrintInfobar)
-      return;
-
-    this._prettyPrintInfobar.setCloseCallback(() => delete this._prettyPrintInfobar);
-    const toolbar = new UI.Toolbar('');
-    const button = new UI.ToolbarButton('', 'largeicon-pretty-print');
-    toolbar.appendToolbarItem(button);
-    toolbar.element.style.display = 'inline-block';
-    toolbar.element.style.verticalAlign = 'middle';
-    toolbar.element.style.marginBottom = '3px';
-    toolbar.element.style.pointerEvents = 'none';
-    const element = this._prettyPrintInfobar.createDetailsRowMessage();
-    element.appendChild(UI.formatLocalized(
-        'You can click the %s button on the bottom status bar, and continue debugging with the new formatted source.',
-        [toolbar.element]));
-    this.attachInfobars([this._prettyPrintInfobar]);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _handleGutterClick(event) {
-    if (this._muted)
-      return;
-
-    const eventData = /** @type {!SourceFrame.SourcesTextEditor.GutterClickEventData} */ (event.data);
-    const lineNumber = eventData.lineNumber;
-    const eventObject = eventData.event;
-
-    if (eventObject.button !== 0 || eventObject.altKey || eventObject.ctrlKey || eventObject.metaKey)
-      return;
-
-    this._toggleBreakpoint(lineNumber, eventObject.shiftKey);
-    eventObject.consume(true);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {boolean} onlyDisable
-   */
-  _toggleBreakpoint(lineNumber, onlyDisable) {
-    const decorations = this._lineBreakpointDecorations(lineNumber);
-    if (!decorations.length) {
-      this._createNewBreakpoint(lineNumber, '', true);
-      return;
-    }
-    const hasDisabled = this.textEditor.hasLineClass(lineNumber, 'cm-breakpoint-disabled');
-    const breakpoints = decorations.map(decoration => decoration.breakpoint).filter(breakpoint => !!breakpoint);
-    for (const breakpoint of breakpoints) {
-      if (onlyDisable)
-        breakpoint.setEnabled(hasDisabled);
-      else
-        breakpoint.remove();
-    }
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {string} condition
-   * @param {boolean} enabled
-   */
-  async _createNewBreakpoint(lineNumber, condition, enabled) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ScriptsBreakpointSet);
-
-    const originLineNumber = lineNumber;
-    const maxLengthToCheck = 1024;
-    let linesToCheck = 5;
-    for (; lineNumber < this.textEditor.linesCount && linesToCheck > 0; ++lineNumber) {
-      const lineLength = this.textEditor.line(lineNumber).length;
-      if (lineLength > maxLengthToCheck)
-        break;
-      if (lineLength === 0)
-        continue;
-      --linesToCheck;
-      const locations = await this._breakpointManager.possibleBreakpoints(
-          this._debuggerSourceCode, new TextUtils.TextRange(lineNumber, 0, lineNumber, lineLength));
-      if (locations && locations.length) {
-        this._setBreakpoint(locations[0].lineNumber, locations[0].columnNumber, condition, enabled);
-        return;
-      }
-    }
-    this._setBreakpoint(originLineNumber, 0, condition, enabled);
-  }
-
-  /**
-   * @param {boolean} onlyDisable
-   */
-  toggleBreakpointOnCurrentLine(onlyDisable) {
-    if (this._muted)
-      return;
-
-    const selection = this.textEditor.selection();
-    if (!selection)
-      return;
-    this._toggleBreakpoint(selection.startLine, onlyDisable);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string} condition
-   * @param {boolean} enabled
-   */
-  _setBreakpoint(lineNumber, columnNumber, condition, enabled) {
-    if (!Bindings.CompilerScriptMapping.uiLineHasMapping(this._debuggerSourceCode, lineNumber))
-      return;
-
-    Common.moduleSetting('breakpointsActive').set(true);
-    this._breakpointManager.setBreakpoint(this._debuggerSourceCode, lineNumber, columnNumber, condition, enabled);
-    this._breakpointWasSetForTest(lineNumber, columnNumber, condition, enabled);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {string} condition
-   * @param {boolean} enabled
-   */
-  _breakpointWasSetForTest(lineNumber, columnNumber, condition, enabled) {
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    this._popoverHelper.dispose();
-
-    this._breakpointManager.removeEventListener(
-        Bindings.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
-    this._breakpointManager.removeEventListener(
-        Bindings.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
-    this.uiSourceCode().removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
-    this.uiSourceCode().removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-    this.uiSourceCode().removeEventListener(
-        Workspace.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfNeeded, this);
-
-    Common.moduleSetting('skipStackFramesPattern').removeChangeListener(this._showBlackboxInfobarIfNeeded, this);
-    Common.moduleSetting('skipContentScripts').removeChangeListener(this._showBlackboxInfobarIfNeeded, this);
-    super.dispose();
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.JavaScriptSourceFrame.BreakpointDecoration = class {
-  /**
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   * @param {!TextEditor.TextEditorPositionHandle} handle
-   * @param {string} condition
-   * @param {boolean} enabled
-   * @param {?Bindings.BreakpointManager.Breakpoint} breakpoint
-   */
-  constructor(textEditor, handle, condition, enabled, breakpoint) {
-    this.textEditor = textEditor;
-    this.handle = handle;
-    this.condition = condition;
-    this.enabled = enabled;
-    this.breakpoint = breakpoint;
-    this.element = UI.Icon.create('smallicon-inline-breakpoint');
-    this.element.classList.toggle('cm-inline-breakpoint', true);
-
-    /** @type {?TextEditor.TextEditorBookMark} */
-    this.bookmark = null;
-  }
-
-  /**
-   * @param {!Sources.JavaScriptSourceFrame.BreakpointDecoration} decoration1
-   * @param {!Sources.JavaScriptSourceFrame.BreakpointDecoration} decoration2
-   * @return {number}
-   */
-  static mostSpecificFirst(decoration1, decoration2) {
-    if (decoration1.enabled !== decoration2.enabled)
-      return decoration1.enabled ? -1 : 1;
-    if (!!decoration1.condition !== !!decoration2.condition)
-      return !!decoration1.condition ? -1 : 1;
-    return 0;
-  }
-
-  update() {
-    if (!this.condition)
-      this.element.setIconType('smallicon-inline-breakpoint');
-    else
-      this.element.setIconType('smallicon-inline-breakpoint-conditional');
-    this.element.classList.toggle('cm-inline-disabled', !this.enabled);
-  }
-
-  show() {
-    if (this.bookmark)
-      return;
-    const location = this.handle.resolve();
-    if (!location)
-      return;
-    this.bookmark = this.textEditor.addBookmark(
-        location.lineNumber, location.columnNumber, this.element,
-        Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol);
-    this.bookmark[Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest] = this.element;
-  }
-
-  hide() {
-    if (!this.bookmark)
-      return;
-    this.bookmark.clear();
-    this.bookmark = null;
-  }
-};
-
-Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol = Symbol('bookmark');
-Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest = Symbol('element');
-
-Sources.JavaScriptSourceFrame.continueToLocationDecorationSymbol = Symbol('bookmark');
\ No newline at end of file
diff --git a/front_end/sources/NavigatorView.js b/front_end/sources/NavigatorView.js
deleted file mode 100644
index 959ac96..0000000
--- a/front_end/sources/NavigatorView.js
+++ /dev/null
@@ -1,1674 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {SDK.TargetManager.Observer}
- * @unrestricted
- */
-Sources.NavigatorView = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('sources/navigatorView.css');
-
-    this._scriptsTree = new UI.TreeOutlineInShadow();
-    this._scriptsTree.registerRequiredCSS('sources/navigatorTree.css');
-    this._scriptsTree.setComparator(Sources.NavigatorView._treeElementsCompare);
-    this.contentElement.appendChild(this._scriptsTree.element);
-    this.setDefaultFocusedElement(this._scriptsTree.element);
-
-    /** @type {!Multimap<!Workspace.UISourceCode, !Sources.NavigatorUISourceCodeTreeNode>} */
-    this._uiSourceCodeNodes = new Multimap();
-    /** @type {!Map.<string, !Sources.NavigatorFolderTreeNode>} */
-    this._subfolderNodes = new Map();
-
-    this._rootNode = new Sources.NavigatorRootTreeNode(this);
-    this._rootNode.populate();
-
-    /** @type {!Map.<!SDK.ResourceTreeFrame, !Sources.NavigatorGroupTreeNode>} */
-    this._frameNodes = new Map();
-
-    this.contentElement.addEventListener('contextmenu', this.handleContextMenu.bind(this), false);
-    UI.shortcutRegistry.addShortcutListener(
-        this.contentElement, 'sources.rename', this._renameShortcut.bind(this), true);
-
-    this._navigatorGroupByFolderSetting = Common.moduleSetting('navigatorGroupByFolder');
-    this._navigatorGroupByFolderSetting.addChangeListener(this._groupingChanged.bind(this));
-
-    this._initGrouping();
-
-    Persistence.persistence.addEventListener(
-        Persistence.Persistence.Events.BindingCreated, this._onBindingChanged, this);
-    Persistence.persistence.addEventListener(
-        Persistence.Persistence.Events.BindingRemoved, this._onBindingChanged, this);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.NameChanged, this._targetNameChanged, this);
-
-    SDK.targetManager.observeTargets(this);
-    this._resetWorkspace(Workspace.workspace);
-    this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
-    Bindings.networkProjectManager.addEventListener(
-        Bindings.NetworkProjectManager.Events.FrameAttributionAdded, this._frameAttributionAdded, this);
-    Bindings.networkProjectManager.addEventListener(
-        Bindings.NetworkProjectManager.Events.FrameAttributionRemoved, this._frameAttributionRemoved, this);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeElement
-   */
-  static _treeElementOrder(treeElement) {
-    if (treeElement._boostOrder)
-      return 0;
-
-    if (!Sources.NavigatorView._typeOrders) {
-      const weights = {};
-      const types = Sources.NavigatorView.Types;
-      weights[types.Root] = 1;
-      weights[types.Domain] = 10;
-      weights[types.FileSystemFolder] = 1;
-      weights[types.NetworkFolder] = 1;
-      weights[types.SourceMapFolder] = 2;
-      weights[types.File] = 10;
-      weights[types.Frame] = 70;
-      weights[types.Worker] = 90;
-      weights[types.FileSystem] = 100;
-      Sources.NavigatorView._typeOrders = weights;
-    }
-
-    let order = Sources.NavigatorView._typeOrders[treeElement._nodeType];
-    if (treeElement._uiSourceCode) {
-      const contentType = treeElement._uiSourceCode.contentType();
-      if (contentType.isDocument())
-        order += 3;
-      else if (contentType.isScript())
-        order += 5;
-      else if (contentType.isStyleSheet())
-        order += 10;
-      else
-        order += 15;
-    }
-
-    return order;
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  static appendAddFolderItem(contextMenu) {
-    function addFolder() {
-      Persistence.isolatedFileSystemManager.addFileSystem();
-    }
-
-    const addFolderLabel = Common.UIString('Add folder to workspace');
-    contextMenu.defaultSection().appendItem(addFolderLabel, addFolder);
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {string=} path
-   */
-  static appendSearchItem(contextMenu, path) {
-    function searchPath() {
-      Sources.SearchSourcesView.openSearch(`file:${path.trim()}`);
-    }
-
-    let searchLabel = Common.UIString('Search in folder');
-    if (!path || !path.trim()) {
-      path = '*';
-      searchLabel = Common.UIString('Search in all files');
-    }
-    contextMenu.viewSection().appendItem(searchLabel, searchPath);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeElement1
-   * @param {!UI.TreeElement} treeElement2
-   * @return {number}
-   */
-  static _treeElementsCompare(treeElement1, treeElement2) {
-    const typeWeight1 = Sources.NavigatorView._treeElementOrder(treeElement1);
-    const typeWeight2 = Sources.NavigatorView._treeElementOrder(treeElement2);
-
-    if (typeWeight1 > typeWeight2)
-      return 1;
-    if (typeWeight1 < typeWeight2)
-      return -1;
-    return treeElement1.titleAsText().compareTo(treeElement2.titleAsText());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onBindingChanged(event) {
-    const binding = /** @type {!Persistence.PersistenceBinding} */ (event.data);
-
-    // Update UISourceCode titles.
-    const networkNodes = this._uiSourceCodeNodes.get(binding.network);
-    for (const networkNode of networkNodes)
-      networkNode.updateTitle();
-    const fileSystemNodes = this._uiSourceCodeNodes.get(binding.fileSystem);
-    for (const fileSystemNode of fileSystemNodes)
-      fileSystemNode.updateTitle();
-
-    // Update folder titles.
-    const pathTokens = Persistence.FileSystemWorkspaceBinding.relativePath(binding.fileSystem);
-    let folderPath = '';
-    for (let i = 0; i < pathTokens.length - 1; ++i) {
-      folderPath += pathTokens[i];
-      const folderId =
-          this._folderNodeId(binding.fileSystem.project(), null, null, binding.fileSystem.origin(), folderPath);
-      const folderNode = this._subfolderNodes.get(folderId);
-      if (folderNode)
-        folderNode.updateTitle();
-      folderPath += '/';
-    }
-
-    // Update fileSystem root title.
-    const fileSystemRoot = this._rootNode.child(binding.fileSystem.project().id());
-    if (fileSystemRoot)
-      fileSystemRoot.updateTitle();
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._scriptsTree.focus();
-  }
-
-  /**
-   * @param {!Workspace.Workspace} workspace
-   */
-  _resetWorkspace(workspace) {
-    this._workspace = workspace;
-    this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
-    this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
-    this._workspace.addEventListener(Workspace.Workspace.Events.ProjectAdded, event => {
-      const project = /** @type {!Workspace.Project} */ (event.data);
-      this._projectAdded(project);
-      if (project.type() === Workspace.projectTypes.FileSystem)
-        this._computeUniqueFileSystemProjectNames();
-    });
-    this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, event => {
-      const project = /** @type {!Workspace.Project} */ (event.data);
-      this._removeProject(project);
-      if (project.type() === Workspace.projectTypes.FileSystem)
-        this._computeUniqueFileSystemProjectNames();
-    });
-    this._workspace.projects().forEach(this._projectAdded.bind(this));
-    this._computeUniqueFileSystemProjectNames();
-  }
-
-  /**
-   * @return {!Workspace.Workspace}
-   * @protected
-   */
-  workspace() {
-    return this._workspace;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  acceptProject(project) {
-    return !project.isServiceProject();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameAttributionAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    if (!this._acceptsUISourceCode(uiSourceCode))
-      return;
-
-    const addedFrame = /** @type {?SDK.ResourceTreeFrame} */ (event.data.frame);
-    // This event does not happen for UISourceCodes without initial attribution.
-    this._addUISourceCodeNode(uiSourceCode, addedFrame);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _frameAttributionRemoved(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    if (!this._acceptsUISourceCode(uiSourceCode))
-      return;
-
-    const removedFrame = /** @type {?SDK.ResourceTreeFrame} */ (event.data.frame);
-    const node = Array.from(this._uiSourceCodeNodes.get(uiSourceCode)).find(node => node.frame() === removedFrame);
-    this._removeUISourceCodeNode(node);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  _acceptsUISourceCode(uiSourceCode) {
-    return this.acceptProject(uiSourceCode.project());
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _addUISourceCode(uiSourceCode) {
-    if (!this._acceptsUISourceCode(uiSourceCode))
-      return;
-
-    const frames = Bindings.NetworkProject.framesForUISourceCode(uiSourceCode);
-    if (frames.length) {
-      for (const frame of frames)
-        this._addUISourceCodeNode(uiSourceCode, frame);
-    } else {
-      this._addUISourceCodeNode(uiSourceCode, null);
-    }
-    this.uiSourceCodeAdded(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {?SDK.ResourceTreeFrame} frame
-   */
-  _addUISourceCodeNode(uiSourceCode, frame) {
-    const isFromSourceMap = uiSourceCode.contentType().isFromSourceMap();
-    let path;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem)
-      path = Persistence.FileSystemWorkspaceBinding.relativePath(uiSourceCode).slice(0, -1);
-    else
-      path = Common.ParsedURL.extractPath(uiSourceCode.url()).split('/').slice(1, -1);
-
-    const project = uiSourceCode.project();
-    const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-    const folderNode =
-        this._folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap);
-    const uiSourceCodeNode = new Sources.NavigatorUISourceCodeTreeNode(this, uiSourceCode, frame);
-    folderNode.appendChild(uiSourceCodeNode);
-    this._uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  uiSourceCodeAdded(uiSourceCode) {
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._addUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeRemoved(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._removeUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @protected
-   * @param {!Workspace.Project} project
-   */
-  tryAddProject(project) {
-    this._projectAdded(project);
-    project.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _projectAdded(project) {
-    if (!this.acceptProject(project) || project.type() !== Workspace.projectTypes.FileSystem ||
-        this._rootNode.child(project.id()))
-      return;
-    this._rootNode.appendChild(new Sources.NavigatorGroupTreeNode(
-        this, project, project.id(), Sources.NavigatorView.Types.FileSystem, project.displayName()));
-  }
-
-  _computeUniqueFileSystemProjectNames() {
-    const fileSystemProjects = this._workspace.projectsForType(Workspace.projectTypes.FileSystem);
-    if (!fileSystemProjects.length)
-      return;
-    const encoder = new Persistence.PathEncoder();
-    const reversedPaths = fileSystemProjects.map(project => {
-      const fileSystem = /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem} */ (project);
-      return encoder.encode(fileSystem.fileSystemPath()).reverse();
-    });
-    const reversedIndex = new Common.Trie();
-    for (const reversedPath of reversedPaths)
-      reversedIndex.add(reversedPath);
-
-    for (let i = 0; i < fileSystemProjects.length; ++i) {
-      const reversedPath = reversedPaths[i];
-      const project = fileSystemProjects[i];
-      reversedIndex.remove(reversedPath);
-      const commonPrefix = reversedIndex.longestPrefix(reversedPath, false /* fullWordOnly */);
-      reversedIndex.add(reversedPath);
-      const path = encoder.decode(reversedPath.substring(0, commonPrefix.length + 1).reverse());
-      const fileSystemNode = this._rootNode.child(project.id());
-      if (fileSystemNode)
-        fileSystemNode.setTitle(path);
-    }
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _removeProject(project) {
-    const uiSourceCodes = project.uiSourceCodes();
-    for (let i = 0; i < uiSourceCodes.length; ++i)
-      this._removeUISourceCode(uiSourceCodes[i]);
-    if (project.type() !== Workspace.projectTypes.FileSystem)
-      return;
-    const fileSystemNode = this._rootNode.child(project.id());
-    if (!fileSystemNode)
-      return;
-    this._rootNode.removeChild(fileSystemNode);
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {?SDK.Target} target
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @param {string} projectOrigin
-   * @param {string} path
-   * @return {string}
-   */
-  _folderNodeId(project, target, frame, projectOrigin, path) {
-    const targetId = target ? target.id() : '';
-    const projectId = project.type() === Workspace.projectTypes.FileSystem ? project.id() : '';
-    const frameId = this._groupByFrame && frame ? frame.id : '';
-    return targetId + ':' + projectId + ':' + frameId + ':' + projectOrigin + ':' + path;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Workspace.Project} project
-   * @param {?SDK.Target} target
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @param {string} projectOrigin
-   * @param {!Array<string>} path
-   * @param {boolean} fromSourceMap
-   * @return {!Sources.NavigatorTreeNode}
-   */
-  _folderNode(uiSourceCode, project, target, frame, projectOrigin, path, fromSourceMap) {
-    if (project.type() === Workspace.projectTypes.Snippets)
-      return this._rootNode;
-
-    if (target && !this._groupByFolder && !fromSourceMap)
-      return this._domainNode(uiSourceCode, project, target, frame, projectOrigin);
-
-    const folderPath = path.join('/');
-    const folderId = this._folderNodeId(project, target, frame, projectOrigin, folderPath);
-    let folderNode = this._subfolderNodes.get(folderId);
-    if (folderNode)
-      return folderNode;
-
-    if (!path.length) {
-      if (target)
-        return this._domainNode(uiSourceCode, project, target, frame, projectOrigin);
-      return /** @type {!Sources.NavigatorTreeNode} */ (this._rootNode.child(project.id()));
-    }
-
-    const parentNode =
-        this._folderNode(uiSourceCode, project, target, frame, projectOrigin, path.slice(0, -1), fromSourceMap);
-    let type = fromSourceMap ? Sources.NavigatorView.Types.SourceMapFolder : Sources.NavigatorView.Types.NetworkFolder;
-    if (project.type() === Workspace.projectTypes.FileSystem)
-      type = Sources.NavigatorView.Types.FileSystemFolder;
-    const name = path[path.length - 1];
-
-    folderNode = new Sources.NavigatorFolderTreeNode(this, project, folderId, type, folderPath, name);
-    this._subfolderNodes.set(folderId, folderNode);
-    parentNode.appendChild(folderNode);
-    return folderNode;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Workspace.Project} project
-   * @param {!SDK.Target} target
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @param {string} projectOrigin
-   * @return {!Sources.NavigatorTreeNode}
-   */
-  _domainNode(uiSourceCode, project, target, frame, projectOrigin) {
-    const frameNode = this._frameNode(project, target, frame);
-    if (!this._groupByDomain)
-      return frameNode;
-    let domainNode = frameNode.child(projectOrigin);
-    if (domainNode)
-      return domainNode;
-
-    domainNode = new Sources.NavigatorGroupTreeNode(
-        this, project, projectOrigin, Sources.NavigatorView.Types.Domain,
-        this._computeProjectDisplayName(target, projectOrigin));
-    if (frame && projectOrigin === Common.ParsedURL.extractOrigin(frame.url))
-      domainNode.treeNode()._boostOrder = true;
-    frameNode.appendChild(domainNode);
-    return domainNode;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {!SDK.Target} target
-   * @param {?SDK.ResourceTreeFrame} frame
-   * @return {!Sources.NavigatorTreeNode}
-   */
-  _frameNode(project, target, frame) {
-    if (!this._groupByFrame || !frame)
-      return this._targetNode(project, target);
-
-    let frameNode = this._frameNodes.get(frame);
-    if (frameNode)
-      return frameNode;
-
-    frameNode = new Sources.NavigatorGroupTreeNode(
-        this, project, target.id() + ':' + frame.id, Sources.NavigatorView.Types.Frame, frame.displayName());
-    frameNode.setHoverCallback(hoverCallback);
-    this._frameNodes.set(frame, frameNode);
-
-    const parentFrame = frame.parentFrame || frame.crossTargetParentFrame();
-    this._frameNode(project, parentFrame ? parentFrame.resourceTreeModel().target() : target, parentFrame)
-        .appendChild(frameNode);
-    if (!parentFrame)
-      frameNode.treeNode()._boostOrder = true;
-
-    /**
-     * @param {boolean} hovered
-     */
-    function hoverCallback(hovered) {
-      if (hovered) {
-        const overlayModel = target.model(SDK.OverlayModel);
-        if (overlayModel)
-          overlayModel.highlightFrame(frame.id);
-      } else {
-        SDK.OverlayModel.hideDOMNodeHighlight();
-      }
-    }
-    return frameNode;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {!SDK.Target} target
-   * @return {!Sources.NavigatorTreeNode}
-   */
-  _targetNode(project, target) {
-    if (target === SDK.targetManager.mainTarget())
-      return this._rootNode;
-
-    let targetNode = this._rootNode.child('target:' + target.id());
-    if (!targetNode) {
-      targetNode = new Sources.NavigatorGroupTreeNode(
-          this, project, 'target:' + target.id(),
-          !target.hasBrowserCapability() ? Sources.NavigatorView.Types.Worker : Sources.NavigatorView.Types.Frame,
-          target.name());
-      this._rootNode.appendChild(targetNode);
-    }
-    return targetNode;
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @param {string} projectOrigin
-   * @return {string}
-   */
-  _computeProjectDisplayName(target, projectOrigin) {
-    const runtimeModel = target.model(SDK.RuntimeModel);
-    const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
-    for (const context of executionContexts) {
-      if (context.name && context.origin && projectOrigin.startsWith(context.origin))
-        return context.name;
-    }
-
-    if (!projectOrigin)
-      return Common.UIString('(no domain)');
-
-    const parsedURL = new Common.ParsedURL(projectOrigin);
-    const prettyURL = parsedURL.isValid ? parsedURL.host + (parsedURL.port ? (':' + parsedURL.port) : '') : '';
-
-    return (prettyURL || projectOrigin);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {boolean=} select
-   * @return {?Sources.NavigatorUISourceCodeTreeNode}
-   */
-  revealUISourceCode(uiSourceCode, select) {
-    const nodes = this._uiSourceCodeNodes.get(uiSourceCode);
-    const node = nodes.firstValue();
-    if (!node)
-      return null;
-    if (this._scriptsTree.selectedTreeElement)
-      this._scriptsTree.selectedTreeElement.deselect();
-    this._lastSelectedUISourceCode = uiSourceCode;
-    // TODO(dgozman): figure out revealing multiple.
-    node.reveal(select);
-    return node;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {boolean} focusSource
-   */
-  _sourceSelected(uiSourceCode, focusSource) {
-    this._lastSelectedUISourceCode = uiSourceCode;
-    Common.Revealer.reveal(uiSourceCode, !focusSource);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  sourceDeleted(uiSourceCode) {
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _removeUISourceCode(uiSourceCode) {
-    const nodes = this._uiSourceCodeNodes.get(uiSourceCode);
-    for (const node of nodes)
-      this._removeUISourceCodeNode(node);
-  }
-
-  /**
-   * @param {!Sources.NavigatorUISourceCodeTreeNode} node
-   */
-  _removeUISourceCodeNode(node) {
-    const uiSourceCode = node.uiSourceCode();
-    this._uiSourceCodeNodes.delete(uiSourceCode, node);
-    const project = uiSourceCode.project();
-    const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-    const frame = node.frame();
-
-    let parentNode = node.parent;
-    parentNode.removeChild(node);
-    node = parentNode;
-
-    while (node) {
-      parentNode = node.parent;
-      if (!parentNode || !node.isEmpty())
-        break;
-      if (parentNode === this._rootNode && project.type() === Workspace.projectTypes.FileSystem)
-        break;
-      if (!(node instanceof Sources.NavigatorGroupTreeNode || node instanceof Sources.NavigatorFolderTreeNode))
-        break;
-      if (node._type === Sources.NavigatorView.Types.Frame) {
-        this._discardFrame(/** @type {!SDK.ResourceTreeFrame} */ (frame));
-        break;
-      }
-
-      const folderId = this._folderNodeId(project, target, frame, uiSourceCode.origin(), node._folderPath);
-      this._subfolderNodes.delete(folderId);
-      parentNode.removeChild(node);
-      node = parentNode;
-    }
-  }
-
-  reset() {
-    for (const node of this._uiSourceCodeNodes.valuesArray())
-      node.dispose();
-
-    this._scriptsTree.removeChildren();
-    this._uiSourceCodeNodes.clear();
-    this._subfolderNodes.clear();
-    this._frameNodes.clear();
-    this._rootNode.reset();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  handleContextMenu(event) {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _renameShortcut() {
-    const node = this._scriptsTree.selectedTreeElement && this._scriptsTree.selectedTreeElement._node;
-    if (!node || !node._uiSourceCode || !node._uiSourceCode.canRename())
-      return false;
-    this.rename(node, false);
-    return true;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {string} path
-   * @param {!Workspace.UISourceCode=} uiSourceCode
-   */
-  _handleContextMenuCreate(project, path, uiSourceCode) {
-    if (uiSourceCode) {
-      const relativePath = Persistence.FileSystemWorkspaceBinding.relativePath(uiSourceCode);
-      relativePath.pop();
-      path = relativePath.join('/');
-    }
-    this.create(project, path, uiSourceCode);
-  }
-
-  /**
-   * @param {!Sources.NavigatorUISourceCodeTreeNode} node
-   */
-  _handleContextMenuRename(node) {
-    this.rename(node, false);
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {string} path
-   */
-  _handleContextMenuExclude(project, path) {
-    const shouldExclude = window.confirm(Common.UIString('Are you sure you want to exclude this folder?'));
-    if (shouldExclude) {
-      UI.startBatchUpdate();
-      project.excludeFolder(Persistence.FileSystemWorkspaceBinding.completeURL(project, path));
-      UI.endBatchUpdate();
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _handleContextMenuDelete(uiSourceCode) {
-    const shouldDelete = window.confirm(Common.UIString('Are you sure you want to delete this file?'));
-    if (shouldDelete)
-      uiSourceCode.project().deleteFile(uiSourceCode);
-  }
-
-  /**
-   * @param {!Event} event
-   * @param {!Sources.NavigatorUISourceCodeTreeNode} node
-   */
-  handleFileContextMenu(event, node) {
-    const uiSourceCode = node.uiSourceCode();
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.appendApplicableItems(uiSourceCode);
-
-    const project = uiSourceCode.project();
-    if (project.type() === Workspace.projectTypes.FileSystem) {
-      contextMenu.editSection().appendItem(
-          Common.UIString('Rename\u2026'), this._handleContextMenuRename.bind(this, node));
-      contextMenu.editSection().appendItem(
-          Common.UIString('Make a copy\u2026'), this._handleContextMenuCreate.bind(this, project, '', uiSourceCode));
-      contextMenu.editSection().appendItem(
-          Common.UIString('Delete'), this._handleContextMenuDelete.bind(this, uiSourceCode));
-    }
-
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Event} event
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  handleFolderContextMenu(event, node) {
-    const path = node._folderPath || '';
-    const project = node._project;
-
-    const contextMenu = new UI.ContextMenu(event);
-
-    Sources.NavigatorView.appendSearchItem(contextMenu, path);
-
-    const folderPath = Common.ParsedURL.urlToPlatformPath(
-        Persistence.FileSystemWorkspaceBinding.completeURL(project, path), Host.isWin());
-    contextMenu.revealSection().appendItem(
-        Common.UIString('Open folder'), () => InspectorFrontendHost.showItemInFolder(folderPath));
-    if (project.canCreateFile()) {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString('New file'), this._handleContextMenuCreate.bind(this, project, path));
-    }
-
-    if (project.canExcludeFolder(path)) {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString('Exclude folder'), this._handleContextMenuExclude.bind(this, project, path));
-    }
-
-    function removeFolder() {
-      const shouldRemove = window.confirm(Common.UIString('Are you sure you want to remove this folder?'));
-      if (shouldRemove)
-        project.remove();
-    }
-
-    if (project.type() === Workspace.projectTypes.FileSystem) {
-      Sources.NavigatorView.appendAddFolderItem(contextMenu);
-      if (node instanceof Sources.NavigatorGroupTreeNode)
-        contextMenu.defaultSection().appendItem(Common.UIString('Remove folder from workspace'), removeFolder);
-    }
-
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Sources.NavigatorUISourceCodeTreeNode} node
-   * @param {boolean} creatingNewUISourceCode
-   * @protected
-   */
-  rename(node, creatingNewUISourceCode) {
-    const uiSourceCode = node.uiSourceCode();
-    node.rename(callback.bind(this));
-
-    /**
-     * @this {Sources.NavigatorView}
-     * @param {boolean} committed
-     */
-    function callback(committed) {
-      if (!creatingNewUISourceCode)
-        return;
-      if (!committed)
-        uiSourceCode.remove();
-      else if (node._treeElement.listItemElement.hasFocus())
-        this._sourceSelected(uiSourceCode, true);
-    }
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {string} path
-   * @param {!Workspace.UISourceCode=} uiSourceCodeToCopy
-   */
-  async create(project, path, uiSourceCodeToCopy) {
-    let content = '';
-    if (uiSourceCodeToCopy)
-      content = (await uiSourceCodeToCopy.requestContent()) || '';
-    const uiSourceCode = await project.createFile(path, null, content);
-    if (!uiSourceCode)
-      return;
-    this._sourceSelected(uiSourceCode, false);
-    const node = this.revealUISourceCode(uiSourceCode, true);
-    if (node)
-      this.rename(node, true);
-  }
-
-  _groupingChanged() {
-    this.reset();
-    this._initGrouping();
-    this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
-  }
-
-  _initGrouping() {
-    this._groupByFrame = true;
-    this._groupByDomain = this._navigatorGroupByFolderSetting.get();
-    this._groupByFolder = this._groupByDomain;
-  }
-
-  _resetForTest() {
-    this.reset();
-    this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
-  }
-
-  /**
-   * @param {!SDK.ResourceTreeFrame} frame
-   */
-  _discardFrame(frame) {
-    const node = this._frameNodes.get(frame);
-    if (!node)
-      return;
-
-    if (node.parent)
-      node.parent.removeChild(node);
-    this._frameNodes.delete(frame);
-    for (const child of frame.childFrames)
-      this._discardFrame(child);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-    const targetNode = this._rootNode.child('target:' + target.id());
-    if (targetNode)
-      this._rootNode.removeChild(targetNode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _targetNameChanged(event) {
-    const target = /** @type {!SDK.Target} */ (event.data);
-    const targetNode = this._rootNode.child('target:' + target.id());
-    if (targetNode)
-      targetNode.setTitle(target.name());
-  }
-};
-
-Sources.NavigatorView.Types = {
-  Domain: 'domain',
-  File: 'file',
-  FileSystem: 'fs',
-  FileSystemFolder: 'fs-folder',
-  Frame: 'frame',
-  NetworkFolder: 'nw-folder',
-  Root: 'root',
-  SourceMapFolder: 'sm-folder',
-  Worker: 'worker'
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorFolderTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Sources.NavigatorView} navigatorView
-   * @param {string} type
-   * @param {string} title
-   * @param {function(boolean)=} hoverCallback
-   */
-  constructor(navigatorView, type, title, hoverCallback) {
-    super('', true);
-    this.listItemElement.classList.add('navigator-' + type + '-tree-item', 'navigator-folder-tree-item');
-    this._nodeType = type;
-    this.title = title;
-    this.tooltip = title;
-    this._navigatorView = navigatorView;
-    this._hoverCallback = hoverCallback;
-    let iconType = 'largeicon-navigator-folder';
-    if (type === Sources.NavigatorView.Types.Domain)
-      iconType = 'largeicon-navigator-domain';
-    else if (type === Sources.NavigatorView.Types.Frame)
-      iconType = 'largeicon-navigator-frame';
-    else if (type === Sources.NavigatorView.Types.Worker)
-      iconType = 'largeicon-navigator-worker';
-    this.setLeadingIcons([UI.Icon.create(iconType, 'icon')]);
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    this._node.populate();
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.collapse();
-    this._node.onattach();
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
-    this.listItemElement.addEventListener('mousemove', this._mouseMove.bind(this), false);
-    this.listItemElement.addEventListener('mouseleave', this._mouseLeave.bind(this), false);
-  }
-
-  /**
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  setNode(node) {
-    this._node = node;
-    const paths = [];
-    while (node && !node.isRoot()) {
-      paths.push(node._title);
-      node = node.parent;
-    }
-    paths.reverse();
-    this.tooltip = paths.join('/');
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    if (!this._node)
-      return;
-    this.select();
-    this._navigatorView.handleFolderContextMenu(event, this._node);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseMove(event) {
-    if (this._hovered || !this._hoverCallback)
-      return;
-    this._hovered = true;
-    this._hoverCallback(true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseLeave(event) {
-    if (!this._hoverCallback)
-      return;
-    this._hovered = false;
-    this._hoverCallback(false);
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorSourceTreeElement = class extends UI.TreeElement {
-  /**
-   * @param {!Sources.NavigatorView} navigatorView
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} title
-   * @param {!Sources.NavigatorUISourceCodeTreeNode} node
-   */
-  constructor(navigatorView, uiSourceCode, title, node) {
-    super('', false);
-    this._nodeType = Sources.NavigatorView.Types.File;
-    this._node = node;
-    this.title = title;
-    this.listItemElement.classList.add(
-        'navigator-' + uiSourceCode.contentType().name() + '-tree-item', 'navigator-file-tree-item');
-    this.tooltip = uiSourceCode.url();
-    this._navigatorView = navigatorView;
-    this._uiSourceCode = uiSourceCode;
-    this.updateIcon();
-  }
-
-  updateIcon() {
-    const binding = Persistence.persistence.binding(this._uiSourceCode);
-    if (binding) {
-      const container = createElementWithClass('span', 'icon-stack');
-      const icon = UI.Icon.create('largeicon-navigator-file-sync', 'icon');
-      const badge = UI.Icon.create('badge-navigator-file-sync', 'icon-badge');
-      // TODO(allada) This does not play well with dark theme. Add an actual icon and use it.
-      if (Persistence.networkPersistenceManager.project() === binding.fileSystem.project())
-        badge.style.filter = 'hue-rotate(160deg)';
-      container.appendChild(icon);
-      container.appendChild(badge);
-      container.title = Persistence.PersistenceUtils.tooltipForUISourceCode(this._uiSourceCode);
-      this.setLeadingIcons([container]);
-    } else {
-      let iconType = 'largeicon-navigator-file';
-      if (this._uiSourceCode.contentType() === Common.resourceTypes.Snippet)
-        iconType = 'largeicon-navigator-snippet';
-      const defaultIcon = UI.Icon.create(iconType, 'icon');
-      this.setLeadingIcons([defaultIcon]);
-    }
-  }
-
-  /**
-   * @return {!Workspace.UISourceCode}
-   */
-  get uiSourceCode() {
-    return this._uiSourceCode;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.listItemElement.draggable = true;
-    this.listItemElement.addEventListener('click', this._onclick.bind(this), false);
-    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
-    this.listItemElement.addEventListener('dragstart', this._ondragstart.bind(this), false);
-  }
-
-  _shouldRenameOnMouseDown() {
-    if (!this._uiSourceCode.canRename())
-      return false;
-    const isSelected = this === this.treeOutline.selectedTreeElement;
-    return isSelected && this.treeOutline.element.hasFocus() && !UI.isBeingEdited(this.treeOutline.element);
-  }
-
-  /**
-   * @override
-   */
-  selectOnMouseDown(event) {
-    if (event.which !== 1 || !this._shouldRenameOnMouseDown()) {
-      super.selectOnMouseDown(event);
-      return;
-    }
-    setTimeout(rename.bind(this), 300);
-
-    /**
-     * @this {Sources.NavigatorSourceTreeElement}
-     */
-    function rename() {
-      if (this._shouldRenameOnMouseDown())
-        this._navigatorView.rename(this._node, false);
-    }
-  }
-
-  /**
-   * @param {!DragEvent} event
-   */
-  _ondragstart(event) {
-    event.dataTransfer.setData('text/plain', this._uiSourceCode.url());
-    event.dataTransfer.effectAllowed = 'copy';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onspace() {
-    this._navigatorView._sourceSelected(this.uiSourceCode, true);
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onclick(event) {
-    this._navigatorView._sourceSelected(this.uiSourceCode, false);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondblclick(event) {
-    const middleClick = event.button === 1;
-    this._navigatorView._sourceSelected(this.uiSourceCode, !middleClick);
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  onenter() {
-    this._navigatorView._sourceSelected(this.uiSourceCode, true);
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  ondelete() {
-    this._navigatorView.sourceDeleted(this.uiSourceCode);
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleContextMenuEvent(event) {
-    this.select();
-    this._navigatorView.handleFileContextMenu(event, this._node);
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorTreeNode = class {
-  /**
-   * @param {string} id
-   * @param {string} type
-   */
-  constructor(id, type) {
-    this.id = id;
-    this._type = type;
-    /** @type {!Map.<string, !Sources.NavigatorTreeNode>} */
-    this._children = new Map();
-  }
-
-  /**
-   * @return {!UI.TreeElement}
-   */
-  treeNode() {
-    throw 'Not implemented';
-  }
-
-  dispose() {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isRoot() {
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasChildren() {
-    return true;
-  }
-
-  onattach() {
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    throw 'Not implemented';
-  }
-
-  populate() {
-    if (this.isPopulated())
-      return;
-    if (this.parent)
-      this.parent.populate();
-    this._populated = true;
-    this.wasPopulated();
-  }
-
-  wasPopulated() {
-    const children = this.children();
-    for (let i = 0; i < children.length; ++i)
-      this.treeNode().appendChild(/** @type {!UI.TreeElement} */ (children[i].treeNode()));
-  }
-
-  /**
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  didAddChild(node) {
-    if (this.isPopulated())
-      this.treeNode().appendChild(/** @type {!UI.TreeElement} */ (node.treeNode()));
-  }
-
-  /**
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  willRemoveChild(node) {
-    if (this.isPopulated())
-      this.treeNode().removeChild(/** @type {!UI.TreeElement} */ (node.treeNode()));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isPopulated() {
-    return this._populated;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEmpty() {
-    return !this._children.size;
-  }
-
-  /**
-   * @return {!Array.<!Sources.NavigatorTreeNode>}
-   */
-  children() {
-    return this._children.valuesArray();
-  }
-
-  /**
-   * @param {string} id
-   * @return {?Sources.NavigatorTreeNode}
-   */
-  child(id) {
-    return this._children.get(id) || null;
-  }
-
-  /**
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  appendChild(node) {
-    this._children.set(node.id, node);
-    node.parent = this;
-    this.didAddChild(node);
-  }
-
-  /**
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  removeChild(node) {
-    this.willRemoveChild(node);
-    this._children.remove(node.id);
-    delete node.parent;
-    node.dispose();
-  }
-
-  reset() {
-    this._children.clear();
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorRootTreeNode = class extends Sources.NavigatorTreeNode {
-  /**
-   * @param {!Sources.NavigatorView} navigatorView
-   */
-  constructor(navigatorView) {
-    super('', Sources.NavigatorView.Types.Root);
-    this._navigatorView = navigatorView;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isRoot() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {!UI.TreeElement}
-   */
-  treeNode() {
-    return this._navigatorView._scriptsTree.rootElement();
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorUISourceCodeTreeNode = class extends Sources.NavigatorTreeNode {
-  /**
-   * @param {!Sources.NavigatorView} navigatorView
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {?SDK.ResourceTreeFrame} frame
-   */
-  constructor(navigatorView, uiSourceCode, frame) {
-    super(uiSourceCode.project().id() + ':' + uiSourceCode.url(), Sources.NavigatorView.Types.File);
-    this._navigatorView = navigatorView;
-    this._uiSourceCode = uiSourceCode;
-    this._treeElement = null;
-    this._eventListeners = [];
-    this._frame = frame;
-  }
-
-  /**
-   * @return {?SDK.ResourceTreeFrame}
-   */
-  frame() {
-    return this._frame;
-  }
-
-  /**
-   * @return {!Workspace.UISourceCode}
-   */
-  uiSourceCode() {
-    return this._uiSourceCode;
-  }
-
-  /**
-   * @override
-   * @return {!UI.TreeElement}
-   */
-  treeNode() {
-    if (this._treeElement)
-      return this._treeElement;
-
-    this._treeElement = new Sources.NavigatorSourceTreeElement(this._navigatorView, this._uiSourceCode, '', this);
-    this.updateTitle();
-
-    const updateTitleBound = this.updateTitle.bind(this, undefined);
-    this._eventListeners = [
-      this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.TitleChanged, updateTitleBound),
-      this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, updateTitleBound),
-      this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted, updateTitleBound)
-    ];
-    return this._treeElement;
-  }
-
-  /**
-   * @param {boolean=} ignoreIsDirty
-   */
-  updateTitle(ignoreIsDirty) {
-    if (!this._treeElement)
-      return;
-
-    let titleText = this._uiSourceCode.displayName();
-    if (!ignoreIsDirty && this._uiSourceCode.isDirty())
-      titleText = '*' + titleText;
-
-    this._treeElement.title = titleText;
-    this._treeElement.updateIcon();
-
-    let tooltip = this._uiSourceCode.url();
-    if (this._uiSourceCode.contentType().isFromSourceMap())
-      tooltip = Common.UIString('%s (from source map)', this._uiSourceCode.displayName());
-    this._treeElement.tooltip = tooltip;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasChildren() {
-    return false;
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-    Common.EventTarget.removeEventListeners(this._eventListeners);
-  }
-
-  /**
-   * @param {boolean=} select
-   */
-  reveal(select) {
-    this.parent.populate();
-    this.parent.treeNode().expand();
-    this._treeElement.reveal(true);
-    if (select)
-      this._treeElement.select(true);
-  }
-
-  /**
-   * @param {function(boolean)=} callback
-   */
-  rename(callback) {
-    if (!this._treeElement)
-      return;
-
-    this._treeElement.listItemElement.focus();
-
-    // Tree outline should be marked as edited as well as the tree element to prevent search from starting.
-    const treeOutlineElement = this._treeElement.treeOutline.element;
-    UI.markBeingEdited(treeOutlineElement, true);
-
-    /**
-     * @param {!Element} element
-     * @param {string} newTitle
-     * @param {string} oldTitle
-     * @this {Sources.NavigatorUISourceCodeTreeNode}
-     */
-    function commitHandler(element, newTitle, oldTitle) {
-      if (newTitle !== oldTitle) {
-        this._treeElement.title = newTitle;
-        this._uiSourceCode.rename(newTitle).then(renameCallback.bind(this));
-        return;
-      }
-      afterEditing.call(this, true);
-    }
-
-    /**
-     * @param {boolean} success
-     * @this {Sources.NavigatorUISourceCodeTreeNode}
-     */
-    function renameCallback(success) {
-      if (!success) {
-        UI.markBeingEdited(treeOutlineElement, false);
-        this.updateTitle();
-        this.rename(callback);
-        return;
-      }
-      afterEditing.call(this, true);
-    }
-
-    /**
-     * @param {boolean} committed
-     * @this {Sources.NavigatorUISourceCodeTreeNode}
-     */
-    function afterEditing(committed) {
-      UI.markBeingEdited(treeOutlineElement, false);
-      this.updateTitle();
-      if (callback)
-        callback(committed);
-    }
-
-    this.updateTitle(true);
-    this._treeElement.startEditingTitle(
-        new UI.InplaceEditor.Config(commitHandler.bind(this), afterEditing.bind(this, false)));
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorFolderTreeNode = class extends Sources.NavigatorTreeNode {
-  /**
-   * @param {!Sources.NavigatorView} navigatorView
-   * @param {?Workspace.Project} project
-   * @param {string} id
-   * @param {string} type
-   * @param {string} folderPath
-   * @param {string} title
-   */
-  constructor(navigatorView, project, id, type, folderPath, title) {
-    super(id, type);
-    this._navigatorView = navigatorView;
-    this._project = project;
-    this._folderPath = folderPath;
-    this._title = title;
-  }
-
-  /**
-   * @override
-   * @return {!UI.TreeElement}
-   */
-  treeNode() {
-    if (this._treeElement)
-      return this._treeElement;
-    this._treeElement = this._createTreeElement(this._title, this);
-    this.updateTitle();
-    return this._treeElement;
-  }
-
-  updateTitle() {
-    if (!this._treeElement || this._project.type() !== Workspace.projectTypes.FileSystem)
-      return;
-    const absoluteFileSystemPath =
-        Persistence.FileSystemWorkspaceBinding.fileSystemPath(this._project.id()) + '/' + this._folderPath;
-    const hasMappedFiles = Persistence.persistence.filePathHasBindings(absoluteFileSystemPath);
-    this._treeElement.listItemElement.classList.toggle('has-mapped-files', hasMappedFiles);
-  }
-
-  /**
-   * @return {!UI.TreeElement}
-   */
-  _createTreeElement(title, node) {
-    if (this._project.type() !== Workspace.projectTypes.FileSystem) {
-      try {
-        title = decodeURI(title);
-      } catch (e) {
-      }
-    }
-    const treeElement = new Sources.NavigatorFolderTreeElement(this._navigatorView, this._type, title);
-    treeElement.setNode(node);
-    return treeElement;
-  }
-
-  /**
-   * @override
-   */
-  wasPopulated() {
-    if (!this._treeElement || this._treeElement._node !== this)
-      return;
-    this._addChildrenRecursive();
-  }
-
-  _addChildrenRecursive() {
-    const children = this.children();
-    for (let i = 0; i < children.length; ++i) {
-      const child = children[i];
-      this.didAddChild(child);
-      if (child instanceof Sources.NavigatorFolderTreeNode)
-        child._addChildrenRecursive();
-    }
-  }
-
-  _shouldMerge(node) {
-    return this._type !== Sources.NavigatorView.Types.Domain && node instanceof Sources.NavigatorFolderTreeNode;
-  }
-
-  /**
-   * @param {!Sources.NavigatorTreeNode} node
-   * @override
-   */
-  didAddChild(node) {
-    function titleForNode(node) {
-      return node._title;
-    }
-
-    if (!this._treeElement)
-      return;
-
-    let children = this.children();
-
-    if (children.length === 1 && this._shouldMerge(node)) {
-      node._isMerged = true;
-      this._treeElement.title = this._treeElement.title + '/' + node._title;
-      node._treeElement = this._treeElement;
-      this._treeElement.setNode(node);
-      return;
-    }
-
-    let oldNode;
-    if (children.length === 2)
-      oldNode = children[0] !== node ? children[0] : children[1];
-    if (oldNode && oldNode._isMerged) {
-      delete oldNode._isMerged;
-      const mergedToNodes = [];
-      mergedToNodes.push(this);
-      let treeNode = this;
-      while (treeNode._isMerged) {
-        treeNode = treeNode.parent;
-        mergedToNodes.push(treeNode);
-      }
-      mergedToNodes.reverse();
-      const titleText = mergedToNodes.map(titleForNode).join('/');
-
-      const nodes = [];
-      treeNode = oldNode;
-      do {
-        nodes.push(treeNode);
-        children = treeNode.children();
-        treeNode = children.length === 1 ? children[0] : null;
-      } while (treeNode && treeNode._isMerged);
-
-      if (!this.isPopulated()) {
-        this._treeElement.title = titleText;
-        this._treeElement.setNode(this);
-        for (let i = 0; i < nodes.length; ++i) {
-          delete nodes[i]._treeElement;
-          delete nodes[i]._isMerged;
-        }
-        return;
-      }
-      const oldTreeElement = this._treeElement;
-      const treeElement = this._createTreeElement(titleText, this);
-      for (let i = 0; i < mergedToNodes.length; ++i)
-        mergedToNodes[i]._treeElement = treeElement;
-      oldTreeElement.parent.appendChild(treeElement);
-
-      oldTreeElement.setNode(nodes[nodes.length - 1]);
-      oldTreeElement.title = nodes.map(titleForNode).join('/');
-      oldTreeElement.parent.removeChild(oldTreeElement);
-      this._treeElement.appendChild(oldTreeElement);
-      if (oldTreeElement.expanded)
-        treeElement.expand();
-    }
-    if (this.isPopulated())
-      this._treeElement.appendChild(node.treeNode());
-  }
-
-  /**
-   * @override
-   * @param {!Sources.NavigatorTreeNode} node
-   */
-  willRemoveChild(node) {
-    if (node._isMerged || !this.isPopulated())
-      return;
-    this._treeElement.removeChild(node._treeElement);
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.NavigatorGroupTreeNode = class extends Sources.NavigatorTreeNode {
-  /**
-   * @param {!Sources.NavigatorView} navigatorView
-   * @param {!Workspace.Project} project
-   * @param {string} id
-   * @param {string} type
-   * @param {string} title
-   */
-  constructor(navigatorView, project, id, type, title) {
-    super(id, type);
-    this._project = project;
-    this._navigatorView = navigatorView;
-    this._title = title;
-    this.populate();
-  }
-
-  /**
-   * @param {function(boolean)} hoverCallback
-   */
-  setHoverCallback(hoverCallback) {
-    this._hoverCallback = hoverCallback;
-  }
-
-  /**
-   * @override
-   * @return {!UI.TreeElement}
-   */
-  treeNode() {
-    if (this._treeElement)
-      return this._treeElement;
-    this._treeElement =
-        new Sources.NavigatorFolderTreeElement(this._navigatorView, this._type, this._title, this._hoverCallback);
-    this._treeElement.setNode(this);
-    return this._treeElement;
-  }
-
-  /**
-   * @override
-   */
-  onattach() {
-    this.updateTitle();
-  }
-
-  updateTitle() {
-    if (!this._treeElement || this._project.type() !== Workspace.projectTypes.FileSystem)
-      return;
-    const fileSystemPath = Persistence.FileSystemWorkspaceBinding.fileSystemPath(this._project.id());
-    const wasActive = this._treeElement.listItemElement.classList.contains('has-mapped-files');
-    const isActive = Persistence.persistence.filePathHasBindings(fileSystemPath);
-    if (wasActive === isActive)
-      return;
-    this._treeElement.listItemElement.classList.toggle('has-mapped-files', isActive);
-    if (this._treeElement.childrenListElement.hasFocus())
-      return;
-    if (isActive)
-      this._treeElement.expand();
-    else
-      this._treeElement.collapse();
-  }
-
-  /**
-   * @param {string} title
-   * @override
-   */
-  setTitle(title) {
-    this._title = title;
-    if (this._treeElement)
-      this._treeElement.title = this._title;
-  }
-};
diff --git a/front_end/sources/OpenFileQuickOpen.js b/front_end/sources/OpenFileQuickOpen.js
deleted file mode 100644
index 39dfe70..0000000
--- a/front_end/sources/OpenFileQuickOpen.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-Sources.OpenFileQuickOpen = class extends Sources.FilteredUISourceCodeListProvider {
-  /**
-   * @override
-   */
-  attach() {
-    this.setDefaultScores(Sources.SourcesView.defaultUISourceCodeScores());
-    super.attach();
-  }
-
-  /**
-   * @override
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   * @param {number=} lineNumber
-   * @param {number=} columnNumber
-   */
-  uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber) {
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.SelectFileFromFilePicker);
-
-    if (!uiSourceCode)
-      return;
-    if (typeof lineNumber === 'number')
-      Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
-    else
-      Common.Revealer.reveal(uiSourceCode);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  filterProject(project) {
-    return !project.isServiceProject();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  renderAsTwoRows() {
-    return true;
-  }
-};
diff --git a/front_end/sources/OutlineQuickOpen.js b/front_end/sources/OutlineQuickOpen.js
deleted file mode 100644
index f5a525c..0000000
--- a/front_end/sources/OutlineQuickOpen.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Sources.OutlineQuickOpen = class extends QuickOpen.FilteredListWidget.Provider {
-  constructor() {
-    super();
-    this._items = [];
-    this._active = false;
-  }
-
-  /**
-   * @override
-   */
-  attach() {
-    this._items = [];
-    this._active = false;
-
-    const uiSourceCode = this._currentUISourceCode();
-    if (uiSourceCode) {
-      this._active = Formatter.formatterWorkerPool().outlineForMimetype(
-          uiSourceCode.workingCopy(), uiSourceCode.contentType().canonicalMimeType(),
-          this._didBuildOutlineChunk.bind(this));
-    }
-  }
-
-  /**
-   * @param {boolean} isLastChunk
-   * @param {!Array<!Formatter.FormatterWorkerPool.OutlineItem>} items
-   */
-  _didBuildOutlineChunk(isLastChunk, items) {
-    this._items.push(...items);
-    this.refresh();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  itemCount() {
-    return this._items.length;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @return {string}
-   */
-  itemKeyAt(itemIndex) {
-    const item = this._items[itemIndex];
-    return item.title + (item.subtitle ? item.subtitle : '');
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @return {number}
-   */
-  itemScoreAt(itemIndex, query) {
-    const item = this._items[itemIndex];
-    const methodName = query.split('(')[0];
-    if (methodName.toLowerCase() === item.title.toLowerCase())
-      return 1 / (1 + item.line);
-    return -item.line - 1;
-  }
-
-  /**
-   * @override
-   * @param {number} itemIndex
-   * @param {string} query
-   * @param {!Element} titleElement
-   * @param {!Element} subtitleElement
-   */
-  renderItem(itemIndex, query, titleElement, subtitleElement) {
-    const item = this._items[itemIndex];
-    titleElement.textContent = item.title + (item.subtitle ? item.subtitle : '');
-    QuickOpen.FilteredListWidget.highlightRanges(titleElement, query);
-    subtitleElement.textContent = ':' + (item.line + 1);
-  }
-
-  /**
-   * @override
-   * @param {?number} itemIndex
-   * @param {string} promptValue
-   */
-  selectItem(itemIndex, promptValue) {
-    if (itemIndex === null)
-      return;
-    const uiSourceCode = this._currentUISourceCode();
-    if (!uiSourceCode)
-      return;
-    const lineNumber = this._items[itemIndex].line;
-    if (!isNaN(lineNumber) && lineNumber >= 0)
-      Common.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, this._items[itemIndex].column));
-  }
-
-
-  /**
-   * @return {?Workspace.UISourceCode}
-   */
-  _currentUISourceCode() {
-    const sourcesView = UI.context.flavor(Sources.SourcesView);
-    if (!sourcesView)
-      return null;
-    return sourcesView.currentUISourceCode();
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  notFoundText() {
-    if (!this._currentUISourceCode())
-      return Common.UIString('No file selected.');
-    if (!this._active)
-      return Common.UIString('Open a JavaScript or CSS file to see symbols');
-    return Common.UIString('No results found');
-  }
-};
diff --git a/front_end/sources/ScopeChainSidebarPane.js b/front_end/sources/ScopeChainSidebarPane.js
deleted file mode 100644
index f1ac922..0000000
--- a/front_end/sources/ScopeChainSidebarPane.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ContextFlavorListener}
- * @unrestricted
- */
-Sources.ScopeChainSidebarPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('sources/scopeChainSidebarPane.css');
-    this._expandController = new ObjectUI.ObjectPropertiesSectionExpandController();
-    this._linkifier = new Components.Linkifier();
-    this._update();
-  }
-
-  /**
-   * @override
-   * @param {?Object} object
-   */
-  flavorChanged(object) {
-    this._update();
-  }
-
-  _update() {
-    const callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-    const details = UI.context.flavor(SDK.DebuggerPausedDetails);
-    this._linkifier.reset();
-    Sources.SourceMapNamesResolver.resolveThisObject(callFrame).then(this._innerUpdate.bind(this, details, callFrame));
-  }
-
-  /**
-   * @param {?SDK.DebuggerPausedDetails} details
-   * @param {?SDK.DebuggerModel.CallFrame} callFrame
-   * @param {?SDK.RemoteObject} thisObject
-   */
-  _innerUpdate(details, callFrame, thisObject) {
-    this.contentElement.removeChildren();
-
-    if (!details || !callFrame) {
-      const infoElement = createElement('div');
-      infoElement.className = 'gray-info-message';
-      infoElement.textContent = Common.UIString('Not paused');
-      this.contentElement.appendChild(infoElement);
-      return;
-    }
-
-    let foundLocalScope = false;
-    const scopeChain = callFrame.scopeChain();
-    for (let i = 0; i < scopeChain.length; ++i) {
-      const scope = scopeChain[i];
-      let title = scope.typeName();
-      let emptyPlaceholder = null;
-      const extraProperties = [];
-
-      switch (scope.type()) {
-        case Protocol.Debugger.ScopeType.Local:
-          foundLocalScope = true;
-          emptyPlaceholder = Common.UIString('No variables');
-          if (thisObject)
-            extraProperties.push(new SDK.RemoteObjectProperty('this', thisObject));
-          if (i === 0) {
-            const exception = details.exception();
-            if (exception) {
-              extraProperties.push(new SDK.RemoteObjectProperty(
-                  Common.UIString('Exception'), exception, undefined, undefined, undefined, undefined, undefined,
-                  true));
-            }
-            const returnValue = callFrame.returnValue();
-            if (returnValue) {
-              extraProperties.push(new SDK.RemoteObjectProperty(
-                  Common.UIString('Return value'), returnValue, undefined, undefined, undefined, undefined, undefined,
-                  true, callFrame.setReturnValue.bind(callFrame)));
-            }
-          }
-          break;
-        case Protocol.Debugger.ScopeType.Closure:
-          const scopeName = scope.name();
-          if (scopeName)
-            title = Common.UIString('Closure (%s)', UI.beautifyFunctionName(scopeName));
-          else
-            title = Common.UIString('Closure');
-          emptyPlaceholder = Common.UIString('No variables');
-          break;
-      }
-
-      let subtitle = scope.description();
-      if (!title || title === subtitle)
-        subtitle = undefined;
-
-      const titleElement = createElementWithClass('div', 'scope-chain-sidebar-pane-section-header');
-      titleElement.createChild('div', 'scope-chain-sidebar-pane-section-subtitle').textContent = subtitle;
-      titleElement.createChild('div', 'scope-chain-sidebar-pane-section-title').textContent = title;
-
-      const section = new ObjectUI.ObjectPropertiesSection(
-          Sources.SourceMapNamesResolver.resolveScopeInObject(scope), titleElement, this._linkifier, emptyPlaceholder,
-          true, extraProperties);
-      this._expandController.watchSection(title + (subtitle ? ':' + subtitle : ''), section);
-
-      if (scope.type() === Protocol.Debugger.ScopeType.Global)
-        section.objectTreeElement().collapse();
-      else if (!foundLocalScope || scope.type() === Protocol.Debugger.ScopeType.Local)
-        section.objectTreeElement().expand();
-
-      section.element.classList.add('scope-chain-sidebar-pane-section');
-      this.contentElement.appendChild(section.element);
-    }
-    this._sidebarPaneUpdatedForTest();
-  }
-
-  _sidebarPaneUpdatedForTest() {
-  }
-};
-
-Sources.ScopeChainSidebarPane._pathSymbol = Symbol('path');
diff --git a/front_end/sources/ScriptFormatterEditorAction.js b/front_end/sources/ScriptFormatterEditorAction.js
deleted file mode 100644
index 9706b77..0000000
--- a/front_end/sources/ScriptFormatterEditorAction.js
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Sources.SourcesView.EditorAction}
- * @unrestricted
- */
-Sources.ScriptFormatterEditorAction = class {
-  constructor() {
-    /** @type {!Set<string>} */
-    this._pathsToFormatOnLoad = new Set();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorSelected(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._updateButton(uiSourceCode);
-
-    if (this._isFormatableScript(uiSourceCode) && this._pathsToFormatOnLoad.has(uiSourceCode.url()) &&
-        !Sources.sourceFormatter.hasFormatted(uiSourceCode))
-      this._showFormatted(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorClosed(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    const wasSelected = /** @type {boolean} */ (event.data.wasSelected);
-
-    if (wasSelected)
-      this._updateButton(null);
-    const original = Sources.sourceFormatter.discardFormattedUISourceCode(uiSourceCode);
-    if (original)
-      this._pathsToFormatOnLoad.delete(original.url());
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   */
-  _updateButton(uiSourceCode) {
-    this._button.element.classList.toggle('hidden', !this._isFormatableScript(uiSourceCode));
-  }
-
-  /**
-   * @override
-   * @param {!Sources.SourcesView} sourcesView
-   * @return {!UI.ToolbarButton}
-   */
-  button(sourcesView) {
-    if (this._button)
-      return this._button;
-
-    this._sourcesView = sourcesView;
-    this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
-    this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
-
-    this._button = new UI.ToolbarButton(Common.UIString('Pretty print'), 'largeicon-pretty-print');
-    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._toggleFormatScriptSource, this);
-    this._updateButton(sourcesView.currentUISourceCode());
-
-    return this._button;
-  }
-
-  /**
-   * @param {?Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  _isFormatableScript(uiSourceCode) {
-    if (!uiSourceCode)
-      return false;
-    if (uiSourceCode.project().canSetFileContent())
-      return false;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.Formatter)
-      return false;
-    if (Persistence.persistence.binding(uiSourceCode))
-      return false;
-    return uiSourceCode.contentType().hasScripts();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _toggleFormatScriptSource(event) {
-    const uiSourceCode = this._sourcesView.currentUISourceCode();
-    if (!this._isFormatableScript(uiSourceCode))
-      return;
-    this._pathsToFormatOnLoad.add(uiSourceCode.url());
-    this._showFormatted(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  async _showFormatted(uiSourceCode) {
-    const formatData = await Sources.sourceFormatter.format(uiSourceCode);
-    if (uiSourceCode !== this._sourcesView.currentUISourceCode())
-      return;
-    const sourceFrame = this._sourcesView.viewForFile(uiSourceCode);
-    let start = [0, 0];
-    if (sourceFrame) {
-      const selection = sourceFrame.selection();
-      start = formatData.mapping.originalToFormatted(selection.startLine, selection.startColumn);
-    }
-    this._sourcesView.showSourceLocation(formatData.formattedSourceCode, start[0], start[1]);
-  }
-};
diff --git a/front_end/sources/SearchSourcesView.js b/front_end/sources/SearchSourcesView.js
deleted file mode 100644
index a6c0a3c..0000000
--- a/front_end/sources/SearchSourcesView.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Sources.SearchSourcesView = class extends Search.SearchView {
-  constructor() {
-    super('sources');
-  }
-
-  /**
-   * @param {string} query
-   * @param {boolean=} searchImmediately
-   * @return {!Promise}
-   */
-  static async openSearch(query, searchImmediately) {
-    const view = UI.viewManager.view('sources.search-sources-tab');
-    // Deliberately use target location name so that it could be changed
-    // based on the setting later.
-    const location = await UI.viewManager.resolveLocation('drawer-view');
-    location.appendView(view);
-    await UI.viewManager.revealView(/** @type {!UI.View} */ (view));
-    const widget = /** @type {!Search.SearchView} */ (await view.widget());
-    widget.toggle(query, !!searchImmediately);
-    return widget;
-  }
-
-  /**
-   * @override
-   * @return {!Search.SearchScope}
-   */
-  createScope() {
-    return new Sources.SourcesSearchScope();
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Sources.SearchSourcesView.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    this._showSearch();
-    return true;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _showSearch() {
-    const selection = UI.inspectorView.element.window().getSelection();
-    let queryCandidate = '';
-    if (selection.rangeCount)
-      queryCandidate = selection.toString().replace(/\r?\n.*/, '');
-
-    return Sources.SearchSourcesView.openSearch(queryCandidate);
-  }
-};
diff --git a/front_end/sources/SimpleHistoryManager.js b/front_end/sources/SimpleHistoryManager.js
deleted file mode 100644
index eb1ca56..0000000
--- a/front_end/sources/SimpleHistoryManager.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-Sources.HistoryEntry = function() {};
-
-Sources.HistoryEntry.prototype = {
-  /**
-   * @return {boolean}
-   */
-  valid() {},
-
-  reveal() {}
-};
-
-/**
- * @unrestricted
- */
-Sources.SimpleHistoryManager = class {
-  /**
-   * @param {number} historyDepth
-   */
-  constructor(historyDepth) {
-    this._entries = [];
-    this._activeEntryIndex = -1;
-    this._coalescingReadonly = 0;
-    this._historyDepth = historyDepth;
-  }
-
-  readOnlyLock() {
-    ++this._coalescingReadonly;
-  }
-
-  releaseReadOnlyLock() {
-    --this._coalescingReadonly;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  readOnly() {
-    return !!this._coalescingReadonly;
-  }
-
-  /**
-   * @param {function(!Sources.HistoryEntry):boolean} filterOutCallback
-   */
-  filterOut(filterOutCallback) {
-    if (this.readOnly())
-      return;
-    const filteredEntries = [];
-    let removedBeforeActiveEntry = 0;
-    for (let i = 0; i < this._entries.length; ++i) {
-      if (!filterOutCallback(this._entries[i]))
-        filteredEntries.push(this._entries[i]);
-      else if (i <= this._activeEntryIndex)
-        ++removedBeforeActiveEntry;
-    }
-    this._entries = filteredEntries;
-    this._activeEntryIndex = Math.max(0, this._activeEntryIndex - removedBeforeActiveEntry);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  empty() {
-    return !this._entries.length;
-  }
-
-  /**
-   * @return {?Sources.HistoryEntry}
-   */
-  active() {
-    return this.empty() ? null : this._entries[this._activeEntryIndex];
-  }
-
-  /**
-   * @param {!Sources.HistoryEntry} entry
-   */
-  push(entry) {
-    if (this.readOnly())
-      return;
-    if (!this.empty())
-      this._entries.splice(this._activeEntryIndex + 1);
-    this._entries.push(entry);
-    if (this._entries.length > this._historyDepth)
-      this._entries.shift();
-    this._activeEntryIndex = this._entries.length - 1;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  rollback() {
-    if (this.empty())
-      return false;
-
-    let revealIndex = this._activeEntryIndex - 1;
-    while (revealIndex >= 0 && !this._entries[revealIndex].valid())
-      --revealIndex;
-    if (revealIndex < 0)
-      return false;
-
-    this.readOnlyLock();
-    this._entries[revealIndex].reveal();
-    this.releaseReadOnlyLock();
-
-    this._activeEntryIndex = revealIndex;
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  rollover() {
-    let revealIndex = this._activeEntryIndex + 1;
-
-    while (revealIndex < this._entries.length && !this._entries[revealIndex].valid())
-      ++revealIndex;
-    if (revealIndex >= this._entries.length)
-      return false;
-
-    this.readOnlyLock();
-    this._entries[revealIndex].reveal();
-    this.releaseReadOnlyLock();
-
-    this._activeEntryIndex = revealIndex;
-    return true;
-  }
-};
diff --git a/front_end/sources/SnippetsPlugin.js b/front_end/sources/SnippetsPlugin.js
deleted file mode 100644
index cb03031..0000000
--- a/front_end/sources/SnippetsPlugin.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Sources.UISourceCodeFrame.Plugin}
- */
-Sources.SnippetsPlugin = class {
-  /**
-   * @param {!SourceFrame.SourcesTextEditor} textEditor
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  constructor(textEditor, uiSourceCode) {
-    this._textEditor = textEditor;
-    this._uiSourceCode = uiSourceCode;
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  static accepts(uiSourceCode) {
-    return uiSourceCode.project().type() === Workspace.projectTypes.Snippets;
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  leftToolbarItems() {
-    return [];
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  rightToolbarItems() {
-    const runSnippet = UI.Toolbar.createActionButtonForId('debugger.run-snippet');
-    runSnippet.setText(Host.isMac() ? Common.UIString('\u2318+Enter') : Common.UIString('Ctrl+Enter'));
-
-    return [runSnippet];
-  }
-
-  /**
-   * @override
-   */
-  dispose() {
-  }
-};
diff --git a/front_end/sources/SourceFormatter.js b/front_end/sources/SourceFormatter.js
deleted file mode 100644
index 527fe64..0000000
--- a/front_end/sources/SourceFormatter.js
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Sources.SourceFormatData = class {
-  /**
-   * @param {!Workspace.UISourceCode} originalSourceCode
-   * @param {!Workspace.UISourceCode} formattedSourceCode
-   * @param {!Formatter.FormatterSourceMapping} mapping
-   */
-  constructor(originalSourceCode, formattedSourceCode, mapping) {
-    this.originalSourceCode = originalSourceCode;
-    this.formattedSourceCode = formattedSourceCode;
-    this.mapping = mapping;
-  }
-
-  originalPath() {
-    return this.originalSourceCode.project().id() + ':' + this.originalSourceCode.url();
-  }
-
-  /**
-   * @param {!Object} object
-   * @return {?Sources.SourceFormatData}
-   */
-  static _for(object) {
-    return object[Sources.SourceFormatData._formatDataSymbol];
-  }
-};
-
-Sources.SourceFormatData._formatDataSymbol = Symbol('formatData');
-
-Sources.SourceFormatter = class {
-  constructor() {
-    this._projectId = 'formatter:';
-    this._project = new Bindings.ContentProviderBasedProject(
-        Workspace.workspace, this._projectId, Workspace.projectTypes.Formatter, 'formatter',
-        true /* isServiceProject */);
-
-    /** @type {!Map<!Workspace.UISourceCode, !{promise: !Promise<!Sources.SourceFormatData>, formatData: ?Sources.SourceFormatData}>} */
-    this._formattedSourceCodes = new Map();
-    this._scriptMapping = new Sources.SourceFormatter.ScriptMapping();
-    this._styleMapping = new Sources.SourceFormatter.StyleMapping();
-    Workspace.workspace.addEventListener(
-        Workspace.Workspace.Events.UISourceCodeRemoved, this._onUISourceCodeRemoved, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onUISourceCodeRemoved(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
-    if (cacheEntry && cacheEntry.formatData)
-      this._discardFormatData(cacheEntry.formatData);
-    this._formattedSourceCodes.remove(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} formattedUISourceCode
-   * @return {?Workspace.UISourceCode}
-   */
-  discardFormattedUISourceCode(formattedUISourceCode) {
-    const formatData = Sources.SourceFormatData._for(formattedUISourceCode);
-    if (!formatData)
-      return null;
-    this._discardFormatData(formatData);
-    this._formattedSourceCodes.remove(formatData.originalSourceCode);
-    return formatData.originalSourceCode;
-  }
-
-  /**
-   * @param {!Sources.SourceFormatData} formatData
-   */
-  _discardFormatData(formatData) {
-    delete formatData.formattedSourceCode[Sources.SourceFormatData._formatDataSymbol];
-    this._scriptMapping._setSourceMappingEnabled(formatData, false);
-    this._styleMapping._setSourceMappingEnabled(formatData, false);
-    this._project.removeFile(formatData.formattedSourceCode.url());
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  hasFormatted(uiSourceCode) {
-    return this._formattedSourceCodes.has(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<!Sources.SourceFormatData>}
-   */
-  async format(uiSourceCode) {
-    const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
-    if (cacheEntry)
-      return cacheEntry.promise;
-
-    let fulfillFormatPromise;
-    const resultPromise = new Promise(fulfill => {
-      fulfillFormatPromise = fulfill;
-    });
-    this._formattedSourceCodes.set(uiSourceCode, {promise: resultPromise, formatData: null});
-    const content = await uiSourceCode.requestContent();
-    // ------------ ASYNC ------------
-    Formatter.Formatter.format(
-        uiSourceCode.contentType(), uiSourceCode.mimeType(), content || '', formatDone.bind(this));
-    return resultPromise;
-
-    /**
-     * @this Sources.SourceFormatter
-     * @param {string} formattedContent
-     * @param {!Formatter.FormatterSourceMapping} formatterMapping
-     */
-    function formatDone(formattedContent, formatterMapping) {
-      const cacheEntry = this._formattedSourceCodes.get(uiSourceCode);
-      if (!cacheEntry || cacheEntry.promise !== resultPromise)
-        return;
-      let formattedURL;
-      let count = 0;
-      let suffix = '';
-      do {
-        formattedURL = `${uiSourceCode.url()}:formatted${suffix}`;
-        suffix = `:${count++}`;
-      } while (this._project.uiSourceCodeForURL(formattedURL));
-      const contentProvider =
-          Common.StaticContentProvider.fromString(formattedURL, uiSourceCode.contentType(), formattedContent);
-      const formattedUISourceCode =
-          this._project.addContentProvider(formattedURL, contentProvider, uiSourceCode.mimeType());
-      const formatData = new Sources.SourceFormatData(uiSourceCode, formattedUISourceCode, formatterMapping);
-      formattedUISourceCode[Sources.SourceFormatData._formatDataSymbol] = formatData;
-      this._scriptMapping._setSourceMappingEnabled(formatData, true);
-      this._styleMapping._setSourceMappingEnabled(formatData, true);
-      cacheEntry.formatData = formatData;
-
-      for (const decoration of uiSourceCode.allDecorations()) {
-        const range = decoration.range();
-        const startLocation = formatterMapping.originalToFormatted(range.startLine, range.startColumn);
-        const endLocation = formatterMapping.originalToFormatted(range.endLine, range.endColumn);
-
-        formattedUISourceCode.addDecoration(
-            new TextUtils.TextRange(startLocation[0], startLocation[1], endLocation[0], endLocation[1]),
-            /** @type {string} */ (decoration.type()), decoration.data());
-      }
-
-      fulfillFormatPromise(formatData);
-    }
-  }
-};
-
-/**
- * @implements {Bindings.DebuggerSourceMapping}
- */
-Sources.SourceFormatter.ScriptMapping = class {
-  constructor() {
-    Bindings.debuggerWorkspaceBinding.addSourceMapping(this);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel.Location} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const script = rawLocation.script();
-    const formatData = script && Sources.SourceFormatData._for(script);
-    if (!formatData)
-      return null;
-    const lineNumber = rawLocation.lineNumber;
-    const columnNumber = rawLocation.columnNumber || 0;
-    const formattedLocation = formatData.mapping.originalToFormatted(lineNumber, columnNumber);
-    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?SDK.DebuggerModel.Location}
-   */
-  uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
-    const formatData = Sources.SourceFormatData._for(uiSourceCode);
-    if (!formatData)
-      return null;
-    const originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
-    const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
-    if (!scripts.length)
-      return null;
-    return scripts[0].debuggerModel.createRawLocation(scripts[0], originalLocation[0], originalLocation[1]);
-  }
-
-  /**
-   * @param {!Sources.SourceFormatData} formatData
-   * @param {boolean} enabled
-   */
-  _setSourceMappingEnabled(formatData, enabled) {
-    const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
-    if (!scripts.length)
-      return;
-    if (enabled) {
-      for (const script of scripts)
-        script[Sources.SourceFormatData._formatDataSymbol] = formatData;
-    } else {
-      for (const script of scripts)
-        delete script[Sources.SourceFormatData._formatDataSymbol];
-    }
-    for (const script of scripts)
-      Bindings.debuggerWorkspaceBinding.updateLocations(script);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Array<!SDK.Script>}
-   */
-  _scriptsForUISourceCode(uiSourceCode) {
-    if (uiSourceCode.contentType() === Common.resourceTypes.Document) {
-      const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
-      const debuggerModel = target && target.model(SDK.DebuggerModel);
-      if (debuggerModel) {
-        const scripts = debuggerModel.scriptsForSourceURL(uiSourceCode.url())
-                            .filter(script => script.isInlineScript() && !script.hasSourceURL);
-        return scripts;
-      }
-    }
-    if (uiSourceCode.contentType().isScript()) {
-      const rawLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, 0, 0);
-      if (rawLocation)
-        return [rawLocation.script()];
-    }
-    return [];
-  }
-};
-
-/**
- * @implements {Bindings.CSSWorkspaceBinding.SourceMapping}
- */
-Sources.SourceFormatter.StyleMapping = class {
-  constructor() {
-    Bindings.cssWorkspaceBinding.addSourceMapping(this);
-    this._headersSymbol = Symbol('Sources.SourceFormatter.StyleMapping._headersSymbol');
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CSSLocation} rawLocation
-   * @return {?Workspace.UILocation}
-   */
-  rawLocationToUILocation(rawLocation) {
-    const styleHeader = rawLocation.header();
-    const formatData = styleHeader && Sources.SourceFormatData._for(styleHeader);
-    if (!formatData)
-      return null;
-    const formattedLocation =
-        formatData.mapping.originalToFormatted(rawLocation.lineNumber, rawLocation.columnNumber || 0);
-    return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UILocation} uiLocation
-   * @return {!Array<!SDK.CSSLocation>}
-   */
-  uiLocationToRawLocations(uiLocation) {
-    const formatData = Sources.SourceFormatData._for(uiLocation.uiSourceCode);
-    if (!formatData)
-      return [];
-    const originalLocation = formatData.mapping.formattedToOriginal(uiLocation.lineNumber, uiLocation.columnNumber);
-    const headers = formatData.originalSourceCode[this._headersSymbol];
-    return headers.map(header => new SDK.CSSLocation(header, originalLocation[0], originalLocation[1]));
-  }
-
-  /**
-   * @param {!Sources.SourceFormatData} formatData
-   * @param {boolean} enable
-   */
-  _setSourceMappingEnabled(formatData, enable) {
-    const original = formatData.originalSourceCode;
-    const rawLocations = Bindings.cssWorkspaceBinding.uiLocationToRawLocations(original.uiLocation(0, 0));
-    const headers = rawLocations.map(rawLocation => rawLocation.header()).filter(header => !!header);
-    if (!headers.length)
-      return;
-    if (enable) {
-      original[this._headersSymbol] = headers;
-      headers.forEach(header => header[Sources.SourceFormatData._formatDataSymbol] = formatData);
-    } else {
-      original[this._headersSymbol] = null;
-      headers.forEach(header => delete header[Sources.SourceFormatData._formatDataSymbol]);
-    }
-    headers.forEach(header => Bindings.cssWorkspaceBinding.updateLocations(header));
-  }
-};
-
-Sources.sourceFormatter = new Sources.SourceFormatter();
diff --git a/front_end/sources/SourceMapNamesResolver.js b/front_end/sources/SourceMapNamesResolver.js
deleted file mode 100644
index 2990a5e..0000000
--- a/front_end/sources/SourceMapNamesResolver.js
+++ /dev/null
@@ -1,573 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Sources.SourceMapNamesResolver = {};
-
-Sources.SourceMapNamesResolver._cachedMapSymbol = Symbol('cache');
-Sources.SourceMapNamesResolver._cachedIdentifiersSymbol = Symbol('cachedIdentifiers');
-
-/**
- * @unrestricted
- */
-Sources.SourceMapNamesResolver.Identifier = class {
-  /**
-   * @param {string} name
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   */
-  constructor(name, lineNumber, columnNumber) {
-    this.name = name;
-    this.lineNumber = lineNumber;
-    this.columnNumber = columnNumber;
-  }
-};
-
-/**
- * @param {!SDK.DebuggerModel.Scope} scope
- * @return {!Promise<!Array<!Sources.SourceMapNamesResolver.Identifier>>}
- */
-Sources.SourceMapNamesResolver._scopeIdentifiers = function(scope) {
-  const startLocation = scope.startLocation();
-  const endLocation = scope.endLocation();
-
-  if (scope.type() === Protocol.Debugger.ScopeType.Global || !startLocation || !endLocation ||
-      !startLocation.script() || !startLocation.script().sourceMapURL ||
-      (startLocation.script() !== endLocation.script()))
-    return Promise.resolve(/** @type {!Array<!Sources.SourceMapNamesResolver.Identifier>}*/ ([]));
-
-  const script = startLocation.script();
-  return script.requestContent().then(onContent);
-
-  /**
-   * @param {?string} content
-   * @return {!Promise<!Array<!Sources.SourceMapNamesResolver.Identifier>>}
-   */
-  function onContent(content) {
-    if (!content)
-      return Promise.resolve(/** @type {!Array<!Sources.SourceMapNamesResolver.Identifier>}*/ ([]));
-
-    const text = new TextUtils.Text(content);
-    const scopeRange = new TextUtils.TextRange(
-        startLocation.lineNumber, startLocation.columnNumber, endLocation.lineNumber, endLocation.columnNumber);
-    const scopeText = text.extract(scopeRange);
-    const scopeStart = text.toSourceRange(scopeRange).offset;
-    const prefix = 'function fui';
-    return Formatter.formatterWorkerPool()
-        .javaScriptIdentifiers(prefix + scopeText)
-        .then(onIdentifiers.bind(null, text, scopeStart, prefix));
-  }
-
-  /**
-   * @param {!TextUtils.Text} text
-   * @param {number} scopeStart
-   * @param {string} prefix
-   * @param {!Array<!{name: string, offset: number}>} identifiers
-   * @return {!Array<!Sources.SourceMapNamesResolver.Identifier>}
-   */
-  function onIdentifiers(text, scopeStart, prefix, identifiers) {
-    const result = [];
-    const cursor = new TextUtils.TextCursor(text.lineEndings());
-    for (let i = 0; i < identifiers.length; ++i) {
-      const id = identifiers[i];
-      if (id.offset < prefix.length)
-        continue;
-      const start = scopeStart + id.offset - prefix.length;
-      cursor.resetTo(start);
-      result.push(new Sources.SourceMapNamesResolver.Identifier(id.name, cursor.lineNumber(), cursor.columnNumber()));
-    }
-    return result;
-  }
-};
-
-/**
- * @param {!SDK.DebuggerModel.Scope} scope
- * @return {!Promise.<!Map<string, string>>}
- */
-Sources.SourceMapNamesResolver._resolveScope = function(scope) {
-  let identifiersPromise = scope[Sources.SourceMapNamesResolver._cachedIdentifiersSymbol];
-  if (identifiersPromise)
-    return identifiersPromise;
-
-  const script = scope.callFrame().script;
-  const sourceMap = Bindings.debuggerWorkspaceBinding.sourceMapForScript(script);
-  if (!sourceMap)
-    return Promise.resolve(new Map());
-
-  /** @type {!Map<string, !TextUtils.Text>} */
-  const textCache = new Map();
-  identifiersPromise = Sources.SourceMapNamesResolver._scopeIdentifiers(scope).then(onIdentifiers);
-  scope[Sources.SourceMapNamesResolver._cachedIdentifiersSymbol] = identifiersPromise;
-  return identifiersPromise;
-
-  /**
-   * @param {!Array<!Sources.SourceMapNamesResolver.Identifier>} identifiers
-   * @return {!Promise<!Map<string, string>>}
-   */
-  function onIdentifiers(identifiers) {
-    const namesMapping = new Map();
-    // Extract as much as possible from SourceMap.
-    for (let i = 0; i < identifiers.length; ++i) {
-      const id = identifiers[i];
-      const entry = sourceMap.findEntry(id.lineNumber, id.columnNumber);
-      if (entry && entry.name)
-        namesMapping.set(id.name, entry.name);
-    }
-
-    // Resolve missing identifier names from sourcemap ranges.
-    const promises = [];
-    for (let i = 0; i < identifiers.length; ++i) {
-      const id = identifiers[i];
-      if (namesMapping.has(id.name))
-        continue;
-      const promise = resolveSourceName(id).then(onSourceNameResolved.bind(null, namesMapping, id));
-      promises.push(promise);
-    }
-    return Promise.all(promises)
-        .then(() => Sources.SourceMapNamesResolver._scopeResolvedForTest())
-        .then(() => namesMapping);
-  }
-
-  /**
-   * @param {!Map<string, string>} namesMapping
-   * @param {!Sources.SourceMapNamesResolver.Identifier} id
-   * @param {?string} sourceName
-   */
-  function onSourceNameResolved(namesMapping, id, sourceName) {
-    if (!sourceName)
-      return;
-    namesMapping.set(id.name, sourceName);
-  }
-
-  /**
-   * @param {!Sources.SourceMapNamesResolver.Identifier} id
-   * @return {!Promise<?string>}
-   */
-  function resolveSourceName(id) {
-    const startEntry = sourceMap.findEntry(id.lineNumber, id.columnNumber);
-    const endEntry = sourceMap.findEntry(id.lineNumber, id.columnNumber + id.name.length);
-    if (!startEntry || !endEntry || !startEntry.sourceURL || startEntry.sourceURL !== endEntry.sourceURL ||
-        !startEntry.sourceLineNumber || !startEntry.sourceColumnNumber || !endEntry.sourceLineNumber ||
-        !endEntry.sourceColumnNumber)
-      return Promise.resolve(/** @type {?string} */ (null));
-    const sourceTextRange = new TextUtils.TextRange(
-        startEntry.sourceLineNumber, startEntry.sourceColumnNumber, endEntry.sourceLineNumber,
-        endEntry.sourceColumnNumber);
-    const uiSourceCode = Bindings.debuggerWorkspaceBinding.uiSourceCodeForSourceMapSourceURL(
-        script.debuggerModel, startEntry.sourceURL, script.isContentScript());
-    if (!uiSourceCode)
-      return Promise.resolve(/** @type {?string} */ (null));
-
-    return uiSourceCode.requestContent().then(onSourceContent.bind(null, sourceTextRange));
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} sourceTextRange
-   * @param {?string} content
-   * @return {?string}
-   */
-  function onSourceContent(sourceTextRange, content) {
-    if (!content)
-      return null;
-    let text = textCache.get(content);
-    if (!text) {
-      text = new TextUtils.Text(content);
-      textCache.set(content, text);
-    }
-    const originalIdentifier = text.extract(sourceTextRange).trim();
-    return /[a-zA-Z0-9_$]+/.test(originalIdentifier) ? originalIdentifier : null;
-  }
-};
-
-Sources.SourceMapNamesResolver._scopeResolvedForTest = function() {};
-
-/**
- * @param {!SDK.DebuggerModel.CallFrame} callFrame
- * @return {!Promise.<!Map<string, string>>}
- */
-Sources.SourceMapNamesResolver._allVariablesInCallFrame = function(callFrame) {
-  const cached = callFrame[Sources.SourceMapNamesResolver._cachedMapSymbol];
-  if (cached)
-    return Promise.resolve(cached);
-
-  const promises = [];
-  const scopeChain = callFrame.scopeChain();
-  for (let i = 0; i < scopeChain.length; ++i)
-    promises.push(Sources.SourceMapNamesResolver._resolveScope(scopeChain[i]));
-
-  return Promise.all(promises).then(mergeVariables);
-
-  /**
-   * @param {!Array<!Map<string, string>>} nameMappings
-   * @return {!Map<string, string>}
-   */
-  function mergeVariables(nameMappings) {
-    const reverseMapping = new Map();
-    for (const map of nameMappings) {
-      for (const compiledName of map.keys()) {
-        const originalName = map.get(compiledName);
-        if (!reverseMapping.has(originalName))
-          reverseMapping.set(originalName, compiledName);
-      }
-    }
-    callFrame[Sources.SourceMapNamesResolver._cachedMapSymbol] = reverseMapping;
-    return reverseMapping;
-  }
-};
-
-/**
- * @param {!SDK.DebuggerModel.CallFrame} callFrame
- * @param {string} originalText
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} startColumnNumber
- * @param {number} endColumnNumber
- * @return {!Promise<string>}
- */
-Sources.SourceMapNamesResolver.resolveExpression = function(
-    callFrame, originalText, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) {
-  if (!uiSourceCode.contentType().isFromSourceMap())
-    return Promise.resolve('');
-
-  return Sources.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(findCompiledName);
-
-  /**
-   * @param {!Map<string, string>} reverseMapping
-   * @return {!Promise<string>}
-   */
-  function findCompiledName(reverseMapping) {
-    if (reverseMapping.has(originalText))
-      return Promise.resolve(reverseMapping.get(originalText) || '');
-
-    return Sources.SourceMapNamesResolver._resolveExpression(
-        uiSourceCode, lineNumber, startColumnNumber, endColumnNumber);
-  }
-};
-
-/**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} startColumnNumber
- * @param {number} endColumnNumber
- * @return {!Promise<string>}
- */
-Sources.SourceMapNamesResolver._resolveExpression = function(
-    uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) {
-  const rawLocation =
-      Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, lineNumber, startColumnNumber);
-  if (!rawLocation)
-    return Promise.resolve('');
-
-  const script = rawLocation.script();
-  if (!script)
-    return Promise.resolve('');
-  const sourceMap = Bindings.debuggerWorkspaceBinding.sourceMapForScript(script);
-  if (!sourceMap)
-    return Promise.resolve('');
-
-  return script.requestContent().then(onContent);
-
-  /**
-   * @param {?string} content
-   * @return {!Promise<string>}
-   */
-  function onContent(content) {
-    if (!content)
-      return Promise.resolve('');
-
-    const text = new TextUtils.Text(content);
-    const textRange = sourceMap.reverseMapTextRange(
-        uiSourceCode.url(), new TextUtils.TextRange(lineNumber, startColumnNumber, lineNumber, endColumnNumber));
-    const originalText = text.extract(textRange);
-    if (!originalText)
-      return Promise.resolve('');
-    return Formatter.formatterWorkerPool().evaluatableJavaScriptSubstring(originalText);
-  }
-};
-
-/**
- * @param {?SDK.DebuggerModel.CallFrame} callFrame
- * @return {!Promise<?SDK.RemoteObject>}
- */
-Sources.SourceMapNamesResolver.resolveThisObject = function(callFrame) {
-  if (!callFrame)
-    return Promise.resolve(/** @type {?SDK.RemoteObject} */ (null));
-  if (!callFrame.scopeChain().length)
-    return Promise.resolve(callFrame.thisObject());
-
-  return Sources.SourceMapNamesResolver._resolveScope(callFrame.scopeChain()[0]).then(onScopeResolved);
-
-  /**
-   * @param {!Map<string, string>} namesMapping
-   * @return {!Promise<?SDK.RemoteObject>}
-   */
-  function onScopeResolved(namesMapping) {
-    const thisMappings = namesMapping.inverse().get('this');
-    if (!thisMappings || thisMappings.size !== 1)
-      return Promise.resolve(callFrame.thisObject());
-
-    const thisMapping = thisMappings.valuesArray()[0];
-    return callFrame
-        .evaluate({
-          expression: thisMapping,
-          objectGroup: 'backtrace',
-          includeCommandLineAPI: false,
-          silent: true,
-          returnByValue: false,
-          generatePreview: true
-        })
-        .then(onEvaluated);
-  }
-
-  /**
-   * @param {!SDK.RuntimeModel.EvaluationResult} result
-   * @return {?SDK.RemoteObject}
-   */
-  function onEvaluated(result) {
-    return !result.exceptionDetails && result.object ? result.object : callFrame.thisObject();
-  }
-};
-
-/**
- * @param {!SDK.DebuggerModel.Scope} scope
- * @return {!SDK.RemoteObject}
- */
-Sources.SourceMapNamesResolver.resolveScopeInObject = function(scope) {
-  const startLocation = scope.startLocation();
-  const endLocation = scope.endLocation();
-
-  if (scope.type() === Protocol.Debugger.ScopeType.Global || !startLocation || !endLocation ||
-      !startLocation.script() || !startLocation.script().sourceMapURL ||
-      startLocation.script() !== endLocation.script())
-    return scope.object();
-
-  return new Sources.SourceMapNamesResolver.RemoteObject(scope);
-};
-
-/**
- * @unrestricted
- */
-Sources.SourceMapNamesResolver.RemoteObject = class extends SDK.RemoteObject {
-  /**
-   * @param {!SDK.DebuggerModel.Scope} scope
-   */
-  constructor(scope) {
-    super();
-    this._scope = scope;
-    this._object = scope.object();
-  }
-
-  /**
-   * @override
-   * @return {?Protocol.Runtime.CustomPreview}
-   */
-  customPreview() {
-    return this._object.customPreview();
-  }
-
-  /**
-   * @override
-   * @return {!Protocol.Runtime.RemoteObjectId|undefined}
-   */
-  get objectId() {
-    return this._object.objectId;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  get type() {
-    return this._object.type;
-  }
-
-  /**
-   * @override
-   * @return {string|undefined}
-   */
-  get subtype() {
-    return this._object.subtype;
-  }
-
-  /**
-   * @override
-   * @return {*}
-   */
-  get value() {
-    return this._object.value;
-  }
-
-  /**
-   * @override
-   * @return {string|undefined}
-   */
-  get description() {
-    return this._object.description;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  get hasChildren() {
-    return this._object.hasChildren;
-  }
-
-  /**
-   * @override
-   * @return {!Protocol.Runtime.ObjectPreview|undefined}
-   */
-  get preview() {
-    return this._object.preview;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  arrayLength() {
-    return this._object.arrayLength();
-  }
-
-  /**
-   * @override
-   * @param {boolean} generatePreview
-   * @param {function(?Array.<!SDK.RemoteObjectProperty>, ?Array.<!SDK.RemoteObjectProperty>)} callback
-   */
-  getOwnProperties(generatePreview, callback) {
-    this._object.getOwnProperties(generatePreview, callback);
-  }
-
-  /**
-   * @override
-   * @param {boolean} accessorPropertiesOnly
-   * @param {boolean} generatePreview
-   * @param {function(?Array<!SDK.RemoteObjectProperty>, ?Array<!SDK.RemoteObjectProperty>)} callback
-   */
-  getAllProperties(accessorPropertiesOnly, generatePreview, callback) {
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     * @this {Sources.SourceMapNamesResolver.RemoteObject}
-     */
-    function wrappedCallback(properties, internalProperties) {
-      Sources.SourceMapNamesResolver._resolveScope(this._scope)
-          .then(resolveNames.bind(null, properties, internalProperties));
-    }
-
-    /**
-     * @param {?Array.<!SDK.RemoteObjectProperty>} properties
-     * @param {?Array.<!SDK.RemoteObjectProperty>} internalProperties
-     * @param {!Map<string, string>} namesMapping
-     */
-    function resolveNames(properties, internalProperties, namesMapping) {
-      const newProperties = [];
-      if (properties) {
-        for (let i = 0; i < properties.length; ++i) {
-          const property = properties[i];
-          const name = namesMapping.get(property.name) || properties[i].name;
-          newProperties.push(new SDK.RemoteObjectProperty(
-              name, property.value, property.enumerable, property.writable, property.isOwn, property.wasThrown,
-              property.symbol, property.synthetic));
-        }
-      }
-
-      callback(newProperties, internalProperties);
-    }
-
-    this._object.getAllProperties(accessorPropertiesOnly, generatePreview, wrappedCallback.bind(this));
-  }
-
-  /**
-   * @override
-   * @param {string|!Protocol.Runtime.CallArgument} argumentName
-   * @param {string} value
-   * @return {!Promise<string|undefined>}
-   */
-  async setPropertyValue(argumentName, value) {
-    const namesMapping = await Sources.SourceMapNamesResolver._resolveScope(this._scope);
-
-    let name;
-    if (typeof argumentName === 'string')
-      name = argumentName;
-    else
-      name = /** @type {string} */ (argumentName.value);
-
-    let actualName = name;
-    for (const compiledName of namesMapping.keys()) {
-      if (namesMapping.get(compiledName) === name) {
-        actualName = compiledName;
-        break;
-      }
-    }
-    return this._object.setPropertyValue(actualName, value);
-  }
-
-  /**
-   * @override
-   * @param {!Array.<string>} propertyPath
-   * @param {function(?SDK.RemoteObject, boolean=)} callback
-   */
-  getProperty(propertyPath, callback) {
-    this._object.getProperty(propertyPath, callback);
-  }
-
-  /**
-   * @override
-   * @param {!Protocol.Runtime.CallArgument} name
-   * @return {!Promise<string|undefined>}
-   */
-  async deleteProperty(name) {
-    return this._object.deleteProperty(name);
-  }
-
-  /**
-   * @override
-   * @param {function(this:Object, ...)} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>=} args
-   * @param {function(?SDK.RemoteObject, boolean=)=} callback
-   */
-  callFunction(functionDeclaration, args, callback) {
-    this._object.callFunction(functionDeclaration, args, callback);
-  }
-
-  /**
-   * @override
-   * @param {function(this:Object, ...)} functionDeclaration
-   * @param {!Array<!Protocol.Runtime.CallArgument>|undefined} args
-   * @param {function(*)} callback
-   */
-  callFunctionJSON(functionDeclaration, args, callback) {
-    this._object.callFunctionJSON(functionDeclaration, args, callback);
-  }
-
-  /**
-   * @override
-   */
-  release() {
-    this._object.release();
-  }
-
-  /**
-   * @override
-   * @return {!SDK.DebuggerModel}
-   */
-  debuggerModel() {
-    return this._object.debuggerModel();
-  }
-
-  /**
-   * @override
-   * @return {!SDK.RuntimeModel}
-   */
-  runtimeModel() {
-    return this._object.runtimeModel();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isNode() {
-    return this._object.isNode();
-  }
-};
diff --git a/front_end/sources/SourcesNavigator.js b/front_end/sources/SourcesNavigator.js
deleted file mode 100644
index 70db55d..0000000
--- a/front_end/sources/SourcesNavigator.js
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Sources.NetworkNavigatorView = class extends Sources.NavigatorView {
-  constructor() {
-    super();
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  acceptProject(project) {
-    return project.type() === Workspace.projectTypes.Network;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _inspectedURLChanged(event) {
-    const mainTarget = SDK.targetManager.mainTarget();
-    if (event.data !== mainTarget)
-      return;
-    const inspectedURL = mainTarget && mainTarget.inspectedURL();
-    if (!inspectedURL)
-      return;
-    for (const uiSourceCode of this.workspace().uiSourceCodes()) {
-      if (this.acceptProject(uiSourceCode.project()) && uiSourceCode.url() === inspectedURL)
-        this.revealUISourceCode(uiSourceCode, true);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  uiSourceCodeAdded(uiSourceCode) {
-    const mainTarget = SDK.targetManager.mainTarget();
-    const inspectedURL = mainTarget && mainTarget.inspectedURL();
-    if (!inspectedURL)
-      return;
-    if (uiSourceCode.url() === inspectedURL)
-      this.revealUISourceCode(uiSourceCode, true);
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.FilesNavigatorView = class extends Sources.NavigatorView {
-  constructor() {
-    super();
-    const toolbar = new UI.Toolbar('navigator-toolbar');
-    const title = Common.UIString('Add folder to workspace');
-    const addButton = new UI.ToolbarButton(title, 'largeicon-add', title);
-    addButton.addEventListener(
-        UI.ToolbarButton.Events.Click, () => Persistence.isolatedFileSystemManager.addFileSystem());
-    toolbar.appendToolbarItem(addButton);
-    this.contentElement.insertBefore(toolbar.element, this.contentElement.firstChild);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  acceptProject(project) {
-    return project.type() === Workspace.projectTypes.FileSystem &&
-        Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides';
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  handleContextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    Sources.NavigatorView.appendAddFolderItem(contextMenu);
-    contextMenu.show();
-  }
-};
-
-Sources.OverridesNavigatorView = class extends Sources.NavigatorView {
-  constructor() {
-    super();
-    this._toolbar = new UI.Toolbar('navigator-toolbar');
-
-    this.contentElement.insertBefore(this._toolbar.element, this.contentElement.lastChild);
-
-    Persistence.networkPersistenceManager.addEventListener(
-        Persistence.NetworkPersistenceManager.Events.ProjectChanged, this._updateProjectAndUI, this);
-    this.workspace().addEventListener(Workspace.Workspace.Events.ProjectAdded, this._onProjectAddOrRemoved, this);
-    this.workspace().addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._onProjectAddOrRemoved, this);
-    this._updateProjectAndUI();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onProjectAddOrRemoved(event) {
-    const project = /** @type {!Workspace.Project} */ (event.data);
-    if (project && project.type() === Workspace.projectTypes.FileSystem &&
-        Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides')
-      return;
-    this._updateUI();
-  }
-
-  _updateProjectAndUI() {
-    this.reset();
-    const project = Persistence.networkPersistenceManager.project();
-    if (project)
-      this.tryAddProject(project);
-    this._updateUI();
-  }
-
-  _updateUI() {
-    this._toolbar.removeToolbarItems();
-    const project = Persistence.networkPersistenceManager.project();
-    if (project) {
-      const enableCheckbox =
-          new UI.ToolbarSettingCheckbox(Common.settings.moduleSetting('persistenceNetworkOverridesEnabled'));
-      this._toolbar.appendToolbarItem(enableCheckbox);
-
-      this._toolbar.appendToolbarItem(new UI.ToolbarSeparator(true));
-      const clearButton = new UI.ToolbarButton(Common.UIString('Clear configuration'), 'largeicon-clear');
-      clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
-        project.remove();
-      });
-      this._toolbar.appendToolbarItem(clearButton);
-      return;
-    }
-    const title = Common.UIString('Select folder for overrides');
-    const setupButton = new UI.ToolbarButton(title, 'largeicon-add', title);
-    setupButton.addEventListener(UI.ToolbarButton.Events.Click, this._setupNewWorkspace, this);
-    this._toolbar.appendToolbarItem(setupButton);
-  }
-
-  async _setupNewWorkspace() {
-    const fileSystem = await Persistence.isolatedFileSystemManager.addFileSystem('overrides');
-    if (!fileSystem)
-      return;
-    Common.settings.moduleSetting('persistenceNetworkOverridesEnabled').set(true);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  acceptProject(project) {
-    return project === Persistence.networkPersistenceManager.project();
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.ContentScriptsNavigatorView = class extends Sources.NavigatorView {
-  constructor() {
-    super();
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  acceptProject(project) {
-    return project.type() === Workspace.projectTypes.ContentScripts;
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.SnippetsNavigatorView = class extends Sources.NavigatorView {
-  constructor() {
-    super();
-    const toolbar = new UI.Toolbar('navigator-toolbar');
-    const newButton = new UI.ToolbarButton('', 'largeicon-add', Common.UIString('New snippet'));
-    newButton.addEventListener(UI.ToolbarButton.Events.Click, this._handleCreateSnippet.bind(this));
-    toolbar.appendToolbarItem(newButton);
-    this.contentElement.insertBefore(toolbar.element, this.contentElement.firstChild);
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.Project} project
-   * @return {boolean}
-   */
-  acceptProject(project) {
-    return project.type() === Workspace.projectTypes.Snippets;
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  handleContextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.headerSection().appendItem(Common.UIString('New'), this._handleCreateSnippet.bind(this));
-    contextMenu.show();
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!Sources.NavigatorUISourceCodeTreeNode} node
-   */
-  handleFileContextMenu(event, node) {
-    const uiSourceCode = node.uiSourceCode();
-    const contextMenu = new UI.ContextMenu(event);
-
-    contextMenu.headerSection().appendItem(
-        Common.UIString('Run'), this._handleEvaluateSnippet.bind(this, uiSourceCode));
-    contextMenu.newSection().appendItem(Common.UIString('New'), this._handleCreateSnippet.bind(this));
-    contextMenu.editSection().appendItem(Common.UIString('Rename'), this.rename.bind(this, node));
-    contextMenu.editSection().appendItem(Common.UIString('Remove'), this._handleRemoveSnippet.bind(this, uiSourceCode));
-    contextMenu.saveSection().appendItem(Common.UIString('Save as...'), this._handleSaveAs.bind(this, uiSourceCode));
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _handleEvaluateSnippet(uiSourceCode) {
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext)
-      return;
-    Snippets.scriptSnippetModel.evaluateScriptSnippet(executionContext, uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  async _handleSaveAs(uiSourceCode) {
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets)
-      return;
-
-    uiSourceCode.commitWorkingCopy();
-    const content = await uiSourceCode.requestContent();
-    Workspace.fileManager.save(uiSourceCode.url(), content, true);
-    Workspace.fileManager.close(uiSourceCode.url());
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _handleRemoveSnippet(uiSourceCode) {
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets)
-      return;
-    uiSourceCode.remove();
-  }
-
-  _handleCreateSnippet() {
-    this.create(Snippets.scriptSnippetModel.project(), '');
-  }
-
-  /**
-   * @override
-   */
-  sourceDeleted(uiSourceCode) {
-    this._handleRemoveSnippet(uiSourceCode);
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Sources.SnippetsNavigatorView.CreatingActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    switch (actionId) {
-      case 'sources.create-snippet':
-        const uiSourceCode = Snippets.scriptSnippetModel.createScriptSnippet('');
-        Common.Revealer.reveal(uiSourceCode);
-        return true;
-      case 'sources.add-folder-to-workspace':
-        Persistence.isolatedFileSystemManager.addFileSystem();
-        return true;
-    }
-    return false;
-  }
-};
diff --git a/front_end/sources/SourcesPanel.js b/front_end/sources/SourcesPanel.js
deleted file mode 100644
index df9a726..0000000
--- a/front_end/sources/SourcesPanel.js
+++ /dev/null
@@ -1,1260 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ContextMenu.Provider}
- * @implements {SDK.TargetManager.Observer}
- * @implements {UI.ViewLocationResolver}
- * @unrestricted
- */
-Sources.SourcesPanel = class extends UI.Panel {
-  constructor() {
-    super('sources');
-    Sources.SourcesPanel._instance = this;
-    this.registerRequiredCSS('sources/sourcesPanel.css');
-    new UI.DropTarget(
-        this.element, [UI.DropTarget.Type.Folder], Common.UIString('Drop workspace folder here'),
-        this._handleDrop.bind(this));
-
-    this._workspace = Workspace.workspace;
-
-    this._togglePauseAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('debugger.toggle-pause'));
-    this._stepOverAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('debugger.step-over'));
-    this._stepIntoAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('debugger.step-into'));
-    this._stepOutAction = /** @type {!UI.Action }*/ (UI.actionRegistry.action('debugger.step-out'));
-    this._stepAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('debugger.step'));
-    this._toggleBreakpointsActiveAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('debugger.toggle-breakpoints-active'));
-
-    this._debugToolbar = this._createDebugToolbar();
-    this._debugToolbarDrawer = this._createDebugToolbarDrawer();
-    this._debuggerPausedMessage = new Sources.DebuggerPausedMessage();
-
-    const initialDebugSidebarWidth = 225;
-    this._splitWidget = new UI.SplitWidget(true, true, 'sourcesPanelSplitViewState', initialDebugSidebarWidth);
-    this._splitWidget.enableShowModeSaving();
-    this._splitWidget.show(this.element);
-
-    // Create scripts navigator
-    const initialNavigatorWidth = 225;
-    this.editorView = new UI.SplitWidget(true, false, 'sourcesPanelNavigatorSplitViewState', initialNavigatorWidth);
-    this.editorView.enableShowModeSaving();
-    this.editorView.element.tabIndex = 0;
-    this._splitWidget.setMainWidget(this.editorView);
-
-    // Create navigator tabbed pane with toolbar.
-    this._navigatorTabbedLocation =
-        UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'navigator-view', true);
-    const tabbedPane = this._navigatorTabbedLocation.tabbedPane();
-    tabbedPane.setMinimumSize(100, 25);
-    tabbedPane.element.classList.add('navigator-tabbed-pane');
-    const navigatorMenuButton = new UI.ToolbarMenuButton(this._populateNavigatorMenu.bind(this), true);
-    navigatorMenuButton.setTitle(Common.UIString('More options'));
-    tabbedPane.rightToolbar().appendToolbarItem(navigatorMenuButton);
-
-    if (UI.viewManager.hasViewsForLocation('run-view-sidebar')) {
-      const navigatorSplitWidget = new UI.SplitWidget(false, true, 'sourcePanelNavigatorSidebarSplitViewState');
-      navigatorSplitWidget.setMainWidget(tabbedPane);
-      navigatorSplitWidget.setSidebarWidget(
-          UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar')
-              .tabbedPane());
-      this.editorView.setSidebarWidget(navigatorSplitWidget);
-    } else {
-      this.editorView.setSidebarWidget(tabbedPane);
-    }
-
-    this._sourcesView = new Sources.SourcesView();
-    this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
-
-    this._toggleNavigatorSidebarButton = this.editorView.createShowHideSidebarButton('navigator');
-    this._toggleDebuggerSidebarButton = this._splitWidget.createShowHideSidebarButton('debugger');
-    this.editorView.setMainWidget(this._sourcesView);
-
-    this._threadsSidebarPane = null;
-    this._watchSidebarPane = /** @type {!UI.View} */ (UI.viewManager.view('sources.watch'));
-    this._callstackPane = self.runtime.sharedInstance(Sources.CallStackSidebarPane);
-
-    Common.moduleSetting('sidebarPosition').addChangeListener(this._updateSidebarPosition.bind(this));
-    this._updateSidebarPosition();
-
-    this._updateDebuggerButtonsAndStatus();
-    this._pauseOnExceptionEnabledChanged();
-    Common.moduleSetting('pauseOnExceptionEnabled').addChangeListener(this._pauseOnExceptionEnabledChanged, this);
-
-    this._liveLocationPool = new Bindings.LiveLocationPool();
-
-    this._setTarget(UI.context.flavor(SDK.Target));
-    Common.moduleSetting('breakpointsActive').addChangeListener(this._breakpointsActiveStateChanged, this);
-    UI.context.addFlavorChangeListener(SDK.Target, this._onCurrentTargetChanged, this);
-    UI.context.addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this._callFrameChanged, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed,
-        event => this._debuggerResumed(/** @type {!SDK.DebuggerModel} */ (event.data)));
-    SDK.targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared,
-        event => this._debuggerResumed(/** @type {!SDK.DebuggerModel} */ (event.data)));
-    Extensions.extensionServer.addEventListener(
-        Extensions.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this);
-    SDK.targetManager.observeTargets(this);
-  }
-
-  /**
-   * @return {!Sources.SourcesPanel}
-   */
-  static instance() {
-    if (Sources.SourcesPanel._instance)
-      return Sources.SourcesPanel._instance;
-    return /** @type {!Sources.SourcesPanel} */ (self.runtime.sharedInstance(Sources.SourcesPanel));
-  }
-
-  /**
-   * @param {!Sources.SourcesPanel} panel
-   */
-  static updateResizerAndSidebarButtons(panel) {
-    panel._sourcesView.leftToolbar().removeToolbarItems();
-    panel._sourcesView.rightToolbar().removeToolbarItems();
-    panel._sourcesView.bottomToolbar().removeToolbarItems();
-    const isInWrapper = Sources.SourcesPanel.WrapperView.isShowing() && !UI.inspectorView.isDrawerMinimized();
-    if (panel._splitWidget.isVertical() || isInWrapper)
-      panel._splitWidget.uninstallResizer(panel._sourcesView.toolbarContainerElement());
-    else
-      panel._splitWidget.installResizer(panel._sourcesView.toolbarContainerElement());
-    if (!isInWrapper) {
-      panel._sourcesView.leftToolbar().appendToolbarItem(panel._toggleNavigatorSidebarButton);
-      if (panel._splitWidget.isVertical())
-        panel._sourcesView.rightToolbar().appendToolbarItem(panel._toggleDebuggerSidebarButton);
-      else
-        panel._sourcesView.bottomToolbar().appendToolbarItem(panel._toggleDebuggerSidebarButton);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetAdded(target) {
-    this._showThreadsIfNeeded();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Target} target
-   */
-  targetRemoved(target) {
-  }
-
-  _showThreadsIfNeeded() {
-    if (Sources.ThreadsSidebarPane.shouldBeShown() && !this._threadsSidebarPane) {
-      this._threadsSidebarPane = /** @type {!UI.View} */ (UI.viewManager.view('sources.threads'));
-      if (this._sidebarPaneStack) {
-        this._sidebarPaneStack.showView(
-            this._threadsSidebarPane, this._splitWidget.isVertical() ? this._watchSidebarPane : this._callstackPane);
-      }
-    }
-  }
-
-
-  /**
-   * @param {?SDK.Target} target
-   */
-  _setTarget(target) {
-    if (!target)
-      return;
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (!debuggerModel)
-      return;
-
-    if (debuggerModel.isPaused()) {
-      this._showDebuggerPausedDetails(
-          /** @type {!SDK.DebuggerPausedDetails} */ (debuggerModel.debuggerPausedDetails()));
-    } else {
-      this._paused = false;
-      this._clearInterface();
-      this._toggleDebuggerSidebarButton.setEnabled(true);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onCurrentTargetChanged(event) {
-    const target = /** @type {?SDK.Target} */ (event.data);
-    this._setTarget(target);
-  }
-  /**
-   * @return {boolean}
-   */
-  paused() {
-    return this._paused;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Sources.SourcesPanel, this);
-    super.wasShown();
-    const wrapper = Sources.SourcesPanel.WrapperView._instance;
-    if (wrapper && wrapper.isShowing()) {
-      UI.inspectorView.setDrawerMinimized(true);
-      Sources.SourcesPanel.updateResizerAndSidebarButtons(this);
-    }
-    this.editorView.setMainWidget(this._sourcesView);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-    UI.context.setFlavor(Sources.SourcesPanel, null);
-    if (Sources.SourcesPanel.WrapperView.isShowing()) {
-      Sources.SourcesPanel.WrapperView._instance._showViewInWrapper();
-      UI.inspectorView.setDrawerMinimized(false);
-      Sources.SourcesPanel.updateResizerAndSidebarButtons(this);
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   * @return {?UI.ViewLocation}
-   */
-  resolveLocation(locationName) {
-    if (locationName === 'sources-sidebar')
-      return this._sidebarPaneStack;
-    else
-      return this._navigatorTabbedLocation;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _ensureSourcesViewVisible() {
-    if (Sources.SourcesPanel.WrapperView.isShowing())
-      return true;
-    if (!UI.inspectorView.canSelectPanel('sources'))
-      return false;
-    UI.viewManager.showView('sources');
-    return true;
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (Common.moduleSetting('sidebarPosition').get() === 'auto')
-      this.element.window().requestAnimationFrame(this._updateSidebarPosition.bind(this));  // Do not force layout.
-  }
-
-  /**
-   * @override
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._sourcesView.searchableView();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _debuggerPaused(event) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    const details = debuggerModel.debuggerPausedDetails();
-    if (!this._paused)
-      this._setAsCurrentPanel();
-
-    if (UI.context.flavor(SDK.Target) === debuggerModel.target())
-      this._showDebuggerPausedDetails(/** @type {!SDK.DebuggerPausedDetails} */ (details));
-    else if (!this._paused)
-      UI.context.setFlavor(SDK.Target, debuggerModel.target());
-  }
-
-  /**
-   * @param {!SDK.DebuggerPausedDetails} details
-   */
-  _showDebuggerPausedDetails(details) {
-    this._paused = true;
-    this._updateDebuggerButtonsAndStatus();
-    UI.context.setFlavor(SDK.DebuggerPausedDetails, details);
-    this._toggleDebuggerSidebarButton.setEnabled(false);
-    this._revealDebuggerSidebar();
-    window.focus();
-    InspectorFrontendHost.bringToFront();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _debuggerResumed(debuggerModel) {
-    const target = debuggerModel.target();
-    if (UI.context.flavor(SDK.Target) !== target)
-      return;
-    this._paused = false;
-    this._clearInterface();
-    this._toggleDebuggerSidebarButton.setEnabled(true);
-    this._switchToPausedTargetTimeout = setTimeout(this._switchToPausedTarget.bind(this, debuggerModel), 500);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _debuggerWasEnabled(event) {
-    const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
-    if (UI.context.flavor(SDK.Target) !== debuggerModel.target())
-      return;
-
-    this._updateDebuggerButtonsAndStatus();
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  get visibleView() {
-    return this._sourcesView.visibleView();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number=} lineNumber 0-based
-   * @param {number=} columnNumber
-   * @param {boolean=} omitFocus
-   */
-  showUISourceCode(uiSourceCode, lineNumber, columnNumber, omitFocus) {
-    if (omitFocus) {
-      const wrapperShowing =
-          Sources.SourcesPanel.WrapperView._instance && Sources.SourcesPanel.WrapperView._instance.isShowing();
-      if (!this.isShowing() && !wrapperShowing)
-        return;
-    } else {
-      this._showEditor();
-    }
-    this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber, omitFocus);
-  }
-
-  _showEditor() {
-    if (Sources.SourcesPanel.WrapperView._instance && Sources.SourcesPanel.WrapperView._instance.isShowing())
-      return;
-    this._setAsCurrentPanel();
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   * @param {boolean=} omitFocus
-   */
-  showUILocation(uiLocation, omitFocus) {
-    this.showUISourceCode(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, omitFocus);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {boolean=} skipReveal
-   */
-  _revealInNavigator(uiSourceCode, skipReveal) {
-    const extensions = self.runtime.extensions(Sources.NavigatorView);
-    Promise.all(extensions.map(extension => extension.instance())).then(filterNavigators.bind(this));
-
-    /**
-     * @this {Sources.SourcesPanel}
-     * @param {!Array.<!Object>} objects
-     */
-    function filterNavigators(objects) {
-      for (let i = 0; i < objects.length; ++i) {
-        const navigatorView = /** @type {!Sources.NavigatorView} */ (objects[i]);
-        const viewId = extensions[i].descriptor()['viewId'];
-        if (navigatorView.acceptProject(uiSourceCode.project())) {
-          navigatorView.revealUISourceCode(uiSourceCode, true);
-          if (skipReveal)
-            this._navigatorTabbedLocation.tabbedPane().selectTab(viewId);
-          else
-            UI.viewManager.showView(viewId);
-        }
-      }
-    }
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _populateNavigatorMenu(contextMenu) {
-    const groupByFolderSetting = Common.moduleSetting('navigatorGroupByFolder');
-    contextMenu.appendItemsAtLocation('navigatorMenu');
-    contextMenu.viewSection().appendCheckboxItem(
-        Common.UIString('Group by folder'), () => groupByFolderSetting.set(!groupByFolderSetting.get()),
-        groupByFolderSetting.get());
-  }
-
-  /**
-   * @param {boolean} ignoreExecutionLineEvents
-   */
-  setIgnoreExecutionLineEvents(ignoreExecutionLineEvents) {
-    this._ignoreExecutionLineEvents = ignoreExecutionLineEvents;
-  }
-
-  updateLastModificationTime() {
-    this._lastModificationTime = window.performance.now();
-  }
-
-  /**
-   * @param {!Bindings.LiveLocation} liveLocation
-   */
-  _executionLineChanged(liveLocation) {
-    const uiLocation = liveLocation.uiLocation();
-    if (!uiLocation)
-      return;
-    this._sourcesView.clearCurrentExecutionLine();
-    this._sourcesView.setExecutionLocation(uiLocation);
-    if (window.performance.now() - this._lastModificationTime < Sources.SourcesPanel._lastModificationTimeout)
-      return;
-    this._sourcesView.showSourceLocation(
-        uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, undefined, true);
-  }
-
-  _lastModificationTimeoutPassedForTest() {
-    Sources.SourcesPanel._lastModificationTimeout = Number.MIN_VALUE;
-  }
-
-  _updateLastModificationTimeForTest() {
-    Sources.SourcesPanel._lastModificationTimeout = Number.MAX_VALUE;
-  }
-
-  _callFrameChanged() {
-    const callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
-    if (!callFrame)
-      return;
-    if (this._executionLineLocation)
-      this._executionLineLocation.dispose();
-    this._executionLineLocation = Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(
-        callFrame.location(), this._executionLineChanged.bind(this), this._liveLocationPool);
-  }
-
-  _pauseOnExceptionEnabledChanged() {
-    const enabled = Common.moduleSetting('pauseOnExceptionEnabled').get();
-    this._pauseOnExceptionButton.setToggled(enabled);
-    this._pauseOnExceptionButton.setTitle(
-        Common.UIString(enabled ? 'Don\'t pause on exceptions' : 'Pause on exceptions'));
-    this._debugToolbarDrawer.classList.toggle('expanded', enabled);
-  }
-
-  async _updateDebuggerButtonsAndStatus() {
-    const currentTarget = UI.context.flavor(SDK.Target);
-    const currentDebuggerModel = currentTarget ? currentTarget.model(SDK.DebuggerModel) : null;
-    if (!currentDebuggerModel) {
-      this._togglePauseAction.setEnabled(false);
-      this._stepOverAction.setEnabled(false);
-      this._stepIntoAction.setEnabled(false);
-      this._stepOutAction.setEnabled(false);
-      this._stepAction.setEnabled(false);
-    } else if (this._paused) {
-      this._togglePauseAction.setToggled(true);
-      this._togglePauseAction.setEnabled(true);
-      this._stepOverAction.setEnabled(true);
-      this._stepIntoAction.setEnabled(true);
-      this._stepOutAction.setEnabled(true);
-      this._stepAction.setEnabled(true);
-    } else {
-      this._togglePauseAction.setToggled(false);
-      this._togglePauseAction.setEnabled(!currentDebuggerModel.isPausing());
-      this._stepOverAction.setEnabled(false);
-      this._stepIntoAction.setEnabled(false);
-      this._stepOutAction.setEnabled(false);
-      this._stepAction.setEnabled(false);
-    }
-
-    const details = currentDebuggerModel ? currentDebuggerModel.debuggerPausedDetails() : null;
-    await this._debuggerPausedMessage.render(details, Bindings.debuggerWorkspaceBinding, Bindings.breakpointManager);
-    if (details)
-      this._updateDebuggerButtonsAndStatusForTest();
-  }
-
-  _updateDebuggerButtonsAndStatusForTest() {
-  }
-
-  _clearInterface() {
-    this._sourcesView.clearCurrentExecutionLine();
-    this._updateDebuggerButtonsAndStatus();
-    UI.context.setFlavor(SDK.DebuggerPausedDetails, null);
-
-    if (this._switchToPausedTargetTimeout)
-      clearTimeout(this._switchToPausedTargetTimeout);
-    this._liveLocationPool.disposeAll();
-  }
-
-  /**
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  _switchToPausedTarget(debuggerModel) {
-    delete this._switchToPausedTargetTimeout;
-    if (this._paused)
-      return;
-    if (debuggerModel.isPaused())
-      return;
-    const debuggerModels = SDK.targetManager.models(SDK.DebuggerModel);
-    for (let i = 0; i < debuggerModels.length; ++i) {
-      if (debuggerModels[i].isPaused()) {
-        UI.context.setFlavor(SDK.Target, debuggerModels[i].target());
-        break;
-      }
-    }
-  }
-
-  _togglePauseOnExceptions() {
-    Common.moduleSetting('pauseOnExceptionEnabled').set(!this._pauseOnExceptionButton.toggled());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _runSnippet() {
-    const uiSourceCode = this._sourcesView.currentUISourceCode();
-    if (!uiSourceCode)
-      return false;
-
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!currentExecutionContext)
-      return false;
-
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets)
-      return false;
-
-    Snippets.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode);
-    return true;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorSelected(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    if (this.editorView.mainWidget() && Common.moduleSetting('autoRevealInNavigator').get())
-      this._revealInNavigator(uiSourceCode, true);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _togglePause() {
-    const target = UI.context.flavor(SDK.Target);
-    if (!target)
-      return true;
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (!debuggerModel)
-      return true;
-
-    if (this._paused) {
-      this._paused = false;
-      debuggerModel.resume();
-    } else {
-      // Make sure pauses didn't stick skipped.
-      debuggerModel.pause();
-    }
-
-    this._clearInterface();
-    return true;
-  }
-
-  /**
-   * @return {?SDK.DebuggerModel}
-   */
-  _prepareToResume() {
-    if (!this._paused)
-      return null;
-
-    this._paused = false;
-
-    this._clearInterface();
-    const target = UI.context.flavor(SDK.Target);
-    return target ? target.model(SDK.DebuggerModel) : null;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _longResume(event) {
-    const debuggerModel = this._prepareToResume();
-    if (!debuggerModel)
-      return;
-
-    debuggerModel.skipAllPausesUntilReloadOrTimeout(500);
-    debuggerModel.resume();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _terminateExecution(event) {
-    const debuggerModel = this._prepareToResume();
-    if (!debuggerModel)
-      return;
-    debuggerModel.runtimeModel().terminateExecution();
-    debuggerModel.resume();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _stepOver() {
-    const debuggerModel = this._prepareToResume();
-    if (!debuggerModel)
-      return true;
-
-    debuggerModel.stepOver();
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _stepInto() {
-    const debuggerModel = this._prepareToResume();
-    if (!debuggerModel)
-      return true;
-
-    debuggerModel.stepInto();
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _stepIntoAsync() {
-    const debuggerModel = this._prepareToResume();
-    if (!debuggerModel)
-      return true;
-    debuggerModel.scheduleStepIntoAsync();
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _stepOut() {
-    const debuggerModel = this._prepareToResume();
-    if (!debuggerModel)
-      return true;
-
-    debuggerModel.stepOut();
-    return true;
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   */
-  _continueToLocation(uiLocation) {
-    const executionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!executionContext)
-      return;
-    // Always use 0 column.
-    const rawLocation =
-        Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, 0);
-    if (!rawLocation || rawLocation.debuggerModel !== executionContext.debuggerModel)
-      return;
-    if (!this._prepareToResume())
-      return;
-
-    rawLocation.continueToLocation();
-  }
-
-  _toggleBreakpointsActive() {
-    Common.moduleSetting('breakpointsActive').set(!Common.moduleSetting('breakpointsActive').get());
-  }
-
-  _breakpointsActiveStateChanged() {
-    const active = Common.moduleSetting('breakpointsActive').get();
-    this._toggleBreakpointsActiveAction.setToggled(!active);
-    this._sourcesView.toggleBreakpointsActiveState(active);
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  _createDebugToolbar() {
-    const debugToolbar = new UI.Toolbar('scripts-debug-toolbar');
-
-    const longResumeButton =
-        new UI.ToolbarButton(Common.UIString('Resume with all pauses blocked for 500 ms'), 'largeicon-play');
-    longResumeButton.addEventListener(UI.ToolbarButton.Events.Click, this._longResume, this);
-    const terminateExecutionButton =
-        new UI.ToolbarButton(ls`Terminate current JavaScript call`, 'largeicon-terminate-execution');
-    terminateExecutionButton.addEventListener(UI.ToolbarButton.Events.Click, this._terminateExecution, this);
-    debugToolbar.appendToolbarItem(
-        UI.Toolbar.createActionButton(this._togglePauseAction, [terminateExecutionButton, longResumeButton], []));
-
-    if (Runtime.experiments.isEnabled('stepIntoAsync')) {
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepOverAction));
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepIntoAction));
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepOutAction));
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepAction));
-    } else {
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepOverAction));
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepAction));
-      debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepOutAction));
-    }
-
-    debugToolbar.appendSeparator();
-    debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleBreakpointsActiveAction));
-
-    this._pauseOnExceptionButton = new UI.ToolbarToggle('', 'largeicon-pause-on-exceptions');
-    this._pauseOnExceptionButton.addEventListener(UI.ToolbarButton.Events.Click, this._togglePauseOnExceptions, this);
-    debugToolbar.appendToolbarItem(this._pauseOnExceptionButton);
-
-    return debugToolbar;
-  }
-
-  _createDebugToolbarDrawer() {
-    const debugToolbarDrawer = createElementWithClass('div', 'scripts-debug-toolbar-drawer');
-
-    const label = Common.UIString('Pause on caught exceptions');
-    const setting = Common.moduleSetting('pauseOnCaughtException');
-    debugToolbarDrawer.appendChild(UI.SettingsUI.createSettingCheckbox(label, setting, true));
-
-    return debugToolbarDrawer;
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    this._appendUISourceCodeItems(event, contextMenu, target);
-    this._appendUISourceCodeFrameItems(event, contextMenu, target);
-    this.appendUILocationItems(contextMenu, target);
-    this._appendRemoteObjectItems(contextMenu, target);
-    this._appendNetworkRequestItems(contextMenu, target);
-  }
-
-  /**
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  _appendUISourceCodeItems(event, contextMenu, target) {
-    if (!(target instanceof Workspace.UISourceCode))
-      return;
-
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (target);
-    if (!uiSourceCode.project().isServiceProject() &&
-        !event.target.isSelfOrDescendant(this._navigatorTabbedLocation.widget().element)) {
-      contextMenu.revealSection().appendItem(
-          Common.UIString('Reveal in sidebar'), this._handleContextMenuReveal.bind(this, uiSourceCode));
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  _appendUISourceCodeFrameItems(event, contextMenu, target) {
-    if (!(target instanceof Sources.UISourceCodeFrame))
-      return;
-    if (target.uiSourceCode().contentType().isFromSourceMap())
-      return;
-    contextMenu.debugSection().appendAction('debugger.evaluate-selection');
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} object
-   */
-  appendUILocationItems(contextMenu, object) {
-    if (!(object instanceof Workspace.UILocation))
-      return;
-    const uiLocation = /** @type {!Workspace.UILocation} */ (object);
-    const uiSourceCode = uiLocation.uiSourceCode;
-
-    const contentType = uiSourceCode.contentType();
-    if (contentType.hasScripts()) {
-      const target = UI.context.flavor(SDK.Target);
-      const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
-      if (debuggerModel && debuggerModel.isPaused()) {
-        contextMenu.debugSection().appendItem(
-            Common.UIString('Continue to here'), this._continueToLocation.bind(this, uiLocation));
-      }
-
-      this._callstackPane.appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode);
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _handleContextMenuReveal(uiSourceCode) {
-    this.editorView.showBoth();
-    this._revealInNavigator(uiSourceCode);
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  _appendRemoteObjectItems(contextMenu, target) {
-    if (!(target instanceof SDK.RemoteObject))
-      return;
-    const remoteObject = /** @type {!SDK.RemoteObject} */ (target);
-    contextMenu.debugSection().appendItem(
-        Common.UIString('Store as global variable'), this._saveToTempVariable.bind(this, remoteObject));
-    if (remoteObject.type === 'function') {
-      contextMenu.debugSection().appendItem(
-          Common.UIString('Show function definition'), this._showFunctionDefinition.bind(this, remoteObject));
-    }
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  _appendNetworkRequestItems(contextMenu, target) {
-    if (!(target instanceof SDK.NetworkRequest))
-      return;
-    const request = /** @type {!SDK.NetworkRequest} */ (target);
-    const uiSourceCode = this._workspace.uiSourceCodeForURL(request.url());
-    if (!uiSourceCode)
-      return;
-    const openText = Common.UIString('Open in Sources panel');
-    contextMenu.revealSection().appendItem(openText, this.showUILocation.bind(this, uiSourceCode.uiLocation(0, 0)));
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} remoteObject
-   */
-  async _saveToTempVariable(remoteObject) {
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (!currentExecutionContext)
-      return;
-
-    const result = await currentExecutionContext.globalObject(/* objectGroup */ '', /* generatePreview */ false);
-    if (!!result.exceptionDetails || !result.object) {
-      failedToSave(result.object || null);
-      return;
-    }
-
-    const globalObject = result.object;
-    const callFunctionResult =
-        await globalObject.callFunctionPromise(saveVariable, [SDK.RemoteObject.toCallArgument(remoteObject)]);
-    globalObject.release();
-    if (callFunctionResult.wasThrown || !callFunctionResult.object || callFunctionResult.object.type !== 'string') {
-      failedToSave(callFunctionResult.object || null);
-    } else {
-      const executionContext = /** @type {!SDK.ExecutionContext} */ (currentExecutionContext);
-      let text = /** @type {string} */ (callFunctionResult.object.value);
-      const message = SDK.consoleModel.addCommandMessage(executionContext, text);
-      text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text);
-      SDK.consoleModel.evaluateCommandInConsole(
-          executionContext, message, text,
-          /* useCommandLineAPI */ false, /* awaitPromise */ false);
-    }
-    if (callFunctionResult.object)
-      callFunctionResult.object.release();
-
-    /**
-     * @suppressReceiverCheck
-     * @this {Window}
-     */
-    function saveVariable(value) {
-      const prefix = 'temp';
-      let index = 1;
-      while ((prefix + index) in this)
-        ++index;
-      const name = prefix + index;
-      this[name] = value;
-      return name;
-    }
-
-    /**
-     * @param {?SDK.RemoteObject} result
-     */
-    function failedToSave(result) {
-      let message = Common.UIString('Failed to save to temp variable.');
-      if (result)
-        message += ' ' + result.description;
-      Common.console.error(message);
-    }
-  }
-
-  /**
-   * @param {!SDK.RemoteObject} remoteObject
-   */
-  _showFunctionDefinition(remoteObject) {
-    remoteObject.debuggerModel().functionDetailsPromise(remoteObject).then(this._didGetFunctionDetails.bind(this));
-  }
-
-  /**
-   * @param {?{location: ?SDK.DebuggerModel.Location}} response
-   */
-  _didGetFunctionDetails(response) {
-    if (!response || !response.location)
-      return;
-
-    const location = response.location;
-    if (!location)
-      return;
-
-    const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location);
-    if (uiLocation)
-      this.showUILocation(uiLocation);
-  }
-
-  _revealNavigatorSidebar() {
-    this._setAsCurrentPanel();
-    this.editorView.showBoth(true);
-  }
-
-  _revealDebuggerSidebar() {
-    this._setAsCurrentPanel();
-    this._splitWidget.showBoth(true);
-  }
-
-  _updateSidebarPosition() {
-    let vertically;
-    const position = Common.moduleSetting('sidebarPosition').get();
-    if (position === 'right')
-      vertically = false;
-    else if (position === 'bottom')
-      vertically = true;
-    else
-      vertically = UI.inspectorView.element.offsetWidth < 680;
-
-    if (this.sidebarPaneView && vertically === !this._splitWidget.isVertical())
-      return;
-
-    if (this.sidebarPaneView && this.sidebarPaneView.shouldHideOnDetach())
-      return;  // We can't reparent extension iframes.
-
-    if (this.sidebarPaneView)
-      this.sidebarPaneView.detach();
-
-    this._splitWidget.setVertical(!vertically);
-    this._splitWidget.element.classList.toggle('sources-split-view-vertical', vertically);
-
-    Sources.SourcesPanel.updateResizerAndSidebarButtons(this);
-
-    // Create vertical box with stack.
-    const vbox = new UI.VBox();
-    vbox.element.appendChild(this._debugToolbarDrawer);
-    vbox.setMinimumAndPreferredSizes(25, 25, Sources.SourcesPanel.minToolbarWidth, 100);
-    this._sidebarPaneStack = UI.viewManager.createStackLocation(this._revealDebuggerSidebar.bind(this));
-    this._sidebarPaneStack.widget().element.classList.add('overflow-auto');
-    this._sidebarPaneStack.widget().show(vbox.element);
-    this._sidebarPaneStack.widget().element.appendChild(this._debuggerPausedMessage.element());
-    vbox.element.appendChild(this._debugToolbar.element);
-
-    if (this._threadsSidebarPane)
-      this._sidebarPaneStack.showView(this._threadsSidebarPane);
-
-    if (!vertically)
-      this._sidebarPaneStack.appendView(this._watchSidebarPane);
-
-    this._sidebarPaneStack.showView(this._callstackPane);
-    const jsBreakpoints = /** @type {!UI.View} */ (UI.viewManager.view('sources.jsBreakpoints'));
-    const scopeChainView = /** @type {!UI.View} */ (UI.viewManager.view('sources.scopeChain'));
-
-    if (this._tabbedLocationHeader) {
-      this._splitWidget.uninstallResizer(this._tabbedLocationHeader);
-      this._tabbedLocationHeader = null;
-    }
-
-    if (!vertically) {
-      // Populate the rest of the stack.
-      this._sidebarPaneStack.showView(scopeChainView);
-      this._sidebarPaneStack.showView(jsBreakpoints);
-      this._extensionSidebarPanesContainer = this._sidebarPaneStack;
-      this.sidebarPaneView = vbox;
-      this._splitWidget.uninstallResizer(this._debugToolbar.gripElementForResize());
-    } else {
-      const splitWidget = new UI.SplitWidget(true, true, 'sourcesPanelDebuggerSidebarSplitViewState', 0.5);
-      splitWidget.setMainWidget(vbox);
-
-      // Populate the left stack.
-      this._sidebarPaneStack.showView(jsBreakpoints);
-
-      const tabbedLocation = UI.viewManager.createTabbedLocation(this._revealDebuggerSidebar.bind(this));
-      splitWidget.setSidebarWidget(tabbedLocation.tabbedPane());
-      this._tabbedLocationHeader = tabbedLocation.tabbedPane().headerElement();
-      this._splitWidget.installResizer(this._tabbedLocationHeader);
-      this._splitWidget.installResizer(this._debugToolbar.gripElementForResize());
-      tabbedLocation.appendView(scopeChainView);
-      tabbedLocation.appendView(this._watchSidebarPane);
-      this._extensionSidebarPanesContainer = tabbedLocation;
-      this.sidebarPaneView = splitWidget;
-    }
-
-    this._sidebarPaneStack.appendApplicableItems('sources-sidebar');
-    const extensionSidebarPanes = Extensions.extensionServer.sidebarPanes();
-    for (let i = 0; i < extensionSidebarPanes.length; ++i)
-      this._addExtensionSidebarPane(extensionSidebarPanes[i]);
-
-    this._splitWidget.setSidebarWidget(this.sidebarPaneView);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _setAsCurrentPanel() {
-    return UI.viewManager.showView('sources');
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _extensionSidebarPaneAdded(event) {
-    const pane = /** @type {!Extensions.ExtensionSidebarPane} */ (event.data);
-    this._addExtensionSidebarPane(pane);
-  }
-
-  /**
-   * @param {!Extensions.ExtensionSidebarPane} pane
-   */
-  _addExtensionSidebarPane(pane) {
-    if (pane.panelName() === this.name)
-      this._extensionSidebarPanesContainer.appendView(pane);
-  }
-
-  /**
-   * @return {!Sources.SourcesView}
-   */
-  sourcesView() {
-    return this._sourcesView;
-  }
-
-  /**
-   * @param {!DataTransfer} dataTransfer
-   */
-  _handleDrop(dataTransfer) {
-    const items = dataTransfer.items;
-    if (!items.length)
-      return;
-    const entry = items[0].webkitGetAsEntry();
-    if (!entry.isDirectory)
-      return;
-    InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem);
-  }
-};
-
-Sources.SourcesPanel._lastModificationTimeout = 200;
-
-Sources.SourcesPanel.minToolbarWidth = 215;
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Sources.SourcesPanel.UILocationRevealer = class {
-  /**
-   * @override
-   * @param {!Object} uiLocation
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  reveal(uiLocation, omitFocus) {
-    if (!(uiLocation instanceof Workspace.UILocation))
-      return Promise.reject(new Error('Internal error: not a ui location'));
-    Sources.SourcesPanel.instance().showUILocation(uiLocation, omitFocus);
-    return Promise.resolve();
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Sources.SourcesPanel.DebuggerLocationRevealer = class {
-  /**
-   * @override
-   * @param {!Object} rawLocation
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  reveal(rawLocation, omitFocus) {
-    if (!(rawLocation instanceof SDK.DebuggerModel.Location))
-      return Promise.reject(new Error('Internal error: not a debugger location'));
-    const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
-    if (!uiLocation)
-      return Promise.resolve();
-    Sources.SourcesPanel.instance().showUILocation(uiLocation, omitFocus);
-    return Promise.resolve();
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Sources.SourcesPanel.UISourceCodeRevealer = class {
-  /**
-   * @override
-   * @param {!Object} uiSourceCode
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  reveal(uiSourceCode, omitFocus) {
-    if (!(uiSourceCode instanceof Workspace.UISourceCode))
-      return Promise.reject(new Error('Internal error: not a ui source code'));
-    Sources.SourcesPanel.instance().showUISourceCode(uiSourceCode, undefined, undefined, omitFocus);
-    return Promise.resolve();
-  }
-};
-
-/**
- * @implements {Common.Revealer}
- * @unrestricted
- */
-Sources.SourcesPanel.DebuggerPausedDetailsRevealer = class {
-  /**
-   * @override
-   * @param {!Object} object
-   * @return {!Promise}
-   */
-  reveal(object) {
-    return Sources.SourcesPanel.instance()._setAsCurrentPanel();
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Sources.SourcesPanel.RevealingActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const panel = Sources.SourcesPanel.instance();
-    if (!panel._ensureSourcesViewVisible())
-      return false;
-    switch (actionId) {
-      case 'debugger.toggle-pause':
-        panel._togglePause();
-        return true;
-    }
-    return false;
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Sources.SourcesPanel.DebuggingActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const panel = Sources.SourcesPanel.instance();
-    switch (actionId) {
-      case 'debugger.step-over':
-        panel._stepOver();
-        return true;
-      case 'debugger.step-into':
-        panel._stepIntoAsync();
-        return true;
-      case 'debugger.step':
-        panel._stepInto();
-        return true;
-      case 'debugger.step-out':
-        panel._stepOut();
-        return true;
-      case 'debugger.run-snippet':
-        panel._runSnippet();
-        return true;
-      case 'debugger.toggle-breakpoints-active':
-        panel._toggleBreakpointsActive();
-        return true;
-      case 'debugger.evaluate-selection':
-        const frame = UI.context.flavor(Sources.UISourceCodeFrame);
-        if (frame) {
-          let text = frame.textEditor.text(frame.textEditor.selection());
-          const executionContext = UI.context.flavor(SDK.ExecutionContext);
-          if (executionContext) {
-            const message = SDK.consoleModel.addCommandMessage(executionContext, text);
-            text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text);
-            SDK.consoleModel.evaluateCommandInConsole(
-                executionContext, message, text, /* useCommandLineAPI */ true, /* awaitPromise */ false);
-          }
-        }
-        return true;
-    }
-    return false;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Sources.SourcesPanel.WrapperView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.element.classList.add('sources-view-wrapper');
-    Sources.SourcesPanel.WrapperView._instance = this;
-    this._view = Sources.SourcesPanel.instance()._sourcesView;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  static isShowing() {
-    return !!Sources.SourcesPanel.WrapperView._instance && Sources.SourcesPanel.WrapperView._instance.isShowing();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (!Sources.SourcesPanel.instance().isShowing())
-      this._showViewInWrapper();
-    else
-      UI.inspectorView.setDrawerMinimized(true);
-    Sources.SourcesPanel.updateResizerAndSidebarButtons(Sources.SourcesPanel.instance());
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.inspectorView.setDrawerMinimized(false);
-    setImmediate(() => Sources.SourcesPanel.updateResizerAndSidebarButtons(Sources.SourcesPanel.instance()));
-  }
-
-  _showViewInWrapper() {
-    this._view.show(this.element);
-  }
-};
diff --git a/front_end/sources/SourcesSearchScope.js b/front_end/sources/SourcesSearchScope.js
deleted file mode 100644
index 23dafdd..0000000
--- a/front_end/sources/SourcesSearchScope.js
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Search.SearchScope}
- */
-Sources.SourcesSearchScope = class {
-  constructor() {
-    // FIXME: Add title once it is used by search controller.
-    this._searchId = 0;
-    /** @type {!Array<!Workspace.UISourceCode>} */
-    this._searchResultCandidates = [];
-    /** @type {?function(!Search.SearchResult)} */
-    this._searchResultCallback = null;
-    /** @type {?function(boolean)} */
-    this._searchFinishedCallback = null;
-    /** @type {?Workspace.ProjectSearchConfig} */
-    this._searchConfig = null;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode1
-   * @param {!Workspace.UISourceCode} uiSourceCode2
-   * @return {number}
-   */
-  static _filesComparator(uiSourceCode1, uiSourceCode2) {
-    if (uiSourceCode1.isDirty() && !uiSourceCode2.isDirty())
-      return -1;
-    if (!uiSourceCode1.isDirty() && uiSourceCode2.isDirty())
-      return 1;
-    const url1 = uiSourceCode1.url();
-    const url2 = uiSourceCode2.url();
-    if (url1 && !url2)
-      return -1;
-    if (!url1 && url2)
-      return 1;
-    return String.naturalOrderComparator(uiSourceCode1.fullDisplayName(), uiSourceCode2.fullDisplayName());
-  }
-
-  /**
-   * @override
-   * @param {!Common.Progress} progress
-   */
-  performIndexing(progress) {
-    this.stopSearch();
-
-    const projects = this._projects();
-    const compositeProgress = new Common.CompositeProgress(progress);
-    for (let i = 0; i < projects.length; ++i) {
-      const project = projects[i];
-      const projectProgress = compositeProgress.createSubProgress(project.uiSourceCodes().length);
-      project.indexContent(projectProgress);
-    }
-  }
-
-  /**
-   * @return {!Array.<!Workspace.Project>}
-   */
-  _projects() {
-    const searchInAnonymousAndContentScripts = Common.moduleSetting('searchInAnonymousAndContentScripts').get();
-
-    return Workspace.workspace.projects().filter(project => {
-      if (project.type() === Workspace.projectTypes.Service)
-        return false;
-      if (!searchInAnonymousAndContentScripts && project.isServiceProject())
-        return false;
-      if (!searchInAnonymousAndContentScripts && project.type() === Workspace.projectTypes.ContentScripts)
-        return false;
-      return true;
-    });
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.ProjectSearchConfig} searchConfig
-   * @param {!Common.Progress} progress
-   * @param {function(!Search.SearchResult)} searchResultCallback
-   * @param {function(boolean)} searchFinishedCallback
-   */
-  performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) {
-    this.stopSearch();
-    this._searchResultCandidates = [];
-    this._searchResultCallback = searchResultCallback;
-    this._searchFinishedCallback = searchFinishedCallback;
-    this._searchConfig = searchConfig;
-
-    const promises = [];
-    const compositeProgress = new Common.CompositeProgress(progress);
-    const searchContentProgress = compositeProgress.createSubProgress();
-    const findMatchingFilesProgress = new Common.CompositeProgress(compositeProgress.createSubProgress());
-    for (const project of this._projects()) {
-      const weight = project.uiSourceCodes().length;
-      const findMatchingFilesInProjectProgress = findMatchingFilesProgress.createSubProgress(weight);
-      const filesMathingFileQuery = this._projectFilesMatchingFileQuery(project, searchConfig);
-      const promise =
-          project
-              .findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, findMatchingFilesInProjectProgress)
-              .then(this._processMatchingFilesForProject.bind(
-                  this, this._searchId, project, searchConfig, filesMathingFileQuery));
-      promises.push(promise);
-    }
-
-    Promise.all(promises).then(this._processMatchingFiles.bind(
-        this, this._searchId, searchContentProgress, this._searchFinishedCallback.bind(this, true)));
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   * @param {!Workspace.ProjectSearchConfig} searchConfig
-   * @param {boolean=} dirtyOnly
-   * @return {!Array.<string>}
-   */
-  _projectFilesMatchingFileQuery(project, searchConfig, dirtyOnly) {
-    const result = [];
-    const uiSourceCodes = project.uiSourceCodes();
-    for (let i = 0; i < uiSourceCodes.length; ++i) {
-      const uiSourceCode = uiSourceCodes[i];
-      if (!uiSourceCode.contentType().isTextType())
-        continue;
-      const binding = Persistence.persistence.binding(uiSourceCode);
-      if (binding && binding.network === uiSourceCode)
-        continue;
-      if (dirtyOnly && !uiSourceCode.isDirty())
-        continue;
-      if (searchConfig.filePathMatchesFileQuery(uiSourceCode.fullDisplayName()))
-        result.push(uiSourceCode.url());
-    }
-    result.sort(String.naturalOrderComparator);
-    return result;
-  }
-
-  /**
-   * @param {number} searchId
-   * @param {!Workspace.Project} project
-   * @param {!Workspace.ProjectSearchConfig} searchConfig
-   * @param {!Array<string>} filesMathingFileQuery
-   * @param {!Array<string>} files
-   */
-  _processMatchingFilesForProject(searchId, project, searchConfig, filesMathingFileQuery, files) {
-    if (searchId !== this._searchId) {
-      this._searchFinishedCallback(false);
-      return;
-    }
-
-    files.sort(String.naturalOrderComparator);
-    files = files.intersectOrdered(filesMathingFileQuery, String.naturalOrderComparator);
-    const dirtyFiles = this._projectFilesMatchingFileQuery(project, searchConfig, true);
-    files = files.mergeOrdered(dirtyFiles, String.naturalOrderComparator);
-
-    const uiSourceCodes = [];
-    for (const file of files) {
-      const uiSourceCode = project.uiSourceCodeForURL(file);
-      if (!uiSourceCode)
-        continue;
-      const script = Bindings.DefaultScriptMapping.scriptForUISourceCode(uiSourceCode);
-      if (script && !script.isAnonymousScript())
-        continue;
-      uiSourceCodes.push(uiSourceCode);
-    }
-    uiSourceCodes.sort(Sources.SourcesSearchScope._filesComparator);
-    this._searchResultCandidates =
-        this._searchResultCandidates.mergeOrdered(uiSourceCodes, Sources.SourcesSearchScope._filesComparator);
-  }
-
-  /**
-   * @param {number} searchId
-   * @param {!Common.Progress} progress
-   * @param {function()} callback
-   */
-  _processMatchingFiles(searchId, progress, callback) {
-    if (searchId !== this._searchId) {
-      this._searchFinishedCallback(false);
-      return;
-    }
-
-    const files = this._searchResultCandidates;
-    if (!files.length) {
-      progress.done();
-      callback();
-      return;
-    }
-
-    progress.setTotalWork(files.length);
-
-    let fileIndex = 0;
-    const maxFileContentRequests = 20;
-    let callbacksLeft = 0;
-
-    for (let i = 0; i < maxFileContentRequests && i < files.length; ++i)
-      scheduleSearchInNextFileOrFinish.call(this);
-
-    /**
-     * @param {!Workspace.UISourceCode} uiSourceCode
-     * @this {Sources.SourcesSearchScope}
-     */
-    function searchInNextFile(uiSourceCode) {
-      if (uiSourceCode.isDirty())
-        contentLoaded.call(this, uiSourceCode, uiSourceCode.workingCopy());
-      else
-        uiSourceCode.requestContent().then(contentLoaded.bind(this, uiSourceCode));
-    }
-
-    /**
-     * @this {Sources.SourcesSearchScope}
-     */
-    function scheduleSearchInNextFileOrFinish() {
-      if (fileIndex >= files.length) {
-        if (!callbacksLeft) {
-          progress.done();
-          callback();
-          return;
-        }
-        return;
-      }
-
-      ++callbacksLeft;
-      const uiSourceCode = files[fileIndex++];
-      setTimeout(searchInNextFile.bind(this, uiSourceCode), 0);
-    }
-
-    /**
-     * @param {!Workspace.UISourceCode} uiSourceCode
-     * @param {?string} content
-     * @this {Sources.SourcesSearchScope}
-     */
-    function contentLoaded(uiSourceCode, content) {
-      /**
-       * @param {!Common.ContentProvider.SearchMatch} a
-       * @param {!Common.ContentProvider.SearchMatch} b
-       */
-      function matchesComparator(a, b) {
-        return a.lineNumber - b.lineNumber;
-      }
-
-      progress.worked(1);
-      let matches = [];
-      const queries = this._searchConfig.queries();
-      if (content !== null) {
-        for (let i = 0; i < queries.length; ++i) {
-          const nextMatches = Common.ContentProvider.performSearchInContent(
-              content, queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex());
-          matches = matches.mergeOrdered(nextMatches, matchesComparator);
-        }
-      }
-      if (matches) {
-        const searchResult = new Sources.FileBasedSearchResult(uiSourceCode, matches);
-        this._searchResultCallback(searchResult);
-      }
-
-      --callbacksLeft;
-      scheduleSearchInNextFileOrFinish.call(this);
-    }
-  }
-
-  /**
-   * @override
-   */
-  stopSearch() {
-    ++this._searchId;
-  }
-};
-
-
-/**
- * @implements {Search.SearchResult}
- */
-Sources.FileBasedSearchResult = class {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Array.<!Common.ContentProvider.SearchMatch>} searchMatches
-   */
-  constructor(uiSourceCode, searchMatches) {
-    this._uiSourceCode = uiSourceCode;
-    this._searchMatches = searchMatches;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  label() {
-    return this._uiSourceCode.displayName();
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  description() {
-    return this._uiSourceCode.fullDisplayName();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  matchesCount() {
-    return this._searchMatches.length;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {string}
-   */
-  matchLineContent(index) {
-    return this._searchMatches[index].lineContent;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {!Object}
-   */
-  matchRevealable(index) {
-    const match = this._searchMatches[index];
-    return this._uiSourceCode.uiLocation(match.lineNumber, match.columnNumber);
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?}
-   */
-  matchLabel(index) {
-    return this._searchMatches[index].lineNumber + 1;
-  }
-};
diff --git a/front_end/sources/SourcesView.js b/front_end/sources/SourcesView.js
deleted file mode 100644
index b57f9e6..0000000
--- a/front_end/sources/SourcesView.js
+++ /dev/null
@@ -1,758 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {Sources.TabbedEditorContainerDelegate}
- * @implements {UI.Searchable}
- * @implements {UI.Replaceable}
- * @unrestricted
- */
-Sources.SourcesView = class extends UI.VBox {
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  constructor() {
-    super();
-    this.registerRequiredCSS('sources/sourcesView.css');
-    this.element.id = 'sources-panel-sources-view';
-    this.setMinimumAndPreferredSizes(88, 52, 150, 100);
-
-    const workspace = Workspace.workspace;
-
-    this._searchableView = new UI.SearchableView(this, 'sourcesViewSearchConfig');
-    this._searchableView.setMinimalSearchQuerySize(0);
-    this._searchableView.show(this.element);
-
-    /** @type {!Map.<!Workspace.UISourceCode, !UI.Widget>} */
-    this._sourceViewByUISourceCode = new Map();
-
-    this._editorContainer = new Sources.TabbedEditorContainer(
-        this, Common.settings.createLocalSetting('previouslyViewedFiles', []), this._placeholderElement());
-    this._editorContainer.show(this._searchableView.element);
-    this._editorContainer.addEventListener(
-        Sources.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
-    this._editorContainer.addEventListener(Sources.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
-
-    this._historyManager = new Sources.EditingLocationHistoryManager(this, this.currentSourceFrame.bind(this));
-
-    this._toolbarContainerElement = this.element.createChild('div', 'sources-toolbar');
-    this._toolbarEditorActions = new UI.Toolbar('', this._toolbarContainerElement);
-
-    self.runtime.allInstances(Sources.SourcesView.EditorAction).then(appendButtonsForExtensions.bind(this));
-    /**
-     * @param {!Array.<!Sources.SourcesView.EditorAction>} actions
-     * @this {Sources.SourcesView}
-     */
-    function appendButtonsForExtensions(actions) {
-      for (let i = 0; i < actions.length; ++i)
-        this._toolbarEditorActions.appendToolbarItem(actions[i].button(this));
-    }
-    this._scriptViewToolbar = new UI.Toolbar('', this._toolbarContainerElement);
-    this._scriptViewToolbar.element.style.flex = 'auto';
-    this._bottomToolbar = new UI.Toolbar('', this._toolbarContainerElement);
-    this._bindingChangeBound = this._onBindingChanged.bind(this);
-
-    /** @type {?Common.EventTarget.EventDescriptor} */
-    this._toolbarChangedListener = null;
-
-    UI.startBatchUpdate();
-    workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
-    UI.endBatchUpdate();
-
-    workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
-    workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
-    workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);
-
-    /**
-     * @param {!Event} event
-     */
-    function handleBeforeUnload(event) {
-      if (event.returnValue)
-        return;
-
-      let unsavedSourceCodes = [];
-      const projects = Workspace.workspace.projectsForType(Workspace.projectTypes.FileSystem);
-      for (let i = 0; i < projects.length; ++i) {
-        unsavedSourceCodes =
-            unsavedSourceCodes.concat(projects[i].uiSourceCodes().filter(sourceCode => sourceCode.isDirty()));
-      }
-
-      if (!unsavedSourceCodes.length)
-        return;
-
-      event.returnValue = Common.UIString('DevTools have unsaved changes that will be permanently lost.');
-      UI.viewManager.showView('sources');
-      for (let i = 0; i < unsavedSourceCodes.length; ++i)
-        Common.Revealer.reveal(unsavedSourceCodes[i]);
-    }
-
-    if (!window.opener)
-      window.addEventListener('beforeunload', handleBeforeUnload, true);
-
-    this._shortcuts = {};
-    this.element.addEventListener('keydown', this._handleKeyDown.bind(this), false);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  _placeholderElement() {
-    const shortcuts = [
-      {actionId: 'quickOpen.show', description: Common.UIString('Open file')},
-      {actionId: 'commandMenu.show', description: Common.UIString('Run command')}
-    ];
-
-    const element = createElementWithClass('span', 'tabbed-pane-placeholder');
-    for (const shortcut of shortcuts) {
-      const shortcutKeyText = UI.shortcutRegistry.shortcutTitleForAction(shortcut.actionId);
-      const row = element.createChild('div', 'tabbed-pane-placeholder-row');
-      row.createChild('div', 'tabbed-pane-placeholder-key').textContent = shortcutKeyText;
-      row.createChild('div', 'tabbed-pane-placeholder-value').textContent = shortcut.description;
-    }
-    element.createChild('div').textContent = Common.UIString('Drop in a folder to add to workspace');
-
-    element.appendChild(UI.XLink.create(
-        'https://developers.google.com/web/tools/chrome-devtools/sources?utm_source=devtools&utm_campaign=2018Q1',
-        'Learn more'));
-
-    return element;
-  }
-
-  /**
-   * @return {!Map.<!Workspace.UISourceCode, number>}
-   */
-  static defaultUISourceCodeScores() {
-    /** @type {!Map.<!Workspace.UISourceCode, number>} */
-    const defaultScores = new Map();
-    const sourcesView = UI.context.flavor(Sources.SourcesView);
-    if (sourcesView) {
-      const uiSourceCodes = sourcesView._editorContainer.historyUISourceCodes();
-      for (let i = 1; i < uiSourceCodes.length; ++i)  // Skip current element
-        defaultScores.set(uiSourceCodes[i], uiSourceCodes.length - i);
-    }
-    return defaultScores;
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  leftToolbar() {
-    return this._editorContainer.leftToolbar();
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  rightToolbar() {
-    return this._editorContainer.rightToolbar();
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  bottomToolbar() {
-    return this._bottomToolbar;
-  }
-
-  /**
-   * @param {!Array.<!UI.KeyboardShortcut.Descriptor>} keys
-   * @param {function(!Event=):boolean} handler
-   */
-  _registerShortcuts(keys, handler) {
-    for (let i = 0; i < keys.length; ++i)
-      this._shortcuts[keys[i].key] = handler;
-  }
-
-  _handleKeyDown(event) {
-    const shortcutKey = UI.KeyboardShortcut.makeKeyFromEvent(event);
-    const handler = this._shortcuts[shortcutKey];
-    if (handler && handler())
-      event.consume(true);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    UI.context.setFlavor(Sources.SourcesView, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.context.setFlavor(Sources.SourcesView, null);
-    super.willHide();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  toolbarContainerElement() {
-    return this._toolbarContainerElement;
-  }
-
-  /**
-   * @return {!UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  visibleView() {
-    return this._editorContainer.visibleView;
-  }
-
-  /**
-   * @return {?Sources.UISourceCodeFrame}
-   */
-  currentSourceFrame() {
-    const view = this.visibleView();
-    if (!(view instanceof Sources.UISourceCodeFrame))
-      return null;
-    return /** @type {!Sources.UISourceCodeFrame} */ (view);
-  }
-
-  /**
-   * @return {?Workspace.UISourceCode}
-   */
-  currentUISourceCode() {
-    return this._editorContainer.currentFile();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _onCloseEditorTab() {
-    const uiSourceCode = this._editorContainer.currentFile();
-    if (!uiSourceCode)
-      return false;
-    this._editorContainer.closeFile(uiSourceCode);
-    return true;
-  }
-
-  _onJumpToPreviousLocation() {
-    this._historyManager.rollback();
-  }
-
-  _onJumpToNextLocation() {
-    this._historyManager.rollover();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._addUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _addUISourceCode(uiSourceCode) {
-    if (uiSourceCode.project().isServiceProject())
-      return;
-    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem &&
-        Persistence.FileSystemWorkspaceBinding.fileSystemType(uiSourceCode.project()) === 'overrides')
-      return;
-    this._editorContainer.addUISourceCode(uiSourceCode);
-  }
-
-  _uiSourceCodeRemoved(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._removeUISourceCodes([uiSourceCode]);
-  }
-
-  /**
-   * @param {!Array.<!Workspace.UISourceCode>} uiSourceCodes
-   */
-  _removeUISourceCodes(uiSourceCodes) {
-    this._editorContainer.removeUISourceCodes(uiSourceCodes);
-    for (let i = 0; i < uiSourceCodes.length; ++i) {
-      this._removeSourceFrame(uiSourceCodes[i]);
-      this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);
-    }
-  }
-
-  _projectRemoved(event) {
-    const project = event.data;
-    const uiSourceCodes = project.uiSourceCodes();
-    this._removeUISourceCodes(uiSourceCodes);
-  }
-
-  _updateScriptViewToolbarItems() {
-    this._scriptViewToolbar.removeToolbarItems();
-    const view = this.visibleView();
-    if (view instanceof UI.SimpleView) {
-      for (const item of (/** @type {?UI.SimpleView} */ (view)).syncToolbarItems())
-        this._scriptViewToolbar.appendToolbarItem(item);
-    }
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number=} lineNumber 0-based
-   * @param {number=} columnNumber
-   * @param {boolean=} omitFocus
-   * @param {boolean=} omitHighlight
-   */
-  showSourceLocation(uiSourceCode, lineNumber, columnNumber, omitFocus, omitHighlight) {
-    this._historyManager.updateCurrentState();
-    this._editorContainer.showFile(uiSourceCode);
-    const currentSourceFrame = this.currentSourceFrame();
-    if (currentSourceFrame && typeof lineNumber === 'number')
-      currentSourceFrame.revealPosition(lineNumber, columnNumber, !omitHighlight);
-    this._historyManager.pushNewState();
-    if (!omitFocus)
-      this.visibleView().focus();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!UI.Widget}
-   */
-  _createSourceView(uiSourceCode) {
-    let sourceFrame;
-    let sourceView;
-    const contentType = uiSourceCode.contentType();
-
-    if (contentType.hasScripts())
-      sourceFrame = new Sources.JavaScriptSourceFrame(uiSourceCode);
-    else if (contentType === Common.resourceTypes.Image)
-      sourceView = new SourceFrame.ImageView(uiSourceCode.mimeType(), uiSourceCode);
-    else if (contentType === Common.resourceTypes.Font)
-      sourceView = new SourceFrame.FontView(uiSourceCode.mimeType(), uiSourceCode);
-    else
-      sourceFrame = new Sources.UISourceCodeFrame(uiSourceCode);
-
-    if (sourceFrame) {
-      sourceFrame.setHighlighterType(uiSourceCode.mimeType());
-      this._historyManager.trackSourceFrameCursorJumps(sourceFrame);
-    }
-    const widget = /** @type {!UI.Widget} */ (sourceFrame || sourceView);
-    this._sourceViewByUISourceCode.set(uiSourceCode, widget);
-    uiSourceCode.addEventListener(Workspace.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this);
-    return widget;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!UI.Widget}
-   */
-  _getOrCreateSourceView(uiSourceCode) {
-    return this._sourceViewByUISourceCode.get(uiSourceCode) || this._createSourceView(uiSourceCode);
-  }
-
-  /**
-   * @param {!Sources.UISourceCodeFrame} sourceFrame
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  _sourceFrameMatchesUISourceCode(sourceFrame, uiSourceCode) {
-    if (uiSourceCode.contentType().hasScripts())
-      return sourceFrame instanceof Sources.JavaScriptSourceFrame;
-    return !(sourceFrame instanceof Sources.JavaScriptSourceFrame);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _recreateSourceFrameIfNeeded(uiSourceCode) {
-    const oldSourceView = this._sourceViewByUISourceCode.get(uiSourceCode);
-    if (!oldSourceView || !(oldSourceView instanceof Sources.UISourceCodeFrame))
-      return;
-    const oldSourceFrame = /** @type {!Sources.UISourceCodeFrame} */ (oldSourceView);
-    if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) {
-      oldSourceFrame.setHighlighterType(uiSourceCode.mimeType());
-    } else {
-      this._editorContainer.removeUISourceCode(uiSourceCode);
-      this._removeSourceFrame(uiSourceCode);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!UI.Widget}
-   */
-  viewForFile(uiSourceCode) {
-    return this._getOrCreateSourceView(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _removeSourceFrame(uiSourceCode) {
-    const sourceView = this._sourceViewByUISourceCode.get(uiSourceCode);
-    this._sourceViewByUISourceCode.remove(uiSourceCode);
-    uiSourceCode.removeEventListener(Workspace.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this);
-    if (sourceView && sourceView instanceof Sources.UISourceCodeFrame)
-      /** @type {!Sources.UISourceCodeFrame} */ (sourceView).dispose();
-  }
-
-  _onBindingChanged() {
-    this.setExecutionLocation(this._executionLocation);
-    this.showSourceLocation(
-        this._executionLocation.uiSourceCode, this._executionLocation.lineNumber, this._executionLocation.columnNumber);
-  }
-
-  clearCurrentExecutionLine() {
-    if (!this._executionLocation)
-      return;
-    Persistence.persistence.unsubscribeFromBindingEvent(this._executionLocation.uiSourceCode, this._bindingChangeBound);
-    this._executionSourceFrame.clearExecutionLine();
-    this._executionSourceFrame = null;
-    this._executionLocation = null;
-  }
-
-  /**
-   * @param {!Workspace.UILocation} uiLocation
-   */
-  setExecutionLocation(uiLocation) {
-    this.clearCurrentExecutionLine();
-    const binding = Persistence.persistence.binding(uiLocation.uiSourceCode);
-    const uiSourceCode = binding ? binding.fileSystem : uiLocation.uiSourceCode;
-    const sourceView = this._getOrCreateSourceView(uiSourceCode);
-    if (!(sourceView instanceof Sources.UISourceCodeFrame))
-      return;
-    Persistence.persistence.subscribeForBindingEvent(uiLocation.uiSourceCode, this._bindingChangeBound);
-    const sourceFrame = /** @type {!Sources.JavaScriptSourceFrame} */ (sourceView);
-    sourceFrame.setExecutionLocation(
-        new Workspace.UILocation(uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber));
-    this._executionSourceFrame = sourceFrame;
-    this._executionLocation = uiLocation;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorClosed(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._historyManager.removeHistoryForSourceCode(uiSourceCode);
-
-    let wasSelected = false;
-    if (!this._editorContainer.currentFile())
-      wasSelected = true;
-
-    // SourcesNavigator does not need to update on EditorClosed.
-    this._removeToolbarChangedListener();
-    this._updateScriptViewToolbarItems();
-    this._searchableView.resetSearch();
-
-    const data = {};
-    data.uiSourceCode = uiSourceCode;
-    data.wasSelected = wasSelected;
-    this.dispatchEventToListeners(Sources.SourcesView.Events.EditorClosed, data);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _editorSelected(event) {
-    const previousSourceFrame =
-        event.data.previousView instanceof Sources.UISourceCodeFrame ? event.data.previousView : null;
-    if (previousSourceFrame)
-      previousSourceFrame.setSearchableView(null);
-    const currentSourceFrame =
-        event.data.currentView instanceof Sources.UISourceCodeFrame ? event.data.currentView : null;
-    if (currentSourceFrame)
-      currentSourceFrame.setSearchableView(this._searchableView);
-
-    this._searchableView.setReplaceable(!!currentSourceFrame && currentSourceFrame.canEditSource());
-    this._searchableView.refreshSearch();
-    this._updateToolbarChangedListener();
-    this._updateScriptViewToolbarItems();
-
-    this.dispatchEventToListeners(Sources.SourcesView.Events.EditorSelected, this._editorContainer.currentFile());
-  }
-
-  _removeToolbarChangedListener() {
-    if (this._toolbarChangedListener)
-      Common.EventTarget.removeEventListeners([this._toolbarChangedListener]);
-    this._toolbarChangedListener = null;
-  }
-
-  _updateToolbarChangedListener() {
-    this._removeToolbarChangedListener();
-    const sourceFrame = this.currentSourceFrame();
-    if (!sourceFrame)
-      return;
-    this._toolbarChangedListener = sourceFrame.addEventListener(
-        Sources.UISourceCodeFrame.Events.ToolbarItemsChanged, this._updateScriptViewToolbarItems, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeTitleChanged(event) {
-    this._recreateSourceFrameIfNeeded(/** @type {!Workspace.UISourceCode} */ (event.data));
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    if (this._searchView)
-      this._searchView.searchCanceled();
-
-    delete this._searchView;
-    delete this._searchConfig;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    const sourceFrame = this.currentSourceFrame();
-    if (!sourceFrame)
-      return;
-
-    this._searchView = sourceFrame;
-    this._searchConfig = searchConfig;
-
-    this._searchView.performSearch(this._searchConfig, shouldJump, jumpBackwards);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._searchView)
-      return;
-
-    if (this._searchView !== this.currentSourceFrame()) {
-      this.performSearch(this._searchConfig, true);
-      return;
-    }
-
-    this._searchView.jumpToNextSearchResult();
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._searchView)
-      return;
-
-    if (this._searchView !== this.currentSourceFrame()) {
-      this.performSearch(this._searchConfig, true);
-      if (this._searchView)
-        this._searchView.jumpToLastSearchResult();
-      return;
-    }
-
-    this._searchView.jumpToPreviousSearchResult();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {string} replacement
-   */
-  replaceSelectionWith(searchConfig, replacement) {
-    const sourceFrame = this.currentSourceFrame();
-    if (!sourceFrame) {
-      console.assert(sourceFrame);
-      return;
-    }
-    sourceFrame.replaceSelectionWith(searchConfig, replacement);
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {string} replacement
-   */
-  replaceAllWith(searchConfig, replacement) {
-    const sourceFrame = this.currentSourceFrame();
-    if (!sourceFrame) {
-      console.assert(sourceFrame);
-      return;
-    }
-    sourceFrame.replaceAllWith(searchConfig, replacement);
-  }
-
-  _showOutlineQuickOpen() {
-    QuickOpen.QuickOpen.show('@');
-  }
-
-  _showGoToLineQuickOpen() {
-    if (this._editorContainer.currentFile())
-      QuickOpen.QuickOpen.show(':');
-  }
-
-  _save() {
-    this._saveSourceFrame(this.currentSourceFrame());
-  }
-
-  _saveAll() {
-    const sourceFrames = this._editorContainer.fileViews();
-    sourceFrames.forEach(this._saveSourceFrame.bind(this));
-  }
-
-  /**
-   * @param {?UI.Widget} sourceFrame
-   */
-  _saveSourceFrame(sourceFrame) {
-    if (!(sourceFrame instanceof Sources.UISourceCodeFrame))
-      return;
-    const uiSourceCodeFrame = /** @type {!Sources.UISourceCodeFrame} */ (sourceFrame);
-    uiSourceCodeFrame.commitEditing();
-  }
-
-  /**
-   * @param {boolean} active
-   */
-  toggleBreakpointsActiveState(active) {
-    this._editorContainer.view.element.classList.toggle('breakpoints-deactivated', !active);
-  }
-};
-
-/** @enum {symbol} */
-Sources.SourcesView.Events = {
-  EditorClosed: Symbol('EditorClosed'),
-  EditorSelected: Symbol('EditorSelected'),
-};
-
-/**
- * @interface
- */
-Sources.SourcesView.EditorAction = function() {};
-
-Sources.SourcesView.EditorAction.prototype = {
-  /**
-   * @param {!Sources.SourcesView} sourcesView
-   * @return {!UI.ToolbarButton}
-   */
-  button(sourcesView) {}
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Sources.SourcesView.SwitchFileActionDelegate = class {
-  /**
-   * @param {!Workspace.UISourceCode} currentUISourceCode
-   * @return {?Workspace.UISourceCode}
-   */
-  static _nextFile(currentUISourceCode) {
-    /**
-     * @param {string} name
-     * @return {string}
-     */
-    function fileNamePrefix(name) {
-      const lastDotIndex = name.lastIndexOf('.');
-      const namePrefix = name.substr(0, lastDotIndex !== -1 ? lastDotIndex : name.length);
-      return namePrefix.toLowerCase();
-    }
-
-    const uiSourceCodes = currentUISourceCode.project().uiSourceCodes();
-    const candidates = [];
-    const url = currentUISourceCode.parentURL();
-    const name = currentUISourceCode.name();
-    const namePrefix = fileNamePrefix(name);
-    for (let i = 0; i < uiSourceCodes.length; ++i) {
-      const uiSourceCode = uiSourceCodes[i];
-      if (url !== uiSourceCode.parentURL())
-        continue;
-      if (fileNamePrefix(uiSourceCode.name()) === namePrefix)
-        candidates.push(uiSourceCode.name());
-    }
-    candidates.sort(String.naturalOrderComparator);
-    const index = mod(candidates.indexOf(name) + 1, candidates.length);
-    const fullURL = (url ? url + '/' : '') + candidates[index];
-    const nextUISourceCode = currentUISourceCode.project().uiSourceCodeForURL(fullURL);
-    return nextUISourceCode !== currentUISourceCode ? nextUISourceCode : null;
-  }
-
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const sourcesView = UI.context.flavor(Sources.SourcesView);
-    const currentUISourceCode = sourcesView.currentUISourceCode();
-    if (!currentUISourceCode)
-      return false;
-    const nextUISourceCode = Sources.SourcesView.SwitchFileActionDelegate._nextFile(currentUISourceCode);
-    if (!nextUISourceCode)
-      return false;
-    sourcesView.showSourceLocation(nextUISourceCode);
-    return true;
-  }
-};
-
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Sources.SourcesView.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const sourcesView = UI.context.flavor(Sources.SourcesView);
-    if (!sourcesView)
-      return false;
-
-    switch (actionId) {
-      case 'sources.close-all':
-        sourcesView._editorContainer.closeAllFiles();
-        return true;
-      case 'sources.jump-to-previous-location':
-        sourcesView._onJumpToPreviousLocation();
-        return true;
-      case 'sources.jump-to-next-location':
-        sourcesView._onJumpToNextLocation();
-        return true;
-      case 'sources.close-editor-tab':
-        return sourcesView._onCloseEditorTab();
-      case 'sources.go-to-line':
-        sourcesView._showGoToLineQuickOpen();
-        return true;
-      case 'sources.go-to-member':
-        sourcesView._showOutlineQuickOpen();
-        return true;
-      case 'sources.save':
-        sourcesView._save();
-        return true;
-      case 'sources.save-all':
-        sourcesView._saveAll();
-        return true;
-    }
-
-    return false;
-  }
-};
diff --git a/front_end/sources/TabbedEditorContainer.js b/front_end/sources/TabbedEditorContainer.js
deleted file mode 100644
index 79bea8e..0000000
--- a/front_end/sources/TabbedEditorContainer.js
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-Sources.TabbedEditorContainerDelegate = function() {};
-
-Sources.TabbedEditorContainerDelegate.prototype = {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!UI.Widget}
-   */
-  viewForFile(uiSourceCode) {},
-};
-
-/**
- * @unrestricted
- */
-Sources.TabbedEditorContainer = class extends Common.Object {
-  /**
-   * @param {!Sources.TabbedEditorContainerDelegate} delegate
-   * @param {!Common.Setting} setting
-   * @param {!Element} placeholderElement
-   */
-  constructor(delegate, setting, placeholderElement) {
-    super();
-    this._delegate = delegate;
-
-    this._tabbedPane = new UI.TabbedPane();
-    this._tabbedPane.setPlaceholderElement(placeholderElement);
-    this._tabbedPane.setTabDelegate(new Sources.EditorContainerTabDelegate(this));
-
-    this._tabbedPane.setCloseableTabs(true);
-    this._tabbedPane.setAllowTabReorder(true, true);
-
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabClosed, this._tabClosed, this);
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-
-    Persistence.persistence.addEventListener(
-        Persistence.Persistence.Events.BindingCreated, this._onBindingCreated, this);
-    Persistence.persistence.addEventListener(
-        Persistence.Persistence.Events.BindingRemoved, this._onBindingRemoved, this);
-
-    this._tabIds = new Map();
-    this._files = {};
-
-    this._previouslyViewedFilesSetting = setting;
-    this._history = Sources.TabbedEditorContainer.History.fromObject(this._previouslyViewedFilesSetting.get());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onBindingCreated(event) {
-    const binding = /** @type {!Persistence.PersistenceBinding} */ (event.data);
-    this._updateFileTitle(binding.fileSystem);
-
-    const networkTabId = this._tabIds.get(binding.network);
-    let fileSystemTabId = this._tabIds.get(binding.fileSystem);
-
-    const wasSelectedInNetwork = this._currentFile === binding.network;
-    const currentSelectionRange = this._history.selectionRange(binding.network.url());
-    const currentScrollLineNumber = this._history.scrollLineNumber(binding.network.url());
-    this._history.remove(binding.network.url());
-
-    if (!networkTabId)
-      return;
-
-    if (!fileSystemTabId) {
-      const tabIndex = this._tabbedPane.tabIndex(networkTabId);
-      fileSystemTabId = this._appendFileTab(binding.fileSystem, false, tabIndex);
-      const fileSystemTabView = /** @type {!UI.Widget} */ (this._tabbedPane.tabView(fileSystemTabId));
-      this._restoreEditorProperties(fileSystemTabView, currentSelectionRange, currentScrollLineNumber);
-    }
-
-    this._closeTabs([networkTabId], true);
-    if (wasSelectedInNetwork)
-      this._tabbedPane.selectTab(fileSystemTabId, false);
-
-    this._updateHistory();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onBindingRemoved(event) {
-    const binding = /** @type {!Persistence.PersistenceBinding} */ (event.data);
-    this._updateFileTitle(binding.fileSystem);
-  }
-
-  /**
-   * @return {!UI.Widget}
-   */
-  get view() {
-    return this._tabbedPane;
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  get visibleView() {
-    return this._tabbedPane.visibleView;
-  }
-
-  /**
-   * @return {!Array.<!UI.Widget>}
-   */
-  fileViews() {
-    return /** @type {!Array.<!UI.Widget>} */ (this._tabbedPane.tabViews());
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  leftToolbar() {
-    return this._tabbedPane.leftToolbar();
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  rightToolbar() {
-    return this._tabbedPane.rightToolbar();
-  }
-
-  /**
-   * @param {!Element} parentElement
-   */
-  show(parentElement) {
-    this._tabbedPane.show(parentElement);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  showFile(uiSourceCode) {
-    this._innerShowFile(uiSourceCode, true);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  closeFile(uiSourceCode) {
-    const tabId = this._tabIds.get(uiSourceCode);
-    if (!tabId)
-      return;
-    this._closeTabs([tabId]);
-  }
-
-  closeAllFiles() {
-    this._closeTabs(this._tabbedPane.allTabs());
-  }
-
-  /**
-   * @return {!Array.<!Workspace.UISourceCode>}
-   */
-  historyUISourceCodes() {
-    // FIXME: there should be a way to fetch UISourceCode for its uri.
-    const uriToUISourceCode = {};
-    for (const id in this._files) {
-      const uiSourceCode = this._files[id];
-      uriToUISourceCode[uiSourceCode.url()] = uiSourceCode;
-    }
-
-    const result = [];
-    const uris = this._history._urls();
-    for (let i = 0; i < uris.length; ++i) {
-      const uiSourceCode = uriToUISourceCode[uris[i]];
-      if (uiSourceCode)
-        result.push(uiSourceCode);
-    }
-    return result;
-  }
-
-  _addViewListeners() {
-    if (!this._currentView || !this._currentView.textEditor)
-      return;
-    this._currentView.textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.ScrollChanged, this._scrollChanged, this);
-    this._currentView.textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.SelectionChanged, this._selectionChanged, this);
-  }
-
-  _removeViewListeners() {
-    if (!this._currentView || !this._currentView.textEditor)
-      return;
-    this._currentView.textEditor.removeEventListener(
-        SourceFrame.SourcesTextEditor.Events.ScrollChanged, this._scrollChanged, this);
-    this._currentView.textEditor.removeEventListener(
-        SourceFrame.SourcesTextEditor.Events.SelectionChanged, this._selectionChanged, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _scrollChanged(event) {
-    if (this._scrollTimer)
-      clearTimeout(this._scrollTimer);
-    const lineNumber = /** @type {number} */ (event.data);
-    this._scrollTimer = setTimeout(saveHistory.bind(this), 100);
-    this._history.updateScrollLineNumber(this._currentFile.url(), lineNumber);
-
-    /**
-     * @this {Sources.TabbedEditorContainer}
-     */
-    function saveHistory() {
-      this._history.save(this._previouslyViewedFilesSetting);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _selectionChanged(event) {
-    const range = /** @type {!TextUtils.TextRange} */ (event.data);
-    this._history.updateSelectionRange(this._currentFile.url(), range);
-    this._history.save(this._previouslyViewedFilesSetting);
-
-    Extensions.extensionServer.sourceSelectionChanged(this._currentFile.url(), range);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {boolean=} userGesture
-   */
-  _innerShowFile(uiSourceCode, userGesture) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-    uiSourceCode = binding ? binding.fileSystem : uiSourceCode;
-    if (this._currentFile === uiSourceCode)
-      return;
-
-    this._removeViewListeners();
-    this._currentFile = uiSourceCode;
-
-    const tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode, userGesture);
-
-    this._tabbedPane.selectTab(tabId, userGesture);
-    if (userGesture)
-      this._editorSelectedByUserAction();
-
-    const previousView = this._currentView;
-    this._currentView = this.visibleView;
-    this._addViewListeners();
-
-    const eventData = {
-      currentFile: this._currentFile,
-      currentView: this._currentView,
-      previousView: previousView,
-      userGesture: userGesture
-    };
-    this.dispatchEventToListeners(Sources.TabbedEditorContainer.Events.EditorSelected, eventData);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  _titleForFile(uiSourceCode) {
-    const maxDisplayNameLength = 30;
-    let title = uiSourceCode.displayName(true).trimMiddle(maxDisplayNameLength);
-    if (uiSourceCode.isDirty())
-      title += '*';
-    return title;
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} nextTabId
-   */
-  _maybeCloseTab(id, nextTabId) {
-    const uiSourceCode = this._files[id];
-    const shouldPrompt = uiSourceCode.isDirty() && uiSourceCode.project().canSetFileContent();
-    // FIXME: this should be replaced with common Save/Discard/Cancel dialog.
-    if (!shouldPrompt ||
-        confirm(Common.UIString('Are you sure you want to close unsaved file: %s?', uiSourceCode.name()))) {
-      uiSourceCode.resetWorkingCopy();
-      if (nextTabId)
-        this._tabbedPane.selectTab(nextTabId, true);
-      this._tabbedPane.closeTab(id, true);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!Array.<string>} ids
-   * @param {boolean=} forceCloseDirtyTabs
-   */
-  _closeTabs(ids, forceCloseDirtyTabs) {
-    const dirtyTabs = [];
-    const cleanTabs = [];
-    for (let i = 0; i < ids.length; ++i) {
-      const id = ids[i];
-      const uiSourceCode = this._files[id];
-      if (!forceCloseDirtyTabs && uiSourceCode.isDirty())
-        dirtyTabs.push(id);
-      else
-        cleanTabs.push(id);
-    }
-    if (dirtyTabs.length)
-      this._tabbedPane.selectTab(dirtyTabs[0], true);
-    this._tabbedPane.closeTabs(cleanTabs, true);
-    for (let i = 0; i < dirtyTabs.length; ++i) {
-      const nextTabId = i + 1 < dirtyTabs.length ? dirtyTabs[i + 1] : null;
-      if (!this._maybeCloseTab(dirtyTabs[i], nextTabId))
-        break;
-    }
-  }
-
-  /**
-   * @param {string} tabId
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _onContextMenu(tabId, contextMenu) {
-    const uiSourceCode = this._files[tabId];
-    if (uiSourceCode)
-      contextMenu.appendApplicableItems(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  addUISourceCode(uiSourceCode) {
-    const binding = Persistence.persistence.binding(uiSourceCode);
-    uiSourceCode = binding ? binding.fileSystem : uiSourceCode;
-    if (this._currentFile === uiSourceCode)
-      return;
-
-    const uri = uiSourceCode.url();
-    const index = this._history.index(uri);
-    if (index === -1)
-      return;
-
-    if (!this._tabIds.has(uiSourceCode))
-      this._appendFileTab(uiSourceCode, false);
-
-    // Select tab if this file was the last to be shown.
-    if (!index) {
-      this._innerShowFile(uiSourceCode, false);
-      return;
-    }
-
-    if (!this._currentFile)
-      return;
-    const currentProjectType = this._currentFile.project().type();
-    const addedProjectType = uiSourceCode.project().type();
-    const snippetsProjectType = Workspace.projectTypes.Snippets;
-    if (this._history.index(this._currentFile.url()) && currentProjectType === snippetsProjectType &&
-        addedProjectType !== snippetsProjectType)
-      this._innerShowFile(uiSourceCode, false);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  removeUISourceCode(uiSourceCode) {
-    this.removeUISourceCodes([uiSourceCode]);
-  }
-
-  /**
-   * @param {!Array.<!Workspace.UISourceCode>} uiSourceCodes
-   */
-  removeUISourceCodes(uiSourceCodes) {
-    const tabIds = [];
-    for (let i = 0; i < uiSourceCodes.length; ++i) {
-      const uiSourceCode = uiSourceCodes[i];
-      const tabId = this._tabIds.get(uiSourceCode);
-      if (tabId)
-        tabIds.push(tabId);
-    }
-    this._tabbedPane.closeTabs(tabIds);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _editorClosedByUserAction(uiSourceCode) {
-    this._history.remove(uiSourceCode.url());
-    this._updateHistory();
-  }
-
-  _editorSelectedByUserAction() {
-    this._updateHistory();
-  }
-
-  _updateHistory() {
-    const tabIds = this._tabbedPane.lastOpenedTabIds(Sources.TabbedEditorContainer.maximalPreviouslyViewedFilesCount);
-
-    /**
-     * @param {string} tabId
-     * @this {Sources.TabbedEditorContainer}
-     */
-    function tabIdToURI(tabId) {
-      return this._files[tabId].url();
-    }
-
-    this._history.update(tabIds.map(tabIdToURI.bind(this)));
-    this._history.save(this._previouslyViewedFilesSetting);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  _tooltipForFile(uiSourceCode) {
-    uiSourceCode = Persistence.persistence.fileSystem(uiSourceCode) || uiSourceCode;
-    return uiSourceCode.url();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {boolean=} userGesture
-   * @param {number=} index
-   * @return {string}
-   */
-  _appendFileTab(uiSourceCode, userGesture, index) {
-    const view = this._delegate.viewForFile(uiSourceCode);
-    const title = this._titleForFile(uiSourceCode);
-    const tooltip = this._tooltipForFile(uiSourceCode);
-
-    const tabId = this._generateTabId();
-    this._tabIds.set(uiSourceCode, tabId);
-    this._files[tabId] = uiSourceCode;
-
-    const savedSelectionRange = this._history.selectionRange(uiSourceCode.url());
-    const savedScrollLineNumber = this._history.scrollLineNumber(uiSourceCode.url());
-    this._restoreEditorProperties(view, savedSelectionRange, savedScrollLineNumber);
-
-    this._tabbedPane.appendTab(tabId, title, view, tooltip, userGesture, undefined, index);
-
-    this._updateFileTitle(uiSourceCode);
-    this._addUISourceCodeListeners(uiSourceCode);
-    return tabId;
-  }
-
-  /**
-   * @param {!UI.Widget} editorView
-   * @param {!TextUtils.TextRange=} selection
-   * @param {number=} firstLineNumber
-   */
-  _restoreEditorProperties(editorView, selection, firstLineNumber) {
-    const sourceFrame =
-        editorView instanceof SourceFrame.SourceFrame ? /** @type {!SourceFrame.SourceFrame} */ (editorView) : null;
-    if (!sourceFrame)
-      return;
-    if (selection)
-      sourceFrame.setSelection(selection);
-    if (typeof firstLineNumber === 'number')
-      sourceFrame.scrollToLine(firstLineNumber);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabClosed(event) {
-    const tabId = /** @type {string} */ (event.data.tabId);
-    const userGesture = /** @type {boolean} */ (event.data.isUserGesture);
-
-    const uiSourceCode = this._files[tabId];
-    if (this._currentFile === uiSourceCode) {
-      this._removeViewListeners();
-      delete this._currentView;
-      delete this._currentFile;
-    }
-    this._tabIds.remove(uiSourceCode);
-    delete this._files[tabId];
-
-    this._removeUISourceCodeListeners(uiSourceCode);
-
-    this.dispatchEventToListeners(Sources.TabbedEditorContainer.Events.EditorClosed, uiSourceCode);
-
-    if (userGesture)
-      this._editorClosedByUserAction(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabSelected(event) {
-    const tabId = /** @type {string} */ (event.data.tabId);
-    const userGesture = /** @type {boolean} */ (event.data.isUserGesture);
-
-    const uiSourceCode = this._files[tabId];
-    this._innerShowFile(uiSourceCode, userGesture);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _addUISourceCodeListeners(uiSourceCode) {
-    uiSourceCode.addEventListener(Workspace.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this);
-    uiSourceCode.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeWorkingCopyChanged, this);
-    uiSourceCode.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeWorkingCopyCommitted, this);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _removeUISourceCodeListeners(uiSourceCode) {
-    uiSourceCode.removeEventListener(Workspace.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleChanged, this);
-    uiSourceCode.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeWorkingCopyChanged, this);
-    uiSourceCode.removeEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeWorkingCopyCommitted, this);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _updateFileTitle(uiSourceCode) {
-    const tabId = this._tabIds.get(uiSourceCode);
-    if (tabId) {
-      const title = this._titleForFile(uiSourceCode);
-      this._tabbedPane.changeTabTitle(tabId, title);
-      let icon = null;
-      if (Persistence.persistence.hasUnsavedCommittedChanges(uiSourceCode)) {
-        icon = UI.Icon.create('smallicon-warning');
-        icon.title = Common.UIString('Changes to this file were not saved to file system.');
-      } else {
-        icon = Persistence.PersistenceUtils.iconForUISourceCode(uiSourceCode);
-      }
-      this._tabbedPane.setTabIcon(tabId, icon);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeTitleChanged(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._updateFileTitle(uiSourceCode);
-    this._updateHistory();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeWorkingCopyChanged(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._updateFileTitle(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeWorkingCopyCommitted(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    this._updateFileTitle(uiSourceCode);
-  }
-
-  /**
-   * @return {string}
-   */
-  _generateTabId() {
-    return 'tab_' + (Sources.TabbedEditorContainer._tabId++);
-  }
-
-  /**
-   * @return {?Workspace.UISourceCode} uiSourceCode
-   */
-  currentFile() {
-    return this._currentFile || null;
-  }
-};
-
-/** @enum {symbol} */
-Sources.TabbedEditorContainer.Events = {
-  EditorSelected: Symbol('EditorSelected'),
-  EditorClosed: Symbol('EditorClosed')
-};
-
-Sources.TabbedEditorContainer._tabId = 0;
-
-Sources.TabbedEditorContainer.maximalPreviouslyViewedFilesCount = 30;
-
-/**
- * @unrestricted
- */
-Sources.TabbedEditorContainer.HistoryItem = class {
-  /**
-   * @param {string} url
-   * @param {!TextUtils.TextRange=} selectionRange
-   * @param {number=} scrollLineNumber
-   */
-  constructor(url, selectionRange, scrollLineNumber) {
-    /** @const */ this.url = url;
-    /** @const */ this._isSerializable =
-        url.length < Sources.TabbedEditorContainer.HistoryItem.serializableUrlLengthLimit;
-    this.selectionRange = selectionRange;
-    this.scrollLineNumber = scrollLineNumber;
-  }
-
-  /**
-   * @param {!Object} serializedHistoryItem
-   * @return {!Sources.TabbedEditorContainer.HistoryItem}
-   */
-  static fromObject(serializedHistoryItem) {
-    const selectionRange = serializedHistoryItem.selectionRange ?
-        TextUtils.TextRange.fromObject(serializedHistoryItem.selectionRange) :
-        undefined;
-    return new Sources.TabbedEditorContainer.HistoryItem(
-        serializedHistoryItem.url, selectionRange, serializedHistoryItem.scrollLineNumber);
-  }
-
-  /**
-   * @return {?Object}
-   */
-  serializeToObject() {
-    if (!this._isSerializable)
-      return null;
-    const serializedHistoryItem = {};
-    serializedHistoryItem.url = this.url;
-    serializedHistoryItem.selectionRange = this.selectionRange;
-    serializedHistoryItem.scrollLineNumber = this.scrollLineNumber;
-    return serializedHistoryItem;
-  }
-};
-
-Sources.TabbedEditorContainer.HistoryItem.serializableUrlLengthLimit = 4096;
-
-
-/**
- * @unrestricted
- */
-Sources.TabbedEditorContainer.History = class {
-  /**
-   * @param {!Array.<!Sources.TabbedEditorContainer.HistoryItem>} items
-   */
-  constructor(items) {
-    this._items = items;
-    this._rebuildItemIndex();
-  }
-
-  /**
-   * @param {!Array.<!Object>} serializedHistory
-   * @return {!Sources.TabbedEditorContainer.History}
-   */
-  static fromObject(serializedHistory) {
-    const items = [];
-    for (let i = 0; i < serializedHistory.length; ++i)
-      items.push(Sources.TabbedEditorContainer.HistoryItem.fromObject(serializedHistory[i]));
-    return new Sources.TabbedEditorContainer.History(items);
-  }
-
-  /**
-   * @param {string} url
-   * @return {number}
-   */
-  index(url) {
-    return this._itemsIndex.has(url) ? /** @type {number} */ (this._itemsIndex.get(url)) : -1;
-  }
-
-  _rebuildItemIndex() {
-    /** @type {!Map<string, number>} */
-    this._itemsIndex = new Map();
-    for (let i = 0; i < this._items.length; ++i) {
-      console.assert(!this._itemsIndex.has(this._items[i].url));
-      this._itemsIndex.set(this._items[i].url, i);
-    }
-  }
-
-  /**
-   * @param {string} url
-   * @return {!TextUtils.TextRange|undefined}
-   */
-  selectionRange(url) {
-    const index = this.index(url);
-    return index !== -1 ? this._items[index].selectionRange : undefined;
-  }
-
-  /**
-   * @param {string} url
-   * @param {!TextUtils.TextRange=} selectionRange
-   */
-  updateSelectionRange(url, selectionRange) {
-    if (!selectionRange)
-      return;
-    const index = this.index(url);
-    if (index === -1)
-      return;
-    this._items[index].selectionRange = selectionRange;
-  }
-
-  /**
-   * @param {string} url
-   * @return {number|undefined}
-   */
-  scrollLineNumber(url) {
-    const index = this.index(url);
-    return index !== -1 ? this._items[index].scrollLineNumber : undefined;
-  }
-
-  /**
-   * @param {string} url
-   * @param {number} scrollLineNumber
-   */
-  updateScrollLineNumber(url, scrollLineNumber) {
-    const index = this.index(url);
-    if (index === -1)
-      return;
-    this._items[index].scrollLineNumber = scrollLineNumber;
-  }
-
-  /**
-   * @param {!Array.<string>} urls
-   */
-  update(urls) {
-    for (let i = urls.length - 1; i >= 0; --i) {
-      const index = this.index(urls[i]);
-      let item;
-      if (index !== -1) {
-        item = this._items[index];
-        this._items.splice(index, 1);
-      } else {
-        item = new Sources.TabbedEditorContainer.HistoryItem(urls[i]);
-      }
-      this._items.unshift(item);
-      this._rebuildItemIndex();
-    }
-  }
-
-  /**
-   * @param {string} url
-   */
-  remove(url) {
-    const index = this.index(url);
-    if (index !== -1) {
-      this._items.splice(index, 1);
-      this._rebuildItemIndex();
-    }
-  }
-
-  /**
-   * @param {!Common.Setting} setting
-   */
-  save(setting) {
-    setting.set(this._serializeToObject());
-  }
-
-  /**
-   * @return {!Array.<!Object>}
-   */
-  _serializeToObject() {
-    const serializedHistory = [];
-    for (let i = 0; i < this._items.length; ++i) {
-      const serializedItem = this._items[i].serializeToObject();
-      if (serializedItem)
-        serializedHistory.push(serializedItem);
-      if (serializedHistory.length === Sources.TabbedEditorContainer.maximalPreviouslyViewedFilesCount)
-        break;
-    }
-    return serializedHistory;
-  }
-
-  /**
-   * @return {!Array.<string>}
-   */
-  _urls() {
-    const result = [];
-    for (let i = 0; i < this._items.length; ++i)
-      result.push(this._items[i].url);
-    return result;
-  }
-};
-
-
-/**
- * @implements {UI.TabbedPaneTabDelegate}
- * @unrestricted
- */
-Sources.EditorContainerTabDelegate = class {
-  /**
-   * @param {!Sources.TabbedEditorContainer} editorContainer
-   */
-  constructor(editorContainer) {
-    this._editorContainer = editorContainer;
-  }
-
-  /**
-   * @override
-   * @param {!UI.TabbedPane} tabbedPane
-   * @param {!Array.<string>} ids
-   */
-  closeTabs(tabbedPane, ids) {
-    this._editorContainer._closeTabs(ids);
-  }
-
-  /**
-   * @override
-   * @param {string} tabId
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  onContextMenu(tabId, contextMenu) {
-    this._editorContainer._onContextMenu(tabId, contextMenu);
-  }
-};
diff --git a/front_end/sources/ThreadsSidebarPane.js b/front_end/sources/ThreadsSidebarPane.js
deleted file mode 100644
index e9c36de..0000000
--- a/front_end/sources/ThreadsSidebarPane.js
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- * @implements {UI.ListDelegate<!SDK.DebuggerModel>}
- */
-Sources.ThreadsSidebarPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('sources/threadsSidebarPane.css');
-
-    /** @type {!UI.ListModel<!SDK.DebuggerModel>} */
-    this._items = new UI.ListModel();
-    /** @type {!UI.ListControl<!SDK.DebuggerModel>} */
-    this._list = new UI.ListControl(this._items, this, UI.ListMode.NonViewport);
-    this.contentElement.appendChild(this._list.element);
-
-    UI.context.addFlavorChangeListener(SDK.Target, this._targetFlavorChanged, this);
-    SDK.targetManager.observeModels(SDK.DebuggerModel, this);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  static shouldBeShown() {
-    return SDK.targetManager.models(SDK.DebuggerModel).length >= 2;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @return {!Element}
-   */
-  createElementForItem(debuggerModel) {
-    const element = createElementWithClass('div', 'thread-item');
-    const title = element.createChild('div', 'thread-item-title');
-    const pausedState = element.createChild('div', 'thread-item-paused-state');
-    element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-thread-icon'));
-
-    function updateTitle() {
-      const executionContext = debuggerModel.runtimeModel().defaultExecutionContext();
-      title.textContent =
-          executionContext && executionContext.label() ? executionContext.label() : debuggerModel.target().name();
-    }
-
-    function updatePausedState() {
-      pausedState.textContent = Common.UIString(debuggerModel.isPaused() ? 'paused' : '');
-    }
-
-    /**
-     * @param {!Common.Event} event
-     */
-    function targetNameChanged(event) {
-      const target = /** @type {!SDK.Target} */ (event.data);
-      if (target === debuggerModel.target())
-        updateTitle();
-    }
-
-    debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerPaused, updatePausedState);
-    debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerResumed, updatePausedState);
-    debuggerModel.runtimeModel().addEventListener(SDK.RuntimeModel.Events.ExecutionContextChanged, updateTitle);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.NameChanged, targetNameChanged);
-
-    updatePausedState();
-    updateTitle();
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @return {number}
-   */
-  heightForItem(debuggerModel) {
-    console.assert(false);  // Should not be called.
-    return 0;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   * @return {boolean}
-   */
-  isItemSelectable(debuggerModel) {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?SDK.DebuggerModel} from
-   * @param {?SDK.DebuggerModel} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('selected');
-    if (toElement)
-      toElement.classList.add('selected');
-    if (to)
-      UI.context.setFlavor(SDK.Target, to.target());
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelAdded(debuggerModel) {
-    this._items.insert(this._items.length, debuggerModel);
-    const currentTarget = UI.context.flavor(SDK.Target);
-    if (currentTarget === debuggerModel.target())
-      this._list.selectItem(debuggerModel);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.DebuggerModel} debuggerModel
-   */
-  modelRemoved(debuggerModel) {
-    this._items.remove(this._items.indexOf(debuggerModel));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _targetFlavorChanged(event) {
-    const target = /** @type {!SDK.Target} */ (event.data);
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (debuggerModel)
-      this._list.selectItem(debuggerModel);
-  }
-};
diff --git a/front_end/sources/UISourceCodeFrame.js b/front_end/sources/UISourceCodeFrame.js
deleted file mode 100644
index 8edfc6c..0000000
--- a/front_end/sources/UISourceCodeFrame.js
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Sources.UISourceCodeFrame = class extends SourceFrame.SourceFrame {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  constructor(uiSourceCode) {
-    super(workingCopy);
-    this._uiSourceCode = uiSourceCode;
-    this.setEditable(this._canEditSource());
-
-    if (Runtime.experiments.isEnabled('sourceDiff'))
-      this._diff = new SourceFrame.SourceCodeDiff(WorkspaceDiff.workspaceDiff(), this.textEditor);
-
-    this._muteSourceCodeEvents = false;
-    this._isSettingContent = false;
-
-    /** @type {?Persistence.PersistenceBinding} */
-    this._persistenceBinding = Persistence.persistence.binding(uiSourceCode);
-
-    /** @type {!Map<number, !Sources.UISourceCodeFrame.RowMessageBucket>} */
-    this._rowMessageBuckets = new Map();
-    /** @type {!Set<string>} */
-    this._typeDecorationsPending = new Set();
-    this._uiSourceCode.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
-    this._uiSourceCode.addEventListener(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
-
-    this._messageAndDecorationListeners = [];
-    this._installMessageAndDecorationListeners();
-
-    Persistence.persistence.subscribeForBindingEvent(this._uiSourceCode, this._onBindingChanged.bind(this));
-
-    this.textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.EditorBlurred,
-        () => UI.context.setFlavor(Sources.UISourceCodeFrame, null));
-    this.textEditor.addEventListener(
-        SourceFrame.SourcesTextEditor.Events.EditorFocused,
-        () => UI.context.setFlavor(Sources.UISourceCodeFrame, this));
-    Common.settings.moduleSetting('persistenceNetworkOverridesEnabled')
-        .addChangeListener(this._onNetworkPersistenceChanged, this);
-
-    this._updateStyle();
-    this._updateDiffUISourceCode();
-
-    this._errorPopoverHelper = new UI.PopoverHelper(this.element, this._getErrorPopoverContent.bind(this));
-    this._errorPopoverHelper.setHasPadding(true);
-
-    this._errorPopoverHelper.setTimeout(100, 100);
-
-    /** @type {!Array<!Sources.UISourceCodeFrame.Plugin>} */
-    this._plugins = [];
-
-    /**
-     * @return {!Promise<?string>}
-     */
-    function workingCopy() {
-      if (uiSourceCode.isDirty())
-        return /** @type {!Promise<?string>} */ (Promise.resolve(uiSourceCode.workingCopy()));
-      return uiSourceCode.requestContent();
-    }
-  }
-
-  _installMessageAndDecorationListeners() {
-    if (this._persistenceBinding) {
-      const networkSourceCode = this._persistenceBinding.network;
-      const fileSystemSourceCode = this._persistenceBinding.fileSystem;
-      this._messageAndDecorationListeners = [
-        networkSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageAdded, this._onMessageAdded, this),
-        networkSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageRemoved, this._onMessageRemoved, this),
-        networkSourceCode.addEventListener(
-            Workspace.UISourceCode.Events.LineDecorationAdded, this._onLineDecorationAdded, this),
-        networkSourceCode.addEventListener(
-            Workspace.UISourceCode.Events.LineDecorationRemoved, this._onLineDecorationRemoved, this),
-
-        fileSystemSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageAdded, this._onMessageAdded, this),
-        fileSystemSourceCode.addEventListener(
-            Workspace.UISourceCode.Events.MessageRemoved, this._onMessageRemoved, this),
-      ];
-    } else {
-      this._messageAndDecorationListeners = [
-        this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageAdded, this._onMessageAdded, this),
-        this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageRemoved, this._onMessageRemoved, this),
-        this._uiSourceCode.addEventListener(
-            Workspace.UISourceCode.Events.LineDecorationAdded, this._onLineDecorationAdded, this),
-        this._uiSourceCode.addEventListener(
-            Workspace.UISourceCode.Events.LineDecorationRemoved, this._onLineDecorationRemoved, this)
-      ];
-    }
-  }
-
-  /**
-   * @return {!Workspace.UISourceCode}
-   */
-  uiSourceCode() {
-    return this._uiSourceCode;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    // We need CodeMirrorTextEditor to be initialized prior to this call as it calls |cursorPositionToCoordinates| internally. @see crbug.com/506566
-    setImmediate(this._updateBucketDecorations.bind(this));
-    this.setEditable(this._canEditSource());
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    super.willHide();
-    UI.context.setFlavor(Sources.UISourceCodeFrame, null);
-    this._uiSourceCode.removeWorkingCopyGetter();
-  }
-
-  /**
-   * @override
-   * @param {string} highlighterType
-   */
-  setHighlighterType(highlighterType) {
-    super.setHighlighterType(highlighterType);
-    if (this.loaded)
-      this._refreshPlugins();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _canEditSource() {
-    if (Persistence.persistence.binding(this._uiSourceCode))
-      return true;
-    if (this._uiSourceCode.project().canSetFileContent())
-      return true;
-    if (this._uiSourceCode.project().isServiceProject())
-      return false;
-    if (this._uiSourceCode.project().type() === Workspace.projectTypes.Network &&
-        Persistence.networkPersistenceManager.active())
-      return true;
-    return this._uiSourceCode.contentType() !== Common.resourceTypes.Document;
-  }
-
-  _onNetworkPersistenceChanged() {
-    this.setEditable(this._canEditSource());
-  }
-
-  commitEditing() {
-    if (!this._uiSourceCode.isDirty())
-      return;
-
-    this._muteSourceCodeEvents = true;
-    this._uiSourceCode.commitWorkingCopy();
-    this._muteSourceCodeEvents = false;
-  }
-
-  /**
-   * @override
-   */
-  onTextEditorContentSet() {
-    super.onTextEditorContentSet();
-    for (const message of this._allMessages())
-      this._addMessageToSource(message);
-    this._decorateAllTypes();
-    this._refreshPlugins();
-  }
-
-  /**
-   * @return {!Set<!Workspace.UISourceCode.Message>}
-   */
-  _allMessages() {
-    if (this._persistenceBinding) {
-      const combinedSet = this._persistenceBinding.network.messages();
-      combinedSet.addAll(this._persistenceBinding.fileSystem.messages());
-      return combinedSet;
-    }
-    return this._uiSourceCode.messages();
-  }
-
-  /**
-   * @override
-   * @param {!TextUtils.TextRange} oldRange
-   * @param {!TextUtils.TextRange} newRange
-   */
-  onTextChanged(oldRange, newRange) {
-    super.onTextChanged(oldRange, newRange);
-    this._errorPopoverHelper.hidePopover();
-    if (this._isSettingContent)
-      return;
-    this._muteSourceCodeEvents = true;
-    if (this.textEditor.isClean())
-      this._uiSourceCode.resetWorkingCopy();
-    else
-      this._uiSourceCode.setWorkingCopyGetter(this.textEditor.text.bind(this.textEditor));
-    this._muteSourceCodeEvents = false;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWorkingCopyChanged(event) {
-    if (this._muteSourceCodeEvents)
-      return;
-    this._innerSetContent(this._uiSourceCode.workingCopy());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWorkingCopyCommitted(event) {
-    if (!this._muteSourceCodeEvents)
-      this._innerSetContent(this._uiSourceCode.workingCopy());
-    this.textEditor.markClean();
-    this._updateStyle();
-  }
-
-  _refreshPlugins() {
-    this._disposePlugins();
-    const binding = Persistence.persistence.binding(this._uiSourceCode);
-    const pluginUISourceCode = binding ? binding.network : this._uiSourceCode;
-
-    // The order of these plugins matters for toolbar items
-    if (Sources.CSSPlugin.accepts(pluginUISourceCode))
-      this._plugins.push(new Sources.CSSPlugin(this.textEditor));
-    if (Sources.JavaScriptCompilerPlugin.accepts(pluginUISourceCode))
-      this._plugins.push(new Sources.JavaScriptCompilerPlugin(this.textEditor, pluginUISourceCode));
-    if (Sources.SnippetsPlugin.accepts(pluginUISourceCode))
-      this._plugins.push(new Sources.SnippetsPlugin(this.textEditor, pluginUISourceCode));
-
-    this.dispatchEventToListeners(Sources.UISourceCodeFrame.Events.ToolbarItemsChanged);
-  }
-
-  _disposePlugins() {
-    for (const plugin of this._plugins)
-      plugin.dispose();
-    this._plugins = [];
-  }
-
-  _onBindingChanged() {
-    const binding = Persistence.persistence.binding(this._uiSourceCode);
-    if (binding === this._persistenceBinding)
-      return;
-    for (const message of this._allMessages())
-      this._removeMessageFromSource(message);
-    Common.EventTarget.removeEventListeners(this._messageAndDecorationListeners);
-
-    this._persistenceBinding = binding;
-
-    for (const message of this._allMessages())
-      this._addMessageToSource(message);
-    this._installMessageAndDecorationListeners();
-    this._updateStyle();
-    this._decorateAllTypes();
-    this._updateDiffUISourceCode();
-    this.onBindingChanged();
-    this._refreshPlugins();
-  }
-
-  /**
-   * @protected
-   */
-  onBindingChanged() {
-    // Overriden in subclasses.
-  }
-
-  _updateDiffUISourceCode() {
-    if (!this._diff)
-      return;
-    if (this._persistenceBinding)
-      this._diff.setUISourceCode(this._persistenceBinding.network);
-    else if (this._uiSourceCode.project().type() === Workspace.projectTypes.Network)
-      this._diff.setUISourceCode(this._uiSourceCode);
-    else
-      this._diff.setUISourceCode(null);
-  }
-
-  _updateStyle() {
-    this.setEditable(this._canEditSource());
-  }
-
-  /**
-   * @param {string} content
-   */
-  _innerSetContent(content) {
-    this._isSettingContent = true;
-    if (this._diff) {
-      const oldContent = this.textEditor.text();
-      this.setContent(content);
-      this._diff.highlightModifiedLines(oldContent, content);
-    } else {
-      this.setContent(content);
-    }
-    this._isSettingContent = false;
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {
-    /**
-     * @this {Sources.UISourceCodeFrame}
-     */
-    function appendItems() {
-      contextMenu.appendApplicableItems(this._uiSourceCode);
-      contextMenu.appendApplicableItems(new Workspace.UILocation(this._uiSourceCode, lineNumber, columnNumber));
-      contextMenu.appendApplicableItems(this);
-    }
-
-    return super.populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber).then(appendItems.bind(this));
-  }
-
-  /**
-   * @param {!Array.<!UI.Infobar|undefined>} infobars
-   */
-  attachInfobars(infobars) {
-    for (let i = infobars.length - 1; i >= 0; --i) {
-      const infobar = infobars[i];
-      if (!infobar)
-        continue;
-      this.element.insertBefore(infobar.element, this.element.children[0]);
-      infobar.setParentView(this);
-    }
-    this.doResize();
-  }
-
-  dispose() {
-    this._errorPopoverHelper.dispose();
-    this._disposePlugins();
-    if (this._diff)
-      this._diff.dispose();
-    this.textEditor.dispose();
-    this.detach();
-    Common.settings.moduleSetting('persistenceNetworkOverridesEnabled')
-        .removeChangeListener(this._onNetworkPersistenceChanged, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onMessageAdded(event) {
-    const message = /** @type {!Workspace.UISourceCode.Message} */ (event.data);
-    this._addMessageToSource(message);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message} message
-   */
-  _addMessageToSource(message) {
-    if (!this.loaded)
-      return;
-    let lineNumber = message.lineNumber();
-    if (lineNumber >= this.textEditor.linesCount)
-      lineNumber = this.textEditor.linesCount - 1;
-    if (lineNumber < 0)
-      lineNumber = 0;
-
-    let messageBucket = this._rowMessageBuckets.get(lineNumber);
-    if (!messageBucket) {
-      messageBucket = new Sources.UISourceCodeFrame.RowMessageBucket(this, this.textEditor, lineNumber);
-      this._rowMessageBuckets.set(lineNumber, messageBucket);
-    }
-    messageBucket.addMessage(message);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onMessageRemoved(event) {
-    const message = /** @type {!Workspace.UISourceCode.Message} */ (event.data);
-    this._removeMessageFromSource(message);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message} message
-   */
-  _removeMessageFromSource(message) {
-    if (!this.loaded)
-      return;
-
-    let lineNumber = message.lineNumber();
-    if (lineNumber >= this.textEditor.linesCount)
-      lineNumber = this.textEditor.linesCount - 1;
-    if (lineNumber < 0)
-      lineNumber = 0;
-
-    const messageBucket = this._rowMessageBuckets.get(lineNumber);
-    if (!messageBucket)
-      return;
-    messageBucket.removeMessage(message);
-    if (!messageBucket.uniqueMessagesCount()) {
-      messageBucket.detachFromEditor();
-      this._rowMessageBuckets.delete(lineNumber);
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {?UI.PopoverRequest}
-   */
-  _getErrorPopoverContent(event) {
-    const element = event.target.enclosingNodeOrSelfWithClass('text-editor-line-decoration-icon') ||
-        event.target.enclosingNodeOrSelfWithClass('text-editor-line-decoration-wave');
-    if (!element)
-      return null;
-    const anchor = element.enclosingNodeOrSelfWithClass('text-editor-line-decoration-icon') ?
-        element.boxInWindow() :
-        new AnchorBox(event.clientX, event.clientY, 1, 1);
-    return {
-      box: anchor,
-      show: popover => {
-        const messageBucket = element.enclosingNodeOrSelfWithClass('text-editor-line-decoration')._messageBucket;
-        const messagesOutline = messageBucket.messagesDescription();
-        popover.contentElement.appendChild(messagesOutline);
-        return Promise.resolve(true);
-      }
-    };
-  }
-
-  _updateBucketDecorations() {
-    for (const bucket of this._rowMessageBuckets.values())
-      bucket._updateDecoration();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onLineDecorationAdded(event) {
-    const marker = /** @type {!Workspace.UISourceCode.LineMarker} */ (event.data);
-    this._decorateTypeThrottled(marker.type());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onLineDecorationRemoved(event) {
-    const marker = /** @type {!Workspace.UISourceCode.LineMarker} */ (event.data);
-    this._decorateTypeThrottled(marker.type());
-  }
-
-  /**
-   * @param {string} type
-   */
-  _decorateTypeThrottled(type) {
-    if (this._typeDecorationsPending.has(type))
-      return;
-    this._typeDecorationsPending.add(type);
-    self.runtime.extensions(SourceFrame.LineDecorator)
-        .find(extension => extension.descriptor()['decoratorType'] === type)
-        .instance()
-        .then(decorator => {
-          this._typeDecorationsPending.delete(type);
-          this.textEditor.codeMirror().operation(() => {
-            decorator.decorate(
-                this._persistenceBinding ? this._persistenceBinding.network : this.uiSourceCode(), this.textEditor);
-          });
-        });
-  }
-
-  _decorateAllTypes() {
-    for (const extension of self.runtime.extensions(SourceFrame.LineDecorator)) {
-      const type = extension.descriptor()['decoratorType'];
-      if (this._uiSourceCode.decorationsForType(type))
-        this._decorateTypeThrottled(type);
-    }
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    const leftToolbarItems = super.syncToolbarItems();
-    const rightToolbarItems = [];
-    for (const plugin of this._plugins) {
-      leftToolbarItems.pushAll(plugin.leftToolbarItems());
-      rightToolbarItems.pushAll(plugin.rightToolbarItems());
-    }
-
-    if (!rightToolbarItems.length)
-      return leftToolbarItems;
-
-    return [...leftToolbarItems, new UI.ToolbarSeparator(true), ...rightToolbarItems];
-  }
-};
-
-Sources.UISourceCodeFrame._iconClassPerLevel = {};
-Sources.UISourceCodeFrame._iconClassPerLevel[Workspace.UISourceCode.Message.Level.Error] = 'smallicon-error';
-Sources.UISourceCodeFrame._iconClassPerLevel[Workspace.UISourceCode.Message.Level.Warning] = 'smallicon-warning';
-
-Sources.UISourceCodeFrame._bubbleTypePerLevel = {};
-Sources.UISourceCodeFrame._bubbleTypePerLevel[Workspace.UISourceCode.Message.Level.Error] = 'error';
-Sources.UISourceCodeFrame._bubbleTypePerLevel[Workspace.UISourceCode.Message.Level.Warning] = 'warning';
-
-Sources.UISourceCodeFrame._lineClassPerLevel = {};
-Sources.UISourceCodeFrame._lineClassPerLevel[Workspace.UISourceCode.Message.Level.Error] =
-    'text-editor-line-with-error';
-Sources.UISourceCodeFrame._lineClassPerLevel[Workspace.UISourceCode.Message.Level.Warning] =
-    'text-editor-line-with-warning';
-
-/**
- * @unrestricted
- */
-Sources.UISourceCodeFrame.RowMessage = class {
-  /**
-   * @param {!Workspace.UISourceCode.Message} message
-   */
-  constructor(message) {
-    this._message = message;
-    this._repeatCount = 1;
-    this.element = createElementWithClass('div', 'text-editor-row-message');
-    this._icon = this.element.createChild('label', '', 'dt-icon-label');
-    this._icon.type = Sources.UISourceCodeFrame._iconClassPerLevel[message.level()];
-    this._repeatCountElement =
-        this.element.createChild('label', 'text-editor-row-message-repeat-count hidden', 'dt-small-bubble');
-    this._repeatCountElement.type = Sources.UISourceCodeFrame._bubbleTypePerLevel[message.level()];
-    const linesContainer = this.element.createChild('div');
-    const lines = this._message.text().split('\n');
-    for (let i = 0; i < lines.length; ++i) {
-      const messageLine = linesContainer.createChild('div');
-      messageLine.textContent = lines[i];
-    }
-  }
-
-  /**
-   * @return {!Workspace.UISourceCode.Message}
-   */
-  message() {
-    return this._message;
-  }
-
-  /**
-   * @return {number}
-   */
-  repeatCount() {
-    return this._repeatCount;
-  }
-
-  setRepeatCount(repeatCount) {
-    if (this._repeatCount === repeatCount)
-      return;
-    this._repeatCount = repeatCount;
-    this._updateMessageRepeatCount();
-  }
-
-  _updateMessageRepeatCount() {
-    this._repeatCountElement.textContent = this._repeatCount;
-    const showRepeatCount = this._repeatCount > 1;
-    this._repeatCountElement.classList.toggle('hidden', !showRepeatCount);
-    this._icon.classList.toggle('hidden', showRepeatCount);
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.UISourceCodeFrame.RowMessageBucket = class {
-  /**
-   * @param {!Sources.UISourceCodeFrame} sourceFrame
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   * @param {number} lineNumber
-   */
-  constructor(sourceFrame, textEditor, lineNumber) {
-    this._sourceFrame = sourceFrame;
-    this.textEditor = textEditor;
-    this._lineHandle = textEditor.textEditorPositionHandle(lineNumber, 0);
-    this._decoration = createElementWithClass('div', 'text-editor-line-decoration');
-    this._decoration._messageBucket = this;
-    this._wave = this._decoration.createChild('div', 'text-editor-line-decoration-wave');
-    this._icon = this._wave.createChild('label', 'text-editor-line-decoration-icon', 'dt-icon-label');
-    /** @type {?number} */
-    this._decorationStartColumn = null;
-
-    this._messagesDescriptionElement = createElementWithClass('div', 'text-editor-messages-description-container');
-    /** @type {!Array.<!Sources.UISourceCodeFrame.RowMessage>} */
-    this._messages = [];
-
-    this._level = null;
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   */
-  _updateWavePosition(lineNumber, columnNumber) {
-    lineNumber = Math.min(lineNumber, this.textEditor.linesCount - 1);
-    const lineText = this.textEditor.line(lineNumber);
-    columnNumber = Math.min(columnNumber, lineText.length);
-    const lineIndent = TextUtils.TextUtils.lineIndent(lineText).length;
-    const startColumn = Math.max(columnNumber - 1, lineIndent);
-    if (this._decorationStartColumn === startColumn)
-      return;
-    if (this._decorationStartColumn !== null)
-      this.textEditor.removeDecoration(this._decoration, lineNumber);
-    this.textEditor.addDecoration(this._decoration, lineNumber, startColumn);
-    this._decorationStartColumn = startColumn;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  messagesDescription() {
-    this._messagesDescriptionElement.removeChildren();
-    UI.appendStyle(this._messagesDescriptionElement, 'source_frame/messagesPopover.css');
-    for (let i = 0; i < this._messages.length; ++i)
-      this._messagesDescriptionElement.appendChild(this._messages[i].element);
-
-    return this._messagesDescriptionElement;
-  }
-
-  detachFromEditor() {
-    const position = this._lineHandle.resolve();
-    if (!position)
-      return;
-    const lineNumber = position.lineNumber;
-    if (this._level)
-      this.textEditor.toggleLineClass(lineNumber, Sources.UISourceCodeFrame._lineClassPerLevel[this._level], false);
-    if (this._decorationStartColumn !== null) {
-      this.textEditor.removeDecoration(this._decoration, lineNumber);
-      this._decorationStartColumn = null;
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  uniqueMessagesCount() {
-    return this._messages.length;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message} message
-   */
-  addMessage(message) {
-    for (let i = 0; i < this._messages.length; ++i) {
-      const rowMessage = this._messages[i];
-      if (rowMessage.message().isEqual(message)) {
-        rowMessage.setRepeatCount(rowMessage.repeatCount() + 1);
-        return;
-      }
-    }
-
-    const rowMessage = new Sources.UISourceCodeFrame.RowMessage(message);
-    this._messages.push(rowMessage);
-    this._updateDecoration();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message} message
-   */
-  removeMessage(message) {
-    for (let i = 0; i < this._messages.length; ++i) {
-      const rowMessage = this._messages[i];
-      if (!rowMessage.message().isEqual(message))
-        continue;
-      rowMessage.setRepeatCount(rowMessage.repeatCount() - 1);
-      if (!rowMessage.repeatCount())
-        this._messages.splice(i, 1);
-      this._updateDecoration();
-      return;
-    }
-  }
-
-  _updateDecoration() {
-    if (!this._sourceFrame.isShowing())
-      return;
-    if (!this._messages.length)
-      return;
-    const position = this._lineHandle.resolve();
-    if (!position)
-      return;
-
-    const lineNumber = position.lineNumber;
-    let columnNumber = Number.MAX_VALUE;
-    let maxMessage = null;
-    for (let i = 0; i < this._messages.length; ++i) {
-      const message = this._messages[i].message();
-      columnNumber = Math.min(columnNumber, message.columnNumber());
-      if (!maxMessage || Workspace.UISourceCode.Message.messageLevelComparator(maxMessage, message) < 0)
-        maxMessage = message;
-    }
-    this._updateWavePosition(lineNumber, columnNumber);
-
-    if (this._level === maxMessage.level())
-      return;
-    if (this._level) {
-      this.textEditor.toggleLineClass(lineNumber, Sources.UISourceCodeFrame._lineClassPerLevel[this._level], false);
-      this._icon.type = '';
-    }
-    this._level = maxMessage.level();
-    if (!this._level)
-      return;
-    this.textEditor.toggleLineClass(lineNumber, Sources.UISourceCodeFrame._lineClassPerLevel[this._level], true);
-    this._icon.type = Sources.UISourceCodeFrame._iconClassPerLevel[this._level];
-  }
-};
-
-Workspace.UISourceCode.Message._messageLevelPriority = {
-  'Warning': 3,
-  'Error': 4
-};
-
-/**
- * @param {!Workspace.UISourceCode.Message} a
- * @param {!Workspace.UISourceCode.Message} b
- * @return {number}
- */
-Workspace.UISourceCode.Message.messageLevelComparator = function(a, b) {
-  return Workspace.UISourceCode.Message._messageLevelPriority[a.level()] -
-      Workspace.UISourceCode.Message._messageLevelPriority[b.level()];
-};
-
-
-/**
- * @interface
- */
-Sources.UISourceCodeFrame.Plugin = class {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  static accepts(uiSourceCode) {
-  }
-
-  /**
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  rightToolbarItems() {
-  }
-
-  /**
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  leftToolbarItems() {
-  }
-
-  dispose() {
-  }
-};
-
-/** @enum {symbol} */
-Sources.UISourceCodeFrame.Events = {
-  ToolbarItemsChanged: Symbol('ToolbarItemsChanged')
-};
diff --git a/front_end/sources/WatchExpressionsSidebarPane.js b/front_end/sources/WatchExpressionsSidebarPane.js
deleted file mode 100644
index 320aef7..0000000
--- a/front_end/sources/WatchExpressionsSidebarPane.js
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) IBM Corp. 2009  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of IBM Corp. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ActionDelegate}
- * @implements {UI.ToolbarItem.ItemsProvider}
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Sources.WatchExpressionsSidebarPane = class extends UI.ThrottledWidget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('object_ui/objectValue.css');
-    this.registerRequiredCSS('sources/watchExpressionsSidebarPane.css');
-
-    /** @type {!Array.<!Sources.WatchExpression>} */
-    this._watchExpressions = [];
-    this._watchExpressionsSetting = Common.settings.createLocalSetting('watchExpressions', []);
-
-    this._addButton = new UI.ToolbarButton(Common.UIString('Add expression'), 'largeicon-add');
-    this._addButton.addEventListener(UI.ToolbarButton.Events.Click, this._addButtonClicked.bind(this));
-    this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this.update, this);
-
-    this.contentElement.classList.add('watch-expressions');
-    this.contentElement.addEventListener('contextmenu', this._contextMenu.bind(this), false);
-    this._expandController = new ObjectUI.ObjectPropertiesSectionExpandController();
-
-    UI.context.addFlavorChangeListener(SDK.ExecutionContext, this.update, this);
-    UI.context.addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this.update, this);
-    this._linkifier = new Components.Linkifier();
-    this.update();
-  }
-
-  /**
-   * @override
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  toolbarItems() {
-    return [this._addButton, this._refreshButton];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasExpressions() {
-    return !!this._watchExpressionsSetting.get().length;
-  }
-
-  _saveExpressions() {
-    const toSave = [];
-    for (let i = 0; i < this._watchExpressions.length; i++) {
-      if (this._watchExpressions[i].expression())
-        toSave.push(this._watchExpressions[i].expression());
-    }
-
-    this._watchExpressionsSetting.set(toSave);
-  }
-
-  _addButtonClicked() {
-    UI.viewManager.showView('sources.watch');
-    this._createWatchExpression(null).startEditing();
-  }
-
-  /**
-   * @override
-   * @return {!Promise.<?>}
-   */
-  doUpdate() {
-    this._linkifier.reset();
-    this.contentElement.removeChildren();
-    this._watchExpressions = [];
-    this._emptyElement = this.contentElement.createChild('div', 'gray-info-message');
-    this._emptyElement.textContent = Common.UIString('No watch expressions');
-    const watchExpressionStrings = this._watchExpressionsSetting.get();
-    for (let i = 0; i < watchExpressionStrings.length; ++i) {
-      const expression = watchExpressionStrings[i];
-      if (!expression)
-        continue;
-
-      this._createWatchExpression(expression);
-    }
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {?string} expression
-   * @return {!Sources.WatchExpression}
-   */
-  _createWatchExpression(expression) {
-    this._emptyElement.classList.add('hidden');
-    const watchExpression = new Sources.WatchExpression(expression, this._expandController, this._linkifier);
-    watchExpression.addEventListener(
-        Sources.WatchExpression.Events.ExpressionUpdated, this._watchExpressionUpdated, this);
-    this.contentElement.appendChild(watchExpression.element());
-    this._watchExpressions.push(watchExpression);
-    return watchExpression;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _watchExpressionUpdated(event) {
-    const watchExpression = /** @type {!Sources.WatchExpression} */ (event.data);
-    if (!watchExpression.expression()) {
-      this._watchExpressions.remove(watchExpression);
-      this.contentElement.removeChild(watchExpression.element());
-      this._emptyElement.classList.toggle('hidden', !!this._watchExpressions.length);
-    }
-
-    this._saveExpressions();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _contextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    this._populateContextMenu(contextMenu, event);
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Event} event
-   */
-  _populateContextMenu(contextMenu, event) {
-    let isEditing = false;
-    for (const watchExpression of this._watchExpressions)
-      isEditing |= watchExpression.isEditing();
-
-    if (!isEditing)
-      contextMenu.debugSection().appendItem(Common.UIString('Add watch expression'), this._addButtonClicked.bind(this));
-
-    if (this._watchExpressions.length > 1) {
-      contextMenu.debugSection().appendItem(
-          Common.UIString('Delete all watch expressions'), this._deleteAllButtonClicked.bind(this));
-    }
-
-
-    const target = event.deepElementFromPoint();
-    if (!target)
-      return;
-    for (const watchExpression of this._watchExpressions) {
-      if (watchExpression.element().isSelfOrAncestor(target))
-        watchExpression._populateContextMenu(contextMenu, event);
-    }
-  }
-
-  _deleteAllButtonClicked() {
-    this._watchExpressions = [];
-    this._saveExpressions();
-    this.update();
-  }
-
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const frame = UI.context.flavor(Sources.UISourceCodeFrame);
-    if (!frame)
-      return false;
-    const text = frame.textEditor.text(frame.textEditor.selection());
-    UI.viewManager.showView('sources.watch');
-    this.doUpdate();
-    this._createWatchExpression(text);
-    this._saveExpressions();
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    const frame = UI.context.flavor(Sources.UISourceCodeFrame);
-    if (!frame || frame.textEditor.selection().isEmpty())
-      return;
-
-    contextMenu.debugSection().appendAction('sources.add-to-watch');
-  }
-};
-
-/**
- * @unrestricted
- */
-Sources.WatchExpression = class extends Common.Object {
-  /**
-   * @param {?string} expression
-   * @param {!ObjectUI.ObjectPropertiesSectionExpandController} expandController
-   * @param {!Components.Linkifier} linkifier
-   */
-  constructor(expression, expandController, linkifier) {
-    super();
-    this._expression = expression;
-    this._expandController = expandController;
-    this._element = createElementWithClass('div', 'watch-expression monospace');
-    this._editing = false;
-    this._linkifier = linkifier;
-
-    this._createWatchExpression();
-    this.update();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  /**
-   * @return {?string}
-   */
-  expression() {
-    return this._expression;
-  }
-
-  update() {
-    const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
-    if (currentExecutionContext && this._expression) {
-      currentExecutionContext
-          .evaluate(
-              {
-                expression: this._expression,
-                objectGroup: Sources.WatchExpression._watchObjectGroupId,
-                includeCommandLineAPI: false,
-                silent: true,
-                returnByValue: false,
-                generatePreview: false
-              },
-              /* userGesture */ false,
-              /* awaitPromise */ false)
-          .then(result => this._createWatchExpression(result.object, result.exceptionDetails));
-    }
-  }
-
-  startEditing() {
-    this._editing = true;
-    this._element.removeChild(this._objectPresentationElement);
-    const newDiv = this._element.createChild('div');
-    newDiv.textContent = this._nameElement.textContent;
-    this._textPrompt = new ObjectUI.ObjectPropertyPrompt();
-    this._textPrompt.renderAsBlock();
-    const proxyElement = this._textPrompt.attachAndStartEditing(newDiv, this._finishEditing.bind(this));
-    proxyElement.classList.add('watch-expression-text-prompt-proxy');
-    proxyElement.addEventListener('keydown', this._promptKeyDown.bind(this), false);
-    this._element.getComponentSelection().selectAllChildren(newDiv);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEditing() {
-    return !!this._editing;
-  }
-
-  /**
-   * @param {!Event} event
-   * @param {boolean=} canceled
-   */
-  _finishEditing(event, canceled) {
-    if (event)
-      event.consume(canceled);
-
-    this._editing = false;
-    this._textPrompt.detach();
-    const newExpression = canceled ? this._expression : this._textPrompt.text();
-    delete this._textPrompt;
-    this._element.removeChildren();
-    this._element.appendChild(this._objectPresentationElement);
-    this._updateExpression(newExpression);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _dblClickOnWatchExpression(event) {
-    event.consume();
-    if (!this.isEditing())
-      this.startEditing();
-  }
-
-  /**
-   * @param {?string} newExpression
-   */
-  _updateExpression(newExpression) {
-    if (this._expression)
-      this._expandController.stopWatchSectionsWithId(this._expression);
-    this._expression = newExpression;
-    this.update();
-    this.dispatchEventToListeners(Sources.WatchExpression.Events.ExpressionUpdated, this);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _deleteWatchExpression(event) {
-    event.consume(true);
-    this._updateExpression(null);
-  }
-
-  /**
-   * @param {!SDK.RemoteObject=} result
-   * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
-   */
-  _createWatchExpression(result, exceptionDetails) {
-    this._result = result || null;
-
-    const headerElement = createElementWithClass('div', 'watch-expression-header');
-    const deleteButton = headerElement.createChild('button', 'watch-expression-delete-button');
-    deleteButton.title = Common.UIString('Delete watch expression');
-    deleteButton.addEventListener('click', this._deleteWatchExpression.bind(this), false);
-
-    const titleElement = headerElement.createChild('div', 'watch-expression-title');
-    this._nameElement = ObjectUI.ObjectPropertiesSection.createNameElement(this._expression);
-    if (!!exceptionDetails || !result) {
-      this._valueElement = createElementWithClass('span', 'watch-expression-error value');
-      titleElement.classList.add('dimmed');
-      this._valueElement.textContent = Common.UIString('<not available>');
-    } else {
-      this._valueElement = ObjectUI.ObjectPropertiesSection.createValueElementWithCustomSupport(
-          result, !!exceptionDetails, false /* showPreview */, titleElement, this._linkifier);
-    }
-    const separatorElement = createElementWithClass('span', 'watch-expressions-separator');
-    separatorElement.textContent = ': ';
-    titleElement.appendChildren(this._nameElement, separatorElement, this._valueElement);
-
-    this._element.removeChildren();
-    this._objectPropertiesSection = null;
-    if (!exceptionDetails && result && result.hasChildren && !result.customPreview()) {
-      headerElement.classList.add('watch-expression-object-header');
-      this._objectPropertiesSection = new ObjectUI.ObjectPropertiesSection(result, headerElement, this._linkifier);
-      this._objectPresentationElement = this._objectPropertiesSection.element;
-      this._expandController.watchSection(/** @type {string} */ (this._expression), this._objectPropertiesSection);
-      const objectTreeElement = this._objectPropertiesSection.objectTreeElement();
-      objectTreeElement.toggleOnClick = false;
-      objectTreeElement.listItemElement.addEventListener('click', this._onSectionClick.bind(this), false);
-      objectTreeElement.listItemElement.addEventListener('dblclick', this._dblClickOnWatchExpression.bind(this));
-    } else {
-      this._objectPresentationElement = headerElement;
-      this._objectPresentationElement.addEventListener('dblclick', this._dblClickOnWatchExpression.bind(this));
-    }
-
-    this._element.appendChild(this._objectPresentationElement);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onSectionClick(event) {
-    event.consume(true);
-    if (event.detail === 1) {
-      this._preventClickTimeout = setTimeout(handleClick.bind(this), 333);
-    } else {
-      clearTimeout(this._preventClickTimeout);
-      delete this._preventClickTimeout;
-    }
-
-    /**
-     * @this {Sources.WatchExpression}
-     */
-    function handleClick() {
-      if (!this._objectPropertiesSection)
-        return;
-
-      const objectTreeElement = this._objectPropertiesSection.objectTreeElement();
-      if (objectTreeElement.expanded)
-        objectTreeElement.collapse();
-      else
-        objectTreeElement.expand();
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _promptKeyDown(event) {
-    if (isEnterKey(event) || isEscKey(event))
-      this._finishEditing(event, isEscKey(event));
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Event} event
-   */
-  _populateContextMenu(contextMenu, event) {
-    if (!this.isEditing()) {
-      contextMenu.editSection().appendItem(
-          Common.UIString('Delete watch expression'), this._updateExpression.bind(this, null));
-    }
-
-
-    if (!this.isEditing() && this._result && (this._result.type === 'number' || this._result.type === 'string'))
-      contextMenu.clipboardSection().appendItem(Common.UIString('Copy value'), this._copyValueButtonClicked.bind(this));
-
-    const target = event.deepElementFromPoint();
-    if (target && this._valueElement.isSelfOrAncestor(target))
-      contextMenu.appendApplicableItems(this._result);
-  }
-
-  _copyValueButtonClicked() {
-    InspectorFrontendHost.copyText(this._valueElement.textContent);
-  }
-};
-
-Sources.WatchExpression._watchObjectGroupId = 'watch-group';
-
-/** @enum {symbol} */
-Sources.WatchExpression.Events = {
-  ExpressionUpdated: Symbol('ExpressionUpdated')
-};
diff --git a/front_end/sources/callStackSidebarPane.css b/front_end/sources/callStackSidebarPane.css
deleted file mode 100644
index c726005..0000000
--- a/front_end/sources/callStackSidebarPane.css
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.blackboxed-message {
-    text-align: center;
-    font-style: italic;
-    padding: 4px;
-    color: #888;
-    background-color: #FFFFC2;
-}
-
-.blackboxed-message > .link {
-    margin-left: 5px;
-}
-
-.show-more-message {
-    text-align: center;
-    font-style: italic;
-    padding: 4px;
-    border-top: 1px solid #d8d8d8;
-}
-
-.show-more-message > .link {
-    margin-left: 5px;
-}
-
-.call-frame-item {
-    padding: 3px 8px 3px 20px;
-    position: relative;
-    min-height: 18px;
-    line-height: 15px;
-    display: flex;
-    flex-wrap: wrap;
-}
-
-.call-frame-title-text {
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.call-frame-item:not(.async-header) {
-    border-top: 1px solid #efefef;
-}
-
-.call-frame-item:not(.async-header):hover {
-    background-color: #eee;
-}
-
-.async-header + .call-frame-item {
-    border-top: 0;
-}
-
-.call-frame-item-title,
-.call-frame-location {
-    display: flex;
-    white-space: nowrap;
-}
-
-.call-frame-location {
-    color: #888;
-    margin-left: auto;
-    padding: 0 10px 0 10px;
-}
-
-.async-header::before {
-    content: " ";
-    width: 100%;
-    border-top: 1px solid #d8d8d8;
-    margin-top: 8px;
-    position: absolute;
-    z-index: -1;
-    left: 0;
-}
-
-.async-header .call-frame-item-title {
-    font-weight: bold;
-    color: #999;
-    background-color: white;
-    margin-left: -5px;
-    padding: 0 5px;
-}
-
-.blackboxed-call-frame {
-    opacity: 0.6;
-    font-style: italic;
-}
-
-.selected-call-frame-icon {
-    display: none;
-    position: absolute;
-    top: 5px;
-    left: 4px;
-}
-
-.call-frame-item.selected .selected-call-frame-icon {
-    display: block;
-}
-
diff --git a/front_end/sources/debuggerPausedMessage.css b/front_end/sources/debuggerPausedMessage.css
deleted file mode 100644
index ef53943..0000000
--- a/front_end/sources/debuggerPausedMessage.css
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.paused-status {
-    padding: 6px;
-    border-bottom: 1px solid transparent;
-    border-top: 1px solid rgb(189, 189, 189);
-    background-color: hsl(50, 100%, 95%);
-    color: rgb(107, 97, 48);
-}
-
-.-theme-with-dark-background .paused-status {
-    background-color: hsl(46, 98%, 22%);
-    color: #ccc;
-}
-
-.paused-status.error-reason {
-    background-color: hsl(0, 100%, 97%);
-    color: #6b3b3b;
-}
-
-.status-main {
-    font-weight: bold;
-    padding-left: 15px;
-    position: relative;
-}
-
-.status-sub:not(:empty) {
-    padding-left: 15px;
-    padding-top: 5px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.paused-status.error-reason .status-sub {
-    color: red;
-    line-height: 11px;
-    max-height: 27px;
-}
-
-.status-icon {
-    -webkit-filter: hue-rotate(190deg);
-    position: absolute;
-    left: 0;
-    top: calc(50% - 5px);
-}
-
-.paused-status.error-reason .status-icon {
-    -webkit-filter: none;
-}
diff --git a/front_end/sources/dialog.css b/front_end/sources/dialog.css
deleted file mode 100644
index 5cfc083..0000000
--- a/front_end/sources/dialog.css
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    padding: 10px;
-}
-
-.widget {
-    align-items: center;
-}
-
-label {
-    white-space: nowrap;
-}
-
-input[type=text] {
-    font-size: inherit;
-    height: 24px;
-    padding-left: 2px;
-    margin: 0 5px;
-}
-
-input[type="search"]:focus,
-input[type="text"]:focus {
-    outline: none;
-}
-
-button {
-    background-image: linear-gradient(hsl(0, 0%, 93%), hsl(0, 0%, 93%) 38%, hsl(0, 0%, 87%));
-    border: 1px solid hsla(0, 0%, 0%, 0.25);
-    border-radius: 2px;
-    box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.08), inset 0 1px 2px hsla(0, 100%, 100%, 0.75);
-    color: hsl(0, 0%, 27%);
-    font-size: 12px;
-    margin: 0 6px 0 6px;
-    text-shadow: 0 1px 0 hsl(0, 0%, 94%);
-    min-height: 2em;
-    padding-left: 10px;
-    padding-right: 10px;
-}
-
-button:active {
-    background-color: rgb(215, 215, 215);
-    background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
-}
diff --git a/front_end/sources/javaScriptBreakpointsSidebarPane.css b/front_end/sources/javaScriptBreakpointsSidebarPane.css
deleted file mode 100644
index 301b8be..0000000
--- a/front_end/sources/javaScriptBreakpointsSidebarPane.css
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.breakpoint-entry {
-    padding: 3px 8px 3px 8px;
-    min-height: 18px;
-    line-height: 15px;
-    border-top: 1px solid #efefef;
-}
-
-.breakpoint-entry [is=dt-checkbox] {
-    max-width: 100%;
-    white-space: nowrap;
-}
-
-:not(.breakpoints-list-deactivated) > .breakpoint-entry:hover {
-    background-color: #eee;
-}
-
-.breakpoint-entry > .source-text {
-    cursor: pointer;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-}
-
-.breakpoints-list-deactivated {
-    background-color: #eee;
-    opacity: 0.3;
-}
-
-.breakpoint-hit {
-    background-color: rgb(255, 255, 194);
-}
-
-:host-context(.-theme-with-dark-background) .breakpoint-hit {
-    background-color: hsl(46, 98%, 22%);
-    color: #ccc;
-}
diff --git a/front_end/sources/module.json b/front_end/sources/module.json
deleted file mode 100644
index ad4d1f0..0000000
--- a/front_end/sources/module.json
+++ /dev/null
@@ -1,894 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "sources",
-            "title": "Sources",
-            "order": 30,
-            "className": "Sources.SourcesPanel"
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "Workspace.UISourceCode",
-                "Workspace.UILocation",
-                "SDK.RemoteObject",
-                "SDK.NetworkRequest",
-                "Sources.UISourceCodeFrame"
-            ],
-            "className": "Sources.SourcesPanel"
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.toggle-pause",
-            "iconClass": "largeicon-pause",
-            "toggledIconClass": "largeicon-resume",
-            "className": "Sources.SourcesPanel.RevealingActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel",
-                "UI.ShortcutRegistry.ForwardedShortcut"
-            ],
-            "options": [
-                {
-                    "value": true,
-                    "title": "Pause script execution"
-                },
-                {
-                    "value": false,
-                    "title": "Resume script execution"
-                }
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "F8 Ctrl+\\"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "F8 Meta+\\"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.step-over",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "title": "Step over next function call",
-            "iconClass": "largeicon-step-over",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "F10 Ctrl+'"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "F10 Meta+'"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.step-into",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "title": "Step into next function call",
-            "iconClass": "largeicon-step-into",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "F11 Ctrl+;"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "F11 Meta+;"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.step",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "title": "Step",
-            "iconClass": "largeicon-step",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "F9"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.step-out",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "title": "Step out of current function",
-            "iconClass": "largeicon-step-out",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Shift+F11 Shift+Ctrl+;"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Shift+F11 Shift+Meta+;"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "debugger.run-snippet",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "title": "Run snippet",
-            "iconClass": "largeicon-play",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Enter"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Enter"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.toggle-breakpoints-active",
-            "iconClass": "largeicon-deactivate-breakpoints",
-            "toggledIconClass": "largeicon-activate-breakpoints",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "options": [
-                {
-                    "value": true,
-                    "title": "Deactivate breakpoints"
-                },
-                {
-                    "value": false,
-                    "title": "Activate breakpoints"
-                }
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+F8"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+F8"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.add-to-watch",
-            "className": "Sources.WatchExpressionsSidebarPane",
-            "title": "Add selected text to watches",
-            "contextTypes": [
-                "Sources.UISourceCodeFrame"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Ctrl+Shift+A"
-                }
-            ]
-        },
-        {
-            "type": "@UI.ContextMenu.Provider",
-            "contextTypes": [
-                "TextEditor.CodeMirrorTextEditor"
-            ],
-            "className": "Sources.WatchExpressionsSidebarPane"
-        },
-        {
-            "type": "action",
-            "actionId": "debugger.evaluate-selection",
-            "className": "Sources.SourcesPanel.DebuggingActionDelegate",
-            "title": "Evaluate in console",
-            "contextTypes": [
-                "Sources.UISourceCodeFrame"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Ctrl+Shift+E"
-                }
-            ]
-        },
-        {
-            "type": "@QuickOpen.FilteredListWidget.Provider",
-            "title": "Open file",
-            "prefix": "",
-            "className": "Sources.OpenFileQuickOpen"
-        },
-        {
-            "type": "@QuickOpen.FilteredListWidget.Provider",
-            "title": "Go to line",
-            "prefix": ":",
-            "className": "Sources.GoToLineQuickOpen"
-        },
-        {
-            "type": "@QuickOpen.FilteredListWidget.Provider",
-            "title": "Go to symbol",
-            "prefix": "@",
-            "className": "Sources.OutlineQuickOpen"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "navigatorMenu/default",
-            "actionId": "quickOpen.show"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "Workspace.UILocation"
-            ],
-            "destination": "Sources panel",
-            "className": "Sources.SourcesPanel.UILocationRevealer"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "SDK.DebuggerModel.Location"
-            ],
-            "destination": "Sources panel",
-            "className": "Sources.SourcesPanel.DebuggerLocationRevealer"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "Workspace.UISourceCode"
-            ],
-            "destination": "Sources panel",
-            "className": "Sources.SourcesPanel.UISourceCodeRevealer"
-        },
-        {
-            "type": "@Common.Revealer",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "destination": "Sources panel",
-            "className": "Sources.SourcesPanel.DebuggerPausedDetailsRevealer"
-        },
-        {
-            "type": "@Sources.SourcesView.EditorAction",
-            "className": "Sources.InplaceFormatterEditorAction"
-        },
-        {
-            "type": "@Sources.SourcesView.EditorAction",
-            "className": "Sources.ScriptFormatterEditorAction"
-        },
-        {
-            "type": "view",
-            "location": "navigator-view",
-            "id": "navigator-files",
-            "title": "Filesystem",
-            "order": 3,
-            "persistence": "permanent",
-            "className": "Sources.FilesNavigatorView"
-        },
-        {
-            "type": "view",
-            "location": "navigator-view",
-            "id": "navigator-overrides",
-            "title": "Overrides",
-            "order": 4,
-            "persistence": "permanent",
-            "className": "Sources.OverridesNavigatorView"
-        },
-        {
-            "type": "view",
-            "location": "navigator-view",
-            "id": "navigator-contentScripts",
-            "title": "Content scripts",
-            "order": 5,
-            "persistence": "permanent",
-            "className": "Sources.ContentScriptsNavigatorView"
-        },
-        {
-            "type": "view",
-            "location": "navigator-view",
-            "id": "navigator-snippets",
-            "title": "Snippets",
-            "order": 6,
-            "persistence": "permanent",
-            "className": "Sources.SnippetsNavigatorView"
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "sources.search-sources-tab",
-            "title": "Search",
-            "order": 7,
-            "persistence": "closeable",
-            "className": "Sources.SearchSourcesView"
-        },
-        {
-            "type": "@Sources.NavigatorView",
-            "viewId": "navigator-network",
-            "className": "Sources.NetworkNavigatorView"
-        },
-        {
-            "type": "@Sources.NavigatorView",
-            "viewId": "navigator-files",
-            "className": "Sources.FilesNavigatorView"
-        },
-        {
-            "type": "@Sources.NavigatorView",
-            "viewId": "navigator-overrides",
-            "className": "Sources.OverridesNavigatorView"
-        },
-        {
-            "type": "@Sources.NavigatorView",
-            "viewId": "navigator-contentScripts",
-            "className": "Sources.ContentScriptsNavigatorView"
-        },
-        {
-            "type": "@Sources.NavigatorView",
-            "viewId": "navigator-snippets",
-            "className": "Sources.SnippetsNavigatorView"
-        },
-        {
-            "type": "action",
-            "actionId": "sources.switch-file",
-            "className": "Sources.SourcesView.SwitchFileActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesView"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Alt+O"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.rename",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "F2"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Enter"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "settingName": "navigatorGroupByFolder",
-            "settingType": "boolean",
-            "defaultValue": "true"
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Search in anonymous and content scripts",
-            "settingName": "searchInAnonymousAndContentScripts",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Search in anonymous and content scripts"
-                },
-                {
-                    "value": false,
-                    "title": "Do not search in anonymous and content scripts"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Automatically reveal files in sidebar",
-            "settingName": "autoRevealInNavigator",
-            "settingType": "boolean",
-            "defaultValue": false,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Automatically reveal files in sidebar"
-                },
-                {
-                    "value": false,
-                    "title": "Do not automatically reveal files in sidebar"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Enable JavaScript source maps",
-            "settingName": "jsSourceMapsEnabled",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable JavaScript source maps"
-                },
-                {
-                    "value": false,
-                    "title": "Disable JavaScript source maps"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Detect indentation",
-            "settingName": "textEditorAutoDetectIndent",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Detect indentation"
-                },
-                {
-                    "value": false,
-                    "title": "Do not detect indentation"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Autocompletion",
-            "settingName": "textEditorAutocompletion",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable autocompletion"
-                },
-                {
-                    "value": false,
-                    "title": "Disable autocompletion"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Bracket matching",
-            "settingName": "textEditorBracketMatching",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable bracket matching"
-                },
-                {
-                    "value": false,
-                    "title": "Disable bracket matching"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Show whitespace characters:",
-            "settingName": "showWhitespacesInEditor",
-            "settingType": "enum",
-            "defaultValue": "original",
-            "options": [
-                {
-                    "title": "Do not show whitespace characters",
-                    "text": "None",
-                    "value": "none"
-                },
-                {
-                    "title": "Show all whitespace characters",
-                    "text": "All",
-                    "value": "all"
-                },
-                {
-                    "title": "Show trailing whitespace characters",
-                    "text": "Trailing",
-                    "value": "trailing"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Display variable values inline while debugging",
-            "settingName": "inlineVariableValues",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Display variable values inline while debugging"
-                },
-                {
-                    "value": false,
-                    "title": "Do not display variable values inline while debugging"
-                }
-            ]
-        },
-        {
-            "type": "setting",
-            "category": "Sources",
-            "title": "Enable CSS source maps",
-            "settingName": "cssSourceMapsEnabled",
-            "settingType": "boolean",
-            "defaultValue": true,
-            "options": [
-                {
-                    "value": true,
-                    "title": "Enable CSS source maps"
-                },
-                {
-                    "value": false,
-                    "title": "Disable CSS source maps"
-                }
-            ]
-        },
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "sources.quick",
-            "title": "Quick source",
-            "persistence": "closeable",
-            "order": 1000,
-            "className": "Sources.SourcesPanel.WrapperView"
-        },
-        {
-            "type": "action",
-            "category": "Sources",
-            "actionId": "sources.close-all",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "title": "Close All"
-        },
-        {
-            "type": "action",
-            "actionId": "sources.jump-to-previous-location",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Alt+Minus"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.jump-to-next-location",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Alt+Plus"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.close-editor-tab",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Alt+w"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.go-to-line",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Ctrl+g"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.go-to-member",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "platform":"windows,linux",
-                    "shortcut": "Ctrl+Shift+o"
-                },
-                {
-                    "platform":"mac",
-                    "shortcut": "Meta+Shift+o"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "debugger.toggle-breakpoint",
-            "bindings": [
-                {
-                    "platform":"windows,linux",
-                    "shortcut": "Ctrl+b"
-                },
-                {
-                    "platform":"mac",
-                    "shortcut": "Meta+b"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "debugger.toggle-breakpoint-enabled",
-            "bindings": [
-                {
-                    "platform":"windows,linux",
-                    "shortcut": "Ctrl+Shift+b"
-                },
-                {
-                    "platform":"mac",
-                    "shortcut": "Meta+Shift+b"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.save",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "platform":"windows,linux",
-                    "shortcut": "Ctrl+s"
-                },
-                {
-                    "platform":"mac",
-                    "shortcut": "Meta+s"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.save-all",
-            "className": "Sources.SourcesView.ActionDelegate",
-            "contextTypes": [
-                "Sources.SourcesPanel"
-            ],
-            "bindings": [
-                {
-                    "platform":"windows,linux",
-                    "shortcut": "Ctrl+Shift+s"
-                },
-                {
-                    "platform":"mac",
-                    "shortcut": "Meta+Alt+s"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Sources",
-            "actionId": "sources.create-snippet",
-            "className": "Sources.SnippetsNavigatorView.CreatingActionDelegate",
-            "title": "Create new snippet"
-        },
-        {
-            "type": "action",
-            "category": "Sources",
-            "actionId": "sources.add-folder-to-workspace",
-            "className": "Sources.SnippetsNavigatorView.CreatingActionDelegate",
-            "title": "Add folder to workspace"
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "navigator-view",
-            "className": "Sources.SourcesPanel"
-        },
-        {
-            "type": "@UI.ViewLocationResolver",
-            "name": "sources-sidebar",
-            "category": "Sources",
-            "className": "Sources.SourcesPanel"
-        },
-        {
-            "type": "view",
-            "id": "sources.threads",
-            "title": "Threads",
-            "persistence": "permanent",
-            "className": "Sources.ThreadsSidebarPane"
-        },
-        {
-            "type": "view",
-            "id": "sources.scopeChain",
-            "title": "Scope",
-            "persistence": "permanent",
-            "className": "Sources.ScopeChainSidebarPane"
-        },
-        {
-            "type": "view",
-            "id": "sources.watch",
-            "title": "Watch",
-            "hasToolbar": true,
-            "persistence": "permanent",
-            "className": "Sources.WatchExpressionsSidebarPane"
-        },
-        {
-            "type": "view",
-            "id": "sources.jsBreakpoints",
-            "title": "Breakpoints",
-            "persistence": "permanent",
-            "className": "Sources.JavaScriptBreakpointsSidebarPane"
-        },
-        {
-            "type": "@UI.ContextFlavorListener",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "className": "Sources.JavaScriptBreakpointsSidebarPane"
-        },
-        {
-            "type": "@UI.ContextFlavorListener",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "className": "Sources.CallStackSidebarPane"
-        },
-        {
-            "type": "@UI.ContextFlavorListener",
-            "contextTypes": [
-                "SDK.DebuggerModel.CallFrame"
-            ],
-            "className": "Sources.ScopeChainSidebarPane"
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.previous-call-frame",
-            "className": "Sources.CallStackSidebarPane.ActionDelegate",
-            "title": "Previous call frame",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Ctrl+,"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Debugger",
-            "actionId": "debugger.next-call-frame",
-            "className": "Sources.CallStackSidebarPane.ActionDelegate",
-            "title": "Next call frame",
-            "contextTypes": [
-                "SDK.DebuggerPausedDetails"
-            ],
-            "bindings": [
-                {
-                    "shortcut": "Ctrl+."
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "sources.search",
-            "title": "Search",
-            "className": "Sources.SearchSourcesView.ActionDelegate",
-            "category": "DevTools",
-            "bindings": [
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Alt+F"
-                },
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Shift+F"
-                }
-            ]
-        },
-        {
-            "type": "context-menu-item",
-            "location": "mainMenu/default",
-            "actionId": "sources.search"
-        }
-
-    ],
-    "dependencies": [
-        "components",
-        "search",
-        "source_frame",
-        "snippets",
-        "extensions",
-        "persistence",
-        "quick_open",
-        "inline_editor",
-        "color_picker",
-        "event_listeners",
-        "object_ui",
-        "formatter"
-    ],
-    "scripts": [
-        "AddSourceMapURLDialog.js",
-        "CallStackSidebarPane.js",
-        "DebuggerPausedMessage.js",
-        "SimpleHistoryManager.js",
-        "EditingLocationHistoryManager.js",
-        "FilePathScoreFunction.js",
-        "FilteredUISourceCodeListProvider.js",
-        "GoToLineQuickOpen.js",
-        "SourceMapNamesResolver.js",
-        "JavaScriptBreakpointsSidebarPane.js",
-        "UISourceCodeFrame.js",
-        "JavaScriptSourceFrame.js",
-        "CSSPlugin.js",
-        "SearchSourcesView.js",
-        "NavigatorView.js",
-        "ScopeChainSidebarPane.js",
-        "SourcesNavigator.js",
-        "OutlineQuickOpen.js",
-        "TabbedEditorContainer.js",
-        "WatchExpressionsSidebarPane.js",
-        "ThreadsSidebarPane.js",
-        "ScriptFormatterEditorAction.js",
-        "InplaceFormatterEditorAction.js",
-        "SourceFormatter.js",
-        "OpenFileQuickOpen.js",
-        "SourcesView.js",
-        "SourcesSearchScope.js",
-        "SourcesPanel.js",
-        "JavaScriptCompilerPlugin.js",
-        "SnippetsPlugin.js"
-    ],
-    "resources": [
-        "callStackSidebarPane.css",
-        "debuggerPausedMessage.css",
-        "javaScriptBreakpointsSidebarPane.css",
-        "navigatorTree.css",
-        "navigatorView.css",
-        "revisionHistory.css",
-        "scopeChainSidebarPane.css",
-        "serviceWorkersSidebar.css",
-        "sourcesPanel.css",
-        "sourcesView.css",
-        "threadsSidebarPane.css",
-        "watchExpressionsSidebarPane.css",
-        "dialog.css"
-    ]
-}
diff --git a/front_end/sources/navigatorTree.css b/front_end/sources/navigatorTree.css
deleted file mode 100644
index 51ed07e..0000000
--- a/front_end/sources/navigatorTree.css
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.icon, .icon-badge {
-    margin: -3px -5px -3px -5px;
-}
-
-.icon-stack {
-    position: relative;
-    display: inline-flex;
-}
-
-.icon-stack > [is=ui-icon]:not(:first-child) {
-    position: absolute;
-    left: 0;
-    top: 0;
-}
-
-.navigator-file-tree-item .icon {
-    background: linear-gradient(45deg, hsl(0, 0%, 50%), hsl(0, 0%, 70%));
-}
-
-.navigator-fs-tree-item:not(.has-mapped-files),
-.navigator-fs-folder-tree-item:not(.has-mapped-files) {
-    filter: grayscale(50%);
-    opacity: 0.5;
-}
-
-.tree-outline li {
-    min-height: 20px;
-}
-
-.tree-outline li:hover:not(.selected) .selection {
-    display: block;
-    background-color: rgba(56, 121, 217, 0.1);
-}
-
-.navigator-folder-tree-item .icon {
-    background-color: #555;
-}
-
-.navigator-sm-folder-tree-item .icon,
-.navigator-fs-tree-item .icon,
-.navigator-fs-folder-tree-item .icon {
-    background: linear-gradient(45deg, hsl(28, 75%, 50%), hsl(28, 75%, 70%));
-}
-
-.navigator-nw-folder-tree-item .icon {
-    background: linear-gradient(45deg, hsl(210, 82%, 65%), hsl(210, 82%, 80%));
-}
-
-.navigator-sm-script-tree-item .icon,
-.navigator-script-tree-item .icon,
-.navigator-snippet-tree-item .icon {
-    background: linear-gradient(45deg, hsl(48, 70%, 50%), hsl(48, 70%, 70%));
-}
-
-.navigator-sm-stylesheet-tree-item .icon,
-.navigator-stylesheet-tree-item .icon {
-    background: linear-gradient(45deg, hsl(256, 50%, 50%), hsl(256, 50%, 70%));
-}
-
-.navigator-image-tree-item .icon,
-.navigator-font-tree-item .icon {
-    background: linear-gradient(45deg, hsl(109, 33%, 50%), hsl(109, 33%, 70%));
-}
-
-.navigator-sm-folder-tree-item .tree-element-title,
-.navigator-sm-script-tree-item .tree-element-title,
-.navigator-sm-stylesheet-tree-item .tree-element-title {
-    font-style: italic;
-}
-
-:host{
-    overflow-y: auto;
-}
diff --git a/front_end/sources/navigatorView.css b/front_end/sources/navigatorView.css
deleted file mode 100644
index 2db86d1..0000000
--- a/front_end/sources/navigatorView.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.navigator-toolbar {
-    border-bottom: 1px solid #ccc;
-    padding-left: 8px;
-}
diff --git a/front_end/sources/revisionHistory.css b/front_end/sources/revisionHistory.css
deleted file mode 100644
index e8144aa..0000000
--- a/front_end/sources/revisionHistory.css
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.revision-history-link {
-    text-decoration: underline;
-    cursor: pointer;
-    color: #00e;
-    padding: 0 4px;
-}
-
-.revision-history-link-row {
-    padding-left: 16px;
-}
-
-li.revision-history-line {
-    padding-left: 6px;
-    -webkit-user-select: text;
-}
-
-.webkit-line-number {
-    border-right: 1px solid #BBB;
-    background-color: #F0F0F0;
-}
-
-li.revision-history-revision {
-    padding-left: 16px;
-}
-
-.revision-history-line-added {
-    background-color: rgb(153, 238, 153);
-}
-
-.revision-history-line-removed {
-    background-color: rgb(255, 221, 221);
-}
-
-.revision-history-line-separator .webkit-line-number {
-    color: transparent;
-}
-
-.revision-history-line {
-    white-space: nowrap;
-}
diff --git a/front_end/sources/scopeChainSidebarPane.css b/front_end/sources/scopeChainSidebarPane.css
deleted file mode 100644
index f1b4bbd..0000000
--- a/front_end/sources/scopeChainSidebarPane.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.scope-chain-sidebar-pane-section-header {
-    flex: auto;
-}
-
-.scope-chain-sidebar-pane-section-subtitle {
-    float: right;
-    margin-left: 5px;
-    max-width: 55%;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.scope-chain-sidebar-pane-section-title {
-    font-weight: normal;
-    word-wrap: break-word;
-    white-space: normal;
-}
-
-.scope-chain-sidebar-pane-section {
-    padding: 2px 4px;
-    flex: none;
-}
diff --git a/front_end/sources/serviceWorkersSidebar.css b/front_end/sources/serviceWorkersSidebar.css
deleted file mode 100644
index dc867f3..0000000
--- a/front_end/sources/serviceWorkersSidebar.css
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.service-worker {
-    padding: 5px 5px 5px 8px;
-    border-bottom: 1px solid #aaa;
-    display: flex;
-    align-items: center;
-}
-
-.service-worker:last-child {
-    border-bottom: none;
-}
-
-.service-worker-scope {
-    color: #777;
-    flex: auto;
-    margin: 5px 5px 0 0;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
diff --git a/front_end/sources/sourcesPanel.css b/front_end/sources/sourcesPanel.css
deleted file mode 100644
index 4b49787..0000000
--- a/front_end/sources/sourcesPanel.css
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.scripts-debug-toolbar {
-    position: absolute;
-    top: 0;
-    width: 100%;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: 1px solid #ccc;
-    overflow: hidden;
-}
-
-.scripts-debug-toolbar-drawer {
-    flex: 0 0 52px;
-    -webkit-transition: margin-top 0.1s ease-in-out;
-    margin-top: -26px;
-    padding-top: 25px;
-    background-color: white;
-    overflow: hidden;
-    white-space: nowrap;
-}
-
-.scripts-debug-toolbar-drawer.expanded {
-    margin-top: 0;
-}
-
-.scripts-debug-toolbar-drawer > label {
-    display: flex;
-    padding-left: 3px;
-    height: 28px;
-}
-
-.panel.sources .sidebar-pane-stack {
-    overflow: auto;
-}
-
-.cursor-pointer {
-    cursor: pointer;
-}
-
-.cursor-auto {
-    cursor: auto;
-}
-
-.navigator-tabbed-pane {
-    background-color: var(--toolbar-bg-color);
-}
diff --git a/front_end/sources/sourcesView.css b/front_end/sources/sourcesView.css
deleted file mode 100644
index 6b27b3e..0000000
--- a/front_end/sources/sourcesView.css
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#sources-panel-sources-view {
-    flex: auto;
-    position: relative;
-}
-
-#sources-panel-sources-view .sources-toolbar {
-    display: flex;
-    flex: 0 0 27px;
-    background-color: var(--toolbar-bg-color);
-    border-top: var(--divider-border);
-    overflow: hidden;
-    z-index: 0;
-}
-
-.sources-toolbar .toolbar {
-    cursor: default;
-}
-
-.sources-toolbar-spacer {
-    flex: auto;
-    pointer-events: none;
-}
-
-.source-frame-debugger-script {
-    background-color: rgba(255, 255, 194, 0.5);
-}
-
-.-theme-with-dark-background .source-frame-debugger-script {
-    background-color: #444;
-}
-
-.source-frame-breakpoint-condition {
-    z-index: 30;
-    padding: 4px;
-    background-color: #e6e6e6;
-    border-radius: 7px;
-    border: 2px solid #bababa;
-    width: 90%;
-    pointer-events: auto;
-}
-
-.source-frame-breakpoint-message {
-    background-color: transparent;
-    font-weight: normal;
-    text-align: left;
-    text-shadow: none;
-    color: rgb(85, 85, 85);
-    cursor: default;
-    margin: 0 0 2px 0;
-}
-
-#source-frame-breakpoint-condition {
-    margin: 0;
-    border: 1px inset rgb(190, 190, 190) !important;
-    width: 100%;
-    box-shadow: none !important;
-    outline: none !important;
-}
-
-@-webkit-keyframes source-frame-value-update-highlight-animation {
-    from {
-        background-color: inherit;
-        color: inherit;
-    }
-    10% {
-        background-color: rgb(158, 54, 153);
-        color: white;
-    }
-    to {
-        background-color: inherit;
-        color: inherit;
-    }
-}
-
-.source-frame-value-update-highlight {
-    -webkit-animation: source-frame-value-update-highlight-animation 0.8s 1 cubic-bezier(0, 0, 0.2, 1);
-    border-radius: 2px;
-}
-
-.diff-entry-insert .diff-marker {
-    border-left: 4px solid hsla(144, 55%, 37%, 1);
-}
-
-.diff-entry-insert .CodeMirror-gutter-background {
-    background-color: hsla(144,55%,49%,.2);
-}
-
-.diff-entry-modify .diff-marker {
-    border-left: 4px solid #9C27B0;
-}
-
-.diff-entry-modify .CodeMirror-gutter-background {
-    background-color: rgba(186,104,200,0.2);
-}
-
-.diff-entry-delete .diff-marker {
-    width: 0;
-    height: 0;
-    border-top: 6px solid transparent;
-    border-bottom: 6px solid transparent;
-    border-left: 6px solid #D32F2F;
-    position: relative;
-    top: 6px;
-    cursor: pointer;
-    left: 0px;
-}
-
-.diff-entry-delete .CodeMirror-gutter-background {
-    border-bottom: 2px solid #D32F2F;
-}
-
-.CodeMirror-gutter-diff {
-    width: 4px;
-}
-
-.highlight-line-modification {
-    animation: source-line-modification-background-fadeout 0.4s 0s;
-    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
-}
-
-.highlight-line-modification span {
-    animation: source-line-modification-foreground-fadeout 0.4s 0s;
-    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
-}
-
-@keyframes source-line-modification-background-fadeout {
-    from { background-color: rgba(158, 54, 153, 0.5); }
-    50% { background-color: rgba(158, 54, 153, 0.5); }
-    90% { background-color: rgba(158, 54, 153, 0); }
-    to { background-color: transparent; }
-}
-
-@keyframes source-line-modification-foreground-fadeout {
-    from { color: white; }
-    50% { color: white; }
-    90% { color: initial; }
-    to { color: initial; }
-}
diff --git a/front_end/sources/threadsSidebarPane.css b/front_end/sources/threadsSidebarPane.css
deleted file mode 100644
index 6863de6..0000000
--- a/front_end/sources/threadsSidebarPane.css
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.thread-item {
-    padding: 3px 8px 3px 20px;
-    position: relative;
-    min-height: 18px;
-    line-height: 15px;
-    display: flex;
-    flex-wrap: wrap;
-}
-
-.thread-item + .thread-item {
-    border-top: 1px solid #efefef;
-}
-
-.thread-item:hover {
-    background-color: #eee;
-}
-
-.thread-item-title,
-.thread-item-paused-state {
-    text-overflow: ellipsis;
-    overflow: hidden;
-    white-space: nowrap;
-}
-
-.thread-item-paused-state {
-    color: #888;
-    margin-left: auto;
-    padding: 0 10px 0 10px;
-}
-
-.selected-thread-icon {
-    display: none;
-    position: absolute;
-    top: 5px;
-    left: 4px;
-}
-
-.thread-item.selected .selected-thread-icon {
-    display: block;
-}
-
diff --git a/front_end/sources/watchExpressionsSidebarPane.css b/front_end/sources/watchExpressionsSidebarPane.css
deleted file mode 100644
index 63bf691..0000000
--- a/front_end/sources/watchExpressionsSidebarPane.css
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.watch-expression-delete-button {
-    width: 10px;
-    height: 10px;
-    background-image: url(Images/deleteIcon.png);
-    background-position: 0 0;
-    background-color: transparent;
-    background-repeat: no-repeat;
-    border: 0 none transparent;
-    position: absolute;
-    top: 4px;
-    right: 3px;
-    display: none;
-}
-
-.watch-expression-header:hover .watch-expression-delete-button {
-    display: inline;
-}
-
-.watch-expressions {
-    overflow-x: hidden;
-    min-height: 26px;
-}
-
-.watch-expressions .dimmed {
-    opacity: 0.6;
-}
-
-.watch-expression-title {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    line-height: 20px;
-    margin-left: 11px;
-}
-
-.watch-expression-object-header .watch-expression-title {
-    margin-left: 1px;
-}
-
-.watch-expression {
-    position: relative;
-    padding: 0 6px;
-    flex: none;
-    min-height: 20px;
-}
-
-.watch-expressions .name {
-    color: rgb(136, 19, 145);
-    flex: none;
-    white-space: nowrap;
-    text-overflow: ellipsis ;
-    overflow: hidden;
-}
-
-.watch-expression-error {
-    color: red;
-}
-
-:host-context(.-theme-with-dark-background) .watch-expression-error {
-    color: hsl(0, 100%, 65%);
-}
-
-.watch-expressions-separator {
-    flex: none;
-}
-
-.watch-expressions .value {
-    white-space: nowrap;
-    display: inline;
-}
-
-.watch-expression .text-prompt {
-    text-overflow: clip;
-    overflow: hidden;
-    white-space: nowrap;
-    padding-left: 4px;
-    -webkit-user-select: text;
-}
-
-.watch-expression-text-prompt-proxy {
-    margin-left: 12px;
-}
-
-.watch-expression-header {
-    flex: auto;
-}
-
-.watch-expression-object-header {
-    margin-left: -12px;
-    padding-left: 12px;
-}
-
-.watch-expression-header:hover {
-    background-color: #F0F0F0;
-    padding-right: 14px;
-}
diff --git a/front_end/sources_test_runner/AutocompleteTestRunner.js b/front_end/sources_test_runner/AutocompleteTestRunner.js
deleted file mode 100644
index 496c83b..0000000
--- a/front_end/sources_test_runner/AutocompleteTestRunner.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-SourcesTestRunner.dumpSuggestions = function(textEditor, lines) {
-  let resolve;
-  const promise = new Promise(fulfill => resolve = fulfill);
-  let lineNumber = -1;
-  let columnNumber;
-
-  for (let i = 0; i < lines.length; ++i) {
-    columnNumber = lines[i].indexOf('|');
-
-    if (columnNumber !== -1) {
-      lineNumber = i;
-      break;
-    }
-  }
-
-  if (lineNumber === -1)
-    throw new Error('Test case is invalid: cursor position is not marked with \'|\' symbol.');
-
-  textEditor.setText(lines.join('\n').replace('|', ''));
-  textEditor.setSelection(TextUtils.TextRange.createFromLocation(lineNumber, columnNumber));
-  TestRunner.addSniffer(
-      TextEditor.TextEditorAutocompleteController.prototype, '_onSuggestionsShownForTest', suggestionsShown);
-  textEditor._autocompleteController.autocomplete();
-
-  function suggestionsShown(words) {
-    TestRunner.addResult('========= Selection In Editor =========');
-    SourcesTestRunner.dumpTextWithSelection(textEditor);
-    TestRunner.addResult('======= Autocomplete Suggestions =======');
-    TestRunner.addResult('[' + words.map(item => item.text).join(', ') + ']');
-    resolve();
-  }
-
-  return promise;
-};
diff --git a/front_end/sources_test_runner/DebuggerTestRunner.js b/front_end/sources_test_runner/DebuggerTestRunner.js
deleted file mode 100644
index 174dcdb..0000000
--- a/front_end/sources_test_runner/DebuggerTestRunner.js
+++ /dev/null
@@ -1,761 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-SourcesTestRunner.startDebuggerTest = function(callback, quiet) {
-  console.assert(TestRunner.debuggerModel.debuggerEnabled(), 'Debugger has to be enabled');
-
-  if (quiet !== undefined)
-    SourcesTestRunner._quiet = quiet;
-
-  UI.viewManager.showView('sources');
-  TestRunner.addSniffer(SDK.DebuggerModel.prototype, '_pausedScript', SourcesTestRunner._pausedScript, true);
-  TestRunner.addSniffer(SDK.DebuggerModel.prototype, '_resumedScript', SourcesTestRunner._resumedScript, true);
-  TestRunner.safeWrap(callback)();
-};
-
-SourcesTestRunner.startDebuggerTestPromise = function(quiet) {
-  let cb;
-  const p = new Promise(fullfill => cb = fullfill);
-  SourcesTestRunner.startDebuggerTest(cb, quiet);
-  return p;
-};
-
-SourcesTestRunner.completeDebuggerTest = function() {
-  Common.moduleSetting('breakpointsActive').set(true);
-  SourcesTestRunner.resumeExecution(TestRunner.completeTest.bind(TestRunner));
-};
-
-(function() {
-const origThen = Promise.prototype.then;
-const origCatch = Promise.prototype.catch;
-
-Promise.prototype.then = function() {
-  const result = origThen.apply(this, arguments);
-  origThen.call(result, undefined, onUncaughtPromiseReject.bind(null, new Error().stack));
-  return result;
-};
-
-Promise.prototype.catch = function() {
-  const result = origCatch.apply(this, arguments);
-  origThen.call(result, undefined, onUncaughtPromiseReject.bind(null, new Error().stack));
-  return result;
-};
-
-function onUncaughtPromiseReject(stack, e) {
-  const message = typeof e === 'object' && e.stack || e;
-  TestRunner.addResult('FAIL: Uncaught exception in promise: ' + message + ' ' + stack);
-  SourcesTestRunner.completeDebuggerTest();
-}
-})();
-
-SourcesTestRunner.runDebuggerTestSuite = function(testSuite) {
-  const testSuiteTests = testSuite.slice();
-
-  function runner() {
-    if (!testSuiteTests.length) {
-      SourcesTestRunner.completeDebuggerTest();
-      return;
-    }
-
-    const nextTest = testSuiteTests.shift();
-    TestRunner.addResult('');
-    TestRunner.addResult(
-        'Running: ' +
-        /function\s([^(]*)/.exec(nextTest)[1]);
-    TestRunner.safeWrap(nextTest)(runner, runner);
-  }
-
-  SourcesTestRunner.startDebuggerTest(runner);
-};
-
-SourcesTestRunner.runTestFunction = function() {
-  TestRunner.evaluateInPageAnonymously('scheduleTestFunction()');
-  TestRunner.addResult('Set timer for test function.');
-};
-
-SourcesTestRunner.runTestFunctionAndWaitUntilPaused = function(callback) {
-  SourcesTestRunner.runTestFunction();
-  SourcesTestRunner.waitUntilPaused(callback);
-};
-
-SourcesTestRunner.runTestFunctionAndWaitUntilPausedPromise = function() {
-  return new Promise(SourcesTestRunner.runTestFunctionAndWaitUntilPaused);
-};
-
-SourcesTestRunner.runAsyncCallStacksTest = function(totalDebuggerStatements, maxAsyncCallStackDepth) {
-  const defaultMaxAsyncCallStackDepth = 32;
-  SourcesTestRunner.setQuiet(true);
-  SourcesTestRunner.startDebuggerTest(step1);
-
-  async function step1() {
-    await TestRunner.DebuggerAgent.setAsyncCallStackDepth(maxAsyncCallStackDepth || defaultMaxAsyncCallStackDepth);
-    SourcesTestRunner.runTestFunctionAndWaitUntilPaused(didPause);
-  }
-
-  let step = 0;
-  const callStacksOutput = [];
-
-  function didPause(callFrames, reason, breakpointIds, asyncStackTrace) {
-    ++step;
-    callStacksOutput.push(SourcesTestRunner.captureStackTraceIntoString(callFrames, asyncStackTrace) + '\n');
-
-    if (step < totalDebuggerStatements) {
-      SourcesTestRunner.resumeExecution(SourcesTestRunner.waitUntilPaused.bind(SourcesTestRunner, didPause));
-    } else {
-      TestRunner.addResult('Captured call stacks in no particular order:');
-      callStacksOutput.sort();
-      TestRunner.addResults(callStacksOutput);
-      SourcesTestRunner.completeDebuggerTest();
-    }
-  }
-};
-
-SourcesTestRunner.dumpSourceFrameMessages = function(sourceFrame, dumpFullURL) {
-  const messages = [];
-
-  for (const bucket of sourceFrame._rowMessageBuckets.values()) {
-    for (const rowMessage of bucket._messages) {
-      const message = rowMessage.message();
-      messages.push(String.sprintf(
-          '  %d:%d [%s] %s', message.lineNumber(), message.columnNumber(), message.level(), message.text()));
-    }
-  }
-
-  const name = (dumpFullURL ? sourceFrame.uiSourceCode().url() : sourceFrame.uiSourceCode().displayName());
-  TestRunner.addResult('SourceFrame ' + name + ': ' + messages.length + ' message(s)');
-  TestRunner.addResult(messages.join('\n'));
-};
-
-SourcesTestRunner.waitUntilPausedNextTime = function(callback) {
-  SourcesTestRunner._waitUntilPausedCallback = TestRunner.safeWrap(callback);
-};
-
-SourcesTestRunner.waitUntilPaused = function(callback) {
-  callback = TestRunner.safeWrap(callback);
-
-  if (SourcesTestRunner._pausedScriptArguments)
-    callback.apply(callback, SourcesTestRunner._pausedScriptArguments);
-  else
-    SourcesTestRunner._waitUntilPausedCallback = callback;
-};
-
-SourcesTestRunner.waitUntilPausedPromise = function() {
-  return new Promise(resolve => SourcesTestRunner.waitUntilPaused(resolve));
-};
-
-SourcesTestRunner.waitUntilResumedNextTime = function(callback) {
-  SourcesTestRunner._waitUntilResumedCallback = TestRunner.safeWrap(callback);
-};
-
-SourcesTestRunner.waitUntilResumed = function(callback) {
-  callback = TestRunner.safeWrap(callback);
-
-  if (!SourcesTestRunner._pausedScriptArguments)
-    callback();
-  else
-    SourcesTestRunner._waitUntilResumedCallback = callback;
-};
-
-SourcesTestRunner.waitUntilResumedPromise = function() {
-  return new Promise(resolve => SourcesTestRunner.waitUntilResumed(resolve));
-};
-
-SourcesTestRunner.resumeExecution = function(callback) {
-  if (UI.panels.sources.paused())
-    UI.panels.sources._togglePause();
-
-  SourcesTestRunner.waitUntilResumed(callback);
-};
-
-SourcesTestRunner.waitUntilPausedAndDumpStackAndResume = function(callback, options) {
-  SourcesTestRunner.waitUntilPaused(paused);
-  TestRunner.addSniffer(Sources.SourcesPanel.prototype, '_updateDebuggerButtonsAndStatusForTest', setStatus);
-  let caption;
-  let callFrames;
-  let asyncStackTrace;
-
-  function setStatus() {
-    const statusElement = this.element.querySelector('.paused-message');
-    caption = statusElement.deepTextContent();
-
-    if (callFrames)
-      step1();
-  }
-
-  function paused(frames, reason, breakpointIds, async) {
-    callFrames = frames;
-    asyncStackTrace = async;
-
-    if (typeof caption === 'string')
-      step1();
-  }
-
-  function step1() {
-    SourcesTestRunner.captureStackTrace(callFrames, asyncStackTrace, options);
-    TestRunner.addResult(TestRunner.clearSpecificInfoFromStackFrames(caption));
-    TestRunner.deprecatedRunAfterPendingDispatches(step2);
-  }
-
-  function step2() {
-    SourcesTestRunner.resumeExecution(TestRunner.safeWrap(callback));
-  }
-};
-
-SourcesTestRunner.stepOver = function() {
-  Promise.resolve().then(function() {
-    UI.panels.sources._stepOver();
-  });
-};
-
-SourcesTestRunner.stepInto = function() {
-  Promise.resolve().then(function() {
-    UI.panels.sources._stepInto();
-  });
-};
-
-SourcesTestRunner.stepOut = function() {
-  Promise.resolve().then(function() {
-    UI.panels.sources._stepOut();
-  });
-};
-
-SourcesTestRunner.togglePause = function() {
-  Promise.resolve().then(function() {
-    UI.panels.sources._togglePause();
-  });
-};
-
-SourcesTestRunner.waitUntilPausedAndPerformSteppingActions = function(actions, callback) {
-  callback = TestRunner.safeWrap(callback);
-  SourcesTestRunner.waitUntilPaused(didPause);
-
-  function didPause(callFrames, reason, breakpointIds, asyncStackTrace) {
-    let action = actions.shift();
-
-    if (action === 'Print') {
-      SourcesTestRunner.captureStackTrace(callFrames, asyncStackTrace);
-      TestRunner.addResult('');
-
-      while (action === 'Print')
-        action = actions.shift();
-    }
-
-    if (!action) {
-      callback();
-      return;
-    }
-
-    TestRunner.addResult('Executing ' + action + '...');
-
-    switch (action) {
-      case 'StepInto':
-        SourcesTestRunner.stepInto();
-        break;
-      case 'StepOver':
-        SourcesTestRunner.stepOver();
-        break;
-      case 'StepOut':
-        SourcesTestRunner.stepOut();
-        break;
-      case 'Resume':
-        SourcesTestRunner.togglePause();
-        break;
-      default:
-        TestRunner.addResult('FAIL: Unknown action: ' + action);
-        callback();
-        return;
-    }
-
-    SourcesTestRunner.waitUntilResumed(
-        (actions.length ? SourcesTestRunner.waitUntilPaused.bind(SourcesTestRunner, didPause) : callback));
-  }
-};
-
-SourcesTestRunner.captureStackTrace = function(callFrames, asyncStackTrace, options) {
-  TestRunner.addResult(SourcesTestRunner.captureStackTraceIntoString(callFrames, asyncStackTrace, options));
-};
-
-SourcesTestRunner.captureStackTraceIntoString = function(callFrames, asyncStackTrace, options) {
-  const results = [];
-  options = options || {};
-
-  function printCallFrames(callFrames, locationFunction, returnValueFunction) {
-    let printed = 0;
-
-    for (let i = 0; i < callFrames.length; i++) {
-      const frame = callFrames[i];
-      const location = locationFunction.call(frame);
-      const script = location.script();
-      const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location);
-      const isFramework = Bindings.blackboxManager.isBlackboxedRawLocation(location);
-
-      if (options.dropFrameworkCallFrames && isFramework)
-        continue;
-
-      let url;
-      let lineNumber;
-
-      if (uiLocation && uiLocation.uiSourceCode.project().type() !== Workspace.projectTypes.Debugger) {
-        url = uiLocation.uiSourceCode.name();
-        lineNumber = uiLocation.lineNumber + 1;
-      } else {
-        url = Bindings.displayNameForURL(script.sourceURL);
-        lineNumber = location.lineNumber + 1;
-      }
-
-      let s = ((isFramework ? '  * ' : '    ')) + printed++ + ') ' + frame.functionName + ' (' + url +
-          ((options.dropLineNumbers ? '' : ':' + lineNumber)) + ')';
-      s = s.replace(/scheduleTestFunction.+$/, 'scheduleTestFunction <omitted>');
-      results.push(s);
-
-      if (options.printReturnValue && returnValueFunction && returnValueFunction.call(frame))
-        results.push('       <return>: ' + returnValueFunction.call(frame).description);
-
-      if (frame.functionName === 'scheduleTestFunction') {
-        const remainingFrames = callFrames.length - 1 - i;
-
-        if (remainingFrames)
-          results.push('    <... skipped remaining frames ...>');
-
-        break;
-      }
-    }
-
-    return printed;
-  }
-
-  function runtimeCallFramePosition() {
-    return new SDK.DebuggerModel.Location(TestRunner.debuggerModel, this.scriptId, this.lineNumber, this.columnNumber);
-  }
-
-  results.push('Call stack:');
-  printCallFrames(
-      callFrames, SDK.DebuggerModel.CallFrame.prototype.location, SDK.DebuggerModel.CallFrame.prototype.returnValue);
-
-  while (asyncStackTrace) {
-    results.push('    [' + (asyncStackTrace.description || 'Async Call') + ']');
-    const printed = printCallFrames(asyncStackTrace.callFrames, runtimeCallFramePosition);
-
-    if (!printed)
-      results.pop();
-
-    asyncStackTrace = asyncStackTrace.parent;
-  }
-
-  return results.join('\n');
-};
-
-SourcesTestRunner.dumpSourceFrameContents = function(sourceFrame) {
-  TestRunner.addResult('==Source frame contents start==');
-  const textEditor = sourceFrame._textEditor;
-
-  for (let i = 0; i < textEditor.linesCount; ++i)
-    TestRunner.addResult(textEditor.line(i));
-
-  TestRunner.addResult('==Source frame contents end==');
-};
-
-SourcesTestRunner._pausedScript = function(callFrames, reason, auxData, breakpointIds, asyncStackTrace) {
-  if (!SourcesTestRunner._quiet)
-    TestRunner.addResult('Script execution paused.');
-
-  const debuggerModel = this.target().model(SDK.DebuggerModel);
-  SourcesTestRunner._pausedScriptArguments = [
-    SDK.DebuggerModel.CallFrame.fromPayloadArray(debuggerModel, callFrames), reason, breakpointIds, asyncStackTrace,
-    auxData
-  ];
-
-  if (SourcesTestRunner._waitUntilPausedCallback) {
-    const callback = SourcesTestRunner._waitUntilPausedCallback;
-    delete SourcesTestRunner._waitUntilPausedCallback;
-    setTimeout(() => callback.apply(callback, SourcesTestRunner._pausedScriptArguments));
-  }
-};
-
-SourcesTestRunner._resumedScript = function() {
-  if (!SourcesTestRunner._quiet)
-    TestRunner.addResult('Script execution resumed.');
-
-  delete SourcesTestRunner._pausedScriptArguments;
-
-  if (SourcesTestRunner._waitUntilResumedCallback) {
-    const callback = SourcesTestRunner._waitUntilResumedCallback;
-    delete SourcesTestRunner._waitUntilResumedCallback;
-    callback();
-  }
-};
-
-SourcesTestRunner.showUISourceCode = function(uiSourceCode, callback) {
-  const panel = UI.panels.sources;
-  panel.showUISourceCode(uiSourceCode);
-  const sourceFrame = panel.visibleView;
-
-  if (sourceFrame.loaded)
-    callback(sourceFrame);
-  else
-    TestRunner.addSniffer(sourceFrame, 'onTextEditorContentSet', callback && callback.bind(null, sourceFrame));
-};
-
-SourcesTestRunner.showUISourceCodePromise = function(uiSourceCode) {
-  let fulfill;
-  const promise = new Promise(x => fulfill = x);
-  SourcesTestRunner.showUISourceCode(uiSourceCode, fulfill);
-  return promise;
-};
-
-SourcesTestRunner.showScriptSource = function(scriptName, callback) {
-  SourcesTestRunner.waitForScriptSource(scriptName, onScriptSource);
-
-  function onScriptSource(uiSourceCode) {
-    SourcesTestRunner.showUISourceCode(uiSourceCode, callback);
-  }
-};
-
-SourcesTestRunner.showScriptSourcePromise = function(scriptName) {
-  return new Promise(resolve => SourcesTestRunner.showScriptSource(scriptName, resolve));
-};
-
-SourcesTestRunner.waitForScriptSource = function(scriptName, callback) {
-  const panel = UI.panels.sources;
-  const uiSourceCodes = panel._workspace.uiSourceCodes();
-
-  for (let i = 0; i < uiSourceCodes.length; ++i) {
-    if (uiSourceCodes[i].project().type() === Workspace.projectTypes.Service)
-      continue;
-
-    if (uiSourceCodes[i].name() === scriptName) {
-      callback(uiSourceCodes[i]);
-      return;
-    }
-  }
-
-  TestRunner.addSniffer(
-      Sources.SourcesView.prototype, '_addUISourceCode',
-      SourcesTestRunner.waitForScriptSource.bind(SourcesTestRunner, scriptName, callback));
-};
-
-SourcesTestRunner.setBreakpoint = function(sourceFrame, lineNumber, condition, enabled) {
-  if (!sourceFrame._muted)
-    sourceFrame._setBreakpoint(lineNumber, 0, condition, enabled);
-};
-
-SourcesTestRunner.removeBreakpoint = function(sourceFrame, lineNumber) {
-  sourceFrame._breakpointManager.findBreakpoints(sourceFrame._uiSourceCode, lineNumber)[0].remove();
-};
-
-SourcesTestRunner.createNewBreakpoint = function(sourceFrame, lineNumber, condition, enabled) {
-  const promise =
-      new Promise(resolve => TestRunner.addSniffer(sourceFrame.__proto__, '_breakpointWasSetForTest', resolve));
-  sourceFrame._createNewBreakpoint(lineNumber, condition, enabled);
-  return promise;
-};
-
-SourcesTestRunner.toggleBreakpoint = function(sourceFrame, lineNumber, disableOnly) {
-  if (!sourceFrame._muted)
-    sourceFrame._toggleBreakpoint(lineNumber, disableOnly);
-};
-
-SourcesTestRunner.waitBreakpointSidebarPane = function(waitUntilResolved) {
-  return new Promise(
-             resolve => TestRunner.addSniffer(
-                 Sources.JavaScriptBreakpointsSidebarPane.prototype, '_didUpdateForTest', resolve))
-      .then(checkIfReady);
-
-  function checkIfReady() {
-    if (!waitUntilResolved)
-      return;
-
-    for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) {
-      if (breakpoint._fakePrimaryLocation && breakpoint.enabled())
-        return SourcesTestRunner.waitBreakpointSidebarPane();
-    }
-  }
-};
-
-SourcesTestRunner.breakpointsSidebarPaneContent = function() {
-  const paneElement = self.runtime.sharedInstance(Sources.JavaScriptBreakpointsSidebarPane).contentElement;
-  const empty = paneElement.querySelector('.gray-info-message');
-
-  if (empty)
-    return TestRunner.textContentWithLineBreaks(empty);
-
-  const entries = Array.from(paneElement.querySelectorAll('.breakpoint-entry'));
-  return entries.map(TestRunner.textContentWithLineBreaks).join('\n');
-};
-
-SourcesTestRunner.dumpBreakpointSidebarPane = function(title) {
-  TestRunner.addResult('Breakpoint sidebar pane ' + (title || ''));
-  TestRunner.addResult(SourcesTestRunner.breakpointsSidebarPaneContent());
-};
-
-SourcesTestRunner.dumpScopeVariablesSidebarPane = function() {
-  TestRunner.addResult('Scope variables sidebar pane:');
-  const sections = SourcesTestRunner.scopeChainSections();
-
-  for (let i = 0; i < sections.length; ++i) {
-    const textContent = TestRunner.textContentWithLineBreaks(sections[i].element);
-    const text = TestRunner.clearSpecificInfoFromStackFrames(textContent);
-
-    if (text.length > 0)
-      TestRunner.addResult(text);
-
-    if (!sections[i].objectTreeElement().expanded)
-      TestRunner.addResult('    <section collapsed>');
-  }
-};
-
-SourcesTestRunner.scopeChainSections = function() {
-  const children = self.runtime.sharedInstance(Sources.ScopeChainSidebarPane).contentElement.children;
-  const sections = [];
-
-  for (let i = 0; i < children.length; ++i)
-    sections.push(children[i]._section);
-
-  return sections;
-};
-
-SourcesTestRunner.expandScopeVariablesSidebarPane = function(callback) {
-  const sections = SourcesTestRunner.scopeChainSections();
-
-  for (let i = 0; i < sections.length - 1; ++i)
-    sections[i].expand();
-
-  TestRunner.deprecatedRunAfterPendingDispatches(callback);
-};
-
-SourcesTestRunner.expandProperties = function(properties, callback) {
-  let index = 0;
-
-  function expandNextPath() {
-    if (index === properties.length) {
-      TestRunner.safeWrap(callback)();
-      return;
-    }
-
-    const parentTreeElement = properties[index++];
-    const path = properties[index++];
-    SourcesTestRunner._expandProperty(parentTreeElement, path, 0, expandNextPath);
-  }
-
-  TestRunner.deprecatedRunAfterPendingDispatches(expandNextPath);
-};
-
-SourcesTestRunner._expandProperty = function(parentTreeElement, path, pathIndex, callback) {
-  if (pathIndex === path.length) {
-    TestRunner.addResult('Expanded property: ' + path.join('.'));
-    callback();
-    return;
-  }
-
-  const name = path[pathIndex++];
-  const propertyTreeElement = SourcesTestRunner._findChildPropertyTreeElement(parentTreeElement, name);
-
-  if (!propertyTreeElement) {
-    TestRunner.addResult('Failed to expand property: ' + path.slice(0, pathIndex).join('.'));
-    SourcesTestRunner.completeDebuggerTest();
-    return;
-  }
-
-  propertyTreeElement.expand();
-  TestRunner.deprecatedRunAfterPendingDispatches(
-      SourcesTestRunner._expandProperty.bind(SourcesTestRunner, propertyTreeElement, path, pathIndex, callback));
-};
-
-SourcesTestRunner._findChildPropertyTreeElement = function(parent, childName) {
-  const children = parent.children();
-
-  for (let i = 0; i < children.length; i++) {
-    const treeElement = children[i];
-    const property = treeElement.property;
-
-    if (property.name === childName)
-      return treeElement;
-  }
-};
-
-SourcesTestRunner.setQuiet = function(quiet) {
-  SourcesTestRunner._quiet = quiet;
-};
-
-SourcesTestRunner.queryScripts = function(filter) {
-  const scripts = TestRunner.debuggerModel.scripts();
-  return (filter ? scripts.filter(filter) : scripts);
-};
-
-SourcesTestRunner.createScriptMock = function(
-    url, startLine, startColumn, isContentScript, source, target, preRegisterCallback) {
-  target = target || SDK.targetManager.mainTarget();
-  const debuggerModel = target.model(SDK.DebuggerModel);
-  const scriptId = ++SourcesTestRunner._lastScriptId + '';
-  const lineCount = source.computeLineEndings().length;
-  const endLine = startLine + lineCount - 1;
-  const endColumn =
-      (lineCount === 1 ? startColumn + source.length : source.length - source.computeLineEndings()[lineCount - 2]);
-  const hasSourceURL =
-      !!source.match(/\/\/#\ssourceURL=\s*(\S*?)\s*$/m) || !!source.match(/\/\/@\ssourceURL=\s*(\S*?)\s*$/m);
-
-  const script = new SDK.Script(
-      debuggerModel, scriptId, url, startLine, startColumn, endLine, endColumn, 0, '', isContentScript, false,
-      undefined, hasSourceURL, source.length);
-
-  script.requestContent = function() {
-    const trimmedSource = SDK.Script._trimSourceURLComment(source);
-    return Promise.resolve(trimmedSource);
-  };
-
-  if (preRegisterCallback)
-    preRegisterCallback(script);
-
-  debuggerModel._registerScript(script);
-  return script;
-};
-
-SourcesTestRunner._lastScriptId = 0;
-
-SourcesTestRunner.checkRawLocation = function(script, lineNumber, columnNumber, location) {
-  TestRunner.assertEquals(script.scriptId, location.scriptId, 'Incorrect scriptId');
-  TestRunner.assertEquals(lineNumber, location.lineNumber, 'Incorrect lineNumber');
-  TestRunner.assertEquals(columnNumber, location.columnNumber, 'Incorrect columnNumber');
-};
-
-SourcesTestRunner.checkUILocation = function(uiSourceCode, lineNumber, columnNumber, location) {
-  TestRunner.assertEquals(
-      uiSourceCode, location.uiSourceCode,
-      'Incorrect uiSourceCode, expected \'' + ((uiSourceCode ? uiSourceCode.url() : null)) + '\',' +
-          ' but got \'' + ((location.uiSourceCode ? location.uiSourceCode.url() : null)) + '\'');
-
-  TestRunner.assertEquals(
-      lineNumber, location.lineNumber,
-      'Incorrect lineNumber, expected \'' + lineNumber + '\', but got \'' + location.lineNumber + '\'');
-
-  TestRunner.assertEquals(
-      columnNumber, location.columnNumber,
-      'Incorrect columnNumber, expected \'' + columnNumber + '\', but got \'' + location.columnNumber + '\'');
-};
-
-SourcesTestRunner.scriptFormatter = function() {
-  return self.runtime.allInstances(Sources.SourcesView.EditorAction).then(function(editorActions) {
-    for (let i = 0; i < editorActions.length; ++i) {
-      if (editorActions[i] instanceof Sources.ScriptFormatterEditorAction)
-        return editorActions[i];
-    }
-
-    return null;
-  });
-};
-
-SourcesTestRunner.waitForExecutionContextInTarget = function(target, callback) {
-  const runtimeModel = target.model(SDK.RuntimeModel);
-
-  if (runtimeModel.executionContexts().length) {
-    callback(runtimeModel.executionContexts()[0]);
-    return;
-  }
-
-  runtimeModel.addEventListener(SDK.RuntimeModel.Events.ExecutionContextCreated, contextCreated);
-
-  function contextCreated() {
-    runtimeModel.removeEventListener(SDK.RuntimeModel.Events.ExecutionContextCreated, contextCreated);
-    callback(runtimeModel.executionContexts()[0]);
-  }
-};
-
-SourcesTestRunner.selectThread = function(target) {
-  const threadsPane = self.runtime.sharedInstance(Sources.ThreadsSidebarPane);
-  threadsPane._list.selectItem(target.model(SDK.DebuggerModel));
-};
-
-SourcesTestRunner.evaluateOnCurrentCallFrame = function(code) {
-  return TestRunner.debuggerModel.evaluateOnSelectedCallFrame({expression: code, objectGroup: 'console'});
-};
-
-SourcesTestRunner.waitJavaScriptSourceFrameBreakpoints = function(sourceFrame) {
-  return waitUpdate().then(checkIfReady);
-
-  function waitUpdate() {
-    return new Promise(
-        resolve => TestRunner.addSniffer(sourceFrame.__proto__, '_breakpointDecorationsUpdatedForTest', resolve));
-  }
-
-  function checkIfReady() {
-    for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) {
-      if (breakpoint._fakePrimaryLocation && breakpoint.enabled())
-        return waitUpdate().then(checkIfReady);
-    }
-
-    return Promise.resolve();
-  }
-};
-
-SourcesTestRunner.dumpJavaScriptSourceFrameBreakpoints = function(sourceFrame) {
-  const textEditor = sourceFrame._textEditor;
-
-  for (let lineNumber = 0; lineNumber < textEditor.linesCount; ++lineNumber) {
-    if (!textEditor.hasLineClass(lineNumber, 'cm-breakpoint'))
-      continue;
-
-    const disabled = textEditor.hasLineClass(lineNumber, 'cm-breakpoint-disabled');
-    const conditional = textEditor.hasLineClass(lineNumber, 'cm-breakpoint-conditional');
-    TestRunner.addResult(
-        'breakpoint at ' + lineNumber + ((disabled ? ' disabled' : '')) + ((conditional ? ' conditional' : '')));
-    const range = new TextUtils.TextRange(lineNumber, 0, lineNumber, textEditor.line(lineNumber).length);
-    let bookmarks = textEditor.bookmarks(range, Sources.JavaScriptSourceFrame.BreakpointDecoration._bookmarkSymbol);
-    bookmarks = bookmarks.filter(bookmark => !!bookmark.position());
-    bookmarks.sort((bookmark1, bookmark2) => bookmark1.position().startColumn - bookmark2.position().startColumn);
-
-    for (const bookmark of bookmarks) {
-      const position = bookmark.position();
-      const element = bookmark[Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest];
-      const disabled = element.classList.contains('cm-inline-disabled');
-      const conditional = element.classList.contains('cm-inline-conditional');
-
-      TestRunner.addResult(
-          '  inline breakpoint at (' + position.startLine + ', ' + position.startColumn + ')' +
-          ((disabled ? ' disabled' : '')) + ((conditional ? ' conditional' : '')));
-    }
-  }
-};
-
-SourcesTestRunner.clickJavaScriptSourceFrameBreakpoint = function(sourceFrame, lineNumber, index, next) {
-  const textEditor = sourceFrame._textEditor;
-  const lineLength = textEditor.line(lineNumber).length;
-  const lineRange = new TextUtils.TextRange(lineNumber, 0, lineNumber, lineLength);
-  const bookmarks = textEditor.bookmarks(lineRange, Sources.JavaScriptSourceFrame.BreakpointDecoration._bookmarkSymbol);
-  bookmarks.sort((bookmark1, bookmark2) => bookmark1.position().startColumn - bookmark2.position().startColumn);
-  const bookmark = bookmarks[index];
-
-  if (bookmark) {
-    bookmark[Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest].click();
-  } else {
-    TestRunner.addResult(`Could not click on Javascript breakpoint - lineNumber: ${lineNumber}, index: ${index}`);
-    next();
-  }
-};
-
-SourcesTestRunner.setEventListenerBreakpoint = function(id, enabled, targetName) {
-  const pane = self.runtime.sharedInstance(BrowserDebugger.EventListenerBreakpointsSidebarPane);
-
-  const auxData = {'eventName': id};
-
-  if (targetName)
-    auxData.targetName = targetName;
-
-  const breakpoint = SDK.domDebuggerManager.resolveEventListenerBreakpoint(auxData);
-
-  if (breakpoint.enabled() !== enabled) {
-    pane._breakpoints.get(breakpoint).checkbox.checked = enabled;
-    pane._breakpointCheckboxClicked(breakpoint);
-  }
-};
-
-TestRunner.deprecatedInitAsync(`
-  function scheduleTestFunction() {
-    setTimeout(testFunction, 0);
-  }
-`);
diff --git a/front_end/sources_test_runner/EditorTestRunner.js b/front_end/sources_test_runner/EditorTestRunner.js
deleted file mode 100644
index 0c3e98a..0000000
--- a/front_end/sources_test_runner/EditorTestRunner.js
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-SourcesTestRunner.createTestEditor = function(clientHeight, textEditorDelegate) {
-  const textEditor =
-      new SourceFrame.SourcesTextEditor(textEditorDelegate || new SourceFrame.SourcesTextEditorDelegate());
-  clientHeight = clientHeight || 100;
-  textEditor.element.style.height = clientHeight + 'px';
-  textEditor.element.style.flex = 'none';
-  textEditor.show(UI.inspectorView.element);
-  return textEditor;
-};
-
-function textWithSelection(text, selections) {
-  if (!selections.length)
-    return text;
-
-  function lineWithCursor(line, column, cursorChar) {
-    return line.substring(0, column) + cursorChar + line.substring(column);
-  }
-
-  const lines = text.split('\n');
-  selections.sort(TextUtils.TextRange.comparator);
-
-  for (let i = selections.length - 1; i >= 0; --i) {
-    let selection = selections[i];
-    selection = selection.normalize();
-    const endCursorChar = (selection.isEmpty() ? '|' : '<');
-    lines[selection.endLine] = lineWithCursor(lines[selection.endLine], selection.endColumn, endCursorChar);
-
-    if (!selection.isEmpty())
-      lines[selection.startLine] = lineWithCursor(lines[selection.startLine], selection.startColumn, '>');
-  }
-
-  return lines.join('\n');
-}
-
-SourcesTestRunner.dumpTextWithSelection = function(textEditor, dumpWhiteSpaces) {
-  let text = textWithSelection(textEditor.text(), textEditor.selections());
-
-  if (dumpWhiteSpaces)
-    text = text.replace(/ /g, '.');
-
-  TestRunner.addResult(text);
-};
-
-SourcesTestRunner.setLineSelections = function(editor, selections) {
-  const coords = [];
-
-  for (let i = 0; i < selections.length; ++i) {
-    const selection = selections[i];
-
-    if (typeof selection.column === 'number') {
-      selection.from = selection.column;
-      selection.to = selection.column;
-    }
-
-    coords.push(new TextUtils.TextRange(selection.line, selection.from, selection.line, selection.to));
-  }
-
-  editor.setSelections(coords);
-};
-
-SourcesTestRunner.typeIn = function(editor, typeText, callback) {
-  callback = callback || new Function();
-  const noop = new Function();
-
-  for (let charIndex = 0; charIndex < typeText.length; ++charIndex) {
-    const iterationCallback = (charIndex + 1 === typeText.length ? callback : noop);
-
-    switch (typeText[charIndex]) {
-      case '\n':
-        SourcesTestRunner.fakeKeyEvent(editor, 'Enter', null, iterationCallback);
-        break;
-      case 'L':
-        SourcesTestRunner.fakeKeyEvent(editor, 'ArrowLeft', null, iterationCallback);
-        break;
-      case 'R':
-        SourcesTestRunner.fakeKeyEvent(editor, 'ArrowRight', null, iterationCallback);
-        break;
-      case 'U':
-        SourcesTestRunner.fakeKeyEvent(editor, 'ArrowUp', null, iterationCallback);
-        break;
-      case 'D':
-        SourcesTestRunner.fakeKeyEvent(editor, 'ArrowDown', null, iterationCallback);
-        break;
-      default:
-        SourcesTestRunner.fakeKeyEvent(editor, typeText[charIndex], null, iterationCallback);
-    }
-  }
-};
-
-const eventCodes = {
-  Enter: 13,
-  Home: 36,
-  ArrowLeft: 37,
-  ArrowUp: 38,
-  ArrowRight: 39,
-  ArrowDown: 40
-};
-
-function createCodeMirrorFakeEvent(editor, eventType, code, charCode, modifiers) {
-  function eventPreventDefault() {
-    this._handled = true;
-  }
-
-  const event = {
-    _handled: false,
-    type: eventType,
-    keyCode: code,
-    charCode: charCode,
-    preventDefault: eventPreventDefault,
-    stopPropagation: function() {},
-    target: editor._codeMirror.display.input.textarea
-  };
-
-  if (modifiers) {
-    for (let i = 0; i < modifiers.length; ++i)
-      event[modifiers[i]] = true;
-  }
-
-  return event;
-}
-
-function fakeCodeMirrorKeyEvent(editor, eventType, code, charCode, modifiers) {
-  const event = createCodeMirrorFakeEvent(editor, eventType, code, charCode, modifiers);
-
-  switch (eventType) {
-    case 'keydown':
-      editor._codeMirror.triggerOnKeyDown(event);
-      break;
-    case 'keypress':
-      editor._codeMirror.triggerOnKeyPress(event);
-      break;
-    case 'keyup':
-      editor._codeMirror.triggerOnKeyUp(event);
-      break;
-    default:
-      throw new Error('Unknown KeyEvent type');
-  }
-
-  return event._handled;
-}
-
-function fakeCodeMirrorInputEvent(editor, character) {
-  if (typeof character === 'string')
-    editor._codeMirror.display.input.textarea.value += character;
-}
-
-SourcesTestRunner.fakeKeyEvent = function(editor, originalCode, modifiers, callback) {
-  modifiers = modifiers || [];
-  let code;
-  let charCode;
-
-  if (originalCode === '\'') {
-    code = 222;
-    charCode = 0;
-  } else if (originalCode === '"') {
-    code = 222;
-    modifiers.push('shiftKey');
-    charCode = 34;
-  } else if (originalCode === '(') {
-    code = '9'.charCodeAt(0);
-    modifiers.push('shiftKey');
-    charCode = originalCode.charCodeAt(0);
-  }
-
-  code = code || eventCodes[originalCode] || originalCode;
-
-  if (typeof code === 'string')
-    code = code.charCodeAt(0);
-
-  if (fakeCodeMirrorKeyEvent(editor, 'keydown', code, charCode, modifiers)) {
-    callback();
-    return;
-  }
-
-  if (fakeCodeMirrorKeyEvent(editor, 'keypress', code, charCode, modifiers)) {
-    callback();
-    return;
-  }
-
-  fakeCodeMirrorInputEvent(editor, originalCode);
-  fakeCodeMirrorKeyEvent(editor, 'keyup', code, charCode, modifiers);
-
-  function callbackWrapper() {
-    editor._codeMirror.off('inputRead', callbackWrapper);
-    callback();
-  }
-
-  editor._codeMirror.on('inputRead', callbackWrapper);
-};
-
-SourcesTestRunner.dumpSelectionStats = function(textEditor) {
-  const listHashMap = {};
-  const sortedKeys = [];
-  const selections = textEditor.selections();
-
-  for (let i = 0; i < selections.length; ++i) {
-    const selection = selections[i];
-    const text = textEditor.text(selection);
-
-    if (!listHashMap[text]) {
-      listHashMap[text] = 1;
-      sortedKeys.push(text);
-    } else {
-      ++listHashMap[text];
-    }
-  }
-
-  for (let i = 0; i < sortedKeys.length; ++i) {
-    let keyName = sortedKeys[i];
-
-    if (!keyName.length)
-      keyName = '<Empty string>';
-    else
-      keyName = '\'' + keyName + '\'';
-
-    TestRunner.addResult(keyName + ': ' + listHashMap[sortedKeys[i]]);
-  }
-};
diff --git a/front_end/sources_test_runner/LiveEditTestRunner.js b/front_end/sources_test_runner/LiveEditTestRunner.js
deleted file mode 100644
index 3136a0a..0000000
--- a/front_end/sources_test_runner/LiveEditTestRunner.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-SourcesTestRunner.replaceInSource = function(sourceFrame, string, replacement) {
-  sourceFrame._textEditor.setReadOnly(false);
-
-  for (let i = 0; i < sourceFrame._textEditor.linesCount; ++i) {
-    const line = sourceFrame._textEditor.line(i);
-    const column = line.indexOf(string);
-
-    if (column === -1)
-      continue;
-
-    const range = new TextUtils.TextRange(i, column, i, column + string.length);
-    sourceFrame._textEditor.editRange(range, replacement);
-    break;
-  }
-};
-
-SourcesTestRunner.commitSource = function(sourceFrame) {
-  sourceFrame.commitEditing();
-};
-
-SourcesTestRunner.undoSourceEditing = function(sourceFrame) {
-  sourceFrame._textEditor.undo();
-};
diff --git a/front_end/sources_test_runner/SearchTestRunner.js b/front_end/sources_test_runner/SearchTestRunner.js
deleted file mode 100644
index 5a601dd..0000000
--- a/front_end/sources_test_runner/SearchTestRunner.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2017 The Chromium Authors. All
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-SourcesTestRunner.dumpSearchResults = function(searchResults) {
-  function comparator(a, b) {
-    a.url.localeCompare(b.url);
-  }
-
-  searchResults.sort(comparator);
-  TestRunner.addResult('Search results: ');
-
-  for (let i = 0; i < searchResults.length; i++) {
-    TestRunner.addResult(
-        'url: ' + searchResults[i].url.replace(/VM\d+/, 'VMXX') + ', matchesCount: ' + searchResults[i].matchesCount);
-  }
-
-  TestRunner.addResult('');
-};
-
-SourcesTestRunner.dumpSearchMatches = function(searchMatches) {
-  TestRunner.addResult('Search matches: ');
-
-  for (let i = 0; i < searchMatches.length; i++) {
-    TestRunner.addResult(
-        'lineNumber: ' + searchMatches[i].lineNumber + ', line: \'' + searchMatches[i].lineContent + '\'');
-  }
-
-  TestRunner.addResult('');
-};
-
-SourcesTestRunner.runSearchAndDumpResults = function(scope, searchConfig, callback) {
-  const searchResults = [];
-  const progress = new Common.Progress();
-  scope.performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback);
-
-  function searchResultCallback(searchResult) {
-    searchResults.push(searchResult);
-  }
-
-  function searchFinishedCallback() {
-    function comparator(searchResultA, searchResultB) {
-      return searchResultA._uiSourceCode.url().compareTo(searchResultB._uiSourceCode.url());
-    }
-
-    searchResults.sort(comparator);
-
-    for (let i = 0; i < searchResults.length; ++i) {
-      const searchResult = searchResults[i];
-      const uiSourceCode = searchResult._uiSourceCode;
-      const searchMatches = searchResult._searchMatches;
-
-      if (!searchMatches.length)
-        continue;
-
-      TestRunner.addResult(
-          'Search result #' + (i + 1) + ': uiSourceCode.url = ' + uiSourceCode.url().replace(/VM\d+/, 'VMXX'));
-
-      for (let j = 0; j < searchMatches.length; ++j) {
-        const lineNumber = searchMatches[j].lineNumber;
-        const lineContent = searchMatches[j].lineContent;
-        TestRunner.addResult(
-            '  search match #' + (j + 1) + ': lineNumber = ' + lineNumber + ', lineContent = \'' + lineContent + '\'');
-      }
-    }
-
-    callback();
-  }
-};
-
-SourcesTestRunner.replaceAndDumpChange = function(sourceFrame, searchConfig, replacement, replaceAll) {
-  const modifiers = [];
-
-  if (searchConfig.isRegex)
-    modifiers.push('regex');
-
-  if (searchConfig.caseSensitive)
-    modifiers.push('caseSensitive');
-
-  if (replaceAll)
-    modifiers.push('replaceAll');
-
-  const modifiersString = (modifiers.length ? ' (' + modifiers.join(', ') + ')' : '');
-  TestRunner.addResult(
-      'Running replace test for /' + searchConfig.query + '/' + replacement + '/ ' + modifiersString + ':');
-  editor = sourceFrame._textEditor;
-  const oldLines = [];
-
-  for (let i = 0; i < editor.linesCount; ++i)
-    oldLines.push(editor.line(i));
-
-  const searchableView = UI.panels.sources.sourcesView().searchableView();
-  searchableView.showSearchField();
-  searchableView._caseSensitiveButton.setToggled(searchConfig.caseSensitive);
-  searchableView._regexButton.setToggled(searchConfig.isRegex);
-  searchableView._searchInputElement.value = searchConfig.query;
-  searchableView._replaceToggleButton.setToggled(true);
-  searchableView._updateSecondRowVisibility();
-  searchableView._replaceInputElement.value = replacement;
-  searchableView._performSearch(true, true);
-
-  if (replaceAll)
-    searchableView._replaceAll();
-  else
-    searchableView._replace();
-
-  const newLines = [];
-
-  for (let i = 0; i < editor.linesCount; ++i)
-    newLines.push(editor.line(i));
-
-  for (let i = 0; i < newLines.length; ++i) {
-    if (oldLines[i] === newLines[i])
-      continue;
-
-    const oldLine = oldLines[i];
-    const newLine = newLines[i];
-    let prefixLength = 0;
-
-    for (let j = 0; j < oldLine.length && j < newLine.length && newLine[j] === oldLine[j]; ++j)
-      ++prefixLength;
-
-    let postfixLength = 0;
-
-    for (let j = 0; j < oldLine.length && j < newLine.length &&
-         newLine[newLine.length - j - 1] === oldLine[oldLine.length - j - 1];
-         ++j)
-      ++postfixLength;
-
-    const prefix = oldLine.substring(0, prefixLength);
-    const removed = oldLine.substring(prefixLength, oldLine.length - postfixLength);
-    const added = newLine.substring(prefixLength, newLine.length - postfixLength);
-    const postfix = oldLine.substring(oldLine.length - postfixLength);
-    TestRunner.addResult('  - ' + prefix + '#' + removed + '#' + added + '#' + postfix);
-  }
-};
-
-TestRunner.deprecatedInitAsync(`
-  if (window.GCController)
-    GCController.collect();
-`);
diff --git a/front_end/sources_test_runner/SourcesTestRunner.js b/front_end/sources_test_runner/SourcesTestRunner.js
deleted file mode 100644
index d589808..0000000
--- a/front_end/sources_test_runner/SourcesTestRunner.js
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-/**
- * @param {!Sources.NavigatorView} navigatorView
- * @param {boolean=} dumpIcons
- */
-SourcesTestRunner.dumpNavigatorView = function(navigatorView, dumpIcons) {
-  dumpNavigatorTreeOutline(navigatorView._scriptsTree);
-
-  /**
-   * @param {string} prefix
-   * @param {!UI.TreeElement} treeElement
-   */
-  function dumpNavigatorTreeElement(prefix, treeElement) {
-    let titleText = '';
-    if (treeElement._leadingIconsElement && dumpIcons) {
-      let icons = treeElement._leadingIconsElement.querySelectorAll('[is=ui-icon]');
-      icons = Array.prototype.slice.call(icons);
-      const iconTypes = icons.map(icon => icon._iconType);
-      if (iconTypes.length)
-        titleText = titleText + '[' + iconTypes.join(', ') + '] ';
-    }
-    titleText += treeElement.title;
-    if (treeElement._nodeType === Sources.NavigatorView.Types.FileSystem ||
-        treeElement._nodeType === Sources.NavigatorView.Types.FileSystemFolder) {
-      const hasMappedFiles = treeElement.listItemElement.classList.contains('has-mapped-files');
-      if (!hasMappedFiles)
-        titleText += ' [dimmed]';
-    }
-    TestRunner.addResult(prefix + titleText);
-    treeElement.expand();
-    const children = treeElement.children();
-    for (let i = 0; i < children.length; ++i)
-      dumpNavigatorTreeElement(prefix + '  ', children[i]);
-  }
-
-  /**
-   * @param {!UI.TreeOutline} treeOutline
-   */
-  function dumpNavigatorTreeOutline(treeOutline) {
-    const children = treeOutline.rootElement().children();
-    for (let i = 0; i < children.length; ++i)
-      dumpNavigatorTreeElement('', children[i]);
-  }
-};
-
-/**
- * @param {!Sources.NavigatorView} view
- */
-SourcesTestRunner.dumpNavigatorViewInAllModes = function(view) {
-  ['frame', 'frame/domain', 'frame/domain/folder', 'domain', 'domain/folder'].forEach(
-      SourcesTestRunner.dumpNavigatorViewInMode.bind(TestRunner, view));
-};
-
-/**
- * @param {!Sources.NavigatorView} view
- * @param {string} mode
- */
-SourcesTestRunner.dumpNavigatorViewInMode = function(view, mode) {
-  TestRunner.addResult(view instanceof Sources.NetworkNavigatorView ? 'Sources:' : 'Content Scripts:');
-  view._groupByFrame = mode.includes('frame');
-  view._groupByDomain = mode.includes('domain');
-  view._groupByFolder = mode.includes('folder');
-  view._resetForTest();
-  TestRunner.addResult('-------- Setting mode: [' + mode + ']');
-  SourcesTestRunner.dumpNavigatorView(view);
-};
-
-/**
- * @param {string} url
- * @param {string} content
- * @param {boolean=} isContentScript
- * @param {number=} worldId
- * @return {!Promise}
- */
-SourcesTestRunner.addScriptUISourceCode = function(url, content, isContentScript, worldId) {
-  content += '\n//# sourceURL=' + url;
-  if (isContentScript)
-    content = `testRunner.evaluateScriptInIsolatedWorld(${worldId}, \`${content}\`)`;
-  TestRunner.evaluateInPageAnonymously(content);
-  return TestRunner.waitForUISourceCode(url);
-};
-
-function testSourceMapping(text1, text2, mapping, testToken) {
-  const originalPosition = text1.indexOf(testToken);
-  TestRunner.assertTrue(originalPosition !== -1);
-  const originalLocation = Formatter.Formatter.positionToLocation(text1.computeLineEndings(), originalPosition);
-  const formattedLocation = mapping.originalToFormatted(originalLocation[0], originalLocation[1]);
-  const formattedPosition =
-      Formatter.Formatter.locationToPosition(text2.computeLineEndings(), formattedLocation[0], formattedLocation[1]);
-  const expectedFormattedPosition = text2.indexOf(testToken);
-
-  if (expectedFormattedPosition === formattedPosition)
-    TestRunner.addResult(String.sprintf('Correct mapping for <%s>', testToken));
-  else
-    TestRunner.addResult(String.sprintf('ERROR: Wrong mapping for <%s>', testToken));
-}
-
-SourcesTestRunner.testPrettyPrint = function(mimeType, text, mappingQueries, next) {
-  new Formatter.ScriptFormatter(mimeType, text, didFormatContent);
-
-  function didFormatContent(formattedSource, mapping) {
-    TestRunner.addResult('====== 8< ------');
-    TestRunner.addResult(formattedSource);
-    TestRunner.addResult('------ >8 ======');
-
-    while (mappingQueries && mappingQueries.length)
-      testSourceMapping(text, formattedSource, mapping, mappingQueries.shift());
-
-    next();
-  }
-};
-
-SourcesTestRunner.testJavascriptOutline = function(text) {
-  let fulfill;
-  const promise = new Promise(x => fulfill = x);
-  Formatter.formatterWorkerPool().javaScriptOutline(text, onChunk);
-  const items = [];
-  return promise;
-
-  function onChunk(isLastChunk, outlineItems) {
-    items.pushAll(outlineItems);
-
-    if (!isLastChunk)
-      return;
-
-    TestRunner.addResult('Text:');
-    TestRunner.addResult(text.split('\n').map(line => '    ' + line).join('\n'));
-    TestRunner.addResult('Outline:');
-
-    for (const item of items)
-      TestRunner.addResult('    ' + item.name + (item.arguments || '') + ':' + item.line + ':' + item.column);
-
-    fulfill();
-  }
-};
-
-SourcesTestRunner.dumpSwatchPositions = function(sourceFrame, bookmarkType) {
-  const textEditor = sourceFrame.textEditor;
-  const markers = textEditor.bookmarks(textEditor.fullRange(), bookmarkType);
-
-  for (let i = 0; i < markers.length; i++) {
-    const position = markers[i].position();
-    const text = markers[i]._marker.widgetNode.firstChild.textContent;
-    TestRunner.addResult('Line ' + position.startLine + ', Column ' + position.startColumn + ': ' + text);
-  }
-};
diff --git a/front_end/sources_test_runner/module.json b/front_end/sources_test_runner/module.json
deleted file mode 100644
index 52a978a..0000000
--- a/front_end/sources_test_runner/module.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "dependencies": [
-    "test_runner",
-    "sources",
-    "workspace",
-    "source_frame",
-    "text_utils",
-    "browser_debugger"
-  ],
-  "scripts": [
-    "SourcesTestRunner.js",
-    "DebuggerTestRunner.js",
-    "LiveEditTestRunner.js",
-    "SearchTestRunner.js",
-    "EditorTestRunner.js",
-    "AutocompleteTestRunner.js"
-  ],
-  "skip_compilation": [
-    "DebuggerTestRunner.js",
-    "LiveEditTestRunner.js",
-    "SearchTestRunner.js",
-    "SourcesTestRunner.js",
-    "EditorTestRunner.js",
-    "AutocompleteTestRunner.js"
-  ]
-}
diff --git a/front_end/terminal/TerminalWidget.js b/front_end/terminal/TerminalWidget.js
deleted file mode 100644
index 1d7bfe3..0000000
--- a/front_end/terminal/TerminalWidget.js
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Terminal.TerminalWidget = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('terminal/xterm.js/build/xterm.css');
-    this.registerRequiredCSS('terminal/terminal.css');
-    this.element.classList.add('terminal-root');
-    this._init();
-    this._linkifier = new Components.Linkifier();
-    this._config = {attributes: true, childList: true, characterData: true, subtree: true};
-  }
-
-  async _init() {
-    const backend = await Services.serviceManager.createRemoteService('Terminal');
-    this._initialized(backend);
-  }
-
-  /**
-   * @param {?Services.ServiceManager.Service} backend
-   */
-  _initialized(backend) {
-    if (!backend) {
-      if (!this._unavailableLabel) {
-        this._unavailableLabel = this.contentElement.createChild('div', 'terminal-error-message fill');
-        this._unavailableLabel.createChild('div').textContent = Common.UIString('Terminal service is not available');
-      }
-      setTimeout(this._init.bind(this), 2000);
-      return;
-    }
-
-    if (this._unavailableLabel) {
-      this._unavailableLabel.remove();
-      delete this._unavailableLabel;
-    }
-
-    this._backend = backend;
-
-    if (!this._term) {
-      this._term = new Terminal({cursorBlink: true});
-      this._term.open(this.contentElement);
-      this._mutationObserver = new MutationObserver(this._linkify.bind(this));
-      this._mutationObserver.observe(this.contentElement, this._config);
-      this._term.on('data', data => {
-        this._backend.send('write', {data: data});
-      });
-      this._term.fit();
-      this._term.on('resize', size => {
-        this._backend.send('resize', {cols: size.cols, rows: size.rows});
-      });
-    }
-
-    this._backend.send('init', {cols: this._term.cols, rows: this._term.rows});
-    this._backend.on('data', result => {
-      this._term.write(result.data);
-    });
-    this._backend.on('disposed', this._disposed.bind(this));
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._term)
-      this._term.fit();
-  }
-
-  _disposed() {
-    this._initialized(null);
-  }
-
-  /**
-   * @override
-   */
-  ownerViewDisposed() {
-    if (this._backend)
-      this._backend.dispose();
-  }
-
-  _linkify() {
-    this._mutationObserver.takeRecords();
-    this._mutationObserver.disconnect();
-    this._linkifier.reset();
-    const rows = this._term['rowContainer'].children;
-    for (let i = 0; i < rows.length; i++)
-      this._linkifyTerminalLine(rows[i]);
-    this._mutationObserver.observe(this.contentElement, this._config);
-  }
-
-  /**
-   * @param {string} string
-   */
-  _linkifyText(string) {
-    const regex1 = /([/\w\.-]*)+\:([\d]+)(?:\:([\d]+))?/;
-    const regex2 = /([/\w\.-]*)+\(([\d]+),([\d]+)\)/;
-    const container = createDocumentFragment();
-
-    while (string) {
-      const linkString = regex1.exec(string) || regex2.exec(string);
-      if (!linkString)
-        break;
-
-      const text = linkString[0];
-      const path = linkString[1];
-      const lineNumber = parseInt(linkString[2], 10) - 1 || 0;
-      const columnNumber = parseInt(linkString[3], 10) - 1 || 0;
-
-      const uiSourceCode = Workspace.workspace.uiSourceCodes().find(uisc => uisc.url().endsWith(path));
-      const linkIndex = string.indexOf(text);
-      const nonLink = string.substring(0, linkIndex);
-      container.appendChild(createTextNode(nonLink));
-
-      if (uiSourceCode) {
-        container.appendChild(Components.Linkifier.linkifyURL(
-            uiSourceCode.url(),
-            {text, lineNumber, columnNumber, maxLengh: Number.MAX_VALUE, className: 'terminal-link'}));
-      } else {
-        container.appendChild(createTextNode(text));
-      }
-      string = string.substring(linkIndex + text.length);
-    }
-
-    if (string)
-      container.appendChild(createTextNode(string));
-    return container;
-  }
-
-  /**
-   * @param {!Node} line
-   */
-  _linkifyTerminalLine(line) {
-    let node = line.firstChild;
-    while (node) {
-      if (node.nodeType !== Node.TEXT_NODE) {
-        node = node.nextSibling;
-        continue;
-      }
-      const nextNode = node.nextSibling;
-      node.remove();
-      const linkified = this._linkifyText(node.textContent);
-      line.insertBefore(linkified, nextNode);
-      node = nextNode;
-    }
-  }
-};
diff --git a/front_end/terminal/module.json b/front_end/terminal/module.json
deleted file mode 100644
index c00e963..0000000
--- a/front_end/terminal/module.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "drawer-view",
-            "id": "drawer.xterm",
-            "title": "Terminal",
-            "order": 10,
-            "persistence": "closeable",
-            "factoryName": "Terminal.TerminalWidget"
-        }
-    ],
-    "dependencies": [
-        "components",
-        "ui",
-        "services"
-    ],
-    "experiment": "terminalInDrawer",
-    "scripts": [
-        "xterm.js/build/xterm.js",
-        "xterm.js/addons/fit/fit.js",
-        "TerminalWidget.js"
-    ],
-    "skip_compilation": [
-        "xterm.js/build/xterm.js",
-        "xterm.js/addons/fit/fit.js"
-    ],
-    "resources": [
-        "terminal.css",
-        "xterm.js/build/xterm.css"
-    ]
-}
diff --git a/front_end/terminal/terminal.css b/front_end/terminal/terminal.css
deleted file mode 100644
index 17fa5a9..0000000
--- a/front_end/terminal/terminal.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.terminal-root {
-    background-color: #111;
-    color: #fafafa;
-    padding: 2px;
-    -webkit-user-select: text;
-    white-space: nowrap;
-}
-
-.terminal-error-message {
-    display: flex;
-    align-items: center;
-    padding: 10px;
-    background-color: rgba(255, 255, 255, 0.8);
-    justify-content: center;
-    font-size: 16px;
-    color: #222;
-}
-
-.terminal-error-message div {
-    padding-right: 10px;
-}
-
-.terminal-link {
-    color: inherit;
-    text-decoration: inherit;
-}
-
-.terminal-link:hover {
-    text-decoration: underline;
-    cursor: pointer;
-}
diff --git a/front_end/terminal/xterm.js/LICENSE b/front_end/terminal/xterm.js/LICENSE
deleted file mode 100644
index 1ed6f2a..0000000
--- a/front_end/terminal/xterm.js/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2014, sourceLair Limited (https://github.com/sourcelair/)
-Copyright (c) 2012-2013, Christopher Jeffrey (https://github.com/chjj/)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/front_end/terminal/xterm.js/README.chromium b/front_end/terminal/xterm.js/README.chromium
deleted file mode 100644
index 662bc38..0000000
--- a/front_end/terminal/xterm.js/README.chromium
+++ /dev/null
@@ -1,7 +0,0 @@
-Name: Xterm.js is a terminal front-end component written in JavaScript that works in the browser.
-Short Name: xterm.js
-URL: https://github.com/sourcelair/xterm.js
-License: MIT
-Security Critical: no
-
-This directory contains Chrome's version of xterm.js with tests, demo and some addons folders removed.
diff --git a/front_end/terminal/xterm.js/addons/fit/fit.js b/front_end/terminal/xterm.js/addons/fit/fit.js
deleted file mode 100644
index 46b79e9..0000000
--- a/front_end/terminal/xterm.js/addons/fit/fit.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Fit terminal columns and rows to the dimensions of its DOM element.
- *
- * ## Approach
- * - Rows: Truncate the division of the terminal parent element height by the terminal row height.
- *
- * - Columns: Truncate the division of the terminal parent element width by the terminal character
- * width (apply display: inline at the terminal row and truncate its width with the current
- * number of columns).
- * @module xterm/addons/fit/fit
- * @license MIT
- */
-
-(function (fit) {
-  if (typeof exports === 'object' && typeof module === 'object') {
-    /*
-     * CommonJS environment
-     */
-    module.exports = fit(require('../../xterm'));
-  } else if (typeof define == 'function') {
-    /*
-     * Require.js is available
-     */
-    define(['../../xterm'], fit);
-  } else {
-    /*
-     * Plain browser environment
-     */
-    fit(window.Terminal);
-  }
-})(function (Xterm) {
-  var exports = {};
-
-  exports.proposeGeometry = function (term) {
-    if (!term.element.parentElement) {
-      return null;
-    }
-    var parentElementStyle = window.getComputedStyle(term.element.parentElement),
-        parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
-        parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17),
-        elementStyle = window.getComputedStyle(term.element),
-        elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
-        elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')),
-        availableHeight = parentElementHeight - elementPaddingVer,
-        availableWidth = parentElementWidth - elementPaddingHor,
-        container = term.rowContainer,
-        subjectRow = term.rowContainer.firstElementChild,
-        contentBuffer = subjectRow.innerHTML,
-        characterHeight,
-        rows,
-        characterWidth,
-        cols,
-        geometry;
-
-    subjectRow.style.display = 'inline';
-    subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace
-    characterWidth = subjectRow.getBoundingClientRect().width;
-    subjectRow.style.display = ''; // Revert style before calculating height, since they differ.
-    characterHeight = subjectRow.getBoundingClientRect().height;
-    subjectRow.innerHTML = contentBuffer;
-
-    rows = parseInt(availableHeight / characterHeight);
-    cols = parseInt(availableWidth / characterWidth);
-
-    geometry = {cols: cols, rows: rows};
-    return geometry;
-  };
-
-  exports.fit = function (term) {
-    var geometry = exports.proposeGeometry(term);
-
-    if (geometry) {
-      term.resize(geometry.cols, geometry.rows);
-    }
-  };
-
-  Xterm.prototype.proposeGeometry = function () {
-    return exports.proposeGeometry(this);
-  };
-
-  Xterm.prototype.fit = function () {
-    return exports.fit(this);
-  };
-
-  return exports;
-});
diff --git a/front_end/terminal/xterm.js/addons/fit/package.json b/front_end/terminal/xterm.js/addons/fit/package.json
deleted file mode 100644
index f7cb5bc..0000000
--- a/front_end/terminal/xterm.js/addons/fit/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "name": "xterm.fit",
-  "main": "fit.js",
-  "private": true
-}
diff --git a/front_end/terminal/xterm.js/build/xterm.css b/front_end/terminal/xterm.js/build/xterm.css
deleted file mode 100644
index efdc016..0000000
--- a/front_end/terminal/xterm.js/build/xterm.css
+++ /dev/null
@@ -1,2248 +0,0 @@
-/**
- * xterm.js: xterm, in the browser
- * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)
- * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
- * https://github.com/chjj/term.js
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * Originally forked from (with the author's permission):
- *   Fabrice Bellard's javascript vt100 for jslinux:
- *   http://bellard.org/jslinux/
- *   Copyright (c) 2011 Fabrice Bellard
- *   The original design remains. The terminal itself
- *   has been extended to include xterm CSI codes, among
- *   other features.
- */
-
-/*
- *  Default style for xterm.js
- */
-
-.terminal {
-    background-color: #000;
-    color: #fff;
-    font-family: courier-new, courier, monospace;
-    font-feature-settings: "liga" 0;
-    position: relative;
-}
-
-.terminal.focus,
-.terminal:focus {
-    outline: none;
-}
-
-.terminal .xterm-helpers {
-    position: absolute;
-    top: 0;
-}
-
-.terminal .xterm-helper-textarea {
-    /*
-     * HACK: to fix IE's blinking cursor
-     * Move textarea out of the screen to the far left, so that the cursor is not visible.
-     */
-    position: absolute;
-    opacity: 0;
-    left: -9999em;
-    top: 0;
-    width: 0;
-    height: 0;
-    z-index: -10;
-    /** Prevent wrapping so the IME appears against the textarea at the correct position */
-    white-space: nowrap;
-    overflow: hidden;
-    resize: none;
-}
-
-.terminal a {
-    color: inherit;
-    text-decoration: none;
-}
-
-.terminal a:hover {
-    cursor: pointer;
-    text-decoration: underline;
-}
-
-.terminal a.xterm-invalid-link:hover {
-    cursor: text;
-    text-decoration: none;
-}
-
-.terminal.focus:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor {
-    background-color: #fff;
-    color: #000;
-}
-
-.terminal:not(.focus) .terminal-cursor {
-    outline: 1px solid #fff;
-    outline-offset: -1px;
-    background-color: transparent;
-}
-
-.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink-on .terminal-cursor {
-    background-color: transparent;
-    color: inherit;
-}
-
-.terminal.xterm-cursor-style-bar .terminal-cursor,
-.terminal.xterm-cursor-style-underline .terminal-cursor {
-    position: relative;
-}
-.terminal.xterm-cursor-style-bar .terminal-cursor::before,
-.terminal.xterm-cursor-style-underline .terminal-cursor::before {
-    content: "";
-    display: block;
-    position: absolute;
-    background-color: #fff;
-}
-.terminal.xterm-cursor-style-bar .terminal-cursor::before {
-    top: 0;
-    bottom: 0;
-    left: 0;
-    width: 1px;
-}
-.terminal.xterm-cursor-style-underline .terminal-cursor::before {
-    bottom: 0;
-    left: 0;
-    right: 0;
-    height: 1px;
-}
-.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before,
-.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before {
-    background-color: transparent;
-}
-.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before,
-.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before {
-    background-color: #fff;
-}
-
-.terminal .composition-view {
-    background: #000;
-    color: #FFF;
-    display: none;
-    position: absolute;
-    white-space: nowrap;
-    z-index: 1;
-}
-
-.terminal .composition-view.active {
-    display: block;
-}
-
-.terminal .xterm-viewport {
-    /* On OS X this is required in order for the scroll bar to appear fully opaque */
-    background-color: #000;
-    overflow-y: scroll;
-}
-
-.terminal .xterm-wide-char,
-.terminal .xterm-normal-char {
-    display: inline-block;
-}
-
-.terminal .xterm-rows {
-    position: absolute;
-    left: 0;
-    top: 0;
-}
-
-.terminal .xterm-rows > div {
-    /* Lines containing spans and text nodes ocassionally wrap despite being the same width (#327) */
-    white-space: nowrap;
-}
-
-.terminal .xterm-scroll-area {
-    visibility: hidden;
-}
-
-.terminal .xterm-char-measure-element {
-    display: inline-block;
-    visibility: hidden;
-    position: absolute;
-    left: -9999em;
-}
-
-/*
- *  Determine default colors for xterm.js
- */
-.terminal .xterm-bold {
-    font-weight: bold;
-}
-
-.terminal .xterm-underline {
-    text-decoration: underline;
-}
-
-.terminal .xterm-blink {
-    text-decoration: blink;
-}
-
-.terminal .xterm-hidden {
-    visibility: hidden;
-}
-
-.terminal .xterm-color-0 {
-    color: #2e3436;
-}
-
-.terminal .xterm-bg-color-0 {
-    background-color: #2e3436;
-}
-
-.terminal .xterm-color-1 {
-    color: #cc0000;
-}
-
-.terminal .xterm-bg-color-1 {
-    background-color: #cc0000;
-}
-
-.terminal .xterm-color-2 {
-    color: #4e9a06;
-}
-
-.terminal .xterm-bg-color-2 {
-    background-color: #4e9a06;
-}
-
-.terminal .xterm-color-3 {
-    color: #c4a000;
-}
-
-.terminal .xterm-bg-color-3 {
-    background-color: #c4a000;
-}
-
-.terminal .xterm-color-4 {
-    color: #3465a4;
-}
-
-.terminal .xterm-bg-color-4 {
-    background-color: #3465a4;
-}
-
-.terminal .xterm-color-5 {
-    color: #75507b;
-}
-
-.terminal .xterm-bg-color-5 {
-    background-color: #75507b;
-}
-
-.terminal .xterm-color-6 {
-    color: #06989a;
-}
-
-.terminal .xterm-bg-color-6 {
-    background-color: #06989a;
-}
-
-.terminal .xterm-color-7 {
-    color: #d3d7cf;
-}
-
-.terminal .xterm-bg-color-7 {
-    background-color: #d3d7cf;
-}
-
-.terminal .xterm-color-8 {
-    color: #555753;
-}
-
-.terminal .xterm-bg-color-8 {
-    background-color: #555753;
-}
-
-.terminal .xterm-color-9 {
-    color: #ef2929;
-}
-
-.terminal .xterm-bg-color-9 {
-    background-color: #ef2929;
-}
-
-.terminal .xterm-color-10 {
-    color: #8ae234;
-}
-
-.terminal .xterm-bg-color-10 {
-    background-color: #8ae234;
-}
-
-.terminal .xterm-color-11 {
-    color: #fce94f;
-}
-
-.terminal .xterm-bg-color-11 {
-    background-color: #fce94f;
-}
-
-.terminal .xterm-color-12 {
-    color: #729fcf;
-}
-
-.terminal .xterm-bg-color-12 {
-    background-color: #729fcf;
-}
-
-.terminal .xterm-color-13 {
-    color: #ad7fa8;
-}
-
-.terminal .xterm-bg-color-13 {
-    background-color: #ad7fa8;
-}
-
-.terminal .xterm-color-14 {
-    color: #34e2e2;
-}
-
-.terminal .xterm-bg-color-14 {
-    background-color: #34e2e2;
-}
-
-.terminal .xterm-color-15 {
-    color: #eeeeec;
-}
-
-.terminal .xterm-bg-color-15 {
-    background-color: #eeeeec;
-}
-
-.terminal .xterm-color-16 {
-    color: #000000;
-}
-
-.terminal .xterm-bg-color-16 {
-    background-color: #000000;
-}
-
-.terminal .xterm-color-17 {
-    color: #00005f;
-}
-
-.terminal .xterm-bg-color-17 {
-    background-color: #00005f;
-}
-
-.terminal .xterm-color-18 {
-    color: #000087;
-}
-
-.terminal .xterm-bg-color-18 {
-    background-color: #000087;
-}
-
-.terminal .xterm-color-19 {
-    color: #0000af;
-}
-
-.terminal .xterm-bg-color-19 {
-    background-color: #0000af;
-}
-
-.terminal .xterm-color-20 {
-    color: #0000d7;
-}
-
-.terminal .xterm-bg-color-20 {
-    background-color: #0000d7;
-}
-
-.terminal .xterm-color-21 {
-    color: #0000ff;
-}
-
-.terminal .xterm-bg-color-21 {
-    background-color: #0000ff;
-}
-
-.terminal .xterm-color-22 {
-    color: #005f00;
-}
-
-.terminal .xterm-bg-color-22 {
-    background-color: #005f00;
-}
-
-.terminal .xterm-color-23 {
-    color: #005f5f;
-}
-
-.terminal .xterm-bg-color-23 {
-    background-color: #005f5f;
-}
-
-.terminal .xterm-color-24 {
-    color: #005f87;
-}
-
-.terminal .xterm-bg-color-24 {
-    background-color: #005f87;
-}
-
-.terminal .xterm-color-25 {
-    color: #005faf;
-}
-
-.terminal .xterm-bg-color-25 {
-    background-color: #005faf;
-}
-
-.terminal .xterm-color-26 {
-    color: #005fd7;
-}
-
-.terminal .xterm-bg-color-26 {
-    background-color: #005fd7;
-}
-
-.terminal .xterm-color-27 {
-    color: #005fff;
-}
-
-.terminal .xterm-bg-color-27 {
-    background-color: #005fff;
-}
-
-.terminal .xterm-color-28 {
-    color: #008700;
-}
-
-.terminal .xterm-bg-color-28 {
-    background-color: #008700;
-}
-
-.terminal .xterm-color-29 {
-    color: #00875f;
-}
-
-.terminal .xterm-bg-color-29 {
-    background-color: #00875f;
-}
-
-.terminal .xterm-color-30 {
-    color: #008787;
-}
-
-.terminal .xterm-bg-color-30 {
-    background-color: #008787;
-}
-
-.terminal .xterm-color-31 {
-    color: #0087af;
-}
-
-.terminal .xterm-bg-color-31 {
-    background-color: #0087af;
-}
-
-.terminal .xterm-color-32 {
-    color: #0087d7;
-}
-
-.terminal .xterm-bg-color-32 {
-    background-color: #0087d7;
-}
-
-.terminal .xterm-color-33 {
-    color: #0087ff;
-}
-
-.terminal .xterm-bg-color-33 {
-    background-color: #0087ff;
-}
-
-.terminal .xterm-color-34 {
-    color: #00af00;
-}
-
-.terminal .xterm-bg-color-34 {
-    background-color: #00af00;
-}
-
-.terminal .xterm-color-35 {
-    color: #00af5f;
-}
-
-.terminal .xterm-bg-color-35 {
-    background-color: #00af5f;
-}
-
-.terminal .xterm-color-36 {
-    color: #00af87;
-}
-
-.terminal .xterm-bg-color-36 {
-    background-color: #00af87;
-}
-
-.terminal .xterm-color-37 {
-    color: #00afaf;
-}
-
-.terminal .xterm-bg-color-37 {
-    background-color: #00afaf;
-}
-
-.terminal .xterm-color-38 {
-    color: #00afd7;
-}
-
-.terminal .xterm-bg-color-38 {
-    background-color: #00afd7;
-}
-
-.terminal .xterm-color-39 {
-    color: #00afff;
-}
-
-.terminal .xterm-bg-color-39 {
-    background-color: #00afff;
-}
-
-.terminal .xterm-color-40 {
-    color: #00d700;
-}
-
-.terminal .xterm-bg-color-40 {
-    background-color: #00d700;
-}
-
-.terminal .xterm-color-41 {
-    color: #00d75f;
-}
-
-.terminal .xterm-bg-color-41 {
-    background-color: #00d75f;
-}
-
-.terminal .xterm-color-42 {
-    color: #00d787;
-}
-
-.terminal .xterm-bg-color-42 {
-    background-color: #00d787;
-}
-
-.terminal .xterm-color-43 {
-    color: #00d7af;
-}
-
-.terminal .xterm-bg-color-43 {
-    background-color: #00d7af;
-}
-
-.terminal .xterm-color-44 {
-    color: #00d7d7;
-}
-
-.terminal .xterm-bg-color-44 {
-    background-color: #00d7d7;
-}
-
-.terminal .xterm-color-45 {
-    color: #00d7ff;
-}
-
-.terminal .xterm-bg-color-45 {
-    background-color: #00d7ff;
-}
-
-.terminal .xterm-color-46 {
-    color: #00ff00;
-}
-
-.terminal .xterm-bg-color-46 {
-    background-color: #00ff00;
-}
-
-.terminal .xterm-color-47 {
-    color: #00ff5f;
-}
-
-.terminal .xterm-bg-color-47 {
-    background-color: #00ff5f;
-}
-
-.terminal .xterm-color-48 {
-    color: #00ff87;
-}
-
-.terminal .xterm-bg-color-48 {
-    background-color: #00ff87;
-}
-
-.terminal .xterm-color-49 {
-    color: #00ffaf;
-}
-
-.terminal .xterm-bg-color-49 {
-    background-color: #00ffaf;
-}
-
-.terminal .xterm-color-50 {
-    color: #00ffd7;
-}
-
-.terminal .xterm-bg-color-50 {
-    background-color: #00ffd7;
-}
-
-.terminal .xterm-color-51 {
-    color: #00ffff;
-}
-
-.terminal .xterm-bg-color-51 {
-    background-color: #00ffff;
-}
-
-.terminal .xterm-color-52 {
-    color: #5f0000;
-}
-
-.terminal .xterm-bg-color-52 {
-    background-color: #5f0000;
-}
-
-.terminal .xterm-color-53 {
-    color: #5f005f;
-}
-
-.terminal .xterm-bg-color-53 {
-    background-color: #5f005f;
-}
-
-.terminal .xterm-color-54 {
-    color: #5f0087;
-}
-
-.terminal .xterm-bg-color-54 {
-    background-color: #5f0087;
-}
-
-.terminal .xterm-color-55 {
-    color: #5f00af;
-}
-
-.terminal .xterm-bg-color-55 {
-    background-color: #5f00af;
-}
-
-.terminal .xterm-color-56 {
-    color: #5f00d7;
-}
-
-.terminal .xterm-bg-color-56 {
-    background-color: #5f00d7;
-}
-
-.terminal .xterm-color-57 {
-    color: #5f00ff;
-}
-
-.terminal .xterm-bg-color-57 {
-    background-color: #5f00ff;
-}
-
-.terminal .xterm-color-58 {
-    color: #5f5f00;
-}
-
-.terminal .xterm-bg-color-58 {
-    background-color: #5f5f00;
-}
-
-.terminal .xterm-color-59 {
-    color: #5f5f5f;
-}
-
-.terminal .xterm-bg-color-59 {
-    background-color: #5f5f5f;
-}
-
-.terminal .xterm-color-60 {
-    color: #5f5f87;
-}
-
-.terminal .xterm-bg-color-60 {
-    background-color: #5f5f87;
-}
-
-.terminal .xterm-color-61 {
-    color: #5f5faf;
-}
-
-.terminal .xterm-bg-color-61 {
-    background-color: #5f5faf;
-}
-
-.terminal .xterm-color-62 {
-    color: #5f5fd7;
-}
-
-.terminal .xterm-bg-color-62 {
-    background-color: #5f5fd7;
-}
-
-.terminal .xterm-color-63 {
-    color: #5f5fff;
-}
-
-.terminal .xterm-bg-color-63 {
-    background-color: #5f5fff;
-}
-
-.terminal .xterm-color-64 {
-    color: #5f8700;
-}
-
-.terminal .xterm-bg-color-64 {
-    background-color: #5f8700;
-}
-
-.terminal .xterm-color-65 {
-    color: #5f875f;
-}
-
-.terminal .xterm-bg-color-65 {
-    background-color: #5f875f;
-}
-
-.terminal .xterm-color-66 {
-    color: #5f8787;
-}
-
-.terminal .xterm-bg-color-66 {
-    background-color: #5f8787;
-}
-
-.terminal .xterm-color-67 {
-    color: #5f87af;
-}
-
-.terminal .xterm-bg-color-67 {
-    background-color: #5f87af;
-}
-
-.terminal .xterm-color-68 {
-    color: #5f87d7;
-}
-
-.terminal .xterm-bg-color-68 {
-    background-color: #5f87d7;
-}
-
-.terminal .xterm-color-69 {
-    color: #5f87ff;
-}
-
-.terminal .xterm-bg-color-69 {
-    background-color: #5f87ff;
-}
-
-.terminal .xterm-color-70 {
-    color: #5faf00;
-}
-
-.terminal .xterm-bg-color-70 {
-    background-color: #5faf00;
-}
-
-.terminal .xterm-color-71 {
-    color: #5faf5f;
-}
-
-.terminal .xterm-bg-color-71 {
-    background-color: #5faf5f;
-}
-
-.terminal .xterm-color-72 {
-    color: #5faf87;
-}
-
-.terminal .xterm-bg-color-72 {
-    background-color: #5faf87;
-}
-
-.terminal .xterm-color-73 {
-    color: #5fafaf;
-}
-
-.terminal .xterm-bg-color-73 {
-    background-color: #5fafaf;
-}
-
-.terminal .xterm-color-74 {
-    color: #5fafd7;
-}
-
-.terminal .xterm-bg-color-74 {
-    background-color: #5fafd7;
-}
-
-.terminal .xterm-color-75 {
-    color: #5fafff;
-}
-
-.terminal .xterm-bg-color-75 {
-    background-color: #5fafff;
-}
-
-.terminal .xterm-color-76 {
-    color: #5fd700;
-}
-
-.terminal .xterm-bg-color-76 {
-    background-color: #5fd700;
-}
-
-.terminal .xterm-color-77 {
-    color: #5fd75f;
-}
-
-.terminal .xterm-bg-color-77 {
-    background-color: #5fd75f;
-}
-
-.terminal .xterm-color-78 {
-    color: #5fd787;
-}
-
-.terminal .xterm-bg-color-78 {
-    background-color: #5fd787;
-}
-
-.terminal .xterm-color-79 {
-    color: #5fd7af;
-}
-
-.terminal .xterm-bg-color-79 {
-    background-color: #5fd7af;
-}
-
-.terminal .xterm-color-80 {
-    color: #5fd7d7;
-}
-
-.terminal .xterm-bg-color-80 {
-    background-color: #5fd7d7;
-}
-
-.terminal .xterm-color-81 {
-    color: #5fd7ff;
-}
-
-.terminal .xterm-bg-color-81 {
-    background-color: #5fd7ff;
-}
-
-.terminal .xterm-color-82 {
-    color: #5fff00;
-}
-
-.terminal .xterm-bg-color-82 {
-    background-color: #5fff00;
-}
-
-.terminal .xterm-color-83 {
-    color: #5fff5f;
-}
-
-.terminal .xterm-bg-color-83 {
-    background-color: #5fff5f;
-}
-
-.terminal .xterm-color-84 {
-    color: #5fff87;
-}
-
-.terminal .xterm-bg-color-84 {
-    background-color: #5fff87;
-}
-
-.terminal .xterm-color-85 {
-    color: #5fffaf;
-}
-
-.terminal .xterm-bg-color-85 {
-    background-color: #5fffaf;
-}
-
-.terminal .xterm-color-86 {
-    color: #5fffd7;
-}
-
-.terminal .xterm-bg-color-86 {
-    background-color: #5fffd7;
-}
-
-.terminal .xterm-color-87 {
-    color: #5fffff;
-}
-
-.terminal .xterm-bg-color-87 {
-    background-color: #5fffff;
-}
-
-.terminal .xterm-color-88 {
-    color: #870000;
-}
-
-.terminal .xterm-bg-color-88 {
-    background-color: #870000;
-}
-
-.terminal .xterm-color-89 {
-    color: #87005f;
-}
-
-.terminal .xterm-bg-color-89 {
-    background-color: #87005f;
-}
-
-.terminal .xterm-color-90 {
-    color: #870087;
-}
-
-.terminal .xterm-bg-color-90 {
-    background-color: #870087;
-}
-
-.terminal .xterm-color-91 {
-    color: #8700af;
-}
-
-.terminal .xterm-bg-color-91 {
-    background-color: #8700af;
-}
-
-.terminal .xterm-color-92 {
-    color: #8700d7;
-}
-
-.terminal .xterm-bg-color-92 {
-    background-color: #8700d7;
-}
-
-.terminal .xterm-color-93 {
-    color: #8700ff;
-}
-
-.terminal .xterm-bg-color-93 {
-    background-color: #8700ff;
-}
-
-.terminal .xterm-color-94 {
-    color: #875f00;
-}
-
-.terminal .xterm-bg-color-94 {
-    background-color: #875f00;
-}
-
-.terminal .xterm-color-95 {
-    color: #875f5f;
-}
-
-.terminal .xterm-bg-color-95 {
-    background-color: #875f5f;
-}
-
-.terminal .xterm-color-96 {
-    color: #875f87;
-}
-
-.terminal .xterm-bg-color-96 {
-    background-color: #875f87;
-}
-
-.terminal .xterm-color-97 {
-    color: #875faf;
-}
-
-.terminal .xterm-bg-color-97 {
-    background-color: #875faf;
-}
-
-.terminal .xterm-color-98 {
-    color: #875fd7;
-}
-
-.terminal .xterm-bg-color-98 {
-    background-color: #875fd7;
-}
-
-.terminal .xterm-color-99 {
-    color: #875fff;
-}
-
-.terminal .xterm-bg-color-99 {
-    background-color: #875fff;
-}
-
-.terminal .xterm-color-100 {
-    color: #878700;
-}
-
-.terminal .xterm-bg-color-100 {
-    background-color: #878700;
-}
-
-.terminal .xterm-color-101 {
-    color: #87875f;
-}
-
-.terminal .xterm-bg-color-101 {
-    background-color: #87875f;
-}
-
-.terminal .xterm-color-102 {
-    color: #878787;
-}
-
-.terminal .xterm-bg-color-102 {
-    background-color: #878787;
-}
-
-.terminal .xterm-color-103 {
-    color: #8787af;
-}
-
-.terminal .xterm-bg-color-103 {
-    background-color: #8787af;
-}
-
-.terminal .xterm-color-104 {
-    color: #8787d7;
-}
-
-.terminal .xterm-bg-color-104 {
-    background-color: #8787d7;
-}
-
-.terminal .xterm-color-105 {
-    color: #8787ff;
-}
-
-.terminal .xterm-bg-color-105 {
-    background-color: #8787ff;
-}
-
-.terminal .xterm-color-106 {
-    color: #87af00;
-}
-
-.terminal .xterm-bg-color-106 {
-    background-color: #87af00;
-}
-
-.terminal .xterm-color-107 {
-    color: #87af5f;
-}
-
-.terminal .xterm-bg-color-107 {
-    background-color: #87af5f;
-}
-
-.terminal .xterm-color-108 {
-    color: #87af87;
-}
-
-.terminal .xterm-bg-color-108 {
-    background-color: #87af87;
-}
-
-.terminal .xterm-color-109 {
-    color: #87afaf;
-}
-
-.terminal .xterm-bg-color-109 {
-    background-color: #87afaf;
-}
-
-.terminal .xterm-color-110 {
-    color: #87afd7;
-}
-
-.terminal .xterm-bg-color-110 {
-    background-color: #87afd7;
-}
-
-.terminal .xterm-color-111 {
-    color: #87afff;
-}
-
-.terminal .xterm-bg-color-111 {
-    background-color: #87afff;
-}
-
-.terminal .xterm-color-112 {
-    color: #87d700;
-}
-
-.terminal .xterm-bg-color-112 {
-    background-color: #87d700;
-}
-
-.terminal .xterm-color-113 {
-    color: #87d75f;
-}
-
-.terminal .xterm-bg-color-113 {
-    background-color: #87d75f;
-}
-
-.terminal .xterm-color-114 {
-    color: #87d787;
-}
-
-.terminal .xterm-bg-color-114 {
-    background-color: #87d787;
-}
-
-.terminal .xterm-color-115 {
-    color: #87d7af;
-}
-
-.terminal .xterm-bg-color-115 {
-    background-color: #87d7af;
-}
-
-.terminal .xterm-color-116 {
-    color: #87d7d7;
-}
-
-.terminal .xterm-bg-color-116 {
-    background-color: #87d7d7;
-}
-
-.terminal .xterm-color-117 {
-    color: #87d7ff;
-}
-
-.terminal .xterm-bg-color-117 {
-    background-color: #87d7ff;
-}
-
-.terminal .xterm-color-118 {
-    color: #87ff00;
-}
-
-.terminal .xterm-bg-color-118 {
-    background-color: #87ff00;
-}
-
-.terminal .xterm-color-119 {
-    color: #87ff5f;
-}
-
-.terminal .xterm-bg-color-119 {
-    background-color: #87ff5f;
-}
-
-.terminal .xterm-color-120 {
-    color: #87ff87;
-}
-
-.terminal .xterm-bg-color-120 {
-    background-color: #87ff87;
-}
-
-.terminal .xterm-color-121 {
-    color: #87ffaf;
-}
-
-.terminal .xterm-bg-color-121 {
-    background-color: #87ffaf;
-}
-
-.terminal .xterm-color-122 {
-    color: #87ffd7;
-}
-
-.terminal .xterm-bg-color-122 {
-    background-color: #87ffd7;
-}
-
-.terminal .xterm-color-123 {
-    color: #87ffff;
-}
-
-.terminal .xterm-bg-color-123 {
-    background-color: #87ffff;
-}
-
-.terminal .xterm-color-124 {
-    color: #af0000;
-}
-
-.terminal .xterm-bg-color-124 {
-    background-color: #af0000;
-}
-
-.terminal .xterm-color-125 {
-    color: #af005f;
-}
-
-.terminal .xterm-bg-color-125 {
-    background-color: #af005f;
-}
-
-.terminal .xterm-color-126 {
-    color: #af0087;
-}
-
-.terminal .xterm-bg-color-126 {
-    background-color: #af0087;
-}
-
-.terminal .xterm-color-127 {
-    color: #af00af;
-}
-
-.terminal .xterm-bg-color-127 {
-    background-color: #af00af;
-}
-
-.terminal .xterm-color-128 {
-    color: #af00d7;
-}
-
-.terminal .xterm-bg-color-128 {
-    background-color: #af00d7;
-}
-
-.terminal .xterm-color-129 {
-    color: #af00ff;
-}
-
-.terminal .xterm-bg-color-129 {
-    background-color: #af00ff;
-}
-
-.terminal .xterm-color-130 {
-    color: #af5f00;
-}
-
-.terminal .xterm-bg-color-130 {
-    background-color: #af5f00;
-}
-
-.terminal .xterm-color-131 {
-    color: #af5f5f;
-}
-
-.terminal .xterm-bg-color-131 {
-    background-color: #af5f5f;
-}
-
-.terminal .xterm-color-132 {
-    color: #af5f87;
-}
-
-.terminal .xterm-bg-color-132 {
-    background-color: #af5f87;
-}
-
-.terminal .xterm-color-133 {
-    color: #af5faf;
-}
-
-.terminal .xterm-bg-color-133 {
-    background-color: #af5faf;
-}
-
-.terminal .xterm-color-134 {
-    color: #af5fd7;
-}
-
-.terminal .xterm-bg-color-134 {
-    background-color: #af5fd7;
-}
-
-.terminal .xterm-color-135 {
-    color: #af5fff;
-}
-
-.terminal .xterm-bg-color-135 {
-    background-color: #af5fff;
-}
-
-.terminal .xterm-color-136 {
-    color: #af8700;
-}
-
-.terminal .xterm-bg-color-136 {
-    background-color: #af8700;
-}
-
-.terminal .xterm-color-137 {
-    color: #af875f;
-}
-
-.terminal .xterm-bg-color-137 {
-    background-color: #af875f;
-}
-
-.terminal .xterm-color-138 {
-    color: #af8787;
-}
-
-.terminal .xterm-bg-color-138 {
-    background-color: #af8787;
-}
-
-.terminal .xterm-color-139 {
-    color: #af87af;
-}
-
-.terminal .xterm-bg-color-139 {
-    background-color: #af87af;
-}
-
-.terminal .xterm-color-140 {
-    color: #af87d7;
-}
-
-.terminal .xterm-bg-color-140 {
-    background-color: #af87d7;
-}
-
-.terminal .xterm-color-141 {
-    color: #af87ff;
-}
-
-.terminal .xterm-bg-color-141 {
-    background-color: #af87ff;
-}
-
-.terminal .xterm-color-142 {
-    color: #afaf00;
-}
-
-.terminal .xterm-bg-color-142 {
-    background-color: #afaf00;
-}
-
-.terminal .xterm-color-143 {
-    color: #afaf5f;
-}
-
-.terminal .xterm-bg-color-143 {
-    background-color: #afaf5f;
-}
-
-.terminal .xterm-color-144 {
-    color: #afaf87;
-}
-
-.terminal .xterm-bg-color-144 {
-    background-color: #afaf87;
-}
-
-.terminal .xterm-color-145 {
-    color: #afafaf;
-}
-
-.terminal .xterm-bg-color-145 {
-    background-color: #afafaf;
-}
-
-.terminal .xterm-color-146 {
-    color: #afafd7;
-}
-
-.terminal .xterm-bg-color-146 {
-    background-color: #afafd7;
-}
-
-.terminal .xterm-color-147 {
-    color: #afafff;
-}
-
-.terminal .xterm-bg-color-147 {
-    background-color: #afafff;
-}
-
-.terminal .xterm-color-148 {
-    color: #afd700;
-}
-
-.terminal .xterm-bg-color-148 {
-    background-color: #afd700;
-}
-
-.terminal .xterm-color-149 {
-    color: #afd75f;
-}
-
-.terminal .xterm-bg-color-149 {
-    background-color: #afd75f;
-}
-
-.terminal .xterm-color-150 {
-    color: #afd787;
-}
-
-.terminal .xterm-bg-color-150 {
-    background-color: #afd787;
-}
-
-.terminal .xterm-color-151 {
-    color: #afd7af;
-}
-
-.terminal .xterm-bg-color-151 {
-    background-color: #afd7af;
-}
-
-.terminal .xterm-color-152 {
-    color: #afd7d7;
-}
-
-.terminal .xterm-bg-color-152 {
-    background-color: #afd7d7;
-}
-
-.terminal .xterm-color-153 {
-    color: #afd7ff;
-}
-
-.terminal .xterm-bg-color-153 {
-    background-color: #afd7ff;
-}
-
-.terminal .xterm-color-154 {
-    color: #afff00;
-}
-
-.terminal .xterm-bg-color-154 {
-    background-color: #afff00;
-}
-
-.terminal .xterm-color-155 {
-    color: #afff5f;
-}
-
-.terminal .xterm-bg-color-155 {
-    background-color: #afff5f;
-}
-
-.terminal .xterm-color-156 {
-    color: #afff87;
-}
-
-.terminal .xterm-bg-color-156 {
-    background-color: #afff87;
-}
-
-.terminal .xterm-color-157 {
-    color: #afffaf;
-}
-
-.terminal .xterm-bg-color-157 {
-    background-color: #afffaf;
-}
-
-.terminal .xterm-color-158 {
-    color: #afffd7;
-}
-
-.terminal .xterm-bg-color-158 {
-    background-color: #afffd7;
-}
-
-.terminal .xterm-color-159 {
-    color: #afffff;
-}
-
-.terminal .xterm-bg-color-159 {
-    background-color: #afffff;
-}
-
-.terminal .xterm-color-160 {
-    color: #d70000;
-}
-
-.terminal .xterm-bg-color-160 {
-    background-color: #d70000;
-}
-
-.terminal .xterm-color-161 {
-    color: #d7005f;
-}
-
-.terminal .xterm-bg-color-161 {
-    background-color: #d7005f;
-}
-
-.terminal .xterm-color-162 {
-    color: #d70087;
-}
-
-.terminal .xterm-bg-color-162 {
-    background-color: #d70087;
-}
-
-.terminal .xterm-color-163 {
-    color: #d700af;
-}
-
-.terminal .xterm-bg-color-163 {
-    background-color: #d700af;
-}
-
-.terminal .xterm-color-164 {
-    color: #d700d7;
-}
-
-.terminal .xterm-bg-color-164 {
-    background-color: #d700d7;
-}
-
-.terminal .xterm-color-165 {
-    color: #d700ff;
-}
-
-.terminal .xterm-bg-color-165 {
-    background-color: #d700ff;
-}
-
-.terminal .xterm-color-166 {
-    color: #d75f00;
-}
-
-.terminal .xterm-bg-color-166 {
-    background-color: #d75f00;
-}
-
-.terminal .xterm-color-167 {
-    color: #d75f5f;
-}
-
-.terminal .xterm-bg-color-167 {
-    background-color: #d75f5f;
-}
-
-.terminal .xterm-color-168 {
-    color: #d75f87;
-}
-
-.terminal .xterm-bg-color-168 {
-    background-color: #d75f87;
-}
-
-.terminal .xterm-color-169 {
-    color: #d75faf;
-}
-
-.terminal .xterm-bg-color-169 {
-    background-color: #d75faf;
-}
-
-.terminal .xterm-color-170 {
-    color: #d75fd7;
-}
-
-.terminal .xterm-bg-color-170 {
-    background-color: #d75fd7;
-}
-
-.terminal .xterm-color-171 {
-    color: #d75fff;
-}
-
-.terminal .xterm-bg-color-171 {
-    background-color: #d75fff;
-}
-
-.terminal .xterm-color-172 {
-    color: #d78700;
-}
-
-.terminal .xterm-bg-color-172 {
-    background-color: #d78700;
-}
-
-.terminal .xterm-color-173 {
-    color: #d7875f;
-}
-
-.terminal .xterm-bg-color-173 {
-    background-color: #d7875f;
-}
-
-.terminal .xterm-color-174 {
-    color: #d78787;
-}
-
-.terminal .xterm-bg-color-174 {
-    background-color: #d78787;
-}
-
-.terminal .xterm-color-175 {
-    color: #d787af;
-}
-
-.terminal .xterm-bg-color-175 {
-    background-color: #d787af;
-}
-
-.terminal .xterm-color-176 {
-    color: #d787d7;
-}
-
-.terminal .xterm-bg-color-176 {
-    background-color: #d787d7;
-}
-
-.terminal .xterm-color-177 {
-    color: #d787ff;
-}
-
-.terminal .xterm-bg-color-177 {
-    background-color: #d787ff;
-}
-
-.terminal .xterm-color-178 {
-    color: #d7af00;
-}
-
-.terminal .xterm-bg-color-178 {
-    background-color: #d7af00;
-}
-
-.terminal .xterm-color-179 {
-    color: #d7af5f;
-}
-
-.terminal .xterm-bg-color-179 {
-    background-color: #d7af5f;
-}
-
-.terminal .xterm-color-180 {
-    color: #d7af87;
-}
-
-.terminal .xterm-bg-color-180 {
-    background-color: #d7af87;
-}
-
-.terminal .xterm-color-181 {
-    color: #d7afaf;
-}
-
-.terminal .xterm-bg-color-181 {
-    background-color: #d7afaf;
-}
-
-.terminal .xterm-color-182 {
-    color: #d7afd7;
-}
-
-.terminal .xterm-bg-color-182 {
-    background-color: #d7afd7;
-}
-
-.terminal .xterm-color-183 {
-    color: #d7afff;
-}
-
-.terminal .xterm-bg-color-183 {
-    background-color: #d7afff;
-}
-
-.terminal .xterm-color-184 {
-    color: #d7d700;
-}
-
-.terminal .xterm-bg-color-184 {
-    background-color: #d7d700;
-}
-
-.terminal .xterm-color-185 {
-    color: #d7d75f;
-}
-
-.terminal .xterm-bg-color-185 {
-    background-color: #d7d75f;
-}
-
-.terminal .xterm-color-186 {
-    color: #d7d787;
-}
-
-.terminal .xterm-bg-color-186 {
-    background-color: #d7d787;
-}
-
-.terminal .xterm-color-187 {
-    color: #d7d7af;
-}
-
-.terminal .xterm-bg-color-187 {
-    background-color: #d7d7af;
-}
-
-.terminal .xterm-color-188 {
-    color: #d7d7d7;
-}
-
-.terminal .xterm-bg-color-188 {
-    background-color: #d7d7d7;
-}
-
-.terminal .xterm-color-189 {
-    color: #d7d7ff;
-}
-
-.terminal .xterm-bg-color-189 {
-    background-color: #d7d7ff;
-}
-
-.terminal .xterm-color-190 {
-    color: #d7ff00;
-}
-
-.terminal .xterm-bg-color-190 {
-    background-color: #d7ff00;
-}
-
-.terminal .xterm-color-191 {
-    color: #d7ff5f;
-}
-
-.terminal .xterm-bg-color-191 {
-    background-color: #d7ff5f;
-}
-
-.terminal .xterm-color-192 {
-    color: #d7ff87;
-}
-
-.terminal .xterm-bg-color-192 {
-    background-color: #d7ff87;
-}
-
-.terminal .xterm-color-193 {
-    color: #d7ffaf;
-}
-
-.terminal .xterm-bg-color-193 {
-    background-color: #d7ffaf;
-}
-
-.terminal .xterm-color-194 {
-    color: #d7ffd7;
-}
-
-.terminal .xterm-bg-color-194 {
-    background-color: #d7ffd7;
-}
-
-.terminal .xterm-color-195 {
-    color: #d7ffff;
-}
-
-.terminal .xterm-bg-color-195 {
-    background-color: #d7ffff;
-}
-
-.terminal .xterm-color-196 {
-    color: #ff0000;
-}
-
-.terminal .xterm-bg-color-196 {
-    background-color: #ff0000;
-}
-
-.terminal .xterm-color-197 {
-    color: #ff005f;
-}
-
-.terminal .xterm-bg-color-197 {
-    background-color: #ff005f;
-}
-
-.terminal .xterm-color-198 {
-    color: #ff0087;
-}
-
-.terminal .xterm-bg-color-198 {
-    background-color: #ff0087;
-}
-
-.terminal .xterm-color-199 {
-    color: #ff00af;
-}
-
-.terminal .xterm-bg-color-199 {
-    background-color: #ff00af;
-}
-
-.terminal .xterm-color-200 {
-    color: #ff00d7;
-}
-
-.terminal .xterm-bg-color-200 {
-    background-color: #ff00d7;
-}
-
-.terminal .xterm-color-201 {
-    color: #ff00ff;
-}
-
-.terminal .xterm-bg-color-201 {
-    background-color: #ff00ff;
-}
-
-.terminal .xterm-color-202 {
-    color: #ff5f00;
-}
-
-.terminal .xterm-bg-color-202 {
-    background-color: #ff5f00;
-}
-
-.terminal .xterm-color-203 {
-    color: #ff5f5f;
-}
-
-.terminal .xterm-bg-color-203 {
-    background-color: #ff5f5f;
-}
-
-.terminal .xterm-color-204 {
-    color: #ff5f87;
-}
-
-.terminal .xterm-bg-color-204 {
-    background-color: #ff5f87;
-}
-
-.terminal .xterm-color-205 {
-    color: #ff5faf;
-}
-
-.terminal .xterm-bg-color-205 {
-    background-color: #ff5faf;
-}
-
-.terminal .xterm-color-206 {
-    color: #ff5fd7;
-}
-
-.terminal .xterm-bg-color-206 {
-    background-color: #ff5fd7;
-}
-
-.terminal .xterm-color-207 {
-    color: #ff5fff;
-}
-
-.terminal .xterm-bg-color-207 {
-    background-color: #ff5fff;
-}
-
-.terminal .xterm-color-208 {
-    color: #ff8700;
-}
-
-.terminal .xterm-bg-color-208 {
-    background-color: #ff8700;
-}
-
-.terminal .xterm-color-209 {
-    color: #ff875f;
-}
-
-.terminal .xterm-bg-color-209 {
-    background-color: #ff875f;
-}
-
-.terminal .xterm-color-210 {
-    color: #ff8787;
-}
-
-.terminal .xterm-bg-color-210 {
-    background-color: #ff8787;
-}
-
-.terminal .xterm-color-211 {
-    color: #ff87af;
-}
-
-.terminal .xterm-bg-color-211 {
-    background-color: #ff87af;
-}
-
-.terminal .xterm-color-212 {
-    color: #ff87d7;
-}
-
-.terminal .xterm-bg-color-212 {
-    background-color: #ff87d7;
-}
-
-.terminal .xterm-color-213 {
-    color: #ff87ff;
-}
-
-.terminal .xterm-bg-color-213 {
-    background-color: #ff87ff;
-}
-
-.terminal .xterm-color-214 {
-    color: #ffaf00;
-}
-
-.terminal .xterm-bg-color-214 {
-    background-color: #ffaf00;
-}
-
-.terminal .xterm-color-215 {
-    color: #ffaf5f;
-}
-
-.terminal .xterm-bg-color-215 {
-    background-color: #ffaf5f;
-}
-
-.terminal .xterm-color-216 {
-    color: #ffaf87;
-}
-
-.terminal .xterm-bg-color-216 {
-    background-color: #ffaf87;
-}
-
-.terminal .xterm-color-217 {
-    color: #ffafaf;
-}
-
-.terminal .xterm-bg-color-217 {
-    background-color: #ffafaf;
-}
-
-.terminal .xterm-color-218 {
-    color: #ffafd7;
-}
-
-.terminal .xterm-bg-color-218 {
-    background-color: #ffafd7;
-}
-
-.terminal .xterm-color-219 {
-    color: #ffafff;
-}
-
-.terminal .xterm-bg-color-219 {
-    background-color: #ffafff;
-}
-
-.terminal .xterm-color-220 {
-    color: #ffd700;
-}
-
-.terminal .xterm-bg-color-220 {
-    background-color: #ffd700;
-}
-
-.terminal .xterm-color-221 {
-    color: #ffd75f;
-}
-
-.terminal .xterm-bg-color-221 {
-    background-color: #ffd75f;
-}
-
-.terminal .xterm-color-222 {
-    color: #ffd787;
-}
-
-.terminal .xterm-bg-color-222 {
-    background-color: #ffd787;
-}
-
-.terminal .xterm-color-223 {
-    color: #ffd7af;
-}
-
-.terminal .xterm-bg-color-223 {
-    background-color: #ffd7af;
-}
-
-.terminal .xterm-color-224 {
-    color: #ffd7d7;
-}
-
-.terminal .xterm-bg-color-224 {
-    background-color: #ffd7d7;
-}
-
-.terminal .xterm-color-225 {
-    color: #ffd7ff;
-}
-
-.terminal .xterm-bg-color-225 {
-    background-color: #ffd7ff;
-}
-
-.terminal .xterm-color-226 {
-    color: #ffff00;
-}
-
-.terminal .xterm-bg-color-226 {
-    background-color: #ffff00;
-}
-
-.terminal .xterm-color-227 {
-    color: #ffff5f;
-}
-
-.terminal .xterm-bg-color-227 {
-    background-color: #ffff5f;
-}
-
-.terminal .xterm-color-228 {
-    color: #ffff87;
-}
-
-.terminal .xterm-bg-color-228 {
-    background-color: #ffff87;
-}
-
-.terminal .xterm-color-229 {
-    color: #ffffaf;
-}
-
-.terminal .xterm-bg-color-229 {
-    background-color: #ffffaf;
-}
-
-.terminal .xterm-color-230 {
-    color: #ffffd7;
-}
-
-.terminal .xterm-bg-color-230 {
-    background-color: #ffffd7;
-}
-
-.terminal .xterm-color-231 {
-    color: #ffffff;
-}
-
-.terminal .xterm-bg-color-231 {
-    background-color: #ffffff;
-}
-
-.terminal .xterm-color-232 {
-    color: #080808;
-}
-
-.terminal .xterm-bg-color-232 {
-    background-color: #080808;
-}
-
-.terminal .xterm-color-233 {
-    color: #121212;
-}
-
-.terminal .xterm-bg-color-233 {
-    background-color: #121212;
-}
-
-.terminal .xterm-color-234 {
-    color: #1c1c1c;
-}
-
-.terminal .xterm-bg-color-234 {
-    background-color: #1c1c1c;
-}
-
-.terminal .xterm-color-235 {
-    color: #262626;
-}
-
-.terminal .xterm-bg-color-235 {
-    background-color: #262626;
-}
-
-.terminal .xterm-color-236 {
-    color: #303030;
-}
-
-.terminal .xterm-bg-color-236 {
-    background-color: #303030;
-}
-
-.terminal .xterm-color-237 {
-    color: #3a3a3a;
-}
-
-.terminal .xterm-bg-color-237 {
-    background-color: #3a3a3a;
-}
-
-.terminal .xterm-color-238 {
-    color: #444444;
-}
-
-.terminal .xterm-bg-color-238 {
-    background-color: #444444;
-}
-
-.terminal .xterm-color-239 {
-    color: #4e4e4e;
-}
-
-.terminal .xterm-bg-color-239 {
-    background-color: #4e4e4e;
-}
-
-.terminal .xterm-color-240 {
-    color: #585858;
-}
-
-.terminal .xterm-bg-color-240 {
-    background-color: #585858;
-}
-
-.terminal .xterm-color-241 {
-    color: #626262;
-}
-
-.terminal .xterm-bg-color-241 {
-    background-color: #626262;
-}
-
-.terminal .xterm-color-242 {
-    color: #6c6c6c;
-}
-
-.terminal .xterm-bg-color-242 {
-    background-color: #6c6c6c;
-}
-
-.terminal .xterm-color-243 {
-    color: #767676;
-}
-
-.terminal .xterm-bg-color-243 {
-    background-color: #767676;
-}
-
-.terminal .xterm-color-244 {
-    color: #808080;
-}
-
-.terminal .xterm-bg-color-244 {
-    background-color: #808080;
-}
-
-.terminal .xterm-color-245 {
-    color: #8a8a8a;
-}
-
-.terminal .xterm-bg-color-245 {
-    background-color: #8a8a8a;
-}
-
-.terminal .xterm-color-246 {
-    color: #949494;
-}
-
-.terminal .xterm-bg-color-246 {
-    background-color: #949494;
-}
-
-.terminal .xterm-color-247 {
-    color: #9e9e9e;
-}
-
-.terminal .xterm-bg-color-247 {
-    background-color: #9e9e9e;
-}
-
-.terminal .xterm-color-248 {
-    color: #a8a8a8;
-}
-
-.terminal .xterm-bg-color-248 {
-    background-color: #a8a8a8;
-}
-
-.terminal .xterm-color-249 {
-    color: #b2b2b2;
-}
-
-.terminal .xterm-bg-color-249 {
-    background-color: #b2b2b2;
-}
-
-.terminal .xterm-color-250 {
-    color: #bcbcbc;
-}
-
-.terminal .xterm-bg-color-250 {
-    background-color: #bcbcbc;
-}
-
-.terminal .xterm-color-251 {
-    color: #c6c6c6;
-}
-
-.terminal .xterm-bg-color-251 {
-    background-color: #c6c6c6;
-}
-
-.terminal .xterm-color-252 {
-    color: #d0d0d0;
-}
-
-.terminal .xterm-bg-color-252 {
-    background-color: #d0d0d0;
-}
-
-.terminal .xterm-color-253 {
-    color: #dadada;
-}
-
-.terminal .xterm-bg-color-253 {
-    background-color: #dadada;
-}
-
-.terminal .xterm-color-254 {
-    color: #e4e4e4;
-}
-
-.terminal .xterm-bg-color-254 {
-    background-color: #e4e4e4;
-}
-
-.terminal .xterm-color-255 {
-    color: #eeeeee;
-}
-
-.terminal .xterm-bg-color-255 {
-    background-color: #eeeeee;
-}
diff --git a/front_end/terminal/xterm.js/build/xterm.js b/front_end/terminal/xterm.js/build/xterm.js
deleted file mode 100644
index 7dfaab5..0000000
--- a/front_end/terminal/xterm.js/build/xterm.js
+++ /dev/null
@@ -1,4318 +0,0 @@
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){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.Terminal = 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 a(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(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.CHARSETS = {};
-exports.DEFAULT_CHARSET = exports.CHARSETS['B'];
-exports.CHARSETS['0'] = {
-    '`': '\u25c6',
-    'a': '\u2592',
-    'b': '\u0009',
-    'c': '\u000c',
-    'd': '\u000d',
-    'e': '\u000a',
-    'f': '\u00b0',
-    'g': '\u00b1',
-    'h': '\u2424',
-    'i': '\u000b',
-    'j': '\u2518',
-    'k': '\u2510',
-    'l': '\u250c',
-    'm': '\u2514',
-    'n': '\u253c',
-    'o': '\u23ba',
-    'p': '\u23bb',
-    'q': '\u2500',
-    'r': '\u23bc',
-    's': '\u23bd',
-    't': '\u251c',
-    'u': '\u2524',
-    'v': '\u2534',
-    'w': '\u252c',
-    'x': '\u2502',
-    'y': '\u2264',
-    'z': '\u2265',
-    '{': '\u03c0',
-    '|': '\u2260',
-    '}': '\u00a3',
-    '~': '\u00b7'
-};
-exports.CHARSETS['A'] = {
-    '#': '£'
-};
-exports.CHARSETS['B'] = null;
-exports.CHARSETS['4'] = {
-    '#': '£',
-    '@': '¾',
-    '[': 'ij',
-    '\\': '½',
-    ']': '|',
-    '{': '¨',
-    '|': 'f',
-    '}': '¼',
-    '~': '´'
-};
-exports.CHARSETS['C'] =
-    exports.CHARSETS['5'] = {
-        '[': 'Ä',
-        '\\': 'Ö',
-        ']': 'Å',
-        '^': 'Ü',
-        '`': 'é',
-        '{': 'ä',
-        '|': 'ö',
-        '}': 'å',
-        '~': 'ü'
-    };
-exports.CHARSETS['R'] = {
-    '#': '£',
-    '@': 'à',
-    '[': '°',
-    '\\': 'ç',
-    ']': '§',
-    '{': 'é',
-    '|': 'ù',
-    '}': 'è',
-    '~': '¨'
-};
-exports.CHARSETS['Q'] = {
-    '@': 'à',
-    '[': 'â',
-    '\\': 'ç',
-    ']': 'ê',
-    '^': 'î',
-    '`': 'ô',
-    '{': 'é',
-    '|': 'ù',
-    '}': 'è',
-    '~': 'û'
-};
-exports.CHARSETS['K'] = {
-    '@': '§',
-    '[': 'Ä',
-    '\\': 'Ö',
-    ']': 'Ü',
-    '{': 'ä',
-    '|': 'ö',
-    '}': 'ü',
-    '~': 'ß'
-};
-exports.CHARSETS['Y'] = {
-    '#': '£',
-    '@': '§',
-    '[': '°',
-    '\\': 'ç',
-    ']': 'é',
-    '`': 'ù',
-    '{': 'à',
-    '|': 'ò',
-    '}': 'è',
-    '~': 'ì'
-};
-exports.CHARSETS['E'] =
-    exports.CHARSETS['6'] = {
-        '@': 'Ä',
-        '[': 'Æ',
-        '\\': 'Ø',
-        ']': 'Å',
-        '^': 'Ü',
-        '`': 'ä',
-        '{': 'æ',
-        '|': 'ø',
-        '}': 'å',
-        '~': 'ü'
-    };
-exports.CHARSETS['Z'] = {
-    '#': '£',
-    '@': '§',
-    '[': '¡',
-    '\\': 'Ñ',
-    ']': '¿',
-    '{': '°',
-    '|': 'ñ',
-    '}': 'ç'
-};
-exports.CHARSETS['H'] =
-    exports.CHARSETS['7'] = {
-        '@': 'É',
-        '[': 'Ä',
-        '\\': 'Ö',
-        ']': 'Å',
-        '^': 'Ü',
-        '`': 'é',
-        '{': 'ä',
-        '|': 'ö',
-        '}': 'å',
-        '~': 'ü'
-    };
-exports.CHARSETS['='] = {
-    '#': 'ù',
-    '@': 'à',
-    '[': 'é',
-    '\\': 'ç',
-    ']': 'ê',
-    '^': 'î',
-    '_': 'è',
-    '`': 'ô',
-    '{': 'ä',
-    '|': 'ö',
-    '}': 'ü',
-    '~': 'û'
-};
-
-
-
-},{}],2:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var CompositionHelper = (function () {
-    function CompositionHelper(textarea, compositionView, terminal) {
-        this.textarea = textarea;
-        this.compositionView = compositionView;
-        this.terminal = terminal;
-        this.isComposing = false;
-        this.isSendingComposition = false;
-        this.compositionPosition = { start: null, end: null };
-    }
-    CompositionHelper.prototype.compositionstart = function () {
-        this.isComposing = true;
-        this.compositionPosition.start = this.textarea.value.length;
-        this.compositionView.textContent = '';
-        this.compositionView.classList.add('active');
-    };
-    CompositionHelper.prototype.compositionupdate = function (ev) {
-        var _this = this;
-        this.compositionView.textContent = ev.data;
-        this.updateCompositionElements();
-        setTimeout(function () {
-            _this.compositionPosition.end = _this.textarea.value.length;
-        }, 0);
-    };
-    CompositionHelper.prototype.compositionend = function () {
-        this.finalizeComposition(true);
-    };
-    CompositionHelper.prototype.keydown = function (ev) {
-        if (this.isComposing || this.isSendingComposition) {
-            if (ev.keyCode === 229) {
-                return false;
-            }
-            else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {
-                return false;
-            }
-            else {
-                this.finalizeComposition(false);
-            }
-        }
-        if (ev.keyCode === 229) {
-            this.handleAnyTextareaChanges();
-            return false;
-        }
-        return true;
-    };
-    CompositionHelper.prototype.finalizeComposition = function (waitForPropogation) {
-        var _this = this;
-        this.compositionView.classList.remove('active');
-        this.isComposing = false;
-        this.clearTextareaPosition();
-        if (!waitForPropogation) {
-            this.isSendingComposition = false;
-            var input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);
-            this.terminal.handler(input);
-        }
-        else {
-            var currentCompositionPosition_1 = {
-                start: this.compositionPosition.start,
-                end: this.compositionPosition.end,
-            };
-            this.isSendingComposition = true;
-            setTimeout(function () {
-                if (_this.isSendingComposition) {
-                    _this.isSendingComposition = false;
-                    var input = void 0;
-                    if (_this.isComposing) {
-                        input = _this.textarea.value.substring(currentCompositionPosition_1.start, currentCompositionPosition_1.end);
-                    }
-                    else {
-                        input = _this.textarea.value.substring(currentCompositionPosition_1.start);
-                    }
-                    _this.terminal.handler(input);
-                }
-            }, 0);
-        }
-    };
-    CompositionHelper.prototype.handleAnyTextareaChanges = function () {
-        var _this = this;
-        var oldValue = this.textarea.value;
-        setTimeout(function () {
-            if (!_this.isComposing) {
-                var newValue = _this.textarea.value;
-                var diff = newValue.replace(oldValue, '');
-                if (diff.length > 0) {
-                    _this.terminal.handler(diff);
-                }
-            }
-        }, 0);
-    };
-    CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) {
-        var _this = this;
-        if (!this.isComposing) {
-            return;
-        }
-        var cursor = this.terminal.element.querySelector('.terminal-cursor');
-        if (cursor) {
-            var xtermRows = this.terminal.element.querySelector('.xterm-rows');
-            var cursorTop = xtermRows.offsetTop + cursor.offsetTop;
-            this.compositionView.style.left = cursor.offsetLeft + 'px';
-            this.compositionView.style.top = cursorTop + 'px';
-            this.compositionView.style.height = cursor.offsetHeight + 'px';
-            this.compositionView.style.lineHeight = cursor.offsetHeight + 'px';
-            var compositionViewBounds = this.compositionView.getBoundingClientRect();
-            this.textarea.style.left = cursor.offsetLeft + 'px';
-            this.textarea.style.top = cursorTop + 'px';
-            this.textarea.style.width = compositionViewBounds.width + 'px';
-            this.textarea.style.height = compositionViewBounds.height + 'px';
-            this.textarea.style.lineHeight = compositionViewBounds.height + 'px';
-        }
-        if (!dontRecurse) {
-            setTimeout(function () { return _this.updateCompositionElements(true); }, 0);
-        }
-    };
-    ;
-    CompositionHelper.prototype.clearTextareaPosition = function () {
-        this.textarea.style.left = '';
-        this.textarea.style.top = '';
-    };
-    ;
-    return CompositionHelper;
-}());
-exports.CompositionHelper = CompositionHelper;
-
-
-
-},{}],3:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var C0;
-(function (C0) {
-    C0.NUL = '\x00';
-    C0.SOH = '\x01';
-    C0.STX = '\x02';
-    C0.ETX = '\x03';
-    C0.EOT = '\x04';
-    C0.ENQ = '\x05';
-    C0.ACK = '\x06';
-    C0.BEL = '\x07';
-    C0.BS = '\x08';
-    C0.HT = '\x09';
-    C0.LF = '\x0a';
-    C0.VT = '\x0b';
-    C0.FF = '\x0c';
-    C0.CR = '\x0d';
-    C0.SO = '\x0e';
-    C0.SI = '\x0f';
-    C0.DLE = '\x10';
-    C0.DC1 = '\x11';
-    C0.DC2 = '\x12';
-    C0.DC3 = '\x13';
-    C0.DC4 = '\x14';
-    C0.NAK = '\x15';
-    C0.SYN = '\x16';
-    C0.ETB = '\x17';
-    C0.CAN = '\x18';
-    C0.EM = '\x19';
-    C0.SUB = '\x1a';
-    C0.ESC = '\x1b';
-    C0.FS = '\x1c';
-    C0.GS = '\x1d';
-    C0.RS = '\x1e';
-    C0.US = '\x1f';
-    C0.SP = '\x20';
-    C0.DEL = '\x7f';
-})(C0 = exports.C0 || (exports.C0 = {}));
-;
-
-
-
-},{}],4:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-;
-var EventEmitter = (function () {
-    function EventEmitter() {
-        this._events = this._events || {};
-    }
-    EventEmitter.prototype.on = function (type, listener) {
-        this._events[type] = this._events[type] || [];
-        this._events[type].push(listener);
-    };
-    EventEmitter.prototype.off = function (type, listener) {
-        if (!this._events[type]) {
-            return;
-        }
-        var obj = this._events[type];
-        var i = obj.length;
-        while (i--) {
-            if (obj[i] === listener || obj[i].listener === listener) {
-                obj.splice(i, 1);
-                return;
-            }
-        }
-    };
-    EventEmitter.prototype.removeAllListeners = function (type) {
-        if (this._events[type]) {
-            delete this._events[type];
-        }
-    };
-    EventEmitter.prototype.once = function (type, listener) {
-        function on() {
-            var args = Array.prototype.slice.call(arguments);
-            this.off(type, on);
-            return listener.apply(this, args);
-        }
-        on.listener = listener;
-        return this.on(type, on);
-    };
-    EventEmitter.prototype.emit = function (type) {
-        var args = [];
-        for (var _i = 1; _i < arguments.length; _i++) {
-            args[_i - 1] = arguments[_i];
-        }
-        if (!this._events[type]) {
-            return;
-        }
-        var obj = this._events[type];
-        for (var i = 0; i < obj.length; i++) {
-            obj[i].apply(this, args);
-        }
-    };
-    EventEmitter.prototype.listeners = function (type) {
-        return this._events[type] || [];
-    };
-    return EventEmitter;
-}());
-exports.EventEmitter = EventEmitter;
-
-
-
-},{}],5:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var EscapeSequences_1 = require("./EscapeSequences");
-var Charsets_1 = require("./Charsets");
-var InputHandler = (function () {
-    function InputHandler(_terminal) {
-        this._terminal = _terminal;
-    }
-    InputHandler.prototype.addChar = function (char, code) {
-        if (char >= ' ') {
-            var ch_width = wcwidth(code);
-            if (this._terminal.charset && this._terminal.charset[char]) {
-                char = this._terminal.charset[char];
-            }
-            var row = this._terminal.y + this._terminal.ybase;
-            if (!ch_width && this._terminal.x) {
-                if (this._terminal.lines.get(row)[this._terminal.x - 1]) {
-                    if (!this._terminal.lines.get(row)[this._terminal.x - 1][2]) {
-                        if (this._terminal.lines.get(row)[this._terminal.x - 2])
-                            this._terminal.lines.get(row)[this._terminal.x - 2][1] += char;
-                    }
-                    else {
-                        this._terminal.lines.get(row)[this._terminal.x - 1][1] += char;
-                    }
-                    this._terminal.updateRange(this._terminal.y);
-                }
-                return;
-            }
-            if (this._terminal.x + ch_width - 1 >= this._terminal.cols) {
-                if (this._terminal.wraparoundMode) {
-                    this._terminal.x = 0;
-                    this._terminal.y++;
-                    if (this._terminal.y > this._terminal.scrollBottom) {
-                        this._terminal.y--;
-                        this._terminal.scroll();
-                    }
-                }
-                else {
-                    if (ch_width === 2)
-                        return;
-                }
-            }
-            row = this._terminal.y + this._terminal.ybase;
-            if (this._terminal.insertMode) {
-                for (var moves = 0; moves < ch_width; ++moves) {
-                    var removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();
-                    if (removed[2] === 0
-                        && this._terminal.lines.get(row)[this._terminal.cols - 2]
-                        && this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)
-                        this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];
-                    this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);
-                }
-            }
-            this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, char, ch_width];
-            this._terminal.x++;
-            this._terminal.updateRange(this._terminal.y);
-            if (ch_width === 2) {
-                this._terminal.lines.get(row)[this._terminal.x] = [this._terminal.curAttr, '', 0];
-                this._terminal.x++;
-            }
-        }
-    };
-    InputHandler.prototype.bell = function () {
-        var _this = this;
-        if (!this._terminal.visualBell) {
-            return;
-        }
-        this._terminal.element.style.borderColor = 'white';
-        setTimeout(function () { return _this._terminal.element.style.borderColor = ''; }, 10);
-        if (this._terminal.popOnBell) {
-            this._terminal.focus();
-        }
-    };
-    InputHandler.prototype.lineFeed = function () {
-        if (this._terminal.convertEol) {
-            this._terminal.x = 0;
-        }
-        this._terminal.y++;
-        if (this._terminal.y > this._terminal.scrollBottom) {
-            this._terminal.y--;
-            this._terminal.scroll();
-        }
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x--;
-        }
-    };
-    InputHandler.prototype.carriageReturn = function () {
-        this._terminal.x = 0;
-    };
-    InputHandler.prototype.backspace = function () {
-        if (this._terminal.x > 0) {
-            this._terminal.x--;
-        }
-    };
-    InputHandler.prototype.tab = function () {
-        this._terminal.x = this._terminal.nextStop();
-    };
-    InputHandler.prototype.shiftOut = function () {
-        this._terminal.setgLevel(1);
-    };
-    InputHandler.prototype.shiftIn = function () {
-        this._terminal.setgLevel(0);
-    };
-    InputHandler.prototype.insertChars = function (params) {
-        var param, row, j, ch;
-        param = params[0];
-        if (param < 1)
-            param = 1;
-        row = this._terminal.y + this._terminal.ybase;
-        j = this._terminal.x;
-        ch = [this._terminal.eraseAttr(), ' ', 1];
-        while (param-- && j < this._terminal.cols) {
-            this._terminal.lines.get(row).splice(j++, 0, ch);
-            this._terminal.lines.get(row).pop();
-        }
-    };
-    InputHandler.prototype.cursorUp = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.y -= param;
-        if (this._terminal.y < 0) {
-            this._terminal.y = 0;
-        }
-    };
-    InputHandler.prototype.cursorDown = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.y += param;
-        if (this._terminal.y >= this._terminal.rows) {
-            this._terminal.y = this._terminal.rows - 1;
-        }
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x--;
-        }
-    };
-    InputHandler.prototype.cursorForward = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.x += param;
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x = this._terminal.cols - 1;
-        }
-    };
-    InputHandler.prototype.cursorBackward = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x--;
-        }
-        this._terminal.x -= param;
-        if (this._terminal.x < 0) {
-            this._terminal.x = 0;
-        }
-    };
-    InputHandler.prototype.cursorNextLine = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.y += param;
-        if (this._terminal.y >= this._terminal.rows) {
-            this._terminal.y = this._terminal.rows - 1;
-        }
-        this._terminal.x = 0;
-    };
-    ;
-    InputHandler.prototype.cursorPrecedingLine = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.y -= param;
-        if (this._terminal.y < 0) {
-            this._terminal.y = 0;
-        }
-        this._terminal.x = 0;
-    };
-    ;
-    InputHandler.prototype.cursorCharAbsolute = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.x = param - 1;
-    };
-    InputHandler.prototype.cursorPosition = function (params) {
-        var row, col;
-        row = params[0] - 1;
-        if (params.length >= 2) {
-            col = params[1] - 1;
-        }
-        else {
-            col = 0;
-        }
-        if (row < 0) {
-            row = 0;
-        }
-        else if (row >= this._terminal.rows) {
-            row = this._terminal.rows - 1;
-        }
-        if (col < 0) {
-            col = 0;
-        }
-        else if (col >= this._terminal.cols) {
-            col = this._terminal.cols - 1;
-        }
-        this._terminal.x = col;
-        this._terminal.y = row;
-    };
-    InputHandler.prototype.cursorForwardTab = function (params) {
-        var param = params[0] || 1;
-        while (param--) {
-            this._terminal.x = this._terminal.nextStop();
-        }
-    };
-    InputHandler.prototype.eraseInDisplay = function (params) {
-        var j;
-        switch (params[0]) {
-            case 0:
-                this._terminal.eraseRight(this._terminal.x, this._terminal.y);
-                j = this._terminal.y + 1;
-                for (; j < this._terminal.rows; j++) {
-                    this._terminal.eraseLine(j);
-                }
-                break;
-            case 1:
-                this._terminal.eraseLeft(this._terminal.x, this._terminal.y);
-                j = this._terminal.y;
-                while (j--) {
-                    this._terminal.eraseLine(j);
-                }
-                break;
-            case 2:
-                j = this._terminal.rows;
-                while (j--)
-                    this._terminal.eraseLine(j);
-                break;
-            case 3:
-                var scrollBackSize = this._terminal.lines.length - this._terminal.rows;
-                if (scrollBackSize > 0) {
-                    this._terminal.lines.trimStart(scrollBackSize);
-                    this._terminal.ybase = Math.max(this._terminal.ybase - scrollBackSize, 0);
-                    this._terminal.ydisp = Math.max(this._terminal.ydisp - scrollBackSize, 0);
-                }
-                break;
-        }
-    };
-    InputHandler.prototype.eraseInLine = function (params) {
-        switch (params[0]) {
-            case 0:
-                this._terminal.eraseRight(this._terminal.x, this._terminal.y);
-                break;
-            case 1:
-                this._terminal.eraseLeft(this._terminal.x, this._terminal.y);
-                break;
-            case 2:
-                this._terminal.eraseLine(this._terminal.y);
-                break;
-        }
-    };
-    InputHandler.prototype.insertLines = function (params) {
-        var param, row, j;
-        param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        row = this._terminal.y + this._terminal.ybase;
-        j = this._terminal.rows - 1 - this._terminal.scrollBottom;
-        j = this._terminal.rows - 1 + this._terminal.ybase - j + 1;
-        while (param--) {
-            if (this._terminal.lines.length === this._terminal.lines.maxLength) {
-                this._terminal.lines.trimStart(1);
-                this._terminal.ybase--;
-                this._terminal.ydisp--;
-                row--;
-                j--;
-            }
-            this._terminal.lines.splice(row, 0, this._terminal.blankLine(true));
-            this._terminal.lines.splice(j, 1);
-        }
-        this._terminal.updateRange(this._terminal.y);
-        this._terminal.updateRange(this._terminal.scrollBottom);
-    };
-    InputHandler.prototype.deleteLines = function (params) {
-        var param, row, j;
-        param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        row = this._terminal.y + this._terminal.ybase;
-        j = this._terminal.rows - 1 - this._terminal.scrollBottom;
-        j = this._terminal.rows - 1 + this._terminal.ybase - j;
-        while (param--) {
-            if (this._terminal.lines.length === this._terminal.lines.maxLength) {
-                this._terminal.lines.trimStart(1);
-                this._terminal.ybase -= 1;
-                this._terminal.ydisp -= 1;
-            }
-            this._terminal.lines.splice(j + 1, 0, this._terminal.blankLine(true));
-            this._terminal.lines.splice(row, 1);
-        }
-        this._terminal.updateRange(this._terminal.y);
-        this._terminal.updateRange(this._terminal.scrollBottom);
-    };
-    InputHandler.prototype.deleteChars = function (params) {
-        var param, row, ch;
-        param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        row = this._terminal.y + this._terminal.ybase;
-        ch = [this._terminal.eraseAttr(), ' ', 1];
-        while (param--) {
-            this._terminal.lines.get(row).splice(this._terminal.x, 1);
-            this._terminal.lines.get(row).push(ch);
-        }
-    };
-    InputHandler.prototype.scrollUp = function (params) {
-        var param = params[0] || 1;
-        while (param--) {
-            this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 1);
-            this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 0, this._terminal.blankLine());
-        }
-        this._terminal.updateRange(this._terminal.scrollTop);
-        this._terminal.updateRange(this._terminal.scrollBottom);
-    };
-    InputHandler.prototype.scrollDown = function (params) {
-        var param = params[0] || 1;
-        while (param--) {
-            this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollBottom, 1);
-            this._terminal.lines.splice(this._terminal.ybase + this._terminal.scrollTop, 0, this._terminal.blankLine());
-        }
-        this._terminal.updateRange(this._terminal.scrollTop);
-        this._terminal.updateRange(this._terminal.scrollBottom);
-    };
-    InputHandler.prototype.eraseChars = function (params) {
-        var param, row, j, ch;
-        param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        row = this._terminal.y + this._terminal.ybase;
-        j = this._terminal.x;
-        ch = [this._terminal.eraseAttr(), ' ', 1];
-        while (param-- && j < this._terminal.cols) {
-            this._terminal.lines.get(row)[j++] = ch;
-        }
-    };
-    InputHandler.prototype.cursorBackwardTab = function (params) {
-        var param = params[0] || 1;
-        while (param--) {
-            this._terminal.x = this._terminal.prevStop();
-        }
-    };
-    InputHandler.prototype.charPosAbsolute = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.x = param - 1;
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x = this._terminal.cols - 1;
-        }
-    };
-    InputHandler.prototype.HPositionRelative = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.x += param;
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x = this._terminal.cols - 1;
-        }
-    };
-    InputHandler.prototype.repeatPrecedingCharacter = function (params) {
-        var param = params[0] || 1, line = this._terminal.lines.get(this._terminal.ybase + this._terminal.y), ch = line[this._terminal.x - 1] || [this._terminal.defAttr, ' ', 1];
-        while (param--) {
-            line[this._terminal.x++] = ch;
-        }
-    };
-    InputHandler.prototype.sendDeviceAttributes = function (params) {
-        if (params[0] > 0) {
-            return;
-        }
-        if (!this._terminal.prefix) {
-            if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {
-                this._terminal.send(EscapeSequences_1.C0.ESC + '[?1;2c');
-            }
-            else if (this._terminal.is('linux')) {
-                this._terminal.send(EscapeSequences_1.C0.ESC + '[?6c');
-            }
-        }
-        else if (this._terminal.prefix === '>') {
-            if (this._terminal.is('xterm')) {
-                this._terminal.send(EscapeSequences_1.C0.ESC + '[>0;276;0c');
-            }
-            else if (this._terminal.is('rxvt-unicode')) {
-                this._terminal.send(EscapeSequences_1.C0.ESC + '[>85;95;0c');
-            }
-            else if (this._terminal.is('linux')) {
-                this._terminal.send(params[0] + 'c');
-            }
-            else if (this._terminal.is('screen')) {
-                this._terminal.send(EscapeSequences_1.C0.ESC + '[>83;40003;0c');
-            }
-        }
-    };
-    InputHandler.prototype.linePosAbsolute = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.y = param - 1;
-        if (this._terminal.y >= this._terminal.rows) {
-            this._terminal.y = this._terminal.rows - 1;
-        }
-    };
-    InputHandler.prototype.VPositionRelative = function (params) {
-        var param = params[0];
-        if (param < 1) {
-            param = 1;
-        }
-        this._terminal.y += param;
-        if (this._terminal.y >= this._terminal.rows) {
-            this._terminal.y = this._terminal.rows - 1;
-        }
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x--;
-        }
-    };
-    InputHandler.prototype.HVPosition = function (params) {
-        if (params[0] < 1)
-            params[0] = 1;
-        if (params[1] < 1)
-            params[1] = 1;
-        this._terminal.y = params[0] - 1;
-        if (this._terminal.y >= this._terminal.rows) {
-            this._terminal.y = this._terminal.rows - 1;
-        }
-        this._terminal.x = params[1] - 1;
-        if (this._terminal.x >= this._terminal.cols) {
-            this._terminal.x = this._terminal.cols - 1;
-        }
-    };
-    InputHandler.prototype.tabClear = function (params) {
-        var param = params[0];
-        if (param <= 0) {
-            delete this._terminal.tabs[this._terminal.x];
-        }
-        else if (param === 3) {
-            this._terminal.tabs = {};
-        }
-    };
-    InputHandler.prototype.setMode = function (params) {
-        if (params.length > 1) {
-            for (var i = 0; i < params.length; i++) {
-                this.setMode([params[i]]);
-            }
-            return;
-        }
-        if (!this._terminal.prefix) {
-            switch (params[0]) {
-                case 4:
-                    this._terminal.insertMode = true;
-                    break;
-                case 20:
-                    break;
-            }
-        }
-        else if (this._terminal.prefix === '?') {
-            switch (params[0]) {
-                case 1:
-                    this._terminal.applicationCursor = true;
-                    break;
-                case 2:
-                    this._terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET);
-                    this._terminal.setgCharset(1, Charsets_1.DEFAULT_CHARSET);
-                    this._terminal.setgCharset(2, Charsets_1.DEFAULT_CHARSET);
-                    this._terminal.setgCharset(3, Charsets_1.DEFAULT_CHARSET);
-                    break;
-                case 3:
-                    this._terminal.savedCols = this._terminal.cols;
-                    this._terminal.resize(132, this._terminal.rows);
-                    break;
-                case 6:
-                    this._terminal.originMode = true;
-                    break;
-                case 7:
-                    this._terminal.wraparoundMode = true;
-                    break;
-                case 12:
-                    break;
-                case 66:
-                    this._terminal.log('Serial port requested application keypad.');
-                    this._terminal.applicationKeypad = true;
-                    this._terminal.viewport.syncScrollArea();
-                    break;
-                case 9:
-                case 1000:
-                case 1002:
-                case 1003:
-                    this._terminal.x10Mouse = params[0] === 9;
-                    this._terminal.vt200Mouse = params[0] === 1000;
-                    this._terminal.normalMouse = params[0] > 1000;
-                    this._terminal.mouseEvents = true;
-                    this._terminal.element.style.cursor = 'default';
-                    this._terminal.log('Binding to mouse events.');
-                    break;
-                case 1004:
-                    this._terminal.sendFocus = true;
-                    break;
-                case 1005:
-                    this._terminal.utfMouse = true;
-                    break;
-                case 1006:
-                    this._terminal.sgrMouse = true;
-                    break;
-                case 1015:
-                    this._terminal.urxvtMouse = true;
-                    break;
-                case 25:
-                    this._terminal.cursorHidden = false;
-                    break;
-                case 1049:
-                    ;
-                case 47:
-                case 1047:
-                    if (!this._terminal.normal) {
-                        var normal = {
-                            lines: this._terminal.lines,
-                            ybase: this._terminal.ybase,
-                            ydisp: this._terminal.ydisp,
-                            x: this._terminal.x,
-                            y: this._terminal.y,
-                            scrollTop: this._terminal.scrollTop,
-                            scrollBottom: this._terminal.scrollBottom,
-                            tabs: this._terminal.tabs
-                        };
-                        this._terminal.reset();
-                        this._terminal.viewport.syncScrollArea();
-                        this._terminal.normal = normal;
-                        this._terminal.showCursor();
-                    }
-                    break;
-            }
-        }
-    };
-    InputHandler.prototype.resetMode = function (params) {
-        if (params.length > 1) {
-            for (var i = 0; i < params.length; i++) {
-                this.resetMode([params[i]]);
-            }
-            return;
-        }
-        if (!this._terminal.prefix) {
-            switch (params[0]) {
-                case 4:
-                    this._terminal.insertMode = false;
-                    break;
-                case 20:
-                    break;
-            }
-        }
-        else if (this._terminal.prefix === '?') {
-            switch (params[0]) {
-                case 1:
-                    this._terminal.applicationCursor = false;
-                    break;
-                case 3:
-                    if (this._terminal.cols === 132 && this._terminal.savedCols) {
-                        this._terminal.resize(this._terminal.savedCols, this._terminal.rows);
-                    }
-                    delete this._terminal.savedCols;
-                    break;
-                case 6:
-                    this._terminal.originMode = false;
-                    break;
-                case 7:
-                    this._terminal.wraparoundMode = false;
-                    break;
-                case 12:
-                    break;
-                case 66:
-                    this._terminal.log('Switching back to normal keypad.');
-                    this._terminal.applicationKeypad = false;
-                    this._terminal.viewport.syncScrollArea();
-                    break;
-                case 9:
-                case 1000:
-                case 1002:
-                case 1003:
-                    this._terminal.x10Mouse = false;
-                    this._terminal.vt200Mouse = false;
-                    this._terminal.normalMouse = false;
-                    this._terminal.mouseEvents = false;
-                    this._terminal.element.style.cursor = '';
-                    break;
-                case 1004:
-                    this._terminal.sendFocus = false;
-                    break;
-                case 1005:
-                    this._terminal.utfMouse = false;
-                    break;
-                case 1006:
-                    this._terminal.sgrMouse = false;
-                    break;
-                case 1015:
-                    this._terminal.urxvtMouse = false;
-                    break;
-                case 25:
-                    this._terminal.cursorHidden = true;
-                    break;
-                case 1049:
-                    ;
-                case 47:
-                case 1047:
-                    if (this._terminal.normal) {
-                        this._terminal.lines = this._terminal.normal.lines;
-                        this._terminal.ybase = this._terminal.normal.ybase;
-                        this._terminal.ydisp = this._terminal.normal.ydisp;
-                        this._terminal.x = this._terminal.normal.x;
-                        this._terminal.y = this._terminal.normal.y;
-                        this._terminal.scrollTop = this._terminal.normal.scrollTop;
-                        this._terminal.scrollBottom = this._terminal.normal.scrollBottom;
-                        this._terminal.tabs = this._terminal.normal.tabs;
-                        this._terminal.normal = null;
-                        this._terminal.refresh(0, this._terminal.rows - 1);
-                        this._terminal.viewport.syncScrollArea();
-                        this._terminal.showCursor();
-                    }
-                    break;
-            }
-        }
-    };
-    InputHandler.prototype.charAttributes = function (params) {
-        if (params.length === 1 && params[0] === 0) {
-            this._terminal.curAttr = this._terminal.defAttr;
-            return;
-        }
-        var l = params.length, i = 0, flags = this._terminal.curAttr >> 18, fg = (this._terminal.curAttr >> 9) & 0x1ff, bg = this._terminal.curAttr & 0x1ff, p;
-        for (; i < l; i++) {
-            p = params[i];
-            if (p >= 30 && p <= 37) {
-                fg = p - 30;
-            }
-            else if (p >= 40 && p <= 47) {
-                bg = p - 40;
-            }
-            else if (p >= 90 && p <= 97) {
-                p += 8;
-                fg = p - 90;
-            }
-            else if (p >= 100 && p <= 107) {
-                p += 8;
-                bg = p - 100;
-            }
-            else if (p === 0) {
-                flags = this._terminal.defAttr >> 18;
-                fg = (this._terminal.defAttr >> 9) & 0x1ff;
-                bg = this._terminal.defAttr & 0x1ff;
-            }
-            else if (p === 1) {
-                flags |= 1;
-            }
-            else if (p === 4) {
-                flags |= 2;
-            }
-            else if (p === 5) {
-                flags |= 4;
-            }
-            else if (p === 7) {
-                flags |= 8;
-            }
-            else if (p === 8) {
-                flags |= 16;
-            }
-            else if (p === 22) {
-                flags &= ~1;
-            }
-            else if (p === 24) {
-                flags &= ~2;
-            }
-            else if (p === 25) {
-                flags &= ~4;
-            }
-            else if (p === 27) {
-                flags &= ~8;
-            }
-            else if (p === 28) {
-                flags &= ~16;
-            }
-            else if (p === 39) {
-                fg = (this._terminal.defAttr >> 9) & 0x1ff;
-            }
-            else if (p === 49) {
-                bg = this._terminal.defAttr & 0x1ff;
-            }
-            else if (p === 38) {
-                if (params[i + 1] === 2) {
-                    i += 2;
-                    fg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff);
-                    if (fg === -1)
-                        fg = 0x1ff;
-                    i += 2;
-                }
-                else if (params[i + 1] === 5) {
-                    i += 2;
-                    p = params[i] & 0xff;
-                    fg = p;
-                }
-            }
-            else if (p === 48) {
-                if (params[i + 1] === 2) {
-                    i += 2;
-                    bg = this._terminal.matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff);
-                    if (bg === -1)
-                        bg = 0x1ff;
-                    i += 2;
-                }
-                else if (params[i + 1] === 5) {
-                    i += 2;
-                    p = params[i] & 0xff;
-                    bg = p;
-                }
-            }
-            else if (p === 100) {
-                fg = (this._terminal.defAttr >> 9) & 0x1ff;
-                bg = this._terminal.defAttr & 0x1ff;
-            }
-            else {
-                this._terminal.error('Unknown SGR attribute: %d.', p);
-            }
-        }
-        this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;
-    };
-    InputHandler.prototype.deviceStatus = function (params) {
-        if (!this._terminal.prefix) {
-            switch (params[0]) {
-                case 5:
-                    this._terminal.send(EscapeSequences_1.C0.ESC + '[0n');
-                    break;
-                case 6:
-                    this._terminal.send(EscapeSequences_1.C0.ESC + '['
-                        + (this._terminal.y + 1)
-                        + ';'
-                        + (this._terminal.x + 1)
-                        + 'R');
-                    break;
-            }
-        }
-        else if (this._terminal.prefix === '?') {
-            switch (params[0]) {
-                case 6:
-                    this._terminal.send(EscapeSequences_1.C0.ESC + '[?'
-                        + (this._terminal.y + 1)
-                        + ';'
-                        + (this._terminal.x + 1)
-                        + 'R');
-                    break;
-                case 15:
-                    break;
-                case 25:
-                    break;
-                case 26:
-                    break;
-                case 53:
-                    break;
-            }
-        }
-    };
-    InputHandler.prototype.softReset = function (params) {
-        this._terminal.cursorHidden = false;
-        this._terminal.insertMode = false;
-        this._terminal.originMode = false;
-        this._terminal.wraparoundMode = true;
-        this._terminal.applicationKeypad = false;
-        this._terminal.viewport.syncScrollArea();
-        this._terminal.applicationCursor = false;
-        this._terminal.scrollTop = 0;
-        this._terminal.scrollBottom = this._terminal.rows - 1;
-        this._terminal.curAttr = this._terminal.defAttr;
-        this._terminal.x = this._terminal.y = 0;
-        this._terminal.charset = null;
-        this._terminal.glevel = 0;
-        this._terminal.charsets = [null];
-    };
-    InputHandler.prototype.setCursorStyle = function (params) {
-        var param = params[0] < 1 ? 1 : params[0];
-        switch (param) {
-            case 1:
-            case 2:
-                this._terminal.setOption('cursorStyle', 'block');
-                break;
-            case 3:
-            case 4:
-                this._terminal.setOption('cursorStyle', 'underline');
-                break;
-            case 5:
-            case 6:
-                this._terminal.setOption('cursorStyle', 'bar');
-                break;
-        }
-        var isBlinking = param % 2 === 1;
-        this._terminal.setOption('cursorBlink', isBlinking);
-    };
-    InputHandler.prototype.setScrollRegion = function (params) {
-        if (this._terminal.prefix)
-            return;
-        this._terminal.scrollTop = (params[0] || 1) - 1;
-        this._terminal.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;
-        this._terminal.x = 0;
-        this._terminal.y = 0;
-    };
-    InputHandler.prototype.saveCursor = function (params) {
-        this._terminal.savedX = this._terminal.x;
-        this._terminal.savedY = this._terminal.y;
-    };
-    InputHandler.prototype.restoreCursor = function (params) {
-        this._terminal.x = this._terminal.savedX || 0;
-        this._terminal.y = this._terminal.savedY || 0;
-    };
-    return InputHandler;
-}());
-exports.InputHandler = InputHandler;
-var wcwidth = (function (opts) {
-    var COMBINING = [
-        [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],
-        [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],
-        [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],
-        [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],
-        [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],
-        [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],
-        [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],
-        [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],
-        [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],
-        [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],
-        [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],
-        [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],
-        [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],
-        [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],
-        [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],
-        [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],
-        [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],
-        [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],
-        [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],
-        [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],
-        [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],
-        [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],
-        [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],
-        [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],
-        [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],
-        [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],
-        [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],
-        [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],
-        [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],
-        [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],
-        [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],
-        [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],
-        [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],
-        [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],
-        [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],
-        [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],
-        [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],
-        [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],
-        [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],
-        [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],
-        [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],
-        [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],
-        [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],
-        [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],
-        [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],
-        [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],
-        [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],
-        [0xE0100, 0xE01EF]
-    ];
-    function bisearch(ucs) {
-        var min = 0;
-        var max = COMBINING.length - 1;
-        var mid;
-        if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1])
-            return false;
-        while (max >= min) {
-            mid = Math.floor((min + max) / 2);
-            if (ucs > COMBINING[mid][1])
-                min = mid + 1;
-            else if (ucs < COMBINING[mid][0])
-                max = mid - 1;
-            else
-                return true;
-        }
-        return false;
-    }
-    function wcwidth(ucs) {
-        if (ucs === 0)
-            return opts.nul;
-        if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
-            return opts.control;
-        if (bisearch(ucs))
-            return 0;
-        if (isWide(ucs)) {
-            return 2;
-        }
-        return 1;
-    }
-    function isWide(ucs) {
-        return (ucs >= 0x1100 && (ucs <= 0x115f ||
-            ucs === 0x2329 ||
-            ucs === 0x232a ||
-            (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) ||
-            (ucs >= 0xac00 && ucs <= 0xd7a3) ||
-            (ucs >= 0xf900 && ucs <= 0xfaff) ||
-            (ucs >= 0xfe10 && ucs <= 0xfe19) ||
-            (ucs >= 0xfe30 && ucs <= 0xfe6f) ||
-            (ucs >= 0xff00 && ucs <= 0xff60) ||
-            (ucs >= 0xffe0 && ucs <= 0xffe6) ||
-            (ucs >= 0x20000 && ucs <= 0x2fffd) ||
-            (ucs >= 0x30000 && ucs <= 0x3fffd)));
-    }
-    return wcwidth;
-})({ nul: 0, control: 0 });
-
-
-
-},{"./Charsets":1,"./EscapeSequences":3}],6:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var INVALID_LINK_CLASS = 'xterm-invalid-link';
-var protocolClause = '(https?:\\/\\/)';
-var domainCharacterSet = '[\\da-z\\.-]+';
-var negatedDomainCharacterSet = '[^\\da-z\\.-]+';
-var domainBodyClause = '(' + domainCharacterSet + ')';
-var tldClause = '([a-z\\.]{2,6})';
-var ipClause = '((\\d{1,3}\\.){3}\\d{1,3})';
-var localHostClause = '(localhost)';
-var portClause = '(:\\d{1,5})';
-var hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';
-var pathClause = '(\\/[\\/\\w\\.\\-%~]*)*';
-var queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*';
-var queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?';
-var hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';
-var negatedPathCharacterSet = '[^\\/\\w\\.\\-%]+';
-var bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause;
-var start = '(?:^|' + negatedDomainCharacterSet + ')(';
-var end = ')($|' + negatedPathCharacterSet + ')';
-var strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end);
-var HYPERTEXT_LINK_MATCHER_ID = 0;
-var Linkifier = (function () {
-    function Linkifier() {
-        this._nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;
-        this._rowTimeoutIds = [];
-        this._linkMatchers = [];
-        this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });
-    }
-    Linkifier.prototype.attachToDom = function (document, rows) {
-        this._document = document;
-        this._rows = rows;
-    };
-    Linkifier.prototype.linkifyRow = function (rowIndex) {
-        if (!this._document) {
-            return;
-        }
-        var timeoutId = this._rowTimeoutIds[rowIndex];
-        if (timeoutId) {
-            clearTimeout(timeoutId);
-        }
-        this._rowTimeoutIds[rowIndex] = setTimeout(this._linkifyRow.bind(this, rowIndex), Linkifier.TIME_BEFORE_LINKIFY);
-    };
-    Linkifier.prototype.setHypertextLinkHandler = function (handler) {
-        this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler;
-    };
-    Linkifier.prototype.setHypertextValidationCallback = function (callback) {
-        this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback;
-    };
-    Linkifier.prototype.registerLinkMatcher = function (regex, handler, options) {
-        if (options === void 0) { options = {}; }
-        if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) {
-            throw new Error('handler must be defined');
-        }
-        var matcher = {
-            id: this._nextLinkMatcherId++,
-            regex: regex,
-            handler: handler,
-            matchIndex: options.matchIndex,
-            validationCallback: options.validationCallback,
-            priority: options.priority || 0
-        };
-        this._addLinkMatcherToList(matcher);
-        return matcher.id;
-    };
-    Linkifier.prototype._addLinkMatcherToList = function (matcher) {
-        if (this._linkMatchers.length === 0) {
-            this._linkMatchers.push(matcher);
-            return;
-        }
-        for (var i = this._linkMatchers.length - 1; i >= 0; i--) {
-            if (matcher.priority <= this._linkMatchers[i].priority) {
-                this._linkMatchers.splice(i + 1, 0, matcher);
-                return;
-            }
-        }
-        this._linkMatchers.splice(0, 0, matcher);
-    };
-    Linkifier.prototype.deregisterLinkMatcher = function (matcherId) {
-        for (var i = 1; i < this._linkMatchers.length; i++) {
-            if (this._linkMatchers[i].id === matcherId) {
-                this._linkMatchers.splice(i, 1);
-                return true;
-            }
-        }
-        return false;
-    };
-    Linkifier.prototype._linkifyRow = function (rowIndex) {
-        var row = this._rows[rowIndex];
-        if (!row) {
-            return;
-        }
-        var text = row.textContent;
-        for (var i = 0; i < this._linkMatchers.length; i++) {
-            var matcher = this._linkMatchers[i];
-            var linkElements = this._doLinkifyRow(row, matcher);
-            if (linkElements.length > 0) {
-                if (matcher.validationCallback) {
-                    var _loop_1 = function (j) {
-                        var element = linkElements[j];
-                        matcher.validationCallback(element.textContent, element, function (isValid) {
-                            if (!isValid) {
-                                element.classList.add(INVALID_LINK_CLASS);
-                            }
-                        });
-                    };
-                    for (var j = 0; j < linkElements.length; j++) {
-                        _loop_1(j);
-                    }
-                }
-                return;
-            }
-        }
-    };
-    Linkifier.prototype._doLinkifyRow = function (row, matcher) {
-        var result = [];
-        var isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID;
-        var nodes = row.childNodes;
-        var match = row.textContent.match(matcher.regex);
-        if (!match || match.length === 0) {
-            return result;
-        }
-        var uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];
-        var rowStartIndex = match.index + uri.length;
-        for (var i = 0; i < nodes.length; i++) {
-            var node = nodes[i];
-            var searchIndex = node.textContent.indexOf(uri);
-            if (searchIndex >= 0) {
-                var linkElement = this._createAnchorElement(uri, matcher.handler, isHttpLinkMatcher);
-                if (node.textContent.length === uri.length) {
-                    if (node.nodeType === 3) {
-                        this._replaceNode(node, linkElement);
-                    }
-                    else {
-                        var element = node;
-                        if (element.nodeName === 'A') {
-                            return result;
-                        }
-                        element.innerHTML = '';
-                        element.appendChild(linkElement);
-                    }
-                }
-                else {
-                    var nodesAdded = this._replaceNodeSubstringWithNode(node, linkElement, uri, searchIndex);
-                    i += nodesAdded;
-                }
-                result.push(linkElement);
-                match = row.textContent.substring(rowStartIndex).match(matcher.regex);
-                if (!match || match.length === 0) {
-                    return result;
-                }
-                uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];
-                rowStartIndex += match.index + uri.length;
-            }
-        }
-        return result;
-    };
-    Linkifier.prototype._createAnchorElement = function (uri, handler, isHypertextLinkHandler) {
-        var element = this._document.createElement('a');
-        element.textContent = uri;
-        element.draggable = false;
-        if (isHypertextLinkHandler) {
-            element.href = uri;
-            element.target = '_blank';
-            element.addEventListener('click', function (event) {
-                if (handler) {
-                    return handler(event, uri);
-                }
-            });
-        }
-        else {
-            element.addEventListener('click', function (event) {
-                if (element.classList.contains(INVALID_LINK_CLASS)) {
-                    return;
-                }
-                return handler(event, uri);
-            });
-        }
-        return element;
-    };
-    Linkifier.prototype._replaceNode = function (oldNode) {
-        var newNodes = [];
-        for (var _i = 1; _i < arguments.length; _i++) {
-            newNodes[_i - 1] = arguments[_i];
-        }
-        var parent = oldNode.parentNode;
-        for (var i = 0; i < newNodes.length; i++) {
-            parent.insertBefore(newNodes[i], oldNode);
-        }
-        parent.removeChild(oldNode);
-    };
-    Linkifier.prototype._replaceNodeSubstringWithNode = function (targetNode, newNode, substring, substringIndex) {
-        var node = targetNode;
-        if (node.nodeType !== 3) {
-            node = node.childNodes[0];
-        }
-        if (node.childNodes.length === 0 && node.nodeType !== 3) {
-            throw new Error('targetNode must be a text node or only contain a single text node');
-        }
-        var fullText = node.textContent;
-        if (substringIndex === 0) {
-            var rightText_1 = fullText.substring(substring.length);
-            var rightTextNode_1 = this._document.createTextNode(rightText_1);
-            this._replaceNode(node, newNode, rightTextNode_1);
-            return 0;
-        }
-        if (substringIndex === targetNode.textContent.length - substring.length) {
-            var leftText_1 = fullText.substring(0, substringIndex);
-            var leftTextNode_1 = this._document.createTextNode(leftText_1);
-            this._replaceNode(node, leftTextNode_1, newNode);
-            return 0;
-        }
-        var leftText = fullText.substring(0, substringIndex);
-        var leftTextNode = this._document.createTextNode(leftText);
-        var rightText = fullText.substring(substringIndex + substring.length);
-        var rightTextNode = this._document.createTextNode(rightText);
-        this._replaceNode(node, leftTextNode, newNode, rightTextNode);
-        return 1;
-    };
-    return Linkifier;
-}());
-Linkifier.TIME_BEFORE_LINKIFY = 200;
-exports.Linkifier = Linkifier;
-
-
-
-},{}],7:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var EscapeSequences_1 = require("./EscapeSequences");
-var Charsets_1 = require("./Charsets");
-var normalStateHandler = {};
-normalStateHandler[EscapeSequences_1.C0.BEL] = function (parser, handler) { return handler.bell(); };
-normalStateHandler[EscapeSequences_1.C0.LF] = function (parser, handler) { return handler.lineFeed(); };
-normalStateHandler[EscapeSequences_1.C0.VT] = normalStateHandler[EscapeSequences_1.C0.LF];
-normalStateHandler[EscapeSequences_1.C0.FF] = normalStateHandler[EscapeSequences_1.C0.LF];
-normalStateHandler[EscapeSequences_1.C0.CR] = function (parser, handler) { return handler.carriageReturn(); };
-normalStateHandler[EscapeSequences_1.C0.BS] = function (parser, handler) { return handler.backspace(); };
-normalStateHandler[EscapeSequences_1.C0.HT] = function (parser, handler) { return handler.tab(); };
-normalStateHandler[EscapeSequences_1.C0.SO] = function (parser, handler) { return handler.shiftOut(); };
-normalStateHandler[EscapeSequences_1.C0.SI] = function (parser, handler) { return handler.shiftIn(); };
-normalStateHandler[EscapeSequences_1.C0.ESC] = function (parser, handler) { return parser.setState(ParserState.ESCAPED); };
-var escapedStateHandler = {};
-escapedStateHandler['['] = function (parser, terminal) {
-    terminal.params = [];
-    terminal.currentParam = 0;
-    parser.setState(ParserState.CSI_PARAM);
-};
-escapedStateHandler[']'] = function (parser, terminal) {
-    terminal.params = [];
-    terminal.currentParam = 0;
-    parser.setState(ParserState.OSC);
-};
-escapedStateHandler['P'] = function (parser, terminal) {
-    terminal.params = [];
-    terminal.currentParam = 0;
-    parser.setState(ParserState.DCS);
-};
-escapedStateHandler['_'] = function (parser, terminal) {
-    parser.setState(ParserState.IGNORE);
-};
-escapedStateHandler['^'] = function (parser, terminal) {
-    parser.setState(ParserState.IGNORE);
-};
-escapedStateHandler['c'] = function (parser, terminal) {
-    terminal.reset();
-};
-escapedStateHandler['E'] = function (parser, terminal) {
-    terminal.x = 0;
-    terminal.index();
-    parser.setState(ParserState.NORMAL);
-};
-escapedStateHandler['D'] = function (parser, terminal) {
-    terminal.index();
-    parser.setState(ParserState.NORMAL);
-};
-escapedStateHandler['M'] = function (parser, terminal) {
-    terminal.reverseIndex();
-    parser.setState(ParserState.NORMAL);
-};
-escapedStateHandler['%'] = function (parser, terminal) {
-    terminal.setgLevel(0);
-    terminal.setgCharset(0, Charsets_1.DEFAULT_CHARSET);
-    parser.setState(ParserState.NORMAL);
-    parser.skipNextChar();
-};
-escapedStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); };
-var csiParamStateHandler = {};
-csiParamStateHandler['?'] = function (parser) { return parser.setPrefix('?'); };
-csiParamStateHandler['>'] = function (parser) { return parser.setPrefix('>'); };
-csiParamStateHandler['!'] = function (parser) { return parser.setPrefix('!'); };
-csiParamStateHandler['0'] = function (parser) { return parser.setParam(parser.getParam() * 10); };
-csiParamStateHandler['1'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 1); };
-csiParamStateHandler['2'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 2); };
-csiParamStateHandler['3'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 3); };
-csiParamStateHandler['4'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 4); };
-csiParamStateHandler['5'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 5); };
-csiParamStateHandler['6'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 6); };
-csiParamStateHandler['7'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 7); };
-csiParamStateHandler['8'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 8); };
-csiParamStateHandler['9'] = function (parser) { return parser.setParam(parser.getParam() * 10 + 9); };
-csiParamStateHandler['$'] = function (parser) { return parser.setPostfix('$'); };
-csiParamStateHandler['"'] = function (parser) { return parser.setPostfix('"'); };
-csiParamStateHandler[' '] = function (parser) { return parser.setPostfix(' '); };
-csiParamStateHandler['\''] = function (parser) { return parser.setPostfix('\''); };
-csiParamStateHandler[';'] = function (parser) { return parser.finalizeParam(); };
-csiParamStateHandler[EscapeSequences_1.C0.CAN] = function (parser) { return parser.setState(ParserState.NORMAL); };
-var csiStateHandler = {};
-csiStateHandler['@'] = function (handler, params, prefix) { return handler.insertChars(params); };
-csiStateHandler['A'] = function (handler, params, prefix) { return handler.cursorUp(params); };
-csiStateHandler['B'] = function (handler, params, prefix) { return handler.cursorDown(params); };
-csiStateHandler['C'] = function (handler, params, prefix) { return handler.cursorForward(params); };
-csiStateHandler['D'] = function (handler, params, prefix) { return handler.cursorBackward(params); };
-csiStateHandler['E'] = function (handler, params, prefix) { return handler.cursorNextLine(params); };
-csiStateHandler['F'] = function (handler, params, prefix) { return handler.cursorPrecedingLine(params); };
-csiStateHandler['G'] = function (handler, params, prefix) { return handler.cursorCharAbsolute(params); };
-csiStateHandler['H'] = function (handler, params, prefix) { return handler.cursorPosition(params); };
-csiStateHandler['I'] = function (handler, params, prefix) { return handler.cursorForwardTab(params); };
-csiStateHandler['J'] = function (handler, params, prefix) { return handler.eraseInDisplay(params); };
-csiStateHandler['K'] = function (handler, params, prefix) { return handler.eraseInLine(params); };
-csiStateHandler['L'] = function (handler, params, prefix) { return handler.insertLines(params); };
-csiStateHandler['M'] = function (handler, params, prefix) { return handler.deleteLines(params); };
-csiStateHandler['P'] = function (handler, params, prefix) { return handler.deleteChars(params); };
-csiStateHandler['S'] = function (handler, params, prefix) { return handler.scrollUp(params); };
-csiStateHandler['T'] = function (handler, params, prefix) {
-    if (params.length < 2 && !prefix) {
-        handler.scrollDown(params);
-    }
-};
-csiStateHandler['X'] = function (handler, params, prefix) { return handler.eraseChars(params); };
-csiStateHandler['Z'] = function (handler, params, prefix) { return handler.cursorBackwardTab(params); };
-csiStateHandler['`'] = function (handler, params, prefix) { return handler.charPosAbsolute(params); };
-csiStateHandler['a'] = function (handler, params, prefix) { return handler.HPositionRelative(params); };
-csiStateHandler['b'] = function (handler, params, prefix) { return handler.repeatPrecedingCharacter(params); };
-csiStateHandler['c'] = function (handler, params, prefix) { return handler.sendDeviceAttributes(params); };
-csiStateHandler['d'] = function (handler, params, prefix) { return handler.linePosAbsolute(params); };
-csiStateHandler['e'] = function (handler, params, prefix) { return handler.VPositionRelative(params); };
-csiStateHandler['f'] = function (handler, params, prefix) { return handler.HVPosition(params); };
-csiStateHandler['g'] = function (handler, params, prefix) { return handler.tabClear(params); };
-csiStateHandler['h'] = function (handler, params, prefix) { return handler.setMode(params); };
-csiStateHandler['l'] = function (handler, params, prefix) { return handler.resetMode(params); };
-csiStateHandler['m'] = function (handler, params, prefix) { return handler.charAttributes(params); };
-csiStateHandler['n'] = function (handler, params, prefix) { return handler.deviceStatus(params); };
-csiStateHandler['p'] = function (handler, params, prefix) {
-    switch (prefix) {
-        case '!':
-            handler.softReset(params);
-            break;
-    }
-};
-csiStateHandler['q'] = function (handler, params, prefix, postfix) {
-    if (postfix === ' ') {
-        handler.setCursorStyle(params);
-    }
-};
-csiStateHandler['r'] = function (handler, params) { return handler.setScrollRegion(params); };
-csiStateHandler['s'] = function (handler, params) { return handler.saveCursor(params); };
-csiStateHandler['u'] = function (handler, params) { return handler.restoreCursor(params); };
-csiStateHandler[EscapeSequences_1.C0.CAN] = function (handler, params, prefix, postfix, parser) { return parser.setState(ParserState.NORMAL); };
-var ParserState;
-(function (ParserState) {
-    ParserState[ParserState["NORMAL"] = 0] = "NORMAL";
-    ParserState[ParserState["ESCAPED"] = 1] = "ESCAPED";
-    ParserState[ParserState["CSI_PARAM"] = 2] = "CSI_PARAM";
-    ParserState[ParserState["CSI"] = 3] = "CSI";
-    ParserState[ParserState["OSC"] = 4] = "OSC";
-    ParserState[ParserState["CHARSET"] = 5] = "CHARSET";
-    ParserState[ParserState["DCS"] = 6] = "DCS";
-    ParserState[ParserState["IGNORE"] = 7] = "IGNORE";
-})(ParserState || (ParserState = {}));
-var Parser = (function () {
-    function Parser(_inputHandler, _terminal) {
-        this._inputHandler = _inputHandler;
-        this._terminal = _terminal;
-        this._state = ParserState.NORMAL;
-    }
-    Parser.prototype.parse = function (data) {
-        var l = data.length, j, cs, ch, code, low;
-        this._position = 0;
-        if (this._terminal.surrogate_high) {
-            data = this._terminal.surrogate_high + data;
-            this._terminal.surrogate_high = '';
-        }
-        for (; this._position < l; this._position++) {
-            ch = data[this._position];
-            code = data.charCodeAt(this._position);
-            if (0xD800 <= code && code <= 0xDBFF) {
-                low = data.charCodeAt(this._position + 1);
-                if (isNaN(low)) {
-                    this._terminal.surrogate_high = ch;
-                    continue;
-                }
-                code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
-                ch += data.charAt(this._position + 1);
-            }
-            if (0xDC00 <= code && code <= 0xDFFF)
-                continue;
-            switch (this._state) {
-                case ParserState.NORMAL:
-                    if (ch in normalStateHandler) {
-                        normalStateHandler[ch](this, this._inputHandler);
-                    }
-                    else {
-                        this._inputHandler.addChar(ch, code);
-                    }
-                    break;
-                case ParserState.ESCAPED:
-                    if (ch in escapedStateHandler) {
-                        escapedStateHandler[ch](this, this._terminal);
-                        break;
-                    }
-                    switch (ch) {
-                        case '(':
-                        case ')':
-                        case '*':
-                        case '+':
-                        case '-':
-                        case '.':
-                            switch (ch) {
-                                case '(':
-                                    this._terminal.gcharset = 0;
-                                    break;
-                                case ')':
-                                    this._terminal.gcharset = 1;
-                                    break;
-                                case '*':
-                                    this._terminal.gcharset = 2;
-                                    break;
-                                case '+':
-                                    this._terminal.gcharset = 3;
-                                    break;
-                                case '-':
-                                    this._terminal.gcharset = 1;
-                                    break;
-                                case '.':
-                                    this._terminal.gcharset = 2;
-                                    break;
-                            }
-                            this._state = ParserState.CHARSET;
-                            break;
-                        case '/':
-                            this._terminal.gcharset = 3;
-                            this._state = ParserState.CHARSET;
-                            this._position--;
-                            break;
-                        case 'N':
-                            break;
-                        case 'O':
-                            break;
-                        case 'n':
-                            this._terminal.setgLevel(2);
-                            break;
-                        case 'o':
-                            this._terminal.setgLevel(3);
-                            break;
-                        case '|':
-                            this._terminal.setgLevel(3);
-                            break;
-                        case '}':
-                            this._terminal.setgLevel(2);
-                            break;
-                        case '~':
-                            this._terminal.setgLevel(1);
-                            break;
-                        case '7':
-                            this._inputHandler.saveCursor();
-                            this._state = ParserState.NORMAL;
-                            break;
-                        case '8':
-                            this._inputHandler.restoreCursor();
-                            this._state = ParserState.NORMAL;
-                            break;
-                        case '#':
-                            this._state = ParserState.NORMAL;
-                            this._position++;
-                            break;
-                        case 'H':
-                            this._terminal.tabSet();
-                            this._state = ParserState.NORMAL;
-                            break;
-                        case '=':
-                            this._terminal.log('Serial port requested application keypad.');
-                            this._terminal.applicationKeypad = true;
-                            this._terminal.viewport.syncScrollArea();
-                            this._state = ParserState.NORMAL;
-                            break;
-                        case '>':
-                            this._terminal.log('Switching back to normal keypad.');
-                            this._terminal.applicationKeypad = false;
-                            this._terminal.viewport.syncScrollArea();
-                            this._state = ParserState.NORMAL;
-                            break;
-                        default:
-                            this._state = ParserState.NORMAL;
-                            this._terminal.error('Unknown ESC control: %s.', ch);
-                            break;
-                    }
-                    break;
-                case ParserState.CHARSET:
-                    if (ch in Charsets_1.CHARSETS) {
-                        cs = Charsets_1.CHARSETS[ch];
-                        if (ch === '/') {
-                            this.skipNextChar();
-                        }
-                    }
-                    else {
-                        cs = Charsets_1.DEFAULT_CHARSET;
-                    }
-                    this._terminal.setgCharset(this._terminal.gcharset, cs);
-                    this._terminal.gcharset = null;
-                    this._state = ParserState.NORMAL;
-                    break;
-                case ParserState.OSC:
-                    if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) {
-                        if (ch === EscapeSequences_1.C0.ESC)
-                            this._position++;
-                        this._terminal.params.push(this._terminal.currentParam);
-                        switch (this._terminal.params[0]) {
-                            case 0:
-                            case 1:
-                            case 2:
-                                if (this._terminal.params[1]) {
-                                    this._terminal.title = this._terminal.params[1];
-                                    this._terminal.handleTitle(this._terminal.title);
-                                }
-                                break;
-                            case 3:
-                                break;
-                            case 4:
-                            case 5:
-                                break;
-                            case 10:
-                            case 11:
-                            case 12:
-                            case 13:
-                            case 14:
-                            case 15:
-                            case 16:
-                            case 17:
-                            case 18:
-                            case 19:
-                                break;
-                            case 46:
-                                break;
-                            case 50:
-                                break;
-                            case 51:
-                                break;
-                            case 52:
-                                break;
-                            case 104:
-                            case 105:
-                            case 110:
-                            case 111:
-                            case 112:
-                            case 113:
-                            case 114:
-                            case 115:
-                            case 116:
-                            case 117:
-                            case 118:
-                                break;
-                        }
-                        this._terminal.params = [];
-                        this._terminal.currentParam = 0;
-                        this._state = ParserState.NORMAL;
-                    }
-                    else {
-                        if (!this._terminal.params.length) {
-                            if (ch >= '0' && ch <= '9') {
-                                this._terminal.currentParam =
-                                    this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;
-                            }
-                            else if (ch === ';') {
-                                this._terminal.params.push(this._terminal.currentParam);
-                                this._terminal.currentParam = '';
-                            }
-                        }
-                        else {
-                            this._terminal.currentParam += ch;
-                        }
-                    }
-                    break;
-                case ParserState.CSI_PARAM:
-                    if (ch in csiParamStateHandler) {
-                        csiParamStateHandler[ch](this);
-                        break;
-                    }
-                    this.finalizeParam();
-                    this._state = ParserState.CSI;
-                case ParserState.CSI:
-                    if (ch in csiStateHandler) {
-                        csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);
-                    }
-                    else {
-                        this._terminal.error('Unknown CSI code: %s.', ch);
-                    }
-                    this._state = ParserState.NORMAL;
-                    this._terminal.prefix = '';
-                    this._terminal.postfix = '';
-                    break;
-                case ParserState.DCS:
-                    if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) {
-                        if (ch === EscapeSequences_1.C0.ESC)
-                            this._position++;
-                        var pt = void 0;
-                        var valid = void 0;
-                        switch (this._terminal.prefix) {
-                            case '':
-                                break;
-                            case '$q':
-                                pt = this._terminal.currentParam;
-                                valid = false;
-                                switch (pt) {
-                                    case '"q':
-                                        pt = '0"q';
-                                        break;
-                                    case '"p':
-                                        pt = '61"p';
-                                        break;
-                                    case 'r':
-                                        pt = ''
-                                            + (this._terminal.scrollTop + 1)
-                                            + ';'
-                                            + (this._terminal.scrollBottom + 1)
-                                            + 'r';
-                                        break;
-                                    case 'm':
-                                        pt = '0m';
-                                        break;
-                                    default:
-                                        this._terminal.error('Unknown DCS Pt: %s.', pt);
-                                        pt = '';
-                                        break;
-                                }
-                                this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '$r' + pt + EscapeSequences_1.C0.ESC + '\\');
-                                break;
-                            case '+p':
-                                break;
-                            case '+q':
-                                pt = this._terminal.currentParam;
-                                valid = false;
-                                this._terminal.send(EscapeSequences_1.C0.ESC + 'P' + +valid + '+r' + pt + EscapeSequences_1.C0.ESC + '\\');
-                                break;
-                            default:
-                                this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);
-                                break;
-                        }
-                        this._terminal.currentParam = 0;
-                        this._terminal.prefix = '';
-                        this._state = ParserState.NORMAL;
-                    }
-                    else if (!this._terminal.currentParam) {
-                        if (!this._terminal.prefix && ch !== '$' && ch !== '+') {
-                            this._terminal.currentParam = ch;
-                        }
-                        else if (this._terminal.prefix.length === 2) {
-                            this._terminal.currentParam = ch;
-                        }
-                        else {
-                            this._terminal.prefix += ch;
-                        }
-                    }
-                    else {
-                        this._terminal.currentParam += ch;
-                    }
-                    break;
-                case ParserState.IGNORE:
-                    if (ch === EscapeSequences_1.C0.ESC || ch === EscapeSequences_1.C0.BEL) {
-                        if (ch === EscapeSequences_1.C0.ESC)
-                            this._position++;
-                        this._state = ParserState.NORMAL;
-                    }
-                    break;
-            }
-        }
-        return this._state;
-    };
-    Parser.prototype.setState = function (state) {
-        this._state = state;
-    };
-    Parser.prototype.setPrefix = function (prefix) {
-        this._terminal.prefix = prefix;
-    };
-    Parser.prototype.setPostfix = function (postfix) {
-        this._terminal.postfix = postfix;
-    };
-    Parser.prototype.setParam = function (param) {
-        this._terminal.currentParam = param;
-    };
-    Parser.prototype.getParam = function () {
-        return this._terminal.currentParam;
-    };
-    Parser.prototype.finalizeParam = function () {
-        this._terminal.params.push(this._terminal.currentParam);
-        this._terminal.currentParam = 0;
-    };
-    Parser.prototype.skipNextChar = function () {
-        this._position++;
-    };
-    return Parser;
-}());
-exports.Parser = Parser;
-
-
-
-},{"./Charsets":1,"./EscapeSequences":3}],8:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var DomElementObjectPool_1 = require("./utils/DomElementObjectPool");
-var MAX_REFRESH_FRAME_SKIP = 5;
-var FLAGS;
-(function (FLAGS) {
-    FLAGS[FLAGS["BOLD"] = 1] = "BOLD";
-    FLAGS[FLAGS["UNDERLINE"] = 2] = "UNDERLINE";
-    FLAGS[FLAGS["BLINK"] = 4] = "BLINK";
-    FLAGS[FLAGS["INVERSE"] = 8] = "INVERSE";
-    FLAGS[FLAGS["INVISIBLE"] = 16] = "INVISIBLE";
-})(FLAGS || (FLAGS = {}));
-;
-var brokenBold = null;
-var Renderer = (function () {
-    function Renderer(_terminal) {
-        this._terminal = _terminal;
-        this._refreshRowsQueue = [];
-        this._refreshFramesSkipped = 0;
-        this._refreshAnimationFrame = null;
-        this._spanElementObjectPool = new DomElementObjectPool_1.DomElementObjectPool('span');
-        if (brokenBold === null) {
-            brokenBold = checkBoldBroken(this._terminal.element);
-        }
-        this._spanElementObjectPool = new DomElementObjectPool_1.DomElementObjectPool('span');
-    }
-    Renderer.prototype.queueRefresh = function (start, end) {
-        this._refreshRowsQueue.push({ start: start, end: end });
-        if (!this._refreshAnimationFrame) {
-            this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));
-        }
-    };
-    Renderer.prototype._refreshLoop = function () {
-        var skipFrame = this._terminal.writeBuffer.length > 0 && this._refreshFramesSkipped++ <= MAX_REFRESH_FRAME_SKIP;
-        if (skipFrame) {
-            this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));
-            return;
-        }
-        this._refreshFramesSkipped = 0;
-        var start;
-        var end;
-        if (this._refreshRowsQueue.length > 4) {
-            start = 0;
-            end = this._terminal.rows - 1;
-        }
-        else {
-            start = this._refreshRowsQueue[0].start;
-            end = this._refreshRowsQueue[0].end;
-            for (var i = 1; i < this._refreshRowsQueue.length; i++) {
-                if (this._refreshRowsQueue[i].start < start) {
-                    start = this._refreshRowsQueue[i].start;
-                }
-                if (this._refreshRowsQueue[i].end > end) {
-                    end = this._refreshRowsQueue[i].end;
-                }
-            }
-        }
-        this._refreshRowsQueue = [];
-        this._refreshAnimationFrame = null;
-        this._refresh(start, end);
-    };
-    Renderer.prototype._refresh = function (start, end) {
-        var parent;
-        if (end - start >= this._terminal.rows / 2) {
-            parent = this._terminal.element.parentNode;
-            if (parent) {
-                this._terminal.element.removeChild(this._terminal.rowContainer);
-            }
-        }
-        var width = this._terminal.cols;
-        var y = start;
-        if (end >= this._terminal.rows) {
-            this._terminal.log('`end` is too large. Most likely a bad CSR.');
-            end = this._terminal.rows - 1;
-        }
-        for (; y <= end; y++) {
-            var row = y + this._terminal.ydisp;
-            var line = this._terminal.lines.get(row);
-            var x = void 0;
-            if (this._terminal.y === y - (this._terminal.ybase - this._terminal.ydisp) &&
-                this._terminal.cursorState &&
-                !this._terminal.cursorHidden) {
-                x = this._terminal.x;
-            }
-            else {
-                x = -1;
-            }
-            var attr = this._terminal.defAttr;
-            var documentFragment = document.createDocumentFragment();
-            var innerHTML = '';
-            var currentElement = void 0;
-            while (this._terminal.children[y].children.length) {
-                var child = this._terminal.children[y].children[0];
-                this._terminal.children[y].removeChild(child);
-                this._spanElementObjectPool.release(child);
-            }
-            for (var i = 0; i < width; i++) {
-                var data = line[i][0];
-                var ch = line[i][1];
-                var ch_width = line[i][2];
-                if (!ch_width) {
-                    continue;
-                }
-                if (i === x) {
-                    data = -1;
-                }
-                if (data !== attr) {
-                    if (attr !== this._terminal.defAttr) {
-                        if (innerHTML) {
-                            currentElement.innerHTML = innerHTML;
-                            innerHTML = '';
-                        }
-                        documentFragment.appendChild(currentElement);
-                        currentElement = null;
-                    }
-                    if (data !== this._terminal.defAttr) {
-                        if (innerHTML && !currentElement) {
-                            currentElement = this._spanElementObjectPool.acquire();
-                        }
-                        if (currentElement) {
-                            if (innerHTML) {
-                                currentElement.innerHTML = innerHTML;
-                                innerHTML = '';
-                            }
-                            documentFragment.appendChild(currentElement);
-                        }
-                        currentElement = this._spanElementObjectPool.acquire();
-                        if (data === -1) {
-                            currentElement.classList.add('reverse-video', 'terminal-cursor');
-                        }
-                        else {
-                            var bg = data & 0x1ff;
-                            var fg = (data >> 9) & 0x1ff;
-                            var flags = data >> 18;
-                            if (flags & FLAGS.BOLD) {
-                                if (!brokenBold) {
-                                    currentElement.classList.add('xterm-bold');
-                                }
-                                if (fg < 8) {
-                                    fg += 8;
-                                }
-                            }
-                            if (flags & FLAGS.UNDERLINE) {
-                                currentElement.classList.add('xterm-underline');
-                            }
-                            if (flags & FLAGS.BLINK) {
-                                currentElement.classList.add('xterm-blink');
-                            }
-                            if (flags & FLAGS.INVERSE) {
-                                var temp = bg;
-                                bg = fg;
-                                fg = temp;
-                                if ((flags & 1) && fg < 8) {
-                                    fg += 8;
-                                }
-                            }
-                            if (flags & FLAGS.INVISIBLE) {
-                                currentElement.classList.add('xterm-hidden');
-                            }
-                            if (flags & FLAGS.INVERSE) {
-                                if (bg === 257) {
-                                    bg = 15;
-                                }
-                                if (fg === 256) {
-                                    fg = 0;
-                                }
-                            }
-                            if (bg < 256) {
-                                currentElement.classList.add("xterm-bg-color-" + bg);
-                            }
-                            if (fg < 256) {
-                                currentElement.classList.add("xterm-color-" + fg);
-                            }
-                        }
-                    }
-                }
-                if (ch_width === 2) {
-                    innerHTML += "<span class=\"xterm-wide-char\">" + ch + "</span>";
-                }
-                else if (ch.charCodeAt(0) > 255) {
-                    innerHTML += "<span class=\"xterm-normal-char\">" + ch + "</span>";
-                }
-                else {
-                    switch (ch) {
-                        case '&':
-                            innerHTML += '&amp;';
-                            break;
-                        case '<':
-                            innerHTML += '&lt;';
-                            break;
-                        case '>':
-                            innerHTML += '&gt;';
-                            break;
-                        default:
-                            if (ch <= ' ') {
-                                innerHTML += '&nbsp;';
-                            }
-                            else {
-                                innerHTML += ch;
-                            }
-                            break;
-                    }
-                }
-                attr = data;
-            }
-            if (innerHTML && !currentElement) {
-                currentElement = this._spanElementObjectPool.acquire();
-            }
-            if (currentElement) {
-                if (innerHTML) {
-                    currentElement.innerHTML = innerHTML;
-                    innerHTML = '';
-                }
-                documentFragment.appendChild(currentElement);
-                currentElement = null;
-            }
-            this._terminal.children[y].appendChild(documentFragment);
-        }
-        if (parent) {
-            this._terminal.element.appendChild(this._terminal.rowContainer);
-        }
-        this._terminal.emit('refresh', { element: this._terminal.element, start: start, end: end });
-    };
-    ;
-    return Renderer;
-}());
-exports.Renderer = Renderer;
-function checkBoldBroken(terminal) {
-    var document = terminal.ownerDocument;
-    var el = document.createElement('span');
-    el.innerHTML = 'hello world';
-    terminal.appendChild(el);
-    var w1 = el.offsetWidth;
-    var h1 = el.offsetHeight;
-    el.style.fontWeight = 'bold';
-    var w2 = el.offsetWidth;
-    var h2 = el.offsetHeight;
-    terminal.removeChild(el);
-    return w1 !== w2 || h1 !== h2;
-}
-
-
-
-},{"./utils/DomElementObjectPool":14}],9:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var Viewport = (function () {
-    function Viewport(terminal, viewportElement, scrollArea, charMeasure) {
-        var _this = this;
-        this.terminal = terminal;
-        this.viewportElement = viewportElement;
-        this.scrollArea = scrollArea;
-        this.charMeasure = charMeasure;
-        this.currentRowHeight = 0;
-        this.lastRecordedBufferLength = 0;
-        this.lastRecordedViewportHeight = 0;
-        this.terminal.on('scroll', this.syncScrollArea.bind(this));
-        this.terminal.on('resize', this.syncScrollArea.bind(this));
-        this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));
-        setTimeout(function () { return _this.syncScrollArea(); }, 0);
-    }
-    Viewport.prototype.refresh = function () {
-        if (this.charMeasure.height > 0) {
-            var rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;
-            if (rowHeightChanged) {
-                this.currentRowHeight = this.charMeasure.height;
-                this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';
-                this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';
-            }
-            var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;
-            if (rowHeightChanged || viewportHeightChanged) {
-                this.lastRecordedViewportHeight = this.terminal.rows;
-                this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';
-            }
-            this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';
-        }
-    };
-    Viewport.prototype.syncScrollArea = function () {
-        if (this.lastRecordedBufferLength !== this.terminal.lines.length) {
-            this.lastRecordedBufferLength = this.terminal.lines.length;
-            this.refresh();
-        }
-        else if (this.lastRecordedViewportHeight !== this.terminal.rows) {
-            this.refresh();
-        }
-        else {
-            if (this.charMeasure.height !== this.currentRowHeight) {
-                this.refresh();
-            }
-        }
-        var scrollTop = this.terminal.ydisp * this.currentRowHeight;
-        if (this.viewportElement.scrollTop !== scrollTop) {
-            this.viewportElement.scrollTop = scrollTop;
-        }
-    };
-    Viewport.prototype.onScroll = function (ev) {
-        var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);
-        var diff = newRow - this.terminal.ydisp;
-        this.terminal.scrollDisp(diff, true);
-    };
-    Viewport.prototype.onWheel = function (ev) {
-        if (ev.deltaY === 0) {
-            return;
-        }
-        var multiplier = 1;
-        if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
-            multiplier = this.currentRowHeight;
-        }
-        else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
-            multiplier = this.currentRowHeight * this.terminal.rows;
-        }
-        this.viewportElement.scrollTop += ev.deltaY * multiplier;
-        ev.preventDefault();
-    };
-    ;
-    return Viewport;
-}());
-exports.Viewport = Viewport;
-
-
-
-},{}],10:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-function prepareTextForClipboard(text) {
-    var space = String.fromCharCode(32), nonBreakingSpace = String.fromCharCode(160), allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'), processedText = text.split('\n').map(function (line) {
-        var processedLine = line.replace(/\s+$/g, '').replace(allNonBreakingSpaces, space);
-        return processedLine;
-    }).join('\n');
-    return processedText;
-}
-exports.prepareTextForClipboard = prepareTextForClipboard;
-function prepareTextForTerminal(text, isMSWindows) {
-    if (isMSWindows) {
-        return text.replace(/\r?\n/g, '\n');
-    }
-    return text;
-}
-exports.prepareTextForTerminal = prepareTextForTerminal;
-function copyHandler(ev, term) {
-    var copiedText = window.getSelection().toString(), text = prepareTextForClipboard(copiedText);
-    if (term.browser.isMSIE) {
-        window.clipboardData.setData('Text', text);
-    }
-    else {
-        ev.clipboardData.setData('text/plain', text);
-    }
-    ev.preventDefault();
-}
-exports.copyHandler = copyHandler;
-function pasteHandler(ev, term) {
-    ev.stopPropagation();
-    var text;
-    var dispatchPaste = function (text) {
-        text = prepareTextForTerminal(text, term.browser.isMSWindows);
-        term.handler(text);
-        term.textarea.value = '';
-        term.emit('paste', text);
-        return term.cancel(ev);
-    };
-    if (term.browser.isMSIE) {
-        if (window.clipboardData) {
-            text = window.clipboardData.getData('Text');
-            dispatchPaste(text);
-        }
-    }
-    else {
-        if (ev.clipboardData) {
-            text = ev.clipboardData.getData('text/plain');
-            dispatchPaste(text);
-        }
-    }
-}
-exports.pasteHandler = pasteHandler;
-function rightClickHandler(ev, term) {
-    var s = document.getSelection(), selectedText = prepareTextForClipboard(s.toString()), clickIsOnSelection = false, x = ev.clientX, y = ev.clientY;
-    if (s.rangeCount) {
-        var r = s.getRangeAt(0), cr = r.getClientRects();
-        for (var i = 0; i < cr.length; i++) {
-            var rect = cr[i];
-            clickIsOnSelection = ((x > rect.left) && (x < rect.right) &&
-                (y > rect.top) && (y < rect.bottom));
-            if (clickIsOnSelection) {
-                break;
-            }
-        }
-        if (selectedText.match(/^\s$/) || !selectedText.length) {
-            clickIsOnSelection = false;
-        }
-    }
-    if (!clickIsOnSelection) {
-        term.textarea.style.position = 'fixed';
-        term.textarea.style.width = '20px';
-        term.textarea.style.height = '20px';
-        term.textarea.style.left = (x - 10) + 'px';
-        term.textarea.style.top = (y - 10) + 'px';
-        term.textarea.style.zIndex = '1000';
-        term.textarea.focus();
-        setTimeout(function () {
-            term.textarea.style.position = null;
-            term.textarea.style.width = null;
-            term.textarea.style.height = null;
-            term.textarea.style.left = null;
-            term.textarea.style.top = null;
-            term.textarea.style.zIndex = null;
-        }, 4);
-    }
-}
-exports.rightClickHandler = rightClickHandler;
-
-
-
-},{}],11:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var Generic_1 = require("./Generic");
-var isNode = (typeof navigator === 'undefined') ? true : false;
-var userAgent = (isNode) ? 'node' : navigator.userAgent;
-var platform = (isNode) ? 'node' : navigator.platform;
-exports.isFirefox = !!~userAgent.indexOf('Firefox');
-exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');
-exports.isMac = Generic_1.contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);
-exports.isIpad = platform === 'iPad';
-exports.isIphone = platform === 'iPhone';
-exports.isMSWindows = Generic_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);
-
-
-
-},{"./Generic":15}],12:[function(require,module,exports){
-"use strict";
-var __extends = (this && this.__extends) || (function () {
-    var extendStatics = Object.setPrototypeOf ||
-        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-    return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-    };
-})();
-Object.defineProperty(exports, "__esModule", { value: true });
-var EventEmitter_js_1 = require("../EventEmitter.js");
-var CharMeasure = (function (_super) {
-    __extends(CharMeasure, _super);
-    function CharMeasure(document, parentElement) {
-        var _this = _super.call(this) || this;
-        _this._document = document;
-        _this._parentElement = parentElement;
-        return _this;
-    }
-    Object.defineProperty(CharMeasure.prototype, "width", {
-        get: function () {
-            return this._width;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(CharMeasure.prototype, "height", {
-        get: function () {
-            return this._height;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    CharMeasure.prototype.measure = function () {
-        var _this = this;
-        if (!this._measureElement) {
-            this._measureElement = this._document.createElement('span');
-            this._measureElement.style.position = 'absolute';
-            this._measureElement.style.top = '0';
-            this._measureElement.style.left = '-9999em';
-            this._measureElement.textContent = 'W';
-            this._measureElement.setAttribute('aria-hidden', 'true');
-            this._parentElement.appendChild(this._measureElement);
-            setTimeout(function () { return _this._doMeasure(); }, 0);
-        }
-        else {
-            this._doMeasure();
-        }
-    };
-    CharMeasure.prototype._doMeasure = function () {
-        var geometry = this._measureElement.getBoundingClientRect();
-        if (geometry.width === 0 || geometry.height === 0) {
-            return;
-        }
-        if (this._width !== geometry.width || this._height !== geometry.height) {
-            this._width = geometry.width;
-            this._height = geometry.height;
-            this.emit('charsizechanged');
-        }
-    };
-    return CharMeasure;
-}(EventEmitter_js_1.EventEmitter));
-exports.CharMeasure = CharMeasure;
-
-
-
-},{"../EventEmitter.js":4}],13:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var CircularList = (function () {
-    function CircularList(maxLength) {
-        this._array = new Array(maxLength);
-        this._startIndex = 0;
-        this._length = 0;
-    }
-    Object.defineProperty(CircularList.prototype, "maxLength", {
-        get: function () {
-            return this._array.length;
-        },
-        set: function (newMaxLength) {
-            var newArray = new Array(newMaxLength);
-            for (var i = 0; i < Math.min(newMaxLength, this.length); i++) {
-                newArray[i] = this._array[this._getCyclicIndex(i)];
-            }
-            this._array = newArray;
-            this._startIndex = 0;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(CircularList.prototype, "length", {
-        get: function () {
-            return this._length;
-        },
-        set: function (newLength) {
-            if (newLength > this._length) {
-                for (var i = this._length; i < newLength; i++) {
-                    this._array[i] = undefined;
-                }
-            }
-            this._length = newLength;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(CircularList.prototype, "forEach", {
-        get: function () {
-            return this._array.forEach;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    CircularList.prototype.get = function (index) {
-        return this._array[this._getCyclicIndex(index)];
-    };
-    CircularList.prototype.set = function (index, value) {
-        this._array[this._getCyclicIndex(index)] = value;
-    };
-    CircularList.prototype.push = function (value) {
-        this._array[this._getCyclicIndex(this._length)] = value;
-        if (this._length === this.maxLength) {
-            this._startIndex++;
-            if (this._startIndex === this.maxLength) {
-                this._startIndex = 0;
-            }
-        }
-        else {
-            this._length++;
-        }
-    };
-    CircularList.prototype.pop = function () {
-        return this._array[this._getCyclicIndex(this._length-- - 1)];
-    };
-    CircularList.prototype.splice = function (start, deleteCount) {
-        var items = [];
-        for (var _i = 2; _i < arguments.length; _i++) {
-            items[_i - 2] = arguments[_i];
-        }
-        if (deleteCount) {
-            for (var i = start; i < this._length - deleteCount; i++) {
-                this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];
-            }
-            this._length -= deleteCount;
-        }
-        if (items && items.length) {
-            for (var i = this._length - 1; i >= start; i--) {
-                this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];
-            }
-            for (var i = 0; i < items.length; i++) {
-                this._array[this._getCyclicIndex(start + i)] = items[i];
-            }
-            if (this._length + items.length > this.maxLength) {
-                this._startIndex += (this._length + items.length) - this.maxLength;
-                this._length = this.maxLength;
-            }
-            else {
-                this._length += items.length;
-            }
-        }
-    };
-    CircularList.prototype.trimStart = function (count) {
-        if (count > this._length) {
-            count = this._length;
-        }
-        this._startIndex += count;
-        this._length -= count;
-    };
-    CircularList.prototype.shiftElements = function (start, count, offset) {
-        if (count <= 0) {
-            return;
-        }
-        if (start < 0 || start >= this._length) {
-            throw new Error('start argument out of range');
-        }
-        if (start + offset < 0) {
-            throw new Error('Cannot shift elements in list beyond index 0');
-        }
-        if (offset > 0) {
-            for (var i = count - 1; i >= 0; i--) {
-                this.set(start + i + offset, this.get(start + i));
-            }
-            var expandListBy = (start + count + offset) - this._length;
-            if (expandListBy > 0) {
-                this._length += expandListBy;
-                while (this._length > this.maxLength) {
-                    this._length--;
-                    this._startIndex++;
-                }
-            }
-        }
-        else {
-            for (var i = 0; i < count; i++) {
-                this.set(start + i + offset, this.get(start + i));
-            }
-        }
-    };
-    CircularList.prototype._getCyclicIndex = function (index) {
-        return (this._startIndex + index) % this.maxLength;
-    };
-    return CircularList;
-}());
-exports.CircularList = CircularList;
-
-
-
-},{}],14:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var DomElementObjectPool = (function () {
-    function DomElementObjectPool(type) {
-        this.type = type;
-        this._type = type;
-        this._pool = [];
-        this._inUse = {};
-    }
-    DomElementObjectPool.prototype.acquire = function () {
-        var element;
-        if (this._pool.length === 0) {
-            element = this._createNew();
-        }
-        else {
-            element = this._pool.pop();
-        }
-        this._inUse[element.getAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE)] = element;
-        return element;
-    };
-    DomElementObjectPool.prototype.release = function (element) {
-        if (!this._inUse[element.getAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE)]) {
-            throw new Error('Could not release an element not yet acquired');
-        }
-        delete this._inUse[element.getAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE)];
-        this._cleanElement(element);
-        this._pool.push(element);
-    };
-    DomElementObjectPool.prototype._createNew = function () {
-        var element = document.createElement(this._type);
-        var id = DomElementObjectPool._objectCount++;
-        element.setAttribute(DomElementObjectPool.OBJECT_ID_ATTRIBUTE, id.toString(10));
-        return element;
-    };
-    DomElementObjectPool.prototype._cleanElement = function (element) {
-        element.className = '';
-        element.innerHTML = '';
-    };
-    return DomElementObjectPool;
-}());
-DomElementObjectPool.OBJECT_ID_ATTRIBUTE = 'data-obj-id';
-DomElementObjectPool._objectCount = 0;
-exports.DomElementObjectPool = DomElementObjectPool;
-
-
-
-},{}],15:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-function contains(arr, el) {
-    return arr.indexOf(el) >= 0;
-}
-exports.contains = contains;
-;
-
-
-
-},{}],16:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-function getCoords(event, rowContainer, charMeasure) {
-    if (event.pageX == null) {
-        return null;
-    }
-    var x = event.pageX;
-    var y = event.pageY;
-    var el = rowContainer;
-    while (el && el !== self.document.documentElement) {
-        x -= el.offsetLeft;
-        y -= el.offsetTop;
-        el = 'offsetParent' in el ? el.offsetParent : el.parentElement;
-    }
-    x = Math.ceil(x / charMeasure.width);
-    y = Math.ceil(y / charMeasure.height);
-    return [x, y];
-}
-exports.getCoords = getCoords;
-function getRawByteCoords(event, rowContainer, charMeasure, colCount, rowCount) {
-    var coords = getCoords(event, rowContainer, charMeasure);
-    var x = coords[0];
-    var y = coords[1];
-    x = Math.min(Math.max(x, 0), colCount);
-    y = Math.min(Math.max(y, 0), rowCount);
-    x += 32;
-    y += 32;
-    return { x: x, y: y };
-}
-exports.getRawByteCoords = getRawByteCoords;
-
-
-
-},{}],17:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var CompositionHelper_1 = require("./CompositionHelper");
-var EventEmitter_1 = require("./EventEmitter");
-var Viewport_1 = require("./Viewport");
-var Clipboard_1 = require("./handlers/Clipboard");
-var CircularList_1 = require("./utils/CircularList");
-var EscapeSequences_1 = require("./EscapeSequences");
-var InputHandler_1 = require("./InputHandler");
-var Parser_1 = require("./Parser");
-var Renderer_1 = require("./Renderer");
-var Linkifier_1 = require("./Linkifier");
-var CharMeasure_1 = require("./utils/CharMeasure");
-var Browser = require("./utils/Browser");
-var Mouse_1 = require("./utils/Mouse");
-var document = (typeof window != 'undefined') ? window.document : null;
-var WRITE_BUFFER_PAUSE_THRESHOLD = 5;
-var WRITE_BATCH_SIZE = 300;
-var CURSOR_BLINK_INTERVAL = 600;
-function Terminal(options) {
-    var self = this;
-    if (!(this instanceof Terminal)) {
-        return new Terminal(arguments[0], arguments[1], arguments[2]);
-    }
-    self.browser = Browser;
-    self.cancel = Terminal.cancel;
-    EventEmitter_1.EventEmitter.call(this);
-    if (typeof options === 'number') {
-        options = {
-            cols: arguments[0],
-            rows: arguments[1],
-            handler: arguments[2]
-        };
-    }
-    options = options || {};
-    Object.keys(Terminal.defaults).forEach(function (key) {
-        if (options[key] == null) {
-            options[key] = Terminal.options[key];
-            if (Terminal[key] !== Terminal.defaults[key]) {
-                options[key] = Terminal[key];
-            }
-        }
-        self[key] = options[key];
-    });
-    if (options.colors.length === 8) {
-        options.colors = options.colors.concat(Terminal._colors.slice(8));
-    }
-    else if (options.colors.length === 16) {
-        options.colors = options.colors.concat(Terminal._colors.slice(16));
-    }
-    else if (options.colors.length === 10) {
-        options.colors = options.colors.slice(0, -2).concat(Terminal._colors.slice(8, -2), options.colors.slice(-2));
-    }
-    else if (options.colors.length === 18) {
-        options.colors = options.colors.concat(Terminal._colors.slice(16, -2), options.colors.slice(-2));
-    }
-    this.colors = options.colors;
-    this.options = options;
-    this.parent = options.body || options.parent || (document ? document.getElementsByTagName('body')[0] : null);
-    this.cols = options.cols || options.geometry[0];
-    this.rows = options.rows || options.geometry[1];
-    this.geometry = [this.cols, this.rows];
-    if (options.handler) {
-        this.on('data', options.handler);
-    }
-    this.ybase = 0;
-    this.ydisp = 0;
-    this.x = 0;
-    this.y = 0;
-    this.cursorState = 0;
-    this.cursorHidden = false;
-    this.convertEol;
-    this.queue = '';
-    this.scrollTop = 0;
-    this.scrollBottom = this.rows - 1;
-    this.customKeydownHandler = null;
-    this.cursorBlinkInterval = null;
-    this.applicationKeypad = false;
-    this.applicationCursor = false;
-    this.originMode = false;
-    this.insertMode = false;
-    this.wraparoundMode = true;
-    this.normal = null;
-    this.charset = null;
-    this.gcharset = null;
-    this.glevel = 0;
-    this.charsets = [null];
-    this.decLocator;
-    this.x10Mouse;
-    this.vt200Mouse;
-    this.vt300Mouse;
-    this.normalMouse;
-    this.mouseEvents;
-    this.sendFocus;
-    this.utfMouse;
-    this.sgrMouse;
-    this.urxvtMouse;
-    this.element;
-    this.children;
-    this.refreshStart;
-    this.refreshEnd;
-    this.savedX;
-    this.savedY;
-    this.savedCols;
-    this.readable = true;
-    this.writable = true;
-    this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
-    this.curAttr = this.defAttr;
-    this.params = [];
-    this.currentParam = 0;
-    this.prefix = '';
-    this.postfix = '';
-    this.inputHandler = new InputHandler_1.InputHandler(this);
-    this.parser = new Parser_1.Parser(this.inputHandler, this);
-    this.renderer = this.renderer || null;
-    this.linkifier = this.linkifier || new Linkifier_1.Linkifier();
-    this.writeBuffer = [];
-    this.writeInProgress = false;
-    this.xoffSentToCatchUp = false;
-    this.writeStopped = false;
-    this.surrogate_high = '';
-    this.lines = new CircularList_1.CircularList(this.scrollback);
-    var i = this.rows;
-    while (i--) {
-        this.lines.push(this.blankLine());
-    }
-    this.tabs;
-    this.setupStops();
-    this.userScrolling = false;
-}
-inherits(Terminal, EventEmitter_1.EventEmitter);
-Terminal.prototype.eraseAttr = function () {
-    return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
-};
-Terminal.tangoColors = [
-    '#2e3436',
-    '#cc0000',
-    '#4e9a06',
-    '#c4a000',
-    '#3465a4',
-    '#75507b',
-    '#06989a',
-    '#d3d7cf',
-    '#555753',
-    '#ef2929',
-    '#8ae234',
-    '#fce94f',
-    '#729fcf',
-    '#ad7fa8',
-    '#34e2e2',
-    '#eeeeec'
-];
-Terminal.colors = (function () {
-    var colors = Terminal.tangoColors.slice(), r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff], i;
-    i = 0;
-    for (; i < 216; i++) {
-        out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);
-    }
-    i = 0;
-    for (; i < 24; i++) {
-        r = 8 + i * 10;
-        out(r, r, r);
-    }
-    function out(r, g, b) {
-        colors.push('#' + hex(r) + hex(g) + hex(b));
-    }
-    function hex(c) {
-        c = c.toString(16);
-        return c.length < 2 ? '0' + c : c;
-    }
-    return colors;
-})();
-Terminal._colors = Terminal.colors.slice();
-Terminal.vcolors = (function () {
-    var out = [], colors = Terminal.colors, i = 0, color;
-    for (; i < 256; i++) {
-        color = parseInt(colors[i].substring(1), 16);
-        out.push([
-            (color >> 16) & 0xff,
-            (color >> 8) & 0xff,
-            color & 0xff
-        ]);
-    }
-    return out;
-})();
-Terminal.defaults = {
-    colors: Terminal.colors,
-    theme: 'default',
-    convertEol: false,
-    termName: 'xterm',
-    geometry: [80, 24],
-    cursorBlink: false,
-    cursorStyle: 'block',
-    visualBell: false,
-    popOnBell: false,
-    scrollback: 1000,
-    screenKeys: false,
-    debug: false,
-    cancelEvents: false,
-    disableStdin: false,
-    useFlowControl: false,
-    tabStopWidth: 8
-};
-Terminal.options = {};
-Terminal.focus = null;
-each(keys(Terminal.defaults), function (key) {
-    Terminal[key] = Terminal.defaults[key];
-    Terminal.options[key] = Terminal.defaults[key];
-});
-Terminal.prototype.focus = function () {
-    return this.textarea.focus();
-};
-Terminal.prototype.getOption = function (key, value) {
-    if (!(key in Terminal.defaults)) {
-        throw new Error('No option with key "' + key + '"');
-    }
-    if (typeof this.options[key] !== 'undefined') {
-        return this.options[key];
-    }
-    return this[key];
-};
-Terminal.prototype.setOption = function (key, value) {
-    if (!(key in Terminal.defaults)) {
-        throw new Error('No option with key "' + key + '"');
-    }
-    switch (key) {
-        case 'scrollback':
-            if (this.options[key] !== value) {
-                if (this.lines.length > value) {
-                    var amountToTrim = this.lines.length - value;
-                    var needsRefresh = (this.ydisp - amountToTrim < 0);
-                    this.lines.trimStart(amountToTrim);
-                    this.ybase = Math.max(this.ybase - amountToTrim, 0);
-                    this.ydisp = Math.max(this.ydisp - amountToTrim, 0);
-                    if (needsRefresh) {
-                        this.refresh(0, this.rows - 1);
-                    }
-                }
-                this.lines.maxLength = value;
-                this.viewport.syncScrollArea();
-            }
-            break;
-    }
-    this[key] = value;
-    this.options[key] = value;
-    switch (key) {
-        case 'cursorBlink':
-            this.setCursorBlinking(value);
-            break;
-        case 'cursorStyle':
-            this.element.classList.toggle("xterm-cursor-style-underline", value === 'underline');
-            this.element.classList.toggle("xterm-cursor-style-bar", value === 'bar');
-            break;
-        case 'tabStopWidth':
-            this.setupStops();
-            break;
-    }
-};
-Terminal.prototype.restartCursorBlinking = function () {
-    this.setCursorBlinking(this.options.cursorBlink);
-};
-Terminal.prototype.setCursorBlinking = function (enabled) {
-    this.element.classList.toggle('xterm-cursor-blink', enabled);
-    this.clearCursorBlinkingInterval();
-    if (enabled) {
-        var self = this;
-        this.cursorBlinkInterval = setInterval(function () {
-            self.element.classList.toggle('xterm-cursor-blink-on');
-        }, CURSOR_BLINK_INTERVAL);
-    }
-};
-Terminal.prototype.clearCursorBlinkingInterval = function () {
-    this.element.classList.remove('xterm-cursor-blink-on');
-    if (this.cursorBlinkInterval) {
-        clearInterval(this.cursorBlinkInterval);
-        this.cursorBlinkInterval = null;
-    }
-};
-Terminal.bindFocus = function (term) {
-    on(term.textarea, 'focus', function (ev) {
-        if (term.sendFocus) {
-            term.send(EscapeSequences_1.C0.ESC + '[I');
-        }
-        term.element.classList.add('focus');
-        term.showCursor();
-        term.restartCursorBlinking.apply(term);
-        Terminal.focus = term;
-        term.emit('focus', { terminal: term });
-    });
-};
-Terminal.prototype.blur = function () {
-    return this.textarea.blur();
-};
-Terminal.bindBlur = function (term) {
-    on(term.textarea, 'blur', function (ev) {
-        term.refresh(term.y, term.y);
-        if (term.sendFocus) {
-            term.send(EscapeSequences_1.C0.ESC + '[O');
-        }
-        term.element.classList.remove('focus');
-        term.clearCursorBlinkingInterval.apply(term);
-        Terminal.focus = null;
-        term.emit('blur', { terminal: term });
-    });
-};
-Terminal.prototype.initGlobal = function () {
-    var term = this;
-    Terminal.bindKeys(this);
-    Terminal.bindFocus(this);
-    Terminal.bindBlur(this);
-    on(this.element, 'copy', function (ev) {
-        Clipboard_1.copyHandler.call(this, ev, term);
-    });
-    on(this.textarea, 'paste', function (ev) {
-        Clipboard_1.pasteHandler.call(this, ev, term);
-    });
-    on(this.element, 'paste', function (ev) {
-        Clipboard_1.pasteHandler.call(this, ev, term);
-    });
-    function rightClickHandlerWrapper(ev) {
-        Clipboard_1.rightClickHandler.call(this, ev, term);
-    }
-    if (term.browser.isFirefox) {
-        on(this.element, 'mousedown', function (ev) {
-            if (ev.button == 2) {
-                rightClickHandlerWrapper(ev);
-            }
-        });
-    }
-    else {
-        on(this.element, 'contextmenu', rightClickHandlerWrapper);
-    }
-};
-Terminal.bindKeys = function (term) {
-    on(term.element, 'keydown', function (ev) {
-        if (document.activeElement != this) {
-            return;
-        }
-        term.keyDown(ev);
-    }, true);
-    on(term.element, 'keypress', function (ev) {
-        if (document.activeElement != this) {
-            return;
-        }
-        term.keyPress(ev);
-    }, true);
-    on(term.element, 'keyup', function (ev) {
-        if (!wasMondifierKeyOnlyEvent(ev)) {
-            term.focus(term);
-        }
-    }, true);
-    on(term.textarea, 'keydown', function (ev) {
-        term.keyDown(ev);
-    }, true);
-    on(term.textarea, 'keypress', function (ev) {
-        term.keyPress(ev);
-        this.value = '';
-    }, true);
-    on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper));
-    on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper));
-    on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper));
-    term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper));
-    term.on('refresh', function (data) {
-        term.queueLinkification(data.start, data.end);
-    });
-};
-Terminal.prototype.insertRow = function (row) {
-    if (typeof row != 'object') {
-        row = document.createElement('div');
-    }
-    this.rowContainer.appendChild(row);
-    this.children.push(row);
-    return row;
-};
-Terminal.prototype.open = function (parent, focus) {
-    var self = this, i = 0, div;
-    this.parent = parent || this.parent;
-    if (!this.parent) {
-        throw new Error('Terminal requires a parent element.');
-    }
-    this.context = this.parent.ownerDocument.defaultView;
-    this.document = this.parent.ownerDocument;
-    this.body = this.document.getElementsByTagName('body')[0];
-    this.element = this.document.createElement('div');
-    this.element.classList.add('terminal');
-    this.element.classList.add('xterm');
-    this.element.classList.add('xterm-theme-' + this.theme);
-    this.setCursorBlinking(this.options.cursorBlink);
-    this.element.style.height;
-    this.element.setAttribute('tabindex', 0);
-    this.viewportElement = document.createElement('div');
-    this.viewportElement.classList.add('xterm-viewport');
-    this.element.appendChild(this.viewportElement);
-    this.viewportScrollArea = document.createElement('div');
-    this.viewportScrollArea.classList.add('xterm-scroll-area');
-    this.viewportElement.appendChild(this.viewportScrollArea);
-    this.rowContainer = document.createElement('div');
-    this.rowContainer.classList.add('xterm-rows');
-    this.element.appendChild(this.rowContainer);
-    this.children = [];
-    this.linkifier.attachToDom(document, this.children);
-    this.helperContainer = document.createElement('div');
-    this.helperContainer.classList.add('xterm-helpers');
-    this.element.appendChild(this.helperContainer);
-    this.textarea = document.createElement('textarea');
-    this.textarea.classList.add('xterm-helper-textarea');
-    this.textarea.setAttribute('autocorrect', 'off');
-    this.textarea.setAttribute('autocapitalize', 'off');
-    this.textarea.setAttribute('spellcheck', 'false');
-    this.textarea.tabIndex = 0;
-    this.textarea.addEventListener('focus', function () {
-        self.emit('focus', { terminal: self });
-    });
-    this.textarea.addEventListener('blur', function () {
-        self.emit('blur', { terminal: self });
-    });
-    this.helperContainer.appendChild(this.textarea);
-    this.compositionView = document.createElement('div');
-    this.compositionView.classList.add('composition-view');
-    this.compositionHelper = new CompositionHelper_1.CompositionHelper(this.textarea, this.compositionView, this);
-    this.helperContainer.appendChild(this.compositionView);
-    this.charSizeStyleElement = document.createElement('style');
-    this.helperContainer.appendChild(this.charSizeStyleElement);
-    for (; i < this.rows; i++) {
-        this.insertRow();
-    }
-    this.parent.appendChild(this.element);
-    this.charMeasure = new CharMeasure_1.CharMeasure(document, this.helperContainer);
-    this.charMeasure.on('charsizechanged', function () {
-        self.updateCharSizeCSS();
-    });
-    this.charMeasure.measure();
-    this.viewport = new Viewport_1.Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);
-    this.renderer = new Renderer_1.Renderer(this);
-    this.refresh(0, this.rows - 1);
-    this.initGlobal();
-    if (typeof focus == 'undefined') {
-        var message = 'You did not pass the `focus` argument in `Terminal.prototype.open()`.\n';
-        message += 'The `focus` argument now defaults to `true` but starting with xterm.js 3.0 ';
-        message += 'it will default to `false`.';
-        console.warn(message);
-        focus = true;
-    }
-    if (focus) {
-        this.focus();
-    }
-    on(this.element, 'click', function () {
-        var selection = document.getSelection(), collapsed = selection.isCollapsed, isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range';
-        if (!isRange) {
-            self.focus();
-        }
-    });
-    this.bindMouse();
-    this.emit('open');
-};
-Terminal.loadAddon = function (addon, callback) {
-    if (typeof exports === 'object' && typeof module === 'object') {
-        return require('./addons/' + addon + '/' + addon);
-    }
-    else if (typeof define == 'function') {
-        return require(['./addons/' + addon + '/' + addon], callback);
-    }
-    else {
-        console.error('Cannot load a module without a CommonJS or RequireJS environment.');
-        return false;
-    }
-};
-Terminal.prototype.updateCharSizeCSS = function () {
-    this.charSizeStyleElement.textContent =
-        ".xterm-wide-char{width:" + this.charMeasure.width * 2 + "px;}" +
-            (".xterm-normal-char{width:" + this.charMeasure.width + "px;}");
-};
-Terminal.prototype.bindMouse = function () {
-    var el = this.element, self = this, pressed = 32;
-    function sendButton(ev) {
-        var button, pos;
-        button = getButton(ev);
-        pos = Mouse_1.getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows);
-        if (!pos)
-            return;
-        sendEvent(button, pos);
-        switch (ev.overrideType || ev.type) {
-            case 'mousedown':
-                pressed = button;
-                break;
-            case 'mouseup':
-                pressed = 32;
-                break;
-            case 'wheel':
-                break;
-        }
-    }
-    function sendMove(ev) {
-        var button = pressed, pos;
-        pos = Mouse_1.getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows);
-        if (!pos)
-            return;
-        button += 32;
-        sendEvent(button, pos);
-    }
-    function encode(data, ch) {
-        if (!self.utfMouse) {
-            if (ch === 255)
-                return data.push(0);
-            if (ch > 127)
-                ch = 127;
-            data.push(ch);
-        }
-        else {
-            if (ch === 2047)
-                return data.push(0);
-            if (ch < 127) {
-                data.push(ch);
-            }
-            else {
-                if (ch > 2047)
-                    ch = 2047;
-                data.push(0xC0 | (ch >> 6));
-                data.push(0x80 | (ch & 0x3F));
-            }
-        }
-    }
-    function sendEvent(button, pos) {
-        if (self.vt300Mouse) {
-            button &= 3;
-            pos.x -= 32;
-            pos.y -= 32;
-            var data = EscapeSequences_1.C0.ESC + '[24';
-            if (button === 0)
-                data += '1';
-            else if (button === 1)
-                data += '3';
-            else if (button === 2)
-                data += '5';
-            else if (button === 3)
-                return;
-            else
-                data += '0';
-            data += '~[' + pos.x + ',' + pos.y + ']\r';
-            self.send(data);
-            return;
-        }
-        if (self.decLocator) {
-            button &= 3;
-            pos.x -= 32;
-            pos.y -= 32;
-            if (button === 0)
-                button = 2;
-            else if (button === 1)
-                button = 4;
-            else if (button === 2)
-                button = 6;
-            else if (button === 3)
-                button = 3;
-            self.send(EscapeSequences_1.C0.ESC + '['
-                + button
-                + ';'
-                + (button === 3 ? 4 : 0)
-                + ';'
-                + pos.y
-                + ';'
-                + pos.x
-                + ';'
-                + (pos.page || 0)
-                + '&w');
-            return;
-        }
-        if (self.urxvtMouse) {
-            pos.x -= 32;
-            pos.y -= 32;
-            pos.x++;
-            pos.y++;
-            self.send(EscapeSequences_1.C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');
-            return;
-        }
-        if (self.sgrMouse) {
-            pos.x -= 32;
-            pos.y -= 32;
-            self.send(EscapeSequences_1.C0.ESC + '[<'
-                + (((button & 3) === 3 ? button & ~3 : button) - 32)
-                + ';'
-                + pos.x
-                + ';'
-                + pos.y
-                + ((button & 3) === 3 ? 'm' : 'M'));
-            return;
-        }
-        var data = [];
-        encode(data, button);
-        encode(data, pos.x);
-        encode(data, pos.y);
-        self.send(EscapeSequences_1.C0.ESC + '[M' + String.fromCharCode.apply(String, data));
-    }
-    function getButton(ev) {
-        var button, shift, meta, ctrl, mod;
-        switch (ev.overrideType || ev.type) {
-            case 'mousedown':
-                button = ev.button != null
-                    ? +ev.button
-                    : ev.which != null
-                        ? ev.which - 1
-                        : null;
-                if (self.browser.isMSIE) {
-                    button = button === 1 ? 0 : button === 4 ? 1 : button;
-                }
-                break;
-            case 'mouseup':
-                button = 3;
-                break;
-            case 'DOMMouseScroll':
-                button = ev.detail < 0
-                    ? 64
-                    : 65;
-                break;
-            case 'wheel':
-                button = ev.wheelDeltaY > 0
-                    ? 64
-                    : 65;
-                break;
-        }
-        shift = ev.shiftKey ? 4 : 0;
-        meta = ev.metaKey ? 8 : 0;
-        ctrl = ev.ctrlKey ? 16 : 0;
-        mod = shift | meta | ctrl;
-        if (self.vt200Mouse) {
-            mod &= ctrl;
-        }
-        else if (!self.normalMouse) {
-            mod = 0;
-        }
-        button = (32 + (mod << 2)) + button;
-        return button;
-    }
-    on(el, 'mousedown', function (ev) {
-        if (!self.mouseEvents)
-            return;
-        sendButton(ev);
-        self.focus();
-        if (self.vt200Mouse) {
-            ev.overrideType = 'mouseup';
-            sendButton(ev);
-            return self.cancel(ev);
-        }
-        if (self.normalMouse)
-            on(self.document, 'mousemove', sendMove);
-        if (!self.x10Mouse) {
-            on(self.document, 'mouseup', function up(ev) {
-                sendButton(ev);
-                if (self.normalMouse)
-                    off(self.document, 'mousemove', sendMove);
-                off(self.document, 'mouseup', up);
-                return self.cancel(ev);
-            });
-        }
-        return self.cancel(ev);
-    });
-    on(el, 'wheel', function (ev) {
-        if (!self.mouseEvents)
-            return;
-        if (self.x10Mouse
-            || self.vt300Mouse
-            || self.decLocator)
-            return;
-        sendButton(ev);
-        return self.cancel(ev);
-    });
-    on(el, 'wheel', function (ev) {
-        if (self.mouseEvents)
-            return;
-        self.viewport.onWheel(ev);
-        return self.cancel(ev);
-    });
-};
-Terminal.prototype.destroy = function () {
-    this.readable = false;
-    this.writable = false;
-    this._events = {};
-    this.handler = function () { };
-    this.write = function () { };
-    if (this.element && this.element.parentNode) {
-        this.element.parentNode.removeChild(this.element);
-    }
-};
-Terminal.prototype.refresh = function (start, end) {
-    if (this.renderer) {
-        this.renderer.queueRefresh(start, end);
-    }
-};
-Terminal.prototype.queueLinkification = function (start, end) {
-    if (this.linkifier) {
-        for (var i = start; i <= end; i++) {
-            this.linkifier.linkifyRow(i);
-        }
-    }
-};
-Terminal.prototype.showCursor = function () {
-    if (!this.cursorState) {
-        this.cursorState = 1;
-        this.refresh(this.y, this.y);
-    }
-};
-Terminal.prototype.scroll = function () {
-    var row;
-    if (this.lines.length === this.lines.maxLength) {
-        this.lines.trimStart(1);
-        this.ybase--;
-        if (this.ydisp !== 0) {
-            this.ydisp--;
-        }
-    }
-    this.ybase++;
-    if (!this.userScrolling) {
-        this.ydisp = this.ybase;
-    }
-    row = this.ybase + this.rows - 1;
-    row -= this.rows - 1 - this.scrollBottom;
-    if (row === this.lines.length) {
-        this.lines.push(this.blankLine());
-    }
-    else {
-        this.lines.splice(row, 0, this.blankLine());
-    }
-    if (this.scrollTop !== 0) {
-        if (this.ybase !== 0) {
-            this.ybase--;
-            if (!this.userScrolling) {
-                this.ydisp = this.ybase;
-            }
-        }
-        this.lines.splice(this.ybase + this.scrollTop, 1);
-    }
-    this.updateRange(this.scrollTop);
-    this.updateRange(this.scrollBottom);
-    this.emit('scroll', this.ydisp);
-};
-Terminal.prototype.scrollDisp = function (disp, suppressScrollEvent) {
-    if (disp < 0) {
-        this.userScrolling = true;
-    }
-    else if (disp + this.ydisp >= this.ybase) {
-        this.userScrolling = false;
-    }
-    this.ydisp += disp;
-    if (this.ydisp > this.ybase) {
-        this.ydisp = this.ybase;
-    }
-    else if (this.ydisp < 0) {
-        this.ydisp = 0;
-    }
-    if (!suppressScrollEvent) {
-        this.emit('scroll', this.ydisp);
-    }
-    this.refresh(0, this.rows - 1);
-};
-Terminal.prototype.scrollPages = function (pageCount) {
-    this.scrollDisp(pageCount * (this.rows - 1));
-};
-Terminal.prototype.scrollToTop = function () {
-    this.scrollDisp(-this.ydisp);
-};
-Terminal.prototype.scrollToBottom = function () {
-    this.scrollDisp(this.ybase - this.ydisp);
-};
-Terminal.prototype.write = function (data) {
-    this.writeBuffer.push(data);
-    if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {
-        this.send(EscapeSequences_1.C0.DC3);
-        this.xoffSentToCatchUp = true;
-    }
-    if (!this.writeInProgress && this.writeBuffer.length > 0) {
-        this.writeInProgress = true;
-        var self = this;
-        setTimeout(function () {
-            self.innerWrite();
-        });
-    }
-};
-Terminal.prototype.innerWrite = function () {
-    var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);
-    while (writeBatch.length > 0) {
-        var data = writeBatch.shift();
-        var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row;
-        if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {
-            this.send(EscapeSequences_1.C0.DC1);
-            this.xoffSentToCatchUp = false;
-        }
-        this.refreshStart = this.y;
-        this.refreshEnd = this.y;
-        var state = this.parser.parse(data);
-        this.parser.setState(state);
-        this.updateRange(this.y);
-        this.refresh(this.refreshStart, this.refreshEnd);
-    }
-    if (this.writeBuffer.length > 0) {
-        var self = this;
-        setTimeout(function () {
-            self.innerWrite();
-        }, 0);
-    }
-    else {
-        this.writeInProgress = false;
-    }
-};
-Terminal.prototype.writeln = function (data) {
-    this.write(data + '\r\n');
-};
-Terminal.prototype.attachCustomKeydownHandler = function (customKeydownHandler) {
-    this.customKeydownHandler = customKeydownHandler;
-};
-Terminal.prototype.setHypertextLinkHandler = function (handler) {
-    if (!this.linkifier) {
-        throw new Error('Cannot attach a hypertext link handler before Terminal.open is called');
-    }
-    this.linkifier.setHypertextLinkHandler(handler);
-    this.refresh(0, this.rows - 1);
-};
-Terminal.prototype.setHypertextValidationCallback = function (handler) {
-    if (!this.linkifier) {
-        throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called');
-    }
-    this.linkifier.setHypertextValidationCallback(handler);
-    this.refresh(0, this.rows - 1);
-};
-Terminal.prototype.registerLinkMatcher = function (regex, handler, options) {
-    if (this.linkifier) {
-        var matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);
-        this.refresh(0, this.rows - 1);
-        return matcherId;
-    }
-};
-Terminal.prototype.deregisterLinkMatcher = function (matcherId) {
-    if (this.linkifier) {
-        if (this.linkifier.deregisterLinkMatcher(matcherId)) {
-            this.refresh(0, this.rows - 1);
-        }
-    }
-};
-Terminal.prototype.keyDown = function (ev) {
-    if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) {
-        return false;
-    }
-    this.restartCursorBlinking();
-    if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) {
-        if (this.ybase !== this.ydisp) {
-            this.scrollToBottom();
-        }
-        return false;
-    }
-    var self = this;
-    var result = this.evaluateKeyEscapeSequence(ev);
-    if (result.key === EscapeSequences_1.C0.DC3) {
-        this.writeStopped = true;
-    }
-    else if (result.key === EscapeSequences_1.C0.DC1) {
-        this.writeStopped = false;
-    }
-    if (result.scrollDisp) {
-        this.scrollDisp(result.scrollDisp);
-        return this.cancel(ev, true);
-    }
-    if (isThirdLevelShift(this, ev)) {
-        return true;
-    }
-    if (result.cancel) {
-        this.cancel(ev, true);
-    }
-    if (!result.key) {
-        return true;
-    }
-    this.emit('keydown', ev);
-    this.emit('key', result.key, ev);
-    this.showCursor();
-    this.handler(result.key);
-    return this.cancel(ev, true);
-};
-Terminal.prototype.evaluateKeyEscapeSequence = function (ev) {
-    var result = {
-        cancel: false,
-        key: undefined,
-        scrollDisp: undefined
-    };
-    var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3;
-    switch (ev.keyCode) {
-        case 8:
-            if (ev.shiftKey) {
-                result.key = EscapeSequences_1.C0.BS;
-                break;
-            }
-            result.key = EscapeSequences_1.C0.DEL;
-            break;
-        case 9:
-            if (ev.shiftKey) {
-                result.key = EscapeSequences_1.C0.ESC + '[Z';
-                break;
-            }
-            result.key = EscapeSequences_1.C0.HT;
-            result.cancel = true;
-            break;
-        case 13:
-            result.key = EscapeSequences_1.C0.CR;
-            result.cancel = true;
-            break;
-        case 27:
-            result.key = EscapeSequences_1.C0.ESC;
-            result.cancel = true;
-            break;
-        case 37:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'D';
-                if (result.key == EscapeSequences_1.C0.ESC + '[1;3D') {
-                    result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'b' : EscapeSequences_1.C0.ESC + '[1;5D';
-                }
-            }
-            else if (this.applicationCursor) {
-                result.key = EscapeSequences_1.C0.ESC + 'OD';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[D';
-            }
-            break;
-        case 39:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'C';
-                if (result.key == EscapeSequences_1.C0.ESC + '[1;3C') {
-                    result.key = (this.browser.isMac) ? EscapeSequences_1.C0.ESC + 'f' : EscapeSequences_1.C0.ESC + '[1;5C';
-                }
-            }
-            else if (this.applicationCursor) {
-                result.key = EscapeSequences_1.C0.ESC + 'OC';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[C';
-            }
-            break;
-        case 38:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'A';
-                if (result.key == EscapeSequences_1.C0.ESC + '[1;3A') {
-                    result.key = EscapeSequences_1.C0.ESC + '[1;5A';
-                }
-            }
-            else if (this.applicationCursor) {
-                result.key = EscapeSequences_1.C0.ESC + 'OA';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[A';
-            }
-            break;
-        case 40:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'B';
-                if (result.key == EscapeSequences_1.C0.ESC + '[1;3B') {
-                    result.key = EscapeSequences_1.C0.ESC + '[1;5B';
-                }
-            }
-            else if (this.applicationCursor) {
-                result.key = EscapeSequences_1.C0.ESC + 'OB';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[B';
-            }
-            break;
-        case 45:
-            if (!ev.shiftKey && !ev.ctrlKey) {
-                result.key = EscapeSequences_1.C0.ESC + '[2~';
-            }
-            break;
-        case 46:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[3;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[3~';
-            }
-            break;
-        case 36:
-            if (modifiers)
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'H';
-            else if (this.applicationCursor)
-                result.key = EscapeSequences_1.C0.ESC + 'OH';
-            else
-                result.key = EscapeSequences_1.C0.ESC + '[H';
-            break;
-        case 35:
-            if (modifiers)
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'F';
-            else if (this.applicationCursor)
-                result.key = EscapeSequences_1.C0.ESC + 'OF';
-            else
-                result.key = EscapeSequences_1.C0.ESC + '[F';
-            break;
-        case 33:
-            if (ev.shiftKey) {
-                result.scrollDisp = -(this.rows - 1);
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[5~';
-            }
-            break;
-        case 34:
-            if (ev.shiftKey) {
-                result.scrollDisp = this.rows - 1;
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[6~';
-            }
-            break;
-        case 112:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'P';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + 'OP';
-            }
-            break;
-        case 113:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'Q';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + 'OQ';
-            }
-            break;
-        case 114:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'R';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + 'OR';
-            }
-            break;
-        case 115:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[1;' + (modifiers + 1) + 'S';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + 'OS';
-            }
-            break;
-        case 116:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[15;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[15~';
-            }
-            break;
-        case 117:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[17;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[17~';
-            }
-            break;
-        case 118:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[18;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[18~';
-            }
-            break;
-        case 119:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[19;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[19~';
-            }
-            break;
-        case 120:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[20;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[20~';
-            }
-            break;
-        case 121:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[21;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[21~';
-            }
-            break;
-        case 122:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[23;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[23~';
-            }
-            break;
-        case 123:
-            if (modifiers) {
-                result.key = EscapeSequences_1.C0.ESC + '[24;' + (modifiers + 1) + '~';
-            }
-            else {
-                result.key = EscapeSequences_1.C0.ESC + '[24~';
-            }
-            break;
-        default:
-            if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
-                if (ev.keyCode >= 65 && ev.keyCode <= 90) {
-                    result.key = String.fromCharCode(ev.keyCode - 64);
-                }
-                else if (ev.keyCode === 32) {
-                    result.key = String.fromCharCode(0);
-                }
-                else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
-                    result.key = String.fromCharCode(ev.keyCode - 51 + 27);
-                }
-                else if (ev.keyCode === 56) {
-                    result.key = String.fromCharCode(127);
-                }
-                else if (ev.keyCode === 219) {
-                    result.key = String.fromCharCode(27);
-                }
-                else if (ev.keyCode === 220) {
-                    result.key = String.fromCharCode(28);
-                }
-                else if (ev.keyCode === 221) {
-                    result.key = String.fromCharCode(29);
-                }
-            }
-            else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {
-                if (ev.keyCode >= 65 && ev.keyCode <= 90) {
-                    result.key = EscapeSequences_1.C0.ESC + String.fromCharCode(ev.keyCode + 32);
-                }
-                else if (ev.keyCode === 192) {
-                    result.key = EscapeSequences_1.C0.ESC + '`';
-                }
-                else if (ev.keyCode >= 48 && ev.keyCode <= 57) {
-                    result.key = EscapeSequences_1.C0.ESC + (ev.keyCode - 48);
-                }
-            }
-            break;
-    }
-    return result;
-};
-Terminal.prototype.setgLevel = function (g) {
-    this.glevel = g;
-    this.charset = this.charsets[g];
-};
-Terminal.prototype.setgCharset = function (g, charset) {
-    this.charsets[g] = charset;
-    if (this.glevel === g) {
-        this.charset = charset;
-    }
-};
-Terminal.prototype.keyPress = function (ev) {
-    var key;
-    this.cancel(ev);
-    if (ev.charCode) {
-        key = ev.charCode;
-    }
-    else if (ev.which == null) {
-        key = ev.keyCode;
-    }
-    else if (ev.which !== 0 && ev.charCode !== 0) {
-        key = ev.which;
-    }
-    else {
-        return false;
-    }
-    if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev))) {
-        return false;
-    }
-    key = String.fromCharCode(key);
-    this.emit('keypress', key, ev);
-    this.emit('key', key, ev);
-    this.showCursor();
-    this.handler(key);
-    return false;
-};
-Terminal.prototype.send = function (data) {
-    var self = this;
-    if (!this.queue) {
-        setTimeout(function () {
-            self.handler(self.queue);
-            self.queue = '';
-        }, 1);
-    }
-    this.queue += data;
-};
-Terminal.prototype.bell = function () {
-    if (!this.visualBell)
-        return;
-    var self = this;
-    this.element.style.borderColor = 'white';
-    setTimeout(function () {
-        self.element.style.borderColor = '';
-    }, 10);
-    if (this.popOnBell)
-        this.focus();
-};
-Terminal.prototype.log = function () {
-    if (!this.debug)
-        return;
-    if (!this.context.console || !this.context.console.log)
-        return;
-    var args = Array.prototype.slice.call(arguments);
-    this.context.console.log.apply(this.context.console, args);
-};
-Terminal.prototype.error = function () {
-    if (!this.debug)
-        return;
-    if (!this.context.console || !this.context.console.error)
-        return;
-    var args = Array.prototype.slice.call(arguments);
-    this.context.console.error.apply(this.context.console, args);
-};
-Terminal.prototype.resize = function (x, y) {
-    if (isNaN(x) || isNaN(y)) {
-        return;
-    }
-    var line, el, i, j, ch, addToY;
-    if (x === this.cols && y === this.rows) {
-        return;
-    }
-    if (x < 1)
-        x = 1;
-    if (y < 1)
-        y = 1;
-    j = this.cols;
-    if (j < x) {
-        ch = [this.defAttr, ' ', 1];
-        i = this.lines.length;
-        while (i--) {
-            while (this.lines.get(i).length < x) {
-                this.lines.get(i).push(ch);
-            }
-        }
-    }
-    this.cols = x;
-    this.setupStops(this.cols);
-    j = this.rows;
-    addToY = 0;
-    if (j < y) {
-        el = this.element;
-        while (j++ < y) {
-            if (this.lines.length < y + this.ybase) {
-                if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) {
-                    this.ybase--;
-                    addToY++;
-                    if (this.ydisp > 0) {
-                        this.ydisp--;
-                    }
-                }
-                else {
-                    this.lines.push(this.blankLine());
-                }
-            }
-            if (this.children.length < y) {
-                this.insertRow();
-            }
-        }
-    }
-    else {
-        while (j-- > y) {
-            if (this.lines.length > y + this.ybase) {
-                if (this.lines.length > this.ybase + this.y + 1) {
-                    this.lines.pop();
-                }
-                else {
-                    this.ybase++;
-                    this.ydisp++;
-                }
-            }
-            if (this.children.length > y) {
-                el = this.children.shift();
-                if (!el)
-                    continue;
-                el.parentNode.removeChild(el);
-            }
-        }
-    }
-    this.rows = y;
-    if (this.y >= y) {
-        this.y = y - 1;
-    }
-    if (addToY) {
-        this.y += addToY;
-    }
-    if (this.x >= x) {
-        this.x = x - 1;
-    }
-    this.scrollTop = 0;
-    this.scrollBottom = y - 1;
-    this.charMeasure.measure();
-    this.refresh(0, this.rows - 1);
-    this.normal = null;
-    this.geometry = [this.cols, this.rows];
-    this.emit('resize', { terminal: this, cols: x, rows: y });
-};
-Terminal.prototype.updateRange = function (y) {
-    if (y < this.refreshStart)
-        this.refreshStart = y;
-    if (y > this.refreshEnd)
-        this.refreshEnd = y;
-};
-Terminal.prototype.maxRange = function () {
-    this.refreshStart = 0;
-    this.refreshEnd = this.rows - 1;
-};
-Terminal.prototype.setupStops = function (i) {
-    if (i != null) {
-        if (!this.tabs[i]) {
-            i = this.prevStop(i);
-        }
-    }
-    else {
-        this.tabs = {};
-        i = 0;
-    }
-    for (; i < this.cols; i += this.getOption('tabStopWidth')) {
-        this.tabs[i] = true;
-    }
-};
-Terminal.prototype.prevStop = function (x) {
-    if (x == null)
-        x = this.x;
-    while (!this.tabs[--x] && x > 0)
-        ;
-    return x >= this.cols
-        ? this.cols - 1
-        : x < 0 ? 0 : x;
-};
-Terminal.prototype.nextStop = function (x) {
-    if (x == null)
-        x = this.x;
-    while (!this.tabs[++x] && x < this.cols)
-        ;
-    return x >= this.cols
-        ? this.cols - 1
-        : x < 0 ? 0 : x;
-};
-Terminal.prototype.eraseRight = function (x, y) {
-    var line = this.lines.get(this.ybase + y);
-    if (!line) {
-        return;
-    }
-    var ch = [this.eraseAttr(), ' ', 1];
-    for (; x < this.cols; x++) {
-        line[x] = ch;
-    }
-    this.updateRange(y);
-};
-Terminal.prototype.eraseLeft = function (x, y) {
-    var line = this.lines.get(this.ybase + y);
-    if (!line) {
-        return;
-    }
-    var ch = [this.eraseAttr(), ' ', 1];
-    x++;
-    while (x--) {
-        line[x] = ch;
-    }
-    this.updateRange(y);
-};
-Terminal.prototype.clear = function () {
-    if (this.ybase === 0 && this.y === 0) {
-        return;
-    }
-    this.lines.set(0, this.lines.get(this.ybase + this.y));
-    this.lines.length = 1;
-    this.ydisp = 0;
-    this.ybase = 0;
-    this.y = 0;
-    for (var i = 1; i < this.rows; i++) {
-        this.lines.push(this.blankLine());
-    }
-    this.refresh(0, this.rows - 1);
-    this.emit('scroll', this.ydisp);
-};
-Terminal.prototype.eraseLine = function (y) {
-    this.eraseRight(0, y);
-};
-Terminal.prototype.blankLine = function (cur) {
-    var attr = cur
-        ? this.eraseAttr()
-        : this.defAttr;
-    var ch = [attr, ' ', 1], line = [], i = 0;
-    for (; i < this.cols; i++) {
-        line[i] = ch;
-    }
-    return line;
-};
-Terminal.prototype.ch = function (cur) {
-    return cur
-        ? [this.eraseAttr(), ' ', 1]
-        : [this.defAttr, ' ', 1];
-};
-Terminal.prototype.is = function (term) {
-    var name = this.termName;
-    return (name + '').indexOf(term) === 0;
-};
-Terminal.prototype.handler = function (data) {
-    if (this.options.disableStdin) {
-        return;
-    }
-    if (this.ybase !== this.ydisp) {
-        this.scrollToBottom();
-    }
-    this.emit('data', data);
-};
-Terminal.prototype.handleTitle = function (title) {
-    this.emit('title', title);
-};
-Terminal.prototype.index = function () {
-    this.y++;
-    if (this.y > this.scrollBottom) {
-        this.y--;
-        this.scroll();
-    }
-    if (this.x >= this.cols) {
-        this.x--;
-    }
-};
-Terminal.prototype.reverseIndex = function () {
-    var j;
-    if (this.y === this.scrollTop) {
-        this.lines.shiftElements(this.y + this.ybase, this.rows - 1, 1);
-        this.lines.set(this.y + this.ybase, this.blankLine(true));
-        this.updateRange(this.scrollTop);
-        this.updateRange(this.scrollBottom);
-    }
-    else {
-        this.y--;
-    }
-};
-Terminal.prototype.reset = function () {
-    this.options.rows = this.rows;
-    this.options.cols = this.cols;
-    var customKeydownHandler = this.customKeydownHandler;
-    var cursorBlinkInterval = this.cursorBlinkInterval;
-    Terminal.call(this, this.options);
-    this.customKeydownHandler = customKeydownHandler;
-    this.cursorBlinkInterval = cursorBlinkInterval;
-    this.refresh(0, this.rows - 1);
-    this.viewport.syncScrollArea();
-};
-Terminal.prototype.tabSet = function () {
-    this.tabs[this.x] = true;
-};
-function on(el, type, handler, capture) {
-    if (!Array.isArray(el)) {
-        el = [el];
-    }
-    el.forEach(function (element) {
-        element.addEventListener(type, handler, capture || false);
-    });
-}
-function off(el, type, handler, capture) {
-    el.removeEventListener(type, handler, capture || false);
-}
-function cancel(ev, force) {
-    if (!this.cancelEvents && !force) {
-        return;
-    }
-    ev.preventDefault();
-    ev.stopPropagation();
-    return false;
-}
-function inherits(child, parent) {
-    function f() {
-        this.constructor = child;
-    }
-    f.prototype = parent.prototype;
-    child.prototype = new f;
-}
-function indexOf(obj, el) {
-    var i = obj.length;
-    while (i--) {
-        if (obj[i] === el)
-            return i;
-    }
-    return -1;
-}
-function isThirdLevelShift(term, ev) {
-    var thirdLevelKey = (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
-        (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
-    if (ev.type == 'keypress') {
-        return thirdLevelKey;
-    }
-    return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
-}
-Terminal.prototype.matchColor = matchColor;
-function matchColor(r1, g1, b1) {
-    var hash = (r1 << 16) | (g1 << 8) | b1;
-    if (matchColor._cache[hash] != null) {
-        return matchColor._cache[hash];
-    }
-    var ldiff = Infinity, li = -1, i = 0, c, r2, g2, b2, diff;
-    for (; i < Terminal.vcolors.length; i++) {
-        c = Terminal.vcolors[i];
-        r2 = c[0];
-        g2 = c[1];
-        b2 = c[2];
-        diff = matchColor.distance(r1, g1, b1, r2, g2, b2);
-        if (diff === 0) {
-            li = i;
-            break;
-        }
-        if (diff < ldiff) {
-            ldiff = diff;
-            li = i;
-        }
-    }
-    return matchColor._cache[hash] = li;
-}
-matchColor._cache = {};
-matchColor.distance = function (r1, g1, b1, r2, g2, b2) {
-    return Math.pow(30 * (r1 - r2), 2)
-        + Math.pow(59 * (g1 - g2), 2)
-        + Math.pow(11 * (b1 - b2), 2);
-};
-function each(obj, iter, con) {
-    if (obj.forEach)
-        return obj.forEach(iter, con);
-    for (var i = 0; i < obj.length; i++) {
-        iter.call(con, obj[i], i, obj);
-    }
-}
-function wasMondifierKeyOnlyEvent(ev) {
-    return ev.keyCode === 16 ||
-        ev.keyCode === 17 ||
-        ev.keyCode === 18;
-}
-function keys(obj) {
-    if (Object.keys)
-        return Object.keys(obj);
-    var key, keys = [];
-    for (key in obj) {
-        if (Object.prototype.hasOwnProperty.call(obj, key)) {
-            keys.push(key);
-        }
-    }
-    return keys;
-}
-Terminal.EventEmitter = EventEmitter_1.EventEmitter;
-Terminal.inherits = inherits;
-Terminal.on = on;
-Terminal.off = off;
-Terminal.cancel = cancel;
-module.exports = Terminal;
-
-
-
-},{"./CompositionHelper":2,"./EscapeSequences":3,"./EventEmitter":4,"./InputHandler":5,"./Linkifier":6,"./Parser":7,"./Renderer":8,"./Viewport":9,"./handlers/Clipboard":10,"./utils/Browser":11,"./utils/CharMeasure":12,"./utils/CircularList":13,"./utils/Mouse":16}]},{},[17])(17)
-});
-//# sourceMappingURL=xterm.js.map
diff --git a/front_end/test_runner/TestRunner.js b/front_end/test_runner/TestRunner.js
deleted file mode 100644
index 3edf86f..0000000
--- a/front_end/test_runner/TestRunner.js
+++ /dev/null
@@ -1,1432 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview using private properties isn't a Closure violation in tests.
- * @suppress {accessControls}
- */
-
-/* eslint-disable no-console */
-
-/** @type {!{logToStderr: function(), navigateSecondaryWindow: function(string), notifyDone: function()}|undefined} */
-self.testRunner;
-
-/**
- * Only tests in /LayoutTests/http/tests/devtools/startup/ need to call
- * this method because these tests need certain activities to be exercised
- * in the inspected page prior to the DevTools session.
- * @param {string} path
- * @return {!Promise<undefined>}
- */
-TestRunner.setupStartupTest = function(path) {
-  const absoluteURL = TestRunner.url(path);
-  self.testRunner.navigateSecondaryWindow(absoluteURL);
-  return new Promise(f => TestRunner._startupTestSetupFinished = () => {
-    TestRunner._initializeTargetForStartupTest();
-    delete TestRunner._startupTestSetupFinished;
-    f();
-  });
-};
-
-TestRunner._executeTestScript = function() {
-  const testScriptURL = /** @type {string} */ (Runtime.queryParam('test'));
-  fetch(testScriptURL)
-      .then(data => data.text())
-      .then(testScript => {
-        if (TestRunner._isDebugTest()) {
-          TestRunner.addResult = console.log;
-          TestRunner.completeTest = () => console.log('Test completed');
-
-          // Auto-start unit tests
-          if (!self.testRunner)
-            eval(`(function test(){${testScript}})()\n//# sourceURL=${testScriptURL}`);
-          else
-            self.eval(`function test(){${testScript}}\n//# sourceURL=${testScriptURL}`);
-          return;
-        }
-
-        // Convert the test script into an expression (if needed)
-        testScript = testScript.trimRight();
-        if (testScript.endsWith(';'))
-          testScript = testScript.slice(0, testScript.length - 1);
-
-        (async function() {
-          try {
-            await eval(testScript + `\n//# sourceURL=${testScriptURL}`);
-          } catch (err) {
-            TestRunner.addResult('TEST ENDED EARLY DUE TO UNCAUGHT ERROR:');
-            TestRunner.addResult(err && err.stack || err);
-            TestRunner.addResult('=== DO NOT COMMIT THIS INTO -expected.txt ===');
-            TestRunner.completeTest();
-          }
-        })();
-      })
-      .catch(error => {
-        TestRunner.addResult(`Unable to execute test script because of error: ${error}`);
-        TestRunner.completeTest();
-      });
-};
-
-/** @type {!Array<string>} */
-TestRunner._results = [];
-
-TestRunner.completeTest = function() {
-  TestRunner.flushResults();
-  self.testRunner.notifyDone();
-};
-
-/**
- * @suppressGlobalPropertiesCheck
- */
-TestRunner.flushResults = function() {
-  Array.prototype.forEach.call(document.documentElement.childNodes, x => x.remove());
-  const outputElement = document.createElement('div');
-  // Support for svg - add to document, not body, check for style.
-  if (outputElement.style) {
-    outputElement.style.whiteSpace = 'pre';
-    outputElement.style.height = '10px';
-    outputElement.style.overflow = 'hidden';
-  }
-  document.documentElement.appendChild(outputElement);
-  for (let i = 0; i < TestRunner._results.length; i++) {
-    outputElement.appendChild(document.createTextNode(TestRunner._results[i]));
-    outputElement.appendChild(document.createElement('br'));
-  }
-  TestRunner._results = [];
-};
-
-/**
- * @param {*} text
- */
-TestRunner.addResult = function(text) {
-  TestRunner._results.push(String(text));
-};
-
-/**
- * @param {!Array<string>} textArray
- */
-TestRunner.addResults = function(textArray) {
-  if (!textArray)
-    return;
-  for (let i = 0, size = textArray.length; i < size; ++i)
-    TestRunner.addResult(textArray[i]);
-};
-
-/**
- * @param {!Array<function()>} tests
- */
-TestRunner.runTests = function(tests) {
-  nextTest();
-
-  function nextTest() {
-    const test = tests.shift();
-    if (!test) {
-      TestRunner.completeTest();
-      return;
-    }
-    TestRunner.addResult('\ntest: ' + test.name);
-    let testPromise = test();
-    if (!(testPromise instanceof Promise))
-      testPromise = Promise.resolve();
-    testPromise.then(nextTest);
-  }
-};
-
-/**
- * @param {!Object} receiver
- * @param {string} methodName
- * @param {!Function} override
- * @param {boolean=} opt_sticky
- */
-TestRunner.addSniffer = function(receiver, methodName, override, opt_sticky) {
-  override = TestRunner.safeWrap(override);
-
-  const original = receiver[methodName];
-  if (typeof original !== 'function')
-    throw new Error('Cannot find method to override: ' + methodName);
-
-  receiver[methodName] = function(var_args) {
-    let result;
-    try {
-      result = original.apply(this, arguments);
-    } finally {
-      if (!opt_sticky)
-        receiver[methodName] = original;
-    }
-    // In case of exception the override won't be called.
-    try {
-      Array.prototype.push.call(arguments, result);
-      override.apply(this, arguments);
-    } catch (e) {
-      throw new Error('Exception in overriden method \'' + methodName + '\': ' + e);
-    }
-    return result;
-  };
-};
-
-/**
- * @param {!Object} receiver
- * @param {string} methodName
- * @return {!Promise<*>}
- */
-TestRunner.addSnifferPromise = function(receiver, methodName) {
-  return new Promise(function(resolve, reject) {
-    const original = receiver[methodName];
-    if (typeof original !== 'function') {
-      reject('Cannot find method to override: ' + methodName);
-      return;
-    }
-
-    receiver[methodName] = function(var_args) {
-      let result;
-      try {
-        result = original.apply(this, arguments);
-      } finally {
-        receiver[methodName] = original;
-      }
-      // In case of exception the override won't be called.
-      try {
-        Array.prototype.push.call(arguments, result);
-        resolve.apply(this, arguments);
-      } catch (e) {
-        reject('Exception in overridden method \'' + methodName + '\': ' + e);
-        TestRunner.completeTest();
-      }
-      return result;
-    };
-  });
-};
-
-/** @type {function():void} */
-TestRunner._resolveOnFinishInits;
-
-/**
- * @param {string} module
- * @return {!Promise<undefined>}
- */
-TestRunner.loadModule = async function(module) {
-  const promise = new Promise(resolve => TestRunner._resolveOnFinishInits = resolve);
-  await self.runtime.loadModulePromise(module);
-  if (!TestRunner._pendingInits)
-    return;
-  return promise;
-};
-
-/**
- * @param {string} panel
- * @return {!Promise.<?UI.Panel>}
- */
-TestRunner.showPanel = function(panel) {
-  return UI.viewManager.showView(panel);
-};
-
-/**
- * @param {string} key
- * @param {boolean=} ctrlKey
- * @param {boolean=} altKey
- * @param {boolean=} shiftKey
- * @param {boolean=} metaKey
- * @return {!KeyboardEvent}
- */
-TestRunner.createKeyEvent = function(key, ctrlKey, altKey, shiftKey, metaKey) {
-  return new KeyboardEvent('keydown', {
-    key: key,
-    bubbles: true,
-    cancelable: true,
-    ctrlKey: !!ctrlKey,
-    altKey: !!altKey,
-    shiftKey: !!shiftKey,
-    metaKey: !!metaKey
-  });
-};
-
-/**
- * @param {!Function|undefined} func
- * @param {!Function=} onexception
- * @return {!Function}
- */
-TestRunner.safeWrap = function(func, onexception) {
-  /**
-   * @this {*}
-   */
-  function result() {
-    if (!func)
-      return;
-    const wrapThis = this;
-    try {
-      return func.apply(wrapThis, arguments);
-    } catch (e) {
-      TestRunner.addResult('Exception while running: ' + func + '\n' + (e.stack || e));
-      if (onexception)
-        TestRunner.safeWrap(onexception)();
-      else
-        TestRunner.completeTest();
-    }
-  }
-  return result;
-};
-
-/**
- * @param {!Node} node
- * @return {string}
- */
-TestRunner.textContentWithLineBreaks = function(node) {
-  function padding(currentNode) {
-    let result = 0;
-    while (currentNode && currentNode !== node) {
-      if (currentNode.nodeName === 'OL' &&
-          !(currentNode.classList && currentNode.classList.contains('object-properties-section')))
-        ++result;
-      currentNode = currentNode.parentNode;
-    }
-    return Array(result * 4 + 1).join(' ');
-  }
-
-  let buffer = '';
-  let currentNode = node;
-  let ignoreFirst = false;
-  while (currentNode.traverseNextNode(node)) {
-    currentNode = currentNode.traverseNextNode(node);
-    if (currentNode.nodeType === Node.TEXT_NODE) {
-      buffer += currentNode.nodeValue;
-    } else if (currentNode.nodeName === 'LI' || currentNode.nodeName === 'TR') {
-      if (!ignoreFirst)
-        buffer += '\n' + padding(currentNode);
-      else
-        ignoreFirst = false;
-    } else if (currentNode.nodeName === 'STYLE') {
-      currentNode = currentNode.traverseNextNode(node);
-      continue;
-    } else if (currentNode.classList && currentNode.classList.contains('object-properties-section')) {
-      ignoreFirst = true;
-    }
-  }
-  return buffer;
-};
-
-/**
- * @param {!Node} node
- * @return {string}
- */
-TestRunner.textContentWithoutStyles = function(node) {
-  let buffer = '';
-  let currentNode = node;
-  while (currentNode.traverseNextNode(node)) {
-    currentNode = currentNode.traverseNextNode(node);
-    if (currentNode.nodeType === Node.TEXT_NODE)
-      buffer += currentNode.nodeValue;
-    else if (currentNode.nodeName === 'STYLE')
-      currentNode = currentNode.traverseNextNode(node);
-  }
-  return buffer;
-};
-
-/**
- * @param {!SDK.Target} target
- */
-TestRunner._setupTestHelpers = function(target) {
-  TestRunner.CSSAgent = target.cssAgent();
-  TestRunner.DeviceOrientationAgent = target.deviceOrientationAgent();
-  TestRunner.DOMAgent = target.domAgent();
-  TestRunner.DOMDebuggerAgent = target.domdebuggerAgent();
-  TestRunner.DebuggerAgent = target.debuggerAgent();
-  TestRunner.EmulationAgent = target.emulationAgent();
-  TestRunner.HeapProfilerAgent = target.heapProfilerAgent();
-  TestRunner.InspectorAgent = target.inspectorAgent();
-  TestRunner.NetworkAgent = target.networkAgent();
-  TestRunner.OverlayAgent = target.overlayAgent();
-  TestRunner.PageAgent = target.pageAgent();
-  TestRunner.ProfilerAgent = target.profilerAgent();
-  TestRunner.RuntimeAgent = target.runtimeAgent();
-  TestRunner.TargetAgent = target.targetAgent();
-
-  TestRunner.networkManager = target.model(SDK.NetworkManager);
-  TestRunner.securityOriginManager = target.model(SDK.SecurityOriginManager);
-  TestRunner.resourceTreeModel = target.model(SDK.ResourceTreeModel);
-  TestRunner.debuggerModel = target.model(SDK.DebuggerModel);
-  TestRunner.runtimeModel = target.model(SDK.RuntimeModel);
-  TestRunner.domModel = target.model(SDK.DOMModel);
-  TestRunner.domDebuggerModel = target.model(SDK.DOMDebuggerModel);
-  TestRunner.cssModel = target.model(SDK.CSSModel);
-  TestRunner.cpuProfilerModel = target.model(SDK.CPUProfilerModel);
-  TestRunner.overlayModel = target.model(SDK.OverlayModel);
-  TestRunner.serviceWorkerManager = target.model(SDK.ServiceWorkerManager);
-  TestRunner.tracingManager = target.model(SDK.TracingManager);
-  TestRunner.mainTarget = target;
-};
-
-/**
- * @param {string} code
- * @return {!Promise<*>}
- */
-TestRunner.evaluateInPageRemoteObject = async function(code) {
-  const response = await TestRunner._evaluateInPage(code);
-  return TestRunner.runtimeModel.createRemoteObject(response.result);
-};
-
-/**
- * @param {string} code
- * @param {function(*, !Protocol.Runtime.ExceptionDetails=):void} callback
- */
-TestRunner.evaluateInPage = async function(code, callback) {
-  const response = await TestRunner._evaluateInPage(code);
-  TestRunner.safeWrap(callback)(response.result.value, response.exceptionDetails);
-};
-
-/** @type {number} */
-TestRunner._evaluateInPageCounter = 0;
-
-/**
- * @param {string} code
- * @return {!Promise<{response: !SDK.RemoteObject,
- *   exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined)}>}
- */
-TestRunner._evaluateInPage = async function(code) {
-  const lines = new Error().stack.split('at ');
-
-  // Handles cases where the function is safe wrapped
-  const testScriptURL = /** @type {string} */ (Runtime.queryParam('test'));
-  const functionLine = lines.reduce((acc, line) => line.includes(testScriptURL) ? line : acc, lines[lines.length - 2]);
-
-  const components = functionLine.trim().split('/');
-  const source = components[components.length - 1].slice(0, -1).split(':');
-  const fileName = source[0];
-  const sourceURL = `test://evaluations/${TestRunner._evaluateInPageCounter++}/` + fileName;
-  const lineOffset = parseInt(source[1], 10);
-  code = '\n'.repeat(lineOffset - 1) + code;
-  if (code.indexOf('sourceURL=') === -1)
-    code += `//# sourceURL=${sourceURL}`;
-  const response = await TestRunner.RuntimeAgent.invoke_evaluate({expression: code, objectGroup: 'console'});
-  const error = response[Protocol.Error];
-  if (error) {
-    TestRunner.addResult('Error: ' + error);
-    TestRunner.completeTest();
-    return;
-  }
-  return response;
-};
-
-/**
- * Doesn't append sourceURL to snippets evaluated in inspected page
- * to avoid churning test expectations
- * @param {string} code
- * @return {!Promise<*>}
- */
-TestRunner.evaluateInPageAnonymously = async function(code) {
-  const response = await TestRunner.RuntimeAgent.invoke_evaluate({expression: code, objectGroup: 'console'});
-  if (!response[Protocol.Error])
-    return response.result.value;
-  TestRunner.addResult(
-      'Error: ' +
-      (response.exceptionDetails && response.exceptionDetails.text || 'exception from evaluateInPageAnonymously.'));
-  TestRunner.completeTest();
-};
-
-/**
- * @param {string} code
- * @return {!Promise<*>}
- */
-TestRunner.evaluateInPagePromise = function(code) {
-  return new Promise(success => TestRunner.evaluateInPage(code, success));
-};
-
-/**
- * @param {string} code
- * @return {!Promise<*>}
- */
-TestRunner.evaluateInPageAsync = async function(code) {
-  const response = await TestRunner.RuntimeAgent.invoke_evaluate(
-      {expression: code, objectGroup: 'console', includeCommandLineAPI: false, awaitPromise: true});
-
-  const error = response[Protocol.Error];
-  if (!error && !response.exceptionDetails)
-    return response.result.value;
-  TestRunner.addResult(
-      'Error: ' +
-      (error || response.exceptionDetails && response.exceptionDetails.text || 'exception while evaluation in page.'));
-  TestRunner.completeTest();
-};
-
-/**
- * @param {string} name
- * @param {!Array<*>} args
- * @return {!Promise<*>}
- */
-TestRunner.callFunctionInPageAsync = function(name, args) {
-  args = args || [];
-  return TestRunner.evaluateInPageAsync(name + '(' + args.map(a => JSON.stringify(a)).join(',') + ')');
-};
-
-/**
- * @param {string} code
- */
-TestRunner.evaluateInPageWithTimeout = function(code) {
-  // FIXME: we need a better way of waiting for chromium events to happen
-  TestRunner.evaluateInPageAnonymously('setTimeout(unescape(\'' + escape(code) + '\'), 1)');
-};
-
-/**
- * @param {function():*} func
- * @param {function(*):void} callback
- */
-TestRunner.evaluateFunctionInOverlay = function(func, callback) {
-  const expression = 'internals.evaluateInInspectorOverlay("(" + ' + func + ' + ")()")';
-  const mainContext = TestRunner.runtimeModel.executionContexts()[0];
-  mainContext
-      .evaluate(
-          {
-            expression: expression,
-            objectGroup: '',
-            includeCommandLineAPI: false,
-            silent: false,
-            returnByValue: true,
-            generatePreview: false
-          },
-          /* userGesture */ false, /* awaitPromise*/ false)
-      .then(result => void callback(result.object.value));
-};
-
-/**
- * @param {boolean} passCondition
- * @param {string} failureText
- */
-TestRunner.check = function(passCondition, failureText) {
-  if (!passCondition)
-    TestRunner.addResult('FAIL: ' + failureText);
-};
-
-/**
- * @param {!Function} callback
- */
-TestRunner.deprecatedRunAfterPendingDispatches = function(callback) {
-  const targets = SDK.targetManager.targets();
-  const promises = targets.map(target => new Promise(resolve => target._deprecatedRunAfterPendingDispatches(resolve)));
-  Promise.all(promises).then(TestRunner.safeWrap(callback));
-};
-
-/**
- * This ensures a base tag is set so all DOM references
- * are relative to the test file and not the inspected page
- * (i.e. http/tests/devtools/resources/inspected-page.html).
- * @param {string} html
- * @return {!Promise<*>}
- */
-TestRunner.loadHTML = function(html) {
-  if (!html.includes('<base')) {
-    // <!DOCTYPE...> tag needs to be first
-    const doctypeRegex = /(<!DOCTYPE.*?>)/i;
-    const baseTag = `<base href="${TestRunner.url()}">`;
-    if (html.match(doctypeRegex))
-      html = html.replace(doctypeRegex, '$1' + baseTag);
-    else
-      html = baseTag + html;
-  }
-  html = html.replace(/'/g, '\\\'').replace(/\n/g, '\\n');
-  return TestRunner.evaluateInPageAnonymously(`document.write(\`${html}\`);document.close();`);
-};
-
-/**
- * @param {string} path
- * @return {!Promise<*>}
- */
-TestRunner.addScriptTag = function(path) {
-  return TestRunner.evaluateInPageAsync(`
-    (function(){
-      let script = document.createElement('script');
-      script.src = '${path}';
-      document.head.append(script);
-      return new Promise(f => script.onload = f);
-    })();
-  `);
-};
-
-/**
- * @param {string} path
- * @return {!Promise<*>}
- */
-TestRunner.addStylesheetTag = function(path) {
-  return TestRunner.evaluateInPageAsync(`
-    (function(){
-      let link = document.createElement('link');
-      link.rel = 'stylesheet';
-      link.type = 'text/css';
-      link.href = '${path}';
-      link.onload = onload;
-      document.head.append(link);
-      let resolve;
-      let promise = new Promise(r => resolve = r);
-      function onload() {
-        // TODO(chenwilliam): It shouldn't be necessary to force
-        // style recalc here but some tests rely on it.
-        window.getComputedStyle(document.body).color;
-        resolve();
-      }
-      return promise;
-    })();
-  `);
-};
-
-/**
- * @param {string} path
- * @return {!Promise<*>}
- */
-TestRunner.addHTMLImport = function(path) {
-  return TestRunner.evaluateInPageAsync(`
-    (function(){
-      let link = document.createElement('link');
-      link.rel = 'import';
-      link.href = '${path}';
-      let promise = new Promise(r => link.onload = r);
-      document.body.append(link);
-      return promise;
-    })();
-  `);
-};
-
-/**
- * @param {string} path
- * @param {!Object|undefined} options
- * @return {!Promise<*>}
- */
-TestRunner.addIframe = function(path, options = {}) {
-  options.id = options.id || '';
-  options.name = options.name || '';
-  return TestRunner.evaluateInPageAsync(`
-    (function(){
-      let iframe = document.createElement('iframe');
-      iframe.src = '${path}';
-      iframe.id = '${options.id}';
-      iframe.name = '${options.name}';
-      document.body.appendChild(iframe);
-      return new Promise(f => iframe.onload = f);
-    })();
-  `);
-};
-
-/** @type {number} */
-TestRunner._pendingInits = 0;
-
-/**
- * The old test framework executed certain snippets in the inspected page
- * context as part of loading a test helper file.
- *
- * This is deprecated because:
- * 1) it makes the testing API less intuitive (need to read the various *TestRunner.js
- * files to know which helper functions are available in the inspected page).
- * 2) it complicates the test framework's module loading process.
- *
- * In most cases, this is used to set up inspected page functions (e.g. makeSimpleXHR)
- * which should become a *TestRunner method (e.g. NetworkTestRunner.makeSimpleXHR)
- * that calls evaluateInPageAnonymously(...).
- * @param {string} code
- */
-TestRunner.deprecatedInitAsync = async function(code) {
-  TestRunner._pendingInits++;
-  await TestRunner.RuntimeAgent.invoke_evaluate({expression: code, objectGroup: 'console'});
-  TestRunner._pendingInits--;
-  if (!TestRunner._pendingInits)
-    TestRunner._resolveOnFinishInits();
-};
-
-/**
- * @param {string} title
- */
-TestRunner.markStep = function(title) {
-  TestRunner.addResult('\nRunning: ' + title);
-};
-
-TestRunner.startDumpingProtocolMessages = function() {
-  // TODO(chenwilliam): stop abusing Closure interface which is why
-  // we need to opt out of type checking here
-  const untypedConnection = /** @type {*} */ (Protocol.InspectorBackend.Connection);
-  untypedConnection.prototype._dumpProtocolMessage = self.testRunner.logToStderr.bind(self.testRunner);
-  Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages = 1;
-};
-
-/**
- * @param {string} url
- * @param {string} content
- * @param {!SDK.ResourceTreeFrame} frame
- */
-TestRunner.addScriptForFrame = function(url, content, frame) {
-  content += '\n//# sourceURL=' + url;
-  const executionContext = TestRunner.runtimeModel.executionContexts().find(context => context.frameId === frame.id);
-  TestRunner.RuntimeAgent.evaluate(content, 'console', false, false, executionContext.id);
-};
-
-TestRunner.formatters = {};
-
-/**
- * @param {*} value
- * @return {string}
- */
-TestRunner.formatters.formatAsTypeName = function(value) {
-  return '<' + typeof value + '>';
-};
-
-/**
- * @param {*} value
- * @return {string}
- */
-TestRunner.formatters.formatAsTypeNameOrNull = function(value) {
-  if (value === null)
-    return 'null';
-  return TestRunner.formatters.formatAsTypeName(value);
-};
-
-/**
- * @param {*} value
- * @return {string|!Date}
- */
-TestRunner.formatters.formatAsRecentTime = function(value) {
-  if (typeof value !== 'object' || !(value instanceof Date))
-    return TestRunner.formatters.formatAsTypeName(value);
-  const delta = Date.now() - value;
-  return 0 <= delta && delta < 30 * 60 * 1000 ? '<plausible>' : value;
-};
-
-/**
- * @param {string} value
- * @return {string}
- */
-TestRunner.formatters.formatAsURL = function(value) {
-  if (!value)
-    return value;
-  const lastIndex = value.lastIndexOf('devtools/');
-  if (lastIndex < 0)
-    return value;
-  return '.../' + value.substr(lastIndex);
-};
-
-/**
- * @param {string} value
- * @return {string}
- */
-TestRunner.formatters.formatAsDescription = function(value) {
-  if (!value)
-    return value;
-  return '"' + value.replace(/^function [gs]et /, 'function ') + '"';
-};
-
-/**
- * @typedef {!Object<string, string>}
- */
-TestRunner.CustomFormatters;
-
-/**
- * @param {!Object} object
- * @param {!TestRunner.CustomFormatters=} customFormatters
- * @param {string=} prefix
- * @param {string=} firstLinePrefix
- */
-TestRunner.addObject = function(object, customFormatters, prefix, firstLinePrefix) {
-  prefix = prefix || '';
-  firstLinePrefix = firstLinePrefix || prefix;
-  TestRunner.addResult(firstLinePrefix + '{');
-  const propertyNames = Object.keys(object);
-  propertyNames.sort();
-  for (let i = 0; i < propertyNames.length; ++i) {
-    const prop = propertyNames[i];
-    if (!object.hasOwnProperty(prop))
-      continue;
-    const prefixWithName = '    ' + prefix + prop + ' : ';
-    const propValue = object[prop];
-    if (customFormatters && customFormatters[prop]) {
-      const formatterName = customFormatters[prop];
-      if (formatterName !== 'skip') {
-        const formatter = TestRunner.formatters[formatterName];
-        TestRunner.addResult(prefixWithName + formatter(propValue));
-      }
-    } else {
-      TestRunner.dump(propValue, customFormatters, '    ' + prefix, prefixWithName);
-    }
-  }
-  TestRunner.addResult(prefix + '}');
-};
-
-/**
- * @param {!Array} array
- * @param {!TestRunner.CustomFormatters=} customFormatters
- * @param {string=} prefix
- * @param {string=} firstLinePrefix
- */
-TestRunner.addArray = function(array, customFormatters, prefix, firstLinePrefix) {
-  prefix = prefix || '';
-  firstLinePrefix = firstLinePrefix || prefix;
-  TestRunner.addResult(firstLinePrefix + '[');
-  for (let i = 0; i < array.length; ++i)
-    TestRunner.dump(array[i], customFormatters, prefix + '    ');
-  TestRunner.addResult(prefix + ']');
-};
-
-/**
- * @param {!Node} node
- */
-TestRunner.dumpDeepInnerHTML = function(node) {
-  /**
-   * @param {string} prefix
-   * @param {!Node} node
-   */
-  function innerHTML(prefix, node) {
-    const openTag = [];
-    if (node.nodeType === Node.TEXT_NODE) {
-      if (!node.parentElement || node.parentElement.nodeName !== 'STYLE')
-        TestRunner.addResult(node.nodeValue);
-      return;
-    }
-    openTag.push('<' + node.nodeName);
-    const attrs = node.attributes;
-    for (let i = 0; attrs && i < attrs.length; ++i)
-      openTag.push(attrs[i].name + '=' + attrs[i].value);
-
-    openTag.push('>');
-    TestRunner.addResult(prefix + openTag.join(' '));
-    for (let child = node.firstChild; child; child = child.nextSibling)
-      innerHTML(prefix + '    ', child);
-    if (node.shadowRoot)
-      innerHTML(prefix + '    ', node.shadowRoot);
-    TestRunner.addResult(prefix + '</' + node.nodeName + '>');
-  }
-  innerHTML('', node);
-};
-
-/**
- * @param {!Node} node
- * @return {string}
- */
-TestRunner.deepTextContent = function(node) {
-  if (!node)
-    return '';
-  if (node.nodeType === Node.TEXT_NODE && node.nodeValue)
-    return !node.parentElement || node.parentElement.nodeName !== 'STYLE' ? node.nodeValue : '';
-  let res = '';
-  const children = node.childNodes;
-  for (let i = 0; i < children.length; ++i)
-    res += TestRunner.deepTextContent(children[i]);
-  if (node.shadowRoot)
-    res += TestRunner.deepTextContent(node.shadowRoot);
-  return res;
-};
-
-/**
- * @param {*} value
- * @param {!TestRunner.CustomFormatters=} customFormatters
- * @param {string=} prefix
- * @param {string=} prefixWithName
- */
-TestRunner.dump = function(value, customFormatters, prefix, prefixWithName) {
-  prefixWithName = prefixWithName || prefix;
-  if (prefixWithName && prefixWithName.length > 80) {
-    TestRunner.addResult(prefixWithName + 'was skipped due to prefix length limit');
-    return;
-  }
-  if (value === null)
-    TestRunner.addResult(prefixWithName + 'null');
-  else if (value && value.constructor && value.constructor.name === 'Array')
-    TestRunner.addArray(/** @type {!Array} */ (value), customFormatters, prefix, prefixWithName);
-  else if (typeof value === 'object')
-    TestRunner.addObject(/** @type {!Object} */ (value), customFormatters, prefix, prefixWithName);
-  else if (typeof value === 'string')
-    TestRunner.addResult(prefixWithName + '"' + value + '"');
-  else
-    TestRunner.addResult(prefixWithName + value);
-};
-
-/**
- * @param {!UI.TreeElement} treeElement
- */
-TestRunner.dumpObjectPropertyTreeElement = function(treeElement) {
-  const expandedSubstring = treeElement.expanded ? '[expanded]' : '[collapsed]';
-  TestRunner.addResult(expandedSubstring + ' ' + treeElement.listItemElement.deepTextContent());
-
-  for (let i = 0; i < treeElement.childCount(); ++i) {
-    const property = treeElement.childAt(i).property;
-    const key = property.name;
-    const value = property.value._description;
-    TestRunner.addResult('    ' + key + ': ' + value);
-  }
-};
-
-/**
- * @param {symbol} event
- * @param {!Common.Object} obj
- * @param {function(?):boolean=} condition
- * @return {!Promise}
- */
-TestRunner.waitForEvent = function(event, obj, condition) {
-  condition = condition || function() {
-    return true;
-  };
-  return new Promise(resolve => {
-    obj.addEventListener(event, onEventFired);
-
-    /**
-     * @param {!Common.Event} event
-     */
-    function onEventFired(event) {
-      if (!condition(event.data))
-        return;
-      obj.removeEventListener(event, onEventFired);
-      resolve(event.data);
-    }
-  });
-};
-
-/**
- * @param {function(!SDK.Target):boolean} filter
- * @return {!Promise<!SDK.Target>}
- */
-TestRunner.waitForTarget = function(filter) {
-  filter = filter || (target => true);
-  for (const target of SDK.targetManager.targets()) {
-    if (filter(target))
-      return Promise.resolve(target);
-  }
-  return new Promise(fulfill => {
-    const observer = /** @type {!SDK.TargetManager.Observer} */ ({
-      targetAdded: function(target) {
-        if (filter(target)) {
-          SDK.targetManager.unobserveTargets(observer);
-          fulfill(target);
-        }
-      },
-      targetRemoved: function() {},
-    });
-    SDK.targetManager.observeTargets(observer);
-  });
-};
-
-/**
- * @param {!SDK.RuntimeModel} runtimeModel
- * @return {!Promise}
- */
-TestRunner.waitForExecutionContext = function(runtimeModel) {
-  if (runtimeModel.executionContexts().length)
-    return Promise.resolve(runtimeModel.executionContexts()[0]);
-  return runtimeModel.once(SDK.RuntimeModel.Events.ExecutionContextCreated);
-};
-
-/**
- * @param {!SDK.ExecutionContext} context
- * @return {!Promise}
- */
-TestRunner.waitForExecutionContextDestroyed = function(context) {
-  const runtimeModel = context.runtimeModel;
-  if (runtimeModel.executionContexts().indexOf(context) === -1)
-    return Promise.resolve();
-  return TestRunner.waitForEvent(
-      SDK.RuntimeModel.Events.ExecutionContextDestroyed, runtimeModel,
-      destroyedContext => destroyedContext === context);
-};
-
-/**
- * @param {number} a
- * @param {number} b
- * @param {string=} message
- */
-TestRunner.assertGreaterOrEqual = function(a, b, message) {
-  if (a < b)
-    TestRunner.addResult('FAILED: ' + (message ? message + ': ' : '') + a + ' < ' + b);
-};
-
-/**
- * @param {string} url
- * @param {function():void} callback
- */
-TestRunner.navigate = function(url, callback) {
-  TestRunner._pageLoadedCallback = TestRunner.safeWrap(callback);
-  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, TestRunner._pageNavigated);
-  // Note: injected <base> means that url is relative to test
-  // and not the inspected page
-  TestRunner.evaluateInPageAnonymously('window.location.replace(\'' + url + '\')');
-};
-
-/**
- * @return {!Promise}
- */
-TestRunner.navigatePromise = function(url) {
-  return new Promise(fulfill => TestRunner.navigate(url, fulfill));
-};
-
-TestRunner._pageNavigated = function() {
-  TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, TestRunner._pageNavigated);
-  TestRunner._handlePageLoaded();
-};
-
-/**
- * @param {function():void} callback
- */
-TestRunner.hardReloadPage = function(callback) {
-  TestRunner._innerReloadPage(true, undefined, callback);
-};
-
-/**
- * @param {function():void} callback
- */
-TestRunner.reloadPage = function(callback) {
-  TestRunner._innerReloadPage(false, undefined, callback);
-};
-
-/**
- * @param {(string|undefined)} injectedScript
- * @param {function():void} callback
- */
-TestRunner.reloadPageWithInjectedScript = function(injectedScript, callback) {
-  TestRunner._innerReloadPage(false, injectedScript, callback);
-};
-
-/**
- * @return {!Promise}
- */
-TestRunner.reloadPagePromise = function() {
-  return new Promise(fulfill => TestRunner.reloadPage(fulfill));
-};
-
-/**
- * @param {boolean} hardReload
- * @param {(string|undefined)} injectedScript
- * @param {function():void} callback
- */
-TestRunner._innerReloadPage = function(hardReload, injectedScript, callback) {
-  TestRunner._pageLoadedCallback = TestRunner.safeWrap(callback);
-  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, TestRunner.pageLoaded);
-  TestRunner.resourceTreeModel.reloadPage(hardReload, injectedScript);
-};
-
-TestRunner.pageLoaded = function() {
-  TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, TestRunner.pageLoaded);
-  TestRunner.addResult('Page reloaded.');
-  TestRunner._handlePageLoaded();
-};
-
-TestRunner._handlePageLoaded = async function() {
-  await TestRunner.waitForExecutionContext(/** @type {!SDK.RuntimeModel} */ (TestRunner.runtimeModel));
-  if (TestRunner._pageLoadedCallback) {
-    const callback = TestRunner._pageLoadedCallback;
-    delete TestRunner._pageLoadedCallback;
-    callback();
-  }
-};
-
-/**
- * @param {function():void} callback
- */
-TestRunner.waitForPageLoad = function(callback) {
-  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, onLoaded);
-
-  function onLoaded() {
-    TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, onLoaded);
-    callback();
-  }
-};
-
-/**
- * @param {function():void} callback
- */
-TestRunner.runWhenPageLoads = function(callback) {
-  const oldCallback = TestRunner._pageLoadedCallback;
-  function chainedCallback() {
-    if (oldCallback)
-      oldCallback();
-    callback();
-  }
-  TestRunner._pageLoadedCallback = TestRunner.safeWrap(chainedCallback);
-};
-
-/**
- * @param {!Array<function(function():void)>} testSuite
- */
-TestRunner.runTestSuite = function(testSuite) {
-  const testSuiteTests = testSuite.slice();
-
-  function runner() {
-    if (!testSuiteTests.length) {
-      TestRunner.completeTest();
-      return;
-    }
-    const nextTest = testSuiteTests.shift();
-    TestRunner.addResult('');
-    TestRunner.addResult(
-        'Running: ' +
-        /function\s([^(]*)/.exec(nextTest)[1]);
-    TestRunner.safeWrap(nextTest)(runner);
-  }
-  runner();
-};
-
-/**
- * @param {*} expected
- * @param {*} found
- * @param {string} message
- */
-TestRunner.assertEquals = function(expected, found, message) {
-  if (expected === found)
-    return;
-
-  let error;
-  if (message)
-    error = 'Failure (' + message + '):';
-  else
-    error = 'Failure:';
-  throw new Error(error + ' expected <' + expected + '> found <' + found + '>');
-};
-
-/**
- * @param {*} found
- * @param {string} message
- */
-TestRunner.assertTrue = function(found, message) {
-  TestRunner.assertEquals(true, !!found, message);
-};
-
-/**
- * @param {!Object} receiver
- * @param {string} methodName
- * @param {!Function} override
- * @param {boolean=} opt_sticky
- * @return {!Function}
- */
-TestRunner.override = function(receiver, methodName, override, opt_sticky) {
-  override = TestRunner.safeWrap(override);
-
-  const original = receiver[methodName];
-  if (typeof original !== 'function')
-    throw new Error('Cannot find method to override: ' + methodName);
-
-  receiver[methodName] = function(var_args) {
-    try {
-      return override.apply(this, arguments);
-    } catch (e) {
-      throw new Error('Exception in overriden method \'' + methodName + '\': ' + e);
-    } finally {
-      if (!opt_sticky)
-        receiver[methodName] = original;
-    }
-  };
-
-  return original;
-};
-
-/**
- * @param {string} text
- * @return {string}
- */
-TestRunner.clearSpecificInfoFromStackFrames = function(text) {
-  let buffer = text.replace(/\(file:\/\/\/(?:[^)]+\)|[\w\/:-]+)/g, '(...)');
-  buffer = buffer.replace(/\(http:\/\/(?:[^)]+\)|[\w\/:-]+)/g, '(...)');
-  buffer = buffer.replace(/\(test:\/\/(?:[^)]+\)|[\w\/:-]+)/g, '(...)');
-  buffer = buffer.replace(/\(<anonymous>:[^)]+\)/g, '(...)');
-  buffer = buffer.replace(/VM\d+/g, 'VM');
-  return buffer.replace(/\s*at[^()]+\(native\)/g, '');
-};
-
-TestRunner.hideInspectorView = function() {
-  UI.inspectorView.element.setAttribute('style', 'display:none !important');
-};
-
-/**
- * @return {?SDK.ResourceTreeFrame}
- */
-TestRunner.mainFrame = function() {
-  return TestRunner.resourceTreeModel.mainFrame;
-};
-
-
-TestRunner.StringOutputStream = class {
-  /**
-   * @param {function(string):void} callback
-   */
-  constructor(callback) {
-    this._callback = callback;
-    this._buffer = '';
-  }
-
-  /**
-   * @param {string} fileName
-   * @return {!Promise<boolean>}
-   */
-  async open(fileName) {
-    return true;
-  }
-
-  /**
-   * @param {string} chunk
-   */
-  async write(chunk) {
-    this._buffer += chunk;
-  }
-
-  async close() {
-    this._callback(this._buffer);
-  }
-};
-
-/**
- * @template V
- */
-TestRunner.MockSetting = class {
-  /**
-   * @param {V} value
-   */
-  constructor(value) {
-    this._value = value;
-  }
-
-  /**
-   * @return {V}
-   */
-  get() {
-    return this._value;
-  }
-
-  /**
-   * @param {V} value
-   */
-  set(value) {
-    this._value = value;
-  }
-};
-
-/**
- * @return {!Array<!Runtime.Module>}
- */
-TestRunner.loadedModules = function() {
-  return self.runtime._modules.filter(module => module._loadedForTest)
-      .filter(module => module.name().indexOf('test_runner') === -1);
-};
-
-/**
- * @param {!Array<!Runtime.Module>} relativeTo
- * @return {!Array<!Runtime.Module>}
- */
-TestRunner.dumpLoadedModules = function(relativeTo) {
-  const previous = new Set(relativeTo || []);
-  function moduleSorter(left, right) {
-    return String.naturalOrderComparator(left._descriptor.name, right._descriptor.name);
-  }
-
-  TestRunner.addResult('Loaded modules:');
-  const loadedModules = TestRunner.loadedModules().sort(moduleSorter);
-  for (const module of loadedModules) {
-    if (previous.has(module))
-      continue;
-    TestRunner.addResult('    ' + module._descriptor.name);
-  }
-  return loadedModules;
-};
-
-/**
- * @param {!SDK.Target} target
- * @return {boolean}
- */
-TestRunner.isDedicatedWorker = function(target) {
-  return target && !target.hasBrowserCapability() && target.hasJSCapability() && !target.hasTargetCapability();
-};
-
-/**
- * @param {!SDK.Target} target
- * @return {boolean}
- */
-TestRunner.isServiceWorker = function(target) {
-  return target && !target.hasBrowserCapability() && !target.hasJSCapability() && target.hasNetworkCapability() &&
-      target.hasTargetCapability();
-};
-
-/**
- * @param {!SDK.Target} target
- * @return {string}
- */
-TestRunner.describeTargetType = function(target) {
-  if (TestRunner.isDedicatedWorker(target))
-    return 'worker';
-  if (TestRunner.isServiceWorker(target))
-    return 'service-worker';
-  if (!target.parentTarget())
-    return 'page';
-  return 'frame';
-};
-
-/**
- * @param {string} urlSuffix
- * @param {!Workspace.projectTypes=} projectType
- * @return {!Promise}
- */
-TestRunner.waitForUISourceCode = function(urlSuffix, projectType) {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  function matches(uiSourceCode) {
-    if (projectType && uiSourceCode.project().type() !== projectType)
-      return false;
-    if (!projectType && uiSourceCode.project().type() === Workspace.projectTypes.Service)
-      return false;
-    if (urlSuffix && !uiSourceCode.url().endsWith(urlSuffix))
-      return false;
-    return true;
-  }
-
-  for (const uiSourceCode of Workspace.workspace.uiSourceCodes()) {
-    if (urlSuffix && matches(uiSourceCode))
-      return Promise.resolve(uiSourceCode);
-  }
-
-  return TestRunner.waitForEvent(Workspace.Workspace.Events.UISourceCodeAdded, Workspace.workspace, matches);
-};
-
-/**
- * @param {!Function} callback
- */
-TestRunner.waitForUISourceCodeRemoved = function(callback) {
-  Workspace.workspace.once(Workspace.Workspace.Events.UISourceCodeRemoved).then(callback);
-};
-
-/**
- * @param {string=} url
- * @return {string}
- */
-TestRunner.url = function(url = '') {
-  const testScriptURL = /** @type {string} */ (Runtime.queryParam('test'));
-
-  // This handles relative (e.g. "../file"), root (e.g. "/resource"),
-  // absolute (e.g. "http://", "data:") and empty (e.g. "") paths
-  return new URL(url, testScriptURL + '/../').href;
-};
-
-/**
- * @param {string} str
- * @param {string} mimeType
- * @return {!Promise.<undefined>}
- * @suppressGlobalPropertiesCheck
- */
-TestRunner.dumpSyntaxHighlight = function(str, mimeType) {
-  const node = document.createElement('span');
-  node.textContent = str;
-  const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter(mimeType, false);
-  return javascriptSyntaxHighlighter.syntaxHighlightNode(node).then(dumpSyntax);
-
-  function dumpSyntax() {
-    const node_parts = [];
-
-    for (let i = 0; i < node.childNodes.length; i++) {
-      if (node.childNodes[i].getAttribute)
-        node_parts.push(node.childNodes[i].getAttribute('class'));
-      else
-        node_parts.push('*');
-    }
-
-    TestRunner.addResult(str + ': ' + node_parts.join(', '));
-  }
-};
-
-/**
- * @param {string} messageType
- */
-TestRunner._consoleOutputHook = function(messageType) {
-  TestRunner.addResult(messageType + ': ' + Array.prototype.slice.call(arguments, 1));
-};
-
-/**
- * This monkey patches console functions in DevTools context so the console
- * messages are shown in the right places, instead of having all of the console
- * messages printed at the top of the test expectation file (default behavior).
- */
-TestRunner._printDevToolsConsole = function() {
-  if (TestRunner._isDebugTest())
-    return;
-  console.log = TestRunner._consoleOutputHook.bind(TestRunner, 'log');
-  console.error = TestRunner._consoleOutputHook.bind(TestRunner, 'error');
-  console.info = TestRunner._consoleOutputHook.bind(TestRunner, 'info');
-};
-
-/**
- * @param {string} querySelector
- */
-TestRunner.dumpInspectedPageElementText = async function(querySelector) {
-  const value = await TestRunner.evaluateInPageAsync(`document.querySelector('${querySelector}').innerText`);
-  TestRunner.addResult(value);
-};
-
-/** @type {boolean} */
-TestRunner._startedTest = false;
-
-/**
- * @implements {SDK.TargetManager.Observer}
- */
-TestRunner._TestObserver = class {
-  /**
-   * @param {!SDK.Target} target
-   * @override
-   */
-  targetAdded(target) {
-    if (TestRunner._startedTest)
-      return;
-    TestRunner._startedTest = true;
-    TestRunner._setupTestHelpers(target);
-    if (TestRunner._isStartupTest())
-      return;
-    TestRunner
-        .loadHTML(`
-      <head>
-        <base href="${TestRunner.url()}">
-      </head>
-      <body>
-      </body>
-    `).then(() => TestRunner._executeTestScript());
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @override
-   */
-  targetRemoved(target) {
-  }
-};
-
-/**
- * @return {boolean}
- */
-TestRunner._isDebugTest = function() {
-  return !self.testRunner || !!Runtime.queryParam('debugFrontend');
-};
-
-/**
- * @return {boolean}
- */
-TestRunner._isStartupTest = function() {
-  return Runtime.queryParam('test').includes('/startup/');
-};
-
-(async function() {
-  /**
-   * @param {string|!Event} message
-   * @param {string} source
-   * @param {number} lineno
-   * @param {number} colno
-   * @param {!Error} error
-   */
-  function completeTestOnError(message, source, lineno, colno, error) {
-    TestRunner.addResult('TEST ENDED IN ERROR: ' + error.stack);
-    TestRunner.completeTest();
-  }
-
-  self['onerror'] = completeTestOnError;
-  TestRunner._printDevToolsConsole();
-  SDK.targetManager.observeTargets(new TestRunner._TestObserver());
-  if (!TestRunner._isStartupTest())
-    return;
-  /**
-   * Startup test initialization:
-   * 1. Wait for DevTools app UI to load
-   * 2. Execute test script, the first line will be TestRunner.setupStartupTest(...) which:
-   *    A. Navigate secondary window
-   *    B. After preconditions occur, secondary window calls testRunner.inspectSecondaryWindow()
-   * 3. Backend executes TestRunner._startupTestSetupFinished() which calls _initializeTarget()
-   */
-  TestRunner._initializeTargetForStartupTest =
-      TestRunner.override(Main.Main._instanceForTest, '_initializeTarget', () => undefined)
-          .bind(Main.Main._instanceForTest);
-  await TestRunner.addSnifferPromise(Main.Main._instanceForTest, '_showAppUI');
-  TestRunner._executeTestScript();
-})();
diff --git a/front_end/test_runner/module.json b/front_end/test_runner/module.json
deleted file mode 100644
index fc2b907..0000000
--- a/front_end/test_runner/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": [
-        "sdk",
-        "workspace",
-        "ui",
-        "host",
-        "main"
-    ],
-    "scripts": [
-        "TestRunner.js"
-    ]
-}
diff --git a/front_end/text_editor/CodeMirrorTextEditor.js b/front_end/text_editor/CodeMirrorTextEditor.js
deleted file mode 100644
index 2b74611..0000000
--- a/front_end/text_editor/CodeMirrorTextEditor.js
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.TextEditor}
- * @unrestricted
- */
-TextEditor.CodeMirrorTextEditor = class extends UI.VBox {
-  /**
-   * @param {!UI.TextEditor.Options} options
-   */
-  constructor(options) {
-    super();
-    this._options = options;
-
-    this.registerRequiredCSS('cm/codemirror.css');
-    this.registerRequiredCSS('text_editor/cmdevtools.css');
-
-    TextEditor.CodeMirrorUtils.appendThemeStyle(this.element);
-
-    this._codeMirror = new window.CodeMirror(this.element, {
-      lineNumbers: options.lineNumbers,
-      matchBrackets: true,
-      smartIndent: true,
-      styleSelectedText: true,
-      electricChars: true,
-      styleActiveLine: true,
-      indentUnit: 4,
-      lineWrapping: options.lineWrapping,
-      lineWiseCopyCut: false,
-      tabIndex: 0
-    });
-    this._codeMirrorElement = this.element.lastElementChild;
-
-    this._codeMirror._codeMirrorTextEditor = this;
-
-    CodeMirror.keyMap['devtools-common'] = {
-      'Left': 'goCharLeft',
-      'Right': 'goCharRight',
-      'Up': 'goLineUp',
-      'Down': 'goLineDown',
-      'End': 'goLineEnd',
-      'Home': 'goLineStartSmart',
-      'PageUp': 'goSmartPageUp',
-      'PageDown': 'goSmartPageDown',
-      'Delete': 'delCharAfter',
-      'Backspace': 'delCharBefore',
-      'Tab': 'defaultTab',
-      'Shift-Tab': 'indentLess',
-      'Enter': 'newlineAndIndent',
-      'Ctrl-Space': 'autocomplete',
-      'Esc': 'dismiss',
-      'Ctrl-M': 'gotoMatchingBracket'
-    };
-
-    CodeMirror.keyMap['devtools-pc'] = {
-      'Ctrl-A': 'selectAll',
-      'Ctrl-Z': 'undoAndReveal',
-      'Shift-Ctrl-Z': 'redoAndReveal',
-      'Ctrl-Y': 'redo',
-      'Ctrl-Home': 'goDocStart',
-      'Ctrl-Up': 'goDocStart',
-      'Ctrl-End': 'goDocEnd',
-      'Ctrl-Down': 'goDocEnd',
-      'Ctrl-Left': 'goGroupLeft',
-      'Ctrl-Right': 'goGroupRight',
-      'Alt-Left': 'moveCamelLeft',
-      'Alt-Right': 'moveCamelRight',
-      'Shift-Alt-Left': 'selectCamelLeft',
-      'Shift-Alt-Right': 'selectCamelRight',
-      'Ctrl-Backspace': 'delGroupBefore',
-      'Ctrl-Delete': 'delGroupAfter',
-      'Ctrl-/': 'toggleComment',
-      'Ctrl-D': 'selectNextOccurrence',
-      'Ctrl-U': 'undoLastSelection',
-      fallthrough: 'devtools-common'
-    };
-
-    CodeMirror.keyMap['devtools-mac'] = {
-      'Cmd-A': 'selectAll',
-      'Cmd-Z': 'undoAndReveal',
-      'Shift-Cmd-Z': 'redoAndReveal',
-      'Cmd-Up': 'goDocStart',
-      'Cmd-Down': 'goDocEnd',
-      'Alt-Left': 'goGroupLeft',
-      'Alt-Right': 'goGroupRight',
-      'Ctrl-Left': 'moveCamelLeft',
-      'Ctrl-Right': 'moveCamelRight',
-      'Ctrl-A': 'goLineLeft',
-      'Ctrl-E': 'goLineRight',
-      'Ctrl-B': 'goCharLeft',
-      'Ctrl-F': 'goCharRight',
-      'Ctrl-Alt-B': 'goGroupLeft',
-      'Ctrl-Alt-F': 'goGroupRight',
-      'Ctrl-H': 'delCharBefore',
-      'Ctrl-D': 'delCharAfter',
-      'Ctrl-K': 'killLine',
-      'Ctrl-T': 'transposeChars',
-      'Shift-Ctrl-Left': 'selectCamelLeft',
-      'Shift-Ctrl-Right': 'selectCamelRight',
-      'Cmd-Left': 'goLineStartSmart',
-      'Cmd-Right': 'goLineEnd',
-      'Cmd-Backspace': 'delLineLeft',
-      'Alt-Backspace': 'delGroupBefore',
-      'Alt-Delete': 'delGroupAfter',
-      'Cmd-/': 'toggleComment',
-      'Cmd-D': 'selectNextOccurrence',
-      'Cmd-U': 'undoLastSelection',
-      fallthrough: 'devtools-common'
-    };
-
-    if (options.bracketMatchingSetting)
-      options.bracketMatchingSetting.addChangeListener(this._enableBracketMatchingIfNeeded, this);
-    this._enableBracketMatchingIfNeeded();
-
-    this._codeMirror.setOption('keyMap', Host.isMac() ? 'devtools-mac' : 'devtools-pc');
-
-    this._codeMirror.setOption('flattenSpans', false);
-
-    let maxHighlightLength = options.maxHighlightLength;
-    if (typeof maxHighlightLength !== 'number')
-      maxHighlightLength = TextEditor.CodeMirrorTextEditor.maxHighlightLength;
-    this._codeMirror.setOption('maxHighlightLength', maxHighlightLength);
-    this._codeMirror.setOption('mode', null);
-    this._codeMirror.setOption('crudeMeasuringFrom', 1000);
-
-    this._shouldClearHistory = true;
-    this._lineSeparator = '\n';
-
-    TextEditor.CodeMirrorTextEditor._fixWordMovement(this._codeMirror);
-
-    this._selectNextOccurrenceController =
-        new TextEditor.CodeMirrorTextEditor.SelectNextOccurrenceController(this, this._codeMirror);
-
-    this._codeMirror.on('changes', this._changes.bind(this));
-    this._codeMirror.on('beforeSelectionChange', this._beforeSelectionChange.bind(this));
-    this._codeMirror.on('keyHandled', this._onKeyHandled.bind(this));
-
-    this.element.style.overflow = 'hidden';
-    this._codeMirrorElement.classList.add('source-code');
-    this._codeMirrorElement.classList.add('fill');
-
-    /** @type {!Multimap<number, !TextEditor.CodeMirrorTextEditor.Decoration>} */
-    this._decorations = new Multimap();
-
-    this.element.addEventListener('keydown', this._handleKeyDown.bind(this), true);
-    this.element.addEventListener('keydown', this._handlePostKeyDown.bind(this), false);
-
-    this._needsRefresh = true;
-
-    this._readOnly = false;
-
-    this._mimeType = '';
-    if (options.mimeType)
-      this.setMimeType(options.mimeType);
-    if (options.autoHeight)
-      this._codeMirror.setSize(null, 'auto');
-
-    this._placeholderElement = null;
-    if (options.placeholder) {
-      this._placeholderElement = createElement('pre');
-      this._placeholderElement.classList.add('placeholder-text');
-      this._placeholderElement.textContent = options.placeholder;
-      this._updatePlaceholder();
-    }
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   */
-  static autocompleteCommand(codeMirror) {
-    const autocompleteController = codeMirror._codeMirrorTextEditor._autocompleteController;
-    if (autocompleteController)
-      autocompleteController.autocomplete(true);
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   */
-  static undoLastSelectionCommand(codeMirror) {
-    codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.undoLastSelection();
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   */
-  static selectNextOccurrenceCommand(codeMirror) {
-    codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.selectNextOccurrence();
-  }
-
-  /**
-   * @param {boolean} shift
-   * @param {!CodeMirror} codeMirror
-   */
-  static moveCamelLeftCommand(shift, codeMirror) {
-    codeMirror._codeMirrorTextEditor._doCamelCaseMovement(-1, shift);
-  }
-
-  /**
-   * @param {boolean} shift
-   * @param {!CodeMirror} codeMirror
-   */
-  static moveCamelRightCommand(shift, codeMirror) {
-    codeMirror._codeMirrorTextEditor._doCamelCaseMovement(1, shift);
-  }
-
-  /**
-   * @param {string} modeName
-   * @param {string} tokenPrefix
-   */
-  static _overrideModeWithPrefixedTokens(modeName, tokenPrefix) {
-    const oldModeName = modeName + '-old';
-    if (CodeMirror.modes[oldModeName])
-      return;
-
-    CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]);
-    CodeMirror.defineMode(modeName, modeConstructor);
-
-    function modeConstructor(config, parserConfig) {
-      const innerConfig = {};
-      for (const i in parserConfig)
-        innerConfig[i] = parserConfig[i];
-      innerConfig.name = oldModeName;
-      const codeMirrorMode = CodeMirror.getMode(config, innerConfig);
-      codeMirrorMode.name = modeName;
-      codeMirrorMode.token = tokenOverride.bind(null, codeMirrorMode.token);
-      return codeMirrorMode;
-    }
-
-    function tokenOverride(superToken, stream, state) {
-      const token = superToken(stream, state);
-      return token ? tokenPrefix + token.split(/ +/).join(' ' + tokenPrefix) : token;
-    }
-  }
-
-  /**
-   * @param {string} mimeType
-   * @return {!Array<!Runtime.Extension>}}
-   */
-  static _collectUninstalledModes(mimeType) {
-    const installed = TextEditor.CodeMirrorTextEditor._loadedMimeModeExtensions;
-
-    const nameToExtension = new Map();
-    const extensions = self.runtime.extensions(TextEditor.CodeMirrorMimeMode);
-    for (const extension of extensions)
-      nameToExtension.set(extension.descriptor()['fileName'], extension);
-
-    const modesToLoad = new Set();
-    for (const extension of extensions) {
-      const descriptor = extension.descriptor();
-      if (installed.has(extension) || descriptor['mimeTypes'].indexOf(mimeType) === -1)
-        continue;
-
-      modesToLoad.add(extension);
-      const deps = descriptor['dependencies'] || [];
-      for (let i = 0; i < deps.length; ++i) {
-        const extension = nameToExtension.get(deps[i]);
-        if (extension && !installed.has(extension))
-          modesToLoad.add(extension);
-      }
-    }
-    return Array.from(modesToLoad);
-  }
-
-  /**
-   * @param {!Array<!Runtime.Extension>} extensions
-   * @return {!Promise}
-   */
-  static _installMimeTypeModes(extensions) {
-    const promises = extensions.map(extension => extension.instance().then(installMode.bind(null, extension)));
-    return Promise.all(promises);
-
-    /**
-     * @param {!Runtime.Extension} extension
-     * @param {!Object} instance
-     */
-    function installMode(extension, instance) {
-      if (TextEditor.CodeMirrorTextEditor._loadedMimeModeExtensions.has(extension))
-        return;
-      const mode = /** @type {!TextEditor.CodeMirrorMimeMode} */ (instance);
-      mode.install(extension);
-      TextEditor.CodeMirrorTextEditor._loadedMimeModeExtensions.add(extension);
-    }
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   */
-  static _fixWordMovement(codeMirror) {
-    function moveLeft(shift, codeMirror) {
-      codeMirror.setExtending(shift);
-      const cursor = codeMirror.getCursor('head');
-      codeMirror.execCommand('goGroupLeft');
-      const newCursor = codeMirror.getCursor('head');
-      if (newCursor.ch === 0 && newCursor.line !== 0) {
-        codeMirror.setExtending(false);
-        return;
-      }
-
-      const skippedText = codeMirror.getRange(newCursor, cursor, '#');
-      if (/^\s+$/.test(skippedText))
-        codeMirror.execCommand('goGroupLeft');
-      codeMirror.setExtending(false);
-    }
-
-    function moveRight(shift, codeMirror) {
-      codeMirror.setExtending(shift);
-      const cursor = codeMirror.getCursor('head');
-      codeMirror.execCommand('goGroupRight');
-      const newCursor = codeMirror.getCursor('head');
-      if (newCursor.ch === 0 && newCursor.line !== 0) {
-        codeMirror.setExtending(false);
-        return;
-      }
-
-      const skippedText = codeMirror.getRange(cursor, newCursor, '#');
-      if (/^\s+$/.test(skippedText))
-        codeMirror.execCommand('goGroupRight');
-      codeMirror.setExtending(false);
-    }
-
-    const modifierKey = Host.isMac() ? 'Alt' : 'Ctrl';
-    const leftKey = modifierKey + '-Left';
-    const rightKey = modifierKey + '-Right';
-    const keyMap = {};
-    keyMap[leftKey] = moveLeft.bind(null, false);
-    keyMap[rightKey] = moveRight.bind(null, false);
-    keyMap['Shift-' + leftKey] = moveLeft.bind(null, true);
-    keyMap['Shift-' + rightKey] = moveRight.bind(null, true);
-    codeMirror.addKeyMap(keyMap);
-  }
-
-  /**
-   * @protected
-   * @return {!CodeMirror}
-   */
-  codeMirror() {
-    return this._codeMirror;
-  }
-
-  /**
-   * @override
-   * @return {!UI.Widget}
-   */
-  widget() {
-    return this;
-  }
-
-  _onKeyHandled() {
-    UI.shortcutRegistry.dismissPendingShortcutAction();
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} lineLength
-   * @param {number} charNumber
-   * @return {{lineNumber: number, columnNumber: number}}
-   */
-  _normalizePositionForOverlappingColumn(lineNumber, lineLength, charNumber) {
-    const linesCount = this._codeMirror.lineCount();
-    let columnNumber = charNumber;
-    if (charNumber < 0 && lineNumber > 0) {
-      --lineNumber;
-      columnNumber = this.line(lineNumber).length;
-    } else if (charNumber >= lineLength && lineNumber < linesCount - 1) {
-      ++lineNumber;
-      columnNumber = 0;
-    } else {
-      columnNumber = Number.constrain(charNumber, 0, lineLength);
-    }
-    return {lineNumber: lineNumber, columnNumber: columnNumber};
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {number} direction
-   * @return {{lineNumber: number, columnNumber: number}}
-   */
-  _camelCaseMoveFromPosition(lineNumber, columnNumber, direction) {
-    /**
-     * @param {number} charNumber
-     * @param {number} length
-     * @return {boolean}
-     */
-    function valid(charNumber, length) {
-      return charNumber >= 0 && charNumber < length;
-    }
-
-    /**
-     * @param {string} text
-     * @param {number} charNumber
-     * @return {boolean}
-     */
-    function isWordStart(text, charNumber) {
-      const position = charNumber;
-      const nextPosition = charNumber + 1;
-      return valid(position, text.length) && valid(nextPosition, text.length) &&
-          TextUtils.TextUtils.isWordChar(text[position]) && TextUtils.TextUtils.isWordChar(text[nextPosition]) &&
-          TextUtils.TextUtils.isUpperCase(text[position]) && TextUtils.TextUtils.isLowerCase(text[nextPosition]);
-    }
-
-    /**
-     * @param {string} text
-     * @param {number} charNumber
-     * @return {boolean}
-     */
-    function isWordEnd(text, charNumber) {
-      const position = charNumber;
-      const prevPosition = charNumber - 1;
-      return valid(position, text.length) && valid(prevPosition, text.length) &&
-          TextUtils.TextUtils.isWordChar(text[position]) && TextUtils.TextUtils.isWordChar(text[prevPosition]) &&
-          TextUtils.TextUtils.isUpperCase(text[position]) && TextUtils.TextUtils.isLowerCase(text[prevPosition]);
-    }
-
-    /**
-     * @param {number} lineNumber
-     * @param {number} lineLength
-     * @param {number} columnNumber
-     * @return {{lineNumber: number, columnNumber: number}}
-     */
-    function constrainPosition(lineNumber, lineLength, columnNumber) {
-      return {lineNumber: lineNumber, columnNumber: Number.constrain(columnNumber, 0, lineLength)};
-    }
-
-    const text = this.line(lineNumber);
-    const length = text.length;
-
-    if ((columnNumber === length && direction === 1) || (columnNumber === 0 && direction === -1))
-      return this._normalizePositionForOverlappingColumn(lineNumber, length, columnNumber + direction);
-
-    let charNumber = direction === 1 ? columnNumber : columnNumber - 1;
-
-    // Move through initial spaces if any.
-    while (valid(charNumber, length) && TextUtils.TextUtils.isSpaceChar(text[charNumber]))
-      charNumber += direction;
-    if (!valid(charNumber, length))
-      return constrainPosition(lineNumber, length, charNumber);
-
-    if (TextUtils.TextUtils.isStopChar(text[charNumber])) {
-      while (valid(charNumber, length) && TextUtils.TextUtils.isStopChar(text[charNumber]))
-        charNumber += direction;
-      if (!valid(charNumber, length))
-        return constrainPosition(lineNumber, length, charNumber);
-      return {lineNumber: lineNumber, columnNumber: direction === -1 ? charNumber + 1 : charNumber};
-    }
-
-    charNumber += direction;
-    while (valid(charNumber, length) && !isWordStart(text, charNumber) && !isWordEnd(text, charNumber) &&
-           TextUtils.TextUtils.isWordChar(text[charNumber]))
-      charNumber += direction;
-
-    if (!valid(charNumber, length))
-      return constrainPosition(lineNumber, length, charNumber);
-    if (isWordStart(text, charNumber) || isWordEnd(text, charNumber))
-      return {lineNumber: lineNumber, columnNumber: charNumber};
-
-
-    return {lineNumber: lineNumber, columnNumber: direction === -1 ? charNumber + 1 : charNumber};
-  }
-
-  /**
-   * @param {number} direction
-   * @param {boolean} shift
-   */
-  _doCamelCaseMovement(direction, shift) {
-    const selections = this.selections();
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const move = this._camelCaseMoveFromPosition(selection.endLine, selection.endColumn, direction);
-      selection.endLine = move.lineNumber;
-      selection.endColumn = move.columnNumber;
-      if (!shift)
-        selections[i] = selection.collapseToEnd();
-    }
-    this.setSelections(selections);
-  }
-
-  dispose() {
-    if (this._options.bracketMatchingSetting)
-      this._options.bracketMatchingSetting.removeChangeListener(this._enableBracketMatchingIfNeeded, this);
-  }
-
-  _enableBracketMatchingIfNeeded() {
-    this._codeMirror.setOption(
-        'autoCloseBrackets', (this._options.bracketMatchingSetting && this._options.bracketMatchingSetting.get()) ?
-            {explode: false} :
-            false);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._needsRefresh)
-      this.refresh();
-  }
-
-  /**
-   * @protected
-   */
-  refresh() {
-    if (this.isShowing()) {
-      this._codeMirror.refresh();
-      this._needsRefresh = false;
-      return;
-    }
-    this._needsRefresh = true;
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    delete this._editorSizeInSync;
-  }
-
-  undo() {
-    this._codeMirror.undo();
-  }
-
-  redo() {
-    this._codeMirror.redo();
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _handleKeyDown(e) {
-    if (this._autocompleteController && this._autocompleteController.keyDown(e))
-      e.consume(true);
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _handlePostKeyDown(e) {
-    if (e.defaultPrevented)
-      e.consume(true);
-  }
-
-  /**
-   * @override
-   * @param {?UI.AutocompleteConfig} config
-   */
-  configureAutocomplete(config) {
-    if (this._autocompleteController) {
-      this._autocompleteController.dispose();
-      delete this._autocompleteController;
-    }
-
-    if (config)
-      this._autocompleteController = new TextEditor.TextEditorAutocompleteController(this, this._codeMirror, config);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} column
-   * @return {?{x: number, y: number, height: number}}
-   */
-  cursorPositionToCoordinates(lineNumber, column) {
-    if (lineNumber >= this._codeMirror.lineCount() || lineNumber < 0 || column < 0 ||
-        column > this._codeMirror.getLine(lineNumber).length)
-      return null;
-    const metrics = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, column));
-    return {x: metrics.left, y: metrics.top, height: metrics.bottom - metrics.top};
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @return {?TextUtils.TextRange}
-   */
-  coordinatesToCursorPosition(x, y) {
-    const element = this.element.ownerDocument.elementFromPoint(x, y);
-    if (!element || !element.isSelfOrDescendant(this._codeMirror.getWrapperElement()))
-      return null;
-    const gutterBox = this._codeMirror.getGutterElement().boxInWindow();
-    if (x >= gutterBox.x && x <= gutterBox.x + gutterBox.width && y >= gutterBox.y &&
-        y <= gutterBox.y + gutterBox.height)
-      return null;
-    const coords = this._codeMirror.coordsChar({left: x, top: y});
-    return TextEditor.CodeMirrorUtils.toRange(coords, coords);
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {!{x: number, y: number}}
-   */
-  visualCoordinates(lineNumber, columnNumber) {
-    const metrics = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, columnNumber));
-    return {x: metrics.left, y: metrics.top};
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?{startColumn: number, endColumn: number, type: string}}
-   */
-  tokenAtTextPosition(lineNumber, columnNumber) {
-    if (lineNumber < 0 || lineNumber >= this._codeMirror.lineCount())
-      return null;
-    const token = this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber, (columnNumber || 0) + 1));
-    if (!token)
-      return null;
-    return {startColumn: token.start, endColumn: token.end, type: token.type};
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isClean() {
-    return this._codeMirror.isClean();
-  }
-
-  markClean() {
-    this._codeMirror.markClean();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _hasLongLines() {
-    function lineIterator(lineHandle) {
-      if (lineHandle.text.length > TextEditor.CodeMirrorTextEditor.LongLineModeLineLengthThreshold)
-        hasLongLines = true;
-      return hasLongLines;
-    }
-    let hasLongLines = false;
-    this._codeMirror.eachLine(lineIterator);
-    return hasLongLines;
-  }
-
-  _enableLongLinesMode() {
-    this._codeMirror.setOption('styleSelectedText', false);
-  }
-
-  _disableLongLinesMode() {
-    this._codeMirror.setOption('styleSelectedText', true);
-  }
-
-  /**
-   * @param {string} mimeType
-   */
-  setMimeType(mimeType) {
-    this._mimeType = mimeType;
-    const modesToLoad = TextEditor.CodeMirrorTextEditor._collectUninstalledModes(mimeType);
-
-    if (!modesToLoad.length)
-      setMode.call(this);
-    else
-      TextEditor.CodeMirrorTextEditor._installMimeTypeModes(modesToLoad).then(setMode.bind(this));
-
-    /**
-     * @this {TextEditor.CodeMirrorTextEditor}
-     */
-    function setMode() {
-      const rewrittenMimeType = this.rewriteMimeType(mimeType);
-      if (this._codeMirror.options.mode !== rewrittenMimeType)
-        this._codeMirror.setOption('mode', rewrittenMimeType);
-    }
-  }
-
-  /**
-   * @param {!Object} mode
-   */
-  setHighlightMode(mode) {
-    this._mimeType = '';
-    this._codeMirror.setOption('mode', mode);
-  }
-
-  /**
-   * @protected
-   * @param {string} mimeType
-   */
-  rewriteMimeType(mimeType) {
-    // Overridden in SourcesTextEditor
-    return mimeType;
-  }
-
-  /**
-   * @protected
-   * @return {string}
-   */
-  mimeType() {
-    return this._mimeType;
-  }
-
-  /**
-   * @param {boolean} readOnly
-   */
-  setReadOnly(readOnly) {
-    if (this._readOnly === readOnly)
-      return;
-    this.clearPositionHighlight();
-    this._readOnly = readOnly;
-    this.element.classList.toggle('CodeMirror-readonly', readOnly);
-    this._codeMirror.setOption('readOnly', readOnly);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  readOnly() {
-    return !!this._codeMirror.getOption('readOnly');
-  }
-
-  /**
-   * @param {function(number):string} formatter
-   */
-  setLineNumberFormatter(formatter) {
-    this._codeMirror.setOption('lineNumberFormatter', formatter);
-  }
-
-  /**
-   * @override
-   * @param {function(!KeyboardEvent)} handler
-   */
-  addKeyDownHandler(handler) {
-    this._codeMirror.on('keydown', (CodeMirror, event) => handler(event));
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @param {!Element} element
-   * @param {symbol} type
-   * @param {boolean=} insertBefore
-   * @return {!TextEditor.TextEditorBookMark}
-   */
-  addBookmark(lineNumber, columnNumber, element, type, insertBefore) {
-    const bookmark = new TextEditor.TextEditorBookMark(
-        this._codeMirror.setBookmark(
-            new CodeMirror.Pos(lineNumber, columnNumber), {widget: element, insertLeft: insertBefore}),
-        type, this);
-    this._updateDecorations(lineNumber);
-    return bookmark;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {symbol=} type
-   * @return {!Array.<!TextEditor.TextEditorBookMark>}
-   */
-  bookmarks(range, type) {
-    const pos = TextEditor.CodeMirrorUtils.toPos(range);
-    let markers = this._codeMirror.findMarksAt(pos.start);
-    if (!range.isEmpty()) {
-      const middleMarkers = this._codeMirror.findMarks(pos.start, pos.end);
-      const endMarkers = this._codeMirror.findMarksAt(pos.end);
-      markers = markers.concat(middleMarkers, endMarkers);
-    }
-    const bookmarks = [];
-    for (let i = 0; i < markers.length; i++) {
-      const bookmark = markers[i][TextEditor.TextEditorBookMark._symbol];
-      if (bookmark && (!type || bookmark.type() === type))
-        bookmarks.push(bookmark);
-    }
-    return bookmarks;
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    this._codeMirror.focus();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasFocus() {
-    return this._codeMirror.hasFocus();
-  }
-
-  /**
-   * @param {function()} operation
-   */
-  operation(operation) {
-    this._codeMirror.operation(operation);
-  }
-
-  /**
-   * @param {number} lineNumber
-   */
-  scrollLineIntoView(lineNumber) {
-    this._innerRevealLine(lineNumber, this._codeMirror.getScrollInfo());
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {!{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}} scrollInfo
-   */
-  _innerRevealLine(lineNumber, scrollInfo) {
-    const topLine = this._codeMirror.lineAtHeight(scrollInfo.top, 'local');
-    const bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, 'local');
-    const linesPerScreen = bottomLine - topLine + 1;
-    if (lineNumber < topLine) {
-      const topLineToReveal = Math.max(lineNumber - (linesPerScreen / 2) + 1, 0) | 0;
-      this._codeMirror.scrollIntoView(new CodeMirror.Pos(topLineToReveal, 0));
-    } else if (lineNumber > bottomLine) {
-      const bottomLineToReveal = Math.min(lineNumber + (linesPerScreen / 2) - 1, this.linesCount - 1) | 0;
-      this._codeMirror.scrollIntoView(new CodeMirror.Pos(bottomLineToReveal, 0));
-    }
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {number} lineNumber
-   * @param {number=} startColumn
-   * @param {number=} endColumn
-   */
-  addDecoration(element, lineNumber, startColumn, endColumn) {
-    const widget = this._codeMirror.addLineWidget(lineNumber, element);
-    let update = null;
-    if (typeof startColumn !== 'undefined') {
-      if (typeof endColumn === 'undefined')
-        endColumn = Infinity;
-      update = this._updateFloatingDecoration.bind(this, element, lineNumber, startColumn, endColumn);
-      update();
-    }
-
-    this._decorations.set(lineNumber, {element: element, update: update, widget: widget});
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {number} lineNumber
-   * @param {number} startColumn
-   * @param {number} endColumn
-   */
-  _updateFloatingDecoration(element, lineNumber, startColumn, endColumn) {
-    const base = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, 0), 'page');
-    const start = this._codeMirror.cursorCoords(new CodeMirror.Pos(lineNumber, startColumn), 'page');
-    const end = this._codeMirror.charCoords(new CodeMirror.Pos(lineNumber, endColumn), 'page');
-    element.style.width = (end.right - start.left) + 'px';
-    element.style.left = (start.left - base.left) + 'px';
-  }
-
-  /**
-   * @param {number} lineNumber
-   */
-  _updateDecorations(lineNumber) {
-    this._decorations.get(lineNumber).forEach(innerUpdateDecorations);
-
-    /**
-     * @param {!TextEditor.CodeMirrorTextEditor.Decoration} decoration
-     */
-    function innerUpdateDecorations(decoration) {
-      if (decoration.update)
-        decoration.update();
-    }
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {number} lineNumber
-   */
-  removeDecoration(element, lineNumber) {
-    this._decorations.get(lineNumber).forEach(innerRemoveDecoration.bind(this));
-
-    /**
-     * @this {TextEditor.CodeMirrorTextEditor}
-     * @param {!TextEditor.CodeMirrorTextEditor.Decoration} decoration
-     */
-    function innerRemoveDecoration(decoration) {
-      if (decoration.element !== element)
-        return;
-      this._codeMirror.removeLineWidget(decoration.widget);
-      this._decorations.delete(lineNumber, decoration);
-    }
-  }
-
-  /**
-   * @param {number} lineNumber 0-based
-   * @param {number=} columnNumber
-   * @param {boolean=} shouldHighlight
-   */
-  revealPosition(lineNumber, columnNumber, shouldHighlight) {
-    lineNumber = Number.constrain(lineNumber, 0, this._codeMirror.lineCount() - 1);
-    if (typeof columnNumber !== 'number')
-      columnNumber = 0;
-    columnNumber = Number.constrain(columnNumber, 0, this._codeMirror.getLine(lineNumber).length);
-
-    this.clearPositionHighlight();
-    this._highlightedLine = this._codeMirror.getLineHandle(lineNumber);
-    if (!this._highlightedLine)
-      return;
-    this.scrollLineIntoView(lineNumber);
-    if (shouldHighlight) {
-      this._codeMirror.addLineClass(
-          this._highlightedLine, null, this._readOnly ? 'cm-readonly-highlight' : 'cm-highlight');
-      if (!this._readOnly)
-        this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
-    }
-    this.setSelection(TextUtils.TextRange.createFromLocation(lineNumber, columnNumber));
-  }
-
-  clearPositionHighlight() {
-    if (this._clearHighlightTimeout)
-      clearTimeout(this._clearHighlightTimeout);
-    delete this._clearHighlightTimeout;
-
-    if (this._highlightedLine) {
-      this._codeMirror.removeLineClass(
-          this._highlightedLine, null, this._readOnly ? 'cm-readonly-highlight' : 'cm-highlight');
-    }
-    delete this._highlightedLine;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [];
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  _updatePaddingBottom(width, height) {
-    if (!this._options.padBottom)
-      return;
-    const scrollInfo = this._codeMirror.getScrollInfo();
-    let newPaddingBottom;
-    const linesElement = this._codeMirrorElement.querySelector('.CodeMirror-lines');
-    const lineCount = this._codeMirror.lineCount();
-    if (lineCount <= 1) {
-      newPaddingBottom = 0;
-    } else {
-      newPaddingBottom =
-          Math.max(scrollInfo.clientHeight - this._codeMirror.getLineHandle(this._codeMirror.lastLine()).height, 0);
-    }
-    newPaddingBottom += 'px';
-    linesElement.style.paddingBottom = newPaddingBottom;
-    this._codeMirror.setSize(width, height);
-  }
-
-  _resizeEditor() {
-    const parentElement = this.element.parentElement;
-    if (!parentElement || !this.isShowing())
-      return;
-    this._codeMirror.operation(() => {
-      const scrollLeft = this._codeMirror.doc.scrollLeft;
-      const scrollTop = this._codeMirror.doc.scrollTop;
-      const width = parentElement.offsetWidth;
-      const height = parentElement.offsetHeight - this.element.offsetTop;
-      if (this._options.autoHeight) {
-        this._codeMirror.setSize(width, 'auto');
-      } else {
-        this._codeMirror.setSize(width, height);
-        this._updatePaddingBottom(width, height);
-      }
-      this._codeMirror.scrollTo(scrollLeft, scrollTop);
-    });
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._autocompleteController)
-      this._autocompleteController.clearAutocomplete();
-    this._resizeEditor();
-    this._editorSizeInSync = true;
-    if (this._selectionSetScheduled) {
-      delete this._selectionSetScheduled;
-      this.setSelection(this._lastSelection);
-    }
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {string} text
-   * @param {string=} origin
-   * @return {!TextUtils.TextRange}
-   */
-  editRange(range, text, origin) {
-    const pos = TextEditor.CodeMirrorUtils.toPos(range);
-    this._codeMirror.replaceRange(text, pos.start, pos.end, origin);
-    const newRange = TextEditor.CodeMirrorUtils.toRange(
-        pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length));
-    this.dispatchEventToListeners(UI.TextEditor.Events.TextChanged, {oldRange: range, newRange: newRange});
-    return newRange;
-  }
-
-  /**
-   * @override
-   */
-  clearAutocomplete() {
-    if (this._autocompleteController)
-      this._autocompleteController.clearAutocomplete();
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} column
-   * @param {function(string):boolean} isWordChar
-   * @return {!TextUtils.TextRange}
-   */
-  wordRangeForCursorPosition(lineNumber, column, isWordChar) {
-    const line = this.line(lineNumber);
-    let wordStart = column;
-    if (column !== 0 && isWordChar(line.charAt(column - 1))) {
-      wordStart = column - 1;
-      while (wordStart > 0 && isWordChar(line.charAt(wordStart - 1)))
-        --wordStart;
-    }
-    let wordEnd = column;
-    while (wordEnd < line.length && isWordChar(line.charAt(wordEnd)))
-      ++wordEnd;
-    return new TextUtils.TextRange(lineNumber, wordStart, lineNumber, wordEnd);
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   * @param {!Array.<!CodeMirror.ChangeObject>} changes
-   */
-  _changes(codeMirror, changes) {
-    if (!changes.length)
-      return;
-
-    this._updatePlaceholder();
-
-    // We do not show "scroll beyond end of file" span for one line documents, so we need to check if "document has one line" changed.
-    const hasOneLine = this._codeMirror.lineCount() === 1;
-    if (hasOneLine !== this._hasOneLine)
-      this._resizeEditor();
-    this._hasOneLine = hasOneLine;
-
-    this._decorations.valuesArray().forEach(decoration => this._codeMirror.removeLineWidget(decoration.widget));
-    this._decorations.clear();
-
-    const edits = [];
-    let currentEdit;
-
-    for (let changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
-      const changeObject = changes[changeIndex];
-      const edit = TextEditor.CodeMirrorUtils.changeObjectToEditOperation(changeObject);
-      if (currentEdit && edit.oldRange.equal(currentEdit.newRange)) {
-        currentEdit.newRange = edit.newRange;
-      } else {
-        currentEdit = edit;
-        edits.push(currentEdit);
-      }
-    }
-
-    for (let i = 0; i < edits.length; i++) {
-      this.dispatchEventToListeners(
-          UI.TextEditor.Events.TextChanged, {oldRange: edits[i].oldRange, newRange: edits[i].newRange});
-    }
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   * @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>}} selection
-   */
-  _beforeSelectionChange(codeMirror, selection) {
-    this._selectNextOccurrenceController.selectionWillChange();
-  }
-
-  /**
-   * @param {number} lineNumber
-   */
-  scrollToLine(lineNumber) {
-    const pos = new CodeMirror.Pos(lineNumber, 0);
-    const coords = this._codeMirror.charCoords(pos, 'local');
-    this._codeMirror.scrollTo(0, coords.top);
-  }
-
-  /**
-   * @return {number}
-   */
-  firstVisibleLine() {
-    return this._codeMirror.lineAtHeight(this._codeMirror.getScrollInfo().top, 'local');
-  }
-
-  /**
-   * @return {number}
-   */
-  scrollTop() {
-    return this._codeMirror.getScrollInfo().top;
-  }
-
-  /**
-   * @param {number} scrollTop
-   */
-  setScrollTop(scrollTop) {
-    this._codeMirror.scrollTo(0, scrollTop);
-  }
-
-  /**
-   * @return {number}
-   */
-  lastVisibleLine() {
-    const scrollInfo = this._codeMirror.getScrollInfo();
-    return this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, 'local');
-  }
-
-  /**
-   * @override
-   * @return {!TextUtils.TextRange}
-   */
-  selection() {
-    const start = this._codeMirror.getCursor('anchor');
-    const end = this._codeMirror.getCursor('head');
-
-    return TextEditor.CodeMirrorUtils.toRange(start, end);
-  }
-
-  /**
-   * @return {!Array.<!TextUtils.TextRange>}
-   */
-  selections() {
-    const selectionList = this._codeMirror.listSelections();
-    const result = [];
-    for (let i = 0; i < selectionList.length; ++i) {
-      const selection = selectionList[i];
-      result.push(TextEditor.CodeMirrorUtils.toRange(selection.anchor, selection.head));
-    }
-    return result;
-  }
-
-  /**
-   * @return {?TextUtils.TextRange}
-   */
-  lastSelection() {
-    return this._lastSelection;
-  }
-
-  /**
-   * @override
-   * @param {!TextUtils.TextRange} textRange
-   */
-  setSelection(textRange) {
-    this._lastSelection = textRange;
-    if (!this._editorSizeInSync) {
-      this._selectionSetScheduled = true;
-      return;
-    }
-    const pos = TextEditor.CodeMirrorUtils.toPos(textRange);
-    this._codeMirror.setSelection(pos.start, pos.end);
-  }
-
-  /**
-   * @param {!Array.<!TextUtils.TextRange>} ranges
-   * @param {number=} primarySelectionIndex
-   */
-  setSelections(ranges, primarySelectionIndex) {
-    const selections = [];
-    for (let i = 0; i < ranges.length; ++i) {
-      const selection = TextEditor.CodeMirrorUtils.toPos(ranges[i]);
-      selections.push({anchor: selection.start, head: selection.end});
-    }
-    primarySelectionIndex = primarySelectionIndex || 0;
-    this._codeMirror.setSelections(selections, primarySelectionIndex, {scroll: false});
-  }
-
-  /**
-   * @param {string} text
-   */
-  _detectLineSeparator(text) {
-    this._lineSeparator = text.indexOf('\r\n') >= 0 ? '\r\n' : '\n';
-  }
-
-  /**
-   * @override
-   * @param {string} text
-   */
-  setText(text) {
-    if (text.length > TextEditor.CodeMirrorTextEditor.MaxEditableTextSize) {
-      this.configureAutocomplete(null);
-      this.setReadOnly(true);
-    }
-    this._codeMirror.setValue(text);
-    if (this._shouldClearHistory) {
-      this._codeMirror.clearHistory();
-      this._shouldClearHistory = false;
-    }
-    this._detectLineSeparator(text);
-
-    if (this._hasLongLines())
-      this._enableLongLinesMode();
-    else
-      this._disableLongLinesMode();
-  }
-
-  /**
-   * @override
-   * @param {!TextUtils.TextRange=} textRange
-   * @return {string}
-   */
-  text(textRange) {
-    if (!textRange)
-      return this._codeMirror.getValue(this._lineSeparator);
-    const pos = TextEditor.CodeMirrorUtils.toPos(textRange.normalize());
-    return this._codeMirror.getRange(pos.start, pos.end, this._lineSeparator);
-  }
-
-  /**
-   * @override
-   * @return {!TextUtils.TextRange}
-   */
-  fullRange() {
-    const lineCount = this.linesCount;
-    const lastLine = this._codeMirror.getLine(lineCount - 1);
-    return TextEditor.CodeMirrorUtils.toRange(
-        new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length));
-  }
-
-  /**
-   * @override
-   * @param {number} lineNumber
-   * @return {string}
-   */
-  line(lineNumber) {
-    return this._codeMirror.getLine(lineNumber);
-  }
-
-  /**
-   * @return {number}
-   */
-  get linesCount() {
-    return this._codeMirror.lineCount();
-  }
-
-  /**
-   * @override
-   */
-  newlineAndIndent() {
-    this._codeMirror.execCommand('newlineAndIndent');
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {!TextEditor.TextEditorPositionHandle}
-   */
-  textEditorPositionHandle(lineNumber, columnNumber) {
-    return new TextEditor.CodeMirrorPositionHandle(this._codeMirror, new CodeMirror.Pos(lineNumber, columnNumber));
-  }
-
-  _updatePlaceholder() {
-    if (!this._placeholderElement)
-      return;
-
-    this._placeholderElement.remove();
-
-    if (this.linesCount === 1 && !this.line(0)) {
-      this._codeMirror.display.lineSpace.insertBefore(
-          this._placeholderElement, this._codeMirror.display.lineSpace.firstChild);
-    }
-  }
-};
-
-TextEditor.CodeMirrorTextEditor.maxHighlightLength = 1000;
-
-
-CodeMirror.commands.autocomplete = TextEditor.CodeMirrorTextEditor.autocompleteCommand;
-
-
-CodeMirror.commands.undoLastSelection = TextEditor.CodeMirrorTextEditor.undoLastSelectionCommand;
-
-
-CodeMirror.commands.selectNextOccurrence = TextEditor.CodeMirrorTextEditor.selectNextOccurrenceCommand;
-
-
-CodeMirror.commands.moveCamelLeft = TextEditor.CodeMirrorTextEditor.moveCamelLeftCommand.bind(null, false);
-CodeMirror.commands.selectCamelLeft = TextEditor.CodeMirrorTextEditor.moveCamelLeftCommand.bind(null, true);
-
-
-CodeMirror.commands.moveCamelRight = TextEditor.CodeMirrorTextEditor.moveCamelRightCommand.bind(null, false);
-CodeMirror.commands.selectCamelRight = TextEditor.CodeMirrorTextEditor.moveCamelRightCommand.bind(null, true);
-
-/**
- * @param {!CodeMirror} codeMirror
- */
-CodeMirror.commands.gotoMatchingBracket = function(codeMirror) {
-  const updatedSelections = [];
-  const selections = codeMirror.listSelections();
-  for (let i = 0; i < selections.length; ++i) {
-    const selection = selections[i];
-    const cursor = selection.head;
-    const matchingBracket = codeMirror.findMatchingBracket(cursor, false, {maxScanLines: 10000});
-    let updatedHead = cursor;
-    if (matchingBracket && matchingBracket.match) {
-      const columnCorrection = CodeMirror.cmpPos(matchingBracket.from, cursor) === 0 ? 1 : 0;
-      updatedHead = new CodeMirror.Pos(matchingBracket.to.line, matchingBracket.to.ch + columnCorrection);
-    }
-    updatedSelections.push({anchor: updatedHead, head: updatedHead});
-  }
-  codeMirror.setSelections(updatedSelections);
-};
-
-/**
- * @param {!CodeMirror} codemirror
- */
-CodeMirror.commands.undoAndReveal = function(codemirror) {
-  const scrollInfo = codemirror.getScrollInfo();
-  codemirror.execCommand('undo');
-  const cursor = codemirror.getCursor('start');
-  codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
-  const autocompleteController = codemirror._codeMirrorTextEditor._autocompleteController;
-  if (autocompleteController)
-    autocompleteController.clearAutocomplete();
-};
-
-/**
- * @param {!CodeMirror} codemirror
- */
-CodeMirror.commands.redoAndReveal = function(codemirror) {
-  const scrollInfo = codemirror.getScrollInfo();
-  codemirror.execCommand('redo');
-  const cursor = codemirror.getCursor('start');
-  codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
-  const autocompleteController = codemirror._codeMirrorTextEditor._autocompleteController;
-  if (autocompleteController)
-    autocompleteController.clearAutocomplete();
-};
-
-/**
- * @return {!Object|undefined}
- */
-CodeMirror.commands.dismiss = function(codemirror) {
-  const selections = codemirror.listSelections();
-  const selection = selections[0];
-  if (selections.length === 1) {
-    if (TextEditor.CodeMirrorUtils.toRange(selection.anchor, selection.head).isEmpty())
-      return CodeMirror.Pass;
-    codemirror.setSelection(selection.anchor, selection.anchor, {scroll: false});
-    codemirror._codeMirrorTextEditor.scrollLineIntoView(selection.anchor.line);
-    return;
-  }
-
-  codemirror.setSelection(selection.anchor, selection.head, {scroll: false});
-  codemirror._codeMirrorTextEditor.scrollLineIntoView(selection.anchor.line);
-};
-
-/**
- * @return {!Object|undefined}
- */
-CodeMirror.commands.goSmartPageUp = function(codemirror) {
-  if (codemirror._codeMirrorTextEditor.selection().equal(TextUtils.TextRange.createFromLocation(0, 0)))
-    return CodeMirror.Pass;
-  codemirror.execCommand('goPageUp');
-};
-
-/**
- * @return {!Object|undefined}
- */
-CodeMirror.commands.goSmartPageDown = function(codemirror) {
-  if (codemirror._codeMirrorTextEditor.selection().equal(codemirror._codeMirrorTextEditor.fullRange().collapseToEnd()))
-    return CodeMirror.Pass;
-  codemirror.execCommand('goPageDown');
-};
-
-TextEditor.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000;
-TextEditor.CodeMirrorTextEditor.MaxEditableTextSize = 1024 * 1024 * 10;
-
-/**
- * @implements {TextEditor.TextEditorPositionHandle}
- * @unrestricted
- */
-TextEditor.CodeMirrorPositionHandle = class {
-  /**
-   * @param {!CodeMirror} codeMirror
-   * @param {!CodeMirror.Pos} pos
-   */
-  constructor(codeMirror, pos) {
-    this._codeMirror = codeMirror;
-    this._lineHandle = codeMirror.getLineHandle(pos.line);
-    this._columnNumber = pos.ch;
-  }
-
-  /**
-   * @override
-   * @return {?{lineNumber: number, columnNumber: number}}
-   */
-  resolve() {
-    const lineNumber = this._lineHandle ? this._codeMirror.getLineNumber(this._lineHandle) : null;
-    if (typeof lineNumber !== 'number')
-      return null;
-    return {lineNumber: lineNumber, columnNumber: this._columnNumber};
-  }
-
-  /**
-   * @override
-   * @param {!TextEditor.TextEditorPositionHandle} positionHandle
-   * @return {boolean}
-   */
-  equal(positionHandle) {
-    return positionHandle._lineHandle === this._lineHandle && positionHandle._columnNumber === this._columnNumber &&
-        positionHandle._codeMirror === this._codeMirror;
-  }
-};
-
-/**
- * @unrestricted
- */
-TextEditor.CodeMirrorTextEditor.SelectNextOccurrenceController = class {
-  /**
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   * @param {!CodeMirror} codeMirror
-   */
-  constructor(textEditor, codeMirror) {
-    this._textEditor = textEditor;
-    this._codeMirror = codeMirror;
-  }
-
-  selectionWillChange() {
-    if (!this._muteSelectionListener)
-      delete this._fullWordSelection;
-  }
-
-  /**
-   * @param {!Array.<!TextUtils.TextRange>} selections
-   * @param {!TextUtils.TextRange} range
-   * @return {boolean}
-   */
-  _findRange(selections, range) {
-    for (let i = 0; i < selections.length; ++i) {
-      if (range.equal(selections[i]))
-        return true;
-    }
-    return false;
-  }
-
-  undoLastSelection() {
-    this._muteSelectionListener = true;
-    this._codeMirror.execCommand('undoSelection');
-    this._muteSelectionListener = false;
-  }
-
-  selectNextOccurrence() {
-    const selections = this._textEditor.selections();
-    let anyEmptySelection = false;
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      anyEmptySelection = anyEmptySelection || selection.isEmpty();
-      if (selection.startLine !== selection.endLine)
-        return;
-    }
-    if (anyEmptySelection) {
-      this._expandSelectionsToWords(selections);
-      return;
-    }
-
-    const last = selections[selections.length - 1];
-    let next = last;
-    do
-      next = this._findNextOccurrence(next, !!this._fullWordSelection);
-    while (next && this._findRange(selections, next) && !next.equal(last));
-
-    if (!next)
-      return;
-    selections.push(next);
-
-    this._muteSelectionListener = true;
-    this._textEditor.setSelections(selections, selections.length - 1);
-    delete this._muteSelectionListener;
-
-    this._textEditor.scrollLineIntoView(next.startLine);
-  }
-
-  /**
-   * @param {!Array.<!TextUtils.TextRange>} selections
-   */
-  _expandSelectionsToWords(selections) {
-    const newSelections = [];
-    for (let i = 0; i < selections.length; ++i) {
-      const selection = selections[i];
-      const startRangeWord = this._textEditor.wordRangeForCursorPosition(
-                                 selection.startLine, selection.startColumn, TextUtils.TextUtils.isWordChar) ||
-          TextUtils.TextRange.createFromLocation(selection.startLine, selection.startColumn);
-      const endRangeWord = this._textEditor.wordRangeForCursorPosition(
-                               selection.endLine, selection.endColumn, TextUtils.TextUtils.isWordChar) ||
-          TextUtils.TextRange.createFromLocation(selection.endLine, selection.endColumn);
-      const newSelection = new TextUtils.TextRange(
-          startRangeWord.startLine, startRangeWord.startColumn, endRangeWord.endLine, endRangeWord.endColumn);
-      newSelections.push(newSelection);
-    }
-    this._textEditor.setSelections(newSelections, newSelections.length - 1);
-    this._fullWordSelection = true;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {boolean} fullWord
-   * @return {?TextUtils.TextRange}
-   */
-  _findNextOccurrence(range, fullWord) {
-    range = range.normalize();
-    let matchedLineNumber;
-    let matchedColumnNumber;
-    const textToFind = this._textEditor.text(range);
-    function findWordInLine(wordRegex, lineNumber, lineText, from, to) {
-      if (typeof matchedLineNumber === 'number')
-        return true;
-      wordRegex.lastIndex = from;
-      const result = wordRegex.exec(lineText);
-      if (!result || result.index + textToFind.length > to)
-        return false;
-      matchedLineNumber = lineNumber;
-      matchedColumnNumber = result.index;
-      return true;
-    }
-
-    let iteratedLineNumber;
-    function lineIterator(regex, lineHandle) {
-      if (findWordInLine(regex, iteratedLineNumber++, lineHandle.text, 0, lineHandle.text.length))
-        return true;
-    }
-
-    let regexSource = textToFind.escapeForRegExp();
-    if (fullWord)
-      regexSource = '\\b' + regexSource + '\\b';
-    const wordRegex = new RegExp(regexSource, 'g');
-    const currentLineText = this._codeMirror.getLine(range.startLine);
-
-    findWordInLine(wordRegex, range.startLine, currentLineText, range.endColumn, currentLineText.length);
-    iteratedLineNumber = range.startLine + 1;
-    this._codeMirror.eachLine(range.startLine + 1, this._codeMirror.lineCount(), lineIterator.bind(null, wordRegex));
-    iteratedLineNumber = 0;
-    this._codeMirror.eachLine(0, range.startLine, lineIterator.bind(null, wordRegex));
-    findWordInLine(wordRegex, range.startLine, currentLineText, 0, range.startColumn);
-
-    if (typeof matchedLineNumber !== 'number')
-      return null;
-    return new TextUtils.TextRange(
-        matchedLineNumber, matchedColumnNumber, matchedLineNumber, matchedColumnNumber + textToFind.length);
-  }
-};
-
-
-/**
- * @interface
- */
-TextEditor.TextEditorPositionHandle = function() {};
-
-TextEditor.TextEditorPositionHandle.prototype = {
-  /**
-   * @return {?{lineNumber: number, columnNumber: number}}
-   */
-  resolve() {},
-
-  /**
-   * @param {!TextEditor.TextEditorPositionHandle} positionHandle
-   * @return {boolean}
-   */
-  equal(positionHandle) {}
-};
-
-TextEditor.CodeMirrorTextEditor._overrideModeWithPrefixedTokens('css', 'css-');
-TextEditor.CodeMirrorTextEditor._overrideModeWithPrefixedTokens('javascript', 'js-');
-TextEditor.CodeMirrorTextEditor._overrideModeWithPrefixedTokens('xml', 'xml-');
-
-/** @type {!Set<!Runtime.Extension>} */
-TextEditor.CodeMirrorTextEditor._loadedMimeModeExtensions = new Set();
-
-
-/**
- * @interface
- */
-TextEditor.CodeMirrorMimeMode = function() {};
-
-TextEditor.CodeMirrorMimeMode.prototype = {
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  install(extension) {}
-};
-
-/**
- * @unrestricted
- */
-TextEditor.TextEditorBookMark = class {
-  /**
-   * @param {!CodeMirror.TextMarker} marker
-   * @param {symbol} type
-   * @param {!TextEditor.CodeMirrorTextEditor} editor
-   */
-  constructor(marker, type, editor) {
-    marker[TextEditor.TextEditorBookMark._symbol] = this;
-
-    this._marker = marker;
-    this._type = type;
-    this._editor = editor;
-  }
-
-  clear() {
-    const position = this._marker.find();
-    this._marker.clear();
-    if (position)
-      this._editor._updateDecorations(position.line);
-  }
-
-  refresh() {
-    this._marker.changed();
-    const position = this._marker.find();
-    if (position)
-      this._editor._updateDecorations(position.line);
-  }
-
-  /**
-   * @return {symbol}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {?TextUtils.TextRange}
-   */
-  position() {
-    const pos = this._marker.find();
-    return pos ? TextUtils.TextRange.createFromLocation(pos.line, pos.ch) : null;
-  }
-};
-
-TextEditor.TextEditorBookMark._symbol = Symbol('TextEditor.TextEditorBookMark');
-
-/**
- * @typedef {{
- *  element: !Element,
- *  widget: !CodeMirror.LineWidget,
- *  update: ?function()
- * }}
- */
-TextEditor.CodeMirrorTextEditor.Decoration;
-
-/**
- * @implements {UI.TextEditorFactory}
- * @unrestricted
- */
-TextEditor.CodeMirrorTextEditorFactory = class {
-  /**
-   * @override
-   * @param {!UI.TextEditor.Options} options
-   * @return {!TextEditor.CodeMirrorTextEditor}
-   */
-  createEditor(options) {
-    return new TextEditor.CodeMirrorTextEditor(options);
-  }
-};
diff --git a/front_end/text_editor/CodeMirrorUtils.js b/front_end/text_editor/CodeMirrorUtils.js
deleted file mode 100644
index 3adbe95..0000000
--- a/front_end/text_editor/CodeMirrorUtils.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-TextEditor.CodeMirrorUtils = {};
-/**
- * @param {!TextUtils.TextRange} range
- * @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}}
- */
-TextEditor.CodeMirrorUtils.toPos = function(range) {
-  return {
-    start: new CodeMirror.Pos(range.startLine, range.startColumn),
-    end: new CodeMirror.Pos(range.endLine, range.endColumn)
-  };
-};
-
-/**
- * @param {!CodeMirror.Pos} start
- * @param {!CodeMirror.Pos} end
- * @return {!TextUtils.TextRange}
- */
-TextEditor.CodeMirrorUtils.toRange = function(start, end) {
-  return new TextUtils.TextRange(start.line, start.ch, end.line, end.ch);
-};
-
-/**
- * @param {!CodeMirror.ChangeObject} changeObject
- * @return {{oldRange: !TextUtils.TextRange, newRange: !TextUtils.TextRange}}
- */
-TextEditor.CodeMirrorUtils.changeObjectToEditOperation = function(changeObject) {
-  const oldRange = TextEditor.CodeMirrorUtils.toRange(changeObject.from, changeObject.to);
-  const newRange = oldRange.clone();
-  const linesAdded = changeObject.text.length;
-  if (linesAdded === 0) {
-    newRange.endLine = newRange.startLine;
-    newRange.endColumn = newRange.startColumn;
-  } else if (linesAdded === 1) {
-    newRange.endLine = newRange.startLine;
-    newRange.endColumn = newRange.startColumn + changeObject.text[0].length;
-  } else {
-    newRange.endLine = newRange.startLine + linesAdded - 1;
-    newRange.endColumn = changeObject.text[linesAdded - 1].length;
-  }
-  return {oldRange: oldRange, newRange: newRange};
-};
-
-/**
- * @param {!CodeMirror} codeMirror
- * @param {number} linesCount
- * @return {!Array.<string>}
- */
-TextEditor.CodeMirrorUtils.pullLines = function(codeMirror, linesCount) {
-  const lines = [];
-  codeMirror.eachLine(0, linesCount, onLineHandle);
-  return lines;
-
-  /**
-   * @param {!{text: string}} lineHandle
-   */
-  function onLineHandle(lineHandle) {
-    lines.push(lineHandle.text);
-  }
-};
-
-/**
- * @param {!Element} element
- */
-TextEditor.CodeMirrorUtils.appendThemeStyle = function(element) {
-  if (UI.themeSupport.hasTheme())
-    return;
-
-  const backgroundColor = InspectorFrontendHost.getSelectionBackgroundColor();
-  const foregroundColor = InspectorFrontendHost.getSelectionForegroundColor();
-  const inactiveBackgroundColor = InspectorFrontendHost.getInactiveSelectionBackgroundColor();
-  const inactiveForegroundColor = InspectorFrontendHost.getInactiveSelectionForegroundColor();
-  const style = createElement('style');
-  style.textContent = `
-    .CodeMirror .CodeMirror-selected {
-      background-color: ${inactiveBackgroundColor};
-    }
-
-    .CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) {
-      color: ${inactiveForegroundColor} !important;
-    }
-
-    .CodeMirror-focused .CodeMirror-selected {
-      background-color: ${backgroundColor};
-    }
-
-    .CodeMirror-focused .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) {
-      color: ${foregroundColor} !important;
-    }
-
-    .CodeMirror .CodeMirror-line::selection,
-    .CodeMirror .CodeMirror-line > span::selection,
-    .CodeMirror .CodeMirror-line > span > span::selection {
-      background: ${backgroundColor};
-      color: ${foregroundColor} !important;
-    }
-  `;
-  element.appendChild(style);
-};
-
-
-/**
- * @implements {TextUtils.TokenizerFactory}
- * @unrestricted
- */
-TextEditor.CodeMirrorUtils.TokenizerFactory = class {
-  /**
-   * @override
-   * @param {string} mimeType
-   * @return {function(string, function(string, ?string, number, number))}
-   */
-  createTokenizer(mimeType) {
-    const mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
-    const state = CodeMirror.startState(mode);
-    function tokenize(line, callback) {
-      const stream = new CodeMirror.StringStream(line);
-      while (!stream.eol()) {
-        const style = mode.token(stream, state);
-        const value = stream.current();
-        callback(value, style, stream.start, stream.start + value.length);
-        stream.start = stream.pos;
-      }
-    }
-    return tokenize;
-  }
-};
-
-/**
- * @unrestricted
- */
-TextEditor.CodeMirrorCSSLoadView = class extends UI.VBox {
-  /**
-   * This bogus view is needed to load/unload CodeMirror-related CSS on demand.
-   */
-  constructor() {
-    super();
-    this.element.classList.add('hidden');
-    this.registerRequiredCSS('cm/codemirror.css');
-    this.registerRequiredCSS('text_editor/cmdevtools.css');
-    TextEditor.CodeMirrorUtils.appendThemeStyle(this.element);
-  }
-};
diff --git a/front_end/text_editor/TextEditorAutocompleteController.js b/front_end/text_editor/TextEditorAutocompleteController.js
deleted file mode 100644
index 56fbe6c..0000000
--- a/front_end/text_editor/TextEditorAutocompleteController.js
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @implements {UI.SuggestBoxDelegate}
- * @unrestricted
- */
-TextEditor.TextEditorAutocompleteController = class {
-  /**
-   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
-   * @param {!CodeMirror} codeMirror
-   * @param {!UI.AutocompleteConfig} config
-   */
-  constructor(textEditor, codeMirror, config) {
-    this._textEditor = textEditor;
-    this._codeMirror = codeMirror;
-    this._config = config;
-    this._initialized = false;
-
-    this._onScroll = this._onScroll.bind(this);
-    this._onCursorActivity = this._onCursorActivity.bind(this);
-    this._changes = this._changes.bind(this);
-    this._blur = this._blur.bind(this);
-    this._beforeChange = this._beforeChange.bind(this);
-    this._mouseDown = this.clearAutocomplete.bind(this);
-    this._codeMirror.on('changes', this._changes);
-    this._lastHintText = '';
-    this._hintElement = createElementWithClass('span', 'auto-complete-text');
-  }
-
-  _initializeIfNeeded() {
-    if (this._initialized)
-      return;
-    this._initialized = true;
-    this._codeMirror.on('scroll', this._onScroll);
-    this._codeMirror.on('cursorActivity', this._onCursorActivity);
-    this._codeMirror.on('mousedown', this._mouseDown);
-    this._codeMirror.on('blur', this._blur);
-    if (this._config.isWordChar) {
-      this._codeMirror.on('beforeChange', this._beforeChange);
-      this._dictionary = new Common.TextDictionary();
-      this._addWordsFromText(this._codeMirror.getValue());
-    }
-  }
-
-  dispose() {
-    this._codeMirror.off('changes', this._changes);
-    if (this._initialized) {
-      this._codeMirror.off('scroll', this._onScroll);
-      this._codeMirror.off('cursorActivity', this._onCursorActivity);
-      this._codeMirror.off('mousedown', this._mouseDown);
-      this._codeMirror.off('blur', this._blur);
-    }
-    if (this._dictionary) {
-      this._codeMirror.off('beforeChange', this._beforeChange);
-      this._dictionary.reset();
-    }
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   * @param {!CodeMirror.BeforeChangeObject} changeObject
-   */
-  _beforeChange(codeMirror, changeObject) {
-    this._updatedLines = this._updatedLines || {};
-    for (let i = changeObject.from.line; i <= changeObject.to.line; ++i)
-      this._updatedLines[i] = this._codeMirror.getLine(i);
-  }
-
-  /**
-   * @param {string} text
-   */
-  _addWordsFromText(text) {
-    TextUtils.TextUtils.textToWords(
-        text, /** @type {function(string):boolean} */ (this._config.isWordChar), addWord.bind(this));
-
-    /**
-     * @param {string} word
-     * @this {TextEditor.TextEditorAutocompleteController}
-     */
-    function addWord(word) {
-      if (word.length && (word[0] < '0' || word[0] > '9'))
-        this._dictionary.addWord(word);
-    }
-  }
-
-  /**
-   * @param {string} text
-   */
-  _removeWordsFromText(text) {
-    TextUtils.TextUtils.textToWords(
-        text, /** @type {function(string):boolean} */ (this._config.isWordChar),
-        word => this._dictionary.removeWord(word));
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?TextUtils.TextRange}
-   */
-  _substituteRange(lineNumber, columnNumber) {
-    let range =
-        this._config.substituteRangeCallback ? this._config.substituteRangeCallback(lineNumber, columnNumber) : null;
-    if (!range && this._config.isWordChar)
-      range = this._textEditor.wordRangeForCursorPosition(lineNumber, columnNumber, this._config.isWordChar);
-    return range;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} queryRange
-   * @param {!TextUtils.TextRange} substituteRange
-   * @param {boolean=} force
-   * @return {!Promise.<!UI.SuggestBox.Suggestions>}
-   */
-  _wordsWithQuery(queryRange, substituteRange, force) {
-    const external =
-        this._config.suggestionsCallback ? this._config.suggestionsCallback(queryRange, substituteRange, force) : null;
-    if (external)
-      return external;
-
-    if (!this._dictionary || (!force && queryRange.isEmpty()))
-      return Promise.resolve([]);
-
-    let completions = this._dictionary.wordsWithPrefix(this._textEditor.text(queryRange));
-    const substituteWord = this._textEditor.text(substituteRange);
-    if (this._dictionary.wordCount(substituteWord) === 1)
-      completions = completions.filter(word => word !== substituteWord);
-
-    completions.sort((a, b) => this._dictionary.wordCount(b) - this._dictionary.wordCount(a) || a.length - b.length);
-    return Promise.resolve(completions.map(item => ({text: item})));
-  }
-
-  /**
-   * @param {!CodeMirror} codeMirror
-   * @param {!Array.<!CodeMirror.ChangeObject>} changes
-   */
-  _changes(codeMirror, changes) {
-    if (!changes.length)
-      return;
-
-    if (this._dictionary && this._updatedLines) {
-      for (const lineNumber in this._updatedLines)
-        this._removeWordsFromText(this._updatedLines[lineNumber]);
-      delete this._updatedLines;
-
-      const linesToUpdate = {};
-      for (let changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
-        const changeObject = changes[changeIndex];
-        const editInfo = TextEditor.CodeMirrorUtils.changeObjectToEditOperation(changeObject);
-        for (let i = editInfo.newRange.startLine; i <= editInfo.newRange.endLine; ++i)
-          linesToUpdate[i] = this._codeMirror.getLine(i);
-      }
-      for (const lineNumber in linesToUpdate)
-        this._addWordsFromText(linesToUpdate[lineNumber]);
-    }
-
-    let singleCharInput = false;
-    let singleCharDelete = false;
-    const cursor = this._codeMirror.getCursor('head');
-    for (let changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
-      const changeObject = changes[changeIndex];
-      if (changeObject.origin === '+input' && changeObject.text.length === 1 && changeObject.text[0].length === 1 &&
-          changeObject.to.line === cursor.line && changeObject.to.ch + 1 === cursor.ch) {
-        singleCharInput = true;
-        break;
-      }
-      if (changeObject.origin === '+delete' && changeObject.removed.length === 1 &&
-          changeObject.removed[0].length === 1 && changeObject.to.line === cursor.line &&
-          changeObject.to.ch - 1 === cursor.ch) {
-        singleCharDelete = true;
-        break;
-      }
-    }
-    if (this._queryRange) {
-      if (singleCharInput)
-        this._queryRange.endColumn++;
-      else if (singleCharDelete)
-        this._queryRange.endColumn--;
-      if (singleCharDelete || singleCharInput)
-        this._setHint(this._lastHintText);
-    }
-
-    if (singleCharInput || singleCharDelete)
-      setImmediate(this.autocomplete.bind(this));
-    else
-      this.clearAutocomplete();
-  }
-
-  _blur() {
-    this.clearAutocomplete();
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} mainSelection
-   * @return {boolean}
-   */
-  _validateSelectionsContexts(mainSelection) {
-    const selections = this._codeMirror.listSelections();
-    if (selections.length <= 1)
-      return true;
-    const mainSelectionContext = this._textEditor.text(mainSelection);
-    for (let i = 0; i < selections.length; ++i) {
-      const wordRange = this._substituteRange(selections[i].head.line, selections[i].head.ch);
-      if (!wordRange)
-        return false;
-      const context = this._textEditor.text(wordRange);
-      if (context !== mainSelectionContext)
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @param {boolean=} force
-   */
-  autocomplete(force) {
-    this._initializeIfNeeded();
-    if (this._codeMirror.somethingSelected()) {
-      this.clearAutocomplete();
-      return;
-    }
-
-    const cursor = this._codeMirror.getCursor('head');
-    const substituteRange = this._substituteRange(cursor.line, cursor.ch);
-    if (!substituteRange || !this._validateSelectionsContexts(substituteRange)) {
-      this.clearAutocomplete();
-      return;
-    }
-
-    const queryRange = substituteRange.clone();
-    queryRange.endColumn = cursor.ch;
-    const query = this._textEditor.text(queryRange);
-    let hadSuggestBox = false;
-    if (this._suggestBox)
-      hadSuggestBox = true;
-    this._wordsWithQuery(queryRange, substituteRange, force).then(wordsAcquired.bind(this));
-
-    /**
-     * @param {!UI.SuggestBox.Suggestions} wordsWithQuery
-     * @this {TextEditor.TextEditorAutocompleteController}
-     */
-    function wordsAcquired(wordsWithQuery) {
-      if (!wordsWithQuery.length || (wordsWithQuery.length === 1 && query === wordsWithQuery[0].text) ||
-          (!this._suggestBox && hadSuggestBox)) {
-        this.clearAutocomplete();
-        this._onSuggestionsShownForTest([]);
-        return;
-      }
-      if (!this._suggestBox) {
-        this._suggestBox = new UI.SuggestBox(this, 20, this._config.captureEnter);
-        this._suggestBox.setDefaultSelectionIsDimmed(!!this._config.captureEnter);
-      }
-
-      const oldQueryRange = this._queryRange;
-      this._queryRange = queryRange;
-      if (!oldQueryRange || queryRange.startLine !== oldQueryRange.startLine ||
-          queryRange.startColumn !== oldQueryRange.startColumn)
-        this._updateAnchorBox();
-      this._suggestBox.updateSuggestions(this._anchorBox, wordsWithQuery, true, !this._isCursorAtEndOfLine(), query);
-      this._onSuggestionsShownForTest(wordsWithQuery);
-    }
-  }
-
-  /**
-   * @param {string} hint
-   */
-  _setHint(hint) {
-    const query = this._textEditor.text(this._queryRange);
-    if (!hint || !this._isCursorAtEndOfLine() || !hint.startsWith(query)) {
-      this._clearHint();
-      return;
-    }
-    const suffix = hint.substring(query.length).split('\n')[0];
-    this._hintElement.textContent = suffix;
-    const cursor = this._codeMirror.getCursor('to');
-    if (this._hintMarker) {
-      const position = this._hintMarker.position();
-      if (!position || !position.equal(TextUtils.TextRange.createFromLocation(cursor.line, cursor.ch))) {
-        this._hintMarker.clear();
-        this._hintMarker = null;
-      }
-    }
-
-    if (!this._hintMarker) {
-      this._hintMarker = this._textEditor.addBookmark(
-          cursor.line, cursor.ch, this._hintElement, TextEditor.TextEditorAutocompleteController.HintBookmark, true);
-    } else if (this._lastHintText !== hint) {
-      this._hintMarker.refresh();
-    }
-    this._lastHintText = hint;
-  }
-
-  _clearHint() {
-    if (!this._hintElement.textContent)
-      return;
-    this._lastHintText = '';
-    this._hintElement.textContent = '';
-    if (this._hintMarker)
-      this._hintMarker.refresh();
-  }
-
-  /**
-   * @param {!UI.SuggestBox.Suggestions} suggestions
-   */
-  _onSuggestionsShownForTest(suggestions) {
-  }
-
-  _onSuggestionsHiddenForTest() {
-  }
-
-  clearAutocomplete() {
-    if (!this._suggestBox)
-      return;
-    this._suggestBox.hide();
-    this._suggestBox = null;
-    this._queryRange = null;
-    this._anchorBox = null;
-    this._clearHint();
-    this._onSuggestionsHiddenForTest();
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  keyDown(event) {
-    if (!this._suggestBox)
-      return false;
-    switch (event.keyCode) {
-      case UI.KeyboardShortcut.Keys.Tab.code:
-        this._suggestBox.acceptSuggestion();
-        this.clearAutocomplete();
-        return true;
-      case UI.KeyboardShortcut.Keys.End.code:
-      case UI.KeyboardShortcut.Keys.Right.code:
-        if (this._isCursorAtEndOfLine()) {
-          this._suggestBox.acceptSuggestion();
-          this.clearAutocomplete();
-          return true;
-        } else {
-          this.clearAutocomplete();
-          return false;
-        }
-      case UI.KeyboardShortcut.Keys.Left.code:
-      case UI.KeyboardShortcut.Keys.Home.code:
-        this.clearAutocomplete();
-        return false;
-      case UI.KeyboardShortcut.Keys.Esc.code:
-        this.clearAutocomplete();
-        return true;
-    }
-    return this._suggestBox.keyPressed(event);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isCursorAtEndOfLine() {
-    const cursor = this._codeMirror.getCursor('to');
-    return cursor.ch === this._codeMirror.getLine(cursor.line).length;
-  }
-
-  /**
-   * @override
-   * @param {string} suggestion
-   * @param {boolean=} isIntermediateSuggestion
-   */
-  applySuggestion(suggestion, isIntermediateSuggestion) {
-    this._currentSuggestion = suggestion;
-    this._setHint(suggestion);
-  }
-
-  /**
-   * @override
-   */
-  acceptSuggestion() {
-    const selections = this._codeMirror.listSelections().slice();
-    const queryLength = this._queryRange.endColumn - this._queryRange.startColumn;
-    for (let i = selections.length - 1; i >= 0; --i) {
-      const start = selections[i].head;
-      const end = new CodeMirror.Pos(start.line, start.ch - queryLength);
-      this._codeMirror.replaceRange(this._currentSuggestion, start, end, '+autocomplete');
-    }
-  }
-
-  _onScroll() {
-    if (!this._suggestBox)
-      return;
-    const cursor = this._codeMirror.getCursor();
-    const scrollInfo = this._codeMirror.getScrollInfo();
-    const topmostLineNumber = this._codeMirror.lineAtHeight(scrollInfo.top, 'local');
-    const bottomLine = this._codeMirror.lineAtHeight(scrollInfo.top + scrollInfo.clientHeight, 'local');
-    if (cursor.line < topmostLineNumber || cursor.line > bottomLine) {
-      this.clearAutocomplete();
-    } else {
-      this._updateAnchorBox();
-      this._suggestBox.setPosition(this._anchorBox);
-    }
-  }
-
-  _onCursorActivity() {
-    if (!this._suggestBox)
-      return;
-    const cursor = this._codeMirror.getCursor();
-    let shouldCloseAutocomplete =
-        !(cursor.line === this._queryRange.startLine && this._queryRange.startColumn <= cursor.ch &&
-          cursor.ch <= this._queryRange.endColumn);
-    // Try not to hide autocomplete when user types in.
-    if (cursor.line === this._queryRange.startLine && cursor.ch === this._queryRange.endColumn + 1) {
-      const line = this._codeMirror.getLine(cursor.line);
-      shouldCloseAutocomplete = this._config.isWordChar ? !this._config.isWordChar(line.charAt(cursor.ch - 1)) : false;
-    }
-    if (shouldCloseAutocomplete)
-      this.clearAutocomplete();
-    this._onCursorActivityHandledForTest();
-  }
-
-  _onCursorActivityHandledForTest() {
-  }
-
-  _updateAnchorBox() {
-    const line = this._queryRange.startLine;
-    const column = this._queryRange.startColumn;
-    const metrics = this._textEditor.cursorPositionToCoordinates(line, column);
-    this._anchorBox = metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null;
-  }
-};
-
-TextEditor.TextEditorAutocompleteController.HintBookmark = Symbol('hint');
diff --git a/front_end/text_editor/cmdevtools.css b/front_end/text_editor/cmdevtools.css
deleted file mode 100644
index 5ff40d8..0000000
--- a/front_end/text_editor/cmdevtools.css
+++ /dev/null
@@ -1,548 +0,0 @@
-.CodeMirror {
-    line-height: 1.2em !important;
-    background-color: transparent !important;
-    color: #222;
-    height: 300px;
-}
-
-.CodeMirror-linewidget {
-    overflow: visible !important;
-}
-
-.CodeMirror-gutter-performance {
-    width: 74px;
-    background-color: white;
-    margin-left: 3px;
-}
-
-.CodeMirror-gutter-coverage {
-    width: 5px;
-    background-color: white;
-    margin-left: 3px;
-}
-
-.CodeMirror .source-frame-eval-expression {
-    outline: 0;
-    border: 1px solid rgb(163, 41, 34);
-    border-left-width: 0;
-    border-right-width: 0;
-    background-color: rgb(255, 255, 194);
-}
-
-.CodeMirror .source-frame-eval-expression-start {
-    border-left-width: 1px;
-    margin-left: -1px;
-}
-
-.CodeMirror .source-frame-eval-expression-end {
-    border-right-width: 1px;
-    margin-right: -1px;
-}
-
-.CodeMirror .source-frame-continue-to-location {
-    outline: 0;
-    border: 1px solid transparent;
-    border-left-width: 0;
-    border-right-width: 0;
-    background-color: rgb(230, 236, 255);
-    cursor: pointer;
-}
-
-.CodeMirror .source-frame-continue-to-location:hover {
-    border: 1px solid rgb(121, 141, 254);
-    background-color: rgb(171, 191, 254);
-}
-
-.-theme-with-dark-background .CodeMirror .source-frame-continue-to-location {
-    background-color: #14522b;
-}
-
-.-theme-with-dark-background .CodeMirror .source-frame-continue-to-location:hover {
-    border: 1px solid #33cc6b;
-    background-color: #14522b;
-}
-
-.CodeMirror .source-frame-continue-to-location-start {
-    border-left-width: 1px;
-    margin-left: -1px;
-}
-
-.CodeMirror .source-frame-continue-to-location-end {
-    border-right-width: 1px;
-    margin-right: -1px;
-}
-
-.CodeMirror .source-frame-async-step-in {
-    outline: 0;
-    background-color: hsla(100, 46%, 80%, 1);
-    cursor: pointer;
-    border: 1px solid transparent;
-    border-left-width: 0;
-    border-right-width: 0;
-}
-
-.source-frame-async-step-in-hovered .source-frame-async-step-in {
-    background-color: hsl(96, 53%, 65%);
-    border-color: rgb(100, 154, 100);
-}
-
-.source-frame-async-step-in-hovered .source-frame-async-step-in-start {
-    border-left-width: 1px;
-    margin-left: -1px;
-}
-
-.source-frame-async-step-in-hovered .source-frame-async-step-in-end {
-    border-right-width: 1px;
-    margin-right: -1px;
-}
-
-.CodeMirror-readonly .CodeMirror-cursor {
-    display: none;
-}
-
-.CodeMirror-gutters {
-    border-right: 1px solid var(--divider-color);
-    white-space: nowrap;
-    background-color: white;
-}
-
-.CodeMirror-linenumber {
-    color: rgb(128, 128, 128);
-    padding: 0 3px 0 5px;
-    min-width: 22px;
-    text-align: right;
-    white-space: nowrap;
-}
-
-.cm-highlight {
-    -webkit-animation: fadeout 2s 0s;
-}
-.-theme-with-dark-background .cm-highlight {
-    -webkit-animation: fadeout-dark 2s 0s;
-}
-@-webkit-keyframes fadeout {
-    from {background-color: rgb(255, 255, 120); }
-    to { background-color: white; }
-}
-@-webkit-keyframes fadeout-dark {
-    from {background-color: hsla(133, 100%, 30%, 0.5); }
-    to { background-color: transparent; }
-}
-
-.cm-readonly-highlight {
-    background-color: rgb(255, 255, 120);
-}
-.-theme-with-dark-background .cm-readonly-highlight {
-    background-color: hsla(133, 100%, 30%, 0.5);
-}
-
-.cm-highlight.cm-execution-line {
-    -webkit-animation: fadeout-execution-line 1s 0s;
-}
-.-theme-with-dark-background .cm-highlight.cm-execution-line {
-    -webkit-animation: fadeout-execution-line-dark 1s 0s;
-}
-
-@-webkit-keyframes fadeout-execution-line {
-    from {background-color: rgb(121, 141, 254); }
-    to { background-color: rgb(171, 191, 254); }
-}
-@-webkit-keyframes fadeout-execution-line-dark {
-    from {background-color: #208043; }
-    to { background-color: #14522b; }
-}
-
-.cm-breakpoint .CodeMirror-gutter-wrapper .CodeMirror-linenumber, -theme-preserve {
-    color: white;
-    border-width: 1px 4px 1px 1px !important;
-    -webkit-border-image: url(Images/breakpoint.png) 1 4 1 1;
-    margin: 0 0 0 3px !important;
-    padding-right: 3px;
-    padding-left: 1px;
-    height: 11px;
-    line-height: 12px !important;
-    border-style: solid;
-}
-
-.cm-line-without-source-mapping .CodeMirror-linenumber {
-    color: rgba(128, 128, 128, 0.4);
-}
-
-.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber {
-    -webkit-border-image: url(Images/breakpointConditional.png) 1 4 1 1;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-.cm-breakpoint .CodeMirror-gutter-wrapper .CodeMirror-linenumber {
-    -webkit-border-image: url(Images/breakpoint_2x.png) 2 8 2 2;
-}
-.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber {
-    -webkit-border-image: url(Images/breakpointConditional_2x.png) 2 8 2 2;
-}
-} /* media */
-
-.-theme-with-dark-background .cm-breakpoint:not(.cm-breakpoint-conditional) .CodeMirror-gutter-wrapper .CodeMirror-linenumber {
-    filter: hue-rotate(-139deg);
-}
-
-.cm-breakpoint-disabled .CodeMirror-linenumber {
-    opacity: 0.5;
-}
-
-.breakpoints-deactivated .cm-breakpoint .CodeMirror-linenumber {
-    opacity: 0.5;
-}
-
-.breakpoints-deactivated .cm-breakpoint-disabled .CodeMirror-linenumber {
-    opacity: 0.3;
-}
-
-.cm-inline-breakpoint {
-    position:relative;
-    top: 2px;
-    cursor: pointer;
-}
-
-.cm-execution-line-tail + .CodeMirror-widget {
-    background-color: #abbffe;
-}
-
-.source-frame-eval-expression + .CodeMirror-widget {
-    border: 1px solid rgb(163, 41, 34);
-    border-left-width: 0;
-    border-right-width: 0;
-    background-color: rgb(255, 255, 194);
-}
-
-.cm-inline-breakpoint.cm-execution-line-tail {
-    background-color: #698cfe;
-}
-
-.cm-execution-line-tail .cm-inline-breakpoint {
-    background-color: white
-}
-
-.cm-inline-breakpoint.cm-inline-conditional {
-    background-color: #ef9d0d;
-}
-
-.cm-inline-breakpoint.cm-inline-disabled {
-    opacity: 0.5;
-}
-
-.cm-continue-to-location {
-    cursor: pointer;
-    opacity: 0.8;
-    position: relative;
-    top: 2px;
-}
-
-.cm-continue-to-location:hover {
-    opacity: 1;
-}
-
-div.CodeMirror span.CodeMirror-matchingbracket {
-    background-color: rgba(0, 0, 0, 0.07);
-    border-bottom: 1px solid rgba(0, 0, 0, 0.5);
-}
-
-div.CodeMirror span.CodeMirror-nonmatchingbracket {
-    background-color: rgba(255, 0, 0, 0.07);
-    border-bottom: 1px solid rgba(255, 0, 0, 0.5);
-}
-
-.-theme-with-dark-background div.CodeMirror span.CodeMirror-matchingbracket {
-    border-bottom: 1px solid rgb(217,217,217);
-    background-color:initial;
-}
-
-.-theme-with-dark-background div.CodeMirror span.CodeMirror-nonmatchingbracket {
-    border-bottom: 1px solid rgb(255, 26, 26);
-    background-color:initial;
-}
-
-.cm-whitespace::before {
-    position: absolute;
-    pointer-events: none;
-    color: rgb(175, 175, 175);
-}
-
-.cm-tab {
-    display: inline-block;
-    text-decoration: inherit;
-    position: relative;
-}
-
-.cm-tab:before {
-    display: none;
-    content: ".";
-    color: transparent;
-    border-bottom: 1px solid rgb(175, 175, 175);
-    position: absolute;
-    width: 90%;
-    bottom: 50%;
-    left: 5%;
-}
-
-.show-whitespaces .CodeMirror .cm-tab:before {
-    display: block !important;
-}
-
-.cm-execution-line {
-    background-color: rgba(0, 59, 255, 0.10);
-}
-
-.cm-execution-line-outline {
-    outline: 1px solid rgb(64, 115, 244);
-}
-
-.cm-execution-line-tail {
-    background-color: rgb(171, 191, 254);
-}
-
-.cm-execution-line .CodeMirror-linenumber {
-    border-right: 1px solid rgb(64, 115, 244);
-}
-
-.-theme-with-dark-background .cm-execution-line {
-    background-color: #14522b;
-}
-
-.-theme-with-dark-background .cm-execution-line-outline {
-    outline: 1px solid #33cc6b;
-}
-
-.-theme-with-dark-background .cm-execution-line-tail {
-    background-color: #347132;
-}
-
-.cm-token-highlight {
-    position: relative;
-}
-
-.cm-token-highlight:before {
-    position: absolute;
-    border: 1px solid gray;
-    border-radius: 3px;
-    top: 0;
-    bottom: -1px;
-    left: 0;
-    right: 0;
-    content: "";
-}
-
-.cm-line-with-selection .cm-column-with-selection:before {
-    border: none;
-}
-
-.cm-search-highlight {
-    position: relative;
-}
-
-.cm-search-highlight:before {
-    position: absolute;
-    border-top-style: solid;
-    border-bottom-style: solid;
-    border-top-color: gray;
-    border-bottom-color: gray;
-    border-top-width: 1px;
-    border-bottom-width: 1px;
-    top: -1px;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    content: "";
-}
-
-.cm-search-highlight-full:before {
-    border: 1px solid gray;
-    border-radius: 3px;
-}
-
-.cm-search-highlight-start:before {
-    border-left-width: 1px;
-    border-top-left-radius: 2px;
-    border-bottom-left-radius: 2px;
-    border-left-style: solid;
-    border-left-color: gray;
-}
-
-.cm-search-highlight-end:before {
-    border-right-width: 1px;
-    border-top-right-radius: 2px;
-    border-bottom-right-radius: 2px;
-    border-right-style: solid;
-    border-right-color: gray;
-}
-
-.cm-line-with-selection .cm-column-with-selection.cm-search-highlight-full:before {
-    border-radius: 1px;
-}
-
-.cm-line-with-selection .cm-column-with-selection.cm-search-highlight-start:before {
-    border-top-left-radius: 1px;
-    border-bottom-left-radius: 1px;
-}
-
-.cm-line-with-selection .cm-column-with-selection.cm-search-highlight-end:before {
-    border-top-right-radius: 1px;
-    border-bottom-right-radius: 1px;
-}
-
-.cm-line-with-selection .cm-column-with-selection.cm-search-highlight:before {
-    margin: -1px -1px -1px -1px;
-    background-color: rgb(241, 234, 0);
-    z-index: -1;
-}
-
-.-theme-with-dark-background .cm-line-with-selection .cm-column-with-selection.cm-search-highlight:before {
-    background-color: hsl(133, 100%, 30%);
-}
-
-.-theme-with-dark-background .cm-line-with-selection .cm-search-highlight {
-    color: #eee;
-}
-
-.CodeMirror .text-editor-line-marker-performance {
-    text-align: right;
-    padding-right: 3px;
-}
-
-.CodeMirror .text-editor-coverage-unused-marker {
-    text-align: right;
-    padding-right: 2px;
-    background-color: #E57373;
-}
-
-.CodeMirror .text-editor-coverage-unused-marker::after {
-    content: " ";
-}
-
-.CodeMirror .text-editor-coverage-used-marker {
-    text-align: right;
-    padding-right: 2px;
-    background-color: #81C784;
-}
-
-.CodeMirror .text-editor-coverage-used-marker::after {
-    content: " ";
-}
-
-.CodeMirror .text-editor-line-decoration {
-    position: absolute;
-}
-
-.CodeMirror .text-editor-line-decoration-wave {
-    position: absolute;
-    top: -2px;
-    right: -4px;
-    left: 4px;
-    cursor: pointer;
-    height: 4px;
-}
-
-.CodeMirror .text-editor-value-decoration {
-    position: absolute;
-    bottom: 0;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    max-width: 1000px;
-    opacity: 0.8;
-    background-color: #FFE3C7;
-    margin-left: 10px;
-    padding-left: 5px;
-    color: #222;
-    -webkit-user-select: text;
-}
-
-.CodeMirror .cm-execution-line .text-editor-value-decoration {
-    background-color: transparent;
-    opacity: 0.5;
-}
-
-.CodeMirror .text-editor-line-decoration-icon {
-    position: absolute;
-    cursor: pointer;
-    right: -16px;
-    top: -9px;
-}
-
-.CodeMirror .text-editor-line-with-warning:not(.cm-execution-line):not(.cm-readonly-highlight) {
-    background-color: rgba(241, 230, 0, 0.1);
-}
-
-.CodeMirror .text-editor-line-with-error:not(.cm-execution-line):not(.cm-readonly-highlight) {
-    background-color: rgba(255, 0, 0, 0.05);
-}
-
-.CodeMirror .text-editor-line-decoration-wave {
-    background-image: url(Images/errorWave.png);
-    background-repeat: repeat-x;
-    background-size: contain;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-.CodeMirror .text-editor-line-decoration-wave {
-    background-image: url(Images/errorWave_2x.png);
-}
-} /* media */
-
-/** @see crbug.com/358161 */
-.CodeMirror .CodeMirror-vscrollbar, .CodeMirror .CodeMirror-hscrollbar {
-    transform: translateZ(0);
-}
-
-.cm-trailing-whitespace {
-    background-color: rgba(255, 0, 0, 0.05);
-}
-
-.CodeMirror-activeline .cm-trailing-whitespace {
-    background-color: transparent;
-}
-
-.-theme-with-dark-background .CodeMirror .CodeMirror-selected {
-    background-color: #454545;
-}
-
-.CodeMirror .auto-complete-text {
-    color: rgb(128,128,128);
-}
-
-.CodeMirror .placeholder-text {
-    height: 0;
-    color: rgb(128,128,128);
-}
-
-/** Prevent the codemirror textarea from stealing PageUp events **/
-.CodeMirror textarea {
-    resize: none;
-    overflow: hidden;
-}
-
-.CodeMirror-lines {
-    padding: 4px 0; /* Vertical padding around content */
-}
-
-.CodeMirror pre {
-    padding: 0 4px; /* Horizontal padding of content */
-}
-
-.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
-    background-color: white; /* The little square between H and V scrollbars */
-}
-
-.CodeMirror-cursor {
-    border-left: 1px solid black;
-    border-right: none;
-    width: 0;
-}
-
-/* Shown when moving in bi-directional text */
-.CodeMirror div.CodeMirror-secondarycursor {
-    border-left: 1px solid silver;
-}
-
-.CodeMirror-composing {
-    border-bottom: 2px solid;
-}
diff --git a/front_end/text_editor/module.json b/front_end/text_editor/module.json
deleted file mode 100644
index 429098b..0000000
--- a/front_end/text_editor/module.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "@TextUtils.TokenizerFactory",
-            "className": "TextEditor.CodeMirrorUtils.TokenizerFactory"
-        },
-        {
-            "type": "@UI.TextEditorFactory",
-            "className": "TextEditor.CodeMirrorTextEditorFactory"
-        }
-    ],
-    "dependencies": [
-        "ui",
-        "platform",
-        "common",
-        "cm"
-    ],
-    "scripts": [
-        "../cm_web_modes/css.js",
-        "../cm_web_modes/javascript.js",
-        "../cm_web_modes/xml.js",
-        "../cm_web_modes/htmlmixed.js",
-        "../cm_web_modes/htmlembedded.js",
-        "CodeMirrorUtils.js",
-        "TextEditorAutocompleteController.js",
-        "CodeMirrorTextEditor.js"
-    ],
-    "resources": [
-        "cmdevtools.css"
-    ],
-    "skip_compilation": [
-        "acorn/acorn.js",
-        "../cm_web_modes/css.js",
-        "../cm_web_modes/javascript.js",
-        "../cm_web_modes/xml.js",
-        "../cm_web_modes/htmlmixed.js",
-        "../cm_web_modes/htmlembedded.js"
-    ]
-}
\ No newline at end of file
diff --git a/front_end/text_utils/Text.js b/front_end/text_utils/Text.js
deleted file mode 100644
index c1f2da2..0000000
--- a/front_end/text_utils/Text.js
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-TextUtils.Text = class {
-  /**
-   * @param {string} value
-   */
-  constructor(value) {
-    this._value = value;
-  }
-
-  /**
-   * @return {!Array<number>}
-   */
-  lineEndings() {
-    if (!this._lineEndings)
-      this._lineEndings = this._value.computeLineEndings();
-    return this._lineEndings;
-  }
-
-  /**
-   * @return {string}
-   */
-  value() {
-    return this._value;
-  }
-
-  /**
-   * @return {number}
-   */
-  lineCount() {
-    const lineEndings = this.lineEndings();
-    return lineEndings.length;
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {number}
-   */
-  offsetFromPosition(lineNumber, columnNumber) {
-    return (lineNumber ? this.lineEndings()[lineNumber - 1] + 1 : 0) + columnNumber;
-  }
-
-  /**
-   * @param {number} offset
-   * @return {!TextUtils.Text.Position}
-   */
-  positionFromOffset(offset) {
-    const lineEndings = this.lineEndings();
-    const lineNumber = lineEndings.lowerBound(offset);
-    return {lineNumber: lineNumber, columnNumber: offset - (lineNumber && (lineEndings[lineNumber - 1] + 1))};
-  }
-
-  /**
-   * @return {string}
-   */
-  lineAt(lineNumber) {
-    const lineEndings = this.lineEndings();
-    const lineStart = lineNumber > 0 ? lineEndings[lineNumber - 1] + 1 : 0;
-    const lineEnd = lineEndings[lineNumber];
-    let lineContent = this._value.substring(lineStart, lineEnd);
-    if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) === '\r')
-      lineContent = lineContent.substring(0, lineContent.length - 1);
-    return lineContent;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @return {!TextUtils.SourceRange}
-   */
-  toSourceRange(range) {
-    const start = this.offsetFromPosition(range.startLine, range.startColumn);
-    const end = this.offsetFromPosition(range.endLine, range.endColumn);
-    return new TextUtils.SourceRange(start, end - start);
-  }
-
-  /**
-   * @param {!TextUtils.SourceRange} sourceRange
-   * @return {!TextUtils.TextRange}
-   */
-  toTextRange(sourceRange) {
-    const cursor = new TextUtils.TextCursor(this.lineEndings());
-    const result = TextUtils.TextRange.createFromLocation(0, 0);
-
-    cursor.resetTo(sourceRange.offset);
-    result.startLine = cursor.lineNumber();
-    result.startColumn = cursor.columnNumber();
-
-    cursor.advance(sourceRange.offset + sourceRange.length);
-    result.endLine = cursor.lineNumber();
-    result.endColumn = cursor.columnNumber();
-    return result;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {string} replacement
-   * @return {string}
-   */
-  replaceRange(range, replacement) {
-    const sourceRange = this.toSourceRange(range);
-    return this._value.substring(0, sourceRange.offset) + replacement +
-        this._value.substring(sourceRange.offset + sourceRange.length);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @return {string}
-   */
-  extract(range) {
-    const sourceRange = this.toSourceRange(range);
-    return this._value.substr(sourceRange.offset, sourceRange.length);
-  }
-};
-
-/** @typedef {{lineNumber: number, columnNumber: number}} */
-TextUtils.Text.Position;
-
-/**
- * @unrestricted
- */
-TextUtils.TextCursor = class {
-  /**
-   * @param {!Array<number>} lineEndings
-   */
-  constructor(lineEndings) {
-    this._lineEndings = lineEndings;
-    this._offset = 0;
-    this._lineNumber = 0;
-    this._columnNumber = 0;
-  }
-
-  /**
-   * @param {number} offset
-   */
-  advance(offset) {
-    this._offset = offset;
-    while (this._lineNumber < this._lineEndings.length && this._lineEndings[this._lineNumber] < this._offset)
-      ++this._lineNumber;
-    this._columnNumber = this._lineNumber ? this._offset - this._lineEndings[this._lineNumber - 1] - 1 : this._offset;
-  }
-
-  /**
-   * @return {number}
-   */
-  offset() {
-    return this._offset;
-  }
-
-  /**
-   * @param {number} offset
-   */
-  resetTo(offset) {
-    this._offset = offset;
-    this._lineNumber = this._lineEndings.lowerBound(offset);
-    this._columnNumber = this._lineNumber ? this._offset - this._lineEndings[this._lineNumber - 1] - 1 : this._offset;
-  }
-
-  /**
-   * @return {number}
-   */
-  lineNumber() {
-    return this._lineNumber;
-  }
-
-  /**
-   * @return {number}
-   */
-  columnNumber() {
-    return this._columnNumber;
-  }
-};
diff --git a/front_end/text_utils/TextRange.js b/front_end/text_utils/TextRange.js
deleted file mode 100644
index 9bc7f41..0000000
--- a/front_end/text_utils/TextRange.js
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-TextUtils.TextRange = class {
-  /**
-   * @param {number} startLine
-   * @param {number} startColumn
-   * @param {number} endLine
-   * @param {number} endColumn
-   */
-  constructor(startLine, startColumn, endLine, endColumn) {
-    this.startLine = startLine;
-    this.startColumn = startColumn;
-    this.endLine = endLine;
-    this.endColumn = endColumn;
-  }
-
-  /**
-   * @param {number} line
-   * @param {number} column
-   * @return {!TextUtils.TextRange}
-   */
-  static createFromLocation(line, column) {
-    return new TextUtils.TextRange(line, column, line, column);
-  }
-
-  /**
-   * @param {!Object} serializedTextRange
-   * @return {!TextUtils.TextRange}
-   */
-  static fromObject(serializedTextRange) {
-    return new TextUtils.TextRange(
-        serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine,
-        serializedTextRange.endColumn);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range1
-   * @param {!TextUtils.TextRange} range2
-   * @return {number}
-   */
-  static comparator(range1, range2) {
-    return range1.compareTo(range2);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} oldRange
-   * @param {string} newText
-   * @return {!TextUtils.TextRange}
-   */
-  static fromEdit(oldRange, newText) {
-    let endLine = oldRange.startLine;
-    let endColumn = oldRange.startColumn + newText.length;
-    const lineEndings = newText.computeLineEndings();
-    if (lineEndings.length > 1) {
-      endLine = oldRange.startLine + lineEndings.length - 1;
-      const len = lineEndings.length;
-      endColumn = lineEndings[len - 1] - lineEndings[len - 2] - 1;
-    }
-    return new TextUtils.TextRange(oldRange.startLine, oldRange.startColumn, endLine, endColumn);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEmpty() {
-    return this.startLine === this.endLine && this.startColumn === this.endColumn;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @return {boolean}
-   */
-  immediatelyPrecedes(range) {
-    if (!range)
-      return false;
-    return this.endLine === range.startLine && this.endColumn === range.startColumn;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @return {boolean}
-   */
-  immediatelyFollows(range) {
-    if (!range)
-      return false;
-    return range.immediatelyPrecedes(this);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @return {boolean}
-   */
-  follows(range) {
-    return (range.endLine === this.startLine && range.endColumn <= this.startColumn) || range.endLine < this.startLine;
-  }
-
-  /**
-   * @return {number}
-   */
-  get linesCount() {
-    return this.endLine - this.startLine;
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  collapseToEnd() {
-    return new TextUtils.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  collapseToStart() {
-    return new TextUtils.TextRange(this.startLine, this.startColumn, this.startLine, this.startColumn);
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  normalize() {
-    if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
-      return new TextUtils.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn);
-    else
-      return this.clone();
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  clone() {
-    return new TextUtils.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
-  }
-
-  /**
-   * @return {!{startLine: number, startColumn: number, endLine: number, endColumn: number}}
-   */
-  serializeToObject() {
-    const serializedTextRange = {};
-    serializedTextRange.startLine = this.startLine;
-    serializedTextRange.startColumn = this.startColumn;
-    serializedTextRange.endLine = this.endLine;
-    serializedTextRange.endColumn = this.endColumn;
-    return serializedTextRange;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} other
-   * @return {number}
-   */
-  compareTo(other) {
-    if (this.startLine > other.startLine)
-      return 1;
-    if (this.startLine < other.startLine)
-      return -1;
-    if (this.startColumn > other.startColumn)
-      return 1;
-    if (this.startColumn < other.startColumn)
-      return -1;
-    return 0;
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {number}
-   */
-  compareToPosition(lineNumber, columnNumber) {
-    if (lineNumber < this.startLine || (lineNumber === this.startLine && columnNumber < this.startColumn))
-      return -1;
-    if (lineNumber > this.endLine || (lineNumber === this.endLine && columnNumber > this.endColumn))
-      return 1;
-    return 0;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} other
-   * @return {boolean}
-   */
-  equal(other) {
-    return this.startLine === other.startLine && this.endLine === other.endLine &&
-        this.startColumn === other.startColumn && this.endColumn === other.endColumn;
-  }
-
-  /**
-   * @param {number} line
-   * @param {number} column
-   * @return {!TextUtils.TextRange}
-   */
-  relativeTo(line, column) {
-    const relative = this.clone();
-
-    if (this.startLine === line)
-      relative.startColumn -= column;
-    if (this.endLine === line)
-      relative.endColumn -= column;
-
-    relative.startLine -= line;
-    relative.endLine -= line;
-    return relative;
-  }
-
-  /**
-   * @param {number} line
-   * @param {number} column
-   * @return {!TextUtils.TextRange}
-   */
-  relativeFrom(line, column) {
-    const relative = this.clone();
-
-    if (this.startLine === 0)
-      relative.startColumn += column;
-    if (this.endLine === 0)
-      relative.endColumn += column;
-
-    relative.startLine += line;
-    relative.endLine += line;
-    return relative;
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} originalRange
-   * @param {!TextUtils.TextRange} editedRange
-   * @return {!TextUtils.TextRange}
-   */
-  rebaseAfterTextEdit(originalRange, editedRange) {
-    console.assert(originalRange.startLine === editedRange.startLine);
-    console.assert(originalRange.startColumn === editedRange.startColumn);
-    const rebase = this.clone();
-    if (!this.follows(originalRange))
-      return rebase;
-    const lineDelta = editedRange.endLine - originalRange.endLine;
-    const columnDelta = editedRange.endColumn - originalRange.endColumn;
-    rebase.startLine += lineDelta;
-    rebase.endLine += lineDelta;
-    if (rebase.startLine === editedRange.endLine)
-      rebase.startColumn += columnDelta;
-    if (rebase.endLine === editedRange.endLine)
-      rebase.endColumn += columnDelta;
-    return rebase;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return JSON.stringify(this);
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {boolean}
-   */
-  containsLocation(lineNumber, columnNumber) {
-    if (this.startLine === this.endLine)
-      return this.startLine === lineNumber && this.startColumn <= columnNumber && columnNumber <= this.endColumn;
-    if (this.startLine === lineNumber)
-      return this.startColumn <= columnNumber;
-    if (this.endLine === lineNumber)
-      return columnNumber <= this.endColumn;
-    return this.startLine < lineNumber && lineNumber < this.endLine;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-TextUtils.SourceRange = class {
-  /**
-   * @param {number} offset
-   * @param {number} length
-   */
-  constructor(offset, length) {
-    this.offset = offset;
-    this.length = length;
-  }
-};
-
-/**
- * @unrestricted
- */
-TextUtils.SourceEdit = class {
-  /**
-   * @param {string} sourceURL
-   * @param {!TextUtils.TextRange} oldRange
-   * @param {string} newText
-   */
-  constructor(sourceURL, oldRange, newText) {
-    this.sourceURL = sourceURL;
-    this.oldRange = oldRange;
-    this.newText = newText;
-  }
-
-  /**
-   * @param {!TextUtils.SourceEdit} edit1
-   * @param {!TextUtils.SourceEdit} edit2
-   * @return {number}
-   */
-  static comparator(edit1, edit2) {
-    return TextUtils.TextRange.comparator(edit1.oldRange, edit2.oldRange);
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  newRange() {
-    return TextUtils.TextRange.fromEdit(this.oldRange, this.newText);
-  }
-};
diff --git a/front_end/text_utils/TextUtils.js b/front_end/text_utils/TextUtils.js
deleted file mode 100644
index d928788..0000000
--- a/front_end/text_utils/TextUtils.js
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-TextUtils.TextUtils = {
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  isStopChar: function(char) {
-    return (char > ' ' && char < '0') || (char > '9' && char < 'A') || (char > 'Z' && char < '_') ||
-        (char > '_' && char < 'a') || (char > 'z' && char <= '~');
-  },
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  isWordChar: function(char) {
-    return !TextUtils.TextUtils.isStopChar(char) && !TextUtils.TextUtils.isSpaceChar(char);
-  },
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  isSpaceChar: function(char) {
-    return TextUtils.TextUtils._SpaceCharRegex.test(char);
-  },
-
-  /**
-   * @param {string} word
-   * @return {boolean}
-   */
-  isWord: function(word) {
-    for (let i = 0; i < word.length; ++i) {
-      if (!TextUtils.TextUtils.isWordChar(word.charAt(i)))
-        return false;
-    }
-    return true;
-  },
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  isOpeningBraceChar: function(char) {
-    return char === '(' || char === '{';
-  },
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  isClosingBraceChar: function(char) {
-    return char === ')' || char === '}';
-  },
-
-  /**
-   * @param {string} char
-   * @return {boolean}
-   */
-  isBraceChar: function(char) {
-    return TextUtils.TextUtils.isOpeningBraceChar(char) || TextUtils.TextUtils.isClosingBraceChar(char);
-  },
-
-  /**
-   * @param {string} text
-   * @param {function(string):boolean} isWordChar
-   * @param {function(string)} wordCallback
-   */
-  textToWords: function(text, isWordChar, wordCallback) {
-    let startWord = -1;
-    for (let i = 0; i < text.length; ++i) {
-      if (!isWordChar(text.charAt(i))) {
-        if (startWord !== -1)
-          wordCallback(text.substring(startWord, i));
-        startWord = -1;
-      } else if (startWord === -1) {
-        startWord = i;
-      }
-    }
-    if (startWord !== -1)
-      wordCallback(text.substring(startWord));
-  },
-
-  /**
-   * @param {string} line
-   * @return {string}
-   */
-  lineIndent: function(line) {
-    let indentation = 0;
-    while (indentation < line.length && TextUtils.TextUtils.isSpaceChar(line.charAt(indentation)))
-      ++indentation;
-    return line.substr(0, indentation);
-  },
-
-  /**
-   * @param {string} text
-   * @return {boolean}
-   */
-  isUpperCase: function(text) {
-    return text === text.toUpperCase();
-  },
-
-  /**
-   * @param {string} text
-   * @return {boolean}
-   */
-  isLowerCase: function(text) {
-    return text === text.toLowerCase();
-  },
-
-  /**
-   * @param {string} text
-   * @param {!Array<!RegExp>} regexes
-   * @return {!Array<{value: string, position: number, regexIndex: number, captureGroups: !Array<string|undefined>}>}
-   */
-  splitStringByRegexes(text, regexes) {
-    const matches = [];
-    const globalRegexes = [];
-    for (let i = 0; i < regexes.length; i++) {
-      const regex = regexes[i];
-      if (!regex.global)
-        globalRegexes.push(new RegExp(regex.source, regex.flags ? regex.flags + 'g' : 'g'));
-      else
-        globalRegexes.push(regex);
-    }
-    doSplit(text, 0, 0);
-    return matches;
-
-    /**
-     * @param {string} text
-     * @param {number} regexIndex
-     * @param {number} startIndex
-     */
-    function doSplit(text, regexIndex, startIndex) {
-      if (regexIndex >= globalRegexes.length) {
-        // Set regexIndex as -1 if text did not match with any regular expression
-        matches.push({value: text, position: startIndex, regexIndex: -1, captureGroups: []});
-        return;
-      }
-      const regex = globalRegexes[regexIndex];
-      let currentIndex = 0;
-      let result;
-      regex.lastIndex = 0;
-      while ((result = regex.exec(text)) !== null) {
-        const stringBeforeMatch = text.substring(currentIndex, result.index);
-        if (stringBeforeMatch)
-          doSplit(stringBeforeMatch, regexIndex + 1, startIndex + currentIndex);
-        const match = result[0];
-        matches.push({
-          value: match,
-          position: startIndex + result.index,
-          regexIndex: regexIndex,
-          captureGroups: result.slice(1)
-        });
-        currentIndex = result.index + match.length;
-      }
-      const stringAfterMatches = text.substring(currentIndex);
-      if (stringAfterMatches)
-        doSplit(stringAfterMatches, regexIndex + 1, startIndex + currentIndex);
-    }
-  }
-};
-
-TextUtils.FilterParser = class {
-  /**
-   * @param {!Array<string>} keys
-   */
-  constructor(keys) {
-    this._keys = keys;
-  }
-
-  /**
-   * @param {!TextUtils.FilterParser.ParsedFilter} filter
-   * @return {!TextUtils.FilterParser.ParsedFilter}
-   */
-  static cloneFilter(filter) {
-    return {key: filter.key, text: filter.text, regex: filter.regex, negative: filter.negative};
-  }
-
-  /**
-   * @param {string} query
-   * @return {!Array<!TextUtils.FilterParser.ParsedFilter>}
-   */
-  parse(query) {
-    const splitResult = TextUtils.TextUtils.splitStringByRegexes(query, [
-      TextUtils.TextUtils._keyValueFilterRegex, TextUtils.TextUtils._regexFilterRegex,
-      TextUtils.TextUtils._textFilterRegex
-    ]);
-    const filters = [];
-    for (let i = 0; i < splitResult.length; i++) {
-      const regexIndex = splitResult[i].regexIndex;
-      if (regexIndex === -1)
-        continue;
-      const result = splitResult[i].captureGroups;
-      if (regexIndex === 0) {
-        if (this._keys.indexOf(/** @type {string} */ (result[1])) !== -1)
-          filters.push({key: result[1], text: result[2], negative: !!result[0]});
-        else
-          filters.push({text: result[1] + ':' + result[2], negative: !!result[0]});
-      } else if (regexIndex === 1) {
-        try {
-          filters.push({regex: new RegExp(result[1], 'i'), negative: !!result[0]});
-        } catch (e) {
-          filters.push({text: '/' + result[1] + '/', negative: !!result[0]});
-        }
-      } else if (regexIndex === 2) {
-        filters.push({text: result[1], negative: !!result[0]});
-      }
-    }
-    return filters;
-  }
-};
-
-/** @typedef {{key:(string|undefined), text:(?string|undefined), regex:(!RegExp|undefined), negative:boolean}} */
-TextUtils.FilterParser.ParsedFilter;
-
-TextUtils.TextUtils._keyValueFilterRegex = /(?:^|\s)(\-)?([\w\-]+):([^\s]+)/;
-TextUtils.TextUtils._regexFilterRegex = /(?:^|\s)(\-)?\/([^\s]+)\//;
-TextUtils.TextUtils._textFilterRegex = /(?:^|\s)(\-)?([^\s]+)/;
-TextUtils.TextUtils._SpaceCharRegex = /\s/;
-
-/**
- * @enum {string}
- */
-TextUtils.TextUtils.Indent = {
-  TwoSpaces: '  ',
-  FourSpaces: '    ',
-  EightSpaces: '        ',
-  TabCharacter: '\t'
-};
-
-/**
- * @unrestricted
- */
-TextUtils.TextUtils.BalancedJSONTokenizer = class {
-  /**
-   * @param {function(string)} callback
-   * @param {boolean=} findMultiple
-   */
-  constructor(callback, findMultiple) {
-    this._callback = callback;
-    this._index = 0;
-    this._balance = 0;
-    this._buffer = '';
-    this._findMultiple = findMultiple || false;
-    this._closingDoubleQuoteRegex = /[^\\](?:\\\\)*"/g;
-  }
-
-  /**
-   * @param {string} chunk
-   * @return {boolean}
-   */
-  write(chunk) {
-    this._buffer += chunk;
-    const lastIndex = this._buffer.length;
-    const buffer = this._buffer;
-    let index;
-    for (index = this._index; index < lastIndex; ++index) {
-      const character = buffer[index];
-      if (character === '"') {
-        this._closingDoubleQuoteRegex.lastIndex = index;
-        if (!this._closingDoubleQuoteRegex.test(buffer))
-          break;
-        index = this._closingDoubleQuoteRegex.lastIndex - 1;
-      } else if (character === '{') {
-        ++this._balance;
-      } else if (character === '}') {
-        --this._balance;
-        if (this._balance < 0) {
-          this._reportBalanced();
-          return false;
-        }
-        if (!this._balance) {
-          this._lastBalancedIndex = index + 1;
-          if (!this._findMultiple)
-            break;
-        }
-      } else if (character === ']' && !this._balance) {
-        this._reportBalanced();
-        return false;
-      }
-    }
-    this._index = index;
-    this._reportBalanced();
-    return true;
-  }
-
-  _reportBalanced() {
-    if (!this._lastBalancedIndex)
-      return;
-    this._callback(this._buffer.slice(0, this._lastBalancedIndex));
-    this._buffer = this._buffer.slice(this._lastBalancedIndex);
-    this._index -= this._lastBalancedIndex;
-    this._lastBalancedIndex = 0;
-  }
-
-  /**
-   * @return {string}
-   */
-  remainder() {
-    return this._buffer;
-  }
-};
-
-/**
- * @interface
- */
-TextUtils.TokenizerFactory = function() {};
-
-TextUtils.TokenizerFactory.prototype = {
-  /**
-   * @param {string} mimeType
-   * @return {function(string, function(string, ?string, number, number))}
-   */
-  createTokenizer(mimeType) {}
-};
-
-/**
- * @param {string} text
- * @return {boolean}
- */
-TextUtils.isMinified = function(text) {
-  const kMaxNonMinifiedLength = 500;
-  let linesToCheck = 10;
-  let lastPosition = 0;
-  do {
-    let eolIndex = text.indexOf('\n', lastPosition);
-    if (eolIndex < 0)
-      eolIndex = text.length;
-    if (eolIndex - lastPosition > kMaxNonMinifiedLength && text.substr(lastPosition, 3) !== '//#')
-      return true;
-    lastPosition = eolIndex + 1;
-  } while (--linesToCheck >= 0 && lastPosition < text.length);
-  return false;
-};
\ No newline at end of file
diff --git a/front_end/text_utils/module.json b/front_end/text_utils/module.json
deleted file mode 100644
index cdc588e..0000000
--- a/front_end/text_utils/module.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "dependencies": [
-        "platform"
-    ],
-    "scripts": [
-        "Text.js",
-        "TextUtils.js",
-        "TextRange.js"
-    ]
-}
diff --git a/front_end/timeline/CountersGraph.js b/front_end/timeline/CountersGraph.js
deleted file mode 100644
index 9c921fc..0000000
--- a/front_end/timeline/CountersGraph.js
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Timeline.TimelineModeView}
- * @unrestricted
- */
-Timeline.CountersGraph = class extends UI.VBox {
-  /**
-   * @param {!Timeline.TimelineModeViewDelegate} delegate
-   */
-  constructor(delegate) {
-    super();
-    this.element.id = 'memory-graphs-container';
-
-    this._delegate = delegate;
-    this._calculator = new Timeline.CountersGraph.Calculator();
-
-    // Create selectors
-    this._header = new UI.HBox();
-    this._header.element.classList.add('timeline-memory-header');
-    this._header.show(this.element);
-    this._toolbar = new UI.Toolbar('timeline-memory-toolbar');
-    this._header.element.appendChild(this._toolbar.element);
-
-    this._graphsContainer = new UI.VBox();
-    this._graphsContainer.show(this.element);
-    const canvasWidget = new UI.VBoxWithResizeCallback(this._resize.bind(this));
-    canvasWidget.show(this._graphsContainer.element);
-    this._createCurrentValuesBar();
-    this._canvasContainer = canvasWidget.element;
-    this._canvasContainer.id = 'memory-graphs-canvas-container';
-    this._canvas = this._canvasContainer.createChild('canvas');
-    this._canvas.id = 'memory-counters-graph';
-
-    this._canvasContainer.addEventListener('mouseover', this._onMouseMove.bind(this), true);
-    this._canvasContainer.addEventListener('mousemove', this._onMouseMove.bind(this), true);
-    this._canvasContainer.addEventListener('mouseleave', this._onMouseLeave.bind(this), true);
-    this._canvasContainer.addEventListener('click', this._onClick.bind(this), true);
-    // We create extra timeline grid here to reuse its event dividers.
-    this._timelineGrid = new PerfUI.TimelineGrid();
-    this._canvasContainer.appendChild(this._timelineGrid.dividersElement);
-
-    this._counters = [];
-    this._counterUI = [];
-
-    this._countersByName = {};
-    this._countersByName['jsHeapSizeUsed'] = this._createCounter(
-        Common.UIString('JS Heap'), Common.UIString('JS Heap: %s'), 'hsl(220, 90%, 43%)', Number.bytesToString);
-    this._countersByName['documents'] =
-        this._createCounter(Common.UIString('Documents'), Common.UIString('Documents: %s'), 'hsl(0, 90%, 43%)');
-    this._countersByName['nodes'] =
-        this._createCounter(Common.UIString('Nodes'), Common.UIString('Nodes: %s'), 'hsl(120, 90%, 43%)');
-    this._countersByName['jsEventListeners'] =
-        this._createCounter(Common.UIString('Listeners'), Common.UIString('Listeners: %s'), 'hsl(38, 90%, 43%)');
-    this._gpuMemoryCounter = this._createCounter(
-        Common.UIString('GPU Memory'), Common.UIString('GPU Memory [KB]: %s'), 'hsl(300, 90%, 43%)',
-        Number.bytesToString);
-    this._countersByName['gpuMemoryUsedKB'] = this._gpuMemoryCounter;
-  }
-
-  /**
-   * @override
-   * @param {?Timeline.PerformanceModel} model
-   * @param {?TimelineModel.TimelineModel.Track} track
-   */
-  setModel(model, track) {
-    this._calculator.setZeroTime(model ? model.timelineModel().minimumRecordTime() : 0);
-    for (let i = 0; i < this._counters.length; ++i) {
-      this._counters[i].reset();
-      this._counterUI[i].reset();
-    }
-    this.scheduleRefresh();
-    this._track = track;
-    if (!track)
-      return;
-    const events = track.syncEvents();
-    for (let i = 0; i < events.length; ++i) {
-      const event = events[i];
-      if (event.name !== TimelineModel.TimelineModel.RecordType.UpdateCounters)
-        continue;
-
-      const counters = event.args.data;
-      if (!counters)
-        return;
-      for (const name in counters) {
-        const counter = this._countersByName[name];
-        if (counter)
-          counter.appendSample(event.startTime, counters[name]);
-      }
-
-      const gpuMemoryLimitCounterName = 'gpuMemoryLimitKB';
-      if (gpuMemoryLimitCounterName in counters)
-        this._gpuMemoryCounter.setLimit(counters[gpuMemoryLimitCounterName]);
-    }
-  }
-
-  _createCurrentValuesBar() {
-    this._currentValuesBar = this._graphsContainer.element.createChild('div');
-    this._currentValuesBar.id = 'counter-values-bar';
-  }
-
-  /**
-   * @param {string} uiName
-   * @param {string} uiValueTemplate
-   * @param {string} color
-   * @param {function(number):string=} formatter
-   * @return {!Timeline.CountersGraph.Counter}
-   */
-  _createCounter(uiName, uiValueTemplate, color, formatter) {
-    const counter = new Timeline.CountersGraph.Counter();
-    this._counters.push(counter);
-    this._counterUI.push(
-        new Timeline.CountersGraph.CounterUI(this, uiName, uiValueTemplate, color, counter, formatter));
-    return counter;
-  }
-
-  /**
-   * @override
-   * @return {!UI.Widget}
-   */
-  view() {
-    return this;
-  }
-
-  /**
-   * @override
-   * @return {?Element}
-   */
-  resizerElement() {
-    return this._header.element;
-  }
-
-  _resize() {
-    const parentElement = this._canvas.parentElement;
-    this._canvas.width = parentElement.clientWidth * window.devicePixelRatio;
-    this._canvas.height = parentElement.clientHeight * window.devicePixelRatio;
-    this._calculator.setDisplayWidth(this._canvas.width);
-    this.refresh();
-  }
-
-  /**
-   * @override
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  setWindowTimes(startTime, endTime) {
-    this._calculator.setWindow(startTime, endTime);
-    this.scheduleRefresh();
-  }
-
-  scheduleRefresh() {
-    UI.invokeOnceAfterBatchUpdate(this, this.refresh);
-  }
-
-  draw() {
-    for (let i = 0; i < this._counters.length; ++i) {
-      this._counters[i]._calculateVisibleIndexes(this._calculator);
-      this._counters[i]._calculateXValues(this._canvas.width);
-    }
-    this._clear();
-
-    for (let i = 0; i < this._counterUI.length; i++)
-      this._counterUI[i]._drawGraph(this._canvas);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    const x = event.x - this._canvasContainer.totalOffsetLeft();
-    let minDistance = Infinity;
-    let bestTime;
-    for (let i = 0; i < this._counterUI.length; ++i) {
-      const counterUI = this._counterUI[i];
-      if (!counterUI.counter.times.length)
-        continue;
-      const index = counterUI._recordIndexAt(x);
-      const distance = Math.abs(x * window.devicePixelRatio - counterUI.counter.x[index]);
-      if (distance < minDistance) {
-        minDistance = distance;
-        bestTime = counterUI.counter.times[index];
-      }
-    }
-    if (bestTime !== undefined)
-      this._delegate.selectEntryAtTime(this._track, bestTime);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseLeave(event) {
-    delete this._markerXPosition;
-    this._clearCurrentValueAndMarker();
-  }
-
-  _clearCurrentValueAndMarker() {
-    for (let i = 0; i < this._counterUI.length; i++)
-      this._counterUI[i]._clearCurrentValueAndMarker();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    const x = event.x - this._canvasContainer.totalOffsetLeft();
-    this._markerXPosition = x;
-    this._refreshCurrentValues();
-  }
-
-  _refreshCurrentValues() {
-    if (this._markerXPosition === undefined)
-      return;
-    for (let i = 0; i < this._counterUI.length; ++i)
-      this._counterUI[i].updateCurrentValue(this._markerXPosition);
-  }
-
-  refresh() {
-    this._timelineGrid.updateDividers(this._calculator);
-    this.draw();
-    this._refreshCurrentValues();
-  }
-
-  _clear() {
-    const ctx = this._canvas.getContext('2d');
-    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
-  }
-
-  /**
-   * @override
-   * @param {?SDK.TracingModel.Event} event
-   */
-  highlightEvent(event) {
-  }
-
-  /**
-   * @override
-   * @param {?Timeline.TimelineSelection} selection
-   */
-  setSelection(selection) {
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.CountersGraph.Counter = class {
-  constructor() {
-    this.times = [];
-    this.values = [];
-  }
-
-  /**
-   * @param {number} time
-   * @param {number} value
-   */
-  appendSample(time, value) {
-    if (this.values.length && this.values.peekLast() === value)
-      return;
-    this.times.push(time);
-    this.values.push(value);
-  }
-
-  reset() {
-    this.times = [];
-    this.values = [];
-  }
-
-  /**
-   * @param {number} value
-   */
-  setLimit(value) {
-    this._limitValue = value;
-  }
-
-  /**
-   * @return {!{min: number, max: number}}
-   */
-  _calculateBounds() {
-    let maxValue;
-    let minValue;
-    for (let i = this._minimumIndex; i <= this._maximumIndex; i++) {
-      const value = this.values[i];
-      if (minValue === undefined || value < minValue)
-        minValue = value;
-      if (maxValue === undefined || value > maxValue)
-        maxValue = value;
-    }
-    minValue = minValue || 0;
-    maxValue = maxValue || 1;
-    if (this._limitValue) {
-      if (maxValue > this._limitValue * 0.5)
-        maxValue = Math.max(maxValue, this._limitValue);
-      minValue = Math.min(minValue, this._limitValue);
-    }
-    return {min: minValue, max: maxValue};
-  }
-
-  /**
-   * @param {!Timeline.CountersGraph.Calculator} calculator
-   */
-  _calculateVisibleIndexes(calculator) {
-    const start = calculator.minimumBoundary();
-    const end = calculator.maximumBoundary();
-
-    // Maximum index of element whose time <= start.
-    this._minimumIndex = Number.constrain(this.times.upperBound(start) - 1, 0, this.times.length - 1);
-
-    // Minimum index of element whose time >= end.
-    this._maximumIndex = Number.constrain(this.times.lowerBound(end), 0, this.times.length - 1);
-
-    // Current window bounds.
-    this._minTime = start;
-    this._maxTime = end;
-  }
-
-  /**
-   * @param {number} width
-   */
-  _calculateXValues(width) {
-    if (!this.values.length)
-      return;
-
-    const xFactor = width / (this._maxTime - this._minTime);
-
-    this.x = new Array(this.values.length);
-    for (let i = this._minimumIndex + 1; i <= this._maximumIndex; i++)
-      this.x[i] = xFactor * (this.times[i] - this._minTime);
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.CountersGraph.CounterUI = class {
-  /**
-   * @param {!Timeline.CountersGraph} countersPane
-   * @param {string} title
-   * @param {string} currentValueLabel
-   * @param {string} graphColor
-   * @param {!Timeline.CountersGraph.Counter} counter
-   * @param {(function(number): string)|undefined} formatter
-   */
-  constructor(countersPane, title, currentValueLabel, graphColor, counter, formatter) {
-    this._countersPane = countersPane;
-    this.counter = counter;
-    this._formatter = formatter || Number.withThousandsSeparator;
-
-    this._setting = Common.settings.createSetting('timelineCountersGraph-' + title, true);
-    this._setting.setTitle(title);
-    this._filter = new UI.ToolbarSettingCheckbox(this._setting, title);
-    this._filter.inputElement.classList.add('-theme-preserve');
-    const color = Common.Color.parse(graphColor).setAlpha(0.5).asString(Common.Color.Format.RGBA);
-    if (color) {
-      this._filter.element.backgroundColor = color;
-      this._filter.element.borderColor = 'transparent';
-    }
-    this._filter.inputElement.addEventListener('click', this._toggleCounterGraph.bind(this));
-    countersPane._toolbar.appendToolbarItem(this._filter);
-    this._range = this._filter.element.createChild('span', 'range');
-
-    this._value = countersPane._currentValuesBar.createChild('span', 'memory-counter-value');
-    this._value.style.color = graphColor;
-    this.graphColor = graphColor;
-    this.limitColor = Common.Color.parse(graphColor).setAlpha(0.3).asString(Common.Color.Format.RGBA);
-    this.graphYValues = [];
-    this._verticalPadding = 10;
-
-    this._currentValueLabel = currentValueLabel;
-    this._marker = countersPane._canvasContainer.createChild('div', 'memory-counter-marker');
-    this._marker.style.backgroundColor = graphColor;
-    this._clearCurrentValueAndMarker();
-  }
-
-  reset() {
-    this._range.textContent = '';
-  }
-
-  /**
-   * @param {number} minValue
-   * @param {number} maxValue
-   */
-  setRange(minValue, maxValue) {
-    const min = this._formatter(minValue);
-    const max = this._formatter(maxValue);
-    this._range.textContent = Common.UIString('[%s\xa0\u2013\xa0%s]', min, max);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _toggleCounterGraph(event) {
-    this._value.classList.toggle('hidden', !this._filter.checked());
-    this._countersPane.refresh();
-  }
-
-  /**
-   * @param {number} x
-   * @return {number}
-   */
-  _recordIndexAt(x) {
-    return this.counter.x.upperBound(
-               x * window.devicePixelRatio, null, this.counter._minimumIndex + 1, this.counter._maximumIndex + 1) -
-        1;
-  }
-
-  /**
-   * @param {number} x
-   */
-  updateCurrentValue(x) {
-    if (!this.visible() || !this.counter.values.length || !this.counter.x)
-      return;
-    const index = this._recordIndexAt(x);
-    const value = Number.withThousandsSeparator(this.counter.values[index]);
-    this._value.textContent = Common.UIString(this._currentValueLabel, value);
-    const y = this.graphYValues[index] / window.devicePixelRatio;
-    this._marker.style.left = x + 'px';
-    this._marker.style.top = y + 'px';
-    this._marker.classList.remove('hidden');
-  }
-
-  _clearCurrentValueAndMarker() {
-    this._value.textContent = '';
-    this._marker.classList.add('hidden');
-  }
-
-  /**
-   * @param {!HTMLCanvasElement} canvas
-   */
-  _drawGraph(canvas) {
-    const ctx = canvas.getContext('2d');
-    const width = canvas.width;
-    const height = canvas.height - 2 * this._verticalPadding;
-    if (height <= 0) {
-      this.graphYValues = [];
-      return;
-    }
-    const originY = this._verticalPadding;
-    const counter = this.counter;
-    const values = counter.values;
-
-    if (!values.length)
-      return;
-
-    const bounds = counter._calculateBounds();
-    const minValue = bounds.min;
-    const maxValue = bounds.max;
-    this.setRange(minValue, maxValue);
-
-    if (!this.visible())
-      return;
-
-    const yValues = this.graphYValues;
-    const maxYRange = maxValue - minValue;
-    const yFactor = maxYRange ? height / (maxYRange) : 1;
-
-    ctx.save();
-    ctx.lineWidth = window.devicePixelRatio;
-    if (ctx.lineWidth % 2)
-      ctx.translate(0.5, 0.5);
-    ctx.beginPath();
-    let value = values[counter._minimumIndex];
-    let currentY = Math.round(originY + height - (value - minValue) * yFactor);
-    ctx.moveTo(0, currentY);
-    let i = counter._minimumIndex;
-    for (; i <= counter._maximumIndex; i++) {
-      const x = Math.round(counter.x[i]);
-      ctx.lineTo(x, currentY);
-      const currentValue = values[i];
-      if (typeof currentValue !== 'undefined')
-        value = currentValue;
-      currentY = Math.round(originY + height - (value - minValue) * yFactor);
-      ctx.lineTo(x, currentY);
-      yValues[i] = currentY;
-    }
-    yValues.length = i;
-    ctx.lineTo(width, currentY);
-    ctx.strokeStyle = this.graphColor;
-    ctx.stroke();
-    if (counter._limitValue) {
-      const limitLineY = Math.round(originY + height - (counter._limitValue - minValue) * yFactor);
-      ctx.moveTo(0, limitLineY);
-      ctx.lineTo(width, limitLineY);
-      ctx.strokeStyle = this.limitColor;
-      ctx.stroke();
-    }
-    ctx.closePath();
-    ctx.restore();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  visible() {
-    return this._filter.checked();
-  }
-};
-
-/**
- * @implements {PerfUI.TimelineGrid.Calculator}
- * @unrestricted
- */
-Timeline.CountersGraph.Calculator = class {
-  /**
-   * @param {number} time
-   */
-  setZeroTime(time) {
-    this._zeroTime = time;
-  }
-
-
-  /**
-   * @override
-   * @param {number} time
-   * @return {number}
-   */
-  computePosition(time) {
-    return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea;
-  }
-
-  setWindow(minimumBoundary, maximumBoundary) {
-    this._minimumBoundary = minimumBoundary;
-    this._maximumBoundary = maximumBoundary;
-  }
-
-  /**
-   * @param {number} clientWidth
-   */
-  setDisplayWidth(clientWidth) {
-    this._workingArea = clientWidth;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.preciseMillisToString(value - this.zeroTime(), precision);
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maximumBoundary() {
-    return this._maximumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  zeroTime() {
-    return this._zeroTime;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  boundarySpan() {
-    return this._maximumBoundary - this._minimumBoundary;
-  }
-};
diff --git a/front_end/timeline/EventsTimelineTreeView.js b/front_end/timeline/EventsTimelineTreeView.js
deleted file mode 100644
index 7ff3e02..0000000
--- a/front_end/timeline/EventsTimelineTreeView.js
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Timeline.EventsTimelineTreeView = class extends Timeline.TimelineTreeView {
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   * @param {!Timeline.TimelineModeViewDelegate} delegate
-   */
-  constructor(filters, delegate) {
-    super();
-    this._filtersControl = new Timeline.EventsTimelineTreeView.Filters();
-    this._filtersControl.addEventListener(
-        Timeline.EventsTimelineTreeView.Filters.Events.FilterChanged, this._onFilterChanged, this);
-    this.init(filters);
-    this._delegate = delegate;
-    this._badgePool = new ProductRegistry.BadgePool(true);
-    this._filters.push.apply(this._filters, this._filtersControl.filters());
-    this._dataGrid.markColumnAsSortedBy('startTime', DataGrid.DataGrid.Order.Ascending);
-    this._splitWidget.showBoth();
-  }
-
-  /**
-   * @override
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  updateContents(selection) {
-    this._badgePool.reset();
-    super.updateContents(selection);
-    if (selection.type() === Timeline.TimelineSelection.Type.TraceEvent) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (selection.object());
-      this._selectEvent(event, true);
-    }
-  }
-
-  /**
-   * @override
-   * @return {!TimelineModel.TimelineProfileTree.Node}
-   */
-  _buildTree() {
-    this._currentTree = this.buildTopDownTree(true, null);
-    return this._currentTree;
-  }
-
-  _onFilterChanged() {
-    const selectedEvent = this.lastSelectedNode() && this.lastSelectedNode().event;
-    this.refreshTree();
-    if (selectedEvent)
-      this._selectEvent(selectedEvent, false);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?TimelineModel.TimelineProfileTree.Node}
-   */
-  _findNodeWithEvent(event) {
-    const iterators = [this._currentTree.children().values()];
-
-    while (iterators.length) {
-      const iterator = iterators.peekLast().next();
-      if (iterator.done) {
-        iterators.pop();
-        continue;
-      }
-      const child = /** @type {!TimelineModel.TimelineProfileTree.Node} */ (iterator.value);
-      if (child.event === event)
-        return child;
-      iterators.push(child.children().values());
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {boolean=} expand
-   */
-  _selectEvent(event, expand) {
-    const node = this._findNodeWithEvent(event);
-    if (!node)
-      return;
-    this.selectProfileNode(node, false);
-    if (expand)
-      this.dataGridNodeForTreeNode(node).expand();
-  }
-
-  /**
-   * @override
-   * @param {!Array<!DataGrid.DataGrid.ColumnDescriptor>} columns
-   */
-  populateColumns(columns) {
-    columns.push(
-        {id: 'startTime', title: Common.UIString('Start Time'), width: '80px', fixedWidth: true, sortable: true});
-    super.populateColumns(columns);
-    columns.filter(c => c.fixedWidth).forEach(c => c.width = '80px');
-  }
-
-  /**
-   * @override
-   * @param {!UI.Toolbar} toolbar
-   */
-  populateToolbar(toolbar) {
-    super.populateToolbar(toolbar);
-    this._filtersControl.populateToolbar(toolbar);
-  }
-
-  /**
-   * @override
-   * @param {!TimelineModel.TimelineProfileTree.Node} node
-   * @return {boolean}
-   */
-  _showDetailsForNode(node) {
-    const traceEvent = node.event;
-    if (!traceEvent)
-      return false;
-    Timeline.TimelineUIUtils
-        .buildTraceEventDetails(traceEvent, this.model().timelineModel(), this._linkifier, this._badgePool, false)
-        .then(fragment => this._detailsView.element.appendChild(fragment));
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?TimelineModel.TimelineProfileTree.Node} node
-   */
-  _onHover(node) {
-    this._delegate.highlightEvent(node && node.event);
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.EventsTimelineTreeView.Filters = class extends Common.Object {
-  constructor() {
-    super();
-    this._categoryFilter = new Timeline.TimelineFilters.Category();
-    this._durationFilter = new Timeline.TimelineFilters.IsLong();
-    this._filters = [this._categoryFilter, this._durationFilter];
-  }
-
-  /**
-   * @return {!Array<!TimelineModel.TimelineModelFilter>}
-   */
-  filters() {
-    return this._filters;
-  }
-
-  /**
-   * @param {!UI.Toolbar} toolbar
-   */
-  populateToolbar(toolbar) {
-    const durationFilterUI = new UI.ToolbarComboBox(durationFilterChanged.bind(this));
-    for (const durationMs of Timeline.EventsTimelineTreeView.Filters._durationFilterPresetsMs) {
-      durationFilterUI.addOption(durationFilterUI.createOption(
-          durationMs ? Common.UIString('\u2265 %d\xa0ms', durationMs) : Common.UIString('All'),
-          durationMs ? Common.UIString('Hide records shorter than %d\xa0ms', durationMs) :
-                       Common.UIString('Show all records'),
-          String(durationMs)));
-    }
-    toolbar.appendToolbarItem(durationFilterUI);
-
-    const categoryFiltersUI = {};
-    const categories = Timeline.TimelineUIUtils.categories();
-    for (const categoryName in categories) {
-      const category = categories[categoryName];
-      if (!category.visible)
-        continue;
-      const checkbox =
-          new UI.ToolbarCheckbox(category.title, undefined, categoriesFilterChanged.bind(this, categoryName));
-      checkbox.setChecked(true);
-      checkbox.inputElement.style.backgroundColor = category.color;
-      categoryFiltersUI[category.name] = checkbox;
-      toolbar.appendToolbarItem(checkbox);
-    }
-
-    /**
-     * @this {Timeline.EventsTimelineTreeView.Filters}
-     */
-    function durationFilterChanged() {
-      const duration = durationFilterUI.selectedOption().value;
-      const minimumRecordDuration = parseInt(duration, 10);
-      this._durationFilter.setMinimumRecordDuration(minimumRecordDuration);
-      this._notifyFiltersChanged();
-    }
-
-    /**
-     * @param {string} name
-     * @this {Timeline.EventsTimelineTreeView.Filters}
-     */
-    function categoriesFilterChanged(name) {
-      const categories = Timeline.TimelineUIUtils.categories();
-      categories[name].hidden = !categoryFiltersUI[name].checked();
-      this._notifyFiltersChanged();
-    }
-  }
-
-  _notifyFiltersChanged() {
-    this.dispatchEventToListeners(Timeline.EventsTimelineTreeView.Filters.Events.FilterChanged);
-  }
-};
-
-Timeline.EventsTimelineTreeView.Filters._durationFilterPresetsMs = [0, 1, 15];
-
-/** @enum {symbol} */
-Timeline.EventsTimelineTreeView.Filters.Events = {
-  FilterChanged: Symbol('FilterChanged')
-};
diff --git a/front_end/timeline/ExtensionTracingSession.js b/front_end/timeline/ExtensionTracingSession.js
deleted file mode 100644
index fffe10f..0000000
--- a/front_end/timeline/ExtensionTracingSession.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Extensions.TracingSession}
- * @implements {Timeline.TimelineLoader.Client}
- */
-Timeline.ExtensionTracingSession = class {
-  /**
-   * @param {!Extensions.ExtensionTraceProvider} provider
-   * @param {!Timeline.PerformanceModel} performanceModel
-   */
-  constructor(provider, performanceModel) {
-    this._provider = provider;
-    this._performanceModel = performanceModel;
-    /** @type {function()} */
-    this._completionCallback;
-    this._completionPromise = new Promise(fulfill => {
-      this._completionCallback = fulfill;
-    });
-    this._timeOffset = 0;
-  }
-
-  /** @override */
-  loadingStarted() {
-  }
-
-  /** @override */
-  processingStarted() {
-  }
-
-  /**
-   * @override
-   * @param {number=} progress
-   */
-  loadingProgress(progress) {
-  }
-
-  /**
-   * @override
-   * @param {?SDK.TracingModel} tracingModel
-   */
-  loadingComplete(tracingModel) {
-    if (!tracingModel)
-      return;
-    this._performanceModel.addExtensionEvents(this._provider.longDisplayName(), tracingModel, this._timeOffset);
-    this._completionCallback();
-  }
-
-  /**
-   * @override
-   * @param {string} url
-   * @param {number} timeOffsetMicroseconds
-   */
-  complete(url, timeOffsetMicroseconds) {
-    if (!url) {
-      this._completionCallback();
-      return;
-    }
-    this._timeOffset = timeOffsetMicroseconds;
-    Timeline.TimelineLoader.loadFromURL(url, this);
-  }
-
-  start() {
-    this._provider.start(this);
-  }
-
-  /** @return {!Promise<string>} */
-  stop() {
-    this._provider.stop();
-    return this._completionPromise;
-  }
-};
diff --git a/front_end/timeline/PerformanceModel.js b/front_end/timeline/PerformanceModel.js
deleted file mode 100644
index d8d8028..0000000
--- a/front_end/timeline/PerformanceModel.js
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Timeline.PerformanceModel = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {?SDK.Target} */
-    this._mainTarget = null;
-    /** @type {?SDK.TracingModel} */
-    this._tracingModel = null;
-
-    this._timelineModel = new TimelineModel.TimelineModel();
-    this._frameModel =
-        new TimelineModel.TimelineFrameModel(event => Timeline.TimelineUIUtils.eventStyle(event).category.name);
-    /** @type {?SDK.FilmStripModel} */
-    this._filmStripModel = null;
-    /** @type {?TimelineModel.TimelineIRModel} */
-    this._irModel = new TimelineModel.TimelineIRModel();
-
-    /** @type {!Array<!{title: string, model: !SDK.TracingModel, timeOffset: number}>} */
-    this._extensionTracingModels = [];
-    /** @type {number|undefined} */
-    this._recordStartTime = undefined;
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   */
-  setMainTarget(target) {
-    this._mainTarget = target;
-  }
-
-  /**
-   * @param {number} time
-   */
-  setRecordStartTime(time) {
-    this._recordStartTime = time;
-  }
-
-  /**
-   * @return {number|undefined}
-   */
-  recordStartTime() {
-    return this._recordStartTime;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} model
-   */
-  setTracingModel(model) {
-    this._tracingModel = model;
-    this._timelineModel.setEvents(model, !this._mainTarget);
-
-    let inputEvents = null;
-    let animationEvents = null;
-    for (const track of this._timelineModel.tracks()) {
-      if (track.type === TimelineModel.TimelineModel.TrackType.Input)
-        inputEvents = track.asyncEvents;
-      if (track.type === TimelineModel.TimelineModel.TrackType.Animation)
-        animationEvents = track.asyncEvents;
-    }
-    if (inputEvents || animationEvents)
-      this._irModel.populate(inputEvents || [], animationEvents || []);
-
-    const mainTracks = this._timelineModel.tracks().filter(
-        track => track.type === TimelineModel.TimelineModel.TrackType.MainThread && track.forMainFrame &&
-            track.events.length);
-    const threadData = mainTracks.map(track => {
-      const event = track.events[0];
-      return {thread: event.thread, time: event.startTime};
-    });
-    this._frameModel.addTraceEvents(this._mainTarget, this._timelineModel.inspectedTargetEvents(), threadData);
-
-    for (const entry of this._extensionTracingModels) {
-      entry.model.adjustTime(
-          this._tracingModel.minimumRecordTime() + (entry.timeOffset / 1000) - this._recordStartTime);
-    }
-  }
-
-  /**
-   * @param {string} title
-   * @param {!SDK.TracingModel} model
-   * @param {number} timeOffset
-   */
-  addExtensionEvents(title, model, timeOffset) {
-    this._extensionTracingModels.push({model: model, title: title, timeOffset: timeOffset});
-    if (!this._tracingModel)
-      return;
-    model.adjustTime(this._tracingModel.minimumRecordTime() + (timeOffset / 1000) - this._recordStartTime);
-    this.dispatchEventToListeners(Timeline.PerformanceModel.Events.ExtensionDataAdded);
-  }
-
-  /**
-   * @return {!SDK.TracingModel}
-   */
-  tracingModel() {
-    if (!this._tracingModel)
-      throw 'call setTracingModel before accessing PerformanceModel';
-    return this._tracingModel;
-  }
-
-  /**
-   * @return {!TimelineModel.TimelineModel}
-   */
-  timelineModel() {
-    return this._timelineModel;
-  }
-
-  /**
-   * @return {!SDK.FilmStripModel} filmStripModel
-   */
-  filmStripModel() {
-    if (this._filmStripModel)
-      return this._filmStripModel;
-    if (!this._tracingModel)
-      throw 'call setTracingModel before accessing PerformanceModel';
-    this._filmStripModel = new SDK.FilmStripModel(this._tracingModel);
-    return this._filmStripModel;
-  }
-
-  /**
-   * @return {!Array<!TimelineModel.TimelineFrame>} frames
-   */
-  frames() {
-    return this._frameModel.frames();
-  }
-
-  /**
-   * @return {!TimelineModel.TimelineFrameModel} frames
-   */
-  frameModel() {
-    return this._frameModel;
-  }
-
-  /**
-   * @return {!Array<!Common.Segment>}
-   */
-  interactionRecords() {
-    return this._irModel.interactionRecords();
-  }
-
-  /**
-   * @return {!Array<!{title: string, model: !SDK.TracingModel}>}
-   */
-  extensionInfo() {
-    return this._extensionTracingModels;
-  }
-
-  dispose() {
-    if (this._tracingModel)
-      this._tracingModel.dispose();
-    for (const extensionEntry of this._extensionTracingModels)
-      extensionEntry.model.dispose();
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineFrame} frame
-   * @return {?SDK.FilmStripModel.Frame}
-   */
-  filmStripModelFrame(frame) {
-    // For idle frames, look at the state at the beginning of the frame.
-    const screenshotTime = frame.idle ? frame.startTime : frame.endTime;
-    const filmStripFrame = this._filmStripModel.frameByTimestamp(screenshotTime);
-    return filmStripFrame && filmStripFrame.timestamp - frame.endTime < 10 ? filmStripFrame : null;
-  }
-
-  /**
-   * @param {!Common.OutputStream} stream
-   * @return {!Promise<?FileError>}
-   */
-  save(stream) {
-    const backingStorage = /** @type {!Bindings.TempFileBackingStorage} */ (this._tracingModel.backingStorage());
-    return backingStorage.writeToStream(stream);
-  }
-};
-
-/**
- * @enum {symbol}
- */
-Timeline.PerformanceModel.Events = {
-  ExtensionDataAdded: Symbol('ExtensionDataAdded')
-};
diff --git a/front_end/timeline/TimelineController.js b/front_end/timeline/TimelineController.js
deleted file mode 100644
index 7a01424..0000000
--- a/front_end/timeline/TimelineController.js
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {SDK.SDKModelObserver<!SDK.CPUProfilerModel>}
- * @implements {SDK.TracingManagerClient}
- * @unrestricted
- */
-Timeline.TimelineController = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {!Timeline.TimelineController.Client} client
-   */
-  constructor(target, client) {
-    this._tracingManager = target.model(SDK.TracingManager);
-    this._performanceModel = new Timeline.PerformanceModel();
-    this._performanceModel.setMainTarget(target);
-    this._client = client;
-
-    const backingStorage = new Bindings.TempFileBackingStorage();
-    this._tracingModel = new SDK.TracingModel(backingStorage);
-
-    /** @type {!Array<!Timeline.ExtensionTracingSession>} */
-    this._extensionSessions = [];
-    SDK.targetManager.observeModels(SDK.CPUProfilerModel, this);
-  }
-
-  /**
-   * @return {!SDK.Target}
-   */
-  mainTarget() {
-    return this._tracingManager.target();
-  }
-
-  /**
-   * @param {!Timeline.TimelineController.RecordingOptions} options
-   * @param {!Array<!Extensions.ExtensionTraceProvider>} providers
-   * @return {!Promise}
-   */
-  startRecording(options, providers) {
-    this._extensionTraceProviders = Extensions.extensionServer.traceProviders().slice();
-
-    /**
-     * @param {string} category
-     * @return {string}
-     */
-    function disabledByDefault(category) {
-      return 'disabled-by-default-' + category;
-    }
-    const categoriesArray = [
-      '-*', 'devtools.timeline', 'v8.execute', disabledByDefault('devtools.timeline'),
-      disabledByDefault('devtools.timeline.frame'), SDK.TracingModel.TopLevelEventCategory,
-      TimelineModel.TimelineModel.Category.Console, TimelineModel.TimelineModel.Category.UserTiming
-    ];
-    categoriesArray.push(TimelineModel.TimelineModel.Category.LatencyInfo);
-
-    if (Runtime.experiments.isEnabled('timelineFlowEvents'))
-      categoriesArray.push('devtools.timeline.async');
-
-    if (Runtime.experiments.isEnabled('timelineV8RuntimeCallStats') && options.enableJSSampling)
-      categoriesArray.push(disabledByDefault('v8.runtime_stats_sampling'));
-    if (Runtime.experiments.isEnabled('timelineTracingJSProfile') && options.enableJSSampling) {
-      categoriesArray.push(disabledByDefault('v8.cpu_profiler'));
-      if (Common.moduleSetting('highResolutionCpuProfiling').get())
-        categoriesArray.push(disabledByDefault('v8.cpu_profiler.hires'));
-    }
-    categoriesArray.push(disabledByDefault('devtools.timeline.stack'));
-    if (Runtime.experiments.isEnabled('timelineInvalidationTracking'))
-      categoriesArray.push(disabledByDefault('devtools.timeline.invalidationTracking'));
-    if (options.capturePictures) {
-      categoriesArray.push(
-          disabledByDefault('devtools.timeline.layers'), disabledByDefault('devtools.timeline.picture'),
-          disabledByDefault('blink.graphics_context_annotations'));
-    }
-    if (options.captureFilmStrip)
-      categoriesArray.push(disabledByDefault('devtools.screenshot'));
-
-    this._extensionSessions =
-        providers.map(provider => new Timeline.ExtensionTracingSession(provider, this._performanceModel));
-    this._extensionSessions.forEach(session => session.start());
-    const startPromise = this._startRecordingWithCategories(categoriesArray.join(','), options.enableJSSampling);
-    this._performanceModel.setRecordStartTime(Date.now());
-    return startPromise;
-  }
-
-  /**
-   * @return {!Promise<!Timeline.PerformanceModel>}
-   */
-  async stopRecording() {
-    const tracingStoppedPromises = [];
-    tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve));
-    tracingStoppedPromises.push(this._stopProfilingOnAllModels());
-    this._tracingManager.stop();
-    tracingStoppedPromises.push(SDK.targetManager.resumeAllTargets());
-
-    this._client.loadingStarted();
-
-    const extensionCompletionPromises = this._extensionSessions.map(session => session.stop());
-    if (extensionCompletionPromises.length) {
-      tracingStoppedPromises.push(
-          Promise.race([Promise.all(extensionCompletionPromises), new Promise(r => setTimeout(r, 5000))]));
-    }
-    await Promise.all(tracingStoppedPromises);
-    this._allSourcesFinished();
-    return this._performanceModel;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CPUProfilerModel} cpuProfilerModel
-   */
-  modelAdded(cpuProfilerModel) {
-    if (this._profiling)
-      cpuProfilerModel.startRecording();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.CPUProfilerModel} cpuProfilerModel
-   */
-  modelRemoved(cpuProfilerModel) {
-    // FIXME: We'd like to stop profiling on the target and retrieve a profile
-    // but it's too late. Backend connection is closed.
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _startProfilingOnAllModels() {
-    this._profiling = true;
-    const models = SDK.targetManager.models(SDK.CPUProfilerModel);
-    return Promise.all(models.map(model => model.startRecording()));
-  }
-
-  /**
-   * @param {string} targetId
-   * @param {?Protocol.Profiler.Profile} cpuProfile
-   */
-  _addCpuProfile(targetId, cpuProfile) {
-    if (!cpuProfile) {
-      Common.console.warn(Common.UIString('CPU profile for a target is not available.'));
-      return;
-    }
-    if (!this._cpuProfiles)
-      this._cpuProfiles = new Map();
-    this._cpuProfiles.set(targetId, cpuProfile);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _stopProfilingOnAllModels() {
-    const models = this._profiling ? SDK.targetManager.models(SDK.CPUProfilerModel) : [];
-    this._profiling = false;
-    const promises = [];
-    for (const model of models) {
-      const targetId = model.target().id();
-      const modelPromise = model.stopRecording().then(this._addCpuProfile.bind(this, targetId));
-      promises.push(modelPromise);
-    }
-    return Promise.all(promises);
-  }
-
-  /**
-   * @param {string} categories
-   * @param {boolean=} enableJSSampling
-   * @return {!Promise}
-   */
-  _startRecordingWithCategories(categories, enableJSSampling) {
-    SDK.targetManager.suspendAllTargets();
-    const profilingStartedPromise = enableJSSampling && !Runtime.experiments.isEnabled('timelineTracingJSProfile') ?
-        this._startProfilingOnAllModels() :
-        Promise.resolve();
-    const samplingFrequencyHz = Common.moduleSetting('highResolutionCpuProfiling').get() ? 10000 : 1000;
-    const options = 'sampling-frequency=' + samplingFrequencyHz;
-    return profilingStartedPromise.then(() => this._tracingManager.start(this, categories, options));
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   * @override
-   */
-  traceEventsCollected(events) {
-    this._tracingModel.addEvents(events);
-  }
-
-  /**
-   * @override
-   */
-  tracingComplete() {
-    this._tracingCompleteCallback();
-    this._tracingCompleteCallback = null;
-  }
-
-  _allSourcesFinished() {
-    this._client.processingStarted();
-    setTimeout(() => this._finalizeTrace(), 0);
-  }
-
-  _finalizeTrace() {
-    this._injectCpuProfileEvents();
-    this._tracingModel.tracingComplete();
-    this._client.loadingComplete(this._tracingModel);
-  }
-
-  /**
-   * @param {number} pid
-   * @param {number} tid
-   * @param {?Protocol.Profiler.Profile} cpuProfile
-   */
-  _injectCpuProfileEvent(pid, tid, cpuProfile) {
-    if (!cpuProfile)
-      return;
-    const cpuProfileEvent = /** @type {!SDK.TracingManager.EventPayload} */ ({
-      cat: SDK.TracingModel.DevToolsMetadataEventCategory,
-      ph: SDK.TracingModel.Phase.Instant,
-      ts: this._tracingModel.maximumRecordTime() * 1000,
-      pid: pid,
-      tid: tid,
-      name: TimelineModel.TimelineModel.RecordType.CpuProfile,
-      args: {data: {cpuProfile: cpuProfile}}
-    });
-    this._tracingModel.addEvents([cpuProfileEvent]);
-  }
-
-  _injectCpuProfileEvents() {
-    if (!this._cpuProfiles)
-      return;
-
-    const metadataEventTypes = TimelineModel.TimelineModel.DevToolsMetadataEvent;
-    const metadataEvents = this._tracingModel.devToolsMetadataEvents();
-    const mainMetaEvent =
-        metadataEvents.filter(event => event.name === metadataEventTypes.TracingStartedInPage).peekLast();
-    if (!mainMetaEvent)
-      return;
-
-    const pid = mainMetaEvent.thread.process().id();
-    const mainCpuProfile = this._cpuProfiles.get(this._tracingManager.target().id());
-    this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfile);
-
-    const workerMetaEvents =
-        metadataEvents.filter(event => event.name === metadataEventTypes.TracingSessionIdForWorker);
-    for (const metaEvent of workerMetaEvents) {
-      const workerId = metaEvent.args['data']['workerId'];
-      const cpuProfile = this._cpuProfiles.get(workerId);
-      this._injectCpuProfileEvent(
-          metaEvent.thread.process().id(), metaEvent.args['data']['workerThreadId'], cpuProfile);
-    }
-    this._cpuProfiles = null;
-  }
-
-  /**
-   * @param {number} usage
-   * @override
-   */
-  tracingBufferUsage(usage) {
-    this._client.recordingProgress(usage);
-  }
-
-  /**
-   * @param {number} progress
-   * @override
-   */
-  eventsRetrievalProgress(progress) {
-    this._client.loadingProgress(progress);
-  }
-};
-
-/**
- * @interface
- * @extends {Timeline.TimelineLoader.Client}
- */
-Timeline.TimelineController.Client = function() {};
-
-Timeline.TimelineController.Client.prototype = {
-  /**
-   * @param {number} usage
-   */
-  recordingProgress(usage) {},
-};
-
-/**
- * @typedef {!{
- *   enableJSSampling: (boolean|undefined),
- *   capturePictures: (boolean|undefined),
- *   captureFilmStrip: (boolean|undefined)
- * }}
- */
-Timeline.TimelineController.RecordingOptions;
diff --git a/front_end/timeline/TimelineDetailsView.js b/front_end/timeline/TimelineDetailsView.js
deleted file mode 100644
index fc1b318..0000000
--- a/front_end/timeline/TimelineDetailsView.js
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- */
-Timeline.TimelineDetailsView = class extends UI.VBox {
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   * @param {!Timeline.TimelineModeViewDelegate} delegate
-   */
-  constructor(filters, delegate) {
-    super();
-    this.element.classList.add('timeline-details');
-
-    this._detailsLinkifier = new Components.Linkifier();
-    this._badgePool = new ProductRegistry.BadgePool();
-    this._badgePool.setShowTitles(true);
-
-    this._tabbedPane = new UI.TabbedPane();
-    this._tabbedPane.show(this.element);
-
-    const tabIds = Timeline.TimelineDetailsView.Tab;
-
-    this._defaultDetailsWidget = new UI.VBox();
-    this._defaultDetailsWidget.element.classList.add('timeline-details-view');
-    this._defaultDetailsContentElement =
-        this._defaultDetailsWidget.element.createChild('div', 'timeline-details-view-body vbox');
-    this._defaultDetailsContentElement.tabIndex = 0;
-    this._appendTab(tabIds.Details, Common.UIString('Summary'), this._defaultDetailsWidget);
-    this.setPreferredTab(tabIds.Details);
-
-    /** @type Map<string, Timeline.TimelineTreeView> */
-    this._rangeDetailViews = new Map();
-
-    const bottomUpView = new Timeline.BottomUpTimelineTreeView(filters);
-    this._appendTab(tabIds.BottomUp, Common.UIString('Bottom-Up'), bottomUpView);
-    this._rangeDetailViews.set(tabIds.BottomUp, bottomUpView);
-
-    const callTreeView = new Timeline.CallTreeTimelineTreeView(filters);
-    this._appendTab(tabIds.CallTree, Common.UIString('Call Tree'), callTreeView);
-    this._rangeDetailViews.set(tabIds.CallTree, callTreeView);
-
-    const eventsView = new Timeline.EventsTimelineTreeView(filters, delegate);
-    this._appendTab(tabIds.EventLog, Common.UIString('Event Log'), eventsView);
-    this._rangeDetailViews.set(tabIds.EventLog, eventsView);
-
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} model
-   * @param {?TimelineModel.TimelineModel.Track} track
-   */
-  setModel(model, track) {
-    this._model = model;
-    this._track = track;
-    this._tabbedPane.closeTabs(
-        [Timeline.TimelineDetailsView.Tab.PaintProfiler, Timeline.TimelineDetailsView.Tab.LayerViewer], false);
-    for (const view of this._rangeDetailViews.values())
-      view.setModel(model, track);
-    this._lazyPaintProfilerView = null;
-    this._lazyLayersView = null;
-  }
-
-  /**
-   * @param {!Node} node
-   */
-  _setContent(node) {
-    const allTabs = this._tabbedPane.otherTabs(Timeline.TimelineDetailsView.Tab.Details);
-    for (let i = 0; i < allTabs.length; ++i) {
-      if (!this._rangeDetailViews.has(allTabs[i]))
-        this._tabbedPane.closeTab(allTabs[i]);
-    }
-    this._defaultDetailsContentElement.removeChildren();
-    this._defaultDetailsContentElement.appendChild(node);
-  }
-
-  _updateContents() {
-    const view = this._rangeDetailViews.get(this._tabbedPane.selectedTabId || '');
-    if (view)
-      view.updateContents(this._selection);
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} tabTitle
-   * @param {!UI.Widget} view
-   * @param {boolean=} isCloseable
-   */
-  _appendTab(id, tabTitle, view, isCloseable) {
-    this._tabbedPane.appendTab(id, tabTitle, view, undefined, undefined, isCloseable);
-    if (this._preferredTabId !== this._tabbedPane.selectedTabId)
-      this._tabbedPane.selectTab(id);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  headerElement() {
-    return this._tabbedPane.headerElement();
-  }
-
-  /**
-   * @param {string} tabId
-   */
-  setPreferredTab(tabId) {
-    this._preferredTabId = tabId;
-  }
-
-  /**
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  setSelection(selection) {
-    this._detailsLinkifier.reset();
-    this._badgePool.reset();
-    this._selection = selection;
-    switch (this._selection.type()) {
-      case Timeline.TimelineSelection.Type.TraceEvent:
-        const event = /** @type {!SDK.TracingModel.Event} */ (this._selection.object());
-        Timeline.TimelineUIUtils
-            .buildTraceEventDetails(event, this._model.timelineModel(), this._detailsLinkifier, this._badgePool, true)
-            .then(fragment => this._appendDetailsTabsForTraceEventAndShowDetails(event, fragment));
-        break;
-      case Timeline.TimelineSelection.Type.Frame:
-        const frame = /** @type {!TimelineModel.TimelineFrame} */ (this._selection.object());
-        const filmStripFrame = this._model.filmStripModelFrame(frame);
-        this._setContent(Timeline.TimelineUIUtils.generateDetailsContentForFrame(frame, filmStripFrame));
-        if (frame.layerTree) {
-          const layersView = this._layersView();
-          layersView.showLayerTree(frame.layerTree);
-          if (!this._tabbedPane.hasTab(Timeline.TimelineDetailsView.Tab.LayerViewer))
-            this._appendTab(Timeline.TimelineDetailsView.Tab.LayerViewer, Common.UIString('Layers'), layersView);
-        }
-        break;
-      case Timeline.TimelineSelection.Type.NetworkRequest:
-        const request = /** @type {!TimelineModel.TimelineModel.NetworkRequest} */ (this._selection.object());
-        Timeline.TimelineUIUtils
-            .buildNetworkRequestDetails(request, this._model.timelineModel(), this._detailsLinkifier, this._badgePool)
-            .then(this._setContent.bind(this));
-        break;
-      case Timeline.TimelineSelection.Type.Range:
-        this._updateSelectedRangeStats(this._selection.startTime(), this._selection.endTime());
-        break;
-    }
-
-    this._updateContents();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabSelected(event) {
-    if (!event.data.isUserGesture)
-      return;
-    this.setPreferredTab(event.data.tabId);
-    this._updateContents();
-  }
-
-  /**
-   * @return {!UI.Widget}
-   */
-  _layersView() {
-    if (this._lazyLayersView)
-      return this._lazyLayersView;
-    this._lazyLayersView =
-        new Timeline.TimelineLayersView(this._model.timelineModel(), this._showSnapshotInPaintProfiler.bind(this));
-    return this._lazyLayersView;
-  }
-
-  /**
-   * @return {!Timeline.TimelinePaintProfilerView}
-   */
-  _paintProfilerView() {
-    if (this._lazyPaintProfilerView)
-      return this._lazyPaintProfilerView;
-    this._lazyPaintProfilerView = new Timeline.TimelinePaintProfilerView(this._model.frameModel());
-    return this._lazyPaintProfilerView;
-  }
-
-  /**
-   * @param {!SDK.PaintProfilerSnapshot} snapshot
-   */
-  _showSnapshotInPaintProfiler(snapshot) {
-    const paintProfilerView = this._paintProfilerView();
-    paintProfilerView.setSnapshot(snapshot);
-    if (!this._tabbedPane.hasTab(Timeline.TimelineDetailsView.Tab.PaintProfiler)) {
-      this._appendTab(
-          Timeline.TimelineDetailsView.Tab.PaintProfiler, Common.UIString('Paint Profiler'), paintProfilerView, true);
-    }
-    this._tabbedPane.selectTab(Timeline.TimelineDetailsView.Tab.PaintProfiler, true);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {!Node} content
-   */
-  _appendDetailsTabsForTraceEventAndShowDetails(event, content) {
-    this._setContent(content);
-    if (event.name === TimelineModel.TimelineModel.RecordType.Paint ||
-        event.name === TimelineModel.TimelineModel.RecordType.RasterTask)
-      this._showEventInPaintProfiler(event);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _showEventInPaintProfiler(event) {
-    const paintProfilerModel = SDK.targetManager.models(SDK.PaintProfilerModel)[0];
-    if (!paintProfilerModel)
-      return;
-    const paintProfilerView = this._paintProfilerView();
-    const hasProfileData = paintProfilerView.setEvent(paintProfilerModel, event);
-    if (!hasProfileData)
-      return;
-    if (this._tabbedPane.hasTab(Timeline.TimelineDetailsView.Tab.PaintProfiler))
-      return;
-    this._appendTab(
-        Timeline.TimelineDetailsView.Tab.PaintProfiler, Common.UIString('Paint Profiler'), paintProfilerView);
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  _updateSelectedRangeStats(startTime, endTime) {
-    if (!this._model || !this._track)
-      return;
-    const aggregatedStats = Timeline.TimelineUIUtils.statsForTimeRange(this._track.syncEvents(), startTime, endTime);
-    const startOffset = startTime - this._model.timelineModel().minimumRecordTime();
-    const endOffset = endTime - this._model.timelineModel().minimumRecordTime();
-
-    const contentHelper = new Timeline.TimelineDetailsContentHelper(null, null);
-    contentHelper.addSection(
-        ls`Range:  ${Number.millisToString(startOffset)} \u2013 ${Number.millisToString(endOffset)}`);
-    const pieChart = Timeline.TimelineUIUtils.generatePieChart(aggregatedStats);
-    contentHelper.appendElementRow('', pieChart);
-    this._setContent(contentHelper.fragment);
-  }
-};
-
-/**
- * @enum {string}
- */
-Timeline.TimelineDetailsView.Tab = {
-  Details: 'Details',
-  EventLog: 'EventLog',
-  CallTree: 'CallTree',
-  BottomUp: 'BottomUp',
-  PaintProfiler: 'PaintProfiler',
-  LayerViewer: 'LayerViewer'
-};
diff --git a/front_end/timeline/TimelineEventOverview.js b/front_end/timeline/TimelineEventOverview.js
deleted file mode 100644
index 63beaf9..0000000
--- a/front_end/timeline/TimelineEventOverview.js
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverview = class extends PerfUI.TimelineOverviewBase {
-  /**
-   * @param {string} id
-   * @param {?string} title
-   */
-  constructor(id, title) {
-    super();
-    this.element.id = 'timeline-overview-' + id;
-    this.element.classList.add('overview-strip');
-    /** @type {?Timeline.PerformanceModel} */
-    this._model = null;
-    if (title)
-      this.element.createChild('div', 'timeline-overview-strip-title').textContent = title;
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} model
-   */
-  setModel(model) {
-    this._model = model;
-  }
-
-  /**
-   * @param {number} begin
-   * @param {number} end
-   * @param {number} position
-   * @param {number} height
-   * @param {string} color
-   */
-  _renderBar(begin, end, position, height, color) {
-    const x = begin;
-    const width = end - begin;
-    const ctx = this.context();
-    ctx.fillStyle = color;
-    ctx.fillRect(x, position, width, height);
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverviewInput = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('input', null);
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    if (!this._model)
-      return;
-    const height = this.height();
-    const descriptors = Timeline.TimelineUIUtils.eventDispatchDesciptors();
-    /** @type {!Map.<string,!Timeline.TimelineUIUtils.EventDispatchTypeDescriptor>} */
-    const descriptorsByType = new Map();
-    let maxPriority = -1;
-    for (const descriptor of descriptors) {
-      for (const type of descriptor.eventTypes)
-        descriptorsByType.set(type, descriptor);
-      maxPriority = Math.max(maxPriority, descriptor.priority);
-    }
-
-    const minWidth = 2 * window.devicePixelRatio;
-    const timeOffset = this._model.timelineModel().minimumRecordTime();
-    const timeSpan = this._model.timelineModel().maximumRecordTime() - timeOffset;
-    const canvasWidth = this.width();
-    const scale = canvasWidth / timeSpan;
-
-    for (let priority = 0; priority <= maxPriority; ++priority) {
-      for (const track of this._model.timelineModel().tracks()) {
-        for (let i = 0; i < track.events.length; ++i) {
-          const event = track.events[i];
-          if (event.name !== TimelineModel.TimelineModel.RecordType.EventDispatch)
-            continue;
-          const descriptor = descriptorsByType.get(event.args['data']['type']);
-          if (!descriptor || descriptor.priority !== priority)
-            continue;
-          const start = Number.constrain(Math.floor((event.startTime - timeOffset) * scale), 0, canvasWidth);
-          const end = Number.constrain(Math.ceil((event.endTime - timeOffset) * scale), 0, canvasWidth);
-          const width = Math.max(end - start, minWidth);
-          this._renderBar(start, start + width, 0, height, descriptor.color);
-        }
-      }
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverviewNetwork = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('network', Common.UIString('NET'));
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    if (!this._model)
-      return;
-    const timelineModel = this._model.timelineModel();
-    const bandHeight = this.height() / 2;
-    const timeOffset = timelineModel.minimumRecordTime();
-    const timeSpan = timelineModel.maximumRecordTime() - timeOffset;
-    const canvasWidth = this.width();
-    const scale = canvasWidth / timeSpan;
-    const highPath = new Path2D();
-    const lowPath = new Path2D();
-    const priorities = Protocol.Network.ResourcePriority;
-    const highPrioritySet = new Set([priorities.VeryHigh, priorities.High, priorities.Medium]);
-    for (const request of timelineModel.networkRequests()) {
-      const path = highPrioritySet.has(request.priority) ? highPath : lowPath;
-      const s = Math.max(Math.floor((request.startTime - timeOffset) * scale), 0);
-      const e = Math.min(Math.ceil((request.endTime - timeOffset) * scale + 1), canvasWidth);
-      path.rect(s, 0, e - s, bandHeight - 1);
-    }
-    const ctx = this.context();
-    ctx.save();
-    ctx.fillStyle = 'hsl(214, 60%, 60%)';
-    ctx.fill(/** @type {?} */ (highPath));
-    ctx.translate(0, bandHeight);
-    ctx.fillStyle = 'hsl(214, 80%, 80%)';
-    ctx.fill(/** @type {?} */ (lowPath));
-    ctx.restore();
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverviewCPUActivity = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('cpu-activity', Common.UIString('CPU'));
-    this._backgroundCanvas = this.element.createChild('canvas', 'fill background');
-  }
-
-  /**
-   * @override
-   */
-  resetCanvas() {
-    super.resetCanvas();
-    this._backgroundCanvas.width = this.element.clientWidth * window.devicePixelRatio;
-    this._backgroundCanvas.height = this.element.clientHeight * window.devicePixelRatio;
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    if (!this._model)
-      return;
-    const timelineModel = this._model.timelineModel();
-    const /** @const */ quantSizePx = 4 * window.devicePixelRatio;
-    const width = this.width();
-    const height = this.height();
-    const baseLine = height;
-    const timeOffset = timelineModel.minimumRecordTime();
-    const timeSpan = timelineModel.maximumRecordTime() - timeOffset;
-    const scale = width / timeSpan;
-    const quantTime = quantSizePx / scale;
-    const categories = Timeline.TimelineUIUtils.categories();
-    const categoryOrder = ['idle', 'loading', 'painting', 'rendering', 'scripting', 'other'];
-    const otherIndex = categoryOrder.indexOf('other');
-    const idleIndex = 0;
-    console.assert(idleIndex === categoryOrder.indexOf('idle'));
-    for (let i = idleIndex + 1; i < categoryOrder.length; ++i)
-      categories[categoryOrder[i]]._overviewIndex = i;
-
-    const backgroundContext = this._backgroundCanvas.getContext('2d');
-    for (const track of timelineModel.tracks()) {
-      if (track.type === TimelineModel.TimelineModel.TrackType.MainThread && track.forMainFrame)
-        drawThreadEvents(this.context(), track.events);
-      else
-        drawThreadEvents(backgroundContext, track.events);
-    }
-    applyPattern(backgroundContext);
-
-    /**
-     * @param {!CanvasRenderingContext2D} ctx
-     * @param {!Array<!SDK.TracingModel.Event>} events
-     */
-    function drawThreadEvents(ctx, events) {
-      const quantizer = new Timeline.Quantizer(timeOffset, quantTime, drawSample);
-      let x = 0;
-      const categoryIndexStack = [];
-      const paths = [];
-      const lastY = [];
-      for (let i = 0; i < categoryOrder.length; ++i) {
-        paths[i] = new Path2D();
-        paths[i].moveTo(0, height);
-        lastY[i] = height;
-      }
-
-      /**
-       * @param {!Array<number>} counters
-       */
-      function drawSample(counters) {
-        let y = baseLine;
-        for (let i = idleIndex + 1; i < categoryOrder.length; ++i) {
-          const h = (counters[i] || 0) / quantTime * height;
-          y -= h;
-          paths[i].bezierCurveTo(x, lastY[i], x, y, x + quantSizePx / 2, y);
-          lastY[i] = y;
-        }
-        x += quantSizePx;
-      }
-
-      /**
-       * @param {!SDK.TracingModel.Event} e
-       */
-      function onEventStart(e) {
-        const index = categoryIndexStack.length ? categoryIndexStack.peekLast() : idleIndex;
-        quantizer.appendInterval(e.startTime, index);
-        categoryIndexStack.push(Timeline.TimelineUIUtils.eventStyle(e).category._overviewIndex || otherIndex);
-      }
-
-      /**
-       * @param {!SDK.TracingModel.Event} e
-       */
-      function onEventEnd(e) {
-        quantizer.appendInterval(e.endTime, categoryIndexStack.pop());
-      }
-
-      TimelineModel.TimelineModel.forEachEvent(events, onEventStart, onEventEnd);
-      quantizer.appendInterval(timeOffset + timeSpan + quantTime, idleIndex);  // Kick drawing the last bucket.
-      for (let i = categoryOrder.length - 1; i > 0; --i) {
-        paths[i].lineTo(width, height);
-        ctx.fillStyle = categories[categoryOrder[i]].color;
-        ctx.fill(paths[i]);
-      }
-    }
-
-    /**
-     * @param {!CanvasRenderingContext2D} ctx
-     */
-    function applyPattern(ctx) {
-      const step = 4 * window.devicePixelRatio;
-      ctx.save();
-      ctx.lineWidth = step / Math.sqrt(8);
-      for (let x = 0.5; x < width + height; x += step) {
-        ctx.moveTo(x, 0);
-        ctx.lineTo(x - height, height);
-      }
-      ctx.globalCompositeOperation = 'destination-out';
-      ctx.stroke();
-      ctx.restore();
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverviewResponsiveness = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('responsiveness', null);
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    if (!this._model)
-      return;
-    const height = this.height();
-
-    const timeOffset = this._model.timelineModel().minimumRecordTime();
-    const timeSpan = this._model.timelineModel().maximumRecordTime() - timeOffset;
-    const scale = this.width() / timeSpan;
-    const frames = this._model.frames();
-    // This is due to usage of new signatures of fill() and storke() that closure compiler does not recognize.
-    const ctx = /** @type {!Object} */ (this.context());
-    const fillPath = new Path2D();
-    const markersPath = new Path2D();
-    for (let i = 0; i < frames.length; ++i) {
-      const frame = frames[i];
-      if (!frame.hasWarnings())
-        continue;
-      paintWarningDecoration(frame.startTime, frame.duration);
-    }
-
-    for (const track of this._model.timelineModel().tracks()) {
-      const events = track.events;
-      for (let i = 0; i < events.length; ++i) {
-        if (!TimelineModel.TimelineData.forEvent(events[i]).warning)
-          continue;
-        paintWarningDecoration(events[i].startTime, events[i].duration);
-      }
-    }
-
-    ctx.fillStyle = 'hsl(0, 80%, 90%)';
-    ctx.strokeStyle = 'red';
-    ctx.lineWidth = 2 * window.devicePixelRatio;
-    ctx.fill(fillPath);
-    ctx.stroke(markersPath);
-
-    /**
-     * @param {number} time
-     * @param {number} duration
-     */
-    function paintWarningDecoration(time, duration) {
-      const x = Math.round(scale * (time - timeOffset));
-      const w = Math.round(scale * duration);
-      fillPath.rect(x, 0, w, height);
-      markersPath.moveTo(x + w, 0);
-      markersPath.lineTo(x + w, height);
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineFilmStripOverview = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('filmstrip', null);
-    this.reset();
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    const frames = this._model ? this._model.filmStripModel().frames() : [];
-    if (!frames.length)
-      return;
-
-    const drawGeneration = Symbol('drawGeneration');
-    this._drawGeneration = drawGeneration;
-    this._imageByFrame(frames[0]).then(image => {
-      if (this._drawGeneration !== drawGeneration)
-        return;
-      if (!image || !image.naturalWidth || !image.naturalHeight)
-        return;
-      const imageHeight = this.height() - 2 * Timeline.TimelineFilmStripOverview.Padding;
-      const imageWidth = Math.ceil(imageHeight * image.naturalWidth / image.naturalHeight);
-      const popoverScale = Math.min(200 / image.naturalWidth, 1);
-      this._emptyImage = new Image(image.naturalWidth * popoverScale, image.naturalHeight * popoverScale);
-      this._drawFrames(imageWidth, imageHeight);
-    });
-  }
-
-  /**
-   * @param {!SDK.FilmStripModel.Frame} frame
-   * @return {!Promise<?HTMLImageElement>}
-   */
-  _imageByFrame(frame) {
-    let imagePromise = this._frameToImagePromise.get(frame);
-    if (!imagePromise) {
-      imagePromise = frame.imageDataPromise().then(data => UI.loadImageFromData(data));
-      this._frameToImagePromise.set(frame, imagePromise);
-    }
-    return imagePromise;
-  }
-
-  /**
-   * @param {number} imageWidth
-   * @param {number} imageHeight
-   */
-  _drawFrames(imageWidth, imageHeight) {
-    if (!imageWidth || !this._model)
-      return;
-    const filmStripModel = this._model.filmStripModel();
-    if (!filmStripModel.frames().length)
-      return;
-    const padding = Timeline.TimelineFilmStripOverview.Padding;
-    const width = this.width();
-    const zeroTime = filmStripModel.zeroTime();
-    const spanTime = filmStripModel.spanTime();
-    const scale = spanTime / width;
-    const context = this.context();
-    const drawGeneration = this._drawGeneration;
-
-    context.beginPath();
-    for (let x = padding; x < width; x += imageWidth + 2 * padding) {
-      const time = zeroTime + (x + imageWidth / 2) * scale;
-      const frame = filmStripModel.frameByTimestamp(time);
-      if (!frame)
-        continue;
-      context.rect(x - 0.5, 0.5, imageWidth + 1, imageHeight + 1);
-      this._imageByFrame(frame).then(drawFrameImage.bind(this, x));
-    }
-    context.strokeStyle = '#ddd';
-    context.stroke();
-
-    /**
-     * @param {number} x
-     * @param {?HTMLImageElement} image
-     * @this {Timeline.TimelineFilmStripOverview}
-     */
-    function drawFrameImage(x, image) {
-      // Ignore draws deferred from a previous update call.
-      if (this._drawGeneration !== drawGeneration || !image)
-        return;
-      context.drawImage(image, x, 1, imageWidth, imageHeight);
-    }
-  }
-
-  /**
-   * @override
-   * @param {number} x
-   * @return {!Promise<?Element>}
-   */
-  overviewInfoPromise(x) {
-    if (!this._model || !this._model.filmStripModel().frames().length)
-      return Promise.resolve(/** @type {?Element} */ (null));
-
-    const time = this.calculator().positionToTime(x);
-    const frame = this._model.filmStripModel().frameByTimestamp(time);
-    if (frame === this._lastFrame)
-      return Promise.resolve(this._lastElement);
-    const imagePromise = frame ? this._imageByFrame(frame) : Promise.resolve(this._emptyImage);
-    return imagePromise.then(createFrameElement.bind(this));
-
-    /**
-     * @this {Timeline.TimelineFilmStripOverview}
-     * @param {?HTMLImageElement} image
-     * @return {?Element}
-     */
-    function createFrameElement(image) {
-      const element = createElementWithClass('div', 'frame');
-      if (image)
-        element.createChild('div', 'thumbnail').appendChild(image);
-      this._lastFrame = frame;
-      this._lastElement = element;
-      return element;
-    }
-  }
-
-  /**
-   * @override
-   */
-  reset() {
-    this._lastFrame = undefined;
-    this._lastElement = null;
-    /** @type {!Map<!SDK.FilmStripModel.Frame,!Promise<!HTMLImageElement>>} */
-    this._frameToImagePromise = new Map();
-    this._imageWidth = 0;
-  }
-};
-
-Timeline.TimelineFilmStripOverview.Padding = 2;
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverviewFrames = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('framerate', Common.UIString('FPS'));
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    if (!this._model)
-      return;
-    const frames = this._model.frames();
-    if (!frames.length)
-      return;
-    const height = this.height();
-    const /** @const */ padding = 1 * window.devicePixelRatio;
-    const /** @const */ baseFrameDurationMs = 1e3 / 60;
-    const visualHeight = height - 2 * padding;
-    const timeOffset = this._model.timelineModel().minimumRecordTime();
-    const timeSpan = this._model.timelineModel().maximumRecordTime() - timeOffset;
-    const scale = this.width() / timeSpan;
-    const baseY = height - padding;
-    const ctx = this.context();
-    const bottomY = baseY + 10 * window.devicePixelRatio;
-    let x = 0;
-    let y = bottomY;
-
-    const lineWidth = window.devicePixelRatio;
-    const offset = lineWidth & 1 ? 0.5 : 0;
-    const tickDepth = 1.5 * window.devicePixelRatio;
-    ctx.beginPath();
-    ctx.moveTo(0, y);
-    for (let i = 0; i < frames.length; ++i) {
-      const frame = frames[i];
-      x = Math.round((frame.startTime - timeOffset) * scale) + offset;
-      ctx.lineTo(x, y);
-      ctx.lineTo(x, y + tickDepth);
-      y = frame.idle ? bottomY :
-                       Math.round(baseY - visualHeight * Math.min(baseFrameDurationMs / frame.duration, 1)) - offset;
-      ctx.lineTo(x, y + tickDepth);
-      ctx.lineTo(x, y);
-    }
-    const lastFrame = frames.peekLast();
-    x = Math.round((lastFrame.startTime + lastFrame.duration - timeOffset) * scale) + offset;
-    ctx.lineTo(x, y);
-    ctx.lineTo(x, bottomY);
-    ctx.fillStyle = 'hsl(110, 50%, 88%)';
-    ctx.strokeStyle = 'hsl(110, 50%, 60%)';
-    ctx.lineWidth = lineWidth;
-    ctx.fill();
-    ctx.stroke();
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineEventOverviewMemory = class extends Timeline.TimelineEventOverview {
-  constructor() {
-    super('memory', Common.UIString('HEAP'));
-    this._heapSizeLabel = this.element.createChild('div', 'memory-graph-label');
-  }
-
-  resetHeapSizeLabels() {
-    this._heapSizeLabel.textContent = '';
-  }
-
-  /**
-   * @override
-   */
-  update() {
-    super.update();
-    const ratio = window.devicePixelRatio;
-
-    if (!this._model) {
-      this.resetHeapSizeLabels();
-      return;
-    }
-
-    const tracks = this._model.timelineModel().tracks().filter(
-        track => track.type === TimelineModel.TimelineModel.TrackType.MainThread && track.forMainFrame);
-    const trackEvents = tracks.map(track => track.events);
-
-    const lowerOffset = 3 * ratio;
-    let maxUsedHeapSize = 0;
-    let minUsedHeapSize = 100000000000;
-    const minTime = this._model.timelineModel().minimumRecordTime();
-    const maxTime = this._model.timelineModel().maximumRecordTime();
-
-    /**
-     * @param {!SDK.TracingModel.Event} event
-     * @return {boolean}
-     */
-    function isUpdateCountersEvent(event) {
-      return event.name === TimelineModel.TimelineModel.RecordType.UpdateCounters;
-    }
-    for (let i = 0; i < trackEvents.length; i++)
-      trackEvents[i] = trackEvents[i].filter(isUpdateCountersEvent);
-
-    /**
-     * @param {!SDK.TracingModel.Event} event
-     */
-    function calculateMinMaxSizes(event) {
-      const counters = event.args.data;
-      if (!counters || !counters.jsHeapSizeUsed)
-        return;
-      maxUsedHeapSize = Math.max(maxUsedHeapSize, counters.jsHeapSizeUsed);
-      minUsedHeapSize = Math.min(minUsedHeapSize, counters.jsHeapSizeUsed);
-    }
-    for (let i = 0; i < trackEvents.length; i++)
-      trackEvents[i].forEach(calculateMinMaxSizes);
-    minUsedHeapSize = Math.min(minUsedHeapSize, maxUsedHeapSize);
-
-    const lineWidth = 1;
-    const width = this.width();
-    const height = this.height() - lowerOffset;
-    const xFactor = width / (maxTime - minTime);
-    const yFactor = (height - lineWidth) / Math.max(maxUsedHeapSize - minUsedHeapSize, 1);
-
-    const histogram = new Array(width);
-
-    /**
-     * @param {!SDK.TracingModel.Event} event
-     */
-    function buildHistogram(event) {
-      const counters = event.args.data;
-      if (!counters || !counters.jsHeapSizeUsed)
-        return;
-      const x = Math.round((event.startTime - minTime) * xFactor);
-      const y = Math.round((counters.jsHeapSizeUsed - minUsedHeapSize) * yFactor);
-      // TODO(alph): use sum instead of max.
-      histogram[x] = Math.max(histogram[x] || 0, y);
-    }
-    for (let i = 0; i < trackEvents.length; i++)
-      trackEvents[i].forEach(buildHistogram);
-
-    const ctx = this.context();
-    const heightBeyondView = height + lowerOffset + lineWidth;
-
-    ctx.translate(0.5, 0.5);
-    ctx.beginPath();
-    ctx.moveTo(-lineWidth, heightBeyondView);
-    let y = 0;
-    let isFirstPoint = true;
-    let lastX = 0;
-    for (let x = 0; x < histogram.length; x++) {
-      if (typeof histogram[x] === 'undefined')
-        continue;
-      if (isFirstPoint) {
-        isFirstPoint = false;
-        y = histogram[x];
-        ctx.lineTo(-lineWidth, height - y);
-      }
-      const nextY = histogram[x];
-      if (Math.abs(nextY - y) > 2 && Math.abs(x - lastX) > 1)
-        ctx.lineTo(x, height - y);
-      y = nextY;
-      ctx.lineTo(x, height - y);
-      lastX = x;
-    }
-    ctx.lineTo(width + lineWidth, height - y);
-    ctx.lineTo(width + lineWidth, heightBeyondView);
-    ctx.closePath();
-
-    ctx.fillStyle = 'hsla(220, 90%, 70%, 0.2)';
-    ctx.fill();
-    ctx.lineWidth = lineWidth;
-    ctx.strokeStyle = 'hsl(220, 90%, 70%)';
-    ctx.stroke();
-
-    this._heapSizeLabel.textContent =
-        Common.UIString('%s \u2013 %s', Number.bytesToString(minUsedHeapSize), Number.bytesToString(maxUsedHeapSize));
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.Quantizer = class {
-  /**
-   * @param {number} startTime
-   * @param {number} quantDuration
-   * @param {function(!Array<number>)} callback
-   */
-  constructor(startTime, quantDuration, callback) {
-    this._lastTime = startTime;
-    this._quantDuration = quantDuration;
-    this._callback = callback;
-    this._counters = [];
-    this._remainder = quantDuration;
-  }
-
-  /**
-   * @param {number} time
-   * @param {number} group
-   */
-  appendInterval(time, group) {
-    let interval = time - this._lastTime;
-    if (interval <= this._remainder) {
-      this._counters[group] = (this._counters[group] || 0) + interval;
-      this._remainder -= interval;
-      this._lastTime = time;
-      return;
-    }
-    this._counters[group] = (this._counters[group] || 0) + this._remainder;
-    this._callback(this._counters);
-    interval -= this._remainder;
-    while (interval >= this._quantDuration) {
-      const counters = [];
-      counters[group] = this._quantDuration;
-      this._callback(counters);
-      interval -= this._quantDuration;
-    }
-    this._counters = [];
-    this._counters[group] = interval;
-    this._lastTime = time;
-    this._remainder = this._quantDuration - interval;
-  }
-};
diff --git a/front_end/timeline/TimelineFilters.js b/front_end/timeline/TimelineFilters.js
deleted file mode 100644
index d3de10a..0000000
--- a/front_end/timeline/TimelineFilters.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-Timeline.TimelineFilters = {};
-
-Timeline.TimelineFilters.IsLong = class extends TimelineModel.TimelineModelFilter {
-  constructor() {
-    super();
-    this._minimumRecordDuration = 0;
-  }
-
-  /**
-   * @param {number} value
-   */
-  setMinimumRecordDuration(value) {
-    this._minimumRecordDuration = value;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    const duration = event.endTime ? event.endTime - event.startTime : 0;
-    return duration >= this._minimumRecordDuration;
-  }
-};
-
-
-Timeline.TimelineFilters.Category = class extends TimelineModel.TimelineModelFilter {
-  constructor() {
-    super();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return !Timeline.TimelineUIUtils.eventStyle(event).category.hidden;
-  }
-};
-
-Timeline.TimelineFilters.RegExp = class extends TimelineModel.TimelineModelFilter {
-  /**
-   * @param {!RegExp=} regExp
-   */
-  constructor(regExp) {
-    super();
-    /** @type {?RegExp} */
-    this._regExp;
-    this.setRegExp(regExp || null);
-  }
-
-  /**
-   * @param {?RegExp} regExp
-   */
-  setRegExp(regExp) {
-    this._regExp = regExp;
-  }
-
-  /**
-   * @return {?RegExp}
-   */
-  regExp() {
-    return this._regExp;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return !this._regExp || Timeline.TimelineUIUtils.testContentMatching(event, this._regExp);
-  }
-};
diff --git a/front_end/timeline/TimelineFlameChartDataProvider.js b/front_end/timeline/TimelineFlameChartDataProvider.js
deleted file mode 100644
index 384c83d..0000000
--- a/front_end/timeline/TimelineFlameChartDataProvider.js
+++ /dev/null
@@ -1,1064 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {PerfUI.FlameChartDataProvider}
- * @unrestricted
- */
-Timeline.TimelineFlameChartDataProvider = class extends Common.Object {
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   */
-  constructor(filters) {
-    super();
-    this.reset();
-    const font = '11px ' + Host.fontFamily();
-    this._font = font;
-    this._filters = filters;
-    /** @type {?PerfUI.FlameChart.TimelineData} */
-    this._timelineData = null;
-    this._currentLevel = 0;
-    /** @type {?Timeline.PerformanceModel} */
-    this._performanceModel = null;
-    /** @type {?TimelineModel.TimelineModel} */
-    this._model = null;
-    this._minimumBoundary = 0;
-    this._maximumBoundary = 0;
-    this._timeSpan = 0;
-
-    this._consoleColorGenerator =
-        new Common.Color.Generator({min: 30, max: 55}, {min: 70, max: 100, count: 6}, 50, 0.7);
-    this._extensionColorGenerator =
-        new Common.Color.Generator({min: 210, max: 300}, {min: 70, max: 100, count: 6}, 70, 0.7);
-
-    /**
-     * @param {!Object} extra
-     * @return {!PerfUI.FlameChart.GroupStyle}
-     */
-    function buildGroupStyle(extra) {
-      const defaultGroupStyle = {
-        padding: 4,
-        height: 17,
-        collapsible: true,
-        color: UI.themeSupport.patchColorText('#222', UI.ThemeSupport.ColorUsage.Foreground),
-        backgroundColor: UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background),
-        font: font,
-        nestingLevel: 0,
-        shareHeaderLine: true
-      };
-      return /** @type {!PerfUI.FlameChart.GroupStyle} */ (Object.assign(defaultGroupStyle, extra));
-    }
-
-    this._headerLevel1 = buildGroupStyle({shareHeaderLine: false});
-    this._headerLevel2 = buildGroupStyle({padding: 2, nestingLevel: 1, collapsible: false});
-    this._staticHeader = buildGroupStyle({collapsible: false});
-    this._framesHeader = buildGroupStyle({useFirstLineForOverview: true});
-    this._screenshotsHeader =
-        buildGroupStyle({useFirstLineForOverview: true, nestingLevel: 1, collapsible: false, itemsHeight: 150});
-    this._interactionsHeaderLevel1 = buildGroupStyle({useFirstLineForOverview: true});
-    this._interactionsHeaderLevel2 = buildGroupStyle({padding: 2, nestingLevel: 1});
-
-    /** @type {!Map<string, number>} */
-    this._flowEventIndexById = new Map();
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} performanceModel
-   */
-  setModel(performanceModel) {
-    this.reset();
-    this._performanceModel = performanceModel;
-    this._model = performanceModel && performanceModel.timelineModel();
-  }
-
-  /**
-   * @param {!PerfUI.FlameChart.Group} group
-   * @return {?TimelineModel.TimelineModel.Track}
-   */
-  groupTrack(group) {
-    return group._track || null;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {?string}
-   */
-  entryTitle(entryIndex) {
-    const entryTypes = Timeline.TimelineFlameChartDataProvider.EntryType;
-    const entryType = this._entryType(entryIndex);
-    if (entryType === entryTypes.Event) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]);
-      if (event.phase === SDK.TracingModel.Phase.AsyncStepInto || event.phase === SDK.TracingModel.Phase.AsyncStepPast)
-        return event.name + ':' + event.args['step'];
-      if (event._blackboxRoot)
-        return Common.UIString('Blackboxed');
-      const name = Timeline.TimelineUIUtils.eventStyle(event).title;
-      // TODO(yurys): support event dividers
-      const detailsText =
-          Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(event, this._model.targetByEvent(event));
-      if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame && detailsText)
-        return detailsText;
-      return detailsText ? Common.UIString('%s (%s)', name, detailsText) : name;
-    }
-    if (entryType === entryTypes.ExtensionEvent) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]);
-      return event.name;
-    }
-    if (entryType === entryTypes.Screenshot)
-      return '';
-    let title = this._entryIndexToTitle[entryIndex];
-    if (!title) {
-      title = Common.UIString('Unexpected entryIndex %d', entryIndex);
-      console.error(title);
-    }
-    return title;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {string}
-   */
-  textColor(index) {
-    const event = this._entryData[index];
-    return event && event._blackboxRoot ? '#888' : Timeline.FlameChartStyle.textColor;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?string}
-   */
-  entryFont(index) {
-    return this._font;
-  }
-
-  reset() {
-    this._currentLevel = 0;
-    this._timelineData = null;
-    /** @type {!Array<!SDK.FilmStripModel.Frame|!SDK.TracingModel.Event|!TimelineModel.TimelineFrame|!TimelineModel.TimelineIRModel.Phases>} */
-    this._entryData = [];
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this._entryParent = [];
-    /** @type {!Array<!Timeline.TimelineFlameChartDataProvider.EntryType>} */
-    this._entryTypeByLevel = [];
-    /** @type {!Array<string>} */
-    this._entryIndexToTitle = [];
-    /** @type {!Array<!Timeline.TimelineFlameChartMarker>} */
-    this._markers = [];
-    /** @type {!Map<!Timeline.TimelineCategory, string>} */
-    this._asyncColorByCategory = new Map();
-    /** @type {!Map<!TimelineModel.TimelineIRModel.Phases, string>} */
-    this._asyncColorByInteractionPhase = new Map();
-    /** @type {!Array<!{title: string, model: !SDK.TracingModel}>} */
-    this._extensionInfo = [];
-    /** @type {!Map<!SDK.FilmStripModel.Frame, ?Image>} */
-    this._screenshotImageCache = new Map();
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maxStackDepth() {
-    return this._currentLevel;
-  }
-
-  /**
-   * @override
-   * @return {!PerfUI.FlameChart.TimelineData}
-   */
-  timelineData() {
-    if (this._timelineData)
-      return this._timelineData;
-
-    this._timelineData = new PerfUI.FlameChart.TimelineData([], [], [], []);
-    if (!this._model)
-      return this._timelineData;
-
-    this._flowEventIndexById.clear();
-
-    this._minimumBoundary = this._model.minimumRecordTime();
-    this._timeSpan = this._model.isEmpty() ? 1000 : this._model.maximumRecordTime() - this._minimumBoundary;
-    this._currentLevel = 0;
-
-    this._appendFrameBars();
-
-    this._appendInteractionRecords();
-
-    const eventEntryType = Timeline.TimelineFlameChartDataProvider.EntryType.Event;
-
-    const weight = track => {
-      switch (track.type) {
-        case TimelineModel.TimelineModel.TrackType.Input:
-          return 0;
-        case TimelineModel.TimelineModel.TrackType.Animation:
-          return 1;
-        case TimelineModel.TimelineModel.TrackType.UserTiming:
-          return 2;
-        case TimelineModel.TimelineModel.TrackType.Console:
-          return 3;
-        case TimelineModel.TimelineModel.TrackType.MainThread:
-          return track.forMainFrame ? 4 : 5;
-        case TimelineModel.TimelineModel.TrackType.Worker:
-          return 6;
-        case TimelineModel.TimelineModel.TrackType.Raster:
-          return 7;
-        case TimelineModel.TimelineModel.TrackType.GPU:
-          return 8;
-        case TimelineModel.TimelineModel.TrackType.Other:
-          return 9;
-      }
-    };
-
-    const tracks = this._model.tracks().slice();
-    tracks.stableSort((a, b) => weight(a) - weight(b));
-    let rasterCount = 0;
-    for (const track of tracks) {
-      switch (track.type) {
-        case TimelineModel.TimelineModel.TrackType.Input:
-          this._appendAsyncEventsGroup(
-              track, ls`Input`, track.asyncEvents, this._interactionsHeaderLevel2, eventEntryType,
-              false /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.Animation:
-          this._appendAsyncEventsGroup(
-              track, ls`Animation`, track.asyncEvents, this._interactionsHeaderLevel2, eventEntryType,
-              false /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.UserTiming:
-          this._appendAsyncEventsGroup(
-              track, ls`User Timing`, track.asyncEvents, this._headerLevel1, eventEntryType, true /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.Console:
-          this._appendAsyncEventsGroup(
-              track, ls`Console`, track.asyncEvents, this._headerLevel1, eventEntryType, true /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.MainThread:
-          if (track.forMainFrame) {
-            const group = this._appendSyncEvents(
-                track, track.events, track.url ? ls`Main \u2014 ${track.url}` : ls`Main`, this._headerLevel1,
-                eventEntryType, true /* selectable */);
-            if (group)
-              this._timelineData.selectedGroup = group;
-          } else {
-            this._appendSyncEvents(
-                track, track.events, track.url ? ls`Frame \u2014 ${track.url}` : ls`Subframe`, this._headerLevel1,
-                eventEntryType, true /* selectable */);
-          }
-          break;
-        case TimelineModel.TimelineModel.TrackType.Worker:
-          this._appendSyncEvents(
-              track, track.events, track.url ? ls`Worker \u2014 ${track.url}` : ls`Dedicated Worker`,
-              this._headerLevel1, eventEntryType, true /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.Raster:
-          if (!rasterCount)
-            this._appendHeader(ls`Raster`, this._headerLevel1, false /* selectable */);
-          ++rasterCount;
-          this._appendSyncEvents(
-              track, track.events, ls`Rasterizer Thread ${rasterCount}`, this._headerLevel2, eventEntryType,
-              true /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.GPU:
-          this._appendSyncEvents(
-              track, track.events, ls`GPU`, this._headerLevel1, eventEntryType, true /* selectable */);
-          break;
-        case TimelineModel.TimelineModel.TrackType.Other:
-          this._appendSyncEvents(
-              track, track.events, track.name || ls`Thread`, this._headerLevel1, eventEntryType, true /* selectable */);
-          this._appendAsyncEventsGroup(
-              track, track.name, track.asyncEvents, this._headerLevel1, eventEntryType, true /* selectable */);
-          break;
-      }
-    }
-    if (this._timelineData.selectedGroup)
-      this._timelineData.selectedGroup.expanded = true;
-
-    for (let extensionIndex = 0; extensionIndex < this._extensionInfo.length; extensionIndex++)
-      this._innerAppendExtensionEvents(extensionIndex);
-
-    this._markers.sort((a, b) => a.startTime() - b.startTime());
-    this._timelineData.markers = this._markers;
-    this._flowEventIndexById.clear();
-
-    return this._timelineData;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  totalTime() {
-    return this._timeSpan;
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {!TimelineModel.TimelineModelFilter} filter
-   * @return {!Array<number>}
-   */
-  search(startTime, endTime, filter) {
-    const result = [];
-    const entryTypes = Timeline.TimelineFlameChartDataProvider.EntryType;
-    this.timelineData();
-    for (let i = 0; i < this._entryData.length; ++i) {
-      if (this._entryType(i) !== entryTypes.Event)
-        continue;
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[i]);
-      if (event.startTime > endTime)
-        continue;
-      if ((event.endTime || event.startTime) < startTime)
-        continue;
-      if (filter.accept(event))
-        result.push(i);
-    }
-    result.sort(
-        (a, b) => SDK.TracingModel.Event.compareStartTime(
-            /** @type {!SDK.TracingModel.Event} */ (this._entryData[a]),
-            /** @type {!SDK.TracingModel.Event} */ (this._entryData[b])));
-    return result;
-  }
-
-  /**
-   * @param {?TimelineModel.TimelineModel.Track} track
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {string} title
-   * @param {!PerfUI.FlameChart.GroupStyle} style
-   * @param {!Timeline.TimelineFlameChartDataProvider.EntryType} entryType
-   * @param {boolean} selectable
-   * @return {?PerfUI.FlameChart.Group}
-   */
-  _appendSyncEvents(track, events, title, style, entryType, selectable) {
-    if (!events.length)
-      return null;
-    const isExtension = entryType === Timeline.TimelineFlameChartDataProvider.EntryType.ExtensionEvent;
-    const openEvents = [];
-    const flowEventsEnabled = Runtime.experiments.isEnabled('timelineFlowEvents');
-    const blackboxingEnabled = !isExtension && Runtime.experiments.isEnabled('blackboxJSFramesOnTimeline');
-    let maxStackDepth = 0;
-    let group = null;
-    const markerEventsFilter = Timeline.TimelineUIUtils.paintEventsFilter();
-    for (let i = 0; i < events.length; ++i) {
-      const e = events[i];
-      if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e) && markerEventsFilter.accept(e)) {
-        this._markers.push(new Timeline.TimelineFlameChartMarker(
-            e.startTime, e.startTime - this._model.minimumRecordTime(),
-            Timeline.TimelineUIUtils.markerStyleForEvent(e)));
-      }
-      if (!SDK.TracingModel.isFlowPhase(e.phase)) {
-        if (!e.endTime && e.phase !== SDK.TracingModel.Phase.Instant)
-          continue;
-        if (SDK.TracingModel.isAsyncPhase(e.phase))
-          continue;
-        if (!isExtension && !this._isVisible(e))
-          continue;
-      }
-      while (openEvents.length && openEvents.peekLast().endTime <= e.startTime)
-        openEvents.pop();
-      e._blackboxRoot = false;
-      if (blackboxingEnabled && this._isBlackboxedEvent(e)) {
-        const parent = openEvents.peekLast();
-        if (parent && parent._blackboxRoot)
-          continue;
-        e._blackboxRoot = true;
-      }
-      if (!group) {
-        group = this._appendHeader(title, style, selectable);
-        if (selectable)
-          group._track = track;
-      }
-
-      const level = this._currentLevel + openEvents.length;
-      if (flowEventsEnabled)
-        this._appendFlowEvent(e, level);
-      const index = this._appendEvent(e, level);
-      if (openEvents.length)
-        this._entryParent[index] = openEvents.peekLast();
-      if (!isExtension && TimelineModel.TimelineModel.isMarkerEvent(e))
-        this._timelineData.entryTotalTimes[this._entryData.length] = undefined;
-
-      maxStackDepth = Math.max(maxStackDepth, openEvents.length + 1);
-      if (e.endTime)
-        openEvents.push(e);
-    }
-    this._entryTypeByLevel.length = this._currentLevel + maxStackDepth;
-    this._entryTypeByLevel.fill(entryType, this._currentLevel);
-    this._currentLevel += maxStackDepth;
-    return group;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  _isBlackboxedEvent(event) {
-    if (event.name !== TimelineModel.TimelineModel.RecordType.JSFrame)
-      return false;
-    const url = event.args['data']['url'];
-    return url && this._isBlackboxedURL(url);
-  }
-
-  /**
-   * @param {string} url
-   * @return {boolean}
-   */
-  _isBlackboxedURL(url) {
-    return Bindings.blackboxManager.isBlackboxedURL(url);
-  }
-
-  /**
-   * @param {?TimelineModel.TimelineModel.Track} track
-   * @param {string} header
-   * @param {!Array<!SDK.TracingModel.AsyncEvent>} events
-   * @param {!PerfUI.FlameChart.GroupStyle} style
-   * @param {!Timeline.TimelineFlameChartDataProvider.EntryType} entryType
-   * @param {boolean} selectable
-   * @return {?PerfUI.FlameChart.Group}
-   */
-  _appendAsyncEventsGroup(track, header, events, style, entryType, selectable) {
-    if (!events.length)
-      return null;
-    const lastUsedTimeByLevel = [];
-    let group = null;
-    for (let i = 0; i < events.length; ++i) {
-      const asyncEvent = events[i];
-      if (!this._isVisible(asyncEvent))
-        continue;
-      if (!group) {
-        group = this._appendHeader(header, style, selectable);
-        if (selectable)
-          group._track = track;
-      }
-      const startTime = asyncEvent.startTime;
-      let level;
-      for (level = 0; level < lastUsedTimeByLevel.length && lastUsedTimeByLevel[level] > startTime; ++level) {
-      }
-      this._appendAsyncEvent(asyncEvent, this._currentLevel + level);
-      lastUsedTimeByLevel[level] = asyncEvent.endTime;
-    }
-    this._entryTypeByLevel.length = this._currentLevel + lastUsedTimeByLevel.length;
-    this._entryTypeByLevel.fill(entryType, this._currentLevel);
-    this._currentLevel += lastUsedTimeByLevel.length;
-    return group;
-  }
-
-  _appendInteractionRecords() {
-    const interactionRecords = this._performanceModel.interactionRecords();
-    if (!interactionRecords.length)
-      return;
-    this._appendHeader(ls`Interactions`, this._interactionsHeaderLevel1, false /* selectable */);
-    for (const segment of interactionRecords) {
-      const index = this._entryData.length;
-      this._entryData.push(/** @type {!TimelineModel.TimelineIRModel.Phases} */ (segment.data));
-      this._entryIndexToTitle[index] = /** @type {string} */ (segment.data);
-      this._timelineData.entryLevels[index] = this._currentLevel;
-      this._timelineData.entryTotalTimes[index] = segment.end - segment.begin;
-      this._timelineData.entryStartTimes[index] = segment.begin;
-    }
-    this._entryTypeByLevel[this._currentLevel++] = Timeline.TimelineFlameChartDataProvider.EntryType.InteractionRecord;
-  }
-
-  _appendFrameBars() {
-    const screenshots = this._performanceModel.filmStripModel().frames();
-    const hasFilmStrip = !!screenshots.length;
-    this._framesHeader.collapsible = hasFilmStrip;
-    this._appendHeader(Common.UIString('Frames'), this._framesHeader, false /* selectable */);
-    this._frameGroup = this._timelineData.groups.peekLast();
-    const style = Timeline.TimelineUIUtils.markerStyleForFrame();
-    this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartDataProvider.EntryType.Frame;
-    for (const frame of this._performanceModel.frames()) {
-      this._markers.push(new Timeline.TimelineFlameChartMarker(
-          frame.startTime, frame.startTime - this._model.minimumRecordTime(), style));
-      this._appendFrame(frame);
-    }
-    ++this._currentLevel;
-    if (!hasFilmStrip)
-      return;
-    this._appendHeader('', this._screenshotsHeader, false /* selectable */);
-    this._entryTypeByLevel[this._currentLevel] = Timeline.TimelineFlameChartDataProvider.EntryType.Screenshot;
-    let prevTimestamp;
-    for (const screenshot of screenshots) {
-      this._entryData.push(screenshot);
-      this._timelineData.entryLevels.push(this._currentLevel);
-      this._timelineData.entryStartTimes.push(screenshot.timestamp);
-      if (prevTimestamp)
-        this._timelineData.entryTotalTimes.push(screenshot.timestamp - prevTimestamp);
-      prevTimestamp = screenshot.timestamp;
-    }
-    if (screenshots.length)
-      this._timelineData.entryTotalTimes.push(this._model.maximumRecordTime() - prevTimestamp);
-    ++this._currentLevel;
-  }
-
-  /**
-   * @param {number} entryIndex
-   * @return {!Timeline.TimelineFlameChartDataProvider.EntryType}
-   */
-  _entryType(entryIndex) {
-    return this._entryTypeByLevel[this._timelineData.entryLevels[entryIndex]];
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {?Element}
-   */
-  prepareHighlightedEntryInfo(entryIndex) {
-    let time = '';
-    let title;
-    let warning;
-    const type = this._entryType(entryIndex);
-    if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]);
-      const totalTime = event.duration;
-      const selfTime = event.selfTime;
-      const /** @const */ eps = 1e-6;
-      if (typeof totalTime === 'number') {
-        time = Math.abs(totalTime - selfTime) > eps && selfTime > eps ?
-            Common.UIString(
-                '%s (self %s)', Number.millisToString(totalTime, true), Number.millisToString(selfTime, true)) :
-            Number.millisToString(totalTime, true);
-      }
-      title = this.entryTitle(entryIndex);
-      warning = Timeline.TimelineUIUtils.eventWarning(event);
-    } else if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) {
-      const frame = /** @type {!TimelineModel.TimelineFrame} */ (this._entryData[entryIndex]);
-      time = Common.UIString(
-          '%s ~ %.0f\xa0fps', Number.preciseMillisToString(frame.duration, 1), (1000 / frame.duration));
-      title = frame.idle ? Common.UIString('Idle Frame') : Common.UIString('Frame');
-      if (frame.hasWarnings()) {
-        warning = createElement('span');
-        warning.textContent = Common.UIString('Long frame');
-      }
-    } else {
-      return null;
-    }
-    const element = createElement('div');
-    const root = UI.createShadowRootWithCoreStyles(element, 'timeline/timelineFlamechartPopover.css');
-    const contents = root.createChild('div', 'timeline-flamechart-popover');
-    contents.createChild('span', 'timeline-info-time').textContent = time;
-    contents.createChild('span', 'timeline-info-title').textContent = title;
-    if (warning) {
-      warning.classList.add('timeline-info-warning');
-      contents.appendChild(warning);
-    }
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {string}
-   */
-  entryColor(entryIndex) {
-    // This is not annotated due to closure compiler failure to properly infer cache container's template type.
-    function patchColorAndCache(cache, key, lookupColor) {
-      let color = cache.get(key);
-      if (color)
-        return color;
-      const parsedColor = Common.Color.parse(lookupColor(key));
-      color = parsedColor.setAlpha(0.7).asString(Common.Color.Format.RGBA) || '';
-      cache.set(key, color);
-      return color;
-    }
-
-    const entryTypes = Timeline.TimelineFlameChartDataProvider.EntryType;
-    const type = this._entryType(entryIndex);
-    if (type === entryTypes.Event) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]);
-      if (!SDK.TracingModel.isAsyncPhase(event.phase))
-        return this._colorForEvent(event);
-      if (event.hasCategory(TimelineModel.TimelineModel.Category.Console) ||
-          event.hasCategory(TimelineModel.TimelineModel.Category.UserTiming))
-        return this._consoleColorGenerator.colorForID(event.name);
-      if (event.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) {
-        const phase =
-            TimelineModel.TimelineIRModel.phaseForEvent(event) || TimelineModel.TimelineIRModel.Phases.Uncategorized;
-        return patchColorAndCache(
-            this._asyncColorByInteractionPhase, phase, Timeline.TimelineUIUtils.interactionPhaseColor);
-      }
-      const category = Timeline.TimelineUIUtils.eventStyle(event).category;
-      return patchColorAndCache(this._asyncColorByCategory, category, () => category.color);
-    }
-    if (type === entryTypes.Frame)
-      return 'white';
-    if (type === entryTypes.InteractionRecord)
-      return 'transparent';
-    if (type === entryTypes.ExtensionEvent) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]);
-      return this._extensionColorGenerator.colorForID(event.name);
-    }
-    return '';
-  }
-
-  /**
-   * @param {number} entryIndex
-   * @param {!CanvasRenderingContext2D} context
-   * @param {?string} text
-   * @param {number} barX
-   * @param {number} barY
-   * @param {number} barWidth
-   * @param {number} barHeight
-   */
-  _drawFrame(entryIndex, context, text, barX, barY, barWidth, barHeight) {
-    const /** @const */ hPadding = 1;
-    const frame = /** @type {!TimelineModel.TimelineFrame} */ (this._entryData[entryIndex]);
-    barX += hPadding;
-    barWidth -= 2 * hPadding;
-    context.fillStyle = frame.idle ? 'white' : (frame.hasWarnings() ? '#fad1d1' : '#d7f0d1');
-    context.fillRect(barX, barY, barWidth, barHeight);
-
-    const frameDurationText = Number.preciseMillisToString(frame.duration, 1);
-    const textWidth = context.measureText(frameDurationText).width;
-    if (textWidth <= barWidth) {
-      context.fillStyle = this.textColor(entryIndex);
-      context.fillText(frameDurationText, barX + (barWidth - textWidth) / 2, barY + barHeight - 4);
-    }
-  }
-
-  /**
-   * @param {number} entryIndex
-   * @param {!CanvasRenderingContext2D} context
-   * @param {number} barX
-   * @param {number} barY
-   * @param {number} barWidth
-   * @param {number} barHeight
-   */
-  async _drawScreenshot(entryIndex, context, barX, barY, barWidth, barHeight) {
-    const screenshot = /** @type {!SDK.FilmStripModel.Frame} */ (this._entryData[entryIndex]);
-    if (!this._screenshotImageCache.has(screenshot)) {
-      this._screenshotImageCache.set(screenshot, null);
-      const data = await screenshot.imageDataPromise();
-      const image = await UI.loadImageFromData(data);
-      this._screenshotImageCache.set(screenshot, image);
-      this.dispatchEventToListeners(Timeline.TimelineFlameChartDataProvider.Events.DataChanged);
-      return;
-    }
-
-    const image = this._screenshotImageCache.get(screenshot);
-    if (!image)
-      return;
-    const imageX = barX + 1;
-    const imageY = barY + 1;
-    const imageHeight = barHeight - 2;
-    const scale = imageHeight / image.naturalHeight;
-    const imageWidth = Math.floor(image.naturalWidth * scale);
-    context.save();
-    context.beginPath();
-    context.rect(barX, barY, barWidth, barHeight);
-    context.clip();
-    context.drawImage(image, imageX, imageY, imageWidth, imageHeight);
-    context.strokeStyle = '#ccc';
-    context.strokeRect(imageX - 0.5, imageY - 0.5, Math.min(barWidth - 1, imageWidth + 1), imageHeight);
-    context.restore();
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @param {!CanvasRenderingContext2D} context
-   * @param {?string} text
-   * @param {number} barX
-   * @param {number} barY
-   * @param {number} barWidth
-   * @param {number} barHeight
-   * @param {number} unclippedBarX
-   * @param {number} timeToPixels
-   * @return {boolean}
-   */
-  decorateEntry(entryIndex, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixels) {
-    const data = this._entryData[entryIndex];
-    const type = this._entryType(entryIndex);
-    const entryTypes = Timeline.TimelineFlameChartDataProvider.EntryType;
-
-    if (type === entryTypes.Frame) {
-      this._drawFrame(entryIndex, context, text, barX, barY, barWidth, barHeight);
-      return true;
-    }
-
-    if (type === entryTypes.Screenshot) {
-      this._drawScreenshot(entryIndex, context, barX, barY, barWidth, barHeight);
-      return true;
-    }
-
-    if (type === entryTypes.InteractionRecord) {
-      const color = Timeline.TimelineUIUtils.interactionPhaseColor(
-          /** @type {!TimelineModel.TimelineIRModel.Phases} */ (data));
-      context.fillStyle = color;
-      context.fillRect(barX, barY, barWidth - 1, 2);
-      context.fillRect(barX, barY - 3, 2, 3);
-      context.fillRect(barX + barWidth - 3, barY - 3, 2, 3);
-      return false;
-    }
-
-    if (type === entryTypes.Event) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (data);
-      if (event.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) {
-        const timeWaitingForMainThread = TimelineModel.TimelineData.forEvent(event).timeWaitingForMainThread;
-        if (timeWaitingForMainThread) {
-          context.fillStyle = 'hsla(0, 70%, 60%, 1)';
-          const width = Math.floor(unclippedBarX - barX + timeWaitingForMainThread * timeToPixels);
-          context.fillRect(barX, barY + barHeight - 3, width, 2);
-        }
-      }
-      if (TimelineModel.TimelineData.forEvent(event).warning)
-        paintWarningDecoration(barX, barWidth - 1.5);
-    }
-
-    /**
-     * @param {number} x
-     * @param {number} width
-     */
-    function paintWarningDecoration(x, width) {
-      const /** @const */ triangleSize = 8;
-      context.save();
-      context.beginPath();
-      context.rect(x, barY, width, barHeight);
-      context.clip();
-      context.beginPath();
-      context.fillStyle = 'red';
-      context.moveTo(x + width - triangleSize, barY);
-      context.lineTo(x + width, barY);
-      context.lineTo(x + width, barY + triangleSize);
-      context.fill();
-      context.restore();
-    }
-
-    return false;
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  forceDecoration(entryIndex) {
-    const entryTypes = Timeline.TimelineFlameChartDataProvider.EntryType;
-    const type = this._entryType(entryIndex);
-    if (type === entryTypes.Frame)
-      return true;
-    if (type === entryTypes.Screenshot)
-      return true;
-
-    if (type === entryTypes.Event) {
-      const event = /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]);
-      return !!TimelineModel.TimelineData.forEvent(event).warning;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!{title: string, model: !SDK.TracingModel}} entry
-   */
-  appendExtensionEvents(entry) {
-    this._extensionInfo.push(entry);
-    if (this._timelineData)
-      this._innerAppendExtensionEvents(this._extensionInfo.length - 1);
-  }
-
-  /**
-   * @param {number} index
-   */
-  _innerAppendExtensionEvents(index) {
-    const entry = this._extensionInfo[index];
-    const entryType = Timeline.TimelineFlameChartDataProvider.EntryType.ExtensionEvent;
-    const allThreads = [].concat(...entry.model.sortedProcesses().map(process => process.sortedThreads()));
-    if (!allThreads.length)
-      return;
-
-    const singleTrack =
-        allThreads.length === 1 && (!allThreads[0].events().length || !allThreads[0].asyncEvents().length);
-    if (!singleTrack)
-      this._appendHeader(entry.title, this._headerLevel1, false /* selectable */);
-    const style = singleTrack ? this._headerLevel2 : this._headerLevel1;
-    let threadIndex = 0;
-    for (const thread of allThreads) {
-      const title = singleTrack ? entry.title : thread.name() || ls`Thread ${++threadIndex}`;
-      this._appendAsyncEventsGroup(null, title, thread.asyncEvents(), style, entryType, false /* selectable */);
-      this._appendSyncEvents(null, thread.events(), title, style, entryType, false /* selectable */);
-    }
-  }
-
-  /**
-   * @param {string} title
-   * @param {!PerfUI.FlameChart.GroupStyle} style
-   * @param {boolean} selectable
-   * @return {!PerfUI.FlameChart.Group}
-   */
-  _appendHeader(title, style, selectable) {
-    const group = {startLevel: this._currentLevel, name: title, style: style, selectable: selectable};
-    this._timelineData.groups.push(group);
-    return group;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {number} level
-   * @return {number}
-   */
-  _appendEvent(event, level) {
-    const index = this._entryData.length;
-    this._entryData.push(event);
-    this._timelineData.entryLevels[index] = level;
-    this._timelineData.entryTotalTimes[index] =
-        event.duration || Timeline.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs;
-    this._timelineData.entryStartTimes[index] = event.startTime;
-    event[Timeline.TimelineFlameChartDataProvider._indexSymbol] = index;
-    return index;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.AsyncEvent} asyncEvent
-   * @param {number} level
-   */
-  _appendAsyncEvent(asyncEvent, level) {
-    if (SDK.TracingModel.isNestableAsyncPhase(asyncEvent.phase)) {
-      // FIXME: also add steps once we support event nesting in the FlameChart.
-      this._appendEvent(asyncEvent, level);
-      return;
-    }
-    const steps = asyncEvent.steps;
-    // If we have past steps, put the end event for each range rather than start one.
-    const eventOffset = steps.length > 1 && steps[1].phase === SDK.TracingModel.Phase.AsyncStepPast ? 1 : 0;
-    for (let i = 0; i < steps.length - 1; ++i) {
-      const index = this._entryData.length;
-      this._entryData.push(steps[i + eventOffset]);
-      const startTime = steps[i].startTime;
-      this._timelineData.entryLevels[index] = level;
-      this._timelineData.entryTotalTimes[index] = steps[i + 1].startTime - startTime;
-      this._timelineData.entryStartTimes[index] = startTime;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {number} level
-   */
-  _appendFlowEvent(event, level) {
-    const timelineData = this._timelineData;
-    /**
-     * @param {!SDK.TracingModel.Event} event
-     * @return {number}
-     */
-    function pushStartFlow(event) {
-      const flowIndex = timelineData.flowStartTimes.length;
-      timelineData.flowStartTimes.push(event.startTime);
-      timelineData.flowStartLevels.push(level);
-      return flowIndex;
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} event
-     * @param {number} flowIndex
-     */
-    function pushEndFlow(event, flowIndex) {
-      timelineData.flowEndTimes[flowIndex] = event.startTime;
-      timelineData.flowEndLevels[flowIndex] = level;
-    }
-
-    switch (event.phase) {
-      case SDK.TracingModel.Phase.FlowBegin:
-        this._flowEventIndexById.set(event.id, pushStartFlow(event));
-        break;
-      case SDK.TracingModel.Phase.FlowStep:
-        pushEndFlow(event, this._flowEventIndexById.get(event.id));
-        this._flowEventIndexById.set(event.id, pushStartFlow(event));
-        break;
-      case SDK.TracingModel.Phase.FlowEnd:
-        pushEndFlow(event, this._flowEventIndexById.get(event.id));
-        this._flowEventIndexById.delete(event.id);
-        break;
-    }
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineFrame} frame
-   */
-  _appendFrame(frame) {
-    const index = this._entryData.length;
-    this._entryData.push(frame);
-    this._entryIndexToTitle[index] = Number.millisToString(frame.duration, true);
-    this._timelineData.entryLevels[index] = this._currentLevel;
-    this._timelineData.entryTotalTimes[index] = frame.duration;
-    this._timelineData.entryStartTimes[index] = frame.startTime;
-  }
-
-  /**
-   * @param {number} entryIndex
-   * @return {?Timeline.TimelineSelection}
-   */
-  createSelection(entryIndex) {
-    const type = this._entryType(entryIndex);
-    let timelineSelection = null;
-    if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Event) {
-      timelineSelection = Timeline.TimelineSelection.fromTraceEvent(
-          /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]));
-    } else if (type === Timeline.TimelineFlameChartDataProvider.EntryType.Frame) {
-      timelineSelection = Timeline.TimelineSelection.fromFrame(
-          /** @type {!TimelineModel.TimelineFrame} */ (this._entryData[entryIndex]));
-    }
-    if (timelineSelection)
-      this._lastSelection = new Timeline.TimelineFlameChartView.Selection(timelineSelection, entryIndex);
-    return timelineSelection;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.preciseMillisToString(value, precision);
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  canJumpToEntry(entryIndex) {
-    return false;
-  }
-
-  /**
-   * @param {?Timeline.TimelineSelection} selection
-   * @return {number}
-   */
-  entryIndexForSelection(selection) {
-    if (!selection || selection.type() === Timeline.TimelineSelection.Type.Range)
-      return -1;
-
-    if (this._lastSelection && this._lastSelection.timelineSelection.object() === selection.object())
-      return this._lastSelection.entryIndex;
-    const index = this._entryData.indexOf(
-        /** @type {!SDK.TracingModel.Event|!TimelineModel.TimelineFrame|!TimelineModel.TimelineIRModel.Phases} */
-        (selection.object()));
-    if (index !== -1)
-      this._lastSelection = new Timeline.TimelineFlameChartView.Selection(selection, index);
-    return index;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  _isVisible(event) {
-    return this._filters.every(filter => filter.accept(event));
-  }
-
-  /**
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  buildFlowForInitiator(entryIndex) {
-    if (this._lastInitiatorEntry === entryIndex)
-      return false;
-    this._lastInitiatorEntry = entryIndex;
-    let event = this.eventByIndex(entryIndex);
-    const td = this._timelineData;
-    td.flowStartTimes = [];
-    td.flowStartLevels = [];
-    td.flowEndTimes = [];
-    td.flowEndLevels = [];
-    while (event) {
-      // Find the closest ancestor with an initiator.
-      let initiator;
-      for (; event; event = this._eventParent(event)) {
-        initiator = TimelineModel.TimelineData.forEvent(event).initiator();
-        if (initiator)
-          break;
-      }
-      if (!initiator)
-        break;
-      const eventIndex = event[Timeline.TimelineFlameChartDataProvider._indexSymbol];
-      const initiatorIndex = initiator[Timeline.TimelineFlameChartDataProvider._indexSymbol];
-      td.flowStartTimes.push(initiator.endTime || initiator.startTime);
-      td.flowStartLevels.push(td.entryLevels[initiatorIndex]);
-      td.flowEndTimes.push(event.startTime);
-      td.flowEndLevels.push(td.entryLevels[eventIndex]);
-      event = initiator;
-    }
-    return true;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?SDK.TracingModel.Event}
-   */
-  _eventParent(event) {
-    return this._entryParent[event[Timeline.TimelineFlameChartDataProvider._indexSymbol]] || null;
-  }
-
-  /**
-   * @param {number} entryIndex
-   * @return {?SDK.TracingModel.Event}
-   */
-  eventByIndex(entryIndex) {
-    return entryIndex >= 0 && this._entryType(entryIndex) === Timeline.TimelineFlameChartDataProvider.EntryType.Event ?
-        /** @type {!SDK.TracingModel.Event} */ (this._entryData[entryIndex]) :
-        null;
-  }
-
-  /**
-   * @param {function(!SDK.TracingModel.Event):string} colorForEvent
-   */
-  setEventColorMapping(colorForEvent) {
-    this._colorForEvent = colorForEvent;
-  }
-};
-
-Timeline.TimelineFlameChartDataProvider.InstantEventVisibleDurationMs = 0.001;
-Timeline.TimelineFlameChartDataProvider._indexSymbol = Symbol('index');
-
-/** @enum {symbol} */
-Timeline.TimelineFlameChartDataProvider.Events = {
-  DataChanged: Symbol('DataChanged')
-};
-
-/** @enum {symbol} */
-Timeline.TimelineFlameChartDataProvider.EntryType = {
-  Frame: Symbol('Frame'),
-  Event: Symbol('Event'),
-  InteractionRecord: Symbol('InteractionRecord'),
-  ExtensionEvent: Symbol('ExtensionEvent'),
-  Screenshot: Symbol('Screenshot'),
-};
diff --git a/front_end/timeline/TimelineFlameChartNetworkDataProvider.js b/front_end/timeline/TimelineFlameChartNetworkDataProvider.js
deleted file mode 100644
index f098af8..0000000
--- a/front_end/timeline/TimelineFlameChartNetworkDataProvider.js
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {PerfUI.FlameChartDataProvider}
- * @unrestricted
- */
-Timeline.TimelineFlameChartNetworkDataProvider = class {
-  constructor() {
-    this._font = '11px ' + Host.fontFamily();
-    this.setModel(null);
-    this._style = {
-      padding: 4,
-      height: 17,
-      collapsible: true,
-      color: UI.themeSupport.patchColorText('#222', UI.ThemeSupport.ColorUsage.Foreground),
-      font: this._font,
-      backgroundColor: UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background),
-      nestingLevel: 0,
-      useFirstLineForOverview: false,
-      useDecoratorsForOverview: true,
-      shareHeaderLine: false
-    };
-    this._group = {startLevel: 0, name: Common.UIString('Network'), expanded: false, style: this._style};
-    this._minimumBoundary = 0;
-    this._maximumBoundary = 0;
-    this._timeSpan = 0;
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} performanceModel
-   */
-  setModel(performanceModel) {
-    this._model = performanceModel && performanceModel.timelineModel();
-    this._maxLevel = 0;
-    this._timelineData = null;
-    /** @type {!Array<!TimelineModel.TimelineModel.NetworkRequest>} */
-    this._requests = [];
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEmpty() {
-    this.timelineData();
-    return !this._requests.length;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  maxStackDepth() {
-    return this._maxLevel;
-  }
-
-  /**
-   * @override
-   * @return {!PerfUI.FlameChart.TimelineData}
-   */
-  timelineData() {
-    if (this._timelineData)
-      return this._timelineData;
-    /** @type {!Array<!TimelineModel.TimelineModel.NetworkRequest>} */
-    this._requests = [];
-    this._timelineData = new PerfUI.FlameChart.TimelineData([], [], [], []);
-    if (this._model)
-      this._appendTimelineData();
-    return this._timelineData;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  minimumBoundary() {
-    return this._minimumBoundary;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  totalTime() {
-    return this._timeSpan;
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  setWindowTimes(startTime, endTime) {
-    this._startTime = startTime;
-    this._endTime = endTime;
-    this._updateTimelineData();
-  }
-
-  /**
-   * @param {number} index
-   * @return {?Timeline.TimelineSelection}
-   */
-  createSelection(index) {
-    if (index === -1)
-      return null;
-    const request = this._requests[index];
-    this._lastSelection =
-        new Timeline.TimelineFlameChartView.Selection(Timeline.TimelineSelection.fromNetworkRequest(request), index);
-    return this._lastSelection.timelineSelection;
-  }
-
-  /**
-   * @param {?Timeline.TimelineSelection} selection
-   * @return {number}
-   */
-  entryIndexForSelection(selection) {
-    if (!selection)
-      return -1;
-
-    if (this._lastSelection && this._lastSelection.timelineSelection.object() === selection.object())
-      return this._lastSelection.entryIndex;
-
-    if (selection.type() !== Timeline.TimelineSelection.Type.NetworkRequest)
-      return -1;
-    const request = /** @type{!TimelineModel.TimelineModel.NetworkRequest} */ (selection.object());
-    const index = this._requests.indexOf(request);
-    if (index !== -1) {
-      this._lastSelection =
-          new Timeline.TimelineFlameChartView.Selection(Timeline.TimelineSelection.fromNetworkRequest(request), index);
-    }
-    return index;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {string}
-   */
-  entryColor(index) {
-    const request = /** @type {!TimelineModel.TimelineModel.NetworkRequest} */ (this._requests[index]);
-    const category = Timeline.TimelineUIUtils.networkRequestCategory(request);
-    return Timeline.TimelineUIUtils.networkCategoryColor(category);
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {string}
-   */
-  textColor(index) {
-    return Timeline.FlameChartStyle.textColor;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?string}
-   */
-  entryTitle(index) {
-    const request = /** @type {!TimelineModel.TimelineModel.NetworkRequest} */ (this._requests[index]);
-    const parsedURL = new Common.ParsedURL(request.url || '');
-    return parsedURL.isValid ? `${parsedURL.displayName} (${parsedURL.host})` : request.url || null;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?string}
-   */
-  entryFont(index) {
-    return this._font;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @param {!CanvasRenderingContext2D} context
-   * @param {?string} text
-   * @param {number} barX
-   * @param {number} barY
-   * @param {number} barWidth
-   * @param {number} barHeight
-   * @param {number} unclippedBarX
-   * @param {number} timeToPixelRatio
-   * @return {boolean}
-   */
-  decorateEntry(index, context, text, barX, barY, barWidth, barHeight, unclippedBarX, timeToPixelRatio) {
-    const request = /** @type {!TimelineModel.TimelineModel.NetworkRequest} */ (this._requests[index]);
-    if (!request.timing)
-      return false;
-
-    /**
-     * @param {number} time
-     * @return {number}
-     */
-    function timeToPixel(time) {
-      return Math.floor(unclippedBarX + (time - beginTime) * timeToPixelRatio);
-    }
-
-    const /** @const */ minBarWidthPx = 2;
-    const beginTime = request.beginTime();
-    const startTime = request.startTime;
-    const endTime = request.endTime;
-    const requestTime = request.timing.requestTime * 1000;
-    const sendStart = Math.max(timeToPixel(requestTime + request.timing.sendStart), unclippedBarX);
-    const headersEnd = Math.max(timeToPixel(requestTime + request.timing.receiveHeadersEnd), sendStart);
-    const finish = Math.max(timeToPixel(request.finishTime || endTime), headersEnd + minBarWidthPx);
-    const start = timeToPixel(startTime);
-    const end = Math.max(timeToPixel(endTime), finish);
-
-    context.fillStyle = 'hsla(0, 100%, 100%, 0.8)';
-    context.fillRect(sendStart + 0.5, barY + 0.5, headersEnd - sendStart - 0.5, barHeight - 2);
-    context.fillStyle = UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background);
-    context.fillRect(barX, barY - 0.5, sendStart - barX, barHeight);
-    context.fillRect(finish, barY - 0.5, barX + barWidth - finish, barHeight);
-
-    if (request.timing.pushStart) {
-      const pushStart = timeToPixel(request.timing.pushStart * 1000);
-      const pushEnd = timeToPixel(request.timing.pushEnd * 1000);
-      const dentSize = Number.constrain(pushEnd - pushStart - 2, 0, 4);
-      const padding = 1;
-      context.save();
-      context.beginPath();
-      context.moveTo(pushStart + dentSize, barY + barHeight / 2);
-      context.lineTo(pushStart, barY + padding);
-      context.lineTo(pushEnd - dentSize, barY + padding);
-      context.lineTo(pushEnd, barY + barHeight / 2);
-      context.lineTo(pushEnd - dentSize, barY + barHeight - padding);
-      context.lineTo(pushStart, barY + barHeight - padding);
-      context.closePath();
-      context.fillStyle = this.entryColor(index);
-      context.globalAlpha = 0.3;
-      context.fill();
-      context.restore();
-    }
-
-    /**
-     * @param {number} begin
-     * @param {number} end
-     * @param {number} y
-     */
-    function drawTick(begin, end, y) {
-      const /** @const */ tickHeightPx = 6;
-      context.moveTo(begin, y - tickHeightPx / 2);
-      context.lineTo(begin, y + tickHeightPx / 2);
-      context.moveTo(begin, y);
-      context.lineTo(end, y);
-    }
-
-    context.beginPath();
-    context.lineWidth = 1;
-    context.strokeStyle = '#ccc';
-    const lineY = Math.floor(barY + barHeight / 2) + 0.5;
-    const leftTick = start + 0.5;
-    const rightTick = end - 0.5;
-    drawTick(leftTick, sendStart, lineY);
-    drawTick(rightTick, finish, lineY);
-    context.stroke();
-
-    if (typeof request.priority === 'string') {
-      const color = this._colorForPriority(request.priority);
-      if (color) {
-        context.fillStyle = color;
-        context.fillRect(sendStart + 0.5, barY + 0.5, 3.5, 3.5);
-      }
-    }
-
-    const textStart = Math.max(sendStart, 0);
-    const textWidth = finish - textStart;
-    const /** @const */ minTextWidthPx = 20;
-    if (textWidth >= minTextWidthPx) {
-      text = this.entryTitle(index) || '';
-      if (request.fromServiceWorker)
-        text = '⚙ ' + text;
-      if (text) {
-        const /** @const */ textPadding = 4;
-        const /** @const */ textBaseline = 5;
-        const textBaseHeight = barHeight - textBaseline;
-        const trimmedText = UI.trimTextEnd(context, text, textWidth - 2 * textPadding);
-        context.fillStyle = '#333';
-        context.fillText(trimmedText, textStart + textPadding, barY + textBaseHeight);
-      }
-    }
-
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {boolean}
-   */
-  forceDecoration(index) {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {number} index
-   * @return {?Element}
-   */
-  prepareHighlightedEntryInfo(index) {
-    const /** @const */ maxURLChars = 80;
-    const request = /** @type {!TimelineModel.TimelineModel.NetworkRequest} */ (this._requests[index]);
-    if (!request.url)
-      return null;
-    const element = createElement('div');
-    const root = UI.createShadowRootWithCoreStyles(element, 'timeline/timelineFlamechartPopover.css');
-    const contents = root.createChild('div', 'timeline-flamechart-popover');
-    const duration = request.endTime - request.startTime;
-    if (request.startTime && isFinite(duration))
-      contents.createChild('span', 'timeline-info-network-time').textContent = Number.millisToString(duration);
-    if (typeof request.priority === 'string') {
-      const div = contents.createChild('span');
-      div.textContent =
-          PerfUI.uiLabelForNetworkPriority(/** @type {!Protocol.Network.ResourcePriority} */ (request.priority));
-      div.style.color = this._colorForPriority(request.priority) || 'black';
-    }
-    contents.createChild('span').textContent = request.url.trimMiddle(maxURLChars);
-    return element;
-  }
-
-  /**
-   * @param {string} priority
-   * @return {?string}
-   */
-  _colorForPriority(priority) {
-    if (!this._priorityToValue) {
-      const priorities = Protocol.Network.ResourcePriority;
-      this._priorityToValue = new Map([
-        [priorities.VeryLow, 1], [priorities.Low, 2], [priorities.Medium, 3], [priorities.High, 4],
-        [priorities.VeryHigh, 5]
-      ]);
-    }
-    const value = this._priorityToValue.get(priority);
-    return value ? `hsla(214, 80%, 50%, ${value / 5})` : null;
-  }
-
-  _appendTimelineData() {
-    this._minimumBoundary = this._model.minimumRecordTime();
-    this._maximumBoundary = this._model.maximumRecordTime();
-    this._timeSpan = this._model.isEmpty() ? 1000 : this._maximumBoundary - this._minimumBoundary;
-    this._model.networkRequests().forEach(this._appendEntry.bind(this));
-    this._updateTimelineData();
-  }
-
-  _updateTimelineData() {
-    if (!this._timelineData)
-      return;
-    const lastTimeByLevel = [];
-    let maxLevel = 0;
-    for (let i = 0; i < this._requests.length; ++i) {
-      const r = this._requests[i];
-      const beginTime = r.beginTime();
-      const visible = beginTime < this._endTime && r.endTime > this._startTime;
-      if (!visible) {
-        this._timelineData.entryLevels[i] = -1;
-        continue;
-      }
-      while (lastTimeByLevel.length && lastTimeByLevel.peekLast() <= beginTime)
-        lastTimeByLevel.pop();
-      this._timelineData.entryLevels[i] = lastTimeByLevel.length;
-      lastTimeByLevel.push(r.endTime);
-      maxLevel = Math.max(maxLevel, lastTimeByLevel.length);
-    }
-    for (let i = 0; i < this._requests.length; ++i) {
-      if (this._timelineData.entryLevels[i] === -1)
-        this._timelineData.entryLevels[i] = maxLevel;
-    }
-    this._timelineData = new PerfUI.FlameChart.TimelineData(
-        this._timelineData.entryLevels, this._timelineData.entryTotalTimes, this._timelineData.entryStartTimes,
-        [this._group]);
-    this._maxLevel = maxLevel;
-  }
-
-
-  /**
-   * @param {!TimelineModel.TimelineModel.NetworkRequest} request
-   */
-  _appendEntry(request) {
-    this._requests.push(request);
-    this._timelineData.entryStartTimes.push(request.beginTime());
-    this._timelineData.entryTotalTimes.push(request.endTime - request.beginTime());
-    this._timelineData.entryLevels.push(this._requests.length - 1);
-  }
-
-  /**
-   * @return {number}
-   */
-  preferredHeight() {
-    return this._style.height * (this._group.expanded ? Number.constrain(this._maxLevel + 1, 4, 8.5) : 1);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isExpanded() {
-    return this._group.expanded;
-  }
-
-  /**
-   * @override
-   * @param {number} value
-   * @param {number=} precision
-   * @return {string}
-   */
-  formatValue(value, precision) {
-    return Number.preciseMillisToString(value, precision);
-  }
-
-  /**
-   * @override
-   * @param {number} entryIndex
-   * @return {boolean}
-   */
-  canJumpToEntry(entryIndex) {
-    return false;
-  }
-};
diff --git a/front_end/timeline/TimelineFlameChartView.js b/front_end/timeline/TimelineFlameChartView.js
deleted file mode 100644
index 2e052f9..0000000
--- a/front_end/timeline/TimelineFlameChartView.js
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Timeline.TimelineModeView}
- * @implements {PerfUI.FlameChartDelegate}
- * @implements {UI.Searchable}
- * @unrestricted
- */
-Timeline.TimelineFlameChartView = class extends UI.VBox {
-  /**
-   * @param {!Timeline.TimelineModeViewDelegate} delegate
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   */
-  constructor(delegate, filters) {
-    super();
-    this.element.classList.add('timeline-flamechart');
-    this._delegate = delegate;
-    /** @type {?Timeline.PerformanceModel} */
-    this._model = null;
-    /** @type {!Array<number>|undefined} */
-    this._searchResults;
-    this._filters = filters;
-
-    this._showMemoryGraphSetting = Common.settings.createSetting('timelineShowMemory', false);
-
-    // Create main and network flamecharts.
-    this._networkSplitWidget = new UI.SplitWidget(false, false, 'timelineFlamechartMainView', 150);
-
-    const mainViewGroupExpansionSetting = Common.settings.createSetting('timelineFlamechartMainViewGroupExpansion', {});
-    this._mainDataProvider = new Timeline.TimelineFlameChartDataProvider(filters);
-    this._mainDataProvider.addEventListener(
-        Timeline.TimelineFlameChartDataProvider.Events.DataChanged, () => this._mainFlameChart.scheduleUpdate());
-    this._mainFlameChart = new PerfUI.FlameChart(this._mainDataProvider, this, mainViewGroupExpansionSetting);
-    this._mainFlameChart.alwaysShowVerticalScroll();
-    this._mainFlameChart.enableRuler(false);
-
-    this._networkFlameChartGroupExpansionSetting =
-        Common.settings.createSetting('timelineFlamechartNetworkViewGroupExpansion', {});
-    this._networkDataProvider = new Timeline.TimelineFlameChartNetworkDataProvider();
-    this._networkFlameChart = new PerfUI.FlameChart(
-        this._networkDataProvider, this, this._networkFlameChartGroupExpansionSetting);
-    this._networkFlameChart.alwaysShowVerticalScroll();
-    this._networkFlameChart.disableRangeSelection();
-
-    this._networkPane = new UI.VBox();
-    this._networkPane.setMinimumSize(23, 23);
-    this._networkFlameChart.show(this._networkPane.element);
-    this._splitResizer = this._networkPane.element.createChild('div', 'timeline-flamechart-resizer');
-    this._networkSplitWidget.hideDefaultResizer(true);
-    this._networkSplitWidget.installResizer(this._splitResizer);
-
-    this._networkSplitWidget.setMainWidget(this._mainFlameChart);
-    this._networkSplitWidget.setSidebarWidget(this._networkPane);
-
-    // Create counters chart splitter.
-    this._chartSplitWidget = new UI.SplitWidget(false, true, 'timelineCountersSplitViewState');
-    this._countersView = new Timeline.CountersGraph(this._delegate);
-    this._chartSplitWidget.setMainWidget(this._networkSplitWidget);
-    this._chartSplitWidget.setSidebarWidget(this._countersView);
-    this._chartSplitWidget.hideDefaultResizer();
-    this._chartSplitWidget.installResizer(/** @type {!Element} */ (this._countersView.resizerElement()));
-    this._updateCountersGraphToggle();
-
-    // Create top level properties splitter.
-    this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState');
-    this._detailsSplitWidget.element.classList.add('timeline-details-split');
-    this._detailsView = new Timeline.TimelineDetailsView(filters, delegate);
-    this._detailsSplitWidget.installResizer(this._detailsView.headerElement());
-    this._detailsSplitWidget.setMainWidget(this._chartSplitWidget);
-    this._detailsSplitWidget.setSidebarWidget(this._detailsView);
-    this._detailsSplitWidget.show(this.element);
-
-    this._onMainEntrySelected = this._onEntrySelected.bind(this, this._mainDataProvider);
-    this._onNetworkEntrySelected = this._onEntrySelected.bind(this, this._networkDataProvider);
-    this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this);
-    this._networkFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this);
-    this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntryHighlighted, this._onEntryHighlighted, this);
-    this._nextExtensionIndex = 0;
-
-    this._boundRefresh = this._refresh.bind(this);
-    this._selectedTrack = null;
-
-    this._mainDataProvider.setEventColorMapping(Timeline.TimelineUIUtils.eventColor);
-    this._groupBySetting =
-        Common.settings.createSetting('timelineTreeGroupBy', Timeline.AggregatedTimelineTreeView.GroupBy.None);
-    this._groupBySetting.addChangeListener(this._updateColorMapper, this);
-    this._updateColorMapper();
-    ProductRegistry.instance().then(registry => this._productRegistry = registry);
-  }
-
-  _updateColorMapper() {
-    /** @type {!Map<string, string>} */
-    this._urlToColorCache = new Map();
-    if (!this._model)
-      return;
-    const colorByProduct = this._groupBySetting.get() === Timeline.AggregatedTimelineTreeView.GroupBy.Product;
-    this._mainDataProvider.setEventColorMapping(
-        colorByProduct ? this._colorByProductForEvent.bind(this) : Timeline.TimelineUIUtils.eventColor);
-    this._mainFlameChart.update();
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  _colorByProductForEvent(event) {
-    return Timeline.TimelineUIUtils.eventColorByProduct(
-        this._productRegistry, this._model.timelineModel(), this._urlToColorCache, event);
-  }
-
-  /**
-   * @override
-   * @return {?Element}
-   */
-  resizerElement() {
-    return null;
-  }
-
-  /**
-   * @override
-   * @param {number} windowStartTime
-   * @param {number} windowEndTime
-   * @param {boolean} animate
-   */
-  requestWindowTimes(windowStartTime, windowEndTime, animate) {
-    this._mainFlameChart.setWindowTimes(windowStartTime, windowEndTime, animate);
-    this._networkFlameChart.setWindowTimes(windowStartTime, windowEndTime, animate);
-    this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
-  }
-
-  /**
-   * @override
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  updateRangeSelection(startTime, endTime) {
-    this._delegate.select(Timeline.TimelineSelection.fromRange(startTime, endTime));
-  }
-
-  /**
-   * @override
-   * @param {!PerfUI.FlameChart} flameChart
-   * @param {?PerfUI.FlameChart.Group} group
-   */
-  updateSelectedGroup(flameChart, group) {
-    if (flameChart !== this._mainFlameChart)
-      return;
-    const track = group ? this._mainDataProvider.groupTrack(group) : null;
-    this._selectedTrack = track;
-    this._updateTrack();
-  }
-
-  /**
-   * @override
-   * @param {?Timeline.PerformanceModel} model
-   */
-  setModel(model) {
-    if (model === this._model)
-      return;
-    const extensionDataAdded = Timeline.PerformanceModel.Events.ExtensionDataAdded;
-    if (this._model)
-      this._model.removeEventListener(extensionDataAdded, this._appendExtensionData, this);
-    this._model = model;
-    this._selectedTrack = null;
-    if (this._model)
-      this._model.addEventListener(extensionDataAdded, this._appendExtensionData, this);
-    this._mainDataProvider.setModel(this._model);
-    this._networkDataProvider.setModel(this._model);
-    this._updateColorMapper();
-    this._updateTrack();
-    this._nextExtensionIndex = 0;
-    this._appendExtensionData();
-    this._refresh();
-  }
-
-  _updateTrack() {
-    this._countersView.setModel(this._model, this._selectedTrack);
-    this._detailsView.setModel(this._model, this._selectedTrack);
-  }
-
-  _refresh() {
-    if (this._networkDataProvider.isEmpty()) {
-      this._mainFlameChart.enableRuler(true);
-      this._networkSplitWidget.hideSidebar();
-    } else {
-      this._mainFlameChart.enableRuler(false);
-      this._networkSplitWidget.showBoth();
-      this.resizeToPreferredHeights();
-    }
-    this._mainFlameChart.reset();
-    this._networkFlameChart.reset();
-    this._updateSearchResults(false, false);
-  }
-
-  _appendExtensionData() {
-    if (!this._model)
-      return;
-    const extensions = this._model.extensionInfo();
-    while (this._nextExtensionIndex < extensions.length)
-      this._mainDataProvider.appendExtensionEvents(extensions[this._nextExtensionIndex++]);
-    this._mainFlameChart.scheduleUpdate();
-  }
-
-  /**
-   * @param {!Common.Event} commonEvent
-   */
-  _onEntryHighlighted(commonEvent) {
-    SDK.OverlayModel.hideDOMNodeHighlight();
-    const entryIndex = /** @type {number} */ (commonEvent.data);
-    const event = this._mainDataProvider.eventByIndex(entryIndex);
-    if (!event)
-      return;
-    const target = this._model && this._model.timelineModel().targetByEvent(event);
-    if (!target)
-      return;
-    const timelineData = TimelineModel.TimelineData.forEvent(event);
-    const backendNodeId = timelineData.backendNodeId;
-    if (!backendNodeId)
-      return;
-    new SDK.DeferredDOMNode(target, backendNodeId).highlight();
-  }
-
-  /**
-   * @override
-   * @param {?SDK.TracingModel.Event} event
-   */
-  highlightEvent(event) {
-    const entryIndex =
-        event ? this._mainDataProvider.entryIndexForSelection(Timeline.TimelineSelection.fromTraceEvent(event)) : -1;
-    if (entryIndex >= 0)
-      this._mainFlameChart.highlightEntry(entryIndex);
-    else
-      this._mainFlameChart.hideHighlight();
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._networkFlameChartGroupExpansionSetting.removeChangeListener(this.resizeToPreferredHeights, this);
-    this._showMemoryGraphSetting.removeChangeListener(this._updateCountersGraphToggle, this);
-    Bindings.blackboxManager.removeChangeListener(this._boundRefresh);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._networkFlameChartGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights, this);
-    this._showMemoryGraphSetting.addChangeListener(this._updateCountersGraphToggle, this);
-    Bindings.blackboxManager.addChangeListener(this._boundRefresh);
-    if (this._needsResizeToPreferredHeights)
-      this.resizeToPreferredHeights();
-    this._mainFlameChart.scheduleUpdate();
-    this._networkFlameChart.scheduleUpdate();
-  }
-
-  _updateCountersGraphToggle() {
-    if (this._showMemoryGraphSetting.get())
-      this._chartSplitWidget.showBoth();
-    else
-      this._chartSplitWidget.hideSidebar();
-  }
-
-  /**
-   * @override
-   * @return {!UI.Widget}
-   */
-  view() {
-    return this;
-  }
-
-  /**
-   * @override
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  setWindowTimes(startTime, endTime) {
-    this._mainFlameChart.setWindowTimes(startTime, endTime, /* animate */ true);
-    this._networkFlameChart.setWindowTimes(startTime, endTime, /* animate */ true);
-    this._networkDataProvider.setWindowTimes(startTime, endTime);
-    this._countersView.setWindowTimes(startTime, endTime);
-    this._windowStartTime = startTime;
-    this._windowEndTime = endTime;
-    this._updateSearchResults(false, false);
-  }
-
-  /**
-   * @override
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  setSelection(selection) {
-    let index = this._mainDataProvider.entryIndexForSelection(selection);
-    this._mainFlameChart.setSelectedEntry(index);
-    index = this._networkDataProvider.entryIndexForSelection(selection);
-    this._networkFlameChart.setSelectedEntry(index);
-    if (this._detailsView)
-      this._detailsView.setSelection(selection);
-  }
-
-  /**
-   * @param {!PerfUI.FlameChartDataProvider} dataProvider
-   * @param {!Common.Event} event
-   */
-  _onEntrySelected(dataProvider, event) {
-    const entryIndex = /** @type{number} */ (event.data);
-    if (Runtime.experiments.isEnabled('timelineEventInitiators') && dataProvider === this._mainDataProvider) {
-      if (this._mainDataProvider.buildFlowForInitiator(entryIndex))
-        this._mainFlameChart.scheduleUpdate();
-    }
-    this._delegate.select(dataProvider.createSelection(entryIndex));
-  }
-
-  resizeToPreferredHeights() {
-    if (!this.isShowing()) {
-      this._needsResizeToPreferredHeights = true;
-      return;
-    }
-    this._needsResizeToPreferredHeights = false;
-    this._networkPane.element.classList.toggle(
-        'timeline-network-resizer-disabled', !this._networkDataProvider.isExpanded());
-    this._networkSplitWidget.setSidebarSize(
-        this._networkDataProvider.preferredHeight() + this._splitResizer.clientHeight + PerfUI.FlameChart.HeaderHeight +
-        2);
-  }
-
-  /**
-   * @param {!UI.SearchableView} searchableView
-   */
-  setSearchableView(searchableView) {
-    this._searchableView = searchableView;
-  }
-
-  // UI.Searchable implementation
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._searchResults || !this._searchResults.length)
-      return;
-    const index = typeof this._selectedSearchResult !== 'undefined' ?
-        this._searchResults.indexOf(this._selectedSearchResult) :
-        -1;
-    this._selectSearchResult(mod(index + 1, this._searchResults.length));
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._searchResults || !this._searchResults.length)
-      return;
-    const index =
-        typeof this._selectedSearchResult !== 'undefined' ? this._searchResults.indexOf(this._selectedSearchResult) : 0;
-    this._selectSearchResult(mod(index - 1, this._searchResults.length));
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-
-  /**
-   * @param {number} index
-   */
-  _selectSearchResult(index) {
-    this._searchableView.updateCurrentMatchIndex(index);
-    this._selectedSearchResult = this._searchResults[index];
-    this._delegate.select(this._mainDataProvider.createSelection(this._selectedSearchResult));
-  }
-
-  /**
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  _updateSearchResults(shouldJump, jumpBackwards) {
-    const oldSelectedSearchResult = this._selectedSearchResult;
-    delete this._selectedSearchResult;
-    this._searchResults = [];
-    if (!this._searchRegex)
-      return;
-
-    const regExpFilter = new Timeline.TimelineFilters.RegExp(this._searchRegex);
-    this._searchResults = this._mainDataProvider.search(this._windowStartTime, this._windowEndTime, regExpFilter);
-    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-    if (!shouldJump || !this._searchResults.length)
-      return;
-    let selectedIndex = this._searchResults.indexOf(oldSelectedSearchResult);
-    if (selectedIndex === -1)
-      selectedIndex = jumpBackwards ? this._searchResults.length - 1 : 0;
-    this._selectSearchResult(selectedIndex);
-  }
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    if (typeof this._selectedSearchResult !== 'undefined')
-      this._delegate.select(null);
-    delete this._searchResults;
-    delete this._selectedSearchResult;
-    delete this._searchRegex;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this._searchRegex = searchConfig.toSearchRegex();
-    this._updateSearchResults(shouldJump, jumpBackwards);
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineFlameChartView.Selection = class {
-  /**
-   * @param {!Timeline.TimelineSelection} selection
-   * @param {number} entryIndex
-   */
-  constructor(selection, entryIndex) {
-    this.timelineSelection = selection;
-    this.entryIndex = entryIndex;
-  }
-};
-
-Timeline.FlameChartStyle = {
-  textColor: '#333'
-};
-
-/**
- * @implements {PerfUI.FlameChartMarker}
- * @unrestricted
- */
-Timeline.TimelineFlameChartMarker = class {
-  /**
-   * @param {number} startTime
-   * @param {number} startOffset
-   * @param {!Timeline.TimelineMarkerStyle} style
-   */
-  constructor(startTime, startOffset, style) {
-    this._startTime = startTime;
-    this._startOffset = startOffset;
-    this._style = style;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  startTime() {
-    return this._startTime;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  color() {
-    return this._style.color;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  title() {
-    const startTime = Number.millisToString(this._startOffset);
-    return Common.UIString('%s at %s', this._style.title, startTime);
-  }
-
-  /**
-   * @override
-   * @param {!CanvasRenderingContext2D} context
-   * @param {number} x
-   * @param {number} height
-   * @param {number} pixelsPerMillisecond
-   */
-  draw(context, x, height, pixelsPerMillisecond) {
-    const lowPriorityVisibilityThresholdInPixelsPerMs = 4;
-
-    if (this._style.lowPriority && pixelsPerMillisecond < lowPriorityVisibilityThresholdInPixelsPerMs)
-      return;
-    context.save();
-
-    if (!this._style.lowPriority) {
-      context.strokeStyle = this._style.color;
-      context.lineWidth = 2;
-      context.beginPath();
-      context.moveTo(x, 0);
-      context.lineTo(x, height);
-      context.stroke();
-    }
-
-    if (this._style.tall) {
-      context.strokeStyle = this._style.color;
-      context.lineWidth = this._style.lineWidth;
-      context.translate(this._style.lineWidth < 1 || (this._style.lineWidth & 1) ? 0.5 : 0, 0.5);
-      context.beginPath();
-      context.moveTo(x, height);
-      context.setLineDash(this._style.dashStyle);
-      context.lineTo(x, context.canvas.height);
-      context.stroke();
-    }
-    context.restore();
-  }
-};
-
-/** @enum {string} */
-Timeline.TimelineFlameChartView._ColorBy = {
-  URL: 'URL',
-  Product: 'Product'
-};
diff --git a/front_end/timeline/TimelineHistoryManager.js b/front_end/timeline/TimelineHistoryManager.js
deleted file mode 100644
index 04da83f..0000000
--- a/front_end/timeline/TimelineHistoryManager.js
+++ /dev/null
@@ -1,446 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Timeline.TimelineHistoryManager = class {
-  constructor() {
-    /** @type {!Array<!Timeline.PerformanceModel>} */
-    this._recordings = [];
-    this._action = /** @type {!UI.Action} */ (UI.actionRegistry.action('timeline.show-history'));
-    /** @type {!Map<string, number>} */
-    this._nextNumberByDomain = new Map();
-    this._button = new Timeline.TimelineHistoryManager.ToolbarButton(this._action);
-    this.clear();
-
-    this._allOverviews = [
-      {constructor: Timeline.TimelineEventOverviewResponsiveness, height: 3},
-      {constructor: Timeline.TimelineEventOverviewFrames, height: 16},
-      {constructor: Timeline.TimelineEventOverviewCPUActivity, height: 20},
-      {constructor: Timeline.TimelineEventOverviewNetwork, height: 8}
-    ];
-    this._totalHeight = this._allOverviews.reduce((acc, entry) => acc + entry.height, 0);
-    this._enabled = true;
-    /** @type {?Timeline.PerformanceModel} */
-    this._lastActiveModel = null;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   */
-  addRecording(performanceModel) {
-    this._lastActiveModel = performanceModel;
-    this._recordings.unshift(performanceModel);
-    this._buildPreview(performanceModel);
-    this._button.setText(this._title(performanceModel));
-    this._updateState();
-    if (this._recordings.length <= Timeline.TimelineHistoryManager._maxRecordings)
-      return;
-    const lruModel = this._recordings.reduce((a, b) => lastUsedTime(a) < lastUsedTime(b) ? a : b);
-    this._recordings.splice(this._recordings.indexOf(lruModel), 1);
-    lruModel.dispose();
-
-    /**
-     * @param {!Timeline.PerformanceModel} model
-     * @return {number}
-     */
-    function lastUsedTime(model) {
-      return Timeline.TimelineHistoryManager._dataForModel(model).lastUsed;
-    }
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._enabled = enabled;
-    this._updateState();
-  }
-
-  button() {
-    return this._button;
-  }
-
-  clear() {
-    this._recordings.forEach(model => model.dispose());
-    this._recordings = [];
-    this._lastActiveModel = null;
-    this._updateState();
-    this._button.setText(Common.UIString('(no recordings)'));
-    this._nextNumberByDomain.clear();
-  }
-
-  /**
-   * @return {!Promise<?Timeline.PerformanceModel>}
-   */
-  async showHistoryDropDown() {
-    if (this._recordings.length < 2 || !this._enabled)
-      return null;
-
-    const model = await Timeline.TimelineHistoryManager.DropDown.show(
-        this._recordings, /** @type {!Timeline.PerformanceModel} */ (this._lastActiveModel), this._button.element);
-    if (!model)
-      return null;
-    const index = this._recordings.indexOf(model);
-    if (index < 0) {
-      console.assert(false, `selected recording not found`);
-      return null;
-    }
-    this._setCurrentModel(model);
-    return model;
-  }
-
-  cancelIfShowing() {
-    Timeline.TimelineHistoryManager.DropDown.cancelIfShowing();
-  }
-
-  /**
-   * @param {number} direction
-   * @return {?Timeline.PerformanceModel}
-   */
-  navigate(direction) {
-    if (!this._enabled || !this._lastActiveModel)
-      return null;
-    const index = this._recordings.indexOf(this._lastActiveModel);
-    if (index < 0)
-      return null;
-    const newIndex = Number.constrain(index + direction, 0, this._recordings.length - 1);
-    const model = this._recordings[newIndex];
-    this._setCurrentModel(model);
-    return model;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} model
-   */
-  _setCurrentModel(model) {
-    Timeline.TimelineHistoryManager._dataForModel(model).lastUsed = Date.now();
-    this._lastActiveModel = model;
-    this._button.setText(this._title(model));
-  }
-
-  _updateState() {
-    this._action.setEnabled(this._recordings.length > 1 && this._enabled);
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   * @return {!Element}
-   */
-  static _previewElement(performanceModel) {
-    const data = Timeline.TimelineHistoryManager._dataForModel(performanceModel);
-    const startedAt = performanceModel.recordStartTime();
-    data.time.textContent =
-        startedAt ? Common.UIString('(%s ago)', Timeline.TimelineHistoryManager._coarseAge(startedAt)) : '';
-    return data.preview;
-  }
-
-  /**
-   * @param {number} time
-   * @return {string}
-   */
-  static _coarseAge(time) {
-    const seconds = Math.round((Date.now() - time) / 1000);
-    if (seconds < 50)
-      return Common.UIString('moments');
-    const minutes = Math.round(seconds / 60);
-    if (minutes < 50)
-      return Common.UIString('%s m', minutes);
-    const hours = Math.round(minutes / 60);
-    return Common.UIString('%s h', hours);
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   * @return {string}
-   */
-  _title(performanceModel) {
-    return Timeline.TimelineHistoryManager._dataForModel(performanceModel).title;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   */
-  _buildPreview(performanceModel) {
-    const parsedURL = performanceModel.timelineModel().pageURL().asParsedURL();
-    const domain = parsedURL ? parsedURL.host : '';
-    const sequenceNumber = this._nextNumberByDomain.get(domain) || 1;
-    const title = Common.UIString('%s #%d', domain, sequenceNumber);
-    this._nextNumberByDomain.set(domain, sequenceNumber + 1);
-    const timeElement = createElement('span');
-
-    const preview = createElementWithClass('div', 'preview-item vbox');
-    const data = {preview: preview, title: title, time: timeElement, lastUsed: Date.now()};
-    performanceModel[Timeline.TimelineHistoryManager._previewDataSymbol] = data;
-
-    preview.appendChild(this._buildTextDetails(performanceModel, title, timeElement));
-    const screenshotAndOverview = preview.createChild('div', 'hbox');
-    screenshotAndOverview.appendChild(this._buildScreenshotThumbnail(performanceModel));
-    screenshotAndOverview.appendChild(this._buildOverview(performanceModel));
-    return data.preview;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   * @param {string} title
-   * @param {!Element} timeElement
-   * @return {!Element}
-   */
-  _buildTextDetails(performanceModel, title, timeElement) {
-    const container = createElementWithClass('div', 'text-details hbox');
-    container.createChild('span', 'name').textContent = title;
-    const tracingModel = performanceModel.tracingModel();
-    const duration = Number.millisToString(tracingModel.maximumRecordTime() - tracingModel.minimumRecordTime(), false);
-    const timeContainer = container.createChild('span', 'time');
-    timeContainer.appendChild(createTextNode(duration));
-    timeContainer.appendChild(timeElement);
-    return container;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   * @return {!Element}
-   */
-  _buildScreenshotThumbnail(performanceModel) {
-    const container = createElementWithClass('div', 'screenshot-thumb');
-    const thumbnailAspectRatio = 3 / 2;
-    container.style.width = this._totalHeight * thumbnailAspectRatio + 'px';
-    container.style.height = this._totalHeight + 'px';
-    const filmStripModel = performanceModel.filmStripModel();
-    const lastFrame = filmStripModel.frames().peekLast();
-    if (!lastFrame)
-      return container;
-    lastFrame.imageDataPromise()
-        .then(data => UI.loadImageFromData(data))
-        .then(image => image && container.appendChild(image));
-    return container;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} performanceModel
-   * @return {!Element}
-   */
-  _buildOverview(performanceModel) {
-    const container = createElement('div');
-
-    container.style.width = Timeline.TimelineHistoryManager._previewWidth + 'px';
-    container.style.height = this._totalHeight + 'px';
-    const canvas = container.createChild('canvas');
-    canvas.width = window.devicePixelRatio * Timeline.TimelineHistoryManager._previewWidth;
-    canvas.height = window.devicePixelRatio * this._totalHeight;
-
-    const ctx = canvas.getContext('2d');
-    let yOffset = 0;
-    for (const overview of this._allOverviews) {
-      const timelineOverview = new overview.constructor();
-      timelineOverview.setCanvasSize(Timeline.TimelineHistoryManager._previewWidth, overview.height);
-      timelineOverview.setModel(performanceModel);
-      timelineOverview.update();
-      const sourceContext = timelineOverview.context();
-      const imageData = sourceContext.getImageData(0, 0, sourceContext.canvas.width, sourceContext.canvas.height);
-      ctx.putImageData(imageData, 0, yOffset);
-      yOffset += overview.height * window.devicePixelRatio;
-    }
-    return container;
-  }
-
-  /**
-   * @param {!Timeline.PerformanceModel} model
-   * @return {?Timeline.TimelineHistoryManager.PreviewData}
-   */
-  static _dataForModel(model) {
-    return model[Timeline.TimelineHistoryManager._previewDataSymbol] || null;
-  }
-};
-
-/** @typedef {!{preview: !Element, time: !Element, lastUsed: number, title: string}} */
-Timeline.TimelineHistoryManager.PreviewData;
-
-Timeline.TimelineHistoryManager._maxRecordings = 5;
-Timeline.TimelineHistoryManager._previewWidth = 450;
-Timeline.TimelineHistoryManager._previewDataSymbol = Symbol('previewData');
-
-/**
- * @implements {UI.ListDelegate<!Timeline.PerformanceModel>}
- */
-Timeline.TimelineHistoryManager.DropDown = class {
-  /**
-   * @param {!Array<!Timeline.PerformanceModel>} models
-   */
-  constructor(models) {
-    this._glassPane = new UI.GlassPane();
-    this._glassPane.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    this._glassPane.setOutsideClickCallback(() => this._close(null));
-    this._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-    this._glassPane.setAnchorBehavior(UI.GlassPane.AnchorBehavior.PreferBottom);
-
-    const shadowRoot =
-        UI.createShadowRootWithCoreStyles(this._glassPane.contentElement, 'timeline/timelineHistoryManager.css');
-    const contentElement = shadowRoot.createChild('div', 'drop-down');
-
-    const listModel = new UI.ListModel();
-    this._listControl = new UI.ListControl(listModel, this, UI.ListMode.NonViewport);
-    this._listControl.element.addEventListener('mousemove', this._onMouseMove.bind(this), false);
-    listModel.replaceAll(models);
-
-    contentElement.appendChild(this._listControl.element);
-    contentElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    contentElement.addEventListener('click', this._onClick.bind(this), false);
-
-    /** @type {?function(?Timeline.PerformanceModel)} */
-    this._selectionDone = null;
-  }
-
-  /**
-   * @param {!Array<!Timeline.PerformanceModel>} models
-   * @param {!Timeline.PerformanceModel} currentModel
-   * @param {!Element} anchor
-   * @return {!Promise<?Timeline.PerformanceModel>}
-   */
-  static show(models, currentModel, anchor) {
-    if (Timeline.TimelineHistoryManager.DropDown._instance)
-      return Promise.resolve(/** @type {?Timeline.PerformanceModel} */ (null));
-    const instance = new Timeline.TimelineHistoryManager.DropDown(models);
-    return instance._show(anchor, currentModel);
-  }
-
-  static cancelIfShowing() {
-    if (!Timeline.TimelineHistoryManager.DropDown._instance)
-      return;
-    Timeline.TimelineHistoryManager.DropDown._instance._close(null);
-  }
-
-  /**
-   * @param {!Element} anchor
-   * @param {!Timeline.PerformanceModel} currentModel
-   * @return {!Promise<?Timeline.PerformanceModel>}
-   */
-  _show(anchor, currentModel) {
-    Timeline.TimelineHistoryManager.DropDown._instance = this;
-    this._glassPane.setContentAnchorBox(anchor.boxInWindow());
-    this._glassPane.show(/** @type {!Document} */ (this._glassPane.contentElement.ownerDocument));
-    this._listControl.element.focus();
-    this._listControl.selectItem(currentModel);
-
-    return new Promise(fulfill => this._selectionDone = fulfill);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    const node = event.target.enclosingNodeOrSelfWithClass('preview-item');
-    const listItem = node && this._listControl.itemForNode(node);
-    if (!listItem)
-      return;
-    this._listControl.selectItem(listItem);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    if (!event.target.enclosingNodeOrSelfWithClass('preview-item'))
-      return;
-    this._close(this._listControl.selectedItem());
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    switch (event.key) {
-      case 'Escape':
-        this._close(null);
-        break;
-      case 'Enter':
-        this._close(this._listControl.selectedItem());
-        break;
-      default:
-        return;
-    }
-    event.consume(true);
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} model
-   */
-  _close(model) {
-    this._selectionDone(model);
-    this._glassPane.hide();
-    Timeline.TimelineHistoryManager.DropDown._instance = null;
-  }
-
-  /**
-   * @override
-   * @param {!Timeline.PerformanceModel} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    const element = Timeline.TimelineHistoryManager._previewElement(item);
-    element.classList.remove('selected');
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {!Timeline.PerformanceModel} item
-   * @return {number}
-   */
-  heightForItem(item) {
-    console.assert(false, 'Should not be called');
-    return 0;
-  }
-
-  /**
-   * @override
-   * @param {!Timeline.PerformanceModel} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?Timeline.PerformanceModel} from
-   * @param {?Timeline.PerformanceModel} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('selected');
-    if (toElement)
-      toElement.classList.add('selected');
-  }
-};
-
-/**
- * @type {?Timeline.TimelineHistoryManager.DropDown}
- */
-Timeline.TimelineHistoryManager.DropDown._instance = null;
-
-
-Timeline.TimelineHistoryManager.ToolbarButton = class extends UI.ToolbarItem {
-  /**
-   * @param {!UI.Action} action
-   */
-  constructor(action) {
-    super(createElementWithClass('button', 'dropdown-button'));
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'timeline/historyToolbarButton.css');
-
-    this._contentElement = shadowRoot.createChild('span', 'content');
-    const dropdownArrowIcon = UI.Icon.create('smallicon-triangle-down');
-    shadowRoot.appendChild(dropdownArrowIcon);
-    this.element.addEventListener('click', () => void action.execute(), false);
-    this.setEnabled(action.enabled());
-    action.addEventListener(UI.Action.Events.Enabled, event => this.setEnabled(/** @type {boolean} */ (event.data)));
-  }
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {
-    this._contentElement.textContent = text;
-  }
-};
diff --git a/front_end/timeline/TimelineLayersView.js b/front_end/timeline/TimelineLayersView.js
deleted file mode 100644
index 2947116..0000000
--- a/front_end/timeline/TimelineLayersView.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/**
- * @unrestricted
- */
-Timeline.TimelineLayersView = class extends UI.SplitWidget {
-  /**
-   * @param {!TimelineModel.TimelineModel} model
-   * @param {function(!SDK.PaintProfilerSnapshot)} showPaintProfilerCallback
-   */
-  constructor(model, showPaintProfilerCallback) {
-    super(true, false, 'timelineLayersView');
-    this._model = model;
-    this._showPaintProfilerCallback = showPaintProfilerCallback;
-
-    this.element.classList.add('timeline-layers-view');
-    this._rightSplitWidget = new UI.SplitWidget(true, true, 'timelineLayersViewDetails');
-    this._rightSplitWidget.element.classList.add('timeline-layers-view-properties');
-    this.setMainWidget(this._rightSplitWidget);
-
-    const vbox = new UI.VBox();
-    this.setSidebarWidget(vbox);
-
-    this._layerViewHost = new LayerViewer.LayerViewHost();
-
-    const layerTreeOutline = new LayerViewer.LayerTreeOutline(this._layerViewHost);
-    vbox.element.appendChild(layerTreeOutline.element);
-
-    this._layers3DView = new LayerViewer.Layers3DView(this._layerViewHost);
-    this._layers3DView.addEventListener(
-        LayerViewer.Layers3DView.Events.PaintProfilerRequested, this._onPaintProfilerRequested, this);
-    this._rightSplitWidget.setMainWidget(this._layers3DView);
-
-    const layerDetailsView = new LayerViewer.LayerDetailsView(this._layerViewHost);
-    this._rightSplitWidget.setSidebarWidget(layerDetailsView);
-    layerDetailsView.addEventListener(
-        LayerViewer.LayerDetailsView.Events.PaintProfilerRequested, this._onPaintProfilerRequested, this);
-  }
-
-  /**
-   * @param {!TimelineModel.TracingFrameLayerTree} frameLayerTree
-   */
-  showLayerTree(frameLayerTree) {
-    this._frameLayerTree = frameLayerTree;
-    if (this.isShowing())
-      this._update();
-    else
-      this._updateWhenVisible = true;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._updateWhenVisible) {
-      this._updateWhenVisible = false;
-      this._update();
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onPaintProfilerRequested(event) {
-    const selection = /** @type {!LayerViewer.LayerView.Selection} */ (event.data);
-    this._layers3DView.snapshotForSelection(selection).then(snapshotWithRect => {
-      if (snapshotWithRect)
-        this._showPaintProfilerCallback(snapshotWithRect.snapshot);
-    });
-  }
-
-  _update() {
-    this._frameLayerTree.layerTreePromise().then(layerTree => this._layerViewHost.setLayerTree(layerTree));
-  }
-};
diff --git a/front_end/timeline/TimelineLoader.js b/front_end/timeline/TimelineLoader.js
deleted file mode 100644
index fb7920a..0000000
--- a/front_end/timeline/TimelineLoader.js
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.OutputStream}
- * @unrestricted
- */
-Timeline.TimelineLoader = class {
-  /**
-   * @param {!Timeline.TimelineLoader.Client} client
-   */
-  constructor(client) {
-    this._client = client;
-
-    this._backingStorage = new Bindings.TempFileBackingStorage();
-    this._tracingModel = new SDK.TracingModel(this._backingStorage);
-
-    /** @type {?function()} */
-    this._canceledCallback = null;
-    this._state = Timeline.TimelineLoader.State.Initial;
-    this._buffer = '';
-    this._firstRawChunk = true;
-    this._firstChunk = true;
-    this._loadedBytes = 0;
-    /** @type {number} */
-    this._totalSize;
-    this._jsonTokenizer = new TextUtils.TextUtils.BalancedJSONTokenizer(this._writeBalancedJSON.bind(this), true);
-  }
-
-  /**
-   * @param {!File} file
-   * @param {!Timeline.TimelineLoader.Client} client
-   * @return {!Timeline.TimelineLoader}
-   */
-  static loadFromFile(file, client) {
-    const loader = new Timeline.TimelineLoader(client);
-    const fileReader = new Bindings.ChunkedFileReader(file, Timeline.TimelineLoader.TransferChunkLengthBytes);
-    loader._canceledCallback = fileReader.cancel.bind(fileReader);
-    loader._totalSize = file.size;
-    fileReader.read(loader).then(success => {
-      if (!success)
-        this._reportErrorAndCancelLoading(fileReader.error().message);
-    });
-    return loader;
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   * @param {!Timeline.TimelineLoader.Client} client
-   * @return {!Timeline.TimelineLoader}
-   */
-  static loadFromEvents(events, client) {
-    const loader = new Timeline.TimelineLoader(client);
-
-    setTimeout(async () => {
-      const eventsPerChunk = 5000;
-      client.loadingStarted();
-      for (let i = 0; i < events.length; i += eventsPerChunk) {
-        const chunk = events.slice(i, i + eventsPerChunk);
-        loader._tracingModel.addEvents(chunk);
-        client.loadingProgress((i + chunk.length) / events.length);
-        await new Promise(r => setTimeout(r));  // Yield event loop to paint.
-      }
-      loader.close();
-    });
-
-    return loader;
-  }
-
-  /**
-   * @param {string} url
-   * @param {!Timeline.TimelineLoader.Client} client
-   * @return {!Timeline.TimelineLoader}
-   */
-  static loadFromURL(url, client) {
-    const loader = new Timeline.TimelineLoader(client);
-    Host.ResourceLoader.loadAsStream(url, null, loader);
-    return loader;
-  }
-
-  cancel() {
-    this._tracingModel = null;
-    this._backingStorage.reset();
-    this._client.loadingComplete(null);
-    this._client = null;
-    if (this._canceledCallback)
-      this._canceledCallback();
-  }
-
-  /**
-   * @override
-   * @param {string} chunk
-   * @return {!Promise}
-   */
-  write(chunk) {
-    if (!this._client)
-      return Promise.resolve();
-    this._loadedBytes += chunk.length;
-    if (this._firstRawChunk)
-      this._client.loadingStarted();
-    else
-      this._client.loadingProgress(this._totalSize ? this._loadedBytes / this._totalSize : undefined);
-    this._firstRawChunk = false;
-
-    if (this._state === Timeline.TimelineLoader.State.Initial) {
-      if (chunk.startsWith('{"nodes":[')) {
-        this._state = Timeline.TimelineLoader.State.LoadingCPUProfileFormat;
-      } else if (chunk[0] === '{') {
-        this._state = Timeline.TimelineLoader.State.LookingForEvents;
-      } else if (chunk[0] === '[') {
-        this._state = Timeline.TimelineLoader.State.ReadingEvents;
-      } else {
-        this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data: Unknown JSON format'));
-        return Promise.resolve();
-      }
-    }
-
-    if (this._state === Timeline.TimelineLoader.State.LoadingCPUProfileFormat) {
-      this._buffer += chunk;
-      return Promise.resolve();
-    }
-
-    if (this._state === Timeline.TimelineLoader.State.LookingForEvents) {
-      const objectName = '"traceEvents":';
-      const startPos = this._buffer.length - objectName.length;
-      this._buffer += chunk;
-      const pos = this._buffer.indexOf(objectName, startPos);
-      if (pos === -1)
-        return Promise.resolve();
-      chunk = this._buffer.slice(pos + objectName.length);
-      this._state = Timeline.TimelineLoader.State.ReadingEvents;
-    }
-
-    if (this._state !== Timeline.TimelineLoader.State.ReadingEvents)
-      return Promise.resolve();
-    if (this._jsonTokenizer.write(chunk))
-      return Promise.resolve();
-    this._state = Timeline.TimelineLoader.State.SkippingTail;
-    if (this._firstChunk)
-      this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline input, wrong JSON brackets balance'));
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {string} data
-   */
-  _writeBalancedJSON(data) {
-    let json = data + ']';
-
-    if (!this._firstChunk) {
-      const commaIndex = json.indexOf(',');
-      if (commaIndex !== -1)
-        json = json.slice(commaIndex + 1);
-      json = '[' + json;
-    }
-
-    let items;
-    try {
-      items = /** @type {!Array.<!SDK.TracingManager.EventPayload>} */ (JSON.parse(json));
-    } catch (e) {
-      this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data: %s', e.toString()));
-      return;
-    }
-
-    if (this._firstChunk) {
-      this._firstChunk = false;
-      if (this._looksLikeAppVersion(items[0])) {
-        this._reportErrorAndCancelLoading(Common.UIString('Legacy Timeline format is not supported.'));
-        return;
-      }
-    }
-
-    try {
-      this._tracingModel.addEvents(items);
-    } catch (e) {
-      this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data: %s', e.toString()));
-    }
-  }
-
-  /**
-   * @param {string=} message
-   */
-  _reportErrorAndCancelLoading(message) {
-    if (message)
-      Common.console.error(message);
-    this.cancel();
-  }
-
-  /**
-   * @param {*} item
-   * @return {boolean}
-   */
-  _looksLikeAppVersion(item) {
-    return typeof item === 'string' && item.indexOf('Chrome') !== -1;
-  }
-
-  /**
-   * @override
-   */
-  close() {
-    if (!this._client)
-      return;
-    this._client.processingStarted();
-    setTimeout(() => this._finalizeTrace(), 0);
-  }
-
-  _finalizeTrace() {
-    if (this._state === Timeline.TimelineLoader.State.LoadingCPUProfileFormat) {
-      this._parseCPUProfileFormat(this._buffer);
-      this._buffer = '';
-    }
-    this._tracingModel.tracingComplete();
-    this._client.loadingComplete(this._tracingModel);
-  }
-
-  /**
-   * @param {string} text
-   */
-  _parseCPUProfileFormat(text) {
-    let traceEvents;
-    try {
-      const profile = JSON.parse(text);
-      traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile(profile);
-    } catch (e) {
-      this._reportErrorAndCancelLoading(Common.UIString('Malformed CPU profile format'));
-      return;
-    }
-    this._tracingModel.addEvents(traceEvents);
-  }
-};
-
-
-Timeline.TimelineLoader.TransferChunkLengthBytes = 5000000;
-
-/**
- * @interface
- */
-Timeline.TimelineLoader.Client = function() {};
-
-Timeline.TimelineLoader.Client.prototype = {
-  loadingStarted() {},
-
-  /**
-   * @param {number=} progress
-   */
-  loadingProgress(progress) {},
-
-  processingStarted() {},
-
-  /**
-   * @param {?SDK.TracingModel} tracingModel
-   */
-  loadingComplete(tracingModel) {},
-};
-
-/**
- * @enum {symbol}
- */
-Timeline.TimelineLoader.State = {
-  Initial: Symbol('Initial'),
-  LookingForEvents: Symbol('LookingForEvents'),
-  ReadingEvents: Symbol('ReadingEvents'),
-  SkippingTail: Symbol('SkippingTail'),
-  LoadingCPUProfileFormat: Symbol('LoadingCPUProfileFormat')
-};
diff --git a/front_end/timeline/TimelinePaintProfilerView.js b/front_end/timeline/TimelinePaintProfilerView.js
deleted file mode 100644
index c4c1153..0000000
--- a/front_end/timeline/TimelinePaintProfilerView.js
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Timeline.TimelinePaintProfilerView = class extends UI.SplitWidget {
-  /**
-   * @param {!TimelineModel.TimelineFrameModel} frameModel
-   */
-  constructor(frameModel) {
-    super(false, false);
-    this.element.classList.add('timeline-paint-profiler-view');
-    this.setSidebarSize(60);
-    this.setResizable(false);
-
-    this._frameModel = frameModel;
-    this._logAndImageSplitWidget = new UI.SplitWidget(true, false);
-    this._logAndImageSplitWidget.element.classList.add('timeline-paint-profiler-log-split');
-    this.setMainWidget(this._logAndImageSplitWidget);
-    this._imageView = new Timeline.TimelinePaintImageView();
-    this._logAndImageSplitWidget.setMainWidget(this._imageView);
-
-    this._paintProfilerView = new LayerViewer.PaintProfilerView(this._imageView.showImage.bind(this._imageView));
-    this._paintProfilerView.addEventListener(
-        LayerViewer.PaintProfilerView.Events.WindowChanged, this._onWindowChanged, this);
-    this.setSidebarWidget(this._paintProfilerView);
-
-    this._logTreeView = new LayerViewer.PaintProfilerCommandLogView();
-    this._logAndImageSplitWidget.setSidebarWidget(this._logTreeView);
-
-    this._needsUpdateWhenVisible = false;
-    /** @type {?SDK.PaintProfilerSnapshot} */
-    this._pendingSnapshot = null;
-    /** @type {?SDK.TracingModel.Event} */
-    this._event = null;
-    /** @type {?SDK.PaintProfilerModel} */
-    this._paintProfilerModel = null;
-    /** @type {?SDK.PaintProfilerSnapshot} */
-    this._lastLoadedSnapshot = null;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    if (this._needsUpdateWhenVisible) {
-      this._needsUpdateWhenVisible = false;
-      this._update();
-    }
-  }
-
-  /**
-   * @param {!SDK.PaintProfilerSnapshot} snapshot
-   */
-  setSnapshot(snapshot) {
-    this._releaseSnapshot();
-    this._pendingSnapshot = snapshot;
-    this._event = null;
-    this._updateWhenVisible();
-  }
-
-  /**
-   * @param {!SDK.PaintProfilerModel} paintProfilerModel
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  setEvent(paintProfilerModel, event) {
-    this._releaseSnapshot();
-    this._paintProfilerModel = paintProfilerModel;
-    this._pendingSnapshot = null;
-    this._event = event;
-
-    this._updateWhenVisible();
-    if (this._event.name === TimelineModel.TimelineModel.RecordType.Paint)
-      return !!TimelineModel.TimelineData.forEvent(event).picture;
-    if (this._event.name === TimelineModel.TimelineModel.RecordType.RasterTask)
-      return this._frameModel.hasRasterTile(this._event);
-    return false;
-  }
-
-  _updateWhenVisible() {
-    if (this.isShowing())
-      this._update();
-    else
-      this._needsUpdateWhenVisible = true;
-  }
-
-  _update() {
-    this._logTreeView.setCommandLog([]);
-    this._paintProfilerView.setSnapshotAndLog(null, [], null);
-
-    let snapshotPromise;
-    if (this._pendingSnapshot) {
-      snapshotPromise = Promise.resolve({rect: null, snapshot: this._pendingSnapshot});
-    } else if (this._event.name === TimelineModel.TimelineModel.RecordType.Paint) {
-      const picture = TimelineModel.TimelineData.forEvent(this._event).picture;
-      snapshotPromise = picture.objectPromise()
-                            .then(data => this._paintProfilerModel.loadSnapshot(data['skp64']))
-                            .then(snapshot => snapshot && {rect: null, snapshot: snapshot});
-    } else if (this._event.name === TimelineModel.TimelineModel.RecordType.RasterTask) {
-      snapshotPromise = this._frameModel.rasterTilePromise(this._event);
-    } else {
-      console.assert(false, 'Unexpected event type or no snapshot');
-      return;
-    }
-    snapshotPromise.then(snapshotWithRect => {
-      this._releaseSnapshot();
-      if (!snapshotWithRect) {
-        this._imageView.showImage();
-        return;
-      }
-      const snapshot = snapshotWithRect.snapshot;
-      this._lastLoadedSnapshot = snapshot;
-      this._imageView.setMask(snapshotWithRect.rect);
-      snapshot.commandLog().then(log => onCommandLogDone.call(this, snapshot, snapshotWithRect.rect, log));
-    });
-
-    /**
-     * @param {!SDK.PaintProfilerSnapshot} snapshot
-     * @param {?Protocol.DOM.Rect} clipRect
-     * @param {!Array.<!SDK.PaintProfilerLogItem>=} log
-     * @this {Timeline.TimelinePaintProfilerView}
-     */
-    function onCommandLogDone(snapshot, clipRect, log) {
-      this._logTreeView.setCommandLog(log || []);
-      this._paintProfilerView.setSnapshotAndLog(snapshot, log || [], clipRect);
-    }
-  }
-
-  _releaseSnapshot() {
-    if (!this._lastLoadedSnapshot)
-      return;
-    this._lastLoadedSnapshot.release();
-    this._lastLoadedSnapshot = null;
-  }
-
-  _onWindowChanged() {
-    this._logTreeView.updateWindow(this._paintProfilerView.selectionWindow());
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelinePaintImageView = class extends UI.Widget {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('timeline/timelinePaintProfiler.css');
-    this.contentElement.classList.add('fill', 'paint-profiler-image-view');
-    this._imageContainer = this.contentElement.createChild('div', 'paint-profiler-image-container');
-    this._imageElement = this._imageContainer.createChild('img');
-    this._maskElement = this._imageContainer.createChild('div');
-    this._imageElement.addEventListener('load', this._updateImagePosition.bind(this), false);
-
-    this._transformController = new LayerViewer.TransformController(this.contentElement, true);
-    this._transformController.addEventListener(
-        LayerViewer.TransformController.Events.TransformChanged, this._updateImagePosition, this);
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    if (this._imageElement.src)
-      this._updateImagePosition();
-  }
-
-  _updateImagePosition() {
-    const width = this._imageElement.naturalWidth;
-    const height = this._imageElement.naturalHeight;
-    const clientWidth = this.contentElement.clientWidth;
-    const clientHeight = this.contentElement.clientHeight;
-
-    const paddingFraction = 0.1;
-    const paddingX = clientWidth * paddingFraction;
-    const paddingY = clientHeight * paddingFraction;
-    const scaleX = (clientWidth - paddingX) / width;
-    const scaleY = (clientHeight - paddingY) / height;
-    const scale = Math.min(scaleX, scaleY);
-
-    if (this._maskRectangle) {
-      const style = this._maskElement.style;
-      style.width = width + 'px';
-      style.height = height + 'px';
-      style.borderLeftWidth = this._maskRectangle.x + 'px';
-      style.borderTopWidth = this._maskRectangle.y + 'px';
-      style.borderRightWidth = (width - this._maskRectangle.x - this._maskRectangle.width) + 'px';
-      style.borderBottomWidth = (height - this._maskRectangle.y - this._maskRectangle.height) + 'px';
-    }
-    this._transformController.setScaleConstraints(0.5, 10 / scale);
-    let matrix = new WebKitCSSMatrix()
-                     .scale(this._transformController.scale(), this._transformController.scale())
-                     .translate(clientWidth / 2, clientHeight / 2)
-                     .scale(scale, scale)
-                     .translate(-width / 2, -height / 2);
-    const bounds = UI.Geometry.boundsForTransformedPoints(matrix, [0, 0, 0, width, height, 0]);
-    this._transformController.clampOffsets(
-        paddingX - bounds.maxX, clientWidth - paddingX - bounds.minX, paddingY - bounds.maxY,
-        clientHeight - paddingY - bounds.minY);
-    matrix = new WebKitCSSMatrix()
-                 .translate(this._transformController.offsetX(), this._transformController.offsetY())
-                 .multiply(matrix);
-    this._imageContainer.style.webkitTransform = matrix.toString();
-  }
-
-  /**
-   * @param {string=} imageURL
-   */
-  showImage(imageURL) {
-    this._imageContainer.classList.toggle('hidden', !imageURL);
-    if (imageURL)
-      this._imageElement.src = imageURL;
-  }
-
-  /**
-   * @param {?Protocol.DOM.Rect} maskRectangle
-   */
-  setMask(maskRectangle) {
-    this._maskRectangle = maskRectangle;
-    this._maskElement.classList.toggle('hidden', !maskRectangle);
-  }
-};
diff --git a/front_end/timeline/TimelinePanel.js b/front_end/timeline/TimelinePanel.js
deleted file mode 100644
index 3ad001e..0000000
--- a/front_end/timeline/TimelinePanel.js
+++ /dev/null
@@ -1,1316 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2012 Intel Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @implements {Timeline.TimelineController.Client}
- * @implements {Timeline.TimelineModeViewDelegate}
- * @unrestricted
- */
-Timeline.TimelinePanel = class extends UI.Panel {
-  constructor() {
-    super('timeline');
-    this.registerRequiredCSS('timeline/timelinePanel.css');
-    this.element.addEventListener('contextmenu', this._contextMenu.bind(this), false);
-    this._dropTarget = new UI.DropTarget(
-        this.element, [UI.DropTarget.Type.File, UI.DropTarget.Type.URI],
-        Common.UIString('Drop timeline file or URL here'), this._handleDrop.bind(this));
-
-    /** @type {!Array<!UI.ToolbarItem>} */
-    this._recordingOptionUIControls = [];
-    this._state = Timeline.TimelinePanel.State.Idle;
-    this._recordingPageReload = false;
-    this._millisecondsToRecordAfterLoadEvent = 3000;
-    this._toggleRecordAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('timeline.toggle-recording'));
-    this._recordReloadAction =
-        /** @type {!UI.Action }*/ (UI.actionRegistry.action('timeline.record-reload'));
-
-    this._historyManager = new Timeline.TimelineHistoryManager();
-
-    /** @type {!Array<!TimelineModel.TimelineModelFilter>} */
-    this._filters = [];
-    if (!Runtime.experiments.isEnabled('timelineShowAllEvents')) {
-      this._filters.push(Timeline.TimelineUIUtils.visibleEventsFilter());
-      this._filters.push(new TimelineModel.ExcludeTopLevelFilter());
-    }
-
-    /** @type {?Timeline.PerformanceModel} */
-    this._performanceModel = null;
-
-    this._viewModeSetting =
-        Common.settings.createSetting('timelineViewMode', Timeline.TimelinePanel.ViewMode.FlameChart);
-
-    this._disableCaptureJSProfileSetting = Common.settings.createSetting('timelineDisableJSSampling', false);
-    this._disableCaptureJSProfileSetting.setTitle(Common.UIString('Disable JavaScript samples'));
-    this._captureLayersAndPicturesSetting = Common.settings.createSetting('timelineCaptureLayersAndPictures', false);
-    this._captureLayersAndPicturesSetting.setTitle(Common.UIString('Enable advanced paint instrumentation (slow)'));
-
-    this._showScreenshotsSetting = Common.settings.createSetting('timelineShowScreenshots', true);
-    this._showScreenshotsSetting.setTitle(Common.UIString('Screenshots'));
-    this._showScreenshotsSetting.addChangeListener(this._updateOverviewControls, this);
-
-    this._showMemorySetting = Common.settings.createSetting('timelineShowMemory', false);
-    this._showMemorySetting.setTitle(Common.UIString('Memory'));
-    this._showMemorySetting.addChangeListener(this._onModeChanged, this);
-
-    this._panelToolbar = new UI.Toolbar('', this.element);
-    this._createSettingsPane();
-    this._updateShowSettingsToolbarButton();
-
-    this._timelinePane = new UI.VBox();
-    this._timelinePane.show(this.element);
-    const topPaneElement = this._timelinePane.element.createChild('div', 'hbox');
-    topPaneElement.id = 'timeline-overview-panel';
-
-    // Create top overview component.
-    this._overviewPane = new PerfUI.TimelineOverviewPane('timeline');
-    this._overviewPane.addEventListener(
-        PerfUI.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
-    this._overviewPane.show(topPaneElement);
-    /** @type {!Array<!Timeline.TimelineEventOverview>} */
-    this._overviewControls = [];
-
-    this._statusPaneContainer = this._timelinePane.element.createChild('div', 'status-pane-container fill');
-
-    this._createFileSelector();
-
-    SDK.targetManager.addModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._loadEventFired, this);
-
-    this._flameChart = new Timeline.TimelineFlameChartView(this, this._filters);
-    this._searchableView = new UI.SearchableView(this._flameChart);
-    this._searchableView.setMinimumSize(0, 100);
-    this._searchableView.element.classList.add('searchable-view');
-    this._searchableView.show(this._timelinePane.element);
-    this._flameChart.show(this._searchableView.element);
-    this._flameChart.setSearchableView(this._searchableView);
-
-    this._onModeChanged();
-    this._populateToolbar();
-    this._showLandingPage();
-    this._updateTimelineControls();
-
-    Extensions.extensionServer.addEventListener(
-        Extensions.ExtensionServer.Events.TraceProviderAdded, this._appendExtensionsToToolbar, this);
-    SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
-  }
-
-  /**
-   * @return {!Timeline.TimelinePanel}
-   */
-  static instance() {
-    return /** @type {!Timeline.TimelinePanel} */ (self.runtime.sharedInstance(Timeline.TimelinePanel));
-  }
-
-  /**
-   * @override
-   * @return {?UI.SearchableView}
-   */
-  searchableView() {
-    return this._searchableView;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Timeline.TimelinePanel, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.context.setFlavor(Timeline.TimelinePanel, null);
-    this._historyManager.cancelIfShowing();
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   */
-  loadFromEvents(events) {
-    if (this._state !== Timeline.TimelinePanel.State.Idle)
-      return;
-    this._prepareToLoadTimeline();
-    this._loader = Timeline.TimelineLoader.loadFromEvents(events, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onWindowChanged(event) {
-    const selectionData = this._currentModelSelectionData();
-    if (!selectionData)
-      return;
-    selectionData.windowStartTime = event.data.startTime;
-    selectionData.windowEndTime = event.data.endTime;
-
-    this._flameChart.setWindowTimes(selectionData.windowStartTime, selectionData.windowEndTime);
-    if (selectionData.selection.type() === Timeline.TimelineSelection.Type.Range)
-      this.select(null);
-  }
-
-  /**
-   * @override
-   * @param {number} windowStartTime
-   * @param {number} windowEndTime
-   */
-  requestWindowTimes(windowStartTime, windowEndTime) {
-    this._overviewPane.requestWindowTimes(windowStartTime, windowEndTime);
-  }
-
-  /**
-   * @param {!Timeline.TimelinePanel.State} state
-   */
-  _setState(state) {
-    this._state = state;
-    this._updateTimelineControls();
-  }
-
-  /**
-   * @param {!Common.Setting} setting
-   * @param {string} tooltip
-   * @return {!UI.ToolbarItem}
-   */
-  _createSettingCheckbox(setting, tooltip) {
-    const checkboxItem = new UI.ToolbarSettingCheckbox(setting, tooltip);
-    this._recordingOptionUIControls.push(checkboxItem);
-    return checkboxItem;
-  }
-
-  _populateToolbar() {
-    // Record
-    this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
-    this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._recordReloadAction));
-    this._clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
-    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._onClearButton());
-    this._panelToolbar.appendToolbarItem(this._clearButton);
-
-    // Load / Save
-    this._loadButton = new UI.ToolbarButton(Common.UIString('Load profile...'), 'largeicon-load');
-    this._loadButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._selectFileToLoad());
-    this._saveButton = new UI.ToolbarButton(Common.UIString('Save profile...'), 'largeicon-download');
-    this._saveButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._saveToFile());
-    this._panelToolbar.appendSeparator();
-    this._panelToolbar.appendToolbarItem(this._loadButton);
-    this._panelToolbar.appendToolbarItem(this._saveButton);
-
-    // History
-    this._panelToolbar.appendSeparator();
-    this._panelToolbar.appendToolbarItem(this._historyManager.button());
-    this._panelToolbar.appendSeparator();
-
-    // View
-    this._panelToolbar.appendSeparator();
-    this._showScreenshotsToolbarCheckbox =
-        this._createSettingCheckbox(this._showScreenshotsSetting, Common.UIString('Capture screenshots'));
-    this._panelToolbar.appendToolbarItem(this._showScreenshotsToolbarCheckbox);
-
-    this._showMemoryToolbarCheckbox =
-        this._createSettingCheckbox(this._showMemorySetting, Common.UIString('Show memory timeline'));
-    this._panelToolbar.appendToolbarItem(this._showMemoryToolbarCheckbox);
-
-    // GC
-    this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));
-
-    // Settings
-    this._panelToolbar.appendSpacer();
-    this._panelToolbar.appendText('');
-    this._panelToolbar.appendSeparator();
-    this._panelToolbar.appendToolbarItem(this._showSettingsPaneButton);
-  }
-
-  _createSettingsPane() {
-    this._showSettingsPaneSetting = Common.settings.createSetting('timelineShowSettingsToolbar', false);
-    this._showSettingsPaneButton = new UI.ToolbarSettingToggle(
-        this._showSettingsPaneSetting, 'largeicon-settings-gear', Common.UIString('Capture settings'));
-    SDK.multitargetNetworkManager.addEventListener(
-        SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._updateShowSettingsToolbarButton, this);
-    MobileThrottling.throttlingManager().addEventListener(
-        MobileThrottling.ThrottlingManager.Events.RateChanged, this._updateShowSettingsToolbarButton, this);
-    this._disableCaptureJSProfileSetting.addChangeListener(this._updateShowSettingsToolbarButton, this);
-    this._captureLayersAndPicturesSetting.addChangeListener(this._updateShowSettingsToolbarButton, this);
-
-    this._settingsPane = new UI.HBox();
-    this._settingsPane.element.classList.add('timeline-settings-pane');
-    this._settingsPane.show(this.element);
-
-    const captureToolbar = new UI.Toolbar('', this._settingsPane.element);
-    captureToolbar.element.classList.add('flex-auto');
-    captureToolbar.makeVertical();
-    captureToolbar.appendToolbarItem(this._createSettingCheckbox(
-        this._disableCaptureJSProfileSetting,
-        Common.UIString('Disables JavaScript sampling, reduces overhead when running against mobile devices')));
-    captureToolbar.appendToolbarItem(this._createSettingCheckbox(
-        this._captureLayersAndPicturesSetting,
-        Common.UIString('Captures advanced paint instrumentation, introduces significant performance overhead')));
-
-    const throttlingPane = new UI.VBox();
-    throttlingPane.element.classList.add('flex-auto');
-    throttlingPane.show(this._settingsPane.element);
-
-    const networkThrottlingToolbar = new UI.Toolbar('', throttlingPane.element);
-    networkThrottlingToolbar.appendText(Common.UIString('Network:'));
-    this._networkThrottlingSelect = this._createNetworkConditionsSelect();
-    networkThrottlingToolbar.appendToolbarItem(this._networkThrottlingSelect);
-
-    const cpuThrottlingToolbar = new UI.Toolbar('', throttlingPane.element);
-    cpuThrottlingToolbar.appendText(Common.UIString('CPU:'));
-    this._cpuThrottlingSelect = MobileThrottling.throttlingManager().createCPUThrottlingSelector();
-    cpuThrottlingToolbar.appendToolbarItem(this._cpuThrottlingSelect);
-
-    this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));
-    this._updateSettingsPaneVisibility();
-  }
-
-  /**
-    * @param {!Common.Event} event
-    */
-  _appendExtensionsToToolbar(event) {
-    const provider = /** @type {!Extensions.ExtensionTraceProvider} */ (event.data);
-    const setting = Timeline.TimelinePanel._settingForTraceProvider(provider);
-    const checkbox = this._createSettingCheckbox(setting, provider.longDisplayName());
-    this._panelToolbar.appendToolbarItem(checkbox);
-  }
-
-  /**
-   * @param {!Extensions.ExtensionTraceProvider} traceProvider
-   * @return {!Common.Setting<boolean>}
-   */
-  static _settingForTraceProvider(traceProvider) {
-    let setting = traceProvider[Timeline.TimelinePanel._traceProviderSettingSymbol];
-    if (!setting) {
-      const providerId = traceProvider.persistentIdentifier();
-      setting = Common.settings.createSetting(providerId, false);
-      setting.setTitle(traceProvider.shortDisplayName());
-      traceProvider[Timeline.TimelinePanel._traceProviderSettingSymbol] = setting;
-    }
-    return setting;
-  }
-
-  /**
-   * @return {!UI.ToolbarComboBox}
-   */
-  _createNetworkConditionsSelect() {
-    const toolbarItem = new UI.ToolbarComboBox(null);
-    toolbarItem.setMaxWidth(140);
-    MobileThrottling.throttlingManager().decorateSelectWithNetworkThrottling(toolbarItem.selectElement());
-    return toolbarItem;
-  }
-
-  _prepareToLoadTimeline() {
-    console.assert(this._state === Timeline.TimelinePanel.State.Idle);
-    this._setState(Timeline.TimelinePanel.State.Loading);
-    if (this._performanceModel) {
-      this._performanceModel.dispose();
-      this._performanceModel = null;
-    }
-  }
-
-  _createFileSelector() {
-    if (this._fileSelectorElement)
-      this._fileSelectorElement.remove();
-    this._fileSelectorElement = UI.createFileSelectorElement(this._loadFromFile.bind(this));
-    this._timelinePane.element.appendChild(this._fileSelectorElement);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _contextMenu(event) {
-    const contextMenu = new UI.ContextMenu(event);
-    contextMenu.appendItemsAtLocation('timelineMenu');
-    contextMenu.show();
-  }
-
-  async _saveToFile() {
-    if (this._state !== Timeline.TimelinePanel.State.Idle)
-      return;
-    const performanceModel = this._performanceModel;
-    if (!performanceModel)
-      return;
-
-    const now = new Date();
-    const fileName = 'Profile-' + now.toISO8601Compact() + '.json';
-    const stream = new Bindings.FileOutputStream();
-
-    const accepted = await stream.open(fileName);
-    if (!accepted)
-      return;
-
-    const error = await performanceModel.save(stream);
-    if (!error)
-      return;
-    Common.console.error(
-        Common.UIString('Failed to save timeline: %s (%s, %s)', error.message, error.name, error.code));
-  }
-
-  async _showHistory() {
-    const model = await this._historyManager.showHistoryDropDown();
-    if (model && model !== this._performanceModel)
-      this._setModel(model);
-  }
-
-  /**
-   * @param {number} direction
-   * @return {boolean}
-   */
-  _navigateHistory(direction) {
-    const model = this._historyManager.navigate(direction);
-    if (model && model !== this._performanceModel)
-      this._setModel(model);
-    return true;
-  }
-
-  _selectFileToLoad() {
-    this._fileSelectorElement.click();
-  }
-
-  /**
-   * @param {!File} file
-   */
-  _loadFromFile(file) {
-    if (this._state !== Timeline.TimelinePanel.State.Idle)
-      return;
-    this._prepareToLoadTimeline();
-    this._loader = Timeline.TimelineLoader.loadFromFile(file, this);
-    this._createFileSelector();
-  }
-
-  /**
-   * @param {string} url
-   */
-  _loadFromURL(url) {
-    if (this._state !== Timeline.TimelinePanel.State.Idle)
-      return;
-    this._prepareToLoadTimeline();
-    this._loader = Timeline.TimelineLoader.loadFromURL(url, this);
-  }
-
-  _updateOverviewControls() {
-    this._overviewControls = [];
-    this._overviewControls.push(new Timeline.TimelineEventOverviewResponsiveness());
-    if (Runtime.experiments.isEnabled('inputEventsOnTimelineOverview'))
-      this._overviewControls.push(new Timeline.TimelineEventOverviewInput());
-    this._overviewControls.push(new Timeline.TimelineEventOverviewFrames());
-    this._overviewControls.push(new Timeline.TimelineEventOverviewCPUActivity());
-    this._overviewControls.push(new Timeline.TimelineEventOverviewNetwork());
-    if (this._showScreenshotsSetting.get())
-      this._overviewControls.push(new Timeline.TimelineFilmStripOverview());
-    if (this._showMemorySetting.get())
-      this._overviewControls.push(new Timeline.TimelineEventOverviewMemory());
-    for (const control of this._overviewControls)
-      control.setModel(this._performanceModel);
-    this._overviewPane.setOverviewControls(this._overviewControls);
-  }
-
-  _onModeChanged() {
-    this._updateOverviewControls();
-    this.doResize();
-    this.select(null);
-  }
-
-  _updateSettingsPaneVisibility() {
-    if (this._showSettingsPaneSetting.get())
-      this._settingsPane.showWidget();
-    else
-      this._settingsPane.hideWidget();
-  }
-
-  _updateShowSettingsToolbarButton() {
-    const messages = [];
-    if (MobileThrottling.throttlingManager().cpuThrottlingRate() !== 1)
-      messages.push(Common.UIString('- CPU throttling is enabled'));
-    if (SDK.multitargetNetworkManager.isThrottling())
-      messages.push(Common.UIString('- Network throttling is enabled'));
-    if (this._captureLayersAndPicturesSetting.get())
-      messages.push(Common.UIString('- Significant overhead due to paint instrumentation'));
-    if (this._disableCaptureJSProfileSetting.get())
-      messages.push(Common.UIString('- JavaScript sampling is disabled'));
-
-    this._showSettingsPaneButton.setDefaultWithRedColor(messages.length);
-    this._showSettingsPaneButton.setToggleWithRedColor(messages.length);
-
-    if (messages.length) {
-      const tooltipElement = createElement('div');
-      messages.forEach(message => {
-        tooltipElement.createChild('div').textContent = message;
-      });
-      this._showSettingsPaneButton.setTitle(tooltipElement);
-    } else {
-      this._showSettingsPaneButton.setTitle(Common.UIString('Capture settings'));
-    }
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  _setUIControlsEnabled(enabled) {
-    this._recordingOptionUIControls.forEach(control => control.setEnabled(enabled));
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  async _startRecording() {
-    console.assert(!this._statusPane, 'Status pane is already opened.');
-    this._setState(Timeline.TimelinePanel.State.StartPending);
-    this._showRecordingStarted();
-
-    const enabledTraceProviders = Extensions.extensionServer.traceProviders().filter(
-        provider => Timeline.TimelinePanel._settingForTraceProvider(provider).get());
-
-    const recordingOptions = {
-      enableJSSampling: !this._disableCaptureJSProfileSetting.get(),
-      capturePictures: this._captureLayersAndPicturesSetting.get(),
-      captureFilmStrip: this._showScreenshotsSetting.get()
-    };
-
-    const mainTarget = /** @type {!SDK.Target} */ (SDK.targetManager.mainTarget());
-    this._controller = new Timeline.TimelineController(mainTarget, this);
-    this._setUIControlsEnabled(false);
-    this._hideLandingPage();
-    await this._controller.startRecording(recordingOptions, enabledTraceProviders);
-    this._recordingStarted();
-  }
-
-  async _stopRecording() {
-    if (this._statusPane) {
-      this._statusPane.finish();
-      this._statusPane.updateStatus(Common.UIString('Stopping timeline\u2026'));
-      this._statusPane.updateProgressBar(Common.UIString('Received'), 0);
-    }
-    this._setState(Timeline.TimelinePanel.State.StopPending);
-    this._performanceModel = await this._controller.stopRecording();
-    this._setUIControlsEnabled(true);
-    this._controller = null;
-  }
-
-  _onSuspendStateChanged() {
-    this._updateTimelineControls();
-  }
-
-  _updateTimelineControls() {
-    const state = Timeline.TimelinePanel.State;
-    this._toggleRecordAction.setToggled(this._state === state.Recording);
-    this._toggleRecordAction.setEnabled(this._state === state.Recording || this._state === state.Idle);
-    this._recordReloadAction.setEnabled(this._state === state.Idle);
-    this._historyManager.setEnabled(this._state === state.Idle);
-    this._clearButton.setEnabled(this._state === state.Idle);
-    this._panelToolbar.setEnabled(this._state !== state.Loading);
-    this._dropTarget.setEnabled(this._state === state.Idle);
-    this._loadButton.setEnabled(this._state === state.Idle);
-    this._saveButton.setEnabled(this._state === state.Idle && !!this._performanceModel);
-  }
-
-  _toggleRecording() {
-    if (this._state === Timeline.TimelinePanel.State.Idle) {
-      this._recordingPageReload = false;
-      this._startRecording();
-      Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelineStarted);
-    } else if (this._state === Timeline.TimelinePanel.State.Recording) {
-      this._stopRecording();
-    }
-  }
-
-  _recordReload() {
-    if (this._state !== Timeline.TimelinePanel.State.Idle)
-      return;
-    this._recordingPageReload = true;
-    this._startRecording();
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelinePageReloadStarted);
-  }
-
-  _onClearButton() {
-    this._historyManager.clear();
-    this._clear();
-  }
-
-  _clear() {
-    this._showLandingPage();
-    this._reset();
-  }
-
-  _reset() {
-    PerfUI.LineLevelProfile.instance().reset();
-    this._setModel(null);
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} model
-   */
-  _setModel(model) {
-    this._performanceModel = model;
-    this._flameChart.setModel(model);
-
-    this._overviewPane.reset();
-    if (model) {
-      this._overviewPane.setBounds(
-          model.timelineModel().minimumRecordTime(), model.timelineModel().maximumRecordTime());
-      if (!model[Timeline.TimelinePanel._modelSelectionDataSymbol]) {
-        const times = Timeline.TimelinePanel._autoWindowTimes(model.timelineModel());
-        model[Timeline.TimelinePanel._modelSelectionDataSymbol] = {
-          selection: Timeline.TimelineSelection.fromRange(times.start, times.end),
-          windowStartTime: times.start,
-          windowEndTime: times.end
-        };
-      }
-    }
-    for (const control of this._overviewControls)
-      control.setModel(model);
-
-    if (model) {
-      const cpuProfiles = model.timelineModel().cpuProfiles();
-      cpuProfiles.forEach(profile => PerfUI.LineLevelProfile.instance().appendCPUProfile(profile));
-
-      this._setMarkers(model.timelineModel());
-      const selectionData = this._currentModelSelectionData();
-      this.requestWindowTimes(selectionData.windowStartTime, selectionData.windowEndTime);
-      this._flameChart.setSelection(selectionData.selection);
-    } else {
-      this.requestWindowTimes(0, Infinity);
-    }
-    if (this._flameChart)
-      this._flameChart.resizeToPreferredHeights();
-    this._updateTimelineControls();
-  }
-
-  _recordingStarted() {
-    if (this._recordingPageReload) {
-      const target = this._controller.mainTarget();
-      const resourceModel = target.model(SDK.ResourceTreeModel);
-      if (resourceModel)
-        resourceModel.reloadPage();
-    }
-    this._reset();
-    this._setState(Timeline.TimelinePanel.State.Recording);
-    this._showRecordingStarted();
-    this._statusPane.updateStatus(Common.UIString('Profiling\u2026'));
-    this._statusPane.updateProgressBar(Common.UIString('Buffer usage'), 0);
-    this._statusPane.startTimer();
-    this._hideLandingPage();
-  }
-
-  /**
-   * @override
-   * @param {number} usage
-   */
-  recordingProgress(usage) {
-    this._statusPane.updateProgressBar(Common.UIString('Buffer usage'), usage * 100);
-  }
-
-  _showLandingPage() {
-    if (this._landingPage) {
-      this._landingPage.show(this._statusPaneContainer);
-      return;
-    }
-
-    /**
-     * @param {string} tagName
-     * @param {string} contents
-     */
-    function encloseWithTag(tagName, contents) {
-      const e = createElement(tagName);
-      e.textContent = contents;
-      return e;
-    }
-
-    const learnMoreNode = UI.XLink.create(
-        'https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/',
-        Common.UIString('Learn\xa0more'));
-
-    const recordKey =
-        encloseWithTag('b', UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording')[0].name);
-    const reloadKey =
-        encloseWithTag('b', UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.record-reload')[0].name);
-    const navigateNode = encloseWithTag('b', Common.UIString('WASD'));
-
-    this._landingPage = new UI.VBox();
-    this._landingPage.contentElement.classList.add('timeline-landing-page', 'fill');
-    const centered = this._landingPage.contentElement.createChild('div');
-
-    const recordButton = UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));
-    const reloadButton = UI.createInlineButton(UI.Toolbar.createActionButtonForId('timeline.record-reload'));
-
-    centered.createChild('p').appendChild(UI.formatLocalized(
-        'Click the record button %s or hit %s to start a new recording.\n' +
-            'Click the reload button %s or hit %s to record the page load.',
-        [recordButton, recordKey, reloadButton, reloadKey]));
-
-    centered.createChild('p').appendChild(UI.formatLocalized(
-        'After recording, select an area of interest in the overview by dragging.\n' +
-        'Then, zoom and pan the timeline with the mousewheel or %s keys.\n%s',
-        [navigateNode, learnMoreNode]));
-
-    this._landingPage.show(this._statusPaneContainer);
-  }
-
-  _hideLandingPage() {
-    this._landingPage.detach();
-  }
-
-  /**
-   * @override
-   */
-  loadingStarted() {
-    this._hideLandingPage();
-
-    if (this._statusPane)
-      this._statusPane.hide();
-    this._statusPane = new Timeline.TimelinePanel.StatusPane(false, this._cancelLoading.bind(this));
-    this._statusPane.showPane(this._statusPaneContainer);
-    this._statusPane.updateStatus(Common.UIString('Loading profile\u2026'));
-    // FIXME: make loading from backend cancelable as well.
-    if (!this._loader)
-      this._statusPane.finish();
-    this.loadingProgress(0);
-  }
-
-  /**
-   * @override
-   * @param {number=} progress
-   */
-  loadingProgress(progress) {
-    if (typeof progress === 'number')
-      this._statusPane.updateProgressBar(Common.UIString('Received'), progress * 100);
-  }
-
-  /**
-   * @override
-   */
-  processingStarted() {
-    this._statusPane.updateStatus(Common.UIString('Processing profile\u2026'));
-  }
-
-  /**
-   * @override
-   * @param {?SDK.TracingModel} tracingModel
-   */
-  loadingComplete(tracingModel) {
-    delete this._loader;
-    this._setState(Timeline.TimelinePanel.State.Idle);
-
-    if (this._statusPane)
-      this._statusPane.hide();
-    delete this._statusPane;
-
-    if (!tracingModel) {
-      this._clear();
-      return;
-    }
-
-    if (!this._performanceModel)
-      this._performanceModel = new Timeline.PerformanceModel();
-    this._performanceModel.setTracingModel(tracingModel);
-    this._setModel(this._performanceModel);
-    this._historyManager.addRecording(this._performanceModel);
-  }
-
-  _showRecordingStarted() {
-    if (this._statusPane)
-      return;
-    this._statusPane = new Timeline.TimelinePanel.StatusPane(true, this._stopRecording.bind(this));
-    this._statusPane.showPane(this._statusPaneContainer);
-    this._statusPane.updateStatus(Common.UIString('Initializing profiler\u2026'));
-  }
-
-  _cancelLoading() {
-    if (this._loader)
-      this._loader.cancel();
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel} timelineModel
-   */
-  _setMarkers(timelineModel) {
-    const markers = new Map();
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    const zeroTime = timelineModel.minimumRecordTime();
-    const filter = Timeline.TimelineUIUtils.paintEventsFilter();
-    for (const event of timelineModel.eventDividers()) {
-      if (event.name === recordTypes.TimeStamp || event.name === recordTypes.ConsoleTime)
-        continue;
-      if (!filter.accept(event))
-        continue;
-      markers.set(event.startTime, Timeline.TimelineUIUtils.createEventDivider(event, zeroTime));
-    }
-    this._overviewPane.setMarkers(markers);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  async _loadEventFired(event) {
-    if (this._state !== Timeline.TimelinePanel.State.Recording || !this._recordingPageReload ||
-        this._controller.mainTarget() !== event.data.resourceTreeModel.target())
-      return;
-    const controller = this._controller;
-    await new Promise(r => setTimeout(r, this._millisecondsToRecordAfterLoadEvent));
-
-    // Check if we're still in the same recording session.
-    if (controller !== this._controller)
-      return;
-    this._recordingPageReload = false;
-    this._stopRecording();
-  }
-
-  /**
-   * @param {!Timeline.TimelineSelection} selection
-   * @return {?TimelineModel.TimelineFrame}
-   */
-  _frameForSelection(selection) {
-    switch (selection.type()) {
-      case Timeline.TimelineSelection.Type.Frame:
-        return /** @type {!TimelineModel.TimelineFrame} */ (selection.object());
-      case Timeline.TimelineSelection.Type.Range:
-        return null;
-      case Timeline.TimelineSelection.Type.TraceEvent:
-        return this._performanceModel.frameModel().filteredFrames(selection._endTime, selection._endTime)[0];
-      default:
-        console.assert(false, 'Should never be reached');
-        return null;
-    }
-  }
-
-  /**
-   * @param {number} offset
-   */
-  _jumpToFrame(offset) {
-    const selection = this._selection();
-    const currentFrame = selection && this._frameForSelection(selection);
-    if (!currentFrame)
-      return;
-    const frames = this._performanceModel.frames();
-    let index = frames.indexOf(currentFrame);
-    console.assert(index >= 0, 'Can\'t find current frame in the frame list');
-    index = Number.constrain(index + offset, 0, frames.length - 1);
-    const frame = frames[index];
-    this._revealTimeRange(frame.startTime, frame.endTime);
-    this.select(Timeline.TimelineSelection.fromFrame(frame));
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?Timeline.TimelineSelection} selection
-   */
-  select(selection) {
-    const selectionData = this._currentModelSelectionData();
-    if (!selectionData)
-      return;
-    if (!selection)
-      selection = Timeline.TimelineSelection.fromRange(selectionData.windowStartTime, selectionData.windowEndTime);
-    selectionData.selection = selection;
-    this._flameChart.setSelection(selection);
-  }
-
-  /**
-   * @override
-   * @param {?Array<!SDK.TracingModel.Event>} events
-   * @param {number} time
-   */
-  selectEntryAtTime(events, time) {
-    if (!events)
-      return;
-    // Find best match, then backtrack to the first visible entry.
-    for (let index = events.upperBound(time, (time, event) => time - event.startTime) - 1; index >= 0; --index) {
-      const event = events[index];
-      const endTime = event.endTime || event.startTime;
-      if (SDK.TracingModel.isTopLevelEvent(event) && endTime < time)
-        break;
-      if (TimelineModel.TimelineModel.isVisible(this._filters, event) && endTime >= time) {
-        this.select(Timeline.TimelineSelection.fromTraceEvent(event));
-        return;
-      }
-    }
-    this.select(null);
-  }
-
-  /**
-   * @override
-   * @param {?SDK.TracingModel.Event} event
-   */
-  highlightEvent(event) {
-    this._flameChart.highlightEvent(event);
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  _revealTimeRange(startTime, endTime) {
-    const selectionData = this._currentModelSelectionData();
-    if (!selectionData)
-      return;
-    let timeShift = 0;
-    if (selectionData.windowEndTime < endTime)
-      timeShift = endTime - selectionData.windowEndTime;
-    else if (selectionData.windowStartTime > startTime)
-      timeShift = startTime - selectionData.windowStartTime;
-    if (timeShift)
-      this.requestWindowTimes(selectionData.windowStartTime + timeShift, selectionData.windowEndTime + timeShift);
-  }
-
-  /**
-   * @param {!DataTransfer} dataTransfer
-   */
-  _handleDrop(dataTransfer) {
-    const items = dataTransfer.items;
-    if (!items.length)
-      return;
-    const item = items[0];
-    if (item.kind === 'string') {
-      const url = dataTransfer.getData('text/uri-list');
-      if (new Common.ParsedURL(url).isValid)
-        this._loadFromURL(url);
-    } else if (item.kind === 'file') {
-      const entry = items[0].webkitGetAsEntry();
-      if (!entry.isFile)
-        return;
-      entry.file(this._loadFromFile.bind(this));
-    }
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel} timelineModel
-   * @return {!{start: number, end: number}}
-   */
-  static _autoWindowTimes(timelineModel) {
-    let tasks = [];
-    for (const track of timelineModel.tracks()) {
-      // Deliberately pick up last main frame's track.
-      if (track.type === TimelineModel.TimelineModel.TrackType.MainThread && track.forMainFrame)
-        tasks = track.tasks;
-    }
-    if (!tasks.length)
-      return {start: timelineModel.minimumRecordTime(), end: timelineModel.maximumRecordTime()};
-
-    /**
-     * @param {number} startIndex
-     * @param {number} stopIndex
-     * @return {number}
-     */
-    function findLowUtilizationRegion(startIndex, stopIndex) {
-      const /** @const */ threshold = 0.1;
-      let cutIndex = startIndex;
-      let cutTime = (tasks[cutIndex].startTime + tasks[cutIndex].endTime) / 2;
-      let usedTime = 0;
-      const step = Math.sign(stopIndex - startIndex);
-      for (let i = startIndex; i !== stopIndex; i += step) {
-        const task = tasks[i];
-        const taskTime = (task.startTime + task.endTime) / 2;
-        const interval = Math.abs(cutTime - taskTime);
-        if (usedTime < threshold * interval) {
-          cutIndex = i;
-          cutTime = taskTime;
-          usedTime = 0;
-        }
-        usedTime += task.duration;
-      }
-      return cutIndex;
-    }
-    const rightIndex = findLowUtilizationRegion(tasks.length - 1, 0);
-    const leftIndex = findLowUtilizationRegion(0, rightIndex);
-    let leftTime = tasks[leftIndex].startTime;
-    let rightTime = tasks[rightIndex].endTime;
-    const span = rightTime - leftTime;
-    const totalSpan = timelineModel.maximumRecordTime() - timelineModel.minimumRecordTime();
-    if (span < totalSpan * 0.1) {
-      leftTime = timelineModel.minimumRecordTime();
-      rightTime = timelineModel.maximumRecordTime();
-    } else {
-      leftTime = Math.max(leftTime - 0.05 * span, timelineModel.minimumRecordTime());
-      rightTime = Math.min(rightTime + 0.05 * span, timelineModel.maximumRecordTime());
-    }
-    return {start: leftTime, end: rightTime};
-  }
-
-  /**
-   * @return {?Timeline.TimelineSelection}
-   */
-  _selection() {
-    const selectionData = this._currentModelSelectionData();
-    return selectionData && selectionData.selection;
-  }
-
-  /**
-   * return {?Timeline.TimelinePanel.ModelSelectionData}
-   */
-  _currentModelSelectionData() {
-    return this._performanceModel && this._performanceModel[Timeline.TimelinePanel._modelSelectionDataSymbol];
-  }
-};
-
-/**
- * @enum {symbol}
- */
-Timeline.TimelinePanel.State = {
-  Idle: Symbol('Idle'),
-  StartPending: Symbol('StartPending'),
-  Recording: Symbol('Recording'),
-  StopPending: Symbol('StopPending'),
-  Loading: Symbol('Loading')
-};
-
-/**
- * @enum {string}
- */
-Timeline.TimelinePanel.ViewMode = {
-  FlameChart: 'FlameChart',
-  BottomUp: 'BottomUp',
-  CallTree: 'CallTree',
-  EventLog: 'EventLog'
-};
-
-// Define row and header height, should be in sync with styles for timeline graphs.
-Timeline.TimelinePanel.rowHeight = 18;
-Timeline.TimelinePanel.headerHeight = 20;
-
-Timeline.TimelinePanel._modelSelectionDataSymbol = Symbol('modelSelectionData');
-
-/** @typedef {{selection: ?Timeline.TimelineSelection, windowLeftTime: number, windowRightTime: number}} */
-Timeline.TimelinePanel.ModelSelectionData;
-
-Timeline.TimelineSelection = class {
-  /**
-   * @param {!Timeline.TimelineSelection.Type} type
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {!Object=} object
-   */
-  constructor(type, startTime, endTime, object) {
-    this._type = type;
-    this._startTime = startTime;
-    this._endTime = endTime;
-    this._object = object || null;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineFrame} frame
-   * @return {!Timeline.TimelineSelection}
-   */
-  static fromFrame(frame) {
-    return new Timeline.TimelineSelection(Timeline.TimelineSelection.Type.Frame, frame.startTime, frame.endTime, frame);
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel.NetworkRequest} request
-   * @return {!Timeline.TimelineSelection}
-   */
-  static fromNetworkRequest(request) {
-    return new Timeline.TimelineSelection(
-        Timeline.TimelineSelection.Type.NetworkRequest, request.startTime, request.endTime || request.startTime,
-        request);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {!Timeline.TimelineSelection}
-   */
-  static fromTraceEvent(event) {
-    return new Timeline.TimelineSelection(
-        Timeline.TimelineSelection.Type.TraceEvent, event.startTime, event.endTime || (event.startTime + 1), event);
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @return {!Timeline.TimelineSelection}
-   */
-  static fromRange(startTime, endTime) {
-    return new Timeline.TimelineSelection(Timeline.TimelineSelection.Type.Range, startTime, endTime);
-  }
-
-  /**
-   * @return {!Timeline.TimelineSelection.Type}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {?Object}
-   */
-  object() {
-    return this._object;
-  }
-
-  /**
-   * @return {number}
-   */
-  startTime() {
-    return this._startTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  endTime() {
-    return this._endTime;
-  }
-};
-
-/**
- * @enum {string}
- */
-Timeline.TimelineSelection.Type = {
-  Frame: 'Frame',
-  NetworkRequest: 'NetworkRequest',
-  TraceEvent: 'TraceEvent',
-  Range: 'Range'
-};
-
-
-/**
- * @interface
- * @extends {Common.EventTarget}
- */
-Timeline.TimelineModeView = function() {};
-
-Timeline.TimelineModeView.prototype = {
-  /**
-   * @return {!UI.Widget}
-   */
-  view() {},
-
-  /**
-   * @return {?Element}
-   */
-  resizerElement() {},
-
-  /**
-   * @param {?Timeline.PerformanceModel} model
-   * @param {?TimelineModel.TimelineModel.Track} track
-   */
-  setModel(model, track) {},
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  setWindowTimes(startTime, endTime) {},
-
-  /**
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  setSelection(selection) {},
-
-  /**
-   * @param {?SDK.TracingModel.Event} event
-   */
-  highlightEvent(event) {}
-};
-
-/**
- * @interface
- */
-Timeline.TimelineModeViewDelegate = function() {};
-
-Timeline.TimelineModeViewDelegate.prototype = {
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  requestWindowTimes(startTime, endTime) {},
-
-  /**
-   * @param {?Timeline.TimelineSelection} selection
-   */
-  select(selection) {},
-
-  /**
-   * @param {?Array<!SDK.TracingModel.Event>} events
-   * @param {number} time
-   */
-  selectEntryAtTime(events, time) {},
-
-  /**
-   * @param {?SDK.TracingModel.Event} event
-   */
-  highlightEvent(event) {},
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelinePanel.StatusPane = class extends UI.VBox {
-  /**
-   * @param {boolean} showTimer
-   * @param {function()} stopCallback
-   */
-  constructor(showTimer, stopCallback) {
-    super(true);
-    this.registerRequiredCSS('timeline/timelineStatusDialog.css');
-    this.contentElement.classList.add('timeline-status-dialog');
-
-    const statusLine = this.contentElement.createChild('div', 'status-dialog-line status');
-    statusLine.createChild('div', 'label').textContent = Common.UIString('Status');
-    this._status = statusLine.createChild('div', 'content');
-
-    if (showTimer) {
-      const timeLine = this.contentElement.createChild('div', 'status-dialog-line time');
-      timeLine.createChild('div', 'label').textContent = Common.UIString('Time');
-      this._time = timeLine.createChild('div', 'content');
-    }
-    const progressLine = this.contentElement.createChild('div', 'status-dialog-line progress');
-    this._progressLabel = progressLine.createChild('div', 'label');
-    this._progressBar = progressLine.createChild('div', 'indicator-container').createChild('div', 'indicator');
-
-    this._stopButton = UI.createTextButton(Common.UIString('Stop'), stopCallback, '', true);
-    this.contentElement.createChild('div', 'stop-button').appendChild(this._stopButton);
-  }
-
-  finish() {
-    this._stopTimer();
-    this._stopButton.disabled = true;
-  }
-
-  hide() {
-    this.element.parentNode.classList.remove('tinted');
-    this.element.remove();
-  }
-
-  /**
-   * @param {!Element} parent
-   */
-  showPane(parent) {
-    this.show(parent);
-    parent.classList.add('tinted');
-    this._stopButton.focus();
-  }
-
-  /**
-   * @param {string} text
-   */
-  updateStatus(text) {
-    this._status.textContent = text;
-  }
-
-  /**
-   * @param {string} activity
-   * @param {number} percent
-   */
-  updateProgressBar(activity, percent) {
-    this._progressLabel.textContent = activity;
-    this._progressBar.style.width = percent.toFixed(1) + '%';
-    this._updateTimer();
-  }
-
-  startTimer() {
-    this._startTime = Date.now();
-    this._timeUpdateTimer = setInterval(this._updateTimer.bind(this, false), 1000);
-    this._updateTimer();
-  }
-
-  _stopTimer() {
-    if (!this._timeUpdateTimer)
-      return;
-    clearInterval(this._timeUpdateTimer);
-    this._updateTimer(true);
-    delete this._timeUpdateTimer;
-  }
-
-  /**
-   * @param {boolean=} precise
-   */
-  _updateTimer(precise) {
-    if (!this._timeUpdateTimer)
-      return;
-    const elapsed = (Date.now() - this._startTime) / 1000;
-    this._time.textContent = Common.UIString('%s\xa0sec', elapsed.toFixed(precise ? 1 : 0));
-  }
-};
-
-
-/**
- * @implements {Common.QueryParamHandler}
- * @unrestricted
- */
-Timeline.LoadTimelineHandler = class {
-  /**
-   * @override
-   * @param {string} value
-   */
-  handleQueryParam(value) {
-    UI.viewManager.showView('timeline').then(() => {
-      Timeline.TimelinePanel.instance()._loadFromURL(window.decodeURIComponent(value));
-    });
-  }
-};
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-Timeline.TimelinePanel.ActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    const panel = UI.context.flavor(Timeline.TimelinePanel);
-    console.assert(panel && panel instanceof Timeline.TimelinePanel);
-    switch (actionId) {
-      case 'timeline.toggle-recording':
-        panel._toggleRecording();
-        return true;
-      case 'timeline.record-reload':
-        panel._recordReload();
-        return true;
-      case 'timeline.save-to-file':
-        panel._saveToFile();
-        return true;
-      case 'timeline.load-from-file':
-        panel._selectFileToLoad();
-        return true;
-      case 'timeline.jump-to-previous-frame':
-        panel._jumpToFrame(-1);
-        return true;
-      case 'timeline.jump-to-next-frame':
-        panel._jumpToFrame(1);
-        return true;
-      case 'timeline.show-history':
-        panel._showHistory();
-        return true;
-      case 'timeline.previous-recording':
-        panel._navigateHistory(1);
-        return true;
-      case 'timeline.next-recording':
-        panel._navigateHistory(-1);
-        return true;
-    }
-    return false;
-  }
-};
-
-Timeline.TimelinePanel._traceProviderSettingSymbol = Symbol('traceProviderSetting');
diff --git a/front_end/timeline/TimelineTreeView.js b/front_end/timeline/TimelineTreeView.js
deleted file mode 100644
index e7696bc..0000000
--- a/front_end/timeline/TimelineTreeView.js
+++ /dev/null
@@ -1,1040 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @unrestricted
- * @implements {UI.Searchable}
- */
-Timeline.TimelineTreeView = class extends UI.VBox {
-  constructor() {
-    super();
-    /** @type {?Timeline.PerformanceModel} */
-    this._model = null;
-    /** @type {?TimelineModel.TimelineModel.Track} */
-    this._track = null;
-    /** @type {?TimelineModel.TimelineProfileTree.Node} */
-    this._tree = null;
-    this.element.classList.add('timeline-tree-view');
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  static eventNameForSorting(event) {
-    if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame) {
-      const data = event.args['data'];
-      return data['functionName'] + '@' + (data['scriptId'] || data['url'] || '');
-    }
-    return event.name + ':@' + TimelineModel.TimelineProfileTree.eventURL(event);
-  }
-
-  /**
-   * @param {!UI.SearchableView} searchableView
-   */
-  setSearchableView(searchableView) {
-    this._searchableView = searchableView;
-  }
-
-  /**
-   * @param {?Timeline.PerformanceModel} model
-   * @param {?TimelineModel.TimelineModel.Track} track
-   */
-  setModel(model, track) {
-    this._model = model;
-    this._track = track;
-    this.refreshTree();
-  }
-
-  /**
-   * @protected
-   * @return {?Timeline.PerformanceModel} model
-   */
-  model() {
-    return this._model;
-  }
-
-  /**
-   * @protected
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   */
-  init(filters) {
-    this._linkifier = new Components.Linkifier();
-
-    this._textFilter = new Timeline.TimelineFilters.RegExp();
-    this._filters = [...filters, this._textFilter];
-
-    this._currentThreadSetting = Common.settings.createSetting('timelineTreeCurrentThread', 0);
-    this._currentThreadSetting.addChangeListener(this.refreshTree, this);
-
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([]);
-    this.populateColumns(columns);
-
-    this._splitWidget = new UI.SplitWidget(true, true, 'timelineTreeViewDetailsSplitWidget');
-    const mainView = new UI.VBox();
-    const toolbar = new UI.Toolbar('', mainView.element);
-    this.populateToolbar(toolbar);
-
-    this._dataGrid = new DataGrid.SortableDataGrid(columns);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortingChanged, this);
-    this._dataGrid.element.addEventListener('mousemove', this._onMouseMove.bind(this), true);
-    this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
-    this._dataGrid.setRowContextMenuCallback(this._onContextMenu.bind(this));
-    this._dataGrid.asWidget().show(mainView.element);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._updateDetailsForSelection, this);
-
-    this._detailsView = new UI.VBox();
-    this._detailsView.element.classList.add('timeline-details-view', 'timeline-details-view-body');
-    this._splitWidget.setMainWidget(mainView);
-    this._splitWidget.setSidebarWidget(this._detailsView);
-    this._splitWidget.hideSidebar();
-    this._splitWidget.show(this.element);
-    this._splitWidget.addEventListener(UI.SplitWidget.Events.ShowModeChanged, this._onShowModeChanged, this);
-
-    /** @type {?TimelineModel.TimelineProfileTree.Node|undefined} */
-    this._lastSelectedNode;
-  }
-
-  /**
-   * @protected
-   * @return {?TimelineModel.TimelineProfileTree.Node|undefined}
-   */
-  lastSelectedNode() {
-    return this._lastSelectedNode;
-  }
-
-  /**
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  updateContents(selection) {
-    this.setRange(selection.startTime(), selection.endTime());
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  setRange(startTime, endTime) {
-    this._startTime = startTime;
-    this._endTime = endTime;
-    this.refreshTree();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _exposePercentages() {
-    return false;
-  }
-
-  /**
-   * @protected
-   * @param {!UI.Toolbar} toolbar
-   */
-  populateToolbar(toolbar) {
-    this._textFilterUI = new UI.ToolbarInput(Common.UIString('Filter'));
-    this._textFilterUI.addEventListener(UI.ToolbarInput.Event.TextChanged, textFilterChanged, this);
-    toolbar.appendToolbarItem(this._textFilterUI);
-
-    /**
-     * @this {Timeline.TimelineTreeView}
-     */
-    function textFilterChanged() {
-      const searchQuery = this._textFilterUI.value();
-      this._textFilter.setRegExp(searchQuery ? createPlainTextSearchRegex(searchQuery, 'i') : null);
-      this.refreshTree();
-    }
-  }
-
-  /**
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  _modelEvents() {
-    return this._track ? this._track.syncEvents() : [];
-  }
-
-  /**
-   * @param {?TimelineModel.TimelineProfileTree.Node} node
-   */
-  _onHover(node) {
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!TimelineModel.TimelineProfileTree.Node} node
-   */
-  _appendContextMenuItems(contextMenu, node) {
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?Element}
-   */
-  _linkifyLocation(event) {
-    const target = this._model.timelineModel().targetByEvent(event);
-    if (!target)
-      return null;
-    const frame = TimelineModel.TimelineProfileTree.eventStackFrame(event);
-    if (!frame)
-      return null;
-    return this._linkifier.maybeLinkifyConsoleCallFrame(target, frame);
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} treeNode
-   * @param {boolean} suppressSelectedEvent
-   */
-  selectProfileNode(treeNode, suppressSelectedEvent) {
-    const pathToRoot = [];
-    for (let node = treeNode; node; node = node.parent)
-      pathToRoot.push(node);
-    for (let i = pathToRoot.length - 1; i > 0; --i) {
-      const gridNode = this.dataGridNodeForTreeNode(pathToRoot[i]);
-      if (gridNode && gridNode.dataGrid)
-        gridNode.expand();
-    }
-    const gridNode = this.dataGridNodeForTreeNode(treeNode);
-    if (gridNode.dataGrid) {
-      gridNode.reveal();
-      gridNode.select(suppressSelectedEvent);
-    }
-  }
-
-  /**
-   * @protected
-   */
-  refreshTree() {
-    this._linkifier.reset();
-    this._dataGrid.rootNode().removeChildren();
-    if (!this._model) {
-      this._updateDetailsForSelection();
-      return;
-    }
-    this._root = this._buildTree();
-    const children = this._root.children();
-    let maxSelfTime = 0;
-    let maxTotalTime = 0;
-    const totalUsedTime = this._root.totalTime - this._root.selfTime;
-    for (const child of children.values()) {
-      maxSelfTime = Math.max(maxSelfTime, child.selfTime);
-      maxTotalTime = Math.max(maxTotalTime, child.totalTime);
-    }
-    for (const child of children.values()) {
-      // Exclude the idle time off the total calculation.
-      const gridNode =
-          new Timeline.TimelineTreeView.TreeGridNode(child, totalUsedTime, maxSelfTime, maxTotalTime, this);
-      this._dataGrid.insertChild(gridNode);
-    }
-    this._sortingChanged();
-    this._updateDetailsForSelection();
-    if (this._searchableView)
-      this._searchableView.refreshSearch();
-  }
-
-  /**
-   * @return {!TimelineModel.TimelineProfileTree.Node}
-   */
-  _buildTree() {
-    throw new Error('Not Implemented');
-  }
-
-  /**
-   * @protected
-   * @param {boolean} doNotAggregate
-   * @param {?function(!SDK.TracingModel.Event):string} groupIdCallback
-   * @return {!TimelineModel.TimelineProfileTree.Node}
-   */
-  buildTopDownTree(doNotAggregate, groupIdCallback) {
-    return new TimelineModel.TimelineProfileTree.TopDownRootNode(
-        this._modelEvents(), this._filters, this._startTime, this._endTime, doNotAggregate, groupIdCallback);
-  }
-
-  /**
-   * @protected
-   * @param {!Array<!DataGrid.DataGrid.ColumnDescriptor>} columns
-   */
-  populateColumns(columns) {
-    columns.push({id: 'self', title: Common.UIString('Self Time'), width: '120px', fixedWidth: true, sortable: true});
-    columns.push({id: 'total', title: Common.UIString('Total Time'), width: '120px', fixedWidth: true, sortable: true});
-    columns.push({id: 'activity', title: Common.UIString('Activity'), disclosure: true, sortable: true});
-  }
-
-  _sortingChanged() {
-    const columnId = this._dataGrid.sortColumnId();
-    if (!columnId)
-      return;
-    let sortFunction;
-    switch (columnId) {
-      case 'startTime':
-        sortFunction = compareStartTime;
-        break;
-      case 'self':
-        sortFunction = compareNumericField.bind(null, 'selfTime');
-        break;
-      case 'total':
-        sortFunction = compareNumericField.bind(null, 'totalTime');
-        break;
-      case 'activity':
-        sortFunction = compareName;
-        break;
-      default:
-        console.assert(false, 'Unknown sort field: ' + columnId);
-        return;
-    }
-    this._dataGrid.sortNodes(sortFunction, !this._dataGrid.isSortOrderAscending());
-
-    /**
-     * @param {string} field
-     * @param {!DataGrid.DataGridNode} a
-     * @param {!DataGrid.DataGridNode} b
-     * @return {number}
-     */
-    function compareNumericField(field, a, b) {
-      const nodeA = /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (a);
-      const nodeB = /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (b);
-      return nodeA._profileNode[field] - nodeB._profileNode[field];
-    }
-
-    /**
-     * @param {!DataGrid.DataGridNode} a
-     * @param {!DataGrid.DataGridNode} b
-     * @return {number}
-     */
-    function compareStartTime(a, b) {
-      const nodeA = /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (a);
-      const nodeB = /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (b);
-      return nodeA._profileNode.event.startTime - nodeB._profileNode.event.startTime;
-    }
-
-    /**
-     * @param {!DataGrid.DataGridNode} a
-     * @param {!DataGrid.DataGridNode} b
-     * @return {number}
-     */
-    function compareName(a, b) {
-      const nodeA = /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (a);
-      const nodeB = /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (b);
-      const nameA = Timeline.TimelineTreeView.eventNameForSorting(nodeA._profileNode.event);
-      const nameB = Timeline.TimelineTreeView.eventNameForSorting(nodeB._profileNode.event);
-      return nameA.localeCompare(nameB);
-    }
-  }
-
-  _onShowModeChanged() {
-    if (this._splitWidget.showMode() === UI.SplitWidget.ShowMode.OnlyMain)
-      return;
-    this._lastSelectedNode = undefined;
-    this._updateDetailsForSelection();
-  }
-
-  _updateDetailsForSelection() {
-    const selectedNode = this._dataGrid.selectedNode ?
-        /** @type {!Timeline.TimelineTreeView.TreeGridNode} */ (this._dataGrid.selectedNode)._profileNode :
-        null;
-    if (selectedNode === this._lastSelectedNode)
-      return;
-    this._lastSelectedNode = selectedNode;
-    if (this._splitWidget.showMode() === UI.SplitWidget.ShowMode.OnlyMain)
-      return;
-    this._detailsView.detachChildWidgets();
-    this._detailsView.element.removeChildren();
-    if (selectedNode && this._showDetailsForNode(selectedNode))
-      return;
-    const banner = this._detailsView.element.createChild('div', 'full-widget-dimmed-banner');
-    banner.createTextChild(Common.UIString('Select item for details.'));
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} node
-   * @return {boolean}
-   */
-  _showDetailsForNode(node) {
-    return false;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseMove(event) {
-    const gridNode = event.target && (event.target instanceof Node) ?
-        /** @type {?Timeline.TimelineTreeView.TreeGridNode} */ (
-            this._dataGrid.dataGridNodeFromNode(/** @type {!Node} */ (event.target))) :
-        null;
-    const profileNode = gridNode && gridNode._profileNode;
-    if (profileNode === this._lastHoveredProfileNode)
-      return;
-    this._lastHoveredProfileNode = profileNode;
-    this._onHover(profileNode);
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!DataGrid.DataGridNode} gridNode
-   */
-  _onContextMenu(contextMenu, gridNode) {
-    const profileNode = gridNode._profileNode;
-    if (!profileNode)
-      return;
-    this._appendContextMenuItems(contextMenu, profileNode);
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} treeNode
-   * @protected
-   * @return {?Timeline.TimelineTreeView.GridNode}
-   */
-  dataGridNodeForTreeNode(treeNode) {
-    return treeNode[Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol] || null;
-  }
-
-  // UI.Searchable implementation
-
-  /**
-   * @override
-   */
-  searchCanceled() {
-    this._searchResults = [];
-    this._currentResult = 0;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this._searchResults = [];
-    this._currentResult = 0;
-    if (!this._root)
-      return;
-    const searchRegex = searchConfig.toSearchRegex();
-    this._searchResults =
-        this._root.searchTree(event => Timeline.TimelineUIUtils.testContentMatching(event, searchRegex));
-    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-  }
-
-  /**
-   * @override
-   */
-  jumpToNextSearchResult() {
-    if (!this._searchResults.length)
-      return;
-    this.selectProfileNode(this._searchResults[this._currentResult], false);
-    this._currentResult = mod(this._currentResult + 1, this._searchResults.length);
-  }
-
-  /**
-   * @override
-   */
-  jumpToPreviousSearchResult() {
-    if (!this._searchResults.length)
-      return;
-    this.selectProfileNode(this._searchResults[this._currentResult], false);
-    this._currentResult = mod(this._currentResult - 1, this._searchResults.length);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  supportsRegexSearch() {
-    return true;
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineTreeView.GridNode = class extends DataGrid.SortableDataGridNode {
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} profileNode
-   * @param {number} grandTotalTime
-   * @param {number} maxSelfTime
-   * @param {number} maxTotalTime
-   * @param {!Timeline.TimelineTreeView} treeView
-   */
-  constructor(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView) {
-    super(null, false);
-    this._populated = false;
-    this._profileNode = profileNode;
-    this._treeView = treeView;
-    this._grandTotalTime = grandTotalTime;
-    this._maxSelfTime = maxSelfTime;
-    this._maxTotalTime = maxTotalTime;
-  }
-
-  /**
-   * @override
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  createCell(columnId) {
-    if (columnId === 'activity')
-      return this._createNameCell(columnId);
-    return this._createValueCell(columnId) || super.createCell(columnId);
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {!Element}
-   */
-  _createNameCell(columnId) {
-    const cell = this.createTD(columnId);
-    const container = cell.createChild('div', 'name-container');
-    const iconContainer = container.createChild('div', 'activity-icon-container');
-    const icon = iconContainer.createChild('div', 'activity-icon');
-    const name = container.createChild('div', 'activity-name');
-    const event = this._profileNode.event;
-    if (this._profileNode.isGroupNode()) {
-      const treeView = /** @type {!Timeline.AggregatedTimelineTreeView} */ (this._treeView);
-      const info = treeView._displayInfoForGroupNode(this._profileNode);
-      name.textContent = info.name;
-      icon.style.backgroundColor = info.color;
-      if (info.icon)
-        iconContainer.insertBefore(info.icon, icon);
-    } else if (event) {
-      const data = event.args['data'];
-      const deoptReason = data && data['deoptReason'];
-      if (deoptReason)
-        container.createChild('div', 'activity-warning').title = Common.UIString('Not optimized: %s', deoptReason);
-
-      name.textContent = Timeline.TimelineUIUtils.eventTitle(event);
-      const link = this._treeView._linkifyLocation(event);
-      if (link)
-        container.createChild('div', 'activity-link').appendChild(link);
-      icon.style.backgroundColor = Timeline.TimelineUIUtils.eventColor(event);
-    }
-    return cell;
-  }
-
-  /**
-   * @param {string} columnId
-   * @return {?Element}
-   */
-  _createValueCell(columnId) {
-    if (columnId !== 'self' && columnId !== 'total' && columnId !== 'startTime')
-      return null;
-
-    let showPercents = false;
-    let value;
-    let maxTime;
-    switch (columnId) {
-      case 'startTime':
-        value = this._profileNode.event.startTime - this._treeView._model.timelineModel().minimumRecordTime();
-        break;
-      case 'self':
-        value = this._profileNode.selfTime;
-        maxTime = this._maxSelfTime;
-        showPercents = true;
-        break;
-      case 'total':
-        value = this._profileNode.totalTime;
-        maxTime = this._maxTotalTime;
-        showPercents = true;
-        break;
-      default:
-        return null;
-    }
-    const cell = this.createTD(columnId);
-    cell.className = 'numeric-column';
-    const textDiv = cell.createChild('div');
-    textDiv.createChild('span').textContent = Common.UIString('%.1f\xa0ms', value);
-
-    if (showPercents && this._treeView._exposePercentages()) {
-      textDiv.createChild('span', 'percent-column').textContent =
-          Common.UIString('%.1f\xa0%%', value / this._grandTotalTime * 100);
-    }
-    if (maxTime) {
-      textDiv.classList.add('background-percent-bar');
-      cell.createChild('div', 'background-bar-container').createChild('div', 'background-bar').style.width =
-          (value * 100 / maxTime).toFixed(1) + '%';
-    }
-    return cell;
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineTreeView.TreeGridNode = class extends Timeline.TimelineTreeView.GridNode {
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} profileNode
-   * @param {number} grandTotalTime
-   * @param {number} maxSelfTime
-   * @param {number} maxTotalTime
-   * @param {!Timeline.TimelineTreeView} treeView
-   */
-  constructor(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView) {
-    super(profileNode, grandTotalTime, maxSelfTime, maxTotalTime, treeView);
-    this.setHasChildren(this._profileNode.hasChildren());
-    profileNode[Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol] = this;
-  }
-
-  /**
-   * @override
-   */
-  populate() {
-    if (this._populated)
-      return;
-    this._populated = true;
-    if (!this._profileNode.children)
-      return;
-    for (const node of this._profileNode.children().values()) {
-      const gridNode = new Timeline.TimelineTreeView.TreeGridNode(
-          node, this._grandTotalTime, this._maxSelfTime, this._maxTotalTime, this._treeView);
-      this.insertChildOrdered(gridNode);
-    }
-  }
-};
-
-Timeline.TimelineTreeView.TreeGridNode._gridNodeSymbol = Symbol('treeGridNode');
-
-/**
- * @unrestricted
- */
-Timeline.AggregatedTimelineTreeView = class extends Timeline.TimelineTreeView {
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   */
-  constructor(filters) {
-    super();
-    this._groupBySetting =
-        Common.settings.createSetting('timelineTreeGroupBy', Timeline.AggregatedTimelineTreeView.GroupBy.None);
-    this._groupBySetting.addChangeListener(this.refreshTree.bind(this));
-    this.init(filters);
-    this._stackView = new Timeline.TimelineStackView(this);
-    this._stackView.addEventListener(
-        Timeline.TimelineStackView.Events.SelectionChanged, this._onStackViewSelectionChanged, this);
-    this._badgePool = new ProductRegistry.BadgePool(true);
-    /** @type {!Map<string, string>} */
-    this._productByURLCache = new Map();
-    /** @type {!Map<string, string>} */
-    this._colorByURLCache = new Map();
-    ProductRegistry.instance().then(registry => {
-      this._productRegistry = registry;
-      this.refreshTree();
-    });
-  }
-
-  /**
-   * @override
-   * @param {?Timeline.PerformanceModel} model
-   * @param {?TimelineModel.TimelineModel.Track} track
-   */
-  setModel(model, track) {
-    this._badgePool.reset();
-    super.setModel(model, track);
-  }
-
-  /**
-   * @override
-   * @param {!Timeline.TimelineSelection} selection
-   */
-  updateContents(selection) {
-    this._updateExtensionResolver();
-    super.updateContents(selection);
-    const rootNode = this._dataGrid.rootNode();
-    if (rootNode.children.length)
-      rootNode.children[0].revealAndSelect();
-  }
-
-  _updateExtensionResolver() {
-    this._executionContextNamesByOrigin = new Map();
-    for (const runtimeModel of SDK.targetManager.models(SDK.RuntimeModel)) {
-      for (const context of runtimeModel.executionContexts())
-        this._executionContextNamesByOrigin.set(context.origin, context.name);
-    }
-  }
-
-  /**
-   * @param {string} name
-   * @return {string}
-   * @this {Timeline.AggregatedTimelineTreeView}
-   */
-  _beautifyDomainName(name) {
-    if (Timeline.AggregatedTimelineTreeView._isExtensionInternalURL(name))
-      name = Common.UIString('[Chrome extensions overhead]');
-    else if (Timeline.AggregatedTimelineTreeView._isV8NativeURL(name))
-      name = Common.UIString('[V8 Runtime]');
-    else if (name.startsWith('chrome-extension'))
-      name = this._executionContextNamesByOrigin.get(name) || name;
-    return name;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} node
-   * @return {!{name: string, color: string, icon: (!Element|undefined)}}
-   */
-  _displayInfoForGroupNode(node) {
-    const categories = Timeline.TimelineUIUtils.categories();
-    let color = node.id ? Timeline.TimelineUIUtils.eventColor(/** @type {!SDK.TracingModel.Event} */ (node.event)) :
-                          categories['other'].color;
-    const unattributed = Common.UIString('[unattributed]');
-
-    switch (this._groupBySetting.get()) {
-      case Timeline.AggregatedTimelineTreeView.GroupBy.Category: {
-        const category = categories[node.id] || categories['other'];
-        return {name: category.title, color: category.color};
-      }
-
-      case Timeline.AggregatedTimelineTreeView.GroupBy.Domain:
-      case Timeline.AggregatedTimelineTreeView.GroupBy.Subdomain: {
-        let domainName = this._beautifyDomainName(node.id);
-        if (domainName) {
-          const productName = this._productByEvent(/** @type {!SDK.TracingModel.Event} */ (node.event));
-          if (productName)
-            domainName += ' \u2014 ' + productName;
-        }
-        return {name: domainName || unattributed, color: color};
-      }
-
-      case Timeline.AggregatedTimelineTreeView.GroupBy.EventName: {
-        const name = node.event.name === TimelineModel.TimelineModel.RecordType.JSFrame ?
-            Common.UIString('JavaScript') :
-            Timeline.TimelineUIUtils.eventTitle(node.event);
-        return {
-          name: name,
-          color: node.event.name === TimelineModel.TimelineModel.RecordType.JSFrame ?
-              Timeline.TimelineUIUtils.eventStyle(node.event).category.color :
-              color
-        };
-      }
-      case Timeline.AggregatedTimelineTreeView.GroupBy.Product: {
-        const event = /** @type {!SDK.TracingModel.Event} */ (node.event);
-        const info = this._productAndBadgeByEvent(event);
-        const name = info && info.name || unattributed;
-        color = Timeline.TimelineUIUtils.eventColorByProduct(
-            this._productRegistry, this._model.timelineModel(), this._colorByURLCache, event);
-        return {name: name, color: color, icon: info && info.badge || undefined};
-      }
-
-      case Timeline.AggregatedTimelineTreeView.GroupBy.URL:
-        break;
-
-      case Timeline.AggregatedTimelineTreeView.GroupBy.Frame: {
-        const frame = this._model.timelineModel().pageFrameById(node.id);
-        const frameName = frame ? Timeline.TimelineUIUtils.displayNameForFrame(frame, 80) : Common.UIString('Page');
-        return {name: frameName, color: color};
-      }
-
-      default:
-        console.assert(false, 'Unexpected grouping type');
-    }
-    return {name: node.id || unattributed, color: color};
-  }
-
-  /**
-   * @override
-   * @param {!UI.Toolbar} toolbar
-   */
-  populateToolbar(toolbar) {
-    super.populateToolbar(toolbar);
-    const groupBy = Timeline.AggregatedTimelineTreeView.GroupBy;
-    const options = [
-      {label: Common.UIString('No Grouping'), value: groupBy.None},
-      {label: Common.UIString('Group by Activity'), value: groupBy.EventName},
-      {label: Common.UIString('Group by Category'), value: groupBy.Category},
-      {label: Common.UIString('Group by Domain'), value: groupBy.Domain},
-      {label: Common.UIString('Group by Frame'), value: groupBy.Frame},
-      {label: Common.UIString('Group by Product'), value: groupBy.Product},
-      {label: Common.UIString('Group by Subdomain'), value: groupBy.Subdomain},
-      {label: Common.UIString('Group by URL'), value: groupBy.URL},
-    ];
-    toolbar.appendToolbarItem(new UI.ToolbarSettingComboBox(options, this._groupBySetting));
-    toolbar.appendSpacer();
-    toolbar.appendToolbarItem(this._splitWidget.createShowHideSidebarButton(Common.UIString('heaviest stack')));
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.Node} treeNode
-   * @return {!Array<!TimelineModel.TimelineProfileTree.Node>}
-   */
-  _buildHeaviestStack(treeNode) {
-    console.assert(!!treeNode.parent, 'Attempt to build stack for tree root');
-    let result = [];
-    // Do not add root to the stack, as it's the tree itself.
-    for (let node = treeNode; node && node.parent; node = node.parent)
-      result.push(node);
-    result = result.reverse();
-    for (let node = treeNode; node && node.children() && node.children().size;) {
-      const children = Array.from(node.children().values());
-      node = children.reduce((a, b) => a.totalTime > b.totalTime ? a : b);
-      result.push(node);
-    }
-    return result;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  _exposePercentages() {
-    return true;
-  }
-
-  _onStackViewSelectionChanged() {
-    const treeNode = this._stackView.selectedTreeNode();
-    if (treeNode)
-      this.selectProfileNode(treeNode, true);
-  }
-
-  /**
-   * @override
-   * @param {!TimelineModel.TimelineProfileTree.Node} node
-   * @return {boolean}
-   */
-  _showDetailsForNode(node) {
-    const stack = this._buildHeaviestStack(node);
-    this._stackView.setStack(stack, node);
-    this._stackView.show(this._detailsView.element);
-    return true;
-  }
-
-  /**
-   * @param {!Timeline.AggregatedTimelineTreeView.GroupBy} groupBy
-   * @return {?function(!SDK.TracingModel.Event):string}
-   */
-  _groupingFunction(groupBy) {
-    const GroupBy = Timeline.AggregatedTimelineTreeView.GroupBy;
-    switch (groupBy) {
-      case GroupBy.None:
-        return null;
-      case GroupBy.EventName:
-        return event => Timeline.TimelineUIUtils.eventStyle(event).title;
-      case GroupBy.Category:
-        return event => Timeline.TimelineUIUtils.eventStyle(event).category.name;
-      case GroupBy.Subdomain:
-        return this._domainByEvent.bind(this, false);
-      case GroupBy.Domain:
-        return this._domainByEvent.bind(this, true);
-      case GroupBy.Product:
-        return event => this._productByEvent(event) || this._domainByEvent(true, event) || '';
-      case GroupBy.URL:
-        return event => TimelineModel.TimelineProfileTree.eventURL(event) || '';
-      case GroupBy.Frame:
-        return event => TimelineModel.TimelineData.forEvent(event).frameId;
-      default:
-        console.assert(false, `Unexpected aggregation setting: ${groupBy}`);
-        return null;
-    }
-  }
-
-  /**
-   * @param {boolean} groupSubdomains
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  _domainByEvent(groupSubdomains, event) {
-    const url = TimelineModel.TimelineProfileTree.eventURL(event);
-    if (!url)
-      return '';
-    if (Timeline.AggregatedTimelineTreeView._isExtensionInternalURL(url))
-      return Timeline.AggregatedTimelineTreeView._extensionInternalPrefix;
-    if (Timeline.AggregatedTimelineTreeView._isV8NativeURL(url))
-      return Timeline.AggregatedTimelineTreeView._v8NativePrefix;
-    const parsedURL = url.asParsedURL();
-    if (!parsedURL)
-      return '';
-    if (parsedURL.scheme === 'chrome-extension')
-      return parsedURL.scheme + '://' + parsedURL.host;
-    if (!groupSubdomains)
-      return parsedURL.host;
-    if (/^[.0-9]+$/.test(parsedURL.host))
-      return parsedURL.host;
-    const domainMatch = /([^.]*\.)?[^.]*$/.exec(parsedURL.host);
-    return domainMatch && domainMatch[0] || '';
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  _productByEvent(event) {
-    const url = TimelineModel.TimelineProfileTree.eventURL(event);
-    if (!url)
-      return '';
-    if (this._productByURLCache.has(url))
-      return this._productByURLCache.get(url);
-    if (!this._productRegistry)
-      return '';
-    const parsedURL = url.asParsedURL();
-    const name = parsedURL && this._productRegistry.nameForUrl(parsedURL) || '';
-    this._productByURLCache.set(url, name);
-    return name;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?{name: string, badge: ?Element}}
-   */
-  _productAndBadgeByEvent(event) {
-    const url = TimelineModel.TimelineProfileTree.eventURL(event);
-    if (!url || !this._productRegistry)
-      return null;
-    const parsedURL = url.asParsedURL();
-    const name = parsedURL && this._productRegistry.nameForUrl(parsedURL) || this._domainByEvent(true, event);
-    if (!name)
-      return null;
-    const icon = parsedURL && this._badgePool.badgeForURL(parsedURL);
-    return {name: this._beautifyDomainName(name), badge: icon};
-  }
-
-  /**
-   * @override
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!TimelineModel.TimelineProfileTree.Node} node
-   */
-  _appendContextMenuItems(contextMenu, node) {
-    if (this._groupBySetting.get() !== Timeline.AggregatedTimelineTreeView.GroupBy.Frame)
-      return;
-    if (!node.isGroupNode())
-      return;
-    const frame = this._model.timelineModel().pageFrameById(node.id);
-    if (!frame || !frame.ownerNode)
-      return;
-    contextMenu.appendApplicableItems(frame.ownerNode);
-  }
-
-  /**
-   * @param {string} url
-   * @return {boolean}
-   */
-  static _isExtensionInternalURL(url) {
-    return url.startsWith(Timeline.AggregatedTimelineTreeView._extensionInternalPrefix);
-  }
-
-  /**
-   * @param {string} url
-   * @return {boolean}
-   */
-  static _isV8NativeURL(url) {
-    return url.startsWith(Timeline.AggregatedTimelineTreeView._v8NativePrefix);
-  }
-};
-
-Timeline.AggregatedTimelineTreeView._extensionInternalPrefix = 'extensions::';
-Timeline.AggregatedTimelineTreeView._v8NativePrefix = 'native ';
-
-/**
- * @enum {string}
- */
-Timeline.AggregatedTimelineTreeView.GroupBy = {
-  None: 'None',
-  EventName: 'EventName',
-  Category: 'Category',
-  Domain: 'Domain',
-  Subdomain: 'Subdomain',
-  Product: 'Product',
-  URL: 'URL',
-  Frame: 'Frame'
-};
-
-/**
- * @unrestricted
- */
-Timeline.CallTreeTimelineTreeView = class extends Timeline.AggregatedTimelineTreeView {
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   */
-  constructor(filters) {
-    super(filters);
-    this._dataGrid.markColumnAsSortedBy('total', DataGrid.DataGrid.Order.Descending);
-  }
-
-  /**
-   * @override
-   * @return {!TimelineModel.TimelineProfileTree.Node}
-   */
-  _buildTree() {
-    const grouping = this._groupBySetting.get();
-    return this.buildTopDownTree(false, this._groupingFunction(grouping));
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.BottomUpTimelineTreeView = class extends Timeline.AggregatedTimelineTreeView {
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   */
-  constructor(filters) {
-    super(filters);
-    this._dataGrid.markColumnAsSortedBy('self', DataGrid.DataGrid.Order.Descending);
-  }
-
-  /**
-   * @override
-   * @return {!TimelineModel.TimelineProfileTree.Node}
-   */
-  _buildTree() {
-    return new TimelineModel.TimelineProfileTree.BottomUpRootNode(
-        this._modelEvents(), this._filters, this._startTime, this._endTime,
-        this._groupingFunction(this._groupBySetting.get()));
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineStackView = class extends UI.VBox {
-  constructor(treeView) {
-    super();
-    const header = this.element.createChild('div', 'timeline-stack-view-header');
-    header.textContent = Common.UIString('Heaviest stack');
-    this._treeView = treeView;
-    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
-      {id: 'total', title: Common.UIString('Total Time'), fixedWidth: true, width: '110px'},
-      {id: 'activity', title: Common.UIString('Activity')}
-    ]);
-    this._dataGrid = new DataGrid.ViewportDataGrid(columns);
-    this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
-    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SelectedNode, this._onSelectionChanged, this);
-    this._dataGrid.asWidget().show(this.element);
-  }
-
-  /**
-   * @param {!Array<!TimelineModel.TimelineProfileTree.Node>} stack
-   * @param {!TimelineModel.TimelineProfileTree.Node} selectedNode
-   */
-  setStack(stack, selectedNode) {
-    const rootNode = this._dataGrid.rootNode();
-    rootNode.removeChildren();
-    let nodeToReveal = null;
-    const totalTime = Math.max.apply(Math, stack.map(node => node.totalTime));
-    for (const node of stack) {
-      const gridNode = new Timeline.TimelineTreeView.GridNode(node, totalTime, totalTime, totalTime, this._treeView);
-      rootNode.appendChild(gridNode);
-      if (node === selectedNode)
-        nodeToReveal = gridNode;
-    }
-    nodeToReveal.revealAndSelect();
-  }
-
-  /**
-   * @return {?TimelineModel.TimelineProfileTree.Node}
-   */
-  selectedTreeNode() {
-    const selectedNode = this._dataGrid.selectedNode;
-    return selectedNode && /** @type {!Timeline.TimelineTreeView.GridNode} */ (selectedNode)._profileNode;
-  }
-
-  _onSelectionChanged() {
-    this.dispatchEventToListeners(Timeline.TimelineStackView.Events.SelectionChanged);
-  }
-};
-
-/** @enum {symbol} */
-Timeline.TimelineStackView.Events = {
-  SelectionChanged: Symbol('SelectionChanged')
-};
diff --git a/front_end/timeline/TimelineUIUtils.js b/front_end/timeline/TimelineUIUtils.js
deleted file mode 100644
index e152c2a..0000000
--- a/front_end/timeline/TimelineUIUtils.js
+++ /dev/null
@@ -1,2376 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2012 Intel Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Timeline.TimelineUIUtils = class {
-  /**
-   * @return {!Object.<string, !Timeline.TimelineRecordStyle>}
-   */
-  static _initEventStyles() {
-    if (Timeline.TimelineUIUtils._eventStylesMap)
-      return Timeline.TimelineUIUtils._eventStylesMap;
-
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    const categories = Timeline.TimelineUIUtils.categories();
-
-    const eventStyles = {};
-    eventStyles[recordTypes.Task] = new Timeline.TimelineRecordStyle(Common.UIString('Task'), categories['other']);
-    eventStyles[recordTypes.Program] = new Timeline.TimelineRecordStyle(Common.UIString('Other'), categories['other']);
-    eventStyles[recordTypes.Animation] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Animation'), categories['rendering']);
-    eventStyles[recordTypes.EventDispatch] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Event'), categories['scripting']);
-    eventStyles[recordTypes.RequestMainThreadFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Request Main Thread Frame'), categories['rendering'], true);
-    eventStyles[recordTypes.BeginFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Frame Start'), categories['rendering'], true);
-    eventStyles[recordTypes.BeginMainThreadFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Frame Start (main thread)'), categories['rendering'], true);
-    eventStyles[recordTypes.DrawFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Draw Frame'), categories['rendering'], true);
-    eventStyles[recordTypes.HitTest] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Hit Test'), categories['rendering']);
-    eventStyles[recordTypes.ScheduleStyleRecalculation] = new Timeline.TimelineRecordStyle(
-        Common.UIString('Schedule Style Recalculation'), categories['rendering'], true);
-    eventStyles[recordTypes.RecalculateStyles] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Recalculate Style'), categories['rendering']);
-    eventStyles[recordTypes.UpdateLayoutTree] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Recalculate Style'), categories['rendering']);
-    eventStyles[recordTypes.InvalidateLayout] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Invalidate Layout'), categories['rendering'], true);
-    eventStyles[recordTypes.Layout] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Layout'), categories['rendering']);
-    eventStyles[recordTypes.PaintSetup] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Paint Setup'), categories['painting']);
-    eventStyles[recordTypes.PaintImage] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Paint Image'), categories['painting'], true);
-    eventStyles[recordTypes.UpdateLayer] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Update Layer'), categories['painting'], true);
-    eventStyles[recordTypes.UpdateLayerTree] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Update Layer Tree'), categories['rendering']);
-    eventStyles[recordTypes.Paint] = new Timeline.TimelineRecordStyle(Common.UIString('Paint'), categories['painting']);
-    eventStyles[recordTypes.RasterTask] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Rasterize Paint'), categories['painting']);
-    eventStyles[recordTypes.ScrollLayer] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Scroll'), categories['rendering']);
-    eventStyles[recordTypes.CompositeLayers] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Composite Layers'), categories['painting']);
-    eventStyles[recordTypes.ParseHTML] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Parse HTML'), categories['loading']);
-    eventStyles[recordTypes.ParseAuthorStyleSheet] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Parse Stylesheet'), categories['loading']);
-    eventStyles[recordTypes.TimerInstall] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Install Timer'), categories['scripting']);
-    eventStyles[recordTypes.TimerRemove] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Remove Timer'), categories['scripting']);
-    eventStyles[recordTypes.TimerFire] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Timer Fired'), categories['scripting']);
-    eventStyles[recordTypes.XHRReadyStateChange] =
-        new Timeline.TimelineRecordStyle(Common.UIString('XHR Ready State Change'), categories['scripting']);
-    eventStyles[recordTypes.XHRLoad] =
-        new Timeline.TimelineRecordStyle(Common.UIString('XHR Load'), categories['scripting']);
-    eventStyles[recordTypes.CompileScript] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Compile Script'), categories['scripting']);
-    eventStyles[recordTypes.EvaluateScript] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Evaluate Script'), categories['scripting']);
-    eventStyles[recordTypes.CompileModule] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Compile Module'), categories['scripting']);
-    eventStyles[recordTypes.EvaluateModule] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Evaluate Module'), categories['scripting']);
-    eventStyles[recordTypes.ParseScriptOnBackground] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Parse Script'), categories['scripting']);
-    eventStyles[recordTypes.MarkLoad] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Load event'), categories['scripting'], true);
-    eventStyles[recordTypes.MarkDOMContent] =
-        new Timeline.TimelineRecordStyle(Common.UIString('DOMContentLoaded event'), categories['scripting'], true);
-    eventStyles[recordTypes.MarkFirstPaint] =
-        new Timeline.TimelineRecordStyle(Common.UIString('First paint'), categories['painting'], true);
-    eventStyles[recordTypes.MarkFCP] =
-        new Timeline.TimelineRecordStyle(Common.UIString('First contentful paint'), categories['rendering'], true);
-    eventStyles[recordTypes.MarkFMP] =
-        new Timeline.TimelineRecordStyle(Common.UIString('First meaningful paint'), categories['rendering'], true);
-    eventStyles[recordTypes.MarkFMPCandidate] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Meaningful paint candidate'), categories['rendering'], true);
-    eventStyles[recordTypes.TimeStamp] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Timestamp'), categories['scripting']);
-    eventStyles[recordTypes.ConsoleTime] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Console Time'), categories['scripting']);
-    eventStyles[recordTypes.UserTiming] =
-        new Timeline.TimelineRecordStyle(Common.UIString('User Timing'), categories['scripting']);
-    eventStyles[recordTypes.ResourceSendRequest] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Send Request'), categories['loading']);
-    eventStyles[recordTypes.ResourceReceiveResponse] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Receive Response'), categories['loading']);
-    eventStyles[recordTypes.ResourceFinish] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Finish Loading'), categories['loading']);
-    eventStyles[recordTypes.ResourceReceivedData] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Receive Data'), categories['loading']);
-    eventStyles[recordTypes.RunMicrotasks] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Run Microtasks'), categories['scripting']);
-    eventStyles[recordTypes.FunctionCall] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Function Call'), categories['scripting']);
-    eventStyles[recordTypes.GCEvent] =
-        new Timeline.TimelineRecordStyle(Common.UIString('GC Event'), categories['scripting']);
-    eventStyles[recordTypes.MajorGC] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Major GC'), categories['scripting']);
-    eventStyles[recordTypes.MinorGC] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Minor GC'), categories['scripting']);
-    eventStyles[recordTypes.JSFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('JS Frame'), categories['scripting']);
-    eventStyles[recordTypes.RequestAnimationFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Request Animation Frame'), categories['scripting']);
-    eventStyles[recordTypes.CancelAnimationFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Cancel Animation Frame'), categories['scripting']);
-    eventStyles[recordTypes.FireAnimationFrame] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Animation Frame Fired'), categories['scripting']);
-    eventStyles[recordTypes.RequestIdleCallback] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Request Idle Callback'), categories['scripting']);
-    eventStyles[recordTypes.CancelIdleCallback] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Cancel Idle Callback'), categories['scripting']);
-    eventStyles[recordTypes.FireIdleCallback] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Fire Idle Callback'), categories['scripting']);
-    eventStyles[recordTypes.WebSocketCreate] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Create WebSocket'), categories['scripting']);
-    eventStyles[recordTypes.WebSocketSendHandshakeRequest] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Send WebSocket Handshake'), categories['scripting']);
-    eventStyles[recordTypes.WebSocketReceiveHandshakeResponse] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Receive WebSocket Handshake'), categories['scripting']);
-    eventStyles[recordTypes.WebSocketDestroy] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Destroy WebSocket'), categories['scripting']);
-    eventStyles[recordTypes.EmbedderCallback] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Embedder Callback'), categories['scripting']);
-    eventStyles[recordTypes.DecodeImage] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Image Decode'), categories['painting']);
-    eventStyles[recordTypes.ResizeImage] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Image Resize'), categories['painting']);
-    eventStyles[recordTypes.GPUTask] = new Timeline.TimelineRecordStyle(Common.UIString('GPU'), categories['gpu']);
-    eventStyles[recordTypes.LatencyInfo] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Input Latency'), categories['scripting']);
-
-    eventStyles[recordTypes.GCIdleLazySweep] =
-        new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']);
-    eventStyles[recordTypes.GCCompleteSweep] =
-        new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']);
-    eventStyles[recordTypes.GCCollectGarbage] =
-        new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']);
-
-    eventStyles[recordTypes.CryptoDoEncrypt] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Encrypt'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoEncryptReply] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Encrypt Reply'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoDecrypt] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Decrypt'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoDecryptReply] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Decrypt Reply'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoDigest] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Digest'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoDigestReply] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Digest Reply'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoSign] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Sign'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoSignReply] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Sign Reply'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoVerify] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Verify'), categories['scripting']);
-    eventStyles[recordTypes.CryptoDoVerifyReply] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Verify Reply'), categories['scripting']);
-
-    eventStyles[recordTypes.AsyncTask] =
-        new Timeline.TimelineRecordStyle(Common.UIString('Async Task'), categories['async']);
-
-    Timeline.TimelineUIUtils._eventStylesMap = eventStyles;
-    return eventStyles;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineIRModel.InputEvents} inputEventType
-   * @return {?string}
-   */
-  static inputEventDisplayName(inputEventType) {
-    if (!Timeline.TimelineUIUtils._inputEventToDisplayName) {
-      const inputEvent = TimelineModel.TimelineIRModel.InputEvents;
-
-      /** @type {!Map<!TimelineModel.TimelineIRModel.InputEvents, string>} */
-      Timeline.TimelineUIUtils._inputEventToDisplayName = new Map([
-        [inputEvent.Char, Common.UIString('Key Character')],
-        [inputEvent.KeyDown, Common.UIString('Key Down')],
-        [inputEvent.KeyDownRaw, Common.UIString('Key Down')],
-        [inputEvent.KeyUp, Common.UIString('Key Up')],
-        [inputEvent.Click, Common.UIString('Click')],
-        [inputEvent.ContextMenu, Common.UIString('Context Menu')],
-        [inputEvent.MouseDown, Common.UIString('Mouse Down')],
-        [inputEvent.MouseMove, Common.UIString('Mouse Move')],
-        [inputEvent.MouseUp, Common.UIString('Mouse Up')],
-        [inputEvent.MouseWheel, Common.UIString('Mouse Wheel')],
-        [inputEvent.ScrollBegin, Common.UIString('Scroll Begin')],
-        [inputEvent.ScrollEnd, Common.UIString('Scroll End')],
-        [inputEvent.ScrollUpdate, Common.UIString('Scroll Update')],
-        [inputEvent.FlingStart, Common.UIString('Fling Start')],
-        [inputEvent.FlingCancel, Common.UIString('Fling Halt')],
-        [inputEvent.Tap, Common.UIString('Tap')],
-        [inputEvent.TapCancel, Common.UIString('Tap Halt')],
-        [inputEvent.ShowPress, Common.UIString('Tap Begin')],
-        [inputEvent.TapDown, Common.UIString('Tap Down')],
-        [inputEvent.TouchCancel, Common.UIString('Touch Cancel')],
-        [inputEvent.TouchEnd, Common.UIString('Touch End')],
-        [inputEvent.TouchMove, Common.UIString('Touch Move')],
-        [inputEvent.TouchStart, Common.UIString('Touch Start')],
-        [inputEvent.PinchBegin, Common.UIString('Pinch Begin')],
-        [inputEvent.PinchEnd, Common.UIString('Pinch End')],
-        [inputEvent.PinchUpdate, Common.UIString('Pinch Update')]
-      ]);
-    }
-    return Timeline.TimelineUIUtils._inputEventToDisplayName.get(inputEventType) || null;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.CallFrame} frame
-   * @return {string}
-   */
-  static frameDisplayName(frame) {
-    if (!TimelineModel.TimelineJSProfileProcessor.isNativeRuntimeFrame(frame))
-      return UI.beautifyFunctionName(frame.functionName);
-    const nativeGroup = TimelineModel.TimelineJSProfileProcessor.nativeGroup(frame.functionName);
-    const groups = TimelineModel.TimelineJSProfileProcessor.NativeGroups;
-    switch (nativeGroup) {
-      case groups.Compile:
-        return Common.UIString('Compile');
-      case groups.Parse:
-        return Common.UIString('Parse');
-    }
-    return frame.functionName;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} traceEvent
-   * @param {!RegExp} regExp
-   * @return {boolean}
-   */
-  static testContentMatching(traceEvent, regExp) {
-    const title = Timeline.TimelineUIUtils.eventStyle(traceEvent).title;
-    const tokens = [title];
-    const url = TimelineModel.TimelineData.forEvent(traceEvent).url;
-    if (url)
-      tokens.push(url);
-    appendObjectProperties(traceEvent.args, 2);
-    return regExp.test(tokens.join('|'));
-
-    /**
-     * @param {!Object} object
-     * @param {number} depth
-     */
-    function appendObjectProperties(object, depth) {
-      if (!depth)
-        return;
-      for (const key in object) {
-        const value = object[key];
-        const type = typeof value;
-        if (type === 'string')
-          tokens.push(value);
-        else if (type === 'number')
-          tokens.push(String(value));
-        else if (type === 'object')
-          appendObjectProperties(value, depth - 1);
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?string}
-   */
-  static eventURL(event) {
-    const data = event.args['data'] || event.args['beginData'];
-    const url = data && data.url;
-    if (url)
-      return url;
-    const stackTrace = data && data['stackTrace'];
-    const frame =
-        stackTrace && stackTrace.length && stackTrace[0] || TimelineModel.TimelineData.forEvent(event).topFrame();
-    return frame && frame.url || null;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {!{title: string, category: !Timeline.TimelineCategory}}
-   */
-  static eventStyle(event) {
-    const eventStyles = Timeline.TimelineUIUtils._initEventStyles();
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.Console) ||
-        event.hasCategory(TimelineModel.TimelineModel.Category.UserTiming))
-      return {title: event.name, category: Timeline.TimelineUIUtils.categories()['scripting']};
-
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) {
-      /** @const */
-      const prefix = 'InputLatency::';
-      const inputEventType = event.name.startsWith(prefix) ? event.name.substr(prefix.length) : event.name;
-      const displayName = Timeline.TimelineUIUtils.inputEventDisplayName(
-          /** @type {!TimelineModel.TimelineIRModel.InputEvents} */ (inputEventType));
-      return {title: displayName || inputEventType, category: Timeline.TimelineUIUtils.categories()['scripting']};
-    }
-    let result = eventStyles[event.name];
-    if (!result) {
-      result = new Timeline.TimelineRecordStyle(event.name, Timeline.TimelineUIUtils.categories()['other'], true);
-      eventStyles[event.name] = result;
-    }
-    return result;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  static eventColor(event) {
-    if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame) {
-      const frame = event.args['data'];
-      if (Timeline.TimelineUIUtils.isUserFrame(frame))
-        return Timeline.TimelineUIUtils.colorForId(frame.url);
-    }
-    return Timeline.TimelineUIUtils.eventStyle(event).category.color;
-  }
-
-  /**
-   * @param {!ProductRegistry.Registry} productRegistry
-   * @param {!TimelineModel.TimelineModel} model
-   * @param {!Map<string, string>} urlToColorCache
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  static eventColorByProduct(productRegistry, model, urlToColorCache, event) {
-    const url = Timeline.TimelineUIUtils.eventURL(event) || '';
-    let color = urlToColorCache.get(url);
-    if (color)
-      return color;
-    const defaultColor = '#f2ecdc';
-    const parsedURL = url.asParsedURL();
-    if (!parsedURL)
-      return defaultColor;
-    let name = productRegistry && productRegistry.nameForUrl(parsedURL);
-    if (!name) {
-      name = parsedURL.host;
-      const rootFrames = model.rootFrames();
-      if (rootFrames.some(pageFrame => new Common.ParsedURL(pageFrame.url).host === name))
-        color = defaultColor;
-    }
-    if (!color)
-      color = name ? ProductRegistry.BadgePool.colorForEntryName(name) : defaultColor;
-    urlToColorCache.set(url, color);
-    return color;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  static eventTitle(event) {
-    const recordType = TimelineModel.TimelineModel.RecordType;
-    const eventData = event.args['data'];
-    if (event.name === recordType.JSFrame)
-      return Timeline.TimelineUIUtils.frameDisplayName(eventData);
-    const title = Timeline.TimelineUIUtils.eventStyle(event).title;
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.Console))
-      return title;
-    if (event.name === recordType.TimeStamp)
-      return Common.UIString('%s: %s', title, eventData['message']);
-    if (event.name === recordType.Animation && eventData && eventData['name'])
-      return Common.UIString('%s: %s', title, eventData['name']);
-    return title;
-  }
-
-  /**
-   * !Map<!TimelineModel.TimelineIRModel.Phases, !{color: string, label: string}>
-   */
-  static _interactionPhaseStyles() {
-    let map = Timeline.TimelineUIUtils._interactionPhaseStylesMap;
-    if (!map) {
-      map = new Map([
-        [TimelineModel.TimelineIRModel.Phases.Idle, {color: 'white', label: 'Idle'}],
-        [
-          TimelineModel.TimelineIRModel.Phases.Response,
-          {color: 'hsl(43, 83%, 64%)', label: Common.UIString('Response')}
-        ],
-        [TimelineModel.TimelineIRModel.Phases.Scroll, {color: 'hsl(256, 67%, 70%)', label: Common.UIString('Scroll')}],
-        [TimelineModel.TimelineIRModel.Phases.Fling, {color: 'hsl(256, 67%, 70%)', label: Common.UIString('Fling')}],
-        [TimelineModel.TimelineIRModel.Phases.Drag, {color: 'hsl(256, 67%, 70%)', label: Common.UIString('Drag')}],
-        [
-          TimelineModel.TimelineIRModel.Phases.Animation,
-          {color: 'hsl(256, 67%, 70%)', label: Common.UIString('Animation')}
-        ],
-        [
-          TimelineModel.TimelineIRModel.Phases.Uncategorized,
-          {color: 'hsl(0, 0%, 87%)', label: Common.UIString('Uncategorized')}
-        ]
-      ]);
-      Timeline.TimelineUIUtils._interactionPhaseStylesMap = map;
-    }
-    return map;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineIRModel.Phases} phase
-   * @return {string}
-   */
-  static interactionPhaseColor(phase) {
-    return Timeline.TimelineUIUtils._interactionPhaseStyles().get(phase).color;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineIRModel.Phases} phase
-   * @return {string}
-   */
-  static interactionPhaseLabel(phase) {
-    return Timeline.TimelineUIUtils._interactionPhaseStyles().get(phase).label;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.CallFrame} frame
-   * @return {boolean}
-   */
-  static isUserFrame(frame) {
-    return frame.scriptId !== '0' && !(frame.url && frame.url.startsWith('native '));
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel.NetworkRequest} request
-   * @return {!Timeline.TimelineUIUtils.NetworkCategory}
-   */
-  static networkRequestCategory(request) {
-    const categories = Timeline.TimelineUIUtils.NetworkCategory;
-    switch (request.mimeType) {
-      case 'text/html':
-        return categories.HTML;
-      case 'application/javascript':
-      case 'application/x-javascript':
-      case 'text/javascript':
-        return categories.Script;
-      case 'text/css':
-        return categories.Style;
-      case 'audio/ogg':
-      case 'image/gif':
-      case 'image/jpeg':
-      case 'image/png':
-      case 'image/svg+xml':
-      case 'image/webp':
-      case 'image/x-icon':
-      case 'font/opentype':
-      case 'font/woff2':
-      case 'application/font-woff':
-        return categories.Media;
-      default:
-        return categories.Other;
-    }
-  }
-
-  /**
-   * @param {!Timeline.TimelineUIUtils.NetworkCategory} category
-   * @return {string}
-   */
-  static networkCategoryColor(category) {
-    const categories = Timeline.TimelineUIUtils.NetworkCategory;
-    switch (category) {
-      case categories.HTML:
-        return 'hsl(214, 67%, 66%)';
-      case categories.Script:
-        return 'hsl(43, 83%, 64%)';
-      case categories.Style:
-        return 'hsl(256, 67%, 70%)';
-      case categories.Media:
-        return 'hsl(109, 33%, 55%)';
-      default:
-        return 'hsl(0, 0%, 70%)';
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {?SDK.Target} target
-   * @return {?string}
-   */
-  static buildDetailsTextForTraceEvent(event, target) {
-    const recordType = TimelineModel.TimelineModel.RecordType;
-    let detailsText;
-    const eventData = event.args['data'];
-    switch (event.name) {
-      case recordType.GCEvent:
-      case recordType.MajorGC:
-      case recordType.MinorGC: {
-        const delta = event.args['usedHeapSizeBefore'] - event.args['usedHeapSizeAfter'];
-        detailsText = Common.UIString('%s collected', Number.bytesToString(delta));
-        break;
-      }
-      case recordType.FunctionCall:
-        if (eventData) {
-          detailsText =
-              linkifyLocationAsText(eventData['scriptId'], eventData['lineNumber'], eventData['columnNumber']);
-        }
-        break;
-      case recordType.JSFrame:
-        detailsText = Timeline.TimelineUIUtils.frameDisplayName(eventData);
-        break;
-      case recordType.EventDispatch:
-        detailsText = eventData ? eventData['type'] : null;
-        break;
-      case recordType.Paint: {
-        const width = Timeline.TimelineUIUtils.quadWidth(eventData.clip);
-        const height = Timeline.TimelineUIUtils.quadHeight(eventData.clip);
-        if (width && height)
-          detailsText = Common.UIString('%d\xa0\u00d7\xa0%d', width, height);
-        break;
-      }
-      case recordType.ParseHTML: {
-        const endLine = event.args['endData'] && event.args['endData']['endLine'];
-        const url = Bindings.displayNameForURL(event.args['beginData']['url']);
-        detailsText = Common.UIString(
-            '%s [%s\u2026%s]', url, event.args['beginData']['startLine'] + 1, endLine >= 0 ? endLine + 1 : '');
-        break;
-      }
-      case recordType.CompileModule:
-        detailsText = Bindings.displayNameForURL(event.args['fileName']);
-        break;
-      case recordType.CompileScript:
-      case recordType.EvaluateScript: {
-        const url = eventData && eventData['url'];
-        if (url)
-          detailsText = Bindings.displayNameForURL(url) + ':' + (eventData['lineNumber'] + 1);
-        break;
-      }
-      case recordType.ParseScriptOnBackground:
-      case recordType.XHRReadyStateChange:
-      case recordType.XHRLoad: {
-        const url = eventData['url'];
-        if (url)
-          detailsText = Bindings.displayNameForURL(url);
-        break;
-      }
-      case recordType.TimeStamp:
-        detailsText = eventData['message'];
-        break;
-
-      case recordType.WebSocketCreate:
-      case recordType.WebSocketSendHandshakeRequest:
-      case recordType.WebSocketReceiveHandshakeResponse:
-      case recordType.WebSocketDestroy:
-      case recordType.ResourceSendRequest:
-      case recordType.ResourceReceivedData:
-      case recordType.ResourceReceiveResponse:
-      case recordType.ResourceFinish:
-      case recordType.PaintImage:
-      case recordType.DecodeImage:
-      case recordType.ResizeImage:
-      case recordType.DecodeLazyPixelRef: {
-        const url = TimelineModel.TimelineData.forEvent(event).url;
-        if (url)
-          detailsText = Bindings.displayNameForURL(url);
-        break;
-      }
-
-      case recordType.EmbedderCallback:
-        detailsText = eventData['callbackName'];
-        break;
-
-      case recordType.Animation:
-        detailsText = eventData && eventData['name'];
-        break;
-
-      case recordType.GCIdleLazySweep:
-        detailsText = Common.UIString('idle sweep');
-        break;
-
-      case recordType.GCCompleteSweep:
-        detailsText = Common.UIString('complete sweep');
-        break;
-
-      case recordType.GCCollectGarbage:
-        detailsText = Common.UIString('collect');
-        break;
-
-      case recordType.AsyncTask:
-        detailsText = eventData ? eventData['name'] : null;
-        break;
-
-      default:
-        if (event.hasCategory(TimelineModel.TimelineModel.Category.Console))
-          detailsText = null;
-        else
-          detailsText = linkifyTopCallFrameAsText();
-        break;
-    }
-
-    return detailsText;
-
-    /**
-     * @param {string} scriptId
-     * @param {number} lineNumber
-     * @param {number} columnNumber
-     * @return {?string}
-     */
-    function linkifyLocationAsText(scriptId, lineNumber, columnNumber) {
-      const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
-      if (!target || target.isDisposed() || !scriptId || !debuggerModel)
-        return null;
-      const rawLocation = debuggerModel.createRawLocationByScriptId(scriptId, lineNumber, columnNumber);
-      if (!rawLocation)
-        return null;
-      const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
-      return uiLocation ? uiLocation.linkText() : null;
-    }
-
-    /**
-     * @return {?string}
-     */
-    function linkifyTopCallFrameAsText() {
-      const frame = TimelineModel.TimelineData.forEvent(event).topFrame();
-      if (!frame)
-        return null;
-      let text = linkifyLocationAsText(frame.scriptId, frame.lineNumber, frame.columnNumber);
-      if (!text) {
-        text = frame.url;
-        if (typeof frame.lineNumber === 'number')
-          text += ':' + (frame.lineNumber + 1);
-      }
-      return text;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {?SDK.Target} target
-   * @param {!Components.Linkifier} linkifier
-   * @return {?Node}
-   */
-  static buildDetailsNodeForTraceEvent(event, target, linkifier) {
-    const recordType = TimelineModel.TimelineModel.RecordType;
-    let details = null;
-    let detailsText;
-    const eventData = event.args['data'];
-    switch (event.name) {
-      case recordType.GCEvent:
-      case recordType.MajorGC:
-      case recordType.MinorGC:
-      case recordType.EventDispatch:
-      case recordType.Paint:
-      case recordType.Animation:
-      case recordType.EmbedderCallback:
-      case recordType.ParseHTML:
-      case recordType.WebSocketCreate:
-      case recordType.WebSocketSendHandshakeRequest:
-      case recordType.WebSocketReceiveHandshakeResponse:
-      case recordType.WebSocketDestroy:
-      case recordType.GCIdleLazySweep:
-      case recordType.GCCompleteSweep:
-      case recordType.GCCollectGarbage:
-        detailsText = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(event, target);
-        break;
-      case recordType.PaintImage:
-      case recordType.DecodeImage:
-      case recordType.ResizeImage:
-      case recordType.DecodeLazyPixelRef:
-      case recordType.XHRReadyStateChange:
-      case recordType.XHRLoad:
-      case recordType.ResourceSendRequest:
-      case recordType.ResourceReceivedData:
-      case recordType.ResourceReceiveResponse:
-      case recordType.ResourceFinish: {
-        const url = TimelineModel.TimelineData.forEvent(event).url;
-        if (url)
-          details = Components.Linkifier.linkifyURL(url);
-        break;
-      }
-      case recordType.FunctionCall:
-      case recordType.JSFrame:
-        details = createElement('span');
-        details.createTextChild(Timeline.TimelineUIUtils.frameDisplayName(eventData));
-        const location = linkifyLocation(
-            eventData['scriptId'], eventData['url'], eventData['lineNumber'], eventData['columnNumber']);
-        if (location) {
-          details.createTextChild(' @ ');
-          details.appendChild(location);
-        }
-        break;
-      case recordType.CompileModule:
-        details = linkifyLocation('', event.args['fileName'], 0, 0);
-        break;
-      case recordType.CompileScript:
-      case recordType.EvaluateScript: {
-        const url = eventData['url'];
-        if (url)
-          details = linkifyLocation('', url, eventData['lineNumber'], 0);
-        break;
-      }
-      case recordType.ParseScriptOnBackground: {
-        const url = eventData['url'];
-        if (url)
-          details = linkifyLocation('', url, 0, 0);
-        break;
-      }
-      default:
-        if (event.hasCategory(TimelineModel.TimelineModel.Category.Console))
-          detailsText = null;
-        else
-          details = linkifyTopCallFrame();
-        break;
-    }
-
-    if (!details && detailsText)
-      details = createTextNode(detailsText);
-    return details;
-
-    /**
-     * @param {string} scriptId
-     * @param {string} url
-     * @param {number} lineNumber
-     * @param {number=} columnNumber
-     * @return {?Element}
-     */
-    function linkifyLocation(scriptId, url, lineNumber, columnNumber) {
-      return linkifier.linkifyScriptLocation(target, scriptId, url, lineNumber, columnNumber, 'timeline-details');
-    }
-
-    /**
-     * @return {?Element}
-     */
-    function linkifyTopCallFrame() {
-      const frame = TimelineModel.TimelineData.forEvent(event).topFrame();
-      return frame ? linkifier.maybeLinkifyConsoleCallFrame(target, frame, 'timeline-details') : null;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {!TimelineModel.TimelineModel} model
-   * @param {!Components.Linkifier} linkifier
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {boolean} detailed
-   * @return {!Promise<!DocumentFragment>}
-   */
-  static async buildTraceEventDetails(event, model, linkifier, badgePool, detailed) {
-    const maybeTarget = model.targetByEvent(event);
-    /** @type {?Map<number, ?SDK.DOMNode>} */
-    let relatedNodesMap = null;
-    if (maybeTarget) {
-      const target = /** @type {!SDK.Target} */ (maybeTarget);
-      if (typeof event[Timeline.TimelineUIUtils._previewElementSymbol] === 'undefined') {
-        let previewElement = null;
-        const url = TimelineModel.TimelineData.forEvent(event).url;
-        if (url)
-          previewElement = await BrowserComponents.ImagePreview.build(target, url, false);
-        else if (TimelineModel.TimelineData.forEvent(event).picture)
-          previewElement = await Timeline.TimelineUIUtils.buildPicturePreviewContent(event, target);
-        event[Timeline.TimelineUIUtils._previewElementSymbol] = previewElement;
-      }
-
-      /** @type {!Set<number>} */
-      const nodeIdsToResolve = new Set();
-      const timelineData = TimelineModel.TimelineData.forEvent(event);
-      if (timelineData.backendNodeId)
-        nodeIdsToResolve.add(timelineData.backendNodeId);
-      const invalidationTrackingEvents = TimelineModel.InvalidationTracker.invalidationEventsFor(event);
-      if (invalidationTrackingEvents)
-        Timeline.TimelineUIUtils._collectInvalidationNodeIds(nodeIdsToResolve, invalidationTrackingEvents);
-      if (nodeIdsToResolve.size) {
-        const domModel = target.model(SDK.DOMModel);
-        if (domModel)
-          relatedNodesMap = await domModel.pushNodesByBackendIdsToFrontend(nodeIdsToResolve);
-      }
-    }
-
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    // This message may vary per event.name;
-    let relatedNodeLabel;
-
-    const contentHelper = new Timeline.TimelineDetailsContentHelper(model.targetByEvent(event), linkifier);
-    contentHelper.addSection(
-        Timeline.TimelineUIUtils.eventTitle(event), Timeline.TimelineUIUtils.eventStyle(event).category.color);
-
-    const eventData = event.args['data'];
-    const timelineData = TimelineModel.TimelineData.forEvent(event);
-    const initiator = timelineData.initiator();
-    let url = null;
-
-    if (timelineData.warning)
-      contentHelper.appendWarningRow(event);
-    if (event.name === recordTypes.JSFrame && eventData['deoptReason'])
-      contentHelper.appendWarningRow(event, TimelineModel.TimelineModel.WarningType.V8Deopt);
-
-    if (detailed) {
-      contentHelper.appendTextRow(Common.UIString('Total Time'), Number.millisToString(event.duration || 0, true));
-      contentHelper.appendTextRow(Common.UIString('Self Time'), Number.millisToString(event.selfTime, true));
-    }
-
-    switch (event.name) {
-      case recordTypes.GCEvent:
-      case recordTypes.MajorGC:
-      case recordTypes.MinorGC:
-        const delta = event.args['usedHeapSizeBefore'] - event.args['usedHeapSizeAfter'];
-        contentHelper.appendTextRow(Common.UIString('Collected'), Number.bytesToString(delta));
-        break;
-      case recordTypes.JSFrame:
-      case recordTypes.FunctionCall:
-        const detailsNode =
-            Timeline.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, model.targetByEvent(event), linkifier);
-        if (detailsNode)
-          contentHelper.appendElementRow(Common.UIString('Function'), detailsNode);
-        break;
-      case recordTypes.TimerFire:
-      case recordTypes.TimerInstall:
-      case recordTypes.TimerRemove:
-        contentHelper.appendTextRow(Common.UIString('Timer ID'), eventData['timerId']);
-        if (event.name === recordTypes.TimerInstall) {
-          contentHelper.appendTextRow(Common.UIString('Timeout'), Number.millisToString(eventData['timeout']));
-          contentHelper.appendTextRow(Common.UIString('Repeats'), !eventData['singleShot']);
-        }
-        break;
-      case recordTypes.FireAnimationFrame:
-        contentHelper.appendTextRow(Common.UIString('Callback ID'), eventData['id']);
-        break;
-      case recordTypes.ResourceSendRequest:
-      case recordTypes.ResourceReceiveResponse:
-      case recordTypes.ResourceReceivedData:
-      case recordTypes.ResourceFinish:
-        url = timelineData.url;
-        if (url)
-          contentHelper.appendElementRow(Common.UIString('Resource'), Components.Linkifier.linkifyURL(url));
-        if (eventData['requestMethod'])
-          contentHelper.appendTextRow(Common.UIString('Request Method'), eventData['requestMethod']);
-        if (typeof eventData['statusCode'] === 'number')
-          contentHelper.appendTextRow(Common.UIString('Status Code'), eventData['statusCode']);
-        if (eventData['mimeType'])
-          contentHelper.appendTextRow(Common.UIString('MIME Type'), eventData['mimeType']);
-        if ('priority' in eventData) {
-          const priority = PerfUI.uiLabelForNetworkPriority(eventData['priority']);
-          contentHelper.appendTextRow(Common.UIString('Priority'), priority);
-        }
-        if (eventData['encodedDataLength']) {
-          contentHelper.appendTextRow(
-              Common.UIString('Encoded Data'), Common.UIString('%d Bytes', eventData['encodedDataLength']));
-        }
-        if (eventData['decodedBodyLength']) {
-          contentHelper.appendTextRow(
-              Common.UIString('Decoded Body'), Common.UIString('%d Bytes', eventData['decodedBodyLength']));
-        }
-        break;
-      case recordTypes.CompileModule:
-        contentHelper.appendLocationRow(Common.UIString('Module'), event.args['fileName'], 0);
-        break;
-      case recordTypes.CompileScript:
-        url = eventData && eventData['url'];
-        if (url) {
-          contentHelper.appendLocationRow(
-              Common.UIString('Script'), url, eventData['lineNumber'], eventData['columnNumber']);
-        }
-        contentHelper.appendTextRow(Common.UIString('Streamed'), Common.UIString('%s', eventData['streamed']));
-        const cacheProduceOptions = eventData && eventData['cacheProduceOptions'];
-        if (cacheProduceOptions) {
-          contentHelper.appendTextRow(
-              Common.UIString('Cache Produce Options'), Common.UIString('%s', cacheProduceOptions));
-          contentHelper.appendTextRow(
-              Common.UIString('Produced Cache Size'), Common.UIString('%d', eventData['producedCacheSize']));
-        }
-        const cacheConsumeOptions = eventData && eventData['cacheConsumeOptions'];
-        if (cacheConsumeOptions) {
-          contentHelper.appendTextRow(
-              Common.UIString('Cache Consume Options'), Common.UIString('%s', cacheConsumeOptions));
-          contentHelper.appendTextRow(
-              Common.UIString('Consumed Cache Size'), Common.UIString('%d', eventData['consumedCacheSize']));
-          contentHelper.appendTextRow(
-              Common.UIString('Cache Rejected'), Common.UIString('%s', eventData['cacheRejected']));
-        }
-        break;
-      case recordTypes.EvaluateScript:
-        url = eventData && eventData['url'];
-        if (url) {
-          contentHelper.appendLocationRow(
-              Common.UIString('Script'), url, eventData['lineNumber'], eventData['columnNumber']);
-        }
-        break;
-      case recordTypes.Paint:
-        const clip = eventData['clip'];
-        contentHelper.appendTextRow(Common.UIString('Location'), Common.UIString('(%d, %d)', clip[0], clip[1]));
-        const clipWidth = Timeline.TimelineUIUtils.quadWidth(clip);
-        const clipHeight = Timeline.TimelineUIUtils.quadHeight(clip);
-        contentHelper.appendTextRow(Common.UIString('Dimensions'), Common.UIString('%d × %d', clipWidth, clipHeight));
-      // Fall-through intended.
-
-      case recordTypes.PaintSetup:
-      case recordTypes.Rasterize:
-      case recordTypes.ScrollLayer:
-        relatedNodeLabel = Common.UIString('Layer Root');
-        break;
-      case recordTypes.PaintImage:
-      case recordTypes.DecodeLazyPixelRef:
-      case recordTypes.DecodeImage:
-      case recordTypes.ResizeImage:
-      case recordTypes.DrawLazyPixelRef:
-        relatedNodeLabel = Common.UIString('Owner Element');
-        url = timelineData.url;
-        if (url)
-          contentHelper.appendElementRow(Common.UIString('Image URL'), Components.Linkifier.linkifyURL(url));
-        break;
-      case recordTypes.ParseAuthorStyleSheet:
-        url = eventData['styleSheetUrl'];
-        if (url)
-          contentHelper.appendElementRow(Common.UIString('Stylesheet URL'), Components.Linkifier.linkifyURL(url));
-        break;
-      case recordTypes.UpdateLayoutTree:  // We don't want to see default details.
-      case recordTypes.RecalculateStyles:
-        contentHelper.appendTextRow(Common.UIString('Elements Affected'), event.args['elementCount']);
-        break;
-      case recordTypes.Layout:
-        const beginData = event.args['beginData'];
-        contentHelper.appendTextRow(
-            Common.UIString('Nodes That Need Layout'),
-            Common.UIString('%s of %s', beginData['dirtyObjects'], beginData['totalObjects']));
-        relatedNodeLabel = Common.UIString('Layout root');
-        break;
-      case recordTypes.ConsoleTime:
-        contentHelper.appendTextRow(Common.UIString('Message'), event.name);
-        break;
-      case recordTypes.WebSocketCreate:
-      case recordTypes.WebSocketSendHandshakeRequest:
-      case recordTypes.WebSocketReceiveHandshakeResponse:
-      case recordTypes.WebSocketDestroy:
-        const initiatorData = initiator ? initiator.args['data'] : eventData;
-        if (typeof initiatorData['webSocketURL'] !== 'undefined')
-          contentHelper.appendTextRow(Common.UIString('URL'), initiatorData['webSocketURL']);
-        if (typeof initiatorData['webSocketProtocol'] !== 'undefined')
-          contentHelper.appendTextRow(Common.UIString('WebSocket Protocol'), initiatorData['webSocketProtocol']);
-        if (typeof eventData['message'] !== 'undefined')
-          contentHelper.appendTextRow(Common.UIString('Message'), eventData['message']);
-        break;
-      case recordTypes.EmbedderCallback:
-        contentHelper.appendTextRow(Common.UIString('Callback Function'), eventData['callbackName']);
-        break;
-      case recordTypes.Animation:
-        if (event.phase === SDK.TracingModel.Phase.NestableAsyncInstant)
-          contentHelper.appendTextRow(Common.UIString('State'), eventData['state']);
-        break;
-      case recordTypes.ParseHTML: {
-        const beginData = event.args['beginData'];
-        const startLine = beginData['startLine'] - 1;
-        const endLine = event.args['endData'] ? event.args['endData']['endLine'] - 1 : undefined;
-        url = beginData['url'];
-        if (url)
-          contentHelper.appendLocationRange(Common.UIString('Range'), url, startLine, endLine);
-        break;
-      }
-
-      case recordTypes.FireIdleCallback:
-        contentHelper.appendTextRow(
-            Common.UIString('Allotted Time'), Number.millisToString(eventData['allottedMilliseconds']));
-        contentHelper.appendTextRow(Common.UIString('Invoked by Timeout'), eventData['timedOut']);
-      // Fall-through intended.
-
-      case recordTypes.RequestIdleCallback:
-      case recordTypes.CancelIdleCallback:
-        contentHelper.appendTextRow(Common.UIString('Callback ID'), eventData['id']);
-        break;
-      case recordTypes.EventDispatch:
-        contentHelper.appendTextRow(Common.UIString('Type'), eventData['type']);
-        break;
-
-      default: {
-        const detailsNode =
-            Timeline.TimelineUIUtils.buildDetailsNodeForTraceEvent(event, model.targetByEvent(event), linkifier);
-        if (detailsNode)
-          contentHelper.appendElementRow(Common.UIString('Details'), detailsNode);
-        break;
-      }
-    }
-
-    Timeline.TimelineUIUtils._maybeAppendProductToDetails(
-        contentHelper, badgePool, url || eventData && eventData['url']);
-
-    if (timelineData.timeWaitingForMainThread) {
-      contentHelper.appendTextRow(
-          Common.UIString('Time Waiting for Main Thread'),
-          Number.millisToString(timelineData.timeWaitingForMainThread, true));
-    }
-
-    const relatedNode = relatedNodesMap && relatedNodesMap.get(timelineData.backendNodeId);
-    if (relatedNode) {
-      const nodeSpan = await Common.Linkifier.linkify(relatedNode);
-      contentHelper.appendElementRow(relatedNodeLabel || Common.UIString('Related Node'), nodeSpan);
-    }
-
-    if (event[Timeline.TimelineUIUtils._previewElementSymbol]) {
-      contentHelper.addSection(Common.UIString('Preview'));
-      contentHelper.appendElementRow('', event[Timeline.TimelineUIUtils._previewElementSymbol]);
-    }
-
-    if (initiator || timelineData.stackTraceForSelfOrInitiator() ||
-        TimelineModel.InvalidationTracker.invalidationEventsFor(event))
-      Timeline.TimelineUIUtils._generateCauses(event, model.targetByEvent(event), relatedNodesMap, contentHelper);
-
-    const stats = {};
-    const showPieChart = detailed && Timeline.TimelineUIUtils._aggregatedStatsForTraceEvent(stats, model, event);
-    if (showPieChart) {
-      contentHelper.addSection(Common.UIString('Aggregated Time'));
-      const pieChart = Timeline.TimelineUIUtils.generatePieChart(
-          stats, Timeline.TimelineUIUtils.eventStyle(event).category, event.selfTime);
-      contentHelper.appendElementRow('', pieChart);
-    }
-
-    return contentHelper.fragment;
-  }
-
-  /**
-   * @param {!Timeline.TimelineDetailsContentHelper} contentHelper
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @param {?string} url
-   */
-  static _maybeAppendProductToDetails(contentHelper, badgePool, url) {
-    const parsedURL = url ? url.asParsedURL() : null;
-    if (parsedURL)
-      contentHelper.appendElementRow('', badgePool.badgeForURL(parsedURL));
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {number} startTime
-   * @param {number} endTime
-   * @return {!Object<string, number>}
-   */
-  static statsForTimeRange(events, startTime, endTime) {
-    if (!events.length)
-      return {'idle': endTime - startTime};
-    const symbol = Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol;
-    Timeline.TimelineUIUtils._buildRangeStatsCacheIfNeeded(events);
-
-    const before = findCachedStatsAfterTime(startTime);
-    const statsBefore =
-        subtractStats(before.stats, Timeline.TimelineUIUtils._slowStatsForTimeRange(events, startTime, before.time));
-
-    const after = findCachedStatsAfterTime(endTime);
-    const statsAfter =
-        subtractStats(after.stats, Timeline.TimelineUIUtils._slowStatsForTimeRange(events, endTime, after.time));
-
-    const aggregatedStats = subtractStats(statsAfter, statsBefore);
-    const aggregatedTotal = Object.values(aggregatedStats).reduce((a, b) => a + b, 0);
-    aggregatedStats['idle'] = Math.max(0, endTime - startTime - aggregatedTotal);
-    return aggregatedStats;
-
-    /**
-     * @param {number} atTime
-     * @return {!{time: number, stats: !Object<string, number>}}
-     */
-    function findCachedStatsAfterTime(atTime) {
-      let index = events.lowerBound(atTime, (time, event) => time - (event.endTime || event.startTime));
-      while (index < events.length && !events[index][symbol])
-        index++;
-      if (index === events.length) {
-        const lastEvent = events.peekLast();
-        return {time: lastEvent.endTime || lastEvent.startTime, stats: events[symbol]};
-      }
-      const event = events[index];
-      return {time: event.endTime || event.startTime, stats: event[symbol]};
-    }
-
-    /**
-      * @param {!Object<string, number>} a
-      * @param {!Object<string, number>} b
-      * @return {!Object<string, number>}
-      */
-    function subtractStats(a, b) {
-      const result = Object.assign({}, a);
-      for (const key in b)
-        result[key] -= b[key];
-      return result;
-    }
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {number} startTime
-   * @param {number} endTime
-   */
-  static _slowStatsForTimeRange(events, startTime, endTime) {
-    /** @type {!Object<string, number>} */
-    const stats = {};
-    const ownTimes = [];
-
-    TimelineModel.TimelineModel.forEachEvent(
-        events, onStartEvent, onEndEvent, undefined, startTime, endTime, Timeline.TimelineUIUtils._filterForStats());
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onStartEvent(e) {
-      const duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startTime);
-      if (ownTimes.length)
-        ownTimes[ownTimes.length - 1] -= duration;
-      ownTimes.push(duration);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onEndEvent(e) {
-      const category = Timeline.TimelineUIUtils.eventStyle(e).category.name;
-      stats[category] = (stats[category] || 0) + ownTimes.pop();
-    }
-    return stats;
-  }
-
-  /**
-   * @return {function(!SDK.TracingModel.Event):boolean}
-   */
-  static _filterForStats() {
-    const visibleEventsFilter = Timeline.TimelineUIUtils.visibleEventsFilter();
-    return event => visibleEventsFilter.accept(event) || SDK.TracingModel.isTopLevelEvent(event);
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   */
-  static _buildRangeStatsCacheIfNeeded(events) {
-    if (events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol])
-      return;
-
-    const aggregatedStats = {};
-    const ownTimes = [];
-    TimelineModel.TimelineModel.forEachEvent(
-        events, onStartEvent, onEndEvent, undefined, undefined, undefined, Timeline.TimelineUIUtils._filterForStats());
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onStartEvent(e) {
-      if (ownTimes.length)
-        ownTimes[ownTimes.length - 1] -= e.duration;
-      ownTimes.push(e.duration);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onEndEvent(e) {
-      const category = Timeline.TimelineUIUtils.eventStyle(e).category.name;
-      aggregatedStats[category] = (aggregatedStats[category] || 0) + ownTimes.pop();
-      if (!ownTimes.length)
-        e[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = Object.assign({}, aggregatedStats);
-    }
-
-    const obj = /** @type {!Object} */ (events);
-    obj[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = Object.assign({}, aggregatedStats);
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel.NetworkRequest} request
-   * @param {!TimelineModel.TimelineModel} model
-   * @param {!Components.Linkifier} linkifier
-   * @param {!ProductRegistry.BadgePool} badgePool
-   * @return {!Promise<!DocumentFragment>}
-   */
-  static async buildNetworkRequestDetails(request, model, linkifier, badgePool) {
-    const target = model.targetByEvent(request.children[0]);
-    const contentHelper = new Timeline.TimelineDetailsContentHelper(target, linkifier);
-    const category = Timeline.TimelineUIUtils.networkRequestCategory(request);
-    const color = Timeline.TimelineUIUtils.networkCategoryColor(category);
-    contentHelper.addSection(Common.UIString('Network request'), color);
-
-    const duration = request.endTime - (request.startTime || -Infinity);
-    if (request.url)
-      contentHelper.appendElementRow(Common.UIString('URL'), Components.Linkifier.linkifyURL(request.url));
-    Timeline.TimelineUIUtils._maybeAppendProductToDetails(contentHelper, badgePool, request.url);
-    if (isFinite(duration))
-      contentHelper.appendTextRow(Common.UIString('Duration'), Number.millisToString(duration, true));
-    if (request.requestMethod)
-      contentHelper.appendTextRow(Common.UIString('Request Method'), request.requestMethod);
-    if (typeof request.priority === 'string') {
-      const priority =
-          PerfUI.uiLabelForNetworkPriority(/** @type {!Protocol.Network.ResourcePriority} */ (request.priority));
-      contentHelper.appendTextRow(Common.UIString('Priority'), priority);
-    }
-    if (request.mimeType)
-      contentHelper.appendTextRow(Common.UIString('Mime Type'), request.mimeType);
-    let lengthText = '';
-    if (request.fromCache)
-      lengthText += Common.UIString(' (from cache)');
-    if (request.fromServiceWorker)
-      lengthText += Common.UIString(' (from service worker)');
-    if (request.encodedDataLength || !lengthText)
-      lengthText = `${Number.bytesToString(request.encodedDataLength)}${lengthText}`;
-    contentHelper.appendTextRow(Common.UIString('Encoded Data'), lengthText);
-    if (request.decodedBodyLength)
-      contentHelper.appendTextRow(Common.UIString('Decoded Body'), Number.bytesToString(request.decodedBodyLength));
-    const title = Common.UIString('Initiator');
-    const sendRequest = request.children[0];
-    const topFrame = TimelineModel.TimelineData.forEvent(sendRequest).topFrame();
-    if (topFrame) {
-      const link = linkifier.maybeLinkifyConsoleCallFrame(target, topFrame);
-      if (link)
-        contentHelper.appendElementRow(title, link);
-    } else {
-      const initiator = TimelineModel.TimelineData.forEvent(sendRequest).initiator();
-      if (initiator) {
-        const initiatorURL = TimelineModel.TimelineData.forEvent(initiator).url;
-        if (initiatorURL) {
-          const link = linkifier.maybeLinkifyScriptLocation(target, null, initiatorURL, 0);
-          if (link)
-            contentHelper.appendElementRow(title, link);
-        }
-      }
-    }
-
-    if (!request.previewElement && request.url && target)
-      request.previewElement = await BrowserComponents.ImagePreview.build(target, request.url, false);
-    if (request.previewElement)
-      contentHelper.appendElementRow(Common.UIString('Preview'), request.previewElement);
-    return contentHelper.fragment;
-  }
-
-  /**
-   * @param {!Array<!Protocol.Runtime.CallFrame>} callFrames
-   * @return {!Protocol.Runtime.StackTrace}
-   */
-  static _stackTraceFromCallFrames(callFrames) {
-    return /** @type {!Protocol.Runtime.StackTrace} */ ({callFrames: callFrames});
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {?SDK.Target} target
-   * @param {?Map<number, ?SDK.DOMNode>} relatedNodesMap
-   * @param {!Timeline.TimelineDetailsContentHelper} contentHelper
-   */
-  static _generateCauses(event, target, relatedNodesMap, contentHelper) {
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-
-    let callSiteStackLabel;
-    let stackLabel;
-
-    switch (event.name) {
-      case recordTypes.TimerFire:
-        callSiteStackLabel = Common.UIString('Timer Installed');
-        break;
-      case recordTypes.FireAnimationFrame:
-        callSiteStackLabel = Common.UIString('Animation Frame Requested');
-        break;
-      case recordTypes.FireIdleCallback:
-        callSiteStackLabel = Common.UIString('Idle Callback Requested');
-        break;
-      case recordTypes.UpdateLayoutTree:
-      case recordTypes.RecalculateStyles:
-        stackLabel = Common.UIString('Recalculation Forced');
-        break;
-      case recordTypes.Layout:
-        callSiteStackLabel = Common.UIString('First Layout Invalidation');
-        stackLabel = Common.UIString('Layout Forced');
-        break;
-    }
-
-    const timelineData = TimelineModel.TimelineData.forEvent(event);
-    // Direct cause.
-    if (timelineData.stackTrace && timelineData.stackTrace.length) {
-      contentHelper.addSection(Common.UIString('Call Stacks'));
-      contentHelper.appendStackTrace(
-          stackLabel || Common.UIString('Stack Trace'),
-          Timeline.TimelineUIUtils._stackTraceFromCallFrames(timelineData.stackTrace));
-    }
-
-    const initiator = TimelineModel.TimelineData.forEvent(event).initiator();
-    // Indirect causes.
-    if (TimelineModel.InvalidationTracker.invalidationEventsFor(event) && target) {
-      // Full invalidation tracking (experimental).
-      contentHelper.addSection(Common.UIString('Invalidations'));
-      Timeline.TimelineUIUtils._generateInvalidations(event, target, relatedNodesMap, contentHelper);
-    } else if (initiator) {  // Partial invalidation tracking.
-      const delay = event.startTime - initiator.startTime;
-      contentHelper.appendTextRow(Common.UIString('Pending for'), Number.preciseMillisToString(delay, 1));
-
-      const link = createElementWithClass('span', 'devtools-link');
-      link.textContent = Common.UIString('reveal');
-      link.addEventListener('click', () => {
-        Timeline.TimelinePanel.instance().select(
-            Timeline.TimelineSelection.fromTraceEvent(/** @type {!SDK.TracingModel.Event} */ (initiator)));
-      });
-      contentHelper.appendElementRow(Common.UIString('Initiator'), link);
-
-      const initiatorStackTrace = TimelineModel.TimelineData.forEvent(initiator).stackTrace;
-      if (initiatorStackTrace) {
-        contentHelper.appendStackTrace(
-            callSiteStackLabel || Common.UIString('First Invalidated'),
-            Timeline.TimelineUIUtils._stackTraceFromCallFrames(initiatorStackTrace));
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {!SDK.Target} target
-   * @param {?Map<number, ?SDK.DOMNode>} relatedNodesMap
-   * @param {!Timeline.TimelineDetailsContentHelper} contentHelper
-   */
-  static _generateInvalidations(event, target, relatedNodesMap, contentHelper) {
-    const invalidationTrackingEvents = TimelineModel.InvalidationTracker.invalidationEventsFor(event);
-    const invalidations = {};
-    invalidationTrackingEvents.forEach(function(invalidation) {
-      if (!invalidations[invalidation.type])
-        invalidations[invalidation.type] = [invalidation];
-      else
-        invalidations[invalidation.type].push(invalidation);
-    });
-
-    Object.keys(invalidations).forEach(function(type) {
-      Timeline.TimelineUIUtils._generateInvalidationsForType(
-          type, target, invalidations[type], relatedNodesMap, contentHelper);
-    });
-  }
-
-  /**
-   * @param {string} type
-   * @param {!SDK.Target} target
-   * @param {!Array.<!TimelineModel.InvalidationTrackingEvent>} invalidations
-   * @param {?Map<number, ?SDK.DOMNode>} relatedNodesMap
-   * @param {!Timeline.TimelineDetailsContentHelper} contentHelper
-   */
-  static _generateInvalidationsForType(type, target, invalidations, relatedNodesMap, contentHelper) {
-    let title;
-    switch (type) {
-      case TimelineModel.TimelineModel.RecordType.StyleRecalcInvalidationTracking:
-        title = Common.UIString('Style Invalidations');
-        break;
-      case TimelineModel.TimelineModel.RecordType.LayoutInvalidationTracking:
-        title = Common.UIString('Layout Invalidations');
-        break;
-      default:
-        title = Common.UIString('Other Invalidations');
-        break;
-    }
-
-    const invalidationsTreeOutline = new UI.TreeOutlineInShadow();
-    invalidationsTreeOutline.registerRequiredCSS('timeline/invalidationsTree.css');
-    invalidationsTreeOutline.element.classList.add('invalidations-tree');
-
-    const invalidationGroups = groupInvalidationsByCause(invalidations);
-    invalidationGroups.forEach(function(group) {
-      const groupElement =
-          new Timeline.TimelineUIUtils.InvalidationsGroupElement(target, relatedNodesMap, contentHelper, group);
-      invalidationsTreeOutline.appendChild(groupElement);
-    });
-    contentHelper.appendElementRow(title, invalidationsTreeOutline.element, false, true);
-
-    /**
-     * @param {!Array<!TimelineModel.InvalidationTrackingEvent>} invalidations
-     * @return {!Array<!Array<!TimelineModel.InvalidationTrackingEvent>>}
-     */
-    function groupInvalidationsByCause(invalidations) {
-      /** @type {!Map<string, !Array<!TimelineModel.InvalidationTrackingEvent>>} */
-      const causeToInvalidationMap = new Map();
-      for (let index = 0; index < invalidations.length; index++) {
-        const invalidation = invalidations[index];
-        let causeKey = '';
-        if (invalidation.cause.reason)
-          causeKey += invalidation.cause.reason + '.';
-        if (invalidation.cause.stackTrace) {
-          invalidation.cause.stackTrace.forEach(function(stackFrame) {
-            causeKey += stackFrame['functionName'] + '.';
-            causeKey += stackFrame['scriptId'] + '.';
-            causeKey += stackFrame['url'] + '.';
-            causeKey += stackFrame['lineNumber'] + '.';
-            causeKey += stackFrame['columnNumber'] + '.';
-          });
-        }
-
-        if (causeToInvalidationMap.has(causeKey))
-          causeToInvalidationMap.get(causeKey).push(invalidation);
-        else
-          causeToInvalidationMap.set(causeKey, [invalidation]);
-      }
-      return causeToInvalidationMap.valuesArray();
-    }
-  }
-
-  /**
-   * @param {!Set<number>} nodeIds
-   * @param {!Array<!TimelineModel.InvalidationTrackingEvent>} invalidations
-   */
-  static _collectInvalidationNodeIds(nodeIds, invalidations) {
-    nodeIds.addAll(invalidations.map(invalidation => invalidation.nodeId).filter(id => id));
-  }
-
-  /**
-   * @param {!Object} total
-   * @param {!TimelineModel.TimelineModel} model
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  static _aggregatedStatsForTraceEvent(total, model, event) {
-    const events = model.inspectedTargetEvents();
-    /**
-     * @param {number} startTime
-     * @param {!SDK.TracingModel.Event} e
-     * @return {number}
-     */
-    function eventComparator(startTime, e) {
-      return startTime - e.startTime;
-    }
-    const index = events.binaryIndexOf(event.startTime, eventComparator);
-    // Not a main thread event?
-    if (index < 0)
-      return false;
-    let hasChildren = false;
-    const endTime = event.endTime;
-    if (endTime) {
-      for (let i = index; i < events.length; i++) {
-        const nextEvent = events[i];
-        if (nextEvent.startTime >= endTime)
-          break;
-        if (!nextEvent.selfTime)
-          continue;
-        if (nextEvent.thread !== event.thread)
-          continue;
-        if (i > index)
-          hasChildren = true;
-        const categoryName = Timeline.TimelineUIUtils.eventStyle(nextEvent).category.name;
-        total[categoryName] = (total[categoryName] || 0) + nextEvent.selfTime;
-      }
-    }
-    if (SDK.TracingModel.isAsyncPhase(event.phase)) {
-      if (event.endTime) {
-        let aggregatedTotal = 0;
-        for (const categoryName in total)
-          aggregatedTotal += total[categoryName];
-        total['idle'] = Math.max(0, event.endTime - event.startTime - aggregatedTotal);
-      }
-      return false;
-    }
-    return hasChildren;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {!SDK.Target} target
-   * @return {!Promise<?Element>}
-   */
-  static async buildPicturePreviewContent(event, target) {
-    const snapshotWithRect = await new TimelineModel.LayerPaintEvent(event, target).snapshotPromise();
-    if (!snapshotWithRect)
-      return null;
-    const imageURLPromise = snapshotWithRect.snapshot.replay();
-    snapshotWithRect.snapshot.release();
-    const imageURL = await imageURLPromise;
-    if (!imageURL)
-      return null;
-    const container = createElement('div');
-    UI.appendStyle(container, 'browser_components/imagePreview.css');
-    container.classList.add('image-preview-container', 'vbox', 'link');
-    const img = container.createChild('img');
-    img.src = imageURL;
-    const paintProfilerButton = container.createChild('a');
-    paintProfilerButton.textContent = Common.UIString('Paint Profiler');
-    container.addEventListener(
-        'click', () => Timeline.TimelinePanel.instance().select(Timeline.TimelineSelection.fromTraceEvent(event)),
-        false);
-    return container;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {number} zeroTime
-   * @return {!Element}
-   */
-  static createEventDivider(event, zeroTime) {
-    const eventDivider = createElementWithClass('div', 'resources-event-divider');
-    const startTime = Number.millisToString(event.startTime - zeroTime);
-    eventDivider.title = Common.UIString('%s at %s', Timeline.TimelineUIUtils.eventTitle(event), startTime);
-    const style = Timeline.TimelineUIUtils.markerStyleForEvent(event);
-    if (style.tall)
-      eventDivider.style.backgroundColor = style.color;
-    return eventDivider;
-  }
-
-  /**
-   * @return {!Array.<string>}
-   */
-  static _visibleTypes() {
-    const eventStyles = Timeline.TimelineUIUtils._initEventStyles();
-    const result = [];
-    for (const name in eventStyles) {
-      if (!eventStyles[name].hidden)
-        result.push(name);
-    }
-    return result;
-  }
-
-  /**
-   * @return {!TimelineModel.TimelineModelFilter}
-   */
-  static visibleEventsFilter() {
-    return new TimelineModel.TimelineVisibleEventsFilter(Timeline.TimelineUIUtils._visibleTypes());
-  }
-
-  /**
-   * @return {!TimelineModel.TimelineModelFilter}
-   */
-  static paintEventsFilter() {
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    return new TimelineModel.TimelineInvisibleEventsFilter(
-        !Runtime.experiments.isEnabled('timelinePaintTimingMarkers') ?
-            [recordTypes.MarkFCP, recordTypes.MarkFMP, recordTypes.MarkFMPCandidate] :
-            []);
-  }
-
-  /**
-   * @return {!Object.<string, !Timeline.TimelineCategory>}
-   */
-  static categories() {
-    if (Timeline.TimelineUIUtils._categories)
-      return Timeline.TimelineUIUtils._categories;
-    Timeline.TimelineUIUtils._categories = {
-      loading: new Timeline.TimelineCategory(
-          'loading', Common.UIString('Loading'), true, 'hsl(214, 67%, 74%)', 'hsl(214, 67%, 66%)'),
-      scripting: new Timeline.TimelineCategory(
-          'scripting', Common.UIString('Scripting'), true, 'hsl(43, 83%, 72%)', 'hsl(43, 83%, 64%) '),
-      rendering: new Timeline.TimelineCategory(
-          'rendering', Common.UIString('Rendering'), true, 'hsl(256, 67%, 76%)', 'hsl(256, 67%, 70%)'),
-      painting: new Timeline.TimelineCategory(
-          'painting', Common.UIString('Painting'), true, 'hsl(109, 33%, 64%)', 'hsl(109, 33%, 55%)'),
-      gpu: new Timeline.TimelineCategory(
-          'gpu', Common.UIString('GPU'), false, 'hsl(109, 33%, 64%)', 'hsl(109, 33%, 55%)'),
-      async: new Timeline.TimelineCategory(
-          'async', Common.UIString('Async'), false, 'hsl(0, 100%, 50%)', 'hsl(0, 100%, 40%)'),
-      other:
-          new Timeline.TimelineCategory('other', Common.UIString('Other'), false, 'hsl(0, 0%, 87%)', 'hsl(0, 0%, 79%)'),
-      idle: new Timeline.TimelineCategory('idle', Common.UIString('Idle'), false, 'hsl(0, 0%, 98%)', 'hsl(0, 0%, 98%)')
-    };
-    return Timeline.TimelineUIUtils._categories;
-  }
-
-  /**
-   * @param {!Object} aggregatedStats
-   * @param {!Timeline.TimelineCategory=} selfCategory
-   * @param {number=} selfTime
-   * @return {!Element}
-   */
-  static generatePieChart(aggregatedStats, selfCategory, selfTime) {
-    let total = 0;
-    for (const categoryName in aggregatedStats)
-      total += aggregatedStats[categoryName];
-
-    const element = createElementWithClass('div', 'timeline-details-view-pie-chart-wrapper hbox');
-    const pieChart = new PerfUI.PieChart(110, value => Number.preciseMillisToString(value), true);
-    pieChart.element.classList.add('timeline-details-view-pie-chart');
-    pieChart.setTotal(total);
-    const pieChartContainer = element.createChild('div', 'vbox');
-    pieChartContainer.appendChild(pieChart.element);
-    const footerElement = element.createChild('div', 'timeline-aggregated-info-legend');
-
-    /**
-     * @param {string} name
-     * @param {string} title
-     * @param {number} value
-     * @param {string} color
-     */
-    function appendLegendRow(name, title, value, color) {
-      if (!value)
-        return;
-      pieChart.addSlice(value, color);
-      const rowElement = footerElement.createChild('div');
-      rowElement.createChild('span', 'timeline-aggregated-legend-value').textContent =
-          Number.preciseMillisToString(value, 1);
-      rowElement.createChild('span', 'timeline-aggregated-legend-swatch').style.backgroundColor = color;
-      rowElement.createChild('span', 'timeline-aggregated-legend-title').textContent = title;
-    }
-
-    // In case of self time, first add self, then children of the same category.
-    if (selfCategory) {
-      if (selfTime) {
-        appendLegendRow(
-            selfCategory.name, Common.UIString('%s (self)', selfCategory.title), selfTime, selfCategory.color);
-      }
-      // Children of the same category.
-      const categoryTime = aggregatedStats[selfCategory.name];
-      const value = categoryTime - selfTime;
-      if (value > 0) {
-        appendLegendRow(
-            selfCategory.name, Common.UIString('%s (children)', selfCategory.title), value, selfCategory.childColor);
-      }
-    }
-
-    // Add other categories.
-    for (const categoryName in Timeline.TimelineUIUtils.categories()) {
-      const category = Timeline.TimelineUIUtils.categories()[categoryName];
-      if (category === selfCategory)
-        continue;
-      appendLegendRow(category.name, category.title, aggregatedStats[category.name], category.childColor);
-    }
-    return element;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineFrame} frame
-   * @param {?SDK.FilmStripModel.Frame} filmStripFrame
-   * @return {!Element}
-   */
-  static generateDetailsContentForFrame(frame, filmStripFrame) {
-    const contentHelper = new Timeline.TimelineDetailsContentHelper(null, null);
-    contentHelper.addSection(Common.UIString('Frame'));
-
-    const duration = Timeline.TimelineUIUtils.frameDuration(frame);
-    contentHelper.appendElementRow(Common.UIString('Duration'), duration, frame.hasWarnings());
-    const durationInMillis = frame.endTime - frame.startTime;
-    contentHelper.appendTextRow(Common.UIString('FPS'), Math.floor(1000 / durationInMillis));
-    contentHelper.appendTextRow(Common.UIString('CPU time'), Number.millisToString(frame.cpuTime, true));
-    if (filmStripFrame) {
-      const filmStripPreview = createElementWithClass('div', 'timeline-filmstrip-preview');
-      filmStripFrame.imageDataPromise()
-          .then(data => UI.loadImageFromData(data))
-          .then(image => image && filmStripPreview.appendChild(image));
-      contentHelper.appendElementRow('', filmStripPreview);
-      filmStripPreview.addEventListener('click', frameClicked.bind(null, filmStripFrame), false);
-    }
-
-    if (frame.layerTree) {
-      contentHelper.appendElementRow(
-          Common.UIString('Layer tree'),
-          Components.Linkifier.linkifyRevealable(frame.layerTree, Common.UIString('show')));
-    }
-
-    /**
-     * @param {!SDK.FilmStripModel.Frame} filmStripFrame
-     */
-    function frameClicked(filmStripFrame) {
-      new PerfUI.FilmStripView.Dialog(filmStripFrame, 0);
-    }
-
-    return contentHelper.fragment;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineFrame} frame
-   * @return {!Element}
-   */
-  static frameDuration(frame) {
-    const durationText = Common.UIString(
-        '%s (at %s)', Number.millisToString(frame.endTime - frame.startTime, true),
-        Number.millisToString(frame.startTimeOffset, true));
-    const element = createElement('span');
-    element.createTextChild(durationText);
-    if (!frame.hasWarnings())
-      return element;
-    element.createTextChild(Common.UIString('. Long frame times are an indication of '));
-    element.appendChild(UI.XLink.create(
-        'https://developers.google.com/web/fundamentals/performance/rendering/', Common.UIString('jank')));
-    element.createTextChild('.');
-    return element;
-  }
-
-  /**
-   * @param {!CanvasRenderingContext2D} context
-   * @param {number} width
-   * @param {number} height
-   * @param {string} color0
-   * @param {string} color1
-   * @param {string} color2
-   * @return {!CanvasGradient}
-   */
-  static createFillStyle(context, width, height, color0, color1, color2) {
-    const gradient = context.createLinearGradient(0, 0, width, height);
-    gradient.addColorStop(0, color0);
-    gradient.addColorStop(0.25, color1);
-    gradient.addColorStop(0.75, color1);
-    gradient.addColorStop(1, color2);
-    return gradient;
-  }
-
-  /**
-   * @param {!Array.<number>} quad
-   * @return {number}
-   */
-  static quadWidth(quad) {
-    return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1] - quad[3], 2)));
-  }
-
-  /**
-   * @param {!Array.<number>} quad
-   * @return {number}
-   */
-  static quadHeight(quad) {
-    return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1] - quad[7], 2)));
-  }
-
-  /**
-   * @return {!Array.<!Timeline.TimelineUIUtils.EventDispatchTypeDescriptor>}
-   */
-  static eventDispatchDesciptors() {
-    if (Timeline.TimelineUIUtils._eventDispatchDesciptors)
-      return Timeline.TimelineUIUtils._eventDispatchDesciptors;
-    const lightOrange = 'hsl(40,100%,80%)';
-    const orange = 'hsl(40,100%,50%)';
-    const green = 'hsl(90,100%,40%)';
-    const purple = 'hsl(256,100%,75%)';
-    Timeline.TimelineUIUtils._eventDispatchDesciptors = [
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(
-          1, lightOrange, ['mousemove', 'mouseenter', 'mouseleave', 'mouseout', 'mouseover']),
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(
-          1, lightOrange, ['pointerover', 'pointerout', 'pointerenter', 'pointerleave', 'pointermove']),
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(2, green, ['wheel']),
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(3, orange, ['click', 'mousedown', 'mouseup']),
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(
-          3, orange, ['touchstart', 'touchend', 'touchmove', 'touchcancel']),
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(
-          3, orange, ['pointerdown', 'pointerup', 'pointercancel', 'gotpointercapture', 'lostpointercapture']),
-      new Timeline.TimelineUIUtils.EventDispatchTypeDescriptor(3, purple, ['keydown', 'keyup', 'keypress'])
-    ];
-    return Timeline.TimelineUIUtils._eventDispatchDesciptors;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {!Timeline.TimelineMarkerStyle}
-   */
-  static markerStyleForEvent(event) {
-    const tallMarkerDashStyle = [10, 5];
-    const title = Timeline.TimelineUIUtils.eventTitle(event);
-
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.Console) ||
-        event.hasCategory(TimelineModel.TimelineModel.Category.UserTiming)) {
-      return {
-        title: title,
-        dashStyle: tallMarkerDashStyle,
-        lineWidth: 0.5,
-        color: event.hasCategory(TimelineModel.TimelineModel.Category.UserTiming) ? 'purple' : 'orange',
-        tall: false,
-        lowPriority: false,
-      };
-    }
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    let tall = false;
-    let color = 'green';
-    switch (event.name) {
-      case recordTypes.MarkDOMContent:
-        color = 'blue';
-        tall = true;
-        break;
-      case recordTypes.MarkLoad:
-        color = 'red';
-        tall = true;
-        break;
-      case recordTypes.MarkFirstPaint:
-        color = 'hsl(180, 45%, 79%)';
-        tall = true;
-        break;
-      case recordTypes.MarkFCP:
-        color = 'hsl(160, 43%, 58%)';
-        tall = true;
-        break;
-      case recordTypes.MarkFMPCandidate:
-        color = 'hsl(146, 57%, 40%)';
-        tall = true;
-        break;
-      case recordTypes.MarkFMP:
-        color = 'hsl(144, 100%, 21%)';
-        tall = true;
-        break;
-      case recordTypes.TimeStamp:
-        color = 'orange';
-        break;
-    }
-    return {
-      title: title,
-      dashStyle: tallMarkerDashStyle,
-      lineWidth: 0.5,
-      color: color,
-      tall: tall,
-      lowPriority: false,
-    };
-  }
-
-  /**
-   * @return {!Timeline.TimelineMarkerStyle}
-   */
-  static markerStyleForFrame() {
-    return {
-      title: Common.UIString('Frame'),
-      color: 'rgba(100, 100, 100, 0.4)',
-      lineWidth: 3,
-      dashStyle: [3],
-      tall: true,
-      lowPriority: true
-    };
-  }
-
-  /**
-   * @param {string} id
-   * @return {string}
-   */
-  static colorForId(id) {
-    if (!Timeline.TimelineUIUtils.colorForId._colorGenerator) {
-      Timeline.TimelineUIUtils.colorForId._colorGenerator =
-          new Common.Color.Generator({min: 30, max: 330}, {min: 50, max: 80, count: 3}, 85);
-      Timeline.TimelineUIUtils.colorForId._colorGenerator.setColorForID('', '#f2ecdc');
-    }
-    return Timeline.TimelineUIUtils.colorForId._colorGenerator.colorForID(id);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {string=} warningType
-   * @return {?Element}
-   */
-  static eventWarning(event, warningType) {
-    const timelineData = TimelineModel.TimelineData.forEvent(event);
-    const warning = warningType || timelineData.warning;
-    if (!warning)
-      return null;
-    const warnings = TimelineModel.TimelineModel.WarningType;
-    const span = createElement('span');
-    const eventData = event.args['data'];
-
-    switch (warning) {
-      case warnings.ForcedStyle:
-      case warnings.ForcedLayout:
-        span.appendChild(UI.createDocumentationLink(
-            '../../fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts',
-            Common.UIString('Forced reflow')));
-        span.createTextChild(Common.UIString(' is a likely performance bottleneck.'));
-        break;
-      case warnings.IdleDeadlineExceeded:
-        span.textContent = Common.UIString(
-            'Idle callback execution extended beyond deadline by ' +
-            Number.millisToString(event.duration - eventData['allottedMilliseconds'], true));
-        break;
-      case warnings.LongHandler:
-        span.textContent = Common.UIString('Handler took %s', Number.millisToString(event.duration, true));
-        break;
-      case warnings.LongRecurringHandler:
-        span.textContent = Common.UIString('Recurring handler took %s', Number.millisToString(event.duration, true));
-        break;
-      case warnings.V8Deopt:
-        span.appendChild(UI.XLink.create(
-            'https://github.com/GoogleChrome/devtools-docs/issues/53', Common.UIString('Not optimized')));
-        span.createTextChild(Common.UIString(': %s', eventData['deoptReason']));
-        break;
-      default:
-        console.assert(false, 'Unhandled TimelineModel.WarningType');
-    }
-    return span;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel.PageFrame} frame
-   * @param {number=} trimAt
-   */
-  static displayNameForFrame(frame, trimAt) {
-    const url = frame.url;
-    if (!trimAt)
-      trimAt = 30;
-    return url.startsWith('about:') ? `"${frame.name.trimMiddle(trimAt)}"` : frame.url.trimEnd(trimAt);
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineRecordStyle = class {
-  /**
-   * @param {string} title
-   * @param {!Timeline.TimelineCategory} category
-   * @param {boolean=} hidden
-   */
-  constructor(title, category, hidden) {
-    this.title = title;
-    this.category = category;
-    this.hidden = !!hidden;
-  }
-};
-
-
-/**
- * @enum {symbol}
- */
-Timeline.TimelineUIUtils.NetworkCategory = {
-  HTML: Symbol('HTML'),
-  Script: Symbol('Script'),
-  Style: Symbol('Style'),
-  Media: Symbol('Media'),
-  Other: Symbol('Other')
-};
-
-
-Timeline.TimelineUIUtils._aggregatedStatsKey = Symbol('aggregatedStats');
-
-
-/**
- * @unrestricted
- */
-Timeline.TimelineUIUtils.InvalidationsGroupElement = class extends UI.TreeElement {
-  /**
-   * @param {!SDK.Target} target
-   * @param {?Map<number, ?SDK.DOMNode>} relatedNodesMap
-   * @param {!Timeline.TimelineDetailsContentHelper} contentHelper
-   * @param {!Array.<!TimelineModel.InvalidationTrackingEvent>} invalidations
-   */
-  constructor(target, relatedNodesMap, contentHelper, invalidations) {
-    super('', true);
-
-    this.listItemElement.classList.add('header');
-    this.selectable = false;
-    this.toggleOnClick = true;
-
-    this._relatedNodesMap = relatedNodesMap;
-    this._contentHelper = contentHelper;
-    this._invalidations = invalidations;
-    this.title = this._createTitle(target);
-  }
-
-  /**
-   * @param {!SDK.Target} target
-   * @return {!Element}
-   */
-  _createTitle(target) {
-    const first = this._invalidations[0];
-    const reason = first.cause.reason;
-    const topFrame = first.cause.stackTrace && first.cause.stackTrace[0];
-
-    const title = createElement('span');
-    if (reason)
-      title.createTextChild(Common.UIString('%s for ', reason));
-    else
-      title.createTextChild(Common.UIString('Unknown cause for '));
-
-    this._appendTruncatedNodeList(title, this._invalidations);
-
-    if (topFrame && this._contentHelper.linkifier()) {
-      title.createTextChild(Common.UIString('. '));
-      const stack = title.createChild('span', 'monospace');
-      stack.createChild('span').textContent = Timeline.TimelineUIUtils.frameDisplayName(topFrame);
-      const link = this._contentHelper.linkifier().maybeLinkifyConsoleCallFrame(target, topFrame);
-      if (link) {
-        stack.createChild('span').textContent = ' @ ';
-        stack.createChild('span').appendChild(link);
-      }
-    }
-
-    return title;
-  }
-
-  /**
-   * @override
-   */
-  onpopulate() {
-    const content = createElementWithClass('div', 'content');
-
-    const first = this._invalidations[0];
-    if (first.cause.stackTrace) {
-      const stack = content.createChild('div');
-      stack.createTextChild(Common.UIString('Stack trace:'));
-      this._contentHelper.createChildStackTraceElement(
-          stack, Timeline.TimelineUIUtils._stackTraceFromCallFrames(first.cause.stackTrace));
-    }
-
-    content.createTextChild(this._invalidations.length > 1 ? Common.UIString('Nodes:') : Common.UIString('Node:'));
-    const nodeList = content.createChild('div', 'node-list');
-    let firstNode = true;
-    for (let i = 0; i < this._invalidations.length; i++) {
-      const invalidation = this._invalidations[i];
-      const invalidationNode = this._createInvalidationNode(invalidation, true);
-      if (invalidationNode) {
-        if (!firstNode)
-          nodeList.createTextChild(Common.UIString(', '));
-        firstNode = false;
-
-        nodeList.appendChild(invalidationNode);
-
-        const extraData = invalidation.extraData ? ', ' + invalidation.extraData : '';
-        if (invalidation.changedId) {
-          nodeList.createTextChild(Common.UIString('(changed id to "%s"%s)', invalidation.changedId, extraData));
-        } else if (invalidation.changedClass) {
-          nodeList.createTextChild(Common.UIString('(changed class to "%s"%s)', invalidation.changedClass, extraData));
-        } else if (invalidation.changedAttribute) {
-          nodeList.createTextChild(
-              Common.UIString('(changed attribute to "%s"%s)', invalidation.changedAttribute, extraData));
-        } else if (invalidation.changedPseudo) {
-          nodeList.createTextChild(
-              Common.UIString('(changed pesudo to "%s"%s)', invalidation.changedPseudo, extraData));
-        } else if (invalidation.selectorPart) {
-          nodeList.createTextChild(Common.UIString('(changed "%s"%s)', invalidation.selectorPart, extraData));
-        }
-      }
-    }
-
-    const contentTreeElement = new UI.TreeElement(content, false);
-    contentTreeElement.selectable = false;
-    this.appendChild(contentTreeElement);
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Array.<!TimelineModel.InvalidationTrackingEvent>} invalidations
-   */
-  _appendTruncatedNodeList(parentElement, invalidations) {
-    const invalidationNodes = [];
-    const invalidationNodeIdMap = {};
-    for (let i = 0; i < invalidations.length; i++) {
-      const invalidation = invalidations[i];
-      const invalidationNode = this._createInvalidationNode(invalidation, false);
-      invalidationNode.addEventListener('click', e => e.consume(), false);
-      if (invalidationNode && !invalidationNodeIdMap[invalidation.nodeId]) {
-        invalidationNodes.push(invalidationNode);
-        invalidationNodeIdMap[invalidation.nodeId] = true;
-      }
-    }
-
-    if (invalidationNodes.length === 1) {
-      parentElement.appendChild(invalidationNodes[0]);
-    } else if (invalidationNodes.length === 2) {
-      parentElement.appendChild(invalidationNodes[0]);
-      parentElement.createTextChild(Common.UIString(' and '));
-      parentElement.appendChild(invalidationNodes[1]);
-    } else if (invalidationNodes.length >= 3) {
-      parentElement.appendChild(invalidationNodes[0]);
-      parentElement.createTextChild(Common.UIString(', '));
-      parentElement.appendChild(invalidationNodes[1]);
-      parentElement.createTextChild(Common.UIString(', and %s others', invalidationNodes.length - 2));
-    }
-  }
-
-  /**
-   * @param {!TimelineModel.InvalidationTrackingEvent} invalidation
-   * @param {boolean} showUnknownNodes
-   */
-  _createInvalidationNode(invalidation, showUnknownNodes) {
-    const node = (invalidation.nodeId && this._relatedNodesMap) ? this._relatedNodesMap.get(invalidation.nodeId) : null;
-    if (node) {
-      const nodeSpan = createElement('span');
-      Common.Linkifier.linkify(node).then(link => nodeSpan.appendChild(link));
-      return nodeSpan;
-    }
-    if (invalidation.nodeName) {
-      const nodeSpan = createElement('span');
-      nodeSpan.textContent = Common.UIString('[ %s ]', invalidation.nodeName);
-      return nodeSpan;
-    }
-    if (showUnknownNodes) {
-      const nodeSpan = createElement('span');
-      return nodeSpan.createTextChild(Common.UIString('[ unknown node ]'));
-    }
-  }
-};
-
-Timeline.TimelineUIUtils._previewElementSymbol = Symbol('previewElement');
-
-/**
- * @unrestricted
- */
-Timeline.TimelineUIUtils.EventDispatchTypeDescriptor = class {
-  /**
-   * @param {number} priority
-   * @param {string} color
-   * @param {!Array.<string>} eventTypes
-   */
-  constructor(priority, color, eventTypes) {
-    this.priority = priority;
-    this.color = color;
-    this.eventTypes = eventTypes;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-Timeline.TimelineCategory = class extends Common.Object {
-  /**
-   * @param {string} name
-   * @param {string} title
-   * @param {boolean} visible
-   * @param {string} childColor
-   * @param {string} color
-   */
-  constructor(name, title, visible, childColor, color) {
-    super();
-    this.name = name;
-    this.title = title;
-    this.visible = visible;
-    this.childColor = childColor;
-    this.color = color;
-    this.hidden = false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  get hidden() {
-    return this._hidden;
-  }
-
-  /**
-   * @param {boolean} hidden
-   */
-  set hidden(hidden) {
-    this._hidden = hidden;
-    this.dispatchEventToListeners(Timeline.TimelineCategory.Events.VisibilityChanged, this);
-  }
-};
-
-/** @enum {symbol} */
-Timeline.TimelineCategory.Events = {
-  VisibilityChanged: Symbol('VisibilityChanged')
-};
-
-/**
- * @typedef {!{
- *     title: string,
- *     color: string,
- *     lineWidth: number,
- *     dashStyle: !Array.<number>,
- *     tall: boolean,
- *     lowPriority: boolean
- * }}
- */
-Timeline.TimelineMarkerStyle;
-
-
-/**
- * @unrestricted
- */
-Timeline.TimelinePopupContentHelper = class {
-  /**
-   * @param {string} title
-   */
-  constructor(title) {
-    this._contentTable = createElement('table');
-    const titleCell = this._createCell(Common.UIString('%s - Details', title), 'timeline-details-title');
-    titleCell.colSpan = 2;
-    const titleRow = createElement('tr');
-    titleRow.appendChild(titleCell);
-    this._contentTable.appendChild(titleRow);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  contentTable() {
-    return this._contentTable;
-  }
-
-  /**
-   * @param {string|number} content
-   * @param {string=} styleName
-   */
-  _createCell(content, styleName) {
-    const text = createElement('label');
-    text.createTextChild(String(content));
-    const cell = createElement('td');
-    cell.className = 'timeline-details';
-    if (styleName)
-      cell.className += ' ' + styleName;
-    cell.textContent = content;
-    return cell;
-  }
-
-  /**
-   * @param {string} title
-   * @param {string|number} content
-   */
-  appendTextRow(title, content) {
-    const row = createElement('tr');
-    row.appendChild(this._createCell(title, 'timeline-details-row-title'));
-    row.appendChild(this._createCell(content, 'timeline-details-row-data'));
-    this._contentTable.appendChild(row);
-  }
-
-  /**
-   * @param {string} title
-   * @param {!Node|string} content
-   */
-  appendElementRow(title, content) {
-    const row = createElement('tr');
-    const titleCell = this._createCell(title, 'timeline-details-row-title');
-    row.appendChild(titleCell);
-    const cell = createElement('td');
-    cell.className = 'details';
-    if (content instanceof Node)
-      cell.appendChild(content);
-    else
-      cell.createTextChild(content || '');
-    row.appendChild(cell);
-    this._contentTable.appendChild(row);
-  }
-};
-
-/**
- * @unrestricted
- */
-Timeline.TimelineDetailsContentHelper = class {
-  /**
-   * @param {?SDK.Target} target
-   * @param {?Components.Linkifier} linkifier
-   */
-  constructor(target, linkifier) {
-    this.fragment = createDocumentFragment();
-
-    this._linkifier = linkifier;
-    this._target = target;
-
-    this.element = createElementWithClass('div', 'timeline-details-view-block');
-    this._tableElement = this.element.createChild('div', 'vbox timeline-details-chip-body');
-    this.fragment.appendChild(this.element);
-  }
-
-  /**
-   * @param {string} title
-   * @param {string=} swatchColor
-   */
-  addSection(title, swatchColor) {
-    if (!this._tableElement.hasChildNodes()) {
-      this.element.removeChildren();
-    } else {
-      this.element = createElementWithClass('div', 'timeline-details-view-block');
-      this.fragment.appendChild(this.element);
-    }
-
-    if (title) {
-      const titleElement = this.element.createChild('div', 'timeline-details-chip-title');
-      if (swatchColor)
-        titleElement.createChild('div').style.backgroundColor = swatchColor;
-      titleElement.createTextChild(title);
-    }
-
-    this._tableElement = this.element.createChild('div', 'vbox timeline-details-chip-body');
-    this.fragment.appendChild(this.element);
-  }
-
-  /**
-   * @return {?Components.Linkifier}
-   */
-  linkifier() {
-    return this._linkifier;
-  }
-
-  /**
-   * @param {string} title
-   * @param {string|number|boolean} value
-   */
-  appendTextRow(title, value) {
-    const rowElement = this._tableElement.createChild('div', 'timeline-details-view-row');
-    rowElement.createChild('div', 'timeline-details-view-row-title').textContent = title;
-    rowElement.createChild('div', 'timeline-details-view-row-value').textContent = value;
-  }
-
-  /**
-   * @param {string} title
-   * @param {!Node|string} content
-   * @param {boolean=} isWarning
-   * @param {boolean=} isStacked
-   */
-  appendElementRow(title, content, isWarning, isStacked) {
-    const rowElement = this._tableElement.createChild('div', 'timeline-details-view-row');
-    if (isWarning)
-      rowElement.classList.add('timeline-details-warning');
-    if (isStacked)
-      rowElement.classList.add('timeline-details-stack-values');
-    const titleElement = rowElement.createChild('div', 'timeline-details-view-row-title');
-    titleElement.textContent = title;
-    const valueElement = rowElement.createChild('div', 'timeline-details-view-row-value');
-    if (content instanceof Node)
-      valueElement.appendChild(content);
-    else
-      valueElement.createTextChild(content || '');
-  }
-
-  /**
-   * @param {string} title
-   * @param {string} url
-   * @param {number} startLine
-   * @param {number=} startColumn
-   */
-  appendLocationRow(title, url, startLine, startColumn) {
-    if (!this._linkifier || !this._target)
-      return;
-    const link = this._linkifier.maybeLinkifyScriptLocation(this._target, null, url, startLine, startColumn);
-    if (!link)
-      return;
-    this.appendElementRow(title, link);
-  }
-
-  /**
-   * @param {string} title
-   * @param {string} url
-   * @param {number} startLine
-   * @param {number=} endLine
-   */
-  appendLocationRange(title, url, startLine, endLine) {
-    if (!this._linkifier || !this._target)
-      return;
-    const locationContent = createElement('span');
-    const link = this._linkifier.maybeLinkifyScriptLocation(this._target, null, url, startLine);
-    if (!link)
-      return;
-    locationContent.appendChild(link);
-    locationContent.createTextChild(String.sprintf(' [%s\u2026%s]', startLine + 1, endLine + 1 || ''));
-    this.appendElementRow(title, locationContent);
-  }
-
-  /**
-   * @param {string} title
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   */
-  appendStackTrace(title, stackTrace) {
-    if (!this._linkifier || !this._target)
-      return;
-
-    const rowElement = this._tableElement.createChild('div', 'timeline-details-view-row');
-    rowElement.createChild('div', 'timeline-details-view-row-title').textContent = title;
-    this.createChildStackTraceElement(rowElement, stackTrace);
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {!Protocol.Runtime.StackTrace} stackTrace
-   */
-  createChildStackTraceElement(parentElement, stackTrace) {
-    if (!this._linkifier || !this._target)
-      return;
-    parentElement.classList.add('timeline-details-stack-values');
-    const stackTraceElement =
-        parentElement.createChild('div', 'timeline-details-view-row-value timeline-details-view-row-stack-trace');
-    const callFrameElem =
-        Components.JSPresentationUtils.buildStackTracePreviewContents(this._target, this._linkifier, stackTrace);
-    stackTraceElement.appendChild(callFrameElem);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {string=} warningType
-   */
-  appendWarningRow(event, warningType) {
-    const warning = Timeline.TimelineUIUtils.eventWarning(event, warningType);
-    if (warning)
-      this.appendElementRow(Common.UIString('Warning'), warning, true);
-  }
-};
-
-Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol = Symbol('categoryBreakdownCache');
diff --git a/front_end/timeline/historyToolbarButton.css b/front_end/timeline/historyToolbarButton.css
deleted file mode 100644
index f66188b..0000000
--- a/front_end/timeline/historyToolbarButton.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-  width: 160px;
-  height: 26px;
-  text-align: left;
-  display: flex;
-}
-
-:host([disabled]) {
-  opacity: .5;
-}
-
-.content {
-  padding-right: 5px;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  flex: 1 1;
-  min-width: 35px;
-}
diff --git a/front_end/timeline/invalidationsTree.css b/front_end/timeline/invalidationsTree.css
deleted file mode 100644
index 98d5004..0000000
--- a/front_end/timeline/invalidationsTree.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.header, .children, .content {
-    min-height: initial;
-    line-height: initial;
-}
-
-/* This TreeElement is always expanded and has no arrow.   */
-/* FIXME(crbug.com/475618): Implement this in TreeElement. */
-.children li::before {
-    display: none;
-}
-
-.content {
-    margin-bottom: 4px;
-}
-
-.content .stack-preview-container {
-    margin-left: 8px;
-}
-
-.content .node-list {
-    margin-left: 10px;
-}
diff --git a/front_end/timeline/module.json b/front_end/timeline/module.json
deleted file mode 100644
index 75f4094..0000000
--- a/front_end/timeline/module.json
+++ /dev/null
@@ -1,260 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "timeline",
-            "title": "Performance",
-            "order": 50,
-            "className": "Timeline.TimelinePanel"
-        },
-        {
-            "type": "setting",
-            "category": "Performance",
-            "title": "Hide chrome frame in Layers view",
-            "settingName": "frameViewerHideChromeWindow",
-            "settingType": "boolean",
-            "defaultValue": false
-        },
-        {
-            "type": "@Common.QueryParamHandler",
-            "name": "loadTimelineFromURL",
-            "className": "Timeline.LoadTimelineHandler"
-        },
-        {
-            "type": "context-menu-item",
-            "location": "timelineMenu/open",
-            "actionId": "timeline.load-from-file",
-            "order": 10
-        },
-        {
-            "type": "context-menu-item",
-            "location": "timelineMenu/open",
-            "actionId": "timeline.save-to-file",
-            "order": 15
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.toggle-recording",
-            "iconClass": "largeicon-start-recording",
-            "toggledIconClass": "largeicon-stop-recording",
-            "toggleWithRedColor": true,
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "options": [
-                {
-                    "value": true,
-                    "title": "Record"
-                },
-                {
-                    "value": false,
-                    "title": "Stop"
-                }
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+E"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+E"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.record-reload",
-            "iconClass": "largeicon-refresh",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "category": "Performance",
-            "title": "Start profiling and reload page",
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+Shift+E"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Shift+E"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Timeline",
-            "actionId": "timeline.save-to-file",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "title": "Save profile\u2026",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+S"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+S"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "category": "Timeline",
-            "actionId": "timeline.load-from-file",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "title": "Load profile\u2026",
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+O"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+O"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.jump-to-previous-frame",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "["
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.jump-to-next-frame",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "bindings": [
-                {
-                    "shortcut": "]"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.show-history",
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "category": "Performance",
-            "title": "Show recent timeline sessions",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Ctrl+H"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Y"
-                }
-            ]
-        },
-        {
-            "type": "view",
-            "location": "panel",
-            "id": "js_profiler",
-            "title": "JavaScript Profiler",
-            "persistence": "closeable",
-            "order": 65,
-            "className": "Profiler.JSProfilerPanel"
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.previous-recording",
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Alt+Left"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Left"
-                }
-            ]
-        },
-        {
-            "type": "action",
-            "actionId": "timeline.next-recording",
-            "className": "Timeline.TimelinePanel.ActionDelegate",
-            "contextTypes": [
-                "Timeline.TimelinePanel"
-            ],
-            "bindings": [
-                {
-                    "platform": "windows,linux",
-                    "shortcut": "Alt+Right"
-                },
-                {
-                    "platform": "mac",
-                    "shortcut": "Meta+Right"
-                }
-            ]
-        }
-    ],
-    "dependencies": [
-        "browser_components",
-        "layer_viewer",
-        "timeline_model",
-        "perf_ui",
-        "extensions",
-        "data_grid",
-        "product_registry",
-        "profiler",
-        "mobile_throttling"
-    ],
-    "scripts": [
-        "CountersGraph.js",
-        "ExtensionTracingSession.js",
-        "PerformanceModel.js",
-        "TimelineController.js",
-        "TimelineDetailsView.js",
-        "TimelineLoader.js",
-        "TimelineEventOverview.js",
-        "TimelineFilters.js",
-        "TimelineFlameChartDataProvider.js",
-        "TimelineFlameChartNetworkDataProvider.js",
-        "TimelineFlameChartView.js",
-        "TimelineHistoryManager.js",
-        "TimelineTreeView.js",
-        "EventsTimelineTreeView.js",
-        "TimelineUIUtils.js",
-        "TimelineLayersView.js",
-        "TimelinePaintProfilerView.js",
-        "TimelinePanel.js"
-    ],
-    "resources": [
-        "historyToolbarButton.css",
-        "invalidationsTree.css",
-        "timelineFlamechartPopover.css",
-        "timelineHistoryManager.css",
-        "timelinePanel.css",
-        "timelinePaintProfiler.css",
-        "timelineStatusDialog.css"
-    ]
-}
diff --git a/front_end/timeline/timelineFlamechartPopover.css b/front_end/timeline/timelineFlamechartPopover.css
deleted file mode 100644
index dacf7d1..0000000
--- a/front_end/timeline/timelineFlamechartPopover.css
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.timeline-flamechart-popover {
-    overflow: hidden;
-}
-
-.timeline-flamechart-popover span {
-    margin-right: 5px;
-}
-
-.timeline-flamechart-popover span.timeline-info-network-time {
-    color: #009;
-}
-
-.timeline-flamechart-popover span.timeline-info-time {
-    color: #282;
-}
-
-.timeline-flamechart-popover span.timeline-info-warning {
-    color: #e44;
-}
-
-.timeline-flamechart-popover span.timeline-info-warning * {
-    color: inherit;
-}
diff --git a/front_end/timeline/timelineHistoryManager.css b/front_end/timeline/timelineHistoryManager.css
deleted file mode 100644
index 4068fa4..0000000
--- a/front_end/timeline/timelineHistoryManager.css
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.drop-down {
-  padding: 1px;
-  box-shadow: var(--drop-shadow);
-  background: white;
-}
-
-.preview-item {
-  border-color: transparent;
-  border-style: solid;
-  border-width: 1px 5px;
-  padding: 2px 0px;
-  margin: 2px 1px;
-}
-
-.preview-item.selected {
-  border-color: var(--selection-bg-color);
-}
-
-.preview-item canvas {
-  width: 100%;
-  height: 100%;
-}
-
-.text-details {
-  font-size: 11px;
-  padding: 3px;
-}
-
-.text-details span {
-  flex: 1 0;
-  padding-left: 8px;
-  padding-right: 8px;
-}
-
-.text-details .name {
-  font-weight: bold;
-}
-
-.text-details span.time {
-  color: #555;
-  text-align: right;
-}
-
-.screenshot-thumb {
-  display: flex;
-  border: 1px solid #ccc;
-  margin: 2px 4px;
-}
-
-.screenshot-thumb img {
-  margin: auto;
-  max-width: 100%;
-  max-height: 100%;
-}
diff --git a/front_end/timeline/timelinePaintProfiler.css b/front_end/timeline/timelinePaintProfiler.css
deleted file mode 100644
index 979c913..0000000
--- a/front_end/timeline/timelinePaintProfiler.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.paint-profiler-image-view {
-    overflow: hidden;
-}
-
-.paint-profiler-image-view .paint-profiler-image-container {
-    -webkit-transform-origin: 0 0;
-}
-
-.paint-profiler-image-view .paint-profiler-image-container div {
-    border-color: rgba(100, 100, 100, 0.4);
-    border-style: solid;
-    z-index: 100;
-    position: absolute;
-    top: 0;
-    left: 0;
-}
-
-.paint-profiler-image-view img {
-    border: solid 1px black;
-}
diff --git a/front_end/timeline/timelinePanel.css b/front_end/timeline/timelinePanel.css
deleted file mode 100644
index 4d11a80..0000000
--- a/front_end/timeline/timelinePanel.css
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.panel.timeline > .toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.timeline-settings-pane {
-    flex: none;
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-#timeline-overview-panel {
-    flex: none;
-    position: relative;
-    border-bottom: 1px solid #bbb;
-}
-
-#timeline-overview-panel .timeline-graph-bar {
-    pointer-events: none;
-}
-
-#timeline-overview-grid {
-    background-color: rgb(255, 255, 255);
-}
-
-#timeline-overview-grid .timeline-grid-header {
-    height: 12px;
-}
-
-#timeline-overview-grid .resources-dividers-label-bar {
-    pointer-events: auto;
-    height: 12px;
-}
-
-#timeline-overview-grid .resources-divider-label {
-    top: 1px;
-}
-
-.timeline-details-split {
-    flex: auto;
-}
-
-.timeline-view-stack {
-    flex: auto;
-    display: flex;
-}
-
-#timeline-container .devtools-link {
-    color: inherit;
-}
-
-.timeline-graph-side.hovered {
-    background-color: rgba(0, 0, 0, 0.05) !important;
-}
-
-.timeline.panel .status-pane-container {
-    z-index: 1000;
-    display: flex;
-    align-items: center;
-    pointer-events: none;
-}
-
-.timeline.panel .status-pane-container.tinted {
-    background-color: hsla(0, 0%, 90%, 0.8);
-    pointer-events: auto;
-}
-
-.timeline.panel .status-pane-container > div {
-    pointer-events: auto;
-}
-
-#timeline-overview-panel .overview-strip {
-    margin-top: 2px;
-    justify-content: center;
-}
-
-#timeline-overview-panel .overview-strip .timeline-overview-strip-title {
-    color: #666;
-    font-size: 10px;
-    font-weight: bold;
-    z-index: 100;
-    background-color: rgba(255, 255, 255, 0.7);
-    padding: 0 4px;
-    position: absolute;
-    top: -2px;
-    right: 0;
-}
-
-#timeline-overview-cpu-activity {
-    flex-basis: 20px;
-}
-
-#timeline-overview-network {
-    flex-basis: 8px;
-}
-
-#timeline-overview-framerate {
-    flex-basis: 16px;
-    margin-top: 0 !important;
-}
-
-#timeline-overview-filmstrip {
-    flex-basis: 30px;
-}
-
-#timeline-overview-memory {
-    flex-basis: 20px;
-}
-
-#timeline-overview-framerate::before,
-#timeline-overview-network::before,
-#timeline-overview-cpu-activity::before {
-    content: "";
-    position: absolute;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    border-bottom: 1px solid hsla(0, 0%, 0%, 0.06);
-    z-index: -200;
-}
-
-.overview-strip .background {
-    z-index: -10;
-}
-
-#timeline-overview-responsiveness {
-    flex-basis: 5px;
-    margin-top: 0 !important;
-}
-
-#timeline-overview-input {
-    flex-basis: 6px;
-}
-
-#timeline-overview-pane {
-    flex: auto;
-    position: relative;
-    overflow: hidden;
-}
-
-#timeline-overview-container {
-    display: flex;
-    flex-direction: column;
-    flex: none;
-    position: relative;
-    overflow: hidden;
-}
-
-#timeline-overview-container canvas {
-    width: 100%;
-    height: 100%;
-}
-
-#timeline-graphs {
-    position: absolute;
-    left: 0;
-    right: 0;
-    max-height: 100%;
-    top: 20px;
-}
-
-.timeline-aggregated-legend-title {
-    display: inline-block;
-}
-
-.timeline-aggregated-legend-value {
-    display: inline-block;
-    width: 70px;
-    text-align: right;
-}
-
-.timeline-aggregated-legend-swatch {
-    display: inline-block;
-    width: 11px;
-    height: 11px;
-    margin: 0 6px;
-    position: relative;
-    top: 1px;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-}
-
-.popover ul {
-    margin: 0;
-    padding: 0;
-    list-style-type: none;
-}
-
-#resources-container-content {
-    overflow: hidden;
-    min-height: 100%;
-}
-
-.memory-graph-label {
-    position: absolute;
-    right: 0;
-    bottom: 0;
-    font-size: 9px;
-    color: #888;
-    white-space: nowrap;
-    padding: 0 4px;
-    background-color: hsla(0, 0%, 100%, 0.8);
-}
-
-#memory-graphs-canvas-container {
-    overflow: hidden;
-    flex: auto;
-    position: relative;
-}
-
-#memory-counters-graph {
-    flex: auto;
-}
-
-#memory-graphs-canvas-container .memory-counter-marker {
-    position: absolute;
-    border-radius: 3px;
-    width: 5px;
-    height: 5px;
-    margin-left: -3px;
-    margin-top: -2px;
-}
-
-#memory-graphs-container .timeline-memory-header {
-    flex: 0 0 26px;
-    background-color: #eee;
-    border-bottom: 1px solid #ddd;
-    justify-content: space-between;
-}
-
-#memory-graphs-container .timeline-memory-header::after {
-    content: "";
-    background-image: url(Images/toolbarResizerVertical.png);
-    background-repeat: no-repeat;
-    background-position: right center, center;
-    flex: 20px 0 0;
-    margin: 0 4px;
-}
-
-.timeline-memory-toolbar {
-    flex-shrink: 1;
-}
-
-.memory-counter-selector-info {
-    flex: 0 0 auto;
-    margin-left: 5px;
-    white-space: nowrap;
-}
-
-.memory-counter-selector-info .range {
-    margin: 0 4px;
-    align-items: center;
-    display: inline-flex;
-}
-
-.memory-counter-value {
-    margin: 8px;
-}
-
-#counter-values-bar {
-    flex: 0 0 20px;
-    border-top: solid 1px lightgray;
-    width: 100%;
-    overflow: hidden;
-    line-height: 18px;
-}
-
-.timeline-filters-header {
-    overflow: hidden;
-    flex: none;
-}
-
-.timeline-details {
-    vertical-align: top;
-}
-
-.timeline-details-title {
-    border-bottom: 1px solid #B8B8B8;
-    font-weight: bold;
-    padding-bottom: 5px;
-    padding-top: 0;
-    white-space: nowrap;
-}
-
-.timeline-details-row-title {
-    font-weight: bold;
-    text-align: right;
-    white-space: nowrap;
-}
-
-.timeline-details-row-data {
-    white-space: nowrap;
-}
-
-.timeline-details-view {
-    color: #333;
-    overflow: hidden;
-}
-
-.timeline-details-view-body {
-    flex: auto;
-    overflow: auto;
-    position: relative;
-    background-color: var(--toolbar-bg-color);
-    -webkit-user-select: text;
-}
-
-.timeline-details-view-body > div {
-    overflow: hidden;
-}
-
-.timeline-details-view-block {
-    flex: none;
-    display: flex;
-    background-color: white;
-    flex-direction: column;
-    padding-bottom: 5px;
-    border-bottom: var(--divider-border);
-}
-
-.timeline-details-view-row {
-    padding-left: 10px;
-    flex-direction: row;
-    display: flex;
-    line-height: 20px;
-}
-
-.timeline-details-view-block .timeline-details-stack-values {
-    flex-direction: column !important;
-}
-
-.timeline-details-chip-title {
-    font-size: 13px;
-    padding: 8px;
-    display: flex;
-    align-items: center;
-}
-
-.timeline-details-chip-title > div {
-    width: 12px;
-    height: 12px;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-    display: inline-block;
-    margin-right: 4px;
-    content: " ";
-}
-
-.timeline-details-view-row-title:not(:empty) {
-    color: rgb(152, 152, 152);
-    overflow: hidden;
-    padding-right: 10px;
-}
-
-.timeline-details-warning {
-    background-color: rgba(250, 209, 209, 0.48);
-}
-
-.timeline-details-warning .timeline-details-view-row-title {
-    color: red;
-}
-
-.timeline-details-warning .timeline-details-view-row-value {
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.timeline-details-view-row-value {
-    -webkit-user-select: text;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.timeline-details-view-row-value .stack-preview-container {
-    line-height: 11px;
-}
-
-.timeline-details-view-row-value .timeline-details-warning-marker {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.timeline-details-view-pie-chart-wrapper {
-    margin: 4px 0;
-}
-
-.timeline-details-view-pie-chart {
-    margin-top: 5px;
-}
-
-.timeline-details-view-row-stack-trace {
-    padding: 4px 0;
-    line-height: inherit;
-}
-
-.timeline-details-view-row-stack-trace div {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    line-height: 12px;
-}
-
-.timeline-aggregated-info-legend > div {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-
-.timeline-flamechart {
-    overflow: hidden;
-}
-
-.timeline-flamechart-resizer {
-    flex: 8px 0 0;
-    background-color: var(--toolbar-bg-color);
-    border: 1px #a3a3a3;
-    border-style: solid none;
-    display: flex;
-    flex-direction: row;
-    align-items: flex-end;
-    justify-content: center;
-}
-
-.timeline-network-resizer-disabled > .timeline-flamechart-resizer {
-    display: none;
-}
-
-.timeline-flamechart-resizer:after {
-    content: "...";
-    font-size: 14px;
-    margin-bottom: -1px;
-}
-
-.timeline-status-pane.full-widget-dimmed-banner {
-    text-align: left !important;
-}
-
-.timeline-layers-view > div:last-child,
-.timeline-layers-view-properties > div:last-child {
-    background-color: #eee;
-}
-
-.timeline-layers-view-properties table {
-    width: 100%;
-    border-collapse: collapse;
-}
-
-.timeline-layers-view-properties td {
-    border: 1px solid #e1e1e1;
-    line-height: 22px;
-}
-
-.timeline-paint-profiler-log-split > div:last-child {
-    background-color: #eee;
-    z-index: 0;
-}
-
-.timeline-gap {
-    flex: none;
-}
-
-.timeline-filmstrip-preview > img {
-    margin-top: 5px;
-    max-width: 500px;
-    max-height: 300px;
-    cursor: pointer;
-    border: 1px solid #ddd;
-}
-
-.timeline-tree-view {
-    display: flex;
-    overflow: hidden;
-}
-
-.timeline-tree-view .toolbar {
-    background-color: var(--toolbar-bg-color);
-    border-bottom: var(--divider-border);
-}
-
-.timeline-tree-view .data-grid {
-    border: none;
-    flex: auto;
-}
-
-.timeline-tree-view .data-grid .data-container {
-    overflow-y: scroll;
-}
-
-.timeline-tree-view .data-grid.data-grid-fits-viewport .corner {
-    display: table-cell;
-}
-
-.timeline-tree-view .data-grid table.data {
-    background: white;
-}
-
-.timeline-tree-view .data-grid tr:not(.selected) .highlight {
-    background-color: rgb(255, 230, 179);
-}
-
-.timeline-tree-view .data-grid tr:hover td:not(.bottom-filler-td) {
-    background-color: rgba(0, 0, 0, 0.1);
-}
-
-.timeline-tree-view .data-grid td.numeric-column {
-    text-align: right;
-    position: relative;
-}
-
-.timeline-tree-view .data-grid div.background-percent-bar {
-    float: right;
-}
-
-.timeline-tree-view .data-grid span.percent-column {
-    color: #888;
-    width: 45px;
-    display: inline-block;
-}
-
-.timeline-tree-view .data-grid tr.selected span {
-    color: inherit;
-}
-
-.timeline-tree-view .data-grid .name-container {
-    display: flex;
-    align-items: center;
-    padding-left: 2px;
-}
-
-.timeline-tree-view .data-grid .name-container div {
-    flex: none;
-}
-
-.timeline-tree-view .data-grid .name-container .activity-icon {
-    width: 12px;
-    height: 12px;
-    border: 1px solid rgba(0, 0, 0, 0.05);
-    margin: 3px 0;
-}
-
-.timeline-tree-view .data-grid .name-container .activity-icon-container {
-    margin-right: 3px;
-    display: flex;
-    flex-wrap: wrap;
-    align-items: center;
-    justify-content: center;
-    width: 18px;
-    height: 18px;
-    overflow: hidden;
-}
-
-.timeline-tree-view .data-grid .name-container .activity-warning::after {
-    content: "[deopt]";
-    margin: 0 4px;
-    line-height: 12px;
-    font-size: 10px;
-    color: #777;
-}
-
-.timeline-tree-view .data-grid tr.selected .name-container .activity-warning::after {
-    color: white;
-}
-
-.timeline-tree-view .data-grid .name-container .activity-link {
-    flex: auto;
-    text-align: right;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    margin-left: 5px;
-}
-
-.timeline-tree-view .data-grid .background-bar-container {
-    position: absolute;
-    left: 3px;
-    right: 0;
-}
-
-.timeline-tree-view .data-grid .background-bar {
-    float: right;
-    height: 18px;
-    background-color: hsla(43, 84%, 64%, 0.2);
-    border-bottom: 1px solid hsl(43, 84%, 64%);
-}
-
-.timeline-tree-view .data-grid .selected .background-bar {
-    background-color: rgba(255, 255, 255, 0.3);
-    border-bottom-color: rgba(255, 255, 255, 0.9);
-}
-
-.timeline-tree-view .timeline-details-view-body .full-widget-dimmed-banner {
-    background-color: inherit;
-}
-
-.timeline-details .filter-input-field {
-    width: 120px;
-}
-
-.timeline-tree-view .data-grid .header-container {
-    height: 21px;
-}
-
-.timeline-tree-view .data-grid .data-container {
-    top: 21px;
-}
-
-.timeline-stack-view-header {
-    height: 27px;
-    background-color: var(--toolbar-bg-color);
-    padding: 6px 10px;
-    color: #5a5a5a;
-    white-space: nowrap;
-    border-bottom: var(--divider-border);
-}
-
-.timeline-landing-page {
-    position: absolute;
-    background-color: white;
-    justify-content: center;
-    align-items: center;
-    overflow: auto;
-    font-size: 13px;
-    color: #777;
-}
-
-.timeline-landing-page > div {
-    max-width: 450px;
-    margin: 10px;
-}
-
-.timeline-landing-page > div > p {
-    flex: none;
-    white-space: pre-line;
-}
diff --git a/front_end/timeline/timelineStatusDialog.css b/front_end/timeline/timelineStatusDialog.css
deleted file mode 100644
index 9ab1641..0000000
--- a/front_end/timeline/timelineStatusDialog.css
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.timeline-status-dialog {
-    display: flex;
-    flex-direction: column;
-    padding: 16px 16px 12px 16px;
-    align-self: center;
-    background-color: white;
-    box-shadow: var(--drop-shadow);
-}
-
-.status-dialog-line {
-    margin: 2px;
-    height: 14px;
-    display: flex;
-    align-items: baseline;
-}
-
-.status-dialog-line .label {
-    display: inline-block;
-    width: 80px;
-    text-align: right;
-    color: #aaa;
-    margin-right: 10px;
-}
-
-.timeline-status-dialog .progress .indicator-container {
-    display: inline-block;
-    width: 200px;
-    height: 8px;
-    background-color: #f4f4f4;
-    display: inline-block;
-    margin: 0 10px 0 0;
-}
-
-.timeline-status-dialog .progress .indicator {
-    background-color: rgb(112, 166, 255);
-    height: 100%;
-    width: 0;
-    margin: 0;
-}
-
-.timeline-status-dialog .stop-button {
-    margin-top: 8px;
-    height: 100%;
-    align-self: center;
-}
-
-.timeline-status-dialog .stop-button button {
-    min-width: 80px;
-}
diff --git a/front_end/timeline_model/TimelineFrameModel.js b/front_end/timeline_model/TimelineFrameModel.js
deleted file mode 100644
index 577ea47..0000000
--- a/front_end/timeline_model/TimelineFrameModel.js
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-TimelineModel.TimelineFrameModel = class {
-  /**
-   * @param {function(!SDK.TracingModel.Event):string} categoryMapper
-   */
-  constructor(categoryMapper) {
-    this._categoryMapper = categoryMapper;
-    this.reset();
-  }
-
-  /**
-   * @return {!Array.<!TimelineModel.TimelineFrame>}
-   */
-  frames() {
-    return this._frames;
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {number} endTime
-   * @return {!Array.<!TimelineModel.TimelineFrame>}
-   */
-  filteredFrames(startTime, endTime) {
-    /**
-     * @param {number} value
-     * @param {!TimelineModel.TimelineFrame} object
-     * @return {number}
-     */
-    function compareStartTime(value, object) {
-      return value - object.startTime;
-    }
-    /**
-     * @param {number} value
-     * @param {!TimelineModel.TimelineFrame} object
-     * @return {number}
-     */
-    function compareEndTime(value, object) {
-      return value - object.endTime;
-    }
-    const frames = this._frames;
-    const firstFrame = frames.lowerBound(startTime, compareEndTime);
-    const lastFrame = frames.lowerBound(endTime, compareStartTime);
-    return frames.slice(firstFrame, lastFrame);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} rasterTask
-   * @return {boolean}
-   */
-  hasRasterTile(rasterTask) {
-    const data = rasterTask.args['tileData'];
-    if (!data)
-      return false;
-    const frameId = data['sourceFrameNumber'];
-    const frame = frameId && this._frameById[frameId];
-    if (!frame || !frame.layerTree)
-      return false;
-    return true;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} rasterTask
-   * @return Promise<?{rect: !Protocol.DOM.Rect, snapshot: !SDK.PaintProfilerSnapshot}>}
-   */
-  rasterTilePromise(rasterTask) {
-    if (!this._target)
-      return Promise.resolve(null);
-    const data = rasterTask.args['tileData'];
-    const frameId = data['sourceFrameNumber'];
-    const tileId = data['tileId'] && data['tileId']['id_ref'];
-    const frame = frameId && this._frameById[frameId];
-    if (!frame || !frame.layerTree || !tileId)
-      return Promise.resolve(null);
-
-    return frame.layerTree.layerTreePromise().then(layerTree => layerTree && layerTree.pictureForRasterTile(tileId));
-  }
-
-  reset() {
-    this._minimumRecordTime = Infinity;
-    this._frames = [];
-    this._frameById = {};
-    this._lastFrame = null;
-    this._lastLayerTree = null;
-    this._mainFrameCommitted = false;
-    this._mainFrameRequested = false;
-    this._framePendingCommit = null;
-    this._lastBeginFrame = null;
-    this._lastNeedsBeginFrame = null;
-    this._framePendingActivation = null;
-    this._lastTaskBeginTime = null;
-    this._target = null;
-    this._layerTreeId = null;
-    this._currentTaskTimeByCategory = {};
-  }
-
-  /**
-   * @param {number} startTime
-   */
-  handleBeginFrame(startTime) {
-    if (!this._lastFrame)
-      this._startFrame(startTime);
-    this._lastBeginFrame = startTime;
-  }
-
-  /**
-   * @param {number} startTime
-   */
-  handleDrawFrame(startTime) {
-    if (!this._lastFrame) {
-      this._startFrame(startTime);
-      return;
-    }
-
-    // - if it wasn't drawn, it didn't happen!
-    // - only show frames that either did not wait for the main thread frame or had one committed.
-    if (this._mainFrameCommitted || !this._mainFrameRequested) {
-      if (this._lastNeedsBeginFrame) {
-        const idleTimeEnd = this._framePendingActivation ? this._framePendingActivation.triggerTime :
-                                                           (this._lastBeginFrame || this._lastNeedsBeginFrame);
-        if (idleTimeEnd > this._lastFrame.startTime) {
-          this._lastFrame.idle = true;
-          this._startFrame(idleTimeEnd);
-          if (this._framePendingActivation)
-            this._commitPendingFrame();
-          this._lastBeginFrame = null;
-        }
-        this._lastNeedsBeginFrame = null;
-      }
-      this._startFrame(startTime);
-    }
-    this._mainFrameCommitted = false;
-  }
-
-  handleActivateLayerTree() {
-    if (!this._lastFrame)
-      return;
-    if (this._framePendingActivation && !this._lastNeedsBeginFrame)
-      this._commitPendingFrame();
-  }
-
-  handleRequestMainThreadFrame() {
-    if (!this._lastFrame)
-      return;
-    this._mainFrameRequested = true;
-  }
-
-  handleCompositeLayers() {
-    if (!this._framePendingCommit)
-      return;
-    this._framePendingActivation = this._framePendingCommit;
-    this._framePendingCommit = null;
-    this._mainFrameRequested = false;
-    this._mainFrameCommitted = true;
-  }
-
-  /**
-   * @param {!TimelineModel.TracingFrameLayerTree} layerTree
-   */
-  handleLayerTreeSnapshot(layerTree) {
-    this._lastLayerTree = layerTree;
-  }
-
-  /**
-   * @param {number} startTime
-   * @param {boolean} needsBeginFrame
-   */
-  handleNeedFrameChanged(startTime, needsBeginFrame) {
-    if (needsBeginFrame)
-      this._lastNeedsBeginFrame = startTime;
-  }
-
-  /**
-   * @param {number} startTime
-   */
-  _startFrame(startTime) {
-    if (this._lastFrame)
-      this._flushFrame(this._lastFrame, startTime);
-    this._lastFrame = new TimelineModel.TimelineFrame(startTime, startTime - this._minimumRecordTime);
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineFrame} frame
-   * @param {number} endTime
-   */
-  _flushFrame(frame, endTime) {
-    frame._setLayerTree(this._lastLayerTree);
-    frame._setEndTime(endTime);
-    if (this._lastLayerTree)
-      this._lastLayerTree._setPaints(frame._paints);
-    if (this._frames.length &&
-        (frame.startTime !== this._frames.peekLast().endTime || frame.startTime > frame.endTime)) {
-      console.assert(
-          false, `Inconsistent frame time for frame ${this._frames.length} (${frame.startTime} - ${frame.endTime})`);
-    }
-    this._frames.push(frame);
-    if (typeof frame._mainFrameId === 'number')
-      this._frameById[frame._mainFrameId] = frame;
-  }
-
-  _commitPendingFrame() {
-    this._lastFrame._addTimeForCategories(this._framePendingActivation.timeByCategory);
-    this._lastFrame._paints = this._framePendingActivation.paints;
-    this._lastFrame._mainFrameId = this._framePendingActivation.mainFrameId;
-    this._framePendingActivation = null;
-  }
-
-  /**
-   * @param {?SDK.Target} target
-   * @param {!Array.<!SDK.TracingModel.Event>} events
-   * @param {!Array<!{thread: !SDK.TracingModel.Thread, time: number}>} threadData
-   */
-  addTraceEvents(target, events, threadData) {
-    this._target = target;
-    let j = 0;
-    this._currentProcessMainThread = threadData.length && threadData[0].thread || null;
-    for (let i = 0; i < events.length; ++i) {
-      while (j + 1 < threadData.length && threadData[j + 1].time <= events[i].startTime)
-        this._currentProcessMainThread = threadData[++j].thread;
-      this._addTraceEvent(events[i]);
-    }
-    this._currentProcessMainThread = null;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addTraceEvent(event) {
-    const eventNames = TimelineModel.TimelineModel.RecordType;
-    if (event.startTime && event.startTime < this._minimumRecordTime)
-      this._minimumRecordTime = event.startTime;
-
-    if (event.name === eventNames.SetLayerTreeId) {
-      this._layerTreeId = event.args['layerTreeId'] || event.args['data']['layerTreeId'];
-    } else if (
-        event.phase === SDK.TracingModel.Phase.SnapshotObject && event.name === eventNames.LayerTreeHostImplSnapshot &&
-        parseInt(event.id, 0) === this._layerTreeId) {
-      const snapshot = /** @type {!SDK.TracingModel.ObjectSnapshot} */ (event);
-      this.handleLayerTreeSnapshot(new TimelineModel.TracingFrameLayerTree(this._target, snapshot));
-    } else {
-      this._processCompositorEvents(event);
-      if (event.thread === this._currentProcessMainThread)
-        this._addMainThreadTraceEvent(event);
-      else if (this._lastFrame && event.selfTime && !SDK.TracingModel.isTopLevelEvent(event))
-        this._lastFrame._addTimeForCategory(this._categoryMapper(event), event.selfTime);
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _processCompositorEvents(event) {
-    const eventNames = TimelineModel.TimelineModel.RecordType;
-
-    if (event.args['layerTreeId'] !== this._layerTreeId)
-      return;
-
-    const timestamp = event.startTime;
-    if (event.name === eventNames.BeginFrame)
-      this.handleBeginFrame(timestamp);
-    else if (event.name === eventNames.DrawFrame)
-      this.handleDrawFrame(timestamp);
-    else if (event.name === eventNames.ActivateLayerTree)
-      this.handleActivateLayerTree();
-    else if (event.name === eventNames.RequestMainThreadFrame)
-      this.handleRequestMainThreadFrame();
-    else if (event.name === eventNames.NeedsBeginFrameChanged)
-      this.handleNeedFrameChanged(timestamp, event.args['data'] && event.args['data']['needsBeginFrame']);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addMainThreadTraceEvent(event) {
-    const eventNames = TimelineModel.TimelineModel.RecordType;
-
-    if (SDK.TracingModel.isTopLevelEvent(event)) {
-      this._currentTaskTimeByCategory = {};
-      this._lastTaskBeginTime = event.startTime;
-    }
-    if (!this._framePendingCommit && TimelineModel.TimelineFrameModel._mainFrameMarkers.indexOf(event.name) >= 0) {
-      this._framePendingCommit =
-          new TimelineModel.PendingFrame(this._lastTaskBeginTime || event.startTime, this._currentTaskTimeByCategory);
-    }
-    if (!this._framePendingCommit) {
-      this._addTimeForCategory(this._currentTaskTimeByCategory, event);
-      return;
-    }
-    this._addTimeForCategory(this._framePendingCommit.timeByCategory, event);
-
-    if (event.name === eventNames.BeginMainThreadFrame && event.args['data'] && event.args['data']['frameId'])
-      this._framePendingCommit.mainFrameId = event.args['data']['frameId'];
-    if (event.name === eventNames.Paint && event.args['data']['layerId'] &&
-        TimelineModel.TimelineData.forEvent(event).picture && this._target)
-      this._framePendingCommit.paints.push(new TimelineModel.LayerPaintEvent(event, this._target));
-    if (event.name === eventNames.CompositeLayers && event.args['layerTreeId'] === this._layerTreeId)
-      this.handleCompositeLayers();
-  }
-
-  /**
-   * @param {!Object.<string, number>} timeByCategory
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _addTimeForCategory(timeByCategory, event) {
-    if (!event.selfTime)
-      return;
-    const categoryName = this._categoryMapper(event);
-    timeByCategory[categoryName] = (timeByCategory[categoryName] || 0) + event.selfTime;
-  }
-};
-
-TimelineModel.TimelineFrameModel._mainFrameMarkers = [
-  TimelineModel.TimelineModel.RecordType.ScheduleStyleRecalculation,
-  TimelineModel.TimelineModel.RecordType.InvalidateLayout, TimelineModel.TimelineModel.RecordType.BeginMainThreadFrame,
-  TimelineModel.TimelineModel.RecordType.ScrollLayer
-];
-
-/**
- * @unrestricted
- */
-TimelineModel.TracingFrameLayerTree = class {
-  /**
-   * @param {!SDK.Target} target
-   * @param {!SDK.TracingModel.ObjectSnapshot} snapshot
-   */
-  constructor(target, snapshot) {
-    this._target = target;
-    this._snapshot = snapshot;
-    /** @type {!Array<!TimelineModel.LayerPaintEvent>|undefined} */
-    this._paints;
-  }
-
-  /**
-   * @return {!Promise<?TimelineModel.TracingLayerTree>}
-   */
-  async layerTreePromise() {
-    const result = await this._snapshot.objectPromise();
-    if (!result)
-      return null;
-    const viewport = result['device_viewport_size'];
-    const tiles = result['active_tiles'];
-    const rootLayer = result['active_tree']['root_layer'];
-    const layers = result['active_tree']['layers'];
-    const layerTree = new TimelineModel.TracingLayerTree(this._target);
-    layerTree.setViewportSize(viewport);
-    layerTree.setTiles(tiles);
-
-    await layerTree.setLayers(rootLayer, layers, this._paints || []);
-    return layerTree;
-  }
-
-  /**
-   * @return {!Array<!TimelineModel.LayerPaintEvent>}
-   */
-  paints() {
-    return this._paints || [];
-  }
-
-  /**
-   * @param {!Array<!TimelineModel.LayerPaintEvent>} paints
-   */
-  _setPaints(paints) {
-    this._paints = paints;
-  }
-};
-
-/**
- * @unrestricted
- */
-TimelineModel.TimelineFrame = class {
-  /**
-   * @param {number} startTime
-   * @param {number} startTimeOffset
-   */
-  constructor(startTime, startTimeOffset) {
-    this.startTime = startTime;
-    this.startTimeOffset = startTimeOffset;
-    this.endTime = this.startTime;
-    this.duration = 0;
-    this.timeByCategory = {};
-    this.cpuTime = 0;
-    this.idle = false;
-    /** @type {?TimelineModel.TracingFrameLayerTree} */
-    this.layerTree = null;
-    /** @type {!Array.<!TimelineModel.LayerPaintEvent>} */
-    this._paints = [];
-    /** @type {number|undefined} */
-    this._mainFrameId = undefined;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasWarnings() {
-    return false;
-  }
-
-  /**
-   * @param {number} endTime
-   */
-  _setEndTime(endTime) {
-    this.endTime = endTime;
-    this.duration = this.endTime - this.startTime;
-  }
-
-  /**
-   * @param {?TimelineModel.TracingFrameLayerTree} layerTree
-   */
-  _setLayerTree(layerTree) {
-    this.layerTree = layerTree;
-  }
-
-  /**
-   * @param {!Object} timeByCategory
-   */
-  _addTimeForCategories(timeByCategory) {
-    for (const category in timeByCategory)
-      this._addTimeForCategory(category, timeByCategory[category]);
-  }
-
-  /**
-   * @param {string} category
-   * @param {number} time
-   */
-  _addTimeForCategory(category, time) {
-    this.timeByCategory[category] = (this.timeByCategory[category] || 0) + time;
-    this.cpuTime += time;
-  }
-};
-
-/**
- * @unrestricted
- */
-TimelineModel.LayerPaintEvent = class {
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {?SDK.Target} target
-   */
-  constructor(event, target) {
-    this._event = event;
-    this._target = target;
-  }
-
-  /**
-   * @return {string}
-   */
-  layerId() {
-    return this._event.args['data']['layerId'];
-  }
-
-  /**
-   * @return {!SDK.TracingModel.Event}
-   */
-  event() {
-    return this._event;
-  }
-
-  /**
-   * @return {!Promise<?{rect: !Array<number>, serializedPicture: string}>}
-   */
-  picturePromise() {
-    const picture = TimelineModel.TimelineData.forEvent(this._event).picture;
-    return picture.objectPromise().then(result => {
-      if (!result)
-        return null;
-      const rect = result['params'] && result['params']['layer_rect'];
-      const picture = result['skp64'];
-      return rect && picture ? {rect: rect, serializedPicture: picture} : null;
-    });
-  }
-
-  /**
-   * @return !Promise<?{rect: !Array<number>, snapshot: !SDK.PaintProfilerSnapshot}>}
-   */
-  snapshotPromise() {
-    const paintProfilerModel = this._target && this._target.model(SDK.PaintProfilerModel);
-    return this.picturePromise().then(picture => {
-      if (!picture || !paintProfilerModel)
-        return null;
-      return paintProfilerModel.loadSnapshot(picture.serializedPicture)
-          .then(snapshot => snapshot ? {rect: picture.rect, snapshot: snapshot} : null);
-    });
-  }
-};
-
-/**
- * @unrestricted
- */
-TimelineModel.PendingFrame = class {
-  /**
-   * @param {number} triggerTime
-   * @param {!Object.<string, number>} timeByCategory
-   */
-  constructor(triggerTime, timeByCategory) {
-    /** @type {!Object.<string, number>} */
-    this.timeByCategory = timeByCategory;
-    /** @type {!Array.<!TimelineModel.LayerPaintEvent>} */
-    this.paints = [];
-    /** @type {number|undefined} */
-    this.mainFrameId = undefined;
-    this.triggerTime = triggerTime;
-  }
-};
diff --git a/front_end/timeline_model/TimelineIRModel.js b/front_end/timeline_model/TimelineIRModel.js
deleted file mode 100644
index 8abb0ae..0000000
--- a/front_end/timeline_model/TimelineIRModel.js
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-TimelineModel.TimelineIRModel = class {
-  constructor() {
-    this.reset();
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {!TimelineModel.TimelineIRModel.Phases}
-   */
-  static phaseForEvent(event) {
-    return event[TimelineModel.TimelineIRModel._eventIRPhase];
-  }
-
-  /**
-   * @param {?Array<!SDK.TracingModel.AsyncEvent>} inputLatencies
-   * @param {?Array<!SDK.TracingModel.AsyncEvent>} animations
-   */
-  populate(inputLatencies, animations) {
-    this.reset();
-    if (!inputLatencies)
-      return;
-    this._processInputLatencies(inputLatencies);
-    if (animations)
-      this._processAnimations(animations);
-    const range = new Common.SegmentedRange();
-    range.appendRange(this._drags);  // Drags take lower precedence than animation, as we can't detect them reliably.
-    range.appendRange(this._cssAnimations);
-    range.appendRange(this._scrolls);
-    range.appendRange(this._responses);
-    this._segments = range.segments();
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.AsyncEvent>} events
-   */
-  _processInputLatencies(events) {
-    const eventTypes = TimelineModel.TimelineIRModel.InputEvents;
-    const phases = TimelineModel.TimelineIRModel.Phases;
-    const thresholdsMs = TimelineModel.TimelineIRModel._mergeThresholdsMs;
-
-    let scrollStart;
-    let flingStart;
-    let touchStart;
-    let firstTouchMove;
-    let mouseWheel;
-    let mouseDown;
-    let mouseMove;
-
-    for (let i = 0; i < events.length; ++i) {
-      const event = events[i];
-      if (i > 0 && events[i].startTime < events[i - 1].startTime)
-        console.assert(false, 'Unordered input events');
-      const type = this._inputEventType(event.name);
-      switch (type) {
-        case eventTypes.ScrollBegin:
-          this._scrolls.append(this._segmentForEvent(event, phases.Scroll));
-          scrollStart = event;
-          break;
-
-        case eventTypes.ScrollEnd:
-          if (scrollStart)
-            this._scrolls.append(this._segmentForEventRange(scrollStart, event, phases.Scroll));
-          else
-            this._scrolls.append(this._segmentForEvent(event, phases.Scroll));
-          scrollStart = null;
-          break;
-
-        case eventTypes.ScrollUpdate:
-          touchStart = null;  // Since we're scrolling now, disregard other touch gestures.
-          this._scrolls.append(this._segmentForEvent(event, phases.Scroll));
-          break;
-
-        case eventTypes.FlingStart:
-          if (flingStart) {
-            Common.console.error(
-                Common.UIString('Two flings at the same time? %s vs %s', flingStart.startTime, event.startTime));
-            break;
-          }
-          flingStart = event;
-          break;
-
-        case eventTypes.FlingCancel:
-          // FIXME: also process renderer fling events.
-          if (!flingStart)
-            break;
-          this._scrolls.append(this._segmentForEventRange(flingStart, event, phases.Fling));
-          flingStart = null;
-          break;
-
-        case eventTypes.ImplSideFling:
-          this._scrolls.append(this._segmentForEvent(event, phases.Fling));
-          break;
-
-        case eventTypes.ShowPress:
-        case eventTypes.Tap:
-        case eventTypes.KeyDown:
-        case eventTypes.KeyDownRaw:
-        case eventTypes.KeyUp:
-        case eventTypes.Char:
-        case eventTypes.Click:
-        case eventTypes.ContextMenu:
-          this._responses.append(this._segmentForEvent(event, phases.Response));
-          break;
-
-        case eventTypes.TouchStart:
-          // We do not produce any response segment for TouchStart -- there's either going to be one upon
-          // TouchMove for drag, or one for GestureTap.
-          if (touchStart) {
-            Common.console.error(
-                Common.UIString('Two touches at the same time? %s vs %s', touchStart.startTime, event.startTime));
-            break;
-          }
-          touchStart = event;
-          event.steps[0][TimelineModel.TimelineIRModel._eventIRPhase] = phases.Response;
-          firstTouchMove = null;
-          break;
-
-        case eventTypes.TouchCancel:
-          touchStart = null;
-          break;
-
-        case eventTypes.TouchMove:
-          if (firstTouchMove) {
-            this._drags.append(this._segmentForEvent(event, phases.Drag));
-          } else if (touchStart) {
-            firstTouchMove = event;
-            this._responses.append(this._segmentForEventRange(touchStart, event, phases.Response));
-          }
-          break;
-
-        case eventTypes.TouchEnd:
-          touchStart = null;
-          break;
-
-        case eventTypes.MouseDown:
-          mouseDown = event;
-          mouseMove = null;
-          break;
-
-        case eventTypes.MouseMove:
-          if (mouseDown && !mouseMove && mouseDown.startTime + thresholdsMs.mouse > event.startTime) {
-            this._responses.append(this._segmentForEvent(mouseDown, phases.Response));
-            this._responses.append(this._segmentForEvent(event, phases.Response));
-          } else if (mouseDown) {
-            this._drags.append(this._segmentForEvent(event, phases.Drag));
-          }
-          mouseMove = event;
-          break;
-
-        case eventTypes.MouseUp:
-          this._responses.append(this._segmentForEvent(event, phases.Response));
-          mouseDown = null;
-          break;
-
-        case eventTypes.MouseWheel:
-          // Do not consider first MouseWheel as trace viewer's implementation does -- in case of MouseWheel it's not really special.
-          if (mouseWheel && canMerge(thresholdsMs.mouse, mouseWheel, event))
-            this._scrolls.append(this._segmentForEventRange(mouseWheel, event, phases.Scroll));
-          else
-            this._scrolls.append(this._segmentForEvent(event, phases.Scroll));
-          mouseWheel = event;
-          break;
-      }
-    }
-
-    /**
-     * @param {number} threshold
-     * @param {!SDK.TracingModel.AsyncEvent} first
-     * @param {!SDK.TracingModel.AsyncEvent} second
-     * @return {boolean}
-     */
-    function canMerge(threshold, first, second) {
-      return first.endTime < second.startTime && second.startTime < first.endTime + threshold;
-    }
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.AsyncEvent>} events
-   */
-  _processAnimations(events) {
-    for (let i = 0; i < events.length; ++i)
-      this._cssAnimations.append(this._segmentForEvent(events[i], TimelineModel.TimelineIRModel.Phases.Animation));
-  }
-
-  /**
-   * @param {!SDK.TracingModel.AsyncEvent} event
-   * @param {!TimelineModel.TimelineIRModel.Phases} phase
-   * @return {!Common.Segment}
-   */
-  _segmentForEvent(event, phase) {
-    this._setPhaseForEvent(event, phase);
-    return new Common.Segment(event.startTime, event.endTime, phase);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.AsyncEvent} startEvent
-   * @param {!SDK.TracingModel.AsyncEvent} endEvent
-   * @param {!TimelineModel.TimelineIRModel.Phases} phase
-   * @return {!Common.Segment}
-   */
-  _segmentForEventRange(startEvent, endEvent, phase) {
-    this._setPhaseForEvent(startEvent, phase);
-    this._setPhaseForEvent(endEvent, phase);
-    return new Common.Segment(startEvent.startTime, endEvent.endTime, phase);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.AsyncEvent} asyncEvent
-   * @param {!TimelineModel.TimelineIRModel.Phases} phase
-   */
-  _setPhaseForEvent(asyncEvent, phase) {
-    asyncEvent.steps[0][TimelineModel.TimelineIRModel._eventIRPhase] = phase;
-  }
-
-  /**
-   * @return {!Array<!Common.Segment>}
-   */
-  interactionRecords() {
-    return this._segments;
-  }
-
-  reset() {
-    const thresholdsMs = TimelineModel.TimelineIRModel._mergeThresholdsMs;
-
-    this._segments = [];
-    this._drags = new Common.SegmentedRange(merge.bind(null, thresholdsMs.mouse));
-    this._cssAnimations = new Common.SegmentedRange(merge.bind(null, thresholdsMs.animation));
-    this._responses = new Common.SegmentedRange(merge.bind(null, 0));
-    this._scrolls = new Common.SegmentedRange(merge.bind(null, thresholdsMs.animation));
-
-    /**
-     * @param {number} threshold
-     * @param {!Common.Segment} first
-     * @param {!Common.Segment} second
-     */
-    function merge(threshold, first, second) {
-      return first.end + threshold >= second.begin && first.data === second.data ? first : null;
-    }
-  }
-
-  /**
-   * @param {string} eventName
-   * @return {?TimelineModel.TimelineIRModel.InputEvents}
-   */
-  _inputEventType(eventName) {
-    const prefix = 'InputLatency::';
-    if (!eventName.startsWith(prefix)) {
-      if (eventName === TimelineModel.TimelineIRModel.InputEvents.ImplSideFling)
-        return /** @type {!TimelineModel.TimelineIRModel.InputEvents} */ (eventName);
-      console.error('Unrecognized input latency event: ' + eventName);
-      return null;
-    }
-    return /** @type {!TimelineModel.TimelineIRModel.InputEvents} */ (eventName.substr(prefix.length));
-  }
-};
-
-/**
- * @enum {string}
- */
-TimelineModel.TimelineIRModel.Phases = {
-  Idle: 'Idle',
-  Response: 'Response',
-  Scroll: 'Scroll',
-  Fling: 'Fling',
-  Drag: 'Drag',
-  Animation: 'Animation',
-  Uncategorized: 'Uncategorized'
-};
-
-/**
- * @enum {string}
- */
-TimelineModel.TimelineIRModel.InputEvents = {
-  Char: 'Char',
-  Click: 'GestureClick',
-  ContextMenu: 'ContextMenu',
-  FlingCancel: 'GestureFlingCancel',
-  FlingStart: 'GestureFlingStart',
-  ImplSideFling: TimelineModel.TimelineModel.RecordType.ImplSideFling,
-  KeyDown: 'KeyDown',
-  KeyDownRaw: 'RawKeyDown',
-  KeyUp: 'KeyUp',
-  LatencyScrollUpdate: 'ScrollUpdate',
-  MouseDown: 'MouseDown',
-  MouseMove: 'MouseMove',
-  MouseUp: 'MouseUp',
-  MouseWheel: 'MouseWheel',
-  PinchBegin: 'GesturePinchBegin',
-  PinchEnd: 'GesturePinchEnd',
-  PinchUpdate: 'GesturePinchUpdate',
-  ScrollBegin: 'GestureScrollBegin',
-  ScrollEnd: 'GestureScrollEnd',
-  ScrollUpdate: 'GestureScrollUpdate',
-  ScrollUpdateRenderer: 'ScrollUpdate',
-  ShowPress: 'GestureShowPress',
-  Tap: 'GestureTap',
-  TapCancel: 'GestureTapCancel',
-  TapDown: 'GestureTapDown',
-  TouchCancel: 'TouchCancel',
-  TouchEnd: 'TouchEnd',
-  TouchMove: 'TouchMove',
-  TouchStart: 'TouchStart'
-};
-
-TimelineModel.TimelineIRModel._mergeThresholdsMs = {
-  animation: 1,
-  mouse: 40,
-};
-
-TimelineModel.TimelineIRModel._eventIRPhase = Symbol('eventIRPhase');
diff --git a/front_end/timeline_model/TimelineJSProfile.js b/front_end/timeline_model/TimelineJSProfile.js
deleted file mode 100644
index d544dd7..0000000
--- a/front_end/timeline_model/TimelineJSProfile.js
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-TimelineModel.TimelineJSProfileProcessor = class {
-  /**
-   * @param {!SDK.CPUProfileDataModel} jsProfileModel
-   * @param {!SDK.TracingModel.Thread} thread
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  static generateTracingEventsFromCpuProfile(jsProfileModel, thread) {
-    const idleNode = jsProfileModel.idleNode;
-    const programNode = jsProfileModel.programNode;
-    const gcNode = jsProfileModel.gcNode;
-    const samples = jsProfileModel.samples;
-    const timestamps = jsProfileModel.timestamps;
-    const jsEvents = [];
-    /** @type {!Map<!Object, !Array<!Protocol.Runtime.CallFrame>>} */
-    const nodeToStackMap = new Map();
-    nodeToStackMap.set(programNode, []);
-    for (let i = 0; i < samples.length; ++i) {
-      let node = jsProfileModel.nodeByIndex(i);
-      if (!node) {
-        console.error(`Node with unknown id ${samples[i]} at index ${i}`);
-        continue;
-      }
-      if (node === gcNode || node === idleNode)
-        continue;
-      let callFrames = nodeToStackMap.get(node);
-      if (!callFrames) {
-        callFrames = /** @type {!Array<!Protocol.Runtime.CallFrame>} */ (new Array(node.depth + 1));
-        nodeToStackMap.set(node, callFrames);
-        for (let j = 0; node.parent; node = node.parent)
-          callFrames[j++] = /** @type {!Protocol.Runtime.CallFrame} */ (node);
-      }
-      const jsSampleEvent = new SDK.TracingModel.Event(
-          SDK.TracingModel.DevToolsTimelineEventCategory, TimelineModel.TimelineModel.RecordType.JSSample,
-          SDK.TracingModel.Phase.Instant, timestamps[i], thread);
-      jsSampleEvent.args['data'] = {stackTrace: callFrames};
-      jsEvents.push(jsSampleEvent);
-    }
-    return jsEvents;
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  static generateJSFrameEvents(events) {
-    /**
-     * @param {!Protocol.Runtime.CallFrame} frame1
-     * @param {!Protocol.Runtime.CallFrame} frame2
-     * @return {boolean}
-     */
-    function equalFrames(frame1, frame2) {
-      return frame1.scriptId === frame2.scriptId &&
-             frame1.functionName === frame2.functionName &&
-             frame1.lineNumber === frame2.lineNumber;
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     * @return {boolean}
-     */
-    function isJSInvocationEvent(e) {
-      switch (e.name) {
-        case TimelineModel.TimelineModel.RecordType.RunMicrotasks:
-        case TimelineModel.TimelineModel.RecordType.FunctionCall:
-        case TimelineModel.TimelineModel.RecordType.EvaluateScript:
-        case TimelineModel.TimelineModel.RecordType.EvaluateModule:
-        case TimelineModel.TimelineModel.RecordType.EventDispatch:
-        case TimelineModel.TimelineModel.RecordType.V8Execute:
-          return true;
-      }
-      return false;
-    }
-
-    const jsFrameEvents = [];
-    const jsFramesStack = [];
-    const lockedJsStackDepth = [];
-    let ordinal = 0;
-    const showAllEvents = Runtime.experiments.isEnabled('timelineShowAllEvents');
-    const showRuntimeCallStats = Runtime.experiments.isEnabled('timelineV8RuntimeCallStats');
-    const showNativeFunctions = Common.moduleSetting('showNativeFunctionsInJSProfile').get();
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onStartEvent(e) {
-      e.ordinal = ++ordinal;
-      extractStackTrace(e);
-      // For the duration of the event we cannot go beyond the stack associated with it.
-      lockedJsStackDepth.push(jsFramesStack.length);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     * @param {?SDK.TracingModel.Event} parent
-     */
-    function onInstantEvent(e, parent) {
-      e.ordinal = ++ordinal;
-      if (parent && isJSInvocationEvent(parent))
-        extractStackTrace(e);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onEndEvent(e) {
-      truncateJSStack(lockedJsStackDepth.pop(), e.endTime);
-    }
-
-    /**
-     * @param {number} depth
-     * @param {number} time
-     */
-    function truncateJSStack(depth, time) {
-      if (lockedJsStackDepth.length) {
-        const lockedDepth = lockedJsStackDepth.peekLast();
-        if (depth < lockedDepth) {
-          console.error(`Child stack is shallower (${depth}) than the parent stack (${lockedDepth}) at ${time}`);
-          depth = lockedDepth;
-        }
-      }
-      if (jsFramesStack.length < depth) {
-        console.error(`Trying to truncate higher than the current stack size at ${time}`);
-        depth = jsFramesStack.length;
-      }
-      for (let k = 0; k < jsFramesStack.length; ++k)
-        jsFramesStack[k].setEndTime(time);
-      jsFramesStack.length = depth;
-    }
-
-    /**
-     * @param {string} name
-     * @return {boolean}
-     */
-    function showNativeName(name) {
-      return showRuntimeCallStats && !!TimelineModel.TimelineJSProfileProcessor.nativeGroup(name);
-    }
-
-    /**
-     * @param {!Array<!Protocol.Runtime.CallFrame>} stack
-     */
-    function filterStackFrames(stack) {
-      if (showAllEvents)
-        return;
-      let previousNativeFrameName = null;
-      let j = 0;
-      for (let i = 0; i < stack.length; ++i) {
-        const frame = stack[i];
-        const url = frame.url;
-        const isNativeFrame = url && url.startsWith('native ');
-        if (!showNativeFunctions && isNativeFrame)
-          continue;
-        const isNativeRuntimeFrame = TimelineModel.TimelineJSProfileProcessor.isNativeRuntimeFrame(frame);
-        if (isNativeRuntimeFrame && !showNativeName(frame.functionName))
-          continue;
-        const nativeFrameName =
-            isNativeRuntimeFrame ? TimelineModel.TimelineJSProfileProcessor.nativeGroup(frame.functionName) : null;
-        if (previousNativeFrameName && previousNativeFrameName === nativeFrameName)
-          continue;
-        previousNativeFrameName = nativeFrameName;
-        stack[j++] = frame;
-      }
-      stack.length = j;
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function extractStackTrace(e) {
-      const recordTypes = TimelineModel.TimelineModel.RecordType;
-      /** @type {!Array<!Protocol.Runtime.CallFrame>} */
-      const callFrames = e.name === recordTypes.JSSample ? e.args['data']['stackTrace'].slice().reverse() :
-                                                           jsFramesStack.map(frameEvent => frameEvent.args['data']);
-      filterStackFrames(callFrames);
-      const endTime = e.endTime || e.startTime;
-      const minFrames = Math.min(callFrames.length, jsFramesStack.length);
-      let i;
-      for (i = lockedJsStackDepth.peekLast() || 0; i < minFrames; ++i) {
-        const newFrame = callFrames[i];
-        const oldFrame = jsFramesStack[i].args['data'];
-        if (!equalFrames(newFrame, oldFrame))
-          break;
-        jsFramesStack[i].setEndTime(Math.max(jsFramesStack[i].endTime, endTime));
-      }
-      truncateJSStack(i, e.startTime);
-      for (; i < callFrames.length; ++i) {
-        const frame = callFrames[i];
-        const jsFrameEvent = new SDK.TracingModel.Event(
-            SDK.TracingModel.DevToolsTimelineEventCategory, recordTypes.JSFrame, SDK.TracingModel.Phase.Complete,
-            e.startTime, e.thread);
-        jsFrameEvent.ordinal = e.ordinal;
-        jsFrameEvent.addArgs({data: frame});
-        jsFrameEvent.setEndTime(endTime);
-        jsFramesStack.push(jsFrameEvent);
-        jsFrameEvents.push(jsFrameEvent);
-      }
-    }
-
-    const firstTopLevelEvent = events.find(SDK.TracingModel.isTopLevelEvent);
-    const startTime = firstTopLevelEvent ? firstTopLevelEvent.startTime : 0;
-    TimelineModel.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, onInstantEvent, startTime);
-    return jsFrameEvents;
-  }
-
-  /**
-   * @param {!Protocol.Runtime.CallFrame} frame
-   * @return {boolean}
-   */
-  static isNativeRuntimeFrame(frame) {
-    return frame.url === 'native V8Runtime';
-  }
-
-  /**
-   * @param {string} nativeName
-   * @return {?TimelineModel.TimelineJSProfileProcessor.NativeGroups}
-   */
-  static nativeGroup(nativeName) {
-    if (nativeName.startsWith('Parse'))
-      return TimelineModel.TimelineJSProfileProcessor.NativeGroups.Parse;
-    if (nativeName.startsWith('Compile') || nativeName.startsWith('Recompile'))
-      return TimelineModel.TimelineJSProfileProcessor.NativeGroups.Compile;
-    return null;
-  }
-
-  /**
-   * @param {*} profile
-   * @return {!Array<!SDK.TracingManager.EventPayload>}
-   */
-  static buildTraceProfileFromCpuProfile(profile) {
-    if (!profile)
-      return [];
-    const events = [];
-    appendEvent('TracingStartedInPage', {'sessionId': '1'}, 0, 0, 'M');
-    const idToNode = new Map();
-    const nodes = profile['nodes'];
-    for (let i = 0; i < nodes.length; ++i)
-      idToNode.set(nodes[i].id, nodes[i]);
-    let programEvent = null;
-    let functionEvent = null;
-    let nextTime = profile.startTime;
-    let currentTime;
-    const samples = profile['samples'];
-    const timeDeltas = profile['timeDeltas'];
-    for (let i = 0; i < samples.length; ++i) {
-      currentTime = nextTime;
-      nextTime += timeDeltas[i];
-      const node = idToNode.get(samples[i]);
-      const name = node.callFrame.functionName;
-      if (name === '(idle)') {
-        closeEvents();
-        continue;
-      }
-      if (!programEvent)
-        programEvent = appendEvent('MessageLoop::RunTask', {}, currentTime, 0, 'X', 'toplevel');
-      if (name === '(program)') {
-        if (functionEvent) {
-          functionEvent.dur = currentTime - functionEvent.ts;
-          functionEvent = null;
-        }
-      } else {
-        // A JS function.
-        if (!functionEvent)
-          functionEvent = appendEvent('FunctionCall', {'sessionId': '1'}, currentTime);
-      }
-    }
-    closeEvents();
-    appendEvent('CpuProfile', {'cpuProfile': profile}, profile.endTime, 0, 'I');
-    return events;
-
-    function closeEvents() {
-      if (programEvent)
-        programEvent.dur = currentTime - programEvent.ts;
-      if (functionEvent)
-        functionEvent.dur = currentTime - functionEvent.ts;
-      programEvent = null;
-      functionEvent = null;
-    }
-
-    /**
-     * @param {string} name
-     * @param {*} data
-     * @param {number} ts
-     * @param {number=} dur
-     * @param {string=} ph
-     * @param {string=} cat
-     * @return {!SDK.TracingManager.EventPayload}
-     */
-    function appendEvent(name, data, ts, dur, ph, cat) {
-      const event = /** @type {!SDK.TracingManager.EventPayload} */ ({
-        cat: cat || 'disabled-by-default-devtools.timeline',
-        name: name,
-        ph: ph || 'X',
-        pid: 1,
-        tid: 1,
-        ts: ts,
-        args: {data: data}
-      });
-      if (dur)
-        event.dur = dur;
-      events.push(event);
-      return event;
-    }
-  }
-};
-
-/** @enum {string} */
-TimelineModel.TimelineJSProfileProcessor.NativeGroups = {
-  'Compile': 'Compile',
-  'Parse': 'Parse'
-};
diff --git a/front_end/timeline_model/TimelineModel.js b/front_end/timeline_model/TimelineModel.js
deleted file mode 100644
index 675727a..0000000
--- a/front_end/timeline_model/TimelineModel.js
+++ /dev/null
@@ -1,2011 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-TimelineModel.TimelineModel = class {
-  constructor() {
-    this._reset();
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {function(!SDK.TracingModel.Event)} onStartEvent
-   * @param {function(!SDK.TracingModel.Event)} onEndEvent
-   * @param {function(!SDK.TracingModel.Event,?SDK.TracingModel.Event)|undefined=} onInstantEvent
-   * @param {number=} startTime
-   * @param {number=} endTime
-   * @param {function(!SDK.TracingModel.Event):boolean=} filter
-   */
-  static forEachEvent(events, onStartEvent, onEndEvent, onInstantEvent, startTime, endTime, filter) {
-    startTime = startTime || 0;
-    endTime = endTime || Infinity;
-    const stack = [];
-    const startEvent = TimelineModel.TimelineModel._topLevelEventEndingAfter(events, startTime);
-    for (let i = startEvent; i < events.length; ++i) {
-      const e = events[i];
-      if ((e.endTime || e.startTime) < startTime)
-        continue;
-      if (e.startTime >= endTime)
-        break;
-      if (SDK.TracingModel.isAsyncPhase(e.phase) || SDK.TracingModel.isFlowPhase(e.phase))
-        continue;
-      while (stack.length && stack.peekLast().endTime <= e.startTime)
-        onEndEvent(stack.pop());
-      if (filter && !filter(e))
-        continue;
-      if (e.duration) {
-        onStartEvent(e);
-        stack.push(e);
-      } else {
-        onInstantEvent && onInstantEvent(e, stack.peekLast() || null);
-      }
-    }
-    while (stack.length)
-      onEndEvent(stack.pop());
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {number} time
-   */
-  static _topLevelEventEndingAfter(events, time) {
-    let index = events.upperBound(time, (time, event) => time - event.startTime) - 1;
-    while (index > 0 && !SDK.TracingModel.isTopLevelEvent(events[index]))
-      index--;
-    return Math.max(index, 0);
-  }
-
-  /**
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  static isVisible(filters, event) {
-    for (let i = 0; i < filters.length; ++i) {
-      if (!filters[i].accept(event))
-        return false;
-    }
-    return true;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  static isMarkerEvent(event) {
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    switch (event.name) {
-      case recordTypes.TimeStamp:
-      case recordTypes.MarkFirstPaint:
-      case recordTypes.MarkFCP:
-      case recordTypes.MarkFMP:
-      case recordTypes.MarkFMPCandidate:
-        return true;
-      case recordTypes.MarkDOMContent:
-      case recordTypes.MarkLoad:
-        return event.args['data']['isMainFrame'];
-      default:
-        return false;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {string} field
-   * @return {string}
-   */
-  static globalEventId(event, field) {
-    const data = event.args['data'] || event.args['beginData'];
-    const id = data && data[field];
-    if (!id)
-      return '';
-    return `${event.thread.process().id()}.${id}`;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {string}
-   */
-  static eventFrameId(event) {
-    const data = event.args['data'] || event.args['beginData'];
-    return (data && data['frame']) || '';
-  }
-
-  /**
-   * @return {!Array<!SDK.CPUProfileDataModel>}
-   */
-  cpuProfiles() {
-    return this._cpuProfiles;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?SDK.Target}
-   */
-  targetByEvent(event) {
-    // FIXME: Consider returning null for loaded traces.
-    const workerId = this._workerIdByThread.get(event.thread);
-    const mainTarget = SDK.targetManager.mainTarget();
-    return workerId ? SDK.targetManager.targetById(workerId) : mainTarget;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {boolean=} produceTraceStartedInPage
-   */
-  setEvents(tracingModel, produceTraceStartedInPage) {
-    this._reset();
-    this._resetProcessingState();
-
-    this._minimumRecordTime = tracingModel.minimumRecordTime();
-    this._maximumRecordTime = tracingModel.maximumRecordTime();
-
-    this._processSyncBrowserEvents(tracingModel);
-    if (this._browserFrameTracking) {
-      this._processThreadsForBrowserFrames(tracingModel);
-    } else {
-      const metadataEvents = this._processMetadataEvents(tracingModel, !!produceTraceStartedInPage);
-      if (Runtime.experiments.isEnabled('timelineShowAllProcesses'))
-        this._processAllThreads(tracingModel, /** @type {!SDK.TracingModel.Event} */ (metadataEvents.page.peekLast()));
-      else
-        this._processMetadataAndThreads(tracingModel, metadataEvents);
-    }
-    this._inspectedTargetEvents.sort(SDK.TracingModel.Event.compareStartTime);
-    this._processAsyncBrowserEvents(tracingModel);
-    this._buildGPUEvents(tracingModel);
-    this._resetProcessingState();
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {!SDK.TracingModel.Event} lastPageMetaEvent
-   */
-  _processAllThreads(tracingModel, lastPageMetaEvent) {
-    for (const process of tracingModel.sortedProcesses()) {
-      for (const thread of process.sortedThreads()) {
-        this._processThreadEvents(
-            tracingModel, [{from: 0, to: Infinity}], thread, thread === lastPageMetaEvent.thread, false, true, null);
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {!TimelineModel.TimelineModel.MetadataEvents} metadataEvents
-   */
-  _processMetadataAndThreads(tracingModel, metadataEvents) {
-    let startTime = 0;
-    for (let i = 0, length = metadataEvents.page.length; i < length; i++) {
-      const metaEvent = metadataEvents.page[i];
-      const process = metaEvent.thread.process();
-      const endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity;
-      this._legacyCurrentPage = metaEvent.args['data'] && metaEvent.args['data']['page'];
-      for (const thread of process.sortedThreads()) {
-        let workerUrl = null;
-        if (thread.name() === TimelineModel.TimelineModel.WorkerThreadName ||
-            thread.name() === TimelineModel.TimelineModel.WorkerThreadNameLegacy) {
-          const workerMetaEvent = metadataEvents.workers.find(e => {
-            if (e.args['data']['workerThreadId'] !== thread.id())
-              return false;
-            // This is to support old traces.
-            if (e.args['data']['sessionId'] === this._sessionId)
-              return true;
-            return !!this._pageFrames.get(TimelineModel.TimelineModel.eventFrameId(e));
-          });
-          if (!workerMetaEvent)
-            continue;
-          const workerId = workerMetaEvent.args['data']['workerId'];
-          if (workerId)
-            this._workerIdByThread.set(thread, workerId);
-          workerUrl = workerMetaEvent.args['data']['url'] || '';
-        }
-        this._processThreadEvents(
-            tracingModel, [{from: startTime, to: endTime}], thread, thread === metaEvent.thread, !!workerUrl, true,
-            workerUrl);
-      }
-      startTime = endTime;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   */
-  _processThreadsForBrowserFrames(tracingModel) {
-    const processData = new Map();
-    for (const frame of this._pageFrames.values()) {
-      for (let i = 0; i < frame.processes.length; i++) {
-        const pid = frame.processes[i].processId;
-        let data = processData.get(pid);
-        if (!data) {
-          data = [];
-          processData.set(pid, data);
-        }
-        const to = i === frame.processes.length - 1 ? (frame.deletedTime || this._maximumRecordTime) :
-                                                      frame.processes[i + 1].time;
-        data.push({from: frame.processes[i].time, to: to, main: !frame.parent, url: frame.processes[i].url});
-      }
-    }
-    const allMetadataEvents = tracingModel.devToolsMetadataEvents();
-    for (const process of tracingModel.sortedProcesses()) {
-      const data = processData.get(process.id());
-      if (!data)
-        continue;
-      data.sort((a, b) => a.from - b.from || a.to - b.to);
-      const ranges = [];
-      let lastUrl = null;
-      let lastMainUrl = null;
-      let hasMain = false;
-      for (const item of data) {
-        if (!ranges.length || item.from > ranges.peekLast().to)
-          ranges.push({from: item.from, to: item.to});
-        else
-          ranges.peekLast().to = item.to;
-        if (item.main)
-          hasMain = true;
-        if (item.url) {
-          if (item.main)
-            lastMainUrl = item.url;
-          lastUrl = item.url;
-        }
-      }
-
-      for (const thread of process.sortedThreads()) {
-        if (thread.name() === TimelineModel.TimelineModel.RendererMainThreadName) {
-          this._processThreadEvents(
-              tracingModel, ranges, thread, true /* isMainThread */, false /* isWorker */, hasMain,
-              hasMain ? lastMainUrl : lastUrl);
-        } else if (
-            thread.name() === TimelineModel.TimelineModel.WorkerThreadName ||
-            thread.name() === TimelineModel.TimelineModel.WorkerThreadNameLegacy) {
-          const workerMetaEvent = allMetadataEvents.find(e => {
-            if (e.name !== TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker)
-              return false;
-            if (e.thread.process() !== process)
-              return false;
-            if (e.args['data']['workerThreadId'] !== thread.id())
-              return false;
-            return !!this._pageFrames.get(TimelineModel.TimelineModel.eventFrameId(e));
-          });
-          if (!workerMetaEvent)
-            continue;
-          this._workerIdByThread.set(thread, workerMetaEvent.args['data']['workerId'] || '');
-          this._processThreadEvents(
-              tracingModel, ranges, thread, false /* isMainThread */, true /* isWorker */, false /* forMainFrame */,
-              workerMetaEvent.args['data']['url'] || '');
-        } else {
-          this._processThreadEvents(
-              tracingModel, ranges, thread, false /* isMainThread */, false /* isWorker */, false /* forMainFrame */,
-              null);
-        }
-      }
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {boolean} produceTraceStartedInPage
-   * @return {!TimelineModel.TimelineModel.MetadataEvents}
-   */
-  _processMetadataEvents(tracingModel, produceTraceStartedInPage) {
-    const metadataEvents = tracingModel.devToolsMetadataEvents();
-
-    const pageDevToolsMetadataEvents = [];
-    const workersDevToolsMetadataEvents = [];
-    for (const event of metadataEvents) {
-      if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage) {
-        pageDevToolsMetadataEvents.push(event);
-        if (event.args['data'] && event.args['data']['persistentIds'])
-          this._persistentIds = true;
-        const frames = ((event.args['data'] && event.args['data']['frames']) || []);
-        frames.forEach(payload => this._addPageFrame(event, payload));
-        this._mainFrame = this.rootFrames()[0];
-      } else if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker) {
-        workersDevToolsMetadataEvents.push(event);
-      } else if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser) {
-        console.assert(!this._mainFrameNodeId, 'Multiple sessions in trace');
-        this._mainFrameNodeId = event.args['frameTreeNodeId'];
-      }
-    }
-    if (!pageDevToolsMetadataEvents.length) {
-      // The trace is probably coming not from DevTools. Make a mock Metadata event.
-      const pageMetaEvent = produceTraceStartedInPage ? this._makeMockPageMetadataEvent(tracingModel) : null;
-      if (!pageMetaEvent) {
-        console.error(TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage + ' event not found.');
-        return {page: [], workers: []};
-      }
-      pageDevToolsMetadataEvents.push(pageMetaEvent);
-    }
-    const sessionId =
-        pageDevToolsMetadataEvents[0].args['sessionId'] || pageDevToolsMetadataEvents[0].args['data']['sessionId'];
-    this._sessionId = sessionId;
-
-    const mismatchingIds = new Set();
-    /**
-     * @param {!SDK.TracingModel.Event} event
-     * @return {boolean}
-     */
-    function checkSessionId(event) {
-      let args = event.args;
-      // FIXME: put sessionId into args["data"] for TracingStartedInPage event.
-      if (args['data'])
-        args = args['data'];
-      const id = args['sessionId'];
-      if (id === sessionId)
-        return true;
-      mismatchingIds.add(id);
-      return false;
-    }
-    const result = {
-      page: pageDevToolsMetadataEvents.filter(checkSessionId).sort(SDK.TracingModel.Event.compareStartTime),
-      workers: workersDevToolsMetadataEvents.sort(SDK.TracingModel.Event.compareStartTime)
-    };
-    if (mismatchingIds.size) {
-      Common.console.error(
-          'Timeline recording was started in more than one page simultaneously. Session id mismatch: ' +
-          this._sessionId + ' and ' + mismatchingIds.valuesArray() + '.');
-    }
-    return result;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @return {?SDK.TracingModel.Event}
-   */
-  _makeMockPageMetadataEvent(tracingModel) {
-    const rendererMainThreadName = TimelineModel.TimelineModel.RendererMainThreadName;
-    // TODO(alph): Support selection of process and thread.
-    const processes = tracingModel.sortedProcesses();
-    const process = processes.find(p => !!p.threadByName(rendererMainThreadName)) || processes[0];
-    if (!process)
-      return null;
-    const thread = process.threadByName(rendererMainThreadName) || process.sortedThreads()[0];
-    if (!thread)
-      return null;
-    const pageMetaEvent = new SDK.TracingModel.Event(
-        SDK.TracingModel.DevToolsMetadataEventCategory,
-        TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage, SDK.TracingModel.Phase.Metadata,
-        tracingModel.minimumRecordTime(), thread);
-    pageMetaEvent.addArgs({'data': {'sessionId': 'mockSessionId'}});
-    return pageMetaEvent;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   */
-  _processSyncBrowserEvents(tracingModel) {
-    const browserMain = SDK.TracingModel.browserMainThread(tracingModel);
-    if (browserMain)
-      browserMain.events().forEach(this._processBrowserEvent, this);
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   */
-  _processAsyncBrowserEvents(tracingModel) {
-    const browserMain = SDK.TracingModel.browserMainThread(tracingModel);
-    if (browserMain)
-      this._processAsyncEvents(browserMain.asyncEvents(), [{from: 0, to: Infinity}]);
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   */
-  _buildGPUEvents(tracingModel) {
-    const thread = tracingModel.threadByName('GPU Process', 'CrGpuMain');
-    if (!thread)
-      return;
-    const gpuEventName = TimelineModel.TimelineModel.RecordType.GPUTask;
-    this._ensureNamedTrack(TimelineModel.TimelineModel.TrackType.GPU).events =
-        thread.events().filter(event => event.name === gpuEventName);
-  }
-
-  _resetProcessingState() {
-    this._asyncEventTracker = new TimelineModel.TimelineAsyncEventTracker();
-    this._invalidationTracker = new TimelineModel.InvalidationTracker();
-    this._layoutInvalidate = {};
-    this._lastScheduleStyleRecalculation = {};
-    this._paintImageEventByPixelRefId = {};
-    this._lastPaintForLayer = {};
-    this._lastRecalculateStylesEvent = null;
-    this._currentScriptEvent = null;
-    this._eventStack = [];
-    /** @type {!Set<string>} */
-    this._knownInputEvents = new Set();
-    this._browserFrameTracking = false;
-    this._persistentIds = false;
-    this._legacyCurrentPage = null;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {!SDK.TracingModel.Thread} thread
-   * @return {?SDK.CPUProfileDataModel}
-   */
-  _extractCpuProfile(tracingModel, thread) {
-    const events = thread.events();
-    let cpuProfile;
-
-    // Check for legacy CpuProfile event format first.
-    let cpuProfileEvent = events.peekLast();
-    if (cpuProfileEvent && cpuProfileEvent.name === TimelineModel.TimelineModel.RecordType.CpuProfile) {
-      const eventData = cpuProfileEvent.args['data'];
-      cpuProfile = /** @type {?Protocol.Profiler.Profile} */ (eventData && eventData['cpuProfile']);
-    }
-
-    if (!cpuProfile) {
-      cpuProfileEvent = events.find(e => e.name === TimelineModel.TimelineModel.RecordType.Profile);
-      if (!cpuProfileEvent)
-        return null;
-      const profileGroup = tracingModel.profileGroup(cpuProfileEvent.id);
-      if (!profileGroup) {
-        Common.console.error('Invalid CPU profile format.');
-        return null;
-      }
-      cpuProfile = /** @type {!Protocol.Profiler.Profile} */ (
-          {startTime: cpuProfileEvent.args['data']['startTime'], endTime: 0, nodes: [], samples: [], timeDeltas: []});
-      for (const profileEvent of profileGroup.children) {
-        const eventData = profileEvent.args['data'];
-        if ('startTime' in eventData)
-          cpuProfile.startTime = eventData['startTime'];
-        if ('endTime' in eventData)
-          cpuProfile.endTime = eventData['endTime'];
-        const nodesAndSamples = eventData['cpuProfile'] || {};
-        cpuProfile.nodes.pushAll(nodesAndSamples['nodes'] || []);
-        cpuProfile.samples.pushAll(nodesAndSamples['samples'] || []);
-        cpuProfile.timeDeltas.pushAll(eventData['timeDeltas'] || []);
-        if (cpuProfile.samples.length !== cpuProfile.timeDeltas.length) {
-          Common.console.error('Failed to parse CPU profile.');
-          return null;
-        }
-      }
-      if (!cpuProfile.endTime)
-        cpuProfile.endTime = cpuProfile.timeDeltas.reduce((x, y) => x + y, cpuProfile.startTime);
-    }
-
-    try {
-      const jsProfileModel = new SDK.CPUProfileDataModel(cpuProfile);
-      this._cpuProfiles.push(jsProfileModel);
-      return jsProfileModel;
-    } catch (e) {
-      Common.console.error('Failed to parse CPU profile.');
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {!SDK.TracingModel.Thread} thread
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  _injectJSFrameEvents(tracingModel, thread) {
-    const jsProfileModel = this._extractCpuProfile(tracingModel, thread);
-    let events = thread.events();
-    const jsSamples = jsProfileModel ?
-        TimelineModel.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile(jsProfileModel, thread) :
-        null;
-    if (jsSamples && jsSamples.length)
-      events = events.mergeOrdered(jsSamples, SDK.TracingModel.Event.orderedCompareStartTime);
-    if (jsSamples || events.some(e => e.name === TimelineModel.TimelineModel.RecordType.JSSample)) {
-      const jsFrameEvents = TimelineModel.TimelineJSProfileProcessor.generateJSFrameEvents(events);
-      if (jsFrameEvents && jsFrameEvents.length)
-        events = jsFrameEvents.mergeOrdered(events, SDK.TracingModel.Event.orderedCompareStartTime);
-    }
-    return events;
-  }
-
-  /**
-   * @param {!SDK.TracingModel} tracingModel
-   * @param {!Array<!{from: number, to: number}>} ranges
-   * @param {!SDK.TracingModel.Thread} thread
-   * @param {boolean} isMainThread
-   * @param {boolean} isWorker
-   * @param {boolean} forMainFrame
-   * @param {?string} url
-   */
-  _processThreadEvents(tracingModel, ranges, thread, isMainThread, isWorker, forMainFrame, url) {
-    const track = new TimelineModel.TimelineModel.Track();
-    track.name = thread.name();
-    track.type = TimelineModel.TimelineModel.TrackType.Other;
-    if (isMainThread) {
-      track.type = TimelineModel.TimelineModel.TrackType.MainThread;
-      track.url = url || null;
-      track.forMainFrame = forMainFrame;
-    } else if (isWorker) {
-      track.type = TimelineModel.TimelineModel.TrackType.Worker;
-      track.url = url;
-    } else if (thread.name().startsWith('CompositorTileWorker')) {
-      track.type = TimelineModel.TimelineModel.TrackType.Raster;
-    }
-    this._tracks.push(track);
-
-    const events = this._injectJSFrameEvents(tracingModel, thread);
-    this._eventStack = [];
-    const eventStack = this._eventStack;
-
-    for (const range of ranges) {
-      let i = events.lowerBound(range.from, (time, event) => time - event.startTime);
-      for (; i < events.length; i++) {
-        const event = events[i];
-        if (event.startTime >= range.to)
-          break;
-        while (eventStack.length && eventStack.peekLast().endTime <= event.startTime)
-          eventStack.pop();
-        if (!this._processEvent(event))
-          continue;
-        if (!SDK.TracingModel.isAsyncPhase(event.phase) && event.duration) {
-          if (eventStack.length) {
-            const parent = eventStack.peekLast();
-            parent.selfTime -= event.duration;
-            if (parent.selfTime < 0)
-              this._fixNegativeDuration(parent, event);
-          }
-          event.selfTime = event.duration;
-          if (!eventStack.length)
-            track.tasks.push(event);
-          eventStack.push(event);
-        }
-        if (TimelineModel.TimelineModel.isMarkerEvent(event))
-          this._eventDividers.push(event);
-
-        track.events.push(event);
-        this._inspectedTargetEvents.push(event);
-      }
-    }
-    this._processAsyncEvents(thread.asyncEvents(), ranges);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {!SDK.TracingModel.Event} child
-   */
-  _fixNegativeDuration(event, child) {
-    const epsilon = 1e-3;
-    if (event.selfTime < -epsilon) {
-      console.error(
-          `Children are longer than parent at ${event.startTime} ` +
-          `(${(child.startTime - this.minimumRecordTime()).toFixed(3)} by ${(-event.selfTime).toFixed(3)}`);
-    }
-    event.selfTime = 0;
-  }
-
-  /**
-   * @param {!Array<!SDK.TracingModel.AsyncEvent>} asyncEvents
-   * @param {!Array<!{from: number, to: number}>} ranges
-   */
-  _processAsyncEvents(asyncEvents, ranges) {
-    const groups = new Map();
-
-    /**
-     * @param {!TimelineModel.TimelineModel.TrackType} type
-     * @return {!Array<!SDK.TracingModel.AsyncEvent>}
-     */
-    function group(type) {
-      if (!groups.has(type))
-        groups.set(type, []);
-      return groups.get(type);
-    }
-
-    for (const range of ranges) {
-      let i = asyncEvents.lowerBound(range.from, function(time, asyncEvent) {
-        return time - asyncEvent.startTime;
-      });
-
-      for (; i < asyncEvents.length; ++i) {
-        const asyncEvent = asyncEvents[i];
-        if (asyncEvent.startTime >= range.to)
-          break;
-
-        if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.Console)) {
-          group(TimelineModel.TimelineModel.TrackType.Console).push(asyncEvent);
-          continue;
-        }
-
-        if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.UserTiming)) {
-          group(TimelineModel.TimelineModel.TrackType.UserTiming).push(asyncEvent);
-          continue;
-        }
-
-        if (asyncEvent.name === TimelineModel.TimelineModel.RecordType.Animation) {
-          group(TimelineModel.TimelineModel.TrackType.Animation).push(asyncEvent);
-          continue;
-        }
-
-        if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo) ||
-            asyncEvent.name === TimelineModel.TimelineModel.RecordType.ImplSideFling) {
-          const lastStep = asyncEvent.steps.peekLast();
-          // FIXME: fix event termination on the back-end instead.
-          if (lastStep.phase !== SDK.TracingModel.Phase.AsyncEnd)
-            continue;
-          const data = lastStep.args['data'];
-          asyncEvent.causedFrame = !!(data && data['INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT']);
-          if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) {
-            if (!this._knownInputEvents.has(lastStep.id))
-              continue;
-            if (asyncEvent.name === TimelineModel.TimelineModel.RecordType.InputLatencyMouseMove &&
-                !asyncEvent.causedFrame)
-              continue;
-            const rendererMain = data['INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT'];
-            if (rendererMain) {
-              const time = rendererMain['time'] / 1000;
-              TimelineModel.TimelineData.forEvent(asyncEvent.steps[0]).timeWaitingForMainThread =
-                  time - asyncEvent.steps[0].startTime;
-            }
-          }
-          group(TimelineModel.TimelineModel.TrackType.Input).push(asyncEvent);
-          continue;
-        }
-      }
-    }
-
-    for (const [type, events] of groups) {
-      const track = this._ensureNamedTrack(type);
-      track.asyncEvents = track.asyncEvents.mergeOrdered(events, SDK.TracingModel.Event.compareStartAndEndTime);
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  _processEvent(event) {
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    const eventStack = this._eventStack;
-
-    if (!eventStack.length) {
-      if (this._currentTaskLayoutAndRecalcEvents && this._currentTaskLayoutAndRecalcEvents.length) {
-        const totalTime = this._currentTaskLayoutAndRecalcEvents.reduce((time, event) => time + event.duration, 0);
-        if (totalTime > TimelineModel.TimelineModel.Thresholds.ForcedLayout) {
-          for (const e of this._currentTaskLayoutAndRecalcEvents) {
-            const timelineData = TimelineModel.TimelineData.forEvent(e);
-            timelineData.warning = e.name === recordTypes.Layout ?
-                TimelineModel.TimelineModel.WarningType.ForcedLayout :
-                TimelineModel.TimelineModel.WarningType.ForcedStyle;
-          }
-        }
-      }
-      this._currentTaskLayoutAndRecalcEvents = [];
-    }
-
-    if (this._currentScriptEvent && event.startTime > this._currentScriptEvent.endTime)
-      this._currentScriptEvent = null;
-
-    const eventData = event.args['data'] || event.args['beginData'] || {};
-    const timelineData = TimelineModel.TimelineData.forEvent(event);
-    if (eventData['stackTrace'])
-      timelineData.stackTrace = eventData['stackTrace'];
-    if (timelineData.stackTrace && event.name !== recordTypes.JSSample) {
-      // TraceEvents come with 1-based line & column numbers. The frontend code
-      // requires 0-based ones. Adjust the values.
-      for (let i = 0; i < timelineData.stackTrace.length; ++i) {
-        --timelineData.stackTrace[i].lineNumber;
-        --timelineData.stackTrace[i].columnNumber;
-      }
-    }
-    let pageFrameId = TimelineModel.TimelineModel.eventFrameId(event);
-    if (!pageFrameId && eventStack.length)
-      pageFrameId = TimelineModel.TimelineData.forEvent(eventStack.peekLast()).frameId;
-    timelineData.frameId = pageFrameId || (this._mainFrame && this._mainFrame.frameId) || '';
-    this._asyncEventTracker.processEvent(event);
-    switch (event.name) {
-      case recordTypes.ResourceSendRequest:
-      case recordTypes.WebSocketCreate:
-        timelineData.setInitiator(eventStack.peekLast() || null);
-        timelineData.url = eventData['url'];
-        break;
-
-      case recordTypes.ScheduleStyleRecalculation:
-        this._lastScheduleStyleRecalculation[eventData['frame']] = event;
-        break;
-
-      case recordTypes.UpdateLayoutTree:
-      case recordTypes.RecalculateStyles:
-        this._invalidationTracker.didRecalcStyle(event);
-        if (event.args['beginData'])
-          timelineData.setInitiator(this._lastScheduleStyleRecalculation[event.args['beginData']['frame']]);
-        this._lastRecalculateStylesEvent = event;
-        if (this._currentScriptEvent)
-          this._currentTaskLayoutAndRecalcEvents.push(event);
-        break;
-
-      case recordTypes.ScheduleStyleInvalidationTracking:
-      case recordTypes.StyleRecalcInvalidationTracking:
-      case recordTypes.StyleInvalidatorInvalidationTracking:
-      case recordTypes.LayoutInvalidationTracking:
-      case recordTypes.LayerInvalidationTracking:
-      case recordTypes.PaintInvalidationTracking:
-      case recordTypes.ScrollInvalidationTracking:
-        this._invalidationTracker.addInvalidation(new TimelineModel.InvalidationTrackingEvent(event));
-        break;
-
-      case recordTypes.InvalidateLayout: {
-        // Consider style recalculation as a reason for layout invalidation,
-        // but only if we had no earlier layout invalidation records.
-        let layoutInitator = event;
-        const frameId = eventData['frame'];
-        if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesEvent &&
-            this._lastRecalculateStylesEvent.endTime > event.startTime)
-          layoutInitator = TimelineModel.TimelineData.forEvent(this._lastRecalculateStylesEvent).initiator();
-        this._layoutInvalidate[frameId] = layoutInitator;
-        break;
-      }
-
-      case recordTypes.Layout: {
-        this._invalidationTracker.didLayout(event);
-        const frameId = event.args['beginData']['frame'];
-        timelineData.setInitiator(this._layoutInvalidate[frameId]);
-        // In case we have no closing Layout event, endData is not available.
-        if (event.args['endData'])
-          timelineData.backendNodeId = event.args['endData']['rootNode'];
-        this._layoutInvalidate[frameId] = null;
-        if (this._currentScriptEvent)
-          this._currentTaskLayoutAndRecalcEvents.push(event);
-        break;
-      }
-
-      case recordTypes.EventDispatch:
-        if (event.duration > TimelineModel.TimelineModel.Thresholds.RecurringHandler)
-          timelineData.warning = TimelineModel.TimelineModel.WarningType.LongHandler;
-        break;
-
-      case recordTypes.TimerFire:
-      case recordTypes.FireAnimationFrame:
-        if (event.duration > TimelineModel.TimelineModel.Thresholds.RecurringHandler)
-          timelineData.warning = TimelineModel.TimelineModel.WarningType.LongRecurringHandler;
-        break;
-
-      case recordTypes.FunctionCall:
-        // Compatibility with old format.
-        if (typeof eventData['scriptName'] === 'string')
-          eventData['url'] = eventData['scriptName'];
-        if (typeof eventData['scriptLine'] === 'number')
-          eventData['lineNumber'] = eventData['scriptLine'];
-
-      // Fallthrough.
-
-      case recordTypes.EvaluateScript:
-      case recordTypes.CompileScript:
-        if (typeof eventData['lineNumber'] === 'number')
-          --eventData['lineNumber'];
-        if (typeof eventData['columnNumber'] === 'number')
-          --eventData['columnNumber'];
-
-      // Fallthrough intended.
-
-      case recordTypes.RunMicrotasks:
-        // Microtasks technically are not necessarily scripts, but for purpose of
-        // forced sync style recalc or layout detection they are.
-        if (!this._currentScriptEvent)
-          this._currentScriptEvent = event;
-        break;
-
-      case recordTypes.SetLayerTreeId:
-        // This is to support old traces.
-        if (this._sessionId && eventData['sessionId'] && this._sessionId === eventData['sessionId']) {
-          this._mainFrameLayerTreeId = eventData['layerTreeId'];
-          break;
-        }
-
-        // We currently only show layer tree for the main frame.
-        const frameId = TimelineModel.TimelineModel.eventFrameId(event);
-        const pageFrame = this._pageFrames.get(frameId);
-        if (!pageFrame || pageFrame.parent)
-          return false;
-        this._mainFrameLayerTreeId = eventData['layerTreeId'];
-        break;
-
-      case recordTypes.Paint: {
-        this._invalidationTracker.didPaint(event);
-        timelineData.backendNodeId = eventData['nodeId'];
-        // Only keep layer paint events, skip paints for subframes that get painted to the same layer as parent.
-        if (!eventData['layerId'])
-          break;
-        const layerId = eventData['layerId'];
-        this._lastPaintForLayer[layerId] = event;
-        break;
-      }
-
-      case recordTypes.DisplayItemListSnapshot:
-      case recordTypes.PictureSnapshot: {
-        const layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
-        if (!layerUpdateEvent || layerUpdateEvent.args['layerTreeId'] !== this._mainFrameLayerTreeId)
-          break;
-        const paintEvent = this._lastPaintForLayer[layerUpdateEvent.args['layerId']];
-        if (paintEvent) {
-          TimelineModel.TimelineData.forEvent(paintEvent).picture =
-              /** @type {!SDK.TracingModel.ObjectSnapshot} */ (event);
-        }
-        break;
-      }
-
-      case recordTypes.ScrollLayer:
-        timelineData.backendNodeId = eventData['nodeId'];
-        break;
-
-      case recordTypes.PaintImage:
-        timelineData.backendNodeId = eventData['nodeId'];
-        timelineData.url = eventData['url'];
-        break;
-
-      case recordTypes.DecodeImage:
-      case recordTypes.ResizeImage: {
-        let paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
-        if (!paintImageEvent) {
-          const decodeLazyPixelRefEvent = this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);
-          paintImageEvent = decodeLazyPixelRefEvent &&
-              this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args['LazyPixelRef']];
-        }
-        if (!paintImageEvent)
-          break;
-        const paintImageData = TimelineModel.TimelineData.forEvent(paintImageEvent);
-        timelineData.backendNodeId = paintImageData.backendNodeId;
-        timelineData.url = paintImageData.url;
-        break;
-      }
-
-      case recordTypes.DrawLazyPixelRef: {
-        const paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
-        if (!paintImageEvent)
-          break;
-        this._paintImageEventByPixelRefId[event.args['LazyPixelRef']] = paintImageEvent;
-        const paintImageData = TimelineModel.TimelineData.forEvent(paintImageEvent);
-        timelineData.backendNodeId = paintImageData.backendNodeId;
-        timelineData.url = paintImageData.url;
-        break;
-      }
-
-      case recordTypes.MarkDOMContent:
-      case recordTypes.MarkLoad: {
-        const frameId = TimelineModel.TimelineModel.eventFrameId(event);
-        if (!this._pageFrames.get(frameId))
-          return false;
-        break;
-      }
-
-      case recordTypes.CommitLoad: {
-        if (this._browserFrameTracking)
-          break;
-        const frameId = TimelineModel.TimelineModel.eventFrameId(event);
-        const isMainFrame = !!eventData['isMainFrame'];
-        const pageFrame = this._pageFrames.get(frameId);
-        if (pageFrame) {
-          pageFrame.update(event.startTime, eventData);
-        } else {
-          // We should only have one main frame which has persistent id,
-          // unless it's an old trace without 'persistentIds' flag.
-          if (!this._persistentIds) {
-            if (eventData['page'] && eventData['page'] !== this._legacyCurrentPage)
-              return false;
-          } else if (isMainFrame) {
-            return false;
-          } else if (!this._addPageFrame(event, eventData)) {
-            return false;
-          }
-        }
-        if (isMainFrame)
-          this._mainFrame = this._pageFrames.get(frameId);
-        break;
-      }
-
-      case recordTypes.FireIdleCallback:
-        if (event.duration >
-            eventData['allottedMilliseconds'] + TimelineModel.TimelineModel.Thresholds.IdleCallbackAddon)
-          timelineData.warning = TimelineModel.TimelineModel.WarningType.IdleDeadlineExceeded;
-        break;
-    }
-    return true;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  _processBrowserEvent(event) {
-    if (event.name === TimelineModel.TimelineModel.RecordType.LatencyInfoFlow) {
-      const frameId = event.args['frameTreeNodeId'];
-      if (typeof frameId === 'number' && frameId === this._mainFrameNodeId)
-        this._knownInputEvents.add(event.bind_id);
-      return;
-    }
-
-    if (event.hasCategory(SDK.TracingModel.DevToolsMetadataEventCategory) && event.args['data']) {
-      const data = event.args['data'];
-      if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser) {
-        if (!data['persistentIds'])
-          return;
-        this._browserFrameTracking = true;
-        this._mainFrameNodeId = data['frameTreeNodeId'];
-        const frames = data['frames'] || [];
-        frames.forEach(payload => {
-          const parent = payload['parent'] && this._pageFrames.get(payload['parent']);
-          if (payload['parent'] && !parent)
-            return;
-          let frame = this._pageFrames.get(payload['frame']);
-          if (!frame) {
-            frame = new TimelineModel.TimelineModel.PageFrame(payload);
-            this._pageFrames.set(frame.frameId, frame);
-            if (parent)
-              parent.addChild(frame);
-            else
-              this._mainFrame = frame;
-          }
-          // TODO(dgozman): this should use event.startTime, but due to races between tracing start
-          // in different processes we cannot do this yet.
-          frame.update(this._minimumRecordTime, payload);
-        });
-        return;
-      }
-      if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.FrameCommittedInBrowser &&
-          this._browserFrameTracking) {
-        let frame = this._pageFrames.get(data['frame']);
-        if (!frame) {
-          const parent = data['parent'] && this._pageFrames.get(data['parent']);
-          if (!parent)
-            return;
-          frame = new TimelineModel.TimelineModel.PageFrame(data);
-          this._pageFrames.set(frame.frameId, frame);
-          parent.addChild(frame);
-        }
-        frame.update(event.startTime, data);
-        return;
-      }
-      if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.ProcessReadyInBrowser &&
-          this._browserFrameTracking) {
-        const frame = this._pageFrames.get(data['frame']);
-        if (frame)
-          frame.processReady(data['processPseudoId'], data['processId']);
-        return;
-      }
-      if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.FrameDeletedInBrowser &&
-          this._browserFrameTracking) {
-        const frame = this._pageFrames.get(data['frame']);
-        if (frame)
-          frame.deletedTime = event.startTime;
-        return;
-      }
-    }
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel.TrackType} type
-   * @return {!TimelineModel.TimelineModel.Track}
-   */
-  _ensureNamedTrack(type) {
-    if (!this._namedTracks.has(type)) {
-      const track = new TimelineModel.TimelineModel.Track();
-      track.type = type;
-      this._tracks.push(track);
-      this._namedTracks.set(type, track);
-    }
-    return this._namedTracks.get(type);
-  }
-
-  /**
-   * @param {string} name
-   * @return {?SDK.TracingModel.Event}
-   */
-  _findAncestorEvent(name) {
-    for (let i = this._eventStack.length - 1; i >= 0; --i) {
-      const event = this._eventStack[i];
-      if (event.name === name)
-        return event;
-    }
-    return null;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {!Object} payload
-   * @return {boolean}
-   */
-  _addPageFrame(event, payload) {
-    const parent = payload['parent'] && this._pageFrames.get(payload['parent']);
-    if (payload['parent'] && !parent)
-      return false;
-    const pageFrame = new TimelineModel.TimelineModel.PageFrame(payload);
-    this._pageFrames.set(pageFrame.frameId, pageFrame);
-    pageFrame.update(event.startTime, payload);
-    if (parent)
-      parent.addChild(pageFrame);
-    return true;
-  }
-
-  _reset() {
-    /** @type {!Array<!TimelineModel.TimelineModel.Track>} */
-    this._tracks = [];
-    /** @type {!Map<!TimelineModel.TimelineModel.TrackType, !TimelineModel.TimelineModel.Track>} */
-    this._namedTracks = new Map();
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this._inspectedTargetEvents = [];
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this._eventDividers = [];
-    /** @type {?string} */
-    this._sessionId = null;
-    /** @type {?number} */
-    this._mainFrameNodeId = null;
-    /** @type {!Array<!SDK.CPUProfileDataModel>} */
-    this._cpuProfiles = [];
-    /** @type {!WeakMap<!SDK.TracingModel.Thread, string>} */
-    this._workerIdByThread = new WeakMap();
-    /** @type {!Map<string, !TimelineModel.TimelineModel.PageFrame>} */
-    this._pageFrames = new Map();
-    this._mainFrame = null;
-
-    this._minimumRecordTime = 0;
-    this._maximumRecordTime = 0;
-  }
-
-  /**
-   * @return {number}
-   */
-  minimumRecordTime() {
-    return this._minimumRecordTime;
-  }
-
-  /**
-   * @return {number}
-   */
-  maximumRecordTime() {
-    return this._maximumRecordTime;
-  }
-
-  /**
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  inspectedTargetEvents() {
-    return this._inspectedTargetEvents;
-  }
-
-  /**
-   * @return {!Array<!TimelineModel.TimelineModel.Track>}
-   */
-  tracks() {
-    return this._tracks;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEmpty() {
-    return this.minimumRecordTime() === 0 && this.maximumRecordTime() === 0;
-  }
-
-  /**
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  eventDividers() {
-    return this._eventDividers;
-  }
-
-  /**
-   * @return {!Array<!TimelineModel.TimelineModel.PageFrame>}
-   */
-  rootFrames() {
-    return Array.from(this._pageFrames.values()).filter(frame => !frame.parent);
-  }
-
-  /**
-   * @return {string}
-   */
-  pageURL() {
-    return this._mainFrame && this._mainFrame.url || '';
-  }
-
-  /**
-   * @param {string} frameId
-   * @return {?TimelineModel.TimelineModel.PageFrame}
-   */
-  pageFrameById(frameId) {
-    return frameId ? this._pageFrames.get(frameId) || null : null;
-  }
-
-  /**
-   * @return {!Array<!TimelineModel.TimelineModel.NetworkRequest>}
-   */
-  networkRequests() {
-    /** @type {!Map<string,!TimelineModel.TimelineModel.NetworkRequest>} */
-    const requests = new Map();
-    /** @type {!Array<!TimelineModel.TimelineModel.NetworkRequest>} */
-    const requestsList = [];
-    /** @type {!Array<!TimelineModel.TimelineModel.NetworkRequest>} */
-    const zeroStartRequestsList = [];
-    const types = TimelineModel.TimelineModel.RecordType;
-    const resourceTypes = new Set(
-        [types.ResourceSendRequest, types.ResourceReceiveResponse, types.ResourceReceivedData, types.ResourceFinish]);
-    const events = this.inspectedTargetEvents();
-    for (let i = 0; i < events.length; ++i) {
-      const e = events[i];
-      if (!resourceTypes.has(e.name))
-        continue;
-      const id = TimelineModel.TimelineModel.globalEventId(e, 'requestId');
-      let request = requests.get(id);
-      if (request) {
-        request.addEvent(e);
-      } else {
-        request = new TimelineModel.TimelineModel.NetworkRequest(e);
-        requests.set(id, request);
-        if (request.startTime)
-          requestsList.push(request);
-        else
-          zeroStartRequestsList.push(request);
-      }
-    }
-    return zeroStartRequestsList.concat(requestsList);
-  }
-};
-
-/**
- * @enum {string}
- */
-TimelineModel.TimelineModel.RecordType = {
-  Task: 'Task',
-  Program: 'Program',
-  EventDispatch: 'EventDispatch',
-
-  GPUTask: 'GPUTask',
-
-  Animation: 'Animation',
-  RequestMainThreadFrame: 'RequestMainThreadFrame',
-  BeginFrame: 'BeginFrame',
-  NeedsBeginFrameChanged: 'NeedsBeginFrameChanged',
-  BeginMainThreadFrame: 'BeginMainThreadFrame',
-  ActivateLayerTree: 'ActivateLayerTree',
-  DrawFrame: 'DrawFrame',
-  HitTest: 'HitTest',
-  ScheduleStyleRecalculation: 'ScheduleStyleRecalculation',
-  RecalculateStyles: 'RecalculateStyles',  // For backwards compatibility only, now replaced by UpdateLayoutTree.
-  UpdateLayoutTree: 'UpdateLayoutTree',
-  InvalidateLayout: 'InvalidateLayout',
-  Layout: 'Layout',
-  UpdateLayer: 'UpdateLayer',
-  UpdateLayerTree: 'UpdateLayerTree',
-  PaintSetup: 'PaintSetup',
-  Paint: 'Paint',
-  PaintImage: 'PaintImage',
-  Rasterize: 'Rasterize',
-  RasterTask: 'RasterTask',
-  ScrollLayer: 'ScrollLayer',
-  CompositeLayers: 'CompositeLayers',
-
-  ScheduleStyleInvalidationTracking: 'ScheduleStyleInvalidationTracking',
-  StyleRecalcInvalidationTracking: 'StyleRecalcInvalidationTracking',
-  StyleInvalidatorInvalidationTracking: 'StyleInvalidatorInvalidationTracking',
-  LayoutInvalidationTracking: 'LayoutInvalidationTracking',
-  LayerInvalidationTracking: 'LayerInvalidationTracking',
-  PaintInvalidationTracking: 'PaintInvalidationTracking',
-  ScrollInvalidationTracking: 'ScrollInvalidationTracking',
-
-  ParseHTML: 'ParseHTML',
-  ParseAuthorStyleSheet: 'ParseAuthorStyleSheet',
-
-  TimerInstall: 'TimerInstall',
-  TimerRemove: 'TimerRemove',
-  TimerFire: 'TimerFire',
-
-  XHRReadyStateChange: 'XHRReadyStateChange',
-  XHRLoad: 'XHRLoad',
-  CompileScript: 'v8.compile',
-  EvaluateScript: 'EvaluateScript',
-  CompileModule: 'v8.compileModule',
-  EvaluateModule: 'v8.evaluateModule',
-
-  CommitLoad: 'CommitLoad',
-  MarkLoad: 'MarkLoad',
-  MarkDOMContent: 'MarkDOMContent',
-  MarkFirstPaint: 'MarkFirstPaint',
-  MarkFCP: 'firstContentfulPaint',
-  MarkFMP: 'firstMeaningfulPaint',
-  MarkFMPCandidate: 'firstMeaningfulPaintCandidate',
-
-  TimeStamp: 'TimeStamp',
-  ConsoleTime: 'ConsoleTime',
-  UserTiming: 'UserTiming',
-
-  ResourceSendRequest: 'ResourceSendRequest',
-  ResourceReceiveResponse: 'ResourceReceiveResponse',
-  ResourceReceivedData: 'ResourceReceivedData',
-  ResourceFinish: 'ResourceFinish',
-
-  RunMicrotasks: 'RunMicrotasks',
-  FunctionCall: 'FunctionCall',
-  GCEvent: 'GCEvent',  // For backwards compatibility only, now replaced by MinorGC/MajorGC.
-  MajorGC: 'MajorGC',
-  MinorGC: 'MinorGC',
-  JSFrame: 'JSFrame',
-  JSSample: 'JSSample',
-  // V8Sample events are coming from tracing and contain raw stacks with function addresses.
-  // After being processed with help of JitCodeAdded and JitCodeMoved events they
-  // get translated into function infos and stored as stacks in JSSample events.
-  V8Sample: 'V8Sample',
-  JitCodeAdded: 'JitCodeAdded',
-  JitCodeMoved: 'JitCodeMoved',
-  ParseScriptOnBackground: 'v8.parseOnBackground',
-  V8Execute: 'V8.Execute',
-
-  UpdateCounters: 'UpdateCounters',
-
-  RequestAnimationFrame: 'RequestAnimationFrame',
-  CancelAnimationFrame: 'CancelAnimationFrame',
-  FireAnimationFrame: 'FireAnimationFrame',
-
-  RequestIdleCallback: 'RequestIdleCallback',
-  CancelIdleCallback: 'CancelIdleCallback',
-  FireIdleCallback: 'FireIdleCallback',
-
-  WebSocketCreate: 'WebSocketCreate',
-  WebSocketSendHandshakeRequest: 'WebSocketSendHandshakeRequest',
-  WebSocketReceiveHandshakeResponse: 'WebSocketReceiveHandshakeResponse',
-  WebSocketDestroy: 'WebSocketDestroy',
-
-  EmbedderCallback: 'EmbedderCallback',
-
-  SetLayerTreeId: 'SetLayerTreeId',
-  TracingStartedInPage: 'TracingStartedInPage',
-  TracingSessionIdForWorker: 'TracingSessionIdForWorker',
-
-  DecodeImage: 'Decode Image',
-  ResizeImage: 'Resize Image',
-  DrawLazyPixelRef: 'Draw LazyPixelRef',
-  DecodeLazyPixelRef: 'Decode LazyPixelRef',
-
-  LazyPixelRef: 'LazyPixelRef',
-  LayerTreeHostImplSnapshot: 'cc::LayerTreeHostImpl',
-  PictureSnapshot: 'cc::Picture',
-  DisplayItemListSnapshot: 'cc::DisplayItemList',
-  LatencyInfo: 'LatencyInfo',
-  LatencyInfoFlow: 'LatencyInfo.Flow',
-  InputLatencyMouseMove: 'InputLatency::MouseMove',
-  InputLatencyMouseWheel: 'InputLatency::MouseWheel',
-  ImplSideFling: 'InputHandlerProxy::HandleGestureFling::started',
-  GCIdleLazySweep: 'ThreadState::performIdleLazySweep',
-  GCCompleteSweep: 'ThreadState::completeSweep',
-  GCCollectGarbage: 'BlinkGCMarking',
-
-  CryptoDoEncrypt: 'DoEncrypt',
-  CryptoDoEncryptReply: 'DoEncryptReply',
-  CryptoDoDecrypt: 'DoDecrypt',
-  CryptoDoDecryptReply: 'DoDecryptReply',
-  CryptoDoDigest: 'DoDigest',
-  CryptoDoDigestReply: 'DoDigestReply',
-  CryptoDoSign: 'DoSign',
-  CryptoDoSignReply: 'DoSignReply',
-  CryptoDoVerify: 'DoVerify',
-  CryptoDoVerifyReply: 'DoVerifyReply',
-
-  // CpuProfile is a virtual event created on frontend to support
-  // serialization of CPU Profiles within tracing timeline data.
-  CpuProfile: 'CpuProfile',
-  Profile: 'Profile',
-
-  AsyncTask: 'AsyncTask',
-};
-
-TimelineModel.TimelineModel.Category = {
-  Console: 'blink.console',
-  UserTiming: 'blink.user_timing',
-  LatencyInfo: 'latencyInfo'
-};
-
-/**
- * @enum {string}
- */
-TimelineModel.TimelineModel.WarningType = {
-  ForcedStyle: 'ForcedStyle',
-  ForcedLayout: 'ForcedLayout',
-  IdleDeadlineExceeded: 'IdleDeadlineExceeded',
-  LongHandler: 'LongHandler',
-  LongRecurringHandler: 'LongRecurringHandler',
-  V8Deopt: 'V8Deopt'
-};
-
-TimelineModel.TimelineModel.WorkerThreadName = 'DedicatedWorker thread';
-TimelineModel.TimelineModel.WorkerThreadNameLegacy = 'DedicatedWorker Thread';
-TimelineModel.TimelineModel.RendererMainThreadName = 'CrRendererMain';
-
-TimelineModel.TimelineModel.DevToolsMetadataEvent = {
-  TracingStartedInBrowser: 'TracingStartedInBrowser',
-  TracingStartedInPage: 'TracingStartedInPage',
-  TracingSessionIdForWorker: 'TracingSessionIdForWorker',
-  FrameCommittedInBrowser: 'FrameCommittedInBrowser',
-  ProcessReadyInBrowser: 'ProcessReadyInBrowser',
-  FrameDeletedInBrowser: 'FrameDeletedInBrowser',
-};
-
-TimelineModel.TimelineModel.Thresholds = {
-  Handler: 150,
-  RecurringHandler: 50,
-  ForcedLayout: 30,
-  IdleCallbackAddon: 5
-};
-
-TimelineModel.TimelineModel.Track = class {
-  constructor() {
-    this.name = '';
-    this.type = TimelineModel.TimelineModel.TrackType.Other;
-    // TODO(dgozman): replace forMainFrame with a list of frames, urls and time ranges.
-    this.forMainFrame = false;
-    this.url = '';
-    // TODO(dgozman): do not distinguish between sync and async events.
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this.events = [];
-    /** @type {!Array<!SDK.TracingModel.AsyncEvent>} */
-    this.asyncEvents = [];
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this.tasks = [];
-    this._syncEvents = null;
-  }
-
-  /**
-   * @return {!Array<!SDK.TracingModel.Event>}
-   */
-  syncEvents() {
-    if (this.events.length)
-      return this.events;
-
-    if (this._syncEvents)
-      return this._syncEvents;
-
-    const stack = [];
-    this._syncEvents = [];
-    for (const event of this.asyncEvents) {
-      const startTime = event.startTime;
-      const endTime = event.endTime;
-      while (stack.length && startTime >= stack.peekLast().endTime)
-        stack.pop();
-      if (stack.length && endTime > stack.peekLast().endTime) {
-        this._syncEvents = [];
-        break;
-      }
-      const syncEvent = new SDK.TracingModel.Event(
-          event.categoriesString, event.name, SDK.TracingModel.Phase.Complete, startTime, event.thread);
-      syncEvent.setEndTime(endTime);
-      syncEvent.addArgs(event.args);
-      this._syncEvents.push(syncEvent);
-      stack.push(syncEvent);
-    }
-    return this._syncEvents;
-  }
-};
-
-/**
- * @enum {symbol}
- */
-TimelineModel.TimelineModel.TrackType = {
-  MainThread: Symbol('MainThread'),
-  Worker: Symbol('Worker'),
-  Input: Symbol('Input'),
-  Animation: Symbol('Animation'),
-  UserTiming: Symbol('UserTiming'),
-  Console: Symbol('Console'),
-  Raster: Symbol('Raster'),
-  GPU: Symbol('GPU'),
-  Other: Symbol('Other'),
-};
-
-TimelineModel.TimelineModel.PageFrame = class {
-  /**
-   * @param {!Object} payload
-   */
-  constructor(payload) {
-    this.frameId = payload['frame'];
-    this.url = payload['url'] || '';
-    this.name = payload['name'];
-    /** @type {!Array<!TimelineModel.TimelineModel.PageFrame>} */
-    this.children = [];
-    /** @type {?TimelineModel.TimelineModel.PageFrame} */
-    this.parent = null;
-    /** @type {!Array<!{time: number, processId: number, processPseudoId: ?string, url: string}>} */
-    this.processes = [];
-    /** @type {?number} */
-    this.deletedTime = null;
-    // TODO(dgozman): figure this out.
-    // this.ownerNode = target && payload['nodeId'] ? new SDK.DeferredDOMNode(target, payload['nodeId']) : null;
-    this.ownerNode = null;
-  }
-
-  /**
-   * @param {number} time
-   * @param {!Object} payload
-   */
-  update(time, payload) {
-    this.url = payload['url'] || '';
-    this.name = payload['name'];
-    if (payload['processId']) {
-      this.processes.push(
-          {time: time, processId: payload['processId'], processPseudoId: '', url: payload['url'] || ''});
-    } else {
-      this.processes.push(
-          {time: time, processId: -1, processPseudoId: payload['processPseudoId'], url: payload['url'] || ''});
-    }
-  }
-
-  /**
-   * @param {string} processPseudoId
-   * @param {number} processId
-   */
-  processReady(processPseudoId, processId) {
-    for (const process of this.processes) {
-      if (process.processPseudoId === processPseudoId) {
-        process.processPseudoId = '';
-        process.processId = processId;
-      }
-    }
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineModel.PageFrame} child
-   */
-  addChild(child) {
-    this.children.push(child);
-    child.parent = this;
-  }
-};
-
-/** @typedef {!{page: !Array<!SDK.TracingModel.Event>, workers: !Array<!SDK.TracingModel.Event>}} */
-TimelineModel.TimelineModel.MetadataEvents;
-
-/**
- * @unrestricted
- */
-TimelineModel.TimelineModel.NetworkRequest = class {
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  constructor(event) {
-    this.startTime = event.name === TimelineModel.TimelineModel.RecordType.ResourceSendRequest ? event.startTime : 0;
-    this.endTime = Infinity;
-    this.encodedDataLength = 0;
-    this.decodedBodyLength = 0;
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this.children = [];
-    /** @type {?Object} */
-    this.timing;
-    /** @type {string} */
-    this.mimeType;
-    /** @type {string} */
-    this.url;
-    /** @type {string} */
-    this.requestMethod;
-    this.addEvent(event);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  addEvent(event) {
-    this.children.push(event);
-    const recordType = TimelineModel.TimelineModel.RecordType;
-    this.startTime = Math.min(this.startTime, event.startTime);
-    const eventData = event.args['data'];
-    if (eventData['mimeType'])
-      this.mimeType = eventData['mimeType'];
-    if ('priority' in eventData)
-      this.priority = eventData['priority'];
-    if (event.name === recordType.ResourceFinish)
-      this.endTime = event.startTime;
-    if (eventData['finishTime'])
-      this.finishTime = eventData['finishTime'] * 1000;
-    if (!this.responseTime &&
-        (event.name === recordType.ResourceReceiveResponse || event.name === recordType.ResourceReceivedData))
-      this.responseTime = event.startTime;
-    const encodedDataLength = eventData['encodedDataLength'] || 0;
-    if (event.name === recordType.ResourceReceiveResponse) {
-      if (eventData['fromCache'])
-        this.fromCache = true;
-      if (eventData['fromServiceWorker'])
-        this.fromServiceWorker = true;
-      this.encodedDataLength = encodedDataLength;
-    }
-    if (event.name === recordType.ResourceReceivedData)
-      this.encodedDataLength += encodedDataLength;
-    if (event.name === recordType.ResourceFinish && encodedDataLength)
-      this.encodedDataLength = encodedDataLength;
-    const decodedBodyLength = eventData['decodedBodyLength'];
-    if (event.name === recordType.ResourceFinish && decodedBodyLength)
-      this.decodedBodyLength = decodedBodyLength;
-    if (!this.url)
-      this.url = eventData['url'];
-    if (!this.requestMethod)
-      this.requestMethod = eventData['requestMethod'];
-    if (!this.timing)
-      this.timing = eventData['timing'];
-    if (eventData['fromServiceWorker'])
-      this.fromServiceWorker = true;
-  }
-
-  /**
-   * @return {number}
-   */
-  beginTime() {
-    return Math.min(this.startTime, this.timing && this.timing.pushStart * 1000 || Infinity);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-TimelineModel.InvalidationTrackingEvent = class {
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  constructor(event) {
-    /** @type {string} */
-    this.type = event.name;
-    /** @type {number} */
-    this.startTime = event.startTime;
-    /** @type {!SDK.TracingModel.Event} */
-    this._tracingEvent = event;
-
-    const eventData = event.args['data'];
-
-    /** @type {number} */
-    this.frame = eventData['frame'];
-    /** @type {?number} */
-    this.nodeId = eventData['nodeId'];
-    /** @type {?string} */
-    this.nodeName = eventData['nodeName'];
-    /** @type {?number} */
-    this.paintId = eventData['paintId'];
-    /** @type {?number} */
-    this.invalidationSet = eventData['invalidationSet'];
-    /** @type {?string} */
-    this.invalidatedSelectorId = eventData['invalidatedSelectorId'];
-    /** @type {?string} */
-    this.changedId = eventData['changedId'];
-    /** @type {?string} */
-    this.changedClass = eventData['changedClass'];
-    /** @type {?string} */
-    this.changedAttribute = eventData['changedAttribute'];
-    /** @type {?string} */
-    this.changedPseudo = eventData['changedPseudo'];
-    /** @type {?string} */
-    this.selectorPart = eventData['selectorPart'];
-    /** @type {?string} */
-    this.extraData = eventData['extraData'];
-    /** @type {?Array.<!Object.<string, number>>} */
-    this.invalidationList = eventData['invalidationList'];
-    /** @type {!TimelineModel.InvalidationCause} */
-    this.cause = {reason: eventData['reason'], stackTrace: eventData['stackTrace']};
-
-    // FIXME: Move this to TimelineUIUtils.js.
-    if (!this.cause.reason && this.cause.stackTrace &&
-        this.type === TimelineModel.TimelineModel.RecordType.LayoutInvalidationTracking)
-      this.cause.reason = 'Layout forced';
-  }
-};
-
-/** @typedef {{reason: string, stackTrace: ?Array<!Protocol.Runtime.CallFrame>}} */
-TimelineModel.InvalidationCause;
-
-TimelineModel.InvalidationTracker = class {
-  constructor() {
-    /** @type {?SDK.TracingModel.Event} */
-    this._lastRecalcStyle = null;
-    /** @type {?SDK.TracingModel.Event} */
-    this._lastPaintWithLayer = null;
-    this._didPaint = false;
-    this._initializePerFrameState();
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {?Array<!TimelineModel.InvalidationTrackingEvent>}
-   */
-  static invalidationEventsFor(event) {
-    return event[TimelineModel.InvalidationTracker._invalidationTrackingEventsSymbol] || null;
-  }
-
-  /**
-   * @param {!TimelineModel.InvalidationTrackingEvent} invalidation
-   */
-  addInvalidation(invalidation) {
-    this._startNewFrameIfNeeded();
-
-    if (!invalidation.nodeId && !invalidation.paintId) {
-      console.error('Invalidation lacks node information.');
-      console.error(invalidation);
-      return;
-    }
-
-    // PaintInvalidationTracking events provide a paintId and a nodeId which
-    // we can use to update the paintId for all other invalidation tracking
-    // events.
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    if (invalidation.type === recordTypes.PaintInvalidationTracking && invalidation.nodeId) {
-      const invalidations = this._invalidationsByNodeId[invalidation.nodeId] || [];
-      for (let i = 0; i < invalidations.length; ++i)
-        invalidations[i].paintId = invalidation.paintId;
-
-      // PaintInvalidationTracking is only used for updating paintIds.
-      return;
-    }
-
-    // Suppress StyleInvalidator StyleRecalcInvalidationTracking invalidations because they
-    // will be handled by StyleInvalidatorInvalidationTracking.
-    // FIXME: Investigate if we can remove StyleInvalidator invalidations entirely.
-    if (invalidation.type === recordTypes.StyleRecalcInvalidationTracking &&
-        invalidation.cause.reason === 'StyleInvalidator')
-      return;
-
-    // Style invalidation events can occur before and during recalc style. didRecalcStyle
-    // handles style invalidations that occur before the recalc style event but we need to
-    // handle style recalc invalidations during recalc style here.
-    const styleRecalcInvalidation =
-        (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking ||
-         invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking ||
-         invalidation.type === recordTypes.StyleRecalcInvalidationTracking);
-    if (styleRecalcInvalidation) {
-      const duringRecalcStyle = invalidation.startTime && this._lastRecalcStyle &&
-          invalidation.startTime >= this._lastRecalcStyle.startTime &&
-          invalidation.startTime <= this._lastRecalcStyle.endTime;
-      if (duringRecalcStyle)
-        this._associateWithLastRecalcStyleEvent(invalidation);
-    }
-
-    // Record the invalidation so later events can look it up.
-    if (this._invalidations[invalidation.type])
-      this._invalidations[invalidation.type].push(invalidation);
-    else
-      this._invalidations[invalidation.type] = [invalidation];
-    if (invalidation.nodeId) {
-      if (this._invalidationsByNodeId[invalidation.nodeId])
-        this._invalidationsByNodeId[invalidation.nodeId].push(invalidation);
-      else
-        this._invalidationsByNodeId[invalidation.nodeId] = [invalidation];
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} recalcStyleEvent
-   */
-  didRecalcStyle(recalcStyleEvent) {
-    this._lastRecalcStyle = recalcStyleEvent;
-    const types = [
-      TimelineModel.TimelineModel.RecordType.ScheduleStyleInvalidationTracking,
-      TimelineModel.TimelineModel.RecordType.StyleInvalidatorInvalidationTracking,
-      TimelineModel.TimelineModel.RecordType.StyleRecalcInvalidationTracking
-    ];
-    for (const invalidation of this._invalidationsOfTypes(types))
-      this._associateWithLastRecalcStyleEvent(invalidation);
-  }
-
-  /**
-   * @param {!TimelineModel.InvalidationTrackingEvent} invalidation
-   */
-  _associateWithLastRecalcStyleEvent(invalidation) {
-    if (invalidation.linkedRecalcStyleEvent)
-      return;
-
-    const recordTypes = TimelineModel.TimelineModel.RecordType;
-    const recalcStyleFrameId = this._lastRecalcStyle.args['beginData']['frame'];
-    if (invalidation.type === recordTypes.StyleInvalidatorInvalidationTracking) {
-      // Instead of calling _addInvalidationToEvent directly, we create synthetic
-      // StyleRecalcInvalidationTracking events which will be added in _addInvalidationToEvent.
-      this._addSyntheticStyleRecalcInvalidations(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
-    } else if (invalidation.type === recordTypes.ScheduleStyleInvalidationTracking) {
-      // ScheduleStyleInvalidationTracking events are only used for adding information to
-      // StyleInvalidatorInvalidationTracking events. See: _addSyntheticStyleRecalcInvalidations.
-    } else {
-      this._addInvalidationToEvent(this._lastRecalcStyle, recalcStyleFrameId, invalidation);
-    }
-
-    invalidation.linkedRecalcStyleEvent = true;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {number} frameId
-   * @param {!TimelineModel.InvalidationTrackingEvent} styleInvalidatorInvalidation
-   */
-  _addSyntheticStyleRecalcInvalidations(event, frameId, styleInvalidatorInvalidation) {
-    if (!styleInvalidatorInvalidation.invalidationList) {
-      this._addSyntheticStyleRecalcInvalidation(
-          styleInvalidatorInvalidation._tracingEvent, styleInvalidatorInvalidation);
-      return;
-    }
-    if (!styleInvalidatorInvalidation.nodeId) {
-      console.error('Invalidation lacks node information.');
-      console.error(styleInvalidatorInvalidation);
-      return;
-    }
-    for (let i = 0; i < styleInvalidatorInvalidation.invalidationList.length; i++) {
-      const setId = styleInvalidatorInvalidation.invalidationList[i]['id'];
-      let lastScheduleStyleRecalculation;
-      const nodeInvalidations = this._invalidationsByNodeId[styleInvalidatorInvalidation.nodeId] || [];
-      for (let j = 0; j < nodeInvalidations.length; j++) {
-        const invalidation = nodeInvalidations[j];
-        if (invalidation.frame !== frameId || invalidation.invalidationSet !== setId ||
-            invalidation.type !== TimelineModel.TimelineModel.RecordType.ScheduleStyleInvalidationTracking)
-          continue;
-        lastScheduleStyleRecalculation = invalidation;
-      }
-      if (!lastScheduleStyleRecalculation) {
-        console.error('Failed to lookup the event that scheduled a style invalidator invalidation.');
-        continue;
-      }
-      this._addSyntheticStyleRecalcInvalidation(
-          lastScheduleStyleRecalculation._tracingEvent, styleInvalidatorInvalidation);
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} baseEvent
-   * @param {!TimelineModel.InvalidationTrackingEvent} styleInvalidatorInvalidation
-   */
-  _addSyntheticStyleRecalcInvalidation(baseEvent, styleInvalidatorInvalidation) {
-    const invalidation = new TimelineModel.InvalidationTrackingEvent(baseEvent);
-    invalidation.type = TimelineModel.TimelineModel.RecordType.StyleRecalcInvalidationTracking;
-    if (styleInvalidatorInvalidation.cause.reason)
-      invalidation.cause.reason = styleInvalidatorInvalidation.cause.reason;
-    if (styleInvalidatorInvalidation.selectorPart)
-      invalidation.selectorPart = styleInvalidatorInvalidation.selectorPart;
-
-    this.addInvalidation(invalidation);
-    if (!invalidation.linkedRecalcStyleEvent)
-      this._associateWithLastRecalcStyleEvent(invalidation);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} layoutEvent
-   */
-  didLayout(layoutEvent) {
-    const layoutFrameId = layoutEvent.args['beginData']['frame'];
-    for (const invalidation of this._invalidationsOfTypes(
-             [TimelineModel.TimelineModel.RecordType.LayoutInvalidationTracking])) {
-      if (invalidation.linkedLayoutEvent)
-        continue;
-      this._addInvalidationToEvent(layoutEvent, layoutFrameId, invalidation);
-      invalidation.linkedLayoutEvent = true;
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} paintEvent
-   */
-  didPaint(paintEvent) {
-    this._didPaint = true;
-
-    // If a paint doesn't have a corresponding graphics layer id, it paints
-    // into its parent so add an effectivePaintId to these events.
-    const layerId = paintEvent.args['data']['layerId'];
-    if (layerId)
-      this._lastPaintWithLayer = paintEvent;
-    // Quietly discard top-level paints without layerId, as these are likely
-    // to come from overlay.
-    if (!this._lastPaintWithLayer)
-      return;
-
-    const effectivePaintId = this._lastPaintWithLayer.args['data']['nodeId'];
-    const paintFrameId = paintEvent.args['data']['frame'];
-    const types = [
-      TimelineModel.TimelineModel.RecordType.StyleRecalcInvalidationTracking,
-      TimelineModel.TimelineModel.RecordType.LayoutInvalidationTracking,
-      TimelineModel.TimelineModel.RecordType.PaintInvalidationTracking,
-      TimelineModel.TimelineModel.RecordType.ScrollInvalidationTracking
-    ];
-    for (const invalidation of this._invalidationsOfTypes(types)) {
-      if (invalidation.paintId === effectivePaintId)
-        this._addInvalidationToEvent(paintEvent, paintFrameId, invalidation);
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @param {number} eventFrameId
-   * @param {!TimelineModel.InvalidationTrackingEvent} invalidation
-   */
-  _addInvalidationToEvent(event, eventFrameId, invalidation) {
-    if (eventFrameId !== invalidation.frame)
-      return;
-    if (!event[TimelineModel.InvalidationTracker._invalidationTrackingEventsSymbol])
-      event[TimelineModel.InvalidationTracker._invalidationTrackingEventsSymbol] = [invalidation];
-    else
-      event[TimelineModel.InvalidationTracker._invalidationTrackingEventsSymbol].push(invalidation);
-  }
-
-  /**
-   * @param {!Array.<string>=} types
-   * @return {!Iterator.<!TimelineModel.InvalidationTrackingEvent>}
-   */
-  _invalidationsOfTypes(types) {
-    const invalidations = this._invalidations;
-    if (!types)
-      types = Object.keys(invalidations);
-    function* generator() {
-      for (let i = 0; i < types.length; ++i) {
-        const invalidationList = invalidations[types[i]] || [];
-        for (let j = 0; j < invalidationList.length; ++j)
-          yield invalidationList[j];
-      }
-    }
-    return generator();
-  }
-
-  _startNewFrameIfNeeded() {
-    if (!this._didPaint)
-      return;
-
-    this._initializePerFrameState();
-  }
-
-  _initializePerFrameState() {
-    /** @type {!Object.<string, !Array.<!TimelineModel.InvalidationTrackingEvent>>} */
-    this._invalidations = {};
-    /** @type {!Object.<number, !Array.<!TimelineModel.InvalidationTrackingEvent>>} */
-    this._invalidationsByNodeId = {};
-
-    this._lastRecalcStyle = null;
-    this._lastPaintWithLayer = null;
-    this._didPaint = false;
-  }
-};
-
-TimelineModel.InvalidationTracker._invalidationTrackingEventsSymbol = Symbol('invalidationTrackingEvents');
-
-/**
- * @unrestricted
- */
-TimelineModel.TimelineAsyncEventTracker = class {
-  constructor() {
-    TimelineModel.TimelineAsyncEventTracker._initialize();
-    /** @type {!Map<!TimelineModel.TimelineModel.RecordType, !Map<string, !SDK.TracingModel.Event>>} */
-    this._initiatorByType = new Map();
-    for (const initiator of TimelineModel.TimelineAsyncEventTracker._asyncEvents.keys())
-      this._initiatorByType.set(initiator, new Map());
-  }
-
-  static _initialize() {
-    if (TimelineModel.TimelineAsyncEventTracker._asyncEvents)
-      return;
-    const events = new Map();
-    let type = TimelineModel.TimelineModel.RecordType;
-
-    events.set(type.TimerInstall, {causes: [type.TimerFire], joinBy: 'timerId'});
-    events.set(
-        type.ResourceSendRequest,
-        {causes: [type.ResourceReceiveResponse, type.ResourceReceivedData, type.ResourceFinish], joinBy: 'requestId'});
-    events.set(type.RequestAnimationFrame, {causes: [type.FireAnimationFrame], joinBy: 'id'});
-    events.set(type.RequestIdleCallback, {causes: [type.FireIdleCallback], joinBy: 'id'});
-    events.set(type.WebSocketCreate, {
-      causes: [type.WebSocketSendHandshakeRequest, type.WebSocketReceiveHandshakeResponse, type.WebSocketDestroy],
-      joinBy: 'identifier'
-    });
-
-    TimelineModel.TimelineAsyncEventTracker._asyncEvents = events;
-    /** @type {!Map<!TimelineModel.TimelineModel.RecordType, !TimelineModel.TimelineModel.RecordType>} */
-    TimelineModel.TimelineAsyncEventTracker._typeToInitiator = new Map();
-    for (const entry of events) {
-      const types = entry[1].causes;
-      for (type of types)
-        TimelineModel.TimelineAsyncEventTracker._typeToInitiator.set(type, entry[0]);
-    }
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   */
-  processEvent(event) {
-    let initiatorType = TimelineModel.TimelineAsyncEventTracker._typeToInitiator.get(
-        /** @type {!TimelineModel.TimelineModel.RecordType} */ (event.name));
-    const isInitiator = !initiatorType;
-    if (!initiatorType)
-      initiatorType = /** @type {!TimelineModel.TimelineModel.RecordType} */ (event.name);
-    const initiatorInfo = TimelineModel.TimelineAsyncEventTracker._asyncEvents.get(initiatorType);
-    if (!initiatorInfo)
-      return;
-    const id = TimelineModel.TimelineModel.globalEventId(event, initiatorInfo.joinBy);
-    if (!id)
-      return;
-    /** @type {!Map<string, !SDK.TracingModel.Event>|undefined} */
-    const initiatorMap = this._initiatorByType.get(initiatorType);
-    if (isInitiator) {
-      initiatorMap.set(id, event);
-      return;
-    }
-    const initiator = initiatorMap.get(id) || null;
-    const timelineData = TimelineModel.TimelineData.forEvent(event);
-    timelineData.setInitiator(initiator);
-    if (!timelineData.frameId && initiator)
-      timelineData.frameId = TimelineModel.TimelineModel.eventFrameId(initiator);
-  }
-};
-
-
-TimelineModel.TimelineData = class {
-  constructor() {
-    /** @type {?string} */
-    this.warning = null;
-    /** @type {?Element} */
-    this.previewElement = null;
-    /** @type {?string} */
-    this.url = null;
-    /** @type {number} */
-    this.backendNodeId = 0;
-    /** @type {?Array<!Protocol.Runtime.CallFrame>} */
-    this.stackTrace = null;
-    /** @type {?SDK.TracingModel.ObjectSnapshot} */
-    this.picture = null;
-    /** @type {?SDK.TracingModel.Event} */
-    this._initiator = null;
-    this.frameId = '';
-    /** @type {number|undefined} */
-    this.timeWaitingForMainThread;
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} initiator
-   */
-  setInitiator(initiator) {
-    this._initiator = initiator;
-    if (!initiator || this.url)
-      return;
-    const initiatorURL = TimelineModel.TimelineData.forEvent(initiator).url;
-    if (initiatorURL)
-      this.url = initiatorURL;
-  }
-
-  /**
-   * @return {?SDK.TracingModel.Event}
-   */
-  initiator() {
-    return this._initiator;
-  }
-
-  /**
-   * @return {?Protocol.Runtime.CallFrame}
-   */
-  topFrame() {
-    const stackTrace = this.stackTraceForSelfOrInitiator();
-    return stackTrace && stackTrace[0] || null;
-  }
-
-  /**
-   * @return {?Array<!Protocol.Runtime.CallFrame>}
-   */
-  stackTraceForSelfOrInitiator() {
-    return this.stackTrace || (this._initiator && TimelineModel.TimelineData.forEvent(this._initiator).stackTrace);
-  }
-
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {!TimelineModel.TimelineData}
-   */
-  static forEvent(event) {
-    let data = event[TimelineModel.TimelineData._symbol];
-    if (!data) {
-      data = new TimelineModel.TimelineData();
-      event[TimelineModel.TimelineData._symbol] = data;
-    }
-    return data;
-  }
-};
-
-TimelineModel.TimelineData._symbol = Symbol('timelineData');
diff --git a/front_end/timeline_model/TimelineModelFilter.js b/front_end/timeline_model/TimelineModelFilter.js
deleted file mode 100644
index 77b2002..0000000
--- a/front_end/timeline_model/TimelineModelFilter.js
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-TimelineModel.TimelineModelFilter = class {
-  /**
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return true;
-  }
-};
-
-TimelineModel.TimelineVisibleEventsFilter = class extends TimelineModel.TimelineModelFilter {
-  /**
-   * @param {!Array<string>} visibleTypes
-   */
-  constructor(visibleTypes) {
-    super();
-    this._visibleTypes = new Set(visibleTypes);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return this._visibleTypes.has(TimelineModel.TimelineVisibleEventsFilter._eventType(event));
-  }
-
-  /**
-   * @return {!TimelineModel.TimelineModel.RecordType}
-   */
-  static _eventType(event) {
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.Console))
-      return TimelineModel.TimelineModel.RecordType.ConsoleTime;
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.UserTiming))
-      return TimelineModel.TimelineModel.RecordType.UserTiming;
-    if (event.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo))
-      return TimelineModel.TimelineModel.RecordType.LatencyInfo;
-    return /** @type !TimelineModel.TimelineModel.RecordType */ (event.name);
-  }
-};
-
-TimelineModel.TimelineInvisibleEventsFilter = class extends TimelineModel.TimelineModelFilter {
-  /**
-   * @param {!Array<string>} invisibleTypes
-   */
-  constructor(invisibleTypes) {
-    super();
-    this._invisibleTypes = new Set(invisibleTypes);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return !this._invisibleTypes.has(TimelineModel.TimelineVisibleEventsFilter._eventType(event));
-  }
-};
-
-TimelineModel.ExclusiveNameFilter = class extends TimelineModel.TimelineModelFilter {
-  /**
-   * @param {!Array<string>} excludeNames
-   */
-  constructor(excludeNames) {
-    super();
-    this._excludeNames = new Set(excludeNames);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return !this._excludeNames.has(event.name);
-  }
-};
-
-TimelineModel.ExcludeTopLevelFilter = class extends TimelineModel.TimelineModelFilter {
-  constructor() {
-    super();
-  }
-
-  /**
-   * @override
-   * @param {!SDK.TracingModel.Event} event
-   * @return {boolean}
-   */
-  accept(event) {
-    return !SDK.TracingModel.isTopLevelEvent(event);
-  }
-};
diff --git a/front_end/timeline_model/TimelineProfileTree.js b/front_end/timeline_model/TimelineProfileTree.js
deleted file mode 100644
index b436563..0000000
--- a/front_end/timeline_model/TimelineProfileTree.js
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-TimelineModel.TimelineProfileTree = {};
-
-/**
- * @unrestricted
- */
-TimelineModel.TimelineProfileTree.Node = class {
-  /**
-   * @param {string} id
-   * @param {?SDK.TracingModel.Event} event
-   */
-  constructor(id, event) {
-    /** @type {number} */
-    this.totalTime = 0;
-    /** @type {number} */
-    this.selfTime = 0;
-    /** @type {string} */
-    this.id = id;
-    /** @type {?SDK.TracingModel.Event} */
-    this.event = event;
-    /** @type {?TimelineModel.TimelineProfileTree.Node} */
-    this.parent;
-
-    /** @type {string} */
-    this._groupId = '';
-    this._isGroupNode = false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isGroupNode() {
-    return this._isGroupNode;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasChildren() {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  children() {
-    throw 'Not implemented';
-  }
-
-  /**
-   * @param {function(!SDK.TracingModel.Event):boolean} matchFunction
-   * @param {!Array<!TimelineModel.TimelineProfileTree.Node>=} results
-   * @return {!Array<!TimelineModel.TimelineProfileTree.Node>}
-   */
-  searchTree(matchFunction, results) {
-    results = results || [];
-    if (this.event && matchFunction(this.event))
-      results.push(this);
-    for (const child of this.children().values())
-      child.searchTree(matchFunction, results);
-    return results;
-  }
-};
-
-TimelineModel.TimelineProfileTree.TopDownNode = class extends TimelineModel.TimelineProfileTree.Node {
-  /**
-   * @param {string} id
-   * @param {?SDK.TracingModel.Event} event
-   * @param {?TimelineModel.TimelineProfileTree.TopDownNode} parent
-   */
-  constructor(id, event, parent) {
-    super(id, event);
-    /** @type {?TimelineModel.TimelineProfileTree.TopDownRootNode} */
-    this._root = parent && parent._root;
-    this._hasChildren = false;
-    this._children = null;
-    this.parent = parent;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasChildren() {
-    return this._hasChildren;
-  }
-
-  /**
-   * @override
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  children() {
-    return this._children || this._buildChildren();
-  }
-
-  /**
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  _buildChildren() {
-    /** @type {!Array<!TimelineModel.TimelineProfileTree.TopDownNode>} */
-    const path = [];
-    for (let node = this; node.parent && !node._isGroupNode; node = node.parent)
-      path.push(/** @type {!TimelineModel.TimelineProfileTree.TopDownNode} */ (node));
-    path.reverse();
-    /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */
-    const children = new Map();
-    const self = this;
-    const root = this._root;
-    const startTime = root._startTime;
-    const endTime = root._endTime;
-    const instantEventCallback = root._doNotAggregate ? onInstantEvent : undefined;
-    const eventIdCallback = root._doNotAggregate ? undefined : TimelineModel.TimelineProfileTree._eventId;
-    const eventGroupIdCallback = root._eventGroupIdCallback;
-    let depth = 0;
-    let matchedDepth = 0;
-    let currentDirectChild = null;
-    TimelineModel.TimelineModel.forEachEvent(
-        root._events, onStartEvent, onEndEvent, instantEventCallback, startTime, endTime, root._filter);
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onStartEvent(e) {
-      ++depth;
-      if (depth > path.length + 2)
-        return;
-      if (!matchPath(e))
-        return;
-      const duration = Math.min(endTime, e.endTime) - Math.max(startTime, e.startTime);
-      if (duration < 0)
-        console.error('Negative event duration');
-      processEvent(e, duration);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onInstantEvent(e) {
-      ++depth;
-      if (matchedDepth === path.length && depth <= path.length + 2)
-        processEvent(e, 0);
-      --depth;
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     * @param {number} duration
-     */
-    function processEvent(e, duration) {
-      if (depth === path.length + 2) {
-        currentDirectChild._hasChildren = true;
-        currentDirectChild.selfTime -= duration;
-        return;
-      }
-      let id;
-      let groupId = '';
-      if (!eventIdCallback) {
-        id = Symbol('uniqueId');
-      } else {
-        id = eventIdCallback(e);
-        groupId = eventGroupIdCallback ? eventGroupIdCallback(e) : '';
-        if (groupId)
-          id += '/' + groupId;
-      }
-      let node = children.get(id);
-      if (!node) {
-        node = new TimelineModel.TimelineProfileTree.TopDownNode(id, e, self);
-        node._groupId = groupId;
-        children.set(id, node);
-      }
-      node.selfTime += duration;
-      node.totalTime += duration;
-      currentDirectChild = node;
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     * @return {boolean}
-     */
-    function matchPath(e) {
-      if (matchedDepth === path.length)
-        return true;
-      if (matchedDepth !== depth - 1)
-        return false;
-      if (!e.endTime)
-        return false;
-      if (!eventIdCallback) {
-        if (e === path[matchedDepth].event)
-          ++matchedDepth;
-        return false;
-      }
-      let id = eventIdCallback(e);
-      const groupId = eventGroupIdCallback ? eventGroupIdCallback(e) : '';
-      if (groupId)
-        id += '/' + groupId;
-      if (id === path[matchedDepth].id)
-        ++matchedDepth;
-      return false;
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onEndEvent(e) {
-      --depth;
-      if (matchedDepth > depth)
-        matchedDepth = depth;
-    }
-
-    this._children = children;
-    return children;
-  }
-};
-
-TimelineModel.TimelineProfileTree.TopDownRootNode = class extends TimelineModel.TimelineProfileTree.TopDownNode {
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {boolean=} doNotAggregate
-   * @param {?function(!SDK.TracingModel.Event):string=} eventGroupIdCallback
-   */
-  constructor(events, filters, startTime, endTime, doNotAggregate, eventGroupIdCallback) {
-    super('', null, null);
-    this._root = this;
-    this._events = events;
-    this._filter = e => TimelineModel.TimelineModel.isVisible(filters, e);
-    this._startTime = startTime;
-    this._endTime = endTime;
-    this._eventGroupIdCallback = eventGroupIdCallback;
-    this._doNotAggregate = doNotAggregate;
-    this.totalTime = endTime - startTime;
-    this.selfTime = this.totalTime;
-  }
-
-  /**
-   * @override
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  children() {
-    return this._children || this._grouppedTopNodes();
-  }
-
-  /**
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  _grouppedTopNodes() {
-    const flatNodes = super.children();
-    for (const node of flatNodes.values())
-      this.selfTime -= node.totalTime;
-    if (!this._eventGroupIdCallback)
-      return flatNodes;
-    const groupNodes = new Map();
-    for (const node of flatNodes.values()) {
-      const groupId = this._eventGroupIdCallback(/** @type {!SDK.TracingModel.Event} */ (node.event));
-      let groupNode = groupNodes.get(groupId);
-      if (!groupNode) {
-        groupNode = new TimelineModel.TimelineProfileTree.GroupNode(
-            groupId, this, /** @type {!SDK.TracingModel.Event} */ (node.event));
-        groupNodes.set(groupId, groupNode);
-      }
-      groupNode.addChild(node, node.selfTime, node.totalTime);
-    }
-    this._children = groupNodes;
-    return groupNodes;
-  }
-};
-
-TimelineModel.TimelineProfileTree.BottomUpRootNode = class extends TimelineModel.TimelineProfileTree.Node {
-  /**
-   * @param {!Array<!SDK.TracingModel.Event>} events
-   * @param {!Array<!TimelineModel.TimelineModelFilter>} filters
-   * @param {number} startTime
-   * @param {number} endTime
-   * @param {?function(!SDK.TracingModel.Event):string} eventGroupIdCallback
-   */
-  constructor(events, filters, startTime, endTime, eventGroupIdCallback) {
-    super('', null);
-    /** @type {?Map<string, !TimelineModel.TimelineProfileTree.Node>} */
-    this._children = null;
-    this._events = events;
-    this._filter = e => TimelineModel.TimelineModel.isVisible(filters, e);
-    this._startTime = startTime;
-    this._endTime = endTime;
-    this._eventGroupIdCallback = eventGroupIdCallback;
-    this.totalTime = endTime - startTime;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasChildren() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  children() {
-    return this._children || this._grouppedTopNodes();
-  }
-
-  /**
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  _ungrouppedTopNodes() {
-    const root = this;
-    const startTime = this._startTime;
-    const endTime = this._endTime;
-    /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */
-    const nodeById = new Map();
-    /** @type {!Array<number>} */
-    const selfTimeStack = [endTime - startTime];
-    /** @type {!Array<boolean>} */
-    const firstNodeStack = [];
-    /** @type {!Map<string, number>} */
-    const totalTimeById = new Map();
-    TimelineModel.TimelineModel.forEachEvent(
-        this._events, onStartEvent, onEndEvent, undefined, startTime, endTime, this._filter);
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onStartEvent(e) {
-      const duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startTime);
-      selfTimeStack[selfTimeStack.length - 1] -= duration;
-      selfTimeStack.push(duration);
-      const id = TimelineModel.TimelineProfileTree._eventId(e);
-      const noNodeOnStack = !totalTimeById.has(id);
-      if (noNodeOnStack)
-        totalTimeById.set(id, duration);
-      firstNodeStack.push(noNodeOnStack);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onEndEvent(e) {
-      const id = TimelineModel.TimelineProfileTree._eventId(e);
-      let node = nodeById.get(id);
-      if (!node) {
-        node = new TimelineModel.TimelineProfileTree.BottomUpNode(root, id, e, true, root);
-        nodeById.set(id, node);
-      }
-      node.selfTime += selfTimeStack.pop();
-      if (firstNodeStack.pop()) {
-        node.totalTime += totalTimeById.get(id);
-        totalTimeById.delete(id);
-      }
-    }
-
-    this.selfTime = selfTimeStack.pop();
-    for (const pair of nodeById) {
-      if (pair[1].selfTime <= 0)
-        nodeById.delete(/** @type {string} */ (pair[0]));
-    }
-    return nodeById;
-  }
-
-  /**
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  _grouppedTopNodes() {
-    const flatNodes = this._ungrouppedTopNodes();
-    if (!this._eventGroupIdCallback) {
-      this._children = flatNodes;
-      return flatNodes;
-    }
-    const groupNodes = new Map();
-    for (const node of flatNodes.values()) {
-      const groupId = this._eventGroupIdCallback(/** @type {!SDK.TracingModel.Event} */ (node.event));
-      let groupNode = groupNodes.get(groupId);
-      if (!groupNode) {
-        groupNode = new TimelineModel.TimelineProfileTree.GroupNode(
-            groupId, this, /** @type {!SDK.TracingModel.Event} */ (node.event));
-        groupNodes.set(groupId, groupNode);
-      }
-      groupNode.addChild(node, node.selfTime, node.selfTime);
-    }
-    this._children = groupNodes;
-    return groupNodes;
-  }
-};
-
-TimelineModel.TimelineProfileTree.GroupNode = class extends TimelineModel.TimelineProfileTree.Node {
-  /**
-   * @param {string} id
-   * @param {!TimelineModel.TimelineProfileTree.BottomUpRootNode|!TimelineModel.TimelineProfileTree.TopDownRootNode} parent
-   * @param {!SDK.TracingModel.Event} event
-   */
-  constructor(id, parent, event) {
-    super(id, event);
-    this._children = new Map();
-    this.parent = parent;
-    this._isGroupNode = true;
-  }
-
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.BottomUpNode} child
-   * @param {number} selfTime
-   * @param {number} totalTime
-   */
-  addChild(child, selfTime, totalTime) {
-    this._children.set(child.id, child);
-    this.selfTime += selfTime;
-    this.totalTime += totalTime;
-    child.parent = this;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasChildren() {
-    return true;
-  }
-
-  /**
-   * @override
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  children() {
-    return this._children;
-  }
-};
-
-TimelineModel.TimelineProfileTree.BottomUpNode = class extends TimelineModel.TimelineProfileTree.Node {
-  /**
-   * @param {!TimelineModel.TimelineProfileTree.BottomUpRootNode} root
-   * @param {string} id
-   * @param {!SDK.TracingModel.Event} event
-   * @param {boolean} hasChildren
-   * @param {!TimelineModel.TimelineProfileTree.Node} parent
-   */
-  constructor(root, id, event, hasChildren, parent) {
-    super(id, event);
-    this.parent = parent;
-    this._root = root;
-    this._depth = (parent._depth || 0) + 1;
-    this._cachedChildren = null;
-    this._hasChildren = hasChildren;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  hasChildren() {
-    return this._hasChildren;
-  }
-
-  /**
-   * @override
-   * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>}
-   */
-  children() {
-    if (this._cachedChildren)
-      return this._cachedChildren;
-    /** @type {!Array<number>} */
-    const selfTimeStack = [0];
-    /** @type {!Array<string>} */
-    const eventIdStack = [];
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    const eventStack = [];
-    /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */
-    const nodeById = new Map();
-    const startTime = this._root._startTime;
-    const endTime = this._root._endTime;
-    let lastTimeMarker = startTime;
-    const self = this;
-    TimelineModel.TimelineModel.forEachEvent(
-        this._root._events, onStartEvent, onEndEvent, undefined, startTime, endTime, this._root._filter);
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onStartEvent(e) {
-      const duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startTime);
-      if (duration < 0)
-        console.assert(false, 'Negative duration of an event');
-      selfTimeStack[selfTimeStack.length - 1] -= duration;
-      selfTimeStack.push(duration);
-      const id = TimelineModel.TimelineProfileTree._eventId(e);
-      eventIdStack.push(id);
-      eventStack.push(e);
-    }
-
-    /**
-     * @param {!SDK.TracingModel.Event} e
-     */
-    function onEndEvent(e) {
-      const selfTime = selfTimeStack.pop();
-      const id = eventIdStack.pop();
-      eventStack.pop();
-      let node;
-      for (node = self; node._depth > 1; node = node.parent) {
-        if (node.id !== eventIdStack[eventIdStack.length + 1 - node._depth])
-          return;
-      }
-      if (node.id !== id || eventIdStack.length < self._depth)
-        return;
-      const childId = eventIdStack[eventIdStack.length - self._depth];
-      node = nodeById.get(childId);
-      if (!node) {
-        const event = eventStack[eventStack.length - self._depth];
-        const hasChildren = eventStack.length > self._depth;
-        node = new TimelineModel.TimelineProfileTree.BottomUpNode(self._root, childId, event, hasChildren, self);
-        nodeById.set(childId, node);
-      }
-      const totalTime = Math.min(e.endTime, endTime) - Math.max(e.startTime, lastTimeMarker);
-      node.selfTime += selfTime;
-      node.totalTime += totalTime;
-      lastTimeMarker = Math.min(e.endTime, endTime);
-    }
-
-    this._cachedChildren = nodeById;
-    return nodeById;
-  }
-
-  /**
-   * @override
-   * @param {function(!SDK.TracingModel.Event):boolean} matchFunction
-   * @param {!Array<!TimelineModel.TimelineProfileTree.Node>=} results
-   * @return {!Array<!TimelineModel.TimelineProfileTree.Node>}
-   */
-  searchTree(matchFunction, results) {
-    results = results || [];
-    if (this.event && matchFunction(this.event))
-      results.push(this);
-    return results;
-  }
-};
-
-/**
- * @param {!SDK.TracingModel.Event} event
- * @return {?string}
- */
-TimelineModel.TimelineProfileTree.eventURL = function(event) {
-  const data = event.args['data'] || event.args['beginData'];
-  if (data && data['url'])
-    return data['url'];
-  let frame = TimelineModel.TimelineProfileTree.eventStackFrame(event);
-  while (frame) {
-    const url = frame['url'];
-    if (url)
-      return url;
-    frame = frame.parent;
-  }
-  return null;
-};
-
-/**
- * @param {!SDK.TracingModel.Event} event
- * @return {?Protocol.Runtime.CallFrame}
- */
-TimelineModel.TimelineProfileTree.eventStackFrame = function(event) {
-  if (event.name === TimelineModel.TimelineModel.RecordType.JSFrame)
-    return /** @type {?Protocol.Runtime.CallFrame} */ (event.args['data'] || null);
-  return TimelineModel.TimelineData.forEvent(event).topFrame();
-};
-
-/**
- * @param {!SDK.TracingModel.Event} event
- * @return {string}
- */
-TimelineModel.TimelineProfileTree._eventId = function(event) {
-  if (event.name === TimelineModel.TimelineModel.RecordType.TimeStamp)
-    return `${event.name}:${event.args.data.message}`;
-  if (event.name !== TimelineModel.TimelineModel.RecordType.JSFrame)
-    return event.name;
-  const frame = event.args['data'];
-  const location = frame['scriptId'] || frame['url'] || '';
-  const functionName = frame['functionName'];
-  const name = TimelineModel.TimelineJSProfileProcessor.isNativeRuntimeFrame(frame) ?
-      TimelineModel.TimelineJSProfileProcessor.nativeGroup(functionName) || functionName :
-      `${functionName}:${frame['lineNumber']}`;
-  return `f:${name}@${location}`;
-};
diff --git a/front_end/timeline_model/TracingLayerTree.js b/front_end/timeline_model/TracingLayerTree.js
deleted file mode 100644
index cfaa503..0000000
--- a/front_end/timeline_model/TracingLayerTree.js
+++ /dev/null
@@ -1,482 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/** @typedef {!{
-        bounds: {height: number, width: number},
-        children: Array.<!TimelineModel.TracingLayerPayload>,
-        layer_id: number,
-        position: Array.<number>,
-        scroll_offset: Array.<number>,
-        layer_quad: Array.<number>,
-        draws_content: number,
-        gpu_memory_usage: number,
-        transform: Array.<number>,
-        owner_node: number,
-        compositing_reasons: Array.<string>
-    }}
-*/
-TimelineModel.TracingLayerPayload;
-
-/** @typedef {!{
-        id: string,
-        layer_id: string,
-        gpu_memory_usage: number,
-        content_rect: !Array.<number>
-    }}
-*/
-TimelineModel.TracingLayerTile;
-
-/**
- * @unrestricted
- */
-TimelineModel.TracingLayerTree = class extends SDK.LayerTreeBase {
-  /**
-   * @param {?SDK.Target} target
-   */
-  constructor(target) {
-    super(target);
-    /** @type {!Map.<string, !TimelineModel.TracingLayerTile>} */
-    this._tileById = new Map();
-    this._paintProfilerModel = target && target.model(SDK.PaintProfilerModel);
-  }
-
-  /**
-   * @param {?TimelineModel.TracingLayerPayload} root
-   * @param {?Array<!TimelineModel.TracingLayerPayload>} layers
-   * @param {!Array<!TimelineModel.LayerPaintEvent>} paints
-   * @return {!Promise}
-   */
-  async setLayers(root, layers, paints) {
-    const idsToResolve = new Set();
-    if (root) {
-      // This is a legacy code path for compatibility, as cc is removing
-      // layer tree hierarchy, this code will eventually be removed.
-      this._extractNodeIdsToResolve(idsToResolve, {}, root);
-    } else {
-      for (let i = 0; i < layers.length; ++i)
-        this._extractNodeIdsToResolve(idsToResolve, {}, layers[i]);
-    }
-
-    await this.resolveBackendNodeIds(idsToResolve);
-
-    const oldLayersById = this._layersById;
-    this._layersById = {};
-    this.setContentRoot(null);
-    if (root) {
-      const convertedLayers = this._innerSetLayers(oldLayersById, root);
-      this.setRoot(convertedLayers);
-    } else {
-      const processedLayers = layers.map(this._innerSetLayers.bind(this, oldLayersById));
-      const contentRoot = this.contentRoot();
-      this.setRoot(contentRoot);
-      for (let i = 0; i < processedLayers.length; ++i) {
-        if (processedLayers[i].id() !== contentRoot.id())
-          contentRoot.addChild(processedLayers[i]);
-      }
-    }
-    this._setPaints(paints);
-  }
-
-  /**
-   * @param {!Array.<!TimelineModel.TracingLayerTile>} tiles
-   */
-  setTiles(tiles) {
-    this._tileById = new Map();
-    for (const tile of tiles)
-      this._tileById.set(tile.id, tile);
-  }
-
-  /**
-   * @param {string} tileId
-   * @return {!Promise<?SDK.SnapshotWithRect>}
-   */
-  pictureForRasterTile(tileId) {
-    const tile = this._tileById.get('cc::Tile/' + tileId);
-    if (!tile) {
-      Common.console.error(`Tile ${tileId} is missing`);
-      return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(null));
-    }
-    const layer = this.layerById(tile.layer_id);
-    if (!layer) {
-      Common.console.error(`Layer ${tile.layer_id} for tile ${tileId} is not found`);
-      return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(null));
-    }
-    return layer._pictureForRect(tile.content_rect);
-  }
-
-  /**
-   * @param {!Array<!TimelineModel.LayerPaintEvent>} paints
-   */
-  _setPaints(paints) {
-    for (let i = 0; i < paints.length; ++i) {
-      const layer = this._layersById[paints[i].layerId()];
-      if (layer)
-        layer._addPaintEvent(paints[i]);
-    }
-  }
-
-  /**
-   * @param {!Object<(string|number), !SDK.Layer>} oldLayersById
-   * @param {!TimelineModel.TracingLayerPayload} payload
-   * @return {!TimelineModel.TracingLayer}
-   */
-  _innerSetLayers(oldLayersById, payload) {
-    let layer = /** @type {?TimelineModel.TracingLayer} */ (oldLayersById[payload.layer_id]);
-    if (layer)
-      layer._reset(payload);
-    else
-      layer = new TimelineModel.TracingLayer(this._paintProfilerModel, payload);
-    this._layersById[payload.layer_id] = layer;
-    if (payload.owner_node)
-      layer._setNode(this.backendNodeIdToNode().get(payload.owner_node) || null);
-    if (!this.contentRoot() && layer.drawsContent())
-      this.setContentRoot(layer);
-    for (let i = 0; payload.children && i < payload.children.length; ++i)
-      layer.addChild(this._innerSetLayers(oldLayersById, payload.children[i]));
-    return layer;
-  }
-
-  /**
-   * @param {!Set<number>} nodeIdsToResolve
-   * @param {!Object} seenNodeIds
-   * @param {!TimelineModel.TracingLayerPayload} payload
-   */
-  _extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload) {
-    const backendNodeId = payload.owner_node;
-    if (backendNodeId && !this.backendNodeIdToNode().has(backendNodeId))
-      nodeIdsToResolve.add(backendNodeId);
-    for (let i = 0; payload.children && i < payload.children.length; ++i)
-      this._extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload.children[i]);
-  }
-};
-
-/**
- * @implements {SDK.Layer}
- * @unrestricted
- */
-TimelineModel.TracingLayer = class {
-  /**
-   * @param {?SDK.PaintProfilerModel} paintProfilerModel
-   * @param {!TimelineModel.TracingLayerPayload} payload
-   */
-  constructor(paintProfilerModel, payload) {
-    this._paintProfilerModel = paintProfilerModel;
-    this._reset(payload);
-  }
-
-  /**
-   * @param {!TimelineModel.TracingLayerPayload} payload
-   */
-  _reset(payload) {
-    /** @type {?SDK.DOMNode} */
-    this._node = null;
-    this._layerId = String(payload.layer_id);
-    this._offsetX = payload.position[0];
-    this._offsetY = payload.position[1];
-    this._width = payload.bounds.width;
-    this._height = payload.bounds.height;
-    this._children = [];
-    this._parentLayerId = null;
-    this._parent = null;
-    this._quad = payload.layer_quad || [];
-    this._createScrollRects(payload);
-    this._compositingReasons = payload.compositing_reasons || [];
-    this._drawsContent = !!payload.draws_content;
-    this._gpuMemoryUsage = payload.gpu_memory_usage;
-    this._paints = [];
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  id() {
-    return this._layerId;
-  }
-
-  /**
-   * @override
-   * @return {?string}
-   */
-  parentId() {
-    return this._parentLayerId;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.Layer}
-   */
-  parent() {
-    return this._parent;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isRoot() {
-    return !this.parentId();
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!SDK.Layer>}
-   */
-  children() {
-    return this._children;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.Layer} child
-   */
-  addChild(child) {
-    if (child._parent)
-      console.assert(false, 'Child already has a parent');
-    this._children.push(child);
-    child._parent = this;
-    child._parentLayerId = this._layerId;
-  }
-
-  /**
-   * @param {?SDK.DOMNode} node
-   */
-  _setNode(node) {
-    this._node = node;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.DOMNode}
-   */
-  node() {
-    return this._node;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.DOMNode}
-   */
-  nodeForSelfOrAncestor() {
-    for (let layer = this; layer; layer = layer._parent) {
-      if (layer._node)
-        return layer._node;
-    }
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  offsetX() {
-    return this._offsetX;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  offsetY() {
-    return this._offsetY;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  width() {
-    return this._width;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  height() {
-    return this._height;
-  }
-
-  /**
-   * @override
-   * @return {?Array.<number>}
-   */
-  transform() {
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<number>}
-   */
-  quad() {
-    return this._quad;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<number>}
-   */
-  anchorPoint() {
-    return [0.5, 0.5, 0];
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  invisible() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  paintCount() {
-    return 0;
-  }
-
-  /**
-   * @override
-   * @return {?Protocol.DOM.Rect}
-   */
-  lastPaintRect() {
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Protocol.LayerTree.ScrollRect>}
-   */
-  scrollRects() {
-    return this._scrollRects;
-  }
-
-  /**
-   * @override
-   * @return {?SDK.Layer.StickyPositionConstraint}
-   */
-  stickyPositionConstraint() {
-    // TODO(smcgruer): Provide sticky layer information in traces.
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  gpuMemoryUsage() {
-    return this._gpuMemoryUsage;
-  }
-
-  /**
-   * @override
-   * @return {!Array<!Promise<?SDK.SnapshotWithRect>>}
-   */
-  snapshots() {
-    return this._paints.map(paint => paint.snapshotPromise().then(snapshot => {
-      if (!snapshot)
-        return null;
-      const rect = {x: snapshot.rect[0], y: snapshot.rect[1], width: snapshot.rect[2], height: snapshot.rect[3]};
-      return {rect: rect, snapshot: snapshot.snapshot};
-    }));
-  }
-
-  /**
-   * @param {!Array<number>} targetRect
-   * @return {!Promise<?SDK.SnapshotWithRect>}
-   */
-  _pictureForRect(targetRect) {
-    return Promise.all(this._paints.map(paint => paint.picturePromise())).then(pictures => {
-      const fragments =
-          pictures.filter(picture => picture && rectsOverlap(picture.rect, targetRect))
-              .map(picture => ({x: picture.rect[0], y: picture.rect[1], picture: picture.serializedPicture}));
-      if (!fragments.length || !this._paintProfilerModel)
-        return null;
-      const x0 = fragments.reduce((min, item) => Math.min(min, item.x), Infinity);
-      const y0 = fragments.reduce((min, item) => Math.min(min, item.y), Infinity);
-      // Rect is in layer content coordinates, make it relative to picture by offsetting to the top left corner.
-      const rect = {x: targetRect[0] - x0, y: targetRect[1] - y0, width: targetRect[2], height: targetRect[3]};
-      return this._paintProfilerModel.loadSnapshotFromFragments(fragments).then(
-          snapshot => snapshot ? {rect: rect, snapshot: snapshot} : null);
-    });
-
-    /**
-     * @param {number} a1
-     * @param {number} a2
-     * @param {number} b1
-     * @param {number} b2
-     * @return {boolean}
-     */
-    function segmentsOverlap(a1, a2, b1, b2) {
-      console.assert(a1 <= a2 && b1 <= b2, 'segments should be specified as ordered pairs');
-      return a2 > b1 && a1 < b2;
-    }
-
-    /**
-     * @param {!Array.<number>} a
-     * @param {!Array.<number>} b
-     * @return {boolean}
-     */
-    function rectsOverlap(a, b) {
-      return segmentsOverlap(a[0], a[0] + a[2], b[0], b[0] + b[2]) &&
-          segmentsOverlap(a[1], a[1] + a[3], b[1], b[1] + b[3]);
-    }
-  }
-
-  /**
-   * @param {!Array.<number>} params
-   * @param {string} type
-   * @return {!Object}
-   */
-  _scrollRectsFromParams(params, type) {
-    return {rect: {x: params[0], y: params[1], width: params[2], height: params[3]}, type: type};
-  }
-
-  /**
-   * @param {!TimelineModel.TracingLayerPayload} payload
-   */
-  _createScrollRects(payload) {
-    this._scrollRects = [];
-    if (payload.non_fast_scrollable_region) {
-      this._scrollRects.push(this._scrollRectsFromParams(
-          payload.non_fast_scrollable_region, SDK.Layer.ScrollRectType.NonFastScrollable.name));
-    }
-    if (payload.touch_event_handler_region) {
-      this._scrollRects.push(this._scrollRectsFromParams(
-          payload.touch_event_handler_region, SDK.Layer.ScrollRectType.TouchEventHandler.name));
-    }
-    if (payload.wheel_event_handler_region) {
-      this._scrollRects.push(this._scrollRectsFromParams(
-          payload.wheel_event_handler_region, SDK.Layer.ScrollRectType.WheelEventHandler.name));
-    }
-    if (payload.scroll_event_handler_region) {
-      this._scrollRects.push(this._scrollRectsFromParams(
-          payload.scroll_event_handler_region, SDK.Layer.ScrollRectType.RepaintsOnScroll.name));
-    }
-  }
-
-  /**
-   * @param {!TimelineModel.LayerPaintEvent} paint
-   */
-  _addPaintEvent(paint) {
-    this._paints.push(paint);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<!Array<string>>}
-   */
-  requestCompositingReasons() {
-    return Promise.resolve(this._compositingReasons);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  drawsContent() {
-    return this._drawsContent;
-  }
-};
diff --git a/front_end/timeline_model/module.json b/front_end/timeline_model/module.json
deleted file mode 100644
index 02e9ace..0000000
--- a/front_end/timeline_model/module.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "dependencies": [
-        "sdk"
-    ],
-    "scripts": [
-        "TimelineModelFilter.js",
-        "TracingLayerTree.js",
-        "TimelineModel.js",
-        "TimelineIRModel.js",
-        "TimelineJSProfile.js",
-        "TimelineFrameModel.js",
-        "TimelineProfileTree.js"
-    ]
-}
diff --git a/front_end/toolbox.html b/front_end/toolbox.html
deleted file mode 100644
index 03b95ec..0000000
--- a/front_end/toolbox.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!--
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' ">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="toolbox.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/toolbox.js b/front_end/toolbox.js
deleted file mode 100644
index fe47ccc..0000000
--- a/front_end/toolbox.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Runtime.startApplication('toolbox');
diff --git a/front_end/toolbox.json b/front_end/toolbox.json
deleted file mode 100644
index 66d55ff..0000000
--- a/front_end/toolbox.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "modules": [
-    { "name": "platform", "type": "autostart" },
-    { "name": "dom_extension","type": "autostart" },
-    { "name": "toolbox_bootstrap", "type": "autostart" }
-  ],
-  "has_html": true
-}
diff --git a/front_end/toolbox_bootstrap/Toolbox.js b/front_end/toolbox_bootstrap/Toolbox.js
deleted file mode 100644
index 731f91b..0000000
--- a/front_end/toolbox_bootstrap/Toolbox.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-(function() {
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  function toolboxLoaded() {
-    if (!window.opener)
-      return;
-    const app = window.opener['Emulation']['AdvancedApp']['_instance']();
-    app['toolboxLoaded'](document);
-  }
-
-  runOnWindowLoad(toolboxLoaded);
-})();
diff --git a/front_end/toolbox_bootstrap/module.json b/front_end/toolbox_bootstrap/module.json
deleted file mode 100644
index b67097d..0000000
--- a/front_end/toolbox_bootstrap/module.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "dependencies": [
-        "platform",
-        "dom_extension"
-    ],
-    "scripts": [
-        "Toolbox.js"
-    ]
-}
diff --git a/front_end/ui/ARIAUtils.js b/front_end/ui/ARIAUtils.js
deleted file mode 100644
index 3d039a0..0000000
--- a/front_end/ui/ARIAUtils.js
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.ARIAUtils = {};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsButton = function(element) {
-  element.setAttribute('role', 'button');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsGroup = function(element) {
-  element.setAttribute('role', 'group');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsLink = function(element) {
-  element.setAttribute('role', 'link');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsTab = function(element) {
-  element.setAttribute('role', 'tab');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsTree = function(element) {
-  element.setAttribute('role', 'tree');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsTreeitem = function(element) {
-  element.setAttribute('role', 'treeitem');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsTextBox = function(element) {
-  element.setAttribute('role', 'textbox');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsHidden = function(element) {
-  element.setAttribute('aria-hidden', 'true');
-};
-
-/**
- * @param {!Element} element
- * @param {?string} placeholder
- */
-UI.ARIAUtils.setPlaceholder = function(element, placeholder) {
-  if (placeholder)
-    element.setAttribute('aria-placeholder', placeholder);
-  else
-    element.removeAttribute('aria-placeholder');
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.markAsPresentation = function(element) {
-  element.setAttribute('role', 'presentation');
-};
-
-/**
- * @param {!Element} element
- * @param {?Element} controlledElement
- */
-UI.ARIAUtils.setControls = function(element, controlledElement) {
-  if (!controlledElement) {
-    element.removeAttribute('aria-controls');
-    return;
-  }
-
-  if (controlledElement.id === '')
-    throw new Error('Controlled element must have ID');
-
-  element.setAttribute('aria-controls', controlledElement.id);
-};
-
-/**
- * @param {!Element} element
- * @param {boolean} value
- */
-UI.ARIAUtils.setExpanded = function(element, value) {
-  element.setAttribute('aria-expanded', !!value);
-};
-
-/**
- * @param {!Element} element
- */
-UI.ARIAUtils.unsetExpanded = function(element) {
-  element.removeAttribute('aria-expanded');
-};
-
-/**
- * @param {!Element} element
- * @param {boolean} value
- */
-UI.ARIAUtils.setSelected = function(element, value) {
-  // aria-selected behaves differently for false and undefined.
-  // Often times undefined values are unintentionally typed as booleans.
-  // Use !! to make sure this is true or false.
-  element.setAttribute('aria-selected', !!value);
-};
-
-/**
- * @param {!Element} element
- * @param {boolean} value
- */
-UI.ARIAUtils.setPressed = function(element, value) {
-  // aria-pressed behaves differently for false and undefined.
-  // Often times undefined values are unintentionally typed as booleans.
-  // Use !! to make sure this is true or false.
-  element.setAttribute('aria-pressed', !!value);
-};
-
-/**
- * @param {!Element} element
- * @param {string} name
- */
-UI.ARIAUtils.setAccessibleName = function(element, name) {
-  element.setAttribute('aria-label', name);
-};
-
-/**
- * @param {string} message
- * @param {!Element} element
- */
-UI.ARIAUtils.alert = function(message, element) {
-  const document = element.ownerDocument;
-  if (!document[UI.ARIAUtils.AlertElementSymbol]) {
-    const alertElement = document.body.createChild('div');
-    alertElement.style.position = 'absolute';
-    alertElement.style.left = '-999em';
-    alertElement.setAttribute('role', 'alert');
-    alertElement.setAttribute('aria-atomic', 'true');
-    document[UI.ARIAUtils.AlertElementSymbol] = alertElement;
-  }
-  document[UI.ARIAUtils.AlertElementSymbol].textContent = message;
-};
-
-UI.ARIAUtils.AlertElementSymbol = Symbol('AlertElementSybmol');
diff --git a/front_end/ui/ActionRegistry.js b/front_end/ui/ActionRegistry.js
deleted file mode 100644
index a147903..0000000
--- a/front_end/ui/ActionRegistry.js
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ActionRegistry = class {
-  constructor() {
-    /** @type {!Map.<string, !UI.Action>} */
-    this._actionsById = new Map();
-    this._registerActions();
-  }
-
-  _registerActions() {
-    self.runtime.extensions('action').forEach(registerExtension, this);
-
-    /**
-     * @param {!Runtime.Extension} extension
-     * @this {UI.ActionRegistry}
-     */
-    function registerExtension(extension) {
-      if (!extension.canInstantiate())
-        return;
-      const actionId = extension.descriptor()['actionId'];
-      console.assert(actionId);
-      console.assert(!this._actionsById.get(actionId));
-
-      const action = new UI.Action(extension);
-      if (!action.category() || action.title())
-        this._actionsById.set(actionId, action);
-      else
-        console.error(`Category actions require a title for command menu: ${actionId}`);
-    }
-  }
-
-  /**
-   * @return {!Array.<!UI.Action>}
-   */
-  availableActions() {
-    return this.applicableActions(this._actionsById.keysArray(), UI.context);
-  }
-
-  /**
-   * @param {!Array.<string>} actionIds
-   * @param {!UI.Context} context
-   * @return {!Array.<!UI.Action>}
-   */
-  applicableActions(actionIds, context) {
-    const extensions = [];
-    actionIds.forEach(function(actionId) {
-      const action = this._actionsById.get(actionId);
-      if (action)
-        extensions.push(action._extension);
-    }, this);
-    return context.applicableExtensions(extensions).valuesArray().map(extensionToAction.bind(this));
-
-    /**
-     * @param {!Runtime.Extension} extension
-     * @return {!UI.Action}
-     * @this {UI.ActionRegistry}
-     */
-    function extensionToAction(extension) {
-      return /** @type {!UI.Action} */ (this.action(extension.descriptor()['actionId']));
-    }
-  }
-
-  /**
-   * @param {string} actionId
-   * @return {?UI.Action}
-   */
-  action(actionId) {
-    return this._actionsById.get(actionId) || null;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.Action = class extends Common.Object {
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  constructor(extension) {
-    super();
-    this._extension = extension;
-    this._enabled = true;
-    this._toggled = false;
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this._extension.descriptor()['actionId'];
-  }
-
-  /**
-   * @return {!Promise.<boolean>}
-   */
-  execute() {
-    return this._extension.instance().then(handleAction.bind(this));
-
-    /**
-     * @param {!Object} actionDelegate
-     * @return {boolean}
-     * @this {UI.Action}
-     */
-    function handleAction(actionDelegate) {
-      const actionId = this._extension.descriptor()['actionId'];
-      const delegate = /** @type {!UI.ActionDelegate} */ (actionDelegate);
-      return delegate.handleAction(UI.context, actionId);
-    }
-  }
-
-  /**
-   * @return {string}
-   */
-  icon() {
-    return this._extension.descriptor()['iconClass'] || '';
-  }
-
-  /**
-   * @return {string}
-   */
-  toggledIcon() {
-    return this._extension.descriptor()['toggledIconClass'] || '';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  toggleWithRedColor() {
-    return !!this._extension.descriptor()['toggleWithRedColor'];
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    if (this._enabled === enabled)
-      return;
-
-    this._enabled = enabled;
-    this.dispatchEventToListeners(UI.Action.Events.Enabled, enabled);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  enabled() {
-    return this._enabled;
-  }
-
-  /**
-   * @return {string}
-   */
-  category() {
-    return this._extension.descriptor()['category'] || '';
-  }
-
-  /**
-   * @return {string}
-   */
-  tags() {
-    return this._extension.descriptor()['tags'] || '';
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    let title = this._extension.title();
-    const options = this._extension.descriptor()['options'];
-    if (options) {
-      for (const pair of options) {
-        if (pair['value'] !== this._toggled)
-          title = pair['title'];
-      }
-    }
-    return title;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  toggled() {
-    return this._toggled;
-  }
-
-  /**
-   * @param {boolean} toggled
-   */
-  setToggled(toggled) {
-    if (this._toggled === toggled)
-      return;
-
-    this._toggled = toggled;
-    this.dispatchEventToListeners(UI.Action.Events.Toggled, toggled);
-  }
-};
-
-/** @enum {symbol} */
-UI.Action.Events = {
-  Enabled: Symbol('Enabled'),
-  Toggled: Symbol('Toggled')
-};
-
-/**
- * @interface
- */
-UI.ActionDelegate = function() {};
-
-UI.ActionDelegate.prototype = {
-  /**
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {}
-};
-
-/** @type {!UI.ActionRegistry} */
-UI.actionRegistry;
diff --git a/front_end/ui/Context.js b/front_end/ui/Context.js
deleted file mode 100644
index 31b5be9..0000000
--- a/front_end/ui/Context.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.Context = class {
-  constructor() {
-    this._flavors = new Map();
-    this._eventDispatchers = new Map();
-  }
-
-  /**
-   * @param {function(new:T, ...)} flavorType
-   * @param {?T} flavorValue
-   * @template T
-   */
-  setFlavor(flavorType, flavorValue) {
-    const value = this._flavors.get(flavorType) || null;
-    if (value === flavorValue)
-      return;
-    if (flavorValue)
-      this._flavors.set(flavorType, flavorValue);
-    else
-      this._flavors.remove(flavorType);
-
-    this._dispatchFlavorChange(flavorType, flavorValue);
-  }
-
-  /**
-   * @param {function(new:T, ...)} flavorType
-   * @param {?T} flavorValue
-   * @template T
-   */
-  _dispatchFlavorChange(flavorType, flavorValue) {
-    for (const extension of self.runtime.extensions(UI.ContextFlavorListener)) {
-      if (extension.hasContextType(flavorType)) {
-        extension.instance().then(
-            instance => /** @type {!UI.ContextFlavorListener} */ (instance).flavorChanged(flavorValue));
-      }
-    }
-    const dispatcher = this._eventDispatchers.get(flavorType);
-    if (!dispatcher)
-      return;
-    dispatcher.dispatchEventToListeners(UI.Context.Events.FlavorChanged, flavorValue);
-  }
-
-  /**
-   * @param {function(new:Object, ...)} flavorType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  addFlavorChangeListener(flavorType, listener, thisObject) {
-    let dispatcher = this._eventDispatchers.get(flavorType);
-    if (!dispatcher) {
-      dispatcher = new Common.Object();
-      this._eventDispatchers.set(flavorType, dispatcher);
-    }
-    dispatcher.addEventListener(UI.Context.Events.FlavorChanged, listener, thisObject);
-  }
-
-  /**
-   * @param {function(new:Object, ...)} flavorType
-   * @param {function(!Common.Event)} listener
-   * @param {!Object=} thisObject
-   */
-  removeFlavorChangeListener(flavorType, listener, thisObject) {
-    const dispatcher = this._eventDispatchers.get(flavorType);
-    if (!dispatcher)
-      return;
-    dispatcher.removeEventListener(UI.Context.Events.FlavorChanged, listener, thisObject);
-    if (!dispatcher.hasEventListeners(UI.Context.Events.FlavorChanged))
-      this._eventDispatchers.remove(flavorType);
-  }
-
-  /**
-   * @param {function(new:T, ...)} flavorType
-   * @return {?T}
-   * @template T
-   */
-  flavor(flavorType) {
-    return this._flavors.get(flavorType) || null;
-  }
-
-  /**
-   * @return {!Set.<function(new:Object, ...)>}
-   */
-  flavors() {
-    return new Set(this._flavors.keys());
-  }
-
-  /**
-   * @param {!Array.<!Runtime.Extension>} extensions
-   * @return {!Set.<!Runtime.Extension>}
-   */
-  applicableExtensions(extensions) {
-    const targetExtensionSet = new Set();
-
-    const availableFlavors = this.flavors();
-    extensions.forEach(function(extension) {
-      if (self.runtime.isExtensionApplicableToContextTypes(extension, availableFlavors))
-        targetExtensionSet.add(extension);
-    });
-
-    return targetExtensionSet;
-  }
-};
-
-/** @enum {symbol} */
-UI.Context.Events = {
-  FlavorChanged: Symbol('FlavorChanged')
-};
-
-/**
- * @interface
- */
-UI.ContextFlavorListener = function() {};
-
-UI.ContextFlavorListener.prototype = {
-  /**
-   * @param {?Object} object
-   */
-  flavorChanged(object) {}
-};
-
-UI.context = new UI.Context();
diff --git a/front_end/ui/ContextMenu.js b/front_end/ui/ContextMenu.js
deleted file mode 100644
index 759b485..0000000
--- a/front_end/ui/ContextMenu.js
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.ContextMenuItem = class {
-  /**
-   * @param {?UI.ContextMenu} contextMenu
-   * @param {string} type
-   * @param {string=} label
-   * @param {boolean=} disabled
-   * @param {boolean=} checked
-   */
-  constructor(contextMenu, type, label, disabled, checked) {
-    this._type = type;
-    this._label = label;
-    this._disabled = disabled;
-    this._checked = checked;
-    this._contextMenu = contextMenu;
-    if (type === 'item' || type === 'checkbox')
-      this._id = contextMenu ? contextMenu._nextId() : 0;
-  }
-
-  /**
-   * @return {number}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEnabled() {
-    return !this._disabled;
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._disabled = !enabled;
-  }
-
-  /**
-   * @return {!InspectorFrontendHostAPI.ContextMenuDescriptor}
-   */
-  _buildDescriptor() {
-    switch (this._type) {
-      case 'item':
-        const result = {type: 'item', id: this._id, label: this._label, enabled: !this._disabled};
-        if (this._customElement)
-          result.element = this._customElement;
-        if (this._shortcut)
-          result.shortcut = this._shortcut;
-        return result;
-      case 'separator':
-        return {type: 'separator'};
-      case 'checkbox':
-        return {type: 'checkbox', id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled};
-    }
-    throw new Error('Invalid item type:' + this._type);
-  }
-
-  /**
-   * @param {string} shortcut
-   */
-  setShortcut(shortcut) {
-    this._shortcut = shortcut;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ContextMenuSection = class {
-  /**
-   * @param {?UI.ContextMenu} contextMenu
-   */
-  constructor(contextMenu) {
-    this._contextMenu = contextMenu;
-    /** @type {!Array<!UI.ContextMenuItem>} */
-    this._items = [];
-  }
-
-  /**
-   * @param {string} label
-   * @param {function(?)} handler
-   * @param {boolean=} disabled
-   * @return {!UI.ContextMenuItem}
-   */
-  appendItem(label, handler, disabled) {
-    const item = new UI.ContextMenuItem(this._contextMenu, 'item', label, disabled);
-    this._items.push(item);
-    this._contextMenu._setHandler(item.id(), handler);
-    return item;
-  }
-
-  /**
-   * @param {!Element} element
-   * @return {!UI.ContextMenuItem}
-   */
-  appendCustomItem(element) {
-    const item = new UI.ContextMenuItem(this._contextMenu, 'item', '<custom>');
-    item._customElement = element;
-    this._items.push(item);
-    return item;
-  }
-
-  /**
-   * @param {string} actionId
-   * @param {string=} label
-   */
-  appendAction(actionId, label) {
-    const action = UI.actionRegistry.action(actionId);
-    if (!action) {
-      console.error(`Action ${actionId} was not defined`);
-      return;
-    }
-    if (!label)
-      label = action.title();
-    const result = this.appendItem(label, action.execute.bind(action));
-    const shortcut = UI.shortcutRegistry.shortcutTitleForAction(actionId);
-    if (shortcut)
-      result.setShortcut(shortcut);
-  }
-
-  /**
-   * @param {string} label
-   * @param {boolean=} disabled
-   * @return {!UI.ContextSubMenu}
-   */
-  appendSubMenuItem(label, disabled) {
-    const item = new UI.ContextSubMenu(this._contextMenu, label, disabled);
-    item._init();
-    this._items.push(item);
-    return item;
-  }
-
-  /**
-   * @param {string} label
-   * @param {function()} handler
-   * @param {boolean=} checked
-   * @param {boolean=} disabled
-   * @return {!UI.ContextMenuItem}
-   */
-  appendCheckboxItem(label, handler, checked, disabled) {
-    const item = new UI.ContextMenuItem(this._contextMenu, 'checkbox', label, disabled, checked);
-    this._items.push(item);
-    this._contextMenu._setHandler(item.id(), handler);
-    return item;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ContextSubMenu = class extends UI.ContextMenuItem {
-  /**
-   * @param {?UI.ContextMenu} contextMenu
-   * @param {string=} label
-   * @param {boolean=} disabled
-   */
-  constructor(contextMenu, label, disabled) {
-    super(contextMenu, 'subMenu', label, disabled);
-    /** @type {!Map<string, !UI.ContextMenuSection>} */
-    this._sections = new Map();
-    /** @type {!Array<!UI.ContextMenuSection>} */
-    this._sectionList = [];
-  }
-
-  _init() {
-    UI.ContextMenu._groupWeights.forEach(name => this.section(name));
-  }
-
-  /**
-   * @param {string=} name
-   * @return {!UI.ContextMenuSection}
-   */
-  section(name) {
-    let section = name ? this._sections.get(name) : null;
-    if (!section) {
-      section = new UI.ContextMenuSection(this._contextMenu);
-      if (name) {
-        this._sections.set(name, section);
-        this._sectionList.push(section);
-      } else {
-        this._sectionList.splice(UI.ContextMenu._groupWeights.indexOf('default'), 0, section);
-      }
-    }
-    return section;
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  headerSection() {
-    return this.section('header');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  newSection() {
-    return this.section('new');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  revealSection() {
-    return this.section('reveal');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  clipboardSection() {
-    return this.section('clipboard');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  editSection() {
-    return this.section('edit');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  debugSection() {
-    return this.section('debug');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  viewSection() {
-    return this.section('view');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  defaultSection() {
-    return this.section('default');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  saveSection() {
-    return this.section('save');
-  }
-
-  /**
-   * @return {!UI.ContextMenuSection}
-   */
-  footerSection() {
-    return this.section('footer');
-  }
-
-  /**
-   * @override
-   * @return {!InspectorFrontendHostAPI.ContextMenuDescriptor}
-   */
-  _buildDescriptor() {
-    /** @type {!InspectorFrontendHostAPI.ContextMenuDescriptor} */
-    const result = {type: 'subMenu', label: this._label, enabled: !this._disabled, subItems: []};
-
-    const nonEmptySections = this._sectionList.filter(section => !!section._items.length);
-    for (const section of nonEmptySections) {
-      for (const item of section._items)
-        result.subItems.push(item._buildDescriptor());
-      if (section !== nonEmptySections.peekLast())
-        result.subItems.push({type: 'separator'});
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} location
-   */
-  appendItemsAtLocation(location) {
-    for (const extension of self.runtime.extensions('context-menu-item')) {
-      const itemLocation = extension.descriptor()['location'] || '';
-      if (!itemLocation.startsWith(location + '/'))
-        continue;
-
-      const section = itemLocation.substr(location.length + 1);
-      if (!section || section.includes('/'))
-        continue;
-
-      this.section(section).appendAction(extension.descriptor()['actionId']);
-    }
-  }
-};
-
-UI.ContextMenuItem._uniqueSectionName = 0;
-
-/**
- * @unrestricted
- */
-UI.ContextMenu = class extends UI.ContextSubMenu {
-  /**
-   * @param {!Event} event
-   * @param {boolean=} useSoftMenu
-   * @param {number=} x
-   * @param {number=} y
-   */
-  constructor(event, useSoftMenu, x, y) {
-    super(null);
-    this._contextMenu = this;
-    super._init();
-    this._defaultSection = this.defaultSection();
-    /** @type {!Array.<!Promise.<!Array.<!UI.ContextMenu.Provider>>>} */
-    this._pendingPromises = [];
-    /** @type {!Array<!Object>} */
-    this._pendingTargets = [];
-    this._event = event;
-    this._useSoftMenu = !!useSoftMenu;
-    this._x = x === undefined ? event.x : x;
-    this._y = y === undefined ? event.y : y;
-    this._handlers = {};
-    this._id = 0;
-
-    const target = event.deepElementFromPoint();
-    if (target)
-      this.appendApplicableItems(/** @type {!Object} */ (target));
-  }
-
-  static initialize() {
-    InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetUseSoftMenu, setUseSoftMenu);
-    /**
-     * @param {!Common.Event} event
-     */
-    function setUseSoftMenu(event) {
-      UI.ContextMenu._useSoftMenu = /** @type {boolean} */ (event.data);
-    }
-  }
-
-  /**
-   * @param {!Document} doc
-   */
-  static installHandler(doc) {
-    doc.body.addEventListener('contextmenu', handler, false);
-
-    /**
-     * @param {!Event} event
-     */
-    function handler(event) {
-      const contextMenu = new UI.ContextMenu(event);
-      contextMenu.show();
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  _nextId() {
-    return this._id++;
-  }
-
-  show() {
-    Promise.all(this._pendingPromises).then(populate.bind(this)).then(this._innerShow.bind(this));
-    UI.ContextMenu._pendingMenu = this;
-
-    /**
-     * @param {!Array.<!Array.<!UI.ContextMenu.Provider>>} appendCallResults
-     * @this {UI.ContextMenu}
-     */
-    function populate(appendCallResults) {
-      if (UI.ContextMenu._pendingMenu !== this)
-        return;
-      delete UI.ContextMenu._pendingMenu;
-
-      for (let i = 0; i < appendCallResults.length; ++i) {
-        const providers = appendCallResults[i];
-        const target = this._pendingTargets[i];
-
-        for (let j = 0; j < providers.length; ++j) {
-          const provider = /** @type {!UI.ContextMenu.Provider} */ (providers[j]);
-          provider.appendApplicableItems(this._event, this, target);
-        }
-      }
-
-      this._pendingPromises = [];
-      this._pendingTargets = [];
-    }
-
-    this._event.consume(true);
-  }
-
-  discard() {
-    if (this._softMenu)
-      this._softMenu.discard();
-  }
-
-  _innerShow() {
-    const menuObject = this._buildMenuDescriptors();
-    if (this._useSoftMenu || UI.ContextMenu._useSoftMenu || InspectorFrontendHost.isHostedMode()) {
-      this._softMenu = new UI.SoftContextMenu(menuObject, this._itemSelected.bind(this));
-      this._softMenu.show(this._event.target.ownerDocument, new AnchorBox(this._x, this._y, 0, 0));
-    } else {
-      InspectorFrontendHost.showContextMenuAtPoint(this._x, this._y, menuObject, this._event.target.ownerDocument);
-
-      /**
-       * @this {UI.ContextMenu}
-       */
-      function listenToEvents() {
-        InspectorFrontendHost.events.addEventListener(
-            InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this);
-        InspectorFrontendHost.events.addEventListener(
-            InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this);
-      }
-
-      // showContextMenuAtPoint call above synchronously issues a clear event for previous context menu (if any),
-      // so we skip it before subscribing to the clear event.
-      setImmediate(listenToEvents.bind(this));
-    }
-  }
-
-  /**
-   * @param {number} id
-   * @param {function(?)} handler
-   */
-  _setHandler(id, handler) {
-    if (handler)
-      this._handlers[id] = handler;
-  }
-
-  /**
-   * @return {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>}
-   */
-  _buildMenuDescriptors() {
-    return /** @type {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} */ (super._buildDescriptor().subItems);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onItemSelected(event) {
-    this._itemSelected(/** @type {string} */ (event.data));
-  }
-
-  /**
-   * @param {string} id
-   */
-  _itemSelected(id) {
-    if (this._handlers[id])
-      this._handlers[id].call(this);
-    this._menuCleared();
-  }
-
-  _menuCleared() {
-    InspectorFrontendHost.events.removeEventListener(
-        InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this);
-    InspectorFrontendHost.events.removeEventListener(
-        InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this);
-  }
-
-  /**
-   * @param {!Object} target
-   */
-  appendApplicableItems(target) {
-    this._pendingPromises.push(self.runtime.allInstances(UI.ContextMenu.Provider, target));
-    this._pendingTargets.push(target);
-  }
-};
-
-UI.ContextMenu._groupWeights =
-    ['header', 'new', 'reveal', 'edit', 'clipboard', 'debug', 'view', 'default', 'save', 'footer'];
-
-/**
- * @interface
- */
-UI.ContextMenu.Provider = function() {};
-
-UI.ContextMenu.Provider.prototype = {
-  /**
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {}
-};
diff --git a/front_end/ui/Dialog.js b/front_end/ui/Dialog.js
deleted file mode 100644
index ee18e27..0000000
--- a/front_end/ui/Dialog.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-UI.Dialog = class extends UI.GlassPane {
-  constructor() {
-    super();
-    this.registerRequiredCSS('ui/dialog.css');
-    this.contentElement.tabIndex = 0;
-    this.contentElement.addEventListener('focus', () => this.widget().focus(), false);
-    this.contentElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    this.widget().setDefaultFocusedElement(this.contentElement);
-    this.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-    this.setOutsideClickCallback(event => {
-      this.hide();
-      event.consume(true);
-    });
-    /** @type {!Map<!HTMLElement, number>} */
-    this._tabIndexMap = new Map();
-    /** @type {?UI.WidgetFocusRestorer} */
-    this._focusRestorer = null;
-    this._closeOnEscape = true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  static hasInstance() {
-    return !!UI.Dialog._instance;
-  }
-
-  /**
-   * @override
-   * @param {!Document|!Element=} where
-   */
-  show(where) {
-    const document = /** @type {!Document} */ (
-        where instanceof Document ? where : (where || UI.inspectorView.element).ownerDocument);
-    if (UI.Dialog._instance)
-      UI.Dialog._instance.hide();
-    UI.Dialog._instance = this;
-    this._disableTabIndexOnElements(document);
-    super.show(document);
-    this._focusRestorer = new UI.WidgetFocusRestorer(this.widget());
-  }
-
-  /**
-   * @override
-   */
-  hide() {
-    this._focusRestorer.restore();
-    super.hide();
-    this._restoreTabIndexOnElements();
-    delete UI.Dialog._instance;
-  }
-
-  /**
-   * @param {boolean} close
-   */
-  setCloseOnEscape(close) {
-    this._closeOnEscape = close;
-  }
-
-  addCloseButton() {
-    const closeButton = this.contentElement.createChild('div', 'dialog-close-button', 'dt-close-button');
-    closeButton.gray = true;
-    closeButton.addEventListener('click', () => this.hide(), false);
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  _disableTabIndexOnElements(document) {
-    this._tabIndexMap.clear();
-    for (let node = document; node; node = node.traverseNextNode(document)) {
-      if (node instanceof HTMLElement) {
-        const element = /** @type {!HTMLElement} */ (node);
-        const tabIndex = element.tabIndex;
-        if (tabIndex >= 0) {
-          this._tabIndexMap.set(element, tabIndex);
-          element.tabIndex = -1;
-        }
-      }
-    }
-  }
-
-  _restoreTabIndexOnElements() {
-    for (const element of this._tabIndexMap.keys())
-      element.tabIndex = /** @type {number} */ (this._tabIndexMap.get(element));
-    this._tabIndexMap.clear();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (this._closeOnEscape && event.keyCode === UI.KeyboardShortcut.Keys.Esc.code) {
-      event.consume(true);
-      this.hide();
-    }
-  }
-};
diff --git a/front_end/ui/DropTarget.js b/front_end/ui/DropTarget.js
deleted file mode 100644
index cb6c616..0000000
--- a/front_end/ui/DropTarget.js
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.DropTarget = class {
-  /**
-   * @param {!Element} element
-   * @param {!Array<{kind: string, type: !RegExp}>} transferTypes
-   * @param {string} messageText
-   * @param {function(!DataTransfer)} handleDrop
-   */
-  constructor(element, transferTypes, messageText, handleDrop) {
-    element.addEventListener('dragenter', this._onDragEnter.bind(this), true);
-    element.addEventListener('dragover', this._onDragOver.bind(this), true);
-    this._element = element;
-    this._transferTypes = transferTypes;
-    this._messageText = messageText;
-    this._handleDrop = handleDrop;
-    this._enabled = true;
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._enabled = enabled;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDragEnter(event) {
-    if (this._enabled && this._hasMatchingType(event))
-      event.consume(true);
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _hasMatchingType(event) {
-    for (const transferType of this._transferTypes) {
-      const found = Array.from(event.dataTransfer.items).find(item => {
-        return transferType.kind === item.kind && !!transferType.type.exec(item.type);
-      });
-      if (found)
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDragOver(event) {
-    if (!this._enabled || !this._hasMatchingType(event))
-      return;
-    event.dataTransfer.dropEffect = 'copy';
-    event.consume(true);
-    if (this._dragMaskElement)
-      return;
-    this._dragMaskElement = this._element.createChild('div', '');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this._dragMaskElement, 'ui/dropTarget.css');
-    shadowRoot.createChild('div', 'drop-target-message').textContent = this._messageText;
-    this._dragMaskElement.addEventListener('drop', this._onDrop.bind(this), true);
-    this._dragMaskElement.addEventListener('dragleave', this._onDragLeave.bind(this), true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDrop(event) {
-    event.consume(true);
-    this._removeMask();
-    if (this._enabled)
-      this._handleDrop(event.dataTransfer);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDragLeave(event) {
-    event.consume(true);
-    this._removeMask();
-  }
-
-  _removeMask() {
-    this._dragMaskElement.remove();
-    delete this._dragMaskElement;
-  }
-};
-
-UI.DropTarget.Type = {
-  URI: {kind: 'string', type: /text\/uri-list/},
-  Folder: {kind: 'file', type: /$^/},
-  File: {kind: 'file', type: /.*/},
-  WebFile: {kind: 'file', type: /[\w]+/},
-  ImageFile: {kind: 'file', type: /image\/.*/},
-};
diff --git a/front_end/ui/EmptyWidget.js b/front_end/ui/EmptyWidget.js
deleted file mode 100644
index c35c254..0000000
--- a/front_end/ui/EmptyWidget.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.EmptyWidget = class extends UI.VBox {
-  /**
-   * @param {string} text
-   */
-  constructor(text) {
-    super();
-    this.registerRequiredCSS('ui/emptyWidget.css');
-    this.element.classList.add('empty-view-scroller');
-    this._contentElement = this.element.createChild('div', 'empty-view');
-    this._textElement = this._contentElement.createChild('h2');
-    this._textElement.textContent = text;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  appendParagraph() {
-    return this._contentElement.createChild('p');
-  }
-
-  /**
-   * @param {string} text
-   */
-  set text(text) {
-    this._textElement.textContent = text;
-  }
-};
diff --git a/front_end/ui/FilterBar.js b/front_end/ui/FilterBar.js
deleted file mode 100644
index 2cbea28..0000000
--- a/front_end/ui/FilterBar.js
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.FilterBar = class extends UI.HBox {
-  /**
-   * @param {string} name
-   * @param {boolean=} visibleByDefault
-   */
-  constructor(name, visibleByDefault) {
-    super();
-    this.registerRequiredCSS('ui/filter.css');
-    this._enabled = true;
-    this.element.classList.add('filter-bar');
-
-    this._stateSetting = Common.settings.createSetting('filterBar-' + name + '-toggled', !!visibleByDefault);
-    this._filterButton = new UI.ToolbarSettingToggle(this._stateSetting, 'largeicon-filter', Common.UIString('Filter'));
-
-    this._filters = [];
-
-    this._updateFilterBar();
-    this._stateSetting.addChangeListener(this._updateFilterBar.bind(this));
-  }
-
-  /**
-   * @return {!UI.ToolbarButton}
-   */
-  filterButton() {
-    return this._filterButton;
-  }
-
-  /**
-   * @param {!UI.FilterUI} filter
-   */
-  addFilter(filter) {
-    this._filters.push(filter);
-    this.element.appendChild(filter.element());
-    filter.addEventListener(UI.FilterUI.Events.FilterChanged, this._filterChanged, this);
-    this._updateFilterButton();
-  }
-
-  setEnabled(enabled) {
-    this._enabled = enabled;
-    this._filterButton.setEnabled(enabled);
-    this._updateFilterBar();
-  }
-
-  forceShowFilterBar() {
-    this._alwaysShowFilters = true;
-    this._updateFilterBar();
-  }
-
-  showOnce() {
-    this._stateSetting.set(true);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _filterChanged(event) {
-    this._updateFilterButton();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._updateFilterBar();
-  }
-
-  _updateFilterBar() {
-    if (!this.parentWidget() || this._showingWidget)
-      return;
-    if (this.visible()) {
-      this._showingWidget = true;
-      this.showWidget();
-      this._showingWidget = false;
-    } else {
-      this.hideWidget();
-    }
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    for (let i = 0; i < this._filters.length; ++i) {
-      if (this._filters[i] instanceof UI.TextFilterUI) {
-        const textFilterUI = /** @type {!UI.TextFilterUI} */ (this._filters[i]);
-        textFilterUI.focus();
-        break;
-      }
-    }
-  }
-
-  _updateFilterButton() {
-    let isActive = false;
-    for (const filter of this._filters)
-      isActive = isActive || filter.isActive();
-    this._filterButton.setDefaultWithRedColor(isActive);
-    this._filterButton.setToggleWithRedColor(isActive);
-  }
-
-  clear() {
-    this.element.removeChildren();
-    this._filters = [];
-    this._updateFilterButton();
-  }
-
-  setting() {
-    return this._stateSetting;
-  }
-
-  visible() {
-    return this._alwaysShowFilters || (this._stateSetting.get() && this._enabled);
-  }
-};
-
-/**
- * @interface
- * @extends {Common.EventTarget}
- */
-UI.FilterUI = function() {};
-
-/** @enum {symbol} */
-UI.FilterUI.Events = {
-  FilterChanged: Symbol('FilterChanged')
-};
-
-UI.FilterUI.prototype = {
-  /**
-   * @return {boolean}
-   */
-  isActive() {},
-
-  /**
-   * @return {!Element}
-   */
-  element() {}
-};
-
-/**
- * @implements {UI.FilterUI}
- * @unrestricted
- */
-UI.TextFilterUI = class extends Common.Object {
-  constructor() {
-    super();
-    this._filterElement = createElement('div');
-    this._filterElement.className = 'filter-text-filter';
-
-    this._filterInputElement = this._filterElement.createChild('span', 'filter-input-field');
-
-    this._prompt = new UI.TextPrompt();
-    this._prompt.initialize(this._completions.bind(this), ' ');
-    this._proxyElement = this._prompt.attach(this._filterInputElement);
-    this._proxyElement.title = Common.UIString('e.g. /small[\\d]+/ url:a.com/b');
-    this._prompt.setPlaceholder(Common.UIString('Filter'));
-    this._prompt.addEventListener(UI.TextPrompt.Events.TextChanged, this._valueChanged.bind(this));
-
-    /** @type {?function(string, string, boolean=):!Promise<!UI.SuggestBox.Suggestions>} */
-    this._suggestionProvider = null;
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} prefix
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  _completions(expression, prefix, force) {
-    if (this._suggestionProvider)
-      return this._suggestionProvider(expression, prefix, force);
-    return Promise.resolve([]);
-  }
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isActive() {
-    return !!this._prompt.text();
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  element() {
-    return this._filterElement;
-  }
-
-  /**
-   * @return {string}
-   */
-  value() {
-    return this._prompt.textWithCurrentSuggestion();
-  }
-
-  /**
-   * @param {string} value
-   */
-  setValue(value) {
-    this._prompt.setText(value);
-    this._valueChanged();
-  }
-
-  focus() {
-    this._filterInputElement.focus();
-  }
-
-  /**
-   * @param {(function(string, string, boolean=):!Promise<!UI.SuggestBox.Suggestions>)} suggestionProvider
-   */
-  setSuggestionProvider(suggestionProvider) {
-    this._prompt.clearAutocomplete();
-    this._suggestionProvider = suggestionProvider;
-  }
-
-  _valueChanged() {
-    this.dispatchEventToListeners(UI.FilterUI.Events.FilterChanged, null);
-  }
-};
-
-/**
- * @implements {UI.FilterUI}
- * @unrestricted
- */
-UI.NamedBitSetFilterUI = class extends Common.Object {
-  /**
-   * @param {!Array.<!UI.NamedBitSetFilterUI.Item>} items
-   * @param {!Common.Setting=} setting
-   */
-  constructor(items, setting) {
-    super();
-    this._filtersElement = createElementWithClass('div', 'filter-bitset-filter');
-    this._filtersElement.title = Common.UIString(
-        '%sClick to select multiple types',
-        UI.KeyboardShortcut.shortcutToString('', UI.KeyboardShortcut.Modifiers.CtrlOrMeta));
-
-    this._allowedTypes = {};
-    this._typeFilterElements = {};
-    this._addBit(UI.NamedBitSetFilterUI.ALL_TYPES, Common.UIString('All'));
-    this._filtersElement.createChild('div', 'filter-bitset-filter-divider');
-
-    for (let i = 0; i < items.length; ++i)
-      this._addBit(items[i].name, items[i].label, items[i].title);
-
-    if (setting) {
-      this._setting = setting;
-      setting.addChangeListener(this._settingChanged.bind(this));
-      this._settingChanged();
-    } else {
-      this._toggleTypeFilter(UI.NamedBitSetFilterUI.ALL_TYPES, false /* allowMultiSelect */);
-    }
-  }
-
-  reset() {
-    this._toggleTypeFilter(UI.NamedBitSetFilterUI.ALL_TYPES, false /* allowMultiSelect */);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isActive() {
-    return !this._allowedTypes[UI.NamedBitSetFilterUI.ALL_TYPES];
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  element() {
-    return this._filtersElement;
-  }
-
-  /**
-   * @param {string} typeName
-   * @return {boolean}
-   */
-  accept(typeName) {
-    return !!this._allowedTypes[UI.NamedBitSetFilterUI.ALL_TYPES] || !!this._allowedTypes[typeName];
-  }
-
-  _settingChanged() {
-    const allowedTypes = this._setting.get();
-    this._allowedTypes = {};
-    for (const typeName in this._typeFilterElements) {
-      if (allowedTypes[typeName])
-        this._allowedTypes[typeName] = true;
-    }
-    this._update();
-  }
-
-  _update() {
-    if ((Object.keys(this._allowedTypes).length === 0) || this._allowedTypes[UI.NamedBitSetFilterUI.ALL_TYPES]) {
-      this._allowedTypes = {};
-      this._allowedTypes[UI.NamedBitSetFilterUI.ALL_TYPES] = true;
-    }
-    for (const typeName in this._typeFilterElements)
-      this._typeFilterElements[typeName].classList.toggle('selected', this._allowedTypes[typeName]);
-    this.dispatchEventToListeners(UI.FilterUI.Events.FilterChanged, null);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} label
-   * @param {string=} title
-   */
-  _addBit(name, label, title) {
-    const typeFilterElement = this._filtersElement.createChild('li', name);
-    typeFilterElement.typeName = name;
-    typeFilterElement.createTextChild(label);
-    if (title)
-      typeFilterElement.title = title;
-    typeFilterElement.addEventListener('click', this._onTypeFilterClicked.bind(this), false);
-    this._typeFilterElements[name] = typeFilterElement;
-  }
-
-  /**
-   * @param {!Event} e
-   */
-  _onTypeFilterClicked(e) {
-    let toggle;
-    if (Host.isMac())
-      toggle = e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey;
-    else
-      toggle = e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey;
-    this._toggleTypeFilter(e.target.typeName, toggle);
-  }
-
-  /**
-   * @param {string} typeName
-   * @param {boolean} allowMultiSelect
-   */
-  _toggleTypeFilter(typeName, allowMultiSelect) {
-    if (allowMultiSelect && typeName !== UI.NamedBitSetFilterUI.ALL_TYPES)
-      this._allowedTypes[UI.NamedBitSetFilterUI.ALL_TYPES] = false;
-    else
-      this._allowedTypes = {};
-
-    this._allowedTypes[typeName] = !this._allowedTypes[typeName];
-
-    if (this._setting)
-      this._setting.set(this._allowedTypes);
-    else
-      this._update();
-  }
-};
-
-/** @typedef {{name: string, label: string, title: (string|undefined)}} */
-UI.NamedBitSetFilterUI.Item;
-
-UI.NamedBitSetFilterUI.ALL_TYPES = 'all';
-
-/**
- * @implements {UI.FilterUI}
- * @unrestricted
- */
-UI.CheckboxFilterUI = class extends Common.Object {
-  /**
-   * @param {string} className
-   * @param {string} title
-   * @param {boolean=} activeWhenChecked
-   * @param {!Common.Setting=} setting
-   */
-  constructor(className, title, activeWhenChecked, setting) {
-    super();
-    this._filterElement = createElementWithClass('div', 'filter-checkbox-filter');
-    this._activeWhenChecked = !!activeWhenChecked;
-    this._label = UI.CheckboxLabel.create(title);
-    this._filterElement.appendChild(this._label);
-    this._checkboxElement = this._label.checkboxElement;
-    if (setting)
-      UI.SettingsUI.bindCheckbox(this._checkboxElement, setting);
-    else
-      this._checkboxElement.checked = true;
-    this._checkboxElement.addEventListener('change', this._fireUpdated.bind(this), false);
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isActive() {
-    return this._activeWhenChecked === this._checkboxElement.checked;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  checked() {
-    return this._checkboxElement.checked;
-  }
-
-  /**
-   * @param {boolean} checked
-   */
-  setChecked(checked) {
-    this._checkboxElement.checked = checked;
-  }
-
-  /**
-   * @override
-   * @return {!Element}
-   */
-  element() {
-    return this._filterElement;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  labelElement() {
-    return this._label;
-  }
-
-  _fireUpdated() {
-    this.dispatchEventToListeners(UI.FilterUI.Events.FilterChanged, null);
-  }
-
-  /**
-   * @param {string} backgroundColor
-   * @param {string} borderColor
-   */
-  setColor(backgroundColor, borderColor) {
-    this._label.backgroundColor = backgroundColor;
-    this._label.borderColor = borderColor;
-  }
-};
diff --git a/front_end/ui/FilterSuggestionBuilder.js b/front_end/ui/FilterSuggestionBuilder.js
deleted file mode 100644
index 9551ba2..0000000
--- a/front_end/ui/FilterSuggestionBuilder.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.FilterSuggestionBuilder = class {
-  /**
-   * @param {!Array<string>} keys
-   * @param {function(string, !Array<string>)=} valueSorter
-   */
-  constructor(keys, valueSorter) {
-    this._keys = keys;
-    this._valueSorter = valueSorter || ((key, result) => result.sort());
-    /** @type {!Map<string, !Set<string>>} */
-    this._valuesMap = new Map();
-  }
-
-  /**
-   * @param {string} expression
-   * @param {string} prefix
-   * @param {boolean=} force
-   * @return {!Promise<!UI.SuggestBox.Suggestions>}
-   */
-  completions(expression, prefix, force) {
-    if (!prefix && !force)
-      return Promise.resolve([]);
-
-    const negative = prefix.startsWith('-');
-    if (negative)
-      prefix = prefix.substring(1);
-    const modifier = negative ? '-' : '';
-    const valueDelimiterIndex = prefix.indexOf(':');
-
-    const suggestions = [];
-    if (valueDelimiterIndex === -1) {
-      const matcher = new RegExp('^' + prefix.escapeForRegExp(), 'i');
-      for (const key of this._keys) {
-        if (matcher.test(key))
-          suggestions.push({text: modifier + key + ':'});
-      }
-    } else {
-      const key = prefix.substring(0, valueDelimiterIndex).toLowerCase();
-      const value = prefix.substring(valueDelimiterIndex + 1);
-      const matcher = new RegExp('^' + value.escapeForRegExp(), 'i');
-      const values = Array.from(this._valuesMap.get(key) || new Set());
-      this._valueSorter(key, values);
-      for (const item of values) {
-        if (matcher.test(item) && (item !== value))
-          suggestions.push({text: modifier + key + ':' + item});
-      }
-    }
-    return Promise.resolve(suggestions);
-  }
-
-  /**
-   * @param {string} key
-   * @param {?string=} value
-   */
-  addItem(key, value) {
-    if (!value)
-      return;
-
-    if (!this._valuesMap.get(key))
-      this._valuesMap.set(key, /** @type {!Set<string>} */ (new Set()));
-    this._valuesMap.get(key).add(value);
-  }
-
-  clear() {
-    this._valuesMap.clear();
-  }
-};
diff --git a/front_end/ui/ForwardedInputEventHandler.js b/front_end/ui/ForwardedInputEventHandler.js
deleted file mode 100644
index 6baa49a..0000000
--- a/front_end/ui/ForwardedInputEventHandler.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ForwardedInputEventHandler = class {
-  constructor() {
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.KeyEventUnhandled, this._onKeyEventUnhandled, this);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onKeyEventUnhandled(event) {
-    const data = event.data;
-    const type = /** @type {string} */ (data.type);
-    const key = /** @type {string} */ (data.key);
-    const keyCode = /** @type {number} */ (data.keyCode);
-    const modifiers = /** @type {number} */ (data.modifiers);
-
-    if (type !== 'keydown')
-      return;
-
-    UI.context.setFlavor(UI.ShortcutRegistry.ForwardedShortcut, UI.ShortcutRegistry.ForwardedShortcut.instance);
-    UI.shortcutRegistry.handleKey(UI.KeyboardShortcut.makeKey(keyCode, modifiers), key);
-    UI.context.setFlavor(UI.ShortcutRegistry.ForwardedShortcut, null);
-  }
-};
-
-/** @type {!UI.ForwardedInputEventHandler} */
-UI.forwardedEventHandler = new UI.ForwardedInputEventHandler();
diff --git a/front_end/ui/Fragment.js b/front_end/ui/Fragment.js
deleted file mode 100644
index d30df1e..0000000
--- a/front_end/ui/Fragment.js
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.Fragment = class {
-  /**
-   * @param {!Element} element
-   */
-  constructor(element) {
-    this._element = element;
-
-    /** @type {!Map<string, !Array<!UI.Fragment._State>>} */
-    this._states = new Map();
-
-    /** @type {!Map<string, !Element>} */
-    this._elementsById = new Map();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  element() {
-    return this._element;
-  }
-
-  /**
-   * @param {string} elementId
-   * @return {!Element}
-   */
-  $(elementId) {
-    return this._elementsById.get(elementId);
-  }
-
-  /**
-   * @param {string} name
-   * @param {boolean} toggled
-   */
-  setState(name, toggled) {
-    const list = this._states.get(name);
-    if (list === undefined) {
-      console.error('Unknown state ' + name);
-      return;
-    }
-    for (const state of list) {
-      if (state.toggled === toggled)
-        continue;
-      state.toggled = toggled;
-      const value = state.attributeValue;
-      state.attributeValue = state.element.getAttribute(state.attributeName);
-      if (value === null)
-        state.element.removeAttribute(state.attributeName);
-      else
-        state.element.setAttribute(state.attributeName, value);
-    }
-  }
-
-  /**
-   * @param {!Array<string>} strings
-   * @param {...*} vararg
-   * @return {!UI.Fragment}
-   */
-  static build(strings, vararg) {
-    const values = Array.prototype.slice.call(arguments, 1);
-    return UI.Fragment._render(UI.Fragment._template(strings), values);
-  }
-
-  /**
-   * @param {!Array<string>} strings
-   * @param {...*} vararg
-   * @return {!UI.Fragment}
-   */
-  static cached(strings, vararg) {
-    const values = Array.prototype.slice.call(arguments, 1);
-    let template = UI.Fragment._templateCache.get(strings);
-    if (!template) {
-      template = UI.Fragment._template(strings);
-      UI.Fragment._templateCache.set(strings, template);
-    }
-    return UI.Fragment._render(template, values);
-  }
-
-  /**
-   * @param {!Array<string>} strings
-   * @return {!UI.Fragment._Template}
-   * @suppressGlobalPropertiesCheck
-   */
-  static _template(strings) {
-    let html = '';
-    let insideText = false;
-    for (let i = 0; i < strings.length - 1; i++) {
-      html += strings[i];
-      const close = strings[i].lastIndexOf('>');
-      if (close !== -1) {
-        if (strings[i].indexOf('<', close + 1) === -1)
-          insideText = true;
-        else
-          insideText = false;
-      }
-      html += insideText ? UI.Fragment._textMarker : UI.Fragment._attributeMarker(i);
-    }
-    html += strings[strings.length - 1];
-
-    const template = window.document.createElement('template');
-    template.innerHTML = html;
-    const walker = template.ownerDocument.createTreeWalker(
-        template.content, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, null, false);
-    let valueIndex = 0;
-    const emptyTextNodes = [];
-    const binds = [];
-    const nodesToMark = [];
-    while (walker.nextNode()) {
-      const node = walker.currentNode;
-      if (node.nodeType === Node.ELEMENT_NODE && node.hasAttributes()) {
-        if (node.hasAttribute('$')) {
-          nodesToMark.push(node);
-          binds.push({elementId: node.getAttribute('$')});
-          node.removeAttribute('$');
-        }
-
-        const attributesToRemove = [];
-        for (let i = 0; i < node.attributes.length; i++) {
-          let name = node.attributes[i].name;
-
-          if (name.startsWith('s-')) {
-            attributesToRemove.push(name);
-            name = name.substring(2);
-            const state = name.substring(0, name.indexOf('-'));
-            const attr = name.substring(state.length + 1);
-            nodesToMark.push(node);
-            binds.push({state: {name: state, attribute: attr, value: node.attributes[i].value}});
-            continue;
-          }
-
-          if (!UI.Fragment._attributeMarkerRegex.test(name) &&
-              !UI.Fragment._attributeMarkerRegex.test(node.attributes[i].value))
-            continue;
-
-          attributesToRemove.push(name);
-          nodesToMark.push(node);
-          const bind = {attr: {index: valueIndex}};
-          bind.attr.names = name.split(UI.Fragment._attributeMarkerRegex);
-          valueIndex += bind.attr.names.length - 1;
-          bind.attr.values = node.attributes[i].value.split(UI.Fragment._attributeMarkerRegex);
-          valueIndex += bind.attr.values.length - 1;
-          binds.push(bind);
-        }
-        for (let i = 0; i < attributesToRemove.length; i++)
-          node.removeAttribute(attributesToRemove[i]);
-      }
-
-      if (node.nodeType === Node.TEXT_NODE && node.data.indexOf(UI.Fragment._textMarker) !== -1) {
-        const texts = node.data.split(UI.Fragment._textMarkerRegex);
-        node.data = texts[texts.length - 1];
-        for (let i = 0; i < texts.length - 1; i++) {
-          if (texts[i])
-            node.parentNode.insertBefore(createTextNode(texts[i]), node);
-          const nodeToReplace = createElement('span');
-          nodesToMark.push(nodeToReplace);
-          binds.push({replaceNodeIndex: valueIndex++});
-          node.parentNode.insertBefore(nodeToReplace, node);
-        }
-      }
-
-      if (node.nodeType === Node.TEXT_NODE &&
-          (!node.previousSibling || node.previousSibling.nodeType === Node.ELEMENT_NODE) &&
-          (!node.nextSibling || node.nextSibling.nodeType === Node.ELEMENT_NODE) && /^\s*$/.test(node.data))
-        emptyTextNodes.push(node);
-    }
-
-    for (let i = 0; i < nodesToMark.length; i++)
-      nodesToMark[i].classList.add(UI.Fragment._class(i));
-
-    for (const emptyTextNode of emptyTextNodes)
-      emptyTextNode.remove();
-    return {template: template, binds: binds};
-  }
-
-  /**
-   * @param {!UI.Fragment._Template} template
-   * @param {!Array<*>} values
-   * @return {!UI.Fragment}
-   */
-  static _render(template, values) {
-    const content = template.template.ownerDocument.importNode(template.template.content, true);
-    const resultElement =
-        /** @type {!Element} */ (content.firstChild === content.lastChild ? content.firstChild : content);
-    const result = new UI.Fragment(resultElement);
-
-    const idByElement = new Map();
-    const boundElements = [];
-    for (let i = 0; i < template.binds.length; i++) {
-      const className = UI.Fragment._class(i);
-      const element = /** @type {!Element} */ (content.querySelector('.' + className));
-      element.classList.remove(className);
-      boundElements.push(element);
-    }
-
-    for (let bindIndex = 0; bindIndex < template.binds.length; bindIndex++) {
-      const bind = template.binds[bindIndex];
-      const element = boundElements[bindIndex];
-      if ('elementId' in bind) {
-        result._elementsById.set(/** @type {string} */ (bind.elementId), element);
-        idByElement.set(element, bind.elementId);
-      } else if ('replaceNodeIndex' in bind) {
-        const value = values[/** @type {number} */ (bind.replaceNodeIndex)];
-        let node = null;
-        if (value instanceof Node)
-          node = value;
-        else if (value instanceof UI.Fragment)
-          node = value._element;
-        else
-          node = createTextNode('' + value);
-
-        element.parentNode.insertBefore(node, element);
-        element.remove();
-      } else if ('state' in bind) {
-        const list = result._states.get(bind.state.name) || [];
-        list.push(
-            {attributeName: bind.state.attribute, attributeValue: bind.state.value, element: element, toggled: false});
-        result._states.set(bind.state.name, list);
-      } else if ('attr' in bind) {
-        if (bind.attr.names.length === 2 && bind.attr.values.length === 1 &&
-            typeof values[bind.attr.index] === 'function') {
-          values[bind.attr.index].call(null, element);
-        } else {
-          let name = bind.attr.names[0];
-          for (let i = 1; i < bind.attr.names.length; i++) {
-            name += values[bind.attr.index + i - 1];
-            name += bind.attr.names[i];
-          }
-          if (name) {
-            let value = bind.attr.values[0];
-            for (let i = 1; i < bind.attr.values.length; i++) {
-              value += values[bind.attr.index + bind.attr.names.length - 1 + i - 1];
-              value += bind.attr.values[i];
-            }
-            element.setAttribute(name, value);
-          }
-        }
-      } else {
-        throw 'Unexpected bind';
-      }
-    }
-
-    // We do this after binds so that querySelector works.
-    const shadows = result._element.querySelectorAll('x-shadow');
-    for (const shadow of shadows) {
-      if (!shadow.parentElement)
-        throw 'There must be a parent element here';
-      const shadowRoot = UI.createShadowRootWithCoreStyles(shadow.parentElement);
-      if (shadow.parentElement.tagName === 'X-WIDGET')
-        shadow.parentElement._shadowRoot = shadowRoot;
-      const children = [];
-      while (shadow.lastChild) {
-        children.push(shadow.lastChild);
-        shadow.lastChild.remove();
-      }
-      for (let i = children.length - 1; i >= 0; i--)
-        shadowRoot.appendChild(children[i]);
-      const id = idByElement.get(shadow);
-      if (id)
-        result._elementsById.set(id, /** @type {!Element} */ (/** @type {!Node} */ (shadowRoot)));
-      shadow.remove();
-    }
-
-    return result;
-  }
-};
-
-/**
- * @typedef {!{
- *   template: !Element,
- *   binds: !Array<!UI.Fragment._Bind>
- * }}
- */
-UI.Fragment._Template;
-
-/**
- * @typedef {!{
- *   attributeName: string,
- *   attributeValue: string,
- *   element: !Element,
- *   toggled: boolean
- * }}
- */
-UI.Fragment._State;
-
-/**
- * @typedef {!{
- *   elementId: (string|undefined),
- *
- *   state: (!{
- *     name: string,
- *     attribute: string,
- *     value: string
- *   }|undefined),
- *
- *   attr: (!{
- *     index: number,
- *     names: !Array<string>,
- *     values: !Array<string>
- *   }|undefined),
- *
- *   replaceNodeIndex: (number|undefined)
- * }}
- */
-UI.Fragment._Bind;
-
-UI.Fragment._textMarker = '{{template-text}}';
-UI.Fragment._textMarkerRegex = /{{template-text}}/;
-
-UI.Fragment._attributeMarker = index => 'template-attribute' + index;
-UI.Fragment._attributeMarkerRegex = /template-attribute\d+/;
-
-UI.Fragment._class = index => 'template-class-' + index;
-
-UI.Fragment._templateCache = new Map();
diff --git a/front_end/ui/Geometry.js b/front_end/ui/Geometry.js
deleted file mode 100644
index 4f5bf4a..0000000
--- a/front_end/ui/Geometry.js
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-UI.Geometry = {};
-
-/**
- * @type {number}
- */
-UI.Geometry._Eps = 1e-5;
-
-/**
- * @unrestricted
- */
-UI.Geometry.Vector = class {
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   */
-  constructor(x, y, z) {
-    this.x = x;
-    this.y = y;
-    this.z = z;
-  }
-
-  /**
-   * @return {number}
-   */
-  length() {
-    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
-  }
-
-  normalize() {
-    const length = this.length();
-    if (length <= UI.Geometry._Eps)
-      return;
-
-    this.x /= length;
-    this.y /= length;
-    this.z /= length;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.Geometry.Point = class {
-  /**
-   * @param {number} x
-   * @param {number} y
-   */
-  constructor(x, y) {
-    this.x = x;
-    this.y = y;
-  }
-
-  /**
-   * @param {!UI.Geometry.Point} p
-   * @return {number}
-   */
-  distanceTo(p) {
-    return Math.sqrt(Math.pow(p.x - this.x, 2) + Math.pow(p.y - this.y, 2));
-  }
-
-  /**
-   * @param {!UI.Geometry.Point} line
-   * @return {!UI.Geometry.Point}
-   */
-  projectOn(line) {
-    if (line.x === 0 && line.y === 0)
-      return new UI.Geometry.Point(0, 0);
-    return line.scale((this.x * line.x + this.y * line.y) / (Math.pow(line.x, 2) + Math.pow(line.y, 2)));
-  }
-
-  /**
-   * @param {number} scalar
-   * @return {!UI.Geometry.Point}
-   */
-  scale(scalar) {
-    return new UI.Geometry.Point(this.x * scalar, this.y * scalar);
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  toString() {
-    return Math.round(this.x * 100) / 100 + ', ' + Math.round(this.y * 100) / 100;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.Geometry.CubicBezier = class {
-  /**
-   * @param {!UI.Geometry.Point} point1
-   * @param {!UI.Geometry.Point} point2
-   */
-  constructor(point1, point2) {
-    this.controlPoints = [point1, point2];
-  }
-
-  /**
-   * @param {string} text
-   * @return {?UI.Geometry.CubicBezier}
-   */
-  static parse(text) {
-    const keywordValues = UI.Geometry.CubicBezier.KeywordValues;
-    const value = text.toLowerCase().replace(/\s+/g, '');
-    if (Object.keys(keywordValues).indexOf(value) !== -1)
-      return UI.Geometry.CubicBezier.parse(keywordValues[value]);
-    const bezierRegex = /^cubic-bezier\(([^,]+),([^,]+),([^,]+),([^,]+)\)$/;
-    const match = value.match(bezierRegex);
-    if (match) {
-      const control1 = new UI.Geometry.Point(parseFloat(match[1]), parseFloat(match[2]));
-      const control2 = new UI.Geometry.Point(parseFloat(match[3]), parseFloat(match[4]));
-      return new UI.Geometry.CubicBezier(control1, control2);
-    }
-    return null;
-  }
-
-  /**
-   * @param {number} t
-   * @return {!UI.Geometry.Point}
-   */
-  evaluateAt(t) {
-    /**
-     * @param {number} v1
-     * @param {number} v2
-     * @param {number} t
-     */
-    function evaluate(v1, v2, t) {
-      return 3 * (1 - t) * (1 - t) * t * v1 + 3 * (1 - t) * t * t * v2 + Math.pow(t, 3);
-    }
-
-    const x = evaluate(this.controlPoints[0].x, this.controlPoints[1].x, t);
-    const y = evaluate(this.controlPoints[0].y, this.controlPoints[1].y, t);
-    return new UI.Geometry.Point(x, y);
-  }
-
-  /**
-   * @return {string}
-   */
-  asCSSText() {
-    const raw = 'cubic-bezier(' + this.controlPoints.join(', ') + ')';
-    const keywordValues = UI.Geometry.CubicBezier.KeywordValues;
-    for (const keyword in keywordValues) {
-      if (raw === keywordValues[keyword])
-        return keyword;
-    }
-    return raw;
-  }
-};
-
-/** @type {!RegExp} */
-UI.Geometry.CubicBezier.Regex = /((cubic-bezier\([^)]+\))|\b(linear|ease-in-out|ease-in|ease-out|ease)\b)/g;
-
-UI.Geometry.CubicBezier.KeywordValues = {
-  'linear': 'cubic-bezier(0, 0, 1, 1)',
-  'ease': 'cubic-bezier(0.25, 0.1, 0.25, 1)',
-  'ease-in': 'cubic-bezier(0.42, 0, 1, 1)',
-  'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1)',
-  'ease-out': 'cubic-bezier(0, 0, 0.58, 1)'
-};
-
-
-/**
- * @unrestricted
- */
-UI.Geometry.EulerAngles = class {
-  /**
-   * @param {number} alpha
-   * @param {number} beta
-   * @param {number} gamma
-   */
-  constructor(alpha, beta, gamma) {
-    this.alpha = alpha;
-    this.beta = beta;
-    this.gamma = gamma;
-  }
-
-  /**
-   * @param {!CSSMatrix} rotationMatrix
-   * @return {!UI.Geometry.EulerAngles}
-   */
-  static fromRotationMatrix(rotationMatrix) {
-    const beta = Math.atan2(rotationMatrix.m23, rotationMatrix.m33);
-    const gamma = Math.atan2(
-        -rotationMatrix.m13,
-        Math.sqrt(rotationMatrix.m11 * rotationMatrix.m11 + rotationMatrix.m12 * rotationMatrix.m12));
-    const alpha = Math.atan2(rotationMatrix.m12, rotationMatrix.m11);
-    return new UI.Geometry.EulerAngles(
-        UI.Geometry.radiansToDegrees(alpha), UI.Geometry.radiansToDegrees(beta), UI.Geometry.radiansToDegrees(gamma));
-  }
-
-  /**
-   * @return {string}
-   */
-  toRotate3DString() {
-    const gammaAxisY = -Math.sin(UI.Geometry.degreesToRadians(this.beta));
-    const gammaAxisZ = Math.cos(UI.Geometry.degreesToRadians(this.beta));
-    const axis = {alpha: [0, 1, 0], beta: [-1, 0, 0], gamma: [0, gammaAxisY, gammaAxisZ]};
-    return 'rotate3d(' + axis.alpha.join(',') + ',' + this.alpha + 'deg) ' +
-        'rotate3d(' + axis.beta.join(',') + ',' + this.beta + 'deg) ' +
-        'rotate3d(' + axis.gamma.join(',') + ',' + this.gamma + 'deg)';
-  }
-};
-
-
-/**
- * @param {!UI.Geometry.Vector} u
- * @param {!UI.Geometry.Vector} v
- * @return {number}
- */
-UI.Geometry.scalarProduct = function(u, v) {
-  return u.x * v.x + u.y * v.y + u.z * v.z;
-};
-
-/**
- * @param {!UI.Geometry.Vector} u
- * @param {!UI.Geometry.Vector} v
- * @return {!UI.Geometry.Vector}
- */
-UI.Geometry.crossProduct = function(u, v) {
-  const x = u.y * v.z - u.z * v.y;
-  const y = u.z * v.x - u.x * v.z;
-  const z = u.x * v.y - u.y * v.x;
-  return new UI.Geometry.Vector(x, y, z);
-};
-
-/**
- * @param {!UI.Geometry.Vector} u
- * @param {!UI.Geometry.Vector} v
- * @return {!UI.Geometry.Vector}
- */
-UI.Geometry.subtract = function(u, v) {
-  const x = u.x - v.x;
-  const y = u.y - v.y;
-  const z = u.z - v.z;
-  return new UI.Geometry.Vector(x, y, z);
-};
-
-/**
- * @param {!UI.Geometry.Vector} v
- * @param {!CSSMatrix} m
- * @return {!UI.Geometry.Vector}
- */
-UI.Geometry.multiplyVectorByMatrixAndNormalize = function(v, m) {
-  const t = v.x * m.m14 + v.y * m.m24 + v.z * m.m34 + m.m44;
-  const x = (v.x * m.m11 + v.y * m.m21 + v.z * m.m31 + m.m41) / t;
-  const y = (v.x * m.m12 + v.y * m.m22 + v.z * m.m32 + m.m42) / t;
-  const z = (v.x * m.m13 + v.y * m.m23 + v.z * m.m33 + m.m43) / t;
-  return new UI.Geometry.Vector(x, y, z);
-};
-
-/**
- * @param {!UI.Geometry.Vector} u
- * @param {!UI.Geometry.Vector} v
- * @return {number}
- */
-UI.Geometry.calculateAngle = function(u, v) {
-  const uLength = u.length();
-  const vLength = v.length();
-  if (uLength <= UI.Geometry._Eps || vLength <= UI.Geometry._Eps)
-    return 0;
-  const cos = UI.Geometry.scalarProduct(u, v) / uLength / vLength;
-  if (Math.abs(cos) > 1)
-    return 0;
-  return UI.Geometry.radiansToDegrees(Math.acos(cos));
-};
-
-/**
- * @param {number} deg
- * @return {number}
- */
-UI.Geometry.degreesToRadians = function(deg) {
-  return deg * Math.PI / 180;
-};
-
-/**
- * @param {number} rad
- * @return {number}
- */
-UI.Geometry.radiansToDegrees = function(rad) {
-  return rad * 180 / Math.PI;
-};
-
-/**
- * @param {!CSSMatrix} matrix
- * @param {!Array.<number>} points
- * @param {{minX: number, maxX: number, minY: number, maxY: number}=} aggregateBounds
- * @return {!{minX: number, maxX: number, minY: number, maxY: number}}
- */
-UI.Geometry.boundsForTransformedPoints = function(matrix, points, aggregateBounds) {
-  if (!aggregateBounds)
-    aggregateBounds = {minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity};
-  if (points.length % 3)
-    console.assert('Invalid size of points array');
-  for (let p = 0; p < points.length; p += 3) {
-    let vector = new UI.Geometry.Vector(points[p], points[p + 1], points[p + 2]);
-    vector = UI.Geometry.multiplyVectorByMatrixAndNormalize(vector, matrix);
-    aggregateBounds.minX = Math.min(aggregateBounds.minX, vector.x);
-    aggregateBounds.maxX = Math.max(aggregateBounds.maxX, vector.x);
-    aggregateBounds.minY = Math.min(aggregateBounds.minY, vector.y);
-    aggregateBounds.maxY = Math.max(aggregateBounds.maxY, vector.y);
-  }
-  return aggregateBounds;
-};
-
-/**
- * @unrestricted
- */
-UI.Size = class {
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  constructor(width, height) {
-    this.width = width;
-    this.height = height;
-  }
-
-  /**
-   * @param {?UI.Size} size
-   * @return {!UI.Size}
-   */
-  clipTo(size) {
-    if (!size)
-      return this;
-    return new UI.Size(Math.min(this.width, size.width), Math.min(this.height, size.height));
-  }
-
-  /**
-   * @param {number} scale
-   * @return {!UI.Size}
-   */
-  scale(scale) {
-    return new UI.Size(this.width * scale, this.height * scale);
-  }
-};
-
-/**
- * @param {?UI.Size} size
- * @return {boolean}
- */
-UI.Size.prototype.isEqual = function(size) {
-  return !!size && this.width === size.width && this.height === size.height;
-};
-
-/**
- * @param {!UI.Size|number} size
- * @return {!UI.Size}
- */
-UI.Size.prototype.widthToMax = function(size) {
-  return new UI.Size(Math.max(this.width, (typeof size === 'number' ? size : size.width)), this.height);
-};
-
-/**
- * @param {!UI.Size|number} size
- * @return {!UI.Size}
- */
-UI.Size.prototype.addWidth = function(size) {
-  return new UI.Size(this.width + (typeof size === 'number' ? size : size.width), this.height);
-};
-
-/**
- * @param {!UI.Size|number} size
- * @return {!UI.Size}
- */
-UI.Size.prototype.heightToMax = function(size) {
-  return new UI.Size(this.width, Math.max(this.height, (typeof size === 'number' ? size : size.height)));
-};
-
-/**
- * @param {!UI.Size|number} size
- * @return {!UI.Size}
- */
-UI.Size.prototype.addHeight = function(size) {
-  return new UI.Size(this.width, this.height + (typeof size === 'number' ? size : size.height));
-};
-
-/**
- * @unrestricted
- */
-UI.Insets = class {
-  /**
-   * @param {number} left
-   * @param {number} top
-   * @param {number} right
-   * @param {number} bottom
-   */
-  constructor(left, top, right, bottom) {
-    this.left = left;
-    this.top = top;
-    this.right = right;
-    this.bottom = bottom;
-  }
-
-  /**
-   * @param {?UI.Insets} insets
-   * @return {boolean}
-   */
-  isEqual(insets) {
-    return !!insets && this.left === insets.left && this.top === insets.top && this.right === insets.right &&
-        this.bottom === insets.bottom;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.Rect = class {
-  /**
-   * @param {number} left
-   * @param {number} top
-   * @param {number} width
-   * @param {number} height
-   */
-  constructor(left, top, width, height) {
-    this.left = left;
-    this.top = top;
-    this.width = width;
-    this.height = height;
-  }
-
-  /**
-   * @param {?UI.Rect} rect
-   * @return {boolean}
-   */
-  isEqual(rect) {
-    return !!rect && this.left === rect.left && this.top === rect.top && this.width === rect.width &&
-        this.height === rect.height;
-  }
-
-  /**
-   * @param {number} scale
-   * @return {!UI.Rect}
-   */
-  scale(scale) {
-    return new UI.Rect(this.left * scale, this.top * scale, this.width * scale, this.height * scale);
-  }
-
-  /**
-   * @return {!UI.Size}
-   */
-  size() {
-    return new UI.Size(this.width, this.height);
-  }
-
-  /**
-   * @param {!UI.Rect} origin
-   * @return {!UI.Rect}
-   */
-  relativeTo(origin) {
-    return new UI.Rect(this.left - origin.left, this.top - origin.top, this.width, this.height);
-  }
-
-  /**
-   * @param {!UI.Rect} origin
-   * @return {!UI.Rect}
-   */
-  rebaseTo(origin) {
-    return new UI.Rect(this.left + origin.left, this.top + origin.top, this.width, this.height);
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.Constraints = class {
-  /**
-   * @param {!UI.Size=} minimum
-   * @param {?UI.Size=} preferred
-   */
-  constructor(minimum, preferred) {
-    /**
-     * @type {!UI.Size}
-     */
-    this.minimum = minimum || new UI.Size(0, 0);
-
-    /**
-     * @type {!UI.Size}
-     */
-    this.preferred = preferred || this.minimum;
-
-    if (this.minimum.width > this.preferred.width || this.minimum.height > this.preferred.height)
-      throw new Error('Minimum size is greater than preferred.');
-  }
-};
-
-/**
- * @param {?UI.Constraints} constraints
- * @return {boolean}
- */
-UI.Constraints.prototype.isEqual = function(constraints) {
-  return !!constraints && this.minimum.isEqual(constraints.minimum) && this.preferred.isEqual(constraints.preferred);
-};
-
-/**
- * @param {!UI.Constraints|number} value
- * @return {!UI.Constraints}
- */
-UI.Constraints.prototype.widthToMax = function(value) {
-  if (typeof value === 'number')
-    return new UI.Constraints(this.minimum.widthToMax(value), this.preferred.widthToMax(value));
-  return new UI.Constraints(this.minimum.widthToMax(value.minimum), this.preferred.widthToMax(value.preferred));
-};
-
-/**
- * @param {!UI.Constraints|number} value
- * @return {!UI.Constraints}
- */
-UI.Constraints.prototype.addWidth = function(value) {
-  if (typeof value === 'number')
-    return new UI.Constraints(this.minimum.addWidth(value), this.preferred.addWidth(value));
-  return new UI.Constraints(this.minimum.addWidth(value.minimum), this.preferred.addWidth(value.preferred));
-};
-
-/**
- * @param {!UI.Constraints|number} value
- * @return {!UI.Constraints}
- */
-UI.Constraints.prototype.heightToMax = function(value) {
-  if (typeof value === 'number')
-    return new UI.Constraints(this.minimum.heightToMax(value), this.preferred.heightToMax(value));
-  return new UI.Constraints(this.minimum.heightToMax(value.minimum), this.preferred.heightToMax(value.preferred));
-};
-
-/**
- * @param {!UI.Constraints|number} value
- * @return {!UI.Constraints}
- */
-UI.Constraints.prototype.addHeight = function(value) {
-  if (typeof value === 'number')
-    return new UI.Constraints(this.minimum.addHeight(value), this.preferred.addHeight(value));
-  return new UI.Constraints(this.minimum.addHeight(value.minimum), this.preferred.addHeight(value.preferred));
-};
diff --git a/front_end/ui/GlassPane.js b/front_end/ui/GlassPane.js
deleted file mode 100644
index 8cd1925..0000000
--- a/front_end/ui/GlassPane.js
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.GlassPane = class {
-  constructor() {
-    this._widget = new UI.Widget(true);
-    this._widget.markAsRoot();
-    this.element = this._widget.element;
-    this.contentElement = this._widget.contentElement;
-    this._arrowElement = UI.Icon.create('', 'arrow hidden');
-    this.element.shadowRoot.appendChild(this._arrowElement);
-
-    this.registerRequiredCSS('ui/glassPane.css');
-    this.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.PierceGlassPane);
-
-    this._onMouseDownBound = this._onMouseDown.bind(this);
-    /** @type {?function(!Event)} */
-    this._onClickOutsideCallback = null;
-    /** @type {?UI.Size} */
-    this._maxSize = null;
-    /** @type {?number} */
-    this._positionX = null;
-    /** @type {?number} */
-    this._positionY = null;
-    /** @type {?AnchorBox} */
-    this._anchorBox = null;
-    this._anchorBehavior = UI.GlassPane.AnchorBehavior.PreferTop;
-    this._sizeBehavior = UI.GlassPane.SizeBehavior.SetExactSize;
-    this._marginBehavior = UI.GlassPane.MarginBehavior.DefaultMargin;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShowing() {
-    return this._widget.isShowing();
-  }
-
-  /**
-   * @param {string} cssFile
-   */
-  registerRequiredCSS(cssFile) {
-    this._widget.registerRequiredCSS(cssFile);
-  }
-
-  /**
-   * @param {?Element} element
-   */
-  setDefaultFocusedElement(element) {
-    this._widget.setDefaultFocusedElement(element);
-  }
-
-  /**
-   * @param {boolean} dimmed
-   */
-  setDimmed(dimmed) {
-    this.element.classList.toggle('dimmed-pane', dimmed);
-  }
-
-  /**
-   * @param {!UI.GlassPane.PointerEventsBehavior} pointerEventsBehavior
-   */
-  setPointerEventsBehavior(pointerEventsBehavior) {
-    this.element.classList.toggle(
-        'no-pointer-events', pointerEventsBehavior !== UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-    this.contentElement.classList.toggle(
-        'no-pointer-events', pointerEventsBehavior === UI.GlassPane.PointerEventsBehavior.PierceContents);
-  }
-
-  /**
-   * @param {?function(!Event)} callback
-   */
-  setOutsideClickCallback(callback) {
-    this._onClickOutsideCallback = callback;
-  }
-
-  /**
-   * @param {?UI.Size} size
-   */
-  setMaxContentSize(size) {
-    this._maxSize = size;
-    this._positionContent();
-  }
-
-  /**
-   * @param {!UI.GlassPane.SizeBehavior} sizeBehavior
-   */
-  setSizeBehavior(sizeBehavior) {
-    this._sizeBehavior = sizeBehavior;
-    this._positionContent();
-  }
-
-  /**
-   * @param {?number} x
-   * @param {?number} y
-   * Position is relative to root element.
-   */
-  setContentPosition(x, y) {
-    this._positionX = x;
-    this._positionY = y;
-    this._positionContent();
-  }
-
-  /**
-   * @param {?AnchorBox} anchorBox
-   * Anchor box is relative to the document.
-   */
-  setContentAnchorBox(anchorBox) {
-    this._anchorBox = anchorBox;
-    this._positionContent();
-  }
-
-  /**
-   * @param {!UI.GlassPane.AnchorBehavior} behavior
-   */
-  setAnchorBehavior(behavior) {
-    this._anchorBehavior = behavior;
-  }
-
-  /**
-   * @param {boolean} behavior
-   */
-  setMarginBehavior(behavior) {
-    this._marginBehavior = behavior;
-    this._arrowElement.classList.toggle('hidden', behavior !== UI.GlassPane.MarginBehavior.Arrow);
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  show(document) {
-    if (this.isShowing())
-      return;
-    // Deliberately starts with 3000 to hide other z-indexed elements below.
-    this.element.style.zIndex = 3000 + 1000 * UI.GlassPane._panes.size;
-    document.body.addEventListener('mousedown', this._onMouseDownBound, true);
-    this._widget.show(document.body);
-    UI.GlassPane._panes.add(this);
-    this._positionContent();
-  }
-
-  hide() {
-    if (!this.isShowing())
-      return;
-    UI.GlassPane._panes.delete(this);
-    this.element.ownerDocument.body.removeEventListener('mousedown', this._onMouseDownBound, true);
-    this._widget.detach();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onMouseDown(event) {
-    if (!this._onClickOutsideCallback)
-      return;
-    const node = event.deepElementFromPoint();
-    if (!node || this.contentElement.isSelfOrAncestor(node))
-      return;
-    this._onClickOutsideCallback.call(null, event);
-  }
-
-  _positionContent() {
-    if (!this.isShowing())
-      return;
-
-    const showArrow = this._marginBehavior === UI.GlassPane.MarginBehavior.Arrow;
-    const gutterSize = showArrow ? 8 : (this._marginBehavior === UI.GlassPane.MarginBehavior.NoMargin ? 0 : 3);
-    const scrollbarSize = UI.measuredScrollbarWidth(this.element.ownerDocument);
-    const arrowSize = 10;
-
-    const container = UI.GlassPane._containers.get(/** @type {!Document} */ (this.element.ownerDocument));
-    if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) {
-      this.contentElement.positionAt(0, 0);
-      this.contentElement.style.width = '';
-      this.contentElement.style.maxWidth = '';
-      this.contentElement.style.height = '';
-      this.contentElement.style.maxHeight = '';
-    }
-
-    const containerWidth = container.offsetWidth;
-    const containerHeight = container.offsetHeight;
-
-    let width = containerWidth - gutterSize * 2;
-    let height = containerHeight - gutterSize * 2;
-    let positionX = gutterSize;
-    let positionY = gutterSize;
-
-    if (this._maxSize) {
-      width = Math.min(width, this._maxSize.width);
-      height = Math.min(height, this._maxSize.height);
-    }
-
-    if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) {
-      const measuredWidth = this.contentElement.offsetWidth;
-      const measuredHeight = this.contentElement.offsetHeight;
-      const widthOverflow = height < measuredHeight ? scrollbarSize : 0;
-      const heightOverflow = width < measuredWidth ? scrollbarSize : 0;
-      width = Math.min(width, measuredWidth + widthOverflow);
-      height = Math.min(height, measuredHeight + heightOverflow);
-    }
-
-    if (this._anchorBox) {
-      const anchorBox = this._anchorBox.relativeToElement(container);
-      let behavior = this._anchorBehavior;
-      this._arrowElement.classList.remove('arrow-none', 'arrow-top', 'arrow-bottom', 'arrow-left', 'arrow-right');
-
-      if (behavior === UI.GlassPane.AnchorBehavior.PreferTop || behavior === UI.GlassPane.AnchorBehavior.PreferBottom) {
-        const top = anchorBox.y - 2 * gutterSize;
-        const bottom = containerHeight - anchorBox.y - anchorBox.height - 2 * gutterSize;
-        if (behavior === UI.GlassPane.AnchorBehavior.PreferTop && top < height && bottom > top)
-          behavior = UI.GlassPane.AnchorBehavior.PreferBottom;
-        if (behavior === UI.GlassPane.AnchorBehavior.PreferBottom && bottom < height && top > bottom)
-          behavior = UI.GlassPane.AnchorBehavior.PreferTop;
-
-        let arrowY;
-        let enoughHeight = true;
-        if (behavior === UI.GlassPane.AnchorBehavior.PreferTop) {
-          positionY = Math.max(gutterSize, anchorBox.y - height - gutterSize);
-          const spaceTop = anchorBox.y - positionY - gutterSize;
-          if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) {
-            if (height > spaceTop) {
-              this._arrowElement.classList.add('arrow-none');
-              enoughHeight = false;
-            }
-          } else {
-            height = Math.min(height, spaceTop);
-          }
-          this._arrowElement.setIconType('mediumicon-arrow-bottom');
-          this._arrowElement.classList.add('arrow-bottom');
-          arrowY = anchorBox.y - gutterSize;
-        } else {
-          positionY = anchorBox.y + anchorBox.height + gutterSize;
-          const spaceBottom = containerHeight - positionY - gutterSize;
-          if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) {
-            if (height > spaceBottom) {
-              this._arrowElement.classList.add('arrow-none');
-              positionY = containerHeight - gutterSize - height;
-              enoughHeight = false;
-            }
-          } else {
-            height = Math.min(height, spaceBottom);
-          }
-          this._arrowElement.setIconType('mediumicon-arrow-top');
-          this._arrowElement.classList.add('arrow-top');
-          arrowY = anchorBox.y + anchorBox.height + gutterSize;
-        }
-
-        positionX = Math.max(gutterSize, Math.min(anchorBox.x, containerWidth - width - gutterSize));
-        if (!enoughHeight)
-          positionX = Math.min(positionX + arrowSize, containerWidth - width - gutterSize);
-        else if (showArrow && positionX - arrowSize >= gutterSize)
-          positionX -= arrowSize;
-        width = Math.min(width, containerWidth - positionX - gutterSize);
-        if (2 * arrowSize >= width) {
-          this._arrowElement.classList.add('arrow-none');
-        } else {
-          let arrowX = anchorBox.x + Math.min(50, Math.floor(anchorBox.width / 2));
-          arrowX = Number.constrain(arrowX, positionX + arrowSize, positionX + width - arrowSize);
-          this._arrowElement.positionAt(arrowX, arrowY, container);
-        }
-      } else {
-        const left = anchorBox.x - 2 * gutterSize;
-        const right = containerWidth - anchorBox.x - anchorBox.width - 2 * gutterSize;
-        if (behavior === UI.GlassPane.AnchorBehavior.PreferLeft && left < width && right > left)
-          behavior = UI.GlassPane.AnchorBehavior.PreferRight;
-        if (behavior === UI.GlassPane.AnchorBehavior.PreferRight && right < width && left > right)
-          behavior = UI.GlassPane.AnchorBehavior.PreferLeft;
-
-        let arrowX;
-        let enoughWidth = true;
-        if (behavior === UI.GlassPane.AnchorBehavior.PreferLeft) {
-          positionX = Math.max(gutterSize, anchorBox.x - width - gutterSize);
-          const spaceLeft = anchorBox.x - positionX - gutterSize;
-          if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) {
-            if (width > spaceLeft) {
-              this._arrowElement.classList.add('arrow-none');
-              enoughWidth = false;
-            }
-          } else {
-            width = Math.min(width, spaceLeft);
-          }
-          this._arrowElement.setIconType('mediumicon-arrow-right');
-          this._arrowElement.classList.add('arrow-right');
-          arrowX = anchorBox.x - gutterSize;
-        } else {
-          positionX = anchorBox.x + anchorBox.width + gutterSize;
-          const spaceRight = containerWidth - positionX - gutterSize;
-          if (this._sizeBehavior === UI.GlassPane.SizeBehavior.MeasureContent) {
-            if (width > spaceRight) {
-              this._arrowElement.classList.add('arrow-none');
-              positionX = containerWidth - gutterSize - width;
-              enoughWidth = false;
-            }
-          } else {
-            width = Math.min(width, spaceRight);
-          }
-          this._arrowElement.setIconType('mediumicon-arrow-left');
-          this._arrowElement.classList.add('arrow-left');
-          arrowX = anchorBox.x + anchorBox.width + gutterSize;
-        }
-
-        positionY = Math.max(gutterSize, Math.min(anchorBox.y, containerHeight - height - gutterSize));
-        if (!enoughWidth)
-          positionY = Math.min(positionY + arrowSize, containerHeight - height - gutterSize);
-        else if (showArrow && positionY - arrowSize >= gutterSize)
-          positionY -= arrowSize;
-        height = Math.min(height, containerHeight - positionY - gutterSize);
-        if (2 * arrowSize >= height) {
-          this._arrowElement.classList.add('arrow-none');
-        } else {
-          let arrowY = anchorBox.y + Math.min(50, Math.floor(anchorBox.height / 2));
-          arrowY = Number.constrain(arrowY, positionY + arrowSize, positionY + height - arrowSize);
-          this._arrowElement.positionAt(arrowX, arrowY, container);
-        }
-      }
-    } else {
-      positionX = this._positionX !== null ? this._positionX : (containerWidth - width) / 2;
-      positionY = this._positionY !== null ? this._positionY : (containerHeight - height) / 2;
-      width = Math.min(width, containerWidth - positionX - gutterSize);
-      height = Math.min(height, containerHeight - positionY - gutterSize);
-      this._arrowElement.classList.add('arrow-none');
-    }
-
-    this.contentElement.style.width = width + 'px';
-    if (this._sizeBehavior === UI.GlassPane.SizeBehavior.SetExactWidthMaxHeight)
-      this.contentElement.style.maxHeight = height + 'px';
-    else
-      this.contentElement.style.height = height + 'px';
-
-    this.contentElement.positionAt(positionX, positionY, container);
-    this._widget.doResize();
-  }
-
-  /**
-   * @protected
-   * @return {!UI.Widget}
-   */
-  widget() {
-    return this._widget;
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  static setContainer(element) {
-    UI.GlassPane._containers.set(/** @type {!Document} */ (element.ownerDocument), element);
-    UI.GlassPane.containerMoved(element);
-  }
-
-  /**
-   * @param {!Document} document
-   * @return {!Element}
-   */
-  static container(document) {
-    return UI.GlassPane._containers.get(document);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  static containerMoved(element) {
-    for (const pane of UI.GlassPane._panes) {
-      if (pane.isShowing() && pane.element.ownerDocument === element.ownerDocument)
-        pane._positionContent();
-    }
-  }
-};
-
-/** @enum {symbol} */
-UI.GlassPane.PointerEventsBehavior = {
-  BlockedByGlassPane: Symbol('BlockedByGlassPane'),
-  PierceGlassPane: Symbol('PierceGlassPane'),
-  PierceContents: Symbol('PierceContents')
-};
-
-/** @enum {symbol} */
-UI.GlassPane.AnchorBehavior = {
-  PreferTop: Symbol('PreferTop'),
-  PreferBottom: Symbol('PreferBottom'),
-  PreferLeft: Symbol('PreferLeft'),
-  PreferRight: Symbol('PreferRight'),
-};
-
-/** @enum {symbol} */
-UI.GlassPane.SizeBehavior = {
-  SetExactSize: Symbol('SetExactSize'),
-  SetExactWidthMaxHeight: Symbol('SetExactWidthMaxHeight'),
-  MeasureContent: Symbol('MeasureContent')
-};
-
-/** @enum {symbol} */
-UI.GlassPane.MarginBehavior = {
-  Arrow: Symbol('Arrow'),
-  DefaultMargin: Symbol('DefaultMargin'),
-  NoMargin: Symbol('NoMargin')
-};
-
-/** @type {!Map<!Document, !Element>} */
-UI.GlassPane._containers = new Map();
-/** @type {!Set<!UI.GlassPane>} */
-UI.GlassPane._panes = new Set();
diff --git a/front_end/ui/HistoryInput.js b/front_end/ui/HistoryInput.js
deleted file mode 100644
index b5cefa7..0000000
--- a/front_end/ui/HistoryInput.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.HistoryInput = class extends HTMLInputElement {
-  /**
-   * @return {!UI.HistoryInput}
-   */
-  static create() {
-    if (!UI.HistoryInput._constructor)
-      UI.HistoryInput._constructor = UI.registerCustomElement('input', 'history-input', UI.HistoryInput.prototype);
-
-    return /** @type {!UI.HistoryInput} */ (new UI.HistoryInput._constructor());
-  }
-
-  /**
-   * @override
-   */
-  createdCallback() {
-    this._history = [''];
-    this._historyPosition = 0;
-    this.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    this.addEventListener('input', this._onInput.bind(this), false);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onInput(event) {
-    if (this._history.length === this._historyPosition + 1)
-      this._history[this._history.length - 1] = this.value;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    if (event.keyCode === UI.KeyboardShortcut.Keys.Up.code) {
-      this._historyPosition = Math.max(this._historyPosition - 1, 0);
-      this.value = this._history[this._historyPosition];
-      this.dispatchEvent(new Event('input', {'bubbles': true, 'cancelable': true}));
-      event.consume(true);
-    } else if (event.keyCode === UI.KeyboardShortcut.Keys.Down.code) {
-      this._historyPosition = Math.min(this._historyPosition + 1, this._history.length - 1);
-      this.value = this._history[this._historyPosition];
-      this.dispatchEvent(new Event('input', {'bubbles': true, 'cancelable': true}));
-      event.consume(true);
-    } else if (event.keyCode === UI.KeyboardShortcut.Keys.Enter.code) {
-      this._saveToHistory();
-    }
-  }
-
-  _saveToHistory() {
-    if (this._history.length > 1 && this._history[this._history.length - 2] === this.value)
-      return;
-    this._history[this._history.length - 1] = this.value;
-    this._historyPosition = this._history.length - 1;
-    this._history.push('');
-  }
-};
diff --git a/front_end/ui/Icon.js b/front_end/ui/Icon.js
deleted file mode 100644
index 9ba57c8..0000000
--- a/front_end/ui/Icon.js
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @constructor
- * @extends {HTMLSpanElement}
- */
-UI.Icon = class extends HTMLSpanElement {
-  constructor() {
-    super();
-    throw new Error('icon must be created via factory method.');
-  }
-
-  /**
-   * @param {string=} iconType
-   * @param {string=} className
-   * @return {!UI.Icon}
-   */
-  static create(iconType, className) {
-    if (!UI.Icon._constructor)
-      UI.Icon._constructor = UI.registerCustomElement('span', 'ui-icon', UI.Icon.prototype);
-
-    const icon = /** @type {!UI.Icon} */ (new UI.Icon._constructor());
-    if (className)
-      icon.className = className;
-    if (iconType)
-      icon.setIconType(iconType);
-    return icon;
-  }
-
-  /**
-   * @override
-   */
-  createdCallback() {
-    /** @type {?UI.Icon.Descriptor} */
-    this._descriptor = null;
-    /** @type {?UI.Icon.SpriteSheet} */
-    this._spriteSheet = null;
-    /** @type {string} */
-    this._iconType = '';
-  }
-
-  /**
-   * @param {string} iconType
-   */
-  setIconType(iconType) {
-    if (this._descriptor) {
-      this.style.removeProperty('--spritesheet-position');
-      this.style.removeProperty('width');
-      this.style.removeProperty('height');
-      this._toggleClasses(false);
-      this._iconType = '';
-      this._descriptor = null;
-      this._spriteSheet = null;
-    }
-    const descriptor = UI.Icon.Descriptors[iconType] || null;
-    if (descriptor) {
-      this._iconType = iconType;
-      this._descriptor = descriptor;
-      this._spriteSheet = UI.Icon.SpriteSheets[this._descriptor.spritesheet];
-      console.assert(
-          this._spriteSheet, `ERROR: icon ${this._iconType} has unknown spritesheet: ${this._descriptor.spritesheet}`);
-
-      this.style.setProperty('--spritesheet-position', this._propertyValue());
-      this.style.setProperty('width', this._spriteSheet.cellWidth + 'px');
-      this.style.setProperty('height', this._spriteSheet.cellHeight + 'px');
-      this._toggleClasses(true);
-    } else if (iconType) {
-      throw new Error(`ERROR: failed to find icon descriptor for type: ${iconType}`);
-    }
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  _toggleClasses(value) {
-    this.classList.toggle('spritesheet-' + this._descriptor.spritesheet, value);
-    this.classList.toggle(this._iconType, value);
-    this.classList.toggle('icon-mask', value && !!this._descriptor.isMask);
-    this.classList.toggle('icon-invert', value && !!this._descriptor.invert);
-  }
-
-  /**
-   * @return {string}
-   */
-  _propertyValue() {
-    if (!this._descriptor.coordinates) {
-      if (!this._descriptor.position || !UI.Icon._positionRegex.test(this._descriptor.position))
-        throw new Error(`ERROR: icon '${this._iconType}' has malformed position: '${this._descriptor.position}'`);
-      const column = this._descriptor.position[0].toLowerCase().charCodeAt(0) - 97;
-      const row = parseInt(this._descriptor.position.substring(1), 10) - 1;
-      this._descriptor.coordinates = {
-        x: -(this._spriteSheet.cellWidth + this._spriteSheet.padding) * column,
-        y: (this._spriteSheet.cellHeight + this._spriteSheet.padding) * (row + 1) - this._spriteSheet.padding
-      };
-    }
-    return `${this._descriptor.coordinates.x}px ${this._descriptor.coordinates.y}px`;
-  }
-};
-
-UI.Icon._positionRegex = /^[a-z][1-9][0-9]*$/;
-
-/** @typedef {{position: string, spritesheet: string, isMask: (boolean|undefined)}} */
-UI.Icon.Descriptor;
-
-/** @typedef {{cellWidth: number, cellHeight: number, padding: number}} */
-UI.Icon.SpriteSheet;
-
-/** @enum {!UI.Icon.SpriteSheet} */
-UI.Icon.SpriteSheets = {
-  'smallicons': {cellWidth: 10, cellHeight: 10, padding: 10},
-  'mediumicons': {cellWidth: 16, cellHeight: 16, padding: 0},
-  'largeicons': {cellWidth: 28, cellHeight: 24, padding: 0},
-  'arrowicons': {cellWidth: 19, cellHeight: 19, padding: 0}
-};
-
-/** @enum {!UI.Icon.Descriptor} */
-UI.Icon.Descriptors = {
-  'smallicon-bezier': {position: 'a5', spritesheet: 'smallicons', isMask: true},
-  'smallicon-checkmark': {position: 'b5', spritesheet: 'smallicons'},
-  'smallicon-checkmark-square': {position: 'b6', spritesheet: 'smallicons', isMask: true},
-  'smallicon-checkmark-behind': {position: 'd6', spritesheet: 'smallicons', isMask: true},
-  'smallicon-command-result': {position: 'a4', spritesheet: 'smallicons'},
-  'smallicon-contrast-ratio': {position: 'a6', spritesheet: 'smallicons', isMask: true},
-  'smallicon-cross': {position: 'b4', spritesheet: 'smallicons'},
-  'smallicon-device': {position: 'c5', spritesheet: 'smallicons'},
-  'smallicon-error': {position: 'c4', spritesheet: 'smallicons'},
-  'smallicon-expand-less': {position: 'f5', spritesheet: 'smallicons', isMask: true},
-  'smallicon-expand-more': {position: 'e6', spritesheet: 'smallicons', isMask: true},
-  'smallicon-green-arrow': {position: 'a3', spritesheet: 'smallicons'},
-  'smallicon-green-ball': {position: 'b3', spritesheet: 'smallicons'},
-  'smallicon-info': {position: 'c3', spritesheet: 'smallicons'},
-  'smallicon-inline-breakpoint-conditional': {position: 'd4', spritesheet: 'smallicons'},
-  'smallicon-inline-breakpoint': {position: 'd5', spritesheet: 'smallicons'},
-  'smallicon-no': {position: 'c6', spritesheet: 'smallicons', isMask: true},
-  'smallicon-orange-ball': {position: 'd3', spritesheet: 'smallicons'},
-  'smallicon-red-ball': {position: 'a2', spritesheet: 'smallicons'},
-  'smallicon-shadow': {position: 'b2', spritesheet: 'smallicons', isMask: true},
-  'smallicon-step-in': {position: 'c2', spritesheet: 'smallicons'},
-  'smallicon-step-out': {position: 'd2', spritesheet: 'smallicons'},
-  'smallicon-text-prompt': {position: 'e5', spritesheet: 'smallicons'},
-  'smallicon-thick-left-arrow': {position: 'e4', spritesheet: 'smallicons'},
-  'smallicon-thick-right-arrow': {position: 'e3', spritesheet: 'smallicons'},
-  'smallicon-triangle-down': {position: 'e2', spritesheet: 'smallicons', isMask: true},
-  'smallicon-triangle-right': {position: 'a1', spritesheet: 'smallicons', isMask: true},
-  'smallicon-triangle-up': {position: 'b1', spritesheet: 'smallicons', isMask: true},
-  'smallicon-user-command': {position: 'c1', spritesheet: 'smallicons'},
-  'smallicon-warning': {position: 'd1', spritesheet: 'smallicons'},
-  'smallicon-network-product': {position: 'e1', spritesheet: 'smallicons'},
-  'smallicon-clear-warning': {position: 'f1', spritesheet: 'smallicons', isMask: true},
-  'smallicon-clear-info': {position: 'f2', spritesheet: 'smallicons'},
-  'smallicon-clear-error': {position: 'f3', spritesheet: 'smallicons'},
-  'smallicon-account-circle': {position: 'f4', spritesheet: 'smallicons'},
-
-  'mediumicon-clear-storage': {position: 'a4', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-cookie': {position: 'b4', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-database': {position: 'c4', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-info': {position: 'c1', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-manifest': {position: 'd4', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-service-worker': {position: 'a3', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-table': {position: 'b3', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-arrow-in-circle': {position: 'c3', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-file-sync': {position: 'd3', spritesheet: 'mediumicons', invert: true},
-  'mediumicon-file': {position: 'a2', spritesheet: 'mediumicons', invert: true},
-  'mediumicon-gray-cross-active': {position: 'b2', spritesheet: 'mediumicons'},
-  'mediumicon-gray-cross-hover': {position: 'c2', spritesheet: 'mediumicons'},
-  'mediumicon-red-cross-active': {position: 'd2', spritesheet: 'mediumicons'},
-  'mediumicon-red-cross-hover': {position: 'a1', spritesheet: 'mediumicons'},
-  'mediumicon-search': {position: 'b1', spritesheet: 'mediumicons'},
-  'mediumicon-replace': {position: 'c5', spritesheet: 'mediumicons', isMask: true},
-  'mediumicon-account-circle': {position: 'e4', spritesheet: 'mediumicons'},
-  'mediumicon-warning-triangle': {position: 'e1', spritesheet: 'mediumicons'},
-  'mediumicon-error-circle': {position: 'e3', spritesheet: 'mediumicons'},
-  'mediumicon-info-circle': {position: 'e2', spritesheet: 'mediumicons'},
-  'mediumicon-bug': {position: 'd1', spritesheet: 'mediumicons'},
-  'mediumicon-list': {position: 'e5', spritesheet: 'mediumicons'},
-  'mediumicon-warning': {position: 'd5', spritesheet: 'mediumicons', isMask: true},
-
-  'badge-navigator-file-sync': {position: 'a9', spritesheet: 'largeicons'},
-  'largeicon-activate-breakpoints': {position: 'b9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-add': {position: 'a8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-background-color': {position: 'b8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-box-shadow': {position: 'a7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-camera': {position: 'b7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-center': {position: 'c9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-checkmark': {position: 'c8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-chevron': {position: 'c7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-clear': {position: 'a6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-copy': {position: 'b6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-deactivate-breakpoints': {position: 'c6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-delete': {position: 'd9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-dock-to-bottom': {position: 'd8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-dock-to-left': {position: 'd7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-dock-to-right': {position: 'd6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-download': {position: 'h6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-edit': {position: 'a5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-eyedropper': {position: 'b5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-filter': {position: 'c5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-foreground-color': {position: 'd5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-hide-bottom-sidebar': {position: 'e9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-hide-left-sidebar': {position: 'e8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-hide-right-sidebar': {position: 'e7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-hide-top-sidebar': {position: 'e6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-large-list': {position: 'e5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-layout-editor': {position: 'a4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-load': {position: 'h5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-longclick-triangle': {position: 'b4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-menu': {position: 'c4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-domain': {position: 'd4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-file': {position: 'e4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-file-sync': {position: 'f9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-folder': {position: 'f8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-frame': {position: 'f7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-snippet': {position: 'f6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-navigator-worker': {position: 'f5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-node-search': {position: 'f4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-pan': {position: 'a3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-pause-animation': {position: 'b3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-pause': {position: 'c3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-pause-on-exceptions': {position: 'd3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-phone': {position: 'e3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-play-animation': {position: 'f3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-play-back': {position: 'a2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-play': {position: 'b2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-pretty-print': {position: 'c2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-refresh': {position: 'd2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-replay-animation': {position: 'e2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-resume': {position: 'f2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-rotate': {position: 'g9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-rotate-screen': {position: 'g8', spritesheet: 'largeicons', isMask: true},
-  'largeicon-search': {position: 'h4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-settings-gear': {position: 'g7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-show-bottom-sidebar': {position: 'g6', spritesheet: 'largeicons', isMask: true},
-  'largeicon-show-left-sidebar': {position: 'g5', spritesheet: 'largeicons', isMask: true},
-  'largeicon-show-right-sidebar': {position: 'g4', spritesheet: 'largeicons', isMask: true},
-  'largeicon-show-top-sidebar': {position: 'g3', spritesheet: 'largeicons', isMask: true},
-  'largeicon-start-recording': {position: 'g2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-step-into': {position: 'a1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-step-out': {position: 'b1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-step-over': {position: 'c1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-step': {position: 'h1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-stop-recording': {position: 'd1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-terminate-execution': {position: 'h2', spritesheet: 'largeicons', isMask: true},
-  'largeicon-text-shadow': {position: 'e1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-trash-bin': {position: 'f1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-undo': {position: 'h7', spritesheet: 'largeicons', isMask: true},
-  'largeicon-undock': {position: 'g1', spritesheet: 'largeicons', isMask: true},
-  'largeicon-visibility': {position: 'h9', spritesheet: 'largeicons', isMask: true},
-  'largeicon-waterfall': {position: 'h8', spritesheet: 'largeicons', isMask: true},
-
-  'mediumicon-arrow-top': {position: 'a4', spritesheet: 'arrowicons'},
-  'mediumicon-arrow-bottom': {position: 'a3', spritesheet: 'arrowicons'},
-  'mediumicon-arrow-left': {position: 'a2', spritesheet: 'arrowicons'},
-  'mediumicon-arrow-right': {position: 'a1', spritesheet: 'arrowicons'}
-};
diff --git a/front_end/ui/Infobar.js b/front_end/ui/Infobar.js
deleted file mode 100644
index b6523a0..0000000
--- a/front_end/ui/Infobar.js
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.Infobar = class {
-  /**
-   * @param {!UI.Infobar.Type} type
-   * @param {string} text
-   * @param {!Common.Setting=} disableSetting
-   */
-  constructor(type, text, disableSetting) {
-    this.element = createElementWithClass('div', 'flex-none');
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/infobar.css');
-    this._contentElement = this._shadowRoot.createChild('div', 'infobar infobar-' + type);
-
-    this._mainRow = this._contentElement.createChild('div', 'infobar-main-row');
-    this._mainRow.createChild('div', type + '-icon icon');
-    this._mainRowText = this._mainRow.createChild('div', 'infobar-main-title');
-    this._mainRowText.textContent = text;
-    this._detailsRows = this._contentElement.createChild('div', 'infobar-details-rows hidden');
-
-    this._toggleElement = this._mainRow.createChild('div', 'infobar-toggle hidden');
-    this._toggleElement.addEventListener('click', this._onToggleDetails.bind(this), false);
-    this._toggleElement.textContent = Common.UIString('more');
-
-    /** @type {?Common.Setting} */
-    this._disableSetting = disableSetting || null;
-    if (disableSetting) {
-      const disableButton = this._mainRow.createChild('div', 'infobar-toggle');
-      disableButton.textContent = Common.UIString('never show');
-      disableButton.addEventListener('click', this._onDisable.bind(this), false);
-    }
-
-    this._closeButton = this._contentElement.createChild('div', 'close-button', 'dt-close-button');
-    this._closeButton.addEventListener('click', this.dispose.bind(this), false);
-
-    /** @type {?function()} */
-    this._closeCallback = null;
-  }
-
-  /**
-   * @param {!UI.Infobar.Type} type
-   * @param {string} text
-   * @param {!Common.Setting=} disableSetting
-   * @return {?UI.Infobar}
-   */
-  static create(type, text, disableSetting) {
-    if (disableSetting && disableSetting.get())
-      return null;
-    return new UI.Infobar(type, text, disableSetting);
-  }
-
-  dispose() {
-    this.element.remove();
-    this._onResize();
-    if (this._closeCallback)
-      this._closeCallback.call(null);
-  }
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {
-    this._mainRowText.textContent = text;
-    this._onResize();
-  }
-
-  /**
-   * @param {?function()} callback
-   */
-  setCloseCallback(callback) {
-    this._closeCallback = callback;
-  }
-
-  /**
-   * @param {!UI.Widget} parentView
-   */
-  setParentView(parentView) {
-    this._parentView = parentView;
-  }
-
-  _onResize() {
-    if (this._parentView)
-      this._parentView.doResize();
-  }
-
-  _onDisable() {
-    this._disableSetting.set(true);
-    this.dispose();
-  }
-
-  _onToggleDetails() {
-    this._detailsRows.classList.remove('hidden');
-    this._toggleElement.remove();
-    this._onResize();
-  }
-
-  /**
-   * @param {string=} message
-   * @return {!Element}
-   */
-  createDetailsRowMessage(message) {
-    this._toggleElement.classList.remove('hidden');
-    const infobarDetailsRow = this._detailsRows.createChild('div', 'infobar-details-row');
-    const detailsRowMessage = infobarDetailsRow.createChild('span', 'infobar-row-message');
-    detailsRowMessage.textContent = message || '';
-    return detailsRowMessage;
-  }
-};
-
-
-/** @enum {string} */
-UI.Infobar.Type = {
-  Warning: 'warning',
-  Info: 'info'
-};
diff --git a/front_end/ui/InplaceEditor.js b/front_end/ui/InplaceEditor.js
deleted file mode 100644
index ae2f538..0000000
--- a/front_end/ui/InplaceEditor.js
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.InplaceEditor = class {
-  /**
-   * @param {!Element} element
-   * @param {!UI.InplaceEditor.Config=} config
-   * @return {?UI.InplaceEditor.Controller}
-   */
-  static startEditing(element, config) {
-    if (!UI.InplaceEditor._defaultInstance)
-      UI.InplaceEditor._defaultInstance = new UI.InplaceEditor();
-    return UI.InplaceEditor._defaultInstance.startEditing(element, config);
-  }
-
-  /**
-   * @return {string}
-   */
-  editorContent(editingContext) {
-    const element = editingContext.element;
-    if (element.tagName === 'INPUT' && element.type === 'text')
-      return element.value;
-
-    return element.textContent;
-  }
-
-  setUpEditor(editingContext) {
-    const element = editingContext.element;
-    element.classList.add('editing');
-    element.setAttribute('contenteditable', 'plaintext-only');
-
-    const oldTabIndex = element.getAttribute('tabIndex');
-    if (typeof oldTabIndex !== 'number' || oldTabIndex < 0)
-      element.tabIndex = 0;
-    this._focusRestorer = new UI.ElementFocusRestorer(element);
-    editingContext.oldTabIndex = oldTabIndex;
-  }
-
-  closeEditor(editingContext) {
-    const element = editingContext.element;
-    element.classList.remove('editing');
-    element.removeAttribute('contenteditable');
-
-    if (typeof editingContext.oldTabIndex !== 'number')
-      element.removeAttribute('tabIndex');
-    else
-      element.tabIndex = editingContext.oldTabIndex;
-    element.scrollTop = 0;
-    element.scrollLeft = 0;
-  }
-
-  cancelEditing(editingContext) {
-    const element = editingContext.element;
-    if (element.tagName === 'INPUT' && element.type === 'text')
-      element.value = editingContext.oldText;
-    else
-      element.textContent = editingContext.oldText;
-  }
-
-  augmentEditingHandle(editingContext, handle) {
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {!UI.InplaceEditor.Config=} config
-   * @return {?UI.InplaceEditor.Controller}
-   */
-  startEditing(element, config) {
-    if (!UI.markBeingEdited(element, true))
-      return null;
-
-    config = config || new UI.InplaceEditor.Config(function() {}, function() {});
-    const editingContext = {element: element, config: config};
-    const committedCallback = config.commitHandler;
-    const cancelledCallback = config.cancelHandler;
-    const pasteCallback = config.pasteHandler;
-    const context = config.context;
-    let moveDirection = '';
-    const self = this;
-
-    this.setUpEditor(editingContext);
-
-    editingContext.oldText = this.editorContent(editingContext);
-
-    /**
-     * @param {!Event=} e
-     */
-    function blurEventListener(e) {
-      if (config.blurHandler && !config.blurHandler(element, e))
-        return;
-      editingCommitted.call(element);
-    }
-
-    function cleanUpAfterEditing() {
-      UI.markBeingEdited(element, false);
-
-      element.removeEventListener('blur', blurEventListener, false);
-      element.removeEventListener('keydown', keyDownEventListener, true);
-      if (pasteCallback)
-        element.removeEventListener('paste', pasteEventListener, true);
-
-      if (self._focusRestorer)
-        self._focusRestorer.restore();
-      self.closeEditor(editingContext);
-    }
-
-    /** @this {Element} */
-    function editingCancelled() {
-      self.cancelEditing(editingContext);
-      cleanUpAfterEditing();
-      cancelledCallback(this, context);
-    }
-
-    /** @this {Element} */
-    function editingCommitted() {
-      cleanUpAfterEditing();
-
-      committedCallback(this, self.editorContent(editingContext), editingContext.oldText, context, moveDirection);
-    }
-
-    /**
-     * @param {!Event} event
-     * @return {string}
-     */
-    function defaultFinishHandler(event) {
-      if (isEnterKey(event))
-        return 'commit';
-      else if (event.keyCode === UI.KeyboardShortcut.Keys.Esc.code || event.key === 'Escape')
-        return 'cancel';
-      else if (event.key === 'Tab')
-        return 'move-' + (event.shiftKey ? 'backward' : 'forward');
-      return '';
-    }
-
-    function handleEditingResult(result, event) {
-      if (result === 'commit') {
-        editingCommitted.call(element);
-        event.consume(true);
-      } else if (result === 'cancel') {
-        editingCancelled.call(element);
-        event.consume(true);
-      } else if (result && result.startsWith('move-')) {
-        moveDirection = result.substring(5);
-        if (event.key === 'Tab')
-          event.consume(true);
-        blurEventListener();
-      }
-    }
-
-    /**
-     * @param {!Event} event
-     */
-    function pasteEventListener(event) {
-      const result = pasteCallback(event);
-      handleEditingResult(result, event);
-    }
-
-    /**
-     * @param {!Event} event
-     */
-    function keyDownEventListener(event) {
-      let result = defaultFinishHandler(event);
-      if (!result && config.postKeydownFinishHandler)
-        result = config.postKeydownFinishHandler(event);
-      handleEditingResult(result, event);
-    }
-
-    element.addEventListener('blur', blurEventListener, false);
-    element.addEventListener('keydown', keyDownEventListener, true);
-    if (pasteCallback)
-      element.addEventListener('paste', pasteEventListener, true);
-
-    const handle = {cancel: editingCancelled.bind(element), commit: editingCommitted.bind(element)};
-    this.augmentEditingHandle(editingContext, handle);
-    return handle;
-  }
-};
-
-/**
- * @typedef {{cancel: function(), commit: function()}}
- */
-UI.InplaceEditor.Controller;
-
-
-/**
- * @template T
- * @unrestricted
- */
-UI.InplaceEditor.Config = class {
-  /**
-   * @param {function(!Element,string,string,T,string)} commitHandler
-   * @param {function(!Element,T)} cancelHandler
-   * @param {T=} context
-   * @param {function(!Element,!Event):boolean=} blurHandler
-   */
-  constructor(commitHandler, cancelHandler, context, blurHandler) {
-    this.commitHandler = commitHandler;
-    this.cancelHandler = cancelHandler;
-    this.context = context;
-    this.blurHandler = blurHandler;
-
-    /**
-     * @type {function(!Event):string|undefined}
-     */
-    this.pasteHandler;
-
-    /**
-     * @type {function(!Event):string|undefined}
-     */
-    this.postKeydownFinishHandler;
-  }
-
-  setPasteHandler(pasteHandler) {
-    this.pasteHandler = pasteHandler;
-  }
-
-  /**
-   * @param {function(!Event):string} postKeydownFinishHandler
-   */
-  setPostKeydownFinishHandler(postKeydownFinishHandler) {
-    this.postKeydownFinishHandler = postKeydownFinishHandler;
-  }
-};
diff --git a/front_end/ui/InspectorView.js b/front_end/ui/InspectorView.js
deleted file mode 100644
index 9a9202e..0000000
--- a/front_end/ui/InspectorView.js
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.ViewLocationResolver}
- * @unrestricted
- */
-UI.InspectorView = class extends UI.VBox {
-  constructor() {
-    super();
-    UI.GlassPane.setContainer(this.element);
-    this.setMinimumSize(240, 72);
-
-    // DevTools sidebar is a vertical split of panels tabbed pane and a drawer.
-    this._drawerSplitWidget = new UI.SplitWidget(false, true, 'Inspector.drawerSplitViewState', 200, 200);
-    this._drawerSplitWidget.hideSidebar();
-    this._drawerSplitWidget.hideDefaultResizer();
-    this._drawerSplitWidget.enableShowModeSaving();
-    this._drawerSplitWidget.show(this.element);
-
-    // Create drawer tabbed pane.
-    this._drawerTabbedLocation =
-        UI.viewManager.createTabbedLocation(this._showDrawer.bind(this, false), 'drawer-view', true, true);
-    this._drawerTabbedLocation.enableMoreTabsButton();
-    this._drawerTabbedPane = this._drawerTabbedLocation.tabbedPane();
-    this._drawerTabbedPane.setMinimumSize(0, 27);
-    const closeDrawerButton = new UI.ToolbarButton(Common.UIString('Close drawer'), 'largeicon-delete');
-    closeDrawerButton.addEventListener(UI.ToolbarButton.Events.Click, this._closeDrawer, this);
-    this._drawerTabbedPane.rightToolbar().appendToolbarItem(closeDrawerButton);
-    this._drawerSplitWidget.installResizer(this._drawerTabbedPane.headerElement());
-    this._drawerSplitWidget.setSidebarWidget(this._drawerTabbedPane);
-    this._drawerTabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._drawerTabSelected, this);
-
-    // Create main area tabbed pane.
-    this._tabbedLocation = UI.viewManager.createTabbedLocation(
-        InspectorFrontendHost.bringToFront.bind(InspectorFrontendHost), 'panel', true, true,
-        Runtime.queryParam('panel'));
-
-    this._tabbedPane = this._tabbedLocation.tabbedPane();
-    this._tabbedPane.registerRequiredCSS('ui/inspectorViewTabbedPane.css');
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-    this._tabbedPane.setAccessibleName(Common.UIString('Panels'));
-
-    if (Host.isUnderTest())
-      this._tabbedPane.setAutoSelectFirstItemOnShow(false);
-    this._drawerSplitWidget.setMainWidget(this._tabbedPane);
-
-    this._keyDownBound = this._keyDown.bind(this);
-    InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ShowPanel, showPanel.bind(this));
-
-    /**
-     * @this {UI.InspectorView}
-     * @param {!Common.Event} event
-     */
-    function showPanel(event) {
-      const panelName = /** @type {string} */ (event.data);
-      this.showPanel(panelName);
-    }
-  }
-
-  /**
-   * @return {!UI.InspectorView}
-   */
-  static instance() {
-    return /** @type {!UI.InspectorView} */ (self.runtime.sharedInstance(UI.InspectorView));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this.element.ownerDocument.addEventListener('keydown', this._keyDownBound, false);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this.element.ownerDocument.removeEventListener('keydown', this._keyDownBound, false);
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   * @return {?UI.ViewLocation}
-   */
-  resolveLocation(locationName) {
-    if (locationName === 'drawer-view')
-      return this._drawerTabbedLocation;
-    if (locationName === 'panel')
-      return this._tabbedLocation;
-    return null;
-  }
-
-  createToolbars() {
-    this._tabbedPane.leftToolbar().appendLocationItems('main-toolbar-left');
-    this._tabbedPane.rightToolbar().appendLocationItems('main-toolbar-right');
-  }
-
-  /**
-   * @param {!UI.View} view
-   */
-  addPanel(view) {
-    this._tabbedLocation.appendView(view);
-  }
-
-  /**
-   * @param {string} panelName
-   * @return {boolean}
-   */
-  hasPanel(panelName) {
-    return this._tabbedPane.hasTab(panelName);
-  }
-
-  /**
-   * @param {string} panelName
-   * @return {!Promise.<!UI.Panel>}
-   */
-  panel(panelName) {
-    return /** @type {!Promise.<!UI.Panel>} */ (UI.viewManager.view(panelName).widget());
-  }
-
-  /**
-   * @param {boolean} allTargetsSuspended
-   */
-  onSuspendStateChanged(allTargetsSuspended) {
-    this._currentPanelLocked = allTargetsSuspended;
-    this._tabbedPane.setCurrentTabLocked(this._currentPanelLocked);
-    this._tabbedPane.leftToolbar().setEnabled(!this._currentPanelLocked);
-    this._tabbedPane.rightToolbar().setEnabled(!this._currentPanelLocked);
-  }
-
-  /**
-   * @param {string} panelName
-   * @return {boolean}
-   */
-  canSelectPanel(panelName) {
-    return !this._currentPanelLocked || this._tabbedPane.selectedTabId === panelName;
-  }
-
-  /**
-   * @param {string} panelName
-   * @return {!Promise.<?UI.Panel>}
-   */
-  showPanel(panelName) {
-    return UI.viewManager.showView(panelName);
-  }
-
-  /**
-   * @param {string} panelName
-   * @param {?UI.Icon} icon
-   */
-  setPanelIcon(panelName, icon) {
-    this._tabbedPane.setTabIcon(panelName, icon);
-  }
-
-  /**
-   * @return {!UI.Panel}
-   */
-  currentPanelDeprecated() {
-    return /** @type {!UI.Panel} */ (UI.viewManager.materializedWidget(this._tabbedPane.selectedTabId || ''));
-  }
-
-  /**
-   * @param {boolean} focus
-   */
-  _showDrawer(focus) {
-    if (this._drawerTabbedPane.isShowing())
-      return;
-    this._drawerSplitWidget.showBoth();
-    if (focus)
-      this._focusRestorer = new UI.WidgetFocusRestorer(this._drawerTabbedPane);
-    else
-      this._focusRestorer = null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  drawerVisible() {
-    return this._drawerTabbedPane.isShowing();
-  }
-
-  _closeDrawer() {
-    if (!this._drawerTabbedPane.isShowing())
-      return;
-    if (this._focusRestorer)
-      this._focusRestorer.restore();
-    this._drawerSplitWidget.hideSidebar(true);
-  }
-
-  /**
-   * @param {boolean} minimized
-   */
-  setDrawerMinimized(minimized) {
-    this._drawerSplitWidget.setSidebarMinimized(minimized);
-    this._drawerSplitWidget.setResizable(!minimized);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDrawerMinimized() {
-    return this._drawerSplitWidget.isSidebarMinimized();
-  }
-
-  /**
-   * @param {string} id
-   * @param {boolean=} userGesture
-   */
-  closeDrawerTab(id, userGesture) {
-    this._drawerTabbedPane.closeTab(id, userGesture);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _keyDown(event) {
-    const keyboardEvent = /** @type {!KeyboardEvent} */ (event);
-    if (!UI.KeyboardShortcut.eventHasCtrlOrMeta(keyboardEvent) || event.altKey || event.shiftKey)
-      return;
-
-    // Ctrl/Cmd + 1-9 should show corresponding panel.
-    const panelShortcutEnabled = Common.moduleSetting('shortcutPanelSwitch').get();
-    if (panelShortcutEnabled) {
-      let panelIndex = -1;
-      if (event.keyCode > 0x30 && event.keyCode < 0x3A)
-        panelIndex = event.keyCode - 0x31;
-      else if (
-          event.keyCode > 0x60 && event.keyCode < 0x6A &&
-          keyboardEvent.location === KeyboardEvent.DOM_KEY_LOCATION_NUMPAD)
-        panelIndex = event.keyCode - 0x61;
-      if (panelIndex !== -1) {
-        const panelName = this._tabbedPane.allTabs()[panelIndex];
-        if (panelName) {
-          if (!UI.Dialog.hasInstance() && !this._currentPanelLocked)
-            this.showPanel(panelName);
-          event.consume(true);
-        }
-      }
-    }
-
-    if (event.key === '[') {
-      this._tabbedPane.selectPrevTab();
-      event.consume(true);
-    }
-
-    if (event.key === ']') {
-      this._tabbedPane.selectNextTab();
-      event.consume(true);
-    }
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    UI.GlassPane.containerMoved(this.element);
-  }
-
-  /**
-   * @return {!Element}
-   */
-  topResizerElement() {
-    return this._tabbedPane.headerElement();
-  }
-
-  toolbarItemResized() {
-    this._tabbedPane.headerResized();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabSelected(event) {
-    const tabId = /** @type {string} */ (event.data['tabId']);
-    Host.userMetrics.panelShown(tabId);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _drawerTabSelected(event) {
-    const tabId = /** @type {string} */ (event.data['tabId']);
-    Host.userMetrics.drawerShown(tabId);
-  }
-
-  /**
-   * @param {!UI.SplitWidget} splitWidget
-   */
-  setOwnerSplit(splitWidget) {
-    this._ownerSplitWidget = splitWidget;
-  }
-
-  minimize() {
-    if (this._ownerSplitWidget)
-      this._ownerSplitWidget.setSidebarMinimized(true);
-  }
-
-  restore() {
-    if (this._ownerSplitWidget)
-      this._ownerSplitWidget.setSidebarMinimized(false);
-  }
-};
-
-
-/**
- * @type {!UI.InspectorView}
- */
-UI.inspectorView;
-
-/**
- * @implements {UI.ActionDelegate}
- * @unrestricted
- */
-UI.InspectorView.DrawerToggleActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    if (UI.inspectorView.drawerVisible())
-      UI.inspectorView._closeDrawer();
-    else
-      UI.inspectorView._showDrawer(true);
-    return true;
-  }
-};
diff --git a/front_end/ui/KeyboardShortcut.js b/front_end/ui/KeyboardShortcut.js
deleted file mode 100644
index baa5271..0000000
--- a/front_end/ui/KeyboardShortcut.js
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.KeyboardShortcut = class {
-  /**
-   * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
-   * It is useful for matching pressed keys.
-   *
-   * @param {number|string} keyCode The code of the key, or a character "a-z" which is converted to a keyCode value.
-   * @param {number=} modifiers Optional list of modifiers passed as additional parameters.
-   * @return {number}
-   */
-  static makeKey(keyCode, modifiers) {
-    if (typeof keyCode === 'string')
-      keyCode = keyCode.charCodeAt(0) - (/^[a-z]/.test(keyCode) ? 32 : 0);
-    modifiers = modifiers || UI.KeyboardShortcut.Modifiers.None;
-    return UI.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
-  }
-
-  /**
-   * @param {?KeyboardEvent} keyboardEvent
-   * @return {number}
-   */
-  static makeKeyFromEvent(keyboardEvent) {
-    let modifiers = UI.KeyboardShortcut.Modifiers.None;
-    if (keyboardEvent.shiftKey)
-      modifiers |= UI.KeyboardShortcut.Modifiers.Shift;
-    if (keyboardEvent.ctrlKey)
-      modifiers |= UI.KeyboardShortcut.Modifiers.Ctrl;
-    if (keyboardEvent.altKey)
-      modifiers |= UI.KeyboardShortcut.Modifiers.Alt;
-    if (keyboardEvent.metaKey)
-      modifiers |= UI.KeyboardShortcut.Modifiers.Meta;
-
-    // Use either a real or a synthetic keyCode (for events originating from extensions).
-    const keyCode = keyboardEvent.keyCode || keyboardEvent['__keyCode'];
-    return UI.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
-  }
-
-  /**
-   * @param {?KeyboardEvent} keyboardEvent
-   * @return {number}
-   */
-  static makeKeyFromEventIgnoringModifiers(keyboardEvent) {
-    const keyCode = keyboardEvent.keyCode || keyboardEvent['__keyCode'];
-    return UI.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, UI.KeyboardShortcut.Modifiers.None);
-  }
-
-  /**
-   * @param {(?KeyboardEvent|?MouseEvent)} event
-   * @return {boolean}
-   */
-  static eventHasCtrlOrMeta(event) {
-    return Host.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  static hasNoModifiers(event) {
-    return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
-  }
-
-  /**
-   * @param {string|!UI.KeyboardShortcut.Key} key
-   * @param {number=} modifiers
-   * @return {!UI.KeyboardShortcut.Descriptor}
-   */
-  static makeDescriptor(key, modifiers) {
-    return {
-      key: UI.KeyboardShortcut.makeKey(typeof key === 'string' ? key : key.code, modifiers),
-      name: UI.KeyboardShortcut.shortcutToString(key, modifiers)
-    };
-  }
-
-  /**
-   * @param {string} shortcut
-   * @return {?UI.KeyboardShortcut.Descriptor}
-   */
-  static makeDescriptorFromBindingShortcut(shortcut) {
-    const parts = shortcut.split(/\+(?!$)/);
-    let modifiers = 0;
-    let keyString;
-    for (let i = 0; i < parts.length; ++i) {
-      if (typeof UI.KeyboardShortcut.Modifiers[parts[i]] !== 'undefined') {
-        modifiers |= UI.KeyboardShortcut.Modifiers[parts[i]];
-        continue;
-      }
-      console.assert(
-          i === parts.length - 1, 'Only one key other than modifier is allowed in shortcut <' + shortcut + '>');
-      keyString = parts[i];
-      break;
-    }
-    console.assert(keyString, 'Modifiers-only shortcuts are not allowed (encountered <' + shortcut + '>)');
-    if (!keyString)
-      return null;
-
-    const key = UI.KeyboardShortcut.Keys[keyString] || UI.KeyboardShortcut.KeyBindings[keyString];
-    if (key && key.shiftKey)
-      modifiers |= UI.KeyboardShortcut.Modifiers.Shift;
-    return UI.KeyboardShortcut.makeDescriptor(key ? key : keyString, modifiers);
-  }
-
-  /**
-   * @param {string|!UI.KeyboardShortcut.Key} key
-   * @param {number=} modifiers
-   * @return {string}
-   */
-  static shortcutToString(key, modifiers) {
-    return UI.KeyboardShortcut._modifiersToString(modifiers) + UI.KeyboardShortcut._keyName(key);
-  }
-
-  /**
-   * @param {string|!UI.KeyboardShortcut.Key} key
-   * @return {string}
-   */
-  static _keyName(key) {
-    if (typeof key === 'string')
-      return key.toUpperCase();
-    if (typeof key.name === 'string')
-      return key.name;
-    return key.name[Host.platform()] || key.name.other || '';
-  }
-
-  /**
-   * @param {number} keyCode
-   * @param {?number} modifiers
-   * @return {number}
-   */
-  static _makeKeyFromCodeAndModifiers(keyCode, modifiers) {
-    return (keyCode & 255) | (modifiers << 8);
-  }
-
-  /**
-   * @param {number} key
-   * @return {!{keyCode: number, modifiers: number}}
-   */
-  static keyCodeAndModifiersFromKey(key) {
-    return {keyCode: key & 255, modifiers: key >> 8};
-  }
-
-  /**
-   * @param {number|undefined} modifiers
-   * @return {string}
-   */
-  static _modifiersToString(modifiers) {
-    const isMac = Host.isMac();
-    const m = UI.KeyboardShortcut.Modifiers;
-    const modifierNames = new Map([
-      [m.Ctrl, isMac ? 'Ctrl\u2004' : 'Ctrl\u200A+\u200A'], [m.Alt, isMac ? '\u2325\u2004' : 'Alt\u200A+\u200A'],
-      [m.Shift, isMac ? '\u21e7\u2004' : 'Shift\u200A+\u200A'], [m.Meta, isMac ? '\u2318\u2004' : 'Win\u200A+\u200A']
-    ]);
-    return [m.Meta, m.Ctrl, m.Alt, m.Shift].map(mapModifiers).join('');
-
-    /**
-     * @param {number} m
-     * @return {string}
-     */
-    function mapModifiers(m) {
-      return modifiers & m ? /** @type {string} */ (modifierNames.get(m)) : '';
-    }
-  }
-};
-
-/**
- * Constants for encoding modifier key set as a bit mask.
- * @see #_makeKeyFromCodeAndModifiers
- */
-UI.KeyboardShortcut.Modifiers = {
-  None: 0,  // Constant for empty modifiers set.
-  Shift: 1,
-  Ctrl: 2,
-  Alt: 4,
-  Meta: 8,  // Command key on Mac, Win key on other platforms.
-  get CtrlOrMeta() {
-    // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
-    return Host.isMac() ? this.Meta : this.Ctrl;
-  },
-  get ShiftOrOption() {
-    // Option on Mac, Shift on other platforms
-    return Host.isMac() ? this.Alt : this.Shift;
-  }
-};
-
-/** @typedef {!{code: number, name: (string|!Object.<string, string>)}} */
-UI.KeyboardShortcut.Key;
-
-/** @type {!Object.<string, !UI.KeyboardShortcut.Key>} */
-UI.KeyboardShortcut.Keys = {
-  Backspace: {code: 8, name: '\u21a4'},
-  Tab: {code: 9, name: {mac: '\u21e5', other: 'Tab'}},
-  Enter: {code: 13, name: {mac: '\u21a9', other: 'Enter'}},
-  Shift: {code: 16, name: {mac: '\u21e7', other: 'Shift'}},
-  Ctrl: {code: 17, name: 'Ctrl'},
-  Esc: {code: 27, name: 'Esc'},
-  Space: {code: 32, name: 'Space'},
-  PageUp: {code: 33, name: {mac: '\u21de', other: 'PageUp'}},      // also NUM_NORTH_EAST
-  PageDown: {code: 34, name: {mac: '\u21df', other: 'PageDown'}},  // also NUM_SOUTH_EAST
-  End: {code: 35, name: {mac: '\u2197', other: 'End'}},            // also NUM_SOUTH_WEST
-  Home: {code: 36, name: {mac: '\u2196', other: 'Home'}},          // also NUM_NORTH_WEST
-  Left: {code: 37, name: '\u2190'},                                // also NUM_WEST
-  Up: {code: 38, name: '\u2191'},                                  // also NUM_NORTH
-  Right: {code: 39, name: '\u2192'},                               // also NUM_EAST
-  Down: {code: 40, name: '\u2193'},                                // also NUM_SOUTH
-  Delete: {code: 46, name: 'Del'},
-  Zero: {code: 48, name: '0'},
-  H: {code: 72, name: 'H'},
-  N: {code: 78, name: 'N'},
-  P: {code: 80, name: 'P'},
-  Meta: {code: 91, name: 'Meta'},
-  F1: {code: 112, name: 'F1'},
-  F2: {code: 113, name: 'F2'},
-  F3: {code: 114, name: 'F3'},
-  F4: {code: 115, name: 'F4'},
-  F5: {code: 116, name: 'F5'},
-  F6: {code: 117, name: 'F6'},
-  F7: {code: 118, name: 'F7'},
-  F8: {code: 119, name: 'F8'},
-  F9: {code: 120, name: 'F9'},
-  F10: {code: 121, name: 'F10'},
-  F11: {code: 122, name: 'F11'},
-  F12: {code: 123, name: 'F12'},
-  Semicolon: {code: 186, name: ';'},
-  NumpadPlus: {code: 107, name: 'Numpad +'},
-  NumpadMinus: {code: 109, name: 'Numpad -'},
-  Numpad0: {code: 96, name: 'Numpad 0'},
-  Plus: {code: 187, name: '+'},
-  Comma: {code: 188, name: ','},
-  Minus: {code: 189, name: '-'},
-  Period: {code: 190, name: '.'},
-  Slash: {code: 191, name: '/'},
-  QuestionMark: {code: 191, name: '?'},
-  Apostrophe: {code: 192, name: '`'},
-  Tilde: {code: 192, name: 'Tilde'},
-  LeftSquareBracket: {code: 219, name: '['},
-  RightSquareBracket: {code: 221, name: ']'},
-  Backslash: {code: 220, name: '\\'},
-  SingleQuote: {code: 222, name: '\''},
-  get CtrlOrMeta() {
-    // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
-    return Host.isMac() ? this.Meta : this.Ctrl;
-  },
-};
-
-UI.KeyboardShortcut.KeyBindings = {};
-
-(function() {
-for (const key in UI.KeyboardShortcut.Keys) {
-  const descriptor = UI.KeyboardShortcut.Keys[key];
-  if (typeof descriptor === 'object' && descriptor['code']) {
-    const name = typeof descriptor['name'] === 'string' ? descriptor['name'] : key;
-    UI.KeyboardShortcut.KeyBindings[name] = descriptor;
-  }
-}
-})();
-
-
-/** @typedef {!{key: number, name: string}} */
-UI.KeyboardShortcut.Descriptor;
diff --git a/front_end/ui/ListControl.js b/front_end/ui/ListControl.js
deleted file mode 100644
index 56f1946..0000000
--- a/front_end/ui/ListControl.js
+++ /dev/null
@@ -1,651 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @template T
- * @interface
- */
-UI.ListDelegate = function() {};
-
-UI.ListDelegate.prototype = {
-  /**
-   * @param {T} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {},
-
-  /**
-   * This method is not called in NonViewport mode.
-   * Return zero to make list measure the item (only works in SameHeight mode).
-   * @param {T} item
-   * @return {number}
-   */
-  heightForItem(item) {},
-
-  /**
-   * @param {T} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {},
-
-  /**
-   * @param {?T} from
-   * @param {?T} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {},
-};
-
-/** @enum {symbol} */
-UI.ListMode = {
-  NonViewport: Symbol('UI.ListMode.NonViewport'),
-  EqualHeightItems: Symbol('UI.ListMode.EqualHeightItems'),
-  VariousHeightItems: Symbol('UI.ListMode.VariousHeightItems')
-};
-
-/**
- * @template T
- */
-UI.ListControl = class {
-  /**
-   * @param {!UI.ListModel<T>} model
-   * @param {!UI.ListDelegate<T>} delegate
-   * @param {!UI.ListMode=} mode
-   */
-  constructor(model, delegate, mode) {
-    this.element = createElement('div');
-    this.element.style.overflowY = 'auto';
-    this._topElement = this.element.createChild('div');
-    this._bottomElement = this.element.createChild('div');
-    this._firstIndex = 0;
-    this._lastIndex = 0;
-    this._renderedHeight = 0;
-    this._topHeight = 0;
-    this._bottomHeight = 0;
-
-    this._model = model;
-    this._model.addEventListener(UI.ListModel.Events.ItemsReplaced, this._replacedItemsInRange, this);
-    /** @type {!Map<T, !Element>} */
-    this._itemToElement = new Map();
-    this._selectedIndex = -1;
-    /** @type {?T} */
-    this._selectedItem = null;
-
-    this.element.tabIndex = -1;
-    this.element.addEventListener('click', this._onClick.bind(this), false);
-    this.element.addEventListener('keydown', this._onKeyDown.bind(this), false);
-
-    this._delegate = delegate;
-    this._mode = mode || UI.ListMode.EqualHeightItems;
-    this._fixedHeight = 0;
-    this._variableOffsets = new Int32Array(0);
-    this._clearContents();
-
-    if (this._mode !== UI.ListMode.NonViewport) {
-      this.element.addEventListener('scroll', () => {
-        this._updateViewport(this.element.scrollTop, this.element.offsetHeight);
-      }, false);
-    }
-  }
-
-  /**
-   * @param {!UI.ListModel<T>} model
-   */
-  setModel(model) {
-    this._itemToElement.clear();
-    const length = this._model.length;
-    this._model.removeEventListener(UI.ListModel.Events.ItemsReplaced, this._replacedItemsInRange, this);
-    this._model = model;
-    this._model.addEventListener(UI.ListModel.Events.ItemsReplaced, this._replacedItemsInRange, this);
-    this.invalidateRange(0, length);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _replacedItemsInRange(event) {
-    const data = /** @type {{index: number, removed: !Array<T>, inserted: number}} */ (event.data);
-    const from = data.index;
-    const to = from + data.removed.length;
-
-    const oldSelectedItem = this._selectedItem;
-    const oldSelectedElement = oldSelectedItem ? (this._itemToElement.get(oldSelectedItem) || null) : null;
-    for (let i = 0; i < data.removed.length; i++)
-      this._itemToElement.delete(data.removed[i]);
-    this._invalidate(from, to, data.inserted);
-
-    if (this._selectedIndex >= to) {
-      this._selectedIndex += data.inserted - (to - from);
-      this._selectedItem = this._model.at(this._selectedIndex);
-    } else if (this._selectedIndex >= from) {
-      let index = this._findFirstSelectable(from + data.inserted, +1, false);
-      if (index === -1)
-        index = this._findFirstSelectable(from - 1, -1, false);
-      this._select(index, oldSelectedItem, oldSelectedElement);
-    }
-  }
-
-  /**
-   * @param {T} item
-   */
-  refreshItem(item) {
-    const index = this._model.indexOf(item);
-    if (index === -1) {
-      console.error('Item to refresh is not present');
-      return;
-    }
-    this._itemToElement.delete(item);
-    this.invalidateRange(index, index + 1);
-    if (this._selectedIndex !== -1)
-      this._select(this._selectedIndex, null, null);
-  }
-
-  /**
-   * @param {number} from
-   * @param {number} to
-   */
-  invalidateRange(from, to) {
-    this._invalidate(from, to, to - from);
-  }
-
-  viewportResized() {
-    if (this._mode === UI.ListMode.NonViewport)
-      return;
-    // TODO(dgozman): try to keep visible scrollTop the same.
-    const scrollTop = this.element.scrollTop;
-    const viewportHeight = this.element.offsetHeight;
-    this._clearViewport();
-    this._updateViewport(Number.constrain(scrollTop, 0, this._totalHeight() - viewportHeight), viewportHeight);
-  }
-
-  invalidateItemHeight() {
-    if (this._mode !== UI.ListMode.EqualHeightItems) {
-      console.error('Only supported in equal height items mode');
-      return;
-    }
-    this._fixedHeight = 0;
-    if (this._model.length) {
-      this._itemToElement.clear();
-      this._invalidate(0, this._model.length, this._model.length);
-    }
-  }
-
-  /**
-   * @param {?Node} node
-   * @return {?T}
-   */
-  itemForNode(node) {
-    while (node && node.parentNodeOrShadowHost() !== this.element)
-      node = node.parentNodeOrShadowHost();
-    if (!node)
-      return null;
-    const element = /** @type {!Element} */ (node);
-    const index = this._model.findIndex(item => this._itemToElement.get(item) === element);
-    return index !== -1 ? this._model.at(index) : null;
-  }
-
-  /**
-   * @param {T} item
-   * @param {boolean=} center
-   */
-  scrollItemIntoView(item, center) {
-    const index = this._model.indexOf(item);
-    if (index === -1) {
-      console.error('Attempt to scroll onto missing item');
-      return;
-    }
-    this._scrollIntoView(index, center);
-  }
-
-  /**
-   * @return {?T}
-   */
-  selectedItem() {
-    return this._selectedItem;
-  }
-
-  /**
-   * @return {number}
-   */
-  selectedIndex() {
-    return this._selectedIndex;
-  }
-
-  /**
-   * @param {?T} item
-   * @param {boolean=} center
-   * @param {boolean=} dontScroll
-   */
-  selectItem(item, center, dontScroll) {
-    let index = -1;
-    if (item !== null) {
-      index = this._model.indexOf(item);
-      if (index === -1) {
-        console.error('Attempt to select missing item');
-        return;
-      }
-      if (!this._delegate.isItemSelectable(item)) {
-        console.error('Attempt to select non-selectable item');
-        return;
-      }
-    }
-    if (this._selectedIndex !== index)
-      this._select(index);
-    if (index !== -1 && !dontScroll)
-      this._scrollIntoView(index, center);
-  }
-
-  /**
-   * @param {boolean=} canWrap
-   * @param {boolean=} center
-   * @return {boolean}
-   */
-  selectPreviousItem(canWrap, center) {
-    if (this._selectedIndex === -1 && !canWrap)
-      return false;
-    let index = this._selectedIndex === -1 ? this._model.length - 1 : this._selectedIndex - 1;
-    index = this._findFirstSelectable(index, -1, !!canWrap);
-    if (index !== -1) {
-      this._scrollIntoView(index, center);
-      this._select(index);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {boolean=} canWrap
-   * @param {boolean=} center
-   * @return {boolean}
-   */
-  selectNextItem(canWrap, center) {
-    if (this._selectedIndex === -1 && !canWrap)
-      return false;
-    let index = this._selectedIndex === -1 ? 0 : this._selectedIndex + 1;
-    index = this._findFirstSelectable(index, +1, !!canWrap);
-    if (index !== -1) {
-      this._scrollIntoView(index, center);
-      this._select(index);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {boolean=} center
-   * @return {boolean}
-   */
-  selectItemPreviousPage(center) {
-    if (this._mode === UI.ListMode.NonViewport)
-      return false;
-    let index = this._selectedIndex === -1 ? this._model.length - 1 : this._selectedIndex;
-    index = this._findPageSelectable(index, -1);
-    if (index !== -1) {
-      this._scrollIntoView(index, center);
-      this._select(index);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {boolean=} center
-   * @return {boolean}
-   */
-  selectItemNextPage(center) {
-    if (this._mode === UI.ListMode.NonViewport)
-      return false;
-    let index = this._selectedIndex === -1 ? 0 : this._selectedIndex;
-    index = this._findPageSelectable(index, +1);
-    if (index !== -1) {
-      this._scrollIntoView(index, center);
-      this._select(index);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @param {number} index
-   * @param {boolean=} center
-   */
-  _scrollIntoView(index, center) {
-    if (this._mode === UI.ListMode.NonViewport) {
-      this._elementAtIndex(index).scrollIntoViewIfNeeded(!!center);
-      return;
-    }
-
-    const top = this._offsetAtIndex(index);
-    const bottom = this._offsetAtIndex(index + 1);
-    const viewportHeight = this.element.offsetHeight;
-    if (center) {
-      const scrollTo = (top + bottom) / 2 - viewportHeight / 2;
-      this._updateViewport(Number.constrain(scrollTo, 0, this._totalHeight() - viewportHeight), viewportHeight);
-      return;
-    }
-
-    const scrollTop = this.element.scrollTop;
-    if (top < scrollTop)
-      this._updateViewport(top, viewportHeight);
-    else if (bottom > scrollTop + viewportHeight)
-      this._updateViewport(bottom - viewportHeight, viewportHeight);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    const item = this.itemForNode(/** @type {?Node} */ (event.target));
-    if (item && this._delegate.isItemSelectable(item))
-      this.selectItem(item);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    let selected = false;
-    switch (event.key) {
-      case 'ArrowUp':
-        selected = this.selectPreviousItem(true, false);
-        break;
-      case 'ArrowDown':
-        selected = this.selectNextItem(true, false);
-        break;
-      case 'PageUp':
-        selected = this.selectItemPreviousPage(false);
-        break;
-      case 'PageDown':
-        selected = this.selectItemNextPage(false);
-        break;
-    }
-    if (selected)
-      event.consume();
-  }
-
-  /**
-   * @return {number}
-   */
-  _totalHeight() {
-    return this._offsetAtIndex(this._model.length);
-  }
-
-  /**
-   * @param {number} offset
-   * @return {number}
-   */
-  _indexAtOffset(offset) {
-    if (this._mode === UI.ListMode.NonViewport)
-      throw 'There should be no offset conversions in non-viewport mode';
-    if (!this._model.length || offset < 0)
-      return 0;
-    if (this._mode === UI.ListMode.VariousHeightItems) {
-      return Math.min(
-          this._model.length - 1, this._variableOffsets.lowerBound(offset, undefined, 0, this._model.length));
-    }
-    if (!this._fixedHeight)
-      this._measureHeight();
-    return Math.min(this._model.length - 1, Math.floor(offset / this._fixedHeight));
-  }
-
-  /**
-   * @param {number} index
-   * @return {!Element}
-   */
-  _elementAtIndex(index) {
-    const item = this._model.at(index);
-    let element = this._itemToElement.get(item);
-    if (!element) {
-      element = this._delegate.createElementForItem(item);
-      this._itemToElement.set(item, element);
-    }
-    return element;
-  }
-
-  /**
-   * @param {number} index
-   * @return {number}
-   */
-  _offsetAtIndex(index) {
-    if (this._mode === UI.ListMode.NonViewport)
-      throw 'There should be no offset conversions in non-viewport mode';
-    if (!this._model.length)
-      return 0;
-    if (this._mode === UI.ListMode.VariousHeightItems)
-      return this._variableOffsets[index];
-    if (!this._fixedHeight)
-      this._measureHeight();
-    return index * this._fixedHeight;
-  }
-
-  _measureHeight() {
-    this._fixedHeight = this._delegate.heightForItem(this._model.at(0));
-    if (!this._fixedHeight)
-      this._fixedHeight = UI.measurePreferredSize(this._elementAtIndex(0), this.element).height;
-  }
-
-  /**
-   * @param {number} index
-   * @param {?T=} oldItem
-   * @param {?Element=} oldElement
-   */
-  _select(index, oldItem, oldElement) {
-    if (oldItem === undefined)
-      oldItem = this._selectedItem;
-    if (oldElement === undefined)
-      oldElement = this._itemToElement.get(oldItem) || null;
-    this._selectedIndex = index;
-    this._selectedItem = index === -1 ? null : this._model.at(index);
-    const newItem = this._selectedItem;
-    const newElement = this._selectedIndex !== -1 ? this._elementAtIndex(index) : null;
-    this._delegate.selectedItemChanged(oldItem, newItem, /** @type {?Element} */ (oldElement), newElement);
-  }
-
-  /**
-   * @param {number} index
-   * @param {number} direction
-   * @param {boolean} canWrap
-   * @return {number}
-   */
-  _findFirstSelectable(index, direction, canWrap) {
-    const length = this._model.length;
-    if (!length)
-      return -1;
-    for (let step = 0; step <= length; step++) {
-      if (index < 0 || index >= length) {
-        if (!canWrap)
-          return -1;
-        index = (index + length) % length;
-      }
-      if (this._delegate.isItemSelectable(this._model.at(index)))
-        return index;
-      index += direction;
-    }
-    return -1;
-  }
-
-  /**
-   * @param {number} index
-   * @param {number} direction
-   * @return {number}
-   */
-  _findPageSelectable(index, direction) {
-    let lastSelectable = -1;
-    const startOffset = this._offsetAtIndex(index);
-    // Compensate for zoom rounding errors with -1.
-    const viewportHeight = this.element.offsetHeight - 1;
-    while (index >= 0 && index < this._model.length) {
-      if (this._delegate.isItemSelectable(this._model.at(index))) {
-        if (Math.abs(this._offsetAtIndex(index) - startOffset) >= viewportHeight)
-          return index;
-        lastSelectable = index;
-      }
-      index += direction;
-    }
-    return lastSelectable;
-  }
-
-  /**
-   * @param {number} length
-   * @param {number} copyTo
-   */
-  _reallocateVariableOffsets(length, copyTo) {
-    if (this._variableOffsets.length < length) {
-      const variableOffsets = new Int32Array(Math.max(length, this._variableOffsets.length * 2));
-      variableOffsets.set(this._variableOffsets.slice(0, copyTo), 0);
-      this._variableOffsets = variableOffsets;
-    } else if (this._variableOffsets.length >= 2 * length) {
-      const variableOffsets = new Int32Array(length);
-      variableOffsets.set(this._variableOffsets.slice(0, copyTo), 0);
-      this._variableOffsets = variableOffsets;
-    }
-  }
-
-  /**
-   * @param {number} from
-   * @param {number} to
-   * @param {number} inserted
-   */
-  _invalidate(from, to, inserted) {
-    if (this._mode === UI.ListMode.NonViewport) {
-      this._invalidateNonViewportMode(from, to - from, inserted);
-      return;
-    }
-
-    if (this._mode === UI.ListMode.VariousHeightItems) {
-      this._reallocateVariableOffsets(this._model.length + 1, from + 1);
-      for (let i = from + 1; i <= this._model.length; i++)
-        this._variableOffsets[i] = this._variableOffsets[i - 1] + this._delegate.heightForItem(this._model.at(i - 1));
-    }
-
-    const viewportHeight = this.element.offsetHeight;
-    const totalHeight = this._totalHeight();
-    const scrollTop = this.element.scrollTop;
-
-    if (this._renderedHeight < viewportHeight || totalHeight < viewportHeight) {
-      this._clearViewport();
-      this._updateViewport(Number.constrain(scrollTop, 0, totalHeight - viewportHeight), viewportHeight);
-      return;
-    }
-
-    const heightDelta = totalHeight - this._renderedHeight;
-    if (to <= this._firstIndex) {
-      const topHeight = this._topHeight + heightDelta;
-      this._topElement.style.height = topHeight + 'px';
-      this.element.scrollTop = scrollTop + heightDelta;
-      this._topHeight = topHeight;
-      this._renderedHeight = totalHeight;
-      const indexDelta = inserted - (to - from);
-      this._firstIndex += indexDelta;
-      this._lastIndex += indexDelta;
-      return;
-    }
-
-    if (from >= this._lastIndex) {
-      const bottomHeight = this._bottomHeight + heightDelta;
-      this._bottomElement.style.height = bottomHeight + 'px';
-      this._bottomHeight = bottomHeight;
-      this._renderedHeight = totalHeight;
-      return;
-    }
-
-    // TODO(dgozman): try to keep visible scrollTop the same
-    // when invalidating after firstIndex but before first visible element.
-    this._clearViewport();
-    this._updateViewport(Number.constrain(scrollTop, 0, totalHeight - viewportHeight), viewportHeight);
-  }
-
-  /**
-   * @param {number} start
-   * @param {number} remove
-   * @param {number} add
-   */
-  _invalidateNonViewportMode(start, remove, add) {
-    let startElement = this._topElement;
-    for (let index = 0; index < start; index++)
-      startElement = startElement.nextElementSibling;
-    while (remove--)
-      startElement.nextElementSibling.remove();
-    while (add--)
-      this.element.insertBefore(this._elementAtIndex(start + add), startElement.nextElementSibling);
-  }
-
-  _clearViewport() {
-    if (this._mode === UI.ListMode.NonViewport) {
-      console.error('There should be no viewport updates in non-viewport mode');
-      return;
-    }
-    this._firstIndex = 0;
-    this._lastIndex = 0;
-    this._renderedHeight = 0;
-    this._topHeight = 0;
-    this._bottomHeight = 0;
-    this._clearContents();
-  }
-
-  _clearContents() {
-    // Note: this method should not force layout. Be careful.
-    this._topElement.style.height = '0';
-    this._bottomElement.style.height = '0';
-    this.element.removeChildren();
-    this.element.appendChild(this._topElement);
-    this.element.appendChild(this._bottomElement);
-  }
-
-  /**
-   * @param {number} scrollTop
-   * @param {number} viewportHeight
-   */
-  _updateViewport(scrollTop, viewportHeight) {
-    // Note: this method should not force layout. Be careful.
-    if (this._mode === UI.ListMode.NonViewport) {
-      console.error('There should be no viewport updates in non-viewport mode');
-      return;
-    }
-    const totalHeight = this._totalHeight();
-    if (!totalHeight) {
-      this._firstIndex = 0;
-      this._lastIndex = 0;
-      this._topHeight = 0;
-      this._bottomHeight = 0;
-      this._renderedHeight = 0;
-      this._topElement.style.height = '0';
-      this._bottomElement.style.height = '0';
-      return;
-    }
-
-    const firstIndex = this._indexAtOffset(scrollTop - viewportHeight);
-    const lastIndex = this._indexAtOffset(scrollTop + 2 * viewportHeight) + 1;
-
-    while (this._firstIndex < Math.min(firstIndex, this._lastIndex)) {
-      this._elementAtIndex(this._firstIndex).remove();
-      this._firstIndex++;
-    }
-    while (this._lastIndex > Math.max(lastIndex, this._firstIndex)) {
-      this._elementAtIndex(this._lastIndex - 1).remove();
-      this._lastIndex--;
-    }
-
-    this._firstIndex = Math.min(this._firstIndex, lastIndex);
-    this._lastIndex = Math.max(this._lastIndex, firstIndex);
-    for (let index = this._firstIndex - 1; index >= firstIndex; index--) {
-      const element = this._elementAtIndex(index);
-      this.element.insertBefore(element, this._topElement.nextSibling);
-    }
-    for (let index = this._lastIndex; index < lastIndex; index++) {
-      const element = this._elementAtIndex(index);
-      this.element.insertBefore(element, this._bottomElement);
-    }
-
-    this._firstIndex = firstIndex;
-    this._lastIndex = lastIndex;
-    this._topHeight = this._offsetAtIndex(firstIndex);
-    this._topElement.style.height = this._topHeight + 'px';
-    this._bottomHeight = totalHeight - this._offsetAtIndex(lastIndex);
-    this._bottomElement.style.height = this._bottomHeight + 'px';
-    this._renderedHeight = totalHeight;
-    this.element.scrollTop = scrollTop;
-  }
-};
diff --git a/front_end/ui/ListModel.js b/front_end/ui/ListModel.js
deleted file mode 100644
index 468e948..0000000
--- a/front_end/ui/ListModel.js
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Iterable<T>}
- * @template T
- */
-UI.ListModel = class extends Common.Object {
-  /**
-   * @param {!Array<T>=} items
-   */
-  constructor(items) {
-    super();
-    this._items = items || [];
-  }
-
-  /**
-   * @return {!Iterator<T>}
-   */
-  [Symbol.iterator]() {
-    return this._items[Symbol.iterator]();
-  }
-
-  /**
-   * @return {number}
-   */
-  get length() {
-    return this._items.length;
-  }
-
-  /**
-   * @param {number} index
-   * @return {T}
-   */
-  at(index) {
-    return this._items[index];
-  }
-
-  /**
-   * @param {function(T):boolean} callback
-   * @return {boolean}
-   */
-  every(callback) {
-    return this._items.every(callback);
-  }
-
-  /**
-   * @param {function(T):boolean} callback
-   * @return {!Array<T>}
-   */
-  filter(callback) {
-    return this._items.filter(callback);
-  }
-
-  /**
-   * @param {function(T):boolean} callback
-   * @return {T|undefined}
-   */
-  find(callback) {
-    return this._items.find(callback);
-  }
-
-  /**
-   * @param {function(T):boolean} callback
-   * @return {number}
-   */
-  findIndex(callback) {
-    return this._items.findIndex(callback);
-  }
-
-  /**
-   * @param {T} value
-   * @param {number=} fromIndex
-   * @return {number}
-   */
-  indexOf(value, fromIndex) {
-    return this._items.indexOf(value, fromIndex);
-  }
-
-  /**
-   * @param {number} index
-   * @param {T} value
-   */
-  insert(index, value) {
-    this._items.splice(index, 0, value);
-    this._replaced(index, [], 1);
-  }
-
-  /**
-   * @param {T} value
-   * @param {function(T, T):number} comparator
-   */
-  insertWithComparator(value, comparator) {
-    this.insert(this._items.lowerBound(value, comparator), value);
-  }
-
-  /**
-   * @param {string=} separator
-   * @return {string}
-   */
-  join(separator) {
-    return this._items.join(separator);
-  }
-
-  /**
-   * @param {number} index
-   * @return {T}
-   */
-  remove(index) {
-    const result = this._items[index];
-    this._items.splice(index, 1);
-    this._replaced(index, [result], 0);
-    return result;
-  }
-
-  /**
-   * @param {number} index
-   * @param {T} value
-   * @return {T}
-   */
-  replace(index, value) {
-    const oldValue = this._items[index];
-    this._items[index] = value;
-    this._replaced(index, [oldValue], 1);
-    return oldValue;
-  }
-
-  /**
-   * @param {number} from
-   * @param {number} to
-   * @param {!Array<T>} items
-   * @return {!Array<T>} removed
-   */
-  replaceRange(from, to, items) {
-    let removed;
-    if (items.length < 10000) {
-      removed = this._items.splice(from, to - from, ...items);
-    } else {
-      removed = this._items.slice(from, to);
-      // Splice may fail with too many arguments.
-      const before = this._items.slice(0, from);
-      const after = this._items.slice(to);
-      this._items = [].concat(before, items, after);
-    }
-    this._replaced(from, removed, items.length);
-    return removed;
-  }
-
-  /**
-   * @param {!Array<T>} items
-   * @return {!Array<T>}
-   */
-  replaceAll(items) {
-    const oldItems = this._items.slice();
-    this._items = items;
-    this._replaced(0, oldItems, items.length);
-    return oldItems;
-  }
-
-  /**
-   * @param {number=} from
-   * @param {number=} to
-   * @return {!Array<T>}
-   */
-  slice(from, to) {
-    return this._items.slice(from, to);
-  }
-
-  /**
-   * @param {function(T):boolean} callback
-   * @return {boolean}
-   */
-  some(callback) {
-    return this._items.some(callback);
-  }
-
-  /**
-   * @param {number} index
-   * @param {!Array<T>} removed
-   * @param {number} inserted
-   */
-  _replaced(index, removed, inserted) {
-    this.dispatchEventToListeners(
-        UI.ListModel.Events.ItemsReplaced, {index: index, removed: removed, inserted: inserted});
-  }
-};
-
-/** @enum {symbol} */
-UI.ListModel.Events = {
-  ItemsReplaced: Symbol('ItemsReplaced'),
-};
diff --git a/front_end/ui/ListWidget.js b/front_end/ui/ListWidget.js
deleted file mode 100644
index c11ae3a..0000000
--- a/front_end/ui/ListWidget.js
+++ /dev/null
@@ -1,421 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @template T
- */
-UI.ListWidget = class extends UI.VBox {
-  /**
-   * @param {!UI.ListWidget.Delegate<T>} delegate
-   */
-  constructor(delegate) {
-    super(true);
-    this.registerRequiredCSS('ui/listWidget.css');
-    this._delegate = delegate;
-
-    this._list = this.contentElement.createChild('div', 'list');
-    this.element.tabIndex = -1;
-
-    this._lastSeparator = false;
-    /** @type {?UI.ElementFocusRestorer} */
-    this._focusRestorer = null;
-    /** @type {!Array<T>} */
-    this._items = [];
-    /** @type {!Array<boolean>} */
-    this._editable = [];
-    /** @type {!Array<!Element>} */
-    this._elements = [];
-    /** @type {?UI.ListWidget.Editor<T>} */
-    this._editor = null;
-    /** @type {?T} */
-    this._editItem = null;
-    /** @type {?Element} */
-    this._editElement = null;
-
-    /** @type {?Element} */
-    this._emptyPlaceholder = null;
-
-    this._updatePlaceholder();
-  }
-
-  clear() {
-    this._items = [];
-    this._editable = [];
-    this._elements = [];
-    this._lastSeparator = false;
-    this._list.removeChildren();
-    this._updatePlaceholder();
-    this._stopEditing();
-  }
-
-  /**
-   * @param {!T} item
-   * @param {boolean} editable
-   */
-  appendItem(item, editable) {
-    if (this._lastSeparator && this._items.length)
-      this._list.appendChild(createElementWithClass('div', 'list-separator'));
-    this._lastSeparator = false;
-
-    this._items.push(item);
-    this._editable.push(editable);
-
-    const element = this._list.createChild('div', 'list-item');
-    element.appendChild(this._delegate.renderItem(item, editable));
-    if (editable) {
-      element.classList.add('editable');
-      element.appendChild(this._createControls(item, element));
-    }
-    this._elements.push(element);
-    this._updatePlaceholder();
-  }
-
-  appendSeparator() {
-    this._lastSeparator = true;
-  }
-
-  /**
-   * @param {number} index
-   */
-  removeItem(index) {
-    if (this._editItem === this._items[index])
-      this._stopEditing();
-
-    const element = this._elements[index];
-
-    const previous = element.previousElementSibling;
-    const previousIsSeparator = previous && previous.classList.contains('list-separator');
-
-    const next = element.nextElementSibling;
-    const nextIsSeparator = next && next.classList.contains('list-separator');
-
-    if (previousIsSeparator && (nextIsSeparator || !next))
-      previous.remove();
-    if (nextIsSeparator && !previous)
-      next.remove();
-    element.remove();
-
-    this._elements.splice(index, 1);
-    this._items.splice(index, 1);
-    this._editable.splice(index, 1);
-    this._updatePlaceholder();
-  }
-
-  /**
-   * @param {number} index
-   * @param {!T} item
-   */
-  addNewItem(index, item) {
-    this._startEditing(item, null, this._elements[index] || null);
-  }
-
-  /**
-   * @param {?Element} element
-   */
-  setEmptyPlaceholder(element) {
-    this._emptyPlaceholder = element;
-    this._updatePlaceholder();
-  }
-
-  /**
-   * @param {!T} item
-   * @param {!Element} element
-   * @return {!Element}
-   */
-  _createControls(item, element) {
-    const controls = createElementWithClass('div', 'controls-container fill');
-    controls.createChild('div', 'controls-gradient');
-
-    const buttons = controls.createChild('div', 'controls-buttons');
-
-    const toolbar = new UI.Toolbar('', buttons);
-
-    const editButton = new UI.ToolbarButton(Common.UIString('Edit'), 'largeicon-edit');
-    editButton.addEventListener(UI.ToolbarButton.Events.Click, onEditClicked.bind(this));
-    toolbar.appendToolbarItem(editButton);
-
-    const removeButton = new UI.ToolbarButton(Common.UIString('Remove'), 'largeicon-trash-bin');
-    removeButton.addEventListener(UI.ToolbarButton.Events.Click, onRemoveClicked.bind(this));
-    toolbar.appendToolbarItem(removeButton);
-
-    return controls;
-
-    /**
-     * @this {UI.ListWidget}
-     */
-    function onEditClicked() {
-      const index = this._elements.indexOf(element);
-      const insertionPoint = this._elements[index + 1] || null;
-      this._startEditing(item, element, insertionPoint);
-    }
-
-    /**
-     * @this {UI.ListWidget}
-     */
-    function onRemoveClicked() {
-      const index = this._elements.indexOf(element);
-      this.element.focus();
-      this._delegate.removeItemRequested(this._items[index], index);
-    }
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    this._stopEditing();
-  }
-
-  _updatePlaceholder() {
-    if (!this._emptyPlaceholder)
-      return;
-
-    if (!this._elements.length && !this._editor)
-      this._list.appendChild(this._emptyPlaceholder);
-    else
-      this._emptyPlaceholder.remove();
-  }
-
-  /**
-   * @param {!T} item
-   * @param {?Element} element
-   * @param {?Element} insertionPoint
-   */
-  _startEditing(item, element, insertionPoint) {
-    if (element && this._editElement === element)
-      return;
-
-    this._stopEditing();
-    this._focusRestorer = new UI.ElementFocusRestorer(this.element);
-
-    this._list.classList.add('list-editing');
-    this._editItem = item;
-    this._editElement = element;
-    if (element)
-      element.classList.add('hidden');
-
-    const index = element ? this._elements.indexOf(element) : -1;
-    this._editor = this._delegate.beginEdit(item);
-    this._updatePlaceholder();
-    this._list.insertBefore(this._editor.element, insertionPoint);
-    this._editor.beginEdit(
-        item, index, element ? Common.UIString('Save') : Common.UIString('Add'), this._commitEditing.bind(this),
-        this._stopEditing.bind(this));
-  }
-
-  _commitEditing() {
-    const editItem = this._editItem;
-    const isNew = !this._editElement;
-    const editor = /** @type {!UI.ListWidget.Editor<T>} */ (this._editor);
-    this._stopEditing();
-    this._delegate.commitEdit(editItem, editor, isNew);
-  }
-
-  _stopEditing() {
-    this._list.classList.remove('list-editing');
-    if (this._focusRestorer)
-      this._focusRestorer.restore();
-    if (this._editElement)
-      this._editElement.classList.remove('hidden');
-    if (this._editor && this._editor.element.parentElement)
-      this._editor.element.remove();
-
-    this._editor = null;
-    this._editItem = null;
-    this._editElement = null;
-    this._updatePlaceholder();
-  }
-};
-
-/**
- * @template T
- * @interface
- */
-UI.ListWidget.Delegate = function() {};
-
-UI.ListWidget.Delegate.prototype = {
-  /**
-   * @param {!T} item
-   * @param {boolean} editable
-   * @return {!Element}
-   */
-  renderItem(item, editable) {},
-
-  /**
-   * @param {!T} item
-   * @param {number} index
-   */
-  removeItemRequested(item, index) {},
-
-  /**
-   * @param {!T} item
-   * @return {!UI.ListWidget.Editor<T>}
-   */
-  beginEdit(item) {},
-
-  /**
-   * @param {!T} item
-   * @param {!UI.ListWidget.Editor<T>} editor
-   * @param {boolean} isNew
-   */
-  commitEdit(item, editor, isNew) {}
-};
-
-/**
- * @template T
- */
-UI.ListWidget.Editor = class {
-  constructor() {
-    this.element = createElementWithClass('div', 'editor-container');
-    this.element.addEventListener('keydown', onKeyDown.bind(null, isEscKey, this._cancelClicked.bind(this)), false);
-    this.element.addEventListener('keydown', onKeyDown.bind(null, isEnterKey, this._commitClicked.bind(this)), false);
-
-    this._contentElement = this.element.createChild('div', 'editor-content');
-
-    const buttonsRow = this.element.createChild('div', 'editor-buttons');
-    this._commitButton = UI.createTextButton('', this._commitClicked.bind(this), '', true /* primary */);
-    buttonsRow.appendChild(this._commitButton);
-    this._cancelButton = UI.createTextButton(Common.UIString('Cancel'), this._cancelClicked.bind(this));
-    this._cancelButton.addEventListener(
-        'keydown', onKeyDown.bind(null, isEnterKey, this._cancelClicked.bind(this)), false);
-    buttonsRow.appendChild(this._cancelButton);
-
-    /**
-     * @param {function(!Event):boolean} predicate
-     * @param {function()} callback
-     * @param {!Event} event
-     */
-    function onKeyDown(predicate, callback, event) {
-      if (predicate(event)) {
-        event.consume(true);
-        callback();
-      }
-    }
-
-    /** @type {!Array<!HTMLInputElement|!HTMLSelectElement>} */
-    this._controls = [];
-    /** @type {!Map<string, !HTMLInputElement|!HTMLSelectElement>} */
-    this._controlByName = new Map();
-    /** @type {!Array<function(!T, number, (!HTMLInputElement|!HTMLSelectElement)):boolean>} */
-    this._validators = [];
-
-    /** @type {?function()} */
-    this._commit = null;
-    /** @type {?function()} */
-    this._cancel = null;
-    /** @type {?T} */
-    this._item = null;
-    /** @type {number} */
-    this._index = -1;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  contentElement() {
-    return this._contentElement;
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} type
-   * @param {string} title
-   * @param {function(!T, number, (!HTMLInputElement|!HTMLSelectElement)):boolean} validator
-   * @return {!HTMLInputElement}
-   */
-  createInput(name, type, title, validator) {
-    const input = /** @type {!HTMLInputElement} */ (UI.createInput('', type));
-    input.placeholder = title;
-    input.addEventListener('input', this._validateControls.bind(this, false), false);
-    input.addEventListener('blur', this._validateControls.bind(this, false), false);
-    this._controlByName.set(name, input);
-    this._controls.push(input);
-    this._validators.push(validator);
-    return input;
-  }
-
-  /**
-   * @param {string} name
-   * @param {!Array<string>} options
-   * @param {function(!T, number, (!HTMLInputElement|!HTMLSelectElement)):boolean} validator
-   * @return {!HTMLSelectElement}
-   */
-  createSelect(name, options, validator) {
-    const select = /** @type {!HTMLSelectElement} */ (createElementWithClass('select', 'chrome-select'));
-    for (let index = 0; index < options.length; ++index) {
-      const option = select.createChild('option');
-      option.value = options[index];
-      option.textContent = options[index];
-    }
-    select.addEventListener('input', this._validateControls.bind(this, false), false);
-    select.addEventListener('blur', this._validateControls.bind(this, false), false);
-    this._controlByName.set(name, select);
-    this._controls.push(select);
-    this._validators.push(validator);
-    return select;
-  }
-
-  /**
-   * @param {string} name
-   * @return {!HTMLInputElement|!HTMLSelectElement}
-   */
-  control(name) {
-    return /** @type {!HTMLInputElement|!HTMLSelectElement} */ (this._controlByName.get(name));
-  }
-
-  /**
-   * @param {boolean} forceValid
-   */
-  _validateControls(forceValid) {
-    let allValid = true;
-    for (let index = 0; index < this._controls.length; ++index) {
-      const input = this._controls[index];
-      const valid = this._validators[index].call(null, this._item, this._index, input);
-      input.classList.toggle('error-input', !valid && !forceValid);
-      allValid &= valid;
-    }
-    this._commitButton.disabled = !allValid;
-  }
-
-  /**
-   * @param {!T} item
-   * @param {number} index
-   * @param {string} commitButtonTitle
-   * @param {function()} commit
-   * @param {function()} cancel
-   */
-  beginEdit(item, index, commitButtonTitle, commit, cancel) {
-    this._commit = commit;
-    this._cancel = cancel;
-    this._item = item;
-    this._index = index;
-
-    this._commitButton.textContent = commitButtonTitle;
-    this.element.scrollIntoViewIfNeeded(false);
-    if (this._controls.length)
-      this._controls[0].focus();
-    this._validateControls(true);
-  }
-
-  _commitClicked() {
-    if (this._commitButton.disabled)
-      return;
-
-    const commit = this._commit;
-    this._commit = null;
-    this._cancel = null;
-    this._item = null;
-    this._index = -1;
-    commit();
-  }
-
-  _cancelClicked() {
-    const cancel = this._cancel;
-    this._commit = null;
-    this._cancel = null;
-    this._item = null;
-    this._index = -1;
-    cancel();
-  }
-};
diff --git a/front_end/ui/Panel.js b/front_end/ui/Panel.js
deleted file mode 100644
index 3c0387a..0000000
--- a/front_end/ui/Panel.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-// For testing.
-UI.panels = {};
-
-/**
- * @unrestricted
- */
-UI.Panel = class extends UI.VBox {
-  /**
-   * @param {string} name
-   */
-  constructor(name) {
-    super();
-
-    this.element.classList.add('panel');
-    this.element.setAttribute('aria-label', name);
-    this.element.classList.add(name);
-    this._panelName = name;
-
-    // For testing.
-    UI.panels[name] = this;
-
-    this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
-  }
-
-  get name() {
-    return this._panelName;
-  }
-
-  /**
-   * @return {?UI.SearchableView}
-   */
-  searchableView() {
-    return null;
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [];
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   */
-  handleShortcut(event) {
-    const shortcutKey = UI.KeyboardShortcut.makeKeyFromEvent(event);
-    const handler = this._shortcuts[shortcutKey];
-    if (handler && handler(event))
-      event.handled = true;
-  }
-
-  /**
-   * @param {!UI.Infobar} infobar
-   */
-  showInfobar(infobar) {
-    infobar.setCloseCallback(this._onInfobarClosed.bind(this, infobar));
-    if (this.element.firstChild)
-      this.element.insertBefore(infobar.element, this.element.firstChild);
-    else
-      this.element.appendChild(infobar.element);
-    infobar.setParentView(this);
-    this.doResize();
-  }
-
-  /**
-   * @param {!UI.Infobar} infobar
-   */
-  _onInfobarClosed(infobar) {
-    infobar.element.remove();
-    this.doResize();
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.PanelWithSidebar = class extends UI.Panel {
-  /**
-   * @param {string} name
-   * @param {number=} defaultWidth
-   */
-  constructor(name, defaultWidth) {
-    super(name);
-
-    this._panelSplitWidget =
-        new UI.SplitWidget(true, false, this._panelName + 'PanelSplitViewState', defaultWidth || 200);
-    this._panelSplitWidget.show(this.element);
-
-    this._mainWidget = new UI.VBox();
-    this._panelSplitWidget.setMainWidget(this._mainWidget);
-
-    this._sidebarWidget = new UI.VBox();
-    this._sidebarWidget.setMinimumSize(100, 25);
-    this._panelSplitWidget.setSidebarWidget(this._sidebarWidget);
-
-    this._sidebarWidget.element.classList.add('panel-sidebar');
-  }
-
-  /**
-   * @return {!Element}
-   */
-  panelSidebarElement() {
-    return this._sidebarWidget.element;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  mainElement() {
-    return this._mainWidget.element;
-  }
-
-  /**
-   * @return {!UI.SplitWidget}
-   */
-  splitWidget() {
-    return this._panelSplitWidget;
-  }
-};
diff --git a/front_end/ui/Popover.js b/front_end/ui/Popover.js
deleted file mode 100644
index b8ba3bd..0000000
--- a/front_end/ui/Popover.js
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-UI.PopoverHelper = class {
-  /**
-   * @param {!Element} container
-   * @param {function(!MouseEvent):?UI.PopoverRequest} getRequest
-   */
-  constructor(container, getRequest) {
-    this._disableOnClick = false;
-    this._hasPadding = false;
-    this._getRequest = getRequest;
-    this._scheduledRequest = null;
-    /** @type {?function()} */
-    this._hidePopoverCallback = null;
-    this._container = container;
-    this._showTimeout = 0;
-    this._hideTimeout = 0;
-    /** @type {?number} */
-    this._hidePopoverTimer = null;
-    /** @type {?number} */
-    this._showPopoverTimer = null;
-    this._boundMouseDown = this._mouseDown.bind(this);
-    this._boundMouseMove = this._mouseMove.bind(this);
-    this._boundMouseOut = this._mouseOut.bind(this);
-    this._container.addEventListener('mousedown', this._boundMouseDown, false);
-    this._container.addEventListener('mousemove', this._boundMouseMove, false);
-    this._container.addEventListener('mouseout', this._boundMouseOut, false);
-    this.setTimeout(1000);
-  }
-
-  /**
-   * @param {number} showTimeout
-   * @param {number=} hideTimeout
-   */
-  setTimeout(showTimeout, hideTimeout) {
-    this._showTimeout = showTimeout;
-    this._hideTimeout = typeof hideTimeout === 'number' ? hideTimeout : showTimeout / 2;
-  }
-
-  /**
-   * @param {boolean} hasPadding
-   */
-  setHasPadding(hasPadding) {
-    this._hasPadding = hasPadding;
-  }
-
-  /**
-   * @param {boolean} disableOnClick
-   */
-  setDisableOnClick(disableOnClick) {
-    this._disableOnClick = disableOnClick;
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _eventInScheduledContent(event) {
-    return this._scheduledRequest ? this._scheduledRequest.box.contains(event.clientX, event.clientY) : false;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseDown(event) {
-    if (this._disableOnClick) {
-      this.hidePopover();
-      return;
-    }
-    if (this._eventInScheduledContent(event))
-      return;
-
-    this._startHidePopoverTimer(0);
-    this._stopShowPopoverTimer();
-    this._startShowPopoverTimer(/** @type {!MouseEvent} */ (event), 0);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseMove(event) {
-    // Pretend that nothing has happened.
-    if (this._eventInScheduledContent(event))
-      return;
-
-    this._startHidePopoverTimer(this._hideTimeout);
-    this._stopShowPopoverTimer();
-    if (event.which && this._disableOnClick)
-      return;
-    this._startShowPopoverTimer(
-        /** @type {!MouseEvent} */ (event), this.isPopoverVisible() ? this._showTimeout * 0.6 : this._showTimeout);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _popoverMouseMove(event) {
-    this._stopHidePopoverTimer();
-  }
-
-  /**
-   * @param {!UI.GlassPane} popover
-   * @param {!Event} event
-   */
-  _popoverMouseOut(popover, event) {
-    if (!popover.isShowing())
-      return;
-    if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(popover.contentElement))
-      this._startHidePopoverTimer(this._hideTimeout);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseOut(event) {
-    if (!this.isPopoverVisible())
-      return;
-    if (!this._eventInScheduledContent(event))
-      this._startHidePopoverTimer(this._hideTimeout);
-  }
-
-  /**
-   * @param {number} timeout
-   */
-  _startHidePopoverTimer(timeout) {
-    // User has |timeout| ms to reach the popup.
-    if (!this._hidePopoverCallback || this._hidePopoverTimer)
-      return;
-
-    this._hidePopoverTimer = setTimeout(() => {
-      this._hidePopover();
-      this._hidePopoverTimer = null;
-    }, timeout);
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @param {number} timeout
-   */
-  _startShowPopoverTimer(event, timeout) {
-    this._scheduledRequest = this._getRequest.call(null, event);
-    if (!this._scheduledRequest)
-      return;
-
-    this._showPopoverTimer = setTimeout(() => {
-      this._showPopoverTimer = null;
-      this._stopHidePopoverTimer();
-      this._hidePopover();
-      this._showPopover(event.target.ownerDocument);
-    }, timeout);
-  }
-
-  _stopShowPopoverTimer() {
-    if (!this._showPopoverTimer)
-      return;
-    clearTimeout(this._showPopoverTimer);
-    this._showPopoverTimer = null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isPopoverVisible() {
-    return !!this._hidePopoverCallback;
-  }
-
-  hidePopover() {
-    this._stopShowPopoverTimer();
-    this._hidePopover();
-  }
-
-  _hidePopover() {
-    if (!this._hidePopoverCallback)
-      return;
-    this._hidePopoverCallback.call(null);
-    this._hidePopoverCallback = null;
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  _showPopover(document) {
-    const popover = new UI.GlassPane();
-    popover.registerRequiredCSS('ui/popover.css');
-    popover.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    popover.setMarginBehavior(UI.GlassPane.MarginBehavior.Arrow);
-    const request = this._scheduledRequest;
-    request.show.call(null, popover).then(success => {
-      if (!success)
-        return;
-
-      if (this._scheduledRequest !== request) {
-        if (request.hide)
-          request.hide.call(null);
-        return;
-      }
-
-      // This should not happen, but we hide previous popover to be on the safe side.
-      if (UI.PopoverHelper._popoverHelper) {
-        console.error('One popover is already visible');
-        UI.PopoverHelper._popoverHelper.hidePopover();
-      }
-      UI.PopoverHelper._popoverHelper = this;
-
-      popover.contentElement.classList.toggle('has-padding', this._hasPadding);
-      popover.contentElement.addEventListener('mousemove', this._popoverMouseMove.bind(this), true);
-      popover.contentElement.addEventListener('mouseout', this._popoverMouseOut.bind(this, popover), true);
-      popover.setContentAnchorBox(request.box);
-      popover.show(document);
-
-      this._hidePopoverCallback = () => {
-        if (request.hide)
-          request.hide.call(null);
-        popover.hide();
-        delete UI.PopoverHelper._popoverHelper;
-      };
-    });
-  }
-
-  _stopHidePopoverTimer() {
-    if (!this._hidePopoverTimer)
-      return;
-    clearTimeout(this._hidePopoverTimer);
-    this._hidePopoverTimer = null;
-
-    // We know that we reached the popup, but we might have moved over other elements.
-    // Discard pending command.
-    this._stopShowPopoverTimer();
-  }
-
-  dispose() {
-    this._container.removeEventListener('mousedown', this._boundMouseDown, false);
-    this._container.removeEventListener('mousemove', this._boundMouseMove, false);
-    this._container.removeEventListener('mouseout', this._boundMouseOut, false);
-  }
-};
-
-/** @typedef {{box: !AnchorBox, show:(function(!UI.GlassPane):!Promise<boolean>), hide:(function()|undefined)}} */
-UI.PopoverRequest;
diff --git a/front_end/ui/ProgressIndicator.js b/front_end/ui/ProgressIndicator.js
deleted file mode 100644
index 2c8bb28..0000000
--- a/front_end/ui/ProgressIndicator.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Common.Progress}
- * @unrestricted
- */
-UI.ProgressIndicator = class {
-  constructor() {
-    this.element = createElementWithClass('div', 'progress-indicator');
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/progressIndicator.css');
-    this._contentElement = this._shadowRoot.createChild('div', 'progress-indicator-shadow-container');
-
-    this._labelElement = this._contentElement.createChild('div', 'title');
-    this._progressElement = this._contentElement.createChild('progress');
-    this._progressElement.value = 0;
-    this._stopButton = this._contentElement.createChild('button', 'progress-indicator-shadow-stop-button');
-    this._stopButton.addEventListener('click', this.cancel.bind(this));
-
-    this._isCanceled = false;
-    this._worked = 0;
-  }
-
-  /**
-   * @param {!Element} parent
-   */
-  show(parent) {
-    parent.appendChild(this.element);
-  }
-
-  /**
-   * @override
-   */
-  done() {
-    if (this._isDone)
-      return;
-    this._isDone = true;
-    this.element.remove();
-  }
-
-  cancel() {
-    this._isCanceled = true;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isCanceled() {
-    return this._isCanceled;
-  }
-
-  /**
-   * @override
-   * @param {string} title
-   */
-  setTitle(title) {
-    this._labelElement.textContent = title;
-  }
-
-  /**
-   * @override
-   * @param {number} totalWork
-   */
-  setTotalWork(totalWork) {
-    this._progressElement.max = totalWork;
-  }
-
-  /**
-   * @override
-   * @param {number} worked
-   * @param {string=} title
-   */
-  setWorked(worked, title) {
-    this._worked = worked;
-    this._progressElement.value = worked;
-    if (title)
-      this.setTitle(title);
-  }
-
-  /**
-   * @override
-   * @param {number=} worked
-   */
-  worked(worked) {
-    this.setWorked(this._worked + (worked || 1));
-  }
-};
diff --git a/front_end/ui/RemoteDebuggingTerminatedScreen.js b/front_end/ui/RemoteDebuggingTerminatedScreen.js
deleted file mode 100644
index 043370d..0000000
--- a/front_end/ui/RemoteDebuggingTerminatedScreen.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.RemoteDebuggingTerminatedScreen = class extends UI.VBox {
-  /**
-   * @param {string} reason
-   */
-  constructor(reason) {
-    super(true);
-    this.registerRequiredCSS('ui/remoteDebuggingTerminatedScreen.css');
-    const message = this.contentElement.createChild('div', 'message');
-    message.createChild('span').textContent = Common.UIString('Debugging connection was closed. Reason: ');
-    message.createChild('span', 'reason').textContent = reason;
-    this.contentElement.createChild('div', 'message').textContent =
-        Common.UIString('Reconnect when ready by reopening DevTools.');
-    const button = UI.createTextButton(Common.UIString('Reconnect DevTools'), () => window.location.reload());
-    this.contentElement.createChild('div', 'button').appendChild(button);
-  }
-
-  /**
-   * @param {string} reason
-   */
-  static show(reason) {
-    const dialog = new UI.Dialog();
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.addCloseButton();
-    dialog.setDimmed(true);
-    new UI.RemoteDebuggingTerminatedScreen(reason).show(dialog.contentElement);
-    dialog.show();
-  }
-};
diff --git a/front_end/ui/ReportView.js b/front_end/ui/ReportView.js
deleted file mode 100644
index 462bc23..0000000
--- a/front_end/ui/ReportView.js
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ReportView = class extends UI.VBox {
-  /**
-   * @param {string=} title
-   */
-  constructor(title) {
-    super(true);
-    this.registerRequiredCSS('ui/reportView.css');
-
-    this._contentBox = this.contentElement.createChild('div', 'report-content-box');
-    this._headerElement = this._contentBox.createChild('div', 'report-header vbox');
-    this._titleElement = this._headerElement.createChild('div', 'report-title');
-    this._titleElement.textContent = title;
-
-    this._sectionList = this._contentBox.createChild('div', 'vbox');
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    if (this._titleElement.textContent === title)
-      return;
-    this._titleElement.textContent = title;
-  }
-
-  /**
-   * @param {string} subtitle
-   */
-  setSubtitle(subtitle) {
-    if (this._subtitleElement && this._subtitleElement.textContent === subtitle)
-      return;
-    if (!this._subtitleElement)
-      this._subtitleElement = this._headerElement.createChild('div', 'report-subtitle');
-    this._subtitleElement.textContent = subtitle;
-  }
-
-  /**
-   * @param {?Element} link
-   */
-  setURL(link) {
-    if (!this._urlElement)
-      this._urlElement = this._headerElement.createChild('div', 'report-url link');
-    this._urlElement.removeChildren();
-    if (link)
-      this._urlElement.appendChild(link);
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  createToolbar() {
-    const toolbar = new UI.Toolbar('');
-    this._headerElement.appendChild(toolbar.element);
-    return toolbar;
-  }
-
-  /**
-   * @param {string} title
-   * @param {string=} className
-   * @return {!UI.ReportView.Section}
-   */
-  appendSection(title, className) {
-    const section = new UI.ReportView.Section(title, className);
-    section.show(this._sectionList);
-    return section;
-  }
-
-  /**
-   * @param {function(!UI.ReportView.Section, !UI.ReportView.Section): number} comparator
-   */
-  sortSections(comparator) {
-    const sections = /** @type {!Array<!UI.ReportView.Section>} */ (this.children().slice());
-    const sorted = sections.every((e, i, a) => !i || comparator(a[i - 1], a[i]) <= 0);
-    if (sorted)
-      return;
-
-    this.detachChildWidgets();
-    sections.sort(comparator);
-    for (const section of sections)
-      section.show(this._sectionList);
-  }
-
-  /**
-   * @param {boolean} visible
-   */
-  setHeaderVisible(visible) {
-    this._headerElement.classList.toggle('hidden', !visible);
-  }
-
-
-  /**
-   * @param {boolean} scrollable
-   */
-  setBodyScrollable(scrollable) {
-    this._contentBox.classList.toggle('no-scroll', !scrollable);
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ReportView.Section = class extends UI.VBox {
-  /**
-   * @param {string} title
-   * @param {string=} className
-   */
-  constructor(title, className) {
-    super();
-    this.element.classList.add('report-section');
-    if (className)
-      this.element.classList.add(className);
-    this._headerElement = this.element.createChild('div', 'report-section-header');
-    this._titleElement = this._headerElement.createChild('div', 'report-section-title');
-    this._titleElement.textContent = title;
-    this._fieldList = this.element.createChild('div', 'vbox');
-    /** @type {!Map.<string, !Element>} */
-    this._fieldMap = new Map();
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._titleElement.textContent;
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    if (this._titleElement.textContent !== title)
-      this._titleElement.textContent = title;
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  createToolbar() {
-    const toolbar = new UI.Toolbar('');
-    this._headerElement.appendChild(toolbar.element);
-    return toolbar;
-  }
-
-  /**
-   * @param {string} title
-   * @param {string=} textValue
-   * @return {!Element}
-   */
-  appendField(title, textValue) {
-    let row = this._fieldMap.get(title);
-    if (!row) {
-      row = this._fieldList.createChild('div', 'report-field');
-      row.createChild('div', 'report-field-name').textContent = title;
-      this._fieldMap.set(title, row);
-      row.createChild('div', 'report-field-value');
-    }
-    if (textValue)
-      row.lastElementChild.textContent = textValue;
-    return /** @type {!Element} */ (row.lastElementChild);
-  }
-
-  /**
-   * @param {string} title
-   */
-  removeField(title) {
-    const row = this._fieldMap.get(title);
-    if (row)
-      row.remove();
-    this._fieldMap.delete(title);
-  }
-
-  /**
-   * @param {string} title
-   * @param {boolean} visible
-   */
-  setFieldVisible(title, visible) {
-    const row = this._fieldMap.get(title);
-    if (row)
-      row.classList.toggle('hidden', !visible);
-  }
-
-  /**
-   * @param {string} title
-   * @return {?Element}
-   */
-  fieldValue(title) {
-    const row = this._fieldMap.get(title);
-    return row ? row.lastElementChild : null;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  appendRow() {
-    return this._fieldList.createChild('div', 'report-row');
-  }
-
-  clearContent() {
-    this._fieldList.removeChildren();
-    this._fieldMap.clear();
-  }
-};
diff --git a/front_end/ui/ResizerWidget.js b/front_end/ui/ResizerWidget.js
deleted file mode 100644
index 6e3fbb3..0000000
--- a/front_end/ui/ResizerWidget.js
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ResizerWidget = class extends Common.Object {
-  constructor() {
-    super();
-
-    this._isEnabled = true;
-    this._elements = [];
-    this._installDragOnMouseDownBound = this._installDragOnMouseDown.bind(this);
-    this._cursor = 'nwse-resize';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEnabled() {
-    return this._isEnabled;
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._isEnabled = enabled;
-    this.updateElementCursors();
-  }
-
-  /**
-   * @return {!Array.<!Element>}
-   */
-  elements() {
-    return this._elements.slice();
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  addElement(element) {
-    if (this._elements.indexOf(element) !== -1)
-      return;
-
-    this._elements.push(element);
-    element.addEventListener('mousedown', this._installDragOnMouseDownBound, false);
-    this._updateElementCursor(element);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  removeElement(element) {
-    if (this._elements.indexOf(element) === -1)
-      return;
-
-    this._elements.remove(element);
-    element.removeEventListener('mousedown', this._installDragOnMouseDownBound, false);
-    element.style.removeProperty('cursor');
-  }
-
-  updateElementCursors() {
-    this._elements.forEach(this._updateElementCursor.bind(this));
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  _updateElementCursor(element) {
-    if (this._isEnabled)
-      element.style.setProperty('cursor', this.cursor());
-    else
-      element.style.removeProperty('cursor');
-  }
-
-  /**
-   * @return {string}
-   */
-  cursor() {
-    return this._cursor;
-  }
-
-  /**
-   * @param {string} cursor
-   */
-  setCursor(cursor) {
-    this._cursor = cursor;
-    this.updateElementCursors();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _installDragOnMouseDown(event) {
-    // Only handle drags of the nodes specified.
-    if (this._elements.indexOf(event.target) === -1)
-      return false;
-    UI.elementDragStart(
-        /** @type {!Element} */ (event.target), this._dragStart.bind(this), this._drag.bind(this),
-        this._dragEnd.bind(this), this.cursor(), event);
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _dragStart(event) {
-    if (!this._isEnabled)
-      return false;
-    this._startX = event.pageX;
-    this._startY = event.pageY;
-    this.sendDragStart(this._startX, this._startY);
-    return true;
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   */
-  sendDragStart(x, y) {
-    this.dispatchEventToListeners(
-        UI.ResizerWidget.Events.ResizeStart, {startX: x, currentX: x, startY: y, currentY: y});
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   * @return {boolean}
-   */
-  _drag(event) {
-    if (!this._isEnabled) {
-      this._dragEnd(event);
-      return true;  // Cancel drag.
-    }
-
-    this.sendDragMove(this._startX, event.pageX, this._startY, event.pageY, event.shiftKey);
-    event.preventDefault();
-    return false;  // Continue drag.
-  }
-
-  /**
-   * @param {number} startX
-   * @param {number} currentX
-   * @param {number} startY
-   * @param {number} currentY
-   * @param {boolean} shiftKey
-   */
-  sendDragMove(startX, currentX, startY, currentY, shiftKey) {
-    this.dispatchEventToListeners(
-        UI.ResizerWidget.Events.ResizeUpdate,
-        {startX: startX, currentX: currentX, startY: startY, currentY: currentY, shiftKey: shiftKey});
-  }
-
-  /**
-   * @param {!MouseEvent} event
-   */
-  _dragEnd(event) {
-    this.dispatchEventToListeners(UI.ResizerWidget.Events.ResizeEnd);
-    delete this._startX;
-    delete this._startY;
-  }
-};
-
-/** @enum {symbol} */
-UI.ResizerWidget.Events = {
-  ResizeStart: Symbol('ResizeStart'),
-  ResizeUpdate: Symbol('ResizeUpdate'),
-  ResizeEnd: Symbol('ResizeEnd')
-};
-
-/**
- * @unrestricted
- */
-UI.SimpleResizerWidget = class extends UI.ResizerWidget {
-  constructor() {
-    super();
-    this._isVertical = true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isVertical() {
-    return this._isVertical;
-  }
-
-  /**
-   * Vertical widget resizes height (along y-axis).
-   * @param {boolean} vertical
-   */
-  setVertical(vertical) {
-    this._isVertical = vertical;
-    this.updateElementCursors();
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  cursor() {
-    return this._isVertical ? 'ns-resize' : 'ew-resize';
-  }
-
-  /**
-   * @override
-   * @param {number} x
-   * @param {number} y
-   */
-  sendDragStart(x, y) {
-    const position = this._isVertical ? y : x;
-    this.dispatchEventToListeners(
-        UI.ResizerWidget.Events.ResizeStart, {startPosition: position, currentPosition: position});
-  }
-
-  /**
-   * @override
-   * @param {number} startX
-   * @param {number} currentX
-   * @param {number} startY
-   * @param {number} currentY
-   * @param {boolean} shiftKey
-   */
-  sendDragMove(startX, currentX, startY, currentY, shiftKey) {
-    if (this._isVertical) {
-      this.dispatchEventToListeners(
-          UI.ResizerWidget.Events.ResizeUpdate, {startPosition: startY, currentPosition: currentY, shiftKey: shiftKey});
-    } else {
-      this.dispatchEventToListeners(
-          UI.ResizerWidget.Events.ResizeUpdate, {startPosition: startX, currentPosition: currentX, shiftKey: shiftKey});
-    }
-  }
-};
diff --git a/front_end/ui/RootView.js b/front_end/ui/RootView.js
deleted file mode 100644
index f6f361b..0000000
--- a/front_end/ui/RootView.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.RootView = class extends UI.VBox {
-  constructor() {
-    super();
-    this.markAsRoot();
-    this.element.classList.add('root-view');
-    this.registerRequiredCSS('ui/rootView.css');
-    this.element.setAttribute('spellcheck', false);
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  attachToDocument(document) {
-    document.defaultView.addEventListener('resize', this.doResize.bind(this), false);
-    this._window = document.defaultView;
-    this.doResize();
-    this.show(/** @type {!Element} */ (document.body));
-  }
-
-  /**
-   * @override
-   */
-  doResize() {
-    if (this._window) {
-      const size = this.constraints().minimum;
-      const zoom = UI.zoomManager.zoomFactor();
-      const right = Math.min(0, this._window.innerWidth - size.width / zoom);
-      this.element.style.marginRight = right + 'px';
-      const bottom = Math.min(0, this._window.innerHeight - size.height / zoom);
-      this.element.style.marginBottom = bottom + 'px';
-    }
-    super.doResize();
-  }
-};
diff --git a/front_end/ui/SearchableView.js b/front_end/ui/SearchableView.js
deleted file mode 100644
index a0fa78f..0000000
--- a/front_end/ui/SearchableView.js
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.SearchableView = class extends UI.VBox {
-  /**
-   * @param {!UI.Searchable} searchable
-   * @param {string=} settingName
-   */
-  constructor(searchable, settingName) {
-    super(true);
-    this.registerRequiredCSS('ui/searchableView.css');
-    this.element[UI.SearchableView._symbol] = this;
-
-    this._searchProvider = searchable;
-    this._setting = settingName ? Common.settings.createSetting(settingName, {}) : null;
-    this._replaceable = false;
-
-    this.contentElement.createChild('content');
-    this._footerElementContainer = this.contentElement.createChild('div', 'search-bar hidden');
-    this._footerElementContainer.style.order = 100;
-    this._footerElement = this._footerElementContainer.createChild('div', 'toolbar-search');
-
-    const replaceToggleToolbar = new UI.Toolbar('replace-toggle-toolbar', this._footerElement);
-    this._replaceToggleButton = new UI.ToolbarToggle(Common.UIString('Replace'), 'mediumicon-replace');
-    this._replaceToggleButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleReplace, this);
-    replaceToggleToolbar.appendToolbarItem(this._replaceToggleButton);
-
-    const searchInputElements = this._footerElement.createChild('div', 'toolbar-search-inputs');
-    const searchControlElement = searchInputElements.createChild('div', 'toolbar-search-control');
-
-    this._searchInputElement = UI.HistoryInput.create();
-    this._searchInputElement.classList.add('search-replace');
-    this._searchInputElement.id = 'search-input-field';
-    this._searchInputElement.placeholder = Common.UIString('Find');
-    searchControlElement.appendChild(this._searchInputElement);
-
-    this._matchesElement = searchControlElement.createChild('label', 'search-results-matches');
-    this._matchesElement.setAttribute('for', 'search-input-field');
-
-    const searchNavigationElement = searchControlElement.createChild('div', 'toolbar-search-navigation-controls');
-
-    this._searchNavigationPrevElement =
-        searchNavigationElement.createChild('div', 'toolbar-search-navigation toolbar-search-navigation-prev');
-    this._searchNavigationPrevElement.addEventListener('click', this._onPrevButtonSearch.bind(this), false);
-    this._searchNavigationPrevElement.title = Common.UIString('Search previous');
-
-    this._searchNavigationNextElement =
-        searchNavigationElement.createChild('div', 'toolbar-search-navigation toolbar-search-navigation-next');
-    this._searchNavigationNextElement.addEventListener('click', this._onNextButtonSearch.bind(this), false);
-    this._searchNavigationNextElement.title = Common.UIString('Search next');
-
-    this._searchInputElement.addEventListener('keydown', this._onSearchKeyDown.bind(this), true);
-    this._searchInputElement.addEventListener('input', this._onInput.bind(this), false);
-
-    this._replaceInputElement =
-        searchInputElements.createChild('input', 'search-replace toolbar-replace-control hidden');
-    this._replaceInputElement.addEventListener('keydown', this._onReplaceKeyDown.bind(this), true);
-    this._replaceInputElement.placeholder = Common.UIString('Replace');
-
-    this._buttonsContainer = this._footerElement.createChild('div', 'toolbar-search-buttons');
-    const firstRowButtons = this._buttonsContainer.createChild('div', 'first-row-buttons');
-
-    const toolbar = new UI.Toolbar('toolbar-search-options', firstRowButtons);
-
-    if (this._searchProvider.supportsCaseSensitiveSearch()) {
-      this._caseSensitiveButton = new UI.ToolbarToggle(Common.UIString('Match Case'));
-      this._caseSensitiveButton.setText('Aa');
-      this._caseSensitiveButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleCaseSensitiveSearch, this);
-      toolbar.appendToolbarItem(this._caseSensitiveButton);
-    }
-
-    if (this._searchProvider.supportsRegexSearch()) {
-      this._regexButton = new UI.ToolbarToggle(Common.UIString('Use Regular Expression'));
-      this._regexButton.setText('.*');
-      this._regexButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleRegexSearch, this);
-      toolbar.appendToolbarItem(this._regexButton);
-    }
-
-    const cancelButtonElement =
-        UI.createTextButton(Common.UIString('Cancel'), this.closeSearch.bind(this), 'search-action-button');
-    firstRowButtons.appendChild(cancelButtonElement);
-
-    this._secondRowButtons = this._buttonsContainer.createChild('div', 'second-row-buttons hidden');
-
-    this._replaceButtonElement =
-        UI.createTextButton(Common.UIString('Replace'), this._replace.bind(this), 'search-action-button');
-    this._replaceButtonElement.disabled = true;
-    this._secondRowButtons.appendChild(this._replaceButtonElement);
-
-    this._replaceAllButtonElement =
-        UI.createTextButton(Common.UIString('Replace all'), this._replaceAll.bind(this), 'search-action-button');
-    this._secondRowButtons.appendChild(this._replaceAllButtonElement);
-    this._replaceAllButtonElement.disabled = true;
-
-    this._minimalSearchQuerySize = 3;
-    this._loadSetting();
-  }
-
-  /**
-   * @param {?Element} element
-   * @return {?UI.SearchableView}
-   */
-  static fromElement(element) {
-    let view = null;
-    while (element && !view) {
-      view = element[UI.SearchableView._symbol];
-      element = element.parentElementOrShadowHost();
-    }
-    return view;
-  }
-
-  _toggleCaseSensitiveSearch() {
-    this._caseSensitiveButton.setToggled(!this._caseSensitiveButton.toggled());
-    this._saveSetting();
-    this._performSearch(false, true);
-  }
-
-  _toggleRegexSearch() {
-    this._regexButton.setToggled(!this._regexButton.toggled());
-    this._saveSetting();
-    this._performSearch(false, true);
-  }
-
-  _toggleReplace() {
-    this._replaceToggleButton.setToggled(!this._replaceToggleButton.toggled());
-    this._updateSecondRowVisibility();
-  }
-
-  _saveSetting() {
-    if (!this._setting)
-      return;
-    const settingValue = this._setting.get() || {};
-    settingValue.caseSensitive = this._caseSensitiveButton.toggled();
-    settingValue.isRegex = this._regexButton.toggled();
-    this._setting.set(settingValue);
-  }
-
-  _loadSetting() {
-    const settingValue = this._setting ? (this._setting.get() || {}) : {};
-    if (this._searchProvider.supportsCaseSensitiveSearch())
-      this._caseSensitiveButton.setToggled(!!settingValue.caseSensitive);
-    if (this._searchProvider.supportsRegexSearch())
-      this._regexButton.setToggled(!!settingValue.isRegex);
-  }
-
-  /**
-   * @param {number} minimalSearchQuerySize
-   */
-  setMinimalSearchQuerySize(minimalSearchQuerySize) {
-    this._minimalSearchQuerySize = minimalSearchQuerySize;
-  }
-
-  /**
-   * @param {string} placeholder
-   */
-  setPlaceholder(placeholder) {
-    this._searchInputElement.placeholder = placeholder;
-  }
-
-  /**
-   * @param {boolean} replaceable
-   */
-  setReplaceable(replaceable) {
-    this._replaceable = replaceable;
-  }
-
-  /**
-   * @param {number} matches
-   */
-  updateSearchMatchesCount(matches) {
-    if (this._searchProvider.currentSearchMatches === matches)
-      return;
-    this._searchProvider.currentSearchMatches = matches;
-    this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentQuery ? matches : 0, -1);
-  }
-
-  /**
-   * @param {number} currentMatchIndex
-   */
-  updateCurrentMatchIndex(currentMatchIndex) {
-    this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentSearchMatches, currentMatchIndex);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isSearchVisible() {
-    return this._searchIsVisible;
-  }
-
-  closeSearch() {
-    this.cancelSearch();
-    if (this._footerElementContainer.hasFocus())
-      this.focus();
-  }
-
-  _toggleSearchBar(toggled) {
-    this._footerElementContainer.classList.toggle('hidden', !toggled);
-    this.doResize();
-  }
-
-  cancelSearch() {
-    if (!this._searchIsVisible)
-      return;
-    this.resetSearch();
-    delete this._searchIsVisible;
-    this._toggleSearchBar(false);
-  }
-
-  resetSearch() {
-    this._clearSearch();
-    this._updateReplaceVisibility();
-    this._matchesElement.textContent = '';
-  }
-
-  refreshSearch() {
-    if (!this._searchIsVisible)
-      return;
-    this.resetSearch();
-    this._performSearch(false, false);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  handleFindNextShortcut() {
-    if (!this._searchIsVisible)
-      return false;
-    this._searchProvider.jumpToNextSearchResult();
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  handleFindPreviousShortcut() {
-    if (!this._searchIsVisible)
-      return false;
-    this._searchProvider.jumpToPreviousSearchResult();
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  handleFindShortcut() {
-    this.showSearchField();
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  handleCancelSearchShortcut() {
-    if (!this._searchIsVisible)
-      return false;
-    this.closeSearch();
-    return true;
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  _updateSearchNavigationButtonState(enabled) {
-    this._replaceButtonElement.disabled = !enabled;
-    this._replaceAllButtonElement.disabled = !enabled;
-    this._searchNavigationPrevElement.classList.toggle('enabled', enabled);
-    this._searchNavigationNextElement.classList.toggle('enabled', enabled);
-  }
-
-  /**
-   * @param {number} matches
-   * @param {number} currentMatchIndex
-   */
-  _updateSearchMatchesCountAndCurrentMatchIndex(matches, currentMatchIndex) {
-    if (!this._currentQuery)
-      this._matchesElement.textContent = '';
-    else if (matches === 0 || currentMatchIndex >= 0)
-      this._matchesElement.textContent = Common.UIString('%d of %d', currentMatchIndex + 1, matches);
-    else if (matches === 1)
-      this._matchesElement.textContent = Common.UIString('1 match');
-    else
-      this._matchesElement.textContent = Common.UIString('%d matches', matches);
-    this._updateSearchNavigationButtonState(matches > 0);
-  }
-
-  showSearchField() {
-    if (this._searchIsVisible)
-      this.cancelSearch();
-
-    let queryCandidate;
-    if (!this._searchInputElement.hasFocus()) {
-      const selection = UI.inspectorView.element.window().getSelection();
-      if (selection.rangeCount)
-        queryCandidate = selection.toString().replace(/\r?\n.*/, '');
-    }
-
-    this._toggleSearchBar(true);
-    this._updateReplaceVisibility();
-    if (queryCandidate)
-      this._searchInputElement.value = queryCandidate;
-    this._performSearch(false, false);
-    this._searchInputElement.focus();
-    this._searchInputElement.select();
-    this._searchIsVisible = true;
-  }
-
-  _updateReplaceVisibility() {
-    this._replaceToggleButton.setVisible(this._replaceable);
-    if (!this._replaceable) {
-      this._replaceToggleButton.setToggled(false);
-      this._updateSecondRowVisibility();
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onSearchKeyDown(event) {
-    if (isEscKey(event)) {
-      this.closeSearch();
-      event.consume(true);
-      return;
-    }
-    if (!isEnterKey(event))
-      return;
-
-    if (!this._currentQuery)
-      this._performSearch(true, true, event.shiftKey);
-    else
-      this._jumpToNextSearchResult(event.shiftKey);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onReplaceKeyDown(event) {
-    if (isEnterKey(event))
-      this._replace();
-  }
-
-  /**
-   * @param {boolean=} isBackwardSearch
-   */
-  _jumpToNextSearchResult(isBackwardSearch) {
-    if (!this._currentQuery || !this._searchNavigationPrevElement.classList.contains('enabled'))
-      return;
-
-    if (isBackwardSearch)
-      this._searchProvider.jumpToPreviousSearchResult();
-    else
-      this._searchProvider.jumpToNextSearchResult();
-  }
-
-  _onNextButtonSearch(event) {
-    if (!this._searchNavigationNextElement.classList.contains('enabled'))
-      return;
-    this._jumpToNextSearchResult();
-    this._searchInputElement.focus();
-  }
-
-  _onPrevButtonSearch(event) {
-    if (!this._searchNavigationPrevElement.classList.contains('enabled'))
-      return;
-    this._jumpToNextSearchResult(true);
-    this._searchInputElement.focus();
-  }
-
-  _onFindClick(event) {
-    if (!this._currentQuery)
-      this._performSearch(true, true);
-    else
-      this._jumpToNextSearchResult();
-    this._searchInputElement.focus();
-  }
-
-  _onPreviousClick(event) {
-    if (!this._currentQuery)
-      this._performSearch(true, true, true);
-    else
-      this._jumpToNextSearchResult(true);
-    this._searchInputElement.focus();
-  }
-
-  _clearSearch() {
-    delete this._currentQuery;
-    if (!!this._searchProvider.currentQuery) {
-      delete this._searchProvider.currentQuery;
-      this._searchProvider.searchCanceled();
-    }
-    this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1);
-  }
-
-  /**
-   * @param {boolean} forceSearch
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  _performSearch(forceSearch, shouldJump, jumpBackwards) {
-    const query = this._searchInputElement.value;
-    if (!query || (!forceSearch && query.length < this._minimalSearchQuerySize && !this._currentQuery)) {
-      this._clearSearch();
-      return;
-    }
-
-    this._currentQuery = query;
-    this._searchProvider.currentQuery = query;
-
-    const searchConfig = this._currentSearchConfig();
-    this._searchProvider.performSearch(searchConfig, shouldJump, jumpBackwards);
-  }
-
-  /**
-   * @return {!UI.SearchableView.SearchConfig}
-   */
-  _currentSearchConfig() {
-    const query = this._searchInputElement.value;
-    const caseSensitive = this._caseSensitiveButton ? this._caseSensitiveButton.toggled() : false;
-    const isRegex = this._regexButton ? this._regexButton.toggled() : false;
-    return new UI.SearchableView.SearchConfig(query, caseSensitive, isRegex);
-  }
-
-  _updateSecondRowVisibility() {
-    const secondRowVisible = this._replaceToggleButton.toggled();
-    this._footerElementContainer.classList.toggle('replaceable', secondRowVisible);
-    this._secondRowButtons.classList.toggle('hidden', !secondRowVisible);
-    this._replaceInputElement.classList.toggle('hidden', !secondRowVisible);
-
-    if (secondRowVisible)
-      this._replaceInputElement.focus();
-    else
-      this._searchInputElement.focus();
-    this.doResize();
-  }
-
-  _replace() {
-    const searchConfig = this._currentSearchConfig();
-    /** @type {!UI.Replaceable} */ (this._searchProvider)
-        .replaceSelectionWith(searchConfig, this._replaceInputElement.value);
-    delete this._currentQuery;
-    this._performSearch(true, true);
-  }
-
-  _replaceAll() {
-    const searchConfig = this._currentSearchConfig();
-    /** @type {!UI.Replaceable} */ (this._searchProvider).replaceAllWith(searchConfig, this._replaceInputElement.value);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onInput(event) {
-    if (this._valueChangedTimeoutId)
-      clearTimeout(this._valueChangedTimeoutId);
-    const timeout = this._searchInputElement.value.length < 3 ? 200 : 0;
-    this._valueChangedTimeoutId = setTimeout(this._onValueChanged.bind(this), timeout);
-  }
-
-  _onValueChanged() {
-    if (!this._searchIsVisible)
-      return;
-    delete this._valueChangedTimeoutId;
-    this._performSearch(false, true);
-  }
-};
-
-
-UI.SearchableView._symbol = Symbol('searchableView');
-
-
-/**
- * @interface
- */
-UI.Searchable = function() {};
-
-UI.Searchable.prototype = {
-  searchCanceled() {},
-
-  /**
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {},
-
-  jumpToNextSearchResult() {},
-
-  jumpToPreviousSearchResult() {},
-
-  /**
-   * @return {boolean}
-   */
-  supportsCaseSensitiveSearch() {},
-
-  /**
-   * @return {boolean}
-   */
-  supportsRegexSearch() {}
-};
-
-/**
- * @interface
- */
-UI.Replaceable = function() {};
-
-UI.Replaceable.prototype = {
-  /**
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {string} replacement
-   */
-  replaceSelectionWith(searchConfig, replacement) {},
-
-  /**
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {string} replacement
-   */
-  replaceAllWith(searchConfig, replacement) {}
-};
-
-/**
- * @unrestricted
- */
-UI.SearchableView.SearchConfig = class {
-  /**
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   */
-  constructor(query, caseSensitive, isRegex) {
-    this.query = query;
-    this.caseSensitive = caseSensitive;
-    this.isRegex = isRegex;
-  }
-
-  /**
-   * @param {boolean=} global
-   * @return {!RegExp}
-   */
-  toSearchRegex(global) {
-    let modifiers = this.caseSensitive ? '' : 'i';
-    if (global)
-      modifiers += 'g';
-    const query = this.isRegex ? '/' + this.query + '/' : this.query;
-
-    let regex;
-
-    // First try creating regex if user knows the / / hint.
-    try {
-      if (/^\/.+\/$/.test(query)) {
-        regex = new RegExp(query.substring(1, query.length - 1), modifiers);
-        regex.__fromRegExpQuery = true;
-      }
-    } catch (e) {
-      // Silent catch.
-    }
-
-    // Otherwise just do a plain text search.
-    if (!regex)
-      regex = createPlainTextSearchRegex(query, modifiers);
-
-    return regex;
-  }
-};
diff --git a/front_end/ui/SegmentedButton.js b/front_end/ui/SegmentedButton.js
deleted file mode 100644
index 194ee18..0000000
--- a/front_end/ui/SegmentedButton.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.SegmentedButton = class extends UI.HBox {
-  constructor() {
-    super(true);
-    /** @type {!Map<string, !Element>} */
-    this._buttons = new Map();
-
-    /** @type {?string} */
-    this._selected = null;
-    this.registerRequiredCSS('ui/segmentedButton.css');
-    this.contentElement.classList.add('segmented-button');
-  }
-
-  /**
-   * @param {string} label
-   * @param {string} value
-   * @param {string=} tooltip
-   */
-  addSegment(label, value, tooltip) {
-    const button = this.contentElement.createChild('button', 'segmented-button-segment');
-    button.textContent = label;
-    button.title = tooltip;
-    this._buttons.set(value, button);
-    button.addEventListener('click', () => this.select(value));
-  }
-
-  /**
-   * @param {string} value
-   */
-  select(value) {
-    if (this._selected === value)
-      return;
-    this._selected = value;
-    for (const key of this._buttons.keys())
-      this._buttons.get(key).classList.toggle('segmented-button-segment-selected', key === this._selected);
-  }
-
-  /**
-   * @return {?string}
-   */
-  selected() {
-    return this._selected;
-  }
-};
diff --git a/front_end/ui/SettingsUI.js b/front_end/ui/SettingsUI.js
deleted file mode 100644
index 8a78ab7..0000000
--- a/front_end/ui/SettingsUI.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-UI.SettingsUI = {};
-
-/**
- * @param {string} name
- * @param {!Common.Setting} setting
- * @param {boolean=} omitParagraphElement
- * @param {string=} tooltip
- * @return {!Element}
- */
-UI.SettingsUI.createSettingCheckbox = function(name, setting, omitParagraphElement, tooltip) {
-  const label = UI.CheckboxLabel.create(name);
-  if (tooltip)
-    label.title = tooltip;
-
-  const input = label.checkboxElement;
-  input.name = name;
-  UI.SettingsUI.bindCheckbox(input, setting);
-
-  if (omitParagraphElement)
-    return label;
-
-  const p = createElement('p');
-  p.appendChild(label);
-  return p;
-};
-
-/**
- * @param {string} name
- * @param {!Array<!{text: string, value: *, raw: (boolean|undefined)}>} options
- * @param {!Common.Setting} setting
- * @return {!Element}
- */
-UI.SettingsUI.createSettingSelect = function(name, options, setting) {
-  const p = createElement('p');
-  p.createChild('label').textContent = name;
-  const select = p.createChild('select', 'chrome-select');
-
-  for (let i = 0; i < options.length; ++i) {
-    // The "raw" flag indicates text is non-i18n-izable.
-    const option = options[i];
-    const optionName = option.raw ? option.text : Common.UIString(option.text);
-    select.add(new Option(optionName, option.value));
-  }
-
-  setting.addChangeListener(settingChanged);
-  settingChanged();
-  select.addEventListener('change', selectChanged, false);
-  return p;
-
-  function settingChanged() {
-    const newValue = setting.get();
-    for (let i = 0; i < options.length; i++) {
-      if (options[i].value === newValue)
-        select.selectedIndex = i;
-    }
-  }
-
-  function selectChanged() {
-    // Don't use event.target.value to avoid conversion of the value to string.
-    setting.set(options[select.selectedIndex].value);
-  }
-};
-
-/**
- * @param {!Element} input
- * @param {!Common.Setting} setting
- */
-UI.SettingsUI.bindCheckbox = function(input, setting) {
-  function settingChanged() {
-    if (input.checked !== setting.get())
-      input.checked = setting.get();
-  }
-  setting.addChangeListener(settingChanged);
-  settingChanged();
-
-  function inputChanged() {
-    if (setting.get() !== input.checked)
-      setting.set(input.checked);
-  }
-  input.addEventListener('change', inputChanged, false);
-};
-
-/**
- * @param {string} name
- * @param {!Element} element
- * @return {!Element}
- */
-UI.SettingsUI.createCustomSetting = function(name, element) {
-  const p = createElement('p');
-  const fieldsetElement = p.createChild('fieldset');
-  fieldsetElement.createChild('label').textContent = name;
-  fieldsetElement.appendChild(element);
-  return p;
-};
-
-/**
- * @param {!Common.Setting} setting
- * @return {?Element}
- */
-UI.SettingsUI.createControlForSetting = function(setting) {
-  if (!setting.extension())
-    return null;
-  const descriptor = setting.extension().descriptor();
-  const uiTitle = Common.UIString(setting.title() || '');
-  switch (descriptor['settingType']) {
-    case 'boolean':
-      return UI.SettingsUI.createSettingCheckbox(uiTitle, setting);
-    case 'enum':
-      if (Array.isArray(descriptor['options']))
-        return UI.SettingsUI.createSettingSelect(uiTitle, descriptor['options'], setting);
-      console.error('Enum setting defined without options');
-      return null;
-    default:
-      console.error('Invalid setting type: ' + descriptor['settingType']);
-      return null;
-  }
-};
-
-/**
- * @interface
- */
-UI.SettingUI = function() {};
-
-UI.SettingUI.prototype = {
-  /**
-   * @return {?Element}
-   */
-  settingElement() {}
-};
diff --git a/front_end/ui/ShortcutRegistry.js b/front_end/ui/ShortcutRegistry.js
deleted file mode 100644
index ae30dc1..0000000
--- a/front_end/ui/ShortcutRegistry.js
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ShortcutRegistry = class {
-  /**
-   * @param {!UI.ActionRegistry} actionRegistry
-   * @param {!Document} document
-   */
-  constructor(actionRegistry, document) {
-    this._actionRegistry = actionRegistry;
-    /** @type {!Multimap.<string, string>} */
-    this._defaultKeyToActions = new Multimap();
-    /** @type {!Multimap.<string, !UI.KeyboardShortcut.Descriptor>} */
-    this._defaultActionToShortcut = new Multimap();
-    this._registerBindings(document);
-  }
-
-  /**
-   * @param {number} key
-   * @return {!Array.<!UI.Action>}
-   */
-  _applicableActions(key) {
-    return this._actionRegistry.applicableActions(this._defaultActionsForKey(key).valuesArray(), UI.context);
-  }
-
-  /**
-   * @param {number} key
-   * @return {!Set.<string>}
-   */
-  _defaultActionsForKey(key) {
-    return this._defaultKeyToActions.get(String(key));
-  }
-
-  /**
-   * @param {string} actionId
-   * @return {!Array.<!UI.KeyboardShortcut.Descriptor>}
-   */
-  shortcutDescriptorsForAction(actionId) {
-    return this._defaultActionToShortcut.get(actionId).valuesArray();
-  }
-
-  /**
-   * @param {!Array.<string>} actionIds
-   * @return {!Array.<number>}
-   */
-  keysForActions(actionIds) {
-    const result = [];
-    for (let i = 0; i < actionIds.length; ++i) {
-      const descriptors = this.shortcutDescriptorsForAction(actionIds[i]);
-      for (let j = 0; j < descriptors.length; ++j)
-        result.push(descriptors[j].key);
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} actionId
-   * @return {string|undefined}
-   */
-  shortcutTitleForAction(actionId) {
-    const descriptors = this.shortcutDescriptorsForAction(actionId);
-    if (descriptors.length)
-      return descriptors[0].name;
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   */
-  handleShortcut(event) {
-    this.handleKey(UI.KeyboardShortcut.makeKeyFromEvent(event), event.key, event);
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  eventMatchesAction(event, actionId) {
-    console.assert(this._defaultActionToShortcut.has(actionId), 'Unknown action ' + actionId);
-    const key = UI.KeyboardShortcut.makeKeyFromEvent(event);
-    return this._defaultActionToShortcut.get(actionId).valuesArray().some(descriptor => descriptor.key === key);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {string} actionId
-   * @param {function():boolean} listener
-   * @param {boolean=} capture
-   */
-  addShortcutListener(element, actionId, listener, capture) {
-    console.assert(this._defaultActionToShortcut.has(actionId), 'Unknown action ' + actionId);
-    element.addEventListener('keydown', event => {
-      if (!this.eventMatchesAction(/** @type {!KeyboardEvent} */ (event), actionId) || !listener.call(null))
-        return;
-      event.consume(true);
-    }, capture);
-  }
-
-  /**
-   * @param {number} key
-   * @param {string} domKey
-   * @param {!KeyboardEvent=} event
-   */
-  handleKey(key, domKey, event) {
-    const keyModifiers = key >> 8;
-    const actions = this._applicableActions(key);
-    if (!actions.length)
-      return;
-    if (UI.Dialog.hasInstance()) {
-      if (event && !isPossiblyInputKey())
-        event.consume(true);
-      return;
-    }
-
-    if (!isPossiblyInputKey()) {
-      if (event)
-        event.consume(true);
-      processNextAction.call(this, false);
-    } else {
-      this._pendingActionTimer = setTimeout(processNextAction.bind(this, false), 0);
-    }
-
-    /**
-     * @param {boolean} handled
-     * @this {UI.ShortcutRegistry}
-     */
-    function processNextAction(handled) {
-      delete this._pendingActionTimer;
-      const action = actions.shift();
-      if (!action || handled)
-        return;
-
-      action.execute().then(processNextAction.bind(this));
-    }
-
-    /**
-     * @return {boolean}
-     */
-    function isPossiblyInputKey() {
-      if (!event || !UI.isEditing() || /^F\d+|Control|Shift|Alt|Meta|Escape|Win|U\+001B$/.test(domKey))
-        return false;
-
-      if (!keyModifiers)
-        return true;
-
-      const modifiers = UI.KeyboardShortcut.Modifiers;
-      if ((keyModifiers & (modifiers.Ctrl | modifiers.Alt)) === (modifiers.Ctrl | modifiers.Alt))
-        return Host.isWin();
-
-      return !hasModifier(modifiers.Ctrl) && !hasModifier(modifiers.Alt) && !hasModifier(modifiers.Meta);
-    }
-
-    /**
-     * @param {number} mod
-     * @return {boolean}
-     */
-    function hasModifier(mod) {
-      return !!(keyModifiers & mod);
-    }
-  }
-
-  /**
-   * @param {string} actionId
-   * @param {string} shortcut
-   */
-  registerShortcut(actionId, shortcut) {
-    const descriptor = UI.KeyboardShortcut.makeDescriptorFromBindingShortcut(shortcut);
-    if (!descriptor)
-      return;
-    this._defaultActionToShortcut.set(actionId, descriptor);
-    this._defaultKeyToActions.set(String(descriptor.key), actionId);
-  }
-
-  dismissPendingShortcutAction() {
-    if (this._pendingActionTimer) {
-      clearTimeout(this._pendingActionTimer);
-      delete this._pendingActionTimer;
-    }
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  _registerBindings(document) {
-    document.addEventListener('input', this.dismissPendingShortcutAction.bind(this), true);
-    const extensions = self.runtime.extensions('action');
-    extensions.forEach(registerExtension, this);
-
-    /**
-     * @param {!Runtime.Extension} extension
-     * @this {UI.ShortcutRegistry}
-     */
-    function registerExtension(extension) {
-      const descriptor = extension.descriptor();
-      const bindings = descriptor['bindings'];
-      for (let i = 0; bindings && i < bindings.length; ++i) {
-        if (!platformMatches(bindings[i].platform))
-          continue;
-        const shortcuts = bindings[i]['shortcut'].split(/\s+/);
-        shortcuts.forEach(this.registerShortcut.bind(this, descriptor['actionId']));
-      }
-    }
-
-    /**
-     * @param {string=} platformsString
-     * @return {boolean}
-     */
-    function platformMatches(platformsString) {
-      if (!platformsString)
-        return true;
-      const platforms = platformsString.split(',');
-      let isMatch = false;
-      const currentPlatform = Host.platform();
-      for (let i = 0; !isMatch && i < platforms.length; ++i)
-        isMatch = platforms[i] === currentPlatform;
-      return isMatch;
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ShortcutRegistry.ForwardedShortcut = class {};
-
-UI.ShortcutRegistry.ForwardedShortcut.instance = new UI.ShortcutRegistry.ForwardedShortcut();
-
-/** @type {!UI.ShortcutRegistry} */
-UI.shortcutRegistry;
diff --git a/front_end/ui/ShortcutsScreen.js b/front_end/ui/ShortcutsScreen.js
deleted file mode 100644
index 8daf09a..0000000
--- a/front_end/ui/ShortcutsScreen.js
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.ShortcutsScreen = class {
-  constructor() {
-    /** @type {!Object.<string, !UI.ShortcutsSection>} */
-    this._sections = {};
-  }
-
-  static registerShortcuts() {
-    // Elements panel
-    const elementsSection = UI.shortcutsScreen.section(Common.UIString('Elements Panel'));
-
-    const navigate = UI.ShortcutsScreen.ElementsPanelShortcuts.NavigateUp.concat(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.NavigateDown);
-    elementsSection.addRelatedKeys(navigate, Common.UIString('Navigate elements'));
-
-    const expandCollapse =
-        UI.ShortcutsScreen.ElementsPanelShortcuts.Expand.concat(UI.ShortcutsScreen.ElementsPanelShortcuts.Collapse);
-    elementsSection.addRelatedKeys(expandCollapse, Common.UIString('Expand/collapse'));
-
-    elementsSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.EditAttribute, Common.UIString('Edit attribute'));
-    elementsSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.HideElement, Common.UIString('Hide element'));
-    elementsSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.ToggleEditAsHTML, Common.UIString('Toggle edit as HTML'));
-
-    const stylesPaneSection = UI.shortcutsScreen.section(Common.UIString('Styles Pane'));
-
-    const nextPreviousProperty = UI.ShortcutsScreen.ElementsPanelShortcuts.NextProperty.concat(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.PreviousProperty);
-    stylesPaneSection.addRelatedKeys(nextPreviousProperty, Common.UIString('Next/previous property'));
-
-    stylesPaneSection.addRelatedKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.IncrementValue, Common.UIString('Increment value'));
-    stylesPaneSection.addRelatedKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.DecrementValue, Common.UIString('Decrement value'));
-
-    stylesPaneSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy10, Common.UIString('Increment by %f', 10));
-    stylesPaneSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy10, Common.UIString('Decrement by %f', 10));
-
-    stylesPaneSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy100, Common.UIString('Increment by %f', 100));
-    stylesPaneSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy100, Common.UIString('Decrement by %f', 100));
-
-    stylesPaneSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy01, Common.UIString('Increment by %f', 0.1));
-    stylesPaneSection.addAlternateKeys(
-        UI.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy01, Common.UIString('Decrement by %f', 0.1));
-
-    // Debugger
-    let section = UI.shortcutsScreen.section(Common.UIString('Debugger'));
-
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-pause'), Common.UIString('Pause/ Continue'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.step-over'), Common.UIString('Step over'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.step-into'), Common.UIString('Step into'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.step-out'), Common.UIString('Step out'));
-
-    const nextAndPrevFrameKeys =
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.next-call-frame')
-            .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.previous-call-frame'));
-    section.addRelatedKeys(nextAndPrevFrameKeys, Common.UIString('Next/previous call frame'));
-
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.EvaluateSelectionInConsole,
-        Common.UIString('Evaluate selection in console'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.AddSelectionToWatch, Common.UIString('Add selection to watch'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoint'),
-        Common.UIString('Toggle breakpoint'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoint-enabled'),
-        Common.UIString('Toggle breakpoint enabled'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoints-active'),
-        Common.UIString('Toggle all breakpoints'));
-
-    // Editing
-    section = UI.shortcutsScreen.section(Common.UIString('Text Editor'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('sources.go-to-member'), Common.UIString('Go to member'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleAutocompletion, Common.UIString('Autocompletion'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('sources.go-to-line'), Common.UIString('Go to line'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('sources.jump-to-previous-location'),
-        Common.UIString('Jump to previous editing location'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('sources.jump-to-next-location'),
-        Common.UIString('Jump to next editing location'));
-    section.addAlternateKeys(UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleComment, Common.UIString('Toggle comment'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByOne, Common.UIString('Increment CSS unit by 1'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByOne, Common.UIString('Decrement CSS unit by 1'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByTen, Common.UIString('Increment CSS unit by 10'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByTen, Common.UIString('Decrement CSS unit by 10'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.SelectNextOccurrence, Common.UIString('Select next occurrence'));
-    section.addAlternateKeys(UI.ShortcutsScreen.SourcesPanelShortcuts.SoftUndo, Common.UIString('Soft undo'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.SourcesPanelShortcuts.GotoMatchingBracket, Common.UIString('Go to matching bracket'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('sources.close-editor-tab'),
-        Common.UIString('Close editor tab'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('sources.switch-file'),
-        Common.UIString('Switch between files with the same name and different extensions.'));
-
-    // Performance panel
-    section = UI.shortcutsScreen.section(Common.UIString('Performance Panel'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording'),
-        Common.UIString('Start/stop recording'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.record-reload'),
-        Common.UIString('Record page reload'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.save-to-file'), Common.UIString('Save profile'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.load-from-file'), Common.UIString('Load profile'));
-    section.addRelatedKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.jump-to-previous-frame')
-            .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.jump-to-next-frame')),
-        Common.UIString('Jump to previous/next frame'));
-    section.addRelatedKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.show-history'),
-        Common.UIString('Pick a recording from history'));
-    section.addRelatedKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.previous-recording')
-            .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.next-recording')),
-        Common.UIString('Show previous/next recording'));
-
-    // Memory panel
-    section = UI.shortcutsScreen.section(Common.UIString('Memory Panel'));
-    section.addAlternateKeys(
-        UI.shortcutRegistry.shortcutDescriptorsForAction('profiler.heap-toggle-recording'),
-        Common.UIString('Start/stop recording'));
-
-    // Layers panel
-    section = UI.shortcutsScreen.section(Common.UIString('Layers Panel'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ResetView, Common.UIString('Reset view'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.PanMode, Common.UIString('Switch to pan mode'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.LayersPanelShortcuts.RotateMode, Common.UIString('Switch to rotate mode'));
-    section.addAlternateKeys(
-        UI.ShortcutsScreen.LayersPanelShortcuts.TogglePanRotate,
-        Common.UIString('Temporarily toggle pan/rotate mode while held'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, Common.UIString('Zoom in'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, Common.UIString('Zoom out'));
-    section.addRelatedKeys(
-        UI.ShortcutsScreen.LayersPanelShortcuts.Up.concat(UI.ShortcutsScreen.LayersPanelShortcuts.Down),
-        Common.UIString('Pan or rotate up/down'));
-    section.addRelatedKeys(
-        UI.ShortcutsScreen.LayersPanelShortcuts.Left.concat(UI.ShortcutsScreen.LayersPanelShortcuts.Right),
-        Common.UIString('Pan or rotate left/right'));
-  }
-
-  /**
-   * @param {string} name
-   * @return {!UI.ShortcutsSection}
-   */
-  section(name) {
-    let section = this._sections[name];
-    if (!section)
-      this._sections[name] = section = new UI.ShortcutsSection(name);
-    return section;
-  }
-
-  /**
-   * @return {!UI.Widget}
-   */
-  createShortcutsTabView() {
-    const orderedSections = [];
-    for (const section in this._sections)
-      orderedSections.push(this._sections[section]);
-    function compareSections(a, b) {
-      return a.order - b.order;
-    }
-    orderedSections.sort(compareSections);
-
-    const widget = new UI.Widget();
-
-    widget.element.className = 'settings-tab-container';  // Override
-    widget.element.createChild('header').createChild('h3').createTextChild(Common.UIString('Shortcuts'));
-    const scrollPane = widget.element.createChild('div', 'settings-container-wrapper');
-    const container = scrollPane.createChild('div');
-    container.className = 'settings-content settings-container';
-    for (let i = 0; i < orderedSections.length; ++i)
-      orderedSections[i].renderSection(container);
-
-    const note = scrollPane.createChild('p', 'settings-footnote');
-    note.appendChild(UI.createDocumentationLink(
-        'iterate/inspect-styles/shortcuts', Common.UIString('Full list of DevTools keyboard shortcuts and gestures')));
-
-    return widget;
-  }
-};
-
-/**
- * We cannot initialize it here as localized strings are not loaded yet.
- * @type {!UI.ShortcutsScreen}
- */
-UI.shortcutsScreen;
-
-/**
- * @unrestricted
- */
-UI.ShortcutsSection = class {
-  /**
-   * @param {string} name
-   */
-  constructor(name) {
-    this.name = name;
-    this._lines = /** @type {!Array.<!{key: !Node, text: string}>} */ ([]);
-    this.order = ++UI.ShortcutsSection._sequenceNumber;
-  }
-
-  /**
-   * @param {!UI.KeyboardShortcut.Descriptor} key
-   * @param {string} description
-   */
-  addKey(key, description) {
-    this._addLine(this._renderKey(key), description);
-  }
-
-  /**
-   * @param {!Array.<!UI.KeyboardShortcut.Descriptor>} keys
-   * @param {string} description
-   */
-  addRelatedKeys(keys, description) {
-    this._addLine(this._renderSequence(keys, '/'), description);
-  }
-
-  /**
-   * @param {!Array.<!UI.KeyboardShortcut.Descriptor>} keys
-   * @param {string} description
-   */
-  addAlternateKeys(keys, description) {
-    this._addLine(this._renderSequence(keys, Common.UIString('or')), description);
-  }
-
-  /**
-   * @param {!Node} keyElement
-   * @param {string} description
-   */
-  _addLine(keyElement, description) {
-    this._lines.push({key: keyElement, text: description});
-  }
-
-  /**
-   * @param {!Element} container
-   */
-  renderSection(container) {
-    const parent = container.createChild('div', 'settings-block');
-
-    const headLine = parent.createChild('div', 'settings-line');
-    headLine.createChild('div', 'settings-key-cell');
-    headLine.createChild('div', 'settings-section-title settings-cell').textContent = this.name;
-
-    for (let i = 0; i < this._lines.length; ++i) {
-      const line = parent.createChild('div', 'settings-line');
-      const keyCell = line.createChild('div', 'settings-key-cell');
-      keyCell.appendChild(this._lines[i].key);
-      keyCell.appendChild(this._createSpan('settings-key-delimiter', ':'));
-      line.createChild('div', 'settings-cell').textContent = this._lines[i].text;
-    }
-  }
-
-  /**
-   * @param {!Array.<!UI.KeyboardShortcut.Descriptor>} sequence
-   * @param {string} delimiter
-   * @return {!Node}
-   */
-  _renderSequence(sequence, delimiter) {
-    const delimiterSpan = this._createSpan('settings-key-delimiter', delimiter);
-    return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan);
-  }
-
-  /**
-   * @param {!UI.KeyboardShortcut.Descriptor} key
-   * @return {!Node}
-   */
-  _renderKey(key) {
-    const keyName = key.name;
-    const plus = this._createSpan('settings-combine-keys', '+');
-    return this._joinNodes(keyName.split(' + ').map(this._createSpan.bind(this, 'settings-key')), plus);
-  }
-
-  /**
-   * @param {string} className
-   * @param {string} textContent
-   * @return {!Element}
-   */
-  _createSpan(className, textContent) {
-    const node = createElement('span');
-    node.className = className;
-    node.textContent = textContent;
-    return node;
-  }
-
-  /**
-   * @param {!Array.<!Element>} nodes
-   * @param {!Element} delimiter
-   * @return {!Node}
-   */
-  _joinNodes(nodes, delimiter) {
-    const result = createDocumentFragment();
-    for (let i = 0; i < nodes.length; ++i) {
-      if (i > 0)
-        result.appendChild(delimiter.cloneNode(true));
-      result.appendChild(nodes[i]);
-    }
-    return result;
-  }
-};
-
-UI.ShortcutsSection._sequenceNumber = 0;
-
-
-UI.ShortcutsScreen.ElementsPanelShortcuts = {
-  NavigateUp: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up)],
-
-  NavigateDown: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down)],
-
-  Expand: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Right)],
-
-  Collapse: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Left)],
-
-  EditAttribute: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Enter)],
-
-  HideElement: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.H)],
-
-  ToggleEditAsHTML: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.F2)],
-
-  NextProperty: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Tab)],
-
-  PreviousProperty:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Tab, UI.KeyboardShortcut.Modifiers.Shift)],
-
-  IncrementValue: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up)],
-
-  DecrementValue: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down)],
-
-  IncrementBy10: [
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.PageUp),
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up, UI.KeyboardShortcut.Modifiers.Shift)
-  ],
-
-  DecrementBy10: [
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.PageDown),
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down, UI.KeyboardShortcut.Modifiers.Shift)
-  ],
-
-  IncrementBy100:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.PageUp, UI.KeyboardShortcut.Modifiers.Shift)],
-
-  DecrementBy100:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.PageDown, UI.KeyboardShortcut.Modifiers.Shift)],
-
-  IncrementBy01: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up, UI.KeyboardShortcut.Modifiers.Alt)],
-
-  DecrementBy01: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down, UI.KeyboardShortcut.Modifiers.Alt)]
-};
-
-UI.ShortcutsScreen.SourcesPanelShortcuts = {
-  SelectNextOccurrence: [UI.KeyboardShortcut.makeDescriptor('d', UI.KeyboardShortcut.Modifiers.CtrlOrMeta)],
-
-  SoftUndo: [UI.KeyboardShortcut.makeDescriptor('u', UI.KeyboardShortcut.Modifiers.CtrlOrMeta)],
-
-  GotoMatchingBracket: [UI.KeyboardShortcut.makeDescriptor('m', UI.KeyboardShortcut.Modifiers.Ctrl)],
-
-  ToggleAutocompletion:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Space, UI.KeyboardShortcut.Modifiers.Ctrl)],
-
-  IncreaseCSSUnitByOne:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up, UI.KeyboardShortcut.Modifiers.Alt)],
-
-  DecreaseCSSUnitByOne:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down, UI.KeyboardShortcut.Modifiers.Alt)],
-
-  IncreaseCSSUnitByTen:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.PageUp, UI.KeyboardShortcut.Modifiers.Alt)],
-
-  DecreaseCSSUnitByTen:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.PageDown, UI.KeyboardShortcut.Modifiers.Alt)],
-  EvaluateSelectionInConsole: [UI.KeyboardShortcut.makeDescriptor(
-      'e', UI.KeyboardShortcut.Modifiers.Shift | UI.KeyboardShortcut.Modifiers.Ctrl)],
-
-  AddSelectionToWatch: [UI.KeyboardShortcut.makeDescriptor(
-      'a', UI.KeyboardShortcut.Modifiers.Shift | UI.KeyboardShortcut.Modifiers.Ctrl)],
-
-  ToggleComment:
-      [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Slash, UI.KeyboardShortcut.Modifiers.CtrlOrMeta)],
-};
-
-UI.ShortcutsScreen.LayersPanelShortcuts = {
-  ResetView: [UI.KeyboardShortcut.makeDescriptor('0')],
-
-  PanMode: [UI.KeyboardShortcut.makeDescriptor('x')],
-
-  RotateMode: [UI.KeyboardShortcut.makeDescriptor('v')],
-
-  TogglePanRotate: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Shift)],
-
-  ZoomIn: [
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Plus, UI.KeyboardShortcut.Modifiers.Shift),
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.NumpadPlus)
-  ],
-
-  ZoomOut: [
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Minus, UI.KeyboardShortcut.Modifiers.Shift),
-    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.NumpadMinus)
-  ],
-
-  Up: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up), UI.KeyboardShortcut.makeDescriptor('w')],
-
-  Down: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down), UI.KeyboardShortcut.makeDescriptor('s')],
-
-  Left: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Left), UI.KeyboardShortcut.makeDescriptor('a')],
-
-  Right: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Right), UI.KeyboardShortcut.makeDescriptor('d')]
-};
diff --git a/front_end/ui/SoftContextMenu.js b/front_end/ui/SoftContextMenu.js
deleted file mode 100644
index c67425a..0000000
--- a/front_end/ui/SoftContextMenu.js
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.SoftContextMenu = class {
-  /**
-   * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
-   * @param {function(string)} itemSelectedCallback
-   * @param {!UI.SoftContextMenu=} parentMenu
-   */
-  constructor(items, itemSelectedCallback, parentMenu) {
-    this._items = items;
-    this._itemSelectedCallback = itemSelectedCallback;
-    this._parentMenu = parentMenu;
-  }
-
-  /**
-   * @param {!Document} document
-   * @param {!AnchorBox} anchorBox
-   */
-  show(document, anchorBox) {
-    if (!this._items.length)
-      return;
-
-    this._document = document;
-
-    this._glassPane = new UI.GlassPane();
-    this._glassPane.setPointerEventsBehavior(
-        this._parentMenu ? UI.GlassPane.PointerEventsBehavior.PierceGlassPane :
-                           UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-    this._glassPane.registerRequiredCSS('ui/softContextMenu.css');
-    this._glassPane.setContentAnchorBox(anchorBox);
-    this._glassPane.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    this._glassPane.setMarginBehavior(UI.GlassPane.MarginBehavior.NoMargin);
-    this._glassPane.setAnchorBehavior(
-        this._parentMenu ? UI.GlassPane.AnchorBehavior.PreferRight : UI.GlassPane.AnchorBehavior.PreferBottom);
-
-    this._contextMenuElement = this._glassPane.contentElement.createChild('div', 'soft-context-menu');
-    this._contextMenuElement.tabIndex = 0;
-    this._contextMenuElement.addEventListener('mouseup', e => e.consume(), false);
-    this._contextMenuElement.addEventListener('keydown', this._menuKeyDown.bind(this), false);
-
-    for (let i = 0; i < this._items.length; ++i)
-      this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
-
-    this._glassPane.show(document);
-    this._focusRestorer = new UI.ElementFocusRestorer(this._contextMenuElement);
-
-    if (!this._parentMenu) {
-      this._onBodyMouseDown = event => {
-        this.discard();
-        event.consume(true);
-      };
-      this._document.body.addEventListener('mousedown', this._onBodyMouseDown, false);
-    }
-  }
-
-  discard() {
-    if (this._subMenu)
-      this._subMenu.discard();
-    if (this._focusRestorer)
-      this._focusRestorer.restore();
-    if (this._glassPane) {
-      this._glassPane.hide();
-      delete this._glassPane;
-      if (this._onBodyMouseDown) {
-        this._document.body.removeEventListener('mousedown', this._onBodyMouseDown, false);
-        delete this._onBodyMouseDown;
-      }
-    }
-    if (this._parentMenu)
-      delete this._parentMenu._subMenu;
-  }
-
-  _createMenuItem(item) {
-    if (item.type === 'separator')
-      return this._createSeparator();
-
-    if (item.type === 'subMenu')
-      return this._createSubMenu(item);
-
-    const menuItemElement = createElementWithClass('div', 'soft-context-menu-item');
-    const checkMarkElement = UI.Icon.create('smallicon-checkmark', 'checkmark');
-    menuItemElement.appendChild(checkMarkElement);
-    if (!item.checked)
-      checkMarkElement.style.opacity = '0';
-
-    if (item.element) {
-      const wrapper = menuItemElement.createChild('div', 'soft-context-menu-custom-item');
-      wrapper.appendChild(item.element);
-      menuItemElement._isCustom = true;
-      return menuItemElement;
-    }
-
-    if (!item.enabled)
-      menuItemElement.classList.add('soft-context-menu-disabled');
-    menuItemElement.createTextChild(item.label);
-    menuItemElement.createChild('span', 'soft-context-menu-shortcut').textContent = item.shortcut;
-
-    menuItemElement.addEventListener('mousedown', this._menuItemMouseDown.bind(this), false);
-    menuItemElement.addEventListener('mouseup', this._menuItemMouseUp.bind(this), false);
-
-    // Manually manage hover highlight since :hover does not work in case of click-and-hold menu invocation.
-    menuItemElement.addEventListener('mouseover', this._menuItemMouseOver.bind(this), false);
-    menuItemElement.addEventListener('mouseleave', this._menuItemMouseLeave.bind(this), false);
-
-    menuItemElement._actionId = item.id;
-    return menuItemElement;
-  }
-
-  _createSubMenu(item) {
-    const menuItemElement = createElementWithClass('div', 'soft-context-menu-item');
-    menuItemElement._subItems = item.subItems;
-
-    // Occupy the same space on the left in all items.
-    const checkMarkElement = UI.Icon.create('smallicon-checkmark', 'soft-context-menu-item-checkmark');
-    checkMarkElement.classList.add('checkmark');
-    menuItemElement.appendChild(checkMarkElement);
-    checkMarkElement.style.opacity = '0';
-
-    menuItemElement.createTextChild(item.label);
-
-    const subMenuArrowElement = menuItemElement.createChild('span', 'soft-context-menu-item-submenu-arrow');
-    subMenuArrowElement.textContent = '\u25B6';  // BLACK RIGHT-POINTING TRIANGLE
-
-    menuItemElement.addEventListener('mousedown', this._menuItemMouseDown.bind(this), false);
-    menuItemElement.addEventListener('mouseup', this._menuItemMouseUp.bind(this), false);
-
-    // Manually manage hover highlight since :hover does not work in case of click-and-hold menu invocation.
-    menuItemElement.addEventListener('mouseover', this._menuItemMouseOver.bind(this), false);
-    menuItemElement.addEventListener('mouseleave', this._menuItemMouseLeave.bind(this), false);
-
-    return menuItemElement;
-  }
-
-  _createSeparator() {
-    const separatorElement = createElementWithClass('div', 'soft-context-menu-separator');
-    separatorElement._isSeparator = true;
-    separatorElement.createChild('div', 'separator-line');
-    return separatorElement;
-  }
-
-  _menuItemMouseDown(event) {
-    // Do not let separator's mouse down hit menu's handler - we need to receive mouse up!
-    event.consume(true);
-  }
-
-  _menuItemMouseUp(event) {
-    this._triggerAction(event.target, event);
-    event.consume();
-  }
-
-  /**
-   * @return {!UI.SoftContextMenu}
-   */
-  _root() {
-    let root = this;
-    while (root._parentMenu)
-      root = root._parentMenu;
-    return root;
-  }
-
-  _triggerAction(menuItemElement, event) {
-    if (!menuItemElement._subItems) {
-      this._root().discard();
-      event.consume(true);
-      if (typeof menuItemElement._actionId !== 'undefined') {
-        this._itemSelectedCallback(menuItemElement._actionId);
-        delete menuItemElement._actionId;
-      }
-      return;
-    }
-
-    this._showSubMenu(menuItemElement);
-    event.consume();
-  }
-
-  _showSubMenu(menuItemElement) {
-    if (menuItemElement._subMenuTimer) {
-      clearTimeout(menuItemElement._subMenuTimer);
-      delete menuItemElement._subMenuTimer;
-    }
-    if (this._subMenu)
-      return;
-
-    this._subMenu = new UI.SoftContextMenu(menuItemElement._subItems, this._itemSelectedCallback, this);
-    const anchorBox = menuItemElement.boxInWindow();
-    // Adjust for padding.
-    anchorBox.y -= 5;
-    anchorBox.x += 3;
-    anchorBox.width -= 6;
-    anchorBox.height += 10;
-    this._subMenu.show(this._document, anchorBox);
-  }
-
-  _menuItemMouseOver(event) {
-    this._highlightMenuItem(event.target, true);
-  }
-
-  _menuItemMouseLeave(event) {
-    if (!this._subMenu || !event.relatedTarget) {
-      this._highlightMenuItem(null, true);
-      return;
-    }
-
-    const relatedTarget = event.relatedTarget;
-    if (relatedTarget === this._contextMenuElement)
-      this._highlightMenuItem(null, true);
-  }
-
-  /**
-   * @param {?Element} menuItemElement
-   * @param {boolean} scheduleSubMenu
-   */
-  _highlightMenuItem(menuItemElement, scheduleSubMenu) {
-    if (this._highlightedMenuItemElement === menuItemElement)
-      return;
-
-    if (this._subMenu)
-      this._subMenu.discard();
-    if (this._highlightedMenuItemElement) {
-      this._highlightedMenuItemElement.classList.remove('force-white-icons');
-      this._highlightedMenuItemElement.classList.remove('soft-context-menu-item-mouse-over');
-      if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) {
-        clearTimeout(this._highlightedMenuItemElement._subMenuTimer);
-        delete this._highlightedMenuItemElement._subMenuTimer;
-      }
-    }
-    this._highlightedMenuItemElement = menuItemElement;
-    if (this._highlightedMenuItemElement) {
-      this._highlightedMenuItemElement.classList.add('force-white-icons');
-      this._highlightedMenuItemElement.classList.add('soft-context-menu-item-mouse-over');
-      this._contextMenuElement.focus();
-      if (scheduleSubMenu && this._highlightedMenuItemElement._subItems &&
-          !this._highlightedMenuItemElement._subMenuTimer) {
-        this._highlightedMenuItemElement._subMenuTimer =
-            setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement), 150);
-      }
-    }
-  }
-
-  _highlightPrevious() {
-    let menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling :
-                                                             this._contextMenuElement.lastChild;
-    while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom))
-      menuItemElement = menuItemElement.previousSibling;
-    if (menuItemElement)
-      this._highlightMenuItem(menuItemElement, false);
-  }
-
-  _highlightNext() {
-    let menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling :
-                                                             this._contextMenuElement.firstChild;
-    while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom))
-      menuItemElement = menuItemElement.nextSibling;
-    if (menuItemElement)
-      this._highlightMenuItem(menuItemElement, false);
-  }
-
-  _menuKeyDown(event) {
-    switch (event.key) {
-      case 'ArrowUp':
-        this._highlightPrevious();
-        break;
-      case 'ArrowDown':
-        this._highlightNext();
-        break;
-      case 'ArrowLeft':
-        if (this._parentMenu) {
-          this._highlightMenuItem(null, false);
-          this.discard();
-        }
-        break;
-      case 'ArrowRight':
-        if (!this._highlightedMenuItemElement)
-          break;
-        if (this._highlightedMenuItemElement._subItems) {
-          this._showSubMenu(this._highlightedMenuItemElement);
-          this._subMenu._highlightNext();
-        }
-        break;
-      case 'Escape':
-        this.discard();
-        break;
-      case 'Enter':
-        if (!isEnterKey(event))
-          break;
-      // Fall through
-      case ' ':  // Space
-        if (this._highlightedMenuItemElement)
-          this._triggerAction(this._highlightedMenuItemElement, event);
-        if (this._highlightedMenuItemElement._subItems)
-          this._subMenu._highlightNext();
-        break;
-    }
-    event.consume(true);
-  }
-};
diff --git a/front_end/ui/SoftDropDown.js b/front_end/ui/SoftDropDown.js
deleted file mode 100644
index 88e8e97..0000000
--- a/front_end/ui/SoftDropDown.js
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @template T
- * @implements {UI.ListDelegate<T>}
- */
-UI.SoftDropDown = class {
-  /**
-   * @param {!UI.ListModel<T>} model
-   * @param {!UI.SoftDropDown.Delegate<T>} delegate
-   */
-  constructor(model, delegate) {
-    this._delegate = delegate;
-    this._selectedItem = null;
-    this._model = model;
-
-    this.element = createElementWithClass('button', 'soft-dropdown');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/softDropDownButton.css');
-    this._titleElement = shadowRoot.createChild('span', 'title');
-    const dropdownArrowIcon = UI.Icon.create('smallicon-triangle-down');
-    shadowRoot.appendChild(dropdownArrowIcon);
-
-    this._glassPane = new UI.GlassPane();
-    this._glassPane.setMarginBehavior(UI.GlassPane.MarginBehavior.NoMargin);
-    this._glassPane.setAnchorBehavior(UI.GlassPane.AnchorBehavior.PreferBottom);
-    this._glassPane.setOutsideClickCallback(this._hide.bind(this));
-    this._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-    this._list = new UI.ListControl(model, this, UI.ListMode.EqualHeightItems);
-    this._list.element.classList.add('item-list');
-    this._rowHeight = 36;
-    this._width = 315;
-    UI.createShadowRootWithCoreStyles(this._glassPane.contentElement, 'ui/softDropDown.css')
-        .appendChild(this._list.element);
-
-    this._listWasShowing200msAgo = false;
-    this.element.addEventListener('mousedown', event => {
-      if (this._listWasShowing200msAgo)
-        this._hide(event);
-      else if (!this.element.disabled)
-        this._show(event);
-    }, false);
-    this.element.addEventListener('keydown', this._onKeyDown.bind(this), false);
-    this.element.addEventListener('focusout', this._hide.bind(this), false);
-    this._list.element.addEventListener('mousedown', event => event.consume(true), false);
-    this._list.element.addEventListener('mouseup', event => {
-      if (event.target === this._list.element)
-        return;
-
-      if (!this._listWasShowing200msAgo)
-        return;
-      this._selectHighlightedItem();
-      this._hide(event);
-    }, false);
-    model.addEventListener(UI.ListModel.Events.ItemsReplaced, this._itemsReplaced, this);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _show(event) {
-    if (this._glassPane.isShowing())
-      return;
-    this._glassPane.setContentAnchorBox(this.element.boxInWindow());
-    this._glassPane.show(/** @type {!Document} **/ (this.element.ownerDocument));
-    this._updateGlasspaneSize();
-    if (this._selectedItem)
-      this._list.selectItem(this._selectedItem);
-    this.element.focus();
-    event.consume(true);
-    setTimeout(() => this._listWasShowing200msAgo = true, 200);
-  }
-
-  _updateGlasspaneSize() {
-    const maxHeight = this._rowHeight * (Math.min(this._model.length, 9));
-    this._glassPane.setMaxContentSize(new UI.Size(this._width, maxHeight));
-    this._list.viewportResized();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _hide(event) {
-    setTimeout(() => this._listWasShowing200msAgo = false, 200);
-    this._glassPane.hide();
-    this._list.selectItem(null);
-    event.consume(true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeyDown(event) {
-    let handled = false;
-    switch (event.key) {
-      case 'ArrowLeft':
-      case 'ArrowUp':
-        handled = this._list.selectPreviousItem(false, false);
-        break;
-      case 'ArrowRight':
-      case 'ArrowDown':
-        handled = this._list.selectNextItem(false, false);
-        break;
-      case 'PageUp':
-        handled = this._list.selectItemPreviousPage(false);
-        break;
-      case 'PageDown':
-        handled = this._list.selectItemNextPage(false);
-        break;
-      case 'Home':
-        for (let i = 0; i < this._model.length; i++) {
-          if (this.isItemSelectable(this._model.at(i))) {
-            this._list.selectItem(this._model.at(i));
-            handled = true;
-            break;
-          }
-        }
-        break;
-      case 'End':
-        for (let i = this._model.length - 1; i >= 0; i--) {
-          if (this.isItemSelectable(this._model.at(i))) {
-            this._list.selectItem(this._model.at(i));
-            handled = true;
-            break;
-          }
-        }
-        break;
-      case 'Escape':
-        this._hide(event);
-        break;
-      case 'Tab':
-        if (!this._glassPane.isShowing())
-          break;
-        this._selectHighlightedItem();
-        this._hide(event);
-        break;
-      case 'Enter':
-        if (!this._glassPane.isShowing()) {
-          this._show(event);
-          break;
-        }
-        this._selectHighlightedItem();
-        this._hide(event);
-        break;
-      case ' ':
-        this._show(event);
-        break;
-      default:
-        if (event.key.length === 1) {
-          const selectedIndex = this._list.selectedIndex();
-          const letter = event.key.toUpperCase();
-          for (let i = 0; i < this._model.length; i++) {
-            const item = this._model.at((selectedIndex + i + 1) % this._model.length);
-            if (this._delegate.titleFor(item).toUpperCase().startsWith(letter)) {
-              this._list.selectItem(item);
-              break;
-            }
-          }
-          handled = true;
-        }
-        break;
-    }
-
-    if (handled) {
-      event.consume(true);
-      this._selectHighlightedItem();
-    }
-  }
-
-  /**
-   * @param {number} width
-   */
-  setWidth(width) {
-    this._width = width;
-    this._updateGlasspaneSize();
-  }
-
-  /**
-   * @param {number} rowHeight
-   */
-  setRowHeight(rowHeight) {
-    this._rowHeight = rowHeight;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _itemsReplaced(event) {
-    const removed = /** @type {!Array<T>} */ (event.data.removed);
-    if (removed.indexOf(this._selectedItem) !== -1) {
-      this._selectedItem = null;
-      this._selectHighlightedItem();
-    }
-    this._updateGlasspaneSize();
-  }
-
-  /**
-   * @param {?T} item
-   */
-  selectItem(item) {
-    this._selectedItem = item;
-    if (this._selectedItem)
-      this._titleElement.textContent = this._delegate.titleFor(this._selectedItem);
-    else
-      this._titleElement.textContent = '';
-    this._delegate.itemSelected(this._selectedItem);
-  }
-
-  /**
-   * @override
-   * @param {T} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    const element = createElementWithClass('div', 'item');
-    element.addEventListener('mousemove', e => {
-      if ((e.movementX || e.movementY) && this._delegate.isItemSelectable(item))
-        this._list.selectItem(item, false, /* Don't scroll */ true);
-    });
-    element.classList.toggle('disabled', !this._delegate.isItemSelectable(item));
-    element.classList.toggle('highlighted', this._list.selectedItem() === item);
-
-    element.appendChild(this._delegate.createElementForItem(item));
-
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {T} item
-   * @return {number}
-   */
-  heightForItem(item) {
-    return this._rowHeight;
-  }
-
-  /**
-   * @override
-   * @param {T} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    return this._delegate.isItemSelectable(item);
-  }
-
-  /**
-   * @override
-   * @param {?T} from
-   * @param {?T} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('highlighted');
-    if (toElement)
-      toElement.classList.add('highlighted');
-    this._delegate.highlightedItemChanged(
-        from, to, fromElement && fromElement.firstElementChild, toElement && toElement.firstElementChild);
-  }
-
-  _selectHighlightedItem() {
-    this.selectItem(this._list.selectedItem());
-  }
-
-  /**
-   * @param {T} item
-   */
-  refreshItem(item) {
-    this._list.refreshItem(item);
-  }
-};
-
-/**
- * @interface
- * @template T
- */
-UI.SoftDropDown.Delegate = class {
-  /**
-   * @param {T} item
-   * @return {string}
-   */
-  titleFor(item) {
-  }
-
-  /**
-   * @param {T} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-  }
-
-  /**
-   * @param {T} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-  }
-
-  /**
-   * @param {?T} item
-   */
-  itemSelected(item) {
-  }
-
-  /**
-   * @param {?T} from
-   * @param {?T} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  highlightedItemChanged(from, to, fromElement, toElement) {
-  }
-};
\ No newline at end of file
diff --git a/front_end/ui/SplitWidget.js b/front_end/ui/SplitWidget.js
deleted file mode 100644
index 2765082..0000000
--- a/front_end/ui/SplitWidget.js
+++ /dev/null
@@ -1,926 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.SplitWidget = class extends UI.Widget {
-  /**
-   * @param {boolean} isVertical
-   * @param {boolean} secondIsSidebar
-   * @param {string=} settingName
-   * @param {number=} defaultSidebarWidth
-   * @param {number=} defaultSidebarHeight
-   * @param {boolean=} constraintsInDip
-   */
-  constructor(isVertical, secondIsSidebar, settingName, defaultSidebarWidth, defaultSidebarHeight, constraintsInDip) {
-    super(true);
-    this.element.classList.add('split-widget');
-    this.registerRequiredCSS('ui/splitWidget.css');
-
-    this.contentElement.classList.add('shadow-split-widget');
-    this._mainElement =
-        this.contentElement.createChild('div', 'shadow-split-widget-contents shadow-split-widget-main vbox');
-    this._mainElement.createChild('content').select = '.insertion-point-main';
-    this._sidebarElement =
-        this.contentElement.createChild('div', 'shadow-split-widget-contents shadow-split-widget-sidebar vbox');
-    this._sidebarElement.createChild('content').select = '.insertion-point-sidebar';
-    this._resizerElement = this.contentElement.createChild('div', 'shadow-split-widget-resizer');
-    this._resizerElementSize = null;
-
-    this._resizerWidget = new UI.SimpleResizerWidget();
-    this._resizerWidget.setEnabled(true);
-    this._resizerWidget.addEventListener(UI.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
-    this._resizerWidget.addEventListener(UI.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate, this);
-    this._resizerWidget.addEventListener(UI.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
-
-    this._defaultSidebarWidth = defaultSidebarWidth || 200;
-    this._defaultSidebarHeight = defaultSidebarHeight || this._defaultSidebarWidth;
-    this._constraintsInDip = !!constraintsInDip;
-    this._resizeStartSizeDIP = 0;
-    this._setting = settingName ? Common.settings.createSetting(settingName, {}) : null;
-
-    this._totalSizeCSS = 0;
-    this._totalSizeOtherDimensionCSS = 0;
-    /** @type {?UI.Widget} */
-    this._mainWidget = null;
-    /** @type {?UI.Widget} */
-    this._sidebarWidget = null;
-    this._animationFrameHandle = 0;
-    /** @type {?function()} */
-    this._animationCallback = null;
-    this._showHideSidebarButtonTitle = '';
-    /** @type {?UI.ToolbarButton} */
-    this._showHideSidebarButton = null;
-    this._isVertical = false;
-    this._sidebarMinimized = false;
-    this._detaching = false;
-    this._sidebarSizeDIP = -1;
-    this._savedSidebarSizeDIP = this._sidebarSizeDIP;
-    this._secondIsSidebar = false;
-    this._shouldSaveShowMode = false;
-    /** @type {?number} */
-    this._savedVerticalMainSize = null;
-    /** @type {?number} */
-    this._savedHorizontalMainSize = null;
-
-    this.setSecondIsSidebar(secondIsSidebar);
-
-    this._innerSetVertical(isVertical);
-    this._showMode = UI.SplitWidget.ShowMode.Both;
-    this._savedShowMode = this._showMode;
-
-    // Should be called after isVertical has the right value.
-    this.installResizer(this._resizerElement);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isVertical() {
-    return this._isVertical;
-  }
-
-  /**
-   * @param {boolean} isVertical
-   */
-  setVertical(isVertical) {
-    if (this._isVertical === isVertical)
-      return;
-
-    this._innerSetVertical(isVertical);
-
-    if (this.isShowing())
-      this._updateLayout();
-  }
-
-  /**
-   * @param {boolean} isVertical
-   */
-  _innerSetVertical(isVertical) {
-    this.contentElement.classList.toggle('vbox', !isVertical);
-    this.contentElement.classList.toggle('hbox', isVertical);
-    this._isVertical = isVertical;
-
-    this._resizerElementSize = null;
-    this._sidebarSizeDIP = -1;
-    this._restoreSidebarSizeFromSettings();
-    if (this._shouldSaveShowMode)
-      this._restoreAndApplyShowModeFromSettings();
-    this._updateShowHideSidebarButton();
-    // FIXME: reverse SplitWidget.isVertical meaning.
-    this._resizerWidget.setVertical(!isVertical);
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @param {boolean=} animate
-   */
-  _updateLayout(animate) {
-    this._totalSizeCSS = 0;  // Lazy update.
-    this._totalSizeOtherDimensionCSS = 0;
-
-    // Remove properties that might affect total size calculation.
-    this._mainElement.style.removeProperty('width');
-    this._mainElement.style.removeProperty('height');
-    this._sidebarElement.style.removeProperty('width');
-    this._sidebarElement.style.removeProperty('height');
-
-    this._innerSetSidebarSizeDIP(this._preferredSidebarSizeDIP(), !!animate);
-  }
-
-  /**
-   * @param {!UI.Widget} widget
-   */
-  setMainWidget(widget) {
-    if (this._mainWidget === widget)
-      return;
-    this.suspendInvalidations();
-    if (this._mainWidget)
-      this._mainWidget.detach();
-    this._mainWidget = widget;
-    if (widget) {
-      widget.element.classList.add('insertion-point-main');
-      widget.element.classList.remove('insertion-point-sidebar');
-      if (this._showMode === UI.SplitWidget.ShowMode.OnlyMain || this._showMode === UI.SplitWidget.ShowMode.Both)
-        widget.show(this.element);
-    }
-    this.resumeInvalidations();
-  }
-
-  /**
-   * @param {!UI.Widget} widget
-   */
-  setSidebarWidget(widget) {
-    if (this._sidebarWidget === widget)
-      return;
-    this.suspendInvalidations();
-    if (this._sidebarWidget)
-      this._sidebarWidget.detach();
-    this._sidebarWidget = widget;
-    if (widget) {
-      widget.element.classList.add('insertion-point-sidebar');
-      widget.element.classList.remove('insertion-point-main');
-      if (this._showMode === UI.SplitWidget.ShowMode.OnlySidebar || this._showMode === UI.SplitWidget.ShowMode.Both)
-        widget.show(this.element);
-    }
-    this.resumeInvalidations();
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  mainWidget() {
-    return this._mainWidget;
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  sidebarWidget() {
-    return this._sidebarWidget;
-  }
-
-  /**
-   * @override
-   * @param {!UI.Widget} widget
-   */
-  childWasDetached(widget) {
-    if (this._detaching)
-      return;
-    if (this._mainWidget === widget)
-      this._mainWidget = null;
-    if (this._sidebarWidget === widget)
-      this._sidebarWidget = null;
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isSidebarSecond() {
-    return this._secondIsSidebar;
-  }
-
-  enableShowModeSaving() {
-    this._shouldSaveShowMode = true;
-    this._restoreAndApplyShowModeFromSettings();
-  }
-
-  /**
-   * @return {string}
-   */
-  showMode() {
-    return this._showMode;
-  }
-
-  /**
-   * @param {boolean} secondIsSidebar
-   */
-  setSecondIsSidebar(secondIsSidebar) {
-    this.contentElement.classList.toggle('shadow-split-widget-first-is-sidebar', !secondIsSidebar);
-    this._secondIsSidebar = secondIsSidebar;
-  }
-
-  /**
-   * @return {?string}
-   */
-  sidebarSide() {
-    if (this._showMode !== UI.SplitWidget.ShowMode.Both)
-      return null;
-    return this._isVertical ? (this._secondIsSidebar ? 'right' : 'left') : (this._secondIsSidebar ? 'bottom' : 'top');
-  }
-
-  /**
-   * @return {!Element}
-   */
-  resizerElement() {
-    return this._resizerElement;
-  }
-
-  /**
-   * @param {boolean=} animate
-   */
-  hideMain(animate) {
-    this._showOnly(this._sidebarWidget, this._mainWidget, this._sidebarElement, this._mainElement, animate);
-    this._updateShowMode(UI.SplitWidget.ShowMode.OnlySidebar);
-  }
-
-  /**
-   * @param {boolean=} animate
-   */
-  hideSidebar(animate) {
-    this._showOnly(this._mainWidget, this._sidebarWidget, this._mainElement, this._sidebarElement, animate);
-    this._updateShowMode(UI.SplitWidget.ShowMode.OnlyMain);
-  }
-
-  /**
-   * @param {boolean} minimized
-   */
-  setSidebarMinimized(minimized) {
-    this._sidebarMinimized = minimized;
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isSidebarMinimized() {
-    return this._sidebarMinimized;
-  }
-
-  /**
-   * @param {?UI.Widget} sideToShow
-   * @param {?UI.Widget} sideToHide
-   * @param {!Element} shadowToShow
-   * @param {!Element} shadowToHide
-   * @param {boolean=} animate
-   */
-  _showOnly(sideToShow, sideToHide, shadowToShow, shadowToHide, animate) {
-    this._cancelAnimation();
-
-    /**
-     * @this {UI.SplitWidget}
-     */
-    function callback() {
-      if (sideToShow) {
-        // Make sure main is first in the children list.
-        if (sideToShow === this._mainWidget)
-          this._mainWidget.show(this.element, this._sidebarWidget ? this._sidebarWidget.element : null);
-        else
-          this._sidebarWidget.show(this.element);
-      }
-      if (sideToHide) {
-        this._detaching = true;
-        sideToHide.detach();
-        this._detaching = false;
-      }
-
-      this._resizerElement.classList.add('hidden');
-      shadowToShow.classList.remove('hidden');
-      shadowToShow.classList.add('maximized');
-      shadowToHide.classList.add('hidden');
-      shadowToHide.classList.remove('maximized');
-      this._removeAllLayoutProperties();
-      this.doResize();
-      this._showFinishedForTest();
-    }
-
-    if (animate)
-      this._animate(true, callback.bind(this));
-    else
-      callback.call(this);
-
-    this._sidebarSizeDIP = -1;
-    this.setResizable(false);
-  }
-
-  _showFinishedForTest() {
-    // This method is sniffed in tests.
-  }
-
-  _removeAllLayoutProperties() {
-    this._sidebarElement.style.removeProperty('flexBasis');
-
-    this._mainElement.style.removeProperty('width');
-    this._mainElement.style.removeProperty('height');
-    this._sidebarElement.style.removeProperty('width');
-    this._sidebarElement.style.removeProperty('height');
-
-    this._resizerElement.style.removeProperty('left');
-    this._resizerElement.style.removeProperty('right');
-    this._resizerElement.style.removeProperty('top');
-    this._resizerElement.style.removeProperty('bottom');
-
-    this._resizerElement.style.removeProperty('margin-left');
-    this._resizerElement.style.removeProperty('margin-right');
-    this._resizerElement.style.removeProperty('margin-top');
-    this._resizerElement.style.removeProperty('margin-bottom');
-  }
-
-  /**
-   * @param {boolean=} animate
-   */
-  showBoth(animate) {
-    if (this._showMode === UI.SplitWidget.ShowMode.Both)
-      animate = false;
-
-    this._cancelAnimation();
-    this._mainElement.classList.remove('maximized', 'hidden');
-    this._sidebarElement.classList.remove('maximized', 'hidden');
-    this._resizerElement.classList.remove('hidden');
-    this.setResizable(true);
-
-    // Make sure main is the first in the children list.
-    this.suspendInvalidations();
-    if (this._sidebarWidget)
-      this._sidebarWidget.show(this.element);
-    if (this._mainWidget)
-      this._mainWidget.show(this.element, this._sidebarWidget ? this._sidebarWidget.element : null);
-    this.resumeInvalidations();
-    // Order widgets in DOM properly.
-    this.setSecondIsSidebar(this._secondIsSidebar);
-
-    this._sidebarSizeDIP = -1;
-    this._updateShowMode(UI.SplitWidget.ShowMode.Both);
-    this._updateLayout(animate);
-  }
-
-  /**
-   * @param {boolean} resizable
-   */
-  setResizable(resizable) {
-    this._resizerWidget.setEnabled(resizable);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isResizable() {
-    return this._resizerWidget.isEnabled();
-  }
-
-  /**
-   * @param {number} size
-   */
-  setSidebarSize(size) {
-    const sizeDIP = UI.zoomManager.cssToDIP(size);
-    this._savedSidebarSizeDIP = sizeDIP;
-    this._saveSetting();
-    this._innerSetSidebarSizeDIP(sizeDIP, false, true);
-  }
-
-  /**
-   * @return {number}
-   */
-  sidebarSize() {
-    const sizeDIP = Math.max(0, this._sidebarSizeDIP);
-    return UI.zoomManager.dipToCSS(sizeDIP);
-  }
-
-  /**
-   * Returns total size in DIP.
-   * @return {number}
-   */
-  _totalSizeDIP() {
-    if (!this._totalSizeCSS) {
-      this._totalSizeCSS = this._isVertical ? this.contentElement.offsetWidth : this.contentElement.offsetHeight;
-      this._totalSizeOtherDimensionCSS =
-          this._isVertical ? this.contentElement.offsetHeight : this.contentElement.offsetWidth;
-    }
-    return UI.zoomManager.cssToDIP(this._totalSizeCSS);
-  }
-
-  /**
-   * @param {string} showMode
-   */
-  _updateShowMode(showMode) {
-    this._showMode = showMode;
-    this._saveShowModeToSettings();
-    this._updateShowHideSidebarButton();
-    this.dispatchEventToListeners(UI.SplitWidget.Events.ShowModeChanged, showMode);
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @param {number} sizeDIP
-   * @param {boolean} animate
-   * @param {boolean=} userAction
-   */
-  _innerSetSidebarSizeDIP(sizeDIP, animate, userAction) {
-    if (this._showMode !== UI.SplitWidget.ShowMode.Both || !this.isShowing())
-      return;
-
-    sizeDIP = this._applyConstraints(sizeDIP, userAction);
-    if (this._sidebarSizeDIP === sizeDIP)
-      return;
-
-    if (!this._resizerElementSize) {
-      this._resizerElementSize =
-          this._isVertical ? this._resizerElement.offsetWidth : this._resizerElement.offsetHeight;
-    }
-
-    // Invalidate layout below.
-
-    this._removeAllLayoutProperties();
-
-    // this._totalSizeDIP is available below since we successfully applied constraints.
-    const roundSizeCSS = Math.round(UI.zoomManager.dipToCSS(sizeDIP));
-    const sidebarSizeValue = roundSizeCSS + 'px';
-    const mainSizeValue = (this._totalSizeCSS - roundSizeCSS) + 'px';
-    this._sidebarElement.style.flexBasis = sidebarSizeValue;
-
-    // Make both sides relayout boundaries.
-    if (this._isVertical) {
-      this._sidebarElement.style.width = sidebarSizeValue;
-      this._mainElement.style.width = mainSizeValue;
-      this._sidebarElement.style.height = this._totalSizeOtherDimensionCSS + 'px';
-      this._mainElement.style.height = this._totalSizeOtherDimensionCSS + 'px';
-    } else {
-      this._sidebarElement.style.height = sidebarSizeValue;
-      this._mainElement.style.height = mainSizeValue;
-      this._sidebarElement.style.width = this._totalSizeOtherDimensionCSS + 'px';
-      this._mainElement.style.width = this._totalSizeOtherDimensionCSS + 'px';
-    }
-
-    // Position resizer.
-    if (this._isVertical) {
-      if (this._secondIsSidebar) {
-        this._resizerElement.style.right = sidebarSizeValue;
-        this._resizerElement.style.marginRight = -this._resizerElementSize / 2 + 'px';
-      } else {
-        this._resizerElement.style.left = sidebarSizeValue;
-        this._resizerElement.style.marginLeft = -this._resizerElementSize / 2 + 'px';
-      }
-    } else {
-      if (this._secondIsSidebar) {
-        this._resizerElement.style.bottom = sidebarSizeValue;
-        this._resizerElement.style.marginBottom = -this._resizerElementSize / 2 + 'px';
-      } else {
-        this._resizerElement.style.top = sidebarSizeValue;
-        this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + 'px';
-      }
-    }
-
-    this._sidebarSizeDIP = sizeDIP;
-
-    // Force layout.
-
-    if (animate) {
-      this._animate(false);
-    } else {
-      // No need to recalculate this._sidebarSizeDIP and this._totalSizeDIP again.
-      this.doResize();
-      this.dispatchEventToListeners(UI.SplitWidget.Events.SidebarSizeChanged, this.sidebarSize());
-    }
-  }
-
-  /**
-   * @param {boolean} reverse
-   * @param {function()=} callback
-   */
-  _animate(reverse, callback) {
-    const animationTime = 50;
-    this._animationCallback = callback || null;
-
-    let animatedMarginPropertyName;
-    if (this._isVertical)
-      animatedMarginPropertyName = this._secondIsSidebar ? 'margin-right' : 'margin-left';
-    else
-      animatedMarginPropertyName = this._secondIsSidebar ? 'margin-bottom' : 'margin-top';
-
-    const marginFrom = reverse ? '0' : '-' + UI.zoomManager.dipToCSS(this._sidebarSizeDIP) + 'px';
-    const marginTo = reverse ? '-' + UI.zoomManager.dipToCSS(this._sidebarSizeDIP) + 'px' : '0';
-
-    // This order of things is important.
-    // 1. Resize main element early and force layout.
-    this.contentElement.style.setProperty(animatedMarginPropertyName, marginFrom);
-    if (!reverse) {
-      suppressUnused(this._mainElement.offsetWidth);
-      suppressUnused(this._sidebarElement.offsetWidth);
-    }
-
-    // 2. Issue onresize to the sidebar element, its size won't change.
-    if (!reverse)
-      this._sidebarWidget.doResize();
-
-    // 3. Configure and run animation
-    this.contentElement.style.setProperty('transition', animatedMarginPropertyName + ' ' + animationTime + 'ms linear');
-
-    const boundAnimationFrame = animationFrame.bind(this);
-    let startTime;
-    /**
-     * @this {UI.SplitWidget}
-     */
-    function animationFrame() {
-      this._animationFrameHandle = 0;
-
-      if (!startTime) {
-        // Kick animation on first frame.
-        this.contentElement.style.setProperty(animatedMarginPropertyName, marginTo);
-        startTime = window.performance.now();
-      } else if (window.performance.now() < startTime + animationTime) {
-        // Process regular animation frame.
-        if (this._mainWidget)
-          this._mainWidget.doResize();
-      } else {
-        // Complete animation.
-        this._cancelAnimation();
-        if (this._mainWidget)
-          this._mainWidget.doResize();
-        this.dispatchEventToListeners(UI.SplitWidget.Events.SidebarSizeChanged, this.sidebarSize());
-        return;
-      }
-      this._animationFrameHandle = this.contentElement.window().requestAnimationFrame(boundAnimationFrame);
-    }
-    this._animationFrameHandle = this.contentElement.window().requestAnimationFrame(boundAnimationFrame);
-  }
-
-  _cancelAnimation() {
-    this.contentElement.style.removeProperty('margin-top');
-    this.contentElement.style.removeProperty('margin-right');
-    this.contentElement.style.removeProperty('margin-bottom');
-    this.contentElement.style.removeProperty('margin-left');
-    this.contentElement.style.removeProperty('transition');
-
-    if (this._animationFrameHandle) {
-      this.contentElement.window().cancelAnimationFrame(this._animationFrameHandle);
-      this._animationFrameHandle = 0;
-    }
-    if (this._animationCallback) {
-      this._animationCallback();
-      this._animationCallback = null;
-    }
-  }
-
-  /**
-   * @param {number} sidebarSize
-   * @param {boolean=} userAction
-   * @return {number}
-   */
-  _applyConstraints(sidebarSize, userAction) {
-    const totalSize = this._totalSizeDIP();
-    const zoomFactor = this._constraintsInDip ? 1 : UI.zoomManager.zoomFactor();
-
-    let constraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new UI.Constraints();
-    let minSidebarSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
-    if (!minSidebarSize)
-      minSidebarSize = UI.SplitWidget.MinPadding;
-    minSidebarSize *= zoomFactor;
-    if (this._sidebarMinimized)
-      sidebarSize = minSidebarSize;
-
-    let preferredSidebarSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
-    if (!preferredSidebarSize)
-      preferredSidebarSize = UI.SplitWidget.MinPadding;
-    preferredSidebarSize *= zoomFactor;
-    // Allow sidebar to be less than preferred by explicit user action.
-    if (sidebarSize < preferredSidebarSize)
-      preferredSidebarSize = Math.max(sidebarSize, minSidebarSize);
-    preferredSidebarSize += zoomFactor;  // 1 css pixel for splitter border.
-
-    constraints = this._mainWidget ? this._mainWidget.constraints() : new UI.Constraints();
-    let minMainSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
-    if (!minMainSize)
-      minMainSize = UI.SplitWidget.MinPadding;
-    minMainSize *= zoomFactor;
-
-    let preferredMainSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
-    if (!preferredMainSize)
-      preferredMainSize = UI.SplitWidget.MinPadding;
-    preferredMainSize *= zoomFactor;
-    const savedMainSize = this.isVertical() ? this._savedVerticalMainSize : this._savedHorizontalMainSize;
-    if (savedMainSize !== null)
-      preferredMainSize = Math.min(preferredMainSize, savedMainSize * zoomFactor);
-    if (userAction)
-      preferredMainSize = minMainSize;
-
-    // Enough space for preferred.
-    const totalPreferred = preferredMainSize + preferredSidebarSize;
-    if (totalPreferred <= totalSize)
-      return Number.constrain(sidebarSize, preferredSidebarSize, totalSize - preferredMainSize);
-
-    // Enough space for minimum.
-    if (minMainSize + minSidebarSize <= totalSize) {
-      const delta = totalPreferred - totalSize;
-      const sidebarDelta = delta * preferredSidebarSize / totalPreferred;
-      sidebarSize = preferredSidebarSize - sidebarDelta;
-      return Number.constrain(sidebarSize, minSidebarSize, totalSize - minMainSize);
-    }
-
-    // Not enough space even for minimum sizes.
-    return Math.max(0, totalSize - minMainSize);
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._forceUpdateLayout();
-    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.zoomManager.removeEventListener(UI.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._updateLayout();
-  }
-
-  /**
-   * @override
-   */
-  onLayout() {
-    this._updateLayout();
-  }
-
-  /**
-   * @override
-   * @return {!UI.Constraints}
-   */
-  calculateConstraints() {
-    if (this._showMode === UI.SplitWidget.ShowMode.OnlyMain)
-      return this._mainWidget ? this._mainWidget.constraints() : new UI.Constraints();
-    if (this._showMode === UI.SplitWidget.ShowMode.OnlySidebar)
-      return this._sidebarWidget ? this._sidebarWidget.constraints() : new UI.Constraints();
-
-    let mainConstraints = this._mainWidget ? this._mainWidget.constraints() : new UI.Constraints();
-    let sidebarConstraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new UI.Constraints();
-    const min = UI.SplitWidget.MinPadding;
-    if (this._isVertical) {
-      mainConstraints = mainConstraints.widthToMax(min).addWidth(1);  // 1 for splitter
-      sidebarConstraints = sidebarConstraints.widthToMax(min);
-      return mainConstraints.addWidth(sidebarConstraints).heightToMax(sidebarConstraints);
-    } else {
-      mainConstraints = mainConstraints.heightToMax(min).addHeight(1);  // 1 for splitter
-      sidebarConstraints = sidebarConstraints.heightToMax(min);
-      return mainConstraints.widthToMax(sidebarConstraints).addHeight(sidebarConstraints);
-    }
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onResizeStart(event) {
-    this._resizeStartSizeDIP = this._sidebarSizeDIP;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onResizeUpdate(event) {
-    const offset = event.data.currentPosition - event.data.startPosition;
-    const offsetDIP = UI.zoomManager.cssToDIP(offset);
-    const newSizeDIP =
-        this._secondIsSidebar ? this._resizeStartSizeDIP - offsetDIP : this._resizeStartSizeDIP + offsetDIP;
-    const constrainedSizeDIP = this._applyConstraints(newSizeDIP, true);
-    this._savedSidebarSizeDIP = constrainedSizeDIP;
-    this._saveSetting();
-    this._innerSetSidebarSizeDIP(constrainedSizeDIP, false, true);
-    if (this.isVertical())
-      this._savedVerticalMainSize = this._totalSizeDIP() - this._sidebarSizeDIP;
-    else
-      this._savedHorizontalMainSize = this._totalSizeDIP() - this._sidebarSizeDIP;
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onResizeEnd(event) {
-    this._resizeStartSizeDIP = 0;
-  }
-
-  /**
-   * @param {boolean=} noSplitter
-   */
-  hideDefaultResizer(noSplitter) {
-    this.uninstallResizer(this._resizerElement);
-    this._sidebarElement.classList.toggle('no-default-splitter', noSplitter);
-  }
-
-  /**
-   * @param {!Element} resizerElement
-   */
-  installResizer(resizerElement) {
-    this._resizerWidget.addElement(resizerElement);
-  }
-
-  /**
-   * @param {!Element} resizerElement
-   */
-  uninstallResizer(resizerElement) {
-    this._resizerWidget.removeElement(resizerElement);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasCustomResizer() {
-    const elements = this._resizerWidget.elements();
-    return elements.length > 1 || (elements.length === 1 && elements[0] !== this._resizerElement);
-  }
-
-  /**
-   * @param {!Element} resizer
-   * @param {boolean} on
-   */
-  toggleResizer(resizer, on) {
-    if (on)
-      this.installResizer(resizer);
-    else
-      this.uninstallResizer(resizer);
-  }
-
-  /**
-   * @return {?UI.SplitWidget.SettingForOrientation}
-   */
-  _settingForOrientation() {
-    const state = this._setting ? this._setting.get() : {};
-    return this._isVertical ? state.vertical : state.horizontal;
-  }
-
-  /**
-   * @return {number}
-   */
-  _preferredSidebarSizeDIP() {
-    let size = this._savedSidebarSizeDIP;
-    if (!size) {
-      size = this._isVertical ? this._defaultSidebarWidth : this._defaultSidebarHeight;
-      // If we have default value in percents, calculate it on first use.
-      if (0 < size && size < 1)
-        size *= this._totalSizeDIP();
-    }
-    return size;
-  }
-
-  _restoreSidebarSizeFromSettings() {
-    const settingForOrientation = this._settingForOrientation();
-    this._savedSidebarSizeDIP = settingForOrientation ? settingForOrientation.size : 0;
-  }
-
-  _restoreAndApplyShowModeFromSettings() {
-    const orientationState = this._settingForOrientation();
-    this._savedShowMode = orientationState && orientationState.showMode ? orientationState.showMode : this._showMode;
-    this._showMode = this._savedShowMode;
-
-    switch (this._savedShowMode) {
-      case UI.SplitWidget.ShowMode.Both:
-        this.showBoth();
-        break;
-      case UI.SplitWidget.ShowMode.OnlyMain:
-        this.hideSidebar();
-        break;
-      case UI.SplitWidget.ShowMode.OnlySidebar:
-        this.hideMain();
-        break;
-    }
-  }
-
-  _saveShowModeToSettings() {
-    this._savedShowMode = this._showMode;
-    this._saveSetting();
-  }
-
-  _saveSetting() {
-    if (!this._setting)
-      return;
-    const state = this._setting.get();
-    const orientationState = (this._isVertical ? state.vertical : state.horizontal) || {};
-
-    orientationState.size = this._savedSidebarSizeDIP;
-    if (this._shouldSaveShowMode)
-      orientationState.showMode = this._savedShowMode;
-
-    if (this._isVertical)
-      state.vertical = orientationState;
-    else
-      state.horizontal = orientationState;
-    this._setting.set(state);
-  }
-
-  _forceUpdateLayout() {
-    // Force layout even if sidebar size does not change.
-    this._sidebarSizeDIP = -1;
-    this._updateLayout();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _onZoomChanged(event) {
-    this._forceUpdateLayout();
-  }
-
-  /**
-   * @param {string} title
-   * @return {!UI.ToolbarButton}
-   */
-  createShowHideSidebarButton(title) {
-    this._showHideSidebarButtonTitle = Common.UIString(title);
-    this._showHideSidebarButton = new UI.ToolbarButton('', '');
-    this._showHideSidebarButton.addEventListener(UI.ToolbarButton.Events.Click, buttonClicked, this);
-    this._updateShowHideSidebarButton();
-
-    /**
-     * @param {!Common.Event} event
-     * @this {UI.SplitWidget}
-     */
-    function buttonClicked(event) {
-      if (this._showMode !== UI.SplitWidget.ShowMode.Both)
-        this.showBoth(true);
-      else
-        this.hideSidebar(true);
-    }
-
-    return this._showHideSidebarButton;
-  }
-
-  _updateShowHideSidebarButton() {
-    if (!this._showHideSidebarButton)
-      return;
-    const sidebarHidden = this._showMode === UI.SplitWidget.ShowMode.OnlyMain;
-    let glyph = '';
-    if (sidebarHidden) {
-      glyph = this.isVertical() ?
-          (this.isSidebarSecond() ? 'largeicon-show-right-sidebar' : 'largeicon-show-left-sidebar') :
-          (this.isSidebarSecond() ? 'largeicon-show-bottom-sidebar' : 'largeicon-show-top-sidebar');
-    } else {
-      glyph = this.isVertical() ?
-          (this.isSidebarSecond() ? 'largeicon-hide-right-sidebar' : 'largeicon-hide-left-sidebar') :
-          (this.isSidebarSecond() ? 'largeicon-hide-bottom-sidebar' : 'largeicon-hide-top-sidebar');
-    }
-    this._showHideSidebarButton.setGlyph(glyph);
-    this._showHideSidebarButton.setTitle(
-        sidebarHidden ? Common.UIString('Show %s', this._showHideSidebarButtonTitle) :
-                        Common.UIString('Hide %s', this._showHideSidebarButtonTitle));
-  }
-};
-
-/** @typedef {{showMode: string, size: number}} */
-UI.SplitWidget.SettingForOrientation;
-
-UI.SplitWidget.ShowMode = {
-  Both: 'Both',
-  OnlyMain: 'OnlyMain',
-  OnlySidebar: 'OnlySidebar'
-};
-
-/** @enum {symbol} */
-UI.SplitWidget.Events = {
-  SidebarSizeChanged: Symbol('SidebarSizeChanged'),
-  ShowModeChanged: Symbol('ShowModeChanged')
-};
-
-UI.SplitWidget.MinPadding = 20;
diff --git a/front_end/ui/SuggestBox.js b/front_end/ui/SuggestBox.js
deleted file mode 100644
index e3cc151..0000000
--- a/front_end/ui/SuggestBox.js
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-UI.SuggestBoxDelegate = function() {};
-
-UI.SuggestBoxDelegate.prototype = {
-  /**
-   * @param {string} suggestion
-   * @param {boolean=} isIntermediateSuggestion
-   */
-  applySuggestion(suggestion, isIntermediateSuggestion) {},
-
-  /**
-   * acceptSuggestion will be always called after call to applySuggestion with isIntermediateSuggestion being equal to false.
-   */
-  acceptSuggestion() {},
-};
-
-/**
- * @implements {UI.ListDelegate}
- */
-UI.SuggestBox = class {
-  /**
-   * @param {!UI.SuggestBoxDelegate} suggestBoxDelegate
-   * @param {number=} maxItemsHeight
-   * @param {boolean=} captureEnter
-   */
-  constructor(suggestBoxDelegate, maxItemsHeight, captureEnter) {
-    this._suggestBoxDelegate = suggestBoxDelegate;
-    this._maxItemsHeight = maxItemsHeight;
-    this._captureEnter = captureEnter;
-    this._rowHeight = 17;
-    this._userInteracted = false;
-    this._userEnteredText = '';
-    this._defaultSelectionIsDimmed = false;
-
-    /** @type {?string} */
-    this._onlyCompletion = null;
-
-    /** @type {!UI.ListModel<!UI.SuggestBox.Suggestion>} */
-    this._items = new UI.ListModel();
-    /** @type {!UI.ListControl<!UI.SuggestBox.Suggestion>} */
-    this._list = new UI.ListControl(this._items, this, UI.ListMode.EqualHeightItems);
-    this._element = this._list.element;
-    this._element.classList.add('suggest-box');
-    this._element.addEventListener('mousedown', event => event.preventDefault(), true);
-    this._element.addEventListener('click', this._onClick.bind(this), false);
-
-    this._glassPane = new UI.GlassPane();
-    this._glassPane.setAnchorBehavior(UI.GlassPane.AnchorBehavior.PreferBottom);
-    this._glassPane.setOutsideClickCallback(this.hide.bind(this));
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this._glassPane.contentElement, 'ui/suggestBox.css');
-    shadowRoot.appendChild(this._element);
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setDefaultSelectionIsDimmed(value) {
-    this._defaultSelectionIsDimmed = value;
-    this._element.classList.toggle('default-selection-is-dimmed', value);
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  _setUserInteracted(value) {
-    this._userInteracted = value;
-    this._element.classList.toggle('user-has-interacted', value);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  visible() {
-    return this._glassPane.isShowing();
-  }
-
-  /**
-   * @param {!AnchorBox} anchorBox
-   */
-  setPosition(anchorBox) {
-    this._glassPane.setContentAnchorBox(anchorBox);
-  }
-
-  /**
-   * @param {!UI.SuggestBox.Suggestions} items
-   */
-  _updateMaxSize(items) {
-    const maxWidth = this._maxWidth(items);
-    const length = this._maxItemsHeight ? Math.min(this._maxItemsHeight, items.length) : items.length;
-    const maxHeight = length * this._rowHeight;
-    this._glassPane.setMaxContentSize(new UI.Size(maxWidth, maxHeight));
-  }
-
-  /**
-   * @param {!UI.SuggestBox.Suggestions} items
-   * @return {number}
-   */
-  _maxWidth(items) {
-    const kMaxWidth = 300;
-    if (!items.length)
-      return kMaxWidth;
-    let maxItem;
-    let maxLength = -Infinity;
-    for (let i = 0; i < items.length; i++) {
-      const length = (items[i].title || items[i].text).length + (items[i].subtitle || '').length;
-      if (length > maxLength) {
-        maxLength = length;
-        maxItem = items[i];
-      }
-    }
-    const element = this.createElementForItem(/** @type {!UI.SuggestBox.Suggestion} */ (maxItem));
-    return Math.min(kMaxWidth, UI.measurePreferredSize(element, this._element).width);
-  }
-
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  _show() {
-    if (this.visible())
-      return;
-    // TODO(dgozman): take document as a parameter.
-    this._glassPane.show(document);
-    this._rowHeight =
-        UI.measurePreferredSize(this.createElementForItem({text: '1', subtitle: '12'}), this._element).height;
-  }
-
-  hide() {
-    if (!this.visible())
-      return;
-    this._setUserInteracted(false);
-    this._glassPane.hide();
-  }
-
-  /**
-   * @param {boolean=} isIntermediateSuggestion
-   * @return {boolean}
-   */
-  _applySuggestion(isIntermediateSuggestion) {
-    if (this._onlyCompletion) {
-      UI.ARIAUtils.alert(ls`${this._onlyCompletion}, suggestion`, this._element);
-      this._suggestBoxDelegate.applySuggestion(this._onlyCompletion, isIntermediateSuggestion);
-      return true;
-    }
-    const suggestion = this._list.selectedItem() ? this._list.selectedItem().text : '';
-    if (suggestion)
-      UI.ARIAUtils.alert(ls`${suggestion}, suggestion`, this._element);
-    this._suggestBoxDelegate.applySuggestion(suggestion, isIntermediateSuggestion);
-
-    return this.visible() && !!suggestion;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  acceptSuggestion() {
-    const result = this._applySuggestion();
-    this.hide();
-    if (!result)
-      return false;
-
-    this._suggestBoxDelegate.acceptSuggestion();
-
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SuggestBox.Suggestion} item
-   * @return {!Element}
-   */
-  createElementForItem(item) {
-    const query = this._userEnteredText;
-    const element = createElementWithClass('div', 'suggest-box-content-item source-code');
-    if (item.iconType) {
-      const icon = UI.Icon.create(item.iconType, 'suggestion-icon');
-      element.appendChild(icon);
-    }
-    if (item.isSecondary)
-      element.classList.add('secondary');
-    element.tabIndex = -1;
-    const maxTextLength = 50 + query.length;
-    const displayText = (item.title || item.text).trimEnd(maxTextLength);
-
-    const titleElement = element.createChild('span', 'suggestion-title');
-    const index = displayText.toLowerCase().indexOf(query.toLowerCase());
-    if (index > 0)
-      titleElement.createChild('span').textContent = displayText.substring(0, index);
-    if (index > -1)
-      titleElement.createChild('span', 'query').textContent = displayText.substring(index, index + query.length);
-    titleElement.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0);
-    titleElement.createChild('span', 'spacer');
-    if (item.subtitle) {
-      const subtitleElement = element.createChild('span', 'suggestion-subtitle');
-      subtitleElement.textContent = item.subtitle.trimEnd(maxTextLength - displayText.length);
-    }
-    return element;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SuggestBox.Suggestion} item
-   * @return {number}
-   */
-  heightForItem(item) {
-    return this._rowHeight;
-  }
-
-  /**
-   * @override
-   * @param {!UI.SuggestBox.Suggestion} item
-   * @return {boolean}
-   */
-  isItemSelectable(item) {
-    return true;
-  }
-
-  /**
-   * @override
-   * @param {?UI.SuggestBox.Suggestion} from
-   * @param {?UI.SuggestBox.Suggestion} to
-   * @param {?Element} fromElement
-   * @param {?Element} toElement
-   */
-  selectedItemChanged(from, to, fromElement, toElement) {
-    if (fromElement)
-      fromElement.classList.remove('selected', 'force-white-icons');
-    if (toElement) {
-      toElement.classList.add('selected');
-      if (fromElement || this._userInteracted || !this._defaultSelectionIsDimmed)
-        toElement.classList.add('force-white-icons');
-    }
-    this._applySuggestion(true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onClick(event) {
-    const item = this._list.itemForNode(/** @type {?Node} */ (event.target));
-    if (!item)
-      return;
-
-    this._list.selectItem(item);
-    this._setUserInteracted(true);
-    this.acceptSuggestion();
-    event.consume(true);
-  }
-
-  /**
-   * @param {!UI.SuggestBox.Suggestions} completions
-   * @param {boolean} canShowForSingleItem
-   * @param {string} userEnteredText
-   * @return {boolean}
-   */
-  _canShowBox(completions, canShowForSingleItem, userEnteredText) {
-    if (!completions || !completions.length)
-      return false;
-
-    if (completions.length > 1)
-      return true;
-
-    if (!completions[0].text.startsWith(userEnteredText))
-      return true;
-
-    // Do not show a single suggestion if it is the same as user-entered query, even if allowed to show single-item suggest boxes.
-    return canShowForSingleItem && completions[0].text !== userEnteredText;
-  }
-
-  /**
-   * @param {!AnchorBox} anchorBox
-   * @param {!UI.SuggestBox.Suggestions} completions
-   * @param {boolean} selectHighestPriority
-   * @param {boolean} canShowForSingleItem
-   * @param {string} userEnteredText
-   */
-  updateSuggestions(anchorBox, completions, selectHighestPriority, canShowForSingleItem, userEnteredText) {
-    this._onlyCompletion = null;
-    if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
-      this._userEnteredText = userEnteredText;
-
-      this._show();
-      this._updateMaxSize(completions);
-      this._glassPane.setContentAnchorBox(anchorBox);
-      this._list.invalidateItemHeight();
-      this._items.replaceAll(completions);
-
-      if (selectHighestPriority) {
-        let highestPriorityItem = completions[0];
-        let highestPriority = completions[0].priority || 0;
-        for (let i = 0; i < completions.length; i++) {
-          const priority = completions[i].priority || 0;
-          if (highestPriority < priority) {
-            highestPriority = priority;
-            highestPriorityItem = completions[i];
-          }
-        }
-        this._list.selectItem(highestPriorityItem, true);
-      } else {
-        this._list.selectItem(null);
-      }
-    } else {
-      if (completions.length === 1) {
-        this._onlyCompletion = completions[0].text;
-        this._applySuggestion(true);
-      }
-      this.hide();
-    }
-  }
-
-  /**
-   * @param {!KeyboardEvent} event
-   * @return {boolean}
-   */
-  keyPressed(event) {
-    let selected = false;
-    switch (event.key) {
-      case 'Enter':
-        return this.enterKeyPressed();
-      case 'ArrowUp':
-        selected = this._list.selectPreviousItem(true, false);
-        break;
-      case 'ArrowDown':
-        selected = this._list.selectNextItem(true, false);
-        break;
-      case 'PageUp':
-        selected = this._list.selectItemPreviousPage(false);
-        break;
-      case 'PageDown':
-        selected = this._list.selectItemNextPage(false);
-        break;
-      default:
-        return false;
-    }
-    if (selected) {
-      this._setUserInteracted(true);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  enterKeyPressed() {
-    if (!this._userInteracted && this._captureEnter)
-      return false;
-
-    const hasSelectedItem = !!this._list.selectedItem() || !!this._onlyCompletion;
-    this.acceptSuggestion();
-
-    // Report the event as non-handled if there is no selected item,
-    // to commit the input or handle it otherwise.
-    return hasSelectedItem;
-  }
-};
-
-/**
- * @typedef {!{text: string, subtitle: (string|undefined), iconType: (string|undefined), priority: (number|undefined), isSecondary: (boolean|undefined), title: (string|undefined)}}
- */
-UI.SuggestBox.Suggestion;
-
-/**
- * @typedef {!Array<!UI.SuggestBox.Suggestion>}
- */
-UI.SuggestBox.Suggestions;
diff --git a/front_end/ui/SyntaxHighlighter.js b/front_end/ui/SyntaxHighlighter.js
deleted file mode 100644
index f4b4aa2..0000000
--- a/front_end/ui/SyntaxHighlighter.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.SyntaxHighlighter = class {
-  /**
-   * @param {string} mimeType
-   * @param {boolean} stripExtraWhitespace
-   */
-  constructor(mimeType, stripExtraWhitespace) {
-    this._mimeType = mimeType;
-    this._stripExtraWhitespace = stripExtraWhitespace;
-  }
-
-  /**
-   * @param {string} content
-   * @param {string} className
-   * @return {!Element}
-   */
-  createSpan(content, className) {
-    const span = createElement('span');
-    span.className = 'cm-' + className;
-    if (this._stripExtraWhitespace && className !== 'whitespace')
-      content = content.replace(/^[\n\r]*/, '').replace(/\s*$/, '');
-    span.createTextChild(content);
-    return span;
-  }
-
-  /**
-   * @param {!Element} node
-   * @return {!Promise.<undefined>}
-   */
-  syntaxHighlightNode(node) {
-    const lines = node.textContent.split('\n');
-    let plainTextStart;
-    let line;
-
-    return self.runtime.extension(TextUtils.TokenizerFactory).instance().then(processTokens.bind(this));
-
-    /**
-     * @param {!TextUtils.TokenizerFactory} tokenizerFactory
-     * @this {UI.SyntaxHighlighter}
-     */
-    function processTokens(tokenizerFactory) {
-      node.removeChildren();
-      const tokenize = tokenizerFactory.createTokenizer(this._mimeType);
-      for (let i = 0; i < lines.length; ++i) {
-        line = lines[i];
-        plainTextStart = 0;
-        tokenize(line, processToken.bind(this));
-        if (plainTextStart < line.length) {
-          const plainText = line.substring(plainTextStart, line.length);
-          node.createTextChild(plainText);
-        }
-        if (i < lines.length - 1)
-          node.createTextChild('\n');
-      }
-    }
-
-    /**
-     * @param {string} token
-     * @param {?string} tokenType
-     * @param {number} column
-     * @param {number} newColumn
-     * @this {UI.SyntaxHighlighter}
-     */
-    function processToken(token, tokenType, column, newColumn) {
-      if (!tokenType)
-        return;
-
-      if (column > plainTextStart) {
-        const plainText = line.substring(plainTextStart, column);
-        node.createTextChild(plainText);
-      }
-      node.appendChild(this.createSpan(token, tokenType));
-      plainTextStart = newColumn;
-    }
-  }
-};
diff --git a/front_end/ui/TabbedPane.js b/front_end/ui/TabbedPane.js
deleted file mode 100644
index 2b5bdd7..0000000
--- a/front_end/ui/TabbedPane.js
+++ /dev/null
@@ -1,1290 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.TabbedPane = class extends UI.VBox {
-  constructor() {
-    super(true);
-    this.registerRequiredCSS('ui/tabbedPane.css');
-    this.element.classList.add('tabbed-pane');
-    this.contentElement.classList.add('tabbed-pane-shadow');
-    this.contentElement.tabIndex = -1;
-    this._headerElement = this.contentElement.createChild('div', 'tabbed-pane-header');
-    this._headerContentsElement = this._headerElement.createChild('div', 'tabbed-pane-header-contents');
-    this._tabSlider = createElementWithClass('div', 'tabbed-pane-tab-slider');
-    this._tabsElement = this._headerContentsElement.createChild('div', 'tabbed-pane-header-tabs');
-    this._tabsElement.setAttribute('role', 'tablist');
-    this._tabsElement.addEventListener('keydown', this._keyDown.bind(this), false);
-    this._contentElement = this.contentElement.createChild('div', 'tabbed-pane-content');
-    this._contentElement.setAttribute('role', 'tabpanel');
-    this._contentElement.createChild('content');
-    /** @type {!Array.<!UI.TabbedPaneTab>} */
-    this._tabs = [];
-    /** @type {!Array.<!UI.TabbedPaneTab>} */
-    this._tabsHistory = [];
-    /** @type {!Map<string, !UI.TabbedPaneTab>} */
-    this._tabsById = new Map();
-    this._currentTabLocked = false;
-    this._autoSelectFirstItemOnShow = true;
-
-    this._dropDownButton = this._createDropDownButton();
-    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this._zoomChanged, this);
-    this.makeTabSlider();
-  }
-
-  /**
-   * @param {string} name
-   */
-  setAccessibleName(name) {
-    UI.ARIAUtils.setAccessibleName(this._tabsElement, name);
-  }
-
-  /**
-   * @param {boolean} locked
-   */
-  setCurrentTabLocked(locked) {
-    this._currentTabLocked = locked;
-    this._headerElement.classList.toggle('locked', this._currentTabLocked);
-  }
-
-  /**
-   * @param {boolean} autoSelect
-   */
-  setAutoSelectFirstItemOnShow(autoSelect) {
-    this._autoSelectFirstItemOnShow = autoSelect;
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  get visibleView() {
-    return this._currentTab ? this._currentTab.view : null;
-  }
-
-  /**
-   * @return {!Array.<string>}
-   */
-  tabIds() {
-    return this._tabs.map(tab => tab._id);
-  }
-
-  /**
-   * @param {string} tabId
-   * @return {number}
-   */
-  tabIndex(tabId) {
-    return this._tabs.findIndex(tab => tab.id === tabId);
-  }
-
-  /**
-   * @return {!Array.<!UI.Widget>}
-   */
-  tabViews() {
-    return this._tabs.map(tab => tab.view);
-  }
-
-  /**
-   * @param {string} tabId
-   * @return {?UI.Widget}
-   */
-  tabView(tabId) {
-    return this._tabsById.has(tabId) ? this._tabsById.get(tabId).view : null;
-  }
-
-  /**
-   * @return {?string}
-   */
-  get selectedTabId() {
-    return this._currentTab ? this._currentTab.id : null;
-  }
-
-  /**
-   * @param {boolean} shrinkableTabs
-   */
-  setShrinkableTabs(shrinkableTabs) {
-    this._shrinkableTabs = shrinkableTabs;
-  }
-
-  makeVerticalTabLayout() {
-    this._verticalTabLayout = true;
-    this._setTabSlider(false);
-    this.contentElement.classList.add('vertical-tab-layout');
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @param {boolean} closeableTabs
-   */
-  setCloseableTabs(closeableTabs) {
-    this._closeableTabs = closeableTabs;
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (this.visibleView)
-      this.visibleView.focus();
-    else
-      this.contentElement.focus();
-  }
-
-  /**
-   * @return {!Element}
-   */
-  headerElement() {
-    return this._headerElement;
-  }
-
-  /**
-   * @param {string} id
-   * @return {boolean}
-   */
-  isTabCloseable(id) {
-    const tab = this._tabsById.get(id);
-    return tab ? tab.isCloseable() : false;
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTabDelegate} delegate
-   */
-  setTabDelegate(delegate) {
-    const tabs = this._tabs.slice();
-    for (let i = 0; i < tabs.length; ++i)
-      tabs[i].setDelegate(delegate);
-    this._delegate = delegate;
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} tabTitle
-   * @param {!UI.Widget} view
-   * @param {string=} tabTooltip
-   * @param {boolean=} userGesture
-   * @param {boolean=} isCloseable
-   * @param {number=} index
-   */
-  appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index) {
-    isCloseable = typeof isCloseable === 'boolean' ? isCloseable : this._closeableTabs;
-    const tab = new UI.TabbedPaneTab(this, id, tabTitle, isCloseable, view, tabTooltip);
-    tab.setDelegate(this._delegate);
-    console.assert(!this._tabsById.has(id), `Tabbed pane already contains a tab with id '${id}'`);
-    this._tabsById.set(id, tab);
-    if (index !== undefined)
-      this._tabs.splice(index, 0, tab);
-    else
-      this._tabs.push(tab);
-    this._tabsHistory.push(tab);
-    if (this._tabsHistory[0] === tab && this.isShowing())
-      this.selectTab(tab.id, userGesture);
-    this._updateTabElements();
-  }
-
-  /**
-   * @param {string} id
-   * @param {boolean=} userGesture
-   */
-  closeTab(id, userGesture) {
-    this.closeTabs([id], userGesture);
-  }
-
-
-  /**
-   * @param {!Array.<string>} ids
-   * @param {boolean=} userGesture
-   */
-  closeTabs(ids, userGesture) {
-    const focused = this.hasFocus();
-    for (let i = 0; i < ids.length; ++i)
-      this._innerCloseTab(ids[i], userGesture);
-    this._updateTabElements();
-    if (this._tabsHistory.length)
-      this.selectTab(this._tabsHistory[0].id, false);
-    if (focused)
-      this.focus();
-  }
-
-  /**
-   * @param {string} id
-   * @param {boolean=} userGesture
-   */
-  _innerCloseTab(id, userGesture) {
-    if (!this._tabsById.has(id))
-      return;
-    if (userGesture && !this._tabsById.get(id)._closeable)
-      return;
-    if (this._currentTab && this._currentTab.id === id)
-      this._hideCurrentTab();
-
-    const tab = this._tabsById.get(id);
-    this._tabsById.delete(id);
-
-    this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
-    this._tabs.splice(this._tabs.indexOf(tab), 1);
-    if (tab._shown)
-      this._hideTabElement(tab);
-
-    const eventData = {tabId: id, view: tab.view, isUserGesture: userGesture};
-    this.dispatchEventToListeners(UI.TabbedPane.Events.TabClosed, eventData);
-    return true;
-  }
-
-  /**
-   * @param {string} tabId
-   * @return {boolean}
-   */
-  hasTab(tabId) {
-    return this._tabsById.has(tabId);
-  }
-
-  /**
-   * @return {!Array.<string>}
-   */
-  allTabs() {
-    return this._tabs.map(function(tab) {
-      return tab.id;
-    });
-  }
-
-  /**
-   * @param {string} id
-   * @return {!Array.<string>}
-   */
-  otherTabs(id) {
-    const result = [];
-    for (let i = 0; i < this._tabs.length; ++i) {
-      if (this._tabs[i].id !== id)
-        result.push(this._tabs[i].id);
-    }
-    return result;
-  }
-
-  /**
-   * @param {string} id
-   * @return {!Array.<string>}
-   */
-  _tabsToTheRight(id) {
-    let index = -1;
-    for (let i = 0; i < this._tabs.length; ++i) {
-      if (this._tabs[i].id === id) {
-        index = i;
-        break;
-      }
-    }
-    if (index === -1)
-      return [];
-    return this._tabs.slice(index + 1).map(function(tab) {
-      return tab.id;
-    });
-  }
-
-  _viewHasFocus() {
-    if (this.visibleView)
-      return this.visibleView.hasFocus();
-    return this.contentElement === this.contentElement.getComponentRoot().activeElement;
-  }
-
-  /**
-   * @param {string} id
-   * @param {boolean=} userGesture
-   * @return {boolean}
-   */
-  selectTab(id, userGesture) {
-    if (this._currentTabLocked)
-      return false;
-    const focused = this._viewHasFocus();
-    const tab = this._tabsById.get(id);
-    if (!tab)
-      return false;
-    if (this._currentTab && this._currentTab.id === id)
-      return true;
-
-    this.suspendInvalidations();
-    this._hideCurrentTab();
-    this._showTab(tab);
-    this.resumeInvalidations();
-    this._currentTab = tab;
-
-    this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
-    this._tabsHistory.splice(0, 0, tab);
-
-    this._updateTabElements();
-    if (focused)
-      this.focus();
-
-    const eventData = {tabId: id, view: tab.view, isUserGesture: userGesture};
-    this.dispatchEventToListeners(UI.TabbedPane.Events.TabSelected, eventData);
-    return true;
-  }
-
-  selectNextTab() {
-    const index = this._tabs.indexOf(this._currentTab);
-    const nextIndex = mod(index + 1, this._tabs.length);
-    this.selectTab(this._tabs[nextIndex].id, true);
-  }
-
-  selectPrevTab() {
-    const index = this._tabs.indexOf(this._currentTab);
-    const nextIndex = mod(index - 1, this._tabs.length);
-    this.selectTab(this._tabs[nextIndex].id, true);
-  }
-
-  /**
-   * @param {number} tabsCount
-   * @return {!Array.<string>}
-   */
-  lastOpenedTabIds(tabsCount) {
-    function tabToTabId(tab) {
-      return tab.id;
-    }
-
-    return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
-  }
-
-  /**
-   * @param {string} id
-   * @param {?UI.Icon} icon
-   */
-  setTabIcon(id, icon) {
-    const tab = this._tabsById.get(id);
-    tab._setIcon(icon);
-    this._updateTabElements();
-  }
-
-  /**
-   * @param {string} id
-   * @param {boolean} enabled
-   */
-  setTabEnabled(id, enabled) {
-    const tab = this._tabsById.get(id);
-    tab.tabElement.classList.toggle('disabled', !enabled);
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} className
-   * @param {boolean=} force
-   */
-  toggleTabClass(id, className, force) {
-    const tab = this._tabsById.get(id);
-    if (tab._toggleClass(className, force))
-      this._updateTabElements();
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _zoomChanged(event) {
-    for (let i = 0; i < this._tabs.length; ++i)
-      delete this._tabs[i]._measuredWidth;
-    if (this.isShowing())
-      this._updateTabElements();
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} tabTitle
-   * @param {string=} tabTooltip
-   */
-  changeTabTitle(id, tabTitle, tabTooltip) {
-    const tab = this._tabsById.get(id);
-    if (tabTooltip !== undefined)
-      tab.tooltip = tabTooltip;
-    if (tab.title !== tabTitle) {
-      tab.title = tabTitle;
-      this._updateTabElements();
-    }
-  }
-
-  /**
-   * @param {string} id
-   * @param {!UI.Widget} view
-   */
-  changeTabView(id, view) {
-    const tab = this._tabsById.get(id);
-    if (tab.view === view)
-      return;
-
-    this.suspendInvalidations();
-    const isSelected = this._currentTab && this._currentTab.id === id;
-    const shouldFocus = tab.view.hasFocus();
-    if (isSelected)
-      this._hideTab(tab);
-    tab.view = view;
-    if (isSelected)
-      this._showTab(tab);
-    if (shouldFocus)
-      tab.view.focus();
-    this.resumeInvalidations();
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._updateTabElements();
-  }
-
-  headerResized() {
-    this._updateTabElements();
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    const effectiveTab = this._currentTab || this._tabsHistory[0];
-    if (effectiveTab && this._autoSelectFirstItemOnShow)
-      this.selectTab(effectiveTab.id);
-  }
-
-  makeTabSlider() {
-    if (this._verticalTabLayout)
-      return;
-    this._setTabSlider(true);
-  }
-
-  /**
-   * @param {boolean} enable
-   */
-  _setTabSlider(enable) {
-    this._sliderEnabled = enable;
-    this._tabSlider.classList.toggle('enabled', enable);
-  }
-
-  /**
-   * @override
-   * @return {!UI.Constraints}
-   */
-  calculateConstraints() {
-    let constraints = super.calculateConstraints();
-    const minContentConstraints = new UI.Constraints(new UI.Size(0, 0), new UI.Size(50, 50));
-    constraints = constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints);
-    if (this._verticalTabLayout)
-      constraints = constraints.addWidth(new UI.Constraints(new UI.Size(120, 0)));
-    else
-      constraints = constraints.addHeight(new UI.Constraints(new UI.Size(0, 30)));
-    return constraints;
-  }
-
-  _updateTabElements() {
-    UI.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  setPlaceholderElement(element) {
-    this._placeholderElement = element;
-
-    if (this._placeholderContainerElement) {
-      this._placeholderContainerElement.removeChildren();
-      this._placeholderContainerElement.appendChild(element);
-    }
-  }
-
-  _innerUpdateTabElements() {
-    if (!this.isShowing())
-      return;
-
-    if (!this._tabs.length) {
-      this._contentElement.classList.add('has-no-tabs');
-      if (this._placeholderElement && !this._placeholderContainerElement) {
-        this._placeholderContainerElement = this._contentElement.createChild('div', 'tabbed-pane-placeholder fill');
-        this._placeholderContainerElement.appendChild(this._placeholderElement);
-      }
-    } else {
-      this._contentElement.classList.remove('has-no-tabs');
-      if (this._placeholderContainerElement) {
-        this._placeholderContainerElement.remove();
-        delete this._placeholderContainerElement;
-      }
-    }
-
-    this._measureDropDownButton();
-    this._updateWidths();
-    this._updateTabsDropDown();
-    this._updateTabSlider();
-  }
-
-  /**
-   * @param {number} index
-   * @param {!UI.TabbedPaneTab} tab
-   */
-  _showTabElement(index, tab) {
-    if (index >= this._tabsElement.children.length)
-      this._tabsElement.appendChild(tab.tabElement);
-    else
-      this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]);
-    tab._shown = true;
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTab} tab
-   */
-  _hideTabElement(tab) {
-    this._tabsElement.removeChild(tab.tabElement);
-    tab._shown = false;
-  }
-
-  _createDropDownButton() {
-    const dropDownContainer = createElementWithClass('div', 'tabbed-pane-header-tabs-drop-down-container');
-    const chevronIcon = UI.Icon.create('largeicon-chevron', 'chevron-icon');
-    dropDownContainer.appendChild(chevronIcon);
-    dropDownContainer.addEventListener('click', this._onDropDownMouseDown.bind(this));
-    dropDownContainer.addEventListener('mousedown', this._onDropDownMouseDown.bind(this));
-    return dropDownContainer;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onDropDownMouseDown(event) {
-    if (event.which !== 1)
-      return;
-    const rect = this._dropDownButton.getBoundingClientRect();
-    const menu = new UI.ContextMenu(event, false, rect.left, rect.bottom);
-    for (let i = 0; i < this._tabs.length; ++i) {
-      const tab = this._tabs[i];
-      if (tab._shown)
-        continue;
-      menu.defaultSection().appendCheckboxItem(
-          tab.title, this._dropDownMenuItemSelected.bind(this, tab), this._tabsHistory[0] === tab);
-    }
-    menu.show();
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTab} tab
-   */
-  _dropDownMenuItemSelected(tab) {
-    this._lastSelectedOverflowTab = tab;
-    this.selectTab(tab.id, true);
-  }
-
-  _totalWidth() {
-    return this._headerContentsElement.getBoundingClientRect().width;
-  }
-
-  /**
-   * @return {number}
-   */
-  _numberOfTabsShown() {
-    let numTabsShown = 0;
-    for (const tab of this._tabs) {
-      if (tab._shown)
-        numTabsShown++;
-    }
-    return numTabsShown;
-  }
-
-  disableOverflowMenu() {
-    this._overflowDisabled = true;
-  }
-
-  _updateTabsDropDown() {
-    const tabsToShowIndexes = this._tabsToShowIndexes(
-        this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth || 0);
-    if (this._lastSelectedOverflowTab && this._numberOfTabsShown() !== tabsToShowIndexes.length) {
-      delete this._lastSelectedOverflowTab;
-      this._updateTabsDropDown();
-      return;
-    }
-
-    for (let i = 0; i < this._tabs.length; ++i) {
-      if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1)
-        this._hideTabElement(this._tabs[i]);
-    }
-    for (let i = 0; i < tabsToShowIndexes.length; ++i) {
-      const tab = this._tabs[tabsToShowIndexes[i]];
-      if (!tab._shown)
-        this._showTabElement(i, tab);
-    }
-
-    if (!this._overflowDisabled)
-      this._maybeShowDropDown(tabsToShowIndexes.length !== this._tabs.length);
-  }
-
-  /**
-   * @param {boolean} hasMoreTabs
-   */
-  _maybeShowDropDown(hasMoreTabs) {
-    if (hasMoreTabs && !this._dropDownButton.parentElement)
-      this._headerContentsElement.appendChild(this._dropDownButton);
-    else if (!hasMoreTabs && this._dropDownButton.parentElement)
-      this._headerContentsElement.removeChild(this._dropDownButton);
-  }
-
-  _measureDropDownButton() {
-    if (this._overflowDisabled || this._measuredDropDownButtonWidth)
-      return;
-    this._dropDownButton.classList.add('measuring');
-    this._headerContentsElement.appendChild(this._dropDownButton);
-    this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width;
-    this._headerContentsElement.removeChild(this._dropDownButton);
-    this._dropDownButton.classList.remove('measuring');
-  }
-
-  _updateWidths() {
-    const measuredWidths = this._measureWidths();
-    const maxWidth =
-        this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;
-
-    let i = 0;
-    for (const tab of this._tabs)
-      tab.setWidth(this._verticalTabLayout ? -1 : Math.min(maxWidth, measuredWidths[i++]));
-  }
-
-  _measureWidths() {
-    // Add all elements to measure into this._tabsElement
-    this._tabsElement.style.setProperty('width', '2000px');
-    const measuringTabElements = [];
-    for (const tab of this._tabs) {
-      if (typeof tab._measuredWidth === 'number')
-        continue;
-      const measuringTabElement = tab._createTabElement(true);
-      measuringTabElement.__tab = tab;
-      measuringTabElements.push(measuringTabElement);
-      this._tabsElement.appendChild(measuringTabElement);
-    }
-
-    // Perform measurement
-    for (let i = 0; i < measuringTabElements.length; ++i) {
-      const width = measuringTabElements[i].getBoundingClientRect().width;
-      measuringTabElements[i].__tab._measuredWidth = Math.ceil(width);
-    }
-
-    // Nuke elements from the UI
-    for (let i = 0; i < measuringTabElements.length; ++i)
-      measuringTabElements[i].remove();
-
-    // Combine the results.
-    const measuredWidths = [];
-    for (const tab of this._tabs)
-      measuredWidths.push(tab._measuredWidth);
-    this._tabsElement.style.removeProperty('width');
-
-    return measuredWidths;
-  }
-
-  /**
-   * @param {!Array.<number>} measuredWidths
-   * @param {number} totalWidth
-   */
-  _calculateMaxWidth(measuredWidths, totalWidth) {
-    if (!measuredWidths.length)
-      return 0;
-
-    measuredWidths.sort(function(x, y) {
-      return x - y;
-    });
-
-    let totalMeasuredWidth = 0;
-    for (let i = 0; i < measuredWidths.length; ++i)
-      totalMeasuredWidth += measuredWidths[i];
-
-    if (totalWidth >= totalMeasuredWidth)
-      return measuredWidths[measuredWidths.length - 1];
-
-    let totalExtraWidth = 0;
-    for (let i = measuredWidths.length - 1; i > 0; --i) {
-      const extraWidth = measuredWidths[i] - measuredWidths[i - 1];
-      totalExtraWidth += (measuredWidths.length - i) * extraWidth;
-
-      if (totalWidth + totalExtraWidth >= totalMeasuredWidth) {
-        return measuredWidths[i - 1] +
-            (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i);
-      }
-    }
-
-    return totalWidth / measuredWidths.length;
-  }
-
-  /**
-   * @param {!Array.<!UI.TabbedPaneTab>} tabsOrdered
-   * @param {!Array.<!UI.TabbedPaneTab>} tabsHistory
-   * @param {number} totalWidth
-   * @param {number} measuredDropDownButtonWidth
-   * @return {!Array.<number>}
-   */
-  _tabsToShowIndexes(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth) {
-    const tabsToShowIndexes = [];
-
-    let totalTabsWidth = 0;
-    const tabCount = tabsOrdered.length;
-    const tabsToLookAt = tabsOrdered.slice(0);
-    if (this._currentTab !== undefined)
-      tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._currentTab), 1)[0]);
-    if (this._lastSelectedOverflowTab !== undefined)
-      tabsToLookAt.unshift(tabsToLookAt.splice(tabsToLookAt.indexOf(this._lastSelectedOverflowTab), 1)[0]);
-    for (let i = 0; i < tabCount; ++i) {
-      const tab = this._automaticReorder ? tabsHistory[i] : tabsToLookAt[i];
-      totalTabsWidth += tab.width();
-      let minimalRequiredWidth = totalTabsWidth;
-      if (i !== tabCount - 1)
-        minimalRequiredWidth += measuredDropDownButtonWidth;
-      if (!this._verticalTabLayout && minimalRequiredWidth > totalWidth)
-        break;
-      tabsToShowIndexes.push(tabsOrdered.indexOf(tab));
-    }
-
-    tabsToShowIndexes.sort(function(x, y) {
-      return x - y;
-    });
-
-    return tabsToShowIndexes;
-  }
-
-  _hideCurrentTab() {
-    if (!this._currentTab)
-      return;
-
-    this._hideTab(this._currentTab);
-    delete this._currentTab;
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTab} tab
-   */
-  _showTab(tab) {
-    tab.tabElement.tabIndex = 0;
-    tab.tabElement.classList.add('selected');
-    UI.ARIAUtils.setSelected(tab.tabElement, true);
-    tab.view.show(this.element);
-    this._updateTabSlider();
-  }
-
-  _updateTabSlider() {
-    if (!this._sliderEnabled)
-      return;
-    if (!this._currentTab) {
-      this._tabSlider.style.width = 0;
-      return;
-    }
-    let left = 0;
-    for (let i = 0; i < this._tabs.length && this._currentTab !== this._tabs[i]; i++) {
-      if (this._tabs[i]._shown)
-        left += this._tabs[i]._measuredWidth;
-    }
-    const sliderWidth = this._currentTab._shown ? this._currentTab._measuredWidth : this._dropDownButton.offsetWidth;
-    const scaleFactor = window.devicePixelRatio >= 1.5 ? ' scaleY(0.75)' : '';
-    this._tabSlider.style.transform = 'translateX(' + left + 'px)' + scaleFactor;
-    this._tabSlider.style.width = sliderWidth + 'px';
-
-    if (this._tabSlider.parentElement !== this._headerContentsElement)
-      this._headerContentsElement.appendChild(this._tabSlider);
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTab} tab
-   */
-  _hideTab(tab) {
-    tab.tabElement.removeAttribute('tabIndex');
-    tab.tabElement.classList.remove('selected');
-    tab.tabElement.setAttribute('aria-selected', 'false');
-    tab.view.detach();
-  }
-
-  /**
-   * @override
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [this._contentElement];
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTab} tab
-   * @param {number} index
-   */
-  _insertBefore(tab, index) {
-    this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.childNodes[index]);
-    const oldIndex = this._tabs.indexOf(tab);
-    this._tabs.splice(oldIndex, 1);
-    if (oldIndex < index)
-      --index;
-    this._tabs.splice(index, 0, tab);
-    this.dispatchEventToListeners(UI.TabbedPane.Events.TabOrderChanged, this._tabs);
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  leftToolbar() {
-    if (!this._leftToolbar) {
-      this._leftToolbar = new UI.Toolbar('tabbed-pane-left-toolbar');
-      this._headerElement.insertBefore(this._leftToolbar.element, this._headerElement.firstChild);
-    }
-    return this._leftToolbar;
-  }
-
-  /**
-   * @return {!UI.Toolbar}
-   */
-  rightToolbar() {
-    if (!this._rightToolbar) {
-      this._rightToolbar = new UI.Toolbar('tabbed-pane-right-toolbar');
-      this._headerElement.appendChild(this._rightToolbar.element);
-    }
-    return this._rightToolbar;
-  }
-
-  /**
-   * @param {boolean} allow
-   * @param {boolean=} automatic
-   */
-  setAllowTabReorder(allow, automatic) {
-    this._allowTabReorder = allow;
-    this._automaticReorder = automatic;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _keyDown(event) {
-    if (!this._currentTab)
-      return;
-    let nextTabElement = null;
-    switch (event.key) {
-      case 'ArrowUp':
-      case 'ArrowLeft':
-        nextTabElement = this._currentTab.tabElement.previousElementSibling;
-        if (!nextTabElement && !this._dropDownButton.parentElement)
-          nextTabElement = this._currentTab.tabElement.parentElement.lastElementChild;
-        break;
-      case 'ArrowDown':
-      case 'ArrowRight':
-        nextTabElement = this._currentTab.tabElement.nextElementSibling;
-        if (!nextTabElement && !this._dropDownButton.parentElement)
-          nextTabElement = this._currentTab.tabElement.parentElement.firstElementChild;
-        break;
-      case 'Enter':
-      case 'Space':
-        this._currentTab.view.focus();
-        return;
-      default:
-        return;
-    }
-    if (!nextTabElement) {
-      this._dropDownButton.click();
-      return;
-    }
-    const tab = this._tabs.find(tab => tab.tabElement === nextTabElement);
-    this.selectTab(tab.id, true);
-    nextTabElement.focus();
-  }
-};
-
-/** @enum {symbol} */
-UI.TabbedPane.Events = {
-  TabSelected: Symbol('TabSelected'),
-  TabClosed: Symbol('TabClosed'),
-  TabOrderChanged: Symbol('TabOrderChanged')
-};
-
-/**
- * @unrestricted
- */
-UI.TabbedPaneTab = class {
-  /**
-   * @param {!UI.TabbedPane} tabbedPane
-   * @param {string} id
-   * @param {string} title
-   * @param {boolean} closeable
-   * @param {!UI.Widget} view
-   * @param {string=} tooltip
-   */
-  constructor(tabbedPane, id, title, closeable, view, tooltip) {
-    this._closeable = closeable;
-    this._tabbedPane = tabbedPane;
-    this._id = id;
-    this._title = title;
-    this._tooltip = tooltip;
-    this._view = view;
-    this._shown = false;
-    /** @type {number} */
-    this._measuredWidth;
-    /** @type {!Element|undefined} */
-    this._tabElement;
-    /** @type {?Element} */
-    this._iconContainer = null;
-  }
-
-  /**
-   * @return {string}
-   */
-  get id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  get title() {
-    return this._title;
-  }
-
-  /**
-   * @param {string} title
-   */
-  set title(title) {
-    if (title === this._title)
-      return;
-    this._title = title;
-    if (this._titleElement)
-      this._titleElement.textContent = title;
-    delete this._measuredWidth;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isCloseable() {
-    return this._closeable;
-  }
-
-  /**
-   * @param {?UI.Icon} icon
-   */
-  _setIcon(icon) {
-    this._icon = icon;
-    if (this._tabElement)
-      this._createIconElement(this._tabElement, this._titleElement, false);
-    delete this._measuredWidth;
-  }
-
-  /**
-   * @param {string} className
-   * @param {boolean=} force
-   * @return {boolean}
-   */
-  _toggleClass(className, force) {
-    const element = this.tabElement;
-    const hasClass = element.classList.contains(className);
-    if (hasClass === force)
-      return false;
-    element.classList.toggle(className, force);
-    delete this._measuredWidth;
-    return true;
-  }
-
-  /**
-   * @return {!UI.Widget}
-   */
-  get view() {
-    return this._view;
-  }
-
-  /**
-   * @param {!UI.Widget} view
-   */
-  set view(view) {
-    this._view = view;
-  }
-
-  /**
-   * @return {string|undefined}
-   */
-  get tooltip() {
-    return this._tooltip;
-  }
-
-  /**
-   * @param {string|undefined} tooltip
-   */
-  set tooltip(tooltip) {
-    this._tooltip = tooltip;
-    if (this._titleElement)
-      this._titleElement.title = tooltip || '';
-  }
-
-  /**
-   * @return {!Element}
-   */
-  get tabElement() {
-    if (!this._tabElement)
-      this._tabElement = this._createTabElement(false);
-
-    return this._tabElement;
-  }
-
-  /**
-   * @return {number}
-   */
-  width() {
-    return this._width;
-  }
-
-  /**
-   * @param {number} width
-   */
-  setWidth(width) {
-    this.tabElement.style.width = width === -1 ? '' : (width + 'px');
-    this._width = width;
-  }
-
-  /**
-   * @param {!UI.TabbedPaneTabDelegate} delegate
-   */
-  setDelegate(delegate) {
-    this._delegate = delegate;
-  }
-
-  /**
-   * @param {!Element} tabElement
-   * @param {!Element} titleElement
-   * @param {boolean} measuring
-   */
-  _createIconElement(tabElement, titleElement, measuring) {
-    if (tabElement.__iconElement) {
-      tabElement.__iconElement.remove();
-      tabElement.__iconElement = null;
-    }
-    if (!this._icon)
-      return;
-
-    const iconContainer = createElementWithClass('span', 'tabbed-pane-header-tab-icon');
-    const iconNode = measuring ? this._icon.cloneNode(true) : this._icon;
-    iconContainer.appendChild(iconNode);
-    tabElement.insertBefore(iconContainer, titleElement);
-    tabElement.__iconElement = iconContainer;
-  }
-
-  /**
-   * @param {boolean} measuring
-   * @return {!Element}
-   */
-  _createTabElement(measuring) {
-    const tabElement = createElementWithClass('div', 'tabbed-pane-header-tab');
-    tabElement.id = 'tab-' + this._id;
-    UI.ARIAUtils.markAsTab(tabElement);
-    UI.ARIAUtils.setSelected(tabElement, false);
-
-    const titleElement = tabElement.createChild('span', 'tabbed-pane-header-tab-title');
-    titleElement.textContent = this.title;
-    titleElement.title = this.tooltip || '';
-    this._createIconElement(tabElement, titleElement, measuring);
-    if (!measuring)
-      this._titleElement = titleElement;
-
-    if (this._closeable) {
-      tabElement.createChild('div', 'tabbed-pane-close-button', 'dt-close-button').gray = true;
-      tabElement.classList.add('closeable');
-    }
-
-    if (measuring) {
-      tabElement.classList.add('measuring');
-    } else {
-      tabElement.addEventListener('click', this._tabClicked.bind(this), false);
-      tabElement.addEventListener('auxclick', this._tabClicked.bind(this), false);
-      tabElement.addEventListener('mousedown', this._tabMouseDown.bind(this), false);
-      tabElement.addEventListener('mouseup', this._tabMouseUp.bind(this), false);
-
-      tabElement.addEventListener('contextmenu', this._tabContextMenu.bind(this), false);
-      if (this._tabbedPane._allowTabReorder) {
-        UI.installDragHandle(
-            tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this),
-            this._endTabDragging.bind(this), '-webkit-grabbing', 'pointer', 200);
-      }
-    }
-
-    return tabElement;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _tabClicked(event) {
-    const middleButton = event.button === 1;
-    const shouldClose =
-        this._closeable && (middleButton || event.target.classList.contains('tabbed-pane-close-button'));
-    if (!shouldClose) {
-      this._tabbedPane.focus();
-      return;
-    }
-    this._closeTabs([this.id]);
-    event.consume(true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _tabMouseDown(event) {
-    if (event.target.classList.contains('tabbed-pane-close-button') || event.button === 1)
-      return;
-    this._tabbedPane.selectTab(this.id, true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _tabMouseUp(event) {
-    // This is needed to prevent middle-click pasting on linux when tabs are clicked.
-    if (event.button === 1)
-      event.consume(true);
-  }
-
-  /**
-   * @param {!Array.<string>} ids
-   */
-  _closeTabs(ids) {
-    if (this._delegate) {
-      this._delegate.closeTabs(this._tabbedPane, ids);
-      return;
-    }
-    this._tabbedPane.closeTabs(ids, true);
-  }
-
-  _tabContextMenu(event) {
-    /**
-     * @this {UI.TabbedPaneTab}
-     */
-    function close() {
-      this._closeTabs([this.id]);
-    }
-
-    /**
-     * @this {UI.TabbedPaneTab}
-     */
-    function closeOthers() {
-      this._closeTabs(this._tabbedPane.otherTabs(this.id));
-    }
-
-    /**
-     * @this {UI.TabbedPaneTab}
-     */
-    function closeAll() {
-      this._closeTabs(this._tabbedPane.allTabs());
-    }
-
-    /**
-     * @this {UI.TabbedPaneTab}
-     */
-    function closeToTheRight() {
-      this._closeTabs(this._tabbedPane._tabsToTheRight(this.id));
-    }
-
-    const contextMenu = new UI.ContextMenu(event);
-    if (this._closeable) {
-      contextMenu.defaultSection().appendItem(Common.UIString('Close'), close.bind(this));
-      contextMenu.defaultSection().appendItem(Common.UIString('Close others'), closeOthers.bind(this));
-      contextMenu.defaultSection().appendItem(Common.UIString('Close tabs to the right'), closeToTheRight.bind(this));
-      contextMenu.defaultSection().appendItem(Common.UIString('Close all'), closeAll.bind(this));
-    }
-    if (this._delegate)
-      this._delegate.onContextMenu(this.id, contextMenu);
-    contextMenu.show();
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  _startTabDragging(event) {
-    if (event.target.classList.contains('tabbed-pane-close-button'))
-      return false;
-    this._dragStartX = event.pageX;
-    this._tabElement.classList.add('dragging');
-    this._tabbedPane._tabSlider.remove();
-    return true;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _tabDragging(event) {
-    const tabElements = this._tabbedPane._tabsElement.childNodes;
-    for (let i = 0; i < tabElements.length; ++i) {
-      let tabElement = tabElements[i];
-      if (tabElement === this._tabElement)
-        continue;
-
-      const intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft &&
-          this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft;
-      if (!intersects)
-        continue;
-
-      if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5)
-        break;
-
-      if (event.pageX - this._dragStartX > 0) {
-        tabElement = tabElement.nextSibling;
-        ++i;
-      }
-
-      const oldOffsetLeft = this._tabElement.offsetLeft;
-      this._tabbedPane._insertBefore(this, i);
-      this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft;
-      break;
-    }
-
-    if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) {
-      this._tabElement.style.setProperty('left', '0px');
-      return;
-    }
-    if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) {
-      this._tabElement.style.setProperty('left', '0px');
-      return;
-    }
-
-    this._tabElement.style.setProperty('left', (event.pageX - this._dragStartX) + 'px');
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _endTabDragging(event) {
-    this._tabElement.classList.remove('dragging');
-    this._tabElement.style.removeProperty('left');
-    delete this._dragStartX;
-    this._tabbedPane._updateTabSlider();
-  }
-};
-
-/**
- * @interface
- */
-UI.TabbedPaneTabDelegate = function() {};
-
-UI.TabbedPaneTabDelegate.prototype = {
-  /**
-   * @param {!UI.TabbedPane} tabbedPane
-   * @param {!Array.<string>} ids
-   */
-  closeTabs(tabbedPane, ids) {},
-
-  /**
-   * @param {string} tabId
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  onContextMenu(tabId, contextMenu) {}
-};
diff --git a/front_end/ui/TargetCrashedScreen.js b/front_end/ui/TargetCrashedScreen.js
deleted file mode 100644
index 5d0f2a1..0000000
--- a/front_end/ui/TargetCrashedScreen.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-UI.TargetCrashedScreen = class extends UI.VBox {
-  /**
-   * @param {function()} hideCallback
-   */
-  constructor(hideCallback) {
-    super(true);
-    this.registerRequiredCSS('ui/targetCrashedScreen.css');
-    this.contentElement.createChild('div', 'message').textContent =
-        Common.UIString('DevTools was disconnected from the page.');
-    this.contentElement.createChild('div', 'message').textContent =
-        Common.UIString('Once page is reloaded, DevTools will automatically reconnect.');
-    this._hideCallback = hideCallback;
-  }
-
-  /**
-   * @override
-   */
-  willHide() {
-    this._hideCallback.call(null);
-  }
-};
diff --git a/front_end/ui/TextEditor.js b/front_end/ui/TextEditor.js
deleted file mode 100644
index 62f7542..0000000
--- a/front_end/ui/TextEditor.js
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @interface
- */
-UI.TextEditorFactory = function() {};
-
-UI.TextEditorFactory.prototype = {
-  /**
-   * @param {!UI.TextEditor.Options} options
-   * @return {!UI.TextEditor}
-   */
-  createEditor(options) {}
-};
-
-/**
- * @interface
- * @extends {Common.EventTarget}
- */
-UI.TextEditor = function() {};
-
-UI.TextEditor.prototype = {
-
-  /**
-   * @return {!UI.Widget}
-   */
-  widget() {},
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  fullRange() {},
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  selection() {},
-
-  /**
-   * @param {!TextUtils.TextRange} selection
-   */
-  setSelection(selection) {},
-
-  /**
-   * @param {!TextUtils.TextRange=} textRange
-   * @return {string}
-   */
-  text(textRange) {},
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {},
-
-  /**
-   * @param {number} lineNumber
-   * @return {string}
-   */
-  line(lineNumber) {},
-
-  newlineAndIndent() {},
-
-  /**
-   * @param {function(!KeyboardEvent)} handler
-   */
-  addKeyDownHandler(handler) {},
-
-  /**
-   * @param {?UI.AutocompleteConfig} config
-   */
-  configureAutocomplete(config) {},
-
-  clearAutocomplete() {},
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {!{x: number, y: number}}
-   */
-  visualCoordinates(lineNumber, columnNumber) {},
-
-  /**
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   * @return {?{startColumn: number, endColumn: number, type: string}}
-   */
-  tokenAtTextPosition(lineNumber, columnNumber) {}
-};
-
-/** @enum {symbol} */
-UI.TextEditor.Events = {
-  TextChanged: Symbol('TextChanged')
-};
-
-/**
- * @typedef {{
- *  bracketMatchingSetting: (!Common.Setting|undefined),
- *  lineNumbers: boolean,
- *  lineWrapping: boolean,
- *  mimeType: (string|undefined),
- *  autoHeight: (boolean|undefined),
- *  padBottom: (boolean|undefined),
- *  maxHighlightLength: (number|undefined),
- *  placeholder: (string|undefined)
- * }}
- */
-UI.TextEditor.Options;
-
-/**
- * @typedef {{
- *     substituteRangeCallback: ((function(number, number):?TextUtils.TextRange)|undefined),
- *     suggestionsCallback: ((function(!TextUtils.TextRange, !TextUtils.TextRange, boolean=):?Promise.<!UI.SuggestBox.Suggestions>)|undefined),
- *     isWordChar: ((function(string):boolean)|undefined),
- *     captureEnter: (boolean|undefined)
- * }}
- */
-UI.AutocompleteConfig;
diff --git a/front_end/ui/TextPrompt.js b/front_end/ui/TextPrompt.js
deleted file mode 100644
index 5d4430d..0000000
--- a/front_end/ui/TextPrompt.js
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2011 Google Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {UI.SuggestBoxDelegate}
- * @unrestricted
- */
-UI.TextPrompt = class extends Common.Object {
-  constructor() {
-    super();
-    /**
-     * @type {!Element|undefined}
-     */
-    this._proxyElement;
-    this._proxyElementDisplay = 'inline-block';
-    this._autocompletionTimeout = UI.TextPrompt.DefaultAutocompletionTimeout;
-    this._title = '';
-    this._queryRange = null;
-    this._previousText = '';
-    this._currentSuggestion = '';
-    this._completionRequestId = 0;
-    this._ghostTextElement = createElementWithClass('span', 'auto-complete-text');
-    this._ghostTextElement.setAttribute('contenteditable', 'false');
-    UI.ARIAUtils.markAsHidden(this._ghostTextElement);
-  }
-
-  /**
-   * @param {(function(this:null, string, string, boolean=):!Promise<!UI.SuggestBox.Suggestions>)} completions
-   * @param {string=} stopCharacters
-   */
-  initialize(completions, stopCharacters) {
-    this._loadCompletions = completions;
-    this._completionStopCharacters = stopCharacters || ' =:[({;,!+-*/&|^<>.';
-  }
-
-  /**
-   * @param {number} timeout
-   */
-  setAutocompletionTimeout(timeout) {
-    this._autocompletionTimeout = timeout;
-  }
-
-  renderAsBlock() {
-    this._proxyElementDisplay = 'block';
-  }
-
-  /**
-   * Clients should never attach any event listeners to the |element|. Instead,
-   * they should use the result of this method to attach listeners for bubbling events.
-   *
-   * @param {!Element} element
-   * @return {!Element}
-   */
-  attach(element) {
-    return this._attachInternal(element);
-  }
-
-  /**
-   * Clients should never attach any event listeners to the |element|. Instead,
-   * they should use the result of this method to attach listeners for bubbling events
-   * or the |blurListener| parameter to register a "blur" event listener on the |element|
-   * (since the "blur" event does not bubble.)
-   *
-   * @param {!Element} element
-   * @param {function(!Event)} blurListener
-   * @return {!Element}
-   */
-  attachAndStartEditing(element, blurListener) {
-    const proxyElement = this._attachInternal(element);
-    this._startEditing(blurListener);
-    return proxyElement;
-  }
-
-  /**
-   * @param {!Element} element
-   * @return {!Element}
-   */
-  _attachInternal(element) {
-    if (this._proxyElement)
-      throw 'Cannot attach an attached TextPrompt';
-    this._element = element;
-
-    this._boundOnKeyDown = this.onKeyDown.bind(this);
-    this._boundOnInput = this.onInput.bind(this);
-    this._boundOnMouseWheel = this.onMouseWheel.bind(this);
-    this._boundClearAutocomplete = this.clearAutocomplete.bind(this);
-    this._proxyElement = element.ownerDocument.createElement('span');
-    const shadowRoot = UI.createShadowRootWithCoreStyles(this._proxyElement, 'ui/textPrompt.css');
-    this._contentElement = shadowRoot.createChild('div', 'text-prompt-root');
-    this._contentElement.createChild('content');
-    this._proxyElement.style.display = this._proxyElementDisplay;
-    element.parentElement.insertBefore(this._proxyElement, element);
-    this._proxyElement.appendChild(element);
-    this._element.classList.add('text-prompt');
-    UI.ARIAUtils.markAsTextBox(this._element);
-    this._element.setAttribute('contenteditable', 'plaintext-only');
-    this._element.addEventListener('keydown', this._boundOnKeyDown, false);
-    this._element.addEventListener('input', this._boundOnInput, false);
-    this._element.addEventListener('mousewheel', this._boundOnMouseWheel, false);
-    this._element.addEventListener('selectstart', this._boundClearAutocomplete, false);
-    this._element.addEventListener('blur', this._boundClearAutocomplete, false);
-
-    this._suggestBox = new UI.SuggestBox(this, 20, true);
-
-    if (this._title)
-      this._proxyElement.title = this._title;
-
-    return this._proxyElement;
-  }
-
-  detach() {
-    this._removeFromElement();
-    this._focusRestorer.restore();
-    this._proxyElement.parentElement.insertBefore(this._element, this._proxyElement);
-    this._proxyElement.remove();
-    delete this._proxyElement;
-    this._element.classList.remove('text-prompt');
-    this._element.removeAttribute('contenteditable');
-    this._element.removeAttribute('role');
-  }
-
-  /**
-   * @return {string}
-   */
-  textWithCurrentSuggestion() {
-    const text = this.text();
-    if (!this._queryRange)
-      return text;
-    return text.substring(0, this._queryRange.startColumn) + this._currentSuggestion +
-        text.substring(this._queryRange.endColumn);
-  }
-
-  /**
-   * @return {string}
-   */
-  text() {
-    let text = this._element.textContent;
-    if (this._ghostTextElement.parentNode) {
-      const addition = this._ghostTextElement.textContent;
-      text = text.substring(0, text.length - addition.length);
-    }
-    return text;
-  }
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {
-    this.clearAutocomplete();
-    this._element.textContent = text;
-    this._previousText = this.text();
-    if (this._element.hasFocus()) {
-      this.moveCaretToEndOfPrompt();
-      this._element.scrollIntoView();
-    }
-  }
-
-  focus() {
-    this._element.focus();
-  }
-
-  /**
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    this._title = title;
-    if (this._proxyElement)
-      this._proxyElement.title = title;
-  }
-
-  /**
-   * @param {string} placeholder
-   */
-  setPlaceholder(placeholder) {
-    if (placeholder) {
-      this._element.setAttribute('data-placeholder', placeholder);
-      UI.ARIAUtils.setPlaceholder(this._element, placeholder);
-    } else {
-      this._element.removeAttribute('data-placeholder');
-      UI.ARIAUtils.setPlaceholder(this._element, null);
-    }
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    if (enabled)
-      this._element.setAttribute('contenteditable', 'plaintext-only');
-    else
-      this._element.removeAttribute('contenteditable');
-    this._element.classList.toggle('disabled', !enabled);
-  }
-
-  _removeFromElement() {
-    this.clearAutocomplete();
-    this._element.removeEventListener('keydown', this._boundOnKeyDown, false);
-    this._element.removeEventListener('input', this._boundOnInput, false);
-    this._element.removeEventListener('selectstart', this._boundClearAutocomplete, false);
-    this._element.removeEventListener('blur', this._boundClearAutocomplete, false);
-    if (this._isEditing)
-      this._stopEditing();
-    if (this._suggestBox)
-      this._suggestBox.hide();
-  }
-
-  /**
-   * @param {function(!Event)=} blurListener
-   */
-  _startEditing(blurListener) {
-    this._isEditing = true;
-    this._contentElement.classList.add('text-prompt-editing');
-    if (blurListener) {
-      this._blurListener = blurListener;
-      this._element.addEventListener('blur', this._blurListener, false);
-    }
-    this._oldTabIndex = this._element.tabIndex;
-    if (this._element.tabIndex < 0)
-      this._element.tabIndex = 0;
-    this._focusRestorer = new UI.ElementFocusRestorer(this._element);
-    if (!this.text())
-      this.autoCompleteSoon();
-  }
-
-  _stopEditing() {
-    this._element.tabIndex = this._oldTabIndex;
-    if (this._blurListener)
-      this._element.removeEventListener('blur', this._blurListener, false);
-    this._contentElement.classList.remove('text-prompt-editing');
-    delete this._isEditing;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  onMouseWheel(event) {
-    // Subclasses can implement.
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  onKeyDown(event) {
-    let handled = false;
-    if (this._isSuggestBoxVisible() && this._suggestBox.keyPressed(event)) {
-      event.consume(true);
-      return;
-    }
-
-    switch (event.key) {
-      case 'Tab':
-        handled = this.tabKeyPressed(event);
-        break;
-      case 'ArrowLeft':
-      case 'ArrowUp':
-      case 'PageUp':
-      case 'Home':
-        this.clearAutocomplete();
-        break;
-      case 'PageDown':
-      case 'ArrowRight':
-      case 'ArrowDown':
-      case 'End':
-        if (this._isCaretAtEndOfPrompt())
-          handled = this.acceptAutoComplete();
-        else
-          this.clearAutocomplete();
-        break;
-      case 'Escape':
-        if (this._isSuggestBoxVisible()) {
-          this.clearAutocomplete();
-          handled = true;
-        }
-        break;
-      case ' ':  // Space
-        if (event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
-          this.autoCompleteSoon(true);
-          handled = true;
-        }
-        break;
-    }
-    if (isEnterKey(event))
-      event.preventDefault();
-
-    if (handled)
-      event.consume(true);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  onInput(event) {
-    const text = this.text();
-    const hasCommonPrefix = text.startsWith(this._previousText) || this._previousText.startsWith(text);
-    if (this._queryRange && hasCommonPrefix)
-      this._queryRange.endColumn += text.length - this._previousText.length;
-    this._refreshGhostText();
-    this._previousText = text;
-    this.dispatchEventToListeners(UI.TextPrompt.Events.TextChanged);
-
-    this.autoCompleteSoon();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  acceptAutoComplete() {
-    let result = false;
-    if (this._isSuggestBoxVisible())
-      result = this._suggestBox.acceptSuggestion();
-    if (!result)
-      result = this._acceptSuggestionInternal();
-
-    return result;
-  }
-
-  clearAutocomplete() {
-    const beforeText = this.textWithCurrentSuggestion();
-
-    if (this._isSuggestBoxVisible())
-      this._suggestBox.hide();
-    this._clearAutocompleteTimeout();
-    this._queryRange = null;
-    this._refreshGhostText();
-
-    if (beforeText !== this.textWithCurrentSuggestion())
-      this.dispatchEventToListeners(UI.TextPrompt.Events.TextChanged);
-  }
-
-  _refreshGhostText() {
-    if (this._queryRange && this._currentSuggestion && this._isCaretAtEndOfPrompt() &&
-        this._currentSuggestion.startsWith(this.text().substring(this._queryRange.startColumn))) {
-      this._ghostTextElement.textContent =
-          this._currentSuggestion.substring(this._queryRange.endColumn - this._queryRange.startColumn);
-      this._element.appendChild(this._ghostTextElement);
-    } else {
-      this._ghostTextElement.remove();
-    }
-  }
-
-  _clearAutocompleteTimeout() {
-    if (this._completeTimeout) {
-      clearTimeout(this._completeTimeout);
-      delete this._completeTimeout;
-    }
-    this._completionRequestId++;
-  }
-
-  /**
-   * @param {boolean=} force
-   */
-  autoCompleteSoon(force) {
-    const immediately = this._isSuggestBoxVisible() || force;
-    if (!this._completeTimeout) {
-      this._completeTimeout =
-          setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout);
-    }
-  }
-
-  /**
-   * @param {boolean=} force
-   */
-  async complete(force) {
-    this._clearAutocompleteTimeout();
-    const selection = this._element.getComponentSelection();
-    const selectionRange = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
-    if (!selectionRange)
-      return;
-
-    let shouldExit;
-
-    if (!force && !this._isCaretAtEndOfPrompt() && !this._isSuggestBoxVisible())
-      shouldExit = true;
-    else if (!selection.isCollapsed)
-      shouldExit = true;
-
-    if (shouldExit) {
-      this.clearAutocomplete();
-      return;
-    }
-
-    const wordQueryRange = selectionRange.startContainer.rangeOfWord(
-        selectionRange.startOffset, this._completionStopCharacters, this._element, 'backward');
-
-    const expressionRange = wordQueryRange.cloneRange();
-    expressionRange.collapse(true);
-    expressionRange.setStartBefore(this._proxyElement);
-    const completionRequestId = ++this._completionRequestId;
-    const completions = await this._loadCompletions(expressionRange.toString(), wordQueryRange.toString(), !!force);
-    this._completionsReady(completionRequestId, selection, wordQueryRange, !!force, completions);
-  }
-
-  disableDefaultSuggestionForEmptyInput() {
-    this._disableDefaultSuggestionForEmptyInput = true;
-  }
-
-  /**
-   * @param {!Selection} selection
-   * @param {!Range} textRange
-   */
-  _boxForAnchorAtStart(selection, textRange) {
-    const rangeCopy = selection.getRangeAt(0).cloneRange();
-    const anchorElement = createElement('span');
-    anchorElement.textContent = '\u200B';
-    textRange.insertNode(anchorElement);
-    const box = anchorElement.boxInWindow(window);
-    anchorElement.remove();
-    selection.removeAllRanges();
-    selection.addRange(rangeCopy);
-    return box;
-  }
-
-  /**
-   * @return {?Range}
-   * @suppressGlobalPropertiesCheck
-   */
-  _createRange() {
-    return document.createRange();
-  }
-
-  /**
-   * @param {string} query
-   * @return {!UI.SuggestBox.Suggestions}
-   */
-  additionalCompletions(query) {
-    return [];
-  }
-
-  /**
-   * @param {number} completionRequestId
-   * @param {!Selection} selection
-   * @param {!Range} originalWordQueryRange
-   * @param {boolean} force
-   * @param {!UI.SuggestBox.Suggestions} completions
-   */
-  _completionsReady(completionRequestId, selection, originalWordQueryRange, force, completions) {
-    if (this._completionRequestId !== completionRequestId)
-      return;
-
-    const query = originalWordQueryRange.toString();
-
-    // Filter out dupes.
-    const store = new Set();
-    completions = completions.filter(item => !store.has(item.text) && !!store.add(item.text));
-
-    if (query || force) {
-      if (query)
-        completions = completions.concat(this.additionalCompletions(query));
-      else
-        completions = this.additionalCompletions(query).concat(completions);
-    }
-
-    if (!completions.length) {
-      this.clearAutocomplete();
-      return;
-    }
-
-    const selectionRange = selection.getRangeAt(0);
-
-    const fullWordRange = this._createRange();
-    fullWordRange.setStart(originalWordQueryRange.startContainer, originalWordQueryRange.startOffset);
-    fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
-
-    if (query + selectionRange.toString() !== fullWordRange.toString())
-      return;
-
-    const beforeRange = this._createRange();
-    beforeRange.setStart(this._element, 0);
-    beforeRange.setEnd(fullWordRange.startContainer, fullWordRange.startOffset);
-    this._queryRange = new TextUtils.TextRange(
-        0, beforeRange.toString().length, 0, beforeRange.toString().length + fullWordRange.toString().length);
-
-    const shouldSelect = !this._disableDefaultSuggestionForEmptyInput || !!this.text();
-    if (this._suggestBox) {
-      this._suggestBox.updateSuggestions(
-          this._boxForAnchorAtStart(selection, fullWordRange), completions, shouldSelect, !this._isCaretAtEndOfPrompt(),
-          this.text());
-    }
-  }
-
-  /**
-   * @override
-   * @param {string} suggestion
-   * @param {boolean=} isIntermediateSuggestion
-   */
-  applySuggestion(suggestion, isIntermediateSuggestion) {
-    this._currentSuggestion = suggestion;
-    this._refreshGhostText();
-    if (isIntermediateSuggestion)
-      this.dispatchEventToListeners(UI.TextPrompt.Events.TextChanged);
-  }
-
-  /**
-   * @override
-   */
-  acceptSuggestion() {
-    this._acceptSuggestionInternal();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _acceptSuggestionInternal() {
-    if (!this._queryRange)
-      return false;
-
-    this._element.textContent = this.textWithCurrentSuggestion();
-    this.setDOMSelection(
-        this._queryRange.startColumn + this._currentSuggestion.length,
-        this._queryRange.startColumn + this._currentSuggestion.length);
-
-    this.clearAutocomplete();
-    this.dispatchEventToListeners(UI.TextPrompt.Events.TextChanged);
-
-    return true;
-  }
-
-  /**
-   * @param {number} startColumn
-   * @param {number} endColumn
-   */
-  setDOMSelection(startColumn, endColumn) {
-    this._element.normalize();
-    const node = this._element.childNodes[0];
-    if (!node || node === this._ghostTextElement)
-      return;
-    const range = this._createRange();
-    range.setStart(node, startColumn);
-    range.setEnd(node, endColumn);
-    const selection = this._element.getComponentSelection();
-    selection.removeAllRanges();
-    selection.addRange(range);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isSuggestBoxVisible() {
-    return this._suggestBox && this._suggestBox.visible();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isCaretInsidePrompt() {
-    const selection = this._element.getComponentSelection();
-    // @see crbug.com/602541
-    const selectionRange = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
-    if (!selectionRange || !selection.isCollapsed)
-      return false;
-    return selectionRange.startContainer.isSelfOrDescendant(this._element);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _isCaretAtEndOfPrompt() {
-    const selection = this._element.getComponentSelection();
-    const selectionRange = selection && selection.rangeCount ? selection.getRangeAt(0) : null;
-    if (!selectionRange || !selection.isCollapsed)
-      return false;
-
-    let node = selectionRange.startContainer;
-    if (!node.isSelfOrDescendant(this._element))
-      return false;
-
-    if (this._ghostTextElement.isAncestor(node))
-      return true;
-
-    if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
-      return false;
-
-    let foundNextText = false;
-    while (node) {
-      if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
-        if (foundNextText && !this._ghostTextElement.isAncestor(node))
-          return false;
-        foundNextText = true;
-      }
-
-      node = node.traverseNextNode(this._element);
-    }
-
-    return true;
-  }
-
-  moveCaretToEndOfPrompt() {
-    const selection = this._element.getComponentSelection();
-    const selectionRange = this._createRange();
-
-    let container = this._element;
-    while (container.childNodes.length)
-      container = container.lastChild;
-    const offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : 0;
-    selectionRange.setStart(container, offset);
-    selectionRange.setEnd(container, offset);
-
-    selection.removeAllRanges();
-    selection.addRange(selectionRange);
-  }
-
-  /**
-   * @param {!Event} event
-   * @return {boolean}
-   */
-  tabKeyPressed(event) {
-    return this.acceptAutoComplete();
-  }
-
-  /**
-   * @return {?Element}
-   */
-  proxyElementForTests() {
-    return this._proxyElement || null;
-  }
-};
-
-UI.TextPrompt.DefaultAutocompletionTimeout = 250;
-
-/** @enum {symbol} */
-UI.TextPrompt.Events = {
-  TextChanged: Symbol('TextChanged')
-};
diff --git a/front_end/ui/ThrottledWidget.js b/front_end/ui/ThrottledWidget.js
deleted file mode 100644
index bbb4f37..0000000
--- a/front_end/ui/ThrottledWidget.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ThrottledWidget = class extends UI.VBox {
-  /**
-   * @param {boolean=} isWebComponent
-   * @param {number=} timeout
-   */
-  constructor(isWebComponent, timeout) {
-    super(isWebComponent);
-    this._updateThrottler = new Common.Throttler(timeout === undefined ? 100 : timeout);
-    this._updateWhenVisible = false;
-  }
-
-  /**
-   * @protected
-   * @return {!Promise<?>}
-   */
-  doUpdate() {
-    return Promise.resolve();
-  }
-
-  update() {
-    this._updateWhenVisible = !this.isShowing();
-    if (this._updateWhenVisible)
-      return;
-    this._updateThrottler.schedule(innerUpdate.bind(this));
-
-    /**
-     * @this {UI.ThrottledWidget}
-     * @return {!Promise<?>}
-     */
-    function innerUpdate() {
-      if (this.isShowing())
-        return this.doUpdate();
-      this._updateWhenVisible = true;
-      return Promise.resolve();
-    }
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    super.wasShown();
-    if (this._updateWhenVisible)
-      this.update();
-  }
-};
diff --git a/front_end/ui/Toolbar.js b/front_end/ui/Toolbar.js
deleted file mode 100644
index d04dfc3..0000000
--- a/front_end/ui/Toolbar.js
+++ /dev/null
@@ -1,1104 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.Toolbar = class {
-  /**
-   * @param {string} className
-   * @param {!Element=} parentElement
-   */
-  constructor(className, parentElement) {
-    /** @type {!Array.<!UI.ToolbarItem>} */
-    this._items = [];
-    this._reverse = false;
-    this.element = parentElement ? parentElement.createChild('div') : createElement('div');
-    this.element.className = className;
-    this.element.classList.add('toolbar');
-    this._enabled = true;
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/toolbar.css');
-    this._contentElement = this._shadowRoot.createChild('div', 'toolbar-shadow');
-    this._insertionPoint = this._contentElement.createChild('content');
-  }
-
-  /**
-   * @param {!UI.Action} action
-   * @param {!Array<!UI.ToolbarButton>=} toggledOptions
-   * @param {!Array<!UI.ToolbarButton>=} untoggledOptions
-   * @return {!UI.ToolbarToggle}
-   */
-  static createActionButton(action, toggledOptions, untoggledOptions) {
-    const button = new UI.ToolbarToggle(action.title(), action.icon(), action.toggledIcon());
-    button.setToggleWithRedColor(action.toggleWithRedColor());
-    button.addEventListener(UI.ToolbarButton.Events.Click, action.execute, action);
-    action.addEventListener(UI.Action.Events.Enabled, enabledChanged);
-    action.addEventListener(UI.Action.Events.Toggled, toggled);
-    /** @type {?UI.LongClickController} */
-    let longClickController = null;
-    /** @type {?Array<!UI.ToolbarButton>} */
-    let longClickButtons = null;
-    /** @type {?Element} */
-    let longClickGlyph = null;
-    toggled();
-    button.setEnabled(action.enabled());
-    return button;
-
-    /**
-     * @param {!Common.Event} event
-     */
-    function enabledChanged(event) {
-      button.setEnabled(/** @type {boolean} */ (event.data));
-    }
-
-    function toggled() {
-      button.setToggled(action.toggled());
-      if (action.title())
-        UI.Tooltip.install(button.element, action.title(), action.id());
-      updateOptions();
-    }
-
-    function updateOptions() {
-      const buttons = action.toggled() ? (toggledOptions || null) : (untoggledOptions || null);
-
-      if (buttons && buttons.length) {
-        if (!longClickController) {
-          longClickController = new UI.LongClickController(button.element, showOptions);
-          longClickGlyph = UI.Icon.create('largeicon-longclick-triangle', 'long-click-glyph');
-          button.element.appendChild(longClickGlyph);
-          longClickButtons = buttons;
-        }
-      } else {
-        if (longClickController) {
-          longClickController.dispose();
-          longClickController = null;
-          longClickGlyph.remove();
-          longClickGlyph = null;
-          longClickButtons = null;
-        }
-      }
-    }
-
-    function showOptions() {
-      let buttons = longClickButtons.slice();
-      const mainButtonClone = new UI.ToolbarToggle(action.title(), action.icon(), action.toggledIcon());
-      mainButtonClone.addEventListener(UI.ToolbarButton.Events.Click, clicked);
-
-      /**
-       * @param {!Common.Event} event
-       */
-      function clicked(event) {
-        button._clicked(/** @type {!Event} */ (event.data));
-      }
-
-      mainButtonClone.setToggled(action.toggled());
-      buttons.push(mainButtonClone);
-
-      const document = button.element.ownerDocument;
-      document.documentElement.addEventListener('mouseup', mouseUp, false);
-
-      const optionsGlassPane = new UI.GlassPane();
-      optionsGlassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-      optionsGlassPane.show(document);
-      const optionsBar = new UI.Toolbar('fill', optionsGlassPane.contentElement);
-      optionsBar._contentElement.classList.add('floating');
-      const buttonHeight = 26;
-
-      const hostButtonPosition = button.element.boxInWindow().relativeToElement(UI.GlassPane.container(document));
-
-      const topNotBottom = hostButtonPosition.y + buttonHeight * buttons.length < document.documentElement.offsetHeight;
-
-      if (topNotBottom)
-        buttons = buttons.reverse();
-
-      optionsBar.element.style.height = (buttonHeight * buttons.length) + 'px';
-      if (topNotBottom)
-        optionsBar.element.style.top = (hostButtonPosition.y - 5) + 'px';
-      else
-        optionsBar.element.style.top = (hostButtonPosition.y - (buttonHeight * (buttons.length - 1)) - 6) + 'px';
-      optionsBar.element.style.left = (hostButtonPosition.x - 5) + 'px';
-
-      for (let i = 0; i < buttons.length; ++i) {
-        buttons[i].element.addEventListener('mousemove', mouseOver, false);
-        buttons[i].element.addEventListener('mouseout', mouseOut, false);
-        optionsBar.appendToolbarItem(buttons[i]);
-      }
-      const hostButtonIndex = topNotBottom ? 0 : buttons.length - 1;
-      buttons[hostButtonIndex].element.classList.add('emulate-active');
-
-      function mouseOver(e) {
-        if (e.which !== 1)
-          return;
-        const buttonElement = e.target.enclosingNodeOrSelfWithClass('toolbar-item');
-        buttonElement.classList.add('emulate-active');
-      }
-
-      function mouseOut(e) {
-        if (e.which !== 1)
-          return;
-        const buttonElement = e.target.enclosingNodeOrSelfWithClass('toolbar-item');
-        buttonElement.classList.remove('emulate-active');
-      }
-
-      function mouseUp(e) {
-        if (e.which !== 1)
-          return;
-        optionsGlassPane.hide();
-        document.documentElement.removeEventListener('mouseup', mouseUp, false);
-
-        for (let i = 0; i < buttons.length; ++i) {
-          if (buttons[i].element.classList.contains('emulate-active')) {
-            buttons[i].element.classList.remove('emulate-active');
-            buttons[i]._clicked(e);
-            break;
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * @param {string} actionId
-   * @return {!UI.ToolbarToggle}
-   */
-  static createActionButtonForId(actionId) {
-    const action = UI.actionRegistry.action(actionId);
-    return UI.Toolbar.createActionButton(/** @type {!UI.Action} */ (action));
-  }
-
-  /**
-   * @return {!Element}
-   */
-  gripElementForResize() {
-    return this._contentElement;
-  }
-
-  /**
-   * @param {boolean=} reverse
-   * @param {boolean=} growVertically
-   */
-  makeWrappable(reverse, growVertically) {
-    this._contentElement.classList.add('wrappable');
-    this._reverse = !!reverse;
-    if (reverse)
-      this._contentElement.classList.add('wrappable-reverse');
-    if (growVertically)
-      this._contentElement.classList.add('toolbar-grow-vertical');
-  }
-
-  makeVertical() {
-    this._contentElement.classList.add('vertical');
-  }
-
-  makeBlueOnHover() {
-    this._contentElement.classList.add('toolbar-blue-on-hover');
-  }
-
-  makeToggledGray() {
-    this._contentElement.classList.add('toolbar-toggled-gray');
-  }
-
-  renderAsLinks() {
-    this._contentElement.classList.add('toolbar-render-as-links');
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setEnabled(enabled) {
-    this._enabled = enabled;
-    for (const item of this._items)
-      item._applyEnabledState(this._enabled && item._enabled);
-  }
-
-  /**
-   * @param {!UI.ToolbarItem} item
-   */
-  appendToolbarItem(item) {
-    this._items.push(item);
-    item._toolbar = this;
-    if (!this._enabled)
-      item._applyEnabledState(false);
-    if (this._reverse)
-      this._contentElement.insertBefore(item.element, this._insertionPoint.nextSibling);
-    else
-      this._contentElement.insertBefore(item.element, this._insertionPoint);
-    this._hideSeparatorDupes();
-  }
-
-  appendSeparator() {
-    this.appendToolbarItem(new UI.ToolbarSeparator());
-  }
-
-  appendSpacer() {
-    this.appendToolbarItem(new UI.ToolbarSeparator(true));
-  }
-
-  /**
-   * @param {string} text
-   */
-  appendText(text) {
-    this.appendToolbarItem(new UI.ToolbarText(text));
-  }
-
-  removeToolbarItems() {
-    for (const item of this._items)
-      delete item._toolbar;
-    this._items = [];
-    this._contentElement.removeChildren();
-    this._insertionPoint = this._contentElement.createChild('content');
-  }
-
-  /**
-   * @param {string} color
-   */
-  setColor(color) {
-    const style = createElement('style');
-    style.textContent = '.toolbar-glyph { background-color: ' + color + ' !important }';
-    this._shadowRoot.appendChild(style);
-  }
-
-  /**
-   * @param {string} color
-   */
-  setToggledColor(color) {
-    const style = createElement('style');
-    style.textContent =
-        '.toolbar-button.toolbar-state-on .toolbar-glyph { background-color: ' + color + ' !important }';
-    this._shadowRoot.appendChild(style);
-  }
-
-  _hideSeparatorDupes() {
-    if (!this._items.length)
-      return;
-    // Don't hide first and last separators if they were added explicitly.
-    let previousIsSeparator = false;
-    let lastSeparator;
-    let nonSeparatorVisible = false;
-    for (let i = 0; i < this._items.length; ++i) {
-      if (this._items[i] instanceof UI.ToolbarSeparator) {
-        this._items[i].setVisible(!previousIsSeparator);
-        previousIsSeparator = true;
-        lastSeparator = this._items[i];
-        continue;
-      }
-      if (this._items[i].visible()) {
-        previousIsSeparator = false;
-        lastSeparator = null;
-        nonSeparatorVisible = true;
-      }
-    }
-    if (lastSeparator && lastSeparator !== this._items.peekLast())
-      lastSeparator.setVisible(false);
-
-    this.element.classList.toggle('hidden', !!lastSeparator && lastSeparator.visible() && !nonSeparatorVisible);
-  }
-
-  /**
-   * @param {string} location
-   */
-  appendLocationItems(location) {
-    const extensions = self.runtime.extensions(UI.ToolbarItem.Provider);
-    const promises = [];
-    for (let i = 0; i < extensions.length; ++i) {
-      if (extensions[i].descriptor()['location'] === location)
-        promises.push(resolveItem(extensions[i]));
-    }
-    Promise.all(promises).then(appendItemsInOrder.bind(this));
-
-    /**
-     * @param {!Runtime.Extension} extension
-     * @return {!Promise<?UI.ToolbarItem>}
-     */
-    function resolveItem(extension) {
-      const descriptor = extension.descriptor();
-      if (descriptor['separator'])
-        return Promise.resolve(/** @type {?UI.ToolbarItem} */ (new UI.ToolbarSeparator()));
-      if (descriptor['actionId']) {
-        return Promise.resolve(
-            /** @type {?UI.ToolbarItem} */ (UI.Toolbar.createActionButtonForId(descriptor['actionId'])));
-      }
-      return extension.instance().then(fetchItemFromProvider);
-
-      /**
-       * @param {!Object} provider
-       * @return {?UI.ToolbarItem}
-       */
-      function fetchItemFromProvider(provider) {
-        return /** @type {!UI.ToolbarItem.Provider} */ (provider).item();
-      }
-    }
-
-    /**
-     * @param {!Array.<?UI.ToolbarItem>} items
-     * @this {UI.Toolbar}
-     */
-    function appendItemsInOrder(items) {
-      for (let i = 0; i < items.length; ++i) {
-        const item = items[i];
-        if (item)
-          this.appendToolbarItem(item);
-      }
-    }
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarItem = class extends Common.Object {
-  /**
-   * @param {!Element} element
-   */
-  constructor(element) {
-    super();
-    this.element = element;
-    this.element.classList.add('toolbar-item');
-    this._visible = true;
-    this._enabled = true;
-  }
-
-  /**
-   * @param {string} title
-   */
-  setTitle(title) {
-    if (this._title === title)
-      return;
-    this._title = title;
-    UI.ARIAUtils.setAccessibleName(this.element, title);
-    UI.Tooltip.install(this.element, title);
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setEnabled(value) {
-    if (this._enabled === value)
-      return;
-    this._enabled = value;
-    this._applyEnabledState(this._enabled && (!this._toolbar || this._toolbar._enabled));
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  _applyEnabledState(enabled) {
-    this.element.disabled = !enabled;
-  }
-
-  /**
-   * @return {boolean} x
-   */
-  visible() {
-    return this._visible;
-  }
-
-  /**
-   * @param {boolean} x
-   */
-  setVisible(x) {
-    if (this._visible === x)
-      return;
-    this.element.classList.toggle('hidden', !x);
-    this._visible = x;
-    if (this._toolbar && !(this instanceof UI.ToolbarSeparator))
-      this._toolbar._hideSeparatorDupes();
-  }
-
-  setRightAligned(alignRight) {
-    this.element.classList.toggle('toolbar-item-right-aligned', alignRight);
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarText = class extends UI.ToolbarItem {
-  /**
-   * @param {string=} text
-   */
-  constructor(text) {
-    super(createElementWithClass('div', 'toolbar-text'));
-    this.element.classList.add('toolbar-text');
-    this.setText(text || '');
-  }
-
-  /**
-   * @return {string}
-   */
-  text() {
-    return this.element.textContent;
-  }
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {
-    this.element.textContent = text;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarButton = class extends UI.ToolbarItem {
-  /**
-   * @param {string} title
-   * @param {string=} glyph
-   * @param {string=} text
-   */
-  constructor(title, glyph, text) {
-    super(createElementWithClass('button', 'toolbar-button'));
-    this.element.addEventListener('click', this._clicked.bind(this), false);
-    this.element.addEventListener('mousedown', this._mouseDown.bind(this), false);
-    this.element.addEventListener('mouseup', this._mouseUp.bind(this), false);
-
-    this._glyphElement = UI.Icon.create('', 'toolbar-glyph hidden');
-    this.element.appendChild(this._glyphElement);
-    this._textElement = this.element.createChild('div', 'toolbar-text hidden');
-
-    this.setTitle(title);
-    if (glyph)
-      this.setGlyph(glyph);
-    this.setText(text || '');
-    this._title = '';
-  }
-
-  /**
-   * @param {string} text
-   */
-  setText(text) {
-    if (this._text === text)
-      return;
-    this._textElement.textContent = text;
-    this._textElement.classList.toggle('hidden', !text);
-    this._text = text;
-  }
-
-  /**
-   * @param {string} glyph
-   */
-  setGlyph(glyph) {
-    if (this._glyph === glyph)
-      return;
-    this._glyphElement.setIconType(glyph);
-    this._glyphElement.classList.toggle('hidden', !glyph);
-    this.element.classList.toggle('toolbar-has-glyph', !!glyph);
-    this._glyph = glyph;
-  }
-
-  /**
-   * @param {string} iconURL
-   */
-  setBackgroundImage(iconURL) {
-    this.element.style.backgroundImage = 'url(' + iconURL + ')';
-  }
-
-  setDarkText() {
-    this.element.classList.add('dark-text');
-  }
-
-  /**
-   * @param {number=} width
-   */
-  turnIntoSelect(width) {
-    this.element.classList.add('toolbar-has-dropdown');
-    const dropdownArrowIcon = UI.Icon.create('smallicon-triangle-down', 'toolbar-dropdown-arrow');
-    this.element.appendChild(dropdownArrowIcon);
-    if (width)
-      this.element.style.width = width + 'px';
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _clicked(event) {
-    if (!this._enabled)
-      return;
-    this.dispatchEventToListeners(UI.ToolbarButton.Events.Click, event);
-    event.consume();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseDown(event) {
-    if (!this._enabled)
-      return;
-    this.dispatchEventToListeners(UI.ToolbarButton.Events.MouseDown, event);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseUp(event) {
-    if (!this._enabled)
-      return;
-    this.dispatchEventToListeners(UI.ToolbarButton.Events.MouseUp, event);
-  }
-};
-
-UI.ToolbarButton.Events = {
-  Click: Symbol('Click'),
-  MouseDown: Symbol('MouseDown'),
-  MouseUp: Symbol('MouseUp')
-};
-
-UI.ToolbarInput = class extends UI.ToolbarItem {
-  /**
-   * @param {string} placeholder
-   * @param {number=} growFactor
-   * @param {number=} shrinkFactor
-   * @param {string=} tooltip
-   * @param {(function(string, string, boolean=):!Promise<!UI.SuggestBox.Suggestions>)=} completions
-   */
-  constructor(placeholder, growFactor, shrinkFactor, tooltip, completions) {
-    super(createElementWithClass('div', 'toolbar-input'));
-
-    const internalPromptElement = this.element.createChild('div', 'toolbar-input-prompt');
-    internalPromptElement.addEventListener('focus', () => this.element.classList.add('focused'));
-    internalPromptElement.addEventListener('blur', () => this.element.classList.remove('focused'));
-
-    this._prompt = new UI.TextPrompt();
-    this._proxyElement = this._prompt.attach(internalPromptElement);
-    this._proxyElement.classList.add('toolbar-prompt-proxy');
-    this._proxyElement.addEventListener('keydown', event => this._onKeydownCallback(event));
-    this._prompt.initialize(completions || (() => Promise.resolve([])), ' ');
-    if (tooltip)
-      this._prompt.setTitle(tooltip);
-    this._prompt.setPlaceholder(placeholder);
-    this._prompt.addEventListener(UI.TextPrompt.Events.TextChanged, this._onChangeCallback.bind(this));
-
-    if (growFactor)
-      this.element.style.flexGrow = growFactor;
-    if (shrinkFactor)
-      this.element.style.flexShrink = shrinkFactor;
-
-    const clearButton = this.element.createChild('div', 'toolbar-input-clear-button');
-    clearButton.appendChild(UI.Icon.create('mediumicon-gray-cross-hover', 'search-cancel-button'));
-    clearButton.addEventListener('click', () => this._internalSetValue('', true));
-
-    this._updateEmptyStyles();
-  }
-
-  /**
-   * @override
-   * @param {boolean} enabled
-   */
-  _applyEnabledState(enabled) {
-    this._prompt.setEnabled(enabled);
-  }
-
-  /**
-   * @param {string} value
-   */
-  setValue(value) {
-    this._internalSetValue(value, false);
-  }
-
-  /**
-   * @param {string} value
-   * @param {boolean} notify
-   */
-  _internalSetValue(value, notify) {
-    this._prompt.setText(value);
-    if (notify)
-      this._onChangeCallback();
-    this._updateEmptyStyles();
-  }
-
-  /**
-   * @return {string}
-   */
-  value() {
-    return this._prompt.textWithCurrentSuggestion();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onKeydownCallback(event) {
-    if (!isEscKey(event) || !this._prompt.text())
-      return;
-    this._internalSetValue('', true);
-    event.consume(true);
-  }
-
-  _onChangeCallback() {
-    this._updateEmptyStyles();
-    this.dispatchEventToListeners(UI.ToolbarInput.Event.TextChanged, this._prompt.text());
-  }
-
-  _updateEmptyStyles() {
-    this.element.classList.toggle('toolbar-input-empty', !this._prompt.text());
-  }
-};
-
-UI.ToolbarInput.Event = {
-  TextChanged: Symbol('TextChanged')
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarToggle = class extends UI.ToolbarButton {
-  /**
-   * @param {string} title
-   * @param {string=} glyph
-   * @param {string=} toggledGlyph
-   */
-  constructor(title, glyph, toggledGlyph) {
-    super(title, glyph, '');
-    this._toggled = false;
-    this._untoggledGlyph = glyph;
-    this._toggledGlyph = toggledGlyph;
-    this.element.classList.add('toolbar-state-off');
-    UI.ARIAUtils.setPressed(this.element, false);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  toggled() {
-    return this._toggled;
-  }
-
-  /**
-   * @param {boolean} toggled
-   */
-  setToggled(toggled) {
-    if (this._toggled === toggled)
-      return;
-    this._toggled = toggled;
-    this.element.classList.toggle('toolbar-state-on', toggled);
-    this.element.classList.toggle('toolbar-state-off', !toggled);
-    UI.ARIAUtils.setPressed(this.element, toggled);
-    if (this._toggledGlyph && this._untoggledGlyph)
-      this.setGlyph(toggled ? this._toggledGlyph : this._untoggledGlyph);
-  }
-
-  /**
-   * @param {boolean} withRedColor
-   */
-  setDefaultWithRedColor(withRedColor) {
-    this.element.classList.toggle('toolbar-default-with-red-color', withRedColor);
-  }
-
-  /**
-   * @param {boolean} toggleWithRedColor
-   */
-  setToggleWithRedColor(toggleWithRedColor) {
-    this.element.classList.toggle('toolbar-toggle-with-red-color', toggleWithRedColor);
-  }
-};
-
-
-/**
- * @unrestricted
- */
-UI.ToolbarMenuButton = class extends UI.ToolbarButton {
-  /**
-   * @param {function(!UI.ContextMenu)} contextMenuHandler
-   * @param {boolean=} useSoftMenu
-   */
-  constructor(contextMenuHandler, useSoftMenu) {
-    super('', 'largeicon-menu');
-    this._contextMenuHandler = contextMenuHandler;
-    this._useSoftMenu = !!useSoftMenu;
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  _mouseDown(event) {
-    if (event.buttons !== 1) {
-      super._mouseDown(event);
-      return;
-    }
-
-    if (!this._triggerTimeout)
-      this._triggerTimeout = setTimeout(this._trigger.bind(this, event), 200);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _trigger(event) {
-    delete this._triggerTimeout;
-
-    // Throttling avoids entering a bad state on Macs when rapidly triggering context menus just
-    // after the window gains focus. See crbug.com/655556
-    if (this._lastTriggerTime && Date.now() - this._lastTriggerTime < 300)
-      return;
-    const contextMenu = new UI.ContextMenu(
-        event, this._useSoftMenu, this.element.totalOffsetLeft(),
-        this.element.totalOffsetTop() + this.element.offsetHeight);
-    this._contextMenuHandler(contextMenu);
-    contextMenu.show();
-    this._lastTriggerTime = Date.now();
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  _clicked(event) {
-    if (this._triggerTimeout)
-      clearTimeout(this._triggerTimeout);
-    this._trigger(event);
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarSettingToggle = class extends UI.ToolbarToggle {
-  /**
-   * @param {!Common.Setting} setting
-   * @param {string} glyph
-   * @param {string} title
-   * @param {string=} toggledTitle
-   */
-  constructor(setting, glyph, title, toggledTitle) {
-    super(title, glyph);
-    this._defaultTitle = title;
-    this._toggledTitle = toggledTitle || title;
-    this._setting = setting;
-    this._settingChanged();
-    this._setting.addChangeListener(this._settingChanged, this);
-  }
-
-  _settingChanged() {
-    const toggled = this._setting.get();
-    this.setToggled(toggled);
-    this.setTitle(toggled ? this._toggledTitle : this._defaultTitle);
-  }
-
-  /**
-   * @override
-   * @param {!Event} event
-   */
-  _clicked(event) {
-    this._setting.set(!this.toggled());
-    super._clicked(event);
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarSeparator = class extends UI.ToolbarItem {
-  /**
-   * @param {boolean=} spacer
-   */
-  constructor(spacer) {
-    super(createElementWithClass('div', spacer ? 'toolbar-spacer' : 'toolbar-divider'));
-  }
-};
-
-/**
- * @interface
- */
-UI.ToolbarItem.Provider = function() {};
-
-UI.ToolbarItem.Provider.prototype = {
-  /**
-   * @return {?UI.ToolbarItem}
-   */
-  item() {}
-};
-
-/**
- * @interface
- */
-UI.ToolbarItem.ItemsProvider = function() {};
-
-UI.ToolbarItem.ItemsProvider.prototype = {
-  /**
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  toolbarItems() {}
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarComboBox = class extends UI.ToolbarItem {
-  /**
-   * @param {?function(!Event)} changeHandler
-   * @param {string=} className
-   */
-  constructor(changeHandler, className) {
-    super(createElementWithClass('span', 'toolbar-select-container'));
-
-    this._selectElement = this.element.createChild('select', 'toolbar-item');
-    const dropdownArrowIcon = UI.Icon.create('smallicon-triangle-down', 'toolbar-dropdown-arrow');
-    this.element.appendChild(dropdownArrowIcon);
-    if (changeHandler)
-      this._selectElement.addEventListener('change', changeHandler, false);
-    if (className)
-      this._selectElement.classList.add(className);
-  }
-
-  /**
-   * @return {!HTMLSelectElement}
-   */
-  selectElement() {
-    return /** @type {!HTMLSelectElement} */ (this._selectElement);
-  }
-
-  /**
-   * @return {number}
-   */
-  size() {
-    return this._selectElement.childElementCount;
-  }
-
-  /**
-   * @return {!Array.<!Element>}
-   */
-  options() {
-    return Array.prototype.slice.call(this._selectElement.children, 0);
-  }
-
-  /**
-   * @param {!Element} option
-   */
-  addOption(option) {
-    this._selectElement.appendChild(option);
-  }
-
-  /**
-   * @param {string} label
-   * @param {string=} title
-   * @param {string=} value
-   * @return {!Element}
-   */
-  createOption(label, title, value) {
-    const option = this._selectElement.createChild('option');
-    option.text = label;
-    if (title)
-      option.title = title;
-    if (typeof value !== 'undefined')
-      option.value = value;
-    return option;
-  }
-
-  /**
-   * @override
-   * @param {boolean} enabled
-   */
-  _applyEnabledState(enabled) {
-    super._applyEnabledState(enabled);
-    this._selectElement.disabled = !enabled;
-  }
-
-  /**
-   * @param {!Element} option
-   */
-  removeOption(option) {
-    this._selectElement.removeChild(option);
-  }
-
-  removeOptions() {
-    this._selectElement.removeChildren();
-  }
-
-  /**
-   * @return {?Element}
-   */
-  selectedOption() {
-    if (this._selectElement.selectedIndex >= 0)
-      return this._selectElement[this._selectElement.selectedIndex];
-    return null;
-  }
-
-  /**
-   * @param {!Element} option
-   */
-  select(option) {
-    this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
-  }
-
-  /**
-   * @param {number} index
-   */
-  setSelectedIndex(index) {
-    this._selectElement.selectedIndex = index;
-  }
-
-  /**
-   * @return {number}
-   */
-  selectedIndex() {
-    return this._selectElement.selectedIndex;
-  }
-
-  /**
-   * @param {number} width
-   */
-  setMaxWidth(width) {
-    this._selectElement.style.maxWidth = width + 'px';
-  }
-
-  /**
-   * @param {number} width
-   */
-  setMinWidth(width) {
-    this._selectElement.style.minWidth = width + 'px';
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarSettingComboBox = class extends UI.ToolbarComboBox {
-  /**
-   * @param {!Array<!{value: string, label: string, title: string}>} options
-   * @param {!Common.Setting} setting
-   * @param {string=} optGroup
-   */
-  constructor(options, setting, optGroup) {
-    super(null);
-    this._setting = setting;
-    this._options = options;
-    this._selectElement.addEventListener('change', this._valueChanged.bind(this), false);
-    if (optGroup) {
-      const optGroupElement = this._selectElement.createChild('optgroup');
-      optGroupElement.label = optGroup;
-      this._optionContainer = optGroupElement;
-    } else {
-      this._optionContainer = this._selectElement;
-    }
-    this.setOptions(options);
-    setting.addChangeListener(this._settingChanged, this);
-  }
-
-  /**
-   * @param {!Array<!{value: string, label: string, title: string}>} options
-   */
-  setOptions(options) {
-    this._options = options;
-    this._optionContainer.removeChildren();
-    for (let i = 0; i < options.length; ++i) {
-      const dataOption = options[i];
-      const option = this.createOption(dataOption.label, dataOption.title, dataOption.value);
-      this._optionContainer.appendChild(option);
-      if (this._setting.get() === dataOption.value)
-        this.setSelectedIndex(i);
-    }
-  }
-
-  /**
-   * @return {string}
-   */
-  value() {
-    return this._options[this.selectedIndex()].value;
-  }
-
-  _settingChanged() {
-    if (this._muteSettingListener)
-      return;
-
-    const value = this._setting.get();
-    for (let i = 0; i < this._options.length; ++i) {
-      if (value === this._options[i].value) {
-        this.setSelectedIndex(i);
-        break;
-      }
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _valueChanged(event) {
-    const option = this._options[this.selectedIndex()];
-    this._muteSettingListener = true;
-    this._setting.set(option.value);
-    this._muteSettingListener = false;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ToolbarCheckbox = class extends UI.ToolbarItem {
-  /**
-   * @param {string} text
-   * @param {string=} tooltip
-   * @param {function()=} listener
-   */
-  constructor(text, tooltip, listener) {
-    super(UI.CheckboxLabel.create(text));
-    this.element.classList.add('checkbox');
-    this.inputElement = this.element.checkboxElement;
-    if (tooltip)
-      this.element.title = tooltip;
-    if (listener)
-      this.inputElement.addEventListener('click', listener, false);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  checked() {
-    return this.inputElement.checked;
-  }
-
-  /**
-   * @param {boolean} value
-   */
-  setChecked(value) {
-    this.inputElement.checked = value;
-  }
-
-  /**
-   * @override
-   * @param {boolean} enabled
-   */
-  _applyEnabledState(enabled) {
-    super._applyEnabledState(enabled);
-    this.inputElement.disabled = !enabled;
-  }
-};
-
-UI.ToolbarSettingCheckbox = class extends UI.ToolbarCheckbox {
-  /**
-   * @param {!Common.Setting} setting
-   * @param {string=} tooltip
-   * @param {string=} alternateTitle
-   */
-  constructor(setting, tooltip, alternateTitle) {
-    super(alternateTitle || setting.title() || '', tooltip);
-    UI.SettingsUI.bindCheckbox(this.inputElement, setting);
-  }
-};
diff --git a/front_end/ui/Tooltip.js b/front_end/ui/Tooltip.js
deleted file mode 100644
index ba7d8ed..0000000
--- a/front_end/ui/Tooltip.js
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.Tooltip = class {
-  /**
-   * @param {!Document} doc
-   */
-  constructor(doc) {
-    this.element = doc.body.createChild('div');
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/tooltip.css');
-
-    this._tooltipElement = this._shadowRoot.createChild('div', 'tooltip');
-    doc.addEventListener('mousemove', this._mouseMove.bind(this), true);
-    doc.addEventListener('mousedown', this._hide.bind(this, true), true);
-    doc.addEventListener('mouseleave', this._hide.bind(this, false), true);
-    doc.addEventListener('keydown', this._hide.bind(this, true), true);
-    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this._reset, this);
-    doc.defaultView.addEventListener('resize', this._reset.bind(this), false);
-  }
-
-  /**
-   * @param {!Document} doc
-   */
-  static installHandler(doc) {
-    new UI.Tooltip(doc);
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {?Element|string} tooltipContent
-   * @param {string=} actionId
-   * @param {!Object=} options
-   */
-  static install(element, tooltipContent, actionId, options) {
-    if (!tooltipContent) {
-      delete element[UI.Tooltip._symbol];
-      return;
-    }
-    element[UI.Tooltip._symbol] = {content: tooltipContent, actionId: actionId, options: options || {}};
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  static addNativeOverrideContainer(element) {
-    UI.Tooltip._nativeOverrideContainer.push(element);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _mouseMove(event) {
-    const mouseEvent = /** @type {!MouseEvent} */ (event);
-    const path = mouseEvent.path;
-    if (!path || mouseEvent.buttons !== 0 || (mouseEvent.movementX === 0 && mouseEvent.movementY === 0))
-      return;
-
-    if (this._anchorElement && path.indexOf(this._anchorElement) === -1)
-      this._hide(false);
-
-    for (const element of path) {
-      if (element === this._anchorElement) {
-        return;
-      } else if (element[UI.Tooltip._symbol]) {
-        this._show(element, mouseEvent);
-        return;
-      }
-    }
-  }
-
-  /**
-   * @param {!Element} anchorElement
-   * @param {!Event} event
-   */
-  _show(anchorElement, event) {
-    const tooltip = anchorElement[UI.Tooltip._symbol];
-    this._anchorElement = anchorElement;
-    this._tooltipElement.removeChildren();
-
-    // Check if native tooltips should be used.
-    for (const element of UI.Tooltip._nativeOverrideContainer) {
-      if (this._anchorElement.isSelfOrDescendant(element)) {
-        Object.defineProperty(this._anchorElement, 'title', UI.Tooltip._nativeTitle);
-        this._anchorElement.title = tooltip.content;
-        return;
-      }
-    }
-
-    if (typeof tooltip.content === 'string')
-      this._tooltipElement.setTextContentTruncatedIfNeeded(tooltip.content);
-    else
-      this._tooltipElement.appendChild(tooltip.content);
-
-    if (tooltip.actionId) {
-      const shortcuts = UI.shortcutRegistry.shortcutDescriptorsForAction(tooltip.actionId);
-      for (const shortcut of shortcuts) {
-        const shortcutElement = this._tooltipElement.createChild('div', 'tooltip-shortcut');
-        shortcutElement.textContent = shortcut.name;
-      }
-    }
-
-    this._tooltipElement.classList.add('shown');
-    // Reposition to ensure text doesn't overflow unnecessarily.
-    this._tooltipElement.positionAt(0, 0);
-
-    // Show tooltip instantly if a tooltip was shown recently.
-    const now = Date.now();
-    const instant = (this._tooltipLastClosed && now - this._tooltipLastClosed < UI.Tooltip.Timing.InstantThreshold);
-    this._tooltipElement.classList.toggle('instant', instant);
-    this._tooltipLastOpened = instant ? now : now + UI.Tooltip.Timing.OpeningDelay;
-
-    // Get container element.
-    const container = UI.GlassPane.container(/** @type {!Document} */ (anchorElement.ownerDocument));
-    // Position tooltip based on the anchor element.
-    const containerBox = container.boxInWindow(this.element.window());
-    const anchorBox = this._anchorElement.boxInWindow(this.element.window());
-    const anchorOffset = 2;
-    const pageMargin = 2;
-    const cursorOffset = 10;
-    this._tooltipElement.classList.toggle('tooltip-breakword', !this._tooltipElement.textContent.match('\\s'));
-    this._tooltipElement.style.maxWidth = (containerBox.width - pageMargin * 2) + 'px';
-    this._tooltipElement.style.maxHeight = '';
-    const tooltipWidth = this._tooltipElement.offsetWidth;
-    const tooltipHeight = this._tooltipElement.offsetHeight;
-    const anchorTooltipAtElement =
-        this._anchorElement.nodeName === 'BUTTON' || this._anchorElement.nodeName === 'LABEL';
-    let tooltipX = anchorTooltipAtElement ? anchorBox.x : event.x + cursorOffset;
-    tooltipX = Number.constrain(
-        tooltipX, containerBox.x + pageMargin, containerBox.x + containerBox.width - tooltipWidth - pageMargin);
-    let tooltipY;
-    if (!anchorTooltipAtElement) {
-      tooltipY = event.y + cursorOffset + tooltipHeight < containerBox.y + containerBox.height ?
-          event.y + cursorOffset :
-          event.y - tooltipHeight;
-    } else {
-      const onBottom =
-          anchorBox.y + anchorOffset + anchorBox.height + tooltipHeight < containerBox.y + containerBox.height;
-      tooltipY = onBottom ? anchorBox.y + anchorBox.height + anchorOffset : anchorBox.y - tooltipHeight - anchorOffset;
-    }
-    this._tooltipElement.positionAt(tooltipX, tooltipY);
-  }
-
-  /**
-   * @param {boolean} removeInstant
-   */
-  _hide(removeInstant) {
-    delete this._anchorElement;
-    this._tooltipElement.classList.remove('shown');
-    if (Date.now() > this._tooltipLastOpened)
-      this._tooltipLastClosed = Date.now();
-    if (removeInstant)
-      delete this._tooltipLastClosed;
-  }
-
-  _reset() {
-    this._hide(true);
-    this._tooltipElement.positionAt(0, 0);
-    this._tooltipElement.style.maxWidth = '0';
-    this._tooltipElement.style.maxHeight = '0';
-  }
-};
-
-UI.Tooltip.Timing = {
-  // Max time between tooltips showing that no opening delay is required.
-  'InstantThreshold': 300,
-  // Wait time before opening a tooltip.
-  'OpeningDelay': 600
-};
-
-UI.Tooltip._symbol = Symbol('Tooltip');
-
-
-/** @type {!Array.<!Element>} */
-UI.Tooltip._nativeOverrideContainer = [];
-UI.Tooltip._nativeTitle =
-    /** @type {!ObjectPropertyDescriptor} */ (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'title'));
-
-Object.defineProperty(HTMLElement.prototype, 'title', {
-  /**
-   * @return {!Element|string}
-   * @this {!Element}
-   */
-  get: function() {
-    const tooltip = this[UI.Tooltip._symbol];
-    return tooltip ? tooltip.content : '';
-  },
-
-  /**
-   * @param {!Element|string} x
-   * @this {!Element}
-   */
-  set: function(x) {
-    UI.Tooltip.install(this, x);
-  }
-});
diff --git a/front_end/ui/UIUtils.js b/front_end/ui/UIUtils.js
deleted file mode 100644
index 13c0a88..0000000
--- a/front_end/ui/UIUtils.js
+++ /dev/null
@@ -1,2020 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.  All rights reserved.
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-UI.highlightedSearchResultClassName = 'highlighted-search-result';
-UI.highlightedCurrentSearchResultClassName = 'current-search-result';
-
-/**
- * @param {!Element} element
- * @param {?function(!MouseEvent): boolean} elementDragStart
- * @param {function(!MouseEvent)} elementDrag
- * @param {?function(!MouseEvent)} elementDragEnd
- * @param {?string} cursor
- * @param {?string=} hoverCursor
- * @param {number=} startDelay
- */
-UI.installDragHandle = function(
-    element, elementDragStart, elementDrag, elementDragEnd, cursor, hoverCursor, startDelay) {
-  /**
-   * @param {!Event} event
-   */
-  function onMouseDown(event) {
-    const dragHandler = new UI.DragHandler();
-    const dragStart = dragHandler.elementDragStart.bind(
-        dragHandler, element, elementDragStart, elementDrag, elementDragEnd, cursor, event);
-    if (startDelay)
-      startTimer = setTimeout(dragStart, startDelay);
-    else
-      dragStart();
-  }
-
-  function onMouseUp() {
-    if (startTimer)
-      clearTimeout(startTimer);
-    startTimer = null;
-  }
-
-  let startTimer;
-  element.addEventListener('mousedown', onMouseDown, false);
-  if (startDelay)
-    element.addEventListener('mouseup', onMouseUp, false);
-  if (hoverCursor !== null)
-    element.style.cursor = hoverCursor || cursor || '';
-};
-
-/**
- * @param {!Element} targetElement
- * @param {?function(!MouseEvent):boolean} elementDragStart
- * @param {function(!MouseEvent)} elementDrag
- * @param {?function(!MouseEvent)} elementDragEnd
- * @param {?string} cursor
- * @param {!Event} event
- */
-UI.elementDragStart = function(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event) {
-  const dragHandler = new UI.DragHandler();
-  dragHandler.elementDragStart(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event);
-};
-
-/**
- * @unrestricted
- */
-UI.DragHandler = class {
-  constructor() {
-    this._elementDragMove = this._elementDragMove.bind(this);
-    this._elementDragEnd = this._elementDragEnd.bind(this);
-    this._mouseOutWhileDragging = this._mouseOutWhileDragging.bind(this);
-  }
-
-  _createGlassPane() {
-    this._glassPaneInUse = true;
-    if (!UI.DragHandler._glassPaneUsageCount++) {
-      UI.DragHandler._glassPane = new UI.GlassPane();
-      UI.DragHandler._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.BlockedByGlassPane);
-      UI.DragHandler._glassPane.show(UI.DragHandler._documentForMouseOut);
-    }
-  }
-
-  _disposeGlassPane() {
-    if (!this._glassPaneInUse)
-      return;
-    this._glassPaneInUse = false;
-    if (--UI.DragHandler._glassPaneUsageCount)
-      return;
-    UI.DragHandler._glassPane.hide();
-    delete UI.DragHandler._glassPane;
-    delete UI.DragHandler._documentForMouseOut;
-  }
-
-  /**
-   * @param {!Element} targetElement
-   * @param {?function(!MouseEvent):boolean} elementDragStart
-   * @param {function(!MouseEvent)} elementDrag
-   * @param {?function(!MouseEvent)} elementDragEnd
-   * @param {?string} cursor
-   * @param {!Event} event
-   */
-  elementDragStart(targetElement, elementDragStart, elementDrag, elementDragEnd, cursor, event) {
-    // Only drag upon left button. Right will likely cause a context menu. So will ctrl-click on mac.
-    if (event.button || (Host.isMac() && event.ctrlKey))
-      return;
-
-    if (this._elementDraggingEventListener)
-      return;
-
-    if (elementDragStart && !elementDragStart(/** @type {!MouseEvent} */ (event)))
-      return;
-
-    const targetDocument = event.target.ownerDocument;
-    this._elementDraggingEventListener = elementDrag;
-    this._elementEndDraggingEventListener = elementDragEnd;
-    console.assert(
-        (UI.DragHandler._documentForMouseOut || targetDocument) === targetDocument, 'Dragging on multiple documents.');
-    UI.DragHandler._documentForMouseOut = targetDocument;
-    this._dragEventsTargetDocument = targetDocument;
-    try {
-      this._dragEventsTargetDocumentTop = targetDocument.defaultView.top.document;
-    } catch (e) {
-      this._dragEventsTargetDocumentTop = this._dragEventsTargetDocument;
-    }
-
-    targetDocument.addEventListener('mousemove', this._elementDragMove, true);
-    targetDocument.addEventListener('mouseup', this._elementDragEnd, true);
-    targetDocument.addEventListener('mouseout', this._mouseOutWhileDragging, true);
-    if (targetDocument !== this._dragEventsTargetDocumentTop)
-      this._dragEventsTargetDocumentTop.addEventListener('mouseup', this._elementDragEnd, true);
-
-    if (typeof cursor === 'string') {
-      this._restoreCursorAfterDrag = restoreCursor.bind(this, targetElement.style.cursor);
-      targetElement.style.cursor = cursor;
-      targetDocument.body.style.cursor = cursor;
-    }
-    /**
-     * @param {string} oldCursor
-     * @this {UI.DragHandler}
-     */
-    function restoreCursor(oldCursor) {
-      targetDocument.body.style.removeProperty('cursor');
-      targetElement.style.cursor = oldCursor;
-      this._restoreCursorAfterDrag = null;
-    }
-    event.preventDefault();
-  }
-
-  _mouseOutWhileDragging() {
-    this._unregisterMouseOutWhileDragging();
-    this._createGlassPane();
-  }
-
-  _unregisterMouseOutWhileDragging() {
-    if (!UI.DragHandler._documentForMouseOut)
-      return;
-    UI.DragHandler._documentForMouseOut.removeEventListener('mouseout', this._mouseOutWhileDragging, true);
-  }
-
-  _unregisterDragEvents() {
-    if (!this._dragEventsTargetDocument)
-      return;
-    this._dragEventsTargetDocument.removeEventListener('mousemove', this._elementDragMove, true);
-    this._dragEventsTargetDocument.removeEventListener('mouseup', this._elementDragEnd, true);
-    if (this._dragEventsTargetDocument !== this._dragEventsTargetDocumentTop)
-      this._dragEventsTargetDocumentTop.removeEventListener('mouseup', this._elementDragEnd, true);
-    delete this._dragEventsTargetDocument;
-    delete this._dragEventsTargetDocumentTop;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _elementDragMove(event) {
-    if (event.buttons !== 1) {
-      this._elementDragEnd(event);
-      return;
-    }
-    if (this._elementDraggingEventListener(/** @type {!MouseEvent} */ (event)))
-      this._cancelDragEvents(event);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _cancelDragEvents(event) {
-    this._unregisterDragEvents();
-    this._unregisterMouseOutWhileDragging();
-
-    if (this._restoreCursorAfterDrag)
-      this._restoreCursorAfterDrag();
-
-    this._disposeGlassPane();
-
-    delete this._elementDraggingEventListener;
-    delete this._elementEndDraggingEventListener;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _elementDragEnd(event) {
-    const elementDragEnd = this._elementEndDraggingEventListener;
-    this._cancelDragEvents(/** @type {!MouseEvent} */ (event));
-    event.preventDefault();
-    if (elementDragEnd)
-      elementDragEnd(/** @type {!MouseEvent} */ (event));
-  }
-};
-
-UI.DragHandler._glassPaneUsageCount = 0;
-
-/**
- * @param {?Node=} node
- * @return {boolean}
- */
-UI.isBeingEdited = function(node) {
-  if (!node || node.nodeType !== Node.ELEMENT_NODE)
-    return false;
-  let element = /** {!Element} */ (node);
-  if (element.classList.contains('text-prompt') || element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA')
-    return true;
-
-  if (!UI.__editingCount)
-    return false;
-
-  while (element) {
-    if (element.__editing)
-      return true;
-    element = element.parentElementOrShadowHost();
-  }
-  return false;
-};
-
-/**
- * @return {boolean}
- * @suppressGlobalPropertiesCheck
- */
-UI.isEditing = function() {
-  if (UI.__editingCount)
-    return true;
-
-  const focused = document.deepActiveElement();
-  if (!focused)
-    return false;
-  return focused.classList.contains('text-prompt') || focused.nodeName === 'INPUT' || focused.nodeName === 'TEXTAREA';
-};
-
-/**
- * @param {!Element} element
- * @param {boolean} value
- * @return {boolean}
- */
-UI.markBeingEdited = function(element, value) {
-  if (value) {
-    if (element.__editing)
-      return false;
-    element.classList.add('being-edited');
-    element.__editing = true;
-    UI.__editingCount = (UI.__editingCount || 0) + 1;
-  } else {
-    if (!element.__editing)
-      return false;
-    element.classList.remove('being-edited');
-    delete element.__editing;
-    --UI.__editingCount;
-  }
-  return true;
-};
-
-// Avoids Infinity, NaN, and scientific notation (e.g. 1e20), see crbug.com/81165.
-UI._numberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;
-
-UI.StyleValueDelimiters = ' \xA0\t\n"\':;,/()';
-
-/**
- * @param {!Event} event
- * @return {?string}
- */
-UI._valueModificationDirection = function(event) {
-  let direction = null;
-  if (event.type === 'mousewheel') {
-    // When shift is pressed while spinning mousewheel, delta comes as wheelDeltaX.
-    if (event.wheelDeltaY > 0 || event.wheelDeltaX > 0)
-      direction = 'Up';
-    else if (event.wheelDeltaY < 0 || event.wheelDeltaX < 0)
-      direction = 'Down';
-  } else {
-    if (event.key === 'ArrowUp' || event.key === 'PageUp')
-      direction = 'Up';
-    else if (event.key === 'ArrowDown' || event.key === 'PageDown')
-      direction = 'Down';
-  }
-  return direction;
-};
-
-/**
- * @param {string} hexString
- * @param {!Event} event
- * @return {?string}
- */
-UI._modifiedHexValue = function(hexString, event) {
-  const direction = UI._valueModificationDirection(event);
-  if (!direction)
-    return null;
-
-  const mouseEvent = /** @type {!MouseEvent} */ (event);
-  const number = parseInt(hexString, 16);
-  if (isNaN(number) || !isFinite(number))
-    return null;
-
-  const hexStrLen = hexString.length;
-  const channelLen = hexStrLen / 3;
-
-  // Colors are either rgb or rrggbb.
-  if (channelLen !== 1 && channelLen !== 2)
-    return null;
-
-  // Precision modifier keys work with both mousewheel and up/down keys.
-  // When ctrl is pressed, increase R by 1.
-  // When shift is pressed, increase G by 1.
-  // When alt is pressed, increase B by 1.
-  // If no shortcut keys are pressed then increase hex value by 1.
-  // Keys can be pressed together to increase RGB channels. e.g trying different shades.
-  let delta = 0;
-  if (UI.KeyboardShortcut.eventHasCtrlOrMeta(mouseEvent))
-    delta += Math.pow(16, channelLen * 2);
-  if (mouseEvent.shiftKey)
-    delta += Math.pow(16, channelLen);
-  if (mouseEvent.altKey)
-    delta += 1;
-  if (delta === 0)
-    delta = 1;
-  if (direction === 'Down')
-    delta *= -1;
-
-  // Increase hex value by 1 and clamp from 0 ... maxValue.
-  const maxValue = Math.pow(16, hexStrLen) - 1;
-  const result = Number.constrain(number + delta, 0, maxValue);
-
-  // Ensure the result length is the same as the original hex value.
-  let resultString = result.toString(16).toUpperCase();
-  for (let i = 0, lengthDelta = hexStrLen - resultString.length; i < lengthDelta; ++i)
-    resultString = '0' + resultString;
-  return resultString;
-};
-
-/**
- * @param {number} number
- * @param {!Event} event
- * @param {number=} modifierMultiplier
- * @return {?number}
- */
-UI._modifiedFloatNumber = function(number, event, modifierMultiplier) {
-  const direction = UI._valueModificationDirection(event);
-  if (!direction)
-    return null;
-
-  const mouseEvent = /** @type {!MouseEvent} */ (event);
-
-  // Precision modifier keys work with both mousewheel and up/down keys.
-  // When ctrl is pressed, increase by 100.
-  // When shift is pressed, increase by 10.
-  // When alt is pressed, increase by 0.1.
-  // Otherwise increase by 1.
-  let delta = 1;
-  if (UI.KeyboardShortcut.eventHasCtrlOrMeta(mouseEvent))
-    delta = 100;
-  else if (mouseEvent.shiftKey)
-    delta = 10;
-  else if (mouseEvent.altKey)
-    delta = 0.1;
-
-  if (direction === 'Down')
-    delta *= -1;
-  if (modifierMultiplier)
-    delta *= modifierMultiplier;
-
-  // Make the new number and constrain it to a precision of 6, this matches numbers the engine returns.
-  // Use the Number constructor to forget the fixed precision, so 1.100000 will print as 1.1.
-  const result = Number((number + delta).toFixed(6));
-  if (!String(result).match(UI._numberRegex))
-    return null;
-  return result;
-};
-
-/**
- * @param {string} wordString
- * @param {!Event} event
- * @param {function(string, number, string):string=} customNumberHandler
- * @return {?string}
- */
-UI.createReplacementString = function(wordString, event, customNumberHandler) {
-  let prefix;
-  let suffix;
-  let number;
-  let replacementString = null;
-  let matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
-  if (matches && matches.length) {
-    prefix = matches[1];
-    suffix = matches[3];
-    number = UI._modifiedHexValue(matches[2], event);
-    if (number !== null)
-      replacementString = prefix + number + suffix;
-  } else {
-    matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
-    if (matches && matches.length) {
-      prefix = matches[1];
-      suffix = matches[3];
-      number = UI._modifiedFloatNumber(parseFloat(matches[2]), event);
-      if (number !== null) {
-        replacementString =
-            customNumberHandler ? customNumberHandler(prefix, number, suffix) : prefix + number + suffix;
-      }
-    }
-  }
-  return replacementString;
-};
-
-/**
- * @param {!Event} event
- * @param {!Element} element
- * @param {function(string,string)=} finishHandler
- * @param {function(string)=} suggestionHandler
- * @param {function(string, number, string):string=} customNumberHandler
- * @return {boolean}
- */
-UI.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler) {
-  /**
-   * @return {?Range}
-   * @suppressGlobalPropertiesCheck
-   */
-  function createRange() {
-    return document.createRange();
-  }
-
-  const arrowKeyOrMouseWheelEvent =
-      (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.type === 'mousewheel');
-  const pageKeyPressed = (event.key === 'PageUp' || event.key === 'PageDown');
-  if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed)
-    return false;
-
-  const selection = element.getComponentSelection();
-  if (!selection.rangeCount)
-    return false;
-
-  const selectionRange = selection.getRangeAt(0);
-  if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
-    return false;
-
-  const originalValue = element.textContent;
-  const wordRange =
-      selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, UI.StyleValueDelimiters, element);
-  const wordString = wordRange.toString();
-
-  if (suggestionHandler && suggestionHandler(wordString))
-    return false;
-
-  const replacementString = UI.createReplacementString(wordString, event, customNumberHandler);
-
-  if (replacementString) {
-    const replacementTextNode = createTextNode(replacementString);
-
-    wordRange.deleteContents();
-    wordRange.insertNode(replacementTextNode);
-
-    const finalSelectionRange = createRange();
-    finalSelectionRange.setStart(replacementTextNode, 0);
-    finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
-
-    selection.removeAllRanges();
-    selection.addRange(finalSelectionRange);
-
-    event.handled = true;
-    event.preventDefault();
-
-    if (finishHandler)
-      finishHandler(originalValue, replacementString);
-
-    return true;
-  }
-  return false;
-};
-
-/**
- * @param {number} ms
- * @param {number=} precision
- * @return {string}
- */
-Number.preciseMillisToString = function(ms, precision) {
-  precision = precision || 0;
-  const format = '%.' + precision + 'f\xa0ms';
-  return Common.UIString(format, ms);
-};
-
-/** @type {!Common.UIStringFormat} */
-UI._microsFormat = new Common.UIStringFormat('%.0f\xa0\u03bcs');
-
-/** @type {!Common.UIStringFormat} */
-UI._subMillisFormat = new Common.UIStringFormat('%.2f\xa0ms');
-
-/** @type {!Common.UIStringFormat} */
-UI._millisFormat = new Common.UIStringFormat('%.0f\xa0ms');
-
-/** @type {!Common.UIStringFormat} */
-UI._secondsFormat = new Common.UIStringFormat('%.2f\xa0s');
-
-/** @type {!Common.UIStringFormat} */
-UI._minutesFormat = new Common.UIStringFormat('%.1f\xa0min');
-
-/** @type {!Common.UIStringFormat} */
-UI._hoursFormat = new Common.UIStringFormat('%.1f\xa0hrs');
-
-/** @type {!Common.UIStringFormat} */
-UI._daysFormat = new Common.UIStringFormat('%.1f\xa0days');
-
-/**
- * @param {number} ms
- * @param {boolean=} higherResolution
- * @return {string}
- */
-Number.millisToString = function(ms, higherResolution) {
-  if (!isFinite(ms))
-    return '-';
-
-  if (ms === 0)
-    return '0';
-
-  if (higherResolution && ms < 0.1)
-    return UI._microsFormat.format(ms * 1000);
-  if (higherResolution && ms < 1000)
-    return UI._subMillisFormat.format(ms);
-  if (ms < 1000)
-    return UI._millisFormat.format(ms);
-
-  const seconds = ms / 1000;
-  if (seconds < 60)
-    return UI._secondsFormat.format(seconds);
-
-  const minutes = seconds / 60;
-  if (minutes < 60)
-    return UI._minutesFormat.format(minutes);
-
-  const hours = minutes / 60;
-  if (hours < 24)
-    return UI._hoursFormat.format(hours);
-
-  const days = hours / 24;
-  return UI._daysFormat.format(days);
-};
-
-/**
- * @param {number} seconds
- * @param {boolean=} higherResolution
- * @return {string}
- */
-Number.secondsToString = function(seconds, higherResolution) {
-  if (!isFinite(seconds))
-    return '-';
-  return Number.millisToString(seconds * 1000, higherResolution);
-};
-
-/**
- * @param {number} bytes
- * @return {string}
- */
-Number.bytesToString = function(bytes) {
-  if (bytes < 1024)
-    return Common.UIString('%.0f\xa0B', bytes);
-
-  const kilobytes = bytes / 1024;
-  if (kilobytes < 100)
-    return Common.UIString('%.1f\xa0KB', kilobytes);
-  if (kilobytes < 1024)
-    return Common.UIString('%.0f\xa0KB', kilobytes);
-
-  const megabytes = kilobytes / 1024;
-  if (megabytes < 100)
-    return Common.UIString('%.1f\xa0MB', megabytes);
-  else
-    return Common.UIString('%.0f\xa0MB', megabytes);
-};
-
-/**
- * @param {number} num
- * @return {string}
- */
-Number.withThousandsSeparator = function(num) {
-  let str = num + '';
-  const re = /(\d+)(\d{3})/;
-  while (str.match(re))
-    str = str.replace(re, '$1\xa0$2');  // \xa0 is a non-breaking space
-  return str;
-};
-
-/**
- * @param {string} format
- * @param {?ArrayLike} substitutions
- * @return {!Element}
- */
-UI.formatLocalized = function(format, substitutions) {
-  const formatters = {s: substitution => substitution};
-  /**
-   * @param {!Element} a
-   * @param {string|!Element} b
-   * @return {!Element}
-   */
-  function append(a, b) {
-    a.appendChild(typeof b === 'string' ? createTextNode(b) : b);
-    return a;
-  }
-  return String.format(Common.UIString(format), substitutions, formatters, createElement('span'), append)
-      .formattedResult;
-};
-
-/**
- * @return {string}
- */
-UI.openLinkExternallyLabel = function() {
-  return Common.UIString('Open in new tab');
-};
-
-/**
- * @return {string}
- */
-UI.copyLinkAddressLabel = function() {
-  return Common.UIString('Copy link address');
-};
-
-/**
- * @return {string}
- */
-UI.anotherProfilerActiveLabel = function() {
-  return Common.UIString('Another profiler is already active');
-};
-
-/**
- * @param {string|undefined} description
- * @return {string}
- */
-UI.asyncStackTraceLabel = function(description) {
-  if (description) {
-    if (description === 'Promise.resolve')
-      description = Common.UIString('Promise resolved');
-    else if (description === 'Promise.reject')
-      description = Common.UIString('Promise rejected');
-    return description + ' ' + Common.UIString('(async)');
-  }
-  return Common.UIString('Async Call');
-};
-
-/**
- * @param {!Element} element
- */
-UI.installComponentRootStyles = function(element) {
-  UI.appendStyle(element, 'ui/inspectorCommon.css');
-  UI.themeSupport.injectHighlightStyleSheets(element);
-  UI.themeSupport.injectCustomStyleSheets(element);
-  element.classList.add('platform-' + Host.platform());
-
-  // Detect overlay scrollbar enable by checking for nonzero scrollbar width.
-  if (!Host.isMac() && UI.measuredScrollbarWidth(element.ownerDocument) === 0)
-    element.classList.add('overlay-scrollbar-enabled');
-};
-
-/**
- * @param {?Document} document
- * @return {number}
- */
-UI.measuredScrollbarWidth = function(document) {
-  if (typeof UI._measuredScrollbarWidth === 'number')
-    return UI._measuredScrollbarWidth;
-  if (!document)
-    return 16;
-  const scrollDiv = document.createElement('div');
-  scrollDiv.setAttribute('style', 'width: 100px; height: 100px; overflow: scroll;');
-  document.body.appendChild(scrollDiv);
-  UI._measuredScrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
-  document.body.removeChild(scrollDiv);
-  return UI._measuredScrollbarWidth;
-};
-
-/**
- * @param {!Element} element
- * @param {string=} cssFile
- * @return {!DocumentFragment}
- */
-UI.createShadowRootWithCoreStyles = function(element, cssFile) {
-  const shadowRoot = element.createShadowRoot();
-  UI.appendStyle(shadowRoot, 'ui/inspectorCommon.css');
-  UI.themeSupport.injectHighlightStyleSheets(shadowRoot);
-  UI.themeSupport.injectCustomStyleSheets(shadowRoot);
-  if (cssFile)
-    UI.appendStyle(shadowRoot, cssFile);
-  shadowRoot.addEventListener('focus', UI._focusChanged.bind(UI), true);
-  return shadowRoot;
-};
-
-/**
- * @param {!Document} document
- * @param {!Event} event
- */
-UI._windowFocused = function(document, event) {
-  if (event.target.document.nodeType === Node.DOCUMENT_NODE)
-    document.body.classList.remove('inactive');
-  UI._keyboardFocus = true;
-  const listener = () => {
-    const activeElement = document.deepActiveElement();
-    if (activeElement)
-      activeElement.removeAttribute('data-keyboard-focus');
-    UI._keyboardFocus = false;
-  };
-  document.defaultView.requestAnimationFrame(() => {
-    UI._keyboardFocus = false;
-    document.removeEventListener('mousedown', listener, true);
-  });
-  document.addEventListener('mousedown', listener, true);
-
-};
-
-/**
- * @param {!Document} document
- * @param {!Event} event
- */
-UI._windowBlurred = function(document, event) {
-  if (event.target.document.nodeType === Node.DOCUMENT_NODE)
-    document.body.classList.add('inactive');
-};
-
-/**
- * @param {!Event} event
- */
-UI._focusChanged = function(event) {
-  const document = event.target && event.target.ownerDocument;
-  const element = document ? document.deepActiveElement() : null;
-  UI.Widget.focusWidgetForNode(element);
-  UI.XWidget.focusWidgetForNode(element);
-  if (!UI._keyboardFocus)
-    return;
-  element.setAttribute('data-keyboard-focus', 'true');
-  element.addEventListener('blur', () => element.removeAttribute('data-keyboard-focus'), {once: true, capture: true});
-};
-
-/**
- * @unrestricted
- */
-UI.ElementFocusRestorer = class {
-  /**
-   * @param {!Element} element
-   */
-  constructor(element) {
-    this._element = element;
-    this._previous = element.ownerDocument.deepActiveElement();
-    element.focus();
-  }
-
-  restore() {
-    if (!this._element)
-      return;
-    if (this._element.hasFocus() && this._previous)
-      this._previous.focus();
-    this._previous = null;
-    this._element = null;
-  }
-};
-
-/**
- * @param {!Element} element
- * @param {number} offset
- * @param {number} length
- * @param {!Array.<!Object>=} domChanges
- * @return {?Element}
- */
-UI.highlightSearchResult = function(element, offset, length, domChanges) {
-  const result = UI.highlightSearchResults(element, [new TextUtils.SourceRange(offset, length)], domChanges);
-  return result.length ? result[0] : null;
-};
-
-/**
- * @param {!Element} element
- * @param {!Array.<!TextUtils.SourceRange>} resultRanges
- * @param {!Array.<!Object>=} changes
- * @return {!Array.<!Element>}
- */
-UI.highlightSearchResults = function(element, resultRanges, changes) {
-  return UI.highlightRangesWithStyleClass(element, resultRanges, UI.highlightedSearchResultClassName, changes);
-};
-
-/**
- * @param {!Element} element
- * @param {string} className
- */
-UI.runCSSAnimationOnce = function(element, className) {
-  function animationEndCallback() {
-    element.classList.remove(className);
-    element.removeEventListener('webkitAnimationEnd', animationEndCallback, false);
-  }
-
-  if (element.classList.contains(className))
-    element.classList.remove(className);
-
-  element.addEventListener('webkitAnimationEnd', animationEndCallback, false);
-  element.classList.add(className);
-};
-
-/**
- * @param {!Element} element
- * @param {!Array.<!TextUtils.SourceRange>} resultRanges
- * @param {string} styleClass
- * @param {!Array.<!Object>=} changes
- * @return {!Array.<!Element>}
- */
-UI.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes) {
-  changes = changes || [];
-  const highlightNodes = [];
-  const textNodes = element.childTextNodes();
-  const lineText = textNodes
-                       .map(function(node) {
-                         return node.textContent;
-                       })
-                       .join('');
-  const ownerDocument = element.ownerDocument;
-
-  if (textNodes.length === 0)
-    return highlightNodes;
-
-  const nodeRanges = [];
-  let rangeEndOffset = 0;
-  for (let i = 0; i < textNodes.length; ++i) {
-    const range = {};
-    range.offset = rangeEndOffset;
-    range.length = textNodes[i].textContent.length;
-    rangeEndOffset = range.offset + range.length;
-    nodeRanges.push(range);
-  }
-
-  let startIndex = 0;
-  for (let i = 0; i < resultRanges.length; ++i) {
-    const startOffset = resultRanges[i].offset;
-    const endOffset = startOffset + resultRanges[i].length;
-
-    while (startIndex < textNodes.length &&
-           nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
-      startIndex++;
-    let endIndex = startIndex;
-    while (endIndex < textNodes.length && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
-      endIndex++;
-    if (endIndex === textNodes.length)
-      break;
-
-    const highlightNode = ownerDocument.createElement('span');
-    highlightNode.className = styleClass;
-    highlightNode.textContent = lineText.substring(startOffset, endOffset);
-
-    const lastTextNode = textNodes[endIndex];
-    const lastText = lastTextNode.textContent;
-    lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
-    changes.push({node: lastTextNode, type: 'changed', oldText: lastText, newText: lastTextNode.textContent});
-
-    if (startIndex === endIndex) {
-      lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
-      changes.push({node: highlightNode, type: 'added', nextSibling: lastTextNode, parent: lastTextNode.parentElement});
-      highlightNodes.push(highlightNode);
-
-      const prefixNode =
-          ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
-      lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
-      changes.push({node: prefixNode, type: 'added', nextSibling: highlightNode, parent: lastTextNode.parentElement});
-    } else {
-      const firstTextNode = textNodes[startIndex];
-      const firstText = firstTextNode.textContent;
-      const anchorElement = firstTextNode.nextSibling;
-
-      firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
-      changes.push(
-          {node: highlightNode, type: 'added', nextSibling: anchorElement, parent: firstTextNode.parentElement});
-      highlightNodes.push(highlightNode);
-
-      firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
-      changes.push({node: firstTextNode, type: 'changed', oldText: firstText, newText: firstTextNode.textContent});
-
-      for (let j = startIndex + 1; j < endIndex; j++) {
-        const textNode = textNodes[j];
-        const text = textNode.textContent;
-        textNode.textContent = '';
-        changes.push({node: textNode, type: 'changed', oldText: text, newText: textNode.textContent});
-      }
-    }
-    startIndex = endIndex;
-    nodeRanges[startIndex].offset = endOffset;
-    nodeRanges[startIndex].length = lastTextNode.textContent.length;
-  }
-  return highlightNodes;
-};
-
-UI.applyDomChanges = function(domChanges) {
-  for (let i = 0, size = domChanges.length; i < size; ++i) {
-    const entry = domChanges[i];
-    switch (entry.type) {
-      case 'added':
-        entry.parent.insertBefore(entry.node, entry.nextSibling);
-        break;
-      case 'changed':
-        entry.node.textContent = entry.newText;
-        break;
-    }
-  }
-};
-
-UI.revertDomChanges = function(domChanges) {
-  for (let i = domChanges.length - 1; i >= 0; --i) {
-    const entry = domChanges[i];
-    switch (entry.type) {
-      case 'added':
-        entry.node.remove();
-        break;
-      case 'changed':
-        entry.node.textContent = entry.oldText;
-        break;
-    }
-  }
-};
-
-/**
- * @param {!Element} element
- * @param {?Element=} containerElement
- * @return {!UI.Size}
- */
-UI.measurePreferredSize = function(element, containerElement) {
-  const oldParent = element.parentElement;
-  const oldNextSibling = element.nextSibling;
-  containerElement = containerElement || element.ownerDocument.body;
-  containerElement.appendChild(element);
-  element.positionAt(0, 0);
-  const result = element.getBoundingClientRect();
-
-  element.positionAt(undefined, undefined);
-  if (oldParent)
-    oldParent.insertBefore(element, oldNextSibling);
-  else
-    element.remove();
-  return new UI.Size(result.width, result.height);
-};
-
-/**
- * @unrestricted
- */
-UI.InvokeOnceHandlers = class {
-  /**
-   * @param {boolean} autoInvoke
-   */
-  constructor(autoInvoke) {
-    this._handlers = null;
-    this._autoInvoke = autoInvoke;
-  }
-
-  /**
-   * @param {!Object} object
-   * @param {function()} method
-   */
-  add(object, method) {
-    if (!this._handlers) {
-      this._handlers = new Map();
-      if (this._autoInvoke)
-        this.scheduleInvoke();
-    }
-    let methods = this._handlers.get(object);
-    if (!methods) {
-      methods = new Set();
-      this._handlers.set(object, methods);
-    }
-    methods.add(method);
-  }
-
-  /**
-   * @suppressGlobalPropertiesCheck
-   */
-  scheduleInvoke() {
-    if (this._handlers)
-      requestAnimationFrame(this._invoke.bind(this));
-  }
-
-  _invoke() {
-    const handlers = this._handlers;
-    this._handlers = null;
-    const keys = handlers.keysArray();
-    for (let i = 0; i < keys.length; ++i) {
-      const object = keys[i];
-      const methods = handlers.get(object).valuesArray();
-      for (let j = 0; j < methods.length; ++j)
-        methods[j].call(object);
-    }
-  }
-};
-
-UI._coalescingLevel = 0;
-UI._postUpdateHandlers = null;
-
-UI.startBatchUpdate = function() {
-  if (!UI._coalescingLevel++)
-    UI._postUpdateHandlers = new UI.InvokeOnceHandlers(false);
-};
-
-UI.endBatchUpdate = function() {
-  if (--UI._coalescingLevel)
-    return;
-  UI._postUpdateHandlers.scheduleInvoke();
-  UI._postUpdateHandlers = null;
-};
-
-/**
- * @param {!Object} object
- * @param {function()} method
- */
-UI.invokeOnceAfterBatchUpdate = function(object, method) {
-  if (!UI._postUpdateHandlers)
-    UI._postUpdateHandlers = new UI.InvokeOnceHandlers(true);
-  UI._postUpdateHandlers.add(object, method);
-};
-
-/**
- * @param {!Window} window
- * @param {!Function} func
- * @param {!Array.<{from:number, to:number}>} params
- * @param {number} duration
- * @param {function()=} animationComplete
- * @return {function()}
- */
-UI.animateFunction = function(window, func, params, duration, animationComplete) {
-  const start = window.performance.now();
-  let raf = window.requestAnimationFrame(animationStep);
-
-  function animationStep(timestamp) {
-    const progress = Number.constrain((timestamp - start) / duration, 0, 1);
-    func(...params.map(p => p.from + (p.to - p.from) * progress));
-    if (progress < 1)
-      raf = window.requestAnimationFrame(animationStep);
-    else if (animationComplete)
-      animationComplete();
-  }
-
-  return () => window.cancelAnimationFrame(raf);
-};
-
-/**
- * @unrestricted
- */
-UI.LongClickController = class extends Common.Object {
-  /**
-   * @param {!Element} element
-   * @param {function(!Event)} callback
-   */
-  constructor(element, callback) {
-    super();
-    this._element = element;
-    this._callback = callback;
-    this._enable();
-  }
-
-  reset() {
-    if (this._longClickInterval) {
-      clearInterval(this._longClickInterval);
-      delete this._longClickInterval;
-    }
-  }
-
-  _enable() {
-    if (this._longClickData)
-      return;
-    const boundMouseDown = mouseDown.bind(this);
-    const boundMouseUp = mouseUp.bind(this);
-    const boundReset = this.reset.bind(this);
-
-    this._element.addEventListener('mousedown', boundMouseDown, false);
-    this._element.addEventListener('mouseout', boundReset, false);
-    this._element.addEventListener('mouseup', boundMouseUp, false);
-    this._element.addEventListener('click', boundReset, true);
-
-    this._longClickData = {mouseUp: boundMouseUp, mouseDown: boundMouseDown, reset: boundReset};
-
-    /**
-     * @param {!Event} e
-     * @this {UI.LongClickController}
-     */
-    function mouseDown(e) {
-      if (e.which !== 1)
-        return;
-      const callback = this._callback;
-      this._longClickInterval = setTimeout(callback.bind(null, e), 200);
-    }
-
-    /**
-     * @param {!Event} e
-     * @this {UI.LongClickController}
-     */
-    function mouseUp(e) {
-      if (e.which !== 1)
-        return;
-      this.reset();
-    }
-  }
-
-  dispose() {
-    if (!this._longClickData)
-      return;
-    this._element.removeEventListener('mousedown', this._longClickData.mouseDown, false);
-    this._element.removeEventListener('mouseout', this._longClickData.reset, false);
-    this._element.removeEventListener('mouseup', this._longClickData.mouseUp, false);
-    this._element.addEventListener('click', this._longClickData.reset, true);
-    delete this._longClickData;
-  }
-};
-
-/**
- * @param {!Document} document
- * @param {!Common.Setting} themeSetting
- */
-UI.initializeUIUtils = function(document, themeSetting) {
-  document.body.classList.toggle('inactive', !document.hasFocus());
-  document.defaultView.addEventListener('focus', UI._windowFocused.bind(UI, document), false);
-  document.defaultView.addEventListener('blur', UI._windowBlurred.bind(UI, document), false);
-  document.addEventListener('focus', UI._focusChanged.bind(UI), true);
-  document.addEventListener('keydown', event => {
-    UI._keyboardFocus = true;
-    document.defaultView.requestAnimationFrame(() => void(UI._keyboardFocus = false));
-  }, true);
-
-  if (!UI.themeSupport)
-    UI.themeSupport = new UI.ThemeSupport(themeSetting);
-  UI.themeSupport.applyTheme(document);
-
-  const body = /** @type {!Element} */ (document.body);
-  UI.appendStyle(body, 'ui/inspectorStyle.css');
-  UI.GlassPane.setContainer(/** @type {!Element} */ (document.body));
-};
-
-/**
- * @param {string} name
- * @return {string}
- */
-UI.beautifyFunctionName = function(name) {
-  return name || Common.UIString('(anonymous)');
-};
-
-/**
- * @param {string} localName
- * @param {string} typeExtension
- * @param {!Object} prototype
- * @return {function()}
- * @suppressGlobalPropertiesCheck
- * @template T
- */
-UI.registerCustomElement = function(localName, typeExtension, prototype) {
-  return document.registerElement(typeExtension, {prototype: Object.create(prototype), extends: localName});
-};
-
-/**
- * @param {string} text
- * @param {function(!Event)=} clickHandler
- * @param {string=} className
- * @param {boolean=} primary
- * @return {!Element}
- */
-UI.createTextButton = function(text, clickHandler, className, primary) {
-  const element = createElementWithClass('button', className || '', 'text-button');
-  element.textContent = text;
-  if (primary)
-    element.classList.add('primary-button');
-  if (clickHandler)
-    element.addEventListener('click', clickHandler, false);
-  return element;
-};
-
-/**
- * @param {string=} className
- * @param {string=} type
- * @return {!Element}
- */
-UI.createInput = function(className, type) {
-  const element = createElementWithClass('input', className || '');
-  element.spellcheck = false;
-  element.classList.add('harmony-input');
-  if (type)
-    element.type = type;
-  return element;
-};
-
-/**
- * @param {string} name
- * @param {string} title
- * @param {boolean=} checked
- * @return {!Element}
- */
-UI.createRadioLabel = function(name, title, checked) {
-  const element = createElement('label', 'dt-radio');
-  element.radioElement.name = name;
-  element.radioElement.checked = !!checked;
-  element.createTextChild(title);
-  return element;
-};
-
-/**
- * @param {string} title
- * @param {string} iconClass
- * @return {!Element}
- */
-UI.createLabel = function(title, iconClass) {
-  const element = createElement('label', 'dt-icon-label');
-  element.createChild('span').textContent = title;
-  element.type = iconClass;
-  return element;
-};
-
-/**
- * @return {!Element}
- * @param {number} min
- * @param {number} max
- * @param {number} tabIndex
- */
-UI.createSliderLabel = function(min, max, tabIndex) {
-  const element = createElement('label', 'dt-slider');
-  element.sliderElement.min = min;
-  element.sliderElement.max = max;
-  element.sliderElement.step = 1;
-  element.sliderElement.tabIndex = tabIndex;
-  return element;
-};
-
-/**
- * @param {!Node} node
- * @param {string} cssFile
- * @suppressGlobalPropertiesCheck
- */
-UI.appendStyle = function(node, cssFile) {
-  const content = Runtime.cachedResources[cssFile] || '';
-  if (!content)
-    console.error(cssFile + ' not preloaded. Check module.json');
-  let styleElement = createElement('style');
-  styleElement.type = 'text/css';
-  styleElement.textContent = content;
-  node.appendChild(styleElement);
-
-  const themeStyleSheet = UI.themeSupport.themeStyleSheet(cssFile, content);
-  if (themeStyleSheet) {
-    styleElement = createElement('style');
-    styleElement.type = 'text/css';
-    styleElement.textContent = themeStyleSheet + '\n' + Runtime.resolveSourceURL(cssFile + '.theme');
-    node.appendChild(styleElement);
-  }
-};
-
-/**
- * @extends {HTMLLabelElement}
- */
-UI.CheckboxLabel = class extends HTMLLabelElement {
-  constructor() {
-    super();
-    /** @type {!DocumentFragment} */
-    this._shadowRoot;
-    /** @type {!HTMLInputElement} */
-    this.checkboxElement;
-    /** @type {!Element} */
-    this.textElement;
-    throw new Error('Checkbox must be created via factory method.');
-  }
-
-  /**
-   * @override
-   */
-  createdCallback() {
-    UI.CheckboxLabel._lastId = (UI.CheckboxLabel._lastId || 0) + 1;
-    const id = 'ui-checkbox-label' + UI.CheckboxLabel._lastId;
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this, 'ui/checkboxTextLabel.css');
-    this.checkboxElement = /** @type {!HTMLInputElement} */ (this._shadowRoot.createChild('input'));
-    this.checkboxElement.type = 'checkbox';
-    this.checkboxElement.setAttribute('id', id);
-    this.textElement = this._shadowRoot.createChild('label', 'dt-checkbox-text');
-    this.textElement.setAttribute('for', id);
-    this._shadowRoot.createChild('content');
-  }
-
-  /**
-   * @param {string=} title
-   * @param {boolean=} checked
-   * @param {string=} subtitle
-   * @return {!UI.CheckboxLabel}
-   */
-  static create(title, checked, subtitle) {
-    if (!UI.CheckboxLabel._constructor)
-      UI.CheckboxLabel._constructor = UI.registerCustomElement('label', 'dt-checkbox', UI.CheckboxLabel.prototype);
-    const element = /** @type {!UI.CheckboxLabel} */ (new UI.CheckboxLabel._constructor());
-    element.checkboxElement.checked = !!checked;
-    if (title !== undefined) {
-      element.textElement.textContent = title;
-      if (subtitle !== undefined)
-        element.textElement.createChild('div', 'dt-checkbox-subtitle').textContent = subtitle;
-    }
-    return element;
-  }
-
-  /**
-   * @param {string} color
-   * @this {Element}
-   */
-  set backgroundColor(color) {
-    this.checkboxElement.classList.add('dt-checkbox-themed');
-    this.checkboxElement.style.backgroundColor = color;
-  }
-
-  /**
-   * @param {string} color
-   * @this {Element}
-   */
-  set checkColor(color) {
-    this.checkboxElement.classList.add('dt-checkbox-themed');
-    const stylesheet = createElement('style');
-    stylesheet.textContent = 'input.dt-checkbox-themed:checked:after { background-color: ' + color + '}';
-    this._shadowRoot.appendChild(stylesheet);
-  }
-
-  /**
-   * @param {string} color
-   * @this {Element}
-   */
-  set borderColor(color) {
-    this.checkboxElement.classList.add('dt-checkbox-themed');
-    this.checkboxElement.style.borderColor = color;
-  }
-};
-
-(function() {
-  UI.registerCustomElement('button', 'text-button', {
-    /**
-     * @this {Element}
-     */
-    createdCallback: function() {
-      this.type = 'button';
-      const root = UI.createShadowRootWithCoreStyles(this, 'ui/textButton.css');
-      root.createChild('content');
-    },
-
-    __proto__: HTMLButtonElement.prototype
-  });
-
-  UI.registerCustomElement('label', 'dt-radio', {
-    /**
-     * @this {Element}
-     */
-    createdCallback: function() {
-      this.radioElement = this.createChild('input', 'dt-radio-button');
-      this.radioElement.type = 'radio';
-      const root = UI.createShadowRootWithCoreStyles(this, 'ui/radioButton.css');
-      root.createChild('content').select = '.dt-radio-button';
-      root.createChild('content');
-      this.addEventListener('click', radioClickHandler, false);
-    },
-
-    __proto__: HTMLLabelElement.prototype
-  });
-
-  /**
-   * @param {!Event} event
-   * @suppressReceiverCheck
-   * @this {Element}
-   */
-  function radioClickHandler(event) {
-    if (this.radioElement.checked || this.radioElement.disabled)
-      return;
-    this.radioElement.checked = true;
-    this.radioElement.dispatchEvent(new Event('change'));
-  }
-
-  UI.registerCustomElement('label', 'dt-icon-label', {
-    /**
-     * @this {Element}
-     */
-    createdCallback: function() {
-      const root = UI.createShadowRootWithCoreStyles(this);
-      this._iconElement = UI.Icon.create();
-      this._iconElement.style.setProperty('margin-right', '4px');
-      root.appendChild(this._iconElement);
-      root.createChild('content');
-    },
-
-    /**
-     * @param {string} type
-     * @this {Element}
-     */
-    set type(type) {
-      this._iconElement.setIconType(type);
-    },
-
-    __proto__: HTMLLabelElement.prototype
-  });
-
-  UI.registerCustomElement('label', 'dt-slider', {
-    /**
-     * @this {Element}
-     */
-    createdCallback: function() {
-      const root = UI.createShadowRootWithCoreStyles(this, 'ui/slider.css');
-      this.sliderElement = createElementWithClass('input', 'dt-range-input');
-      this.sliderElement.type = 'range';
-      root.appendChild(this.sliderElement);
-    },
-
-    /**
-     * @param {number} amount
-     * @this {Element}
-     */
-    set value(amount) {
-      this.sliderElement.value = amount;
-    },
-
-    /**
-     * @this {Element}
-     */
-    get value() {
-      return this.sliderElement.value;
-    },
-
-    __proto__: HTMLLabelElement.prototype
-  });
-
-  UI.registerCustomElement('label', 'dt-small-bubble', {
-    /**
-     * @this {Element}
-     */
-    createdCallback: function() {
-      const root = UI.createShadowRootWithCoreStyles(this, 'ui/smallBubble.css');
-      this._textElement = root.createChild('div');
-      this._textElement.className = 'info';
-      this._textElement.createChild('content');
-    },
-
-    /**
-     * @param {string} type
-     * @this {Element}
-     */
-    set type(type) {
-      this._textElement.className = type;
-    },
-
-    __proto__: HTMLLabelElement.prototype
-  });
-
-  UI.registerCustomElement('div', 'dt-close-button', {
-    /**
-     * @this {Element}
-     */
-    createdCallback: function() {
-      const root = UI.createShadowRootWithCoreStyles(this, 'ui/closeButton.css');
-      this._buttonElement = root.createChild('div', 'close-button');
-      const regularIcon = UI.Icon.create('smallicon-cross', 'default-icon');
-      this._hoverIcon = UI.Icon.create('mediumicon-red-cross-hover', 'hover-icon');
-      this._activeIcon = UI.Icon.create('mediumicon-red-cross-active', 'active-icon');
-      this._buttonElement.appendChild(regularIcon);
-      this._buttonElement.appendChild(this._hoverIcon);
-      this._buttonElement.appendChild(this._activeIcon);
-    },
-
-    /**
-     * @param {boolean} gray
-     * @this {Element}
-     */
-    set gray(gray) {
-      if (gray) {
-        this._hoverIcon.setIconType('mediumicon-gray-cross-hover');
-        this._activeIcon.setIconType('mediumicon-gray-cross-active');
-      } else {
-        this._hoverIcon.setIconType('mediumicon-red-cross-hover');
-        this._activeIcon.setIconType('mediumicon-red-cross-active');
-      }
-    },
-
-    __proto__: HTMLDivElement.prototype
-  });
-})();
-
-/**
- * @param {!Element} input
- * @param {function(string)} apply
- * @param {function(string):boolean} validate
- * @param {boolean} numeric
- * @param {number=} modifierMultiplier
- * @return {function(string)}
- */
-UI.bindInput = function(input, apply, validate, numeric, modifierMultiplier) {
-  input.addEventListener('change', onChange, false);
-  input.addEventListener('input', onInput, false);
-  input.addEventListener('keydown', onKeyDown, false);
-  input.addEventListener('focus', input.select.bind(input), false);
-
-  function onInput() {
-    input.classList.toggle('error-input', !validate(input.value));
-  }
-
-  function onChange() {
-    const valid = validate(input.value);
-    input.classList.toggle('error-input', !valid);
-    if (valid)
-      apply(input.value);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  function onKeyDown(event) {
-    if (isEnterKey(event)) {
-      if (validate(input.value))
-        apply(input.value);
-      event.preventDefault();
-      return;
-    }
-
-    if (!numeric)
-      return;
-
-    const value = UI._modifiedFloatNumber(parseFloat(input.value), event, modifierMultiplier);
-    const stringValue = value ? String(value) : '';
-    if (!validate(stringValue) || !value)
-      return;
-
-    input.value = stringValue;
-    apply(input.value);
-    event.preventDefault();
-  }
-
-  /**
-   * @param {string} value
-   */
-  function setValue(value) {
-    if (value === input.value)
-      return;
-    const valid = validate(value);
-    input.classList.toggle('error-input', !valid);
-    input.value = value;
-  }
-
-  return setValue;
-};
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {string} text
- * @param {number} maxWidth
- * @param {function(string, number):string} trimFunction
- * @return {string}
- */
-UI.trimText = function(context, text, maxWidth, trimFunction) {
-  const maxLength = 200;
-  if (maxWidth <= 10)
-    return '';
-  if (text.length > maxLength)
-    text = trimFunction(text, maxLength);
-  const textWidth = UI.measureTextWidth(context, text);
-  if (textWidth <= maxWidth)
-    return text;
-
-  let l = 0;
-  let r = text.length;
-  let lv = 0;
-  let rv = textWidth;
-  while (l < r && lv !== rv && lv !== maxWidth) {
-    const m = Math.ceil(l + (r - l) * (maxWidth - lv) / (rv - lv));
-    const mv = UI.measureTextWidth(context, trimFunction(text, m));
-    if (mv <= maxWidth) {
-      l = m;
-      lv = mv;
-    } else {
-      r = m - 1;
-      rv = mv;
-    }
-  }
-  text = trimFunction(text, l);
-  return text !== '\u2026' ? text : '';
-};
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {string} text
- * @param {number} maxWidth
- * @return {string}
- */
-UI.trimTextMiddle = function(context, text, maxWidth) {
-  return UI.trimText(context, text, maxWidth, (text, width) => text.trimMiddle(width));
-};
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {string} text
- * @param {number} maxWidth
- * @return {string}
- */
-UI.trimTextEnd = function(context, text, maxWidth) {
-  return UI.trimText(context, text, maxWidth, (text, width) => text.trimEnd(width));
-};
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {string} text
- * @return {number}
- */
-UI.measureTextWidth = function(context, text) {
-  const maxCacheableLength = 200;
-  if (text.length > maxCacheableLength)
-    return context.measureText(text).width;
-
-  let widthCache = UI.measureTextWidth._textWidthCache;
-  if (!widthCache) {
-    widthCache = new Map();
-    UI.measureTextWidth._textWidthCache = widthCache;
-  }
-  const font = context.font;
-  let textWidths = widthCache.get(font);
-  if (!textWidths) {
-    textWidths = new Map();
-    widthCache.set(font, textWidths);
-  }
-  let width = textWidths.get(text);
-  if (!width) {
-    width = context.measureText(text).width;
-    textWidths.set(text, width);
-  }
-  return width;
-};
-
-/**
- * @unrestricted
- */
-UI.ThemeSupport = class {
-  /**
-   * @param {!Common.Setting} setting
-   */
-  constructor(setting) {
-    this._themeName = setting.get() || 'default';
-    this._themableProperties = new Set([
-      'color', 'box-shadow', 'text-shadow', 'outline-color', 'background-image', 'background-color',
-      'border-left-color', 'border-right-color', 'border-top-color', 'border-bottom-color', '-webkit-border-image'
-    ]);
-    /** @type {!Map<string, string>} */
-    this._cachedThemePatches = new Map();
-    this._setting = setting;
-    this._customSheets = new Set();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasTheme() {
-    return this._themeName !== 'default';
-  }
-
-  /**
-   * @return {string}
-   */
-  themeName() {
-    return this._themeName;
-  }
-
-  /**
-   * @param {!Element} element
-   */
-  injectHighlightStyleSheets(element) {
-    this._injectingStyleSheet = true;
-    UI.appendStyle(element, 'ui/inspectorSyntaxHighlight.css');
-    if (this._themeName === 'dark')
-      UI.appendStyle(element, 'ui/inspectorSyntaxHighlightDark.css');
-    this._injectingStyleSheet = false;
-  }
-
-   /**
-   * @param {!Element|!ShadowRoot} element
-   */
-  injectCustomStyleSheets(element) {
-    for (const sheet of this._customSheets){
-      const styleElement = createElement('style');
-      styleElement.type = 'text/css';
-      styleElement.textContent = sheet;
-      element.appendChild(styleElement);
-    }
-  }
-
-  /**
-   * @param {string} sheetText
-   */
-  addCustomStylesheet(sheetText) {
-    this._customSheets.add(sheetText);
-  }
-
-  /**
-   * @param {!Document} document
-   */
-  applyTheme(document) {
-    if (!this.hasTheme())
-      return;
-
-    if (this._themeName === 'dark')
-      document.documentElement.classList.add('-theme-with-dark-background');
-
-    const styleSheets = document.styleSheets;
-    const result = [];
-    for (let i = 0; i < styleSheets.length; ++i)
-      result.push(this._patchForTheme(styleSheets[i].href, styleSheets[i]));
-    result.push('/*# sourceURL=inspector.css.theme */');
-
-    const styleElement = createElement('style');
-    styleElement.type = 'text/css';
-    styleElement.textContent = result.join('\n');
-    document.head.appendChild(styleElement);
-  }
-
-  /**
-   * @param {string} id
-   * @param {string} text
-   * @return {string}
-   * @suppressGlobalPropertiesCheck
-   */
-  themeStyleSheet(id, text) {
-    if (!this.hasTheme() || this._injectingStyleSheet)
-      return '';
-
-    let patch = this._cachedThemePatches.get(id);
-    if (!patch) {
-      const styleElement = createElement('style');
-      styleElement.type = 'text/css';
-      styleElement.textContent = text;
-      document.body.appendChild(styleElement);
-      patch = this._patchForTheme(id, styleElement.sheet);
-      document.body.removeChild(styleElement);
-    }
-    return patch;
-  }
-
-  /**
-   * @param {string} id
-   * @param {!StyleSheet} styleSheet
-   * @return {string}
-   */
-  _patchForTheme(id, styleSheet) {
-    const cached = this._cachedThemePatches.get(id);
-    if (cached)
-      return cached;
-
-    try {
-      const rules = styleSheet.cssRules;
-      const result = [];
-      for (let j = 0; j < rules.length; ++j) {
-        if (rules[j] instanceof CSSImportRule) {
-          result.push(this._patchForTheme(rules[j].styleSheet.href, rules[j].styleSheet));
-          continue;
-        }
-        const output = [];
-        const style = rules[j].style;
-        const selectorText = rules[j].selectorText;
-        for (let i = 0; style && i < style.length; ++i)
-          this._patchProperty(selectorText, style, style[i], output);
-        if (output.length)
-          result.push(rules[j].selectorText + '{' + output.join('') + '}');
-      }
-
-      const fullText = result.join('\n');
-      this._cachedThemePatches.set(id, fullText);
-      return fullText;
-    } catch (e) {
-      this._setting.set('default');
-      return '';
-    }
-  }
-
-  /**
-   * @param {string} selectorText
-   * @param {!CSSStyleDeclaration} style
-   * @param {string} name
-   * @param {!Array<string>} output
-   *
-   * Theming API is primarily targeted at making dark theme look good.
-   * - If rule has ".-theme-preserve" in selector, it won't be affected.
-   * - One can create specializations for dark themes via body.-theme-with-dark-background selector in host context.
-   */
-  _patchProperty(selectorText, style, name, output) {
-    if (!this._themableProperties.has(name))
-      return;
-
-    const value = style.getPropertyValue(name);
-    if (!value || value === 'none' || value === 'inherit' || value === 'initial' || value === 'transparent')
-      return;
-    if (name === 'background-image' && value.indexOf('gradient') === -1)
-      return;
-
-    if (selectorText.indexOf('-theme-') !== -1)
-      return;
-
-    let colorUsage = UI.ThemeSupport.ColorUsage.Unknown;
-    if (name.indexOf('background') === 0 || name.indexOf('border') === 0)
-      colorUsage |= UI.ThemeSupport.ColorUsage.Background;
-    if (name.indexOf('background') === -1)
-      colorUsage |= UI.ThemeSupport.ColorUsage.Foreground;
-
-    output.push(name);
-    output.push(':');
-    const items = value.replace(Common.Color.Regex, '\0$1\0').split('\0');
-    for (let i = 0; i < items.length; ++i)
-      output.push(this.patchColorText(items[i], colorUsage));
-    if (style.getPropertyPriority(name))
-      output.push(' !important');
-    output.push(';');
-  }
-
-  /**
-   * @param {string} text
-   * @param {!UI.ThemeSupport.ColorUsage} colorUsage
-   * @return {string}
-   */
-  patchColorText(text, colorUsage) {
-    const color = Common.Color.parse(text);
-    if (!color)
-      return text;
-    const outColor = this.patchColor(color, colorUsage);
-    let outText = outColor.asString(null);
-    if (!outText)
-      outText = outColor.asString(outColor.hasAlpha() ? Common.Color.Format.RGBA : Common.Color.Format.RGB);
-    return outText || text;
-  }
-
-  /**
-   * @param {!Common.Color} color
-   * @param {!UI.ThemeSupport.ColorUsage} colorUsage
-   * @return {!Common.Color}
-   */
-  patchColor(color, colorUsage) {
-    const hsla = color.hsla();
-    this._patchHSLA(hsla, colorUsage);
-    const rgba = [];
-    Common.Color.hsl2rgb(hsla, rgba);
-    return new Common.Color(rgba, color.format());
-  }
-
-  /**
-   * @param {!Array<number>} hsla
-   * @param {!UI.ThemeSupport.ColorUsage} colorUsage
-   */
-  _patchHSLA(hsla, colorUsage) {
-    const hue = hsla[0];
-    const sat = hsla[1];
-    let lit = hsla[2];
-    const alpha = hsla[3];
-
-    switch (this._themeName) {
-      case 'dark':
-        const minCap = colorUsage & UI.ThemeSupport.ColorUsage.Background ? 0.14 : 0;
-        const maxCap = colorUsage & UI.ThemeSupport.ColorUsage.Foreground ? 0.9 : 1;
-        lit = 1 - lit;
-        if (lit < minCap * 2)
-          lit = minCap + lit / 2;
-        else if (lit > 2 * maxCap - 1)
-          lit = maxCap - 1 / 2 + lit / 2;
-
-        break;
-    }
-    hsla[0] = Number.constrain(hue, 0, 1);
-    hsla[1] = Number.constrain(sat, 0, 1);
-    hsla[2] = Number.constrain(lit, 0, 1);
-    hsla[3] = Number.constrain(alpha, 0, 1);
-  }
-};
-
-/**
- * @enum {number}
- */
-UI.ThemeSupport.ColorUsage = {
-  Unknown: 0,
-  Foreground: 1 << 0,
-  Background: 1 << 1,
-};
-
-/**
- * @param {string} article
- * @param {string} title
- * @return {!Element}
- */
-UI.createDocumentationLink = function(article, title) {
-  return UI.XLink.create('https://developers.google.com/web/tools/chrome-devtools/' + article, title);
-};
-
-/**
- * @param {string} url
- * @return {!Promise<?Image>}
- */
-UI.loadImage = function(url) {
-  return new Promise(fulfill => {
-    const image = new Image();
-    image.addEventListener('load', () => fulfill(image));
-    image.addEventListener('error', () => fulfill(null));
-    image.src = url;
-  });
-};
-
-/**
- * @param {?string} data
- * @return {!Promise<?Image>}
- */
-UI.loadImageFromData = function(data) {
-  return data ? UI.loadImage('data:image/jpg;base64,' + data) : Promise.resolve(null);
-};
-
-/** @type {!UI.ThemeSupport} */
-UI.themeSupport;
-
-/**
- * @param {function(!File)} callback
- * @return {!Node}
- */
-UI.createFileSelectorElement = function(callback) {
-  const fileSelectorElement = createElement('input');
-  fileSelectorElement.type = 'file';
-  fileSelectorElement.style.display = 'none';
-  fileSelectorElement.setAttribute('tabindex', -1);
-  fileSelectorElement.onchange = onChange;
-  function onChange(event) {
-    callback(fileSelectorElement.files[0]);
-  }
-  return fileSelectorElement;
-};
-
-/**
- * @const
- * @type {number}
- */
-UI.MaxLengthForDisplayedURLs = 150;
-
-UI.MessageDialog = class {
-  /**
-   * @param {string} message
-   * @param {!Document|!Element=} where
-   * @return {!Promise}
-   */
-  static async show(message, where) {
-    const dialog = new UI.Dialog();
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.setDimmed(true);
-    const shadowRoot = UI.createShadowRootWithCoreStyles(dialog.contentElement, 'ui/confirmDialog.css');
-    const content = shadowRoot.createChild('div', 'widget');
-    await new Promise(resolve => {
-      const okButton = UI.createTextButton(Common.UIString('OK'), resolve, '', true);
-      content.createChild('div', 'message').createChild('span').textContent = message;
-      content.createChild('div', 'button').appendChild(okButton);
-      dialog.setOutsideClickCallback(event => {
-        event.consume();
-        resolve();
-      });
-      dialog.show(where);
-      okButton.focus();
-    });
-    dialog.hide();
-  }
-};
-
-UI.ConfirmDialog = class {
-  /**
-   * @param {string} message
-   * @param {!Document|!Element=} where
-   * @return {!Promise<boolean>}
-   */
-  static async show(message, where) {
-    const dialog = new UI.Dialog();
-    dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
-    dialog.setDimmed(true);
-    const shadowRoot = UI.createShadowRootWithCoreStyles(dialog.contentElement, 'ui/confirmDialog.css');
-    const content = shadowRoot.createChild('div', 'widget');
-    content.createChild('div', 'message').createChild('span').textContent = message;
-    const buttonsBar = content.createChild('div', 'button');
-    const result = await new Promise(resolve => {
-      buttonsBar.appendChild(UI.createTextButton(Common.UIString('OK'), () => resolve(true), '', true));
-      buttonsBar.appendChild(UI.createTextButton(Common.UIString('Cancel'), () => resolve(false)));
-      dialog.setOutsideClickCallback(event => {
-        event.consume();
-        resolve(false);
-      });
-      dialog.show(where);
-    });
-    dialog.hide();
-    return result;
-  }
-};
-
-/**
- * @param {!UI.ToolbarToggle} toolbarButton
- * @return {!Element}
- */
-UI.createInlineButton = function(toolbarButton) {
-  const element = createElement('span');
-  const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'ui/inlineButton.css');
-  element.classList.add('inline-button');
-  const toolbar = new UI.Toolbar('');
-  toolbar.appendToolbarItem(toolbarButton);
-  shadowRoot.appendChild(toolbar.element);
-  return element;
-};
diff --git a/front_end/ui/View.js b/front_end/ui/View.js
deleted file mode 100644
index bc3d3be..0000000
--- a/front_end/ui/View.js
+++ /dev/null
@@ -1,922 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @interface
- */
-UI.View = function() {};
-
-UI.View.prototype = {
-  /**
-   * @return {string}
-   */
-  viewId() {},
-
-  /**
-   * @return {string}
-   */
-  title() {},
-
-  /**
-   * @return {boolean}
-   */
-  isCloseable() {},
-
-  /**
-   * @return {boolean}
-   */
-  isTransient() {},
-
-  /**
-   * @return {!Promise<!Array<!UI.ToolbarItem>>}
-   */
-  toolbarItems() {},
-
-  /**
-   * @return {!Promise<!UI.Widget>}
-   */
-  widget() {},
-
-  disposeView() {}
-};
-
-UI.View._symbol = Symbol('view');
-UI.View._widgetSymbol = Symbol('widget');
-
-/**
- * @implements {UI.View}
- * @unrestricted
- */
-UI.SimpleView = class extends UI.VBox {
-  /**
-   * @param {string} title
-   * @param {boolean=} isWebComponent
-   */
-  constructor(title, isWebComponent) {
-    super(isWebComponent);
-    this._title = title;
-    /** @type {!Array<!UI.ToolbarItem>} */
-    this._toolbarItems = [];
-    this[UI.View._symbol] = this;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  viewId() {
-    return this._title;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  title() {
-    return this._title;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isCloseable() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isTransient() {
-    return false;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<!Array<!UI.ToolbarItem>>}
-   */
-  toolbarItems() {
-    return Promise.resolve(this.syncToolbarItems());
-  }
-
-  /**
-   * @return {!Array<!UI.ToolbarItem>}
-   */
-  syncToolbarItems() {
-    return this._toolbarItems;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<!UI.Widget>}
-   */
-  widget() {
-    return /** @type {!Promise<!UI.Widget>} */ (Promise.resolve(this));
-  }
-
-  /**
-   * @param {!UI.ToolbarItem} item
-   */
-  addToolbarItem(item) {
-    this._toolbarItems.push(item);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  revealView() {
-    return UI.viewManager.revealView(this);
-  }
-
-  /**
-   * @override
-   */
-  disposeView() {
-  }
-};
-
-/**
- * @implements {UI.View}
- * @unrestricted
- */
-UI.ProvidedView = class {
-  /**
-   * @param {!Runtime.Extension} extension
-   */
-  constructor(extension) {
-    this._extension = extension;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  viewId() {
-    return this._extension.descriptor()['id'];
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  title() {
-    return this._extension.title();
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isCloseable() {
-    return this._extension.descriptor()['persistence'] === 'closeable';
-  }
-
-  /**
-   * @override
-   * @return {boolean}
-   */
-  isTransient() {
-    return this._extension.descriptor()['persistence'] === 'transient';
-  }
-
-  /**
-   * @override
-   * @return {!Promise<!Array<!UI.ToolbarItem>>}
-   */
-  toolbarItems() {
-    const actionIds = this._extension.descriptor()['actionIds'];
-    if (actionIds) {
-      const result = actionIds.split(',').map(id => UI.Toolbar.createActionButtonForId(id.trim()));
-      return Promise.resolve(result);
-    }
-
-    if (this._extension.descriptor()['hasToolbar'])
-      return this.widget().then(widget => /** @type {!UI.ToolbarItem.ItemsProvider} */ (widget).toolbarItems());
-    return Promise.resolve([]);
-  }
-
-  /**
-   * @override
-   * @return {!Promise<!UI.Widget>}
-   */
-  async widget() {
-    this._widgetRequested = true;
-    const widget = await this._extension.instance();
-    if (!(widget instanceof UI.Widget))
-      throw new Error('view className should point to a UI.Widget');
-    widget[UI.View._symbol] = this;
-    return /** @type {!UI.Widget} */ (widget);
-  }
-
-  /**
-   * @override
-   */
-  async disposeView() {
-    if (!this._widgetRequested)
-      return;
-    const widget = await this.widget();
-    widget.ownerViewDisposed();
-  }
-};
-
-/**
- * @interface
- */
-UI.ViewLocation = function() {};
-
-UI.ViewLocation.prototype = {
-  /**
-   * @param {string} locationName
-   */
-  appendApplicableItems(locationName) {},
-
-  /**
-   * @param {!UI.View} view
-   * @param {?UI.View=} insertBefore
-   */
-  appendView(view, insertBefore) {},
-
-  /**
-   * @param {!UI.View} view
-   * @param {?UI.View=} insertBefore
-   * @param {boolean=} userGesture
-   * @return {!Promise}
-   */
-  showView(view, insertBefore, userGesture) {},
-
-  /**
-   * @param {!UI.View} view
-   */
-  removeView(view) {},
-
-  /**
-   * @return {!UI.Widget}
-   */
-  widget() {}
-};
-
-/**
- * @interface
- * @extends {UI.ViewLocation}
- */
-UI.TabbedViewLocation = function() {};
-
-UI.TabbedViewLocation.prototype = {
-  /**
-   * @return {!UI.TabbedPane}
-   */
-  tabbedPane() {},
-
-  enableMoreTabsButton() {}
-};
-
-/**
- * @interface
- */
-UI.ViewLocationResolver = function() {};
-
-UI.ViewLocationResolver.prototype = {
-  /**
-   * @param {string} location
-   * @return {?UI.ViewLocation}
-   */
-  resolveLocation(location) {}
-};
-
-/**
- * @unrestricted
- */
-UI.ViewManager = class {
-  constructor() {
-    /** @type {!Map<string, !UI.View>} */
-    this._views = new Map();
-    /** @type {!Map<string, string>} */
-    this._locationNameByViewId = new Map();
-
-    for (const extension of self.runtime.extensions('view')) {
-      const descriptor = extension.descriptor();
-      this._views.set(descriptor['id'], new UI.ProvidedView(extension));
-      this._locationNameByViewId.set(descriptor['id'], descriptor['location']);
-    }
-  }
-
-  /**
-   * @param {!Element} element
-   * @param {!Array<!UI.ToolbarItem>} toolbarItems
-   */
-  static _populateToolbar(element, toolbarItems) {
-    if (!toolbarItems.length)
-      return;
-    const toolbar = new UI.Toolbar('');
-    element.insertBefore(toolbar.element, element.firstChild);
-    for (const item of toolbarItems)
-      toolbar.appendToolbarItem(item);
-  }
-
-  /**
-   * @param {!UI.View} view
-   * @return {!Promise}
-   */
-  revealView(view) {
-    const location = /** @type {?UI.ViewManager._Location} */ (view[UI.ViewManager._Location.symbol]);
-    if (!location)
-      return Promise.resolve();
-    location._reveal();
-    return location.showView(view);
-  }
-
-  /**
-   * @param {string} viewId
-   * @return {?UI.View}
-   */
-  view(viewId) {
-    return this._views.get(viewId);
-  }
-
-  /**
-   * @param {string} viewId
-   * @return {?UI.Widget}
-   */
-  materializedWidget(viewId) {
-    const view = this.view(viewId);
-    return view ? view[UI.View._widgetSymbol] : null;
-  }
-
-  /**
-   * @param {string} viewId
-   * @param {boolean=} userGesture
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  showView(viewId, userGesture, omitFocus) {
-    const view = this._views.get(viewId);
-    if (!view) {
-      console.error('Could not find view for id: \'' + viewId + '\' ' + new Error().stack);
-      return Promise.resolve();
-    }
-
-    const locationName = this._locationNameByViewId.get(viewId);
-
-    const location = view[UI.ViewManager._Location.symbol];
-    if (location) {
-      location._reveal();
-      return location.showView(view, undefined, userGesture, omitFocus);
-    }
-
-    return this.resolveLocation(locationName).then(location => {
-      if (!location)
-        throw new Error('Could not resolve location for view: ' + viewId);
-      location._reveal();
-      return location.showView(view, undefined, userGesture, omitFocus);
-    });
-  }
-
-  /**
-   * @param {string=} location
-   * @return {!Promise<?UI.ViewManager._Location>}
-   */
-  resolveLocation(location) {
-    if (!location)
-      return /** @type {!Promise<?UI.ViewManager._Location>} */ (Promise.resolve(null));
-
-    const resolverExtensions = self.runtime.extensions(UI.ViewLocationResolver)
-                                   .filter(extension => extension.descriptor()['name'] === location);
-    if (!resolverExtensions.length)
-      throw new Error('Unresolved location: ' + location);
-    const resolverExtension = resolverExtensions[0];
-    return resolverExtension.instance().then(
-        resolver => /** @type {?UI.ViewManager._Location} */ (resolver.resolveLocation(location)));
-  }
-
-  /**
-   * @param {function()=} revealCallback
-   * @param {string=} location
-   * @param {boolean=} restoreSelection
-   * @param {boolean=} allowReorder
-   * @param {?string=} defaultTab
-   * @return {!UI.TabbedViewLocation}
-   */
-  createTabbedLocation(revealCallback, location, restoreSelection, allowReorder, defaultTab) {
-    return new UI.ViewManager._TabbedLocation(
-        this, revealCallback, location, restoreSelection, allowReorder, defaultTab);
-  }
-
-  /**
-   * @param {function()=} revealCallback
-   * @param {string=} location
-   * @return {!UI.ViewLocation}
-   */
-  createStackLocation(revealCallback, location) {
-    return new UI.ViewManager._StackLocation(this, revealCallback, location);
-  }
-
-  /**
-   * @param {string} location
-   * @return {boolean}
-   */
-  hasViewsForLocation(location) {
-    return !!this._viewsForLocation(location).length;
-  }
-
-  /**
-   * @param {string} location
-   * @return {!Array<!UI.View>}
-   */
-  _viewsForLocation(location) {
-    const result = [];
-    for (const id of this._views.keys()) {
-      if (this._locationNameByViewId.get(id) === location)
-        result.push(this._views.get(id));
-    }
-    return result;
-  }
-};
-
-
-/**
- * @unrestricted
- */
-UI.ViewManager._ContainerWidget = class extends UI.VBox {
-  /**
-   * @param {!UI.View} view
-   */
-  constructor(view) {
-    super();
-    this.element.classList.add('flex-auto', 'view-container', 'overflow-auto');
-    this._view = view;
-    this.element.tabIndex = -1;
-    this.setDefaultFocusedElement(this.element);
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _materialize() {
-    if (this._materializePromise)
-      return this._materializePromise;
-    const promises = [];
-    promises.push(this._view.toolbarItems().then(UI.ViewManager._populateToolbar.bind(UI.ViewManager, this.element)));
-    promises.push(this._view.widget().then(widget => {
-      // Move focus from |this| to loaded |widget| if any.
-      const shouldFocus = this.element.hasFocus();
-      this.setDefaultFocusedElement(null);
-      this._view[UI.View._widgetSymbol] = widget;
-      widget.show(this.element);
-      if (shouldFocus)
-        widget.focus();
-    }));
-    this._materializePromise = Promise.all(promises);
-    return this._materializePromise;
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    this._materialize().then(() => {
-      this._wasShownForTest();
-    });
-  }
-
-  _wasShownForTest() {
-    // This method is sniffed in tests.
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.ViewManager._ExpandableContainerWidget = class extends UI.VBox {
-  /**
-   * @param {!UI.View} view
-   */
-  constructor(view) {
-    super(true);
-    this.element.classList.add('flex-none');
-    this.registerRequiredCSS('ui/viewContainers.css');
-
-    this._titleElement = createElementWithClass('div', 'expandable-view-title');
-    UI.ARIAUtils.markAsLink(this._titleElement);
-    this._titleExpandIcon = UI.Icon.create('smallicon-triangle-right', 'title-expand-icon');
-    this._titleElement.appendChild(this._titleExpandIcon);
-    this._titleElement.createTextChild(view.title());
-    this._titleElement.tabIndex = 0;
-    this._titleElement.addEventListener('click', this._toggleExpanded.bind(this), false);
-    this._titleElement.addEventListener('keydown', this._onTitleKeyDown.bind(this), false);
-    this.contentElement.insertBefore(this._titleElement, this.contentElement.firstChild);
-
-    this.contentElement.createChild('content');
-    this._view = view;
-    view[UI.ViewManager._ExpandableContainerWidget._symbol] = this;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _materialize() {
-    if (this._materializePromise)
-      return this._materializePromise;
-    const promises = [];
-    promises.push(
-        this._view.toolbarItems().then(UI.ViewManager._populateToolbar.bind(UI.ViewManager, this._titleElement)));
-    promises.push(this._view.widget().then(widget => {
-      this._widget = widget;
-      this._view[UI.View._widgetSymbol] = widget;
-      widget.show(this.element);
-    }));
-    this._materializePromise = Promise.all(promises);
-    return this._materializePromise;
-  }
-
-  /**
-   * @return {!Promise}
-   */
-  _expand() {
-    if (this._titleElement.classList.contains('expanded'))
-      return this._materialize();
-    this._titleElement.classList.add('expanded');
-    UI.ARIAUtils.setExpanded(this._titleElement, true);
-    this._titleExpandIcon.setIconType('smallicon-triangle-down');
-    return this._materialize().then(() => this._widget.show(this.element));
-  }
-
-  _collapse() {
-    if (!this._titleElement.classList.contains('expanded'))
-      return;
-    this._titleElement.classList.remove('expanded');
-    UI.ARIAUtils.setExpanded(this._titleElement, false);
-    this._titleExpandIcon.setIconType('smallicon-triangle-right');
-    this._materialize().then(() => this._widget.detach());
-  }
-
-  _toggleExpanded() {
-    if (this._titleElement.classList.contains('expanded'))
-      this._collapse();
-    else
-      this._expand();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _onTitleKeyDown(event) {
-    if (isEnterKey(event) || event.keyCode === UI.KeyboardShortcut.Keys.Space.code) {
-      this._toggleExpanded();
-    } else if (event.key === 'ArrowLeft') {
-      this._collapse();
-    } else if (event.key === 'ArrowRight') {
-      if (!this._titleElement.classList.contains('expanded'))
-        this._expand();
-      else if (this._widget)
-        this._widget.focus();
-    }
-  }
-};
-
-UI.ViewManager._ExpandableContainerWidget._symbol = Symbol('container');
-
-/**
- * @unrestricted
- */
-UI.ViewManager._Location = class {
-  /**
-   * @param {!UI.ViewManager} manager
-   * @param {!UI.Widget} widget
-   * @param {function()=} revealCallback
-   */
-  constructor(manager, widget, revealCallback) {
-    this._manager = manager;
-    this._revealCallback = revealCallback;
-    this._widget = widget;
-  }
-
-  /**
-   * @return {!UI.Widget}
-   */
-  widget() {
-    return this._widget;
-  }
-
-  _reveal() {
-    if (this._revealCallback)
-      this._revealCallback();
-  }
-};
-
-UI.ViewManager._Location.symbol = Symbol('location');
-
-/**
- * @implements {UI.TabbedViewLocation}
- * @unrestricted
- */
-UI.ViewManager._TabbedLocation = class extends UI.ViewManager._Location {
-  /**
-   * @param {!UI.ViewManager} manager
-   * @param {function()=} revealCallback
-   * @param {string=} location
-   * @param {boolean=} restoreSelection
-   * @param {boolean=} allowReorder
-   * @param {?string=} defaultTab
-   */
-  constructor(manager, revealCallback, location, restoreSelection, allowReorder, defaultTab) {
-    const tabbedPane = new UI.TabbedPane();
-    if (allowReorder)
-      tabbedPane.setAllowTabReorder(true);
-
-    super(manager, tabbedPane, revealCallback);
-    this._tabbedPane = tabbedPane;
-    this._allowReorder = allowReorder;
-
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabClosed, this._tabClosed, this);
-    this._closeableTabSetting = Common.settings.createSetting(location + '-closeableTabs', {});
-    this._tabOrderSetting = Common.settings.createSetting(location + '-tabOrder', {});
-    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabOrderChanged, this._persistTabOrder, this);
-    if (restoreSelection)
-      this._lastSelectedTabSetting = Common.settings.createSetting(location + '-selectedTab', '');
-    this._defaultTab = defaultTab;
-
-    /** @type {!Map.<string, !UI.View>} */
-    this._views = new Map();
-
-    if (location)
-      this.appendApplicableItems(location);
-  }
-
-  /**
-   * @override
-   * @return {!UI.Widget}
-   */
-  widget() {
-    return this._tabbedPane;
-  }
-
-  /**
-   * @override
-   * @return {!UI.TabbedPane}
-   */
-  tabbedPane() {
-    return this._tabbedPane;
-  }
-
-  /**
-   * @override
-   */
-  enableMoreTabsButton() {
-    this._tabbedPane.leftToolbar().appendToolbarItem(new UI.ToolbarMenuButton(this._appendTabsToMenu.bind(this)));
-    this._tabbedPane.disableOverflowMenu();
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   */
-  appendApplicableItems(locationName) {
-    const views = this._manager._viewsForLocation(locationName);
-    if (this._allowReorder) {
-      let i = 0;
-      const persistedOrders = this._tabOrderSetting.get();
-      const orders = new Map();
-      for (const view of views)
-        orders.set(view.viewId(), persistedOrders[view.viewId()] || (++i) * UI.ViewManager._TabbedLocation.orderStep);
-      views.sort((a, b) => orders.get(a.viewId()) - orders.get(b.viewId()));
-    }
-
-    for (const view of views) {
-      const id = view.viewId();
-      this._views.set(id, view);
-      view[UI.ViewManager._Location.symbol] = this;
-      if (view.isTransient())
-        continue;
-      if (!view.isCloseable())
-        this._appendTab(view);
-      else if (this._closeableTabSetting.get()[id])
-        this._appendTab(view);
-    }
-    if (this._defaultTab && this._tabbedPane.hasTab(this._defaultTab))
-      this._tabbedPane.selectTab(this._defaultTab);
-    else if (this._lastSelectedTabSetting && this._tabbedPane.hasTab(this._lastSelectedTabSetting.get()))
-      this._tabbedPane.selectTab(this._lastSelectedTabSetting.get());
-  }
-
-  /**
-   * @param {!UI.ContextMenu} contextMenu
-   */
-  _appendTabsToMenu(contextMenu) {
-    const views = Array.from(this._views.values());
-    views.sort((viewa, viewb) => viewa.title().localeCompare(viewb.title()));
-    for (const view of views) {
-      const title = Common.UIString(view.title());
-      contextMenu.defaultSection().appendItem(title, this.showView.bind(this, view, undefined, true));
-    }
-  }
-
-  /**
-   * @param {!UI.View} view
-   * @param {number=} index
-   */
-  _appendTab(view, index) {
-    this._tabbedPane.appendTab(
-        view.viewId(), view.title(), new UI.ViewManager._ContainerWidget(view), undefined, false,
-        view.isCloseable() || view.isTransient(), index);
-  }
-
-  /**
-   * @override
-   * @param {!UI.View} view
-   * @param {?UI.View=} insertBefore
-   */
-  appendView(view, insertBefore) {
-    if (this._tabbedPane.hasTab(view.viewId()))
-      return;
-    const oldLocation = view[UI.ViewManager._Location.symbol];
-    if (oldLocation && oldLocation !== this)
-      oldLocation.removeView(view);
-    view[UI.ViewManager._Location.symbol] = this;
-    this._manager._views.set(view.viewId(), view);
-    this._views.set(view.viewId(), view);
-    let index = undefined;
-    const tabIds = this._tabbedPane.tabIds();
-    if (this._allowReorder) {
-      const orderSetting = this._tabOrderSetting.get();
-      const order = orderSetting[view.viewId()];
-      for (let i = 0; order && i < tabIds.length; ++i) {
-        if (orderSetting[tabIds[i]] && orderSetting[tabIds[i]] > order) {
-          index = i;
-          break;
-        }
-      }
-    } else if (insertBefore) {
-      for (let i = 0; i < tabIds.length; ++i) {
-        if (tabIds[i] === insertBefore.viewId()) {
-          index = i;
-          break;
-        }
-      }
-    }
-    this._appendTab(view, index);
-
-    if (view.isCloseable()) {
-      const tabs = this._closeableTabSetting.get();
-      const tabId = view.viewId();
-      if (!tabs[tabId]) {
-        tabs[tabId] = true;
-        this._closeableTabSetting.set(tabs);
-      }
-    }
-    this._persistTabOrder();
-  }
-
-  /**
-   * @override
-   * @param {!UI.View} view
-   * @param {?UI.View=} insertBefore
-   * @param {boolean=} userGesture
-   * @param {boolean=} omitFocus
-   * @return {!Promise}
-   */
-  showView(view, insertBefore, userGesture, omitFocus) {
-    this.appendView(view, insertBefore);
-    this._tabbedPane.selectTab(view.viewId(), userGesture);
-    if (!omitFocus)
-      this._tabbedPane.focus();
-    const widget = /** @type {!UI.ViewManager._ContainerWidget} */ (this._tabbedPane.tabView(view.viewId()));
-    return widget._materialize();
-  }
-
-  /**
-   * @param {!UI.View} view
-   * @override
-   */
-  removeView(view) {
-    if (!this._tabbedPane.hasTab(view.viewId()))
-      return;
-
-    delete view[UI.ViewManager._Location.symbol];
-    this._manager._views.delete(view.viewId());
-    this._tabbedPane.closeTab(view.viewId());
-    this._views.delete(view.viewId());
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabSelected(event) {
-    const tabId = /** @type {string} */ (event.data.tabId);
-    if (this._lastSelectedTabSetting && event.data['isUserGesture'])
-      this._lastSelectedTabSetting.set(tabId);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _tabClosed(event) {
-    const id = /** @type {string} */ (event.data['tabId']);
-    const tabs = this._closeableTabSetting.get();
-    if (tabs[id]) {
-      delete tabs[id];
-      this._closeableTabSetting.set(tabs);
-    }
-    this._views.get(id).disposeView();
-  }
-
-  _persistTabOrder() {
-    const tabIds = this._tabbedPane.tabIds();
-    const tabOrders = {};
-    for (let i = 0; i < tabIds.length; i++)
-      tabOrders[tabIds[i]] = (i + 1) * UI.ViewManager._TabbedLocation.orderStep;
-    this._tabOrderSetting.set(tabOrders);
-  }
-};
-
-UI.ViewManager._TabbedLocation.orderStep = 10;  // Keep in sync with descriptors.
-
-/**
- * @implements {UI.ViewLocation}
- * @unrestricted
- */
-UI.ViewManager._StackLocation = class extends UI.ViewManager._Location {
-  /**
-   * @param {!UI.ViewManager} manager
-   * @param {function()=} revealCallback
-   * @param {string=} location
-   */
-  constructor(manager, revealCallback, location) {
-    const vbox = new UI.VBox();
-    super(manager, vbox, revealCallback);
-    this._vbox = vbox;
-
-    /** @type {!Map<string, !UI.ViewManager._ExpandableContainerWidget>} */
-    this._expandableContainers = new Map();
-
-    if (location)
-      this.appendApplicableItems(location);
-  }
-
-  /**
-   * @override
-   * @param {!UI.View} view
-   * @param {?UI.View=} insertBefore
-   */
-  appendView(view, insertBefore) {
-    const oldLocation = view[UI.ViewManager._Location.symbol];
-    if (oldLocation && oldLocation !== this)
-      oldLocation.removeView(view);
-
-    let container = this._expandableContainers.get(view.viewId());
-    if (!container) {
-      view[UI.ViewManager._Location.symbol] = this;
-      this._manager._views.set(view.viewId(), view);
-      container = new UI.ViewManager._ExpandableContainerWidget(view);
-      let beforeElement = null;
-      if (insertBefore) {
-        const beforeContainer = insertBefore[UI.ViewManager._ExpandableContainerWidget._symbol];
-        beforeElement = beforeContainer ? beforeContainer.element : null;
-      }
-      container.show(this._vbox.contentElement, beforeElement);
-      this._expandableContainers.set(view.viewId(), container);
-    }
-  }
-
-  /**
-   * @override
-   * @param {!UI.View} view
-   * @param {?UI.View=} insertBefore
-   * @return {!Promise}
-   */
-  showView(view, insertBefore) {
-    this.appendView(view, insertBefore);
-    const container = this._expandableContainers.get(view.viewId());
-    return container._expand();
-  }
-
-  /**
-   * @param {!UI.View} view
-   * @override
-   */
-  removeView(view) {
-    const container = this._expandableContainers.get(view.viewId());
-    if (!container)
-      return;
-
-    container.detach();
-    this._expandableContainers.delete(view.viewId());
-    delete view[UI.ViewManager._Location.symbol];
-    this._manager._views.delete(view.viewId());
-  }
-
-  /**
-   * @override
-   * @param {string} locationName
-   */
-  appendApplicableItems(locationName) {
-    for (const view of this._manager._viewsForLocation(locationName))
-      this.appendView(view);
-  }
-};
-
-/**
- * @type {!UI.ViewManager}
- */
-UI.viewManager;
diff --git a/front_end/ui/Widget.js b/front_end/ui/Widget.js
deleted file mode 100644
index 861f157..0000000
--- a/front_end/ui/Widget.js
+++ /dev/null
@@ -1,748 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * Copyright (C) 2011 Google Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.Widget = class extends Common.Object {
-  /**
-   * @param {boolean=} isWebComponent
-   */
-  constructor(isWebComponent) {
-    super();
-    this.contentElement = createElementWithClass('div', 'widget');
-    if (isWebComponent) {
-      this.element = createElementWithClass('div', 'vbox flex-auto');
-      this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element);
-      this._shadowRoot.appendChild(this.contentElement);
-    } else {
-      this.element = this.contentElement;
-    }
-    this._isWebComponent = isWebComponent;
-    this.element.__widget = this;
-    this._visible = false;
-    this._isRoot = false;
-    this._isShowing = false;
-    this._children = [];
-    this._hideOnDetach = false;
-    this._notificationDepth = 0;
-    this._invalidationsSuspended = 0;
-    this._defaultFocusedChild = null;
-  }
-
-  static _incrementWidgetCounter(parentElement, childElement) {
-    const count = (childElement.__widgetCounter || 0) + (childElement.__widget ? 1 : 0);
-    if (!count)
-      return;
-
-    while (parentElement) {
-      parentElement.__widgetCounter = (parentElement.__widgetCounter || 0) + count;
-      parentElement = parentElement.parentElementOrShadowHost();
-    }
-  }
-
-  static _decrementWidgetCounter(parentElement, childElement) {
-    const count = (childElement.__widgetCounter || 0) + (childElement.__widget ? 1 : 0);
-    if (!count)
-      return;
-
-    while (parentElement) {
-      parentElement.__widgetCounter -= count;
-      parentElement = parentElement.parentElementOrShadowHost();
-    }
-  }
-
-  static __assert(condition, message) {
-    if (!condition)
-      throw new Error(message);
-  }
-
-  /**
-   * @param {?Node} node
-   */
-  static focusWidgetForNode(node) {
-    while (node) {
-      if (node.__widget)
-        break;
-      node = node.parentNodeOrShadowHost();
-    }
-    if (!node)
-      return;
-
-    let widget = node.__widget;
-    while (widget._parentWidget) {
-      widget._parentWidget._defaultFocusedChild = widget;
-      widget = widget._parentWidget;
-    }
-  }
-
-  markAsRoot() {
-    UI.Widget.__assert(!this.element.parentElement, 'Attempt to mark as root attached node');
-    this._isRoot = true;
-  }
-
-  /**
-   * @return {?UI.Widget}
-   */
-  parentWidget() {
-    return this._parentWidget;
-  }
-
-  /**
-   * @return {!Array.<!UI.Widget>}
-   */
-  children() {
-    return this._children;
-  }
-
-  /**
-   * @param {!UI.Widget} widget
-   * @protected
-   */
-  childWasDetached(widget) {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShowing() {
-    return this._isShowing;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  shouldHideOnDetach() {
-    if (!this.element.parentElement)
-      return false;
-    if (this._hideOnDetach)
-      return true;
-    for (const child of this._children) {
-      if (child.shouldHideOnDetach())
-        return true;
-    }
-    return false;
-  }
-
-  setHideOnDetach() {
-    this._hideOnDetach = true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _inNotification() {
-    return !!this._notificationDepth || (this._parentWidget && this._parentWidget._inNotification());
-  }
-
-  _parentIsShowing() {
-    if (this._isRoot)
-      return true;
-    return !!this._parentWidget && this._parentWidget.isShowing();
-  }
-
-  /**
-   * @param {function(this:UI.Widget)} method
-   */
-  _callOnVisibleChildren(method) {
-    const copy = this._children.slice();
-    for (let i = 0; i < copy.length; ++i) {
-      if (copy[i]._parentWidget === this && copy[i]._visible)
-        method.call(copy[i]);
-    }
-  }
-
-  _processWillShow() {
-    this._callOnVisibleChildren(this._processWillShow);
-    this._isShowing = true;
-  }
-
-  _processWasShown() {
-    if (this._inNotification())
-      return;
-    this.restoreScrollPositions();
-    this._notify(this.wasShown);
-    this._callOnVisibleChildren(this._processWasShown);
-  }
-
-  _processWillHide() {
-    if (this._inNotification())
-      return;
-    this.storeScrollPositions();
-
-    this._callOnVisibleChildren(this._processWillHide);
-    this._notify(this.willHide);
-    this._isShowing = false;
-  }
-
-  _processWasHidden() {
-    this._callOnVisibleChildren(this._processWasHidden);
-  }
-
-  _processOnResize() {
-    if (this._inNotification())
-      return;
-    if (!this.isShowing())
-      return;
-    this._notify(this.onResize);
-    this._callOnVisibleChildren(this._processOnResize);
-  }
-
-  /**
-   * @param {function(this:UI.Widget)} notification
-   */
-  _notify(notification) {
-    ++this._notificationDepth;
-    try {
-      notification.call(this);
-    } finally {
-      --this._notificationDepth;
-    }
-  }
-
-  wasShown() {
-  }
-
-  willHide() {
-  }
-
-  onResize() {
-  }
-
-  onLayout() {
-  }
-
-  ownerViewDisposed() {
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {?Node=} insertBefore
-   */
-  show(parentElement, insertBefore) {
-    UI.Widget.__assert(parentElement, 'Attempt to attach widget with no parent element');
-
-    if (!this._isRoot) {
-      // Update widget hierarchy.
-      let currentParent = parentElement;
-      while (currentParent && !currentParent.__widget)
-        currentParent = currentParent.parentElementOrShadowHost();
-      UI.Widget.__assert(currentParent, 'Attempt to attach widget to orphan node');
-      this._attach(currentParent.__widget);
-    }
-
-    this._showWidget(parentElement, insertBefore);
-  }
-
-  /**
-   * @param {!UI.Widget} parentWidget
-   */
-  _attach(parentWidget) {
-    if (parentWidget === this._parentWidget)
-      return;
-    if (this._parentWidget)
-      this.detach();
-    this._parentWidget = parentWidget;
-    this._parentWidget._children.push(this);
-    this._isRoot = false;
-  }
-
-  showWidget() {
-    if (this._visible)
-      return;
-    UI.Widget.__assert(this.element.parentElement, 'Attempt to show widget that is not hidden using hideWidget().');
-    this._showWidget(/** @type {!Element} */ (this.element.parentElement), this.element.nextSibling);
-  }
-
-  /**
-   * @param {!Element} parentElement
-   * @param {?Node=} insertBefore
-   */
-  _showWidget(parentElement, insertBefore) {
-    let currentParent = parentElement;
-    while (currentParent && !currentParent.__widget)
-      currentParent = currentParent.parentElementOrShadowHost();
-
-    if (this._isRoot) {
-      UI.Widget.__assert(!currentParent, 'Attempt to show root widget under another widget');
-    } else {
-      UI.Widget.__assert(
-          currentParent && currentParent.__widget === this._parentWidget,
-          'Attempt to show under node belonging to alien widget');
-    }
-
-    const wasVisible = this._visible;
-    if (wasVisible && this.element.parentElement === parentElement)
-      return;
-
-    this._visible = true;
-
-    if (!wasVisible && this._parentIsShowing())
-      this._processWillShow();
-
-    this.element.classList.remove('hidden');
-
-    // Reparent
-    if (this.element.parentElement !== parentElement) {
-      UI.Widget._incrementWidgetCounter(parentElement, this.element);
-      if (insertBefore)
-        UI.Widget._originalInsertBefore.call(parentElement, this.element, insertBefore);
-      else
-        UI.Widget._originalAppendChild.call(parentElement, this.element);
-    }
-
-    if (!wasVisible && this._parentIsShowing())
-      this._processWasShown();
-
-    if (this._parentWidget && this._hasNonZeroConstraints())
-      this._parentWidget.invalidateConstraints();
-    else
-      this._processOnResize();
-  }
-
-  hideWidget() {
-    if (!this._visible)
-      return;
-    this._hideWidget(false);
-  }
-
-  /**
-   * @param {boolean} removeFromDOM
-   */
-  _hideWidget(removeFromDOM) {
-    this._visible = false;
-    const parentElement = this.element.parentElement;
-
-    if (this._parentIsShowing())
-      this._processWillHide();
-
-    if (removeFromDOM) {
-      // Force legal removal
-      UI.Widget._decrementWidgetCounter(parentElement, this.element);
-      UI.Widget._originalRemoveChild.call(parentElement, this.element);
-    } else {
-      this.element.classList.add('hidden');
-    }
-
-    if (this._parentIsShowing())
-      this._processWasHidden();
-    if (this._parentWidget && this._hasNonZeroConstraints())
-      this._parentWidget.invalidateConstraints();
-  }
-
-  /**
-   * @param {boolean=} overrideHideOnDetach
-   */
-  detach(overrideHideOnDetach) {
-    if (!this._parentWidget && !this._isRoot)
-      return;
-
-    // hideOnDetach means that we should never remove element from dom - content
-    // has iframes and detaching it will hurt.
-    //
-    // overrideHideOnDetach will override hideOnDetach and the client takes
-    // responsibility for the consequences.
-    const removeFromDOM = overrideHideOnDetach || !this.shouldHideOnDetach();
-    if (this._visible) {
-      this._hideWidget(removeFromDOM);
-    } else if (removeFromDOM && this.element.parentElement) {
-      const parentElement = this.element.parentElement;
-      // Force kick out from DOM.
-      UI.Widget._decrementWidgetCounter(parentElement, this.element);
-      UI.Widget._originalRemoveChild.call(parentElement, this.element);
-    }
-
-    // Update widget hierarchy.
-    if (this._parentWidget) {
-      const childIndex = this._parentWidget._children.indexOf(this);
-      UI.Widget.__assert(childIndex >= 0, 'Attempt to remove non-child widget');
-      this._parentWidget._children.splice(childIndex, 1);
-      if (this._parentWidget._defaultFocusedChild === this)
-        this._parentWidget._defaultFocusedChild = null;
-      this._parentWidget.childWasDetached(this);
-      this._parentWidget = null;
-    } else {
-      UI.Widget.__assert(this._isRoot, 'Removing non-root widget from DOM');
-    }
-  }
-
-  detachChildWidgets() {
-    const children = this._children.slice();
-    for (let i = 0; i < children.length; ++i)
-      children[i].detach();
-  }
-
-  /**
-   * @return {!Array.<!Element>}
-   */
-  elementsToRestoreScrollPositionsFor() {
-    return [this.element];
-  }
-
-  storeScrollPositions() {
-    const elements = this.elementsToRestoreScrollPositionsFor();
-    for (let i = 0; i < elements.length; ++i) {
-      const container = elements[i];
-      container._scrollTop = container.scrollTop;
-      container._scrollLeft = container.scrollLeft;
-    }
-  }
-
-  restoreScrollPositions() {
-    const elements = this.elementsToRestoreScrollPositionsFor();
-    for (let i = 0; i < elements.length; ++i) {
-      const container = elements[i];
-      if (container._scrollTop)
-        container.scrollTop = container._scrollTop;
-      if (container._scrollLeft)
-        container.scrollLeft = container._scrollLeft;
-    }
-  }
-
-  doResize() {
-    if (!this.isShowing())
-      return;
-    // No matter what notification we are in, dispatching onResize is not needed.
-    if (!this._inNotification())
-      this._callOnVisibleChildren(this._processOnResize);
-  }
-
-  doLayout() {
-    if (!this.isShowing())
-      return;
-    this._notify(this.onLayout);
-    this.doResize();
-  }
-
-  /**
-   * @param {string} cssFile
-   */
-  registerRequiredCSS(cssFile) {
-    UI.appendStyle(this._isWebComponent ? this._shadowRoot : this.element, cssFile);
-  }
-
-  printWidgetHierarchy() {
-    const lines = [];
-    this._collectWidgetHierarchy('', lines);
-    console.log(lines.join('\n'));  // eslint-disable-line no-console
-  }
-
-  _collectWidgetHierarchy(prefix, lines) {
-    lines.push(prefix + '[' + this.element.className + ']' + (this._children.length ? ' {' : ''));
-
-    for (let i = 0; i < this._children.length; ++i)
-      this._children[i]._collectWidgetHierarchy(prefix + '    ', lines);
-
-    if (this._children.length)
-      lines.push(prefix + '}');
-  }
-
-  /**
-   * @param {?Element} element
-   */
-  setDefaultFocusedElement(element) {
-    this._defaultFocusedElement = element;
-  }
-
-  /**
-   * @param {!UI.Widget} child
-   */
-  setDefaultFocusedChild(child) {
-    UI.Widget.__assert(child._parentWidget === this, 'Attempt to set non-child widget as default focused.');
-    this._defaultFocusedChild = child;
-  }
-
-  focus() {
-    if (!this.isShowing())
-      return;
-
-    const element = this._defaultFocusedElement;
-    if (element) {
-      if (!element.hasFocus())
-        element.focus();
-      return;
-    }
-
-    if (this._defaultFocusedChild && this._defaultFocusedChild._visible) {
-      this._defaultFocusedChild.focus();
-    } else {
-      for (const child of this._children) {
-        if (child._visible) {
-          child.focus();
-          return;
-        }
-      }
-      let child = this.contentElement.traverseNextNode(this.contentElement);
-      while (child) {
-        if (child instanceof UI.XWidget) {
-          child.focus();
-          return;
-        }
-        child = child.traverseNextNode(this.contentElement);
-      }
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasFocus() {
-    return this.element.hasFocus();
-  }
-
-  /**
-   * @return {!UI.Constraints}
-   */
-  calculateConstraints() {
-    return new UI.Constraints();
-  }
-
-  /**
-   * @return {!UI.Constraints}
-   */
-  constraints() {
-    if (typeof this._constraints !== 'undefined')
-      return this._constraints;
-    if (typeof this._cachedConstraints === 'undefined')
-      this._cachedConstraints = this.calculateConstraints();
-    return this._cachedConstraints;
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   * @param {number} preferredWidth
-   * @param {number} preferredHeight
-   */
-  setMinimumAndPreferredSizes(width, height, preferredWidth, preferredHeight) {
-    this._constraints = new UI.Constraints(new UI.Size(width, height), new UI.Size(preferredWidth, preferredHeight));
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @param {number} width
-   * @param {number} height
-   */
-  setMinimumSize(width, height) {
-    this._constraints = new UI.Constraints(new UI.Size(width, height));
-    this.invalidateConstraints();
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _hasNonZeroConstraints() {
-    const constraints = this.constraints();
-    return !!(
-        constraints.minimum.width || constraints.minimum.height || constraints.preferred.width ||
-        constraints.preferred.height);
-  }
-
-  suspendInvalidations() {
-    ++this._invalidationsSuspended;
-  }
-
-  resumeInvalidations() {
-    --this._invalidationsSuspended;
-    if (!this._invalidationsSuspended && this._invalidationsRequested)
-      this.invalidateConstraints();
-  }
-
-  invalidateConstraints() {
-    if (this._invalidationsSuspended) {
-      this._invalidationsRequested = true;
-      return;
-    }
-    this._invalidationsRequested = false;
-    const cached = this._cachedConstraints;
-    delete this._cachedConstraints;
-    const actual = this.constraints();
-    if (!actual.isEqual(cached) && this._parentWidget)
-      this._parentWidget.invalidateConstraints();
-    else
-      this.doLayout();
-  }
-};
-
-UI.Widget._originalAppendChild = Element.prototype.appendChild;
-UI.Widget._originalInsertBefore = Element.prototype.insertBefore;
-UI.Widget._originalRemoveChild = Element.prototype.removeChild;
-UI.Widget._originalRemoveChildren = Element.prototype.removeChildren;
-
-
-/**
- * @unrestricted
- */
-UI.VBox = class extends UI.Widget {
-  /**
-   * @param {boolean=} isWebComponent
-   */
-  constructor(isWebComponent) {
-    super(isWebComponent);
-    this.contentElement.classList.add('vbox');
-  }
-
-  /**
-   * @override
-   * @return {!UI.Constraints}
-   */
-  calculateConstraints() {
-    let constraints = new UI.Constraints();
-
-    /**
-     * @this {!UI.Widget}
-     * @suppressReceiverCheck
-     */
-    function updateForChild() {
-      const child = this.constraints();
-      constraints = constraints.widthToMax(child);
-      constraints = constraints.addHeight(child);
-    }
-
-    this._callOnVisibleChildren(updateForChild);
-    return constraints;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.HBox = class extends UI.Widget {
-  /**
-   * @param {boolean=} isWebComponent
-   */
-  constructor(isWebComponent) {
-    super(isWebComponent);
-    this.contentElement.classList.add('hbox');
-  }
-
-  /**
-   * @override
-   * @return {!UI.Constraints}
-   */
-  calculateConstraints() {
-    let constraints = new UI.Constraints();
-
-    /**
-     * @this {!UI.Widget}
-     * @suppressReceiverCheck
-     */
-    function updateForChild() {
-      const child = this.constraints();
-      constraints = constraints.addWidth(child);
-      constraints = constraints.heightToMax(child);
-    }
-
-    this._callOnVisibleChildren(updateForChild);
-    return constraints;
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.VBoxWithResizeCallback = class extends UI.VBox {
-  /**
-   * @param {function()} resizeCallback
-   */
-  constructor(resizeCallback) {
-    super();
-    this._resizeCallback = resizeCallback;
-  }
-
-  /**
-   * @override
-   */
-  onResize() {
-    this._resizeCallback();
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.WidgetFocusRestorer = class {
-  /**
-   * @param {!UI.Widget} widget
-   */
-  constructor(widget) {
-    this._widget = widget;
-    this._previous = widget.element.ownerDocument.deepActiveElement();
-    widget.focus();
-  }
-
-  restore() {
-    if (!this._widget)
-      return;
-    if (this._widget.hasFocus() && this._previous)
-      this._previous.focus();
-    this._previous = null;
-    this._widget = null;
-  }
-};
-
-/**
- * @override
- * @param {?Node} child
- * @return {!Node}
- * @suppress {duplicate}
- */
-Element.prototype.appendChild = function(child) {
-  UI.Widget.__assert(
-      !child.__widget || child.parentElement === this, 'Attempt to add widget via regular DOM operation.');
-  return UI.Widget._originalAppendChild.call(this, child);
-};
-
-/**
- * @override
- * @param {?Node} child
- * @param {?Node} anchor
- * @return {!Node}
- * @suppress {duplicate}
- */
-Element.prototype.insertBefore = function(child, anchor) {
-  UI.Widget.__assert(
-      !child.__widget || child.parentElement === this, 'Attempt to add widget via regular DOM operation.');
-  return UI.Widget._originalInsertBefore.call(this, child, anchor);
-};
-
-/**
- * @override
- * @param {?Node} child
- * @return {!Node}
- * @suppress {duplicate}
- */
-Element.prototype.removeChild = function(child) {
-  UI.Widget.__assert(
-      !child.__widgetCounter && !child.__widget,
-      'Attempt to remove element containing widget via regular DOM operation');
-  return UI.Widget._originalRemoveChild.call(this, child);
-};
-
-Element.prototype.removeChildren = function() {
-  UI.Widget.__assert(!this.__widgetCounter, 'Attempt to remove element containing widget via regular DOM operation');
-  UI.Widget._originalRemoveChildren.call(this);
-};
diff --git a/front_end/ui/XElement.js b/front_end/ui/XElement.js
deleted file mode 100644
index 09d340a..0000000
--- a/front_end/ui/XElement.js
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @extends {HTMLElement}
- */
-UI.XElement = class extends HTMLElement {
-  static get observedAttributes() {
-    return [
-      'flex',          'padding',     'padding-top',      'padding-bottom', 'padding-left',
-      'padding-right', 'margin',      'margin-top',       'margin-bottom',  'margin-left',
-      'margin-right',  'overflow',    'overflow-x',       'overflow-y',     'font-size',
-      'color',         'background',  'background-color', 'border',         'border-top',
-      'border-bottom', 'border-left', 'border-right',     'max-width',      'max-height'
-    ];
-  }
-
-  /**
-   * @param {string} attr
-   * @param {?string} oldValue
-   * @param {?string} newValue
-   * @override
-   */
-  attributeChangedCallback(attr, oldValue, newValue) {
-    if (attr === 'flex') {
-      if (newValue === null)
-        this.style.removeProperty('flex');
-      else if (newValue === 'initial' || newValue === 'auto' || newValue === 'none' || newValue.indexOf(' ') !== -1)
-        this.style.setProperty('flex', newValue);
-      else
-        this.style.setProperty('flex', '0 0 ' + newValue);
-      return;
-    }
-    if (newValue === null) {
-      this.style.removeProperty(attr);
-      if (attr.startsWith('padding-') || attr.startsWith('margin-') || attr.startsWith('border-') ||
-          attr.startsWith('background-') || attr.startsWith('overflow-')) {
-        const shorthand = attr.substring(0, attr.indexOf('-'));
-        const shorthandValue = this.getAttribute(shorthand);
-        if (shorthandValue !== null)
-          this.style.setProperty(shorthand, shorthandValue);
-      }
-    } else {
-      this.style.setProperty(attr, newValue);
-    }
-  }
-};
-
-/**
- * @extends {UI.XElement}
- */
-UI._XBox = class extends UI.XElement {
-  /**
-   * @param {string} direction
-   */
-  constructor(direction) {
-    super();
-    this.style.setProperty('display', 'flex');
-    this.style.setProperty('flex-direction', direction);
-    this.style.setProperty('justify-content', 'flex-start');
-  }
-
-  static get observedAttributes() {
-    // TODO(dgozman): should be super.observedAttributes, but does not compile.
-    return UI.XElement.observedAttributes.concat(['x-start', 'x-center', 'x-stretch', 'x-baseline', 'justify-content']);
-  }
-
-  /**
-   * @param {string} attr
-   * @param {?string} oldValue
-   * @param {?string} newValue
-   * @override
-   */
-  attributeChangedCallback(attr, oldValue, newValue) {
-    if (attr === 'x-start' || attr === 'x-center' || attr === 'x-stretch' || attr === 'x-baseline') {
-      if (newValue === null)
-        this.style.removeProperty('align-items');
-      else
-        this.style.setProperty('align-items', attr === 'x-start' ? 'flex-start' : attr.substr(2));
-      return;
-    }
-    super.attributeChangedCallback(attr, oldValue, newValue);
-  }
-};
-
-/**
- * @extends {UI._XBox}
- */
-UI.XVBox = class extends UI._XBox {
-  constructor() {
-    super('column');
-  }
-};
-
-/**
- * @extends {UI._XBox}
- */
-UI.XHBox = class extends UI._XBox {
-  constructor() {
-    super('row');
-  }
-};
-
-/**
- * @extends {UI.XElement}
- */
-UI.XCBox = class extends UI.XElement {
-  constructor() {
-    super();
-    this.style.setProperty('display', 'flex');
-    this.style.setProperty('flex-direction', 'column');
-    this.style.setProperty('justify-content', 'center');
-    this.style.setProperty('align-items', 'center');
-  }
-};
-
-/**
- * @extends {UI.XElement}
- */
-UI.XDiv = class extends UI.XElement {
-  constructor() {
-    super();
-    this.style.setProperty('display', 'block');
-  }
-};
-
-/**
- * @extends {UI.XElement}
- */
-UI.XSpan = class extends UI.XElement {
-  constructor() {
-    super();
-    this.style.setProperty('display', 'inline');
-  }
-};
-
-/**
- * @extends {UI.XElement}
- */
-UI.XText = class extends UI.XElement {
-  constructor() {
-    super();
-    this.style.setProperty('display', 'inline');
-    this.style.setProperty('white-space', 'pre');
-  }
-};
-
-self.customElements.define('x-vbox', UI.XVBox);
-self.customElements.define('x-hbox', UI.XHBox);
-self.customElements.define('x-cbox', UI.XCBox);
-self.customElements.define('x-div', UI.XDiv);
-self.customElements.define('x-span', UI.XSpan);
-self.customElements.define('x-text', UI.XText);
diff --git a/front_end/ui/XLink.js b/front_end/ui/XLink.js
deleted file mode 100644
index e7bdbbc..0000000
--- a/front_end/ui/XLink.js
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @extends {UI.XElement}
- */
-UI.XLink = class extends UI.XElement {
-  /**
-   * @param {string} url
-   * @param {string=} linkText
-   * @param {string=} className
-   * @param {boolean=} preventClick
-   * @return {!Element}
-   */
-  static create(url, linkText, className, preventClick) {
-    if (!linkText)
-      linkText = url;
-    className = className || '';
-    // clang-format off
-    // TODO(dgozman): migrate css from 'devtools-link' to 'x-link'.
-    return (UI.Fragment.cached`
-        <x-link href='${url}' class='${className} devtools-link' ${preventClick ? 'no-click' : ''}
-        >${linkText.trimMiddle(UI.MaxLengthForDisplayedURLs)}</x-link>`).element();
-    // clang-format on
-  }
-
-  constructor() {
-    super();
-
-    this.style.setProperty('display', 'inline');
-    UI.ARIAUtils.markAsLink(this);
-    this.tabIndex = 0;
-    this.setAttribute('target', '_blank');
-
-    /** @type {?string} */
-    this._href = null;
-    this._clickable = true;
-
-    this._onClick = event => {
-      event.consume(true);
-      InspectorFrontendHost.openInNewTab(/** @type {string} */ (this._href));
-    };
-    this._onKeyDown = event => {
-      if (event.key !== ' ' && !isEnterKey(event))
-        return;
-      event.consume(true);
-      InspectorFrontendHost.openInNewTab(/** @type {string} */ (this._href));
-    };
-  }
-
-  /**
-   * @return {!Array<string>}
-   */
-  static get observedAttributes() {
-    // TODO(dgozman): should be super.observedAttributes, but it does not compile.
-    return UI.XElement.observedAttributes.concat(['href', 'no-click']);
-  }
-
-  /**
-   * @param {string} attr
-   * @param {?string} oldValue
-   * @param {?string} newValue
-   * @override
-   */
-  attributeChangedCallback(attr, oldValue, newValue) {
-    if (attr === 'no-click') {
-      this._clickable = !newValue;
-      this._updateClick();
-      return;
-    }
-
-    if (attr === 'href') {
-      let href = newValue;
-      if (newValue.trim().toLowerCase().startsWith('javascript:'))
-        href = null;
-      if (Common.ParsedURL.isRelativeURL(newValue))
-        href = null;
-
-      this._href = href;
-      this.title = newValue;
-      this._updateClick();
-      return;
-    }
-
-    super.attributeChangedCallback(attr, oldValue, newValue);
-  }
-
-  _updateClick() {
-    if (this._href !== null && this._clickable) {
-      this.addEventListener('click', this._onClick, false);
-      this.addEventListener('keydown', this._onKeyDown, false);
-      this.style.setProperty('cursor', 'pointer');
-    } else {
-      this.removeEventListener('click', this._onClick, false);
-      this.removeEventListener('keydown', this._onKeyDown, false);
-      this.style.removeProperty('cursor');
-    }
-  }
-};
-
-/**
- * @implements {UI.ContextMenu.Provider}
- */
-UI.XLink.ContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    let targetNode = /** @type {!Node} */ (target);
-    while (targetNode && !(targetNode instanceof UI.XLink))
-      targetNode = targetNode.parentNodeOrShadowHost();
-    if (!targetNode || !targetNode._href)
-      return;
-    contextMenu.revealSection().appendItem(
-        UI.openLinkExternallyLabel(), () => InspectorFrontendHost.openInNewTab(targetNode._href));
-    contextMenu.revealSection().appendItem(
-        UI.copyLinkAddressLabel(), () => InspectorFrontendHost.copyText(targetNode._href));
-  }
-};
-
-self.customElements.define('x-link', UI.XLink);
diff --git a/front_end/ui/XWidget.js b/front_end/ui/XWidget.js
deleted file mode 100644
index 6e33f2b..0000000
--- a/front_end/ui/XWidget.js
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @extends {UI.XElement}
- */
-UI.XWidget = class extends UI.XElement {
-  constructor() {
-    super();
-    this.style.setProperty('display', 'flex');
-    this.style.setProperty('flex-direction', 'column');
-    this.style.setProperty('align-items', 'stretch');
-    this.style.setProperty('justify-content', 'flex-start');
-    this.style.setProperty('contain', 'layout style');
-
-    this._visible = false;
-    /** @type {?DocumentFragment} */
-    this._shadowRoot;
-    /** @type {?Element} */
-    this._defaultFocusedElement = null;
-    /** @type {!Array<!Element>} */
-    this._elementsToRestoreScrollPositionsFor = [];
-    /** @type {?function()} */
-    this._onShownCallback;
-    /** @type {?function()} */
-    this._onHiddenCallback;
-    /** @type {?function()} */
-    this._onResizedCallback;
-
-    if (!UI.XWidget._observer) {
-      UI.XWidget._observer = new ResizeObserver(entries => {
-        for (const entry of entries) {
-          if (entry.target._visible && entry.target._onResizedCallback)
-            entry.target._onResizedCallback.call(null);
-        }
-      });
-    }
-    UI.XWidget._observer.observe(this);
-
-    this.setElementsToRestoreScrollPositionsFor([this]);
-  }
-
-  /**
-   * @param {?Node} node
-   */
-  static focusWidgetForNode(node) {
-    node = node && node.parentNodeOrShadowHost();
-    let widget = null;
-    while (node) {
-      if (node instanceof UI.XWidget) {
-        if (widget)
-          node._defaultFocusedElement = widget;
-        widget = node;
-      }
-      node = node.parentNodeOrShadowHost();
-    }
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isShowing() {
-    return this._visible;
-  }
-
-  /**
-   * @param {string} cssFile
-   */
-  registerRequiredCSS(cssFile) {
-    UI.appendStyle(this._shadowRoot || this, cssFile);
-  }
-
-  /**
-   * @param {?function()} callback
-   */
-  setOnShown(callback) {
-    this._onShownCallback = callback;
-  }
-
-  /**
-   * @param {?function()} callback
-   */
-  setOnHidden(callback) {
-    this._onHiddenCallback = callback;
-  }
-
-  /**
-   * @param {?function()} callback
-   */
-  setOnResized(callback) {
-    this._onResizedCallback = callback;
-  }
-
-  /**
-   * @param {!Array<!Element>} elements
-   */
-  setElementsToRestoreScrollPositionsFor(elements) {
-    for (const element of this._elementsToRestoreScrollPositionsFor)
-      element.removeEventListener('scroll', UI.XWidget._storeScrollPosition, {passive: true, capture: false});
-    this._elementsToRestoreScrollPositionsFor = elements;
-    for (const element of this._elementsToRestoreScrollPositionsFor)
-      element.addEventListener('scroll', UI.XWidget._storeScrollPosition, {passive: true, capture: false});
-  }
-
-  restoreScrollPositions() {
-    for (const element of this._elementsToRestoreScrollPositionsFor) {
-      if (element._scrollTop)
-        element.scrollTop = element._scrollTop;
-      if (element._scrollLeft)
-        element.scrollLeft = element._scrollLeft;
-    }
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  static _storeScrollPosition(event) {
-    const element = event.currentTarget;
-    element._scrollTop = element.scrollTop;
-    element._scrollLeft = element.scrollLeft;
-  }
-
-  /**
-   * @param {?Element} element
-   */
-  setDefaultFocusedElement(element) {
-    if (element && !this.isSelfOrAncestor(element))
-      throw new Error('Default focus must be descendant');
-    this._defaultFocusedElement = element;
-  }
-
-  /**
-   * @override
-   */
-  focus() {
-    if (!this._visible)
-      return;
-
-    let element;
-    if (this._defaultFocusedElement && this.isSelfOrAncestor(this._defaultFocusedElement)) {
-      element = this._defaultFocusedElement;
-    } else if (this.tabIndex !== -1) {
-      element = this;
-    } else {
-      let child = this.traverseNextNode(this);
-      while (child) {
-        if ((child instanceof UI.XWidget) && child._visible) {
-          element = child;
-          break;
-        }
-        child = child.traverseNextNode(this);
-      }
-    }
-
-    if (!element || element.hasFocus())
-      return;
-    if (element === this)
-      HTMLElement.prototype.focus.call(this);
-    else
-      element.focus();
-  }
-
-  /**
-   * @override
-   */
-  connectedCallback() {
-    this._visible = true;
-    this.restoreScrollPositions();
-    if (this._onShownCallback)
-      this._onShownCallback.call(null);
-  }
-
-  /**
-   * @override
-   */
-  disconnectedCallback() {
-    this._visible = false;
-    if (this._onHiddenCallback)
-      this._onHiddenCallback.call(null);
-  }
-};
-
-self.customElements.define('x-widget', UI.XWidget);
diff --git a/front_end/ui/ZoomManager.js b/front_end/ui/ZoomManager.js
deleted file mode 100644
index d029538..0000000
--- a/front_end/ui/ZoomManager.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-UI.ZoomManager = class extends Common.Object {
-  /**
-   * @param {!Window} window
-   * @param {!InspectorFrontendHostAPI} frontendHost
-   */
-  constructor(window, frontendHost) {
-    super();
-    this._frontendHost = frontendHost;
-    this._zoomFactor = this._frontendHost.zoomFactor();
-    window.addEventListener('resize', this._onWindowResize.bind(this), true);
-  }
-
-  /**
-   * @return {number}
-   */
-  zoomFactor() {
-    return this._zoomFactor;
-  }
-
-  /**
-   * @param {number} value
-   * @return {number}
-   */
-  cssToDIP(value) {
-    return value * this._zoomFactor;
-  }
-
-  /**
-   * @param {number} valueDIP
-   * @return {number}
-   */
-  dipToCSS(valueDIP) {
-    return valueDIP / this._zoomFactor;
-  }
-
-  _onWindowResize() {
-    const oldZoomFactor = this._zoomFactor;
-    this._zoomFactor = this._frontendHost.zoomFactor();
-    if (oldZoomFactor !== this._zoomFactor)
-      this.dispatchEventToListeners(UI.ZoomManager.Events.ZoomChanged, {from: oldZoomFactor, to: this._zoomFactor});
-  }
-};
-
-/** @enum {symbol} */
-UI.ZoomManager.Events = {
-  ZoomChanged: Symbol('ZoomChanged')
-};
-
-/**
- * @type {!UI.ZoomManager}
- */
-UI.zoomManager;
diff --git a/front_end/ui/checkboxTextLabel.css b/front_end/ui/checkboxTextLabel.css
deleted file mode 100644
index f562144..0000000
--- a/front_end/ui/checkboxTextLabel.css
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    padding: 0;
-    margin: 0;
-    display: inline-flex;
-    flex-shrink: 0;
-    align-items: center !important;
-}
-
-input {
-    height: 12px;
-    width: 12px;
-    flex-shrink: 0;
-}
-
-input:focus {
-    outline: auto 5px -webkit-focus-ring-color;
-}
-
-input.dt-checkbox-themed {
-    -webkit-appearance: none;
-    margin: auto 5px auto 2px;
-    border: 1px solid rgb(45, 45, 45);
-    border-radius: 3px;
-    background-color: rgb(102, 102, 102);
-}
-
-input.dt-checkbox-themed:after {
-    content: '';
-    line-height: 10px;
-    position: absolute;
-    cursor: pointer;
-    width: 12px;
-    height: 12px;
-    background: none;
-}
-
-input.dt-checkbox-themed:checked:after {
-    background-color: #333;
-}
-
-input.dt-checkbox-themed:after {
-    -webkit-mask-image: url(Images/checkboxCheckmark.png);
-    -webkit-mask-size: 11px 11px;
-    -webkit-mask-position: 0 0;
-}
-
-:host-context(.-theme-with-dark-background) input:not(.dt-checkbox-themed) {
-    filter: invert(80%);
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-input.dt-checkbox-themed:after {
-    -webkit-mask-image: url(Images/checkboxCheckmark_2x.png);
-}
-
-} /* media */
-
-.dt-checkbox-text {
-    margin-left: 3px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.dt-checkbox-subtitle {
-    color: gray;
-}
diff --git a/front_end/ui/closeButton.css b/front_end/ui/closeButton.css
deleted file mode 100644
index 2d6d991..0000000
--- a/front_end/ui/closeButton.css
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.close-button {
-    width: 14px;
-    height: 14px;
-    cursor: default;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.hover-icon, .active-icon {
-    display: none;
-}
-
-.close-button:hover .default-icon, .close-button:active .default-icon {
-    display: none;
-}
-
-.close-button:hover .hover-icon {
-    display: block;
-}
-
-.close-button:active .hover-icon {
-    display: none !important;
-}
-
-.close-button:active .active-icon {
-    display: block;
-}
diff --git a/front_end/ui/confirmDialog.css b/front_end/ui/confirmDialog.css
deleted file mode 100644
index 1e7d5e4..0000000
--- a/front_end/ui/confirmDialog.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.widget {
-    padding: 20px;
-}
-
-.message, .button {
-    font-size: larger;
-    white-space: pre;
-    margin: 5px;
-}
-
-.button {
-    text-align: center;
-    margin-top: 10px;
-}
-
-.button button {
-    min-width: 80px;
-}
-
-.reason {
-    color: #8b0000;
-}
diff --git a/front_end/ui/dialog.css b/front_end/ui/dialog.css
deleted file mode 100644
index b91b838..0000000
--- a/front_end/ui/dialog.css
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.widget {
-    box-shadow: var(--drop-shadow);
-    background: white;
-    justify-content: flex-start;
-    align-items: stretch;
-    display: flex;
-}
-
-.dialog-close-button {
-    position: absolute;
-    right: 9px;
-    top: 9px;
-    z-index: 1;
-}
\ No newline at end of file
diff --git a/front_end/ui/dropTarget.css b/front_end/ui/dropTarget.css
deleted file mode 100644
index 314dbae..0000000
--- a/front_end/ui/dropTarget.css
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    display: flex;
-    background-color: rgba(255,255,255,0.8);
-    z-index: 1000;
-}
-
-.drop-target-message {
-    flex: auto;
-    font-size: 30px;
-    color: #999;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    margin: 20px;
-    border: 4px dashed #ddd;
-    pointer-events: none;
-}
diff --git a/front_end/ui/emptyWidget.css b/front_end/ui/emptyWidget.css
deleted file mode 100644
index 76cbe65..0000000
--- a/front_end/ui/emptyWidget.css
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.empty-view {
-    color: hsla(0, 0%, 65%, 1);
-    padding: 30px;
-    display: flex;
-    align-items: center;
-    flex-direction: column;
-    min-width: 70px;
-}
-
-.empty-view-scroller {
-    justify-content: center;
-    overflow: auto;
-}
-
-.empty-view p {
-    white-space: initial;
-    line-height: 18px;
-    max-width: 300px;
-}
diff --git a/front_end/ui/filter.css b/front_end/ui/filter.css
deleted file mode 100644
index 08ddde1..0000000
--- a/front_end/ui/filter.css
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.filter-bar {
-    background-color: var(--toolbar-bg-color);
-    flex: none;
-    flex-wrap: wrap;
-    align-items: center;
-    border-bottom: var(--divider-border);
-}
-
-.filter-text-filter {
-    display: inline-flex;
-    margin-left: 1px;
-    margin-right: 2px;
-    min-width: 40px;
-    max-width: 200px;
-    height: 24px;
-    align-items: center;
-}
-
-.filter-text-filter label {
-    margin: auto 0;
-}
-
-.filter-bitset-filter {
-    padding: 2px;
-    display: inline-flex;
-    overflow: hidden;
-    height: 24px;
-    position: relative;
-}
-
-.filter-bitset-filter li {
-    display: inline-block;
-    flex: none;
-    margin: auto 2px;
-    padding: 3px;
-    background: transparent;
-    text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
-    border-radius: 6px;
-    overflow: hidden;
-}
-
-.filter-bitset-filter-divider {
-    background-color: #ccc;
-    height: 16px;
-    width: 1px;
-    margin: auto 2px;
-    display: inline-block;
-}
-
-.filter-bitset-filter li.selected,
-.filter-bitset-filter li:hover,
-.filter-bitset-filter li:active {
-    color: white;
-    text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
-}
-
-.filter-bitset-filter li:hover {
-    background: rgba(0, 0, 0, 0.2);
-}
-
-.filter-bitset-filter li.selected {
-    background: rgba(0, 0, 0, 0.3);
-}
-
-.filter-bitset-filter li:active {
-    background: rgba(0, 0, 0, 0.5);
-}
-
-.filter-combobox-filter {
-    margin-left: 5px;
-    margin-right: 2px;
-    flex: 0 0 auto;
-    display: inline-block;
-}
-
-.filter-checkbox-filter {
-    padding-left: 4px;
-    padding-right: 2px;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    display: inline-flex;
-    vertical-align: middle;
-    height: 24px;
-    position: relative;
-}
-
-.filter-checkbox-filter > label {
-    display: flex;
-    margin: auto 0;
-}
-
-.filter-checkbox-filter .checkbox-filter-checkbox {
-    width: 10px;
-    height: 10px;
-    margin: auto 3px;
-    padding: 0;
-    border-radius: 2px;
-    border: solid 1px;
-    display: inline-block;
-    overflow: visible;
-    opacity: 0.8;
-    flex-shrink: 0;
-}
-
-.filter-input-field {
-    margin: 0 3px;
-    padding-left: 3px;
-    width: 163px;
-    height: 18px;
-    line-height: 20px;
-    display: inline-block;
-    background: #FFF;
-    overflow: hidden;
-    white-space: nowrap;
-    cursor: auto;
-}
-
-.filter-input-field:hover {
-    box-shadow: var(--focus-ring-inactive-shadow);
-}
-
-.filter-input-field:focus {
-    box-shadow: var(--focus-ring-active-shadow);
-}
diff --git a/front_end/ui/glassPane.css b/front_end/ui/glassPane.css
deleted file mode 100644
index 1a170f4..0000000
--- a/front_end/ui/glassPane.css
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    position: absolute !important;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    overflow: hidden;
-    contain: strict;
-    background-color: transparent;
-}
-
-:host-context(.dimmed-pane) {
-    background-color: rgba(255, 255, 255, 0.5);
-}
-
-:host-context(.no-pointer-events) {
-    pointer-events: none;
-}
-
-.widget {
-    display: flex;
-    background-color: transparent;
-    pointer-events: auto;
-    flex: none;
-}
-
-.no-pointer-events {
-    pointer-events: none;
-}
-
-.arrow-top {
-    margin-top: -19px;
-    margin-left: -9px;
-}
-
-.arrow-bottom {
-    margin-left: -9px;
-}
-
-.arrow-left {
-    margin-left: -19px;
-    margin-top: -9px;
-}
-
-.arrow-right {
-    margin-top: -9px;
-}
-
-.arrow-none {
-    display: none;
-}
-
-:host-context(.-theme-with-dark-background) .arrow {
-    -webkit-filter: invert(80%);
-}
diff --git a/front_end/ui/infobar.css b/front_end/ui/infobar.css
deleted file mode 100644
index c18e76b..0000000
--- a/front_end/ui/infobar.css
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.infobar {
-    color: rgb(34, 34, 34);
-    display: flex;
-    flex: auto;
-    border-bottom: 1px solid rgb(171, 171, 171);
-    flex-direction: column;
-    align-items: stretch;
-    position: relative;
-}
-
-.infobar-warning {
-    background-color: rgb(253, 242, 192);
-}
-
-.infobar-info {
-    background-color: rgb(255, 255, 255);
-}
-
-.infobar-main-row {
-    display: flex;
-    flex-direction: row;
-    flex: auto;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    justify-content: space-between;
-    margin-right: 20px;
-    min-height: 25px;
-    align-items: center;
-    padding-left: 4px;
-}
-
-.infobar-main-row > * {
-    flex: none;
-    padding: 0 3px;
-}
-
-.infobar-main-title {
-    flex: auto;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.infobar-details-rows {
-    padding: 5px 5px 0 5px;
-}
-
-.infobar-details-row {
-    display: flex;
-    flex-direction: column;
-    line-height: 18px;
-    padding-bottom: 6px;
-}
-
-.close-button {
-    position: absolute;
-    top: 5px;
-    right: 6px;
-}
-
-.infobar-toggle {
-    color: hsl(214, 92%, 50%);
-    cursor: pointer;
-}
-
-.infobar-toggle:hover {
-    color: hsl(214, 92%, 30%);
-}
-
-.info-icon {
-    -webkit-mask-image: url(Images/ic_info_black_18dp.svg);
-    background-color: hsl(214, 92%, 50%);
-}
-
-.warning-icon {
-    -webkit-mask-image: url(Images/ic_warning_black_18dp.svg);
-    background-color: hsl(44, 92%, 50%);
-}
-
-.icon {
-    -webkit-mask-size: 18px 18px;
-    width: 18px;
-    height: 19px;
-}
diff --git a/front_end/ui/inlineButton.css b/front_end/ui/inlineButton.css
deleted file mode 100644
index d6d6c51..0000000
--- a/front_end/ui/inlineButton.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-  display: inline-block;
-  border: 1px solid #ddd;
-  position: relative;
-  top: 7px;
-  margin: 2px;
-  background-color: var(--toolbar-bg-color);
-}
-
-:host > * {
-  position: relative;
-  left: -2px;
-  width: 28px;
-  height: 26px;
-}
\ No newline at end of file
diff --git a/front_end/ui/inspectorCommon.css b/front_end/ui/inspectorCommon.css
deleted file mode 100644
index fb4b813..0000000
--- a/front_end/ui/inspectorCommon.css
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-* {
-    /* This is required for correct sizing of flex items because we rely
-     * on an old version of the flexbox spec.
-     * Longer-term we should remove this, see crbug.com/473625 */
-    min-width: 0;
-    min-height: 0;
-}
-
-:host-context(.platform-mac) .monospace,
-:host-context(.platform-mac) .source-code,
-.platform-mac .monospace,
-.platform-mac .source-code {
-    font-size: 11px !important;
-    font-family: Menlo, monospace;
-}
-
-:host-context(.platform-windows) .monospace,
-:host-context(.platform-windows) .source-code,
-.platform-windows .monospace,
-.platform-windows .source-code {
-    font-size: 12px !important;
-    font-family: Consolas, Lucida Console, Courier New, monospace;
-}
-
-:host-context(.platform-linux) .monospace,
-:host-context(.platform-linux) .source-code,
-.platform-linux .monospace,
-.platform-linux .source-code {
-    font-size: 11px !important;
-    font-family: dejavu sans mono, monospace;
-}
-
-.source-code {
-    font-family: monospace;
-    font-size: 11px !important;
-    white-space: pre-wrap;
-}
-
-* {
-    box-sizing: border-box;
-}
-
-:focus {
-    outline-width: 0;
-}
-
-img {
-    -webkit-user-drag: none;
-}
-
-iframe,
-a img {
-    border: none;
-}
-
-.fill {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-}
-
-iframe.fill {
-    width: 100%;
-    height: 100%;
-}
-
-.widget {
-    position: relative;
-    flex: auto;
-    contain: layout style;
-}
-
-.hbox {
-    display: flex;
-    flex-direction: row !important;
-    position: relative;
-}
-
-.vbox {
-    display: flex;
-    flex-direction: column !important;
-    position: relative;
-}
-
-.view-container > .toolbar {
-    border-bottom: 1px solid #eee;
-}
-
-.flex-auto {
-    flex: auto;
-}
-
-.flex-auto-important {
-    flex: auto !important;
-}
-
-.flex-none {
-    flex: none;
-}
-
-.flex-centered {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.overflow-auto {
-    overflow: auto;
-}
-
-iframe.widget {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-}
-
-.hidden {
-    display: none !important;
-}
-
-.monospace {
-    font-size: 10px !important;
-    font-family: monospace;
-}
-
-.highlighted-search-result {
-    border-radius: 1px;
-    padding: 1px;
-    margin: -1px;
-    background-color: rgba(255, 255, 0, 0.8);
-}
-
-.-theme-with-dark-background .highlighted-search-result,
-:host-context(.-theme-with-dark-background) .highlighted-search-result {
-    background-color: hsl(133, 100%, 30%);
-    color: #333;
-}
-
-.link {
-    cursor: pointer;
-    text-decoration: underline;
-    color: rgb(17, 85, 204);
-}
-
-button,
-input,
-select {
-    font-family: inherit;
-    font-size: inherit;
-    color: inherit;
-}
-
-input {
-    background-color: white;
-}
-
-:host-context(.-theme-with-dark-background) input[type="checkbox"]::not(.-theme-preserve) {
-    -webkit-filter: invert(80%);
-}
-
-.harmony-input:not([type]),
-.harmony-input[type=number],
-.harmony-input[type=text] {
-    padding: 3px 6px;
-    height: 24px;
-    border: none;
-}
-
-.harmony-input:not([type]):not(.error-input):not(:invalid):hover,
-.harmony-input[type=number]:not(.error-input):not(:invalid):hover,
-.harmony-input[type=text]:not(.error-input):not(:invalid):hover {
-    box-shadow: var(--focus-ring-inactive-shadow);
-}
-
-.harmony-input:not([type]):not(.error-input):not(:invalid):focus,
-.harmony-input[type=number]:not(.error-input):not(:invalid):focus,
-.harmony-input[type=text]:not(.error-input):not(:invalid):focus {
-    box-shadow: var(--focus-ring-active-shadow);
-}
-
-.highlighted-search-result.current-search-result {
-    border-radius: 1px;
-    padding: 1px;
-    margin: -1px;
-    background-color: rgba(255, 127, 0, 0.8);
-}
-
-.dimmed {
-    opacity: 0.6;
-}
-
-.editing {
-    box-shadow: var(--drop-shadow);
-    background-color: white;
-    text-overflow: clip !important;
-    padding-left: 2px;
-    margin-left: -2px;
-    padding-right: 2px;
-    margin-right: -2px;
-    margin-bottom: -1px;
-    padding-bottom: 1px;
-    opacity: 1.0 !important;
-}
-
-.editing,
-.editing * {
-    color: #222 !important;
-    text-decoration: none !important;
-}
-
-.harmony-input:not([type]).error-input,
-.harmony-input[type=number].error-input,
-.harmony-input[type=text].error-input,
-.harmony-input:not([type]):invalid,
-.harmony-input[type=number]:invalid,
-.harmony-input[type=text]:invalid {
-    box-shadow: 0 0 0 1px #ff1a00;
-}
-
-.chrome-select {
-    -webkit-appearance: none;
-    -webkit-user-select: none;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-    border-radius: 2px;
-    color: #333;
-    font: inherit;
-    margin: 0;
-    outline: none;
-    padding-right: 20px;
-    padding-left: 6px;
-    background-image: -webkit-image-set(url(Images/chromeSelect.png) 1x, url(Images/chromeSelect_2x.png) 2x);
-    background-color: hsl(0, 0%, 98%);
-    background-position: right center;
-    background-repeat: no-repeat;
-    min-height: 24px;
-    min-width: 80px;
-    background-size: 15px;
-}
-
-.chrome-select:enabled:active,
-.chrome-select:enabled:focus,
-.chrome-select:enabled:hover {
-    background-color: hsl(0, 0%, 96%);
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.chrome-select:enabled:active {
-    background-color: #f2f2f2;
-}
-
-.chrome-select:enabled:focus {
-    border-color: transparent;
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(66, 133, 244, 0.4);
-}
-
-.chrome-select:disabled {
-    opacity: 0.38;
-}
-
-.chrome-select optgroup,
-.chrome-select option {
-    background-color: #EEEEEE;
-    color: #222;
-}
-
-:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar,
-:host-context(:not(.platform-mac).-theme-with-dark-background) ::-webkit-scrollbar {
-    width: 14px;
-}
-
-:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar-track,
-:host-context(:not(.platform-mac).-theme-with-dark-background) ::-webkit-scrollbar-track {
-    -webkit-box-shadow: inset 0 0 1px rgba(255,255,255,0.3);
-}
-
-:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar-thumb,
-:host-context(:not(.platform-mac).-theme-with-dark-background) ::-webkit-scrollbar-thumb {
-    border-radius: 2px;
-    background-color: #333;
-    -webkit-box-shadow: inset 0 0 1px rgba(255,255,255,0.5);
-}
-
-:not(.platform-mac).-theme-with-dark-background ::-webkit-scrollbar-corner,
-:host-context(:not(.platform-mac).-theme-with-dark-background) ::-webkit-scrollbar-corner {
-    background-color: #242424;
-}
-
-.gray-info-message {
-    text-align: center;
-    font-style: italic;
-    padding: 6px;
-    color: #888;
-    white-space: nowrap;
-}
-
-label[is=dt-icon-label] {
-    flex: none;
-}
-
-.full-widget-dimmed-banner a {
-    color: inherit;
-}
-
-.full-widget-dimmed-banner {
-    color: #777;
-    background-color: white;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    text-align: center;
-    padding: 20px;
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    left: 0;
-    font-size: 13px;
-    overflow: auto;
-    z-index: 500;
-}
-
-[is=ui-icon] {
-    display: inline-block;
-    flex-shrink: 0;
-}
-
-.-theme-with-dark-background [is=ui-icon].icon-invert,
-:host-context(.-theme-with-dark-background) [is=ui-icon].icon-invert {
-    filter: invert(80%) hue-rotate(180deg);
-}
-
-[is=ui-icon].icon-mask {
-    background-color: rgb(110, 110, 110);
-    -webkit-mask-position: var(--spritesheet-position);
-}
-
-[is=ui-icon]:not(.icon-mask) {
-    background-position: var(--spritesheet-position);
-}
-
-.spritesheet-smallicons:not(.icon-mask) {
-    background-image: -webkit-image-set(url(Images/smallIcons.png) 1x, url(Images/smallIcons_2x.png) 2x);
-}
-
-.spritesheet-smallicons.icon-mask {
-    -webkit-mask-image: -webkit-image-set(url(Images/smallIcons.png) 1x, url(Images/smallIcons_2x.png) 2x);
-}
-
-.spritesheet-largeicons:not(.icon-mask) {
-    background-image: -webkit-image-set(url(Images/largeIcons.png) 1x, url(Images/largeIcons_2x.png) 2x);
-}
-
-.spritesheet-largeicons.icon-mask {
-    -webkit-mask-image: -webkit-image-set(url(Images/largeIcons.png) 1x, url(Images/largeIcons_2x.png) 2x);
-}
-
-.spritesheet-mediumicons:not(.icon-mask) {
-    background-image: -webkit-image-set(url(Images/mediumIcons.png) 1x, url(Images/mediumIcons_2x.png) 2x);
-}
-
-.spritesheet-mediumicons.icon-mask {
-    -webkit-mask-image: -webkit-image-set(url(Images/mediumIcons.png) 1x, url(Images/mediumIcons_2x.png) 2x);
-}
-
-.spritesheet-arrowicons {
-    background-image: url(Images/popoverArrows.png);
-}
-
-.force-white-icons [is=ui-icon].spritesheet-smallicons, [is=ui-icon].force-white-icons.spritesheet-smallicons, -theme-preserve {
-    -webkit-mask-image: -webkit-image-set(url(Images/smallIcons.png) 1x, url(Images/smallIcons_2x.png) 2x);
-    -webkit-mask-position: var(--spritesheet-position);
-    background: #fafafa !important;
-}
-
-.force-white-icons [is=ui-icon].spritesheet-largeicons, [is=ui-icon].force-white-icons.spritesheet-largeicons, -theme-preserve {
-    -webkit-mask-image: -webkit-image-set(url(Images/largeIcons.png) 1x, url(Images/largeIcons_2x.png) 2x);
-    -webkit-mask-position: var(--spritesheet-position);
-    background: #fafafa !important;
-}
-
-.force-white-icons [is=ui-icon].spritesheet-mediumicons, [is=ui-icon].force-white-icons.spritesheet-mediumicons, -theme-preserve {
-    -webkit-mask-image: -webkit-image-set(url(Images/mediumIcons.png) 1x, url(Images/mediumIcons_2x.png) 2x);
-    -webkit-mask-position: var(--spritesheet-position);
-    background: #fafafa !important;
-}
diff --git a/front_end/ui/inspectorStyle.css b/front_end/ui/inspectorStyle.css
deleted file mode 100644
index fa7b26b..0000000
--- a/front_end/ui/inspectorStyle.css
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-:root {
-    height: 100%;
-    overflow: hidden;
-}
-
-:root {
-    --accent-color: #03a9f4;
-    --accent-color-b: #2196f3;
-    --accent-color-c: #3e82f7;
-    --toolbar-bg-color: #f3f3f3;
-    --toolbar-hover-bg-color: #eaeaea;
-    --selection-fg-color: white;
-    --selection-inactive-bg-color: #dadada;
-    --tab-selected-fg-color: #333;
-    --tab-selected-bg-color: var(--toolbar-bg-color);
-    --drop-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05),
-                   0 2px 4px rgba(0, 0, 0, 0.2),
-                   0 2px 6px rgba(0, 0, 0, 0.1);
-    --divider-color: #d0d0d0;
-    --focus-ring-inactive-shadow: 0 0 0 1px #e0e0e0;
-}
-
-.-theme-with-dark-background {
-    --accent-color: #32699f;
-    --accent-color-b: #2f84da;
-    --accent-color-c: #1f4061;
-    --toolbar-bg-color: #333333;
-    --toolbar-hover-bg-color: #202020;
-    --selection-fg-color: #cdcdcd;
-    --selection-inactive-bg-color: #333333;
-    --tab-selected-fg-color: #eaeaea;
-    --tab-selected-bg-color: black;
-    --drop-shadow: 0 0 0 1px rgba(255, 255, 255, 0.2),
-                   0 2px 4px 2px rgba(0, 0, 0, 0.2),
-                   0 2px 6px 2px rgba(0, 0, 0, 0.1);
-    --divider-color: #525252;
-    --focus-ring-inactive-shadow: 0 0 0 1px #5a5a5a;
-}
-
-:root {
-    --focus-ring-active-shadow: 0 0 0 1px var(--accent-color);
-    --selection-bg-color: var(--accent-color-b);
-    --divider-border: 1px solid var(--divider-color);
-}
-
-body {
-    height: 100%;
-    width: 100%;
-    position: relative;
-    overflow: hidden;
-    margin: 0;
-    cursor: default;
-    font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;
-    font-size: 12px;
-    tab-size: 4;
-    -webkit-user-select: none;
-    color: #222;
-}
-
-.platform-linux {
-    color: rgb(48, 57, 66);
-    font-family: Roboto, Ubuntu, Arial, sans-serif;
-}
-
-.platform-mac {
-    color: rgb(48, 57, 66);
-    font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;
-}
-
-.platform-windows {
-    font-family: 'Segoe UI', Tahoma, sans-serif;
-}
-
-.panel {
-    display: flex;
-    overflow: hidden;
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    z-index: 0;
-    background-color: white;
-}
-
-.panel-sidebar {
-    overflow-x: hidden;
-    background-color: var(--toolbar-bg-color);
-}
-
-iframe.extension {
-    flex: auto;
-    width: 100%;
-    height: 100%;
-}
-
-iframe.panel.extension {
-    display: block;
-    height: 100%;
-}
diff --git a/front_end/ui/inspectorSyntaxHighlight.css b/front_end/ui/inspectorSyntaxHighlight.css
deleted file mode 100644
index 1ea9518..0000000
--- a/front_end/ui/inspectorSyntaxHighlight.css
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-.cm-js-keyword {color: hsl(310, 86%, 36%);}
-.cm-js-number {color: hsl(248, 100%, 41%);}
-.cm-js-comment {color: hsl(120, 100%, 23%); font-style: italic;}
-.cm-js-string {color: hsl(1, 80%, 43%);}
-.cm-js-string-2 {color: hsl(1, 99%, 39%);}
-.cm-js-atom {color: hsl(310, 86%, 36%);}
-.cm-js-def {color: hsl(240, 73%, 38%);}
-.cm-js-operator {color: hsl(27, 100%, 30%);}
-.cm-js-meta {color: hsl(27, 100%, 30%);}
-.cm-js-variable-2 {color: hsl(240, 73%, 38%);}
-
-.cm-css-keyword { color: rgb(7, 144, 154);}
-.cm-css-number {color: rgb(50, 0, 255);}
-.cm-css-comment {color: rgb(0, 116, 0);}
-.cm-css-def {color: rgb(200, 0, 0);}
-.cm-css-meta {color: rgb(200, 0, 0);}
-.cm-css-atom {color: rgb(7, 144, 154);}
-.cm-css-string {color: rgb(7, 144, 154);}
-.cm-css-string-2 {color: rgb(7, 144, 154);}
-.cm-css-link {color: rgb(7, 144, 154);}
-.cm-css-variable {color: rgb(200, 0, 0);}
-.cm-css-variable-2 {color: rgb(0, 0, 128);}
-.cm-css-property, .webkit-css-property {color: rgb(200, 0, 0);}
-
-.cm-xml-meta {color: rgb(192, 192, 192);}
-.cm-xml-comment {color: rgb(35, 110, 37);}
-.cm-xml-string {color: rgb(26, 26, 166);}
-.cm-xml-tag {color: var(--dom-tag-name-color);}
-.cm-xml-attribute {color: rgb(153, 69, 0);}
-.cm-xml-link {color: #00e;}
-
-:root {
-    --dom-tag-name-color: rgb(136, 18, 128);
-    --dom-attribute-name-color: rgb(153, 69, 0);
-}
-
-.webkit-html-comment {
-    /* Keep this in sync with view-source.css (.webkit-html-comment) */
-    color: rgb(35, 110, 37);
-}
-
-.webkit-html-tag {
-    color: rgb(168, 148, 166);
-}
-
-.webkit-html-tag-name, .webkit-html-close-tag-name {
-    /* Keep this in sync with view-source.css (.webkit-html-tag) */
-    color: var(--dom-tag-name-color);
-}
-
-.webkit-html-pseudo-element {
-    /* This one is non-standard. */
-    color: brown;
-}
-
-.webkit-html-js-node,
-.webkit-html-css-node {
-    white-space: pre-wrap;
-}
-
-.webkit-html-text-node {
-    unicode-bidi: -webkit-isolate;
-}
-
-.webkit-html-entity-value {
-    /* This one is non-standard. */
-    background-color: rgba(0, 0, 0, 0.15);
-    unicode-bidi: -webkit-isolate;
-}
-
-.webkit-html-doctype {
-    /* Keep this in sync with view-source.css (.webkit-html-doctype) */
-    color: rgb(192, 192, 192);
-}
-
-.webkit-html-attribute-name {
-    /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */
-    color: var(--dom-attribute-name-color);
-    unicode-bidi: -webkit-isolate;
-}
-
-.webkit-html-attribute-value {
-    /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */
-    color: rgb(26, 26, 166);
-    unicode-bidi: -webkit-isolate;
-}
-
-.devtools-link {
-    color: rgb(17, 85, 204);
-    text-decoration: underline;
-}
-
-.devtools-link [is=ui-icon] {
-    vertical-align: middle;
-}
-
-.devtools-link[data-keyboard-focus="true"]:focus {
-    outline-width: unset;
-}
-
-.devtools-link:not(.devtools-link-prevent-click) {
-    cursor: pointer;
-}
-
-.-theme-with-dark-background .devtools-link,
-:host-context(.-theme-with-dark-background) .devtools-link {
-    color: hsl(0, 0%, 67%);
-}
-
-.webkit-html-end-of-file {
-    /* Keep this in sync with view-source.css (.webkit-html-end-of-file) */
-    color: rgb(255, 0, 0);
-    font-weight: bold;
-}
-
-/* Default CodeMirror Theme */
-.cm-negative {color: #d44;}
-.cm-positive {color: #292;}
-.cm-header, .cm-strong {font-weight: bold;}
-.cm-em {font-style: italic;}
-.cm-link {text-decoration: underline;}
-.cm-strikethrough {text-decoration: line-through;}
-
-.cm-invalidchar {color: #f00;}
-
-.cm-header {color: blue;}
-.cm-quote {color: #090;}
-
-.cm-keyword {color: #708;}
-.cm-atom {color: #219;}
-.cm-number {color: #164;}
-.cm-def {color: #00f;}
-.cm-variable-2 {color: #05a;}
-.cm-variable-3, .cm-type {color: #085;}
-.cm-comment {color: #a50;}
-.cm-string {color: #a11;}
-.cm-string-2 {color: #f50;}
-.cm-meta {color: #555;}
-.cm-qualifier {color: #555;}
-.cm-builtin {color: #30a;}
-.cm-bracket {color: #997;}
-.cm-tag {color: #170;}
-.cm-attribute {color: #00c;}
-.cm-hr {color: #999;}
-.cm-link {color: #00c;}
-
-.cm-error {color: #f00;}
diff --git a/front_end/ui/inspectorSyntaxHighlightDark.css b/front_end/ui/inspectorSyntaxHighlightDark.css
deleted file mode 100644
index 0346373..0000000
--- a/front_end/ui/inspectorSyntaxHighlightDark.css
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.cm-js-atom{color:rgb(161, 247, 181);}
-.cm-js-attribute{color:rgb(97, 148, 198);}
-.cm-js-builtin{color:rgb(159, 180, 214);}
-.cm-js-comment{color:rgb(116, 116, 116);}
-.cm-js-def{color:var(--dom-tag-name-color);}
-.cm-js-keyword{color:rgb(154, 127, 213);}
-.cm-js-link{color:rgb(159, 180, 214);}
-.cm-js-meta{color:rgb(221, 251, 85);}
-.cm-js-number{color:rgb(161, 247, 181);}
-.cm-js-operator{color:rgb(210, 192, 87);}
-.cm-js-property{color:rgb(210, 192, 87);}
-.cm-js-string{color:rgb(242, 139, 84);}
-.cm-js-string-2{color:rgb(242, 139, 84);}
-.cm-js-tag{color:var(--dom-tag-name-color);}
-.cm-js-variable{color:rgb(217, 217, 217);}
-.cm-js-variable-2{color:rgb(217, 217, 217);}
-.cm-atom{color:rgb(161, 247, 181);}
-.cm-comment{color:rgb(116, 116, 116);}
-.cm-variable{color:rgb(217, 217, 217);}
-.cm-string{color:rgb(242, 139, 84);}
-.cm-keyword{color:rgb(154, 127, 213);}
-.cm-number{color:rgb(161, 247, 181);}
-.cm-operator{color:rgb(210, 192, 87);}
-.cm-css-atom{color:rgb(217, 217, 217);}
-.cm-css-builtin{color:rgb(255, 163, 79);}
-.cm-css-def{color:rgb(255, 163, 79);}
-.cm-css-comment{color:rgb(116, 116, 116);}
-.cm-css-meta{color:rgb(132, 240, 255);}
-.cm-css-number{color:rgb(217, 217, 217);}
-.cm-css-operator{color:rgb(217, 217, 217);}
-.cm-css-property{color:rgb(132, 240, 255);}
-.cm-css-qualifier{color:rgb(255, 163, 79);}
-.cm-css-string{color:rgb(231, 194, 111);}
-.cm-css-string-2{color:rgb(217, 217, 217);}
-.cm-css-tag{color:rgb(255, 163, 79);}
-.cm-css-variable{color:rgb(255, 163, 79);}
-.cm-css-variable-2{color:rgb(255, 163, 79);}
-.cm-xml-comment{color:rgb(137, 137, 137);}
-.cm-xml-error{color:rgb(198, 95, 95);}
-.cm-xml-string{color:rgb(242, 151, 102);}
-.cm-xml-tag{color:var(--dom-tag-name-color);}
-.cm-xml-attribute{color:var(--dom-attribute-name-color);}
-.cm-xml-link{color:rgb(231, 194, 111);}
-
-.webkit-html-attribute-name{color:var(--dom-attribute-name-color);}
-.webkit-html-attribute-value{color:rgb(242, 151, 102);}
-.webkit-html-comment{color:rgb(137, 137, 137);}
-.devtools-link{color:rgb(231, 194, 111);}
-.webkit-html-tag{color:var(--dom-tag-name-color);}
-.webkit-html-tag-name{color:var(--dom-tag-name-color);}
-.webkit-html-close-tag-name{color:var(--dom-tag-name-color);}
-.webkit-html-text-node{color:rgb(207, 208, 208);}
-.webkit-html-css-node{color:rgb(207, 208, 208);}
-.webkit-html-js-node{color:rgb(207, 208, 208);}
-.webkit-html-pseudo-element{color:rgb(93, 175, 215);}
-.webkit-css-selector{color:rgb(255, 163, 79);}
-.webkit-css-at-rule{color:rgb(188, 164, 197);}
-.webkit-css-color{color:rgb(255, 163, 79);}
-.webkit-css-comment{color:rgb(116, 116, 116);}
-.webkit-css-important{color:rgb(255, 26, 26);}
-.webkit-css-keyword{color:rgb(255, 163, 79);}
-.webkit-css-number{color:rgb(217, 217, 217);}
-.webkit-css-property{color: rgb(53, 212, 199);}
-.webkit-css-string{color:rgb(231, 194, 111);}
-.webkit-css-url{color:rgb(231, 194, 111);}
-
-.cm-def{color:var(--dom-tag-name-color);}
-.cm-header{color:var(--dom-tag-name-color);}
-.cm-variable-2{color:rgb(217, 217, 217);}
-
-.cm-variable-2 {color: #05a;}
-.cm-variable-3, .cm-type {color: rgb(93, 176, 215);}
-.cm-string {color: rgb(242, 139, 84);}
-.cm-meta {color: #555;}
-.cm-meta {color:rgb(221, 251, 85);}
-.cm-qualifier{color:rgb(255, 163, 79);}
-.cm-builtin{color:rgb(159, 180, 214);}
-.cm-bracket {color: #997;}
-.cm-tag{color:var(--dom-tag-name-color);}
-.cm-attribute{color:rgb(97, 148, 198);}
-.cm-hr {color: #999;}
-.cm-link{color:rgb(159, 180, 214);}
-
-:root {
-    --dom-tag-name-color: rgb(93, 176, 215);
-    --dom-attribute-name-color: rgb(155, 187, 220);
-}
diff --git a/front_end/ui/inspectorViewTabbedPane.css b/front_end/ui/inspectorViewTabbedPane.css
deleted file mode 100644
index c461ce2..0000000
--- a/front_end/ui/inspectorViewTabbedPane.css
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tabbed-pane-header-tab,
-.tabbed-pane-header-tab.selected {
-    height: 26px;
-    margin: 0;
-    border: none;
-    border-left: 2px solid transparent;
-    border-right: 2px solid transparent;
-}
-
-.tabbed-pane-header-tab.selected {
-    border-width: 0 2px 0 2px;
-}
-
-.tabbed-pane-header-contents {
-    margin-left: 0;
-}
-
-.tabbed-pane-left-toolbar {
-    margin-right: 0 !important;
-}
diff --git a/front_end/ui/listWidget.css b/front_end/ui/listWidget.css
deleted file mode 100644
index b1680a3..0000000
--- a/front_end/ui/listWidget.css
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.list {
-    flex: auto 0 1;
-    overflow-y: auto;
-    border: 1px solid rgb(231, 231, 231);
-    flex-direction: column;
-}
-
-.list-separator {
-    background: rgb(231, 231, 231);
-    height: 1px;
-}
-
-.list-item {
-    flex: none;
-    min-height: 30px;
-    display: flex;
-    align-items: center;
-    position: relative;
-    overflow: hidden;
-}
-
-.list-item:hover {
-    background: hsl(0, 0%, 96%);
-}
-
-.controls-container {
-    display: flex;
-    flex-direction: row;
-    justify-content: flex-end;
-    align-items: stretch;
-    pointer-events: none;
-}
-
-.controls-gradient {
-    flex: 0 1 50px;
-}
-
-.list-item:hover .controls-gradient {
-    background-image: linear-gradient(90deg, transparent, hsl(0, 0%, 96%));
-}
-
-.controls-buttons {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    pointer-events: auto;
-    visibility: hidden;
-}
-
-.list-item:hover .controls-buttons {
-    background-color: hsl(0, 0%, 96%);
-    visibility: visible;
-}
-
-.editor-container {
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-    flex: none;
-    background: hsl(0, 0%, 96%);
-    overflow: hidden;
-}
-
-.editor-content {
-    flex: auto;
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-}
-
-.editor-buttons {
-    flex: none;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    justify-content: flex-start;
-    padding: 5px;
-}
-
-.editor-buttons > button {
-    flex: none;
-    margin-right: 10px;
-}
-
-.editor-content input {
-    margin-right: 10px;
-}
-
-.editor-content input.error-input {
-    background-color: white;
-}
diff --git a/front_end/ui/module.json b/front_end/ui/module.json
deleted file mode 100644
index bd5f5a1..0000000
--- a/front_end/ui/module.json
+++ /dev/null
@@ -1,105 +0,0 @@
-{
-    "dependencies": [
-        "platform",
-        "dom_extension",
-        "common",
-        "host"
-    ],
-    "scripts": [
-        "XElement.js",
-        "Widget.js",
-        "View.js",
-        "treeoutline.js",
-        "InspectorView.js",
-        "ActionRegistry.js",
-        "ShortcutRegistry.js",
-        "Context.js",
-        "ContextMenu.js",
-        "GlassPane.js",
-        "Dialog.js",
-        "SyntaxHighlighter.js",
-        "DropTarget.js",
-        "EmptyWidget.js",
-        "FilterBar.js",
-        "FilterSuggestionBuilder.js",
-        "ForwardedInputEventHandler.js",
-        "Fragment.js",
-        "HistoryInput.js",
-        "Icon.js",
-        "Infobar.js",
-        "InplaceEditor.js",
-        "TextEditor.js",
-        "KeyboardShortcut.js",
-        "ListControl.js",
-        "ListModel.js",
-        "ListWidget.js",
-        "Panel.js",
-        "Popover.js",
-        "ProgressIndicator.js",
-        "ResizerWidget.js",
-        "RemoteDebuggingTerminatedScreen.js",
-        "ReportView.js",
-        "RootView.js",
-        "SearchableView.js",
-        "SegmentedButton.js",
-        "SettingsUI.js",
-        "SoftContextMenu.js",
-        "SoftDropDown.js",
-        "SplitWidget.js",
-        "TargetCrashedScreen.js",
-        "TextPrompt.js",
-        "ThrottledWidget.js",
-        "Toolbar.js",
-        "Tooltip.js",
-        "SuggestBox.js",
-        "TabbedPane.js",
-        "UIUtils.js",
-        "ARIAUtils.js",
-        "ZoomManager.js",
-        "ShortcutsScreen.js",
-        "Geometry.js",
-        "XLink.js",
-        "XWidget.js"
-    ],
-    "resources": [
-        "checkboxTextLabel.css",
-        "closeButton.css",
-        "confirmDialog.css",
-        "dialog.css",
-        "dropTarget.css",
-        "emptyWidget.css",
-        "filter.css",
-        "glassPane.css",
-        "infobar.css",
-        "inlineButton.css",
-        "inspectorCommon.css",
-        "inspectorStyle.css",
-        "inspectorSyntaxHighlight.css",
-        "inspectorSyntaxHighlightDark.css",
-        "inspectorViewTabbedPane.css",
-        "listWidget.css",
-        "popover.css",
-        "progressIndicator.css",
-        "radioButton.css",
-        "remoteDebuggingTerminatedScreen.css",
-        "reportView.css",
-        "rootView.css",
-        "searchableView.css",
-        "slider.css",
-        "smallBubble.css",
-        "segmentedButton.css",
-        "softContextMenu.css",
-        "softDropDown.css",
-        "softDropDownButton.css",
-        "splitWidget.css",
-        "toolbar.css",
-        "suggestBox.css",
-        "tabbedPane.css",
-        "targetCrashedScreen.css",
-        "textButton.css",
-        "textPrompt.css",
-        "tooltip.css",
-        "treeoutline.css",
-        "viewContainers.css"
-    ]
-}
diff --git a/front_end/ui/popover.css b/front_end/ui/popover.css
deleted file mode 100644
index 6f0752f..0000000
--- a/front_end/ui/popover.css
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.widget {
-    display: flex;
-    background: white;
-    box-shadow: var(--drop-shadow);
-    border-radius: 2px;
-    overflow: auto;
-    -webkit-user-select: text;
-    line-height: 11px;
-}
-
-.widget.has-padding {
-    padding: 6px;
-}
diff --git a/front_end/ui/progressIndicator.css b/front_end/ui/progressIndicator.css
deleted file mode 100644
index 6844f60..0000000
--- a/front_end/ui/progressIndicator.css
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.progress-indicator-shadow-stop-button {
-    background-color: rgb(216, 0, 0) !important;
-    border: 0;
-    width: 10px;
-    height: 12px;
-    border-radius: 2px;
-}
-
-.progress-indicator-shadow-container {
-    display: flex;
-    flex: 1 0 auto;
-    align-items: center;
-}
-
-.progress-indicator-shadow-container .title {
-    text-overflow: ellipsis;
-    overflow: hidden;
-    max-width: 150px;
-    margin-right: 2px;
-    color: #777;
-}
-
-.progress-indicator-shadow-container progress {
-    flex: auto;
-    margin: 0 2px;
-    width: 100px
-}
diff --git a/front_end/ui/radioButton.css b/front_end/ui/radioButton.css
deleted file mode 100644
index 47f4775..0000000
--- a/front_end/ui/radioButton.css
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-::content .dt-radio-button {
-    height: 17px;
-    width: 17px;
-    min-width: 17px;
-    border: 1px solid rgb(165, 165, 165);
-    background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
-    border-radius: 8px;
-    -webkit-appearance: none;
-    vertical-align: middle;
-    margin: 0 5px 5px 0;
-}
-
-::content .dt-radio-button:active:not(:disabled) {
-    background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
-}
-
-::content .dt-radio-button:checked {
-    background: url(Images/radioDot.png) center no-repeat,
-                linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
-}
-
-::content .dt-radio-button:checked:active {
-    background: url(Images/radioDot.png) center no-repeat,
-                linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
-}
diff --git a/front_end/ui/remoteDebuggingTerminatedScreen.css b/front_end/ui/remoteDebuggingTerminatedScreen.css
deleted file mode 100644
index 84916e1..0000000
--- a/front_end/ui/remoteDebuggingTerminatedScreen.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.widget {
-    padding: 20px;
-}
-
-.message, .button {
-    font-size: larger;
-    white-space: pre;
-    margin: 5px;
-}
-
-.button {
-    text-align: center;
-    margin-top: 10px;
-}
-
-.reason {
-    color: #8b0000;
-}
diff --git a/front_end/ui/reportView.css b/front_end/ui/reportView.css
deleted file mode 100644
index 50c2f2f..0000000
--- a/front_end/ui/reportView.css
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    background-color: #f9f9f9;
-}
-
-.report-content-box {
-    background-color: white;
-    white-space: nowrap;
-    overflow: auto;
-}
-
-.report-content-box.no-scroll {
-    overflow: visible;
-}
-
-.report-header {
-    border-bottom: 1px solid rgb(230, 230, 230);
-    padding: 12px 24px;
-}
-
-.report-header .toolbar {
-    margin-bottom: -8px;
-}
-
-.report-header .toolbar {
-    margin-top: 5px;
-    margin-left: -8px;
-}
-
-.report-title {
-    font-size: 15px;
-}
-
-.report-url, .report-subtitle {
-    font-size: 12px;
-    margin-top: 10px;
-}
-
-.report-section {
-    display: flex;
-    padding: 12px;
-    border-bottom: 1px solid rgb(230, 230, 230);
-    flex-direction: column;
-}
-
-.report-section-header {
-    margin-left: 18px;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-}
-
-.report-section-title {
-    flex: auto;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    font-weight: bold;
-    color: #555;
-}
-
-.report-field {
-    margin-top: 8px;
-    display: flex;
-    line-height: 28px;
-}
-
-.report-row {
-    margin: 10px 0 2px 18px;
-}
-
-.report-field-name {
-    color: #888;
-    flex: 0 0 128px;
-    text-align: right;
-    padding: 0 6px;
-    white-space: pre;
-}
-
-.report-field-value {
-    flex: auto;
-    padding: 0 6px;
-    white-space: pre;
-}
-
-.report-field-value-subtitle {
-    color: #888;
-    line-height: 14px;
-}
diff --git a/front_end/ui/rootView.css b/front_end/ui/rootView.css
deleted file mode 100644
index c6f8964..0000000
--- a/front_end/ui/rootView.css
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.root-view {
-    background-color: white;
-    overflow: hidden;
-    position: absolute !important;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-}
diff --git a/front_end/ui/searchableView.css b/front_end/ui/searchableView.css
deleted file mode 100644
index 6ea9c1a..0000000
--- a/front_end/ui/searchableView.css
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.search-bar {
-    flex: 0 0 31px;
-    background-color: #eee;
-    border-top: 1px solid #ccc;
-    display: flex;
-    overflow: hidden;
-    z-index: 0;
-}
-
-.search-bar.replaceable {
-    flex: 0 0 57px;
-}
-
-.search-replace {
-    -webkit-appearance: none;
-    border: 0;
-    padding: 0 3px;
-    margin: 0;
-    flex: 1;
-}
-
-.search-replace:focus {
-    outline: none;
-}
-
-.toolbar-search {
-    display: flex;
-    width: 100%;
-}
-
-.toolbar-search > div {
-    margin: 2px 2px;
-    flex-shrink: 0;
-}
-
-.toolbar-search-inputs {
-    flex-grow: 1;
-    min-width: 150px;
-}
-
-.toolbar-search-navigation-controls {
-    align-self: stretch;
-}
-
-.toolbar-search-navigation {
-    display: inline-block;
-    width: 20px;
-    height: 20px;
-    background-repeat: no-repeat;
-    background-position: 4px 7px;
-    border-left: 1px solid rgb(170, 170, 170);
-    opacity: 0.3;
-}
-
-.toolbar-search-navigation.enabled {
-    opacity: 1.0;
-}
-
-.toolbar-search button.search-action-button {
-    font-weight: 400;
-    height: 22px;
-    width: 87px;
-}
-
-.toolbar-search-control {
-    display: -webkit-flex;
-    position: relative;
-    background-color: white;
-}
-
-.toolbar-search-buttons {
-    display: flex;
-    flex-direction: column;
-}
-
-.toolbar-replace-control,
-#search-input-field {
-    margin-top: 1px;
-    line-height: 17px;
-}
-
-.toolbar-search-control, .toolbar-replace-control {
-    border: 1px solid rgb(163, 163, 163);
-    height: 22px;
-    border-radius: 2px;
-    width: 100%;
-    margin-top: 2px;
-    margin-bottom: 2px;
-}
-
-.toolbar-search-navigation.enabled:active {
-    background-position: 4px 7px, 0 0;
-}
-
-.toolbar-search-navigation.toolbar-search-navigation-prev {
-    background-image: url(Images/searchPrev.png);
-    border-left: 1px solid rgb(163, 163, 163);
-}
-
-:host-context(.-theme-with-dark-background) .toolbar-search-navigation {
-    -webkit-filter: invert(90%);
-}
-
-.toolbar-search-navigation.toolbar-search-navigation-prev.enabled:active {
-    background-image: url(Images/searchPrev.png), #f2f2f2;
-}
-
-.toolbar-search-navigation.toolbar-search-navigation-next {
-    background-image: url(Images/searchNext.png);
-    border-left: 1px solid rgb(230, 230, 230);
-}
-
-.toolbar-search-navigation.toolbar-search-navigation-next.enabled:active {
-    background-image: url(Images/searchNext.png), #f2f2f2;
-}
-
-.search-results-matches {
-    display: inline-block;
-    text-align: right;
-    padding: 0 4px;
-    color: rgb(165, 165, 165);
-    align-self: center;
-}
-
-.first-row-buttons {
-    display: flex;
-    justify-content: space-between;
-}
-
-.toolbar-search > .replace-toggle-toolbar {
-    margin: 2px -2px 0 0;
-}
-
-.toolbar-search-options {
-    margin: 0 auto;
-}
diff --git a/front_end/ui/segmentedButton.css b/front_end/ui/segmentedButton.css
deleted file mode 100644
index 725b487..0000000
--- a/front_end/ui/segmentedButton.css
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.segmented-button {
-  align-items: center;
-  align-content: center;
-  display: flex;
-}
-
-.segmented-button-segment {
-  background-color: white;
-  border: var(--divider-border);
-  border-right-style: none;
-  color: #5a5a5a;
-  flex: 1 1 0;
-  font-weight: 700;
-  margin-left: -1px;
-  padding: 4px 16px;
-}
-
-.segmented-button-segment:hover {
-  background-color: #F4F4F4;
-  color: #333;
-}
-
-.segmented-button-segment:first-child {
-  border-bottom-left-radius: 4px;
-  border-top-left-radius: 4px;
-}
-
-.segmented-button-segment:last-child {
-  border-bottom-right-radius: 4px;
-  border-right-style: solid;
-  border-top-right-radius: 4px;
-}
-
-.segmented-button-segment.segmented-button-segment-selected {
-  background-color: hsl(218, 81%, 59%);
-  border-color: transparent;
-  color: #FAFAFA;
-}
-
-.segmented-button-segment.segmented-button-segment-selected:hover {
-  background-color: hsl(218, 81%, 62%);
-  color: #FFF;
-}
-
-/* Remove a border between the selected button and its siblin */
-.segmented-button-segment-selected + .segmented-button-segment {
-  border-left-color: transparent;
-}
diff --git a/front_end/ui/slider.css b/front_end/ui/slider.css
deleted file mode 100644
index 6210c94..0000000
--- a/front_end/ui/slider.css
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.dt-range-input {
-    -webkit-appearance: none;
-    margin: 0;
-    padding: 0;
-    height: 10px;
-    width: 88px;
-    outline: none;
-    background: none;
-}
-
-.dt-range-input::-webkit-slider-thumb, -theme-preserve {
-    -webkit-appearance: none;
-    margin: 0;
-    padding: 0;
-    border: 0;
-    width: 12px;
-    height: 12px;
-    margin-top: -5px;
-    border-radius: 50%;
-    background-color: #4285F4;
-}
-
-.dt-range-input::-webkit-slider-runnable-track {
-    -webkit-appearance: none;
-    margin: 0;
-    padding: 0;
-    width: 100%;
-    height: 2px;
-    background-color: rgba(0, 0, 0, 0.26);
-}
-
-.dt-range-input:focus::-webkit-slider-thumb, -theme-preserve {
-    box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.4);
-}
-
-.dt-range-input:disabled::-webkit-slider-thumb {
-    background-color: #bdbdbd;
-}
diff --git a/front_end/ui/smallBubble.css b/front_end/ui/smallBubble.css
deleted file mode 100644
index 856890b..0000000
--- a/front_end/ui/smallBubble.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-div {
-    display: inline-block;
-    height: 14px;
-    vertical-align: middle;
-    white-space: nowrap;
-    padding: 1px 4px;
-    text-align: left;
-    font-size: 11px;
-    line-height: normal;
-    font-weight: bold;
-    text-shadow: none;
-    color: white;
-    margin-top: -1px;
-    border-radius: 7px;
-}
-
-div.verbose {
-    background-color: rgb(0, 0, 255);
-}
-
-div.info {
-    background-color: rgb(128, 151, 189);
-}
-
-div.warning {
-    background-color: rgb(232, 164, 0);
-}
-
-div.error {
-    background-color: rgb(216, 35, 35);
-}
diff --git a/front_end/ui/softContextMenu.css b/front_end/ui/softContextMenu.css
deleted file mode 100644
index c49a1b0..0000000
--- a/front_end/ui/softContextMenu.css
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.soft-context-menu {
-    border: 1px solid rgba(196, 196, 196, 0.9);
-    border-top: 1px solid rgba(196, 196, 196, 0.5);
-    /* NOTE: Keep padding in sync with padding adjustment in SoftContextMenu.js */
-    padding: 4px 0 4px 0;
-    border-radius: 4px;
-    background-color: rgb(240, 240, 240);
-    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25);
-    overflow-y: auto;
-    min-width: 160px !important;
-}
-
-:host-context(.-theme-with-dark-background) .soft-context-menu {
-    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25);
-}
-
-.soft-context-menu-item {
-    display: flex;
-    width: 100%;
-    line-height: 14px;
-    font-size: 12px;
-    border-top: 1px solid transparent;
-    border-bottom: 1px solid transparent;
-    padding: 2px 7px 2px 8px;
-    margin: 0 13px 0 0;
-    white-space: nowrap;
-}
-
-.soft-context-menu-disabled {
-    color: #999;
-    pointer-events: none;
-}
-
-.soft-context-menu-separator {
-    height: 10px;
-    margin: 0 1px;
-}
-
-.soft-context-menu-separator > .separator-line {
-    margin: 0;
-    height: 5px;
-    border-bottom: 1px solid rgb(222, 222, 222);
-    pointer-events: none;
-}
-
-.soft-context-menu-item-mouse-over,
-.-theme-selection-color {
-    border-top: 1px solid var(--selection-bg-color);
-    border-bottom: 1px solid var(--selection-bg-color);
-    background-color: var(--selection-bg-color);
-    color: white;
-}
-
-:host-context(.platform-mac) .soft-context-menu-item-mouse-over, -theme-preserve {
-    border-top: 1px solid transparent;
-    border-bottom: 1px solid transparent;
-    background-image: linear-gradient(to right, hsl(214, 81%, 60%), hsl(214, 100%, 56%));
-}
-
-:host-context(.platform-mac) .separator-line {
-    border-width: 2px;
-}
-
-.soft-context-menu-item-submenu-arrow {
-    color: #222;
-    pointer-events: none;
-    font-size: 11px;
-    flex: 1 1 auto;
-    text-align: right;
-}
-
-.soft-context-menu-item-mouse-over .soft-context-menu-item-checkmark {
-    color: var(--selection-fg-color);
-}
-
-.soft-context-menu-custom-item {
-    display: inline-flex;
-    justify-content: center;
-    align-items: center;
-    flex: auto;
-}
-
-.soft-context-menu-shortcut {
-    color: gray;
-    pointer-events: none;
-    flex: 1 1 auto;
-    text-align: right;
-    padding-left: 10px;
-}
-
-.soft-context-menu-item-mouse-over .soft-context-menu-shortcut {
-    color: inherit;
-}
-
-.checkmark {
-    opacity: 0.7;
-    pointer-events: none;
-    margin: auto 5px auto 0px;
-}
-
-.soft-context-menu-item-mouse-over .checkmark {
-    opacity: 1;
-}
diff --git a/front_end/ui/softDropDown.css b/front_end/ui/softDropDown.css
deleted file mode 100644
index 7b14baf..0000000
--- a/front_end/ui/softDropDown.css
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.item.disabled {
-    opacity: 0.5;
-}
-
-.item-list {
-    background-color: white;
-    box-shadow: var(--drop-shadow);
-    overflow-x: hidden;
-    overflow-y: auto;
-    width: 100%;
-}
-
-.item.highlighted {
-    color: var(--selection-fg-color);
-    background-color: var(--selection-bg-color);
-}
diff --git a/front_end/ui/softDropDownButton.css b/front_end/ui/softDropDownButton.css
deleted file mode 100644
index 689c27b..0000000
--- a/front_end/ui/softDropDownButton.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-:host {
-    height: 26px;
-    text-align: left;
-    position: relative;
-    border: none;
-    background: none;
-}
-
-:host([disabled]) {
-    opacity: .5;
-}
-
-:host .title {
-    padding-right: 5px;
-    width: 120px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-:host([data-keyboard-focus="true"]:focus)::before {
-    content: "";
-    position: absolute;
-    top: 2px;
-    left: 2px;
-    right: 2px;
-    bottom: 2px;
-    border-radius: 2px;
-    background: rgba(0, 0, 0, 0.08);
-}
-
-:host(.warning) {
-    background: #ffd7d7 !important;
-}
diff --git a/front_end/ui/splitWidget.css b/front_end/ui/splitWidget.css
deleted file mode 100644
index 1702593..0000000
--- a/front_end/ui/splitWidget.css
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-:host {
-    overflow: hidden;
-}
-
-.shadow-split-widget {
-    display: flex;
-    overflow: hidden;
-}
-
-.shadow-split-widget-contents {
-    display: flex;
-    position: relative;
-    flex-direction: column;
-    contain: layout size style;
-}
-
-.shadow-split-widget-sidebar {
-    flex: none;
-}
-
-.shadow-split-widget-main, .shadow-split-widget-sidebar.maximized {
-    flex: auto;
-}
-
-.shadow-split-widget.hbox > .shadow-split-widget-resizer {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    width: 6px;
-    z-index: 500;
-}
-
-.shadow-split-widget.vbox > .shadow-split-widget-resizer {
-    position: absolute;
-    left: 0;
-    right: 0;
-    height: 6px;
-    z-index: 500;
-}
-
-.shadow-split-widget.hbox.shadow-split-widget-first-is-sidebar {
-    flex-direction: row-reverse !important;
-}
-
-.shadow-split-widget.vbox.shadow-split-widget-first-is-sidebar {
-    flex-direction: column-reverse !important;
-}
-
-.shadow-split-widget-resizer-border {
-    pointer-events: none;
-}
-
-.shadow-split-widget.vbox > .shadow-split-widget-sidebar.no-default-splitter {
-    border: 0 !important;
-}
-
-.shadow-split-widget.vbox > .shadow-split-widget-sidebar:not(.maximized) {
-    border: 0;
-    border-top: 1px solid var(--divider-color);
-}
-
-.shadow-split-widget.vbox.shadow-split-widget-first-is-sidebar > .shadow-split-widget-sidebar:not(.maximized) {
-    border: 0;
-    border-bottom: 1px solid var(--divider-color);
-}
-
-.shadow-split-widget.hbox > .shadow-split-widget-sidebar:not(.maximized) {
-    border: 0;
-    border-left: 1px solid var(--divider-color);
-}
-
-.shadow-split-widget.hbox.shadow-split-widget-first-is-sidebar > .shadow-split-widget-sidebar:not(.maximized) {
-    border: 0;
-    border-right: 1px solid var(--divider-color);
-}
diff --git a/front_end/ui/suggestBox.css b/front_end/ui/suggestBox.css
deleted file mode 100644
index 9bc8647..0000000
--- a/front_end/ui/suggestBox.css
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-:host {
-    display: flex;
-    flex: auto;
-}
-
-.suggest-box {
-    flex: auto;
-    background-color: #FFFFFF;
-    pointer-events: auto;
-    margin-left: -3px;
-    box-shadow: var(--drop-shadow);
-    overflow-x: hidden;
-}
-
-.suggest-box-content-item {
-    padding: 1px 0 1px 1px;
-    margin: 0;
-    border: 1px solid transparent;
-    white-space: nowrap;
-    display: flex;
-}
-
-.suggest-box-content-item.secondary {
-    background-color: #f9f9f9;
-}
-
-.suggestion-title {
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.suggestion-subtitle {
-    flex: auto;
-    text-align: right;
-    color: #999;
-    margin-right: 3px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.suggestion-icon {
-    user-select: none;
-    align-self: center;
-    flex-shrink: 0;
-}
-
-.suggest-box-content-item .query {
-    font-weight: bold;
-}
-
-.suggest-box-content-item .spacer {
-    display: inline-block;
-    width: 20px;
-}
-
-.suggest-box-content-item.selected {
-    background-color: var(--selection-bg-color);
-}
-
-.suggest-box-content-item.selected > span {
-    color: var(--selection-fg-color);
-}
-
-.default-selection-is-dimmed .suggest-box-content-item.selected {
-    background-color: #E0E0E0;
-}
-
-.default-selection-is-dimmed .suggest-box-content-item.selected > span {
-    color: inherit;
-}
-
-.user-has-interacted .suggest-box-content-item.selected {
-    background-color: var(--selection-bg-color);
-}
-
-.user-has-interacted .suggest-box-content-item.selected > span {
-   color: var(--selection-fg-color);
-}}
-
-.suggest-box-content-item:hover:not(.selected) {
-    background-color: rgba(56, 121, 217, 0.1);
-}
diff --git a/front_end/ui/tabbedPane.css b/front_end/ui/tabbedPane.css
deleted file mode 100644
index fff7248..0000000
--- a/front_end/ui/tabbedPane.css
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.tabbed-pane {
-    flex: auto;
-    overflow: hidden;
-}
-
-.tabbed-pane-content {
-    position: relative;
-    overflow: auto;
-    flex: auto;
-    display: flex;
-    flex-direction: column;
-}
-
-.tabbed-pane-content.has-no-tabs {
-    background-color: lightgray;
-}
-
-.tabbed-pane-placeholder {
-    font-size: 14px;
-    text-align: center;
-    margin-top: 20px;
-    text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
-    line-height: 28px;
-    overflow: hidden;
-}
-
-.tabbed-pane-placeholder-row {
-    display: flex;
-    white-space: nowrap;
-}
-
-.tabbed-pane-placeholder-key {
-    flex: 1;
-    text-align: right;
-    padding-right: 14px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.tabbed-pane-placeholder-value {
-    flex: 1;
-    text-align: left;
-    padding-left: 14px;
-}
-
-.tabbed-pane-header {
-    display: flex;
-    flex: 0 0 27px;
-    border-bottom: 1px solid #ccc;
-    overflow: visible;
-    width: 100%;
-    background-color: var(--toolbar-bg-color);
-}
-
-.tabbed-pane-header-contents {
-    flex: auto;
-    pointer-events: none;
-    margin-left: 0;
-    position: relative;
-}
-
-.tabbed-pane-header-contents > * {
-    pointer-events: initial;
-}
-
-.tabbed-pane-header-tab-icon {
-    min-width: 14px;
-    display: flex;
-    align-items: center;
-    margin-right: 2px;
-}
-
-.tabbed-pane-header-tab {
-    float: left;
-    padding: 2px 0.8em;
-    height: 26px;
-    line-height: 15px;
-    white-space: nowrap;
-    cursor: default;
-    display: flex;
-    align-items: center;
-    color: #5a5a5a;
-}
-
-.tabbed-pane-header-tab.closeable {
-    padding-right: 4px;
-}
-
-.tabbed-pane-header-tab:hover,
-.tabbed-pane-shadow .tabbed-pane-header-tab[data-keyboard-focus="true"]:focus {
-    color: #333;
-    background-color: var(--toolbar-hover-bg-color);
-}
-
-.tabbed-pane-header-tab-title {
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.tabbed-pane-header-tab.measuring {
-    visibility: hidden;
-}
-
-.tabbed-pane-header-tab.selected {
-    border-bottom: none;
-}
-
-.tabbed-pane-header-tab.selected {
-    background-color: var(--tab-selected-bg-color);
-    color: var(--tab-selected-fg-color);
-}
-
-.tabbed-pane-header-tab.dragging {
-    position: relative;
-    box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37);
-    background-color: #e5e5e5;
-}
-
-.tabbed-pane-header-tab .tabbed-pane-close-button {
-    margin: 0 -3px 0 4px;
-    visibility: hidden;
-}
-
-.tabbed-pane-header-tab:hover .tabbed-pane-close-button,
-.tabbed-pane-header-tab.selected .tabbed-pane-close-button {
-    visibility: visible;
-}
-
-.tabbed-pane-header-tabs-drop-down-container {
-    float: left;
-    opacity: 0.8;
-    cursor: pointer;
-    display: flex;
-    align-items: center;
-    height: 100%;
-}
-
-.tabbed-pane-header-tabs-drop-down-container > .chevron-icon {
-    background-color: hsla(0,0%,20%,1);
-    display: block;
-}
-
-.tabbed-pane-header-tabs-drop-down-container:hover {
-    background-color: rgb(229, 229, 229);
-}
-
-.tabbed-pane-header-tabs-drop-down-container.measuring {
-    visibility: hidden;
-}
-
-.tabbed-pane-header-tabs-drop-down-container:hover {
-    opacity: 1.0;
-}
-
-.tabbed-pane-header-tabs-drop-down-container:active {
-    opacity: 0.8;
-}
-
-/* Web page style */
-
-.tabbed-pane-shadow.vertical-tab-layout {
-    flex-direction: row !important;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header {
-    background-color: transparent;
-    border: none transparent !important;
-    width: auto;
-    flex: 0 0 auto;
-    flex-direction: column;
-    padding-top: 10px;
-    overflow: hidden;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-content {
-    padding: 10px 10px 10px 0;
-    overflow-x: hidden;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-contents {
-    margin: 0;
-    flex: none;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tabs {
-    display: flex;
-    flex-direction: column;
-    width: 120px;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tab {
-    background-color: transparent;
-    border: none transparent;
-    font-weight: normal;
-    text-shadow: none;
-    color: #777;
-    height: 26px;
-    padding-left: 10px;
-    border-left: 6px solid transparent;
-    margin: 0;
-    display: flex;
-    align-items: center;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tab:not(.selected) {
-    cursor: pointer !important;
-}
-
-.tabbed-pane-shadow.vertical-tab-layout .tabbed-pane-header-tab.selected {
-    color: inherit;
-    border: none transparent;
-    border-left: 6px solid #666;
-}
-
-.tabbed-pane-tab-slider {
-    height: 2px;
-    position: absolute;
-    bottom: -1px;
-    background-color: #03a9f4;
-    left: 0;
-    z-index: 50;
-    transform-origin: 0 100%;
-    transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);
-    visibility: hidden;
-}
-
-:host-context(.-theme-with-dark-background) .tabbed-pane-tab-slider {
-    display: none;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-    .tabbed-pane-tab-slider {
-        border-top: none;
-    }
-}
-
-.tabbed-pane-tab-slider.enabled {
-    visibility: visible;
-}
-
-.tabbed-pane-header-tab.disabled {
-    opacity: 0.5;
-    pointer-events: none;
-}
-
-.tabbed-pane-left-toolbar {
-    margin-right: -4px;
-    flex: none;
-}
-
-.tabbed-pane-right-toolbar {
-    margin-left: -4px;
-    flex: none;
-}
diff --git a/front_end/ui/targetCrashedScreen.css b/front_end/ui/targetCrashedScreen.css
deleted file mode 100644
index 037c3d5..0000000
--- a/front_end/ui/targetCrashedScreen.css
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.widget {
-    padding: 25px;
-}
-
-.message {
-    font-size: larger;
-    white-space: pre;
-    margin: 5px;
-}
diff --git a/front_end/ui/textButton.css b/front_end/ui/textButton.css
deleted file mode 100644
index 001189a..0000000
--- a/front_end/ui/textButton.css
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    margin: 2px;
-    height: 24px;
-    font-size: 12px;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-    border-radius: 2px;
-    padding: 0px 12px;
-    font-weight: 500;
-    color: #333;
-    background-color: #fff;
-    flex: none;
-    white-space: nowrap;
-}
-
-:host(:not(:disabled):focus),
-:host(:not(:disabled):hover),
-:host(:not(:disabled):active) {
-    background-color: var(--toolbar-bg-color);
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-    cursor: pointer;
-}
-
-:host(:not(:disabled):active) {
-    background-color: #f2f2f2;
-}
-
-:host(:not(:disabled):focus) {
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(66, 133, 244, 0.4);
-}
-
-:host(:disabled) {
-    opacity: 0.38;
-}
-
-:host(.primary-button), -theme-preserve {
-    background-color: #4285F4;
-    border: none;
-    color: #fff;
-}
-
-:host(.primary-button:not(:disabled):focus),
-:host(.primary-button:not(:disabled):hover), -theme-preserve {
-    background-color: #3B78E7;
-}
-
-:host(.primary-button:not(:disabled):active), -theme-preserve {
-    background-color: #3367D6;
-}
-
-:host-context(.-theme-with-dark-background):host(:not(.primary-button):not(:disabled):focus),
-:host-context(.-theme-with-dark-background):host(:not(.primary-button):not(:disabled):hover),
-:host-context(.-theme-with-dark-background):host(:not(.primary-button):not(:disabled):active) {
-    background-color: #313131;
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-:host-context(.-theme-with-dark-background):host(:not(.primary-button):not(:disabled):focus) {
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(94, 151, 246, 0.6);
-}
-
-:host-context(.-theme-with-dark-background):host(:not(.primary-button):not(:disabled):active) {
-    background-color: #3e3e3e;
-}
diff --git a/front_end/ui/textPrompt.css b/front_end/ui/textPrompt.css
deleted file mode 100644
index 052cc2d..0000000
--- a/front_end/ui/textPrompt.css
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.text-prompt-root {
-    display: flex;
-    align-items: center;
-}
-
-.text-prompt-editing {
-    box-shadow: var(--drop-shadow);
-    background-color: white;
-    text-overflow: clip !important;
-    padding-left: 2px;
-    margin-left: -2px;
-    padding-right: 2px;
-    margin-right: -2px;
-    margin-bottom: -1px;
-    padding-bottom: 1px;
-    opacity: 1.0 !important;
-}
-
-.text-prompt-editing,
-.text-prompt-editing ::content * {
-    color: #222 !important;
-    text-decoration: none !important;
-    white-space: pre;
-}
-
-::content .auto-complete-text {
-    color: rgb(128, 128, 128) !important;
-}
-
-::content .text-prompt[data-placeholder]:empty::before {
-    content: attr(data-placeholder);
-    color: rgb(128, 128, 128);
-}
-
-::content .text-prompt:not([data-placeholder]):empty::after {
-    content: '\00A0';
-    width: 0;
-    display: block;
-}
-
-::content .text-prompt {
-    cursor: text;
-}
-
-::content .text-prompt.disabled {
-    opacity: 0.5;
-    cursor: default;
-}
-
-.text-prompt-editing ::content br {
-    display: none;
-}
diff --git a/front_end/ui/toolbar.css b/front_end/ui/toolbar.css
deleted file mode 100644
index 4ef66dd..0000000
--- a/front_end/ui/toolbar.css
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    flex: none;
-    padding: 0 2px;
-}
-
-.toolbar-shadow {
-    position: relative;
-    white-space: nowrap;
-    height: 26px;
-    overflow: hidden;
-    z-index: 12;
-    display: flex;
-    flex: none;
-    align-items: center;
-}
-
-.toolbar-shadow.wrappable {
-    flex-wrap: wrap;
-    overflow: visible;
-}
-
-.toolbar-shadow.wrappable-reverse {
-    flex-direction: row-reverse;
-}
-
-.toolbar-shadow.toolbar-grow-vertical {
-    height: initial;
-}
-
-.toolbar-shadow.vertical {
-    flex-direction: column;
-    height: auto;
-    align-items: flex-start;
-}
-
-.toolbar-item {
-    position: relative;
-    display: flex;
-    background-color: transparent;
-    flex: none;
-    align-items: center;
-    justify-content: center;
-    padding: 0;
-    height: 26px;
-    border: none;
-    color: #5a5a5a;
-}
-
-select.toolbar-item:disabled {
-    opacity: 0.5;
-}
-
-.toolbar-dropdown-arrow {
-    background-color: #6D6D6D;
-    pointer-events: none;
-    flex: none;
-}
-
-select.toolbar-item:disabled + .toolbar-dropdown-arrow {
-    opacity: 0.5;
-}
-
-/* Toolbar item */
-
-.toolbar-button {
-    white-space: nowrap;
-    overflow: hidden;
-    min-width: 28px;
-    background: transparent;
-    border-radius: 0;
-}
-
-.toolbar-text {
-    margin: 0 5px;
-    flex: none;
-    color: #5a5a5a;
-}
-
-.toolbar-text:empty {
-    margin: 0;
-}
-
-.toolbar-has-dropdown {
-    justify-content: space-between;
-    padding: 0 3px 0 5px;
-}
-
-.toolbar-has-dropdown .toolbar-text {
-    margin: 0 4px 0 0;
-    text-overflow: ellipsis;
-    flex: auto;
-    overflow: hidden;
-    text-align: right;
-}
-
-.toolbar-button.dark-text .toolbar-dropdown-arrow {
-    background-color: #333;
-}
-
-.toolbar-has-glyph .toolbar-text {
-    margin-left: -4px;
-}
-
-.toolbar-button:not(.toolbar-has-glyph):not(.toolbar-has-dropdown):not(.largeicon-menu) {
-    font-weight: bold;
-}
-
-.toolbar-render-as-links * {
-    font-weight: initial;
-    color: rgb(17, 85, 204);
-    text-decoration: underline;
-    cursor: pointer;
-}
-
-.toolbar-toggled-gray:not(.toolbar-render-as-links) .toolbar-button:not(.toolbar-has-glyph):not(.toolbar-has-dropdown):not(.largeicon-menu):hover {
-    background-color: var(--toolbar-bg-color);
-}
-
-.toolbar-glyph {
-    background-color: #5a5a5a;
-    flex: none;
-}
-
-/* Button */
-
-.toolbar-button:disabled {
-    opacity: 0.5;
-}
-
-.toolbar-button.dark-text .toolbar-text{
-    color: #333 !important;
-}
-
-:not(.toolbar-render-as-links) .toolbar-button:enabled:hover:not(:active) .toolbar-glyph {
-    background-color: #333;
-}
-
-:not(.toolbar-render-as-links) .toolbar-button:enabled:hover:not(:active) .toolbar-text {
-    color: #333;
-}
-
-.toolbar-button.toolbar-state-on .toolbar-glyph,
-.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover:not(:active),
-.-theme-selection-color {
-    background-color: var(--accent-color-b);
-}
-
-.toolbar-button.toolbar-state-on .toolbar-text,
-.-theme-selection-color {
-    color: var(--accent-color-b);
-}
-
-.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover .toolbar-glyph {
-    background-color: white;
-}
-
-.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover .toolbar-text {
-    color: white;
-}
-
-.toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-glyph,
-.toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:active:hover,
-.-theme-selection-color {
-    background-color: var(--accent-color-b);
-}
-
-.toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-text,
-.-theme-selection-color {
-    color: var(--accent-color-b);
-}
-
-.toolbar-toggled-gray .toolbar-button.toolbar-state-on {
-    background-color: var(--toolbar-bg-color) !important;
-}
-
-.toolbar-button.toolbar-state-on.toolbar-toggle-with-red-color .toolbar-glyph,
-.toolbar-button.toolbar-state-off.toolbar-default-with-red-color .toolbar-glyph {
-    background-color: rgb(216, 0, 0) !important;
-}
-
-:host-context(.-theme-with-dark-background) .toolbar-button.toolbar-state-on.toolbar-toggle-with-red-color .toolbar-glyph,
-:host-context(.-theme-with-dark-background) .toolbar-button.toolbar-state-off.toolbar-default-with-red-color .toolbar-glyph {
-    background-color: hsl(0, 100%, 65%) !important;
-}
-
-
-/* Checkbox */
-
-.toolbar-item.checkbox {
-    padding: 0 5px 0 2px;
-}
-
-.toolbar-item.checkbox:hover {
-    color: #333;
-}
-
-/* Select */
-
-.toolbar-select-container {
-    display: inline-flex;
-    flex-shrink: 0;
-    margin-right: 6px;
-}
-
-select.toolbar-item {
-    min-width: 38px;
-    -webkit-appearance: none;
-    border: 0;
-    border-radius: 0;
-    padding: 0 13px 0 5px;
-    margin-right: -10px;
-    position: relative;
-    height: 22px;
-    margin-top: 2px;
-    margin-bottom: 2px;
-}
-
-select.toolbar-item[data-keyboard-focus="true"]:focus {
-    background: rgba(0, 0, 0, 0.08);
-    border-radius: 2px;
-}
-
-select.toolbar-item[data-keyboard-focus="true"]:focus > * {
-    background: white;
-}
-
-/* Input */
-
-.toolbar-input {
-    width: 120px;
-    height: 19px;
-    padding: 4px 3px 3px 3px;
-    margin: 1px 3px;
-    background-color: white;
-    border: 1px solid transparent ;
-    min-width: 35px;
-}
-
-.toolbar-input:hover {
-    box-shadow: var(--focus-ring-inactive-shadow);
-}
-
-.toolbar-input.focused {
-    box-shadow: var(--focus-ring-active-shadow);
-}
-
-.toolbar-input > input {
-    border: none;
-    flex-grow: 1;
-}
-
-.toolbar-input-clear-button {
-    opacity: 0.7;
-    flex-basis: 13px;
-    flex-shrink: 0;
-    height: 16px;
-}
-
-.toolbar-input-clear-button:hover {
-    opacity: 1;
-}
-
-.toolbar-input-empty .toolbar-input-clear-button {
-    display: none;
-}
-
-.toolbar-prompt-proxy {
-    flex: 1;
-}
-
-.toolbar-input-prompt {
-    flex: 1;
-    overflow: hidden;
-    white-space: nowrap;
-    cursor: auto;
-}
-
-/* Separator */
-
-.toolbar-divider {
-    background-color: #ccc;
-    width: 1px;
-    margin: 5px 4px;
-    height: 16px;
-}
-
-.toolbar-spacer {
-    flex: auto;
-}
-
-/* Long click */
-
-.long-click-glyph {
-    position: absolute;
-    background-color: #5a5a5a;
-    top: 0;
-    left:  0;
-}
-
-.toolbar-button.emulate-active {
-    background-color: rgb(163, 163, 163);
-}
-
-.toolbar-button[data-keyboard-focus="true"]:focus::after {
-    position: absolute;
-    top: 2px;
-    bottom: 2px;
-    left: 2px;
-    right: 2px;
-    background-color: rgba(0, 0, 0, 0.08);
-    border-radius: 2px;
-    content: "";
-}
-
-.toolbar-shadow.floating {
-    flex-direction: column;
-    height: auto;
-    background-color: white;
-    border: 1px solid #ccc;
-    margin-top: -1px;
-    width: 28px;
-    left: -2px;
-}
-
-input[is=history-input] {
-    border: none;
-    line-height: 16px;
-    padding: 1px;
-}
-
-input[is=history-input]:hover {
-    box-shadow: var(--focus-ring-inactive-shadow);
-}
-
-input[is=history-input]:focus {
-    box-shadow: var(--focus-ring-active-shadow);
-}
diff --git a/front_end/ui/tooltip.css b/front_end/ui/tooltip.css
deleted file mode 100644
index e1440b9..0000000
--- a/front_end/ui/tooltip.css
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-.tooltip {
-    background: hsl(0, 0%, 95%);
-    border-radius: 2px;
-    color: hsl(0, 0%, 20%);
-    padding: 5px 8px;
-    line-height: 14px;
-    display: flex;
-    align-items: center;
-    -webkit-filter: drop-shadow(0 1px 2px hsla(0, 0%, 0%, 0.3));
-    border: 1px solid hsla(0, 0%, 0%, 0.1);
-    background-clip: padding-box;
-    box-sizing: border-box;
-    position: absolute;
-    visibility: hidden;
-    transition: visibility 0s 100ms, opacity 150ms cubic-bezier(0, 0, .2, 1);
-    z-index: 20001;
-    top: 0;
-    left: 0;
-    opacity: 0;
-    text-overflow: ellipsis;
-    overflow: hidden;
-}
-
-.tooltip-breakword {
-    word-break: break-word;
-}
-
-.tooltip.shown {
-    visibility: visible;
-    transition-delay: 600ms;
-    opacity: 1;
-}
-
-.tooltip.shown.instant {
-    transition-delay: 0s;
-}
-
-.tooltip-shortcut {
-    color: hsl(0, 0%, 45%);
-    display: inline-block;
-    margin-left: 8px;
-    flex: 0 0 auto;
-}
diff --git a/front_end/ui/treeoutline.css b/front_end/ui/treeoutline.css
deleted file mode 100644
index 59abb46..0000000
--- a/front_end/ui/treeoutline.css
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2015 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-:host {
-    flex: 1 1;
-    padding: 2px 0 0 0;
-}
-
-.tree-outline-disclosure:not(.tree-outline-disclosure-hide-overflow) {
-    min-width: 100%;
-    display: inline-block;
-}
-
-.tree-outline {
-    padding: 0 0 4px 4px;
-    margin: 0;
-    z-index: 0;
-    position: relative;
-}
-
-.tree-outline li.hovered:not(.selected) .selection {
-    display: block;
-    left: 3px;
-    right: 3px;
-    background-color: rgba(56, 121, 217, 0.1);
-    border-radius: 5px;
-}
-
-.tree-outline li .selection {
-    display: none;
-    z-index: -1;
-    margin-left: -10000px;
-}
-
-.tree-outline li.selected .selection {
-    display: block;
-    background-color: var(--selection-inactive-bg-color);
-}
-
-.tree-outline li.in-clipboard .highlight {
-    outline: 1px dotted darkgrey;
-}
-
-.tree-outline li.elements-drag-over .selection {
-    display: block;
-    margin-top: -2px;
-    border-top: 2px solid;
-    border-top-color: var(--selection-bg-color);
-}
-
-ol.tree-outline li.selected:focus .selection {
-    background-color: var(--selection-bg-color);
-}
-
-ol.tree-outline li.parent.selected:focus::before {
-    background-color: var(--selection-fg-color);
-}
-
-ol.tree-outline,
-.tree-outline ol {
-    list-style-type: none;
-}
-
-.tree-outline-no-padding {
-    padding: 0;
-}
-
-.tree-outline ol {
-    padding-left: 12px;
-}
-
-.tree-outline li {
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    position: relative;
-    display: flex;
-    align-items: center;
-    min-height: 16px;
-}
-
-ol.tree-outline li.selected:focus {
-    color: var(--selection-fg-color);
-}
-
-ol.tree-outline li.selected:focus * {
-    color: inherit;
-}
-
-.tree-outline li .icons-container {
-    align-self: center;
-    display: flex;
-    align-items: center;
-}
-
-.tree-outline li .leading-icons {
-    margin-right: 4px;
-}
-
-.tree-outline li .trailing-icons {
-    margin-left: 4px;
-}
-
-.tree-outline li::before {
-    -webkit-user-select: none;
-    -webkit-mask-image: url(Images/treeoutlineTriangles.png);
-    -webkit-mask-size: 32px 24px;
-    content: "aa";
-    color: transparent;
-    text-shadow: none;
-    margin-right: -2px;
-    height: 12px;
-}
-
-.tree-outline li:not(.parent)::before {
-    background-color: transparent;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.1) {
-.tree-outline li::before {
-    -webkit-mask-image: url(Images/treeoutlineTriangles_2x.png);
-}
-} /* media */
-
-.tree-outline li::before {
-    -webkit-mask-position: 0 0;
-    background-color: #727272;
-}
-
-.tree-outline li.parent.expanded::before {
-    -webkit-mask-position: -16px 0;
-}
-
-.tree-outline ol.children {
-    display: none;
-}
-
-.tree-outline ol.children.expanded {
-    display: block;
-}
-
-.tree-outline.tree-outline-dense li {
-    margin-top: 1px;
-    min-height: 12px;
-}
-
-.tree-outline.tree-outline-dense li.parent {
-    margin-top: 0;
-}
-
-.tree-outline.tree-outline-dense li.parent::before {
-    top: 0;
-}
-
-.tree-outline.tree-outline-dense ol {
-    padding-left: 10px;
-}
diff --git a/front_end/ui/treeoutline.js b/front_end/ui/treeoutline.js
deleted file mode 100644
index a4adc62..0000000
--- a/front_end/ui/treeoutline.js
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.TreeOutline = class extends Common.Object {
-  constructor() {
-    super();
-    this._createRootElement();
-
-    /** @type {?UI.TreeElement} */
-    this.selectedTreeElement = null;
-    this.expandTreeElementsWhenArrowing = false;
-    /** @type {?function(!UI.TreeElement, !UI.TreeElement):number} */
-    this._comparator = null;
-
-    this.contentElement = this._rootElement._childrenListNode;
-    this.contentElement.addEventListener('keydown', this._treeKeyDown.bind(this), true);
-
-    this._focusable = true;
-    this.setFocusable(this._focusable);
-    if (this._focusable)
-      this.contentElement.setAttribute('tabIndex', -1);
-    this.element = this.contentElement;
-    UI.ARIAUtils.markAsTree(this.element);
-
-    // Adjust to allow computing margin-left for the selection element.
-    // Check the padding-left for the li element for correct value.
-    this._paddingSize = 0;
-  }
-
-  _createRootElement() {
-    this._rootElement = new UI.TreeElement();
-    this._rootElement.treeOutline = this;
-    this._rootElement.root = true;
-    this._rootElement.selectable = false;
-    this._rootElement.expanded = true;
-    this._rootElement._childrenListNode.classList.remove('children');
-  }
-
-  /**
-   * @return {!UI.TreeElement}
-   */
-  rootElement() {
-    return this._rootElement;
-  }
-
-  /**
-   * @return {?UI.TreeElement}
-   */
-  firstChild() {
-    return this._rootElement.firstChild();
-  }
-
-  /**
-   * @return {?UI.TreeElement}
-   */
-  _lastDescendent() {
-    let last = this._rootElement.lastChild();
-    while (last.expanded && last.childCount())
-      last = last.lastChild();
-    return last;
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   */
-  appendChild(child) {
-    this._rootElement.appendChild(child);
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   * @param {number} index
-   */
-  insertChild(child, index) {
-    this._rootElement.insertChild(child, index);
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   */
-  removeChild(child) {
-    this._rootElement.removeChild(child);
-  }
-
-  removeChildren() {
-    this._rootElement.removeChildren();
-  }
-
-  /**
-   * @param {number} x
-   * @param {number} y
-   * @return {?UI.TreeElement}
-   */
-  treeElementFromPoint(x, y) {
-    const node = this.contentElement.ownerDocument.deepElementFromPoint(x, y);
-    if (!node)
-      return null;
-
-    const listNode = node.enclosingNodeOrSelfWithNodeNameInArray(['ol', 'li']);
-    if (listNode)
-      return listNode.parentTreeElement || listNode.treeElement;
-    return null;
-  }
-
-  /**
-   * @param {?Event} event
-   * @return {?UI.TreeElement}
-   */
-  treeElementFromEvent(event) {
-    return event ? this.treeElementFromPoint(event.pageX, event.pageY) : null;
-  }
-
-  /**
-   * @param {?function(!UI.TreeElement, !UI.TreeElement):number} comparator
-   */
-  setComparator(comparator) {
-    this._comparator = comparator;
-  }
-
-  /**
-   * @param {boolean} focusable
-   */
-  setFocusable(focusable) {
-    if (focusable) {
-      this._focusable = true;
-      this.contentElement.setAttribute('tabIndex', -1);
-      if (this.selectedTreeElement)
-        this.selectedTreeElement._setFocusable(true);
-    } else {
-      this._focusable = false;
-      this.contentElement.removeAttribute('tabIndex');
-      if (this.selectedTreeElement)
-        this.selectedTreeElement._setFocusable(false);
-    }
-  }
-
-  focus() {
-    if (this.selectedTreeElement)
-      this.selectedTreeElement.listItemElement.focus();
-    else
-      this.contentElement.focus();
-  }
-
-  /**
-   * @param {!UI.TreeElement} element
-   */
-  _bindTreeElement(element) {
-    if (element.treeOutline)
-      console.error('Binding element for the second time: ' + new Error().stack);
-    element.treeOutline = this;
-    element.onbind();
-  }
-
-  /**
-   * @param {!UI.TreeElement} element
-   */
-  _unbindTreeElement(element) {
-    if (!element.treeOutline)
-      console.error('Unbinding element that was not bound: ' + new Error().stack);
-
-    element.deselect();
-    element.onunbind();
-    element.treeOutline = null;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  selectPrevious() {
-    let nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
-    while (nextSelectedElement && !nextSelectedElement.selectable)
-      nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
-    if (!nextSelectedElement)
-      return false;
-    nextSelectedElement.select(false, true);
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  selectNext() {
-    let nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
-    while (nextSelectedElement && !nextSelectedElement.selectable)
-      nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
-    if (!nextSelectedElement)
-      return false;
-    nextSelectedElement.select(false, true);
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _selectFirst() {
-    let first = this.firstChild();
-    while (first && !first.selectable)
-      first = first.traverseNextTreeElement(true);
-    if (!first)
-      return false;
-    first.select(false, true);
-    return true;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  _selectLast() {
-    let last = this._lastDescendent();
-    while (last && !last.selectable)
-      last = last.traversePreviousTreeElement(true);
-    if (!last)
-      return false;
-    last.select(false, true);
-    return true;
-  }
-
-  /**
-   * @param {number} paddingSize
-   */
-  setPaddingSize(paddingSize) {
-    this._paddingSize = paddingSize;
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _treeKeyDown(event) {
-    if (!this.selectedTreeElement || event.target !== this.selectedTreeElement.listItemElement || event.shiftKey ||
-        event.metaKey || event.ctrlKey)
-      return;
-
-    let handled = false;
-    if (event.key === 'ArrowUp' && !event.altKey) {
-      handled = this.selectPrevious();
-    } else if (event.key === 'ArrowDown' && !event.altKey) {
-      handled = this.selectNext();
-    } else if (event.key === 'ArrowLeft') {
-      handled = this.selectedTreeElement.collapseOrAscend(event.altKey);
-    } else if (event.key === 'ArrowRight') {
-      if (!this.selectedTreeElement.revealed()) {
-        this.selectedTreeElement.reveal();
-        handled = true;
-      } else {
-        handled = this.selectedTreeElement.descendOrExpand(event.altKey);
-      }
-    } else if (event.keyCode === 8 /* Backspace */ || event.keyCode === 46 /* Delete */) {
-      handled = this.selectedTreeElement.ondelete();
-    } else if (isEnterKey(event)) {
-      handled = this.selectedTreeElement.onenter();
-    } else if (event.keyCode === UI.KeyboardShortcut.Keys.Space.code) {
-      handled = this.selectedTreeElement.onspace();
-    } else if (event.key === 'Home') {
-      handled = this._selectFirst();
-    } else if (event.key === 'End') {
-      handled = this._selectLast();
-    }
-
-    if (handled)
-      event.consume(true);
-  }
-
-  /**
-   * @param {!UI.TreeElement} treeElement
-   * @param {boolean} center
-   */
-  _deferredScrollIntoView(treeElement, center) {
-    if (!this._treeElementToScrollIntoView)
-      this.element.window().requestAnimationFrame(deferredScrollIntoView.bind(this));
-    this._treeElementToScrollIntoView = treeElement;
-    this._centerUponScrollIntoView = center;
-    /**
-     * @this {UI.TreeOutline}
-     */
-    function deferredScrollIntoView() {
-      this._treeElementToScrollIntoView.listItemElement.scrollIntoViewIfNeeded(this._centerUponScrollIntoView);
-      delete this._treeElementToScrollIntoView;
-      delete this._centerUponScrollIntoView;
-    }
-  }
-};
-
-/** @enum {symbol} */
-UI.TreeOutline.Events = {
-  ElementAttached: Symbol('ElementAttached'),
-  ElementExpanded: Symbol('ElementExpanded'),
-  ElementCollapsed: Symbol('ElementCollapsed'),
-  ElementSelected: Symbol('ElementSelected')
-};
-
-/**
- * @unrestricted
- */
-UI.TreeOutlineInShadow = class extends UI.TreeOutline {
-  constructor() {
-    super();
-    this.contentElement.classList.add('tree-outline');
-
-    // Redefine element to the external one.
-    this.element = createElement('div');
-    this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/treeoutline.css');
-    this._disclosureElement = this._shadowRoot.createChild('div', 'tree-outline-disclosure');
-    this._disclosureElement.appendChild(this.contentElement);
-    this._renderSelection = true;
-  }
-
-  /**
-   * @param {string} cssFile
-   */
-  registerRequiredCSS(cssFile) {
-    UI.appendStyle(this._shadowRoot, cssFile);
-  }
-
-  hideOverflow() {
-    this._disclosureElement.classList.add('tree-outline-disclosure-hide-overflow');
-  }
-
-  makeDense() {
-    this.contentElement.classList.add('tree-outline-dense');
-  }
-};
-
-/**
- * @unrestricted
- */
-UI.TreeElement = class {
-  /**
-   * @param {(string|!Node)=} title
-   * @param {boolean=} expandable
-   */
-  constructor(title, expandable) {
-    /** @type {?UI.TreeOutline} */
-    this.treeOutline = null;
-    this.parent = null;
-    this.previousSibling = null;
-    this.nextSibling = null;
-    this._boundOnFocus = this._onFocus.bind(this);
-    this._boundOnBlur = this._onBlur.bind(this);
-
-    this._listItemNode = createElement('li');
-    this._titleElement = this._listItemNode.createChild('span', 'tree-element-title');
-    this._listItemNode.treeElement = this;
-    if (title)
-      this.title = title;
-    this._listItemNode.addEventListener('mousedown', this._handleMouseDown.bind(this), false);
-    this._listItemNode.addEventListener('click', this._treeElementToggled.bind(this), false);
-    this._listItemNode.addEventListener('dblclick', this._handleDoubleClick.bind(this), false);
-    UI.ARIAUtils.markAsTreeitem(this._listItemNode);
-
-    this._childrenListNode = createElement('ol');
-    this._childrenListNode.parentTreeElement = this;
-    this._childrenListNode.classList.add('children');
-    UI.ARIAUtils.markAsGroup(this._childrenListNode);
-
-    this._hidden = false;
-    this._selectable = true;
-    this.expanded = false;
-    this.selected = false;
-    this.setExpandable(expandable || false);
-    this._collapsible = true;
-  }
-
-  /**
-   * @param {?UI.TreeElement} ancestor
-   * @return {boolean}
-   */
-  hasAncestor(ancestor) {
-    if (!ancestor)
-      return false;
-
-    let currentNode = this.parent;
-    while (currentNode) {
-      if (ancestor === currentNode)
-        return true;
-      currentNode = currentNode.parent;
-    }
-
-    return false;
-  }
-
-  /**
-   * @param {?UI.TreeElement} ancestor
-   * @return {boolean}
-   */
-  hasAncestorOrSelf(ancestor) {
-    return this === ancestor || this.hasAncestor(ancestor);
-  }
-
-  /**
-   * @return {!Array.<!UI.TreeElement>}
-   */
-  children() {
-    return this._children || [];
-  }
-
-  /**
-   * @return {number}
-   */
-  childCount() {
-    return this._children ? this._children.length : 0;
-  }
-
-  /**
-   * @return {?UI.TreeElement}
-   */
-  firstChild() {
-    return this._children ? this._children[0] : null;
-  }
-
-  /**
-   * @return {?UI.TreeElement}
-   */
-  lastChild() {
-    return this._children ? this._children[this._children.length - 1] : null;
-  }
-
-  /**
-   * @param {number} index
-   * @return {?UI.TreeElement}
-   */
-  childAt(index) {
-    return this._children ? this._children[index] : null;
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   * @return {number}
-   */
-  indexOfChild(child) {
-    return this._children ? this._children.indexOf(child) : -1;
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   */
-  appendChild(child) {
-    if (!this._children)
-      this._children = [];
-
-    let insertionIndex;
-    if (this.treeOutline && this.treeOutline._comparator)
-      insertionIndex = this._children.lowerBound(child, this.treeOutline._comparator);
-    else
-      insertionIndex = this._children.length;
-    this.insertChild(child, insertionIndex);
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   * @param {number} index
-   */
-  insertChild(child, index) {
-    if (!this._children)
-      this._children = [];
-
-    if (!child)
-      throw 'child can\'t be undefined or null';
-
-    console.assert(
-        !child.parent, 'Attempting to insert a child that is already in the tree, reparenting is not supported.');
-
-    const previousChild = (index > 0 ? this._children[index - 1] : null);
-    if (previousChild) {
-      previousChild.nextSibling = child;
-      child.previousSibling = previousChild;
-    } else {
-      child.previousSibling = null;
-    }
-
-    const nextChild = this._children[index];
-    if (nextChild) {
-      nextChild.previousSibling = child;
-      child.nextSibling = nextChild;
-    } else {
-      child.nextSibling = null;
-    }
-
-    this._children.splice(index, 0, child);
-
-    this.setExpandable(true);
-    child.parent = this;
-
-    if (this.treeOutline)
-      this.treeOutline._bindTreeElement(child);
-    for (let current = child.firstChild(); this.treeOutline && current;
-         current = current.traverseNextTreeElement(false, child, true))
-      this.treeOutline._bindTreeElement(current);
-    child.onattach();
-    child._ensureSelection();
-    if (this.treeOutline)
-      this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementAttached, child);
-    const nextSibling = child.nextSibling ? child.nextSibling._listItemNode : null;
-    this._childrenListNode.insertBefore(child._listItemNode, nextSibling);
-    this._childrenListNode.insertBefore(child._childrenListNode, nextSibling);
-    if (child.selected)
-      child.select();
-    if (child.expanded)
-      child.expand();
-  }
-
-  /**
-   * @param {number} childIndex
-   */
-  removeChildAtIndex(childIndex) {
-    if (childIndex < 0 || childIndex >= this._children.length)
-      throw 'childIndex out of range';
-
-    const child = this._children[childIndex];
-    this._children.splice(childIndex, 1);
-
-    const parent = child.parent;
-    if (this.treeOutline && this.treeOutline.selectedTreeElement &&
-        this.treeOutline.selectedTreeElement.hasAncestorOrSelf(child)) {
-      if (child.nextSibling)
-        child.nextSibling.select(true);
-      else if (child.previousSibling)
-        child.previousSibling.select(true);
-      else if (parent)
-        parent.select(true);
-    }
-
-    if (child.previousSibling)
-      child.previousSibling.nextSibling = child.nextSibling;
-    if (child.nextSibling)
-      child.nextSibling.previousSibling = child.previousSibling;
-    child.parent = null;
-
-    if (this.treeOutline)
-      this.treeOutline._unbindTreeElement(child);
-    for (let current = child.firstChild(); this.treeOutline && current;
-         current = current.traverseNextTreeElement(false, child, true))
-      this.treeOutline._unbindTreeElement(current);
-
-    child._detach();
-  }
-
-  /**
-   * @param {!UI.TreeElement} child
-   */
-  removeChild(child) {
-    if (!child)
-      throw 'child can\'t be undefined or null';
-    if (child.parent !== this)
-      return;
-
-    const childIndex = this._children.indexOf(child);
-    if (childIndex === -1)
-      throw 'child not found in this node\'s children';
-
-    this.removeChildAtIndex(childIndex);
-  }
-
-  removeChildren() {
-    if (!this.root && this.treeOutline && this.treeOutline.selectedTreeElement &&
-        this.treeOutline.selectedTreeElement.hasAncestorOrSelf(this))
-      this.select(true);
-
-    for (let i = 0; this._children && i < this._children.length; ++i) {
-      const child = this._children[i];
-      child.previousSibling = null;
-      child.nextSibling = null;
-      child.parent = null;
-
-      if (this.treeOutline)
-        this.treeOutline._unbindTreeElement(child);
-      for (let current = child.firstChild(); this.treeOutline && current;
-           current = current.traverseNextTreeElement(false, child, true))
-        this.treeOutline._unbindTreeElement(current);
-      child._detach();
-    }
-    this._children = [];
-  }
-
-  get selectable() {
-    if (this._hidden)
-      return false;
-    return this._selectable;
-  }
-
-  set selectable(x) {
-    this._selectable = x;
-  }
-
-  get listItemElement() {
-    return this._listItemNode;
-  }
-
-  /**
-   * @return {!Element}
-   */
-  titleElement() {
-    return this._titleElement;
-  }
-
-  get childrenListElement() {
-    return this._childrenListNode;
-  }
-
-  /**
-   * @return {string|!Node}
-   */
-  get title() {
-    return this._title;
-  }
-
-  /**
-   * @param {string|!Node} x
-   */
-  set title(x) {
-    if (this._title === x)
-      return;
-    this._title = x;
-
-    if (typeof x === 'string') {
-      this._titleElement.textContent = x;
-      this.tooltip = x;
-    } else {
-      this._titleElement = x;
-      this.tooltip = '';
-    }
-
-    this._listItemNode.removeChildren();
-    if (this._leadingIconsElement)
-      this._listItemNode.appendChild(this._leadingIconsElement);
-    this._listItemNode.appendChild(this._titleElement);
-    if (this._trailingIconsElement)
-      this._listItemNode.appendChild(this._trailingIconsElement);
-    this._ensureSelection();
-  }
-
-  /**
-   * @return {string}
-   */
-  titleAsText() {
-    if (!this._title)
-      return '';
-    if (typeof this._title === 'string')
-      return this._title;
-    return this._title.textContent;
-  }
-
-  /**
-   * @param {!UI.InplaceEditor.Config} editingConfig
-   */
-  startEditingTitle(editingConfig) {
-    UI.InplaceEditor.startEditing(this._titleElement, editingConfig);
-    this.treeOutline._shadowRoot.getSelection().selectAllChildren(this._titleElement);
-  }
-
-  /**
-   * @param {!Array<!UI.Icon>} icons
-   */
-  setLeadingIcons(icons) {
-    if (!this._leadingIconsElement && !icons.length)
-      return;
-    if (!this._leadingIconsElement) {
-      this._leadingIconsElement = createElementWithClass('div', 'leading-icons');
-      this._leadingIconsElement.classList.add('icons-container');
-      this._listItemNode.insertBefore(this._leadingIconsElement, this._titleElement);
-      this._ensureSelection();
-    }
-    this._leadingIconsElement.removeChildren();
-    for (const icon of icons)
-      this._leadingIconsElement.appendChild(icon);
-  }
-
-  /**
-   * @param {!Array<!UI.Icon>} icons
-   */
-  setTrailingIcons(icons) {
-    if (!this._trailingIconsElement && !icons.length)
-      return;
-    if (!this._trailingIconsElement) {
-      this._trailingIconsElement = createElementWithClass('div', 'trailing-icons');
-      this._trailingIconsElement.classList.add('icons-container');
-      this._listItemNode.appendChild(this._trailingIconsElement);
-      this._ensureSelection();
-    }
-    this._trailingIconsElement.removeChildren();
-    for (const icon of icons)
-      this._trailingIconsElement.appendChild(icon);
-  }
-
-
-  /**
-   * @return {string}
-   */
-  get tooltip() {
-    return this._tooltip || '';
-  }
-
-  /**
-   * @param {string} x
-   */
-  set tooltip(x) {
-    if (this._tooltip === x)
-      return;
-    this._tooltip = x;
-    this._listItemNode.title = x;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isExpandable() {
-    return this._expandable;
-  }
-
-  /**
-   * @param {boolean} expandable
-   */
-  setExpandable(expandable) {
-    if (this._expandable === expandable)
-      return;
-
-    this._expandable = expandable;
-
-    this._listItemNode.classList.toggle('parent', expandable);
-    if (!expandable) {
-      this.collapse();
-      UI.ARIAUtils.unsetExpanded(this._listItemNode);
-    } else {
-      UI.ARIAUtils.setExpanded(this._listItemNode, false);
-    }
-  }
-
-  /**
-   * @param {boolean} collapsible
-   */
-  setCollapsible(collapsible) {
-    if (this._collapsible === collapsible)
-      return;
-
-    this._collapsible = collapsible;
-
-    this._listItemNode.classList.toggle('always-parent', !collapsible);
-    if (!collapsible)
-      this.expand();
-  }
-
-  get hidden() {
-    return this._hidden;
-  }
-
-  set hidden(x) {
-    if (this._hidden === x)
-      return;
-
-    this._hidden = x;
-
-    this._listItemNode.classList.toggle('hidden', x);
-    this._childrenListNode.classList.toggle('hidden', x);
-  }
-
-  invalidateChildren() {
-    if (this._children) {
-      this.removeChildren();
-      this._children = null;
-    }
-  }
-
-  /**
-   * @return {number}
-   */
-  computeLeftMargin() {
-    let treeElement = this.parent;
-    let depth = 0;
-    while (treeElement !== null) {
-      depth++;
-      treeElement = treeElement.parent;
-    }
-
-    return -(this.treeOutline._paddingSize * (depth - 1) + 4);
-  }
-
-  _ensureSelection() {
-    if (!this.treeOutline || !this.treeOutline._renderSelection)
-      return;
-    if (!this._selectionElement)
-      this._selectionElement = createElementWithClass('div', 'selection fill');
-    if (this.treeOutline._paddingSize)
-      this._selectionElement.style.setProperty('margin-left', this.computeLeftMargin() + 'px');
-    this._listItemNode.insertBefore(this._selectionElement, this.listItemElement.firstChild);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _treeElementToggled(event) {
-    const element = event.currentTarget;
-    if (element.treeElement !== this || element.hasSelection())
-      return;
-
-    const toggleOnClick = this.toggleOnClick && !this.selectable;
-    const isInTriangle = this.isEventWithinDisclosureTriangle(event);
-    if (!toggleOnClick && !isInTriangle)
-      return;
-
-    if (this.expanded) {
-      if (event.altKey)
-        this.collapseRecursively();
-      else
-        this.collapse();
-    } else {
-      if (event.altKey)
-        this.expandRecursively();
-      else
-        this.expand();
-    }
-    event.consume();
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleMouseDown(event) {
-    const element = event.currentTarget;
-    if (!element)
-      return;
-    if (!this.selectable)
-      return;
-    if (element.treeElement !== this)
-      return;
-
-    if (this.isEventWithinDisclosureTriangle(event))
-      return;
-
-    this.selectOnMouseDown(event);
-  }
-
-  /**
-   * @param {!Event} event
-   */
-  _handleDoubleClick(event) {
-    const element = event.currentTarget;
-    if (!element || element.treeElement !== this)
-      return;
-
-    const handled = this.ondblclick(event);
-    if (handled)
-      return;
-    if (this._expandable && !this.expanded)
-      this.expand();
-  }
-
-  _detach() {
-    this._listItemNode.remove();
-    this._childrenListNode.remove();
-  }
-
-  collapse() {
-    if (!this.expanded || !this._collapsible)
-      return;
-    this._listItemNode.classList.remove('expanded');
-    this._childrenListNode.classList.remove('expanded');
-    UI.ARIAUtils.setExpanded(this._listItemNode, false);
-    this.expanded = false;
-    this.oncollapse();
-    if (this.treeOutline)
-      this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementCollapsed, this);
-  }
-
-  collapseRecursively() {
-    let item = this;
-    while (item) {
-      if (item.expanded)
-        item.collapse();
-      item = item.traverseNextTreeElement(false, this, true);
-    }
-  }
-
-  collapseChildren() {
-    if (!this._children)
-      return;
-    for (const child of this._children)
-      child.collapseRecursively();
-  }
-
-  expand() {
-    if (!this._expandable || (this.expanded && this._children))
-      return;
-
-    // Set this before onpopulate. Since onpopulate can add elements, this makes
-    // sure the expanded flag is true before calling those functions. This prevents the possibility
-    // of an infinite loop if onpopulate were to call expand.
-
-    this.expanded = true;
-
-    this._populateIfNeeded();
-    this._listItemNode.classList.add('expanded');
-    this._childrenListNode.classList.add('expanded');
-    UI.ARIAUtils.setExpanded(this._listItemNode, true);
-
-    if (this.treeOutline) {
-      this.onexpand();
-      this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementExpanded, this);
-    }
-  }
-
-  /**
-   * @param {number=} maxDepth
-   */
-  expandRecursively(maxDepth) {
-    let item = this;
-    const info = {};
-    let depth = 0;
-
-    // The Inspector uses TreeOutlines to represents object properties, so recursive expansion
-    // in some case can be infinite, since JavaScript objects can hold circular references.
-    // So default to a recursion cap of 3 levels, since that gives fairly good results.
-    if (isNaN(maxDepth))
-      maxDepth = 3;
-
-    while (item) {
-      if (depth < maxDepth)
-        item.expand();
-      item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
-      depth += info.depthChange;
-    }
-  }
-
-  /**
-   * @param {boolean} altKey
-   * @return {boolean}
-   */
-  collapseOrAscend(altKey) {
-    if (this.expanded) {
-      if (altKey)
-        this.collapseRecursively();
-      else
-        this.collapse();
-      return true;
-    }
-
-    if (!this.parent || this.parent.root)
-      return false;
-
-    if (!this.parent.selectable) {
-      this.parent.collapse();
-      return true;
-    }
-
-    let nextSelectedElement = this.parent;
-    while (nextSelectedElement && !nextSelectedElement.selectable)
-      nextSelectedElement = nextSelectedElement.parent;
-
-    if (!nextSelectedElement)
-      return false;
-    nextSelectedElement.select(false, true);
-    return true;
-  }
-
-  /**
-   * @param {boolean} altKey
-   * @return {boolean}
-   */
-  descendOrExpand(altKey) {
-    if (!this._expandable)
-      return false;
-
-    if (!this.expanded) {
-      if (altKey)
-        this.expandRecursively();
-      else
-        this.expand();
-      return true;
-    }
-
-    let nextSelectedElement = this.firstChild();
-    while (nextSelectedElement && !nextSelectedElement.selectable)
-      nextSelectedElement = nextSelectedElement.nextSibling;
-
-    if (!nextSelectedElement)
-      return false;
-    nextSelectedElement.select(false, true);
-    return true;
-  }
-
-  /**
-   * @param {boolean=} center
-   */
-  reveal(center) {
-    let currentAncestor = this.parent;
-    while (currentAncestor && !currentAncestor.root) {
-      if (!currentAncestor.expanded)
-        currentAncestor.expand();
-      currentAncestor = currentAncestor.parent;
-    }
-
-    this.treeOutline._deferredScrollIntoView(this, !!center);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  revealed() {
-    let currentAncestor = this.parent;
-    while (currentAncestor && !currentAncestor.root) {
-      if (!currentAncestor.expanded)
-        return false;
-      currentAncestor = currentAncestor.parent;
-    }
-
-    return true;
-  }
-
-  selectOnMouseDown(event) {
-    if (this.select(false, true))
-      event.consume(true);
-  }
-
-  /**
-   * @param {boolean=} omitFocus
-   * @param {boolean=} selectedByUser
-   * @return {boolean}
-   */
-  select(omitFocus, selectedByUser) {
-    if (!this.treeOutline || !this.selectable || this.selected)
-      return false;
-    // Wait to deselect this element so that focus only changes once
-    const lastSelected = this.treeOutline.selectedTreeElement;
-    this.treeOutline.selectedTreeElement = null;
-
-    if (this.treeOutline._rootElement === this) {
-      if (lastSelected)
-        lastSelected.deselect();
-      return false;
-    }
-
-    this.selected = true;
-
-    this.treeOutline.selectedTreeElement = this;
-    if (this.treeOutline._focusable)
-      this._setFocusable(true);
-    if (!omitFocus || this.treeOutline.contentElement.hasFocus())
-      this.listItemElement.focus();
-
-    this._listItemNode.classList.add('selected');
-    this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementSelected, this);
-    if (lastSelected)
-      lastSelected.deselect();
-    return this.onselect(selectedByUser);
-  }
-
-  /**
-   * @param {boolean} focusable
-   */
-  _setFocusable(focusable) {
-    if (focusable) {
-      this._listItemNode.setAttribute('tabIndex', 0);
-      this._listItemNode.addEventListener('focus', this._boundOnFocus, false);
-      this._listItemNode.addEventListener('blur', this._boundOnBlur, false);
-    } else {
-      this._listItemNode.removeAttribute('tabIndex');
-      this._listItemNode.removeEventListener('focus', this._boundOnFocus, false);
-      this._listItemNode.removeEventListener('blur', this._boundOnBlur, false);
-    }
-  }
-
-  _onFocus() {
-    this._listItemNode.classList.add('force-white-icons');
-  }
-
-  _onBlur() {
-    this._listItemNode.classList.remove('force-white-icons');
-  }
-
-  /**
-   * @param {boolean=} omitFocus
-   */
-  revealAndSelect(omitFocus) {
-    this.reveal(true);
-    this.select(omitFocus);
-  }
-
-  deselect() {
-    const hadFocus = this._listItemNode.hasFocus();
-    this.selected = false;
-    this._listItemNode.classList.remove('selected');
-    this._setFocusable(false);
-
-    if (this.treeOutline && this.treeOutline.selectedTreeElement === this) {
-      this.treeOutline.selectedTreeElement = null;
-      if (hadFocus)
-        this.treeOutline.focus();
-    }
-  }
-
-  _populateIfNeeded() {
-    if (this.treeOutline && this._expandable && !this._children) {
-      this._children = [];
-      this.onpopulate();
-    }
-  }
-
-  onpopulate() {
-    // Overridden by subclasses.
-  }
-
-  /**
-   * @return {boolean}
-   */
-  onenter() {
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  ondelete() {
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  onspace() {
-    return false;
-  }
-
-  onbind() {
-  }
-
-  onunbind() {
-  }
-
-  onattach() {
-  }
-
-  onexpand() {
-  }
-
-  oncollapse() {
-  }
-
-  /**
-   * @param {!Event} e
-   * @return {boolean}
-   */
-  ondblclick(e) {
-    return false;
-  }
-
-  /**
-   * @param {boolean=} selectedByUser
-   * @return {boolean}
-   */
-  onselect(selectedByUser) {
-    return false;
-  }
-
-  /**
-   * @param {boolean} skipUnrevealed
-   * @param {?UI.TreeElement=} stayWithin
-   * @param {boolean=} dontPopulate
-   * @param {!Object=} info
-   * @return {?UI.TreeElement}
-   */
-  traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate, info) {
-    if (!dontPopulate)
-      this._populateIfNeeded();
-
-    if (info)
-      info.depthChange = 0;
-
-    let element = skipUnrevealed ? (this.revealed() ? this.firstChild() : null) : this.firstChild();
-    if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
-      if (info)
-        info.depthChange = 1;
-      return element;
-    }
-
-    if (this === stayWithin)
-      return null;
-
-    element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
-    if (element)
-      return element;
-
-    element = this;
-    while (element && !element.root &&
-           !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) &&
-           element.parent !== stayWithin) {
-      if (info)
-        info.depthChange -= 1;
-      element = element.parent;
-    }
-
-    if (!element || element.root)
-      return null;
-
-    return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
-  }
-
-  /**
-   * @param {boolean} skipUnrevealed
-   * @param {boolean=} dontPopulate
-   * @return {?UI.TreeElement}
-   */
-  traversePreviousTreeElement(skipUnrevealed, dontPopulate) {
-    let element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
-    if (!dontPopulate && element)
-      element._populateIfNeeded();
-
-    while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.lastChild() : null) :
-                                        element.lastChild())) {
-      if (!dontPopulate)
-        element._populateIfNeeded();
-      element =
-          (skipUnrevealed ? (element.revealed() && element.expanded ? element.lastChild() : null) :
-                            element.lastChild());
-    }
-
-    if (element)
-      return element;
-
-    if (!this.parent || this.parent.root)
-      return null;
-
-    return this.parent;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEventWithinDisclosureTriangle(event) {
-    // FIXME: We should not use getComputedStyle(). For that we need to get rid of using ::before for disclosure triangle. (http://webk.it/74446)
-    const paddingLeftValue = window.getComputedStyle(this._listItemNode).paddingLeft;
-    console.assert(paddingLeftValue.endsWith('px'));
-    const computedLeftPadding = parseFloat(paddingLeftValue);
-    const left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
-    return event.pageX >= left && event.pageX <= left + UI.TreeElement._ArrowToggleWidth && this._expandable;
-  }
-};
-
-/** @const */
-UI.TreeElement._ArrowToggleWidth = 10;
-
-(function() {
-const img = new Image();
-if (window.devicePixelRatio > 1)
-  img.src = 'Images/treeoutlineTriangles_2x.png';
-else
-  img.src = 'Images/treeoutlineTriangles.png';
-UI.TreeElement._imagePreload = img;
-})();
diff --git a/front_end/ui/viewContainers.css b/front_end/ui/viewContainers.css
deleted file mode 100644
index 5b720a7..0000000
--- a/front_end/ui/viewContainers.css
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
- * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.sidebar-hidden-override {
-    display: none !important;
-}
-
-.expandable-view-title {
-    display: flex;
-    align-items: center;
-    background-color: var(--toolbar-bg-color);
-    height: 22px;
-    padding: 0 5px;
-    border-top: var(--divider-border);
-    white-space: nowrap;
-    overflow: hidden;
-    position: relative;
-    border-bottom: 1px solid transparent;
-}
-
-.expandable-view-title.expanded,
-.expandable-view-title:last-child {
-    border-bottom: 1px solid #ddd;
-}
-
-.expandable-view-title .toolbar {
-    margin-top: -3px;
-}
-
-.expandable-view-title:not(.expanded) .toolbar {
-    display: none;
-}
-
-.title-expand-icon {
-    margin-right: 2px;
-    margin-bottom: -2px;
-}
-
-.expandable-view-title[data-keyboard-focus="true"]:focus {
-    background-color: #e0e0e0;
-}
-
-.expandable-view-title > .toolbar {
-    position: absolute;
-    right: 0;
-    top: 0;
-}
-
-.sidebar-pane-container .toolbar {
-    border-bottom: 1px solid #eee;
-}
-
-.sidebar-pane-container .toolbar > * {
-    pointer-events: auto;
-}
diff --git a/front_end/worker_app.html b/front_end/worker_app.html
deleted file mode 100644
index 82f8321..0000000
--- a/front_end/worker_app.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- * Copyright 2018 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
--->
-<!doctype html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8">
-    <meta http-equiv="Content-Security-Policy" content="object-src 'none'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://chrome-devtools-frontend.appspot.com">
-    <meta name="referrer" content="no-referrer">
-    <script type="text/javascript" src="Runtime.js"></script>
-    <script type="text/javascript" src="worker_app.js"></script>
-</head>
-<body class="undocked" id="-blink-dev-tools"></body>
-</html>
diff --git a/front_end/worker_app.js b/front_end/worker_app.js
deleted file mode 100644
index 4cd27a8..0000000
--- a/front_end/worker_app.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-Runtime.startApplication('worker_app');
diff --git a/front_end/worker_app.json b/front_end/worker_app.json
deleted file mode 100644
index deadd1f..0000000
--- a/front_end/worker_app.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "modules" : [
-    { "name": "mobile_throttling", "type": "autostart"  },
-    { "name": "worker_main", "type": "autostart" },
-    { "name": "browser_components", "type": "autostart" },
-
-    { "name": "browser_console" },
-    { "name": "browser_debugger" },
-    { "name": "cookie_table" },
-    { "name": "elements" },
-    { "name": "har_importer" },
-    { "name": "help" },
-    { "name": "layer_viewer" },
-    { "name": "network" },
-    { "name": "product_registry_impl", "type": "remote" },
-    { "name": "resources" },
-    { "name": "timeline" },
-    { "name": "timeline_model" }
-  ],
-  "extends": "shell",
-  "has_html": true
-}
diff --git a/front_end/worker_main/WorkerMain.js b/front_end/worker_main/WorkerMain.js
deleted file mode 100644
index bed1ecd..0000000
--- a/front_end/worker_main/WorkerMain.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.Runnable}
- */
-WorkerMain.WorkerMain = class extends Common.Object {
-  /**
-   * @override
-   */
-  run() {
-    const capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.Log | SDK.Target.Capability.Network |
-        SDK.Target.Capability.Target;
-    SDK.targetManager.createTarget(
-        'main', Common.UIString('Main'), capabilities, this._createMainConnection.bind(this), null);
-    InspectorFrontendHost.connectionReady();
-    new MobileThrottling.NetworkPanelIndicator();
-  }
-
-  /**
-   * @param {!Protocol.InspectorBackend.Connection.Params} params
-   * @return {!Protocol.InspectorBackend.Connection}
-   */
-  _createMainConnection(params) {
-    return SDK.createMainConnection(params, () => Components.TargetDetachedDialog.webSocketConnectionLost());
-  }
-};
-
-SDK.ChildTargetManager.install(({target, waitingForDebugger}) => {
-  const parentTarget = target.parentTarget();
-  // Only pause the new worker if debugging SW - we are going through the pause on start checkbox.
-  if (!parentTarget.parentTarget() && waitingForDebugger) {
-    const debuggerModel = target.model(SDK.DebuggerModel);
-    if (debuggerModel)
-      debuggerModel.pause();
-  }
-});
diff --git a/front_end/worker_main/module.json b/front_end/worker_main/module.json
deleted file mode 100644
index 4029b30..0000000
--- a/front_end/worker_main/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "extensions": [
-        {
-            "type": "early-initialization",
-            "className": "WorkerMain.WorkerMain"
-        }
-    ],
-    "dependencies": [
-        "components",
-        "mobile_throttling"
-    ],
-    "scripts": [
-        "WorkerMain.js"
-    ]
-}
diff --git a/front_end/worker_service/ServiceDispatcher.js b/front_end/worker_service/ServiceDispatcher.js
deleted file mode 100644
index cee212e..0000000
--- a/front_end/worker_service/ServiceDispatcher.js
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @interface
- */
-function Service() {
-}
-
-Service.prototype = {
-  /**
-   * @return {!Promise}
-   */
-  dispose() {},
-
-  /**
-   * @return {function(string)}
-   */
-  setNotify(notify) {}
-};
-
-/**
- * @unrestricted
- */
-ServiceDispatcher = class {
-  /**
-   * @param {!ServicePort} port
-   */
-  constructor(port) {
-    /** @type {!Map<string, !Object>} */
-    this._objects = new Map();
-    this._lastObjectId = 1;
-    this._port = port;
-    this._port.setHandlers(this._dispatchMessageWrapped.bind(this), this._connectionClosed.bind(this));
-  }
-
-  /**
-   * @param {string} data
-   */
-  _dispatchMessageWrapped(data) {
-    try {
-      const message = JSON.parse(data);
-      if (!(message instanceof Object)) {
-        this._sendErrorResponse(message['id'], 'Malformed message');
-        return;
-      }
-      this._dispatchMessage(message);
-    } catch (e) {
-      this._sendErrorResponse(message['id'], e.toString() + ' ' + e.stack);
-    }
-  }
-
-  /**
-   * @param {!Object} message
-   */
-  _dispatchMessage(message) {
-    const domainAndMethod = message['method'].split('.');
-    const serviceName = domainAndMethod[0];
-    const method = domainAndMethod[1];
-
-    if (method === 'create') {
-      const extensions =
-          self.runtime.extensions(Service).filter(extension => extension.descriptor()['name'] === serviceName);
-      if (!extensions.length) {
-        this._sendErrorResponse(message['id'], 'Could not resolve service \'' + serviceName + '\'');
-        return;
-      }
-      extensions[0].instance().then(object => {
-        const id = String(this._lastObjectId++);
-        object.setNotify(this._notify.bind(this, id, serviceName));
-        this._objects.set(id, object);
-        this._sendResponse(message['id'], {id: id});
-      });
-    } else if (method === 'dispose') {
-      const object = this._objects.get(message['params']['id']);
-      if (!object) {
-        console.error('Could not look up object with id for ' + JSON.stringify(message));
-        return;
-      }
-      this._objects.delete(message['params']['id']);
-      object.dispose().then(() => this._sendResponse(message['id'], {}));
-    } else {
-      if (!message['params']) {
-        console.error('No params in the message: ' + JSON.stringify(message));
-        return;
-      }
-      const object = this._objects.get(message['params']['id']);
-      if (!object) {
-        console.error('Could not look up object with id for ' + JSON.stringify(message));
-        return;
-      }
-      const handler = object[method];
-      if (!(handler instanceof Function)) {
-        console.error('Handler for \'' + method + '\' is missing.');
-        return;
-      }
-      object[method](message['params']).then(result => this._sendResponse(message['id'], result));
-    }
-  }
-
-  _connectionClosed() {
-    for (const object of this._objects.values())
-      object.dispose();
-    this._objects.clear();
-  }
-
-  /**
-   * @param {string} objectId
-   * @param {string} serviceName
-   * @param {string} method
-   * @param {!Object} params
-   */
-  _notify(objectId, serviceName, method, params) {
-    params['id'] = objectId;
-    const message = {method: serviceName + '.' + method, params: params};
-    this._port.send(JSON.stringify(message));
-  }
-
-  /**
-   * @param {string} messageId
-   * @param {!Object} result
-   */
-  _sendResponse(messageId, result) {
-    const message = {id: messageId, result: result};
-    this._port.send(JSON.stringify(message));
-  }
-
-  /**
-   * @param {string} messageId
-   * @param {string} error
-   */
-  _sendErrorResponse(messageId, error) {
-    const message = {id: messageId, error: error};
-    this._port.send(JSON.stringify(message));
-  }
-};
-
-/**
- * @implements {ServicePort}
- * @unrestricted
- */
-WorkerServicePort = class {
-  /**
-   * @param {!Port|!Worker} port
-   */
-  constructor(port) {
-    this._port = port;
-    this._port.onmessage = this._onMessage.bind(this);
-    this._port.onerror = console.error;
-  }
-
-  /**
-   * @override
-   * @param {function(string)} messageHandler
-   * @param {function(string)} closeHandler
-   */
-  setHandlers(messageHandler, closeHandler) {
-    this._messageHandler = messageHandler;
-    this._closeHandler = closeHandler;
-  }
-
-  /**
-   * @override
-   * @param {string} data
-   * @return {!Promise}
-   */
-  send(data) {
-    this._port.postMessage(data);
-    return Promise.resolve();
-  }
-
-  /**
-   * @override
-   * @return {!Promise}
-   */
-  close() {
-    return Promise.resolve();
-  }
-
-  /**
-   * @param {!MessageEvent} event
-   */
-  _onMessage(event) {
-    this._messageHandler(event.data);
-  }
-};
-
-const dispatchers = [];
-
-const worker = /** @type {!Object} */ (self);
-const servicePort = new WorkerServicePort(/** @type {!Worker} */ (worker));
-dispatchers.push(new ServiceDispatcher(servicePort));
diff --git a/front_end/worker_service/module.json b/front_end/worker_service/module.json
deleted file mode 100644
index 252322c..0000000
--- a/front_end/worker_service/module.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "scripts": [
-        "ServiceDispatcher.js"
-    ]
-}
diff --git a/front_end/workspace/FileManager.js b/front_end/workspace/FileManager.js
deleted file mode 100644
index 16063e8..0000000
--- a/front_end/workspace/FileManager.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-Workspace.FileManager = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!Map<string, function(?{fileSystemPath: (string|undefined)})>} */
-    this._saveCallbacks = new Map();
-    InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SavedURL, this._savedURL, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.CanceledSaveURL, this._canceledSavedURL, this);
-    InspectorFrontendHost.events.addEventListener(
-        InspectorFrontendHostAPI.Events.AppendedToURL, this._appendedToURL, this);
-  }
-
-  /**
-   * @param {string} url
-   * @param {string} content
-   * @param {boolean} forceSaveAs
-   * @return {!Promise<?{fileSystemPath: (string|undefined)}>}
-   */
-  save(url, content, forceSaveAs) {
-    // Remove this url from the saved URLs while it is being saved.
-    InspectorFrontendHost.save(url, content, forceSaveAs);
-    return new Promise(resolve => this._saveCallbacks.set(url, resolve));
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _savedURL(event) {
-    const url = /** @type {string} */ (event.data.url);
-    const callback = this._saveCallbacks.get(url);
-    this._saveCallbacks.delete(url);
-    if (callback)
-      callback({fileSystemPath: /** @type {string} */ (event.data.fileSystemPath)});
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _canceledSavedURL(event) {
-    const url = /** @type {string} */ (event.data);
-    const callback = this._saveCallbacks.get(url);
-    this._saveCallbacks.delete(url);
-    if (callback)
-      callback(null);
-  }
-
-  /**
-   * @param {string} url
-   * @param {string} content
-   */
-  append(url, content) {
-    InspectorFrontendHost.append(url, content);
-  }
-
-  /**
-   * @param {string} url
-   */
-  close(url) {
-    // Currently a no-op.
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _appendedToURL(event) {
-    const url = /** @type {string} */ (event.data);
-    this.dispatchEventToListeners(Workspace.FileManager.Events.AppendedToURL, url);
-  }
-};
-
-/** @enum {symbol} */
-Workspace.FileManager.Events = {
-  AppendedToURL: Symbol('AppendedToURL')
-};
-
-/**
- * @type {?Workspace.FileManager}
- */
-Workspace.fileManager;
diff --git a/front_end/workspace/UISourceCode.js b/front_end/workspace/UISourceCode.js
deleted file mode 100644
index 41bf1f8..0000000
--- a/front_end/workspace/UISourceCode.js
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-Workspace.UISourceCode = class extends Common.Object {
-  /**
-   * @param {!Workspace.Project} project
-   * @param {string} url
-   * @param {!Common.ResourceType} contentType
-   */
-  constructor(project, url, contentType) {
-    super();
-    this._project = project;
-    this._url = url;
-
-    const parsedURL = url.asParsedURL();
-    if (parsedURL) {
-      this._origin = parsedURL.securityOrigin();
-      this._parentURL = this._origin + parsedURL.folderPathComponents;
-      this._name = parsedURL.lastPathComponent;
-      if (parsedURL.queryParams)
-        this._name += '?' + parsedURL.queryParams;
-    } else {
-      this._origin = '';
-      this._parentURL = '';
-      this._name = url;
-    }
-
-    this._contentType = contentType;
-    /** @type {?Promise<?string>} */
-    this._requestContentPromise = null;
-    /** @type {?Multimap<string, !Workspace.UISourceCode.LineMarker>} */
-    this._decorations = null;
-    this._hasCommits = false;
-    /** @type {?Set<!Workspace.UISourceCode.Message>} */
-    this._messages = null;
-    this._contentLoaded = false;
-    /** @type {?string} */
-    this._content = null;
-    /** @type {boolean|undefined} */
-    this._contentEncoded;
-    this._forceLoadOnCheckContent = false;
-    this._checkingContent = false;
-    /** @type {?string} */
-    this._lastAcceptedContent = null;
-    /** @type {?string} */
-    this._workingCopy = null;
-    /** @type {?function() : string} */
-    this._workingCopyGetter = null;
-  }
-
-  /**
-   * @return {!Promise<?Workspace.UISourceCodeMetadata>}
-   */
-  requestMetadata() {
-    return this._project.requestMetadata(this);
-  }
-
-  /**
-   * @return {string}
-   */
-  name() {
-    return this._name;
-  }
-
-  /**
-   * @return {string}
-   */
-  mimeType() {
-    return this._project.mimeType(this);
-  }
-
-  /**
-   * @return {string}
-   */
-  url() {
-    return this._url;
-  }
-
-  /**
-   * @return {string}
-   */
-  parentURL() {
-    return this._parentURL;
-  }
-
-  /**
-   * @return {string}
-   */
-  origin() {
-    return this._origin;
-  }
-
-  /**
-   * @return {string}
-   */
-  fullDisplayName() {
-    return this._project.fullDisplayName(this);
-  }
-
-  /**
-   * @param {boolean=} skipTrim
-   * @return {string}
-   */
-  displayName(skipTrim) {
-    if (!this._name)
-      return Common.UIString('(index)');
-    let name = this._name;
-    try {
-      if (this.project().type() === Workspace.projectTypes.FileSystem)
-        name = unescape(name);
-      else
-        name = decodeURI(name);
-    } catch (e) {
-    }
-    return skipTrim ? name : name.trimEnd(100);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canRename() {
-    return this._project.canRename();
-  }
-
-  /**
-   * @param {string} newName
-   * @return {!Promise<boolean>}
-   */
-  rename(newName) {
-    let fulfill;
-    const promise = new Promise(x => fulfill = x);
-    this._project.rename(this, newName, innerCallback.bind(this));
-    return promise;
-
-    /**
-     * @param {boolean} success
-     * @param {string=} newName
-     * @param {string=} newURL
-     * @param {!Common.ResourceType=} newContentType
-     * @this {Workspace.UISourceCode}
-     */
-    function innerCallback(success, newName, newURL, newContentType) {
-      if (success) {
-        this._updateName(
-            /** @type {string} */ (newName), /** @type {string} */ (newURL),
-            /** @type {!Common.ResourceType} */ (newContentType));
-      }
-      fulfill(success);
-    }
-  }
-
-  remove() {
-    this._project.deleteFile(this);
-  }
-
-  /**
-   * @param {string} name
-   * @param {string} url
-   * @param {!Common.ResourceType=} contentType
-   */
-  _updateName(name, url, contentType) {
-    const oldURL = this._url;
-    this._url = this._url.substring(0, this._url.length - this._name.length) + name;
-    this._name = name;
-    if (url)
-      this._url = url;
-    if (contentType)
-      this._contentType = contentType;
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.TitleChanged, this);
-    this.project().workspace().dispatchEventToListeners(
-        Workspace.Workspace.Events.UISourceCodeRenamed, {oldURL: oldURL, uiSourceCode: this});
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  contentURL() {
-    return this.url();
-  }
-
-  /**
-   * @override
-   * @return {!Common.ResourceType}
-   */
-  contentType() {
-    return this._contentType;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<boolean>}
-   */
-  async contentEncoded() {
-    await this.requestContent();
-    return this._contentEncoded || false;
-  }
-
-  /**
-   * @return {!Workspace.Project}
-   */
-  project() {
-    return this._project;
-  }
-
-  /**
-   * @override
-   * @return {!Promise<?string>}
-   */
-  requestContent() {
-    if (this._requestContentPromise)
-      return this._requestContentPromise;
-
-    if (this._contentLoaded) {
-      this._requestContentPromise = Promise.resolve(this._content);
-    } else {
-      let fulfill;
-      this._requestContentPromise = new Promise(x => fulfill = x);
-      this._project.requestFileContent(this, (content, encoded) => {
-        if (!this._contentLoaded) {
-          this._contentLoaded = true;
-          this._content = content;
-          this._contentEncoded = encoded;
-        }
-        fulfill(content);
-      });
-    }
-    return this._requestContentPromise;
-  }
-
-  checkContentUpdated() {
-    if (!this._contentLoaded && !this._forceLoadOnCheckContent)
-      return;
-
-    if (!this._project.canSetFileContent() || this._checkingContent)
-      return;
-
-    this._checkingContent = true;
-    this._project.requestFileContent(this, contentLoaded.bind(this));
-
-    /**
-     * @param {?string} updatedContent
-     * @param {boolean} encoded
-     * @this {Workspace.UISourceCode}
-     */
-    async function contentLoaded(updatedContent, encoded) {
-      this._checkingContent = false;
-      if (updatedContent === null) {
-        const workingCopy = this.workingCopy();
-        this._contentCommitted('', false);
-        this.setWorkingCopy(workingCopy);
-        return;
-      }
-      if (this._lastAcceptedContent === updatedContent)
-        return;
-
-      if (this._content === updatedContent) {
-        this._lastAcceptedContent = null;
-        return;
-      }
-
-      if (!this.isDirty() || this._workingCopy === updatedContent) {
-        this._contentCommitted(/** @type {string} */ (updatedContent), false);
-        return;
-      }
-
-      await Common.Revealer.reveal(this);
-
-      // Make sure we are in the next frame before stopping the world with confirm
-      await new Promise(resolve => setTimeout(resolve, 0));
-
-      const shouldUpdate =
-          window.confirm(Common.UIString('This file was changed externally. Would you like to reload it?'));
-      if (shouldUpdate)
-        this._contentCommitted(/** @type {string} */ (updatedContent), false);
-      else
-        this._lastAcceptedContent = updatedContent;
-    }
-  }
-
-  forceLoadOnCheckContent() {
-    this._forceLoadOnCheckContent = true;
-  }
-
-  /**
-   * @param {string} content
-   */
-  _commitContent(content) {
-    if (this._project.canSetFileContent())
-      this._project.setFileContent(this, content, false, function() {});
-    this._contentCommitted(content, true);
-  }
-
-  /**
-   * @param {string} content
-   * @param {boolean} committedByUser
-   */
-  _contentCommitted(content, committedByUser) {
-    this._lastAcceptedContent = null;
-    this._content = content;
-    this._contentLoaded = true;
-    this._requestContentPromise = null;
-
-    this._hasCommits = true;
-
-    this._innerResetWorkingCopy();
-    this.dispatchEventToListeners(
-        Workspace.UISourceCode.Events.WorkingCopyCommitted, {uiSourceCode: this, content: content});
-    this._project.workspace().dispatchEventToListeners(
-        Workspace.Workspace.Events.WorkingCopyCommitted, {uiSourceCode: this, content: content});
-    if (committedByUser) {
-      this._project.workspace().dispatchEventToListeners(
-          Workspace.Workspace.Events.WorkingCopyCommittedByUser, {uiSourceCode: this, content: content});
-    }
-  }
-
-  /**
-   * @param {string} content
-   */
-  addRevision(content) {
-    this._commitContent(content);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasCommits() {
-    return this._hasCommits;
-  }
-
-  /**
-   * @return {string}
-   */
-  workingCopy() {
-    if (this._workingCopyGetter) {
-      this._workingCopy = this._workingCopyGetter();
-      this._workingCopyGetter = null;
-    }
-    if (this.isDirty())
-      return /** @type {string} */ (this._workingCopy);
-    return this._content || '';
-  }
-
-  resetWorkingCopy() {
-    this._innerResetWorkingCopy();
-    this._workingCopyChanged();
-  }
-
-  _innerResetWorkingCopy() {
-    this._workingCopy = null;
-    this._workingCopyGetter = null;
-  }
-
-  /**
-   * @param {string} newWorkingCopy
-   */
-  setWorkingCopy(newWorkingCopy) {
-    this._workingCopy = newWorkingCopy;
-    this._workingCopyGetter = null;
-    this._workingCopyChanged();
-  }
-
-  /**
-   * @param {string} content
-   * @param {boolean} isBase64
-   */
-  setContent(content, isBase64) {
-    if (this._project.canSetFileContent())
-      this._project.setFileContent(this, content, isBase64, function() {});
-    this._contentCommitted(content, true);
-  }
-
-  /**
-  * @param {function(): string } workingCopyGetter
-  */
-  setWorkingCopyGetter(workingCopyGetter) {
-    this._workingCopyGetter = workingCopyGetter;
-    this._workingCopyChanged();
-  }
-
-  _workingCopyChanged() {
-    this._removeAllMessages();
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.WorkingCopyChanged, this);
-    this._project.workspace().dispatchEventToListeners(
-        Workspace.Workspace.Events.WorkingCopyChanged, {uiSourceCode: this});
-  }
-
-  removeWorkingCopyGetter() {
-    if (!this._workingCopyGetter)
-      return;
-    this._workingCopy = this._workingCopyGetter();
-    this._workingCopyGetter = null;
-  }
-
-  commitWorkingCopy() {
-    if (this.isDirty())
-      this._commitContent(this.workingCopy());
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isDirty() {
-    return this._workingCopy !== null || this._workingCopyGetter !== null;
-  }
-
-  /**
-   * @return {string}
-   */
-  extension() {
-    return Common.ParsedURL.extractExtension(this._name);
-  }
-
-  /**
-   * @return {?string}
-   */
-  content() {
-    return this._content;
-  }
-
-  /**
-   * @override
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInContent(query, caseSensitive, isRegex) {
-    const content = this.content();
-    if (!content)
-      return this._project.searchInFileContent(this, query, caseSensitive, isRegex);
-    return Promise.resolve(Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex));
-  }
-
-  /**
-   * @return {boolean}
-   */
-  contentLoaded() {
-    return this._contentLoaded;
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Workspace.UILocation}
-   */
-  uiLocation(lineNumber, columnNumber) {
-    if (typeof columnNumber === 'undefined')
-      columnNumber = 0;
-    return new Workspace.UILocation(this, lineNumber, columnNumber);
-  }
-
-  /**
-   * @return {!Set<!Workspace.UISourceCode.Message>}
-   */
-  messages() {
-    return this._messages ? new Set(this._messages) : new Set();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message.Level} level
-   * @param {string} text
-   * @param {number} lineNumber
-   * @param {number=} columnNumber
-   * @return {!Workspace.UISourceCode.Message} message
-   */
-  addLineMessage(level, text, lineNumber, columnNumber) {
-    return this.addMessage(
-        level, text, new TextUtils.TextRange(lineNumber, columnNumber || 0, lineNumber, columnNumber || 0));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message.Level} level
-   * @param {string} text
-   * @param {!TextUtils.TextRange} range
-   * @return {!Workspace.UISourceCode.Message} message
-   */
-  addMessage(level, text, range) {
-    const message = new Workspace.UISourceCode.Message(this, level, text, range);
-    if (!this._messages)
-      this._messages = new Set();
-    this._messages.add(message);
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.MessageAdded, message);
-    return message;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message} message
-   */
-  removeMessage(message) {
-    if (this._messages && this._messages.delete(message))
-      this.dispatchEventToListeners(Workspace.UISourceCode.Events.MessageRemoved, message);
-  }
-
-  _removeAllMessages() {
-    if (!this._messages)
-      return;
-    for (const message of this._messages)
-      this.dispatchEventToListeners(Workspace.UISourceCode.Events.MessageRemoved, message);
-    this._messages = null;
-  }
-
-  /**
-   * @param {number} lineNumber
-   * @param {string} type
-   * @param {?} data
-   */
-  addLineDecoration(lineNumber, type, data) {
-    this.addDecoration(TextUtils.TextRange.createFromLocation(lineNumber, 0), type, data);
-  }
-
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {string} type
-   * @param {?} data
-   */
-  addDecoration(range, type, data) {
-    const marker = new Workspace.UISourceCode.LineMarker(range, type, data);
-    if (!this._decorations)
-      this._decorations = new Multimap();
-    this._decorations.set(type, marker);
-    this.dispatchEventToListeners(Workspace.UISourceCode.Events.LineDecorationAdded, marker);
-  }
-
-  /**
-   * @param {string} type
-   */
-  removeDecorationsForType(type) {
-    if (!this._decorations)
-      return;
-    const markers = this._decorations.get(type);
-    this._decorations.deleteAll(type);
-    markers.forEach(marker => {
-      this.dispatchEventToListeners(Workspace.UISourceCode.Events.LineDecorationRemoved, marker);
-    });
-  }
-
-  /**
-   * @return {!Array<!Workspace.UISourceCode.LineMarker>}
-   */
-  allDecorations() {
-    return this._decorations ? this._decorations.valuesArray() : [];
-  }
-
-  removeAllDecorations() {
-    if (!this._decorations)
-      return;
-    const decorationList = this._decorations.valuesArray();
-    this._decorations.clear();
-    decorationList.forEach(
-        marker => this.dispatchEventToListeners(Workspace.UISourceCode.Events.LineDecorationRemoved, marker));
-  }
-
-  /**
-   * @param {string} type
-   * @return {?Set<!Workspace.UISourceCode.LineMarker>}
-   */
-  decorationsForType(type) {
-    return this._decorations ? this._decorations.get(type) : null;
-  }
-};
-
-/** @enum {symbol} */
-Workspace.UISourceCode.Events = {
-  WorkingCopyChanged: Symbol('WorkingCopyChanged'),
-  WorkingCopyCommitted: Symbol('WorkingCopyCommitted'),
-  TitleChanged: Symbol('TitleChanged'),
-  MessageAdded: Symbol('MessageAdded'),
-  MessageRemoved: Symbol('MessageRemoved'),
-  LineDecorationAdded: Symbol('LineDecorationAdded'),
-  LineDecorationRemoved: Symbol('LineDecorationRemoved')
-};
-
-/**
- * @unrestricted
- */
-Workspace.UILocation = class {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {number} lineNumber
-   * @param {number} columnNumber
-   */
-  constructor(uiSourceCode, lineNumber, columnNumber) {
-    this.uiSourceCode = uiSourceCode;
-    this.lineNumber = lineNumber;
-    this.columnNumber = columnNumber;
-  }
-
-  /**
-   * @param {boolean=} skipTrim
-   * @return {string}
-   */
-  linkText(skipTrim) {
-    let linkText = this.uiSourceCode.displayName(skipTrim);
-    if (typeof this.lineNumber === 'number')
-      linkText += ':' + (this.lineNumber + 1);
-    return linkText;
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this.uiSourceCode.project().id() + ':' + this.uiSourceCode.url() + ':' + this.lineNumber + ':' +
-        this.columnNumber;
-  }
-
-  /**
-   * @return {string}
-   */
-  toUIString() {
-    return this.uiSourceCode.url() + ':' + (this.lineNumber + 1);
-  }
-
-  /**
-   * @param {!Workspace.UILocation} location1
-   * @param {!Workspace.UILocation} location2
-   * @return {number}
-   */
-  static comparator(location1, location2) {
-    return location1.compareTo(location2);
-  }
-
-  /**
-   * @param {!Workspace.UILocation} other
-   * @return {number}
-   */
-  compareTo(other) {
-    if (this.uiSourceCode.url() !== other.uiSourceCode.url())
-      return this.uiSourceCode.url() > other.uiSourceCode.url() ? 1 : -1;
-    if (this.lineNumber !== other.lineNumber)
-      return this.lineNumber - other.lineNumber;
-    return this.columnNumber - other.columnNumber;
-  }
-};
-
-/**
- * @unrestricted
- */
-Workspace.UISourceCode.Message = class {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {!Workspace.UISourceCode.Message.Level} level
-   * @param {string} text
-   * @param {!TextUtils.TextRange} range
-   */
-  constructor(uiSourceCode, level, text, range) {
-    this._uiSourceCode = uiSourceCode;
-    this._level = level;
-    this._text = text;
-    this._range = range;
-  }
-
-  /**
-   * @return {!Workspace.UISourceCode}
-   */
-  uiSourceCode() {
-    return this._uiSourceCode;
-  }
-
-  /**
-   * @return {!Workspace.UISourceCode.Message.Level}
-   */
-  level() {
-    return this._level;
-  }
-
-  /**
-   * @return {string}
-   */
-  text() {
-    return this._text;
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  range() {
-    return this._range;
-  }
-
-  /**
-   * @return {number}
-   */
-  lineNumber() {
-    return this._range.startLine;
-  }
-
-  /**
-   * @return {(number|undefined)}
-   */
-  columnNumber() {
-    return this._range.startColumn;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode.Message} another
-   * @return {boolean}
-   */
-  isEqual(another) {
-    return this._uiSourceCode === another._uiSourceCode && this.text() === another.text() &&
-        this.level() === another.level() && this.range().equal(another.range());
-  }
-
-  remove() {
-    this._uiSourceCode.removeMessage(this);
-  }
-};
-
-/**
- * @enum {string}
- */
-Workspace.UISourceCode.Message.Level = {
-  Error: 'Error',
-  Warning: 'Warning'
-};
-
-/**
- * @unrestricted
- */
-Workspace.UISourceCode.LineMarker = class {
-  /**
-   * @param {!TextUtils.TextRange} range
-   * @param {string} type
-   * @param {?} data
-   */
-  constructor(range, type, data) {
-    this._range = range;
-    this._type = type;
-    this._data = data;
-  }
-
-  /**
-   * @return {!TextUtils.TextRange}
-   */
-  range() {
-    return this._range;
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {*}
-   */
-  data() {
-    return this._data;
-  }
-};
-
-/**
- * @unrestricted
- */
-Workspace.UISourceCodeMetadata = class {
-  /**
-   * @param {?Date} modificationTime
-   * @param {?number} contentSize
-   */
-  constructor(modificationTime, contentSize) {
-    this.modificationTime = modificationTime;
-    this.contentSize = contentSize;
-  }
-};
diff --git a/front_end/workspace/Workspace.js b/front_end/workspace/Workspace.js
deleted file mode 100644
index 5577980..0000000
--- a/front_end/workspace/Workspace.js
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @interface
- */
-Workspace.ProjectSearchConfig = function() {};
-
-Workspace.ProjectSearchConfig.prototype = {
-  /**
-   * @return {string}
-   */
-  query() {},
-
-  /**
-   * @return {boolean}
-   */
-  ignoreCase() {},
-
-  /**
-   * @return {boolean}
-   */
-  isRegex() {},
-
-  /**
-   * @return {!Array.<string>}
-   */
-  queries() {},
-
-  /**
-   * @param {string} filePath
-   * @return {boolean}
-   */
-  filePathMatchesFileQuery(filePath) {}
-};
-
-/**
- * @interface
- */
-Workspace.Project = function() {};
-
-Workspace.Project.prototype = {
-  /**
-   * @return {!Workspace.Workspace}
-   */
-  workspace() {},
-
-  /**
-   * @return {string}
-   */
-  id() {},
-
-  /**
-   * @return {string}
-   */
-  type() {},
-
-  /**
-   * @return {boolean}
-   */
-  isServiceProject() {},
-
-  /**
-   * @return {string}
-   */
-  displayName() {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<?Workspace.UISourceCodeMetadata>}
-   */
-  requestMetadata(uiSourceCode) {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function(?string,boolean)} callback
-   */
-  requestFileContent(uiSourceCode, callback) {},
-
-  /**
-   * @return {boolean}
-   */
-  canSetFileContent() {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newContent
-   * @param {boolean} isBase64
-   * @param {function(?string)} callback
-   */
-  setFileContent(uiSourceCode, newContent, isBase64, callback) {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  fullDisplayName(uiSourceCode) {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {string}
-   */
-  mimeType(uiSourceCode) {},
-
-  /**
-   * @return {boolean}
-   */
-  canRename() {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newName
-   * @param {function(boolean, string=, string=, !Common.ResourceType=)} callback
-   */
-  rename(uiSourceCode, newName, callback) {},
-
-  /**
-   * @param {string} path
-   */
-  excludeFolder(path) {},
-
-  /**
-   * @param {string} path
-   * @return {boolean}
-   */
-  canExcludeFolder(path) {},
-
-  /**
-   * @param {string} path
-   * @param {?string} name
-   * @param {string} content
-   * @param {boolean=} isBase64
-   * @return {!Promise<?Workspace.UISourceCode>}
-   */
-  createFile(path, name, content, isBase64) {},
-
-  /**
-   * @return {boolean}
-   */
-  canCreateFile() {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  deleteFile(uiSourceCode) {},
-
-  remove() {},
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} query
-   * @param {boolean} caseSensitive
-   * @param {boolean} isRegex
-   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
-   */
-  searchInFileContent(uiSourceCode, query, caseSensitive, isRegex) {},
-
-  /**
-   * @param {!Workspace.ProjectSearchConfig} searchConfig
-   * @param {!Array.<string>} filesMathingFileQuery
-   * @param {!Common.Progress} progress
-   * @return {!Promise<!Array<string>>}
-   */
-  findFilesMatchingSearchRequest(searchConfig, filesMathingFileQuery, progress) {},
-
-  /**
-   * @param {!Common.Progress} progress
-   */
-  indexContent(progress) {},
-
-  /**
-   * @param {string} url
-   * @return {?Workspace.UISourceCode}
-   */
-  uiSourceCodeForURL(url) {},
-
-  /**
-   * @return {!Array.<!Workspace.UISourceCode>}
-   */
-  uiSourceCodes() {}
-};
-
-/**
- * @enum {string}
- */
-Workspace.projectTypes = {
-  Debugger: 'debugger',
-  Formatter: 'formatter',
-  Network: 'network',
-  Snippets: 'snippets',
-  FileSystem: 'filesystem',
-  ContentScripts: 'contentscripts',
-  Service: 'service'
-};
-
-/**
- * @unrestricted
- */
-Workspace.ProjectStore = class {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   * @param {string} id
-   * @param {!Workspace.projectTypes} type
-   * @param {string} displayName
-   */
-  constructor(workspace, id, type, displayName) {
-    this._workspace = workspace;
-    this._id = id;
-    this._type = type;
-    this._displayName = displayName;
-
-    /** @type {!Map.<string, !{uiSourceCode: !Workspace.UISourceCode, index: number}>} */
-    this._uiSourceCodesMap = new Map();
-    /** @type {!Array.<!Workspace.UISourceCode>} */
-    this._uiSourceCodesList = [];
-
-    this._project = /** @type {!Workspace.Project} */ (this);
-  }
-
-  /**
-   * @return {string}
-   */
-  id() {
-    return this._id;
-  }
-
-  /**
-   * @return {string}
-   */
-  type() {
-    return this._type;
-  }
-
-  /**
-   * @return {string}
-   */
-  displayName() {
-    return this._displayName;
-  }
-
-  /**
-   * @return {!Workspace.Workspace}
-   */
-  workspace() {
-    return this._workspace;
-  }
-
-  /**
-   * @param {string} url
-   * @param {!Common.ResourceType} contentType
-   * @return {!Workspace.UISourceCode}
-   */
-  createUISourceCode(url, contentType) {
-    return new Workspace.UISourceCode(this._project, url, contentType);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {boolean}
-   */
-  addUISourceCode(uiSourceCode) {
-    const url = uiSourceCode.url();
-    if (this.uiSourceCodeForURL(url))
-      return false;
-    this._uiSourceCodesMap.set(url, {uiSourceCode: uiSourceCode, index: this._uiSourceCodesList.length});
-    this._uiSourceCodesList.push(uiSourceCode);
-    this._workspace.dispatchEventToListeners(Workspace.Workspace.Events.UISourceCodeAdded, uiSourceCode);
-    return true;
-  }
-
-  /**
-   * @param {string} url
-   */
-  removeUISourceCode(url) {
-    const uiSourceCode = this.uiSourceCodeForURL(url);
-    if (!uiSourceCode)
-      return;
-
-    const entry = this._uiSourceCodesMap.get(url);
-    const movedUISourceCode = this._uiSourceCodesList[this._uiSourceCodesList.length - 1];
-    this._uiSourceCodesList[entry.index] = movedUISourceCode;
-    const movedEntry = this._uiSourceCodesMap.get(movedUISourceCode.url());
-    movedEntry.index = entry.index;
-    this._uiSourceCodesList.splice(this._uiSourceCodesList.length - 1, 1);
-    this._uiSourceCodesMap.delete(url);
-    this._workspace.dispatchEventToListeners(Workspace.Workspace.Events.UISourceCodeRemoved, entry.uiSourceCode);
-  }
-
-  removeProject() {
-    this._workspace._removeProject(this._project);
-    this._uiSourceCodesMap = new Map();
-    this._uiSourceCodesList = [];
-  }
-
-  /**
-   * @param {string} url
-   * @return {?Workspace.UISourceCode}
-   */
-  uiSourceCodeForURL(url) {
-    const entry = this._uiSourceCodesMap.get(url);
-    return entry ? entry.uiSourceCode : null;
-  }
-
-  /**
-   * @return {!Array.<!Workspace.UISourceCode>}
-   */
-  uiSourceCodes() {
-    return this._uiSourceCodesList;
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {string} newName
-   */
-  renameUISourceCode(uiSourceCode, newName) {
-    const oldPath = uiSourceCode.url();
-    const newPath = uiSourceCode.parentURL() ? uiSourceCode.parentURL() + '/' + newName : newName;
-    const value =
-        /** @type {!{uiSourceCode: !Workspace.UISourceCode, index: number}} */ (this._uiSourceCodesMap.get(oldPath));
-    this._uiSourceCodesMap.set(newPath, value);
-    this._uiSourceCodesMap.delete(oldPath);
-  }
-};
-
-/**
- * @unrestricted
- */
-Workspace.Workspace = class extends Common.Object {
-  constructor() {
-    super();
-    /** @type {!Map<string, !Workspace.Project>} */
-    this._projects = new Map();
-    this._hasResourceContentTrackingExtensions = false;
-  }
-
-  /**
-   * @param {string} projectId
-   * @param {string} url
-   * @return {?Workspace.UISourceCode}
-   */
-  uiSourceCode(projectId, url) {
-    const project = this._projects.get(projectId);
-    return project ? project.uiSourceCodeForURL(url) : null;
-  }
-
-  /**
-   * @param {string} url
-   * @return {?Workspace.UISourceCode}
-   */
-  uiSourceCodeForURL(url) {
-    for (const project of this._projects.values()) {
-      const uiSourceCode = project.uiSourceCodeForURL(url);
-      if (uiSourceCode)
-        return uiSourceCode;
-    }
-    return null;
-  }
-
-  /**
-   * @param {string} type
-   * @return {!Array.<!Workspace.UISourceCode>}
-   */
-  uiSourceCodesForProjectType(type) {
-    let result = [];
-    for (const project of this._projects.values()) {
-      if (project.type() === type)
-        result = result.concat(project.uiSourceCodes());
-    }
-    return result;
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  addProject(project) {
-    console.assert(!this._projects.has(project.id()), `A project with id ${project.id()} already exists!`);
-    this._projects.set(project.id(), project);
-    this.dispatchEventToListeners(Workspace.Workspace.Events.ProjectAdded, project);
-  }
-
-  /**
-   * @param {!Workspace.Project} project
-   */
-  _removeProject(project) {
-    this._projects.delete(project.id());
-    this.dispatchEventToListeners(Workspace.Workspace.Events.ProjectRemoved, project);
-  }
-
-  /**
-   * @param {string} projectId
-   * @return {?Workspace.Project}
-   */
-  project(projectId) {
-    return this._projects.get(projectId) || null;
-  }
-
-  /**
-   * @return {!Array.<!Workspace.Project>}
-   */
-  projects() {
-    return this._projects.valuesArray();
-  }
-
-  /**
-   * @param {string} type
-   * @return {!Array.<!Workspace.Project>}
-   */
-  projectsForType(type) {
-    function filterByType(project) {
-      return project.type() === type;
-    }
-    return this.projects().filter(filterByType);
-  }
-
-  /**
-   * @return {!Array.<!Workspace.UISourceCode>}
-   */
-  uiSourceCodes() {
-    let result = [];
-    for (const project of this._projects.values())
-      result = result.concat(project.uiSourceCodes());
-    return result;
-  }
-
-  /**
-   * @param {boolean} hasExtensions
-   */
-  setHasResourceContentTrackingExtensions(hasExtensions) {
-    this._hasResourceContentTrackingExtensions = hasExtensions;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasResourceContentTrackingExtensions() {
-    return this._hasResourceContentTrackingExtensions;
-  }
-};
-
-/** @enum {symbol} */
-Workspace.Workspace.Events = {
-  UISourceCodeAdded: Symbol('UISourceCodeAdded'),
-  UISourceCodeRemoved: Symbol('UISourceCodeRemoved'),
-  UISourceCodeRenamed: Symbol('UISourceCodeRenamed'),
-  WorkingCopyChanged: Symbol('WorkingCopyChanged'),
-  WorkingCopyCommitted: Symbol('WorkingCopyCommitted'),
-  WorkingCopyCommittedByUser: Symbol('WorkingCopyCommittedByUser'),
-  ProjectAdded: Symbol('ProjectAdded'),
-  ProjectRemoved: Symbol('ProjectRemoved')
-};
-
-/**
- * @type {!Workspace.Workspace}
- */
-Workspace.workspace;
diff --git a/front_end/workspace/module.json b/front_end/workspace/module.json
deleted file mode 100644
index 56005a8..0000000
--- a/front_end/workspace/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "dependencies": [
-        "common",
-        "host",
-        "platform"
-    ],
-    "scripts": [
-        "FileManager.js",
-        "UISourceCode.js",
-        "Workspace.js"
-    ]
-}
diff --git a/front_end/workspace_diff/WorkspaceDiff.js b/front_end/workspace_diff/WorkspaceDiff.js
deleted file mode 100644
index 98791f0..0000000
--- a/front_end/workspace_diff/WorkspaceDiff.js
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-WorkspaceDiff.WorkspaceDiff = class extends Common.Object {
-  /**
-   * @param {!Workspace.Workspace} workspace
-   */
-  constructor(workspace) {
-    super();
-    /** @type {!WeakMap<!Workspace.UISourceCode, !WorkspaceDiff.WorkspaceDiff.UISourceCodeDiff>} */
-    this._uiSourceCodeDiffs = new WeakMap();
-
-    /** @type {!Map<!Workspace.UISourceCode, !Promise>} */
-    this._loadingUISourceCodes = new Map();
-
-    /** @type {!Set<!Workspace.UISourceCode>} */
-    this._modifiedUISourceCodes = new Set();
-    workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyChanged, this._uiSourceCodeChanged, this);
-    workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyCommitted, this._uiSourceCodeChanged, this);
-    workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
-    workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
-    workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
-    workspace.uiSourceCodes().forEach(this._updateModifiedState.bind(this));
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<?Diff.Diff.DiffArray>}
-   */
-  requestDiff(uiSourceCode) {
-    return this._uiSourceCodeDiff(uiSourceCode).requestDiff();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function(!Common.Event)} callback
-   * @param {!Object=} thisObj
-   */
-  subscribeToDiffChange(uiSourceCode, callback, thisObj) {
-    this._uiSourceCodeDiff(uiSourceCode).addEventListener(WorkspaceDiff.Events.DiffChanged, callback, thisObj);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @param {function(!Common.Event)} callback
-   * @param {!Object=} thisObj
-   */
-  unsubscribeFromDiffChange(uiSourceCode, callback, thisObj) {
-    this._uiSourceCodeDiff(uiSourceCode).removeEventListener(WorkspaceDiff.Events.DiffChanged, callback, thisObj);
-  }
-
-  /**
-   * @return {!Array<!Workspace.UISourceCode>}
-   */
-  modifiedUISourceCodes() {
-    return Array.from(this._modifiedUISourceCodes);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!WorkspaceDiff.WorkspaceDiff.UISourceCodeDiff}
-   */
-  _uiSourceCodeDiff(uiSourceCode) {
-    if (!this._uiSourceCodeDiffs.has(uiSourceCode))
-      this._uiSourceCodeDiffs.set(uiSourceCode, new WorkspaceDiff.WorkspaceDiff.UISourceCodeDiff(uiSourceCode));
-    return this._uiSourceCodeDiffs.get(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeChanged(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data.uiSourceCode);
-    this._updateModifiedState(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeAdded(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._updateModifiedState(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _uiSourceCodeRemoved(event) {
-    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
-    this._removeUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _projectRemoved(event) {
-    const project = /** @type {!Workspace.Project} */ (event.data);
-    for (const uiSourceCode of project.uiSourceCodes())
-      this._removeUISourceCode(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _removeUISourceCode(uiSourceCode) {
-    this._loadingUISourceCodes.delete(uiSourceCode);
-    const uiSourceCodeDiff = this._uiSourceCodeDiffs.get(uiSourceCode);
-    if (uiSourceCodeDiff)
-      uiSourceCodeDiff._dispose = true;
-    this._markAsUnmodified(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _markAsUnmodified(uiSourceCode) {
-    this._uiSourceCodeProcessedForTest();
-    if (this._modifiedUISourceCodes.delete(uiSourceCode))
-      this.dispatchEventToListeners(WorkspaceDiff.Events.ModifiedStatusChanged, {uiSourceCode, isModified: false});
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  _markAsModified(uiSourceCode) {
-    this._uiSourceCodeProcessedForTest();
-    if (this._modifiedUISourceCodes.has(uiSourceCode))
-      return;
-    this._modifiedUISourceCodes.add(uiSourceCode);
-    this.dispatchEventToListeners(WorkspaceDiff.Events.ModifiedStatusChanged, {uiSourceCode, isModified: true});
-  }
-
-  _uiSourceCodeProcessedForTest() {
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  async _updateModifiedState(uiSourceCode) {
-    this._loadingUISourceCodes.delete(uiSourceCode);
-
-    if (uiSourceCode.project().type() !== Workspace.projectTypes.Network) {
-      this._markAsUnmodified(uiSourceCode);
-      return;
-    }
-    if (uiSourceCode.isDirty()) {
-      this._markAsModified(uiSourceCode);
-      return;
-    }
-    if (!uiSourceCode.hasCommits()) {
-      this._markAsUnmodified(uiSourceCode);
-      return;
-    }
-
-    const contentsPromise =
-        Promise.all([this.requestOriginalContentForUISourceCode(uiSourceCode), uiSourceCode.requestContent()]);
-    this._loadingUISourceCodes.set(uiSourceCode, contentsPromise);
-    const contents = await contentsPromise;
-    if (this._loadingUISourceCodes.get(uiSourceCode) !== contentsPromise)
-      return;
-    this._loadingUISourceCodes.delete(uiSourceCode);
-
-    if (contents[0] !== null && contents[1] !== null && contents[0] !== contents[1])
-      this._markAsModified(uiSourceCode);
-    else
-      this._markAsUnmodified(uiSourceCode);
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise<?string>}
-   */
-  requestOriginalContentForUISourceCode(uiSourceCode) {
-    return this._uiSourceCodeDiff(uiSourceCode)._originalContent();
-  }
-
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   * @return {!Promise}
-   */
-  revertToOriginal(uiSourceCode) {
-    /**
-     * @param {?string} content
-     */
-    function callback(content) {
-      if (typeof content !== 'string')
-        return;
-
-      uiSourceCode.addRevision(content);
-    }
-
-    Host.userMetrics.actionTaken(Host.UserMetrics.Action.RevisionApplied);
-    return this.requestOriginalContentForUISourceCode(uiSourceCode).then(callback);
-  }
-};
-
-WorkspaceDiff.WorkspaceDiff.UISourceCodeDiff = class extends Common.Object {
-  /**
-   * @param {!Workspace.UISourceCode} uiSourceCode
-   */
-  constructor(uiSourceCode) {
-    super();
-    this._uiSourceCode = uiSourceCode;
-    uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeChanged, this);
-    uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeChanged, this);
-    this._requestDiffPromise = null;
-    this._pendingChanges = null;
-    this._dispose = false;
-  }
-
-  _uiSourceCodeChanged() {
-    if (this._pendingChanges) {
-      clearTimeout(this._pendingChanges);
-      this._pendingChanges = null;
-    }
-    this._requestDiffPromise = null;
-
-    const content = this._uiSourceCode.content();
-    const delay = (!content || content.length < 65536) ? 0 : WorkspaceDiff.WorkspaceDiff.UpdateTimeout;
-    this._pendingChanges = setTimeout(emitDiffChanged.bind(this), delay);
-
-    /**
-     * @this {WorkspaceDiff.WorkspaceDiff.UISourceCodeDiff}
-     */
-    function emitDiffChanged() {
-      if (this._dispose)
-        return;
-      this.dispatchEventToListeners(WorkspaceDiff.Events.DiffChanged);
-      this._pendingChanges = null;
-    }
-  }
-
-  /**
-   * @return {!Promise<?Diff.Diff.DiffArray>}
-   */
-  requestDiff() {
-    if (!this._requestDiffPromise)
-      this._requestDiffPromise = this._innerRequestDiff();
-    return this._requestDiffPromise;
-  }
-
-  /**
-   * @return {!Promise<?string>}
-   */
-  _originalContent() {
-    const originalNetworkContent =
-        Persistence.networkPersistenceManager.originalContentForUISourceCode(this._uiSourceCode);
-    if (originalNetworkContent)
-      return originalNetworkContent;
-
-    let callback;
-    const promise = new Promise(fulfill => callback = fulfill);
-    this._uiSourceCode.project().requestFileContent(this._uiSourceCode, callback);
-    return promise;
-  }
-
-  /**
-   * @return {!Promise<?Diff.Diff.DiffArray>}
-   */
-  async _innerRequestDiff() {
-    if (this._dispose)
-      return null;
-
-    const baseline = await this._originalContent();
-    if (baseline.length > 1024 * 1024)
-      return null;
-    // ------------ ASYNC ------------
-    if (this._dispose)
-      return null;
-
-    let current = this._uiSourceCode.workingCopy();
-    if (!current && !this._uiSourceCode.contentLoaded())
-      current = await this._uiSourceCode.requestContent();
-    if (current.length > 1024 * 1024)
-      return null;
-    // ------------ ASYNC ------------
-
-    if (this._dispose)
-      return null;
-
-    if (current === null || baseline === null)
-      return null;
-    return Diff.Diff.lineDiff(baseline.split(/\r\n|\n|\r/), current.split(/\r\n|\n|\r/));
-  }
-};
-
-/**
- * @enum {symbol}
- */
-WorkspaceDiff.Events = {
-  DiffChanged: Symbol('DiffChanged'),
-  ModifiedStatusChanged: Symbol('ModifiedStatusChanged')
-};
-
-/**
- * @return {!WorkspaceDiff.WorkspaceDiff}
- */
-WorkspaceDiff.workspaceDiff = function() {
-  if (!WorkspaceDiff.WorkspaceDiff._instance)
-    WorkspaceDiff.WorkspaceDiff._instance = new WorkspaceDiff.WorkspaceDiff(Workspace.workspace);
-  return WorkspaceDiff.WorkspaceDiff._instance;
-};
-
-WorkspaceDiff.WorkspaceDiff.UpdateTimeout = 200;
\ No newline at end of file
diff --git a/front_end/workspace_diff/module.json b/front_end/workspace_diff/module.json
deleted file mode 100644
index 0860770..0000000
--- a/front_end/workspace_diff/module.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "dependencies": [
-      "workspace",
-      "diff",
-      "persistence"
-  ],
-  "scripts": [
-      "WorkspaceDiff.js"
-  ]
-}
\ No newline at end of file
diff --git a/package.json b/package.json
deleted file mode 100644
index 6df88ea..0000000
--- a/package.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "name": "chrome-devtools-frontend",
-  "description": "Chrome DevTools UI",
-  "scripts": {
-    "start": "node scripts/start_chrome_and_server.js",
-    "chrome": "node scripts/chrome_debug_launcher/launch_chrome.js",
-    "server": "node scripts/hosted_mode/server.js",
-    "test": "node scripts/npm_test.js",
-    "debug-test": "node scripts/npm_test.js --debug-devtools",
-    "lint": "eslint front_end",
-    "closure": "python scripts/compile_frontend.py",
-    "setup-dtrun": "cd scripts/devtools_run && npm link",
-    "format-py": "yapf --exclude scripts/build/rjsmin.py -i --recursive scripts PRESUBMIT.py",
-    "extract": "node scripts/extract_module/extract_module.js",
-    "check-gn": "node scripts/check_gn.js",
-    "check-json": "node scripts/json_validator/validate_module_json.js"
-  },
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/ChromeDevTools/devtools-frontend.git"
-  },
-  "keywords": [
-    "devtools",
-    "chrome",
-    "chromium",
-    "blink",
-    "debugger"
-  ],
-  "author": "The Chromium Authors",
-  "license": "SEE LICENSE IN https://chromium.googlesource.com/chromium/src/+/master/LICENSE",
-  "bugs": {
-    "url": "https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component:Platform%3EDevTools%20&sort=-opened&colspec=ID%20Stars%20Owner%20Summary%20Modified%20Opened"
-  },
-  "homepage": "https://devtools.chrome.com",
-  "devDependencies": {
-    "ajv": "^5.1.5"
-  }
-}
diff --git a/protocol.json b/protocol.json
deleted file mode 100644
index abca7b5..0000000
--- a/protocol.json
+++ /dev/null
@@ -1,12 +0,0 @@
-The protocol.json has split into separate files. https://crbug.com/580337
-
-One for the browser, one for a V8 javascript environment:
-    src/third_party/WebKit/Source/core/inspector/browser_protocol.json
-    src/v8/src/inspector/js_protocol.json
-
-Browsable here:
-    https://chromium.googlesource.com/chromium/src/+/master/third_party/WebKit/Source/core/inspector/browser_protocol.json
-    https://chromium.googlesource.com/v8/v8/+/master/src/inspector/js_protocol.json
-
-More details on the protocol:
-    https://developer.chrome.com/devtools/docs/debugger-protocol
diff --git a/readme.md b/readme.md
deleted file mode 100644
index 8fee41f..0000000
--- a/readme.md
+++ /dev/null
@@ -1,124 +0,0 @@
-# Chrome DevTools frontend
-
-The client-side of the Chrome DevTools, including all JS & CSS to run the DevTools webapp.
-
-It is available on NPM as the [chrome-devtools-frontend](https://www.npmjs.com/package/chrome-devtools-frontend) package. It's not currently available via CJS or ES2015 modules, so consuming this package in other tools may require [some effort](https://github.com/paulirish/devtools-timeline-model/blob/master/index.js).
-
-#### Package versioning
-The version number of the npm package (e.g. `1.0.373466`) refers to the Chromium commit position of latest frontend git commit. It's incremented with every Chromium commit, however the package is updated roughly daily.
-
-### Source code
-The frontend is available through a git subtree mirror on [chromium.googlesource.com](https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/devtools/), with a regularly updating GitHub mirror at [github.com/ChromeDevTools/devtools-frontend](https://github.com/ChromeDevTools/devtools-frontend). The codebase's true location is in `third_party/WebKit/Source/devtools/` in [Chromium's git repo](https://chromium.googlesource.com/chromium/src/).
-
-### Getting Started
-
-1. Clone the repo
-2. Go to repo root and run:  `npm start`
-    - This launches Chrome Canary and starts the dev server with 1 command
-3. Go to http://localhost:9222#custom=true&experiments=true
-
-> **Power user tips:**
->
-> You can customize the port for the dev server: e.g. `PORT=8888 npm start`.
->
-> You can also launch chrome and start the server separately:
-> - `npm run chrome`
-> - `npm run server`
->
-> When you start Chrome separately, you can pass extra args to Chrome:
-> ```
-> npm run chrome -- https://news.ycombinator.com
-> ```
-> (e.g. this launches Hacker News on startup)
->
-> If you want to reset your development profile for Chrome, pass in "--reset-profile":
-> ```
-> npm start -- --reset-profile
-> ```
-> *OR*
-> ```
-> npm run chrome -- --reset-profile
-> ```
-
-### Hacking
-* DevTools documentation: [devtools.chrome.com](https://devtools.chrome.com)
-* [Debugging protocol docs](https://developer.chrome.com/devtools/docs/debugger-protocol) and [Chrome Debugging Protocol Viewer](http://chromedevtools.github.io/debugger-protocol-viewer/)
-* [awesome-chrome-devtools](https://github.com/paulirish/awesome-chrome-devtools): recommended tools and resources
-* Contributing to DevTools: [bit.ly/devtools-contribution-guide](http://bit.ly/devtools-contribution-guide)
-
-### Useful Commands
-
-#### Simpler npm commands w/ `dtrun`
-If you want to run these npm commands anywhere in the chromium repo (e.g. in chromium/src), you'll want to setup our `dtrun` CLI helper.
-
-One-time setup:
-```
-npm run setup-dtrun
-```
-
-Now, you can use any of the following commands by simply doing: `dtrun test`. 
-
-In addition, you no longer need to pass double dashes (e.g. `--`) before you pass in the flags. So you can do: `dtrun test -d inspector/test.html`.
-
-#### `npm run format` 
-Formats your code using clang-format
-
-### `npm run format-py`
-Formats your Python code using [yapf](https://github.com/google/yapf)
-
-> Note: Yapf is a command line tool. You will have to install this manually, either from PyPi through `pip install yapf` or if you want to enable multiprocessing in Python 2.7, `pip install futures`
-
-#### `npm test`
-Builds devtools and runs all inspector/devtools layout tests.
-
-> Note: If you're using a full chromium checkout and compiled content shell in out/Release, then `npm test` uses that. Otherwise, with only a front-end checkout (i.e. cloning from GitHub), then `npm test` will fetch a previously compiled content shell from the cloud (and cache it for future test runs).
-
-#### `npm test` basics
-```
-# run specific tests
-npm test -- inspector/sources inspector/console
-
-# debug a specific test. Any one of:
-npm run debug-test inspector/cookie-resource-match.html
-npm test -- --debug-devtools inspector/cookie-resource-match.html 
-npm test -- -d inspector/cookie-resource-match.html 
-
-# pass in additional flags to the test harness
-npm test -- -f --child-processes=16
-
-# ...for example, use a higher test timeout
-npm test -- --time-out-ms=6000000 <test_path>
-```
-
-> **Tip**: [Learn about the test harness flags](https://chromium.googlesource.com/chromium/src/+/master/docs/testing/layout_tests.md#Test-Harness-Options)
-
-#### `--fetch-content-shell`
-```
-# If you're using a full chromium checkout and have a compiled content shell, 
-# this will fetch a pre-compiled content shell. This is useful if you 
-# haven't compiled your content shell recently
-npm test -- --fetch-content-shell
-```
-
-#### `--target=SUB_DIRECTORY_NAME`
-```
-# If you're using a build sub-directory that's not out/Release, 
-# such as out/Default, then use --target=SUB_DIRECTORY_NAME
-npm test -- --target=Default
-```
-### Development
-* All devtools commits: [View the log], [RSS feed] or [@DevToolsCommits] on Twitter
-* [All open DevTools tickets] on crbug.com
-* File a new DevTools ticket: [new.crbug.com](https://bugs.chromium.org/p/chromium/issues/entry?labels=OS-All,Type-Bug,Pri-2&components=Platform%3EDevTools)
-* Code reviews mailing list: [devtools-reviews@chromium.org]
-
-### Getting in touch
-* [@ChromeDevTools] on Twitter
-* Chrome DevTools mailing list: [groups.google.com/forum/google-chrome-developer-tools](https://groups.google.com/forum/#!forum/google-chrome-developer-tools)
-
-  [devtools-reviews@chromium.org]: https://groups.google.com/a/chromium.org/forum/#!forum/devtools-reviews
-  [RSS feed]: https://feeds.peter.sh/chrome-devtools/
-  [View the log]: https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/devtools/+log/master
-  [@ChromeDevTools]: http://twitter.com/ChromeDevTools
-  [@DevToolsCommits]: http://twitter.com/DevToolsCommits
-  [all open DevTools tickets]: https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3APlatform%3EDevTools&sort=&groupby=&colspec=ID+Stars+Owner+Summary+Modified+Opened
diff --git a/scripts/OWNERS b/scripts/OWNERS
deleted file mode 100644
index 76aa59e..0000000
--- a/scripts/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-einbinder@chromium.org
diff --git a/scripts/README.md b/scripts/README.md
deleted file mode 100644
index 0a89e46..0000000
--- a/scripts/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# DevTools Scripts
-
-## Development workflow scripts
-
-These are scripts that can be useful to run independently as you're working on Chrome DevTools front-end.
-
-The newer scripts such as for testing and hosted mode are written in Node.js, which has become the standard toolchain for web apps. The older scripts such as building (e.g. bundling and minifying) are written in Python, which has first-class support in Chromium's infrastructure.
-
-## Overview
-
-### Folders
-
-- build - Python package for generating DevTools debug and release mode
-- chrome_debug_launcher - automagically finds Chrome Canary and launches it with debugging flags (e.g. remote debugging port)
-- closure - see section on Closure Compiler below
-- gulp - experimental build process written in node.js & gulp to remove the dependency on Chromium-specific build tools (i.e. gn and ninja)
-- hosted_mode - run DevTools on a localhost development server
-- jsdoc_validator - enforces the use of Closure type annotations
-- local_node - installs a local runtime of node.js
-
-### Python Scripts
-- convert_svg_images_to_png.py - manually run when adding svg images
-- compile_frontend.py - runs closure compiler to do static type analysis
-    - Note: the compiled outputs are not actually used to run DevTools
-- lint_javascript.py - run eslint
-- optimize_png_images.py - manually run when adding png images
-
-### Node.js scripts
-
-The easiest way to run the node.js scripts is to use `npm run` which displays all the commands. For more information on the specific `npm run` commands, take a look at the primary devtools front-end readme (`../readme.md`).
-
-## Closure
-
-DevTools manually rolls the closure compiler to ./closure. If you manually roll closure compiler, you will need to re-generate the closure_runner (in ./closure) and jsdoc_validator custom jars using the python scripts in their respective directory.
\ No newline at end of file
diff --git a/scripts/__init__.py b/scripts/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/scripts/__init__.py
+++ /dev/null
diff --git a/scripts/build/__init__.py b/scripts/build/__init__.py
deleted file mode 100644
index 05cc409..0000000
--- a/scripts/build/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
\ No newline at end of file
diff --git a/scripts/build/build_debug_applications.py b/scripts/build/build_debug_applications.py
deleted file mode 100755
index 42f8e4c..0000000
--- a/scripts/build/build_debug_applications.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-#
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-Builds applications in debug mode:
-- Copies the module directories into their destinations.
-- Copies app.html as-is.
-"""
-
-from os import path
-from os.path import join
-import os
-import shutil
-import sys
-
-import modular_build
-
-
-def main(argv):
-    try:
-        input_path_flag_index = argv.index('--input_path')
-        input_path = argv[input_path_flag_index + 1]
-        output_path_flag_index = argv.index('--output_path')
-        output_path = argv[output_path_flag_index + 1]
-        application_names = argv[1:input_path_flag_index]
-    except:
-        print('Usage: %s app_1 app_2 ... app_N --input_path <input_path> --output_path <output_path>' % argv[0])
-        raise
-
-    loader = modular_build.DescriptorLoader(input_path)
-    for app in application_names:
-        descriptors = loader.load_application(app)
-        builder = DebugBuilder(app, descriptors, input_path, output_path)
-        builder.build_app()
-
-
-def symlink_or_copy_file(src, dest, safe=False):
-    if safe and path.exists(dest):
-        os.remove(dest)
-    if hasattr(os, 'symlink'):
-        os.symlink(src, dest)
-    else:
-        shutil.copy(src, dest)
-
-
-def symlink_or_copy_dir(src, dest):
-    if path.exists(dest):
-        shutil.rmtree(dest)
-    for src_dir, dirs, files in os.walk(src):
-        subpath = path.relpath(src_dir, src)
-        dest_dir = path.normpath(join(dest, subpath))
-        os.mkdir(dest_dir)
-        for name in files:
-            src_name = join(os.getcwd(), src_dir, name)
-            dest_name = join(dest_dir, name)
-            symlink_or_copy_file(src_name, dest_name)
-
-
-# Outputs:
-#   <app_name>.html as-is
-#   <app_name>.js as-is
-#   <module_name>/<all_files>
-class DebugBuilder(object):
-
-    def __init__(self, application_name, descriptors, application_dir, output_dir):
-        self.application_name = application_name
-        self.descriptors = descriptors
-        self.application_dir = application_dir
-        self.output_dir = output_dir
-
-    def app_file(self, extension):
-        return self.application_name + '.' + extension
-
-    def build_app(self):
-        if self.descriptors.has_html:
-            self._build_html()
-        for filename in os.listdir(self.application_dir):
-            src = join(os.getcwd(), self.application_dir, filename)
-            if os.path.isdir(src):
-                symlink_or_copy_dir(src, join(self.output_dir, filename))
-            else:
-                symlink_or_copy_file(src, join(self.output_dir, filename), safe=True)
-
-    def _build_html(self):
-        html_name = self.app_file('html')
-        symlink_or_copy_file(join(os.getcwd(), self.application_dir, html_name), join(self.output_dir, html_name), True)
-
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/scripts/build/build_release_applications.py b/scripts/build/build_release_applications.py
deleted file mode 100755
index 2787190..0000000
--- a/scripts/build/build_release_applications.py
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-#
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-Builds applications in release mode:
-- Concatenates autostart modules, application modules' module.json descriptors,
-and the application loader into a single script.
-- Builds app.html referencing the application script.
-"""
-
-from cStringIO import StringIO
-from os import path
-from os.path import join
-import copy
-import os
-import re
-import shutil
-import sys
-
-from modular_build import read_file, write_file, bail_error
-import modular_build
-import rjsmin
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-special_case_namespaces_path = path.join(path.dirname(path.dirname(path.abspath(__file__))), 'special_case_namespaces.json')
-
-
-def main(argv):
-    try:
-        input_path_flag_index = argv.index('--input_path')
-        input_path = argv[input_path_flag_index + 1]
-        output_path_flag_index = argv.index('--output_path')
-        output_path = argv[output_path_flag_index + 1]
-        application_names = argv[1:input_path_flag_index]
-    except:
-        print('Usage: %s app_1 app_2 ... app_N --input_path <input_path> --output_path <output_path>' % argv[0])
-        raise
-
-    loader = modular_build.DescriptorLoader(input_path)
-    for app in application_names:
-        descriptors = loader.load_application(app)
-        builder = ReleaseBuilder(app, descriptors, input_path, output_path)
-        builder.build_app()
-
-
-def resource_source_url(url):
-    return '\n/*# sourceURL=' + url + ' */'
-
-
-def minify_js(javascript):
-    return rjsmin.jsmin(javascript)
-
-
-def concatenated_module_filename(module_name, output_dir):
-    return join(output_dir, module_name + '/' + module_name + '_module.js')
-
-
-def symlink_or_copy_file(src, dest, safe=False):
-    if safe and path.exists(dest):
-        os.remove(dest)
-    if hasattr(os, 'symlink'):
-        os.symlink(src, dest)
-    else:
-        shutil.copy(src, dest)
-
-
-def symlink_or_copy_dir(src, dest):
-    if path.exists(dest):
-        shutil.rmtree(dest)
-    for src_dir, dirs, files in os.walk(src):
-        subpath = path.relpath(src_dir, src)
-        dest_dir = path.normpath(join(dest, subpath))
-        os.mkdir(dest_dir)
-        for name in files:
-            src_name = join(os.getcwd(), src_dir, name)
-            dest_name = join(dest_dir, name)
-            symlink_or_copy_file(src_name, dest_name)
-
-
-# Outputs:
-#   <app_name>.html
-#   <app_name>.js
-#   <module_name>_module.js
-class ReleaseBuilder(object):
-
-    def __init__(self, application_name, descriptors, application_dir, output_dir):
-        self.application_name = application_name
-        self.descriptors = descriptors
-        self.application_dir = application_dir
-        self.output_dir = output_dir
-        with open(special_case_namespaces_path) as json_file:
-            self._special_case_namespaces = json.load(json_file)
-
-    def app_file(self, extension):
-        return self.application_name + '.' + extension
-
-    def autorun_resource_names(self):
-        result = []
-        for module in self.descriptors.sorted_modules():
-            if self.descriptors.application[module].get('type') != 'autostart':
-                continue
-
-            resources = self.descriptors.modules[module].get('resources')
-            if not resources:
-                continue
-            for resource_name in resources:
-                result.append(path.join(module, resource_name))
-        return result
-
-    def build_app(self):
-        if self.descriptors.has_html:
-            self._build_html()
-        self._build_app_script()
-        for module in filter(lambda desc: (not desc.get('type') or desc.get('type') == 'remote'),
-                             self.descriptors.application.values()):
-            self._concatenate_dynamic_module(module['name'])
-
-    def _write_include_tags(self, descriptors, output):
-        if descriptors.extends:
-            self._write_include_tags(descriptors.extends, output)
-        output.write(self._generate_include_tag(descriptors.application_name + '.js'))
-
-
-    def _build_html(self):
-        html_name = self.app_file('html')
-        output = StringIO()
-        with open(join(self.application_dir, html_name), 'r') as app_input_html:
-            for line in app_input_html:
-                if '<script ' in line or '<link ' in line:
-                    continue
-                if '</head>' in line:
-                    self._write_include_tags(self.descriptors, output)
-                    js_file = join(self.application_dir, self.app_file('js'))
-                    if path.exists(js_file):
-                        output.write('    <script>%s</script>\n' % minify_js(read_file(js_file)))
-                output.write(line)
-
-        write_file(join(self.output_dir, html_name), output.getvalue())
-        output.close()
-
-    def _build_app_script(self):
-        script_name = self.app_file('js')
-        output = StringIO()
-        self._concatenate_application_script(output)
-        write_file(join(self.output_dir, script_name), minify_js(output.getvalue()))
-        output.close()
-
-    def _generate_include_tag(self, resource_path):
-        if resource_path.endswith('.js'):
-            return '    <script type="text/javascript" src="%s"></script>\n' % resource_path
-        else:
-            assert resource_path
-
-    def _release_module_descriptors(self):
-        module_descriptors = self.descriptors.modules
-        result = []
-        for name in module_descriptors:
-            module = copy.copy(module_descriptors[name])
-            module_type = self.descriptors.application[name].get('type')
-            # Clear scripts, as they are not used at runtime
-            # (only the fact of their presence is important).
-            resources = module.get('resources', None)
-            if module.get('scripts') or resources:
-                if module_type == 'autostart':
-                    # Autostart modules are already baked in.
-                    del module['scripts']
-                else:
-                    # Non-autostart modules are vulcanized.
-                    module['scripts'] = [name + '_module.js']
-            # Resources are already baked into scripts.
-            if resources is not None:
-                del module['resources']
-            result.append(module)
-        return json.dumps(result)
-
-    def _write_module_resources(self, resource_names, output):
-        for resource_name in resource_names:
-            resource_name = path.normpath(resource_name).replace('\\', '/')
-            output.write('Runtime.cachedResources["%s"] = "' % resource_name)
-            resource_content = read_file(path.join(self.application_dir, resource_name)) + resource_source_url(resource_name)
-            resource_content = resource_content.replace('\\', '\\\\')
-            resource_content = resource_content.replace('\n', '\\n')
-            resource_content = resource_content.replace('"', '\\"')
-            output.write(resource_content)
-            output.write('";\n')
-
-    def _concatenate_autostart_modules(self, output):
-        non_autostart = set()
-        sorted_module_names = self.descriptors.sorted_modules()
-        for name in sorted_module_names:
-            desc = self.descriptors.modules[name]
-            name = desc['name']
-            type = self.descriptors.application[name].get('type')
-            if type == 'autostart':
-                deps = set(desc.get('dependencies', []))
-                non_autostart_deps = deps & non_autostart
-                if len(non_autostart_deps):
-                    bail_error('Non-autostart dependencies specified for the autostarted module "%s": %s' %
-                               (name, non_autostart_deps))
-                namespace = self._map_module_to_namespace(name)
-                output.write('\n/* Module %s */\n' % name)
-                output.write('\nself[\'%s\'] = self[\'%s\'] || {};\n' % (namespace, namespace))
-                modular_build.concatenate_scripts(desc.get('scripts'), join(self.application_dir, name), self.output_dir, output)
-            else:
-                non_autostart.add(name)
-
-    def _map_module_to_namespace(self, module):
-        camel_case_namespace = "".join(map(lambda x: x[0].upper() + x[1:], module.split('_')))
-        return self._special_case_namespaces.get(module, camel_case_namespace)
-
-    def _concatenate_application_script(self, output):
-        if not self.descriptors.extends:
-            runtime_contents = read_file(join(self.application_dir, 'Runtime.js'))
-            output.write('/* Runtime.js */\n')
-            output.write(runtime_contents)
-            output.write('allDescriptors.push(...%s);' % self._release_module_descriptors())
-            output.write('/* Application descriptor %s */\n' % self.app_file('json'))
-            output.write('applicationDescriptor = ')
-            output.write(self.descriptors.application_json())
-        else:
-            output.write('/* Additional descriptors */\n')
-            output.write('allDescriptors.push(...%s);' % self._release_module_descriptors())
-            output.write('/* Additional descriptors %s */\n' % self.app_file('json'))
-            output.write('applicationDescriptor.modules.push(...%s)' % json.dumps(self.descriptors.application.values()))
-
-        output.write('\n/* Autostart modules */\n')
-        self._concatenate_autostart_modules(output)
-        output.write(';\n/* Autostart resources */\n')
-        self._write_module_resources(self.autorun_resource_names(), output)
-        if not self.descriptors.has_html:
-            js_file = join(self.application_dir, self.app_file('js'))
-            if path.exists(js_file):
-                output.write(';\n/* Autostart script for worker */\n')
-                output.write(read_file(js_file))
-
-    def _concatenate_dynamic_module(self, module_name):
-        module = self.descriptors.modules[module_name]
-        scripts = module.get('scripts')
-        resources = self.descriptors.module_resources(module_name)
-        module_dir = join(self.application_dir, module_name)
-        output = StringIO()
-        if scripts:
-            modular_build.concatenate_scripts(scripts, module_dir, self.output_dir, output)
-        if resources:
-            self._write_module_resources(resources, output)
-        output_file_path = concatenated_module_filename(module_name, self.output_dir)
-        write_file(output_file_path, minify_js(output.getvalue()))
-        output.close()
-
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/scripts/build/code_generator_frontend.py b/scripts/build/code_generator_frontend.py
deleted file mode 100755
index 12226dc..0000000
--- a/scripts/build/code_generator_frontend.py
+++ /dev/null
@@ -1,295 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 Google Inc. All rights reserved.
-# Copyright (c) 2012 Intel Corporation. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os.path
-import sys
-import string
-import optparse
-import re
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-cmdline_parser = optparse.OptionParser()
-cmdline_parser.add_option("--output_js_dir")
-
-try:
-    arg_options, arg_values = cmdline_parser.parse_args()
-    if (len(arg_values) != 1):
-        raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
-    input_json_filename = arg_values[0]
-    output_js_dirname = arg_options.output_js_dir
-    if not output_js_dirname:
-        raise Exception("Output .js directory must be specified")
-except Exception:
-    # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
-    exc = sys.exc_info()[1]
-    sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
-    sys.stderr.write("Usage: <script> some.json --output_js_dir <output_js_dir>\n")
-    exit(1)
-
-
-def fix_camel_case(name):
-    prefix = ""
-    if name[0] == "-":
-        prefix = "Negative"
-        name = name[1:]
-    refined = re.sub(r'-(\w)', lambda pat: pat.group(1).upper(), name)
-    refined = to_title_case(refined)
-    return prefix + re.sub(r'(?i)HTML|XML|WML|API', lambda pat: pat.group(0).upper(), refined)
-
-
-def to_title_case(name):
-    return name[:1].upper() + name[1:]
-
-
-class RawTypes(object):
-
-    @staticmethod
-    def get_js(json_type):
-        if json_type == "boolean":
-            return "boolean"
-        elif json_type == "string":
-            return "string"
-        elif json_type == "array":
-            return "object"
-        elif json_type == "object":
-            return "object"
-        elif json_type == "integer":
-            return "number"
-        elif json_type == "number":
-            return "number"
-        elif json_type == "any":
-            raise Exception("Unsupported")
-        else:
-            raise Exception("Unknown type: %s" % json_type)
-
-
-class TypeData(object):
-
-    def __init__(self, json_type):
-        if "type" not in json_type:
-            raise Exception("Unknown type")
-        json_type_name = json_type["type"]
-        self.raw_type_js_ = RawTypes.get_js(json_type_name)
-
-    def get_raw_type_js(self):
-        return self.raw_type_js_
-
-
-class TypeMap:
-
-    def __init__(self, api):
-        self.map_ = {}
-        for json_domain in api["domains"]:
-            domain_name = json_domain["domain"]
-
-            domain_map = {}
-            self.map_[domain_name] = domain_map
-
-            if "types" in json_domain:
-                for json_type in json_domain["types"]:
-                    type_name = json_type["id"]
-                    type_data = TypeData(json_type)
-                    domain_map[type_name] = type_data
-
-    def get(self, domain_name, type_name):
-        return self.map_[domain_name][type_name]
-
-
-def resolve_param_raw_type_js(json_parameter, scope_domain_name):
-    if "$ref" in json_parameter:
-        json_ref = json_parameter["$ref"]
-        return get_ref_data_js(json_ref, scope_domain_name)
-    elif "type" in json_parameter:
-        json_type = json_parameter["type"]
-        return RawTypes.get_js(json_type)
-    else:
-        raise Exception("Unknown type")
-
-
-def get_ref_data_js(json_ref, scope_domain_name):
-    dot_pos = json_ref.find(".")
-    if dot_pos == -1:
-        domain_name = scope_domain_name
-        type_name = json_ref
-    else:
-        domain_name = json_ref[:dot_pos]
-        type_name = json_ref[dot_pos + 1:]
-
-    return type_map.get(domain_name, type_name).get_raw_type_js()
-
-
-input_file = open(input_json_filename, "r")
-json_string = input_file.read()
-json_api = json.loads(json_string)
-
-
-class Templates:
-
-    def get_this_script_path_(absolute_path):
-        absolute_path = os.path.abspath(absolute_path)
-        components = []
-
-        def fill_recursive(path_part, depth):
-            if depth <= 0 or path_part == '/':
-                return
-            fill_recursive(os.path.dirname(path_part), depth - 1)
-            components.append(os.path.basename(path_part))
-
-        # Typical path is /Source/platform/inspector_protocol/CodeGenerator.py
-        # Let's take 4 components from the real path then.
-        fill_recursive(absolute_path, 4)
-
-        return "/".join(components)
-
-    file_header_ = ("// File is generated by %s\n\n" % get_this_script_path_(sys.argv[0]) +
-                    """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-""")
-
-    backend_js = string.Template(file_header_ + """
-
-$domainInitializers
-""")
-
-
-type_map = TypeMap(json_api)
-
-
-class Generator:
-    backend_js_domain_initializer_list = []
-
-    @staticmethod
-    def go():
-        for json_domain in json_api["domains"]:
-            domain_name = json_domain["domain"]
-            domain_name_lower = domain_name.lower()
-            if domain_name_lower == "console":
-                continue
-
-            Generator.backend_js_domain_initializer_list.append("// %s.\n" % domain_name)
-
-            if "types" in json_domain:
-                for json_type in json_domain["types"]:
-                    if "type" in json_type and json_type["type"] == "string" and "enum" in json_type:
-                        enum_name = "%s.%s" % (domain_name, json_type["id"])
-                        Generator.process_enum(json_type, enum_name)
-                    elif json_type["type"] == "object":
-                        if "properties" in json_type:
-                            for json_property in json_type["properties"]:
-                                if "type" in json_property and json_property["type"] == "string" and "enum" in json_property:
-                                    enum_name = "%s.%s%s" % (domain_name, json_type["id"], to_title_case(json_property["name"]))
-                                    Generator.process_enum(json_property, enum_name)
-
-            if "events" in json_domain:
-                for json_event in json_domain["events"]:
-                    Generator.process_event(json_event, domain_name)
-
-            if "commands" in json_domain:
-                for json_command in json_domain["commands"]:
-                    Generator.process_command(json_command, domain_name)
-
-            Generator.backend_js_domain_initializer_list.append("\n")
-
-    @staticmethod
-    def process_enum(json_enum, enum_name):
-        enum_members = []
-        for member in json_enum["enum"]:
-            enum_members.append("%s: \"%s\"" % (fix_camel_case(member), member))
-
-        Generator.backend_js_domain_initializer_list.append("Protocol.inspectorBackend.registerEnum(\"%s\", {%s});\n" %
-                                                            (enum_name, ", ".join(enum_members)))
-
-    @staticmethod
-    def process_event(json_event, domain_name):
-        event_name = json_event["name"]
-
-        json_parameters = json_event.get("parameters")
-
-        backend_js_event_param_list = []
-        if json_parameters:
-            for parameter in json_parameters:
-                parameter_name = parameter["name"]
-                backend_js_event_param_list.append("\"%s\"" % parameter_name)
-
-        Generator.backend_js_domain_initializer_list.append("Protocol.inspectorBackend.registerEvent(\"%s.%s\", [%s]);\n" %
-                                                            (domain_name, event_name, ", ".join(backend_js_event_param_list)))
-
-    @staticmethod
-    def process_command(json_command, domain_name):
-        json_command_name = json_command["name"]
-
-        js_parameters_text = ""
-        if "parameters" in json_command:
-            json_params = json_command["parameters"]
-            js_param_list = []
-
-            for json_parameter in json_params:
-                json_param_name = json_parameter["name"]
-                js_bind_type = resolve_param_raw_type_js(json_parameter, domain_name)
-
-                optional = json_parameter.get("optional")
-
-                js_param_text = "{\"name\": \"%s\", \"type\": \"%s\", \"optional\": %s}" % (json_param_name, js_bind_type, (
-                    "true" if ("optional" in json_parameter and json_parameter["optional"]) else "false"))
-
-                js_param_list.append(js_param_text)
-
-            js_parameters_text = ", ".join(js_param_list)
-
-        backend_js_reply_param_list = []
-        if "returns" in json_command:
-            for json_return in json_command["returns"]:
-                json_return_name = json_return["name"]
-                backend_js_reply_param_list.append("\"%s\"" % json_return_name)
-
-        js_reply_list = "[%s]" % ", ".join(backend_js_reply_param_list)
-        if "error" in json_command:
-            has_error_data_param = "true"
-        else:
-            has_error_data_param = "false"
-
-        Generator.backend_js_domain_initializer_list.append(
-            "Protocol.inspectorBackend.registerCommand(\"%s.%s\", [%s], %s, %s);\n" %
-            (domain_name, json_command_name, js_parameters_text, js_reply_list, has_error_data_param))
-
-
-Generator.go()
-
-backend_js_file = open(output_js_dirname + "/InspectorBackendCommands.js", "w")
-
-backend_js_file.write(
-    Templates.backend_js.substitute(
-        None, domainInitializers="".join(Generator.backend_js_domain_initializer_list)))
-
-backend_js_file.close()
diff --git a/scripts/build/devtools_file_hashes.py b/scripts/build/devtools_file_hashes.py
deleted file mode 100755
index 8c67f1c..0000000
--- a/scripts/build/devtools_file_hashes.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import hashlib
-import os.path
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-def save_hashes(hashes_file_path, hashes):
-    try:
-        with open(hashes_file_path, "wt") as hashes_file:
-            json.dump(hashes, hashes_file, indent=4, separators=(",", ": "))
-    except:
-        print "ERROR: Failed to write %s" % hashes_file_path
-        raise
-
-
-def load_hashes(hashes_file_path):
-    try:
-        with open(hashes_file_path, "r") as hashes_file:
-            hashes = json.load(hashes_file)
-    except:
-        return {}
-    return hashes
-
-
-def calculate_file_hash(file_path):
-    with open(file_path) as file:
-        data = file.read()
-        md5_hash = hashlib.md5(data).hexdigest()
-    return md5_hash
-
-
-def files_with_invalid_hashes(hash_file_path, file_paths):
-    hashes = load_hashes(hash_file_path)
-    result = []
-    for file_path in file_paths:
-        file_name = os.path.basename(file_path)
-        if calculate_file_hash(file_path) != hashes.get(file_name, ""):
-            result.append(file_path)
-    return result
-
-
-def update_file_hashes(hash_file_path, file_paths):
-    hashes = {}
-    for file_path in file_paths:
-        file_name = os.path.basename(file_path)
-        hashes[file_name] = calculate_file_hash(file_path)
-    save_hashes(hash_file_path, hashes)
diff --git a/scripts/build/generate_devtools_extension_api.py b/scripts/build/generate_devtools_extension_api.py
deleted file mode 100755
index 6d5728b..0000000
--- a/scripts/build/generate_devtools_extension_api.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#         * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#         * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#         * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-import sys
-
-
-def write_devtools_extension_api(output, input_names):
-    output.write("""(function() {
-    """)
-    for input_name in input_names:
-        input = open(input_name, 'r')
-        output.write(input.read())
-    output.write("""
-        var tabId;
-        var extensionInfo = {};
-        var extensionServer;
-        platformExtensionAPI(injectedExtensionAPI("remote-" + window.parent.frames.length));
-    })();""")
-
-
-def main(argv):
-
-    if len(argv) < 3:
-        print('usage: %s output_js input_files ...' % argv[0])
-        return 1
-
-    output_name = argv[1]
-    output = open(output_name, 'w')
-    write_devtools_extension_api(output, argv[2:])
-    output.close()
-
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/scripts/build/generate_devtools_grd.py b/scripts/build/generate_devtools_grd.py
deleted file mode 100755
index 9f6076b..0000000
--- a/scripts/build/generate_devtools_grd.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#         * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#         * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#         * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Creates a grd file for packaging the inspector files."""
-
-from __future__ import with_statement
-from os import path
-
-import errno
-import os
-import shlex
-import shutil
-import sys
-from xml.dom import minidom
-
-kDevToolsResourcePrefix = 'IDR_DEVTOOLS_'
-kGrdTemplate = '''<?xml version="1.0" encoding="UTF-8"?>
-<grit latest_public_release="0" current_release="1"
-      output_all_resource_defines="false">
-  <outputs>
-    <output filename="grit/devtools_resources.h" type="rc_header">
-      <emit emit_type='prepend'></emit>
-    </output>
-    <output filename="grit/devtools_resources_map.cc" type="resource_file_map_source" />
-    <output filename="grit/devtools_resources_map.h" type="resource_map_header" />
-
-    <output filename="devtools_resources.pak" type="data_package" />
-  </outputs>
-  <release seq="1">
-    <includes>
-      <include name="COMPRESSED_PROTOCOL_JSON" file="${compressed_protocol_file}" use_base_dir="false" type="BINDATA" />
-    </includes>
-  </release>
-</grit>
-'''
-
-
-class ParsedArgs:
-
-    def __init__(self, source_files, relative_path_dirs, image_dirs, output_filename):
-        self.source_files = source_files
-        self.relative_path_dirs = relative_path_dirs
-        self.image_dirs = image_dirs
-        self.output_filename = output_filename
-
-
-def parse_args(argv):
-    # The arguments are of the format:
-    #   [ <source_files> ]*
-    #   --relative_path_dirs [ <directory> ]*
-    #   --images [ <image_dirs> ]*
-    #   --output <output_file>
-    relative_path_dirs_position = argv.index('--relative_path_dirs')
-    images_position = argv.index('--images')
-    output_position = argv.index('--output')
-    source_files = argv[:relative_path_dirs_position]
-    relative_path_dirs = argv[relative_path_dirs_position + 1:images_position]
-    image_dirs = argv[images_position + 1:output_position]
-    return ParsedArgs(source_files, relative_path_dirs, image_dirs, argv[output_position + 1])
-
-
-def make_name_from_filename(filename):
-    return (filename.replace('/', '_').replace('\\', '_').replace('-', '_').replace('.', '_')).upper()
-
-
-def add_file_to_grd(grd_doc, relative_filename):
-    includes_node = grd_doc.getElementsByTagName('includes')[0]
-    includes_node.appendChild(grd_doc.createTextNode('\n      '))
-
-    new_include_node = grd_doc.createElement('include')
-    new_include_node.setAttribute('name', make_name_from_filename(relative_filename))
-    new_include_node.setAttribute('file', relative_filename)
-    new_include_node.setAttribute('type', 'BINDATA')
-    includes_node.appendChild(new_include_node)
-
-
-def build_relative_filename(relative_path_dirs, filename):
-    for relative_path_dir in relative_path_dirs:
-        index = filename.find(relative_path_dir)
-        if index == 0:
-            return filename[len(relative_path_dir) + 1:]
-    return path.basename(filename)
-
-
-def main(argv):
-    parsed_args = parse_args(argv[1:])
-
-    doc = minidom.parseString(kGrdTemplate)
-    output_directory = path.dirname(parsed_args.output_filename)
-
-    try:
-        os.makedirs(path.join(output_directory, 'Images'))
-    except OSError, e:
-        if e.errno != errno.EEXIST:
-            raise e
-
-    written_filenames = set()
-    for filename in parsed_args.source_files:
-        relative_filename = build_relative_filename(parsed_args.relative_path_dirs, filename)
-        # Avoid writing duplicate relative filenames.
-        if relative_filename in written_filenames:
-            continue
-        written_filenames.add(relative_filename)
-        target_dir = path.join(output_directory, path.dirname(relative_filename))
-        if not path.exists(target_dir):
-            os.makedirs(target_dir)
-        shutil.copy(filename, target_dir)
-        add_file_to_grd(doc, relative_filename)
-
-    for dirname in parsed_args.image_dirs:
-        for filename in sorted(os.listdir(dirname)):
-            if not filename.endswith('.png') and not filename.endswith('.gif') and not filename.endswith('.svg'):
-                continue
-            shutil.copy(path.join(dirname, filename), path.join(output_directory, 'Images'))
-            add_file_to_grd(doc, path.join('Images', filename))
-
-    with open(parsed_args.output_filename, 'w') as output_file:
-        output_file.write(doc.toxml(encoding='UTF-8'))
-
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/scripts/build/generate_protocol_externs.py b/scripts/build/generate_protocol_externs.py
deleted file mode 100755
index 418361b..0000000
--- a/scripts/build/generate_protocol_externs.py
+++ /dev/null
@@ -1,269 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os
-import re
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-type_traits = {
-    "any": "*",
-    "string": "string",
-    "integer": "number",
-    "number": "number",
-    "boolean": "boolean",
-    "array": "!Array<*>",
-    "object": "!Object",
-}
-
-ref_types = {}
-
-
-def full_qualified_type_id(domain_name, type_id):
-    if type_id.find(".") == -1:
-        return "%s.%s" % (domain_name, type_id)
-    return type_id
-
-
-def fix_camel_case(name):
-    prefix = ""
-    if name[0] == "-":
-        prefix = "Negative"
-        name = name[1:]
-    refined = re.sub(r'-(\w)', lambda pat: pat.group(1).upper(), name)
-    refined = to_title_case(refined)
-    return prefix + re.sub(r'(?i)HTML|XML|WML|API', lambda pat: pat.group(0).upper(), refined)
-
-
-def to_title_case(name):
-    return name[:1].upper() + name[1:]
-
-
-def generate_enum(name, json):
-    enum_members = []
-    for member in json["enum"]:
-        enum_members.append("    %s: \"%s\"" % (fix_camel_case(member), member))
-    return "\n/** @enum {string} */\n%s = {\n%s\n};\n" % (name, (",\n".join(enum_members)))
-
-
-def param_type(domain_name, param):
-    if "type" in param:
-        if param["type"] == "array":
-            items = param["items"]
-            return "!Array<%s>" % param_type(domain_name, items)
-        else:
-            return type_traits[param["type"]]
-    if "$ref" in param:
-        type_id = full_qualified_type_id(domain_name, param["$ref"])
-        if type_id in ref_types:
-            return ref_types[type_id]
-        else:
-            print "Type not found: " + type_id
-            return "!! Type not found: " + type_id
-
-
-def param_name(param):
-    name = param["name"]
-    return name if name != "arguments" else "_arguments"
-
-
-def load_schema(file, domains):
-    input_file = open(file, "r")
-    json_string = input_file.read()
-    parsed_json = json.loads(json_string)
-    domains.extend(parsed_json["domains"])
-
-
-def generate_protocol_externs(output_path, file1, file2):
-    domains = []
-    load_schema(file1, domains)
-    load_schema(file2, domains)
-    output_file = open(output_path, "w")
-
-    for domain in domains:
-        domain_name = domain["domain"]
-        if "types" in domain:
-            for type in domain["types"]:
-                type_id = full_qualified_type_id(domain_name, type["id"])
-                ref_types[type_id] = "Protocol.%s.%s" % (domain_name, type["id"])
-
-    for domain in domains:
-        domain_name = domain["domain"]
-
-        output_file.write("Protocol.%s = {};\n" % domain_name)
-        output_file.write("\n\n/**\n * @constructor\n*/\n")
-        output_file.write("Protocol.%sAgent = function(){};\n" % domain_name)
-
-        if "commands" in domain:
-            for command in domain["commands"]:
-                output_file.write("\n/**\n")
-                params = []
-                in_param_to_type = {}
-                out_param_to_type = {}
-                has_return_value = "returns" in command
-                if "parameters" in command:
-                    for in_param in command["parameters"]:
-                        in_param_name = param_name(in_param)
-                        if "optional" in in_param:
-                            in_param_to_type[in_param_name] = "(%s|undefined)" % param_type(domain_name, in_param)
-                            params.append("opt_%s" % in_param_name)
-                            output_file.write(" * @param {%s=} opt_%s\n" % (param_type(domain_name, in_param), in_param_name))
-                        else:
-                            in_param_to_type[in_param_name] = param_type(domain_name, in_param)
-                            params.append(in_param_name)
-                            output_file.write(" * @param {%s} %s\n" % (param_type(domain_name, in_param), in_param_name))
-                returns = []
-                returns.append("?Protocol.Error")
-                if ("error" in command):
-                    returns.append("%s=" % param_type(domain_name, command["error"]))
-                if (has_return_value):
-                    for out_param in command["returns"]:
-                        out_param_type = param_type(domain_name, out_param)
-                        out_param_to_type[out_param["name"]] = out_param_type
-                        if ("optional" in out_param):
-                            returns.append("%s=" % out_param_type)
-                        else:
-                            returns.append("%s" % out_param_type)
-
-                if has_return_value and len(command["returns"]) > 0:
-                    out_param_type = param_type(domain_name, command["returns"][0])
-                    if re.match(r"^[!?]", out_param_type[:1]):
-                        out_param_type = out_param_type[1:]
-                    out_param_type = "?%s" % out_param_type
-                else:
-                    out_param_type = "undefined"
-                output_file.write(" * @return {!Promise<%s>}\n" % out_param_type)
-
-                output_file.write(" */\n")
-                output_file.write("Protocol.%sAgent.prototype.%s = function(%s) {};\n" %
-                                  (domain_name, command["name"], ", ".join(params)))
-
-                request_object_properties = []
-                request_type = "Protocol.%sAgent.%sRequest" % (domain_name, to_title_case(command["name"]))
-                for param in in_param_to_type:
-                    request_object_properties.append("%s: %s" % (param, in_param_to_type[param]))
-                if request_object_properties:
-                    output_file.write("/** @typedef {!{%s}} */\n" % (", ".join(request_object_properties)))
-                else:
-                    output_file.write("/** @typedef {Object|undefined} */\n")
-                output_file.write("%s;\n" % request_type)
-
-                response_object_properties = []
-                response_type = "Protocol.%sAgent.%sResponse" % (domain_name, to_title_case(command["name"]))
-                for param in out_param_to_type:
-                    response_object_properties.append("%s: %s" % (param, out_param_to_type[param]))
-                if response_object_properties:
-                    output_file.write("/** @typedef {!{%s}} */\n" % (", ".join(response_object_properties)))
-                else:
-                    output_file.write("/** @typedef {Object|undefined} */\n")
-                output_file.write("%s;\n" % response_type)
-
-                output_file.write("/**\n")
-                output_file.write(" * @param {!%s} obj\n" % request_type)
-                output_file.write(" * @return {!Promise<!%s>}" % response_type)
-                output_file.write(" */\n")
-                output_file.write("Protocol.%sAgent.prototype.invoke_%s = function(obj) {};\n" %
-                                  (domain_name, command["name"]))
-
-        if "types" in domain:
-            for type in domain["types"]:
-                if type["type"] == "object":
-                    typedef_args = []
-                    if "properties" in type:
-                        for property in type["properties"]:
-                            suffix = ""
-                            if ("optional" in property):
-                                suffix = "|undefined"
-                            if "enum" in property:
-                                enum_name = "Protocol.%s.%s%s" % (domain_name, type["id"], to_title_case(property["name"]))
-                                output_file.write(generate_enum(enum_name, property))
-                                typedef_args.append("%s:(%s%s)" % (property["name"], enum_name, suffix))
-                            else:
-                                typedef_args.append("%s:(%s%s)" % (property["name"], param_type(domain_name, property), suffix))
-                    if (typedef_args):
-                        output_file.write("\n/** @typedef {!{%s}} */\nProtocol.%s.%s;\n" %
-                                          (", ".join(typedef_args), domain_name, type["id"]))
-                    else:
-                        output_file.write("\n/** @typedef {!Object} */\nProtocol.%s.%s;\n" % (domain_name, type["id"]))
-                elif type["type"] == "string" and "enum" in type:
-                    output_file.write(generate_enum("Protocol.%s.%s" % (domain_name, type["id"]), type))
-                elif type["type"] == "array":
-                    output_file.write("\n/** @typedef {!Array<!%s>} */\nProtocol.%s.%s;\n" %
-                                      (param_type(domain_name, type["items"]), domain_name, type["id"]))
-                else:
-                    output_file.write("\n/** @typedef {%s} */\nProtocol.%s.%s;\n" %
-                                      (type_traits[type["type"]], domain_name, type["id"]))
-
-        output_file.write("/** @interface */\n")
-        output_file.write("Protocol.%sDispatcher = function() {};\n" % domain_name)
-        if "events" in domain:
-            for event in domain["events"]:
-                params = []
-                if ("parameters" in event):
-                    output_file.write("/**\n")
-                    for param in event["parameters"]:
-                        if ("optional" in param):
-                            params.append("opt_%s" % param["name"])
-                            output_file.write(" * @param {%s=} opt_%s\n" % (param_type(domain_name, param), param["name"]))
-                        else:
-                            params.append(param["name"])
-                            output_file.write(" * @param {%s} %s\n" % (param_type(domain_name, param), param["name"]))
-                    output_file.write(" */\n")
-                output_file.write("Protocol.%sDispatcher.prototype.%s = function(%s) {};\n" %
-                                  (domain_name, event["name"], ", ".join(params)))
-
-    for domain in domains:
-        domain_name = domain["domain"]
-        uppercase_length = 0
-        while uppercase_length < len(domain_name) and domain_name[uppercase_length].isupper():
-            uppercase_length += 1
-
-        output_file.write("/** @return {!Protocol.%sAgent}*/\n" % domain_name)
-        output_file.write("Protocol.TargetBase.prototype.%s = function(){};\n" %
-                          (domain_name[:uppercase_length].lower() + domain_name[uppercase_length:] + "Agent"))
-
-        output_file.write("/**\n * @param {!Protocol.%sDispatcher} dispatcher\n */\n" % domain_name)
-        output_file.write("Protocol.TargetBase.prototype.register%sDispatcher = function(dispatcher) {}\n" % domain_name)
-
-    output_file.close()
-
-
-if __name__ == "__main__":
-    import sys
-    import os.path
-    program_name = os.path.basename(__file__)
-    if len(sys.argv) < 5 or sys.argv[1] != "-o":
-        sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE_1 INPUT_FILE_2\n" % program_name)
-        exit(1)
-    output_path = sys.argv[2]
-    input_path_1 = sys.argv[3]
-    input_path_2 = sys.argv[4]
-    generate_protocol_externs(output_path, input_path_1, input_path_2)
diff --git a/scripts/build/generate_supported_css.py b/scripts/build/generate_supported_css.py
deleted file mode 100755
index 45f9629..0000000
--- a/scripts/build/generate_supported_css.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-import ast
-import re
-import sys
-
-
-def _json5_load(lines):
-    # Use json5.loads when json5 is available. Currently we use simple
-    # regexs to convert well-formed JSON5 to PYL format.
-    # Strip away comments and quote unquoted keys.
-    re_comment = re.compile(r"^\s*//.*$|//+ .*$", re.MULTILINE)
-    re_map_keys = re.compile(r"^\s*([$A-Za-z_][\w]*)\s*:", re.MULTILINE)
-    pyl = re.sub(re_map_keys, r"'\1':", re.sub(re_comment, "", lines))
-    # Convert map values of true/false to Python version True/False.
-    re_true = re.compile(r":\s*true\b")
-    re_false = re.compile(r":\s*false\b")
-    pyl = re.sub(re_true, ":True", re.sub(re_false, ":False", pyl))
-    return ast.literal_eval(pyl)
-
-
-def _keep_only_required_keys(entry):
-    for key in entry.keys():
-        if key not in ("name", "longhands", "svg", "inherited"):
-            del entry[key]
-    return entry
-
-
-def properties_from_file(file_name):
-    with open(file_name) as json5_file:
-        doc = _json5_load(json5_file.read())
-
-    properties = []
-    property_names = {}
-    for entry in doc["data"]:
-        if type(entry) is str:
-            entry = {"name": entry}
-        if "alias_for" in entry:
-            continue
-        properties.append(_keep_only_required_keys(entry))
-        property_names[entry["name"]] = entry
-
-    properties.sort(key=lambda entry: entry["name"])
-
-    # Filter out unsupported longhands.
-    for property in properties:
-        longhands = property.get("longhands")
-        if not longhands:
-            continue
-        if type(longhands) is str:
-            longhands = longhands.split(";")
-        longhands = [longhand for longhand in longhands if longhand in property_names]
-        if not longhands:
-            del property["longhands"]
-        else:
-            property["longhands"] = longhands
-        all_inherited = True
-        for longhand in longhands:
-            longhand_property = property_names[longhand]
-            all_inherited = all_inherited and ("inherited" in longhand_property) and longhand_property["inherited"]
-        if all_inherited:
-            property["inherited"] = True
-
-    return properties
-
-
-properties = properties_from_file(sys.argv[1])
-with open(sys.argv[2], "w") as f:
-    f.write("SDK.CSSMetadata._generatedProperties = %s;" % json.dumps(properties))
diff --git a/scripts/build/modular_build.py b/scripts/build/modular_build.py
deleted file mode 100755
index 90d6697..0000000
--- a/scripts/build/modular_build.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-Utilities for the modular DevTools build.
-"""
-
-import collections
-from os import path
-import os
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-
-def read_file(filename):
-    with open(path.normpath(filename), 'rt') as input:
-        return input.read()
-
-
-def write_file(filename, content):
-    if path.exists(filename):
-        os.remove(filename)
-    directory = path.dirname(filename)
-    if not path.exists(directory):
-        os.makedirs(directory)
-    with open(filename, 'wt') as output:
-        output.write(content)
-
-
-def bail_error(message):
-    raise Exception(message)
-
-
-def load_and_parse_json(filename):
-    try:
-        return json.loads(read_file(filename))
-    except:
-        print 'ERROR: Failed to parse %s' % filename
-        raise
-
-
-def concatenate_scripts(file_names, module_dir, output_dir, output):
-    for file_name in file_names:
-        output.write('/* %s */\n' % file_name)
-        file_path = path.join(module_dir, file_name)
-        if not path.isfile(file_path):
-            file_path = path.join(output_dir, path.basename(module_dir), file_name)
-        output.write(read_file(file_path))
-        output.write(';')
-
-
-class Descriptors:
-
-    def __init__(self, application_name, application_dir, application_descriptor, module_descriptors, extends, has_html):
-        self.application_name = application_name
-        self.application_dir = application_dir
-        self.application = application_descriptor
-        self._cached_sorted_modules = None
-        self.modules = module_descriptors
-        self.extends = extends
-        self.has_html = has_html
-
-    def application_json(self):
-        result = dict()
-        result['modules'] = self.application.values()
-        result['has_html'] = self.has_html
-        return json.dumps(result)
-
-    def all_compiled_files(self):
-        files = collections.OrderedDict()
-        for name in self.sorted_modules():
-            module = self.modules[name]
-            skipped_files = set(module.get('skip_compilation', []))
-            for script in module.get('scripts', []):
-                if script not in skipped_files:
-                    files[path.normpath(path.join(self.application_dir, name, script))] = True
-        return files.keys()
-
-    def module_compiled_files(self, name):
-        files = []
-        module = self.modules.get(name)
-        skipped_files = set(module.get('skip_compilation', []))
-        for script in module.get('scripts', []):
-            if script not in skipped_files:
-                files.append(script)
-        return files
-
-    def module_resources(self, name):
-        return [name + '/' + resource for resource in self.modules[name].get('resources', [])]
-
-    def sorted_modules(self):
-        if self._cached_sorted_modules:
-            return self._cached_sorted_modules
-
-        result = []
-        unvisited_modules = set(self.modules)
-        temp_modules = set()
-
-        def visit(parent, name):
-            if name not in unvisited_modules:
-                return None
-            if name not in self.modules:
-                return (parent, name)
-            if name in temp_modules:
-                bail_error('Dependency cycle found at module "%s"' % name)
-            temp_modules.add(name)
-            deps = self.modules[name].get('dependencies')
-            if deps:
-                for dep_name in deps:
-                    bad_dep = visit(name, dep_name)
-                    if bad_dep:
-                        return bad_dep
-            unvisited_modules.remove(name)
-            temp_modules.remove(name)
-            result.append(name)
-            return None
-
-        while len(unvisited_modules):
-            for next in unvisited_modules:
-                break
-            failure = visit(None, next)
-            if failure:
-                # failure[0] can never be None
-                bail_error('Unknown module "%s" encountered in dependencies of "%s"' % (failure[1], failure[0]))
-
-        self._cached_sorted_modules = result
-        return result
-
-    def sorted_dependencies_closure(self, module_name):
-        visited = set()
-
-        def sorted_deps_for_module(name):
-            result = []
-            desc = self.modules[name]
-            deps = desc.get('dependencies', [])
-            for dep in deps:
-                result += sorted_deps_for_module(dep)
-            if name not in visited:
-                result.append(name)
-                visited.add(name)
-            return result
-
-        return sorted_deps_for_module(module_name)
-
-
-class DescriptorLoader:
-
-    def __init__(self, application_dir):
-        self.application_dir = application_dir
-
-    def load_application(self, application_descriptor_name):
-        all_module_descriptors = {}
-        result = self._load_application(application_descriptor_name, all_module_descriptors)
-        return result
-
-    def load_applications(self, application_descriptor_names):
-        all_module_descriptors = {}
-        all_application_descriptors = {}
-        for application_descriptor_name in application_descriptor_names:
-            descriptors = {}
-            result = self._load_application(application_descriptor_name, descriptors)
-            for name in descriptors:
-                all_module_descriptors[name] = descriptors[name]
-            for name in result.application:
-                all_application_descriptors[name] = result.application[name]
-        return Descriptors('all', self.application_dir, all_application_descriptors, all_module_descriptors, None, False)
-
-    def _load_application(self, application_descriptor_name, all_module_descriptors):
-        module_descriptors = {}
-        application_descriptor_filename = path.join(self.application_dir, application_descriptor_name + '.json')
-        descriptor_json = load_and_parse_json(application_descriptor_filename)
-        application_descriptor = {desc['name']: desc for desc in descriptor_json['modules']}
-        extends = descriptor_json['extends'] if 'extends' in descriptor_json else None
-        if extends:
-            extends = self._load_application(extends, all_module_descriptors)
-        has_html = True if 'has_html' in descriptor_json and descriptor_json['has_html'] else False
-
-        for (module_name, module) in application_descriptor.items():
-            if all_module_descriptors.get(module_name):
-                bail_error('Duplicate definition of module "%s" in %s' % (module_name, application_descriptor_filename))
-            module_descriptors[module_name] = self._read_module_descriptor(module_name, application_descriptor_filename)
-            all_module_descriptors[module_name] = module_descriptors[module_name]
-
-        for module in module_descriptors.values():
-            for dep in module.get('dependencies', []):
-                if dep not in all_module_descriptors:
-                    bail_error('Module "%s" (dependency of "%s") not listed in application descriptor %s' %
-                               (dep, module['name'], application_descriptor_filename))
-
-        return Descriptors(
-            application_descriptor_name, self.application_dir, application_descriptor, module_descriptors, extends, has_html)
-
-    def _read_module_descriptor(self, module_name, application_descriptor_filename):
-        json_filename = path.join(self.application_dir, module_name, 'module.json')
-        if not path.exists(json_filename):
-            bail_error('Module descriptor %s referenced in %s is missing' % (json_filename, application_descriptor_filename))
-        module_json = load_and_parse_json(json_filename)
-        module_json['name'] = module_name
-        return module_json
diff --git a/scripts/build/rjsmin.py b/scripts/build/rjsmin.py
deleted file mode 100755
index 54e20ec..0000000
--- a/scripts/build/rjsmin.py
+++ /dev/null
@@ -1,515 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: ascii -*-
-r"""
-=====================
- Javascript Minifier
-=====================
-
-rJSmin is a javascript minifier written in python.
-
-The minifier is based on the semantics of `jsmin.c by Douglas Crockford`_\\.
-
-:Copyright:
-
- Copyright 2011 - 2015
- Andr\xe9 Malo or his licensors, as applicable
-
-:License:
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-The module is a re-implementation aiming for speed, so it can be used at
-runtime (rather than during a preprocessing step). Usually it produces the
-same results as the original ``jsmin.c``. It differs in the following ways:
-
-- there is no error detection: unterminated string, regex and comment
-  literals are treated as regular javascript code and minified as such.
-- Control characters inside string and regex literals are left untouched; they
-  are not converted to spaces (nor to \\n)
-- Newline characters are not allowed inside string and regex literals, except
-  for line continuations in string literals (ECMA-5).
-- "return /regex/" is recognized correctly.
-- Line terminators after regex literals are handled more sensibly
-- "+ +" and "- -" sequences are not collapsed to '++' or '--'
-- Newlines before ! operators are removed more sensibly
-- Comments starting with an exclamation mark (``!``) can be kept optionally
-- rJSmin does not handle streams, but only complete strings. (However, the
-  module provides a "streamy" interface).
-
-Since most parts of the logic are handled by the regex engine it's way faster
-than the original python port of ``jsmin.c`` by Baruch Even. The speed factor
-varies between about 6 and 55 depending on input and python version (it gets
-faster the more compressed the input already is). Compared to the
-speed-refactored python port by Dave St.Germain the performance gain is less
-dramatic but still between 3 and 50 (for huge inputs). See the docs/BENCHMARKS
-file for details.
-
-rjsmin.c is a reimplementation of rjsmin.py in C and speeds it up even more.
-
-Both python 2 and python 3 are supported.
-
-.. _jsmin.c by Douglas Crockford:
-   http://www.crockford.com/javascript/jsmin.c
-"""
-if __doc__:
-    # pylint: disable = redefined-builtin
-    __doc__ = __doc__.encode('ascii').decode('unicode_escape')
-__author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape')
-__docformat__ = "restructuredtext en"
-__license__ = "Apache License, Version 2.0"
-__version__ = '1.0.12'
-__all__ = ['jsmin']
-
-import re as _re
-
-
-def _make_jsmin(python_only=False):
-    """
-    Generate JS minifier based on `jsmin.c by Douglas Crockford`_
-
-    .. _jsmin.c by Douglas Crockford:
-       http://www.crockford.com/javascript/jsmin.c
-
-    :Parameters:
-      `python_only` : ``bool``
-        Use only the python variant. If true, the c extension is not even
-        tried to be loaded.
-
-    :Return: Minifier
-    :Rtype: ``callable``
-    """
-    # pylint: disable = unused-variable
-    # pylint: disable = too-many-locals
-
-    if not python_only:
-        try:
-            import _rjsmin
-        except ImportError:
-            pass
-        else:
-            return _rjsmin.jsmin
-    try:
-        xrange
-    except NameError:
-        xrange = range  # pylint: disable = redefined-builtin
-
-    space_chars = r'[\000-\011\013\014\016-\040]'
-
-    line_comment = r'(?://[^\r\n]*)'
-    space_comment = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
-    space_comment_nobang = r'(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/)'
-    bang_comment = r'(?:/\*![^*]*\*+(?:[^/*][^*]*\*+)*/)'
-
-    string1 = \
-        r'(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^\047\\\r\n]*)*\047)'
-    string2 = r'(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^"\\\r\n]*)*")'
-    string3 = r'(?:`(?:[^`\\]|\\.)*`)'
-    strings = r'(?:%s|%s|%s)' % (string1, string2, string3)
-
-    charclass = r'(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\])'
-    nospecial = r'[^/\\\[\r\n]'
-    regex = r'(?:/(?![\r\n/*])%s*(?:(?:\\[^\r\n]|%s)%s*)*/)' % (
-        nospecial, charclass, nospecial
-    )
-    space = r'(?:%s|%s)' % (space_chars, space_comment)
-    newline = r'(?:%s?[\r\n])' % line_comment
-
-    def fix_charclass(result):
-        """ Fixup string of chars to fit into a regex char class """
-        pos = result.find('-')
-        if pos >= 0:
-            result = r'%s%s-' % (result[:pos], result[pos + 1:])
-
-        def sequentize(string):
-            """
-            Notate consecutive characters as sequence
-
-            (1-4 instead of 1234)
-            """
-            first, last, result = None, None, []
-            for char in map(ord, string):
-                if last is None:
-                    first = last = char
-                elif last + 1 == char:
-                    last = char
-                else:
-                    result.append((first, last))
-                    first = last = char
-            if last is not None:
-                result.append((first, last))
-            return ''.join(['%s%s%s' % (
-                chr(first),
-                last > first + 1 and '-' or '',
-                last != first and chr(last) or ''
-            ) for first, last in result])  # noqa
-
-        return _re.sub(
-            r'([\000-\040\047])',  # \047 for better portability
-            lambda m: '\\%03o' % ord(m.group(1)), (
-                sequentize(result)
-                .replace('\\', '\\\\')
-                .replace('[', '\\[')
-                .replace(']', '\\]')
-            )
-        )
-
-    def id_literal_(what):
-        """ Make id_literal like char class """
-        match = _re.compile(what).match
-        result = ''.join([
-            chr(c) for c in xrange(127) if not match(chr(c))
-        ])
-        return '[^%s]' % fix_charclass(result)
-
-    def not_id_literal_(keep):
-        """ Make negated id_literal like char class """
-        match = _re.compile(id_literal_(keep)).match
-        result = ''.join([
-            chr(c) for c in xrange(127) if not match(chr(c))
-        ])
-        return r'[%s]' % fix_charclass(result)
-
-    not_id_literal = not_id_literal_(r'[a-zA-Z0-9_$]')
-    preregex1 = r'[(,=:\[!&|?{};\r\n]'
-    preregex2 = r'%(not_id_literal)sreturn' % locals()
-
-    id_literal = id_literal_(r'[a-zA-Z0-9_$]')
-    id_literal_open = id_literal_(r'[a-zA-Z0-9_${\[(!+-]')
-    id_literal_close = id_literal_(r'[a-zA-Z0-9_$}\])"\047+-]')
-    post_regex_off = id_literal_(r'[^\000-\040}\])?:|,;.&=+-]')
-
-    dull = r'[^\047"`/\000-\040]'
-
-    space_sub_simple = _re.compile((
-        # noqa pylint: disable = bad-continuation
-
-        r'(%(dull)s+)'                                         # 0
-        r'|(%(strings)s%(dull)s*)'                             # 1
-        r'|(?<=%(preregex1)s)'
-            r'%(space)s*(?:%(newline)s%(space)s*)*'
-            r'(%(regex)s)'                                     # 2
-            r'(%(space)s*(?:%(newline)s%(space)s*)+'           # 3
-                r'(?=%(post_regex_off)s))?'
-        r'|(?<=%(preregex2)s)'
-            r'%(space)s*(?:(%(newline)s)%(space)s*)*'          # 4
-            r'(%(regex)s)'                                     # 5
-            r'(%(space)s*(?:%(newline)s%(space)s*)+'           # 6
-                r'(?=%(post_regex_off)s))?'
-        r'|(?<=%(id_literal_close)s)'
-            r'%(space)s*(?:(%(newline)s)%(space)s*)+'          # 7
-            r'(?=%(id_literal_open)s)'
-        r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)'  # 8
-        r'|(?<=\+)(%(space)s)+(?=\+)'                          # 9
-        r'|(?<=-)(%(space)s)+(?=-)'                            # 10
-        r'|%(space)s+'
-        r'|(?:%(newline)s%(space)s*)+'
-    ) % locals()).sub
-
-    # print space_sub_simple.__self__.pattern
-
-    def space_subber_simple(match):
-        """ Substitution callback """
-        # pylint: disable = too-many-return-statements
-
-        groups = match.groups()
-        if groups[0]:
-            return groups[0]
-        elif groups[1]:
-            return groups[1]
-        elif groups[2]:
-            if groups[3]:
-                return groups[2] + '\n'
-            return groups[2]
-        elif groups[5]:
-            return "%s%s%s" % (
-                groups[4] and '\n' or '',
-                groups[5],
-                groups[6] and '\n' or '',
-            )
-        elif groups[7]:
-            return '\n'
-        elif groups[8] or groups[9] or groups[10]:
-            return ' '
-        else:
-            return ''
-
-    space_sub_banged = _re.compile((
-        # noqa pylint: disable = bad-continuation
-
-        r'(%(dull)s+)'                                         # 0
-        r'|(%(strings)s%(dull)s*)'                             # 1
-        r'|(?<=%(preregex1)s)'
-            r'(%(space)s*(?:%(newline)s%(space)s*)*)'          # 2
-            r'(%(regex)s)'                                     # 3
-            r'(%(space)s*(?:%(newline)s%(space)s*)+'           # 4
-                r'(?=%(post_regex_off)s))?'
-        r'|(?<=%(preregex2)s)'
-            r'(%(space)s*(?:(%(newline)s)%(space)s*)*)'        # 5, 6
-            r'(%(regex)s)'                                     # 7
-            r'(%(space)s*(?:%(newline)s%(space)s*)+'           # 8
-                r'(?=%(post_regex_off)s))?'
-        r'|(?<=%(id_literal_close)s)'
-            r'(%(space)s*(?:%(newline)s%(space)s*)+)'          # 9
-            r'(?=%(id_literal_open)s)'
-        r'|(?<=%(id_literal)s)(%(space)s+)(?=%(id_literal)s)'  # 10
-        r'|(?<=\+)(%(space)s+)(?=\+)'                          # 11
-        r'|(?<=-)(%(space)s+)(?=-)'                            # 12
-        r'|(%(space)s+)'                                       # 13
-        r'|((?:%(newline)s%(space)s*)+)'                       # 14
-    ) % locals()).sub
-
-    # print space_sub_banged.__self__.pattern
-
-    keep = _re.compile((
-        r'%(space_chars)s+|%(space_comment_nobang)s+|%(newline)s+'
-        r'|(%(bang_comment)s+)'
-    ) % locals()).sub
-    keeper = lambda m: m.groups()[0] or ''
-
-    # print keep.__self__.pattern
-
-    def space_subber_banged(match):
-        """ Substitution callback """
-        # pylint: disable = too-many-return-statements
-
-        groups = match.groups()
-        if groups[0]:
-            return groups[0]
-        elif groups[1]:
-            return groups[1]
-        elif groups[3]:
-            return "%s%s%s%s" % (
-                keep(keeper, groups[2]),
-                groups[3],
-                keep(keeper, groups[4] or ''),
-                groups[4] and '\n' or '',
-            )
-        elif groups[7]:
-            return "%s%s%s%s%s" % (
-                keep(keeper, groups[5]),
-                groups[6] and '\n' or '',
-                groups[7],
-                keep(keeper, groups[8] or ''),
-                groups[8] and '\n' or '',
-            )
-        elif groups[9]:
-            return keep(keeper, groups[9]) + '\n'
-        elif groups[10] or groups[11] or groups[12]:
-            return keep(keeper, groups[10] or groups[11] or groups[12]) or ' '
-        else:
-            return keep(keeper, groups[13] or groups[14])
-
-    def jsmin(script, keep_bang_comments=False):
-        r"""
-        Minify javascript based on `jsmin.c by Douglas Crockford`_\.
-
-        Instead of parsing the stream char by char, it uses a regular
-        expression approach which minifies the whole script with one big
-        substitution regex.
-
-        .. _jsmin.c by Douglas Crockford:
-           http://www.crockford.com/javascript/jsmin.c
-
-        :Parameters:
-          `script` : ``str``
-            Script to minify
-
-          `keep_bang_comments` : ``bool``
-            Keep comments starting with an exclamation mark? (``/*!...*/``)
-
-        :Return: Minified script
-        :Rtype: ``str``
-        """
-        # pylint: disable = redefined-outer-name
-
-        if keep_bang_comments:
-            return space_sub_banged(
-                space_subber_banged, '\n%s\n' % script
-            ).strip()
-        else:
-            return space_sub_simple(
-                space_subber_simple, '\n%s\n' % script
-            ).strip()
-
-    return jsmin
-
-jsmin = _make_jsmin()
-
-
-def jsmin_for_posers(script, keep_bang_comments=False):
-    r"""
-    Minify javascript based on `jsmin.c by Douglas Crockford`_\.
-
-    Instead of parsing the stream char by char, it uses a regular
-    expression approach which minifies the whole script with one big
-    substitution regex.
-
-    .. _jsmin.c by Douglas Crockford:
-       http://www.crockford.com/javascript/jsmin.c
-
-    :Warning: This function is the digest of a _make_jsmin() call. It just
-              utilizes the resulting regexes. It's here for fun and may
-              vanish any time. Use the `jsmin` function instead.
-
-    :Parameters:
-      `script` : ``str``
-        Script to minify
-
-      `keep_bang_comments` : ``bool``
-        Keep comments starting with an exclamation mark? (``/*!...*/``)
-
-    :Return: Minified script
-    :Rtype: ``str``
-    """
-    if not keep_bang_comments:
-        rex = (
-            r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]'
-            r'|\r?\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]'
-            r'|\r?\n|\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?'
-            r'{};\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*'
-            r'][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\0'
-            r'14\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r'
-            r'\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r'
-            r'\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/))((?:[\000-\011\013\014'
-            r'\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[^\r'
-            r'\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:'
-            r'[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)+,.:;=?\]|}-]))?|(?<=[\00'
-            r'0-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\016-\040]|(?'
-            r':/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?[\r\n]'
-            r'))(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*'
-            r'\*+)*/))*)*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\['
-            r'[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/))(('
-            r'?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)'
-            r'*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\04'
-            r'0]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)+,.:;'
-            r'=?\]|}-]))?|(?<=[^\000-!#%&(*,./:-@\[\\^`{|~])(?:[\000-\011\01'
-            r'3\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:((?:(?:'
-            r'//[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]'
-            r'*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,./:-@\\-^'
-            r'`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\013\014\0'
-            r'16-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./'
-            r':-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|(?:/\*['
-            r'^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013'
-            r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:['
-            r'\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
-            r')+|(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]'
-            r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+'
-        )
-
-        def subber(match):
-            """ Substitution callback """
-            groups = match.groups()
-            return (
-                groups[0] or
-                groups[1] or
-                (groups[3] and (groups[2] + '\n')) or
-                groups[2] or
-                (groups[5] and "%s%s%s" % (
-                    groups[4] and '\n' or '',
-                    groups[5],
-                    groups[6] and '\n' or '',
-                )) or
-                (groups[7] and '\n') or
-                (groups[8] and ' ') or
-                (groups[9] and ' ') or
-                (groups[10] and ' ') or
-                ''
-            )
-    else:
-        rex = (
-            r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]'
-            r'|\r?\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]'
-            r'|\r?\n|\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?'
-            r'{};\r\n])((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/'
-            r'*][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013'
-            r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*)((?:/(?!'
-            r'[\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^'
-            r'\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/))((?:[\000-\011\013\01'
-            r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[^'
-            r'\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+('
-            r'?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)+,.:;=?\]|}-]))?|(?<=['
-            r'\000-#%-,./:-@\[-^`{-~-]return)((?:[\000-\011\013\014\016-\040'
-            r']|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?['
-            r'\r\n]))(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*]['
-            r'^*]*\*+)*/))*)*)((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|'
-            r'(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*'
-            r'/))((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]'
-            r'*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\01'
-            r'6-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)'
-            r'+,.:;=?\]|}-]))?|(?<=[^\000-!#%&(*,./:-@\[\\^`{|~])((?:[\000-'
-            r'\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:'
-            r'(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/'
-            r'\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+)(?=[^\000-\040"#%-\047)*,./'
-            r':-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\01'
-            r'3\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+)(?=[^\000'
-            r'-#%-,./:-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|'
-            r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+)(?=\+)|(?<=-)((?:[\000-\0'
-            r'11\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+)(?=-'
-            r')|((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*'
-            r'\*+)*/))+)|((?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014'
-            r'\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+)'
-        )
-
-        keep = _re.compile((
-            r'[\000-\011\013\014\016-\040]+|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*'
-            r'\*+)*/)+|(?:(?://[^\r\n]*)?[\r\n])+|((?:/\*![^*]*\*+(?:[^/*][^'
-            r'*]*\*+)*/)+)'
-        ) % locals()).sub
-        keeper = lambda m: m.groups()[0] or ''
-
-        def subber(match):
-            """ Substitution callback """
-            groups = match.groups()
-            return (
-                groups[0] or
-                groups[1] or
-                (groups[3] and "%s%s%s%s" % (
-                    keep(keeper, groups[2]),
-                    groups[3],
-                    keep(keeper, groups[4] or ''),
-                    groups[4] and '\n' or '',
-                )) or
-                (groups[7] and "%s%s%s%s%s" % (
-                    keep(keeper, groups[5]),
-                    groups[6] and '\n' or '',
-                    groups[7],
-                    keep(keeper, groups[8] or ''),
-                    groups[8] and '\n' or '',
-                )) or
-                (groups[9] and keep(keeper, groups[9] + '\n')) or
-                (groups[10] and keep(keeper, groups[10]) or ' ') or
-                (groups[11] and keep(keeper, groups[11]) or ' ') or
-                (groups[12] and keep(keeper, groups[12]) or ' ') or
-                keep(keeper, groups[13] or groups[14])
-            )
-
-    return _re.sub(rex, subber, '\n%s\n' % script).strip()
-
-
-if __name__ == '__main__':
-    def main():
-        """ Main """
-        import sys as _sys
-
-        argv = _sys.argv[1:]
-        keep_bang_comments = '-b' in argv or '-bp' in argv or '-pb' in argv
-        if '-p' in argv or '-bp' in argv or '-pb' in argv:
-            xjsmin = _make_jsmin(python_only=True)
-        else:
-            xjsmin = jsmin
-
-        _sys.stdout.write(xjsmin(
-            _sys.stdin.read(), keep_bang_comments=keep_bang_comments
-        ))
-
-    main()
diff --git a/scripts/check_gn.js b/scripts/check_gn.js
deleted file mode 100644
index 2df36ad..0000000
--- a/scripts/check_gn.js
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-'use strict';
-
-const fs = require('fs');
-const path = require('path');
-
-const FRONTEND_PATH = path.resolve(__dirname, '..', 'front_end');
-
-const manifestModules = [];
-for (var config of ['inspector.json', 'devtools_app.json', 'js_app.json', 'node_app.json', 'shell.json', 'worker_app.json'])
-  manifestModules.push(...require(path.resolve(FRONTEND_PATH, config)).modules);
-
-const utils = require('./utils');
-
-const gnPath = path.resolve(__dirname, '..', 'BUILD.gn');
-const gnFile = fs.readFileSync(gnPath, 'utf-8');
-const gnLines = gnFile.split('\n');
-
-function main() {
-  let errors = [];
-  errors = errors.concat(checkNonAutostartNonRemoteModules());
-  errors = errors.concat(checkAllDevToolsFiles());
-  if (errors.length) {
-    console.log('DevTools BUILD.gn checker detected errors!');
-    console.log(`There's an issue with: ${gnPath}`);
-    console.log(errors.join('\n'));
-    process.exit(1);
-  }
-  console.log('DevTools BUILD.gn checker passed');
-}
-
-main();
-
-/**
- * Ensures that generated module files are in the right list in BUILD.gn.
- * This is primarily to avoid remote modules from accidentally getting
- * bundled with the main Chrome binary.
- */
-function checkNonAutostartNonRemoteModules() {
-  const errors = [];
-  const gnVariable = 'generated_non_autostart_non_remote_modules';
-  const lines = selectGNLines(`${gnVariable} = [`, ']');
-  if (!lines.length) {
-    return [
-      'Could not identify non-autostart non-remote modules in gn file',
-      'Please look at: ' + __filename,
-    ];
-  }
-  const text = lines.join('\n');
-  const modules = manifestModules.filter(m => m.type !== 'autostart' && m.type !== 'remote').map(m => m.name);
-
-  const missingModules = modules.filter(m => !utils.includes(text, `${m}/${m}_module.js`));
-  if (missingModules.length)
-    errors.push(`Check that you've included [${missingModules.join(', ')}] modules in: ` + gnVariable);
-
-  // e.g. "$resources_out_dir/audits/audits_module.js" => "audits"
-  const mapLineToModuleName = line => line.split('/')[2].split('_module')[0];
-
-  const extraneousModules = lines.map(mapLineToModuleName).filter(module => !utils.includes(modules, module));
-  if (extraneousModules.length)
-    errors.push(`Found extraneous modules [${extraneousModules.join(', ')}] in: ` + gnVariable);
-
-  return errors;
-}
-
-/**
- * Ensures that all source files (according to the various module.json files) are
- * listed in BUILD.gn.
- */
-function checkAllDevToolsFiles() {
-  const errors = [];
-  const excludedFiles = ['InspectorBackendCommands.js', 'SupportedCSSProperties.js'];
-  const gnVariable = 'all_devtools_files';
-  const lines = selectGNLines(`${gnVariable} = [`, ']');
-  if (!lines.length) {
-    return [
-      'Could not identify all_devtools_files list in gn file',
-      'Please look at: ' + __filename,
-    ];
-  }
-  const gnFiles = new Set(lines);
-  var moduleFiles = [];
-  fs.readdirSync(FRONTEND_PATH).forEach(function(moduleName) {
-    const moduleJSONPath = path.join(FRONTEND_PATH, moduleName, 'module.json');
-    if (utils.isFile(moduleJSONPath)) {
-      const moduleJSON = require(moduleJSONPath);
-      const scripts = moduleJSON.scripts || [];
-      const resources = moduleJSON.resources || [];
-      const files = scripts.concat(resources)
-                        .map(relativePathFromBuildGN)
-                        .filter(file => excludedFiles.every(excludedFile => !file.includes(excludedFile)));
-      moduleFiles = moduleFiles.concat(files);
-
-      function relativePathFromBuildGN(filename) {
-        const relativePath = path.normalize(`front_end/${moduleName}/${filename}`);
-        return `"${relativePath}",`;
-      }
-    }
-  });
-  for (const file of moduleFiles) {
-    if (!gnFiles.has(file))
-      errors.push(`Missing file in BUILD.gn for ${gnVariable}: ` + file);
-  }
-  return errors;
-}
-
-function selectGNLines(startLine, endLine) {
-  let lines = gnLines.map(line => line.trim());
-  let startIndex = lines.indexOf(startLine);
-  if (startIndex === -1)
-    return [];
-  let endIndex = lines.indexOf(endLine, startIndex);
-  if (endIndex === -1)
-    return [];
-  return lines.slice(startIndex + 1, endIndex);
-}
diff --git a/scripts/chrome_debug_launcher/launch_chrome.js b/scripts/chrome_debug_launcher/launch_chrome.js
deleted file mode 100644
index e7b2625..0000000
--- a/scripts/chrome_debug_launcher/launch_chrome.js
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var childProcess = require('child_process');
-var fs = require('fs');
-var path = require('path');
-var shell = childProcess.execSync;
-
-var utils = require('../utils');
-
-var REMOTE_DEBUGGING_PORT = parseInt(process.env.REMOTE_DEBUGGING_PORT, 10) || 9222;
-var SERVER_PORT = parseInt(process.env.PORT, 10) || 8090;
-var CHROMIUM_DEFAULT_PATH = path.resolve(__dirname, '..', '..', '..', '..', '..', '..', 'out', 'Release', 'chrome');
-var CHROME_PROFILE_PATH = path.resolve(__dirname, '..', '..', '.dev_profile');
-
-var Flags = {
-  RESET_PROFILE: '--reset-profile',
-};
-
-if (utils.includes(process.argv, Flags.RESET_PROFILE)) {
-  console.log(`Removing your dev profile for Chrome Canary / Chromium at:`);
-  console.log(CHROME_PROFILE_PATH, '\n');
-  utils.removeRecursive(CHROME_PROFILE_PATH);
-}
-
-var chromeArgs = [
-  `--remote-debugging-port=${REMOTE_DEBUGGING_PORT}`,
-  `--custom-devtools-frontend=http://localhost:${SERVER_PORT}/front_end/`, `--no-first-run`,
-  '--enable-devtools-experiments', `http://localhost:${REMOTE_DEBUGGING_PORT}#custom=true&experiments=true`,
-  `https://devtools.chrome.com`, `--user-data-dir=${CHROME_PROFILE_PATH}`
-].concat(process.argv.slice(2));
-
-if (process.platform === 'win32') {
-  launchChromeWindows();
-  return;
-}
-if (process.platform === 'darwin') {
-  launchChromeMac();
-  return;
-}
-if (process.platform === 'linux') {
-  launchChromeLinux();
-  return;
-}
-
-throw new Error(`Unrecognized platform detected: ${process.platform}`);
-
-function launchChromeWindows() {
-  var chromeCanaryPath;
-  var suffix = '\\Google\\Chrome SxS\\Application\\chrome.exe';
-  var prefixes = [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']];
-  for (var i = 0; i < prefixes.length; i++) {
-    var prefix = prefixes[i];
-    try {
-      chromeCanaryPath = path.join(prefix, suffix);
-      fs.accessSync(chromeCanaryPath);
-      break;
-    } catch (e) {
-    }
-  }
-  launchChrome(chromeCanaryPath, chromeArgs);
-}
-
-function launchChromeMac() {
-  var chromeExecPath;
-  if (utils.isFile(process.env.CHROMIUM_PATH)) {
-    chromeExecPath = process.env.CHROMIUM_PATH;
-  } else {
-    var lsregister =
-        '/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister';
-    var chromeCanaryPath = shellOutput(
-        `${lsregister} -dump | grep -i 'applications/google chrome canary.app$' | awk '{$1=""; print $0}' | head -n 1`);
-    chromeExecPath = `${chromeCanaryPath}/Contents/MacOS/Google Chrome Canary`;
-  }
-  launchChrome(chromeExecPath, chromeArgs);
-}
-
-function launchChromeLinux() {
-  var chromiumPath;
-  if (utils.isFile(process.env.CHROMIUM_PATH))
-    chromiumPath = process.env.CHROMIUM_PATH;
-  else if (utils.isFile(CHROMIUM_DEFAULT_PATH)) {
-    chromiumPath = CHROMIUM_DEFAULT_PATH;
-  } else {
-    onLaunchChromeError();
-    return;
-  }
-  launchChrome(chromiumPath, chromeArgs);
-}
-
-function launchChrome(filePath, chromeArgs) {
-  console.log(`Launching Chrome from ${filePath}`);
-  console.log('Chrome args:', chromeArgs.join(' '), '\n');
-  var child;
-  try {
-    child = childProcess.spawn(filePath, chromeArgs, {
-      stdio: 'inherit',
-    });
-  } catch (error) {
-    onLaunchChromeError();
-    return;
-  }
-  child.on('error', onLaunchChromeError);
-  child.on('exit', onExit);
-  function onExit(code) {
-    console.log('Exited Chrome with code', code);
-  }
-}
-
-function onLaunchChromeError() {
-  if (process.platform !== 'linux') {
-    console.log('ERROR: Cannot find Chrome Canary on your computer');
-    console.log('Install Chome Canary at:');
-    console.log('https://www.google.com/chrome/browser/canary.html\n');
-  } else {
-    console.log('ERROR: Could not launch Chromium');
-    console.log('The environment variable CHROMIUM_PATH must be set to executable of a build of Chromium');
-    console.log('If you do not have a recent build of chromium, you can get one from:');
-    console.log('https://download-chromium.appspot.com/\n');
-  }
-}
-
-function print(buffer) {
-  var string = buffer.toString();
-  console.log(string);
-  return string;
-}
-
-function shellOutput(command) {
-  return shell(command).toString().trim();
-}
diff --git a/scripts/chrome_debug_launcher/package.json b/scripts/chrome_debug_launcher/package.json
deleted file mode 100644
index c949381..0000000
--- a/scripts/chrome_debug_launcher/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "chrome-debug-launcher",
-  "description": "Finds Chrome Canary and launches it in debug mode",
-  "version": "0.1.0",
-  "keywords": [
-    "devtools",
-    "chrome",
-    "chromium"
-  ],
-  "author": "The Chromium Authors",
-  "license": "SEE LICENSE IN https://chromium.googlesource.com/chromium/src/+/master/LICENSE",
-  "bugs": {
-    "url": "https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component:Platform%3EDevTools%20&sort=-opened&colspec=ID%20Stars%20Owner%20Summary%20Modified%20Opened"
-  }
-}
diff --git a/scripts/closure/COPYING b/scripts/closure/COPYING
deleted file mode 100644
index d645695..0000000
--- a/scripts/closure/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/scripts/closure/README.md b/scripts/closure/README.md
deleted file mode 100644
index 83f5621..0000000
--- a/scripts/closure/README.md
+++ /dev/null
@@ -1,494 +0,0 @@
-# [Google Closure Compiler](https://developers.google.com/closure/compiler/)
-
-[![Build Status](https://travis-ci.org/google/closure-compiler.svg?branch=master)](https://travis-ci.org/google/closure-compiler)
-
-The [Closure Compiler](https://developers.google.com/closure/compiler/) is a tool for making JavaScript download and run faster. It is a true compiler for JavaScript. Instead of compiling from a source language to machine code, it compiles from JavaScript to better JavaScript. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls.
-
-## Getting Started
- * [Download the latest version](http://dl.google.com/closure-compiler/compiler-latest.zip) ([Release details here](https://github.com/google/closure-compiler/wiki/Releases))
- * [Download a specific version](https://github.com/google/closure-compiler/wiki/Binary-Downloads)
- * See the [Google Developers Site](https://developers.google.com/closure/compiler/docs/gettingstarted_app) for documentation including instructions for running the compiler from the command line.
-
-## Options for Getting Help
-1. Post in the [Closure Compiler Discuss Group](https://groups.google.com/forum/#!forum/closure-compiler-discuss)
-2. Ask a question on [Stack Overflow](http://stackoverflow.com/questions/tagged/google-closure-compiler)
-3. Consult the [FAQ](https://github.com/google/closure-compiler/wiki/FAQ)
-
-## Building it Yourself
-
-Note: The Closure Compiler requires [Java 7 or higher](http://www.java.com/).
-
-### Using [Ant](http://ant.apache.org/)
-
-1. Download the [Ant build tool](http://ant.apache.org/bindownload.cgi).
-
-2. At the root of the source tree, there is an Ant file named ```build.xml```.
-   To use it, navigate to the same directory and type the command
-
-    ```
-    ant jar
-    ```
-
-    This will produce a jar file called ```build/compiler.jar```.
-
-### Using [Eclipse](http://www.eclipse.org/)
-
-1. Download and open the [Eclipse IDE](http://www.eclipse.org/).
-2. Navigate to ```File > New > Project ...``` and create a Java Project. Give
-   the project a name.
-3. Select ```Create project from existing source``` and choose the root of the
-   checked-out source tree as the existing directory.
-3. Navigate to the ```build.xml``` file. You will see all the build rules in
-   the Outline pane. Run the ```jar``` rule to build the compiler in
-   ```build/compiler.jar```.
-
-## Running
-
-On the command line, at the root of this project, type
-
-```
-java -jar build/compiler.jar
-```
-
-This starts the compiler in interactive mode. Type
-
-```javascript
-var x = 17 + 25;
-```
-
-then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux)
-and "Enter" again. The Compiler will respond:
-
-```javascript
-var x=42;
-```
-
-The Closure Compiler has many options for reading input from a file, writing
-output to a file, checking your code, and running optimizations. To learn more,
-type
-
-```
-java -jar compiler.jar --help
-```
-
-More detailed information about running the Closure Compiler is available in the
-[documentation](http://code.google.com/closure/compiler/docs/gettingstarted_app.html).
-
-## Compiling Multiple Scripts
-
-If you have multiple scripts, you should compile them all together with one
-compile command.
-
-```bash
-java -jar compiler.jar --js_output_file=out.js in1.js in2.js in3.js ...
-```
-
-You can also use minimatch-style globs.
-
-```bash
-# Recursively include all js files in subdirs
-java -jar compiler.jar --js_output_file=out.js 'src/**.js'
-
-# Recursively include all js files in subdirs, exclusing test files.
-# Use single-quotes, so that bash doesn't try to expand the '!'
-java -jar compiler.jar --js_output_file=out.js 'src/**.js' '!**_test.js'
-```
-
-The Closure Compiler will concatenate the files in the order they're passed at
-the command line.
-
-If you're using globs or many files, you may start to run into
-problems with managing dependencies between scripts. In this case, you should
-use the [Closure Library](https://developers.google.com/closure/library/). It
-contains functions for enforcing dependencies between scripts, and Closure Compiler
-will re-order the inputs automatically.
-
-## How to Contribute
-### Reporting a bug
-1. First make sure that it is really a bug and not simply the way that Closure Compiler works (especially true for ADVANCED_OPTIMIZATIONS).
- * Check the [official documentation](https://developers.google.com/closure/compiler/)
- * Consult the [FAQ](https://github.com/google/closure-compiler/wiki/FAQ)
- * Search on [Stack Overflow](http://stackoverflow.com/questions/tagged/google-closure-compiler) and in the [Closure Compiler Discuss Group](https://groups.google.com/forum/#!forum/closure-compiler-discuss)
-2. If you still think you have found a bug, make sure someone hasn't already reported it. See the list of [known issues](https://github.com/google/closure-compiler/issues).
-3. If it hasn't been reported yet, post a new issue. Make sure to add enough detail so that the bug can be recreated. The smaller the reproduction code, the better.
-
-### Suggesting a Feature
-1. Consult the [FAQ](https://github.com/google/closure-compiler/wiki/FAQ) to make sure that the behaviour you would like isn't specifically excluded (such as string inlining).
-2. Make sure someone hasn't requested the same thing. See the list of [known issues](https://github.com/google/closure-compiler/issues).
-3. Read up on [what type of feature requests are accepted](https://github.com/google/closure-compiler/wiki/FAQ#how-do-i-submit-a-feature-request-for-a-new-type-of-optimization).
-4. Submit your reqest as an issue.
-
-### Submitting patches
-1. All contributors must sign a contributor license agreement. See the [CONTRIBUTORS](https://raw.githubusercontent.com/google/closure-compiler/master/CONTRIBUTORS) file for details.
-2. To make sure your changes are of the type that will be accepted, ask about your patch on the [Closure Compiler Discuss Group](https://groups.google.com/forum/#!forum/closure-compiler-discuss)
-3. Fork the repository.
-4. Make your changes.
-5. Submit a pull request for your changes. A project developer will review your work and then merge your request into the project.
-
-## Closure Compiler License
-
-Copyright 2009 The Closure Compiler Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-## Dependency Licenses
-
-### Rhino
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td>
-      <code>src/com/google/javascript/rhino</code>, <code>test/com/google/javascript/rhino</code>
-    </td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>http://www.mozilla.org/rhino</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>1.5R3, with heavy modifications</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Netscape Public License and MPL / GPL dual license</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>A partial copy of Mozilla Rhino. Mozilla Rhino is an
-implementation of JavaScript for the JVM.  The JavaScript
-parse tree data structures were extracted and modified
-significantly for use by Google's JavaScript compiler.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>The packages have been renamespaced. All code not
-relevant to the parse tree has been removed. A JsDoc parser and static typing
-system have been added.</td>
-  </tr>
-</table>
-
-### Args4j
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/args4j.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>https://args4j.dev.java.net/</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>2.0.26</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>MIT</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>args4j is a small Java class library that makes it easy to parse command line
-options/arguments in your CUI application.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### Guava Libraries
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/guava.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>https://github.com/google/guava</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>18.0</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Apache License 2.0</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>Google's core Java libraries.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### JSR 305
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/jsr305.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>http://code.google.com/p/jsr-305/</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>svn revision 47</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>BSD License</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>Annotations for software defect detection.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### JUnit
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/junit.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>http://sourceforge.net/projects/junit/</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>4.11</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Common Public License 1.0</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>A framework for writing and running automated tests in Java.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### Protocol Buffers
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/protobuf-java.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>http://code.google.com/p/protobuf/</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>2.5.0</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>New BSD License</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>Supporting libraries for protocol buffers,
-an encoding of structured data.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### Truth
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/truth.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>https://github.com/google/truth</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>0.24</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Apache License 2.0</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>Assertion/Proposition framework for Java unit tests</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### Ant
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td>
-      <code>lib/ant.jar</code>, <code>lib/ant-launcher.jar</code>
-    </td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>http://ant.apache.org/bindownload.cgi</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>1.8.1</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Apache License 2.0</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>Ant is a Java based build tool. In theory it is kind of like "make"
-without make's wrinkles and with the full portability of pure java code.</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### GSON
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>lib/gson.jar</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>https://code.google.com/p/google-gson/</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>2.2.4</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Apache license 2.0</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>A Java library to convert JSON to Java objects and vice-versa</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>None</td>
-  </tr>
-</table>
-
-### Node.js Closure Compiler Externs
-
-<table>
-  <tr>
-    <td>Code Path</td>
-    <td><code>contrib/nodejs</code></td>
-  </tr>
-
-  <tr>
-    <td>URL</td>
-    <td>https://github.com/dcodeIO/node.js-closure-compiler-externs</td>
-  </tr>
-
-  <tr>
-    <td>Version</td>
-    <td>e891b4fbcf5f466cc4307b0fa842a7d8163a073a</td>
-  </tr>
-
-  <tr>
-    <td>License</td>
-    <td>Apache 2.0 license</td>
-  </tr>
-
-  <tr>
-    <td>Description</td>
-    <td>Type contracts for NodeJS APIs</td>
-  </tr>
-
-  <tr>
-    <td>Local Modifications</td>
-    <td>Substantial changes to make them compatible with NpmCommandLineRunner.</td>
-  </tr>
-</table>
diff --git a/scripts/closure/closure_runner/build_compiler_runner_jar.py b/scripts/closure/closure_runner/build_compiler_runner_jar.py
deleted file mode 100755
index 7be1449..0000000
--- a/scripts/closure/closure_runner/build_compiler_runner_jar.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/python
-
-import os
-import shutil
-import subprocess
-import sys
-import tempfile
-
-
-def rel_to_abs(rel_path):
-    return os.path.join(script_path, rel_path)
-
-
-java_bin_path = os.getenv('JAVA_HOME', '')
-if java_bin_path:
-    java_bin_path = os.path.join(java_bin_path, 'bin')
-
-main_class = 'org.chromium.devtools.compiler.Runner'
-jar_name = 'closure_runner.jar'
-src_dir = 'src'
-script_path = os.path.dirname(os.path.abspath(__file__))
-closure_jar_relpath = os.path.join('..', 'compiler.jar')
-src_path = rel_to_abs(src_dir)
-
-
-def run_and_communicate(command, error_template):
-    proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
-    proc.communicate()
-    if proc.returncode:
-        print >> sys.stderr, error_template % proc.returncode
-        sys.exit(proc.returncode)
-
-
-def build_artifacts():
-    print 'Compiling...'
-    java_files = []
-    for root, dirs, files in sorted(os.walk(src_path)):
-        for file_name in files:
-            java_files.append(os.path.join(root, file_name))
-
-    bin_path = tempfile.mkdtemp()
-    manifest_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
-    try:
-        manifest_file.write('Class-Path: %s\n' % closure_jar_relpath)
-        manifest_file.close()
-        javac_path = os.path.join(java_bin_path, 'javac')
-        javac_command = '%s -target 7 -source 7 -d %s -cp %s %s' % (javac_path, bin_path, rel_to_abs(closure_jar_relpath),
-                                                                    ' '.join(java_files))
-        run_and_communicate(javac_command, 'Error: javac returned %d')
-
-        print 'Building jar...'
-        artifact_path = rel_to_abs(jar_name)
-        jar_path = os.path.join(java_bin_path, 'jar')
-        jar_command = '%s cvfme %s %s %s -C %s .' % (jar_path, artifact_path, manifest_file.name, main_class, bin_path)
-        run_and_communicate(jar_command, 'Error: jar returned %d')
-    finally:
-        os.remove(manifest_file.name)
-        shutil.rmtree(bin_path, True)
-
-
-def help():
-    print 'usage: %s' % os.path.basename(__file__)
-    print 'Builds closure_runner.jar from the %s directory contents' % src_dir
-
-
-def main():
-    if len(sys.argv) > 1:
-        help()
-        return
-    build_artifacts()
-    print 'Done.'
-
-
-if __name__ == '__main__':
-    main()
diff --git a/scripts/closure/closure_runner/closure_runner.jar b/scripts/closure/closure_runner/closure_runner.jar
deleted file mode 100644
index 8559612..0000000
--- a/scripts/closure/closure_runner/closure_runner.jar
+++ /dev/null
Binary files differ
diff --git a/scripts/closure/closure_runner/src/org/chromium/devtools/compiler/DevToolsCodingConvention.java b/scripts/closure/closure_runner/src/org/chromium/devtools/compiler/DevToolsCodingConvention.java
deleted file mode 100644
index a238589..0000000
--- a/scripts/closure/closure_runner/src/org/chromium/devtools/compiler/DevToolsCodingConvention.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.chromium.devtools.compiler;
-
-import com.google.javascript.jscomp.CodingConventions;
-
-public class DevToolsCodingConvention extends CodingConventions.Proxy {
-    private static final long serialVersionUID = 1L;
-
-    public DevToolsCodingConvention() {
-        super(CodingConventions.getDefault());
-    }
-
-    @Override
-    public boolean isPrivate(String name) {
-        return name.length() > 1 && name.charAt(0) == '_' && name.charAt(1) != '_';
-    }
-
-    @Override
-    public boolean isValidEnumKey(String key) {
-        return !key.isEmpty() && Character.isUpperCase(key.charAt(0));
-    }
-}
diff --git a/scripts/closure/closure_runner/src/org/chromium/devtools/compiler/Runner.java b/scripts/closure/closure_runner/src/org/chromium/devtools/compiler/Runner.java
deleted file mode 100644
index bcea380..0000000
--- a/scripts/closure/closure_runner/src/org/chromium/devtools/compiler/Runner.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package org.chromium.devtools.compiler;
-
-import com.google.common.collect.Lists;
-import com.google.common.io.Resources;
-import com.google.javascript.jscomp.*;
-import com.google.javascript.jscomp.Compiler;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.Option;
-
-import javax.xml.transform.Source;
-import java.io.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Prepares and executes several instances of the closure compiler.
- */
-public class Runner {
-    protected final Flags flags = new Flags();
-    private final PrintStream err;
-    private boolean isConfigValid;
-
-    public Runner(String[] args, PrintStream err) {
-        this.err = err;
-        List<String> argList = processArgs(args);
-        CmdLineParser parser = new CmdLineParser(flags);
-        isConfigValid = true;
-        try {
-            parser.parseArgument(argList.toArray(new String[] {}));
-            if (flags.compilerArgsFile == null) {
-                isConfigValid = false;
-            }
-        } catch (CmdLineException e) {
-            err.println(e.getMessage());
-            isConfigValid = false;
-        }
-
-        if (!isConfigValid) {
-            parser.printUsage(err);
-        }
-    }
-
-    private List<String> processArgs(String[] args) {
-        Pattern argPattern = Pattern.compile("(--[a-zA-Z_]+)=(.*)");
-        Pattern quotesPattern = Pattern.compile("^['\"](.*)['\"]$");
-        List<String> processedArgs = Lists.newArrayList();
-
-        for (String arg : args) {
-            Matcher matcher = argPattern.matcher(arg);
-            if (matcher.matches()) {
-                processedArgs.add(matcher.group(1));
-
-                String value = matcher.group(2);
-                Matcher quotesMatcher = quotesPattern.matcher(value);
-                if (quotesMatcher.matches()) {
-                    processedArgs.add(quotesMatcher.group(1));
-                } else {
-                    processedArgs.add(value);
-                }
-            } else {
-                processedArgs.add(arg);
-            }
-        }
-
-        return processedArgs;
-    }
-
-    private boolean shouldRunCompiler() {
-        return isConfigValid;
-    }
-
-    protected void logError(String message, Exception e) {
-        err.println("ERROR: " + message);
-        if (e != null) {
-            e.printStackTrace(err);
-        }
-    }
-
-    private void run() {
-        List<CompilerInstanceDescriptor> descriptors = getDescriptors();
-        if (descriptors == null) {
-            return;
-        }
-        ExecutorService executor = Executors.newFixedThreadPool(
-                Math.min(descriptors.size(), Runtime.getRuntime().availableProcessors() / 2 + 1));
-        try {
-            runWithExecutor(descriptors, executor);
-        } finally {
-            executor.shutdown();
-        }
-    }
-
-    private void runWithExecutor(
-            List<CompilerInstanceDescriptor> descriptors, ExecutorService executor) {
-        List<Future<CompilerRunner>> futures = new ArrayList<>(descriptors.size());
-        for (CompilerInstanceDescriptor descriptor : descriptors) {
-            try {
-                ByteArrayOutputStream rawStream = new ByteArrayOutputStream(512);
-                PrintStream errPrintStream = new PrintStream(rawStream, false, "UTF-8");
-                // We have to create instance of LocalCommandLineRunner object here,
-                // because its constructor should be executed on a single thread.
-                // Constructor is parsing flags and creating options object that can
-                // be used later in parallel during compilation.
-                LocalCommandLineRunner runner = new LocalCommandLineRunner(
-                        descriptor.commandLine.split(" +"), System.out, errPrintStream);
-
-                CompilerRunner task = new CompilerRunner(descriptor, rawStream, runner);
-                futures.add(executor.submit(task));
-            } catch (Exception e) {
-                System.err.println("ERROR - " + e.getMessage());
-                e.printStackTrace(System.err);
-            }
-        }
-
-        for (Future<CompilerRunner> future : futures) {
-            try {
-                CompilerRunner task = future.get();
-                int result = task.result;
-                if (result != 0) {
-                    System.err.println("ERROR: Compiler returned " + result);
-                }
-                task.errStream.flush();
-                System.err.println("@@ START_MODULE:" + task.descriptor.moduleName + " @@");
-                System.err.println(task.errStream.toString("UTF-8"));
-                System.err.println("@@ END_MODULE @@");
-            } catch (Exception e) {
-                System.err.println("ERROR - " + e.getMessage());
-                e.printStackTrace(System.err);
-            }
-        }
-        System.exit(0);
-    }
-
-    private List<CompilerInstanceDescriptor> getDescriptors() {
-        List<CompilerInstanceDescriptor> result = new ArrayList<>();
-        try (BufferedReader reader = new BufferedReader(
-                     new InputStreamReader(new FileInputStream(flags.compilerArgsFile), "UTF-8"))) {
-            int lineIndex = 0;
-            while (true) {
-                ++lineIndex;
-                String line = reader.readLine();
-                if (line == null) {
-                    break;
-                }
-                if (line.length() == 0) {
-                    continue;
-                }
-                String[] moduleAndArgs = line.split(" +", 2);
-                if (moduleAndArgs.length != 2) {
-                    logError(String.format(
-                                     "Line %d does not contain module name and compiler arguments",
-                                     lineIndex),
-                            null);
-                    continue;
-                }
-                result.add(new CompilerInstanceDescriptor(moduleAndArgs[0], moduleAndArgs[1]));
-            }
-        } catch (IOException e) {
-            logError("Failed to read compiler arguments file", e);
-            return null;
-        }
-
-        return result;
-    }
-
-    public static void main(String[] args) {
-        Runner runner = new Runner(args, System.err);
-        if (runner.shouldRunCompiler()) {
-            runner.run();
-        } else {
-            System.exit(-1);
-        }
-    }
-
-    private static class LocalCommandLineRunner extends CommandLineRunner {
-        protected LocalCommandLineRunner(String[] args, PrintStream out, PrintStream err) {
-            super(args, out, err);
-        }
-
-        @Override
-        protected void setRunOptions(CompilerOptions options)
-                throws FlagUsageException, IOException {
-            super.setRunOptions(options);
-            options.setCodingConvention(new DevToolsCodingConvention());
-        }
-
-        @Override
-        protected Compiler createCompiler() {
-            Compiler compiler = new Compiler();
-            final LightweightMessageFormatter formatter = new LightweightMessageFormatter(compiler);
-            PrintStreamErrorManager errorManager =
-                    new PrintStreamErrorManager(formatter, getErrorPrintStream()) {
-                @Override
-                public void report(CheckLevel level, JSError error) {
-                    String text = formatter.formatError(error);
-                    if (text.indexOf("access on a struct") == -1 || text.indexOf("Symbol") == -1)
-                        super.report(level, error);
-                }
-            };
-            errorManager.setSummaryDetailLevel(3);
-            compiler.setErrorManager(errorManager);
-            return compiler;
-        }
-
-        int execute() {
-            try {
-                return doRun();
-            } catch (Throwable t) {
-                t.printStackTrace();
-                return -2;
-            }
-        }
-    }
-
-    private static class CompilerRunner implements Callable<CompilerRunner> {
-        private final CompilerInstanceDescriptor descriptor;
-        private final ByteArrayOutputStream errStream;
-        private int result;
-        private final LocalCommandLineRunner runner;
-
-        public CompilerRunner(CompilerInstanceDescriptor descriptor,
-                ByteArrayOutputStream errStream, LocalCommandLineRunner runner) {
-            this.descriptor = descriptor;
-            this.errStream = errStream;
-            this.runner = runner;
-        }
-
-        @Override
-        public CompilerRunner call() throws Exception {
-            if (!this.runner.shouldRunCompiler()) {
-                this.result = -1;
-            }
-            this.result = this.runner.execute();
-            return this;
-        }
-    }
-
-    private static class Flags {
-        @Option(name = "--compiler-args-file",
-                usage = "Full path to file containing compiler arguments (one line per instance)")
-        private String compilerArgsFile = null;
-    }
-
-    private static class CompilerInstanceDescriptor {
-        private final String moduleName;
-        private final String commandLine;
-
-        public CompilerInstanceDescriptor(String moduleName, String commandLine) {
-            this.moduleName = moduleName;
-            this.commandLine = commandLine;
-        }
-    }
-}
diff --git a/scripts/closure/compiler.jar b/scripts/closure/compiler.jar
deleted file mode 100644
index ca4eec4..0000000
--- a/scripts/closure/compiler.jar
+++ /dev/null
Binary files differ
diff --git a/scripts/compile_frontend.py b/scripts/compile_frontend.py
deleted file mode 100755
index 1c45aa0..0000000
--- a/scripts/compile_frontend.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import argparse
-import os
-import os.path as path
-import re
-import shutil
-import subprocess
-import sys
-import tempfile
-
-from build import modular_build
-from build import generate_protocol_externs
-
-import dependency_preprocessor
-import utils
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-is_cygwin = sys.platform == 'cygwin'
-
-
-def popen(arguments):
-    return subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-
-def to_platform_path(filepath):
-    if not is_cygwin:
-        return filepath
-    return re.sub(r'^/cygdrive/(\w)', '\\1:', filepath)
-
-
-def to_platform_path_exact(filepath):
-    if not is_cygwin:
-        return filepath
-    output, _ = popen(['cygpath', '-w', filepath]).communicate()
-    # pylint: disable=E1103
-    return output.strip().replace('\\', '\\\\')
-
-
-scripts_path = path.dirname(path.abspath(__file__))
-devtools_path = path.dirname(scripts_path)
-inspector_path = path.join(path.dirname(devtools_path), 'core', 'inspector')
-# TODO(dgozman): move these checks to v8.
-v8_inspector_path = path.normpath(path.join(path.dirname(devtools_path), os.pardir, os.pardir, os.pardir, 'v8', 'src', 'inspector'))
-devtools_frontend_path = path.join(devtools_path, 'front_end')
-global_externs_file = to_platform_path(path.join(devtools_frontend_path, 'externs.js'))
-protocol_externs_file = path.join(devtools_frontend_path, 'protocol_externs.js')
-runtime_file = to_platform_path(path.join(devtools_frontend_path, 'Runtime.js'))
-
-closure_compiler_jar = to_platform_path(path.join(scripts_path, 'closure', 'compiler.jar'))
-closure_runner_jar = to_platform_path(path.join(scripts_path, 'closure', 'closure_runner', 'closure_runner.jar'))
-jsdoc_validator_jar = to_platform_path(path.join(scripts_path, 'jsdoc_validator', 'jsdoc_validator.jar'))
-
-type_checked_jsdoc_tags_list = ['param', 'return', 'type', 'enum']
-type_checked_jsdoc_tags_or = '|'.join(type_checked_jsdoc_tags_list)
-
-# Basic regex for invalid JsDoc types: an object type name ([A-Z][_A-Za-z0-9.]+[A-Za-z0-9]) not preceded by '!', '?', ':' (this, new), or '.' (object property).
-invalid_type_regex = re.compile(r'@(?:' + type_checked_jsdoc_tags_or +
-                                r')\s*\{.*(?<![!?:._A-Za-z0-9])([A-Z][_A-Za-z0-9.]+[A-Za-z0-9])[^/]*\}')
-invalid_type_designator_regex = re.compile(r'@(?:' + type_checked_jsdoc_tags_or + r')\s*.*(?<![{: ])([?!])=?\}')
-invalid_non_object_type_regex = re.compile(r'@(?:' + type_checked_jsdoc_tags_or + r')\s*\{.*(![a-z]+)[^/]*\}')
-error_warning_regex = re.compile(r'WARNING|ERROR')
-loaded_css_regex = re.compile(r'(?:registerRequiredCSS|WebInspector\.View\.createStyleElement)\s*\(\s*"(.+)"\s*\)')
-
-java_build_regex = re.compile(r'\w+ version "(\d+)\.(\d+)')
-
-
-def log_error(message):
-    print 'ERROR: ' + message
-
-
-def error_excepthook(exctype, value, traceback):
-    print 'ERROR:'
-    sys.__excepthook__(exctype, value, traceback)
-
-
-sys.excepthook = error_excepthook
-
-application_descriptors = [
-    'inspector',
-    'toolbox',
-    'integration_test_runner',
-    'formatter_worker',
-    'heap_snapshot_worker',
-]
-
-skipped_namespaces = {
-    'Console',  # Closure uses Console as a namespace item so we cannot override it right now.
-    'Gonzales',  # third party module defined in front_end/externs.js
-    'Terminal',  # third party module defined in front_end/externs.js
-}
-
-
-def has_errors(output):
-    return re.search(error_warning_regex, output) != None
-
-
-class JSDocChecker:
-
-    def __init__(self, descriptors, java_exec):
-        self._error_found = False
-        self._all_files = descriptors.all_compiled_files()
-        self._java_exec = java_exec
-
-    def check(self):
-        print 'Verifying JSDoc comments...'
-        self._verify_jsdoc()
-        self._run_jsdoc_validator()
-        return self._error_found
-
-    def _run_jsdoc_validator(self):
-        files = [to_platform_path(f) for f in self._all_files]
-        file_list = tempfile.NamedTemporaryFile(mode='wt', delete=False)
-        try:
-            file_list.write('\n'.join(files))
-        finally:
-            file_list.close()
-        proc = popen(self._java_exec + ['-jar', jsdoc_validator_jar, '--files-list-name', to_platform_path_exact(file_list.name)])
-        (out, _) = proc.communicate()
-        if out:
-            print('JSDoc validator output:%s%s' % (os.linesep, out))
-            self._error_found = True
-        os.remove(file_list.name)
-
-    def _verify_jsdoc(self):
-        for full_file_name in self._all_files:
-            line_index = 0
-            with open(full_file_name, 'r') as sourceFile:
-                for line in sourceFile:
-                    line_index += 1
-                    if line.rstrip():
-                        self._verify_jsdoc_line(full_file_name, line_index, line)
-
-    def _verify_jsdoc_line(self, file_name, line_index, line):
-
-        def print_error(message, error_position):
-            print '%s:%s: ERROR - %s%s%s%s%s%s' % (file_name, line_index, message, os.linesep, line, os.linesep,
-                                                   ' ' * error_position + '^', os.linesep)
-
-        known_css = {}
-        match = re.search(invalid_type_regex, line)
-        if match:
-            print_error('Type "%s" nullability not marked explicitly with "?" (nullable) or "!" (non-nullable)' % match.group(1),
-                        match.start(1))
-            self._error_found = True
-
-        match = re.search(invalid_non_object_type_regex, line)
-        if match:
-            print_error('Non-object type explicitly marked with "!" (non-nullable), which is the default and should be omitted',
-                        match.start(1))
-            self._error_found = True
-
-        match = re.search(invalid_type_designator_regex, line)
-        if match:
-            print_error('Type nullability indicator misplaced, should precede type', match.start(1))
-            self._error_found = True
-
-        match = re.search(loaded_css_regex, line)
-        if match:
-            file = path.join(devtools_frontend_path, match.group(1))
-            exists = known_css.get(file)
-            if exists is None:
-                exists = path.isfile(file)
-                known_css[file] = exists
-            if not exists:
-                print_error('Dynamically loaded CSS stylesheet is missing in the source tree', match.start(1))
-                self._error_found = True
-
-
-def find_java():
-    required_major = 1
-    required_minor = 7
-    exec_command = None
-    has_server_jvm = True
-    java_path = utils.which('java')
-
-    if not java_path:
-        print 'NOTE: No Java executable found in $PATH.'
-        sys.exit(1)
-
-    is_ok = False
-    java_version_out, _ = popen([java_path, '-version']).communicate()
-    # pylint: disable=E1103
-    match = re.search(java_build_regex, java_version_out)
-    if match:
-        major = int(match.group(1))
-        minor = int(match.group(2))
-        is_ok = major >= required_major and minor >= required_minor
-    if is_ok:
-        exec_command = [java_path, '-Xms1024m', '-server', '-XX:+TieredCompilation']
-        check_server_proc = popen(exec_command + ['-version'])
-        check_server_proc.communicate()
-        if check_server_proc.returncode != 0:
-            # Not all Java installs have server JVMs.
-            exec_command = exec_command.remove('-server')
-            has_server_jvm = False
-
-    if not is_ok:
-        print 'NOTE: Java executable version %d.%d or above not found in $PATH.' % (required_major, required_minor)
-        sys.exit(1)
-    print 'Java executable: %s%s' % (java_path, '' if has_server_jvm else ' (no server JVM)')
-    return exec_command
-
-
-common_closure_args = [
-    '--summary_detail_level',
-    '3',
-    '--jscomp_error',
-    'visibility',
-    '--jscomp_warning',
-    'missingOverride',
-    '--compilation_level',
-    'SIMPLE_OPTIMIZATIONS',
-    '--warning_level',
-    'VERBOSE',
-    '--language_in=ECMASCRIPT_2017',
-    '--language_out=ES5_STRICT',
-    '--extra_annotation_name',
-    'suppressReceiverCheck',
-    '--extra_annotation_name',
-    'suppressGlobalPropertiesCheck',
-    '--checks-only',
-    '--allow_method_call_decomposing',
-]
-
-
-def check_conditional_dependencies(modules_by_name):
-    errors_found = False
-    for name in modules_by_name:
-        if 'test_runner' in name:
-            continue
-        for dep_name in modules_by_name[name].get('dependencies', []):
-            dependency = modules_by_name[dep_name]
-            if dependency.get('experiment') or dependency.get('condition'):
-                log_error('Module "%s" may not depend on the conditional module "%s"' % (name, dep_name))
-                errors_found = True
-    return errors_found
-
-
-def prepare_closure_frontend_compile(temp_devtools_path, descriptors, namespace_externs_path):
-    temp_frontend_path = path.join(temp_devtools_path, 'front_end')
-    checker = dependency_preprocessor.DependencyPreprocessor(descriptors, temp_frontend_path, devtools_frontend_path)
-    checker.enforce_dependencies()
-
-    command = common_closure_args + [
-        '--externs',
-        to_platform_path(global_externs_file),
-        '--externs',
-        namespace_externs_path,
-        '--js',
-        runtime_file,
-    ]
-
-    all_files = descriptors.all_compiled_files()
-    args = []
-    for file in all_files:
-        args.extend(['--js', file])
-        if "InspectorBackend.js" in file:
-            args.extend(['--js', protocol_externs_file])
-    command += args
-    command = [arg.replace(devtools_frontend_path, temp_frontend_path) for arg in command]
-    compiler_args_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
-    try:
-        compiler_args_file.write('devtools_frontend %s' % (' '.join(command)))
-    finally:
-        compiler_args_file.close()
-    return compiler_args_file.name
-
-
-def generate_namespace_externs(modules_by_name):
-    special_case_namespaces_path = path.join(path.dirname(path.abspath(__file__)), 'special_case_namespaces.json')
-    with open(special_case_namespaces_path) as json_file:
-        special_case_namespaces = json.load(json_file)
-
-    def map_module_to_namespace(module):
-        return special_case_namespaces.get(module, to_camel_case(module))
-
-    def to_camel_case(snake_string):
-        components = snake_string.split('_')
-        return ''.join(x.title() for x in components)
-
-    all_namespaces = [map_module_to_namespace(module) for module in modules_by_name]
-    namespaces = [namespace for namespace in all_namespaces if namespace not in skipped_namespaces]
-    namespaces.sort()
-    namespace_externs_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
-    try:
-        for namespace in namespaces:
-            namespace_externs_file.write('/** @const */\n')
-            namespace_externs_file.write('var %s = {};\n' % namespace)
-    finally:
-        namespace_externs_file.close()
-    namespace_externs_path = to_platform_path(namespace_externs_file.name)
-    return namespace_externs_path
-
-
-def main():
-    global protocol_externs_file
-    errors_found = False
-    parser = argparse.ArgumentParser()
-    parser.add_argument('--protocol-externs-file')
-    args, _ = parser.parse_known_args()
-    if args.protocol_externs_file:
-        protocol_externs_file = args.protocol_externs_file
-    else:
-        generate_protocol_externs.generate_protocol_externs(protocol_externs_file,
-                                                            path.join(inspector_path, 'browser_protocol.json'),
-                                                            path.join(v8_inspector_path, 'js_protocol.json'))
-    loader = modular_build.DescriptorLoader(devtools_frontend_path)
-    descriptors = loader.load_applications(application_descriptors)
-    modules_by_name = descriptors.modules
-
-    java_exec = find_java()
-    errors_found |= check_conditional_dependencies(modules_by_name)
-
-    print 'Compiling frontend...'
-    temp_devtools_path = tempfile.mkdtemp()
-    namespace_externs_path = generate_namespace_externs(modules_by_name)
-    compiler_args_file_path = prepare_closure_frontend_compile(temp_devtools_path, descriptors, namespace_externs_path)
-    frontend_compile_proc = popen(
-        java_exec + ['-jar', closure_runner_jar, '--compiler-args-file', to_platform_path_exact(compiler_args_file_path)])
-
-    print 'Compiling devtools_compatibility.js...'
-
-    closure_compiler_command = java_exec + ['-jar', closure_compiler_jar] + common_closure_args
-
-    devtools_js_compile_command = closure_compiler_command + [
-        '--externs', to_platform_path(global_externs_file), '--externs',
-        to_platform_path(path.join(devtools_frontend_path, 'host', 'InspectorFrontendHostAPI.js')),
-        '--jscomp_off=externsValidation', '--js', to_platform_path(path.join(devtools_frontend_path, 'devtools_compatibility.js'))
-    ]
-    devtools_js_compile_proc = popen(devtools_js_compile_command)
-
-    errors_found |= JSDocChecker(descriptors, java_exec).check()
-
-    (devtools_js_compile_out, _) = devtools_js_compile_proc.communicate()
-    print 'devtools_compatibility.js compilation output:%s' % os.linesep, devtools_js_compile_out
-    errors_found |= has_errors(devtools_js_compile_out)
-
-    (frontend_compile_out, _) = frontend_compile_proc.communicate()
-    print 'devtools frontend compilation output:'
-    for line in frontend_compile_out.splitlines():
-        if "@@ START_MODULE" in line or "@@ END_MODULE" in line:
-            continue
-        print line
-    errors_found |= has_errors(frontend_compile_out)
-
-    os.remove(protocol_externs_file)
-    os.remove(namespace_externs_path)
-    os.remove(compiler_args_file_path)
-    shutil.rmtree(temp_devtools_path, True)
-
-    if errors_found:
-        print 'ERRORS DETECTED'
-        sys.exit(1)
-    print 'DONE - compiled without errors'
-
-
-if __name__ == "__main__":
-    main()
diff --git a/scripts/convert-3pas-product-registry.js b/scripts/convert-3pas-product-registry.js
deleted file mode 100644
index e4ea131..0000000
--- a/scripts/convert-3pas-product-registry.js
+++ /dev/null
@@ -1,471 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-const fs = require('fs');
-
-/*
-How to use:
-1) Get dump of data as CSV format and name it 3pas.csv same directory as this script.
-2) Header fields in the CSV will be used as keys when destructing into JSON objects [ie: top row data should not have spaces or special chars]
-3) The two important column names are: 'name_legal_product' and 'domain'.
-4) There may not be a header named 'prefix'.
-5) 'name_legal_product' Will have it's data cleaned up a bit, so be prepared for it to change.
-6) This script tries to de-duplicate any data, so be prepared for many entries to go away if it finds a shorter one.
-7) This script will output a javascript file in the product_registry's data format.
-*/
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-const hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-const b64pad = '='; /* base-64 pad character. "=" for strict RFC compliance   */
-const chrsz = 8;    /* bits per input character. 8 - ASCII; 16 - Unicode      */
-
-const typeClassifications = new Map([
-  ['cdn_provider', 0], ['cdn_commercial_owner', 2], ['cdn_creative_agency', 2], ['ad_blocking', 0], ['ad_exchange', 0],
-  ['ad_server_ad_network', 0], ['ad_server_advertiser', 0], ['demand_side_platform', 0], ['vast_provider', 0],
-  ['data_management_platform', 1], ['research_analytics', 1], ['research_verification', 1],
-  ['research_brand_lift', 1]
-]);
-
-var data = fs.readFileSync('3pas.csv', 'utf8');
-var headerLine = data.split('\n', 1)[0];
-data = data.substr(headerLine.length);
-
-var columnNames = Array.from(csvUnmarshaller(headerLine)).map(v => v[0]);
-var lineObjs = [];
-
-var blacklistData = fs.readFileSync('3pas-blacklist.csv', 'utf8');
-var blacklistHeaderLine = blacklistData.split('\n', 1)[0];
-blacklistData = blacklistData.substr(blacklistHeaderLine.length);
-var blacklistColumnNames = Array.from(csvUnmarshaller(blacklistHeaderLine)).map(v => v[0]);
-var blacklistDomainColumnIndex = blacklistColumnNames.findIndex(name => name === 'domain');
-console.assert(blacklistDomainColumnIndex !== undefined, '"domain" column not found in blacklist file.');
-
-var marshaller = csvUnmarshaller(blacklistData, 2);
-var blacklistDomains = new Set();
-var colIndex = 0;
-for (var [colData, isEnding] of marshaller) {
-  // extracts just the 'domain' column from blacklist file
-  if (colIndex === blacklistDomainColumnIndex)
-    blacklistDomains.add(colData);
-  colIndex++;
-  if (isEnding)
-    colIndex = 0;
-}
-
-var marshaller = csvUnmarshaller(data, 2);
-var lineObj = {};
-var colIndex = 0;
-for (var [colData, isEnding] of marshaller) {
-  if (!(columnNames[colIndex] in lineObj))
-    lineObj[columnNames[colIndex]] = colData;
-  colIndex++;
-  if (isEnding) {
-    lineObj = {};
-    lineObjs.push(lineObj);
-    colIndex = 0;
-  }
-}
-
-// Removes blacklist items.
-lineObjs = lineObjs.filter(lineObj => !blacklistDomains.has(lineObj.domain));
-
-var map = new Map();
-for (var lineObj of lineObjs) {
-  if (lineObj.domain === null || lineObj.domain === undefined ||
-      (lineObj.status_allowed !== 'allowed' && lineObj.status_allowed !== 'disallowed'))
-    continue;
-  lineObj.domain =
-      lineObj.domain.trim().toLowerCase().replace(/[^a-z0-9_\-*.]/g, '').replace(/^www\.(?=[^.]+\.[^.]+$)/, '');
-
-  lineObj.name_legal_product = lineObj.name_legal_product.trim()
-                                   .replace(/\s\s/g, ' ')
-                                   .replace(/[\x00-\x1F]/g, '')
-                                   .replace(/&quot;/g, '"')
-                                   // The following two lines are to keep input data from currupting output data.
-                                   .replace(/","/g, '')
-                                   .replace(/},{/g, '')
-                                   .replace(/“|”/g, '"')
-                                   .replace(/,$/g, '')
-                                   .replace(/&amp;/g, '&')
-                                   // This is how csv escapes double quotes.
-                                   .replace(/""/g, '"');
-  if (!map.has(lineObj.domain))
-    map.set(lineObj.domain, lineObj);
-}
-
-lineObjs = Array.from(map.values());
-
-var map = new Map();
-for (var lineObj of lineObjs) {
-  if (!lineObj)
-    continue;
-  var domain = lineObj.domain.trim();
-  if (!domain.length)
-    continue;
-  var prefixSuffix = domain.split('*');
-  if (prefixSuffix.length > 2)
-    throw 'We do not support multiple * in domains';
-  var prefix = '';
-  var suffixDomain = '';
-  if (prefixSuffix.length === 1) {
-    suffixDomain = prefixSuffix[0];
-  } else {
-    prefix = prefixSuffix[0];
-    if (prefix === '')
-      prefix = '*';
-    suffixDomain = prefixSuffix[1];
-  }
-
-  var domainParts = suffixDomain.split('.');
-  if (domainParts.length < 2)
-    throw 'Invalid domain';
-  var baseDomain = domainParts[domainParts.length - 2] + '.' + domainParts[domainParts.length - 1];
-  while (domainParts[0] === '')
-    domainParts.shift();
-  lineObj.domain = domainParts.join('.');
-  lineObj.prefix = prefix;
-
-  var mapOfSubdomains = map.get(baseDomain);
-  if (!mapOfSubdomains) {
-    mapOfSubdomains = new Map();
-    map.set(baseDomain, mapOfSubdomains);
-  }
-
-  var prefixMap = mapOfSubdomains.get(lineObj.domain);
-  if (!prefixMap) {
-    prefixMap = new Map();
-    mapOfSubdomains.set(lineObj.domain, prefixMap);
-  }
-  if (prefixMap.has(prefix))
-    console.log('Problem with: ', domain, lineObj.domain);
-  prefixMap.set(prefix, lineObj);
-}
-
-var outputProducts = [];
-var outputObj = new Map();
-for (var [baseDomain, subdomains] of map) {
-  for (var prefixes of subdomains.values()) {
-    SKIP_ENTRY: for (var lineObj of prefixes.values()) {
-      var prefix = lineObj.prefix;
-      var wildLineObj = prefixes.get('*');
-      if (wildLineObj && prefix !== '*') {
-        if (wildLineObj.name_legal_product === lineObj.name_legal_product) {
-          // Skip entry, since wild card is there and already in table.
-          continue SKIP_ENTRY;
-        }
-      }
-      var fullSubdomain = lineObj.domain;
-      var domainParts = lineObj.domain.split('.');
-      // Ignore fist one since we are on it now.
-      var previousDomainPart = domainParts.shift();
-      var ignoreEntry = false;
-
-      while (domainParts.length > 1) {
-        var subdomain = domainParts.join('.');
-        var subdomainPrefixes = subdomains.get(subdomain);
-        if (subdomainPrefixes) {
-          for (var innerLineObj of subdomainPrefixes.values()) {
-            if (innerLineObj.prefix === '' || innerLineObj.name_legal_product !== lineObj.name_legal_product)
-              continue;
-            if (innerLineObj.prefix === '*')
-              continue SKIP_ENTRY;
-            // Per chat with 3pas team. We need to check prefix on subdomain not top level domain.
-            // ie: f*.foo.bar -> [b.f00.foo.bar, true], [f00.foo.bar, true], [f00.b.foo.bar, false]
-            if (previousDomainPart.substr(0, innerLineObj.prefix.length) === innerLineObj.prefix)
-              continue SKIP_ENTRY;
-          }
-        }
-        previousDomainPart = domainParts.shift();
-      }
-      var outputPart = outputObj.get(fullSubdomain);
-      if (!outputPart) {
-        outputPart = {hash: hex_sha1(fullSubdomain).substr(0, 16), prefixes: {}};
-        outputObj.set(fullSubdomain, outputPart);
-      }
-      outputPart.prefixes[lineObj.prefix] = registerOutputProduct(lineObj.name_legal_product, lineObj.type_vendor);
-    }
-  }
-}
-
-console.log(
-    '// Copyright 2017 The Chromium Authors. All rights reserved.\n' +
-    '// Use of this source code is governed by a BSD-style license that can be\n' +
-    '// found in the LICENSE file.\n' +
-    '// clang-format off\n' +
-    '/* eslint-disable */\n' +
-    'ProductRegistryImpl.register([');
-var data = JSON.stringify(outputProducts).replace(/","/g, '",\n  "');
-console.log('  ' + data.substring(1, data.length - 1));
-console.log('],');
-console.log('[');
-var outputObjArray = Array.from(outputObj.values());
-for (var i = 0; i < outputObjArray.length; i++) {
-  var obj = outputObjArray[i];
-  var lineEnding = (i === outputObjArray.length - 1) ? '' : ',';
-  var comments = [];
-  for (var prefix in obj.prefixes)
-    comments.push('[' + outputProducts[obj.prefixes[prefix].product] + ']');
-  console.log('  ' + JSON.stringify(obj) + lineEnding + ' // ' + comments.join(' '));
-}
-console.log(']);');
-
-
-// items.forEach(lineObj => console.log(lineObj.name_legal_product.padStart(50), lineObj.domain.padStart(30)));
-// console.log("With *: ", items.filter(v => v.domain.indexOf('*') !== -1).length);
-// console.log("Total: ", items.length);
-
-
-
-// Linear but meh.
-function registerOutputProduct(name, type) {
-  var index = outputProducts.indexOf(name);
-  var typeIndex = registerOutputType(type);
-  var outObj = {product: index};
-  if (index === -1) {
-    outputProducts.push(name);
-    outObj.product = outputProducts.length - 1;
-  }
-  if (typeIndex !== -1)
-    outObj.type = typeIndex;
-  return outObj;
-}
-
-function registerOutputType(type) {
-  var index = typeClassifications.get(type);
-  if (index === undefined)
-    return -1;
-  return index;
-}
-
-function* csvUnmarshaller(data, lineOffset) {
-  var origLen = data.length;
-  var colLength = 0;
-  var lineNo = lineOffset || 1;
-  while (data.length) {
-    var colData;
-    var match;
-    if (data[0] === '"') {
-      match = data.match(/^"((?:[^"]|"")*)"(,|\n|$)/m);
-      if (!match)
-        throw 'Bad data at line ' + lineNo + ' col: ' + colLength + ' ' + data.substr(0, 15);
-    } else if (data[0] === '\'') {
-      match = data.match(/^'((?:[^']|'')*)'(,|\n|$)/m);
-      if (!match)
-        throw 'Bad data at line ' + lineNo + ' col: ' + colLength + ' ' + data.substr(0, 15);
-    } else {
-      match = data.match(/^([^,\r\n]*)(?:,|\r?(\n)|\r?$)/);
-      if (!match)
-        throw 'Bad data at line ' + lineNo + ' col: ' + colLength + ' ' + data.substr(0, 15);
-      match[1] = match[1] === 'NULL' ? null : match[1];
-    }
-    colLength += match[0].length;
-    if (match[2] === '\n') {
-      lineNo++;
-      colLength = 0;
-    }
-    yield [match[1], match[2] === '\n'];
-    data = data.substr(match[0].length);
-  }
-}
-
-
-// All sha1 helpers from here down.
-
-
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS PUB 180-1
- * Version 2.1a Copyright Paul Johnston 2000 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s) {
-  return binb2hex(core_sha1(str2binb(s), s.length * chrsz));
-}
-function b64_sha1(s) {
-  return binb2b64(core_sha1(str2binb(s), s.length * chrsz));
-}
-function str_sha1(s) {
-  return binb2str(core_sha1(str2binb(s), s.length * chrsz));
-}
-function hex_hmac_sha1(key, data) {
-  return binb2hex(core_hmac_sha1(key, data));
-}
-function b64_hmac_sha1(key, data) {
-  return binb2b64(core_hmac_sha1(key, data));
-}
-function str_hmac_sha1(key, data) {
-  return binb2str(core_hmac_sha1(key, data));
-}
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test() {
-  return hex_sha1('abc') == 'a9993e364706816aba3e25717850c26c9cd0d89d';
-}
-
-/*
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function core_sha1(x, len) {
-  /* append padding */
-  x[len >> 5] |= 0x80 << (24 - len % 32);
-  x[((len + 64 >> 9) << 4) + 15] = len;
-
-  var w = Array(80);
-  var a = 1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d = 271733878;
-  var e = -1009589776;
-
-  for (var i = 0; i < x.length; i += 16) {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-    var olde = e;
-
-    for (var j = 0; j < 80; j++) {
-      if (j < 16)
-        w[j] = x[i + j];
-      else
-        w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
-      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
-      e = d;
-      d = c;
-      c = rol(b, 30);
-      b = a;
-      a = t;
-    }
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-    e = safe_add(e, olde);
-  }
-  return Array(a, b, c, d, e);
-}
-
-/*
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d) {
-  if (t < 20)
-    return (b & c) | ((~b) & d);
-  if (t < 40)
-    return b ^ c ^ d;
-  if (t < 60)
-    return (b & c) | (b & d) | (c & d);
-  return b ^ c ^ d;
-}
-
-/*
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t) {
-  return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
-}
-
-/*
- * Calculate the HMAC-SHA1 of a key and some data
- */
-function core_hmac_sha1(key, data) {
-  var bkey = str2binb(key);
-  if (bkey.length > 16)
-    bkey = core_sha1(bkey, key.length * chrsz);
-
-  var ipad = Array(16), opad = Array(16);
-  for (var i = 0; i < 16; i++) {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
-  return core_sha1(opad.concat(hash), 512 + 160);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y) {
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function rol(num, cnt) {
-  return (num << cnt) | (num >>> (32 - cnt));
-}
-
-/*
- * Convert an 8-bit or 16-bit string to an array of big-endian words
- * In 8-bit function, characters >255 have their hi-byte silently ignored.
- */
-function str2binb(str) {
-  var bin = Array();
-  var mask = (1 << chrsz) - 1;
-  for (var i = 0; i < str.length * chrsz; i += chrsz)
-    bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i % 32);
-  return bin;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2str(bin) {
-  var str = '';
-  var mask = (1 << chrsz) - 1;
-  for (var i = 0; i < bin.length * 32; i += chrsz)
-    str += String.fromCharCode((bin[i >> 5] >>> (32 - chrsz - i % 32)) & mask);
-  return str;
-}
-
-/*
- * Convert an array of big-endian words to a hex string.
- */
-function binb2hex(binarray) {
-  var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef';
-  var str = '';
-  for (var i = 0; i < binarray.length * 4; i++) {
-    str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
-        hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
-  }
-  return str;
-}
-
-/*
- * Convert an array of big-endian words to a base-64 string
- */
-function binb2b64(binarray) {
-  var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-  var str = '';
-  for (var i = 0; i < binarray.length * 4; i += 3) {
-    var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) |
-        (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) |
-        ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
-    for (var j = 0; j < 4; j++) {
-      if (i * 8 + j * 6 > binarray.length * 32)
-        str += b64pad;
-      else
-        str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
-    }
-  }
-  return str;
-}
diff --git a/scripts/convert_svg_images_to_png.py b/scripts/convert_svg_images_to_png.py
deleted file mode 100755
index 2f0a0a4..0000000
--- a/scripts/convert_svg_images_to_png.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os.path
-import re
-import subprocess
-import sys
-
-from build import devtools_file_hashes
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-def check_installed(app_name):
-    proc = subprocess.Popen("which %s" % app_name, stdout=subprocess.PIPE, shell=True)
-    proc.communicate()
-    if proc.returncode != 0:
-        print "This script needs \"%s\" to be installed." % app_name
-        sys.exit(1)
-
-
-check_installed("inkscape")
-
-scripts_path = os.path.dirname(os.path.abspath(__file__))
-devtools_path = os.path.dirname(scripts_path)
-devtools_frontend_path = devtools_path + "/front_end"
-images_path = devtools_frontend_path + "/Images"
-image_sources_path = images_path + "/src"
-hashes_file_name = "svg2png.hashes"
-hashes_file_path = image_sources_path + "/" + hashes_file_name
-
-file_names = os.listdir(image_sources_path)
-svg_file_paths = [image_sources_path + "/" + file_name for file_name in file_names if file_name.endswith(".svg")]
-
-svg_file_paths_to_convert = devtools_file_hashes.files_with_invalid_hashes(hashes_file_path, svg_file_paths)
-svg_file_names = [re.sub(".svg$", "", re.sub(".*/", "", file_path)) for file_path in svg_file_paths_to_convert]
-
-
-def convert_svg_to_png(svg_file_name, png_file_name, dpi):
-    svg_full_path = image_sources_path + "/" + svg_file_name + ".svg"
-    png_full_path = images_path + "/" + png_file_name + ".png"
-    convert_command = "inkscape -f %s -e %s -d %s" % (svg_full_path, png_full_path, dpi)
-    proc = subprocess.Popen(convert_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
-    return proc
-
-
-processes = {}
-for file_name in svg_file_names:
-    name = re.sub(".svg$", "", file_name)
-    name2x = name + "_2x"
-    processes[name] = convert_svg_to_png(name, name, 96)
-    processes[name2x] = convert_svg_to_png(name, name2x, 192)
-
-for file_name, proc in processes.items():
-    (convert_out, _) = proc.communicate()
-    print("Conversion of %s finished: %s" % (file_name, convert_out))
-
-devtools_file_hashes.update_file_hashes(hashes_file_path, svg_file_paths)
diff --git a/scripts/dependency_preprocessor.py b/scripts/dependency_preprocessor.py
deleted file mode 100644
index 6b0e558..0000000
--- a/scripts/dependency_preprocessor.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-This ensures that each front-end module does not accidentally rely on a module
-that isn't listed as a transitive dependency in the module.json.
-
-How this works:
-1. Renames any potential undeclared namespace usage across the entire front-end code
-(e.g. identifiers, strings) into e.g. "$$UndeclaredDependency_SDK$$.Foo".
-2. Closure Compiler catches any illegal usage and safely ignores coincidental
-usages (e.g. "Console.Foo" in a string).
-"""
-
-import codecs
-import multiprocessing
-from os import path
-import re
-import shutil
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-special_case_namespaces_path = path.join(path.dirname(path.abspath(__file__)), 'special_case_namespaces.json')
-
-
-class DependencyPreprocessor(object):
-
-    def __init__(self, descriptors, temp_frontend_path, devtools_frontend_path):
-        self.descriptors = descriptors
-        self.temp_frontend_path = temp_frontend_path
-        self.module_descriptors = descriptors.modules
-        self.modules = set(self.descriptors.sorted_modules())
-        shutil.copytree(devtools_frontend_path, self.temp_frontend_path)
-        with open(special_case_namespaces_path) as json_file:
-            self._special_case_namespaces = json.load(json_file)
-
-    def enforce_dependencies(self):
-        arg_list = []
-        for module in self.modules:
-            dependencies = set(self.descriptors.sorted_dependencies_closure(module))
-            excluded_modules = self.modules - {module} - dependencies
-            excluded_namespaces = [self._map_module_to_namespace(m) for m in excluded_modules]
-            file_paths = [
-                path.join(self.temp_frontend_path, module, file_name)
-                for file_name in self.descriptors.module_compiled_files(module)
-            ]
-            arg = {
-                'excluded_namespaces': excluded_namespaces,
-                'file_paths': file_paths,
-            }
-            arg_list.append(arg)
-        parallelize(poison_module, arg_list)
-
-    def _map_module_to_namespace(self, module):
-        return self._special_case_namespaces.get(module, self._to_camel_case(module))
-
-    def _to_camel_case(self, snake_string):
-        components = snake_string.split('_')
-        return ''.join(x.title() for x in components)
-
-
-def poison_module(target):
-    excluded_namespaces = target['excluded_namespaces']
-    file_paths = target['file_paths']
-    for file_path in file_paths:
-        with codecs.open(file_path, 'r', 'utf-8') as file:
-            file_contents = file.read()
-        file_contents = poison_contents_for_namespaces(file_contents, excluded_namespaces)
-        with codecs.open(file_path, 'w', 'utf-8') as file:
-            file.write(file_contents)
-
-
-def poison_contents_for_namespaces(file_contents, namespaces):
-    # Technically, should be [^.]\s*\b + NAMESPACES + \b\s*[^:]
-    # but we rely on clang-format to format like this:
-    #   SomeModule
-    #     .Console
-    regex = r'([^.]\b)(' + '|'.join(namespaces) + r')(\b[^:])'
-    replace = r'\1$$UndeclaredDependency_\2$$\3'
-    return re.sub(regex, replace, file_contents)
-
-
-def parallelize(fn, arg_list):
-    number_of_processes = min(multiprocessing.cpu_count(), 8)
-    pool = multiprocessing.Pool(number_of_processes)
-    pool.map(fn, arg_list)
-    pool.close()
-    pool.join()
diff --git a/scripts/devtools_run/devtools_run_cli b/scripts/devtools_run/devtools_run_cli
deleted file mode 100755
index 4b50ead..0000000
--- a/scripts/devtools_run/devtools_run_cli
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env node
-
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var childProcess = require('child_process');
-var fs = require('fs');
-var path = require('path');
-var shell = require('child_process').execSync;
-
-var repoRootPath;
-try {
-  repoRootPath = shellOutput('git rev-parse --show-toplevel');
-} catch (error) {
-  console.log('ERROR: cannot use dtrun outside of chromium repo');
-  process.exit(1);
-}
-
-var devtoolsPath = path.join(repoRootPath, 'third_party', 'WebKit', 'Source', 'devtools');
-
-if (!isDir(devtoolsPath)) {
-  console.log('ERROR: cannot use dtrun outside of chromium repo');
-  process.exit(1);
-}
-
-var npmPath = shellOutput('which npm');
-var args = ['run'];
-if (process.argv.length > 2) {
-  args.push(process.argv[2]);
-  args.push('--');
-  args = args.concat(process.argv.slice(3));
-}
-var child = childProcess.spawn(npmPath, args, {
-  cwd: devtoolsPath,
-  stdio: 'inherit',
-});
-
-function shellOutput(command) {
-  return shell(command).toString().trim();
-}
-
-function isDir(path) {
-  try {
-    return fs.statSync(path).isDirectory();
-  } catch (error) {
-    return false;
-  }
-}
\ No newline at end of file
diff --git a/scripts/devtools_run/package.json b/scripts/devtools_run/package.json
deleted file mode 100644
index a1e4563..0000000
--- a/scripts/devtools_run/package.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "name": "devtools-run",
-  "description": "cli helper for using devtools npm commands anywhere in a chromium repo",
-  "version": "0.1.0",
-  "author": "The Chromium Authors",
-  "license": "SEE LICENSE IN https://chromium.googlesource.com/chromium/src/+/master/LICENSE",
-  "bugs": {
-    "url": "https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component:Platform%3EDevTools%20&sort=-opened&colspec=ID%20Stars%20Owner%20Summary%20Modified%20Opened"
-  },
-  "bin": {
-    "dtrun": "./devtools_run_cli"
-  }
-}
diff --git a/scripts/extract_module/extract_module.js b/scripts/extract_module/extract_module.js
deleted file mode 100644
index eddfff1..0000000
--- a/scripts/extract_module/extract_module.js
+++ /dev/null
@@ -1,741 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-'use strict';
-const fs = require('fs');
-const path = require('path');
-
-const utils = require('../utils');
-
-const FRONTEND_PATH = path.resolve(__dirname, '..', '..', 'front_end');
-const BUILD_GN_PATH = path.resolve(__dirname, '..', '..', 'BUILD.gn');
-const SPECIAL_CASE_NAMESPACES_PATH = path.resolve(__dirname, '..', 'special_case_namespaces.json');
-
-/*
- * This is used to extract a new module from an existing module by:
- * - Moving selected files into new modules (including relevant
- * css files)
- * - Renaming all identifiers to the new namespace
- * - Updating the BUILD.gn and module.json files (including extensions)
- * ==========================================
- * START EDITING HERE - TRANSFORMATION INPUTS
- * ==========================================
- */
-
-const APPLICATION_DESCRIPTORS = [
-  'devtools_app.json',
-  'js_app.json',
-  'shell.json',
-  'worker_app.json',
-  'inspector.json',
-  'toolbox.json',
-  'integration_test_runner.json',
-  'formatter_worker.json',
-  'heap_snapshot_worker.json',
-];
-
-/*
- * If the transformation removes all the files of a module:
- * ['text_editor']
- */
-const MODULES_TO_REMOVE = ['profiler_test_runner', 'heap_snapshot_test_runner'];
-
-/**
- * If moving to a new module:
- * {file: 'common/Text.js', new: 'a_new_module'}
- *
- * If moving to an existing module:
- * {file: 'ui/SomeFile.js', existing: 'common'}
- */
-const JS_FILES_MAPPING = [
-  // {file: 'heap_snapshot_test_runner/HeapSnapshotTestRunner.js', new: 'heap_profiler_test_runner'},
-  // {file: 'profiler_test_runner/ProfilerTestRunner.js', new: 'cpu_profiler_test_runner'},
-  {file: 'network_log/HAREntry.js', existing: 'browser_sdk'},
-];
-
-/**
- * List all new modules here:
- * mobile_throttling: {
- *   dependencies: ['sdk'],
- *   dependents: ['console'],
- *   applications: ['inspector.json'],
- *   autostart: false,
- * }
- */
-const MODULE_MAPPING = {
-  // heap_profiler_test_runner: {
-  //   dependencies: ['heap_snapshot_worker', 'test_runner'],
-  //   dependents: [],
-  //   applications: ['integration_test_runner.json'],
-  //   autostart: false,
-  // },
-  // cpu_profiler_test_runner: {
-  //   dependencies: ['profiler', 'test_runner'],
-  //   dependents: [],
-  //   applications: ['integration_test_runner.json'],
-  //   autostart: false,
-  // },
-};
-
-/**
- * If an existing module will have a new dependency on an existing module:
- * console: ['new_dependency']
- */
-const NEW_DEPENDENCIES_BY_EXISTING_MODULES = {
-    // resources: ['components'],
-};
-
-/**
- * If an existing module will no longer have a dependency on a module:
- * console: ['former_dependency']
- */
-const REMOVE_DEPENDENCIES_BY_EXISTING_MODULES = {
-    // console_test_runner: ['main']
-};
-
-/*
- * ==========================================
- * STOP EDITING HERE
- * ==========================================
- */
-
-const DEPENDENCIES_BY_MODULE = Object.keys(MODULE_MAPPING).reduce((acc, module) => {
-  acc[module] = MODULE_MAPPING[module].dependencies;
-  return acc;
-}, {});
-
-const APPLICATIONS_BY_MODULE = Object.keys(MODULE_MAPPING).reduce((acc, module) => {
-  acc[module] = MODULE_MAPPING[module].applications;
-  return acc;
-}, {});
-
-const DEPENDENTS_BY_MODULE = Object.keys(MODULE_MAPPING).reduce((acc, module) => {
-  acc[module] = MODULE_MAPPING[module].dependents;
-  return acc;
-}, {});
-
-function extractModule() {
-  const modules = new Set();
-  for (let fileObj of JS_FILES_MAPPING) {
-    let moduleName = fileObj.file.split('/')[0];
-    modules.add(moduleName);
-  }
-  const newModuleSet = JS_FILES_MAPPING.reduce((acc, file) => file.new ? acc.add(file.new) : acc, new Set());
-  const targetToOriginalFilesMap = JS_FILES_MAPPING.reduce((acc, f) => {
-    let components = f.file.split('/');
-    components[0] = f.new || f.existing;
-    acc.set(components.join('/'), f.file);
-    return acc;
-  }, new Map());
-
-  const cssFilesMapping = findCSSFiles();
-  console.log('cssFilesMapping', cssFilesMapping);
-  const identifiersByFile = calculateIdentifiers();
-  const identifierMap = mapIdentifiers(identifiersByFile, cssFilesMapping);
-  console.log('identifierMap', identifierMap);
-  const extensionMap = removeFromExistingModuleDescriptors(modules, identifierMap, cssFilesMapping);
-
-  // Find out which files are moving extensions
-  for (let e of extensionMap.keys()) {
-    for (let [f, identifiers] of identifiersByFile) {
-      if (identifiers.includes(e))
-        console.log(`extension: ${e} in file: ${f}`);
-    }
-  }
-
-  moveFiles(cssFilesMapping);
-  createNewModuleDescriptors(extensionMap, cssFilesMapping, identifiersByFile, targetToOriginalFilesMap);
-  updateExistingModuleDescriptors(extensionMap, cssFilesMapping, identifiersByFile, targetToOriginalFilesMap);
-  addDependenciesToDescriptors();
-  renameIdentifiers(identifierMap);
-  updateBuildGNFile(cssFilesMapping, newModuleSet);
-  for (let descriptor of APPLICATION_DESCRIPTORS)
-    updateApplicationDescriptor(descriptor, newModuleSet);
-
-  for (let m of MODULES_TO_REMOVE)
-    utils.removeRecursive(path.resolve(FRONTEND_PATH, m));
-}
-
-String.prototype.replaceAll = function(search, replacement) {
-  let target = this;
-  return target.replace(new RegExp('\\b' + search + '\\b', 'g'), replacement);
-};
-
-Set.prototype.union = function(setB) {
-  let union = new Set(this);
-  for (let elem of setB)
-    union.add(elem);
-
-  return union;
-};
-
-function mapModuleToNamespace(module) {
-  const specialCases = require(SPECIAL_CASE_NAMESPACES_PATH);
-  return specialCases[module] || toCamelCase(module);
-
-  function toCamelCase(module) {
-    return module.split('_').map(a => a.substring(0, 1).toUpperCase() + a.substring(1)).join('');
-  }
-}
-
-function findCSSFiles() {
-  let cssFilesMapping = new Map();
-  for (let fileObj of JS_FILES_MAPPING)
-    cssFilesMapping.set(fileObj.file, scrapeCSSFile(fileObj.file));
-
-
-  function scrapeCSSFile(filePath) {
-    let cssFiles = new Set();
-    const fullPath = path.resolve(FRONTEND_PATH, filePath);
-    let content = fs.readFileSync(fullPath).toString();
-    let lines = content.split('\n');
-    for (let line of lines) {
-      let match = line.match(/'(.+\.css)'/);
-      if (!match)
-        continue;
-      let matchPath = match[1];
-      cssFiles.add(path.basename(path.resolve(FRONTEND_PATH, matchPath)));
-    }
-    return cssFiles;
-  }
-
-  return cssFilesMapping;
-}
-
-function calculateIdentifiers() {
-  const identifiersByFile = new Map();
-  for (let fileObj of JS_FILES_MAPPING) {
-    const fullPath = path.resolve(FRONTEND_PATH, fileObj.file);
-    let content = fs.readFileSync(fullPath).toString();
-    identifiersByFile.set(fileObj.file, scrapeIdentifiers(content, fileObj));
-  }
-  return identifiersByFile;
-
-  function scrapeIdentifiers(content, fileObj) {
-    let identifiers = [];
-    let lines = content.split('\n');
-    for (let line of lines) {
-      let match =
-          line.match(new RegExp(`^\\s*([a-z_A-Z0-9\.]+)\\s=`)) || line.match(new RegExp(`^\\s*([a-z_A-Z0-9\.]+);`));
-      if (!match)
-        continue;
-      let name = match[1];
-
-      var currentModule = fileObj.file.split('/')[0];
-      if (name.split('.')[0] !== mapModuleToNamespace(currentModule)) {
-        console.log(`POSSIBLE ISSUE: identifier: ${name} found in ${currentModule}`);
-        // one-off
-        if (name.includes('UI.')) {
-          console.log(`including ${name} anyways`);
-          identifiers.push(name);
-        }
-      } else {
-        identifiers.push(name);
-      }
-    }
-    return identifiers;
-  }
-}
-
-function moveFiles(cssFilesMapping) {
-  for (let fileObj of JS_FILES_MAPPING) {
-    let sourceFilePath = path.resolve(FRONTEND_PATH, fileObj.file);
-    let targetFilePath = getMappedFilePath(fileObj);
-    let moduleDir = path.resolve(targetFilePath, '..');
-    if (!fs.existsSync(moduleDir))
-      fs.mkdirSync(moduleDir);
-
-    move(sourceFilePath, targetFilePath);
-    if (cssFilesMapping.has(fileObj.file)) {
-      cssFilesMapping.get(fileObj.file).forEach((file) => {
-        let module = fileObj.new || fileObj.existing;
-        move(path.resolve(FRONTEND_PATH, fileObj.file.split('/')[0], file), path.resolve(FRONTEND_PATH, module, file));
-      });
-    }
-  }
-
-  function move(sourceFilePath, targetFilePath) {
-    try {
-      fs.writeFileSync(targetFilePath, fs.readFileSync(sourceFilePath));
-      fs.unlinkSync(sourceFilePath);
-    } catch (err) {
-      console.log(`error moving ${sourceFilePath} -> ${targetFilePath}`);
-    }
-  }
-
-  function getMappedFilePath(fileObj) {
-    let components = fileObj.file.split('/');
-    components[0] = fileObj.existing || fileObj.new;
-    return path.resolve(FRONTEND_PATH, components.join('/'));
-  }
-}
-
-function updateBuildGNFile(cssFilesMapping, newModuleSet) {
-  let content = fs.readFileSync(BUILD_GN_PATH).toString();
-  let newSourcesToAdd = [];
-  let partialPathMapping = calculatePartialPathMapping();
-  for (let module of MODULES_TO_REMOVE) {
-    partialPathMapping.set(`"front_end/${module}/module.json",\n`, '');
-    partialPathMapping.set(`"$resources_out_dir/${module}/${module}_module.js",\n`, '');
-  }
-  const newNonAutostartModules = [...newModuleSet]
-                                     .filter(module => !MODULE_MAPPING[module].autostart)
-                                     .map(module => `"$resources_out_dir/${module}/${module}_module.js",`);
-
-  let newContent = addContentToLinesInSortedOrder({
-    content,
-    startLine: 'generated_non_autostart_non_remote_modules = [',
-    endLine: ']',
-    linesToInsert: newNonAutostartModules,
-  });
-
-  for (let pair of partialPathMapping.entries())
-    newContent = newContent.replace(pair[0], pair[1]);
-
-  newContent = addContentToLinesInSortedOrder({
-    content: newContent,
-    startLine: 'all_devtools_files = [',
-    endLine: ']',
-    linesToInsert: newSourcesToAdd.concat([...newModuleSet].map(module => `"front_end/${module}/module.json",`)),
-  });
-
-  fs.writeFileSync(BUILD_GN_PATH, newContent);
-
-  function calculatePartialPathMapping() {
-    let partialPathMapping = new Map();
-    for (let fileObj of JS_FILES_MAPPING) {
-      let components = fileObj.file.split('/');
-      let sourceModule = components[0];
-      let targetModule = fileObj.existing || fileObj.new;
-      components[0] = targetModule;
-      partialPathMapping.set(`"front_end/${fileObj.file}",\n`, '');
-      newSourcesToAdd.push(`"front_end/${components.join('/')}",`);
-      if (cssFilesMapping.has(fileObj.file)) {
-        for (let cssFile of cssFilesMapping.get(fileObj.file)) {
-          partialPathMapping.set(`"front_end/${sourceModule}/${cssFile}",\n`, '');
-          newSourcesToAdd.push(`"front_end/${targetModule}/${cssFile}",`);
-        }
-      }
-    }
-    return partialPathMapping;
-  }
-
-  function top(array) {
-    return array[array.length - 1];
-  }
-
-  function addContentToLinesInSortedOrder({content, startLine, endLine, linesToInsert}) {
-    if (linesToInsert.length === 0)
-      return content;
-    let lines = content.split('\n');
-    let seenStartLine = false;
-    let contentStack = linesToInsert.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).reverse();
-    for (var i = 0; i < lines.length; i++) {
-      let line = lines[i].trim();
-      let nextLine = lines[i + 1].trim();
-      if (line === startLine)
-        seenStartLine = true;
-
-      if (line === endLine && seenStartLine)
-        break;
-
-      if (!seenStartLine)
-        continue;
-
-      const nextContent = top(contentStack) ? top(contentStack).toLowerCase() : '';
-      if ((line === startLine || nextContent >= line.toLowerCase()) &&
-          (nextLine === endLine || nextContent <= nextLine.toLowerCase()))
-        lines.splice(i + 1, 0, contentStack.pop());
-    }
-    if (contentStack.length)
-      lines.splice(i, 0, ...contentStack);
-    return lines.join('\n');
-  }
-}
-
-function mapIdentifiers(identifiersByFile, cssFilesMapping) {
-  const filesToTargetModule = new Map();
-  for (let fileObj of JS_FILES_MAPPING)
-    filesToTargetModule.set(fileObj.file, fileObj.existing || fileObj.new);
-
-
-  const map = new Map();
-  for (let [file, identifiers] of identifiersByFile) {
-    let targetModule = filesToTargetModule.get(file);
-    for (let identifier of identifiers) {
-      let components = identifier.split('.');
-      components[0] = mapModuleToNamespace(targetModule);
-      let newIdentifier = components.join('.');
-      map.set(identifier, newIdentifier);
-    }
-  }
-  for (let [jsFile, cssFiles] of cssFilesMapping) {
-    let fileObj = JS_FILES_MAPPING.filter(f => f.file === jsFile)[0];
-    let sourceModule = fileObj.file.split('/')[0];
-    let targetModule = fileObj.existing || fileObj.new;
-    for (let cssFile of cssFiles) {
-      let key = `${sourceModule}/${cssFile}`;
-      let value = `${targetModule}/${cssFile}`;
-      map.set(key, value);
-    }
-  }
-  return map;
-}
-
-function renameIdentifiers(identifierMap) {
-  walkSync('front_end', write, true);
-
-  walkSync('../../LayoutTests/http/tests/devtools', write, false);
-  walkSync('../../LayoutTests/http/tests/inspector-protocol', write, false);
-  walkSync('../../LayoutTests/inspector-protocol', write, false);
-
-  function walkSync(currentDirPath, process, json) {
-    fs.readdirSync(currentDirPath).forEach(function(name) {
-      let filePath = path.join(currentDirPath, name);
-      let stat = fs.statSync(filePath);
-      if (stat.isFile() && (filePath.endsWith('.js') || filePath.endsWith('.html') || filePath.endsWith('.xhtml') ||
-                            filePath.endsWith('-expected.txt') || (json && filePath.endsWith('.json')))) {
-        if (filePath.includes('ExtensionAPI.js'))
-          return;
-        if (filePath.includes('externs.js'))
-          return;
-        if (filePath.includes('eslint') || filePath.includes('lighthouse-background.js') || filePath.includes('/cm/') ||
-            filePath.includes('/xterm.js/') || filePath.includes('/acorn/'))
-          return;
-        if (filePath.includes('/cm_modes/') && !filePath.includes('DefaultCodeMirror') &&
-            !filePath.includes('module.json'))
-          return;
-        process(filePath);
-      } else if (stat.isDirectory()) {
-        walkSync(filePath, process, json);
-      }
-    });
-  }
-
-  function write(filePath) {
-    let content = fs.readFileSync(filePath).toString();
-    let newContent = content;
-    for (let key of identifierMap.keys()) {
-      let originalIdentifier = key;
-      let newIdentifier = identifierMap.get(key);
-      newContent = newContent.replaceAll(originalIdentifier, newIdentifier);
-    }
-
-    if (content !== newContent)
-      fs.writeFileSync(filePath, newContent);
-  }
-}
-
-function removeFromExistingModuleDescriptors(modules, identifierMap, cssFilesMapping) {
-  let extensionMap = new Map();
-  let moduleFileMap = new Map();
-
-  for (let fileObj of JS_FILES_MAPPING) {
-    let components = fileObj.file.split('/');
-    let module = components[0];
-    let fileName = components[1];
-
-    if (!moduleFileMap.get(module))
-      moduleFileMap.set(module, []);
-
-    moduleFileMap.set(module, moduleFileMap.get(module).concat(fileName));
-  }
-
-  for (let module of modules) {
-    let moduleJSONPath = path.resolve(FRONTEND_PATH, module, 'module.json');
-    let content = fs.readFileSync(moduleJSONPath).toString();
-    let moduleObj = parseJSON(content);
-    let removedScripts = removeScripts(moduleObj, module);
-    removeResources(moduleObj, removedScripts);
-    removeExtensions(moduleObj);
-    fs.writeFileSync(moduleJSONPath, stringifyJSON(moduleObj));
-  }
-
-  return extensionMap;
-
-  function removeScripts(moduleObj, module) {
-    let remainingScripts = [];
-    let removedScripts = [];
-    let moduleFiles = moduleFileMap.get(module);
-    for (let script of moduleObj.scripts) {
-      if (!moduleFiles.includes(script))
-        remainingScripts.push(script);
-      else
-        removedScripts.push(module + '/' + script);
-    }
-    moduleObj.scripts = remainingScripts;
-    return removedScripts;
-  }
-
-  function removeResources(moduleObj, removedScripts) {
-    if (!moduleObj.resources)
-      return;
-    let remainingResources = [];
-    let removedResources = new Set();
-    for (let script of removedScripts)
-      removedResources = removedResources.union(cssFilesMapping.get(script));
-
-
-    for (let resource of moduleObj.resources) {
-      if (!removedResources.has(resource))
-        remainingResources.push(resource);
-    }
-    moduleObj.resources = remainingResources;
-  }
-
-  function removeExtensions(moduleObj) {
-    if (!moduleObj.extensions)
-      return;
-    let remainingExtensions = [];
-    for (let extension of moduleObj.extensions) {
-      if (!objectIncludesIdentifier(extension)) {
-        remainingExtensions.push(extension);
-      } else {
-        if (extensionMap.has(objectIncludesIdentifier(extension))) {
-          let existingExtensions = extensionMap.get(objectIncludesIdentifier(extension));
-          extensionMap.set(objectIncludesIdentifier(extension), existingExtensions.concat(extension));
-        } else {
-          extensionMap.set(objectIncludesIdentifier(extension), [extension]);
-        }
-      }
-    }
-    moduleObj.extensions = remainingExtensions;
-  }
-
-  function objectIncludesIdentifier(object) {
-    for (let key in object) {
-      let value = object[key];
-      if (identifierMap.has(value))
-        return value;
-    }
-    return false;
-  }
-}
-
-function createNewModuleDescriptors(extensionMap, cssFilesMapping, identifiersByFile, targetToOriginalFilesMap) {
-  let filesByNewModule = getFilesByNewModule();
-
-  for (let module of filesByNewModule.keys()) {
-    let moduleObj = {};
-
-    let scripts = getModuleScripts(module);
-    let extensions = getModuleExtensions(scripts, module);
-    if (extensions.length)
-      moduleObj.extensions = extensions;
-
-    moduleObj.dependencies = DEPENDENCIES_BY_MODULE[module];
-
-    moduleObj.scripts = scripts;
-
-    let resources = getModuleResources(moduleObj.scripts, module);
-    if (resources.length)
-      moduleObj.resources = resources;
-
-    let moduleJSONPath = path.resolve(FRONTEND_PATH, module, 'module.json');
-    fs.writeFileSync(moduleJSONPath, stringifyJSON(moduleObj));
-  }
-
-  function getFilesByNewModule() {
-    let filesByNewModule = new Map();
-    for (let fileObj of JS_FILES_MAPPING) {
-      if (!fileObj.new)
-        continue;
-      if (!filesByNewModule.has(fileObj.new))
-        filesByNewModule.set(fileObj.new, []);
-
-      filesByNewModule.set(fileObj.new, filesByNewModule.get(fileObj.new).concat([fileObj.file]));
-    }
-    return filesByNewModule;
-  }
-
-  function getModuleScripts(module) {
-    return filesByNewModule.get(module).map((file) => file.split('/')[1]);
-  }
-
-  function getModuleResources(scripts, module) {
-    let resources = [];
-    scripts.map(script => module + '/' + script).forEach((script) => {
-      script = targetToOriginalFilesMap.get(script);
-      if (!cssFilesMapping.has(script))
-        return;
-
-      resources = resources.concat([...cssFilesMapping.get(script)]);
-    });
-    return resources;
-  }
-
-  function getModuleExtensions(scripts, module) {
-    let extensions = [];
-    let identifiers =
-        scripts.map(script => module + '/' + script)
-            .reduce((acc, file) => acc.concat(identifiersByFile.get(targetToOriginalFilesMap.get(file))), []);
-    for (let identifier of identifiers) {
-      if (extensionMap.has(identifier))
-        extensions = extensions.concat(extensionMap.get(identifier));
-    }
-    return extensions;
-  }
-}
-
-function calculateFilesByModuleType(type) {
-  let filesByNewModule = new Map();
-  for (let fileObj of JS_FILES_MAPPING) {
-    if (!fileObj[type])
-      continue;
-    if (!filesByNewModule.has(fileObj[type]))
-      filesByNewModule.set(fileObj[type], []);
-
-    filesByNewModule.set(fileObj[type], filesByNewModule.get(fileObj[type]).concat([fileObj.file]));
-  }
-  return filesByNewModule;
-}
-
-function updateExistingModuleDescriptors(extensionMap, cssFilesMapping, identifiersByFile, targetToOriginalFilesMap) {
-  let filesByExistingModule = calculateFilesByModuleType('existing');
-  for (let module of filesByExistingModule.keys()) {
-    let moduleJSONPath = path.resolve(FRONTEND_PATH, module, 'module.json');
-    let content = fs.readFileSync(moduleJSONPath).toString();
-    let moduleObj = parseJSON(content);
-
-    let scripts = getModuleScripts(module);
-    let existingExtensions = moduleObj.extensions || [];
-    let extensions = existingExtensions.concat(getModuleExtensions(scripts, module));
-    if (extensions.length)
-      moduleObj.extensions = extensions;
-
-    moduleObj.scripts = moduleObj.scripts.concat(scripts);
-
-    let existingResources = moduleObj.resources || [];
-    let resources = existingResources.concat(getModuleResources(scripts, module));
-    if (resources.length)
-      moduleObj.resources = resources;
-
-    fs.writeFileSync(moduleJSONPath, stringifyJSON(moduleObj));
-  }
-
-
-  function getModuleScripts(module) {
-    return filesByExistingModule.get(module).map((file) => file.split('/')[1]);
-  }
-
-  function getModuleResources(scripts, module) {
-    let resources = [];
-    scripts.map(script => module + '/' + script).forEach((script) => {
-      script = targetToOriginalFilesMap.get(script);
-      if (!cssFilesMapping.has(script))
-        return;
-
-      resources = resources.concat([...cssFilesMapping.get(script)]);
-    });
-    return resources;
-  }
-
-  function getModuleExtensions(scripts, module) {
-    let extensions = [];
-    let identifiers =
-        scripts.map(script => module + '/' + script)
-            .reduce((acc, file) => acc.concat(identifiersByFile.get(targetToOriginalFilesMap.get(file))), []);
-    for (let identifier of identifiers) {
-      if (extensionMap.has(identifier))
-        extensions = extensions.concat(extensionMap.get(identifier));
-    }
-    return extensions;
-  }
-}
-
-function addDependenciesToDescriptors() {
-  for (let module of getModules()) {
-    let moduleJSONPath = path.resolve(FRONTEND_PATH, module, 'module.json');
-    let content = fs.readFileSync(moduleJSONPath).toString();
-    let moduleObj = parseJSON(content);
-
-    let existingDependencies = moduleObj.dependencies || [];
-    let dependencies =
-        existingDependencies.concat(getModuleDependencies(module))
-            .filter((depModule) => !MODULES_TO_REMOVE.includes(depModule))
-            .filter((depModule) => !(REMOVE_DEPENDENCIES_BY_EXISTING_MODULES[module] || []).includes(depModule));
-    let newDependenciesForExistingModule = NEW_DEPENDENCIES_BY_EXISTING_MODULES[module];
-    if (newDependenciesForExistingModule)
-      dependencies = dependencies.concat(newDependenciesForExistingModule);
-    if (dependencies.length)
-      moduleObj.dependencies = dependencies;
-    let newStringified = stringifyJSON(moduleObj);
-    if (stringifyJSON(moduleObj) !== stringifyJSON(parseJSON(content)))
-      fs.writeFileSync(moduleJSONPath, newStringified);
-  }
-
-  function getModuleDependencies(existingModule) {
-    let newDeps = [];
-    for (let newModule in DEPENDENTS_BY_MODULE) {
-      let dependents = DEPENDENTS_BY_MODULE[newModule];
-      if (dependents.includes(existingModule))
-        newDeps.push(newModule);
-    }
-    return newDeps;
-  }
-}
-
-function updateApplicationDescriptor(descriptorFileName, newModuleSet) {
-  let descriptorPath = path.join(FRONTEND_PATH, descriptorFileName);
-  let newModules = [...newModuleSet].filter(m => APPLICATIONS_BY_MODULE[m].includes(descriptorFileName));
-  if (newModules.length === 0)
-    return;
-  let includeNewModules = (acc, line) => {
-    if (line.includes('{') && line.endsWith('}')) {
-      line += ',';
-      acc.push(line);
-      return acc.concat(newModules.map((m, i) => {
-        // Need spacing to preserve indentation
-        let string;
-        if (MODULE_MAPPING[m].autostart)
-          string = `        { "name": "${m}", "type": "autostart" }`;
-        else
-          string = `        { "name": "${m}" }`;
-        if (i !== newModules.length - 1)
-          string += ',';
-        return string;
-      }));
-    }
-    return acc.concat([line]);
-  };
-  let removeModules = (acc, line) => MODULES_TO_REMOVE.every(m => !line.includes(m)) ? acc.concat([line]) : acc;
-  let lines =
-      fs.readFileSync(descriptorPath).toString().split('\n').reduce(includeNewModules, []).reduce(removeModules, []);
-  fs.writeFileSync(descriptorPath, lines.join('\n'));
-}
-
-function getModules() {
-  return fs.readdirSync(FRONTEND_PATH).filter(function(file) {
-    return fs.statSync(path.join(FRONTEND_PATH, file)).isDirectory() &&
-        utils.isFile(path.join(FRONTEND_PATH, file, 'module.json'));
-  });
-}
-
-function parseJSON(string) {
-  return JSON.parse(string);
-}
-
-function stringifyJSON(obj) {
-  return unicodeEscape(JSON.stringify(obj, null, 4) + '\n');
-}
-
-// http://stackoverflow.com/questions/7499473/need-to-escape-non-ascii-characters-in-javascript
-function unicodeEscape(string) {
-  function padWithLeadingZeros(string) {
-    return new Array(5 - string.length).join('0') + string;
-  }
-
-  function unicodeCharEscape(charCode) {
-    return '\\u' + padWithLeadingZeros(charCode.toString(16));
-  }
-
-  return string.split('')
-      .map(function(char) {
-        var charCode = char.charCodeAt(0);
-        return charCode > 127 ? unicodeCharEscape(charCode) : char;
-      })
-      .join('');
-}
-
-if (require.main === module)
-  extractModule();
diff --git a/scripts/hosted_mode/server.js b/scripts/hosted_mode/server.js
deleted file mode 100644
index 4303c26..0000000
--- a/scripts/hosted_mode/server.js
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-var fs = require('fs');
-var http = require('http');
-var path = require('path');
-var parseURL = require('url').parse;
-
-var utils = require('../utils');
-
-const remoteDebuggingPort = parseInt(process.env.REMOTE_DEBUGGING_PORT, 10) || 9222;
-const serverPort = parseInt(process.env.PORT, 10) || 8090;
-const localProtocolPath = process.env.LOCAL_PROTOCOL_PATH;
-const devtoolsFolder = path.resolve(path.join(__dirname, '../..'));
-
-http.createServer(requestHandler).listen(serverPort);
-console.log(`Started hosted mode server at http://localhost:${serverPort}\n`);
-console.log('For info on using the hosted mode server, see our contributing docs:');
-console.log('https://bit.ly/devtools-contribution-guide');
-console.log('Tip: Look for the \'Development server options\' section\n');
-
-function requestHandler(request, response) {
-  var filePath = parseURL(request.url).pathname;
-  if (filePath === '/') {
-    var landingURL = `http://localhost:${remoteDebuggingPort}#custom=true&experiments=true`;
-    sendResponse(200, `<html>Please go to <a href="${landingURL}">${landingURL}</a></html>`);
-    return;
-  }
-
-  var proxiedFile = proxy(filePath, sendResponse);
-  if (proxiedFile) {
-    proxiedFile.then(data => sendResponse(200, data)).catch(handleProxyError);
-    return;
-  }
-
-  function handleProxyError(err) {
-    console.log(`Error serving the file ${filePath}:`, err);
-    console.log(`Make sure you opened Chrome with the flag "--remote-debugging-port=${remoteDebuggingPort}"`);
-    sendResponse(500, '500 - Internal Server Error');
-  }
-
-  var absoluteFilePath = path.join(process.cwd(), filePath);
-  if (!path.resolve(absoluteFilePath).startsWith(devtoolsFolder)) {
-    console.log(`File requested is outside of devtools folder: ${devtoolsFolder}`);
-    sendResponse(403, `403 - Access denied. File requested is outside of devtools folder: ${devtoolsFolder}`);
-    return;
-  }
-
-  fs.exists(absoluteFilePath, fsExistsCallback);
-
-  function fsExistsCallback(fileExists) {
-    if (!fileExists) {
-      console.log(`Cannot find file ${absoluteFilePath}`);
-      sendResponse(404, '404 - File not found');
-      return;
-    }
-    fs.readFile(absoluteFilePath, 'binary', readFileCallback);
-  }
-
-  function readFileCallback(err, file) {
-    if (err) {
-      console.log(`Unable to read local file ${absoluteFilePath}:`, err);
-      sendResponse(500, '500 - Internal Server Error');
-      return;
-    }
-    sendResponse(200, file);
-  }
-
-  function sendResponse(statusCode, data) {
-    response.writeHead(statusCode);
-    response.write(data, 'binary');
-    response.end();
-  }
-}
-
-var proxyFilePathToURL = {
-  '/front_end/SupportedCSSProperties.js': cloudURL.bind(null, 'SupportedCSSProperties.js'),
-  '/front_end/InspectorBackendCommands.js': cloudURL.bind(null, 'InspectorBackendCommands.js'),
-  '/favicon.ico': () => 'https://chrome-devtools-frontend.appspot.com/favicon.ico'
-};
-
-function cloudURL(path, commitHash) {
-  return `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitHash}/${path}`;
-}
-
-var proxyFileCache = new Map();
-
-function proxy(filePath) {
-  if (!(filePath in proxyFilePathToURL))
-    return null;
-  if (localProtocolPath && filePath === '/front_end/InspectorBackendCommands.js')
-    return serveLocalProtocolFile();
-  if (process.env.CHROMIUM_COMMIT)
-    return onProxyFileURL(proxyFilePathToURL[filePath](process.env.CHROMIUM_COMMIT));
-  return utils.fetch(`http://localhost:${remoteDebuggingPort}/json/version`)
-      .then(onBrowserMetadata)
-      .then(onProxyFileURL);
-
-  function serveLocalProtocolFile() {
-    return new Promise((resolve, reject) => {
-      fs.exists(localProtocolPath, fsExistsCallback);
-      function fsExistsCallback(fileExists) {
-        if (!fileExists) {
-          reject(new Error(`Cannot find local protocol file ${localProtocolPath}`));
-          return;
-        }
-        fs.readFile(localProtocolPath, 'binary', readFileCallback);
-      }
-      function readFileCallback(err, file) {
-        if (err) {
-          reject(new Error(`Unable to read local protocol file ${localProtocolPath}`));
-          return;
-        }
-        return resolve(file);
-      }
-    });
-  }
-
-  function onBrowserMetadata(metadata) {
-    var metadataObject = JSON.parse(metadata);
-    var match = metadataObject['WebKit-Version'].match(/\s\(@(\b[0-9a-f]{5,40}\b)/);
-    var commitHash = match[1];
-    var proxyFileURL = proxyFilePathToURL[filePath](commitHash);
-    return proxyFileURL;
-  }
-
-  function onProxyFileURL(proxyFileURL) {
-    if (proxyFileCache.has(proxyFileURL))
-      return Promise.resolve(proxyFileCache.get(proxyFileURL));
-    return utils.fetch(proxyFileURL).then(cacheProxyFile.bind(null, proxyFileURL)).catch(onMissingFile);
-  }
-
-  function onMissingFile() {
-    var isFullCheckout = utils.shellOutput('git config --get remote.origin.url') ===
-        'https://chromium.googlesource.com/chromium/src.git';
-    var earlierCommitHash;
-    var gitLogCommand = `git log --max-count=1 --grep="Commit-Position" --before="12 hours ago"`;
-    if (isFullCheckout) {
-      earlierCommitHash = utils.shellOutput(`${gitLogCommand} --pretty=format:"%H"`);
-    } else {
-      var commitMessage = utils.shellOutput(`${gitLogCommand}`);
-      earlierCommitHash = commitMessage.match(/Cr-Mirrored-Commit: (.*)/)[1];
-    }
-    var fallbackURL = proxyFilePathToURL[filePath](earlierCommitHash);
-    console.log('WARNING: Unable to fetch generated file based on browser\'s revision');
-    console.log('Fetching earlier revision of same file as fallback');
-    console.log('There may be a mismatch between the front-end and back-end');
-    console.log(fallbackURL, '\n');
-    return utils.fetch(fallbackURL).then(cacheProxyFile.bind(null, fallbackURL));
-  }
-
-  function cacheProxyFile(proxyFileURL, data) {
-    proxyFileCache.set(proxyFileURL, data);
-    return data;
-  }
-}
diff --git a/scripts/jsdoc_validator/PRESUBMIT.py b/scripts/jsdoc_validator/PRESUBMIT.py
deleted file mode 100644
index 99e6dce..0000000
--- a/scripts/jsdoc_validator/PRESUBMIT.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2013 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""DevTools JSDoc validator presubmit script
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into gcl.
-"""
-
-import sys
-
-
-def _ValidateHashes(input_api, output_api):
-    sys.path.append(input_api.PresubmitLocalPath())
-    import build_jsdoc_validator_jar
-    hashes_modified = build_jsdoc_validator_jar.hashes_modified()
-    if not hashes_modified:
-        return []
-
-    results = '\n'.join(['%s (%s != %s)' % (name, expected, actual) for (name, expected, actual) in hashes_modified])
-    return [
-        output_api.PresubmitError(
-            'DevTools frontend JSDoc validator Java code, "%s" and "%s" must always be updated together. Please rebuild.\nModifications found:\n%s'
-            % (build_jsdoc_validator_jar.jar_name, build_jsdoc_validator_jar.hashes_name, results))
-    ]
-
-
-def CheckChangeOnUpload(input_api, output_api):
-    return _ValidateHashes(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
-    return _ValidateHashes(input_api, output_api)
diff --git a/scripts/jsdoc_validator/build_jsdoc_validator_jar.py b/scripts/jsdoc_validator/build_jsdoc_validator_jar.py
deleted file mode 100755
index fdf8254..0000000
--- a/scripts/jsdoc_validator/build_jsdoc_validator_jar.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/python
-
-import hashlib
-import operator
-import os
-import shutil
-import stat
-import subprocess
-import sys
-import tempfile
-
-
-def rel_to_abs(rel_path):
-    return os.path.join(script_path, rel_path)
-
-
-java_bin_path = os.getenv('JAVA_HOME', '')
-if java_bin_path:
-    java_bin_path = os.path.join(java_bin_path, 'bin')
-
-main_class = 'org.chromium.devtools.jsdoc.JsDocValidator'
-jar_name = 'jsdoc_validator.jar'
-hashes_name = 'hashes'
-src_dir = 'src'
-script_path = os.path.dirname(os.path.abspath(__file__))
-closure_jar_relpath = os.path.join('..', 'closure', 'compiler.jar')
-src_path = rel_to_abs(src_dir)
-hashes_path = rel_to_abs(hashes_name)
-
-
-def get_file_hash(file, blocksize=65536):
-    sha = hashlib.sha256()
-    buf = file.read(blocksize)
-    while len(buf) > 0:
-        sha.update(buf)
-        buf = file.read(blocksize)
-    return sha.hexdigest()
-
-
-def traverse(hasher, path):
-    abs_path = rel_to_abs(path)
-    info = os.lstat(abs_path)
-    quoted_name = repr(path.replace('\\', '/'))
-    if stat.S_ISDIR(info.st_mode) and not os.path.basename(path).startswith('.'):
-        hasher.update('d ' + quoted_name + '\n')
-        for entry in sorted(os.listdir(abs_path)):
-            traverse(hasher, os.path.join(path, entry))
-    elif stat.S_ISREG(info.st_mode) and path.endswith('.java'):
-        hasher.update('r ' + quoted_name + ' ')
-        hasher.update(str(info.st_size) + ' ')
-        with open(abs_path, 'Ur') as file:
-            f_hash = get_file_hash(file)
-            hasher.update(f_hash + '\n')
-
-
-def get_src_dir_hash(dir):
-    sha = hashlib.sha256()
-    traverse(sha, dir)
-    return sha.hexdigest()
-
-
-def get_actual_hashes():
-    hashed_files = [(jar_name, True)]
-    hashes = {}
-    for (file_name, binary) in hashed_files:
-        try:
-            hash = get_file_hash(open(file_name, 'rb' if binary else 'r'))
-            hashes[file_name] = hash
-        except IOError:
-            hashes[file_name] = '0'
-    hashes[src_dir] = get_src_dir_hash(src_dir)
-    return hashes
-
-
-def get_expected_hashes():
-    try:
-        with open(hashes_path, 'r') as file:
-            return {
-                file_name: hash
-                for (file_name, hash) in [(name.strip(), hash.strip()) for (hash, name) in [line.split(' ', 1) for line in file]]
-            }
-    except:
-        return None
-
-
-def run_and_communicate(command, error_template):
-    proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
-    proc.communicate()
-    if proc.returncode:
-        print >> sys.stderr, error_template % proc.returncode
-        sys.exit(proc.returncode)
-
-
-def build_artifacts():
-    print 'Compiling...'
-    java_files = []
-    for root, dirs, files in sorted(os.walk(src_path)):
-        for file_name in files:
-            if file_name.endswith('.java'):
-                java_files.append(os.path.join(root, file_name))
-
-    bin_path = tempfile.mkdtemp()
-    manifest_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
-    try:
-        manifest_file.write('Class-Path: %s\n' % closure_jar_relpath)
-        manifest_file.close()
-        javac_path = os.path.join(java_bin_path, 'javac')
-        javac_command = '%s -target 7 -source 7 -d %s -cp %s %s' % (javac_path, bin_path, rel_to_abs(closure_jar_relpath),
-                                                                    ' '.join(java_files))
-        run_and_communicate(javac_command, 'Error: javac returned %d')
-
-        print 'Building jar...'
-        artifact_path = rel_to_abs(jar_name)
-        jar_path = os.path.join(java_bin_path, 'jar')
-        jar_command = '%s cvfme %s %s %s -C %s .' % (jar_path, artifact_path, manifest_file.name, main_class, bin_path)
-        run_and_communicate(jar_command, 'Error: jar returned %d')
-    finally:
-        os.remove(manifest_file.name)
-        shutil.rmtree(bin_path, True)
-
-
-def update_hashes():
-    print 'Updating hashes...'
-    with open(hashes_path, 'w') as file:
-        file.writelines(['%s %s\n' % (hash, name) for (name, hash) in get_actual_hashes().iteritems()])
-
-
-def hashes_modified():
-    expected_hashes = get_expected_hashes()
-    if not expected_hashes:
-        return [('<no expected hashes>', 1, 0)]
-    actual_hashes = get_actual_hashes()
-    results = []
-    for name, expected_hash in expected_hashes.iteritems():
-        actual_hash = actual_hashes.get(name)
-        if expected_hash != actual_hash:
-            results.append((name, expected_hash, actual_hash))
-    return results
-
-
-def help():
-    print 'usage: %s [option]' % os.path.basename(__file__)
-    print 'Options:'
-    print '--force-rebuild: Rebuild classes and jar even if there are no source file changes'
-    print '--no-rebuild: Do not rebuild jar, just update hashes'
-
-
-def main():
-    no_rebuild = False
-    force_rebuild = False
-
-    if len(sys.argv) > 1:
-        if sys.argv[1] == '--help':
-            help()
-            return
-        no_rebuild = sys.argv[1] == '--no-rebuild'
-        force_rebuild = sys.argv[1] == '--force-rebuild'
-
-    if not hashes_modified() and not force_rebuild:
-        print 'No modifications found, rebuild not required.'
-        return
-    if not no_rebuild:
-        build_artifacts()
-
-    update_hashes()
-    print 'Done.'
-
-
-if __name__ == '__main__':
-    main()
diff --git a/scripts/jsdoc_validator/hashes b/scripts/jsdoc_validator/hashes
deleted file mode 100644
index 196e0a5..0000000
--- a/scripts/jsdoc_validator/hashes
+++ /dev/null
@@ -1,2 +0,0 @@
-41de8b8314e09505c2d54694c45e76cbcaba3a7a55aa84bad7be64f79d29ce36 jsdoc_validator.jar
-a85a8bc9d70c97eeb9a0c6bbc08687595664941cd54ab3a9dda2ea61691404c0 src
diff --git a/scripts/jsdoc_validator/jsdoc_validator.jar b/scripts/jsdoc_validator/jsdoc_validator.jar
deleted file mode 100644
index 994218c..0000000
--- a/scripts/jsdoc_validator/jsdoc_validator.jar
+++ /dev/null
Binary files differ
diff --git a/scripts/jsdoc_validator/run_tests.py b/scripts/jsdoc_validator/run_tests.py
deleted file mode 100755
index 1fc290e..0000000
--- a/scripts/jsdoc_validator/run_tests.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/python
-
-import hashlib
-import operator
-import os
-import shutil
-import stat
-import subprocess
-import sys
-import tempfile
-
-
-def rel_to_abs(rel_path):
-    return os.path.join(script_path, rel_path)
-
-
-java_exec = 'java -Xms1024m -server -XX:+TieredCompilation'
-tests_dir = 'tests'
-jar_name = 'jsdoc_validator.jar'
-script_path = os.path.dirname(os.path.abspath(__file__))
-tests_path = rel_to_abs(tests_dir)
-validator_jar_file = rel_to_abs(jar_name)
-golden_file = os.path.join(tests_path, 'golden.dat')
-
-test_files = [
-    os.path.join(tests_path, f) for f in os.listdir(tests_path)
-    if f.endswith('.js') and os.path.isfile(os.path.join(tests_path, f))
-]
-
-validator_command = "%s -jar %s %s" % (java_exec, validator_jar_file, " ".join(sorted(test_files)))
-
-
-def run_and_communicate(command, error_template):
-    proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
-    (out, _) = proc.communicate()
-    if proc.returncode:
-        print >> sys.stderr, error_template % proc.returncode
-        sys.exit(proc.returncode)
-    return out
-
-
-def help():
-    print 'usage: %s [option]' % os.path.basename(__file__)
-    print 'Options:'
-    print '--generate-golden: Re-generate golden file'
-    print '--dump: Dump the test results to stdout'
-
-
-def main():
-    need_golden = False
-    need_dump = False
-    if len(sys.argv) > 1:
-        if sys.argv[1] == '--generate-golden':
-            need_golden = True
-        elif sys.argv[1] == '--dump':
-            need_dump = True
-        else:
-            help()
-            return
-
-    result = run_and_communicate(validator_command, "Error running validator: %d")
-    result = result.replace(script_path, "")  # pylint: disable=E1103
-    if need_dump:
-        print result
-        return
-
-    if need_golden:
-        with open(golden_file, 'wt') as golden:
-            golden.write(result)
-    else:
-        with open(golden_file, 'rt') as golden:
-            golden_text = golden.read()
-            if golden_text == result:
-                print 'OK'
-            else:
-                print 'ERROR: Golden output mismatch'
-
-
-if __name__ == '__main__':
-    main()
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DEPS b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DEPS
deleted file mode 100644
index fa04739..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-    "+Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc",
-]
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DoDidNodeVisitor.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DoDidNodeVisitor.java
deleted file mode 100644
index 36a9ebc..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DoDidNodeVisitor.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.chromium.devtools.jsdoc;
-
-import com.google.javascript.rhino.Node;
-
-public interface DoDidNodeVisitor {
-    /**
-     * Pre-visit node. Visitable children (if any) of {@code node} will be visited afterwards.
-     * @param node
-     */
-    void doVisit(Node node);
-
-    /**
-     * Post-visit node. The method is invoked once all visitable children (if any) of {@code node}
-     * have been visited.
-     * @param node
-     */
-    void didVisit(Node node);
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DoDidVisitorAdapter.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DoDidVisitorAdapter.java
deleted file mode 100644
index b81a816..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/DoDidVisitorAdapter.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.chromium.devtools.jsdoc;
-
-import com.google.javascript.jscomp.NodeTraversal;
-import com.google.javascript.rhino.Node;
-
-public abstract class DoDidVisitorAdapter implements DoDidNodeVisitor, NodeTraversal.Callback {
-    @Override
-    public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n, Node parent) {
-        doVisit(n);
-        return true;
-    }
-
-    @Override
-    public void visit(NodeTraversal t, Node n, Node parent) {
-        didVisit(n);
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/FileCheckerCallable.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/FileCheckerCallable.java
deleted file mode 100644
index 44e4676..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/FileCheckerCallable.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.chromium.devtools.jsdoc;
-
-import com.google.javascript.jscomp.Compiler;
-import com.google.javascript.jscomp.NodeTraversal;
-import com.google.javascript.jscomp.parsing.Config;
-import com.google.javascript.jscomp.parsing.Config.JsDocParsing;
-import com.google.javascript.jscomp.parsing.Config.LanguageMode;
-import com.google.javascript.jscomp.parsing.Config.StrictMode;
-import com.google.javascript.jscomp.parsing.Config.RunMode;
-import com.google.javascript.jscomp.parsing.ParserRunner;
-import com.google.javascript.rhino.ErrorReporter;
-import com.google.javascript.rhino.Node;
-
-import org.chromium.devtools.jsdoc.checks.ContextTrackingValidationCheck;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-public class FileCheckerCallable implements Callable<ValidatorContext> {
-    private static Set<String> EXTRA_ANNOTATIONS =
-            new HashSet<>(Arrays.asList("suppressReceiverCheck", "suppressGlobalPropertiesCheck"));
-    private final String fileName;
-
-    public FileCheckerCallable(String fileName) {
-        this.fileName = fileName;
-    }
-
-    @Override
-    public ValidatorContext call() {
-        try {
-            ValidatorContext context = new ValidatorContext(readScriptText(), fileName);
-            ValidationCheckDispatcher dispatcher = new ValidationCheckDispatcher(context);
-            dispatcher.registerCheck(new ContextTrackingValidationCheck());
-            NodeTraversal.traverseEs6ScopeRoots(new Compiler(), parseScript(context), null, dispatcher, true);
-            return context;
-        } catch (FileNotFoundException e) {
-            logError("File not found: " + fileName);
-        } catch (IOException e) {
-            logError("Failed to read file " + fileName);
-        }
-        return null;
-    }
-
-    private String readScriptText() throws IOException {
-        byte[] encoded = Files.readAllBytes(FileSystems.getDefault().getPath(fileName));
-        String text = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(encoded)).toString();
-        return text;
-    }
-
-    private static Node parseScript(final ValidatorContext context) {
-        Config config = ParserRunner.createConfig(LanguageMode.ECMASCRIPT6,
-                JsDocParsing.INCLUDE_DESCRIPTIONS_WITH_WHITESPACE, RunMode.KEEP_GOING,
-                EXTRA_ANNOTATIONS, true, StrictMode.STRICT);
-        ErrorReporter errorReporter = new ErrorReporter() {
-            @Override
-            public void warning(String message, String sourceName, int line, int lineOffset) {
-                // Ignore.
-            }
-
-            @Override
-            public void error(String message, String sourceName, int line, int lineOffset) {
-                logError("at " + sourceName + ":" + line + ":" + lineOffset);
-            }
-        };
-        try {
-            return ParserRunner
-                    .parse(context.sourceFile, context.sourceFile.getCode(), config, errorReporter)
-                    .ast;
-        } catch (IOException e) {
-            // Does not happen with preloaded files.
-            return null;
-        }
-    }
-
-    private static void logError(String message) {
-        System.err.println("ERROR: " + message);
-    }
-
-    private static class ValidationCheckDispatcher extends DoDidVisitorAdapter {
-        private final List<ValidationCheck> checks = new ArrayList<>(2);
-        private final ValidatorContext context;
-
-        public ValidationCheckDispatcher(ValidatorContext context) {
-            this.context = context;
-        }
-
-        public void registerCheck(ValidationCheck check) {
-            check.setContext(context);
-            checks.add(check);
-        }
-
-        @Override
-        public void doVisit(Node node) {
-            for (DoDidNodeVisitor visitor : checks) {
-                visitor.doVisit(node);
-            }
-        }
-
-        @Override
-        public void didVisit(Node node) {
-            for (ValidationCheck check : checks) {
-                check.didVisit(node);
-            }
-        }
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java
deleted file mode 100644
index 460158a..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/JsDocValidator.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Validator for Closure-based JSDoc.
- */
-
-package org.chromium.devtools.jsdoc;
-
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-public class JsDocValidator {
-    private static final String FILES_LIST_NAME = "--files-list-name";
-
-    private void run(String[] args) {
-        if (args.length == 0) {
-            System.err.println("At least 1 argument is expected");
-            System.exit(1);
-        }
-        String[] files;
-        if (FILES_LIST_NAME.equals(args[0])) {
-            files = readFileNames(args);
-        } else {
-            files = args;
-        }
-        int threadCount = Math.min(files.length, Runtime.getRuntime().availableProcessors());
-        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
-        try {
-            runWithExecutor(files, executor);
-        } finally {
-            executor.shutdown();
-        }
-    }
-
-    private String[] readFileNames(String[] args) {
-        if (args.length != 2) {
-            System.err.println("A single file name is expected to follow " + FILES_LIST_NAME);
-            System.exit(1);
-        }
-        try {
-            List<String> list = Files.readAllLines(
-                    FileSystems.getDefault().getPath(args[1]), Charset.forName("UTF-8"));
-            return list.toArray(new String[list.size()]);
-        } catch (IOException e) {
-            System.err.println("Unable to read list file " + args[1]);
-            e.printStackTrace();
-            System.exit(1);
-            return new String[0];
-        }
-    }
-
-    private void runWithExecutor(String[] args, ExecutorService executor) {
-        List<Future<ValidatorContext>> futures = new ArrayList<>(args.length);
-        Map<Future<ValidatorContext>, String> fileNamesByFuture = new HashMap<>();
-        for (String fileName : args) {
-            Future<ValidatorContext> future = executor.submit(new FileCheckerCallable(fileName));
-            fileNamesByFuture.put(future, fileName);
-            futures.add(future);
-        }
-
-        List<ValidatorContext> contexts = new ArrayList<>(args.length);
-        for (Future<ValidatorContext> future : futures) {
-            try {
-                ValidatorContext context = future.get();
-                if (context != null) {
-                    contexts.add(context);
-                }
-            } catch (InterruptedException | ExecutionException e) {
-                if (e.getMessage().indexOf("DESTRUCTURING_LHS") == -1) {
-                    System.err.println(
-                            fileNamesByFuture.get(future) + ": ERROR - " + e.getMessage());
-                }
-            }
-        }
-
-        int entryCount = 0;
-        for (ValidatorContext context : contexts) {
-            entryCount += context.getValidationResult().size();
-        }
-        List<LogEntry> entries = new ArrayList<>(entryCount);
-        for (ValidatorContext context : contexts) {
-            SortedSet<ValidatorContext.MessageRecord> records = context.getValidationResult();
-            for (ValidatorContext.MessageRecord record : records) {
-                entries.add(new LogEntry(context.scriptFileName, record));
-            }
-        }
-        Collections.sort(entries);
-        for (LogEntry entry : entries) {
-            System.err.println(entry.record.text);
-        }
-        if (!entries.isEmpty()) System.err.println("Total errors: " + entries.size());
-    }
-
-    public static void main(String[] args) {
-        new JsDocValidator().run(args);
-    }
-
-    private static class LogEntry implements Comparable<LogEntry> {
-        private final String fileName;
-        private final ValidatorContext.MessageRecord record;
-
-        LogEntry(String fileName, ValidatorContext.MessageRecord record) {
-            this.fileName = fileName;
-            this.record = record;
-        }
-
-        @Override
-        public int compareTo(LogEntry other) {
-            int result = fileName.compareTo(other.fileName);
-            if (result != 0) {
-                return result;
-            }
-            return Integer.compare(record.position, other.record.position);
-        }
-
-        @Override
-        public int hashCode() {
-            return 17 + fileName.hashCode() * 3 + this.record.hashCode() * 5;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            LogEntry other = (LogEntry) obj;
-            if (fileName != other.fileName
-                    && (fileName != null && !fileName.equals(other.fileName))) {
-                return false;
-            }
-
-            if (record == other.record) {
-                return true;
-            }
-            if (record != null) {
-                if (other.record == null) {
-                    return false;
-                }
-                return record.position == other.record.position;
-            }
-            return false;
-        }
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/ValidationCheck.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/ValidationCheck.java
deleted file mode 100644
index c80399c..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/ValidationCheck.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.chromium.devtools.jsdoc;
-
-import com.google.javascript.rhino.Node;
-
-/**
- * A base class for all JSDoc validation checks.
- */
-public abstract class ValidationCheck implements DoDidNodeVisitor {
-    private ValidatorContext context;
-
-    protected String getNodeText(Node node) {
-        return context.getNodeText(node);
-    }
-
-    protected void setContext(ValidatorContext context) {
-        if (this.context != null) {
-            throw new RuntimeException("ValidatorContext already set");
-        }
-        this.context = context;
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/ValidatorContext.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/ValidatorContext.java
deleted file mode 100644
index 7e7b321..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/ValidatorContext.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.chromium.devtools.jsdoc;
-
-import com.google.javascript.jscomp.SourceFile;
-import com.google.javascript.rhino.Node;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-public class ValidatorContext {
-    private static final Comparator<MessageRecord> MESSAGE_RECORD_COMPARATOR =
-            new Comparator<MessageRecord>() {
-                @Override
-                public int compare(MessageRecord left, MessageRecord right) {
-                    return left.position - right.position;
-                }
-            };
-
-    public final String scriptFileName;
-    public final SourceFile sourceFile;
-    private final SortedSet<MessageRecord> validationResult =
-            new TreeSet<>(MESSAGE_RECORD_COMPARATOR);
-
-    public ValidatorContext(String text, String scriptFileName) {
-        this.scriptFileName = scriptFileName;
-        this.sourceFile = SourceFile.builder().buildFromCode(scriptFileName, text);
-    }
-
-    public SortedSet<MessageRecord> getValidationResult() {
-        return Collections.unmodifiableSortedSet(validationResult);
-    }
-
-    public String getNodeText(Node node) {
-        if (node == null) {
-            return null;
-        }
-        try {
-            return sourceFile.getCode().substring(
-                    node.getSourceOffset(), node.getSourceOffset() + node.getLength());
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    public SourcePosition getPosition(int offset) {
-        return new SourcePosition(
-                sourceFile.getLineOfOffset(offset), sourceFile.getColumnOfOffset(offset));
-    }
-
-    public void reportErrorInNode(Node node, int offsetInNodeText, String errorText) {
-        int errorAbsoluteOffset = node.getSourceOffset() + offsetInNodeText;
-        reportErrorAtOffset(errorAbsoluteOffset, errorText);
-    }
-
-    public void reportErrorAtOffset(int offset, String errorText) {
-        SourcePosition position = getPosition(offset);
-        StringBuilder positionMarker = new StringBuilder(position.column + 1);
-        for (int i = position.column; i > 0; --i) {
-            positionMarker.append(' ');
-        }
-        positionMarker.append('^');
-        String message = String.format("%s:%d: ERROR - %s%n%s%n%s%n", scriptFileName, position.line,
-                errorText, sourceFile.getLine(position.line), positionMarker.toString());
-        validationResult.add(new MessageRecord(offset, message));
-    }
-
-    public static class MessageRecord {
-        public final int position;
-        public final String text;
-
-        public MessageRecord(int position, String text) {
-            this.position = position;
-            this.text = text;
-        }
-    }
-
-    public static class SourcePosition {
-        public final int line;
-        public final int column;
-
-        public SourcePosition(int line, int column) {
-            this.line = line;
-            this.column = column;
-        }
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/AstUtil.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/AstUtil.java
deleted file mode 100644
index 5eb671e..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/AstUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.common.base.Preconditions;
-import com.google.javascript.rhino.JSTypeExpression;
-import com.google.javascript.rhino.Node;
-import com.google.javascript.rhino.Token;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class AstUtil {
-    private static final String PROTOTYPE_SUFFIX = ".prototype";
-
-    static Node parentOfType(Node node, Token tokenType) {
-        Node parent = node.getParent();
-        return (parent == null || parent.getToken() != tokenType) ? null : parent;
-    }
-
-    /**
-     * Based on NodeUtil#getFunctionNameNode(Node).
-     */
-    static Node getFunctionNameNode(Node node) {
-        Preconditions.checkState(node.isFunction());
-
-        Node parent = node.getParent();
-        if (parent != null) {
-            switch (parent.getToken()) {
-                case NAME:
-                    // var name = function() ...
-                    // var name2 = function name1() ...
-                    return parent;
-                // FIXME: Enable the setter and getter checks.
-                // case SETTER_DEF:
-                // case GETTER_DEF:
-                case STRING_KEY:
-                    return parent;
-                case NUMBER:
-                    return parent;
-                case ASSIGN:
-                    Token nameType = parent.getFirstChild().getToken();
-                    // We only consider these types of name nodes as acceptable.
-                    return nameType == Token.NAME || nameType == Token.GETPROP
-                            ? parent.getFirstChild()
-                            : null;
-                case VAR:
-                    return parent.getFirstChild();
-                default:
-                    Node funNameNode = node.getFirstChild();
-                    // Don't return the name node for anonymous functions
-                    return funNameNode.getString().isEmpty() ? null : funNameNode;
-            }
-        }
-
-        return null;
-    }
-
-    static String getTypeNameFromPrototype(String value) {
-        return value.substring(0, value.length() - PROTOTYPE_SUFFIX.length());
-    }
-
-    static boolean isPrototypeName(String typeName) {
-        return typeName.endsWith(PROTOTYPE_SUFFIX);
-    }
-
-    static Node getAssignedTypeNameNode(Node assignment) {
-        Preconditions.checkState(assignment.isAssign() || assignment.isVar());
-        Node typeNameNode = assignment.getFirstChild();
-        if (typeNameNode.getToken() != Token.GETPROP && typeNameNode.getToken() != Token.NAME) {
-            return null;
-        }
-        return typeNameNode;
-    }
-
-    static List<Node> getArguments(Node functionCall) {
-        int childCount = functionCall.getChildCount();
-        if (childCount == 1) {
-            return Collections.emptyList();
-        }
-        List<Node> arguments = new ArrayList<>(childCount - 1);
-        for (int i = 1; i < childCount; ++i) {
-            arguments.add(functionCall.getChildAtIndex(i));
-        }
-        return arguments;
-    }
-
-    static String getAnnotationTypeString(JSTypeExpression expression) {
-        return expression.getRoot().getFirstChild().getString();
-    }
-
-    private AstUtil() {}
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingChecker.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingChecker.java
deleted file mode 100644
index f77b1f6..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingChecker.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.javascript.rhino.Node;
-
-import org.chromium.devtools.jsdoc.ValidatorContext;
-
-abstract class ContextTrackingChecker {
-    private ContextTrackingState state;
-
-    abstract void enterNode(Node node);
-
-    abstract void leaveNode(Node node);
-
-    void setState(ContextTrackingState state) {
-        this.state = state;
-    }
-
-    protected ContextTrackingState getState() {
-        return state;
-    }
-
-    protected ValidatorContext getContext() {
-        return state.getContext();
-    }
-
-    protected void reportErrorAtNodeStart(Node node, String errorText) {
-        getContext().reportErrorInNode(node, 0, errorText);
-    }
-
-    protected void reportErrorAtOffset(int offset, String errorText) {
-        getContext().reportErrorAtOffset(offset, errorText);
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingState.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingState.java
deleted file mode 100644
index 2e336a2..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingState.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.javascript.rhino.Node;
-
-import org.chromium.devtools.jsdoc.ValidatorContext;
-
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-public class ContextTrackingState {
-    private final ValidatorContext context;
-
-    ContextTrackingState(ValidatorContext context) {
-        this.context = context;
-    }
-
-    final Map<String, TypeRecord> typeRecordsByTypeName = new HashMap<>();
-    final Deque<TypeRecord> typeRecords = new LinkedList<>();
-    final Deque<FunctionRecord> functionRecords = new LinkedList<>();
-
-    TypeRecord getCurrentTypeRecord() {
-        return typeRecords.peekLast();
-    }
-
-    FunctionRecord getCurrentFunctionRecord() {
-        return functionRecords.peekLast();
-    }
-
-    ValidatorContext getContext() {
-        return context;
-    }
-
-    Map<String, TypeRecord> getTypeRecordsByTypeName() {
-        return typeRecordsByTypeName;
-    }
-
-    String getNodeText(Node node) {
-        return getContext().getNodeText(node);
-    }
-
-    void pushTypeRecord(TypeRecord record) {
-        typeRecords.addLast(record);
-    }
-
-    void popTypeRecord() {
-        typeRecords.removeLast();
-    }
-
-    void pushFunctionRecord(FunctionRecord record) {
-        functionRecords.addLast(record);
-    }
-
-    void popFunctionRecord() {
-        functionRecords.removeLast();
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingValidationCheck.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingValidationCheck.java
deleted file mode 100644
index 0e42182..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ContextTrackingValidationCheck.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.javascript.jscomp.NodeUtil;
-import com.google.javascript.rhino.JSDocInfo;
-import com.google.javascript.rhino.Node;
-import com.google.javascript.rhino.Token;
-
-import org.chromium.devtools.jsdoc.ValidationCheck;
-import org.chromium.devtools.jsdoc.ValidatorContext;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ContextTrackingValidationCheck extends ValidationCheck {
-    private ContextTrackingState state;
-    private final List<ContextTrackingChecker> clients = new ArrayList<>(5);
-
-    @Override
-    protected void setContext(ValidatorContext context) {
-        super.setContext(context);
-        state = new ContextTrackingState(context);
-        registerClient(new ProtoFollowsExtendsChecker());
-        registerClient(new MethodAnnotationChecker());
-        registerClient(new FunctionReceiverChecker());
-        registerClient(new DisallowedGlobalPropertiesChecker());
-    }
-
-    @Override
-    public void doVisit(Node node) {
-        switch (node.getToken()) {
-            case ASSIGN:
-            case VAR:
-                enterAssignOrVarNode(node);
-                break;
-            case FUNCTION:
-                enterFunctionNode(node);
-                break;
-            default:
-                break;
-        }
-
-        enterNode(node);
-    }
-
-    @Override
-    public void didVisit(Node node) {
-        leaveNode(node);
-
-        switch (node.getToken()) {
-            case ASSIGN:
-                leaveAssignNode(node);
-                break;
-            case FUNCTION:
-                leaveFunctionNode(node);
-                break;
-            default:
-                break;
-        }
-    }
-
-    public void registerClient(ContextTrackingChecker client) {
-        this.clients.add(client);
-        client.setState(state);
-    }
-
-    private void enterNode(Node node) {
-        for (ContextTrackingChecker client : clients) {
-            client.enterNode(node);
-        }
-    }
-
-    private void leaveNode(Node node) {
-        for (ContextTrackingChecker client : clients) {
-            client.leaveNode(node);
-        }
-    }
-
-    private void enterFunctionNode(Node node) {
-        TypeRecord parentType =
-                state.getCurrentFunctionRecord() == null ? state.getCurrentTypeRecord() : null;
-        Node nameNode = AstUtil.getFunctionNameNode(node);
-        String functionName = nameNode == null ? null : state.getNodeText(nameNode);
-        FunctionRecord functionRecord = new FunctionRecord(node, functionName,
-                getFunctionParameterNames(node), parentType, state.getCurrentFunctionRecord());
-        state.pushFunctionRecord(functionRecord);
-        rememberTypeRecordIfNeeded(functionName, functionRecord.info);
-    }
-
-    @SuppressWarnings("unused")
-    private void leaveFunctionNode(Node node) {
-        state.functionRecords.removeLast();
-    }
-
-    private void enterAssignOrVarNode(Node node) {
-        String assignedTypeName = getAssignedTypeName(node);
-        if (assignedTypeName == null) {
-            return;
-        }
-        if (AstUtil.isPrototypeName(assignedTypeName)) {
-            // MyType.prototype = ...
-            String typeName = AstUtil.getTypeNameFromPrototype(assignedTypeName);
-            TypeRecord typeRecord = state.typeRecordsByTypeName.get(typeName);
-            // We should push anything here to maintain a valid current type record.
-            state.pushTypeRecord(typeRecord);
-            state.pushFunctionRecord(null);
-            return;
-        }
-    }
-
-    private void leaveAssignNode(Node assignment) {
-        String assignedTypeName = getAssignedTypeName(assignment);
-        if (assignedTypeName == null) {
-            return;
-        }
-        if (AstUtil.isPrototypeName(assignedTypeName)) {
-            // Remove the current type record when leaving prototype object.
-            state.typeRecords.removeLast();
-            state.functionRecords.removeLast();
-            return;
-        }
-    }
-
-    private String getAssignedTypeName(Node assignment) {
-        Node node = AstUtil.getAssignedTypeNameNode(assignment);
-        return getNodeText(node);
-    }
-
-    private List<String> getFunctionParameterNames(Node functionNode) {
-        List<String> parameterNames = new ArrayList<String>();
-        Node parametersNode = NodeUtil.getFunctionParameters(functionNode);
-        for (int i = 0, childCount = parametersNode.getChildCount(); i < childCount; ++i) {
-            Node paramNode = parametersNode.getChildAtIndex(i);
-            String paramText = state.getContext().getNodeText(paramNode);
-
-            // Handle default parameters (ES6)
-            String paramName = paramText.split("=")[0].trim();
-            parameterNames.add(paramName);
-        }
-        return parameterNames;
-    }
-
-    private boolean rememberTypeRecordIfNeeded(String typeName, JSDocInfo info) {
-        if (info == null) {
-            return false;
-        }
-        if (typeName == null) {
-            return info.isConstructor() || info.isInterface();
-        }
-        if (!info.isConstructor() && !info.isInterface()) {
-            return false;
-        }
-        TypeRecord record = new TypeRecord(typeName, info);
-        state.typeRecordsByTypeName.put(typeName, record);
-        return true;
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/DisallowedGlobalPropertiesChecker.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/DisallowedGlobalPropertiesChecker.java
deleted file mode 100644
index 3d1fab2..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/DisallowedGlobalPropertiesChecker.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.javascript.jscomp.NodeUtil;
-import com.google.javascript.rhino.JSDocInfo;
-import com.google.javascript.rhino.Node;
-import com.google.javascript.rhino.Token;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public final class DisallowedGlobalPropertiesChecker extends ContextTrackingChecker {
-    private static final Set<String> GLOBAL_OBJECT_NAMES = new HashSet<>();
-    private static final Set<String> DISALLOWED_PROPERTIES = new HashSet<>();
-    static {
-        GLOBAL_OBJECT_NAMES.add("window");
-        GLOBAL_OBJECT_NAMES.add("self");
-        DISALLOWED_PROPERTIES.add("document");
-        DISALLOWED_PROPERTIES.add("addEventListener");
-        DISALLOWED_PROPERTIES.add("removeEventListener");
-        DISALLOWED_PROPERTIES.add("requestAnimationFrame");
-        DISALLOWED_PROPERTIES.add("cancelAnimationFrame");
-        DISALLOWED_PROPERTIES.add("getSelection");
-    }
-
-    private static final FunctionRecord TOP_LEVEL_FUNCTION = new FunctionRecord();
-
-    private final Map<FunctionRecord, Set<String>> declaredLocalVariables = new HashMap<>();
-    private final Map<FunctionRecord, List<Node>> globalPropertyAccessNodes = new HashMap<>();
-
-    @Override
-    protected void enterNode(Node node) {
-        switch (node.getToken()) {
-            case VAR:
-                handleVar(node);
-                break;
-            case CONST:
-                handleVar(node);
-                break;
-            case LET:
-                handleVar(node);
-                break;
-            case NAME:
-                handleName(node);
-                break;
-            case STRING:
-                handleString(node);
-                break;
-            case FUNCTION:
-            case SCRIPT:
-                enterFunctionOrScript();
-                break;
-            default:
-                break;
-        }
-    }
-
-    @Override
-    protected void leaveNode(Node node) {
-        switch (node.getToken()) {
-            case FUNCTION:
-            case SCRIPT:
-                leaveFunctionOrScript();
-                break;
-            default:
-                break;
-        }
-    }
-
-    private void enterFunctionOrScript() {
-        FunctionRecord function = getCurrentFunction();
-        declaredLocalVariables.put(function, new HashSet<String>());
-        globalPropertyAccessNodes.put(function, new ArrayList<Node>());
-    }
-
-    private void leaveFunctionOrScript() {
-        FunctionRecord function = getCurrentFunction();
-        if (!function.suppressesGlobalPropertiesCheck()) {
-            checkAccessNodes(globalPropertyAccessNodes.get(function));
-        }
-        declaredLocalVariables.remove(function);
-        globalPropertyAccessNodes.remove(function);
-    }
-
-    private void checkAccessNodes(List<Node> nodes) {
-        FunctionRecord function = getCurrentFunction();
-        for (Node node : nodes) {
-            String name = getContext().getNodeText(node);
-            if (!functionHasVisibleIdentifier(function, name)) {
-                reportErrorAtNodeStart(node,
-                        String.format(
-                                "Access to \"%s\" property of global object is disallowed", name));
-            }
-        }
-    }
-
-    private void handleVar(Node varNode) {
-        Node nameNode = varNode.getFirstChild();
-        if (nameNode == null) {
-            return;
-        }
-        String name = nameNode.getString();
-        if (name != null) {
-            declaredLocalVariables.get(getCurrentFunction()).add(name);
-        }
-    }
-
-    private void handleName(Node nameNode) {
-        Node parent = nameNode.getParent();
-        if (parent != null && parent.getToken() == Token.FUNCTION) {
-            return;
-        }
-
-        String name = getContext().getNodeText(nameNode);
-        if (!DISALLOWED_PROPERTIES.contains(name)) {
-            return;
-        }
-
-        if (parent != null && parent.getToken() == Token.GETPROP) {
-            boolean isGlobalPropertyAccess = parent.getFirstChild() == nameNode;
-            if (!isGlobalPropertyAccess) {
-                return;
-            }
-        }
-        globalPropertyAccessNodes.get(getCurrentFunction()).add(nameNode);
-    }
-
-    private void handleString(Node stringNode) {
-        String name = getContext().getNodeText(stringNode);
-        if (!DISALLOWED_PROPERTIES.contains(name)) {
-            return;
-        }
-
-        Node parent = stringNode.getParent();
-        if (parent == null || parent.getToken() != Token.GETPROP) {
-            return;
-        }
-
-        Node objectNode = parent.getFirstChild();
-        boolean isGlobalObjectAccess = objectNode != null && isGlobalObject(objectNode)
-                && objectNode.getNext() == stringNode;
-        if (isGlobalObjectAccess) {
-            globalPropertyAccessNodes.get(getCurrentFunction()).add(stringNode);
-        }
-    }
-
-    private FunctionRecord getCurrentFunction() {
-        FunctionRecord function = getState().getCurrentFunctionRecord();
-        return function == null ? TOP_LEVEL_FUNCTION : function;
-    }
-
-    private boolean isGlobalObject(Node node) {
-        String name = getContext().getNodeText(node);
-        if (!GLOBAL_OBJECT_NAMES.contains(name)) {
-            return false;
-        }
-        return node.getToken() == Token.NAME
-                && !functionHasVisibleIdentifier(getCurrentFunction(), name);
-    }
-
-    private boolean functionHasVisibleIdentifier(FunctionRecord function, String name) {
-        if (functionHasLocalIdentifier(function, name)) {
-            return true;
-        }
-        if (function == TOP_LEVEL_FUNCTION) {
-            return false;
-        }
-        FunctionRecord parent = function.enclosingFunctionRecord;
-        return functionHasVisibleIdentifier(parent == null ? TOP_LEVEL_FUNCTION : parent, name);
-    }
-
-    private boolean functionHasLocalIdentifier(FunctionRecord function, String name) {
-        return function.parameterNames.contains(name)
-                || declaredLocalVariables.get(function).contains(name);
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/FunctionReceiverChecker.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/FunctionReceiverChecker.java
deleted file mode 100644
index 73cbf3c..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/FunctionReceiverChecker.java
+++ /dev/null
@@ -1,290 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.common.base.Preconditions;
-import com.google.javascript.rhino.Node;
-import com.google.javascript.rhino.Token;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public final class FunctionReceiverChecker extends ContextTrackingChecker {
-    private static final Set<String> FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT =
-            new HashSet<>();
-    private static final String SUPPRESSION_HINT = "This check can be suppressed using "
-            + "@suppressReceiverCheck annotation on function declaration.";
-    static {
-        // Array.prototype methods.
-        FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT.add("every");
-        FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT.add("filter");
-        FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT.add("forEach");
-        FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT.add("map");
-        FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT.add("some");
-    }
-
-    private final Map<String, FunctionRecord> nestedFunctionsByName = new HashMap<>();
-    private final Map<String, Set<CallSite>> callSitesByFunctionName = new HashMap<>();
-    private final Map<String, Set<SymbolicArgument>> symbolicArgumentsByName = new HashMap<>();
-    private final Set<FunctionRecord> functionsRequiringThisAnnotation = new HashSet<>();
-
-    @Override
-    void enterNode(Node node) {
-        switch (node.getToken()) {
-            case CALL:
-                handleCall(node);
-                break;
-            case FUNCTION: {
-                handleFunction(node);
-                break;
-            }
-            case THIS: {
-                handleThis();
-                break;
-            }
-            default:
-                break;
-        }
-    }
-
-    private void handleCall(Node functionCall) {
-        Preconditions.checkState(functionCall.isCall());
-        String[] callParts = getContext().getNodeText(functionCall.getFirstChild()).split("\\.");
-        String firstPart = callParts[0];
-        List<Node> argumentNodes = AstUtil.getArguments(functionCall);
-        List<String> actualArguments = argumentsForCall(argumentNodes);
-        int partCount = callParts.length;
-        String functionName = callParts[partCount - 1];
-
-        saveSymbolicArguments(functionName, argumentNodes, actualArguments);
-
-        boolean isBindCall = partCount > 1 && "bind".equals(functionName);
-        if (isBindCall && partCount == 3 && "this".equals(firstPart)
-                && !(actualArguments.size() > 0 && "this".equals(actualArguments.get(0)))) {
-            reportErrorAtNodeStart(
-                    functionCall, "Member function can only be bound to 'this' as the receiver");
-            return;
-        }
-        if (partCount > 2 || "this".equals(firstPart)) {
-            return;
-        }
-        boolean hasReceiver = isBindCall && isReceiverSpecified(actualArguments);
-        hasReceiver |= (partCount == 2)
-                && ("call".equals(functionName) || "apply".equals(functionName))
-                && isReceiverSpecified(actualArguments);
-        getOrCreateSetByKey(callSitesByFunctionName, firstPart)
-                .add(new CallSite(hasReceiver, functionCall));
-    }
-
-    private void handleFunction(Node node) {
-        Preconditions.checkState(node.isFunction());
-        FunctionRecord function = getState().getCurrentFunctionRecord();
-        if (function == null) {
-            return;
-        }
-        if (function.isTopLevelFunction()) {
-            symbolicArgumentsByName.clear();
-        } else {
-            Node nameNode = AstUtil.getFunctionNameNode(node);
-            if (nameNode == null) {
-                return;
-            }
-            nestedFunctionsByName.put(getContext().getNodeText(nameNode), function);
-        }
-    }
-
-    private void handleThis() {
-        FunctionRecord function = getState().getCurrentFunctionRecord();
-        while (function != null && function.functionNode.isArrowFunction()) {
-            function = function.enclosingFunctionRecord;
-        }
-        if (function == null) {
-            return;
-        }
-        if (!function.isTopLevelFunction() && !function.isConstructor()) {
-            functionsRequiringThisAnnotation.add(function);
-        }
-    }
-
-    private List<String> argumentsForCall(List<Node> argumentNodes) {
-        int argumentCount = argumentNodes.size();
-        List<String> arguments = new ArrayList<>(argumentCount);
-        for (Node argumentNode : argumentNodes) {
-            arguments.add(getContext().getNodeText(argumentNode));
-        }
-        return arguments;
-    }
-
-    private void saveSymbolicArguments(
-            String functionName, List<Node> argumentNodes, List<String> arguments) {
-        int argumentCount = arguments.size();
-        CheckedReceiverPresence receiverPresence = CheckedReceiverPresence.MISSING;
-        if (FUNCTIONS_WITH_CALLBACK_RECEIVER_AS_SECOND_ARGUMENT.contains(functionName)) {
-            if (argumentCount >= 2) {
-                receiverPresence = CheckedReceiverPresence.PRESENT;
-            }
-        } else if ("addEventListener".equals(functionName)
-                || "removeEventListener".equals(functionName)) {
-            String receiverArgument = argumentCount < 3 ? "" : arguments.get(2);
-            switch (receiverArgument) {
-                case "":
-                case "true":
-                case "false":
-                    receiverPresence = CheckedReceiverPresence.MISSING;
-                    break;
-                case "this":
-                    receiverPresence = CheckedReceiverPresence.PRESENT;
-                    break;
-                default:
-                    receiverPresence = CheckedReceiverPresence.IGNORE;
-            }
-        }
-
-        for (int i = 0; i < argumentCount; ++i) {
-            String argumentText = arguments.get(i);
-            getOrCreateSetByKey(symbolicArgumentsByName, argumentText)
-                    .add(new SymbolicArgument(receiverPresence, argumentNodes.get(i)));
-        }
-    }
-
-    private static <K, T> Set<T> getOrCreateSetByKey(Map<K, Set<T>> map, K key) {
-        Set<T> set = map.get(key);
-        if (set == null) {
-            set = new HashSet<>();
-            map.put(key, set);
-        }
-        return set;
-    }
-
-    private boolean isReceiverSpecified(List<String> arguments) {
-        return arguments.size() > 0 && !"null".equals(arguments.get(0));
-    }
-
-    @Override
-    void leaveNode(Node node) {
-        if (node.getToken() != Token.FUNCTION) {
-            return;
-        }
-
-        ContextTrackingState state = getState();
-        FunctionRecord function = state.getCurrentFunctionRecord();
-        if (function == null) {
-            return;
-        }
-        checkThisAnnotation(function);
-
-        // The nested function checks are only run when leaving a top-level function.
-        if (!function.isTopLevelFunction()) {
-            return;
-        }
-
-        for (FunctionRecord record : nestedFunctionsByName.values()) {
-            processFunctionUsesAsArgument(record, symbolicArgumentsByName.get(record.name));
-            processFunctionCallSites(record, callSitesByFunctionName.get(record.name));
-        }
-
-        nestedFunctionsByName.clear();
-        callSitesByFunctionName.clear();
-        symbolicArgumentsByName.clear();
-    }
-
-    private void checkThisAnnotation(FunctionRecord function) {
-        Node functionNameNode = AstUtil.getFunctionNameNode(function.functionNode);
-        if (functionNameNode == null && function.info == null) {
-            // Do not check anonymous functions without a JSDoc.
-            return;
-        }
-        int errorTargetOffset = functionNameNode == null
-                ? (function.info == null ? function.functionNode.getSourceOffset()
-                                         : function.info.getOriginalCommentPosition())
-                : functionNameNode.getSourceOffset();
-        boolean hasThisAnnotation = function.hasThisAnnotation();
-        if (hasThisAnnotation == functionReferencesThis(function)) {
-            return;
-        }
-        if (hasThisAnnotation) {
-            if (!function.isTopLevelFunction()) {
-                reportErrorAtOffset(errorTargetOffset,
-                        "@this annotation found for function not referencing 'this'");
-            }
-            return;
-        } else {
-            reportErrorAtOffset(errorTargetOffset,
-                    "@this annotation is required for functions referencing 'this'");
-        }
-    }
-
-    private boolean functionReferencesThis(FunctionRecord function) {
-        return functionsRequiringThisAnnotation.contains(function);
-    }
-
-    private void processFunctionCallSites(FunctionRecord function, Set<CallSite> callSites) {
-        if (callSites == null) {
-            return;
-        }
-        boolean functionReferencesThis = functionReferencesThis(function);
-        for (CallSite callSite : callSites) {
-            if (functionReferencesThis == callSite.hasReceiver || function.isConstructor()) {
-                continue;
-            }
-            if (callSite.hasReceiver) {
-                reportErrorAtNodeStart(callSite.callNode,
-                        "Receiver specified for a function not referencing 'this'");
-            } else {
-                reportErrorAtNodeStart(callSite.callNode,
-                        "Receiver not specified for a function referencing 'this'");
-            }
-        }
-    }
-
-    private void processFunctionUsesAsArgument(
-            FunctionRecord function, Set<SymbolicArgument> argumentUses) {
-        if (argumentUses == null || function.suppressesReceiverCheck()) {
-            return;
-        }
-
-        boolean referencesThis = functionReferencesThis(function);
-        for (SymbolicArgument argument : argumentUses) {
-            if (argument.receiverPresence == CheckedReceiverPresence.IGNORE) {
-                continue;
-            }
-            boolean receiverProvided = argument.receiverPresence == CheckedReceiverPresence.PRESENT;
-            if (referencesThis == receiverProvided) {
-                continue;
-            }
-            if (referencesThis) {
-                reportErrorAtNodeStart(
-                        argument.node, "Function referencing 'this' used as argument without "
-                                + "a receiver. " + SUPPRESSION_HINT);
-            } else {
-                reportErrorAtNodeStart(
-                        argument.node, "Function not referencing 'this' used as argument with "
-                                + "a receiver. " + SUPPRESSION_HINT);
-            }
-        }
-    }
-
-    private static enum CheckedReceiverPresence { PRESENT, MISSING, IGNORE }
-
-    private static class SymbolicArgument {
-        CheckedReceiverPresence receiverPresence;
-        Node node;
-
-        public SymbolicArgument(CheckedReceiverPresence receiverPresence, Node node) {
-            this.receiverPresence = receiverPresence;
-            this.node = node;
-        }
-    }
-
-    private static class CallSite {
-        boolean hasReceiver;
-        Node callNode;
-
-        public CallSite(boolean hasReceiver, Node callNode) {
-            this.hasReceiver = hasReceiver;
-            this.callNode = callNode;
-        }
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/FunctionRecord.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/FunctionRecord.java
deleted file mode 100644
index a44286d..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/FunctionRecord.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.javascript.jscomp.NodeUtil;
-import com.google.javascript.rhino.JSDocInfo;
-import com.google.javascript.rhino.Node;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class FunctionRecord {
-    final Node functionNode;
-    final JSDocInfo info;
-    final String name;
-    final List<String> parameterNames;
-    final TypeRecord enclosingType;
-    final FunctionRecord enclosingFunctionRecord;
-
-    public FunctionRecord(Node functionNode, String name, List<String> parameterNames,
-            TypeRecord parentType, FunctionRecord enclosingFunctionRecord) {
-        this.functionNode = functionNode;
-        this.info = NodeUtil.getBestJSDocInfo(functionNode);
-        this.name = name;
-        this.parameterNames = parameterNames;
-        this.enclosingType = parentType;
-        this.enclosingFunctionRecord = enclosingFunctionRecord;
-    }
-
-    public FunctionRecord() {
-        this.functionNode = null;
-        this.info = null;
-        this.name = "";
-        this.parameterNames = new ArrayList<>();
-        this.enclosingType = null;
-        this.enclosingFunctionRecord = null;
-    }
-
-    public boolean isConstructor() {
-        return info != null && info.isConstructor();
-    }
-
-    public boolean isTopLevelFunction() {
-        return enclosingFunctionRecord == null;
-    }
-
-    public boolean hasReturnAnnotation() {
-        return info != null && info.getReturnType() != null;
-    }
-
-    public boolean hasThisAnnotation() {
-        return info != null && info.getThisType() != null;
-    }
-
-    public boolean suppressesReceiverCheck() {
-        return info != null && info.getOriginalCommentString().contains("@suppressReceiverCheck");
-    }
-
-    public boolean suppressesGlobalPropertiesCheck() {
-        return info != null
-                && info.getOriginalCommentString().contains("@suppressGlobalPropertiesCheck");
-    }
-
-    @Override
-    public String toString() {
-        return (info == null ? "" : info.getOriginalCommentString() + "\n")
-                + (name == null ? "<anonymous>" : name) + "() @" + functionNode.getLineno();
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java
deleted file mode 100644
index 4d5deea..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.common.base.Joiner;
-import com.google.javascript.jscomp.NodeUtil;
-import com.google.javascript.rhino.JSDocInfo;
-import com.google.javascript.rhino.Node;
-import com.google.javascript.rhino.Token;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public final class MethodAnnotationChecker extends ContextTrackingChecker {
-    private static final Pattern PARAM_PATTERN =
-            Pattern.compile("^[^@\n]*@param\\s+(\\{.+\\}\\s+)?([^\\s]+).*$", Pattern.MULTILINE);
-
-    private static final Pattern INVALID_RETURN_PATTERN =
-            Pattern.compile("^[^@\n]*(@)return(?:s.*|\\s+[^{]*)$", Pattern.MULTILINE);
-
-    private final Set<FunctionRecord> valueReturningFunctions = new HashSet<>();
-    private final Set<FunctionRecord> throwingFunctions = new HashSet<>();
-
-    @Override
-    public void enterNode(Node node) {
-        switch (node.getToken()) {
-            case FUNCTION:
-                handleFunction(node);
-                break;
-            case RETURN:
-                handleReturn(node);
-                break;
-            case THROW:
-                handleThrow();
-                break;
-            default:
-                break;
-        }
-    }
-
-    private void handleFunction(Node functionNode) {
-        FunctionRecord function = getState().getCurrentFunctionRecord();
-        if (function == null || function.parameterNames.size() == 0) {
-            return;
-        }
-        String[] nonAnnotatedParams = getNonAnnotatedParamData(function);
-        if (nonAnnotatedParams.length > 0
-                && function.parameterNames.size() != nonAnnotatedParams.length) {
-            reportErrorAtOffset(function.info.getOriginalCommentPosition(),
-                    String.format("No @param JSDoc tag found for parameters: [%s]",
-                            Joiner.on(',').join(nonAnnotatedParams)));
-        }
-    }
-
-    private String[] getNonAnnotatedParamData(FunctionRecord function) {
-        if (function.info == null) {
-            return new String[0];
-        }
-        Set<String> formalParamNames = new HashSet<>();
-        for (int i = 0; i < function.parameterNames.size(); ++i) {
-            String paramName = function.parameterNames.get(i);
-            if (!formalParamNames.add(paramName)) {
-                reportErrorAtNodeStart(function.functionNode,
-                        String.format("Duplicate function argument name: %s", paramName));
-            }
-        }
-        Matcher m = PARAM_PATTERN.matcher(function.info.getOriginalCommentString());
-        while (m.find()) {
-            String paramType = m.group(1);
-            if (paramType == null) {
-                reportErrorAtOffset(function.info.getOriginalCommentPosition() + m.start(2),
-                        String.format("Invalid @param annotation found -"
-                                + " should be \"@param {<type>} paramName\""));
-            } else {
-                formalParamNames.remove(m.group(2));
-            }
-        }
-        return formalParamNames.toArray(new String[formalParamNames.size()]);
-    }
-
-    private void handleReturn(Node node) {
-        if (node.getFirstChild() == null || AstUtil.parentOfType(node, Token.ASSIGN) != null) {
-            return;
-        }
-
-        FunctionRecord record = getState().getCurrentFunctionRecord();
-        if (record == null) {
-            return;
-        }
-        Node nameNode = getFunctionNameNode(record.functionNode);
-        if (nameNode == null) {
-            return;
-        }
-        valueReturningFunctions.add(record);
-    }
-
-    private void handleThrow() {
-        FunctionRecord record = getState().getCurrentFunctionRecord();
-        if (record == null) {
-            return;
-        }
-        Node nameNode = getFunctionNameNode(record.functionNode);
-        if (nameNode == null) {
-            return;
-        }
-        throwingFunctions.add(record);
-    }
-
-    @Override
-    public void leaveNode(Node node) {
-        if (node.getToken() != Token.FUNCTION) {
-            return;
-        }
-
-        FunctionRecord record = getState().getCurrentFunctionRecord();
-        if (record != null) {
-            checkFunctionAnnotation(record);
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private void checkFunctionAnnotation(FunctionRecord function) {
-        String functionName = getFunctionName(function.functionNode);
-        if (functionName == null) {
-            return;
-        }
-        String[] parts = functionName.split("\\.");
-        functionName = parts[parts.length - 1];
-        boolean isApiFunction = !functionName.startsWith("_")
-                && (function.isTopLevelFunction()
-                           || (function.enclosingType != null
-                                      && isPlainTopLevelFunction(
-                                                 function.enclosingFunctionRecord)));
-
-        boolean isReturningFunction = valueReturningFunctions.contains(function);
-        boolean isInterfaceFunction =
-                function.enclosingType != null && function.enclosingType.isInterface();
-        int invalidAnnotationIndex = invalidReturnAnnotationIndex(function.info);
-        if (invalidAnnotationIndex != -1) {
-            String suggestedResolution = (isReturningFunction || isInterfaceFunction)
-                    ? "should be \"@return {<type>}\""
-                    : "please remove, as function does not return value";
-            getContext().reportErrorAtOffset(
-                    function.info.getOriginalCommentPosition() + invalidAnnotationIndex,
-                    String.format(
-                            "invalid return type annotation found - %s", suggestedResolution));
-            return;
-        }
-        Node functionNameNode = getFunctionNameNode(function.functionNode);
-        if (functionNameNode == null) {
-            return;
-        }
-
-        if (isReturningFunction) {
-            if (!function.isConstructor() && !function.hasReturnAnnotation() && isApiFunction) {
-                reportErrorAtNodeStart(functionNameNode,
-                        "@return annotation is required for API functions that return value");
-            }
-        } else {
-            // A @return-function that does not actually return anything and
-            // is intended to be overridden in subclasses must throw.
-            if (function.hasReturnAnnotation() && !isInterfaceFunction
-                    && !throwingFunctions.contains(function)) {
-                reportErrorAtNodeStart(functionNameNode,
-                        "@return annotation found, yet function does not return value");
-            }
-        }
-    }
-
-    private static boolean isPlainTopLevelFunction(FunctionRecord record) {
-        return record != null && record.isTopLevelFunction()
-                && (record.enclosingType == null && !record.isConstructor());
-    }
-
-    private String getFunctionName(Node functionNode) {
-        Node nameNode = getFunctionNameNode(functionNode);
-        return nameNode == null ? null : getState().getNodeText(nameNode);
-    }
-
-    private static int invalidReturnAnnotationIndex(JSDocInfo info) {
-        if (info == null) {
-            return -1;
-        }
-        Matcher m = INVALID_RETURN_PATTERN.matcher(info.getOriginalCommentString());
-        return m.find() ? m.start(1) : -1;
-    }
-
-    private static Node getFunctionNameNode(Node functionNode) {
-        // FIXME: Do not require annotation for assignment-RHS functions.
-        return AstUtil.getFunctionNameNode(functionNode);
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ProtoFollowsExtendsChecker.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ProtoFollowsExtendsChecker.java
deleted file mode 100644
index 9605fbf..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/ProtoFollowsExtendsChecker.java
+++ /dev/null
@@ -1,238 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.javascript.rhino.JSTypeExpression;
-import com.google.javascript.rhino.Node;
-import com.google.javascript.rhino.Token;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public final class ProtoFollowsExtendsChecker extends ContextTrackingChecker {
-    private static final String PROTO_PROPERTY_NAME = "__proto__";
-    private static final Set<String> IGNORED_SUPER_TYPES = new HashSet<>();
-    static {
-        IGNORED_SUPER_TYPES.add("WebInspector.Object");
-    }
-
-    private final Set<TypeRecord> typesWithAssignedProto = new HashSet<>();
-    private final Set<FunctionRecord> functionsMissingSuperCall = new HashSet<>();
-
-    @Override
-    protected void enterNode(Node node) {
-        switch (node.getToken()) {
-            case ASSIGN:
-            case VAR:
-                handleAssignment(node);
-                break;
-            case STRING_KEY:
-                handleColonNode(node);
-                break;
-            case FUNCTION:
-                enterFunction();
-                break;
-            case CALL:
-                handleCall(node);
-                break;
-            default:
-                break;
-        }
-    }
-
-    private void handleCall(Node callNode) {
-        FunctionRecord contextFunction = getState().getCurrentFunctionRecord();
-        if (contextFunction == null || !contextFunction.isConstructor()
-                || !functionsMissingSuperCall.contains(contextFunction)) {
-            return;
-        }
-        String typeName = validSuperConstructorName(callNode);
-        if (typeName == null) {
-            return;
-        }
-        TypeRecord typeRecord = getState().typeRecordsByTypeName.get(contextFunction.name);
-        if (typeRecord == null) {
-            return;
-        }
-        JSTypeExpression extendedType = typeRecord.getExtendedType();
-        // FIXME: Strip template parameters from the extendedType.
-        if (extendedType == null
-                || !typeName.equals(AstUtil.getAnnotationTypeString(extendedType))) {
-            return;
-        }
-        functionsMissingSuperCall.remove(contextFunction);
-    }
-
-    private String validSuperConstructorName(Node callNode) {
-        String callTarget = getContext().getNodeText(callNode.getFirstChild());
-        int lastDotIndex = callTarget.lastIndexOf('.');
-        if (lastDotIndex == -1) {
-            return null;
-        }
-        String methodName = callTarget.substring(lastDotIndex + 1);
-        if (!"call".equals(methodName) && !"apply".equals(methodName)) {
-            return null;
-        }
-        List<Node> arguments = AstUtil.getArguments(callNode);
-        if (arguments.isEmpty() || !"this".equals(getContext().getNodeText(arguments.get(0)))) {
-            return null;
-        }
-        return callTarget.substring(0, lastDotIndex);
-    }
-
-    @Override
-    protected void leaveNode(Node node) {
-        if (node.getToken() == Token.SCRIPT) {
-            checkFinished();
-            return;
-        }
-        if (node.getToken() == Token.FUNCTION) {
-            leaveFunction();
-            return;
-        }
-    }
-
-    private void enterFunction() {
-        FunctionRecord function = getState().getCurrentFunctionRecord();
-        JSTypeExpression extendedType = getExtendedTypeToCheck(function);
-        if (extendedType == null) {
-            return;
-        }
-        if (!IGNORED_SUPER_TYPES.contains(AstUtil.getAnnotationTypeString(extendedType))) {
-            functionsMissingSuperCall.add(function);
-        }
-    }
-
-    private void leaveFunction() {
-        FunctionRecord function = getState().getCurrentFunctionRecord();
-        if (!functionsMissingSuperCall.contains(function)) {
-            return;
-        }
-        JSTypeExpression extendedType = getExtendedTypeToCheck(function);
-        if (extendedType == null) {
-            return;
-        }
-        String annotationTypeString = AstUtil.getAnnotationTypeString(extendedType);
-        if (annotationTypeString.startsWith("HTML")) {
-            return;
-        }
-
-        reportErrorAtNodeStart(AstUtil.getFunctionNameNode(function.functionNode),
-                String.format("Type %s extends %s but does not properly invoke its constructor",
-                        function.name, annotationTypeString));
-    }
-
-    private JSTypeExpression getExtendedTypeToCheck(FunctionRecord function) {
-        if (!function.isConstructor() || function.name == null) {
-            return null;
-        }
-        TypeRecord type = getState().typeRecordsByTypeName.get(function.name);
-        if (type == null || type.isInterface()) {
-            return null;
-        }
-        return type.getExtendedType();
-    }
-
-    private void checkFinished() {
-        for (TypeRecord record : getState().getTypeRecordsByTypeName().values()) {
-            if (record.isInterface() || typesWithAssignedProto.contains(record)) {
-                continue;
-            }
-            JSTypeExpression extendedType = record.getExtendedType();
-            if (extendedType != null) {
-                Node rootNode = extendedType.getRoot();
-                if (rootNode.getToken() == Token.BANG && rootNode.getFirstChild() != null) {
-                    rootNode = rootNode.getFirstChild();
-                }
-                getContext().reportErrorAtOffset(rootNode.getSourceOffset(),
-                        String.format("No __proto__ assigned for type %s having @extends",
-                                record.typeName));
-            }
-        }
-    }
-
-    private void handleColonNode(Node node) {
-        ContextTrackingState state = getState();
-        TypeRecord type = state.getCurrentTypeRecord();
-        if (type == null) {
-            return;
-        }
-        String propertyName = node.getString();
-        if (!PROTO_PROPERTY_NAME.equals(propertyName)) {
-            return;
-        }
-        TypeRecord currentType = state.getCurrentTypeRecord();
-        if (currentType == null) {
-            // FIXME: __proto__: Foo.prototype not in an object literal for Bar.prototype.
-            return;
-        }
-        typesWithAssignedProto.add(currentType);
-        Node rightNode = node.getFirstChild();
-        String value = state.getNodeText(rightNode);
-        boolean isNullPrototype = "null".equals(value);
-        if (!isNullPrototype && !AstUtil.isPrototypeName(value)) {
-            reportErrorAtNodeStart(rightNode, "__proto__ value is not a prototype");
-            return;
-        }
-        String superType = isNullPrototype ? "null" : AstUtil.getTypeNameFromPrototype(value);
-        if (type.isInterface()) {
-            reportErrorAtNodeStart(
-                    node, String.format("__proto__ defined for interface %s", type.typeName));
-            return;
-        } else {
-            if (!isNullPrototype && type.getExtendedType() == null) {
-                reportErrorAtNodeStart(
-                        rightNode, String.format("No @extends annotation for %s extending %s",
-                                           type.typeName, superType));
-                return;
-            }
-        }
-
-        if (isNullPrototype) {
-            return;
-        }
-
-        // FIXME: Should we check that there is only one @extend-ed type
-        // for the non-interface |type|? Closure is supposed to do this anyway...
-        JSTypeExpression extendedType = type.getExtendedType();
-        String extendedTypeName = AstUtil.getAnnotationTypeString(extendedType);
-        if (!superType.equals(extendedTypeName)) {
-            reportErrorAtNodeStart(rightNode,
-                    String.format(
-                            "Supertype does not match %s declared in @extends for %s (line %d)",
-                            extendedTypeName, type.typeName,
-                            state.getContext()
-                                    .getPosition(extendedType.getRoot().getSourceOffset())
-                                    .line));
-        }
-    }
-
-    private void handleAssignment(Node assignment) {
-        String assignedTypeName =
-                getState().getNodeText(AstUtil.getAssignedTypeNameNode(assignment));
-        if (assignedTypeName == null) {
-            return;
-        }
-        if (!AstUtil.isPrototypeName(assignedTypeName)) {
-            return;
-        }
-        Node prototypeValueNode = assignment.getLastChild();
-
-        if (prototypeValueNode.getToken() == Token.OBJECTLIT) {
-            return;
-        }
-
-        // Foo.prototype = notObjectLiteral
-        ContextTrackingState state = getState();
-        TypeRecord type = state.getCurrentTypeRecord();
-        if (type == null) {
-            // Assigning a prototype for unknown type. Leave it to the closure compiler.
-            return;
-        }
-        if (type.getExtendedType() != null) {
-            reportErrorAtNodeStart(prototypeValueNode,
-                    String.format("@extends found for type %s but its prototype is not an object "
-                                    + "containing __proto__",
-                            AstUtil.getTypeNameFromPrototype(assignedTypeName)));
-        }
-    }
-}
diff --git a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/TypeRecord.java b/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/TypeRecord.java
deleted file mode 100644
index d6c677d..0000000
--- a/scripts/jsdoc_validator/src/org/chromium/devtools/jsdoc/checks/TypeRecord.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.chromium.devtools.jsdoc.checks;
-
-import com.google.common.base.Preconditions;
-import com.google.javascript.rhino.JSDocInfo;
-import com.google.javascript.rhino.JSTypeExpression;
-
-public class TypeRecord {
-    public final String typeName;
-    public final JSDocInfo info;
-
-    public TypeRecord(String typeName, JSDocInfo info) {
-        Preconditions.checkNotNull(info);
-        this.typeName = typeName;
-        this.info = info;
-    }
-
-    public boolean isInterface() {
-        return this.info.isInterface();
-    }
-
-    public JSTypeExpression getExtendedType() {
-        return this.info.getBaseType();
-    }
-}
diff --git a/scripts/jsdoc_validator/tests/document.js b/scripts/jsdoc_validator/tests/document.js
deleted file mode 100644
index 07c19fa..0000000
--- a/scripts/jsdoc_validator/tests/document.js
+++ /dev/null
@@ -1,68 +0,0 @@
-document.bar();
-window.document.bar();
-bar.document();
-bar.window.document();
-document();
-var x = window.document;
-
-function a(document) {
-    document.bar();
-    document();
-
-    function inner() {
-        var y = document;
-    }
-}
-
-function b(bar) {
-    document.bar();
-    document();
-    var document = bar;
-}
-
-function c(bar) {
-    document.bar();
-    document();
-    var inner = document + bar;
-}
-
-function d(window) {
-    window.document();
-    window.document.bar = 2;
-}
-
-/**
- * @suppressGlobalPropertiesCheck
- * @param {string} param
- */
-function e(param) {
-    document;
-    window.document;
-}
-
-/**
- * @param {string} param
- */
-function f(param) {
-    document;
-    window.document;
-}
-
-var y = x.document;
-window.x.document();
-var z = document.document;
-var bar = window + window.document;
-
-self.document = bar;
-self.addEventListener();
-self.removeEventListener();
-self.requestAnimationFrame();
-window.cancelAnimationFrame();
-getSelection();
-
-function g() {
-    var self = this;
-    self.document;
-}
-
-function h() { var a = { document: true }; }
diff --git a/scripts/jsdoc_validator/tests/function.js b/scripts/jsdoc_validator/tests/function.js
deleted file mode 100644
index 1343675..0000000
--- a/scripts/jsdoc_validator/tests/function.js
+++ /dev/null
@@ -1,380 +0,0 @@
-function badFuncNoAnnotation() {
-    return 1; // ERROR - no @return annotation.
-}
-
-/**
- * @return {number}
- */
-function badFuncAnnotatedButNoReturn() // ERROR - no @return annotation.
-{
-}
-
-/**
- * @return {number}
- */
-function badFuncAnnotatedButNoReturnValue() // ERROR - no returned value.
-{
-    return;
-}
-
-/**
- * @return {number}
- */
-function goodFunc() // OK - annotated @return.
-{
-    return 1;
-}
-
-/**
- * @returns {number}
- */
-function badReturnsShouldBeReturnFunc() // ERROR - @returns, should be @return.
-{
-    return 1;
-}
-
-/**
- * @return number
- */
-function badReturnShouldBeTypedFunc() // ERROR - number, not {number}.
-{
-    return 1;
-}
-
-/**
- * @param number foo
- * @param bar
- */
-function badParamAnnotationsFunc(foo, bar) // ERROR - @param's should be well-formed
-{
-    return 1;
-}
-
-
-/**
- * @returns {number}
- */
-function badReturnsShouldBeReturnNoValueFunc() // ERROR - @returns, should be @return.
-{
-    return;
-}
-
-/**
- * @returns {number}
- */
-function badReturnsShouldBeAbsentFunc() // ERROR - @returns, should be absent.
-{
-}
-
-/**
- * @constructor
- */
-function TypeOne() {
-    function callback() // OK - not a method.
-    {
-        return 1;
-    }
-}
-
-TypeOne.prototype = {
-    badApiMethodNoAnnotation: function() // ERROR - public method.
-    {
-        return 1;
-    },
-
-    _privateMethod: function() // OK - non-public method.
-    {
-        var obj = {};
-
-        /**
-         * @constructor
-         * @param {number} val
-         */
-        obj["a"] = obj["b"] = function(val) { // OK - constructor
-            this.foo = val;
-        }
-
-        /**
-         * @param {number} val
-         */
-        obj["c"] = obj["d"] = function(val) { // ERROR - no @this
-            this.foo = val;
-        }
-
-        return 1;
-    },
-
-    methodTwo: function()
-    {
-        function callback() // OK - not a method.
-        {
-            return 1;
-        }
-    },
-
-    /**
-     * @return {number}
-     */
-    methodThatThrows: function() // OK - throws and should be overridden in subclasses.
-    {
-        throw "Not implemented";
-    },
-
-    /**
-     * @return {number}
-     */
-    badMethodDoesNotReturnValue: function() // ERROR - does not return value.
-    {
-        return;
-    },
-
-    /**
-     * @return {number}
-     */
-    badMethodDoesNotReturn: function() // ERROR - does not return.
-    {
-        var foo = 1;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeReturn: function() // ERROR - @returns, should be @return
-    {
-        return 1;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeAbsentToo: function() // ERROR - @returns, should be absent
-    {
-        return;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeAbsent: function() // ERROR - @returns, should be absent
-    {
-        var foo = 1;
-    }
-}
-
-
-/**
- * @constructor
- */
-TypeTwo = function() {
-    function callback() // OK - not a method.
-    {
-        return 1;
-    }
-}
-
-TypeTwo.prototype = {
-    badApiMethodNoAnnotation: function() // ERROR - public method.
-    {
-        return 1;
-    },
-
-    _privateMethod: function() // OK - non-public method.
-    {
-        return 1;
-    },
-
-    methodTwo: function()
-    {
-        function callback() // OK - not a method.
-        {
-            return 1;
-        }
-    },
-
-    /**
-     * @return {number}
-     */
-    badMethodDoesNotReturnValue: function() // ERROR - does not return value.
-    {
-        return;
-    },
-
-    /**
-     * @return {number}
-     */
-    badMethodDoesNotReturn: function() // ERROR - does not return.
-    {
-        var foo = 1;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeReturn: function() // ERROR - @returns, should be @return
-    {
-        return 1;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeAbsentToo: function() // ERROR - @returns, should be absent
-    {
-        return;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeAbsent: function() // ERROR - @returns, should be absent
-    {
-        var foo = 1;
-    }
-}
-
-/**
- * @interface
- */
-Interface = function() {}
-
-Interface.prototype = {
-    /**
-     * @return {number}
-     */
-    interfaceMethod: function() {}, // OK - interface method.
-
-    /**
-     * @returns {number}
-     */
-    badReturnsInterfaceMethod: function() {} // ERROR - @returns instead of return.
-}
-
-/**
- * @return {!Object}
- */
-function returnConstructedObject() {
-
-/**
- * @constructor
- */
-TypeThree = function() {
-    function callback() // OK - not a method.
-    {
-        return 1;
-    }
-}
-
-TypeThree.prototype = {
-    badApiMethodNoAnnotation: function() // ERROR - public method.
-    {
-        return 1;
-    },
-
-    _privateMethod: function() // OK - non-public method.
-    {
-        return 1;
-    },
-
-    methodTwo: function()
-    {
-        function callback() // OK - not a method.
-        {
-            return 1;
-        }
-    },
-
-    /**
-     * @return {number}
-     */
-    badMethodDoesNotReturnValue: function() // ERROR - does not return value.
-    {
-        return;
-    },
-
-    /**
-     * @return {number}
-     */
-    badMethodDoesNotReturn: function() // ERROR - does not return.
-    {
-        var foo = 1;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeReturn: function() // ERROR - @returns, should be @return
-    {
-        return 1;
-    },
-
-    /**
-     * @returns number
-     */
-    badMethodReturnShouldBeTyped: function() // ERROR - number, not {number}
-    {
-        return 1;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeAbsentToo: function() // ERROR - @returns, should be absent
-    {
-        return;
-    },
-
-    /**
-     * @returns {number}
-     */
-    badMethodReturnsShouldBeAbsent: function() // ERROR - @returns, should be absent
-    {
-        var foo = 1;
-    },
-
-    /**
-     * @param number foo
-     * @param bar
-     */
-    badMethodParamAnnotations: function(foo, bar) // ERROR - @param's should be well-formed
-    {
-        return 1;
-    }
-}
-
-return new TypeThree();
-}
-
-
-/**
- * @param {string} a
- * @param {string} b
- * @param {string} c
- */
-function funcParamsOK1(a, b, c) {}
-
-function funcParamsOK2(a, b, c) {}
-
-/**
- * @param {string} a
- * @param {string} c
- */
-function funcParamsMissingTag1(a, b, c) {}
-
-/**
- * @param {string} a
- */
-function funcParamsMissingTag2(a, b, c) {}
-
-/**
- * @interface
- */
-function FuncInterface()
-{
-}
-
-FuncInterface.prototype = {
-    /**
-     * @return {number}
-     */
-    returnNumber: function() { }
-}
diff --git a/scripts/jsdoc_validator/tests/golden.dat b/scripts/jsdoc_validator/tests/golden.dat
deleted file mode 100644
index 8c72773..0000000
--- a/scripts/jsdoc_validator/tests/golden.dat
+++ /dev/null
@@ -1,424 +0,0 @@
-/tests/document.js:1: ERROR - Access to "document" property of global object is disallowed
-document.bar();
-^
-
-/tests/document.js:2: ERROR - Access to "document" property of global object is disallowed
-window.document.bar();
-       ^
-
-/tests/document.js:5: ERROR - Access to "document" property of global object is disallowed
-document();
-^
-
-/tests/document.js:6: ERROR - Access to "document" property of global object is disallowed
-var x = window.document;
-               ^
-
-/tests/document.js:24: ERROR - Access to "document" property of global object is disallowed
-    document.bar();
-    ^
-
-/tests/document.js:25: ERROR - Access to "document" property of global object is disallowed
-    document();
-    ^
-
-/tests/document.js:26: ERROR - Access to "document" property of global object is disallowed
-    var inner = document + bar;
-                ^
-
-/tests/document.js:47: ERROR - Access to "document" property of global object is disallowed
-    document;
-    ^
-
-/tests/document.js:48: ERROR - Access to "document" property of global object is disallowed
-    window.document;
-           ^
-
-/tests/document.js:53: ERROR - Access to "document" property of global object is disallowed
-var z = document.document;
-        ^
-
-/tests/document.js:54: ERROR - Access to "document" property of global object is disallowed
-var bar = window + window.document;
-                          ^
-
-/tests/document.js:56: ERROR - Access to "document" property of global object is disallowed
-self.document = bar;
-     ^
-
-/tests/document.js:57: ERROR - Access to "addEventListener" property of global object is disallowed
-self.addEventListener();
-     ^
-
-/tests/document.js:58: ERROR - Access to "removeEventListener" property of global object is disallowed
-self.removeEventListener();
-     ^
-
-/tests/document.js:59: ERROR - Access to "requestAnimationFrame" property of global object is disallowed
-self.requestAnimationFrame();
-     ^
-
-/tests/document.js:60: ERROR - Access to "cancelAnimationFrame" property of global object is disallowed
-window.cancelAnimationFrame();
-       ^
-
-/tests/document.js:61: ERROR - Access to "getSelection" property of global object is disallowed
-getSelection();
-^
-
-/tests/function.js:1: ERROR - @return annotation is required for API functions that return value
-function badFuncNoAnnotation() {
-         ^
-
-/tests/function.js:8: ERROR - @return annotation found, yet function does not return value
-function badFuncAnnotatedButNoReturn() // ERROR - no @return annotation.
-         ^
-
-/tests/function.js:15: ERROR - @return annotation found, yet function does not return value
-function badFuncAnnotatedButNoReturnValue() // ERROR - no returned value.
-         ^
-
-/tests/function.js:29: ERROR - invalid return type annotation found - should be "@return {<type>}"
- * @returns {number}
-   ^
-
-/tests/function.js:37: ERROR - invalid return type annotation found - should be "@return {<type>}"
- * @return number
-   ^
-
-/tests/function.js:45: ERROR - Invalid @param annotation found - should be "@param {<type>} paramName"
- * @param number foo
-          ^
-
-/tests/function.js:46: ERROR - Invalid @param annotation found - should be "@param {<type>} paramName"
- * @param bar
-          ^
-
-/tests/function.js:48: ERROR - @return annotation is required for API functions that return value
-function badParamAnnotationsFunc(foo, bar) // ERROR - @param's should be well-formed
-         ^
-
-/tests/function.js:55: ERROR - invalid return type annotation found - please remove, as function does not return value
- * @returns {number}
-   ^
-
-/tests/function.js:63: ERROR - invalid return type annotation found - please remove, as function does not return value
- * @returns {number}
-   ^
-
-/tests/function.js:80: ERROR - @return annotation is required for API functions that return value
-    badApiMethodNoAnnotation: function() // ERROR - public method.
-    ^
-
-/tests/function.js:97: ERROR - @this annotation is required for functions referencing 'this'
-        /**
-        ^
-
-/tests/function.js:126: ERROR - @return annotation found, yet function does not return value
-    badMethodDoesNotReturnValue: function() // ERROR - does not return value.
-    ^
-
-/tests/function.js:134: ERROR - @return annotation found, yet function does not return value
-    badMethodDoesNotReturn: function() // ERROR - does not return.
-    ^
-
-/tests/function.js:140: ERROR - invalid return type annotation found - should be "@return {<type>}"
-     * @returns {number}
-       ^
-
-/tests/function.js:148: ERROR - invalid return type annotation found - please remove, as function does not return value
-     * @returns {number}
-       ^
-
-/tests/function.js:156: ERROR - invalid return type annotation found - please remove, as function does not return value
-     * @returns {number}
-       ^
-
-/tests/function.js:176: ERROR - @return annotation is required for API functions that return value
-    badApiMethodNoAnnotation: function() // ERROR - public method.
-    ^
-
-/tests/function.js:197: ERROR - @return annotation found, yet function does not return value
-    badMethodDoesNotReturnValue: function() // ERROR - does not return value.
-    ^
-
-/tests/function.js:205: ERROR - @return annotation found, yet function does not return value
-    badMethodDoesNotReturn: function() // ERROR - does not return.
-    ^
-
-/tests/function.js:211: ERROR - invalid return type annotation found - should be "@return {<type>}"
-     * @returns {number}
-       ^
-
-/tests/function.js:219: ERROR - invalid return type annotation found - please remove, as function does not return value
-     * @returns {number}
-       ^
-
-/tests/function.js:227: ERROR - invalid return type annotation found - please remove, as function does not return value
-     * @returns {number}
-       ^
-
-/tests/function.js:247: ERROR - invalid return type annotation found - should be "@return {<type>}"
-     * @returns {number}
-       ^
-
-/tests/function.js:268: ERROR - @return annotation is required for API functions that return value
-    badApiMethodNoAnnotation: function() // ERROR - public method.
-    ^
-
-/tests/function.js:289: ERROR - @return annotation found, yet function does not return value
-    badMethodDoesNotReturnValue: function() // ERROR - does not return value.
-    ^
-
-/tests/function.js:297: ERROR - @return annotation found, yet function does not return value
-    badMethodDoesNotReturn: function() // ERROR - does not return.
-    ^
-
-/tests/function.js:303: ERROR - invalid return type annotation found - should be "@return {<type>}"
-     * @returns {number}
-       ^
-
-/tests/function.js:311: ERROR - invalid return type annotation found - should be "@return {<type>}"
-     * @returns number
-       ^
-
-/tests/function.js:319: ERROR - invalid return type annotation found - please remove, as function does not return value
-     * @returns {number}
-       ^
-
-/tests/function.js:327: ERROR - invalid return type annotation found - please remove, as function does not return value
-     * @returns {number}
-       ^
-
-/tests/function.js:335: ERROR - Invalid @param annotation found - should be "@param {<type>} paramName"
-     * @param number foo
-              ^
-
-/tests/function.js:336: ERROR - Invalid @param annotation found - should be "@param {<type>} paramName"
-     * @param bar
-              ^
-
-/tests/function.js:338: ERROR - @return annotation is required for API functions that return value
-    badMethodParamAnnotations: function(foo, bar) // ERROR - @param's should be well-formed
-    ^
-
-/tests/function.js:357: ERROR - No @param JSDoc tag found for parameters: [b]
-/**
-^
-
-/tests/function.js:363: ERROR - No @param JSDoc tag found for parameters: [b,c]
-/**
-^
-
-/tests/proto.js:8: ERROR - No __proto__ assigned for type DerivedNoProto having @extends
- * @extends {Base}
-             ^
-
-/tests/proto.js:10: ERROR - Type DerivedNoProto extends Base but does not properly invoke its constructor
-DerivedNoProto = function() {}
-^
-
-/tests/proto.js:16: ERROR - Type DerivedBadProto extends Base but does not properly invoke its constructor
-DerivedBadProto = function() {}
-^
-
-/tests/proto.js:19: ERROR - __proto__ value is not a prototype
-    __proto__: Base
-               ^
-
-/tests/proto.js:28: ERROR - __proto__ defined for interface InterfaceWithProto
-    __proto__: Base.prototype
-    ^
-
-/tests/proto.js:37: ERROR - No @extends annotation for ProtoNoExtends extending Base
-    __proto__: Base.prototype
-               ^
-
-/tests/proto.js:44: ERROR - Type ProtoNotSameAsExtends extends Base but does not properly invoke its constructor
-ProtoNotSameAsExtends = function() {}
-^
-
-/tests/proto.js:47: ERROR - Supertype does not match Base declared in @extends for ProtoNotSameAsExtends (line 42)
-    __proto__: Object.prototype
-               ^
-
-/tests/proto.js:52: ERROR - No __proto__ assigned for type ProtoNotObjectLiteral having @extends
- * @extends {Base}
-             ^
-
-/tests/proto.js:54: ERROR - Type ProtoNotObjectLiteral extends Base but does not properly invoke its constructor
-ProtoNotObjectLiteral = function() {}
-^
-
-/tests/proto.js:56: ERROR - @extends found for type ProtoNotObjectLiteral but its prototype is not an object containing __proto__
-ProtoNotObjectLiteral.prototype = Object;
-                                  ^
-
-/tests/proto.js:62: ERROR - Type DerivedNoSuperCall extends Base but does not properly invoke its constructor
-DerivedNoSuperCall = function() {
-^
-
-/tests/proto.js:73: ERROR - Type DerivedBadSuperCall extends Base but does not properly invoke its constructor
-DerivedBadSuperCall = function() {
-^
-
-/tests/proto.js:107: ERROR - No __proto__ assigned for type GoodSetSubclass = function()
-{
-    Set.call(this);
-} having @extends
- * @extends {Set.<T>}
-             ^
-
-/tests/proto.js:121: ERROR - No __proto__ assigned for type BadSetSubclass = function()
-{
-} having @extends
- * @extends {Set.<T>}
-             ^
-
-/tests/proto.js:124: ERROR - Type BadSetSubclass = function()
-{
-} extends Set but does not properly invoke its constructor
-var BadSetSubclass = function()
-    ^
-
-/tests/proto.js:135: ERROR - No __proto__ assigned for type NS.BadSubClass having @extends
- * @extends {Base}
-             ^
-
-/tests/proto.js:137: ERROR - Type NS.BadSubClass extends Base but does not properly invoke its constructor
-NS.BadSubClass = function() {}
-^
-
-/tests/this.js:19: ERROR - @this annotation is required for functions referencing 'this'
-        function badInnerCallback() {
-                 ^
-
-/tests/this.js:24: ERROR - @this annotation is required for functions referencing 'this'
-    function badCallbackInCtor() {
-             ^
-
-/tests/this.js:54: ERROR - @this annotation is required for functions referencing 'this'
-        function badCallbackInMethod() {
-                 ^
-
-/tests/this.js:73: ERROR - @this annotation is required for functions referencing 'this'
-        function badInnerCallback() {
-                 ^
-
-/tests/this.js:78: ERROR - @this annotation is required for functions referencing 'this'
-    function badCallbackInCtor() {
-             ^
-
-/tests/this.js:98: ERROR - @this annotation is required for functions referencing 'this'
-        function badCallbackInMethod() {
-                 ^
-
-/tests/this.js:121: ERROR - @this annotation is required for functions referencing 'this'
-        function badInnerCallback() {
-                 ^
-
-/tests/this.js:126: ERROR - @this annotation is required for functions referencing 'this'
-    function badCallbackInCtor() {
-             ^
-
-/tests/this.js:146: ERROR - @this annotation is required for functions referencing 'this'
-        function badCallbackInMethod() {
-                 ^
-
-/tests/this.js:153: ERROR - @this annotation found for function not referencing 'this'
-        function callbackNotReferencingThis() {
-                 ^
-
-/tests/this.js:191: ERROR - Member function can only be bound to 'this' as the receiver
-        var badMemberBinding1 = this.memberTwo.bind(null); // ERROR - Member not bound to |this| receiver.
-                                ^
-
-/tests/this.js:192: ERROR - Member function can only be bound to 'this' as the receiver
-        var badMemberBinding2 = this.memberTwo.bind(bar); // ERROR - Member not bound to |this| receiver.
-                                ^
-
-/tests/this.js:217: ERROR - Receiver not specified for a function referencing 'this'
-        callbackWithThis(); // ERROR - No receiver.
-        ^
-
-/tests/this.js:218: ERROR - Receiver not specified for a function referencing 'this'
-        callbackWithThis.call(); // ERROR - No receiver.
-        ^
-
-/tests/this.js:219: ERROR - Receiver not specified for a function referencing 'this'
-        callbackWithThis.call(null); // ERROR - No receiver.
-        ^
-
-/tests/this.js:220: ERROR - Receiver not specified for a function referencing 'this'
-        callbackWithThis.apply(); // ERROR - No receiver.
-        ^
-
-/tests/this.js:221: ERROR - Receiver not specified for a function referencing 'this'
-        callbackWithThis.apply(null); // ERROR - No receiver.
-        ^
-
-/tests/this.js:222: ERROR - Receiver specified for a function not referencing 'this'
-        callbackNoThis.call(this); // ERROR - Function has no @this annotation.
-        ^
-
-/tests/this.js:223: ERROR - Receiver specified for a function not referencing 'this'
-        callbackNoThis.call(foo); // ERROR - Function has no @this annotation.
-        ^
-
-/tests/this.js:224: ERROR - Receiver specified for a function not referencing 'this'
-        callbackNoThis.apply(this); // ERROR - Function has no @this annotation.
-        ^
-
-/tests/this.js:225: ERROR - Receiver specified for a function not referencing 'this'
-        callbackNoThis.bind(this); // ERROR - Function has no @this annotation.
-        ^
-
-/tests/this.js:227: ERROR - Function referencing 'this' used as argument without a receiver. This check can be suppressed using @suppressReceiverCheck annotation on function declaration.
-        this.memberTwo(callbackWithThis); // ERROR - Used as argument with no bound receiver.
-                       ^
-
-/tests/this.js:228: ERROR - Receiver not specified for a function referencing 'this'
-        this.memberTwo(callbackWithThis.bind(null, 2)); // ERROR - Used as argument with no bound receiver (null means "no receiver").
-                       ^
-
-/tests/this.js:229: ERROR - Receiver specified for a function not referencing 'this'
-        this.memberTwo(callbackNoThis.bind(this)); // ERROR - Bound to a receiver but has no @this annotation.
-                       ^
-
-/tests/this.js:230: ERROR - Receiver specified for a function not referencing 'this'
-        this.memberTwo(callbackNoThis.bind(foo)); // ERROR - Bound to a receiver but has no @this annotation.
-                       ^
-
-/tests/this.js:237: ERROR - Function referencing 'this' used as argument without a receiver. This check can be suppressed using @suppressReceiverCheck annotation on function declaration.
-        array.forEach(callbackWithThis); // ERROR - No receiver.
-                      ^
-
-/tests/this.js:238: ERROR - Function not referencing 'this' used as argument with a receiver. This check can be suppressed using @suppressReceiverCheck annotation on function declaration.
-        array.forEach(callbackNoThis, this); // ERROR - Receiver for callback with no @this annotation.
-                      ^
-
-/tests/this.js:247: ERROR - Function not referencing 'this' used as argument with a receiver. This check can be suppressed using @suppressReceiverCheck annotation on function declaration.
-        element.addEventListener("click", callbackNoThis, this); // ERROR.
-                                          ^
-
-/tests/this.js:253: ERROR - Function referencing 'this' used as argument without a receiver. This check can be suppressed using @suppressReceiverCheck annotation on function declaration.
-        element.addEventListener("click", callbackWithThis, true); // ERROR.
-                                          ^
-
-/tests/this.js:254: ERROR - Function referencing 'this' used as argument without a receiver. This check can be suppressed using @suppressReceiverCheck annotation on function declaration.
-        element.addEventListener("click", callbackWithThis, false); // ERROR.
-                                          ^
-
-/tests/this.js:268: ERROR - @this annotation is required for functions referencing 'this'
-        function callbackReferencingThisNotAnnotated()
-                 ^
-
-/tests/this.js:277: ERROR - @this annotation found for function not referencing 'this'
-        function callbackNotReferencingThisAnnotated()
-                 ^
-
-/tests/this.js:321: ERROR - @this annotation is required for functions referencing 'this'
-        function testArrowFunctionReferencingThisMissingAnnotation(a)
-                 ^
-
-Total errors: 104
diff --git a/scripts/jsdoc_validator/tests/proto.js b/scripts/jsdoc_validator/tests/proto.js
deleted file mode 100644
index 2d977ec..0000000
--- a/scripts/jsdoc_validator/tests/proto.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * @constructor
- */
-Base = function() {}
-
-/**
- * @constructor
- * @extends {Base}
- */
-DerivedNoProto = function() {}
-
-/**
- * @constructor
- * @extends {Base}
- */
-DerivedBadProto = function() {}
-
-DerivedBadProto.prototype = {
-    __proto__: Base
-}
-
-/**
- * @interface
- */
-InterfaceWithProto = function() {}
-
-InterfaceWithProto.prototype = {
-    __proto__: Base.prototype
-}
-
-/**
- * @constructor
- */
-ProtoNoExtends = function() {}
-
-ProtoNoExtends.prototype = {
-    __proto__: Base.prototype
-}
-
-/**
- * @constructor
- * @extends {Base}
- */
-ProtoNotSameAsExtends = function() {}
-
-ProtoNotSameAsExtends.prototype = {
-    __proto__: Object.prototype
-}
-
-/**
- * @constructor
- * @extends {Base}
- */
-ProtoNotObjectLiteral = function() {}
-
-ProtoNotObjectLiteral.prototype = Object;
-
-/**
- * @constructor
- * @extends {Base}
- */
-DerivedNoSuperCall = function() {
-}
-
-DerivedNoSuperCall.prototype = {
-    __proto__: Base.prototype
-}
-
-/**
- * @constructor
- * @extends {Base}
- */
-DerivedBadSuperCall = function() {
-    Base.call(1);
-}
-
-DerivedBadSuperCall.prototype = {
-    __proto__: Base.prototype
-}
-
-/**
- * @extends {Base}
- */
-GoodDerived = function() {
-    Base.call(this);
-}
-
-GoodDerived.prototype = {
-    __proto__: Base.prototype
-}
-
-/**
- * @constructor
- * @template T
- */
-var Set = function() {}
-
-Set.prototype = {
-    add: function(item) {},
-    remove: function(item) {},
-    /** @return {boolean} */
-    contains: function(item) { return true; }
-}
-
-/**
- * @constructor
- * @extends {Set.<T>}
- * @template T
- */
-var GoodSetSubclass = function()
-{
-    Set.call(this);
-}
-
-GoodSetSubclass.prototype = {
-    __proto__: Set.prototype
-}
-
-/**
- * @constructor
- * @extends {Set.<T>}
- * @template T
- */
-var BadSetSubclass = function()
-{
-}
-
-BadSetSubclass.prototype = {
-}
-
-var NS = {};
-
-/**
- * @constructor
- * @extends {Base}
- */
-NS.BadSubClass = function() {}
diff --git a/scripts/jsdoc_validator/tests/this.js b/scripts/jsdoc_validator/tests/this.js
deleted file mode 100644
index 2aafe13..0000000
--- a/scripts/jsdoc_validator/tests/this.js
+++ /dev/null
@@ -1,327 +0,0 @@
-this.foo = this.foo + 1; // OK - outside of function.
-
-function f() {
-    this.foo = this.foo + 1; // OK - global |this|.
-}
-
-/**
- * @constructor
- */
-function TypeOne() {
-    this.foo = this.foo + 1; // OK - object field in ctor.
-
-    /**
-     * @this {TypeOne}
-     */
-    function callbackOne() {
-        this.foo = this.foo + 1; // OK - @this declared.
-
-        function badInnerCallback() {
-            this.foo = this.foo + 2; // ERROR - @this not declared.
-        }
-    }
-
-    function badCallbackInCtor() {
-        this.foo = this.foo + 1; // ERROR - @this not declared.
-    }
-}
-
-TypeOne.prototype = {
-    addListener: function(callback)
-    {
-        if (typeof callback !== "function")
-            throw "addListener: callback is not a function";
-        if (this._listeners.length === 0)
-            extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
-        this._listeners.push(callback);
-        extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this));
-    },
-
-    funcOne: function() {
-        this.foo = this.foo + 1; // OK - in method.
-    },
-
-    funcTwo: function() {
-        /**
-         * @this {TypeOne}
-         */
-        function callback() {
-            this.foo = this.foo + 1; // OK - @this declared.
-        }
-    },
-
-    funcThree: function() {
-        function badCallbackInMethod() {
-            this.foo = this.foo + 1; // ERROR - @this not declared.
-        }
-    }
-}
-
-
-/**
- * @constructor
- */
-TypeTwo = function() {
-    this.bar = this.bar + 1; // OK - object field in ctor.
-
-    /**
-     * @this {TypeTwo}
-     */
-    function callbackOne() {
-        this.bar = this.bar + 1; // OK - @this declared.
-
-        function badInnerCallback() {
-            this.bar = this.bar + 2; // ERROR - @this not declared.
-        }
-    }
-
-    function badCallbackInCtor() {
-        this.bar = this.bar + 1; // ERROR - @this not declared.
-    }
-}
-
-TypeTwo.prototype = {
-    funcOne: function() {
-        this.bar = this.bar + 1; // OK - in method.
-    },
-
-    funcTwo: function() {
-        /**
-         * @this {TypeTwo}
-         */
-        function callback() {
-            this.bar = this.bar + 1; // OK - @this declared.
-        }
-    },
-
-    funcThree: function() {
-        function badCallbackInMethod() {
-            this.bar = this.bar + 1; // ERROR - @this not declared.
-        }
-    }
-}
-
-/**
- * @return {!Object}
- */
-function returnConstructedObject() {
-
-/**
- * @constructor
- */
-TypeThree = function() {
-    this.bar = this.bar + 1; // OK - object field in ctor.
-
-    /**
-     * @this {TypeThree}
-     */
-    function callbackOne() {
-        this.bar = this.bar + 1; // OK - @this declared.
-
-        function badInnerCallback() {
-            this.bar = this.bar + 2; // ERROR - @this not declared.
-        }
-    }
-
-    function badCallbackInCtor() {
-        this.bar = this.bar + 1; // ERROR - @this not declared.
-    }
-}
-
-TypeThree.prototype = {
-    funcOne: function() {
-        this.bar = this.bar + 1; // OK - in method.
-    },
-
-    funcTwo: function() {
-        /**
-         * @this {TypeThree}
-         */
-        function callback() {
-            this.bar = this.bar + 1; // OK - @this declared.
-        }
-    },
-
-    funcThree: function() {
-        function badCallbackInMethod() {
-            this.bar = this.bar + 1; // ERROR - @this not declared.
-        }
-
-        /**
-         * @this {TypeOne}
-         */
-        function callbackNotReferencingThis() {
-            return 3; // ERROR - @this for a function not referencing |this|.
-        }
-    }
-}
-
-return new TypeThree();
-}
-
-var object = {
-    /**
-     * @this {MyType}
-     */
-    value: function()
-    {
-        this.foo = 1; // OK - @this annotated.
-    }
-};
-
-(function() {
-    var object = {
-        /**
-         * @this {MyType}
-         */
-        value: function()
-        {
-            this.foo = 1; // OK - @this annotated.
-        }
-    };
-})();
-
-/**
- * @constructor
- */
-var ReceiverTest = function() {}
-
-ReceiverTest.prototype = {
-    memberOne: function() {
-        var badMemberBinding1 = this.memberTwo.bind(null); // ERROR - Member not bound to |this| receiver.
-        var badMemberBinding2 = this.memberTwo.bind(bar); // ERROR - Member not bound to |this| receiver.
-        var goodMemberBinding = this.memberTwo.bind(this);
-
-        /** @this {ReceiverTest} */
-        function callbackWithThis()
-        {
-            this.memberTwo();
-        }
-
-        function callbackNoThis()
-        {
-            return 42;
-        }
-
-        callbackWithThis.call(this);
-        callbackWithThis.call(foo);
-        callbackNoThis();
-        callbackNoThis.call(null, 1);
-        callbackNoThis.apply(null, [2]);
-        callbackNoThis.bind(null, 1);
-        this.memberTwo(callbackWithThis.bind(this, 1));
-        this.memberTwo(callbackWithThis.bind(foo, 1));
-        this.memberTwo(callbackNoThis);
-        this.memberTwo(callbackNoThis.bind(null));
-
-        callbackWithThis(); // ERROR - No receiver.
-        callbackWithThis.call(); // ERROR - No receiver.
-        callbackWithThis.call(null); // ERROR - No receiver.
-        callbackWithThis.apply(); // ERROR - No receiver.
-        callbackWithThis.apply(null); // ERROR - No receiver.
-        callbackNoThis.call(this); // ERROR - Function has no @this annotation.
-        callbackNoThis.call(foo); // ERROR - Function has no @this annotation.
-        callbackNoThis.apply(this); // ERROR - Function has no @this annotation.
-        callbackNoThis.bind(this); // ERROR - Function has no @this annotation.
-
-        this.memberTwo(callbackWithThis); // ERROR - Used as argument with no bound receiver.
-        this.memberTwo(callbackWithThis.bind(null, 2)); // ERROR - Used as argument with no bound receiver (null means "no receiver").
-        this.memberTwo(callbackNoThis.bind(this)); // ERROR - Bound to a receiver but has no @this annotation.
-        this.memberTwo(callbackNoThis.bind(foo)); // ERROR - Bound to a receiver but has no @this annotation.
-
-        // Callback receivers specified as arguments.
-
-        array.forEach(callbackWithThis, this);
-        array.forEach(callbackNoThis);
-
-        array.forEach(callbackWithThis); // ERROR - No receiver.
-        array.forEach(callbackNoThis, this); // ERROR - Receiver for callback with no @this annotation.
-
-        var isMultiline = false;
-
-        element.addEventListener("click", callbackNoThis);
-        element.addEventListener("click", callbackNoThis, true);
-        element.addEventListener("click", callbackNoThis, false);
-        element.addEventListener("click", callbackNoThis, isMultiline); // OK - ignored.
-
-        element.addEventListener("click", callbackNoThis, this); // ERROR.
-
-        element.addEventListener("click", callbackWithThis, this);
-        element.addEventListener("click", callbackWithThis, foo); // OK - ignored.
-        element.addEventListener("click", callbackWithThis, isMultiline); // OK - ignored.
-
-        element.addEventListener("click", callbackWithThis, true); // ERROR.
-        element.addEventListener("click", callbackWithThis, false); // ERROR.
-
-        // DevTools-specific.
-
-        /**
-         * @suppressReceiverCheck
-         * @this {Object}
-         */
-        function ignoredCallbackWithThis()
-        {
-            this.foo = 1;
-        }
-        object.callFunction(func, [], ignoredCallbackWithThis); // OK - ignored.
-
-        function callbackReferencingThisNotAnnotated()
-        {
-            this.foo = 2;
-        }
-        this.memberTwo(callbackReferencingThisNotAnnotated.bind(this)); // OK - No @this annotation, but references |this|.
-
-        /**
-         * @this {Object}
-         */
-        function callbackNotReferencingThisAnnotated()
-        {
-        }
-        this.memberTwo(callbackNotReferencingThisAnnotated); // OK - Has @this annotation, but does not reference |this|.
-    },
-
-    memberTwo: function(arg) {}
-}
-
-/**
- * @constructor
- */
-function ReceiverWithArrowsTest()
-{
-    this._q = [];
-}
-
-ReceiverWithArrowsTest.prototype = {
-    /**
-     * @param {string} s
-     */
-    memberOne: function(s)
-    {
-        /**
-         * @param {string} a
-         * @this {C}
-         */
-        function testArrowFunctionReferencingThis(a)
-        {
-            (x => this._q.push(x))(a);
-        }
-
-        /**
-         * @param {string} a
-         * @this {C}
-         */
-        function testNestedArrowFunctionReferencingThis(a)
-        {
-            (x => (y => this._q.push(y))(x))(a);
-        }
-
-        /**
-         * @param {string} a
-         */
-        function testArrowFunctionReferencingThisMissingAnnotation(a)
-        {
-            (x => this._q.push(x))(a);
-        }
-
-    }
-};
diff --git a/scripts/json_validator/module.schema.json b/scripts/json_validator/module.schema.json
deleted file mode 100644
index 2c7c3fa..0000000
--- a/scripts/json_validator/module.schema.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-    "$schema": "http://json-schema.org/draft-04/schema#",
-    "type": "object",
-    "additionalProperties": false,
-    "properties": {
-        "extensions": {
-            "type": "array",
-            "description": "Extension points",
-            "items": {
-                "properties": {
-                    "type": {"type": "string"},
-                    "order": {"type": "number"}
-                }
-            }
-        },
-        "dependencies": {
-            "type": "array",
-            "items": {
-                "type": "string"
-            }
-        },
-        "scripts": {
-            "type": "array",
-            "items": {
-                "type": "string"
-            }
-        },
-        "resources": {
-            "type": "array",
-            "items": {
-                "type": "string"
-            }
-        },
-        "skip_compilation": {
-            "type": "array",
-            "items": {
-                "type": "string"
-            }
-        },
-        "experiment": {
-            "type": "string"
-        }
-    },
-    "definitions": {
-    }
-}
\ No newline at end of file
diff --git a/scripts/json_validator/validate_module_json.js b/scripts/json_validator/validate_module_json.js
deleted file mode 100644
index 2d43584..0000000
--- a/scripts/json_validator/validate_module_json.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-const utils = require('../utils');
-
-const FRONTEND_PATH = path.resolve(__dirname, '..', '..', 'front_end');
-
-const modules = [];
-for (let dir of fs.readdirSync(FRONTEND_PATH)) {
-  if (!utils.isDir(path.resolve(FRONTEND_PATH, dir)))
-    continue;
-  let module = path.resolve(dir, 'module.json');
-  if (utils.isFile(path.resolve(FRONTEND_PATH, dir, 'module.json')))
-    modules.push(dir);
-}
-
-const Ajv = require('ajv');
-const ajv = new Ajv();
-// This seems to be the most widely supported version of the schema.
-ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
-const schema = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'module.schema.json')));
-const validate = ajv.compile(schema);
-
-let totalErrors = 0;
-for (let module of modules) {
-  const moduleObject = JSON.parse(fs.readFileSync(path.resolve(FRONTEND_PATH, module, 'module.json')));
-  const valid = validate(moduleObject);
-  if (!valid) {
-    console.log('Issue with ./front_end/' + module + '/module.json:');
-    totalErrors++;
-    validate.errors.sort((a, b) => b.dataPath.length - a.dataPath.length);
-    const error = validate.errors[0];
-    console.log('  ', error.dataPath, error.message, error.params);
-    console.log('');
-  }
-}
-if (totalErrors)
-  console.log('module.json errors:', totalErrors);
-process.exit(totalErrors);
diff --git a/scripts/lint_javascript.py b/scripts/lint_javascript.py
deleted file mode 100755
index 3d43a5c..0000000
--- a/scripts/lint_javascript.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os.path as path
-import re
-import subprocess
-import sys
-
-import local_node
-
-files_to_lint = None
-
-if len(sys.argv) >= 2:
-    if sys.argv[1] == "--help":
-        print("Usage: %s [file|dir|glob]*" % path.basename(sys.argv[0]))
-        print
-        print(" [file|dir|glob]*  Path or glob to run eslint on.")
-        print("                   If absent, the entire frontend will be checked.")
-        sys.exit(0)
-
-    else:
-        print("Linting only these files:\n %s" % sys.argv[1:])
-        files_to_lint = sys.argv[1:]
-
-is_cygwin = sys.platform == "cygwin"
-
-
-def popen(arguments, cwd=None):
-    return subprocess.Popen(arguments, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-
-def to_platform_path(filepath):
-    if not is_cygwin:
-        return filepath
-    return re.sub(r"^/cygdrive/(\w)", "\\1:", filepath)
-
-
-def to_platform_path_exact(filepath):
-    if not is_cygwin:
-        return filepath
-    output, _ = popen(["cygpath", "-w", filepath]).communicate()
-    # pylint: disable=E1103
-    return output.strip().replace("\\", "\\\\")
-
-
-scripts_path = path.dirname(path.abspath(__file__))
-devtools_path = path.dirname(scripts_path)
-devtools_frontend_path = path.join(devtools_path, "front_end")
-
-print("Linting JavaScript with eslint...\n")
-
-
-def js_lint(files_list=None):
-    eslint_errors_found = False
-
-    if files_list is None:
-        files_list = [devtools_frontend_path]
-    files_list = [file_name for file_name in files_list if not file_name.endswith(".eslintrc.js")]
-
-    eslintconfig_path = path.join(devtools_path, ".eslintrc.js")
-    eslintignore_path = path.join(devtools_path, ".eslintignore")
-    exec_command = [
-        local_node.node_path(),
-        local_node.eslint_path(),
-        "--config",
-        to_platform_path_exact(eslintconfig_path),
-        "--ignore-path",
-        to_platform_path_exact(eslintignore_path),
-    ] + files_list
-
-    eslint_proc = popen(exec_command, cwd=devtools_path)
-    (eslint_proc_out, _) = eslint_proc.communicate()
-    if eslint_proc.returncode != 0:
-        eslint_errors_found = True
-    else:
-        print("eslint exited successfully")
-
-    print(eslint_proc_out)
-    return eslint_errors_found
-
-
-errors_found = js_lint(files_to_lint)
-
-if errors_found:
-    print("ERRORS DETECTED")
-    sys.exit(1)
diff --git a/scripts/local_node.py b/scripts/local_node.py
deleted file mode 100644
index 3054114..0000000
--- a/scripts/local_node.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-Thin wrapper around the local node.js installed as part of chromium DEPS
-"""
-
-from os import path
-import sys
-
-SCRIPTS_PATH = path.dirname(path.abspath(__file__))
-THIRD_PARTY_PATH = path.join(SCRIPTS_PATH, '..', '..', '..', '..')
-NODE_PATH = path.join(THIRD_PARTY_PATH, 'node')
-ESLINT_PATH = path.join(THIRD_PARTY_PATH, 'devtools-node-modules', 'third_party',
-                        'node_modules', '.bin', 'eslint')
-
-try:
-    old_sys_path = sys.path[:]
-    sys.path.append(NODE_PATH)
-    import node
-finally:
-    sys.path = old_sys_path
-
-
-def node_path():
-    return node.GetBinaryPath()
-
-
-def eslint_path():
-    return ESLINT_PATH
diff --git a/scripts/npm_test.js b/scripts/npm_test.js
deleted file mode 100644
index 17e05a1..0000000
--- a/scripts/npm_test.js
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var childProcess = require('child_process');
-var fs = require('fs');
-var path = require('path');
-var shell = require('child_process').execSync;
-
-var utils = require('./utils');
-
-var Flags = {
-  DEBUG_DEVTOOLS: '--debug-devtools',
-  DEBUG_DEVTOOLS_SHORTHAND: '-d',
-  FETCH_CONTENT_SHELL: '--fetch-content-shell',
-  CHROMIUM_PATH: '--chromium-path',  // useful for bisecting
-  TARGET: '--target',                // build sub-directory (e.g. Release, Default)
-};
-
-var IS_DEBUG_ENABLED =
-    utils.includes(process.argv, Flags.DEBUG_DEVTOOLS) || utils.includes(process.argv, Flags.DEBUG_DEVTOOLS_SHORTHAND);
-var CUSTOM_CHROMIUM_PATH = utils.parseArgs(process.argv)[Flags.CHROMIUM_PATH];
-var IS_FETCH_CONTENT_SHELL = utils.includes(process.argv, Flags.FETCH_CONTENT_SHELL);
-var TARGET = utils.parseArgs(process.argv)[Flags.TARGET] || 'Release';
-
-var CONTENT_SHELL_ZIP = 'content-shell.zip';
-var MAX_CONTENT_SHELLS = 10;
-var PLATFORM = getPlatform();
-var PYTHON = process.platform === 'win32' ? 'python.bat' : 'python';
-
-var CHROMIUM_SRC_PATH = CUSTOM_CHROMIUM_PATH || path.resolve(__dirname, '..', '..', '..', '..', '..');
-var RELEASE_PATH = path.resolve(CHROMIUM_SRC_PATH, 'out', TARGET);
-var BLINK_TEST_PATH = path.resolve(CHROMIUM_SRC_PATH, 'blink', 'tools', 'run_layout_tests.py');
-var DEVTOOLS_PATH = path.resolve(CHROMIUM_SRC_PATH, 'third_party', 'WebKit', 'Source', 'devtools');
-var CACHE_PATH = path.resolve(DEVTOOLS_PATH, '.test_cache');
-var SOURCE_PATH = path.resolve(DEVTOOLS_PATH, 'front_end');
-
-function main() {
-  if (!utils.isDir(CACHE_PATH))
-    fs.mkdirSync(CACHE_PATH);
-  deleteOldContentShells();
-
-  var hasUserCompiledContentShell = utils.isFile(getContentShellBinaryPath(RELEASE_PATH));
-  if (!IS_FETCH_CONTENT_SHELL && hasUserCompiledContentShell) {
-    var outDir = path.resolve(RELEASE_PATH, '..');
-    if (!IS_DEBUG_ENABLED)
-      compileFrontend();
-
-    runTests(outDir, IS_DEBUG_ENABLED);
-    return;
-  }
-
-  findPreviousUploadedPosition(findMostRecentChromiumCommit()).then(onUploadedCommitPosition).catch(onError);
-
-  function onError(error) {
-    console.log('Unable to run tests because of error:', error);
-    console.log(`Try removing the .test_cache folder [${CACHE_PATH}] and retrying`);
-  }
-}
-main();
-
-function compileFrontend() {
-  console.log('Compiling devtools frontend');
-  try {
-    shell(`ninja -C ${RELEASE_PATH} devtools_frontend_resources`, {cwd: CHROMIUM_SRC_PATH});
-  } catch (err) {
-    console.log(err.stdout.toString());
-    console.log('ERROR: Cannot compile frontend\n' + err);
-    process.exit(1);
-  }
-}
-
-function onUploadedCommitPosition(commitPosition) {
-  var contentShellDirPath = path.resolve(CACHE_PATH, commitPosition, 'out', TARGET);
-  var contentShellResourcesPath = path.resolve(contentShellDirPath, 'resources');
-  var contentShellPath = path.resolve(CACHE_PATH, commitPosition, 'out');
-
-  var hasCachedContentShell = utils.isFile(getContentShellBinaryPath(contentShellDirPath));
-  if (hasCachedContentShell) {
-    console.log(`Using cached content shell at: ${contentShellPath}`);
-    copyFrontend(contentShellResourcesPath);
-    return runTests(contentShellPath, true);
-  }
-  var url = `http://commondatastorage.googleapis.com/chromium-browser-snapshots/${PLATFORM}/${commitPosition
-  }/${CONTENT_SHELL_ZIP}`;
-  return prepareContentShellDirectory(commitPosition)
-      .then(() => downloadContentShell(url, commitPosition))
-      .then(extractContentShell)
-      .then(() => copyFrontend(contentShellResourcesPath))
-      .then(() => runTests(contentShellPath, true));
-}
-
-function copyFrontend(contentShellResourcesPath) {
-  var devtoolsResourcesPath = path.resolve(contentShellResourcesPath, 'inspector');
-  var copiedFrontendPath = path.resolve(devtoolsResourcesPath, 'front_end');
-  var debugFrontendPath = path.resolve(devtoolsResourcesPath, 'debug');
-  var inspectorBackendCommandsPath = path.resolve(devtoolsResourcesPath, 'InspectorBackendCommands.js');
-  var supportedCSSPropertiesPath = path.resolve(devtoolsResourcesPath, 'SupportedCSSProperties.js');
-  utils.removeRecursive(copiedFrontendPath);
-  utils.removeRecursive(debugFrontendPath);
-  utils.copyRecursive(SOURCE_PATH, devtoolsResourcesPath);
-  fs.renameSync(copiedFrontendPath, debugFrontendPath);
-  utils.copy(inspectorBackendCommandsPath, debugFrontendPath);
-  utils.copy(supportedCSSPropertiesPath, debugFrontendPath);
-}
-
-function getPlatform() {
-  if (process.platform === 'linux') {
-    return 'Linux_x64';
-  }
-  if (process.platform === 'win32') {
-    return 'Win_x64';
-  }
-  if (process.platform === 'darwin')
-    return 'Mac';
-
-  throw new Error(`Unrecognized platform detected: ${process.platform}`);
-}
-
-function findMostRecentChromiumCommit() {
-  var commitMessage = shell(`git log --max-count=1 --grep="Cr-Commit-Position"`).toString().trim();
-  var commitPosition = commitMessage.match(/Cr-Commit-Position: refs\/heads\/master@\{#([0-9]+)\}/)[1];
-  return commitPosition;
-}
-
-function deleteOldContentShells() {
-  var files = fs.readdirSync(CACHE_PATH);
-  if (files.length < MAX_CONTENT_SHELLS)
-    return;
-  files.sort((a, b) => parseInt(b, 10) - parseInt(a, 10));
-  var remainingNumberOfContentShells = MAX_CONTENT_SHELLS / 2;
-  var oldContentShellDirs = files.slice(remainingNumberOfContentShells);
-  for (var i = 0; i < oldContentShellDirs.length; i++)
-    utils.removeRecursive(path.resolve(CACHE_PATH, oldContentShellDirs[i]));
-  console.log(`Removed old content shells: ${oldContentShellDirs}`);
-}
-
-function findPreviousUploadedPosition(commitPosition) {
-  var previousPosition = commitPosition - 100;
-  var positionsListURL =
-      `http://commondatastorage.googleapis.com/chromium-browser-snapshots/?delimiter=/&prefix=${PLATFORM
-  }/&marker=${PLATFORM}/${previousPosition}/`;
-  return utils.fetch(positionsListURL).then(onPositionsList).catch(onError);
-
-  function onPositionsList(buffer) {
-    var positions = buffer.toString('binary')
-                        .match(/([^<>]+)(?=<\/Prefix><\/CommonPrefixes>)/g)
-                        .map(prefixedPosition => prefixedPosition.split('/')[1])
-                        .map(positionString => parseInt(positionString, 10));
-    var positionSet = new Set(positions);
-    var previousUploadedPosition = commitPosition;
-    while (commitPosition - previousUploadedPosition < 100) {
-      if (positionSet.has(previousUploadedPosition))
-        return previousUploadedPosition.toString();
-      previousUploadedPosition--;
-    }
-    onError();
-  }
-
-  function onError(error) {
-    if (error)
-      console.log(`Received error: ${error} trying to fetch positions list from url: ${positionsListURL}`);
-    throw new Error(`Unable to find a previous upload position for commit position: ${commitPosition}`);
-  }
-}
-
-function prepareContentShellDirectory(folder) {
-  var contentShellPath = path.join(CACHE_PATH, folder);
-  if (utils.isDir(contentShellPath))
-    utils.removeRecursive(contentShellPath);
-  fs.mkdirSync(contentShellPath);
-  return Promise.resolve(folder);
-}
-
-function downloadContentShell(url, folder) {
-  console.log('Downloading content shell from:', url);
-  console.log('NOTE: Download is ~35-65 MB depending on OS');
-  return utils.fetch(url).then(writeZip).catch(onError);
-
-  function writeZip(buffer) {
-    console.log('Completed download of content shell');
-    var contentShellZipPath = path.join(CACHE_PATH, folder, CONTENT_SHELL_ZIP);
-    fs.writeFileSync(contentShellZipPath, buffer);
-    return contentShellZipPath;
-  }
-
-  function onError(error) {
-    console.log(`Received error: ${error} trying to download content shell from url: ${url}`);
-    throw new Error('Unable to download content shell');
-  }
-}
-
-function extractContentShell(contentShellZipPath) {
-  console.log(`Extracting content shell zip: ${contentShellZipPath}`);
-  var unzipScriptPath = path.resolve(__dirname, 'unzip.py');
-  var src = contentShellZipPath;
-  var dest = path.resolve(path.dirname(src), 'out');
-  shell(`${PYTHON} ${unzipScriptPath} ${src} ${dest}`);
-  fs.unlinkSync(src);
-  var originalDirPath = path.resolve(dest, 'content-shell');
-  var newDirPath = path.resolve(dest, TARGET);
-  fs.renameSync(originalDirPath, newDirPath);
-  fs.chmodSync(getContentShellBinaryPath(newDirPath), '755');
-  if (process.platform === 'darwin') {
-    var helperPath = path.resolve(
-        newDirPath, 'Content Shell.app', 'Contents', 'Frameworks', 'Content Shell Helper.app', 'Contents', 'MacOS',
-        'Content Shell Helper');
-    fs.chmodSync(helperPath, '755');
-  }
-  return dest;
-}
-
-function getContentShellBinaryPath(dirPath) {
-  if (process.platform === 'linux')
-    return path.resolve(dirPath, 'content_shell');
-
-  if (process.platform === 'win32')
-    return path.resolve(dirPath, 'content_shell.exe');
-
-  if (process.platform === 'darwin')
-    return path.resolve(dirPath, 'Content Shell.app', 'Contents', 'MacOS', 'Content Shell');
-}
-
-function runTests(buildDirectoryPath, useDebugDevtools) {
-  var testArgs = getInspectorTests().concat([
-    '--no-pixel-tests',
-    '--build-directory',
-    buildDirectoryPath,
-    '--target',
-    TARGET,
-  ]);
-  if (useDebugDevtools)
-    testArgs.push('--additional-driver-flag=--debug-devtools');
-  else
-    console.log('TIP: You can debug a test using: npm run debug-test inspector/test-name.html');
-
-  if (IS_DEBUG_ENABLED) {
-    testArgs.push('--additional-driver-flag=--remote-debugging-port=9222');
-    testArgs.push('--time-out-ms=6000000');
-    console.log('\n=============================================');
-    var unitTest = testArgs.find(arg => arg.includes('http/tests/devtools/unit/'));
-    if (unitTest) {
-      var unitTestPath = `http://localhost:8080/${unitTest.slice('http/tests/'.length)}`;
-      var link =
-          `http://localhost:8080/inspector-sources/debug/integration_test_runner.html?experiments=true&test=${
-                                                                                                              unitTestPath
-                                                                                                            }`;
-      console.log('1) Go to: ', link);
-      console.log('2) Go to: http://localhost:9222/, click on "inspected-page.html", and copy the ws query parameter');
-      console.log('3) Open DevTools on DevTools and you can refresh to re-run the test')
-    } else {
-      console.log('Go to: http://localhost:9222/');
-      console.log('Click on link and in console execute: test()');
-    }
-    console.log('=============================================\n');
-  }
-  var args = [BLINK_TEST_PATH].concat(testArgs).concat(getTestFlags());
-  console.log(`Running layout tests with args: ${args}`);
-  childProcess.spawn(PYTHON, args, {stdio: 'inherit'});
-}
-
-function getTestFlags() {
-  var flagValues = Object.keys(Flags).map(key => Flags[key]);
-  return process.argv.slice(2).filter(arg => {
-    var flagName = utils.includes(arg, '=') ? arg.slice(0, arg.indexOf('=')) : arg;
-    return !utils.includes(flagValues, flagName) && !utils.includes(arg, 'inspector') &&
-        !utils.includes(arg, 'http/tests/devtools');
-  });
-}
-
-function getInspectorTests() {
-  var specificTests =
-      process.argv.filter(arg => utils.includes(arg, 'inspector') || utils.includes(arg, 'http/tests/devtools'));
-  if (specificTests.length)
-    return specificTests;
-  return [
-    'inspector*',
-    'http/tests/inspector*',
-    'http/tests/devtools',
-  ];
-}
\ No newline at end of file
diff --git a/scripts/optimize_png_images.py b/scripts/optimize_png_images.py
deleted file mode 100755
index d2b73e6..0000000
--- a/scripts/optimize_png_images.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os
-import os.path
-import subprocess
-import sys
-
-from build import devtools_file_hashes
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-scripts_path = os.path.dirname(os.path.abspath(__file__))
-devtools_path = os.path.dirname(scripts_path)
-blink_source_path = os.path.dirname(devtools_path)
-blink_path = os.path.dirname(blink_source_path)
-chromium_src_path = os.path.dirname(os.path.dirname(blink_path))
-devtools_frontend_path = os.path.join(devtools_path, "front_end")
-images_path = os.path.join(devtools_frontend_path, "Images")
-image_sources_path = os.path.join(images_path, "src")
-hashes_file_name = "optimize_png.hashes"
-hashes_file_path = os.path.join(image_sources_path, hashes_file_name)
-
-file_names = os.listdir(image_sources_path)
-svg_file_paths = [os.path.join(image_sources_path, file_name) for file_name in file_names if file_name.endswith(".svg")]
-svg_file_paths_to_optimize = devtools_file_hashes.files_with_invalid_hashes(hashes_file_path, svg_file_paths)
-svg_file_names = [os.path.basename(file_path) for file_path in svg_file_paths_to_optimize]
-
-
-def check_installed(app_name):
-    proc = subprocess.Popen("which %s" % app_name, stdout=subprocess.PIPE, shell=True)
-    proc.communicate()
-    if proc.returncode != 0:
-        print "This script needs \"%s\" to be installed." % app_name
-        print "Run sudo gem install image_optim image_optim_pack"
-        sys.exit(1)
-
-
-check_installed("image_optim")
-
-
-def optimize_png(file_name):
-    png_full_path = os.path.join(images_path, file_name + ".png")
-    optimize_command = "image_optim %s" % png_full_path
-    proc = subprocess.Popen(optimize_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, cwd=chromium_src_path)
-    return proc
-
-
-if len(svg_file_names):
-    print "%d unoptimized png files found." % len(svg_file_names)
-else:
-    print "All png files are already optimized."
-    sys.exit()
-
-processes = {}
-for file_name in svg_file_names:
-    name = os.path.splitext(file_name)[0]
-    name2x = name + "_2x"
-    processes[name] = optimize_png(name)
-    processes[name2x] = optimize_png(name2x)
-
-for file_name, proc in processes.items():
-    (optimize_out, _) = proc.communicate()
-    print("Optimization of %s finished: %s" % (file_name, optimize_out))
-
-devtools_file_hashes.update_file_hashes(hashes_file_path, svg_file_paths)
diff --git a/scripts/special_case_namespaces.json b/scripts/special_case_namespaces.json
deleted file mode 100644
index d0d204d..0000000
--- a/scripts/special_case_namespaces.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "sdk": "SDK",
-  "js_sdk": "JSSDK",
-  "browser_sdk": "BrowserSDK",
-  "ui": "UI",
-  "object_ui": "ObjectUI",
-  "perf_ui": "PerfUI",
-  "har_importer": "HARImporter",
-  "sdk_test_runner": "SDKTestRunner",
-  "cpu_profiler_test_runner": "CPUProfilerTestRunner"
-}
\ No newline at end of file
diff --git a/scripts/start_chrome_and_server.js b/scripts/start_chrome_and_server.js
deleted file mode 100644
index 603c02d..0000000
--- a/scripts/start_chrome_and_server.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var childProcess = require('child_process');
-var path = require('path');
-
-var chrome = childProcess.fork(path.join(__dirname, 'chrome_debug_launcher/launch_chrome.js'), process.argv.slice(2));
-var server = childProcess.fork(path.join(__dirname, 'hosted_mode/server.js'));
-
-chrome.on('exit', function() {
-  server.kill();
-});
diff --git a/scripts/unzip.py b/scripts/unzip.py
deleted file mode 100755
index 68f5eae..0000000
--- a/scripts/unzip.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-import zipfile
-
-if len(sys.argv) < 3:
-    print('Usage: {} <src> <dest>'.format(sys.argv[0]))
-    print(' <src> full path to zip file to be extracted')
-    print(' <dest> full path to destination folder')
-    sys.exit(1)
-
-src = sys.argv[1]
-dest = sys.argv[2]
-
-zip_ref = zipfile.ZipFile(src, 'r')
-zip_ref.extractall(dest)
-zip_ref.close()
diff --git a/scripts/utils.js b/scripts/utils.js
deleted file mode 100644
index b2b76d2..0000000
--- a/scripts/utils.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var fs = require('fs');
-var http = require('http');
-var https = require('https');
-var path = require('path');
-var parseURL = require('url').parse;
-var shell = require('child_process').execSync;
-var Stream = require('stream').Transform;
-
-function fetch(url) {
-  return new Promise(fetchPromise);
-
-  function fetchPromise(resolve, reject) {
-    var request;
-    var protocol = parseURL(url).protocol;
-    var handleResponse = getCallback.bind(null, resolve, reject);
-    if (protocol === 'https:') {
-      request = https.get(url, handleResponse);
-    } else if (protocol === 'http:') {
-      request = http.get(url, handleResponse);
-    } else {
-      reject(new Error(`Invalid protocol for url: ${url}`));
-      return;
-    }
-    request.on('error', err => reject(err));
-  }
-
-  function getCallback(resolve, reject, response) {
-    if (response.statusCode !== 200) {
-      reject(new Error(`Request error: + ${response.statusCode}`));
-      return;
-    }
-    var body = new Stream();
-    response.on('data', chunk => body.push(chunk));
-    response.on('end', () => resolve(body.read()));
-  }
-}
-
-function atob(str) {
-  return new Buffer(str, 'base64').toString('binary');
-}
-
-function isFile(path) {
-  try {
-    return fs.statSync(path).isFile();
-  } catch (error) {
-    return false;
-  }
-}
-
-function isDir(path) {
-  try {
-    return fs.statSync(path).isDirectory();
-  } catch (error) {
-    return false;
-  }
-}
-
-function copy(src, dest) {
-  try {
-    var targetFilePath = path.resolve(dest, path.basename(src));
-    fs.writeFileSync(targetFilePath, fs.readFileSync(src));
-  } catch (error) {
-    throw new Error(`Received an error: [${error}] while trying to copy: ${src} -> ${dest}`);
-  }
-}
-
-function copyRecursive(src, dest) {
-  try {
-    if (isFile(src)) {
-      copy(src, dest);
-      return;
-    }
-    var targetDirPath = path.resolve(dest, path.basename(src));
-    if (!fs.existsSync(targetDirPath))
-      fs.mkdirSync(targetDirPath);
-    if (isDir(src)) {
-      var files = fs.readdirSync(src);
-      for (var i = 0; i < files.length; i++) {
-        var childPath = path.resolve(src, files[i]);
-        if (isDir(childPath)) {
-          copyRecursive(childPath, targetDirPath);
-        } else {
-          var targetFilePath = path.resolve(targetDirPath, path.basename(childPath));
-          fs.writeFileSync(targetFilePath, fs.readFileSync(childPath));
-        }
-      }
-    }
-  } catch (error) {
-    throw new Error(`Received an error: [${error}] while trying to copy: ${src} -> ${dest}`);
-  }
-}
-
-function removeRecursive(filePath) {
-  try {
-    if (fs.existsSync(filePath)) {
-      if (isFile(filePath)) {
-        fs.unlinkSync(filePath);
-        return;
-      }
-      var files = fs.readdirSync(filePath);
-      for (var i = 0; i < files.length; i++) {
-        var childPath = path.resolve(filePath, files[i]);
-        if (isDir(childPath))
-          removeRecursive(childPath);
-        else
-          fs.unlinkSync(childPath);
-      }
-      fs.rmdirSync(filePath);
-    }
-  } catch (error) {
-    throw new Error(`Received an error: [${error}] while trying to remove: ${filePath}`);
-  }
-}
-
-function includes(sequence, target) {
-  return sequence.indexOf(target) > -1;
-}
-
-function shellOutput(command) {
-  return shell(command).toString().trim();
-}
-
-function parseArgs(args) {
-  var argObject = {};
-  for (var i = 0; i < args.length; i++) {
-    var arg = args[i];
-    var components = arg.split('=');
-    var key = components[0];
-    argObject[key] = components[1] || true;
-  }
-  return argObject;
-}
-
-module.exports = {
-    fetch, atob, isFile, isDir, copy, copyRecursive, removeRecursive, includes, shellOutput, parseArgs,
-};
\ No newline at end of file
diff --git a/scripts/utils.py b/scripts/utils.py
deleted file mode 100644
index 508cc43..0000000
--- a/scripts/utils.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from os import path
-import sys
-
-
-# Based on http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python.
-def which(program):
-
-    def is_executable(fpath):
-        return path.isfile(fpath) and os.access(fpath, os.X_OK)
-
-    fpath, fname = path.split(program)
-    if fpath:
-        if is_executable(program):
-            return program
-        return None
-    env_paths = os.environ["PATH"].split(os.pathsep)
-    if sys.platform == "win32":
-        env_paths = get_windows_path(env_paths)
-    for part in env_paths:
-        part = part.strip('\"')
-        file = path.join(part, program)
-        if is_executable(file):
-            return file
-        if sys.platform == "win32" and not file.endswith(".exe"):
-            file_exe = file + ".exe"
-            if is_executable(file_exe):
-                return file_exe
-    return None
-
-
-# Use to find 64-bit programs (e.g. Java) when using 32-bit python in Windows
-def get_windows_path(env_paths):
-    new_env_paths = env_paths[:]
-    for env_path in env_paths:
-        env_path = env_path.lower()
-        if "system32" in env_path:
-            new_env_paths.append(env_path.replace("system32", "sysnative"))
-    return new_env_paths
diff --git a/scripts/visualize_deps/jquery_svg.html b/scripts/visualize_deps/jquery_svg.html
deleted file mode 100644
index 2522d5d..0000000
--- a/scripts/visualize_deps/jquery_svg.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!--
- * Copyright (c) 2015 Mountainstorm
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- -->
-<html>
-<head>
-    <link rel="stylesheet" href="http://cdn.rawgit.com/mountainstorm/jquery.graphviz.svg/master/css/graphviz.svg.css">
-</head>
-<body>
-<div id="graph" style="width: 100%; height: 100%; overflow: scroll; position: relative;"></div>
-<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
-<script type="text/javascript" src="https://cdn.rawgit.com/jquery/jquery-mousewheel/master/jquery.mousewheel.min.js"></script>
-<script type="text/javascript" src="https://cdn.rawgit.com/jquery/jquery-color/master/jquery.color.js"></script>
-<script type="text/javascript" src="http://cdn.rawgit.com/mountainstorm/jquery.graphviz.svg/master/js/jquery.graphviz.svg.js"></script>
-
-<script>
-    $(document).ready(function() {
-        $("#graph").graphviz({
-            url: "out/dependencies.dot.svg",
-            ready: function() {
-                var gv = this
-                gv.nodes().click(function() {
-                    var $set = $()
-                    $set.push(this)
-                    $set = $set.add(gv.linkedFrom(this, true))
-                    $set = $set.add(gv.linkedTo(this, true))
-                    gv.highlight($set, true)
-                    gv.bringToFront($set)
-                })
-                $(document).keydown(function(evt) {
-                    if (evt.keyCode == 27) {
-                        gv.highlight()
-                    }
-                })
-            }
-        });
-    });
-</script>
-</body>
-</html>
\ No newline at end of file
diff --git a/scripts/visualize_deps/run_visualize.js b/scripts/visualize_deps/run_visualize.js
deleted file mode 100644
index ab7e74b..0000000
--- a/scripts/visualize_deps/run_visualize.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-var childProcess = require('child_process');
-const fs = require('fs');
-var http = require('http');
-const path = require('path');
-var parseURL = require('url').parse;
-
-const utils = require('../utils');
-
-const FRONTEND_PATH = path.resolve(__dirname, '..', '..', 'front_end');
-const OUT_DIR_PATH = path.resolve(__dirname, 'out');
-const OUT_FILE_PATH = path.resolve(OUT_DIR_PATH, 'dependencies.dot');
-
-const SERVER_PORT = parseInt(process.env.PORT, 10) || 8001;
-
-function main() {
-  generateDot();
-  try {
-    childProcess.execSync(`dot -O -Tsvg ${OUT_FILE_PATH}`);
-  } catch (err) {
-    console.log(`Could not generate dot svg because: ${err}`);
-    console.log('Make sure you have graphviz installed (e.g. sudo apt install graphviz)');
-    return;
-  }
-  console.log('Generated dot file & svg');
-  startServer();
-  console.log(`Go to: http://localhost:${SERVER_PORT}/jquery_svg.html`);
-}
-
-function generateDot() {
-  if (!utils.isDir(OUT_DIR_PATH))
-    fs.mkdirSync(OUT_DIR_PATH);
-  const modules = new Set();
-  const moduleToDependencyList = ['digraph dependencies {'];
-  moduleToDependencyList.push('fixedsize = true;');
-  fs.readdirSync(FRONTEND_PATH).forEach(function(file) {
-    const moduleJSONPath = path.join(FRONTEND_PATH, file, 'module.json');
-    if (fs.statSync(path.join(FRONTEND_PATH, file)).isDirectory() && utils.isFile(moduleJSONPath)) {
-      const module = file;
-      if (module === 'audits2_worker')
-        return;
-      modules.add(module);
-      const moduleJSON = require(moduleJSONPath);
-      let moduleSize = 0;
-
-      let resources = (moduleJSON.scripts || []).concat((moduleJSON.resources || []));
-      for (let script of resources) {
-        if (fs.existsSync(path.join(FRONTEND_PATH, module, script)))
-          moduleSize += fs.statSync(path.join(FRONTEND_PATH, module, script)).size;
-      }
-      moduleSize /= 200000;
-      moduleSize = Math.max(0.5, moduleSize);
-      let fontSize = Math.max(moduleSize * 14, 14);
-
-      moduleToDependencyList.push(`${module} [width=${moduleSize}, height=${moduleSize} fontsize=${fontSize}];`);
-
-      if (moduleJSON.dependencies) {
-        for (let d of moduleJSON.dependencies)
-          moduleToDependencyList.push(`  ${module} -> ${d}`);
-      }
-    }
-  });
-  moduleToDependencyList.push('}');
-  const content = moduleToDependencyList.join('\n');
-  fs.writeFileSync(OUT_FILE_PATH, content);
-}
-
-function startServer() {
-  http.createServer(requestHandler).listen(SERVER_PORT);
-
-  function requestHandler(request, response) {
-    var filePath = parseURL(request.url).pathname;
-    var absoluteFilePath = path.join(__dirname, filePath);
-    if (!path.resolve(absoluteFilePath).startsWith(__dirname)) {
-      console.log(`File requested is outside of folder: ${__dirname}`);
-      sendResponse(403, `403 - Access denied. File requested is outside of folder: ${__dirname}`);
-      return;
-    }
-
-    fs.exists(absoluteFilePath, fsExistsCallback);
-
-    function fsExistsCallback(fileExists) {
-      if (!fileExists) {
-        console.log(`Cannot find file ${absoluteFilePath}`);
-        sendResponse(404, '404 - File not found');
-        return;
-      }
-      fs.readFile(absoluteFilePath, 'binary', readFileCallback);
-    }
-
-    function readFileCallback(err, file) {
-      if (err) {
-        console.log(`Unable to read local file ${absoluteFilePath}:`, err);
-        sendResponse(500, '500 - Internal Server Error');
-        return;
-      }
-      sendResponse(200, file);
-    }
-
-    function sendResponse(statusCode, data) {
-      response.writeHead(statusCode);
-      response.write(data, 'binary');
-      response.end();
-    }
-  }
-}
-
-if (require.main === module)
-  main();
\ No newline at end of file
diff --git a/services/devtools.js b/services/devtools.js
deleted file mode 100644
index 831acea..0000000
--- a/services/devtools.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var dispatcher = require("./dispatcher.js");
-var terminal = require("./terminal.js");
-
-var d = new dispatcher.Dispatcher();
-d.registerObject("Terminal", terminal.Terminal);
-d.start(9022);
-
-console.log("Run chrome as `chrome --devtools-flags='service-backend=ws://localhost:9022/endpoint'`");
diff --git a/services/dispatcher.js b/services/dispatcher.js
deleted file mode 100644
index 3735931..0000000
--- a/services/dispatcher.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var http = require("http");
-var ws = require("ws");
-
-function Dispatcher()
-{
-    this._constructors = new Map();
-    this._connections = new Set();
-}
-
-Dispatcher.prototype = {
-    start: function(port)
-    {
-        var http_server = http.createServer();
-        http_server.listen(port);
-
-        var WebSocketServer = ws.Server;
-        var options = { server: http_server, path: "/endpoint" };
-        var wss = new WebSocketServer(options);
-        wss.on("connection", (socket) => {
-            var connection = new Connection(this, socket);
-            this._connections.add(connection);
-        });
-    },
-
-    registerObject: function(name, constructor)
-    {
-        this._constructors.set(name, constructor);
-    },
-
-    _connectionClosed: function(connection)
-    {
-        this._connections.delete(connection);
-    }
-}
-
-exports.Dispatcher = Dispatcher;
-
-function Connection(dispatcher, socket)
-{
-    this._dispatcher = dispatcher;
-    this._objects = new Map();
-    this._lastObjectId = 1;
-    this._socket = socket;
-    this._socket.on("message", this._dispatchMessageWrapped.bind(this));
-    this._socket.on("close", this._connectionClosed.bind(this));
-}
-
-Connection.prototype = {
-    _dispatchMessageWrapped: function(data)
-    {
-        try {
-            var message = JSON.parse(data);
-            this._dispatchMessage(message);
-        } catch(e) {
-            this._sendErrorResponse(message.id, e.toString());
-        }
-    },
-
-    _dispatchMessage: function(message)
-    {
-        var [objectName, method] = message.method.split(".");
-        var result = JSON.stringify({id: message.id});
-        var constructor = this._dispatcher._constructors.get(objectName);
-        if (!constructor) {
-            this._sendErrorResponse(message.id, "Could not resolve service '" + objectName + "'");
-            return;
-        }
-        if (method === "create") {
-            var id = String(this._lastObjectId++);
-            var object = new constructor(this._notify.bind(this, id, objectName));
-            this._objects.set(id, object);
-            this._sendResponse(message.id, { id: id });
-        } else if (method === "dispose") {
-            var object = this._objects.get(message.params.id);
-            if (!object) {
-                console.error("Could not look up object with id for " + JSON.stringify(message));
-                return;
-            }
-            this._objects.delete(message.params.id);
-            object.dispose().then(() => this._sendResponse(message.id));
-        } else {
-            if (!message.params) {
-                console.error("No params in the message: " + JSON.stringify(message));
-                return;
-            }
-            var object = this._objects.get(message.params.id);
-            if (!object) {
-                console.error("Could not look up object with id for " + JSON.stringify(message));
-                return;
-            }
-            var handler = object[method];
-            if (!(handler instanceof Function)) {
-                console.error("Handler for '" + method + "' is missing.");
-                return;
-            }
-            object[method](message.params).then(result => this._sendResponse(message.id, result));
-        }
-    },
-
-    _connectionClosed: function()
-    {
-        for (var object of this._objects.values())
-            object.dispose();
-        this._objects.clear();
-        this._dispatcher._connectionClosed(this);
-    },
-
-    _notify: function(objectId, objectName, method, params)
-    {
-        params["id"] = objectId;
-        var message = { method: objectName + "." + method, params: params };
-        this._socket.send(JSON.stringify(message));
-    },
-
-    _sendResponse: function(messageId, result)
-    {
-        var message = { id: messageId, result: result };
-        this._socket.send(JSON.stringify(message));
-    },
-
-    _sendErrorResponse: function(messageId, error)
-    {
-        var message = { id: messageId, error: error };
-        this._socket.send(JSON.stringify(message));
-    },
-}
diff --git a/services/package.json b/services/package.json
deleted file mode 100644
index 824851c..0000000
--- a/services/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "name": "devtools-backend",
-  "version": "1.0.0",
-  "ignore": [
-    ".gitignore"
-  ],
-  "dependencies": {
-    "pty.js": "0.3.1",
-    "ws": "^1.1.1"
-  }
-}
diff --git a/services/terminal.js b/services/terminal.js
deleted file mode 100644
index 742b553..0000000
--- a/services/terminal.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var pty = require("pty.js");
-
-function Terminal(notify)
-{
-    this._notify = notify;
-}
-
-Terminal.prototype = {
-    init: function(params)
-    {
-        this._term = pty.spawn(process.platform === "win32" ? "cmd.exe" : "bash", [], {
-            name: "xterm-color",
-            cols: params.cols || 80,
-            rows: params.rows || 24,
-            cwd: process.env.PWD,
-            env: process.env
-        });
-
-        this._term.on("data", data => {
-            if (this._notify)
-                this._notify("data", { data: data });
-        });
-        return Promise.resolve({});
-    },
-
-    resize: function(params)
-    {
-        if (this._term)
-            this._term.resize(params.cols, params.rows);
-        return Promise.resolve({});
-    },
-
-    write: function(params)
-    {
-        this._term.write(params.data);
-        return Promise.resolve({});
-    },
-
-    dispose: function(params)
-    {
-        this._notify = null;
-        if (this._term)
-            process.kill(this._term.pid);
-        return Promise.resolve({});
-    },
-}
-
-exports.Terminal = Terminal;